递归加载菜单树

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格式化后可以清楚的看出层级结构。

原文地址:https://www.cnblogs.com/Zs-book1/p/12443433.html

时间: 2024-11-05 23:35:54

递归加载菜单树的相关文章

C# IO操作(五)文件的递归加载

本篇是一个案例,其核心通过代码展示代码中的递归这个用法,程序的界面如下: 当点击“加载”按钮时,根据路径中的地址,加载该文件夹下所有的子文件夹和子文件,代码如下: 1 private void BtnLoad_Click(object sender, EventArgs e) 2 { 3 string sPath = txtPath.Text.Trim(); 4 LoadDirAndFile(sPath, tvList.Nodes); 5 } 6 7 private void LoadDirAn

在mvc中动态加载菜单

最近做了一个项目, 要在客户端动态的显示菜单,也就是这些菜单是保存在数据库中的, 在客户端动态加载菜单,这样做的好处很明显,就是菜单很容易修改,直接在后台进行维护,再也不会直接在前面的 视图页面中进行修改,但是,缺点也很明显,实现起来有一定的难度,如果菜单多的话,在前台首次加载时,页面就会变慢,我想谈谈自己在这方面的经验 首先, 我们要创建两个表,(其实一个表也可以了,不过那样的话会变得比较复杂), 一个一级分类表, 一个二级分类表, 两个表的结构如下 : 一个是一级分类表,对应的就是父级菜单,

省市数据递归加载到TreeView

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Data.SqlClient; namespace 省市数据递归加载到TreeView { public

转:zTree树控件实战篇:针对多个下拉加载zTree树应该如何做出合理的配置

今天有一个zTree的朋友遇到一个非常棘手的问题,才研究zTree树控件两天就被上头催着看成果,很是苦恼.他面对的问题就是页面内多个地方需要下拉在其文本框下方加载zTree树,由于对zTree下拉加载树的一些关键配置以及原理的不太深入导致问题无从查起.今天就来一起聊聊这样一个下拉加载zTree的问题. 一.几个关键的配置需要注意 1.针对不同的下拉选择需要有自己独立控制zTree显示位置以及隐藏相应标签的方法: 2.需要根据所点击事件定位zTree的显示位置: 3.zTree树选择后需要加以判断

jqxtree异步加载部门树

整体思路 A.要想实现异步加载第一次加载的是一级部门 B.加载一级部门,如果有子部门,部门前面带+号,没有子部门,部门前面没有+号(+号也就是点击可以展开) C.在sql中实现如果有子部门默认都加载一个子部门名称为“查询中...”的部门,id自己定唯一就行,这样就可以实现加载的一级部门到底前面带不带+号 D.当点击可以展开的部门时,将部门为“查询中...”的替换为异步查出来的部门 1.引入样式和js(差不多能用到的都引入吧以便以后能用到) <link rel="stylesheet&quo

递归加载目录

public void LoadTree(string path, TreeNode node = null) { string[] dirs = Directory.GetDirectories(path); foreach (var dir in dirs) { TreeNode node1 = new TreeNode(Path.GetFileName(dir)); if (node == null) { //首次加载在treeview控件上 treeView1.Nodes.Add(nod

C#递归加载树

递归,就是有去有回,自己调用自己. 1 public partial class SiteMaster : MasterPage 2 { 3 public DataSet list = null; 4 5 public List<TreeData> treeDatas = new List<TreeData>(); 6 string str = ""; 7 protected void Page_Load(object sender, EventArgs e)

WinForm TreeView递归加载

这个其实通俗一点讲就是的树状分支图 首先利用递归添加数据 数据放入 treeView1.Nodes.Add() 中 public Form3() { InitializeComponent(); TreeNode t1 = new TreeNode("中国"); TreeNode t2 = new TreeNode("北京"); TreeNode t3 = new TreeNode("朝阳区"); t2.Nodes.Add(t3); t1.Nod

easyUi在后台加载异步树

DAO就不写接口了,直接写实现类 public List<Dept> tree(String hql, String par) { Session session = getHibernateTemplate().getSessionFactory() .getCurrentSession(); List list = new ArrayList(); if (par.length() == 0) { list = session.createQuery(hql).list(); } else