一些检查失败了
changelog-filename-gate / validate (push) Failing after 2s
适配 4 项:adapter 改读 baseInfo、driver 汇总卡 6 字段改读 baseInfo+转账方向推导、 删 vehicleLines 项、补 date/reimburseAmount 字段翻译;group 分支零改动。 测试:ReportModal.spec 重构+1,returnDetailAdapter.spec +4,settlement 91+4 全绿。
564 行
26 KiB
Markdown
564 行
26 KiB
Markdown
---
|
||
schema: "hl-changelog/v2"
|
||
ticket: "5820"
|
||
title: "主报账人报账表出参重构:顶层三维化 + 支出行统一扁平字段(破坏性变更)"
|
||
consumer: "admin"
|
||
change_type: "修改接口"
|
||
author: "yaosutu(GIT)"
|
||
backend_status: "deployed"
|
||
gateway_status: "pending"
|
||
frontend_status: "implemented"
|
||
frontend_owner: "mmg"
|
||
frontend_ref: "fd070dc2"
|
||
target_release: ""
|
||
verified_at: "2026-08-11"
|
||
status_note: "前端已实现(2026-08-11,mmg,fd070dc2),仅 driver/reimbursement 分支,group 单团核算未重构零改动:①adaptSettlementReport 的 reportStatus/confirmedAt 改优先读 baseInfo 回退顶层(不改则 confirmed 恒 false);②driver 汇总卡 6 字段改读 baseInfo,公共预支 publicPrepaidAmount→approvedAdvanceAmount,删 transferDirection 改 reporterNetAmount 正负推导(正=报账人应转回公司/负=公司应补报账人,金额取 transferAmount);③REPORT_DETAIL_CONFIG.driver 删 vehicleLines 项(车辆并入 expenseLines category=VEHICLE 逐天一行);④REPORT_FIELD_LABELS 补 date/reimburseAmount,expenseLines 12 扁平明细列数据驱动自适应。orderHeader 新增 returnDate/travelerCount 未接入(ReportModal 标题栏取 props.order 不读 orderHeader,按本次范围不接)。测试:ReportModal.spec 重构 fixture+1 baseInfo 方向推导用例,returnDetailAdapter.spec +4 baseInfo 兼容用例,settlement 91+4 全绿,checkpoint 精确文件集全过。"
|
||
updated_at: "2026-08-11"
|
||
base: "dev-v3"
|
||
---
|
||
|
||
# 【⚠️ 修改接口·管理后台】主报账人报账表出参重构:顶层三维化 + 支出行统一扁平字段(#5820 / #5859)
|
||
|
||
## 1. 接口背景
|
||
|
||
核单结算域的「主报账人报账表」接口,供管理后台在订单核单时查看主报账人(通常是司机)的代收、垫付支出、预支与净额结算情况。
|
||
|
||
本次重构解决两个历史问题:
|
||
|
||
1. **出参结构混乱**(#5820):原出参把 30+ 个汇总字段平铺在顶层,支出行按费用类别拆成 7 族各自一套字段名(住宿用 hotelName/roomTypeName/stayDate、餐食用 mealName/mealTypeName/mealDate、门票用 scenicName/specName/dayDate、车辆用 vehiclePlate/driverName/serviceDate/dailyPrice……),前端需要为每类支出写一套渲染逻辑,且存在 4 对语义重复的镜像字段。
|
||
2. **订单抬头字段不全 + 方向字段冗余**(#5859):baseInfo.transferDirection 与 transferAmount 正负 / reporterNetAmount 表达的信息重复;orderHeader 缺返回日期与出行人总数。
|
||
|
||
## 2. 变更清单
|
||
|
||
| # | 变更 | 类型 |
|
||
|---|------|------|
|
||
| 1 | 顶层 30+ 平铺汇总字段全部收拢进 baseInfo 子对象 | ⚠️ 破坏性 |
|
||
| 2 | expenseLines 支出行由 7 族稀疏字段统一为同一套 12 个扁平字段 | ⚠️ 破坏性 |
|
||
| 3 | 顶层 vehicleLines 字段删除(车辆支出行并入 expenseLines,签单/公司直付不再重复列出) | ⚠️ 破坏性 |
|
||
| 4 | baseInfo 删除 6 个冗余字段:reconNetAmount / driverCollectedTailAmount / publicPrepaidAmount / advanceOutstandingAmount / transferStatus / transferDirection | ⚠️ 破坏性 |
|
||
| 5 | 报账口径明确为口径 A:expenseLines 只含报账人垫付(CASH_PAID)支出 | 🔧 行为变化 |
|
||
| 6 | orderHeader 新增 returnDate(返回日期)、travelerCount(出行人总数) | ✨ 新增字段 |
|
||
|
||
## 3. 接口详情
|
||
|
||
| 项 | 值 |
|
||
|---|---|
|
||
| 方法 + 路径 | GET /v3/admin/order/{orderId}/settlement/reports/reimbursement |
|
||
| 接口名 | 查询主报账人报账表 |
|
||
| 使用场景 | 管理后台订单核单页,查看主报账人代收/垫付/预支/净额结算报表 |
|
||
| 认证 | 管理后台 JWT(/v3/admin/* 走网关鉴权) |
|
||
| 角色限制 | 房务角色(HOUSE)不可访问,调了会被拦截 |
|
||
| 幂等性 | 只读查询,幂等 |
|
||
| 限流 | 走网关默认限流,无接口级特殊限流 |
|
||
|
||
## 4. 接口入参
|
||
|
||
### 4.1 路径参数
|
||
|
||
| 参数 | 类型 | 必填 | 说明 |
|
||
|------|------|------|------|
|
||
| orderId | Long | 是 | 订单 ID,必须大于 0 |
|
||
|
||
### 4.2 请求体
|
||
|
||
无请求体,无 Query 参数。
|
||
|
||
## 5. 出参字段
|
||
|
||
统一响应 Result<SettlementReimbursementReportRespVO>,data 结构如下。
|
||
|
||
### 5.1 顶层结构
|
||
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
|------|------|------|------|
|
||
| baseInfo | Object | 是 | 基础信息(汇总值 + 报账人 + 审计字段),恒下发对象 |
|
||
| orderHeader | Object | 否 | 订单头(订单号/团号/产品/客户/出团日期/定制师/出行人构成) |
|
||
| incomeLines | Array | 是 | 收入行(司机代收);无数据固定返回空数组 [] |
|
||
| expenseLines | Array | 是 | 支出行(统一扁平字段,仅报账人垫付支出);无数据固定返回空数组 [] |
|
||
| advanceLines | Array | 是 | 预支明细行(已审批预支逐条);无数据固定返回空数组 [] |
|
||
|
||
> 顶层**不再有任何平铺的汇总金额字段**,也**不再有 vehicleLines**。
|
||
|
||
### 5.2 baseInfo 字段表
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| id | Long(String) | 核单记录 ID(settlement_recon.recon_id);未生成时为空。Long 序列化为字符串防 JS 精度丢失 |
|
||
| orderId | Long(String) | 订单 ID,序列化为字符串 |
|
||
| reportStatus | String | 报表状态,枚举:GENERATED(已生成)/ CONFIRMED(已确认) |
|
||
| reportVersion | Integer | 报表版本号,固定从 1 开始 |
|
||
| primaryReporterId | Long(String) | 主报账人人员安排 ID |
|
||
| primaryReporterName | String | 主报账人姓名 |
|
||
| primaryReporterRole | String | 主报账人角色(如 DRIVER) |
|
||
| primaryReporterCollectedAmount | BigDecimal | 主报账人代收金额(收入行合计),保留两位小数 |
|
||
| approvedAdvanceAmount | BigDecimal | 已审批预支金额(预支行合计),保留两位小数 |
|
||
| reportablePaidCostAmount | BigDecimal | 可报账已付成本(支出行合计),保留两位小数 |
|
||
| reporterNetAmount | BigDecimal | 报账人净额(代收 + 预支 - 支出);正 = 报账人应转回公司,负 = 公司应补报账人 |
|
||
| primaryReporterDueAmount | BigDecimal | 主报账人应收尾款(核单口径),保留两位小数 |
|
||
| transferAmount | BigDecimal | 转账金额(净额绝对值),保留两位小数 |
|
||
| generatedBy | Long(String) | 生成人 ID |
|
||
| generatedByName | String | 生成人姓名 |
|
||
| generatedAt | String | 生成时间,格式 yyyy-MM-dd HH:mm:ss |
|
||
| confirmedBy | Long(String) | 确认人 ID;未确认时为空 |
|
||
| confirmedByName | String | 确认人姓名;未确认时为空 |
|
||
| confirmedAt | String | 确认时间,格式 yyyy-MM-dd HH:mm:ss;未确认时为空 |
|
||
|
||
**转账方向判定**(替代被删的 transferDirection):
|
||
|
||
- reporterNetAmount > 0 → 报账人应转回公司
|
||
- reporterNetAmount < 0 → 公司应补报账人
|
||
- transferAmount = |reporterNetAmount|
|
||
|
||
### 5.3 orderHeader 字段表
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| orderNo | String | 订单号 |
|
||
| teamNo | String | 团号(订金未支付为 null) |
|
||
| productName | String | 产品名 |
|
||
| productType | String | 产品类型枚举(如 CORE) |
|
||
| productTypeName | String | 产品类型中文名(字典 product_type 回填) |
|
||
| customerName | String | 客户姓名 |
|
||
| departDate | String | 出团日期,格式 yyyy-MM-dd |
|
||
| returnDate | String | **新增**:返回日期,格式 yyyy-MM-dd |
|
||
| consultantName | String | 定制师姓名 |
|
||
| travelerCount | Integer | **新增**:出行人总数(成人+儿童+幼童+婴儿,空档按 0 计) |
|
||
| travelerComposition | String | 出行人构成(数量为 0 的档不显示,全空为 null),如 "2大 1儿童 1幼童" |
|
||
|
||
### 5.4 expenseLines 支出行字段表(统一扁平 12 字段)
|
||
|
||
**所有分类共用同一套字段**,前端单 table 渲染即可,不用再按类别分叉。
|
||
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
|------|------|------|------|
|
||
| category | String | 是 | 费用类别 code:HOTEL / TICKET / MEAL / VEHICLE / GUIDE / PHOTOGRAPHER / OTHER_EXPENSE / INSURANCE |
|
||
| categoryName | String | 是 | 费用类别中文名(字典 settlement_category) |
|
||
| itemName | String | 是 | 项目名(分类特有信息折叠,见下方折叠规则表) |
|
||
| unitPrice | BigDecimal | 否 | 单价,保留两位小数;**无单价概念的分类不输出该键** |
|
||
| quantity | BigDecimal | 否 | 数量(住宿=房间数,餐食=份数,门票=票数,车辆按天每行=1);**无数量概念的分类不输出该键** |
|
||
| amount | BigDecimal | 是 | 实际金额,保留两位小数 |
|
||
| reimburseAmount | BigDecimal | 是 | 报账金额,保留两位小数;人员行应报销与金额不同时分别给出,其余分类与 amount 相同 |
|
||
| paymentMethod | String | 是 | 付款方式;报账支出行固定 CASH_PAID |
|
||
| paymentMethodName | String | 是 | 付款方式中文名(字典 settlement_payment_method,缺值回退硬编码),如 "现金已付" |
|
||
| date | String | 是 | 业务日期,格式 yyyy-MM-dd(住宿=入住日,门票=游玩日,餐食=用餐日,车辆=服务日,人员=结算日) |
|
||
| remark | String | 否 | 备注;**无备注时不输出该键** |
|
||
| voucherUrls | Array<String> | 否 | 凭证 URL 数组;**无凭证时不输出该键** |
|
||
|
||
**itemName 折叠规则**(按 category):
|
||
|
||
| category | itemName 格式 | 示例 |
|
||
|----------|--------------|------|
|
||
| HOTEL | 酒店名-房型 | 呼伦贝尔香格里拉大酒店-大床房 |
|
||
| TICKET | 景区名-规格 | 套娃景区-成人票 |
|
||
| MEAL | 餐食名(餐类型) | 手把肉套餐(午餐) |
|
||
| VEHICLE | 车牌 车型/司机 | 蒙A-E2E01 丰田普拉多/巴雅尔 |
|
||
| GUIDE / PHOTOGRAPHER | 人员姓名 | 巴特尔 |
|
||
| OTHER_EXPENSE / INSURANCE | 项目名 | 旅游意外险 |
|
||
|
||
### 5.5 incomeLines 收入行字段表(本次未动)
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| type | String | 行类型 code |
|
||
| typeName | String | 行类型中文名(字典 settlement_report_line_type) |
|
||
| receiptId | Long(String) | 线下收款记录 ID |
|
||
| amount | BigDecimal | 收款金额,保留两位小数 |
|
||
| channel | String | 收款渠道 code |
|
||
| channelName | String | 收款渠道中文名(PaymentChannelEnum 枚举 label) |
|
||
| payType | String | 收款款项类型 code |
|
||
| payTypeName | String | 收款款项类型中文名(PayType 枚举 label) |
|
||
| collectorStaffId | Long(String) | 收款人人员安排 ID |
|
||
| collectorName | String | 收款人姓名 |
|
||
| collectorRole | String | 收款人角色 code |
|
||
| collectorRoleName | String | 收款人角色中文名(字典 staff_role) |
|
||
| receivedAt | String | 收款时间,格式 yyyy-MM-dd HH:mm:ss |
|
||
| remark | String | 备注;无备注时为空 |
|
||
|
||
### 5.6 advanceLines 预支明细行字段表(本次未动)
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| type | String | 行类型 code |
|
||
| typeName | String | 行类型中文名(字典 settlement_report_line_type),如 "已审批预支" |
|
||
| advanceId | Long(String) | 预支单 ID |
|
||
| payeeStaffId | Long(String) | 借款对象人员安排 ID |
|
||
| payeeName | String | 借款对象姓名 |
|
||
| payeeRole | String | 借款对象角色 code |
|
||
| payeeRoleName | String | 借款对象角色中文名(字典 staff_role) |
|
||
| advanceType | String | 预支类型 code |
|
||
| advanceTypeName | String | 预支类型中文名(字典 advance_type),如 "住宿押金" |
|
||
| amount | BigDecimal | 预支金额,保留两位小数 |
|
||
| purpose | String | 预支用途 |
|
||
| voucherUrl | String | 凭证 URL |
|
||
| status | String | 预支状态 code |
|
||
| statusText | String | 预支状态中文名(AdvanceStatus 枚举 label),如 "已通过" |
|
||
| submittedAt | String | 提交时间,格式 yyyy-MM-dd HH:mm:ss |
|
||
| approvedAt | String | 审批时间,格式 yyyy-MM-dd HH:mm:ss |
|
||
| approvedBy | String | 审批人姓名 |
|
||
|
||
## 6. 枚举 / 数据字典
|
||
|
||
| 字段 | 来源 | 取值 |
|
||
|------|------|------|
|
||
| baseInfo.reportStatus | 枚举 | GENERATED(已生成)/ CONFIRMED(已确认) |
|
||
| expenseLines.category | 字典 settlement_category | HOTEL(住宿)/ TICKET(门票/游玩项目)/ MEAL(餐食)/ VEHICLE(车辆)/ GUIDE(导游)/ PHOTOGRAPHER(摄影师)/ OTHER_EXPENSE(其他费用)/ INSURANCE(保险) |
|
||
| expenseLines.paymentMethod | 字典 settlement_payment_method | 报账支出行固定 CASH_PAID(现金已付) |
|
||
| incomeLines.channel | PaymentChannelEnum | 收款渠道枚举 |
|
||
| incomeLines.payType | PayType 枚举 | 收款款项类型枚举(如尾款) |
|
||
| advanceLines.status | AdvanceStatus 枚举 | 预支状态(如已通过) |
|
||
| orderHeader.productType | 字典 product_type | 产品类型 |
|
||
|
||
**已删除的枚举字段**:transferStatus(#5816 连带下线)、transferDirection(#5859 删除,方向由 transferAmount 正负 / reporterNetAmount 表达)。
|
||
|
||
## 7. 错误码
|
||
|
||
| code | message | 触发场景 |
|
||
|------|---------|----------|
|
||
| 581007 | 订单不存在 | orderId 查不到订单 |
|
||
| 584088 | 核单凭证数据损坏,请联系管理员处理 | 快照读回时凭证数据异常(脏行),不会抛 500 |
|
||
| 400 | 订单 ID 必须大于 0 | orderId 路径参数校验失败 |
|
||
|
||
## 8. 示例
|
||
|
||
### 8.1 典型成功
|
||
|
||
请求:
|
||
|
||
GET /v3/admin/order/2087088947225038849/settlement/reports/reimbursement
|
||
|
||
响应(已核单 CONFIRMED 订单,含住宿/门票/餐食/车辆支出 + 一条已审批预支):
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"message": "成功",
|
||
"data": {
|
||
"baseInfo": {
|
||
"id": "2087089146102255617",
|
||
"orderId": "2087088947225038849",
|
||
"reportStatus": "CONFIRMED",
|
||
"reportVersion": 1,
|
||
"primaryReporterId": "7001",
|
||
"primaryReporterName": "巴雅尔",
|
||
"primaryReporterRole": "DRIVER",
|
||
"primaryReporterCollectedAmount": 0,
|
||
"approvedAdvanceAmount": 3000.00,
|
||
"reportablePaidCostAmount": 1799.00,
|
||
"reporterNetAmount": -4799.00,
|
||
"primaryReporterDueAmount": 0,
|
||
"transferAmount": 4799.00,
|
||
"generatedBy": "2037350531801993218",
|
||
"generatedByName": "腰苏图",
|
||
"generatedAt": "2026-08-11 16:10:03",
|
||
"confirmedBy": "2037350531801993218",
|
||
"confirmedByName": "腰苏图",
|
||
"confirmedAt": "2026-08-11 16:10:03"
|
||
},
|
||
"orderHeader": {
|
||
"orderNo": "HL20260811001",
|
||
"teamNo": "T20260811001",
|
||
"productName": "呼伦贝尔草原 5 日游",
|
||
"productType": "CORE",
|
||
"productTypeName": "核心产品",
|
||
"customerName": "张三",
|
||
"departDate": "2026-08-29",
|
||
"returnDate": "2026-09-02",
|
||
"consultantName": "李四",
|
||
"travelerCount": 5,
|
||
"travelerComposition": "2大 1儿童 1幼童"
|
||
},
|
||
"incomeLines": [],
|
||
"expenseLines": [
|
||
{
|
||
"category": "HOTEL",
|
||
"categoryName": "住宿",
|
||
"itemName": "呼伦贝尔香格里拉大酒店-大床房",
|
||
"unitPrice": 320.00,
|
||
"quantity": 1,
|
||
"amount": 320.00,
|
||
"reimburseAmount": 320.00,
|
||
"paymentMethod": "CASH_PAID",
|
||
"paymentMethodName": "现金已付",
|
||
"date": "2026-08-29",
|
||
"remark": "含早",
|
||
"voucherUrls": ["https://oss.example.com/voucher/hotel-1.jpg"]
|
||
},
|
||
{
|
||
"category": "TICKET",
|
||
"categoryName": "门票/游玩项目",
|
||
"itemName": "套娃景区-成人票",
|
||
"unitPrice": 99.00,
|
||
"quantity": 1,
|
||
"amount": 99.00,
|
||
"reimburseAmount": 99.00,
|
||
"paymentMethod": "CASH_PAID",
|
||
"paymentMethodName": "现金已付",
|
||
"date": "2026-08-30"
|
||
},
|
||
{
|
||
"category": "MEAL",
|
||
"categoryName": "餐食",
|
||
"itemName": "手把肉套餐(午餐)",
|
||
"unitPrice": 68.00,
|
||
"quantity": 5,
|
||
"amount": 340.00,
|
||
"reimburseAmount": 340.00,
|
||
"paymentMethod": "CASH_PAID",
|
||
"paymentMethodName": "现金已付",
|
||
"date": "2026-08-30"
|
||
},
|
||
{
|
||
"category": "VEHICLE",
|
||
"categoryName": "车辆",
|
||
"itemName": "蒙A-E2E01 丰田普拉多/巴雅尔",
|
||
"unitPrice": 1000.00,
|
||
"quantity": 1,
|
||
"amount": 1000.00,
|
||
"reimburseAmount": 1000.00,
|
||
"paymentMethod": "CASH_PAID",
|
||
"paymentMethodName": "现金已付",
|
||
"date": "2026-08-29"
|
||
}
|
||
],
|
||
"advanceLines": [
|
||
{
|
||
"type": "APPROVED_ADVANCE",
|
||
"typeName": "已审批预支",
|
||
"advanceId": "5001",
|
||
"payeeStaffId": "7001",
|
||
"payeeName": "巴雅尔",
|
||
"payeeRole": "DRIVER",
|
||
"payeeRoleName": "司机",
|
||
"advanceType": "ACCOMMODATION_DEPOSIT",
|
||
"advanceTypeName": "住宿押金",
|
||
"amount": 3000.00,
|
||
"purpose": "酒店押金",
|
||
"voucherUrl": "https://oss.example.com/advance-v1.jpg",
|
||
"status": "APPROVED",
|
||
"statusText": "已通过",
|
||
"submittedAt": "2026-08-28 10:00:00",
|
||
"approvedAt": "2026-08-28 12:00:00",
|
||
"approvedBy": "财务丙"
|
||
}
|
||
]
|
||
},
|
||
"traceId": null,
|
||
"success": true
|
||
}
|
||
```
|
||
|
||
### 8.2 边界情况
|
||
|
||
**边界 1:零收入零预支零支出**(刚生成报表、尚未录任何行)——三个数组固定返回空数组,不是 null:
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"data": {
|
||
"baseInfo": {
|
||
"id": "2087089146102255617",
|
||
"orderId": "2087088947225038849",
|
||
"reportStatus": "GENERATED",
|
||
"reportVersion": 1,
|
||
"primaryReporterId": "7001",
|
||
"primaryReporterName": "巴雅尔",
|
||
"primaryReporterRole": "DRIVER",
|
||
"primaryReporterCollectedAmount": 0,
|
||
"approvedAdvanceAmount": 0,
|
||
"reportablePaidCostAmount": 0,
|
||
"reporterNetAmount": 0,
|
||
"primaryReporterDueAmount": 0,
|
||
"transferAmount": 0,
|
||
"generatedBy": "2037350531801993218",
|
||
"generatedByName": "腰苏图",
|
||
"generatedAt": "2026-08-11 16:10:03",
|
||
"confirmedBy": null,
|
||
"confirmedByName": null,
|
||
"confirmedAt": null
|
||
},
|
||
"orderHeader": {
|
||
"orderNo": "HL20260811001",
|
||
"teamNo": null,
|
||
"productName": "呼伦贝尔草原 5 日游",
|
||
"productType": "CORE",
|
||
"productTypeName": "核心产品",
|
||
"customerName": "张三",
|
||
"departDate": "2026-08-29",
|
||
"returnDate": "2026-09-02",
|
||
"consultantName": "李四",
|
||
"travelerCount": 0,
|
||
"travelerComposition": null
|
||
},
|
||
"incomeLines": [],
|
||
"expenseLines": [],
|
||
"advanceLines": []
|
||
},
|
||
"success": true
|
||
}
|
||
```
|
||
|
||
**边界 2:人员行(GUIDE)+ 无凭证无备注 + 报销金额与金额不同**——unitPrice/quantity/remark/voucherUrls 键不输出:
|
||
|
||
```json
|
||
{
|
||
"category": "GUIDE",
|
||
"categoryName": "导游",
|
||
"itemName": "巴特尔",
|
||
"amount": 500.00,
|
||
"reimburseAmount": 450.00,
|
||
"paymentMethod": "CASH_PAID",
|
||
"paymentMethodName": "现金已付",
|
||
"date": "2026-08-31"
|
||
}
|
||
```
|
||
|
||
**边界 3:门票单价为 0**(免费票)——unitPrice: 0.0 正常输出,金额 0:
|
||
|
||
```json
|
||
{
|
||
"category": "TICKET",
|
||
"categoryName": "门票/游玩项目",
|
||
"itemName": "蓝房子(乌苏浪子湖)-成人票",
|
||
"unitPrice": 0.0,
|
||
"quantity": 1,
|
||
"amount": 0.0,
|
||
"reimburseAmount": 0.0,
|
||
"paymentMethod": "CASH_PAID",
|
||
"paymentMethodName": "现金已付",
|
||
"date": "2026-08-31"
|
||
}
|
||
```
|
||
|
||
### 8.3 业务失败
|
||
|
||
**订单不存在**:
|
||
|
||
GET /v3/admin/order/999999999/settlement/reports/reimbursement
|
||
|
||
```json
|
||
{
|
||
"code": 581007,
|
||
"message": "订单不存在",
|
||
"success": false
|
||
}
|
||
```
|
||
|
||
**参数校验失败**(orderId = 0):
|
||
|
||
GET /v3/admin/order/0/settlement/reports/reimbursement
|
||
|
||
```json
|
||
{
|
||
"code": 400,
|
||
"message": "订单 ID 必须大于 0",
|
||
"success": false
|
||
}
|
||
```
|
||
|
||
**房务角色访问被拦**(House 角色 JWT 调用):
|
||
|
||
```json
|
||
{
|
||
"code": 403,
|
||
"message": "无权限访问",
|
||
"success": false
|
||
}
|
||
```
|
||
|
||
## 9. 业务边界
|
||
|
||
**适用**:
|
||
- 订单已进入核单流程(已生成核单记录),查看主报账人维度的结算报表
|
||
- 已核单(CONFIRMED)与核单中(GENERATED)订单均可调,报表实时计算
|
||
|
||
**不适用**:
|
||
- 未发起核单的订单:baseInfo.id 等审计字段为空,汇总金额为 0
|
||
- 需要看整团(含非报账人支付)口径时用单团核算表接口 GET /v3/admin/order/{orderId}/settlement/reports/group,本接口是报账人视角
|
||
|
||
**特殊边界**:
|
||
- **报账口径 A**:expenseLines 只含报账人垫付(CASH_PAID)的支出;签单 / 公司直接付的车务费**不进** expenseLines,前端不要期待在支出行里看到所有成本
|
||
- incomeLines 只含报账人代收,线上支付(微信等)不在此列
|
||
- 旧快照兼容:历史已确认报表的旧快照数据读回时,旧扁平键静默忽略、落默认空 baseInfo,不会抛 500
|
||
|
||
## 10. 修改前后对比
|
||
|
||
### 10.1 顶层结构对比
|
||
|
||
| 维度 | 修改前 | 修改后 |
|
||
|------|--------|--------|
|
||
| 汇总字段 | 30+ 个平铺在顶层(id/orderId/reportStatus/primaryReporterCollectedAmount/...) | 全部收拢进 baseInfo 子对象 |
|
||
| 车辆支出 | 顶层独立 vehicleLines 数组(车辆专属字段) | 删除;车辆支出行并入 expenseLines(category=VEHICLE) |
|
||
| 订单头 | orderHeader(9 字段) | orderHeader(11 字段,新增 returnDate/travelerCount) |
|
||
|
||
### 10.2 baseInfo 字段级对比(删除清单)
|
||
|
||
| 删除字段 | 原位置 | 替代取值 |
|
||
|----------|--------|----------|
|
||
| reconNetAmount | 顶层平铺 | baseInfo.reporterNetAmount(同值镜像) |
|
||
| driverCollectedTailAmount | 顶层平铺 | baseInfo.primaryReporterCollectedAmount(同值镜像) |
|
||
| publicPrepaidAmount | 顶层平铺 | baseInfo.approvedAdvanceAmount(同口径) |
|
||
| advanceOutstandingAmount | 顶层平铺 | 无替代(该口径废弃,预支看 approvedAdvanceAmount + advanceLines) |
|
||
| transferStatus | baseInfo(#5816 连带下线) | 无替代(转账状态跟踪能力下线) |
|
||
| transferDirection | baseInfo | 由 reporterNetAmount 正负判定:正=报账人应转回公司,负=公司应补报账人;金额取 transferAmount |
|
||
|
||
> 其余原顶层平铺字段(id/orderId/reportStatus/reportVersion/primaryReporter*/各金额/generated*/confirmed*)**字段名与语义不变**,仅位置从顶层移入 baseInfo。
|
||
|
||
### 10.3 expenseLines 字段级对比
|
||
|
||
| 修改前(按类别稀疏字段) | 修改后(统一扁平字段) |
|
||
|--------------------------|------------------------|
|
||
| HOTEL: hotelName / roomTypeName / stayDate / roomCount / unitPrice | itemName=「酒店-房型」/ date / quantity / unitPrice |
|
||
| TICKET: scenicName / specName / dayDate / ticketCount / ticketUnitPrice | itemName=「景区-规格」/ date / quantity / unitPrice |
|
||
| MEAL: mealName / mealTypeName / mealDate / quantity / unitPrice | itemName=「餐食名(餐类型)」/ date / quantity / unitPrice |
|
||
| VEHICLE: vehiclePlate / driverName / serviceDate / dailyPrice | itemName=「车牌 车型/司机」/ date / unitPrice(quantity 恒 1) |
|
||
| GUIDE/PHOTOGRAPHER: staffName / settledDate / amount / reimburseAmount | itemName=姓名 / date / amount / reimburseAmount |
|
||
| 各类各自的付款方式/备注/凭证字段名 | 统一 paymentMethod/paymentMethodName/remark/voucherUrls |
|
||
|
||
### 10.4 行为级对比
|
||
|
||
| 场景 | 修改前 | 修改后 |
|
||
|------|--------|--------|
|
||
| 签单/公司直付车务费 | 出现在 vehicleLines | 不出现在本接口任何行(口径 A:只列报账人垫付) |
|
||
| 支出行渲染 | 前端按 7 族类别各写一套列 | 单 table 统一 12 字段渲染 |
|
||
| 调旧字段(如 data.reportStatus、data.vehicleLines、data.baseInfo.transferDirection) | 有值 | **undefined**(字段不存在,不报错静默丢失) |
|
||
|
||
## 11. 影响评估 / 回滚
|
||
|
||
### 11.1 影响评估
|
||
|
||
- **破坏兼容性**:⚠️ 是。所有读顶层平铺汇总字段、读 vehicleLines、按类别分叉渲染支出行、读 transferStatus/transferDirection 的前端代码**全部失效**(取到 undefined)。
|
||
- **前端必须同步上线**:是。前端需要:
|
||
1. 汇总字段读取路径从 data.xxx 改为 data.baseInfo.xxx
|
||
2. 支出行渲染改为单 table 统一字段(category/categoryName/itemName/unitPrice/quantity/amount/reimburseAmount/paymentMethod/paymentMethodName/date/remark/voucherUrls)
|
||
3. 删除 vehicleLines 相关渲染
|
||
4. 转账方向展示改由 reporterNetAmount 正负 + transferAmount 推导
|
||
5. 4 个镜像字段改读保留字段(见 §10.2 替代表)
|
||
- **后端兼容**:旧快照数据读回不报错(静默忽略旧键),无需数据迁移。
|
||
|
||
### 11.2 回滚方案
|
||
|
||
- 后端回滚 = revert PR #5839 + PR #5865 两个 merge commit,重启 hl-order-service-v3。出参即恢复旧结构。
|
||
- 前端回滚 = 切回旧版前端包。前后端必须同版本(新后端 + 旧前端 = 页面全空)。
|
||
- 无 DDL,无数据迁移,回滚无残留风险。
|
||
|
||
## 12. 注意事项
|
||
|
||
1. **所有 Long ID 字段(id/orderId/primaryReporterId/receiptId/advanceId/各种 staffId/generatedBy/confirmedBy)序列化为 JSON 字符串**,前端按 string 处理,不要 Number() 转换(防 JS 精度丢失)。
|
||
2. expenseLines 中 unitPrice / quantity / remark / voucherUrls 是**条件输出键**:无值时整个键不出现(NON_NULL),前端取值前判空。
|
||
3. reimburseAmount 大多数分类与 amount 相同;只有人员行(GUIDE/PHOTOGRAPHER)应报销与金额可能不同,展示报账口径时以 reimburseAmount 为准。
|
||
4. 转账方向不要再找 transferDirection 字段:用 reporterNetAmount > 0 判「报账人转回公司」、< 0 判「公司补报账人」,transferAmount 恒为绝对值。
|
||
5. orderHeader.travelerComposition 全空档时为 null,teamNo 订金未支付时为 null,展示需兜底。
|
||
6. 本接口与单团核算表 reports/group 是两个口径:本接口 = 主报账人视角(只含报账人垫付),group = 整团视角(含全部成本)。前端不要把两个接口的行混在一起渲染。
|
||
7. 车辆支出行在 expenseLines 里按服务日**逐天一行**(quantity 恒 1),不是一车一行。
|
||
|
||
## 13. 关联 / 联系人
|
||
|
||
- Issue:
|
||
- https://git.1814.love:8443/wx/HL/issues/5820 (主报账人报账表 RespVO 重构)
|
||
- https://git.1814.love:8443/wx/HL/issues/5859 (删 transferDirection + orderHeader 补 returnDate/travelerCount)
|
||
- PR:
|
||
- https://git.1814.love:8443/wx/HL/pulls/5839 (#5820 出参重构)
|
||
- https://git.1814.love:8443/wx/HL/pulls/5865 (#5859 orderHeader 补字段 + 删 transferDirection)
|
||
- 服务:hl-order-service-v3(端口 8086)
|
||
- 后端负责人:腰苏图
|