hl-api-changelog/changelogs-v2/2026-08/03_5379_终止行程车辆退款权威口径-修改接口-管理后台.md
Mimingguang cdf37e39f8
所有检测均成功
changelog-filename-gate / validate (push) Successful in 1s
chore(changelog): 回写 #5379 前端修复终态
修改原因:终止行程首次请求响应丢失时必须稳定重放同一正文,车辆使用状态也需按单日事实消费。

修改内容:记录冻结 API 正文与展示快照的修复提交,回写 released、verified 与 v2.1 发布信息。

实际验证:reviewer no findings;pnpm checkpoint 定向 Vitest 与生产构建通过;source npm test 46 项通过。

路径:changelogs-v2/2026-08/03_5379_终止行程车辆退款权威口径-修改接口-管理后台.md。
2026-08-04 15:36:00 +08:00

9.6 KiB

schema, ticket, title, consumer, change_type, author, backend_status, gateway_status, frontend_status, frontend_owner, frontend_ref, target_release, verified_at, status_note, updated_at, base
schema ticket title consumer change_type author backend_status gateway_status frontend_status frontend_owner frontend_ref target_release verified_at status_note updated_at base
hl-changelog/v2 5379 终止行程车辆退款改为 Fleet 服务日权威判定 admin 修改接口 wx(GIT) deployed verified verified Pi hl-admin@d7a7e995cb9555fe07ef13bfb3d0f781f139e535 v2.1 2026-08-04 后端实现完成:双模块 verify 通过order 7402 全绿 / fleet 3010 仅 Docker 环境型 1 error,本单新增代码行覆盖率 91.7%,PR #5417+#5445 已合并 dev-v3 并部署 TESTfleet→order-v3 顺序,网关已验证预览成功路径15 行 VEHICLE+terminateDate wire key、终止提交成功COMPLETED+PENDING_REVIEW+settlement refund 落库)、幂等重放(同 terminateRefundId、阻断路径581018 COMPLETED 拒绝/584100 费用不可用 fail-closed、空集路径无需求允许空车辆成本;管理后台已由 Pi 领取并开始兼容适配。 2026-08-04 dev-v3

订单: 终止行程车辆退款改为 Fleet 服务日权威判定

服务: hl-order-service-v3 PR: #5417 Issue: #5379 日期: 2026-08-03 影响范围: 管理后台订单终止退款预览及终止提交


⚠️ 关键变化

终止行程时,车辆是否已发生不再采用客户端提交的 vehicles[].used;后端按 Fleet 返回的 serviceDateendDayNumber 对应终止日权威判定。vehicles[].used 仍为必填兼容字段,仅参与请求重放一致性校验。

变更接口

# 接口 方法 路径 变更类型 说明
1 终止行程退款预览 POST /v3/admin/order/:id/terminate/refund-preview 响应语义修改 车辆行 defaultUsed 仅供初始化展示,最终提交以后端权威事实为准
2 终止行程 POST /v3/admin/order/:id/terminate 请求字段语义修改 vehicles[].used 保持必填,但不再参与车辆退款金额计算

二、接口详情

1. 终止行程退款预览 POST /v3/admin/order/:id/terminate/refund-preview

出参: Result<OrderTerminateRefundPreviewRespVO>

refundLines[] 统一资源行(新逻辑主用,提交 lineUsageslineKey 回传)

refundLinesList<TerminateRefundItemVO>,住宿/门票/活动/服务/交通/备品/用车/保险全部资源统一展平为行,已按 dayNumber 展开(用车每天一行)。

字段 类型 说明 示例
refundLines[].lineKey String 统一退款资源行 key,提交 lineUsages 时原样回传 ITINERARY_NODE:97010:2
refundLines[].categoryCode String 资源类型 discriminatorROOM/TICKET/ACTIVITY/SERVICE/TRANSPORT/SUPPLIES/VEHICLE/INSURANCE,前端据此判断每行资源类型 SERVICE
refundLines[].categoryName String 资源分类名称(与 categoryCode 对应) 服务
refundLines[].sourceType String 资源来源类型 discriminatorHOTEL_ASSIGNMENT/ITINERARY_NODE/BATCH_SUPPLIES/PRODUCT_SUPPLIES/VEHICLE_ASSIGNMENT/INSURANCE_ORDER,决定 sourceId 语义 ITINERARY_NODE
refundLines[].sourceId String(Long) 资源来源 ID,语义由 sourceType 决定Long 序列化为 String 防 JS 精度丢失) 97010
refundLines[].refId String(Long) 资源配单记录 IDString 防 JS 精度丢失) 96011
refundLines[].name String 资源名称快照(酒店名/景点名/车型) 拉萨瑞吉·大床房
refundLines[].dayNumber Integer 第几天(住宿/门票/用车每天行有值;保险为 null 1
refundLines[].dealPrice String(BigDecimal) 结算单价(住宿=settlementPrice/间·晚;门票按节点价格口径;用车=dailyFee 1280.00
refundLines[].quantity Integer 数量(住宿=间数;门票=张数;用车=车辆数;保险=1 1
refundLines[].billingType String 计费方式快照,备品等资源使用 PER_QUANTITY
refundLines[].totalAmount String(BigDecimal) 行金额合计 = dealPrice × quantity 1280.00
refundLines[].defaultUsed Boolean 前端初始化展示值;车辆行最终是否已发生由提交时 Fleet serviceDate 与终止日重新判定,非车辆行按提交 used 重算 false
refundLines[].locked Boolean 是否锁定不退true=保险等不可退资源) false
refundLines[].lockedReason String 锁定原因(locked=true 时有值) 保险已生效不退

旧分组字段(兼容保留,与 refundLines 并存)

rooms/tickets/services/supplies/vehicles/insurance 继续返回,类型均为 List<TerminateRefundItemVO>(与 refundLines 同构,字段集完全一致):

字段 类型 说明
rooms List<TerminateRefundItemVO> 住宿清单(每晚×每组房一行)
tickets List<TerminateRefundItemVO> 门票/活动清单(景点/活动节点,含套餐内)
services List<TerminateRefundItemVO> 服务清单SERVICE/TRANSPORT 节点)
supplies List<TerminateRefundItemVO> 备品清单hasCost=true 的备品,无天维度整单一行)
vehicles List<TerminateRefundItemVO> 用车清单(每段车按 totalDays 展开成每天一行)
insurance List<TerminateRefundItemVO> 保险(整单 1 行,locked=true 不可退)

