docs(changelog): Epic #8361 团期报销核单一团一张——团期核单 finalize/confirm/reports 三端点新增 + 台账应收整团聚合一行(rowType/groupBatchId) + 报账单 biz 三字段 + 搜索兼容团号 + summary 新增 SETTLED(新增接口-管理后台)
changelog-filename-gate / validate (push) Failing after 1s
changelog-filename-gate / validate (push) Failing after 1s
这个提交包含在:
@@ -0,0 +1,492 @@
|
||||
---
|
||||
schema: "hl-changelog/v2"
|
||||
ticket: "8361"
|
||||
title: "团期报销核单「一团一张报账单」——团期核单 finalize/confirm/reports 三端点新增 + 台账应收整团聚合一行 + 报账单 biz 三字段 + 搜索兼容团号 + 核单 summary 新增 SETTLED"
|
||||
consumer: "admin"
|
||||
author: "yst"
|
||||
change_type: "新增接口"
|
||||
backend_status: "merged"
|
||||
gateway_status: "pending"
|
||||
frontend_status: "pending"
|
||||
frontend_owner: ""
|
||||
frontend_ref: ""
|
||||
target_release: ""
|
||||
verified_at: ""
|
||||
status_note: "Epic #8361 五 PR(#8366/#8367/#8368/#8400/#8406)已全部合并 dev-v3,尚未部署测试服、网关未实测。前端需动三处:①应收台账行按 rowType 分流(GROUP_BATCH 行 id 是团期批次 ID,按订单详情跳转必 404);②报账单列表按 bizType 分流展示(GROUP_BATCH 行展示 bizNo 团号);③新增团期核单页(finalize/confirm/reports 三端点 + settlementStatus 新增 SETTLED 态)。"
|
||||
updated_at: "2026-09-27"
|
||||
base: "dev-v3"
|
||||
---
|
||||
|
||||
# 团期报销核单「一团一张报账单」(管理后台)
|
||||
|
||||
**服务**: hl-order-service-v3(团期核单三端点)+ hl-finance(台账应收 / 报账单列表)
|
||||
**Epic**: #8361
|
||||
**PR**: #8366(G1 多态 DDL)+ #8367(G2 三端点)+ #8368(G3 一团一张推送)+ #8400(G4 台账整团聚合/搜索/反向联动)+ #8406(biz 三字段 + keyword 团号)
|
||||
|
||||
---
|
||||
|
||||
## 1. 接口背景
|
||||
|
||||
原核单链路只有「一户一张报账单」(按订单 orderId 聚合)。团期(出团批次)场景下,财务需要按整团做核单、复核、回款跟踪。本次 Epic 把核单与报账单从「一户一张」泛化为「一个业务对象一张」:
|
||||
|
||||
- 团期维度新增「一团一核单」三端点(finalize 核单 → confirm 财务复核并推一团一张报账单 → reports/group 读核单表),快照落库一团一行。
|
||||
- 报账单 fin_reimburse 改 biz_type + biz_id 多态关联:ORDER(一户一张,不变)/ GROUP_BATCH(一团一张,新增)。
|
||||
- 应收台账对团期批次**整团聚合一行**(不按户拆),行上补 rowType/groupBatchId 鉴别字段。
|
||||
- 报账单列表补 bizType/bizId/bizNo 三字段;报账单搜索与台账 keyword 均兼容团号。
|
||||
- 一团一张报账单 RECEIVABLE 全收后,自动反向把团期核单快照 settlementStatus 回写 SETTLED(已结清)。
|
||||
|
||||
## 2. 变更清单
|
||||
|
||||
| # | 变更 | 方法 | 路径 | 类型 | 摘要 |
|
||||
|---|------|------|------|------|------|
|
||||
| 1 | 完成团期核单 | POST | /v3/admin/order/group-batch/{groupBatchId}/settlement/finalize | 新增接口 | 按团聚合落核单快照,幂等 |
|
||||
| 2 | 团期核单财务复核 | POST | /v3/admin/order/group-batch/{groupBatchId}/settlement/confirm | 新增接口 | 复核通过 + 同事务推一团一张报账单 |
|
||||
| 3 | 查询团期核单表 | GET | /v3/admin/order/group-batch/{groupBatchId}/settlement/reports/group | 新增接口 | 读 active 快照;未核单返回 finalized=false 空壳 |
|
||||
| 4 | 应收台账分页 | GET | /admin/finance/receipt/receivable/page | 修改接口 | 行新增 rowType/groupBatchId;团期整团聚合一行;keyword 兼容团号 |
|
||||
| 5 | 报账单分页 | GET | /admin/finance/reimburses/page | 修改接口 | 行新增 bizType/bizId/bizNo;orderNo 入参扩为同时匹配团号 biz_no |
|
||||
| 6 | 团期核单 summary | — | (端点 1/2/3 的出参 GroupSettlementRespVO) | 修改接口 | settlementStatus 新增枚举值 SETTLED(全收自动回写,非人工触发) |
|
||||
|
||||
## 3. 接口详情
|
||||
|
||||
| 端点 | 使用场景 | 认证 | 幂等性 | 限流 |
|
||||
|------|---------|------|--------|------|
|
||||
| POST finalize | 团期出行完毕后,核单员按团聚合落核单快照 | 网关 JWT;角色须 SUPER_ADMIN / ADMIN / FINANCE(缺 589507) | **幂等**:重复提交返回既有 active 快照,不重复落库 | 网关统一限流 |
|
||||
| POST confirm | 财务复核团期核单,通过后推一团一张报账单 | 同 finalize | 状态门 + CAS 挡重复复核;推送侧 uk_biz_version(biz_type,biz_id,version_no) 撞号重查兜底返回既有单;推送失败整单回滚(review_status 停 PENDING),**可安全重试** | 网关统一限流 |
|
||||
| GET reports/group | 团期核单表展示(核单前/后都调) | 网关 JWT;须 group-batch:finance:view 权限码(缺 589507) | 只读 | 网关统一限流 |
|
||||
| GET receivable/page | 财务收款-应收台账 | 网关 JWT(finance 域先例,无方法级权限注解) | 只读 | 网关统一限流 |
|
||||
| GET reimburses/page | 报账款列表(复核视角) | 网关 JWT | 只读 | 网关统一限流 |
|
||||
|
||||
**金额/ID 序列化约定**:GroupSettlementRespVO 的所有 BigDecimal 金额字段与 Long ID 字段均序列化为 **JSON 字符串**(防精度丢失);台账行/报账单行的 Long ID 为字符串,BigDecimal 金额为 JSON number。
|
||||
|
||||
## 4. 接口入参
|
||||
|
||||
### 4.1 路径 / Query 参数
|
||||
|
||||
**团期核单三端点**(均无请求体):
|
||||
|
||||
| 参数 | 位置 | 类型 | 必填 | 说明 |
|
||||
|------|------|------|------|------|
|
||||
| groupBatchId | path | Long | 是 | 团期 ID,必须 ≥ 1(否则 400「团期 ID 必须大于 0」) |
|
||||
|
||||
**应收台账分页** GET /admin/finance/receipt/receivable/page(query):
|
||||
|
||||
| 参数 | 类型 | 必填 | 说明 |
|
||||
|------|------|------|------|
|
||||
| page | int | 是 | 页码,从 1 起 |
|
||||
| pageSize | int | 是 | 每页条数 |
|
||||
| keyword | string | 否 | 搜索关键字(**团号 batch_no / 客户姓名 / 产品名 / 订单号** 模糊,任一命中);空=不限。注:只模糊匹配团号本身,不匹配团期名称/期次 |
|
||||
| receivableStatus | string | 否 | UNPAID 待收款 / PARTIAL 部分收款 / DONE 已收讫;空或非法值=不按收款状态过滤 |
|
||||
|
||||
**报账单分页** GET /admin/finance/reimburses/page(query):
|
||||
|
||||
| 参数 | 类型 | 必填 | 说明 |
|
||||
|------|------|------|------|
|
||||
| page | int | 是 | 页码 |
|
||||
| pageSize | int | 是 | 每页条数 |
|
||||
| status | string | 否 | 单据状态(枚举见 §6);空=全部 |
|
||||
| direction | string | 否 | PAYABLE 公司应付报账人 / RECEIVABLE 报账人应回款 / BALANCED 两清;空=全部 |
|
||||
| orderNo | string | 否 | **订单号/团号**(模糊,同时匹配 order_no 与 biz_no——团期报账单 order_no 为空,按团号 biz_no 也能搜到);空=不限 |
|
||||
| reporterName | string | 否 | 报账人姓名(模糊);空=不限 |
|
||||
|
||||
### 4.2 请求体字段
|
||||
|
||||
三端点均无请求体;两个分页接口均为 GET query 传参,无请求体。
|
||||
|
||||
## 5. 出参字段
|
||||
|
||||
### 5.1 GroupSettlementRespVO(finalize / confirm / reports/group 三端点共用)
|
||||
|
||||
外层统一包装 {"code":200,"success":true,"data":{...}},下表为 data 结构:
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| finalized | boolean | 是否已有核单快照;false=尚未核单,**快照字段全 null**,只填团期基本信息段(batchNo/productName/departDate/batchStatus),不抛 404 |
|
||||
| groupSettlementId | string(Long) | 团期核单快照 ID |
|
||||
| groupBatchId | string(Long) | 团期 ID |
|
||||
| batchNo | string | 团期号,例 20261001-01 |
|
||||
| productName | string | 产品名称快照 |
|
||||
| departDate | string(date) | 出发日期 yyyy-MM-dd |
|
||||
| batchStatus | string | 团期状态(GroupBatchStatus 码,见 §6) |
|
||||
| settledOrderCount | int | 已核单子订单户数 |
|
||||
| totalActiveOrderCount | int | 在团子订单总户数(仅排除已取消) |
|
||||
| subOrderTotalActualCost | string(BigDecimal) | 子订单实际成本合计 |
|
||||
| subOrderTotalProfit | string(BigDecimal) | 子订单毛利合计 |
|
||||
| sharedCostTotal | string(BigDecimal) | 团期共享成本合计 |
|
||||
| sharedCostByType | array | 共享成本按类型汇总,元素见下表 |
|
||||
| grandTotalCost | string(BigDecimal) | 团期总成本(子订单成本合计 + 共享成本合计) |
|
||||
| actualTravelerCount | int | 实际出行人数 |
|
||||
| perPersonSharedCost | string(BigDecimal) 或 null | 人均共享成本;出行人数为 0 时为 null |
|
||||
| groupAdvanceApproved | string(BigDecimal) | 整团预支已批合计(scope=GROUP_BATCH;资金拨付提示,不计入 grandTotalCost) |
|
||||
| groupAdvancePending | string(BigDecimal) | 整团预支待批合计(仅提示,不参与成本/毛利公式) |
|
||||
| groupTotalAmount | string(BigDecimal) | 全团应收总额(一团一张报账单净额输入) |
|
||||
| groupPaidAmount | string(BigDecimal) | 全团已付总额 |
|
||||
| reviewStatus | string | 复核状态:PENDING 待复核 / APPROVED 已复核 / RETURNED 已退回 |
|
||||
| settlementStatus | string | 核单状态:PENDING 待核单 / FINALIZED 已核单 / **SETTLED 已结清(新增,见 §6)** |
|
||||
| flowStatus | string | 团期流程状态快照:TRIP_FINISHED / REVIEWING / SETTLED(confirm 通过后翻 SETTLED;独立于团期本体状态机,不动 order_group_batch.batch_status) |
|
||||
| settledBy | string(Long) | 核单人 ID |
|
||||
| settledByName | string | 核单人姓名快照 |
|
||||
| settledAt | string(datetime) | 团核单完成时间 yyyy-MM-dd HH:mm:ss |
|
||||
| remark | string | 备注 |
|
||||
| createTime | string(datetime) | 快照创建时间 |
|
||||
|
||||
**sharedCostByType[] 元素(SharedCostByTypeVO)**:
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| costType | string | 成本类型码:BUS 整团大巴 / LEADER 领队 / PHOTOGRAPHER 摄影 / OTHER 其他 |
|
||||
| costTypeDesc | string | 成本类型中文标签 |
|
||||
| total | string(BigDecimal) | 该类型成本合计 |
|
||||
|
||||
### 5.2 应收台账行 ReceiptReceivableRowRespVO(receivable/page 的 data.records[])
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| **rowType** | string | **新增**。ORDER 订单行 / GROUP_BATCH 团期整团聚合行。**行点击/跳转策略必须按本字段分流** |
|
||||
| id | string(Long) | rowType=ORDER 时为订单 ID(可跳订单详情);**rowType=GROUP_BATCH 时挂团期批次 ID(与 groupBatchId 同值),按订单 ID 跳详情必 404** |
|
||||
| **groupBatchId** | string(Long) 或 null | **新增**。rowType=GROUP_BATCH 时有值;ORDER 行恒 null |
|
||||
| orderNo | string | rowType=ORDER 为订单号;GROUP_BATCH 行挂团号 batch_no |
|
||||
| teamNo | string | 团号;GROUP_BATCH 行同为团号 batch_no |
|
||||
| productName | string | 产品名(GROUP_BATCH 行为团期名) |
|
||||
| customerName | string 或 null | 客户姓名;**GROUP_BATCH 团行恒 null(整团无单一客户)** |
|
||||
| customerPhone | string 或 null | 客户手机号(明文,内部财务对账用);**GROUP_BATCH 团行恒 null** |
|
||||
| orderStatus | string | rowType=ORDER 为 OrderStatus 枚举值;**rowType=GROUP_BATCH 为 GroupBatchStatus 码——两套枚举空间按 rowType 分流** |
|
||||
| orderStatusName | string | 上述状态的中文名 |
|
||||
| receivableStatus | string | UNPAID 待收款 / PARTIAL 部分收款 / DONE 已收讫 |
|
||||
| receivableStatusName | string | 收款状态中文名 |
|
||||
| receivableAmount | number | 应收总额(取消单归 0)。团行:已核单团读快照全团应收;未核单团按在团子订单实时求和 |
|
||||
| paidAmount | number | 已收金额(毛额,退款不回减)。团行结清(SETTLED)后顶满应收 |
|
||||
| collectedAmount | number | 代收金额。已核单团的未结清欠收挂本列(一团一张报账单已推送,全团尾款=主报账人代收口径);未核单团恒 0 |
|
||||
| balanceAmount | number | 欠收金额。与 collectedAmount 互斥、合计恒等于实时待收尾款;团行结清后归 0 |
|
||||
|
||||
**团期整团聚合行为(新增)**:页内命中的团期子订单按 groupBatchId 折叠——**每团只出一行台账**,同团其余子订单行丢弃,total 按页内折叠数修正。已知近似(后端拍板接受):折叠在页内做,同团子订单跨页时该团在每页各出一行;DONE 筛选视图下 total 为近似值,跨页行数/total 可能有偏差。
|
||||
|
||||
### 5.3 报账单行 ReimburseRowRespVO(reimburses/page 的 data.records[])
|
||||
|
||||
只列本次**新增**三字段(其余字段不变:id/reimburseNo/reporterName/reporterRole/direction/collectableAmount/actualCollectedAmount/underCollectAmount/advanceAmount/cashPaidAmount/netAmount/settleAmount/receivedAmount/remainingAmount/status/reviewByName/reviewTime/createTime):
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| **bizType** | string | **新增**。ORDER 订单单(一户一张)/ GROUP_BATCH 团期单(一团一张);前端按本字段分流展示——GROUP_BATCH 行展示 bizNo(团号) |
|
||||
| **bizId** | string(Long) | **新增**。bizType=ORDER 为订单 ID;GROUP_BATCH 为团期批次 ID(**勿按订单 ID 跳详情**) |
|
||||
| **bizNo** | string | **新增**。bizType=ORDER 为订单号;GROUP_BATCH 为团号 batch_no |
|
||||
|
||||
既有字段语义修订:
|
||||
|
||||
| 字段 | 修订 |
|
||||
|------|------|
|
||||
| orderId | bizType=GROUP_BATCH 团期单**恒 null** |
|
||||
| orderNo | bizType=GROUP_BATCH 团期单**恒 null**,团号看 bizNo |
|
||||
|
||||
## 6. 枚举 / 数据字典
|
||||
|
||||
**rowType(台账行类型,新增)**:ORDER 订单行 / GROUP_BATCH 团期整团聚合行。
|
||||
|
||||
**bizType(报账单业务对象类型,新增)**:ORDER 订单单(一户一张)/ GROUP_BATCH 团期单(一团一张)。
|
||||
|
||||
**settlementStatus(团期核单状态,本次新增 SETTLED)**:
|
||||
|
||||
| 值 | 中文 | 说明 |
|
||||
|----|------|------|
|
||||
| PENDING | 待核单 | 快照未 finalize(reports/group 空壳态不出现本值,看 finalized=false) |
|
||||
| FINALIZED | 已核单 | finalize 完成,待财务复核 |
|
||||
| **SETTLED** | **已结清** | **新增**。一团一张报账单 RECEIVABLE 全收后由后端监听端自动回写(FINALIZED→SETTLED),**非任何人工端点触发**;confirm 不会把 settlementStatus 翻成 SETTLED(confirm 翻的是 reviewStatus 与 flowStatus) |
|
||||
|
||||
**reviewStatus(复核状态)**:PENDING 待复核 / APPROVED 已复核 / RETURNED 已退回。
|
||||
|
||||
**flowStatus(快照内流程状态)**:TRIP_FINISHED / REVIEWING / SETTLED。
|
||||
|
||||
**GroupBatchStatus(团期状态,GROUP_BATCH 台账行的 orderStatus 与核单快照 batchStatus 用)**:RECRUITING 招募中 / RESOURCE_PREPARING 资源准备中 / MATERIAL_PREPARING 物料准备中 / PENDING_DEPARTURE 待出发 / TRAVELLING 出行中 / TRIP_FINISHED 出行完毕 / REVIEWING 核单中 / SETTLED 已结算 / CANCELLED 已取消。
|
||||
|
||||
**OrderStatus(订单粗状态,ORDER 台账行的 orderStatus 用)**:PENDING_PAY 待支付 / CUSTOMIZING 定制中 / PENDING_DEPARTURE 待出行 / TRAVELLING 出行中 / COMPLETED 已完成 / CANCELLED 已取消。
|
||||
|
||||
**receivableStatus(收款状态)**:UNPAID 待收款 / PARTIAL 部分收款 / DONE 已收讫。
|
||||
|
||||
**报账单 status**:PENDING 待复核 / APPROVED 已批准 / PARTIAL_RECEIVED 部分收讫 / PAID 已付讫 / RECEIVED 已回款 / CLOSED 两清 / RETURNED 已退回。
|
||||
|
||||
**direction(报账方向)**:PAYABLE 公司应付报账人 / RECEIVABLE 报账人应回款 / BALANCED 两清。
|
||||
|
||||
**costType(共享成本类型)**:BUS 整团大巴 / LEADER 领队 / PHOTOGRAPHER 摄影 / OTHER 其他。
|
||||
|
||||
## 7. 错误码
|
||||
|
||||
外层结构 {"code":错误码,"message":"文案","data":null,"success":false}。
|
||||
|
||||
| 错误码 | 触发端点 | 文案({0} 为占位) | 处置建议 |
|
||||
|--------|---------|-------------------|---------|
|
||||
| 400 | 三端点 | 团期 ID 必须大于 0 | 参数校验失败 |
|
||||
| 589500 | 三端点 | 团期不存在 | 检查 groupBatchId |
|
||||
| 589507 | 三端点 | 无操作权限(当前角色未授予团期权限,或该团期不在您名下) | finalize/confirm 需 SUPER_ADMIN/ADMIN/FINANCE;reports/group 需 group-batch:finance:view |
|
||||
| 584133 | finalize | 该团期未配置主报账人,请先在团期人员配置中设置主报账人后再核单 | 去团期人员配置设主 |
|
||||
| 584134 | finalize | 该团期存在 {0} 个主报账人,一团只能有一个主报账人,请先去重后再核单 | 去重主报账人 |
|
||||
| 584135 | finalize | 团期子订单 {0} 尚未确认行程,请全团子订单都确认行程后再核单({0}=子订单 ID) | 催该户确认行程 |
|
||||
| 584136 | confirm | 该团期尚未完成核单,请先完成核单后再做财务复核 | 先 finalize |
|
||||
| 584137 | confirm | 当前团期核单状态不允许财务复核(须为已核单且待复核),操作已回滚 | 刷新快照状态;并发复核败者也会命中 |
|
||||
| 584138 | finalize | 团期当前状态为「{0}」,未到核单节点(需出行完毕或核单中),不允许核单({0}=当前 batchStatus) | 等团期到 TRIP_FINISHED/REVIEWING |
|
||||
|
||||
## 8. 示例
|
||||
|
||||
### 8.1 典型成功——finalize 后读团期核单表
|
||||
|
||||
POST /v3/admin/order/group-batch/2097250563497385985/settlement/finalize(无请求体)→ 响应与 GET reports/group 同构:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"success": true,
|
||||
"data": {
|
||||
"finalized": true,
|
||||
"groupSettlementId": "9101234567890123456",
|
||||
"groupBatchId": "2097250563497385985",
|
||||
"batchNo": "20261001-01",
|
||||
"productName": "呼伦贝尔草原 5 日游",
|
||||
"departDate": "2026-10-01",
|
||||
"batchStatus": "REVIEWING",
|
||||
"settledOrderCount": 5,
|
||||
"totalActiveOrderCount": 6,
|
||||
"subOrderTotalActualCost": "45600.00",
|
||||
"subOrderTotalProfit": "8400.00",
|
||||
"sharedCostTotal": "3200.00",
|
||||
"sharedCostByType": [
|
||||
{"costType": "BUS", "costTypeDesc": "整团大巴", "total": "2000.00"},
|
||||
{"costType": "LEADER", "costTypeDesc": "领队", "total": "1200.00"}
|
||||
],
|
||||
"grandTotalCost": "48800.00",
|
||||
"actualTravelerCount": 18,
|
||||
"perPersonSharedCost": "177.78",
|
||||
"groupAdvanceApproved": "5000.00",
|
||||
"groupAdvancePending": "0.00",
|
||||
"groupTotalAmount": "54000.00",
|
||||
"groupPaidAmount": "48000.00",
|
||||
"reviewStatus": "PENDING",
|
||||
"settlementStatus": "FINALIZED",
|
||||
"flowStatus": "REVIEWING",
|
||||
"settledBy": "40001",
|
||||
"settledByName": "王财务",
|
||||
"settledAt": "2026-09-27 12:00:00",
|
||||
"remark": "团核单",
|
||||
"createTime": "2026-09-27 12:00:00"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
台账分页典型响应(GET /admin/finance/receipt/receivable/page?page=1&pageSize=20&keyword=20261001):
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"success": true,
|
||||
"data": {
|
||||
"records": [
|
||||
{
|
||||
"rowType": "ORDER",
|
||||
"id": "2097000000000000001",
|
||||
"groupBatchId": null,
|
||||
"orderNo": "HL20260920001",
|
||||
"teamNo": "T-0920-01",
|
||||
"productName": "阿尔山 3 日游",
|
||||
"customerName": "张三",
|
||||
"customerPhone": "13800001111",
|
||||
"orderStatus": "COMPLETED",
|
||||
"orderStatusName": "已完成",
|
||||
"receivableStatus": "PARTIAL",
|
||||
"receivableStatusName": "部分收款",
|
||||
"receivableAmount": 6000.00,
|
||||
"paidAmount": 3000.00,
|
||||
"collectedAmount": 0,
|
||||
"balanceAmount": 3000.00
|
||||
},
|
||||
{
|
||||
"rowType": "GROUP_BATCH",
|
||||
"id": "2097250563497385985",
|
||||
"groupBatchId": "2097250563497385985",
|
||||
"orderNo": "20261001-01",
|
||||
"teamNo": "20261001-01",
|
||||
"productName": "呼伦贝尔草原 5 日游",
|
||||
"customerName": null,
|
||||
"customerPhone": null,
|
||||
"orderStatus": "SETTLED",
|
||||
"orderStatusName": "已结算",
|
||||
"receivableStatus": "DONE",
|
||||
"receivableStatusName": "已收讫",
|
||||
"receivableAmount": 54000.00,
|
||||
"paidAmount": 54000.00,
|
||||
"collectedAmount": 0,
|
||||
"balanceAmount": 0
|
||||
}
|
||||
],
|
||||
"total": 2,
|
||||
"page": 1,
|
||||
"pageSize": 20
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 8.2 边界——未核单团读核单表(finalized=false 空壳)+ 报账单 GROUP_BATCH 行
|
||||
|
||||
GET reports/group(该团尚未 finalize)——**不抛 404**,快照字段全 null,前端展示「尚未核单」占位:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"success": true,
|
||||
"data": {
|
||||
"finalized": false,
|
||||
"groupSettlementId": null,
|
||||
"groupBatchId": "2097250563497385985",
|
||||
"batchNo": "20261001-01",
|
||||
"productName": "呼伦贝尔草原 5 日游",
|
||||
"departDate": "2026-10-01",
|
||||
"batchStatus": "TRIP_FINISHED",
|
||||
"settledOrderCount": null,
|
||||
"totalActiveOrderCount": null,
|
||||
"subOrderTotalActualCost": null,
|
||||
"subOrderTotalProfit": null,
|
||||
"sharedCostTotal": null,
|
||||
"sharedCostByType": null,
|
||||
"grandTotalCost": null,
|
||||
"actualTravelerCount": null,
|
||||
"perPersonSharedCost": null,
|
||||
"groupAdvanceApproved": null,
|
||||
"groupAdvancePending": null,
|
||||
"groupTotalAmount": null,
|
||||
"groupPaidAmount": null,
|
||||
"reviewStatus": null,
|
||||
"settlementStatus": null,
|
||||
"flowStatus": null,
|
||||
"settledBy": null,
|
||||
"settledByName": null,
|
||||
"settledAt": null,
|
||||
"remark": null,
|
||||
"createTime": null
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
报账单列表中的团期单(GET /admin/finance/reimburses/page?page=1&pageSize=20&orderNo=20261001,按团号搜到)——orderId/orderNo 恒 null,团号看 bizNo:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"success": true,
|
||||
"data": {
|
||||
"records": [
|
||||
{
|
||||
"id": "9123456789012345678",
|
||||
"reimburseNo": "BZ-20260927-0001",
|
||||
"orderId": null,
|
||||
"orderNo": null,
|
||||
"bizType": "GROUP_BATCH",
|
||||
"bizId": "2097250563497385985",
|
||||
"bizNo": "20261001-01",
|
||||
"reporterName": "李领队",
|
||||
"reporterRole": "GUIDE",
|
||||
"direction": "RECEIVABLE",
|
||||
"collectableAmount": 54000.00,
|
||||
"actualCollectedAmount": 48000.00,
|
||||
"underCollectAmount": 6000.00,
|
||||
"advanceAmount": 0,
|
||||
"cashPaidAmount": 0,
|
||||
"netAmount": 6000.00,
|
||||
"settleAmount": 6000.00,
|
||||
"receivedAmount": 0,
|
||||
"remainingAmount": 6000.00,
|
||||
"status": "APPROVED",
|
||||
"reviewByName": "王财务",
|
||||
"reviewTime": "2026-09-27 12:30:00",
|
||||
"createTime": "2026-09-27 12:30:00"
|
||||
}
|
||||
],
|
||||
"total": 1,
|
||||
"page": 1,
|
||||
"pageSize": 20
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 8.3 业务失败——confirm 时团期未核单(584136)
|
||||
|
||||
POST confirm(该团尚未 finalize):
|
||||
|
||||
```json
|
||||
{"code": 584136, "message": "该团期尚未完成核单,请先完成核单后再做财务复核", "data": null, "success": false}
|
||||
```
|
||||
|
||||
finalize 时团期状态未到核单节点(584138,{0} 透出当前状态):
|
||||
|
||||
```json
|
||||
{"code": 584138, "message": "团期当前状态为「TRAVELLING」,未到核单节点(需出行完毕或核单中),不允许核单", "data": null, "success": false}
|
||||
```
|
||||
|
||||
## 9. 业务边界
|
||||
|
||||
**适用**:
|
||||
- finalize:团期状态须为 TRIP_FINISHED(出行完毕)或 REVIEWING(核单中);全团恰好 1 个 PRIMARY 主报账人;全团在团子订单(不含已取消)均已确认行程。
|
||||
- confirm:须已存在 active 核单快照且为「FINALIZED + 待复核 PENDING」。
|
||||
- 台账/报账单列表的 GROUP_BATCH 行:仅团期批次订单(有 groupBatchId 关联)才会聚合/出现;散单(ORDER 行)行为完全不变。
|
||||
|
||||
**不适用**:
|
||||
- 招募中~出行中的团期不允许 finalize(584138)——共享成本未录、子订单成本未发生,快照无意义。
|
||||
- 未 finalize 的团期不允许 confirm(584136)。
|
||||
- SETTLED / CANCELLED 团期同样不允许 finalize(584138,fail-closed 闭集)。
|
||||
|
||||
**特殊边界**:
|
||||
- 重复 finalize:幂等返回既有快照,不重复落库、不报错。
|
||||
- 并发 confirm:CAS 败者报 584137,不静默成功。
|
||||
- confirm 推送报账单失败:整单回滚(review_status 停 PENDING),可安全重试;推送幂等由 uk_biz_version 兜底。
|
||||
- settlementStatus=SETTLED 只能由「一团一张报账单 RECEIVABLE 全收」自动回写,无人工端点能置该态;部分回款不触发。
|
||||
- 团期回款不回写子订单 paid_amount:台账团行已核单后金额读团快照,子订单级欠收停留在订金态属预期,全团回款进度由报账单承接。
|
||||
|
||||
## 10. 修改前后对比
|
||||
|
||||
### 字段级
|
||||
|
||||
| 接口 | 字段 | 原来 | 现在 |
|
||||
|------|------|------|------|
|
||||
| receivable/page 行 | rowType | 无此字段 | 新增,ORDER / GROUP_BATCH |
|
||||
| receivable/page 行 | groupBatchId | 无此字段 | 新增;GROUP_BATCH 行有值,ORDER 行恒 null |
|
||||
| receivable/page 行 | id | 恒为订单 ID | GROUP_BATCH 行挂团期批次 ID(勿跳订单详情) |
|
||||
| receivable/page 行 | customerName / customerPhone | 恒有值 | GROUP_BATCH 行恒 null |
|
||||
| receivable/page 行 | orderStatus / orderStatusName | 恒为 OrderStatus 枚举 | GROUP_BATCH 行为 GroupBatchStatus 码(两套枚举按 rowType 分流) |
|
||||
| receivable/page 入参 | keyword | 团号(散团 team_no)/客户姓名/产品名/订单号 四字段模糊 | 追加兼容**团期团号 batch_no**(命中的团整团进入结果集并折叠成 GROUP_BATCH 行) |
|
||||
| reimburses/page 行 | bizType / bizId / bizNo | 无此三字段 | 新增;GROUP_BATCH 行 orderId/orderNo 恒 null |
|
||||
| reimburses/page 入参 | orderNo | 仅模糊匹配 order_no | 同时模糊匹配 order_no 与 **biz_no**(团号可搜到团期单) |
|
||||
| GroupSettlementRespVO | settlementStatus | PENDING / FINALIZED | 追加 **SETTLED**(全收自动回写) |
|
||||
|
||||
### 行为级
|
||||
|
||||
| 行为 | 原来 | 现在 |
|
||||
|------|------|------|
|
||||
| 台账团期订单展示 | 逐户一行(团期子订单每户一行台账) | 整团聚合一行(页内折叠,total 按折叠数修正) |
|
||||
| 台账行数/total | 订单粒度精确计数 | 团折叠后 total 为近似值(跨页折叠 + DONE 视图粗筛假阳性剔除,后端拍板接受) |
|
||||
| 报账单生成 | 只有订单核单「一户一张」 | 团期 confirm 追加「一团一张」(biz_type=GROUP_BATCH,单号同为 BZ- 前缀) |
|
||||
| 报账单 biz 关联 | order_id 单列 | biz_type + biz_id 多态(ORDER 单 biz 三字段与旧 order 字段同值) |
|
||||
|
||||
## 11. 影响评估 / 回滚
|
||||
|
||||
**破坏兼容评估**:
|
||||
- 新增端点(finalize/confirm/reports/group):纯新增,无兼容风险。
|
||||
- 台账/报账单列表新增字段:纯追加,旧前端忽略新字段可继续工作。
|
||||
- **行为级不兼容(唯一必须前端同步的点)**:台账对团期子订单**不再逐户出行**。旧前端若把每行当订单、按 id 跳订单详情,GROUP_BATCH 行会 404;且团期子订单行数变少。旧前端没有团期入口时感知为「团期订单从台账消失、多了一个点不开的行」。
|
||||
|
||||
**前端同步上线建议**:台账 rowType 分流与报账单 bizType 分流随后端同窗口上线;团期核单页(三端点)可随后迭代,不阻塞。
|
||||
|
||||
**回滚方案**:后端回滚 #8406/#8400/#8368/#8367/#8366 五个合并提交(逆序)。回滚后台账恢复逐户一行、新增字段消失;已落库的 GROUP_BATCH 报账单与团期核单快照保留在库但不再被读写。前端对新增字段若做了「有则展示」的容错,回滚零改动;若强依赖 rowType 分流,回滚后分流逻辑永不命中 GROUP_BATCH 分支,自然降级为 ORDER 行为。
|
||||
|
||||
## 12. 注意事项
|
||||
|
||||
1. **rowType 分流是硬要求**:GROUP_BATCH 行的 id 是团期批次 ID(与 groupBatchId 同值),**严禁**当订单 ID 跳订单详情(必 404)。
|
||||
2. **两套状态枚举空间**:台账行 orderStatus 在 GROUP_BATCH 行是 GroupBatchStatus 码(9 态)、ORDER 行是 OrderStatus 码(6 态),翻译展示必须按 rowType 选字典,不可混用(两边都有 TRAVELLING/SETTLED/CANCELLED 等同名值但语义层级不同)。
|
||||
3. **金额与 ID 序列化**:GroupSettlementRespVO 的 BigDecimal 金额与 Long ID 全是 JSON 字符串;台账行/报账单行 Long ID 是字符串、金额是 number。
|
||||
4. **keyword 只匹配团号本身**(batch_no LIKE),不匹配团期名称/期次;台账团行上的标识就是团号(orderNo/teamNo 同挂 batch_no)。
|
||||
5. **SETTLED 无人工触发口**:settlementStatus=SETTLED 只由回款全收自动回写;前端不要提供「手动结清」按钮,也不要在 confirm 后期望 settlementStatus 立即变 SETTLED(confirm 翻的是 reviewStatus/flowStatus)。
|
||||
6. **空壳范式**:reports/group 用 finalized=false + 全 null 表示未核单,不是 404;前端先判 finalized 再渲染快照区。
|
||||
7. **报账单列表 GROUP_BATCH 行** orderId/orderNo 恒 null,展示层一律取 bizNo;报账单详情接口 GET /admin/finance/reimburses/{id} 路径不变、按报账单 id 查,两种 bizType 通用。
|
||||
8. 团期回款不回写子订单 paid_amount,勿因「子订单仍显示欠收」报 bug——全团回款进度看报账单与台账团行。
|
||||
|
||||
## 13. 关联 / 联系人
|
||||
|
||||
- Epic:https://git.1814.love/wx/HL/issues/8361
|
||||
- 子 Issue:https://git.1814.love/wx/HL/issues/8362(G1)/ https://git.1814.love/wx/HL/issues/8363(G2)/ https://git.1814.love/wx/HL/issues/8364(G3)/ https://git.1814.love/wx/HL/issues/8365(G4)/ https://git.1814.love/wx/HL/issues/8402(biz 三字段 + keyword 团号)
|
||||
- PR:https://git.1814.love/wx/HL/pulls/8366 / https://git.1814.love/wx/HL/pulls/8367 / https://git.1814.love/wx/HL/pulls/8368 / https://git.1814.love/wx/HL/pulls/8400 / https://git.1814.love/wx/HL/pulls/8406
|
||||
- Commit:https://git.1814.love/wx/HL/commit/97e1736ca6 / https://git.1814.love/wx/HL/commit/355c578d1b / https://git.1814.love/wx/HL/commit/1f65d78941 / https://git.1814.love/wx/HL/commit/a7d41a3b22 / https://git.1814.love/wx/HL/commit/811f3a2fc4
|
||||
- 后端负责人:腰苏图(yst)
|
||||
在新工单中引用
屏蔽一个用户