# 派单功能根本原因和修复方案 ## 🔍 根本原因确认 通过SQL查询结果,我找到了问题的根本原因: ### 1. 订单309派单失败 **数据库实际状态:** ``` id = 309 order_no = TEST20260121160442 teacher_id = NULL ❌ 应该是10096 status = -1 ❌ 应该是1 pay_status = 1 ✅ 已支付 ``` **结论:派单根本没有成功!数据库中的数据没有更新。** ### 2. 大量订单状态异常 从SQL查询结果可以看到: - **78个订单的 `teacher_id = NULL` 但 `status = 1`** ❌ 异常 - **50个订单的 `status = -1`** ❌ 未知状态 - 只有4个订单的 `status = 0` (待派单) ✅ 正常 **正常情况应该是:** - `teacher_id = NULL` → `status = 0` (待派单) - `teacher_id != NULL` → `status = 1` (已派单/待接单) ### 3. 订单状态统计 ``` status = -1: 50个订单 (未知状态) status = 0: 4个订单 (待派单) ✅ status = 1: 78个订单 (已派单/待接单) ⚠️ 但很多teacher_id为NULL status = 2: 3个订单 (待服务) status = 3: 87个订单 (服务中) status = 4: 35个订单 (已完成) ``` ## 🚨 问题分析 ### 问题1:派单更新失败的原因 虽然后端日志显示"派单成功",但数据库没有更新。可能的原因: #### 原因A:MyBatis-Plus逻辑删除机制 Order实体类有 `@TableLogic` 注解: ```java @TableLogic private Integer deleted; ``` 这意味着: 1. MyBatis-Plus在更新时会自动添加 `WHERE deleted = 0` 条件 2. 如果订单的 `deleted` 字段不是0,更新会失败 3. 但 `updateById()` 仍然返回 `true`(这是MyBatis-Plus的一个已知问题) #### 原因B:订单初始状态设置错误 从数据可以看到,很多订单在创建时就被设置为 `status=1` 或 `status=-1`,但 `teacher_id=NULL`。 这说明在订单创建或支付成功时,状态设置逻辑有问题。 #### 原因C:并发更新冲突 如果多个请求同时更新同一个订单,可能导致更新失败。 ### 问题2:待派单查询逻辑不完善 当前待派单查询条件: ```java pendingQuery.eq("pay_status", 1) // 已支付 .isNull("teacher_id") // 未分配陪伴员 .eq("deleted", 0); ``` **问题:** - 没有检查 `status` 字段 - 导致 `status=1` 但 `teacher_id=NULL` 的异常订单也被计入待派单 **正确的查询条件应该是:** ```java pendingQuery.eq("pay_status", 1) // 已支付 .eq("status", 0) // 待派单状态 .isNull("teacher_id") // 未分配陪伴员 .eq("deleted", 0); ``` ## 🔧 修复方案 ### 方案1:修复派单逻辑(立即执行) #### 步骤1:添加更详细的日志和错误处理 ```java @ApiOperation("派单") @PostMapping("/assign") public Result assignOrder(@RequestBody Map requestParams) { // ... 参数解析 ... try { com.peidu.entity.Order order = orderService.getById(orderId); if (order == null) { return Result.error("订单不存在"); } // 🔥 检查订单状态 if (order.getDeleted() != null && order.getDeleted() == 1) { return Result.error("订单已删除,无法派单"); } if (order.getPayStatus() == null || order.getPayStatus() != 1) { return Result.error("订单未支付,无法派单"); } System.out.println("派单前订单信息:"); System.out.println(" ID: " + order.getId()); System.out.println(" 状态: " + order.getStatus()); System.out.println(" 陪伴员ID: " + order.getTeacherId()); System.out.println(" 删除标记: " + order.getDeleted()); // 更新订单信息 order.setTeacherId(teacherId); order.setStatus(1); // 1-已派单/待接单 // 🔥 使用LambdaUpdateWrapper确保更新条件正确 LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>(); updateWrapper.eq(com.peidu.entity.Order::getId, orderId) .eq(com.peidu.entity.Order::getDeleted, 0); // 确保未删除 updateWrapper.set(com.peidu.entity.Order::getTeacherId, teacherId) .set(com.peidu.entity.Order::getStatus, 1); boolean success = orderService.update(updateWrapper); System.out.println("数据库更新结果: " + success); if (!success) { System.out.println("❌ 数据库更新失败"); return Result.error("派单失败:数据库更新失败"); } // 🔥 验证更新结果 com.peidu.entity.Order updatedOrder = orderService.getById(orderId); System.out.println("更新后订单验证:"); System.out.println(" ID: " + updatedOrder.getId()); System.out.println(" 状态: " + updatedOrder.getStatus()); System.out.println(" 陪伴员ID: " + updatedOrder.getTeacherId()); System.out.println(" 删除标记: " + updatedOrder.getDeleted()); // 🔥 验证更新是否真的成功 if (updatedOrder.getTeacherId() == null || !updatedOrder.getTeacherId().equals(teacherId)) { System.out.println("❌ 验证失败:陪伴员ID未更新"); return Result.error("派单失败:陪伴员ID未更新"); } if (updatedOrder.getStatus() == null || updatedOrder.getStatus() != 1) { System.out.println("❌ 验证失败:订单状态未更新"); return Result.error("派单失败:订单状态未更新"); } System.out.println("✅ 订单状态更新成功"); // ... 发送通知 ... return Result.success(true, "派单成功"); } catch (Exception e) { e.printStackTrace(); return Result.error("派单失败:" + e.getMessage()); } } ``` #### 步骤2:修复待派单查询条件 ```java // 待派单订单数(已支付且状态为0的订单) QueryWrapper pendingQuery = new QueryWrapper<>(); pendingQuery.eq("pay_status", 1) // 已支付 .eq("status", 0) // 🔥 添加:待派单状态 .isNull("teacher_id") // 未分配陪伴员 .eq("deleted", 0); long pendingOrders = orderService.count(pendingQuery); ``` ### 方案2:修复历史数据(立即执行) 创建SQL脚本修复状态不一致的订单: ```sql -- 1. 修复:已派单但状态不是1的订单 UPDATE `order` SET status = 1 WHERE teacher_id IS NOT NULL AND status != 1 AND pay_status = 1 AND deleted = 0; -- 2. 修复:未派单但状态不是0的订单 UPDATE `order` SET status = 0 WHERE teacher_id IS NULL AND status NOT IN (0, 4, 5) -- 排除已完成和已取消 AND pay_status = 1 AND deleted = 0; -- 3. 检查修复结果 SELECT status, COUNT(*) as count, CASE WHEN status = 0 THEN '待派单' WHEN status = 1 THEN '已派单/待接单' WHEN status = 2 THEN '待服务' WHEN status = 3 THEN '服务中' WHEN status = 4 THEN '已完成' WHEN status = 5 THEN '已取消' ELSE '未知状态' END as status_name FROM `order` WHERE pay_status = 1 AND deleted = 0 GROUP BY status ORDER BY status; -- 4. 检查是否还有异常订单 SELECT id, order_no, teacher_id, status, pay_status, CASE WHEN teacher_id IS NULL AND status != 0 THEN '❌ 异常:未派单但状态不是0' WHEN teacher_id IS NOT NULL AND status = 0 THEN '❌ 异常:已派单但状态是0' ELSE '✅ 正常' END as check_result FROM `order` WHERE pay_status = 1 AND deleted = 0 AND ( (teacher_id IS NULL AND status NOT IN (0, 4, 5)) OR (teacher_id IS NOT NULL AND status = 0) ) ORDER BY create_time DESC; ``` ### 方案3:优化订单状态管理(长期优化) #### 3.1 定义清晰的订单状态枚举 ```java public enum OrderStatus { PENDING_ASSIGN(0, "待派单"), // 已支付,等待管理师派单 PENDING_ACCEPT(1, "待接单"), // 已派单,等待陪伴员接单 PENDING_SERVICE(2, "待服务"), // 已接单,等待服务开始 IN_SERVICE(3, "服务中"), // 服务进行中 COMPLETED(4, "已完成"), // 服务已完成 CANCELLED(5, "已取消"); // 订单已取消 private final int code; private final String desc; OrderStatus(int code, String desc) { this.code = code; this.desc = desc; } public int getCode() { return code; } public String getDesc() { return desc; } } ``` #### 3.2 添加订单状态转换验证 ```java public class OrderStatusValidator { /** * 验证订单状态转换是否合法 */ public static boolean isValidTransition(Integer fromStatus, Integer toStatus) { if (fromStatus == null || toStatus == null) { return false; } // 定义合法的状态转换 Map> validTransitions = new HashMap<>(); validTransitions.put(0, Arrays.asList(1, 5)); // 待派单 → 待接单/已取消 validTransitions.put(1, Arrays.asList(2, 0, 5)); // 待接单 → 待服务/待派单(拒单)/已取消 validTransitions.put(2, Arrays.asList(3, 5)); // 待服务 → 服务中/已取消 validTransitions.put(3, Arrays.asList(4)); // 服务中 → 已完成 validTransitions.put(4, Arrays.asList()); // 已完成 → 无 validTransitions.put(5, Arrays.asList()); // 已取消 → 无 List allowedNextStatuses = validTransitions.get(fromStatus); return allowedNextStatuses != null && allowedNextStatuses.contains(toStatus); } } ``` #### 3.3 添加订单状态一致性检查 ```java /** * 检查订单状态是否一致 */ public boolean checkOrderConsistency(Order order) { // 检查1:teacher_id和status的一致性 if (order.getTeacherId() == null && order.getStatus() != 0 && order.getStatus() != 4 && order.getStatus() != 5) { log.warn("订单{}状态不一致:teacher_id为空但status不是0/4/5", order.getId()); return false; } if (order.getTeacherId() != null && order.getStatus() == 0) { log.warn("订单{}状态不一致:teacher_id不为空但status是0", order.getId()); return false; } // 检查2:pay_status和status的一致性 if (order.getPayStatus() != 1 && order.getStatus() != 0 && order.getStatus() != 5) { log.warn("订单{}状态不一致:未支付但status不是0或5", order.getId()); return false; } return true; } ``` ## 📝 修复步骤 ### 立即执行(修复当前问题) 1. **修复历史数据** - 运行SQL脚本修复状态不一致的订单 - 验证修复结果 2. **修改派单逻辑** - 使用 `LambdaUpdateWrapper` 替代 `updateById()` - 添加更新结果验证 - 添加详细的错误日志 3. **修改待派单查询条件** - 添加 `status=0` 条件 - 确保只查询真正待派单的订单 4. **测试验证** - 重新测试派单功能 - 验证待派单数量是否正确 - 验证陪伴员能否看到派单 ### 长期优化(提升系统稳定性) 1. **添加订单状态枚举** 2. **添加状态转换验证** 3. **添加状态一致性检查** 4. **添加单元测试** ## 🎯 预期结果 修复后: - ✅ 派单成功后,订单的 `teacher_id` 和 `status` 正确更新 - ✅ 待派单数量正确减少 - ✅ 陪伴员能看到派单的订单 - ✅ 不再有状态不一致的订单 --- **创建时间:** 2026-01-26 **分析人员:** Kiro AI **状态:** 待执行修复