Browse Source

Merge branch 'dev' of http://219.151.181.73:3000/zhuwei/bladex into test-trial

# Conflicts:
#	blade-service-api/blade-business-api/src/main/java/org/springblade/business/dto/TrialMaterialMobilizationDTO.java
#	blade-service-api/blade-business-api/src/main/java/org/springblade/business/dto/TrialSampleInfoDTO.java
#	blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/TrialAutoNumber.java
#	blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/MessageWarningVO.java
#	blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/WbsTreeContractLazyVO.java
#	blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchivesAutoController.java
#	blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchivesAutoServiceImpl.java
#	blade-service/blade-business/src/main/java/org/springblade/business/controller/TrialNumberRuleController.java
#	blade-service/blade-business/src/main/java/org/springblade/business/mapper/ArchiveFileMapper.xml
#	blade-service/blade-business/src/main/java/org/springblade/business/mapper/EntrustInfoMapper.xml
#	blade-service/blade-business/src/main/java/org/springblade/business/mapper/TrialNumberRuleMapper.xml
#	blade-service/blade-business/src/main/java/org/springblade/business/service/ITrialNumberRuleService.java
#	blade-service/blade-business/src/main/java/org/springblade/business/service/impl/EntrustInfoServiceImpl.java
#	blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TrialMaterialMobilizationServiceImpl.java
#	blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TrialNumberRuleServiceImpl.java
#	blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TrialSampleInfoServiceImpl.java
#	blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TrialSelfInspectionRecordServiceImpl.java
#	blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ArchiveTreeContractController.java
#	blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ExcelTabController.java
#	blade-service/blade-manager/src/main/java/org/springblade/manager/feign/ExcelTabClientImpl.java
#	blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsTreeContractMapper.java
#	blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ExcelTabServiceImpl.java
#	blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsSynchronousEViSaServiceImpl.java
#	blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsSynchronousServiceImpl.java
#	blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeSynchronousRecordServiceImpl.java
lvy 4 weeks ago
parent
commit
6f2a3d68bb
100 changed files with 3488 additions and 283 deletions
  1. 14 0
      blade-common/pom.xml
  2. 1 1
      blade-common/src/main/java/org/springblade/common/utils/AsyncConfigurer.java
  3. 238 0
      blade-common/src/main/java/org/springblade/common/utils/DeepSeekClient.java
  4. 26 0
      blade-common/src/main/java/org/springblade/common/utils/ForestNodeMergerEx.java
  5. 34 0
      blade-common/src/main/java/org/springblade/common/vo/DeepSeekResponse.java
  6. 7 1
      blade-ops-api/blade-resource-api/src/main/java/org/springblade/resource/entity/Oss.java
  7. 5 4
      blade-ops-api/blade-resource-api/src/main/java/org/springblade/resource/feign/CommonFileClient.java
  8. 24 0
      blade-ops-api/blade-resource-api/src/main/java/org/springblade/resource/feign/FeignConfig.java
  9. 5 5
      blade-ops/blade-admin/pom.xml
  10. 10 0
      blade-ops/blade-resource/pom.xml
  11. 1 0
      blade-ops/blade-resource/src/main/java/org/springblade/resource/builder/oss/OssBuilder.java
  12. 1 0
      blade-ops/blade-resource/src/main/java/org/springblade/resource/builder/ossre/MinioTemplateRe.java
  13. 12 0
      blade-ops/blade-resource/src/main/java/org/springblade/resource/builder/ossre/S3Template2.java
  14. 1 1
      blade-ops/blade-resource/src/main/java/org/springblade/resource/endpoint/LargeFileEndpoint.java
  15. 5 4
      blade-ops/blade-resource/src/main/java/org/springblade/resource/feign/CommonFileClientImpl.java
  16. 1 0
      blade-ops/blade-resource/src/main/java/org/springblade/resource/mapper/OssMapper.xml
  17. 31 0
      blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/dto/FindAndReplaceDto.java
  18. 64 0
      blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/entity/ArchiveAiName.java
  19. 2 0
      blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/entity/ArchivesAuto.java
  20. 2 1
      blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/entity/TaskSplit.java
  21. 9 0
      blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/trans/ArchiveFileVo.java
  22. 47 0
      blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/trans/ArchiveReq.java
  23. 12 0
      blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/trans/ArchiveTreeVo.java
  24. 11 0
      blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/vo/ArchiveAiNameVO.java
  25. 12 0
      blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/vo/ArchiveAiNameVO1.java
  26. 58 0
      blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/vo/ArchiveDataVo.java
  27. 19 0
      blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/vo/ArchivesAutoVO4.java
  28. 1 17
      blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/vo/TaskSplitVO.java
  29. 20 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/dto/PrivateStandardDTO.java
  30. 7 1
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/dto/StandardInfoJoinDTO.java
  31. 1 4
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/dto/TrialMaterialMobilizationDTO.java
  32. 1 1
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/dto/TrialSampleInfoDTO.java
  33. 17 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/ArchiveFile.java
  34. 4 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/StandardInfoJoin.java
  35. 5 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/StandardInfoPrivateJoin.java
  36. 2 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/TrialAutoNumber.java
  37. 6 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/feign/ArchiveFileClient.java
  38. 1 1
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/feign/InformationQueryClient.java
  39. 3 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/feign/MetadataClassificationClient.java
  40. 5 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/ArchiveFileVO.java
  41. 3 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/MessageWarningVO.java
  42. 20 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/StandardElementVo.java
  43. 26 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/StandardInfoConditionVo.java
  44. 21 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/StandardInfoGroupNameVO.java
  45. 38 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/StandardInfoPrivateJoinGroupVO.java
  46. 7 3
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/StandardInfoPrivateJoinVO.java
  47. 6 1
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/StandardInfoVO.java
  48. 3 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/TaskSignInfoVO.java
  49. 16 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/AddBussFileSortDTO.java
  50. 39 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/ServicePlanDTO.java
  51. 34 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/ServicePlanTaskDTO.java
  52. 13 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/ServiceUserDto.java
  53. 11 4
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/ArchiveTreeContract.java
  54. 21 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/MeterFormNumberWs.java
  55. 18 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/MeterItemWs.java
  56. 86 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/ServicePlan.java
  57. 50 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/ServicePlanTask.java
  58. 2 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/TableFile.java
  59. 3 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/WbsTreeContract.java
  60. 10 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/feign/ArchiveTreeContractClient.java
  61. 9 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/feign/ExcelTabClient.java
  62. 5 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/feign/ExcelTabClientFallBack.java
  63. 10 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/CurrentNode.java
  64. 11 4
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/EvaSummary.java
  65. 5 1
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/FB02.java
  66. 34 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/ServicePlanTaskVO.java
  67. 50 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/ServicePlanVO.java
  68. 156 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/TrialBaseInfo.java
  69. 6 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/WbsTreeContractLazyVO.java
  70. 2 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/WbsTreePrivateQueryValueVO.java
  71. 1 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/WtcEva.java
  72. 29 0
      blade-service-api/blade-user-api/src/main/java/org/springblade/system/user/vo/InformationQueryBIMVO.java
  73. 155 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchiveAiNameController.java
  74. 6 2
      blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchiveFileAutoController.java
  75. 13 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchiveFileController.java
  76. 89 19
      blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchivesAutoController.java
  77. 1 1
      blade-service/blade-archive/src/main/java/org/springblade/archive/controller/TaskSplitController.java
  78. 37 1
      blade-service/blade-archive/src/main/java/org/springblade/archive/external/impl/ExternalDataArchiveBuildService.java
  79. 33 13
      blade-service/blade-archive/src/main/java/org/springblade/archive/external/impl/ExternalDataArchiveFileService.java
  80. 21 1
      blade-service/blade-archive/src/main/java/org/springblade/archive/external/impl/ExternalDataArchiveTreeService.java
  81. 44 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/ArchiveAiNameMapper.java
  82. 32 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/ArchiveAiNameMapper.xml
  83. 11 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/ArchivesAutoMapper.java
  84. 65 18
      blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/ArchivesAutoMapper.xml
  85. 8 1
      blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/TaskSplitMapper.java
  86. 15 2
      blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/TaskSplitMapper.xml
  87. 45 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/IArchiveAiNameService.java
  88. 65 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/IArchiveNameService.java
  89. 16 1
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/IArchivesAutoService.java
  90. 155 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchiveAiNameServiceImpl.java
  91. 117 8
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchiveAutoPdfServiceImpl.java
  92. 438 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchiveNameServiceImpl.java
  93. 498 147
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchivesAutoServiceImpl.java
  94. 38 3
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/TaskSplitServiceImpl.java
  95. 1 1
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/TraceLogServiceImpl.java
  96. 6 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/utils/FileUtils.java
  97. 1 1
      blade-service/blade-business/pom.xml
  98. 30 3
      blade-service/blade-business/src/main/java/org/springblade/business/controller/EVisaTaskCheckController.java
  99. 14 3
      blade-service/blade-business/src/main/java/org/springblade/business/controller/InformationWriteQueryController.java
  100. 64 4
      blade-service/blade-business/src/main/java/org/springblade/business/controller/PrivateStandardController.java

+ 14 - 0
blade-common/pom.xml

@@ -82,6 +82,20 @@
             <version>0.1.6</version>
         </dependency>
 
+        <!-- 使用OkHttp -->
+        <dependency>
+            <groupId>com.squareup.okhttp3</groupId>
+            <artifactId>okhttp</artifactId>
+            <version>4.9.3</version>
+        </dependency>
+
+        <!-- 使用Gson进行JSON处理 -->
+        <dependency>
+            <groupId>com.google.code.gson</groupId>
+            <artifactId>gson</artifactId>
+            <version>2.8.9</version>
+        </dependency>
+
     </dependencies>
 
     <build>

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

@@ -15,7 +15,7 @@ public class AsyncConfigurer {
     /**
      * cpu 核心数量
      */
-    public static final int cpuNum = 3 ;//Runtime.getRuntime().availableProcessors();
+    public static final int cpuNum = 1 ;//Runtime.getRuntime().availableProcessors();
 
     /**
      * 线程池配置

+ 238 - 0
blade-common/src/main/java/org/springblade/common/utils/DeepSeekClient.java

@@ -0,0 +1,238 @@
+package org.springblade.common.utils;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import okhttp3.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+@Component
+public class DeepSeekClient {
+    private static final Logger logger = LoggerFactory.getLogger(DeepSeekClient.class);
+
+    private static final String API_KEY = "sk-16ebce9ef2eb40a68f29d9c2a70fe6b6";
+
+    private static final String API_URL = "https://api.deepseek.com/v1/chat/completions";
+
+    private final OkHttpClient client;
+    private final Gson gson = new Gson();
+
+    public DeepSeekClient() {
+        this.client = new OkHttpClient.Builder()
+                .connectTimeout(30, TimeUnit.SECONDS)
+                .readTimeout(60, TimeUnit.SECONDS)
+                .writeTimeout(30, TimeUnit.SECONDS)
+                .build();
+    }
+
+    /**
+     * 请求 DeepSeek API
+     */
+    public String callDeepSeek(String prompt) throws IOException {
+        DeepSeekRequest request = new DeepSeekRequest(prompt, "deepseek-chat");
+        String requestJson = gson.toJson(request);
+
+        logger.debug("Sending request to DeepSeek: {}", requestJson);
+
+        Request httpRequest = new Request.Builder()
+                .url(API_URL)
+                .post(RequestBody.create(requestJson, MediaType.parse("application/json")))
+                .addHeader("Authorization", "Bearer " + API_KEY)
+                .addHeader("Content-Type", "application/json")
+                .addHeader("Accept", "application/json")
+                .build();
+
+        try (Response response = client.newCall(httpRequest).execute()) {
+            if (!response.isSuccessful()) {
+                String errorBody = response.body() != null ? response.body().string() : "No error body";
+                logger.error("API request failed with code: {}, Body: {}", response.code(), errorBody);
+                throw new IOException("API request failed with code: " + response.code());
+            }
+            return response.body().string();
+        }
+    }
+
+    /**
+     * 解析响应获取结果
+     */
+    public String analysisResponse(String responseJson) {
+        try {
+            JsonObject jsonObject = JsonParser.parseString(responseJson).getAsJsonObject();
+
+            if (jsonObject.has("error")) {
+                JsonObject error = jsonObject.getAsJsonObject("error");
+                String errorMsg = error.get("message").getAsString();
+                logger.error("API returned error: {}", errorMsg);
+                return "Error: " + errorMsg;
+            }
+
+            DeepSeekResponse response = gson.fromJson(jsonObject, DeepSeekResponse.class);
+
+            if (response == null || response.getChoices() == null || response.getChoices().isEmpty()) {
+                logger.error("Invalid response structure");
+                return "Error: Invalid response structure";
+            }
+
+            return response.getChoices().get(0).getMessage().getContent();
+        } catch (Exception e) {
+            logger.error("Error parsing response: {}", e.getMessage());
+            return "Error: " + e.getMessage();
+        }
+    }
+
+    /**
+     * 直接获取精简后的内容
+     */
+    public String getSimplifiedContent(String prompt) {
+        try {
+            String response = callDeepSeek(prompt);
+            return analysisResponse(response);
+        } catch (IOException e) {
+            logger.error("API call failed: {}", e.getMessage());
+            return "Error: " + e.getMessage();
+        }
+    }
+
+    static class DeepSeekRequest {
+        private String model;
+        private Message[] messages;
+        private double temperature = 0.7;
+        private int max_tokens = 2000;
+        private boolean stream = false;
+
+        // 构造函数
+        public DeepSeekRequest(String prompt, String model) {
+            this.model = model;
+
+            // 构造专家级对话上下文
+            this.messages = new Message[]{
+                    // 系统角色设定
+                    new Message("system", "你是有20年经验的建筑施工资料专家,熟悉GB/T50328、GB50202等规范。请用专业术语回答。"),
+
+                    // 用户问题
+                    new Message("user", "作为资料管理专家,请处理以下案卷题名:" + prompt)
+            };
+
+            this.temperature = 0.3;  // 降低随机性,提高专业性
+            this.max_tokens = 1000;
+        }
+
+        // Getters and Setters
+        public String getModel() {
+            return model;
+        }
+
+        public void setModel(String model) {
+            this.model = model;
+        }
+
+        public Message[] getMessages() {
+            return messages;
+        }
+
+        public void setMessages(Message[] messages) {
+            this.messages = messages;
+        }
+
+        public double getTemperature() {
+            return temperature;
+        }
+
+        public void setTemperature(double temperature) {
+            this.temperature = temperature;
+        }
+
+        public int getMax_tokens() {
+            return max_tokens;
+        }
+
+        public void setMax_tokens(int max_tokens) {
+            this.max_tokens = max_tokens;
+        }
+
+        public boolean isStream() {
+            return stream;
+        }
+
+        public void setStream(boolean stream) {
+            this.stream = stream;
+        }
+    }
+
+    static class Message {
+        private String role;
+        private String content;
+
+        // 构造函数
+        public Message(String role, String content) {
+            this.role = role;
+            this.content = content;
+        }
+
+        // Getters and Setters
+        public String getRole() {
+            return role;
+        }
+
+        public void setRole(String role) {
+            this.role = role;
+        }
+
+        public String getContent() {
+            return content;
+        }
+
+        public void setContent(String content) {
+            this.content = content;
+        }
+    }
+
+    static class DeepSeekResponse {
+        private List<Choice> choices;
+
+        public List<Choice> getChoices() {
+            return choices;
+        }
+
+        public void setChoices(List<Choice> choices) {
+            this.choices = choices;
+        }
+
+        static class Choice {
+            private Message message;
+            private int index;
+            private String finish_reason;
+
+            public Message getMessage() {
+                return message;
+            }
+
+            public void setMessage(Message message) {
+                this.message = message;
+            }
+
+            public int getIndex() {
+                return index;
+            }
+
+            public void setIndex(int index) {
+                this.index = index;
+            }
+
+            public String getFinish_reason() {
+                return finish_reason;
+            }
+
+            public void setFinish_reason(String finish_reason) {
+                this.finish_reason = finish_reason;
+            }
+        }
+    }
+}

+ 26 - 0
blade-common/src/main/java/org/springblade/common/utils/ForestNodeMergerEx.java

@@ -331,4 +331,30 @@ public class ForestNodeMergerEx {
     }
 
 
