Browse Source

推送平天路

huangtf 5 months ago
parent
commit
0e6d04d8ec
17 changed files with 431 additions and 276 deletions
  1. 28 0
      blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/entity/ArchivesAuto.java
  2. 83 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/ArchiveFile.java
  3. 6 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/feign/ArchiveFileClient.java
  4. 1 1
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/ArchiveTreeContract.java
  5. 6 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/feign/ArchiveTreeContractClient.java
  6. 17 4
      blade-service/blade-archive/src/main/java/org/springblade/archive/external/impl/ExternalDataArchiveAutoService.java
  7. 1 1
      blade-service/blade-archive/src/main/java/org/springblade/archive/external/impl/ExternalDataArchiveBuildService.java
  8. 116 247
      blade-service/blade-archive/src/main/java/org/springblade/archive/external/impl/ExternalDataArchiveFileService.java
  9. 15 3
      blade-service/blade-archive/src/main/java/org/springblade/archive/external/impl/ExternalDataArchiveTreeService.java
  10. 2 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/ArchivesAutoMapper.java
  11. 87 6
      blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/ArchivesAutoMapper.xml
  12. 19 6
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchivesAutoServiceImpl.java
  13. 10 0
      blade-service/blade-business/src/main/java/org/springblade/business/feignClient/ArchiveFileClientImpl.java
  14. 8 8
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/ArchiveFileMapper.xml
  15. 4 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/IArchiveFileService.java
  16. 14 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/ArchiveFileServiceImpl.java
  17. 14 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/feign/ArchiveTreeContractImpl.java

+ 28 - 0
blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/entity/ArchivesAuto.java

@@ -231,6 +231,34 @@ public class ArchivesAuto extends BaseEntity {
             this.setFileSize(autoVo.getSize().longValue());
         }
 
+        //保管期限
+        String storageTime = autoVo.getStorageTime();
+
+        if ("9999".equals(storageTime)) {
+            this.setStorageTime("3");
+        } else if ("10".equals(storageTime)) {
+            this.setStorageTime("1");
+        } else if ("20".equals(storageTime)) {
+            this.setStorageTime("2");
+        } else {
+            // 默认值处理,包含 null 和其他未定义值
+            this.setStorageTime("3");
+        }
+
+        //秘技
+        String secretLevel = autoVo.getSecretLevel();
+        // 使用预定义映射关系
+        if ("机密".equals(secretLevel)) {
+            this.setSecretLevel("1");
+        } else if ("绝密".equals(secretLevel)) {
+            this.setSecretLevel("2");
+        } else if ("秘密".equals(secretLevel)) {
+            this.setSecretLevel("3");
+        } else if ("公开".equals(secretLevel)) {
+            this.setSecretLevel("4");
+        }
+
+
         // 4. 设置默认值(根据业务需求)
         this.setIsAutoFile(0);
         this.setIsArchive(1);

+ 83 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/ArchiveFile.java

@@ -18,11 +18,15 @@ package org.springblade.business.entity;
 
 import com.baomidou.mybatisplus.annotation.TableName;
 import io.swagger.annotations.ApiModelProperty;
+import org.springblade.archive.trans.ArchiveFileVo;
+import org.springblade.archive.trans.ArchiveTreeVo;
 import org.springblade.core.mp.base.BaseEntity;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
+import org.springframework.beans.BeanUtils;
 
 import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
 
 /**
  * 实体类
@@ -320,4 +324,83 @@ public class ArchiveFile extends BaseEntity {
      * 外部同步的id,常常文件url不是来自外部
      */
     private String outId;
+
+    private String sortNum;
+
+    public void fromExternal(ArchiveFileVo vo) {
+        if (vo == null) {
+            return;
+        }
+
+        // 1. 使用工具类拷贝同名且类型兼容的属性
+        BeanUtils.copyProperties(vo, this);
+
+        // 2. 处理类型转换的字段
+        // String -> Long 转换
+
+        // String -> LocalDateTime 转换(示例,需根据实际格式调整)
+        if (vo.getFilmingTime() != null) {
+            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+            this.setFilmingTime(LocalDateTime.parse(vo.getFilmingTime(), formatter));
+        }
+
+        // String -> Integer 转换
+        if (vo.getPageCount() != null) {
+            this.setFilePage(vo.getPageCount());
+        }
+
+        // String -> Long 转换(fileSize)
+        if (vo.getFileSize() != null && !vo.getFileSize().isEmpty()) {
+            try {
+                this.setFileSize(Long.parseLong(vo.getFileSize()));
+            } catch (NumberFormatException e) {
+                // 处理格式错误(根据业务需求记录日志或忽略)
+            }
+        }
+
+        // 3. 处理 ArchiveFile 特有字段(尝试从 Vo 找相近字段)
+        // pdfFileUrl 对应 Vo 的 pdfUrl
+        this.setPdfFileUrl(vo.getPdfUrl());
+        // filePage 已通过 pageCount 赋值(见上文)
+        // dutyUser 对应 Vo 的 responsibleUserName
+        this.setDutyUser(vo.getResponsibleUserName());
+        // eVisaFile 可能对应 Vo 的 approveType(根据业务逻辑调整)
+        this.setEVisaFile(vo.getApproveType());
+        // utime 对应 Vo 的 upTime(需转换)
+        if (vo.getUpTime() != null) {
+            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+            this.setUtime(LocalDateTime.parse(vo.getUpTime(), formatter));
+        }
+
+        this.setSort(vo.getOrderNum());
+
+
+        String type = vo.getType();
+        if ("0".equals(type)) {
+            this.setClassify(1);
+        } else if ("1".equals(type)) {
+            this.setClassify(2);
+        } else {
+            // 处理意外值的策略(以下是两种方案,根据业务需求二选一)
+
+            this.setClassify(1);
+        }
+
+        // 工程文件则设置成数字化上传的文件,其他为原生电子文件
+        if (vo.getFileType() == 15) {
+            this.setSourceType(2);
+        }else {
+            this.setSourceType(1);
+        }
+
+
+        //已认证
+        this.setIsCertification(1);
+        //已审批
+        this.setStatus(2);
+        //已归档
+        this.setIsArchive(1);
+        this.setIsDeleted(0);
+
+    }
 }

