---
schema: "hl-changelog/v2"
ticket: "5324"
title: "删除旧核单兼容接口"
consumer: "admin"
change_type: "删除接口"
backend_status: "deployed"
backend_ref: "PR #5328 · merge 709105c1a1d26ae1c867fcc998286781f499faf2"
deployment_status: "deployed"
deployment_ref: "deploy-panel task ad042377"
gateway_status: "verified"
verification_status: "verified"
verification_ref: "D:/work/project-doc/PRPs/reports/5328-deploy-qa-report.md · D:/work/project-doc/test/5328/evidence.json"
frontend_status: "implemented"
frontend_owner: "hl-ui-pi"
frontend_ref: "2ab427c62a8d44155e740f4abfcc5c812a5b63ad"
target_release: ""
verified_at: "2026-07-29T10:21:44+08:00"
status_note: "部署 task ad042377 成功；8086/8186 正常；网关 20/20 HTTP 200、0 网络错误、0 个 5xx、RST 0；3 个删除路由均返回业务 404，4 个保留路由进入业务门禁且零写入。管理后台待迁移到双报表确认后调用 finalize 的五步流程。"
updated_at: "2026-07-29"
base: "dev-v3"
generated: "2026-07-28T18:04:49+08:00"
---

# 【删除接口·管理后台】删除旧核单兼容接口 (#5324)

> **PR**: #5328 | **服务**: hl-order-service-v3 | **更新时间**: 2026-07-28 18:04

## 1. 接口背景

核单完成入口统一为“双报表确认后完成核单”：管理后台先读取并确认主报账人报账表，再读取并确认单团核算表，最后携带两份报告的当前来源指纹调用 `finalize`。旧分类确认兼容接口和旧 Step6 提交入口不再提供。

## 2. 变更清单

### 2.1 删除的接口

| # | 接口 | 方法 | 路径 | 变更类型 | 前端动作 |
|---|------|------|------|----------|----------|
| 1 | 查询核单分类确认状态 | GET | `/v3/admin/order/{orderId}/settlement/category-checks` | 删除 | 删除调用及分类确认状态门禁 |
| 2 | 确认单个核单分类 | POST | `/v3/admin/order/{orderId}/settlement/category-checks/{category}/confirm` | 删除 | 删除调用及“本分类已确认”交互 |
| 3 | 旧 Step6 提交核单 | POST | `/v3/admin/order/{orderId}/settlement/step6/submit` | 删除 | 改为下表五步流程 |

### 2.2 唯一替代流程

| 顺序 | 接口 | 方法 | 路径 | 用途 |
|------|------|------|------|------|
| 1 | 查询主报账人报账表 | GET | `/v3/admin/order/{orderId}/settlement/reports/reimbursement` | 获取实时数据和主报账表 `sourceFingerprint` |
| 2 | 确认主报账人报账表 | POST | `/v3/admin/order/{orderId}/settlement/reports/reimbursement/confirm` | 确认转账、预支结清标志和签字凭证 |
| 3 | 查询单团核算表 | GET | `/v3/admin/order/{orderId}/settlement/reports/group` | 获取实时数据和单团核算表 `sourceFingerprint` |
| 4 | 确认单团核算表 | POST | `/v3/admin/order/{orderId}/settlement/reports/group/confirm` | 确认当前单团核算结果 |
| 5 | 完成核单 | POST | `/v3/admin/order/{orderId}/settlement/finalize` | 携带两份已确认报告的当前指纹完成核单 |

## 3. 接口详情

以下五个接口都需要管理后台登录态，房务角色不可访问；`orderId` 为必填路径参数，类型为 `Long/String`，值必须大于 0。

### 3.1 查询主报账人报账表

- **方法 + 路径**：`GET /v3/admin/order/{orderId}/settlement/reports/reimbursement`
- **使用场景**：进入报账报表页面、确认前刷新、来源数据变化后重新获取。
- **幂等性**：幂等，只读。
- **请求体**：无。
- **成功响应**：`Result<SettlementReimbursementReportRespVO>`，完整字段见 §5.2。
- **关键规则**：前端必须保存本次响应的 `data.sourceFingerprint`；确认请求不得使用缓存的旧指纹。

**请求示例**

```http
GET /v3/admin/order/1914050000000001/settlement/reports/reimbursement
Authorization: Bearer <token>
```

**响应示例**

