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 <T extends TreeNode> List<T> build(List<T> treeNodes, Long 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 TreeNode> T findChildren(List<T> treeNodes, T rootNode) {
|
for (T treeNode : treeNodes) {
|
if (rootNode.getId().equals(treeNode.getPid())) {
|
rootNode.getChildren().add(findChildren(treeNodes, treeNode));
|
}
|
}
|
return rootNode;
|
}
|
|
/**
|
* 构建树节点
|
*/
|
public static <T extends TreeNode> 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.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 <T>
|
* @return
|
*/
|
public static <T extends TreeNode> 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 TreeNode> 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 TreeNode> List<T> toFlatList(List<T> treeNodes) {
|
List<T> temp = build(treeNodes);
|
List<T> result = toList(temp);
|
return result;
|
}
|
|
public static <T extends TreeNode> List<T> toFlatList(List<T> treeNodes, Long pid) {
|
List<T> temp = build(treeNodes, pid);
|
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 TreeNode> 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 TreeNode> List<T> getAncestor(List<T> allNodes, Long id) {
|
Map<Long, T> map = allNodes.stream().collect(Collectors.toMap(dept -> dept.getId(), dept -> dept));
|
List<T> 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 extends TreeNode> T getTreeRoot(List<T> allNodes, Long id, Long rootParentId) {
|
Map<Long, T> 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 <T>
|
* @return
|
*/
|
public static <T extends TreeNode> 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.getId().equals(id)).count() > 0) {
|
T node = allNodes.stream().filter(n -> n.getId().equals(id)).findFirst().get();
|
list.add(node);
|
queryChildrenDepartmentRecursion((List<TreeNode>) list, (List<TreeNode>) allNodes, node.getId());
|
}
|
}
|
return list;
|
}
|
|
/**
|
* 获取下级
|
*
|
* @param allNodes
|
* @param id
|
* @return
|
*/
|
public static <T extends TreeNode> List<T> getDescendant(List<T> allNodes, Long id) {
|
List<T> list = new ArrayList<>();
|
queryChildrenDepartmentRecursion((List<TreeNode>) list, (List<TreeNode>) allNodes, id);
|
return list;
|
}
|
|
/**
|
* 递归查询子节点
|
*/
|
private static void queryChildrenDepartmentRecursion(List<TreeNode> list, List<TreeNode> 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 <T extends TreeNode> void updateValidate(List<T> 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<T> list = TreeUtils.getDescendant(allNodes, node.getId());
|
for (T d : list) {
|
if (d.getId().equals(node.getPid())) {
|
throw new RenException("上级不能设置为其下级!");
|
}
|
}
|
}
|
}
|
}
|