From 92e6a54628dc21a5d14382298234b1c7c9056536 Mon Sep 17 00:00:00 2001 From: zhuxinru Date: Tue, 24 Mar 2026 14:14:32 +0800 Subject: [PATCH 1/2] =?UTF-8?q?fix:=E4=BB=BB=E5=8A=A1=E6=89=A7=E8=A1=8C?= =?UTF-8?q?=E6=B6=89=E5=8F=8A=E7=AB=8B=E5=8D=B3=E5=88=A0=E9=99=A4=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/SimulationReportTemplateServiceImpl.java | 1 + .../sdm/project/service/impl/SimulationRunServiceImpl.java | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/capability/src/main/java/com/sdm/capability/service/impl/SimulationReportTemplateServiceImpl.java b/capability/src/main/java/com/sdm/capability/service/impl/SimulationReportTemplateServiceImpl.java index bbeac453..5831f643 100644 --- a/capability/src/main/java/com/sdm/capability/service/impl/SimulationReportTemplateServiceImpl.java +++ b/capability/src/main/java/com/sdm/capability/service/impl/SimulationReportTemplateServiceImpl.java @@ -201,6 +201,7 @@ public class SimulationReportTemplateServiceImpl extends ServiceImpl Date: Tue, 24 Mar 2026 14:23:56 +0800 Subject: [PATCH 2/2] =?UTF-8?q?fix=EF=BC=9A=E6=95=B0=E6=8D=AE=E6=80=BB?= =?UTF-8?q?=E8=A7=88=E6=96=87=E4=BB=B6=E6=8E=92=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/DimensionTemplateServiceImpl.java | 182 +++++++++++------- 1 file changed, 116 insertions(+), 66 deletions(-) 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 1f641713..c613387e 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 @@ -419,61 +419,16 @@ public class DimensionTemplateServiceImpl extends ServiceImpl result = new ArrayList<>(); - groupedChildren.values().forEach(children -> { + for (List children : groupedChildren.values()) { FileMetadataChildrenDTO baseDto = new FileMetadataChildrenDTO(); BeanUtils.copyProperties(children.get(0),baseDto); baseDto.setMergeSameNameChildren(children); baseDto.setFileIds(children.stream().map(FileMetadataInfoResp::getId).toList()); result.add(baseDto); - }); + } if(CollectionUtils.isNotEmpty(result)) { - // 判断是否存在PHASE类型的节点 - boolean hasPhaseNode = result.stream() - .flatMap(dto -> dto.getMergeSameNameChildren().stream()) - .anyMatch(child -> NodeTypeEnum.PHASE.getValue().equals(child.getRelatedResourceUuidOwnType())); - - // 先按dataType排序(文件夹在前dataType=1,文件在后dataType=2),再按children中的最大创建时间倒序排序 - result.sort((dto1, dto2) -> { - // 首先按dataType排序:文件夹(1)在前,文件(2)在后 - Integer dataType1 = dto1.getDataType(); - Integer dataType2 = dto2.getDataType(); - if (dataType1 != null && dataType2 != null && !dataType1.equals(dataType2)) { - return dataType1.compareTo(dataType2); // 升序:1(文件夹) < 2(文件) - } - - boolean isWorkspace1 = dto1.getMergeSameNameChildren().stream() - .anyMatch(child -> NodeTypeEnum.WORKSPACE.getValue().equals(child.getRelatedResourceUuidOwnType())); - boolean isWorkspace2 = dto2.getMergeSameNameChildren().stream() - .anyMatch(child -> NodeTypeEnum.WORKSPACE.getValue().equals(child.getRelatedResourceUuidOwnType())); - if (isWorkspace1 && isWorkspace2) { - return compareWorkspaceNodeCode(dto1.getNodeCode(), dto2.getNodeCode()); - } - - // 如果存在PHASE类型节点,dataType相同时按主键ID正序排序 - if (hasPhaseNode) { - Long id1 = dto1.getId(); - Long id2 = dto2.getId(); - if (id1 != null && id2 != null && !id1.equals(id2)) { - return id1.compareTo(id2); // 正序排序 - } - } - - // dataType相同或都为null时,按创建时间倒序排序 - LocalDateTime maxCreateTime1 = dto1.getMergeSameNameChildren().stream() - .map(FileMetadataInfoResp::getCreateTime) - .filter(Objects::nonNull) - .max(LocalDateTime::compareTo) - .orElse(LocalDateTime.MIN); - - LocalDateTime maxCreateTime2 = dto2.getMergeSameNameChildren().stream() - .map(FileMetadataInfoResp::getCreateTime) - .filter(Objects::nonNull) - .max(LocalDateTime::compareTo) - .orElse(LocalDateTime.MIN); - - return maxCreateTime2.compareTo(maxCreateTime1); // 倒序排序 - }); + result = sortMergedNodeDirResult(result); } log.info("getSimulationNodeTree 方法耗时 " + @@ -484,31 +439,126 @@ public class DimensionTemplateServiceImpl extends ServiceImpl result) { - if (CollectionUtils.isEmpty(result)) { - return; + + /** + * 聚合后的节点目录排序规则(分层分组 + 组内排序): + * + *
+     * 一、顶层:先文件夹,后文件
+     *  1) 文件夹(dataType=1)
+     *  2) 文件(dataType!=1)按创建时间倒序(最新在前)
+     *
+     * 二、文件夹层:先普通文件夹,后节点类型文件夹
+     *  1) 普通文件夹:按创建时间倒序(最新在前)
+     *  2) 节点类型文件夹:按节点类型分组后依次展开
+     *
+     * 三、节点类型文件夹分组顺序
+     *  1) TASK / RUN 分组优先
+     *  2) 其他节点类型分组在后
+     *  同优先级分组按节点类型字符串字典序兜底,保证结果稳定
+     *
+     * 四、节点类型分组内排序
+     *  1) WORKSPACE:先将 nodeCode 包含 "-M" 的工位置前,再按 compareWorkspaceNodeCode 排序
+     *  2) TASK / RUN / PHASE / 其他:按主键 ID 正序;若 ID 相同或为空,再按创建时间倒序兜底
+     * 
+ * + * 说明:创建时间使用 mergeSameNameChildren 中的最大 createTime 参与比较。 + */ + private List sortMergedNodeDirResult(List source) { + List folders = source.stream() + .filter(this::isFolder) + .collect(Collectors.toCollection(ArrayList::new)); + List files = source.stream() + .filter(dto -> !isFolder(dto)) + .sorted(Comparator.comparing(this::getMaxCreateTime, Comparator.nullsLast(Comparator.naturalOrder())).reversed()) + .collect(Collectors.toCollection(ArrayList::new)); + + List normalFolders = folders.stream() + .filter(dto -> !isNodeTypeFolder(dto)) + .sorted(Comparator.comparing(this::getMaxCreateTime, Comparator.nullsLast(Comparator.naturalOrder())).reversed()) + .collect(Collectors.toCollection(ArrayList::new)); + + List nodeTypeFolders = folders.stream() + .filter(this::isNodeTypeFolder) + .collect(Collectors.toCollection(ArrayList::new)); + + Map> groupedByNodeType = nodeTypeFolders.stream() + .collect(Collectors.groupingBy(this::getNodeTypeKey)); + + List nodeTypeOrder = groupedByNodeType.keySet().stream() + .sorted(Comparator.comparingInt(this::nodeTypeGroupPriority).thenComparing(String::compareTo)) + .toList(); + + List sortedNodeTypeFolders = new ArrayList<>(); + for (String nodeType : nodeTypeOrder) { + List group = new ArrayList<>(groupedByNodeType.get(nodeType)); + group.sort(getNodeTypeFolderComparator(nodeType)); + sortedNodeTypeFolders.addAll(group); } - FileMetadataChildrenDTO specialWorkspace = result.stream() - .filter(this::isWorkspaceNode) - .filter(dto -> StringUtils.contains(dto.getNodeCode(), "-M")) - .findFirst() - .orElse(null); - if (specialWorkspace != null) { - result.remove(specialWorkspace); - result.add(0, specialWorkspace); - } + List result = new ArrayList<>(source.size()); + result.addAll(normalFolders); + result.addAll(sortedNodeTypeFolders); + result.addAll(files); + return result; } - private boolean isWorkspaceNode(FileMetadataChildrenDTO dto) { - return dto != null && CollectionUtils.isNotEmpty(dto.getMergeSameNameChildren()) - && dto.getMergeSameNameChildren().stream() - .anyMatch(child -> NodeTypeEnum.WORKSPACE.getValue().equals(child.getRelatedResourceUuidOwnType())); + private Comparator getNodeTypeFolderComparator(String nodeType) { + if (NodeTypeEnum.WORKSPACE.getValue().equals(nodeType)) { + return (a, b) -> { + boolean isSpecialA = StringUtils.contains(a.getNodeCode(), "-M"); + boolean isSpecialB = StringUtils.contains(b.getNodeCode(), "-M"); + if (isSpecialA != isSpecialB) { + return isSpecialA ? -1 : 1; + } + return compareWorkspaceNodeCode(a.getNodeCode(), b.getNodeCode()); + }; + } + + return Comparator + .comparing(FileMetadataChildrenDTO::getId, Comparator.nullsLast(Long::compareTo)) + .thenComparing(Comparator.comparing(this::getMaxCreateTime, Comparator.nullsLast(Comparator.naturalOrder())).reversed()); + } + + private int nodeTypeGroupPriority(String nodeType) { + if (NodeTypeEnum.TASK.getValue().equals(nodeType) || NodeTypeEnum.RUN.getValue().equals(nodeType)) { + return 0; + } + return 1; + } + + private boolean isFolder(FileMetadataChildrenDTO dto) { + return dto != null &&Objects.equals(DataTypeEnum.DIRECTORY.getValue(), dto.getDataType()); + } + + private boolean isNodeTypeFolder(FileMetadataChildrenDTO dto) { + String nodeType = getNodeTypeKey(dto); + return StringUtils.isNotBlank(nodeType); + } + + private String getNodeTypeKey(FileMetadataChildrenDTO dto) { + if (dto == null || CollectionUtils.isEmpty(dto.getMergeSameNameChildren())) { + return ""; + } + return dto.getMergeSameNameChildren().stream() + .map(FileMetadataInfoResp::getRelatedResourceUuidOwnType) + .filter(StringUtils::isNotBlank) + .findFirst() + .orElse(""); + } + + private LocalDateTime getMaxCreateTime(FileMetadataChildrenDTO dto) { + if (dto == null || CollectionUtils.isEmpty(dto.getMergeSameNameChildren())) { + return LocalDateTime.MIN; + } + return dto.getMergeSameNameChildren().stream() + .map(FileMetadataInfoResp::getCreateTime) + .filter(Objects::nonNull) + .max(LocalDateTime::compareTo) + .orElse(LocalDateTime.MIN); } private int compareWorkspaceNodeCode(String nodeCode1, String nodeCode2) {