Просмотр исходного кода

Merge branch 'refs/heads/dev' into feature-lihb-20250710

LHB 1 месяц назад
Родитель
Сommit
1442de5b72
100 измененных файлов с 5680 добавлено и 168 удалено
  1. 14 0
      blade-common/pom.xml
  2. 238 0
      blade-common/src/main/java/org/springblade/common/utils/DeepSeekClient.java
  3. 34 0
      blade-common/src/main/java/org/springblade/common/vo/DeepSeekResponse.java
  4. 5 4
      blade-ops-api/blade-resource-api/src/main/java/org/springblade/resource/feign/CommonFileClient.java
  5. 24 0
      blade-ops-api/blade-resource-api/src/main/java/org/springblade/resource/feign/FeignConfig.java
  6. 1 1
      blade-ops-api/blade-resource-api/src/main/java/org/springblade/resource/feign/NewIOSSClient.java
  7. 10 0
      blade-ops/blade-resource/pom.xml
  8. 5 0
      blade-ops/blade-resource/src/main/java/org/springblade/resource/builder/oss/BladeOssRuleRe.java
  9. 12 0
      blade-ops/blade-resource/src/main/java/org/springblade/resource/builder/ossre/S3Template2.java
  10. 5 4
      blade-ops/blade-resource/src/main/java/org/springblade/resource/feign/CommonFileClientImpl.java
  11. 64 0
      blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/entity/ArchiveAiName.java
  12. 2 0
      blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/entity/ArchivesAuto.java
  13. 11 0
      blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/vo/ArchiveAiNameVO.java
  14. 12 0
      blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/vo/ArchiveAiNameVO1.java
  15. 42 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/dto/PrivateStandardDTO.java
  16. 25 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/dto/StandardInfoDTO.java
  17. 38 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/dto/StandardInfoJoinDTO.java
  18. 31 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/dto/StandardInfoPrivateJoinDTO.java
  19. 34 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/dto/TrialAutoNumberDTO.java
  20. 6 3
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/dto/TrialMaterialMobilizationDTO.java
  21. 37 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/dto/TrialNumberRuleDTO.java
  22. 6 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/dto/TrialSampleInfoDTO.java
  23. 11 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/dto/TrialSelfInspectionRecordDTO.java
  24. 121 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/PrivateStandard.java
  25. 118 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/StandardFile.java
  26. 107 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/StandardInfo.java
  27. 62 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/StandardInfoJoin.java
  28. 103 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/StandardInfoPrivateJoin.java
  29. 58 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/TrialAutoNumber.java
  30. 77 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/TrialNumberRule.java
  31. 20 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/StandardElementVo.java
  32. 26 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/StandardInfoConditionVo.java
  33. 17 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/StandardInfoDtoVo.java
  34. 21 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/StandardInfoGroupNameVO.java
  35. 38 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/StandardInfoPrivateJoinGroupVO.java
  36. 26 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/StandardInfoPrivateJoinVO.java
  37. 28 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/StandardInfoVO.java
  38. 34 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/TrialAutoNumberVO.java
  39. 36 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/TrialNumberRuleVO.java
  40. 17 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/TrialNumberRuleVO1.java
  41. 16 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/AddBussFileSortDTO.java
  42. 2 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/TableFile.java
  43. 155 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchiveAiNameController.java
  44. 12 17
      blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchivesAutoController.java
  45. 44 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/ArchiveAiNameMapper.java
  46. 32 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/ArchiveAiNameMapper.xml
  47. 3 1
      blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/ArchivesAutoMapper.xml
  48. 45 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/IArchiveAiNameService.java
  49. 2 1
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/IArchivesAutoService.java
  50. 155 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchiveAiNameServiceImpl.java
  51. 51 6
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchiveAutoPdfServiceImpl.java
  52. 8 1
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchiveNameServiceImpl.java
  53. 51 9
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchivesAutoServiceImpl.java
  54. 212 0
      blade-service/blade-business/src/main/java/org/springblade/business/controller/PrivateStandardController.java
  55. 224 0
      blade-service/blade-business/src/main/java/org/springblade/business/controller/StandardInfoController.java
  56. 129 0
      blade-service/blade-business/src/main/java/org/springblade/business/controller/TrialAutoNumberController.java
  57. 1 1
      blade-service/blade-business/src/main/java/org/springblade/business/controller/TrialMaterialController.java
  58. 347 0
      blade-service/blade-business/src/main/java/org/springblade/business/controller/TrialNumberRuleController.java
  59. 20 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/PrivateStandardMapper.java
  60. 35 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/PrivateStandardMapper.xml
  61. 18 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/StandardFileMapper.java
  62. 23 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/StandardFileMapper.xml
  63. 28 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/StandardInfoJoinMapper.java
  64. 32 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/StandardInfoJoinMapper.xml
  65. 45 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/StandardInfoMapper.java
  66. 305 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/StandardInfoMapper.xml
  67. 28 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/StandardInfoPrivateJoinMapper.java
  68. 33 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/StandardInfoPrivateJoinMapper.xml
  69. 44 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/TrialAutoNumberMapper.java
  70. 22 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/TrialAutoNumberMapper.xml
  71. 46 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/TrialNumberRuleMapper.java
  72. 34 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/TrialNumberRuleMapper.xml
  73. 1 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/IEntrustInfoService.java
  74. 41 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/ITrialAutoNumberService.java
  75. 1 1
      blade-service/blade-business/src/main/java/org/springblade/business/service/ITrialMaterialMobilizationService.java
  76. 59 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/ITrialNumberRuleService.java
  77. 28 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/PrivateStandardService.java
  78. 13 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/StandardFileService.java
  79. 10 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/StandardInfoJoinService.java
  80. 10 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/StandardInfoPrivateJoinService.java
  81. 45 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/StandardInfoService.java
  82. 67 43
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/EntrustInfoServiceImpl.java
  83. 442 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/PrivateStandardServiceImpl.java
  84. 22 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/StandardFileServiceImpl.java
  85. 14 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/StandardInfoJoinServiceImpl.java
  86. 45 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TrialAutoNumberServiceImpl.java
  87. 19 2
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TrialMaterialMobilizationServiceImpl.java
  88. 455 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TrialNumberRuleServiceImpl.java
  89. 18 4
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TrialSampleInfoServiceImpl.java
  90. 25 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TrialSelfInspectionRecordServiceImpl.java
  91. 14 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/UStandardInfoPrivateJoinServiceImpl.java
  92. 365 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/UStandardInfoServiceImpl.java
  93. 3 3
      blade-service/blade-business/src/main/java/org/springblade/business/utils/PDFUtil.java
  94. 21 14
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/service/impl/EVDataServiceImpl.java
  95. 6 6
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/utils/PDFUtils.java
  96. 8 1
      blade-service/blade-manager/src/main/java/com/jfireel/expression/node/impl/EqualNode.java
  97. 6 1
      blade-service/blade-manager/src/main/java/com/jfireel/expression/node/impl/GtEqNode.java
  98. 13 0
      blade-service/blade-manager/src/main/java/com/jfireel/expression/node/impl/NotEqualNode.java
  99. 139 44
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ExcelTabController.java
  100. 12 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/TableFileController.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>

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

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

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

+ 1 - 1
blade-ops-api/blade-resource-api/src/main/java/org/springblade/resource/feign/NewIOSSClient.java

@@ -28,7 +28,7 @@ public interface NewIOSSClient {
     @PostMapping(value = UPLOAD_FILE_INFO_INPUT_STREAM, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
     BladeFile uploadFileByInputStream(MultipartFile file);
 
-    @PostMapping(value = UPLOAD_FILE_INFO_INPUT_STREAM2)
+    @PostMapping(value = UPLOAD_FILE_INFO_INPUT_STREAM2,  consumes = MediaType.APPLICATION_OCTET_STREAM_VALUE)
     BladeFile uploadFileByInputStream2(@RequestParam String OriginalFilename,@RequestParam InputStream inputStream);
 
     @PostMapping(UPLOAD_FILE_INFO)

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

+ 5 - 0
blade-ops/blade-resource/src/main/java/org/springblade/resource/builder/oss/BladeOssRuleRe.java

@@ -19,6 +19,11 @@ class BladeOssRuleRe implements OssRule {
     }
 
     public String fileName(String originalFilename) {
+        //试验-规范管理
+        if(originalFilename.contains("standard")){
+            String[] split = originalFilename.split("\\|");
+            return "upload/" + split[0] + "/" + DateUtil.today() + "/" + FileUtil.getNameWithoutExtension(split[1]) + "." + FileUtil.getFileExtension(split[1]);
+        }
         return "upload/" + DateUtil.today() + "/" + FileUtil.getNameWithoutExtension(originalFilename) + "." + FileUtil.getFileExtension(originalFilename);
     }
 

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

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

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

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

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

@@ -0,0 +1,42 @@
+package org.springblade.business.dto;
+
+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;
+
+/**
+ * @author LHB
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+@ApiModel(description = "规范文件夹及规范文件对象")
+public class PrivateStandardDTO extends PrivateStandard {
+    /**
+     * 文件
+     */
+    private MultipartFile[] files;
+    /**
+     * 文件
+     */
+    private List<StandardFile> standardFiles;
+
+    /**
+     * 当前规范文件下文件的数量
+     */
+    private Integer filesCount;
+
+    /**
+     * 单个文件
+     */
+    private MultipartFile file;
+
+    /**
+     * 单个文件
+     */
+    private StandardFile standardFile;
+}

+ 25 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/dto/StandardInfoDTO.java

@@ -0,0 +1,25 @@
+package org.springblade.business.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springblade.business.entity.StandardInfo;
+
+import java.util.List;
+
+/**
+ * 试验规范信息DTO
+ *
+ * @author LHB
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+@ApiModel(description = "试验规范信息DTO")
+public class StandardInfoDTO extends StandardInfo {
+    /**
+     * 基础信息
+     */
+    @ApiModelProperty(value = "基础信息", required = true)
+    private List<StandardInfo> info;
+}

+ 38 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/dto/StandardInfoJoinDTO.java

@@ -0,0 +1,38 @@
+package org.springblade.business.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 条件设置
+ *
+ * @author LHB
+ */
+@Data
+@ApiModel(description = "新增对象")
+public class StandardInfoJoinDTO {
+    /**
+     * 主关联id
+     */
+    @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 = new ArrayList<>();
+}

+ 31 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/dto/StandardInfoPrivateJoinDTO.java

@@ -0,0 +1,31 @@
+package org.springblade.business.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springblade.business.entity.StandardInfoPrivateJoin;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+/**
+ * 与表单的关联对象
+ * @author LHB
+ */
+@Data
+@ApiModel(description = "新增对象")
+public class StandardInfoPrivateJoinDTO {
+    /**
+     * 主关联id
+     */
+    @NotNull(message = "主关联id不能为空")
+    @ApiModelProperty(value = "主关联id")
+    private Long leftId;
+    /**
+     * 副连接id
+     */
+    @NotEmpty(message = "副连接信息不能为空")
+    @ApiModelProperty(value = "副连接信息集合")
+    private List<StandardInfoPrivateJoin> rightIds;
+}

+ 34 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/dto/TrialAutoNumberDTO.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.business.dto;
+
+import org.springblade.business.entity.TrialAutoNumber;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 数据传输对象实体类
+ *
+ * @author BladeX
+ * @since 2025-06-10
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class TrialAutoNumberDTO extends TrialAutoNumber {
+	private static final long serialVersionUID = 1L;
+
+}

+ 6 - 3
blade-service-api/blade-business-api/src/main/java/org/springblade/business/dto/TrialMaterialMobilizationDTO.java

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

+ 37 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/dto/TrialNumberRuleDTO.java

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

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

@@ -21,5 +21,11 @@ public class TrialSampleInfoDTO extends TrialSampleInfo {
     @ApiModelProperty("数据序号")
     private Integer dataNumber;
 
+    @ApiModelProperty("旧编号")
+    private String trialNumber;
+
+    @ApiModelProperty("自增流水号")
+    private String autoIncrementNumber;
+
 
 }

+ 11 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/dto/TrialSelfInspectionRecordDTO.java

@@ -29,4 +29,15 @@ public class TrialSelfInspectionRecordDTO extends TrialSelfInspectionRecord {
     @ApiModelProperty(value = "是否批量保存 0=单保存,1=批量保存")
     private Integer isBatchSave;
 
+    @ApiModelProperty(value = "记录表自增流水号")
+    private String recordAutoNumber;
+
+    @ApiModelProperty(value = "报告单自增流水号")
+    private String reportAutoNumber;
+
+    @ApiModelProperty(value = "旧记录编号")
+    private String oldRecordNumber;
+    @ApiModelProperty(value = "旧报告编号")
+    private String oldReportNumber;
+
 }

+ 121 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/PrivateStandard.java

@@ -0,0 +1,121 @@
+package org.springblade.business.entity;
+
+import cn.hutool.core.date.DateTime;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+
+import java.time.LocalDateTime;
+import java.util.Date;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+
+/**
+ * 规范文件夹及规范文件表
+ *
+ * @author LHB
+ * @TableName u_wbs_private_standard
+ */
+@TableName(value = "u_wbs_private_standard")
+@Data
+@ApiModel(description = "规范文件夹及规范文件对象")
+public class PrivateStandard {
+    /**
+     *
+     */
+    @TableId
+    @ApiModelProperty(value = "主键", required = true)
+    private Long id;
+
+    /**
+     * 名称(规范文件夹名称及规范名称)
+     */
+    @NotBlank(message = "名称不能为空")
+    @ApiModelProperty(value = "名称", required = true)
+    private String name;
+
+    /**
+     * 父级节点id
+     * type = 2 必传
+     */
+    @ApiModelProperty(value = "父级节点id(type = 2 必传)")
+    private Long parentId;
+
+    /**
+     * 项目试验节点id
+     * type = 1 必传
+     */
+    @ApiModelProperty(value = "项目试验节点id(type = 1 必传)")
+    private Long privateId;
+
+    /**
+     * 类型(1-规范文件夹,2-规范文件)
+     */
+    @ApiModelProperty(value = "类型(1-规范文件夹,2-规范文件)", required = true)
+    @NotNull(message = "类型不能为空")
+    private Integer type;
+
+    /**
+     * 下达日期(年月日)
+     * type = 2 必传
+     */
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
+    @ApiModelProperty(value = "下达日期(年月日)(type = 2 必传)")
+    private Date issueDate;
+
+    /**
+     * 实施日期(年月日)
+     * type = 2 必传
+     */
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
+    @ApiModelProperty(value = "实施日期(年月日)(type = 2 必传)")
+    private Date actualizeDate;
+
+    /**
+     * 是否删除(0-正常,1-已删除)
+     */
+    @ApiModelProperty(value = "是否删除(0-正常,1-已删除)")
+    private Integer isDeleted = 0;
+    /**
+     * 状态(1-正常,2-过期)
+     */
+    @ApiModelProperty(value = "状态(1-正常,2-过期)")
+    private Integer status;
+
+    /**
+     * 创建时间
+     */
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @ApiModelProperty(value = "创建时间", hidden = true)
+    private LocalDateTime createTime;
+
+    /**
+     * 创建人
+     */
+    @ApiModelProperty(value = "创建人", hidden = true)
+    private Long createUser;
+
+    /**
+     * 修改时间
+     */
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @ApiModelProperty(value = "修改时间", hidden = true)
+    private LocalDateTime updateTime;
+
+    /**
+     * 修改人
+     */
+    @ApiModelProperty(value = "修改人", hidden = true)
+    private Long updateUser;
+}

+ 118 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/StandardFile.java

@@ -0,0 +1,118 @@
+package org.springblade.business.entity;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import java.util.Date;
+import lombok.Data;
+
+/**
+ * 规范文件表
+ * @TableName u_standard_file
+ */
+@TableName(value ="u_standard_file")
+@Data
+public class StandardFile {
+    /**
+     * 
+     */
+    @TableId
+    private Long id;
+
+    /**
+     * 规范id
+     */
+    private Long standardId;
+
+    /**
+     * 文件名称
+     */
+    private String fileName;
+
+    /**
+     * 规范文件路径
+     */
+    private String standardFileUrl;
+
+    /**
+     *  是否删除(0-正常,1-已删除)
+     */
+    private Integer isDeleted;
+
+    /**
+     *  创建时间
+     */
+    private Date createTime;
+
+    /**
+     *  创建人
+     */
+    private Long createUser;
+
+    /**
+     *  修改时间
+     */
+    private Date updateTime;
+
+    /**
+     *  修改人
+     */
+    private Long updateUser;
+
+    @Override
+    public boolean equals(Object that) {
+        if (this == that) {
+            return true;
+        }
+        if (that == null) {
+            return false;
+        }
+        if (getClass() != that.getClass()) {
+            return false;
+        }
+        StandardFile other = (StandardFile) that;
+        return (this.getId() == null ? other.getId() == null : this.getId().equals(other.getId()))
+            && (this.getStandardId() == null ? other.getStandardId() == null : this.getStandardId().equals(other.getStandardId()))
+            && (this.getFileName() == null ? other.getFileName() == null : this.getFileName().equals(other.getFileName()))
+            && (this.getStandardFileUrl() == null ? other.getStandardFileUrl() == null : this.getStandardFileUrl().equals(other.getStandardFileUrl()))
+            && (this.getIsDeleted() == null ? other.getIsDeleted() == null : this.getIsDeleted().equals(other.getIsDeleted()))
+            && (this.getCreateTime() == null ? other.getCreateTime() == null : this.getCreateTime().equals(other.getCreateTime()))
+            && (this.getCreateUser() == null ? other.getCreateUser() == null : this.getCreateUser().equals(other.getCreateUser()))
+            && (this.getUpdateTime() == null ? other.getUpdateTime() == null : this.getUpdateTime().equals(other.getUpdateTime()))
+            && (this.getUpdateUser() == null ? other.getUpdateUser() == null : this.getUpdateUser().equals(other.getUpdateUser()));
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((getId() == null) ? 0 : getId().hashCode());
+        result = prime * result + ((getStandardId() == null) ? 0 : getStandardId().hashCode());
+        result = prime * result + ((getFileName() == null) ? 0 : getFileName().hashCode());
+        result = prime * result + ((getStandardFileUrl() == null) ? 0 : getStandardFileUrl().hashCode());
+        result = prime * result + ((getIsDeleted() == null) ? 0 : getIsDeleted().hashCode());
+        result = prime * result + ((getCreateTime() == null) ? 0 : getCreateTime().hashCode());
+        result = prime * result + ((getCreateUser() == null) ? 0 : getCreateUser().hashCode());
+        result = prime * result + ((getUpdateTime() == null) ? 0 : getUpdateTime().hashCode());
+        result = prime * result + ((getUpdateUser() == null) ? 0 : getUpdateUser().hashCode());
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append(getClass().getSimpleName());
+        sb.append(" [");
+        sb.append("Hash = ").append(hashCode());
+        sb.append(", id=").append(id);
+        sb.append(", standardId=").append(standardId);
+        sb.append(", fileName=").append(fileName);
+        sb.append(", standardFileUrl=").append(standardFileUrl);
+        sb.append(", isDeleted=").append(isDeleted);
+        sb.append(", createTime=").append(createTime);
+        sb.append(", createUser=").append(createUser);
+        sb.append(", updateTime=").append(updateTime);
+        sb.append(", updateUser=").append(updateUser);
+        sb.append("]");
+        return sb.toString();
+    }
+}

+ 107 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/StandardInfo.java

@@ -0,0 +1,107 @@
+package org.springblade.business.entity;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+
+import java.util.Date;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.hibernate.validator.constraints.Range;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+
+/**
+ * 规范参数管理-基础信息
+ *
+ * @author LHB
+ * @TableName u_standard_info
+ */
+@TableName(value = "u_standard_info")
+@Data
+@ApiModel(description = "规范参数管理-基础信息")
+public class StandardInfo {
+    /**
+     *
+     */
+    @TableId
+    @ApiModelProperty(value = "主键")
+    private Long id;
+
+    /**
+     * 名称(样品信息名称)
+     */
+    @NotBlank(message = "名称不能为空")
+    @ApiModelProperty(value = "名称(样品信息名称)")
+    private String name;
+    /**
+     * 符号
+     */
+    @ApiModelProperty(value = "符号")
+    private String symbol;
+
+    /**
+     * 父级节点id
+     */
+    @ApiModelProperty(value = "父级节点id")
+    private Long parentId;
+
+    /**
+     * 规范文件id
+     */
+    @ApiModelProperty(value = "规范文件id")
+    private Long standardId;
+
+    /**
+     * 类型(1-样品信息,2-技术指标)
+     */
+    @ApiModelProperty(value = "类型(1-样品信息,2-技术指标)")
+    @NotNull(message = "类型不能为空")
+    @Range(min = 1, max = 2, message = "类型只能为1或2")
+    private Integer type;
+
+    /**
+     * 是否删除(0-正常,1-已删除)
+     */
+    @ApiModelProperty(value = "是否删除(0-正常,1-已删除)")
+    private Integer isDeleted;
+
+    /**
+     * 创建时间
+     */
+    @ApiModelProperty(value = "创建时间", hidden = true)
+    private Date createTime;
+
+    /**
+     * 创建人
+     */
+    @ApiModelProperty(value = "创建人", hidden = true)
+    private Long createUser;
+
+    /**
+     * 修改时间
+     */
+    @ApiModelProperty(value = "修改时间", hidden = true)
+    private Date updateTime;
+
+    /**
+     * 修改人
+     */
+    @ApiModelProperty(value = "修改人", hidden = true)
+    private Long updateUser;
+
+    /**
+     * 符号名称
+     */
+    @TableField(exist = false)
+    private String symbolName;
+
+    /**
+     * 父级名称
+     */
+    @TableField(exist = false)
+    private String parentName;
+}

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

@@ -0,0 +1,62 @@
+package org.springblade.business.entity;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import java.util.Date;
+import lombok.Data;
+
+/**
+ * 样品信息关联表
+ * @author LHB
+ * @TableName u_standard_info_join
+ */
+@TableName(value ="u_standard_info_join")
+@Data
+public class StandardInfoJoin {
+    /**
+     * 
+     */
+    @TableId
+    private Long id;
+
+    /**
+     * 组Id
+     */
+    private Long groupId;
+    /**
+     * 规范基础信息关联主id
+     */
+    private Long standardInfoLeftId;
+
+    /**
+     * 规范基础信息关联副id
+     */
+    private Long standardInfoRightId;
+
+    /**
+     *  是否删除(0-正常,1-已删除)
+     */
+    private Integer isDeleted;
+
+    /**
+     *  创建时间
+     */
+    private Date createTime;
+
+    /**
+     *  创建人
+     */
+    private Long createUser;
+
+    /**
+     *  修改时间
+     */
+    private Date updateTime;
+
+    /**
+     *  修改人
+     */
+    private Long updateUser;
+
+
+}

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

@@ -0,0 +1,103 @@
+package org.springblade.business.entity;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import java.util.Date;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+
+/**
+ * 样品信息与试验表 关联表
+ * @author LHB
+ * @TableName u_standard_info_private_join
+ */
+@TableName(value ="u_standard_info_private_join")
+@Data
+
+@ApiModel(description = "副连接信息集合")
+public class StandardInfoPrivateJoin {
+    /**
+     * 
+     */
+    @TableId
+    @ApiModelProperty(value = "主键", required = true)
+    private Long id;
+
+    /**
+     * 组id
+     */
+    @ApiModelProperty(value = "组id", hidden = false)
+    private Long groupId;
+    /**
+     * 规范基础信息关联主id
+     */
+    @NotNull(message = "规范基础信息关联主id不能为空")
+    @ApiModelProperty(value = "规范基础信息关联主id", hidden = true)
+    private Long standardInfoId;
+
+    /**
+     * 试验wbs表单id
+     */
+    @NotNull(message = "试验wbs表单id不能为空")
+    @ApiModelProperty(value = "试验wbs表单id", required = true)
+    private Long privateId;
+
+    /**
+     * 元素key
+     */
+    @NotBlank(message = "元素key不能为空")
+    @ApiModelProperty(value = "元素key", required = true)
+    private String colKey;
+
+    /**
+     * 元素名称
+     */
+    @NotBlank(message = "元素名称不能为空")
+    @ApiModelProperty(value = "元素名称", required = true)
+    private String colName;
+
+    /**
+     *  是否删除(0-正常,1-已删除)
+     */
+    @ApiModelProperty(value = "是否删除(0-正常,1-已删除)")
+    private Integer isDeleted;
+
+    /**
+     *  创建时间
+     */
+    @ApiModelProperty(value = "创建时间", hidden = true)
+    private Date createTime;
+
+    /**
+     *  创建人
+     */
+    @ApiModelProperty(value = "创建人", hidden = true)
+    private Long createUser;
+
+    /**
+     *  修改时间
+     */
+    @ApiModelProperty(value = "修改时间", hidden = true)
+    private Date updateTime;
+
+    /**
+     *  修改人
+     */
+    @ApiModelProperty(value = "修改人", hidden = true)
+    private Long updateUser;
+
+
+    /**
+     * 表单名称(展示用)
+     */
+    @ApiModelProperty(value = "表单名称(展示用)")
+    @TableField(exist = false)
+    private String privateName;
+
+}

+ 58 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/TrialAutoNumber.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.business.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-10
+ */
+@Data
+@TableName("u_trial_auto_number")
+@EqualsAndHashCode(callSuper = true)
+public class TrialAutoNumber extends BaseEntity {
+
+	private static final long serialVersionUID = 1L;
+
+	/**
+	* 自增的流水号
+	*/
+		private String autoIncrementNumber;
+
+		private Long contractId;
+	/**
+	* 来源主表的主键ID
+	*/
+		private Long formDataId;
+	/**
+	* 1材料 2样品 3委托单 4记录表 5报告表
+	*/
+		private Integer type;
+    /**
+     * 试验编号规则ID
+      */
+        private Long numberRuleId;
+
+
+}

+ 77 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/TrialNumberRule.java

