文件
hl-api-changelog/changelogs-v2/2026-08/09_5729_核单报表出参强类型化补中文名-修改接口-管理后台.md
T
Mimingguang 87ed9d0a3f
changelog-filename-gate / validate (push) Failing after 2s
chore(changelog): 全量清理 implemented 存量——81 条复核翻 verified + 1 条改判 not_required + #5827 补登 frontend_ref
处置明细(mmg 2026-09-18):
- 68 条机械核验通过批量翻 verified:frontend_ref 均可达且为 v2.1 祖先、
  交付文件 HEAD 均在、关联 spec 批量 58 文件 891 例全绿。
- 11 条带演进史的例外逐条核后翻 verified:3 条交付自删文件(06_5610/
  07_5655/11_5810,删除即交付内容且终态保持);8 条被后续 changelog 预期
  演进(10_5784→#5810、07_5664/08_5592→#5827、07_5665→去槽位化 U1、
  01_5380/05_5356/06_5567/06_5581→settlement 族A扁平化与 mock 清理),
  status_note 均如实记录演进链。
- 05_5552 改判 not_required:frontend_ref 自述前端无需改动,grep 实证
  vehicleFeeAmount.js 直接读后端 calendarPrice/calendarPriceMissing。
- 11_5827 frontend_ref 原空,经核交付即 753503c8(向导 4 步改 3 步提交
  即派定),补登全哈希 753503c87cc635e5646b4368a8ed506746c79cf1。
另:保险域 2 条相邻条目(05_5530/06_5593)同标准复核翻 verified。
2026-07 历史月 45 条按规则不回扫,保持原状。
2026-09-18 15:56:52 +08:00

32 KiB
原始文件 Blame 文件历史

schema, ticket, title, consumer, change_type, author, backend_status, gateway_status, frontend_status, frontend_owner, frontend_ref, target_release, verified_at, status_note, updated_at, base, generated
schema ticket title consumer change_type author backend_status gateway_status frontend_status frontend_owner frontend_ref target_release verified_at status_note updated_at base generated
hl-changelog/v2 5729 核单报表(单团核算+报账表)出参明细数组 List<Map> 改为强类型 VO,并为所有枚举/字典 code 字段补充中文 xxxName 标签字段 admin 修改接口 yaosutu(GIT) deployed verified verified mmg 4f5f4e47 2026-09-18 PR #5743 已合并 dev-v3;单团核算 incomeLines/costCategories 与报账表 incomeLines/expenseLines/advanceLines/vehicleLines 共 6 个列表字段从 List<Map<String,Object>> 改为强类型 VO;新增 13 个 xxxName/statusText 中文标签字段;新增 5 个数据字典。出参有新增字段、无删除字段,旧字段名保持不变——前端不传这些新字段不影响,但应尽快适配以展示中文名。[mmg 2026-09-18 批量复核翻 verified] ref 4f5f4e47 可达且为 v2.1 祖先;交付文件 HEAD 均在;关联 spec 批量 891 例全绿。 2026-09-18 dev-v3 2026-08-09T18:00:00+08:00

