service.xpcool.com/internal/service/admin/system/menu/menu.go
夏犀麟 4b3c00270f
Some checks failed
Build and Deploy (service.xpcool.com) / build-and-deploy (push) Failing after 31s
feat(i18n): 中文化校验提示与服务层错误信息
将 api 层校验规则提示语、service 层 gerror.Wrap 与 response.Error
错误信息、panic 未注册提示统一改为中文,并同步中文化 cmd 路由注释
与变更记录。仅涉及注释、文档与字符串改动,无业务逻辑变更。
2026-09-13 23:22:46 +08:00

93 lines
2.5 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package admin_system_menu
import (
"context"
"sort"
"strings"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/text/gstr"
"service.xpcool.com/internal/dao"
"service.xpcool.com/internal/model/dto"
"service.xpcool.com/internal/model/entity"
)
type IAdminMenu interface {
// Routes 返回管理员的可见菜单树vben 路由项)。
Routes(context.Context, uint64) ([]*dto.RouteItem, error)
}
type adminMenu struct{}
func NewAdminMenu() IAdminMenu { return &adminMenu{} }
var localAdminMenu IAdminMenu
func AdminMenu() IAdminMenu {
if localAdminMenu == nil {
panic("AdminMenu 实现未注册")
}
return localAdminMenu
}
func RegisterAdminMenu(i IAdminMenu) { localAdminMenu = i }
// routeName 将权限码(如 "system:admin")转换为唯一的
// vben 路由名,如 "SystemAdmin"。
func routeName(permission string) string {
if permission == "" {
return ""
}
return gstr.CaseCamel(strings.ReplaceAll(permission, ":", "_"))
}
func (s *adminMenu) Routes(ctx context.Context, adminID uint64) ([]*dto.RouteItem, error) {
// 当前管理员所有启用角色r.status=1可见的菜单type=1含按钮行但不作为路由节点。
var list []entity.AdminMenu
if err := dao.AdminUserRole.Ctx(ctx).As("ur").
LeftJoin("admin_role r", "ur.role_id=r.id").
LeftJoin("admin_role_menu rm", "ur.role_id=rm.role_id").
LeftJoin("admin_menu m", "rm.menu_id=m.id").
Where("ur.admin_user_id", adminID).
Where("m.type", 1).
Where("m.status", 1).
Where("r.status", 1).
Where("m.deleted_at IS NULL").
Fields("m.*").
Scan(&list); err != nil {
return nil, gerror.Wrap(err, "查询管理员菜单路由失败")
}
byID := make(map[uint64]*dto.RouteItem, len(list))
for i := range list {
m := &list[i]
byID[m.Id] = &dto.RouteItem{
Name: routeName(m.Permission),
Path: m.Path,
Component: m.Component,
Meta: dto.RouteMeta{Title: m.Name, Icon: m.Icon, Order: m.Sort, HideInMenu: m.Hidden},
}
}
var roots []*dto.RouteItem
for i := range list {
m := &list[i]
item := byID[m.Id]
if m.ParentId == 0 {
roots = append(roots, item)
} else if p, ok := byID[m.ParentId]; ok {
p.Children = append(p.Children, item)
}
}
sort.Slice(roots, func(i, j int) bool { return roots[i].Meta.Order < roots[j].Meta.Order })
for _, r := range roots {
sortRouteChildren(r)
}
return roots, nil
}
func sortRouteChildren(r *dto.RouteItem) {
sort.Slice(r.Children, func(i, j int) bool { return r.Children[i].Meta.Order < r.Children[j].Meta.Order })
for _, c := range r.Children {
sortRouteChildren(c)
}
}