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