docs(finance): 供应商应付期初表单对接纠偏 changelog(后端接口零改动)
changelog-filename-gate / validate (push) Failing after 1s
changelog-filename-gate / validate (push) Failing after 1s
财务初始化·供应商应付期初表单前端画错(手填雪花ID+双金额+必填佐证), 本文档给出正确 6 字段形态与字段映射,POST /admin/finance/opening-balances 入参/出参/枚举均无变更,无 Issue/PR。
这个提交包含在:
@@ -0,0 +1,321 @@
|
||||
---
|
||||
schema: "hl-changelog/v2"
|
||||
ticket: "frontend"
|
||||
title: "供应商应付期初表单对接纠偏:后端接口零改动,纠正表单形态与字段映射"
|
||||
consumer: "admin"
|
||||
author: "yst(GIT)"
|
||||
change_type: "修改接口"
|
||||
backend_status: "not_required"
|
||||
gateway_status: "not_required"
|
||||
frontend_status: "required"
|
||||
frontend_owner: ""
|
||||
frontend_ref: ""
|
||||
target_release: ""
|
||||
verified_at: ""
|
||||
status_note: "后端 POST /admin/finance/opening-balances 入参/出参/枚举零改动。本文档为前端对接纠偏指引:财务初始化·供应商应付期初表单当前画错(手填雪花ID + 应收/应付双金额 + 必填佐证),正确形态为 6 字段(供应商下拉 / 单一应付金额 / 所属公司下拉 / 记账日期只读 / 佐证选填 / 备注选填),前端需按本文档修正表单。"
|
||||
updated_at: "2026-09-29"
|
||||
base: "dev-v3"
|
||||
---
|
||||
|
||||
# finance:供应商应付期初表单对接纠偏(后端接口零改动)(管理后台)
|
||||
|
||||
**服务**: hl-order-service-v3(finance 模块,同进程)
|
||||
**PR**: 无(前端对接纠偏,无后端改动)
|
||||
**Issue**: 无(前端对接纠偏,无后端改动)
|
||||
|
||||
---
|
||||
|
||||
## 一、接口背景
|
||||
|
||||
管理后台「财务初始化」里有一组**期初余额录入**表单,按账套区分(供应商应付 / 客户应收等)。本文档只针对**「供应商应付期初」**这一张表单。
|
||||
|
||||
联调发现前端把这张表单画错了:画成了「手填往来对象雪花 ID + 应收/应付两个金额框 + 佐证材料必填」。后端接口 `POST /admin/finance/opening-balances` **自始至终没有变过**(入参 / 出参 / 枚举零改动),是前端表单形态与字段映射理解偏差。本文档给出正确表单形态和逐字段映射,前端按此修正即可,不需要等任何后端发版。
|
||||
|
||||
## 二、变更清单
|
||||
|
||||
| 项 | 变更 |
|
||||
|---|---|
|
||||
| 提交接口 `POST /admin/finance/opening-balances` | **无变更**(签名 / 字段 / 枚举 / 错误码均未变) |
|
||||
| 前端表单 | **需纠偏**:表单元素从「手填 ID + 双金额 + 必填佐证」改为「下拉 + 单一应付金额 + 佐证选填」6 字段形态 |
|
||||
| 数据库表 | 零 DDL |
|
||||
|
||||
## 三、接口详情
|
||||
|
||||
- **路径**:`POST /admin/finance/opening-balances`
|
||||
- **认证**:网关 JWT(admin)
|
||||
- **幂等性**:否。但同一供应商重复录入会被业务唯一性拦截,返回 598401(见 §七),不会产生脏数据
|
||||
- **限流**:无特殊限流
|
||||
|
||||
**表单最终形态(6 个元素,多了少了都是错)**:
|
||||
|
||||
| # | 表单元素 | 控件 | 必填 | 说明 |
|
||||
|---|---|---|---|---|
|
||||
| 1 | 供应商 | 下拉选择 | ✅ | 数据源见 §4.3;选中后提交 `refId` + `refName` |
|
||||
| 2 | 应付金额 | 数字输入 | ✅ | label 写「应付金额(我们欠供应商)」。**只有这一个金额框,不要画应收框** |
|
||||
| 3 | 所属公司 | 下拉选择 | ✅ | 数据源见 §4.4;提交 `companyId` |
|
||||
| 4 | 记账日期 | 只读展示 | — | 后端自动取当前未封账账期的 startDate 落库,**前端不传**;展示值来源见 §4.5 |
|
||||
| 5 | 佐证材料 | 图片上传 | ❌ 选填 | 上传后把 URL 填 `evidenceUrl`;不传则该字段不出现或为 null |
|
||||
| 6 | 备注 | 文本域 | ❌ 选填 | ≤ 200 字 |
|
||||
|
||||
**表单上不要出现的元素**:
|
||||
|
||||
| 不要出现 | 原因 |
|
||||
|---|---|
|
||||
| 往来对象 ID 手填框 | 供应商必须走下拉选择,ID 由选项带出,不允许手填雪花 ID |
|
||||
| 期初应收金额框 | 供应商账套只有应付,没有应收 |
|
||||
| 供应商名称手填框 | 名称由下拉选项自动带出(`refName`),不手填 |
|
||||
| 客户分类 | 那是应收账套(客户侧)的字段,供应商账套不传 |
|
||||
|
||||
## 四、接口入参
|
||||
|
||||
### 4.1 路径参数 / Query 参数
|
||||
|
||||
无。
|
||||
|
||||
### 4.2 请求体字段
|
||||
|
||||
| 字段 | 类型 | 必填 | 说明 | 校验规则 |
|
||||
|------|------|------|------|----------|
|
||||
| `ledgerType` | String | ✅ | 账套类型。本表单**固定传 `SUPPLIER`** | 枚举,见 §六 |
|
||||
| `refId` | String | ✅ | 供应商 ID(取下拉项的 `supplierId`) | 必须是存在的供应商 |
|
||||
| `refName` | String | ✅ | 供应商名称(取下拉项的 `fullName`) | ≤ 128 字 |
|
||||
| `companyId` | String | ✅ | 所属公司主体 ID(取下拉项的 `agencyId`) | 必须是启用中的公司主体,否则 598407 |
|
||||
| `openingPayable` | Number | ✅ | 应付期初金额(元) | 必填且 **> 0**,否则 598405 |
|
||||
| `evidenceUrl` | String | ❌ | 佐证材料图片 URL | 可空 / 不传 |
|
||||
| `remark` | String | ❌ | 备注 | ≤ 200 字 |
|
||||
|
||||
**不要传的字段**(传了属于画错账套):
|
||||
|
||||
| 字段 | 说明 |
|
||||
|---|---|
|
||||
| `openingReceivable` | 应收期初金额,供应商账套不传 |
|
||||
| `customerCategory` | 客户分类,应收账套(客户侧)字段,供应商账套不传 |
|
||||
| 记账日期相关字段 | 请求体里**没有**记账日期字段,后端自动取当前未封账账期 startDate,前端不传 |
|
||||
|
||||
> ⚠️ `refId` / `companyId` 后端是 Long 大数(雪花 ID),JSON 序列化为字符串下发;前端 JS 一律**当字符串处理**,不要 `Number()` 转换,防精度丢失。
|
||||
|
||||
### 4.3 供应商下拉数据源
|
||||
|
||||
- **路径**:`GET /admin/supplier/items/list`(资源服务)
|
||||
- **认证**:网关 JWT(admin)
|
||||
|
||||
Query 参数(全部选填):
|
||||
|
||||
| 字段 | 类型 | 必填 | 说明 |
|
||||
|------|------|------|------|
|
||||
| `status` | String | ❌ | 本表单**固定传 `ACTIVE`**(只在用供应商可录期初) |
|
||||
| `keyword` | String | ❌ | 名称 / 编号模糊搜索 |
|
||||
| `limit` | Integer | ❌ | 默认 50,最大 200 |
|
||||
|
||||
响应 `data` 为数组,每项字段:
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `supplierId` | String | 供应商 ID(Long 序列化字符串) |
|
||||
| `fullName` | String | 供应商全称(下拉显示用) |
|
||||
| `shortName` | String | 简称 |
|
||||
| `supplierNo` | String | 供应商编号 |
|
||||
| `statusName` | String | 状态中文名 |
|
||||
|
||||
**取值映射**:下拉显示 `fullName`;选中后提交 `refId = supplierId`、`refName = fullName`。
|
||||
|
||||
### 4.4 所属公司下拉数据源
|
||||
|
||||
- **路径**:`GET /v3/admin/travel-agency/enabled`(order-v3)
|
||||
- **认证**:网关 JWT(admin)
|
||||
- **入参**:无
|
||||
|
||||
响应 `data` 为数组,每项字段:
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `agencyId` | String | 公司主体 ID(Long 序列化字符串) |
|
||||
| `agencyName` | String | 公司名称(下拉显示用) |
|
||||
| `isPrimary` | Integer | 是否主体公司:1 = 是,0 = 否 |
|
||||
|
||||
**取值映射**:下拉显示 `agencyName`;`isPrimary = 1` 的主体公司**默认选中**;选中后提交 `companyId = agencyId`。公司名称由后端自取快照,前端不用传。
|
||||
|
||||
### 4.5 记账日期展示值来源(只读,不入参)
|
||||
|
||||
记账日期 = 当前**未封账**账期的 `startDate`,后端落库时自动取,前端不传。若表单上要展示该值:
|
||||
|
||||
- **路径**:`GET /admin/finance/account-periods/page`
|
||||
- **取数**:取返回列表中 `isClosed = 0`(未封账)那一行的 `startDate` 展示即可
|
||||
|
||||
## 五、出参
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `data` | String | 新建期初行 ID(Long 序列化字符串,JS 当字符串处理) |
|
||||
|
||||
外层为标准响应包:`code` / `data` / `message` / `success`。
|
||||
|
||||
## 六、枚举 / 数据字典
|
||||
|
||||
### 6.1 ledgerType(账套类型)
|
||||
|
||||
**所属字段**:请求体 `ledgerType` | **类型**:`String` | **必填**:✅
|
||||
|
||||
| 值 | 中文 | 说明 |
|
||||
|----|------|------|
|
||||
| `SUPPLIER` | 供应商 | 本表单固定传此值(供应商应付期初) |
|
||||
|
||||
> 接口本身支持其他账套值(应收侧等),但**本表单只涉及 `SUPPLIER`**,其他账套的表单形态不在本文档范围。
|
||||
|
||||
## 七、错误码
|
||||
|
||||
| code | 含义 | 触发场景 |
|
||||
|------|------|----------|
|
||||
| 598405 | 期初金额未填或 ≤ 0 | `openingPayable` 缺失 / 为 0 / 负数 |
|
||||
| 598401 | 该供应商期初已录过 | 同一供应商重复提交期初(已有期初的供应商要改金额走「期初调整」,不要重复录) |
|
||||
| 598407 | 所属公司非法或已停用 | `companyId` 不存在或该公司主体已停用 |
|
||||
| 598403 | 无未封账账期 | 当前没有 `isClosed = 0` 的账期,无法落记账日期 |
|
||||
|
||||
## 八、示例
|
||||
|
||||
### 8.1 典型成功
|
||||
|
||||
**请求**:
|
||||
|
||||
```http
|
||||
POST /admin/finance/opening-balances
|
||||
Authorization: Bearer <admin-token>
|
||||
Content-Type: application/json
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"ledgerType": "SUPPLIER",
|
||||
"refId": "1834567890123456789",
|
||||
"refName": "内蒙古某景区门票有限公司",
|
||||
"companyId": "1723456789012345678",
|
||||
"openingPayable": 1000.00,
|
||||
"evidenceUrl": "https://oss.example.com/finance/evidence/x.jpg",
|
||||
"remark": "2026 年度合作期初应付"
|
||||
}
|
||||
```
|
||||
|
||||
**响应**:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"data": "1956789012345678901",
|
||||
"message": "成功",
|
||||
"success": true
|
||||
}
|
||||
```
|
||||
|
||||
### 8.2 边界(佐证材料、备注均不传)
|
||||
|
||||
**场景说明**:`evidenceUrl` / `remark` 均为选填,最小合法请求只有 5 个字段。
|
||||
|
||||
**请求**:
|
||||
|
||||
```json
|
||||
{
|
||||
"ledgerType": "SUPPLIER",
|
||||
"refId": "1834567890123456789",
|
||||
"refName": "内蒙古某景区门票有限公司",
|
||||
"companyId": "1723456789012345678",
|
||||
"openingPayable": 0.01
|
||||
}
|
||||
```
|
||||
|
||||
**响应**:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"data": "1956789012345678902",
|
||||
"message": "成功",
|
||||
"success": true
|
||||
}
|
||||
```
|
||||
|
||||
### 8.3 业务失败(金额未填 / ≤ 0,触发 598405)
|
||||
|
||||
**请求**:
|
||||
|
||||
```json
|
||||
{
|
||||
"ledgerType": "SUPPLIER",
|
||||
"refId": "1834567890123456789",
|
||||
"refName": "内蒙古某景区门票有限公司",
|
||||
"companyId": "1723456789012345678",
|
||||
"openingPayable": 0
|
||||
}
|
||||
```
|
||||
|
||||
**响应**:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 598405,
|
||||
"data": null,
|
||||
"message": "期初金额未填或必须大于 0",
|
||||
"success": false
|
||||
}
|
||||
```
|
||||
|
||||
> 重复提交同一供应商则返回 `598401`(该供应商期初已录过,请走期初调整)。
|
||||
|
||||
## 九、业务边界
|
||||
|
||||
- ✅ **适用场景**:供应商首次录入应付期初,且当前存在未封账账期、所属公司主体启用中。
|
||||
- ❌ **不适用场景**:
|
||||
- 该供应商已录过期初 → 598401,改金额请走「期初调整」功能,不要重复提交本接口;
|
||||
- 无未封账账期 → 598403;
|
||||
- 所属公司已停用 → 598407。
|
||||
- ⚠️ **特殊边界**:记账日期不可指定历史 / 未来日期,恒等于当前未封账账期 startDate(后端落库)。
|
||||
|
||||
## 十、修改前后对比(前端错误实现 vs 正确实现)
|
||||
|
||||
> 后端接口**零改动**,本节对比的是前端表单的「当前错误实现」与「正确实现」。
|
||||
|
||||
### 10.1 表单元素级对比
|
||||
|
||||
| 表单元素 | 错误实现(当前) | 正确实现 |
|
||||
|---|---|---|
|
||||
| 供应商 | 手填往来对象 ID(雪花 ID)输入框 | 下拉选择(数据源 `GET /admin/supplier/items/list?status=ACTIVE`),选中后自动带 `refId` + `refName` |
|
||||
| 供应商名称 | 手填输入框 | **不出现**,由下拉选项带出(`fullName` → `refName`) |
|
||||
| 金额 | 应收 + 应付**两个**金额框 | **只有一个**金额框:「应付金额(我们欠供应商)」,必填 > 0 |
|
||||
| 客户分类 | 出现下拉 | **不出现**(应收账套字段,供应商账套不传 `customerCategory`) |
|
||||
| 佐证材料 | 必填 | **选填**(`evidenceUrl` 可空) |
|
||||
| 记账日期 | 前端手填 / 传参 | **只读展示、不传参**,后端自动取当前未封账账期 startDate |
|
||||
|
||||
### 10.2 提交报文级对比
|
||||
|
||||
| 项 | 错误实现(当前) | 正确实现 |
|
||||
|---|---|---|
|
||||
| `refId` | 手填数字 / Number 类型 | 下拉带出,字符串原样提交 |
|
||||
| `openingReceivable` | 出现在 body | **不传** |
|
||||
| `customerCategory` | 出现在 body | **不传** |
|
||||
| `evidenceUrl` | 必填校验拦截提交 | 可空 |
|
||||
| 记账日期字段 | 出现在 body | **不传**(body 里本就没这个字段) |
|
||||
|
||||
## 十一、影响评估 / 回滚
|
||||
|
||||
- **是否破坏向后兼容**:否。后端接口零改动,已按正确形态对接的调用不受影响。
|
||||
- **前端是否必须同步上线**:是。当前错误表单提交必被 598405 / 598407 等拦截或录错账套,需尽快按本文档修正。
|
||||
- **影响已有数据**:无(无 DDL、无数据迁移)。
|
||||
- **回滚方案**:后端无动作;前端如需回退,回退表单版本即可。
|
||||
|
||||
## 十二、注意事项
|
||||
|
||||
- ⚠️ `refId` / `companyId` / 响应 `data` 均为 Long 大数序列化的字符串,JS 全程当字符串处理,禁止 `Number()` 转换(精度丢失)。
|
||||
- ⚠️ 供应商账套**只有一个金额框**(应付)。出现应收框 / 客户分类 = 套错了应收账套的表单。
|
||||
- ⚠️ 佐证材料是**选填**,不要加必填校验拦截提交。
|
||||
- ⚠️ 记账日期前端不传;如需展示,查 `GET /admin/finance/account-periods/page` 取 `isClosed = 0` 行的 `startDate`。
|
||||
|
||||
## 十三、关联 / 联系人
|
||||
|
||||
### 13.1 链接
|
||||
|
||||
- Issue:无(前端对接纠偏,无后端改动)
|
||||
- PR:无(前端对接纠偏,无后端改动)
|
||||
- Merge commit:无
|
||||
|
||||
### 13.2 联系人
|
||||
|
||||
- 后端负责人:yst
|
||||
在新工单中引用
屏蔽一个用户