---
schema: "hl-changelog/v2"
ticket: "5676"
title: "改派支持按天改派（排车表逐行改派按钮）+ 统一选择修复交接"
consumer: "admin"
author: "wx"
change_type: "修改接口"
backend_status: "deployed"
gateway_status: "verified"
frontend_status: "implemented"
frontend_owner: "mmg"
frontend_ref: "3df533a5"
target_release: ""
verified_at: ""
status_note: "后端完成：PR #5686 合并 dev-v3（4e993920440cad0b6105a5f7682d6b33d1444bad）并部署 TEST，网关验证按天改派只改指定天+统一选择单次全改均通过。统一选择「只改第一天」bug 实证为前端逐日循环互覆盖（后端无 bug），修复=前端改单次调 change。待前端接入按天改派+统一选择单次调用。"
updated_at: "2026-08-08"
base: "dev-v3"
generated: "2026-08-08T11:10:00+08:00"
---

# 改派支持按天改派 + 统一选择修复交接（#5676）

## 需求

1. 排车表**每行（每个服务日）**有【改派】按钮——单独改某天的车/司机（按天改派，每天可不同）
2. 统一选择按钮=整体改派（所有日期），保留
3. wx 实测补充：统一选择**现在不好使，只能改第一天**（选的车/司机只应用到第一天）

## 统一选择「只改第一天」bug 根因（后端无 bug，前端修复）

**根因 = 前端「统一选择」逐日循环调 change 互相覆盖**，非后端问题：

- 改派操作日志实证：order `2080600006514872322` 在 2026-08-06 17:25 对同一槽位**连续两次调 change**（`effectiveDate=2026-08-29` 和 `2026-08-28` 分开、每天一行）——前端对「统一选择」**逐日循环**（每天调一次）。
- change 语义 = **「effectiveDate 起连续后缀」**：eff=8/29 改 8/29 起后缀，eff=8/28 又改 8/28 起后缀（覆盖 8/29）…… 逐日循环互相覆盖 → 只有部分天生效（表现为「只改第一天」）。
- **后端单次 change 正确全改**：单测证明逐日槽位 3 天，单次 `change(effectiveDate=第一天, 不传 serviceDates)` → 取消整段后缀 + 重建 3 行全新车/司机。

## 修改接口：`POST /admin/fleet/assignments/{assignmentId}/change`

新增**可选**字段 `serviceDates`（`List<LocalDate>`，其余字段不变）：

| 字段 | 说明 |
|---|---|
| `serviceDates` | **按天改派限定的服务日期集**。非空=按天改派模式：只改这些日期的行（其余天保留）；**空/不传=现状**（effectiveDate 起连续后缀整体改派）。 |

### 前端交接（两种改派的正确调用方式）

**1. 统一选择（整体改派）——修复点**：
```json
{
  "effectiveDate": "<第一天>",
  "newVehicleId": ..., "newDriverId": ...,
  "holdMode": 0, "reason": "...", "requestId": "<唯一>"
}
```
- **单次调用**，`effectiveDate`=第一天，**不传 `serviceDates`** → 一次整体改派所有天。
- **不要再逐日循环调 change**（会互相覆盖）。
- 每次操作生成唯一 `requestId`（幂等）。

**2. 按天改派（新增，每行改派按钮）**：
```json
{
  "effectiveDate": "<该天>",
  "serviceDates": ["<该天>"],
  "newVehicleId": ..., "newDriverId": ...,
  "holdMode": 0, "reason": "...", "requestId": "<唯一>"
}
```
- 某天【改派】→ `effectiveDate`=该天 + `serviceDates=[该天]` → **只改该天，其他天不变**。
- 每天可不同车/司机（逐行各调一次，每天独立 `requestId`）。
- `assignmentId` 路径参数=该槽位任一派单行 ID。

### 行为说明

- **校验按天**：按天改派的档期/占用/常驻/保险校验只针对 `serviceDates` 指定的天（某天换车/司机只需该天资源空闲，不影响其他天）。
- **逐日价格**：按天改派后逐日车费按各天价格日历/车型分别算（`resolveDaily` 按子集日期逐日取价）。
- **兼容**：`serviceDates` 不传时行为与现状完全一致（统一选择整体改派）。

## 验证

- AssignmentServiceTest **397/397**（新增 3：按天单天只改该天/按天非连续子集其余保留/统一选择单次全改对照）；dev-v3 全量 verify 3273/0F/0E。
- 网关实证（TEST，槽位 `344052387587166208`，order `2085662570479304706`，8/21-8/23 三天）：
  - **按天改派**：`change(serviceDates=[8/22])` 换车 → 只 8/22 变，8/21/8/23 保留原车；
  - **统一选择单次**：`change(effectiveDate=8/21, 不传 serviceDates)` 换车 → 3 天全改。