+    //芯的更新
+    public static <T extends INodeEx<T>> void InitTreeSortEx(T node, String parentTreeSort, int siblingIndex) {
+        // 计算当前节点排序值:100 + 兄弟索引
+        int currentSort = 100 + siblingIndex;
+
+        // 格式化为3位数字(100-999)
+        String sortStr = String.format("%03d", currentSort);
+
+        // 拼接树路径(无分隔符)
+        String currentTreeSort = parentTreeSort + sortStr;
+
+        // 检查是否需要更新
+        if (node.getTreeSort() == null || !node.getTreeSort().equals(currentTreeSort)) {
+            node.setFlag(1);
+            node.setTreeSort(currentTreeSort);
+        }
+
+        // 递归处理子节点
+        List<T> children = node.getChildren();
+        if (children != null && !children.isEmpty()) {
+            for (int i = 0; i < children.size(); i++) {
+                InitTreeSortEx(children.get(i), currentTreeSort, i);
+            }
+        }
+    }
+
 }

+ 34 - 0
blade-common/src/main/java/org/springblade/common/vo/DeepSeekResponse.java

@@ -0,0 +1,34 @@
+package org.springblade.common.vo;
+
+import lombok.Data;
+
+import java.util.List;
+@Data
+public class DeepSeekResponse {
+    private String id;
+    private String object;
+    private long created;
+    private String model;
+    private List<Choice> choices;
+    private Usage usage;
+
+    @Data
+    public static class Choice {
+        private int index;
+        private Message message;
+        private String finish_reason;
+    }
+
+    @Data
+    public static class Message {
+        private String role;
+        private String content;
+    }
+
+    @Data
+    public static class Usage {
+        private int prompt_tokens;
+        private int completion_tokens;
+        private int total_tokens;
+    }
+}

+ 7 - 1
blade-ops-api/blade-resource-api/src/main/java/org/springblade/resource/entity/Oss.java

