diff --git a/common/src/main/java/com/sdm/common/entity/enums/NodeTypeEnum.java b/common/src/main/java/com/sdm/common/entity/enums/NodeTypeEnum.java index 1c28a6cd..f3b99a91 100644 --- a/common/src/main/java/com/sdm/common/entity/enums/NodeTypeEnum.java +++ b/common/src/main/java/com/sdm/common/entity/enums/NodeTypeEnum.java @@ -24,12 +24,4 @@ public enum NodeTypeEnum { return value; } - /** - * 是否节点类型 - */ - public static boolean isNodeType(String value) { - return PROJECT.getValue().equals(value) || PHASE.getValue().equals(value) - || DISCIPLINE.getValue().equals(value) || MACHINE.getValue().equals(value) - || WORKSPACE.getValue().equals(value); - } } \ No newline at end of file diff --git a/common/src/main/java/com/sdm/common/entity/req/data/UploadFilesReq.java b/common/src/main/java/com/sdm/common/entity/req/data/UploadFilesReq.java index f87918b0..03df3075 100644 --- a/common/src/main/java/com/sdm/common/entity/req/data/UploadFilesReq.java +++ b/common/src/main/java/com/sdm/common/entity/req/data/UploadFilesReq.java @@ -135,6 +135,9 @@ public class UploadFilesReq { @Schema(description = "知识库文件审批模板名称") private String templateName; + @Schema(description = "是否需要覆盖同名文件") + private Boolean isConverSameNameFile; + /** * 扩展信息 */ diff --git a/common/src/main/java/com/sdm/common/service/TagMapService.java b/common/src/main/java/com/sdm/common/service/TagMapService.java index d74d716c..5b090d23 100644 --- a/common/src/main/java/com/sdm/common/service/TagMapService.java +++ b/common/src/main/java/com/sdm/common/service/TagMapService.java @@ -31,4 +31,12 @@ public class TagMapService { // project-->tag1 phase-->tag2 return tagMapList.getData().stream().collect(Collectors.toMap(DataDictionary::getDictValue, DataDictionary::getDictName)); } + + /** + * 是否节点类型 + */ + public boolean isNodeType(String tag) { + Map tagMap = getTagMapName(); + return tagMap.containsKey(tag); + } } diff --git a/data/src/main/java/com/sdm/data/model/req/QueryBigFileReq.java b/data/src/main/java/com/sdm/data/model/req/QueryBigFileReq.java index df1b2649..4bb20260 100644 --- a/data/src/main/java/com/sdm/data/model/req/QueryBigFileReq.java +++ b/data/src/main/java/com/sdm/data/model/req/QueryBigFileReq.java @@ -8,9 +8,7 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; +import java.util.*; @Data public class QueryBigFileReq extends BaseReq { @@ -22,7 +20,7 @@ public class QueryBigFileReq extends BaseReq { /** * 目录ID列表 */ - private List dirIds = new ArrayList<>(); + private Set dirIds = new HashSet<>(); /** * 目录ID列表的大小,用于 HAVING 子句 diff --git a/data/src/main/java/com/sdm/data/service/impl/DataAnalysisServiceImpl.java b/data/src/main/java/com/sdm/data/service/impl/DataAnalysisServiceImpl.java index e88b0cb1..0a9f8356 100644 --- a/data/src/main/java/com/sdm/data/service/impl/DataAnalysisServiceImpl.java +++ b/data/src/main/java/com/sdm/data/service/impl/DataAnalysisServiceImpl.java @@ -68,7 +68,7 @@ public class DataAnalysisServiceImpl implements IDataAnalysisService { BeanUtils.copyProperties(getSimulationTaskFileReq, queryBigFileReq); // 步骤 1: 收集所有直接传入的 dirId - List allDirIds = new ArrayList<>(); + Set allDirIds = new HashSet<>(); if (CollectionUtils.isNotEmpty(getSimulationTaskFileReq.getProjectDirIds())) { allDirIds.addAll(getSimulationTaskFileReq.getProjectDirIds()); } diff --git a/data/src/main/java/com/sdm/data/service/impl/DataStorageAnalysisImpl.java b/data/src/main/java/com/sdm/data/service/impl/DataStorageAnalysisImpl.java index 4466455f..56ec257b 100644 --- a/data/src/main/java/com/sdm/data/service/impl/DataStorageAnalysisImpl.java +++ b/data/src/main/java/com/sdm/data/service/impl/DataStorageAnalysisImpl.java @@ -554,7 +554,7 @@ public class DataStorageAnalysisImpl implements DataStorageAnalysis { } Long tenantId = ThreadLocalContext.getTenantId(); - List dirIds = CollectionUtils.isEmpty(queryBigFileReq.getDirIds()) ? null : queryBigFileReq.getDirIds(); + Set dirIds = CollectionUtils.isEmpty(queryBigFileReq.getDirIds()) ? null : queryBigFileReq.getDirIds(); // 查询符合标签的文件id return fileTagRelService.lambdaQuery() diff --git a/data/src/main/java/com/sdm/data/service/impl/DimensionTemplateServiceImpl.java b/data/src/main/java/com/sdm/data/service/impl/DimensionTemplateServiceImpl.java index 5cd59068..e6f1ccf1 100644 --- a/data/src/main/java/com/sdm/data/service/impl/DimensionTemplateServiceImpl.java +++ b/data/src/main/java/com/sdm/data/service/impl/DimensionTemplateServiceImpl.java @@ -26,6 +26,7 @@ import com.sdm.common.entity.resp.system.CIDUserResp; import com.sdm.common.feign.impl.project.SimulationNodeFeignClientImpl; import com.sdm.common.feign.impl.system.SysUserFeignClientImpl; import com.sdm.common.feign.inter.project.ISimulationTaskFeignClient; +import com.sdm.common.service.TagMapService; import com.sdm.common.utils.CidSysUserUtil; import com.sdm.common.utils.PageUtils; import com.sdm.data.convert.FileMetadataConvert; @@ -87,6 +88,10 @@ public class DimensionTemplateServiceImpl extends ServiceImpl chooseUuids = nodeDirInfos.stream().map(FileMetadataInfo::getRelatedResourceUuid).toList(); // chooseUuid和chooseNodeType不为空,并且是node节点类型,才是节点文件夹,才需要查询子节点文件夹文件 - if (ObjectUtils.isNotEmpty(chooseUuids) && ObjectUtils.isNotEmpty(chooseNodeType) && NodeTypeEnum.isNodeType(chooseNodeType)) { + if (ObjectUtils.isNotEmpty(chooseUuids) && ObjectUtils.isNotEmpty(chooseNodeType) && tagMapService.isNodeType(chooseNodeType)) { // 从dimensionNodeTyepOrderList中获取chooseNodeType下一个位置的数据,有可能chooseNodeType所在位置就是最后一层节点,SdmResponse返回空数据 int index = dimensionNodeTyepOrderList.indexOf(chooseNodeType); if (index == -1) { return SdmResponse.failed("选中节点类型不在数据展示维度中"); } - // 判断是否是最后一层节点,如果是最后一层节点,则不需要查询子节点文件 - if (index != dimensionNodeTyepOrderList.size() - 1) { - // 获取dimensionNodeTyepOrderList的index+1位置的节点类型 - String nextNodeType = dimensionNodeTyepOrderList.get(index + 1); - SdmResponse> allNodeByProjectIdAndType = simuluationNodeFeignClient.getAllNodeByProjectIdAndType(chooseUuids, nextNodeType); - if (allNodeByProjectIdAndType.isSuccess() && ObjectUtils.isNotEmpty(allNodeByProjectIdAndType.getData())) { - uuids.addAll(allNodeByProjectIdAndType.getData().stream().map(AllNodeByProjectIdAndTypeResp::getUuid).toList()); - } - + // 非最后一层:查模板下一层;最后一层:查同类型连续子节点(例如 分类->分类) + String nextNodeType = (index != dimensionNodeTyepOrderList.size() - 1) + ? dimensionNodeTyepOrderList.get(index + 1) + : chooseNodeType; + SdmResponse> allNodeByProjectIdAndType = simuluationNodeFeignClient.getAllNodeByProjectIdAndType(chooseUuids, nextNodeType); + if (allNodeByProjectIdAndType.isSuccess() && ObjectUtils.isNotEmpty(allNodeByProjectIdAndType.getData())) { + uuids.addAll(allNodeByProjectIdAndType.getData().stream().map(AllNodeByProjectIdAndTypeResp::getUuid).toList()); } } @@ -466,7 +469,7 @@ public class DimensionTemplateServiceImpl extends ServiceImpl dirIds = new ArrayList<>(); + Set dirIds = new HashSet<>(); Integer dirType; if (ObjectUtils.isNotEmpty(minioFileSearchReq.getParentUuid())) { // 项目节点下搜索文件 @@ -2058,6 +2058,11 @@ public class MinioFileIDataFileServiceImpl implements IDataFileService { } FileMetadataInfo dirMetadataInfo = dirResponse.getData(); + SdmResponse permissionResponse = checkUploadPermission(dirMetadataInfo); + if (!permissionResponse.isSuccess()) { + return permissionResponse; + } + String originalName = resolveOriginalName(req); SdmResponse versionedNameResponse = buildVersionedFileName(originalName); if (!versionedNameResponse.isSuccess()) { @@ -2068,11 +2073,12 @@ public class MinioFileIDataFileServiceImpl implements IDataFileService { SdmResponse existsResponse = ensureFileNotExists(fileMinioObjectKey); if (!existsResponse.isSuccess()) { - return existsResponse; - } - SdmResponse permissionResponse = checkUploadPermission(dirMetadataInfo); - if (!permissionResponse.isSuccess()) { - return permissionResponse; + if(!req.getIsConverSameNameFile()) { + return permissionResponse; + }else { + // 支持覆盖同名文件,直接minioService.uploadFile 覆盖一下原文件就行 + minioService.uploadFile(req.getFile(), fileMinioObjectKey, null, dirMetadataInfo.getBucketName()); + } } try { diff --git a/data/src/test/java/com/sdm/data/dao/MapperCompatibilityTest.java b/data/src/test/java/com/sdm/data/dao/MapperCompatibilityTest.java index 30d59899..1005ec6c 100644 --- a/data/src/test/java/com/sdm/data/dao/MapperCompatibilityTest.java +++ b/data/src/test/java/com/sdm/data/dao/MapperCompatibilityTest.java @@ -179,7 +179,6 @@ public class MapperCompatibilityTest { void testFileStorageMapperSelectBigFiles() { QueryBigFileReq req = new QueryBigFileReq(); req.setIsLatest(true); - req.setDirIds(Arrays.asList(1L)); List result = fileStorageMapper.selectBigFiles(req, 1000L, 1L); assertNotNull(result); diff --git a/project/src/main/java/com/sdm/project/schedule/lyric/LyricEncExceptionSchedule.java b/project/src/main/java/com/sdm/project/schedule/lyric/LyricEncExceptionSchedule.java index 550fba88..83031c08 100644 --- a/project/src/main/java/com/sdm/project/schedule/lyric/LyricEncExceptionSchedule.java +++ b/project/src/main/java/com/sdm/project/schedule/lyric/LyricEncExceptionSchedule.java @@ -3,7 +3,7 @@ package com.sdm.project.schedule.lyric; import com.alibaba.fastjson2.JSON; import com.sdm.common.common.SdmResponse; import com.sdm.common.utils.MdcUtil; -import com.sdm.project.service.ILyricInternalService; +import com.sdm.project.service.impl.LyricInternalNewServiceImpl; import com.xxl.job.core.context.XxlJobHelper; import com.xxl.job.core.handler.annotation.XxlJob; import lombok.extern.slf4j.Slf4j; @@ -15,8 +15,11 @@ import org.springframework.stereotype.Component; public class LyricEncExceptionSchedule { +// @Autowired +// private ILyricInternalService lyricInternalService; + @Autowired - private ILyricInternalService lyricInternalService; + private LyricInternalNewServiceImpl lyricInternalNewService; // xxljob平台配置定时任务 @XxlJob("lyricEncExceptionHandler") @@ -25,7 +28,7 @@ public class LyricEncExceptionSchedule { String traceId = MdcUtil.generateAndPutTraceId(); XxlJobHelper.log("{} XXL-JOB:拉起lyric异常任务信息开始,param:{}", traceId); long startTime = System.currentTimeMillis(); - SdmResponse response = lyricInternalService.syncException(); + SdmResponse response = lyricInternalNewService.syncException(); long endTime = System.currentTimeMillis(); long second = (endTime - startTime) / 1000; log.info("{} lyricEncExceptionHandler cost [{}] s", traceId,second); diff --git a/project/src/main/java/com/sdm/project/service/impl/NodeServiceImpl.java b/project/src/main/java/com/sdm/project/service/impl/NodeServiceImpl.java index ee5d4c4c..3ac96dbb 100644 --- a/project/src/main/java/com/sdm/project/service/impl/NodeServiceImpl.java +++ b/project/src/main/java/com/sdm/project/service/impl/NodeServiceImpl.java @@ -2293,94 +2293,180 @@ public class NodeServiceImpl extends ServiceImpl> getAllNodeByProjectIdAndType(List uuids, String nextNodeType) { - Map TagMap = tagMapService.getTagMapName(); - if ( ObjectUtils.isEmpty(TagMap)) { + if (CollectionUtils.isEmpty(uuids) || StringUtils.isBlank(nextNodeType)) { + return SdmResponse.success(); + } + + Map tagMap = tagMapService.getTagMapName(); + if (ObjectUtils.isEmpty(tagMap)) { log.error("字典信息查询失败"); return SdmResponse.success(); } - Optional simulationNodeOptional = this.lambdaQuery().in(SimulationNode::getUuid, uuids).list().stream().findFirst(); - if (!simulationNodeOptional.isPresent()) { + List 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 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 preSimulationNodeList = this.lambdaQuery().in(SimulationNode::getUuid, preUUids).list(); - - - // 当前节点向后搜索 - List 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 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 matchedParentUuids = sameTypeChildren.stream() + .map(SimulationNode::getParentId) + .filter(StringUtils::isNotBlank) + .collect(Collectors.toSet()); + + List remainingUuids = uuids.stream() + .filter(uuid -> !matchedParentUuids.contains(uuid)) + .toList(); + log.info("getAllNodeByProjectIdAndType remainingUuids size:{}, matchedParentUuids size:{}", + remainingUuids.size(), matchedParentUuids.size()); + + List 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 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 matchedChainNodes = queryNodesByCurrentTagValues(currentNodeTag, currentTagValues); + List preUUids = matchedChainNodes.stream() + .map(simulationNode -> resolveTagValue(simulationNode, nextNodeTag)) + .filter(StringUtils::isNotBlank) + .map(tag-> { + return tag.split(",")[0]; + }) + .toList(); + + List preSimulationNodeList = CollectionUtils.isEmpty(preUUids) + ? Collections.emptyList() + : this.lambdaQuery().in(SimulationNode::getUuid, preUUids).list(); + simulationNodeList.addAll(preSimulationNodeList); + // 规则3:同时保留原有“按nextNodeType正向查下一层”能力 + /* List 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 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 extractTagValuesByNodeTag(List currentNodes, List 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 queryNodesByCurrentTagValues(String currentNodeTag, List 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 buildNodeRespList(List 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