ソースを参照

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

lvy 1 ヶ月 前
コミット
7251871c06
100 ファイル変更5113 行追加239 行削除
  1. 1 0
      blade-common/src/main/java/org/springblade/common/utils/FileUtils.java
  2. 1 1
      blade-ops-api/blade-resource-api/src/main/java/org/springblade/resource/feign/NewIOSSClient.java
  3. 5 0
      blade-ops/blade-resource/src/main/java/org/springblade/resource/builder/oss/BladeOssRuleRe.java
  4. 6 0
      blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/entity/ArchivesAuto.java
  5. 2 0
      blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/vo/ArchivesAutoVO.java
  6. 22 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/dto/PrivateStandardDTO.java
  7. 25 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/dto/StandardInfoDTO.java
  8. 32 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/dto/StandardInfoJoinDTO.java
  9. 31 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/dto/StandardInfoPrivateJoinDTO.java
  10. 34 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/dto/TrialAutoNumberDTO.java
  11. 1 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/dto/TrialFileSubmitDTO.java
  12. 6 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/dto/TrialMaterialMobilizationDTO.java
  13. 37 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/dto/TrialNumberRuleDTO.java
  14. 6 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/dto/TrialSampleInfoDTO.java
  15. 11 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/dto/TrialSelfInspectionRecordDTO.java
  16. 121 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/PrivateStandard.java
  17. 118 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/StandardFile.java
  18. 107 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/StandardInfo.java
  19. 58 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/StandardInfoJoin.java
  20. 98 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/StandardInfoPrivateJoin.java
  21. 56 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/TrialAutoNumber.java
  22. 77 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/TrialNumberRule.java
  23. 3 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/FixedFlowVO.java
  24. 17 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/StandardInfoDtoVo.java
  25. 22 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/StandardInfoPrivateJoinVO.java
  26. 23 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/StandardInfoVO.java
  27. 34 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/TrialAutoNumberVO.java
  28. 36 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/TrialNumberRuleVO.java
  29. 17 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/TrialNumberRuleVO1.java
  30. 1 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/ArchiveTreeContractDTO.java
  31. 7 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/WbsTreeContract.java
  32. 7 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/WbsTreePrivate.java
  33. 142 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/WbsTreeSynchronousRecord.java
  34. 55 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/enums/WbsSyncTypeEnum.java
  35. 3 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/feign/ArchiveTreeContractClient.java
  36. 3 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/feign/WbsParamClient.java
  37. 2 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/WbsTreeContractLazyVO.java
  38. 27 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/WbsTreeSynchronousRecordVo.java
  39. 2 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchivesAutoController.java
  40. 370 142
      blade-service/blade-archive/src/main/java/org/springblade/archive/external/utils/TransUtil.java
  41. 26 3
      blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/ArchivesAutoMapper.xml
  42. 17 5
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchiveAutoPdfServiceImpl.java
  43. 313 5
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchivesAutoServiceImpl.java
  44. 3 3
      blade-service/blade-archive/src/main/java/org/springblade/archive/utils/FileUtils.java
  45. 146 30
      blade-service/blade-business/src/main/java/org/springblade/business/controller/InformationWriteQueryController.java
  46. 152 0
      blade-service/blade-business/src/main/java/org/springblade/business/controller/PrivateStandardController.java
  47. 199 0
      blade-service/blade-business/src/main/java/org/springblade/business/controller/StandardInfoController.java
  48. 129 0
      blade-service/blade-business/src/main/java/org/springblade/business/controller/TrialAutoNumberController.java
  49. 3 0
      blade-service/blade-business/src/main/java/org/springblade/business/controller/TrialDetectionController.java
  50. 3 1
      blade-service/blade-business/src/main/java/org/springblade/business/controller/TrialMaterialController.java
  51. 250 0
      blade-service/blade-business/src/main/java/org/springblade/business/controller/TrialNumberRuleController.java
  52. 5 1
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/ArchiveFileMapper.xml
  53. 1 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/FixedFlowLinkMapper.java
  54. 3 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/FixedFlowLinkMapper.xml
  55. 20 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/PrivateStandardMapper.java
  56. 35 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/PrivateStandardMapper.xml
  57. 18 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/StandardFileMapper.java
  58. 23 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/StandardFileMapper.xml
  59. 28 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/StandardInfoJoinMapper.java
  60. 31 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/StandardInfoJoinMapper.xml
  61. 36 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/StandardInfoMapper.java
  62. 193 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/StandardInfoMapper.xml
  63. 28 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/StandardInfoPrivateJoinMapper.java
  64. 33 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/StandardInfoPrivateJoinMapper.xml
  65. 44 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/TrialAutoNumberMapper.java
  66. 22 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/TrialAutoNumberMapper.xml
  67. 46 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/TrialNumberRuleMapper.java
  68. 34 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/TrialNumberRuleMapper.xml
  69. 1 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/IFixedFlowLinkService.java
  70. 41 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/ITrialAutoNumberService.java
  71. 1 1
      blade-service/blade-business/src/main/java/org/springblade/business/service/ITrialMaterialMobilizationService.java
  72. 55 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/ITrialNumberRuleService.java
  73. 1 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/ITrialSelfInspectionRecordService.java
  74. 23 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/PrivateStandardService.java
  75. 13 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/StandardFileService.java
  76. 10 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/StandardInfoJoinService.java
  77. 10 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/StandardInfoPrivateJoinService.java
  78. 46 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/StandardInfoService.java
  79. 1 1
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/ArchiveFileServiceImpl.java
  80. 14 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/EntrustInfoServiceImpl.java
  81. 5 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/FixedFlowLinkServiceImpl.java
  82. 6 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/FixedFlowServiceImpl.java
  83. 212 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. 17 6
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TrialMaterialMobilizationServiceImpl.java
  88. 357 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TrialNumberRuleServiceImpl.java
  89. 12 4
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TrialSampleInfoServiceImpl.java
  90. 45 14
      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. 270 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/UStandardInfoServiceImpl.java
  93. 27 5
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ArchiveTreeContractController.java
  94. 2 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ArchiveTreeController.java
  95. 208 9
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ExcelTabController.java
  96. 17 2
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/TextdictInfoController.java
  97. 2 2
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/WbsTreeController.java
  98. 4 4
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/WbsTreePrivateController.java
  99. 147 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/WbsTreeSynchronousRecordController.java
  100. 4 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/feign/ArchiveTreeContractImpl.java

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

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

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

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

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

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

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

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

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

@@ -0,0 +1,22 @@
+package org.springblade.business.dto;
+
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springblade.business.entity.PrivateStandard;
+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;
+}

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

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

@@ -0,0 +1,32 @@
+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.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)
+    @NotEmpty(message = "副连接id不能为空")
+    private List<Long> rightIds;
+}

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

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

@@ -1,6 +1,7 @@
 package org.springblade.business.dto;
 
 import io.swagger.annotations.ApiModelProperty;
+import io.swagger.models.auth.In;
 import lombok.Data;
 
 import java.io.Serializable;

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

@@ -26,4 +26,10 @@ public class TrialMaterialMobilizationDTO extends TrialMaterialMobilization {
     @ApiModelProperty("数据序号")
     private Integer dataNumber;
 
+    @ApiModelProperty("旧编号")
+    private String trialAutoNumber;
+
+    @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 trialAutoNumber;
+
+    @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;
+}

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

@@ -0,0 +1,58 @@
+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 standardInfoLeftId;
+
+    /**
+     * 规范基础信息关联副id
+     */
+    private Long standardInfoRightId;
+
+    /**
+     *  是否删除(0-正常,1-已删除)
+     */
+    private Integer isDeleted;
+
+    /**
+     *  创建时间
+     */
+    private Date createTime;
+
+    /**
+     *  创建人
+     */
+    private Long createUser;
+
+    /**
+     *  修改时间
+     */
+    private Date updateTime;
+
+    /**
+     *  修改人
+     */
+    private Long updateUser;
+
+
+}

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

@@ -0,0 +1,98 @@
+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
+     */
+    @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;
+
+}

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

@@ -0,0 +1,56 @@
+/*
+ *      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;
+	/**
+	* 来源主表的主键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;
+
+
+}

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

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

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

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

@@ -0,0 +1,22 @@
+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 = "关联元素副元素集合")
+    private List<StandardInfoPrivateJoin> privateJoins;
+}

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

@@ -0,0 +1,23 @@
+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 {
+    /**
+     * 副连接对象
+     */
+    @ApiModelProperty(value = "副连接对象集合")
+    private List<StandardInfo> 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;
+}

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

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

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