```json
{
  "code": 200,
  "msg": "success",
  "data": {
    "id": null,
    "orderId": "1914050000000001",
    "reportStatus": "GENERATED",
    "sourceFingerprint": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
    "primaryReporterId": "3001",
    "primaryReporterName": "王司机",
    "primaryReporterRole": "DRIVER",
    "reportVersion": 1,
    "driverCollectedTailAmount": 2000.00,
    "approvedAdvanceAmount": 500.00,
    "reportablePaidCostAmount": 1000.00,
    "reporterNetAmount": 1500.00,
    "primaryReporterCollectedAmount": 2000.00,
    "publicPrepaidAmount": 1000.00,
    "primaryReporterDueAmount": 1000.00,
    "advanceOutstandingAmount": 500.00,
    "reconNetAmount": 1500.00,
    "transferDirection": "REPORTER_TO_COMPANY",
    "transferAmount": 1500.00,
    "incomeLines": [
      {
        "type": "DRIVER_CASH_RECEIPT",
        "receiptId": "9100000000001",
        "amount": 2000.00,
        "channel": "DRIVER_CASH",
        "payType": "CASH",
        "collectorStaffId": "3001",
        "collectorName": "王司机",
        "collectorRole": "DRIVER",
        "receivedAt": "2026-07-27T18:30:00",
        "remark": "司机代收尾款"
      }
    ],
    "expenseLines": [
      {
        "category": "HOTEL",
        "kind": "HOTEL",
        "hotelAssignmentId": "9200000000001",
        "hotelName": "示例酒店",
        "stayDate": "2026-07-20",
        "amount": 1000.00,
        "paymentMethod": "CASH_PAID",
        "remark": null
      }
    ],
    "advanceLines": [
      {
        "type": "APPROVED_ADVANCE",
        "advanceId": "9300000000001",
        "payeeStaffId": "3001",
        "payeeName": "王司机",
        "payeeRole": "DRIVER",
        "advanceType": "PUBLIC",
        "amount": 500.00,
        "purpose": "途中费用",
        "voucherUrl": "https://oss.example.com/advance.jpg",
        "status": "APPROVED",
        "submittedAt": "2026-07-18T10:00:00",
        "approvedAt": "2026-07-18T11:00:00",
        "approvedBy": "10001"
      }
    ],
    "vehicleLines": [],
    "transferStatus": null,
    "transferDate": null,
    "transferRef": null,
    "advanceSettledFlag": false,
    "signedVoucher": null,
    "generatedBy": null,
    "generatedByName": null,
    "generatedAt": null,
    "confirmedBy": null,
    "confirmedByName": null,
    "confirmedAt": null
  }
}
```

### 3.2 确认主报账人报账表

- **方法 + 路径**：`POST /v3/admin/order/{orderId}/settlement/reports/reimbursement/confirm`
- **使用场景**：已核对主报账表，且转账、预支标记和签字凭证已经填写完毕。
- **幂等性**：同一当前指纹和完全相同的确认内容可重复提交；确认后改传其它内容返回 `584317`。
- **请求体**：见 §4.2。
- **成功响应**：与 §3.1 相同，`reportStatus=CONFIRMED`，并返回确认信息。

**请求示例**

```http
POST /v3/admin/order/1914050000000001/settlement/reports/reimbursement/confirm
Authorization: Bearer <token>
Content-Type: application/json

{
  "expectedSourceFingerprint": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
  "transferStatus": "COMPLETED",
  "transferDate": "2026-07-28",
  "transferRef": "BANK-20260728-001",
  "advanceSettledFlag": true,
  "signedVoucher": {
    "files": [
      {
        "name": "司机签字单.pdf",
        "url": "https://oss.example.com/signed-voucher.pdf"
      }
    ],
    "note": "签字凭证已回收"
  }
}
```

**响应示例**

```json
{
  "code": 200,
  "msg": "success",
  "data": {
    "id": "9400000000001",
    "orderId": "1914050000000001",
    "reportStatus": "CONFIRMED",
    "sourceFingerprint": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
    "primaryReporterId": "3001",
    "primaryReporterName": "王司机",
    "primaryReporterRole": "DRIVER",
    "reportVersion": 1,
    "driverCollectedTailAmount": 2000.00,
    "approvedAdvanceAmount": 500.00,
    "reportablePaidCostAmount": 1000.00,
    "reporterNetAmount": 1500.00,
    "primaryReporterCollectedAmount": 2000.00,
    "publicPrepaidAmount": 1000.00,
    "primaryReporterDueAmount": 1000.00,
    "advanceOutstandingAmount": 500.00,
    "reconNetAmount": 1500.00,
    "transferDirection": "REPORTER_TO_COMPANY",
    "transferAmount": 1500.00,
    "incomeLines": [],
    "expenseLines": [],
    "advanceLines": [],
    "vehicleLines": [],
    "transferStatus": "COMPLETED",
    "transferDate": "2026-07-28",
    "transferRef": "BANK-20260728-001",
    "advanceSettledFlag": true,
    "signedVoucher": {
      "files": [
        {
          "name": "司机签字单.pdf",
          "url": "https://oss.example.com/signed-voucher.pdf"
        }
      ],
      "note": "签字凭证已回收"
    },
    "generatedBy": null,
    "generatedByName": null,
    "generatedAt": null,
    "confirmedBy": "10001",
    "confirmedByName": "财务管理员",
    "confirmedAt": "2026-07-28T18:10:00"
  }
}
```