@@ -0,0 +1,77 @@
+/*
+ *      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.business.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import java.io.Serializable;
+
+import io.swagger.annotations.ApiModelProperty;
+import org.springblade.core.mp.base.BaseEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 实体类
+ *
+ * @author BladeX
+ * @since 2025-06-10
+ */
+@Data
+@TableName("u_trial_number_rule")
+@EqualsAndHashCode(callSuper = true)
+public class TrialNumberRule extends BaseEntity {
+
+	private static final long serialVersionUID = 1L;
+
+	/**
+	* 项目ID
+	*/
+    @ApiModelProperty("项目ID")
+		private Long projectId;
+	/**
+	* 合同段ID
+	*/
+    @ApiModelProperty("合同段ID")
+		private Long contractId;
+	/**
+	* 编号规则 1材料 2样品 3委托单 4记录表 5报告表
+	*/
+    @ApiModelProperty("编号规则 1材料 2样品 3委托单 4记录表 5报告表")
+		private Integer type;
+	/**
+	* 编号规则
+	*/
+    @ApiModelProperty("编号规则")
+		private Integer rule;
+	/**
+	* 数据填充
+	*/
+    @ApiModelProperty("数据填充")
+		private String data;
+	/**
+	* 是否自增
+	*/
+    @ApiModelProperty("是否自增0否1是")
+		private Integer isAutoIncrement;
+    /**
+     * 排序
+      */
+    @ApiModelProperty("排序")
+        private Integer sort;
+
+
+}

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

+ 17 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/StandardInfoDtoVo.java

@@ -0,0 +1,17 @@
+package org.springblade.business.vo;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springblade.business.dto.StandardInfoDTO;
+
+/**
+ * @author LHB
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class StandardInfoDtoVo extends StandardInfoDTO {
+    /**
+     * 符号拼接名称
+     */
+    private String symbolName;
+}

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

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

@@ -0,0 +1,26 @@
+package org.springblade.business.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springblade.business.entity.StandardInfo;
+import org.springblade.business.entity.StandardInfoPrivateJoin;
+
+import java.util.List;
+
+/**
+ * @author LHB
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+@ApiModel(description = "关联元素对象-视图")
+public class StandardInfoPrivateJoinVO extends StandardInfo {
+    @ApiModelProperty(value = "组id")
+    private Long groupId;
+    /**
+     * 项目组集合
+     */
+    @ApiModelProperty(value = "项目组集合")
+    private List<StandardInfoPrivateJoinGroupVO> group;
+}

+ 28 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/StandardInfoVO.java

@@ -0,0 +1,28 @@
+package org.springblade.business.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springblade.business.entity.StandardInfo;
+
+import java.util.List;
+
+/**
+ * @author LHB
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+@ApiModel(description = "条件设置对象")
+public class StandardInfoVO extends StandardInfo {
+    /**
+     * 分组id
+     */
+    @ApiModelProperty(value = "分组id")
+    private Long groupId;
+    /**
+     * 副连接对象
+     */
+    @ApiModelProperty(value = "副连接对象集合")
+    private List<StandardInfoConditionVo> standardInfos;
+}

+ 34 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/TrialAutoNumberVO.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.business.vo;
+
+import org.springblade.business.entity.TrialAutoNumber;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 视图实体类
+ *
+ * @author BladeX
+ * @since 2025-06-10
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class TrialAutoNumberVO extends TrialAutoNumber {
+	private static final long serialVersionUID = 1L;
+
+}

+ 36 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/TrialNumberRuleVO.java

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

+ 17 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/TrialNumberRuleVO1.java

@@ -0,0 +1,17 @@
+package org.springblade.business.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.springblade.business.entity.TrialNumberRule;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class TrialNumberRuleVO1 {
+    private List<TrialNumberRule> list=new ArrayList<>();
+    private String trialNumber;
+}

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

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

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

+ 12 - 17
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;
 
@@ -41,13 +38,10 @@ 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.business.feign.ArchiveFileClient;
-import org.springblade.common.constant.CommonConstant;
-import org.springblade.common.utils.CommonUtil;
+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;
@@ -56,15 +50,10 @@ 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.*;
@@ -76,7 +65,6 @@ 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.*;
 import java.util.concurrent.ExecutorService;
@@ -107,11 +95,11 @@ public class ArchivesAutoController extends BladeController {
 	private ExecutorService executorService;
 	@Autowired
 	private ITraceLogService iTraceLogService;
-
     private final JdbcTemplate jdbcTemplate;
     @Autowired
     private ArchiveFileClient archiveFileClient;
 
+
 	/**
 	 * 详情
 	 */
@@ -161,15 +149,15 @@ public class ArchivesAutoController extends BladeController {
     @GetMapping("/fileNumberFlush")
     @ApiOperationSupport(order = 4)
     @ApiOperation(value = "档号整理——按档号排序")
-    public R fileNumberFlush(Long projectId,Long contractId,String nodeId,Integer isArchive){
+    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);
-        return R.success("正在重置题名中,请稍后刷新");
+        archivesAutoService.fileNumberFlush(projectId,contractId,ids,isArchive,startNumber);
+        return R.success("正在刷新档号中,请稍后刷新");
     }
 
 
@@ -551,6 +539,13 @@ public class ArchivesAutoController extends BladeController {
 		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));
+	}
+
 	/**
 	 * 预览案卷文件
 	 */

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

+ 3 - 1
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">
@@ -1434,6 +1435,7 @@
         <foreach collection="nodeIds" item="nodeId" open="(" separator="," close=")">
             #{nodeId}
         </foreach>
-        ORDER BY uaa.auto_file_sort Asc
+        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>

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

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

@@ -159,7 +159,7 @@ public interface IArchivesAutoService extends BaseService<ArchivesAuto> {
 
 	R sendFileToEArchives(ArchiveDataVo dataInfo);
 
-    void fileNumberFlush(Long projectId, Long contractId, List<String> nodeIds,Integer isArchive);
+    void fileNumberFlush(Long projectId, Long contractId, List<String> nodeIds,Integer isArchive,Integer startNumber);
 
     boolean reBuildArchiveFrontPdfs(String archiveIds, Long projectId);
 
@@ -168,4 +168,5 @@ public interface IArchivesAutoService extends BaseService<ArchivesAuto> {
 	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);
+	}
+}

+ 51 - 6
blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchiveAutoPdfServiceImpl.java

@@ -41,10 +41,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
@@ -321,7 +318,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));
@@ -671,7 +668,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);
+                                }
                             }
                         }
                     }
@@ -741,6 +777,12 @@ 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);
         }
         //设置总页数
@@ -825,6 +867,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")) {

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

@@ -334,7 +334,14 @@ public class ArchiveNameServiceImpl implements IArchiveNameService {
                     String childNames = groupNodes.stream()
                             .map(ArchiveTreeContract::getNodeName)
                             .collect(Collectors.joining("、"));
-                    nameParts.add(parentName + childNames);
+                    // 修改点:根据条件决定添加的内容
+                    if (!useCovering ) {
+                        // 当 useCovering=false 且不是第一个父节点时,只添加子节点名称
+                        nameParts.add(childNames);
+                    } else {
+                        // 其他情况:添加父节点名称+子节点名称
+                        nameParts.add(parentName + childNames);
+                    }
                 }
 
                 // 后续节点不再是第一个

+ 51 - 9
blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchivesAutoServiceImpl.java

@@ -52,6 +52,7 @@ import org.springblade.business.feign.ArchiveFileClient;
 import org.springblade.business.feign.MetadataClassificationClient;
 import org.springblade.business.feign.TaskClient;
 import org.springblade.common.utils.CommonUtil;
+import org.springblade.common.utils.DeepSeekClient;
 import org.springblade.common.utils.SnowFlakeUtil;
 import org.springblade.core.log.exception.ServiceException;
 import org.springblade.core.mp.base.BaseServiceImpl;
@@ -91,6 +92,7 @@ import java.net.URL;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
+import java.rmi.ServerException;
 import java.time.LocalDateTime;
 import java.util.*;
 import java.util.List;
@@ -152,6 +154,8 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 
 	private final IArchiveNameService archiveNameService;
 
+	private final IArchiveAiNameService aiNameService;
+
 
 	@Override
 	public IPage<ArchivesAutoVO> selectArchivesAutoPage(IPage<ArchivesAutoVO> page, ArchivesAutoVO archivesAuto) {
@@ -1099,7 +1103,9 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 			indexMap.put(treeCode, fileNumberSuffix + 1);
 		}
 
-		archivesAuto.setFileNumber(fileNumberSuffix.toString());//档号
+		// 将数值格式化为3位数字字符串(不足3位前面补0)
+		String formattedNumber = String.format("%03d", fileNumberSuffix);
+		archivesAuto.setFileNumber(formattedNumber); // 设置档号
 		//archivesAuto.setMicron();//微缩号
 		archivesAuto.setUnit(unit);//立卷单位
 		//archivesAuto.setQuantity();//数量/单位
@@ -1536,7 +1542,38 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 		archiveFileClient.updateArchiveFile(waitArchiveFiles);
 	}
 
-
+	@Override
+	public boolean creatFileNameFormAI(String ids, Long projectId, Long contractId) throws IOException {
+		List<ArchivesAuto> archivesAutoList = this.listByIds(Func.toLongList(ids));
+		List<ArchiveAiName>aiNames=new ArrayList<>();
+		Long taskId=SnowFlakeUtil.getId();
+		List<ArchiveAiName> archiveAiNameList = aiNameService.getBaseMapper().selectList(new LambdaQueryWrapper<>(ArchiveAiName.class).eq(ArchiveAiName::getProjectId, projectId).eq(ArchiveAiName::getContractId, contractId).in(ArchiveAiName::getArchiveAutoId, Func.toLongList(ids)));
+		List<Long> existid=new ArrayList<>();
+		if(!archiveAiNameList.isEmpty()){
+			existid= archiveAiNameList.stream().filter(ai -> ai.getStatus() == 1).map(ai -> ai.getArchiveAutoId()).collect(Collectors.toList());
+		}
+		for (ArchivesAuto auto : archivesAutoList) {
+			if(!existid.isEmpty()){
+				if(existid.contains(auto.getId())){
+					continue;
+				}
+			}
+			ArchiveAiName aiName = new ArchiveAiName();
+			aiName.setProjectId(projectId);
+			aiName.setContractId(contractId);
+			aiName.setTaskId(taskId);
+			aiName.setArchiveAutoId(auto.getId());
+			aiName.setArchiveName(auto.getName());
+			aiName.setStatus(1);
+			aiNames.add(aiName);
+		}
+		if(aiNames.size()<=0){
+			throw new ServerException("所选节点正在生成中,请勿重复提交");
+		}
+		//异步调用AI接口
+		aiNameService.syncCreatAiName(aiNames);
+		return aiNameService.saveBatch(aiNames);
+	}
 
 
 	/**
@@ -2556,7 +2593,8 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 				.ne("is_auto_file", 1)
 				.orderByAsc("tree_sort")
 				.orderByAsc("auto_file_sort")
-				.orderByAsc("file_number");
+				.orderByAsc("file_number")
+		         .orderByAsc("create_time");
 
 		return this.list(queryWrapper);
 	}
@@ -4466,18 +4504,18 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 
     @Override
     @Async
-    public void fileNumberFlush(Long projectId, Long contractId, List<String> nodeIds,Integer isArchive) {
+    public void fileNumberFlush(Long projectId, Long contractId, List<String> nodeIds,Integer isArchive,Integer startNumber) {
         ArchiveProjectConfig config = archiveProjectConfigService.getByProjectIdOrNew(projectId);
         List<ArchivesAutoVO4>list=baseMapper.selectAllArchiveAuto(projectId,contractId,nodeIds,isArchive);
         if(list!=null && list.size()>0){
             if(config.getDirType()==null||config.getDirType()==0){
-                List<ArchivesAuto> archivesAutos = setFileNumberByConfig(config, list);
+                List<ArchivesAuto> archivesAutos = setFileNumberByConfig(config, list,startNumber);
                 this.updateBatchById(archivesAutos);
             }else {
                 Map<Long, List<ArchivesAutoVO4>> map = list.stream().collect(Collectors.groupingBy(ArchivesAutoVO4::getParentId));
                 for (Map.Entry<Long, List<ArchivesAutoVO4>> entry : map.entrySet()) {
                     List<ArchivesAutoVO4> value = entry.getValue();
-                    List<ArchivesAuto> archivesAutos = setFileNumberByConfig(config, value);
+                    List<ArchivesAuto> archivesAutos = setFileNumberByConfig(config, value,startNumber);
                    this.updateBatchById(archivesAutos);
                 }
             }
@@ -4498,6 +4536,7 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
             //List<ArchiveFile> archiveFiles = archiveFileClient.getArchiveFileByArchiveID(Long.valueOf(archiveId));
             List<ArchiveFile> archiveFiles= jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(ArchiveFile.class));
             archiveAutoPdfService.buildArchiveFrontPdfs(projectId,auto,archiveFiles,true);
+			auto.setColourStatus(1);
             baseMapper.updateById(auto);
         }
         return true;
@@ -4581,8 +4620,11 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
         return true;
     }
 
-    public List<ArchivesAuto> setFileNumberByConfig(ArchiveProjectConfig config,List<ArchivesAutoVO4> value){
-        int i=1;
+    public List<ArchivesAuto> setFileNumberByConfig(ArchiveProjectConfig config,List<ArchivesAutoVO4> value,Integer startNumber){
+        int i=startNumber;
+		if(config.getIndexType()==1&&startNumber.toString().length()>config.getIndexNum()+1){
+			throw new ServiceException("起始流水号位数不能超过设置的虚数位数");
+		}
         List<ArchivesAuto>list=new ArrayList<>();
         for (ArchivesAutoVO4 v:value) {
             ArchivesAuto auto = new ArchivesAuto();
@@ -4590,7 +4632,7 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
                v.setFileNumber(v.getFileNumberPrefix()+"_"+i);
            }else {
                String prefix = v.getFileNumberPrefix();
-               int index = i; // 编号从 1 开始
+               int index = i; // 编号从 startNumber 开始
                // 获取配置中的编号长度(最多多少位)
                int numLength = config.getIndexNum();
                // 默认最多4位,防止过长或无效值

+ 212 - 0
blade-service/blade-business/src/main/java/org/springblade/business/controller/PrivateStandardController.java

@@ -0,0 +1,212 @@
+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;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * 规范文件夹及规范文件表(UWbsPrivateStandard)表控制层
+ *
+ * @author makejava
+ * @since 2025-06-10 11:09:22
+ */
+@RestController
+@RequestMapping("PrivateStandard")
+@Api(tags = "试验-规范管理-规范文件夹及规范文件接口")
+public class PrivateStandardController {
+    /**
+     * 服务对象
+     */
+    @Resource
+    private PrivateStandardService privateStandardService;
+
+    @Resource
+    private StandardFileService standardFileService;
+
+    /**
+     * 分页查询所有数据
+     *
+     * @param query               分页对象
+     * @param privateStandard 查询实体
+     * @return 所有数据
+     */
+    @GetMapping("page")
+    @ApiOperation(value = "分页查询所有数据", notes = "传入分页对象和高级查询对象")
+    public R<IPage<PrivateStandardDTO>> selectAll(Query query, PrivateStandard privateStandard) {
+        try {
+            Page page = new Page(query.getCurrent(), query.getSize());
+            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) {
+            // 可根据实际需求记录日志或返回特定错误信息
+            return R.fail("查询失败");
+        }
+    }
+
+
+    /**
+     * 通过主键查询单条数据
+     *
+     * @param id 主键
+     * @return 单条数据
+     */
+    @ApiOperation(value = "通过主键查询单条数据", notes = "传入主键Id")
+    @ApiImplicitParam(name = "id", value = "主键id", required = true)
+    @GetMapping("/getById")
+    public R<PrivateStandardDTO> selectOne(Long id) {
+        PrivateStandard byId = this.privateStandardService.getById(id);
+        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);
+    }
+
+    /**
+     * 新增数据
+     *
+     * @param privateStandard 实体对象
+     * @return 新增结果
+     */
+    @PostMapping("add")
+    @ApiOperation(value = "新增数据", notes = "privateStandard")
+    @ApiImplicitParam(name = "privateStandard", value = "实体对象", required = true)
+    public R<Boolean> insert(@RequestPart("data") @Validated PrivateStandardDTO privateStandard,@RequestPart("files") MultipartFile[] files) {
+        privateStandard.setId(SnowFlakeUtil.getId());
+        privateStandard.setFiles(files);
+        if (privateStandard.getType() != 1 && privateStandard.getType() != 2) {
+            return R.fail("类型错误");
+        }
+        if (privateStandard.getType() == 1) {
+            privateStandard.setParentId(0L);
+            if (privateStandard.getPrivateId() == null) {
+                return R.fail("节点不能为空");
+            }
+        } else {
+            if (privateStandard.getParentId() == null) {
+                return R.fail("父级节点不能为空");
+            }
+            if (privateStandard.getIssueDate() == null) {
+                return R.fail("下达日期不能为空");
+            }
+            if (privateStandard.getActualizeDate() == null) {
+                return R.fail("实施日期不能为空");
+            }
+        }
+        boolean save = this.privateStandardService.insert(privateStandard);
+        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);
+    }
+
+    /**
+     * 修改数据
+     *
+     * @param privateStandards 实体对象
+     * @return 修改结果
+     */
+    @ApiOperation(value = "修改数据")
+    @PostMapping("edit")
+    @ApiImplicitParam(name = "privateStandards", value = "实体对象", required = true)
+    public R<Boolean> update(@RequestBody @Validated List<PrivateStandardDTO> privateStandards) {
+        BladeUser user = SecureUtil.getUser();
+        privateStandards.forEach(f -> f.setUpdateUser(user.getUserId()));
+        boolean b = this.privateStandardService.update(privateStandards);
+        return R.data(b);
+    }
+
+    /**
+     * 删除数据
+     *
+     * @param id 主键
+     * @return 删除结果
+     */
+    @ApiOperation(value = "删除数据")
+    @GetMapping("/delete")
+    @ApiImplicitParam(name = "id", value = "主键id", required = true)
+    public R<Boolean> delete(Long id) {
+        boolean b = this.privateStandardService.delete(id);
+        return R.data(b);
+    }
+
+    /**
+     * 删除文件
+     */
+    @ApiOperation(value = "删除文件")
+    @GetMapping("/deleteFile")
+    @ApiImplicitParam(name = "id", value = "文件Id", required = true)
+    public R<Boolean> deleteFile(Long id) {
+        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);
+    }
+
+}
+

+ 224 - 0
blade-service/blade-business/src/main/java/org/springblade/business/controller/StandardInfoController.java

@@ -0,0 +1,224 @@
+package org.springblade.business.controller;
+
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.springblade.business.dto.StandardInfoDTO;
+import org.springblade.business.dto.StandardInfoJoinDTO;
+import org.springblade.business.dto.StandardInfoPrivateJoinDTO;
+import org.springblade.business.entity.StandardInfo;
+import org.springblade.business.service.StandardInfoService;
+import org.springblade.business.vo.StandardInfoDtoVo;
+import org.springblade.business.vo.StandardInfoPrivateJoinVO;
+import org.springblade.business.vo.StandardInfoVO;
+import org.springblade.core.mp.support.Query;
+import org.springblade.core.tool.api.R;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * 规范参数管理-基础信息(UStandardInfo)表控制层
+ *
+ * @author makejava
+ * @since 2025-06-11 10:03:01
+ */
+@RestController
+@RequestMapping("uStandardInfo")
+@Api(tags = "试验-规范管理-基础信息接口")
+public class StandardInfoController {
+    /**
+     * 服务对象
+     */
+    @Resource
+    private StandardInfoService uStandardInfoService;
+
+    /**
+     * 分页查询所有数据
+     *
+     * @param query        分页对象
+     * @param standardInfo 查询实体
+     * @return 所有数据
+     */
+    @GetMapping("page")
+    @ApiOperation(value = "分页查询所有数据", notes = "传入分页对象和高级查询对象")
+    public R<IPage<StandardInfoDTO>> selectAll(Query query, StandardInfo standardInfo) {
+        IPage<StandardInfoDTO> page = this.uStandardInfoService.selectMyPage(query, standardInfo);
+        return R.data(page);
+    }
+
+    /**
+     * 通过主键查询单条数据
+     *
+     * @param id 主键
+     * @return 单条数据
+     */
+    @GetMapping("/getById")
+    @ApiOperation(value = "通过主键查询单条数据", notes = "传入主键Id")
+    @ApiImplicitParam(name = "id", value = "主键", required = true)
+    public R<StandardInfoDTO> selectOne(Long id) {
+        StandardInfoDTO dto = this.uStandardInfoService.selectOne(id);
+        return R.data(dto);
+    }
+
+    /**
+     * 新增数据
+     *
+     * @param standardInfo 实体对象
+     * @return 新增结果
+     */
+    @PostMapping("add")
+    @ApiOperation(value = "新增数据")
+    public R<Boolean> insert(@RequestBody @Validated StandardInfoDTO standardInfo) {
+        Boolean b = this.uStandardInfoService.insert(standardInfo);
+        return R.data(b);
+    }
+
+    /**
+     * 修改数据
+     *
+     * @param standardInfo 实体对象
+     * @return 修改结果
+     */
+    @PostMapping("edit")
+    @ApiOperation(value = "修改数据")
+    public R<Boolean> update(@RequestBody @Validated StandardInfoDTO standardInfo) {
+        Boolean b = this.uStandardInfoService.edit(standardInfo);
+        return R.data(b);
+    }
+
+    /**
+     * 删除数据
+     *
+     * @param id 主键
+     * @return 删除结果
+     */
+    @ApiOperation(value = "删除数据")
+    @ApiImplicitParam(name = "id", value = "主键", required = true)
+    @GetMapping("/delete")
+    public R<Boolean> delete(Long id) {
+        Boolean b = this.uStandardInfoService.delete(id);
+        return R.data(b);
+    }
+
+
+    /**
+     * 条件设置
+     *
+     * @param standardInfoJoins 条件设置对象
+     * @param id                规范文件id
+     * @return 结果
+     */
+    @ApiOperation(value = "条件设置")
+    @PostMapping("saveConditionSet")
+    public R<Boolean> setCondition(@RequestBody @Validated List<StandardInfoVO> standardInfoJoins,
+                                   @RequestParam Long id) {
+        Boolean b = this.uStandardInfoService.setCondition(standardInfoJoins, id);
+        return R.data(b);
+    }
+
+    /**
+     * 关联元素
+     *
+     * @param standardInfoPrivateJoins 关联元素对象
+     * @return 结果
+     */
+    @ApiOperation(value = "关联元素")
+    @PostMapping("saveElementJoin")
+    public R<Boolean> setElementJoin(@RequestBody @Validated List<StandardInfoPrivateJoinVO> standardInfoPrivateJoins,
+                                     @RequestParam Long id) {
+        Boolean b = this.uStandardInfoService.setElementJoin(standardInfoPrivateJoins, id);
+        return R.data(b);
+    }
+
+    /**
+     * 删除条件设置
+     *
+     * @param leftId 主关联id
+     * @return 删除结果
+     */
+    @ApiOperation(value = "删除条件设置")
+    @ApiImplicitParam(name = "groupId", value = "组id", required = true)
+    @GetMapping("deleteConditionSet")
+    public R<Boolean> deleteConditionSet(Long groupId) {
+        Boolean b = this.uStandardInfoService.deleteConditionSet(groupId);
+        return R.data(b);
+    }
+
+    /**
+     * 删除关联元素
+     *
+     * @param leftId 主关联id
+     * @return 删除结果
+     */
+    @ApiOperation(value = "删除关联元素")
+    @ApiImplicitParam(name = "groupId", value = "组id", required = true)
+    @GetMapping("deleteElementJoin")
+    public R<Boolean> deleteElementJoin(Long groupId) {
+        Boolean b = this.uStandardInfoService.deleteElementJoin(groupId);
+        return R.data(b);
+    }
+
+    /**
+     * 查询条件设置
+     *
+     * @param id 规范文件id
+     * @param leftId 条件设置组id
+     * @param groupId 文件信息组id
+     */
+    @ApiOperation(value = "查询条件设置")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "规范文件id", required = true),
+            @ApiImplicitParam(name = "leftId", value = "条件设置组id"),
+            @ApiImplicitParam(name = "groupId", value = "文件信息组id", required = true),
+            @ApiImplicitParam(name = "joinGroupId", value = "条件设置组id")
+
+    })
+    @GetMapping("getConditionSet")
+    public R<List<StandardInfoVO>> getConditionSet(Long id, Long leftId, Long groupId, Long joinGroupId) {
+        List<StandardInfoVO> list = this.uStandardInfoService.getConditionSet(id, leftId, groupId, joinGroupId);
+        return R.data(list);
+    }
+
+    /**
+     * 查询关联元素
+     *
+     * @param id 规范文件id
+     * @param leftId 文件信息Id
+     * @param groupId 文件信息组id
+     */
+    @ApiOperation(value = "查询关联元素")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "规范文件id", required = true),
+            @ApiImplicitParam(name = "leftId", value = "文件信息Id"),
+            @ApiImplicitParam(name = "groupId", value = "文件信息组id", required = true),
+            @ApiImplicitParam(name = "joinGroupId", value = "条件设置组id")
+
+    })
+    @GetMapping("getElementJoin")
+    public R<List<StandardInfoPrivateJoinVO>> getElementJoin(Long id, Long leftId, Long groupId, Long joinGroupId) {
+        List<StandardInfoPrivateJoinVO> list = this.uStandardInfoService.getElementJoin(id, leftId, groupId, joinGroupId);
+        return R.data(list);
+    }
+
+    /**
+     * 效果预览
+     *
+     * @param ids standardInfo type=1的子级id集合
+     */
+    @ApiOperation(value = "效果预览")
+    @ApiImplicitParam(name = "ids", value = "standardInfo type=2的id集合", required = true)
+    @GetMapping("effectPreview")
+    public R<List<StandardInfoPrivateJoinVO>> effectPreview(String ids) {
+        List<StandardInfoPrivateJoinVO> list = this.uStandardInfoService.effectPreview(ids);
+        return R.data(list);
+    }
+
+
+}
+

+ 129 - 0
blade-service/blade-business/src/main/java/org/springblade/business/controller/TrialAutoNumberController.java

