Prechádzať zdrojové kódy

Merge branch 'dev' of http://219.151.181.73:3000/zhuwei/bladex into feature-lihb-20250610

LHB 4 mesiacov pred
rodič
commit
d110431122
89 zmenil súbory, kde vykonal 3092 pridanie a 438 odobranie
  1. 1 0
      blade-common/src/main/java/org/springblade/common/utils/FileUtils.java
  2. 2 2
      blade-ops/blade-resource/src/main/java/org/springblade/resource/endpoint/LargeFileEndpoint.java
  3. 6 0
      blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/entity/ArchivesAuto.java
  4. 2 1
      blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/entity/TaskSplit.java
  5. 58 0
      blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/vo/ArchiveDataVo.java
  6. 2 0
      blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/vo/ArchivesAutoVO.java
  7. 1 17
      blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/vo/TaskSplitVO.java
  8. 3 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/feign/ArchiveFileClient.java
  9. 3 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/feign/MetadataClassificationClient.java
  10. 3 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/FixedFlowVO.java
  11. 16 8
      blade-service-api/blade-e-visa-api/src/main/java/org/springblade/evisa/redissionUtil/DistributedRedisLock.java
  12. 51 0
      blade-service-api/blade-e-visa-api/src/main/java/org/springblade/evisa/vo/ArchivesSplitInfoVO.java
  13. 8 0
      blade-service-api/blade-e-visa-api/src/main/java/org/springblade/evisa/vo/TaskArchiveSplitVO.java
  14. 1 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/ArchiveTreeContractDTO.java
  15. 6 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/ArchiveTreeContract.java
  16. 4 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/feign/ArchiveTreeContractClient.java
  17. 14 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/WbsTreeContractVO6.java
  18. 28 0
      blade-service-api/blade-user-api/src/main/java/org/springblade/system/user/vo/InformationQueryBIMVO.java
  19. 1 1
      blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchiveFileAutoController.java
  20. 13 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchiveFileController.java
  21. 2 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchivesAutoController.java
  22. 1 1
      blade-service/blade-archive/src/main/java/org/springblade/archive/controller/TaskSplitController.java
  23. 370 142
      blade-service/blade-archive/src/main/java/org/springblade/archive/external/utils/TransUtil.java
  24. 2 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/ArchivesAutoMapper.java
  25. 23 3
      blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/ArchivesAutoMapper.xml
  26. 6 1
      blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/TaskSplitMapper.java
  27. 6 1
      blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/TaskSplitMapper.xml
  28. 65 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/IArchiveNameService.java
  29. 2 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/IArchivesAutoService.java
  30. 19 5
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchiveAutoPdfServiceImpl.java
  31. 287 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchiveNameServiceImpl.java
  32. 440 16
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchivesAutoServiceImpl.java
  33. 30 1
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/TaskSplitServiceImpl.java
  34. 1 1
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/TraceLogServiceImpl.java
  35. 9 3
      blade-service/blade-archive/src/main/java/org/springblade/archive/utils/FileUtils.java
  36. 12 9
      blade-service/blade-business/src/main/java/org/springblade/business/controller/InformationWriteQueryController.java
  37. 14 3
      blade-service/blade-business/src/main/java/org/springblade/business/controller/TaskController.java
  38. 2 2
      blade-service/blade-business/src/main/java/org/springblade/business/controller/TrialDetectionController.java
  39. 5 0
      blade-service/blade-business/src/main/java/org/springblade/business/feignClient/ArchiveFileClientImpl.java
  40. 6 0
      blade-service/blade-business/src/main/java/org/springblade/business/feignClient/MetadataClassificationClientImpl.java
  41. 5 1
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/ArchiveFileMapper.xml
  42. 1 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/FixedFlowLinkMapper.java
  43. 3 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/FixedFlowLinkMapper.xml
  44. 1 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/MetadataClassificationMapper.java
  45. 9 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/MetadataClassificationMapper.xml
  46. 1 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/IFixedFlowLinkService.java
  47. 2 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/IMetadataClassificationService.java
  48. 5 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/FixedFlowLinkServiceImpl.java
  49. 6 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/FixedFlowServiceImpl.java
  50. 67 60
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/InformationQueryServiceImpl.java
  51. 591 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/MetadataClassificationServiceImpl.java
  52. 1 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TaskServiceImpl.java
  53. 41 20
      blade-service/blade-business/src/main/java/org/springblade/business/utils/PDFUtil.java
  54. 252 27
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/controller/ArchiveController.java
  55. 1 1
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/controller/EVController.java
  56. 8 1
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/service/impl/EVDataServiceImpl.java
  57. 34 8
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/utils/PDFUtils.java
  58. 27 5
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ArchiveTreeContractController.java
  59. 197 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ExcelTabController.java
  60. 2 2
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/SignConfigController.java
  61. 3 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/SystemMsgController.java
  62. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/TableFileController.java
  63. 2 2
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/WbsTreeController.java
  64. 4 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/feign/ArchiveTreeContractImpl.java
  65. 16 5
      blade-service/blade-manager/src/main/java/org/springblade/manager/job/SystemMsgJob.java
  66. 2 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/ArchiveTreeContractMapper.java
  67. 15 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/ArchiveTreeContractMapper.xml
  68. 3 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/ContractInfoMapper.xml
  69. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/SignConfigMapper.java
  70. 8 3
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/SignConfigMapper.xml
  71. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsTreeMapper.java
  72. 4 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsTreeMapper.xml
  73. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsTreePrivateMapper.java
  74. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/ISignConfigService.java
  75. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/IWbsTreeService.java
  76. 1 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ArTreeContractInitServiceImpl.java
  77. 84 9
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ArchiveTreeContractSyncImpl.java
  78. 61 23
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ExcelTabServiceImpl.java
  79. 26 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormulaServiceImpl.java
  80. 19 24
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/SignConfigServiceImpl.java
  81. 20 13
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/TextdictInfoServiceImpl.java
  82. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreePrivateServiceImpl.java
  83. 2 2
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeServiceImpl.java
  84. 1 1
      blade-service/blade-meter/src/main/java/org/springblade/meter/service/impl/InterimPayCertificateItemServiceImpl.java
  85. 12 0
      blade-service/blade-user/src/main/java/org/springblade/system/user/controller/WbsTreeController.java
  86. 4 4
      blade-service/blade-user/src/main/java/org/springblade/system/user/mapper/UserMapper.java
  87. 4 0
      blade-service/blade-user/src/main/java/org/springblade/system/user/mapper/UserMapper.xml
  88. 3 0
      blade-service/blade-user/src/main/java/org/springblade/system/user/service/IUserService.java
  89. 12 0
      blade-service/blade-user/src/main/java/org/springblade/system/user/service/impl/UserServiceImpl.java

+ 1 - 0
blade-common/src/main/java/org/springblade/common/utils/FileUtils.java

@@ -54,6 +54,7 @@ public class FileUtils {
                     Double fileLength = Double.parseDouble(contentLength + "");
                     file.setFileSize(Math.ceil(fileLength / 1024));
                 } catch (IOException e) {
+                    System.out.println("getOssFileSize errurl " + fileUrl);
                     e.printStackTrace();
                 }
                 reData.add(file);

+ 2 - 2
blade-ops/blade-resource/src/main/java/org/springblade/resource/endpoint/LargeFileEndpoint.java

