fix:数据总览,兼容同类型多级构建
This commit is contained in:
@@ -2293,94 +2293,180 @@ public class NodeServiceImpl extends ServiceImpl<SimulationNodeMapper, Simulatio
|
||||
|
||||
@Override
|
||||
public SdmResponse<List<AllNodeByProjectIdAndTypeResp>> getAllNodeByProjectIdAndType(List<String> uuids, String nextNodeType) {
|
||||
Map<String, String> TagMap = tagMapService.getTagMapName();
|
||||
if ( ObjectUtils.isEmpty(TagMap)) {
|
||||
if (CollectionUtils.isEmpty(uuids) || StringUtils.isBlank(nextNodeType)) {
|
||||
return SdmResponse.success();
|
||||
}
|
||||
|
||||
Map<String, String> tagMap = tagMapService.getTagMapName();
|
||||
if (ObjectUtils.isEmpty(tagMap)) {
|
||||
log.error("字典信息查询失败");
|
||||
return SdmResponse.success();
|
||||
}
|
||||
|
||||
Optional<SimulationNode> simulationNodeOptional = this.lambdaQuery().in(SimulationNode::getUuid, uuids).list().stream().findFirst();
|
||||
if (!simulationNodeOptional.isPresent()) {
|
||||
List<SimulationNode> currentNodes = this.lambdaQuery()
|
||||
.in(SimulationNode::getUuid, uuids)
|
||||
.list();
|
||||
if (CollectionUtils.isEmpty(currentNodes)) {
|
||||
return SdmResponse.failed("未找到节点");
|
||||
}
|
||||
|
||||
SimulationNode currentNode = simulationNodeOptional.get();
|
||||
SimulationNode currentNode = currentNodes.get(0);
|
||||
String currentNodeType = currentNode.getNodeType();
|
||||
String currentNodeTag = TagMap.get(currentNodeType);
|
||||
|
||||
String nextNodeTag = TagMap.get(nextNodeType);
|
||||
|
||||
// 当前节点向前搜索
|
||||
List<String> preUUids = this.lambdaQuery()
|
||||
.in(TagConstant.TAG1.equals(currentNodeTag), SimulationNode::getTag1, uuids)
|
||||
.in(TagConstant.TAG2.equals(currentNodeTag), SimulationNode::getTag2, uuids)
|
||||
.in(TagConstant.TAG3.equals(currentNodeTag), SimulationNode::getTag3, uuids)
|
||||
.in(TagConstant.TAG4.equals(currentNodeTag), SimulationNode::getTag4, uuids)
|
||||
.in(TagConstant.TAG5.equals(currentNodeTag), SimulationNode::getTag5, uuids)
|
||||
.in(TagConstant.TAG6.equals(currentNodeTag), SimulationNode::getTag6, uuids)
|
||||
.in(TagConstant.TAG7.equals(currentNodeTag), SimulationNode::getTag7, uuids)
|
||||
.in(TagConstant.TAG8.equals(currentNodeTag), SimulationNode::getTag8, uuids)
|
||||
.in(TagConstant.TAG9.equals(currentNodeTag), SimulationNode::getTag9, uuids)
|
||||
.in(TagConstant.TAG10.equals(currentNodeTag), SimulationNode::getTag10, uuids)
|
||||
.orderByDesc(SimulationNode::getCreateTime)
|
||||
.list().stream().map(simulationNode -> {
|
||||
if (TagConstant.TAG1.equals(nextNodeTag)) {
|
||||
return simulationNode.getTag1();
|
||||
} else if (TagConstant.TAG2.equals(nextNodeTag)) {
|
||||
return simulationNode.getTag2();
|
||||
} else if (TagConstant.TAG3.equals(nextNodeTag)) {
|
||||
return simulationNode.getTag3();
|
||||
} else if (TagConstant.TAG4.equals(nextNodeTag)) {
|
||||
return simulationNode.getTag4();
|
||||
} else if (TagConstant.TAG5.equals(nextNodeTag)) {
|
||||
return simulationNode.getTag5();
|
||||
} else if (TagConstant.TAG6.equals(nextNodeTag)) {
|
||||
return simulationNode.getTag6();
|
||||
} else if (TagConstant.TAG7.equals(nextNodeTag)) {
|
||||
return simulationNode.getTag7();
|
||||
} else if (TagConstant.TAG8.equals(nextNodeTag)) {
|
||||
return simulationNode.getTag8();
|
||||
} else if (TagConstant.TAG9.equals(nextNodeTag)) {
|
||||
return simulationNode.getTag9();
|
||||
} else if (TagConstant.TAG10.equals(nextNodeTag)) {
|
||||
return simulationNode.getTag10();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
).toList();
|
||||
List<SimulationNode> preSimulationNodeList = this.lambdaQuery().in(SimulationNode::getUuid, preUUids).list();
|
||||
|
||||
|
||||
// 当前节点向后搜索
|
||||
List<SimulationNode> simulationNodeList = this.lambdaQuery()
|
||||
.in(TagConstant.TAG1.equals(currentNodeTag), SimulationNode::getTag1, uuids)
|
||||
.in(TagConstant.TAG2.equals(currentNodeTag), SimulationNode::getTag2, uuids)
|
||||
.in(TagConstant.TAG3.equals(currentNodeTag), SimulationNode::getTag3, uuids)
|
||||
.in(TagConstant.TAG4.equals(currentNodeTag), SimulationNode::getTag4, uuids)
|
||||
.in(TagConstant.TAG5.equals(currentNodeTag), SimulationNode::getTag5, uuids)
|
||||
.in(TagConstant.TAG6.equals(currentNodeTag), SimulationNode::getTag6, uuids)
|
||||
.in(TagConstant.TAG7.equals(currentNodeTag), SimulationNode::getTag7, uuids)
|
||||
.in(TagConstant.TAG8.equals(currentNodeTag), SimulationNode::getTag8, uuids)
|
||||
.in(TagConstant.TAG9.equals(currentNodeTag), SimulationNode::getTag9, uuids)
|
||||
.in(TagConstant.TAG10.equals(currentNodeTag), SimulationNode::getTag10, uuids)
|
||||
.eq(SimulationNode::getNodeType, nextNodeType)
|
||||
// 先查当前节点下是否存在同类型直接子节点(连续同类型场景)
|
||||
List<SimulationNode> sameTypeChildren = this.lambdaQuery()
|
||||
.in(SimulationNode::getParentId, uuids)
|
||||
.eq(SimulationNode::getNodeType, currentNodeType)
|
||||
.orderByDesc(SimulationNode::getCreateTime)
|
||||
.list();
|
||||
log.info("getAllNodeByProjectIdAndType sameTypeChildren size:{}, currentNodeType:{}, inputUuidsSize:{}",
|
||||
sameTypeChildren.size(), currentNodeType, uuids.size());
|
||||
|
||||
Set<String> matchedParentUuids = sameTypeChildren.stream()
|
||||
.map(SimulationNode::getParentId)
|
||||
.filter(StringUtils::isNotBlank)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
List<String> remainingUuids = uuids.stream()
|
||||
.filter(uuid -> !matchedParentUuids.contains(uuid))
|
||||
.toList();
|
||||
log.info("getAllNodeByProjectIdAndType remainingUuids size:{}, matchedParentUuids size:{}",
|
||||
remainingUuids.size(), matchedParentUuids.size());
|
||||
|
||||
List<SimulationNode> simulationNodeList = new ArrayList<>(sameTypeChildren);
|
||||
|
||||
// 当 nextNodeType 与 currentNodeType 相同(最后一层继续同类型下钻)时,
|
||||
// 仅允许返回直接子节点,禁止对 remainingUuids 走 tag 链路查询,避免引入平级数据。
|
||||
if (StringUtils.equals(currentNodeType, nextNodeType)) {
|
||||
if (CollectionUtils.isEmpty(simulationNodeList)) {
|
||||
return SdmResponse.success();
|
||||
}
|
||||
return SdmResponse.success(buildNodeRespList(simulationNodeList));
|
||||
}
|
||||
|
||||
if (CollectionUtils.isNotEmpty(remainingUuids)) {
|
||||
String currentNodeTag = tagMap.get(currentNodeType);
|
||||
String nextNodeTag = tagMap.get(nextNodeType);
|
||||
if (StringUtils.isBlank(currentNodeTag) || StringUtils.isBlank(nextNodeTag)) {
|
||||
log.error("节点类型未配置tag映射,currentNodeType:{},nextNodeType:{}", currentNodeType, nextNodeType);
|
||||
if (CollectionUtils.isEmpty(simulationNodeList)) {
|
||||
return SdmResponse.success();
|
||||
}
|
||||
} else {
|
||||
// 规则1:剩余节点不能直接拿uuid去匹配tag,必须先取出当前层对应的tag值(兼容tag链路逗号拼接)
|
||||
List<String> currentTagValues = extractTagValuesByNodeTag(currentNodes, remainingUuids, currentNodeTag);
|
||||
if (CollectionUtils.isEmpty(currentTagValues)) {
|
||||
log.info("getAllNodeByProjectIdAndType currentTagValues empty, currentNodeTag:{}, remainingUuidsSize:{}",
|
||||
currentNodeTag, remainingUuids.size());
|
||||
} else {
|
||||
// 规则2:按当前层tag值定位同链路节点,再映射到下一层tag值并反查uuid
|
||||
List<SimulationNode> matchedChainNodes = queryNodesByCurrentTagValues(currentNodeTag, currentTagValues);
|
||||
List<String> preUUids = matchedChainNodes.stream()
|
||||
.map(simulationNode -> resolveTagValue(simulationNode, nextNodeTag))
|
||||
.filter(StringUtils::isNotBlank)
|
||||
.map(tag-> {
|
||||
return tag.split(",")[0];
|
||||
})
|
||||
.toList();
|
||||
|
||||
List<SimulationNode> preSimulationNodeList = CollectionUtils.isEmpty(preUUids)
|
||||
? Collections.emptyList()
|
||||
: this.lambdaQuery().in(SimulationNode::getUuid, preUUids).list();
|
||||
simulationNodeList.addAll(preSimulationNodeList);
|
||||
// 规则3:同时保留原有“按nextNodeType正向查下一层”能力
|
||||
/* List<SimulationNode> nextTypeNodeList = matchedChainNodes.stream()
|
||||
.filter(node -> StringUtils.equals(node.getNodeType(), nextNodeType))
|
||||
.toList();
|
||||
simulationNodeList.addAll(nextTypeNodeList);
|
||||
*/
|
||||
log.info("getAllNodeByProjectIdAndType matchedChainNodes size:{}, nextNodeType:{}",
|
||||
matchedChainNodes.size(), nextNodeType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
simulationNodeList.addAll(preSimulationNodeList);
|
||||
if (CollectionUtils.isEmpty(simulationNodeList)) {
|
||||
return SdmResponse.success();
|
||||
}
|
||||
List<AllNodeByProjectIdAndTypeResp> allNodeByProjectIdAndTypeRespList = new ArrayList<>();
|
||||
simulationNodeList.forEach(simulationNode -> {
|
||||
AllNodeByProjectIdAndTypeResp allNodeByProjectIdAndTypeResp = new AllNodeByProjectIdAndTypeResp();
|
||||
BeanUtils.copyProperties(simulationNode, allNodeByProjectIdAndTypeResp);
|
||||
allNodeByProjectIdAndTypeResp.setId(simulationNode.getId().longValue());
|
||||
allNodeByProjectIdAndTypeRespList.add(allNodeByProjectIdAndTypeResp);
|
||||
});
|
||||
|
||||
return SdmResponse.success(allNodeByProjectIdAndTypeRespList);
|
||||
return SdmResponse.success(buildNodeRespList(simulationNodeList));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据当前节点类型对应的tag位,从当前节点集合中提取tag值。
|
||||
* 说明:
|
||||
* 1) 这里只从 remainingUuids 对应节点提取,避免混入已命中同类型子节点的父节点;
|
||||
* 2) 提取的是 tag 字段值,不是 uuid,兼容 tag4 这类“逗号拼接链路”场景;
|
||||
* 3) 统一去空和去重,减少后续 in 查询的数据量。
|
||||
*/
|
||||
private List<String> extractTagValuesByNodeTag(List<SimulationNode> currentNodes, List<String> remainingUuids, String currentNodeTag) {
|
||||
return currentNodes.stream()
|
||||
.filter(node -> remainingUuids.contains(node.getUuid()))
|
||||
.map(node -> resolveTagValue(node, currentNodeTag))
|
||||
.filter(StringUtils::isNotBlank)
|
||||
.distinct()
|
||||
.toList();
|
||||
}
|
||||
|
||||
/**
|
||||
* 按“当前层tag值”查询同链路节点。
|
||||
* 规则:tag字段存的是层级链路值,因此这里必须用 tag 值匹配,不使用 uuid 直接匹配 tag 字段。
|
||||
*/
|
||||
private List<SimulationNode> queryNodesByCurrentTagValues(String currentNodeTag, List<String> currentTagValues) {
|
||||
return this.lambdaQuery()
|
||||
.in(TagConstant.TAG1.equals(currentNodeTag), SimulationNode::getTag1, currentTagValues)
|
||||
.in(TagConstant.TAG2.equals(currentNodeTag), SimulationNode::getTag2, currentTagValues)
|
||||
.in(TagConstant.TAG3.equals(currentNodeTag), SimulationNode::getTag3, currentTagValues)
|
||||
.in(TagConstant.TAG4.equals(currentNodeTag), SimulationNode::getTag4, currentTagValues)
|
||||
.in(TagConstant.TAG5.equals(currentNodeTag), SimulationNode::getTag5, currentTagValues)
|
||||
.in(TagConstant.TAG6.equals(currentNodeTag), SimulationNode::getTag6, currentTagValues)
|
||||
.in(TagConstant.TAG7.equals(currentNodeTag), SimulationNode::getTag7, currentTagValues)
|
||||
.in(TagConstant.TAG8.equals(currentNodeTag), SimulationNode::getTag8, currentTagValues)
|
||||
.in(TagConstant.TAG9.equals(currentNodeTag), SimulationNode::getTag9, currentTagValues)
|
||||
.in(TagConstant.TAG10.equals(currentNodeTag), SimulationNode::getTag10, currentTagValues)
|
||||
.list();
|
||||
}
|
||||
|
||||
/**
|
||||
* 按 tag 位读取节点的 tag 值。
|
||||
*/
|
||||
private String resolveTagValue(SimulationNode node, String tag) {
|
||||
if (TagConstant.TAG1.equals(tag)) {
|
||||
return node.getTag1();
|
||||
} else if (TagConstant.TAG2.equals(tag)) {
|
||||
return node.getTag2();
|
||||
} else if (TagConstant.TAG3.equals(tag)) {
|
||||
return node.getTag3();
|
||||
} else if (TagConstant.TAG4.equals(tag)) {
|
||||
return node.getTag4();
|
||||
} else if (TagConstant.TAG5.equals(tag)) {
|
||||
return node.getTag5();
|
||||
} else if (TagConstant.TAG6.equals(tag)) {
|
||||
return node.getTag6();
|
||||
} else if (TagConstant.TAG7.equals(tag)) {
|
||||
return node.getTag7();
|
||||
} else if (TagConstant.TAG8.equals(tag)) {
|
||||
return node.getTag8();
|
||||
} else if (TagConstant.TAG9.equals(tag)) {
|
||||
return node.getTag9();
|
||||
} else if (TagConstant.TAG10.equals(tag)) {
|
||||
return node.getTag10();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将节点列表转为响应对象并按 uuid 去重,避免多路径合并导致重复。
|
||||
*/
|
||||
private List<AllNodeByProjectIdAndTypeResp> buildNodeRespList(List<SimulationNode> simulationNodeList) {
|
||||
return simulationNodeList.stream()
|
||||
.collect(Collectors.toMap(SimulationNode::getUuid, Function.identity(), (a, b) -> a, LinkedHashMap::new))
|
||||
.values().stream().map(simulationNode -> {
|
||||
AllNodeByProjectIdAndTypeResp resp = new AllNodeByProjectIdAndTypeResp();
|
||||
BeanUtils.copyProperties(simulationNode, resp);
|
||||
resp.setId(simulationNode.getId().longValue());
|
||||
return resp;
|
||||
}).toList();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user