docs(finance): 补推期初建账/业务外收支/出纳/费用报销 changelog(#7164/#7165/#7217/#7232)
changelog-filename-gate / validate (push) Failing after 1s
changelog-filename-gate / validate (push) Failing after 1s
这个提交包含在:
@@ -0,0 +1,229 @@
|
||||
---
|
||||
schema: "hl-changelog/v2"
|
||||
ticket: "7164"
|
||||
title: "往来期初建账(客户应收 / 供应商应付 / 员工往来 三本账)"
|
||||
consumer: "admin"
|
||||
author: "yst"
|
||||
change_type: "新增接口"
|
||||
backend_status: "deployed"
|
||||
gateway_status: "verified"
|
||||
frontend_status: "pending"
|
||||
frontend_owner: "hl-admin"
|
||||
frontend_ref: ""
|
||||
target_release: ""
|
||||
verified_at: "2026-09-06"
|
||||
status_note: "后端已合 dev-v3(hl-finance ledger 域)并部署测试服,E2E 验证通过。期初基准日=当前未封账账期起始日;净额=INIT+ΣADJUST 现算。"
|
||||
updated_at: "2026-09-06"
|
||||
base: "dev-v3"
|
||||
---
|
||||
|
||||
# 往来期初建账
|
||||
|
||||
## 1. 接口背景
|
||||
财务域「期初建账」:系统启用财务模块时,对客户应收、供应商应付、员工往来三本账做期初余额的一次性录入与后续调整。期初金额必须附佐证材料(影像 URL),期初基准日由后端取当前未封账账期的起始日,前端无需传。
|
||||
|
||||
- 路径前缀:`/admin/finance/opening-balances`(3 个新端点)
|
||||
- 服务:hl-finance(财务服务)
|
||||
|
||||
## 2. 变更清单
|
||||
| 类型 | 接口 | 说明 |
|
||||
|---|---|---|
|
||||
| 新增 | GET `/admin/finance/opening-balances/page` | 往来期初分页(按账套过滤,支持类别/往来对象名筛选) |
|
||||
| 新增 | POST `/admin/finance/opening-balances` | 往来期初一次录入(同往来对象仅可录入一次初始期初) |
|
||||
| 新增 | POST `/admin/finance/opening-balances/adjust` | 往来期初调整单(须已录入初始期初;存调整全量值非差额) |
|
||||
|
||||
## 3. 接口详情
|
||||
|
||||
### 3.1 期初分页 GET /page
|
||||
- 使用场景:管理后台「期初建账」三个页签(客户应收 / 供应商应付 / 员工往来)的列表查询,页签切换 = 换 `ledgerType`。
|
||||
- 认证:管理后台管理员 Token(`Authorization: Bearer <admin-token>`),未登录返 401。
|
||||
- 幂等性:查询接口,天然幂等。
|
||||
- 限流:网关默认限流,无特殊配置。
|
||||
|
||||
### 3.2 期初一次录入 POST /
|
||||
- 使用场景:首次为某往来对象建立期初余额(INIT 行)。同一 `(ledgerType, refId)` 仅允许一条 INIT,重复录入报 598401。
|
||||
- 认证:同上。幂等性:非幂等(重复提交报 598401 不会产生重复 INIT 行,前端提交后应禁用按钮)。
|
||||
- 限流:网关默认。
|
||||
|
||||
### 3.3 期初调整单 POST /adjust
|
||||
- 使用场景:已录入 INIT 后修正期初金额。**存的是调整后全量值(非差额)**,每次调整落一行 `kind=ADJUST`,当前净额 = INIT + ΣADJUST 由后端现算。
|
||||
- 认证:同上。幂等性:非幂等(每次提交落一行调整记录)。
|
||||
- 限流:网关默认。
|
||||
|
||||
## 4. 接口入参
|
||||
|
||||
### 4.1 分页 Query(OpeningBalancePageReqVO)
|
||||
|
||||
| 字段 | 类型 | 必填 | 约束 | 说明 |
|
||||
|---|---|---:|---|---|
|
||||
| `ledgerType` | String | 是 | `CUSTOMER`/`SUPPLIER`/`STAFF` | 账套:CUSTOMER 客户应收 / SUPPLIER 供应商应付 / STAFF 员工往来 |
|
||||
| `kind` | String | 否 | `INIT`/`ADJUST` | 类别:INIT 初始 / ADJUST 期初调整;空=全部 |
|
||||
| `refName` | String | 否 | 模糊匹配 | 往来对象名筛选;空=不限 |
|
||||
| `page` | Number | 否 | ≥1,默认 1 | 页码 |
|
||||
| `pageSize` | Number | 否 | 默认 20 | 每页条数 |
|
||||
|
||||
### 4.2 一次录入 Body(OpeningBalanceCreateReqVO)
|
||||
|
||||
| 字段 | 类型 | 必填 | 约束 | 说明 |
|
||||
|---|---|---:|---|---|
|
||||
| `ledgerType` | String | 是 | 同上枚举 | 账套 |
|
||||
| `refId` | Number | 是 | — | 往来对象 ID(客户/供应商/员工主键,按账套对应) |
|
||||
| `refName` | String | 是 | ≤128 字 | 往来对象名称(冗余快照,落库后不随主数据改名) |
|
||||
| `openingPayable` | Number | 条件 | >0 | 期初应付(我欠他);与 openingReceivable 至少填一项 |
|
||||
| `openingReceivable` | Number | 条件 | >0 | 期初应收(他欠我们);与 openingPayable 至少填一项 |
|
||||
| `evidenceUrl` | String | 是 | — | 佐证材料影像 URL(必传,缺失抛 598402) |
|
||||
| `remark` | String | 否 | ≤200 字 | 备注 |
|
||||
|
||||
### 4.3 调整单 Body(OpeningBalanceAdjustReqVO)
|
||||
|
||||
| 字段 | 类型 | 必填 | 约束 | 说明 |
|
||||
|---|---|---:|---|---|
|
||||
| `ledgerType` | String | 是 | 同上枚举 | 账套 |
|
||||
| `refId` | Number | 是 | — | 往来对象 ID(须已存在 INIT 行,否则 598404) |
|
||||
| `openingPayable` | Number | 否 | >0 | 调整后**全量**期初应付(不调整传 null) |
|
||||
| `openingReceivable` | Number | 否 | >0 | 调整后**全量**期初应收(不调整传 null) |
|
||||
| `evidenceUrl` | String | 是 | — | 佐证材料影像 URL(必传,缺失抛 598402) |
|
||||
| `reason` | String | 是 | ≤200 字 | 调整原因(必填留痕) |
|
||||
|
||||
## 5. 出参字段
|
||||
|
||||
### 5.1 分页行(OpeningBalanceRowRespVO)
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|---|---|---|
|
||||
| `id` | String | 期初行 ID(雪花 ID,Long 序列化为字符串防 JS 精度丢失) |
|
||||
| `ledgerType` | String | 账套码(CUSTOMER/SUPPLIER/STAFF) |
|
||||
| `refId` | String | 往来对象 ID(雪花字符串) |
|
||||
| `refName` | String | 往来对象名称快照 |
|
||||
| `openingDate` | String | 期初基准日(yyyy-MM-dd,= 当前未封账账期起始日,后端带入) |
|
||||
| `kind` | String | 类别:INIT 初始 / ADJUST 期初调整 |
|
||||
| `openingPayable` | Number | 期初应付(无 = null) |
|
||||
| `openingReceivable` | Number | 期初应收(无 = null) |
|
||||
| `evidenceUrl` | String | 佐证材料影像 URL |
|
||||
| `recordedByName` | String | 录入人姓名快照 |
|
||||
| `createTime` | String | 创建时间(yyyy-MM-dd HH:mm:ss) |
|
||||
|
||||
分页包裹:`data.records[]` / `data.total` / `data.page` / `data.pageSize`。
|
||||
|
||||
### 5.2 录入 / 调整响应(OpeningBalanceIdRespVO)
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|---|---|---|
|
||||
| `id` | String | 新落库期初行 ID(雪花字符串) |
|
||||
|
||||
## 6. 枚举 / 数据字典
|
||||
|
||||
### `ledgerType`(账套,代码枚举)
|
||||
| 值 | 中文 | 说明 |
|
||||
|---|---|---|
|
||||
| `CUSTOMER` | 客户应收 | 客户欠我们的期初 |
|
||||
| `SUPPLIER` | 供应商应付 | 我们欠供应商的期初 |
|
||||
| `STAFF` | 员工往来 | 员工借款/备用金期初 |
|
||||
|
||||
### `kind`(期初行类别,代码枚举)
|
||||
| 值 | 中文 | 说明 |
|
||||
|---|---|---|
|
||||
| `INIT` | 初始期初 | 首次录入,同往来对象唯一 |
|
||||
| `ADJUST` | 期初调整 | 调整单,存调整后全量值,可多条 |
|
||||
|
||||
## 7. 错误码(段位 598400-598499)
|
||||
|
||||
| 错误码 | 含义 | 触发场景 |
|
||||
|---|---|---|
|
||||
| 598401 | 该往来对象期初已录入 | 同 `(ledgerType, refId)` 重复 POST 录入 INIT |
|
||||
| 598402 | 佐证材料必传 | `evidenceUrl` 为空 |
|
||||
| 598403 | 账期已封账,不允许录入或调整期初 | 当前账期已封账 / 无未封账账期(视同未开账) |
|
||||
| 598404 | 该往来对象尚未录入初始期初,不可调整 | POST /adjust 时无 INIT 行 |
|
||||
| 598405 | 期初应付/应收须至少填一项 | 两项均空或均 ≤0 |
|
||||
| 598406 | 账套类型非法,须为 SUPPLIER、CUSTOMER 或 STAFF | `ledgerType` 传其他值 |
|
||||
|
||||
## 8. 示例
|
||||
|
||||
### 8.1 典型成功(供应商应付期初录入)
|
||||
```http
|
||||
POST /admin/finance/opening-balances
|
||||
Authorization: Bearer <admin-token>
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"ledgerType": "SUPPLIER",
|
||||
"refId": 2094123456789012345,
|
||||
"refName": "云山景区管理有限公司",
|
||||
"openingPayable": 50000.00,
|
||||
"openingReceivable": null,
|
||||
"evidenceUrl": "https://oss.example.com/evidence/abc.jpg",
|
||||
"remark": "2026 年 8 月对账单确认"
|
||||
}
|
||||
```
|
||||
```json
|
||||
{"code":200,"message":"成功","success":true,"data":{"id":"2094300011122233445"}}
|
||||
```
|
||||
|
||||
分页查询:
|
||||
```http
|
||||
GET /admin/finance/opening-balances/page?ledgerType=SUPPLIER&page=1&pageSize=20
|
||||
```
|
||||
```json
|
||||
{"code":200,"success":true,"data":{"records":[{"id":"2094300011122233445","ledgerType":"SUPPLIER","refId":"2094123456789012345","refName":"云山景区管理有限公司","openingDate":"2026-09-01","kind":"INIT","openingPayable":50000.00,"openingReceivable":null,"evidenceUrl":"https://oss.example.com/evidence/abc.jpg","recordedByName":"腰苏图","createTime":"2026-09-06 10:00:00"}],"total":1,"page":1,"pageSize":20}}
|
||||
```
|
||||
|
||||
### 8.2 边界情况(期初调整为零 / 双项同调)
|
||||
调整单传全量值,可把某项调成新值、另一项保持 null 不动:
|
||||
```json
|
||||
{
|
||||
"ledgerType": "SUPPLIER",
|
||||
"refId": 2094123456789012345,
|
||||
"openingPayable": 48000.00,
|
||||
"openingReceivable": null,
|
||||
"evidenceUrl": "https://oss.example.com/evidence/def.jpg",
|
||||
"reason": "对方减免 2000 元尾款"
|
||||
}
|
||||
```
|
||||
```json
|
||||
{"code":200,"success":true,"data":{"id":"2094300099988877766"}}
|
||||
```
|
||||
空分页:无数据时 `records=[]`、`total=0`,HTTP 200,前端正常渲染空列表。
|
||||
|
||||
### 8.3 业务失败(重复录入 / 未录初始就调整)
|
||||
```http
|
||||
POST /admin/finance/opening-balances # 同一 refId 再次录入
|
||||
```
|
||||
```json
|
||||
{"code":598401,"message":"该往来对象期初已录入","success":false,"data":null}
|
||||
```
|
||||
```http
|
||||
POST /admin/finance/opening-balances/adjust # 该对象从未录入 INIT
|
||||
```
|
||||
```json
|
||||
{"code":598404,"message":"该往来对象尚未录入初始期初,不可调整","success":false,"data":null}
|
||||
```
|
||||
缺佐证材料:`{"code":598402,"message":"佐证材料必传"}`;两项金额均空:`{"code":598405,"message":"期初应付/应收须至少填一项"}`。
|
||||
|
||||
## 9. 业务边界
|
||||
|
||||
**适用**:
|
||||
- 财务模块上线初始化时,批量为三本账建立期初基准。
|
||||
- 期初金额有误时,通过调整单修正(保留全部调整留痕)。
|
||||
|
||||
**不适用 / 限制**:
|
||||
- 同往来对象只能录入一次 INIT,后续一律走调整单。
|
||||
- 账期封账后禁止录入与调整(598403);未开账(无未封账账期)同样拦截。
|
||||
- 期初基准日不可指定,由后端取当前未封账账期的 `start_date`。
|
||||
- 期初数据**暂未回流勾稽到往来账**(方案 A,留 TODO 接缝),本期仅作独立台账。
|
||||
|
||||
**特殊边界**:
|
||||
- `refName` 是冗余快照,主数据改名不影响历史期初行显示。
|
||||
- 调整单存**全量值**不是差额,前端表单应展示「调整后金额」而非「调增/调减」。
|
||||
|
||||
## 10. 注意事项
|
||||
- 所有雪花 ID(`id` / `refId`)均已序列化为字符串,前端按 String 处理,勿转 Number。
|
||||
- `openingDate` 由后端带入,入参里没有该字段。
|
||||
- 前端三个页签(客户应收 / 供应商应付 / 员工往来)对应 `ledgerType` 三值,建议页签切换即重置筛选条件重新查询。
|
||||
- 新表 `fin_opening_balance`(Flyway `V20260906_101`),部署时自动执行,无需前端动作。
|
||||
|
||||
## 11. 关联 / 联系人
|
||||
- Issue:https://git.1814.love:8443/wx/HL/issues/7164
|
||||
- PR:https://git.1814.love:8443/wx/HL/pulls/7166
|
||||
- Commit:https://git.1814.love:8443/wx/HL/commit/d0f06fa2e8
|
||||
- Epic:https://git.1814.love:8443/wx/HL/issues/7163
|
||||
- 负责人:腰苏图(yst)
|
||||
@@ -0,0 +1,274 @@
|
||||
---
|
||||
schema: "hl-changelog/v2"
|
||||
ticket: "7165"
|
||||
title: "业务外收支流水(收入 IN / 支出 OUT 同表两入口)"
|
||||
consumer: "admin"
|
||||
author: "yst"
|
||||
change_type: "新增接口"
|
||||
backend_status: "deployed"
|
||||
gateway_status: "verified"
|
||||
frontend_status: "pending"
|
||||
frontend_owner: "hl-admin"
|
||||
frontend_ref: ""
|
||||
target_release: ""
|
||||
verified_at: "2026-09-06"
|
||||
status_note: "后端已合 dev-v3(hl-finance nonbiz 域)并部署测试服,E2E 验证通过。本期状态机只落 PENDING 草稿;提交/审批端点在 PR #7221 补齐,勾稽联动留 TODO。"
|
||||
updated_at: "2026-09-06"
|
||||
base: "dev-v3"
|
||||
---
|
||||
|
||||
# 业务外收支流水
|
||||
|
||||
## 1. 接口背景
|
||||
财务域「业务外收支」:记录与订单业务无关的公司收支(如利息收入、罚款支出、押金退回等),收入(IN)与支出(OUT)同表同接口、靠 direction 区分,管理后台拆成「业务外收入」「业务外支出」两个菜单页签。单据落库为 PENDING 草稿,本期草稿可编辑/删除;提交与审批流转在后续 PR #7221 补齐。
|
||||
|
||||
- 路径前缀:/admin/finance/nonbiz-flows(5 个新端点)
|
||||
- 服务:hl-finance(财务服务)
|
||||
|
||||
## 2. 变更清单
|
||||
| 类型 | 接口 | 说明 |
|
||||
|---|---|---|
|
||||
| 新增 | GET /admin/finance/nonbiz-flows/page | 业务外收支分页(direction 必填区分收入/支出页签) |
|
||||
| 新增 | POST /admin/finance/nonbiz-flows | 业务外收支申请(收入/支出同接口,落 PENDING 草稿) |
|
||||
| 新增 | GET /admin/finance/nonbiz-flows/{id} | 收支单详情(收入/支出通用全字段) |
|
||||
| 新增 | PUT /admin/finance/nonbiz-flows/{id} | 编辑收支草稿(仅 PENDING;direction 不可改) |
|
||||
| 新增 | DELETE /admin/finance/nonbiz-flows/{id} | 删除收支草稿(仅 PENDING,软删) |
|
||||
|
||||
## 3. 接口详情
|
||||
|
||||
### 3.1 分页 GET /page
|
||||
- 使用场景:管理后台「业务外收入」「业务外支出」两个菜单共用一个接口,菜单切换 = 换 direction(IN/OUT)。
|
||||
- 认证:管理后台管理员 Token(Authorization: Bearer admin-token),未登录返 401。
|
||||
- 幂等性:查询接口,天然幂等。限流:网关默认。
|
||||
|
||||
### 3.2 申请 POST /
|
||||
- 使用场景:财务录入一笔业务外收入或支出,落 PENDING 草稿。
|
||||
- 认证:同上。幂等性:非幂等(每次创建生成新单据,前端提交后应禁用按钮)。限流:网关默认。
|
||||
|
||||
### 3.3 详情 GET /{id}
|
||||
- 使用场景:列表行点击进详情抽屉/页。
|
||||
- 认证:同上。幂等:查询接口。限流:网关默认。
|
||||
|
||||
### 3.4 编辑 PUT /{id}
|
||||
- 使用场景:修改 PENDING 草稿的类别/单位/金额/凭证等字段;方向不可改(收入单不能改成支出单)。
|
||||
- 认证:同上。幂等性:同参数重复提交效果一致。限流:网关默认。
|
||||
|
||||
### 3.5 删除 DELETE /{id}
|
||||
- 使用场景:作废 PENDING 草稿(软删,单据从所有列表消失)。
|
||||
- 认证:同上。幂等性:重复删除返 598504。限流:网关默认。
|
||||
|
||||
## 4. 接口入参
|
||||
|
||||
### 4.1 分页 Query(NonbizFlowPageReqVO)
|
||||
|
||||
| 字段 | 类型 | 必填 | 约束 | 说明 |
|
||||
|---|---|---:|---|---|
|
||||
| direction | String | 是 | IN/OUT | 方向:IN 业务外收入 / OUT 业务外支出 |
|
||||
| category | String | 否 | — | 收支类别码(fin_nonbiz_category,按方向分组);空=不限 |
|
||||
| unitId | Number | 否 | — | 外部单位 ID;空=不限 |
|
||||
| status | String | 否 | 见状态枚举 | 单据状态;空=全部 |
|
||||
| occurDateStart | String | 否 | yyyy-MM-dd | 发生日期起 |
|
||||
| occurDateEnd | String | 否 | yyyy-MM-dd | 发生日期止 |
|
||||
| page | Number | 否 | 默认 1 | 页码 |
|
||||
| pageSize | Number | 否 | 默认 20 | 每页条数 |
|
||||
|
||||
### 4.2 申请 Body(NonbizFlowCreateReqVO)
|
||||
|
||||
| 字段 | 类型 | 必填 | 约束 | 说明 |
|
||||
|---|---|---:|---|---|
|
||||
| direction | String | 是 | IN/OUT | 方向 |
|
||||
| category | String | 是 | 不超64字 | 收支类别码,须为 fin_nonbiz_category 同方向组的正常项(598502) |
|
||||
| unitId | Number | 是 | — | 外部单位 ID(本期仅非空校验,存在性校验待往来账域接缝) |
|
||||
| unitName | String | 是 | 不超128字 | 外部单位名(冗余快照) |
|
||||
| amount | Number | 是 | 大于0 | 收支金额(598501) |
|
||||
| feeRate | Number | 否 | 千分率 | 手续费率(默认 0;收入页改动自动重算 fee) |
|
||||
| fee | Number | 否 | 不小于0 | 手续费(收入缺省按费率算、可手改;支出手填;actualAmount 联动重算) |
|
||||
| fundAccountId | Number | 否 | — | 入/出账公司账户 ID(空=批准时仅入账不联动资金结存) |
|
||||
| occurDate | String | 是 | yyyy-MM-dd | 发生日期 |
|
||||
| payMethod | String | 否 | 不超32字 | 收付方式(字典 fin_pay_way 码值) |
|
||||
| deptId | Number | 否 | — | 归属部门 ID(公司主体;用户域部门树) |
|
||||
| voucherNo | String | 否 | 不超64字 | 凭证号 |
|
||||
| voucherUrl | String | 否 | 不超500字 | 凭证影像 URL |
|
||||
| remark | String | 否 | 不超200字 | 备注 |
|
||||
|
||||
### 4.3 编辑 Body(NonbizFlowUpdateReqVO)
|
||||
字段与申请 Body 完全一致,唯不含 direction(方向由单据自身决定,编辑不换方向),见 4.2 表。
|
||||
|
||||
### 4.4 路径参数
|
||||
| 接口 | 字段 | 类型 | 说明 |
|
||||
|---|---|---|---|
|
||||
| GET/PUT/DELETE /{id} | id | Number | 收支单 ID(路径传数字即可,响应中为字符串) |
|
||||
|
||||
## 5. 出参字段
|
||||
|
||||
### 5.1 分页行(NonbizFlowRowRespVO)
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|---|---|---|
|
||||
| id | String | 收支单 ID(雪花字符串) |
|
||||
| direction | String | 方向:IN / OUT |
|
||||
| category | String | 收支类别码 |
|
||||
| categoryName | String | 收支类别中文名(取自 fin_nonbiz_category;类别停用不影响历史单据回显) |
|
||||
| unitId | String | 外部单位 ID(雪花字符串) |
|
||||
| unitName | String | 外部单位名快照 |
|
||||
| amount | Number | 收支金额 |
|
||||
| fee | Number | 手续费(挂本单) |
|
||||
| actualAmount | Number | 实收/实付 = amount − fee |
|
||||
| deptId | String | 归属部门 ID(雪花字符串) |
|
||||
| operatorName | String | 经办人姓名快照 |
|
||||
| occurDate | String | 发生日期(yyyy-MM-dd) |
|
||||
| status | String | 单据状态码 |
|
||||
| payMethod | String | 收付方式码值(字典 fin_pay_way) |
|
||||
| payMethodName | String | 收付方式中文名(字典标签,字典缺失时为空) |
|
||||
|
||||
### 5.2 详情(NonbizFlowDetailRespVO)
|
||||
列表行全字段 + 以下增量字段:
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|---|---|---|
|
||||
| feeRate | Number | 手续费率(千分率) |
|
||||
| fundAccountId | String | 入/出账公司账户 ID(空=批准时仅入账不联动结存) |
|
||||
| operatorId | String | 经办人 ID(雪花字符串) |
|
||||
| voucherNo | String | 凭证号 |
|
||||
| voucherUrl | String | 凭证影像 URL |
|
||||
| remark | String | 备注 |
|
||||
| createTime | String | 创建时间(yyyy-MM-dd HH:mm:ss) |
|
||||
|
||||
### 5.3 申请响应(NonbizFlowIdRespVO)
|
||||
| 字段 | 类型 | 说明 |
|
||||
|---|---|---|
|
||||
| id | String | 新建收支单 ID(PENDING 草稿) |
|
||||
|
||||
### 5.4 编辑 / 删除响应
|
||||
data 为 null(Result<Void>),code=200 即成功。
|
||||
|
||||
## 6. 枚举 / 数据字典
|
||||
|
||||
### direction(方向,代码枚举)
|
||||
| 值 | 中文 |
|
||||
|---|---|
|
||||
| IN | 业务外收入 |
|
||||
| OUT | 业务外支出 |
|
||||
|
||||
### status(单据状态,代码枚举)
|
||||
| 值 | 中文 | 说明 |
|
||||
|---|---|---|
|
||||
| PENDING | 草稿 | 可编辑可删除(本期创建后唯一状态) |
|
||||
| SUBMITTED | 审批中 | 提交后锁定(流转端点在 PR #7221 补齐) |
|
||||
| APPROVED | 已批准 | 待出纳收付(流转端点在 PR #7221 补齐) |
|
||||
| REJECTED | 已驳回 | 审批驳回 |
|
||||
| PAID | 已收付讫 | 出纳执行完成,终态 |
|
||||
|
||||
### category(收支类别,基础数据表 fin_nonbiz_category)
|
||||
- 按类别码传值;类别按方向分组(IN 组 / OUT 组),跨组传值报 598502。
|
||||
- 类别维护走「业务外收支分类」管理接口(见 09_7052 changelog)。
|
||||
|
||||
### payMethod(收付方式,数据字典 fin_pay_way,dict_type_id=10157)
|
||||
| 码值 | 中文 |
|
||||
|---|---|
|
||||
| CASH | 现金 |
|
||||
| BANK_TRANSFER | 银行转账 |
|
||||
| WECHAT | 微信 |
|
||||
| ALIPAY | 支付宝 |
|
||||
|
||||
字典标签由后端回显为 payMethodName,前端列表/详情直接展示,无需自行映射。
|
||||
|
||||
## 7. 错误码(段位 598500-598599)
|
||||
|
||||
| 错误码 | 含义 | 触发场景 |
|
||||
|---|---|---|
|
||||
| 598501 | 金额无效(收支金额须大于0,且实收/实付不得为负) | amount≤0、fee<0 或 amount−fee<0 |
|
||||
| 598502 | 收支类别不存在或不属于该方向组 | category 不存在 / 跨方向组 / 已停用 |
|
||||
| 598503 | 当前状态不允许此操作,仅草稿可编辑或删除 | 非 PENDING 状态调 PUT/DELETE |
|
||||
| 598504 | 收支单不存在 | 详情/编辑/删除传错 ID(或已软删) |
|
||||
| 598505 | 状态流转非法(提交须草稿态,批准须审批中) | 状态机推进校验(流转端点见 PR #7221 changelog) |
|
||||
| 598506 | 方向非法,须为 IN 或 OUT | direction 传其他值 |
|
||||
|
||||
## 8. 示例
|
||||
|
||||
### 8.1 典型成功(录一笔业务外支出)
|
||||
```http
|
||||
POST /admin/finance/nonbiz-flows
|
||||
Authorization: Bearer <admin-token>
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"direction": "OUT",
|
||||
"category": "DEPOSIT_REFUND",
|
||||
"unitId": 2094001122334455667,
|
||||
"unitName": "市文旅局",
|
||||
"amount": 2000.00,
|
||||
"fee": 0,
|
||||
"fundAccountId": 2097009988776655443,
|
||||
"occurDate": "2026-09-05",
|
||||
"payMethod": "BANK_TRANSFER",
|
||||
"deptId": 10086,
|
||||
"voucherNo": "PZ-20260905-01",
|
||||
"voucherUrl": "https://oss.example.com/voucher/pz01.jpg",
|
||||
"remark": "质保金退回"
|
||||
}
|
||||
```
|
||||
```json
|
||||
{"code":200,"message":"成功","success":true,"data":{"id":"2094311122233344455"}}
|
||||
```
|
||||
|
||||
收入页签分页:
|
||||
```http
|
||||
GET /admin/finance/nonbiz-flows/page?direction=IN&page=1&pageSize=20&status=PENDING
|
||||
```
|
||||
```json
|
||||
{"code":200,"success":true,"data":{"records":[{"id":"2094311000000000001","direction":"IN","category":"INTEREST","categoryName":"利息收入","unitId":"2094001122334455667","unitName":"某银行","amount":500.00,"fee":0,"actualAmount":500.00,"deptId":"10086","operatorName":"腰苏图","occurDate":"2026-09-01","status":"PENDING","payMethod":"BANK_TRANSFER","payMethodName":"银行转账"}],"total":1,"page":1,"pageSize":20}}
|
||||
```
|
||||
|
||||
### 8.2 边界情况(可选项全空 / 最小金额)
|
||||
```json
|
||||
{
|
||||
"direction": "OUT",
|
||||
"category": "FINE",
|
||||
"unitId": 2094001122334455667,
|
||||
"unitName": "交管局",
|
||||
"amount": 0.01,
|
||||
"occurDate": "2026-09-06"
|
||||
}
|
||||
```
|
||||
最小金额 0.01、可选项(feeRate/fee/fundAccountId/payMethod/deptId/voucher*/remark)全省略也可创建;actualAmount 后端按 amount − fee(默认0) 算好返回。空分页:records=[]、total=0,HTTP 200,前端正常渲染空列表。
|
||||
|
||||
### 8.3 业务失败(类别跨方向组 / 编辑非草稿)
|
||||
direction=IN 但传了 OUT 组的类别码:
|
||||
```json
|
||||
{"code":598502,"message":"收支类别不存在或不属于该方向组","success":false,"data":null}
|
||||
```
|
||||
对非 PENDING 单据调 PUT/DELETE:
|
||||
```json
|
||||
{"code":598503,"message":"当前状态不允许此操作,仅草稿可编辑或删除","success":false,"data":null}
|
||||
```
|
||||
amount=0 时:{"code":598501,"message":"金额无效(收支金额须大于0,且实收/实付不得为负)"}。
|
||||
|
||||
## 9. 业务边界
|
||||
|
||||
适用:
|
||||
- 与订单无关的公司收支记账(利息、罚款、押金、捐赠等)。
|
||||
|
||||
不适用 / 限制:
|
||||
- 本期(PR #7179)只落 PENDING 草稿 + 草稿编辑/删除;提交/审批流转端点在 PR #7221 补齐(submit/approve),状态机走到 PAID 依赖出纳域 cashier 端点。
|
||||
- 勾稽联动(批准后联动资金结存、进出纳队列、企微审批)本期未接通(方案 A,留 TODO 接缝);fundAccountId 传了也只是记账引用,不会在批准时自动动账——动账由出纳域执行。
|
||||
- unitId 本期仅非空校验,不校验外部单位真实存在(待往来账域接缝,Epic #7163)。
|
||||
- direction 创建后不可改;改方向 = 删草稿重新录。
|
||||
|
||||
特殊边界:
|
||||
- fee 收入单缺省按 feeRate(千分率)自动算、可手改覆盖;支出单手填。改 amount/feeRate/fee 后端联动重算 actualAmount。
|
||||
- 类别停用不删,历史单据 categoryName 正常回显。
|
||||
|
||||
## 10. 注意事项
|
||||
- 所有雪花 ID 均为字符串,前端按 String 处理,勿转 Number。
|
||||
- 两个菜单(收入/支出)共用接口,direction 必填,建议菜单切换即重置筛选重新查询。
|
||||
- payMethodName / categoryName 由后端字典回显,前端不要自己维护码表。
|
||||
- 新表 fin_nonbiz_flow(Flyway V20260906_102)+ 新字典 fin_pay_way(user-service V20260906_003,dict_type_id=10157),部署顺序先 user-service 后 finance,均部署自动执行。
|
||||
- 提交/审批端点(PUT /{id}/submit、/{id}/approve)与出纳付款能力见「07_7217_支付管理出纳」changelog。
|
||||
|
||||
## 11. 关联 / 联系人
|
||||
- Issue:https://git.1814.love:8443/wx/HL/issues/7165
|
||||
- PR:https://git.1814.love:8443/wx/HL/pulls/7179
|
||||
- Commit:https://git.1814.love:8443/wx/HL/commit/dc3b306f73
|
||||
- Epic:https://git.1814.love:8443/wx/HL/issues/7163
|
||||
- 负责人:腰苏图(yst)
|
||||
@@ -0,0 +1,290 @@
|
||||
---
|
||||
schema: "hl-changelog/v2"
|
||||
ticket: "7217"
|
||||
title: "支付管理·出纳(待付款队列 / 登记付款 / 已付款台账 / 收款确认 + 业务外状态机补全)"
|
||||
consumer: "admin"
|
||||
author: "yst"
|
||||
change_type: "新增接口"
|
||||
backend_status: "deployed"
|
||||
gateway_status: "verified"
|
||||
frontend_status: "pending"
|
||||
frontend_owner: "hl-admin"
|
||||
frontend_ref: ""
|
||||
target_release: ""
|
||||
verified_at: "2026-09-07"
|
||||
status_note: "后端已合 dev-v3(hl-finance cashier 域)并部署测试服。出纳统一付款执行出口:记资金流水 + 回写业务单 PAID + 重算结存 + 透支闸;本期队列/登记仅接通 NONBIZ 业务外线。"
|
||||
updated_at: "2026-09-07"
|
||||
base: "dev-v3"
|
||||
---
|
||||
|
||||
# 支付管理(出纳统一收付执行)
|
||||
|
||||
## 1. 接口背景
|
||||
财务域「支付管理」:出纳统一收付执行出口。上游业务单(本期=业务外支出)审批通过后进入出纳待付款队列,出纳在队列里选单登记付款——后端同事务完成「记资金流水 OUT + 回写业务单 PAID + 重算账户结存 + 透支闸校验」;业务外收入走「收款确认入账」端点直接记 IN 流水。同时业务外收支域补两个状态机推进端点(submit/approve),把单据从草稿推到已批准。
|
||||
|
||||
- 出纳域路径前缀:/admin/finance/cashier(4 个新端点)
|
||||
- 业务外域补端点:/admin/finance/nonbiz-flows/{id}/submit、/{id}/approve(2 个新端点)
|
||||
- 服务:hl-finance(财务服务)
|
||||
|
||||
## 2. 变更清单
|
||||
| 类型 | 接口 | 说明 |
|
||||
|---|---|---|
|
||||
| 新增 | GET /admin/finance/cashier/queue | 出纳待付款队列(本期仅 NONBIZ 业务外支出进队列) |
|
||||
| 新增 | POST /admin/finance/cashier/pay | 登记付款(统一动作:记 OUT 流水 + 回写 PAID + 重算结存 + 透支闸) |
|
||||
| 新增 | GET /admin/finance/cashier/payments/page | 出纳已付款流水台账分页(数据源 fin_fund_flow OUT) |
|
||||
| 新增 | POST /admin/finance/cashier/confirm-in | 收款确认入账(业务外收入批准即入账:记 IN 流水 + 回写 PAID) |
|
||||
| 新增 | PUT /admin/finance/nonbiz-flows/{id}/submit | 提交收支单(PENDING → SUBMITTED,提交后锁定) |
|
||||
| 新增 | PUT /admin/finance/nonbiz-flows/{id}/approve | 批准收支单(SUBMITTED → APPROVED;本期手工置,企微审批待接通) |
|
||||
|
||||
## 3. 接口详情
|
||||
|
||||
### 3.1 待付款队列 GET /queue
|
||||
- 使用场景:管理后台「支付管理」待付款页签,出纳看待付单据列表。
|
||||
- 认证:管理后台管理员 Token(Authorization: Bearer admin-token),未登录返 401。
|
||||
- 幂等性:查询接口,天然幂等。限流:网关默认。
|
||||
|
||||
### 3.2 登记付款 POST /pay
|
||||
- 使用场景:出纳实际打款后在系统登记。后端同事务:记资金流水 OUT → 回写业务单 status=PAID → 重算账户结存 → 透支闸(余额不足且账户不允许透支时整单回滚报 598604)。
|
||||
- 认证:同上。幂等性:业务幂等——同一业务单重复付款被 CAS 条件更新拦截,返回 598602,不会重复记账。限流:网关默认。
|
||||
|
||||
### 3.3 已付款台账 GET /payments/page
|
||||
- 使用场景:出纳「已付款」页签,查历史付款流水(数据源为资金流水表 fin_fund_flow 的 OUT 出纳业务类记录)。
|
||||
- 认证:同上。幂等:查询接口。限流:网关默认。
|
||||
|
||||
### 3.4 收款确认入账 POST /confirm-in
|
||||
- 使用场景:业务外收入单批准(APPROVED)后,出纳确认钱已到账,记 IN 流水并回写单据 PAID。入账金额 = 单据实收 actualAmount,不可手改。
|
||||
- 认证:同上。幂等性:业务幂等——单据回写 PAID 后重复调用报 598606。限流:网关默认。
|
||||
|
||||
### 3.5 提交收支单 PUT /nonbiz-flows/{id}/submit
|
||||
- 使用场景:业务外收支草稿录入人提交审批,单据 PENDING → SUBMITTED 并锁定(不可编辑/删除)。
|
||||
- 认证:同上。幂等性:重复提交报 598505。限流:网关默认。无 Body。
|
||||
|
||||
### 3.6 批准收支单 PUT /nonbiz-flows/{id}/approve
|
||||
- 使用场景:财务负责人批准审批中的单据,SUBMITTED → APPROVED;支出单此后进出纳待付款队列,收入单待收款确认。本期为手工审批,企微审批流待接通。
|
||||
- 认证:同上。幂等性:重复批准报 598505。限流:网关默认。无 Body。
|
||||
|
||||
## 4. 接口入参
|
||||
|
||||
### 4.1 队列 Query(CashierQueueReqVO)
|
||||
|
||||
| 字段 | 类型 | 必填 | 约束 | 说明 |
|
||||
|---|---|---:|---|---|
|
||||
| payType | String | 否 | NONBIZ | 付款类型;空=NONBIZ。本期仅接通 NONBIZ(业务外支出),其余为预留枚举未建上游,传未接通值报 598607 |
|
||||
| page | Number | 否 | 默认 1 | 页码 |
|
||||
| pageSize | Number | 否 | 默认 20 | 每页条数 |
|
||||
|
||||
### 4.2 登记付款 Body(CashierPayReqVO)
|
||||
|
||||
| 字段 | 类型 | 必填 | 约束 | 说明 |
|
||||
|---|---|---:|---|---|
|
||||
| bizType | String | 是 | NONBIZ | 业务类型;本期仅 NONBIZ(业务外支出) |
|
||||
| bizId | Number | 是 | — | 业务单据 ID(须 status=APPROVED,否则 598602) |
|
||||
| payAccountId | Number | 是 | — | 出账公司账户 ID(fin_fund_account,不存在/停用报 598603) |
|
||||
| payMethod | String | 否 | — | 付款方式(字典 fin_pay_way 码值:CASH/BANK_TRANSFER/WECHAT/ALIPAY) |
|
||||
| amount | Number | 是 | 大于0 | 付款金额(598605) |
|
||||
| fee | Number | 否 | 不小于0 | 手续费(挂出账流水) |
|
||||
| voucherNo | String | 否 | — | 付款凭证号 |
|
||||
| voucherUrl | String | 否 | — | 付款凭证影像 URL |
|
||||
| payDate | String | 是 | yyyy-MM-dd | 付款日期(可回溯补录) |
|
||||
| operatorName | String | 否 | — | 后端忽略,统一取当前登录人快照;字段保留仅为入参兼容 |
|
||||
|
||||
### 4.3 台账 Query(CashierPaymentPageReqVO)
|
||||
|
||||
| 字段 | 类型 | 必填 | 约束 | 说明 |
|
||||
|---|---|---:|---|---|
|
||||
| bizType | String | 否 | NONBIZ | 业务类型筛选;空=NONBIZ |
|
||||
| fundAccountId | Number | 否 | — | 出账公司账户 ID;空=不限 |
|
||||
| flowNo | String | 否 | 模糊 | 流水号筛选 |
|
||||
| flowAtStart | String | 否 | yyyy-MM-dd | 收付日期起 |
|
||||
| flowAtEnd | String | 否 | yyyy-MM-dd | 收付日期止 |
|
||||
| page | Number | 否 | 默认 1 | 页码 |
|
||||
| pageSize | Number | 否 | 默认 20 | 每页条数 |
|
||||
|
||||
### 4.4 收款确认 Body(CashierConfirmInReqVO)
|
||||
|
||||
| 字段 | 类型 | 必填 | 约束 | 说明 |
|
||||
|---|---|---:|---|---|
|
||||
| bizId | Number | 是 | — | 业务单据 ID(须 direction=IN 且 status=APPROVED,否则 598606) |
|
||||
| payAccountId | Number | 是 | — | 入账公司账户 ID(fin_fund_account) |
|
||||
| payMethod | String | 否 | — | 收款方式(字典 fin_pay_way 码值) |
|
||||
| voucherNo | String | 否 | — | 收款凭证号 |
|
||||
| voucherUrl | String | 否 | — | 收款凭证影像 URL |
|
||||
| payDate | String | 是 | yyyy-MM-dd | 收款日期(可回溯补录) |
|
||||
|
||||
### 4.5 状态机端点路径参数
|
||||
| 接口 | 字段 | 类型 | 说明 |
|
||||
|---|---|---|---|
|
||||
| PUT /nonbiz-flows/{id}/submit、/{id}/approve | id | Number | 收支单 ID;无 Body |
|
||||
|
||||
## 5. 出参字段
|
||||
|
||||
### 5.1 队列行(CashierQueueRowRespVO)
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|---|---|---|
|
||||
| id | String | 单据 ID(雪花字符串) |
|
||||
| bizNo | String | 业务单号(上游单据无单号列时为空,前端展示以 id 兜底) |
|
||||
| payType | String | 付款类型码(NONBIZ) |
|
||||
| payTypeName | String | 付款类型中文名(业务外支出) |
|
||||
| unitId | String | 外部单位 ID(雪花字符串) |
|
||||
| unitName | String | 外部单位名快照 |
|
||||
| category | String | 收支类别码 |
|
||||
| categoryName | String | 收支类别中文名(取自 fin_nonbiz_category) |
|
||||
| amount | Number | 付款金额 |
|
||||
| fee | Number | 手续费(挂本单) |
|
||||
| actualAmount | Number | 实付 = amount − fee |
|
||||
| operatorName | String | 申请人姓名快照 |
|
||||
| createTime | String | 申请时间(yyyy-MM-dd HH:mm:ss) |
|
||||
| occurDate | String | 发生日期(yyyy-MM-dd) |
|
||||
| status | String | 单据状态(队列内恒 APPROVED) |
|
||||
| remark | String | 备注 |
|
||||
|
||||
### 5.2 台账行(CashierPaymentRowRespVO)
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|---|---|---|
|
||||
| id | String | 流水 ID(雪花字符串) |
|
||||
| flowNo | String | 流水号(LS+yyyyMMdd+4位序号) |
|
||||
| fundAccountId | String | 出账公司账户 ID(雪花字符串) |
|
||||
| accountName | String | 出账账户名称 |
|
||||
| amount | Number | 金额 |
|
||||
| fee | Number | 手续费(挂出账流水) |
|
||||
| balanceAfter | Number | 本笔记完后账户结存快照 |
|
||||
| bizType | String | 业务类型码(NONBIZ) |
|
||||
| bizTypeName | String | 业务类型中文名 |
|
||||
| bizId | String | 关联业务单据 ID(雪花字符串) |
|
||||
| bizNo | String | 业务单号(上游无单号列时为空) |
|
||||
| counterparty | String | 对方单位名快照 |
|
||||
| voucherUrl | String | 付款凭证影像 URL |
|
||||
| flowAt | String | 收付落账时间(yyyy-MM-dd HH:mm:ss) |
|
||||
| operatorName | String | 经办人姓名快照 |
|
||||
| remark | String | 备注 |
|
||||
|
||||
### 5.3 付款 / 收款确认响应(CashierPayRespVO)
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|---|---|---|
|
||||
| flowId | String | 资金流水 ID(雪花字符串) |
|
||||
| flowNo | String | 资金流水号(LS+yyyyMMdd+4位序号) |
|
||||
| balanceAfter | Number | 本笔记完后账户结存快照 |
|
||||
| bizId | String | 业务单据 ID(已回写 PAID) |
|
||||
|
||||
### 5.4 状态机端点响应
|
||||
data 为 null(Result<Void>),code=200 即流转成功。
|
||||
|
||||
## 6. 枚举 / 数据字典
|
||||
|
||||
### payType / bizType(出纳业务类型,代码枚举)
|
||||
| 值 | 中文 | 说明 |
|
||||
|---|---|---|
|
||||
| NONBIZ | 业务外支出 | 本期唯一接通(队列/登记/台账均支持) |
|
||||
| EXPENSE / PAYMENT 等 | — | 预留枚举,上游未建,传入报 598607 |
|
||||
|
||||
### 业务外单据状态机(本次补全后)
|
||||
PENDING →(submit)→ SUBMITTED →(approve)→ APPROVED →(出纳 pay / confirm-in)→ PAID;SUBMITTED 可驳回为 REJECTED(驳回端点后续提供)。状态值见「06_7165_业务外收支流水」changelog 第 6 节。
|
||||
|
||||
### payMethod(收付方式,数据字典 fin_pay_way)
|
||||
| 码值 | 中文 |
|
||||
|---|---|
|
||||
| CASH | 现金 |
|
||||
| BANK_TRANSFER | 银行转账 |
|
||||
| WECHAT | 微信 |
|
||||
| ALIPAY | 支付宝 |
|
||||
|
||||
## 7. 错误码(段位 598600-598699 + 业务外段补 598505)
|
||||
|
||||
| 错误码 | 含义 | 触发场景 |
|
||||
|---|---|---|
|
||||
| 598601 | 业务单不存在 | bizId 无效或已软删 |
|
||||
| 598602 | 业务单状态非已批准,不可付款 | 业务单非 APPROVED 即登记付款;同一单据重复付款(CAS 兜底)也报此码 |
|
||||
| 598603 | 出账账户不存在或已停用 | payAccountId 无效(recordFlow 内 FOR UPDATE 重读兜底) |
|
||||
| 598604 | 账户余额不足且不允许透支 | 出账触发透支闸(资金流水域 595103 在出纳边界的翻译) |
|
||||
| 598605 | 付款金额无效(金额须大于0,手续费不得为负) | amount≤0 或 fee<0 |
|
||||
| 598606 | 收款确认单状态非法(须为已批准的业务外收入单) | confirm-in 的单据非 direction=IN+APPROVED;重复确认也报此码 |
|
||||
| 598607 | 付款类型非法 | payType/bizType 传未接通值(本期仅 NONBIZ) |
|
||||
| 598505 | 状态流转非法(提交须草稿态,批准须审批中) | submit/approve 时状态不符(业务外收支段,见 7165 changelog) |
|
||||
|
||||
## 8. 示例
|
||||
|
||||
### 8.1 典型成功(队列选单 → 登记付款)
|
||||
```http
|
||||
GET /admin/finance/cashier/queue?payType=NONBIZ&page=1&pageSize=20
|
||||
```
|
||||
```json
|
||||
{"code":200,"success":true,"data":{"records":[{"id":"2094311122233344455","bizNo":null,"payType":"NONBIZ","payTypeName":"业务外支出","unitId":"2094001122334455667","unitName":"市文旅局","category":"DEPOSIT_REFUND","categoryName":"押金退回","amount":2000.00,"fee":0,"actualAmount":2000.00,"operatorName":"腰苏图","createTime":"2026-09-06 11:00:00","occurDate":"2026-09-05","status":"APPROVED","remark":"质保金退回"}],"total":1,"page":1,"pageSize":20}}
|
||||
```
|
||||
```http
|
||||
POST /admin/finance/cashier/pay
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"bizType": "NONBIZ",
|
||||
"bizId": 2094311122233344455,
|
||||
"payAccountId": 2097009988776655443,
|
||||
"payMethod": "BANK_TRANSFER",
|
||||
"amount": 2000.00,
|
||||
"fee": 0,
|
||||
"voucherNo": "FK-20260907-01",
|
||||
"payDate": "2026-09-07"
|
||||
}
|
||||
```
|
||||
```json
|
||||
{"code":200,"success":true,"data":{"flowId":"2094400011122233445","flowNo":"LS202609070001","balanceAfter":112894.00,"bizId":"2094311122233344455"}}
|
||||
```
|
||||
|
||||
### 8.2 边界情况(回溯补录 / 收款确认)
|
||||
付款日期可回溯补录历史付款:
|
||||
```json
|
||||
{"bizType":"NONBIZ","bizId":2094311122233344460,"payAccountId":2097009988776655443,"amount":0.01,"payDate":"2026-08-15"}
|
||||
```
|
||||
收款确认入账(业务外收入 APPROVED 单):
|
||||
```json
|
||||
{"bizId":2094311000000000001,"payAccountId":2097009988776655443,"payMethod":"BANK_TRANSFER","payDate":"2026-09-07"}
|
||||
```
|
||||
入账金额由后端取单据 actualAmount,Body 无金额字段。空队列:records=[]、total=0,HTTP 200。
|
||||
|
||||
### 8.3 业务失败(重复付款 / 余额不足 / 类型非法)
|
||||
对同一单据再次登记付款:
|
||||
```json
|
||||
{"code":598602,"message":"业务单状态非已批准,不可付款","success":false,"data":null}
|
||||
```
|
||||
账户余额不足且不允许透支:
|
||||
```json
|
||||
{"code":598604,"message":"账户余额不足且不允许透支","success":false,"data":null}
|
||||
```
|
||||
payType 传未接通值:
|
||||
```json
|
||||
{"code":598607,"message":"付款类型非法(本期仅支持 NONBIZ 业务外支出)","success":false,"data":null}
|
||||
```
|
||||
|
||||
## 9. 业务边界
|
||||
|
||||
适用:
|
||||
- 业务外支出(NONBIZ OUT)批准后的出纳付款执行与台账查询。
|
||||
- 业务外收入(NONBIZ IN)批准后的收款确认入账。
|
||||
- 业务外收支单从草稿到已批准的状态机推进(submit/approve)。
|
||||
|
||||
不适用 / 限制:
|
||||
- 队列/登记付款本期仅接通 NONBIZ 一条线(方案 A);工资/提成等类型已裁掉,其余枚举预留未建上游,传未接通值报 598607。
|
||||
- 批准本期为手工操作(approve 端点直接置 APPROVED),企微审批流留 TODO 未接通。
|
||||
- 出纳实付金额与单据 actualAmount 不一致时后端打 WARN 审计日志但不硬拦,允许出纳按实际打款登记。
|
||||
- confirm-in 入账金额恒等于单据 actualAmount,不支持部分入账。
|
||||
|
||||
特殊边界:
|
||||
- operatorName 入参被后端忽略,经办人统一取当前登录人快照,防止冒名登记。
|
||||
- 登记付款 / 收款确认均为同事务「流水 + 回写」原子操作,失败整单回滚,不会出现只记流水不回写。
|
||||
- fin_nonbiz_flow 本 PR 补 3 列(pay_account_id/pay_flow_id/paid_at,Flyway V20260906_104),部署自动执行。
|
||||
|
||||
## 10. 注意事项
|
||||
- 所有雪花 ID 均为字符串,前端按 String 处理。
|
||||
- 队列行 bizNo 可能为空(上游单据无单号列),前端展示建议以单据 id 兜底。
|
||||
- 台账数据源是资金流水表(fin_fund_flow OUT),不是业务单表;一笔付款对应一行台账。
|
||||
- balanceAfter 是「本笔记完后」的账户结存快照,前端可直接展示无需再查账户余额。
|
||||
- 业务外收支域的 5 个基础端点见「06_7165_业务外收支流水」changelog;本文件只覆盖出纳 4 端点 + nonbiz 2 个流转端点。
|
||||
|
||||
## 11. 关联 / 联系人
|
||||
- Issue:https://git.1814.love:8443/wx/HL/issues/7217
|
||||
- PR:https://git.1814.love:8443/wx/HL/pulls/7221
|
||||
- Commit:https://git.1814.love:8443/wx/HL/commit/850cbf454c
|
||||
- Epic:https://git.1814.love:8443/wx/HL/issues/7216
|
||||
- 负责人:腰苏图(yst)
|
||||
@@ -0,0 +1,510 @@
|
||||
---
|
||||
schema: "hl-changelog/v2"
|
||||
ticket: "7232"
|
||||
title: "费用报销(申请→审批→出纳付款)+ 出纳队列接通费用线"
|
||||
consumer: "admin"
|
||||
author: "yst"
|
||||
change_type: "新增接口"
|
||||
backend_status: "deployed"
|
||||
gateway_status: "verified"
|
||||
frontend_status: "pending"
|
||||
frontend_owner: "hl-admin"
|
||||
frontend_ref: ""
|
||||
target_release: "v2.1"
|
||||
verified_at: "2026-09-07"
|
||||
status_note: "后端已合 dev-v3(hl-finance expense 域 + cashier 域扩 EXPENSE 分支)并部署测试服,E2E 16 PASS/0 FAIL。出纳 queue/pay/payments 入参枚举扩容 EXPENSE,省略时行为不变。"
|
||||
updated_at: "2026-09-07"
|
||||
base: "dev-v3"
|
||||
---
|
||||
|
||||
# 费用报销(申请→审批→出纳付款)+ 出纳队列接通费用线
|
||||
|
||||
财务域新增**费用报销**子域:员工申请报销 → 财务审批(本期手工)→ 出纳付款 → 回写付讫。同时**出纳域待付款队列 / 付款登记 / 已付款台账**三个既有接口的入参枚举扩容,接通费用报销线(`payType/bizType` 新增 `EXPENSE` 值)。
|
||||
|
||||
- expense 新域路径前缀:`/admin/finance/expenses`(8 个新端点)
|
||||
- cashier 既有域路径前缀:`/admin/finance/cashier`(3 个端点入参枚举扩容,无字段增删)
|
||||
|
||||
## 二、变更接口清单
|
||||
|
||||
| # | 接口 | 方法 | 路径 | 变更类型 |
|
||||
|---:|---|---|---|---|
|
||||
| 1 | 报销分页 | GET | `/admin/finance/expenses/page` | 新增 |
|
||||
| 2 | 申请报销 | POST | `/admin/finance/expenses` | 新增 |
|
||||
| 3 | 报销详情 | GET | `/admin/finance/expenses/{id}` | 新增 |
|
||||
| 4 | 编辑草稿 | PUT | `/admin/finance/expenses/{id}` | 新增 |
|
||||
| 5 | 删除草稿 | DELETE | `/admin/finance/expenses/{id}` | 新增 |
|
||||
| 6 | 提交报销 | PUT | `/admin/finance/expenses/{id}/submit` | 新增 |
|
||||
| 7 | 批准报销 | PUT | `/admin/finance/expenses/{id}/approve` | 新增 |
|
||||
| 8 | 驳回报销 | PUT | `/admin/finance/expenses/{id}/reject` | 新增 |
|
||||
| 9 | 出纳待付款队列 | GET | `/admin/finance/cashier/queue` | 修改(入参 `payType` 扩容 `EXPENSE`) |
|
||||
| 10 | 出纳付款登记 | POST | `/admin/finance/cashier/pay` | 修改(入参 `bizType` 扩容 `EXPENSE`) |
|
||||
| 11 | 出纳已付款台账 | GET | `/admin/finance/cashier/payments/page` | 修改(入参 `bizType` 扩容 `EXPENSE`) |
|
||||
|
||||
## 三、接口详情
|
||||
|
||||
### 1. 报销分页 `GET /admin/finance/expenses/page`
|
||||
|
||||
#### 使用场景
|
||||
|
||||
管理后台「费用报销」列表页,按状态 / 部门 / 公司主体 / 关键字筛选分页查询。
|
||||
|
||||
#### 认证 / 幂等性 / 限流
|
||||
|
||||
- 认证:管理后台管理员 Token(`Authorization: Bearer <admin-token>`),未登录返 401。
|
||||
- 幂等性:查询接口,天然幂等。
|
||||
- 限流:走网关默认限流,无特殊配置。
|
||||
|
||||
#### 入参(Query)
|
||||
|
||||
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||||
|---|---|---|---:|---|---|
|
||||
| `status` | Query | String | 否 | 见状态枚举 | 按报销状态筛选,省略查全部 |
|
||||
| `departmentId` | Query | Number | 否 | 正整数 | 按部门 ID 筛选 |
|
||||
| `company` | Query | String | 否 | — | 按公司主体名称筛选 |
|
||||
| `keyword` | Query | String | 否 | — | 关键字模糊搜索(单号 / 事由) |
|
||||
| `page` | Query | Number | 是 | ≥1 | 页码 |
|
||||
| `pageSize` | Query | Number | 是 | 1-100 | 每页条数 |
|
||||
|
||||
#### 出参
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|---|---|---|
|
||||
| `data.records[].id` | String | 报销单 ID(雪花 ID,Long 转字符串防 JS 精度丢失) |
|
||||
| `data.records[].expenseNo` | String | 报销单号(`FY-` 前缀) |
|
||||
| `data.records[].expenseCategory` | String | 费用分类末级名称 |
|
||||
| `data.records[].departmentId` | String | 部门 ID |
|
||||
| `data.records[].departmentName` | String | 部门名称 |
|
||||
| `data.records[].company` | String | 公司主体名称 |
|
||||
| `data.records[].amount` | Number | 报销金额 |
|
||||
| `data.records[].offsetLoanAmt` | Number | 冲销借款金额(本期恒 0,见业务边界) |
|
||||
| `data.records[].payableAmt` | Number | 应付金额(本期 = amount) |
|
||||
| `data.records[].reason` | String | 报销事由 |
|
||||
| `data.records[].rejectReason` | String | 驳回原因(仅 REJECTED 状态有值,其余为 null) |
|
||||
| `data.records[].fundAccountId` | String | 付讫资金账户 ID(仅 PAID 有值) |
|
||||
| `data.records[].status` | String | 状态码,见状态枚举 |
|
||||
| `data.records[].paidAt` | String | 付讫时间(仅 PAID 有值) |
|
||||
| `data.records[].approvalInstanceId` | String | 审批实例 ID(本期恒空,企微审批未接) |
|
||||
| `data.records[].createTime` | String | 创建时间 |
|
||||
| `data.total` / `page` / `pageSize` | Number | 分页元信息 |
|
||||
|
||||
#### 请求示例(典型)
|
||||
|
||||
```http
|
||||
GET /admin/finance/expenses/page?page=1&pageSize=20&status=APPROVED&departmentId=10086
|
||||
Authorization: Bearer <admin-token>
|
||||
```
|
||||
|
||||
#### 响应示例(典型)
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "成功",
|
||||
"success": true,
|
||||
"data": {
|
||||
"records": [
|
||||
{
|
||||
"id": "2094278854020399106",
|
||||
"expenseNo": "FY-20260907-0001",
|
||||
"expenseCategory": "市内交通费",
|
||||
"departmentId": "10086",
|
||||
"departmentName": "市场部",
|
||||
"company": "呼籁旅行社有限公司",
|
||||
"amount": 300.00,
|
||||
"offsetLoanAmt": 0,
|
||||
"payableAmt": 300.00,
|
||||
"reason": "客户拜访打车费",
|
||||
"rejectReason": null,
|
||||
"fundAccountId": null,
|
||||
"status": "APPROVED",
|
||||
"paidAt": null,
|
||||
"approvalInstanceId": null,
|
||||
"createTime": "2026-09-07 10:00:00"
|
||||
}
|
||||
],
|
||||
"total": 1,
|
||||
"page": 1,
|
||||
"pageSize": 20
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 空数据 / 边界响应
|
||||
|
||||
无匹配时 `records=[]`、`total=0`,HTTP 200,前端正常渲染空列表。
|
||||
|
||||
### 2. 申请报销 `POST /admin/finance/expenses`
|
||||
|
||||
**VO**: `ExpenseCreateReqVO`
|
||||
|
||||
#### 使用场景
|
||||
|
||||
员工在管理后台提交一张费用报销单,落库为 PENDING 草稿(未进审批)。
|
||||
|
||||
#### 认证 / 幂等性 / 限流
|
||||
|
||||
- 认证:管理后台管理员 Token。
|
||||
- 幂等性:非幂等(每次创建生成新单号),重复提交产生多张单据,前端提交后应禁用按钮。
|
||||
- 限流:网关默认。
|
||||
|
||||
#### 入参(Body)
|
||||
|
||||
| 字段 | 类型 | 必填 | 约束 | 说明 |
|
||||
|---|---|---:|---|---|
|
||||
| `expenseCategory` | String | 是 | 必须存在、为末级(level=2)、未停用 | 费用分类**末级名称**,按名称传不按 ID(取自 `fin_expense_category` 字典) |
|
||||
| `departmentId` | Number | 是 | 必须存在 | 部门 ID(用户域组织树 `wechat_department`) |
|
||||
| `company` | String | 是 | 必须为启用项 | 公司主体名称,按名称传(取自 `travel_agency` 启用项) |
|
||||
| `amount` | Number | 是 | >0 | 报销金额 |
|
||||
| `reason` | String | 是 | 非空 | 报销事由 |
|
||||
|
||||
#### 出参
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|---|---|---|
|
||||
| `data.id` | String | 新建报销单 ID |
|
||||
| `data.expenseNo` | String | 报销单号(`FY-` 前缀) |
|
||||
| `data.status` | String | 创建后为 `PENDING` |
|
||||
|
||||
#### 请求示例(典型成功)
|
||||
|
||||
```json
|
||||
{
|
||||
"expenseCategory": "市内交通费",
|
||||
"departmentId": 10086,
|
||||
"company": "呼籁旅行社有限公司",
|
||||
"amount": 300.00,
|
||||
"reason": "客户拜访打车费"
|
||||
}
|
||||
```
|
||||
|
||||
#### 请求示例(边界情况)
|
||||
|
||||
金额为最小粒度 / 事由最长:
|
||||
|
||||
```json
|
||||
{
|
||||
"expenseCategory": "办公用品费",
|
||||
"departmentId": 10086,
|
||||
"company": "呼籁旅行社有限公司",
|
||||
"amount": 0.01,
|
||||
"reason": "采购 A4 打印纸一箱"
|
||||
}
|
||||
```
|
||||
|
||||
#### 请求示例(业务失败)
|
||||
|
||||
费用分类传了非末级 / 已停用名称 → 598703:
|
||||
|
||||
```json
|
||||
{
|
||||
"expenseCategory": "交通费",
|
||||
"departmentId": 10086,
|
||||
"company": "呼籁旅行社有限公司",
|
||||
"amount": 300.00,
|
||||
"reason": "打车"
|
||||
}
|
||||
```
|
||||
|
||||
```json
|
||||
{"code":598703,"message":"费用分类非法(不存在/非末级/已停用)","success":false,"data":null}
|
||||
```
|
||||
|
||||
金额 ≤0 → 598704;部门或公司主体非法 → 598705。
|
||||
|
||||
### 3. 报销详情 `GET /admin/finance/expenses/{id}`
|
||||
|
||||
#### 入参
|
||||
|
||||
| 字段 | 位置 | 类型 | 必填 | 说明 |
|
||||
|---|---|---|---:|---|
|
||||
| `id` | Path | String | 是 | 报销单 ID(雪花字符串) |
|
||||
|
||||
#### 出参
|
||||
|
||||
字段与分页行一致(`id/expenseNo/expenseCategory/departmentId/departmentName/company/amount/offsetLoanAmt/payableAmt/reason/rejectReason/fundAccountId/status/paidAt/approvalInstanceId/createTime`),见 §1 出参表。
|
||||
|
||||
#### 错误响应
|
||||
|
||||
```json
|
||||
{"code":598701,"message":"报销单不存在","success":false,"data":null}
|
||||
```
|
||||
|
||||
### 4. 编辑草稿 `PUT /admin/finance/expenses/{id}`
|
||||
|
||||
**VO**: `ExpenseUpdateReqVO`(字段与 `ExpenseCreateReqVO` 完全一致,见 §2 入参表)
|
||||
|
||||
#### 业务边界
|
||||
|
||||
- 仅 `PENDING` 状态可编辑,其余状态调用返回 598702。
|
||||
- 编辑不改单号,状态保持 PENDING。
|
||||
|
||||
#### 请求示例
|
||||
|
||||
```json
|
||||
{
|
||||
"expenseCategory": "市内交通费",
|
||||
"departmentId": 10086,
|
||||
"company": "呼籁旅行社有限公司",
|
||||
"amount": 350.00,
|
||||
"reason": "客户拜访打车费(含返程)"
|
||||
}
|
||||
```
|
||||
|
||||
#### 错误响应
|
||||
|
||||
```json
|
||||
{"code":598702,"message":"报销单状态非法(仅PENDING可编辑删除、提交须PENDING、审批须SUBMITTED)","success":false,"data":null}
|
||||
```
|
||||
|
||||
### 5. 删除草稿 `DELETE /admin/finance/expenses/{id}`
|
||||
|
||||
#### 业务边界
|
||||
|
||||
- 仅 `PENDING` 状态可删除,其余状态调用返回 598702。
|
||||
- 删除为软删除,单据不再出现在任何列表。
|
||||
|
||||
#### 出参
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|---|---|---|
|
||||
| `data` | Boolean | `true` 表示删除成功 |
|
||||
|
||||
### 6. 提交报销 `PUT /admin/finance/expenses/{id}/submit`
|
||||
|
||||
#### 业务边界
|
||||
|
||||
- 仅 `PENDING` 状态可提交,提交后流转 `PENDING → SUBMITTED`,单据进入锁定态(不可编辑 / 删除)。
|
||||
- 无 Body 入参。
|
||||
|
||||
#### 出参
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|---|---|---|
|
||||
| `data.id` | String | 报销单 ID |
|
||||
| `data.status` | String | 提交后为 `SUBMITTED` |
|
||||
|
||||
### 7. 批准报销 `PUT /admin/finance/expenses/{id}/approve`
|
||||
|
||||
#### 业务边界
|
||||
|
||||
- 仅 `SUBMITTED` 状态可批准,流转 `SUBMITTED → APPROVED`,进入出纳待付款队列。
|
||||
- 本期为**手工审批**(不接企微审批流),`approvalInstanceId` 恒空。
|
||||
- 无 Body 入参。
|
||||
|
||||
#### 出参
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|---|---|---|
|
||||
| `data.id` | String | 报销单 ID |
|
||||
| `data.status` | String | 批准后为 `APPROVED` |
|
||||
|
||||
### 8. 驳回报销 `PUT /admin/finance/expenses/{id}/reject`
|
||||
|
||||
#### 入参(Body)
|
||||
|
||||
| 字段 | 类型 | 必填 | 约束 | 说明 |
|
||||
|---|---|---:|---|---|
|
||||
| `rejectReason` | String | 是 | 非空 | 驳回原因(回显在详情 `rejectReason` 字段) |
|
||||
|
||||
#### 业务边界
|
||||
|
||||
- 仅 `SUBMITTED` 状态可驳回,流转 `SUBMITTED → REJECTED`,不进出纳队列。
|
||||
|
||||
#### 请求示例
|
||||
|
||||
```json
|
||||
{"rejectReason": "缺少打车发票附件,请补充后重新提交"}
|
||||
```
|
||||
|
||||
#### 出参
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|---|---|---|
|
||||
| `data.id` | String | 报销单 ID |
|
||||
| `data.status` | String | 驳回后为 `REJECTED` |
|
||||
|
||||
### 9. 出纳待付款队列 `GET /admin/finance/cashier/queue`(修改:payType 扩容)
|
||||
|
||||
#### 变更点
|
||||
|
||||
入参 `payType` 枚举由仅 `NONBIZ` 扩容为 `NONBIZ / EXPENSE`。传 `EXPENSE` 时返回费用报销线(`fin_expense` 表 `status=APPROVED` 的单据);其余字段、结构、分页契约不变。
|
||||
|
||||
#### 入参(Query,增量)
|
||||
|
||||
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||||
|---|---|---|---:|---|---|
|
||||
| `payType` | Query | String | 否 | `NONBIZ` / `EXPENSE` | 付款类型筛选;省略 / 空 = 既有行为 |
|
||||
|
||||
#### 出参(队列行,费用线字段填充规则)
|
||||
|
||||
| 字段 | 类型 | 费用线(payType=EXPENSE)取值 |
|
||||
|---|---|---|
|
||||
| `id` | String | 报销单 ID |
|
||||
| `bizNo` | String | 报销单号(= expenseNo) |
|
||||
| `payType` | String | `EXPENSE` |
|
||||
| `payTypeName` | String | `费用` |
|
||||
| `unitId` / `unitName` | String | 槽位复用:部门 ID / 部门名称 |
|
||||
| `category` / `categoryName` | String | 费用分类(末级名称) |
|
||||
| `amount` | Number | 报销金额 |
|
||||
| `fee` | Number | 手续费(费用线为 0) |
|
||||
| `actualAmount` | Number | 应付金额(= payableAmt) |
|
||||
| `operatorName` | String | 申请人 |
|
||||
| `createTime` | String | 创建时间 |
|
||||
| `occurDate` | String | 发生日期 |
|
||||
| `status` | String | 队列状态 |
|
||||
| `remark` | String | 报销事由(= reason) |
|
||||
|
||||
#### 请求示例
|
||||
|
||||
```http
|
||||
GET /admin/finance/cashier/queue?payType=EXPENSE
|
||||
Authorization: Bearer <admin-token>
|
||||
```
|
||||
|
||||
### 10. 出纳付款登记 `POST /admin/finance/cashier/pay`(修改:bizType 扩容)
|
||||
|
||||
#### 变更点
|
||||
|
||||
入参 `bizType` 枚举新增 `EXPENSE` 值。`bizType=EXPENSE` 时 `bizId` 传报销单 ID,登记付款后回写 `fin_expense` 状态为 `PAID`、记录 `fundAccountId` / `paidAt`,同事务记资金流水。
|
||||
|
||||
#### 入参(Body,关键字段)
|
||||
|
||||
| 字段 | 类型 | 必填 | 约束 | 说明 |
|
||||
|---|---|---:|---|---|
|
||||
| `bizType` | String | 是 | 新增 `EXPENSE` | 业务类型;费用报销传 `EXPENSE` |
|
||||
| `bizId` | String | 是 | 对应业务单据 ID | `bizType=EXPENSE` 时传报销单 ID |
|
||||
| `fundAccountId` | String | 是 | 必须存在 | 付款资金账户 ID |
|
||||
| `actualAmount` | Number | 是 | >0 | 出纳手录实际打款金额(默认带入 payableAmt,可改) |
|
||||
| 其余字段 | — | — | — | 与既有 NONBIZ 线一致,不变 |
|
||||
|
||||
#### 业务边界
|
||||
|
||||
- 出纳实际打款金额与 `payableAmt` 不一致时后端**打 WARN 审计日志但不硬拦**(允许出纳按实际打款登记)。
|
||||
- 并发防重:同事务记资金流水 + 条件更新回写,对同一报销单重复付款返回 598602。
|
||||
|
||||
#### 错误响应
|
||||
|
||||
重复付款:
|
||||
|
||||
```json
|
||||
{"code":598602,"message":"该单据已付款,请勿重复操作","success":false,"data":null}
|
||||
```
|
||||
|
||||
付款类型非法(598607 文案已扩为含 EXPENSE):
|
||||
|
||||
```json
|
||||
{"code":598607,"message":"付款类型非法,本期支持 NONBIZ/EXPENSE","success":false,"data":null}
|
||||
```
|
||||
|
||||
### 11. 出纳已付款台账 `GET /admin/finance/cashier/payments/page`(修改:bizType 扩容)
|
||||
|
||||
#### 变更点
|
||||
|
||||
入参新增 `bizType` 筛选,支持 `EXPENSE`;传空 / 省略 = 既有 NONBIZ 行为。其余字段、结构不变。
|
||||
|
||||
#### 入参(Query,增量)
|
||||
|
||||
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||||
|---|---|---|---:|---|---|
|
||||
| `bizType` | Query | String | 否 | `NONBIZ` / `EXPENSE` | 业务类型筛选;空 = NONBIZ(既有行为) |
|
||||
|
||||
#### 请求示例
|
||||
|
||||
```http
|
||||
GET /admin/finance/cashier/payments/page?page=1&pageSize=20&bizType=EXPENSE
|
||||
Authorization: Bearer <admin-token>
|
||||
```
|
||||
|
||||
## 六.5、枚举 / 数据字典
|
||||
|
||||
### `status`(报销单状态,代码枚举)
|
||||
|
||||
**所属字段**: `ExpensePageReqVO.status / ExpenseRespVO.status` | **类型**: `String`
|
||||
|
||||
| 值 | 中文 | 说明 |
|
||||
|---|---|---|
|
||||
| `PENDING` | 待提交 | 草稿态,可编辑可删除 |
|
||||
| `SUBMITTED` | 审批中 | 已提交,锁定(不可编辑 / 删除) |
|
||||
| `APPROVED` | 已批准 | 审批通过,待出纳付款 |
|
||||
| `REJECTED` | 已驳回 | 审批驳回,`rejectReason` 有值 |
|
||||
| `PAID` | 已付讫 | 出纳付款完成,终态只读 |
|
||||
|
||||
状态机:`PENDING →(submit)→ SUBMITTED →(approve)→ APPROVED →(出纳付款)→ PAID`;`SUBMITTED →(reject)→ REJECTED`。
|
||||
|
||||
### `payType` / `bizType`(出纳域,枚举值扩容)
|
||||
|
||||
**所属字段**: `cashier/queue` 入参 `payType`、`cashier/pay` 入参 `bizType`、`cashier/payments/page` 入参 `bizType` | **类型**: `String`
|
||||
|
||||
| 值 | 中文 | 说明 |
|
||||
|---|---|---|
|
||||
| `NONBIZ` | 非业务付款 | 既有值,行为不变 |
|
||||
| `EXPENSE` | 费用(报销) | 新增值,费用报销线 |
|
||||
|
||||
### `expenseCategory`(费用分类,数据字典 `fin_expense_category`)
|
||||
|
||||
- 按**末级名称**(level=2)传值,按名称不按 ID。
|
||||
- 仅正常(未停用)项可选;传非末级 / 不存在 / 已停用名称返回 598703。
|
||||
|
||||
### `company`(公司主体,数据字典 `travel_agency`)
|
||||
|
||||
- 按名称传值,仅启用项可选;非法返回 598705。
|
||||
|
||||
### 错误码(新段 5987xx + 出纳段扩充)
|
||||
|
||||
| 错误码 | 含义 | 触发场景 |
|
||||
|---|---|---|
|
||||
| 598701 | 报销单不存在 | 详情 / 编辑 / 删除 / 提交 / 审批传错 ID |
|
||||
| 598702 | 报销单状态非法 | 非 PENDING 编辑删除、非 PENDING 提交、非 SUBMITTED 审批 |
|
||||
| 598703 | 费用分类非法 | 分类不存在 / 非末级 / 已停用 |
|
||||
| 598704 | 金额无效 | `amount ≤ 0` |
|
||||
| 598705 | 部门或公司主体非法 | `departmentId` 不存在或 `company` 非启用项 |
|
||||
| 598706 | 单号取号撞号重试耗尽 | 极端并发下取号失败(重试后仍撞号) |
|
||||
| 598607 | 付款类型非法(文案扩充) | 出纳付款 / 台账传非 `NONBIZ/EXPENSE` 值 |
|
||||
|
||||
## 六.6、修改前后对比
|
||||
|
||||
| 项目 | 修改前 | 修改后 |
|
||||
|---|---|---|
|
||||
| 费用报销接口 | 无 | 新增 `/admin/finance/expenses` 下 8 端点(分页 / 申请 / 详情 / 编辑 / 删除 / 提交 / 批准 / 驳回) |
|
||||
| 出纳队列 `payType` | 仅 `NONBIZ` | 扩容 `NONBIZ / EXPENSE` |
|
||||
| 出纳付款 `bizType` | 仅 `NONBIZ` | 扩容 `NONBIZ / EXPENSE` |
|
||||
| 出纳台账筛选 | 无 `bizType` 入参 | 新增 `bizType` 入参(空 = NONBIZ) |
|
||||
| 598607 文案 | 仅提示 NONBIZ | 扩为「付款类型非法,本期支持 NONBIZ/EXPENSE」 |
|
||||
|
||||
## 六.7、影响评估
|
||||
|
||||
- **是否破坏向后兼容**:否。expense 8 端点为纯新增;出纳 3 端点为入参枚举扩容,省略新值时行为与之前完全一致。
|
||||
- **前端是否必须同步上线**:否。旧功能不受影响;费用报销页面与出纳队列费用线 Tab 可按节奏上线。
|
||||
- **前端 workaround 清理点**:无(全新能力)。
|
||||
|
||||
## 七、不影响范围
|
||||
|
||||
- 小程序端(C 端):费用报销为纯管理后台能力,`/mp/**` 零改动。
|
||||
- 出纳 NONBIZ 线:不传 `payType/bizType=EXPENSE` 时行为与之前完全一致。
|
||||
- 员工借款 / 冲销:本期未建借款域,`offsetLoanAmt` 恒 0、`payableAmt = amount`,留 TODO 后续接入。
|
||||
|
||||
## 八、测试环境已验证
|
||||
|
||||
192.168.100.236 测试服行为级 E2E **16 PASS / 0 FAIL**:
|
||||
|
||||
- 全链路走通:申请 → 提交 → 批准 → 出纳付款 → 回写 PAID。
|
||||
- 结存勾稽正确:付款前资金账户余额 114894 − 打款 300 = 114594。
|
||||
- 并发防重生效:重复付款返回 598602。
|
||||
- 四类校验生效:598702(状态非法)/ 598703(分类非法)/ 598704(金额无效)/ 598705(部门或公司非法)。
|
||||
|
||||
## 当前状态
|
||||
|
||||
- 后端:已部署并已验证。
|
||||
- 前端:待处理(费用报销页面 + 出纳队列费用线 Tab)。
|
||||
|
||||
## 十、相关文档
|
||||
|
||||
- Issue:[#7232](https://git.1814.love:8443/wx/HL/issues/7232)
|
||||
- 后端 PR:[#7247](https://git.1814.love:8443/wx/HL/pulls/7247)
|
||||
|
||||
## 关联 / 联系人
|
||||
|
||||
- **Issue**: [#7232](https://git.1814.love:8443/wx/HL/issues/7232)
|
||||
- **PR**: [#7247](https://git.1814.love:8443/wx/HL/pulls/7247)
|
||||
- **后端负责人**: @yst
|
||||
- **当前状态**: 后端已就绪(TEST 已验证),前端待接入。
|
||||
在新工单中引用
屏蔽一个用户