模型定义,这里受Spring Security的UserService启发,给model设置接口.想要使用此工具类的话,实现此接口即可.
package xyz.yq56.easytool.abs;
import java.util.List;
public interface TreeNode {
String getId();
String getPid();
List getChildren();
void setChildren(List children);
}
工具类源码:
package xyz.yq56.easytool.utils.recursion;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import xyz.yq56.easytool.abs.TreeNode;
import xyz.yq56.easytool.utils.collection.CollectUtil;
public class RecursionUtil {
private RecursionUtil() {}
public static void buildTree(List list, T node) {
if (CollectUtil.isEmpty(list)) {
return;
}
List children = new ArrayList<>();
for (T menu : list) {
if (Objects.equals(menu.getPid(), node.getId())) {
children.add(menu);
buildTree(getRemainList(list, menu.getPid()), menu);
}
}
if(!CollectUtil.isEmpty(children)){
node.setChildren(children);
}
}
private static List getRemainList(List list, String pid) {
return CollectUtil.filter(list,item -> !Objects.equals(item.getPid(), pid));
}
}
2. 使用示例
实现TreeNode接口
package xyz.yq56.sm.module.menu.model;
import java.util.List;
import lombok.Data;
import xyz.yq56.easytool.abs.TreeNode;
@Data
public class MenuVo implements TreeNode {
private String id;
private String pid;
private String name;
private String path;
private String icon;
private List children;
@Override
public void setChildren(List list) {
this.children = (List) list;
}
}
service层代码: 直接使用RecursionUtil.buildTree方法即可
package xyz.yq56.sm.module.menu.service.impl;
import java.util.List;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import xyz.yq56.easytool.utils.collection.CollectUtil;
import xyz.yq56.easytool.utils.nvll.NullUtil;
import xyz.yq56.easytool.utils.recursion.RecursionUtil;
import xyz.yq56.sm.module.menu.model.Menu;
import xyz.yq56.sm.module.menu.model.MenuVo;
import xyz.yq56.sm.module.menu.service.MenuBizService;
import xyz.yq56.sm.module.menu.service.MenuService;
@Service
public class MenuBizServiceImpl implements MenuBizService {
@Autowired
private MenuService menuService;
@Override
public MenuVo getMenu(String pid) {
//拿到菜单原始数据
List
controller
@RestController
@RequestMapping("/menu/biz/")
public class MenuBizController {
@Autowired
MenuBizService menuBizService;
@GetMapping("getMenu")
public MenuVo getMenu(String pid) {
return menuBizService.getMenu(pid);
}
}
请求效果
不指定特定节点时,以null为根节点.日常使用,可以直接拿根节点的children作为菜单也可.
http://localhost:8080/menu/biz/getMenu
{
"code": 200,
"data": {
"id": null,
"pid": null,
"name": null,
"path": null,
"icon": null,
"children": [
{
"id": "1445371079417503745",
"pid": null,
"name": "用户管理",
"path": "/user",
"icon": "el-icon-user",
"children": [
{
"id": "1445372598120456194",
"pid": "1445371079417503745",
"name": "用户信息",
"path": "/user_info",
"icon": "el-icon-s-custom",
"children": null
},
{
"id": "1445405355609530370",
"pid": "1445371079417503745",
"name": "用户列表",
"path": "/users",
"icon": "el-icon-s-custom",
"children": null
}
]
},
{
"id": "1445372340355309569",
"pid": null,
"name": "菜单管理",
"path": "/menu",
"icon": "el-icon-menu",
"children": null
}
]
},
"msg": "success",
"date": "2021-10-05T17:38:36.153+00:00"
}
指定特定节点.比如我只想取以上用户管理的菜单,那么拿到用户管理的id传入即可.
http://localhost:8080/menu/biz/getMenu?pid=1445371079417503745
{
"code": 200,
"data": {
"id": "1445371079417503745",
"pid": null,
"name": "用户管理",
"path": "/user",
"icon": "el-icon-user",
"children": [
{
"id": "1445372598120456194",
"pid": "1445371079417503745",
"name": "用户信息",
"path": "/user_info",
"icon": "el-icon-s-custom",
"children": null
},
{
"id": "1445405355609530370",
"pid": "1445371079417503745",
"name": "用户列表",
"path": "/users",
"icon": "el-icon-s-custom",
"children": null
}
]
},
"msg": "success",
"date": "2021-10-05T17:41:30.870+00:00"
}
数据库原始数据
前端展示(Vue)
不知道怎么构建树形菜单的小伙伴可以看下这个工具类,希望可以给一部分朋友一点启示.有帮助的话,请点赞或评论,谢谢