### 3.3 查询单团核算表

- **方法 + 路径**：`GET /v3/admin/order/{orderId}/settlement/reports/group`
- **使用场景**：主报账表确认后查看单团收入、成本、毛利和人均指标。
- **幂等性**：幂等，只读。
- **请求体**：无。
- **成功响应**：`Result<SettlementGroupReportRespVO>`，完整字段见 §5.3。
- **关键规则**：前端必须保存本次响应的 `data.sourceFingerprint`；确认请求不得使用缓存的旧指纹。

**请求示例**

```http
GET /v3/admin/order/1914050000000001/settlement/reports/group
Authorization: Bearer <token>
```

**响应示例**

```json
{
  "code": 200,
  "msg": "success",
  "data": {
    "id": null,
    "orderId": "1914050000000001",
    "reportStatus": "GENERATED",
    "sourceFingerprint": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
    "baseOrderAmount": 24800.00,
    "otherIncomeAmount": 500.00,
    "discountAmount": 300.00,
    "adjustedReceivableAmount": 25000.00,
    "paidAmount": 25000.00,
    "actualRefundedAmount": 0.00,
    "netRevenueAmount": 25000.00,
    "netReceivedAmount": 25000.00,
    "outstandingAmount": 0.00,
    "hotelCost": 4280.00,
    "ticketCost": 3680.00,
    "mealCost": 860.00,
    "vehicleCost": 1260.00,
    "guideCost": 800.00,
    "photographerCost": 600.00,
    "otherExpenseCost": 300.00,
    "insurancePremium": 180.00,
    "totalCost": 11960.00,
    "paidCost": 11960.00,
    "unpaidCost": 0.00,
    "grossProfit": 13040.00,
    "grossProfitRate": 0.5216,
    "travelerCount": 5,
    "perCapitaRevenue": 5000.00,
    "perCapitaCost": 2392.00,
    "perCapitaProfit": 2608.00,
    "incomeLines": [
      {"type": "BASE_ORDER", "amount": 24800.00},
      {"type": "OTHER_INCOME", "amount": 500.00},
      {"type": "DISCOUNT", "amount": -300.00},
      {"type": "ACTUAL_REFUND", "amount": 0.00}
    ],
    "costCategories": [
      {"category": "HOTEL", "amount": 4280.00},
      {"category": "TICKET", "amount": 3680.00},
      {"category": "MEAL", "amount": 860.00},
      {"category": "VEHICLE", "amount": 1260.00},
      {"category": "GUIDE", "amount": 800.00},
      {"category": "PHOTOGRAPHER", "amount": 600.00},
      {"category": "OTHER_EXPENSE", "amount": 300.00},
      {"category": "INSURANCE", "amount": 180.00}
    ],
    "generatedBy": null,
    "generatedByName": null,
    "generatedAt": null,
    "confirmedBy": null,
    "confirmedByName": null,
    "confirmedAt": null
  }
}
```

### 3.4 确认单团核算表

- **方法 + 路径**：`POST /v3/admin/order/{orderId}/settlement/reports/group/confirm`
- **使用场景**：主报账表已经确认，且已核对当前单团收入、成本和利润。
- **幂等性**：相同当前指纹重复确认返回已确认结果。
- **请求体**：见 §4.3。
- **成功响应**：与 §3.3 相同，`reportStatus=CONFIRMED`，并返回确认人和确认时间。

**请求示例**

```http
POST /v3/admin/order/1914050000000001/settlement/reports/group/confirm
Authorization: Bearer <token>
Content-Type: application/json

{
  "expectedSourceFingerprint": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
}
```

**响应示例**

