diff --git a/changelogs-v2/2026-08/31_6834_供应商余额支付类型与草稿编辑项-修改接口-管理后台.md b/changelogs-v2/2026-08/31_6834_供应商余额支付类型与草稿编辑项-修改接口-管理后台.md new file mode 100644 index 00000000..05283a32 --- /dev/null +++ b/changelogs-v2/2026-08/31_6834_供应商余额支付类型与草稿编辑项-修改接口-管理后台.md @@ -0,0 +1,488 @@ +--- +schema: "hl-changelog/v2" +ticket: "6834" +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-31" +status_note: "PR #6860 已合并 dev-v3,合并提交 6ed8e24c0f04051c9c4385c79de67f255abb4952 已部署 TEST。真实 Gateway 已验证支付类型字典、新增必填与失败零写入、余额和支付类型保存回显、草稿省略 changeReason 更新及验收数据清理。当前状态:后端已就绪,前端待处理。" +updated_at: "2026-08-31" +base: "dev-v3" +--- + +# 供应商余额支付类型与草稿编辑项 + +供应商新增、提交、编辑和详情增加 `balance`、`paymentType`。新增与提交时两项必填;编辑时可按增量提交,详情用于回显。支付类型从 `supplier_payment_type` 字典读取。 + +供应商详情 `status=DRAFT` 时,编辑页隐藏“变更原因”;其他状态继续显示并必填。 + +## 二、变更接口清单 + +| # | 接口 | 方法 | 路径 | 变更类型 | 说明 | +|---:|---|---|---|---|---| +| 1 | 新增供应商草稿 | POST | `/admin/supplier/items/add` | 请求字段 | `balance`、`paymentType` 必填 | +| 2 | 提交供应商审批 | POST | `/admin/supplier/items/{supplierId}/submit` | 请求字段 | 完整表单中的两个字段必填 | +| 3 | 编辑供应商 | PUT | `/admin/supplier/items/{supplierId}/update` | 请求字段与状态规则 | 可更新两个字段;草稿可省略 `changeReason` | +| 4 | 查询供应商基本信息 | GET | `/admin/supplier/items/{supplierId}/basic-info/view` | 响应字段 | 返回 `balance`、`paymentType`、`status` | +| 5 | 查询支付类型字典类型 | GET | `/admin/dict/type` | 新增字典数据 | 可按 `supplier_payment_type` 查询字典类型 | +| 6 | 查询支付类型字典项 | GET | `/admin/dict/data/supplier_payment_type` | 新增字典数据 | 返回现付、签单、月付 | + +## 三、接口详情 + +### 1. 新增供应商草稿 `POST /admin/supplier/items/add` + +**VO**: `SupplierDraftSaveReqVO / SupplierWriteRespVO` + +#### 使用场景 + +新增供应商时录入初始余额并选择支付类型。 + +#### 入参 + +| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 | +|---|---|---|---:|---|---| +| `balance` | Body | Number | 是 | 最多 16 位整数、2 位小数,可为正数、0 或负数 | 供应商当前余额 | +| `paymentType` | Body | String | 是 | 必须命中当前生效的 `supplier_payment_type` 字典项 | 支付类型值,传 `1`、`2` 或 `3` | +| `fullName` / `taxNo` / `mainCooperation` | Body | String | 是 | 沿用既有规则 | 其他新增必填字段 | + +#### 出参 + +| 字段 | 类型 | 说明 | +|---|---|---| +| `data.supplierId` | String | 新供应商 ID | +| `data.status` | String | 新增草稿为 `DRAFT` | +| `data.updateTime` | String | 后续编辑使用的并发版本 | + +#### 请求示例 + +```json +{ + "fullName": "示例供应商有限公司", + "taxNo": "91350211M000100Y46", + "mainCooperation": "旅游资源合作", + "balance": 1200.50, + "paymentType": "1" +} +``` + +#### 响应示例 + +```json +{ + "code": 200, + "message": "成功", + "success": true, + "data": { + "supplierId": "2094278854020399106", + "status": "DRAFT", + "updateTime": "2026-08-31 12:19:23" + } +} +``` + +#### 空数据 / 降级响应 + +`balance` 或 `paymentType` 省略、为 `null` 或支付类型为空白时返回业务码 `400`,不创建草稿。 + +#### 错误响应 + +```json +{"code":400,"message":"余额不能为空","success":false,"data":null} +``` + +```json +{"code":400,"message":"供应商支付类型不合法或已停用","success":false,"data":null} +``` + +#### 业务边界 + +- 前端必须传数值型 `balance`,不要传格式化金额字符串。 +- `paymentType` 传字典 `dictValue`,不要传“现付”等展示文本。 +- 校验失败时不产生供应商记录。 + +### 2. 提交供应商审批 `POST /admin/supplier/items/{supplierId}/submit` + +**VO**: `SupplierSubmitReqVO / SupplierApprovalCommandRespVO` + +#### 使用场景 + +把完整供应商表单提交审批时,一并提交余额和支付类型。 + +#### 入参 + +| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 | +|---|---|---|---:|---|---| +| `supplierId` | Path | String | 是 | 正整数 ID 字符串 | 草稿供应商 | +| `balance` | Body | Number | 是 | 最多 16 位整数、2 位小数 | 当前余额 | +| `paymentType` | Body | String | 是 | 当前生效字典值 | 支付类型 | +| `expectedUpdateTime` | Body | String | 是 | `yyyy-MM-dd HH:mm:ss` | 当前供应商并发版本 | +| 其他完整表单字段 | Body | 对应类型 | 按既有规则 | 沿用现有提交契约 | 不得只提交本次新增字段 | + +#### 出参 + +| 字段 | 类型 | 说明 | +|---|---|---| +| `data.approvalLogId` | String | 审批记录 ID | +| `data.approvalStatus` | String | 审批状态 | + +#### 请求示例 + +```json +{ + "fullName": "示例供应商有限公司", + "taxNo": "91350211M000100Y46", + "mainCooperation": "旅游资源合作", + "balance": 1200.50, + "paymentType": "1", + "expectedUpdateTime": "2026-08-31 12:19:23" +} +``` + +#### 响应示例 + +```json +{"code":200,"message":"成功","success":true,"data":{"approvalLogId":"2094279000000000001","approvalStatus":"PENDING"}} +``` + +#### 空数据 / 降级响应 + +两个新增字段任一为空即拒绝提交,审批状态不推进。 + +#### 错误响应 + +```json +{"code":400,"message":"支付类型不能为空","success":false,"data":null} +``` + +#### 业务边界 + +- 提交仍是完整表单命令,并继续执行既有状态、并发、审批和幂等门禁。 +- 支付类型失效或不存在时失败关闭,不使用本地默认值代替。 + +### 3. 编辑供应商 `PUT /admin/supplier/items/{supplierId}/update` + +**VO**: `SupplierUpdateReqVO / SupplierWriteRespVO` + +#### 使用场景 + +编辑页修改余额或支付类型;根据详情的服务端状态决定是否显示变更原因。 + +#### 入参 + +| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 | +|---|---|---|---:|---|---| +| `supplierId` | Path | String | 是 | 正整数 ID 字符串 | 目标供应商 | +| `balance` | Body | Number | 否 | 最多 16 位整数、2 位小数 | 省略表示不修改 | +| `paymentType` | Body | String | 否 | 非空时必须命中当前生效字典项 | 省略表示不修改 | +| `changeReason` | Body | String | 条件必填 | 最长 500 | `DRAFT` 可省略;其他状态去空白后必须非空 | +| `expectedUpdateTime` | Body | String | 是 | `yyyy-MM-dd HH:mm:ss` | 详情最新并发版本 | + +#### 出参 + +| 字段 | 类型 | 说明 | +|---|---|---| +| `data.supplierId` | String | 供应商 ID | +| `data.status` | String | 保存后的服务端状态 | +| `data.updateTime` | String | 保存后的新并发版本 | + +#### 请求示例 + +`DRAFT` 草稿完全省略 `changeReason`: + +```json +{ + "balance": -12.34, + "paymentType": "3", + "expectedUpdateTime": "2026-08-31 12:19:23" +} +``` + +#### 响应示例 + +```json +{"code":200,"message":"成功","success":true,"data":{"supplierId":"2094278854020399106","status":"DRAFT","updateTime":"2026-08-31 12:19:33"}} +``` + +#### 空数据 / 降级响应 + +省略 `balance` 或 `paymentType` 表示该字段不修改;历史供应商尚未补录时,详情可返回 `null`。 + +#### 错误响应 + +非草稿缺少变更原因: + +```json +{"code":400,"message":"变更原因不能为空","success":false,"data":null} +``` + +#### 业务边界 + +- 是否为草稿只取服务端锁定后的当前状态,不接收客户端自报状态。 +- 草稿隐藏“变更原因”并省略 `changeReason`;非草稿继续显示且必填。 +- 更新成功后使用新 `updateTime` 重新查询详情;并发失败返回既有 `395014`。 + +### 4. 查询供应商基本信息 `GET /admin/supplier/items/{supplierId}/basic-info/view` + +**VO**: `SupplierBasicInfoRespVO` + +#### 使用场景 + +新增后或进入编辑页时回显余额、支付类型和当前状态。 + +#### 入参 + +| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 | +|---|---|---|---:|---|---| +| `supplierId` | Path | String | 是 | 正整数 ID 字符串 | 目标供应商 | + +#### 出参 + +| 字段 | 类型 | 说明 | +|---|---|---| +| `data.balance` | Number/null | 当前余额;历史未补录可为 `null` | +| `data.paymentType` | String/null | `supplier_payment_type` 字典值;历史未补录可为 `null` | +| `data.status` | String | 用于控制变更原因框 | +| `data.updateTime` | String | 编辑请求的并发版本 | + +#### 请求示例 + +```http +GET /admin/supplier/items/2094278854020399106/basic-info/view +Authorization: Bearer +``` + +#### 响应示例 + +```json +{ + "code": 200, + "message": "成功", + "success": true, + "data": { + "supplierId": "2094278854020399106", + "balance": -12.34, + "paymentType": "3", + "status": "DRAFT", + "updateTime": "2026-08-31 12:19:33" + } +} +``` + +#### 空数据 / 降级响应 + +历史供应商没有新字段时返回 `null`;前端显示未补录,不自行写入默认值。 + +#### 错误响应 + +```json +{"code":395001,"message":"供应商不存在","success":false,"data":null} +``` + +#### 业务边界 + +- `paymentType` 原样返回字典值,中文标签由字典项映射。 +- 业务失败可能仍是 HTTP 200,必须同时判断 `code` 和 `success`。 + +### 5. 查询支付类型字典类型 `GET /admin/dict/type` + +**VO**: `PageResult` + +#### 使用场景 + +字典管理页或联调时确认 `supplier_payment_type` 类型已经存在。 + +#### 入参 + +| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 | +|---|---|---|---:|---|---| +| `page` | Query | Number | 否 | 默认 1 | 页码 | +| `pageSize` | Query | Number | 否 | 默认 20 | 每页条数 | +| `keyword` | Query | String | 否 | 传 `supplier_payment_type` | 按编码或名称搜索 | + +#### 出参 + +| 字段 | 类型 | 说明 | +|---|---|---| +| `data.records[].dictType` | String | `supplier_payment_type` | +| `data.records[].dictName` | String | `供应商支付类型` | +| `data.records[].status` | String | `ACTIVE` | + +#### 请求示例 + +```http +GET /admin/dict/type?page=1&pageSize=20&keyword=supplier_payment_type +``` + +#### 响应示例 + +```json +{"code":200,"message":"成功","success":true,"data":{"records":[{"dictType":"supplier_payment_type","dictName":"供应商支付类型","status":"ACTIVE"}],"total":1,"page":1,"pageSize":20}} +``` + +#### 空数据 / 降级响应 + +未命中时 `records=[]`;这表示字典未就绪,前端不要回退到其他结算字典。 + +#### 错误响应 + +```json +{"code":401,"message":"Token无效或已过期","success":false,"data":null} +``` + +#### 业务边界 + +- 该接口只查询字典类型,不直接提供下拉项。 +- 下拉选项必须继续调用下一接口。 + +### 6. 查询支付类型字典项 `GET /admin/dict/data/supplier_payment_type` + +**VO**: `List` + +#### 使用场景 + +新增、编辑供应商页面加载支付类型下拉选项。 + +#### 入参 + +| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 | +|---|---|---|---:|---|---| +| 无 | - | - | 否 | 字典编码固定在路径中 | 无请求体、查询参数或动态路径参数 | + +#### 出参 + +| 字段 | 类型 | 说明 | +|---|---|---| +| `data[].dictValue` | String | 请求保存的值 | +| `data[].dictLabel` | String | 下拉展示文案 | +| `data[].sortOrder` | Number | 排序号 | +| `data[].status` | String | 当前均为 `ACTIVE` | + +#### 请求示例 + +```http +GET /admin/dict/data/supplier_payment_type +``` + +#### 响应示例 + +```json +{ + "code": 200, + "message": "成功", + "success": true, + "data": [ + {"dictValue":"1","dictLabel":"现付","sortOrder":10,"status":"ACTIVE"}, + {"dictValue":"2","dictLabel":"签单","sortOrder":20,"status":"ACTIVE"}, + {"dictValue":"3","dictLabel":"月付","sortOrder":30,"status":"ACTIVE"} + ] +} +``` + +#### 空数据 / 降级响应 + +返回空数组或调用失败时禁用提交并提示字典加载失败,不硬编码替代值。 + +#### 错误响应 + +```json +{"code":401,"message":"Token无效或已过期","success":false,"data":null} +``` + +#### 业务边界 + +- 请求保存 `dictValue`,界面展示 `dictLabel`。 +- 后端每次写入都动态校验当前生效项;已停用或未知值返回业务码 `400`。 + +## 四、契约约束与正确调用方式 + +1. 页面初始化先查询详情与支付类型字典项,用 `paymentType` 匹配 `dictValue`。 +2. 新增和提交时 `balance`、`paymentType` 都必填;编辑时只发送实际修改字段和最新 `expectedUpdateTime`。 +3. `status=DRAFT` 隐藏“变更原因”并可省略 `changeReason`;其他状态必须收集非空原因。 +4. 金额输入保留最多两位小数,允许负数;不要把千分位格式化文本发给后端。 + +| 场景 | payload | 结果 | +|---|---|---| +| 新增完整 | `{ "balance": 100.00, "paymentType": "1", ... }` | 成功 | +| 新增缺余额 | `{ "paymentType": "1", ... }` | `400`,余额不能为空 | +| 新增非法支付类型 | `{ "balance": 100.00, "paymentType": "9", ... }` | `400`,支付类型不合法或已停用 | +| 草稿编辑 | `{ "balance": -12.34, "paymentType": "3", "expectedUpdateTime": "..." }` | 成功,可省略 `changeReason` | +| 非草稿编辑缺原因 | `{ "balance": 0, "expectedUpdateTime": "..." }` | `400`,变更原因不能为空 | + +## 五、数据库行为 + +- 新增或更新成功后,详情回读相同的 `balance`、`paymentType`。 +- 历史供应商不强制回填,新字段可返回 `null`;创建和提交的新数据仍由接口强制必填。 +- 审批与非草稿变更继续保留两个字段的业务快照;失败时不产生部分写入。 + +## 六、边界行为 + +- `balance` 最多 16 位整数和 2 位小数,正数、0、负数均有效。 +- `paymentType` 必须是当前生效字典值;未知、空白或停用值不保存。 +- 未登录返回业务码 `401`;不存在返回 `395001`;并发版本过期返回 `395014`。 +- 不新增权限、Gateway 路由、Redis、MQ 或配置行为。 + +## 六.5、枚举 / 数据字典 + +### `paymentType`(字典 `supplier_payment_type`) + +**所属字段**: `SupplierDraftSaveReqVO.paymentType / SupplierUpdateReqVO.paymentType / SupplierBasicInfoRespVO.paymentType` | **类型**: `String` + +| 值 | 中文 | 说明 | +|---|---|---| +| `1` | 现付 | 按现付方式处理 | +| `2` | 签单 | 按签单方式处理 | +| `3` | 月付 | 按月付方式处理 | + +## 六.6、修改前后对比 + +| 项目 | 修改前 | 修改后 | +|---|---|---| +| 新增与提交 | 无余额、支付类型字段 | 两字段必填并校验 | +| 编辑与详情 | 无法录入和回显两字段 | 支持增量修改并原值回显 | +| 支付类型选项 | 无专用字典 | 使用 `supplier_payment_type` 三个生效项 | +| 草稿变更原因 | 页面仍可能显示 | `DRAFT` 隐藏;非草稿继续必填 | + +## 六.7、影响评估 + +- **是否破坏向后兼容**:新增、提交请求增加必填字段,前端必须同步;编辑与详情为兼容扩展。 +- **前端是否必须同步上线**:是,需要新增两个控件、接入字典并按状态调整变更原因框。 +- **前端 workaround 清理点**:删除支付类型硬编码和草稿 `changeReason` 必填/展示逻辑;非草稿校验必须保留。 + +## 七、不影响范围 + +- 不修改供应商权限、状态机、审批流程、并发、软删除和既有错误码。 +- 不复用 `resource_settle_type`,也不影响供应商账户、合同和资源关系接口。 +- 本次仅交付后端接口 Changelog,不修改任何前端源码或资源。 + +## 八、测试环境已验证 + +- TEST Gateway 查询到字典类型及精确字典项 `1-现付`、`2-签单`、`3-月付`。 +- 缺余额、缺支付类型、非法支付类型均返回 `400`,验证前后列表为空。 +- 有效新增返回 `DRAFT`;详情回显 `balance=12.34`、`paymentType=1`。 +- 草稿省略 `changeReason` 更新成功;详情回显 `balance=-12.34`、`paymentType=3`。 +- 验收草稿已通过删除接口清理,列表为空且详情返回“供应商不存在”。 + +## 当前状态 + +- 后端:已部署并已验证。 +- 前端:待处理。 + +## 十、相关文档 + +- Issue:[#6834](https://git.1814.love:8443/wx/HL/issues/6834) +- 后端 PR:[#6860](https://git.1814.love:8443/wx/HL/pulls/6860) +- 合并提交:[6ed8e24c](https://git.1814.love:8443/wx/HL/commit/6ed8e24c0f04051c9c4385c79de67f255abb4952) + +## 关联 / 联系人 + +- **Issue**: [#6834](https://git.1814.love:8443/wx/HL/issues/6834) +- **PR**: [#6860](https://git.1814.love:8443/wx/HL/pulls/6860) +- **后端负责人**: @lc +- **当前状态**: 后端已就绪,前端待处理。