Some checks failed
Build and Deploy (service.xpcool.com) / build-and-deploy (push) Failing after 5m7s
- 新增 9 张房屋相关数据表(社区/楼宇/房源/价格快照/交易/设施/社区设施/学区/偏好) - 添加菜单权限种子数据并绑定超级管理员角色 - 生成 DAO 层代码和实体对象 - 实现房屋模块 API 接口(社区/房源/看板)和控制器服务层 - 支持多平台软关联匹配、笋盘标记和低可信度标记功能 - 更新超级管理员账号为 xxcool/xxCool@2026 - 调整 RBAC 菜单结构,移除管理员管理功能,新增日志管理菜单 - 修复 RBAC 安全漏洞,确保禁用角色权限失效 - 重构认证模块,将登录相关接口迁移到统一包结构下 - 移除废弃的管理模块和工具类接口定义 - 为通用工具包添加中文注释和文档说明
132 lines
4.2 KiB
Go
132 lines
4.2 KiB
Go
package admin_system_menu_manage
|
|
|
|
import (
|
|
"context"
|
|
"sort"
|
|
|
|
"github.com/gogf/gf/v2/errors/gerror"
|
|
|
|
"service.xpcool.com/internal/consts"
|
|
"service.xpcool.com/internal/dao"
|
|
"service.xpcool.com/internal/library/response"
|
|
"service.xpcool.com/internal/model/do"
|
|
"service.xpcool.com/internal/model/dto"
|
|
"service.xpcool.com/internal/model/entity"
|
|
)
|
|
|
|
// IMenuManage 管理菜单树(菜单 + 按钮权限)。
|
|
type IMenuManage interface {
|
|
Tree(context.Context) ([]*dto.MenuNode, error)
|
|
Create(context.Context, dto.MenuCreateInput) (uint64, error)
|
|
Update(context.Context, dto.MenuUpdateInput) error
|
|
Delete(context.Context, uint64) error
|
|
}
|
|
|
|
type menuManage struct{}
|
|
|
|
var localMenuManage IMenuManage
|
|
|
|
func NewMenuManage() IMenuManage { return &menuManage{} }
|
|
|
|
func MenuManage() IMenuManage {
|
|
if localMenuManage == nil {
|
|
panic("MenuManage implementation not registered")
|
|
}
|
|
return localMenuManage
|
|
}
|
|
func RegisterMenuManage(i IMenuManage) { localMenuManage = i }
|
|
|
|
// ---------------------- Menu manage ----------------------
|
|
|
|
func (s *menuManage) Tree(ctx context.Context) ([]*dto.MenuNode, error) {
|
|
var list []entity.AdminMenu
|
|
if err := dao.AdminMenu.Ctx(ctx).OrderAsc("sort").Scan(&list); err != nil {
|
|
return nil, gerror.Wrap(err, "query menus")
|
|
}
|
|
byID := make(map[uint64]*dto.MenuNode, len(list))
|
|
for i := range list {
|
|
m := &list[i]
|
|
byID[m.Id] = &dto.MenuNode{
|
|
Id: m.Id, ParentId: m.ParentId, Name: m.Name, Icon: m.Icon, Type: m.Type,
|
|
Path: m.Path, Component: m.Component, Permission: m.Permission,
|
|
Sort: m.Sort, Status: m.Status, Hidden: m.Hidden,
|
|
}
|
|
}
|
|
var roots []*dto.MenuNode
|
|
for i := range list {
|
|
m := &list[i]
|
|
node := byID[m.Id]
|
|
if m.ParentId == 0 {
|
|
roots = append(roots, node)
|
|
} else if p, ok := byID[m.ParentId]; ok {
|
|
p.Children = append(p.Children, node)
|
|
}
|
|
}
|
|
sort.Slice(roots, func(i, j int) bool { return roots[i].Sort < roots[j].Sort })
|
|
for _, r := range roots {
|
|
sortMenuChildren(r)
|
|
}
|
|
return roots, nil
|
|
}
|
|
|
|
func sortMenuChildren(n *dto.MenuNode) {
|
|
sort.Slice(n.Children, func(i, j int) bool { return n.Children[i].Sort < n.Children[j].Sort })
|
|
for _, c := range n.Children {
|
|
sortMenuChildren(c)
|
|
}
|
|
}
|
|
|
|
func (s *menuManage) Create(ctx context.Context, in dto.MenuCreateInput) (uint64, error) {
|
|
count, err := dao.AdminMenu.Ctx(ctx).Where(do.AdminMenu{Permission: in.Permission}).Count()
|
|
if err != nil {
|
|
return 0, gerror.Wrap(err, "check menu permission")
|
|
}
|
|
if count > 0 {
|
|
return 0, response.Error(consts.CodeInvalidParam, "permission already exists")
|
|
}
|
|
id, err := dao.AdminMenu.Ctx(ctx).Data(do.AdminMenu{
|
|
ParentId: in.ParentId, Name: in.Name, Icon: in.Icon, Type: in.Type, Path: in.Path,
|
|
Component: in.Component, Permission: in.Permission, Sort: in.Sort, Status: in.Status, Hidden: in.Hidden,
|
|
}).InsertAndGetId()
|
|
if err != nil {
|
|
return 0, gerror.Wrap(err, "insert menu")
|
|
}
|
|
return uint64(id), nil
|
|
}
|
|
|
|
func (s *menuManage) Update(ctx context.Context, in dto.MenuUpdateInput) error {
|
|
count, err := dao.AdminMenu.Ctx(ctx).Where("permission = ? AND id != ?", in.Permission, in.Id).Count()
|
|
if err != nil {
|
|
return gerror.Wrap(err, "check menu permission")
|
|
}
|
|
if count > 0 {
|
|
return response.Error(consts.CodeInvalidParam, "permission already exists")
|
|
}
|
|
_, err = dao.AdminMenu.Ctx(ctx).Where(do.AdminMenu{Id: in.Id}).Data(do.AdminMenu{
|
|
ParentId: in.ParentId, Name: in.Name, Icon: in.Icon, Type: in.Type, Path: in.Path,
|
|
Component: in.Component, Permission: in.Permission, Sort: in.Sort, Status: in.Status, Hidden: in.Hidden,
|
|
}).Update()
|
|
if err != nil {
|
|
return gerror.Wrap(err, "update menu")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (s *menuManage) Delete(ctx context.Context, id uint64) error {
|
|
// 删除前检查是否存在子节点。
|
|
cnt, err := dao.AdminMenu.Ctx(ctx).Where(do.AdminMenu{ParentId: id}).Count()
|
|
if err != nil {
|
|
return gerror.Wrap(err, "check menu children")
|
|
}
|
|
if cnt > 0 {
|
|
return response.Error(consts.CodeInvalidParam, "delete children first")
|
|
}
|
|
if _, err = dao.AdminMenu.Ctx(ctx).Where(do.AdminMenu{Id: id}).Delete(); err != nil {
|
|
return gerror.Wrap(err, "delete menu")
|
|
}
|
|
if _, err = dao.AdminRoleMenu.Ctx(ctx).Unscoped().Where(do.AdminRoleMenu{MenuId: id}).Delete(); err != nil {
|
|
return gerror.Wrap(err, "delete role menu bindings")
|
|
}
|
|
return nil
|
|
}
|