# 菜单为空问题最终修复方案 ## 问题根本原因 前端显示"生成菜单数量: 0 去重后: 0"的根本原因是: **后端 RouteService 错误地过滤掉了 home 路由** 代码中有这样的逻辑: ```java // 排除 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:重启后端服务(必须!) **非常重要!** 代码已修改,必须重启后端才能生效! ```bash # 停止当前运行的后端服务(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 **正确的响应应该包含路由数据:** ```json { "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" **原因:** 角色没有配置菜单权限 **解决:** ```bash # 运行权限修复脚本 fix_403_complete.bat # 重启后端 ``` ### 问题B:后端返回路由,但前端还是显示"生成菜单数量: 0" **原因:** 浏览器缓存问题 **解决:** 1. 完全清除浏览器缓存(Ctrl+Shift+Delete,选择全部时间) 2. 关闭所有浏览器窗口 3. 重新打开浏览器 4. 使用无痕模式测试 ### 问题C:某些菜单看不到 **原因:** 路由名称不匹配 **检查:** ```sql -- 查看角色配置的菜单 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. 在动态路由模式下,所有业务路由都应该由后端返回 ### 正确的设计 在动态路由模式下: - **constantRoutes**:login、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. ✅ 清除浏览器缓存 现在登录后应该能正常看到菜单了!