---
schema: "hl-changelog/v2"
ticket: "5636"
title: "对账vehicle-fee对齐核单重设计（补driverId必填+移除退款字段）"
consumer: "admin"
author: "wx(GIT)"
change_type: "修改接口"
backend_status: "deployed"
gateway_status: "verified"
frontend_status: "implemented"
frontend_owner: "mmg"
frontend_ref: "hl-admin@d897c3d4fc31932dd351e99f1911144314e2cc2f"
target_release: ""
verified_at: ""
status_note: "后端完成：PR #5641 已合并 dev-v3 并部署 TEST（hl-fleet-service + hl-order-service-v3 双实例）。网关验证通过（对账车辆费用查询接口正常返回，响应已不含 refund 字段）。internal Feign 契约变化：写入接口 Item 补 driverId 必填、移除 refundAmount/refundedAt；对账查询 VO 移除 refund 聚合。"
updated_at: "2026-08-07"
base: "dev-v3"
generated: "2026-08-07T14:00:00+08:00"
---

# 对账 vehicle-fee 对齐核单重设计（补 driverId 必填 + 移除退款字段）

> 后端完成：PR #5641 已合并 dev-v3 并部署 TEST，网关验证通过。

## 关联 / 联系人

### 链接

- **Issue**: [#5636](https://git.1814.love:8443/wx/HL/issues/5636)
- **PR**: [#5641](https://git.1814.love:8443/wx/HL/pulls/5641)
- **Merge commit**: [d0e976f9e](https://git.1814.love:8443/wx/HL/commit/d0e976f9e)

### 联系人

- **后端负责人**: @wx

## 背景

#5610 已实现 `POST /internal/fleet/reconciliation/vehicle-fee`（核单完毕写入对账车辆实际费用），但参数与核单重设计（hl-backend-changelog 06_5597）不一致：

| 项 | 设计要求 | 修复前实现 |
|----|---------|-----------|
| driverId | **必填**（对账按司机关联） | **缺失**（只有 driverName） |
| refundAmount/refundedAt | **不含**（核单无退款） | **多了**（核单无退款数据，字段恒空） |
| vehicleId | fleet 侧按派单（司机+日期）关联 | order 透传 |

## 口径（wx 定）

- **driverId 由核单传**（核单按司机算钱天然携带）
- **vehicleId 由 fleet 侧按派单（司机+日期）从 `fleet_assignment` 关联**（核单可不传）
- **无 refundAmount/refundedAt**（核单无退款数据；退款归支付/退款模块）

## 方案

1. **写入契约** `SettlementVehicleFeeWriteDTO.Item`：补 `driverId`（`@NotNull` 必填）；移除 `refundAmount`/`refundedAt`
2. **表 `fleet_reconciliation_vehicle_fee`**：migration `V20260807_001` 加 `driver_id` 列 + `idx_driver_service_date` 索引，删 `refund_amount`/`refunded_at` 列（H2 兼容：单动作 ALTER / CREATE INDEX，不带 AFTER）
3. **写入 Service**：`driverId` 必填校验（缺失 → 605610）；`vehicleId` item 未传时按派单反查 `fleet_assignment.vehicle_id` 关联填入；`driverName` 快照缺失时按派单反查补全
4. **对账查询**：移除 refund 聚合（`ReconCarsVehicleVO.refundAmount` / `ReconCarsFleetVO.refundTotal` / `ReconCarsGrandTotalVO.refundTotal` + `ReconciliationQueryService` 三处聚合）
5. **order 侧 publisher**：`buildItems` 透传核单冻结行 `line.driverId()`；移除「终止退款挂首行」逻辑

## 变更接口

| 方法 | 路径 | 服务 | 说明 |
|---|---|---|---|
| POST | `/internal/fleet/reconciliation/vehicle-fee` | hl-fleet-service | **internal Feign 契约**：Item 补 `driverId`（必填），移除 `refundAmount`/`refundedAt` |
| GET | `/admin/fleet/reconciliation/cars` | hl-fleet-service | 响应 VO 移除 `refundTotal`（车队/总计）与 `refundAmount`（车辆明细）字段 |

**契约变化**：
- internal 写入接口（order-v3 → fleet，Feign 直连不经网关）：请求 Item **新增必填 `driverId`**、**删除 `refundAmount`/`refundedAt`**。order 侧 publisher 同 PR 同步改造，双侧一并部署，无跨版本兼容窗口。
- 对账查询接口（管理后台）：响应**删除 refund 相关字段**（`grandTotal.refundTotal`、`fleets[].refundTotal`、`fleets[].vehicles[].refundAmount`）。核单无退款数据，这些字段恒为 0/null，删除不影响实际口径。

## 行为变化

- 核单完毕写入对账车辆费用时，每条明细必须携带 `driverId`（核单按司机算钱天然有）；缺失返回 `code=605610`
- 对账「实际结算」列数据源不变（仍读 `SUM(actual_amount)`）；退款相关展示字段从响应移除
- 既有 `#5610` 期间写入的历史行若无 `driver_id`，随重核覆盖写自然补全

## 前端/调用方动作

- **管理后台对账页**：若引用了对账车辆费用响应的 `refundTotal`/`refundAmount` 字段，需移除相关展示（核单无退款，这些字段恒空）。「实际结算」列数据源不变。
- internal 写入接口由 order-v3 内部 Feign 调用，双侧同 PR 同步改造并一并部署，前端无感知。

## 验证证据

- **测试**：fleet reconciliation 38/38（VehicleFeeService 10 含新增 driverId 必填/vehicleId 派单关联用例 + Query 11 + Period 17）；order publisher 4/4（含 driverId 透传用例）+ outbox 26/26 + InternalRequirement 17/17；fleet spotless:check 通过
- **fleet verify**：3243 例，仅 ReleaseE 8033（需 MySQL 8.0.33 环境）+ MixedBinaryHarness 偶发——基线已知失败，与本案无关
- **order-v3 verify**：LayerEnforcement/RedLineArch 转绿（顺带修复 #5603 引入的 Controller→DO ArchUnit 违规）；剩余 7 失败 + 95 errors 全为 Testcontainers/MySQL schema 基线失败（`order_settlement_summary` 缺表等），与 vehicle-fee driverId 无关
- **部署**：hl-fleet-service + hl-order-service-v3 双实例滚动部署 UP（13:53-13:55）
- **网关验证**：VEHICLE_MANAGER 调 `GET /admin/fleet/reconciliation/cars` → 200，`grandTotal` 仅含 `actual/diff/estimated/payable/totalDays/totalOrderCount`，已无 `refundTotal`；CUSTOMIZER 调 → 403（#5626 门禁生效）
