diff --git a/changelogs-v2/2026-08/24_6266_供应商审批记录业务展示字段调整-修改接口-管理后台.md b/changelogs-v2/2026-08/24_6266_供应商审批记录业务展示字段调整-修改接口-管理后台.md new file mode 100644 index 00000000..69c1bbce --- /dev/null +++ b/changelogs-v2/2026-08/24_6266_供应商审批记录业务展示字段调整-修改接口-管理后台.md @@ -0,0 +1,259 @@ +--- +schema: "hl-changelog/v2" +ticket: "6266" +title: "供应商审批记录业务展示字段调整" +consumer: "admin" +author: "lc(GIT)" +change_type: "修改接口" +backend_status: "deployed" +gateway_status: "verified" +frontend_status: "pending" +frontend_owner: "" +frontend_ref: "" +target_release: "" +verified_at: "" +status_note: "PR #6270 已合并 dev-v3,合并提交 f14544fe0 已随 Resource 双实例滚动部署到 TEST。审批记录新增供应商名称、供应商类型、操作人姓名和审批角色,隐藏四个技术字段,并把变更前后值、状态和历史原因转换为中文脱敏业务展示。管理端需同步调整表格列和字段绑定。" +updated_at: "2026-08-24" +base: "dev-v3" +--- + +# 供应商审批记录业务展示字段调整 + +## ⚠️ 破坏性变更 + +供应商详情的审批记录响应改为面向业务展示:新增供应商名称、供应商类型、操作人姓名和审批角色;不再返回变更记录 ID、字段名、审批日志 ID 和操作人 ID。管理端必须按本契约调整表格列,不能继续依赖已移除字段。 + +## 变更接口 + +| 方法 | 路径 | 权限 | 行为变化 | +|---|---|---|---| +| GET | `/admin/supplier/items/{supplierId}/approval-records/page` | `supplier:approval:read` | 调整分页记录的响应字段和展示语义;请求参数、分页结构及权限不变 | + +### 请求 + +```http +GET /admin/supplier/items/2091715622923657217/approval-records/page?page=1&pageSize=10 HTTP/1.1 +Host: api.test.1814.love:9443 +Authorization: Bearer +``` + +GET 请求无请求体。 + +#### 路径参数 + +| 参数 | 类型 | 必填 | 说明 | +|---|---|---:|---| +| `supplierId` | String | 是 | 供应商 ID | + +#### 查询参数 + +| 参数 | 类型 | 必填 | 默认值 | 说明 | +|---|---|---:|---|---| +| `page` | Integer | 否 | `1` | 页码,最小为 1;兼容别名 `pageNo` | +| `pageSize` | Integer | 否 | `20` | 每页条数,范围 1–100 | +| `approvalLogId` | String | 否 | — | 按关联审批日志 ID 精确筛选;仅为请求筛选条件,响应不再回传该字段 | +| `operationType` | String | 否 | — | `CREATE`、`UPDATE`、`ENABLE`、`DISABLE`、`DELETE` | +| `targetType` | String | 否 | — | 当前仅支持 `SUPPLIER` | +| `fieldName` | String | 否 | — | 按历史变更字段精确筛选;仅为请求筛选条件,响应不再回传该字段 | +| `status` | String | 否 | — | 以生命周期编码筛选:`DRAFT`、`VETTING`、`ACTIVE`、`SUSPENDED`、`FROZEN`、`BLACKLIST`、`ARCHIVED` | +| `from` | String | 否 | — | 开始时间,格式 `yyyy-MM-dd HH:mm:ss`;必须与 `to` 同时传入 | +| `to` | String | 否 | — | 结束时间,格式 `yyyy-MM-dd HH:mm:ss`;不得早于 `from` | +| `sortBy` | String | 否 | `createTime` | `createTime` 或 `changeLogId` | +| `sortDirection` | String | 否 | `DESC` | `ASC` 或 `DESC`,大小写均可 | + +## 响应字段变化 + +### 新增字段 + +| 字段 | 类型 | 空值语义 | 说明 | +|---|---|---|---| +| `supplierName` | String | 供应商存在时非空 | 当前供应商法定全称 | +| `supplierTypes` | Array | 无类型时 `[]` | 当前供应商全部类型,主类型优先;`typeCode` 为字典值,`typeName` 为运行时中文名称 | +| `operatorName` | String | 不返回 `null` | 优先返回操作人的企微姓名,其次为用户名;系统记录显示 `系统`,人员信息暂不可用时显示 `管理员#` | +| `operatorRole` | String | 不返回 `null` | 审计发生时的角色快照中文名;空角色显示 `系统`,未知历史角色显示 `其他角色()` | + +`supplierTypes[]` 元素结构: + +| 字段 | 类型 | 说明 | +|---|---|---| +| `typeCode` | String | 供应商类型字典值 | +| `typeName` | String | 供应商类型中文名称 | + +### 移除字段 + +| 原字段 | 前端处理 | +|---|---| +| `changeLogId` | 删除“变更 ID”列及所有字段读取 | +| `fieldName` | 删除“字段”列及所有字段读取;变更内容已经合并到中文摘要 | +| `approvalLogId` | 删除“审批日志 ID”列及所有字段读取 | +| `operatorId` | 改为展示 `operatorName`,不要再直接展示管理员 ID | + +上述字段仅从响应记录中移除;`approvalLogId`、`fieldName` 和 `sortBy=changeLogId` 作为既有查询能力继续兼容。 + +### 保留字段与新语义 + +| 字段 | 类型 | 新语义 | +|---|---|---| +| `supplierId` | String | 供应商 ID | +| `operationType` | String | 操作类型编码保持不变 | +| `targetType` | String | 当前固定为 `SUPPLIER` | +| `targetId` | String / null | 主体变更记录为 `null` | +| `oldValueMasked` | String | 变更前的中文脱敏业务摘要,不再直接返回生命周期等原始编码 | +| `newValueMasked` | String | 变更后的中文脱敏业务摘要,不再直接返回生命周期等原始编码 | +| `changeReason` | String | 业务原因;已识别的历史注册记录同步校正为正确原因 | +| `status` | String / null | 变更后生命周期中文名,不再返回原始状态编码 | +| `createTime` | String | `yyyy-MM-dd HH:mm:ss` | + +生命周期展示值如下: + +| 原编码 | 响应中文值 | +|---|---| +| `DRAFT` | `草稿` | +| `VETTING` | `注册审核中` | +| `ACTIVE` | `合作中` | +| `SUSPENDED` | `暂停合作` | +| `FROZEN` | `已冻结` | +| `BLACKLIST` | `黑名单` | +| `ARCHIVED` | `已归档` | + +审批角色常用展示值如下: + +| 角色快照 | `operatorRole` | +|---|---| +| `SUPER_ADMIN` | `超级管理员` | +| `ADMIN` | `管理员` | +| `FINANCE` | `财务` | +| `OPERATOR` | `运营人员` | +| `CUSTOMIZER` | `定制师` | +| `HOUSEKEEPING_ADMIN` | `房务管理员` | +| `LOGISTICS_ADMIN` | `车务管理员` | +| `VEHICLE_MANAGER` | `车辆管理员` | + +历史注册链路中可明确识别的原因统一为: + +| 场景 | `changeReason` | +|---|---| +| 创建供应商草稿 | `创建供应商注册草稿` | +| 草稿提交注册审核 | `提交供应商注册审批` | +| 注册审批通过并启用 | `供应商注册审批通过并启用合作` | + +## 典型成功响应 + +```json +{ + "code": 200, + "message": "成功", + "traceId": "6266-success-example", + "success": true, + "data": { + "records": [ + { + "supplierId": "2091715622923657217", + "supplierName": "内蒙古示例景区有限公司", + "supplierTypes": [ + { + "typeCode": "SCENIC", + "typeName": "景区管理" + } + ], + "operationType": "ENABLE", + "targetType": "SUPPLIER", + "targetId": null, + "oldValueMasked": "供应商状态:注册审核中;供应商编号:无", + "newValueMasked": "供应商状态:合作中;供应商编号:SUP2091715622923657217", + "changeReason": "供应商注册审批通过并启用合作", + "status": "合作中", + "operatorName": "示例管理员", + "operatorRole": "超级管理员", + "createTime": "2026-08-24 10:34:34" + } + ], + "total": 1, + "page": 1, + "pageSize": 10 + } +} +``` + +前端不能从示例中的名称、类型或状态推导固定值;供应商名称和类型取当前档案,状态、角色和变更内容由服务端提供中文展示。 + +## 边界响应 + +供应商存在但筛选条件下没有审批记录时返回空分页,不返回 `null`: + +```json +{ + "code": 200, + "message": "成功", + "traceId": "6266-empty-example", + "success": true, + "data": { + "records": [], + "total": 0, + "page": 1, + "pageSize": 10 + } +} +``` + +## 错误语义 + +| 场景 | HTTP | 业务码 | 说明 | +|---|---:|---:|---| +| 缺少或无效认证 | 可能为 200 | `401` | `success=false`;不能只判断 HTTP 状态 | +| 无可信管理员身份、角色或 `supplier:approval:read` 权限 | 403 | `403` | 拒绝查询,不返回审批记录 | +| 供应商不存在或已删除 | 200 | `395001` | `供应商不存在` | +| 查询枚举、分页或时间范围非法 | 200 | `400` | 返回对应参数校验消息 | + +未认证示例: + +```json +{ + "code": 401, + "message": "缺少有效的 Authorization 头", + "data": null, + "traceId": "6266-auth-example", + "success": false +} +``` + +## 脱敏与兼容约束 + +- 税号、联系电话、证件号和银行账号等敏感内容始终按字段语义重新脱敏;历史摘要也不会因旧数据格式而返回完整敏感值。 +- 集合型资料只返回有界中文摘要;未知历史资料显示为安全的“其他资料:已变更”,客户端不要解析摘要反推结构化表单。 +- 无变更值统一显示 `—`;前端直接展示服务端摘要,不再对 `oldValueMasked`、`newValueMasked` 或 `status` 做生命周期编码翻译。 +- `supplierName` 和 `supplierTypes` 是当前供应商档案信息,不是每次审批发生时的历史快照。 +- 本次不修改请求参数、分页外壳、认证方式、权限码、Gateway 路由或操作类型编码。 + +## 管理端改造清单 + +1. 隐藏“变更 ID”“字段”“审批日志 ID”列。 +2. 新增“供应商名称”“供应商类型”“操作人”“审批角色”列,分别绑定 `supplierName`、`supplierTypes`、`operatorName`、`operatorRole`。 +3. “变更前(脱敏)”“变更后(脱敏)”直接展示 `oldValueMasked`、`newValueMasked`,不再显示原始状态编码。 +4. “状态快照”直接展示中文 `status`;操作类型筛选仍提交既有英文编码。 +5. 删除对 `changeLogId`、`fieldName`、`approvalLogId`、`operatorId` 的响应依赖。 + +## 验证证据 + +- 自动化:审批记录投影与契约定向测试 22 项零失败;Supplier 聚焦回归 196 项零失败(1 项条件跳过);Resource 全量 1953 项零失败(38 项仓库既有条件跳过)。 +- 部署:TEST 部署任务 `73bfe0aa` 成功、退出码 0;`hl-resource-service` 的 8182、8082 双实例依次启动并健康。部署服务器 HEAD `4de8e1703` 包含目标合并提交 `f14544fe0` 和功能提交 `bdcb48d78`。 +- 真实 Gateway:管理端开发代理明确指向 `https://api.test.1814.love:9443`;有效超级管理员查询得到 `code=200`、`success=true` 和 4 条真实审批记录。 +- 响应断言:四个新增字段在每条记录中均存在,四个移除字段均不存在;变更前后摘要和状态未出现 `DRAFT`、`VETTING`、`ACTIVE` 等原始生命周期编码;操作人返回姓名、审批角色返回中文。 +- 原因断言:同一供应商的创建、提交、审批通过记录分别返回正确中文业务原因。 +- 认证门禁:直接经 TEST Gateway 不携带 Authorization 查询,返回 HTTP 200、业务码 `401`、`success=false`。 +- 清理:本次 TEST 验收仅执行只读查询,未创建、修改或删除业务数据,无需数据清理。 + +## 撤回 + +1. 从最新 `dev-v3` 创建回退分支,执行 `git revert -m 1 --no-edit f14544fe0430ccafb7b74bca1ef43c080eabf491`,经独立 PR 合入。 +2. 重新构建并滚动部署 `hl-resource-service`;无需恢复数据库、配置、Redis 或 MQ,也没有不可逆数据影响。 +3. 回退后审批记录会恢复旧响应字段和旧展示语义;管理端若已接入新字段,必须同步回退字段绑定,避免空列。 +4. 经 Gateway 复测成功分页、空分页、未认证、无权限、中文/旧编码展示、敏感字段脱敏和历史原因。 +5. 撤回本 Changelog 时,以新的文档提交删除本文件并通知管理端停止消费新契约;不要重写已发布提交历史。 + +## 关联 / 联系人 + +- **Issue**: [#6266](https://git.1814.love:8443/wx/HL/issues/6266) +- **PR**: [#6270](https://git.1814.love:8443/wx/HL/pulls/6270) +- **合并提交**: [f14544fe0](https://git.1814.love:8443/wx/HL/commit/f14544fe0430ccafb7b74bca1ef43c080eabf491) +- **后端负责人**: @lc