```json
{
  "code": 200,
  "msg": "success",
  "data": {
    "id": "9500000000001",
    "orderId": "1914050000000001",
    "reportStatus": "CONFIRMED",
    "sourceFingerprint": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
    "baseOrderAmount": 24800.00,
    "otherIncomeAmount": 500.00,
    "discountAmount": 300.00,
    "adjustedReceivableAmount": 25000.00,
    "paidAmount": 25000.00,
    "actualRefundedAmount": 0.00,
    "netRevenueAmount": 25000.00,
    "netReceivedAmount": 25000.00,
    "outstandingAmount": 0.00,
    "hotelCost": 4280.00,
    "ticketCost": 3680.00,
    "mealCost": 860.00,
    "vehicleCost": 1260.00,
    "guideCost": 800.00,
    "photographerCost": 600.00,
    "otherExpenseCost": 300.00,
    "insurancePremium": 180.00,
    "totalCost": 11960.00,
    "paidCost": 11960.00,
    "unpaidCost": 0.00,
    "grossProfit": 13040.00,
    "grossProfitRate": 0.5216,
    "travelerCount": 5,
    "perCapitaRevenue": 5000.00,
    "perCapitaCost": 2392.00,
    "perCapitaProfit": 2608.00,
    "incomeLines": [
      {"type": "BASE_ORDER", "amount": 24800.00},
      {"type": "OTHER_INCOME", "amount": 500.00},
      {"type": "DISCOUNT", "amount": -300.00},
      {"type": "ACTUAL_REFUND", "amount": 0.00}
    ],
    "costCategories": [
      {"category": "HOTEL", "amount": 4280.00},
      {"category": "TICKET", "amount": 3680.00},
      {"category": "MEAL", "amount": 860.00},
      {"category": "VEHICLE", "amount": 1260.00},
      {"category": "GUIDE", "amount": 800.00},
      {"category": "PHOTOGRAPHER", "amount": 600.00},
      {"category": "OTHER_EXPENSE", "amount": 300.00},
      {"category": "INSURANCE", "amount": 180.00}
    ],
    "generatedBy": null,
    "generatedByName": null,
    "generatedAt": null,
    "confirmedBy": "10001",
    "confirmedByName": "财务管理员",
    "confirmedAt": "2026-07-28T18:12:00"
  }
}
```

### 3.5 完成核单

- **方法 + 路径**：`POST /v3/admin/order/{orderId}/settlement/finalize`
- **使用场景**：两份报告均已确认且来源仍为当前版本时，点击“完成核单”。
- **幂等性**：已完成且存在当前终态结果时，重复提交返回当前终态结果。
- **请求体**：见 §4.4；请求体在业务上必填。
- **成功响应**：`Result<SettlementSubmitRespVO>`，完整字段见 §5.4。

**请求示例**

```http
POST /v3/admin/order/1914050000000001/settlement/finalize
Authorization: Bearer <token>
Content-Type: application/json

{
  "remark": "双报表已核对完成",
  "reimbursementExpectedSourceFingerprint": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
  "groupExpectedSourceFingerprint": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
}
```

**响应示例**

```json
{
  "code": 200,
  "msg": "success",
  "data": {
    "summaryId": "9600000000001",
    "finalSnapshotId": "9600000000002",
    "finalSnapshotVersionNo": 1,
    "finalSnapshotStatus": "FINALIZED",
    "orderId": "1914050000000001",
    "settledAt": "2026-07-28T18:15:00",
    "totalAmount": 25000.00,
    "paidAmount": 25000.00,
    "balanceAmount": 0.00,
    "roomCost": 4280.00,
    "ticketCost": 3680.00,
    "staffCost": 1400.00,
    "subsidyCost": 0.00,
    "mealCost": 860.00,
    "vehicleCost": 1260.00,
    "otherExpenseCost": 300.00,
    "insurancePremium": 180.00,
    "totalActualCost": 11960.00,
    "driverTransferAmount": 1000.00,
    "profitAmount": 13040.00,
    "profitRate": 0.5216,
    "orderStatusAfter": "待财务复核",
    "mqTriggered": true,
    "warnings": []
  }
}
```

## 4. 接口入参

### 4.1 五个替代接口共用路径参数

| 字段 | 类型 | 必填 | 说明 | 校验 |
|------|------|------|------|------|
| `orderId` | Long/String | 是 | 订单 ID | 必须大于 0 |

两个 GET 接口没有 Query 参数和请求体。

### 4.2 主报账表确认请求体

| 字段 | 类型 | 必填 | 说明 | 校验规则 |
|------|------|------|------|----------|
| `expectedSourceFingerprint` | String | 是 | §3.1 最新响应的 `data.sourceFingerprint` | 64 位小写十六进制 |
| `transferStatus` | String | 是 | 转账处理状态 | 固定传 `COMPLETED` |
| `transferDate` | String/date | 条件必填 | 转账日期 | `reporterNetAmount != 0` 时必填；格式 `YYYY-MM-DD` |
| `transferRef` | String | 条件必填 | 转账流水号或可追溯凭证号 | `reporterNetAmount != 0` 时不得为空白 |
| `advanceSettledFlag` | Boolean | 是 | 预支款项是否已处理完毕 | 不得为 `null` |
| `signedVoucher` | Object | 是 | 签字凭证 | 不得为 `null` |
| `signedVoucher.files` | Array | 是 | 签字凭证文件列表 | 至少 1 项 |
| `signedVoucher.files[].name` | String | 否 | 文件名 | 可为空 |
| `signedVoucher.files[].url` | String | 是 | 文件地址 | 不得为空白 |
| `signedVoucher.note` | String | 否 | 凭证备注 | 可为空 |

当 `reporterNetAmount = 0` 时，`transferDate` 和 `transferRef` 可不传；`transferStatus` 仍必须是 `COMPLETED`，签字凭证仍必须至少包含一个有效文件。

