114 lines
2.7 KiB
Go
114 lines
2.7 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
|
|
"git.nobla.cn/golang/aeus-admin/models"
|
|
"git.nobla.cn/golang/aeus-admin/pb"
|
|
"git.nobla.cn/golang/aeus-admin/types"
|
|
"git.nobla.cn/golang/aeus/middleware/auth"
|
|
"git.nobla.cn/golang/aeus/pkg/errors"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
type (
|
|
menuOptions struct {
|
|
db *gorm.DB
|
|
}
|
|
MenuOption func(o *menuOptions)
|
|
|
|
MenuService struct {
|
|
opts *menuOptions
|
|
}
|
|
)
|
|
|
|
func WithMenuDB(db *gorm.DB) MenuOption {
|
|
return func(o *menuOptions) {
|
|
o.db = db
|
|
}
|
|
}
|
|
|
|
func (s *MenuService) hasPermission(menuID int64, permissions []*models.Permission) bool {
|
|
for _, permission := range permissions {
|
|
if permission.MenuId == menuID {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func (s *MenuService) getPermissions(menuID int64, permissions []*models.Permission) []*pb.PermissionItem {
|
|
ss := make([]*pb.PermissionItem, 0, 10)
|
|
for _, permission := range permissions {
|
|
if permission.MenuId == menuID {
|
|
ss = append(ss, &pb.PermissionItem{
|
|
Value: permission.Permission,
|
|
Label: permission.Label,
|
|
})
|
|
}
|
|
}
|
|
return ss
|
|
}
|
|
|
|
func (s *MenuService) recursiveNestedMenu(ctx context.Context, parent int64, perm bool, menus []*models.Menu, permissions []*models.Permission) []*pb.MenuItem {
|
|
values := make([]*pb.MenuItem, 0)
|
|
for _, row := range menus {
|
|
if row.ParentId == parent {
|
|
if !row.Public && !s.hasPermission(row.Id, permissions) {
|
|
continue
|
|
}
|
|
v := &pb.MenuItem{
|
|
Label: row.Label,
|
|
Name: row.Name,
|
|
Icon: row.Icon,
|
|
Hidden: row.Hidden,
|
|
Route: row.Uri,
|
|
Children: s.recursiveNestedMenu(ctx, row.Id, perm, menus, permissions),
|
|
}
|
|
if perm {
|
|
v.Permissions = s.getPermissions(row.Id, permissions)
|
|
}
|
|
values = append(values, v)
|
|
}
|
|
}
|
|
return values
|
|
}
|
|
|
|
func (s *MenuService) GetRolePermissions(ctx context.Context, db *gorm.DB, role string) (permissions []*models.Permission, err error) {
|
|
permissions = make([]*models.Permission, 0)
|
|
err = db.Where("id IN (SELECT permission_id FROM role_permissions WHERE role = ?)", role).Find(&permissions).Error
|
|
return
|
|
}
|
|
|
|
func (s *MenuService) GetMenus(ctx context.Context, req *pb.GetMenuRequest) (res *pb.GetMenuResponse, err error) {
|
|
claims, ok := auth.FromContext(ctx)
|
|
if !ok {
|
|
return nil, errors.ErrAccessDenied
|
|
}
|
|
var (
|
|
permissions []*models.Permission
|
|
)
|
|
tx := s.opts.db.WithContext(ctx)
|
|
if claims, ok := claims.(*types.Claims); ok {
|
|
permissions, err = s.GetRolePermissions(ctx, tx, claims.Role)
|
|
}
|
|
values := make([]*models.Menu, 0)
|
|
if err = tx.Find(&values).Error; err != nil {
|
|
return
|
|
}
|
|
res = &pb.GetMenuResponse{
|
|
Data: s.recursiveNestedMenu(ctx, 0, req.Permission, values, permissions),
|
|
}
|
|
return
|
|
}
|
|
|
|
func NewMenuService(cbs ...MenuOption) *MenuService {
|
|
opts := &menuOptions{}
|
|
for _, cb := range cbs {
|
|
cb(opts)
|
|
}
|
|
return &MenuService{
|
|
opts: opts,
|
|
}
|
|
}
|