跳转到正文

菜单管理

菜单用于描述客户端导航,并以 code 对接认证模块名称。先按快速开始引入管理端 Controller,再维护菜单和角色授权。

接口约定

本模块 HTTP 接口返回 ResultModel<T>,业务数据位于 data;默认成功业务码为 00000,外层另有 successmessagetraceIdt。状态修改、排序和绑定操作使用无参数的 R.success(),虽然方法泛型为 Boolean,成功时也没有 true 业务值。删除接口显式返回 data=true

菜单 ID、角色 ID、关系 ID、用户 ID 的 Java 类型均为 LongBase 默认 MVC JSON 将包装类型 Long 输出为字符串,应用覆盖转换器时以实际协议为准。前端应保留完整精度,示例以十进制字符串提交 ID,不应转换成可能丢精度的 JavaScript Number。

公共响应与失败标识的边界见 Base 响应约定,不能仅根据 HTTP 成功状态或 success=true 判断业务成功。

分页使用 pagerows:默认第 1 页、每页 10 条,rows 最大 100。结果包含 data.pagerowstotallistisLastPagekeywords 虽继承自基础 Query,本模块没有配置对应搜索字段,不产生关键字过滤;公共行为见 Base Business 查询与分页

完整 VO 的创建时间以及菜单、角色的修改时间使用 LocalDateTime,格式为 yyyy-MM-dd HH:mm:ss,注解标注 GMT+8;它们不是 Unix 时间戳。数据库列为 datetime,应用需统一数据库与 JVM 的时间口径。创建与修改人字段取决于应用审计填充,不能仅凭调用 CRUD 保证这些字段非空。MapVo 是轻量业务视图,不含创建、修改审计字段。

管理端请求不会自动将 clientId 覆盖为会话客户端;缺少客户端条件时可跨客户端查询,按 ID 操作也不校验所属客户端。需要客户端隔离的后台应在应用入口补齐授权范围校验。

查询与维护接口

以下路径统一加前缀 /api/admin/system/menu,权限模块编码为 system-menu。表中同一格的多项操作权限必须同时满足。

方法与路径请求体返回业务数据操作权限
POST /pageSystemMenuQueryPageModel<SystemMenuVo>查询
POST /treeSystemMenuQueryTreeNode<SystemMenuMapVo>[]查询
GET /{menuId}SystemMenuVo查看详情、查询
POST /SystemMenuDtoSystemMenuVo新增、查询
PUT /{menuId}SystemMenuDtoSystemMenuVo修改、查询
DELETE /{menuId}true,需要二次确认删除、查询
PUT /disable/{menuId}/{disable}修改、查询
PUT /show/{menuId}/{show}修改、查询
PUT /advanced/sortSystemMenuAdvancedSortForm高级排序、修改、查询

菜单管理没有独立的 /all/map、批量删除接口;App 的 /all当前用户查询

查询条件与树结构

json
{
  "page": 1,
  "rows": 10,
  "clientId": "web",
  "title": "报表",
  "isDisable": 0
}
条件行为
codetitle非空白时模糊匹配
clientId非空白时精确匹配
parentId非空时精确匹配父级 ID;传 null 表示不限制,并非只取根节点
isDisableisShow非空时精确匹配整数状态

管理端 Query 查询按 createTimeid 倒序,树接口先查询再组树,不分页,也不自动补齐被条件过滤掉的祖先。节点为 {"item":{...菜单字段...},"children":[...]};父节点不在结果集合中的节点会成为根节点。children 可为空值。

菜单表单和字段

SystemMenuDto 用于新增和修改。菜单 VO 包含下表业务字段以及审计字段、version;MapVo 包含下表除 memo 外的业务字段。

字段含义与当前校验
code菜单编码,必填,最多 50 字符;认证按此值定位模块
title标题,必填,最多 8 字符
clientId客户端标识,必填,最多 32 字符
parentId父菜单 ID,根节点可为 null
pathicon路由和图标元数据,由前端解释
isDisable0 可用、1 禁用;执行 DTO 校验时缺省为 0
isShow0 隐藏、1 显示;执行 DTO 校验时缺省为 1,App 查询不据此过滤
permission菜单可配置的操作字符串,如 查询,新增;不会自动写入角色授权
sortOrder排序值,执行 DTO 校验时缺省为 0
chainNamechainIds逗号分隔的祖先链名称与 ID,由调用方维护
memo备注;当前 DTO 新增转换时不会复制该值,修改已有实体时才复制

isDisableisShow 会对输入做 % 2,不是严格的 0/1 校验,调用方应只提交 01。完整修改也会应用缺省状态与排序值,不应把 PUT 当成仅更新已提交字段的 PATCH。parentIdpathiconpermissionchainNamechainIds 允许以空值覆盖已有值。

菜单编码没有数据库唯一约束,服务也未检查同客户端编码重复。为使认证按模块定位唯一菜单,应用应保证同一 clientId 下的 code 唯一。

层级校验

修改时只有 chainIds 非空白才检查父节点不是自身、链中不含自身,以及名称链和 ID 链长度一致。chainIds 为空时会跳过这些检查;新增只做基础字段校验。

服务不会自动计算链字段,也未检查祖先链真实性、跨客户端父节点或完整环路。应用应先验证父节点及整条祖先链,再同步写入层级字段;移动父节点时还需自行维护后代链信息。

修改状态与排序

HTTP 状态路径必须带 disableshow,只使用 01。Service 的对应方法支持传 null 切换已有状态,但 HTTP 没有省略状态值的路由,不能通过空路径触发切换。

高级排序请求示例,替换为实际菜单 ID:

json
{
  "itemList": [
    { "id": "10001", "sort": 10 },
    { "id": "10002", "sort": 20 }
  ]
}

表单要求非空列表,每项 idsort 不能为 null。请求字段是 sort,最终写入菜单的 sortOrder;不会修改父节点,也不重算连续序号。服务逐项更新,未声明整批事务或检查各次更新行数。

目前管理端查询按创建时间和 ID 倒序,App 菜单查询没有显式排序,均未按 sortOrder 排序。前端如需按排序值展示,应在平铺列表或每一层树节点中自行排序。排序写入本身不刷新权限缓存;菜单新增、修改、删除和显隐/禁用操作会刷新全局权限缓存时间戳。

删除及二次确认

管理端菜单、角色和角色权限删除均标记二次确认。其装配要求 Servlet/AOP 相关类、StoreClientStoreLockManager,且确认开关启用。满足默认配置时,首次 DELETE 返回业务码 C0001 和确认提示;客户端取 data.keydata.token,用户确认后在有效期内以相同身份、方法、地址、参数重发,并添加该请求头。默认有效期为 30 秒,应以响应的头名与令牌为准。

菜单删除使用逻辑删除,只删除该菜单记录,不会级联删除子菜单和角色权限记录。原有子菜单可能因父节点不再出现在结果中而成为根节点。确认提示中的“所有资料会被删除”不能视为级联清理承诺。

接口不以更新或删除影响行数决定成功,data=true 不能证明目标原先存在。角色删除的关系清理与缓存边界见角色与授权