### 4.3 单团核算表确认请求体

| 字段 | 类型 | 必填 | 说明 | 校验规则 |
|------|------|------|------|----------|
| `expectedSourceFingerprint` | String | 是 | §3.3 最新响应的 `data.sourceFingerprint` | 64 位小写十六进制 |

### 4.4 完成核单请求体

| 字段 | 类型 | 必填 | 说明 | 校验规则 |
|------|------|------|------|----------|
| `remark` | String | 否 | 本次完成核单的整体备注 | 最长 500 字 |
| `reimbursementExpectedSourceFingerprint` | String | 是 | 已确认主报账表的当前 `sourceFingerprint` | 64 位小写十六进制 |
| `groupExpectedSourceFingerprint` | String | 是 | 已确认单团核算表的当前 `sourceFingerprint` | 64 位小写十六进制 |

### 4.5 指纹传递关系

| 来源 | 确认接口字段 | 完成核单字段 |
|------|--------------|--------------|
| `GET .../reports/reimbursement` 的 `data.sourceFingerprint` | `POST .../reports/reimbursement/confirm` 的 `expectedSourceFingerprint` | `POST .../finalize` 的 `reimbursementExpectedSourceFingerprint` |
| `GET .../reports/group` 的 `data.sourceFingerprint` | `POST .../reports/group/confirm` 的 `expectedSourceFingerprint` | `POST .../finalize` 的 `groupExpectedSourceFingerprint` |

## 5. 出参

### 5.1 统一响应外层

| 字段 | 类型 | 说明 |
|------|------|------|
| `code` | Integer | `200` 表示成功；其它值见 §7 |
| `msg` | String | 结果说明 |
| `data` | Object/null | 成功时为业务数据，失败时通常为 `null` |

所有 Long ID 以 JSON 字符串消费，避免前端数字精度损失；金额字段为十进制数。

### 5.2 主报账人报账表响应

| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | String/null | 报账表记录 ID；仅实时预览、尚未确认时可为 `null` |
| `orderId` | String | 订单 ID |
| `reportStatus` | String | `GENERATED` / `CONFIRMED` / `STALE`，见 §6.1 |
| `sourceFingerprint` | String | 当前来源指纹，64 位小写十六进制 |
| `primaryReporterId` | String/null | 主报账人 ID |
| `primaryReporterName` | String/null | 主报账人姓名 |
| `primaryReporterRole` | String/null | 主报账人角色 |
| `reportVersion` | Integer/null | 报账表版本 |
| `driverCollectedTailAmount` | Decimal | 司机代收尾款 |
| `approvedAdvanceAmount` | Decimal | 已审批预支合计 |
| `reportablePaidCostAmount` | Decimal | 主报账人已支付、可报账成本合计 |
| `reporterNetAmount` | Decimal | 报账净额：司机代收尾款 + 已审批预支 - 可报账已支付成本 |
| `primaryReporterCollectedAmount` | Decimal | 主报账人代收金额 |
| `publicPrepaidAmount` | Decimal | 公共预支金额 |
| `primaryReporterDueAmount` | Decimal | 主报账人应报账金额 |
| `advanceOutstandingAmount` | Decimal | 待处理预支金额 |
| `reconNetAmount` | Decimal | 报账净额兼容字段 |
| `transferDirection` | String | 转账方向，见 §6.2 |
| `transferAmount` | Decimal | 需转账金额，取 `reporterNetAmount` 绝对值 |
| `incomeLines` | Array<Object> | 司机代收尾款明细 |
| `expenseLines` | Array<Object> | 主报账人现金支付成本明细 |
| `advanceLines` | Array<Object> | 已审批预支明细 |
| `vehicleLines` | Array<Object> | 车辆逐日明细；允许空数组 |
| `transferStatus` | String/null | 未确认时可为空；确认后为 `COMPLETED` |
| `transferDate` | String/date/null | 转账日期 |
| `transferRef` | String/null | 转账流水号或凭证号 |
| `advanceSettledFlag` | Boolean | 预支是否已处理完毕 |
| `signedVoucher` | Object/null | 签字凭证，结构同 §4.2 |
| `generatedBy` | String/null | 历史生成操作人 ID |
| `generatedByName` | String/null | 历史生成操作人姓名 |
| `generatedAt` | String/date-time/null | 历史生成时间 |
| `confirmedBy` | String/null | 确认人 ID |
| `confirmedByName` | String/null | 确认人姓名 |
| `confirmedAt` | String/date-time/null | 确认时间 |

`incomeLines[]` 的固定字段为 `type`、`receiptId`、`amount`、`channel`、`payType`、`collectorStaffId`、`collectorName`、`collectorRole`、`receivedAt`、`remark`。