核单报表(单团核算+报账表)出参强类型化并补充中文标签字段(#5729)

PR: #5743 | Commit: db8974cc9 | Merge: 7b4c69aa8 | 服务: hl-order-service-v3 | 更新时间: 2026-08-09

1. 接口背景

核单模块的「单团核算报表」和「报账表」两个查询接口,此前明细数组(收入行、成本分类、支出行、预支行、车辆逐日行)返回类型为 List<Map<String,Object>>,前端无法生成 TypeScript 类型定义,且枚举/字典 code 字段(如 type、category、channel、payType、collectorRole、staffRole、expenseType、subsidyType、advanceType、sourceType 等)只有 code 没有对应中文名,前端需自行硬编码 code→label 映射。本次将 6 个列表字段改为强类型 VO,并为所有枚举/字典 code 新增对应的中文 xxxName / statusText 字段(后端走数据字典/枚举 label 回填),前端可直接展示中文名,逐步移除硬编码。

本次为出参扩展类变更:仅新增字段,无删除字段,旧字段名、类型、语义完全不变。前端不传/不读新字段不影响现有功能,但建议尽快适配以展示中文标签。

2. 变更清单

# 接口 方法 路径 变更类型 前端动作
1 查询单团核算表 GET /v3/admin/order/{orderId}/settlement/reports/group 出参 incomeLines[] 从 Map 改 VO,新增 typeName 类型适配,展示中文名
2 查询单团核算表 GET /v3/admin/order/{orderId}/settlement/reports/group 出参 costCategories[] 从 Map 改 VO,新增 categoryName 类型适配,展示中文名
3 查询报账表 GET /v3/admin/order/{orderId}/settlement/reports/reimbursement 出参 incomeLines[] 从 Map 改 VO,新增 typeName/channelName/payTypeName/collectorRoleName 类型适配,展示中文名
4 查询报账表 GET /v3/admin/order/{orderId}/settlement/reports/reimbursement 出参 expenseLines[] 从 Map 改 VO,新增 categoryName/paymentMethodName/mealTypeName/expenseTypeName/subsidyTypeName/staffRoleName/sourceTypeName 类型适配,展示中文名
5 查询报账表 GET /v3/admin/order/{orderId}/settlement/reports/reimbursement 出参 advanceLines[] 从 Map 改 VO,新增 typeName/payeeRoleName/advanceTypeName/statusText 类型适配,展示中文名
6 查询报账表 GET /v3/admin/order/{orderId}/settlement/reports/reimbursement 出参 vehicleLines[] 新增 sourceTypeName 展示中文名

3. 接口详情

  • 使用场景:核单人员在订单核单页查看单团核算报表(收入与成本汇总)和报账表(收支明细与预支),用于财务复核与结算。
  • 认证:需要管理后台登录态(Bearer Token)。
  • 幂等性:GET 接口,天然幂等。
  • 限流:未声明接口专属限流。
  • 方法/路径:见 §2 变更清单。

4. 接口入参

两个接口均为纯 GET 查询,仅路径参数:

参数 类型 必填 说明
orderId Long 是 订单 ID,路径参数,两个接口一致

无 Query 参数、无请求体。本次入参无变化。

5. 出参字段

以下仅列出本次有变更的行级 VO 字段;RespVO 顶层字段(如 baseOrderAmount/totalCost/grossProfit 等汇总字段)不变,不重复列出。

5.1 单团核算收入行(SettlementGroupIncomeLineVO)

incomeLines[] 从 List<Map> 改为 List<SettlementGroupIncomeLineVO>,固定 4 行:

字段 类型 必填 说明
type String 是 行类型枚举 code:BASE_ORDER(订单应收)/ OTHER_INCOME(其他收入)/ DISCOUNT(优惠,负数)/ ACTUAL_REFUND(实际退款,负数)
typeName ⭐新增 String 否 行类型中文名,走 settlement_report_line_type 字典;BASE_ORDER→订单应收、OTHER_INCOME→其他收入、DISCOUNT→优惠、ACTUAL_REFUND→实际退款
amount BigDecimal 是 金额,保留两位小数;DISCOUNT/ACTUAL_REFUND 为负数

5.2 单团核算成本分类行(SettlementGroupCostCategoryVO)

costCategories[] 从 List<Map> 改为 List<SettlementGroupCostCategoryVO>,固定 8 行:

字段 类型 必填 说明
category String 是 费用类别 code:HOTEL / TICKET / MEAL / VEHICLE / GUIDE / PHOTOGRAPHER / OTHER_EXPENSE / INSURANCE
categoryName ⭐新增 String 否 费用类别中文名,走 settlement_category 字典;HOTEL→住宿、TICKET→门票/游玩项目、MEAL→餐食、VEHICLE→车辆、GUIDE→导游、PHOTOGRAPHER→摄影、OTHER_EXPENSE→其他支出、INSURANCE→保险
amount BigDecimal 是 金额,保留两位小数

5.3 报账表收入行(SettlementReimbursementIncomeLineVO)

incomeLines[] 从 List<Map> 改为 List<SettlementReimbursementIncomeLineVO>,目前仅 DRIVER_CASH_RECEIPT(司机现金收款)一类:

字段 类型 必填 说明
type String 是 行类型 code:当前固定 DRIVER_CASH_RECEIPT
typeName ⭐新增 String 否 行类型中文名,走 settlement_report_line_type 字典;DRIVER_CASH_RECEIPT→司机现金收款
receiptId Long 否 线下收款记录 ID(Long,JSON 序列化为字符串)
amount BigDecimal 是 收款金额,保留两位小数
channel String 否 收款渠道 code:DRIVER_CASH / BANK_TRANSFER / CONSULTANT_COLLECTION
channelName ⭐新增 String 否 收款渠道中文名,走 PaymentChannelEnum 枚举 label;DRIVER_CASH→报账人收款、BANK_TRANSFER→银行转账、CONSULTANT_COLLECTION→顾问代收
payType String 否 收款款项类型 code:DEPOSIT / FULL / BALANCE
payTypeName ⭐新增 String 否 收款款项类型中文名,走 PayType 枚举 label;DEPOSIT→定金、FULL→全款、BALANCE→尾款
collectorStaffId Long 否 收款人人员安排 ID(Long,JSON 序列化为字符串)
collectorName String 否 收款人姓名
collectorRole String 否 收款人角色 code:如 DRIVER
collectorRoleName ⭐新增 String 否 收款人角色中文名,走 staff_role 字典;DRIVER→司机等
receivedAt String 否 收款时间,格式 yyyy-MM-dd HH:mm:ss
remark String 否 备注;无备注时为空

5.4 报账表支出行(SettlementReimbursementExpenseLineVO)

expenseLines[] 从 List<Map> 改为 List<SettlementReimbursementExpenseLineVO>,7 族稀疏联合(每行仅本族字段非 null):

字段 类型 必填 说明
kind String 是 行种类:HOTEL / TICKET / MEAL / VEHICLE_FEE / STAFF:GUIDE / EXPENSE:FUEL / SUBSIDY:MEAL 等
category String 是 费用类别 code:HOTEL / TICKET / MEAL / VEHICLE / GUIDE / PHOTOGRAPHER / OTHER_EXPENSE / INSURANCE
categoryName ⭐新增 String 否 费用类别中文名,走 settlement_category 字典(同 §5.2)
amount BigDecimal 是 实际金额,保留两位小数
paymentMethod String 是 付款方式:CASH_PAID / COMPANY_PAID / SIGNED
paymentMethodName ⭐新增 String 否 付款方式中文名,走 settlement_payment_method 字典;CASH_PAID→现金已付、COMPANY_PAID→公司支付、SIGNED→签单
voucherUrls Array of String 否 凭证 URL 数组;无凭证时为空数组
remark String 否 备注
-- -- -- 以下按族分组,仅本族字段非 null
hotelAssignmentId Long 否 [HOTEL] 配房安排 ID
hotelId Long 否 [HOTEL] 酒店资源 ID
roomTypeId Long 否 [HOTEL] 房型 ID
dayNumber Integer 否 [HOTEL/TICKET] 行程第几天
stayDate String 否 [HOTEL] 入住日期 yyyy-MM-dd
hotelName String 否 [HOTEL] 酒店名称
roomType String 否 [HOTEL] 房型编码
roomTypeName String 否 [HOTEL] 房型名称
roomCount Integer 否 [HOTEL] 房间数
unitPrice BigDecimal 否 [HOTEL/MEAL] 单价
plannedCost BigDecimal 否 [HOTEL/TICKET] 计划成本
sourceType String 否 [HOTEL/TICKET] 明细来源类型 code
sourceTypeName ⭐新增 String 否 [HOTEL/TICKET] 明细来源类型中文名,走 SettlementDetailSourceType 枚举 label
sourceId Long 否 [HOTEL] 来源记录 ID
scenicAssignmentId Long 否 [TICKET] 景区安排 ID
dayDate String 否 [TICKET] 游玩日期 yyyy-MM-dd
scenicName String 否 [TICKET] 景区/项目名称
specName String 否 [TICKET] 规格名称
ticketCount Integer 否 [TICKET] 票数
ticketUnitPrice BigDecimal 否 [TICKET] 门票单价
sellPrice BigDecimal 否 [TICKET] 销售价
totalAmount BigDecimal 否 [TICKET] 票面总额
mealType String 否 [MEAL] 餐食类型:BREAKFAST / LUNCH / DINNER / SELF
mealTypeName ⭐新增 String 否 [MEAL] 餐食类型中文名,走 meal_type 字典;BREAKFAST→早餐、LUNCH→午餐、DINNER→晚餐、SELF→自理
mealDate String 否 [MEAL] 用餐日期 yyyy-MM-dd
mealName String 否 [MEAL] 餐食名称
quantity Integer 否 [MEAL] 份数
staffRole String 否 [STAFF] 人员角色 code:GUIDE / GUIDE_ASSISTANT / LEADER / PHOTOGRAPHER / DRIVER / OTHER
staffRoleName ⭐新增 String 否 [STAFF] 人员角色中文名,走 staff_role 字典
staffId Long 否 [STAFF] 人员安排 ID
staffName String 否 [STAFF] 人员姓名
totalPlannedCost BigDecimal 否 [STAFF] 计划费用合计
reimburse BigDecimal 否 [STAFF] 应报销金额
detail Object 否 [STAFF] 人员费用嵌套明细(JSON 对象)
settleStatus String 否 [STAFF] 结算状态
settledDate String 否 [STAFF] 结算日期 yyyy-MM-dd
transferRef String 否 [STAFF] 转账流水号
sourceRecordType String 否 [VEHICLE_FEE] 来源记录类型
sourceDetailId Long 否 [VEHICLE_FEE] 车辆费用明细 ID
serviceDate String 否 [VEHICLE_FEE] 服务日期 yyyy-MM-dd
vehicleId Long 否 [VEHICLE_FEE] 车辆 ID
vehiclePlate String 否 [VEHICLE_FEE] 车牌号
vehicleModelId Long 否 [VEHICLE_FEE] 车型 ID
vehicleModelName String 否 [VEHICLE_FEE] 车型名称
driverId Long 否 [VEHICLE_FEE] 司机 ID
driverName String 否 [VEHICLE_FEE] 司机姓名
startDate String 否 [VEHICLE_FEE] 服务开始日期 yyyy-MM-dd
endDate String 否 [VEHICLE_FEE] 服务结束日期 yyyy-MM-dd
dailyPrice BigDecimal 否 [VEHICLE_FEE] 日单价
paymentTypeCode String 否 [VEHICLE_FEE] 车务付款类型编码
paymentTypeName String 否 [VEHICLE_FEE] 车务付款类型名称(原已有字段,不变)
vehicleFeeWaiverReason String 否 [VEHICLE_FEE] 车辆费用减免原因
vehicleFeeSource String 否 [VEHICLE_FEE] 车辆费用来源说明
vehicleFeeAdjustmentReason String 否 [VEHICLE_FEE] 车辆费用调整原因
vehicleFeeAdjustedBy Long 否 [VEHICLE_FEE] 车辆费用调整操作人 ID
vehicleFeeAdjustedAt String 否 [VEHICLE_FEE] 车辆费用调整时间
expenseType String 否 [EXPENSE] 其他费用类型:FUEL / TOLL / PARKING / RENTAL / MAINTENANCE / OTHER
expenseTypeName ⭐新增 String 否 [EXPENSE] 其他费用类型中文名,走 expense_type 字典;FUEL→油费、TOLL→过路费、PARKING→停车费、RENTAL→租车费、MAINTENANCE→维修保养、OTHER→其他
projectName String 否 [EXPENSE/SUBSIDY] 项目名称
expenseDate String 否 [EXPENSE/SUBSIDY] 费用发生日期 yyyy-MM-dd
subsidyType String 否 [SUBSIDY] 补贴类型:MEAL / PHONE / OVERTIME / OTHER
subsidyTypeName ⭐新增 String 否 [SUBSIDY] 补贴类型中文名,走 subsidy_type 字典;MEAL→餐补、PHONE→话补、OVERTIME→加班补贴、OTHER→其他

5.5 报账表预支行(SettlementReimbursementAdvanceLineVO)

advanceLines[] 从 List<Map> 改为 List<SettlementReimbursementAdvanceLineVO>:

字段 类型 必填 说明
type String 是 行类型 code:当前固定 APPROVED_ADVANCE
typeName ⭐新增 String 否 行类型中文名,走 settlement_report_line_type 字典;APPROVED_ADVANCE→已审批预支
advanceId Long 否 预支单 ID(Long,JSON 序列化为字符串)
payeeStaffId Long 否 借款对象人员安排 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 否 预支状态:SUBMITTED / APPROVED / REJECTED
statusText ⭐新增 String 否 预支状态中文名,走 AdvanceStatus 枚举 label;SUBMITTED→已提交、APPROVED→已通过、REJECTED→已拒绝
submittedAt String 否 提交时间 yyyy-MM-dd HH:mm:ss
approvedAt String 否 审批时间 yyyy-MM-dd HH:mm:ss
approvedBy String 否 审批人姓名

5.6 报账表车辆逐日行(SettlementReimbursementVehicleLineVO)

vehicleLines[] 原已是强类型 VO,本次仅新增 1 个字段:

字段 类型 必填 说明
sourceTypeName ⭐新增 String 否 车辆费用来源中文名,走 SettlementDetailSourceType 枚举 label;FLEET→车务、MANUAL→外部

其余字段(sourceDetailId、serviceDate、vehicleId、vehiclePlate、vehicleModelId、vehicleModelName、driverId、driverName、dailyPrice、amount、paymentMethod、paymentMethodName、sourceType、draftLineId、settlementConfirmStatus、remark、voucherUrls、vehicleFeeWaiverReason、vehicleFeeSource、vehicleFeeAdjustmentReason、vehicleFeeAdjustedById、vehicleFeeAdjustedAt)不变。

6. 枚举 / 数据字典

6.1 新增数据字典

本次通过 Flyway 迁移(hl-user-service)新建 5 个字典,并为 staff_role 补回 DRIVER 值:

字典类型 dict_type_id 值数 用途 取值
settlement_category 10143 8 核单费用类别中文名 HOTEL→住宿、TICKET→门票/游玩项目、MEAL→餐食、VEHICLE→车辆、GUIDE→导游、PHOTOGRAPHER→摄影、OTHER_EXPENSE→其他支出、INSURANCE→保险
settlement_payment_method 10144 3 核单付款方式中文名 CASH_PAID→现金已付、COMPANY_PAID→公司支付、SIGNED→签单
settlement_report_line_type 10145 6 核单报表行类型中文名 BASE_ORDER→订单应收、OTHER_INCOME→其他收入、DISCOUNT→优惠、ACTUAL_REFUND→实际退款、DRIVER_CASH_RECEIPT→司机现金收款、APPROVED_ADVANCE→已审批预支
expense_type 10147 6 其他费用类型中文名 FUEL→油费、TOLL→过路费、PARKING→停车费、RENTAL→租车费、MAINTENANCE→维修保养、OTHER→其他
subsidy_type 10148 4 补贴类型中文名 MEAL→餐补、PHONE→话补、OVERTIME→加班补贴、OTHER→其他
staff_role 8012 +1 人员角色补回 DRIVER;现有 5 值不变 新增 DRIVER→司机;原 GUIDE→导游、GUIDE_ASSISTANT→助理导游、LEADER→领队、PHOTOGRAPHER→摄影师、OTHER→其他 不变

注:dict_type_id=10146 跳过(meal_type 字典为历史手工所建,已存在,直接复用,不新建)。

6.2 涉及的既有枚举/字典(不变,仅补充中文名映射来源)

来源 作用字段 说明
PaymentChannelEnum channelName DRIVER_CASH→报账人收款、BANK_TRANSFER→银行转账、CONSULTANT_COLLECTION→顾问代收
PayType 枚举 payTypeName DEPOSIT→定金、FULL→全款、BALANCE→尾款
SettlementDetailSourceType 枚举 sourceTypeName(支出行 + 车辆行) MANUAL→手工、HOUSE_ASSIGNMENT→配房结果、SCENIC_ASSIGNMENT→配景区结果 等
AdvanceStatus 枚举 statusText SUBMITTED→已提交、APPROVED→已通过、REJECTED→已拒绝
advance_type 字典 advanceTypeName 预支类型中文(如 ACCOMMODATION_DEPOSIT→住宿押金)
meal_type 字典 mealTypeName BREAKFAST→早餐、LUNCH→午餐、DINNER→晚餐、SELF→自理

7. 错误码

本次不涉及错误码新增、删除或语义变化。584118(报表数据未就绪)、584066(暂无主报账人)等既有错误码不变。

8. 示例

8.1 典型成功(单团核算报表)

GET /v3/admin/order/2084000000000002978/settlement/reports/group
Authorization: Bearer <token>
{
  "code": 200,
  "message": "success",
  "data": {
    "id": "1001",
    "orderId": "2084000000000002978",
    "reportStatus": "CONFIRMED",
    "baseOrderAmount": "12800.00",
    "otherIncomeAmount": "500.00",
    "discountAmount": "-200.00",
    "adjustedReceivableAmount": "12600.00",
    "paidAmount": "10000.00",
    "actualRefundedAmount": "-300.00",
    "netRevenueAmount": "12300.00",
    "netReceivedAmount": "9700.00",
    "outstandingAmount": "2600.00",
    "hotelCost": "3600.00",
    "ticketCost": "2400.00",
    "mealCost": "1200.00",
    "vehicleCost": "880.00",
    "guideCost": "500.00",
    "photographerCost": "0.00",
    "otherExpenseCost": "200.00",
    "insurancePremium": "150.00",
    "totalCost": "8930.00",
    "paidCost": "7500.00",
    "unpaidCost": "1430.00",
    "grossProfit": "3370.00",
    "grossProfitRate": "0.2740",
    "travelerCount": 8,
    "perCapitaRevenue": "1537.50",
    "perCapitaCost": "1116.25",
    "perCapitaProfit": "421.25",
    "incomeLines": [
      {"type": "BASE_ORDER", "typeName": "订单应收", "amount": "12800.00"},
      {"type": "OTHER_INCOME", "typeName": "其他收入", "amount": "500.00"},
      {"type": "DISCOUNT", "typeName": "优惠", "amount": "-200.00"},
      {"type": "ACTUAL_REFUND", "typeName": "实际退款", "amount": "-300.00"}
    ],
    "costCategories": [
      {"category": "HOTEL", "categoryName": "住宿", "amount": "3600.00"},
      {"category": "TICKET", "categoryName": "门票/游玩项目", "amount": "2400.00"},
      {"category": "MEAL", "categoryName": "餐食", "amount": "1200.00"},
      {"category": "VEHICLE", "categoryName": "车辆", "amount": "880.00"},
      {"category": "GUIDE", "categoryName": "导游", "amount": "500.00"},
      {"category": "PHOTOGRAPHER", "categoryName": "摄影", "amount": "0.00"},
      {"category": "OTHER_EXPENSE", "categoryName": "其他支出", "amount": "200.00"},
      {"category": "INSURANCE", "categoryName": "保险", "amount": "150.00"}
    ],
    "generatedBy": "2037",
    "generatedByName": "腰苏图",
    "generatedAt": "2026-08-08T15:30:00",
    "confirmedBy": null,
    "confirmedByName": null,
    "confirmedAt": null
  },
  "success": true
}

8.2 典型成功(报账表,含多族支出行、预支行、车辆逐日行)

GET /v3/admin/order/2084000000000002978/settlement/reports/reimbursement
Authorization: Bearer <token>
{
  "code": 200,
  "message": "success",
  "data": {
    "id": "2001",
    "orderId": "2084000000000002978",
    "reportStatus": "CONFIRMED",
    "primaryReporterId": "7001",
    "primaryReporterName": "司机甲",
    "primaryReporterRole": "DRIVER",
    "driverCollectedTailAmount": "5000.00",
    "approvedAdvanceAmount": "3000.00",
    "reportablePaidCostAmount": "7500.00",
    "reporterNetAmount": "-2500.00",
    "incomeLines": [
      {
        "type": "DRIVER_CASH_RECEIPT",
        "typeName": "司机现金收款",
        "receiptId": "8001",
        "amount": "2000.00",
        "channel": "DRIVER_CASH",
        "channelName": "报账人收款",
        "payType": "BALANCE",
        "payTypeName": "尾款",
        "collectorStaffId": "7001",
        "collectorName": "司机甲",
        "collectorRole": "DRIVER",
        "collectorRoleName": "司机",
        "receivedAt": "2026-08-06 18:20:30",
        "remark": "尾款现金"
      }
    ],
    "expenseLines": [
      {
        "kind": "HOTEL",
        "category": "HOTEL",
        "categoryName": "住宿",
        "amount": "1200.00",
        "paymentMethod": "CASH_PAID",
        "paymentMethodName": "现金已付",
        "voucherUrls": ["https://oss.example.com/v1.jpg"],
        "remark": "含早",
        "hotelAssignmentId": "6001",
        "hotelName": "草原明珠大酒店",
        "roomType": "STANDARD",
        "roomTypeName": "标间",
        "roomCount": 3,
        "unitPrice": "400.00",
        "plannedCost": "1200.00",
        "sourceType": "HOUSE_ASSIGNMENT",
        "sourceTypeName": "配房结果",
        "dayNumber": 2,
        "stayDate": "2026-08-06"
      },
      {
        "kind": "TICKET",
        "category": "TICKET",
        "categoryName": "门票/游玩项目",
        "amount": "600.00",
        "paymentMethod": "CASH_PAID",
        "paymentMethodName": "现金已付",
        "voucherUrls": [],
        "scenicName": "希拉穆仁草原",
        "specName": "成人票",
        "ticketCount": 5,
        "ticketUnitPrice": "120.00",
        "sellPrice": "150.00",
        "totalAmount": "600.00",
        "sourceType": "SCENIC_ASSIGNMENT",
        "sourceTypeName": "配景区结果",
        "dayNumber": 3,
        "dayDate": "2026-08-07"
      },
      {
        "kind": "STAFF:GUIDE",
        "category": "GUIDE",
        "categoryName": "导游",
        "amount": "300.00",
        "paymentMethod": "CASH_PAID",
        "paymentMethodName": "现金已付",
        "voucherUrls": [],
        "staffRole": "GUIDE",
        "staffRoleName": "导游",
        "staffId": "7011",
        "staffName": "导游乙",
        "totalPlannedCost": "1500.00",
        "reimburse": "300.00",
        "detail": {},
        "settleStatus": "COMPLETED",
        "settledDate": "2026-08-08",
        "transferRef": "TX20260808001"
      },
      {
        "kind": "EXPENSE:FUEL",
        "category": "OTHER_EXPENSE",
        "categoryName": "其他支出",
        "amount": "200.00",
        "paymentMethod": "CASH_PAID",
        "paymentMethodName": "现金已付",
        "voucherUrls": [],
        "expenseType": "FUEL",
        "expenseTypeName": "油费",
        "projectName": "全程油费",
        "expenseDate": "2026-08-06"
      },
      {
        "kind": "SUBSIDY:MEAL",
        "category": "OTHER_EXPENSE",
        "categoryName": "其他支出",
        "amount": "150.00",
        "paymentMethod": "CASH_PAID",
        "paymentMethodName": "现金已付",
        "voucherUrls": [],
        "subsidyType": "MEAL",
        "subsidyTypeName": "餐补",
        "projectName": "每日餐补",
        "expenseDate": "2026-08-06"
      }
    ],
    "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-05 10:00:00",
        "approvedAt": "2026-08-05 12:00:00",
        "approvedBy": "财务丙"
      }
    ],
    "vehicleLines": [
      {
        "sourceDetailId": "9001",
        "serviceDate": "2026-08-06",
        "vehicleId": "9101",
        "vehiclePlate": "蒙A-5376",
        "vehicleModelId": "9201",
        "vehicleModelName": "坦克500",
        "driverId": "9301",
        "driverName": "司机甲",
        "dailyPrice": "880.00",
        "amount": "880.00",
        "paymentMethod": "CASH_PAID",
        "paymentMethodName": "现金已付",
        "sourceType": "FLEET",
        "sourceTypeName": "车务",
        "draftLineId": "9401",
        "settlementConfirmStatus": "CONFIRMED",
        "remark": null,
        "voucherUrls": []
      }
    ],
    "generatedBy": "2037",
    "generatedByName": "腰苏图",
    "generatedAt": "2026-08-08T15:30:00"
  },
  "success": true
}

