package system import ( "context" "encoding/json" "strconv" "strings" "time" "management/internal/db/model/dto" db "management/internal/db/sqlc" "management/internal/global/keys" "management/internal/pkg/redis" "management/internal/pkg/session" ) type MenuBiz interface { MenuExpansion } type MenuExpansion interface { GetSysMenuByUrl(ctx context.Context, url string) (*db.SysMenu, error) ListOwnerMenuByRoleID(ctx context.Context, roleID int32) ([]*dto.OwnerMenuDto, error) RecursiveSysMenus(ctx context.Context, roleID int32) ([]*dto.MenuUIDto, error) SetRecursiveSysMenus(ctx context.Context, roleID int32) ([]*dto.MenuUIDto, error) MapOwnerMenuByRoleID(ctx context.Context, roleID int32) (map[string]*dto.OwnerMenuDto, error) SetOwnerMapMenuByRoleID(ctx context.Context, roleID int32) (map[string]*dto.OwnerMenuDto, error) } type menuBiz struct { store db.Store redis redis.IRedis session session.ISession } var _ MenuBiz = (*menuBiz)(nil) func NewMenu(store db.Store, redis redis.IRedis, session session.ISession) *menuBiz { return &menuBiz{ store: store, redis: redis, session: session, } } func (b *menuBiz) GetSysMenuByUrl(ctx context.Context, url string) (*db.SysMenu, error) { return b.store.GetSysMenuByUrl(ctx, url) } func (b *menuBiz) ListOwnerMenuByRoleID(ctx context.Context, roleID int32) ([]*dto.OwnerMenuDto, error) { // 判断redis是否存储 key := keys.GetManageKey(ctx, keys.OwnerMenus, roleID) bs, err := b.redis.GetBytes(ctx, key) if err == nil { var res []*dto.OwnerMenuDto if err := json.Unmarshal(bs, &res); err == nil { return res, nil } } return b.SetOwnerListMenuByRoleID(ctx, roleID) } func (b *menuBiz) SetOwnerListMenuByRoleID(ctx context.Context, roleID int32) ([]*dto.OwnerMenuDto, error) { menus, err := b.ownerMenusByRoleID(ctx, roleID) if err != nil { return nil, err } var res []*dto.OwnerMenuDto for _, menu := range menus { res = append(res, &dto.OwnerMenuDto{ ID: menu.ID, DisplayName: menu.DisplayName, Url: menu.Url, ParentID: menu.ParentID, Avatar: menu.Avatar, Style: menu.Style, IsList: menu.IsList, }) } bs, err := json.Marshal(res) if err != nil { return nil, err } key := keys.GetManageKey(ctx, keys.OwnerMenus, roleID) _ = redis.Set(ctx, key, bs, time.Hour*6) return res, nil } func (b *menuBiz) RecursiveSysMenus(ctx context.Context, roleID int32) ([]*dto.MenuUIDto, error) { // 判断redis是否存储 key := keys.GetManageKey(ctx, keys.RecursiveMenus, roleID) bs, err := b.redis.GetBytes(ctx, key) if err == nil { var res []*dto.MenuUIDto if err := json.Unmarshal(bs, &res); err == nil { return res, nil } } return b.SetRecursiveSysMenus(ctx, roleID) } func (b *menuBiz) SetRecursiveSysMenus(ctx context.Context, roleID int32) ([]*dto.MenuUIDto, error) { // 判断当前用户是否有vip角色 role, err := b.store.GetSysRole(ctx, roleID) if err != nil { return nil, err } var menus []*db.SysMenu if role.Vip { // vip 用户 all, err := b.store.RecursiveSysMenus(ctx) if err != nil { return nil, err } menus = convertToMenuUIDto(all) } else { // not vip all, err := b.store.RecursiveSysMenusByRoleID(ctx, roleID) if err != nil { return nil, err } menus = convertToMenuUIDto2(all) } menuList := uniqueSysMenus(menus) if len(menuList) == 0 { return nil, nil } tree := convertToUITree(menuList, 0) bs, err := json.Marshal(tree) if err != nil { return nil, err } key := keys.GetManageKey(ctx, keys.RecursiveMenus, roleID) _ = redis.Set(ctx, key, bs, time.Hour*6) return tree, nil } func (b *menuBiz) MapOwnerMenuByRoleID(ctx context.Context, roleID int32) (map[string]*dto.OwnerMenuDto, error) { // 判断redis是否存储 key := keys.GetManageKey(ctx, keys.OwnerMenus, roleID) bs, err := b.redis.GetBytes(ctx, key) if err == nil { var res map[string]*dto.OwnerMenuDto if err := json.Unmarshal(bs, &res); err == nil { return res, nil } } return b.SetOwnerMapMenuByRoleID(ctx, roleID) } func (b *menuBiz) SetOwnerMapMenuByRoleID(ctx context.Context, roleID int32) (map[string]*dto.OwnerMenuDto, error) { result := make(map[string]*dto.OwnerMenuDto) menus, err := b.ownerMenusByRoleID(ctx, roleID) if err != nil { return result, err } for _, menu := range menus { result[menu.Url] = &dto.OwnerMenuDto{ ID: menu.ID, DisplayName: menu.DisplayName, Url: menu.Url, ParentID: menu.ParentID, Avatar: menu.Avatar, Style: menu.Style, IsList: menu.IsList, } } bs, err := json.Marshal(result) if err != nil { return nil, err } key := keys.GetManageKey(ctx, keys.OwnerMenus, roleID) _ = redis.Set(ctx, key, bs, time.Hour*6) return result, nil } func (b *menuBiz) ownerMenusByRoleID(ctx context.Context, roleID int32) ([]*db.SysMenu, error) { // 判断当前用户是否有vip角色 role, err := b.store.GetSysRole(ctx, roleID) if err != nil { return nil, err } var e error var menus []*db.SysMenu if role.Vip { // vip 用户 menus, e = b.store.AllSysMenu(ctx) if e != nil { return nil, err } } else { // not vip menus, e = b.store.ListSysMenuByRoleID(ctx, roleID) if e != nil { return nil, err } } return menus, nil } func convertToMenuUIDto(data []*db.RecursiveSysMenusRow) []*db.SysMenu { var res []*db.SysMenu for _, item := range data { temp := &db.SysMenu{ ID: item.ID, Name: item.Name, DisplayName: item.DisplayName, Url: item.Url, Type: item.Type, ParentID: item.ParentID, ParentPath: item.ParentPath, Avatar: item.Avatar, Style: item.Style, Visible: item.Visible, IsList: item.IsList, Status: item.Status, Sort: item.Sort, CreatedAt: item.CreatedAt, UpdatedAt: item.UpdatedAt, } res = append(res, temp) } return res } func convertToMenuUIDto2(data []*db.RecursiveSysMenusByRoleIDRow) []*db.SysMenu { var res []*db.SysMenu for _, item := range data { temp := &db.SysMenu{ ID: item.ID, Name: item.Name, DisplayName: item.DisplayName, Url: item.Url, Type: item.Type, ParentID: item.ParentID, ParentPath: item.ParentPath, Avatar: item.Avatar, Style: item.Style, Visible: item.Visible, IsList: item.IsList, Status: item.Status, Sort: item.Sort, CreatedAt: item.CreatedAt, UpdatedAt: item.UpdatedAt, } res = append(res, temp) } return res } func convertToUITree(data []*db.SysMenu, parentID int32) []*dto.MenuUIDto { var root []*dto.MenuUIDto for _, item := range data { if item.ParentID == parentID { if item.IsList { temp := &dto.MenuUIDto{ ID: strings.ToLower(item.Url), Title: item.DisplayName, Icon: item.Avatar, Type: 1, OpenType: "_iframe", // OpenType: "_component", Href: item.Url, } root = append(root, temp) } else { temp := &dto.MenuUIDto{ ID: strconv.Itoa(int(item.ID)), Title: item.DisplayName, Icon: item.Avatar, Type: 0, } temp.Children = convertToUITree(data, item.ID) root = append(root, temp) } } } return root } func uniqueSysMenus(sm []*db.SysMenu) []*db.SysMenu { res := make([]*db.SysMenu, 0) // 返回的新切片 m1 := make(map[int32]byte) // 用来去重的临时map for _, v := range sm { if _, ok := m1[v.ID]; !ok { m1[v.ID] = 1 res = append(res, v) } } return res }