123 lines
3.9 KiB
Markdown
123 lines
3.9 KiB
Markdown
# 工单查询 JOIN 修复说明
|
||
|
||
## 问题描述
|
||
样品生成工单后,提示"生成成功",但工单列表中看不到新创建的工单。
|
||
|
||
## 根本原因
|
||
工单查询使用了大量的 `INNER JOIN` 连接用户表和其他关联表。当某些字段的值为 0 或不存在对应记录时(例如 `tester_id=0`),`INNER JOIN` 会过滤掉这些工单,导致查询结果为空。
|
||
|
||
## 解决方案
|
||
将所有 `INNER JOIN` 改为 `LEFT OUTER JOIN`(简写为 `outerjoin`),允许关联表的数据为空。
|
||
|
||
## 修改内容
|
||
|
||
### 文件
|
||
`ruoyi-fastapi-backend/module_admin/system/dao/test_work_order_dao.py`
|
||
|
||
### 修改的 JOIN
|
||
将以下 JOIN 从 `join` 改为 `outerjoin`:
|
||
- Creator (创建人)
|
||
- Updater (更新人)
|
||
- Tester (测试人)
|
||
- Reviewer (一审人)
|
||
- SecondTester (二审人)
|
||
- ThirdTester (三审人)
|
||
- TesterNick (测试人昵称)
|
||
- ReviewerNick (一审人昵称)
|
||
- SecondTesterNick (二审人昵称)
|
||
- ThirdTesterNick (三审人昵称)
|
||
- Eut (产品)
|
||
- Category (测试类别)
|
||
- Item (测试单元)
|
||
- ItemTemplate (测试单元模板)
|
||
|
||
### 代码对比
|
||
|
||
**修改前**:
|
||
```python
|
||
.join(Creator, TestWorkOrder.creator == Creator.user_id)
|
||
.join(Updater, TestWorkOrder.update_by == Updater.user_id)
|
||
.join(Tester, TestWorkOrder.tester_id == Tester.user_id)
|
||
# ... 其他 join
|
||
```
|
||
|
||
**修改后**:
|
||
```python
|
||
.outerjoin(Creator, TestWorkOrder.creator == Creator.user_id)
|
||
.outerjoin(Updater, TestWorkOrder.update_by == Updater.user_id)
|
||
.outerjoin(Tester, TestWorkOrder.tester_id == Tester.user_id)
|
||
# ... 其他 outerjoin
|
||
```
|
||
|
||
## 为什么会出现这个问题
|
||
|
||
### 样品生成工单时的默认值
|
||
在 `warehouse_sample_service.py` 中,创建工单时使用了以下默认值:
|
||
```python
|
||
tester_id=test_job.tester_id if (test_job and test_job.tester_id) else 0,
|
||
reviewer_id=test_job.reviewer_id if (test_job and test_job.reviewer_id) else 0,
|
||
second_tester_id=test_job.second_tester_id if (test_job and test_job.second_tester_id) else 0,
|
||
third_tester_id=test_job.third_tester_id if (test_job and test_job.third_tester_id) else 0,
|
||
```
|
||
|
||
如果 `test_job` 不存在或者相关字段为空,这些 ID 会被设置为 0。
|
||
|
||
### INNER JOIN 的行为
|
||
当使用 `INNER JOIN` 时:
|
||
```sql
|
||
SELECT * FROM test_work_order
|
||
INNER JOIN sys_user ON test_work_order.tester_id = sys_user.user_id
|
||
```
|
||
|
||
如果 `tester_id = 0` 且 `sys_user` 表中没有 `user_id = 0` 的记录,这条工单就不会出现在查询结果中。
|
||
|
||
### LEFT OUTER JOIN 的行为
|
||
当使用 `LEFT OUTER JOIN` 时:
|
||
```sql
|
||
SELECT * FROM test_work_order
|
||
LEFT OUTER JOIN sys_user ON test_work_order.tester_id = sys_user.user_id
|
||
```
|
||
|
||
即使 `tester_id = 0` 且 `sys_user` 表中没有对应记录,工单仍然会出现在查询结果中,只是关联的用户字段为 NULL。
|
||
|
||
## 验证步骤
|
||
|
||
### 1. 重启后端服务
|
||
```bash
|
||
cd ruoyi-fastapi-backend
|
||
# 停止服务
|
||
# 启动服务
|
||
```
|
||
|
||
### 2. 测试样品生成工单
|
||
1. 进入样品管理页面
|
||
2. 选择样品,点击"生成工单"
|
||
3. 填写工单信息,提交
|
||
|
||
### 3. 检查工单列表
|
||
1. 进入工单列表页面
|
||
2. **验证**: 应该能看到刚才创建的工单
|
||
3. **验证**: 工单的用户信息可能为空(如果对应的用户ID不存在)
|
||
|
||
### 4. 使用 SQL 验证
|
||
运行 `check_recent_workorders.sql` 查看最近创建的工单:
|
||
```bash
|
||
mysql -u root -p your_database < check_recent_workorders.sql
|
||
```
|
||
|
||
## 相关问题
|
||
|
||
这个问题与之前修复的"订单查询问题"类似:
|
||
- **订单查询**: 使用 INNER JOIN 连接用户表,导致某些订单不显示
|
||
- **工单查询**: 使用 INNER JOIN 连接用户表和其他表,导致某些工单不显示
|
||
|
||
**解决方案都是**: 将 INNER JOIN 改为 LEFT OUTER JOIN
|
||
|
||
## 相关文件
|
||
- `ruoyi-fastapi-backend/module_admin/system/dao/test_work_order_dao.py` ✅ 已修复
|
||
- `check_recent_workorders.sql` - 检查工单的 SQL 脚本
|
||
- `订单查询问题修复说明.md` - 类似问题的修复说明
|
||
|
||
## 完成时间
|
||
2026-01-08
|