aeus-admin/service/menu.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,
}
}