---
schema: "hl-changelog/v2"
ticket: "6079"
title: "终止行程按勾选「未用」行释放房车资源——金额/释放双通道解耦，替代按日期截断"
consumer: "admin"
author: "wx"
change_type: "修改接口"
backend_status: "deployed"
gateway_status: "verified"
frontend_status: "verified"
frontend_owner: "mmg"
frontend_ref: "7ce54680"
target_release: ""
verified_at: "2026-08-19"
status_note: "后端完成：PR #6083 已合并 dev-v3（6c30bc50c9d1）并部署 TEST（hl-order-service-v3 双实例 16:24 滚动重启成功）。测试服端到端实测两单通过（勾未用释放/无释放行兼容）。目标单测 556 + ArchTest 44 + IT 101 全绿。"
updated_at: "2026-08-19"
base: "dev-v3"
generated: "2026-08-19T16:50:00+08:00"
---

# 终止行程按勾选「未用」行释放房车资源（#6079）

## ⚠️ 关键变化

- **以前**：终止行程的房车资源释放按 `endDayNumber` 日期截断——车侧把「出发日+(endDayNumber-1)」及之后的派单整段取消，房侧自动释放该日及之后的未确认候选库存。
- **现在**：释放完全由前端**逐行勾选的「未用」项**驱动。请求新增可选字段 `releaseLines`（与金额用的 `lineUsages` 完全独立、互不影响）：
  - **车**：`releaseLines` 里 `used=false` 的车行把 fleet 截断边界**提前到最早勾选未用车行的服务日**（fleet 协议上终止日终身唯一、做不到真正逐行，勾选只能把边界提前——请按「尾部连续段」勾选未用天）。不传/空 → 仍按 `endDayNumber` 日期截断（兼容）。
  - **房**：`releaseLines` 里 `used=false` 的房行按「哪晚哪间」精确释放未确认（INQUIRING）候选库存；**已确认（CONFIRMED）的房行即使勾了未用也不自动删**，由房务在异常桶手动处置。不传/空 → 不自动释放任何候选（旧按日期整段释放已下线）。
- **退款金额不变**：仍只按 `lineUsages[].used` 权威重算，与 `releaseLines` 无关；车行勾「未用」**不影响退款**（车辆退款按服务日权威判定），只影响资源释放。

## 变更接口

### `POST /v3/admin/order/{id}/terminate` 终止行程（出行中）

请求体新增可选字段（其余字段不变）：

| 字段 | 类型 | 必填 | 说明 |
|---|---|:---:|---|
| `releaseLines` | `List<LineUsageItem>` | ❌ | 资源释放行。只取 `used=false` 且 lineKey 前缀为 `VEHICLE_ASSIGNMENT:`/`HOTEL_ASSIGNMENT:` 的行驱动释放；其它来源行忽略。与 `lineUsages` 不做一致性比对。`lineKey` 取值与退款预览 `refundLines[].lineKey` 一致 |

`LineUsageItem` 结构：`{ "lineKey": "VEHICLE_ASSIGNMENT:348303531385688064:2", "used": false }`。

请求示例（勾第 2 天车未用 + 第 2 晚房未住）：

```json
{
  "cancelReason": "客户高反送医终止",
  "endDayNumber": 2,
  "lineUsages": [
    {"lineKey": "HOTEL_ASSIGNMENT:2089913001904680962:1", "used": true},
    {"lineKey": "HOTEL_ASSIGNMENT:2089913001917263874:2", "used": false}
  ],
  "releaseLines": [
    {"lineKey": "VEHICLE_ASSIGNMENT:348303531385688064:2", "used": false},
    {"lineKey": "HOTEL_ASSIGNMENT:2089913001917263874:2", "used": false}
  ]
}
```

## 前端动作

- 终止弹窗里「逐行勾选已用/未用」的房车行，**未用行同时放进 `lineUsages`（used=false，驱动退款）和 `releaseLines`（used=false，驱动释放）**；两个数组都要传，职责不同。
- 车辆未用天请按**尾部连续段**勾选（如 3 天行程勾第 2、3 天未用）；断档勾法（勾第 2 天不勾第 3 天）会把第 3 天也一并截断释放（fleet 协议限制，terminateDate 只能取最早未用日）。
- 房行勾「未住」的已确认（CONFIRMED）行不会自动释放——房务会在「异常桶」看到该终止需求 + REFUND 待办，手动取消未入住部分。

## 验证证据（测试服实测）

- 单测：目标套件 9 类 556 用例全绿（新增 TerminateReleasePlanParserTest 6 用例 + OrderServiceTest 真提前场景/事件透传/兼容回退 + HouseTodo/HouseAssignment 按行释放与 CONFIRMED 跳过计数）；ArchTest 44 绿；IT 101 跑 0 失败。CR Workflow 25 agents 对抗复核确认 2 个 P2 已收口。
- 实测 1（订单 HL20260819110439216，3 天行程当前第 2 天）：`endDayNumber=2` + `releaseLines` 勾车 day2/房 day2 未用 → 退款 6504 按 lineUsages 独立重算；fleet outbox `terminateDate=2026-08-19`（=day2 服务日，**边界提前生效**），day2/day3 派单 canceled、day1 保留 assigned；房侧需求转 EXCEPTION + 产 REFUND 待办，勾的 CONFIRMED 房行保留未删（`skippedConfirmed=1`，符合设计）。
- 实测 2（订单 HL20260819110313216，不传 releaseLines）：fleet 按 `endDayNumber=2` 日期截断（兼容路径），day2/day3 canceled；房侧不自动释放候选、需求转 EXCEPTION + REFUND 待办。
- 部署：PR #6083 squash 合并 dev-v3（merge 6c30bc50c9d1），Deploy Panel 滚动部署双实例 UP（8186/8086 均 16:24 重启健康）。

## 关联 / 联系人

- Issue：https://git.1814.love:8443/wx/HL/issues/6079
- PR：https://git.1814.love:8443/wx/HL/pulls/6083
- Commit（merge）：https://git.1814.love:8443/wx/HL/commit/6c30bc50c9d1
- 后端负责人：wx
