---
schema: "hl-changelog/v2"
ticket: "5567"
title: "历史终止订单车辆核单空态"
consumer: "admin"
change_type: "修改接口"
author: "yst(GIT)"
backend_status: "pending"
gateway_status: "pending"
frontend_status: "implemented"
frontend_owner: "pi-main-session"
frontend_ref: "hl-admin@4a2dcc8e20fe23ffc2b3d35ae8f02e62661b642d"
target_release: "v2.1"
verified_at: "2026-08-06"
status_note: "PR #5570 已合并 dev-v3；运行时行为尚未验证，管理后台待适配新增阻断枚举。"
updated_at: "2026-08-06"
base: "dev-v3"
---

# 🔧【修改接口·管理后台】历史终止订单车辆核单空态 (#5567)

> **PR**：[#5570](https://git.1814.love:8443/wx/HL/pulls/5570) ｜ **服务**：`hl-order-service-v3` ｜ **更新时间**：2026-08-06 ｜ **消费端**：管理后台

## 1. 接口背景

部分历史终止订单只有旧版车辆费用记录，无法还原为当前车辆核单的权威金额。此类订单只需要安全展示为“缺少权威车辆费用来源、不可完成核单”，不应把它当作车务临时故障，也不得把未知金额当成 0 元已确认。

## 2. 变更清单

| # | 接口名 | 方法 | 路径 | 变更类型 | 说明 |
|---|---|---|---|---|---|
| 1 | 查询车辆核单草稿 | `GET` | `/v3/admin/order/{orderId}/settlement/step3/vehicles` | 修改 | `blockReasonCode` 新增 `LEGACY_VEHICLE_FEE_SOURCE_MISSING`；严格历史终止 LEGACY 场景由 `584100` 改为 `code=200` 的安全阻塞空态 |

## 3. 接口详情

### 3.1 查询车辆核单草稿

- **接口说明**：查询车辆 Tab 当前全量明细、草稿版本、确认状态，以及车辆费用是否具备完成核单条件。
- **使用场景**：进入管理后台订单核单的车辆 Tab 或刷新车辆核单状态。
- **认证**：需要管理后台登录态和订单查看权限；房务角色不可访问。
- **幂等性**：是，只读查询。
- **限流**：未声明接口级独立限流规则。

## 4. 接口入参

### 4.1 路径参数 / Query 参数

| 字段 | 位置 | 类型 | 必填 | 说明与校验 |
|---|---|---|---|---|
| `orderId` | Path | String(Long) | 是 | 订单 ID，必须为正整数；按字符串传递，避免大整数精度损失 |

无 Query 参数。

### 4.2 请求体字段

GET 请求无请求体。

## 5. 出参字段

响应类型：`Result<SettlementVehicleFeesRespVO>`。

### 5.1 统一响应外层

| 字段 | 类型 | 可空 | 说明 |
|---|---|---|---|
| `code` | Integer | 否 | 成功为 `200`；失败见 §7 |
| `message` | String | 否 | 结果说明 |
| `data` | VehicleDraft/null | 失败时为空 | 成功时为车辆核单草稿 |
| `traceId` | String | 是 | 链路追踪 ID |
| `success` | Boolean | 否 | `code=200` 时为 `true` |

### 5.2 成功响应 `data`

| 字段 | 类型 | 可空 | 说明 |
|---|---|---|---|
| `orderId` | String(Long) | 否 | 订单 ID，按字符串返回 |
| `version` | Long | 否 | 当前车辆核单草稿版本；安全阻塞空态为 `0` |
| `totalAmount` | Decimal/null | 是 | 当前明细总金额；`LEGACY_VEHICLE_FEE_SOURCE_MISSING` 时必须为 `null`，表示金额未知，不是 `0.00` |
| `allConfirmed` | Boolean | 否 | 非空明细是否全部确认；LEGACY 安全阻塞空态固定为 `false` |
| `settlementReady` | Boolean | 否 | 车辆费用是否具备完成核单条件；LEGACY 安全阻塞空态固定为 `false` |
| `blockReasonCode` | String/null | 是 | 不具备条件时的机器可读原因，完整取值见 §6；具备条件时为 `null` |
| `items` | VehicleItem[] | 否 | 当前全量明细；LEGACY 安全阻塞空态固定为 `[]` |

### 5.3 `data.items[]`

| 字段 | 类型 | 可空 | 说明 |
|---|---|---|---|
| `id` | String(Long) | 否 | 车辆核单明细 ID |
| `sourceType` | String | 否 | 来源类型：`FLEET` 或 `MANUAL` |
| `sourceTypeName` | String | 否 | 来源名称：车务或手工 |
| `serviceDate` | String(date) | 否 | 服务日期，格式 `YYYY-MM-DD` |
| `vehicleId` | String(Long) | 是 | 车辆 ID |
| `vehiclePlate` | String | 是 | 车牌号 |
| `vehicleModelId` | String(Long) | 是 | 车型 ID |
| `vehicleModelName` | String | 是 | 车型名称 |
| `driverId` | String(Long) | 是 | 司机 ID |
| `driverName` | String | 是 | 司机姓名 |
| `amount` | Decimal | 否 | 核单金额 |
| `paymentMethod` | String | 否 | 付款方式编码 |
| `paymentMethodName` | String | 否 | 付款方式名称 |
| `settlementConfirmStatus` | String | 否 | 确认状态编码：`UNCONFIRMED` 或 `CONFIRMED` |
| `settlementConfirmStatusName` | String | 否 | 确认状态名称：未确认或已确认 |
| `remark` | String | 是 | 备注 |
| `voucherUrls` | String[] | 否 | 凭证 URL；无凭证时为 `[]` |

## 6. 枚举 / 数据字典

### 6.1 `blockReasonCode`

**所属字段**：`data.blockReasonCode` ｜ **类型**：String/null ｜ **可空**：是

| 值 | 中文 | 说明 |
|---|---|---|
| `VEHICLE_FEE_NOT_READY` | 车辆费用尚未就绪 | 有当前用车需求，但尚无可返回的车辆费用明细；`settlementReady=false`、`totalAmount=0.00`、`allConfirmed=false`、`items=[]` |
| `LEGACY_VEHICLE_FEE_SOURCE_MISSING` | 历史车辆费用权威来源缺失 | 历史终止 LEGACY 场景无法确认权威车辆金额；`settlementReady=false`、`totalAmount=null`、`allConfirmed=false`、`items=[]` |
| `null` | 无阻断原因 | 车辆费用来源已就绪；为 JSON 空值，不是字符串 `"null"` |

### 6.2 `items[].sourceType`

| 值 | 中文 | 说明 |
|---|---|---|
| `FLEET` | 车务 | 车务来源的车辆核单明细 |
| `MANUAL` | 手工 | 管理后台手工维护的车辆核单明细 |

### 6.3 `items[].paymentMethod`

| 值 | 中文 | 说明 |
|---|---|---|
| `CASH_PAID` | 现金已付 | 现金支付 |
| `SIGNED` | 签单 | 按签单方式结算 |
| `COMPANY_PAID` | 公司付款 | 由公司支付 |

### 6.4 `items[].settlementConfirmStatus`

| 值 | 中文 | 说明 |
|---|---|---|
| `UNCONFIRMED` | 未确认 | 当前车辆费用行尚未完成核单确认 |
| `CONFIRMED` | 已确认 | 当前车辆费用行已完成核单确认 |

## 7. 错误码

| code | 含义 | 触发场景 |
|---|---|---|
| `200` | 查询成功 | 包括历史终止 LEGACY 安全阻塞空态；此时以 `settlementReady` 和 `blockReasonCode` 判断是否可继续 |
| `400` | 请求参数错误 | `orderId` 不是正整数 |
| `403` | 无访问权限 | 登录态、角色或权限不允许访问 |
| `581007` | 订单不存在 | `orderId` 对应订单不存在 |
| `584071` | 无权访问该订单 | 当前账号不在订单可访问范围内 |
| `584100` | 车辆费用暂时不可用 | 真实车辆快照损坏、依赖故障、响应身份不匹配或必要字段无效；本次不把这些故障转换为空态 |
| `584101` | 车辆费用尚未满足核单条件 | 已有非空车辆明细，但来源未完结或费用条件未满足 |

## 8. 示例

### 8.1 典型成功：历史终止 LEGACY 安全阻塞空态

**请求**：

```http
GET /v3/admin/order/9223372036854775000/settlement/step3/vehicles
Authorization: Bearer <管理后台访问令牌>
```

无请求体。

**响应**：

```json
{
  "code": 200,
  "message": "成功",
  "data": {
    "orderId": "9223372036854775000",
    "version": 0,
    "totalAmount": null,
    "allConfirmed": false,
    "settlementReady": false,
    "blockReasonCode": "LEGACY_VEHICLE_FEE_SOURCE_MISSING",
    "items": []
  },
  "traceId": null,
  "success": true
}
```

### 8.2 边界情况：无当前用车需求

**场景说明**：该场景同样返回空数组，但它是合法可继续状态，金额为真实的 `0.00`，与历史 LEGACY 金额未知完全不同。

**请求**：

```http
GET /v3/admin/order/900000000002/settlement/step3/vehicles
Authorization: Bearer <管理后台访问令牌>
```

无请求体。

**响应**：

```json
{
  "code": 200,
  "message": "成功",
  "data": {
    "orderId": "900000000002",
    "version": 0,
    "totalAmount": 0.00,
    "allConfirmed": true,
    "settlementReady": true,
    "blockReasonCode": null,
    "items": []
  },
  "traceId": null,
  "success": true
}
```

### 8.3 业务失败：真实车辆快照损坏或依赖故障

**请求**：

```http
GET /v3/admin/order/900000000004/settlement/step3/vehicles
Authorization: Bearer <管理后台访问令牌>
```

无请求体。

**响应**：

```json
{
  "code": 584100,
  "message": "车务车辆总车费暂时不可用，请稍后重试",
  "data": null,
  "traceId": null,
  "success": false
}
```

## 9. 业务边界

- **适用场景**：仅当订单属于历史终止场景，并被判定为缺少当前权威车辆费用来源的 LEGACY 数据时，返回 `code=200` 和 `LEGACY_VEHICLE_FEE_SOURCE_MISSING`。
- **不可放行**：该安全空态固定为 `totalAmount=null`、`allConfirmed=false`、`settlementReady=false`、`items=[]`。金额是未知，不得转成 `0`，也不得按“0 元且已确认”处理。
- **判断顺序**：先检查 `settlementReady`，再读取 `blockReasonCode`；不能仅凭 `code=200`、`items=[]` 或 `version=0` 判断可完成核单。
- **故障边界**：真实车辆快照损坏、依赖故障、响应身份不匹配或必要字段无效仍可返回 `584100`，不伪装为 LEGACY 安全空态。
- **其他订单**：非历史终止 LEGACY 场景沿用原有车辆核单成功、未就绪或失败契约。

## 10. 修改前后对比

### 10.1 字段级对比

| 字段 | 原来 | 现在 |
|---|---|---|
| `data.blockReasonCode` | `VEHICLE_FEE_NOT_READY` 或 `null` | 新增 `LEGACY_VEHICLE_FEE_SOURCE_MISSING` |
| LEGACY 空态 `data.totalAmount` | 无成功响应字段值 | `null`，明确表示金额未知 |
| LEGACY 空态 `data.allConfirmed` | 无成功响应字段值 | `false` |
| LEGACY 空态 `data.settlementReady` | 无成功响应字段值 | `false` |
| LEGACY 空态 `data.items` | 无成功响应字段值 | `[]` |

### 10.2 行为级对比

| 行为 | 原来 | 现在 |
|---|---|---|
| 历史终止 LEGACY 数据缺少权威车辆费用来源 | 返回 `code=584100`“车务车辆总车费暂时不可用” | 返回 `code=200` 的安全阻塞空态，`blockReasonCode=LEGACY_VEHICLE_FEE_SOURCE_MISSING` |
| 真实车辆快照损坏或依赖故障 | 返回 `584100` | 仍可返回 `584100`，行为不变 |

## 11. 影响评估 / 回滚

### 11.1 影响评估

- **是否破坏向后兼容**：响应字段结构不变，枚举为新增值；但历史终止 LEGACY 场景由失败响应改为成功阻塞响应，依赖捕获 `584100` 的旧控制流需要适配。
- **前端是否必须同步上线**：需要识别新增枚举值，并按 `settlementReady=false` 保持阻塞；不得把 `totalAmount=null` 转成 0 或把空数组视为已确认。

### 11.2 回滚方案

- 若接口行为回滚，历史终止 LEGACY 场景会恢复为 `584100`；前端应同时兼容该错误码和本次新增的安全阻塞空态，避免回滚期间误放行。

## 12. 注意事项

- `totalAmount=null` 表示无法确认权威金额；`0.00` 才表示确定为 0 元，两者不可互换。
- `items=[]` 不代表车辆核单已完成；必须同时读取 `settlementReady` 和 `allConfirmed`。
- `LEGACY_VEHICLE_FEE_SOURCE_MISSING` 是机器可读阻断原因，不是车务临时不可用的别名。
- 不要清除对 `584100` 的失败处理：真实快照损坏和依赖故障仍可能返回该错误码。

## 13. 关联 / 联系人

### 13.1 链接

- **Issue**：[#5567](https://git.1814.love:8443/wx/HL/issues/5567)
- **PR**：[#5570](https://git.1814.love:8443/wx/HL/pulls/5570)
- **Merge commit**：[fbc42f31b173](https://git.1814.love:8443/wx/HL/commit/fbc42f31b17301b078a9b63c3c064eb983807f79)

### 13.2 联系人

- **后端负责人**：@yst / yaosutu
- **前端消费方**：管理后台车辆核单 Tab