`advanceLines[]` 的固定字段为 `type`、`advanceId`、`payeeStaffId`、`payeeName`、`payeeRole`、`advanceType`、`amount`、`purpose`、`voucherUrl`、`status`、`submittedAt`、`approvedAt`、`approvedBy`。

`expenseLines[]` 至少包含 `category`、`kind`、`amount`、`paymentMethod`；按分类还会包含对应的名称、日期、数量、单价、人员或车辆标识、凭证和备注字段。前端列表应按字段是否存在展示，不依赖固定列宽。

### 5.3 单团核算表响应

| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | String/null | 单团核算表记录 ID；仅实时预览、尚未确认时可为 `null` |
| `orderId` | String | 订单 ID |
| `reportStatus` | String | `GENERATED` / `CONFIRMED` / `STALE` |
| `sourceFingerprint` | String | 当前来源指纹，64 位小写十六进制 |
| `baseOrderAmount` | Decimal | 订单基础金额 |
| `otherIncomeAmount` | Decimal | 其他收入 |
| `discountAmount` | Decimal | 优惠金额 |
| `adjustedReceivableAmount` | Decimal | 调整后应收 |
| `paidAmount` | Decimal | 已收金额 |
| `actualRefundedAmount` | Decimal | 实际退款 |
| `netRevenueAmount` | Decimal | 净收入 |
| `netReceivedAmount` | Decimal | 净已收 |
| `outstandingAmount` | Decimal | 待收金额 |
| `hotelCost` | Decimal | 住宿成本 |
| `ticketCost` | Decimal | 门票/游玩项目成本 |
| `mealCost` | Decimal | 餐食成本 |
| `vehicleCost` | Decimal | 车辆成本 |
| `guideCost` | Decimal | 导游成本 |
| `photographerCost` | Decimal | 摄影成本 |
| `otherExpenseCost` | Decimal | 其他支出成本 |
| `insurancePremium` | Decimal | 保险保费 |
| `totalCost` | Decimal | 总成本 |
| `paidCost` | Decimal | 已支付成本 |
| `unpaidCost` | Decimal | 未支付成本 |
| `grossProfit` | Decimal | 毛利 |
| `grossProfitRate` | Decimal | 毛利率；收入为 0 时为 0 |
| `travelerCount` | Integer | 出行人数 |
| `perCapitaRevenue` | Decimal | 人均收入 |
| `perCapitaCost` | Decimal | 人均成本 |
| `perCapitaProfit` | Decimal | 人均利润 |
| `incomeLines` | Array<Object> | 收入构成；元素字段为 `type`、`amount` |
| `costCategories` | Array<Object> | 成本构成；元素字段为 `category`、`amount` |
| `generatedBy` | String/null | 历史生成操作人 ID |
| `generatedByName` | String/null | 历史生成操作人姓名 |
| `generatedAt` | String/date-time/null | 历史生成时间 |
| `confirmedBy` | String/null | 确认人 ID |
| `confirmedByName` | String/null | 确认人姓名 |
| `confirmedAt` | String/date-time/null | 确认时间 |

### 5.4 完成核单响应

| 字段 | 类型 | 说明 |
|------|------|------|
| `summaryId` | String | 核单汇总 ID |
| `finalSnapshotId` | String | 核单终态版本 ID |
| `finalSnapshotVersionNo` | Integer | 核单终态版本号 |
| `finalSnapshotStatus` | String | 核单终态状态，成功时为 `FINALIZED` |
| `orderId` | String | 订单 ID |
| `settledAt` | String/date-time | 核单完成时间 |
| `totalAmount` | Decimal | 订单总金额 |
| `paidAmount` | Decimal | 已收金额 |
| `balanceAmount` | Decimal | 待收金额；完成核单时必须为 0 |
| `roomCost` | Decimal | 住宿实际成本 |
| `ticketCost` | Decimal | 门票实际成本 |
| `staffCost` | Decimal | 人员实际成本 |
| `subsidyCost` | Decimal | 补助实际成本 |
| `mealCost` | Decimal | 餐食实际成本 |
| `vehicleCost` | Decimal | 车辆实际成本 |
| `otherExpenseCost` | Decimal | 其他支出实际成本 |
| `insurancePremium` | Decimal | 保险保费 |
| `totalActualCost` | Decimal | 总实际成本 |
| `driverTransferAmount` | Decimal | 需与司机/主报账人结算的金额 |
| `profitAmount` | Decimal | 公司毛利 |
| `profitRate` | Decimal | 公司毛利率 |
| `orderStatusAfter` | String | 完成核单后的订单状态 |
| `mqTriggered` | Boolean | 核单完成事件是否已触发 |
| `warnings` | Array<String> | 软提示列表；不阻塞成功结果 |

## 6. 枚举 / 数据字典

### 6.1 `reportStatus`

**所属字段**：两份报告的 `reportStatus` | **类型**：String

