这个提交包含在:
yaosutu 2026-04-23 17:33:42 +08:00
当前提交 485a180781

查看文件

@ -0,0 +1,114 @@
# 订单内部流程 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<Void>`
- **失败**: `确认后尾款为负(¥-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`)字段过渡期保留,返回值恒为 0T+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`