递归加载菜单树

Posted zs-book1

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了递归加载菜单树相关的知识,希望对你有一定的参考价值。

1.创建数据库表

create table system_resource
(
    id                   bigint(11)   not null primary key auto_increment comment id,
    resource_name        varchar(20)  not null comment 资源名称,
    resource_name_cn varchar(20) not null comment 资源中文名,
    resource_parent_name varchar(20)  null comment 父级资源名称,
    resource_url         varchar(100) null comment 资源路径,
    resource_icon varchar(100) comment 资源图标,
    create_time          timestamp    not null default 0000-00-00 00:00:00 comment 创建时间,
    update_time          timestamp    not null default current_timestamp on update current_timestamp comment 修改时间
) charset = utf8mb4 comment 角色资源表;
create trigger resource_insert
    before insert
    on system_resource
    for each row set new.create_time = now();

插入测试数据:

技术图片

 

 然后java代码加载菜单树:

新建一个菜单的bean对象,用来存放加载出来的菜单:

package com.whx.gxrsms.bean;

import lombok.Data;
import lombok.experimental.Accessors;

import java.io.Serializable;
import java.util.List;

/**
 * @author ZhaoShuai
 * @company lihfinance.com
 * @date Create in 2020/3/3
 **/
@Data
@Accessors(chain = true)
public class MenuTree implements Serializable {

    private static final long serialVersionUID = 1L;

    private Long id;

    private String name;

    private String title;

    private String icon;

    private String href;

    private List<MenuTree> list;
}

使用mybatis和通用mapper来写dao层,这一块就不写出来了,直接写主要方法:

@Override
    public List<MenuTree> getMenuTree() {
        /*加载出所有的菜单*/
        List<SystemResource> resources = resourceMapper.select(new SystemResource());
        /*筛选出所有的第一级菜单*/
        List<MenuTree> menuTrees = resources.parallelStream().filter(r -> StringUtils.isEmpty(r.getResourceParentName()))
                .map(this::convertResource)
                .collect(Collectors.toList());
        /*加载出所有的子菜单*/
        List<SystemResource> childResource = resources.parallelStream()
                .filter(f -> !StringUtils.isEmpty(f.getResourceParentName()))
                .collect(Collectors.toList());
        /*生成菜单树*/
        menuTrees = menuTrees.parallelStream().map(m -> recursiveMenu(m, childResource)).collect(Collectors.toList());

        return menuTrees;
    }
    /**
     * @company lihfinance.com
     * @author create by ZhaoShuai in 2020/3/3
     *  递归生成菜单树
     * @param menuTree, resources
     * @return com.whx.gxrsms.bean.MenuTree
     **/
    private MenuTree recursiveMenu(MenuTree menuTree, List<SystemResource> resources) {
        List<MenuTree> childMenu = resources.parallelStream()
                .filter(r -> menuTree.getName().equals(r.getResourceParentName()))
                .map(this::convertResource).collect(Collectors.toList());
        if (!childMenu.isEmpty()) {
            childMenu = childMenu.parallelStream().map(m -> recursiveMenu(m, resources)).collect(Collectors.toList());
        }
        menuTree.setList(childMenu);
        return menuTree;
    }

    /**
     * @company lihfinance.com
     * @author create by ZhaoShuai in 2020/3/3
     *  将资源转换为菜单类
     * @param
     * @return
     **/
    private MenuTree convertResource(SystemResource resource) {
        MenuTree tree = new MenuTree();
        tree.setId(resource.getId());
        tree.setName(resource.getResourceName());
        tree.setTitle(resource.getResourceNameCn());
        tree.setHref(resource.getResourceUrl());
        tree.setIcon(resource.getResourceIcon());
        return tree;
    }

然后配置controller,访问调用该方法:

 @RequestMapping("/getMenuTree")
    @ResponseBody
    public Result getMenuTree() {
        Result result = Result.success();

        List<MenuTree> menuTrees = loginService.getMenuTree();
        result.setData(menuTrees);
        return result;
    }

页面展示结果为:

{"code":200,"msg":"操作成功","data":[{"id":1,"name":"system.manager","title":"系统管理","icon":"aaa","href":null,"list":[{"id":2,"name":"save.resource","title":"添加资源","icon":"bbb","href":"/gxrsms/resource.html","list":[]},{"id":3,"name":"role.manager","title":"角色管理","icon":null,"href":null,"list":[{"id":5,"name":"role.add","title":"添加角色","icon":"","href":"/gxrsms/role/insert","list":[]}]},{"id":4,"name":"user.manager","title":"用户管理","icon":null,"href":null,"list":[{"id":6,"name":"user.add","title":"添加用户","icon":"","href":"/gxrsms/user/insert","list":[]}]}]},{"id":7,"name":"dept.manager","title":"部门管理","icon":"ccc","href":null,"list":[{"id":8,"name":"dept.add","title":"添加部门","icon":"","href":"/gxrsms/dept/insert","list":[]}]}]}

这就是我们要加载的菜单树了,json格式化后可以清楚的看出层级结构。

以上是关于递归加载菜单树的主要内容,如果未能解决你的问题,请参考以下文章

el-menu 菜单递归循环

java从数据库读取菜单,递归生成菜单树

Java菜单树递归

三种方式实现递归树加载

具有递归功能的回声菜单树

vue.js 树菜单 递归组件树来实现