# 订单内部流程 ProcessStatus V2 重构(Cola 状态机 + 清单确认 + 申请开票) **日期**: 2026-04-23 **PR**: #1318 (dev) **Issue**: #1310 **类型**: refactor **服务**: hl-order-service-v2 --- ## 摘要 订单内部流程状态 `ProcessStatus` 彻底重构:线性 switch → Cola 状态机;新增"清单确认"节点统一改尾款;新增"申请开票"C 端入口;房差/车差自动写入优惠/增项。 ## 新流程 ``` PENDING_TRAVELER_INFO → PENDING_ROOM_CONFIG → PENDING_VEHICLE_CONFIG → PENDING_CHECKLIST_CONFIRM → READY → PENDING_INVOICE ``` ## 枚举值变化(字典 order_process_status) ### 删除(老值软删) - PENDING_INFO / PENDING_ROOM / PENDING_VEHICLE / PENDING_FINANCE - PENDING_INSURANCE / PENDING_CONTRACT / INTERNAL_CONFIRMED ### 新增(6 个) | value | label | 业务含义 | |-------|-------|---------| | `PENDING_TRAVELER_INFO` | 待补全出行人信息 | 支付订金/全款后初始态 | | `PENDING_ROOM_CONFIG` | 配置房子 | 出行人齐全后 | | `PENDING_VEHICLE_CONFIG` | 配置车辆 | 房型分配后 | | `PENDING_CHECKLIST_CONFIRM` | 确认清单 | 车辆分配后,确认前 | | `READY` | 已就绪 | 清单确认通过,保险/合同异步触发 | | `PENDING_INVOICE` | 待开票 | 尾款付清后用户主动申请开票 | ## 接口变化(管理端 + C 端) ### 新增接口 #### 1. `POST /admin/order/{orderId}/checklist-confirm` **管理员确认清单**(把所有未确认优惠/增项批量锁定 → 推进到 READY → 触发保险/合同自动化) - **权限**: Admin - **幂等**: `@Idempotent(60s)` · key = `orderId + operatorId` - **校验**: - `processStatus == PENDING_CHECKLIST_CONFIRM` - 尾款计算 `totalPrice - SUM(confirmedDiscount) + SUM(confirmedSurcharge) - paidAmount >= 0`(含即将 confirmed=true 的条目) - `checklist_confirmed != true`(幂等双保险) - **响应**: `Result` - **失败**: `确认后尾款为负(¥-xxx),请调整优惠/增项` / `流程状态不正确` / `清单已确认` #### 2. `POST /mp/orders/{orderId}/checklist/confirm` **用户端确认清单**(架构预留,本次 PR 未上线 MP Controller,待下个 PR) ### 修改接口 #### 3. `POST /mp/invoices/apply`(既有 `OrderInvoiceService.applyInvoice` 升级) **申请开票** - **幂等**: `@Idempotent(300s)` · key = `userId + orderId` - **新增 Guard**: - `processStatus == READY` - OrderStatus NOT IN `{CANCELLED, REFUNDED, REFUNDING}` - `paidAmount >= totalPrice`(原只检查 `paidAmount > 0`) - **保留**: 原 countValidByOrderId 判重兜底 - **失败**: - `流程状态不允许开票,请先完成确认清单` - `订单已取消或退款,无法开票` - `尾款未结清,无法开票` ### VO 字段变化 #### `OrderDiscountVO` / `OrderSurchargeVO`(新增 3 字段) ```json { "confirmed": true, // false=未确认不影响尾款,true=已确认 "sourceType": "ROOM_ASSIGN", // MANUAL / ROOM_ASSIGN / VEHICLE_ASSIGN "sourceRefId": 12345 // 来源主键(如 hotel_assignment_id) } ``` #### `OrderVO` / `OrderDetailVO` - `待确认差价`(`pendingUpgradeAmount`)字段过渡期保留,返回值恒为 0(T+2 周清理 PR 硬删) - `processStatus` / `processStatusLabel` 返回新 6 个枚举值(字典自动下发 label) ## 保险/合同触发时机变化(⚠️ 重要) - **旧**: 订单 CONFIRMED 时立即自动投保/签约(`OrderConfirmedEvent`) - **新**: **清单确认时**触发(`ChecklistConfirmedEvent`)→ 避免出行人/房型未定就投保导致的退保重投 - 失败处理: 业务失败 → 创建 `OrderTodo` 人工补救;5xx/超时 → LocalEvent 兜底 - ProcessStatus 保持 READY 不变(即使保险或合同失败) ## 追加优惠/增项自动 REOPEN - 订单 `process_status ∈ {READY, PENDING_INVOICE}` + `checklist_confirmed = true` 时 - 调用 `addDiscount` / `addSurcharge` 会自动触发 `PROC_CHECKLIST_REOPENED` - 订单回退到 `PENDING_CHECKLIST_CONFIRM`,`checklist_confirmed=false` - **已完成的保险/合同不反向取消**(业务硬规则) - 新追加的条目 `confirmed=false`,需要再次"确认清单" ## 前端影响(前端 AI 必读) 1. 订单详情页的 `待确认差价` 字段**过渡期保留值为 0**,**不要**继续读此字段做展示;改读 `discounts[]` / `surcharges[]` 数组 + 按 `confirmed` 字段分组展示 2. 流程状态标签 6 个新中文(字典自动下发) 3. Admin 端**新增"确认清单"按钮**,调 `POST /admin/order/{orderId}/checklist-confirm` 4. Admin 端 `addDiscount` / `addSurcharge` 在订单已 READY/PENDING_INVOICE 时会**自动 REOPEN**,前端需要刷新订单状态 5. C 端新增"申请开票"入口,调 `POST /mp/invoices/apply`(需订单 processStatus = READY + 尾款已付清) ## 文档 - 需求单 V2: `docs/tasks/order-process-v2-statemachine-20260423.md` - 架构详设: `docs/tasks/order-process-v2-arch-design-20260423.md` - 评审报告: `docs/tasks/order-process-v2-review-v2-20260423.md` - CR 报告: `docs/tasks/order-process-v2-cr-20260423.md`