| 值 | 中文 | 说明 |
|----|------|------|
| `GENERATED` | 待确认 | 当前实时数据可供核对，尚未确认 |
| `CONFIRMED` | 已确认 | 当前来源数据已经确认 |
| `STALE` | 已失效 | 来源数据已变化，旧确认不能用于完成核单 |

### 6.2 `transferDirection`

**所属字段**：主报账表 `transferDirection` | **类型**：String

| 值 | 中文 | 说明 |
|----|------|------|
| `REPORTER_TO_COMPANY` | 报账人转给公司 | `reporterNetAmount > 0` |
| `COMPANY_TO_REPORTER` | 公司转给报账人 | `reporterNetAmount < 0` |
| `BALANCED` | 无需转账 | `reporterNetAmount = 0` |

### 6.3 `transferStatus`

**所属字段**：主报账表确认请求和响应 `transferStatus` | **类型**：String

| 值 | 中文 | 说明 |
|----|------|------|
| `COMPLETED` | 已完成 | 确认主报账表时唯一允许值 |

### 6.4 单团收入行 `type`

| 值 | 中文 | 金额符号 |
|----|------|----------|
| `BASE_ORDER` | 订单基础收入 | 正数 |
| `OTHER_INCOME` | 其他收入 | 正数 |
| `DISCOUNT` | 优惠 | 负数 |
| `ACTUAL_REFUND` | 实际退款 | 负数或 0 |

### 6.5 单团成本行 `category`

| 值 | 中文 |
|----|------|
| `HOTEL` | 住宿 |
| `TICKET` | 门票/游玩项目 |
| `MEAL` | 餐食 |
| `VEHICLE` | 车辆 |
| `GUIDE` | 导游 |
| `PHOTOGRAPHER` | 摄影 |
| `OTHER_EXPENSE` | 其他支出 |
| `INSURANCE` | 保险 |

## 7. 错误码

| code | 含义 | 触发场景 |
|------|------|----------|
| `400` | 参数校验失败 | `orderId <= 0`、请求体缺字段、指纹格式错误等 |
| `403` | 无访问或写入权限 | 房务角色访问，或操作人没有核单写权限 |
| `404` | 接口不存在 | 调用本次删除的 3 个旧接口 |
| `584082` | 存在待收尾款，请收齐后再提交核单 | `finalize` 时单团核算表 `outstandingAmount != 0` |
| `584312` | 主报账表尚未确认或数据已变化 | 单团核算表确认前，主报账表未确认或已失效 |
| `584314` | 单团核算表尚未确认或数据已变化 | `finalize` 时单团核算表未确认、已失效或指纹不匹配 |
| `584315` | 核单来源数据已变化，请刷新后重新确认 | 确认报告时提交的 `expectedSourceFingerprint` 不是当前值 |
| `584316` | 核单报告发生并发变化，请刷新后重试 | 多人同时确认同一报告发生冲突 |
| `584317` | 当前报告状态不允许执行该操作 | 确认内容不合法，或报告当前状态不允许重复变更 |
| `584325` | 完成核单必须提交主报账和单团核算的当前指纹 | `finalize` 缺少任一指纹或指纹不是 64 位小写十六进制 |

## 8. 示例（典型 / 边界 / 异常）

### 8.1 典型成功：五步完成核单

1. 调用 `GET .../reports/reimbursement`，保存响应 `sourceFingerprint=aaaa...`。
2. 调用 `POST .../reports/reimbursement/confirm`，`expectedSourceFingerprint` 传 `aaaa...`，响应状态为 `CONFIRMED`。
3. 调用 `GET .../reports/group`，保存响应 `sourceFingerprint=bbbb...`。
4. 调用 `POST .../reports/group/confirm`，`expectedSourceFingerprint` 传 `bbbb...`，响应状态为 `CONFIRMED`。
5. 调用 `POST .../finalize`，两个指纹分别传 `aaaa...` 和 `bbbb...`，响应 `finalSnapshotStatus=FINALIZED`。

各步完整请求和响应见 §3.1～§3.5。

### 8.2 边界：报账净额为 0

当最新主报账表返回 `reporterNetAmount=0`、`transferDirection=BALANCED` 时：

```http
POST /v3/admin/order/1914050000000001/settlement/reports/reimbursement/confirm
Authorization: Bearer <token>
Content-Type: application/json

{
  "expectedSourceFingerprint": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
  "transferStatus": "COMPLETED",
  "advanceSettledFlag": true,
  "signedVoucher": {
    "files": [
      {
        "name": "司机签字单.pdf",
        "url": "https://oss.example.com/signed-voucher.pdf"
      }
    ],
    "note": null
  }
}
```

