144 lines
4.6 KiB
Markdown
144 lines
4.6 KiB
Markdown
# 订单查询问题修复说明
|
||
|
||
## 问题描述
|
||
用户反馈:工单生成订单后,提示"订单生成成功",但在订单列表的任何分页中都查询不到新生成的订单。
|
||
|
||
## 问题分析
|
||
|
||
### 症状
|
||
1. 后端日志显示订单生成成功
|
||
2. 前端显示成功提示消息
|
||
3. 但订单列表中完全看不到新订单
|
||
4. 与排序无关,在所有分页中都找不到
|
||
|
||
### 根本原因
|
||
在 `test_order_dao.py` 的 `get_test_order_list` 方法中,使用了 **INNER JOIN** 连接用户表:
|
||
|
||
```python
|
||
# 问题代码
|
||
.join(Creator, TestOrder.creator == Creator.user_id)
|
||
.join(Updater, TestOrder.update_by == Updater.user_id)
|
||
```
|
||
|
||
**INNER JOIN 的行为**:
|
||
- 只返回两个表中都有匹配记录的行
|
||
- 如果 `TestOrder.creator` 或 `TestOrder.update_by` 的用户ID在 `sys_user` 表中不存在
|
||
- 整个订单记录会被过滤掉,不会出现在查询结果中
|
||
|
||
**为什么会出现这个问题**:
|
||
- 订单创建时使用的 `creator` 和 `update_by` 可能是无效的用户ID
|
||
- 或者用户记录已被删除/禁用
|
||
- 导致 INNER JOIN 无法找到匹配的用户记录
|
||
|
||
## 解决方案
|
||
|
||
### 修改内容
|
||
将 **INNER JOIN** 改为 **LEFT JOIN (outerjoin)**:
|
||
|
||
```python
|
||
# 修复后的代码
|
||
.outerjoin(Creator, TestOrder.creator == Creator.user_id)
|
||
.outerjoin(Updater, TestOrder.update_by == Updater.user_id)
|
||
```
|
||
|
||
**LEFT JOIN 的行为**:
|
||
- 返回左表(订单表)的所有记录
|
||
- 如果右表(用户表)没有匹配记录,用户字段显示为 NULL
|
||
- 订单记录仍然会显示,只是创建人/更新人名称为空
|
||
|
||
### 修改文件
|
||
- `ruoyi-fastapi-backend/module_admin/system/dao/test_order_dao.py`
|
||
|
||
### 具体改动
|
||
```python
|
||
query = (
|
||
select(
|
||
TestOrder.id,
|
||
TestOrder.name,
|
||
Creator.nick_name.label('creator_name'),
|
||
TestOrder.create_time,
|
||
Updater.nick_name.label('update_by_name'),
|
||
TestOrder.update_time,
|
||
TestOrder.complate_count,
|
||
TestOrder.total_count,
|
||
TestOrder.state,
|
||
TestOrder.memo,
|
||
func.coalesce(work_order_count_subquery.c.work_order_count, 0).label('work_order_count')
|
||
)
|
||
.outerjoin(Creator, TestOrder.creator == Creator.user_id) # 改为 outerjoin
|
||
.outerjoin(Updater, TestOrder.update_by == Updater.user_id) # 改为 outerjoin
|
||
.outerjoin(work_order_count_subquery, TestOrder.id == work_order_count_subquery.c.test_order_id)
|
||
.where(...)
|
||
)
|
||
```
|
||
|
||
## 验证步骤
|
||
|
||
### 1. 重启后端服务
|
||
```bash
|
||
# 停止当前服务
|
||
# 重新启动后端
|
||
```
|
||
|
||
### 2. 测试订单生成
|
||
1. 进入工单页面
|
||
2. 选择多个工单(确保属于同一订单)
|
||
3. 点击"生成订单"按钮
|
||
4. 填写订单名称和说明
|
||
5. 点击确认
|
||
|
||
### 3. 验证结果
|
||
- 应该看到"订单生成成功"提示
|
||
- 订单列表第一页应该立即显示新订单
|
||
- 新订单应该在最上方(按ID降序排列)
|
||
|
||
### 4. 数据库检查(可选)
|
||
运行 `check_orders_issue.sql` 脚本检查:
|
||
```sql
|
||
-- 查看最近创建的订单
|
||
SELECT id, name, creator, create_time, update_by, update_time
|
||
FROM test_order
|
||
ORDER BY id DESC
|
||
LIMIT 20;
|
||
|
||
-- 检查是否有订单的用户ID不存在
|
||
SELECT o.id, o.name, o.creator, u.user_id, u.nick_name
|
||
FROM test_order o
|
||
LEFT JOIN sys_user u ON o.creator = u.user_id
|
||
WHERE u.user_id IS NULL;
|
||
```
|
||
|
||
## 影响范围
|
||
|
||
### 正面影响
|
||
- 所有订单都能正常显示,即使创建人/更新人信息缺失
|
||
- 提高系统健壮性,避免因用户数据问题导致订单不可见
|
||
- 符合业务需求:订单数据比用户信息更重要
|
||
|
||
### 潜在影响
|
||
- 如果用户信息缺失,订单列表中创建人/更新人列会显示为空
|
||
- 这是可接受的行为,比订单完全不显示要好
|
||
|
||
## 最佳实践建议
|
||
|
||
### 1. 数据完整性
|
||
- 在创建订单时,确保 `creator` 和 `update_by` 使用有效的用户ID
|
||
- 可以添加外键约束(如果业务允许)
|
||
|
||
### 2. 查询设计
|
||
- 对于核心业务数据(如订单),使用 LEFT JOIN 连接辅助信息(如用户)
|
||
- 对于必须存在的关联数据,使用 INNER JOIN
|
||
- 根据业务重要性选择合适的 JOIN 类型
|
||
|
||
### 3. 错误处理
|
||
- 在前端显示时,处理用户信息为空的情况
|
||
- 可以显示用户ID或"未知用户"作为后备
|
||
|
||
## 相关文件
|
||
- `ruoyi-fastapi-backend/module_admin/system/dao/test_order_dao.py` - 已修复
|
||
- `check_orders_issue.sql` - 数据库诊断脚本
|
||
- `工单生成订单功能实现进度.md` - 功能实现进度文档
|
||
|
||
## 总结
|
||
这是一个典型的 SQL JOIN 类型选择问题。通过将 INNER JOIN 改为 LEFT JOIN,确保订单数据的可见性优先于用户信息的完整性,符合业务需求。修复后,所有订单都能正常显示,问题得到彻底解决。
|