huliguo
2025-06-05 0a492b64ca1a4e40cc9ea56eddd1afe2c09a12b3
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysMenuServiceImpl.java
@@ -1,13 +1,10 @@
package com.ruoyi.system.service.impl;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.*;
import java.util.stream.Collectors;
import com.ruoyi.system.pojo.vo.MenuTreeVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.common.constant.Constants;
@@ -540,4 +537,66 @@
        return StringUtils.replaceEach(path, new String[] { Constants.HTTP, Constants.HTTPS, Constants.WWW, ".", ":" },
                new String[] { "", "", "", "/", "/" });
    }
    @Override
    public List<MenuTreeVO> tree(Long userId) {
        //  构建菜单树
        return buildMenuTree(userId);
    }
    /**
     * 构建菜单树(递归实现)
     * @return 菜单树列表
     */
    public List<MenuTreeVO> buildMenuTree(Long userId) {
        // 1. 根据用户ID查询角色ID集合
        List<Long> roleList = roleMapper.selectRoleListByUserId(userId);
        // 2. 查询角色关联的菜单ID
        List<Long> menuIds = roleMenuMapper.selectMenuIdsByRoleIds(roleList);
        // 获取所有菜单
        List<MenuTreeVO> rootMenus = menuMapper.getAllRootMenu();
        // 递归构建子菜单
        List<MenuTreeVO> list = rootMenus.stream()
                .map(x -> convertToMenuTreeVO(x,menuIds))
                .collect(Collectors.toList());
        return list.stream().filter(this::shouldIncludeMenu).collect(Collectors.toList());
    }
    /**
     * 递归转换菜单并构建子菜单树
     */
    private MenuTreeVO convertToMenuTreeVO(MenuTreeVO menu,List<Long> menuIds) {
        MenuTreeVO vo = new MenuTreeVO();
        BeanUtils.copyProperties(menu, vo, "children"); // 复制基本属性,忽略children字段
        // 获取当前菜单的子菜单
        List<MenuTreeVO> childMenus = menuMapper.selectMenusByParentId(menu.getMenuId());
        // 递归处理子菜单
        if (!childMenus.isEmpty()) {
            childMenus = childMenus.stream()
                    .filter(x -> !("C".equals(x.getMenuType()) && !menuIds.contains(x.getMenuId())))
                    .collect(Collectors.toList());
            List<MenuTreeVO> filteredChildren = childMenus.stream()
                    .map(x -> convertToMenuTreeVO(x,menuIds))
                    .filter(this::shouldIncludeMenu) // 过滤子菜单
                    .collect(Collectors.toList());
            vo.setChildren(filteredChildren);
        }
        return vo;
    }
    /**
     * 判断菜单是否应该被包含在结果中
     * - 如果是M类型且没有子菜单,则不包含
     * - 否则包含
     */
    private boolean shouldIncludeMenu(MenuTreeVO menu) {
        // 如果菜单类型是M(目录)且没有子菜单,则过滤掉
        return !("M".equals(menu.getMenuType()) && (menu.getChildren() == null || menu.getChildren().isEmpty()));
    }
}