---
schema: "hl-changelog/v2"
ticket: "5953"
title: "主报账表展示其他收入/其他支出明细（不影响报账人净额）"
consumer: "admin"
change_type: "修改接口"
author: "yst"
backend_status: "deployed"
gateway_status: "verified"
frontend_status: "pending"
frontend_owner: ""
frontend_ref: ""
target_release: ""
verified_at: ""
status_note: "PR #5954 已合并 dev-v3（merge commit d945ffc3d6）。纯追加式变更：incomeLines 追加 OTHER_INCOME 其他收入展示行、expenseLines 追加 OTHER_EXPENSE 其他支出展示行并扩充行字段，baseInfo 汇总口径零漂移；字典 settlement_report_line_type 补 OTHER_EXPENSE（user-service Flyway V20260813_001，随 hl-user-service 部署生效）。"
updated_at: "2026-08-13"
base: "dev-v3"
---

# 【修改接口·管理后台】主报账表展示其他收入/其他支出明细（不影响报账人净额）（#5953）

## 1. 接口背景

主报账人报账表（reimbursement）是管理后台订单核单页查看主报账人（通常是司机）代收、垫付支出、预支与净额结算情况的只读报表。

此前报表有两个信息缺口：

- **收入侧**：只有 DRIVER_CASH_RECEIPT（报账人现金收款）一类行，订单的「其他收入」（升级房型、下马酒等逐项增收）完全看不到，财务对账时要跳到别的页面查。
- **支出侧**：只含报账人现金垫付（CASH_PAID）的支出，「其他支出」分类（其他费用/补贴）整类不透出，签单/公司直付的其他支出也无从展示。

本次变更把 **OTHER_INCOME 其他收入** 和 **OTHER_EXPENSE 其他支出** 两类的逐项明细以**展示行**形式追加进报账表：**纯展示、不并入 baseInfo 任何汇总值**，报账人净额口径与之前完全一致（零漂移）。

## 2. 变更清单

| # | 位置 | 变更 | 类型 |
|---|------|------|------|
| 1 | incomeLines | 追加 OTHER_INCOME 其他收入展示行（type=OTHER_INCOME），逐行透出 itemName/content/unitPrice/quantity/amount/paymentMethod(+Name)/sourceType(+Name)/remark/voucherUrls | ✨ 新增展示行 |
| 2 | incomeLines 元素 | 新增 9 个字段：itemName / content / unitPrice / quantity / paymentMethod / paymentMethodName / sourceType / sourceTypeName / voucherUrls（仅 OTHER_INCOME 行输出） | ✨ 新增字段 |
| 3 | expenseLines | 追加 OTHER_EXPENSE 其他支出展示行（type=OTHER_EXPENSE，整类追加在支出行数组尾部），透出实际付款方式（不再固定 CASH_PAID） | ✨ 新增展示行 |
| 4 | expenseLines 元素 | 新增 8 个字段：type / typeName / expenseType / expenseTypeName / subsidyType / subsidyTypeName / sourceType / sourceTypeName（仅 OTHER_EXPENSE 展示行输出 type 系字段） | ✨ 新增字段 |
| 5 | baseInfo 汇总口径 | **不变但更明确**：primaryReporterCollectedAmount 仍只算 DRIVER_CASH_RECEIPT 行；reportablePaidCostAmount 仍只算 CASH_PAID 垫付行（含 OTHER_EXPENSE 分类中的 CASH_PAID 行）；reporterNetAmount 公式不变 | 🔧 口径声明（数值零漂移） |
| 6 | expenseLines 排序 | OTHER_EXPENSE 分类的 CASH_PAID 行**从原主排序块移到支出行数组尾部**（整类统一走尾部展示块） | 🔧 行为变化 |
| 7 | 字典 | settlement_report_line_type 新增 OTHER_EXPENSE=其他支出（dict_data_id=101457） | ✨ 新增字典值 |

无入参变化、无新接口、无删除字段，属**非破坏性追加**。

## 3. 接口详情

