2
This commit is contained in:
457
internal/erpserver/service/v1/system/menu.go
Normal file
457
internal/erpserver/service/v1/system/menu.go
Normal file
@@ -0,0 +1,457 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"management/internal/db/model/dto"
|
||||
"management/internal/erpserver/model/system"
|
||||
"management/internal/erpserver/model/view"
|
||||
"management/internal/erpserver/repository"
|
||||
v1 "management/internal/erpserver/service/v1"
|
||||
"management/internal/pkg/know"
|
||||
"management/internal/pkg/redis"
|
||||
)
|
||||
|
||||
type menuService struct {
|
||||
redis redis.RedisCache
|
||||
store repository.Store
|
||||
repo system.MenuRepository
|
||||
rolesvc v1.RoleService
|
||||
rolemenusvc v1.RoleMenuService
|
||||
}
|
||||
|
||||
var _ v1.MenuService = (*menuService)(nil)
|
||||
|
||||
func NewMenuService(redis redis.RedisCache, store repository.Store, repo system.MenuRepository, rolesvc v1.RoleService, rolemenusvc v1.RoleMenuService) *menuService {
|
||||
return &menuService{
|
||||
redis: redis,
|
||||
store: store,
|
||||
repo: repo,
|
||||
rolesvc: rolesvc,
|
||||
rolemenusvc: rolemenusvc,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *menuService) Create(ctx context.Context, req *system.Menu) error {
|
||||
return s.repo.Create(ctx, req)
|
||||
}
|
||||
|
||||
func (s *menuService) Update(ctx context.Context, req *system.Menu) error {
|
||||
return s.repo.Update(ctx, req)
|
||||
}
|
||||
|
||||
func (s *menuService) Get(ctx context.Context, id int32) (*system.Menu, error) {
|
||||
return s.repo.Get(ctx, id)
|
||||
}
|
||||
|
||||
func (s *menuService) GetByUrl(ctx context.Context, url string) (*system.Menu, error) {
|
||||
return s.repo.GetByUrl(ctx, url)
|
||||
}
|
||||
|
||||
func (s *menuService) All(ctx context.Context) ([]*system.Menu, error) {
|
||||
key := know.GetManageKey(ctx, know.AllMenus)
|
||||
b, err := s.redis.GetBytes(ctx, key)
|
||||
if err == nil {
|
||||
var res []*system.Menu
|
||||
if err := json.Unmarshal(b, &res); err == nil {
|
||||
return res, nil
|
||||
}
|
||||
}
|
||||
|
||||
res, err := s.repo.All(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
b, err = json.Marshal(res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
_ = s.redis.Set(ctx, key, b, time.Hour*6)
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (s *menuService) ListMenuTree(ctx context.Context) ([]*view.MenuTree, error) {
|
||||
all, err := s.All(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return toListTree(0, all), nil
|
||||
}
|
||||
|
||||
func (s *menuService) ListByRoleID(ctx context.Context, roleID int32) ([]*dto.OwnerMenuDto, error) {
|
||||
key := know.GetManageKey(ctx, know.OwnerMenus, roleID)
|
||||
bs, err := s.redis.GetBytes(ctx, key)
|
||||
if err == nil {
|
||||
var res []*dto.OwnerMenuDto
|
||||
if err := json.Unmarshal(bs, &res); err == nil {
|
||||
return res, nil
|
||||
}
|
||||
}
|
||||
|
||||
return s.SetListByRoleID(ctx, roleID)
|
||||
}
|
||||
|
||||
func (s *menuService) SetListByRoleID(ctx context.Context, roleID int32) ([]*dto.OwnerMenuDto, error) {
|
||||
key := know.GetManageKey(ctx, know.OwnerMenus, roleID)
|
||||
menus, err := s.listByRoleID(ctx, roleID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res := toOwnerMenuDto(menus)
|
||||
b, err := json.Marshal(res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
_ = s.redis.Set(ctx, key, b, time.Hour*6)
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (s *menuService) ListByRoleIDToMap(ctx context.Context, roleID int32) (map[string]*dto.OwnerMenuDto, error) {
|
||||
key := know.GetManageKey(ctx, know.OwnerMenusMap, roleID)
|
||||
bs, err := s.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 s.SetListByRoleIDToMap(ctx, roleID)
|
||||
}
|
||||
|
||||
func (s *menuService) SetListByRoleIDToMap(ctx context.Context, roleID int32) (map[string]*dto.OwnerMenuDto, error) {
|
||||
key := know.GetManageKey(ctx, know.OwnerMenusMap, roleID)
|
||||
menus, err := s.listByRoleID(ctx, roleID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res := toOwnerMenuDtoMap(menus)
|
||||
b, err := json.Marshal(res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
_ = s.redis.Set(ctx, key, b, time.Hour*6)
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (s *menuService) OwerMenus(ctx context.Context, roleID int32) ([]*dto.MenuUIDto, error) {
|
||||
key := know.GetManageKey(ctx, know.AdminMenus, roleID)
|
||||
bs, err := s.redis.GetBytes(ctx, key)
|
||||
if err == nil {
|
||||
var res []*dto.MenuUIDto
|
||||
if err := json.Unmarshal(bs, &res); err == nil {
|
||||
return res, nil
|
||||
}
|
||||
}
|
||||
|
||||
return s.SetOwerMenus(ctx, roleID)
|
||||
}
|
||||
|
||||
func (s *menuService) SetOwerMenus(ctx context.Context, roleID int32) ([]*dto.MenuUIDto, error) {
|
||||
key := know.GetManageKey(ctx, know.AdminMenus, roleID)
|
||||
|
||||
menus, err := s.listByRoleID(ctx, roleID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res := convertToUITree(menus, 0)
|
||||
b, err := json.Marshal(res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
_ = s.redis.Set(ctx, key, b, time.Hour*6)
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (s *menuService) MenuViewData(ctx context.Context, roleID int32) ([]*dto.SetMenuDto, error) {
|
||||
// 获取该用户已经有的权限
|
||||
hs, err := s.listByRoleID(ctx, roleID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
all, err := s.All(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return toSetMenuTree(all, hs, 0), nil
|
||||
}
|
||||
|
||||
func (s *menuService) SetRoleMenu(ctx context.Context, roleID int32, rms []*system.RoleMenu) error {
|
||||
// 开启事务
|
||||
return s.store.TX(ctx, func(ctx context.Context) error {
|
||||
// 先删除该角色的所有权限
|
||||
err := s.rolemenusvc.DeleteByRoleID(ctx, roleID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 再添加该角色的所有权限
|
||||
return s.rolemenusvc.Create(ctx, rms)
|
||||
})
|
||||
}
|
||||
|
||||
func (s *menuService) RefreshCache(ctx context.Context) error {
|
||||
key := know.GetManageKey(ctx, know.AllMenus)
|
||||
res, err := s.All(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
b, err := json.Marshal(res)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_ = redis.Set(ctx, key, b, time.Hour*6)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *menuService) RebuildParentPath(ctx context.Context) error {
|
||||
return s.repo.RebuildParentPath(ctx)
|
||||
}
|
||||
|
||||
func (s *menuService) Tree(ctx context.Context, id int32) ([]*view.LayuiTree, error) {
|
||||
all, err := s.All(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.toTree(id, all), nil
|
||||
}
|
||||
|
||||
func (s *menuService) XmSelectTree(ctx context.Context, id int32) ([]*view.XmSelectTree, error) {
|
||||
all, err := s.All(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.toXmSelectTree(id, all), nil
|
||||
}
|
||||
|
||||
// listByRoleID 获取该角色所拥有的菜单集合
|
||||
func (s *menuService) listByRoleID(ctx context.Context, roleID int32) ([]*system.Menu, error) {
|
||||
role, err := s.rolesvc.Get(ctx, roleID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res, err := s.repo.All(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if role.Vip {
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// 通过角色获取所拥有的权限
|
||||
roleMenus, err := s.rolemenusvc.ListByRoleID(ctx, roleID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return findMenu(roleMenus, res), nil
|
||||
}
|
||||
|
||||
func (s *menuService) toTree(parentId int32, data []*system.Menu) []*view.LayuiTree {
|
||||
var res []*view.LayuiTree
|
||||
for _, v := range data {
|
||||
if v.ParentID == parentId {
|
||||
item := view.LayuiTree{}
|
||||
item.ID = strconv.FormatInt(int64(v.ID), 10)
|
||||
item.Title = v.Name
|
||||
item.Children = s.toTree(v.ID, data)
|
||||
if v.ParentID == 0 {
|
||||
item.Spread = true
|
||||
}
|
||||
res = append(res, &item)
|
||||
}
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
func (s *menuService) toXmSelectTree(parentId int32, data []*system.Menu) []*view.XmSelectTree {
|
||||
var res []*view.XmSelectTree
|
||||
for _, v := range data {
|
||||
if v.ParentID == parentId {
|
||||
item := view.XmSelectTree{
|
||||
Name: v.Name,
|
||||
Value: strconv.FormatInt(int64(v.ID), 10),
|
||||
Children: s.toXmSelectTree(v.ID, data),
|
||||
}
|
||||
res = append(res, &item)
|
||||
}
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
func findMenu(rms []*system.RoleMenu, ms []*system.Menu) []*system.Menu {
|
||||
var res []*system.Menu
|
||||
for _, rm := range rms {
|
||||
for _, m := range ms {
|
||||
if rm.MenuID == m.ID {
|
||||
res = append(res, m)
|
||||
}
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func toOwnerMenuDto(ms []*system.Menu) []*dto.OwnerMenuDto {
|
||||
var res []*dto.OwnerMenuDto
|
||||
for _, m := range ms {
|
||||
res = append(res, &dto.OwnerMenuDto{
|
||||
ID: m.ID,
|
||||
DisplayName: m.DisplayName,
|
||||
Url: m.Url,
|
||||
ParentID: m.ParentID,
|
||||
Avatar: m.Avatar,
|
||||
Style: m.Style,
|
||||
IsList: m.IsList,
|
||||
})
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func toOwnerMenuDtoMap(ms []*system.Menu) map[string]*dto.OwnerMenuDto {
|
||||
res := make(map[string]*dto.OwnerMenuDto)
|
||||
for _, m := range ms {
|
||||
res[m.Url] = &dto.OwnerMenuDto{
|
||||
ID: m.ID,
|
||||
DisplayName: m.DisplayName,
|
||||
Url: m.Url,
|
||||
ParentID: m.ParentID,
|
||||
Avatar: m.Avatar,
|
||||
Style: m.Style,
|
||||
IsList: m.IsList,
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func convertToUITree(data []*system.Menu, 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 toSetMenuTree(data []*system.Menu, ids []*system.Menu, 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 []*system.Menu, id int32) bool {
|
||||
for _, v := range data {
|
||||
if v.ID == id {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func toListTree(parentId int32, data []*system.Menu) []*view.MenuTree {
|
||||
var res []*view.MenuTree
|
||||
for _, v := range data {
|
||||
if v.ParentID == parentId {
|
||||
item := view.MenuTree{}
|
||||
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 = toListTree(v.ID, data)
|
||||
res = append(res, &item)
|
||||
}
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
Reference in New Issue
Block a user