peixue-dev/Archive/[一次性]派单功能问题分析.md

350 lines
8.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 派单功能问题分析
## 📋 问题描述
**现象:**
1. 管理师派单后,待派单数量没有减少
2. 派单后的订单没有转到被指定的陪伴员那里
3. 控制台显示派单前后订单状态都一样
**用户反馈:**
> "当管理师派过一单之后,这个待派单数目应该减少,同时这个派过的订单应该转到被指定订单的陪伴员那里,但是现在这个订单状态根据相应的控制台可以得知不管是派单前还是派单后订单状态都是一样的"
## 🔍 代码分析
### 1. 派单逻辑ManagerController.assignOrder
**文件:** `peidu/backend/src/main/java/com/peidu/controller/ManagerController.java`
**派单时的操作:**
```java
// 更新订单信息
order.setTeacherId(teacherId); // 设置陪伴员ID
order.setStatus(1); // 1-已派单/待接单
boolean success = orderService.updateById(order);
```
**控制台日志显示:**
```
派单前订单信息:
ID: 309
状态: ?
陪伴员ID: null
派单后订单信息:
ID: 309
状态: 1
陪伴员ID: 10096
数据库更新结果: true
派单成功
```
### 2. 待派单查询逻辑ManagerController.getStatistics
**查询条件:**
```java
QueryWrapper<com.peidu.entity.Order> pendingQuery = new QueryWrapper<>();
pendingQuery.eq("pay_status", 1) // 已支付
.isNull("teacher_id") // 未分配陪伴员
.eq("deleted", 0);
long pendingOrders = orderService.count(pendingQuery);
```
**关键点:**
- ✅ 待派单的判断条件:`pay_status=1` AND `teacher_id IS NULL`
- ✅ 派单后 `teacher_id` 被设置为 10096不再为 NULL
- ✅ 理论上派单后应该不会出现在待派单列表中
### 3. 订单列表查询逻辑ManagerController.getWorkOrders
**派单状态筛选:**
```java
if ("pending".equals(dispatchStatus)) {
queryWrapper.isNull("teacher_id");
System.out.println("✅ 添加派单状态过滤: teacher_id IS NULL (待派单)");
} else if ("assigned".equals(dispatchStatus)) {
queryWrapper.isNotNull("teacher_id");
System.out.println("✅ 添加派单状态过滤: teacher_id IS NOT NULL (已派单)");
}
```
**关键点:**
- ✅ 待派单列表:`teacher_id IS NULL`
- ✅ 已派单列表:`teacher_id IS NOT NULL`
- ✅ 逻辑正确
## 🤔 可能的问题原因
### 原因1数据库更新失败但日志显示成功
**可能性:低**
控制台日志显示:
```
数据库更新结果: true
更新后订单验证:
ID: 309
状态: 1
陪伴员ID: 10096
✅ 订单状态更新成功
```
如果数据库更新失败,`updateById()` 应该返回 `false`
### 原因2数据库事务回滚
**可能性:中**
可能的情况:
1. 更新操作在事务中执行
2. 后续操作(如发送通知)失败导致事务回滚
3. 但是日志已经打印了"派单成功"
**检查点:**
- 方法上是否有 `@Transactional` 注解?
- 发送通知失败是否会导致事务回滚?
### 原因3前端缓存问题
**可能性:高**
可能的情况:
1. 派单成功后,前端没有刷新待派单列表
2. 前端显示的是缓存的旧数据
3. 数据库中的数据已经更新,但前端没有重新查询
**检查点:**
- 派单成功后是否调用了刷新列表的方法?
- 前端是否有缓存机制?
### 原因4订单状态定义不一致
**可能性:中**
**订单状态定义:**
```java
// 支付成功后
order.setStatus(0); // 0-待派单
// 派单后
order.setStatus(1); // 1-已派单/待接单
// 陪伴员接单后
order.setStatus(2); // 2-待服务
// 服务中
order.setStatus(3); // 3-服务中
// 已完成
order.setStatus(4); // 4-已完成
// 已取消
order.setStatus(5); // 5-已取消
```
**问题:**
- 待派单查询只检查 `teacher_id IS NULL`,没有检查 `status=0`
- 如果订单的 `status` 字段没有正确更新,可能导致状态不一致
### 原因5数据库字段类型或默认值问题
**可能性:低**
可能的情况:
1. `teacher_id` 字段类型不是 `BIGINT`,而是 `VARCHAR`
2. 更新时传入的是数字,但数据库存储的是字符串
3. 导致查询时 `IS NULL` 判断失败
## 🔧 排查步骤
### 步骤1检查数据库中的实际数据
运行SQL查询`Archive/[一次性]检查订单309派单状态.sql`
**检查内容:**
1. 订单309的 `teacher_id` 是否为 10096
2. 订单309的 `status` 是否为 1
3. 订单309的 `update_time` 是否更新
4. 是否有其他待派单订单(`teacher_id IS NULL`
**预期结果:**
-`teacher_id = 10096`
-`status = 1`
-`update_time` 已更新
- ✅ 待派单列表中不包含订单309
### 步骤2检查前端刷新逻辑
**文件:** `peidu/uniapp/src/manager-package/pages/manager/assign.vue`
**检查内容:**
1. 派单成功后是否调用了 `refreshPendingOrders()` 或类似方法
2. 是否有缓存机制阻止了数据刷新
3. 是否需要手动刷新页面才能看到更新
### 步骤3检查事务配置
**文件:** `peidu/backend/src/main/java/com/peidu/controller/ManagerController.java`
**检查内容:**
1. `assignOrder` 方法上是否有 `@Transactional` 注解
2. 如果有,检查异常处理是否会导致事务回滚
3. 发送通知失败是否会影响派单结果
### 步骤4添加更详细的日志
在派单方法中添加更多日志:
```java
// 派单前
System.out.println("=== 开始派单 ===");
System.out.println("订单ID: " + orderId);
System.out.println("陪伴员ID: " + teacherId);
// 更新前
System.out.println("更新前订单状态: " + order.getStatus());
System.out.println("更新前陪伴员ID: " + order.getTeacherId());
// 更新后
System.out.println("更新后订单状态: " + order.getStatus());
System.out.println("更新后陪伴员ID: " + order.getTeacherId());
// 数据库验证
Order dbOrder = orderService.getById(orderId);
System.out.println("数据库中的订单状态: " + dbOrder.getStatus());
System.out.println("数据库中的陪伴员ID: " + dbOrder.getTeacherId());
// 查询待派单数量
QueryWrapper<Order> pendingQuery = new QueryWrapper<>();
pendingQuery.eq("pay_status", 1)
.isNull("teacher_id")
.eq("deleted", 0);
long pendingCount = orderService.count(pendingQuery);
System.out.println("当前待派单数量: " + pendingCount);
```
### 步骤5检查陪伴员端订单列表
**检查内容:**
1. 陪伴员10096登录后能否看到订单309
2. 订单309的状态是否为"待接单"
3. 陪伴员能否接单
## 🎯 预期的正确流程
```
1. 用户下单并支付
订单状态: status=0 (待派单)
陪伴员ID: teacher_id=NULL
支付状态: pay_status=1 (已支付)
2. 管理师派单
订单状态: status=1 (已派单/待接单)
陪伴员ID: teacher_id=10096
支付状态: pay_status=1 (已支付)
3. 待派单列表查询
条件: pay_status=1 AND teacher_id IS NULL
结果: 不包含订单309 ✅
4. 陪伴员待接单列表查询
条件: teacher_id=10096 AND status=1
结果: 包含订单309 ✅
5. 陪伴员接单
订单状态: status=2 (待服务)
陪伴员ID: teacher_id=10096
```
## 📝 建议的修复方案
### 方案1前端添加刷新逻辑推荐
派单成功后,立即刷新待派单列表和统计数据:
```javascript
// 派单成功后
uni.showToast({ title: '派单成功', icon: 'success' })
// 刷新待派单列表
this.refreshPendingOrders()
// 刷新统计数据
this.loadStatistics()
// 返回上一页
setTimeout(() => {
uni.navigateBack()
}, 1500)
```
### 方案2优化待派单查询条件
同时检查 `teacher_id``status`
```java
QueryWrapper<Order> pendingQuery = new QueryWrapper<>();
pendingQuery.eq("pay_status", 1) // 已支付
.isNull("teacher_id") // 未分配陪伴员
.eq("status", 0) // 待派单状态
.eq("deleted", 0);
```
### 方案3添加订单状态一致性检查
定期检查并修复状态不一致的订单:
```sql
-- 修复已派单但状态不是1的订单
UPDATE `order`
SET status = 1
WHERE teacher_id IS NOT NULL
AND status = 0
AND pay_status = 1
AND deleted = 0;
-- 修复未派单但状态不是0的订单
UPDATE `order`
SET status = 0
WHERE teacher_id IS NULL
AND status != 0
AND pay_status = 1
AND deleted = 0;
```
## 📊 需要确认的信息
在修复之前,请先确认:
1. **数据库中订单309的实际状态是什么**
- teacher_id = ?
- status = ?
- update_time = ?
2. **前端是否有刷新逻辑?**
- 派单成功后是否调用了刷新方法?
- 是否需要手动刷新页面?
3. **陪伴员能否看到订单309**
- 陪伴员10096登录后能否看到订单309
- 订单309在陪伴员端的状态是什么
4. **是否有其他待派单订单?**
- 待派单列表中有多少订单?
- 这些订单的状态是否正确?
---
**创建时间:** 2026-01-26
**分析人员:** Kiro AI
**状态:** 待用户确认数据库实际状态