--- schema: "hl-changelog/v2" ticket: "7767" title: "团车户与免车团户可终止行程,终止车费投影认可团车与整团免车" consumer: "admin" author: "wx(GIT)" change_type: "修改接口" backend_status: "deployed" gateway_status: "verified" frontend_status: "verified" frontend_owner: "mmg" frontend_ref: "a2a4e2ddae0508de89e941e308ffde5b1d9944c5" target_release: "" verified_at: "2026-09-16" status_note: "仅后端交付。新增错误码 584132 与修改的 584100 文案在源码与 API-SPEC 已核对;测试服验证见工单 #7767 验收评论。前端需补错误码 584132 的提示文案映射,误将两码混用则会给出不恰当的稍后重试建议。;前端 hl-admin a2a4e2dd 已实现:terminateRefund.js 补 584132 提示(等车务配车完成后再试)与 584100(稍后重试)语义区分,api docstring 同步,spec +1,checkpoint 全绿。" updated_at: "2026-09-16" base: "dev-v3" --- # order-v3: 团车户与免车团户可终止行程 > **存放目录**: changelogs-v2/{YYYY-MM}/(管理后台,二期 order-v3) > > **服务**: hl-order-service-v3 (端口 8083) > **PR**: #7789 > **Issue**: #7767 > **日期**: 2026-09-16 > **影响范围**: 终止行程接口新增错误码 584132;错误码 584100 文案修改,收窄适用场景 --- ## 关键变化 1. **原本终止行程对团级配车户(GROUP_VEHICLE)和整团免车户恒返 584100**——该两类户现已可成功终止。 2. **新增错误码 584132**:用于"用车需求未完成"场景,与 584100"车费暂时不可用"语义分开。前端**必须区别对待**两个错误码: - `584132` → "等车务配车完成后再试"(需催车务处理) - `584100` → "暂时不可用,请稍后重试"(快照异常,应自己好转) --- ## 一、背景 #7441 新增了团级正式用车需求声明的端点,其后 #7445 给定制师逐户所报的用车需求引入"就绪状态"检查(DAILY_V3 契约版本)。此前团车户与免车户因为 assignment_contract_version 判据不满足而永久卡死在 584100 错误,无法终止。本次放行这两类户,同时将终止失败分成两个语义明确的错误码。 --- ## 二、变更接口清单 | # | 接口 | 方法 | 路径 | 变更类型 | 说明 | |---|------|------|------|----------|------| | 1 | 终止行程·退款预览 | POST | `/v3/admin/order/{orderId}/terminate-refund/preview` | 修改 | 新增错误码 584132;修改 584100 文案与适用范围 | | 2 | 终止行程 | POST | `/v3/admin/order/{orderId}/terminate` | 修改 | 新增错误码 584132;修改 584100 文案与适用范围 | --- ## 三、接口详情 ### 1. 终止行程·退款预览 `POST /v3/admin/order/{orderId}/terminate-refund/preview` **VO**: `(路径参数 → OrderTerminateRefundPreviewRespVO)` #### 使用场景 出行中点击"终止行程"时的前置预览,展示本单若干今日已用、剩余天数、应退金额等。预览过程不做任何写入,失败也不影响后续正式终止接口调用。 #### 入参字段表 | 字段 | 位置 | 类型 | 必填 | 约束 | 说明 | |------|------|------|------|------|------| | orderId | Path | Long | 是 | - | 订单 ID | #### 出参字段表 | 字段 | 类型 | 说明 | |------|------|------| | orderId | Long | 订单 ID | | orderNo | String | 订单号 | | usedDays | Integer | 已用天数(截至今日) | | remainingDays | Integer | 剩余天数(今日之后) | | refundAmount | BigDecimal | 应退总金额(含车费、房费等) | | vehicleFeeRefund | BigDecimal | 车费应退(拆分显示,供前端按业务决策) | | houseFeeRefund | BigDecimal | 房费应退 | #### 请求示例 ```json GET /v3/admin/order/1934567890123456789/terminate-refund/preview ``` #### 响应示例 ```json { "code": 200, "message": "成功", "data": { "orderId": 1934567890123456789, "orderNo": "26-0503", "usedDays": 2, "remainingDays": 4, "refundAmount": "8000.00", "vehicleFeeRefund": "3200.00", "houseFeeRefund": "4800.00" }, "success": true } ``` #### 空数据 / 降级响应 本接口无空数据场景(订单存在即可预览)。 #### 错误响应 ```json { "code": 584100, "message": "车务车辆总车费暂时不可用,请稍后重试", "success": false, "data": null } ``` ```json { "code": 584132, "message": "用车需求未完成,暂不能终止行程,请等车务配车完成后再试", "success": false, "data": null } ``` #### 错误响应 ```json { "code": 581001, "message": "订单不存在", "success": false, "data": null } ``` ```json { "code": 583301, "message": "订单状态不允许此操作", "success": false, "data": null } ``` #### 业务边界 - **鉴权**: 需 admin 权限,团期户与散客户均支持 - **状态机**: 仅 TRAVELLING/TRANSFER 状态订单可预览,其他状态拒绝(401) - **幂等**: 无写入,重复调用返回一致结果 - **零副作用**: 预览失败不作用任何表与缓存,安全重试 - **旧数据兼容**: refundAmount 等字段在快照 JSON 损毁时可能为 null,前端需判空 --- ### 2. 终止行程 `POST /v3/admin/order/{orderId}/terminate` **VO**: `OrderTerminateTripReqVO → OrderTerminateTripRespVO` #### 使用场景 出行中因特殊原因(天气、医疗等)提前终止订单,订单进入 COMPLETED 状态。结算与房车资源释放在终止之后由结算流程异步处理。 #### 入参字段表 | 字段 | 位置 | 类型 | 必填 | 约束 | 说明 | |------|------|------|------|------|------| | orderId | Path | Long | 是 | - | 订单 ID | | cancelReason | Body | String | 是 | ≤500 字符 | 终止原因(运营内部备注) | | endDayNumber | Body | Integer | 是 | 1 ≤ dayNumber ≤ 行程天数 | 终止日在行程中的序号(Day 1、Day 2 等) | | vehicles | Body | List | 否 | - | 旧客户端兼容字段,新客户端可不传 | #### 出参字段表 | 字段 | 类型 | 说明 | |------|------|------| | orderId | Long | 订单 ID | | orderNo | String | 订单号 | | status | String | 订单状态(转移为 COMPLETED) | | terminateRefundRecord | Object | 退款记录快照 | | terminateRefundRecord.refundAmount | BigDecimal | 实退总金额 | | terminateRefundRecord.createdAt | LocalDateTime | 记录时刻 | #### 请求示例 ```json { "cancelReason": "客户身体不适,需提前返程", "endDayNumber": 3 } ``` #### 响应示例 ```json { "code": 200, "message": "成功", "data": { "orderId": 1934567890123456789, "orderNo": "26-0503", "status": "COMPLETED", "terminateRefundRecord": { "refundAmount": "8000.00", "createdAt": "2026-09-16T14:30:00" } }, "success": true } ``` #### 空数据 / 降级响应 本接口无空数据场景。 #### 错误响应 ```json { "code": 584132, "message": "用车需求未完成,暂不能终止行程,请等车务配车完成后再试", "success": false, "data": null } ``` ```json { "code": 584100, "message": "车务车辆总车费暂时不可用,请稍后重试", "success": false, "data": null } ``` #### 业务边界 - **鉴权**: 需 admin 权限 - **状态机**: 仅 TRAVELLING 状态可终止 - **幂等**: 同一订单同一 endDayNumber 重复终止返 581049(已终止) - **团车户与免车户放行**: 现已支持,按 DAILY_V3 规则正常处理 --- ## 四、契约约束与正确调用方式 | 场景 | 做法 | |------|------| | 出行中 Day 3 终止 | 先预览、再提交,endDayNumber=3 | | 重复终止(幂等) | 同一订单同 endDayNumber 重复 POST,返 200 或 581049 | | 错误码 584132 | "等车务配车完成",需催车务处理 | | 错误码 584100 | "暂时不可用",稍后重试 | --- ## 五、数据库行为 | 操作 | order_main.order_status | order_terminate_refund | 房车资源释放 | |------|---------------------------|---------------------------|------------| | 终止成功 | TRAVELLING → COMPLETED | INSERT 一行 | 异步触发 | | 终止失败 | 无变更 | 无新增 | 无 | --- ## 六、边界行为 - **未登录** → 401 - **无权限** → 403 - **订单不存在** → 404 - **状态非 TRAVELLING** → 583301 - **结束日越界** → 581047 - **车费快照异常** → 584100 - **用车需求未配车** → 584132 --- ## 六.5、枚举 ### 订单状态 (status 字段) **所属字段**: OrderTerminateTripRespVO.status | **类型**: String | 值 | 中文 | 说明 | |----|------|------| | TRAVELLING | 出行中 | 使用终止接口前的状态 | | COMPLETED | 已完成 | 终止成功后的状态 | --- ## 六.6、修改前后对比 ### 错误码对比 | 错误码 | 改前 | 改后 | |--------|------|------| | 584100 | 对所有车费投影缺失的户统一返回 | 收窄为仅覆盖 DAILY_V3 契约版本但快照未就绪的户 | | 584132 | 不存在 | 新增,覆盖非 DAILY_V3 且未配车的户 | --- ## 六.7、影响评估 - **是否破坏向后兼容**: 是(团车户和免车户原本失败,现已成功) - **前端是否必须同步上线**: 是(需处理新错误码 584132) - **前端 workaround 清理点**: 删除硬编码的"团车户无法终止"逻辑 --- ## 七、不影响范围 - **仅影响**: 管理后台出行中订单的终止功能 - **零影响**: - C 端应用 - 其他状态订单的操作 - 房费结算 - 用车需求声明等其他模块 --- ## 八、测试环境已验证 ``` POST /v3/admin/order/{id}/terminate-refund/preview → 200 ✓ POST /v3/admin/order/{id}/terminate (GROUP_VEHICLE) → 200 ✓ POST /v3/admin/order/{id}/terminate (免车户) → 200 ✓ ``` --- ## 十、相关文档 - Issue: [#7767](https://git.1814.love:8443/wx/HL/issues/7767) - PR: [#7789](https://git.1814.love:8443/wx/HL/pulls/7789) - Merge commit: [42dea4c36](https://git.1814.love:8443/wx/HL/commit/42dea4c36) ## 关联 / 联系人 ### 链接 - **Issue**: [#7767](https://git.1814.love:8443/wx/HL/issues/7767) - **PR**: [#7789](https://git.1814.love:8443/wx/HL/pulls/7789) - **Merge commit**: [42dea4c36](https://git.1814.love:8443/wx/HL/commit/42dea4c36) ### 联系人 - **后端负责人**: @wx