+ 6 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/feign/ArchiveFileClient.java

@@ -155,4 +155,10 @@ public interface ArchiveFileClient {
      */
     @PostMapping(API_PREFIX + "/getListByContractIdAndArchiveFileStorageType")
     List<ArchiveFile> getListByContractIdAndArchiveFileStorageType(@RequestParam Long contractId,@RequestParam Integer getListByContractIdAndArchiveFileStorageType);
+
+    @PostMapping(API_PREFIX + "/addFilesEx")
+    void addArchiveFileEx(@RequestBody List<ArchiveFile> files);
+
+    @PostMapping(API_PREFIX + "/updateFilesEx")
+    void updateArchiveFileEx(@RequestBody List<ArchiveFile> files);
 }

+ 1 - 1
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/ArchiveTreeContract.java

@@ -392,7 +392,7 @@ public class ArchiveTreeContract extends BaseEntity {
         this.nodeName = archiveTree.getName();
         this.fullName = archiveTree.getName();
         this.nodeType = 1;
-
+        this.setTreeSort(archiveTree.getProcsort());
         //质检资料
         this.associationType = 1;
 //        this.majorDataType = archiveTree.getMajorDataType();

+ 6 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/feign/ArchiveTreeContractClient.java

@@ -69,4 +69,10 @@ public interface ArchiveTreeContractClient {
 
     @PostMapping(API_PREFIX+"/getOutNodesByOutIds")
     public List<ArchiveTreeContract> getOutNodesByOutIds(@RequestParam Long projectId,@RequestParam List<String> outIds);
+
+    @PostMapping(API_PREFIX+"/updateArchiveTreeContract")
+    public void updateArchiveTreeContract(@RequestBody List<ArchiveTreeContract> archiveTreeContracts);
+
+    @PostMapping(API_PREFIX+"/adsArchiveTreeContract")
+    public void addArchiveTreeContract(@RequestBody List<ArchiveTreeContract> archiveTreeContracts,@RequestParam Long rootId);
 }

+ 17 - 4
blade-service/blade-archive/src/main/java/org/springblade/archive/external/impl/ExternalDataArchiveAutoService.java

@@ -4,6 +4,7 @@ import lombok.AllArgsConstructor;
 import org.springblade.archive.entity.ArchivesAuto;
 import org.springblade.archive.external.bean.ExternalDataInfo;
 import org.springblade.archive.mapper.ArchivesAutoMapper;
+import org.springblade.archive.service.IArchivesAutoService;
 import org.springblade.archive.trans.ArchiveAutoVo;
 import org.springblade.archive.trans.ArchiveReq;
 import org.springblade.archive.trans.ArchiveTreeVo;
@@ -23,6 +24,8 @@ public class ExternalDataArchiveAutoService {
 
     private ArchivesAutoMapper autoMapper;
 
+    private final IArchivesAutoService archivesAutoService;
+
     public void handleArchiveAutos(Long projectId, ArchiveReq req, ExternalDataInfo externalDataInfo){
         syncData(projectId, req, externalDataInfo);
     }
@@ -49,6 +52,7 @@ public class ExternalDataArchiveAutoService {
             ArchivesAuto archivesAuto = new ArchivesAuto();
 
             // 拷贝rootNode的属性到当前节点(如名称、类型等元数据)
+            archivesAuto.fromExternal(autoVo);
 
             // 设置新ID(从映射表中获取)
             Long newNodeId = archiveAutoOutIdMapping.get(autoVo.getId());
@@ -59,7 +63,7 @@ public class ExternalDataArchiveAutoService {
             archivesAuto.setNodeId(archiveNodeId);
 
             //核心转化
-            archivesAuto.fromExternal(autoVo);
+
             archivesAuto.setProjectId(rootNode.getProjectId());
             archivesAuto.setContractId(rootNode.getContractId());
             // 设置父ID逻辑:
@@ -137,6 +141,13 @@ public class ExternalDataArchiveAutoService {
      */
     private void addAndUpdateArchives(List<ArchivesAuto> addArchives, List<ArchivesAuto> upArchives) {
         // 待实现:批量插入新增数据,批量更新现有数据
+        if (addArchives != null && !addArchives.isEmpty()) {
+            archivesAutoService.saveBatch(addArchives);
+        }
+
+        if (upArchives != null && !upArchives.isEmpty()) {
+            archivesAutoService.updateBatchById(upArchives);
+        }
     }
 
 
@@ -184,11 +195,13 @@ public class ExternalDataArchiveAutoService {
 
     // 辅助方法:仅根据关键字段判断是否需要更新
     private boolean needUpdate(ArchivesAuto external, ArchivesAuto local) {
-        // 示例:检查 outUrl 是否不同
-        return !Objects.equals(external.getOutUrl(), local.getOutUrl());
+        // 检查关键字段差异
+        return !Objects.equals(external.getOutUrl(), local.getOutUrl())
+                || !Objects.equals(external.getName(), local.getName());
 
-        // 如果需要检查更多字段,可以追加条件,例如
+        // 扩展检查示例(如需其他字段比较,可追加条件)
         // || !Objects.equals(external.getFileNumber(), local.getFileNumber())
+        // || !Objects.equals(external.getSecretLevel(), local.getSecretLevel())
     }
 
 

+ 1 - 1
blade-service/blade-archive/src/main/java/org/springblade/archive/external/impl/ExternalDataArchiveBuildService.java

@@ -61,7 +61,7 @@ public class ExternalDataArchiveBuildService {
         // 调用同步函数,传入 ExternalDataInfo 对象
         //externalTreeService.syncData(externalDataInfo);
         //externalDataArchiveAutoService.syncData(externalDataInfo);
-        externalDataArchiveFileService.syncData(externalDataInfo);
+        //externalDataArchiveFileService.syncData(externalDataInfo);
 
         // 返回同步后的 ExternalDataInfo 对象
         return externalDataInfo;

+ 116 - 247
blade-service/blade-archive/src/main/java/org/springblade/archive/external/impl/ExternalDataArchiveFileService.java

@@ -1,16 +1,20 @@
 package org.springblade.archive.external.impl;
 
 import lombok.AllArgsConstructor;
+import org.springblade.archive.entity.ArchivesAuto;
 import org.springblade.archive.external.bean.ExternalDataInfo;
+import org.springblade.archive.mapper.ArchivesAutoMapper;
+import org.springblade.archive.trans.ArchiveAutoVo;
+import org.springblade.archive.trans.ArchiveFileVo;
 import org.springblade.archive.trans.ArchiveReq;
 import org.springblade.business.entity.ArchiveFile;
 import org.springblade.business.feign.ArchiveFileClient;
+import org.springblade.common.utils.SnowFlakeUtil;
+import org.springblade.manager.entity.ArchiveTreeContract;
 import org.springframework.stereotype.Service;
 
 import java.time.LocalDateTime;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 import java.util.stream.Collectors;
 
 @Service
@@ -19,12 +23,14 @@ public class ExternalDataArchiveFileService {
 
     private ArchiveFileClient archiveFileClient;
 
+    private ArchivesAutoMapper autoMapper;
 
-    public void handleArchiveFiles(Long projectId, ArchiveReq req, ExternalDataInfo externalDataInfo){
 
+    public void handleArchiveFiles(Long projectId, ArchiveReq req, ExternalDataInfo externalDataInfo){
+        syncData(projectId, req, externalDataInfo);
     }
 
-    public void syncData(ExternalDataInfo externalDataInfo) {
+    public void syncData(Long projectId, ArchiveReq req, ExternalDataInfo externalDataInfo) {
         // 创建 ExternalDataInfo 对象
         //新增的文件
         List<ArchiveFile> addFiles = new ArrayList<>();
@@ -33,11 +39,17 @@ public class ExternalDataArchiveFileService {
         List<ArchiveFile> upFiles = new ArrayList<>();
 
         //外部文件
-        List<ArchiveFile> externalFiles = getExternalFils(externalDataInfo.getProjectName(),externalDataInfo);
+        List<ArchiveFile> externalFiles = listConvert(req.getNodeId(), req.getFiles(), externalDataInfo);
 
-        //本地的文件
-        List<ArchiveFile> localFiles = getLocalFils(externalDataInfo.getProjectName());
+        List<String> outIds = Optional.ofNullable(externalFiles)
+                .orElseGet(Collections::emptyList)
+                .stream()
+                .map(ArchiveFile::getOutId) // 假设 getOutId() 返回 String
+                .filter(Objects::nonNull) // 可选:过滤 null 值
+                .collect(Collectors.toList());
 
+        //本地的文件
+        List<ArchiveFile> localFiles = getLocalFils(projectId,outIds);
         //比较获取
         getAddAndUpdateFiles(externalDataInfo,externalFiles, localFiles, addFiles, upFiles);
 
@@ -45,283 +57,140 @@ public class ExternalDataArchiveFileService {
         addAndUpdateFiles(addFiles,upFiles);
     }
 
+    public List<ArchiveFile> listConvert(String nodeId, List<ArchiveFileVo> archiveFileVos, ExternalDataInfo externalDataInfo) {
 
+        List<ArchiveFile> archiveFiles = new ArrayList<>();
+        Map<String, Long> archiveFileOutIdMapping = new LinkedHashMap<>();
 
-    private void getAddAndUpdateFiles(ExternalDataInfo externalDataInfo,List<ArchiveFile> externalFiles, List<ArchiveFile> localFiles,
-                                   List<ArchiveFile> addFiles, List<ArchiveFile> upFiles) {
-        // 将外部文件转换为 Map,键为 ID,值为 ArchiveFile
-        Map<Long, ArchiveFile> externalFileMap =
-                externalFiles.stream()
-                .collect(Collectors.toMap(ArchiveFile::getId, file -> file));
-
-        // 遍历本地文件,找出新增和更新的文件
-        for (ArchiveFile localFile : localFiles) {
-            ArchiveFile externalFile = externalFileMap.get(localFile.getId());
-            if (externalFile == null) {
-                // 外部文件中没有此 ID,认为是新增文件
-                addFiles.add(localFile);
-            } else {
-                // 外部文件中有此 ID,比较更新时间
-                if (!externalFile.getFtime().equals(localFile.getFtime())) {
-                    // 更新时间不同,认为是更新文件
-                    localFile.setFileUrl(externalFile.getFileUrl());
-                    localFile.setEVisaFile(externalFile.getEVisaFile());
-                    localFile.setPdfPageUrl(externalFile.getPdfPageUrl());
-                    localFile.setFilePage(externalFile.getFilePage());
-                    localFile.setFileSize(externalFile.getFileSize());
-                    upFiles.add(localFile);
-                }
-            }
-        }
-
-        // 将外部文件中没有在本地文件中的,认为是新增文件
-        for (ArchiveFile externalFile : externalFiles) {
-            boolean isExistInLocal = localFiles.stream().anyMatch(localFile -> localFile.getId().equals(externalFile.getId()));
-            if (!isExistInLocal) {
-                addFiles.add(externalFile);
-            }
-        }
+        //内外映射
+        Map<String, Long> archiveTreeOutIdMapping = externalDataInfo.getArchiveTreeNodeIdMapping();
+        Map<String, Long> archiveAutoOutIdMapping = externalDataInfo.getArchiveIdMapping();
 
+        Long rootId = externalDataInfo.getPid();
+        ArchiveTreeContract rootNode = externalDataInfo.getParent();
 
-        //刷新
-        if (addFiles != null && !addFiles.isEmpty()) {
-            for (ArchiveFile addFile :addFiles) {
-//                if (addFile.getNodeId()!= null && externalDataInfo.getArchiveTreeNodeIdMapping()!= null) {
-//                    String nodeId = externalDataInfo.getArchiveTreeNodeIdMapping().get(addFile.getNodeId());
-//                    if (nodeId!=null) {
-//                        addFile.setNodeId(nodeId);
-//                    }
-//                }
-//
-//                // Process NodeExtId
-//                if (addFile.getNodeExtId() != null && externalDataInfo.getArchiveTreeNodeIdMapping() != null) {
-//                    String nodeExtId = externalDataInfo.getArchiveTreeNodeIdMapping().get(addFile.getNodeExtId());
-//                    if (nodeExtId != null) {
-//                        addFile.setNodeExtId(Long.parseLong(nodeExtId));
-//                    }
-//                }
-
-                // Process ArchiveId
-                if (addFile.getArchiveId() != null && externalDataInfo.getArchiveIdMappingMapping() != null) {
-                    Long archiveId = externalDataInfo.getArchiveIdMappingMapping().get(addFile.getArchiveId());
-                    if (archiveId != null) {
-                        addFile.setArchiveId(archiveId);
-                    }
-                }
-            }
+        // 1. 生成所有节点的唯一新ID并建立映射
+        for (ArchiveFileVo archiveFileVo : archiveFileVos) {
+            archiveFileOutIdMapping.put(archiveFileVo.getId(), SnowFlakeUtil.getId());
         }
 
-
-    }
+        // 2. 遍历所有节点,构建ArchiveTreeContract对象
+        for (ArchiveFileVo archiveFileVo : archiveFileVos) {
 
 
-    private List<ArchiveFile> getExternalFils(String projectName, ExternalDataInfo externalDataInfo) {
-        // 这里模拟获取外部文件的逻辑,具体实现根据 externalDataInfo 来获取
+            ArchiveFile archiveFile = new ArchiveFile();
 
-        List<ArchiveFile> externalFils = new ArrayList<>();
+            // 拷贝属性
+            archiveFile.fromExternal(archiveFileVo);
 
+            // 设置新ID(从映射表中获取)
+            Long newNodeId = archiveFileOutIdMapping.get(archiveFileVo.getId());
+            archiveFile.setId(newNodeId);
+            archiveFile.setOutId(archiveFileVo.getId());
 
-        return externalFils;
-    }
+            //组卷ID
+            Long archiveId = archiveAutoOutIdMapping.get(archiveFileVo.getArchiveId());
+            archiveFile.setArchiveId(archiveId);
 
-    // 获取本地文件
-    private List<ArchiveFile> getLocalFils(String projectName) {
+            //nodeId nodeSUB
+            Long fileNodeId = archiveTreeOutIdMapping.get(archiveFileVo.getNodeId());
+            archiveFile.setNodeId(fileNodeId.toString());
 
-        List<ArchiveFile> localFils = new ArrayList<>();
-        // 这里模拟获取本地文件的逻辑,具体实现根据项目名称来获取
-        return localFils;
-    }
+            Long fileNodeExtId = archiveTreeOutIdMapping.get(archiveFileVo.getNodeIdSub());
+            if (fileNodeExtId!= null ) {
+                archiveFile.setNodeExtId(fileNodeExtId);
+            }
 
+            archiveFile.setProjectId(rootNode.getProjectId().toString());
+            archiveFile.setContractId(rootNode.getContractId().toString());
 
-    public void addAndUpdateFiles(List<ArchiveFile> addFiles, List<ArchiveFile> upFiles) {
-        if (addFiles != null && !addFiles.isEmpty()) {
-            archiveFileClient.addArchiveFile(addFiles);
+            // 将构建好的对象加入结果列表
+            archiveFiles.add(archiveFile);
         }
+        externalDataInfo.setFileIdMapping(archiveFileOutIdMapping);
 
-        if (upFiles != null && !upFiles.isEmpty()) {
-            archiveFileClient.updateArchiveFile(upFiles);
-        }
+        return archiveFiles;
     }
 
-    public ArchiveFile createArchiveFileFromMap(Map<String, Object> fileDataMap) {
-        ArchiveFile archiveFile = new ArchiveFile();
-
-        // 项目ID
-        if (fileDataMap.containsKey("projectId")) {
-            archiveFile.setProjectId((String) fileDataMap.get("projectId"));
-        }
-
-        // 合同段ID
-        if (fileDataMap.containsKey("contractId")) {
-            archiveFile.setContractId((String) fileDataMap.get("contractId"));
-        }
-
-        // 文件绑定的节点ID
-        if (fileDataMap.containsKey("nodeId")) {
-            archiveFile.setNodeId((String) fileDataMap.get("nodeId"));
-        }
-
-        // 文件编号
-        if (fileDataMap.containsKey("fileNumber")) {
-            archiveFile.setFileNumber((String) fileDataMap.get("fileNumber"));
-        }
-
-        // 文件名称
-        if (fileDataMap.containsKey("fileName")) {
-            archiveFile.setFileName((String) fileDataMap.get("fileName"));
-        }
-
-        // 文件时间
-        if (fileDataMap.containsKey("fileTime")) {
-            archiveFile.setFileTime((String) fileDataMap.get("fileTime"));
-        }
-
-        // 文件路径
-        if (fileDataMap.containsKey("fileUrl")) {
-            archiveFile.setFileUrl((String) fileDataMap.get("fileUrl"));
-        }
-
-        // PDF文件路径
-        if (fileDataMap.containsKey("pdfFileUrl")) {
-            archiveFile.setPdfFileUrl((String) fileDataMap.get("pdfFileUrl"));
-        }
-
-        // 文件页数
-        if (fileDataMap.containsKey("filePage")) {
-            archiveFile.setFilePage((Integer) fileDataMap.get("filePage"));
-        }
-
-        // 责任者
-        if (fileDataMap.containsKey("dutyUser")) {
-            archiveFile.setDutyUser((String) fileDataMap.get("dutyUser"));
-        }
-
-        // 图表来源
-        if (fileDataMap.containsKey("sheetSource")) {
-            archiveFile.setSheetSource((String) fileDataMap.get("sheetSource"));
-        }
-
-        // 图号
-        if (fileDataMap.containsKey("drawingNo")) {
-            archiveFile.setDrawingNo((String) fileDataMap.get("drawingNo"));
-        }
-
-        // 引用变更令编号
-        if (fileDataMap.containsKey("citeChangeNumber")) {
-            archiveFile.setCiteChangeNumber((String) fileDataMap.get("citeChangeNumber"));
-        }
-
-        // 电签pdf文件
-        if (fileDataMap.containsKey("eVisaFile")) {
-            archiveFile.setEVisaFile((String) fileDataMap.get("eVisaFile"));
-        }
-
-        // 文件归属的扩展节点ID
-        if (fileDataMap.containsKey("nodeExtId")) {
-            archiveFile.setNodeExtId((Long) fileDataMap.get("nodeExtId"));
-        }
-
-        // 文件类型
-        if (fileDataMap.containsKey("fileType")) {
-            archiveFile.setFileType((Long) fileDataMap.get("fileType"));
-        }
-
-        // 归属案卷ID
-        if (fileDataMap.containsKey("archiveId")) {
-            archiveFile.setArchiveId((Long) fileDataMap.get("archiveId"));
-        }
-
-        // 原始归属案卷ID(用于拆卷)
-        if (fileDataMap.containsKey("originId")) {
-            archiveFile.setOriginId((Long) fileDataMap.get("originId"));
-        }
-
-        // 拍摄时间
-        if (fileDataMap.containsKey("filmingTime")) {
-            archiveFile.setFilmingTime((LocalDateTime) fileDataMap.get("filmingTime"));
-        }
 
-        // 实际拍摄时间
-        if (fileDataMap.containsKey("filmingorTime")) {
-            archiveFile.setFilmingorTime((LocalDateTime) fileDataMap.get("filmingorTime"));
-        }
 
-        // 媒体分类
-        if (fileDataMap.containsKey("tagId")) {
-            archiveFile.setTagId((String) fileDataMap.get("tagId"));
-        }
+    private void getAddAndUpdateFiles(
+            ExternalDataInfo externalDataInfo,
+            List<ArchiveFile> externalFiles,
+            List<ArchiveFile> localFiles,
+            List<ArchiveFile> addFiles,
+            List<ArchiveFile> upFiles) {
 
-        // 相片号
-        if (fileDataMap.containsKey("picCode")) {
-            archiveFile.setPicCode((String) fileDataMap.get("picCode"));
-        }
+        // 1. 提取本地文件的 outId 集合(用于快速判断外部文件是否已存在)
+        Set<String> localOutIdSet = localFiles.stream()
+                .map(ArchiveFile::getOutId) // 假设 ArchiveFile 有 outId 字段
+                .filter(outId -> outId != null && !outId.isEmpty())
+                .collect(Collectors.toSet());
 
-        // 参见号
-        if (fileDataMap.containsKey("referCode")) {
-            archiveFile.setReferCode((String) fileDataMap.get("referCode"));
-        }
+        // 2. 将本地文件转为 Map<outId, ArchiveFile> 以便快速查找
+        Map<String, ArchiveFile> localFileMap = localFiles.stream()
+                .filter(file -> file.getOutId() != null && !file.getOutId().isEmpty())
+                .collect(Collectors.toMap(ArchiveFile::getOutId, file -> file));
 
-        // 底片号
-        if (fileDataMap.containsKey("filmCode")) {
-            archiveFile.setFilmCode((String) fileDataMap.get("filmCode"));
-        }
+        // 3. 遍历外部文件,判断新增或更新
+        for (ArchiveFile externalFile : externalFiles) {
+            String externalOutId = externalFile.getOutId();
 
-        // 图片宽
-        if (fileDataMap.containsKey("width")) {
-            archiveFile.setWidth((Integer) fileDataMap.get("width"));
-        }
+            // 跳过空 outId(根据业务需求调整)
+            if (externalOutId == null || externalOutId.isEmpty()) {
+                continue;
+            }
 
-        // 图片高
-        if (fileDataMap.containsKey("height")) {
-            archiveFile.setHeight((Integer) fileDataMap.get("height"));
+            // 判断外部 outId 是否存在于本地
+            if (!localOutIdSet.contains(externalOutId)) {
+                addFiles.add(externalFile); // 新增外部文件
+            } else {
+                // 存在则查找本地对应文件,判断是否需要更新
+                ArchiveFile localFile = localFileMap.get(externalOutId);
+                if (localFile != null && needUpdate(externalFile, localFile)) {
+                    updateLocalFile(localFile, externalFile); // 更新字段
+                    upFiles.add(localFile);
+                }
+            }
         }
+    }
 
-        // 同步时间
-        if (fileDataMap.containsKey("ftime")) {
-            archiveFile.setFtime((LocalDateTime) fileDataMap.get("ftime"));
-        }
+    // 辅助方法:判断是否需要更新
+    private boolean needUpdate(ArchiveFile external, ArchiveFile local) {
+        // 示例:检查关键字段是否变化
+        return !Objects.equals(external.getFileUrl(), local.getFileUrl())
+                || !Objects.equals(external.getPdfPageUrl(), local.getPdfPageUrl())
+                || !Objects.equals(external.getFileSize(), local.getFileSize());
+    }
 
-        // 更新时间
-        if (fileDataMap.containsKey("utime")) {
-            archiveFile.setUtime((LocalDateTime) fileDataMap.get("utime"));
-        }
+    // 辅助方法:更新本地文件字段
+    private void updateLocalFile(ArchiveFile local, ArchiveFile external) {
+        local.setFileUrl(external.getFileUrl());
+        local.setEVisaFile(external.getEVisaFile());
+        local.setPdfPageUrl(external.getPdfPageUrl());
+        local.setFilePage(external.getFilePage());
+        local.setFileSize(external.getFileSize());
+    }
 
-        // 排序
-        if (fileDataMap.containsKey("sort")) {
-            archiveFile.setSort((Integer) fileDataMap.get("sort"));
-        }
 
-        // 是否已组卷(0未组卷,1已组卷)
-        if (fileDataMap.containsKey("isArchive")) {
-            archiveFile.setIsArchive((Integer) fileDataMap.get("isArchive"));
-        }
 
-        // 页号
-        if (fileDataMap.containsKey("pageNum")) {
-            archiveFile.setPageNum((String) fileDataMap.get("pageNum"));
-        }
+    // 获取本地文件
+    private List<ArchiveFile> getLocalFils(Long projectId, List<String> outIds) {
+        List<ArchiveFile> localContracts = autoMapper.getOutArchiveFilesByOutIds(projectId,outIds);
 
-        // 文件大小
-        if (fileDataMap.containsKey("fileSize")) {
-            archiveFile.setFileSize((Long) fileDataMap.get("fileSize"));
-        }
+        return localContracts;
+    }
 
-        // 数据源类型(1原生,2数字化)
-        if (fileDataMap.containsKey("sourceType")) {
-            archiveFile.setSourceType((Integer) fileDataMap.get("sourceType"));
-        }
 
-        // 打了页码的pdf文件路径
-        if (fileDataMap.containsKey("pdfPageUrl")) {
-            archiveFile.setPdfPageUrl((String) fileDataMap.get("pdfPageUrl"));
+    public void addAndUpdateFiles(List<ArchiveFile> addFiles, List<ArchiveFile> upFiles) {
+        if (addFiles != null && !addFiles.isEmpty()) {
+            archiveFileClient.addArchiveFileEx(addFiles);
         }
 
-        // 类型(1施工,2监理)
-        if (fileDataMap.containsKey("classify")) {
-            archiveFile.setClassify((Integer) fileDataMap.get("classify"));
+        if (upFiles != null && !upFiles.isEmpty()) {
+            archiveFileClient.updateArchiveFileEx(upFiles);
         }
-
-        return archiveFile;
     }
 
+
 }

+ 15 - 3
blade-service/blade-archive/src/main/java/org/springblade/archive/external/impl/ExternalDataArchiveTreeService.java

@@ -60,8 +60,9 @@ public class ExternalDataArchiveTreeService {
             //根节点也映射
             if (advertTreeVo.getId().equals(nodeId)) {
                 archiveTreeNodeIdMapping.put(nodeId, rootId);
+            }else {
+                archiveTreeNodeIdMapping.put(advertTreeVo.getId(), SnowFlakeUtil.getId());
             }
-            archiveTreeNodeIdMapping.put(advertTreeVo.getId(), SnowFlakeUtil.getId());
         }
 
         // 2. 遍历所有节点,构建ArchiveTreeContract对象
@@ -113,6 +114,8 @@ public class ExternalDataArchiveTreeService {
         // 更新的合同列表
         List<ArchiveTreeContract> upContracts = new ArrayList<>();
 
+        Long rootId = externalDataInfo.getPid();
+
         // 获取外部系统合同数据
         List<ArchiveTreeContract> externalContracts = listConvert(req.getNodeId(), externalDataInfo.getArchives(),externalDataInfo);
 
@@ -136,7 +139,7 @@ public class ExternalDataArchiveTreeService {
         );
 
         // 持久化操作
-        addAndUpdateContracts(addContracts, upContracts);
+        addAndUpdateContracts(rootId,addContracts, upContracts);
     }
 
     /**
@@ -167,8 +170,17 @@ public class ExternalDataArchiveTreeService {
      * @param addContracts 新增合同集合
      * @param upContracts 更新合同集合
      */
-    private void addAndUpdateContracts(List<ArchiveTreeContract> addContracts, List<ArchiveTreeContract> upContracts) {
+    private void addAndUpdateContracts(Long rootId, List<ArchiveTreeContract> addContracts, List<ArchiveTreeContract> upContracts) {
         // 待实现:批量插入新增数据,批量更新现有数据
+
+        //如果addContracts 不为空,应该发送一个请求对root排序
+        if (addContracts!= null && addContracts.size() > 0) {
+            archiveTreeContractClient.addArchiveTreeContract(addContracts,rootId);
+        }
+
+        if (upContracts!= null && upContracts.size() > 0) {
+            archiveTreeContractClient.updateArchiveTreeContract(upContracts);
+        }
     }
 
     private void getAddAndUpdateContracts(

+ 2 - 0
blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/ArchivesAutoMapper.java

@@ -210,4 +210,6 @@ public interface ArchivesAutoMapper extends BaseMapper<ArchivesAuto> {
 	List<ArchiveTreeContract> getOutNodesByOutIds(@Param("projectId")Long projectId,@Param("ids") List<String> outIds);
 
 	List<ArchivesAuto> getOutArchiveAutosByOutIds(@Param("projectId")Long projectId,@Param("ids") List<String> outIds);
+
+	List<ArchiveFile> getOutArchiveFilesByOutIds(@Param("projectId")Long projectId,@Param("ids") List<String> outIds);
 }

+ 87 - 6
blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/ArchivesAutoMapper.xml

@@ -154,6 +154,68 @@
         <result column="out_id" property="outId"/>
     </resultMap>
 
+    <!-- 通用查询映射结果 -->
+    <resultMap id="archiveFileResultMap1" type="org.springblade.business.entity.ArchiveFile">
+        <result column="id" property="id"/>
+        <result column="create_user" property="createUser"/>
+        <result column="create_dept" property="createDept"/>
+        <result column="create_time" property="createTime"/>
+        <result column="update_user" property="updateUser"/>
+        <result column="update_time" property="updateTime"/>
+        <result column="status" property="status"/>
+        <result column="is_deleted" property="isDeleted"/>
+        <result column="project_id" property="projectId"/>
+        <result column="contract_id" property="contractId"/>
+        <result column="node_id" property="nodeId"/>
+        <result column="file_number" property="fileNumber"/>
+        <result column="file_name" property="fileName"/>
+        <result column="file_time" property="fileTime"/>
+        <result column="file_url" property="fileUrl"/>
+        <result column="file_page" property="filePage"/>
+        <result column="is_approval" property="isApproval"/>
+        <result column="is_certification" property="isCertification"/>
+        <result column="certification_time" property="certificationTime"/>
+        <result column="is_need_certification" property="isNeedCertification"/>
+        <result column="duty_user" property="dutyUser"/>
+        <result column="pdf_file_url" property="pdfFileUrl"/>
+        <result column="sheet_type" property="sheetType"/>
+        <result column="sheet_source" property="sheetSource"/>
+        <result column="drawing_no" property="drawingNo"/>
+        <result column="cite_change_number" property="citeChangeNumber"/>
+        <result column="e_visa_file" property="eVisaFile"/>
+        <result column="node_ext_id" property="nodeExtId"/>
+        <result column="file_type" property="fileType"/>
+        <result column="archive_id" property="archiveId"/>
+        <result column="origin_id" property="originId"/>
+        <result column="filming_time" property="filmingTime"/>
+        <result column="filmingor_time" property="filmingorTime"/>
+        <result column="tag_id" property="tagId"/>
+        <result column="pic_code" property="picCode"/>
+        <result column="refer_code" property="referCode"/>
+        <result column="film_code" property="filmCode"/>
+        <result column="width" property="width"/>
+        <result column="height" property="height"/>
+        <result column="ftime" property="ftime"/>
+        <result column="utime" property="utime"/>
+        <result column="del_time" property="delTime"/>
+        <result column="sort" property="sort"/>
+        <result column="box_name" property="boxName"/>
+        <result column="box_number" property="boxNumber"/>
+        <result column="is_auto_file" property="isAutoFile"/>
+        <result column="is_archive" property="isArchive"/>
+        <result column="page_num" property="pageNum"/>
+        <result column="file_size" property="fileSize"/>
+        <result column="source_type" property="sourceType"/>
+        <result column="is_element" property="isElement"/>
+        <result column="pdf_page_url" property="pdfPageUrl"/>
+        <result column="fid" property="fid"/>
+        <result column="rectification" property="rectification"/>
+        <result column="m_wbs_tree_contract_p_key_id" property="mWbsTreeContractPKeyId"/>
+        <result column="u_image_classification_file_id" property="uImageClassificationFileId"/>
+        <result column="out_id" property="outId"/>
+        <result column="sort_num" property="sortNum"/>
+    </resultMap>
+
     <select id="approvalFile" resultType="org.springblade.archive.vo.ArchivesAutoVO$ApprovalFile">
         <if test="archiveId!=null">
             select * from u_archive_file where archive_id = #{archiveId} and is_element = 0
@@ -1265,7 +1327,27 @@
             #{item.cqContractId}
         </foreach>
     </select>
-    <select id="getOutNodesByOutIds" resultType="org.springblade.manager.entity.ArchiveTreeContract">
+
+    <select id="getOutArchiveAutosByOutIds" resultMap="archivesAutoResultMap">
+        select *
+        from u_archives_auto
+        where project_id = #{projectId}
+        and is_auto_file!=1
+        and is_deleted=0
+        and is_lock!=1
+        and
+        out_id in
+        <foreach collection="ids" item="id" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </select>
+
+    <select id="selectArchivesAutoPage1" resultMap="archivesAutoResultMap">
+        select *
+        from u_archives_auto
+        where is_deleted = 0
+    </select>
+    <select id="getOutNodesByOutIds" resultMap="archiveTreeContractResultMap">
         select id,node_name,parent_id,out_id
         from m_archive_tree_contract
         where project_id = #{projectId} and is_deleted = 0 and
@@ -1275,13 +1357,12 @@
         </foreach>
     </select>
 
-    <select id="getOutArchiveAutosByOutIds" resultType="org.springblade.manager.entity.ArchiveTreeContract">
+
+    <select id="getOutArchiveFilesByOutIds" resultMap="archiveFileResultMap1">
         select *
-        from u_archives_auto
+        from u_archive_file
         where project_id = #{projectId}
-          and is_auto_file!=1
-          and is_deleted=0
-          and is_lock!=1
+        and is_deleted=0
         and
         out_id in
         <foreach collection="ids" item="id" open="(" separator="," close=")">

+ 19 - 6
blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchivesAutoServiceImpl.java

@@ -2025,27 +2025,40 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 		try {
 			if (frontUrls != null) {
 				for (String frontUrl : frontUrls) {
-					if (frontUrl.contains(ArchiveAutoPdfServiceImpl.ARCHIVE_NUMBER[0]) && config.getFactorType().contains("1")) {
+					// 封面(原r_Archives_front)增加中文"封面"匹配
+					if ((frontUrl.contains(ArchiveAutoPdfServiceImpl.ARCHIVE_NUMBER[0])
+							|| frontUrl.contains("封面"))
+							&& config.getFactorType().contains("1")) {
 						if(frontUrl.contains("@@@")){
 							front = frontUrl.substring(0,frontUrl.indexOf("@@@"));
 						}else {
 							front = frontUrl;
 						}
-					} else if (frontUrl.contains(ArchiveAutoPdfServiceImpl.ARCHIVE_NUMBER[1]) && config.getFactorType().contains("2")) {
+					}
+					// 卷内目录(原r_Archives_catalog)增加中文匹配
+					else if ((frontUrl.contains(ArchiveAutoPdfServiceImpl.ARCHIVE_NUMBER[1])
+							|| frontUrl.contains("卷内目录"))
+							&& config.getFactorType().contains("2")) {
 						if(frontUrl.contains("@@@")){
 							cataLog = frontUrl.substring(0,frontUrl.indexOf("@@@"));
 						}else {
 							cataLog = frontUrl;
 						}
-
-					} else if (frontUrl.contains(ArchiveAutoPdfServiceImpl.ARCHIVE_NUMBER[2]) && config.getFactorType().contains("3")) {
+					}
+					// 备考表(原r_Archives_spare)增加中文匹配
+					else if ((frontUrl.contains(ArchiveAutoPdfServiceImpl.ARCHIVE_NUMBER[2])
+							|| frontUrl.contains("备考表"))
+							&& config.getFactorType().contains("3")) {
 						if(frontUrl.contains("@@@")){
 							spare = frontUrl.substring(0,frontUrl.indexOf("@@@"));
 						}else {
 							spare = frontUrl;
 						}
-
-					} else if (frontUrl.contains(ArchiveAutoPdfServiceImpl.ARCHIVE_NUMBER[3]) && config.getFactorType().contains("4")) {
+					}
+					// 背脊(原r_Archives_back)增加中文匹配
+					else if ((frontUrl.contains(ArchiveAutoPdfServiceImpl.ARCHIVE_NUMBER[3])
+							|| frontUrl.contains("背脊"))
+							&& config.getFactorType().contains("4")) {
 						if(frontUrl.contains("@@@")){
 							back = frontUrl.substring(0,frontUrl.indexOf("@@@"));
 						}else {

+ 10 - 0
blade-service/blade-business/src/main/java/org/springblade/business/feignClient/ArchiveFileClientImpl.java

@@ -346,4 +346,14 @@ public class ArchiveFileClientImpl implements ArchiveFileClient {
         return this.iArchiveFileService.list(wrapper);
     }
 
+    @Override
+    public void addArchiveFileEx(List<ArchiveFile> files) {
+        iArchiveFileService.saveBatch(files);
+    }
+
+    @Override
+    public void updateArchiveFileEx(List<ArchiveFile> files) {
+        iArchiveFileService.updateBatchById(files);
+    }
+
 }

+ 8 - 8
blade-service/blade-business/src/main/java/org/springblade/business/mapper/ArchiveFileMapper.xml

@@ -177,7 +177,7 @@
         <if test="vo.nodeIds != null and vo.nodeIds != ''">
             t.tree_sort,
         </if>
-        u.sort,u.create_time
+        u.sort,u.sort_num,u.create_time
         limit #{current}, #{size}
     </select>
 
@@ -218,7 +218,7 @@
             cite_change_number like concat('%',#{vo.queryValue},'%')
             )
         </if>
-        order by box_number,sort,create_time
+        order by box_number,sort,sort_num,create_time
 
     </select>
     <select id="selectArchiveFilePageByBoxName" resultMap="archiveFileResultMap">
@@ -258,7 +258,7 @@
             cite_change_number like concat('%',#{vo.queryValue},'%')
             )
         </if>
-        order by box_number,sort,create_time
+        order by box_number,sort,sort_num,create_time
         limit #{current}, #{size}
     </select>
     <select id="getDeleteDataByIds" resultType="org.springblade.business.entity.ArchiveFile">
@@ -316,7 +316,7 @@
                 #{id}
             </foreach>
         </if>
-        order by sort,create_time
+        order by sort,sort_num,create_time
     </select>
     <select id="getArchiveFileByFileIds" resultMap="archiveFileResultMap">
         select * from u_archive_file where is_deleted = 0
@@ -326,7 +326,7 @@
                 #{id}
             </foreach>
         </if>
-        order by sort,create_time
+        order by sort,sort_num,create_time
     </select>
     <select id="getListByProjectId" resultType="org.springblade.business.entity.ArchiveFile">
         select *
@@ -362,7 +362,7 @@
           and (is_archive = 0 OR is_archive IS NULL)
           and (is_auto_file is null or is_auto_file != 1)
           and is_deleted = 0
-        order by sort,create_time
+        order by sort,sort_num,create_time
     </select>
 
     <select id="getListByNodeIDName" resultMap="archiveFileResultMap">
@@ -372,7 +372,7 @@
           and (is_archive = 0 OR is_archive IS NULL)
           and (is_auto_file is null or is_auto_file != 1)
           and is_deleted = 0
-        order by sort,create_time
+        order by sort,sort_num,create_time
     </select>
 
     <select id="getArchiveFileByArchiveID" resultMap="archiveFileResultMap">
@@ -380,7 +380,7 @@
         from u_archive_file
         where archive_id = #{archiveId}
           and is_deleted = 0
-        order by sort,create_time
+        order by sort,sort_num,create_time
     </select>
 
 

+ 4 - 0
blade-service/blade-business/src/main/java/org/springblade/business/service/IArchiveFileService.java

@@ -70,4 +70,8 @@ public interface IArchiveFileService extends BaseService<ArchiveFile> {
     List<ArchiveFile> getArchiveFileByArchivesId(String archivesIds, String fileIds);
 
     boolean updateArchiveFileByBoxNameOne(String boxName, Integer boxNumber);
+
+    public void addArchiveFileEx(List<ArchiveFile> files);
+
+    public void updateArchiveFileEx(List<ArchiveFile> files);
 }

+ 14 - 0
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/ArchiveFileServiceImpl.java

@@ -293,4 +293,18 @@ public class ArchiveFileServiceImpl extends BaseServiceImpl<ArchiveFileMapper, A
         return iPage.setRecords(pageVoList);
     }
 
+    @Override
+    public void addArchiveFileEx(List<ArchiveFile> files) {
+        executorService.execute(()->{
+            this.saveBatch(files);
+        });
+    }
+
+    @Override
+    public void updateArchiveFileEx(List<ArchiveFile> files) {
+        executorService.execute(()->{
+            this.updateBatchById(files);
+        });
+    }
+
 }

+ 14 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/feign/ArchiveTreeContractImpl.java

@@ -3,10 +3,12 @@ package org.springblade.manager.feign;
 import lombok.AllArgsConstructor;
 import org.apache.ibatis.annotations.Param;
 import org.springblade.archive.dto.JiLinQueryDto;
+import org.springblade.business.entity.ArchiveFile;
 import org.springblade.manager.dto.ArchiveTreeContractDTO;
 import org.springblade.manager.entity.ArchiveTreeContract;
 import org.springblade.manager.mapper.ArchiveTreeContractMapper;
 import org.springblade.manager.service.IArchiveTreeContractService;
+import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
@@ -153,6 +155,18 @@ public class ArchiveTreeContractImpl implements ArchiveTreeContractClient {
         return archiveTreeContractMapper.getOutNodesByOutIds(projectId,outIds);
     }
 
+    @Override
+    public void updateArchiveTreeContract(List<ArchiveTreeContract> archiveTreeContracts) {
+        archiveTreeContractService.updateBatchById(archiveTreeContracts);
+    }
+    @Override
+    public void addArchiveTreeContract(@RequestBody List<ArchiveTreeContract> archiveTreeContracts, @RequestParam Long rootId){
+        archiveTreeContractService.saveBatch(archiveTreeContracts);
+        ArchiveTreeContract rootContract = archiveTreeContractService.getById(rootId);
+
+        //排序
+
+    }