@@ -0,0 +1,129 @@
+/*
+ *      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.business.controller;
+
+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.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.business.entity.TrialAutoNumber;
+import org.springblade.business.vo.TrialAutoNumberVO;
+import org.springblade.business.service.ITrialAutoNumberService;
+import org.springblade.core.boot.ctrl.BladeController;
+
+/**
+ *  控制器
+ *
+ * @author BladeX
+ * @since 2025-06-10
+ */
+@RestController
+@AllArgsConstructor
+@RequestMapping("/trialautonumber")
+@Api(value = "试验编号自增", tags = "试验编号自增")
+public class TrialAutoNumberController extends BladeController {
+
+	private final ITrialAutoNumberService trialAutoNumberService;
+
+	/**
+	 * 详情
+	 */
+	@GetMapping("/detail")
+	@ApiOperationSupport(order = 1)
+	@ApiOperation(value = "详情", notes = "传入trialAutoNumber")
+	public R<TrialAutoNumber> detail(TrialAutoNumber trialAutoNumber) {
+		TrialAutoNumber detail = trialAutoNumberService.getOne(Condition.getQueryWrapper(trialAutoNumber));
+		return R.data(detail);
+	}
+
+	/**
+	 * 分页
+	 */
+	@GetMapping("/list")
+	@ApiOperationSupport(order = 2)
+	@ApiOperation(value = "分页", notes = "传入trialAutoNumber")
+	public R<IPage<TrialAutoNumber>> list(TrialAutoNumber trialAutoNumber, Query query) {
+		IPage<TrialAutoNumber> pages = trialAutoNumberService.page(Condition.getPage(query), Condition.getQueryWrapper(trialAutoNumber));
+		return R.data(pages);
+	}
+
+	/**
+	 * 自定义分页
+	 */
+	@GetMapping("/page")
+	@ApiOperationSupport(order = 3)
+	@ApiOperation(value = "分页", notes = "传入trialAutoNumber")
+	public R<IPage<TrialAutoNumberVO>> page(TrialAutoNumberVO trialAutoNumber, Query query) {
+		IPage<TrialAutoNumberVO> pages = trialAutoNumberService.selectTrialAutoNumberPage(Condition.getPage(query), trialAutoNumber);
+		return R.data(pages);
+	}
+
+	/**
+	 * 新增
+	 */
+	@PostMapping("/save")
+	@ApiOperationSupport(order = 4)
+	@ApiOperation(value = "新增", notes = "传入trialAutoNumber")
+	public R save(@Valid @RequestBody TrialAutoNumber trialAutoNumber) {
+		return R.status(trialAutoNumberService.save(trialAutoNumber));
+	}
+
+	/**
+	 * 修改
+	 */
+	@PostMapping("/update")
+	@ApiOperationSupport(order = 5)
+	@ApiOperation(value = "修改", notes = "传入trialAutoNumber")
+	public R update(@Valid @RequestBody TrialAutoNumber trialAutoNumber) {
+		return R.status(trialAutoNumberService.updateById(trialAutoNumber));
+	}
+
+	/**
+	 * 新增或修改
+	 */
+	@PostMapping("/submit")
+	@ApiOperationSupport(order = 6)
+	@ApiOperation(value = "新增或修改", notes = "传入trialAutoNumber")
+	public R submit(@Valid @RequestBody TrialAutoNumber trialAutoNumber) {
+		return R.status(trialAutoNumberService.saveOrUpdate(trialAutoNumber));
+	}
+
+
+	/**
+	 * 删除
+	 */
+	@PostMapping("/remove")
+	@ApiOperationSupport(order = 7)
+	@ApiOperation(value = "逻辑删除", notes = "传入ids")
+	public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
+		return R.status(trialAutoNumberService.deleteLogic(Func.toLongList(ids)));
+	}
+
+
+
+
+}

+ 1 - 1
blade-service/blade-business/src/main/java/org/springblade/business/controller/TrialMaterialController.java

