From 1ca7c886cc5e963359ad8bc1b3c5ea437fc40773 Mon Sep 17 00:00:00 2001 From: API Changelog Bot Date: Thu, 23 Apr 2026 19:04:11 +0800 Subject: [PATCH] =?UTF-8?q?=E8=AE=A2=E5=8D=95=E5=BE=85=E5=8A=9E=E5=AE=8C?= =?UTF-8?q?=E6=88=90=E6=8E=A5=E5=8F=A3=E8=A1=A5=E9=BD=90=E4=B8=9A=E5=8A=A1?= =?UTF-8?q?=E5=89=8D=E7=BD=AE=E6=A0=A1=E9=AA=8C=20(PR=20#1327)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 空点分配房间/车辆/投保/签约不再成功, 确认清单真正触发锁单+事件 --- ...fix_order-v2_todo-complete-prerequisite.md | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 changelogs/2026-04/23_fix_order-v2_todo-complete-prerequisite.md diff --git a/changelogs/2026-04/23_fix_order-v2_todo-complete-prerequisite.md b/changelogs/2026-04/23_fix_order-v2_todo-complete-prerequisite.md new file mode 100644 index 0000000..f4232d4 --- /dev/null +++ b/changelogs/2026-04/23_fix_order-v2_todo-complete-prerequisite.md @@ -0,0 +1,65 @@ +# 订单待办完成接口补齐业务前置校验(杜绝空点成功) + +**日期**: 2026-04-23 +**PR**: #1327 (dev) +**Issue**: #1324 +**类型**: fix +**服务**: hl-order-service-v2 + +--- + +## 摘要 + +订单详情页「待办」按钮(分配房间 / 分配车辆 / 确认清单 / 购买保险 / 签署合同)**过去即使对应业务未完成也能直接点成功**,仅改 `order_todo.status=COMPLETED`,但 `order.checklist_confirmed` / `process_status` / 下游保险合同事件全未触发,相当于 UI 假成功。 + +本次修复在 `PUT /admin/order/todo/{todoId}/complete` 内部补齐业务前置校验,未就绪直接返回业务异常。 + +## 接口 + +**路径没变**:`PUT /admin/order/todo/{todoId}/complete` + +**新的错误响应**(HTTP 仍为 200,业务码在 `Result.code`): + +| 触发场景 | `Result.code` | `Result.msg` | +|---|---|---| +| 点「分配房间」但房间未安排 | BUSINESS_ERROR | `请先在行程安排中完成房间分配` | +| 点「分配车辆」但车辆未安排 | BUSINESS_ERROR | `请先在行程安排中完成车辆分配` | +| 点「购买保险」但未投保 | BUSINESS_ERROR | `请先完成保险购买` | +| 点「签署合同」但合同未签 | BUSINESS_ERROR | `请先完成合同签署` | +| 点「确认清单」但 `process_status ≠ PENDING_CHECKLIST_CONFIRM` | BUSINESS_ERROR | `流程状态不正确,当前: {状态label}` | +| 点「确认清单」但尾款为负 | BUSINESS_ERROR | `确认后尾款为负(¥X),请调整优惠/增项后再确认` | + +> 正常成功仍返回 `{"code":"SUCCESS","data":null}`。 + +## 「确认清单」待办的完整行为(本次接通) + +以前:点「确认清单」只改 `order_todo.status`,没任何副作用。 +现在:点「确认清单」会真正执行锁单全流程: + +- 状态机 `PENDING_CHECKLIST_CONFIRM → READY` +- `order.checklist_confirmed = true`,`order.ready_at` 填充 +- 所有未确认的 `order_discount` / `order_surcharge` 批量 `confirmed = 1`(优惠/增项金额锁定) +- 尾款锁定 +- afterCommit 发布 `ChecklistConfirmedEvent` → 下游保险自动投保 + 合同自动签约流程启动 +- Timeline 新增 `CHECKLIST_CONFIRMED` 记录 + +## 前端联调建议 + +1. 待办按钮点击后的错误提示继续按 `Result.msg` 显示即可,无需改接口调用方式 +2. 「确认清单」按钮点击后建议**刷新订单详情页**,因为会联动触发 process_status + checklist_confirmed + 保险/合同状态变化 +3. 行程安排 tab 的「暂未安排房间/车辆」与顶部待办按钮是一个系统:只要这边没数据,对应待办就点不动(符合直觉) +4. 「购买保险」/「签署合同」待办:只有当前端子模块或管理员在保险/合同页面成功操作后,对应待办才能被点 + +## 幂等与并发 + +- 「确认清单」受 `@Idempotent(keyArg=orderId+operatorId, timeout=60s)` + `@Lock4j('order:checklist:' + orderId)` 双重保护 +- 其余待办按钮依然被单例 activeTodo 机制限制(只有当前序号最小的 PENDING 待办能被完成) + +## 关联字典 + +无新增字典。`ProcessStatus` 枚举取值见 PR #1318 已发布的字典项(本次不动)。 + +## 风险与回滚 + +- 纯后端校验增强,**不改接口签名/返回结构** +- 回滚方式:revert PR #1327 即可恢复到空点成功的旧行为