package org.dromara.common.core.utils; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.lang.tree.Tree; import cn.hutool.core.lang.tree.TreeNodeConfig; import cn.hutool.core.lang.tree.TreeUtil; import cn.hutool.core.lang.tree.parser.NodeParser; import lombok.AccessLevel; import lombok.NoArgsConstructor; import org.dromara.common.core.utils.reflect.ReflectUtils; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; /** * 扩展 hutool TreeUtil 封装系统树构建 * * @author Lion Li */ @NoArgsConstructor(access = AccessLevel.PRIVATE) public class TreeBuildUtils extends TreeUtil { /** * 根据前端定制差异化字段 */ public static final TreeNodeConfig DEFAULT_CONFIG = TreeNodeConfig.DEFAULT_CONFIG.setNameKey("label"); /** * 构建树形结构 * * @param 输入节点的类型 * @param 节点ID的类型 * @param list 节点列表,其中包含了要构建树形结构的所有节点 * @param nodeParser 解析器,用于将输入节点转换为树节点 * @return 构建好的树形结构列表 */ public static List> build(List list, NodeParser nodeParser) { if (CollUtil.isEmpty(list)) { return CollUtil.newArrayList(); } K k = ReflectUtils.invokeGetter(list.get(0), "parentId"); return TreeUtil.build(list, k, DEFAULT_CONFIG, nodeParser); } /** * 构建树形结构 * * @param 输入节点的类型 * @param 节点ID的类型 * @param parentId 顶级节点 * @param list 节点列表,其中包含了要构建树形结构的所有节点 * @param nodeParser 解析器,用于将输入节点转换为树节点 * @return 构建好的树形结构列表 */ public static List> build(List list, K parentId, NodeParser nodeParser) { if (CollUtil.isEmpty(list)) { return CollUtil.newArrayList(); } return TreeUtil.build(list, parentId, DEFAULT_CONFIG, nodeParser); } /** * 获取节点列表中所有节点的叶子节点 * * @param 节点ID的类型 * @param nodes 节点列表 * @return 包含所有叶子节点的列表 */ public static List> getLeafNodes(List> nodes) { if (CollUtil.isEmpty(nodes)) { return CollUtil.newArrayList(); } return nodes.stream() .flatMap(TreeBuildUtils::extractLeafNodes) .collect(Collectors.toList()); } /** * 获取指定节点下的所有叶子节点 * * @param 节点ID的类型 * @param node 要查找叶子节点的根节点 * @return 包含所有叶子节点的列表 */ private static Stream> extractLeafNodes(Tree node) { if (!node.hasChild()) { return Stream.of(node); } else { // 递归调用,获取所有子节点的叶子节点 return node.getChildren().stream() .flatMap(TreeBuildUtils::extractLeafNodes); } } }