@@ -90,7 +90,7 @@ public class TrialMaterialController extends BladeController {
     @PostMapping("/mobilization/submit")
     @ApiOperationSupport(order = 5)
     @ApiOperation(value = "进场材料新增或修改", notes = "传入TrialMaterialMobilization对象")
-    public R<Object> mobilizationSubmit(@Valid @RequestBody TrialMaterialMobilization obj) {
+    public R<Object> mobilizationSubmit(@Valid @RequestBody TrialMaterialMobilizationDTO obj) {
         return R.status(iTrialMaterialMobilizationService.mobilizationSubmit(obj));
     }
 

+ 347 - 0
blade-service/blade-business/src/main/java/org/springblade/business/controller/TrialNumberRuleController.java

@@ -0,0 +1,347 @@
+/*
+ *      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.business.controller;
+
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+import io.swagger.models.auth.In;
+import lombok.AllArgsConstructor;
+import javax.validation.Valid;
+
+import org.springblade.business.dto.TrialNumberRuleDTO;
+import org.springblade.business.mapper.TrialNumberRuleMapper;
+import org.springblade.business.vo.TrialNumberRuleVO1;
+import org.springblade.common.utils.SnowFlakeUtil;
+import org.springblade.core.log.exception.ServiceException;
+import org.springblade.core.mp.support.Condition;
+import org.springblade.core.mp.support.Query;
+import org.springblade.core.secure.BladeUser;
+import org.springblade.core.tool.api.R;
+import org.springblade.core.tool.utils.Func;
+import org.springblade.core.tool.utils.ObjectUtil;
+import org.springblade.manager.entity.WbsTreePrivate;
+import org.springframework.beans.BeanUtils;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.bind.annotation.RequestParam;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import org.springblade.business.entity.TrialNumberRule;
+import org.springblade.business.vo.TrialNumberRuleVO;
+import org.springblade.business.service.ITrialNumberRuleService;
+import org.springblade.core.boot.ctrl.BladeController;
+
+import java.io.FileNotFoundException;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+/**
+ *  控制器
+ *
+ * @author BladeX
+ * @since 2025-06-10
+ */
+@RestController
+@AllArgsConstructor
+@RequestMapping("/trialnumberrule")
+@Api(value = "试验编号规则", tags = "试验编号规则")
+public class TrialNumberRuleController extends BladeController {
+
+	private final ITrialNumberRuleService trialNumberRuleService;
+    private final TrialNumberRuleMapper  trialNumberRuleMapper;
+    private final JdbcTemplate jdbcTemplate;
+
+	/**
+	 * 详情
+	 */
+//	@GetMapping("/detail")
+//	@ApiOperationSupport(order = 1)
+//	@ApiOperation(value = "详情", notes = "传入trialNumberRule")
+//	public R<TrialNumberRule> detail(TrialNumberRule trialNumberRule) {
+//		TrialNumberRule detail = trialNumberRuleService.getOne(Condition.getQueryWrapper(trialNumberRule));
+//		return R.data(detail);
+//	}
+//
+//	/**
+//	 * 分页
+//	 */
+//	@GetMapping("/list")
+//	@ApiOperationSupport(order = 2)
+//	@ApiOperation(value = "分页", notes = "传入trialNumberRule")
+//	public R<IPage<TrialNumberRule>> list(TrialNumberRule trialNumberRule, Query query) {
+//		IPage<TrialNumberRule> pages = trialNumberRuleService.page(Condition.getPage(query), Condition.getQueryWrapper(trialNumberRule));
+//		return R.data(pages);
+//	}
+
+	/**
+	 * 自定义分页
+	 */
+//	@GetMapping("/page")
+//	@ApiOperationSupport(order = 3)
+//	@ApiOperation(value = "分页", notes = "传入trialNumberRule")
+//	public R<IPage<TrialNumberRuleVO>> page(TrialNumberRuleVO trialNumberRule, Query query) {
+//		IPage<TrialNumberRuleVO> pages = trialNumberRuleService.selectTrialNumberRulePage(Condition.getPage(query), trialNumberRule);
+//		return R.data(pages);
+//	}
+
+	/**
+	 * 新增
+	 */
+	@PostMapping("/save")
+	@ApiOperationSupport(order = 4)
+	@ApiOperation(value = "新增", notes = "传入trialNumberRule")
+	public R<String> save(@Valid @RequestBody TrialNumberRule trialNumberRule) {
+        if(trialNumberRule.getRule()==6){
+            if(StringUtils.isEmpty(trialNumberRule.getData())){
+                throw new ServiceException("数据填充不能为空");
+            }
+            String data = trialNumberRule.getData();
+            if (!data.matches("\\d+")) {
+                throw new ServiceException("数据填充只能为数字且不能有其他字符");
+            }
+        }
+        Integer maxSort=trialNumberRuleMapper.selectMaxSort(trialNumberRule.getProjectId(),trialNumberRule.getContractId(),trialNumberRule.getType());
+        List<TrialNumberRule> rules = trialNumberRuleMapper.selectList(Wrappers.<TrialNumberRule>query().lambda().eq(TrialNumberRule::getProjectId, trialNumberRule.getProjectId()).eq(TrialNumberRule::getContractId, trialNumberRule.getContractId()).eq(TrialNumberRule::getType, trialNumberRule.getType()));
+        if(!rules.isEmpty()){
+            for (TrialNumberRule rule : rules) {
+                if(Objects.equals(rule.getRule(), trialNumberRule.getRule())&&trialNumberRule.getRule()==6){
+                    throw new ServiceException("已存在流水号规则");
+                }
+            }
+        }
+        trialNumberRule.setSort(maxSort+1);
+        if(trialNumberRule.getContractId()==null||trialNumberRule.getContractId()==0L){
+            trialNumberRule.setStatus(1);
+        }else {
+            trialNumberRule.setStatus(2);
+        }
+        trialNumberRuleService.save(trialNumberRule);
+        if(trialNumberRule.getContractId()!=0L){
+            trialNumberRuleService.clearTrialNumber(trialNumberRule.getProjectId(),trialNumberRule.getContractId(),trialNumberRule.getType());
+        }
+        Map<String, String> map = trialNumberRuleService.getTrialNumber(trialNumberRule.getProjectId(),trialNumberRule.getContractId(), trialNumberRule.getType(), null, false);
+		return R.data(map.get("trialNumber"));
+	}
+
+    @PostMapping("/submitList")
+    public R<String> saveList(@RequestBody List<TrialNumberRule>list){
+        List<TrialNumberRule> collect = list.stream().filter(rule -> rule.getRule() == 6).collect(Collectors.toList());
+        if(collect.size()>1){
+            throw new ServiceException("流水只保存一个,不可保存多个");
+        }
+        List<TrialNumberRule> rules = trialNumberRuleMapper.selectList(Wrappers.<TrialNumberRule>query().lambda().eq(TrialNumberRule::getProjectId, list.get(0).getProjectId()).eq(TrialNumberRule::getContractId, list.get(0).getContractId()).eq(TrialNumberRule::getType, list.get(0).getType()));
+        List<TrialNumberRule> collect1 = rules.stream().filter(rule -> rule.getRule() == 6).collect(Collectors.toList());
+        TrialNumberRule rule6 = null;
+        if(collect1.size()>0){
+            rule6=collect1.get(0);
+        }
+        int i=1;
+        for (TrialNumberRule rule : list) {
+            if(rule.getContractId()==null||rule.getContractId()==0L){
+                rule.setStatus(1);
+            }else {
+                rule.setStatus(2);
+            }
+            rule.setSort(i++);
+            if(rule.getRule()==6){
+                if(StringUtils.isEmpty(rule.getData())){
+                    throw new ServiceException("数据填充不能为空");
+                }
+                String data = rule.getData();
+                if (!data.matches("\\d+")) {
+                    throw new ServiceException("数据填充只能为数字且不能有其他字符");
+                }
+                if(rule6!=null){
+                    if(rule.getId()!=null&&rule.getId().equals(rule6.getId())){
+                        if(rule.getContractId()!=null&&rule.getContractId()!=0L){
+                            if(!StringUtils.equals(rule.getData(),rule6.getData())){
+                                trialNumberRuleMapper.updateAutoIncrement(rule.getId());
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        trialNumberRuleService.saveOrUpdateBatch(list);
+        Map<String, String> map = trialNumberRuleService.getTrialNumber(list.get(0).getProjectId(),list.get(0).getContractId(), list.get(0).getType(), null, false);
+        return R.data(map.get("trialNumber"));
+    }
+
+	/**
+	 * 修改
+	 */
+	@PostMapping("/update")
+	@ApiOperationSupport(order = 5)
+	@ApiOperation(value = "修改", notes = "传入trialNumberRule")
+	public R<String> update(@Valid @RequestBody TrialNumberRule trialNumberRule) {
+        if(trialNumberRule.getRule()==6){
+            if(StringUtils.isEmpty(trialNumberRule.getData())){
+                throw new ServiceException("数据填充不能为空");
+            }
+            String data = trialNumberRule.getData();
+            if (!data.matches("\\d+")) {
+                throw new ServiceException("数据填充只能为数字且不能有其他字符");
+            }
+        }
+        List<TrialNumberRule> rules = trialNumberRuleMapper.selectList(Wrappers.<TrialNumberRule>query().lambda().eq(TrialNumberRule::getProjectId, trialNumberRule.getProjectId()).eq(TrialNumberRule::getContractId, trialNumberRule.getContractId()).eq(TrialNumberRule::getType, trialNumberRule.getType()));
+        if(!rules.isEmpty()){
+            for (TrialNumberRule rule : rules) {
+                if(!Objects.equals(rule.getId(), trialNumberRule.getId())&&trialNumberRule.getRule()==6&&rule.getRule()==6){
+                    throw new ServiceException("已存在流水号规则");
+                }
+            }
+        }
+        if(trialNumberRule.getRule()==6){
+            //查出流水号规则
+            TrialNumberRule trialNumberRule1 = trialNumberRuleService.getById(trialNumberRule.getId());
+            //如果是合同段的规则
+            if(trialNumberRule.getContractId()!=null&&trialNumberRule.getContractId()!=0L){
+                //并且数据填充发生改变
+                if(!StringUtils.equals(trialNumberRule1.getData(),trialNumberRule.getData())){
+                    //将自增表的数据删除
+                    trialNumberRuleMapper.updateAutoIncrement(trialNumberRule.getId());
+                }
+            }
+        }
+        trialNumberRuleService.updateById(trialNumberRule);
+        Map<String, String> map = trialNumberRuleService.getTrialNumber(trialNumberRule.getProjectId(),trialNumberRule.getContractId(), trialNumberRule.getType(), null, false);
+		return R.data(map.get("trialNumber"));
+	}
+
+	/**
+	 * 调整排序
+	 */
+	@PostMapping("/sort")
+	@ApiOperationSupport(order = 6)
+	@ApiOperation(value = "调整排序", notes = "传入List<TrialNumberRule>")
+	public R<String> sort(@Valid @RequestBody List<TrialNumberRule> trialNumberRules) {
+        for (int i = 0; i < trialNumberRules.size(); i++) {
+            trialNumberRules.get(i).setSort(i+1);
+        }
+        trialNumberRuleService.saveOrUpdateBatch(trialNumberRules);
+        if(ObjectUtil.isNotEmpty(trialNumberRules.get(0).getContractId())&&trialNumberRules.get(0).getContractId()!=0L){
+            trialNumberRuleService.clearTrialNumber(trialNumberRules.get(0).getProjectId(),trialNumberRules.get(0).getContractId(),trialNumberRules.get(0).getType());
+        }
+        Map<String, String> map = trialNumberRuleService.getTrialNumber(trialNumberRules.get(0).getProjectId(),trialNumberRules.get(0).getContractId(), trialNumberRules.get(0).getType(), null, false);
+        return R.data(map.get("trialNumber"));
+	}
+
+
+    /**
+     * 新增或修改
+     */
+//    @PostMapping("/submit")
+//    @ApiOperationSupport(order = 6)
+//    @ApiOperation(value = "新增或修改", notes = "传入trialNumberRule")
+//    public R<String> submit(@Valid @RequestBody TrialNumberRule trialNumberRule,BladeUser bladeUser) {
+//
+//
+//
+//
+//        return null;
+//    }
+
+
+	/**
+	 * 删除
+	 */
+	@PostMapping("/remove")
+	@ApiOperationSupport(order = 7)
+	@ApiOperation(value = "逻辑删除", notes = "传入ids")
+	public R<String> remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
+        String[] idss = ids.split(",");
+        TrialNumberRule trialNumberRule = trialNumberRuleService.getById(idss[0]);
+        trialNumberRuleService.clearTrialNumber(trialNumberRule.getProjectId(),trialNumberRule.getContractId(),trialNumberRule.getType());
+        trialNumberRuleService.deleteLogic(Func.toLongList(ids));
+        Map<String, String> map = trialNumberRuleService.getTrialNumber(trialNumberRule.getProjectId(),trialNumberRule.getContractId(), trialNumberRule.getType(), null, false);
+		return R.data(map.get("trialNumber"));
+	}
+
+
+
+
+    /**
+     * type 1材料 2样品  4记录表 5报告表
+     * 委托单另外一个方法单独获取
+     */
+    @GetMapping("/getTrialNumber")
+    @ApiOperationSupport(order = 8)
+    @ApiOperation(value = "获取试验编号", notes = "传入projectId,contractId,type,nodeId")
+    public R<Map<String, String>> getTrialNumber(Long projectId,Long contractId, Integer type, Long nodeId){
+        Map<String, String> map = trialNumberRuleService.getTrialNumber(projectId,contractId, type, nodeId, true);
+        return  R.data(map);
+    }
+    @GetMapping("/getEntrustNumber")
+    @ApiOperationSupport(order = 11)
+    @ApiOperation(value = "获取委托单编号")
+    public R<Map<String, String>>getEntrustNumber(Long pkeyId,Long contractId) throws FileNotFoundException {
+        return R.data(trialNumberRuleService.getEntrustNumber(pkeyId,contractId));
+    }
+
+    /**
+     * 获取试验编号规则
+     * @param
+     * @param contractId
+     * @param type
+     * @return
+     */
+    @GetMapping("/getTrialNumberRule")
+    @ApiOperationSupport(order = 9)
+    @ApiOperation(value = "获取试验编号规则", notes = "传入projectId,contractId(后管查询传0),type")
+    public R<TrialNumberRuleVO1> getTrialNumberRule(Long projectId,Long contractId, Integer type){
+        return R.data(trialNumberRuleService.getTrialNumberRule(projectId,contractId,type));
+    }
+
+    @GetMapping("/reTrialNumberRule")
+    @ApiOperationSupport(order = 10)
+    @ApiOperation(value = "重置试验编号规则")
+    public R<String> reTrialNumberRule(Long projectId, Long contractId, Integer type){
+        List<TrialNumberRule> trialNumberRules = trialNumberRuleService.getBaseMapper().selectList(Wrappers.<TrialNumberRule>query().lambda().eq(TrialNumberRule::getProjectId, projectId).eq(TrialNumberRule::getContractId, contractId).eq(TrialNumberRule::getType, type).eq(TrialNumberRule::getStatus,2).orderByAsc(TrialNumberRule::getSort));
+        if(!trialNumberRules.isEmpty()){
+            String ids = trialNumberRules.stream()
+                    .map(o -> o.getId().toString())
+                    .collect(Collectors.joining(","));
+            TrialNumberRule trialNumberRule = trialNumberRules.get(0);
+            trialNumberRuleService.clearTrialNumber(trialNumberRule.getProjectId(),trialNumberRule.getContractId(),trialNumberRule.getType());
+            trialNumberRuleService.deleteLogic(Func.toLongList(ids));
+        }
+        List<TrialNumberRule> rules = trialNumberRuleService.getBaseMapper().selectList(Wrappers.<TrialNumberRule>query().lambda().eq(TrialNumberRule::getProjectId, projectId).eq(TrialNumberRule::getType, type).eq(TrialNumberRule::getStatus, 1).orderByAsc(TrialNumberRule::getSort));
+        if(!rules.isEmpty()){
+            for (TrialNumberRule rule : rules) {
+                rule.setId(null);
+                rule.setStatus(2);
+                rule.setContractId(contractId);
+            }
+            trialNumberRuleService.saveOrUpdateBatch(rules);
+            Map<String, String> map = trialNumberRuleService.getTrialNumber(projectId,contractId, type, null, false);
+            return R.data(map.get("trialNumber"));
+        }else {
+            return R.fail("请先在后管设置编号规则");
+        }
+    }
+
+
+
+
+
+
+}

+ 20 - 0
blade-service/blade-business/src/main/java/org/springblade/business/mapper/PrivateStandardMapper.java

@@ -0,0 +1,20 @@
+package org.springblade.business.mapper;
+
+import org.apache.ibatis.annotations.Param;
+import org.springblade.business.entity.PrivateStandard;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+* @author LHB
+* @description 针对表【u_wbs_private_standard(规范文件夹及规范文件表)】的数据库操作Mapper
+* @createDate 2025-06-10 10:48:37
+* @Entity generator.domain.UWbsPrivateStandard
+*/
+public interface PrivateStandardMapper extends BaseMapper<PrivateStandard> {
+
+    void updateStatus(@Param("parentId") Long parentId);
+}
+
+
+
+

+ 35 - 0
blade-service/blade-business/src/main/java/org/springblade/business/mapper/PrivateStandardMapper.xml

@@ -0,0 +1,35 @@
+<?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.business.mapper.PrivateStandardMapper">
+
+    <resultMap id="BaseResultMap" type="org.springblade.business.entity.PrivateStandard">
+            <id property="id" column="id" />
+            <result property="name" column="name" />
+            <result property="parentId" column="parent_id" />
+            <result property="privateId" column="private_id" />
+            <result property="type" column="type" />
+            <result property="issueDate" column="issue_date" />
+            <result property="actualizeDate" column="actualize_date" />
+            <result property="isDeleted" column="is_deleted" />
+            <result property="createTime" column="create_time" />
+            <result property="createUser" column="create_user" />
+            <result property="updateTime" column="update_time" />
+            <result property="updateUser" column="update_user" />
+    </resultMap>
+
+    <sql id="Base_Column_List">
+        id,name,parent_id,private_id,type,issue_date,
+        actualize_date,is_deleted,create_time,create_user,
+        update_time,update_user
+    </sql>
+    <update id="updateStatus">
+        UPDATE u_wbs_private_standard
+        SET `status` = 2,
+            `name` = concat( NAME, '-已过期' )
+        WHERE
+            parent_id = #{parentId}
+          AND STATUS = 1
+    </update>
+</mapper>

+ 18 - 0
blade-service/blade-business/src/main/java/org/springblade/business/mapper/StandardFileMapper.java

@@ -0,0 +1,18 @@
+package org.springblade.business.mapper;
+
+import org.springblade.business.entity.StandardFile;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+* @author LHB
+* @description 针对表【u_standard_file(规范文件表)】的数据库操作Mapper
+* @createDate 2025-06-13 09:24:14
+* @Entity generator.domain.UStandardFile
+*/
+public interface StandardFileMapper extends BaseMapper<StandardFile> {
+
+}
+
+
+
+

+ 23 - 0
blade-service/blade-business/src/main/java/org/springblade/business/mapper/StandardFileMapper.xml

@@ -0,0 +1,23 @@
+<?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.business.mapper.StandardFileMapper">
+
+    <resultMap id="BaseResultMap" type="org.springblade.business.entity.StandardFile">
+            <id property="id" column="id" />
+            <result property="standardId" column="standard_id" />
+            <result property="fileName" column="file_name" />
+            <result property="standardFileUrl" column="standard_file_url" />
+            <result property="isDeleted" column="is_deleted" />
+            <result property="createTime" column="create_time" />
+            <result property="createUser" column="create_user" />
+            <result property="updateTime" column="update_time" />
+            <result property="updateUser" column="update_user" />
+    </resultMap>
+
+    <sql id="Base_Column_List">
+        id,standard_id,file_name,standard_file_url,is_deleted,create_time,
+        create_user,update_time,update_user
+    </sql>
+</mapper>

+ 28 - 0
blade-service/blade-business/src/main/java/org/springblade/business/mapper/StandardInfoJoinMapper.java

@@ -0,0 +1,28 @@
+package org.springblade.business.mapper;
+
+import org.apache.ibatis.annotations.Param;
+import org.springblade.business.entity.StandardInfoJoin;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+* @author LHB
+* @description 针对表【u_standard_info_join(样品信息关联表)】的数据库操作Mapper
+* @createDate 2025-06-11 09:57:39
+* @Entity org.springblade.business.entity.UStandardInfoJoin
+*/
+public interface StandardInfoJoinMapper extends BaseMapper<StandardInfoJoin> {
+
+    /**
+     * 软删除
+     * @param userId 用户 id
+     * @param isDeleted 删除状态
+     * @param standardId 规范文件id
+     */
+    void updateJoin(@Param("userId") Long userId,
+                    @Param("isDeleted") int isDeleted,
+                    @Param("standardId") Long standardId);
+}
+
+
+
+

+ 32 - 0
blade-service/blade-business/src/main/java/org/springblade/business/mapper/StandardInfoJoinMapper.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.business.mapper.StandardInfoJoinMapper">
+
+    <resultMap id="BaseResultMap" type="org.springblade.business.entity.StandardInfoJoin">
+            <id property="id" column="id" />
+            <result property="groupId" column="group_id" />
+            <result property="standardInfoLeftId" column="standard_info_left_id" />
+            <result property="standardInfoRightId" column="standard_info_right_id" />
+            <result property="isDeleted" column="is_deleted" />
+            <result property="createTime" column="create_time" />
+            <result property="createUser" column="create_user" />
+            <result property="updateTime" column="update_time" />
+            <result property="updateUser" column="update_user" />
+    </resultMap>
+
+    <sql id="Base_Column_List">
+        id,group_id,standard_info_left_id,standard_info_right_id,is_deleted,create_time,create_user,
+        update_time,update_user
+    </sql>
+    <update id="updateJoin">
+        UPDATE u_standard_info_join a
+            INNER JOIN u_standard_info b ON a.standard_info_left_id = b.id
+        SET a.is_deleted = #{isDeleted},
+            a.update_user = #{userId}
+        WHERE
+            b.is_deleted = 0
+          AND b.standard_id = #{standardId}
+    </update>
+</mapper>

+ 45 - 0
blade-service/blade-business/src/main/java/org/springblade/business/mapper/StandardInfoMapper.java

@@ -0,0 +1,45 @@
+package org.springblade.business.mapper;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.apache.ibatis.annotations.Param;
+import org.springblade.business.dto.StandardInfoDTO;
+import org.springblade.business.entity.StandardInfo;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.springblade.business.vo.StandardInfoDtoVo;
+import org.springblade.business.vo.StandardInfoPrivateJoinVO;
+import org.springblade.business.vo.StandardInfoVO;
+
+import java.util.List;
+
+/**
+ * @author LHB
+ * @description 针对表【u_standard_info(规范参数管理-基础信息)】的数据库操作Mapper
+ * @createDate 2025-06-11 09:57:39
+ * @Entity org.springblade.business.entity.UStandardInfo
+ */
+public interface StandardInfoMapper extends BaseMapper<StandardInfo> {
+
+    IPage<StandardInfoDTO> selectMyPage(Page<StandardInfoDTO> page, @Param("query") StandardInfo standardInfo);
+
+    StandardInfoDTO selectMyOne(@Param("id") Long id);
+
+    List<StandardInfoVO> getConditionSet(@Param("id") Long id,
+                                         @Param("leftId") Long leftId,
+                                         @Param("groupId") Long groupId,
+                                         @Param("joinGroupId") Long joinGroupId
+    );
+
+    List<StandardInfoPrivateJoinVO> getElementJoin(@Param("id") Long id,
+                                                   @Param("leftId") Long leftId,
+                                                   @Param("groupId") Long groupId,
+                                                   @Param("joinGroupId") Long joinGroupId
+    );
+
+    List<StandardInfoPrivateJoinVO> effectPreview(@Param("rightIds") List<Long> rightIds,
+                                                  @Param("size") Integer size);
+}
+
+
+
+

+ 305 - 0
blade-service/blade-business/src/main/java/org/springblade/business/mapper/StandardInfoMapper.xml

@@ -0,0 +1,305 @@
+<?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.business.mapper.StandardInfoMapper">
+
+    <resultMap id="BaseResultMap" type="org.springblade.business.entity.StandardInfo">
+        <id property="id" column="id"/>
+        <result property="name" column="name"/>
+        <result property="symbol" column="symbol"/>
+        <result property="parentId" column="parent_id"/>
+        <result property="type" column="type"/>
+        <result property="isDeleted" column="is_deleted"/>
+        <result property="createTime" column="create_time"/>
+        <result property="createUser" column="create_user"/>
+        <result property="updateTime" column="update_time"/>
+        <result property="updateUser" column="update_user"/>
+    </resultMap>
+    <resultMap id="BaseResultPageMap" type="org.springblade.business.dto.StandardInfoDTO">
+        <id property="id" column="id"/>
+        <result property="name" column="name"/>
+        <result property="symbol" column="symbol"/>
+        <result property="parentId" column="parent_id"/>
+        <result property="standardId" column="standard_id"/>
+        <result property="type" column="type"/>
+        <result property="isDeleted" column="is_deleted"/>
+        <result property="createTime" column="create_time"/>
+        <result property="createUser" column="create_user"/>
+        <result property="updateTime" column="update_time"/>
+        <result property="updateUser" column="update_user"/>
+        <collection property="info" ofType="org.springblade.business.entity.StandardInfo" select="findByParentId" column="{parentId=id}">
+        </collection>
+    </resultMap>
+
+    <sql id="Base_Column_List">
+        id
+        ,name,symbol,parent_id,standard_id,type,is_deleted,create_time,
+        create_user,update_time,update_user
+    </sql>
+    <select id="selectMyPage" resultMap="BaseResultPageMap">
+        SELECT
+            <include refid="Base_Column_List"/>
+        FROM
+            u_standard_info
+        <where>
+            is_deleted = 0
+            <if test="query.type != null">
+                AND type = #{query.type}
+            </if>
+            <choose>
+                <when test="query.parentId != null">
+                    AND parent_id = #{query.parentId}
+                </when>
+                <otherwise>
+                    AND parent_id = 0
+                </otherwise>
+            </choose>
+            <if test="query.standardId != null">
+                AND standard_id =  #{query.standardId}
+            </if>
+        </where>
+    </select>
+    <select id="selectMyOne" resultMap="BaseResultPageMap">
+        SELECT
+            <include refid="Base_Column_List"/>
+        FROM
+            u_standard_info
+        WHERE
+            is_deleted = 0 AND
+            id = #{id}
+    </select>
+    <select id="findByParentId" resultType="org.springblade.business.entity.StandardInfo">
+        select
+            <include refid="Base_Column_List"/>,concat(symbol,name) symbolName
+        FROM
+            u_standard_info
+        WHERE
+            is_deleted = 0
+            AND parent_id = #{parentId}
+    </select>
+
+
+
+
+    <!-- ``````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````` -->
+
+    <resultMap id="BaseResultConditionSet" type="org.springblade.business.vo.StandardInfoVO">
+        <id property="id" column="id"/>
+        <result property="name" column="name"/>
+        <result property="parentId" column="parent_id"/>
+        <result property="type" column="type"/>
+        <result property="symbol" column="symbol"/>
+        <result property="symbolName" column="symbolName"/>
+        <result property="groupId" column="group_id"/>
+        <collection property="standardInfos" ofType="org.springblade.business.vo.StandardInfoConditionVo" select="findByJoinLeftId" column="{leftId=id,groupId=group_id}">
+        </collection>
+    </resultMap>
+    <sql id="Base_Column_Join_List">
+        a.id,
+        a.`name`,
+        a.parent_id,
+        a.standard_id,
+        a.`type`,
+        a.is_deleted,
+        a.create_time,
+        a.create_user,
+        a.update_time,
+        a.update_user
+    </sql>
+
+    <select id="getConditionSet" resultMap="BaseResultConditionSet">
+        select
+            <include refid="Base_Column_Join_List"/>, concat(a.symbol,a.name) symbolName,b.group_id
+        from
+            u_standard_info a
+            INNER join u_standard_info p on a.parent_id = p.id and a.is_deleted = p.is_deleted
+            INNER JOIN u_standard_info_join b on a.id = b.standard_info_left_id and a.is_deleted = b.is_deleted
+        where
+            a.is_deleted = 0
+            <if test="id != null">
+                and  a.standard_id = #{id}
+            </if>
+            <if test="leftId != null">
+                and  b.standard_info_left_id = #{leftId}
+            </if>
+            <if test="groupId != null">
+                and  p.id = #{groupId}
+            </if>
+            <if test="joinGroupId != null">
+                and  b.group_id = #{joinGroupId}
+            </if>
+
+        GROUP BY
+            b.group_id,b.standard_info_left_id
+    </select>
+
+    <resultMap id="findByJoinLeftIdMap" type="org.springblade.business.vo.StandardInfoConditionVo">
+        <id property="id" column="id"/>
+        <collection property="rightStandardInfos" ofType="org.springblade.business.entity.StandardInfo" select="findRightByJoinLeftId" column="{id=id,leftId=leftId,groupId=groupId}">
+        </collection>
+    </resultMap>
+
+    <select id="findByJoinLeftId" resultMap="findByJoinLeftIdMap">
+        SELECT
+            c.id,
+            c.`name`,
+            c.parent_id,
+            c.standard_id,
+            c.`type`,
+            c.is_deleted,
+            c.create_time,
+            c.create_user,
+            c.update_time,
+            c.update_user,
+            b.standard_info_left_id leftId,
+            b.group_id groupId
+        FROM
+            u_standard_info a
+            INNER JOIN u_standard_info_join b ON a.id = b.standard_info_right_id AND a.is_deleted = b.is_deleted
+            INNER JOIN u_standard_info c ON a.parent_id = c.id AND a.is_deleted = c.is_deleted
+        WHERE
+            b.standard_info_left_id = #{leftId}
+            <if test="groupId != null">
+                and b.group_id = #{groupId}
+            </if>
+            and a.is_deleted = 0
+        group by
+            c.id
+    </select>
+    <select id="findRightByJoinLeftId" resultType="org.springblade.business.entity.StandardInfo">
+        SELECT
+            <include refid="Base_Column_Join_List"/>
+        FROM
+            u_standard_info a
+            INNER JOIN u_standard_info_join b ON a.id = b.standard_info_right_id AND a.is_deleted = b.is_deleted
+            INNER JOIN u_standard_info c ON a.parent_id = c.id AND a.is_deleted = c.is_deleted
+        WHERE
+            a.parent_id = #{id} and b.standard_info_left_id = #{leftId}
+            <if test="groupId != null">
+                and b.group_id = #{groupId}
+            </if>
+            and a.is_deleted = 0
+        group by
+            a.id
+    </select>
+    <!-- ``````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````` -->
+
+    <resultMap id="BaseResultElementJoin" type="org.springblade.business.vo.StandardInfoPrivateJoinVO">
+        <id property="id" column="id"/>
+        <result property="groupId" column="group_id"/>
+        <result property="name" column="name"/>
+        <result property="parentId" column="parent_id"/>
+        <result property="type" column="type"/>
+        <result property="symbol" column="symbol"/>
+        <result property="symbolName" column="symbolName"/>
+        <collection property="group" ofType="org.springblade.business.vo.StandardInfoPrivateJoinGroupVO" select="findByPrivateJoinLeftId" column="{leftId=id,groupId=group_id}">
+        </collection>
+    </resultMap>
+
+    <sql id="Base_Private_Column_List">
+        a.id,
+        a.standard_info_id,
+        a.private_id,
+        a.col_key,
+        a.col_name,
+        a.is_deleted,
+        a.create_time,
+        a.create_user,
+        a.update_time,
+        a.update_user
+    </sql>
+    <select id="getElementJoin" resultMap="BaseResultElementJoin">
+        select
+            <include refid="Base_Column_Join_List"/>, concat(a.symbol,a.name) symbolName,b.group_id
+        from
+            u_standard_info a
+            INNER JOIN u_standard_info c on a.parent_id = c.id and a.is_deleted = c.is_deleted
+            INNER JOIN u_standard_info_private_join b on a.id = b.standard_info_id and a.is_deleted = b.is_deleted
+        where
+            a.is_deleted = 0
+            <if test="id != null">
+                and  a.standard_id = #{id}
+            </if>
+            <if test="leftId != null">
+                and  b.standard_info_id = #{leftId}
+            </if>
+            <if test="groupId != null">
+                and  c.id = #{groupId}
+            </if>
+        GROUP BY
+            b.group_id,b.standard_info_id
+    </select>
+
+
+    <resultMap id="BaseResultElementGroupPrivate" type="org.springblade.business.vo.StandardInfoPrivateJoinGroupVO">
+        <result property="standardInfoId" column="standard_info_id"/>
+        <result property="privateId" column="private_id"/>
+        <result property="privateName" column="privateName"/>
+        <result property="elementNames" column="elementNames"/>
+        <collection property="keys" ofType="org.springblade.business.vo.StandardElementVo" select="findByPrivateGroupJoinLeftId" column="{standardInfoId=standard_info_id,privateId=private_id,groupId=groupId}">
+        </collection>
+    </resultMap>
+    <select id="findByPrivateJoinLeftId" resultMap="BaseResultElementGroupPrivate">
+        SELECT
+            a.standard_info_id,
+            a.private_id,
+            b.node_name privateName,
+            GROUP_CONCAT(col_name SEPARATOR ',') elementNames,
+            a.group_id groupId
+        FROM
+            u_standard_info_private_join a
+            INNER JOIN m_wbs_tree_private b ON a.private_id = b.p_key_id AND a.is_deleted = b.is_deleted
+        WHERE
+            a.standard_info_id = #{leftId}
+          <if test="groupId!=null">
+              and a.group_id = #{groupId}
+          </if>
+          AND a.is_deleted = 0
+        GROUP BY
+            a.group_id,a.private_id
+    </select>
+
+    <select id="findByPrivateGroupJoinLeftId" resultType="org.springblade.business.vo.StandardElementVo">
+        SELECT
+            col_key,col_name
+        FROM
+        u_standard_info_private_join a
+        INNER JOIN m_wbs_tree_private b ON a.private_id = b.p_key_id AND a.is_deleted = b.is_deleted
+        WHERE
+        a.standard_info_id = #{standardInfoId} and a.private_id = #{privateId}
+        <if test="groupId!=null">
+            and a.group_id = #{groupId}
+        </if>
+        AND a.is_deleted = 0
+    </select>
+
+
+
+
+
+    <!-- ``````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````` -->
+
+
+
+
+    <select id="effectPreview" resultMap="BaseResultElementJoin">
+        SELECT
+            a.*, concat(a.symbol,a.name) symbolName,null group_id
+        FROM
+            u_standard_info a
+                INNER JOIN u_standard_info_join b ON a.id = b.standard_info_left_id
+                LEFT JOIN u_standard_info_private_join c ON a.id = c.standard_info_id
+
+                AND a.is_deleted = b.is_deleted
+        WHERE
+            a.is_deleted = 0
+            AND b.standard_info_right_id in
+            <foreach item="item" collection="rightIds" separator="," open="(" close=")" index="index">
+                #{item}
+            </foreach>
+        GROUP BY
+            b.standard_info_left_id
+        HAVING COUNT(DISTINCT b.standard_info_right_id) = #{size};
+    </select>
+</mapper>

+ 28 - 0
blade-service/blade-business/src/main/java/org/springblade/business/mapper/StandardInfoPrivateJoinMapper.java

@@ -0,0 +1,28 @@
+package org.springblade.business.mapper;
+
+import org.apache.ibatis.annotations.Param;
+import org.springblade.business.entity.StandardInfoPrivateJoin;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+* @author LHB
+* @description 针对表【u_standard_info_private_join(样品信息与试验表 关联表)】的数据库操作Mapper
+* @createDate 2025-06-11 09:57:39
+* @Entity org.springblade.business.entity.UStandardInfoPrivateJoin
+*/
+public interface StandardInfoPrivateJoinMapper extends BaseMapper<StandardInfoPrivateJoin> {
+
+    /**
+     * 软删除
+     * @param userId 用户 id
+     * @param isDeleted 删除状态
+     * @param standardId 规范文件id
+     */
+    void updateJoin(@Param("userId") Long userId,
+                    @Param("isDeleted") int isDeleted,
+                    @Param("standardId") Long standardId);
+}
+
+
+
+

+ 33 - 0
blade-service/blade-business/src/main/java/org/springblade/business/mapper/StandardInfoPrivateJoinMapper.xml

@@ -0,0 +1,33 @@
+<?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.business.mapper.StandardInfoPrivateJoinMapper">
+
+    <resultMap id="BaseResultMap" type="org.springblade.business.entity.StandardInfoPrivateJoin">
+            <id property="id" column="id" />
+            <result property="standardInfoId" column="standard_info_id" />
+            <result property="privateId" column="private_id" />
+            <result property="colKey" column="col_key" />
+            <result property="colName" column="col_name" />
+            <result property="isDeleted" column="is_deleted" />
+            <result property="createTime" column="create_time" />
+            <result property="createUser" column="create_user" />
+            <result property="updateTime" column="update_time" />
+            <result property="updateUser" column="update_user" />
+    </resultMap>
+
+    <sql id="Base_Column_List">
+        id,standard_info_id,private_id,col_key,col_name,is_deleted,
+        create_time,create_user,update_time,update_user
+    </sql>
+    <update id="updateJoin">
+        UPDATE u_standard_info_private_join a
+            INNER JOIN u_standard_info b ON a.standard_info_id = b.id
+        SET a.is_deleted = #{isDeleted},
+            a.update_user = #{userId}
+        WHERE
+            b.is_deleted = 0
+          AND b.standard_id = #{standardId}
+    </update>
+</mapper>

+ 44 - 0
blade-service/blade-business/src/main/java/org/springblade/business/mapper/TrialAutoNumberMapper.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.business.mapper;
+
+import org.apache.ibatis.annotations.Param;
+import org.springblade.business.entity.TrialAutoNumber;
+import org.springblade.business.vo.TrialAutoNumberVO;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import java.util.List;
+
+/**
+ *  Mapper 接口
+ *
+ * @author BladeX
+ * @since 2025-06-10
+ */
+public interface TrialAutoNumberMapper extends BaseMapper<TrialAutoNumber> {
+
+	/**
+	 * 自定义分页
+	 *
+	 * @param page
+	 * @param trialAutoNumber
+	 * @return
+	 */
+	List<TrialAutoNumberVO> selectTrialAutoNumberPage(IPage page, TrialAutoNumberVO trialAutoNumber);
+
+    void clearTrialAutoNumber(@Param("nameRuleId") Long nameRuleId);
+}

+ 22 - 0
blade-service/blade-business/src/main/java/org/springblade/business/mapper/TrialAutoNumberMapper.xml

@@ -0,0 +1,22 @@
+<?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.business.mapper.TrialAutoNumberMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="trialAutoNumberResultMap" type="org.springblade.business.entity.TrialAutoNumber">
+        <result column="id" property="id"/>
+        <result column="is_deleted" property="isDeleted"/>
+        <result column="auto_increment_number" property="autoIncrementNumber"/>
+        <result column="form_data_id" property="formDataId"/>
+        <result column="type" property="type"/>
+    </resultMap>
+    <update id="clearTrialAutoNumber">
+        update u_trial_auto_number set is_deleted = 1 where name_rule_id = #{nameRuleId}
+    </update>
+
+
+    <select id="selectTrialAutoNumberPage" resultMap="trialAutoNumberResultMap">
+        select * from u_trial_auto_number where is_deleted = 0
+    </select>
+
+</mapper>

+ 46 - 0
blade-service/blade-business/src/main/java/org/springblade/business/mapper/TrialNumberRuleMapper.java

@@ -0,0 +1,46 @@
+/*
+ *      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.business.mapper;
+
+import org.apache.ibatis.annotations.Param;
+import org.springblade.business.entity.TrialNumberRule;
+import org.springblade.business.vo.TrialNumberRuleVO;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import java.util.List;
+
+/**
+ *  Mapper 接口
+ *
+ * @author BladeX
+ * @since 2025-06-10
+ */
+public interface TrialNumberRuleMapper extends BaseMapper<TrialNumberRule> {
+
+	/**
+	 * 自定义分页
+	 *
+	 * @param page
+	 * @param trialNumberRule
+	 * @return
+	 */
+	List<TrialNumberRuleVO> selectTrialNumberRulePage(IPage page, TrialNumberRuleVO trialNumberRule);
+
+    Integer selectMaxSort(@Param("projectId") Long projectId, @Param("contractId") Long contractId, @Param("type") Integer type);
+
+    void updateAutoIncrement(@Param("id") Long id);
+}

+ 34 - 0
blade-service/blade-business/src/main/java/org/springblade/business/mapper/TrialNumberRuleMapper.xml

@@ -0,0 +1,34 @@
+<?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.business.mapper.TrialNumberRuleMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="trialNumberRuleResultMap" type="org.springblade.business.entity.TrialNumberRule">
+        <result column="id" property="id"/>
+        <result column="create_time" property="createTime"/>
+        <result column="create_user" property="createUser"/>
+        <result column="create_dept" property="createDept"/>
+        <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="type" property="type"/>
+        <result column="rule" property="rule"/>
+        <result column="data" property="data"/>
+        <result column="is_auto_increment" property="isAutoIncrement"/>
+    </resultMap>
+    <update id="updateAutoIncrement">
+        update u_trial_auto_number set is_deleted=1 where number_rule_id = #{id}
+    </update>
+
+
+    <select id="selectTrialNumberRulePage" resultMap="trialNumberRuleResultMap">
+        select * from u_trial_number_rule where is_deleted = 0
+    </select>
+    <select id="selectMaxSort" resultType="java.lang.Integer">
+        select IFNULL(MAX(sort), 0) from u_trial_number_rule where project_id = #{projectId} and contract_id = #{contractId} and type = #{type}
+    </select>
+
+</mapper>

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

@@ -77,4 +77,5 @@ public interface IEntrustInfoService extends BaseService<EntrustInfo> {
 	R checkSample(Long sampleId);
 
     R annul(String id);
+
 }

+ 41 - 0
blade-service/blade-business/src/main/java/org/springblade/business/service/ITrialAutoNumberService.java

@@ -0,0 +1,41 @@
+/*
+ *      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.business.service;
+
+import org.springblade.business.entity.TrialAutoNumber;
+import org.springblade.business.vo.TrialAutoNumberVO;
+import org.springblade.core.mp.base.BaseService;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+
+/**
+ *  服务类
+ *
+ * @author BladeX
+ * @since 2025-06-10
+ */
+public interface ITrialAutoNumberService extends BaseService<TrialAutoNumber> {
+
+	/**
+	 * 自定义分页
+	 *
+	 * @param page
+	 * @param trialAutoNumber
+	 * @return
+	 */
+	IPage<TrialAutoNumberVO> selectTrialAutoNumberPage(IPage<TrialAutoNumberVO> page, TrialAutoNumberVO trialAutoNumber);
+
+}

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

@@ -17,7 +17,7 @@ public interface ITrialMaterialMobilizationService extends BaseService<TrialMate
 
     boolean mobilizationVerification(String number, String id, String contractId);
 
-    boolean mobilizationSubmit(TrialMaterialMobilization obj);
+    boolean mobilizationSubmit(TrialMaterialMobilizationDTO obj);
 
     TrialMaterialMobilization mobilizationDetail(Long id);
 

+ 59 - 0
blade-service/blade-business/src/main/java/org/springblade/business/service/ITrialNumberRuleService.java

@@ -0,0 +1,59 @@
+/*
+ *      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.business.service;
+
+import cn.hutool.core.lang.hash.Hash;
+import org.springblade.business.entity.TrialNumberRule;
+import org.springblade.business.vo.TrialNumberRuleVO;
+import org.springblade.business.vo.TrialNumberRuleVO1;
+import org.springblade.core.mp.base.BaseService;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import org.springblade.core.secure.BladeUser;
+
+import java.io.FileNotFoundException;
+import java.util.Map;
+
+/**
+ *  服务类
+ *
+ * @author BladeX
+ * @since 2025-06-10
+ */
+public interface ITrialNumberRuleService extends BaseService<TrialNumberRule> {
+
+	/**
+	 * 自定义分页
+	 *
+	 * @param page
+	 * @param trialNumberRule
+	 * @return
+	 */
+	IPage<TrialNumberRuleVO> selectTrialNumberRulePage(IPage<TrialNumberRuleVO> page, TrialNumberRuleVO trialNumberRule);
+
+    Map<String,String> getTrialNumber(Long projectId,Long contractId, Integer type, Long nodeId, Boolean isSaveRedis);
+
+    TrialNumberRuleVO1 getTrialNumberRule(Long project,Long contractId, Integer type);
+    //编号规则发生改变,清空对应的编号
+    boolean clearTrialNumber(Long projectId, Long contractId, Integer type);
+
+	boolean checkTrialNumberIsExist(String trialNumber,Integer type,Long contractId);
+
+
+    Map<String, String> getEntrustNumber(Long pkeyId,Long contractId) throws FileNotFoundException;
+
+	void checkSave(Long contractId, int i, Long id, String autoIncrementNumber);
+}

+ 28 - 0
blade-service/blade-business/src/main/java/org/springblade/business/service/PrivateStandardService.java

@@ -0,0 +1,28 @@
+package org.springblade.business.service;
+
+import org.springblade.business.dto.PrivateStandardDTO;
+import org.springblade.business.entity.PrivateStandard;
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.List;
+
+/**
+* @author LHB
+* @description 针对表【u_wbs_private_standard(规范文件夹及规范文件表)】的数据库操作Service
+* @createDate 2025-06-10 10:48:37
+*/
+public interface PrivateStandardService extends IService<PrivateStandard> {
+
+    boolean delete(Long id);
+
+    boolean insert(PrivateStandardDTO uWbsPrivateStandard);
+
+    boolean update(List<PrivateStandardDTO> privateStandards);
+
+    boolean deleteFile(Long id);
+
+    boolean updateTypeByTwo(List<PrivateStandardDTO> data, List<Long> delIds, List<Long> delFileIds, MultipartFile[] files);
+
+    Long standardUpdate(Long id);
+}

+ 13 - 0
blade-service/blade-business/src/main/java/org/springblade/business/service/StandardFileService.java

@@ -0,0 +1,13 @@
+package org.springblade.business.service;
+
+import org.springblade.business.entity.StandardFile;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+* @author LHB
+* @description 针对表【u_standard_file(规范文件表)】的数据库操作Service
+* @createDate 2025-06-13 09:24:14
+*/
+public interface StandardFileService extends IService<StandardFile> {
+
+}

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

@@ -0,0 +1,10 @@
+package org.springblade.business.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.springblade.business.entity.StandardInfoJoin;
+
+/**
+ * @author LHB
+ */
+public interface StandardInfoJoinService extends IService<StandardInfoJoin> {
+}

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

@@ -0,0 +1,10 @@
+package org.springblade.business.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.springblade.business.entity.StandardInfoPrivateJoin;
+
+/**
+ * @author LHB
+ */
+public interface StandardInfoPrivateJoinService extends IService<StandardInfoPrivateJoin> {
+}

+ 45 - 0
blade-service/blade-business/src/main/java/org/springblade/business/service/StandardInfoService.java

@@ -0,0 +1,45 @@
+package org.springblade.business.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.springblade.business.dto.StandardInfoDTO;
+import org.springblade.business.dto.StandardInfoPrivateJoinDTO;
+import org.springblade.business.entity.StandardInfo;
+import org.springblade.business.vo.StandardInfoPrivateJoinVO;
+import org.springblade.business.vo.StandardInfoVO;
+import org.springblade.core.mp.support.Query;
+
+import java.util.List;
+
+/**
+ * @author LHB
+ * @description 针对表【u_standard_info(规范参数管理-基础信息)】的数据库操作Service
+ * @createDate 2025-06-11 09:57:39
+ */
+public interface StandardInfoService extends IService<StandardInfo> {
+
+    IPage<StandardInfoDTO> selectMyPage(Query query, StandardInfo standardInfo);
+
+    StandardInfoDTO selectOne(Long id);
+
+    Boolean insert(StandardInfoDTO uStandardInfo);
+
+    Boolean edit(StandardInfoDTO uStandardInfo);
+
+    Boolean delete(Long id);
+
+    Boolean setCondition(List<StandardInfoVO> standardInfoJoins, Long id);
+
+    Boolean setElementJoin(List<StandardInfoPrivateJoinVO> standardInfoPrivateJoins, Long id);
+
+    Boolean deleteConditionSet(Long groupId);
+
+    Boolean deleteElementJoin(Long groupId);
+
+    List<StandardInfoVO> getConditionSet(Long id, Long leftId, Long groupId, Long joinGroupId);
+
+    List<StandardInfoPrivateJoinVO> getElementJoin(Long id, Long leftId, Long groupId, Long joinGroupId);
+
+    List<StandardInfoPrivateJoinVO> effectPreview(String ids);
+
+}

+ 67 - 43
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/EntrustInfoServiceImpl.java

@@ -28,6 +28,7 @@ import org.springblade.business.feign.OperationLogClient;
 import org.springblade.business.mapper.EntrustInfoMapper;
 import org.springblade.business.service.IEntrustInfoService;
 import org.springblade.business.service.IInformationQueryService;
+import org.springblade.business.service.ITrialNumberRuleService;
 import org.springblade.business.vo.EntrustDataInfoVO;
 import org.springblade.business.vo.EntrustInfoVO;
 import org.springblade.business.vo.LoadDataInfoVO;
@@ -68,6 +69,7 @@ public class EntrustInfoServiceImpl extends BaseServiceImpl<EntrustInfoMapper, E
 	private final EntrustInfoMapper entrustInfoMapper;
     private final IInformationQueryService informationQueryService;
 	private final OperationLogClient operationLogClient;
+	private final ITrialNumberRuleService trialNumberRuleService;
 
     @Override
 	public IPage<EntrustInfoVO> selectEntrustInfoPage(IPage<EntrustInfoVO> page, EntrustInfoVO entrustInfo) {
@@ -122,22 +124,22 @@ public class EntrustInfoServiceImpl extends BaseServiceImpl<EntrustInfoMapper, E
 		}
 		String sampleId = "";
 		String contractId = "";
-        String sqlNodeName="select node_name, node_type from m_wbs_tree_private where p_key_id="+dataInfo.getString("nodeId");
+		String sqlNodeName="select node_name, node_type from m_wbs_tree_private where p_key_id="+dataInfo.getString("nodeId");
 		Map<String, Object> wbsTreePrivateMap = jdbcTemplate.queryForMap(sqlNodeName);
 		String nodeName = wbsTreePrivateMap.get("node_name").toString();
 		String nodeType = wbsTreePrivateMap.get("node_type").toString();
-		if(!"51".equals(nodeType) && !nodeName.equals("回弹法检测混凝土抗压强度")&&!nodeName.equals("路基压实度")&&!nodeName.equals("地基承载力")&&!nodeName.equals("路基路面弯沉")&&!nodeName.equals("锚杆")&&!nodeName.equals("喷射混凝土厚度")){
-            // 创建 委托单信息
-            if(!dataInfo.containsKey("sampleId")){
-                return R.fail("取样信息为sampleId不存在");
-            }else{
-                sampleId = dataInfo.getString("sampleId");
-            }
-        }else {
-            if(dataInfo.containsKey("sampleId")){
-                sampleId = dataInfo.getString("sampleId");
-            }
-        }
+		if(!"51".equals(nodeType)){
+			// 创建 委托单信息
+			if(!dataInfo.containsKey("sampleId")){
+				return R.fail("取样信息为sampleId不存在");
+			}else{
+				sampleId = dataInfo.getString("sampleId");
+			}
+		}else {
+			if(dataInfo.containsKey("sampleId")){
+				sampleId = dataInfo.getString("sampleId");
+			}
+		}
 		if(!dataInfo.containsKey("contractId")){
 			return R.fail("取样信息为contractId不存在");
 		}else{
@@ -146,24 +148,26 @@ public class EntrustInfoServiceImpl extends BaseServiceImpl<EntrustInfoMapper, E
 
 		String nodeErTreeId = dataInfo.getString("nodeErTreeId");
 
-        EntrustInfo entrustInfo=new EntrustInfo();
+		EntrustInfo entrustInfo=new EntrustInfo();
 		// 保存数据文件
-        if(!dataInfo.containsKey("sampleId")){
-            entrustInfo.setSampleStatus("0");
-        }else {
-            if(!"51".equals(nodeType) && !nodeName.equals("回弹法检测混凝土抗压强度")&&!nodeName.equals("路基压实度")&&!nodeName.equals("地基承载力")&&!nodeName.equals("路基路面弯沉")&&!nodeName.equals("锚杆")){
-                entrustInfo = baseMapper.selectOne(Wrappers.<EntrustInfo>query().lambda().eq(EntrustInfo::getSampleId, sampleId).eq(EntrustInfo::getContractId,contractId));
-            }else {
-                entrustInfo = baseMapper.selectOne(Wrappers.<EntrustInfo>query().lambda().eq(EntrustInfo::getId,dataInfo.get("id")).eq(EntrustInfo::getContractId,contractId));
-            }
-            if(entrustInfo==null && Func.isEmpty(entrustInfo)){
-                entrustInfo = new EntrustInfo();
-                //委托单未上报不进入样品流转 状态设置为0
-                entrustInfo.setSampleStatus("0");
-            }
-        }
+		if(!dataInfo.containsKey("sampleId")){
+			entrustInfo.setSampleStatus("0");
+		}else {
+			if(!"51".equals(nodeType)){
+				if (sampleId != null && !sampleId.isEmpty() && !"0".equals(sampleId)) {
+					entrustInfo = baseMapper.selectOne(Wrappers.<EntrustInfo>query().lambda().eq(EntrustInfo::getSampleId, sampleId).eq(EntrustInfo::getContractId,contractId));
+				}
+			}else {
+				entrustInfo = baseMapper.selectOne(Wrappers.<EntrustInfo>query().lambda().eq(EntrustInfo::getId,dataInfo.get("id")).eq(EntrustInfo::getContractId,contractId));
+			}
+			if(entrustInfo==null && Func.isEmpty(entrustInfo)){
+				entrustInfo = new EntrustInfo();
+				//委托单未上报不进入样品流转 状态设置为0
+				entrustInfo.setSampleStatus("0");
+			}
+		}
 		//WbsTreePrivate wbsTreePrivate = wbsTreePrivateClient.getNodeByPrimaryKeyId(nodeErTreeId);
-        WbsTreePrivate wbsTreePrivate=jdbcTemplate.query("select * from m_wbs_tree_private where p_key_id="+nodeErTreeId+" and status=1",new BeanPropertyRowMapper<>(WbsTreePrivate.class)).get(0);
+		WbsTreePrivate wbsTreePrivate=jdbcTemplate.query("select * from m_wbs_tree_private where p_key_id="+nodeErTreeId+" and status=1",new BeanPropertyRowMapper<>(WbsTreePrivate.class)).get(0);
 		String sql ="select * from m_wbs_form_element where is_deleted = 0 and dynamic_dict in(500,501,502)  and f_id="+wbsTreePrivate.getInitTableId();
 		List<Map<String, Object>> wbsFormElements = jdbcTemplate.queryForList(sql);
 
@@ -188,23 +192,43 @@ public class EntrustInfoServiceImpl extends BaseServiceImpl<EntrustInfoMapper, E
 				}
 			}
 		}
-        entrustInfo.setNodeId(dataInfo.get("nodeId").toString());
+		entrustInfo.setNodeId(dataInfo.get("nodeId").toString());
 		entrustInfo.setEntrustName(wbsTreePrivate.getNodeName());
-        if(dataInfo.containsKey("id")){
-            entrustInfo.setId(Long.parseLong(dataInfo.get("id").toString()));
-        }
-        this.saveOrUpdate(entrustInfo);
+		if(dataInfo.containsKey("id")){
+			entrustInfo.setId(Long.parseLong(dataInfo.get("id").toString()));
+		}
+		if(!dataInfo.containsKey("id")){
+			boolean b =true;
+			if(StringUtils.isNotEmpty(entrustInfo.getEntrustNo())){
+				trialNumberRuleService.checkTrialNumberIsExist(entrustInfo.getEntrustNo(), 3,Long.parseLong(entrustInfo.getContractId()));
+			}
+			if(!b){
+				throw new ServiceException("委托单编号已存在");
+			}
+		}
+		this.saveOrUpdate(entrustInfo);
+		String autoIncrementNumber=dataInfo.get("autoIncrementNumber")==null?"":dataInfo.get("autoIncrementNumber").toString();
+		String trialAutoNumber=dataInfo.get("trialNumber")==null?"":dataInfo.get("trialNumber").toString();
+		String entrustNo=entrustInfo.getEntrustNo()==null?"":entrustInfo.getEntrustNo();
+		if(StringUtils.isNotEmpty(autoIncrementNumber)){
+			if(trialAutoNumber.equals(entrustNo)){
+				trialNumberRuleService.checkSave(Long.parseLong(entrustInfo.getContractId()), 3, entrustInfo.getId(), autoIncrementNumber);
+			}
+			//bladeRedis.del("trialAutoNumber:" + entrustInfo.getContractId() + ":" + 3 + ":" + entrustInfo.getId() + ":" + "lock:" + autoIncrementNumber);
+		}
 		dataInfo.put("groupId",entrustInfo.getId());
 		dataInfo.put("pkeyId", dataInfo.getString("nodeErTreeId"));
-        if(StringUtils.isEmpty(entrustInfo.getEntrustNo())){
-            entrustInfo.setEntrustNo("");
-        }
-        if(StringUtils.isEmpty(entrustInfo.getEntrustName())){
-            entrustInfo.setEntrustName("");
-        }
-        dataInfo.put("entrustInfoName",entrustInfo.getEntrustNo()+entrustInfo.getEntrustName());
-        String pdfUrl = excelTabClient.saveEntrustTabData(dataInfo);
-        return R.data(200,pdfUrl,"操作成功");
+		if(StringUtils.isEmpty(entrustInfo.getEntrustNo())){
+			entrustInfo.setEntrustNo("");
+		}
+		if(StringUtils.isEmpty(entrustInfo.getEntrustName())){
+			entrustInfo.setEntrustName("");
+		}
+		dataInfo.put("entrustInfoName",entrustInfo.getEntrustNo()+entrustInfo.getEntrustName());
+		dataInfo.remove("autoIncrementNumber");
+		dataInfo.remove("trialNumber");
+		String pdfUrl = excelTabClient.saveEntrustTabData(dataInfo);
+		return R.data(200,pdfUrl,"操作成功");
 	}
 
 	/**

+ 442 - 0
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/PrivateStandardServiceImpl.java

@@ -0,0 +1,442 @@
+package org.springblade.business.service.impl;
+
+import cn.hutool.core.date.DateTime;
+import cn.hutool.core.util.ReflectUtil;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springblade.business.entity.*;
+import org.springblade.business.service.StandardFileService;
+import org.springblade.business.dto.PrivateStandardDTO;
+import org.springblade.business.mapper.StandardInfoJoinMapper;
+import org.springblade.business.mapper.StandardInfoMapper;
+import org.springblade.business.mapper.StandardInfoPrivateJoinMapper;
+import org.springblade.business.service.PrivateStandardService;
+import org.springblade.business.mapper.PrivateStandardMapper;
+import org.springblade.common.utils.SnowFlakeUtil;
+import org.springblade.core.log.exception.ServiceException;
+import org.springblade.core.oss.model.BladeFile;
+import org.springblade.core.secure.BladeUser;
+import org.springblade.core.secure.utils.SecureUtil;
+import org.springblade.core.tool.utils.BeanUtil;
+import org.springblade.resource.feign.NewIOSSClient;
+import org.springframework.mock.web.MockMultipartFile;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.annotation.Resource;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * @author LHB
+ * @description 针对表【u_wbs_private_standard(规范文件夹及规范文件表)】的数据库操作Service实现
+ * @createDate 2025-06-10 10:48:37
+ */
+@Service
+public class PrivateStandardServiceImpl extends ServiceImpl<PrivateStandardMapper, PrivateStandard>
+        implements PrivateStandardService {
+    @Resource
+    private StandardInfoMapper standardInfoMapper;
+    @Resource
+    private StandardInfoJoinMapper standardInfoJoinMapper;
+    @Resource
+    private StandardInfoPrivateJoinMapper standardInfoPrivateJoinMapper;
+
+    @Resource
+    private StandardFileService standardFileService;
+
+    /**
+     * 对象存储构建类
+     */
+    @Resource
+    private NewIOSSClient newIOSSClient;
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean insert(PrivateStandardDTO uWbsPrivateStandard) {
+        BladeUser user = SecureUtil.getUser();
+        uWbsPrivateStandard.setCreateUser(user.getUserId());
+        Boolean isUploadFile = false;
+        if (uWbsPrivateStandard.getType() == 2 && uWbsPrivateStandard.getFiles().length > 0) {
+            isUploadFile = true;
+        }
+
+        //先上传文件,上传成功在执行添加
+        if (isUploadFile) {
+            List<StandardFile> standardFiles = new ArrayList<>();
+            MultipartFile[] files = uWbsPrivateStandard.getFiles();
+
+            try {
+                for (MultipartFile file : files) {
+
+                    StandardFile standardFile = new StandardFile();
+                    standardFile.setId(SnowFlakeUtil.getId());
+                    standardFile.setStandardId(uWbsPrivateStandard.getId());
+                    standardFile.setCreateUser(user.getUserId());
+
+
+                    String originalFilename = file.getOriginalFilename();
+                    standardFile.setFileName(originalFilename);
+
+
+                    originalFilename = "standard/" + uWbsPrivateStandard.getId() + "|" + originalFilename;
+//
+//                    ReflectUtil.setFieldValue(file,"filename",originalFilename);
+
+                    MockMultipartFile multipartFile = new MockMultipartFile("file", originalFilename, "application/pdf", file.getInputStream());
+                    //Oss上传 传特殊文件名 在oss中做特殊路径处理
+                    BladeFile bladeFile = newIOSSClient.uploadFileByInputStream(multipartFile);
+
+                    standardFile.setStandardFileUrl(bladeFile.getLink());
+                    standardFiles.add(standardFile);
+                }
+            } catch (Exception e) {
+                //删除之前上传的文件
+                for (StandardFile standardFile : standardFiles) {
+                    String pdfName = standardFile.getStandardFileUrl().split("upload")[1];
+                    this.newIOSSClient.removeFile("upload" + pdfName);
+                }
+                e.printStackTrace();
+                throw new ServiceException("文件上传失败!请检查Oss");
+            }
+            standardFileService.saveBatch(standardFiles);
+        }
+
+        if (uWbsPrivateStandard.getType() == 2) {
+            //修改之前的规则为过期
+            baseMapper.updateStatus(uWbsPrivateStandard.getParentId());
+        }
+        return baseMapper.insert(uWbsPrivateStandard) > 0;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean update(List<PrivateStandardDTO> privateStandards) {
+        BladeUser user = SecureUtil.getUser();
+
+        List<PrivateStandard> privateStandards1 = new ArrayList<>();
+
+        for (PrivateStandardDTO privateStandard : privateStandards) {
+            PrivateStandard privateStandard1 = BeanUtil.copyProperties(privateStandard, PrivateStandard.class);
+            privateStandards1.add(privateStandard1);
+        }
+
+        this.updateBatchById(privateStandards1);
+
+        return false;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean delete(Long id) {
+
+        try {
+            //获取当前用户
+            BladeUser user = SecureUtil.getUser();
+
+            //删除文件
+            List<StandardFile> list = standardFileService.list(Wrappers.<StandardFile>lambdaQuery()
+                    .eq(StandardFile::getStandardId, id));
+            for (StandardFile standardFile : list) {
+                deleteFile(standardFile.getId());
+            }
+            //更新西悉尼
+            int update = baseMapper.update(null, Wrappers.<PrivateStandard>lambdaUpdate()
+                    .set(PrivateStandard::getIsDeleted, 1)
+                    .set(PrivateStandard::getUpdateUser, user.getUserId())
+                    .eq(PrivateStandard::getId, id)
+                    .or()
+                    .eq(PrivateStandard::getParentId, id)
+            );
+
+            int update1 = standardInfoMapper.update(null, Wrappers.<StandardInfo>lambdaUpdate()
+                    .set(StandardInfo::getIsDeleted, 1)
+                    .set(StandardInfo::getUpdateUser, user.getUserId())
+                    .eq(StandardInfo::getStandardId, id));
+            //TODO 还要删除关联信息
+            standardInfoJoinMapper.updateJoin(user.getUserId(), 1, id);
+            //TODo 还要删除与表单的关联信息
+            standardInfoPrivateJoinMapper.updateJoin(user.getUserId(), 1, id);
+
+            return update > 0;
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new ServiceException("删除失败");
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean deleteFile(Long id) {
+        StandardFile byId = standardFileService.getById(id);
+        if (byId != null) {
+            try {
+                String pdfName = byId.getStandardFileUrl().split("upload")[1];
+                this.newIOSSClient.removeFile("upload" + pdfName);
+            } catch (Exception e) {
+                e.printStackTrace();
+                throw new ServiceException("文件删除失败,Oss异常");
+            }
+            standardFileService.update(Wrappers.<StandardFile>lambdaUpdate()
+                    .set(StandardFile::getIsDeleted, 1)
+                    .set(StandardFile::getUpdateUser, SecureUtil.getUser().getUserId())
+                    .eq(StandardFile::getId, id));
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean updateTypeByTwo(List<PrivateStandardDTO> data,
+                                   List<Long> delIds,
+                                   List<Long> delFileIds,
+                                   MultipartFile[] allFiles) {
+        BladeUser user = SecureUtil.getUser();
+        //先删除文件
+        try {
+            if (CollectionUtils.isNotEmpty(delFileIds)) {
+                List<StandardFile> standardFiles = standardFileService.listByIds(delFileIds);
+                if (CollectionUtils.isNotEmpty(standardFiles)) {
+                    for (StandardFile standardFile : standardFiles) {
+                        this.deleteFile(standardFile.getId());
+                    }
+                }
+            }
+            //删除规范文件
+            if (CollectionUtils.isNotEmpty(delIds)) {
+                for (Long delId : delIds) {
+                    delete(delId);
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new ServiceException("Oss删除文件失败");
+        }
+        //文件集合
+        List<StandardFile> standardFiles = new ArrayList<>();
+        try {
+            //空文件曲中
+            List<MultipartFile> files = new ArrayList<>();
+            for (MultipartFile allFile : allFiles) {
+                if (allFile != null) {
+                    files.add(allFile);
+                }
+            }
+
+            // 文件索引计数器
+            int fileIndex = 0;
+            for (PrivateStandardDTO dto : data) {
+                // 获取当前对象需要的文件数量
+                int fileCount = dto.getFilesCount();
+                if (files != null && files.size() > 0) {
+                    if (fileCount > 0 && fileIndex < files.size()) {
+                        dto.setFile(files.get(fileIndex++));
+                    }
+                    //先上传文件,上传成功在执行添加
+                    if (dto.getFile() != null) {
+                        //再去查询当前规范文件是否在数据库中存在未删除的文件
+                        List<StandardFile> list = standardFileService.list(Wrappers.<StandardFile>lambdaQuery()
+                                .eq(StandardFile::getStandardId, dto.getId())
+                                .eq(StandardFile::getIsDeleted, 0));
+                        if (CollectionUtils.isNotEmpty(list)) {
+                            //删除文件
+                            for (StandardFile standardFile : list) {
+                                String pdfName = standardFile.getStandardFileUrl().split("upload")[1];
+                                this.newIOSSClient.removeFile("upload" + pdfName);
+                                standardFile.setIsDeleted(1);
+                            }
+                            standardFileService.saveOrUpdateBatch(list);
+                        }
+                        MultipartFile file = dto.getFile();
+                        StandardFile standardFile = new StandardFile();
+                        standardFile.setId(SnowFlakeUtil.getId());
+                        standardFile.setStandardId(dto.getId());
+                        standardFile.setCreateUser(user.getUserId());
+                        String originalFilename = file.getOriginalFilename();
+                        standardFile.setFileName(originalFilename);
+                        originalFilename = "standard/" + dto.getId() + "|" + originalFilename;
+                        MockMultipartFile multipartFile = new MockMultipartFile("file", originalFilename, "application/pdf", file.getInputStream());
+
+                        //Oss上传 传特殊文件名 在oss中做特殊路径处理
+                        BladeFile bladeFile = newIOSSClient.uploadFileByInputStream(multipartFile);
+                        if (bladeFile == null) {
+                            throw new ServiceException("Oss异常");
+                        }
+                        standardFile.setStandardFileUrl(bladeFile.getLink());
+                        //添加新文件
+                        standardFileService.save(standardFile);
+                    }
+                }
+
+
+                //创建数据
+                PrivateStandard privateStandard = BeanUtil.copyProperties(dto, PrivateStandard.class);
+                //修改
+                baseMapper.updateById(privateStandard);
+            }
+            return true;
+        } catch (Exception e) {
+            //删除之前上传的文件
+            if (CollectionUtils.isNotEmpty(standardFiles)) {
+                for (StandardFile standardFile : standardFiles) {
+                    String pdfName = standardFile.getStandardFileUrl().split("upload")[1];
+                    this.newIOSSClient.removeFile("upload" + pdfName);
+                }
+                throw new ServiceException("Oss异常");
+            }
+            e.printStackTrace();
+            throw new ServiceException("更新失败");
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Long standardUpdate(Long id) {
+        BladeUser user = SecureUtil.getUser();
+        //获取当前规范文件信息
+        PrivateStandard privateStandard = baseMapper.selectById(id);
+        if(privateStandard == null){
+            throw new ServiceException("未查询到规范文件");
+        }
+
+        //获取信息
+        List<StandardInfo> standardInfos = standardInfoMapper.selectList(Wrappers.<StandardInfo>lambdaQuery()
+                .eq(StandardInfo::getStandardId, id)
+                .eq(StandardInfo::getIsDeleted, 0));
+
+        List<Long> infoIds = null;
+        if (CollectionUtils.isNotEmpty(standardInfos)) {
+            infoIds = standardInfos.stream().filter(f -> f.getType() == 2).map(StandardInfo::getId).collect(Collectors.toList());
+        }
+
+        List<StandardInfoJoin> standardInfoJoins = null;
+        List<StandardInfoPrivateJoin> standardInfoPrivateJoins = null;
+        if (CollectionUtils.isNotEmpty(infoIds)) {
+            //获取绑定信息
+            standardInfoJoins = standardInfoJoinMapper.selectList(Wrappers.<StandardInfoJoin>lambdaQuery()
+                    .in(StandardInfoJoin::getStandardInfoLeftId, infoIds));
+
+            //获取绑定表单信息
+            standardInfoPrivateJoins = standardInfoPrivateJoinMapper.selectList(Wrappers.<StandardInfoPrivateJoin>lambdaQuery()
+                    .in(StandardInfoPrivateJoin::getStandardInfoId, infoIds));
+        }
+        //获取文件信息
+        List<StandardFile> standardFiles = standardFileService.list(Wrappers.<StandardFile>lambdaQuery()
+                .eq(StandardFile::getStandardId, id)
+                .eq(StandardFile::getIsDeleted, 0));
+
+
+        //复制数据
+
+        //新规范文件id
+        Long newId = SnowFlakeUtil.getId();
+
+        privateStandard.setId(newId);
+        if (privateStandard.getStatus() == 2) {
+            privateStandard.setName(privateStandard.getName().replace("-已过期", ""));
+            privateStandard.setStatus(1);
+        }
+        privateStandard.setCreateTime(LocalDateTime.now());
+        privateStandard.setCreateUser(user.getUserId());
+
+        try {
+            //修改之前的规则为过期
+            baseMapper.updateStatus(privateStandard.getParentId());
+
+            baseMapper.insert(privateStandard);
+
+            if(CollectionUtils.isNotEmpty(standardInfos)){
+                //旧id与新id的映射关系
+                Map<Long, Long> map = new HashMap<>();
+                standardInfos.forEach(f -> {
+                    Long newInfoId = SnowFlakeUtil.getId();
+                    map.put(f.getId(), newInfoId);
+                });
+                standardInfos.forEach(f -> {
+                    f.setId(map.get(f.getId()));
+                    f.setParentId(map.get(f.getParentId()) == null ? 0 : map.get(f.getParentId()));
+                    f.setStandardId(newId);
+                    f.setCreateTime(DateTime.now());
+                    f.setCreateUser(user.getUserId());
+                    standardInfoMapper.insert(f);
+                });
+                if(CollectionUtils.isNotEmpty(standardInfoJoins)){
+                    standardInfoJoins.forEach(f -> {
+                        f.setId(SnowFlakeUtil.getId());
+                        f.setStandardInfoLeftId(map.get(f.getStandardInfoLeftId()));
+                        f.setStandardInfoRightId(map.get(f.getStandardInfoRightId()));
+                        f.setCreateTime(DateTime.now());
+                        f.setCreateUser(user.getUserId());
+                        standardInfoJoinMapper.insert(f);
+                    });
+                }
+                if(CollectionUtils.isNotEmpty(standardInfoPrivateJoins)){
+                    standardInfoPrivateJoins.forEach(f -> {
+                        f.setId(SnowFlakeUtil.getId());
+                        f.setStandardInfoId(map.get(f.getStandardInfoId()));
+                        f.setCreateTime(DateTime.now());
+                        f.setCreateUser(user.getUserId());
+                        standardInfoPrivateJoinMapper.insert(f);
+                    });
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new ServiceException("复制失败");
+        }
+
+
+
+        if(CollectionUtils.isNotEmpty(standardFiles)){
+            //文件集合
+            List<String> urls = new ArrayList<>();
+            try {
+                for (StandardFile f : standardFiles) {
+                    f.setId(SnowFlakeUtil.getId());
+                    f.setStandardId(newId);
+                    f.setCreateTime(DateTime.now());
+                    f.setCreateUser(user.getUserId());
+                    if (StringUtils.isNotEmpty(f.getStandardFileUrl())) {
+                        URL urlFile = new URL(f.getStandardFileUrl());
+                        InputStream inputStream = urlFile.openStream();
+                        String originalFilename = "standard/" + f.getId() + "|" + f.getFileName();
+                        MockMultipartFile multipartFile = new MockMultipartFile("file", originalFilename, "application/pdf", inputStream);
+                        //Oss上传 传特殊文件名 在oss中做特殊路径处理
+                        BladeFile bladeFile = newIOSSClient.uploadFileByInputStream(multipartFile);
+                        if (bladeFile == null) {
+                            throw new ServiceException("Oss异常");
+                        }
+                        f.setStandardFileUrl(bladeFile.getLink());
+                        urls.add(bladeFile.getLink());
+                    }
+                }
+            } catch (Exception e) {
+                for (String url : urls) {
+                    String pdfName = url.split("upload")[1];
+                    this.newIOSSClient.removeFile("upload" + pdfName);
+                }
+                e.printStackTrace();
+                throw new ServiceException("Oss异常");
+            }
+            standardFileService.saveBatch(standardFiles);
+        }
+        return newId;
+    }
+}
+
+
+
+

+ 22 - 0
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/StandardFileServiceImpl.java

@@ -0,0 +1,22 @@
+package org.springblade.business.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springblade.business.entity.StandardFile;
+import org.springblade.business.service.StandardFileService;
+import org.springblade.business.mapper.StandardFileMapper;
+import org.springframework.stereotype.Service;
+
+/**
+* @author LHB
+* @description 针对表【u_standard_file(规范文件表)】的数据库操作Service实现
+* @createDate 2025-06-13 09:24:14
+*/
+@Service
+public class StandardFileServiceImpl extends ServiceImpl<StandardFileMapper, StandardFile>
+    implements StandardFileService {
+
+}
+
+
+
+

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

@@ -0,0 +1,14 @@
+package org.springblade.business.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springblade.business.entity.StandardInfoJoin;
+import org.springblade.business.mapper.StandardInfoJoinMapper;
+import org.springblade.business.service.StandardInfoJoinService;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author LHB
+ */
+@Service
+public class StandardInfoJoinServiceImpl extends ServiceImpl<StandardInfoJoinMapper, StandardInfoJoin> implements StandardInfoJoinService {
+}

+ 45 - 0
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TrialAutoNumberServiceImpl.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.business.service.impl;
+
+import org.springblade.business.entity.TrialAutoNumber;
+import org.springblade.business.vo.TrialAutoNumberVO;
+import org.springblade.business.mapper.TrialAutoNumberMapper;
+import org.springblade.business.service.ITrialAutoNumberService;
+import org.springblade.core.mp.base.BaseServiceImpl;
+import org.springframework.stereotype.Service;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+
+/**
+ *  服务实现类
+ *
+ * @author BladeX
+ * @since 2025-06-10
+ */
+@Service
+public class TrialAutoNumberServiceImpl extends BaseServiceImpl<TrialAutoNumberMapper, TrialAutoNumber> implements ITrialAutoNumberService {
+
+	@Override
+	public IPage<TrialAutoNumberVO> selectTrialAutoNumberPage(IPage<TrialAutoNumberVO> page, TrialAutoNumberVO trialAutoNumber) {
+		return page.setRecords(baseMapper.selectTrialAutoNumberPage(page, trialAutoNumber));
+	}
+
+    public void clearTrialAutoNumber(Long nameRuleId){
+        baseMapper.clearTrialAutoNumber(nameRuleId);
+    }
+
+}

+ 19 - 2
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TrialMaterialMobilizationServiceImpl.java

@@ -22,6 +22,7 @@ import org.springblade.business.mapper.TrialMaterialMobilizationMapper;
 import org.springblade.business.mapper.TrialSampleInfoMapper;
 import org.springblade.business.mapper.TrialSamplingRecordMapper;
 import org.springblade.business.service.ITrialMaterialMobilizationService;
+import org.springblade.business.service.ITrialNumberRuleService;
 import org.springblade.business.utils.PDFUtil;
 import org.springblade.business.vo.TrialMaterialMobilizationVO;
 import org.springblade.business.vo.TrialSamplingRecordVO;
@@ -68,6 +69,7 @@ public class TrialMaterialMobilizationServiceImpl extends BaseServiceImpl<TrialM
     private final NewIOSSClient newIOSSClient;
     private final JdbcTemplate jdbcTemplate;
     private final CommonFileClient commonFileClient;
+    private final ITrialNumberRuleService trialNumberRuleService;
 
     @Override
     public boolean mobilizationVerification(String number, String id, String contractId) {
@@ -88,12 +90,27 @@ public class TrialMaterialMobilizationServiceImpl extends BaseServiceImpl<TrialM
     }
 
     @Override
-    public boolean mobilizationSubmit(TrialMaterialMobilization obj) {
+    public boolean mobilizationSubmit(TrialMaterialMobilizationDTO obj) {
         if (ObjectUtil.isEmpty(SecureUtil.getUserId())) {
             throw new ServiceException("获取用户信息失败");
         }
+        boolean b=true;
+        if(StringUtils.isNotEmpty(obj.getMaterialNumber())){
+            b= trialNumberRuleService.checkTrialNumberIsExist(obj.getMaterialNumber(), 1,obj.getContractId());
+        }
+        if(!b){
+            throw new ServiceException("编号已存在");
+        }
         obj.setUserId(SecureUtil.getUserId());
-        return this.saveOrUpdate(obj);
+        this.saveOrUpdate(obj);
+        if(StringUtils.isNotEmpty(obj.getAutoIncrementNumber())){
+            if(obj.getTrialNumber().equals(obj.getMaterialNumber())){
+                trialNumberRuleService.checkSave(obj.getContractId(), 1, obj.getId(), obj.getAutoIncrementNumber());
+            }
+            //bladeRedis.del("trialAutoNumber:" + obj.getContractId() + ":" + 1 + ":" + obj.getId() + ":" + "lock:" + obj.getAutoIncrementNumber());
+        }
+
+        return true;
     }
 
     @Override

+ 455 - 0
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TrialNumberRuleServiceImpl.java

@@ -0,0 +1,455 @@
+/*
+ *      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.business.service.impl;
+
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+import org.jsoup.select.Elements;
+import org.springblade.business.entity.TrialAutoNumber;
+import org.springblade.business.entity.TrialNumberRule;
+import org.springblade.business.vo.TrialNumberRuleVO;
+import org.springblade.business.mapper.TrialNumberRuleMapper;
+import org.springblade.business.service.ITrialNumberRuleService;
+import org.springblade.business.vo.TrialNumberRuleVO1;
+import org.springblade.common.constant.CommonConstant;
+import org.springblade.common.utils.CommonUtil;
+import org.springblade.common.utils.SnowFlakeUtil;
+import org.springblade.core.log.exception.ServiceException;
+import org.springblade.core.mp.base.BaseServiceImpl;
+import org.springblade.core.redis.cache.BladeRedis;
+import org.springblade.core.secure.BladeUser;
+import org.springblade.core.tool.api.R;
+import org.springblade.core.tool.utils.IoUtil;
+import org.springblade.core.tool.utils.ResourceUtil;
+import org.springblade.manager.entity.ContractInfo;
+import org.springblade.manager.entity.WbsTreePrivate;
+import org.springblade.manager.feign.WbsTreePrivateClient;
+import org.springblade.system.cache.ParamCache;
+import org.springframework.jdbc.core.BeanPropertyRowMapper;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.core.SingleColumnRowMapper;
+import org.springframework.stereotype.Service;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+
+import javax.annotation.Resource;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.time.LocalDate;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ *  服务实现类
+ *
+ * @author BladeX
+ * @since 2025-06-10
+ */
+@Service
+public class TrialNumberRuleServiceImpl extends BaseServiceImpl<TrialNumberRuleMapper, TrialNumberRule> implements ITrialNumberRuleService {
+
+    @Resource
+    private JdbcTemplate jdbcTemplate;
+    @Resource
+    private BladeRedis bladeRedis;
+    @Resource
+    private  TrialAutoNumberServiceImpl trialAutoNumberService;
+
+
+    @Override
+	public IPage<TrialNumberRuleVO> selectTrialNumberRulePage(IPage<TrialNumberRuleVO> page, TrialNumberRuleVO trialNumberRule) {
+		return page.setRecords(baseMapper.selectTrialNumberRulePage(page, trialNumberRule));
+	}
+
+    @Override
+    public Map<String,String> getTrialNumber(Long projectId,Long contractId, Integer type,Long nodeId,Boolean isSaveRedis) {
+        HashMap<String, String> map = new HashMap<>();
+        StringBuilder trialNumber = new StringBuilder();
+        List<TrialNumberRule> rules;
+        if(contractId==null||contractId==0L){
+            rules = baseMapper.selectList(Wrappers.<TrialNumberRule>query().lambda().eq(TrialNumberRule::getProjectId, projectId).eq(TrialNumberRule::getType, type).eq(TrialNumberRule::getStatus,1).orderByAsc(TrialNumberRule::getSort));
+        }else {
+             rules = baseMapper.selectList(Wrappers.<TrialNumberRule>query().lambda().eq(TrialNumberRule::getContractId, contractId).eq(TrialNumberRule::getType, type).eq(TrialNumberRule::getStatus,2).orderByAsc(TrialNumberRule::getSort));
+        }
+        boolean flag=true;
+        int i=1;
+        do {
+            for (TrialNumberRule rule : rules) {
+                if(rule.getRule()==1){
+                    trialNumber.append(rule.getData());
+                } else if (rule.getRule()==2) {
+                    if(contractId!=null&&contractId!=0L){
+                        String sql1="select contract_number from m_contract_info where id="+contractId;
+                        String result = jdbcTemplate.query(sql1, rs -> {
+                            if (rs.next()) {
+                                return rs.getString(1);
+                            } else {
+                                return "";
+                            }
+                        });
+                        trialNumber.append(result==null?"":result);
+                    }else {
+                        trialNumber.append("TJ01");
+                    }
+                } else if (rule.getRule()==3) {
+                    if (nodeId!=null) {
+                        String sql2="select unique_code from m_wbs_tree_private where p_key_id="+nodeId+" and is_deleted=0";
+                        String  result = jdbcTemplate.query(sql2, rs -> {
+                            if (rs.next()) {
+                                return rs.getString(1);
+                            } else {
+                                return "";
+                            }
+                        });
+                        trialNumber.append(result==null?"":result);
+                    }else {
+                        trialNumber.append("SNY");
+                    }
+                } else if (rule.getRule()==4) {
+                    String currentYearStr = String.valueOf(LocalDate.now().getYear());
+                    trialNumber.append(currentYearStr);
+                } else if (rule.getRule()==5) {
+                    int currentMonthValue = LocalDate.now().getMonthValue();
+                    String currentMonthStr = String.format("%02d", currentMonthValue);
+                    trialNumber.append(currentMonthStr);
+                } else if (rule.getRule()==6) {
+                    if(StringUtils.isEmpty(rule.getData())){
+                        trialNumber.append("");
+                        map.put("autoIncrementNumber","");
+                        continue;
+                    }
+                    if(!isSaveRedis){
+                        trialNumber.append(rule.getData());
+                        map.put("autoIncrementNumber",rule.getData());
+                    }
+                    if(rule.getIsAutoIncrement()!=null&&rule.getIsAutoIncrement()==1){
+                        String autoIncrementNumber="";
+                        //如果是需要自增的 先要查出当前数据库中自增编号的最大值
+                        String sql3 = "SELECT auto_increment_number FROM u_trial_auto_number where type="+type+" and contract_id="+contractId+" and is_deleted=0 ORDER BY auto_increment_number DESC LIMIT 1";
+                        String maxNumber = jdbcTemplate.query(sql3, rs -> {
+                            if (rs.next()) {
+                                return rs.getObject(1, String.class);
+                            } else {
+                                return null;
+                            }
+                        });
+                        if(StringUtils.isEmpty(maxNumber)){
+                            autoIncrementNumber=rule.getData();
+                        }else {
+                            autoIncrementNumber=incrementFormattedNumberWithCheck(maxNumber,i);
+                        }
+//
+//                    String sql4="select auto_increment_number FROM u_trial_auto_number where type="+type+" and contract_id="+contractId+" and is_deleted=0  ORDER BY auto_increment_number ASC";
+//                    List<String> autoNumbers = jdbcTemplate.query(sql4, new SingleColumnRowMapper<>(String.class));
+//                    //判断自增的流水号是否是连续的 是连续的就在最大值加1,不是连续的先使用缺失的编号
+//                    List<String> missingNumbers = findMissingNumberPatterns(autoNumbers);
+//                    if(missingNumbers.isEmpty()){
+//                        while (true){
+//                            maxNumber=incrementFormattedNumberWithCheck(maxNumber);
+//                            Object o = bladeRedis.get("trialAutoNumber:" + contractId + ":" + type + ":" + nodeId + ":" + "lock:" + maxNumber);
+//                            if(o==null){
+//                                break;
+//                            }
+//                        }
+//                        autoIncrementNumber=maxNumber;
+//                    }else {
+//                        for (int i = 0; i < missingNumbers.size(); i++) {
+//                            autoIncrementNumber=missingNumbers.get(i);
+//                            Object o = bladeRedis.get("trialAutoNumber:" + contractId + ":" + type + ":" + nodeId + ":" + "lock:" + autoIncrementNumber);
+//                            if(o==null){
+//                                break;
+//                            }
+//                            autoIncrementNumber="";
+//                        }
+//                        if(autoIncrementNumber.equals("")){
+//                            while (true){
+//                                maxNumber=incrementFormattedNumberWithCheck(maxNumber);
+//                                Object o = bladeRedis.get("trialAutoNumber:" + contractId + ":" + type + ":" + nodeId + ":" + "lock:" + maxNumber);
+//                                if(o==null){
+//                                    break;
+//                                }
+//                            }
+//                            autoIncrementNumber=String.valueOf(maxNumber);
+//                        }
+//                    }
+//                      if (isSaveRedis) {
+//                        bladeRedis.setEx("trialAutoNumber:" + contractId + ":" + type + ":" + nodeId + ":" + "lock:" + autoIncrementNumber , autoIncrementNumber,10 * 60 * 1000L);
+//                      }
+                        map.put("autoIncrementNumber",autoIncrementNumber);
+                        trialNumber.append(autoIncrementNumber);
+                    }
+                    else {
+                        map.put("autoIncrementNumber","");
+                        trialNumber.append(rule.getData());
+                    }
+                }
+            }
+            if(isSaveRedis){
+                flag=checkTrialNumberIsExist(trialNumber.toString(),type,contractId);
+                i++;
+                if(!flag){
+                    trialNumber.setLength(0);
+                }
+            }
+        }while (!flag);
+        map.put("trialNumber",trialNumber.toString());
+        return map;
+    }
+
+    public String incrementFormattedNumberWithCheck(String data,int i) {
+        if (data == null || data.isEmpty()) {
+            return "0";
+        }
+
+        int length = data.length();
+        int number = Integer.parseInt(data);
+        number += i;
+
+        // 检查自增后的数字位数是否超过原始数据的长度
+        if (String.valueOf(number).length() > length) {
+            throw new ServiceException("自增后的编号超出原始格式位数限制:" + data);
+        }
+
+        return String.format("%0" + length + "d", number);
+    }
+
+    public List<String> findMissingNumberPatterns(List<String> autoNumbersStr) {
+        if (autoNumbersStr == null || autoNumbersStr.size() <= 1) {
+            return Collections.emptyList();
+        }
+
+        // 提取数字和最大长度
+        List<Long> numbers = new ArrayList<>();
+        int maxLength = 0;
+
+        for (String s : autoNumbersStr) {
+            try {
+                Long num = Long.parseLong(s);
+                numbers.add(num);
+                maxLength = Math.max(maxLength, s.length());
+            } catch (NumberFormatException ignored) {
+            }
+        }
+
+        if (numbers.size() <= 1) {
+            return Collections.emptyList();
+        }
+
+        // 排序
+        numbers.sort(Long::compareTo);
+
+        long start = numbers.get(0);
+        long end = numbers.get(numbers.size() - 1);
+        Set<Long> numberSet = new HashSet<>(numbers);
+
+        List<String> missing = new ArrayList<>();
+
+        for (long i = start; i <= end; i++) {
+            if (!numberSet.contains(i)) {
+                // 使用原始最长字符串的长度进行格式化
+                String formatted = String.format("%0" + maxLength + "d", i);
+                missing.add(formatted);
+            }
+        }
+
+        return missing;
+    }
+    @Override
+    public boolean checkTrialNumberIsExist(String trialNumber,Integer type,Long contractId){
+        String tableName="";
+        String number="";
+        if(type==1){
+            tableName="u_trial_material_mobilization";
+            number="material_number";
+        }
+        if(type==2){
+            tableName="u_trial_sample_info";
+            number="specification_number";
+        }
+        if(type==3){
+            tableName="u_entrust_info";
+            number="entrust_no";
+        }
+        if(type==4){
+            tableName="u_trial_self_inspection_record";
+            number="record_no";
+        }
+        if(type==5){
+            tableName="u_trial_self_inspection_record";
+            number="report_no";
+        }
+        String sql="select count(id) from "+tableName+" where "+number+" = '"+trialNumber+"' and is_deleted=0 and contract_id="+contractId;
+        System.out.println(sql);
+        Integer count = jdbcTemplate.queryForObject(sql, Integer.class);
+        if(count==0){
+            return true;
+        }else {
+            return false;
+        }
+    }
+
+    @Override
+    public TrialNumberRuleVO1 getTrialNumberRule(Long projectId,Long contractId, Integer type) {
+        TrialNumberRuleVO1 vo1 = new TrialNumberRuleVO1();
+        List<TrialNumberRule> trialNumberRules;
+        if(contractId==0L){
+            trialNumberRules = baseMapper.selectList(Wrappers.<TrialNumberRule>query().lambda().eq(TrialNumberRule::getProjectId, projectId).eq(TrialNumberRule::getType, type).eq(TrialNumberRule::getStatus,1).orderByAsc(TrialNumberRule::getSort));
+        }else {
+            trialNumberRules = baseMapper.selectList(Wrappers.<TrialNumberRule>query().lambda().eq(TrialNumberRule::getContractId, contractId).eq(TrialNumberRule::getType, type).eq(TrialNumberRule::getStatus,2).orderByAsc(TrialNumberRule::getSort));
+        }
+        if(trialNumberRules.size()>0){
+            for (TrialNumberRule rule : trialNumberRules) {
+                if(rule.getRule()==2){
+                    if(rule.getContractId()==null||rule.getContractId()==0L){
+                        rule.setData("TJ01");
+                    }else {
+                        String sql1="select contract_number from m_contract_info where id="+contractId;
+                        String result = jdbcTemplate.query(sql1, rs -> {
+                            if (rs.next()) {
+                                return rs.getString(1);
+                            } else {
+                                return "";
+                            }
+                        });
+                        rule.setData(result);
+                    }
+                } else if (rule.getRule()==3) {
+                    rule.setData("SNY");
+                } else if (rule.getRule()==4) {
+                    String currentYearStr = String.valueOf(LocalDate.now().getYear());
+                    rule.setData(currentYearStr);
+                } else if (rule.getRule()==5) {
+                    int currentMonthValue = LocalDate.now().getMonthValue();
+                    String currentMonthStr = String.format("%02d", currentMonthValue);
+                    rule.setData(currentMonthStr);
+                }
+            }
+        }
+        if(trialNumberRules!=null){
+            Map<String, String> map = getTrialNumber(projectId,contractId, type, null, false);
+            vo1.setList(trialNumberRules);
+            vo1.setTrialNumber(map.get("trialNumber"));
+            return vo1;
+        }
+        return null;
+    }
+
+    /**
+     * type 1材料 2样品 3委托单 4记录表 5报告表
+     * @param projectId
+     * @param contractId
+     * @param type
+     * @return
+     */
+    @Override
+    public boolean clearTrialNumber(Long projectId, Long contractId, Integer type) {
+        if(contractId!=null&&contractId!=0L){
+//            String update;
+//            if(type==1){
+//                update="update u_trial_material_mobilization set material_number = NULL where contract_id="+contractId;
+//            } else if (type==2) {
+//                update="update u_trial_sample_info set specification_number = NULL where contract_id="+contractId;
+//            } else if (type==3) {
+//                update="update u_entrust_info set entrust_no = NULL where contract_id="+contractId+" and status=1";
+//            } else if (type==4) {
+//                update="update u_trial_self_inspection_record set record_no = NULL where contract_id="+contractId+" and task_status='未上报'";
+//            }else{
+//                update="update u_trial_self_inspection_record set report_no = NULL where contract_id="+contractId+" and task_status='未上报'";
+//            }
+//            jdbcTemplate.execute(update);
+            List<TrialNumberRule> trialNumberRules;
+            trialNumberRules = baseMapper.selectList(Wrappers.<TrialNumberRule>query().lambda().eq(TrialNumberRule::getContractId, contractId).eq(TrialNumberRule::getType, type).eq(TrialNumberRule::getStatus,2).orderByAsc(TrialNumberRule::getSort));
+            if(!trialNumberRules.isEmpty()){
+                boolean b = trialNumberRules.stream().anyMatch(t -> t.getRule() == 6);
+                if(b){
+                    String sql="update u_trial_auto_number set is_deleted=1 where contract_id="+contractId+" and type="+ type;
+                    jdbcTemplate.update(sql);
+                }
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public Map<String, String> getEntrustNumber(Long pkeyId,Long contractId) throws FileNotFoundException {
+        final Long nodeId=pkeyId;
+        // 合同段信息
+        String sql="select * from m_contract_info where id="+contractId;
+        ContractInfo contractInfo =jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<>(ContractInfo.class));
+        String sql1="select * from m_wbs_tree_private where p_key_id="+pkeyId;
+        // 节点数
+        WbsTreePrivate treePrivate = jdbcTemplate.queryForObject(sql1,new BeanPropertyRowMapper<>(WbsTreePrivate.class));
+        if (contractInfo == null) {
+            throw new ServiceException("合同段信息为null");
+        }
+        if (contractInfo.getContractType() == 2) { //3 监理
+            pkeyId = treePrivate.getJlerTreeId();
+        } else if (contractInfo.getContractType() == 3 || contractInfo.getContractType() == 8) { //业主
+            pkeyId = treePrivate.getYzerTreeId();
+        }else {
+            return null;
+        }
+        String sql2="select * from m_wbs_tree_private where p_key_id="+pkeyId;
+        WbsTreePrivate wbsTreePrivate1 = jdbcTemplate.queryForObject(sql2, new BeanPropertyRowMapper<>(WbsTreePrivate.class));
+        String fileUrl = wbsTreePrivate1.getHtmlUrl();
+        String file_path = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
+        String sys_file_net_url = ParamCache.getValue(CommonConstant.SYS_FILE_NET_URL);
+        File file1 = ResourceUtil.getFile(fileUrl);
+        InputStream fileInputStream;
+        if (file1.exists()) {
+            fileInputStream = new FileInputStream(file1);
+        } else {
+            String path = sys_file_net_url + fileUrl.replaceAll("//", "/").replaceAll(file_path, "");
+            fileInputStream = CommonUtil.getOSSInputStream(path);
+        }
+        String htmlString = IoUtil.readToString(fileInputStream);
+        Document doc = Jsoup.parse(htmlString);
+        Elements elementsWithPlaceholderxx = doc.select("el-input[placeholder*=委托单编号]");
+        if(!elementsWithPlaceholderxx.isEmpty()){
+            Element first = elementsWithPlaceholderxx.first();
+            String key = first.attr("id");
+            Map<String, String> map = getTrialNumber(Long.valueOf(wbsTreePrivate1.getProjectId()),contractId, 3, nodeId, true);
+            map.put(key,map.get("trialNumber"));
+            return map;
+        }
+        return null;
+    }
+    public void checkSave(Long contractId,int type,Long formDataId,String autoNumber){
+        List<TrialNumberRule> list = baseMapper.selectList(Wrappers.<TrialNumberRule>query().lambda().eq(TrialNumberRule::getContractId, contractId).eq(TrialNumberRule::getType, type).eq(TrialNumberRule::getStatus,2).orderByAsc(TrialNumberRule::getSort));
+            if(list!=null&&list.size()>0){
+                List<TrialNumberRule> collect = list.stream().filter(o -> o.getRule() == 6 && o.getIsAutoIncrement() == 1).collect(Collectors.toList());
+                if(!collect.isEmpty()){
+                    TrialAutoNumber one = trialAutoNumberService.getOne(Wrappers.lambdaQuery(TrialAutoNumber.class).eq(TrialAutoNumber::getFormDataId, formDataId).eq(TrialAutoNumber::getType, type));
+                    if(one==null){
+                        TrialAutoNumber trialAutoNumber = new TrialAutoNumber();
+                        trialAutoNumber.setId(SnowFlakeUtil.getId());
+                        trialAutoNumber.setContractId(contractId);
+                        trialAutoNumber.setType(type);
+                        trialAutoNumber.setNumberRuleId(collect.get(0).getId());
+                        trialAutoNumber.setFormDataId(formDataId);
+                        trialAutoNumber.setAutoIncrementNumber(autoNumber);
+                        trialAutoNumberService.save(trialAutoNumber);
+                    }
+                }
+            }
+    }
+
+}

+ 18 - 4
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TrialSampleInfoServiceImpl.java

@@ -23,6 +23,7 @@ import org.springblade.business.excel.TrialSampleInfoExcel;
 import org.springblade.business.mapper.TrialSampleInfoMapper;
 import org.springblade.business.mapper.TrialSamplingRecordMapper;
 import org.springblade.business.service.IEntrustInfoService;
+import org.springblade.business.service.ITrialNumberRuleService;
 import org.springblade.business.service.ITrialSampleInfoService;
 import org.springblade.business.utils.PDFUtil;
 import org.springblade.business.utils.StringSPUtils;
@@ -65,6 +66,7 @@ public class TrialSampleInfoServiceImpl extends BaseServiceImpl<TrialSampleInfoM
     private final TrialSamplingRecordMapper trialSamplingRecordMapper;
     private final JdbcTemplate jdbcTemplate;
     private final IEntrustInfoService entrustInfoService;
+    private final ITrialNumberRuleService trialNumberRuleService;
 
     @Override
     public boolean sampleVerification(String specificationNumber, String id, String contractId, String nodeId) {
@@ -133,10 +135,9 @@ public class TrialSampleInfoServiceImpl extends BaseServiceImpl<TrialSampleInfoM
     @Override
     public boolean sampleSubmit(TrialSampleInfoDTO obj) {
         //如果样品编号为空,那么就自动生成
-        if (ObjectUtil.isEmpty(obj.getSpecificationNumber())) {
-            this.buildNumber(obj);
-        }
-
+//        if (ObjectUtil.isEmpty(obj.getSpecificationNumber())) {
+//            this.buildNumber(obj);
+//        }
         TrialSampleInfo trialSampleInfo = BeanUtil.copyProperties(obj, TrialSampleInfo.class);
         if (trialSampleInfo != null) {
             if (ObjectUtils.isEmpty(trialSampleInfo.getMaterialCount())) {
@@ -145,7 +146,20 @@ public class TrialSampleInfoServiceImpl extends BaseServiceImpl<TrialSampleInfoM
             if (ObjectUtils.isEmpty(trialSampleInfo.getRepresentativeCount())) {
                 trialSampleInfo.setRepresentativeCount("0");
             }
+            boolean b =true;
+            if(StringUtils.isNotEmpty(obj.getSpecificationNumber())){
+                trialNumberRuleService.checkTrialNumberIsExist(obj.getSpecificationNumber(), 2,obj.getContractId());
+            }
+            if(!b){
+                throw new ServiceException("样品编号已存在");
+            }
             this.saveOrUpdate(trialSampleInfo);
+            if(StringUtils.isNotEmpty(obj.getAutoIncrementNumber())){
+                if(obj.getTrialNumber().equals(obj.getSpecificationNumber())){
+                    trialNumberRuleService.checkSave(obj.getContractId(), 2, obj.getId(), obj.getAutoIncrementNumber());
+                }
+                //bladeRedis.del("trialAutoNumber:" + obj.getContractId() + ":" + 2 + ":" + obj.getId() + ":" + "lock:" + obj.getAutoIncrementNumber());
+            }
 
             if (trialSampleInfo.getId() != null && obj.getMobilizationId() != null && obj.getMobilizationId() != -1) {
                 TrialSamplingRecord trialSamplingRecord = trialSamplingRecordMapper.selectByMobilizationIdAndSampleInfoId(obj.getMobilizationId(), trialSampleInfo.getId());

+ 25 - 0
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TrialSelfInspectionRecordServiceImpl.java

@@ -26,6 +26,7 @@ import org.springblade.business.mapper.TrialMaterialMobilizationMapper;
 import org.springblade.business.mapper.TrialSampleInfoMapper;
 import org.springblade.business.mapper.TrialSelfInspectionRecordMapper;
 import org.springblade.business.service.IEntrustInfoService;
+import org.springblade.business.service.ITrialNumberRuleService;
 import org.springblade.business.service.ITrialSelfInspectionRecordService;
 import org.springblade.business.utils.FileUtils;
 import org.springblade.business.utils.FileUtils2;
@@ -93,6 +94,7 @@ public class TrialSelfInspectionRecordServiceImpl extends BaseServiceImpl<TrialS
     private final InformationQueryServiceImpl informationQueryService;
     private final TrialDetectionDataServiceImpl trialDetectionDataService;
     private final IEntrustInfoService entrustInfoService;
+    private final ITrialNumberRuleService trialNumberRuleService;
 
     @Override
     public IPage<TrialSelfInspectionRecordVO> selfPage(IPage<TrialSelfInspectionRecord> page, TrialSelfInspectionRecordPageDTO dto) throws FileNotFoundException {
@@ -1137,6 +1139,29 @@ public class TrialSelfInspectionRecordServiceImpl extends BaseServiceImpl<TrialS
             //修改项目节点基础信息
             jdbcTemplate.update("update u_entrust_info set sample_status=4 where id ='"+dto.getEntrustId()+"'");
         }
+        String[] strings = dto.getTableType().split(",");
+        if(StringUtils.isNotEmpty(dto.getRecordAutoNumber())||StringUtils.isNotEmpty(dto.getReportAutoNumber())){
+            if (dto.getOldRecordNumber()!=null&&dto.getOldRecordNumber().equals(dto.getRecordNo())||dto.getOldReportNumber()!=null&&dto.getOldReportNumber().equals(dto.getReportNo())) {
+                if(strings.length==1){
+                    if(strings[0].equals("1")){
+                        if(StringUtils.isNotEmpty(dto.getRecordAutoNumber())){
+                            trialNumberRuleService.checkSave(Long.valueOf(dto.getProjectId()),4,dto.getId(),dto.getRecordAutoNumber());
+                        }
+                    }else {
+                        if(StringUtils.isNotEmpty(dto.getReportAutoNumber())){
+                            trialNumberRuleService.checkSave(Long.valueOf(dto.getProjectId()),5,dto.getId(),dto.getReportAutoNumber());
+                        }
+                    }
+                }else {
+                    if(StringUtils.isNotEmpty(dto.getRecordAutoNumber())){
+                        trialNumberRuleService.checkSave(Long.valueOf(dto.getProjectId()),4,dto.getId(),dto.getRecordAutoNumber());
+                    }
+                    if(StringUtils.isNotEmpty(dto.getReportAutoNumber())){
+                        trialNumberRuleService.checkSave(Long.valueOf(dto.getProjectId()),5,dto.getId(),dto.getReportAutoNumber());
+                    }
+                }
+            }
+        }
         return dto.getId().toString();
     }
 

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

@@ -0,0 +1,14 @@
+package org.springblade.business.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springblade.business.entity.StandardInfoPrivateJoin;
+import org.springblade.business.mapper.StandardInfoPrivateJoinMapper;
+import org.springblade.business.service.StandardInfoPrivateJoinService;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author LHB
+ */
+@Service
+public class UStandardInfoPrivateJoinServiceImpl extends ServiceImpl<StandardInfoPrivateJoinMapper, StandardInfoPrivateJoin> implements StandardInfoPrivateJoinService {
+}

+ 365 - 0
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/UStandardInfoServiceImpl.java

@@ -0,0 +1,365 @@
+package org.springblade.business.service.impl;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springblade.business.dto.StandardInfoJoinDTO;
+import org.springblade.business.dto.StandardInfoPrivateJoinDTO;
+import org.springblade.business.dto.StandardInfoDTO;
+import org.springblade.business.entity.StandardInfo;
+import org.springblade.business.entity.StandardInfoJoin;
+import org.springblade.business.entity.StandardInfoPrivateJoin;
+import org.springblade.business.mapper.StandardInfoMapper;
+import org.springblade.business.service.StandardInfoJoinService;
+import org.springblade.business.service.StandardInfoPrivateJoinService;
+import org.springblade.business.service.StandardInfoService;
+import org.springblade.business.vo.*;
+import org.springblade.common.utils.SnowFlakeUtil;
+import org.springblade.core.log.exception.ServiceException;
+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.utils.BeanUtil;
+import org.springblade.core.tool.utils.CollectionUtil;
+import org.springblade.core.tool.utils.StringUtil;
+import org.springframework.beans.BeansException;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.Resource;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * @author LHB
+ * @description 针对表【u_standard_info(规范参数管理-基础信息)】的数据库操作Service实现
+ * @createDate 2025-06-11 09:57:39
+ */
+@Service
+public class UStandardInfoServiceImpl extends ServiceImpl<StandardInfoMapper, StandardInfo>
+        implements StandardInfoService {
+
+    /**
+     * 关联表
+     */
+    @Resource
+    private StandardInfoJoinService standardInfoJoinService;
+
+    /**
+     * 与表单的关联关系
+     */
+    @Resource
+    private StandardInfoPrivateJoinService standardInfoPrivateJoinService;
+
+
+    @Override
+    public IPage<StandardInfoDTO> selectMyPage(Query query, StandardInfo standardInfo) {
+        return baseMapper.selectMyPage(new Page<StandardInfoDTO>(query.getCurrent(), query.getSize()), standardInfo);
+    }
+
+    @Override
+    public StandardInfoDTO selectOne(Long id) {
+        return baseMapper.selectMyOne(id);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean insert(StandardInfoDTO uStandardInfo) {
+        try {
+            //获取当前用户
+            BladeUser user = SecureUtil.getUser();
+            uStandardInfo.setId(SnowFlakeUtil.getId());
+            uStandardInfo.setCreateUser(user.getUserId());
+
+            List<StandardInfo> info = uStandardInfo.getInfo();
+
+            //给集合设置id、父级id、创建人
+            info.forEach(item -> {
+                item.setId(SnowFlakeUtil.getId());
+                item.setParentId(uStandardInfo.getId());
+                item.setStandardId(uStandardInfo.getStandardId());
+                item.setCreateUser(user.getUserId());
+            });
+
+            //把父级对象转出来单独保存
+            StandardInfo parent = BeanUtil.copyProperties(uStandardInfo, StandardInfo.class);
+            baseMapper.insert(parent);
+            //通过mybatis-plus 批量新增
+            this.saveBatch(info);
+
+            return true;
+        } catch (BeansException e) {
+            e.printStackTrace();
+            throw new ServiceException("添加失败");
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean edit(StandardInfoDTO uStandardInfo) {
+        try {
+            //获取当前用户
+            BladeUser user = SecureUtil.getUser();
+            uStandardInfo.setUpdateUser(user.getUserId());
+
+            List<StandardInfo> info = uStandardInfo.getInfo();
+            info.forEach(item -> {
+                if (item.getId() == null) {
+                    //新增的子集合设置id、父级id、创建人
+                    item.setId(SnowFlakeUtil.getId());
+                    item.setParentId(uStandardInfo.getId());
+                    item.setStandardId(uStandardInfo.getStandardId());
+                    item.setCreateUser(user.getUserId());
+                } else {
+                    //更新的子集合 添加更新人
+                    item.setUpdateUser(user.getUserId());
+                }
+            });
+            //更新父级对象
+            StandardInfo parent = BeanUtil.copyProperties(uStandardInfo, StandardInfo.class);
+            baseMapper.updateById(parent);
+            //批量更新
+            this.saveOrUpdateBatch(info);
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new ServiceException("更新失败");
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean delete(Long id) {
+        try {
+            //查询关联表 如果有关联关系不允许删除
+            long joinCount = standardInfoJoinService.count(Wrappers.<StandardInfoJoin>lambdaQuery()
+                    .eq(StandardInfoJoin::getStandardInfoRightId, id)
+                    .or()
+                    .eq(StandardInfoJoin::getStandardInfoLeftId, id));
+            if (joinCount > 0) {
+                throw new ServiceException("当前数据正在【条件设置】中使用,无法删除");
+            }
+            //查询与表单的关联表
+            long privateJoinCount = standardInfoPrivateJoinService.count(Wrappers.<StandardInfoPrivateJoin>lambdaQuery()
+                    .eq(StandardInfoPrivateJoin::getStandardInfoId, id));
+            if (privateJoinCount > 0) {
+                throw new ServiceException("当前数据正在【关联元素】中使用,无法删除");
+            }
+
+            int update = baseMapper.update(null, Wrappers.<StandardInfo>lambdaUpdate()
+                    .set(StandardInfo::getIsDeleted, 1)
+                    .eq(StandardInfo::getId, id)
+                    .or()
+                    .eq(StandardInfo::getParentId, id));
+            return update > 0;
+        } catch (ServiceException e) {
+            e.printStackTrace();
+            throw new ServiceException("删除失败");
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean setCondition(List<StandardInfoVO> standardInfoJoins, Long id) {
+        if (CollectionUtil.isNotEmpty(standardInfoJoins)) {
+            //按照组进行删除
+            StandardInfoVO standardInfoVO = standardInfoJoins.get(0);
+            Long parentId = standardInfoVO.getParentId();
+
+            List<StandardInfo> standardInfoIds = baseMapper.selectList(Wrappers.<StandardInfo>lambdaQuery()
+                    .eq(StandardInfo::getParentId, parentId)
+                    .eq(StandardInfo::getIsDeleted, 0));
+            List<Long> collect = standardInfoIds.stream().map(StandardInfo::getId).collect(Collectors.toList());
+
+            //删除当前规范文件当前组下的条件设置
+            standardInfoJoinService.remove(Wrappers.<StandardInfoJoin>lambdaQuery()
+                    .in(StandardInfoJoin::getStandardInfoLeftId, collect));
+
+            BladeUser user = SecureUtil.getUser();
+            //获取参宿
+            List<StandardInfoJoinDTO> list = new ArrayList<>();
+            //新增数据
+            List<StandardInfoJoin> saveData = new ArrayList<>();
+            //数据校验
+            List<String> newGroupRightIds = new ArrayList<>();
+            //解析参数
+            for (StandardInfoVO standardInfoJoin : standardInfoJoins) {
+                StandardInfoJoinDTO standardInfoJoinDTO = new StandardInfoJoinDTO();
+
+                Long leftId = standardInfoJoin.getId();
+
+                standardInfoJoinDTO.setLeftId(leftId);
+                List<StandardInfoConditionVo> standardInfos = standardInfoJoin.getStandardInfos();
+                if (CollectionUtil.isNotEmpty(standardInfos)) {
+                    for (StandardInfoConditionVo standardInfo : standardInfos) {
+                        StandardInfoGroupNameVO standardInfoGroupNameVO = standardInfo.getStandardInfoGroupNameVO();
+                        List<Long> ids = standardInfoGroupNameVO.getIds();
+                        standardInfoJoinDTO.getRightIds().addAll(ids);
+                    }
+                    list.add(standardInfoJoinDTO);
+                }
+
+                //新的数据排序后组合成字符串
+                List<Long> newRightIds = standardInfoJoinDTO.getRightIds();
+                Collections.sort(newRightIds);
+
+                String newRightIdsStr = String.join(",", newRightIds.stream().map(String::valueOf).collect(Collectors.toList()));
+                if(CollectionUtil.isNotEmpty(newRightIds)){
+                    //把左Id加进来 确保只有在左id相同的情况下才进行判断
+                    newRightIdsStr = newRightIdsStr + "," + leftId;
+                }
+                newGroupRightIds.add(newRightIdsStr);
+            }
+
+            Set<String> set = new HashSet<>(newGroupRightIds);
+            if (set.size() < list.size()) {
+                throw new ServiceException("请勿重复添加条件");
+            }
+
+
+            //封装参数
+            for (StandardInfoJoinDTO standardInfoJoin : list) {
+                List<Long> rightIds = standardInfoJoin.getRightIds();
+                standardInfoJoin.setGroupId(SnowFlakeUtil.getId());
+                for (Long rightId : rightIds) {
+                    StandardInfoJoin uStandardInfoJoin = new StandardInfoJoin();
+                    uStandardInfoJoin.setId(SnowFlakeUtil.getId());
+                    //设置组id
+                    uStandardInfoJoin.setGroupId(standardInfoJoin.getGroupId());
+                    uStandardInfoJoin.setStandardInfoLeftId(standardInfoJoin.getLeftId());
+                    uStandardInfoJoin.setStandardInfoRightId(rightId);
+                    uStandardInfoJoin.setCreateUser(user.getUserId());
+                    saveData.add(uStandardInfoJoin);
+                }
+            }
+
+            return standardInfoJoinService.saveOrUpdateBatch(saveData);
+        }
+        return true;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean setElementJoin(List<StandardInfoPrivateJoinVO> standardInfoPrivateJoins, Long id) {
+        BladeUser user = SecureUtil.getUser();
+        List<StandardInfoPrivateJoin> saveData = new ArrayList<>();
+
+
+        if (CollectionUtil.isNotEmpty(standardInfoPrivateJoins)) {
+            //根据
+            StandardInfoPrivateJoinVO standardInfoPrivateJoinVO = standardInfoPrivateJoins.get(0);
+            Long parentId = standardInfoPrivateJoinVO.getParentId();
+
+            List<StandardInfo> standardInfoIds = baseMapper.selectList(Wrappers.<StandardInfo>lambdaQuery()
+                    .eq(StandardInfo::getParentId, parentId)
+                    .eq(StandardInfo::getIsDeleted, 0));
+            List<Long> collect = standardInfoIds.stream().map(StandardInfo::getId).collect(Collectors.toList());
+
+
+            //删除当前规范文件下的条件设置
+            standardInfoPrivateJoinService.remove(Wrappers.<StandardInfoPrivateJoin>lambdaQuery()
+                    .in(StandardInfoPrivateJoin::getStandardInfoId, collect));
+
+            try {
+                for (StandardInfoPrivateJoinVO standardInfoPrivateJoin : standardInfoPrivateJoins) {
+                    Long leftId = standardInfoPrivateJoin.getId();
+
+                    standardInfoPrivateJoin.setGroupId(SnowFlakeUtil.getId());
+                    List<StandardInfoPrivateJoinGroupVO> group = standardInfoPrivateJoin.getGroup();
+                    //项目组
+                    for (StandardInfoPrivateJoinGroupVO standardInfoPrivateJoinGroupVO : group) {
+                        //项目id
+                        Long privateId = standardInfoPrivateJoinGroupVO.getPrivateId();
+                        List<StandardElementVo> keys = standardInfoPrivateJoinGroupVO.getKeys();
+
+                        for (StandardElementVo key : keys) {
+                            StandardInfoPrivateJoin join = new StandardInfoPrivateJoin();
+                            join.setGroupId(standardInfoPrivateJoin.getGroupId());
+                            join.setStandardInfoId(leftId);
+                            join.setId(SnowFlakeUtil.getId());
+                            join.setPrivateId(privateId);
+                            join.setColKey(key.getColKey());
+                            join.setColName(key.getColName());
+                            join.setCreateUser(user.getUserId());
+                            saveData.add(join);
+                        }
+                    }
+                }
+                return standardInfoPrivateJoinService.saveOrUpdateBatch(saveData);
+            } catch (Exception e) {
+                e.printStackTrace();
+                throw new ServiceException("元素关联失败");
+            }
+        }
+        return false;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean deleteConditionSet(Long groupId) {
+        BladeUser user = SecureUtil.getUser();
+        try {
+            return standardInfoJoinService.update(Wrappers.<StandardInfoJoin>lambdaUpdate()
+                    .set(StandardInfoJoin::getIsDeleted, 1)
+                    .set(StandardInfoJoin::getUpdateUser, user.getUserId())
+                    .eq(StandardInfoJoin::getGroupId, groupId));
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new ServiceException("删除失败");
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean deleteElementJoin(Long groupId) {
+        BladeUser user = SecureUtil.getUser();
+        try {
+            return standardInfoPrivateJoinService.update(Wrappers.<StandardInfoPrivateJoin>lambdaUpdate()
+                    .set(StandardInfoPrivateJoin::getIsDeleted, 1)
+                    .set(StandardInfoPrivateJoin::getUpdateUser, user.getUserId())
+                    .eq(StandardInfoPrivateJoin::getGroupId, groupId));
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new ServiceException("删除失败");
+        }
+    }
+
+    @Override
+    public List<StandardInfoVO> getConditionSet(Long id, Long leftId, Long groupId, Long joinGroupId) {
+        List<StandardInfoVO> conditionSet = baseMapper.getConditionSet(id, leftId, groupId, joinGroupId);
+        for (StandardInfoVO standardInfoVO : conditionSet) {
+            List<StandardInfoConditionVo> standardInfos = standardInfoVO.getStandardInfos();
+            for (StandardInfoConditionVo standardInfo : standardInfos) {
+                //重新组装数据
+                List<String> name = standardInfo.getRightStandardInfos().stream().map(StandardInfo::getName).collect(Collectors.toList());
+                List<Long> ids = standardInfo.getRightStandardInfos().stream().map(StandardInfo::getId).collect(Collectors.toList());
+
+                StandardInfoGroupNameVO standardInfoGroupNameVO = new StandardInfoGroupNameVO();
+                standardInfoGroupNameVO.setName(StringUtil.join(name, ","));
+                standardInfoGroupNameVO.setIds(ids);
+
+                standardInfo.setStandardInfoGroupNameVO(standardInfoGroupNameVO);
+                standardInfo.setRightStandardInfos(null);
+            }
+        }
+        return conditionSet;
+    }
+
+    @Override
+    public List<StandardInfoPrivateJoinVO> getElementJoin(Long id, Long leftId, Long groupId, Long joinGroupId) {
+        return baseMapper.getElementJoin(id, leftId, groupId, joinGroupId);
+
+    }
+
+    @Override
+    public List<StandardInfoPrivateJoinVO> effectPreview(String ids) {
+        List<Long> collect = Arrays.stream(ids.split(",")).map(Long::parseLong).collect(Collectors.toList());
+        return baseMapper.effectPreview(collect,collect.size());
+    }
+}
+
+
+
+

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

@@ -116,7 +116,7 @@ public class PDFUtil {
                             txt=txt.substring(0,i);
                         }
                     }
-                    if (txt.length() >= 15 && Func.isNumeric(txt)) {
+                    if (txt.length() >= 15 && Func.isNumeric(txt)||(Func.isNumeric(txt)&&txt.length()==8&&txt.startsWith("123"))) {
                         eVisaConfigList.add(txt);
                     }
                 }
@@ -127,7 +127,7 @@ public class PDFUtil {
                             txt=txt.substring(0,i);
                         }
                     }
-                    if (txt.length() >= 15 && Func.isNumeric(txt)) {
+                    if (txt.length() >= 15 && Func.isNumeric(txt)||(Func.isNumeric(txt)&&txt.length()==8&&txt.startsWith("123"))) {
                         eVisaConfigList.add(txt);
                     }
                 }
@@ -135,7 +135,7 @@ public class PDFUtil {
                 // 特殊处理
                 if(textStr.indexOf("1")>=0){
                     String txt = textStr.substring(textStr.indexOf("1"));
-                    if (txt.length() >= 15 && Func.isNumeric(txt)) {
+                    if (txt.length() >= 15 && Func.isNumeric(txt)||(Func.isNumeric(txt)&&txt.length()==8&&txt.startsWith("123"))) {
                         System.out.println(txt);
                         eVisaConfigList.add(txt);
                     }

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

@@ -101,6 +101,7 @@ public class EVDataServiceImpl implements EVDataService {
                 //添加电签策略
                 List<SealStrategyVO> strategyListByAXQ = getStrategyListByAXQ(taskApp, ids);
                 if (strategyListByAXQ == null || Func.isEmpty(strategyListByAXQ) || strategyListByAXQ.size() == 0) {
+                    ids = ids.replaceAll("✹", "");
                     List<Map<String, Object>> mapList = jdbcTemplate.queryForList("SELECT * from m_textdict_info where type=6  and is_deleted=0 and id in(" + ids + ")");
                     if (mapList != null && mapList.size() > 0) {
                         taskApp.setSigState(2);
@@ -529,14 +530,17 @@ public class EVDataServiceImpl implements EVDataService {
         }
         if(strArray!=null && strArray.length>0) {
             for (int i = 0; i < strArray.length; i++) {
-                String sqlinfo = " SELECT * from ( SELECT a.id as keyWord,a.project_id,a.pyzbx ,a.pyzby,(SELECT acc_code from blade_user where id='" + strArray[i] + "' and is_deleted=0  ) as sealId from m_textdict_info a where  a.type =2 and a.id in (" + dqIds + ")  and sig_role_id in (SELECT DISTINCT c.role_id from m_project_assignment_user c  where c.contract_id=" + task.getContractId() + " and user_id=" + strArray[i] + " and c.is_deleted=0 ) ) x where x.sealId is not null ";
-                if (task.getSigType() == 2) {
-                    sqlinfo = "SELECT a.id as keyWord,a.pyzbx,a.pyzby,b.certificate_number as sealId from m_textdict_info a ,m_sign_pfx_file b where a.sig_role_id = b.pfx_type and b.project_contract_role like '%" + task.getContractId() + "%' and a.is_deleted=0 and b.is_deleted=0 and a.type=6 and a.id in(" + dqIds + ")";
-                    System.out.println("东方中讯--签章--" + sqlinfo);
-                } else {
-                    System.out.println("东方中讯--签字--" + sqlinfo);
+                List<Map<String, Object>> maps2 = null;
+                if (dqIds.length() > 0) {
+                    String sqlinfo = " SELECT * from ( SELECT a.id as keyWord,a.project_id,a.pyzbx ,a.pyzby,(SELECT acc_code from blade_user where id='" + strArray[i] + "' and is_deleted=0  ) as sealId from m_textdict_info a where  a.type =2 and a.id in (" + dqIds + ")  and sig_role_id in (SELECT DISTINCT c.role_id from m_project_assignment_user c  where c.contract_id=" + task.getContractId() + " and user_id=" + strArray[i] + " and c.is_deleted=0 ) ) x where x.sealId is not null ";
+                    if (task.getSigType() == 2) {
+                        sqlinfo = "SELECT a.id as keyWord,a.pyzbx,a.pyzby,b.certificate_number as sealId from m_textdict_info a ,m_sign_pfx_file b where a.sig_role_id = b.pfx_type and b.project_contract_role like '%" + task.getContractId() + "%' and a.is_deleted=0 and b.is_deleted=0 and a.type=6 and a.id in(" + dqIds + ")";
+                        System.out.println("东方中讯--签章--" + sqlinfo);
+                    } else {
+                        System.out.println("东方中讯--签字--" + sqlinfo);
+                    }
+                    maps2 = jdbcTemplate.queryForList(sqlinfo);
                 }
-                List<Map<String, Object>> maps2 = jdbcTemplate.queryForList(sqlinfo);
                 if(CollectionUtil.isNotEmpty(maps2)) {
                     Map<String, List<Map<String, Object>>> peopleByAge = maps2.stream()
                             .collect(Collectors.groupingBy(hada -> (Func.toStr(hada.get("keyWord")))));
@@ -609,14 +613,17 @@ public class EVDataServiceImpl implements EVDataService {
         if(strArray!=null && strArray.length>0){
             for (int i =0 ;i < strArray.length;i++) {
                 String userId =strArray[i];
-                String sqlinfo = "SELECT * from ( SELECT DISTINCT a.id,a.pyzbx ,a.pyzby,a.project_id,(SELECT signature_file_url from m_sign_pfx_file where is_register=1 and certificate_user_id='" + userId + "' and is_deleted=0  ) as signature_file_url, (SELECT wide from m_sign_pfx_file where is_register=1 and certificate_user_id='" + userId + "' and is_deleted=0  ) as wide ,(SELECT high from m_sign_pfx_file where is_register=1 and certificate_user_id='" + userId + "' and is_deleted=0  ) as high from m_textdict_info a where  a.type =2 and a.id in (" + dqIds + ") and sig_role_id in (SELECT DISTINCT c.role_id from m_project_assignment_user c  where c.contract_id=" + task.getContractId() + " and user_id=" + userId + " and c.is_deleted=0 ) ) x where x.signature_file_url is not null ";
-                if (task.getSigType() == 2) {
-                    sqlinfo = "SELECT a.id,a.pyzbx,a.pyzby,b.signature_file_url,b.id as sfId,a.project_id,b.certificate_password,b.certificate_user_name,b.certificate_number ,b.wide,b.high from m_textdict_info a ,m_sign_pfx_file b where a.sig_role_id = b.pfx_type and b.project_contract_role like '%" + task.getContractId() + "%' and a.is_deleted=0 and b.is_deleted=0 and a.type=6 and a.id in(" + dqIds + ") ";
-                    System.out.println("安心签--签章--=" + sqlinfo);
-                } else {
-                    System.out.println("安心签--签字--=" + sqlinfo);
+                List<Map<String, Object>> maps2 = null;
+                if (dqIds.length() > 0) {
+                    String sqlinfo = "SELECT * from ( SELECT DISTINCT a.id,a.pyzbx ,a.pyzby,a.project_id,(SELECT signature_file_url from m_sign_pfx_file where is_register=1 and certificate_user_id='" + userId + "' and is_deleted=0  ) as signature_file_url, (SELECT wide from m_sign_pfx_file where is_register=1 and certificate_user_id='" + userId + "' and is_deleted=0  ) as wide ,(SELECT high from m_sign_pfx_file where is_register=1 and certificate_user_id='" + userId + "' and is_deleted=0  ) as high from m_textdict_info a where  a.type =2 and a.id in (" + dqIds + ") and sig_role_id in (SELECT DISTINCT c.role_id from m_project_assignment_user c  where c.contract_id=" + task.getContractId() + " and user_id=" + userId + " and c.is_deleted=0 ) ) x where x.signature_file_url is not null ";
+                    if (task.getSigType() == 2) {
+                        sqlinfo = "SELECT a.id,a.pyzbx,a.pyzby,b.signature_file_url,b.id as sfId,a.project_id,b.certificate_password,b.certificate_user_name,b.certificate_number ,b.wide,b.high from m_textdict_info a ,m_sign_pfx_file b where a.sig_role_id = b.pfx_type and b.project_contract_role like '%" + task.getContractId() + "%' and a.is_deleted=0 and b.is_deleted=0 and a.type=6 and a.id in(" + dqIds + ") ";
+                        System.out.println("安心签--签章--=" + sqlinfo);
+                    } else {
+                        System.out.println("安心签--签字--=" + sqlinfo);
+                    }
+                    maps2 = jdbcTemplate.queryForList(sqlinfo);
                 }
-                List<Map<String, Object>> maps2 = jdbcTemplate.queryForList(sqlinfo);
                 if (maps2 != null && maps2.size() > 0) {
                     List<Map<String, Object>> maps = new ArrayList<>();
                     Map<String, List<Map<String, Object>>> peopleByAge = maps2.stream()

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

@@ -42,7 +42,7 @@ public class PDFUtils {
                             txt=txt.substring(0,i);
                         }
                     }
-                    if (txt.length() >= 15 && Func.isNumeric(txt)) {
+                    if (txt.length() >= 15 && Func.isNumeric(txt)||(Func.isNumeric(txt)&&txt.length()==8&&txt.startsWith("123"))) {
                         eVisaConfigList.add(txt);
                     }
                 }
@@ -59,7 +59,7 @@ public class PDFUtils {
                             txt=txt.substring(0,i);
                         }
                     }
-                    if (txt.length() >= 15 && Func.isNumeric(txt)) {
+                    if (txt.length() >= 15 && Func.isNumeric(txt)||(Func.isNumeric(txt)&&txt.length()==8&&txt.startsWith("123"))) {
                         eVisaConfigList.add(txt);
                     }
                 }
@@ -67,7 +67,7 @@ public class PDFUtils {
                 // 特殊处理
                 if(textStr.indexOf("1")>=0){
                     String txt = textStr.substring(textStr.indexOf("1"));
-                    if (txt.length() >= 15 && Func.isNumeric(txt)) {
+                    if (txt.length() >= 15 && Func.isNumeric(txt)||(Func.isNumeric(txt)&&txt.length()==8&&txt.startsWith("123"))) {
                         System.out.println(txt);
                         eVisaConfigList.add(txt);
                     }
@@ -146,7 +146,7 @@ public class PDFUtils {
                             txt=txt.substring(0,i);
                         }
                     }
-                    if (txt.length() >= 15 && Func.isNumeric(txt)) {
+                    if (txt.length() >= 15 && Func.isNumeric(txt)||(Func.isNumeric(txt)&&txt.length()==8&&txt.startsWith("123"))) {
                         eVisaConfigList.add(txt);
                     }
                 }
@@ -157,7 +157,7 @@ public class PDFUtils {
                             txt=txt.substring(0,i);
                         }
                     }
-                    if (txt.length() >= 15 && Func.isNumeric(txt)) {
+                    if (txt.length() >= 15 && Func.isNumeric(txt)||(Func.isNumeric(txt)&&txt.length()==8&&txt.startsWith("123"))) {
                         eVisaConfigList.add(txt);
                     }
                 }
@@ -165,7 +165,7 @@ public class PDFUtils {
                 // 特殊处理
                 if(textStr.indexOf("1")>=0){
                     String txt = textStr.substring(textStr.indexOf("1"));
-                    if (txt.length() >= 15 && Func.isNumeric(txt)) {
+                    if (txt.length() >= 15 && Func.isNumeric(txt)||(Func.isNumeric(txt)&&txt.length()==8&&txt.startsWith("123"))) {
                         System.out.println(txt);
                         eVisaConfigList.add(txt);
                     }

+ 8 - 1
blade-service/blade-manager/src/main/java/com/jfireel/expression/node/impl/EqualNode.java

@@ -29,7 +29,14 @@ public class EqualNode extends OperatorResultNode {
                 return EqUtil.calculate((Number) leftValue, (Number) rightValue);
             } else if (leftValue instanceof List || rightValue instanceof List) {
                 Object[] leftAndRight = ValueUtil.obtain(leftOperand.calculate(variables), rightOperand.calculate(variables));
-                return leftAndRight == null ? null : StringUtils.isEquals(leftAndRight[0], leftAndRight[1]);
+
+                //如果是数字类型 第一个是float  第二个是整数所以不能使用equals
+                if(leftAndRight[0] instanceof Number && leftAndRight[1] instanceof Number){
+                    return EqUtil.calculate((Number) leftAndRight[0], (Number) leftAndRight[1]);
+                }
+
+                boolean equals = StringUtils.isEquals(leftAndRight[0], leftAndRight[1]);
+                return leftAndRight == null ? null : equals;
             } else {
                 return leftValue.equals(rightValue);
             }

+ 6 - 1
blade-service/blade-manager/src/main/java/com/jfireel/expression/node/impl/GtEqNode.java

@@ -23,7 +23,12 @@ public class GtEqNode extends OperatorResultNode {
 //		if (rightValue == null) {
 //			return null;
 //		}
-        Object[] leftAndRight = ValueUtil.obtain(leftOperand.calculate(variables), rightOperand.calculate(variables));
+        Object calculate = leftOperand.calculate(variables);
+        if(calculate instanceof Boolean && !(Boolean) calculate){
+            return calculate;
+        }
+        Object calculate1 = rightOperand.calculate(variables);
+        Object[] leftAndRight = ValueUtil.obtain(calculate, calculate1);
         return leftAndRight == null ? null : !((Boolean) LtUtil.calculate((Number) leftAndRight[0], (Number) leftAndRight[1]));
     }
 }

+ 13 - 0
blade-service/blade-manager/src/main/java/com/jfireel/expression/node/impl/NotEqualNode.java

@@ -1,8 +1,11 @@
 package com.jfireel.expression.node.impl;
 
 import com.jfireel.expression.token.Operator;
+import com.jfireel.expression.util.ValueUtil;
 import com.jfireel.expression.util.number.EqUtil;
+import com.mixsmart.utils.StringUtils;
 
+import java.util.List;
 import java.util.Map;
 
 public class NotEqualNode extends OperatorResultNode {
@@ -24,6 +27,16 @@ public class NotEqualNode extends OperatorResultNode {
         } else {
             if (leftValue instanceof Number && rightValue instanceof Number) {
                 return EqUtil.calculate((Number) leftValue, (Number) rightValue) == false;
+            } else if (leftValue instanceof List || rightValue instanceof List) {
+                Object[] leftAndRight = ValueUtil.obtain(leftOperand.calculate(variables), rightOperand.calculate(variables));
+
+                //如果是数字类型 第一个是float  第二个是整数所以不能使用equals
+                if(leftAndRight[0] instanceof Number && leftAndRight[1] instanceof Number){
+                    return !EqUtil.calculate((Number) leftAndRight[0], (Number) leftAndRight[1]);
+                }
+
+                boolean equals = !StringUtils.isEquals(leftAndRight[0], leftAndRight[1]);
+                return leftAndRight == null ? null : equals;
             } else {
                 return leftValue.equals(rightValue) == false;
             }

+ 139 - 44
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ExcelTabController.java

@@ -19,6 +19,8 @@ import com.spire.xls.collections.PicturesCollection;
 import com.spire.xls.core.spreadsheet.HTMLOptions;
 import io.swagger.annotations.*;
 import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
 import lombok.SneakyThrows;
 import org.apache.commons.codec.Charsets;
 import org.apache.commons.io.IOUtils;
@@ -52,6 +54,7 @@ import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.constant.BladeConstant;
 import org.springblade.core.tool.utils.*;
 import org.springblade.manager.bean.TableInfo;
+import org.springblade.manager.dto.AddBussFileSortDTO;
 import org.springblade.manager.entity.*;
 import org.springblade.manager.enums.ExecuteType;
 import org.springblade.manager.mapper.ExcelTabMapper;
@@ -1710,7 +1713,7 @@ public class ExcelTabController extends BladeController {
     /**
      * 上传文件
      *
-     * @param file 文件
+     * @param files 文件
      * @return ObjectStat
      */
     @SneakyThrows
@@ -1725,40 +1728,45 @@ public class ExcelTabController extends BladeController {
             @ApiImplicitParam(name = "classify", value = "classify", required = true),
             @ApiImplicitParam(name = "projectId", value = "projectId", required = true)
     })
-    public R addBussFile(@RequestParam("file") MultipartFile file, Long pkeyId, String nodeId, String contractId, String projectId, String classify) {
-
+    public R addBussFile(@RequestParam("file") MultipartFile[] file, Long pkeyId, String nodeId, String contractId, String projectId, String classify) {
+        List<TableFile>list=new ArrayList<>();
+        for (int i = 0; i < file.length; i++) {
+            R<BladeFile> bladeFile = iossClient.addFileInfo(file[i]);
+            BladeFile bladeFile1 = bladeFile.getData();
+            TableFile tableFile = new TableFile();
+            String fileExtension = FileUtil.getFileExtension(bladeFile1.getName()).toLowerCase();
+            tableFile.setTabId(pkeyId + "");
+            tableFile.setName(file[i].getOriginalFilename());
+            tableFile.setContractId(Long.valueOf(contractId));
+            tableFile.setClassify(Integer.parseInt(classify));
+            tableFile.setType(2);
+            tableFile.setDomainUrl(bladeFile1.getLink());
+            tableFile.setIsDeleted(0);
+            tableFile.setExtension(fileExtension);
+
+            NewBladeFile newBladeFile = new NewBladeFile();
+            if (fileExtension.contains("xlsx")) {
+                newBladeFile = this.commonFileClient.excelToPdf(file[i]);
+                tableFile.setDomainPdfUrl(newBladeFile.getPdfUrl());
+            } else if (fileExtension.contains("xls")) {
+                newBladeFile = this.commonFileClient.excelToPdf(file[i]);
+                tableFile.setDomainPdfUrl(newBladeFile.getPdfUrl());
+            } else if (fileExtension.contains("docx")) {
+                newBladeFile = this.commonFileClient.wordToPdf(file[i]);
+                tableFile.setDomainPdfUrl(newBladeFile.getPdfUrl());
+            } else if (fileExtension.contains("png") || fileExtension.contains("jpg") || fileExtension.contains("webp") || fileExtension.contains("apng") ||
+                    fileExtension.contains("bmp") || fileExtension.contains("jepg") || fileExtension.contains("tif") || fileExtension.contains("gif")) {
+                newBladeFile = this.commonFileClient.pngOrJpgToPdf(file[i]);
+                tableFile.setDomainPdfUrl(newBladeFile.getPdfUrl());
+            } else if (fileExtension.contains("pdf")) {
+                tableFile.setDomainPdfUrl(bladeFile1.getLink());
+            }
 
-        R<BladeFile> bladeFile = iossClient.addFileInfo(file);
-        BladeFile bladeFile1 = bladeFile.getData();
-        TableFile tableFile = new TableFile();
-        String fileExtension = FileUtil.getFileExtension(bladeFile1.getName()).toLowerCase();
-        tableFile.setTabId(pkeyId + "");
-        tableFile.setName(file.getOriginalFilename());
-        tableFile.setType(2);
-        tableFile.setDomainUrl(bladeFile1.getLink());
-        tableFile.setIsDeleted(0);
-        tableFile.setExtension(fileExtension);
-
-        NewBladeFile newBladeFile = new NewBladeFile();
-        if (fileExtension.contains("xlsx")) {
-            newBladeFile = this.commonFileClient.excelToPdf(file);
-            tableFile.setDomainPdfUrl(newBladeFile.getPdfUrl());
-        } else if (fileExtension.contains("xls")) {
-            newBladeFile = this.commonFileClient.excelToPdf(file);
-            tableFile.setDomainPdfUrl(newBladeFile.getPdfUrl());
-        } else if (fileExtension.contains("docx")) {
-            newBladeFile = this.commonFileClient.wordToPdf(file);
-            tableFile.setDomainPdfUrl(newBladeFile.getPdfUrl());
-        } else if (fileExtension.contains("png") || fileExtension.contains("jpg") || fileExtension.contains("webp") || fileExtension.contains("apng") ||
-                fileExtension.contains("bmp") || fileExtension.contains("jepg") || fileExtension.contains("tif") || fileExtension.contains("gif")) {
-            newBladeFile = this.commonFileClient.pngOrJpgToPdf(file);
-            tableFile.setDomainPdfUrl(newBladeFile.getPdfUrl());
-        } else if (fileExtension.contains("pdf")) {
-            tableFile.setDomainPdfUrl(bladeFile1.getLink());
+            tableFile.setStatus("finished");
+            list.add(tableFile);
         }
 
-        tableFile.setStatus("finished");
-        tableFileService.save(tableFile);
+        tableFileService.saveBatch(list);
 
         // 生成单个pdf
         excelTabService.getBussPdfInfo(pkeyId);
@@ -1789,7 +1797,7 @@ public class ExcelTabController extends BladeController {
             informationQueryClient.saveInfo(query);
         }
         excelTabService.getBussPdfs(nodeId, classify, contractId, projectId);
-        return R.data(tableFile.getId());
+        return R.status(true);
     }
 
     @GetMapping("/show-buss-tab")
@@ -1810,6 +1818,8 @@ public class ExcelTabController extends BladeController {
         excelTabService.getBussPdfInfo(pkeyId);
         //重新生成PDF修改queryInfo
         excelTabService.getBussPdfs(nodeId, classify, wbsTreeContract.getContractId(), wbsTreeContract.getProjectId());
+        WbsTreeContract contract = wbsTreeContractService.getById(Long.parseLong(nodeId));
+        wbsTreeContractService.checkNodeAllDate(contract);
         return R.data("成功");
     }
 
@@ -2053,7 +2063,11 @@ public class ExcelTabController extends BladeController {
                 }
             });
         }
-
+        //检查当前节点下所有的未隐藏的表单日期是否填写完整
+        WbsTreeContract contract = wbsTreeContractService.getById(Long.parseLong(nodeId));
+        if(contract!=null){
+            wbsTreeContractService.checkNodeAllDate(contract);
+        }
         executionTime.info("----数据保存完毕 ----");
         //发生异常后直接返回,不进行合并
         if (errorPKeyIds.size() > 0) {
@@ -4402,6 +4416,43 @@ public class ExcelTabController extends BladeController {
 
 
     }
+    @Data
+    @AllArgsConstructor
+    @NoArgsConstructor
+    public static class BussfileDTO{
+        private String name;
+        private String url;
+    }
+    @PostMapping("/previewBussfile")
+    public R<List<BussfileDTO>> previewBussfile(@RequestPart("file")MultipartFile[] file){
+        List<BussfileDTO>list=new ArrayList<>();
+        for (int i = 0; i < file.length; i++){
+            BussfileDTO dto = new BussfileDTO();
+            R<BladeFile> bladeFile = iossClient.addFileInfo(file[i]);
+            BladeFile bladeFile1 = bladeFile.getData();
+            String fileExtension = FileUtil.getFileExtension(bladeFile1.getName()).toLowerCase();
+            NewBladeFile newBladeFile = new NewBladeFile();
+            if (fileExtension.contains("xlsx")) {
+                newBladeFile = this.commonFileClient.excelToPdf(file[i]);
+                dto.setUrl(newBladeFile.getPdfUrl());
+            } else if (fileExtension.contains("xls")) {
+                newBladeFile = this.commonFileClient.excelToPdf(file[i]);
+                dto.setUrl(newBladeFile.getPdfUrl());
+            } else if (fileExtension.contains("docx")) {
+                newBladeFile = this.commonFileClient.wordToPdf(file[i]);
+                dto.setUrl(newBladeFile.getPdfUrl());
+            } else if (fileExtension.contains("png") || fileExtension.contains("jpg") || fileExtension.contains("webp") || fileExtension.contains("apng") ||
+                    fileExtension.contains("bmp") || fileExtension.contains("jepg") || fileExtension.contains("tif") || fileExtension.contains("gif")) {
+                newBladeFile = this.commonFileClient.pngOrJpgToPdf(file[i]);
+                dto.setUrl(newBladeFile.getPdfUrl());
+            } else if (fileExtension.contains("pdf")) {
+                dto.setUrl(bladeFile1.getLink());
+            }
+            dto.setName(file[i].getOriginalFilename());
+            list.add(dto);
+        }
+        return R.data(list);
+    }
 
     /**
      * 质检附件追加
@@ -4417,11 +4468,12 @@ public class ExcelTabController extends BladeController {
             @ApiImplicitParam(name = "nodeId", value = "nodeId", required = true),
 
     })
-    public R addBussFile(@RequestParam("file") MultipartFile[] file, String nodeId, Integer type, Long contractId, Integer classify, BladeUser b) {
+    public R addBussFile(Integer classify,Long contractId,@RequestParam("file") MultipartFile[] file, String nodeId, Integer type,BladeUser b) {
         List<TableFile> fileList = new ArrayList<>();
         if (file != null && file.length >= 1) {
-            for (MultipartFile multipartFile : file) {
-                R<BladeFile> bladeFile = iossClient.addFileInfo(multipartFile);
+            for (int i = 0; i < file.length; i++) {
+
+                R<BladeFile> bladeFile = iossClient.addFileInfo(file[i]);
                 BladeFile bladeFile1 = bladeFile.getData();
 
                 TableFile tableFile = new TableFile();
@@ -4429,7 +4481,7 @@ public class ExcelTabController extends BladeController {
                 String fileExtension = FileUtil.getFileExtension(bladeFile1.getName()).toLowerCase();
                 tableFile.setTabId(nodeId + "");
                 tableFile.setContractId(contractId);
-                tableFile.setName(multipartFile.getOriginalFilename());
+                tableFile.setName(file[i].getOriginalFilename());
                 tableFile.setType(type); //10 代表附件
                 if (type == 10 || type == 11 || type == 12 || type == 20 || type == 21 || type == 22) {
                     tableFile.setDomainPdfUrl(bladeFile1.getLink());
@@ -4439,8 +4491,26 @@ public class ExcelTabController extends BladeController {
                 tableFile.setExtension(fileExtension);
                 tableFile.setClassify(classify);
                 fileList.add(tableFile);
+                NewBladeFile newBladeFile = new NewBladeFile();
+                if (fileExtension.contains("xlsx")) {
+                    newBladeFile = this.commonFileClient.excelToPdf(file[i]);
+                    tableFile.setDomainPdfUrl(newBladeFile.getPdfUrl());
+                } else if (fileExtension.contains("xls")) {
+                    newBladeFile = this.commonFileClient.excelToPdf(file[i]);
+                    tableFile.setDomainPdfUrl(newBladeFile.getPdfUrl());
+                } else if (fileExtension.contains("docx")) {
+                    newBladeFile = this.commonFileClient.wordToPdf(file[i]);
+                    tableFile.setDomainPdfUrl(newBladeFile.getPdfUrl());
+                } else if (fileExtension.contains("png") || fileExtension.contains("jpg") || fileExtension.contains("webp") || fileExtension.contains("apng") ||
+                        fileExtension.contains("bmp") || fileExtension.contains("jepg") || fileExtension.contains("tif") || fileExtension.contains("gif")) {
+                    newBladeFile = this.commonFileClient.pngOrJpgToPdf(file[i]);
+                    tableFile.setDomainPdfUrl(newBladeFile.getPdfUrl());
+                } else if (fileExtension.contains("pdf")) {
+                    tableFile.setDomainPdfUrl(bladeFile1.getLink());
+                }
             }
             tableFileService.saveOrUpdateBatch(fileList);
+
             String file_path = FileUtils.getSysLocalFileUrl();
             String sys_isonline = ParamCache.getValue(CommonConstant.SYS_ISONLINE);
             List<TableFileVO> data = tableFileService.selectTableFileListByTen(Long.valueOf(nodeId + ""), Integer.valueOf(classify));
@@ -4453,7 +4523,9 @@ public class ExcelTabController extends BladeController {
             if (tabpdf2.exists()) {
                 tabpdf2.delete();
             }
-            FileUtils.mergePdfPublicMethods(datainfo, listPdf);
+            if(datainfo.size()>=1){
+                FileUtils.mergePdfPublicMethods(datainfo, listPdf);
+            }
             String netUrl = "";
             BladeFile bladeFile = this.newIOSSClient.uploadFile(nodeId + ".pdf", listPdf);
             if (bladeFile != null && ObjectUtils.isNotEmpty(bladeFile.getLink())) {
@@ -4509,6 +4581,24 @@ public class ExcelTabController extends BladeController {
         }
     }
 
+    @PostMapping("/add-bussfile-node-sort")
+    public R addBussFileNodeSort(@RequestBody AddBussFileSortDTO dto){
+        List<TableFile> tableFileList = tableFileService.list(new LambdaQueryWrapper<>(TableFile.class).eq(TableFile::getClassify, dto.getClassify()).eq(TableFile::getContractId, dto.getContractId()).eq(TableFile::getTabId, dto.getId()).eq(TableFile::getType, dto.getType()));
+        System.out.println(tableFileList);
+        if(dto.getList().length>0&&!tableFileList.isEmpty()){
+            for (TableFile file : tableFileList) {
+                for (int i = 0; i < dto.getList().length; i++) {
+                    if(dto.getList()[i].equals(file.getName())){
+                        file.setSort(i);
+                        break;
+                    }
+                }
+            }
+            return R.status(tableFileService.updateBatchById(tableFileList));
+       }
+       return R.status(true);
+    }
+
 
     @PostMapping("/save_nodeId")
     @ApiOperationSupport(order = 72)
@@ -4635,16 +4725,21 @@ public class ExcelTabController extends BladeController {
             @ApiImplicitParam(name = "id", value = "记录id-当做groupId", required = true),
             @ApiImplicitParam(name = "contractId", value = "合同段id", required = true)
     })
-    public R<List<Map<String, Object>>> getBussDataInfoTrialentrust(Long id, Long pkeyId, Long contractId, Long sampleId, String formData,Boolean isCancel) {
+    public R<List<Map<String, Object>>> getBussDataInfoTrialentrust(Long id, Long pkeyId, Long contractId, Long sampleId, String formData) {
         JSONObject jsonObject = JSONObject.parseObject(formData);
         Boolean isrmove=true;
-        if(isCancel==null){
-            isCancel=false;
-        }
-        List<Map<String, Object>> bussDataInfoTrial = excelTabService.getBussDataInfoTrialentrust(id, pkeyId, contractId, sampleId, jsonObject,isrmove,isCancel);
+        List<Map<String, Object>> bussDataInfoTrial = excelTabService.getBussDataInfoTrialentrust(id, pkeyId, contractId, sampleId, jsonObject,isrmove);
         return R.data(bussDataInfoTrial);
     }
 
+    @GetMapping("/cancelSample")
+    @ApiOperationSupport(order = 4)
+    @ApiOperation(value = "委托单取消关联样品")
+    public R cancelSample(Long groupId, Long pkeyId, Long contractId,Long sampleId1) throws Exception {
+        excelTabService.cancelSample(groupId,pkeyId,contractId,sampleId1);
+        return R.status(true);
+    }
+
     public static synchronized InputStream getOSSInputStream2(String urlStr) throws Exception {
         //获取OSS文件流
         URL url = new URL(urlStr);

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

@@ -55,6 +55,7 @@ import org.springblade.core.boot.ctrl.BladeController;
 import java.rmi.ServerException;
 import java.util.Arrays;
 import java.util.List;
+import java.util.Objects;
 import java.util.stream.Collectors;
 
 /**
@@ -137,7 +138,7 @@ public class TableFileController extends BladeController {
                 updateWrapper.set("tab_file_type", 1);
                 wbsTreeContractService.update(updateWrapper);
                 WbsTreeContract wbsTreeContract = wbsTreeContractService.getBaseMapper().selectOne(new QueryWrapper<WbsTreeContract>().eq("p_key_id", tableFile.getTabId()));
-                if(wbsTreeContract.getNodeClass().equals(Integer.valueOf(2))){
+                if(Objects.equals(wbsTreeContract.getNodeClass(), 2)){
                     Integer classify =
                             Arrays.asList("1", "2", "3").contains(wbsTreeContract.getTableOwner()) ? 1 :
                                     Arrays.asList("4", "5", "6").contains(wbsTreeContract.getTableOwner()) ? 2 : 1;
@@ -279,4 +280,14 @@ public class TableFileController extends BladeController {
         }
         return R.data("成功");
     }
+    @PostMapping("/sort")
+    @ApiOperationSupport(order = 1)
+    @ApiOperation(value = "附件排序", notes = "传入listids")
+    public R sort(@RequestBody List<TableFile> list){
+        int i=1;
+        for (TableFile file : list) {
+            file.setSort(i++);
+        }
+      return R.status(tableFileService.updateBatchById(list));
+    }
 }

Некоторые файлы не были показаны из-за большого количества измененных файлов