@@ -1,5 +1,8 @@
 package org.springblade.manager.entity;
 
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import io.swagger.annotations.ApiModelProperty;
@@ -23,8 +26,12 @@ public class WbsTreeContract extends BaseEntity {
      * 主键id
      */
     @ApiModelProperty(value = "主键id")
+    @TableId(value = "p_key_id", type = IdType.INPUT)
     private Long pKeyId;
 
+    @TableField
+    private Long id;
+
 
     @ApiModelProperty(value = "新节点Id")
     private Long pId;

+ 7 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/WbsTreePrivate.java

@@ -1,5 +1,8 @@
 package org.springblade.manager.entity;
 
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import io.swagger.annotations.ApiModelProperty;
@@ -20,9 +23,13 @@ public class WbsTreePrivate extends BaseEntity {
     /**
      * 主键
      */
+    @TableId(value = "p_key_id", type = IdType.INPUT)
     @JsonProperty(value = "pKeyId")
     private Long pKeyId;
 
+    @TableField
+    private Long id;
+
     @ApiModelProperty(value = "pid")
     private Long pId;
 

+ 142 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/WbsTreeSynchronousRecord.java

@@ -0,0 +1,142 @@
+package org.springblade.manager.entity;
+
+import com.baomidou.mybatisplus.annotation.FieldStrategy;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * WBS同步记录表
+ *
+ * @author LHB
+ * @TableName m_wbs_tree_synchronous_record
+ */
+@TableName(value = "m_wbs_tree_synchronous_record")
+@Data
+public class WbsTreeSynchronousRecord {
+    /**
+     * id111
+     */
+    @TableId
+    private Long id;
+
+    /**
+     * 项目id
+     */
+    private Long projectId;
+
+    /**
+     * 项目名称
+     */
+    private String projectName;
+
+
+    @TableField("`range`")
+    private Integer range;
+    /**
+     * 同步范围名称
+     */
+    private String rangeName;
+    /**
+     * 合同段范围 逗号拼接的编号 101.未填报 102.已填报-未上报 103.未上报 104.待审批 105.已审批
+     */
+    private String contractRange;
+    /**
+     * 合同段范围名称
+     */
+    private String contractRangeName;
+
+    /**
+     * 同步源Id
+     */
+    private Long templateId;
+
+    /**
+     * 同步源名称
+     */
+    private String templateName;
+
+    /**
+     * 同步类型 逗号拼接的编号 1.新增表单 2.清表配置 3.元素配置 4.电签配置 5.公式配置 6.默认值配置 7.表单排序
+     */
+    private String type;
+
+    /**
+     * 同步类型名称
+     */
+    private String typeName;
+
+    /**
+     * 同步节点id 多个节点
+     */
+    private String nodeId;
+
+    /**
+     * 同步节点名称
+     */
+    private String nodeName;
+    /**
+     * 表单Ids     range = 4 强制同步时  当前数据为同步源
+     */
+    private String formIds;
+    /**
+     * 同步节点数量
+     */
+    private Integer nodeNum;
+    /**
+     * 已同步数量
+     */
+    private Integer nodeNumEnd;
+
+    /**
+     * 是否删除(0-未删除,1-删除)
+     */
+    private Integer isDeleted;
+
+    /**
+     * 状态(0-未同步,1-正在同步,2-已同步,3-同步失败)
+     */
+    private Integer status;
+    /**
+     * 状态(0-未同步,1-正在同步,2-已同步,3-同步失败)
+     */
+    @TableField(exist = false)
+    private String statusName;
+    /**
+     * 错误信息
+     */
+    @TableField(updateStrategy = FieldStrategy.NOT_EMPTY)
+    private String errorMsg;
+    /**
+     * 创建时间
+     */
+    private Date createTime;
+
+    /**
+     * 创建人
+     */
+    private String createUser;
+
+    /**
+     * 创建人id
+     */
+    private Long createUserId;
+
+    /**
+     * 修改时间
+     */
+    private Date updateTime;
+
+    /**
+     * 修改人
+     */
+    private String updateUser;
+
+    /**
+     * 修改人id
+     */
+    private Long updateUserId;
+}

+ 55 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/enums/WbsSyncTypeEnum.java

@@ -0,0 +1,55 @@
+package org.springblade.manager.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import org.springblade.core.tool.utils.ObjectUtil;
+
+/**
+ * @author LHB
+ */
+@Getter
+@AllArgsConstructor
+public enum WbsSyncTypeEnum {
+    UNKNOWN(-1, ""),
+    INSERT_FORM(1, "新增表单"),
+    CLEAR_TABLE_CONFIG(2, "清表配置"),
+    ELEMENT_CONFIG(3, "元素配置"),
+    E_VISA_CONFIG(4, "电签配置"),
+    FORMULA_CONFIG(5, "公式配置"),
+    DEFAULT_VALUE_CONFIG(6, "默认值配置"),
+    FORM_SORT(7, "表单排序"),
+    /**
+     * 合同段同步范围
+     */
+    NOT_FILLED_IN(101, "未填报"),
+    ALREADY_FILLED_IN_NOT_REPORTED(102, "已填报-未上报"),
+    NOT_REPORTED(103, "未上报"),
+    PENDING_APPROVAL(104, "待审批"),
+    APPROVED(105, "已审批"),
+    ;
+
+    /**
+     * 编码
+     */
+    public Integer code;
+
+    /**
+     * 描述
+     */
+    private String desc;
+
+    /**
+     * 根据编码获取枚举描述
+     */
+    public static String getByCode(int code) {
+        // 判断code
+        if(ObjectUtil.isNotEmpty(code)){
+            for (StorageTypeEnum storageTypeEnum : StorageTypeEnum.values()) {
+                if (storageTypeEnum.getCode() == code) {
+                    return storageTypeEnum.getDesc();
+                }
+            }
+        }
+        return WbsSyncTypeEnum.UNKNOWN.getDesc();
+    }
+}

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

@@ -27,6 +27,9 @@ public interface ArchiveTreeContractClient {
     @PostMapping(API_PREFIX + "/getHavedFileNodeByProjectID")
     List<ArchiveTreeContract> getHavedFileNodeByProjectID(@RequestParam Long projectId);
 
+    @PostMapping(API_PREFIX + "/getTopAutoTypeNodeByProjectID")
+    List<ArchiveTreeContract> getTopAutoTypeNodeByProjectID(@RequestParam Long projectId);
+
     /**
      * 根据项目id获取所有数据
      */

+ 3 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/feign/WbsParamClient.java

@@ -2,6 +2,7 @@ package org.springblade.manager.feign;
 
 
 import org.springblade.manager.entity.WbsParam;
+import org.springblade.manager.entity.WbsTreeContract;
 import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PostMapping;
@@ -27,4 +28,6 @@ public interface WbsParamClient {
 
     @PostMapping(API_PREFIX + "/saveWbsParams")
     void saveWbsParams(@RequestBody List<WbsParam> wbsParamList);
+    @PostMapping(API_PREFIX + "/createFileTitle")
+    String createFileTitle(@RequestBody WbsTreeContract contract);
 }

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

@@ -133,4 +133,6 @@ public class WbsTreeContractLazyVO implements Serializable {
     @ApiModelProperty(value = "关联后管节点ID")
     private Long isTypePrivatePid;
 
+
+
 }

+ 27 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/WbsTreeSynchronousRecordVo.java

@@ -0,0 +1,27 @@
+package org.springblade.manager.vo;
+
+import lombok.Data;
+
+/**
+ *
+ * @author LHB
+ */
+@Data
+public class WbsTreeSynchronousRecordVo {
+    /**
+     * id
+     */
+    private Long id;
+    /**
+     * 项目名称
+     */
+    private String name;
+    /**
+     * wbsId
+     */
+    private String wbsId;
+    /**
+     * type = 1 公共  type = 2 私有
+     */
+    private Integer type;
+}

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

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

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

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

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

@@ -285,6 +285,22 @@
                 #{nodeId}
             </foreach>
         </if>
+        <if test="vo.queryValueSize != null and vo.queryValueSize != ''">
+            <choose>
+                <when test="vo.queryValueSize == 1">
+                    and CHAR_LENGTH(u.name) <![CDATA[ < ]]> 80
+                </when>
+                <when test="vo.queryValueSize == 2">
+                    and CHAR_LENGTH(u.name) >= 80 and CHAR_LENGTH(u.name) <![CDATA[ < ]]> 120
+                </when>
+                <when test="vo.queryValueSize == 3">
+                    and CHAR_LENGTH(u.name) >= 120 and CHAR_LENGTH(u.name) <![CDATA[ < ]]> 150
+                </when>
+                <when test="vo.queryValueSize == 4">
+                    and CHAR_LENGTH(u.name) >= 150
+                </when>
+            </choose>
+        </if>
         order by m.tree_sort,u.auto_file_sort is null ,u.auto_file_sort,u.file_number is null,
         SUBSTRING_INDEX(u.file_number, '_', 1), SUBSTRING_INDEX(u.file_number, '_', -1) + 0 ,u.create_time asc
         limit #{current}, #{size}
@@ -559,7 +575,7 @@
         select uaa.*
         from m_archive_tree_contract matc left join u_archives_auto uaa on matc.id = uaa.node_id left join
         u_archive_file uaf on uaa.id = uaf.archive_id
-        where uaa.is_deleted = 0 and uaa.is_archive = 1
+        where uaa.is_deleted = 0  and matc.is_deleted = 0 and uaa.is_archive = 1
             and matc.project_id = #{vo.projectId}
         <if test="vo.contractId != null and vo.contractId != ''">
             and uaa.contract_id = #{vo.contractId} and matc.contract_id = #{vo.contractId}
@@ -570,6 +586,13 @@
         <if test="vo.searchType == 2 and vo.queryValue != null and vo.queryValue != ''">
             and uaf.file_name like concat('%',#{vo.queryValue},'%')
         </if>
+        <if test="vo.searchType == 2 and vo.queryList != null and vo.queryList.size() > 0">
+            and (
+            <foreach collection="vo.queryList" item="queryItem" separator=" OR ">
+                uaf.file_name like concat('%',#{queryItem},'%')
+            </foreach>
+            )
+        </if>
         <if test="vo.storageTimes != null and vo.storageTimes != ''">
             and uaa.storage_time in
             <foreach collection="vo.storageTimes" item="storageTime" open="(" separator="," close=")">
@@ -607,7 +630,7 @@
     <select id="pageByArchivesAuto11" resultMap="archivesAutoResultMap">
         select uaa.*
         from m_archive_tree_contract matc left join u_archives_auto uaa on matc.id = uaa.node_id
-        where uaa.is_deleted = 0 and uaa.is_archive = 1
+        where uaa.is_deleted = 0 and matc.is_deleted = 0 and uaa.is_archive = 1
         <if test="vo.queryValue != null and vo.queryValue != ''">
             and (uaa.name like concat('%',#{vo.queryValue},'%') or uaa.file_number like concat('%',#{vo.queryValue},'%'))
         </if>
@@ -1370,7 +1393,7 @@
     <select id="getMetadaFileByFileIds" resultType="java.util.Map">
         SELECT id,file_id
         FROM u_metadata_file
-        WHERE file_id IN
+        WHERE  is_deleted=0 and file_id IN
         <foreach collection="fileIds" item="fileId" open="(" close=")" separator=",">
             #{fileId}
         </foreach>

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

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

+ 313 - 5
blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchivesAutoServiceImpl.java

@@ -573,7 +573,6 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 		if (test == 1) {
 			fixArchivesAutoFile(vo);
 		}
-
 		List<ArchivesAuto> pageList = this.baseMapper.selectArchivesAutoFilePage(current, vo.getSize(), vo);
 		//设置分页信息
 		iPage.setTotal(total);
@@ -813,6 +812,8 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 		//步list = {ArrayList@18238}  size = 19骤二:查询归档树节点。存在未归档文件的节点。
 		List<ArchiveTreeContract> list = archiveTreeContractClient.getHavedFileNodeByProjectID(projectId);
 
+		List<ArchiveTreeContract> listTop = archiveTreeContractClient.getTopAutoTypeNodeByProjectID(projectId);
+
 
 		if (nodeId != null) {
 			ArchiveTreeContract node = archiveTreeContractClient.getArchiveTreeContractById(nodeId);
@@ -856,7 +857,7 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 		archiveAutoMethod3(list3, boxMap, boxFileMap, traceId);//单独组卷
 		//设置完成度30%
 		projectClient.updateIsArchivesAutoById(projectId, 30);
-		archiveAutoMethod2(list2, projectId, boxMap, boxFileMap, traceId);//分类组卷
+		archiveAutoMethod2_new(list2, listTop,projectId, boxMap, boxFileMap, traceId);//分类组卷
 		//设置完成度50%
 		projectClient.updateIsArchivesAutoById(projectId, 50);
 		archiveAutoMethod1(list1, boxMap, boxFileMap, traceId);//默认组卷
@@ -1607,13 +1608,117 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 		}
 	}
 
+	private void archiveAutoMethod3(List<ArchiveTreeContract> list, Map<String, List<ArchiveFile>> boxMap,
+									Map<Long, String> boxFileMap, Long traceId) {
+		// 步骤1:遍历节点集合
+		for (ArchiveTreeContract node : list) {
+			// 步骤2:获取当前节点的案卷规格
+			String specificationStr = node.getSpecification();
+			if (StringUtils.isEmpty(specificationStr)) {
+				specificationStr = "30";
+			}
+			int specification = Integer.parseInt(specificationStr);
+			int specificationSize = specification * 10;
+
+			// 步骤3:查询节点下的未组卷文件
+			List<ArchiveFile> archiveFiles = archiveFileClient.getListByNodeID(node.getId().toString());
+			if (archiveFiles == null || archiveFiles.isEmpty()) {
+				continue;
+			}
+
+			// 记录节点文件数量日志
+			String completeMsg = "[自动组卷] 单独组卷:" + "-traceId:" + traceId + "节点:" + node.getNodeName() + " 文件数量:" + archiveFiles.size();
+			iTraceLogService.saveLog(traceId, completeMsg);
+
+			// 步骤4:遍历未归档文件
+			List<ArchiveFile> waitArchiveFiles = new ArrayList<>();  // 待组卷文件集合
+			int archivesSize = 0;  // 待组卷文件总页数
+			int archiveFilesSize = 0;
+
+			for (ArchiveFile file : archiveFiles) {
+				archiveFilesSize++;
+
+				// 步骤5:判断文件是否存在分盒设置
+				if (file.getBoxNumber() != null && file.getBoxNumber() != -1) {
+					// 添加到分盒文件集合
+					addBoxMap(file, boxMap, boxFileMap);
+
+					// 如果是最后一个文件且有待组卷文件,则组卷
+					if (archiveFilesSize == archiveFiles.size() && !waitArchiveFiles.isEmpty()) {
+						createArchive3(waitArchiveFiles, node, archivesSize);
+						waitArchiveFiles.clear();
+						archivesSize = 0;
+					}
+				} else {
+					// 非分盒文件处理
+					Integer filePage = file.getFilePage() != null ? file.getFilePage() : 0;
+
+					// 步骤6:检查规格状态
+					int tempTotalSize = archivesSize + filePage;
+					int checkStatus = checkSpecificationSize(specificationSize, tempTotalSize);
+
+					// 6.1 未到规格
+					if (checkStatus == 0) {
+						waitArchiveFiles.add(file);
+						archivesSize = tempTotalSize;
+
+						// 最后一个文件直接组卷
+						if (archiveFilesSize == archiveFiles.size()) {
+							createArchive3(waitArchiveFiles, node, archivesSize);
+							waitArchiveFiles.clear();
+							archivesSize = 0;
+						}
+					}
+					// 6.2 达到规格
+					else if (checkStatus == 1) {
+						waitArchiveFiles.add(file);
+						archivesSize = tempTotalSize;
+						createArchive3(waitArchiveFiles, node, archivesSize);
+
+						// 重置待组卷集合
+						waitArchiveFiles.clear();
+						archivesSize = 0;
+					}
+					// 6.3 超出规格
+					else if (checkStatus == -1) {
+						if (!waitArchiveFiles.isEmpty()) {
+							// 先将现有集合组卷(不含当前文件)
+							createArchive3(waitArchiveFiles, node, archivesSize);
+
+							// 新建集合存放当前文件
+							waitArchiveFiles.clear();
+							waitArchiveFiles.add(file);
+							archivesSize = filePage;
+
+							// 最后一个文件直接组卷
+							if (archiveFilesSize == archiveFiles.size()) {
+								createArchive3(waitArchiveFiles, node, archivesSize);
+								waitArchiveFiles.clear();
+								archivesSize = 0;
+							}
+						} else {
+							// 当前文件单独成卷
+							waitArchiveFiles.add(file);
+							archivesSize = filePage;
+							createArchive3(waitArchiveFiles, node, archivesSize);
+
+							// 重置集合
+							waitArchiveFiles.clear();
+							archivesSize = 0;
+						}
+					}
+				}
+			}
+		}
+	}
+
 	/**
-	 * 单租组卷流程  20230628 SBD又说单独组卷规则节点下只组一卷,不用满规格新组。这辈子没见过这样的人。
+	 * 单租组卷流程  20230628 SBD又说单独组卷规则节点下只组一卷,不用满规格新组。
 	 *
 	 * @param list
 	 * @param boxMap
 	 */
-	private void archiveAutoMethod3(List<ArchiveTreeContract> list, Map<String, List<ArchiveFile>> boxMap, Map<Long, String> boxFileMap, Long traceId) {
+	private void archiveAutoMethod3_1(List<ArchiveTreeContract> list, Map<String, List<ArchiveFile>> boxMap, Map<Long, String> boxFileMap, Long traceId) {
 		//步骤1:遍历节点集合
 		for (ArchiveTreeContract node : list) {
 			//步骤2:查询节点下的未组卷文件
@@ -1707,11 +1812,177 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 			Long archiveAutoGroupId = entry.getKey();
 			List<ArchiveFile> archiveFiles = entry.getValue();
 			//一个archiveAutoGroupId组成一个案卷  案卷归属同个key的归档树节点select=1的第一个groupId2NodeIdMap
-			createArchive2(archiveFiles, archiveAutoGroupId, projectId);
+			//createArchive2(archiveFiles, archiveAutoGroupId, projectId);
+
+			archiveAutoMethodGroup(archiveFiles, archiveAutoGroupId, projectId);
+		}
+
+	}
+
+
+	private void archiveAutoMethod2_new(List<ArchiveTreeContract> list, List<ArchiveTreeContract> topList, Long projectId,
+										Map<String, List<ArchiveFile>> boxMap, Map<Long, String> boxFileMap, Long traceId) {
+
+		// 分类并卷集合<groupId, List<文件>>
+		Map<Long, List<ArchiveFile>> archiveMap = new LinkedHashMap<>();
+		// 记录同个分组id对应的第一个节点ID(案卷归属节点)
+		Map<Long, Long> groupId2NodeIdMap = new HashMap<>();
+
+		// 当前处理的顶层节点ID
+		Long curTopId = null;
+		// 当前顶层节点对应的分组ID
+		Long currArchiveAutoGroupId = null;
+
+		// 步骤1:遍历节点集合
+		for (ArchiveTreeContract node : list) {
+			// 初始化当前节点的分组ID和顶层节点ID
+			Long archiveAutoGroupId = node.getArchiveAutoGroupId();
+			Long nodeTopId = 0L;
+
+			// 步骤2:查找当前节点的顶层节点ID
+			for (ArchiveTreeContract topNode : topList) {
+				Long topId = topNode.getId();
+				// 检查当前节点是否属于此顶层节点
+				if (node.getAncestors() != null &&
+						node.getAncestors().contains(topId.toString())) {
+					nodeTopId = topId;
+					break;
+				}
+			}
+
+			// 步骤3:确定当前节点的分组ID
+			if (curTopId != null && curTopId.equals(nodeTopId) && nodeTopId != 0) {
+				// 如果属于同一个非零顶层节点,使用之前的分组ID
+				archiveAutoGroupId = currArchiveAutoGroupId;
+			} else {
+				// 新顶层节点或没有顶层节点,更新当前分组信息
+				curTopId = nodeTopId;
+				currArchiveAutoGroupId = archiveAutoGroupId;
+			}
+
+			// 步骤4:查询节点下的未归档文件
+			List<ArchiveFile> archiveFiles = archiveFileClient.getListByNodeID(node.getId().toString());
+
+			if (archiveFiles != null && !archiveFiles.isEmpty()) {
+				// 记录日志(每个节点只记录一次)
+				String completeMsg = "[自动组卷] 分类组卷:" + "-traceId:" + traceId + "节点:" + node.getNodeName() + " 文件数量:" + archiveFiles.size();
+				iTraceLogService.saveLog(traceId, completeMsg);
+
+				// 步骤5:遍历未归档文件
+				for (ArchiveFile file : archiveFiles) {
+					// 步骤6:判断文件是否存在分盒设置
+					if (file.getBoxNumber() != null && file.getBoxNumber() != -1) {
+						// 添加到分盒文件集合
+						addBoxMap(file, boxMap, boxFileMap);
+					} else {
+						// 分类并卷流程
+						// 步骤7:将文件按照<groupId,List<文件>>放入集合
+						if (archiveMap.containsKey(archiveAutoGroupId)) {
+							List<ArchiveFile> groupList = archiveMap.get(archiveAutoGroupId);
+							groupList.add(file);
+						} else {
+							List<ArchiveFile> groupList = new ArrayList<>();
+							groupList.add(file);
+							archiveMap.put(archiveAutoGroupId, groupList);
+							groupId2NodeIdMap.put(archiveAutoGroupId, node.getId());
+						}
+					}
+				}
+			}
 		}
 
+		// 步骤8:按集合创建案卷
+		for (Map.Entry<Long, List<ArchiveFile>> entry : archiveMap.entrySet()) {
+			Long archiveAutoGroupId = entry.getKey();
+			List<ArchiveFile> archiveFiles = entry.getValue();
+
+			// 同一个分组ID下的文件分组组卷
+			archiveAutoMethodGroup(archiveFiles, archiveAutoGroupId, projectId);
+		}
 	}
 
+	private void archiveAutoMethodGroup(List<ArchiveFile> archiveFiles, Long archiveAutoGroupId, Long projectId) {
+		if (archiveFiles.size()==0) {
+			return;
+		}
+
+		// 获取分组规格(取第一个文件的节点规格作为分组规格)
+		int specificationSize = 300; // 默认规格(300页)
+		if (archiveFiles.get(0).getNodeId() != null) {
+			// 查询文件所在节点的规格
+			Long nodeId = Long.parseLong(archiveFiles.get(0).getNodeId());
+			ArchiveTreeContract node = archiveTreeContractClient.getArchiveTreeContractById(nodeId);
+			//ArchiveTreeContract node = archiveTreeClient.getNodeById(archiveFiles.get(0).getNodeId());
+			if (node != null && !StringUtils.isEmpty(node.getSpecification())) {
+				try {
+					specificationSize = Integer.parseInt(node.getSpecification()) * 10;
+				} catch (NumberFormatException e) {
+					// 规格格式错误时使用默认值
+					log.error("规格格式错误: {}", node.getSpecification(), e);
+				}
+			}
+		}
+
+		// 待组卷文件集合
+		List<ArchiveFile> waitArchiveFiles = new ArrayList<>();
+		// 待组卷文件总页数
+		int archivesSize = 0;
+
+		// 遍历文件列表
+		int fileIndex = 0;
+		int totalFiles = archiveFiles.size();
+
+		for (ArchiveFile file : archiveFiles) {
+			fileIndex++;
+			// 获取文件页数,处理null值
+			int filePage = file.getFilePage() != null ? file.getFilePage() : 0;
+
+			// 计算临时总页数
+			int tempTotalSize = archivesSize + filePage;
+
+			// 检查规格状态
+			int checkStatus = checkSpecificationSize(specificationSize, tempTotalSize);
+
+			// 处理不同检查状态
+			switch (checkStatus) {
+				case 0: // 未到规格
+					waitArchiveFiles.add(file);
+					archivesSize = tempTotalSize;
+					if (fileIndex == totalFiles) { // 是最后一个文件
+						createArchive2(waitArchiveFiles, archiveAutoGroupId, projectId);
+					}
+					break;
+
+				case 1: // 达到规格
+					waitArchiveFiles.add(file);
+					createArchive2(waitArchiveFiles, archiveAutoGroupId, projectId);
+					waitArchiveFiles = new ArrayList<>();
+					archivesSize = 0;
+					break;
+
+				case -1: // 超出规格
+					if (waitArchiveFiles.isEmpty()) {
+						// 当前文件单独成卷
+						createArchive2(Collections.singletonList(file), archiveAutoGroupId, projectId);
+					} else {
+						// 先将现有文件组卷
+						createArchive2(waitArchiveFiles, archiveAutoGroupId, projectId);
+
+						// 创建新的待组卷集合
+						waitArchiveFiles = new ArrayList<>();
+						waitArchiveFiles.add(file);
+						archivesSize = filePage;
+
+						if (fileIndex == totalFiles) { // 是最后一个文件
+							createArchive2(waitArchiveFiles, archiveAutoGroupId, projectId);
+						}
+					}
+					break;
+			}
+		}
+	}
+
+
 	/**
 	 * 默认组卷流程 文件可以跨节点组卷,受最高并卷节点限制范围,跨节点文件组卷时,案卷规格按照第一个文件所在的节点规格 组卷。
 	 */
@@ -2498,7 +2769,44 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 	 * @param nodeId               筛选条件:节点编号
 	 * @return 符合条件的档案列表
 	 */
+
 	public List<ArchiveTreeContract> archiveTreeContractFilterNum(List<ArchiveTreeContract> archiveTreeContracts, String treeCode, String nodeId, Long contractId) {
+		if (contractId == null) {
+			return archiveTreeContracts;
+		}
+
+		List<ArchiveTreeContract> result = new ArrayList<>();
+		for (ArchiveTreeContract contract : archiveTreeContracts) {
+			// 核心逻辑:nodeId不为空时必须满足祖先/ID条件
+			if (StringUtils.isNotEmpty(nodeId)) {
+				boolean matchesNode = (StringUtils.isNotEmpty(contract.getAncestors()) && contract.getAncestors().contains(nodeId))
+						|| contract.getId().toString().equals(nodeId);
+				if (!matchesNode) {
+					continue; // 不满足node条件直接跳过
+				}
+			}
+
+			// 根据treeCode决定额外条件
+			boolean isOwnerContract = StringUtils.isEmpty(treeCode); // 业主合同段标识
+			boolean passesOwnerCheck = contractId.toString().equals(contract.getTreeCode())
+					|| contractId.equals(contract.getContractId())
+					|| StringUtils.isEmpty(contract.getTreeCode());
+
+			if (isOwnerContract) {
+				// 业主合同段:仅需额外检查(nodeId为空时)
+				if (passesOwnerCheck) {
+					result.add(contract);
+				}
+			} else {
+				// 非业主合同段:treeCode匹配或额外检查
+				if (treeCode.equals(contract.getTreeCode()) || passesOwnerCheck) {
+					result.add(contract);
+				}
+			}
+		}
+		return result;
+	}
+	public List<ArchiveTreeContract> archiveTreeContractFilterNum1(List<ArchiveTreeContract> archiveTreeContracts, String treeCode, String nodeId, Long contractId) {
 		List<ArchiveTreeContract> result = new ArrayList<>();
 
 		if (contractId == null) {

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

@@ -293,7 +293,7 @@ public class FileUtils {
 
             for (String urlStr : urlList) {
                 try {
-                    if (urlStr.indexOf("https") >= 0 && urlStr.indexOf("aliyuncs") >= 0) {
+                    if (urlStr.indexOf("https") >= 0 && urlStr.indexOf("ctyun") >= 0) {
                         int lastIndexOf = urlStr.lastIndexOf("/");
                         String prefix = urlStr.substring(0, lastIndexOf + 1);
                         String suffix = urlStr.substring(lastIndexOf + 1);
@@ -516,7 +516,7 @@ public class FileUtils {
 
                     String fileNameWithoutExtension = fileNameWithExtension.substring(0, fileNameWithExtension.lastIndexOf("."));
 
-                    if (url.indexOf("https") >= 0 && url.indexOf("aliyuncs") >= 0) {
+                    if (url.indexOf("https") >= 0 && url.indexOf("ctyun") >= 0) {
                         int lastIndexOf = url.lastIndexOf("/");
                         String prefix = url.substring(0, lastIndexOf + 1);
                         String suffix = url.substring(lastIndexOf + 1);
@@ -661,7 +661,7 @@ public class FileUtils {
 
                     String fileNameWithoutExtension = fileNameWithExtension.substring(0, fileNameWithExtension.lastIndexOf("."));
 
-                    if (url.indexOf("https") >= 0 && url.indexOf("aliyuncs") >= 0) {
+                    if (url.indexOf("https") >= 0 && url.indexOf("ctyun") >= 0) {
                         int lastIndexOf = url.lastIndexOf("/");
                         String prefix = url.substring(0, lastIndexOf + 1);
                         String suffix = url.substring(lastIndexOf + 1);

+ 146 - 30
blade-service/blade-business/src/main/java/org/springblade/business/controller/InformationWriteQueryController.java

@@ -150,6 +150,7 @@ public class InformationWriteQueryController extends BladeController {
 
     private final IRecycleBinService recycleBinService;
 
+
     @Autowired
     StringRedisTemplate RedisTemplate;
 
@@ -200,7 +201,7 @@ public class InformationWriteQueryController extends BladeController {
             .map(Long::valueOf)
             .collect(Collectors.toList());
         List<InformationQuery> queryList = this.informationQueryService.list(Wrappers.<InformationQuery>lambdaQuery()
-            .select(InformationQuery::getId, InformationQuery::getName,InformationQuery::getProjectId,InformationQuery::getClassify,InformationQuery::getStatus).in(InformationQuery::getId, idList));
+            .select(InformationQuery::getId, InformationQuery::getName,InformationQuery::getProjectId,InformationQuery::getClassify,InformationQuery::getStatus,InformationQuery::getWbsId).in(InformationQuery::getId, idList));
         String sgSuffix="";
         String jlSuffix="";
         if(queryList.size()>0){
@@ -211,15 +212,23 @@ public class InformationWriteQueryController extends BladeController {
                 jlSuffix=projectInfos.get(0).getJlSuffix()==null?"":projectInfos.get(0).getJlSuffix();
             }
             for (InformationQuery query : queryList) {
-                if(query.getClassify()!=null&&query.getClassify()==1&&StringUtils.isNotEmpty(sgSuffix)){
-                   if(!query.getName().endsWith(sgSuffix)){
-                       query.setName(query.getName()+sgSuffix);
-                   }
-                }else if(query.getClassify()!=null&&query.getClassify()==2&&StringUtils.isNotEmpty(jlSuffix)){
-                    if(!query.getName().endsWith(jlSuffix)){
-                        query.setName(query.getName()+jlSuffix);
+                String sql="select * from m_wbs_tree_contract where p_key_id="+query.getWbsId()+" and is_deleted=0";
+                WbsTreeContract contract = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<>(WbsTreeContract.class));
+                  String result=wbsParamClient.createFileTitle(contract);
+                if(contract!=null&&contract.getMajorDataType()!=null&&contract.getMajorDataType()==4){
+                    if(query.getClassify()!=null&&query.getClassify()==1&&StringUtils.isNotEmpty(sgSuffix)){
+                        result=result+sgSuffix;
+                        if(!query.getName().equals(result)){
+                            query.setName(result);
+                        }
+                    }else if(query.getClassify()!=null&&query.getClassify()==2&&StringUtils.isNotEmpty(jlSuffix)){
+                        result=result+jlSuffix;
+                        if(!query.getName().equals(result)){
+                            query.setName(result);
+                        }
                     }
                 }
+                query.setName(result);
             }
         }
         List<InformationQuery> taskList = queryList.stream().filter(o -> o.getStatus() == 1 || o.getStatus() == 2).collect(Collectors.toList());
@@ -1992,13 +2001,20 @@ public R<Boolean> copyContractTreeNode(@RequestBody CopyContractTreeNodeVO vo) {
             }
 
             //TODO 20250414-lhb-新增 添加祖级字段 ancestorsPId
-            List<WbsTreeContract> contractWbsTreeByContractId = wbsTreeContractClient.getContractWbsTreeByContractId(Long.valueOf(needCopyNode.getContractId()));
-            contractWbsTreeByContractId.addAll(saveList);
-            Map<Long, WbsTreeContract> collect = contractWbsTreeByContractId.stream().collect(Collectors.toMap(WbsTreeContract::getPKeyId, Function.identity()));
-            saveList.forEach(node -> {
-                String correctAncestors = createAncestorsPId(node,collect);;
-                node.setAncestorsPId(correctAncestors);
-            });
+            //因为复制选中节点,所以要查询出选中节点的父节点信息 来组装祖级节点
+            if(needCopyNode != null){
+                Long parentPKeyId = null;
+                String ancestorsPId = null;
+                if(needCopyNode.getPId() == 0L){
+                    ancestorsPId = "0";
+                    parentPKeyId = 0L;
+                }else{
+                    WbsTreeContract parentNode = this.wbsTreeContractClient.getContractNodeByPrimaryKeyId(String.valueOf(needCopyNode.getPId()));
+                    ancestorsPId = parentNode.getAncestorsPId();
+                    parentPKeyId = parentNode.getPKeyId();
+                }
+                attachNodesToTarget(saveList,parentPKeyId,ancestorsPId);
+            }
         }
         needCopyNode.setNodeName(vo.getNeedCopyNodeName());
 
@@ -2166,6 +2182,26 @@ public R<Boolean> copyContractTreeNode(@RequestBody CopyContractTreeNodeVO vo) {
                                     this.addCopyTabData(needCopyNode, toCopyNode, tabOwner, resultTablesData, addTabList, vo.getIsCopyData(), addNewFileTabs);
                                 }
                             }
+
+
+                            /*重构祖级id*/
+                            List<WbsTreeContract> resultAll = new ArrayList<>();
+                            resultAll.addAll(addNodeList);
+                            resultAll.addAll(addTabList);
+                            //因为复制选中节点,所以要查询出选中节点的父节点信息 来组装祖级节点
+                            if(needCopyNode != null && CollectionUtil.isNotEmpty(resultAll)){
+                                Long parentPKeyId = null;
+                                String ancestorsPId = null;
+                                if(needCopyNode.getPId() == 0L){
+                                    ancestorsPId = "0";
+                                    parentPKeyId = 0L;
+                                }else{
+                                    WbsTreeContract parentNode = this.wbsTreeContractClient.getContractNodeByPrimaryKeyId(String.valueOf(toCopyVO.getPrimaryKeyId()));
+                                    ancestorsPId = parentNode.getAncestorsPId();
+                                    parentPKeyId = parentNode.getPKeyId();
+                                }
+                                attachNodesToTarget(resultAll,parentPKeyId,ancestorsPId);
+                            }
                         }
                     }
                 }
@@ -2175,14 +2211,6 @@ public R<Boolean> copyContractTreeNode(@RequestBody CopyContractTreeNodeVO vo) {
                 resultAll.addAll(addNodeList);
                 resultAll.addAll(addTabList);
 
-                //TODO 20250414-lhb-新增
-                List<WbsTreeContract> contractWbsTreeByContractId = wbsTreeContractClient.getContractWbsTreeByContractId(Long.valueOf(contractId));
-                contractWbsTreeByContractId.addAll(resultAll);
-                Map<Long, WbsTreeContract> collect = contractWbsTreeByContractId.stream().collect(Collectors.toMap(WbsTreeContract::getPKeyId, Function.identity()));
-                resultAll.forEach(node -> {
-                    String correctAncestors = createAncestorsPId(node,collect);;
-                    node.setAncestorsPId(correctAncestors);
-                });
 
                 List<WbsTreeContract> allData = this.reBuildAncestors(resultAll);
                 List<WbsTreeContract> nodes = allData.stream().filter(f -> f.getType().equals(1)).collect(Collectors.toList());
@@ -3917,13 +3945,7 @@ public R<Boolean> saveContractTreeNode(@RequestBody AddContractTreeNodeVO vo) {
             }
         }
         //TODO 20250414-lhb-新增 添加ancestorsPId字段
-        List<WbsTreeContract> contractWbsTreeByContractId = wbsTreeContractClient.getContractWbsTreeByContractId(Long.valueOf(treeContract.getContractId()));
-        contractWbsTreeByContractId.addAll(saveList);
-        Map<Long, WbsTreeContract> collect = contractWbsTreeByContractId.stream().collect(Collectors.toMap(WbsTreeContract::getPKeyId, Function.identity()));
-        saveList.forEach(node -> {
-            String correctAncestors = createAncestorsPId(node,collect);;
-            node.setAncestorsPId(correctAncestors);
-        });
+        attachNodesToTarget(saveList,treeContract.getPKeyId(),treeContract.getAncestorsPId());
 
         R<Boolean> booleanR = this.saveOrCopyNodeTree(saveList, saveLedger, 2, treeContract);
 
@@ -4833,4 +4855,98 @@ public R<Object> customAddContractNode(@RequestBody CustomAddContractNodeDTO dto
         }
     }
 
+    public void attachNodesToTarget(List<WbsTreeContract> newNodes, Long targetId, String targetAncestors) {
+        // 1. 找到新数据中的顶层节点(新树的根节点)
+        WbsTreeContract newRoot = findRootNode(newNodes);
+
+        // 2. 将新树的根节点绑定到目标节点
+        newRoot.setPId(targetId);
+        newRoot.setAncestorsPId(calculateAncestors(targetAncestors, targetId));
+
+        // 3. 构建映射关系
+        Map<Long, WbsTreeContract> nodeMap = new HashMap<>();
+        Map<Long, List<WbsTreeContract>> childrenMap = new HashMap<>();
+
+        for (WbsTreeContract node : newNodes) {
+            nodeMap.put(node.getPKeyId(), node);
+            childrenMap.computeIfAbsent(node.getPId(), k -> new ArrayList<>()).add(node);
+        }
+
+        // 4. 安全层序遍历(带循环检测)
+        safeBfsTraversal(newRoot, childrenMap, newNodes.size());
+    }
+
+    private void safeBfsTraversal(WbsTreeContract root,
+                                  Map<Long, List<WbsTreeContract>> childrenMap,
+                                  int totalNodes) {
+        Queue<WbsTreeContract> queue = new LinkedList<>();
+        Set<Long> visited = new HashSet<>();  // 已访问节点集合
+        queue.add(root);
+        visited.add(root.getPKeyId());
+
+        int processedCount = 0;  // 已处理节点计数器
+        final int MAX_DEPTH = 100;  // 最大深度保护
+
+        while (!queue.isEmpty()) {
+            WbsTreeContract parent = queue.poll();
+            processedCount++;
+
+            // 安全检测1:防止循环引用导致无限循环
+            if (processedCount > totalNodes * 2) {
+                throw new IllegalStateException("处理节点数超过预期,可能存在循环引用。已处理: "
+                        + processedCount + ",总节点: " + totalNodes);
+            }
+
+            // 安全检测2:防止路径过长
+            if (parent.getAncestorsPId().split(",").length > MAX_DEPTH) {
+                throw new IllegalStateException("祖级路径超过最大深度限制: " + MAX_DEPTH);
+            }
+
+            List<WbsTreeContract> children = childrenMap.get(parent.getPKeyId());
+            if (children == null) continue;
+
+            for (WbsTreeContract child : children) {
+                // 安全检测3:检查循环引用
+                if (visited.contains(child.getPKeyId())) {
+                    throw new IllegalStateException("检测到循环引用: 节点" + child.getPKeyId()
+                            + " -> 节点" + parent.getPKeyId());
+                }
+
+                // 更新祖级路径 = 父路径 + 父ID
+                child.setAncestorsPId(calculateAncestors(parent.getAncestorsPId(), parent.getPKeyId()));
+
+                queue.add(child);
+                visited.add(child.getPKeyId());
+            }
+        }
+
+        // 验证是否处理了所有节点
+        if (processedCount < totalNodes) {
+            throw new IllegalStateException("存在未处理的节点,可能是不连通的子树。已处理: "
+                    + processedCount + ",总节点: " + totalNodes);
+        }
+    }
+
+    private String calculateAncestors(String parentAncestors, Long parentId) {
+        if (parentAncestors == null || parentAncestors.isEmpty()) {
+            return parentId.toString();
+        }
+        return parentAncestors + "," + parentId;
+    }
+
+    private WbsTreeContract findRootNode(List<WbsTreeContract> nodes) {
+        Set<Long> nodeIds = new HashSet<>();
+        for (WbsTreeContract node : nodes) {
+            nodeIds.add(node.getPKeyId());
+        }
+
+        for (WbsTreeContract node : nodes) {
+            Long parentId = node.getPId();
+            // 父节点为空 或 父节点不在当前新数据列表中 → 视为根节点
+            if (parentId == null || !nodeIds.contains(parentId)) {
+                return node;
+            }
+        }
+        throw new IllegalArgumentException("新数据中未找到根节点");
+    }
 }

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

@@ -0,0 +1,152 @@
+package org.springblade.business.controller;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+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.service.PrivateStandardService;
+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.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;
+
+    /**
+     * 分页查询所有数据
+     *
+     * @param query               分页对象
+     * @param privateStandard 查询实体
+     * @return 所有数据
+     */
+    @GetMapping("page")
+    @ApiOperation(value = "分页查询所有数据", notes = "传入分页对象和高级查询对象")
+    public R<IPage<PrivateStandard>> selectAll(Query query, PrivateStandard privateStandard) {
+        try {
+            Page page = new Page(query.getCurrent(), query.getSize());
+            IPage<PrivateStandard> resultPage = this.privateStandardService.page(page, new QueryWrapper<>(privateStandard));
+            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<PrivateStandard> selectOne(Long id) {
+        PrivateStandard byId = this.privateStandardService.getById(id);
+        return R.data(byId);
+    }
+
+    /**
+     * 新增数据
+     *
+     * @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 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);
+    }
+}
+

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

@@ -0,0 +1,199 @@
+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.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<StandardInfoDtoVo>> selectAll(Query query, StandardInfo standardInfo) {
+        IPage<StandardInfoDtoVo> 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 条件设置对象
+     * @return 结果
+     */
+    @ApiOperation(value = "条件设置")
+    @PostMapping("saveConditionSet")
+    public R<Boolean> setCondition(@RequestBody @Validated List<StandardInfoJoinDTO> standardInfoJoins) {
+        Boolean b = this.uStandardInfoService.setCondition(standardInfoJoins);
+        return R.data(b);
+    }
+
+    /**
+     * 关联元素
+     *
+     * @param standardInfoPrivateJoins 关联元素对象
+     * @return 结果
+     */
+    @ApiOperation(value = "关联元素")
+    @PostMapping("saveElementJoin")
+    public R<Boolean> setElementJoin(@RequestBody @Validated List<StandardInfoPrivateJoinDTO> standardInfoPrivateJoins) {
+        Boolean b = this.uStandardInfoService.setElementJoin(standardInfoPrivateJoins);
+        return R.data(b);
+    }
+
+    /**
+     * 删除条件设置
+     * @param leftId 主关联id
+     * @return 删除结果
+     */
+    @ApiOperation(value = "删除条件设置")
+    @ApiImplicitParam(name = "leftId", value = "主关联id", required = true)
+    @GetMapping("deleteConditionSet")
+    public R<Boolean> deleteConditionSet(Long leftId) {
+        Boolean b = this.uStandardInfoService.deleteConditionSet(leftId);
+        return R.data(b);
+    }
+
+    /**
+     * 删除关联元素
+     * @param leftId 主关联id
+     * @return 删除结果
+     */
+    @ApiOperation(value = "删除关联元素")
+    @ApiImplicitParam(name = "leftId", value = "主关联id", required = true)
+    @GetMapping("deleteElementJoin")
+    public R<Boolean> deleteElementJoin(Long leftId) {
+        Boolean b = this.uStandardInfoService.deleteElementJoin(leftId);
+        return R.data(b);
+    }
+
+    /**
+     * 查询条件设置
+     * @param id 规范文件id
+     */
+    @ApiOperation(value = "查询条件设置")
+    @ApiImplicitParam(name = "id", value = "规范文件id", required = true)
+    @GetMapping("getConditionSet")
+    public R<List<StandardInfoVO>> getConditionSet(Long id) {
+        List<StandardInfoVO> list = this.uStandardInfoService.getConditionSet(id);
+        return R.data(list);
+    }
+
+    /**
+     * 查询关联元素
+     * @param id 规范文件id
+     */
+    @ApiOperation(value = "查询关联元素")
+    @ApiImplicitParam(name = "id", value = "规范文件id", required = true)
+    @GetMapping("getElementJoin")
+    public R<List<StandardInfoPrivateJoinVO>> getElementJoin(Long id) {
+        List<StandardInfoPrivateJoinVO> list = this.uStandardInfoService.getElementJoin(id);
+        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)));
+	}
+
+
+
+
+}

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

@@ -26,6 +26,7 @@ import org.springblade.core.boot.ctrl.BladeController;
 import org.springblade.core.mp.support.Condition;
 import org.springblade.core.mp.support.Query;
 import org.springblade.core.oss.model.BladeFile;
+import org.springblade.core.secure.BladeUser;
 import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.utils.BeanUtil;
 import org.springblade.core.tool.utils.Func;
@@ -180,6 +181,8 @@ public class TrialDetectionController extends BladeController {
         jdbcTemplate.execute(sql5);
         String sql6 = "delete from u_information_query where wbs_id in(" + ids + ") and type = 2";
         jdbcTemplate.execute(sql6);
+        String sql7="update u_trial_auto_number set is_deleted=0 where form_data_id in ("+ids+")";
+        jdbcTemplate.execute(sql7);
         return R.status(true);
     }
 

+ 3 - 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));
     }
 
@@ -153,8 +153,10 @@ public class TrialMaterialController extends BladeController {
         if(b){
             //删除关联表中的额数据
             String sqlForDelTrailSampleRecord = "delete from u_trial_sampling_record where sample_info_id in ("+ids+")";
+            String update="update u_trial_auto_number set is_deleted=1 where form_data_id in ("+ids+")";
             try {
                 jdbcTemplate.execute(sqlForDelTrailSampleRecord);
+                jdbcTemplate.update(update);
             } catch (DataAccessException e) {
                 log.error("删除关联表中的额数据失败", e);
                 throw new RuntimeException(e);

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

@@ -0,0 +1,250 @@
+/*
+ *      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.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.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;
+
+	/**
+	 * 详情
+	 */
+//	@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) {
+        Integer maxSort=trialNumberRuleMapper.selectMaxSort(trialNumberRule.getProjectId(),trialNumberRule.getContractId(),trialNumberRule.getType());
+        trialNumberRule.setSort(maxSort+1);
+        if(trialNumberRule.getContractId()==null||trialNumberRule.getContractId()==0L){
+            trialNumberRule.setStatus(1);
+        }else {
+            trialNumberRule.setStatus(2);
+        }
+        trialNumberRuleService.save(trialNumberRule);
+        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("/update")
+	@ApiOperationSupport(order = 5)
+	@ApiOperation(value = "修改", notes = "传入trialNumberRule")
+	public R<String> update(@Valid @RequestBody TrialNumberRule trialNumberRule) {
+        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);
+        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));
+        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));
+        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"));
+    }
+
+
+
+
+}

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

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

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

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

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

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

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

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

@@ -0,0 +1,31 @@
+<?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="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,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>

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

@@ -0,0 +1,36 @@
+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<StandardInfoDtoVo> selectMyPage(Page<StandardInfoDtoVo> page, @Param("query") StandardInfo standardInfo);
+
+    StandardInfoDTO selectMyOne(@Param("id") Long id);
+
+    List<StandardInfoVO> getConditionSet(@Param("id") Long id);
+
+    List<StandardInfoPrivateJoinVO> getElementJoin(@Param("id") Long id);
+
+    List<StandardInfoPrivateJoinVO> effectPreview(@Param("rightIds") List<Long> rightIds);
+}
+
+
+
+

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

@@ -0,0 +1,193 @@
+<?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.vo.StandardInfoDtoVo">
+        <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"/>
+        <result property="symbolName" column="symbolName"/>
+        <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"/>,concat(symbol,name) symbolName
+        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"/>,concat(symbol,name) symbolName
+        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"/>
+        <collection property="standardInfos" ofType="org.springblade.business.entity.StandardInfo" select="findByJoinLeftId" column="{leftId=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"/>
+        from
+            u_standard_info a
+            INNER JOIN u_standard_info_join b on a.id = b.standard_info_left_id and a.is_deleted = b.is_deleted
+        where
+            a.standard_id = #{id} and a.is_deleted = 0
+        GROUP BY
+            b.standard_info_left_id
+    </select>
+    <select id="findByJoinLeftId" resultType="org.springblade.business.entity.StandardInfo">
+        SELECT
+            <include refid="Base_Column_Join_List"/>, c.name parentName
+        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} and a.is_deleted = 0
+    </select>
+
+    <!-- ``````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````` -->
+
+    <resultMap id="BaseResultElementJoin" type="org.springblade.business.vo.StandardInfoPrivateJoinVO">
+        <id property="id" column="id"/>
+        <result property="name" column="name"/>
+        <result property="parentId" column="parent_id"/>
+        <result property="type" column="type"/>
+        <collection property="privateJoins" ofType="org.springblade.business.entity.StandardInfoPrivateJoin" select="findByPrivateJoinLeftId" column="{leftId=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"/>
+        from
+            u_standard_info a
+            INNER JOIN u_standard_info_private_join b on a.id = b.standard_info_id and a.is_deleted = b.is_deleted
+        where
+            a.standard_id = #{id} and a.is_deleted = 0
+        GROUP BY
+            b.standard_info_id
+    </select>
+
+    <select id="findByPrivateJoinLeftId" resultType="org.springblade.business.entity.StandardInfoPrivateJoin">
+        SELECT
+            <include refid="Base_Private_Column_List"/>,
+            b.node_name privateName
+        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}
+          AND a.is_deleted = 0
+    </select>
+    <select id="effectPreview" resultMap="BaseResultElementJoin">
+        SELECT
+            a.*
+        FROM
+            u_standard_info a
+                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
+            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
+    </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_number_rule set is_deleted=0 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/IFixedFlowLinkService.java

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

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

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

@@ -0,0 +1,55 @@
+/*
+ *      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);
+
+
+    Map<String, String> getEntrustNumber(Long pkeyId,Long contractId) throws FileNotFoundException;
+}

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

@@ -5,6 +5,7 @@ import org.springblade.business.dto.*;
 import org.springblade.business.entity.TrialSelfInspectionRecord;
 import org.springblade.business.vo.*;
 import org.springblade.core.mp.base.BaseService;
+import org.springblade.core.secure.BladeUser;
 import org.springblade.core.tool.api.R;
 import org.springframework.web.multipart.MultipartFile;
 

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

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

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

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

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

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

@@ -42,7 +42,7 @@ public class ArchiveFileServiceImpl extends BaseServiceImpl<ArchiveFileMapper, A
 
     private ExecutorService executorService;
     private final ArchiveInspectionInfoClient archiveInspectionInfoClient;
-    private final JdbcTemplate   jdbcTemplate;
+    private final JdbcTemplate  jdbcTemplate;
 
 
     @Override

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

@@ -34,6 +34,7 @@ import org.springblade.business.vo.LoadDataInfoVO;
 import org.springblade.business.vo.TrialSampleDataInfoVO;
 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.utils.SecureUtil;
 import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.utils.Func;
@@ -68,6 +69,8 @@ public class EntrustInfoServiceImpl extends BaseServiceImpl<EntrustInfoMapper, E
 	private final EntrustInfoMapper entrustInfoMapper;
     private final IInformationQueryService informationQueryService;
 	private final OperationLogClient operationLogClient;
+    private final TrialNumberRuleServiceImpl trialNumberRuleService;
+    private final BladeRedis bladeRedis;
 
     @Override
 	public IPage<EntrustInfoVO> selectEntrustInfoPage(IPage<EntrustInfoVO> page, EntrustInfoVO entrustInfo) {
@@ -194,6 +197,15 @@ public class EntrustInfoServiceImpl extends BaseServiceImpl<EntrustInfoMapper, E
             entrustInfo.setId(Long.parseLong(dataInfo.get("id").toString()));
         }
         this.saveOrUpdate(entrustInfo);
+        String autoIncrementNumber=dataInfo.get("autoIncrementNumber")==null?"":dataInfo.get("autoIncrementNumber").toString();
+        String trialAutoNumber=dataInfo.get("trialAutoNumber")==null?"":dataInfo.get("trialAutoNumber").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())){
@@ -203,6 +215,8 @@ public class EntrustInfoServiceImpl extends BaseServiceImpl<EntrustInfoMapper, E
             entrustInfo.setEntrustName("");
         }
         dataInfo.put("entrustInfoName",entrustInfo.getEntrustNo()+entrustInfo.getEntrustName());
+        dataInfo.remove("autoIncrementNumber");
+        dataInfo.remove("trialAutoNumber");
         String pdfUrl = excelTabClient.saveEntrustTabData(dataInfo);
         return R.data(200,pdfUrl,"操作成功");
 	}

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

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

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

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

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

@@ -0,0 +1,212 @@
+package org.springblade.business.service.impl;
+
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springblade.business.entity.StandardFile;
+import org.springblade.business.service.StandardFileService;
+import org.springblade.business.dto.PrivateStandardDTO;
+import org.springblade.business.entity.PrivateStandard;
+import org.springblade.business.entity.StandardInfo;
+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.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @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;
+
+
+
+                    //Oss上传 传特殊文件名 在oss中做特殊路径处理
+                    BladeFile bladeFile = this.newIOSSClient.uploadFileByInputStream2(file.getOriginalFilename(), file.getInputStream());
+
+                    standardFile.setStandardFileUrl(bladeFile.getLink());
+                    standardFiles.add(standardFile);
+                }
+            } catch (Exception e) {
+                //删除之前上传的文件
+                for (StandardFile standardFile : standardFiles) {
+                    this.newIOSSClient.removeFile(standardFile.getStandardFileUrl());
+                }
+                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) {
+            List<StandardFile> standardFiles = new ArrayList<>();
+            MultipartFile[] files = privateStandard.getFiles();
+
+            try {
+                for (MultipartFile file : files) {
+                    StandardFile standardFile = new StandardFile();
+                    standardFile.setId(SnowFlakeUtil.getId());
+                    standardFile.setStandardId(privateStandard.getId());
+                    standardFile.setCreateUser(user.getUserId());
+
+
+                    String originalFilename = file.getOriginalFilename();
+                    standardFile.setFileName(originalFilename);
+                    originalFilename = "standard/" + privateStandard.getId() + "|" + originalFilename;
+
+                    //Oss上传 传特殊文件名 在oss中做特殊路径处理
+                    BladeFile bladeFile = this.newIOSSClient.uploadFileByInputStream2(originalFilename, file.getInputStream());
+
+                    standardFile.setStandardFileUrl(bladeFile.getLink());
+                    standardFiles.add(standardFile);
+                }
+            } catch (Exception e) {
+                //删除之前上传的文件
+                for (StandardFile standardFile : standardFiles) {
+                    this.newIOSSClient.removeFile(standardFile.getStandardFileUrl());
+                }
+                e.printStackTrace();
+                throw new ServiceException("文件上传失败!请检查Oss");
+            }
+
+            standardFileService.saveBatch(standardFiles);
+
+
+            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();
+            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)
+            );
+            //TODO 后续还要删除规范详细信息
+
+
+            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 {
+                this.newIOSSClient.removeFile(byId.getStandardFileUrl());
+            } 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;
+    }
+}
+
+
+
+

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

+ 17 - 6
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TrialMaterialMobilizationServiceImpl.java

@@ -11,10 +11,6 @@ import com.lowagie.text.pdf.BaseFont;
 import com.lowagie.text.pdf.PdfPTable;
 import com.lowagie.text.pdf.PdfWriter;
 import lombok.AllArgsConstructor;
-import org.apache.commons.fileupload.disk.DiskFileItem;
-import org.apache.commons.fileupload.disk.DiskFileItemFactory;
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang.time.DateUtils;
 import org.springblade.business.dto.TrialMaterialMobilizationDTO;
@@ -37,6 +33,7 @@ import org.springblade.core.log.exception.ServiceException;
 import org.springblade.core.mp.base.BaseServiceImpl;
 import org.springblade.core.mp.support.Condition;
 import org.springblade.core.oss.model.BladeFile;
+import org.springblade.core.redis.cache.BladeRedis;
 import org.springblade.core.secure.utils.SecureUtil;
 import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.utils.*;
@@ -72,6 +69,8 @@ public class TrialMaterialMobilizationServiceImpl extends BaseServiceImpl<TrialM
     private final NewIOSSClient newIOSSClient;
     private final JdbcTemplate jdbcTemplate;
     private final CommonFileClient commonFileClient;
+    private final TrialNumberRuleServiceImpl trialNumberRuleService;
+    private final BladeRedis bladeRedis;
 
     @Override
     public boolean mobilizationVerification(String number, String id, String contractId) {
@@ -92,12 +91,20 @@ 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("获取用户信息失败");
         }
         obj.setUserId(SecureUtil.getUserId());
-        return this.saveOrUpdate(obj);
+        this.saveOrUpdate(obj);
+        if(StringUtils.isNotEmpty(obj.getAutoIncrementNumber())){
+            if(obj.getTrialAutoNumber().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
@@ -485,6 +492,10 @@ public class TrialMaterialMobilizationServiceImpl extends BaseServiceImpl<TrialM
             return R.fail("所选数据均存在取样记录,不允许删除");
         }
         boolean b = super.deleteLogic(newIdList);
+        if(b){
+          String update="update u_trial_auto_number set is_deleted=1 where form_data_id in ("+ids+")";
+          jdbcTemplate.update(update);
+        }
         return  b?R.success("删除成功"):R.fail("删除失败");
     }
 }

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

@@ -0,0 +1,357 @@
+/*
+ *      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.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));
+        }
+        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);
+                }else {
+                    trialNumber.append("合同段编号");
+                }
+            } 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);
+                }
+            } 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(rule.getIsAutoIncrement()!=null&&rule.getIsAutoIncrement()==1){
+                    String autoIncrementNumber="";
+                    //如果是需要自增的 先要查出当前数据库中自增编号的最大值
+
+                    String sql3 = "SELECT auto_increment_number FROM u_trial_auto_number where type="+type+" 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 rule.getData();
+                        }
+                    });
+                    String sql4="select auto_increment_number FROM u_trial_auto_number where type="+type+" 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,30 * 60 * 1000L);
+                      }
+                    map.put("autoIncrementNumber",autoIncrementNumber);
+                    trialNumber.append(autoIncrementNumber);
+                }
+                else {
+                    map.put("autoIncrementNumber","");
+                    trialNumber.append(rule.getData());
+                }
+            }
+        }
+        map.put("trialNumber",trialNumber.toString());
+        return map;
+    }
+
+    public String incrementFormattedNumberWithCheck(String data) {
+        if (data == null || data.isEmpty()) {
+            return "0";
+        }
+
+        int length = data.length();
+        int number = Integer.parseInt(data);
+        number += 1;
+
+        // 检查自增后的数字位数是否超过原始数据的长度
+        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 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!=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);
+        }
+        return true;
+    }
+
+    @Override
+    public Map<String, String> getEntrustNumber(Long pkeyId,Long contractId) throws FileNotFoundException {
+        // 合同段信息
+        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, pkeyId, true);
+            map.put(key,map.get("trialNumber"));
+            return map;
+        }
+        return null;
+    }
+
+
+    public void checkSave(Long contractId,Integer 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, 4));
+                    if(one==null){
+                        TrialAutoNumber trialAutoNumber = new TrialAutoNumber();
+                        trialAutoNumber.setId(SnowFlakeUtil.getId());
+                        trialAutoNumber.setType(type);
+                        trialAutoNumber.setNumberRuleId(collect.get(0).getId());
+                        trialAutoNumber.setFormDataId(formDataId);
+                        trialAutoNumber.setAutoIncrementNumber(autoNumber);
+                        trialAutoNumberService.save(trialAutoNumber);
+                    }
+                }
+            }
+    }
+
+}

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

@@ -37,6 +37,7 @@ import org.springblade.core.log.exception.ServiceException;
 import org.springblade.core.mp.base.BaseServiceImpl;
 import org.springblade.core.mp.support.Condition;
 import org.springblade.core.oss.model.BladeFile;
+import org.springblade.core.redis.cache.BladeRedis;
 import org.springblade.core.secure.utils.SecureUtil;
 import org.springblade.core.tool.utils.*;
 import org.springblade.resource.feign.NewIOSSClient;
@@ -65,6 +66,8 @@ public class TrialSampleInfoServiceImpl extends BaseServiceImpl<TrialSampleInfoM
     private final TrialSamplingRecordMapper trialSamplingRecordMapper;
     private final JdbcTemplate jdbcTemplate;
     private final IEntrustInfoService entrustInfoService;
+    private final TrialNumberRuleServiceImpl trialNumberRuleService;
+    private final BladeRedis bladeRedis;
 
     @Override
     public boolean sampleVerification(String specificationNumber, String id, String contractId, String nodeId) {
@@ -133,10 +136,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())) {
@@ -146,6 +148,12 @@ public class TrialSampleInfoServiceImpl extends BaseServiceImpl<TrialSampleInfoM
                 trialSampleInfo.setRepresentativeCount("0");
             }
             this.saveOrUpdate(trialSampleInfo);
+            if(StringUtils.isNotEmpty(obj.getAutoIncrementNumber())){
+                if(obj.getTrialAutoNumber().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());

+ 45 - 14
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TrialSelfInspectionRecordServiceImpl.java

@@ -39,6 +39,8 @@ import org.springblade.core.log.exception.ServiceException;
 import org.springblade.core.mp.base.BaseServiceImpl;
 import org.springblade.core.mp.support.Condition;
 import org.springblade.core.oss.model.BladeFile;
+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.*;
 import org.springblade.manager.entity.*;
@@ -92,7 +94,9 @@ public class TrialSelfInspectionRecordServiceImpl extends BaseServiceImpl<TrialS
     private final TrialDeviceUseServiceImpl trialDeviceUseService;
     private final InformationQueryServiceImpl informationQueryService;
     private final TrialDetectionDataServiceImpl trialDetectionDataService;
-    private final IEntrustInfoService entrustInfoService;
+    private final BladeRedis bladeRedis;
+    private final TrialAutoNumberServiceImpl trialAutoNumberService;
+    private final TrialNumberRuleServiceImpl trialNumberRuleService;
 
     @Override
     public IPage<TrialSelfInspectionRecordVO> selfPage(IPage<TrialSelfInspectionRecord> page, TrialSelfInspectionRecordPageDTO dto) throws FileNotFoundException {
@@ -1087,21 +1091,21 @@ public class TrialSelfInspectionRecordServiceImpl extends BaseServiceImpl<TrialS
         //------初始当前填报的表pKeyIds------
         this.initTrialTabIds(dto);
 
-        if(!this.judgingParameters(dto)){
-            //------初始编号信息------
-            this.initBuildNumber(dto);
-        }
+//        if(!this.judgingParameters(dto)){
+//            //------初始编号信息------
+//            this.initBuildNumber(dto);
+//        }
         this.saveOrUpdate(dto);
+
         if (ObjectUtil.isNotEmpty(dto.getId())) {
             //------获取最新试验记录------
             TrialSelfInspectionRecord obj = baseMapper.selectById(dto.getId());
             //如果传递了编号就修改对应记录的值 以第一张表的数据为准
             this.updateRecordNoOrReportNo(obj, dto);
             //------编辑时记录表编号或报告单编号为Null的重新生成------
-            if(!this.judgingParameters(dto)){
-                this.reBuildNumber(obj, dto);
-            }
-
+//            if(!this.judgingParameters(dto)){
+//                this.reBuildNumber(obj, dto);
+//            }
             //------保存实体表数据、试验记录信息、生成PDF------
             this.submitTrialData(obj, dto);
 
@@ -1114,12 +1118,34 @@ public class TrialSelfInspectionRecordServiceImpl extends BaseServiceImpl<TrialS
             //------关联新增设备使用记录信息------
             this.trialDeviceUseService.addDeviceUseInfo(dto);
         }
-
         // ---- 修改样品单号信息 --------
         if(dto!=null && Func.isNotEmpty(dto.getEntrustId())){
             //修改项目节点基础信息
             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")){
+                        trialNumberRuleService.checkSave(Long.valueOf(dto.getProjectId()),4,dto.getId(),dto.getRecordAutoNumber());
+                    }else {
+                        trialNumberRuleService.checkSave(Long.valueOf(dto.getProjectId()),5,dto.getId(),dto.getReportAutoNumber());
+                    }
+                }else {
+                    trialNumberRuleService.checkSave(Long.valueOf(dto.getProjectId()),4,dto.getId(),dto.getRecordAutoNumber());
+                    trialNumberRuleService.checkSave(Long.valueOf(dto.getProjectId()),5,dto.getId(),dto.getReportAutoNumber());
+                }
+            }
+            if(strings.length==1&&strings[0].equals("1")){
+                bladeRedis.del("trialAutoNumber:" + dto.getContractId() + ":" + 4 + ":" + dto.getId() + ":" + "lock:" + dto.getRecordAutoNumber());
+            }else if(strings.length==1&&strings[0].equals("2")){
+                bladeRedis.del("trialAutoNumber:" + dto.getContractId() + ":" + 5 + ":" + dto.getId() + ":" + "lock:" + dto.getReportAutoNumber());
+            }else {
+                bladeRedis.del("trialAutoNumber:" + dto.getContractId() + ":" + 4 + ":" + dto.getId() + ":" + "lock:" + dto.getRecordAutoNumber());
+                bladeRedis.del("trialAutoNumber:" + dto.getContractId() + ":" + 5 + ":" + dto.getId() + ":" + "lock:" + dto.getReportAutoNumber());
+            }
+        }
         return dto.getId().toString();
     }
 
@@ -1895,11 +1921,16 @@ public class TrialSelfInspectionRecordServiceImpl extends BaseServiceImpl<TrialS
 
                     //自检pdf
                     List<TrialSelfInspectionRecord> trialSelfInspectionRecords = baseMapper.selectList(Wrappers.<TrialSelfInspectionRecord>lambdaQuery()
-                            .select(TrialSelfInspectionRecord::getPdfUrl)
+                            .select(TrialSelfInspectionRecord::getPdfUrl,TrialSelfInspectionRecord::getContractId,TrialSelfInspectionRecord::getId,TrialSelfInspectionRecord::getType)
                             .in(TrialSelfInspectionRecord::getId, Func.toLongList(dto.getIds())));
-                    List<String> pdfURLs = trialSelfInspectionRecords.stream().map(TrialSelfInspectionRecord::getPdfUrl).collect(Collectors.toList());
-                    pdfList.addAll(pdfURLs);
-
+                    if(trialSelfInspectionRecords.size()>0){
+                        for (TrialSelfInspectionRecord record : trialSelfInspectionRecords) {
+                            String pdf = this.getMergePdfToTrialNew(record.getContractId(), record.getId(), record.getType());
+                            pdfList.add(pdf);
+                        }
+                    }
+//                    List<String> pdfURLs = trialSelfInspectionRecords.stream().map(TrialSelfInspectionRecord::getPdfUrl).collect(Collectors.toList());
+//                    pdfList.addAll(pdfURLs);
                     //------第三方、外委------
                 } else if (dto.getType().equals(2) || dto.getType().equals(3)) {
                     if (informationQuery.getPdfTrialUrl() != null) {

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

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

@@ -0,0 +1,270 @@
+package org.springblade.business.service.impl;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+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.StandardInfoDtoVo;
+import org.springblade.business.vo.StandardInfoPrivateJoinVO;
+import org.springblade.business.vo.StandardInfoVO;
+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.springframework.beans.BeansException;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+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<StandardInfoDtoVo> selectMyPage(Query query, StandardInfo standardInfo) {
+        return baseMapper.selectMyPage(new Page<StandardInfoDtoVo>(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<StandardInfoJoinDTO> standardInfoJoins) {
+        BladeUser user = SecureUtil.getUser();
+        List<StandardInfoJoin> saveData = new ArrayList<>();
+        try {
+            for (StandardInfoJoinDTO standardInfoJoin : standardInfoJoins) {
+                Long leftId = standardInfoJoin.getLeftId();
+                List<Long> rightIds = standardInfoJoin.getRightIds();
+                for (Long rightId : rightIds) {
+                    StandardInfoJoin uStandardInfoJoin = new StandardInfoJoin();
+                    uStandardInfoJoin.setId(SnowFlakeUtil.getId());
+                    uStandardInfoJoin.setStandardInfoLeftId(leftId);
+                    uStandardInfoJoin.setStandardInfoRightId(rightId);
+                    uStandardInfoJoin.setCreateUser(user.getUserId());
+                    saveData.add(uStandardInfoJoin);
+                }
+                //先删除之前的关联关系
+                standardInfoJoinService.remove(Wrappers.<StandardInfoJoin>lambdaQuery()
+                        .eq(StandardInfoJoin::getStandardInfoLeftId,leftId));
+            }
+            //新增
+            return standardInfoJoinService.saveBatch(saveData);
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new ServiceException("条件设置失败");
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean setElementJoin(List<StandardInfoPrivateJoinDTO> standardInfoPrivateJoins) {
+        BladeUser user = SecureUtil.getUser();
+        List<StandardInfoPrivateJoin> saveData = new ArrayList<>();
+
+        try {
+            for (StandardInfoPrivateJoinDTO standardInfoPrivateJoin : standardInfoPrivateJoins) {
+                Long leftId = standardInfoPrivateJoin.getLeftId();
+                List<StandardInfoPrivateJoin> rightIds = standardInfoPrivateJoin.getRightIds();
+                rightIds.forEach(f -> {
+                    f.setId(SnowFlakeUtil.getId());
+                    f.setStandardInfoId(leftId);
+                    f.setCreateUser(user.getUserId());
+                });
+                saveData.addAll(rightIds);
+                //删除之前的关联关系
+                standardInfoPrivateJoinService.remove(Wrappers.<StandardInfoPrivateJoin>lambdaQuery()
+                        .eq(StandardInfoPrivateJoin::getStandardInfoId,leftId));
+            }
+            return standardInfoPrivateJoinService.saveBatch(saveData);
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new ServiceException("元素关联失败");
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean deleteConditionSet(Long leftId) {
+        BladeUser user = SecureUtil.getUser();
+        try {
+            return standardInfoJoinService.update(Wrappers.<StandardInfoJoin>lambdaUpdate()
+                    .set(StandardInfoJoin::getIsDeleted, 1)
+                    .set(StandardInfoJoin::getUpdateUser, user.getUserId())
+                    .eq(StandardInfoJoin::getStandardInfoLeftId, leftId));
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new ServiceException("删除失败");
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean deleteElementJoin(Long leftId) {
+        BladeUser user = SecureUtil.getUser();
+        try {
+            return standardInfoPrivateJoinService.update(Wrappers.<StandardInfoPrivateJoin>lambdaUpdate()
+                    .set(StandardInfoPrivateJoin::getIsDeleted, 1)
+                    .set(StandardInfoPrivateJoin::getUpdateUser, user.getUserId())
+                    .eq(StandardInfoPrivateJoin::getStandardInfoId, leftId));
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new ServiceException("删除失败");
+        }
+    }
+
+    @Override
+    public List<StandardInfoVO> getConditionSet(Long id) {
+        return baseMapper.getConditionSet(id);
+    }
+
+    @Override
+    public List<StandardInfoPrivateJoinVO> getElementJoin(Long id) {
+        return baseMapper.getElementJoin(id);
+
+    }
+
+    @Override
+    public List<StandardInfoPrivateJoinVO> effectPreview(String ids) {
+        List<Long> collect = Arrays.stream(ids.split(",")).map(Long::parseLong).collect(Collectors.toList());
+        return baseMapper.effectPreview(collect);
+    }
+}
+
+
+
+

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

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

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

@@ -17,11 +17,13 @@ import org.springblade.core.tool.utils.Func;
 import org.springblade.manager.dto.ArchiveTreeContractAutoRuleMapDTO;
 import org.springblade.manager.dto.ArchiveTreeDTO;
 import org.springblade.manager.dto.ArchiveTreeSortDTO;
+import org.springblade.manager.entity.WbsTree;
 import org.springblade.manager.service.IArchiveTreeContractService;
 import org.springblade.manager.vo.ArchiveTreeVO2;
 import org.springblade.manager.vo.ArchiveTreeVO3;
 import org.springframework.jdbc.core.BeanPropertyRowMapper;
 import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springblade.manager.entity.ArchiveTree;

+ 208 - 9
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ExcelTabController.java

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

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

@@ -113,7 +113,9 @@ public class TextdictInfoController extends BladeController {
     @ApiOperationSupport(order = 3)
     @ApiOperation(value = "分页", notes = "传入textdictInfo")
     public R<IPage<TextdictInfoVO>> page(TextdictInfoVO textdictInfo, Query query) {
-
+        if(textdictInfo.getType() == 4){
+            return R.data(textdictInfoService.analysisHtmlDefault(textdictInfo.getTabId()));
+        }
         IPage<TextdictInfoVO> pages = textdictInfoService.selectTextdictInfoPage(Condition.getPage(query), textdictInfo);
         return R.data(pages);
     }
@@ -155,7 +157,15 @@ public class TextdictInfoController extends BladeController {
     @PostMapping("/remove")
     @ApiOperationSupport(order = 7)
     @ApiOperation(value = "逻辑删除", notes = "传入ids")
-    public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids,@ApiParam(value = "wbs p_key_id", required = true) @RequestParam String tabId) throws FileNotFoundException {
+    public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids,
+                    @ApiParam(value = "wbs p_key_id", required = true) @RequestParam String tabId,
+                    String colKey,
+                    Integer type) throws FileNotFoundException {
+        if(type != null && type == 4){
+            textdictInfoService.removeHtmlDefault(tabId,colKey);
+            return R.success("删除成功");
+        }
+
         //获取节点信息
 
         WbsTreePrivate wbsTreePrivate = wbsTreePrivateMapper.getByPKeyId(Long.parseLong(tabId));
@@ -559,6 +569,11 @@ public class TextdictInfoController extends BladeController {
     @ApiOperationSupport(order = 7)
     @ApiOperation(value = "保存默认值", notes = "保存默认值")
     public R<String> saveDefaulVal(@Valid @RequestBody TextdictBy345VO textdictInfo) throws Exception {
+        if(textdictInfo.getType() == 4){
+            textdictInfoService.saveHtmlDefault(textdictInfo);
+            return R.success("操作成功");
+        }
+
 
         //当前清表信息
         WbsTreePrivate wbsTreePrivate = wbsTreePrivateMapper.getByPKeyId(textdictInfo.getTableId());

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

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

+ 4 - 4
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/WbsTreePrivateController.java

@@ -980,8 +980,8 @@ public class WbsTreePrivateController extends BladeController {
     public String getNameRuleV(String string){
         // 定义工程名称到C格式的映射
         Map<String, String> mapping = new HashMap<>();
-        mapping.put("单位工程", "C0");
-        mapping.put("单位工程", "C1");
+        mapping.put("单位工程类型", "C0");
+        mapping.put("单位工程", "C1");
         mapping.put("分部工程", "C2");
         mapping.put("子分部工程", "C3");
         mapping.put("分项工程", "C4");
@@ -1002,8 +1002,8 @@ public class WbsTreePrivateController extends BladeController {
     public String getNameRuleV1(String string){
         // 定义工程名称到C格式的映射
         Map<String, String> mapping = new HashMap<>();
-        mapping.put("C0", "单位工程");
-        mapping.put("C1", "单位工程");
+        mapping.put("C0", "单位工程类型");
+        mapping.put("C1", "单位工程");
         mapping.put("C2", "分部工程");
         mapping.put("C3", "子分部工程");
         mapping.put("C4", "分项工程");

+ 147 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/WbsTreeSynchronousRecordController.java

@@ -0,0 +1,147 @@
+package org.springblade.manager.controller;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import org.springblade.core.tool.utils.StringUtil;
+import org.springblade.manager.entity.ProjectInfo;
+import org.springblade.manager.entity.WbsTreePrivate;
+import org.springblade.manager.entity.WbsTreeSynchronousRecord;
+import org.springblade.manager.service.WbsTreeSynchronousRecordService;
+import org.springblade.core.mp.support.Condition;
+import org.springblade.core.mp.support.Query;
+import org.springblade.core.tool.api.R;
+import org.springblade.manager.vo.WbsTreeSynchronousRecordVo;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * WBS同步记录表(MWbsTreeSynchronousRecord)表控制层
+ *
+ * @author makejava
+ * @since 2025-05-15 13:50:25
+ */
+@RestController
+@RequestMapping("/synchronousRecord")
+public class WbsTreeSynchronousRecordController {
+    /**
+     * 服务对象
+     */
+    @Resource
+    private WbsTreeSynchronousRecordService mWbsTreeSynchronousRecordService;
+
+    /**
+     * 分页查询所有数据
+     *
+     * @param record 查询对象
+     * @param query  分页对象
+     * @return 所有数据
+     */
+    @GetMapping("/page")
+    public R<IPage<WbsTreeSynchronousRecord>> selectAll(WbsTreeSynchronousRecord record, Query query) {
+        LambdaQueryWrapper<WbsTreeSynchronousRecord> lambda = new QueryWrapper().lambda();
+        lambda
+                .eq(record.getProjectId() != null, WbsTreeSynchronousRecord::getProjectId, record.getProjectId())
+                .eq(record.getStatus() != null, WbsTreeSynchronousRecord::getStatus, record.getStatus())
+                .eq(record.getRange() != null, WbsTreeSynchronousRecord::getRange, record.getRange());
+        if (!StringUtil.isBlank(record.getType())) {
+            lambda.apply("FIND_IN_SET({0},type)", record.getType());
+        }
+        IPage<WbsTreeSynchronousRecord> page = mWbsTreeSynchronousRecordService.page(Condition.getPage(query), lambda);
+        for (WbsTreeSynchronousRecord pageRecord : page.getRecords()) {
+            switch (pageRecord.getStatus()) {
+                case 0:
+                    pageRecord.setStatusName("待同步");
+                    break;
+                case 1:
+                    pageRecord.setStatusName("正在同步");
+                    break;
+                case 2:
+                    pageRecord.setStatusName("已同步");
+                    break;
+                case 3:
+                    pageRecord.setStatusName("同步失败");
+                    break;
+                default:
+                    break;
+            }
+        }
+        return R.data(page);
+    }
+
+    /**
+     * 通过主键查询单条数据
+     *
+     * @param id 主键
+     * @return 单条数据
+     */
+    @GetMapping("getById")
+    public R<WbsTreeSynchronousRecord> selectOne(@RequestParam Long id) {
+        return R.data(this.mWbsTreeSynchronousRecordService.getById(id));
+    }
+
+
+    /**
+     * 新增数据
+     *
+     * @param mWbsTreeSynchronousRecord 实体对象
+     * @return 新增结果
+     */
+    @PostMapping("add")
+    public R<WbsTreeSynchronousRecord> insert(@RequestBody WbsTreeSynchronousRecord mWbsTreeSynchronousRecord) {
+        if (StringUtil.isBlank(mWbsTreeSynchronousRecord.getNodeId())) {
+            return R.fail("节点不能为空");
+        }else{
+            String[] split = mWbsTreeSynchronousRecord.getNodeId().split(",");
+            if(split.length > 100){
+                return R.fail("节点过多,如果勾选了父节点,请勿带子节点!");
+            }
+        }
+        if (StringUtil.isBlank(mWbsTreeSynchronousRecord.getType())) {
+            return R.fail("请选择同步类型");
+        }
+        if (mWbsTreeSynchronousRecord.getRange() == null) {
+            return R.fail("请选择同步范围");
+        }
+
+        if (mWbsTreeSynchronousRecord.getRange() == 2 && StringUtil.isBlank(mWbsTreeSynchronousRecord.getContractRange())) {
+            return R.fail("请选择合同同步范围");
+        }
+        if (mWbsTreeSynchronousRecord.getProjectId() == null) {
+            return R.fail("项目Id为空");
+        }
+        if (mWbsTreeSynchronousRecord.getRange() == 1 && mWbsTreeSynchronousRecord.getTemplateId() == null) {
+            return R.fail("同步源为空");
+        }
+
+        return R.data(this.mWbsTreeSynchronousRecordService.insert(mWbsTreeSynchronousRecord));
+    }
+
+    /**
+     * 认证接口是否正在同步
+     */
+    @PostMapping("getNodeStatus")
+    public R<WbsTreeSynchronousRecord> getNodeStatus(@RequestParam Long id) {
+        return R.data(this.mWbsTreeSynchronousRecordService.getNodeStatus(id));
+    }
+
+
+    /**
+     * 获取当前项目的模板项目
+     *
+     * @param nodeIds 节点ids 逗号拼接
+     */
+    @GetMapping("getTempProject")
+    public R<List<WbsTreeSynchronousRecordVo>> getProjectTemplate(@RequestParam String nodeIds) {
+        if (StringUtil.isBlank(nodeIds)) {
+            return R.fail("参数不能为空");
+        }
+        return R.data(this.mWbsTreeSynchronousRecordService.getProjectTemplate(nodeIds));
+    }
+
+}
+

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

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

この差分においてかなりの量のファイルが変更されているため、一部のファイルを表示していません