From 8821d1df6f1860baecd37079cf11ce5d219a687c Mon Sep 17 00:00:00 2001 From: lc Date: Sun, 30 Aug 2026 08:18:42 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E4=BA=A4=E4=BB=98=E4=BE=9B=E5=BA=94?= =?UTF-8?q?=E5=95=86=E8=8D=89=E7=A8=BF=E5=8F=98=E6=9B=B4=E5=8E=9F=E5=9B=A0?= =?UTF-8?q?=E5=A5=91=E7=BA=A6=20(#6684)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...¾‘变更原因可选且不写变更记录-修改接口-管理后台.md | 208 ++++++++++++++++++ 1 file changed, 208 insertions(+) create mode 100644 changelogs-v2/2026-08/30_6684_供应商草稿编辑变更原因可选且不写变更记录-修改接口-管理后台.md diff --git a/changelogs-v2/2026-08/30_6684_供应商草稿编辑变更原因可选且不写变更记录-修改接口-管理后台.md b/changelogs-v2/2026-08/30_6684_供应商草稿编辑变更原因可选且不写变更记录-修改接口-管理后台.md new file mode 100644 index 00000000..ccd30ea0 --- /dev/null +++ b/changelogs-v2/2026-08/30_6684_供应商草稿编辑变更原因可选且不写变更记录-修改接口-管理后台.md @@ -0,0 +1,208 @@ +--- +schema: "hl-changelog/v2" +ticket: "6684" +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: "2026-08-30" +status_note: "PR #6686 已合并 dev-v3,合并提交 ae7226ac8e2a23f0ce79ddda1a3a892542b81996 已由 Deploy Panel 任务 da7ffb3a 精确部署 TEST。真实 Gateway 已验证 DRAFT 草稿不传 changeReason 可成功保存、详情回读状态与修改值正确、主体变更记录仍为 0,并已删除合成草稿。当前状态:待前端处理。" +updated_at: "2026-08-30" +base: "dev-v3" +--- + +# 🔧 供应商草稿编辑变更原因可选且不写变更记录 + +供应商当前状态为 `DRAFT` 时,编辑接口不再要求填写 `changeReason`,并且本次草稿编辑不会新增主体变更记录。其他状态继续要求非空变更原因并保留原审计行为。 + +管理端需要按详情返回的当前状态调整表单校验:草稿隐藏或取消“变更原因”必填,非草稿继续必填。 + +## 二、变更接口清单 + +| # | 接口 | 方法 | 路径 | 变更类型 | 说明 | +|---:|---|---|---|---|---| +| 1 | 编辑供应商 | PUT | `/admin/supplier/items/{supplierId}/update` | 修改请求校验与写入行为 | `DRAFT` 可省略 `changeReason` 且不新增主体变更记录;其他状态不变 | + +## 三、接口详情 + +### 1. 编辑供应商 `PUT /admin/supplier/items/{supplierId}/update` + +**VO**: `SupplierUpdateReqVO / SupplierWriteRespVO` + +#### 使用场景 + +在供应商编辑页继续完善尚未提交审批的草稿资料。调用方先读取供应商详情取得当前 `status` 和 `updateTime`,再按当前状态决定是否发送变更原因。 + +#### 入参 + +| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 | +|---|---|---|---:|---|---| +| `supplierId` | Path | String | 是 | 正整数 ID 字符串 | 目标供应商 | +| `changeReason` | Body | String | 条件必填 | 最长 500 字符 | 服务端当前状态为 `DRAFT` 时可省略或为空;其他状态去空白后必须非空 | +| `expectedUpdateTime` | Body | String | 是 | `yyyy-MM-dd HH:mm:ss` | 最近一次详情或写响应返回的并发版本 | +| `fullName`、`shortName` 等资料字段 | Body | 对应类型 | 否 | 沿用既有字段规则 | 仅发送本次需要修改的字段;示例使用 `remark` | + +请求体不接收客户端自报的供应商状态;是否为草稿由服务端锁定并读取当前供应商后判定。 + +#### 出参 + +| 字段 | 类型 | 说明 | +|---|---|---| +| `code` | Number | 业务码;成功为 `200` | +| `success` | Boolean | 业务是否成功 | +| `data.supplierId` | String | 供应商 ID | +| `data.supplierNo` | String | 供应商业务编号 | +| `data.status` | String | 保存后的当前状态;本场景为 `DRAFT` | +| `data.onboardingStage` | String | 草稿为 `PROFILE_DRAFT` | +| `data.initialAccounts` | Array | 当前初始结算账户摘要,未登记时为空数组 | +| `data.updateTime` | String | 保存后的新并发版本 | + +#### 请求示例 + +`DRAFT` 草稿请求体完全不发送 `changeReason`: + +```json +{ + "remark": "补充草稿内部备注", + "expectedUpdateTime": "2026-08-30 08:15:29" +} +``` + +#### 响应示例 + +```json +{ + "code": 200, + "message": "成功", + "success": true, + "data": { + "supplierId": "2093855088501035010", + "supplierNo": "SUP2093855088501035010", + "status": "DRAFT", + "onboardingStage": "PROFILE_DRAFT", + "initialAccounts": [], + "updateTime": "2026-08-30 08:15:45" + } +} +``` + +#### 空数据 / 降级响应 + +- `DRAFT` 时省略 `changeReason`、传 `null` 或只传空白,不会因变更原因被拒绝。 +- 省略其他可选资料字段仍表示“不修改该字段”,不自动清空既有值。 +- 依赖服务异常继续按既有失败关闭语义返回,不把未完成写入伪装成成功。 + +#### 错误响应 + +非 `DRAFT` 供应商省略或传空白 `changeReason`,继续返回原业务错误且零写入: + +```json +{ + "code": 400, + "message": "变更原因不能为空", + "success": false, + "data": null +} +``` + +并发版本过期继续返回既有错误: + +```json +{ + "code": 395014, + "message": "数据已被他人修改,请刷新后重试", + "success": false, + "data": null +} +``` + +#### 业务边界 + +- 接口继续要求有效管理端身份、既有可信角色及 `supplier:update` 服务端权限。 +- 草稿判定使用服务端锁定后读取到的持久状态,不能通过请求体伪造 `DRAFT` 绕过非草稿审计。 +- `DRAFT` 成功编辑只更新草稿资料与并发版本,不新增主体变更记录。 +- 非 `DRAFT` 的原因必填、主体变更记录、事务、聚合锁、幂等和乐观并发规则均不变。 +- 参数、权限、状态或并发校验失败时不产生部分资料写入或变更记录。 + +## 四、契约约束与正确调用方式 + +1. 进入编辑页先调用 `GET /admin/supplier/items/{supplierId}/basic-info/view`,使用返回的 `status` 和 `updateTime`。 +2. `status=DRAFT` 时可以不渲染变更原因输入框,或取消其必填校验;保存请求可完全省略 `changeReason`。 +3. `status` 不是 `DRAFT` 时继续收集非空 `changeReason`,不要把草稿规则扩展到其他状态。 +4. 每次成功保存后使用响应中的新 `updateTime` 作为下一次编辑的 `expectedUpdateTime`。 + +| 场景 | payload | 结果 | +|---|---|---| +| `DRAFT` 省略原因 | `{ "remark": "补充资料", "expectedUpdateTime": "2026-08-30 08:15:29" }` | 成功,不新增主体变更记录 | +| `DRAFT` 显式空原因 | `{ "changeReason": "", "expectedUpdateTime": "2026-08-30 08:15:29" }` | 成功,不新增主体变更记录 | +| 非 `DRAFT` 省略原因 | `{ "remark": "调整资料", "expectedUpdateTime": "2026-08-30 08:15:29" }` | `400`,变更原因不能为空 | +| 非 `DRAFT` 提供原因 | `{ "changeReason": "更新登记资料", "expectedUpdateTime": "2026-08-30 08:15:29" }` | 按既有编辑与审计规则处理 | + +## 五、数据库行为 + +| 服务端当前状态 | 资料保存 | 主体变更记录 | +|---|---|---| +| `DRAFT` | 按既有增量编辑和并发规则保存 | 不新增本次编辑记录 | +| 非 `DRAFT` 且原因有效 | 按既有编辑规则保存 | 继续新增完整变更记录并保留原因 | +| 非 `DRAFT` 且原因为空 | 不保存 | 不新增记录 | + +本次不新增数据库 migration,不改历史记录,不执行跨服务写入,也不引入 Redis、MQ 或配置写行为。 + +## 六、边界行为 + +- 未登录请求继续由 Gateway 拒绝;本次不改变认证级别。 +- 无供应商写权限、供应商不存在、状态不允许或并发版本过期时继续按既有错误语义失败。 +- `changeReason` 长度上限仍为 500 字符;非草稿只传空白等同未填写。 +- 草稿成功编辑后,详情回读应保持 `status=DRAFT` 并返回本次修改值与新版本。 +- 草稿的主体变更记录分页在本次保存前后数量保持不变。 + +## 六.6、修改前后对比 + +| 项目 | 修改前 | 修改后 | +|---|---|---| +| `DRAFT` 的 `changeReason` | 请求模型无条件必填,省略即返回“变更原因不能为空” | 可省略、为 `null` 或空白 | +| `DRAFT` 编辑审计 | 每次成功编辑都会新增主体变更记录 | 不新增主体变更记录 | +| 非 `DRAFT` 的 `changeReason` | 必填 | 继续必填 | +| 非 `DRAFT` 编辑审计 | 成功后记录完整变化与原因 | 保持不变 | + +## 六.7、影响评估 + +- **是否破坏向后兼容**:否;原来已发送 `changeReason` 的草稿请求继续可用,非草稿契约不变。 +- **前端是否必须同步上线**:是;管理端当前草稿编辑表单仍把“变更原因”显示为必填,需要按详情 `status` 取消草稿必填。 +- **前端 workaround 清理点**:删除 `DRAFT` 草稿保存前对 `changeReason` 的必填拦截;不得删除非草稿校验。 +- **响应与错误码影响**:成功响应字段不变;只移除草稿缺少原因时的 `400`,不新增错误码。 + +## 七、不影响范围 + +- 不修改供应商创建、注册提交、草稿删除、暂停、拉黑、归档、合同、账户或资源关系接口。 +- 不修改非草稿资料编辑的变更原因与主体变更记录语义。 +- 不修改 Gateway 路由、认证策略、角色或权限点。 +- 不新增数据库结构、历史数据回填、Redis、MQ、Nacos 或配置变更。 +- 本工单仅交付后端和接口 Changelog,不修改任何前端源码或资源。 + +## 八、测试环境已验证 + +- 合并提交 `ae7226ac8e2a23f0ce79ddda1a3a892542b81996` 已由 Deploy Panel 任务 `da7ffb3a` 精确部署到 TEST,Resource 双实例与 Nacos 注册均健康。 +- 通过真实 TEST Gateway 创建合成 `DRAFT` 草稿,并用完全不含 `changeReason` 的请求修改 `remark`;返回 `code=200`、`success=true`、`status=DRAFT` 和新的 `updateTime`。 +- 保存后再次查询详情,`remark` 为本次修改值且状态仍为 `DRAFT`。 +- 保存前后查询该供应商的 `UPDATE` 主体变更记录均返回 `total=0`、`records=[]`。 +- 验收后通过草稿删除接口清理合成数据;详情返回“供应商不存在”,按供应商编号查询列表为空。 + +## 十、相关文档 + +- Issue [#6684](https://git.1814.love:8443/wx/HL/issues/6684) +- PR [#6686](https://git.1814.love:8443/wx/HL/pulls/6686) +- 合并提交 [ae7226ac8e2a23f0ce79ddda1a3a892542b81996](https://git.1814.love:8443/wx/HL/commit/ae7226ac8e2a23f0ce79ddda1a3a892542b81996) + +## 关联 / 联系人 + +### 联系人 + +- **后端负责人**:@lc +- **当前状态**:待前端处理