Commit 312f7e4890a1d3b5102e54b199234c621f8e6887

Authored by dongdong.xiang
1 parent 088871d0

【修复】获取菜单精简信息列表接口没有排除父 ID 非 0 的节点

yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/AuthController.java
... ... @@ -109,7 +109,6 @@ public class AuthController {
109 109 // 1.3 获得菜单列表
110 110 Set<Long> menuIds = permissionService.getRoleMenuListByRoleId(convertSet(roles, RoleDO::getId));
111 111 List<MenuDO> menuList = menuService.getMenuList(menuIds);
112   - menuList.removeIf(menu -> !CommonStatusEnum.ENABLE.getStatus().equals(menu.getStatus())); // 移除禁用的菜单
113 112  
114 113 // 2. 拼接结果返回
115 114 return success(AuthConvert.INSTANCE.convert(user, roles, menuList));
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/MenuController.java
... ... @@ -71,7 +71,7 @@ public class MenuController {
71 71 "在多租户的场景下,会只返回租户所在套餐有的菜单")
72 72 public CommonResult<List<MenuSimpleRespVO>> getSimpleMenuList() {
73 73 List<MenuDO> list = menuService.getMenuListByTenant(
74   - new MenuListReqVO().setStatus(CommonStatusEnum.ENABLE.getStatus()));
  74 + new MenuListReqVO());
75 75 list.sort(Comparator.comparing(MenuDO::getSort));
76 76 return success(BeanUtils.toBean(list, MenuSimpleRespVO.class));
77 77 }
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/MenuServiceImpl.java
1 1 package cn.iocoder.yudao.module.system.service.permission;
2 2  
3 3 import cn.hutool.core.collection.CollUtil;
  4 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
4 5 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
5 6 import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.MenuListReqVO;
6 7 import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.MenuSaveVO;
... ... @@ -13,14 +14,15 @@ import com.google.common.annotations.VisibleForTesting;
13 14 import com.google.common.collect.Lists;
14 15 import jakarta.annotation.Resource;
15 16 import lombok.extern.slf4j.Slf4j;
  17 +import org.apache.commons.collections4.CollectionUtils;
16 18 import org.springframework.cache.annotation.CacheEvict;
17 19 import org.springframework.cache.annotation.Cacheable;
18 20 import org.springframework.context.annotation.Lazy;
19 21 import org.springframework.stereotype.Service;
20 22 import org.springframework.transaction.annotation.Transactional;
21 23  
22   -import java.util.Collection;
23   -import java.util.List;
  24 +import java.util.*;
  25 +import java.util.stream.Collectors;
24 26  
25 27 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
26 28 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
... ... @@ -106,12 +108,60 @@ public class MenuServiceImpl implements MenuService {
106 108  
107 109 @Override
108 110 public List<MenuDO> getMenuListByTenant(MenuListReqVO reqVO) {
109   - List<MenuDO> menus = getMenuList(reqVO);
  111 + // 查询所有菜单,并过滤掉关闭的节点
  112 + List<MenuDO> menus = filterClosedNodes(getMenuList(reqVO));
110 113 // 开启多租户的情况下,需要过滤掉未开通的菜单
111 114 tenantService.handleTenantMenu(menuIds -> menus.removeIf(menu -> !CollUtil.contains(menuIds, menu.getId())));
112 115 return menus;
113 116 }
114 117  
  118 + /**
  119 + * 过滤关闭的菜单节点及其子节点
  120 + *
  121 + * @param menuList 所有菜单列表
  122 + * @return 过滤后的菜单列表
  123 + */
  124 + public List<MenuDO> filterClosedNodes(List<MenuDO> menuList) {
  125 + // 根据parentId快速查找子节点
  126 + Map<Long, List<MenuDO>> childrenMap = menuList.stream()
  127 + .collect(Collectors.groupingBy(MenuDO::getParentId));
  128 +
  129 + // 所有关闭的节点ID
  130 + Set<Long> closedNodeIds = new HashSet<>();
  131 +
  132 + // 标记所有关闭的节点
  133 + for (MenuDO menu : menuList) {
  134 + if (Objects.equals(menu.getStatus(), CommonStatusEnum.DISABLE.getStatus())) {
  135 + markClosedNodes(menu.getId(), childrenMap, closedNodeIds);
  136 + }
  137 + }
  138 +
  139 + // 过滤掉关闭的节点及其子节点
  140 + return menuList.stream()
  141 + .filter(menu -> !closedNodeIds.contains(menu.getId()))
  142 + .collect(Collectors.toList());
  143 + }
  144 +
  145 + /**
  146 + * 递归标记关闭的节点及其子节点
  147 + *
  148 + * @param nodeId 节点ID
  149 + * @param childrenMap 子节点Map
  150 + * @param closedNodeIds 关闭节点ID集合
  151 + */
  152 + private void markClosedNodes(Long nodeId, Map<Long,
  153 + List<MenuDO>> childrenMap,
  154 + Set<Long> closedNodeIds) {
  155 + closedNodeIds.add(nodeId);
  156 + List<MenuDO> children = childrenMap.get(nodeId);
  157 + if (CollectionUtils.isNotEmpty(children)) {
  158 + for (MenuDO child : children) {
  159 + markClosedNodes(child.getId(), childrenMap, closedNodeIds);
  160 + }
  161 + }
  162 + }
  163 +
  164 +
115 165 @Override
116 166 public List<MenuDO> getMenuList(MenuListReqVO reqVO) {
117 167 return menuMapper.selectList(reqVO);
... ... @@ -135,7 +185,7 @@ public class MenuServiceImpl implements MenuService {
135 185 if (CollUtil.isEmpty(ids)) {
136 186 return Lists.newArrayList();
137 187 }
138   - return menuMapper.selectBatchIds(ids);
  188 + return filterClosedNodes(menuMapper.selectBatchIds(ids));
139 189 }
140 190  
141 191 /**
... ...