# 菜单权限与操作权限分离修复报告 ## 问题描述 用户反映:用户"12.27新增姓名"设置了用户专属权限后,不仅操作按钮被隐藏了,连菜单也全部隐藏了。用户要求菜单权限和操作权限应该是两个独立的东西: - **菜单权限**:控制左侧菜单栏的显示/隐藏(如"装车订单"菜单项) - **操作权限**:控制页面内操作按钮的显示/隐藏(如"编辑"、"删除"等按钮) ## 问题根本原因 ### 1. 权限类型混淆 我之前的修改将菜单权限和操作权限混淆了: - **菜单权限**:应该只包含菜单项(type=0,1),用于控制左侧菜单栏 - **操作权限**:应该包含操作按钮(type=2),用于控制页面内的按钮 ### 2. getUserMenus API 的问题 **文件**:`tradeCattle/aiotagro-cattle-trade/src/main/java/com/aiotagro/cattletrade/business/service/impl/LoginServiceImpl.java` **错误的修改**(第147-171行): ```java @Override public AjaxResult getUserMenus() { // 使用修改后的权限查询逻辑(优先使用用户专属权限) List permissions = queryUserPermissions(userId, user.getRoleId()); // 根据权限查询菜单 List menus; if (permissions.contains(RoleConstants.ALL_PERMISSION)) { // 超级管理员:返回所有菜单 menus = menuMapper.selectList(null); } else { // 普通用户:根据权限查询菜单 menus = menuMapper.selectMenusByPermissions(permissions); } } ``` **问题**:`queryUserPermissions` 方法返回的是**所有权限**(包括操作按钮权限),但是 `getUserMenus` API 应该只返回**菜单权限**。 ### 3. 权限查询逻辑错误 `queryUserPermissions` 方法会返回所有类型的权限(菜单+操作按钮),但是菜单权限查询应该只返回菜单项,不包含操作按钮。 ## 修复方案 ### 1. 分离菜单权限和操作权限查询 创建两个独立的查询方法: - **`queryUserMenus`**:专门查询菜单权限(只包含菜单项,不包含操作按钮) - **`queryUserPermissions`**:专门查询操作权限(包含所有权限,用于按钮控制) ### 2. 修改 getUserMenus API **修改文件**:`tradeCattle/aiotagro-cattle-trade/src/main/java/com/aiotagro/cattletrade/business/service/impl/LoginServiceImpl.java` **修改内容**: ```java @Override public AjaxResult getUserMenus() { Integer userId = SecurityUtil.getCurrentUserId(); // 获取当前用户的角色ID SysUser user = userMapper.selectById(userId); if (user == null) { return AjaxResult.error("用户不存在"); } // 菜单权限查询:优先使用用户专属菜单权限,否则使用角色菜单权限 List menus = queryUserMenus(userId, user.getRoleId()); log.info("=== 用户 {} 菜单查询结果,菜单数量: {}", userId, menus.size()); return AjaxResult.success("查询成功", menus); } ``` ### 3. 添加 queryUserMenus 方法 **新增方法**: ```java /** * 查询用户菜单权限(优先使用用户专属菜单权限) * * @param userId 用户ID * @param roleId 角色ID * @return 菜单列表 */ private List queryUserMenus(Integer userId, Integer roleId) { if (userId == null || roleId == null) { return Collections.emptyList(); } // 1. 先查询用户专属菜单权限(只查询菜单,不查询操作按钮) List userMenus = sysUserMenuMapper.selectMenusByUserId(userId); if (userMenus != null && !userMenus.isEmpty()) { // 过滤掉操作按钮(type=2),只保留菜单(type=0,1) List filteredMenus = userMenus.stream() .filter(menu -> menu.getType() != 2) // 排除操作按钮 .collect(Collectors.toList()); if (!filteredMenus.isEmpty()) { log.info("=== 用户 {} 使用专属菜单权限,菜单数量: {}", userId, filteredMenus.size()); return filteredMenus; } } // 2. 如果没有专属菜单权限,使用角色菜单权限 if (roleId.equals(RoleConstants.SUPER_ADMIN_ROLE_ID)) { log.info("=== 超级管理员用户 {} 使用所有菜单权限(无专属菜单权限)", userId); return menuMapper.selectList(null); } // 3. 普通角色菜单权限 log.info("=== 用户 {} 使用角色菜单权限,roleId: {}", userId, roleId); return menuMapper.queryMenusByUserId(userId); } ``` ## 权限分离逻辑 ### 菜单权限查询流程 ``` 用户登录 → getUserMenus() → queryUserMenus() → 只查询菜单项(type≠2)→ 控制左侧菜单栏 ``` ### 操作权限查询流程 ``` 用户登录 → queryUserPermissions() → 查询所有权限(包括操作按钮)→ 控制页面内按钮 ``` ## 权限类型说明 ### 菜单类型(type字段) - **type=0**:目录(如"系统管理") - **type=1**:菜单(如"装车订单") - **type=2**:按钮(如"编辑"、"删除") ### 权限查询范围 - **菜单权限**:只查询 type=0,1 的项目 - **操作权限**:查询所有类型(type=0,1,2)的项目 ## 修复效果 ### 修复前 - ❌ 菜单权限和操作权限混淆 - ❌ 用户专属权限影响菜单显示 - ❌ 用户看不到任何菜单 ### 修复后 - ✅ 菜单权限和操作权限分离 - ✅ 用户专属权限只影响操作按钮 - ✅ 用户能看到菜单,但操作按钮被隐藏 ## 测试验证 ### 测试步骤 1. **重新编译后端**:`mvn clean compile` 2. **重启后端服务**:`mvn spring-boot:run` 3. **清除浏览器缓存** 4. **使用"12.27新增姓名"账号重新登录** 5. **检查左侧菜单栏和页面操作按钮** ### 预期结果 - **左侧菜单栏**:用户应该能看到"装车订单"等菜单项 - **页面操作按钮**:用户不应该看到"编辑"、"删除"等操作按钮 - **权限分离**:菜单权限和操作权限独立控制 ## 技术细节 ### 权限数据流 ``` 后端菜单权限查询 → getUserMenus() → queryUserMenus() → 只返回菜单项 → 前端菜单显示 ↓ 后端操作权限查询 → queryUserPermissions() → 返回所有权限 → 前端按钮控制 ``` ### 日志输出 修复后的日志输出示例: ``` === 用户 3 使用专属菜单权限,菜单数量: 8 === 用户 3 使用专属权限,权限数量: 15 ``` ## 相关文件 - `tradeCattle/aiotagro-cattle-trade/src/main/java/com/aiotagro/cattletrade/business/service/impl/LoginServiceImpl.java` - 权限查询逻辑分离 - `pc-cattle-transportation/src/store/permission.js` - 前端权限store - `pc-cattle-transportation/src/directive/permission/hasPermi.js` - 前端权限检查 ## 总结 通过分离菜单权限和操作权限的查询逻辑,成功解决了用户专属权限影响菜单显示的问题。修复后的系统能够: 1. **正确显示菜单**:用户专属权限不影响菜单权限 2. **正确隐藏操作按钮**:用户专属权限只影响操作权限 3. **权限分离**:菜单权限和操作权限独立控制 4. **向后兼容**:不影响现有功能 **修复状态**:✅ 已完成 **测试状态**:⏳ 待验证 **部署状态**:✅ 已部署