新增后台管理
This commit is contained in:
		
							
								
								
									
										250
									
								
								app/main/api/internal/logic/admin_menu/getmenualllogic.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										250
									
								
								app/main/api/internal/logic/admin_menu/getmenualllogic.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,250 @@ | ||||
| package admin_menu | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| 	"sort" | ||||
| 	"strconv" | ||||
|  | ||||
| 	"tydata-server/app/main/api/internal/svc" | ||||
| 	"tydata-server/app/main/api/internal/types" | ||||
| 	"tydata-server/common/ctxdata" | ||||
| 	"tydata-server/common/xerr" | ||||
|  | ||||
| 	"github.com/Masterminds/squirrel" | ||||
| 	"github.com/bytedance/sonic" | ||||
| 	"github.com/pkg/errors" | ||||
| 	"github.com/samber/lo" | ||||
| 	"github.com/zeromicro/go-zero/core/logx" | ||||
| 	"github.com/zeromicro/go-zero/core/mr" | ||||
| ) | ||||
|  | ||||
| type GetMenuAllLogic struct { | ||||
| 	logx.Logger | ||||
| 	ctx    context.Context | ||||
| 	svcCtx *svc.ServiceContext | ||||
| } | ||||
|  | ||||
| func NewGetMenuAllLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetMenuAllLogic { | ||||
| 	return &GetMenuAllLogic{ | ||||
| 		Logger: logx.WithContext(ctx), | ||||
| 		ctx:    ctx, | ||||
| 		svcCtx: svcCtx, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (l *GetMenuAllLogic) GetMenuAll(req *types.GetMenuAllReq) (resp *[]types.GetMenuAllResp, err error) { | ||||
| 	userId, err := ctxdata.GetUidFromCtx(l.ctx) | ||||
| 	if err != nil { | ||||
| 		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取用户ID失败, %+v", err) | ||||
| 	} | ||||
|  | ||||
| 	// 使用MapReduceVoid并发获取用户角色 | ||||
| 	var roleIds []int64 | ||||
| 	var permissions []*struct { | ||||
| 		RoleId int64 | ||||
| 	} | ||||
|  | ||||
| 	type UserRoleResult struct { | ||||
| 		RoleId int64 | ||||
| 	} | ||||
|  | ||||
| 	err = mr.MapReduceVoid( | ||||
| 		func(source chan<- interface{}) { | ||||
| 			adminUserRoleBuilder := l.svcCtx.AdminUserRoleModel.SelectBuilder().Where(squirrel.Eq{"user_id": userId}) | ||||
| 			source <- adminUserRoleBuilder | ||||
| 		}, | ||||
| 		func(item interface{}, writer mr.Writer[*UserRoleResult], cancel func(error)) { | ||||
| 			builder := item.(squirrel.SelectBuilder) | ||||
| 			result, err := l.svcCtx.AdminUserRoleModel.FindAll(l.ctx, builder, "role_id DESC") | ||||
| 			if err != nil { | ||||
| 				cancel(errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取用户角色信息失败, %+v", err)) | ||||
| 				return | ||||
| 			} | ||||
|  | ||||
| 			for _, r := range result { | ||||
| 				writer.Write(&UserRoleResult{RoleId: r.RoleId}) | ||||
| 			} | ||||
| 		}, | ||||
| 		func(pipe <-chan *UserRoleResult, cancel func(error)) { | ||||
| 			for item := range pipe { | ||||
| 				permissions = append(permissions, &struct{ RoleId int64 }{RoleId: item.RoleId}) | ||||
| 			} | ||||
| 		}, | ||||
| 	) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	for _, permission := range permissions { | ||||
| 		roleIds = append(roleIds, permission.RoleId) | ||||
| 	} | ||||
|  | ||||
| 	// 使用MapReduceVoid并发获取角色菜单 | ||||
| 	var menuIds []int64 | ||||
| 	var roleMenus []*struct { | ||||
| 		MenuId int64 | ||||
| 	} | ||||
|  | ||||
| 	type RoleMenuResult struct { | ||||
| 		MenuId int64 | ||||
| 	} | ||||
|  | ||||
| 	err = mr.MapReduceVoid( | ||||
| 		func(source chan<- interface{}) { | ||||
| 			getRoleMenuBuilder := l.svcCtx.AdminRoleMenuModel.SelectBuilder().Where(squirrel.Eq{"role_id": roleIds}) | ||||
| 			source <- getRoleMenuBuilder | ||||
| 		}, | ||||
| 		func(item interface{}, writer mr.Writer[*RoleMenuResult], cancel func(error)) { | ||||
| 			builder := item.(squirrel.SelectBuilder) | ||||
| 			result, err := l.svcCtx.AdminRoleMenuModel.FindAll(l.ctx, builder, "id DESC") | ||||
| 			if err != nil { | ||||
| 				cancel(errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取角色菜单信息失败, %+v", err)) | ||||
| 				return | ||||
| 			} | ||||
|  | ||||
| 			for _, r := range result { | ||||
| 				writer.Write(&RoleMenuResult{MenuId: r.MenuId}) | ||||
| 			} | ||||
| 		}, | ||||
| 		func(pipe <-chan *RoleMenuResult, cancel func(error)) { | ||||
| 			for item := range pipe { | ||||
| 				roleMenus = append(roleMenus, &struct{ MenuId int64 }{MenuId: item.MenuId}) | ||||
| 			} | ||||
| 		}, | ||||
| 	) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	for _, roleMenu := range roleMenus { | ||||
| 		menuIds = append(menuIds, roleMenu.MenuId) | ||||
| 	} | ||||
|  | ||||
| 	// 使用MapReduceVoid并发获取菜单 | ||||
| 	type AdminMenuStruct struct { | ||||
| 		Id        int64 | ||||
| 		Pid       int64 | ||||
| 		Name      string | ||||
| 		Path      string | ||||
| 		Component string | ||||
| 		Redirect  struct { | ||||
| 			String string | ||||
| 			Valid  bool | ||||
| 		} | ||||
| 		Meta   string | ||||
| 		Sort   int64 | ||||
| 		Type   int64 | ||||
| 		Status int64 | ||||
| 	} | ||||
|  | ||||
| 	var menus []*AdminMenuStruct | ||||
|  | ||||
| 	err = mr.MapReduceVoid( | ||||
| 		func(source chan<- interface{}) { | ||||
| 			adminMenuBuilder := l.svcCtx.AdminMenuModel.SelectBuilder().Where(squirrel.Eq{"id": menuIds}) | ||||
| 			source <- adminMenuBuilder | ||||
| 		}, | ||||
| 		func(item interface{}, writer mr.Writer[*AdminMenuStruct], cancel func(error)) { | ||||
| 			builder := item.(squirrel.SelectBuilder) | ||||
| 			result, err := l.svcCtx.AdminMenuModel.FindAll(l.ctx, builder, "sort ASC") | ||||
| 			if err != nil { | ||||
| 				cancel(errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取菜单信息失败, %+v", err)) | ||||
| 				return | ||||
| 			} | ||||
|  | ||||
| 			for _, r := range result { | ||||
| 				menu := &AdminMenuStruct{ | ||||
| 					Id:        r.Id, | ||||
| 					Pid:       r.Pid, | ||||
| 					Name:      r.Name, | ||||
| 					Path:      r.Path, | ||||
| 					Component: r.Component, | ||||
| 					Redirect:  r.Redirect, | ||||
| 					Meta:      r.Meta, | ||||
| 					Sort:      r.Sort, | ||||
| 					Type:      r.Type, | ||||
| 					Status:    r.Status, | ||||
| 				} | ||||
| 				writer.Write(menu) | ||||
| 			} | ||||
| 		}, | ||||
| 		func(pipe <-chan *AdminMenuStruct, cancel func(error)) { | ||||
| 			for item := range pipe { | ||||
| 				menus = append(menus, item) | ||||
| 			} | ||||
| 		}, | ||||
| 	) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	// 转换为types.Menu结构并存储到映射表 | ||||
| 	menuMap := make(map[string]types.GetMenuAllResp) | ||||
| 	for _, menu := range menus { | ||||
| 		// 只处理状态正常的菜单 | ||||
| 		if menu.Status != 1 { | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		meta := make(map[string]interface{}) | ||||
| 		err = sonic.Unmarshal([]byte(menu.Meta), &meta) | ||||
| 		if err != nil { | ||||
| 			return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "解析菜单Meta信息失败, %+v", err) | ||||
| 		} | ||||
|  | ||||
| 		redirect := func() string { | ||||
| 			if menu.Redirect.Valid { | ||||
| 				return menu.Redirect.String | ||||
| 			} | ||||
| 			return "" | ||||
| 		}() | ||||
|  | ||||
| 		menuId := strconv.FormatInt(menu.Id, 10) | ||||
| 		menuMap[menuId] = types.GetMenuAllResp{ | ||||
| 			Name:      menu.Name, | ||||
| 			Path:      menu.Path, | ||||
| 			Redirect:  redirect, | ||||
| 			Component: menu.Component, | ||||
| 			Sort:      menu.Sort, | ||||
| 			Meta:      meta, | ||||
| 			Children:  make([]types.GetMenuAllResp, 0), | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// 按ParentId将菜单分组 | ||||
| 	menuGroups := lo.GroupBy(menus, func(item *AdminMenuStruct) int64 { | ||||
| 		return item.Pid | ||||
| 	}) | ||||
|  | ||||
| 	// 递归构建菜单树 | ||||
| 	var buildMenuTree func(parentId int64) []types.GetMenuAllResp | ||||
| 	buildMenuTree = func(parentId int64) []types.GetMenuAllResp { | ||||
| 		children := make([]types.GetMenuAllResp, 0) | ||||
|  | ||||
| 		childMenus, ok := menuGroups[parentId] | ||||
| 		if !ok { | ||||
| 			return children | ||||
| 		} | ||||
|  | ||||
| 		// 按Sort排序 | ||||
| 		sort.Slice(childMenus, func(i, j int) bool { | ||||
| 			return childMenus[i].Sort < childMenus[j].Sort | ||||
| 		}) | ||||
|  | ||||
| 		for _, childMenu := range childMenus { | ||||
| 			menuId := strconv.FormatInt(childMenu.Id, 10) | ||||
| 			if menu, exists := menuMap[menuId]; exists && childMenu.Status == 1 { | ||||
| 				// 递归构建子菜单 | ||||
| 				menu.Children = buildMenuTree(childMenu.Id) | ||||
| 				children = append(children, menu) | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		return children | ||||
| 	} | ||||
|  | ||||
| 	// 从根菜单开始构建(ParentId为0的是根菜单) | ||||
| 	menuTree := buildMenuTree(0) | ||||
|  | ||||
| 	return &menuTree, nil | ||||
| } | ||||
		Reference in New Issue
	
	Block a user