# 工单列表显示修复完成 ## 问题描述 数据库中有工单数据(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 ## 状态 ✅ 已完成并验证