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" ) func CreateSysMenu(ctx context.Context, arg *db.CreateSysMenuParams) (*db.SysMenu, error) { return db.Engine.CreateSysMenu(ctx, arg) } func UpdateSysMenu(ctx context.Context, arg *db.UpdateSysMenuParams) (*db.SysMenu, error) { return db.Engine.UpdateSysMenu(ctx, arg) } func GetSysMenu(ctx context.Context, id int32) (*db.SysMenu, error) { return db.Engine.GetSysMenu(ctx, id) } func GetSysMenuByUrl(ctx context.Context, url string) (*db.SysMenu, error) { return db.Engine.GetSysMenuByUrl(ctx, url) } func ListSysMenuByRoleID(ctx context.Context, roleID int32) ([]*db.SysMenu, error) { return db.Engine.ListSysMenuByRoleID(ctx, roleID) } func AllMenusCache(ctx context.Context) ([]*db.SysMenu, error) { key := keys.GetManageKey(ctx, keys.AllMenus) b, err := redis.GetBytes(ctx, key) if err == nil { var res []*db.SysMenu if err := json.Unmarshal(b, &res); err == nil { return res, nil } } all, err := db.Engine.AllSysMenu(ctx) if err != nil { return nil, err } b, err = json.Marshal(all) if err != nil { return nil, err } _ = redis.Set(ctx, key, b, time.Hour*6) return all, nil } func ListMenuTree(ctx context.Context) ([]*db.SysMenuDto, error) { all, err := AllMenusCache(ctx) if err != nil { return nil, err } return toTreeSysMenu(0, all), nil } func ListMenuByRoles(ctx context.Context, roles []*db.SysRole) ([]*db.SysMenu, error) { // 判断角色是否有vip var vip bool for _, item := range roles { if item.Vip { vip = true break } } var err error var userMenus []*db.SysMenu if vip { userMenus, err = AllMenusCache(ctx) if err != nil { return nil, err } } else { for _, item := range roles { ums, err := db.Engine.ListSysMenuByRoleID(ctx, item.ID) if err != nil { return nil, err } userMenus = append(userMenus, ums...) } } return userMenus, nil } func IListMenuByUserID(ctx context.Context, userID int32) ([]*db.SysMenu, error) { // 判断redis是否存储 key := keys.GetManageKey(ctx, keys.AdminMenus, userID) b, err := redis.GetBytes(ctx, key) if err == nil { var res []*db.SysMenu if err := json.Unmarshal(b, &res); err == nil { return res, nil } } return SetListMenuByUserID(ctx, userID) } func SetListMenuByUserID(ctx context.Context, userID int32) ([]*db.SysMenu, error) { // 判断当前用户是否有vip角色 role, err := db.Engine.GetSysRoleByUserID(ctx, userID) if err != nil { return nil, err } var e error var menus []*db.SysMenu if role.Vip { // vip 用户 menus, e = db.Engine.AllSysMenu(ctx) if e != nil { return nil, err } } else { // not vip menus, e = db.Engine.AllSysMenu(ctx) // db.Engine.ListSysMenuByUserID(ctx, userID) if e != nil { return nil, err } } b, err := json.Marshal(menus) if err != nil { return nil, err } key := keys.GetManageKey(ctx, keys.AdminMenus, userID) _ = redis.Set(ctx, key, b, time.Hour*6) return menus, nil } func MapOwnerMenuByRoleID(ctx context.Context, roleID int32) (map[string]*dto.OwnerMenuDto, error) { // 判断redis是否存储 key := keys.GetManageKey(ctx, keys.OwnerMenus, roleID) b, err := redis.GetBytes(ctx, key) if err == nil { var res map[string]*dto.OwnerMenuDto if err := json.Unmarshal(b, &res); err == nil { return res, nil } } return SetOwnerMapMenuByRoleID(ctx, roleID) } func ListOwnerMenuByRoleID(ctx context.Context, roleID int32) ([]*dto.OwnerMenuDto, error) { // 判断redis是否存储 key := keys.GetManageKey(ctx, keys.OwnerMenus, roleID) b, err := redis.GetBytes(ctx, key) if err == nil { var res []*dto.OwnerMenuDto if err := json.Unmarshal(b, &res); err == nil { return res, nil } } return SetOwnerListMenuByRoleID(ctx, roleID) } func ownerMenusByRoleID(ctx context.Context, roleID int32) ([]*db.SysMenu, error) { // 判断当前用户是否有vip角色 role, err := db.Engine.GetSysRole(ctx, roleID) if err != nil { return nil, err } var e error var menus []*db.SysMenu if role.Vip { // vip 用户 menus, e = db.Engine.AllSysMenu(ctx) if e != nil { return nil, err } } else { // not vip menus, e = db.Engine.ListSysMenuByRoleID(ctx, roleID) if e != nil { return nil, err } } return menus, nil } func SetOwnerListMenuByRoleID(ctx context.Context, roleID int32) ([]*dto.OwnerMenuDto, error) { menus, err := 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, }) } b, err := json.Marshal(res) if err != nil { return nil, err } key := keys.GetManageKey(ctx, keys.OwnerMenus, roleID) _ = redis.Set(ctx, key, b, time.Hour*6) return res, nil } func SetOwnerMapMenuByRoleID(ctx context.Context, roleID int32) (map[string]*dto.OwnerMenuDto, error) { result := make(map[string]*dto.OwnerMenuDto) menus, err := 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, } } b, err := json.Marshal(result) if err != nil { return nil, err } key := keys.GetManageKey(ctx, keys.OwnerMenus, roleID) _ = redis.Set(ctx, key, b, time.Hour*6) return result, nil } // RecursiveSysMenus 递归查询菜单 (pear layui 展示菜单的格式) func RecursiveSysMenus(ctx context.Context, roleID int32) ([]*dto.MenuUIDto, error) { // 判断redis是否存储 key := keys.GetManageKey(ctx, keys.RecursiveMenus, roleID) b, err := redis.GetBytes(ctx, key) if err == nil { var res []*dto.MenuUIDto if err := json.Unmarshal(b, &res); err == nil { return res, nil } } return SetRecursiveSysMenus(ctx, roleID) } func SetRecursiveSysMenus(ctx context.Context, roleID int32) ([]*dto.MenuUIDto, error) { // 判断当前用户是否有vip角色 role, err := db.Engine.GetSysRole(ctx, roleID) if err != nil { return nil, err } var menus []*db.SysMenu if role.Vip { // vip 用户 all, err := db.Engine.RecursiveSysMenus(ctx) if err != nil { return nil, err } menus = convertToMenuUIDto(all) } else { // not vip all, err := db.Engine.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) b, err := json.Marshal(tree) if err != nil { return nil, err } key := keys.GetManageKey(ctx, keys.RecursiveMenus, roleID) _ = redis.Set(ctx, key, b, time.Hour*6) return tree, 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", 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 } func ToTreeMenu(ctx context.Context, id int, hasRoot bool) ([]*dto.TreeDto, error) { all, err := AllMenusCache(ctx) if err != nil { return nil, err } if hasRoot { root := getSysMenuRootParentId(int32(id), all) if root == nil { root = &dto.TreeDto{ ID: 0, Title: "根节点", } } root.Children = toDtoTreeSysMenu(int32(id), all) return []*dto.TreeDto{root}, nil } return toDtoTreeSysMenu(int32(id), all), nil } func RefreshMenus(ctx context.Context) error { key := keys.GetManageKey(ctx, keys.AllMenus) all, err := db.Engine.AllSysMenu(ctx) if err != nil { return err } b, err := json.Marshal(all) if err != nil { return err } err = redis.Set(ctx, key, b, time.Hour*6) return err } func getSysMenuRootParentId(parentId int32, data []*db.SysMenu) *dto.TreeDto { for _, v := range data { if v.ID == parentId { return &dto.TreeDto{ ID: int(v.ID), Title: v.Name, } } } return nil } func toTreeSysMenu(parentId int32, data []*db.SysMenu) []*db.SysMenuDto { var res []*db.SysMenuDto for _, v := range data { if v.ParentID == parentId { item := db.SysMenuDto{} item.ID = v.ID item.Name = v.Name item.DisplayName = v.DisplayName item.Url = v.Url item.Type = v.Type item.ParentID = v.ParentID item.ParentPath = v.ParentPath item.Avatar = v.Avatar item.Style = v.Style item.Visible = v.Visible item.IsList = v.IsList item.Status = v.Status item.Sort = v.Sort item.CreatedAt = v.CreatedAt item.UpdatedAt = v.UpdatedAt item.Children = toTreeSysMenu(v.ID, data) res = append(res, &item) } } return res } func toDtoTreeSysMenu(parentId int32, data []*db.SysMenu) []*dto.TreeDto { var res []*dto.TreeDto for _, v := range data { if v.ParentID == parentId { item := dto.TreeDto{} item.ID = int(v.ID) item.Title = v.Name item.Children = toDtoTreeSysMenu(v.ID, data) res = append(res, &item) } } return res } func SetMenuViewData(ctx context.Context, roleID int32) ([]*dto.SetMenuDto, error) { // 获取该用户已经有的权限 hs, err := db.Engine.ListSysMenuIDByRoleID(ctx, roleID) if err != nil { return nil, err } all, err := AllMenusCache(ctx) if err != nil { return nil, err } return toSetMenuTree(all, hs, 0), nil } func toSetMenuTree(data []*db.SysMenu, ids []int32, parentID int32) []*dto.SetMenuDto { var res []*dto.SetMenuDto for _, v := range data { if v.ParentID == parentID { isSelect := hasValueInArray(ids, v.ID) if v.IsList { item := dto.SetMenuDto{ ID: v.ID, Name: v.DisplayName, Link: v.Type, IsList: v.IsList, IsSelect: isSelect, } item.Items = []*dto.SetMenuDto{ { ID: v.ID, Name: "列表", Link: "btn", IsList: false, IsSelect: isSelect, Items: toSetMenuTree(data, ids, v.ID), }, } item.Items = append(item.Items, toSetMenuTree(data, ids, v.ID)...) res = append(res, &item) } else { item := dto.SetMenuDto{ ID: v.ID, Name: v.DisplayName, Link: v.Type, IsList: v.IsList, IsSelect: isSelect, Items: toSetMenuTree(data, ids, v.ID), } res = append(res, &item) } } } return res } func hasValueInArray(data []int32, id int32) bool { for _, v := range data { if id == v { return true } } return false }