# 用户服务接口契约审计修复(错误码下移 Service + Map→VO + 角色守卫规范化)— 修改接口 — 管理后台 > 变更类型:⚠️ 部分行为收紧(错误码规范化 + 响应结构稳定化),无破坏性字段删除 > 端类型:管理后台(用户/系统管理) > 日期:2026-06-17 > 服务:hl-user-service > PR:https://git.1814.love:8443/wx/HL/pulls/3924 --- ## ⚠️ 关键说明 用接口契约语义审计工作流全量扫描用户服务(hl-user-service)全部 Controller,逐端点比对「Swagger `@ApiOperation` 声明的契约 ⨯ 实际实现 ⨯ 业务规则」,对抗复核后修复一批「接口能跑但返回值/错误码/落库逻辑与契约不符」。已合并 dev-v3、部署测试服、网关 9443 + 真 admin token 实测(`/admin/role`、`/admin/menu/tree` 返回 VO 结构、双实例 totalCodes=282 健康)、本地全量 2793 单测零新增回归。 下面只列**与前端对接相关**的变更。最影响前端的是第 1 节(部分管理端接口的鉴权失败由裸 403/字符串改为业务错误码)。 --- ## 1. 角色守卫规范化:非超管/非管理员失败改为业务错误码(前端按 Result.code 处理) 平台 HTTP 始终 200,业务码在 `Result.code`。系统管理类接口此前部分用裸 403 / 字符串提示拦截越权,本次统一下移 Service 层并改为业务错误码,行为与 notes 文档对齐。 | 接口 | 方法 | 变更错误码 | 触发场景 | |---|---|---|---| | 完整菜单树 | GET `/admin/menu/tree` | **200307** | 非 SUPER_ADMIN 调用(原行为允许 ADMIN,现严格仅 SUPER_ADMIN,与 notes「仅 SUPER_ADMIN」一致) | | 角色列表 | GET `/admin/role` | **200313** | 非 SUPER_ADMIN/非 ADMIN 调用(原裸 403,现业务码「仅管理员或超级管理员可执行」) | | 创建/编辑/删除角色、分配菜单 | POST/PUT/DELETE `/admin/role/**` | **200307** | 非 SUPER_ADMIN(原裸 403,现业务码) | | 删除内置角色 | DELETE `/admin/role/{roleId}` | **210104** | 删除 SUPER_ADMIN 等系统预置角色(兑现「内置角色不可删除」契约) | > 前端处理:以上接口鉴权/业务失败请按 `Result.code` 判断(200307=仅超管、200313=仅管理员或超管、210104=内置角色不可删除),不要再依赖 HTTP 403 或固定文案。 --- ## 2. 系统字典/菜单:新增业务错误码(原 404/400 → 业务码) | 接口 | 方法 | 变更错误码 | 触发场景 | |---|---|---|---| | 字典数据编辑/删除/查询 | `/admin/dict/data/**` | **210404** | 字典数据项不存在(原 404,现业务码「字典数据不存在」) | | 菜单创建/编辑(类型校验) | POST/PUT `/admin/menu/**` | **210204** | menuType 不在白名单(D/M/B),原通用错误,现稳定业务码 | | 菜单创建/编辑(状态校验) | POST/PUT `/admin/menu/**` | **210205** | status 不属于 common_status 字典(ACTIVE/INACTIVE) | --- ## 3. 响应结构稳定化:Map → 强类型 VO(字段名不变,类型更稳定) 以下接口此前返回 `Map`,本次改为强类型 VO,**字段名与层级不变**,前端无需改动,仅类型更稳定可预期: | 接口 | 方法 | 响应类型 | |---|---|---| | 角色详情 | GET `/admin/role/{roleId}` | `Map` → `SysRoleDetailRespVO`(roleId/roleName/roleKey/sortOrder/status/menuIds 等) | | 完整菜单树 / 角色菜单树 / 我的菜单 | GET `/admin/menu/tree`、`/tree/role/{id}`、`/my` | `List` → `List`(递归 children,含 menuType/path/component/icon/visible/isCache/status) | | 角色列表 | GET `/admin/role` | 列表项统一为 `SysRoleRespVO` | > 大雪花 ID(roleId/menuId 等超 JS 安全范围的 Long)按平台口径以**字符串**返回(如 `"2049331915839700993"`),小 ID 仍为数字;前端按字符串/数字皆可解析处理。 --- ## 4. 其它对齐(前端基本无感) - 部分响应 VO 字段名/null 语义/缺字段与 Swagger 契约对齐;金额类字段补 `@JsonSerialize(ToStringSerializer)` 输出字符串。 - 安全:创建管理员/重置密码/登录接口的 Swagger notes 不再明文写出默认密码(仅文档措辞,接口行为不变)。 --- ## 暂缓项(本次未改,留作后续) - 内部接口 `/internal/user/admin/info/{adminId}` 的错误码微调(404→业务码)暂缓,本期回退保持原行为。 - 前端配置 `SECRET` 类型脱敏策略待产品确认,本期保持原行为(管理端详情/列表仍返真值供编辑)。