文件
hl-api-changelog/changelogs-v2/2026-06/11_3556_出行中取消路径下线-cancel-on-trip改terminate-修改接口-管理后台.md
T
yaosutu 0456209b4e docs(changelog): 补出行中取消路径下线说明(cancel/on-trip 改 terminate)
前期 #3556 changelog 只写了新路径入参出参,未点明旧路径已删除,
导致前端联调仍调旧 URL 收到 404。本篇专补路径下线这一环,自包含。
2026-06-11 10:09:10 +08:00

10 KiB
原始文件 Blame 文件历史

【⚠️修改接口·管理后台】出行中取消旧路径下线:cancel/on-trip → terminate (#3556)

服务: hl-order-service-v3 | 更新时间: 2026-06-11 ⚠️ 破坏性变更(路径级):旧端点 POST /v3/admin/order/{id}/cancel/on-trip 已删除,调用返回 404。 📌 本篇专补「路径下线」这一环(前期 #3556 changelog 只写了新路径的入参/出参,未点明旧路径已废,导致前端联调时仍在调旧 URL 收到 404)。入参/出参完整改造见 #3556 那篇,本篇做自包含汇总。

1. 接口背景

「出行中取消」此前走 POST /v3/admin/order/{id}/cancel/on-trip。后端在终止行程改造时把该端点重命名为 POST /v3/admin/order/{id}/terminate,并改变了语义:

  • 旧:出行中取消 → 订单直接进入 CANCELLED(已取消)。
  • 新:终止行程 → 订单进入 COMPLETED(已完成),再在核单子状态(reviewStatus / flowStatus)中流转结算,不再直接 CANCELLED。

后端代码里 cancel/on-trip 路径已全量删除(全仓 git grep 无残留),任何对旧路径的调用都会 404。前端「出行中取消」分支若仍指向旧 URL,必须改指新 URL。

2. 变更清单

# 操作 旧 新 变更类型
1 取消/终止 出行中订单 POST /v3/admin/order/{id}/cancel/on-trip POST /v3/admin/order/{id}/terminate 路径下线 + 重命名
2 退款预览(出行中) (旧流程无独立预览,或复用 cancel-preview) POST /v3/admin/order/{id}/terminate/refund-preview 新增(详见 #3556 配套篇)

3. 接口详情

3.1 终止行程(替代出行中取消)

  • 路径:POST /v3/admin/order/{id}/terminate
  • 使用场景:出行中订单提前终止,定制师调用。需先调「终止退款预览」拿资源清单。
  • 认证:管理端 JWT(Authorization 头)
  • 幂等性:是。订单一旦终止状态变为 COMPLETED,二次调用因状态非 TRAVELLING 返回 581018。

4. 接口入参

4.1 路径参数

字段 类型 必填 说明
id String ✅ 订单 ID

4.2 请求体(OrderTerminateTripReqVO)

字段 类型 必填 说明 校验
cancelReason String ✅ 终止原因(调整额说明也并入此处,不单列字段) 非空
endDayNumber Integer ✅ 停在第几天(截断点,1-based) ≥ 1
rooms Array<{refId, used}> ✅ 住宿各行已用判定 列表非 null
tickets Array<{refId, used}> ✅ 门票各行已用判定 列表非 null
vehicles Array<{refId, dayNumber, used}> ✅ 用车各行已用判定(同车跨天靠 dayNumber 区分) 列表非 null
adjustAmount BigDecimal ❌ 人工调整额(±,正=多退 负=少退),默认 0 —

refId 全部取自「终止退款预览」接口返回值。入参只传 used 判定 + adjustAmount,不传任何金额单价——退款额由后端按预览同源成交价权威重算(防篡改)。保险不在入参,后端自动按锁定不退处理。

rooms / tickets 行(ResourceUsedItem)

字段 类型 必填 说明
refId String ✅ 配单记录 ID(住宿=house_hotel_assignment.id;门票=order_scenic_assignment.assignment_id)
used Boolean ✅ 是否已使用(true=已用不退 / false=未用可退)

vehicles 行(VehicleUsedItem)

字段 类型 必填 说明
refId String ✅ 配车记录 ID(同段车跨天 refId 相同)
dayNumber Integer ✅ 第几天(1-based,≥ 1)
used Boolean ✅ 当天该车是否已使用

5. 出参(Result<OrderTerminateTripRespVO>)

字段 类型 说明
terminateRefundId String 终止退款主表 ID
baselineRefund BigDecimal 系统建议基线 = max(0, paidAmount − usedAmount)
adjustAmount BigDecimal 人工调整额(回显入参,默认 0)
finalRefund BigDecimal 最终返还额 = max(0, baselineRefund + adjustAmount)
settlementRefundId String 核单返还记录 ID(核单模块写入后回填)
newStatus String 终止后订单粗状态(恒 COMPLETED)
newFlowStatus String 终止后流程细状态(恒 PENDING_REVIEW)

6. 枚举 / 数据字典

6.1 newStatus

值 中文 说明
COMPLETED 已完成 终止后订单进入完成态,转入核单流程(注意:不再是旧的 CANCELLED)

6.2 newFlowStatus

值 中文 说明
PENDING_REVIEW 待核单 终止后等待核单录入与结算复核

7. 错误码

code 含义 触发场景
581007 订单不存在 id 无对应订单
581018 出行中取消仅适用于出行中订单 订单当前状态非 TRAVELLING(未出发 / 已终止 / 已完成时调用,含二次终止)

8. 示例

8.1 典型成功

请求:

POST /v3/admin/order/60001234567890/terminate
Authorization: Bearer {token}
Content-Type: application/json
{
  "cancelReason": "客户中途高反送医终止;林芝段酒店已付全款不可退,调整 -300",
  "endDayNumber": 3,
  "rooms": [
    {"refId": "96011", "used": true},
    {"refId": "96014", "used": false}
  ],
  "tickets": [
    {"refId": "97001", "used": true}
  ],
  "vehicles": [
    {"refId": "98001", "dayNumber": 1, "used": true},
    {"refId": "98001", "dayNumber": 2, "used": true},
    {"refId": "98001", "dayNumber": 3, "used": true}
  ],
  "adjustAmount": -300.00
}

响应:

{
  "code": 200,
  "message": "ok",
  "success": true,
  "data": {
    "terminateRefundId": "9610000001",
    "baselineRefund": 2264.00,
    "adjustAmount": -300.00,
    "finalRefund": 1964.00,
    "settlementRefundId": "9620000001",
    "newStatus": "COMPLETED",
    "newFlowStatus": "PENDING_REVIEW"
  }
}

8.2 边界(不填调整额,默认 0)

请求(片段):

{ "cancelReason": "客户主动终止", "endDayNumber": 5, "rooms": [], "tickets": [], "vehicles": [] }

响应(片段):

{ "code": 200, "data": { "baselineRefund": 0.00, "adjustAmount": 0.00, "finalRefund": 0.00, "newStatus": "COMPLETED", "newFlowStatus": "PENDING_REVIEW" } }

8.3 异常 —— 调旧路径(前端联调踩的就是这个)

请求:

POST /v3/admin/order/60001234567890/cancel/on-trip

响应:

HTTP 404 Not Found

旧路径在后端已无任何映射,必须改调 POST /v3/admin/order/{id}/terminate。

8.4 异常 —— 订单非出行中

响应:

{ "code": 581018, "message": "出行中取消仅适用于出行中订单", "success": false }

9. 业务边界

  • ✅ 适用:订单当前粗状态 = TRAVELLING(出行中)
  • ❌ 不适用:未出发订单走「取消订单」流程(cancel/pre-trip);已终止 / 已完成订单二次调用返回 581018
  • ⚠️ finalRefund 最低为 0,不会出现负数;退款额进入核单返还,由财务复核放款;保险恒不退

10. 修改前后对比

10.1 路径与语义

维度 改前 改后
路径 POST /{id}/cancel/on-trip POST /{id}/terminate
退款预览 复用取消预览(或无独立预览) POST /{id}/terminate/refund-preview(独立,POST)
终止后订单状态 CANCELLED(已取消) COMPLETED(已完成)→ 进核单 PENDING_REVIEW
入参 VO OrderCancelOnTripReqVO OrderTerminateTripReqVO
出参 VO OrderCancelOnTripRespVO OrderTerminateTripRespVO

10.2 入参字段级

字段 改前 改后
cancelReason ✅ 终止原因 ✅ 终止原因(+ 调整说明并入)
returnAmount ✅ 手填返还额(必填) ❌ 删除(改由后端按资源核算)
returnRemark ✅ 返还备注(必填) ❌ 删除(说明并入 cancelReason)
endDayNumber — ✅ 新增,停在第几天
rooms / tickets / vehicles — ✅ 新增,各资源行已用判定
adjustAmount — ✅ 新增(可选),人工调整额

10.3 出参字段级

字段 改前 改后
returnAmount ✅ 返还额(回显) ❌ 删除
settlementRefundId ✅(旧实现恒 null) ✅ 真实核单返还记录 ID
newStatus ✅(值 已取消) ✅(值变 COMPLETED)
terminateRefundId — ✅ 新增
baselineRefund / adjustAmount / finalRefund — ✅ 新增 退款明细金额
newFlowStatus — ✅ 新增(PENDING_REVIEW)

11. 影响评估 / 回滚

  • 是否破坏向后兼容:是。路径、入参、出参、终态全部变化。前端仍调旧路径 → 404;仍按旧 body → 校验失败。
  • 前端必须同步:是。「出行中取消」分支需:① 改 URL 为 /terminate;② 改 body 为资源勾选模型;③ 终态判断从「已取消」改为「已完成→待核单」。
  • 回滚:本路径下线在后端已合入主线(rename commit + #3557),如需回滚需后端 revert,前端无单独回滚动作。

12. 注意事项

  • ⚠️ 旧路径 cancel/on-trip 在后端无任何兼容映射,不会做 301/308 跳转,直接 404。
  • 必须配合「终止退款预览」POST /{id}/terminate/refund-preview 使用:预览拿资源清单 → 前端本地按结束天标已用/可退 → 提交时只回传 used 判定 + adjustAmount。
  • 终止后订单是「已完成(待核单)」而非「已取消」,列表/详情的状态展示需按新枚举对齐。

13. 关联 / 联系人

13.1 链接

  • Issue: #3556
  • 入参/出参完整改造 changelog(同 Issue): 06_3556_终止行程接口改造-修改接口-管理后台.md + 06_3556_终止退款预览-新增接口-管理后台.md
  • PR: #3557

13.2 联系人

  • 后端负责人: @yst
  • 前端对接(管理后台): 订单详情「出行中取消 / 终止行程」分支