6.3 菜单管理
概述
菜单模块(goframe_menu,平台级表)统一承载两类节点:type=0 目录/菜单(进前端菜单树)与 type=1 权限节点(进后端 Perms 校验)。树形结构、防环校验、关联清理齐备。
接口清单
text
七件套:sys:menu:{page|list|detail|add|update|delete|batchDelete}
List 返回树形(IsTree + ParentOf)type 语义(关键概念)
| type | 名称 | 消费方 |
|---|---|---|
| 0 | 菜单/目录 | 前端菜单树(getMenuTree 过滤 type=0 且 status=0 且 hide=0) |
| 1 | 权限节点 | 后端 Perms 校验(LoadIdentity 过滤 type=1 且 status=0 且 hide=0) |
text
menu 行的关键列:
parent_id 父级(树形)
type 0-菜单 1-权限节点(注释枚举)
permission 权限码(sys:user:page 形式;type=1 必填)
status 0-启用(禁用节点不进树也不进 Perms)
hide 0-显示(hide=1 不进菜单树)
sort 排序hide 与 status 的区别(易错)
hide=1 的权限节点不生效:getMenuTree 与 LoadIdentity 都过滤 hide=0,hide=1 节点既不进菜单树也不进 Perms。"禁用权限"必须用 status,不能用 hide。
树形与守卫
text
List 树形:spec 声明 IsTree + ParentOf(DTO 含 Id/Children,叶子 Children 预置 [])
删除守卫 menuDeleteGuard:存在子菜单拒绝(1011)
关联清理 menuCleanRelations:删除菜单时同步清理 role_menu 引用
(批量删除同理)——防止悬挂授权
父级校验 menuParentGuard:parentId 不得指向自身或后代(防环)菜单树的消费(index.GetMenus)
text
getMenuTree:
1) 仅取 type=0 且 status=0 且 hide=0 的节点(按钮权限不进菜单树,
由 GetUser.permissions 下发)
2) 超管全量;其余 user→user_role→role_menu→menu.id IN(...) 授权过滤
3) 无角色返回空树([] 非 null)
4) 挂树规则:父节点不在授权集合内(未授权/顶级)一律挂根,避免菜单丢失
5) 排序 sort,id(稳定排序)与生成器的关系
代码生成器 createMenu 副作用自动创建:主菜单(type=0,挂 generator.parentMenuId 下)+ 权限节点(type=1,7 固定 + status/import/export 按需)。按 path+type 查重幂等。详见 10.8 实战案例。
管理建议
- 权限节点命名与 gmeta permission 严格一致(sys:{module小驼峰}:{action})
- 一个模块一个主菜单 + N 个权限节点,权限节点挂主菜单下
- 禁用节点用 status=2(保留数据可恢复);删除走软删 + 关联清理
- hide 只用于"菜单树隐藏但(当前实现下)不建议用于权限节点"——见上方警告