hl-api-changelog/changelogs-v2/2026-08/04_5460_终止行程幂等重放契约恢复-修改接口-管理后台.md
Mimingguang b94a49f0e1
一些检查失败了
changelog-filename-gate / validate (push) Failing after 2s
chore(changelog): 回写 #5460 前端核账终态
修改原因:终止行程幂等重放后端契约恢复,需要核对管理后台是否已稳定复用首次请求正文。

修改内容:确认现有实现和测试完整满足同正文重试、581049 保留输入及字符串 ID,并回写 verified 与历史业务提交。

实际验证:reviewer no findings;当前 hl-admin checkpoint 全量通过;source npm test 46 项通过。

路径:changelogs-v2/2026-08/04_5460_终止行程幂等重放契约恢复-修改接口-管理后台.md。
2026-08-04 14:20:30 +08:00

7.2 KiB

schema, ticket, title, consumer, author, change_type, backend_status, gateway_status, frontend_status, frontend_owner, frontend_ref, target_release, verified_at, status_note, updated_at, base
schema ticket title consumer author change_type backend_status gateway_status frontend_status frontend_owner frontend_ref target_release verified_at status_note updated_at base
hl-changelog/v2 5460 终止行程接口幂等重放契约恢复:同正文重放返回既有结果,不同正文返回 581049 admin wx(GIT) 修改接口 deployed verified verified Pi hl-admin@49f38c7cfb4d5859a13c6ab1a7fea540cb524de5 v2.1 2026-08-04 行为修复:恢复 #5379 已承诺的终止行程幂等重放语义(#5379 最终合并版丢失了早期迭代的幂等实现,导致首次终止成功后同正文重放被 581018 提前拦截、无法取回既有结果。PR #5468 已合并 dev-v3 并部署 TEST,网关已验证新订单首次终止 200、同正文重放返回既有 terminateRefundId/finalRefund、不同边界/正文返回 581049修复前同场景实测 581018 2026-08-04 dev-v3

终止行程接口幂等重放契约恢复:同正文重放返回既有结果,不同正文返回 581049

服务: hl-order-service-v3 PR: #5468 Issue: #5460 日期: 2026-08-04 影响范围: 管理后台订单终止行程(出行中终止)提交接口的重试/重放行为


⚠️ 关键变化

#5379 契约承诺的幂等重放语义此前在 TEST 实测失效:首次终止提交成功但响应丢失后,对同一订单原样重放同一请求,接口返回 581018「出行中取消仅适用于出行中订单」,而不是返回既有终止结果;用不同正文重试也返回 581018 而不是 581049现已修复,行为与 #5379 changelog 契约一致:

场景 修复前实测 修复后
相同正文重放(首次已成功) 581018错误 200,返回既有终止结果(含 terminateRefundId / finalRefund
不同正文 / 不同终止边界重试 581018错误 581049 终止行程重试与首次终止边界或请求不一致

前端无需改动,但超时/网络重试逻辑现在可以依赖该接口的幂等语义:重试时原样复用首次请求正文即可取回既有结果,不要修改正文内容(包括 vehicles[].usedlineUsages[].used)。

二、变更接口清单

# 接口 方法 路径 变更类型 说明
1 终止行程 POST /v3/admin/order/:id/terminate 行为修复 幂等重放语义恢复(契约不变,见 #5379

三、接口详情

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

请求体: OrderTerminateTripReqVO(字段、必填性、约束均不变,与 #5379 一致)

字段 类型 必填 说明
endDayNumber Integer 停在第几天1-based重试必须与首次完全一致
cancelReason String 终止原因;重试必须与首次完全一致
adjustAmount BigDecimal 人工调整额;重试必须与首次一致0 与 null 视为等价)
lineUsages[] Array 统一资源行已用判定;重试必须与首次一致
rooms[] / tickets[] / services[] / supplies[] Array 兼容分组入参;重试必须与首次一致
vehicles[] Array 用车行refId/dayNumber/used;used 仍参与重放一致性校验,金额以后端 Fleet 事实为准

业务边界(重放判定规则)

  1. 订单为 TRAVELLING 时:正常执行首次终止 → 200,订单变 COMPLETED。
  2. 订单已 COMPLETED已终止时,先判定重放身份,不再直接返回 581018
    • 同边界 + 同正文(请求指纹一致)→ 200,返回既有终止结果:terminateRefundIdbaselineRefundadjustAmountfinalRefundsettlementRefundIdnewStatus=COMPLETEDnewFlowStatus=PENDING_REVIEW;不产生任何副作用(不重复写退款、不重复发事件)。
    • 同边界但正文不一致,或边界不一致(endDayNumber 等不同)→ 581049 终止行程重试与首次终止边界或请求不一致
    • 升级前已终止的订单(无指纹快照):按主表与明细快照做语义等价校验,等价重放同样返回既有结果,不等价返回 581049。
  3. endDayNumber 超出订单行程 → 581047(不变);车辆费用不可用 → 584100 fail closed不变

错误码

错误码 含义 触发条件
581018 出行中取消仅适用于出行中订单 订单非 TRAVELLING 且从未终止(自然结束/已取消等)时提交终止
581049 终止行程重试与首次终止边界或请求不一致 已终止订单以不同边界/不同正文重试
581047 终止行程:结束日不在订单行程范围内 endDayNumber 越界
581044 终止行程:结束日之前的资源必须标记为已使用 结束日前资源 used=false

典型成功示例(同正文重放)

请求:

POST /v3/admin/order/2084280231786430466/terminate
Authorization: Bearer <token>
Content-Type: application/json

{
  "cancelReason": "客户高反送医终止",
  "endDayNumber": 2,
  "adjustAmount": 0,
  "lineUsages": [
    { "lineKey": "HOTEL_ASSIGNMENT:96011:1", "used": true },
    { "lineKey": "ITINERARY_NODE:97010:1", "used": true }
  ],
  "vehicles": [
    { "refId": 9000004500000001, "dayNumber": 1, "used": true }
  ]
}

响应(首次终止与同正文重放均为此响应,重放时 terminateRefundId/finalRefund 与首次一致):

{
  "code": 200,
  "data": {
    "terminateRefundId": "2084497785524011009",
    "baselineRefund": "6500.00",
    "adjustAmount": "0.00",
    "finalRefund": "6500.00",
    "settlementRefundId": "2084497785561759746",
    "newStatus": "COMPLETED",
    "newFlowStatus": "PENDING_REVIEW"
  },
  "success": true
}

异常示例(不同正文重试)

{
  "code": 581049,
  "message": "终止行程重试与首次终止边界或请求不一致",
  "success": false
}

四、验证证据

  • mvn -pl hl-order-service-v3 -am verify 全绿(含 spotless + 全部单元/集成测试;新增幂等重放回归:首次终止写指纹 → 同正文重放 → 不同正文冲突三态)。
  • TEST 网关验证wx 定制师,2026-08-04新订单首次终止 200 且写指纹;同正文重放返回同一 terminateRefundId/finalRefund;不同 endDayNumber 返回 581049;升级前已终止订单同语义重放返回既有 terminateRefundId/finalRefund、不同边界返回 581049修复前同场景实测 581018
  • 已部署 TESTdev-v3 滚动部署,双实例健康)。

五、相关文档

关联 / 联系人

链接

联系人

  • 后端负责人: @wx