前端可任选一种渲染:新逻辑按 refundLines[] + categoryCode/sourceType 区分资源;旧分组字段不会删除,兼容期可继续使用。

days 与其余顶层字段

字段 类型 说明
days[].terminateDate String(date) 结束日期选项 wire key 固定为 terminateDate(原 date 字段改名),值 = departDate + (dayNumber-1);dayNumber/label/isCurrent 不变

2. 终止行程 POST /v3/admin/order/:id/terminate

VO: OrderTerminateTripReqVO

字段 位置 类型 必填 约束 说明
endDayNumber Body Integer 1-based,必须落在订单行程范围内 用于确定终止日;预览返回的 days[].terminateDate 即对应日期
vehicles[].refId Body Long/String ID 有效配车记录 ID 同段车跨天可重复
vehicles[].dayNumber Body Integer >= 1 区分同段车辆的服务日
vehicles[].used Body Boolean 不可省略 兼容及重放摘要字段,不参与车辆退款金额计算
lineUsages[].used Body Boolean 非车辆资源按该值重算 不覆盖车辆 Fleet 事实

三、契约约束与正确调用方式

场景 后端行为
vehicles[].used 与 Fleet 服务日事实不同 车辆退款采用 Fleet 服务日事实;客户端值只保留在请求摘要中
相同终止边界和相同正文重试 返回既有终止结果
已终止订单以不同 endDayNumber 或不同正文重试 拒绝,错误码 581049
endDayNumber 超出订单行程 拒绝,错误码 581047
Fleet serviceDate 无法映射到订单行程 拒绝,错误码 581048
Fleet 车辆事实不可用或不完整 fail closed,错误码 584100,不按零车费继续

前端调用要求:

  1. 继续提交完整的 vehicles[].refId/dayNumber/used,不要删除 used 字段。
  2. 不要根据 vehicles[].used 自行推导最终车辆退款金额;以接口返回的 baselineRefundfinalRefund 为准。
  3. 收到上述错误码时保留用户输入并提示重试或刷新事实,不要按“无车辆费用”继续。

四、边界行为与兼容性

  • 请求字段、类型和必填性未删除,旧客户端 payload 可继续解析。
  • vehicles[].used 的金额语义发生变化,但仍参与幂等重放摘要;重试时必须复用首次正文。
  • 非车辆资源仍按既有 lineUsages[].used 规则处理。
  • 后端修复尚未合并、部署或经网关验证;本文件不声明 TEST 环境可用。

验证证据

  • 定向单元测试覆盖 Fleet 服务日权威判定、越界/不一致 fail-closed、重放冲突及车辆 used 不覆盖事实。
  • 真实独立 Redis 验证覆盖 owner-token 在事务提交前被替换时,订单状态、终止退款和 Fleet Outbox 三类本地写入全部回滚SettlementFleetPlanLockCommitRedisIntegrationTest,本机 Redis 7.4 真实运行通过)。
  • Fleet 真表 H2 IT 覆盖 reservation 生命周期与 terminate 截断隔离5 个;order-v3 真表 IT 覆盖 Outbox 最新命令因果查询。
  • 双模块 reactor verifyorder-v3 7334 全绿;fleet 2914,仅 #5374 Docker MySQL 测试环境型失败(本机无 Docker
  • 本单核心新增代码 changed-line coverage 90.5%≥90%;evidence 包含 raw JaCoCo、provider receipts 与 SHA-256 索引。
  • MySQL 8.0.33 gate 凭据不可恢复,未运行(如实记录,不冒充通过)。
  • PR 合并、TEST 部署与网关验收仍待完成,因此 backend_statusgateway_status 保持 pending

六、相关文档

关联 / 联系人

链接

联系人

  • 后端负责人: @wx