优化组织机构树构建逻辑,修改为根据根节点展示多条数据,支持多级机构并提升性能
1. 重构`getTreeByNode`方法: - 新增父节点到子节点的映射表(parentToChildrenMap),通过预处理将子节点查找时间从O(n)优化为O(1) - 使用StringBuilder累加部门ID,避免字符串拼接的性能损耗 - 提前将SysOrg转换为SysOrgVO并应用树形结构字段(id/title/key/value),减少重复转换操作 2. 新增`buildMultiLevelTree`方法: - 独立递归构建多级树的核心逻辑,提升代码可读性 - 通过映射表快速获取子节点列表,支持任意层级的组织机构树构建 - 对每层级子节点按sort字段排序,保持原有展示顺序 3. 移除原低效递归方法`getChildrenNode`,消除全量数据遍历的性能瓶颈 影响范围:组织机构树形查询接口(对应Controller的`/queryAll`端点),显著提升大数据量(20000+条)时的响应速度。
This commit is contained in:
@ -22,9 +22,7 @@ import com.coscoshipping.ebtp.project.org.service.SysOrgService;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@ -50,8 +48,7 @@ public class SysOrgServiceImpl extends BaseServiceImpl<SysOrgMapper,SysOrg> imp
|
||||
|
||||
@Override
|
||||
public List<SysOrgVO> getTreeByNode(SysOrg org) {
|
||||
SysOrgVO sysOrgVO = new SysOrgVO();
|
||||
List<SysOrg> sysOrgList = new ArrayList<>();
|
||||
List<SysOrg> sysOrgList;
|
||||
if (!StringUtils.isEmpty(org.getOrgName()) || !StringUtils.isEmpty(org.getOrgNum())){
|
||||
SysOrgVO vo = BeanUtil.toBean(org, SysOrgVO.class);
|
||||
IPage<SysOrg> page = this.getPage(vo);
|
||||
@ -59,33 +56,77 @@ public class SysOrgServiceImpl extends BaseServiceImpl<SysOrgMapper,SysOrg> imp
|
||||
return sysOrgList.stream().map(entity -> BeanUtil.toBean(entity, SysOrgVO.class)).collect(Collectors.toList());
|
||||
} else {
|
||||
sysOrgList = this.list();
|
||||
|
||||
//存储所有的部门ID
|
||||
String allDepartmentId = "";
|
||||
|
||||
if (!CollectionUtils.isEmpty(sysOrgList)) {
|
||||
//获取要查询的节点ID 如果为空则查询所有节点进行树形展示
|
||||
String rootNode = StringUtils.isNotBlank(org.getOrgId()) ? org.getOrgId() : CommonUtil.ROOT_NODE;
|
||||
|
||||
allDepartmentId += rootNode;
|
||||
|
||||
List<SysOrgVO> sysOrgVOList = JsonUtils.jsonToList(sysOrgList, SysOrgVO.class);
|
||||
//获取要查询的节点
|
||||
sysOrgVO = sysOrgVOList.stream()
|
||||
.filter(n -> StringUtils.equals(n.getUpOrgId(), rootNode))
|
||||
.map(this::setInfoForTree)
|
||||
.collect(Collectors.toList())
|
||||
.get(0);
|
||||
//递归查询节点信息
|
||||
getChildrenNode(sysOrgVOList, sysOrgVO, allDepartmentId);
|
||||
}
|
||||
sysOrgVO.setAllDepartmentId(allDepartmentId);
|
||||
List<SysOrgVO> voList = new ArrayList<>();
|
||||
voList.add(sysOrgVO);
|
||||
|
||||
if (CollectionUtils.isEmpty(sysOrgList)) {
|
||||
return voList;
|
||||
}
|
||||
|
||||
// 预处理所有节点为SysOrgVO,并构建子节点映射表
|
||||
List<SysOrgVO> allOrgVOs = sysOrgList.stream()
|
||||
.map(entity -> BeanUtil.toBean(entity, SysOrgVO.class))
|
||||
.map(this::setInfoForTree) // 提前应用树形结构转换
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 构建父节点到子节点的映射(key: upOrgId,value: 子节点列表)
|
||||
Map<String, List<SysOrgVO>> parentToChildrenMap = new HashMap<>();
|
||||
String rootOrgCode = "10000000";
|
||||
for (SysOrgVO orgVO : allOrgVOs) {
|
||||
String parentId = StringUtils.isBlank(orgVO.getUpOrgId()) ? rootOrgCode : orgVO.getUpOrgId();
|
||||
parentToChildrenMap.computeIfAbsent(parentId, k -> new ArrayList<>()).add(orgVO);
|
||||
}
|
||||
|
||||
// 获取根节点ID
|
||||
String rootNode = StringUtils.isNotBlank(org.getOrgId()) ? org.getOrgId() : rootOrgCode;
|
||||
|
||||
// 使用StringBuilder记录所有部门ID
|
||||
StringBuilder allDepartmentIdBuilder = new StringBuilder(rootNode);
|
||||
|
||||
// 构建多级树结构(从根节点开始递归)
|
||||
List<SysOrgVO> rootChildren = parentToChildrenMap.getOrDefault(rootNode, new ArrayList<>());
|
||||
for (SysOrgVO rootChild : rootChildren) {
|
||||
buildMultiLevelTree(rootChild, parentToChildrenMap, allDepartmentIdBuilder);
|
||||
voList.add(rootChild);
|
||||
}
|
||||
|
||||
// 设置全量部门ID
|
||||
voList.forEach(vo -> vo.setAllDepartmentId(allDepartmentIdBuilder.toString()));
|
||||
|
||||
return voList;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归构建多级组织机构树结构
|
||||
*
|
||||
* @param currentNode 当前需要处理的组织机构节点
|
||||
* @param parentToChildrenMap 父节点ID到子节点列表的映射表(预处理结果,用于O(1)时间查找子节点)
|
||||
* @param allDepartmentIdBuilder 记录所有层级部门ID的字符串构建器(按层级顺序累加)
|
||||
* @apiNote 通过递归方式为当前节点设置子节点,并继续处理子节点的子节点,最终形成完整的多级树结构。
|
||||
* 依赖预处理的{@code parentToChildrenMap}提升查找子节点效率,避免重复遍历全量数据。
|
||||
*/
|
||||
private void buildMultiLevelTree(SysOrgVO currentNode,
|
||||
Map<String, List<SysOrgVO>> parentToChildrenMap,
|
||||
StringBuilder allDepartmentIdBuilder) {
|
||||
// 从映射表直接获取当前节点的子节点(O(1))
|
||||
List<SysOrgVO> children = parentToChildrenMap.getOrDefault(currentNode.getOrgId(), new ArrayList<>());
|
||||
|
||||
// 排序
|
||||
List<SysOrgVO> sortedChildren = children.stream()
|
||||
.sorted(Comparator.comparing(SysOrgVO::getSort, Comparator.nullsLast(String::compareTo)))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
currentNode.setChildren(sortedChildren);
|
||||
|
||||
// 记录当前节点ID,累加所有层级ID
|
||||
allDepartmentIdBuilder.append(",").append(currentNode.getOrgId());
|
||||
|
||||
// 递归处理子节点
|
||||
for (SysOrgVO child : sortedChildren) {
|
||||
buildMultiLevelTree(child, parentToChildrenMap, allDepartmentIdBuilder);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean insertByVo(SysOrgVO vo) {
|
||||
vo.setOrgId(PropertyUtils.getSnowflakeId()).setCreateDate(LocalDateTime.now());
|
||||
@ -165,37 +206,6 @@ public class SysOrgServiceImpl extends BaseServiceImpl<SysOrgMapper,SysOrg> imp
|
||||
.setKey(orgVO.getOrgId())
|
||||
.setValue(orgVO.getOrgId());
|
||||
}
|
||||
/**
|
||||
* 递归查询部门信息树形展示
|
||||
*
|
||||
* @param sysOrgVOList 所有部门信息
|
||||
* @param sysOrg 当前查询节点
|
||||
*/
|
||||
private void getChildrenNode(List<SysOrgVO> sysOrgVOList, SysOrgVO sysOrg, String allDepartmentId) {
|
||||
|
||||
List<SysOrgVO> childrenNodeList = new ArrayList<>();
|
||||
|
||||
for (SysOrgVO sysOrgVO : sysOrgVOList) {
|
||||
//判断机构部门上级ID和当前节点ID是否相等
|
||||
if (StringUtils.equals(sysOrg.getOrgId(), sysOrgVO.getUpOrgId())) {
|
||||
childrenNodeList.add(sysOrgVO);
|
||||
allDepartmentId += sysOrgVO.getOrgId();
|
||||
getChildrenNode(sysOrgVOList, sysOrgVO, allDepartmentId);
|
||||
}
|
||||
}
|
||||
//判断是否有下级节点
|
||||
if (!CollectionUtils.isEmpty(childrenNodeList)) {
|
||||
//根据sort排序
|
||||
childrenNodeList = childrenNodeList
|
||||
.stream()
|
||||
.map(this::setInfoForTree)
|
||||
.sorted(Comparator.comparing(SysOrgVO::getSort, Comparator.nullsLast(String::compareTo)))
|
||||
.collect(Collectors.toList());
|
||||
sysOrg.setChildren(childrenNodeList);
|
||||
} else {
|
||||
sysOrg.setChildren(ListUtil.empty());
|
||||
}
|
||||
}
|
||||
|
||||
private LambdaQueryWrapper<SysOrg> buildQueryWrapper(SysOrgVO vo) {
|
||||
LambdaQueryWrapper<SysOrg> lqw = Wrappers.lambdaQuery();
|
||||
|
Reference in New Issue
Block a user