update 优化构建多根节点的树结构(支持多个顶级节点)

This commit is contained in:
AprilWind 2025-06-26 14:36:18 +08:00 committed by 疯狂的狮子Li
parent e659740cb8
commit eea96e87d9
3 changed files with 58 additions and 36 deletions

View File

@ -10,6 +10,9 @@ import lombok.NoArgsConstructor;
import org.dromara.common.core.utils.reflect.ReflectUtils;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@ -60,6 +63,38 @@ public class TreeBuildUtils extends TreeUtil {
return TreeUtil.build(list, parentId, DEFAULT_CONFIG, nodeParser);
}
/**
* 构建多根节点的树结构支持多个顶级节点
*
* @param list 原始数据列表
* @param getId 获取节点 ID 的方法引用例如node -> node.getId()
* @param getParentId 获取节点父级 ID 的方法引用例如node -> node.getParentId()
* @param parser 树节点属性映射器用于将原始节点 T 转为 Tree 节点
* @param <T> 原始数据类型如实体类DTO
* @param <K> 节点 ID 类型 LongString
* @return 构建完成的树形结构可能包含多个顶级根节点
*/
public static <T, K> List<Tree<K>> buildMultiRoot(List<T> list, Function<T, K> getId, Function<T, K> getParentId, NodeParser<T, K> parser) {
if (CollUtil.isEmpty(list)) {
return CollUtil.newArrayList();
}
// 提取所有节点 ID用于后续判断哪些节点为根节点 parentId 不在其中
Set<K> allIds = StreamUtils.toSet(list, getId);
// 筛选出所有 parentId 不在 allIds 中的节点这些节点的 parentId 可认为是根节点
Set<K> rootParentIds = list.stream()
.map(getParentId)
.filter(Objects::nonNull)
.filter(pid -> !allIds.contains(pid))
.collect(Collectors.toSet());
// 使用流处理遍历每个顶级 parentId构建对应树并合并为一个列表返回
return rootParentIds.stream()
.flatMap(rootParentId -> TreeUtil.build(list, rootParentId, parser).stream())
.collect(Collectors.toList());
}
/**
* 获取节点列表中所有节点的叶子节点
*

View File

@ -131,23 +131,17 @@ public class SysDeptServiceImpl implements ISysDeptService, DeptService {
if (CollUtil.isEmpty(depts)) {
return CollUtil.newArrayList();
}
// 获取当前列表中每一个节点的parentId然后在列表中查找是否有id与其parentId对应若无对应则表明此时节点列表中该节点在当前列表中属于顶级节点
List<Tree<Long>> treeList = CollUtil.newArrayList();
for (SysDeptVo d : depts) {
Long parentId = d.getParentId();
SysDeptVo sysDeptVo = StreamUtils.findFirst(depts, it -> it.getDeptId().longValue() == parentId);
if (ObjectUtil.isNull(sysDeptVo)) {
List<Tree<Long>> trees = TreeBuildUtils.build(depts, parentId, (dept, tree) ->
tree.setId(dept.getDeptId())
.setParentId(dept.getParentId())
.setName(dept.getDeptName())
.setWeight(dept.getOrderNum())
.putExtra("disabled", SystemConstants.DISABLE.equals(dept.getStatus())));
Tree<Long> tree = StreamUtils.findFirst(trees, it -> it.getId().longValue() == d.getDeptId());
treeList.add(tree);
}
}
return treeList;
return TreeBuildUtils.buildMultiRoot(
depts,
SysDeptVo::getDeptId,
SysDeptVo::getParentId,
(node, treeNode) -> treeNode
.setId(node.getDeptId())
.setParentId(node.getParentId())
.setName(node.getDeptName())
.setWeight(node.getOrderNum())
.putExtra("disabled", SystemConstants.DISABLE.equals(node.getStatus()))
);
}
/**

View File

@ -95,27 +95,20 @@ public class FlwCategoryServiceImpl implements IFlwCategoryService {
*/
@Override
public List<Tree<String>> selectCategoryTreeList(FlowCategoryBo category) {
LambdaQueryWrapper<FlowCategory> lqw = buildQueryWrapper(category);
List<FlowCategoryVo> categorys = baseMapper.selectVoList(lqw);
if (CollUtil.isEmpty(categorys)) {
List<FlowCategoryVo> categoryList = this.queryList(category);
if (CollUtil.isEmpty(categoryList)) {
return CollUtil.newArrayList();
}
// 获取当前列表中每一个节点的parentId然后在列表中查找是否有id与其parentId对应若无对应则表明此时节点列表中该节点在当前列表中属于顶级节点
List<Tree<String>> treeList = CollUtil.newArrayList();
for (FlowCategoryVo d : categorys) {
String parentId = d.getParentId().toString();
FlowCategoryVo categoryVo = StreamUtils.findFirst(categorys, it -> it.getCategoryId().toString().equals(parentId));
if (ObjectUtil.isNull(categoryVo)) {
List<Tree<String>> trees = TreeBuildUtils.build(categorys, parentId, (dept, tree) ->
tree.setId(dept.getCategoryId().toString())
.setParentId(dept.getParentId().toString())
.setName(dept.getCategoryName())
.setWeight(dept.getOrderNum()));
Tree<String> tree = StreamUtils.findFirst(trees, it -> it.getId().equals(d.getCategoryId().toString()));
treeList.add(tree);
}
}
return treeList;
return TreeBuildUtils.buildMultiRoot(
categoryList,
node -> String.valueOf(node.getCategoryId()),
node -> String.valueOf(node.getParentId()),
(node, treeNode) -> treeNode
.setId(String.valueOf(node.getCategoryId()))
.setParentId(String.valueOf(node.getParentId()))
.setName(node.getCategoryName())
.setWeight(node.getOrderNum())
);
}
/**