perf: 零部件性能优化
This commit is contained in:
+2
-12
@@ -3,7 +3,6 @@ package com.jero.modules.laws.standard.controller;
|
|||||||
import com.jero.common.api.vo.Result;
|
import com.jero.common.api.vo.Result;
|
||||||
import com.jero.common.aspect.annotation.AutoLog;
|
import com.jero.common.aspect.annotation.AutoLog;
|
||||||
import com.jero.modules.laws.standard.entity.PartName;
|
import com.jero.modules.laws.standard.entity.PartName;
|
||||||
import com.jero.modules.laws.standard.entity.TreePage;
|
|
||||||
import com.jero.modules.laws.standard.service.ILawsPartNameService;
|
import com.jero.modules.laws.standard.service.ILawsPartNameService;
|
||||||
import io.swagger.annotations.Api;
|
import io.swagger.annotations.Api;
|
||||||
import io.swagger.annotations.ApiOperation;
|
import io.swagger.annotations.ApiOperation;
|
||||||
@@ -31,17 +30,8 @@ public class LawsPartNameController {
|
|||||||
@AutoLog(value = "企业标准-零部件树")
|
@AutoLog(value = "企业标准-零部件树")
|
||||||
@ApiOperation(value = "企业标准-零部件树", notes = "企业标准-零部件树")
|
@ApiOperation(value = "企业标准-零部件树", notes = "企业标准-零部件树")
|
||||||
@GetMapping("/")
|
@GetMapping("/")
|
||||||
public Result<TreePage<PartName>> queryENTreeList(
|
public Result<List<PartName>> queryENTreeList() {
|
||||||
@RequestParam(name = "nodeName", required = false, defaultValue = "") @ApiParam("一级节点名称") String nodeName,
|
List<PartName> list = IPartNameService.queryTreeList();
|
||||||
@RequestParam(name = "pageNo", defaultValue = "1") @ApiParam("页码") Integer pageNo,
|
|
||||||
@RequestParam(name = "pageSize", defaultValue = "10") @ApiParam("页面大小") Integer pageSize) {
|
|
||||||
if (pageNo == null) {
|
|
||||||
pageNo = 1;
|
|
||||||
}
|
|
||||||
if (pageSize == null) {
|
|
||||||
pageSize = 5;
|
|
||||||
}
|
|
||||||
TreePage<PartName> list = IPartNameService.queryTreeList(nodeName, pageNo, pageSize);
|
|
||||||
return Result.OK(list);
|
return Result.OK(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-6
@@ -2,7 +2,6 @@ package com.jero.modules.laws.standard.service;
|
|||||||
|
|
||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
import com.jero.modules.laws.standard.entity.PartName;
|
import com.jero.modules.laws.standard.entity.PartName;
|
||||||
import com.jero.modules.laws.standard.entity.TreePage;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -16,13 +15,9 @@ public interface ILawsPartNameService extends IService<PartName> {
|
|||||||
/**
|
/**
|
||||||
* 查询零部件树
|
* 查询零部件树
|
||||||
*
|
*
|
||||||
* @param nodeName 节点名称
|
|
||||||
* @param pageNo 页码
|
|
||||||
* @param pageSize 页面大小
|
|
||||||
* @return 零部件树
|
* @return 零部件树
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
List<PartName> queryTreeList();
|
||||||
TreePage<PartName> queryTreeList(String nodeName, Integer pageNo, Integer pageSize);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 零部件树选中回显
|
* 零部件树选中回显
|
||||||
|
|||||||
+40
-89
@@ -3,10 +3,8 @@ package com.jero.modules.laws.standard.service.impl;
|
|||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import com.jero.common.constant.enums.YesOrNoEnum;
|
|
||||||
import com.jero.common.exception.JeroBootException;
|
import com.jero.common.exception.JeroBootException;
|
||||||
import com.jero.modules.laws.standard.entity.PartName;
|
import com.jero.modules.laws.standard.entity.PartName;
|
||||||
import com.jero.modules.laws.standard.entity.TreePage;
|
|
||||||
import com.jero.modules.laws.standard.mapper.PartNameMapper;
|
import com.jero.modules.laws.standard.mapper.PartNameMapper;
|
||||||
import com.jero.modules.laws.standard.service.ILawsPartNameService;
|
import com.jero.modules.laws.standard.service.ILawsPartNameService;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
@@ -33,54 +31,10 @@ public class PartNameServiceImpl extends ServiceImpl<PartNameMapper, PartName>
|
|||||||
private PartNameMapper partNameMapper;
|
private PartNameMapper partNameMapper;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TreePage<PartName> queryTreeList(String nodeName, Integer pageNo, Integer pageSize) {
|
public List<PartName> queryTreeList() {
|
||||||
LambdaQueryWrapper<PartName> queryWrapper = new LambdaQueryWrapper<>();
|
List<PartName> allNodes = list();
|
||||||
List<PartName> topLevelNodes;
|
// 构建完整的树形结构
|
||||||
queryWrapper.eq(PartName::getDelFlag, YesOrNoEnum.NO.getValue())
|
return buildTree(new HashSet<>(allNodes)); // 直接返回构建的树形列表
|
||||||
.like(StrUtil.isNotBlank(nodeName), PartName::getName, nodeName);
|
|
||||||
List<PartName> allNodes = partNameMapper.selectList(queryWrapper);
|
|
||||||
List<String> firstNodeCodeList = allNodes.stream()
|
|
||||||
.map(PartName::getFirstNode)
|
|
||||||
.distinct()
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
// 不做筛选的时候查询加速
|
|
||||||
if (StrUtil.isBlank(nodeName)) {
|
|
||||||
// 构建树结构
|
|
||||||
topLevelNodes = this.buildTree(allNodes);
|
|
||||||
} else {
|
|
||||||
// 做筛选的时候需要自己组树
|
|
||||||
queryWrapper.clear();
|
|
||||||
queryWrapper.eq(PartName::getDelFlag, YesOrNoEnum.NO.getValue())
|
|
||||||
.in(PartName::getFirstNode, firstNodeCodeList)
|
|
||||||
.or().in(PartName::getCode, firstNodeCodeList);
|
|
||||||
List<PartName> allNodeList = partNameMapper.selectList(queryWrapper);
|
|
||||||
|
|
||||||
// 构建树形结构
|
|
||||||
Set<PartName> nodesSet = new HashSet<>();
|
|
||||||
for (PartName node : allNodes) {
|
|
||||||
nodesSet.addAll(findPathToRoot(allNodeList, node));
|
|
||||||
nodesSet.addAll(findAllChildren(allNodeList, node));
|
|
||||||
}
|
|
||||||
topLevelNodes = this.buildTree(nodesSet);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!topLevelNodes.isEmpty()) {
|
|
||||||
if (topLevelNodes.get(0).getParentCode().equals("0")) {
|
|
||||||
topLevelNodes = topLevelNodes.get(0).getChildPartNameList();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 实现分页逻辑
|
|
||||||
int start = (pageNo - 1) * pageSize;
|
|
||||||
int end = Math.min(start + pageSize, topLevelNodes.size());
|
|
||||||
List<PartName> pageData = topLevelNodes.subList(start, end);
|
|
||||||
|
|
||||||
// 封装分页信息
|
|
||||||
TreePage<PartName> result = new TreePage<>();
|
|
||||||
result.setRecords(pageData);
|
|
||||||
result.setTotal(topLevelNodes.size());
|
|
||||||
result.setSize(pageSize);
|
|
||||||
result.setCurrent(pageNo);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<PartName> buildTree(Collection<PartName> nodesCollection) {
|
private List<PartName> buildTree(Collection<PartName> nodesCollection) {
|
||||||
@@ -103,6 +57,8 @@ public class PartNameServiceImpl extends ServiceImpl<PartNameMapper, PartName>
|
|||||||
for (PartName node : nodesCollection) {
|
for (PartName node : nodesCollection) {
|
||||||
node.setLeafFlag(node.getChildPartNameList() == null || node.getChildPartNameList().isEmpty());
|
node.setLeafFlag(node.getChildPartNameList() == null || node.getChildPartNameList().isEmpty());
|
||||||
}
|
}
|
||||||
|
// 排序
|
||||||
|
topLevelNodes.sort(Comparator.comparing(PartName::getName));
|
||||||
return topLevelNodes;
|
return topLevelNodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -185,13 +141,16 @@ public class PartNameServiceImpl extends ServiceImpl<PartNameMapper, PartName>
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<PartName> queryList(String nodeName) {
|
public List<PartName> queryList(String nodeName) {
|
||||||
// 查询所有节点并建立父节点映射
|
// 查询所有节点
|
||||||
LambdaQueryWrapper<PartName> queryWrapper = new LambdaQueryWrapper<>();
|
LambdaQueryWrapper<PartName> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
List<PartName> allNodes = list(queryWrapper);
|
List<PartName> allNodes = list(queryWrapper);
|
||||||
Map<String, PartName> nodeMap = allNodes.stream()
|
|
||||||
.collect(Collectors.toMap(PartName::getCode, node -> node));
|
|
||||||
|
|
||||||
// 通过 nodeName 过滤符合条件的节点
|
// 通过 nodeName 过滤符合条件的节点
|
||||||
|
Map<String, PartName> nodeMap = allNodes.parallelStream()
|
||||||
|
.collect(Collectors.toConcurrentMap(PartName::getCode, Function.identity()));
|
||||||
|
Map<String, List<PartName>> parentChildMap = allNodes.parallelStream()
|
||||||
|
.collect(Collectors.groupingByConcurrent(PartName::getParentCode));
|
||||||
|
|
||||||
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());
|
||||||
@@ -200,13 +159,11 @@ public class PartNameServiceImpl extends ServiceImpl<PartNameMapper, PartName>
|
|||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 用于存储一级节点
|
// 查找每个匹配节点的一级父节点
|
||||||
Set<PartName> rootNodes = ConcurrentHashMap.newKeySet();
|
Set<PartName> rootNodes = 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("Part")) {
|
||||||
currentNode = nodeMap.get(currentNode.getParentCode());
|
currentNode = nodeMap.get(currentNode.getParentCode());
|
||||||
}
|
}
|
||||||
if (currentNode != null) {
|
if (currentNode != null) {
|
||||||
@@ -214,34 +171,27 @@ public class PartNameServiceImpl extends ServiceImpl<PartNameMapper, PartName>
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 并行设置叶子标志
|
// 设置叶子标志
|
||||||
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()
|
rootNode.setLeafFlag(children == null || children.isEmpty());
|
||||||
.noneMatch(matchedNode -> descendantCodes.contains(matchedNode.getCode()));
|
|
||||||
node.setLeafFlag(isLeaf);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// 按名字排序
|
|
||||||
return rootNodes.stream()
|
return rootNodes.stream()
|
||||||
.sorted(Comparator.comparing(PartName::getName))
|
.sorted(Comparator.comparing(PartName::getName))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
// 方法:获取给定节点ID的所有子孙节点ID
|
// 方法:获取给定节点ID的所有子孙节点ID
|
||||||
private Set<String> getAllDescendantCodes(String parentCode, Map<String, PartName> nodeMap) {
|
private Set<String> getAllDescendantCodes(String parentCode, List<PartName> allNodes) {
|
||||||
Set<String> descendantCodes = new HashSet<>();
|
Set<String> descendantCodes = new HashSet<>();
|
||||||
Deque<String> stack = new ArrayDeque<>();
|
List<PartName> directChildren = allNodes.stream()
|
||||||
stack.push(parentCode);
|
.filter(node -> node.getParentCode().equals(parentCode))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
while (!stack.isEmpty()) {
|
for (PartName child : directChildren) {
|
||||||
String currentCode = stack.pop();
|
descendantCodes.add(child.getCode());
|
||||||
nodeMap.values().parallelStream()
|
descendantCodes.addAll(getAllDescendantCodes(child.getCode(), allNodes)); // 递归获取子孙节点
|
||||||
.filter(node -> node.getParentCode().equals(currentCode))
|
|
||||||
.forEach(child -> {
|
|
||||||
descendantCodes.add(child.getCode());
|
|
||||||
stack.push(child.getCode());
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return descendantCodes;
|
return descendantCodes;
|
||||||
@@ -249,13 +199,17 @@ public class PartNameServiceImpl extends ServiceImpl<PartNameMapper, PartName>
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<PartName> getChild(String parentCode, String nodeName) {
|
public List<PartName> getChild(String parentCode, String nodeName) {
|
||||||
// 查询所有节点并建立父节点映射
|
// 查询所有节点
|
||||||
LambdaQueryWrapper<PartName> queryWrapper = new LambdaQueryWrapper<>();
|
LambdaQueryWrapper<PartName> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
List<PartName> allNodes = list(queryWrapper);
|
List<PartName> allNodes = list(queryWrapper);
|
||||||
Map<String, PartName> nodeMap = allNodes.stream()
|
|
||||||
.collect(Collectors.toMap(PartName::getCode, node -> node));
|
|
||||||
|
|
||||||
// 通过 nodeName 过滤符合条件的节点
|
// 构建节点映射,以及父子关系映射
|
||||||
|
Map<String, PartName> nodeMap = allNodes.parallelStream()
|
||||||
|
.collect(Collectors.toConcurrentMap(PartName::getCode, Function.identity()));
|
||||||
|
Map<String, List<PartName>> parentChildMap = allNodes.parallelStream()
|
||||||
|
.collect(Collectors.groupingByConcurrent(PartName::getParentCode));
|
||||||
|
|
||||||
|
// 过滤符合条件的节点
|
||||||
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());
|
||||||
@@ -264,13 +218,11 @@ public class PartNameServiceImpl extends ServiceImpl<PartNameMapper, PartName>
|
|||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 用于存储一级节点
|
// 查找每个匹配节点的一级父节点
|
||||||
Set<PartName> rootNodes = ConcurrentHashMap.newKeySet();
|
Set<PartName> rootNodes = ConcurrentHashMap.newKeySet();
|
||||||
|
|
||||||
// 并行查找每个匹配节点的一级父节点
|
|
||||||
matchedNodes.parallelStream().forEach(matchedNode -> {
|
matchedNodes.parallelStream().forEach(matchedNode -> {
|
||||||
PartName currentNode = matchedNode;
|
PartName currentNode = matchedNode;
|
||||||
while (currentNode != null && !parentCode.equals(currentNode.getParentCode())) {
|
while (currentNode != null && !currentNode.getParentCode().equals(parentCode)) {
|
||||||
currentNode = nodeMap.get(currentNode.getParentCode());
|
currentNode = nodeMap.get(currentNode.getParentCode());
|
||||||
}
|
}
|
||||||
if (currentNode != null) {
|
if (currentNode != null) {
|
||||||
@@ -278,12 +230,10 @@ public class PartNameServiceImpl extends ServiceImpl<PartNameMapper, PartName>
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 并行设置叶子标志
|
// 设置叶子标志
|
||||||
rootNodes.parallelStream().forEach(node -> {
|
rootNodes.parallelStream().forEach(rootNode -> {
|
||||||
boolean isLeaf = matchedNodes.stream()
|
List<PartName> children = parentChildMap.get(rootNode.getCode());
|
||||||
.noneMatch(n -> parentCode.equals(n.getParentCode()) &&
|
rootNode.setLeafFlag(children == null || children.isEmpty());
|
||||||
n.getParentCode().equals(node.getCode()));
|
|
||||||
node.setLeafFlag(isLeaf);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// 按名字排序
|
// 按名字排序
|
||||||
@@ -292,6 +242,7 @@ public class PartNameServiceImpl extends ServiceImpl<PartNameMapper, PartName>
|
|||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private PartName getFirstLevelNode(PartName node, Map<String, PartName> nodeMap) {
|
private PartName getFirstLevelNode(PartName node, Map<String, PartName> nodeMap) {
|
||||||
if (node.getParentCode().equals("Part")) {
|
if (node.getParentCode().equals("Part")) {
|
||||||
return node;
|
return node;
|
||||||
|
|||||||
Reference in New Issue
Block a user