```json
{
  "code": 200,
  "msg": "success",
  "data": {
    "orderId": "1914050000000001",
    "reportStatus": "CONFIRMED",
    "sourceFingerprint": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
    "reporterNetAmount": 0.00,
    "transferDirection": "BALANCED",
    "transferAmount": 0.00,
    "transferStatus": "COMPLETED",
    "transferDate": null,
    "transferRef": null,
    "advanceSettledFlag": true,
    "signedVoucher": {
      "files": [
        {
          "name": "司机签字单.pdf",
          "url": "https://oss.example.com/signed-voucher.pdf"
        }
      ],
      "note": null
    }
  }
}
```

### 8.3 异常：来源数据变化

```http
POST /v3/admin/order/1914050000000001/settlement/reports/group/confirm
Authorization: Bearer <token>
Content-Type: application/json

{
  "expectedSourceFingerprint": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
}
```

```json
{
  "code": 584315,
  "msg": "核单来源数据已变化，请刷新后重新确认",
  "data": null
}
```

收到该错误后重新执行对应 GET，使用新的 `data.sourceFingerprint` 重新确认；不得继续用旧指纹调用 `finalize`。

### 8.4 异常：仍有待收尾款

```http
POST /v3/admin/order/1914050000000001/settlement/finalize
Authorization: Bearer <token>
Content-Type: application/json

{
  "reimbursementExpectedSourceFingerprint": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
  "groupExpectedSourceFingerprint": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
}
```

```json
{
  "code": 584082,
  "msg": "存在待收尾款，请收齐后再提交核单",
  "data": null
}
```

## 9. 业务边界

- 必须按“查询主报账表 → 确认主报账表 → 查询单团核算表 → 确认单团核算表 → 完成核单”的顺序执行。
- 两份报告的指纹互不通用；禁止把主报账表指纹传到单团核算字段，或反向混用。
- 每次确认前都应重新 GET；当 `reportStatus=STALE` 或收到 `584315` 时，必须刷新数据并使用新指纹。
- 单团核算表确认依赖当前有效的主报账表确认，否则返回 `584312`。
- `finalize` 同时校验两份报告已确认、指纹仍为当前值，以及 `outstandingAmount=0`。
- 主报账表 `reporterNetAmount != 0` 时，确认请求必须提供 `transferDate` 和非空 `transferRef`。
- 主报账表确认始终要求至少一个含有效 `url` 的签字凭证文件。

## 10. 修改前后对比

### 10.1 接口级对比

| 功能 | 修改前 | 修改后 |
|------|--------|--------|
| 分类状态 | 调用 `GET .../category-checks` | 不再查询分类确认状态 |
| 分类确认 | 调用 `POST .../category-checks/{category}/confirm` | 保存各核单明细即可，不再单独确认分类 |
| 报账与单团核算 | 可能绕过双报表直接提交旧 Step6 | 必须分别 GET、confirm 两份报告 |
| 完成核单 | `POST .../step6/submit` | `POST .../finalize`，请求体必须携带两个当前指纹 |

### 10.2 请求体对比

| 入口 | 修改前 | 修改后 |
|------|--------|--------|
| 旧 `step6/submit` | 旧提交请求 | 接口删除 |
| 新 `finalize` | 不适用 | `remark` 可选；`reimbursementExpectedSourceFingerprint`、`groupExpectedSourceFingerprint` 必填 |

## 11. 影响评估 / 回滚

### 11.1 影响评估

- **是否破坏向后兼容**：是。3 个旧接口已删除。
- **前端是否必须同步上线**：是。仍调用任一旧接口的管理后台将收到 404；旧 Step6 提交必须迁移为五步流程。

### 11.2 回滚原则

- 后端回退时，前端仍可保留五步新流程。
- 前端不得因为短期回退重新新增分类确认入口或恢复旧 Step6 调用；如需临时兼容，应单独确认接口契约后再处理。

## 12. 注意事项

- 删除 `category-checks` 查询、分类确认 API 封装、分类确认按钮和相关状态门禁。
- 删除 `step6/submit` API 封装及所有调用点。
- “完成核单”按钮改为调用 `finalize`，并在调用前确保两份报告都为 `CONFIRMED`。
- 页面状态中分别保存两份 `sourceFingerprint`，不要只保存一个通用指纹。
- 主报账表确认成功后再开放单团核算确认；单团核算确认成功后再开放“完成核单”。
- 收到 `584312`、`584314`、`584315`、`584316` 时刷新对应报告，不得自动使用旧数据重试。

## 13. 关联 / 联系人

### 13.1 链接

- **Issue**: [#5324](https://git.1814.love:8443/wx/HL/issues/5324)
- **PR**: [#5328](https://git.1814.love:8443/wx/HL/pulls/5328)
- **Merge commit**: [709105c1a1](https://git.1814.love:8443/wx/HL/commit/709105c1a1d26ae1c867fcc998286781f499faf2)

### 13.2 联系人

- **后端负责人**: @yst
- **前端负责人**: 待认领
