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

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

238 lines
5.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 菜单为空问题最终修复方案
## 问题根本原因
前端显示"生成菜单数量: 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. ✅ 清除浏览器缓存
现在登录后应该能正常看到菜单了!