package rolepolicy 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/model/entity" "github.com/gogf/gf/v2/errors/gerror" ) func WithMenuAncestors(ctx context.Context, ids []int64) ([]int64, error) { var ( seen = make(map[int64]bool, len(ids)) queue = slices.Clone(ids) ) for _, id := range ids { seen[id] = true } for len(queue) > 0 { var menus []*entity.SysMenu if err := dao.SysMenu.Ctx(ctx).Master().WhereIn("menu_id", queue).Where("status", consts.SysMenuStatusNormal).Scan(&menus); err != nil { return nil, err } queue = nil for _, menu := range menus { if menu.ParentId > 0 && !seen[menu.ParentId] { seen[menu.ParentId] = true queue = append(queue, menu.ParentId) } } } result := make([]int64, 0, len(seen)) for id := range seen { result = append(result, id) } slices.Sort(result) return result, nil } func NormalizeAssignableMenus(ctx context.Context, tenantID string, deptID, userID int64, ids []int64) ([]int64, error) { allowed, err := RestrictAssignableMenus(ctx, tenantID, deptID, userID, ids) if err != nil { return nil, err } if len(allowed) > 0 { var menus []*entity.SysMenu if err := dao.SysMenu.Ctx(ctx).Master().WhereIn("menu_id", allowed).Where("status", consts.SysMenuStatusNormal).Scan(&menus); err != nil { return nil, err } allowed = make([]int64, 0, len(menus)) for _, menu := range menus { allowed = append(allowed, menu.MenuId) } } visible, err := WithMenuAncestors(ctx, allowed) if err != nil { return nil, err } for _, id := range ids { if !slices.Contains(visible, id) { return nil, gerror.Newf("角色授权超出机构或模板范围,或菜单已停用(菜单ID:%d),请刷新授权列表后重试", id) } } slices.Sort(allowed) return slices.Compact(allowed), nil }