8.3 边界情况(空数组:订单还未生成核单报表)

GET /v3/admin/order/2084000000000002999/settlement/reports/group
Authorization: Bearer <token>
{
  "code": 584118,
  "message": "核单报表数据未就绪,请先完成核单",
  "data": null,
  "success": false
}

当订单尚未完成核单(无终态快照)时,两个报表接口均返回 584118。完成核单后,两个接口正常返回数据,incomeLines / costCategories / expenseLines / advanceLines 等明细数组无数据时为空数组 [](不会是 null)。

9. 业务边界

  • 适用状态:订单已完成核单(存在终态快照),settlement_status 为 COMPLETED 或已反确认重开前曾确认过。
  • 不适用状态:核单未完成(settlement_status=PENDING 或其他中间态)时返回 584118(报表数据未就绪)。
  • 特殊边界:
    • 单团核算 incomeLines[] 固定 4 行(BASE_ORDER / OTHER_INCOME / DISCOUNT / ACTUAL_REFUND),无数据行也不缺行(金额为 0)。
    • 单团核算 costCategories[] 固定 8 行(HOTEL~INSURANCE),同样不缺行。
    • 报账表 incomeLines[] 目前仅司机现金收款行,无司机收款时为空数组。
    • 报账表 expenseLines[] 每行仅本族字段非 null(@JsonInclude(NON_NULL)),前端按 kind 前缀(如 HOTEL / TICKET / MEAL / STAFF: / VEHICLE_FEE / EXPENSE: / SUBSIDY:)区分族渲染。
    • xxxName 字段在字典不可用或 code 未命中时可能为 null(不阻断主流程),前端展示时应降级回 code 或以空字符串处理。

