| package com.zt.common.utils; | 
|   | 
| import cn.hutool.core.collection.CollectionUtil; | 
| import com.zt.common.entity.TreeNode2; | 
| import com.zt.common.exception.ErrorCode; | 
| import com.zt.common.exception.RenException; | 
| import com.zt.common.validator.AssertUtils; | 
|   | 
| 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 TreeUtils2 { | 
|   | 
|     /** | 
|      * 根据pid,构建树节点 | 
|      */ | 
|     public static <T extends TreeNode2> List<T> build(List<T> treeNodes, String pid) { | 
|         // pid不能为空 | 
|         AssertUtils.isNull(pid, "pid"); | 
|   | 
|         List<T> treeList = new ArrayList<>(); | 
|         for (T treeNode : treeNodes) { | 
|             if (pid.equals(treeNode.getPid())) { | 
|                 treeList.add(findChildren(treeNodes, treeNode)); | 
|             } | 
|         } | 
|   | 
|         return treeList; | 
|     } | 
|   | 
|     /** | 
|      * 查找子节点 | 
|      */ | 
|     private static <T extends TreeNode2> T findChildren(List<T> treeNodes, T rootNode) { | 
|         for (T treeNode : treeNodes) { | 
|             if (rootNode.getIid().equals(treeNode.getPid())) { | 
|                 rootNode.getChildren().add(findChildren(treeNodes, treeNode)); | 
|             } | 
|         } | 
|         return rootNode; | 
|     } | 
|   | 
|     /** | 
|      * 构建树节点 | 
|      */ | 
|     public static <T extends TreeNode2> List<T> build(List<T> treeNodes) { | 
|         List<T> result = new ArrayList<>(); | 
|   | 
|         // list转map | 
|         Map<Long, T> nodeMap = new LinkedHashMap<>(treeNodes.size()); | 
|         for (T treeNode : treeNodes) { | 
|             nodeMap.put(treeNode.getIid(), treeNode); | 
|         } | 
|   | 
|         for (T node : nodeMap.values()) { | 
|             T parent = nodeMap.get(node.getPid()); | 
|             if (parent != null && !(node.getIid().equals(parent.getIid()))) { | 
|                 parent.getChildren().add(node); | 
|                 continue; | 
|             } | 
|             result.add(node); | 
|         } | 
|         return result; | 
|     } | 
|   | 
|   | 
|   | 
|     /** | 
|      * 树结构转为list | 
|      * | 
|      * @param treeNode | 
|      * @param <T> | 
|      * @return | 
|      */ | 
|     public static <T extends TreeNode2> List<T> toList(T treeNode) { | 
|         List<T> result = new ArrayList<>(); | 
|         result.add(treeNode); | 
|         result.addAll(getChildren(treeNode)); | 
|         return result; | 
|     } | 
|   | 
|     /** | 
|      * 树结构转为list | 
|      * | 
|      * @param treeNodes | 
|      * @param <T> | 
|      * @return | 
|      */ | 
|     public static <T extends TreeNode2> List<T> toList(List<T> treeNodes) { | 
|         List<T> 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 <T> | 
|      * @return | 
|      */ | 
|     public static <T extends TreeNode2> List<T> toFlatList(List<T> treeNodes) { | 
|         List<T> temp = build(treeNodes); | 
|         List<T> 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 <T extends TreeNode2> List<T> getChildren(T node) { | 
|         List<T> result = new ArrayList<>(); | 
|         List<T> 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 <T> | 
|      * @return | 
|      */ | 
|     public static <T extends TreeNode2> List<T> getAncestor(List<T> allNodes, Long id) { | 
|         Map<Long, T> map = allNodes.stream().collect(Collectors.toMap(item -> item.getIid(), item -> item)); | 
|         List<T> list = new ArrayList<>(); | 
|         TreeNode2 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 extends TreeNode2> T getTreeRoot(List<T> allNodes, Long id, Long rootParentId) { | 
|         Map<Long, T> map = allNodes.stream().collect(Collectors.toMap(type -> type.getIid(), 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 <T> | 
|      * @return | 
|      */ | 
|     public static <T extends TreeNode2> List<T> getWithDescendant(List<T> allNodes, Long id) { | 
|         List<T> list = new ArrayList<>(); | 
|         if (id == 0) { | 
|             list.addAll(allNodes); | 
|         } else { | 
|             if (allNodes.stream().filter(n -> n.getIid().equals(id)).count() > 0) { | 
|                 T node = allNodes.stream().filter(n -> n.getIid().equals(id)).findFirst().get(); | 
|                 list.add(node); | 
|                 queryChildrenDepartmentRecursion((List<TreeNode2>) list, (List<TreeNode2>) allNodes, node.getIid()); | 
|             } | 
|         } | 
|         return list; | 
|     } | 
|   | 
|     /** | 
|      * 获取下级 | 
|      * | 
|      * @param allNodes | 
|      * @param id | 
|      * @return | 
|      */ | 
|     public static <T extends TreeNode2> List<T> getDescendant(List<T> allNodes, Long id) { | 
|         List<T> list = new ArrayList<>(); | 
|         queryChildrenDepartmentRecursion((List<TreeNode2>) list, (List<TreeNode2>) allNodes, id); | 
|         return list; | 
|     } | 
|   | 
|     /** | 
|      * 递归查询子节点 | 
|      */ | 
|     private static void queryChildrenDepartmentRecursion(List<TreeNode2> list, List<TreeNode2> allNodes, Long id) { | 
|         for (TreeNode2 node : allNodes.stream().filter(n -> n.getPid().equals(id)).collect(Collectors.toList())) { | 
|             list.add(node); | 
|             queryChildrenDepartmentRecursion(list, allNodes, node.getIid()); | 
|         } | 
|     } | 
|   | 
|     /** | 
|      * 修改校验 | 
|      * | 
|      * @param allNodes | 
|      * @param node | 
|      * @param dbNode | 
|      */ | 
|     public static <T extends TreeNode2> void updateValidate(List<T> allNodes, TreeNode2 node, TreeNode2 dbNode) { | 
|         if (dbNode == null) { | 
|             throw new RenException("查询信息失败"); | 
|         } | 
|         // 上级菜单不能为自身 | 
|         if (node.getIid().equals(node.getPid())) { | 
|             throw new RenException(ErrorCode.SUPERIOR_MENU_ERROR); | 
|         } | 
|         // 上级不能为下级 | 
|         if (!dbNode.getPid().equals(node.getPid())) {// 层级改变了 | 
|             if (node.getIid().equals(node.getPid())) { | 
|                 throw new RenException("上级不能设置为其本身!"); | 
|             } | 
|   | 
|             List<T> list = TreeUtils2.getDescendant(allNodes, node.getIid()); | 
|             for (T d : list) { | 
|                 if (d.getIid().equals(node.getPid())) { | 
|                     throw new RenException("上级不能设置为其下级!"); | 
|                 } | 
|             } | 
|         } | 
|     } | 
| } |