@@ -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 <admin-token>
|
||||
```
|
||||
|
||||
#### 响应示例
|
||||
|
||||
```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<SysDictTypeRespVO>`
|
||||
|
||||
#### 使用场景
|
||||
|
||||
字典管理页或联调时确认 `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<SysDictDataRespVO>`
|
||||
|
||||
#### 使用场景
|
||||
|
||||
新增、编辑供应商页面加载支付类型下拉选项。
|
||||
|
||||
#### 入参
|
||||
|
||||
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||||
|---|---|---|---:|---|---|
|
||||
| 无 | - | - | 否 | 字典编码固定在路径中 | 无请求体、查询参数或动态路径参数 |
|
||||
|
||||
#### 出参
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|---|---|---|
|
||||
| `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
|
||||
- **当前状态**: 后端已就绪,前端待处理。
|
||||
在新工单中引用
屏蔽一个用户