---
schema: "hl-changelog/v2"
ticket: "5654"
title: "修复应用到槽位丢价：批量逐日方案未传价日期按价格日历兜底"
consumer: "admin"
author: "wx"
change_type: "修改接口"
backend_status: "deployed"
gateway_status: "verified"
frontend_status: "not_required"
frontend_owner: ""
frontend_ref: ""
target_release: ""
verified_at: ""
status_note: "后端修复完成：PR #5659 合并 dev-v3（d39ef846e166861a836cc86308134d2da0bbca99）并部署 TEST；网关实证修复前 500 NPE、修复后应用到槽位成功且未传价日期按日历价兜底落库+排车表正常读取。前端无需改动（纯后端容错修复）。"
updated_at: "2026-08-07"
base: "dev-v3"
generated: "2026-08-07T18:10:00+08:00"
---

# 修复应用到槽位丢价（#5654）

## Bug

排车表选车弹窗候选带出本次价 ¥900（#5643 已修候选带出），但点「应用到槽位」后排车表该槽位「本次派车价」全 ¥0.00、「日历价」列"—"——价格没写入槽位。

## 根因

「应用到槽位」（统一选择车辆/司机→应用）走 `POST /admin/fleet/assignments/batch`（dailyPlan 逐日方案）：

1. `DailyPlanItem.assignmentPrice` 注释「used=true 时必填」但**无校验注解**，前端统一选择应用时不带价；
2. `flushDailyPlanSegment` 把 null 价原样包进 `dailyVehicleFees`；
3. `assertDailyFeeAdjustmentReasons` 对 null price 调 `compareTo` → **500 NullPointerException**（TEST 堆栈实证 `AssignmentService.java:2919`）；
4. 应用失败槽位无派车行 → 排车表读取兜底 ¥0/—。

## 修复（行为变化）

`POST /admin/fleet/assignments/batch`（dailyPlan 模式）：

- **未传价（assignmentPrice=null）的用车日期不再报错**，按「所选车辆车型 + 服务日」从价格日历兜底（与单体派单 `POST /assignments` 未传 protocolPrice 的口径一致）——修复前该场景 500 NPE。
- 未传价日期附带的单日调价原因被忽略（价格来自日历无调价）；显式传价且与日历价不一致的日期仍需调价原因（不变）。
- VO 注释对齐口径：`assignmentPrice` 可空=日历兜底；`used=false` 时仍必须为空。
- 防御：`assertDailyFeeAdjustmentReasons` 对 null 日价跳过（不再 NPE）。

## 验证

- AssignmentServiceTest **389/389**（新增 3：无价日不进覆盖集/全无价空覆盖集/null 价不 NPE 防御）；dev-v3 全量 verify 3259 项（唯一 Failure 为 releasee 进程时序 flaky，单跑 PASS，与本改动无关）。
- 网关实证（复现单 8/13-8/16 双槽位）：修复前不带价应用 → 500 NPE；修复后 → 200 成功，槽位 1（汉兰达不带价）4 天 holding `protocol_price=vehicle_fee_calendar_price=800`（日历兜底）AUTO，排车表 `dailyVehiclePlan` 返回 `calendarPrice=assignmentPrice=800、priceSource=CALENDAR`；槽位 0（GL8 带价 900）3600 AUTO 正常。
