admin/菜单为空问题最终修复方案.md
lvfengfree b92e1119ae fix: 修复菜单为空问题 - 移除后端过滤home路由的错误逻辑
- 修复RouteService中错误过滤home路由的问题
- 后端现在正确返回所有用户有权限的路由
- 添加设备管理相关功能(列表、在线监控、电源管理、远程监控)
- 添加详细的修复文档和重启脚本
- 更新权限配置脚本

问题根源:后端代码中有逻辑会过滤掉home路由,导致前端收到空数组,无法生成菜单
解决方案:移除过滤home路由的逻辑,让后端返回所有有权限的路由
2026-03-01 09:50:19 +08:00

5.7 KiB
Raw Blame History

菜单为空问题最终修复方案

问题根本原因

前端显示"生成菜单数量: 0 去重后: 0"的根本原因是:

后端 RouteService 错误地过滤掉了 home 路由

代码中有这样的逻辑:

// 排除 home 路由,它应该由前端的 constantRoutes 管理
if ("home".equals(route.getName())) {
    return false;
}

这导致即使角色配置了 home 权限,后端也不会返回任何路由给前端,因为:

  1. 后端过滤掉了 home
  2. 其他路由(如 device、user-manage也被过滤掉了
  3. 最终返回空数组给前端
  4. 前端收到空数组,无法生成菜单

已修复的问题

我已经修改了 backend/src/main/java/com/soybean/admin/service/RouteService.java,移除了过滤 home 路由的逻辑。

现在后端会正确返回所有用户有权限的路由,包括 home。

修复步骤

步骤1重启后端服务必须

非常重要! 代码已修改,必须重启后端才能生效!

# 停止当前运行的后端服务Ctrl+C

# 重新启动
cd backend
mvn spring-boot:run

或者在 IDE 中重启应用。

步骤2清除浏览器缓存

方法1完全清除缓存推荐

  1. Ctrl + Shift + Delete
  2. 选择"全部时间"
  3. 勾选"缓存的图片和文件"
  4. 点击"清除数据"

方法2使用无痕模式

  • Chrome: Ctrl + Shift + N
  • Edge: Ctrl + Shift + P
  • Firefox: Ctrl + Shift + P

步骤3重新登录测试

  1. 打开浏览器开发者工具F12
  2. 切换到 Console 标签
  3. 访问登录页面
  4. 使用 admin/admin123 登录
  5. 观察控制台输出

预期结果:

生成菜单数量: 10 去重后: 10

(具体数量取决于角色权限)

步骤4检查 Network 请求

在开发者工具的 Network 标签中:

  1. 找到 /route/getUserRoutes 请求
  2. 查看 Response

正确的响应应该包含路由数据:

{
  "code": "0000",
  "msg": "success",
  "data": {
    "routes": [
      {
        "id": "home",
        "name": "home",
        "path": "/home",
        "component": "layout.base$view.home",
        "meta": {
          "title": "首页",
          "i18nKey": "route.home",
          "icon": "mdi:home",
          "order": 1
        }
      },
      {
        "id": "device",
        "name": "device",
        "path": "/device",
        "component": "layout.base",
        "meta": {
          "title": "设备管理",
          "i18nKey": "route.device",
          "icon": "mdi:devices",
          "order": 2
        },
        "children": [...]
      }
    ],
    "home": "home"
  }
}

验证修复

1. 后端日志验证

重启后端后,登录时应该看到:

=== 用户路由权限调试 ===
用户ID: 1
用户角色: R_SUPER,R_ADMIN
查询到的角色数量: 2
角色: R_SUPER - 超级管理员
配置的菜单: home,device,device_list,device_online,...
允许访问的菜单: [home, device, device_list, ...]
数据库中的路由总数: 21
路由: home - 是否允许: true
路由: device - 是否允许: true
...
过滤后的路由数量: 21
最终返回的路由数量: 5
根路由: home - 子路由数: 0
根路由: device - 子路由数: 5
...

关键点:

  • 路由: home - 是否允许: true ← home 不再被跳过
  • 过滤后的路由数量: 21 ← 不是 0
  • 最终返回的路由数量: 5 ← 返回了根路由

2. 前端控制台验证

生成菜单数量: 10 去重后: 10

不再是 0

3. 界面验证

  • 左侧菜单栏显示所有有权限的菜单
  • 不再跳转到 403 页面
  • 可以正常访问各个页面

如果还是有问题

问题A后端日志显示"过滤后的路由数量: 0"

原因: 角色没有配置菜单权限

解决:

# 运行权限修复脚本
fix_403_complete.bat

# 重启后端

问题B后端返回路由但前端还是显示"生成菜单数量: 0"

原因: 浏览器缓存问题

解决:

  1. 完全清除浏览器缓存Ctrl+Shift+Delete选择全部时间
  2. 关闭所有浏览器窗口
  3. 重新打开浏览器
  4. 使用无痕模式测试

问题C某些菜单看不到

原因: 路由名称不匹配

检查:

-- 查看角色配置的菜单
SELECT role_code, menus FROM sys_role WHERE role_code = 'R_SUPER';

-- 查看数据库中的路由名称
SELECT name, path FROM sys_route WHERE status = 1 ORDER BY order_num;

确保角色的 menus 字段中的名称与 sys_route 表中的 name 字段完全一致。

技术说明

为什么之前要过滤 home

之前的设计思路是:

  • home 是常量路由,应该由前端的 constantRoutes 管理
  • 后端只返回需要权限控制的路由

但这个设计有问题:

  1. 前端的 constantRoutes 只包含 login、403、404、500 等特殊页面
  2. home 实际上需要权限控制(不同角色可能有不同的首页)
  3. 在动态路由模式下,所有业务路由都应该由后端返回

正确的设计

在动态路由模式下:

  • constantRouteslogin、403、404、500 等不需要权限的特殊页面
  • authRoutes:所有需要权限的业务路由,包括 home

后端根据用户角色过滤路由,前端直接使用后端返回的路由,不再进行二次权限检查。

相关文件

  • backend/src/main/java/com/soybean/admin/service/RouteService.java - 已修复
  • src/store/modules/route/index.ts - 前端路由存储
  • src/router/guard/route.ts - 前端路由守卫
  • fix_403_complete.sql - 权限修复脚本

总结

修复的核心是:

  1. 移除后端过滤 home 路由的逻辑
  2. 确保角色配置了正确的菜单权限
  3. 重启后端服务
  4. 清除浏览器缓存

现在登录后应该能正常看到菜单了!