- 终止退款预览:新增 POST /v3/admin/order/{id}/terminate/refund-preview,返回资源清单+行程信息
- 终止行程接口改造:入参改资源已用判定+调整额,出参补退款明细字段(破坏性,前端必改)
7.1 KiB
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 终止退款预览
- 使用场景:出行中订单点击「终止行程」打开退款弹框时调用一次,拿到整趟全部资源清单
- 认证:需要管理端 JWT(
Authorization头) - 幂等性:是(只读查询,不落库)
- 限流:无
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 天日期 = 出发日 + N−1) |
| 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
- 前端对接(管理后台): 终止行程弹框页面