@@ -486,7 +486,7 @@ public class LargeFileEndpoint {
      *
      * @param mappedByteBuffer
      */
-    private static void freeMappedByteBuffer(final MappedByteBuffer mappedByteBuffer) {
+/*    private static void freeMappedByteBuffer(final MappedByteBuffer mappedByteBuffer) {
         try {
             if (mappedByteBuffer == null) {
                 return;
@@ -512,7 +512,7 @@ public class LargeFileEndpoint {
         } catch (Exception e) {
             e.printStackTrace();
         }
-    }
+    }*/
 
     private static String getFileName(MultipartFileParam param) {
         String extension;

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

@@ -261,10 +261,16 @@ public class ArchivesAuto extends BaseEntity {
             this.setSecretLevel("4");
         }
 
+        //排序
+        if (autoVo.getOrderNum()!= null) {
+            this.setAutoFileSort(autoVo.getOrderNum());
+        }
 
         // 4. 设置默认值(根据业务需求)
         this.setIsAutoFile(0);
         this.setIsArchive(1);
         this.setIsDeleted(0);
     }
+
+    
 }

+ 2 - 1
blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/entity/TaskSplit.java

@@ -69,5 +69,6 @@ public class TaskSplit extends BaseEntity {
 	@ApiModelProperty("完成数量")
 		private Integer finished;
 
-
+	@ApiModelProperty("分解任务名称")
+	private String taskName;
 }

+ 58 - 0
blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/vo/ArchiveDataVo.java

@@ -0,0 +1,58 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.archive.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * 任务审核主表视图实体类
+ *
+ * @author BladeX
+ * @since 2022-07-01
+ */
+@Data
+public class ArchiveDataVo {
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty("节点Id")
+    private String nodeId;
+
+    @ApiModelProperty("文件编号")
+    private String filenNo;
+
+    @ApiModelProperty("文件名称")
+    private String fileNmae;
+
+    @ApiModelProperty("文件路径")
+    private String fileUrl;
+
+    @ApiModelProperty("文件日期")
+    private String fileDate;
+
+    @ApiModelProperty("责任者")
+    private String responsibility;
+
+    @ApiModelProperty("文件来源")
+    private String fileSible;
+
+    @ApiModelProperty("合同段Id")
+    private String contractId;
+
+    @ApiModelProperty("1:签名文件 2:附件")
+    private String sendType;
+}

+ 2 - 0
blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/vo/ArchivesAutoVO.java

@@ -80,6 +80,8 @@ public class ArchivesAutoVO extends ArchivesAuto {
 	 */
 	private List<String> queryList;
 
+    private Integer queryValueSize;
+
 	/**
 	 * 节点查询条件
 	 */

+ 1 - 17
blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/vo/TaskSplitVO.java

@@ -1,24 +1,8 @@
-/*
- *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *
- *  Redistributions of source code must retain the above copyright notice,
- *  this list of conditions and the following disclaimer.
- *  Redistributions in binary form must reproduce the above copyright
- *  notice, this list of conditions and the following disclaimer in the
- *  documentation and/or other materials provided with the distribution.
- *  Neither the name of the dreamlu.net developer nor the names of its
- *  contributors may be used to endorse or promote products derived from
- *  this software without specific prior written permission.
- *  Author: Chill 庄骞 (smallchill@163.com)
- */
 package org.springblade.archive.vo;
 
-import org.springblade.archive.entity.TaskSplit;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
+import org.springblade.archive.entity.TaskSplit;
 
 /**
  * 解析主标任务视图实体类

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

@@ -161,4 +161,7 @@ public interface ArchiveFileClient {
 
     @PostMapping(API_PREFIX + "/updateFilesEx")
     void updateArchiveFileEx(@RequestBody List<ArchiveFile> files);
+
+    @PostMapping(API_PREFIX + "/saveArchiveFileByBIM")
+    void saveArchiveFileByBIM(@RequestBody ArchiveFile archiveFile);
 }

+ 3 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/feign/MetadataClassificationClient.java

@@ -29,4 +29,7 @@ public interface MetadataClassificationClient {
 
     @PostMapping(API_PREFIX + "/getMetadataClassification")
     List<MetadataClassification> getMetadataClassification();
+
+    @PostMapping(API_PREFIX + "/createMetadataFiles")
+    boolean createMetadataFiles(@RequestBody List<Long> fileId);
 }

+ 3 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/FixedFlowVO.java

@@ -55,6 +55,9 @@ public class FixedFlowVO extends FixedFlow {
     @ApiModelProperty("提示信息")
     private String tips;
 
+    @ApiModelProperty("是否删除")
+    private boolean deletedIs;
+
     private Query query;
 
     public Query getQuery(Integer current, Integer size) {

+ 16 - 8
blade-service-api/blade-e-visa-api/src/main/java/org/springblade/evisa/redissionUtil/DistributedRedisLock.java

@@ -14,8 +14,7 @@ import java.util.concurrent.TimeUnit;
 public class DistributedRedisLock {
 
     private static final Logger _log = Logger.getLogger(DistributedRedisLock.class);
-
-    private static final Config config = new Config();
+    private static volatile Redisson redisson;
 
     private static final String LOCK_TITLE = "redisLock_";
 
@@ -104,13 +103,22 @@ public class DistributedRedisLock {
     }
 
     private static Redisson getRedisson() {
-        config.useSingleServer()
-                .setAddress("redis://" + RedissonManager.SPRING_REDIS_HOST + ":" + RedissonManager.SPRING_REDIS_PORT)
-                .setConnectionPoolSize(500);
-        if (StringUtil.isNotEmpty(RedissonManager.SPRING_REDIS_PASSWORD)) {
-            config.useSingleServer().setPassword(RedissonManager.SPRING_REDIS_PASSWORD);
+        if (redisson == null) {
+            synchronized (DistributedRedisLock.class) {
+                if (redisson == null) {
+                    Config config = new Config();
+                    config.useSingleServer()
+                            .setAddress("redis://" + RedissonManager.SPRING_REDIS_HOST + ":" + RedissonManager.SPRING_REDIS_PORT)
+                            .setConnectionPoolSize(500);
+                    if (StringUtil.isNotEmpty(RedissonManager.SPRING_REDIS_PASSWORD)) {
+                        config.useSingleServer().setPassword(RedissonManager.SPRING_REDIS_PASSWORD);
+                    }
+                    redisson = (Redisson) Redisson.create(config);
+                    _log.info("Redisson instance created.");
+                }
+            }
         }
-        return (Redisson) Redisson.create(config);
+        return redisson;
     }
 
 }

+ 51 - 0
blade-service-api/blade-e-visa-api/src/main/java/org/springblade/evisa/vo/ArchivesSplitInfoVO.java

@@ -0,0 +1,51 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.evisa.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+/**
+ * 视图实体类
+ *
+ * @author BladeX
+ * @since 2025-06-10
+ */
+@Data
+public class ArchivesSplitInfoVO {
+	// u_archv_file 主键id
+	@ApiModelProperty("id")
+	private String id;
+
+	// 文件Id
+	@ApiModelProperty("first_file_url")
+	private String firstFileUrl;
+
+	//需要分解的文件url
+	@ApiModelProperty("file_url")
+	private String fileUrl;
+
+	//需要分解的文件url
+	@ApiModelProperty("status")
+	private String status;
+
+	//分解任务主键ID
+	@ApiModelProperty("task_id")
+	private String taskId;
+
+	@ApiModelProperty("archive_id")
+	private String archiveId;
+}

+ 8 - 0
blade-service-api/blade-e-visa-api/src/main/java/org/springblade/evisa/vo/TaskArchiveSplitVO.java

@@ -6,13 +6,21 @@ import lombok.Data;
 @Data
 public class TaskArchiveSplitVO {
 
+    // u_archv_file 主键id
     @ApiModelProperty("id")
     private String id;
 
+    // u_archv_auto 主键id
     @ApiModelProperty("archiveId")
     private String archiveId;
 
+    //需要分解的文件url
     @ApiModelProperty("fileUrl")
     private String fileUrl;
 
+    //分解任务主键ID
+    @ApiModelProperty("taskId")
+    private String taskId;
+
+
 }

+ 1 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/ArchiveTreeContractDTO.java

@@ -39,4 +39,5 @@ public class ArchiveTreeContractDTO extends ArchiveTreeContract {
     private String nodeName;
     private String updateUserName;
     private String updateUserTime;
+    private Integer isSaveChild;
 }

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

@@ -159,6 +159,12 @@ public class ArchiveTreeContract extends BaseEntity {
      */
     private Long extKeyId;
 
+    /**
+     *
+     * 1单位工程2分部工程 3子分部工程 4分项工程5子分项工程 6工序
+     */
+    private Integer extNodeType;
+
     /**
      * 自动立卷类型 1最高 2分类并卷 3单独组卷   说明:1规则下可以有2或3;2和3两种规则互斥,2下不能有3,3下不能有2;
      */

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

@@ -27,6 +27,9 @@ public interface ArchiveTreeContractClient {
     @PostMapping(API_PREFIX + "/getHavedFileNodeByProjectID")
     List<ArchiveTreeContract> getHavedFileNodeByProjectID(@RequestParam Long projectId);
 
+    @PostMapping(API_PREFIX + "/getTopAutoTypeNodeByProjectID")
+    List<ArchiveTreeContract> getTopAutoTypeNodeByProjectID(@RequestParam Long projectId);
+
     /**
      * 根据项目id获取所有数据
      */
@@ -75,4 +78,5 @@ public interface ArchiveTreeContractClient {
 
     @PostMapping(API_PREFIX+"/adsArchiveTreeContract")
     public void addArchiveTreeContract(@RequestBody List<ArchiveTreeContract> archiveTreeContracts,@RequestParam Long rootId);
+
 }

+ 14 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/WbsTreeContractVO6.java

@@ -3,6 +3,7 @@ package org.springblade.manager.vo;
 import com.fasterxml.jackson.annotation.JsonInclude;
 import com.fasterxml.jackson.databind.annotation.JsonSerialize;
 import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 import org.springblade.core.tool.node.INode;
 import org.springblade.core.tool.node.TreeNode;
@@ -40,6 +41,10 @@ public class WbsTreeContractVO6 extends WbsTreeContract implements INode<WbsTree
 
     private Integer sort;
 
+    @ApiModelProperty(value = "1 水利工程 2是数字化")
+    private Integer nodeClass;
+
+
     @JsonInclude(JsonInclude.Include.NON_EMPTY)
     private Boolean hasChildren;
 
@@ -131,6 +136,15 @@ public class WbsTreeContractVO6 extends WbsTreeContract implements INode<WbsTree
         this.sort = sort;
     }
 
+    public Integer getNodeClass() {
+        return nodeClass;
+    }
+
+    public void setNodeClass(Integer nodeClass) {
+        this.nodeClass = nodeClass;
+    }
+
+
     @Override
     public String toString() {
         return "WbsTreeContractVO{" +

+ 28 - 0
blade-service-api/blade-user-api/src/main/java/org/springblade/system/user/vo/InformationQueryBIMVO.java

@@ -0,0 +1,28 @@
+package org.springblade.system.user.vo;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+
+@Data
+@TableName("u_information_query")
+public class InformationQueryBIMVO {
+
+    @TableField("id")
+    private String id;
+    @TableField("父级id")
+    private String parentId;
+
+    @TableField("名称")
+    private String name;
+
+    @JsonProperty("eVisaPdfUrl")
+    private String fileUrlPath;
+
+    @TableField("nodeType 1节点 2文件")
+    private String nodeType;
+
+    @TableField("文件状态 0未上报,1待审批,2已审批,3已废除")
+    private String status;
+}

+ 1 - 1
blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchiveFileAutoController.java

@@ -341,7 +341,7 @@ ArchiveFileAutoController extends BladeController {
         List<ArchiveFile> result = this.archiveFileClient.getArchiveFileByArchivesId(ids, "");
         List<String> pdfUrls = result.stream().map(archiveFile -> StringUtils.isNotEmpty(archiveFile.getPdfFileUrl()) ? archiveFile.getPdfFileUrl() : archiveFile.getFileUrl()).distinct().collect(Collectors.toList());
 
-//        FileUtils.mergePdfPublicMethods(pdfUrls,"");
+        //FileUtils.mergePdfPublicMethods(pdfUrls,"");
         /**
          * 案卷的只有一个文件,不合并先,需要的时候在把合并方法放出来
          * **/

+ 13 - 0
blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchiveFileController.java

@@ -12,6 +12,7 @@ import lombok.SneakyThrows;
 import org.apache.commons.lang.StringUtils;
 import org.springblade.archive.service.IArchivesAutoService;
 import org.springblade.archive.utils.FileUtils;
+import org.springblade.archive.vo.ArchiveDataVo;
 import org.springblade.business.entity.ArchiveFile;
 import org.springblade.business.feign.ArchiveFileClient;
 import org.springblade.business.feign.MetadataClassificationClient;
@@ -435,4 +436,16 @@ public class ArchiveFileController extends BladeController {
         }
         return R.data(true);
     }
+
+
+    /**
+     * 智慧工地推送文件至电子档案数据规则 接口
+     */
+    @PostMapping("/sendFileToEArchives")
+    @ApiOperationSupport(order = 18)
+    @ApiOperation(value = "智慧工地推送文件至电子档案数据规则接口")
+    public R<Boolean> sendFileToEArchives(@RequestBody ArchiveDataVo vo) {
+        //数据入库
+        return  autoService.sendFileToEArchives(vo);
+    }
 }

+ 2 - 0
blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchivesAutoController.java

@@ -152,6 +152,8 @@ public class ArchivesAutoController extends BladeController {
 		return R.data(pages);
 	}
 
+
+
 	/**
 	 * 档案利用-档案查询
 	 */

+ 1 - 1
blade-service/blade-archive/src/main/java/org/springblade/archive/controller/TaskSplitController.java

@@ -22,6 +22,7 @@ import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
 import lombok.AllArgsConstructor;
 import javax.validation.Valid;
 
+import org.springblade.archive.vo.TaskSplitVO;
 import org.springblade.core.mp.support.Condition;
 import org.springblade.core.mp.support.Query;
 import org.springblade.core.tool.api.R;
@@ -30,7 +31,6 @@ import org.springframework.web.bind.annotation.*;
 import org.springframework.web.bind.annotation.RequestParam;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import org.springblade.archive.entity.TaskSplit;
-import org.springblade.archive.vo.TaskSplitVO;
 import org.springblade.archive.service.ITaskSplitService;
 import org.springblade.core.boot.ctrl.BladeController;
 

+ 370 - 142
blade-service/blade-archive/src/main/java/org/springblade/archive/external/utils/TransUtil.java

@@ -19,208 +19,431 @@ public class TransUtil {
     public static final Map<String, Long> EXTERNAL_TO_INTERNAL_NODE_ID_MAP = new LinkedHashMap<String, Long>() {{
         // 初始化默认映射关系(可按需添加)
 
-        //=================建设单位
+        //=================建设单位】====
         //军教工验收文件
-        put("3b843c05e00c4b65a1e666db80cf", 1892759789381877760L);
+//        put("3b843c05e00c4b65a1e666db80cf", 1892759789381877760L);
+//
+//        //征地拆迁
+//        put("ced7daa78cc040d1b731dfedd51f", 1892759789381877780L);
+//
+//        //工程文件
+//        put("e18bd5c3b1f7489b87d27594dee9", 1892759789381877794L);
+//
+//        //决算和审计文件
+//        put("442e7e595dce411abd984da1866d", 1892759789381877811L);
+
+        //====建设单位数字化扫描档案(第一部分 综合文件)
+        //三、征地拆迁资料
+        put("8d69b1589c8d47bcac6ee0579f21", 1927614316916244487L);
+
+        //=======建设单位数字化扫描档案(第二部分 决算和审计文件)
+        //一、支付报表及计算单
+        put("c3073682882249cb83fb87ef83d4", 1927614316916244492L);
 
-        //征地拆迁
-        put("ced7daa78cc040d1b731dfedd51f", 1892759789381877780L);
+        //====监理
+        //====================【第一总监】
 
-        //工程文件
-        put("e18bd5c3b1f7489b87d27594dee9", 1892759789381877794L);
+        //监理抽检资料
+        put("5d17cfbfcc134319b3bc2251d1cf", 1927992314584629254L);
+
+        //交工验收工程质量评定资料
+        put("e6189ff32e8c4b07ab2f89453a6a", 1927992314584629271L);
+
+        //NoJL1合同段数字化扫描档案
+        //一、监理管理文件
+        put("dfe39a7134c34aea833b51ecd889", 1927992314584629252L);
+        //一、监理管理文件
+        //(一)质量控制措施、规定
+        put("55fe4f6011294050b65210d814e0", 1927992314584629250L);
+        //(二)质量控制往来文件
+        put("f72d6d2c24564e01a456c8f49593", 1927992314584629253L);
+        //(三)监理独立抽检资料(试验)
+        put("972d06c557924952abaa8257dc71", 1927992314584629272L);
+        //(四)监理独立抽检报告
+        put("535f2dca3d4a4c6f84d3b154e961", 1927992314584629255L);
+        //三、工程进度计划管理文件
+        put("487c6416e2f34158838588773454", 1927992314584629286L);
+        //五、其它文件
+        put("5491ddc563e74ad4bbb4baddcb9f", 1927992314584629288L);
+        //六、其它资料
+        put("1817a9c924fc4a9686ab5b02e077", 1927992314584629296L);
+
+//        //印章启用文件、监理人员变更的函和批复文件
+//        put("465c2ebad85e44e9b4217d7ae415", 1892759789402849282L);
+//        //工程监理月报(2022年1月至2023年2月)
+//        put("ffce00c9bd7443d9b3d6ef63f885", 1902189729003851778L);
+//        //监理日志(张换丽)
+//        put("6e7ad41e5cd542f893a69ec7cebd", 1902189935200030722L);
+//        //监理日志(钟兆革)
+//        put("8d818ccbf39247cbb1f49ed3c7b0", 1902190429066743809L);
+//
+//        //原材料、设备及构件试验报告、记录 1902201113984880642
+//        put("89aaa0372cc24d14b3efdd788141", 1902200995105722370L);
+//
+//
+//        //试验检测汇总表
+//        put("0b023c2125664791a0511fc587f8", 1902205006567428097L);
+//        //原材料、半成品、成品报告
+//        put("bbc75d54e5d14b1f8368ce6fb51f", 1902206555712638977L);
+//        //机械连接、焊接报告
+//        put("402d59509f78443b88923f9c6876", 1902206715393986562L);
+//        //土工、配合比
+//        put("3650e321d07845e3b1a0a38bc1c2", 1902206873229840386L);
+//
+//
+//
+//        //就安全生产印发的实施方案
+//        put("eadf2038639446dcb40c4fe198c8", 1902198126172426241L);
+//        //2020年至2023年业主就安全生产检查的通报及整改回复
+//        put("9067f2889fbe42d0917f80d20978", 1902198303939612673L);
+
+
+        //=========【第二总监】======================
+
+        //监理抽检资料
+        put("216663852e784ba1a96a2980d663", 1927992314593017861L);
+
+        //交工验收工程质量评定资料
+        put("60c2a98a533842e09625ef74f728", 1927992314593017878L);
+
+        //原材料、设备及构件试验报告、记录
+        //put("6dec0a4c4a8e42a0a2b138e6e4ff", 1902200181465272322L);
+
+        //NoJL2合同段数字化扫描档案
+        //一、监理管理文件
+
+        //一、监理管理文件
+        //(一)质量控制措施、规定
+
+        //(二)质量控制往来文件
+
+        //(三)监理独立抽检资料(试验)
+
+        //(四)监理独立抽检报告
+
+        //三、工程进度计划管理文件
+        put("a341cabc10834e42836424489eb9", 1927992314593017893L);
+        //五、其它文件
+        put("1f452f1671cb4e188b3623924927", 1927992314593017895L);
+        //六、其它资料
+        put("8005d637346d4523b7af12fbaaaf", 1927992314593017903L);
 
-        //决算和审计文件
-        put("442e7e595dce411abd984da1866d", 1892759789381877811L);
 
-        //====监理
-        //=========第一总监
-        //印章启用文件、监理人员变更的函和批复文件
-        put("465c2ebad85e44e9b4217d7ae415", 1892759789402849282L);
-        //工程监理月报(2022年1月至2023年2月)
-        put("ffce00c9bd7443d9b3d6ef63f885", 1902189729003851778L);
-        //监理日志(张换丽)
-        put("6e7ad41e5cd542f893a69ec7cebd", 1902189935200030722L);
-        //监理日志(钟兆革)
-        put("8d818ccbf39247cbb1f49ed3c7b0", 1902190429066743809L);
-
-        //原材料、设备及构件试验报告、记录 1902201113984880642
-        put("89aaa0372cc24d14b3efdd788141", 1902200995105722370L);
-
-
-        //试验检测汇总表
-        put("0b023c2125664791a0511fc587f8", 1902205006567428097L);
-        //原材料、半成品、成品报告
-        put("bbc75d54e5d14b1f8368ce6fb51f", 1902206555712638977L);
-        //机械连接、焊接报告
-        put("402d59509f78443b88923f9c6876", 1902206715393986562L);
-        //土工、配合比
-        put("3650e321d07845e3b1a0a38bc1c2", 1902206873229840386L);
 
+        //=========【第三总监】
         //监理抽检资料
-        put("5d17cfbfcc134319b3bc2251d1cf", 1892759789402849302L);
+        put("91aee6c9b92e4a10806266fa9513", 1927992314593017914L);
+
+        //交工验收工程质量评定资料
+        put("a1029e86a1994ca0b7d6c4d5dbda", 1927992314593017931L);
+//        put("05ac2ef4857f468483924d51f90a", 1902638005113028610L);
+
+        //NoJL3合同段数字化扫描档案
+        //一、监理管理文件
+        put("26314b7d11c44533bea9ad8e277b", 1927992314593017910L);
+
+        //二、工程质量控制文件
+        //(一)质量控制措施、规定
+        put("02bcd9bcbdb044d1ba974bc5f24a", 1927992314593017912L);
+        //(二)质量控制往来文件
+        put("a749afe440a746e1b88594b8bb0b", 1927992314593017913L);
+        //(三)监理独立抽检资料(试验)
+        put("f1ed755800004c4cb46440bc7ecb", 1927992314593017932L);
+        //(四)监理独立抽检报告
+        put("7bb1ceb7d69941e5a22a3343c266", 1927992314593017915L);
+        //三、工程进度计划管理文件
+        put("0d73872e37a14328a667510da2b7", 1927992314593017946L);
+        //五、其它文件
+        put("633076005a33419b935261445a39", 1927992314593017948L);
+        //六、其它资料
+        put("863f42ce1acd4d60b157f6184ee2", 1927992314593017956L);
 
-        //就安全生产印发的实施方案
-        put("eadf2038639446dcb40c4fe198c8", 1902198126172426241L);
-        //2020年至2023年业主就安全生产检查的通报及整改回复
-        put("9067f2889fbe42d0917f80d20978", 1902198303939612673L);
 
 
-        //=========第二总监
 
-        //原材料、设备及构件试验报告、记录
-        put("6dec0a4c4a8e42a0a2b138e6e4ff", 1902200181465272322L);
 
+        //=========【第四总监】
+        //监理抽检资料
+        put("ad7896d5c0b74d988a02c342928c", 1927992314597212165L);
+
+        //交工验收质量评定
+        put("0679ddcea354420e893a00586737", 1927992314597212182L);
 
-        put("216663852e784ba1a96a2980d663", 1892759789407043606L);
 
-        //=========第三总监
-        put("05ac2ef4857f468483924d51f90a", 1902638005113028610L);
 
+        //NoJL4合同段数字化扫描档案
+        //一、监理管理文件
+        put("c46141f9c8dd4116b056a7db6a2d", 1927992314597212161L);
 
-        put("91aee6c9b92e4a10806266fa9513", 1892759789407043641L);
+        //二、工程质量控制文件
+        //(一)质量控制措施、规定
+        put("2dafbff0d0ae43bfa6bb64f35cab", 1927992314597212163L);
+        //(二)质量控制往来文件
+        put("67107bea233a4047a886bfd48014", 1927992314597212164L);
+        //(三)监理独立抽检资料(试验)
+        put("d1d5d934f6eb45eebb1616816cd5", 1927992314597212183L);
+        //(四)监理独立抽检报告
+        put("3a31de201c604f97a66c02836669", 1927992314597212166L);
+        //三、工程进度计划管理文件
+        put("ae9523597eac403ca8d7eb096840", 1927992314597212197L);
+        //五、其它文件
+        put("2ae858ae006443258446ebe892b9", 1927992314597212199L);
+        //六、其它资料
+        put("8c6913b1dacc45fe966a56d2ff56", 1927992314597212207L);
 
-        //=========第四总监
-        put("ad7896d5c0b74d988a02c342928c", 1892759789407043676L);
+
+
+        //=========【机电标总监】
+        //监理抽检资料
+        put("5b8da50309334dcbb8a02b3339bc", 1927992314597212218L);
 
         //交工验收质量评定
-        put("0679ddcea354420e893a00586737", 1892759789407043678L);
+        put("5831fc73d47a4f35b7df75e862df", 1927992314597212235L);
 
-        //管理文件
-        put("c46141f9c8dd4116b056a7db6a2d", 1892759789407043655L);
-        //计划文件
-        put("ae9523597eac403ca8d7eb096840", 1892759789407043679L);
 
 
-        //质量控制措施
-        put("2dafbff0d0ae43bfa6bb64f35cab", 1892759789407043671L);
-        //监理独立抽检
-        put("d1d5d934f6eb45eebb1616816cd5", 1892759789407043672L);
-        //监理独立报告
-        put("3a31de201c604f97a66c02836669", 1892759789407043673L);
+        //===========施工单位归档资料
 
-        //其他文件
-        put("2ae858ae006443258446ebe892b9", 1892759789407043686L);
 
-        //其他资料
-        put("8c6913b1dacc45fe966a56d2ff56", 1915963769346564097L);
 
 
-        //=========机电标总监
-        put("5b8da50309334dcbb8a02b3339bc", 1892759789407043711L);
 
 
 
 
+        //=====================【第一合同段】=======================================================
 
-        //===========施工单位归档资料
-        //=========第四合同段
-          //二工程管理文件
-            //施工准备文件 -1.施工项目部组建、印章启用、人员任命文件,进场人员资质报审文件,施工设备仪器进场报审文件、设备仪器校验、率定文件
-            put("0b0ac82851d7484bba414bb1ccbd", 1892759789415432263L);
-
-            //施工准备文件 -5.工地试验室备案申请表及交通质监部门备案通知书、工地实验室成立、资质、授权
-            put("9144353d740c428ea46ca4228d22", 1892759789415432267L);
-         //三 施工质量控制文件
-            //原材
-            put("54dc995fc9814ecd81f6f25dc936", 1892759789415432282L);
-            //配合比
-             put("5f07af9ef5d14a2781cef179ef7c", 1892759789415432284L);
-            //试验报告
-             put("ffe1d44383ed4f438d29b73b7dbb", 1892759789415432285L);
-             //施工工序资料
-             put("075d3e8a3d48418f959283c55616", 1892759789415432286L);
-         //五 进度控制文件
-          //1 进度计划
-             put("31bc6b0a55cb4c408e292ee0fcdb", 1892759789415432296L);
-
-             //============================
-
-        //=========第三合同段
-            //二工程管理文件
-            //施工准备文件 -1.施工项目部组建、印章启用、人员任命文件,进场人员资质报审文件,施工设备仪器进场报审文件、设备仪器校验、率定文件
-            //put("0b0ac82851d7484bba414bb1ccbd", 1892759789415432263L);
-
-            //三 施工质量控制文件
-            //原材
-            put("da9434c6a86147c0979ef09624dd", 1892759789415432221L);
-            //配合比
-            put("3080795a07544c2c972cc938da1f", 1892759789415432223L);
-            //试验报告
-            //put("ffe1d44383ed4f438d29b73b7dbb", 1892759789415432285L);
-            //施工工序资料
-            put("a1a4ea5ea88549c09c57b6da8e9e", 1892759789415432225L);
-            //五 进度控制文件
-            //1 进度计划
-            //put("31bc6b0a55cb4c408e292ee0fcdb", 1892759789415432296L);
-
-
-        //=========机电标
-        //二工程管理文件
-        //施工准备文件 -1.施工项目部组建、印章启用、人员任命文件,进场人员资质报审文件,施工设备仪器进场报审文件、设备仪器校验、率定文件
-        //put("0b0ac82851d7484bba414bb1ccbd", 1892759789415432263L);
+        //评定
+        put("1984907813174e698cb7d473911d", 1927992893465690119L);
+        //施工工序资料
+        put("a22abc54ff8446e59760309263f7", 1927992893465690135L);
 
-        //三 施工质量控制文
+
+        //【No1合同段数字化扫描档案】
+        //二、工程管理文件
+        put("3f84d392080e4375b0f3a6467b22", 1927992893465690115L);
+
+        //三、施工质量控制文件   (一)工程质量管理文件
+        put("2f1c3a407b64441a83416def6c97", 1927992893465690118L);
+
+        //三、施工质量控制文件 (二)工地试验室成立
+        put("f363c765bab44c6082731d529f7f", 1927992893465690136L);
+
+        //三、施工质量控制文件 (四)仪器校准证书
+        put("4ec32cc441394a48a608571a361f", 1927992893465690137L);
+
+        //三、施工质量控制文件 (五)材料及标准试验
+        put("d5b62eb13097434fab99879ed98a", 1927992893465690120L);
+
+        //三、施工质量控制文件 (六)现场抽检试验检测报告
+        put("426db97ebf1a4de9b28153335342", 1927992893465690138L);
+
+        //四、安全文明施工文件
+        put("ff0f6b6962494df7b7b3f03539b2", 1927992893465690146L);
+
+        //五、进度控制文件
+        put("4fbcf1973adb481a89a36d8b9898", 1927992893465690147L);
+
+        //七、变更文件
+        put("2e203ab2574640c2895ac5196204", 1927992893465690162L);
+        //八、施工原始记录
+        put("f50cb7a3288848a88f99ee87e800", 1927992893465690149L);
+
+        //三 施工质量控制文件
+
+
+        //原材
+//        put("4620774da89544e7b8d815d65c01", 1892759789411237917L);
+//        //各种试验报告
+//        put("1929194d06794a6a940a761561f9", 1892759789411237920L);
+//        //配合比
+//        put("c05b1ab104f44875b264c52e81eb", 1892759789411237919L);
         //试验报告
         //put("ffe1d44383ed4f438d29b73b7dbb", 1892759789415432285L);
+
+
+
+        //=======================【第二合同段】=======================================
+
+        //评定
+        put("f6fb614a515440cb95676d99ce41", 1927992893469884422L);
+
         //施工工序资料
-        put("8a0aa647278548fa9edba59b78c4", 1892759789419626529L);
+        put("4707eb84188443b481398a15e8cf", 1927992893469884438L);
 
 
-        //=========第一合同段
         //二工程管理文件
-        put("3f84d392080e4375b0f3a6467b22", 1892759789411237894L);
 
-        //施工质量文件
-        put("2f1c3a407b64441a83416def6c97", 1892759789411237906L);
 
-        //工地
-        put("f363c765bab44c6082731d529f7f", 1892759789411237916L);
 
-        //仪器
-        put("4ec32cc441394a48a608571a361f", 1892759789411237922L);
 
-        //材料标准试验
-        put("d5b62eb13097434fab99879ed98a", 1915971643921637377L);
+        //三 施工质量控制文件
+        //原材
+        //put("87edcc42ba2b4859a1aec5191080", 1892759789411237978L);
+
+
 
-        //现场抽检
-        put("426db97ebf1a4de9b28153335342", 1915971747701301249L);
+        //【No2合同段数字化扫描档案】
+        //二、工程管理文件
+        put("c2ff86882ea5461084650afc89f4", 1927992893469884418L);
 
-        //安全文明
-        put("ff0f6b6962494df7b7b3f03539b2", 1892759789411237923L);
+        //三、施工质量控制文件   (一)工程质量管理文件
+        put("3b12c00d0fbc4cfbb73804aec5f2", 1927992893469884421L);
 
-        //进度管理文件
-        put("4fbcf1973adb481a89a36d8b9898", 1915965348099366914L);
+        //三、施工质量控制文件 (二)工地试验室成立
+        put("fdbd69cb41f94775b619bdaa3c6e", 1927992893469884439L);
 
-        //变更文件
-        put("2e203ab2574640c2895ac5196204", 1915965498528079873L);
-        //施工原始记录
-        put("f50cb7a3288848a88f99ee87e800", 1915965617583398913L);
+        //三、施工质量控制文件 (四)仪器校准证书
+        put("5501ee640af0481ab4c447dfe201", 1927992893469884440L);
 
-        //三 施工质量控制文件
+        //三、施工质量控制文件 (五)材料及标准试验
+        put("f6fff76903254aeab4511376fed5", 1927992893469884423L);
+
+        //三、施工质量控制文件 (六)现场抽检试验检测报告
+        put("020567726035400a971f95f5a585", 1927992893469884441L);
+
+        //四、安全文明施工文件
+        put("e8e2af76849d4fe392fbfec50156", 1927992893469884449L);
+
+        //五、进度控制文件
+        put("9f7b03959db646f791a1b2581ed2", 1927992893469884450L);
+
+        //七、变更文件
+        put("e04b9db2c50749629bf8a01bf6f3", 1927992893469884465L);
+        //八、施工原始记录
+        put("44c6ef4bacb144d18f06742a2c27", 1927992893469884452L);
+
+        //=========第三合同段================================================
 
         //评定
-        put("1984907813174e698cb7d473911d", 1892759789411237907L);
+        put("0372bb19089347e7aca7683fdd37", 1927992893469884472L);
+
+        //施工工序资料
+        put("a1a4ea5ea88549c09c57b6da8e9e", 1927992893469884488L);
+
+
+        //二工程管理文件
+        //施工准备文件 -1.施工项目部组建、印章启用、人员任命文件,进场人员资质报审文件,施工设备仪器进场报审文件、设备仪器校验、率定文件
+        //put("0b0ac82851d7484bba414bb1ccbd", 1892759789415432263L);
+
+        //三 施工质量控制文件
         //原材
-        put("4620774da89544e7b8d815d65c01", 1892759789411237917L);
-        //各种试验报告
-        put("1929194d06794a6a940a761561f9", 1892759789411237920L);
+        put("da9434c6a86147c0979ef09624dd", 1892759789415432221L);
         //配合比
-        put("c05b1ab104f44875b264c52e81eb", 1892759789411237919L);
+        put("3080795a07544c2c972cc938da1f", 1892759789415432223L);
+
+
+        //No3合同段数字化扫描档案
+        //二、工程管理文件
+        put("a6f86360805e494dbd048f0ade6c", 1927992893469884468L);
+
+        //三、施工质量控制文件   (一)工程质量管理文件
+        put("b3fcf7f41c8c475c951bc9dcca9d", 1927992893469884471L);
+
+        //三、施工质量控制文件 (二)工地试验室成立
+        put("fa8b6b2292df4663b7520e69acc8", 1927992893469884489L);
+
+        //三、施工质量控制文件 (四)仪器校准证书
+        put("837670159d8e46eb997c0bdc786a", 1927992893469884490L);
+
+        //三、施工质量控制文件 (五)材料及标准试验
+        put("cfdf96cdaf474f01924861db5828", 1927992893469884473L);
+
+        //三、施工质量控制文件 (六)现场抽检试验检测报告
+        put("70dda230cbca40a4b34004aa03f5", 1927992893469884491L);
+
+        //四、安全文明施工文件
+        put("a5f598023ed4402ba1859ff8d1fa", 1927992893469884499L);
+
+        //五、进度控制文件
+        put("9f3d46f37d194604925ab6bf1f30", 1927992893469884500L);
+
+        //七、变更文件
+        put("7eccf837cfb649c69086427ef9e3", 1927992893469884515L);
+        //八、施工原始记录
+        put("9706a2a21284470eb9625a0417ce", 1927992893469884502L);
+
         //试验报告
         //put("ffe1d44383ed4f438d29b73b7dbb", 1892759789415432285L);
+
+        //五 进度控制文件
+        //1 进度计划
+        //put("31bc6b0a55cb4c408e292ee0fcdb", 1892759789415432296L);
+
+        //================================【第四合同段】=======================================
+
+        //评定
+        put("ea82c02057f64424948c02a1144f", 1927992893474078726L);
+
         //施工工序资料
-        put("a22abc54ff8446e59760309263f7", 1892759789411237921L);
+        put("075d3e8a3d48418f959283c55616", 1927992893474078742L);
+
+        //No4合同段数字化扫描档案
+        //二工程管理文件
+        put("f0ed754f4068424b9f86a6450674", 1927992893474078722L);
+
+        //二、工程管理文件
+        //(一)工程质量管理文件
+        put("d6862df110b84c18b68c69c84903", 1927992893474078725L);
+
+        //(二)工地试验成立
+        put("30d615fc781244f68f19d2e7c2d3", 1927992893474078743L);
+
+        //(四)仪器校准证书
+        put("2f3bb1a2d7684fae81261f1c68be", 1927992893474078744L);
+
+        //(五)材料及标准试验
+        put("4d5b3a8cb22e422cbc9e89c85a7a", 1927992893474078727L);
+
+        //(六)现场抽检试验检测报告
+        put("d37d15a6893d4f26b7fa326cab98", 1927992893474078745L);
+
+        //四、安全文明施工文件
+        put("eecc8d374650469b87b04af099c3", 1927992893474078753L);
+        //五、进度控制文件
+        put("74a3f78dff114518b3ebd1800562", 1927992893474078754L);
+        //七、变更文件
+        put("c37db7bb196b411ca59b99fad259", 1927992893474078769L);
+        //八、施工原始记录
+        put("04f0816131814923bd4e7d2d2e20", 1927992893474078756L);
 
 
-        //=========第二合同段
         //二工程管理文件
+        //施工准备文件 -1.施工项目部组建、印章启用、人员任命文件,进场人员资质报审文件,施工设备仪器进场报审文件、设备仪器校验、率定文件
+//        put("0b0ac82851d7484bba414bb1ccbd", 1892759789415432263L);
+//
+//        //施工准备文件 -5.工地试验室备案申请表及交通质监部门备案通知书、工地实验室成立、资质、授权
+//        put("9144353d740c428ea46ca4228d22", 1892759789415432267L);
+//        //三 施工质量控制文件
+//        //原材
+//        put("54dc995fc9814ecd81f6f25dc936", 1892759789415432282L);
+//        //配合比
+//        put("5f07af9ef5d14a2781cef179ef7c", 1892759789415432284L);
+//        //试验报告
+//        put("ffe1d44383ed4f438d29b73b7dbb", 1892759789415432285L);
+//
+//        //五 进度控制文件
+//        //1 进度计划
+//        put("31bc6b0a55cb4c408e292ee0fcdb", 1892759789415432296L);
+
+
+        //============================
+
+        //======================【机电标】==============================================
 
-        //三 施工质量控制文件
-        //原材
-        put("87edcc42ba2b4859a1aec5191080", 1892759789411237978L);
+        //评定
+        put("1cb9ca589d2840cba3ce49b18494", 1927992893474078776L);
 
         //施工工序资料
-        put("4707eb84188443b481398a15e8cf", 1892759789411237982L);
+        put("8a0aa647278548fa9edba59b78c4", 1927992893474078792L);
+        //二工程管理文件
+        //施工准备文件 -1.施工项目部组建、印章启用、人员任命文件,进场人员资质报审文件,施工设备仪器进场报审文件、设备仪器校验、率定文件
+        //put("0b0ac82851d7484bba414bb1ccbd", 1892759789415432263L);
+
+        //三 施工质量控制文
+        //试验报告
+        //put("ffe1d44383ed4f438d29b73b7dbb", 1892759789415432285L);
+
 
     }};
 
@@ -310,6 +533,11 @@ public class TransUtil {
         put("relation_typestr", "关系类型");
         put("relationstr", "关系");
         put("relationstrids", "相关实体标识");
+
+        put("fill_user", "创建用户");
+        put("fill_time", "创建时间");
+        put("fill_user1", "修改用户");
+        put("fill_time1", "修改时间");
     }};
 
 

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

@@ -224,4 +224,6 @@ public interface ArchivesAutoMapper extends BaseMapper<ArchivesAuto> {
 	 * @return
 	 */
 	Map<String, BigDecimal> getAllArchiveByContractTypeSummary(@Param("projectId") Long projectId,@Param("type") String typ);
+
+	String getArchiveFileByParentId(@Param("nodeId") String nodeId,@Param("contractId") String contractId);
 }

+ 23 - 3
blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/ArchivesAutoMapper.xml

@@ -285,6 +285,22 @@
                 #{nodeId}
             </foreach>
         </if>
+        <if test="vo.queryValueSize != null and vo.queryValueSize != ''">
+            <choose>
+                <when test="vo.queryValueSize == 1">
+                    and CHAR_LENGTH(u.name) <![CDATA[ < ]]> 80
+                </when>
+                <when test="vo.queryValueSize == 2">
+                    and CHAR_LENGTH(u.name) >= 80 and CHAR_LENGTH(u.name) <![CDATA[ < ]]> 120
+                </when>
+                <when test="vo.queryValueSize == 3">
+                    and CHAR_LENGTH(u.name) >= 120 and CHAR_LENGTH(u.name) <![CDATA[ < ]]> 150
+                </when>
+                <when test="vo.queryValueSize == 4">
+                    and CHAR_LENGTH(u.name) >= 150
+                </when>
+            </choose>
+        </if>
         order by m.tree_sort,u.auto_file_sort is null ,u.auto_file_sort,u.file_number is null,
         SUBSTRING_INDEX(u.file_number, '_', 1), SUBSTRING_INDEX(u.file_number, '_', -1) + 0 ,u.create_time asc
         limit #{current}, #{size}
@@ -559,7 +575,7 @@
         select uaa.*
         from m_archive_tree_contract matc left join u_archives_auto uaa on matc.id = uaa.node_id left join
         u_archive_file uaf on uaa.id = uaf.archive_id
-        where uaa.is_deleted = 0 and uaa.is_archive = 1
+        where uaa.is_deleted = 0  and matc.is_deleted = 0 and uaa.is_archive = 1
             and matc.project_id = #{vo.projectId}
         <if test="vo.contractId != null and vo.contractId != ''">
             and uaa.contract_id = #{vo.contractId} and matc.contract_id = #{vo.contractId}
@@ -607,7 +623,7 @@
     <select id="pageByArchivesAuto11" resultMap="archivesAutoResultMap">
         select uaa.*
         from m_archive_tree_contract matc left join u_archives_auto uaa on matc.id = uaa.node_id
-        where uaa.is_deleted = 0 and uaa.is_archive = 1
+        where uaa.is_deleted = 0 and matc.is_deleted = 0 and uaa.is_archive = 1
         <if test="vo.queryValue != null and vo.queryValue != ''">
             and (uaa.name like concat('%',#{vo.queryValue},'%') or uaa.file_number like concat('%',#{vo.queryValue},'%'))
         </if>
@@ -1370,7 +1386,7 @@
     <select id="getMetadaFileByFileIds" resultType="java.util.Map">
         SELECT id,file_id
         FROM u_metadata_file
-        WHERE file_id IN
+        WHERE  is_deleted=0 and file_id IN
         <foreach collection="fileIds" item="fileId" open="(" close=")" separator=",">
             #{fileId}
         </foreach>
@@ -1396,5 +1412,9 @@
         )a
     </select>
 
+    <select id="getArchiveFileByParentId" resultType="java.lang.String">
+        SELECT b.id from m_archive_tree a ,m_archive_tree_contract b where a.id=b.from_id and a.id=#{nodeId} and contract_id=#{contractId} and a.is_deleted=0 and b.is_deleted=0
+    </select>
+
 
 </mapper>

+ 6 - 1
blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/TaskSplitMapper.java

@@ -16,6 +16,7 @@
  */
 package org.springblade.archive.mapper;
 
+import org.apache.ibatis.annotations.Param;
 import org.springblade.archive.entity.TaskSplit;
 import org.springblade.archive.vo.TaskSplitVO;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
@@ -37,7 +38,11 @@ public interface TaskSplitMapper extends BaseMapper<TaskSplit> {
 	 * @param taskSplit
 	 * @return
 	 */
-	List<TaskSplitVO> selectTaskSplitPage(IPage page, TaskSplitVO taskSplit);
+	List<TaskSplitVO> selectTaskSplitPage(IPage page,@Param("taskSplit") TaskSplitVO taskSplit);
 
+	//获取合同段下 整个文件数
 	Integer getArchiveCount(String contractId);
+
+	// 获取分解任务是否存在
+	Integer getSpliteTaskCount(String contractId);
 }

+ 6 - 1
blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/TaskSplitMapper.xml

@@ -18,15 +18,20 @@
         <result column="type" property="type"/>
         <result column="tool_count" property="toolCount"/>
         <result column="finished" property="finished"/>
+        <result column="task_name" property="taskName"/>
     </resultMap>
 
 
     <select id="selectTaskSplitPage" resultMap="taskSplitResultMap">
-        select * from u_task_split where is_deleted = 0
+        select * from u_task_split where is_deleted = 0 and contract_id = #{taskSplit.contractId}
     </select>
 
     <select id="getArchiveCount" resultType="java.lang.Integer">
         select count(1) from u_archives_auto where contract_id = #{contractId}
     </select>
 
+    <select id="getSpliteTaskCount" resultType="java.lang.Integer">
+        select count(1) from u_task_split where contract_id = #{contractId} and type=2
+    </select>
+
 </mapper>

+ 65 - 0
blade-service/blade-archive/src/main/java/org/springblade/archive/service/IArchiveNameService.java

@@ -0,0 +1,65 @@
+package org.springblade.archive.service;
+
+import org.springblade.manager.entity.ArchiveTreeContract;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+public interface IArchiveNameService {
+
+    /* 节点层级结构(通用静态类)
+     */
+    public class NodeHierarchy {
+        private final Map<Long, List<ArchiveTreeContract>> hierarchyMap;
+        private final Map<Long, ArchiveTreeContract> allNodeMap;
+        private final Map<Long, List<ArchiveTreeContract>> childrenMap; // 新增:父节点到子节点映射
+        private final Map<Long, Integer> totalChildrenCountMap; // 新增:每个父节点的子节点总数
+
+        public NodeHierarchy(
+                Map<Long, List<ArchiveTreeContract>> hierarchyMap,
+                Map<Long, ArchiveTreeContract> allNodeMap,
+                Map<Long, List<ArchiveTreeContract>> childrenMap,
+                Map<Long, Integer> totalChildrenCountMap
+        ) {
+            this.hierarchyMap = hierarchyMap;
+            this.allNodeMap = allNodeMap;
+            this.childrenMap = childrenMap;
+            this.totalChildrenCountMap = totalChildrenCountMap;
+        }
+
+        // 获取某个节点的所有直接子节点
+        public List<ArchiveTreeContract> getChildren(Long parentId) {
+            return childrenMap.getOrDefault(parentId, Collections.emptyList());
+        }
+
+        // 获取某个父节点的子节点总数
+        public int getTotalChildrenCount(Long parentId) {
+            return totalChildrenCountMap.getOrDefault(parentId, 0);
+        }
+
+        // 原始 getters...
+        public Map<Long, List<ArchiveTreeContract>> getHierarchyMap() {
+            return hierarchyMap;
+        }
+
+        public Map<Long, ArchiveTreeContract> getAllNodeMap() {
+            return allNodeMap;
+        }
+    }
+
+    /* 构建节点层级结构映射
+     */
+    NodeHierarchy buildNodeHierarchy(List<ArchiveTreeContract> nodeList);
+
+    /* 获取节点的层级名称
+     */
+    String getLevelName(NodeHierarchy hierarchy, Long nodeId);
+
+    /* 生成完整的层级名称
+     */
+    String generateFullLevelName(
+            List<Long> nodeList,
+            NodeHierarchy hierarchy
+    );
+}

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

@@ -154,4 +154,6 @@ public interface IArchivesAutoService extends BaseService<ArchivesAuto> {
 	List<List<Map<String, List<CabinetVO>>>> getUnitAllCabinet(Long projectId, Integer type);
 
     List<JiLinArchiveAutoDto> getArchiveAutoDtoList(Long projId, List<JiLinQueryDto>dtos);
+
+	R sendFileToEArchives(ArchiveDataVo dataInfo);
 }

+ 19 - 5
blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchiveAutoPdfServiceImpl.java

@@ -73,10 +73,10 @@ public class ArchiveAutoPdfServiceImpl implements IArchiveAutoPdfService {
 //        URL_MAP.put("r_Archives_spare", "https://bladex-chongqing-info.oss-cn-hangzhou.aliyuncs.com//upload/20230414/3798f8c3db6f94c8fce63eec8c716d6c.xlsx");
 //        URL_MAP.put("r_Archives_back", "https://bladex-chongqing-info.oss-cn-hangzhou.aliyuncs.com//upload/20230413/31081917b41e12b9b0359f6a9c1755bd.xlsx");
 
-        URL_MAP.put("r_Archives_front", "https://blade-oss-chongqing.oss-cn-shenzhen.aliyuncs.com//upload/20230413/306c87ffc640699aa92d53a5f4e6d632.xlsx");
-        URL_MAP.put("r_Archives_catalog", "https://blade-oss-chongqing.oss-cn-shenzhen.aliyuncs.com//upload/20230413/f2a083fca685c646e4a47daaaa46f04b.xlsx");
-        URL_MAP.put("r_Archives_spare", "https://blade-oss-chongqing.oss-cn-shenzhen.aliyuncs.com//upload/20230414/3798f8c3db6f94c8fce63eec8c716d6c.xlsx");
-        URL_MAP.put("r_Archives_back", "https://blade-oss-chongqing.oss-cn-shenzhen.aliyuncs.com//upload/20230413/31081917b41e12b9b0359f6a9c1755bd.xlsx");
+        URL_MAP.put("r_Archives_front", "https://xinan1.zos.ctyun.cn/blade-oss-chongqing/upload/20230413/306c87ffc640699aa92d53a5f4e6d632.xlsx");
+        URL_MAP.put("r_Archives_catalog", "https://xinan1.zos.ctyun.cn/blade-oss-chongqing/upload/20230413/f2a083fca685c646e4a47daaaa46f04b.xlsx");
+        URL_MAP.put("r_Archives_spare", "https://xinan1.zos.ctyun.cn/blade-oss-chongqing/upload/20230414/3798f8c3db6f94c8fce63eec8c716d6c.xlsx");
+        URL_MAP.put("r_Archives_back", "https://xinan1.zos.ctyun.cn/blade-oss-chongqing/upload/20230413/31081917b41e12b9b0359f6a9c1755bd.xlsx");
 
         NAME_MAP.put("r_Archives_front", "封面");
         NAME_MAP.put("r_Archives_catalog", "卷内目录");
@@ -551,6 +551,18 @@ public class ArchiveAutoPdfServiceImpl implements IArchiveAutoPdfService {
             }
         }
 
+        if ("Archive['secretLevel']".equals(formula)){
+            if (object!= null ) {
+                String strObject = object.toString();
+                if (strObject.contains("null")) {
+                    strObject = strObject.replace("null", "");
+                    object =  strObject;
+                }
+            }else {
+                object = "";
+            }
+        }
+
         dataInfo.put(key, object);
     }
 
@@ -626,7 +638,7 @@ public class ArchiveAutoPdfServiceImpl implements IArchiveAutoPdfService {
                     String myData = DataInfo.get(val) + "";
 
 
-                    if (myData.indexOf("http") >= 0 && (myData.indexOf("aliyuncs") >= 0 ||myData.indexOf("183.247.216.148") >= 0)) {
+                    if (myData.indexOf("http") >= 0 && (myData.indexOf("ctyun") >= 0 ||myData.indexOf("183.247.216.148") >= 0)) {
 
                         InputStream imageIn = CommonUtil.getOSSInputStream(myData);
                         byte[] bytes = IOUtils.toByteArray(imageIn);
@@ -726,6 +738,8 @@ public class ArchiveAutoPdfServiceImpl implements IArchiveAutoPdfService {
                 }
             }
 
+            file.setFileTime(FileUtils.cleanFileTime(file.getFileTime()));
+
             Map<String, Object> fileMap = new ObjectMapper().convertValue(file, Map.class);
             fileMapList.add(fileMap);
         }

+ 287 - 0
blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchiveNameServiceImpl.java

@@ -0,0 +1,287 @@
+package org.springblade.archive.service.impl;
+
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springblade.archive.service.IArchiveNameService;
+import org.springblade.manager.entity.ArchiveTreeContract;
+import org.springblade.manager.feign.ArchiveTreeContractClient;
+import org.springframework.stereotype.Service;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Service
+@AllArgsConstructor
+public class ArchiveNameServiceImpl implements IArchiveNameService {
+
+    private final ArchiveTreeContractClient archiveTreeContractClient;
+
+
+    @Override
+    public NodeHierarchy buildNodeHierarchy(List<ArchiveTreeContract> nodeList) {
+        if (nodeList == null || nodeList.isEmpty()) {
+            return new NodeHierarchy(
+                    Collections.emptyMap(),
+                    Collections.emptyMap(),
+                    Collections.emptyMap(),
+                    Collections.emptyMap()
+            );
+        }
+
+        // 1. 创建数据结构容器
+        Map<Long, List<ArchiveTreeContract>> hierarchyMap = new HashMap<>();
+        Map<Long, ArchiveTreeContract> allNodeMap = new HashMap<>();
+        Map<Long, List<ArchiveTreeContract>> childrenMap = new HashMap<>();
+        Map<Long, Integer> totalChildrenCountMap = new HashMap<>();
+
+        // 2. 处理当前节点并加入映射
+        Map<Long, ArchiveTreeContract> tempNodeMap = new HashMap<>();
+        for (ArchiveTreeContract node : nodeList) {
+            Long nodeId = node.getId();
+            tempNodeMap.put(nodeId, node);
+            allNodeMap.put(nodeId, node);
+            childrenMap.putIfAbsent(nodeId, new ArrayList<>());
+        }
+
+        // 3. 收集缺失的祖先节点ID
+        Set<Long> missingAncestorIds = new HashSet<>();
+        for (ArchiveTreeContract node : nodeList) {
+            String ancestors = node.getAncestors();
+            if (ancestors == null || ancestors.isEmpty()) continue;
+
+            Arrays.stream(ancestors.split(","))
+                    .map(String::trim)
+                    .filter(id -> !id.isEmpty())
+                    .map(Long::parseLong)
+                    .filter(ancestorId -> !tempNodeMap.containsKey(ancestorId))
+                    .forEach(missingAncestorIds::add);
+        }
+
+        // 4. 批量获取缺失的祖先节点
+        List<ArchiveTreeContract> missingAncestors = Collections.emptyList();
+        if (!missingAncestorIds.isEmpty()) {
+            String ancestorIdsStr = missingAncestorIds.stream()
+                    .map(String::valueOf)
+                    .collect(Collectors.joining(","));
+
+            missingAncestors = archiveTreeContractClient
+                    .getArchiveTreeContractListByIds(ancestorIdsStr);
+
+            for (ArchiveTreeContract ancestor : missingAncestors) {
+                Long ancestorId = ancestor.getId();
+                tempNodeMap.put(ancestorId, ancestor);
+                allNodeMap.put(ancestorId, ancestor);
+                childrenMap.putIfAbsent(ancestorId, new ArrayList<>());
+            }
+
+            log.debug("成功获取 {} 个祖先节点", missingAncestors.size());
+        }
+
+        // 5. 合并所有节点
+        List<ArchiveTreeContract> allNodes = new ArrayList<>(nodeList);
+        allNodes.addAll(missingAncestors);
+
+        // 6. 为每个节点构建完整的层级路径
+        for (ArchiveTreeContract node : allNodes) {
+            Long nodeId = node.getId();
+            List<ArchiveTreeContract> hierarchyList = new ArrayList<>();
+
+            // 处理祖先路径
+            String ancestors = node.getAncestors();
+            if (ancestors != null && !ancestors.isEmpty()) {
+                String[] pathIds = ancestors.split(",");
+                for (String idStr : pathIds) {
+                    idStr = idStr.trim();
+                    if (!idStr.isEmpty()) {
+                        Long id = Long.parseLong(idStr);
+                        ArchiveTreeContract ancestor = tempNodeMap.get(id);
+                        if (ancestor != null) {
+                            hierarchyList.add(ancestor);
+                        }
+                    }
+                }
+            }
+
+            // 添加当前节点到路径末端
+            hierarchyList.add(node);
+
+            // 存入层级映射
+            hierarchyMap.put(nodeId, hierarchyList);
+
+            // 构建父子关系映射
+            Long parentId = node.getParentId();
+            if (parentId != null) {
+                childrenMap.computeIfAbsent(parentId, k -> new ArrayList<>()).add(node);
+            }
+        }
+
+        // 7. 填充总子节点计数
+        for (Map.Entry<Long, List<ArchiveTreeContract>> entry : childrenMap.entrySet()) {
+            totalChildrenCountMap.put(entry.getKey(), entry.getValue().size());
+        }
+
+        return new NodeHierarchy(hierarchyMap, allNodeMap, childrenMap, totalChildrenCountMap);
+    }
+
+    @Override
+    public String getLevelName(NodeHierarchy hierarchy, Long nodeId) {
+        Map<Long, ArchiveTreeContract> allNodeMap = hierarchy.getAllNodeMap();
+
+        // 1. 获取目标节点
+        ArchiveTreeContract targetNode = allNodeMap.get(nodeId);
+        if (targetNode == null) {
+            log.warn("无法找到节点 {} 的详细信息", nodeId);
+            return "未知节点";
+        }
+
+        // 2. 获取节点的层级路径
+        Map<Long, List<ArchiveTreeContract>> hierarchyMap = hierarchy.getHierarchyMap();
+        List<ArchiveTreeContract> hierarchyList = hierarchyMap.getOrDefault(
+                nodeId, Collections.emptyList()
+        );
+
+        // 3. 提取关键层级的节点
+        ArchiveTreeContract lastUnitNode = null;
+        ArchiveTreeContract lastDivisionNode = null;
+        ArchiveTreeContract lastItemNode = null;
+
+        for (ArchiveTreeContract node : hierarchyList) {
+            // 获取displayHierarchy值
+            Integer extNodeType = node.getExtNodeType();
+
+            // 处理空值或空白值
+            if (extNodeType == null ) {
+                continue;
+            }
+
+            try {
+                // 尝试转换为
+
+                switch (extNodeType) {
+                    case 1:
+                        lastUnitNode = node;
+                        break;
+                    case 2:
+                    case 3:
+                        lastDivisionNode = node;
+                        break;
+                    case 4:
+                    case 5:
+                        lastItemNode = node;
+                        break;
+                    // 其他情况不处理
+                }
+            } catch (NumberFormatException e) {
+                // 记录格式错误但继续处理其他节点
+                log.warn("节点 {} 的displayHierarchy值 '{}' 无法转换为整数",
+                        node.getNodeName(), extNodeType);
+            }
+        }
+
+        // 4. 构建层级名称
+        StringBuilder nameBuilder = new StringBuilder();
+
+        // 依次添加单位工程、分部工程、分项工程的名称
+        if (lastUnitNode != null) {
+            nameBuilder.append(lastUnitNode.getNodeName());
+        }
+        if (lastDivisionNode != null) {
+            nameBuilder.append(lastDivisionNode.getNodeName());
+        }
+        if (lastItemNode != null) {
+            nameBuilder.append(lastItemNode.getNodeName());
+        }
+
+        // 5. 返回结果(如果没有找到任何层级节点,则返回目标节点名称)
+        return nameBuilder.length() > 0 ?
+                nameBuilder.toString() :
+                targetNode.getNodeName();
+    }
+
+
+    @Override
+    public String generateFullLevelName(
+            List<Long> nodeIds,
+            NodeHierarchy hierarchy
+    ) {
+        // 1. 获取输入节点
+        Map<Long, ArchiveTreeContract> allNodeMap = hierarchy.getAllNodeMap();
+        List<ArchiveTreeContract> nodes = new ArrayList<>();
+
+        for (Long nodeId : nodeIds) {
+            ArchiveTreeContract node = allNodeMap.get(nodeId);
+            if (node != null) {
+                nodes.add(node);
+            }
+        }
+
+        if (nodes.isEmpty()) {
+            return "";
+        }
+
+        // 2. 按父节点分组
+        Map<Long, List<ArchiveTreeContract>> parentGroups = new LinkedHashMap<>();
+
+        for (ArchiveTreeContract node : nodes) {
+            Long parentId = node.getParentId();
+
+            // 如果没有父节点,单独处理
+            if (parentId == null) {
+                parentGroups.put(node.getId(), Collections.singletonList(node));
+            } else {
+                parentGroups.computeIfAbsent(parentId, k -> new ArrayList<>()).add(node);
+            }
+        }
+
+        // 3. 构建结果部分
+        List<String> nameParts = new ArrayList<>();
+
+        for (Map.Entry<Long, List<ArchiveTreeContract>> entry : parentGroups.entrySet()) {
+            Long groupId = entry.getKey();
+            List<ArchiveTreeContract> groupNodes = entry.getValue();
+
+            // 处理没有父节点的情况
+            if (groupId == null) {
+                groupId = groupNodes.get(0).getId();
+            }
+
+            // 获取父节点(组代表)
+            ArchiveTreeContract parent = allNodeMap.get(groupId);
+
+            // 父节点不存在(特殊情况处理)
+            if (parent == null) {
+                // 可能是没有父节点的单独节点
+                for (ArchiveTreeContract node : groupNodes) {
+                    nameParts.add(node.getNodeName());
+                }
+                continue;
+            }
+
+            // 获取父节点层级名称
+            String parentLevelName = getLevelName(hierarchy, parent.getId());
+
+            // 获取该父节点下的所有子节点(在hierarchy中)
+            List<ArchiveTreeContract> allChildren = hierarchy.getChildren(parent.getId());
+
+            // 获取该父节点下的所有子节点数量
+            int totalChildrenCount = hierarchy.getTotalChildrenCount(parent.getId());
+
+            // 判断是否涵盖所有子节点
+            if (groupNodes.size() == totalChildrenCount && !allChildren.isEmpty()) {
+                // 涵盖所有子节点,直接使用父节点层级名称
+                nameParts.add(parentLevelName);
+            } else {
+                // 部分子节点,添加节点名称
+                StringBuilder groupName = new StringBuilder(parentLevelName);
+                for (ArchiveTreeContract node : groupNodes) {
+                    groupName.append(node.getNodeName());
+                }
+                nameParts.add(groupName.toString());
+            }
+        }
+
+        // 4. 拼接最终结果
+        return String.join("、", nameParts);
+    }
+}

+ 440 - 16
blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchivesAutoServiceImpl.java

@@ -76,6 +76,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
 import org.springframework.web.multipart.MultipartFile;
 
 import javax.servlet.http.HttpServletResponse;
@@ -89,6 +90,7 @@ import java.time.LocalDateTime;
 import java.util.*;
 import java.util.List;
 import java.util.concurrent.ExecutorService;
+import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
 
 /**
@@ -729,6 +731,8 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 		//步list = {ArrayList@18238}  size = 19骤二:查询归档树节点。存在未归档文件的节点。
 		List<ArchiveTreeContract> list = archiveTreeContractClient.getHavedFileNodeByProjectID(projectId);
 
+		List<ArchiveTreeContract> listTop = archiveTreeContractClient.getTopAutoTypeNodeByProjectID(projectId);
+
 
 		if (nodeId != null) {
 			ArchiveTreeContract node = archiveTreeContractClient.getArchiveTreeContractById(nodeId);
@@ -772,7 +776,7 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 		archiveAutoMethod3(list3, boxMap, boxFileMap, traceId);//单独组卷
 		//设置完成度30%
 		projectClient.updateIsArchivesAutoById(projectId, 30);
-		archiveAutoMethod2(list2, projectId, boxMap, boxFileMap, traceId);//分类组卷
+		archiveAutoMethod2_new(list2, listTop,projectId, boxMap, boxFileMap, traceId);//分类组卷
 		//设置完成度50%
 		projectClient.updateIsArchivesAutoById(projectId, 50);
 		archiveAutoMethod1(list1, boxMap, boxFileMap, traceId);//默认组卷
@@ -1256,9 +1260,10 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 		}
 		archiveFileClient.updateArchiveFileForCreateArchive(waitArchiveFiles);
 		try {
-			for (ArchiveFile saveVo : waitArchiveFiles) {
-				metadataClassificationClient.createMetadataFile(saveVo.getId(), 0);
-			}
+//			for (ArchiveFile saveVo : waitArchiveFiles) {
+//				metadataClassificationClient.createMetadataFile(saveVo.getId(), 0);
+//			}
+			batchCreateMetadataFiles(waitArchiveFiles);
 		} catch (Exception e) {
 			e.printStackTrace();
 		}
@@ -1278,7 +1283,23 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 		if (selectList== null || selectList.size() == 0) {
 			return;
 		}
+
+		if (waitArchiveFiles==null || waitArchiveFiles.size()== 0) {
+			return;
+		}
+
+		String strfirstNodeId = waitArchiveFiles.get(0).getNodeId();
+
 		ArchiveTreeContract node = selectList.get(0);
+		if (StringUtils.isNotEmpty(strfirstNodeId)) {
+			Long firstNodeId = Long.parseLong(strfirstNodeId);
+			ArchiveTreeContract firstNode = archiveTreeContractClient.getArchiveTreeContractById(firstNodeId);
+			if (firstNode!= null) {
+				node = firstNode;
+			}
+		}
+
+
 		//获取案卷文件起止时间
 		String archiveStartDateAndEndDate = getArchiveStartDateAndEndDate(waitArchiveFiles);
 		String[] split = archiveStartDateAndEndDate.split(",");
@@ -1314,9 +1335,7 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 		}
 		archiveFileClient.updateArchiveFileForCreateArchive(waitArchiveFiles);
 		try {
-			for (ArchiveFile saveVo : waitArchiveFiles) {
-				metadataClassificationClient.createMetadataFile(saveVo.getId(), 0);
-			}
+			batchCreateMetadataFiles(waitArchiveFiles);
 		} catch (Exception e) {
 			e.printStackTrace();
 		}
@@ -1363,9 +1382,10 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 		}
 		archiveFileClient.updateArchiveFileForCreateArchive(waitArchiveFiles);
 		try {
-			for (ArchiveFile saveVo : waitArchiveFiles) {
-				metadataClassificationClient.createMetadataFile(saveVo.getId(), 0);
-			}
+//			for (ArchiveFile saveVo : waitArchiveFiles) {
+//				metadataClassificationClient.createMetadataFile(saveVo.getId(), 0);
+//			}
+			batchCreateMetadataFiles(waitArchiveFiles);
 		} catch (Exception e) {
 			e.printStackTrace();
 		}
@@ -1418,9 +1438,10 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 		}
 		archiveFileClient.updateArchiveFileForCreateArchive(waitArchiveFiles);
 		try {
-			for (ArchiveFile saveVo : waitArchiveFiles) {
-				metadataClassificationClient.createMetadataFile(saveVo.getId(), 0);
-			}
+//			for (ArchiveFile saveVo : waitArchiveFiles) {
+//				metadataClassificationClient.createMetadataFile(saveVo.getId(), 0);
+//			}
+			batchCreateMetadataFiles(waitArchiveFiles);
 		} catch (Exception e) {
 			e.printStackTrace();
 		}
@@ -1523,13 +1544,117 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 		}
 	}
 
+	private void archiveAutoMethod3(List<ArchiveTreeContract> list, Map<String, List<ArchiveFile>> boxMap,
+									Map<Long, String> boxFileMap, Long traceId) {
+		// 步骤1:遍历节点集合
+		for (ArchiveTreeContract node : list) {
+			// 步骤2:获取当前节点的案卷规格
+			String specificationStr = node.getSpecification();
+			if (StringUtils.isEmpty(specificationStr)) {
+				specificationStr = "30";
+			}
+			int specification = Integer.parseInt(specificationStr);
+			int specificationSize = specification * 10;
+
+			// 步骤3:查询节点下的未组卷文件
+			List<ArchiveFile> archiveFiles = archiveFileClient.getListByNodeID(node.getId().toString());
+			if (archiveFiles == null || archiveFiles.isEmpty()) {
+				continue;
+			}
+
+			// 记录节点文件数量日志
+			String completeMsg = "[自动组卷] 单独组卷:" + "-traceId:" + traceId + "节点:" + node.getNodeName() + " 文件数量:" + archiveFiles.size();
+			iTraceLogService.saveLog(traceId, completeMsg);
+
+			// 步骤4:遍历未归档文件
+			List<ArchiveFile> waitArchiveFiles = new ArrayList<>();  // 待组卷文件集合
+			int archivesSize = 0;  // 待组卷文件总页数
+			int archiveFilesSize = 0;
+
+			for (ArchiveFile file : archiveFiles) {
+				archiveFilesSize++;
+
+				// 步骤5:判断文件是否存在分盒设置
+				if (file.getBoxNumber() != null && file.getBoxNumber() != -1) {
+					// 添加到分盒文件集合
+					addBoxMap(file, boxMap, boxFileMap);
+
+					// 如果是最后一个文件且有待组卷文件,则组卷
+					if (archiveFilesSize == archiveFiles.size() && !waitArchiveFiles.isEmpty()) {
+						createArchive3(waitArchiveFiles, node, archivesSize);
+						waitArchiveFiles.clear();
+						archivesSize = 0;
+					}
+				} else {
+					// 非分盒文件处理
+					Integer filePage = file.getFilePage() != null ? file.getFilePage() : 0;
+
+					// 步骤6:检查规格状态
+					int tempTotalSize = archivesSize + filePage;
+					int checkStatus = checkSpecificationSize(specificationSize, tempTotalSize);
+
+					// 6.1 未到规格
+					if (checkStatus == 0) {
+						waitArchiveFiles.add(file);
+						archivesSize = tempTotalSize;
+
+						// 最后一个文件直接组卷
+						if (archiveFilesSize == archiveFiles.size()) {
+							createArchive3(waitArchiveFiles, node, archivesSize);
+							waitArchiveFiles.clear();
+							archivesSize = 0;
+						}
+					}
+					// 6.2 达到规格
+					else if (checkStatus == 1) {
+						waitArchiveFiles.add(file);
+						archivesSize = tempTotalSize;
+						createArchive3(waitArchiveFiles, node, archivesSize);
+
+						// 重置待组卷集合
+						waitArchiveFiles.clear();
+						archivesSize = 0;
+					}
+					// 6.3 超出规格
+					else if (checkStatus == -1) {
+						if (!waitArchiveFiles.isEmpty()) {
+							// 先将现有集合组卷(不含当前文件)
+							createArchive3(waitArchiveFiles, node, archivesSize);
+
+							// 新建集合存放当前文件
+							waitArchiveFiles.clear();
+							waitArchiveFiles.add(file);
+							archivesSize = filePage;
+
+							// 最后一个文件直接组卷
+							if (archiveFilesSize == archiveFiles.size()) {
+								createArchive3(waitArchiveFiles, node, archivesSize);
+								waitArchiveFiles.clear();
+								archivesSize = 0;
+							}
+						} else {
+							// 当前文件单独成卷
+							waitArchiveFiles.add(file);
+							archivesSize = filePage;
+							createArchive3(waitArchiveFiles, node, archivesSize);
+
+							// 重置集合
+							waitArchiveFiles.clear();
+							archivesSize = 0;
+						}
+					}
+				}
+			}
+		}
+	}
+
 	/**
-	 * 单租组卷流程  20230628 SBD又说单独组卷规则节点下只组一卷,不用满规格新组。这辈子没见过这样的人。
+	 * 单租组卷流程  20230628 SBD又说单独组卷规则节点下只组一卷,不用满规格新组。
 	 *
 	 * @param list
 	 * @param boxMap
 	 */
-	private void archiveAutoMethod3(List<ArchiveTreeContract> list, Map<String, List<ArchiveFile>> boxMap, Map<Long, String> boxFileMap, Long traceId) {
+	private void archiveAutoMethod3_1(List<ArchiveTreeContract> list, Map<String, List<ArchiveFile>> boxMap, Map<Long, String> boxFileMap, Long traceId) {
 		//步骤1:遍历节点集合
 		for (ArchiveTreeContract node : list) {
 			//步骤2:查询节点下的未组卷文件
@@ -1623,11 +1748,177 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 			Long archiveAutoGroupId = entry.getKey();
 			List<ArchiveFile> archiveFiles = entry.getValue();
 			//一个archiveAutoGroupId组成一个案卷  案卷归属同个key的归档树节点select=1的第一个groupId2NodeIdMap
-			createArchive2(archiveFiles, archiveAutoGroupId, projectId);
+			//createArchive2(archiveFiles, archiveAutoGroupId, projectId);
+
+			archiveAutoMethodGroup(archiveFiles, archiveAutoGroupId, projectId);
+		}
+
+	}
+
+
+	private void archiveAutoMethod2_new(List<ArchiveTreeContract> list, List<ArchiveTreeContract> topList, Long projectId,
+										Map<String, List<ArchiveFile>> boxMap, Map<Long, String> boxFileMap, Long traceId) {
+
+		// 分类并卷集合<groupId, List<文件>>
+		Map<Long, List<ArchiveFile>> archiveMap = new LinkedHashMap<>();
+		// 记录同个分组id对应的第一个节点ID(案卷归属节点)
+		Map<Long, Long> groupId2NodeIdMap = new HashMap<>();
+
+		// 当前处理的顶层节点ID
+		Long curTopId = null;
+		// 当前顶层节点对应的分组ID
+		Long currArchiveAutoGroupId = null;
+
+		// 步骤1:遍历节点集合
+		for (ArchiveTreeContract node : list) {
+			// 初始化当前节点的分组ID和顶层节点ID
+			Long archiveAutoGroupId = node.getArchiveAutoGroupId();
+			Long nodeTopId = 0L;
+
+			// 步骤2:查找当前节点的顶层节点ID
+			for (ArchiveTreeContract topNode : topList) {
+				Long topId = topNode.getId();
+				// 检查当前节点是否属于此顶层节点
+				if (node.getAncestors() != null &&
+						node.getAncestors().contains(topId.toString())) {
+					nodeTopId = topId;
+					break;
+				}
+			}
+
+			// 步骤3:确定当前节点的分组ID
+			if (curTopId != null && curTopId.equals(nodeTopId) && nodeTopId != 0) {
+				// 如果属于同一个非零顶层节点,使用之前的分组ID
+				archiveAutoGroupId = currArchiveAutoGroupId;
+			} else {
+				// 新顶层节点或没有顶层节点,更新当前分组信息
+				curTopId = nodeTopId;
+				currArchiveAutoGroupId = archiveAutoGroupId;
+			}
+
+			// 步骤4:查询节点下的未归档文件
+			List<ArchiveFile> archiveFiles = archiveFileClient.getListByNodeID(node.getId().toString());
+
+			if (archiveFiles != null && !archiveFiles.isEmpty()) {
+				// 记录日志(每个节点只记录一次)
+				String completeMsg = "[自动组卷] 分类组卷:" + "-traceId:" + traceId + "节点:" + node.getNodeName() + " 文件数量:" + archiveFiles.size();
+				iTraceLogService.saveLog(traceId, completeMsg);
+
+				// 步骤5:遍历未归档文件
+				for (ArchiveFile file : archiveFiles) {
+					// 步骤6:判断文件是否存在分盒设置
+					if (file.getBoxNumber() != null && file.getBoxNumber() != -1) {
+						// 添加到分盒文件集合
+						addBoxMap(file, boxMap, boxFileMap);
+					} else {
+						// 分类并卷流程
+						// 步骤7:将文件按照<groupId,List<文件>>放入集合
+						if (archiveMap.containsKey(archiveAutoGroupId)) {
+							List<ArchiveFile> groupList = archiveMap.get(archiveAutoGroupId);
+							groupList.add(file);
+						} else {
+							List<ArchiveFile> groupList = new ArrayList<>();
+							groupList.add(file);
+							archiveMap.put(archiveAutoGroupId, groupList);
+							groupId2NodeIdMap.put(archiveAutoGroupId, node.getId());
+						}
+					}
+				}
+			}
 		}
 
+		// 步骤8:按集合创建案卷
+		for (Map.Entry<Long, List<ArchiveFile>> entry : archiveMap.entrySet()) {
+			Long archiveAutoGroupId = entry.getKey();
+			List<ArchiveFile> archiveFiles = entry.getValue();
+
+			// 同一个分组ID下的文件分组组卷
+			archiveAutoMethodGroup(archiveFiles, archiveAutoGroupId, projectId);
+		}
 	}
 
+	private void archiveAutoMethodGroup(List<ArchiveFile> archiveFiles, Long archiveAutoGroupId, Long projectId) {
+		if (archiveFiles.size()==0) {
+			return;
+		}
+
+		// 获取分组规格(取第一个文件的节点规格作为分组规格)
+		int specificationSize = 300; // 默认规格(300页)
+		if (archiveFiles.get(0).getNodeId() != null) {
+			// 查询文件所在节点的规格
+			Long nodeId = Long.parseLong(archiveFiles.get(0).getNodeId());
+			ArchiveTreeContract node = archiveTreeContractClient.getArchiveTreeContractById(nodeId);
+			//ArchiveTreeContract node = archiveTreeClient.getNodeById(archiveFiles.get(0).getNodeId());
+			if (node != null && !StringUtils.isEmpty(node.getSpecification())) {
+				try {
+					specificationSize = Integer.parseInt(node.getSpecification()) * 10;
+				} catch (NumberFormatException e) {
+					// 规格格式错误时使用默认值
+					log.error("规格格式错误: {}", node.getSpecification(), e);
+				}
+			}
+		}
+
+		// 待组卷文件集合
+		List<ArchiveFile> waitArchiveFiles = new ArrayList<>();
+		// 待组卷文件总页数
+		int archivesSize = 0;
+
+		// 遍历文件列表
+		int fileIndex = 0;
+		int totalFiles = archiveFiles.size();
+
+		for (ArchiveFile file : archiveFiles) {
+			fileIndex++;
+			// 获取文件页数,处理null值
+			int filePage = file.getFilePage() != null ? file.getFilePage() : 0;
+
+			// 计算临时总页数
+			int tempTotalSize = archivesSize + filePage;
+
+			// 检查规格状态
+			int checkStatus = checkSpecificationSize(specificationSize, tempTotalSize);
+
+			// 处理不同检查状态
+			switch (checkStatus) {
+				case 0: // 未到规格
+					waitArchiveFiles.add(file);
+					archivesSize = tempTotalSize;
+					if (fileIndex == totalFiles) { // 是最后一个文件
+						createArchive2(waitArchiveFiles, archiveAutoGroupId, projectId);
+					}
+					break;
+
+				case 1: // 达到规格
+					waitArchiveFiles.add(file);
+					createArchive2(waitArchiveFiles, archiveAutoGroupId, projectId);
+					waitArchiveFiles = new ArrayList<>();
+					archivesSize = 0;
+					break;
+
+				case -1: // 超出规格
+					if (waitArchiveFiles.isEmpty()) {
+						// 当前文件单独成卷
+						createArchive2(Collections.singletonList(file), archiveAutoGroupId, projectId);
+					} else {
+						// 先将现有文件组卷
+						createArchive2(waitArchiveFiles, archiveAutoGroupId, projectId);
+
+						// 创建新的待组卷集合
+						waitArchiveFiles = new ArrayList<>();
+						waitArchiveFiles.add(file);
+						archivesSize = filePage;
+
+						if (fileIndex == totalFiles) { // 是最后一个文件
+							createArchive2(waitArchiveFiles, archiveAutoGroupId, projectId);
+						}
+					}
+					break;
+			}
+		}
+	}
+
+
 	/**
 	 * 默认组卷流程 文件可以跨节点组卷,受最高并卷节点限制范围,跨节点文件组卷时,案卷规格按照第一个文件所在的节点规格 组卷。
 	 */
@@ -2414,7 +2705,44 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 	 * @param nodeId               筛选条件:节点编号
 	 * @return 符合条件的档案列表
 	 */
+
 	public List<ArchiveTreeContract> archiveTreeContractFilterNum(List<ArchiveTreeContract> archiveTreeContracts, String treeCode, String nodeId, Long contractId) {
+		if (contractId == null) {
+			return archiveTreeContracts;
+		}
+
+		List<ArchiveTreeContract> result = new ArrayList<>();
+		for (ArchiveTreeContract contract : archiveTreeContracts) {
+			// 核心逻辑:nodeId不为空时必须满足祖先/ID条件
+			if (StringUtils.isNotEmpty(nodeId)) {
+				boolean matchesNode = (StringUtils.isNotEmpty(contract.getAncestors()) && contract.getAncestors().contains(nodeId))
+						|| contract.getId().toString().equals(nodeId);
+				if (!matchesNode) {
+					continue; // 不满足node条件直接跳过
+				}
+			}
+
+			// 根据treeCode决定额外条件
+			boolean isOwnerContract = StringUtils.isEmpty(treeCode); // 业主合同段标识
+			boolean passesOwnerCheck = contractId.toString().equals(contract.getTreeCode())
+					|| contractId.equals(contract.getContractId())
+					|| StringUtils.isEmpty(contract.getTreeCode());
+
+			if (isOwnerContract) {
+				// 业主合同段:仅需额外检查(nodeId为空时)
+				if (passesOwnerCheck) {
+					result.add(contract);
+				}
+			} else {
+				// 非业主合同段:treeCode匹配或额外检查
+				if (treeCode.equals(contract.getTreeCode()) || passesOwnerCheck) {
+					result.add(contract);
+				}
+			}
+		}
+		return result;
+	}
+	public List<ArchiveTreeContract> archiveTreeContractFilterNum1(List<ArchiveTreeContract> archiveTreeContracts, String treeCode, String nodeId, Long contractId) {
 		List<ArchiveTreeContract> result = new ArrayList<>();
 
 		if (contractId == null) {
@@ -3734,5 +4062,101 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 		process.waitFor();
 	}
 
+	/**
+	 * 批量更新
+	 * @param waitArchiveFiles
+	 */
+	public void batchCreateMetadataFiles(List<ArchiveFile> waitArchiveFiles) {
+		if (CollectionUtils.isEmpty(waitArchiveFiles)) {
+			return;
+		}
+
+		// 提取所有文件ID
+		List<Long> fileIds = waitArchiveFiles.stream()
+				.map(ArchiveFile::getId)
+				.collect(Collectors.toList());
+
+		long startTime = System.currentTimeMillis();
+		log.info("[自动组卷-更新元数据前]{}", "");
+
+		// 直接调用批量创建接口
+		boolean success = metadataClassificationClient.createMetadataFiles(fileIds);
+		long endTime = System.currentTimeMillis();
+
+		log.info("[自动组卷-更新元数据后], 耗时: {} 毫秒", endTime-startTime);
+
+	}
+
+
+	private String formatExecutionTime(long millis) {
+		if (millis < 1000) {
+			return millis + "毫秒";
+		} else if (millis < 60000) {
+			return String.format("%.2f秒", millis / 1000.0);
+		} else {
+			long minutes = TimeUnit.MILLISECONDS.toMinutes(millis);
+			long seconds = TimeUnit.MILLISECONDS.toSeconds(millis) % 60;
+			return minutes + "分钟" + seconds + "秒";
+		}
+	}
+
+
+	@Override
+	public R sendFileToEArchives(ArchiveDataVo dataInfo) {
+
+		if(dataInfo==null || Func.isNull(dataInfo)){
+			return R.fail("请根据接口文档上传参数");
+		}
+
+		String nodeId = dataInfo.getNodeId();
+		String contractId = dataInfo.getContractId();
+		String fileUrl = dataInfo.getFileUrl();
+		String fileName = dataInfo.getFileNmae();
+		if(nodeId==null || Func.isNull(nodeId)){
+			return R.fail("请上传nodeId");
+		}
+		if(contractId==null || Func.isNull(contractId)){
+			R.fail("请上传contractId");
+		}
+		if(fileUrl==null || Func.isNull(fileUrl)){
+			R.fail("请上传fileUrl");
+		}
+
+
+		if(fileName==null || Func.isNull(fileName)){
+			R.fail("请上传fileName");
+		}
+
+		ContractInfo contractInfo = contractClient.getContractById(Func.toLong(contractId));
+		if(contractInfo==null){
+			return R.fail("请传输正确的contractId");
+		}
+		//获取文件的父节点Id
+		String treeContractId = baseMapper.getArchiveFileByParentId(nodeId, contractId);
+		if(treeContractId==null || Func.isNull(treeContractId)){
+			R.fail("请校验传输的nodeId和contractId,没有查到父节点Id");
+		}
+
+
+
+		// 将数据插入到 auto表中
+		ArchivesAuto archivesAuto = new ArchivesAuto();
+		long newPkId = SnowFlakeUtil.getId(); //主键Id
+		archivesAuto.setId(newPkId);
+		archivesAuto.setProjectId(Func.toLong(contractInfo.getPId()));
+		archivesAuto.setContractId(Func.toLong(contractId));
+		archivesAuto.setName(fileName);
+		archivesAuto.setIsDeleted(0);
+		this.save(archivesAuto);
+
+		// 保存文件到archive_file表中
+		long arueId = SnowFlakeUtil.getId(); //主键Id
+		ArchiveFile archiveFile = new ArchiveFile();
+		archiveFile.setId(arueId);
+		archiveFile.setArchiveId(newPkId);
+		archiveFile.setFileName(fileName);
+		archiveFileClient.saveArchiveFileByBIM(archiveFile);
+		return R.success("保存成功");
+	}
 
 }

+ 30 - 1
blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/TaskSplitServiceImpl.java

@@ -24,11 +24,17 @@ import org.springblade.archive.service.ITaskSplitService;
 import org.springblade.core.mp.base.BaseService;
 import org.springblade.core.mp.base.BaseServiceImpl;
 import org.springblade.core.tool.api.R;
+import org.springblade.core.tool.utils.DateUtil;
 import org.springblade.core.tool.utils.Func;
 import org.springframework.stereotype.Service;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 
 import javax.annotation.Resource;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Random;
 
 /**
  * 解析主标任务 服务实现类
@@ -51,6 +57,7 @@ public class TaskSplitServiceImpl extends BaseServiceImpl<TaskSplitMapper, TaskS
 	@Override
 	public R saveTaskSplit(TaskSplit taskSplit) {
 		// 数据校验区
+		Map<String,Object> data = new HashMap<>();
 		String contractId = taskSplit.getContractId();
 		String splitIds = taskSplit.getIds();
 		if (contractId=="" || contractId==null || contractId.length()==0 || Func.isEmpty(contractId)){
@@ -60,19 +67,41 @@ public class TaskSplitServiceImpl extends BaseServiceImpl<TaskSplitMapper, TaskS
 		if (splitIds=="" || splitIds==null || splitIds.length()==0 || Func.isEmpty(splitIds)){ // 代表整个合同解析
 			taskSplit.setType(2);
 			// 查询整个合同段下的所有文件
+			Integer spliteTaskCount =baseMapper.getSpliteTaskCount(contractId);
+			if(spliteTaskCount>=1){
+				return R.fail("该合同已经添加任务,无需重复操作");
+			}
+
+			Random random = new Random();
+			int randomNumber = random.nextInt(11) + 10; // 生成10到20之间的随机数
+			int i = (int) Math.ceil(randomNumber * spliteTaskCount/60.0 );
+
 			Integer archiveCount = baseMapper.getArchiveCount(contractId);
 			taskSplit.setToolCount(archiveCount);
 			taskSplit.setFinished(0);
 
+			taskSplit.setTaskName("整个合同段 "+archiveCount+" 条的分解任务");
+			data.put("fileCount",archiveCount);
+			data.put("taskTime",i);
 		}else{ // 指定文件解析
 			taskSplit.setType(3);
 			String[] split = splitIds.split(",");
 			taskSplit.setToolCount(split.length);
 			taskSplit.setFinished(0);
+
+			Random random = new Random();
+			int randomNumber = random.nextInt(11) + 10; // 生成10到20之间的随机数
+			int i = (int) Math.ceil(randomNumber * split.length/60.0 );
+			data.put("fileCount",split.length);
+			data.put("taskTime",i);
+			LocalDateTime now = LocalDateTime.now();
+			DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd HH:mm:ss");
+			String formattedDateTime = now.format(formatter)+"_"+split.length+"条分解任务";
+			taskSplit.setTaskName(formattedDateTime);
 		}
 
 		int insert = baseMapper.insert(taskSplit);
-		return R.success("dddd");
+		return R.data(200,data,"操作成功");
 	}
 
 }

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

@@ -59,7 +59,7 @@ public class TraceLogServiceImpl extends BaseServiceImpl<TraceLogMapper, TraceLo
             TraceLog traceLog = new TraceLog();
             traceLog.setTraceId(traceId);
             traceLog.setContent(content);
-            save(traceLog);
+            //save(traceLog);
 
         } catch (Exception e) {
             // 异常处理逻辑,比如打印日志

+ 9 - 3
blade-service/blade-archive/src/main/java/org/springblade/archive/utils/FileUtils.java

@@ -293,7 +293,7 @@ public class FileUtils {
 
             for (String urlStr : urlList) {
                 try {
-                    if (urlStr.indexOf("https") >= 0 && urlStr.indexOf("aliyuncs") >= 0) {
+                    if (urlStr.indexOf("https") >= 0 && urlStr.indexOf("ctyun") >= 0) {
                         int lastIndexOf = urlStr.lastIndexOf("/");
                         String prefix = urlStr.substring(0, lastIndexOf + 1);
                         String suffix = urlStr.substring(lastIndexOf + 1);
@@ -516,7 +516,7 @@ public class FileUtils {
 
                     String fileNameWithoutExtension = fileNameWithExtension.substring(0, fileNameWithExtension.lastIndexOf("."));
 
-                    if (url.indexOf("https") >= 0 && url.indexOf("aliyuncs") >= 0) {
+                    if (url.indexOf("https") >= 0 && url.indexOf("ctyun") >= 0) {
                         int lastIndexOf = url.lastIndexOf("/");
                         String prefix = url.substring(0, lastIndexOf + 1);
                         String suffix = url.substring(lastIndexOf + 1);
@@ -661,7 +661,7 @@ public class FileUtils {
 
                     String fileNameWithoutExtension = fileNameWithExtension.substring(0, fileNameWithExtension.lastIndexOf("."));
 
-                    if (url.indexOf("https") >= 0 && url.indexOf("aliyuncs") >= 0) {
+                    if (url.indexOf("https") >= 0 && url.indexOf("ctyun") >= 0) {
                         int lastIndexOf = url.lastIndexOf("/");
                         String prefix = url.substring(0, lastIndexOf + 1);
                         String suffix = url.substring(lastIndexOf + 1);
@@ -832,4 +832,10 @@ public class FileUtils {
         return os.toByteArray();
     }
 
+    public static String cleanFileTime(String fileTime) {
+        if (fileTime == null) return "";
+        String cleaned = fileTime.replace(".", "").replace("-", "");
+        return cleaned.length() > 8 ? cleaned.substring(0, 8) : cleaned;
+    }
+
 }

+ 12 - 9
blade-service/blade-business/src/main/java/org/springblade/business/controller/InformationWriteQueryController.java

@@ -215,17 +215,20 @@ public class InformationWriteQueryController extends BladeController {
                 String sql="select * from m_wbs_tree_contract where p_key_id="+query.getWbsId()+" and is_deleted=0";
                 WbsTreeContract contract = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<>(WbsTreeContract.class));
                   String result=wbsParamClient.createFileTitle(contract);
-                if(query.getClassify()!=null&&query.getClassify()==1&&StringUtils.isNotEmpty(sgSuffix)){
-                    result=result+sgSuffix;
-                   if(!query.getName().equals(result)){
-                       query.setName(result);
-                   }
-                }else if(query.getClassify()!=null&&query.getClassify()==2&&StringUtils.isNotEmpty(jlSuffix)){
-                    result=result+jlSuffix;
-                    if(!query.getName().equals(result)){
-                        query.setName(result);
+                if(contract!=null&&contract.getMajorDataType()!=null&&contract.getMajorDataType()==4){
+                    if(query.getClassify()!=null&&query.getClassify()==1&&StringUtils.isNotEmpty(sgSuffix)){
+                        result=result+sgSuffix;
+                        if(!query.getName().equals(result)){
+                            query.setName(result);
+                        }
+                    }else if(query.getClassify()!=null&&query.getClassify()==2&&StringUtils.isNotEmpty(jlSuffix)){
+                        result=result+jlSuffix;
+                        if(!query.getName().equals(result)){
+                            query.setName(result);
+                        }
                     }
                 }
+                query.setName(result);
             }
         }
         List<InformationQuery> taskList = queryList.stream().filter(o -> o.getStatus() == 1 || o.getStatus() == 2).collect(Collectors.toList());

+ 14 - 3
blade-service/blade-business/src/main/java/org/springblade/business/controller/TaskController.java

@@ -329,11 +329,16 @@ public class TaskController extends BladeController {
             }
 
             //校验当前项目是否为垂直审批
-            List<Task> taskList = taskService.getBaseMapper().selectList(Wrappers.<Task>lambdaQuery().select(Task::getId,Task::getProjectId, Task::getTaskName, Task::getProcessInstanceId, Task::getContractId, Task::getFormDataId).in(Task::getId, Arrays.asList(taskIdArray)));
+            List<String> taskIdList = new ArrayList<>();
+            List<Task> taskList = taskService.getBaseMapper().selectList(Wrappers.<Task>lambdaQuery().select(Task::getId,Task::getProjectId, Task::getTaskName, Task::getProcessInstanceId, Task::getContractId, Task::getFormDataId, Task::getStatus).in(Task::getId, Arrays.asList(taskIdArray)));
             for (Task task : taskList) {
                 if (ObjectUtil.isEmpty(task.getProjectId())) {
                     throw new ServiceException("未获取到任务【" + task.getTaskName() + "】对应的项目信息");
                 }
+                if (task.getStatus() != null && task.getStatus() == 3) {
+                    taskIdList.add(task.getId() + "");
+                    continue;
+                }
                 ProjectInfo projectInfo = jdbcTemplate.query("select approval_type from m_project_info where id = " + task.getProjectId(), new BeanPropertyRowMapper<>(ProjectInfo.class)).stream().findAny().orElse(null);
                 //如果是垂直审批,那么检查当前用户是否符合当前顺序
                 if (projectInfo != null && projectInfo.getApprovalType() != null && new Integer(1).equals(projectInfo.getApprovalType())) {
@@ -369,6 +374,9 @@ public class TaskController extends BladeController {
             List<TaskApprovalVO> taskApprovalVOS = new ArrayList<>();
 
             for (int i = 0, l = taskIdArray.length; i < l; i++) {
+                if (taskIdList.contains(taskIdArray[i])) {
+                    continue;
+                }
                 TaskApprovalVO approvalVO = new TaskApprovalVO();
                 approvalVO.setTaskId(taskIdArray[i]);
                 approvalVO.setParallelProcessInstanceId(parallelProcessInstanceIdArray[i]);
@@ -384,7 +392,7 @@ public class TaskController extends BladeController {
             this.taskService.batchCompleteApprovalTask(taskApprovalVOS);
             Map<String, TaskApprovalVO> taskApprovalVOMap = taskApprovalVOS.stream().collect(Collectors.toMap(TaskApprovalVO::getTaskId, taskApprovalVO -> taskApprovalVO, (o1, o2) -> o1));
             for (Task task : taskList) {
-                if (batchTaskVO.getFlag().equals("NO")) {
+                if (batchTaskVO.getFlag().equals("NO") && task.getStatus() != null && task.getStatus() != 3) {
                     JSONObject json = new JSONObject();
                     json.put("operationObjIds", Func.toStrList(task.getFormDataId()));
                     json.put("operationObjName", "批量废除");
@@ -1233,9 +1241,12 @@ public class TaskController extends BladeController {
         //生成等待批次,任务完成后删除
         List<TaskApprovalVO> taskApprovalVOS = new ArrayList<>();
         taskApprovalVOS.add(taskApprovalVO);
+        Task task = taskService.getOne(Wrappers.<Task>lambdaQuery().eq(Task::getId, taskApprovalVO.getTaskId()));
+        if (task == null || (task.getStatus() != null && task.getStatus() == 3)) {
+            return R.fail("任务已被撤回或者驳回");
+        }
         this.taskService.batchCompleteApprovalTask(taskApprovalVOS);
         if (!taskApprovalVO.isPass()) {
-            Task task = taskService.getBaseMapper().selectOne(Wrappers.<Task>lambdaQuery().select(Task::getProjectId, Task::getContractId, Task::getFormDataId).eq(Task::getId, taskApprovalVO.getTaskId()));
             JSONObject json = new JSONObject();
             json.put("operationObjIds", Func.toStrList(task.getFormDataId()));
             json.put("operationObjName", "批量废除");

+ 2 - 2
blade-service/blade-business/src/main/java/org/springblade/business/controller/TrialDetectionController.java

@@ -294,12 +294,12 @@ public class TrialDetectionController extends BladeController {
     @ApiOperationSupport(order = 18)
     @ApiOperation(value = "自检多表PDF预览", notes = "传入nodeId=试验记录id、classify、contractId、projectId")
     public R<Object> getPDFs(String nodeId, String classify, String contractId, String projectId) throws FileNotFoundException {
-        String sql = "select pdf_url,e_visa_pdf_url from u_information_query where project_id ='" + projectId + "' and classify='" + classify + "' and  wbs_id='" + nodeId + "' and contract_id ='" + contractId + "'";
+        String sql = "select pdf_url,e_visa_pdf_url from u_information_query where status in(0,1,2) and project_id ='" + projectId + "' and classify='" + classify + "' and  wbs_id='" + nodeId + "' and contract_id ='" + contractId + "'";
         List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql);
         if (maps.size() >= 1) {
             Map<String, Object> stringObjectMap = maps.get(0);
             Object pdfUrl = stringObjectMap.get("pdf_url");
-            if (stringObjectMap.get("e_visa_pdf_url") != null) {
+            if (stringObjectMap.get("e_visa_pdf_url") != null ) {
                 //优先使用电签的pdf
                 pdfUrl = stringObjectMap.get("e_visa_pdf_url");
             }

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

@@ -341,4 +341,9 @@ public class ArchiveFileClientImpl implements ArchiveFileClient {
         }
     }
 
+    @Override
+    public void saveArchiveFileByBIM(ArchiveFile archiveFile) {
+        iArchiveFileService.save(archiveFile);
+    }
+
 }

+ 6 - 0
blade-service/blade-business/src/main/java/org/springblade/business/feignClient/MetadataClassificationClientImpl.java

@@ -5,6 +5,7 @@ import org.springblade.business.entity.MetadataClassification;
 import org.springblade.business.feign.MetadataClassificationClient;
 import org.springblade.business.service.IMetadataClassificationService;
 import org.springblade.business.vo.MetadataClassificationVO;
+import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
 import java.util.List;
@@ -36,4 +37,9 @@ public class MetadataClassificationClientImpl implements MetadataClassificationC
     public List<MetadataClassification> getMetadataClassification() {
         return iMetadataClassificationService.getMetadataClassification();
     }
+
+    @Override
+    public boolean createMetadataFiles(List<Long> fileIds){
+        return iMetadataClassificationService.createMetadataFiles(fileIds, 0);
+    }
 }

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

@@ -160,6 +160,10 @@
         <if test="vo.rectification != null and vo.rectification != ''">
             and u.rectification = #{vo.rectification}
         </if>
+        <if test="vo.sourceType != null and vo.sourceType != ''">
+            and u.source_type = #{sourceType}
+        </if>
+
         <if test="vo.rectification == null and vo.archiveId == null">
             and (u.is_auto_file is null or u.is_auto_file != 1)
         </if>
@@ -452,7 +456,7 @@
                 LEFT JOIN m_archive_tree_contract ar on u.node_id = ar.id
         where 	u.contract_id = #{contractId} and u.classify = #{classify}
           AND u.is_deleted = 0
-          AND u.source_type = 1 and ar.is_deleted = 0;
+          AND u.node_ext_id is not null and ar.is_deleted = 0  order by u.sort,u.sort_num,u.create_time
     </select>
 
     <select id="getListByContractId1" resultType="org.springblade.business.entity.ArchiveFile">

+ 1 - 0
blade-service/blade-business/src/main/java/org/springblade/business/mapper/FixedFlowLinkMapper.java

@@ -36,4 +36,5 @@ public interface FixedFlowLinkMapper extends BaseMapper<FixedFlowLink> {
 
     List<FixedFlowLink> selectFixedFlowLink(@Param("fixedFlowId") String fixedFlowId);
 
+    Integer selectIsDeleted(@Param("fixedFlowId") Long fixedFlowId);
 }

+ 3 - 0
blade-service/blade-business/src/main/java/org/springblade/business/mapper/FixedFlowLinkMapper.xml

@@ -37,5 +37,8 @@
           and fixed_flow_id = #{fixedFlowId}
         order by fixed_flow_link_sort ASC
     </select>
+    <select id="selectIsDeleted" resultType="java.lang.Integer">
+        SELECT COUNT(*) FROM u_task WHERE fixed_flow_id = #{fixedFlowId} AND is_deleted = 0 And status !=3
+    </select>
 
 </mapper>

+ 1 - 0
blade-service/blade-business/src/main/java/org/springblade/business/mapper/MetadataClassificationMapper.java

@@ -29,4 +29,5 @@ public interface MetadataClassificationMapper extends BaseMapper<MetadataClassif
 
 
     List<HashMap<String, Object>> getMetadaFileByFileId(@Param("fileId") Long fileId);
+    List<HashMap<String, Object>> getMetadaFileByFileIds(@Param("fileIds") List<Long> fileIds);
 }

+ 9 - 0
blade-service/blade-business/src/main/java/org/springblade/business/mapper/MetadataClassificationMapper.xml

@@ -95,4 +95,13 @@
         where file_id = #{fileId}
         order by create_time desc limit 1
     </select>
+    <select id="getMetadaFileByFileIds" resultType="java.util.Map">
+        SELECT *
+        FROM u_metadata_file
+        WHERE  is_deleted=0 and file_id IN
+        <foreach collection="fileIds" item="fileId" open="(" close=")" separator=",">
+            #{fileId}
+        </foreach>
+        ORDER BY file_id, create_time DESC
+    </select>
 </mapper>

+ 1 - 0
blade-service/blade-business/src/main/java/org/springblade/business/service/IFixedFlowLinkService.java

@@ -35,4 +35,5 @@ public interface IFixedFlowLinkService extends BaseService<FixedFlowLink> {
 
     List<FixedFlowLink> selectFixedFlowLink(String fixedFlowId);
 
+    Integer selectIsDeleted(Long fixedFlowId);
 }

+ 2 - 0
blade-service/blade-business/src/main/java/org/springblade/business/service/IMetadataClassificationService.java

@@ -26,4 +26,6 @@ public interface IMetadataClassificationService extends BaseService<MetadataClas
     boolean updateMetadata(MetadataClassificationVO vo);
 
     List<MetadataClassification> getMetadataClassification();
+
+    boolean createMetadataFiles(List<Long> fileIds, Integer type);
 }

+ 5 - 0
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/FixedFlowLinkServiceImpl.java

@@ -46,4 +46,9 @@ public class FixedFlowLinkServiceImpl extends BaseServiceImpl<FixedFlowLinkMappe
         return this.baseMapper.selectFixedFlowLink(fixedFlowId);
     }
 
+    @Override
+    public Integer selectIsDeleted(Long fixedFlowId) {
+        return this.baseMapper.selectIsDeleted(fixedFlowId);
+    }
+
 }

+ 6 - 0
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/FixedFlowServiceImpl.java

@@ -64,6 +64,12 @@ public class FixedFlowServiceImpl extends BaseServiceImpl<FixedFlowMapper, Fixed
                 vos.setLinkUserJoinString(linkJoin.substring(1));
                 vos.setFixedFlowLinkList(links);
             }
+             Integer size=this.fixedFlowLinkService.selectIsDeleted(vos.getId());
+            if(size>0){
+                vos.setDeletedIs(false);
+            }else {
+                vos.setDeletedIs(true);
+            }
         });
         //设置总数
         iPage.setTotal(count);

+ 67 - 60
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/InformationQueryServiceImpl.java

@@ -387,71 +387,76 @@ public class InformationQueryServiceImpl extends BaseServiceImpl<InformationQuer
         } else {
             //首先根据wbsId获取合同段ID和项目ID
             WbsTreeContract contractTree = this.wbsTreeContractClient.getContractWbsTreeByPrimaryKeyId(Long.parseLong(primaryKeyId));
+            int type = (contractTree.getIsExpernode() == null || contractTree.getIsExpernode() <= 0) ? 1 : 2;
+            if (DistributedRedisLock.acquire("saveOrUpdateInformationQueryData:" + primaryKeyId + ":" + contractTree.getContractId() + ":" + classify + ":" + type,5)) {
+                try {
+                    //判断当前填报节点下是否已经存在相应数据
+                    InformationQuery oldData = this.baseMapper.getInformationQueryByWbsId(contractTree.getPKeyId(), classify,contractTree.getContractId());
 
-            //判断当前填报节点下是否已经存在相应数据
-            InformationQuery oldData = this.baseMapper.getInformationQueryByWbsId(contractTree.getPKeyId(), classify,contractTree.getContractId());
-
-            if (oldData != null) {
-                //存在记录,修改
-                if (StringUtils.isNotEmpty(fileName)) {
-                    oldData.setName(fileName);
-                }
-
-                //拼接填报人信息
-                String fileUser = userId + "-" + userNmae;
-                if (StringUtils.isNotEmpty(oldData.getFileUserIdAndName())) {
-                    if (!oldData.getFileUserIdAndName().contains(userId.toString())) {
-                        //不包含,拼接
-                        oldData.setFileUserIdAndName(oldData.getFileUserIdAndName() + "," + fileUser);
-                    }
-                } else {
-                    oldData.setFileUserIdAndName(fileUser);
-                }
-
-                oldData.setUpdateTime(new Date());
-                oldData.setUpdateUser(userId);
+                    if (oldData != null) {
+                        //存在记录,修改
+                        if (StringUtils.isNotEmpty(fileName)) {
+                            oldData.setName(fileName);
+                        }
 
-                List<String> linkIds = linkDataList.stream().map(json -> json.getString("id")).distinct().collect(Collectors.toList());
-                if (linkIds.size() > 0) {
-                    oldData.setSjRecordIds(StringUtils.join(linkIds, ","));
-                }
+                        //拼接填报人信息
+                        String fileUser = userId + "-" + userNmae;
+                        if (StringUtils.isNotEmpty(oldData.getFileUserIdAndName())) {
+                            if (!oldData.getFileUserIdAndName().contains(userId.toString())) {
+                                //不包含,拼接
+                                oldData.setFileUserIdAndName(oldData.getFileUserIdAndName() + "," + fileUser);
+                            }
+                        } else {
+                            oldData.setFileUserIdAndName(fileUser);
+                        }
 
-                //修改数据
-                this.baseMapper.updateById(oldData);
-            } else {
-                //新增基础数据
-                InformationQuery newData = new InformationQuery();
-                //设置文件题名
-                newData.setName(fileName);
-                //设置文件类型
-                newData.setCategory(contractTree.getNodeType());
-                //项目ID
-                newData.setProjectId(Long.parseLong(contractTree.getProjectId()));
-                //合同段ID
-                newData.setContractId(Long.parseLong(contractTree.getContractId()));
-                //施工资料还是质检资料
-                newData.setClassify(classify);
-                //节点ID
-                newData.setWbsId(contractTree.getPKeyId());
-
-                //1资料填报,2试验,3首件
-                newData.setType((contractTree.getIsExpernode() == null || contractTree.getIsExpernode() <= 0) ? 1 : 2);
-
-                //流程状态,默认未上报
-                newData.setStatus(0);
-                //填报人ID及姓名
-                newData.setFileUserIdAndName(userId + "-" + userNmae);
-                //数据源类型
-                newData.setSourceType(sourceType);
-                newData.setCreateUser(userId);
-                newData.setCreateTime(new Date());
+                        oldData.setUpdateTime(new Date());
+                        oldData.setUpdateUser(userId);
 
-                List<String> linkIds = linkDataList.stream().map(json -> json.getString("id")).distinct().collect(Collectors.toList());
-                if (linkIds.size() > 0) {
-                    newData.setSjRecordIds(StringUtils.join(linkIds, ","));
+                        List<String> linkIds = linkDataList.stream().map(json -> json.getString("id")).distinct().collect(Collectors.toList());
+                        if (linkIds.size() > 0) {
+                            oldData.setSjRecordIds(StringUtils.join(linkIds, ","));
+                        }
+                        //修改数据
+                        this.baseMapper.updateById(oldData);
+                    } else {
+                        //新增基础数据
+                        InformationQuery newData = new InformationQuery();
+                        //设置文件题名
+                        newData.setName(fileName);
+                        //设置文件类型
+                        newData.setCategory(contractTree.getNodeType());
+                        //项目ID
+                        newData.setProjectId(Long.parseLong(contractTree.getProjectId()));
+                        //合同段ID
+                        newData.setContractId(Long.parseLong(contractTree.getContractId()));
+                        //施工资料还是质检资料
+                        newData.setClassify(classify);
+                        //节点ID
+                        newData.setWbsId(contractTree.getPKeyId());
+
+                        //1资料填报,2试验,3首件
+                        newData.setType(type);
+
+                        //流程状态,默认未上报
+                        newData.setStatus(0);
+                        //填报人ID及姓名
+                        newData.setFileUserIdAndName(userId + "-" + userNmae);
+                        //数据源类型
+                        newData.setSourceType(sourceType);
+                        newData.setCreateUser(userId);
+                        newData.setCreateTime(new Date());
+
+                        List<String> linkIds = linkDataList.stream().map(json -> json.getString("id")).distinct().collect(Collectors.toList());
+                        if (linkIds.size() > 0) {
+                            newData.setSjRecordIds(StringUtils.join(linkIds, ","));
+                        }
+                        //保存数据
+                        this.baseMapper.insert(newData);
+                    }
+                } finally {
+                    DistributedRedisLock.release("saveOrUpdateInformationQueryData:" + primaryKeyId + ":" + contractTree.getContractId() + ":" + classify + ":" + type);
                 }
-                //保存数据
-                this.baseMapper.insert(newData);
             }
         }
         return null;
@@ -1091,6 +1096,8 @@ public class InformationQueryServiceImpl extends BaseServiceImpl<InformationQuer
                         informationQuery.setReportNumber(null);
                         informationQuery.setAuditUserIdAndName(null);
                         informationQuery.setTaskId(null);
+                        informationQuery.setCreateTime(new Date());
+                        informationQuery.setUpdateTime(new Date());
                         this.save(informationQuery);
                     } finally {
                         DistributedRedisLock.release("informationQueryLock_" + informationQuery.getWbsId() + "_" + informationQuery.getContractId() + "_" + informationQuery.getClassify() + "_" + informationQuery.getType());

+ 591 - 0
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/MetadataClassificationServiceImpl.java

@@ -1,6 +1,8 @@
 package org.springblade.business.service.impl;
 
 
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import lombok.AllArgsConstructor;
 import org.apache.commons.lang.StringUtils;
@@ -37,7 +39,9 @@ import org.springframework.dao.DataAccessException;
 import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.stereotype.Service;
 
+import java.sql.Statement;
 import java.util.*;
+import java.util.function.Function;
 import java.util.stream.Collectors;
 
 @Service
@@ -581,4 +585,591 @@ public class MetadataClassificationServiceImpl
         List<MetadataClassification> metadataClassifications = baseMapper.selectList(metadata);
         return metadataClassifications ;
     }
+
+    /**
+     *  批量操作
+     * @param fileIds
+     * @param type
+     * @return
+     */
+
+    public boolean createMetadataFiles(List<Long> fileIds, Integer type) {
+        if (fileIds == null || fileIds.isEmpty()) return true;
+
+        try {
+            BladeUser user = AuthUtil.getUser();
+            // tenantId 是 String 类型
+            String tenantId = user != null ? String.valueOf(user.getTenantId()) : "-1";
+            Long userId = user != null ? user.getUserId() : -1L;
+            String now = DateUtil.formatDateTime(new Date());
+
+            // 批量获取文件信息
+            List<ArchiveFile> files = iArchiveFileService.listByIds(fileIds);
+            Map<Long, ArchiveFile> fileMap = new HashMap<>();
+            for (ArchiveFile file : files) {
+                fileMap.put(file.getId(), file);
+            }
+
+            // 批量获取元数据文件状态
+            List<HashMap<String, Object>> metadataMapList = baseMapper.getMetadaFileByFileIds(fileIds);
+            Map<Long, Map<String, Object>> metadataFileMap = new HashMap<>();
+            for (HashMap<String, Object> map : metadataMapList) {
+                Long fileId = (Long) map.get("file_id");
+                if (fileId != null) {
+                    metadataFileMap.put(fileId, map);
+                }
+            }
+
+            // 获取元数据字段
+            QueryWrapper<MetadataClassification> metadataWrapper = new QueryWrapper<>();
+            metadataWrapper.lambda().eq(MetadataClassification::getIsDeleted, 0);
+            List<MetadataClassification> metadataClassifications = baseMapper.selectList(metadataWrapper);
+            Map<String, MetadataClassification> mapAll = new HashMap<>();
+            for (MetadataClassification mc : metadataClassifications) {
+                mapAll.put(mc.getContainerName(), mc);
+            }
+
+            // === 优化点1:获取 ArchiveAuto 映射(循环调用)===
+            Map<Long, ArchivesAuto> archiveAutoMap = new HashMap<>();
+            Set<Long> archiveIds = files.stream()
+                    .map(ArchiveFile::getArchiveId)
+                    .filter(Objects::nonNull)
+                    .collect(Collectors.toSet());
+            if (!archiveIds.isEmpty()) {
+                for (Long archiveId : archiveIds) {
+                    try {
+                        ArchivesAuto archivesAuto = archiveAutoClient.saveArchiveAutoById(archiveId);
+                        if (archivesAuto != null) {
+                            archiveAutoMap.put(archiveId, archivesAuto);
+                        }
+                    } catch (Exception e) {
+                    }
+                }
+            }
+
+            // === 优化点2:获取 ContractInfo 映射(循环调用)===
+            Map<String, ContractInfo> contractInfoMap = new HashMap<>();
+            Set<String> contractIds = files.stream()
+                    .map(ArchiveFile::getContractId)
+                    .filter(contractId -> contractId != null && !contractId.isEmpty())
+                    .collect(Collectors.toSet());
+            if (!contractIds.isEmpty()) {
+                for (String contractId : contractIds) {
+                    try {
+                        Long contractIdLong = Long.parseLong(contractId);
+                        ContractInfo contractInfo = contractClient.getContractById(contractIdLong);
+                        if (contractInfo != null) {
+                            contractInfoMap.put(contractId, contractInfo);
+                        }
+                    } catch (Exception e) {
+
+                    }
+                }
+            }
+
+            // === 优化点3:处理所有唯一的 nodeId(循环调用)===
+            // 提取所有不重复的 nodeId
+//            Set<String> uniqueNodeIds = files.stream()
+//                    .map(ArchiveFile::getNodeId)
+//                    .filter(nodeId -> nodeId != null && !nodeId.isEmpty())
+//                    .collect(Collectors.toSet());
+//
+//            Map<String, ArchiveTreeContract> nodeContractMap = new HashMap<>();
+//            Map<String, List<ArchiveTreeContract>> ancestorListMap = new HashMap<>();
+//
+//            // 循环处理每个唯一 nodeId
+//            for (String nodeId : uniqueNodeIds) {
+//                try {
+//                    // 获取当前节点
+//                    ArchiveTreeContract currentNode = archiveTreeContractClient.getArchiveTreeContractById(Long.parseLong(nodeId));
+//                    if (currentNode == null) continue;
+//                    nodeContractMap.put(nodeId, currentNode);
+//
+//                    // 构建祖先层次结构
+//                    String ancestors = currentNode.getAncestors();
+//                    if (ancestors != null && !ancestors.isEmpty()) {
+//                        // 添加当前节点ID
+//                        ancestors = ancestors + "," + currentNode.getId();
+//
+//                        // 获取祖先节点列表
+//                        List<ArchiveTreeContract> ancestorList = archiveTreeContractClient.getArchiveTreeContractListByIds(ancestors);
+//                        ancestorListMap.put(nodeId, ancestorList);
+//                    }
+//                } catch (Exception e) {
+//                }
+//            }
+
+            // === 优化点3:批量获取节点数据并构建祖先映射 ===
+            Set<String> uniqueNodeIds = files.stream()
+                    .map(ArchiveFile::getNodeId)
+                    .filter(nodeId -> nodeId != null && !nodeId.isEmpty())
+                    .collect(Collectors.toSet());
+
+            Map<String, ArchiveTreeContract> nodeContractMap = new HashMap<>();
+            Map<String, List<ArchiveTreeContract>> ancestorListMap = new HashMap<>();
+
+            if (!uniqueNodeIds.isEmpty()) {
+                try {
+                    // 1. 批量获取所有节点
+                    String nodeIdsStr = String.join(",", uniqueNodeIds);
+                    List<ArchiveTreeContract> nodeList = archiveTreeContractClient.getArchiveTreeContractListByIds(nodeIdsStr);
+
+                    // 2. 直接使用nodeList中的节点(避免重复添加当前节点ID)
+                    Map<Long, ArchiveTreeContract> allAncestorsMap = new HashMap<>();
+                    for (ArchiveTreeContract node : nodeList) {
+                        // 所有当前节点直接加入祖先映射
+                        allAncestorsMap.put(node.getId(), node);
+                        nodeContractMap.put(String.valueOf(node.getId()), node);
+                    }
+
+                    // 3. 收集祖先ID(不包括当前节点)
+                    Set<Long> ancestorIdsToFetch = new HashSet<>();
+                    for (ArchiveTreeContract node : nodeList) {
+                        String ancestors = node.getAncestors();
+                        if (ancestors != null && !ancestors.isEmpty()) {
+                            String[] ids = ancestors.split(",");
+                            for (String id : ids) {
+                                if (!id.trim().isEmpty()) {
+                                    long ancestorId = Long.parseLong(id.trim());
+                                    // 仅添加不在当前节点集合中的祖先ID
+                                    if (!allAncestorsMap.containsKey(ancestorId)) {
+                                        ancestorIdsToFetch.add(ancestorId);
+                                    }
+                                }
+                            }
+                        }
+                    }
+
+                    // 4. 批量获取缺失的祖先节点
+                    if (!ancestorIdsToFetch.isEmpty()) {
+                        String ancestorIdsStr = ancestorIdsToFetch.stream()
+                                .map(String::valueOf)
+                                .collect(Collectors.joining(","));
+
+                        List<ArchiveTreeContract> missingAncestors =
+                                archiveTreeContractClient.getArchiveTreeContractListByIds(ancestorIdsStr);
+
+                        for (ArchiveTreeContract ancestor : missingAncestors) {
+                            allAncestorsMap.put(ancestor.getId(), ancestor);
+                        }
+                    }
+
+                    // 5. 为每个节点重建祖先列表
+                    for (ArchiveTreeContract node : nodeList) {
+                        String nodeIdStr = String.valueOf(node.getId());
+                        List<ArchiveTreeContract> ancestorList = new ArrayList<>();
+
+                        // 构建完整路径(祖先ID + 当前节点ID)
+                        String ancestors = node.getAncestors();
+                        String fullPath = ancestors != null && !ancestors.isEmpty() ?
+                                ancestors + "," + node.getId() :
+                                String.valueOf(node.getId());
+
+                        // 按顺序构建祖先列表
+                        String[] pathIds = fullPath.split(",");
+                        for (String idStr : pathIds) {
+                            if (!idStr.trim().isEmpty()) {
+                                Long id = Long.parseLong(idStr.trim());
+                                ArchiveTreeContract ancestor = allAncestorsMap.get(id);
+                                if (ancestor != null) {
+                                    ancestorList.add(ancestor);
+                                }
+                            }
+                        }
+
+                        ancestorListMap.put(nodeIdStr, ancestorList);
+                    }
+                } catch (Exception e) {
+                    log.error("批量处理节点失败", e);
+                }
+            }
+
+
+            // 准备批量SQL和参数
+            StringBuilder insertSql = new StringBuilder();
+            List<Object[]> insertParams = new ArrayList<>();
+            StringBuilder updateSql = new StringBuilder();
+            List<Object[]> updateParams = new ArrayList<>();
+
+            for (Long fileId : fileIds) {
+                ArchiveFile file = fileMap.get(fileId);
+                if (file == null || file.getNodeId() == null || file.getNodeId().isEmpty()) {
+                    continue;
+                }
+
+                Map<String, Object> metadataMap = metadataFileMap.get(fileId);
+                boolean isAdd = (metadataMap == null);
+                Map<String, Object> keyValue = new LinkedHashMap<>();
+
+                // 收集元数据值
+                // 收集元数据值 - 传入预处理的数据映射
+                this.collectFileMetadata(
+                        file, type, keyValue, isAdd,
+                        archiveAutoMap, contractInfoMap,
+                        nodeContractMap, ancestorListMap
+                );
+
+                if (isAdd) {
+                    buildInsertSqlParams(file, keyValue, mapAll, metadataClassifications,
+                            tenantId, userId, now, insertSql, insertParams);
+                } else {
+                    buildUpdateSqlParams(fileId, keyValue, mapAll, metadataMap,
+                            userId, now, updateSql, updateParams);
+                }
+            }
+
+            // 执行批量操作
+            if (insertSql.length() > 0 && !insertParams.isEmpty()) {
+                int[] insertResults = jdbcTemplate.batchUpdate(insertSql.toString(), insertParams);
+                logBatchResultsSimple(insertResults, "INSERT");
+            }
+
+            if (updateSql.length() > 0 && !updateParams.isEmpty()) {
+                int[] updateResults = jdbcTemplate.batchUpdate(updateSql.toString(), updateParams);
+                logBatchResultsSimple(updateResults, "UPDATE");
+            }
+
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    private void buildInsertSqlParams(ArchiveFile file, Map<String, Object> keyValue,
+                                      Map<String, MetadataClassification> mapAll,
+                                      List<MetadataClassification> metadataClassifications,
+                                      String tenantId, Long userId, String now,
+                                      StringBuilder insertSql, List<Object[]> insertParams) {
+        // 准备参数列表
+        List<Object> params = new ArrayList<>();
+
+        // 固定字段参数
+        params.add(SnowFlakeUtil.getId());   // id
+        params.add(tenantId);                // tenant_id (String 类型)
+        params.add(userId);                  // create_user
+        params.add(now);                     // create_time
+        params.add(userId);                  // update_user
+        params.add(now);                     // update_time
+        params.add(0);                       // status
+        params.add(0);                       // is_deleted
+        params.add(file.getContractId());    // contract_id
+        params.add(file.getId());            // file_id
+
+        // 添加元数据字段参数
+        for (MetadataClassification mc : metadataClassifications) {
+            Object value = keyValue.getOrDefault(mc.getContainerName(), null);
+            params.add(value);
+        }
+
+        // 构建SQL模板(只构建一次)
+        if (insertSql.length() == 0) {
+            insertSql.append("INSERT INTO u_metadata_file (id, tenant_id, create_user, create_time, ");
+            insertSql.append("update_user, update_time, status, is_deleted, contract_id, file_id, ");
+
+            // 添加所有元数据字段
+            List<String> fieldKeys = new ArrayList<>();
+            for (MetadataClassification mc : metadataClassifications) {
+                fieldKeys.add(mc.getFieldKey());
+            }
+            insertSql.append(String.join(", ", fieldKeys));
+
+            insertSql.append(") VALUES (");
+
+            // 构建占位符字符串
+            StringBuilder placeholders = new StringBuilder();
+            for (int i = 0; i < (10 + metadataClassifications.size()); i++) {
+                if (i > 0) placeholders.append(", ");
+                placeholders.append("?");
+            }
+            insertSql.append(placeholders);
+
+            insertSql.append(")");
+        }
+
+        // 将参数转换为数组并添加到批处理列表
+        insertParams.add(params.toArray());
+    }
+
+    private void buildUpdateSqlParams(Long fileId, Map<String, Object> keyValue,
+                                      Map<String, MetadataClassification> mapAll,
+                                      Map<String, Object> metadataMap,
+                                      Long userId, String now,
+                                      StringBuilder updateSql, List<Object[]> updateParams) {
+        // 准备参数列表
+        List<Object> params = new ArrayList<>();
+        List<String> setFields = new ArrayList<>();
+
+        // 添加固定更新字段
+        setFields.add("update_user = ?");
+        params.add(userId);
+
+        setFields.add("update_time = ?");
+        params.add(now);
+
+        // 添加元数据字段参数
+        for (Map.Entry<String, Object> entry : keyValue.entrySet()) {
+            String containerName = entry.getKey();
+            Object value = entry.getValue();
+
+            if (mapAll.containsKey(containerName)) {
+                MetadataClassification mc = mapAll.get(containerName);
+                setFields.add(mc.getFieldKey() + " = ?");
+                params.add(value);
+            }
+        }
+
+        // 添加WHERE条件标识(最后处理)
+        params.add(fileId);
+
+        // 构建SQL模板(只构建一次)
+        if (updateSql.length() == 0 && !setFields.isEmpty()) {
+            updateSql.append("UPDATE u_metadata_file SET ");
+            updateSql.append(String.join(", ", setFields));
+            updateSql.append(" WHERE file_id = ?");
+        }
+
+        // 将参数转换为数组并添加到批处理列表
+        if (!setFields.isEmpty()) {
+            updateParams.add(params.toArray());
+        }
+    }
+
+
+    private void collectFileMetadata(ArchiveFile file, Integer type,
+                                     Map<String, Object> keyValue, boolean isAdd,Map<Long, ArchivesAuto> archiveAutoMap,
+                                     Map<String, ContractInfo> contractInfoMap,Map<String, ArchiveTreeContract> nodeContractMap,
+                                     Map<String, List<ArchiveTreeContract>> ancestorListMap) {
+        // 只有类型0需要处理
+        if (type != 0) return;
+
+        // 获取当前节点
+        ArchiveTreeContract currentNode = nodeContractMap.get(file.getNodeId());
+        if (currentNode == null) return;
+
+        // 获取祖先列表
+        List<ArchiveTreeContract> ancestorList = ancestorListMap.get(file.getNodeId());
+        if (ancestorList == null || ancestorList.isEmpty()) return;
+
+        // 准备各种层级结构
+        StringBuffer paperAddress = new StringBuffer();
+        StringBuffer nameStr = new StringBuffer();
+        StringBuffer unitProjectString = new StringBuffer();
+        StringBuffer unitProjectIdString = new StringBuffer();
+        StringBuffer divisionProjectString = new StringBuffer();
+        StringBuffer divisionProjectIdString = new StringBuffer();
+        StringBuffer itemizedProjectString = new StringBuffer();
+        StringBuffer itemizedProjectIdString = new StringBuffer();
+
+        // 处理每个层级
+        for (int i = 0; i < ancestorList.size(); i++) {
+            ArchiveTreeContract node = ancestorList.get(i);
+            metadataSetting(node, unitProjectString, unitProjectIdString,
+                    divisionProjectString, divisionProjectIdString,
+                    itemizedProjectString, itemizedProjectIdString);
+
+            if (i == 0) continue;
+
+            // 构建纸质文件位置
+            if (node.getId().equals(currentNode.getParentId())) {
+                paperAddress.append(node.getNodeName());
+                paperAddress.append(">");
+                paperAddress.append(currentNode.getNodeName());
+            }
+
+            nameStr.append(node.getNodeName());
+            nameStr.append("/");
+        }
+
+        // 设置基础元数据
+        keyValue.put("聚合层次", nameStr.toString());
+        keyValue.put("纸质文件位置", paperAddress.toString());
+
+        // 责任单位名称
+        String dutyUser = "";
+        if ((file.getDutyUser() == null || file.getDutyUser().isEmpty()) &&
+                (file.getContractId() != null && !file.getContractId().isEmpty())) {
+            ContractInfo contract = contractInfoMap.get(file.getContractId());
+            if (contract != null) {
+                if (contract.getContractType() == 1) {
+                    dutyUser = contract.getConstructionUnitName();
+                } else if (contract.getContractType() == 2) {
+                    dutyUser = contract.getSupervisionUnitName();
+                } else {
+                    dutyUser = contract.getContractorUnitName();
+                }
+            }
+        } else {
+            dutyUser = file.getDutyUser() != null ? file.getDutyUser() : "";
+        }
+        keyValue.put("立档单位名称", dutyUser);
+        keyValue.put("责任者名称", file.getDutyUser());
+
+        // 设置文件基本信息
+        keyValue.put("元数据目录文件", nameStr.toString());
+        keyValue.put("电子文件号", file.getId());
+        keyValue.put("文件页数", file.getFilePage());
+        keyValue.put("生成方式", file.getSourceType());
+        keyValue.put("题名", file.getFileName());
+
+        // 关键词生成
+        String keyWords = "";
+        if (file.getFileName() != null && file.getFileName().length() < 9) {
+            keyWords = file.getFileName();
+        } else if (file.getFileName() != null) {
+            keyWords = file.getFileName().substring(0, 8);
+        }
+        keyValue.put("关键词", keyWords);
+
+        // 摘要生成
+        String zhaiyao = "该文件为【" + (file.getSourceType() == 1 ? "原生" : "数字化") + "】于【" +
+                (file.getFileTime() != null ? file.getFileTime() : "") + "】形成,共【" +
+                (file.getFilePage() != null ? file.getFilePage() : 0) + "】页、【" +
+                (file.getFileName() != null ? file.getFileName() : "") + "】,责任者为【" +
+                dutyUser + "】";
+        keyValue.put("摘要", zhaiyao);
+        keyValue.put("文件日期", file.getFileTime());
+
+        // 设置档案信息(如果有)
+        if (file.getArchiveId() != null) {
+            ArchivesAuto archivesAuto = archiveAutoMap.get(file.getArchiveId());
+            if (archivesAuto != null) {
+                keyValue.put("密级", archivesAuto.getSecretLevel());
+                keyValue.put("档号", archivesAuto.getFileNumber());
+                keyValue.put("保管期限", archivesAuto.getStorageTime());
+                keyValue.put("文件件数", archivesAuto.getFileN());
+                keyValue.put("验证码", archivesAuto.getId());
+            }
+        }
+
+        // 文件编号和拍摄信息
+        keyValue.put("文号", file.getFileNumber());
+        keyValue.put("拍摄时间", file.getFilmingTime());
+        keyValue.put("分组号", file.getFilmCode());
+        keyValue.put("组内照片编号", file.getReferCode());
+
+        // 文件路径相关处理
+        if (file.getFileUrl() != null && !file.getFileUrl().isEmpty()) {
+            // 格式名称和存储位置
+            String fileUrl = file.getFileUrl();
+            if (fileUrl.contains(".")) {
+                keyValue.put("格式名称", fileUrl.substring(fileUrl.lastIndexOf(".") + 1));
+            } else {
+                keyValue.put("格式名称", "");
+            }
+
+            keyValue.put("存储位置", fileUrl);
+            keyValue.put("计算机文件名", fileUrl.substring(fileUrl.lastIndexOf("/") + 1));
+        }
+
+        // 文件大小和扫描信息
+        keyValue.put("计算机文件大小", file.getFileSize());
+        keyValue.put("扫描分辨率", "300dpi");
+        keyValue.put("扫描色彩模式", "彩色");
+
+        // 单位/分部/分项工程信息
+        keyValue.put("单位工程", trimLastComma(unitProjectString));
+        keyValue.put("单位工程编码", trimLastComma(unitProjectIdString));
+        keyValue.put("分部工程", trimLastComma(divisionProjectString));
+        keyValue.put("分部工程编码", trimLastComma(divisionProjectIdString));
+        keyValue.put("分项工程", trimLastComma(itemizedProjectString));
+        keyValue.put("分项工程编码", trimLastComma(itemizedProjectIdString));
+
+        // 关系默认值
+        keyValue.put("关系", "引用");
+
+        // 如果是竣工图
+        if ((currentNode.getIsBuiltDrawing() != null && currentNode.getIsBuiltDrawing() == 1) ||
+                (currentNode.getStorageType() != null && currentNode.getStorageType() == 2)) {
+            keyValue.put("图号", file.getDrawingNo());
+            keyValue.put("图幅", file.getSheetType());
+            keyValue.put("图表来源", file.getSheetSource());
+            keyValue.put("引用变更令 编号", file.getCiteChangeNumber());
+        }
+
+        // 存储类型处理
+        if (currentNode.getStorageType() != null) {
+            keyValue.put("业务事项", StorageTypeEnum.getByCode(currentNode.getStorageType()));
+        }
+
+        // 签名信息(只有当需要时处理,避免不必要查询)
+        if (isAdd) {
+            Task task = iTaskService.getTaskByFormDataId(file.getId().toString());
+            if (task != null) {
+                List<TaskParallel> taskParallelList = iTaskParallelService.queryApprovalUser(task.getProcessInstanceId());
+                if (taskParallelList != null && !taskParallelList.isEmpty()) {
+                    taskParallelList = taskParallelList.stream()
+                            .filter(taskParallel -> taskParallel.getEVisaStatus() == 1)
+                            .collect(Collectors.toList());
+
+                    if (!taskParallelList.isEmpty()) {
+                        // 处理签名信息
+                        StringBuffer nameString = new StringBuffer();
+                        StringBuffer dateString = new StringBuffer();
+                        List<Long> userIdList = new ArrayList<>();
+
+                        for (TaskParallel taskParallel : taskParallelList) {
+                            nameString.append(taskParallel.getTaskUserName()).append("、");
+                            dateString.append(taskParallel.getUpdateTime()).append("、");
+                            userIdList.add(Long.valueOf(task.getTaskUser()));
+                        }
+
+                        // 查询用户信息
+                        if (!userIdList.isEmpty()) {
+                            List<User> userList = iUserClient.userInfoByIds(userIdList);
+                            if (userList != null && !userList.isEmpty()) {
+                                List<String> postIds = userList.stream()
+                                        .map(User::getPostId)
+                                        .filter(Objects::nonNull)
+                                        .collect(Collectors.toList());
+
+                                R<List<String>> postNames = iSysClient.getPostNames(Func.join(postIds));
+                                if (postNames != null && postNames.getCode() == 200) {
+                                    keyValue.put("签名项", Func.join(postNames.getData()));
+                                }
+                            }
+                        }
+
+                        keyValue.put("签名者", trimLastComma(nameString));
+                        keyValue.put("签名时间", trimLastComma(dateString));
+                    }
+                }
+            }
+        }
+    }
+
+    // 辅助方法:去除字符串最后一个逗号/顿号
+    private String trimLastComma(StringBuffer buffer) {
+        if (buffer == null || buffer.length() == 0) return null;
+        return buffer.substring(0, buffer.length() - 1);
+    }
+
+    // 新增方法:记录批处理结果
+    private void logBatchResultsSimple(int[] results, String operation) {
+        int successCount = 0;
+        int failureCount = 0;
+        int affectedTotal = 0;
+
+        for (int rowCount : results) {
+            if (rowCount >= 0) {
+                successCount++;
+                affectedTotal += rowCount;
+            } else if (rowCount == Statement.EXECUTE_FAILED) {
+                failureCount++;
+            }
+        }
+
+        String msg = operation + " 操作结果: 成功批次 = " + successCount +
+                ", 失败批次 = " + failureCount +
+                ", 影响行数 = " + affectedTotal +
+                ", 总批次 = " + results.length;
+
+        if (failureCount == 0) {
+            log.error(msg);
+        } else {
+            log.error(msg);
+        }
+    }
+
+
 }

+ 1 - 0
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TaskServiceImpl.java

@@ -691,6 +691,7 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
                         jdbcTemplate.execute("update u_contract_log set status=3 where id='"+taskApp.getFormDataId()+"'");
                     }else if (taskApp.getApprovalType()==8) {
                         this.jdbcTemplate.execute("update u_entrust_info set status=1 where id=(SELECT wbs_id from u_information_query where id='"+taskApp.getFormDataId()+"')");
+                        this.jdbcTemplate.execute("update u_information_query set status=3 where id='"+taskApp.getFormDataId()+"'");
                     }else {
                         jdbcTemplate.execute("update u_information_query set e_visa_pdf_url='',status=3 where id='"+taskApp.getFormDataId()+"'");
                         InformationQuery informationQuery = informationQueryService.getById(taskApp.getFormDataId());

+ 41 - 20
blade-service/blade-business/src/main/java/org/springblade/business/utils/PDFUtil.java

@@ -8,12 +8,17 @@ import com.spire.pdf.PdfDocument;
 import com.spire.pdf.PdfPageBase;
 import com.spire.pdf.general.find.PdfTextFind;
 import com.spire.pdf.general.find.PdfTextFindCollection;
+import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.text.PDFTextStripper;
 import org.springblade.common.utils.CommonUtil;
 import org.springblade.core.tool.utils.Func;
 
+import java.io.File;
+import java.io.FileInputStream;
 import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.stream.Collectors;
 
 
 public class PDFUtil {
@@ -89,34 +94,50 @@ public class PDFUtil {
         table.addCell(cell);
     }
 
-    public static List<String> getPdfSignIds(String pdfUrl) {
-        PdfDocument pdf = new PdfDocument();
+    public static List<String>  getPdfSignIds(String pdfUr) {
         List<String> eVisaConfigList = new ArrayList<>();
-        try {
-            InputStream ossInputStream = CommonUtil.getOSSInputStream(pdfUrl);
-            //加载PDF文档
-            pdf.loadFromStream(ossInputStream);
-
-            for(int i= 0;i<pdf.getPages().getCount();i++){
-                PdfPageBase page = pdf.getPages().get(i);
-                PdfTextFindCollection allText = page.findAllText();
-                PdfTextFind[] finds = allText.getFinds();
-                for(int k=0;k<finds.length;k++){
-                    String textStr = finds[k].getMatchText();
-                    System.out.println(textStr);
-                    String[] textS = Func.toStrArray("\\|\\|",textStr);
-                    for(String txt : textS){
-                        if (txt.length() >= 15 && Func.isNumeric(txt)||(Func.isNumeric(txt)&&txt.length()==8&&txt.startsWith("123"))) {
-                            eVisaConfigList.add(txt);
+        try  {
+            InputStream inputStream = CommonUtil.getOSSInputStream(pdfUr);
+            PDDocument document = PDDocument.load(inputStream);
+            PDFTextStripper stripper = new PDFTextStripper();
+            String text = stripper.getText(document);
+            String[] lines = text.split("[ \\n]+");
+            for(int k=0;k<lines.length;k++){
+                String textStr = lines[k];
+                if(textStr.indexOf("*")>=0){
+                    textStr = textStr.substring(textStr.lastIndexOf("*")+1,textStr.length());
+                }
+
+                String[] textS = Func.toStrArray("\\|\\|",textStr);
+                for(String txt : textS){
+                    for (int i = 0; i < txt.length(); i++) {
+                        if (!Character.isDigit(txt.charAt(i))) {
+                            txt=txt.substring(0,i);
                         }
                     }
+                    if (txt.length() >= 15 && Func.isNumeric(txt)) {
+                        eVisaConfigList.add(txt);
+                    }
+                }
+
+                // 特殊处理
+                if(textStr.indexOf("1")>=0){
+                    String txt = textStr.substring(textStr.indexOf("1"));
+                    if (txt.length() >= 15 && Func.isNumeric(txt)) {
+                        System.out.println(txt);
+                        eVisaConfigList.add(txt);
+                    }
                 }
             }
-            ossInputStream.close();
+
+            List<String> unique = eVisaConfigList.stream().distinct().collect(Collectors.toList());
+            document.close();
+            return unique;
         }catch (Exception e){
             e.printStackTrace();
+            System.out.println("pdf大小为0");
+            return eVisaConfigList;
         }
-        return eVisaConfigList;
     }
 
 /*     public static void main(String[] args) {

+ 252 - 27
blade-service/blade-e-visa/src/main/java/org/springblade/evisa/controller/ArchiveController.java

@@ -5,10 +5,18 @@ import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.pdfbox.pdmodel.PDDocument;
 import org.apache.pdfbox.pdmodel.PDPage;
-import org.springblade.business.vo.TaskSignInfoVO;
-import org.springblade.evisa.service.EVDataService;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+import org.jsoup.select.Elements;
+import org.springblade.common.utils.SnowFlakeUtil;
+import org.springblade.core.oss.model.BladeFile;
+import org.springblade.core.tool.utils.Func;
+import org.springblade.core.tool.utils.IoUtil;
 import org.springblade.evisa.utils.FileUtils;
+import org.springblade.evisa.vo.ArchivesSplitInfoVO;
 import org.springblade.evisa.vo.TaskArchiveSplitVO;
+import org.springblade.resource.feign.NewIOSSClient;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.redis.core.StringRedisTemplate;
 import org.springframework.jdbc.core.BeanPropertyRowMapper;
@@ -17,8 +25,7 @@ import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.web.bind.annotation.RestController;
 
 import javax.annotation.Resource;
-import java.io.File;
-import java.io.InputStream;
+import java.io.*;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.CompletableFuture;
@@ -26,6 +33,7 @@ import java.util.concurrent.ThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
 
 import org.apache.pdfbox.rendering.PDFRenderer;
+
 import java.awt.image.BufferedImage;
 import javax.imageio.ImageIO;
 
@@ -47,34 +55,32 @@ public class ArchiveController {
     // jdbc
     private final JdbcTemplate jdbcTemplate;
 
-    //电签服务类
-    private final EVDataService evDataService;
+    private final NewIOSSClient newIOSSClient;
 
     // 线程池
     @Resource(name = "taskExecutor1")
     private ThreadPoolExecutor executor;
 
-    @Scheduled(cron = "0/10 * * * * ?")
+   @Scheduled(cron = "0 0/1 * * * ?")
     public void SignInfo() {
         //执行代码
 
-        log.info("扫描开始");
-
-        String sql = "SELECT a.id,a.archive_id as archiveId,a.file_url as fileUrl from u_archive_file a, u_task_split b where FIND_IN_SET(a.archive_id,b.ids) and b.type=3 ";
+        log.info("分解pdf专图片");
+        String sql = "SELECT distinct b.id,b.archive_id as archiveId ,b.file_url as fileUrl,c.id as taskId from u_archives_auto a , u_archive_file b ,u_task_split c  where a.id=b.archive_id and ((FIND_IN_SET(a.id,c.ids) and c.type=3) or (a.contract_id=c.contract_id and c.type=2)) and a.is_deleted=0 and b.is_deleted=0 and a.split_status not in(1,2) ";
         List<TaskArchiveSplitVO> query = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(TaskArchiveSplitVO.class));
 
         if (query != null && query.size() >= 1) {
             for (TaskArchiveSplitVO dataInfo : query) {
                 if (executor.getQueue().size() <= 10) {
-                    Boolean aBoolean = RedisTemplate.hasKey("sign-" + dataInfo.getArchiveId());
+                    Boolean aBoolean = RedisTemplate.hasKey("splitpng-" + dataInfo.getArchiveId());
                     if (!aBoolean) {
 
-                        if(!aBoolean){
-                            RedisTemplate.opsForValue().set("sign-" + dataInfo.getArchiveId(), "1", 7200, TimeUnit.SECONDS);
+                        if (!aBoolean) {
+                            RedisTemplate.opsForValue().set("splitpng-" + dataInfo.getArchiveId(), "1", 7200, TimeUnit.SECONDS);
                             CompletableFuture<Void> runAsync = CompletableFuture.runAsync(() -> {
                                 try {
                                     /*===============执行批量任务===============*/
-                                    signTaskBatch(dataInfo);
+                                    signTaskBatchpngToHtml(dataInfo);
                                 } catch (Exception e) {
                                     e.printStackTrace();
                                 }
@@ -84,31 +90,217 @@ public class ArchiveController {
                 }
             }
         }
-
-        System.out.println("队列数量" + executor.getQueue().size());
-        System.out.println("活跃数量" + executor.getActiveCount());
-        System.out.println("总共数量" + executor.getTaskCount());
-        System.out.println("完成数量" + executor.getCompletedTaskCount());
+        System.out.println("队列数量_img2" + executor.getQueue().size());
+        System.out.println("活跃数量_img2" + executor.getActiveCount());
+        System.out.println("总共数量_img2" + executor.getTaskCount());
+        System.out.println("完成数量_img2" + executor.getCompletedTaskCount());
     }
 
-    public void signTaskBatch(TaskArchiveSplitVO taskSign) {
+    // 分解第一页的任务
+    public void signTaskBatchpngToHtml(TaskArchiveSplitVO taskSign) {
         try {
             String fileUrl = taskSign.getFileUrl();
             String archiveId = taskSign.getArchiveId();
             String id = taskSign.getId();
-            // 获取pdf第一页的数据
-            String firstUrl = FileUtils.getSysLocalFileUrl()+"archiveSplit/"+archiveId+"_001.pdf";
-            getPdfByPage(2,2,fileUrl,firstUrl);
+            String taskId = taskSign.getTaskId();
+
+            // 获取pdf第二页的数据
+            String firstUrl = FileUtils.getSysLocalFileUrl() + "archiveSplit/" + archiveId + "_001.pdf";
+            File file = new File(firstUrl);
+            if (!file.exists()) {
+                getPdfByPage(2, 2, fileUrl, firstUrl);
+            }
+
             // 保存第一页为300DPI图片
             String imagePath = FileUtils.getSysLocalFileUrl() + "archiveSplit/" + archiveId + "_001.png";
-            savePdfAsImage(1, firstUrl, imagePath);
+            File imgfile = new File(imagePath);
+            if (!imgfile.exists()) {
+                savePdfAsImage(1, firstUrl, imagePath);
+            }
+
+            //判断
+            List<Map<String, Object>> mapList = jdbcTemplate.queryForList("select * from u_archives_split_info where id=" + id + "");
+            if (mapList != null && Func.isNotEmpty(mapList) && mapList.size() >= 1) {
+                String status = mapList.get(0).get("status") + "";
+                if (status.equals("3")) {
+                    String updateSql = "update u_archives_auto set split_status=1 where id=" + id;
+                    jdbcTemplate.execute(updateSql);
+                }
+            } else {
+                String sql22 = "insert into u_archives_split_info(id,status,file_url,first_file_url,task_id,archive_id,create_time) VALUES(" + id + ",2,'" + fileUrl + "','" + imagePath + "'," + taskId + "," + archiveId + ",SYSDATE())";
+                jdbcTemplate.execute(sql22);
+                String updateSql = "update u_archives_auto set split_status=2 where id=" + id;
+                jdbcTemplate.execute(updateSql);
+            }
+            RedisTemplate.delete("splitpng-" + archiveId);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+
+    @Scheduled(cron = "0/30 * * * * ?")
+    public void SplitPdfInfo() {
+        //执行代码
+
+        log.info("分解html开始");
+        String sql = "select  * from u_archives_split_info where status =2 "; // and TIMESTAMPDIFF(MINUTE, create_time, NOW()) >=3";
+        List<ArchivesSplitInfoVO> query = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(ArchivesSplitInfoVO.class));
+
+        if (query != null && query.size() >= 1) {
+            for (ArchivesSplitInfoVO dataInfo : query) {
+                if (executor.getQueue().size() <= 10) {
+                    Boolean aBoolean = RedisTemplate.hasKey("splithtml-" + dataInfo.getArchiveId());
+                    if (!aBoolean) {
+
+                        if (!aBoolean) {
+                            RedisTemplate.opsForValue().set("splithtml-" + dataInfo.getArchiveId(), "1", 600, TimeUnit.SECONDS);
+                            CompletableFuture<Void> runAsync = CompletableFuture.runAsync(() -> {
+                                try {
+                                    /*===============执行批量任务===============*/
+                                    signTaskBatchpng(dataInfo);
+                                } catch (Exception e) {
+                                    e.printStackTrace();
+                                }
+                            }, executor);
+                        }
+                    }
+                }
+            }
+        }
+        System.out.println("队列数量_html" + executor.getQueue().size());
+        System.out.println("活跃数量_html" + executor.getActiveCount());
+        System.out.println("总共数量_html" + executor.getTaskCount());
+        System.out.println("完成数量_html" + executor.getCompletedTaskCount());
+    }
 
+    public void signTaskBatchpng(ArchivesSplitInfoVO taskSign) {
+        try {
+            String archiveId = taskSign.getArchiveId();
+            String fileUlr = taskSign.getFileUrl();
+            String firstPage = FileUtils.getSysLocalFileUrl() + "archiveSplit/";
+            int bkb = 0 ;
+            //将imagePath 的数据转成一个可解析的html
+            String htmlUrl = pngToHtml(firstPage, archiveId);
+            /*String htmlUrl2 = pngToHtml(firstPage, archiveId);
+            String htmlUrl = "";
+            if (htmlUrl1.equals(htmlUrl2) && htmlUrl1.indexOf("_001.html") >= 0 && htmlUrl1.indexOf("archiveSplit") >= 0) {
+                htmlUrl = htmlUrl2;
+            }*/
+
+            if (htmlUrl.indexOf("_001.html") >= 0 && htmlUrl.indexOf("archiveSplit") >= 0) {
+                String htmlString = IoUtil.readToString(new FileInputStream(htmlUrl));
+                Document doc = Jsoup.parse(htmlString);
+                Element table = doc.select("table").first();
+                Elements trs = table.select("tr");
+
+                for (int i = 1; i <= trs.size() - 1; i++) {
+                    Element tr = trs.get(i);
+                    String zrz = tr.select("td").get(0).text();
+                    String wjtm = tr.select("td").get(1).text();
+                    String rq = tr.select("td").get(2).text();
+                    String ym = tr.select("td").get(3).text();
+                    int startYm = 0;
+                    int endYm = 0;
+                    if(i<trs.size()-1){
+                        startYm = Func.toInt(ym);
+                        String enData = trs.get(i+1).select("td").get(3).text();
+                        if(enData.indexOf("-")>=0){
+                            endYm = Func.toInt(enData.split("-")[0])-1;
+                        }else{
+                            endYm = Func.toInt(enData)-1;
+                        }
+                    }else{
+                        if(ym.indexOf("-")>=0){
+                            String[] split = ym.split("-");
+                            startYm = Func.toInt(split[0]);
+                            endYm = Func.toInt(split[1]);
+                        }
+                    }
+                    startYm = startYm + 2 ;
+                    endYm = endYm + 2 ;
+                    System.out.println(zrz + " " + wjtm + " " + rq + " " + ym);
+                    // 分解文件
+                    String fmlUrl = FileUtils.getSysLocalFileUrl() + "archiveSplit/"+archiveId+"_cf_00"+i+".pdf";
+                    getPdfByPage(startYm,endYm,fileUlr,fmlUrl);
+                    saveDataToMysql(fmlUrl,wjtm,taskSign.getId(),endYm-startYm+1);
+                    bkb =  endYm ;
+                }
+
+            } else {
+
+            }
+
+            // 添加封面信息
+            String fmlUrl = FileUtils.getSysLocalFileUrl() + "archiveSplit/"+archiveId+"_fm_001.pdf";
+            getPdfByPage(1,1,fileUlr,fmlUrl);
+            saveDataToMysql(fmlUrl,"封面",taskSign.getId(),1);
+
+            // 卷内目录
+            String jnmuUrl = FileUtils.getSysLocalFileUrl() + "archiveSplit/"+archiveId+"_jnml_001.pdf";
+            getPdfByPage(2,2,fileUlr,jnmuUrl);
+            saveDataToMysql(jnmuUrl,"卷内目录",taskSign.getId(),1);
+
+            // 卷内备考表
+            String jnbkbUrl = FileUtils.getSysLocalFileUrl() + "archiveSplit/"+archiveId+"_jnbkb_001.pdf";
+            getPdfByPage(bkb+1,bkb+1,fileUlr,jnbkbUrl);
+            saveDataToMysql(jnbkbUrl,"卷内备考表",taskSign.getId(),1);
+
+            // 修改任务状态
+            String updateSql = "update u_archives_split_info set status=3 where id=" + taskSign.getId();
+            jdbcTemplate.execute(updateSql);
+            // 修改 u_archives_auto 为 已经分解
+            String updateSqlAuto = "update u_archives_auto set split_status=1 where id=" + taskSign.getArchiveId();
+            jdbcTemplate.execute(updateSqlAuto);
+
+            // 统计各个任务的结果
+            String taxkSql = "UPDATE u_task_split a set finished = (SELECT count(1) from u_archives_auto b where FIND_IN_SET(b.id,a.ids) and b.split_status=1) where FIND_IN_SET("+taskSign.getArchiveId()+",a.ids)  and a.type=3";
+            String taxkSql2 = "UPDATE u_task_split a set finished = (SELECT count(1) from u_archives_auto b where a.contract_id=b.contract_id) where a.id="+taskSign.getTaskId()+" and a.type=2";
+            jdbcTemplate.execute(taxkSql);
+            jdbcTemplate.execute(taxkSql2);
+
+            // 修改完成情况
+
+            RedisTemplate.delete("splithtml-" + archiveId);
         } catch (Exception e) {
             throw new RuntimeException(e);
         }
     }
 
-    public void getPdfByPage(int startPage, int endPage, String filePath, String savePath) {
+    public static String pngToHtml(String fileUrl, String pKeyId) {
+        String lasHhtmlUrl = "";
+        try {
+            // 定义Python解释器路径和脚本路径
+            String pythonScript = "/Users/hongchuangyanfa/Desktop/PycharmProjects/splitPngToHtml.py";
+            // 构建命令
+            ProcessBuilder pb = new ProcessBuilder("python3", pythonScript, fileUrl, pKeyId);
+            Process process = pb.start();
+
+            // 读取Python脚本输出
+            BufferedReader reader = new BufferedReader(
+                    new InputStreamReader(process.getInputStream()));
+            String htmlUrl;
+            while ((htmlUrl = reader.readLine()) != null) {
+                System.out.println("222" + htmlUrl);
+                if (htmlUrl.indexOf("html文件路径") >= 0 && htmlUrl.indexOf("_001.html") >= 0 && htmlUrl.indexOf("archiveSplit") >= 0) {
+                    lasHhtmlUrl = htmlUrl.replace("html文件路径", "");
+                }
+            }
+            // 等待进程结束
+            int exitCode = process.waitFor();
+            if (exitCode == 0) {
+                return lasHhtmlUrl;
+            } else {
+                return "1";
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            return "1";
+        }
+    }
+
+
+    public static void getPdfByPage(int startPage, int endPage, String filePath, String savePath) {
         try {
             InputStream inputStreamByUrl = FileUtils.getInputStreamByUrl(filePath);
             // 加载PDF文件
@@ -152,18 +344,51 @@ public class ArchiveController {
             final int DPI = 300;
 
             // 渲染指定页面(注意PDFBox使用0-based索引)
-            BufferedImage image = renderer.renderImage(pageNum - 1, DPI / 72f);
-
+            //BufferedImage image = renderer.renderImage(pageNum - 1, DPI / 72f);
+            BufferedImage image = renderer.renderImageWithDPI(0, DPI); // 0 表示第一页
             // 确保输出目录存在
             File outputFile = new File(outputPath);
             outputFile.getParentFile().mkdirs();
 
             // 保存为PNG格式(可改为JPG等)
             ImageIO.write(image, "PNG", outputFile);
+
             log.info("PDF页面已成功保存为图片: {}", outputPath);
+            inputStream.close();
+            document.close();
         } catch (Exception e) {
             log.error("PDF转图片失败", e);
             throw new RuntimeException("PDF转图片失败", e);
         }
     }
+
+    public int saveDataToMysql(String upFileUrl,String fileName,String fileId,int filePage) {
+        // 获取封面信息
+        long newPkId = SnowFlakeUtil.getId(); //主键Id
+        File fmfile = new File(upFileUrl);
+        if (fmfile.exists()) {
+            BladeFile bladeFile = this.newIOSSClient.uploadFile(fileName+".pdf", upFileUrl);
+            if (bladeFile != null && Func.isNotEmpty(bladeFile.getLink())) {
+                String FmPdfUrl = bladeFile.getLink();
+                String sql = " insert into u_archive_file( " +
+                        " id,project_id,contract_id,node_id,file_number,file_name,file_time,file_url,pdf_file_url,file_page,is_approval,is_certification,is_need_certification,duty_user,create_user,create_dept,create_time,update_user,update_time,status,is_deleted,sheet_type,sheet_source, " +
+                        " drawing_no,cite_change_number,certification_time,e_visa_file,node_ext_id,file_type,archive_id,origin_id,filming_time,filmingor_time,tag_id,pic_code,refer_code,film_code,width,height,ftime,utime,del_time,sort,box_name,box_number,is_auto_file,is_archive,page_num, " +
+                        " file_size,source_type,is_element,pdf_page_url,fid,rectification,classify,m_wbs_tree_contract_p_key_id,u_image_classification_file_id,archive_file_storage_type,node_tree_structure,date_name,archive_file_stroage_type,out_id,sort_num " +
+                        "   ) " +
+                        " SELECT "+newPkId+",project_id,contract_id,node_id,file_number,'" + fileName + "',file_time,'" + FmPdfUrl + "','" + FmPdfUrl + "',"+filePage+",is_approval,is_certification,is_need_certification,duty_user,create_user,create_dept,create_time,update_user,update_time,status,is_deleted,sheet_type,sheet_source, " +
+                        "        drawing_no,cite_change_number,certification_time,e_visa_file,node_ext_id,file_type,archive_id,origin_id,filming_time,filmingor_time,tag_id,pic_code,refer_code,film_code,width,height,ftime,utime,del_time,sort,box_name,box_number,is_auto_file,is_archive,page_num, " +
+                        "        file_size,source_type,is_element,pdf_page_url,fid,rectification,classify,m_wbs_tree_contract_p_key_id,u_image_classification_file_id,archive_file_storage_type,node_tree_structure,date_name,archive_file_stroage_type,out_id,sort_num " +
+                        " from u_archive_file where id=" + fileId;
+                System.out.println(fileName + "----" + sql);
+                jdbcTemplate.execute(sql);
+                return 200;
+            } else {
+                // 检查一下oss是否启动
+                System.out.println("oss服务未启动,无法上传文件到oss");
+                return 500;
+            }
+        }else{
+            return 404;
+        }
+    }
 }

+ 1 - 1
blade-service/blade-e-visa/src/main/java/org/springblade/evisa/controller/EVController.java

@@ -58,7 +58,7 @@ public class EVController {
     @Resource(name = "taskExecutor1")
     private ThreadPoolExecutor executor;
 
-    @Scheduled(cron = "0/10 * * * * ?")
+   // @Scheduled(cron = "0/10 * * * * ?")
     public void SignInfo() {
         //执行代码
 

+ 8 - 1
blade-service/blade-e-visa/src/main/java/org/springblade/evisa/service/impl/EVDataServiceImpl.java

@@ -335,7 +335,7 @@ public class EVDataServiceImpl implements EVDataService {
                     if (taskApp.getSigType() == 2) {
                         this.jdbcTemplate.execute("update u_entrust_info set sample_status=2,status=" + (taskApp.getSigType() + 1) + ",entrust_e_pdf='" + taskApp.getLastFilePdfUrl() + "' where id=(SELECT wbs_id from u_information_query where id='" + taskApp.getFormDataId() + "')");
                     }
-                    updateSql = "update u_information_query set e_visa_pdf_url='" + taskApp.getLastFilePdfUrl() + "',status=" + taskApp.getSigType() + " where id='" + taskApp.getFormDataId() + "'";
+                    updateSql = "update u_information_query set e_visa_pdf_url='" + taskApp.getLastFilePdfUrl() + "',status=" + taskApp.getSigType() + ",business_time='" + taskApp.getPdfDate() + "' where id='" + taskApp.getFormDataId() + "'";
                 }
                 this.jdbcTemplate.execute(updateSql);
                 System.out.println("u_information_query修改语句:"+updateSql);
@@ -378,6 +378,13 @@ public class EVDataServiceImpl implements EVDataService {
                 String eVisaPdfUrl = map.get("e_visa_pdf_url") + ""; //签字的PDF路径
                 String pdfUrl = map.get("pdf_url") + ""; //合并后的PDF路径
                 String type = map.get("type") + ""; //资料类型,1资料填报,2试验,3首件
+                Object status = map.get("status");
+                if (status != null && status.toString().equals("3")) {
+                     this.jdbcTemplate.execute("delete from u_task_batch where id in(" + taskApp.getId()+")");
+                     RedisTemplate.delete("sign-" + taskApp.getFormDataId());
+                     taskApp.setSigState(2);
+                     return;
+                }
                 taskApp.setPdfDataType(type);
                 if (StringUtils.isNotEmpty(pdfTrialUrlPosition) || StringUtils.isNotEmpty(pdfTrialUrl) || StringUtils.isNotEmpty(eVisaPdfUrl) || StringUtils.isNotEmpty(pdfUrl)) {
                     if ("1".equals(type)) {

+ 34 - 8
blade-service/blade-e-visa/src/main/java/org/springblade/evisa/utils/PDFUtils.java

@@ -1,16 +1,17 @@
 package org.springblade.evisa.utils;
 
 import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.pdmodel.PDPage;
 import org.apache.pdfbox.text.PDFTextStripper;
 import org.springblade.business.vo.TaskSignInfoVO;
 import org.springblade.common.utils.CommonUtil;
 import org.springblade.core.tool.utils.Func;
 
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.InputStream;
+import java.io.*;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Optional;
+import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 
@@ -23,7 +24,9 @@ public class PDFUtils {
             PDFTextStripper stripper = new PDFTextStripper();
             String text = stripper.getText(document);
             String[] lines = text.split("[ \\n]+");
-            String regex = "^\\d{4}年\\d{2}月\\d{2}日$";
+            String lastDate = getPdfFirstPageLastDate(document);
+            taskApp.setPdfDate(lastDate);
+            Pattern pattern = Pattern.compile("(\\d{4}[年-]\\d{2}[月-]\\d{2}日?)");
 
             for(int k=0;k<lines.length;k++){
                 String textStr = lines[k];
@@ -41,10 +44,11 @@ public class PDFUtils {
                     if (txt.length() >= 15 && Func.isNumeric(txt)||(Func.isNumeric(txt)&&txt.length()==8&&txt.startsWith("123"))) {
                         eVisaConfigList.add(txt);
                     }
-
-                    Pattern pattern = Pattern.compile(regex);
-                    if(pattern.matcher(txt).matches()){
-                        taskApp.setPdfDate(txt);
+                    if (taskApp.getPdfDate() == null || taskApp.getPdfDate().isEmpty()) {
+                        Matcher matcher = pattern.matcher(txt);
+                        if(matcher.matches()){
+                            taskApp.setPdfDate(matcher.group(1));
+                        }
                     }
                 }
 
@@ -123,4 +127,26 @@ public class PDFUtils {
         }
     }
 
+    public static String getPdfFirstPageLastDate(PDDocument document) throws IOException {
+        PDFTextStripper stripper = new PDFTextStripper();
+        stripper.setStartPage(1);
+        stripper.setEndPage(1);
+        String text = stripper.getText(document);
+        Pattern pattern = Pattern.compile("(\\d{4}[-年.]\r?\n?\\d{2}[-月.]\r?\n?\\d{2}日?)");
+        Matcher matcher = pattern.matcher(text);
+        List<String> dates = new ArrayList<>();
+        while (matcher.find()) {
+            dates.add(matcher.group(1));
+        }
+        if (!dates.isEmpty()) {
+            Optional<String> max = dates.stream().map(item -> {
+                String replace = item.replace("年", "-").replace("月", "-").replace("日", "").replaceAll("\\.", "-");
+                return replace.replaceAll("[\r\n]",  "");
+            }).max(String::compareTo);
+            return max.get();
+        } else {
+            return "";
+        }
+    }
+
 }

+ 27 - 5
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ArchiveTreeContractController.java

@@ -16,6 +16,7 @@
  */
 package org.springblade.manager.controller;
 
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.mixsmart.utils.StringUtils;
 import io.swagger.annotations.*;
 import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
@@ -47,6 +48,8 @@ import org.springblade.manager.service.IContractInfoService;
 import org.springblade.manager.service.impl.ArchiveTreeContractSyncImpl;
 import org.springblade.manager.vo.*;
 
+import org.springframework.jdbc.core.BeanPropertyRowMapper;
+import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.bind.annotation.RequestParam;
 import com.baomidou.mybatisplus.core.metadata.IPage;
@@ -82,6 +85,7 @@ public class ArchiveTreeContractController extends BladeController {
     private final ArchiveTreeContractSyncImpl archiveTreeContractSync;
 
     private final IContractInfoService contractInfoService;
+    private final JdbcTemplate jdbcTemplate;
 
     /**
      * 详情
@@ -90,7 +94,22 @@ public class ArchiveTreeContractController extends BladeController {
     @ApiOperationSupport(order = 1)
     @ApiOperation(value = "详情", notes = "传入archiveTreeContract")
     public R<ArchiveTreeContract> detail(ArchiveTreeContract archiveTreeContract) {
-        ArchiveTreeContract detail = archiveTreeContractService.getOne(Condition.getQueryWrapper(archiveTreeContract));
+        ArchiveTreeContract detail = archiveTreeContractService.getOne(Wrappers.lambdaQuery(ArchiveTreeContract.class).eq(ArchiveTreeContract::getId,archiveTreeContract.getId()));
+        Long contractId1 = detail.getContractId();
+        if(contractId1==null){
+            contractId1=archiveTreeContract.getContractId();
+        }
+        String sql="select * from m_contract_info where id="+contractId1;
+        ContractInfo info = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<>(ContractInfo.class));
+        if(detail.getRollor()==null&&info!=null&&info.getFiler()!=null){
+            detail.setRollor(info.getFiler());
+        }
+        if(detail.getReviewer()==null&&info!=null&&info.getReviewer()!=null){
+            detail.setReviewer(info.getReviewer());
+        }
+        if(detail.getFileNumberPrefix()==null&&info!=null&&info.getPrefix()!=null){
+            detail.setFileNumberPrefix(info.getPrefix());
+        }
         return R.data(detail);
     }
 
@@ -138,7 +157,10 @@ public class ArchiveTreeContractController extends BladeController {
     @PostMapping("/update")
     @ApiOperationSupport(order = 5)
     @ApiOperation(value = "修改", notes = "传入archiveTreeContract")
-    public R update(@Valid @RequestBody ArchiveTreeContract archiveTreeContract) {
+    /**
+     * isSaveChild 0是保存子节点,1不保存子节点
+     */
+    public R update(@Valid @RequestBody ArchiveTreeContractDTO archiveTreeContract) {
         if (archiveTreeContract == null) {
             return R.fail(200, "未查询到对应节点信息");
         }
@@ -203,9 +225,9 @@ public class ArchiveTreeContractController extends BladeController {
 
         boolean b = archiveTreeContractService.updateById(ar);
         //更新下级节点为同一规则
-
-        archiveTreeContractService.updateAllSonNodeIdsForArchiveAutoRule(ar);
-
+        if(archiveTreeContract.getIsSaveChild()!=null&&archiveTreeContract.getIsSaveChild()==0){
+            archiveTreeContractService.updateAllSonNodeIdsForArchiveAutoRule(ar);
+        }
         return R.status(b);
     }
 

+ 197 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ExcelTabController.java

@@ -3015,6 +3015,203 @@ public class ExcelTabController extends BladeController {
         return R.data(resultMapList);
     }
 
+    /**
+     * 获取新增时的表头数据
+     * @param theLogId
+     * @param nodePrimaryKeyId
+     * @param recordTime
+     * @param contractId
+     * @return
+     * @throws Exception
+     */
+    @GetMapping("/getAddTheLogBusinessData")
+    @ApiOperationSupport(order = 26)
+    @ApiOperation(value = "获取新增表格的默认值")
+    @ApiImplicitParams({
+        @ApiImplicitParam(name = "theLogId", value = "日志记录的ids,可能为空(多张表)"),
+        @ApiImplicitParam(name = "nodePrimaryKeyId", value = "当前操作的日志类型ID,即左侧列表的节点primaryKeyId"),
+        @ApiImplicitParam(name = "recordTime", value = "当前选择的填写日期,即右侧日期控件所选日期,格式为 yyyy-MM-dd"),
+        @ApiImplicitParam(name = "contractId", value = "合同段id")
+    })
+    public R<Map<String, Object>> getAddTheLogBusinessData(String theLogId, String nodePrimaryKeyId, String recordTime, String contractId) throws Exception {
+        Map<String, Object> resultMapList = new HashMap<>();
+        //数据结果
+        String logId2 = "";
+        //获取对应的记录
+        String dataIds;
+        if (StringUtils.isNotEmpty(theLogId)) {
+            String[] split = theLogId.split(",");
+            List<String> ids = new LinkedList<>();
+            for (String logId : split) {
+                ContractLog contractLog = this.contractLogClient.queryContractLogByIdToObj(logId);
+                ids.add(contractLog.getDataId().toString());
+            }
+            dataIds = ids.stream().filter(Objects::nonNull).collect(Collectors.joining(","));
+        } else {
+            List<ContractLog> contractLogs = this.contractLogClient.queryContractLogByPrimaryKeyIdAndRecordTimeList(nodePrimaryKeyId, recordTime, contractId,null);
+            if (contractLogs.size() == 0) {
+                logId2 = "";
+            } else {
+                logId2 = contractLogs.get(0).getId() + "";
+            }
+            dataIds = contractLogs.stream().map(ContractLog::getDataId).filter(Objects::nonNull).map(String::valueOf).collect(Collectors.joining(","));
+        }
+        WbsTreePrivate node;
+        WbsTreePrivate tableNode2;
+        try{
+            node = this.wbsTreePrivateService.getOne(Wrappers.<WbsTreePrivate>lambdaQuery().eq(WbsTreePrivate::getPKeyId, nodePrimaryKeyId));
+            tableNode2= this.wbsTreePrivateService.getOne(Wrappers.<WbsTreePrivate>lambdaQuery()
+                .eq(WbsTreePrivate::getParentId, node.getId()).eq(WbsTreePrivate::getProjectId, node.getProjectId()));
+        } catch (Exception e) {
+            throw new ServiceException("表单重复,请确认表单");
+        }
+        if (StringUtils.isNotEmpty(dataIds)) {
+            if (dataIds.startsWith(",")) {
+                dataIds = dataIds.substring(1);
+            }
+            String[] ids = dataIds.split(",");
+            //检查实体表是否存在
+            String tabName = tableNode2.getInitTableName();
+            String isExitSql = " select * from information_schema.TABLES where TABLE_NAME='" + tabName + "'";
+            List<Map<String, Object>> tabList = this.jdbcTemplate.queryForList(isExitSql);
+            if (tabList.size() <= 0) {
+                return R.fail("无实体表对应");
+            }
+            //查询数据
+            String querySql = "SELECT * FROM " + tabName + " WHERE id = " + ids[0] + " and group_id = " + tableNode2.getPKeyId();
+            List<Map<String, Object>> businessDataMap = this.jdbcTemplate.queryForList(querySql);
+            Map<String, Object> reData=new HashMap<>();
+            if (businessDataMap.size() > 0){
+                try {
+                    if (tableNode2.getHtmlUrl() != null){
+                        InputStream inputStreamByUrl = FileUtils.getInputStreamByUrl(tableNode2.getHtmlUrl());
+                        String htmlString = IoUtil.readToString(inputStreamByUrl);
+                        Document doc = Jsoup.parse(htmlString);
+                        List<Elements> allElements = getBiaoTou(doc);
+                        if(allElements.size()>0){
+                            for (String key : businessDataMap.get(0).keySet()) {
+                                String tabVal = businessDataMap.get(0).get(key) + "";
+                                // 时间段处理
+                                if (StringUtils.isNotEmpty(tabVal) && !tabVal.equals("null")) {
+                                    if (tabVal.indexOf("T") >= 0 && tabVal.indexOf(".000Z]") >= 0) {
+                                        String[] tabData = tabVal.split("_\\^_");
+                                        if (reData.containsKey("pickerKey")) {
+                                            String pickerKey = reData.get("pickerKey") + "," + key + "__" + tabData[1];
+                                            reData.put("pickerKey", pickerKey);
+                                        } else {
+                                            reData.put("pickerKey", key + "__" + tabData[1]);
+                                        }
+                                        String sql = tabData[0];
+                                        sql = sql.replaceAll("\\[", "['");
+                                        sql = sql.replaceAll("]", "']");
+                                        sql = sql.replaceAll("000Z,", "000Z',");
+                                        sql = sql.replaceAll(", 20", ", '20");
+                                        sql = sql.replaceAll("'", "");
+                                        reData.put(key + "__" + tabData[1], sql);
+                                    } else if (tabVal.indexOf("T") >= 0 && tabVal.indexOf(".000Z") >= 0) { //时间
+                                        String[] tabData = tabVal.split("_\\^_");
+                                        reData.put(key + "__" + tabData[1], tabData[0]);
+                                    } else if (tabVal.indexOf("☆") >= 0) {
+                                        String[] mysql = tabVal.split("☆");
+                                        for (String data : mysql) {
+                                            String[] tabData = data.split("_\\^_");
+                                            reData.put(key + "__" + tabData[1], tabData[0]);
+                                        }
+                                    } else if (tabVal.indexOf("_^_") >= 0) { //数组处理方式
+                                        String[] tabData = tabVal.split("_\\^_");
+                                        if (StringUtils.isNotEmpty(tabData[0])) {
+                                            if (tabVal.contains("[") && tabVal.contains("年")) {
+                                                String[] strings = StringUtils.strip(tabData[0], "[]").split(",");
+                                                reData.put(key + "__" + tabData[1], strings);
+                                            }
+                                            if (tabVal.contains("[") && tabVal.contains("]") && tabVal.indexOf(",") >= 0) {
+                                                String[] strings = StringUtils.strip(tabData[0], "[]").split(",");
+                                                reData.put(key + "__" + tabData[1], strings);
+                                            } else {
+                                                if (tabVal.contains("[") && tabVal.contains("]")) {
+                                                    String[] strings = new String[]{tabData[0].replaceAll("\\[","").replaceAll("]","")};
+                                                    reData.put(key + "__" + tabData[1],strings);
+                                                } else {
+                                                    reData.put(key + "__" + tabData[1], tabData[0]);
+                                                }
+                                            }
+                                        }
+                                    } else {
+                                        reData.put(key, tabVal);
+                                    }
+                                }
+                            }
+                            for (Elements element : allElements) {
+                                for (Element element1 : element) {
+                                    if(reData.containsKey(element1.attr("keyname"))){
+                                        resultMapList.put(element1.attr("keyname"),reData.get(element1.attr("keyname")));
+                                    }
+                                }
+                            }
+                        }
+                    }
+                } catch (Exception e) {
+                    throw new RuntimeException(e);
+                }
+            }
+        }
+        return R.data(resultMapList);
+    }
+
+    public List<Elements> getBiaoTou(Document doc){
+        // 模糊匹配
+        Elements cbdw = doc.select("el-select[placeholder*=承包单位]");
+        Elements cbdw1 = doc.select("el-input[placeholder*=承包单位]");
+        Elements htd = doc.select("el-select[placeholder*=合同段]");
+        Elements htd1 = doc.select("el-input[placeholder*=合同段]");
+        Elements jldw = doc.select("el-input[placeholder*=监理单位]");
+        Elements jljg = doc.select("el-select[placeholder*=监理机构]");
+        Elements jljg1 = doc.select("el-input[placeholder*=监理机构]");
+        Elements jlr = doc.select("el-input[placeholder*=记录人]");
+        Elements rq = doc.select("el-date-picker[placeholder*=日期]");
+        Elements shr = doc.select("el-input[placeholder*=审核人]");
+        Elements tqqk = doc.select("el-input[placeholder*=天气情况]");
+        Elements dwgc = doc.select("el-input[placeholder*=单位工程]");
+        Elements fxgc = doc.select("el-input[placeholder*=分项工程]");
+        Elements fbgc = doc.select("el-input[placeholder*=分部工程]");
+        Elements zh = doc.select("el-input[placeholder*=桩号]");
+        Elements bw = doc.select("el-input[placeholder*=部位]");
+        Elements xq = doc.select("el-select[placeholder*=星期]");
+        Elements tq = doc.select("el-input[placeholder*=天气]");
+        Elements qw = doc.select("el-input[placeholder*=气温_最高]");
+        Elements qw1 = doc.select("el-input[placeholder*=气温_最低]");
+        Elements sgdw = doc.select("el-input[placeholder*=施工单位]");
+        Elements hth = doc.select("el-input[placeholder*=合同号]");
+        Elements bh = doc.select("el-input[placeholder*=编号]");
+        List<Elements> allElements=new ArrayList<>();
+        allElements.add(cbdw);
+        allElements.add(cbdw1);
+        allElements.add(htd);
+        allElements.add(htd1);
+        allElements.add(jldw);
+        allElements.add(jljg);
+        allElements.add(jljg1);
+        allElements.add(jlr);
+        allElements.add(rq);
+        allElements.add(shr);
+        allElements.add(tqqk);
+        allElements.add(dwgc);
+        allElements.add(fxgc);
+        allElements.add(fbgc);
+        allElements.add(zh);
+        allElements.add(bw);
+        allElements.add(xq);
+        allElements.add(tq);
+        allElements.add(qw);
+        allElements.add(qw1);
+        allElements.add(sgdw);
+        allElements.add(hth);
+        allElements.add(bh);
+        return allElements.stream().filter(o->o!=null&&o.size()>0).distinct().collect(Collectors.toList());
+    }
+
+
+
     /**
      * 复制指定日期的日志填报数据
      */

+ 2 - 2
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/SignConfigController.java

@@ -63,8 +63,8 @@ public class SignConfigController extends BladeController {
     @GetMapping("/list")
     @ApiOperationSupport(order = 2)
     @ApiOperation(value = "分页", notes = "传入excelTab")
-    public R<IPage<SignConfigVO>> list(@ApiParam(value = "岗位id") @RequestParam(required = false) Long roleId, @ApiParam(value = "搜索keyword") @RequestParam(required = false) String keyword, Query query) {
-        return R.data(signConfigService.selectPageByRoleId(Condition.getPage(query), roleId, keyword));
+    public R<IPage<SignConfigVO>> list(@ApiParam(value = "岗位id") @RequestParam(required = false) Long roleId, @ApiParam(value = "搜索keyword") @RequestParam(required = false) String keyword, Query query, @RequestParam() Integer type) {
+        return R.data(signConfigService.selectPageByRoleId(Condition.getPage(query), roleId, keyword, type));
     }
 
     /**

+ 3 - 1
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/SystemMsgController.java

@@ -47,7 +47,9 @@ public class SystemMsgController extends BladeController {
     @ApiOperationSupport(order = 1)
     @ApiOperation(value = "新增", notes = "传入版本信息")
     public R add(@Valid @RequestBody SystemMsg systemMsg){
-        systemMsg.setPushDateTime(systemMsg.getPushDateTime().with(ChronoField.SECOND_OF_MINUTE, 0));
+        //systemMsg.setPushDateTime(systemMsg.getPushDateTime().with(ChronoField.SECOND_OF_MINUTE, 0));
+
+        systemMsg.setPushDateTime(systemMsg.getPushDateTime());
         //如果新增的是更新公告,则校验是否已经存在更新公告
         if (systemMsg.getMsgType() == 1) {
             List<SystemMsg> list = systemMsgService.list(new LambdaQueryWrapper<SystemMsg>()

+ 1 - 1
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/TableFileController.java

@@ -126,7 +126,7 @@ public class TableFileController extends BladeController {
             }
             excelTabService.getBussPdfs(wbsTreeContractP.getPKeyId() + "", classfy, wbsTreeContract.getContractId(), wbsTreeContract.getProjectId());
         }
-        if (tableFile.getType() == 20 || tableFile.getType() == 21||tableFile.getType() == 22) {
+        if (tableFile.getType() == 20 || tableFile.getType() == 21||tableFile.getType() == 22 || tableFile.getType() == 10 || tableFile.getType() == 11||tableFile.getType() == 12) {
             //查询当前节点 如果是数字化节点 需要删除上报信息,变成未填报
             List<TableFileVO> fileVOList = tableFileService.selectTableFileList1(Long.parseLong(tableFile.getTabId()));
             // 该文本无附件

+ 2 - 2
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/WbsTreeController.java

@@ -510,10 +510,10 @@ public class WbsTreeController extends BladeController {
     @ApiOperationSupport(order = 20)
     @ApiOperation(value = "根据表单id查询所有元素", notes = "传入表单id")
     @ApiImplicitParam(name = "id", value = "表单id", required = true)
-    public R<List<WbsFormElementVO>> selectPrivateFormElements(@RequestParam("id") String id, String eName) {
+    public R<List<WbsFormElementVO>> selectPrivateFormElements(@RequestParam("id") String id, String eName,Integer eType) {
         List<WbsFormElementVO> wbsFormElements = null;
         if (StringUtils.isNotEmpty(id)) {
-            wbsFormElements = wbsTreeService.selectPrivateFormElements(id, eName);
+            wbsFormElements = wbsTreeService.selectPrivateFormElements(id, eName,eType);
             if (wbsFormElements.size() > 0) {
                 return R.data(wbsFormElements);
             }

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

@@ -166,6 +166,10 @@ public class ArchiveTreeContractImpl implements ArchiveTreeContractClient {
         archiveTreeContractService.addArchiveTreeContract(archiveTreeContracts,rootId);
     }
 
+    @Override
+    public List<ArchiveTreeContract> getTopAutoTypeNodeByProjectID(@RequestParam Long projectId){
+        return archiveTreeContractMapper.getTopAutoTypeNodeByProjectID(projectId);
+    }
 
 
 }

+ 16 - 5
blade-service/blade-manager/src/main/java/org/springblade/manager/job/SystemMsgJob.java

@@ -10,6 +10,7 @@ import org.springblade.manager.entity.SystemMsg;
 import org.springblade.manager.service.ISystemMsgService;
 import org.springblade.websocket.vo.MsgVO;
 import org.springblade.websocket.vo.SystMsgVO;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.jdbc.core.BeanPropertyRowMapper;
 import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.scheduling.annotation.Scheduled;
@@ -34,13 +35,20 @@ public class SystemMsgJob {
 
     private final JdbcTemplate jdbcTemplate;
 
+    // 读取配置并设置默认值
+    @Value("${scheduler.enabled:true}")
+    private boolean schedulerEnabled;
+
     /**
      *  定时推送公告-取消公告-修改公告状态,不想污染日志,使用jdbc
      */
-    @Scheduled(cron = "0 */1 * * * ?")
+    @Scheduled(cron = "0/10 * * * * ?")
     public void autoUpdateMsgStatus(){
+        // 本地环境跳过执行(可添加日志输出)
+        if (!schedulerEnabled) return;
+
         /** 普通公告推送*/
-        String sql1 = "select * from m_system_msg where is_deleted = 0 and msg_type = 2 and push_status = 1 and push_date_time <= TIMESTAMPADD(SECOND, 1, NOW()) and push_end_date_time >= now()";
+        String sql1 = "select * from m_system_msg where is_deleted = 0 and msg_type = 2 and push_status = 1 and now()<=push_end_date_time and now()>=push_date_time ";
         List<SystemMsg> list1 = jdbcTemplate.query(sql1,new BeanPropertyRowMapper<>(SystemMsg.class));
         if (list1.size() > 0){
             for (SystemMsg msg : list1) {
@@ -51,7 +59,8 @@ public class SystemMsgJob {
                     .in(SystemMsg::getId,list1.stream().map(SystemMsg::getId).collect(Collectors.toList())));
         }
         /** 维护公告推送*/
-        String sql2 = "select * from m_system_msg where is_deleted = 0 and msg_type = 1 and status = 1 and push_status = 1 and push_date_time >= now() and push_warn_date_time <= TIMESTAMPADD(SECOND, 1, NOW())";
+        //String sql2 = "select * from m_system_msg where is_deleted = 0 and msg_type = 1 and status = 1 and push_status = 1 and push_date_time >= now() and push_warn_date_time <= TIMESTAMPADD(SECOND, 1, NOW())";
+        String sql2 = "select * from m_system_msg where is_deleted = 0 and msg_type = 1 and status = 1 and push_status = 1 and TIMESTAMPDIFF(SECOND,push_warn_date_time,sysdate())>0  ";
         List<SystemMsg> list2 = jdbcTemplate.query(sql2,new BeanPropertyRowMapper<>(SystemMsg.class));
         if (list2.size() > 0){
             for (SystemMsg msg : list2) {
@@ -62,12 +71,14 @@ public class SystemMsgJob {
                     .in(SystemMsg::getId,list2.stream().map(SystemMsg::getId).collect(Collectors.toList())));
         }
         /** 维护倒计时*/
-        String sql3 = "select * from m_system_msg where is_deleted = 0 and msg_type = 1 and status != 3 and TIMESTAMPADD(SECOND, 1, NOW()) >= push_count_down_date_time and now() < push_date_time ";
+      //  String sql3 = "select * from m_system_msg where is_deleted = 0 and msg_type = 1 and status != 3 and TIMESTAMPADD(SECOND, 1, NOW()) >= push_count_down_date_time and now() < push_date_time ";
+        String sql3 = "select * from m_system_msg where is_deleted = 0 and msg_type = 1 and status != 3 and TIMESTAMPDIFF(SECOND,push_count_down_date_time,sysdate())>0  ";
         List<SystemMsg> list3 = jdbcTemplate.query(sql3,new BeanPropertyRowMapper<>(SystemMsg.class));
         if (list3.size() > 0){
             SystemMsg msg = list3.get(0);
             msg.setMsgType(3);
-            msg.setMsgContent(Duration.between(LocalDateTime.now(), msg.getPushDateTime()).getSeconds()+"");
+           // msg.setMsgContent(Duration.between(LocalDateTime.now(), msg.getPushDateTime()).getSeconds()+"");
+            msg.setMsgContent((msg.getMsgCountDownTime()*60)+"");
             systemMsgService.pushSystemMsgToAllUser(msg);
             systemMsgService.update(new LambdaUpdateWrapper<SystemMsg>()
                     .set(SystemMsg::getStatus,3)

+ 2 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/ArchiveTreeContractMapper.java

@@ -84,6 +84,8 @@ public interface ArchiveTreeContractMapper extends BaseMapper<ArchiveTreeContrac
 
     List<ArchiveTreeContract> getListByProjectId(@Param("projectId") Long projectId);
 
+    List<ArchiveTreeContract> getTopAutoTypeNodeByProjectID(@Param("projectId") Long projectId);
+
     List<ArchiveTreeContract> getStorageNodeByGroupId(@Param("projectId") Long projectId, @Param("archiveAutoGroupId") Long archiveAutoGroupId);
 
     @MapKey("id")

+ 15 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/ArchiveTreeContractMapper.xml

@@ -50,6 +50,7 @@
         <result column="archive_name_suffix" property="archiveNameSuffix"/>
         <result column="ext_key_id" property="extKeyId"/>
         <result column="out_id" property="outId"/>
+        <result column="ext_node_type" property="extNodeType"/>
     </resultMap>
     <delete id="removeImageNodeChild">
         delete from m_archive_tree_contract
@@ -357,6 +358,20 @@
         order by ancestors asc,tree_sort asc
     </select>
 
+
+    <select id="getTopAutoTypeNodeByProjectID" resultMap="archiveTreeContractResultMap">
+        SELECT
+            *
+        FROM
+            m_archive_tree_contract
+        WHERE
+            1 = 1
+          AND project_id = #{projectId}
+          AND is_deleted = 0
+          AND archive_auto_type = 1
+        order by ancestors asc,tree_sort asc
+    </select>
+
     <select id="getHavedBoxFileNodeByProjectID" resultMap="archiveTreeContractResultMap">
         SELECT
             *

+ 3 - 1
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/ContractInfoMapper.xml

@@ -77,6 +77,7 @@
         <result column="major_data_type" property="majorDataType"/>
         <result column="old_id" property="oldId"/>
         <result column="sort" property="sort"/>
+        <result column="node_class" property="nodeClass"/>
     </resultMap>
 
 
@@ -472,7 +473,8 @@
         d.id AS "key",
         old_id,
         major_data_type,
-        sort
+        sort,
+        node_class
         FROM m_wbs_tree_contract d
         WHERE
         d.is_deleted = 0

+ 1 - 1
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/SignConfigMapper.java

@@ -38,7 +38,7 @@ public interface SignConfigMapper extends BaseMapper<SignConfig> {
     List<RoleVO2> getRoleList(@Param("relationType") Integer relationType,@Param("roleName") String roleName);
     List<SignConfigRelation> getSignConfigRelationListByConfId(@Param("confId") Long confId, @Param("type") Integer type);
 
-    List<SignConfig> selectPageByRoleId(IPage<SignConfig> page,@Param("roleId") Long roleId,@Param("keyword") String keyword);
+    List<SignConfig> selectPageByRoleId(IPage<SignConfig> page, @Param("roleId") Long roleId, @Param("keyword") String keyword, @Param("relationType") Integer relationType);
 
     List<SignConfigVO> getConfigByENames(@Param("names") Set<String> names);
 }

+ 8 - 3
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/SignConfigMapper.xml

@@ -59,11 +59,16 @@
         </if>
     </select>
     <select id="selectPageByRoleId" resultType="org.springblade.manager.entity.SignConfig">
-        select a.id,a.e_name,a.e_id,a.e_key,a.table_type,a.element_type,a.tenant_id,a.create_user,a.create_dept,a.create_time,a.update_user,a.update_time,a.status,a.is_deleted from m_sign_config a LEFT JOIN m_sign_config_relation b
-            on a.id = b.conf_id WHERE b.type = 1 and a.is_deleted = 0
+        select a.id,a.e_name,a.e_id,a.e_key,a.table_type,a.element_type,a.tenant_id,a.create_user,a.create_dept,a.create_time,a.update_user,a.update_time,a.status,a.is_deleted
+        from m_sign_config a WHERE a.is_deleted = 0
+        and ( SELECT count(1) from m_sign_config_relation  where type = 1 and is_deleted = 0 and conf_id = a.id
         <if test="roleId != null">
-            and b.relation_id = #{roleId}
+            and relation_id = #{roleId}
         </if>
+        <if test="relationType != null">
+            and relation_type = #{relationType}
+        </if>
+        limit 1 ) > 0
         <if test="keyword != null and keyword != ''">
             and a.e_name like concat('%',#{keyword},'%')
         </if>

+ 1 - 1
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsTreeMapper.java

@@ -40,7 +40,7 @@ public interface WbsTreeMapper extends EasyBaseMapper<WbsTree> {
 
     List<WbsFormElementVO> selectFormElements4TableId(@Param("id") String id);
 
-    List<WbsFormElementVO> selectPrivateFormElements(@Param("id") String id, @Param("eName") String eName);
+    List<WbsFormElementVO> selectPrivateFormElements(@Param("id") String id, @Param("eName") String eName,@Param("eType") Integer eType);
 
     Integer insertForm(WbsTree wbsTree);
 

+ 4 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsTreeMapper.xml

@@ -467,6 +467,10 @@
         <if test="eName != null and eName != '' ">
             and e_name like concat('%',#{eName},'%')
         </if>
+        <if test="eType != null and eType != '' ">
+            and e_type = #{eType}
+        </if>
+
     </select>
 
     <select id="selectRepeatByProjectId" resultType="java.lang.Integer">

+ 1 - 1
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsTreePrivateMapper.java

@@ -43,7 +43,7 @@ public interface WbsTreePrivateMapper extends EasyBaseMapper<WbsTreePrivate> {
 
     List<TreeNodeVOByTabType> tabTypeLazyTree(IPage page, Long parentId, String projectId, String titleName);
 
-    List<TreeNodeVOByTabType> tabTypeLazyTreeAll(IPage page, Long parentId, String titleName);
+    List<TreeNodeVOByTabType> tabTypeLazyTreeAll(Long parentId, String titleName);
 
     int updateByPKeyId(@Param("pKeyId") Long pKeyId, @Param("wbsTP") WbsTreePrivate wbsTP);
 

+ 1 - 1
blade-service/blade-manager/src/main/java/org/springblade/manager/service/ISignConfigService.java

@@ -24,7 +24,7 @@ public interface ISignConfigService extends BaseService<SignConfig> {
 
     List<WbsFormElementVO3> elementList();
 
-    IPage<SignConfigVO> selectPageByRoleId(IPage<SignConfig> page, Long roleId, String keyword);
+    IPage<SignConfigVO> selectPageByRoleId(IPage<SignConfig> page, Long roleId, String keyword, Integer relationType);
 
     List<RoleVO> queryAllRoleList(Integer type, String roleName);
 

+ 1 - 1
blade-service/blade-manager/src/main/java/org/springblade/manager/service/IWbsTreeService.java

@@ -41,7 +41,7 @@ public interface IWbsTreeService extends BaseService<WbsTree> {
     List<WbsFormElementVO> selectFormElements4Formula(String id);
 
     // 项目级
-    List<WbsFormElementVO> selectPrivateFormElements(String id, String eName);
+     List<WbsFormElementVO> selectPrivateFormElements(String id, String eName,Integer eType);
 
     boolean importWbsTree(MultipartFile excelFile, WbsTree wbsTreeFu, WbsTree wbsTree1) throws IOException;
 

+ 1 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ArTreeContractInitServiceImpl.java

@@ -513,6 +513,7 @@ public class ArTreeContractInitServiceImpl {
             archiveTree.setExtAttachId(subTree.getId());
             archiveTree.setSort(wbsTreeVO2.getSort());
             archiveTree.setDisplayHierarchy(level.toString());
+            archiveTree.setExtNodeType(wbsTreeVO2.getNodeType());
             archiveTree.setIsDeleted(0);
             //上传节点
             if (wbsTreeVO2.getNodeType() != null && wbsTreeVO2.getNodeType().longValue() == level) {

+ 84 - 9
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ArchiveTreeContractSyncImpl.java

@@ -367,7 +367,7 @@ public class ArchiveTreeContractSyncImpl {
         Map<Long,WbsTreeContractVO6> wbsTreeContractVO6Map = new HashMap<>();
         // keyid 到id的映射
         Map<Long,Long> wbsTreeKeyToIdMap = new HashMap<>();
-        Map<Long,Integer> wbsTreeKeyToSortMap = new HashMap<>();
+        Map<Long,Integer> wbsTreeKeyToSortMap = new LinkedHashMap<>();
         for (WbsTreeContractVO6 wbsTreeContractVO6 : wbsTreeContractVO6s) {
             i++;
             wbsTreeKeyToSortMap.put(wbsTreeContractVO6.getPKeyId(),i);
@@ -381,7 +381,7 @@ public class ArchiveTreeContractSyncImpl {
 
         //同步质检关联节点
         syncNodes(contractId, informationQueryList, wbsTreeContractVO6Map, wbsTreeKeyToSortMap,
-                wbsTreeKeyToIdMap, archiveKeyIdMap, contractIndfo,classify,orgContractId);
+                wbsTreeKeyToIdMap, archiveKeyIdMap, contractIndfo,classify,orgContractId,archiveFiles);
 
 
         //wbs的keyId到 归档树的映射
@@ -467,8 +467,8 @@ public class ArchiveTreeContractSyncImpl {
 
     private void syncNodes(Long contractId, List<InformationQuery> informationQueryList,
                            Map<Long, WbsTreeContractVO6> wbsTreeContractVO6Map, Map<Long, Integer> wbsTreeKeyToSortMap,
-                           Map<Long, Long> wbsTreeKeyToIdMap, Map<Long, ArchiveFile> archiveKeyIdMap,
-                           ContractInfo contractIndfo,Integer classify,Long orgContractId) {
+                           Map<Long, Long> wbsTreeKeyToIdMap, Map<Long, ArchiveFile> checkMap,
+                           ContractInfo contractIndfo,Integer classify,Long orgContractId,List<ArchiveFile>  archiveFiles) {
         // 获取关联节点的合同段id
         Long associatedContractId = contractId;
         if (classify == 2) {
@@ -484,6 +484,7 @@ public class ArchiveTreeContractSyncImpl {
 
         Map<Long,Long> archiveTreeContractIdMap = new LinkedHashMap<>();
 
+
         for (ArchiveTreeContract node : associatedNodes) {
             Integer nodeLevel = Integer.valueOf(node.getDisplayHierarchy());
 
@@ -495,12 +496,37 @@ public class ArchiveTreeContractSyncImpl {
             // 获取该合同段下的wbs节点
             List<ArchiveTreeContract> archiveTreeContracts = getArchiveTreeContractsWbs(contractId, node.getId(),classify);
 
+            Set<Long> archiveTreeContractIds = archiveTreeContracts.stream()
+                    .map(ArchiveTreeContract::getId)
+                    .collect(Collectors.toSet());
+
             // 更新archiveTreeContractIdMap映射
              archiveTreeContractIdMap.clear();
             for (ArchiveTreeContract ar : archiveTreeContracts) {
                 archiveTreeContractIdMap.put(ar.getExtKeyId(), ar.getId());
             }
 
+            Map<Long, ArchiveFile> archiveKeyIdMap = new LinkedHashMap<>();
+            for (ArchiveFile file : archiveFiles) {
+                // 获取nodeId字符串
+                String nodeIdStr = file.getNodeId();
+                if (nodeIdStr != null && !nodeIdStr.isEmpty()) {
+                    try {
+                        Long nodeIdLong = Long.parseLong(nodeIdStr);
+                        // 如果转换后的nodeIdLong在archiveTreeContractIds集合中,则加入映射
+                        if (archiveTreeContractIds.contains(nodeIdLong)) {
+                            // 注意:这里使用file.getNodeExtId()作为key(原始代码逻辑)
+                            if (file.getNodeExtId()!= null) {
+                                archiveKeyIdMap.put(file.getNodeExtId(),file);
+                            }
+                        }
+                    } catch (NumberFormatException e) {
+                        // 转换失败,忽略这个文件
+                        log.warn("文件nodeId不是有效的数字: {}, 文件ID: {}", nodeIdStr, file.getId());
+                    }
+                }
+            }
+
             syncNode(informationQueryList, wbsTreeContractVO6Map, wbsTreeKeyToSortMap, wbsTreeKeyToIdMap,
                     archiveKeyIdMap, archiveTreeContractIdMap,
                     nodeLevel, node.getMajorDataType(), contractIndfo,classify);
@@ -548,8 +574,11 @@ public class ArchiveTreeContractSyncImpl {
                     continue;
                 }
                 if (treeContractVO6.getMajorDataType()!= null) {
-                    if (!majarDataType.contains(treeContractVO6.getMajorDataType().toString())) {
-                        continue;
+//                    if (!majarDataType.contains(treeContractVO6.getMajorDataType().toString())) {
+//                        continue;
+//                    }
+                    if (!shouldIncludeTreeContract(treeContractVO6, majarDataType)) {
+                        continue; // 跳过不符合条件的项
                     }
                 }
 
@@ -618,13 +647,19 @@ public class ArchiveTreeContractSyncImpl {
             //向上找到符合条件的level
             Long levelKeyId = findPKeyIdByNodeType(wbsTreeContractVO6Map,id,level);
 
+            Integer nodeClass = 1;
+            WbsTreeContractVO6 treeContractVO6 = wbsTreeContractVO6Map.get(id);
+            if (treeContractVO6!= null && treeContractVO6.getNodeClass()!= null ) {
+                nodeClass = treeContractVO6.getNodeClass();
+            }
+
             //根据map获取到对应的归档树节点nodeid
             Long nodeId = archiveTreeContractIdMap.get(levelKeyId);
             if (nodeId == null) {
                 continue;
             }
             //生成新增的归档文件
-            ArchiveFile archiveFile = getArchiveFile(info,nodeId,info.getWbsId(),contractIndfo,classify);
+            ArchiveFile archiveFile = getArchiveFile(info,nodeId,info.getWbsId(),contractIndfo,classify,nodeClass);
             if (archiveFile != null) {
                 newArchiveFiles.add(archiveFile);
             }
@@ -634,6 +669,46 @@ public class ArchiveTreeContractSyncImpl {
         handleAddandUpdateFiles(newArchiveFiles,updateArchiveFiles);
     }
 
+
+    /**
+     * 针对质量评定的处理
+     * @param treeContractVO6
+     * @param majarDataType
+     * @return
+     */
+    public boolean shouldIncludeTreeContract(WbsTreeContractVO6 treeContractVO6, String majarDataType) {
+        if (treeContractVO6.getMajorDataType() == null) {
+            return false; // 如果 majorDataType 为空,过滤
+        }
+
+        String currentMajor = treeContractVO6.getMajorDataType().toString();
+
+        // 检查是否是特殊类型 (2,8,9)
+        if (currentMajor.equals("2") || currentMajor.equals("8") || currentMajor.equals("9")) {
+            // 特殊类型处理:根据 nodeType 匹配对应的数字
+            if (treeContractVO6.getNodeType() != null) {
+                switch (treeContractVO6.getNodeType()) {
+                    case 1: // 单位工程 → 匹配 2
+                        return majarDataType.contains("2");
+                    case 2: // 分部工程 → 匹配 8
+                    case 3: // 子分部工程 → 匹配 8
+                        return majarDataType.contains("8");
+                    case 4: // 分项工程 → 匹配 9
+                    case 5: // 子分项工程 → 匹配 9
+                        return majarDataType.contains("9");
+                    default:
+                        return majarDataType.contains(currentMajor);
+                }
+            } else {
+                // nodeType 为空时,按原逻辑处理
+                return majarDataType.contains(currentMajor);
+            }
+        } else {
+            // 非特殊类型 (1,4 等):直接匹配
+            return majarDataType.contains(currentMajor);
+        }
+    }
+
     /**
      * 刷新文件
      * @param newArchiveFiles
@@ -706,7 +781,7 @@ public class ArchiveTreeContractSyncImpl {
         }
     }
 
-    public ArchiveFile getArchiveFile(InformationQuery query,Long nodeId,Long keyId,ContractInfo contractIndfo,Integer classify) {
+    public ArchiveFile getArchiveFile(InformationQuery query,Long nodeId,Long keyId,ContractInfo contractIndfo,Integer classify,Integer nodeClass) {
         ArchiveFile archiveFile = new ArchiveFile();
         archiveFile.setNodeId(nodeId.toString());
         archiveFile.setNodeExtId(keyId);
@@ -733,7 +808,7 @@ public class ArchiveTreeContractSyncImpl {
             archiveFile.setFileTime(businessTime);
         }
 
-        archiveFile.setSourceType(1);
+        archiveFile.setSourceType(nodeClass);
         archiveFile.setIsArchive(0);
 
         //设置认证

+ 61 - 23
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ExcelTabServiceImpl.java

@@ -49,6 +49,7 @@ import org.springblade.core.mp.support.Query;
 import org.springblade.core.oss.model.BladeFile;
 import org.springblade.core.secure.BladeUser;
 import org.springblade.core.secure.utils.AuthUtil;
+import org.springblade.core.secure.utils.SecureUtil;
 import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.node.ForestNodeMerger;
 import org.springblade.core.tool.utils.DateUtil;
@@ -1246,13 +1247,15 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                     if (wbsTreeContractByP != null) {
                         //处理文件提名
                         String fileName = this.wbsParamService.createFileTitle(wbsTreeContractByP);
-                        String sql1="Select sg_suffix,jl_suffix from m_project_info where id="+wbsTreeContractByP.getProjectId()+" and is_deleted=0";
-                        List<ProjectInfo> query = jdbcTemplate.query(sql1, new BeanPropertyRowMapper<>(ProjectInfo.class));
-                        if(query.size()>0){
-                            if(tableInfo.getClassify()!=null&&tableInfo.getClassify().equals("1")){
-                                fileName=fileName+(query.get(0).getSgSuffix()==null?"":query.get(0).getSgSuffix());
-                            }else {
-                                fileName=fileName+(query.get(0).getJlSuffix()==null?"":query.get(0).getJlSuffix());
+                        if(wbsTreeContract.getMajorDataType()!=null&&wbsTreeContract.getMajorDataType()==6){
+                            String sql1="Select sg_suffix,jl_suffix from m_project_info where id="+wbsTreeContractByP.getProjectId()+" and is_deleted=0";
+                            List<ProjectInfo> query = jdbcTemplate.query(sql1, new BeanPropertyRowMapper<>(ProjectInfo.class));
+                            if(query.size()>0){
+                                if(tableInfo.getClassify()!=null&&tableInfo.getClassify().equals("1")){
+                                    fileName=fileName+(query.get(0).getSgSuffix()==null?"":query.get(0).getSgSuffix());
+                                }else {
+                                    fileName=fileName+(query.get(0).getJlSuffix()==null?"":query.get(0).getJlSuffix());
+                                }
                             }
                         }
                         //huangjn 保存成功后调用生成资料查询列表数据
@@ -1291,15 +1294,18 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                         .eq(WbsTreeContract::getId, wbsTreeContract.getParentId()).eq(WbsTreeContract::getContractId, wbsTreeContract.getContractId()));
                 //处理文件提名
                 fileName1= this.wbsParamService.createFileTitle(wbsTreeContractByP);
-                String sql1="Select sg_suffix,jl_suffix from m_project_info where id="+wbsTreeContractByP.getProjectId()+" and is_deleted=0";
-                List<ProjectInfo> query = jdbcTemplate.query(sql1, new BeanPropertyRowMapper<>(ProjectInfo.class));
-                if(query.size()>0){
-                    if(tableInfoList.get(0).getClassify()!=null&&tableInfoList.get(0).getClassify().equals("1")){
-                        fileName1=fileName1+(query.get(0).getSgSuffix()==null?"":query.get(0).getSgSuffix());
-                    }else {
-                        fileName1=fileName1+(query.get(0).getJlSuffix()==null?"":query.get(0).getJlSuffix());
+                if(wbsTreeContract.getMajorDataType()!=null&&wbsTreeContract.getMajorDataType()==6){
+                    String sql1="Select sg_suffix,jl_suffix from m_project_info where id="+wbsTreeContractByP.getProjectId()+" and is_deleted=0";
+                    List<ProjectInfo> query = jdbcTemplate.query(sql1, new BeanPropertyRowMapper<>(ProjectInfo.class));
+                    if(query.size()>0){
+                        if(tableInfoList.get(0).getClassify()!=null&&tableInfoList.get(0).getClassify().equals("1")){
+                            fileName1=fileName1+(query.get(0).getSgSuffix()==null?"":query.get(0).getSgSuffix());
+                        }else {
+                            fileName1=fileName1+(query.get(0).getJlSuffix()==null?"":query.get(0).getJlSuffix());
+                        }
                     }
                 }
+
                 //huangjn 保存成功后调用生成资料查询列表数据
                 this.informationQueryClient.saveOrUpdateInformationQueryData(wbsTreeContractByP.getPKeyId() + "", "首件使用字段", "业务ID(主要将来给首件使用)", fileName1, Integer.parseInt(tableInfoList.get(0).getClassify()), 2, "false", "源文件(首件字段)", "pdf文件(首件字段)", "首件上传总结报告名称", new ArrayList<>());
                 JSONObject json = new JSONObject();
@@ -2364,10 +2370,11 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
         }
 
         //附件
-        TableFile tableFile1 = tableFileService.getBaseMapper().selectList(Wrappers.<TableFile>query().lambda().eq(TableFile::getTabId, pkeyId + "").eq(TableFile::getType, 1)).stream().findAny().orElse(null);
-        if (tableFile1 != null) {
-            tableFileService.update(Wrappers.<TableFile>lambdaUpdate().set(TableFile::getDomainPdfUrl, bladeFile.getLink()).eq(TableFile::getId, tableFile1.getId()));
-        } else {
+//        TableFile tableFile1 = tableFileService.getBaseMapper().selectList(Wrappers.<TableFile>query().lambda().eq(TableFile::getTabId, pkeyId + "").eq(TableFile::getType, 1)).stream().findAny().orElse(null);
+//        if (tableFile1 != null) {
+//            tableFileService.update(Wrappers.<TableFile>lambdaUpdate().set(TableFile::getDomainPdfUrl, bladeFile.getLink()).eq(TableFile::getId, tableFile1.getId()));
+//        } else
+        {
             TableFile tableFile = new TableFile();
             String fileExtension = FileUtil.getFileExtension(wbsTreeContract.getFullName() + ".pdf");
             tableFile.setTabId(pkeyId + "");
@@ -2377,7 +2384,8 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
             tableFile.setIsDeleted(0);
             tableFile.setExtension(fileExtension);
             tableFile.setDomainPdfUrl(bladeFile.getLink());
-            tableFileService.saveOrUpdate(tableFile);
+            tableFileService.remove(Wrappers.<TableFile>query().lambda().eq(TableFile::getTabId, pkeyId + "").eq(TableFile::getType, 1));
+            tableFileService.save(tableFile);
         }
 
         List<TableFile> tableFileList = tableFileService.getBaseMapper().selectList(Wrappers.<TableFile>query().lambda().eq(TableFile::getTabId, pkeyId + "").eq(TableFile::getIsDeleted, 0));
@@ -2443,7 +2451,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
             }
         }
 
-        String listPdf = file_path + "/pdf/" + nodeId + ".pdf";
+        String listPdf = file_path + "/pdf/" + nodeId + "_" + classify + ".pdf";
         File tabpdf2 = ResourceUtil.getFile(listPdf);
         if (tabpdf2.exists()) {
             tabpdf2.delete();
@@ -3249,14 +3257,14 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
             //报告编号
             if (bgHB.size() >= 1 && StringUtils.isNotEmpty(dto.getReportNo())) {
                 for (Element element : bgHB) {
-                    DataInfo.put(element.attr("keyname"), "NUMBER-" + dto.getReportNo());
+                   // DataInfo.put(element.attr("keyname"), "NUMBER-" + dto.getReportNo());
                     break;
                 }
             }
             //记录编号
             if (jlBH.size() >= 1 && StringUtils.isNotEmpty(dto.getRecordNo())) {
                 for (Element element : jlBH) {
-                    DataInfo.put(element.attr("keyname"), "NUMBER-" + dto.getRecordNo());
+                   // DataInfo.put(element.attr("keyname"), "NUMBER-" + dto.getRecordNo());
                     break;
                 }
             }
@@ -3636,7 +3644,6 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                 keyStr = keyStr.substring(0, keyStr.lastIndexOf(","));
                 valStr = valStr.substring(0, valStr.lastIndexOf(","));
                 sqlInfo = sqlInfo + keyStr + ") VALUES (" + valStr + ")";
-
                 TransactionStatus transactionStatus = this.beginTransaction(transactionManager1);
                 try {
                     //删除
@@ -3650,6 +3657,37 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                     transactionManager1.rollback(transactionStatus);
                     throw new RuntimeException("500"+e.getCause().getMessage()+"  字段过长,新增失败");
                 }
+                //添加操作日志
+                try {
+                    String delSqlNew = delSql.replace("\"", "'");
+                    StringBuffer sb = new StringBuffer();
+                    sb.append("insert into blade_trial_sql (id,p_key_id,group_id,user_id,create_time,sql_info) VALUES");
+                    sb.append("(" + SnowFlakeUtil.getId());
+                    sb.append(",\"" + tableInfo.getPkeyId()+"\"");
+                    sb.append(",\"" + groupId+"\"");
+                    sb.append(","+ AuthUtil.getUserId());
+                    sb.append(",SYSDATE()");
+                    sb.append(",\"");
+                    sb.append(delSqlNew);
+                    sb.append("\")");
+                    jdbcTemplate.execute(sb.toString());
+
+                    String sqlInfoNew = sqlInfo.replace("\"", "'");
+                    StringBuffer sb1 = new StringBuffer();
+                    sb1.append("insert into blade_trial_sql (id,p_key_id,group_id,user_id,create_time,sql_info) VALUES");
+                    sb1.append("(" + SnowFlakeUtil.getId());
+                    sb1.append(",\"" + tableInfo.getPkeyId()+"\"");
+                    sb1.append(",\"" + groupId+"\"");
+                    sb1.append(","+ AuthUtil.getUserId());
+                    sb1.append(",SYSDATE()");
+                    sb1.append(",\"");
+                    sb1.append(sqlInfoNew);
+                    sb1.append("\")");
+                    jdbcTemplate.execute(sb1.toString());
+                } catch (DataAccessException e) {
+                    log.error("添加操作日志异常:ExcelTabServiceImpl-saveOrUpdateInfoTrial() ");
+                }
+
             }
         }
     }

+ 26 - 1
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormulaServiceImpl.java

@@ -684,7 +684,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                         return;
                     }
                     List<Map<String, Object>> tableNamePkIdsMaps = this.jdbcTemplate.queryForList(
-                            "select c.init_table_name tableName,c.p_key_id pkId,c.html_url url from" +
+                            "select c.init_table_name tableName,c.p_key_id pkId,c.html_url url,c.p_id from" +
                                     " (select id from m_wbs_tree_contract where contract_id=" + currentNode.getContractId() + " and is_deleted=0 and node_type=6 and tree_code like '" + parent.getTreeCode() + "%' ORDER BY sort) k" +
                                     " join m_wbs_tree_contract c on c.parent_id = k.id " +
                                     "where  c.contract_id=" + currentNode.getContractId() + " and c.is_deleted=0 "
@@ -705,6 +705,31 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                                 }
                                 List<Map<String, Object>> tableDatas = this.jdbcTemplate.queryForList("select * from " + tn + " where p_key_id in (" + targetIds + ")");
                                 String tmp = elementInfo == null ? "" : StringUtils.handleNull(elementInfo.get("ename"));
+                                // 优先查找当前节点下的元素
+                                if (!tableDatas.isEmpty()) {
+                                    Map<Long, Long> map = new HashMap<>();
+                                    tableNamePkIdsMaps.forEach(m -> {
+                                        if (StringUtils.isEquals(m.get("tableName"), tn)) {
+                                            Object o = m.get("pkId");
+                                            Object o1 = m.get("p_id");
+                                            if(o instanceof Long && currentNode.getPkId().equals(o1)) {
+                                                map.put((Long) o, 1L);
+                                            }
+                                        }
+                                    });
+                                    if (!map.isEmpty()) {
+                                        List<Map<String, Object>> datas = tableDatas.stream().filter(t -> {
+                                            Object pKeyId = t.get("p_key_id");
+                                            if (pKeyId instanceof Long) {
+                                                return map.containsKey(pKeyId);
+                                            }
+                                            return false;
+                                        }).collect(Collectors.toList());
+                                        if (!datas.isEmpty()) {
+                                            tableDatas = datas;
+                                        }
+                                    }
+                                }
                                 fill(tableDatas, removeList, tn, key, tmp, tec);
                             }
                         });

+ 19 - 24
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/SignConfigServiceImpl.java

@@ -25,7 +25,6 @@ import org.springblade.core.mp.base.BaseServiceImpl;
 import org.springblade.core.secure.utils.AuthUtil;
 import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.utils.BeanUtil;
-import org.springblade.core.tool.utils.Func;
 import org.springblade.core.tool.utils.StringUtil;
 import org.springblade.manager.dto.SignConfigDTO;
 import org.springblade.manager.entity.SignConfig;
@@ -210,13 +209,9 @@ public class SignConfigServiceImpl extends BaseServiceImpl<SignConfigMapper, Sig
     }
 
     @Override
-    public IPage<SignConfigVO> selectPageByRoleId(IPage<SignConfig> page, Long roleId, String keyword) {
-        if (roleId == null && (keyword == null || keyword.trim().isEmpty())) {
-            page = this.page(page);
-        } else {
-            List<SignConfig> signConfigs = baseMapper.selectPageByRoleId(page, roleId, keyword);
-            page.setRecords(signConfigs);
-        }
+    public IPage<SignConfigVO> selectPageByRoleId(IPage<SignConfig> page, Long roleId, String keyword, Integer relationType) {
+        List<SignConfig> signConfigs = baseMapper.selectPageByRoleId(page, roleId, keyword, relationType);
+        page.setRecords(signConfigs);
         IPage<SignConfigVO> pageVO = SignConfigWrapper.build().pageVO(page);
         List<SignConfigVO> records = pageVO.getRecords();
         List<Long> ids = records.stream().map(SignConfigVO::getId).collect(Collectors.toList());
@@ -329,8 +324,7 @@ public class SignConfigServiceImpl extends BaseServiceImpl<SignConfigMapper, Sig
             if (signConfigVOS == null || signConfigVOS.isEmpty()) {
                 return;
             }
-            List<Long> roleIds = new ArrayList<>();
-            List<String> roleNames = new ArrayList<>();
+            Map<Long, String> roleIdNameMap = new HashMap<>();
             signConfigVOS.forEach(signConfigVO -> {
                 List<SignConfigRelation> relations = signConfigVO.getRelations();
                 if (relations != null && !relations.isEmpty()) {
@@ -350,24 +344,25 @@ public class SignConfigServiceImpl extends BaseServiceImpl<SignConfigMapper, Sig
                     List<SignConfigRelation> roles = collect.get(1);
                     if (roles != null && !roles.isEmpty()) {
                         roles.forEach(role -> {
-                            roleIds.add(role.getRelationId());
-                            roleNames.add(role.getRelationName());
+                            roleIdNameMap.put(role.getRelationId(), role.getRelationName());
                         });
                     }
                 }
             });
-            if (!roleIds.isEmpty()) {
-                TextdictInfoVO textdictInfoVO = new TextdictInfoVO();
-                if (vo != null) {
-                    BeanUtil.copy(vo, textdictInfoVO);
-                }
-                textdictInfoVO.setId(null);
-                textdictInfoVO.setColKey(value);
-                textdictInfoVO.setColName(colName);
-                textdictInfoVO.setIsSystem(1);
-                textdictInfoVO.setSigRoleId(StringUtil.join(roleIds, ","));
-                textdictInfoVO.setSigRoleName(StringUtil.join(roleNames, ","));
-                textdictInfoVOS.add(textdictInfoVO);
+            if (!roleIdNameMap.isEmpty()) {
+                roleIdNameMap.forEach((roleId, roleName) -> {
+                    TextdictInfoVO textdictInfoVO = new TextdictInfoVO();
+                    if (vo != null) {
+                        BeanUtil.copy(vo, textdictInfoVO);
+                    }
+                    textdictInfoVO.setId(null);
+                    textdictInfoVO.setColKey(value);
+                    textdictInfoVO.setColName(colName);
+                    textdictInfoVO.setIsSystem(1);
+                    textdictInfoVO.setSigRoleId(roleId + "");
+                    textdictInfoVO.setSigRoleName(roleName);
+                    textdictInfoVOS.add(textdictInfoVO);
+                });
             }
         });
         return textdictInfoVOS;

+ 20 - 13
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/TextdictInfoServiceImpl.java

@@ -82,19 +82,12 @@ public class TextdictInfoServiceImpl extends ServiceImpl<TextdictInfoMapper, Tex
                     }else {
                         textdict = new ArrayList<>();
                     }
-                }else{
-                    textdict = baseMapper.selectTextdictInfoByExcelId(page, textdictInfo);
-                }
-                if (textdict != null && !keys.isEmpty()) {
-                    for (TextdictInfoVO vo : textdict) {
-                        if (!(privateInfo.getPKeyId() + "").equals(vo.getTabId())) {
-                            vo.setIsSystem(1);
-                        }
-                        keys.remove(vo.getColKey());
-                    }
-                    if (Func.isNotEmpty(keys)) {
+                    if (!keys.isEmpty()) {
                         // 查询系统级电签配置
-                        TextdictInfoVO temp = textdict.stream().findFirst().orElse(null);
+                        TextdictInfoVO temp = null;
+                        if (textdict != null && !textdict.isEmpty()) {
+                            temp = textdict.get(0);
+                        }
                         if (temp == null) {
                             temp = new TextdictInfoVO();
                             temp.setProjectId(privateInfo.getProjectId());
@@ -103,8 +96,22 @@ public class TextdictInfoServiceImpl extends ServiceImpl<TextdictInfoMapper, Tex
                             temp.setType(2);
                         }
                         List<TextdictInfoVO> textdictList = iSignConfigService.hasSignConfig(privateInfo.getInitTableName(), keys, temp);
-                        textdict.addAll(textdictList);
+                        if (textdict == null || textdict.isEmpty()) {
+                            textdict = textdictList;
+                        } else {
+                            Map<String, Map<String, TextdictInfoVO>> map = textdict.stream().collect(Collectors.groupingBy(TextdictInfoVO::getColKey, Collectors.toMap(TextdictInfoVO::getSigRoleId, v -> v, (v1, v2) -> v1)));
+                            List<TextdictInfoVO> collect = textdictList.stream().filter(textdictInfoVO -> {
+                                Map<String, TextdictInfoVO> voMap = map.get(textdictInfoVO.getColKey());
+                                if (voMap != null && !voMap.isEmpty() ) {
+                                    return voMap.get(textdictInfoVO.getSigRoleId()) == null;
+                                }
+                                return true;
+                            }).collect(Collectors.toList());
+                            textdict.addAll(collect);
+                        }
                     }
+                }else{
+                    textdict = baseMapper.selectTextdictInfoByExcelId(page, textdictInfo);
                 }
             } catch (Exception e) {
                 throw new RuntimeException(e);

+ 1 - 1
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreePrivateServiceImpl.java

@@ -310,7 +310,7 @@ public class WbsTreePrivateServiceImpl extends BaseServiceImpl<WbsTreePrivateMap
         if (SelectorModel.ID <= parentId && parentId <= SelectorModel.MAX_ID) {
             data = this.baseList(titleName);
         } else {
-            data = baseMapper.tabTypeLazyTreeAll(page, parentId, titleName);
+            data = baseMapper.tabTypeLazyTreeAll(parentId, titleName);
         }
         addBase(data, base);
      /*   if (base && hasPartFormula != null) {

+ 2 - 2
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeServiceImpl.java

@@ -818,8 +818,8 @@ public class WbsTreeServiceImpl extends BaseServiceImpl<WbsTreeMapper, WbsTree>
     }
 
     @Override
-    public List<WbsFormElementVO> selectPrivateFormElements(String id, String eName) {
-        return wbsTreeMapper.selectPrivateFormElements(id, eName);
+    public List<WbsFormElementVO> selectPrivateFormElements(String id, String eName,Integer eType) {
+        return wbsTreeMapper.selectPrivateFormElements(id, eName,eType);
     }
 
     @Override

+ 1 - 1
blade-service/blade-meter/src/main/java/org/springblade/meter/service/impl/InterimPayCertificateItemServiceImpl.java

@@ -127,7 +127,7 @@ public class InterimPayCertificateItemServiceImpl extends BaseServiceImpl<Interi
 
     @Override
     public void saveOrUpdateBatchList(List<InterimPayCertificateItem> items,Long reportId) {
-        List<InterimPayCertificateItem> list = baseMapper.selectList(new QueryWrapper<InterimPayCertificateItem>().eq("certificate_id", reportId));
+        List<InterimPayCertificateItem> list = baseMapper.selectList(new QueryWrapper<InterimPayCertificateItem>().eq("certificate_id", reportId).ne("chapter_seq","施工单位送审金额"));
         if(list.size()>0){
             for (InterimPayCertificateItem item : items) {
                 baseMapper.updateById(item);

+ 12 - 0
blade-service/blade-user/src/main/java/org/springblade/system/user/controller/WbsTreeController.java

@@ -19,6 +19,7 @@ import org.springblade.manager.vo.PrivateTreeVO2;
 import org.springblade.manager.vo.WbsTreeContractLazyVO;
 import org.springblade.system.user.service.IUserService;
 import org.springblade.system.user.util.ComplexStringComparator;
+import org.springblade.system.user.vo.InformationQueryBIMVO;
 import org.springblade.system.user.vo.InformationQueryVO1;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.redis.core.StringRedisTemplate;
@@ -167,6 +168,17 @@ public class WbsTreeController extends BladeController {
         return R.data(iUserService.queryInformationByContractIdAndName(contractId, name));
     }
 
+    @GetMapping("/informationWriteQuery/queryInformationByFileNumber")
+    @ApiOperation("根据合同段Id,模糊文件名查询(杭宁项目专用)")
+    @ApiImplicitParams(value = {
+            @ApiImplicitParam(name = "contractId",value = "合同段Id"),
+            @ApiImplicitParam(name="fileNumber",value = "划分编号")
+    })
+    public R<List<InformationQueryBIMVO>> queryInformationByFileNumber(@RequestParam String contractId, @RequestParam String fileNumber){
+        return R.data(iUserService.queryInformationByFileNumber(contractId, fileNumber));
+    }
+
+
 //    /**
 //     * 项目全加载树
 //     *

+ 4 - 4
blade-service/blade-user/src/main/java/org/springblade/system/user/mapper/UserMapper.java

@@ -25,10 +25,7 @@ import org.springblade.business.vo.InformationQueryVO;
 import org.springblade.manager.vo.PrivateTreeVO2;
 import org.springblade.system.user.entity.User;
 import org.springblade.system.user.excel.UserExcel;
-import org.springblade.system.user.vo.InformationQueryVO1;
-import org.springblade.system.user.vo.InformationQueryVO2;
-import org.springblade.system.user.vo.UserContractInfoVO;
-import org.springblade.system.user.vo.UserVO;
+import org.springblade.system.user.vo.*;
 
 import java.util.List;
 
@@ -80,4 +77,7 @@ public interface UserMapper extends BaseMapper<User> {
     List<PrivateTreeVO2> getAllNode(@Param("projectId") String projectId);
 
     List<InformationQueryVO1> queryInformationByContractIdAndName(@Param("contractId")String contractId, @Param("name")String name);
+
+    //
+    List<InformationQueryBIMVO> queryInformationByFileNumber(@Param("contractId")String contractId, @Param("name")String name);
 }

+ 4 - 0
blade-service/blade-user/src/main/java/org/springblade/system/user/mapper/UserMapper.xml

@@ -247,4 +247,8 @@
         </if>
     </select>
 
+    <select id="queryInformationByFileNumber" resultType="org.springblade.system.user.vo.InformationQueryBIMVO">
+
+    </select>
+
 </mapper>

+ 3 - 0
blade-service/blade-user/src/main/java/org/springblade/system/user/service/IUserService.java

@@ -16,6 +16,7 @@ import org.springblade.system.user.entity.UserInfo;
 import org.springblade.system.user.entity.UserOauth;
 import org.springblade.system.user.enums.UserEnum;
 import org.springblade.system.user.excel.UserExcel;
+import org.springblade.system.user.vo.InformationQueryBIMVO;
 import org.springblade.system.user.vo.InformationQueryVO1;
 import org.springblade.system.user.vo.UserVO;
 
@@ -244,4 +245,6 @@ public interface IUserService extends BaseService<User> {
 
 
     List<InformationQueryVO1> queryInformationByContractIdAndName(String contractId, String name);
+
+    List<InformationQueryBIMVO> queryInformationByFileNumber(String contractId, String fieldNumber);
 }

+ 12 - 0
blade-service/blade-user/src/main/java/org/springblade/system/user/service/impl/UserServiceImpl.java

@@ -63,6 +63,7 @@ import org.springblade.system.user.service.IUserOauthService;
 import org.springblade.system.user.service.IUserService;
 import org.springblade.system.user.util.FileUtils;
 import org.springblade.system.user.util.ForestNodeMerger;
+import org.springblade.system.user.vo.InformationQueryBIMVO;
 import org.springblade.system.user.vo.InformationQueryVO1;
 import org.springblade.system.user.vo.InformationQueryVO2;
 import org.springblade.system.user.vo.UserVO;
@@ -2048,4 +2049,15 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
     }
 
 
+    @Override
+    public List<InformationQueryBIMVO> queryInformationByFileNumber(String contractId, String fileNumber) {
+        if (StringUtil.isEmpty(contractId)) {
+            throw new ServiceException("未获取到合同段id");
+        }
+
+        List<InformationQueryBIMVO> informationQueryVO1s = baseMapper.queryInformationByFileNumber(contractId, fileNumber);
+
+        return informationQueryVO1s;
+    }
+
 }