hl-api-changelog/changelogs-v2/2026-06/06_3556_终止退款预览-新增接口-管理后台.md
yaosutu 2106e5be43 新增终止行程退款 changelog(预览新接口 + 终止接口改造,#3556 / PR #3557)
- 终止退款预览:新增 POST /v3/admin/order/{id}/terminate/refund-preview,返回资源清单+行程信息
- 终止行程接口改造:入参改资源已用判定+调整额,出参补退款明细字段(破坏性,前端必改)
2026-06-06 23:29:56 +08:00

7.1 KiB

新增接口·管理后台】终止行程·退款预览 (#3556)

PR: #3557 | 服务: hl-order-service-v3 | 更新时间: 2026-06-06

1. 接口背景

出行中订单因特殊原因需要提前终止行程时,需要给定制师一个「按已用资源算应退多少」的界面。本接口提供终止退款弹框所需的全部资源清单 + 行程时间轴信息,定制师选择「停在第几天」后,由前端本地标记每项资源已用/未用并实时算出退款额,最终在终止提交接口落账。

2. 变更清单

# 接口 方法 路径 变更类型 说明
1 终止退款预览 POST /v3/admin/order/{id}/terminate/refund-preview 新增接口 返回终止退款弹框所需资源清单 + 行程信息

3. 接口详情

3.1 终止退款预览

  • 使用场景:出行中订单点击「终止行程」打开退款弹框时调用一次,拿到整趟全部资源清单
  • 认证:需要管理端 JWTAuthorization 头)
  • 幂等性:是(只读查询,不落库)
  • 限流:无

4. 接口入参

4.1 路径参数

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

4.2 请求体字段

无请求体。前端一次性拿到整趟全部资源,「停在第几天」的选择与已用/未用标记、退款金额计算全部在前端本地完成,不需要每选一天再调本接口

5. 出参(响应)

5.1 响应字段(data

字段 类型 说明
paidAmount BigDecimal 已付金额(公司账上已收,前端算退款基线用)
tripDays Integer 行程总天数(画时间轴用,如 7 天 6 晚 = 7
departDate String(date) 出发日期(yyyy-MM-dd,第 N 天日期 = 出发日 + N1
tripCurrentDay Integer 当前已出行到第几天(时间轴默认选中点)
rooms Array 住宿资源清单(每晚每组房一行)
tickets Array 门票资源清单(每景点每天一行)
vehicles Array 用车资源清单(整车已按天展开,每天一行
insurance Array 保险清单(整单一行,锁定不退)

5.2 ResourceItem 字段rooms / tickets / vehicles / insurance 各行通用)

字段 类型 说明
refId String 资源记录 ID提交终止时按此回传已用判定;用车多天共用同一 refId,靠 dayNumber 区分;保险可能为 null
name String 资源名称(酒店名 / 景点名 / 车型 / 保险产品名)
dayNumber Integer 对应行程第几天(保险为 null
dealPrice BigDecimal 成交单价(住宿=每间每晚价 / 门票=每张价 / 用车=每天每辆日租 / 保险=保费)
quantity Integer 数量(住宿=房间数 / 门票=张数 / 用车=车辆数 / 保险=1
totalAmount BigDecimal 本行小计(= dealPrice × quantity
locked Boolean 是否锁定不退(保险恒 true,其余 false
lockedReason String 锁定原因(如「保险已生效不退」;未锁定为 null

响应不含「是否已用」标记与「退款合计」——这些由前端按所选结束天(dayNumber ≤ 结束天 默认已用,之后默认可退)实时计算。

6. 枚举 / 数据字典

本接口无枚举字段。资源分类通过 rooms / tickets / vehicles / insurance 四个数组区分,无独立 resourceType 字段。

7. 错误码

code 含义 触发场景
581018 出行中取消仅适用于出行中订单 订单当前状态非「出行中」时调用本接口

8. 示例

8.1 典型成功

请求

POST /v3/admin/order/60001234567890/terminate/refund-preview
Authorization: Bearer {token}
(无请求体)

响应

{
  "code": 200,
  "message": "ok",
  "success": true,
  "data": {
    "paidAmount": 6000.00,
    "tripDays": 7,
    "departDate": "2026-05-12",
    "tripCurrentDay": 3,
    "rooms": [
      {"refId": "96011", "name": "拉萨瑞吉度假酒店·大床房", "dayNumber": 1, "dealPrice": 1280.00, "quantity": 1, "totalAmount": 1280.00, "locked": false, "lockedReason": null},
      {"refId": "96014", "name": "拉萨瑞吉度假酒店·大床房", "dayNumber": 4, "dealPrice": 1280.00, "quantity": 1, "totalAmount": 1280.00, "locked": false, "lockedReason": null}
    ],
    "tickets": [
      {"refId": "97001", "name": "布达拉宫门票", "dayNumber": 2, "dealPrice": 200.00, "quantity": 2, "totalAmount": 400.00, "locked": false, "lockedReason": null}
    ],
    "vehicles": [
      {"refId": "98001", "name": "丰田赛那 商务车", "dayNumber": 1, "dealPrice": 600.00, "quantity": 1, "totalAmount": 600.00, "locked": false, "lockedReason": null},
      {"refId": "98001", "name": "丰田赛那 商务车", "dayNumber": 2, "dealPrice": 600.00, "quantity": 1, "totalAmount": 600.00, "locked": false, "lockedReason": null},
      {"refId": "98001", "name": "丰田赛那 商务车", "dayNumber": 3, "dealPrice": 600.00, "quantity": 1, "totalAmount": 600.00, "locked": false, "lockedReason": null}
    ],
    "insurance": [
      {"refId": null, "name": "安联境内旅行险·尊享版", "dayNumber": null, "dealPrice": 256.00, "quantity": 1, "totalAmount": 256.00, "locked": true, "lockedReason": "保险已生效不退"}
    ]
  }
}

8.2 边界情况

场景说明:某天住两个酒店(同一 dayNumber 出现多行)。

响应rooms 片段)

"rooms": [
  {"refId": "96021", "name": "林芝希尔顿·双床房", "dayNumber": 2, "dealPrice": 980.00, "quantity": 1, "totalAmount": 980.00, "locked": false, "lockedReason": null},
  {"refId": "96022", "name": "林芝工布庄园·大床房", "dayNumber": 2, "dealPrice": 880.00, "quantity": 1, "totalAmount": 880.00, "locked": false, "lockedReason": null}
]

8.3 业务失败(异常)

场景说明:订单非出行中(如已确认待出发)时调用。

响应

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

9. 业务边界

  • 适用场景:订单当前状态 = 出行中TRAVELLING
  • 不适用场景:未出发(待支付 / 待完善 / 已确认待出发)→ 返回 581018;这些状态请走「取消订单」流程,不走终止退款
  • ⚠️ 特殊边界
    • 保险行恒 locked=true,不参与退款
    • 同一天可有多行(多酒店 / 多门票 / 多车),按 refId 区分
    • 用车一段车按行程天数展开为多行,多行共用同一 refId

13. 关联 / 联系人

13.1 链接

13.2 联系人

  • 后端负责人: @yst
  • 前端对接(管理后台): 终止行程弹框页面