fix: 零部件懒加载搜索

This commit is contained in:
2024-08-28 17:36:47 +08:00
parent bd6858af99
commit fe48cc49af
3 changed files with 31 additions and 85 deletions
@@ -66,7 +66,7 @@ public class LawsPartNameController {
@GetMapping("/queryFirstList") @GetMapping("/queryFirstList")
public Result<List<PartName>> queryFirstList( public Result<List<PartName>> queryFirstList(
@RequestParam(name = "nodeName", required = false, defaultValue = "") @ApiParam("节点名称") String nodeName) { @RequestParam(name = "nodeName", required = false, defaultValue = "") @ApiParam("节点名称") String nodeName) {
List<PartName> list = partNameService.queryList(nodeName); List<PartName> list = partNameService.getTree("Part", nodeName);
return Result.OK(list); return Result.OK(list);
} }
@@ -76,7 +76,7 @@ public class LawsPartNameController {
@GetMapping("/getChild") @GetMapping("/getChild")
public Result<List<PartName>> getChild(@RequestParam("parentCode") String parentCode, public Result<List<PartName>> getChild(@RequestParam("parentCode") String parentCode,
@RequestParam("nodeName") String nodeName) { @RequestParam("nodeName") String nodeName) {
return Result.OK(partNameService.getChild(parentCode, nodeName)); return Result.OK(partNameService.getTree(parentCode, nodeName));
} }
} }
@@ -36,7 +36,8 @@ public interface PartNameService extends IService<PartName> {
*/ */
void fixFirstNodeCode(); void fixFirstNodeCode();
List<PartName> queryList(String nodeName); /**
* 零部件树懒加载
List<PartName> getChild(String parentCode, String nodeName); */
List<PartName> getTree(String parentCode, String nodeName);
} }
@@ -190,108 +190,53 @@ public class PartNameServiceImpl extends ServiceImpl<PartNameMapper, PartName>
return null; return null;
} }
@Override @Override
public List<PartName> queryList(String nodeName) { public List<PartName> getTree(String parentCode, String nodeName) {
// 查询所有节点并建立父节点映射 // 查询所有节点
LambdaQueryWrapper<PartName> queryWrapper = new LambdaQueryWrapper<>(); List<PartName> allNodes = list();
List<PartName> allNodes = list(queryWrapper);
Map<String, PartName> nodeMap = allNodes.stream()
.collect(Collectors.toMap(PartName::getCode, node -> node));
// 通过 nodeName 过滤符合条件的节点 // 过滤符合条件的节点
List<PartName> matchedNodes = allNodes.parallelStream() List<PartName> matchedNodes = allNodes.parallelStream()
.filter(node -> node.getName() != null && node.getName().contains(nodeName)) .filter(node -> node.getName() != null && node.getName().contains(nodeName))
.collect(Collectors.toList()); .collect(Collectors.toList());
// 构建节点映射,以及父子关系映射
Map<String, PartName> nodeMap = allNodes.parallelStream()
.collect(Collectors.toConcurrentMap(PartName::getCode, Function.identity()));
Map<String, List<PartName>> parentChildMap = matchedNodes.parallelStream()
.collect(Collectors.groupingByConcurrent(PartName::getParentCode));
if (matchedNodes.isEmpty()) { if (matchedNodes.isEmpty()) {
return Collections.emptyList(); return Collections.emptyList();
} }
// 用于存储一级节点 // 查找每个匹配节点的一级节点
Set<PartName> rootNodes = ConcurrentHashMap.newKeySet(); Set<PartName> rootNodes = ConcurrentHashMap.newKeySet();
Set<String> allParentNodeCodes = ConcurrentHashMap.newKeySet();
// 并行查找每个匹配节点的一级父节点
matchedNodes.parallelStream().forEach(matchedNode -> { matchedNodes.parallelStream().forEach(matchedNode -> {
PartName currentNode = matchedNode; PartName currentNode = matchedNode;
while (currentNode != null && !"Part".equals(currentNode.getParentCode())) { while (currentNode != null && !currentNode.getParentCode().equals(parentCode)) {
currentNode = nodeMap.get(currentNode.getParentCode()); currentNode = nodeMap.get(currentNode.getParentCode());
if (currentNode != null) {
allParentNodeCodes.add(currentNode.getCode());
}
} }
if (currentNode != null) { if (currentNode != null) {
rootNodes.add(currentNode); rootNodes.add(currentNode);
} }
}); });
// 并行设置叶子标志 // 设置叶子标志
rootNodes.parallelStream().forEach(node -> { rootNodes.parallelStream().forEach(rootNode -> {
Set<String> descendantCodes = getAllDescendantCodes(node.getCode(), nodeMap); List<PartName> children = parentChildMap.get(rootNode.getCode());
boolean isLeaf = matchedNodes.stream() boolean hasNoChildren = (children == null || children.isEmpty());
.noneMatch(matchedNode -> descendantCodes.contains(matchedNode.getCode()));
node.setLeafFlag(isLeaf);
});
// 按名字排序 if (StrUtil.isBlank(nodeName)) {
return rootNodes.stream() rootNode.setLeafFlag(hasNoChildren);
.sorted(Comparator.comparing(PartName::getName)) } else {
.collect(Collectors.toList()); boolean isNotInAllParents = !allParentNodeCodes.contains(rootNode.getCode());
} rootNode.setLeafFlag(hasNoChildren && isNotInAllParents);
// 优化后的获取子孙节点ID方法,使用节点映射避免重复计算
private Set<String> getAllDescendantCodes(String parentCode, Map<String, PartName> nodeMap) {
Set<String> descendantCodes = new HashSet<>();
Deque<String> stack = new ArrayDeque<>();
stack.push(parentCode);
while (!stack.isEmpty()) {
String currentCode = stack.pop();
nodeMap.values().parallelStream()
.filter(node -> node.getParentCode().equals(currentCode))
.forEach(child -> {
descendantCodes.add(child.getCode());
stack.push(child.getCode());
});
}
return descendantCodes;
}
@Override
public List<PartName> getChild(String parentCode, String nodeName) {
// 查询所有节点并建立父节点映射
LambdaQueryWrapper<PartName> queryWrapper = new LambdaQueryWrapper<>();
List<PartName> allNodes = list(queryWrapper);
Map<String, PartName> nodeMap = allNodes.stream()
.collect(Collectors.toMap(PartName::getCode, node -> node));
// 通过 nodeName 过滤符合条件的节点
List<PartName> matchedNodes = allNodes.parallelStream()
.filter(node -> node.getName() != null && node.getName().contains(nodeName))
.collect(Collectors.toList());
if (matchedNodes.isEmpty()) {
return Collections.emptyList();
}
// 用于存储一级节点
Set<PartName> rootNodes = ConcurrentHashMap.newKeySet();
// 并行查找每个匹配节点的一级父节点
matchedNodes.parallelStream().forEach(matchedNode -> {
PartName currentNode = matchedNode;
while (currentNode != null && !parentCode.equals(currentNode.getParentCode())) {
currentNode = nodeMap.get(currentNode.getParentCode());
} }
if (currentNode != null) {
rootNodes.add(currentNode);
}
});
// 并行设置叶子标志
rootNodes.parallelStream().forEach(node -> {
boolean isLeaf = matchedNodes.stream()
.noneMatch(n -> parentCode.equals(n.getParentCode()) &&
n.getParentCode().equals(node.getCode()));
node.setLeafFlag(isLeaf);
}); });
// 按名字排序 // 按名字排序