@@ -52,6 +52,13 @@ public class Oss extends TenantEntity {
      */
     @ApiModelProperty(value = "资源地址")
     private String endpoint;
+
+    /**
+     * oss地址
+     */
+    @ApiModelProperty(value = "资源地址")
+    private String transformEndpoint;
+
     /**
      * accessKey
      */
@@ -83,5 +90,4 @@ public class Oss extends TenantEntity {
     @ApiModelProperty(value = "备注")
     private String remark;
 
-
 }

+ 5 - 4
blade-ops-api/blade-resource-api/src/main/java/org/springblade/resource/feign/CommonFileClient.java

@@ -6,23 +6,24 @@ import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.http.MediaType;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RequestPart;
 import org.springframework.web.multipart.MultipartFile;
 
 @FeignClient(
-        value = AppConstant.APPLICATION_RESOURCE_NAME
+        value = AppConstant.APPLICATION_RESOURCE_NAME,configuration = FeignConfig.class
 )
 public interface CommonFileClient {
 
     String API_PREFIX = "/CommonFileApi";
 
     @PostMapping(value = API_PREFIX + "/pngOrJpgToPdf", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
-    NewBladeFile pngOrJpgToPdf(MultipartFile file);
+    NewBladeFile pngOrJpgToPdf(@RequestPart("file")MultipartFile file);
 
     @PostMapping(value = API_PREFIX + "/wordToPdf", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
-    NewBladeFile wordToPdf(MultipartFile file);
+    NewBladeFile wordToPdf(@RequestPart("file")MultipartFile file);
 
     @PostMapping(value = API_PREFIX + "/excelToPdf", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
-    NewBladeFile excelToPdf(MultipartFile file);
+    NewBladeFile excelToPdf(@RequestPart("file")MultipartFile file);
 
     @PostMapping(value = API_PREFIX + "/getPdfNum")
     String getPdfNum(@RequestParam("url") String url);

+ 24 - 0
blade-ops-api/blade-resource-api/src/main/java/org/springblade/resource/feign/FeignConfig.java

@@ -0,0 +1,24 @@
+package org.springblade.resource.feign;
+
+import feign.codec.Encoder;
+import feign.form.spring.SpringFormEncoder;
+import org.springframework.beans.factory.ObjectFactory;
+import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
+import org.springframework.cloud.openfeign.support.SpringEncoder;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class FeignConfig {
+    private final ObjectFactory<HttpMessageConverters> messageConverters;
+
+    public FeignConfig(ObjectFactory<HttpMessageConverters> messageConverters) {
+        this.messageConverters = messageConverters;
+    }
+
+    @Bean
+    public Encoder feignEncoder() {
+        // 默认使用 SpringEncoder(支持 JSON),但如果遇到 MultipartFile 则用 SpringFormEncoder
+        return new SpringFormEncoder(new SpringEncoder(messageConverters));
+    }
+}

+ 5 - 5
blade-ops/blade-admin/pom.xml

@@ -91,11 +91,11 @@
             <artifactId>spring-cloud-starter-security</artifactId>
         </dependency>
         <!--Taobao-Sdk-->
-        <dependency>
-            <groupId>com.taobao</groupId>
-            <artifactId>taobao-sdk</artifactId>
-            <version>20201116</version>
-        </dependency>
+<!--        <dependency>-->
+<!--            <groupId>com.taobao</groupId>-->
+<!--            <artifactId>taobao-sdk</artifactId>-->
+<!--            <version>20201116</version>-->
+<!--        </dependency>-->
     </dependencies>
 
     <build>

+ 10 - 0
blade-ops/blade-resource/pom.xml

@@ -149,6 +149,16 @@
             <groupId>org.springblade</groupId>
             <artifactId>blade-starter-oss</artifactId>
         </dependency>
+        <dependency>
+            <groupId>io.github.openfeign.form</groupId>
+            <artifactId>feign-form</artifactId>
+            <version>3.8.0</version>
+        </dependency>
+        <dependency>
+            <groupId>io.github.openfeign.form</groupId>
+            <artifactId>feign-form-spring</artifactId>
+            <version>3.8.0</version>
+        </dependency>
     </dependencies>
 
 

+ 1 - 0
blade-ops/blade-resource/src/main/java/org/springblade/resource/builder/oss/OssBuilder.java

@@ -98,6 +98,7 @@ public class OssBuilder {
                 oss.setEndpoint("https://xinan1.zos.ctyun.cn");
             }
         }
+		oss.setEndpoint("https://xinan1.zos.ctyun.cn");
 		System.out.println("oss111="+oss.getEndpoint());
 		Oss ossCached = ossPool.get(tenantId);
 		OssTemplate template = templatePool.get(tenantId);

+ 1 - 0
blade-ops/blade-resource/src/main/java/org/springblade/resource/builder/ossre/MinioTemplateRe.java

@@ -483,6 +483,7 @@ public class MinioTemplateRe implements OssTemplateRe {
 	//	ossProperties.setEndpoint("http://183.247.216.148:9000");
 		//return ossProperties.getEndpoint();
 		return "http://183.247.216.148:9000";
+		//return "http://8.130.108.204:9000";
 	}
 
 

+ 12 - 0
blade-ops/blade-resource/src/main/java/org/springblade/resource/builder/ossre/S3Template2.java

@@ -20,12 +20,15 @@ import com.amazonaws.services.s3.AmazonS3;
 import com.amazonaws.services.s3.model.*;
 import lombok.AllArgsConstructor;
 import lombok.SneakyThrows;
+import org.springblade.common.utils.SnowFlakeUtil;
 import org.springblade.core.oss.OssTemplate;
 import org.springblade.core.oss.enums.PolicyType;
 import org.springblade.core.oss.model.BladeFile;
 import org.springblade.core.oss.model.OssFile;
 import org.springblade.core.oss.props.OssProperties;
 import org.springblade.core.oss.rule.OssRule;
+import org.springblade.core.tool.utils.DateUtil;
+import org.springblade.core.tool.utils.FileUtil;
 import org.springblade.core.tool.utils.Func;
 import org.springblade.core.tool.utils.StringPool;
 import org.springframework.web.multipart.MultipartFile;
@@ -417,6 +420,15 @@ public class S3Template2 implements OssTemplate {
 	 * @return string
 	 */
 	private String getFileName(String originalFilename) {
+		return fileName(originalFilename);
+	}
+
+	public String fileName(String originalFilename) {
+		//试验-规范管理
+		if(originalFilename.contains("|")){
+			String[] split = originalFilename.split("\\|");
+			return "upload/" + split[0] + "/" + DateUtil.today() + "/" + SnowFlakeUtil.getId() + "." + FileUtil.getFileExtension(split[1]);
+		}
 		return ossRule.fileName(originalFilename);
 	}
 

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

@@ -286,7 +286,7 @@ public class LargeFileEndpoint {
 
             if (param.getFilename().contains("pdf") || param.getFilename().contains("PDF")) {
                 try {
-                    PdfReader pdfReader = new PdfReader(inputStream);
+                    PdfReader pdfReader = new PdfReader(new FileInputStream(file1));
                     int pages = pdfReader.getNumberOfPages();
                     //获取文件页数
                     newBladeFile.setPage(pages);

+ 5 - 4
blade-ops/blade-resource/src/main/java/org/springblade/resource/feign/CommonFileClientImpl.java

@@ -4,7 +4,6 @@ import com.aspose.cells.SaveFormat;
 import com.aspose.words.DocumentBuilder;
 import com.itextpdf.text.Image;
 import com.itextpdf.text.Rectangle;
-import com.itextpdf.text.Utilities;
 import com.itextpdf.text.pdf.PdfWriter;
 import lombok.AllArgsConstructor;
 import org.apache.pdfbox.pdmodel.PDDocument;
@@ -16,6 +15,7 @@ import org.springblade.core.tool.utils.FileUtil;
 import org.springblade.core.tool.utils.IoUtil;
 import org.springblade.resource.builder.oss.OssBuilder;
 import org.springblade.resource.vo.NewBladeFile;
+import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 import org.springframework.web.multipart.MultipartFile;
 
@@ -33,11 +33,12 @@ public class CommonFileClientImpl implements CommonFileClient {
      */
     private final OssBuilder ossBuilder;
 
+
     /**
      * png 和 jpg 转 pdf
      */
     @Override
-    public NewBladeFile pngOrJpgToPdf(MultipartFile file) {
+    public NewBladeFile pngOrJpgToPdf(@RequestParam("file")MultipartFile file) {
         String pdfFileUrl = "";
         InputStream pdfInput = null;
         try {
@@ -103,7 +104,7 @@ public class CommonFileClientImpl implements CommonFileClient {
      * word 转 pdf
      */
     @Override
-    public NewBladeFile wordToPdf(MultipartFile file) {
+    public NewBladeFile wordToPdf(@RequestParam("file")MultipartFile file) {
         String pdfFileUrl = "";
         int page = 0;
         InputStream pdfInput = null;
@@ -149,7 +150,7 @@ public class CommonFileClientImpl implements CommonFileClient {
      * excel 转 pdf
      */
     @Override
-    public NewBladeFile excelToPdf(MultipartFile file) {
+    public NewBladeFile excelToPdf(@RequestParam("file") MultipartFile file) {
         String pdfFileUrl = "";
         int page = 0;
         org.apache.poi.ss.usermodel.Workbook ss = null;

+ 1 - 0
blade-ops/blade-resource/src/main/java/org/springblade/resource/mapper/OssMapper.xml

@@ -14,6 +14,7 @@
         <result column="oss_code" property="ossCode"/>
         <result column="category" property="category"/>
         <result column="endpoint" property="endpoint"/>
+        <result column="transform_endpoint" property="transformEndpoint"/>
         <result column="access_key" property="accessKey"/>
         <result column="secret_key" property="secretKey"/>
         <result column="bucket_name" property="bucketName"/>

+ 31 - 0
blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/dto/FindAndReplaceDto.java

@@ -0,0 +1,31 @@
+package org.springblade.archive.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@EqualsAndHashCode
+public class FindAndReplaceDto {
+    private String ids;
+    /**
+     * 1新增 2替换 3删除
+     */
+    private Integer type;
+    /**
+     * 查找内容
+     */
+    private String query;
+    /**
+     * 新增内容
+     */
+    private String replace;
+
+    /**
+     * 1 前   2 后
+     */
+    private Integer position;
+}

+ 64 - 0
blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/entity/ArchiveAiName.java

@@ -0,0 +1,64 @@
+/*
+ *      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.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import java.io.Serializable;
+import org.springblade.core.mp.base.BaseEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 实体类
+ *
+ * @author BladeX
+ * @since 2025-07-03
+ */
+@Data
+@TableName("u_archive_ai_name")
+@EqualsAndHashCode(callSuper = true)
+public class ArchiveAiName extends BaseEntity {
+
+	private static final long serialVersionUID = 1L;
+
+	/**
+	* 项目ID
+	*/
+		private Long projectId;
+	/**
+	* 合同段ID
+	*/
+		private Long contractId;
+	/**
+	* 任务ID
+	*/
+		private Long taskId;
+	/**
+	* 档案案卷ID
+	*/
+		private Long archiveAutoId;
+	/**
+	* 档案案卷题目
+	*/
+		private String archiveName;
+	/**
+	* 档案案卷题目AI
+	*/
+		private String archiveNameAi;
+
+
+}

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

@@ -186,6 +186,8 @@ public class ArchivesAuto extends BaseEntity {
     @ApiModelProperty("是否解析,其他=未解析 1=已解析")
     private Integer splitStatus;
 
+    @ApiModelProperty("颜色状态")
+    private Integer colourStatus;
     //是否是影音
     public boolean isMedia() {
         return (this.getCarrierType() != null &&

+ 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;
 }

+ 9 - 0
blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/trans/ArchiveFileVo.java

@@ -48,6 +48,7 @@ public class ArchiveFileVo {
     private Integer width;
     private Integer height;
     private String isArchive;
+    private Integer sort;
 
     public String getId() {
         return id;
@@ -400,4 +401,12 @@ public class ArchiveFileVo {
     public void setIsArchive(String isArchive) {
         this.isArchive = isArchive;
     }
+
+    public Integer getSort() {
+        return sort;
+    }
+
+    public void setSort(Integer sort) {
+        this.sort = sort;
+    }
 }

+ 47 - 0
blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/trans/ArchiveReq.java

@@ -22,6 +22,21 @@ public class ArchiveReq {
 
     String remoteId;
 
+    /**
+     * 默认0,用nodeId去找
+     * 为1时,用contractName,nodeName找
+     */
+    Integer transType= 0;
+
+    //合同段名称
+    String contractName;
+
+    //节点名称
+    String nodeName;
+
+    //0 施工,1 监理
+    Integer nodeType;
+
     //归档树
     List<ArchiveTreeVo> trees=new ArrayList<>();
     //案卷
@@ -102,4 +117,36 @@ public class ArchiveReq {
     public void setProjectName(String projectName) {
         this.projectName = projectName;
     }
+
+    public Integer getTransType() {
+        return transType;
+    }
+
+    public void setTransType(Integer transType) {
+        this.transType = transType;
+    }
+
+    public String getContractName() {
+        return contractName;
+    }
+
+    public void setContractName(String contractName) {
+        this.contractName = contractName;
+    }
+
+    public String getNodeName() {
+        return nodeName;
+    }
+
+    public void setNodeName(String nodeName) {
+        this.nodeName = nodeName;
+    }
+
+    public Integer getNodeType() {
+        return nodeType;
+    }
+
+    public void setNodeType(Integer nodeType) {
+        this.nodeType = nodeType;
+    }
 }

+ 12 - 0
blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/trans/ArchiveTreeVo.java

@@ -43,6 +43,7 @@ public class ArchiveTreeVo {
     private String code;
     private String storageTime;
     private String secretLevel;
+    private Integer extNodeType;
 
     public String getId() {
         return id;
@@ -328,7 +329,18 @@ public class ArchiveTreeVo {
         return secretLevel;
     }
 
+
+
+
     public void setSecretLevel(String secretLevel) {
         this.secretLevel = secretLevel;
     }
+
+    public Integer getExtNodeType() {
+        return extNodeType;
+    }
+
+    public void setExtNodeType(Integer extNodeType) {
+        this.extNodeType = extNodeType;
+    }
 }

+ 11 - 0
blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/vo/ArchiveAiNameVO.java

@@ -0,0 +1,11 @@
+package org.springblade.archive.vo;
+
+import lombok.Data;
+
+@Data
+public class ArchiveAiNameVO {
+    private Long taskId;
+    private String taskTime;
+    private Integer status;
+    private Integer num;
+}

+ 12 - 0
blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/vo/ArchiveAiNameVO1.java

@@ -0,0 +1,12 @@
+package org.springblade.archive.vo;
+
+import lombok.Data;
+
+@Data
+public class ArchiveAiNameVO1 {
+    private Long id;
+    private Long archiveAutoId;
+    private String archiveNameAi;
+    private Integer status;
+    private Long taskId;
+}

+ 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;
+}

+ 19 - 0
blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/vo/ArchivesAutoVO4.java

@@ -0,0 +1,19 @@
+package org.springblade.archive.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import org.springblade.archive.entity.ArchivesAuto;
+
+@Data
+@EqualsAndHashCode
+@NoArgsConstructor
+@AllArgsConstructor
+public class ArchivesAutoVO4{
+    private Long id;
+    private String fileNumber;
+    private Long nodeId;
+    private Long parentId;
+    private String fileNumberPrefix;
+}

+ 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;
 
 /**
  * 解析主标任务视图实体类

+ 20 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/dto/PrivateStandardDTO.java

@@ -4,6 +4,7 @@ import io.swagger.annotations.ApiModel;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import org.springblade.business.entity.PrivateStandard;
+import org.springblade.business.entity.StandardFile;
 import org.springframework.web.multipart.MultipartFile;
 
 import java.util.List;
@@ -19,4 +20,23 @@ public class PrivateStandardDTO extends PrivateStandard {
      * 文件
      */
     private MultipartFile[] files;
+    /**
+     * 文件
+     */
+    private List<StandardFile> standardFiles;
+
+    /**
+     * 当前规范文件下文件的数量
+     */
+    private Integer filesCount;
+
+    /**
+     * 单个文件
+     */
+    private MultipartFile file;
+
+    /**
+     * 单个文件
+     */
+    private StandardFile standardFile;
 }

+ 7 - 1
blade-service-api/blade-business-api/src/main/java/org/springblade/business/dto/StandardInfoJoinDTO.java

@@ -6,6 +6,7 @@ import lombok.Data;
 
 import javax.validation.constraints.NotEmpty;
 import javax.validation.constraints.NotNull;
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -22,11 +23,16 @@ public class StandardInfoJoinDTO {
     @ApiModelProperty(value = "主关联id", required = true)
     @NotNull(message = "主关联id不能为空")
     private Long leftId;
+    /**
+     * 组Id
+     */
+    @ApiModelProperty(value = "组Id", required = true)
+    private Long groupId;
 
     /**
      * 副连接id
      */
     @ApiModelProperty(value = "副连接id集合", required = true)
     @NotEmpty(message = "副连接id不能为空")
-    private List<Long> rightIds;
+    private List<Long> rightIds = new ArrayList<>();
 }

+ 1 - 4
blade-service-api/blade-business-api/src/main/java/org/springblade/business/dto/TrialMaterialMobilizationDTO.java

@@ -20,14 +20,11 @@ import java.util.Date;
 public class TrialMaterialMobilizationDTO extends TrialMaterialMobilization {
     private static final long serialVersionUID = 1L;
 
-    /**
-     * 数据序号
-     */
     @ApiModelProperty("数据序号")
     private Integer dataNumber;
 
     @ApiModelProperty("旧编号")
-    private String trialAutoNumber;
+    private String trialNumber;
 
     @ApiModelProperty("自增流水号")
     private String autoIncrementNumber;

+ 1 - 1
blade-service-api/blade-business-api/src/main/java/org/springblade/business/dto/TrialSampleInfoDTO.java

@@ -22,7 +22,7 @@ public class TrialSampleInfoDTO extends TrialSampleInfo {
     private Integer dataNumber;
 
     @ApiModelProperty("旧编号")
-    private String trialAutoNumber;
+    private String trialNumber;
 
     @ApiModelProperty("自增流水号")
     private String autoIncrementNumber;

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

@@ -280,6 +280,9 @@ public class ArchiveFile extends BaseEntity {
     @ApiModelProperty("卷内索引")
     private Integer fid;
 
+    @ApiModelProperty("卷内排序")
+    private Integer archiveSort;
+
     //整改情况,0,无整改,1 待整改,2 已整改
     @ApiModelProperty("整改情况")
     private Integer rectification;
@@ -328,6 +331,8 @@ public class ArchiveFile extends BaseEntity {
     private String outId;
 
     private String sortNum;
+    @ApiModelProperty("是否锁定 1已锁定")
+    private Integer isLock;
 
     public void fromExternal(ArchiveFileVo vo) {
         if (vo == null) {
@@ -389,6 +394,10 @@ public class ArchiveFile extends BaseEntity {
         }
 
         this.setSort(vo.getOrderNum());
+        //设置了专门排序的就设置
+        if (vo.getSort()!= null) {
+            this.setSort(vo.getSort());
+        }
 
 
         String type = vo.getType();
@@ -420,4 +429,12 @@ public class ArchiveFile extends BaseEntity {
         this.setIsDeleted(0);
 
     }
+
+    public void setFileTime(String fileTime) {
+        if (fileTime == null || fileTime.equals("null") ) {
+            this.fileTime = "";
+            return;
+        }
+        this.fileTime = fileTime.replaceAll("[^0-9]", "");
+    }
 }

+ 4 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/StandardInfoJoin.java

@@ -19,6 +19,10 @@ public class StandardInfoJoin {
     @TableId
     private Long id;
 
+    /**
+     * 组Id
+     */
+    private Long groupId;
     /**
      * 规范基础信息关联主id
      */

+ 5 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/StandardInfoPrivateJoin.java

@@ -29,6 +29,11 @@ public class StandardInfoPrivateJoin {
     @ApiModelProperty(value = "主键", required = true)
     private Long id;
 
+    /**
+     * 组id
+     */
+    @ApiModelProperty(value = "组id", hidden = false)
+    private Long groupId;
     /**
      * 规范基础信息关联主id
      */

+ 2 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/TrialAutoNumber.java

@@ -39,6 +39,8 @@ public class TrialAutoNumber extends BaseEntity {
 	* 自增的流水号
 	*/
 		private String autoIncrementNumber;
+
+		private Long contractId;
 	/**
 	* 来源主表的主键ID
 	*/

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

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

+ 1 - 1
blade-service-api/blade-business-api/src/main/java/org/springblade/business/feign/InformationQueryClient.java

@@ -97,7 +97,7 @@ public interface InformationQueryClient {
     void insert(@RequestBody InformationQuery iq);
 
     @PostMapping(API_PREFIX+"/getInfoByWbsId")
-    InformationQuery getInfoByWbsId(@RequestParam Long wbsId);
+    InformationQuery getInfoByWbsId(@RequestParam Long wbsId,@RequestParam Integer classify);
 
     @PostMapping(API_PREFIX+"/updateInformationQuery1")
     void update(@RequestBody  InformationQuery iq);

+ 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);
 }

+ 5 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/ArchiveFileVO.java

@@ -97,4 +97,9 @@ public class ArchiveFileVO extends ArchiveFile {
     private String archiveName;
 
     private Integer extType;
+
+    /**
+     * 是否已组卷
+     */
+    private Integer isArchive;
 }

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

@@ -48,6 +48,9 @@ public class MessageWarningVO extends MessageWarning {
     @ApiModelProperty("1废除, 2驳回")
     private String repealType;
 
+    @ApiModelProperty("1废除, 2驳回")
+    private String typeValue;
+
     @ApiModelProperty("任务催办未读数量")
     private Long typeOneNumber;
 

+ 20 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/StandardElementVo.java

@@ -0,0 +1,20 @@
+package org.springblade.business.vo;
+
+import lombok.Data;
+
+
+/**
+ * @author LHB
+ */
+@Data
+public class StandardElementVo {
+    /**
+     * key
+     */
+    private String colKey;
+    /**
+     * name
+     */
+    private String colName;
+
+}

+ 26 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/StandardInfoConditionVo.java

@@ -0,0 +1,26 @@
+package org.springblade.business.vo;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springblade.business.entity.StandardInfo;
+
+import java.util.List;
+
+/**
+ * 试验-规范管理-信息-条件设置
+ * @author LHB
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class StandardInfoConditionVo extends StandardInfo {
+    /**
+     * 子级信息
+     */
+    private List<StandardInfo> rightStandardInfos;
+
+
+    /**
+     * 子级信息
+     */
+    private StandardInfoGroupNameVO standardInfoGroupNameVO;
+}

+ 21 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/StandardInfoGroupNameVO.java

@@ -0,0 +1,21 @@
+package org.springblade.business.vo;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 条件查询最子层响应处理
+ * @author LHB
+ */
+@Data
+public class StandardInfoGroupNameVO {
+    /**
+     * 名称
+     */
+    private String name;
+    /**
+     * ids
+     */
+    private List<Long> ids;
+}

+ 38 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/StandardInfoPrivateJoinGroupVO.java

@@ -0,0 +1,38 @@
+package org.springblade.business.vo;
+
+import lombok.Data;
+import org.springblade.business.entity.StandardInfoPrivateJoin;
+
+import java.util.List;
+
+/**
+ * 项目组
+ * @author LHB
+ */
+@Data
+public class StandardInfoPrivateJoinGroupVO {
+    /**
+     * leftId
+     */
+    private Long standardInfoId;
+    /**
+     * 项目id
+     */
+    private Long privateId;
+
+    /**
+     * 项目名称
+     */
+    private String privateName;
+
+    /**
+     * 元素名称
+     */
+    private String elementNames;
+
+    /**
+     * 元素key集合
+     */
+    private List<StandardElementVo> keys;
+
+}

+ 7 - 3
blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/StandardInfoPrivateJoinVO.java

@@ -16,7 +16,11 @@ import java.util.List;
 @Data
 @ApiModel(description = "关联元素对象-视图")
 public class StandardInfoPrivateJoinVO extends StandardInfo {
-
-    @ApiModelProperty(value = "关联元素副元素集合")
-    private List<StandardInfoPrivateJoin> privateJoins;
+    @ApiModelProperty(value = "组id")
+    private Long groupId;
+    /**
+     * 项目组集合
+     */
+    @ApiModelProperty(value = "项目组集合")
+    private List<StandardInfoPrivateJoinGroupVO> group;
 }

+ 6 - 1
blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/StandardInfoVO.java

@@ -15,9 +15,14 @@ import java.util.List;
 @Data
 @ApiModel(description = "条件设置对象")
 public class StandardInfoVO extends StandardInfo {
+    /**
+     * 分组id
+     */
+    @ApiModelProperty(value = "分组id")
+    private Long groupId;
     /**
      * 副连接对象
      */
     @ApiModelProperty(value = "副连接对象集合")
-    private List<StandardInfo> standardInfos;
+    private List<StandardInfoConditionVo> standardInfos;
 }

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

@@ -89,4 +89,7 @@ public class TaskSignInfoVO {
     @ApiModelProperty("电签内容")
     private String signSmg;
 
+    @ApiModelProperty("是否可以签章:0-表示可以,否则就不行")
+    private Integer isSignature;
+
 }

+ 16 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/AddBussFileSortDTO.java

@@ -0,0 +1,16 @@
+package org.springblade.manager.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class AddBussFileSortDTO {
+    private String[] list;
+    private Integer classify;
+    private Long contractId;
+    private String id;
+    private Integer type;
+}

+ 39 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/ServicePlanDTO.java

@@ -0,0 +1,39 @@
+/*
+ *      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.manager.dto;
+
+import org.springblade.manager.entity.ServicePlan;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 数据传输对象实体类
+ *
+ * @author BladeX
+ * @since 2025-06-25
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class ServicePlanDTO extends ServicePlan {
+	private static final long serialVersionUID = 1L;
+
+    private String userId;
+
+    private String planStartTime1;
+
+    private String planEndTime1;
+}

+ 34 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/ServicePlanTaskDTO.java

@@ -0,0 +1,34 @@
+/*
+ *      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.manager.dto;
+
+import org.springblade.manager.entity.ServicePlanTask;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 数据传输对象实体类
+ *
+ * @author BladeX
+ * @since 2025-06-27
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class ServicePlanTaskDTO extends ServicePlanTask {
+	private static final long serialVersionUID = 1L;
+
+}

+ 13 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/ServiceUserDto.java

@@ -0,0 +1,13 @@
+package org.springblade.manager.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class ServiceUserDto {
+    private String userId;
+    private String userName;
+}

+ 11 - 4
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;
      */
@@ -366,10 +372,11 @@ public class ArchiveTreeContract extends BaseEntity {
         this.projectType = archiveTree.getProjectType();
         this.storageType = archiveTree.getStorageType();
         this.expDataType = archiveTree.getExpDataType();
-        this.archiveAutoType = archiveTree.getArchiveAutoType();
-        this.archiveAutoNodeId = archiveTree.getArchiveAutoNodeId();
-        this.archiveAutoGroupId = archiveTree.getArchiveAutoGroupId();
-        this.archiveAutoGroupSelect = archiveTree.getArchiveAutoGroupSelect();
+        //TODO 0625
+//        this.archiveAutoType = archiveTree.getArchiveAutoType();
+//        this.archiveAutoNodeId = archiveTree.getArchiveAutoNodeId();
+//        this.archiveAutoGroupId = archiveTree.getArchiveAutoGroupId();
+//        this.archiveAutoGroupSelect = archiveTree.getArchiveAutoGroupSelect();
         this.isUploadFileDisplayConfigurationTree = archiveTree.getIsDisplayTree();
         this.classify = archiveTree.getClassify();
         this.treeSort =  archiveTree.getTreeSort();

+ 21 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/MeterFormNumberWs.java

@@ -0,0 +1,21 @@
+package org.springblade.manager.entity;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.math.BigDecimal;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class MeterFormNumberWs {
+    private Long id;
+    private Long periodId;
+    private String formNumber;
+    private BigDecimal nowMoney;
+    private BigDecimal nowTotal;
+    private BigDecimal nowEndMoney;
+    private BigDecimal nowEndTotal;
+    private Integer isDeleted;
+}

+ 18 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/MeterItemWs.java

@@ -0,0 +1,18 @@
+package org.springblade.manager.entity;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.math.BigDecimal;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class MeterItemWs {
+    private Long id;
+    private Long periodId;
+    private String meterItem;
+    private BigDecimal amount;
+    private Integer isDeleted;
+}

+ 86 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/ServicePlan.java

@@ -0,0 +1,86 @@
+/*
+ *      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.manager.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import java.io.Serializable;
+import java.time.LocalDate;
+
+import io.swagger.annotations.ApiModelProperty;
+import org.springblade.core.mp.base.BaseEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 实体类
+ *
+ * @author BladeX
+ * @since 2025-06-25
+ */
+@Data
+@TableName("m_service_plan")
+@EqualsAndHashCode(callSuper = true)
+public class ServicePlan extends BaseEntity {
+
+	private static final long serialVersionUID = 1L;
+
+	/**
+	* 填写类型 1月度服务计划 2服务完成确认单
+	*/
+    @ApiModelProperty(value = "填写类型 1月度服务计划 2服务完成确认单")
+		private Integer fileInType;
+    /**
+     * 项目Id
+     */
+    @ApiModelProperty(value = "项目Id")
+        private Long projectId;
+    /**
+     * 合同段Id
+     */
+    @ApiModelProperty(value = "合同段Id")
+        private Long contractId;
+	/**
+	* 计划开始时间
+	*/
+    @ApiModelProperty(value = "计划开始时间")
+		private LocalDate planStartTime;
+	/**
+	* 计划结束时间
+	*/
+    @ApiModelProperty(value = "计划结束时间")
+		private LocalDate planEndTime;
+    /**
+     * 编写人
+     */
+    @ApiModelProperty(value = "编写人ID 逗号拼接")
+        private String writeUser;
+	/**
+	* 发送人员
+	*/
+    @ApiModelProperty(value = "发送人员ID 逗号拼接")
+		private String sendUser;
+    /**
+     * pdf路径
+      */
+    @ApiModelProperty(value = "pdf路径")
+        private String pdfUrl;
+
+
+
+
+
+}

+ 50 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/ServicePlanTask.java

@@ -0,0 +1,50 @@
+/*
+ *      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.manager.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import java.io.Serializable;
+import org.springblade.core.mp.base.BaseEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 实体类
+ *
+ * @author BladeX
+ * @since 2025-06-27
+ */
+@Data
+@TableName("m_service_plan_task")
+@EqualsAndHashCode(callSuper = true)
+public class ServicePlanTask extends BaseEntity {
+
+	private static final long serialVersionUID = 1L;
+
+	/**
+	* 服务计划主键ID
+	*/
+		private Long servicePlanId;
+	/**
+	* 发送人ID
+	*/
+		private Long userId;
+
+		private Integer isCancel;
+
+
+}

+ 2 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/TableFile.java

@@ -96,4 +96,6 @@ public class TableFile implements Serializable {
     @ApiModelProperty(value = "1施工2监理")
     private Integer classify;
 
+    private Integer sort;
+
 }

+ 3 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/WbsTreeContract.java

@@ -328,6 +328,9 @@ public class WbsTreeContract extends BaseEntity {
     @JsonProperty(value = "treePId")
     private Long treePId;
 
+    @ApiModelProperty(value = "是否完成日期填写 1是 2否")
+    private Integer dateIsComplete;
+
 
 
 }

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

@@ -48,6 +48,9 @@ public interface ArchiveTreeContractClient {
     @PostMapping(API_PREFIX + "/getArchiveTreeContractListByIds")
     List<ArchiveTreeContract> getArchiveTreeContractListByIds(@RequestParam String ids);
 
+    @PostMapping(API_PREFIX + "/getArchiveTreeContractListByList")
+    List<ArchiveTreeContract> getArchiveTreeContractListByList(@RequestBody List<Long> ids);
+
     @PostMapping(API_PREFIX + "/getFirstNodeByTreeCode")
     ArchiveTreeContract getFirstNodeByTreeCode(@RequestParam Long projectId,@RequestParam Integer type);
 
@@ -78,4 +81,11 @@ public interface ArchiveTreeContractClient {
 
     @PostMapping(API_PREFIX+"/adsArchiveTreeContract")
     public void addArchiveTreeContract(@RequestBody List<ArchiveTreeContract> archiveTreeContracts,@RequestParam Long rootId);
+
+
+    @PostMapping(API_PREFIX + "/getNodeIdByName")
+    Long getNodeIdByName(@RequestParam("projectName") String projectName,
+                         @RequestParam("contractName") String contractName,
+                         @RequestParam("nodeName") String nodeName);
+
 }

+ 9 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/feign/ExcelTabClient.java

@@ -58,6 +58,15 @@ public interface ExcelTabClient {
                  @RequestParam String projectId,
                  @RequestHeader("Blade-Auth") String header) throws Exception;
 
+
+
+    @PostMapping(API_PREFIX + "/synPdfKeyInfo")
+    R synPdfKeyInfo(@RequestParam String contractId,
+                 @RequestParam String nodeIds,
+                 @RequestParam String classify,
+                 @RequestParam String projectId,
+                 @RequestHeader("Blade-Auth") String header) throws Exception;
+
     @PostMapping(API_PREFIX + "/getArchiveTabList")
     List<ExcelTab> getArchiveTabList();
 

+ 5 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/feign/ExcelTabClientFallBack.java

@@ -51,6 +51,11 @@ public class ExcelTabClientFallBack implements ExcelTabClient {
         return null;
     }
 
+    @Override
+    public R synPdfKeyInfo(String contractId, String nodeIds, String classify, String projectId, String header) throws Exception {
+        return null;
+    }
+
     @Override
     public List<ExcelTab> getArchiveTabList(){
         return null;

+ 10 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/CurrentNode.java

@@ -1,7 +1,9 @@
 package org.springblade.manager.vo;
 
+import com.fasterxml.jackson.annotation.JsonFormat;
 import lombok.Data;
 import org.springblade.manager.entity.WbsTreePrivate;
+import org.springframework.format.annotation.DateTimeFormat;
 
 import java.time.LocalDate;
 import java.time.LocalDateTime;
@@ -37,6 +39,14 @@ public class CurrentNode {
     private Long wbsNodeId;
     /**节点类型*/
     private Integer nodeType;
+    /**节点排序*/
+    private Integer sort;
+    /**节点名称*/
+    private String title;
+    /**创建时间*/
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime  createTime;
     /**treeCode*/
     private List<String> treeCode =new ArrayList<>();
     /**

+ 11 - 4
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/EvaSummary.java

@@ -60,17 +60,24 @@ public abstract class EvaSummary<T> {
                     ));
 
             int index=1;
+            int pageSizex=0;
             for (Map.Entry<Integer, List<T>> entry : pages.entrySet()) {
                 /*每一页就是一条插入记录*/
                 int k = entry.getKey();
+
                 if (wtcList.size() <= k) {
                     break;
                 }
                 List<T> v = entry.getValue();
                 /*是否是最后一页,fb02最后一页汇总用到*/
                 boolean isLast=index==pages.size();
+                // 算出 每页大小
+                if(pageSizex<=0){
+                    pageSizex = v.size();
+                }
                 index++;
-                List<Object> l=this.fds.stream().map(fd->putEd(k,v,fd,datas,isLast)).collect(Collectors.toList());
+                int finalPageSizex = pageSizex;
+                List<Object> l=this.fds.stream().map(fd->putEd(finalPageSizex,k,v,fd,datas,isLast)).collect(Collectors.toList());
                 l.add(wtcList.get(k).getPKeyId());
                 params.add(l.toArray());
             }
@@ -79,8 +86,8 @@ public abstract class EvaSummary<T> {
         return false;
     }
 
-    /**把数据放到对应元素*/
-    private String putEd(int pn, List<T> items, FormData fd,List<T>datas,boolean isLastPage){
+    /**把数据放到对应元素(一页一行的添加)*/
+    private String putEd(int pageSize,int pn, List<T> items, FormData fd,List<T>datas,boolean isLastPage){
         BiFunction<List<T>,Integer,List<Object>> fc = this.fm.get(fd.getCode());
         if(fc!=null) {
             List<Object> data ;
@@ -93,7 +100,7 @@ public abstract class EvaSummary<T> {
                     data=Collections.singletonList("");
                 }
             }else {
-                data  = fc.apply(items,pn);
+                data  = fc.apply(items,pn*pageSize);
             }
             for (int i = 0; i < data.size(); i++) {
                 Coords c = fd.getCoordsList().get(i);

+ 5 - 1
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/FB02.java

@@ -6,9 +6,13 @@ import lombok.EqualsAndHashCode;
 import org.apache.commons.lang.StringUtils;
 import org.springblade.common.utils.BaseUtils;
 import org.springblade.core.tool.utils.Func;
+import org.springblade.core.tool.utils.IoUtil;
 import org.springblade.manager.dto.FormData;
 import org.springblade.manager.entity.FormulaDataBlock;
 
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.util.*;
@@ -56,7 +60,7 @@ public class FB02 extends EvaSummary<Item02>{
                   this.fm.put(fd.getCode(),(List<Item02> l,Integer pn)->l.stream().map(Item02::getSubItem).collect(Collectors.toList()));
               }else if(fd.getEName().contains("序号")){
                   this.sn=fd;
-                  this.fm.put(fd.getCode(),(List<Item02> l,Integer pn)->IntStream.range(0, l.size()).boxed().map(i->i+pn*l.size()+1).collect(Collectors.toList()));
+                  this.fm.put(fd.getCode(),(List<Item02> l,Integer pn)->IntStream.range(0, l.size()).boxed().map(i->i+pn+1).collect(Collectors.toList()));
               }else if(fd.getEName().contains("实测项目")){
                   this.name=fd;
                   this.fm.put(fd.getCode(),(List<Item02> l,Integer pn)->l.stream().map(Item02::getName).collect(Collectors.toList()));

+ 34 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/ServicePlanTaskVO.java

@@ -0,0 +1,34 @@
+/*
+ *      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.manager.vo;
+
+import org.springblade.manager.entity.ServicePlanTask;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 视图实体类
+ *
+ * @author BladeX
+ * @since 2025-06-27
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class ServicePlanTaskVO extends ServicePlanTask {
+	private static final long serialVersionUID = 1L;
+
+}

+ 50 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/ServicePlanVO.java

@@ -0,0 +1,50 @@
+/*
+ *      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.manager.vo;
+
+import org.springblade.manager.entity.ServicePlan;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 视图实体类
+ *
+ * @author BladeX
+ * @since 2025-06-25
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class ServicePlanVO extends ServicePlan {
+	private static final long serialVersionUID = 1L;
+   //1计划中  2协同中-甲方  3协同中-系统  4已计划
+    private String statusValue;
+    //是否可编辑
+   private Boolean isEdit;
+    //计划开始时间
+   private String startTime;
+   //计划结束时间
+   private String endTime;
+   //发送人
+   private String sendUserName;
+
+   private String writeUserName;
+
+   private String planTime;
+
+
+
+}

+ 156 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/TrialBaseInfo.java

@@ -0,0 +1,156 @@
+package org.springblade.manager.vo;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springblade.business.entity.TrialSampleInfo;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * @author yangyj
+ * @Date 2023/12/14 15:55
+ * @description 基础信息
+ */
+@Data
+public class TrialBaseInfo implements  DataModel{
+    public static final String ID="20370000000";
+    public static final String TBN="TBInfo";
+    public static final String TBN_CH="试验基础信息";
+    static final String UNKNOWN="未设置";
+    /**
+     * 项目名称/工程名称
+     */
+    @JSONField(name = "key_1",label="项目名称",ordinal = 1)
+    private String projectName;
+    /**
+     * 施工单位
+     */
+    @JSONField(name = "key_2",label="施工单位",ordinal = 2)
+    private String constructionUnit;
+
+    /**
+     * 监理单位
+     */
+    @JSONField(name = "key_3",label="监理单位",ordinal = 3)
+    private String supervisionUnit;
+
+    /**
+     * 实验室名称
+     */
+    @JSONField(name = "key_4",label="实验室名称",ordinal = 4)
+    private String labName;
+
+    /**
+     * 合同段/工区
+     */
+    @JSONField(name = "key_5",label="合同段/工区",ordinal = 5)
+    private String contractName;
+
+    /**
+     * 工程部位/用途
+     */
+    @JSONField(name = "key_6",label="工程部位/用途",ordinal = 6)
+    private String projectPosition;
+
+    /**
+     * 委托单编号
+     */
+    @JSONField(name = "key_7",label="委托单编号",ordinal = 7)
+    private String entrustNo;
+
+    /**
+     * 记录编号
+     */
+    @JSONField(name = "key_8",label="记录编号",ordinal = 8)
+    private String recordNo;
+
+    /**
+     * 报告编号
+     */
+    @JSONField(name = "key_9",label="报告编号",ordinal = 9)
+    private String reportNo;
+
+    /**
+     * 判断依据
+     */
+    @JSONField(name = "key_10",label="判断依据",ordinal = 10)
+    private String standard;
+
+    /**
+     * 样品名称
+     */
+    @JSONField(name = "key_11",label="样品名称",ordinal = 11)
+    private String materialName;
+
+    /**
+     * 样品编号
+     */
+    @JSONField(name = "key_12",label="样品编号",ordinal = 12)
+    private String specificationNumber;
+
+    /**
+     * 样品描述
+     */
+    @JSONField(name = "key_13",label="样品描述",ordinal = 13)
+    private String sampleDescription;
+
+    /**
+     * 来样/取样时间
+     */
+    @JSONField(name = "key_14",label="来样/取样时间",ordinal = 14)
+    private Date samplingDate;
+
+    /**
+     * 样品数量
+     */
+    @JSONField(name = "key_15",label="样品数量",ordinal = 15)
+    private String materialCount;
+
+    /**
+     * 样品数量
+     */
+    @JSONField(name = "key_16",label="强度等级",ordinal = 16)
+    private String designStrength;
+
+    public Object getValueByKey(String key) {
+        String keyPrefix = TBN + ":";
+        if ((keyPrefix + "key_1").equals( key)) {
+            return projectName;
+        } else if ((keyPrefix + "key_2").equals( key)) {
+            return constructionUnit;
+        } else if ((keyPrefix + "key_3").equals( key)) {
+            return supervisionUnit;
+        } else if ((keyPrefix + "key_4").equals( key)) {
+            return labName;
+        } else if ((keyPrefix + "key_5").equals( key)) {
+            return contractName;
+        } else if ((keyPrefix + "key_6").equals( key)) {
+            return projectPosition;
+        } else if ((keyPrefix + "key_7").equals( key)) {
+            return entrustNo;
+        } else if ((keyPrefix + "key_8").equals( key)) {
+            return recordNo;
+        } else if ((keyPrefix + "key_9").equals( key)) {
+            return reportNo;
+        } else if ((keyPrefix + "key_10").equals( key)) {
+            return standard;
+        } else if ((keyPrefix + "key_11").equals( key)) {
+            return materialName;
+        } else if ((keyPrefix + "key_12").equals( key)) {
+            return specificationNumber;
+        } else if ((keyPrefix + "key_13").equals( key)) {
+            return sampleDescription;
+        } else if ((keyPrefix + "key_14").equals(key)) {
+            return samplingDate;
+        } else if ((keyPrefix + "key_15").equals(key)) {
+            return materialCount;
+        } else if ((keyPrefix + "key_16").equals(key)) {
+            return designStrength;
+        }
+        return null;
+    }
+
+}

+ 6 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/WbsTreeContractLazyVO.java

@@ -19,6 +19,9 @@ public class WbsTreeContractLazyVO implements Serializable {
     @JsonProperty(value = "pKeyId")
     private Long pKeyId;
 
+    @ApiModelProperty("pkeyId的节点父级id")
+    private Long pId;
+
     @ApiModelProperty("节点主键pKeyId别名,其他接口要用")
     private Long primaryKeyId;
 
@@ -133,6 +136,9 @@ public class WbsTreeContractLazyVO implements Serializable {
     @ApiModelProperty(value = "关联后管节点ID")
     private Long isTypePrivatePid;
 
+    @ApiModelProperty(value = "是否完成日期填写1是2否")
+    private Integer dateIsComplete;
+
 
 
 }

+ 2 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/WbsTreePrivateQueryValueVO.java

@@ -14,4 +14,6 @@ public class WbsTreePrivateQueryValueVO extends WbsTreePrivate {
 
     private Boolean hasChildren;
 
+    private Long primaryKeyId;
+
 }

+ 1 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/WtcEva.java

@@ -19,6 +19,7 @@ public class WtcEva {
     private String treeCode;
     private Long parentId;
     private Long pKeyId;
+    private Long pId;//pkeyid 的父级 id
     public boolean isEva(){
       return Objects.requireNonNull(this.nodeName, "nodeName不能为空").contains("评定");
   }

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

@@ -0,0 +1,29 @@
+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;
+}

+ 155 - 0
blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchiveAiNameController.java

@@ -0,0 +1,155 @@
+/*
+ *      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.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+import lombok.AllArgsConstructor;
+import javax.validation.Valid;
+
+import org.springblade.archive.vo.ArchiveAiNameVO;
+import org.springblade.archive.vo.ArchiveAiNameVO1;
+import org.springblade.core.mp.support.Condition;
+import org.springblade.core.mp.support.Query;
+import org.springblade.core.tool.api.R;
+import org.springblade.core.tool.utils.Func;
+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.ArchiveAiName;
+import org.springblade.archive.service.IArchiveAiNameService;
+import org.springblade.core.boot.ctrl.BladeController;
+
+import java.util.List;
+
+/**
+ *  控制器
+ *
+ * @author BladeX
+ * @since 2025-07-03
+ */
+@RestController
+@AllArgsConstructor
+@RequestMapping("/archiveainame")
+@Api(value = "", tags = "接口")
+public class ArchiveAiNameController extends BladeController {
+
+	private final IArchiveAiNameService archiveAiNameService;
+
+	/**
+	 * 详情
+	 */
+	@GetMapping("/detail")
+	@ApiOperationSupport(order = 1)
+	@ApiOperation(value = "详情", notes = "传入archiveAiName")
+	public R<ArchiveAiName> detail(ArchiveAiName archiveAiName) {
+		ArchiveAiName detail = archiveAiNameService.getOne(Condition.getQueryWrapper(archiveAiName));
+		return R.data(detail);
+	}
+
+	@GetMapping("/getArchiveAiTask")
+	@ApiOperationSupport(order = 2)
+	@ApiOperation(value = "获取AI任务", notes = "获取AI任务")
+	public R<List<ArchiveAiNameVO>>getArchiveAiTask(Long projectId, Long contractId){
+		return R.data(archiveAiNameService.getArchiveAiTask(projectId,contractId));
+	}
+
+	@GetMapping("/deletedArchiveAiTask")
+	@ApiOperationSupport(order = 3)
+	@ApiOperation(value = "删除AI任务", notes = "删除AI任务")
+	public R deletedArchiveAiTask(Long taskId){
+		return R.status(archiveAiNameService.deletedArchiveAiTask(taskId));
+	}
+	@GetMapping("/page")
+	@ApiOperationSupport(order = 2)
+	@ApiOperation(value = "分页")
+	public R<IPage<ArchiveAiName>>page(Long taskId,Long projectId,Long contractId,Query query){
+		if(taskId!=null){
+			IPage<ArchiveAiName> pages = archiveAiNameService.page(Condition.getPage(query), new LambdaQueryWrapper<>(ArchiveAiName.class).eq(ArchiveAiName::getTaskId,taskId).eq(ArchiveAiName::getStatus,2));
+			return R.data(pages);
+		}else {
+			IPage<ArchiveAiName> pages = archiveAiNameService.page(Condition.getPage(query), new LambdaQueryWrapper<>(ArchiveAiName.class).eq(ArchiveAiName::getProjectId,projectId).eq(ArchiveAiName::getContractId,contractId).eq(ArchiveAiName::getStatus,2));
+			return R.data(pages);
+		}
+	}
+
+	@PostMapping("/confirmAiName")
+	@ApiOperationSupport(order = 3)
+	@ApiOperation(value = "确认AI名称", notes = "确认AI名称")
+	public R confirmAiName(@RequestBody List<ArchiveAiNameVO1>list){
+		return R.status(archiveAiNameService.confirmAiName(list));
+	}
+
+//	/**
+//	 * 分页
+//	 */
+//	@GetMapping("/list")
+//	@ApiOperationSupport(order = 2)
+//	@ApiOperation(value = "分页", notes = "传入archiveAiName")
+//	public R<IPage<ArchiveAiName>> list(ArchiveAiName archiveAiName, Query query) {
+//		IPage<ArchiveAiName> pages = archiveAiNameService.page(Condition.getPage(query), Condition.getQueryWrapper(archiveAiName));
+//		return R.data(pages);
+//	}
+
+//
+//
+//	/**
+//	 * 新增
+//	 */
+//	@PostMapping("/save")
+//	@ApiOperationSupport(order = 4)
+//	@ApiOperation(value = "新增", notes = "传入archiveAiName")
+//	public R save(@Valid @RequestBody ArchiveAiName archiveAiName) {
+//		return R.status(archiveAiNameService.save(archiveAiName));
+//	}
+//
+//	/**
+//	 * 修改
+//	 */
+//	@PostMapping("/update")
+//	@ApiOperationSupport(order = 5)
+//	@ApiOperation(value = "修改", notes = "传入archiveAiName")
+//	public R update(@Valid @RequestBody ArchiveAiName archiveAiName) {
+//		return R.status(archiveAiNameService.updateById(archiveAiName));
+//	}
+//
+//	/**
+//	 * 新增或修改
+//	 */
+//	@PostMapping("/submit")
+//	@ApiOperationSupport(order = 6)
+//	@ApiOperation(value = "新增或修改", notes = "传入archiveAiName")
+//	public R submit(@Valid @RequestBody ArchiveAiName archiveAiName) {
+//		return R.status(archiveAiNameService.saveOrUpdate(archiveAiName));
+//	}
+//
+//
+//	/**
+//	 * 删除
+//	 */
+//	@PostMapping("/remove")
+//	@ApiOperationSupport(order = 7)
+//	@ApiOperation(value = "逻辑删除", notes = "传入ids")
+//	public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
+//		return R.status(archiveAiNameService.deleteLogic(Func.toLongList(ids)));
+//	}
+
+	
+}

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

@@ -339,12 +339,16 @@ ArchiveFileAutoController extends BladeController {
     @ApiOperation(value = "预览")
     public R<Object> mergePdf(@RequestParam String ids) {
         List<ArchiveFile> result = this.archiveFileClient.getArchiveFileByArchivesId(ids, "");
+        // 由于文件分解后,pdf文件会生成多个,所以需要合并
+        if(result!=null && result.size()>0){
+            result.sort(Comparator.comparing(ArchiveFile::getSort));
+        }
         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,"");
         /**
          * 案卷的只有一个文件,不合并先,需要的时候在把合并方法放出来
          * **/
-        return R.data(pdfUrls);
+        return R.data(pdfUrls.get(0));
     }
 }

+ 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;
@@ -442,4 +443,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);
+    }
 }

+ 89 - 19
blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchivesAutoController.java

@@ -16,16 +16,13 @@
  */
 package org.springblade.archive.controller;
 
-import cn.hutool.core.text.split.SplitIter;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
-import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import io.swagger.annotations.*;
 import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
 import lombok.AllArgsConstructor;
 
 import javax.servlet.ServletOutputStream;
-import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import javax.validation.Valid;
 
@@ -34,18 +31,17 @@ import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang.StringUtils;
 import org.apache.http.message.BasicNameValuePair;
 import org.springblade.archive.dto.ArchiveWarningDTO;
+import org.springblade.archive.dto.FindAndReplaceDto;
 import org.springblade.archive.dto.SaveApplyDTO;
 import org.springblade.archive.entity.ArchiveConclusion;
 import org.springblade.archive.entity.ExpertInspection;
 import org.springblade.archive.service.IArchiveAutoPdfService;
 import org.springblade.archive.service.ITraceLogService;
 import org.springblade.archive.utils.CallBgrsjk;
-import org.springblade.archive.utils.FileUtils;
 import org.springblade.archive.vo.*;
 import org.springblade.business.entity.ArchiveFile;
-import org.springblade.business.entity.InformationQuery;
-import org.springblade.common.constant.CommonConstant;
-import org.springblade.common.utils.CommonUtil;
+import org.springblade.business.feign.ArchiveFileClient;
+import org.springblade.common.utils.DeepSeekClient;
 import org.springblade.common.utils.SnowFlakeUtil;
 import org.springblade.core.mp.support.Condition;
 import org.springblade.core.mp.support.Query;
@@ -54,15 +50,12 @@ import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.utils.Func;
 import org.springblade.manager.entity.ArchiveTreeContract;
 import org.springblade.manager.entity.ContractInfo;
-import org.springblade.manager.entity.ExcelEditCallback;
-import org.springblade.manager.entity.ProjectInfo;
 import org.springblade.manager.feign.ArchiveTreeContractClient;
 import org.springblade.manager.feign.ContractClient;
 import org.springblade.manager.feign.ProjectClient;
-import org.springblade.manager.vo.MyInspectTreeVO;
-import org.springblade.system.cache.ParamCache;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.http.MediaType;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.bind.annotation.RequestParam;
 import com.baomidou.mybatisplus.core.metadata.IPage;
@@ -72,12 +65,8 @@ import org.springblade.archive.service.IArchivesAutoService;
 import org.springblade.core.boot.ctrl.BladeController;
 import org.springframework.web.multipart.MultipartFile;
 
-import java.io.File;
 import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 import java.util.concurrent.ExecutorService;
 import java.util.stream.Collectors;
 
@@ -106,6 +95,11 @@ public class ArchivesAutoController extends BladeController {
 	private ExecutorService executorService;
 	@Autowired
 	private ITraceLogService iTraceLogService;
+    private final JdbcTemplate jdbcTemplate;
+    @Autowired
+    private ArchiveFileClient archiveFileClient;
+
+
 	/**
 	 * 详情
 	 */
@@ -152,6 +146,22 @@ public class ArchivesAutoController extends BladeController {
 		return R.data(pages);
 	}
 
+    @GetMapping("/fileNumberFlush")
+    @ApiOperationSupport(order = 4)
+    @ApiOperation(value = "档号整理——按档号排序")
+    public R fileNumberFlush(Long projectId,Long contractId,String nodeId,Integer isArchive,Integer startNumber){
+        List<ArchiveTreeContract> archiveTreeContracts = this.archiveTreeContractClient.queryAllChildByAncestors(nodeId,contractId);
+        List<String> ids = new ArrayList<>();
+        if(archiveTreeContracts != null && archiveTreeContracts.size() > 0){
+            ids=JSONArray.parseArray(JSONObject.toJSONString(archiveTreeContracts.stream().map(ArchiveTreeContract::getId).distinct().collect(Collectors.toList())), String.class);
+        }
+        ids.add(nodeId);
+        archivesAutoService.fileNumberFlush(projectId,contractId,ids,isArchive,startNumber);
+        return R.success("正在刷新档号中,请稍后刷新");
+    }
+
+
+
 
 
 	/**
@@ -391,13 +401,15 @@ public class ArchivesAutoController extends BladeController {
 	@ApiOperationSupport(order = 10)
 	@ApiOperation(value = "锁定", notes = "传入ids")
 	public R lock(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
-
 		List<ArchivesAuto> archivesAutos = archivesAutoService.listByIds(Func.toLongList(ids));
 		for (ArchivesAuto ar  :archivesAutos) {
 			ar.setIsLock(1);
+            String sql="update u_archive_file set is_lock=1 where archive_id="+ar.getId()+" and is_deleted=0";
+            jdbcTemplate.update(sql);
 		}
+        archivesAutoService.updateBatchById(archivesAutos);
 
-		return R.status(archivesAutoService.updateBatchById(archivesAutos));
+		return R.status(true);
 	}
 
 	/**
@@ -410,9 +422,18 @@ public class ArchivesAutoController extends BladeController {
 		List<ArchivesAuto> archivesAutos = archivesAutoService.listByIds(Func.toLongList(ids));
 		for (ArchivesAuto ar  :archivesAutos) {
 			ar.setIsLock(0);
+            String sql="update u_archive_file set is_lock=0 where archive_id="+ar.getId()+" and is_deleted=0";
+            jdbcTemplate.update(sql);
 		}
 		return R.status(archivesAutoService.updateBatchById(archivesAutos));
 	}
+    @PostMapping("/findAndReplace")
+    @ApiOperationSupport(order = 12)
+    @ApiOperation(value = "查找并替换", notes = "传入ids")
+    public R findAndReplace(@RequestBody FindAndReplaceDto dto){
+        List<ArchivesAuto> archivesAutos = archivesAutoService.listByIds(Func.toLongList(dto.getIds()));
+        return R.status(archivesAutoService.findAndReplace(archivesAutos,dto));
+    }
 
 
 	@PostMapping("/archiveAutoPercentComplete")
@@ -482,6 +503,48 @@ public class ArchivesAutoController extends BladeController {
 		}
 
 	}
+	@PostMapping("/reCreateArchiveAuto")
+	@ApiOperationSupport(order = 13)
+	@ApiOperation(value = "重新生成案卷", notes = "传入ids")
+	@Transactional
+	public R reCreateArchiveAuto(@ApiParam(value = "主键集合", required = true) @RequestParam String ids,@ApiParam(value = "合并后的文件题目", required = true)String name){
+		//先查出勾选的案卷
+		List<ArchivesAuto> archivesAutoList=archivesAutoService.listByIds(Func.toLongList(ids));
+		if(archivesAutoList.size()<=1){
+			return R.fail("请选择多个案卷进行合并");
+		}
+		archivesAutoList.sort(Comparator.comparingInt(a -> {
+			String[] parts = a.getFileNumber().split("_");
+			return Integer.parseInt(parts[parts.length - 1]); // 取最后一个部分作为数字
+		}));
+		//根据档号后缀排序 拿到第一个
+		ArchivesAuto auto = archivesAutoList.get(0);
+		//查出所有案卷文件
+		List<ArchiveFile>archiveFileList=archiveFileClient.getArchiveFileByArchiveIds(ids);
+		//将除第一个以外的案卷文件archiveId 设置成第一个的id
+		List<ArchiveFile>updateArchiveFileList=new ArrayList<>();
+		for (ArchiveFile file : archiveFileList) {
+			if (!file.getArchiveId().equals(auto.getId())) {
+				file.setArchiveId(auto.getId());
+				updateArchiveFileList.add(file);
+			}
+		}
+		archiveFileClient.updateArchiveFile(updateArchiveFileList);
+		auto.setName(name);
+		//删除其他案卷
+		archivesAutoList.remove(auto);
+		archivesAutoService.deleteLogic(archivesAutoList.stream().map(o->o.getId()).collect(Collectors.toList()));
+		//设置案卷页码和四要素
+		archivesAutoService.reCreateArchiveAuto(auto, archiveFileList);
+		return R.status(true);
+	}
+
+	@PostMapping("/creatFileNameFormAI")
+	@ApiOperationSupport(order = 10)
+	@ApiOperation(value = "案卷ai题名", notes = "传入ids")
+	public R creatFileNameFormAI(String ids,Long projectId,Long contractId) throws IOException {
+		return R.status(archivesAutoService.creatFileNameFormAI(ids,projectId,contractId));
+	}
 
 	/**
 	 * 预览案卷文件
@@ -961,5 +1024,12 @@ public class ArchivesAutoController extends BladeController {
 		return R.data(iPage);
 	}
 
+    @GetMapping("/reBuildArchiveFrontPdfs")
+    @ApiOperationSupport(order = 41)
+    @ApiModelProperty(value = "重新生成档案四要素")
+    public R reBuildArchiveFrontPdfs(String archiveIds,Long projectId){
+        return R.status(archivesAutoService.reBuildArchiveFrontPdfs(archiveIds,projectId));
+    }
+
 
 }

+ 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;
 

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

@@ -4,6 +4,7 @@ import lombok.AllArgsConstructor;
 import org.springblade.archive.external.bean.ExternalDataInfo;
 import org.springblade.archive.external.utils.TransUtil;
 import org.springblade.archive.trans.ArchiveReq;
+import org.springblade.manager.feign.ArchiveTreeContractClient;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
@@ -18,8 +19,11 @@ public class ExternalDataArchiveBuildService {
     @Autowired
     private  ExternalDataArchiveTreeService externalTreeService;
 
+
     private ExternalDataArchiveMetaService externalMetaService;
 
+    private final ArchiveTreeContractClient archiveTreeContractClient;
+
 
     /**
      *
@@ -31,7 +35,39 @@ public class ExternalDataArchiveBuildService {
             throw new IllegalArgumentException("请求参数不能为空");
         }
 
-        ExternalDataInfo externalDataInfo = externalTreeService.getDataByIds(req.getNodeId(),req.getRemoteId());
+        // 当 transType 为 1 时,使用新方式获取 remoteId, 并且在传输开始时设置
+        if (req.getTransType() != null && req.getTransType() == 1 && req.getType()== 0) {
+            // 获取节点ID
+            Long remoteIdLong = archiveTreeContractClient.getNodeIdByName(
+                    req.getProjectName(),
+                    req.getContractName(),
+                    req.getNodeName()
+            );
+
+            if (remoteIdLong == null) {
+                throw new RuntimeException("无法找到匹配的节点: " +
+                        req.getProjectName() + "/" +
+                        req.getContractName() + "/" +
+                        req.getNodeName());
+            }
+
+            // 将 Long 转换为 String
+            req.setRemoteId(String.valueOf(remoteIdLong));
+        }
+
+        // 调用获取数据的方法
+        ExternalDataInfo externalDataInfo = externalTreeService.getDataByIds(
+                req.getNodeId(),
+                req.getRemoteId(),
+                req.getProjectName(),
+                req.getContractName(),
+                req.getNodeName(),
+                req.getTransType()
+        );
+
+        if (externalDataInfo == null) {
+            return;
+        }
 
         switch (req.getType()) {
             case 0:

+ 33 - 13
blade-service/blade-archive/src/main/java/org/springblade/archive/external/impl/ExternalDataArchiveFileService.java

@@ -40,7 +40,7 @@ public class ExternalDataArchiveFileService {
         List<ArchiveFile> upFiles = new ArrayList<>();
 
         //外部文件
-        List<ArchiveFile> externalFiles = listConvert(req.getNodeId(), req.getFiles(), externalDataInfo);
+        List<ArchiveFile> externalFiles = listConvert(req.getNodeId(), req.getFiles(), externalDataInfo,req.getTransType());
 
         List<String> outIds = Optional.ofNullable(externalFiles)
                 .orElseGet(Collections::emptyList)
@@ -55,13 +55,13 @@ public class ExternalDataArchiveFileService {
         //把本地的也加进去,一般用不到作为冗余手段
         updateFileMapping(externalDataInfo,localFiles);
         //比较获取
-        getAddAndUpdateFiles(externalDataInfo,externalFiles, localFiles, addFiles, upFiles);
+        getAddAndUpdateFiles(externalDataInfo,externalFiles, localFiles, addFiles, upFiles,req);
 
         //保存
         addAndUpdateFiles(addFiles,upFiles);
     }
 
-    public List<ArchiveFile> listConvert(String nodeId, List<ArchiveFileVo> archiveFileVos, ExternalDataInfo externalDataInfo) {
+    public List<ArchiveFile> listConvert(String nodeId, List<ArchiveFileVo> archiveFileVos, ExternalDataInfo externalDataInfo,Integer transType) {
 
         List<ArchiveFile> archiveFiles = new ArrayList<>();
         Map<String, Long> archiveFileOutIdMapping = new LinkedHashMap<>();
@@ -84,9 +84,14 @@ public class ExternalDataArchiveFileService {
 
             ArchiveFile archiveFile = new ArchiveFile();
 
-            // 拷贝属性
+            //
             archiveFile.fromExternal(archiveFileVo);
 
+            //模式1,只传递未组卷得案卷
+            if (transType != null && transType == 1) {
+                archiveFile.setIsArchive(0);
+            }
+
             // 设置新ID(从映射表中获取)
             Long newNodeId = archiveFileOutIdMapping.get(archiveFileVo.getId());
             archiveFile.setId(newNodeId);
@@ -127,7 +132,7 @@ public class ExternalDataArchiveFileService {
             List<ArchiveFile> externalFiles,
             List<ArchiveFile> localFiles,
             List<ArchiveFile> addFiles,
-            List<ArchiveFile> upFiles) {
+            List<ArchiveFile> upFiles,ArchiveReq req) {
 
         // 1. 提取本地文件的 outId 集合(用于快速判断外部文件是否已存在)
         Set<String> localOutIdSet = localFiles.stream()
@@ -155,7 +160,7 @@ public class ExternalDataArchiveFileService {
             } else {
                 // 存在则查找本地对应文件,判断是否需要更新
                 ArchiveFile localFile = localFileMap.get(externalOutId);
-                if (localFile != null && needUpdate(externalFile, localFile)) {
+                if (localFile != null && needUpdate(externalFile, localFile,req)) {
                     updateLocalFile(localFile, externalFile); // 更新字段
                     upFiles.add(localFile);
                 }
@@ -164,15 +169,30 @@ public class ExternalDataArchiveFileService {
     }
 
     // 辅助方法:判断是否需要更新
-    private boolean needUpdate(ArchiveFile external, ArchiveFile local) {
-        String extUtimeStr = formatTime(external.getUtime());
-        String localUtimeStr = formatTime(local.getUtime());
+// 辅助方法:判断是否需要更新
+    private boolean needUpdate(ArchiveFile external, ArchiveFile local, ArchiveReq req) {
+        // 处理 transType == 1 的情况
+        if (req.getTransType() != null && req.getTransType() == 1) {
+            // 比较 fileTime(避免空指针)和 sort 字段
+            String extFileTime = external.getFileTime();
+            String localFileTime = local.getFileTime();
+            boolean fileTimeDifferent = !Objects.equals(extFileTime, localFileTime);
+
+            boolean sortDifferent = !Objects.equals(external.getSort(), local.getSort());
+
+            return fileTimeDifferent || sortDifferent;
+        }
+        // 处理 transType == 0 和其他情况(默认逻辑)
+        else {
+            String extUtimeStr = formatTime(external.getUtime());
+            String localUtimeStr = formatTime(local.getUtime());
 
-        // 字符串严格比较:格式或内容不同即视为不一致
-        return !Objects.equals(extUtimeStr, localUtimeStr)
-                || !Objects.equals(external.getPdfPageUrl(), local.getPdfPageUrl());
-                //|| !Objects.equals(external.getArchiveId(), local.getArchiveId());
+            // 确保 external.getPdfPageUrl() 非空才比较(external有值)
+            boolean pdfUrlDifferent = external.getPdfPageUrl() != null &&
+                    !Objects.equals(external.getPdfPageUrl(), local.getPdfPageUrl());
 
+            return !Objects.equals(extUtimeStr, localUtimeStr) || pdfUrlDifferent;
+        }
     }
 
     /**

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

@@ -26,7 +26,27 @@ public class ExternalDataArchiveTreeService {
     private ArchivesAutoMapper autoMapper;
     private final MetadataClassificationClient metadataClassificationClient;
 
-    public  ExternalDataInfo getDataByIds(String nodeId, String remoteId){
+    public ExternalDataInfo getDataByIds(String nodeId, String remoteId,
+                                         String projectName, String contractName,
+                                         String nodeName, Integer transType) {
+
+        // 当 transType 为 1 时,重新获取 remoteId
+        if (transType != null && transType == 1) {
+            // 获取节点ID
+            Long remoteIdLong = archiveTreeContractClient.getNodeIdByName(
+                    projectName,
+                    contractName,
+                    nodeName
+            );
+
+            if (remoteIdLong == null) {
+                throw new RuntimeException("无法找到匹配的节点: " +
+                        projectName + "/" + contractName + "/" + nodeName);
+            }
+
+            // 将 Long 转换为 String
+            remoteId = String.valueOf(remoteIdLong);
+        }
         ExternalDataInfo externalDataInfo = TransUtil.getDataByIds(nodeId, remoteId);
 
         if (externalDataInfo.getParent() == null) {

+ 44 - 0
blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/ArchiveAiNameMapper.java

@@ -0,0 +1,44 @@
+/*
+ *      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.mapper;
+
+import io.lettuce.core.dynamic.annotation.Param;
+import org.springblade.archive.entity.ArchiveAiName;
+import org.springblade.archive.vo.ArchiveAiNameVO;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import java.util.List;
+
+/**
+ *  Mapper 接口
+ *
+ * @author BladeX
+ * @since 2025-07-03
+ */
+public interface ArchiveAiNameMapper extends BaseMapper<ArchiveAiName> {
+
+	/**
+	 * 自定义分页
+	 *
+	 * @param page
+	 * @param archiveAiName
+	 * @return
+	 */
+	List<ArchiveAiNameVO> selectArchiveAiNamePage(IPage page, ArchiveAiNameVO archiveAiName);
+
+    boolean deletedArchiveAiTask(@Param("taskId") Long taskId);
+}

+ 32 - 0
blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/ArchiveAiNameMapper.xml

@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.springblade.archive.mapper.ArchiveAiNameMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="archiveAiNameResultMap" type="org.springblade.archive.entity.ArchiveAiName">
+        <result column="id" property="id"/>
+        <result column="create_user" property="createUser"/>
+        <result column="create_dept" property="createDept"/>
+        <result column="create_time" property="createTime"/>
+        <result column="update_user" property="updateUser"/>
+        <result column="update_time" property="updateTime"/>
+        <result column="status" property="status"/>
+        <result column="is_deleted" property="isDeleted"/>
+        <result column="project_id" property="projectId"/>
+        <result column="contract_id" property="contractId"/>
+        <result column="task_id" property="taskId"/>
+        <result column="archive_auto_id" property="archiveAutoId"/>
+        <result column="archive_name" property="archiveName"/>
+        <result column="archive_name_ai" property="archiveNameAi"/>
+    </resultMap>
+    <update id="deletedArchiveAiTask">
+        update  u_archive_ai_name set is_deleted=1 where task_id=#{taskId}
+
+    </update>
+
+
+    <select id="selectArchiveAiNamePage" resultMap="archiveAiNameResultMap">
+        select * from u_archive_ai_name where is_deleted = 0
+    </select>
+
+</mapper>

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

@@ -224,4 +224,15 @@ 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);
+
+    List<ArchivesAutoVO4> selectAllArchiveAuto(@Param("projectId")Long projectId, @Param("contractId") Long contractId, @Param("nodeIds") List<String> nodeIds,@Param("isArchive")Integer isArchive);
+
+
+
+
+	void deleteIsElementFileByProjectId(@Param("projectId") Long projectId);
+
+	void deleteIsElementFileByNode(@Param("projectId") Long projectId,@Param("ancestors") String ancestors,@Param("nodeId") String nodeId);
 }

+ 65 - 18
blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/ArchivesAutoMapper.xml

@@ -49,6 +49,7 @@
         <result column="filing_unit" property="filingUnit"/>
         <result column="file_size" property="fileSize"/>
         <result column="is_reviewed" property="isReviewed"/>
+        <result column="colour_status" property="colourStatus"/>
     </resultMap>
 <!-- 带文件子查询的-->
     <resultMap id="archivesAutoResultMap2" type="org.springblade.archive.vo.ArchivesAutoVO">
@@ -215,6 +216,36 @@
         <result column="out_id" property="outId"/>
         <result column="sort_num" property="sortNum"/>
     </resultMap>
+    <update id="deleteIsElementFileByProjectId">
+        UPDATE u_archive_file set is_deleted = 1 WHERE archive_id in (
+            select id
+            from u_archives_auto
+            where project_id = #{projectId}
+              and is_auto_file!=1
+              and is_deleted=0
+              and is_lock!=1
+        ) and is_element = 1
+    </update>
+    <update id="deleteIsElementFileByNode">
+        UPDATE u_archive_file set is_deleted = 1 WHERE archive_id in (
+            select id
+            from u_archives_auto
+            where project_id = #{projectId}
+              AND is_auto_file != 1
+              AND is_deleted = 0
+              AND is_lock != 1
+              AND node_id IN (
+                SELECT id FROM m_archive_tree_contract
+                WHERE project_id = #{projectId}
+                    AND ancestors IS NOT NULL
+                    AND ancestors LIKE concat(''
+                        , #{ancestors}
+                        , '%')
+                   OR id = #{nodeId}
+            )
+        ) and is_element = 1
+    </update>
+
 
     <select id="approvalFile" resultType="org.springblade.archive.vo.ArchivesAutoVO$ApprovalFile">
         <if test="archiveId!=null">
@@ -1401,23 +1432,39 @@
     </select>
     <select id="getAllArchiveByContractTypeSummary" resultType="java.util.Map">
         select sum(a.key1 + a.key11) key1,sum(a.key2 + a.key12) key2,sum(a.key3 +a.key13) key3  from (
-         SELECT
-             sum( matc.tree_code IS NULL ) key3,
-             sum( matc.tree_code = 'S' ) key2,
-             sum( matc.tree_code = 'C' ) key1,
-             sum( mci.contract_type = 1 ) key11,
-             sum( mci.contract_type = 2 ) key12,
-             sum( mci.contract_type NOT IN ( 1, 2 )) key13
-         FROM
-             m_archive_tree_contract matc
-                 LEFT JOIN u_archives_auto uaa ON uaa.node_id = matc.id
-                 LEFT JOIN m_contract_info mci ON matc.tree_code = mci.id  and mci.is_deleted = 0
-         WHERE
-             uaa.project_id = #{projectId}
-           AND uaa.is_deleted = #{type}
-           AND uaa.is_destroy = #{type}
-        )a
+             SELECT
+                 IFNULL(sum( matc.tree_code IS NULL ),0) key3,
+                 IFNULL(sum( matc.tree_code = 'S' ),0) key2,
+                 IFNULL(sum( matc.tree_code = 'C' ),0) key1,
+                 IFNULL(sum( mci.contract_type = 1 ),0) key11,
+                 IFNULL(sum( mci.contract_type = 2 ),0) key12,
+                 IFNULL(sum( mci.contract_type NOT IN ( 1, 2 )),0) key13
+             FROM
+                 u_archives_auto uaa
+                     inner JOIN m_archive_tree_contract matc ON uaa.node_id = matc.id and matc.is_deleted = 0
+                     LEFT JOIN m_contract_info mci ON matc.tree_code = mci.id  and mci.is_deleted = 0
+             WHERE
+                 uaa.project_id = #{projectId}
+               AND uaa.is_deleted = #{type}
+               AND uaa.is_destroy = #{type}
+               AND uaa.is_archive = 1
+         )a
+    </select>
+    <select id="selectAllArchiveAuto" resultType="org.springblade.archive.vo.ArchivesAutoVO4">
+        select uaa.id ,uaa.file_number,uaa.node_id,uatc.parent_Id,uatc.file_number_prefix from u_archives_auto uaa left join m_archive_tree_contract uatc on uaa.node_id=uatc.id where uaa.is_deleted = 0 and uaa.project_id=#{projectId}
+        <choose>
+            <when test="isArchive != null and isArchive != ''">
+                and uaa.is_archive = #{isArchive}
+            </when>
+            <otherwise>
+                and (uaa.is_archive is null or uaa.is_archive != 1)
+            </otherwise>
+        </choose>
+        and uaa.node_id in
+        <foreach collection="nodeIds" item="nodeId" open="(" separator="," close=")">
+            #{nodeId}
+        </foreach>
+        order by uatc.tree_sort,uaa.auto_file_sort is null ,uaa.auto_file_sort,uaa.file_number is null,
+        SUBSTRING_INDEX(uaa.file_number, '_', 1), SUBSTRING_INDEX(uaa.file_number, '_', -1) + 0 ,uaa.create_time asc
     </select>
-
-
 </mapper>

+ 8 - 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,13 @@ 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);
+
+	//Integer updateArchiveByIds(String contractId,);
 }

+ 15 - 2
blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/TaskSplitMapper.xml

@@ -18,15 +18,28 @@
         <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 count(1) from u_archives_auto where contract_id = #{contractId} and is_deleted = 0
     </select>
 
+    <select id="getSpliteTaskCount" resultType="java.lang.Integer">
+        select count(1) from u_task_split where contract_id = #{contractId} and type=2
+    </select>
+
+<!--    <update id="updateArchiveByIds">
+        update u_archives_auto set status = 1 where contract_id = #{contractId} and id in
+        <foreach item="item" collection="ids" separator="," close=")" open="(" index="index">
+            #{item}
+        </foreach>
+    </update>-->
+
+
 </mapper>

+ 45 - 0
blade-service/blade-archive/src/main/java/org/springblade/archive/service/IArchiveAiNameService.java

@@ -0,0 +1,45 @@
+/*
+ *      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.service;
+
+import org.springblade.archive.entity.ArchiveAiName;
+import org.springblade.archive.vo.ArchiveAiNameVO;
+import org.springblade.archive.vo.ArchiveAiNameVO1;
+import org.springblade.core.mp.base.BaseService;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+
+import java.io.IOException;
+import java.util.List;
+
+/**
+ *  服务类
+ *
+ * @author BladeX
+ * @since 2025-07-03
+ */
+public interface IArchiveAiNameService extends BaseService<ArchiveAiName> {
+
+
+
+    void syncCreatAiName(List<ArchiveAiName> aiNames) throws IOException;
+
+    List<ArchiveAiNameVO> getArchiveAiTask(Long projectId, Long contractId);
+
+    boolean confirmAiName(List<ArchiveAiNameVO1>vos);
+
+    Boolean deletedArchiveAiTask(Long taskId);
+}

+ 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,boolean useCovering
+    );
+}

+ 16 - 1
blade-service/blade-archive/src/main/java/org/springblade/archive/service/IArchivesAutoService.java

@@ -18,6 +18,7 @@ package org.springblade.archive.service;
 
 
 import org.springblade.archive.dto.ArchiveWarningDTO;
+import org.springblade.archive.dto.FindAndReplaceDto;
 import org.springblade.archive.dto.JiLinQueryDto;
 import org.springblade.archive.dto.SaveApplyDTO;
 import org.springblade.archive.entity.ArchiveConclusion;
@@ -25,6 +26,7 @@ import org.springblade.archive.entity.ArchivesAuto;
 import org.springblade.archive.entity.ExpertInspection;
 import org.springblade.archive.entity.JiLinArchiveAutoDto;
 import org.springblade.archive.vo.*;
+import org.springblade.business.entity.ArchiveFile;
 import org.springblade.core.mp.base.BaseService;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import org.springblade.core.mp.support.Query;
@@ -88,7 +90,7 @@ public interface IArchivesAutoService extends BaseService<ArchivesAuto> {
 	//刷新某个项目的档号
 	void refreshFileNumberNoSlipt(Long projectId,Long contractId,Long nodeId,boolean bforce, Long traceId);
 
-	void test();
+	void test666();
 
     List<DictBiz> getCarrierTypeByDict();
 
@@ -154,4 +156,17 @@ 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);
+
+    void fileNumberFlush(Long projectId, Long contractId, List<String> nodeIds,Integer isArchive,Integer startNumber);
+
+    boolean reBuildArchiveFrontPdfs(String archiveIds, Long projectId);
+
+    boolean findAndReplace(List<ArchivesAuto> archivesAutos, FindAndReplaceDto dto);
+
+	void reCreateArchiveAuto(ArchivesAuto archivesAuto, List<ArchiveFile> waitArchiveFiles);
+
+
+	boolean creatFileNameFormAI(String ids, Long projectId, Long contractId) throws IOException;
 }

+ 155 - 0
blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchiveAiNameServiceImpl.java

@@ -0,0 +1,155 @@
+/*
+ *      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.service.impl;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import org.apache.commons.lang.StringUtils;
+import org.springblade.archive.entity.ArchiveAiName;
+import org.springblade.archive.mapper.ArchiveAiNameMapper;
+import org.springblade.archive.service.IArchiveAiNameService;
+import org.springblade.archive.vo.ArchiveAiNameVO;
+import org.springblade.archive.vo.ArchiveAiNameVO1;
+import org.springblade.common.utils.DeepSeekClient;
+import org.springblade.core.mp.base.BaseServiceImpl;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.jdbc.core.BeanPropertyRowMapper;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.Resource;
+import java.text.SimpleDateFormat;
+import java.util.*;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.stream.Collectors;
+
+import static java.util.stream.Collectors.groupingBy;
+
+/**
+ *  服务实现类
+ *
+ * @author BladeX
+ * @since 2025-07-03
+ */
+@Service
+public class ArchiveAiNameServiceImpl extends BaseServiceImpl<ArchiveAiNameMapper, ArchiveAiName> implements IArchiveAiNameService {
+
+	 private static String DEEPSEEK_ARCHIVE_NAME = ".这是一段案卷题名,精简案卷题名重复啰嗦的内容,不要加以上内容没有的词语 返回值不要有任何多余得废话,只要结果";
+	 private static final int MAX_CONCURRENT_REQUESTS = 5;
+
+	@Autowired
+	private JdbcTemplate jdbcTemplate;
+
+	@Autowired
+	private DeepSeekClient deepSeekClient;
+
+	@Resource(name = "taskExecutor1")
+	private ThreadPoolExecutor executor;
+
+	private final Semaphore apiSemaphore = new Semaphore(MAX_CONCURRENT_REQUESTS);
+
+	@Override
+	@Async("taskExecutor1")
+	@Transactional
+	public void syncCreatAiName(List<ArchiveAiName> aiNames) {
+		aiNames.parallelStream().forEach(name -> {
+			try {
+				apiSemaphore.acquire();
+				try {
+					String content = deepSeekClient.getSimplifiedContent(name.getArchiveName() + DEEPSEEK_ARCHIVE_NAME);
+					if (content.startsWith("API_ERROR:") ||
+							content.startsWith("PARSE_ERROR:") ||
+							content.startsWith("IO_ERROR:")||content.startsWith("Error:")) {
+						name.setStatus(4);
+						name.setArchiveNameAi("获取失败");
+					} else {
+						name.setArchiveNameAi(content);
+						name.setStatus(2); // 标记为成功
+					}
+				} finally {
+					apiSemaphore.release();
+				}
+			} catch (InterruptedException e) {
+				Thread.currentThread().interrupt();
+				name.setStatus(4); // 设置失败状态
+				name.setArchiveNameAi("获取失败");
+			} catch (Exception e) {
+				name.setStatus(4); // 设置失败状态
+				name.setArchiveNameAi("获取失败");
+			}
+		});
+
+		// 分批更新数据库
+		int batchSize = 100;
+		for (int i = 0; i < aiNames.size(); i += batchSize) {
+			int end = Math.min(i + batchSize, aiNames.size());
+			List<ArchiveAiName> batch = aiNames.subList(i, end);
+			this.updateBatchById(batch);
+		}
+	}
+
+	@Override
+	public List<ArchiveAiNameVO> getArchiveAiTask(Long projectId, Long contractId) {
+		List<ArchiveAiNameVO>list=new ArrayList<>();
+		List<ArchiveAiName> archiveAiNameList = this.baseMapper.selectList(new LambdaQueryWrapper<>(ArchiveAiName.class).eq(ArchiveAiName::getProjectId, projectId).eq(ArchiveAiName::getContractId, contractId));
+		if(!archiveAiNameList.isEmpty()){
+			Map<Long, List<ArchiveAiName>> map = archiveAiNameList.stream().collect(groupingBy(ArchiveAiName::getTaskId));
+			for (Map.Entry<Long, List<ArchiveAiName>> entry : map.entrySet()) {
+				ArchiveAiNameVO archiveAiNameVO = new ArchiveAiNameVO();
+				List<ArchiveAiName> archiveAiNames = entry.getValue();
+				archiveAiNameVO.setTaskId(entry.getKey());
+				Date createTime = archiveAiNames.get(0).getCreateTime();
+				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+				String formattedDate = sdf.format(createTime);
+				archiveAiNameVO.setTaskTime(formattedDate);
+				archiveAiNameVO.setNum(archiveAiNames.size());
+				archiveAiNameVO.setStatus(archiveAiNames.stream().allMatch(ai -> ai.getStatus() >1) ? 2:1);
+				list.add(archiveAiNameVO);
+			}
+		}
+		return list;
+	}
+
+
+	@Transactional
+	public boolean confirmAiName(List<ArchiveAiNameVO1>vos) {
+		for (ArchiveAiNameVO1 archiveAiName : vos) {
+			if(archiveAiName.getStatus()==2&& StringUtils.isNotEmpty(archiveAiName.getArchiveNameAi())){
+				archiveAiName.setStatus(3);
+				String sql=" update u_archives_auto set name='"+archiveAiName.getArchiveNameAi()+"', colour_status=2  where id="+archiveAiName.getArchiveAutoId();
+				jdbcTemplate.update(sql);
+				String sql2="update u_archive_ai_name set status=3 where id="+archiveAiName.getId();
+				jdbcTemplate.update(sql2);
+			}
+		}
+		Long taskId = vos.get(0).getTaskId();
+		String sql3="select * from u_archive_ai_name where task_id="+taskId+" and is_deleted=0";
+		List<ArchiveAiName> list = jdbcTemplate.query(sql3, new BeanPropertyRowMapper<>(ArchiveAiName.class));
+		if(list.stream().allMatch(item -> item.getStatus() >= 3)){
+			deletedArchiveAiTask(taskId);
+		};
+		return true;
+	}
+
+	@Override
+	public Boolean deletedArchiveAiTask(Long taskId) {
+		return baseMapper.deletedArchiveAiTask(taskId);
+	}
+}

+ 117 - 8
blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchiveAutoPdfServiceImpl.java

@@ -26,6 +26,7 @@ import org.springblade.common.utils.SystemUtils;
 import org.springblade.common.vo.DataVO;
 import org.springblade.common.vo.FileSize;
 import org.springblade.core.oss.model.BladeFile;
+import org.springblade.core.tool.utils.BeanUtil;
 import org.springblade.core.tool.utils.ObjectUtil;
 import org.springblade.core.tool.utils.ResourceUtil;
 import org.springblade.core.tool.utils.StringUtil;
@@ -41,10 +42,7 @@ import java.io.OutputStream;
 import java.io.*;
 import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 import java.util.stream.Collectors;
 
 @Slf4j
@@ -280,12 +278,70 @@ public class ArchiveAutoPdfServiceImpl implements IArchiveAutoPdfService {
 
         //统计文件大小
         RefreshFileSize(archivesAuto, archiveFileList, frontUrls);
-
+        // todo 四要素持久化
+        saveElementFiles(archivesAuto, archiveFileList.get(0), frontUrls);
         String joinedUrls = String.join(", ", frontUrls);
         archivesAuto.setOutUrl(joinedUrls);
         archivesAuto.setSecretLevel(secretLevel);
         archivesAuto.setStorageTime(storageTime);
     }
+    private void saveElementFiles(ArchivesAuto archivesAuto, ArchiveFile archiveFile, List<String> frontUrls) {
+        List<ArchiveFile> archiveFiles = new ArrayList<>();
+        if (frontUrls != null && !frontUrls.isEmpty()) {
+            try {
+                for (String frontUrl : frontUrls) {
+                    // 封面(原r_Archives_front)增加中文"封面"匹配
+                    ArchiveFile file = new ArchiveFile();
+                    String fileName = null;
+                    String fileUrl;
+                    int sort = 0;
+                    if (frontUrl.contains(ArchiveAutoPdfServiceImpl.ARCHIVE_NUMBER[0])
+                            || frontUrl.contains("封面")) {
+                        fileName = "封面";
+                        sort = -4;
+                    }
+                    // 卷内目录(原r_Archives_catalog)增加中文匹配
+                    else if (frontUrl.contains(ArchiveAutoPdfServiceImpl.ARCHIVE_NUMBER[1])
+                            || frontUrl.contains("卷内目录")) {
+                        fileName = "卷内目录";
+                        sort = -3;
+                    }
+                    // 备考表(原r_Archives_spare)增加中文匹配
+                    else if (frontUrl.contains(ArchiveAutoPdfServiceImpl.ARCHIVE_NUMBER[2])
+                            || frontUrl.contains("备考表")) {
+                        fileName = "备考表";
+                        sort = (int)(archivesAuto.getFileSize() + 100);
+                    }
+                    // 背脊(原r_Archives_back)增加中文匹配
+                    else if (frontUrl.contains(ArchiveAutoPdfServiceImpl.ARCHIVE_NUMBER[3])
+                            || frontUrl.contains("背脊")) {
+                        fileName = "背脊";
+                        sort = (int)(archivesAuto.getFileSize() + 101);
+                    }
+                    if(frontUrl.contains("@@@")){
+                        fileUrl = frontUrl.substring(0,frontUrl.indexOf("@@@"));
+                    }else {
+                        fileUrl = frontUrl;
+                    }
+                    if (fileName == null || fileUrl == null) {
+                        continue;
+                    }
+                    BeanUtil.copy(archiveFile, file);
+                    file.setFileName(fileName);
+                    file.setFileUrl(fileUrl);
+                    file.setPdfFileUrl(fileUrl);
+                    file.setIsElement(1);
+                    file.setSort(sort);
+                    archiveFiles.add(file);
+                }
+                if (!archiveFiles.isEmpty()) {
+                    archiveFileClient.addArchiveFile(archiveFiles);
+                }
+            } catch (Exception e) {
+                log.error("保存档案四要素失败:" + e);
+            }
+        }
+    }
 
     /**
      * 打码
@@ -321,7 +377,7 @@ public class ArchiveAutoPdfServiceImpl implements IArchiveAutoPdfService {
                 urls.add(url);
             }
         }
-        String localPath = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
+        String localPath = FileUtils.getSysLocalFileUrl();
         List<String> pageUrls = FileUtils.doForPageNumberUseItextpdf(urls, localPath, newIOSSClient, archivesAuto.getProjectId());
         for (int i = 0; i < waitArchiveFiles.size(); i++) {
             waitArchiveFiles.get(i).setPdfPageUrl(pageUrls.get(i));
@@ -561,6 +617,9 @@ public class ArchiveAutoPdfServiceImpl implements IArchiveAutoPdfService {
             }else {
                 object = "";
             }
+
+            //秘级用空
+            object = "";
         }
 
         dataInfo.put(key, object);
@@ -671,7 +730,46 @@ public class ArchiveAutoPdfServiceImpl implements IArchiveAutoPdfService {
 //                                    newStyle.setWrapText(true);
 //                                    cell.setCellStyle(newStyle);
 //                                }
-                                cell.setCellValue(myData);
+                                // ====================== 核心修改开始 ======================
+                                if (myData.startsWith("twospaces")) {
+                                    // 1. 去掉开头的"twospaces",并添加"占位"两个汉字
+                                    String actualText = myData.substring("twospaces".length()).trim();
+                                    String displayText = "占位" + actualText;
+
+                                    // 2. 创建富文本格式:白色"占位"+默认颜色实际文本
+                                    CreationHelper helper = workbook.getCreationHelper();
+                                    RichTextString richText = helper.createRichTextString(displayText);
+
+                                    // 创建白色字体(用于"占位"两字)
+                                    Font whiteFont = workbook.createFont();
+                                    whiteFont.setColor(IndexedColors.WHITE.getIndex());
+
+                                    // 创建默认黑色字体(用于实际文本)
+                                    Font defaultFont = workbook.createFont();
+                                    defaultFont.setColor(IndexedColors.BLACK.getIndex());
+
+                                    // 🔴 修复:正确设置索引范围
+                                    // "占位"是两个字符,索引0-1
+                                    richText.applyFont(0, 2, whiteFont);  // 第0-1个字符:白色
+
+                                    // 剩余字符:黑色(从索引2开始)
+                                    if (displayText.length() > 2) {
+                                        richText.applyFont(3, displayText.length() - 1, defaultFont);
+                                    }
+
+                                    // 3. 设置单元格值
+                                    cell.setCellValue(richText);
+
+                                    // 4. 设置单元格样式确保白色文字不可见
+                                    CellStyle style = workbook.createCellStyle();
+                                    style.cloneStyleFrom(cell.getCellStyle());
+                                    style.setWrapText(true);  // 保持自动换行
+                                    cell.setCellStyle(style);
+
+                                } else {
+                                    // 非"twospaces"开头的正常处理
+                                    cell.setCellValue(myData);
+                                }
                             }
                         }
                     }
@@ -723,7 +821,7 @@ public class ArchiveAutoPdfServiceImpl implements IArchiveAutoPdfService {
                 file.setFid(idx);
                 //设置文件编号
                 if (StringUtil.isEmpty(file.getFileNumber())) {
-                    file.setFileNumber("\\");
+                    //file.setFileNumber("\\");
                 }
                 //设置页数
                 file.setPageNum(iStartPage.toString());
@@ -738,7 +836,15 @@ public class ArchiveAutoPdfServiceImpl implements IArchiveAutoPdfService {
                 }
             }
 
+            file.setFileTime(FileUtils.cleanFileTime(file.getFileTime()));
+
             Map<String, Object> fileMap = new ObjectMapper().convertValue(file, Map.class);
+
+            if (fileMap.containsKey("fileName") && fileMap.get("fileName") != null) {
+                String fileName = fileMap.get("fileName").toString();
+                fileMap.put("fileName", "twospaces" + fileName); // 添加两个空格前缀
+            }
+
             fileMapList.add(fileMap);
         }
         //设置总页数
@@ -823,6 +929,9 @@ public class ArchiveAutoPdfServiceImpl implements IArchiveAutoPdfService {
         try {
             if (file != null) {
                 url = file.getPdfFileUrl();
+                if(StringUtils.isNotEmpty(file.getEVisaFile())&& !Objects.equals(file.getPdfFileUrl(),file.getEVisaFile())){
+                    url=file.getEVisaFile();
+                }
                 if (StringUtil.isEmpty(url)) {
                     String fileUrl = file.getFileUrl();
                     if (fileUrl != null && StringUtils.isNotEmpty(fileUrl) && fileUrl.endsWith(".pdf")) {

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

@@ -0,0 +1,438 @@
+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()) {
+            // 直接使用Set<Long>,无需转换为字符串
+            List<Long> ancestorIdsList = new ArrayList<>(missingAncestorIds);
+
+            // 使用新方法调用
+            missingAncestors = archiveTreeContractClient
+                    .getArchiveTreeContractListByList(ancestorIdsList);
+
+            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,boolean useCovering
+    ) {
+        // 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. 按祖父节点分组 (二级分组)
+        Map<Long, List<Map.Entry<Long, List<ArchiveTreeContract>>>> grandParentGroups = new LinkedHashMap<>();
+        for (Map.Entry<Long, List<ArchiveTreeContract>> entry : parentGroups.entrySet()) {
+            Long parentId = entry.getKey();
+            ArchiveTreeContract parentNode = allNodeMap.get(parentId);
+            Long grandParentId = (parentNode != null) ? parentNode.getParentId() : null;
+            grandParentGroups.computeIfAbsent(grandParentId, k -> new ArrayList<>()).add(entry);
+        }
+
+        // 4. 处理分组
+        List<String> nameParts = new ArrayList<>();
+        for (Map.Entry<Long, List<Map.Entry<Long, List<ArchiveTreeContract>>>> grandEntry : grandParentGroups.entrySet()) {
+            Long grandParentId = grandEntry.getKey();
+            List<Map.Entry<Long, List<ArchiveTreeContract>>> directParentGroups = grandEntry.getValue();
+
+            // 尝试在祖父节点级别合并
+            boolean canUseGrandParentName = false;
+            if (grandParentId != null) {
+                ArchiveTreeContract grandParentNode = allNodeMap.get(grandParentId);
+                if (grandParentNode != null) {
+                    // 获取祖父节点的所有直接子节点
+                    List<ArchiveTreeContract> grandChildren = hierarchy.getChildren(grandParentId);
+                    if (grandChildren != null && !grandChildren.isEmpty()) {
+                        // 检查是否覆盖所有直接子节点
+                        boolean allChildrenCovered = true;
+                        Set<Long> coveredParentIds = new HashSet<>();
+                        for (Map.Entry<Long, List<ArchiveTreeContract>> directEntry : directParentGroups) {
+                            coveredParentIds.add(directEntry.getKey());
+                        }
+
+                        // 验证所有子节点都被覆盖
+                        for (ArchiveTreeContract child : grandChildren) {
+                            if (!coveredParentIds.contains(child.getId())) {
+                                allChildrenCovered = false;
+                                break;
+                            }
+                        }
+
+                        // 验证每个被覆盖的子节点组是否都是全覆盖状态
+                        if (allChildrenCovered) {
+                            boolean allGroupsFullyCovered = true;
+                            for (Map.Entry<Long, List<ArchiveTreeContract>> directEntry : directParentGroups) {
+                                List<ArchiveTreeContract> groupNodes = directEntry.getValue();
+                                // 获取该父节点的所有子节点
+                                List<ArchiveTreeContract> childrenOfParent = hierarchy.getChildren(directEntry.getKey());
+                                int childrenCount = (childrenOfParent != null) ? childrenOfParent.size() : 0;
+
+                                // 检查是否全覆盖
+                                if (childrenCount == 0 || groupNodes.size() != childrenCount) {
+                                    allGroupsFullyCovered = false;
+                                    break;
+                                }
+                            }
+
+                            if (allGroupsFullyCovered && useCovering) {
+                                nameParts.add(getLevelName(hierarchy, grandParentId));
+                                canUseGrandParentName = true;
+                            }
+                        }
+                    }
+                }
+            }
+
+            if (canUseGrandParentName) {
+                continue; // 已使用祖父节点名称,跳过直接父节点处理
+            }
+
+            // 处理直接父节点组
+            boolean firstParentInGroup = true;
+            for (Map.Entry<Long, List<ArchiveTreeContract>> directEntry : directParentGroups) {
+                Long groupId = directEntry.getKey();
+                List<ArchiveTreeContract> groupNodes = directEntry.getValue();
+                ArchiveTreeContract parent = allNodeMap.get(groupId);
+
+                if (parent == null) {
+                    // 无父节点的情况:添加所有节点名称(用顿号分隔)
+                    String nodeNames = groupNodes.stream()
+                            .map(ArchiveTreeContract::getNodeName)
+                            .collect(Collectors.joining("、"));
+                    nameParts.add(nodeNames);
+                    continue;
+                }
+
+                // 获取直接子节点
+                List<ArchiveTreeContract> allChildren = hierarchy.getChildren(groupId);
+                int childrenCount = (allChildren != null) ? allChildren.size() : 0;
+
+                // 检查是否全覆盖所有子节点
+                if (childrenCount > 0 && groupNodes.size() == childrenCount ) {
+                    // 只有组内第一个父节点使用完整层级名称
+                    String parentName = firstParentInGroup ?
+                            getLevelName(hierarchy, groupId) :
+                            parent.getNodeName();
+
+                    nameParts.add(parentName);
+                } else {
+                    // 获取父节点名称
+                    String parentName = firstParentInGroup ?
+                            getLevelName(hierarchy, groupId) :
+                            parent.getNodeName();
+
+                    // 部分覆盖:添加父节点名称+子节点名称(用顿号分隔)
+                    String childNames = groupNodes.stream()
+                            .map(ArchiveTreeContract::getNodeName)
+                            .collect(Collectors.joining("、"));
+                    // 修改点:根据条件决定添加的内容
+                    if (!useCovering ) {
+                        // 当 useCovering=false 且不是第一个父节点时,只添加子节点名称
+                        nameParts.add(childNames);
+                    } else {
+                        // 其他情况:添加父节点名称+子节点名称
+                        nameParts.add(parentName + childNames);
+                    }
+                }
+
+                // 后续节点不再是第一个
+                firstParentInGroup = false;
+            }
+        }
+
+        // 5. 拼接最终结果
+        return String.join("、", nameParts);
+    }
+    public String generateFullLevelName1(
+            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);
+    }
+}

File diff suppressed because it is too large
+ 498 - 147
blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchivesAutoServiceImpl.java


+ 38 - 3
blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/TaskSplitServiceImpl.java

@@ -24,11 +24,18 @@ 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.List;
+import java.util.Map;
+import java.util.Random;
 
 /**
  * 解析主标任务 服务实现类
@@ -51,6 +58,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 +68,46 @@ 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(30) + 150; // 生成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);
+			//String[] split = splitIds.split(",");
+			List<String> split = Func.toStrList(splitIds);
+			taskSplit.setToolCount(split.size());
 			taskSplit.setFinished(0);
+
+			// 修改当前文件的状体
+			// baseMapper.updateArchiveByIds(contractId,splitIds);
+
+
+			Random random = new Random();
+			int randomNumber = random.nextInt(30) + 150;// 生成10到20之间的随机数
+			int i = (int) Math.ceil(randomNumber * split.size()/60.0 );
+			data.put("fileCount",split.size());
+			data.put("taskTime",i);
+			LocalDateTime now = LocalDateTime.now();
+			DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd HH:mm:ss");
+			String formattedDateTime = now.format(formatter)+"_"+split.size()+"条分解任务";
+			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) {
             // 异常处理逻辑,比如打印日志

+ 6 - 0
blade-service/blade-archive/src/main/java/org/springblade/archive/utils/FileUtils.java

@@ -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;
+    }
+
 }

+ 1 - 1
blade-service/blade-business/pom.xml

@@ -194,7 +194,7 @@
                     <target>${java.version}</target>
                     <encoding>${project.build.sourceEncoding}</encoding>
                     <compilerArguments>
-                        <bootclasspath>${java.home}/lib/rt.jar;${java.home}/lib/jce.jar;${java.home}/lib/jsse.jar
+                        <bootclasspath>${java.home}/lib/rt.jar:${java.home}/lib/jce.jar:${java.home}/lib/jsse.jar
                         </bootclasspath>
                     </compilerArguments>
                 </configuration>

+ 30 - 3
blade-service/blade-business/src/main/java/org/springblade/business/controller/EVisaTaskCheckController.java

@@ -844,9 +844,36 @@ public class EVisaTaskCheckController {
             if (ids == null || ids.size() == 0) {
                 return null;
             }
-            String sql = "select * from m_textdict_info where id in(" + StringUtils.join(ids, ",") + ") ";
-            List<TextdictInfo> query = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(TextdictInfo.class));
-            jsonList = JSONArray.parseArray(JSONObject.toJSONString(query), JSONObject.class);
+        Map<String, List<String>> groupMap = ids.stream().collect(Collectors.groupingBy(str -> {
+            if (str.contains("✹")) {
+                return "sign";
+            }
+            return "dqid";
+        }));
+        List<String> dqIds = groupMap.get("dqid");
+        List<TextdictInfo> query = null;
+        if (dqIds != null && !dqIds.isEmpty()) {
+            String sql = "select * from m_textdict_info where id in(" + StringUtils.join(dqIds, ",") + ") ";
+            query = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(TextdictInfo.class));
+        }
+        List<String> signList = groupMap.get("sign");
+        if (signList != null && !signList.isEmpty()) {
+            String signIds = signList.stream().map(sign -> sign.replace("✹", "")).collect(Collectors.joining(","));
+            String sql = "SELECT distinct conf_id,relation_id from m_sign_config_relation WHERE conf_id in ( " + signIds + ") and type = 1 and is_deleted = 0";
+            List<SignConfigRelation> signConfigRelationList = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(SignConfigRelation.class));
+            if (!signConfigRelationList.isEmpty()) {
+                if (query == null) {
+                    query = new ArrayList<>();
+                }
+                for (SignConfigRelation relation : signConfigRelationList) {
+                    TextdictInfo textdictInfo = new TextdictInfo();
+                    textdictInfo.setId(relation.getConfId());
+                    textdictInfo.setSigRoleId(relation.getRelationId() + "");
+                    query.add(textdictInfo);
+                }
+            }
+        }
+        jsonList = JSONArray.parseArray(JSONObject.toJSONString(query), JSONObject.class);
 //        }
         return jsonList;
     }

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

@@ -1456,7 +1456,7 @@ public R<String> batchDownloadFileToZip(String ids, HttpServletResponse response
                     String[] idss = query.stream()
                             .map(item -> String.valueOf(item.getId()))
                             .toArray(String[]::new);
-                    String update = "update u_entrust_info set status=3 where id in(" + String.join(",", idss) + ")";
+                    String update = "update u_entrust_info set status=4 where id in(" + String.join(",", idss) + ")";
                     jdbcTemplate.execute(update);
                 }
                 return R.success("操作成功");
@@ -1897,6 +1897,8 @@ public R<Boolean> copyContractTreeNode(@RequestBody CopyContractTreeNodeVO vo) {
                 newData.setIsTabPdf(1);
                 newData.setPdfUrl(null);
                 newData.setCreateUser(AuthUtil.getUserId());
+                //设置日期检查
+                newData.setDateIsComplete(null);
                 newData.setSort(ObjectUtil.isNotEmpty(nodeOld.getSort()) ? nodeOld.getSort() : 0);
                 //重构 祖级节点
                 this.restoreParent(newData, oldToNewIdMap);
@@ -2624,7 +2626,8 @@ private void addCopyTabData(WbsTreeContract needCopyNode, WbsTreeContract toCopy
                         objTab.setCreateTime(new Date());
                         //获取当前复制的表的sort
                         objTab.setSort(ObjectUtils.isNotEmpty(needTab.getSort()) ? needTab.getSort() : 0);
-
+                        //设置日期检查
+                        objTab.setDateIsComplete(null);
                         //复制表
                         addChildNodesTablesAll.add(objTab);
 
@@ -2711,6 +2714,8 @@ private void addCopyNodesAndTabsBuildData(List<WbsTreeContract> addNodeList, Lis
                 obj.setFullName(toCopyNode.getNodeName());
                 obj.setPartitionCode(toCopyNode.getPartitionCode());
                 obj.setCreateTime(new Date());
+                //设置日期检查
+                obj.setDateIsComplete(null);
                 //获取当前复制的节点的sort
                 obj.setSort(ObjectUtils.isNotEmpty(needNode.getSort()) ? needNode.getSort() : 0);
                 addNodeList.add(obj);
@@ -2746,6 +2751,8 @@ private void addCopyNodesAndTabsBuildData(List<WbsTreeContract> addNodeList, Lis
                 obj.setCreateTime(new Date());
                 //获取当前复制的表的sort
                 obj.setSort(ObjectUtils.isNotEmpty(needTab.getSort()) ? needTab.getSort() : 0);
+                //设置日期检查
+                obj.setDateIsComplete(null);
 
                 addTabList.add(obj);
 
@@ -2857,8 +2864,10 @@ private void addCopyNodesAndTabsBuildData(List<WbsTreeContract> addNodeList, Lis
                 obj.setCreateTime(new Date());
                 //获取当前复制的节点的sort
                 obj.setSort(ObjectUtils.isNotEmpty(node.getSort()) ? node.getSort() : 0);
-
+                //设置日期检查
+                obj.setDateIsComplete(null);
                 addNodeList.add(obj);
+
                 if (obj.getNodeType() != null && obj.getNodeType() == 6) {
                     peerMap.put(obj.getPKeyId(), node.getPKeyId());
                 }
@@ -2893,6 +2902,8 @@ private void addCopyNodesAndTabsBuildData(List<WbsTreeContract> addNodeList, Lis
                             objTab.setCreateTime(new Date());
                             //获取当前复制的表的sort
                             objTab.setSort(ObjectUtils.isNotEmpty(needTab.getSort()) ? needTab.getSort() : 0);
+                            //设置日期检查
+                            objTab.setDateIsComplete(null);
 
                             addTabList.add(objTab);
 

+ 64 - 4
blade-service/blade-business/src/main/java/org/springblade/business/controller/PrivateStandardController.java

@@ -3,18 +3,24 @@ package org.springblade.business.controller;
 
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiImplicitParam;
 import io.swagger.annotations.ApiOperation;
 import org.springblade.business.dto.PrivateStandardDTO;
 import org.springblade.business.entity.PrivateStandard;
+import org.springblade.business.entity.StandardFile;
 import org.springblade.business.service.PrivateStandardService;
+import org.springblade.business.service.StandardFileService;
 import org.springblade.common.utils.SnowFlakeUtil;
 import org.springblade.core.mp.support.Query;
 import org.springblade.core.secure.BladeUser;
 import org.springblade.core.secure.utils.SecureUtil;
 import org.springblade.core.tool.api.R;
+import org.springblade.core.tool.utils.BeanUtil;
+import org.springblade.core.tool.utils.CollectionUtil;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
@@ -38,6 +44,9 @@ public class PrivateStandardController {
     @Resource
     private PrivateStandardService privateStandardService;
 
+    @Resource
+    private StandardFileService standardFileService;
+
     /**
      * 分页查询所有数据
      *
@@ -47,10 +56,21 @@ public class PrivateStandardController {
      */
     @GetMapping("page")
     @ApiOperation(value = "分页查询所有数据", notes = "传入分页对象和高级查询对象")
-    public R<IPage<PrivateStandard>> selectAll(Query query, PrivateStandard privateStandard) {
+    public R<IPage<PrivateStandardDTO>> selectAll(Query query, PrivateStandard privateStandard) {
         try {
             Page page = new Page(query.getCurrent(), query.getSize());
-            IPage<PrivateStandard> resultPage = this.privateStandardService.page(page, new QueryWrapper<>(privateStandard));
+            IPage<PrivateStandardDTO> resultPage = this.privateStandardService.page(page, new QueryWrapper<>(privateStandard));
+            if(privateStandard.getType() != null && privateStandard.getType() == 2){
+                List<PrivateStandardDTO> privateStandardDTOS = BeanUtil.copyProperties(resultPage.getRecords(), PrivateStandardDTO.class);
+                for (PrivateStandardDTO record : privateStandardDTOS) {
+                    List<StandardFile> list = standardFileService.list(Wrappers.<StandardFile>lambdaQuery()
+                            .eq(StandardFile::getStandardId, record.getId())
+                            .eq(StandardFile::getIsDeleted, 0)
+                            .last("limit 1"));
+                    record.setStandardFile(CollectionUtils.isNotEmpty(list) ? list.get(0) : null);
+                }
+                resultPage.setRecords(privateStandardDTOS);
+            }
             return R.data(resultPage);
         } catch (Exception e) {
             // 可根据实际需求记录日志或返回特定错误信息
@@ -68,9 +88,15 @@ public class PrivateStandardController {
     @ApiOperation(value = "通过主键查询单条数据", notes = "传入主键Id")
     @ApiImplicitParam(name = "id", value = "主键id", required = true)
     @GetMapping("/getById")
-    public R<PrivateStandard> selectOne(Long id) {
+    public R<PrivateStandardDTO> selectOne(Long id) {
         PrivateStandard byId = this.privateStandardService.getById(id);
-        return R.data(byId);
+        List<StandardFile> list = standardFileService.list(Wrappers.<StandardFile>lambdaQuery()
+                .eq(StandardFile::getStandardId, id)
+                .eq(StandardFile::getIsDeleted, 0));
+
+        PrivateStandardDTO privateStandardDTO = BeanUtil.copyProperties(byId, PrivateStandardDTO.class);
+        privateStandardDTO.setStandardFiles(list);
+        return R.data(privateStandardDTO);
     }
 
     /**
@@ -108,6 +134,27 @@ public class PrivateStandardController {
         return R.data(save);
     }
 
+
+    /**
+     * 规范文件修改数据
+     *
+     * @param data 实体对象
+     * @param delIds 需要删除的规范文件id集合
+     * @param delFileIds 需要删除的文件id集合
+     * @param files 文件
+     * @return 新增结果
+     */
+    @PostMapping("updateTypeByTwo")
+    @ApiOperation(value = "规范文件修改数据")
+    public R<Boolean> updateTypeByTwo(@RequestPart("data") @Validated List<PrivateStandardDTO> data,
+                             @RequestPart("delIds")  List<Long> delIds,
+                             @RequestPart("delFileIds") List<Long> delFileIds,
+                             @RequestPart("files") MultipartFile[] files) {
+        //封装数据
+        boolean save = this.privateStandardService.updateTypeByTwo(data,delIds,delFileIds,files);
+        return R.data(save);
+    }
+
     /**
      * 修改数据
      *
@@ -148,5 +195,18 @@ public class PrivateStandardController {
         boolean b = this.privateStandardService.deleteFile(id);
         return R.data(b);
     }
+
+    /**
+     * 规范更新
+     * @param id 规范文件id
+     */
+    @ApiOperation(value = "规范更新")
+    @GetMapping("/standardUpdate")
+    @ApiImplicitParam(name = "id", value = "规范文件id", required = true)
+    public R<Long> standardUpdate(Long id) {
+        Long b = this.privateStandardService.standardUpdate(id);
+        return R.data(b);
+    }
+
 }
 

Some files were not shown because too many files changed in this diff