ETest-Vue-FastAPI/订单查询问题修复说明.md

4.6 KiB
Raw Permalink Blame History

订单查询问题修复说明

问题描述

用户反馈:工单生成订单后,提示"订单生成成功",但在订单列表的任何分页中都查询不到新生成的订单。

问题分析

症状

  1. 后端日志显示订单生成成功
  2. 前端显示成功提示消息
  3. 但订单列表中完全看不到新订单
  4. 与排序无关,在所有分页中都找不到

根本原因

test_order_dao.pyget_test_order_list 方法中,使用了 INNER JOIN 连接用户表:

# 问题代码
.join(Creator, TestOrder.creator == Creator.user_id)
.join(Updater, TestOrder.update_by == Updater.user_id)

INNER JOIN 的行为

  • 只返回两个表中都有匹配记录的行
  • 如果 TestOrder.creatorTestOrder.update_by 的用户ID在 sys_user 表中不存在
  • 整个订单记录会被过滤掉,不会出现在查询结果中

为什么会出现这个问题

  • 订单创建时使用的 creatorupdate_by 可能是无效的用户ID
  • 或者用户记录已被删除/禁用
  • 导致 INNER JOIN 无法找到匹配的用户记录

解决方案

修改内容

INNER JOIN 改为 LEFT JOIN (outerjoin)

# 修复后的代码
.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

具体改动

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. 重启后端服务

# 停止当前服务
# 重新启动后端

2. 测试订单生成

  1. 进入工单页面
  2. 选择多个工单(确保属于同一订单)
  3. 点击"生成订单"按钮
  4. 填写订单名称和说明
  5. 点击确认

3. 验证结果

  • 应该看到"订单生成成功"提示
  • 订单列表第一页应该立即显示新订单
  • 新订单应该在最上方按ID降序排列

4. 数据库检查(可选)

运行 check_orders_issue.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. 数据完整性

  • 在创建订单时,确保 creatorupdate_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确保订单数据的可见性优先于用户信息的完整性符合业务需求。修复后所有订单都能正常显示问题得到彻底解决。