文件
hl-api-changelog/changelogs-v2/2026-09/16_7767_团车户与免车团户可终止行程-修改接口-管理后台.md
T
2026-09-17 09:17:58 +08:00

435 行
13 KiB
Markdown
原始文件 Blame 文件历史

此文件含有模棱两可的 Unicode 字符
此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。
---
schema: "hl-changelog/v2"
ticket: "7767"
title: "团车户与免车团户可终止行程,终止车费投影认可团车与整团免车"
consumer: "admin"
author: "wx(GIT)"
change_type: "修改接口"
backend_status: "deployed"
gateway_status: "verified"
frontend_status: "not_required"
frontend_owner: ""
frontend_ref: ""
target_release: ""
verified_at: ""
status_note: "仅后端交付。新增错误码 584132 与修改的 584100 文案在源码与 API-SPEC 已核对;测试服验证见工单 #7767 验收评论。前端需补错误码 584132 的提示文案映射,误将两码混用则会给出不恰当的稍后重试建议。;前端 hl-admin a2a4e2dd 已实现:terminateRefund.js 补 584132 提示(等车务配车完成后再试)与 584100(稍后重试)语义区分,api docstring 同步,spec +1,checkpoint 全绿。重开增补(2026-09-17 mmg):not_required——前端调用本就是勘误后真实路径 /terminate/refund-preview 与 /terminate;adjustAmount 人工调整额输入框已有(MidTripRefundModal);团车户预览 vehicles=[] 前端空安全渲染;/transition eventCode=TERMINATE 无前端调用方。"
updated_at: "2026-09-16"
base: "dev-v3"
---
# order-v3: 团车户与免车团户可终止行程
> **存放目录**: changelogs-v2/{YYYY-MM}/(管理后台,二期 order-v3)
>
> **服务**: hl-order-service-v3 (端口 8083)
> **PR**: #7789
> **Issue**: #7767
> **日期**: 2026-09-16
> **影响范围**: 终止行程接口新增错误码 584132;错误码 584100 文案修改,收窄适用场景
---
## 关键变化
1. **原本终止行程对团级配车户(GROUP_VEHICLE)和整团免车户恒返 584100**——该两类户现已可成功终止。
2. **新增错误码 584132**:用于"用车需求未完成"场景,与 584100"车费暂时不可用"语义分开。前端**必须区别对待**两个错误码:
- `584132` → "等车务配车完成后再试"(需催车务处理)
- `584100` → "暂时不可用,请稍后重试"(快照异常,应自己好转)
3. **团车户车费按 0 计、调整用 adjustAmount**:团车户(GROUP_VEHICLE)用车由团级承担,在该户的终止预览中 vehicles=[],退款明细中无 VEHICLE 行。若运营需向该户扣回团车成本,通过 `POST /terminate` 的 `adjustAmount` 参数调整(负数表示减免)。实测:订单 `2100132795681525761` 团车户,`finalRefund = max(0, 2000 − 176 + 0) = 1824`
---
## 一、背景
#7441 新增了团级正式用车需求声明的端点,其后 #7445 给定制师逐户所报的用车需求引入"就绪状态"检查(DAILY_V3 契约版本)。此前团车户与免车户因为 assignment_contract_version 判据不满足而永久卡死在 584100 错误,无法终止。本次放行这两类户,同时将终止失败分成两个语义明确的错误码。
---
## 二、变更接口清单
| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|---|------|------|------|----------|------|
| 1 | 终止行程·退款预览 | POST | `/v3/admin/order/{id}/terminate/refund-preview` | 修改 | 新增错误码 584132;修改 584100 文案与适用范围 |
| 2 | 终止行程 | POST | `/v3/admin/order/{id}/terminate` | 修改 | 新增错误码 584132;修改 584100 文案与适用范围 |
| 3 | 状态变更(通用) | POST | `/v3/admin/order/{id}/transition` | 修改 | 当 eventCode=TERMINATE 时同样触发上述两个错误码 |
---
## 三、接口详情
### 1. 终止行程·退款预览 `POST /v3/admin/order/{id}/terminate/refund-preview`
**VO**: `(路径参数 → OrderTerminateRefundPreviewRespVO)`
#### 使用场景
出行中点击"终止行程"时的前置预览,展示本单若干今日已用、剩余天数、应退金额等。预览过程不做任何写入,失败也不影响后续正式终止接口调用。
#### 入参字段表
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|------|------|------|------|------|------|
| id | Path | Long | 是 | - | 订单 ID |
#### 出参字段表
| 字段 | 类型 | 说明 |
|------|------|------|
| id | Long | 订单 ID |
| orderNo | String | 订单号 |
| usedDays | Integer | 已用天数(截至今日) |
| remainingDays | Integer | 剩余天数(今日之后) |
| refundAmount | BigDecimal | 应退总金额(含车费、房费等) |
| vehicleFeeRefund | BigDecimal | 车费应退(拆分显示,供前端按业务决策) |
| houseFeeRefund | BigDecimal | 房费应退 |
#### 请求示例
```json
GET /v3/admin/order/1934567890123456789/terminate-refund/preview
```
#### 响应示例
```json
{
"code": 200,
"message": "成功",
"data": {
"id": 1934567890123456789,
"orderNo": "26-0503",
"usedDays": 2,
"remainingDays": 4,
"refundAmount": "8000.00",
"vehicleFeeRefund": "3200.00",
"houseFeeRefund": "4800.00"
},
"success": true
}
```
#### 空数据 / 降级响应
本接口无空数据场景(订单存在即可预览)。
#### 错误响应
```json
{
"code": 584100,
"message": "车务车辆总车费暂时不可用,请稍后重试",
"success": false,
"data": null
}
```
```json
{
"code": 584132,
"message": "用车需求未完成,暂不能终止行程,请等车务配车完成后再试",
"success": false,
"data": null
}
```
#### 错误响应
```json
{
"code": 581001,
"message": "订单不存在",
"success": false,
"data": null
}
```
```json
{
"code": 583301,
"message": "订单状态不允许此操作",
"success": false,
"data": null
}
```
#### 业务边界
- **鉴权**: 需 admin 权限,团期户与散客户均支持
- **状态机**: 仅 TRAVELLING/TRANSFER 状态订单可预览,其他状态拒绝(401)
- **幂等**: 无写入,重复调用返回一致结果
- **零副作用**: 预览失败不作用任何表与缓存,安全重试
- **旧数据兼容**: refundAmount 等字段在快照 JSON 损毁时可能为 null,前端需判空
---
### 2. 终止行程 `POST /v3/admin/order/{id}/terminate`
**VO**: `OrderTerminateTripReqVO → OrderTerminateTripRespVO`
#### 使用场景
出行中因特殊原因(天气、医疗等)提前终止订单,订单进入 COMPLETED 状态。结算与房车资源释放在终止之后由结算流程异步处理。
#### 入参字段表
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|------|------|------|------|------|------|
| id | Path | Long | 是 | - | 订单 ID |
| cancelReason | Body | String | 是 | ≤500 字符 | 终止原因(运营内部备注) |
| endDayNumber | Body | Integer | 是 | 1 ≤ dayNumber ≤ 行程天数 | 终止日在行程中的序号(Day 1、Day 2 等) |
| adjustAmount | Body | BigDecimal | 否 | 任意 | 人工调整额(默认 0,负数表示减免;用于团车户向其扣回团车成本) |
| vehicles | Body | List | 否 | - | 旧客户端兼容字段,新客户端可不传 |
#### 出参字段表
| 字段 | 类型 | 说明 |
|------|------|------|
| id | Long | 订单 ID |
| orderNo | String | 订单号 |
| status | String | 订单状态(转移为 COMPLETED) |
| terminateRefundRecord | Object | 退款记录快照 |
| terminateRefundRecord.refundAmount | BigDecimal | 实退总金额 |
| terminateRefundRecord.createdAt | LocalDateTime | 记录时刻 |
#### 请求示例
```json
{
"cancelReason": "客户身体不适,需提前返程",
"endDayNumber": 3
}
```
#### 响应示例
```json
{
"code": 200,
"message": "成功",
"data": {
"id": 1934567890123456789,
"orderNo": "26-0503",
"status": "COMPLETED",
"terminateRefundRecord": {
"refundAmount": "8000.00",
"createdAt": "2026-09-16T14:30:00"
}
},
"success": true
}
```
#### 空数据 / 降级响应
本接口无空数据场景。
#### 错误响应
```json
{
"code": 584132,
"message": "用车需求未完成,暂不能终止行程,请等车务配车完成后再试",
"success": false,
"data": null
}
```
```json
{
"code": 584100,
"message": "车务车辆总车费暂时不可用,请稍后重试",
"success": false,
"data": null
}
```
#### 业务边界
- **鉴权**: 需 admin 权限
- **状态机**: 仅 TRAVELLING 状态可终止
- **幂等**: 同一订单同一 endDayNumber 重复终止返 581049(已终止)
- **团车户与免车户放行**: 现已支持,按 DAILY_V3 规则正常处理
- **adjustAmount 用途**:系统计算 baselineRefund 后,运营可通过该参数人工调整;finalRefund = max(0, baselineRefund + adjustAmount)。团车户成本扣减常用负值,如 adjustAmount = -300 表示减免 300 元
- **团车户退款细节**:用车行置空(vehicles=[]),退款明细无 VEHICLE 行,但其他资源行(房费、保险等)仍正常计算
### 3. 状态变更·通用 `POST /v3/admin/order/{id}/transition`
**VO**: `OrderTransitionReqVO → OrderTransitionRespVO`
#### 使用场景
通用状态机触发端点。当 `eventCode=TERMINATE` 时等价于调用终止接口,触发同样的错误码 584132/584100。
#### 入参字段表
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|------|------|------|------|------|------|
| id | Path | Long | ✅ | - | 订单ID |
| eventCode | Body | String | ✅ | - | 事件码(本变更涉及 TERMINATE) |
#### 出参字段表
| 字段 | 类型 | 说明 |
|------|------|------|
| success | Boolean | 是否成功 |
| oldStatus | String | 变更前粗状态 |
| newStatus | String | 变更后粗状态 |
#### 请求示例
```json
{
"eventCode": "TERMINATE",
"comment": "客户提前返程"
}
```
#### 响应示例
```json
{
"code": 200,
"message": "成功",
"data": {
"success": true,
"oldStatus": "TRAVELLING",
"newStatus": "COMPLETED"
},
"success": true
}
```
#### 空数据 / 降级响应
无。
#### 错误响应
```json
{
"code": 584132,
"message": "用车需求未完成,暂不能终止行程,请等车务配车完成后再试",
"success": false
}
```
```json
{
"code": 584100,
"message": "车务车辆总车费暂时不可用,请稍后重试",
"success": false
}
```
#### 业务边界
- **eventCode=TERMINATE**:触发终止行程逻辑,返回同样的错误码 584132/584100
- **失败回滚**:状态变更失败时不落库,可安全重试
---
## 四、契约约束与正确调用方式
| 场景 | 做法 |
|------|------|
| 出行中 Day 3 终止 | 先预览、再提交,endDayNumber=3 |
| 重复终止(幂等) | 同一订单同 endDayNumber 重复 POST,返 200 或 581049 |
| 错误码 584132 | "等车务配车完成",需催车务处理 |
| 错误码 584100 | "暂时不可用",稍后重试 |
---
## 五、数据库行为
| 操作 | order_main.order_status | order_terminate_refund | 房车资源释放 |
|------|---------------------------|---------------------------|------------|
| 终止成功 | TRAVELLING → COMPLETED | INSERT 一行 | 异步触发 |
| 终止失败 | 无变更 | 无新增 | 无 |
---
## 六、边界行为
- **未登录** → 401
- **无权限** → 403
- **订单不存在** → 404
- **状态非 TRAVELLING** → 583301
- **结束日越界** → 581047
- **车费快照异常** → 584100
- **用车需求未配车** → 584132
---
## 六.5、枚举
### 订单状态 (status 字段)
**所属字段**: OrderTerminateTripRespVO.status | **类型**: String
| 值 | 中文 | 说明 |
|----|------|------|
| TRAVELLING | 出行中 | 使用终止接口前的状态 |
| COMPLETED | 已完成 | 终止成功后的状态 |
---
## 六.6、修改前后对比
### 错误码对比
| 错误码 | 改前 | 改后 |
|--------|------|------|
| 584100 | 对所有车费投影缺失的户统一返回 | 收窄为仅覆盖 DAILY_V3 契约版本但快照未就绪的户 |
| 584132 | 不存在 | 新增,覆盖非 DAILY_V3 且未配车的户 |
---
## 六.7、影响评估
- **是否破坏向后兼容**: 是(团车户和免车户原本失败,现已成功)
- **前端是否必须同步上线**: 是(需处理新错误码 584132)
- **前端 workaround 清理点**: 删除硬编码的"团车户无法终止"逻辑
---
## 七、不影响范围
- **仅影响**: 管理后台出行中订单的终止功能
- **零影响**:
- C 端应用
- 其他状态订单的操作
- 房费结算
- 用车需求声明等其他模块
---
## 八、测试环境已验证
```
POST /v3/admin/order/{id}/terminate/refund-preview → 200 ✓
POST /v3/admin/order/{id}/terminate (GROUP_VEHICLE) → 200 ✓
POST /v3/admin/order/{id}/terminate (免车户) → 200 ✓
```
---
## 十、相关文档
- Issue: [#7767](https://git.1814.love:8443/wx/HL/issues/7767)
- PR: [#7789](https://git.1814.love:8443/wx/HL/pulls/7789)
- Merge commit: [42dea4c36](https://git.1814.love:8443/wx/HL/commit/42dea4c36)
## 关联 / 联系人
### 链接
- **Issue**: [#7767](https://git.1814.love:8443/wx/HL/issues/7767)
- **PR**: [#7789](https://git.1814.love:8443/wx/HL/pulls/7789)
- **Merge commit**: [42dea4c36](https://git.1814.love:8443/wx/HL/commit/42dea4c36)
### 联系人
- **后端负责人**: @wx