10. 修改前后对比

10.1 字段级对比

数组字段 修改前类型 修改后类型 影响
SettlementGroupReportRespVO.incomeLines List<Map<String,Object>> List<SettlementGroupIncomeLineVO> TS 类型可生成;新增 typeName 字段
SettlementGroupReportRespVO.costCategories List<Map<String,Object>> List<SettlementGroupCostCategoryVO> TS 类型可生成;新增 categoryName 字段
SettlementReimbursementReportRespVO.incomeLines List<Map<String,Object>> List<SettlementReimbursementIncomeLineVO> TS 类型可生成;新增 typeName/channelName/payTypeName/collectorRoleName
SettlementReimbursementReportRespVO.expenseLines List<Map<String,Object>> List<SettlementReimbursementExpenseLineVO> TS 类型可生成;新增 categoryName/paymentMethodName/mealTypeName/expenseTypeName/subsidyTypeName/staffRoleName/sourceTypeName
SettlementReimbursementReportRespVO.advanceLines List<Map<String,Object>> List<SettlementReimbursementAdvanceLineVO> TS 类型可生成;新增 typeName/payeeRoleName/advanceTypeName/statusText
SettlementReimbursementVehicleLineVO.sourceTypeName 不存在 String 新增字段

10.2 行为级对比

