package com.example.client.utils; import cn.hutool.core.collection.CollectionUtil; import com.example.client.entity.AssertUtils; import com.example.client.entity.ErrorCode; import com.example.client.entity.RenException; import com.example.client.entity.TreeNode; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; /** * 树形结构工具类,如:菜单、部门等 * * @author hehz * @since 1.0.0 */ public class TreeUtils { /** * 根据pid,构建树节点 */ public static List build(List treeNodes, Long pid) { // pid不能为空 AssertUtils.isNull(pid, "pid"); List treeList = new ArrayList<>(); for (T treeNode : treeNodes) { if (pid.equals(treeNode.getPid())) { treeList.add(findChildren(treeNodes, treeNode)); } } return treeList; } /** * 查找子节点 */ private static T findChildren(List treeNodes, T rootNode) { for (T treeNode : treeNodes) { if (rootNode.getId().equals(treeNode.getPid())) { rootNode.getChildren().add(findChildren(treeNodes, treeNode)); } } return rootNode; } /** * 构建树节点 */ public static List build(List treeNodes) { List result = new ArrayList<>(); // list转map Map nodeMap = new LinkedHashMap<>(treeNodes.size()); for (T treeNode : treeNodes) { nodeMap.put(treeNode.getId(), treeNode); } for (T node : nodeMap.values()) { T parent = nodeMap.get(node.getPid()); if (parent != null && !(node.getId().equals(parent.getId()))) { parent.getChildren().add(node); continue; } result.add(node); } return result; } /** * 树结构转为list * * @param treeNode * @param * @return */ public static List toList(T treeNode) { List result = new ArrayList<>(); result.add(treeNode); result.addAll(getChildren(treeNode)); return result; } /** * 树结构转为list * * @param treeNodes * @param * @return */ public static List toList(List treeNodes) { List result = new ArrayList<>(); for (T node : treeNodes) { result.add(node); result.addAll(getChildren(node)); } for (T node : result) { setFieldValueByName(node, "children", null); } return result; } /** * 树结构转为list * * @param treeNodes * @param * @return */ public static List toFlatList(List treeNodes) { List temp = build(treeNodes); List result = toList(temp); return result; } public static List toFlatList(List treeNodes, Long pid) { List temp = build(treeNodes, pid); List result = toList(temp); return result; } //zzw public static void setFieldValueByName(Object obj, String fieldName, Object value) { try { Class c = obj.getClass(); Field f = c.getDeclaredField(fieldName); f.setAccessible(true); f.set(obj, value); } catch (Exception e) { System.out.println(e.getMessage()); } } private static List getChildren(T node) { List result = new ArrayList<>(); List children = node.getChildren(); if (CollectionUtil.isNotEmpty(children)) { for (T child : children) { result.add(child); result.addAll(getChildren(child)); } } return result; } /** * 查找所有祖先,按照祖先的层级排序 * * @param allNodes * @param id * @param * @return */ public static List getAncestor(List allNodes, Long id) { Map map = allNodes.stream().collect(Collectors.toMap(dept -> dept.getId(), dept -> dept)); List list = new ArrayList<>(); TreeNode node = map.get(id); if (node != null) { T parent = map.get(node.getPid()); while (parent != null) { list.add(0, parent); parent = map.get(parent.getPid()); } } return list; } public static T getTreeRoot(List allNodes, Long id, Long rootParentId) { Map map = allNodes.stream().collect(Collectors.toMap(type -> type.getId(), type -> type)); T parent = map.get(id); while (parent != null) { if (rootParentId.equals(parent.getPid())) { break; } parent = map.get(parent.getPid()); } return parent; } /** * 获取自己和所有下级 * * @param allNodes * @param id * @param * @return */ public static List getWithDescendant(List allNodes, Long id) { List list = new ArrayList<>(); if (id == 0) { list.addAll(allNodes); } else { if (allNodes.stream().filter(n -> n.getId().equals(id)).count() > 0) { T node = allNodes.stream().filter(n -> n.getId().equals(id)).findFirst().get(); list.add(node); queryChildrenDepartmentRecursion((List) list, (List) allNodes, node.getId()); } } return list; } /** * 获取下级 * * @param allNodes * @param id * @return */ public static List getDescendant(List allNodes, Long id) { List list = new ArrayList<>(); queryChildrenDepartmentRecursion((List) list, (List) allNodes, id); return list; } /** * 递归查询子节点 */ private static void queryChildrenDepartmentRecursion(List list, List allNodes, Long id) { for (TreeNode node : allNodes.stream().filter(n -> n.getPid().equals(id)).collect(Collectors.toList())) { list.add(node); queryChildrenDepartmentRecursion(list, allNodes, node.getId()); } } /** * 修改校验 * * @param allNodes * @param node * @param dbNode */ public static void updateValidate(List allNodes, TreeNode node, TreeNode dbNode) { if (dbNode == null) { throw new RenException("查询信息失败"); } // 上级菜单不能为自身 if (node.getId().equals(node.getPid())) { throw new RenException(ErrorCode.SUPERIOR_MENU_ERROR); } // 上级不能为下级 if (!dbNode.getPid().equals(node.getPid())) {// 层级改变了 if (node.getId().equals(node.getPid())) { throw new RenException("上级不能设置为其本身!"); } List list = TreeUtils.getDescendant(allNodes, node.getId()); for (T d : list) { if (d.getId().equals(node.getPid())) { throw new RenException("上级不能设置为其下级!"); } } } } }