【Java树形菜单系统设计与实现】

Java树形菜单系统设计与实现

ruoyi实现

根据用户 ID 查询菜单树

java 复制代码
   public List<SysMenu> selectMenuTreeByUserId(String useNo) {
        List<SysMenu> menus = null;
        if (SecurityUtils.isAdmin(useNo))
        {
        	// 管理员查询所有权限
            menus = menuMapper.selectMenuTreeAll();
        }
        else
        {
            // 不是管理员,需要查询路由
            menus = menuMapper.selectMenuTreeByUseNo(useNo);
        }
        return getChildPerms(menus, 0);
    }

根据给定的父节点ID构建出树形结构的子菜单。

java 复制代码
   // 根据给定的父节点ID从平面菜单列表中筛选并构建出树形结构的子菜单。
    public List<SysMenu> getChildPerms(List<SysMenu> list, int parentId) {
        List<SysMenu> returnList = new ArrayList<SysMenu>();

        for (SysMenu t : list) {
            if (t.getParentId() == parentId) {
                recursionFn(list, t);
                returnList.add(t);
            }
        }
        return returnList;
    }

递归地为当前菜单节点构建完整的子树结构

java 复制代码
   // 递归地为当前菜单节点构建完整的子树结构,设置其所有子节点及其后代节点。
   private void recursionFn(List<SysMenu> list, SysMenu t) {
        // 得到子节点列表
        List<SysMenu> childList = getChildList(list, t);
        t.setChildren(childList);
        for (SysMenu tChild : childList) {
            if (hasChild(list, tChild)) {
                recursionFn(list, tChild);
            }
        }
    }

查找特定父节点所有直接子节点

java 复制代码
	// 从平面菜单列表中查找特定父节点所有直接子节点的方法。
    private List<SysMenu> getChildList(List<SysMenu> list, SysMenu t) {
        List<SysMenu> tlist = new ArrayList<SysMenu>();
        for (SysMenu n : list) {
            if (n.getParentId().longValue() == t.getMenuId().longValue()) {
                tlist.add(n);
            }
        }
        return tlist;
    }

判断是否有子节点

java 复制代码
	// 判断是否有子节点
    private boolean hasChild(List<SysMenu> list, SysMenu t) {
        return getChildList(list, t).size() > 0;
    }

简化

java 复制代码
 public List<SysMenu> selectMenuTreeByUserId(String useNo) {
        List<SysMenu> menus = null;
        if (useNo.equals("P059569")) {
            // 管理员查询所有权限
           return selectMenuTree() ;


        } else {
            // 不是管理员,需要查询路由
            return selectMenuTree() ;
        }
    }
java 复制代码
    // 查询所有菜单并递归子菜单
    @Override
    public List<SysMenu> selectMenuTree() {
        LambdaQueryWrapper<SysMenu> wrapper = new LambdaQueryWrapper<>();
        // 设置查询条件
        wrapper.in(SysMenu::getMenuType, Arrays.asList("M", "C"))  // 菜单类型为目录(M)或菜单(C)
                .eq(SysMenu::getStatus, 0)                      // 状态为0(正常)
                .orderByAsc(SysMenu::getParentId, SysMenu::getOrderNum);// 设置排序(先按父ID排序,再按排序号排序)

        List<SysMenu> menus = menuMapper.selectList(wrapper);

        // 1. 创建菜单映射表并初始化children
        // 将菜单列表转换为一个Map,其中:
        // - 键(key)是菜单ID(Long类型)
        // - 值(value)是菜单对象(SysMenu)
        Map<Long, SysMenu> menuMap = menus.stream()

                // peek()是一个中间操作,用于对每个元素执行操作但不改变流内容
                // 这里对每个菜单对象执行初始化children列表的操作
                .peek(menu -> menu.setChildren(new ArrayList<>()))

                // 终止操作,将流转换为Map
                // Collectors.toMap()需要两个参数:
                // 1. SysMenu::getMenuId - 键提取函数,从菜单对象获取菜单ID作为Map的键
                // 2. Function.identity() - 值提取函数,直接使用菜单对象本身作为Map的值
                .collect(Collectors.toMap(SysMenu::getMenuId, Function.identity()));

        // 2. 构建父子关系
        menus.forEach(menu -> {
            if (menu.getParentId() != 0) {// 如果不是根菜单(parentId=0的是根菜单)
                SysMenu parent = menuMap.get(menu.getParentId());
                if (parent != null) {
                    parent.getChildren().add(menu);// 将当前菜单添加到父菜单的children列表中
                }
            }
        });

        // 3. 返回根节点并排序
        return menus.stream()
                // 1.筛选出所有根菜单(parentId == 0的菜单)
                .filter(menu -> menu.getParentId() == 0)
                // 2.对每个根菜单进行处理
                .peek(root ->
                        // 对当前根菜单的子菜单列表进行排序
                        // 使用Comparator.comparingInt根据orderNum字段进行升序排序
                        root.getChildren().sort(Comparator.comparingInt(SysMenu::getOrderNum)))
                // 3.对所有根菜单进行升序排序
                .sorted(Comparator.comparingInt(SysMenu::getOrderNum))
                // 4.将处理后的Stream收集为List
                .collect(Collectors.toList());
    }
相关推荐
JAVA面经实录9175 小时前
Java企业级工程化·终极完整版背诵手册(无遗漏、全覆盖、面试+落地通用)
java·开发语言·面试
许彰午7 小时前
CacheSQL(二):主从复制——OpLog 环形缓冲区与故障自动恢复
java·数据库·缓存
Bat U8 小时前
JavaEE|多线程初阶(七)
java·开发语言
掌心向暖RPA自动化10 小时前
如何获取网页某个元素在屏幕可见部分的中心坐标影刀RPA懒加载坐标定位技巧
java·javascript·自动化·rpa·影刀rpa
日取其半万世不竭10 小时前
Minecraft Java版社区服务器搭建教程(Linux,适合新手)
java·linux·服务器
TeamDev11 小时前
JxBrowser 9.0.0 版本发布啦!
java·前端·混合应用·jxbrowser·浏览器控件·跨平台渲染·原声输入
AI人工智能+电脑小能手12 小时前
【大白话说Java面试题】【Java基础篇】第24题:Java面向对象有哪些特征
java·开发语言·后端·面试
AI人工智能+电脑小能手12 小时前
【大白话说Java面试题】【Java基础篇】第25题:JDK1.8的新特性有哪些
java·开发语言·后端·面试
likerhood12 小时前
SLF4J: Failed to load class “StaticLoggerBinder“ 解决
java·log4j·maven
早日退休!!!13 小时前
大模型推理瓶颈七层分析模型
java·服务器·数据库