方面 修改前 修改后
前端获取 code 中文名 需前端自维护 code→label 硬编码映射表 后端直接在出参里提供 xxxName 字段,前端直接渲染
类型安全 Map<String,Object>,IDE 无补全,字段拼写错误运行时才发现 强类型 VO,Knife4j 和前端代码生成均有完整类型定义
JSON 输出 所有 Map key 全量输出(含 null 值 key) @JsonInclude(NON_NULL),仅非 null 字段输出,JSON 体积减小
字典降级 前端硬编码,字典增减需发版 后端走数据字典动态加载(5 分钟本地缓存),字典变化实时生效

11. 影响评估 / 回滚

  • 破坏兼容:否。本次为纯新增字段,旧字段名、类型、语义完全不变。前端不读新字段不影响现有功能。
  • 前端同步上线:不强制同步。前端可先上线新接口对接(读 xxxName 替换硬编码),再逐步移除旧硬编码。但建议尽快适配以统一展示效果——后端字典更新后前端硬编码可能不同步。
  • 回滚方案:若需回滚后端,前端需回退到读旧 Map 结构(字段名不变,只是少了 xxxName)。回滚到旧版后 xxxName 字段不再出现,前端如已移除硬编码则中文名会丢失。

12. 注意事项

  1. 出参 JSON 的 key 集合可能有变化:旧版 List<Map> 输出所有 key(含 null 值 key),新版 @JsonInclude(NON_NULL) 仅输出非 null key。前端按 key 遍历/检查存在性时注意——null 值的 key 不再出现,应使用 != null 而非 hasOwnProperty 检查。
  2. xxxName 可能为 null:字典加载失败或 code 未命中时 xxxName 为 null(不阻断主流程),前端展示时应 fallback 到 code 原值或空字符串。不要假设 xxxName 一定非空。
  3. kind 字段区分支出行族:报账表支出行的 7 个族(HOTEL / TICKET / MEAL / STAFF:* / VEHICLE_FEE / EXPENSE:* / SUBSIDY:*)共享同一个 VO,kind 字段标识当前行属于哪个族,前端按 kind 前缀路由渲染组件。kind 字段本次不变。
  4. Long 类型 ID 字段:receiptId、collectorStaffId、advanceId、payeeStaffId、staffId、hotelAssignmentId、hotelId、roomTypeId、sourceId、scenicAssignmentId、sourceDetailId、vehicleId、vehicleModelId、driverId、vehicleFeeAdjustedBy、draftLineId 等均为 Long 类型,JSON 序列化为字符串(@JsonSerialize(using = ToStringSerializer.class)),前端注意不要用 typeof === 'number' 判断。
  5. 车辆逐日行 vehicleFeeAdjustedAt 时间格式:该字段格式为 yyyy-MM-dd'T'HH:mm:ss(ISO-8601),不同于其他时间字段的 yyyy-MM-dd HH:mm:ss,前端解析时注意。
  6. staff_role 字典新增 DRIVER:团期人员角色下拉会新增「司机」选项(用户已确认接受此副作用)。

13. 关联 / 联系人

链接

联系人

  • 后端负责人: @yst(yaosutu / 腰苏图)