275 行
13 KiB
Markdown
275 行
13 KiB
Markdown
---
|
||
schema: "hl-changelog/v2"
|
||
ticket: "7165"
|
||
title: "业务外收支流水(收入 IN / 支出 OUT 同表两入口)"
|
||
consumer: "admin"
|
||
author: "yst"
|
||
change_type: "新增接口"
|
||
backend_status: "deployed"
|
||
gateway_status: "verified"
|
||
frontend_status: "verified"
|
||
frontend_owner: "mmg"
|
||
frontend_ref: "016572ee"
|
||
target_release: ""
|
||
verified_at: "2026-09-10"
|
||
status_note: "verified 2026-09-10 mmg: 收入IN/支出OUT 同表两入口共享 NonbizFlowPage(props.direction)。nonbiz-flow.js 七端点+calcFeeByRate/buildNonbizFlowPayload(编辑剥 direction/ID 字符串化/不收 actualAmount);金额直读 actualAmount 不自算,fee 三件套千分率联动;按状态机显隐(PENDING 编辑/提交/删除、SUBMITTED 批准);主会话集成补「确认到账」(IN 且 APPROVED)调 cashierConfirmIn。receipt/nonbiz-in 与 payable/nonbiz-out 两薄壳。checkpoint 全绿。"
|
||
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)
|