| 项 | 值 |
|---|---|
| 方法 + 路径 | GET /v3/admin/order/{orderId}/settlement/reports/reimbursement |
| 接口名 | 查询主报账人报账表 |
| 使用场景 | 管理后台订单核单页，查看主报账人代收/垫付/预支/净额结算报表（含其他收入/其他支出逐项展示） |
| 认证 | 管理后台 JWT（/v3/admin/* 走网关鉴权） |
| 角色限制 | 房务角色（HOUSE）不可访问，调了会被 403 拦截 |
| 幂等性 | 只读查询，幂等 |
| 限流 | 走网关默认限流，无接口级特殊限流 |

## 4. 接口入参

### 4.1 路径参数

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| orderId | Long | 是 | 订单 ID，必须大于 0（否则 400「订单 ID 必须大于 0」） |

### 4.2 请求体 / Query

无请求体、无 Query 参数。

## 5. 出参字段

返回 `Result<SettlementReimbursementReportRespVO>`。顶层 4 个字段不变：baseInfo / incomeLines / expenseLines / advanceLines。baseInfo 与 advanceLines 字段结构**本次零变化**（baseInfo 汇总口径见 §9），下面只列**有变化的 incomeLines / expenseLines**。

### 5.1 incomeLines 元素字段表（两类行：DRIVER_CASH_RECEIPT + OTHER_INCOME）

| 字段 | 类型 | 输出条件 | 说明 |
|------|------|----------|------|
| type | String | 恒输出 | 行类型：DRIVER_CASH_RECEIPT（报账人现金收款）/ **OTHER_INCOME（其他收入展示行，本次新增）** |
| typeName | String | 恒输出 | 行类型中文名（字典 settlement_report_line_type） |
| receiptId | Long(String) | 仅收款行 | 线下收款记录 ID，序列化为字符串 |
| amount | BigDecimal | 恒输出 | 金额，保留两位小数 |
| channel | String | 仅收款行 | 收款渠道：DRIVER_CASH / BANK_TRANSFER / CONSULTANT_COLLECTION |
| channelName | String | 仅收款行 | 收款渠道中文名（枚举 label） |
| payType | String | 仅收款行 | 收款款项类型：DEPOSIT / FULL / BALANCE |
| payTypeName | String | 仅收款行 | 款项类型中文名（枚举 label） |
| collectorStaffId | Long(String) | 仅收款行 | 收款人人员安排 ID，序列化为字符串 |
| collectorName | String | 仅收款行 | 收款人姓名 |
| collectorRole | String | 仅收款行 | 收款人角色（如 DRIVER） |
| collectorRoleName | String | 仅收款行 | 收款人角色中文名（字典 staff_role） |
| receivedAt | String | 仅收款行 | 收款时间，格式 yyyy-MM-dd HH:mm:ss |
| remark | String | 无备注不输出 | 备注 |
| **itemName** | String | **仅 OTHER_INCOME 行** | 项目名（与支出行 / 明细 tab 的 itemName 同义对齐，如「升级房型」） |
| **content** | String | 仅 OTHER_INCOME 行，无规格不输出 | 规格/内容（如「豪华蒙古包」） |
| **unitPrice** | BigDecimal | 仅 OTHER_INCOME 行 | 单价，保留两位小数 |
| **quantity** | BigDecimal | 仅 OTHER_INCOME 行 | 数量 |
| **paymentMethod** | String | 仅 OTHER_INCOME 行 | 收付款方式：CASH_PAID / COMPANY_PAID / SIGNED |
| **paymentMethodName** | String | 仅 OTHER_INCOME 行 | 收付款方式中文名（字典 settlement_payment_method，缺值回退硬编码） |
| **sourceType** | String | 仅 OTHER_INCOME 行，无来源不输出 | 明细来源类型（如 ORDER_SURCHARGE，全量取值见 §6） |
| **sourceTypeName** | String | 仅 OTHER_INCOME 行 | 明细来源类型中文名（SettlementDetailSourceType 枚举 label） |
| **voucherUrls** | Array<String> | 仅 OTHER_INCOME 行，无凭证不输出该键 | 凭证 URL 数组 |

**排序**：收款行（DRIVER_CASH_RECEIPT）按收款时间升序在前，OTHER_INCOME 展示行按分类快照稳定序**追加在后**。

### 5.2 expenseLines 元素字段表（CASH_PAID 垫付行 + OTHER_EXPENSE 展示行）

| 字段 | 类型 | 输出条件 | 说明 |
|------|------|----------|------|
| **type** | String | **仅 OTHER_EXPENSE 展示行输出，其余支出行不输出该键** | 行类型，固定 OTHER_EXPENSE |
| **typeName** | String | 仅 OTHER_EXPENSE 展示行 | 行类型中文名（字典 settlement_report_line_type，值「其他支出」） |
| category | String | 恒输出 | 费用类别：HOTEL / TICKET / MEAL / VEHICLE / GUIDE / PHOTOGRAPHER / OTHER_EXPENSE / INSURANCE |
| categoryName | String | 恒输出 | 费用类别中文名（字典 settlement_category） |
| itemName | String | 恒输出 | 项目名（分类特有信息折叠：住宿=酒店-房型，餐食=餐食名(餐类型)，其他支出=项目名 等） |
| unitPrice | BigDecimal | 无单价概念不输出 | 单价，保留两位小数 |
| quantity | BigDecimal | 无数量概念不输出 | 数量 |
| amount | BigDecimal | 恒输出 | 实际金额，保留两位小数 |
| reimburseAmount | BigDecimal | 恒输出 | 报账金额；注意 **OTHER_EXPENSE 非 CASH_PAID 展示行的 reimburseAmount 也是全额**（仅展示口径，不代表可报账），前端自算合计见 §9 警示 |
| paymentMethod | String | 恒输出 | 付款方式：CASH_PAID / COMPANY_PAID / SIGNED；非 OTHER_EXPENSE 支出行固定 CASH_PAID，**OTHER_EXPENSE 展示行透出实际付款方式** |
| paymentMethodName | String | 恒输出 | 付款方式中文名（字典 settlement_payment_method，缺值回退硬编码） |
| date | String | 无日期概念不输出 | 业务日期，格式 yyyy-MM-dd |
| remark | String | 无备注不输出 | 备注 |
| voucherUrls | Array<String> | 无凭证不输出该键 | 凭证 URL 数组 |
| **expenseType** | String | 仅 OTHER_EXPENSE 展示行（EXPENSE 族） | 其他费用类型（如 OTHER） |
| **expenseTypeName** | String | 仅 OTHER_EXPENSE 展示行（EXPENSE 族） | 其他费用类型中文名（字典 expense_type） |
| **subsidyType** | String | 仅 OTHER_EXPENSE 展示行（SUBSIDY 族） | 补贴类型：PHONE / OVERTIME |
| **subsidyTypeName** | String | 仅 OTHER_EXPENSE 展示行（SUBSIDY 族） | 补贴类型中文名（字典 subsidy_type，如「话补」） |
| **sourceType** | String | 仅 OTHER_EXPENSE 展示行，无来源不输出 | 明细来源类型（全量取值见 §6） |
| **sourceTypeName** | String | 仅 OTHER_EXPENSE 展示行 | 明细来源类型中文名（SettlementDetailSourceType 枚举 label） |

**排序**：原主排序块（全分类 CASH_PAID 垫付行，不含 OTHER_EXPENSE）在前；OTHER_EXPENSE 分类**整类追加在支出行数组尾部**（含其中的 CASH_PAID 行——这类行原本混在主排序块里，本次统一移到尾部展示块）。

### 5.3 baseInfo / advanceLines

结构零变化。baseInfo 汇总口径（数值与修改前完全一致）：

- primaryReporterCollectedAmount = 仅 DRIVER_CASH_RECEIPT 收款行合计（**不含** OTHER_INCOME 展示行）
- reportablePaidCostAmount = 仅 CASH_PAID 现金垫付支出行合计（**含** OTHER_EXPENSE 分类中的 CASH_PAID 行，不含其它付款方式展示行）
- reporterNetAmount = 代收 + 预支 - 支出，公式不变

## 6. 枚举 / 数据字典

| 字段 | 来源 | 取值 |
|------|------|------|
| incomeLines[].type | settlement_report_line_type 字典 | DRIVER_CASH_RECEIPT（司机现金收款）/ **OTHER_INCOME（其他收入）** |
| expenseLines[].type | settlement_report_line_type 字典 | **OTHER_EXPENSE（其他支出）—— 本次新增字典值**（dict_data_id=101457，sort=70）；其余支出行不输出 type 键 |
| incomeLines[].channel | PaymentChannelEnum 枚举 | DRIVER_CASH / BANK_TRANSFER / CONSULTANT_COLLECTION |
| incomeLines[].payType | PayType 枚举 | DEPOSIT（订金）/ FULL（全款）/ BALANCE（尾款） |
| *.paymentMethod | settlement_payment_method 字典 | CASH_PAID（现金已付）/ COMPANY_PAID（公司直付）/ SIGNED（签单） |
| expenseLines[].expenseType | expense_type 字典 | 如 OTHER（其他）等 |
| expenseLines[].subsidyType | subsidy_type 字典 | PHONE（话补）/ OVERTIME（加班补）等 |
| *.sourceType | SettlementDetailSourceType 枚举 | MANUAL（手工）/ HOUSE_ASSIGNMENT / SCENIC_ASSIGNMENT / ACTIVITY_ASSIGNMENT / MEAL_ASSIGNMENT / FLEET / STAFF_ASSIGNMENT / ORDER_SURCHARGE（订单增费）/ SYSTEM |
| collectorRole 等角色字段 | staff_role 字典 | DRIVER（司机）/ GUIDE（导游）等 |

## 7. 错误码

本次无新增错误码，沿用既有：

| code | message | 触发场景 |
|------|---------|----------|
| 400 | 订单 ID 必须大于 0 | orderId 路径参数校验失败 |
| 403 | 无权限访问 | 房务角色（HOUSE）JWT 调用 |
| 581007 | 订单不存在 | orderId 查不到订单 |

## 8. 示例

### 8.1 典型成功（含 OTHER_INCOME / OTHER_EXPENSE 展示行）

    GET /v3/admin/order/2087088947225038849/settlement/reports/reimbursement

```json
{
  "code": 200,
  "message": "成功",
  "data": {
    "baseInfo": {
      "orderId": "2087088947225038849",
      "orderNo": "HL20260730001",
      "primaryReporterName": "司机甲",
      "primaryReporterRole": "DRIVER",
      "primaryReporterCollectedAmount": 2000.00,
      "approvedAdvanceAmount": 500.00,
      "reportablePaidCostAmount": 1500.00,
      "reporterNetAmount": 1000.00,
      "outstandingAmount": 0.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-07-30 18:20:30",
        "remark": "尾款现金"
      },
      {
        "type": "OTHER_INCOME",
        "typeName": "其他收入",
        "itemName": "升级房型",
        "content": "豪华蒙古包",
        "unitPrice": 50.00,
        "quantity": 2,
        "amount": 100.00,
        "paymentMethod": "CASH_PAID",
        "paymentMethodName": "现金已付",
        "sourceType": "ORDER_SURCHARGE",
        "sourceTypeName": "订单增费",
        "remark": "客人现场升级",
        "voucherUrls": ["https://oss/i1.jpg"]
      },
      {
        "type": "OTHER_INCOME",
        "typeName": "其他收入",
        "itemName": "下马酒",
        "unitPrice": 50.00,
        "quantity": 1,
        "amount": 50.00,
        "paymentMethod": "SIGNED",
        "paymentMethodName": "签单",
        "sourceType": "MANUAL",
        "sourceTypeName": "手工"
      }
    ],
    "expenseLines": [
      {
        "category": "HOTEL",
        "categoryName": "住宿",
        "itemName": "草原明珠大酒店-标间",
        "unitPrice": 400.00,
        "quantity": 3,
        "amount": 1200.00,
        "reimburseAmount": 1200.00,
        "paymentMethod": "CASH_PAID",
        "paymentMethodName": "现金已付",
        "date": "2026-07-30",
        "voucherUrls": ["https://oss/v1.jpg"]
      },
      {
        "type": "OTHER_EXPENSE",
        "typeName": "其他支出",
        "category": "OTHER_EXPENSE",
        "categoryName": "其他支出",
        "itemName": "景区停车费",
        "amount": 300.00,
        "reimburseAmount": 300.00,
        "paymentMethod": "CASH_PAID",
        "paymentMethodName": "现金已付",
        "expenseType": "OTHER",
        "expenseTypeName": "其他",
        "sourceType": "MANUAL",
        "sourceTypeName": "手工",
        "voucherUrls": ["https://oss/v2.jpg"]
      },
      {
        "type": "OTHER_EXPENSE",
        "typeName": "其他支出",
        "category": "OTHER_EXPENSE",
        "categoryName": "其他支出",
        "itemName": "司机话补",
        "amount": 200.00,
        "reimburseAmount": 200.00,
        "paymentMethod": "SIGNED",
        "paymentMethodName": "签单",
        "subsidyType": "PHONE",
        "subsidyTypeName": "话补",
        "sourceType": "STAFF_ASSIGNMENT",
        "sourceTypeName": "人员安排"
      }
    ],
    "advanceLines": []
  },
  "success": true
}
```

注意上例的**对账关系**（本变更的核心语义）：

- incomeLines 三行 amount 合计 2150.00，但 baseInfo.primaryReporterCollectedAmount = **2000.00**（只算 DRIVER_CASH_RECEIPT 行）—— 数组和 ≠ 汇总值属**预期**。
- expenseLines 三行 amount 合计 1700.00，但 baseInfo.reportablePaidCostAmount = **1500.00**（只算 CASH_PAID 行：住宿 1200 + 其他支出现金垫付 300；签单的话补 200 仅展示不入账）。
- reporterNetAmount = 2000 + 500 - 1500 = **1000.00**，与修改前公式完全一致。

### 8.2 边界情况

**边界 1：无其他收入/其他支出** —— incomeLines / expenseLines 只有原有行（或空数组 []），不出现 OTHER_INCOME / OTHER_EXPENSE 行；新增字段键一律不输出（NON_NULL 省略），与修改前响应完全一致：

```json
{ "incomeLines": [], "expenseLines": [], "advanceLines": [] }
```

**边界 2：OTHER_INCOME 行无规格/无凭证/无来源** —— content / voucherUrls / sourceType 键不输出（不是 null）：

```json
{
  "type": "OTHER_INCOME",
  "typeName": "其他收入",
  "itemName": "下马酒",
  "unitPrice": 50.00,
  "quantity": 1,
  "amount": 50.00,
  "paymentMethod": "COMPANY_PAID",
  "paymentMethodName": "公司直付"
}
```

### 8.3 业务失败

**房务角色（HOUSE）访问被拦**：

```json
{ "code": 403, "message": "无权限访问", "success": false }
```

**订单不存在**：

```json
{ "code": 581007, "message": "订单不存在", "success": false }
```

## 9. 业务边界

**适用**：

- 核单页查看主报账人结算全貌：代收 + 垫付 + 预支 + 净额（baseInfo），以及其他收入 / 其他支出的逐项展示（incomeLines / expenseLines 展示行）。

**不适用**：

- 拿 incomeLines / expenseLines **数组自算合计去对 baseInfo 汇总值** —— 两者口径不同（见下「特殊边界」），对不上属预期。
- 想看整单收入/成本/毛利 —— 走单团核算表（reports/group），报账表是主报账人维度。

**特殊边界（前端必知）**：

1. **数组和 ≠ 汇总值属预期**：OTHER_INCOME / OTHER_EXPENSE 展示行**纯展示不计入** baseInfo 任何汇总。primaryReporterCollectedAmount 仍只算 DRIVER_CASH_RECEIPT 行；reportablePaidCostAmount 仍只算 CASH_PAID 垫付行；reporterNetAmount 公式不变。**汇总值一律直接读 baseInfo，不要前端自算。**
2. **OTHER_EXPENSE 非 CASH_PAID 展示行的 reimburseAmount 也是全额**（如签单话补 reimburseAmount=200.00），但它不代表可报账。前端若坚持自算 sum(reimburseAmount)，必须**按 type=OTHER_EXPENSE 排除展示行**（更精确的做法是按 paymentMethod=CASH_PAID 过滤，与后端口径一致；直接排除全部 OTHER_EXPENSE 行会漏掉其中 CASH_PAID 垫付行，与 reportablePaidCostAmount 差出该行金额）。
3. **OTHER_EXPENSE 的 CASH_PAID 行位置变了**：这类行原本混在支出行主排序块里，本次整类移到**支出行数组尾部**。若前端曾按「位置/下标」识别这类行，需改为按 type=OTHER_EXPENSE 识别。
4. **行类型判别方式两侧不对称**：
   - 收入行：靠 **type 值**判别（DRIVER_CASH_RECEIPT / OTHER_INCOME，type 恒输出）；
   - 支出行：靠 **type 键是否出现**判别（仅 OTHER_EXPENSE 展示行输出 type=OTHER_EXPENSE，其余支出行**没有 type 键**——不是 null，是键不存在）。
5. OTHER_EXPENSE 展示行**全量付款方式**都透出（CASH_PAID / COMPANY_PAID / SIGNED），不再像普通支出行那样固定 CASH_PAID。

## 10. 修改前后对比

### 10.1 字段级对比

| 位置 | 字段 | 修改前 | 修改后 |
|------|------|--------|--------|
| incomeLines | type 取值 | 仅 DRIVER_CASH_RECEIPT | DRIVER_CASH_RECEIPT + **OTHER_INCOME** |
| incomeLines 元素 | itemName / content / unitPrice / quantity / paymentMethod(+Name) / sourceType(+Name) / voucherUrls | 无 | **新增**（仅 OTHER_INCOME 行输出） |
| expenseLines 元素 | type / typeName | 无 | **新增**（仅 OTHER_EXPENSE 展示行输出） |
| expenseLines 元素 | expenseType(+Name) / subsidyType(+Name) / sourceType(+Name) | 无 | **新增**（仅 OTHER_EXPENSE 展示行输出） |
| expenseLines | paymentMethod 取值 | 固定 CASH_PAID | 普通支出行仍固定 CASH_PAID；**OTHER_EXPENSE 展示行透出实际付款方式**（CASH_PAID / COMPANY_PAID / SIGNED） |
| baseInfo | 全部汇总字段 | 原口径 | **零变化**（仅口径描述更明确，数值不变） |
| 字典 | settlement_report_line_type | 6 值（无 OTHER_EXPENSE） | **+OTHER_EXPENSE=其他支出** |

### 10.2 行为级对比

| 场景 | 修改前 | 修改后 |
|------|--------|--------|
| 其他收入逐项 | 报账表完全看不到 | incomeLines 尾部追加 OTHER_INCOME 展示行 |
| 其他支出逐项 | 仅 CASH_PAID 垫付行混在主排序块 | OTHER_EXPENSE 整类（全付款方式）追加在 expenseLines 尾部展示 |
| OTHER_EXPENSE CASH_PAID 行位置 | 支出行主排序块内（按金额等排序） | **移到支出行数组尾部**展示块 |
| baseInfo 汇总值 | 代收=收款行合计，支出=CASH_PAID 合计 | **数值逐分不差**（展示行不入账） |
| 无其他收支的订单 | 原样 | **响应与原样完全一致**（新行不出现、新字段键不输出） |

## 11. 影响评估 / 回滚

### 11.1 影响评估

- **破坏兼容性**：非破坏性。纯追加行 + 追加字段，既有字段名/类型/结构零变化；无其他收支的订单响应与修改前逐字节一致。
- **前端是否必须同步上线**：**不强制**。只读 baseInfo 汇总 + 渲染既有行的前端**零改动可继续用**；但要看到其他收入/其他支出明细，需按 §5 新行结构做渲染，并按 §9 特殊边界处理（汇总读 baseInfo、支出行按 type 键识别 OTHER_EXPENSE）。
- **前端如有 workaround 需清理**：若前端曾从别的接口拼「其他收入/其他支出」进报账页，可改读本接口展示行；若前端曾自算 sum(incomeLines.amount) 当代收，需改读 baseInfo.primaryReporterCollectedAmount（此前碰巧相等，现在会虚高）。
- **字典依赖**：expenseLines[].typeName（「其他支出」）依赖 hl-user-service 字典迁移 V20260813_001（sys_dict_data 101457）；该迁移未部署前 typeName 会落 null，前端需兜底显示原 code。

### 11.2 回滚方案

- 后端回滚 = revert PR #5954 的 merge commit（d945ffc3d6），重启 hl-order-service-v3。
- 字典迁移残留：V20260813_001 新增的 OTHER_EXPENSE 字典值在回滚后无消费方，残留无害，无需回退。
- 零业务表 DDL，回滚无数据残留风险。

## 12. 注意事项

1. **汇总只读 baseInfo**：primaryReporterCollectedAmount / reportablePaidCostAmount / reporterNetAmount 是后端算好的权威值，前端不要拿 incomeLines / expenseLines 数组自算（口径不同，必然对不上）。
2. **NON_NULL 省略**：incomeLines / expenseLines 元素带 @JsonInclude(NON_NULL)，**null 字段不下发该 key**（不是下 null）；OTHER_INCOME / OTHER_EXPENSE 专属字段在普通行上键不存在，前端读取必须兜底。
3. **行判别**：收入行看 type 值；支出行看 type 键**是否存在**（JS 可用 'type' in line 判别）。
4. **Long 主键序列化为字符串**（orderId / receiptId / collectorStaffId 等），前端按 string 处理，不要 Number() 转换。
5. OTHER_EXPENSE 展示行的 expenseType 与 subsidyType 互斥（EXPENSE 族出费用类型 / SUBSIDY 族出补贴类型），渲染时按存在的键展示即可。
6. 排序约定：收入行 = 收款行（按收款时间升序）在前 + OTHER_INCOME 展示行在后；支出行 = 主排序块在前 + OTHER_EXPENSE 展示块在尾部。前端按数组顺序渲染即可，不要自行重排。
7. 本变更只影响 reimbursement 报账表；单团核算表（reports/group）结构本次零变化。

## 13. 关联 / 联系人

- Issue #5953：https://git.1814.love:8443/wx/HL/issues/5953
- PR #5954：https://git.1814.love:8443/wx/HL/pulls/5954
- Commit（merge）：https://git.1814.love:8443/wx/HL/commit/d945ffc3d6
- 服务：hl-order-service-v3（端口 8086）；字典迁移在 hl-user-service（V20260813_001，随 user-service 部署生效）
- 后端负责人：yst（腰苏图）

## 14. 验证证据

- 后端单测：SettlementReportFlowServiceTest / SettlementReportLabelEnricherTest / SettlementReportLineConverterTest 覆盖 OTHER_INCOME/OTHER_EXPENSE 展示行组装、汇总口径零漂移（代收仍只算 DRIVER_CASH 行、可报账支出仍只算 CASH_PAID 行）、字典 label 回填，PR #5954 CI 通过。
- 代码已合并 dev-v3（merge commit d945ffc3d6）并部署测试服；字典迁移 V20260813_001 随 hl-user-service 部署生效（INSERT IGNORE 幂等）。
- 前端联调验证点：无其他收支订单响应与修改前一致；含其他收支订单按 §8.1 对账关系核对（数组和 ≠ 汇总值属预期）。
