--- schema: "hl-changelog/v2" ticket: "6710" title: "供应商联系人快照版本字段兼容" consumer: "admin" author: "lc(GIT)" change_type: "修改接口" backend_status: "deployed" gateway_status: "verified" frontend_status: "verified" frontend_owner: "mmg" frontend_ref: "95e1f917" target_release: "v2.1" verified_at: "2026-08-30" status_note: "PR #6712 已合并 dev-v3,合并提交 7f3f944bf361b7ae41424c43b29262fb634fe791 已精确部署 TEST。后端后改判「当前前端已回传 updateTime 无需修改代码」,但前端实证:修复前 cleanContactRow 对已有联系人仅发 contactId 不带任何版本,必触发 400「联系人快照项不合法」;本次前端补回传条目级版本(commit 95e1f917),修复后方可正常保存。前端按实际修复记 verified。" updated_at: "2026-08-30" base: "dev-v3" --- # 供应商联系人快照版本字段兼容 后端现已兼容详情联系人字段 `contacts[].updateTime`。当前前端已经回传该字段,无需修改代码;本记录仅保留历史审计,不构成前端任务。 ## 二、变更接口清单 | # | 接口 | 方法 | 路径 | 变更类型 | 说明 | |---:|---|---|---|---|---| | 1 | 编辑供应商 | PUT | `/admin/supplier/items/{supplierId}/update` | 请求兼容 | 已有联系人可用 `updateTime` 作为条目级并发版本 | ## 三、接口详情 ### 1. 编辑供应商 `PUT /admin/supplier/items/{supplierId}/update` **VO**: `SupplierUpdateReqVO / SupplierContactMergeReqVO / SupplierWriteRespVO` #### 使用场景 保留已有联系人并在一次编辑中新增多个联系人。 #### 入参 | 字段 | 位置 | 类型 | 必填 | 约束 | 说明 | |---|---|---|---:|---|---| | `expectedUpdateTime` | Body | String | 是 | `yyyy-MM-dd HH:mm:ss` | 主体并发版本 | | `contacts` | Body | Array | 否 | 最多 100 项 | 联系人完整快照 | | `contacts[].contactId` | Body | String | 已有项是 | 正整数 | 为空表示新增 | | `contacts[].expectedUpdateTime` / `updateTime` | Body | String | 已有项二选一 | 时间格式同上 | 条目级并发版本 | 姓名和联系电话允许与已有联系人或同批新增联系人重复。新增项仍按既有规则提供姓名、电话和角色,不传 ID 与版本。 #### 出参 `Result` | 字段 | 类型 | 说明 | |---|---|---| | `data.updateTime` | String | 保存后的主体并发版本 | #### 请求示例 ```json {"expectedUpdateTime":"2026-08-30 10:04:18","contacts":[{"contactId":"2093000000000000001","contactName":"张三","contactPhone":"18501941408","contactRole":"contentBus","updateTime":"2026-08-30 10:04:19"},{"contactName":"张三","contactPhone":"18501941408","contactRole":"contentMoney"}]} ``` #### 响应示例 ```json {"code":200,"message":"成功","success":true,"data":{"updateTime":"2026-08-30 10:04:29"}} ``` #### 空数据 / 降级响应 - 省略 `contacts` 或传 `null`:联系人不变。 - 依赖异常:沿用既有失败关闭语义,不产生部分写入。 #### 错误响应 版本过期时: ```json {"code":395014,"message":"数据已被他人修改,请刷新后重试","success":false,"data":null} ``` 已有联系人未携带任一版本字段时,仍返回 `400`、`联系人快照项不合法`。 #### 业务边界 - 已有联系人仍须提供 `contactId` 和有效版本;本次没有取消并发校验。 - 姓名或联系电话重复本身不是错误条件。 - 权限、状态、默认联系人及角色字典规则均不变。 ## 四、契约约束与正确调用方式 1. 主体详情 `updateTime` 放入请求顶层 `expectedUpdateTime`。 2. 已有联系人的 `updateTime` 可原样回传;新增联系人不传 ID 和版本。 3. 保存后重新读取详情,使用最新版本继续编辑。 ## 五、数据库行为 - 不新增数据库结构或姓名、电话唯一约束。 - 校验失败时联系人和主体均不写入。 ## 六、边界行为 - 未登录、无权限、供应商不存在或版本过期时沿用既有错误。 - `contacts=[]` 沿用既有清空语义。 - 业务失败可能仍为 HTTP 200,调用方同时判断 `code` 和 `success`。 ## 六.6、修改前后对比 | 项目 | 修改前 | 修改后 | |---|---|---| | 联系人版本字段 | 仅识别 `expectedUpdateTime` | 同时识别 `expectedUpdateTime`、`updateTime` | | 姓名、电话重复 | 允许 | 继续允许 | ## 六.7、影响评估 - **是否破坏向后兼容**:否。 - **前端是否必须同步上线**:否,当前前端已回传 `updateTime`。 - **前端 workaround 清理点**:无。 - **响应与错误码影响**:无。 ## 七、不影响范围 - 不修改其他供应商接口、权限或状态机。 - 不修改数据库结构、配置、Redis 或 MQ。 - 不修改任何前端代码。 ## 八、测试环境已验证 - 详情 `updateTime` 原样回传后,可保留已有联系人并新增多个联系人。 - 多个联系人姓名、电话重复时保存成功。 - 过期版本返回 `395014` 且零写入;验收草稿已清理。 ## 十、相关文档 - [Issue #6710](https://git.1814.love:8443/wx/HL/issues/6710) - [PR #6712](https://git.1814.love:8443/wx/HL/pulls/6712) ## 关联 / 联系人 - **后端负责人**:@lc - **当前状态**:已消费(`frontend_status: verified`)。SupplierEditModal fillForm 回填详情联系人条目级 updateTime、createContactRow 新增行置 null;cleanContactRow 已有项(contactId 存在)加发 expectedUpdateTime=row.updateTime 原样回传,新增行仍不发版本;快照比对两侧同经 cleanContactRow,未改动不误携带。spec +3 例累计 71 例绿,commit 95e1f917 已推 v2.1。注:后端后改判「无需前端处理」系基于修复后前端,修复前旧前端仅发 contactId 必 400,本修复为必要。