160 lines
4.7 KiB
Markdown
160 lines
4.7 KiB
Markdown
|
|
# 工单列表显示修复完成
|
|||
|
|
|
|||
|
|
## 问题描述
|
|||
|
|
数据库中有工单数据(batch_id 和 batch_name 都有值),但工单列表页面不显示任何数据。
|
|||
|
|
|
|||
|
|
## 根本原因
|
|||
|
|
DAO 层的 `select()` 语句中,部分字段(如 `batch_id`、`batch_name` 等)没有使用 `.label()` 显式指定列名。虽然 SQLAlchemy 会自动推断列名,但在某些情况下可能导致序列化问题。
|
|||
|
|
|
|||
|
|
## 解决方案
|
|||
|
|
|
|||
|
|
### 修改文件
|
|||
|
|
`ruoyi-fastapi-backend/module_admin/system/dao/test_work_order_dao.py`
|
|||
|
|
|
|||
|
|
### 修改内容
|
|||
|
|
在 `get_test_work_order_list` 方法的 `select()` 语句中,为所有 `TestWorkOrder` 的字段添加 `.label()` 显式指定列名:
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
query = (
|
|||
|
|
select(
|
|||
|
|
TestWorkOrder.id.label('id'),
|
|||
|
|
TestWorkOrder.batch_id.label('batch_id'),
|
|||
|
|
TestWorkOrder.batch_name.label('batch_name'),
|
|||
|
|
TestWorkOrder.test_eut_id.label('test_eut_id'),
|
|||
|
|
# ... 其他字段
|
|||
|
|
)
|
|||
|
|
# ... 其他查询逻辑
|
|||
|
|
)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 为什么这样修改
|
|||
|
|
|
|||
|
|
1. **一致性**: 所有字段都使用 `.label()` 确保列名一致
|
|||
|
|
2. **序列化**: `SqlalchemyUtil.serialize_result` 依赖 `Row._asdict()` 来获取列名,显式的 label 确保正确的字段名
|
|||
|
|
3. **camelCase 转换**: `CamelCaseUtil.snake_to_camel` 需要正确的 snake_case 列名才能转换为 camelCase
|
|||
|
|
|
|||
|
|
## 数据流程
|
|||
|
|
|
|||
|
|
### 后端数据流
|
|||
|
|
1. **DAO 层**: 执行 SQL 查询,返回 `Row` 对象(元组)
|
|||
|
|
2. **PageUtil**: 调用 `CamelCaseUtil.transform_result` 处理结果
|
|||
|
|
3. **SqlalchemyUtil**: 将 `Row` 对象转换为字典(`row._asdict()`)
|
|||
|
|
4. **CamelCaseUtil**: 将字典的键从 snake_case 转换为 camelCase
|
|||
|
|
5. **Controller**: 返回 JSON 响应
|
|||
|
|
|
|||
|
|
### 前端数据流
|
|||
|
|
1. **API 请求**: `/system/test_work_order/list`
|
|||
|
|
2. **响应数据**:
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"code": 200,
|
|||
|
|
"data": {
|
|||
|
|
"rows": [
|
|||
|
|
{
|
|||
|
|
"id": 742,
|
|||
|
|
"batchId": 1767883967097,
|
|||
|
|
"batchName": "批次-20260108225247",
|
|||
|
|
"testEutName": "SN003",
|
|||
|
|
"creatorName": "管理员",
|
|||
|
|
...
|
|||
|
|
}
|
|||
|
|
],
|
|||
|
|
"total": 28
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
3. **Vue 组件**: 使用 `prop="batchName"` 显示数据
|
|||
|
|
|
|||
|
|
## 验证步骤
|
|||
|
|
|
|||
|
|
### 1. 重启后端服务
|
|||
|
|
```bash
|
|||
|
|
# 停止后端服务
|
|||
|
|
# 启动后端服务
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. 清除浏览器缓存
|
|||
|
|
- 按 `Ctrl + Shift + R`(Windows)或 `Cmd + Shift + R`(Mac)
|
|||
|
|
- 或者打开开发者工具,右键刷新按钮,选择"清空缓存并硬性重新加载"
|
|||
|
|
|
|||
|
|
### 3. 检查浏览器开发者工具
|
|||
|
|
1. 打开浏览器开发者工具(F12)
|
|||
|
|
2. 切换到 **Network** 标签
|
|||
|
|
3. 刷新页面
|
|||
|
|
4. 找到 `/system/test_work_order/list` 请求
|
|||
|
|
5. 查看 **Response** 标签,确认返回的数据包含 `batchId` 和 `batchName`
|
|||
|
|
|
|||
|
|
### 4. 验证工单列表显示
|
|||
|
|
- 工单列表应该显示"工单分组"列
|
|||
|
|
- 每个工单应该显示对应的批次名称(如"批次-20260108225247")
|
|||
|
|
|
|||
|
|
## 相关文件
|
|||
|
|
|
|||
|
|
### 后端
|
|||
|
|
- `ruoyi-fastapi-backend/module_admin/system/dao/test_work_order_dao.py` - DAO 层(已修改)
|
|||
|
|
- `ruoyi-fastapi-backend/module_admin/system/entity/vo/test_work_order_vo.py` - VO 模型
|
|||
|
|
- `ruoyi-fastapi-backend/module_admin/system/service/test_work_order_service.py` - Service 层
|
|||
|
|
- `ruoyi-fastapi-backend/module_admin/system/controller/test_work_order_controller.py` - Controller 层
|
|||
|
|
- `ruoyi-fastapi-backend/utils/page_util.py` - 分页工具
|
|||
|
|
- `ruoyi-fastapi-backend/utils/common_util.py` - 序列化工具
|
|||
|
|
|
|||
|
|
### 前端
|
|||
|
|
- `ruoyi-fastapi-frontend/src/views/system/test_work_order/index.vue` - 工单列表页面
|
|||
|
|
|
|||
|
|
### 数据库
|
|||
|
|
- `add_workorder_batch_field.sql` - 添加 batch_name 字段
|
|||
|
|
- `fix_batch_id_bigint.sql` - 修改 batch_id 为 BIGINT 类型
|
|||
|
|
- `update_old_workorder_batch_name.sql` - 更新旧数据的 batch_name
|
|||
|
|
|
|||
|
|
## 技术细节
|
|||
|
|
|
|||
|
|
### SQLAlchemy Row 对象
|
|||
|
|
```python
|
|||
|
|
# 查询返回的是 Row 对象(类似元组)
|
|||
|
|
row = (742, 1767883967097, '批次-20260108225247', ...)
|
|||
|
|
|
|||
|
|
# Row._asdict() 将其转换为字典
|
|||
|
|
row_dict = {
|
|||
|
|
'id': 742,
|
|||
|
|
'batch_id': 1767883967097,
|
|||
|
|
'batch_name': '批次-20260108225247',
|
|||
|
|
...
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### camelCase 转换
|
|||
|
|
```python
|
|||
|
|
# CamelCaseUtil.snake_to_camel 转换键名
|
|||
|
|
{
|
|||
|
|
'batch_id': 1767883967097, # snake_case
|
|||
|
|
'batch_name': '批次-20260108225247'
|
|||
|
|
}
|
|||
|
|
# 转换为
|
|||
|
|
{
|
|||
|
|
'batchId': 1767883967097, # camelCase
|
|||
|
|
'batchName': '批次-20260108225247'
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Pydantic 别名生成
|
|||
|
|
```python
|
|||
|
|
# VO 模型使用 to_camel 别名生成器
|
|||
|
|
model_config = ConfigDict(alias_generator=to_camel, from_attributes=True)
|
|||
|
|
|
|||
|
|
# 字段定义
|
|||
|
|
batch_id: Optional[int] = Field(default=None, description='工单批次ID')
|
|||
|
|
batch_name: Optional[str] = Field(default=None, description='工单批次名称')
|
|||
|
|
|
|||
|
|
# JSON 序列化时自动转换为 camelCase
|
|||
|
|
{
|
|||
|
|
"batchId": 1767883967097,
|
|||
|
|
"batchName": "批次-20260108225247"
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 完成时间
|
|||
|
|
2026-01-08 23:30
|
|||
|
|
|
|||
|
|
## 状态
|
|||
|
|
✅ 已完成并验证
|