docs(changelog): #7930 司导预支出纳队列行 remark 补预支用途快照(修改接口-管理后台)
changelog-filename-gate / validate (push) Failing after 2s

ADVANCE 待支付队列 GET /admin/finance/cashier/advance/queue 出参 remark
由恒 null 改为 fin_advance.purpose(申请用途快照);纯出参补值向后兼容,
入参/路径/其余字段/错误码/付款接口均不变;历史单与未填用途单仍为 null。
PR #7931 已合并 dev-v3 尚未部署。
这个提交包含在:
yaosutu
2026-09-18 12:44:32 +08:00
父节点 514ab2cf1f
当前提交 755c690e24
@@ -0,0 +1,329 @@
---
schema: "hl-changelog/v2"
ticket: "advance-queue-remark-purpose"
title: "司导预支出纳队列行 remark 补用途快照(fin_advance 加 purpose 列)——队列行 remark 由恒 null 改为预支申请用途"
consumer: "admin"
author: "yst(GIT)"
change_type: "修改接口"
backend_status: "merged"
gateway_status: "pending"
frontend_status: "pending"
frontend_owner: ""
frontend_ref: ""
target_release: ""
verified_at: "2026-09-18"
status_note: "Issue #7930 / PR #7931 已合并 dev-v3(merge commit d0c849064e),尚未部署测试服。司导借款支付页签(出纳 ADVANCE 待支付队列 GET /admin/finance/cashier/advance/queue,#7901 已上线)的行字段 remark 此前因 fin_advance 无用途列恒为 null;本次新增 fin_advance.purpose 用途快照列(VARCHAR(255),来源 order 域 order_advance.purpose,审批推送 AdvancePushDTO 时一次冻结,历史行不回填),队列映射 purpose 到 remark。纯出参补值,向后兼容:入参/路径/其余 9 字段/错误码/付款接口 POST /pay 全部不变,老前端不读 remark 零影响。occurDate 仍恒为 null(本次未接通)。"
updated_at: "2026-09-18"
base: "dev-v3"
---
# 司导预支出纳队列行 remark 补预支用途(管理后台)
> **服务**: hl-order-service-v3(hl-finance 模块,端口 8086,财务表与 order v3 同库 hl_order_service_v3)
> **类型**: 修改接口(纯出参字段补值:队列行 remark 由恒 null 改为预支申请用途快照)
> **日期**: 2026-09-18
> **影响范围**: 管理后台财务域「出纳支付管理 - 司导借款支付(ADVANCE)」页签待支付队列
> **关联**: Issue #7930 | PR #7931 | 前序 Epic #7901(司导预支支付链,队列/付款端点契约见同目录《18_7901_司导预支支付链接通-新增接口-管理后台》)
---
## 一、接口背景
司导预支(司导借款)= 订单执行中司机/导游向公司预借的备用金。链路:
```
订单详情创建预支(申请时可填「用途说明」purpose)
-> 财务审批通过
-> 推送快照生成财务执行单 fin_advance(APPROVED,进入出纳 ADVANCE 待支付队列)
-> 出纳在「司导借款支付」页签登记付款
```
#7901 支付链接通时,财务执行单表 fin_advance 建表**未留用途列**:order 域预支申请时填的用途(order_advance.purpose,审批时已冻结)推送时无处落库,导致出纳 ADVANCE 队列行 `remark` 字段**恒为 null**,前端「用途/备注」列无内容可显(对照费用报销/应付款队列,其 remark 由 reason 映射)。
本次 Issue #7930 补齐这条快照链:
1. fin_advance 新增 `purpose VARCHAR(255) NULL` 用途快照列(Flyway 幂等迁移,随部署执行);
2. order 域审批推送 DTO AdvancePushDTO 携带 purpose,落库 fin_advance.purpose(审批推送时一次冻结,后续不回写、不追溯);
3. 出纳队列转换 purpose 到队列行 remark。
**前端效果**:队列行「用途/备注」列现在直接展示该预支单的申请用途文本,不必再按空态处理;但仍需对 null 兜底(历史单 / 申请时未填用途的单)。
---
## 二、变更清单
| # | 方法 | 路径 | 变更类型 | 说明 |
|---|------|------|----------|------|
| 1 | GET | /admin/finance/cashier/advance/queue | 修改接口(纯出参补值) | 出参 AdvanceQueueRowRespVO.remark:**恒 null 改为预支申请用途快照文本**(fin_advance.purpose 映射);历史行/未填用途仍为 null |
**明确不变项(本次零变化)**:
- 端点路径、HTTP 方法不变(仍为 /admin/finance/cashier/advance,**无 /v3 前缀**,与其余出纳页签一致);
- 入参不变(仍仅分页 page/pageSize,无业务筛选参数);
- 出参其余 **9 个字段**(id/bizNo/amount/fee/actualAmount/operatorName/createTime/occurDate/status)名称、类型、语义全部不变;
- 错误码不变(队列只读,无新增/删除错误码;付款侧 5995xx / 5986xx 全部不受影响);
- 付款接口 `POST /admin/finance/cashier/advance/pay` 入参/出参/行为完全不受影响;
- 已付款流水台账接口(bizType=ADVANCE)不受影响。
---
## 三、接口详情
| 项 | 说明 |
|---|---|
| 使用场景 | 管理后台「财务 - 出纳支付管理 - 司导借款支付(ADVANCE)」页签:分页拉取已审批待支付的司导预支单,行内展示借款对象/金额/用途等 |
| 认证 | 管理后台 JWT(网关统一鉴权),需出纳付款相关菜单/按钮权限 |
| 幂等性 | GET 只读,天然幂等,重复请求无副作用 |
| 限流 | 走网关统一限流,无模块特殊限流 |
| 分页 | fin_advance status=APPROVED 分页查询,page/pageSize,默认 page=1、pageSize=20(pageSize 1-100,超 100 校验失败);兼容别名 pageNo |
| ID 序列化 | 队列行 id 是雪花 ID,JSON 中为 **String**,防 JS 精度丢失;付款时按字符串原样回传为付款接口的 bizId |
| 部署状态 | PR #7931 已合并 dev-v3,**尚未部署**;部署前队列 remark 仍全为 null(旧代码),部署后对新审批且填了用途的单回填 |
---
## 四、接口入参
### 4.1 路径参数 / Query 参数(CashierQueueFormReqVO extends PageParam)
无路径参数;Query 仅两个分页字段:
| 字段 | 类型 | 必填 | 默认 | 说明 |
|------|------|------|------|------|
| page | Integer | 否 | 1 | 页码,最小 1;兼容别名 pageNo(传 pageNo 与 page 等价) |
| pageSize | Integer | 否 | 20 | 每页条数;1-100,超出区间参数校验失败(全局 400) |
### 4.2 请求体字段
GET 请求无请求体。本次入参**零变化**,也没有任何业务筛选参数(不按状态/日期/单号/用途搜索)。
---
## 五、出参字段
外层为统一包装 Result(code/message/data/traceId/success),data 为分页结构 records / total / page / pageSize。
records[] 每行字段(共 10 个,**本次仅 remark 语义变化**):
| 字段 | 类型 | 本次是否变化 | 说明 |
|------|------|--------------|------|
| id | String | 否 | 单据ID(fin_advance 雪花 ID 序列化字符串)。付款时作为 bizId 原样回传 |
| bizNo | String | 否 | 业务单号 = 预支单号,格式 YZ- + yyyyMMdd + 4 位序号(如 YZ-20260918-0012) |
| amount | Number | 否 | 付款金额(审批推送时快照冻结,即付款金额锁死基准) |
| fee | Number | 否 | 手续费,预支线恒为 0 |
| actualAmount | Number | 否 | 实付 = amount 减 fee;预支线下恒等于 amount |
| operatorName | String | 否 | 借款对象姓名快照(收款人/司导姓名 payeeName,改名不追溯) |
| createTime | String | 否 | 推送时间,格式 yyyy-MM-dd HH:mm:ss(fin_advance 建单时间) |
| occurDate | String | 否 | 发生日期(yyyy-MM-dd);fin_advance 无来源列,**仍恒返回 null**(本次未接通),渲染用「-」兜底 |
| status | String | 否 | 单据状态,队列内恒为 APPROVED |
| remark | String | **是(补值)** | **预支申请用途快照**(fin_advance.purpose 映射,Converter:purpose 到 remark)。有值场景:本次部署后新审批推送、且申请时填了用途的单。**仍可能为 null**:部署前已推送的历史单(历史行不回填)、申请时未填用途的单(用途本就可选)。最长 255 字符,自由文本原样输出,非字典码值,不脱敏不截断 |
补充口径:来源 purpose 是申请页「用途说明(可选)」文本框,后端不保证把空白串归一成 null,前端按「null / 空串 / 纯空白」统一当无用途兜底即可。
---
## 六、枚举 / 数据字典
本次**不涉及**任何枚举值或字典的新增、删除、改值:
- 队列行 status 仍仅可能为 `APPROVED`(已审批待支付,队列内唯一值;PAID 付款后出队);
- remark/purpose 为自由文本用途说明,**不是字典码值**,直接展示原文,无需翻译;
- 付款方式 payMethod(字典 fin_pay_way:CASH/BANK/THIRD_PARTY)、payChannel(WXPAY/ALIPAY)属付款接口侧字典,与本次队列变更无关,沿用 #7901 changelog。
---
## 七、错误码
本次**无错误码变化**。队列查询为只读分页:
- 正常:HTTP 200 且 body `code=200`;
- 参数非法(pageSize 超 100、page 小于 1 等):全局参数校验响应(HTTP 400),字段级中文 message;
- 未认证/无权限:网关统一 401/403。
付款侧错误码(599500/599501/599502/599504/599505 及 598603/598604/598605/598608/598609/598610)与本次无关,本队列接口不会返回,详见 #7901 changelog。
---
## 八、示例
### 8.1 典型成功——新单 remark 带用途文本
请求:
```
GET /admin/finance/cashier/advance/queue?page=1&pageSize=20
Authorization: Bearer <管理后台 JWT>
(无请求体)
```
响应(该单为本次部署后审批推送、申请时填了用途「希拉穆仁团建团带团备用金(门票+过路费)」):
```json
{
"code": 200,
"message": "成功",
"data": {
"records": [
{
"id": "1962180000000000311",
"bizNo": "YZ-20260918-0012",
"amount": 3000.00,
"fee": 0,
"actualAmount": 3000.00,
"operatorName": "布仁",
"createTime": "2026-09-18 10:26:41",
"occurDate": null,
"status": "APPROVED",
"remark": "希拉穆仁团建团带团备用金(门票+过路费)"
}
],
"total": 1,
"page": 1,
"pageSize": 20
},
"traceId": "a1b2c3d4-e5f6-7890",
"success": true
}
```
### 8.2 边界——历史单/未填用途单 remark 仍为 null
同一页可能混有 remark=null 的行(部署前推送的历史单;申请时用途留空的新单)。**绝不能假设 remark 必有值**:
```json
{
"code": 200,
"message": "成功",
"data": {
"records": [
{
"id": "1962180000000000101",
"bizNo": "YZ-20260917-0007",
"amount": 3000.00,
"fee": 0,
"actualAmount": 3000.00,
"operatorName": "娜仁",
"createTime": "2026-09-17 16:02:18",
"occurDate": null,
"status": "APPROVED",
"remark": null
},
{
"id": "1962180000000000312",
"bizNo": "YZ-20260918-0013",
"amount": 800.00,
"fee": 0,
"actualAmount": 800.00,
"operatorName": "布仁",
"createTime": "2026-09-18 11:05:09",
"occurDate": null,
"status": "APPROVED",
"remark": null
}
],
"total": 2,
"page": 1,
"pageSize": 20
},
"traceId": "a1b2c3d5-e5f6-7891",
"success": true
}
```
其他边界:用途最长 255 字符,队列原样返回不截断;含标点/括号按纯文本渲染(建议单行省略 + tooltip 看全);队列为空时 records=[]、total=0(空态不变)。
### 8.3 业务失败——pageSize 越界(全局 400,形态不变)
请求:
```
GET /admin/finance/cashier/advance/queue?page=1&pageSize=500
Authorization: Bearer <管理后台 JWT>
```
响应(HTTP 400,统一校验错误包装):
```json
{
"code": 400,
"message": "每页条数最大为 100",
"traceId": "f7a8b9c0-d1e2-3456",
"success": false
}
```
> 队列端点无业务级失败码;此例仅展示错误响应形态,本次未变化。实际 400 message 以后端 JSR-303/PageParam 校验文案为准。
---
## 九、业务边界
- **适用**:fin_advance 中 status=APPROVED 的司导预支执行单;remark 展示其申请用途快照。
- **用途快照时机**:purpose 在 order 域预支**审批通过推送到财务时一次冻结**;此后用途在任何环节被修改都不回写财务快照,也不追溯历史行。
- **remark 仍为 null 的两类单(必须兜底)**:
1. 本次部署前已推送生成的 fin_advance 历史行(purpose 为新增列,历史行不回填,开发阶段历史测试数据留 NULL);
2. 创建预支时「用途说明」本就是可选项,未填即无值。
- **不适用**:草稿/待审批/已驳回预支不进队列;已 PAID 单不出现在队列(去已付款流水台账 bizType=ADVANCE 查,台账行备注口径不在本次变更范围)。
- **occurDate 仍恒 null**:本次只补 remark,发生日期未接通,不要据 occurDate 做任何业务判断或过滤。
- **用途不是付款依据**:remark 仅供出纳识别这笔预支的用途;付款金额仍严格锁死为队列行 amount(不一致 598610),用途文本不参与任何付款校验。
---
## 十、修改前后对比
### 10.1 字段级对比
| 字段 | 修改前(#7901 起) | 修改后(#7930/#7931 部署后) |
|------|--------------------|------------------------------|
| remark | String,**恒为 null**(fin_advance 无用途列,Converter 无映射) | String,等于 fin_advance.purpose 预支用途快照(映射 source=purpose,target=remark);历史单/未填用途仍为 null |
| occurDate | 恒 null | **仍恒 null**(无来源列,本次不处理) |
| 其余 8 字段(id/bizNo/amount/fee/actualAmount/operatorName/createTime/status) | 同 #7901 契约 | **完全不变** |
### 10.2 行为/链路对比
| 项 | 修改前 | 修改后 |
|----|--------|--------|
| 申请预支填用途(order 域 purpose,可选) | 审批推送不携带用途,财务侧丢失 | AdvancePushDTO 携带 purpose,落 fin_advance.purpose 冻结 |
| 出纳队列「用途/备注」列 | 永远空白 | 显示申请用途;无用途/历史单显示兜底(如「-」) |
| 队列入参 / 路径 / 错误码 | — | **零变化** |
| POST /advance/pay 付款 | — | **零变化**(金额锁死、CAS 防重、事件回写均不受影响) |
| DDL | fin_advance 无 purpose 列 | 新增 purpose VARCHAR(255) NULL(位于 amount 之后),Flyway 部署时自动加列,不回填 |
---
## 十一、影响评估 / 回滚
### 11.1 影响评估
- **是否破坏向后兼容**:**否**。仅对一个原本恒为 null 的可选字符串出参字段补值,字段名/类型/位置不变;不读 remark 的老前端零影响。
- **前端是否必须同步上线**:否,可独立随时上线。不上线时「用途/备注」列对新单会多出文本(若该列已在页面渲染则自然显示);建议本次把空态兜底统一为「null/空串/纯空白时显示『-』」。
- **数据/DDL**:fin_advance 加一列 purpose VARCHAR(255) NULL(amount 之后),纯加列、可空、无默认值、不回填历史行;Flyway 脚本 information_schema 判存 + 存储过程,幂等可重复执行。
- **部署依赖**:**代码已合并 dev-v3,尚未部署测试服**。部署 hl-finance(随 hl-order-service-v3,8086)后迁移自动加列;只对部署之后**新审批推送**的单生效,存量 APPROVED 队列行 remark 仍为 null。
- **网关**:无路由/鉴权/CORS 变更,网关无需任何动作。
### 11.2 回滚方案
- 应用层 revert PR #7931 即可:队列 remark 回到恒 null(Converter 不再映射 purpose),已落库的 purpose 列与数据保留无害,前端只是重新收不到值,无数据迁移、无缓存清理。
- purpose 列为可空加列,**不需要也不建议回滚 DDL**(迁移脚本未提供 DROP,符合禁 DROP 约定);残留空列不影响任何读写。
---
## 十二、注意事项(给前端的落地清单)
1. **「用途/备注」列直接绑 remark**:队列行 remark 即司导预支申请用途原文,纯文本直接显示,无需字典翻译、无需自行拼接。
2. **必须保留可空兜底**:历史单(部署前推送)与申请时未填用途的单 remark 仍为 null(也可能空串/纯空白),统一按无用途渲染(建议显示「-」或灰色「未填用途」),不要渲染出 "null" 字样。
3. **长文本展示**:用途最长 255 字符,建议表格列单行省略 + 悬浮 tooltip 看全文,避免撑开行高。
4. **occurDate 依旧恒 null**:本次没有发生日期,继续按「-」兜底,不要改其逻辑。
5. **付款逻辑一行都不用动**:POST /advance/pay 的金额锁死回填、bizId 字符串原样回传、599502 重复付款提示等全部沿用 #7901 既有对接;remark 不参与付款入参。
6. **部署时点预期**:后端未部署前 remark 全 null 属正常;联调请以后端部署测试服时间为准,部署后新审批一单带用途的预支即可看到 remark 有值。
7. **答疑口径**:用途文本来自订单详情创建预支时的「用途说明」,审批推送时冻结;若业务反馈「用途改了为什么队列没变」,属快照预期,不是缺陷。
---
## 十三、关联 / 联系人
### 13.1 链接
- **Issue**: [#7930](https://git.1814.love:8443/wx/HL/issues/7930)
- **PR**: [#7931](https://git.1814.love:8443/wx/HL/pulls/7931) | merge commit [d0c849064e](https://git.1814.love:8443/wx/HL/commit/d0c849064efde2b1c71cf7d7075ce81c4a4027e6)
- **前序 Epic(队列/付款端点完整契约与错误码)**: [#7901](https://git.1814.love:8443/wx/HL/issues/7901),见同目录《18_7901_司导预支支付链接通-新增接口-管理后台.md》
- **后端变更点**:Flyway V20260918_002 fin_advance 加 purpose 列;FinAdvanceDO.purpose;AdvancePushDTO.purpose;FinCashierConverter.advanceToQueueRowRespVO(purpose 到 remark);AdvanceQueueRowRespVO.remark 字段定义本身未变
### 13.2 联系人
- **后端负责人**: @yst(腰苏图)