package agent import ( "context" "slices" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/consts" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/dao" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/library/contexts" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/library/rolepolicy" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/library/xgorm/handler" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/model" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/model/entity" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/service" "github.com/gogf/gf/v2/util/gconv" ) type sAgentMenu struct { *agentBase } func NewAgentMenu() *sAgentMenu { return &sAgentMenu{ agentBase: newAgentBase(), } } func init() { service.RegisterAgentMenu(NewAgentMenu()) } // AllowedMenuIdsByDeptRole 获取当前机构允许的菜单ID func (s *sAgentMenu) AllowedMenuIdsByDeptRole(ctx context.Context, deptId int64) (menuIds []int64, err error) { if err = s.ensureDeptInScope(ctx, deptId); err != nil { return nil, err } var dept *entity.SysDept err = service.SysDept().Model(ctx, &handler.Option{FilterTenant: true, FilterAuth: false}). Where(dao.SysDept.Columns().DeptId, deptId). Scan(&dept) if err != nil { return nil, err } if dept == nil || dept.DeptRole == 0 { return []int64{}, nil } if dept.DeptRole == consts.SuperAdminRoleId { menuIds, err = s.allMenuIds(ctx) } else { var roleMenus []*entity.SysRoleMenu roleMenus, err = service.SysRole().GetRoleListMenu(ctx, []int64{dept.DeptRole}) for _, item := range roleMenus { menuIds = append(menuIds, item.MenuId) } } if err != nil { return nil, err } slices.Sort(menuIds) menuIds = slices.Compact(menuIds) if !contexts.IsSuperAdmin(ctx) { return rolepolicy.RestrictAssignableMenus(ctx, dept.TenantId, dept.DeptId, contexts.GetUserId(ctx), menuIds) } return rolepolicy.RestrictMenus(ctx, dept.TenantId, dept.DeptId, menuIds) } func (s *sAgentMenu) allMenuIds(ctx context.Context) (menuIds []int64, err error) { var menus []*entity.SysMenu err = service.SysMenu().Model(ctx). Where(dao.SysMenu.Columns().Status, consts.SysMenuStatusNormal). Order(dao.SysMenu.Columns().OrderNum, "ASC"). Scan(&menus) if err != nil { return nil, err } for _, item := range menus { menuIds = append(menuIds, item.MenuId) } slices.Sort(menuIds) return slices.Compact(menuIds), nil } func (s *sAgentMenu) getRoleById(ctx context.Context, roleId int64) (role *entity.SysRole, err error) { err = service.SysRole().Model(ctx, &handler.Option{FilterTenant: true, FilterAuth: false}). Where(dao.SysRole.Columns().RoleId, roleId). Scan(&role) return role, err } func (s *sAgentMenu) AllowedMenuTree(ctx context.Context, deptId int64) (tree []*model.SysMenuTreeModel, menuIds []int64, err error) { deptId = contexts.GetDeptId(ctx) menuIds, err = s.AllowedMenuIdsByDeptRole(ctx, deptId) if err != nil { return nil, nil, err } if len(menuIds) == 0 && !contexts.IsSuperAdmin(ctx) { return []*model.SysMenuTreeModel{}, []int64{}, nil } visibleMenuIds, err := rolepolicy.WithMenuAncestors(ctx, menuIds) if err != nil { return nil, nil, err } mod := service.SysMenu().Model(ctx) if !contexts.IsSuperAdmin(ctx) { mod = mod.WhereIn(dao.SysMenu.Columns().MenuId, visibleMenuIds) } var menus []*entity.SysMenu err = mod.Where(dao.SysMenu.Columns().Status, consts.SysMenuStatusNormal). Order(dao.SysMenu.Columns().OrderNum, "ASC"). Scan(&menus) if err != nil { return nil, nil, err } tree = s.buildMenuList(menus) activeMenuIds := make([]int64, 0, len(menus)) for _, menu := range menus { activeMenuIds = append(activeMenuIds, menu.MenuId) } if contexts.IsSuperAdmin(ctx) { menuIds = activeMenuIds } else { menuIds = rolepolicy.Intersect(menuIds, activeMenuIds) } return tree, menuIds, nil } func (s *sAgentMenu) buildMenuList(menus []*entity.SysMenu) (list []*model.SysMenuTreeModel) { for _, menu := range menus { list = append(list, &model.SysMenuTreeModel{ Title: menu.MenuName, Key: gconv.String(menu.MenuId), ParentId: menu.ParentId, MenuId: menu.MenuId, MenuName: menu.MenuName, MenuType: menu.MenuType, Perms: menu.Perms, }) } return list } func (s *sAgentMenu) buildMenuTree(parentId int64, menus []*entity.SysMenu) (tree []*model.SysMenuTreeModel) { for _, menu := range menus { if menu.ParentId != parentId { continue } item := &model.SysMenuTreeModel{ Title: menu.MenuName, Key: gconv.String(menu.MenuId), ParentId: menu.ParentId, MenuId: menu.MenuId, MenuName: menu.MenuName, MenuType: menu.MenuType, Perms: menu.Perms, } item.Children = s.buildMenuTree(menu.MenuId, menus) tree = append(tree, item) } if parentId == 0 && len(tree) == 0 { for _, menu := range menus { item := &model.SysMenuTreeModel{ Title: menu.MenuName, Key: gconv.String(menu.MenuId), ParentId: menu.ParentId, MenuId: menu.MenuId, MenuName: menu.MenuName, MenuType: menu.MenuType, Perms: menu.Perms, } item.Children = s.buildMenuTree(menu.MenuId, menus) tree = append(tree, item) } } return tree }