Pārlūkot izejas kodu

Merge remote-tracking branch 'origin/master' into master

yangyj 2 gadi atpakaļ
vecāks
revīzija
242ac0c7df
85 mainītis faili ar 4301 papildinājumiem un 954 dzēšanām
  1. 1 1
      blade-common/src/main/java/org/springblade/common/utils/AsyncConfigurer.java
  2. 67 0
      blade-common/src/main/java/org/springblade/common/utils/FileUtils.java
  3. 11 0
      blade-common/src/main/java/org/springblade/common/vo/FileSize.java
  4. 2 1
      blade-ops-api/blade-resource-api/src/main/java/org/springblade/resource/feign/NewIOSSClient.java
  5. 2 0
      blade-ops-api/blade-resource-api/src/main/java/org/springblade/resource/vo/NewBladeFile.java
  6. 3 2
      blade-ops/blade-resource/src/main/java/org/springblade/resource/builder/oss/OssBuilder.java
  7. 5 7
      blade-ops/blade-resource/src/main/java/org/springblade/resource/endpoint/LargeFileEndpoint.java
  8. 4 21
      blade-ops/blade-resource/src/main/java/org/springblade/resource/endpoint/OssEndpoint.java
  9. 4 0
      blade-ops/blade-resource/src/main/java/org/springblade/resource/feign/NewIOSSClientImpl.java
  10. 34 0
      blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/entity/ArchiveFormulaConfig.java
  11. 4 0
      blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/entity/ArchivesAuto.java
  12. 44 0
      blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/vo/ArchivesAutoVO.java
  13. 9 1
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/ArchiveFile.java
  14. 2 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/TaskBatch.java
  15. 6 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/feign/ArchiveFileClient.java
  16. 0 2
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/feign/TrialSelfInspectionRecordClient.java
  17. 5 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/ArchiveFileVO.java
  18. 14 4
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/CopyContractTreeNodeVO.java
  19. 2 1
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/ArchiveTree.java
  20. 1 1
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/ExcelEditCallback.java
  21. 4 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/feign/TableFileClient.java
  22. 9 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/feign/WbsTreeContractClient.java
  23. 5 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/WbsTreePrivateVO.java
  24. 42 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/WbsTreePrivateVO5.java
  25. 9 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchiveFileAutoController.java
  26. 28 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchiveFileController.java
  27. 87 4
      blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchivesAutoController.java
  28. 13 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/ArchiveFormulaConfigMapper.java
  29. 5 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/ArchiveFormulaConfigMapper.xml
  30. 19 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/ArchivesAutoMapper.java
  31. 67 1
      blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/ArchivesAutoMapper.xml
  32. 25 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/IArchiveAutoPdfService.java
  33. 16 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/IArchiveFormulaConfigService.java
  34. 9 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/IArchivesAutoService.java
  35. 701 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchiveAutoPdfServiceImpl.java
  36. 20 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchiveFormulaConfigServiceImpl.java
  37. 88 1
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchivesAutoServiceImpl.java
  38. 370 3
      blade-service/blade-archive/src/main/java/org/springblade/archive/utils/FileUtils.java
  39. 184 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/utils/FormulaUtil.java
  40. 5 0
      blade-service/blade-business/pom.xml
  41. 66 1
      blade-service/blade-business/src/main/java/org/springblade/business/controller/EVisaTaskCheckController.java
  42. 4 7
      blade-service/blade-business/src/main/java/org/springblade/business/controller/ImageClassificationFileController.java
  43. 596 120
      blade-service/blade-business/src/main/java/org/springblade/business/controller/InformationWriteQueryController.java
  44. 0 1
      blade-service/blade-business/src/main/java/org/springblade/business/controller/TaskController.java
  45. 81 2
      blade-service/blade-business/src/main/java/org/springblade/business/feignClient/ArchiveFileClientImpl.java
  46. 4 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/ArchiveFileMapper.java
  47. 14 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/ArchiveFileMapper.xml
  48. 4 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/InformationQueryMapper.java
  49. 491 405
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/InformationQueryMapper.xml
  50. 1 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/TaskBatchMapper.xml
  51. 3 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/IInformationQueryService.java
  52. 2 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/ITaskBatchService.java
  53. 13 5
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/ImageClassificationFileServiceImpl.java
  54. 5 2
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/InformationQueryServiceImpl.java
  55. 75 9
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TaskServiceImpl.java
  56. 12 12
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TrialSelfInspectionRecordServiceImpl.java
  57. 100 15
      blade-service/blade-business/src/main/java/org/springblade/business/utils/FileUtils.java
  58. 12 3
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/service/impl/EVisaServiceImpl.java
  59. 11 5
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ExcelTabController.java
  60. 18 2
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/FirstController.java
  61. 28 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ProjectInfoController.java
  62. 2 2
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/TableFileController.java
  63. 27 27
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/WbsTreeContractController.java
  64. 9 2
      blade-service/blade-manager/src/main/java/org/springblade/manager/feign/ArchiveTreeContractImpl.java
  65. 14 19
      blade-service/blade-manager/src/main/java/org/springblade/manager/feign/ExcelTabClientImpl.java
  66. 11 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/feign/TableFileClientImpl.java
  67. 49 9
      blade-service/blade-manager/src/main/java/org/springblade/manager/feign/WbsTreeContractClientImpl.java
  68. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsTreeContractMapper.xml
  69. 5 2
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsTreeMapper.xml
  70. 4 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsTreePrivateMapper.java
  71. 29 12
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsTreePrivateMapper.xml
  72. 2 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/IArchiveTreeContractService.java
  73. 2 2
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/IExcelTabService.java
  74. 4 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/IWbsTreePrivateService.java
  75. 7 2
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ArTreeContractInitServiceImpl.java
  76. 268 10
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ArchiveAutoRuleSyncImpl.java
  77. 54 3
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ArchiveTreeContractServiceImpl.java
  78. 6 3
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ArchiveTreeContractSyncImpl.java
  79. 33 12
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ArchiveTreeServiceImpl.java
  80. 84 46
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ExcelTabServiceImpl.java
  81. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsFormElementServiceImpl.java
  82. 99 81
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeContractServiceImpl.java
  83. 122 30
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreePrivateServiceImpl.java
  84. 0 46
      blade-service/blade-manager/src/main/java/org/springblade/manager/utils/AsyncConfigurer.java
  85. 2 2
      blade-service/blade-manager/src/main/java/org/springblade/manager/utils/test.java

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

@@ -25,7 +25,7 @@ public class AsyncConfigurer {
     @Bean("taskExecutor1")
     public ThreadPoolExecutor getAsyncExecutor() {
         return new ThreadPoolMonitor(cpuNum
-                , 3
+                , 6
                 , 60
                 , TimeUnit.SECONDS
                 , new LinkedBlockingQueue<>(2000)

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

@@ -1,10 +1,17 @@
 package org.springblade.common.utils;
 
+import lombok.SneakyThrows;
+import org.springblade.common.vo.FileSize;
 import org.springframework.web.multipart.MultipartFile;
 
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.text.DecimalFormat;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Objects;
 
 public class FileUtils  {
@@ -31,4 +38,64 @@ public class FileUtils  {
         return convertFile;
     }
 
+    //获取文件大小
+    public static List<FileSize> getOssFileSize(List<String> fileList){
+        List<FileSize> reData =new ArrayList<>();
+        if(fileList!=null){
+            for(String fileUrl:fileList){
+                FileSize file =new FileSize();
+                file.setFileUrl(fileUrl);
+                try {
+                    URLConnection  openConnection = new URL(fileUrl).openConnection();
+                    int contentLength = openConnection.getContentLength();
+                    Double fileLength = Double.parseDouble(contentLength+"");
+                    file.setFileSize(Math.ceil(fileLength/1024));
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+                reData.add(file);
+            }
+        }
+        return  reData;
+    }
+
+    //获取OSS文件总大小
+    public static String getOssFileSizeCount(List<String> fileList){
+        Long count = 0L;
+        if(fileList!=null){
+            for(String fileUrl:fileList){
+                try {
+                    URLConnection  openConnection = new URL(fileUrl).openConnection();
+                    count += openConnection.getContentLength();
+
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        return formatSize(count);
+    }
+
+    /**
+     * 根据字节返回文件大小
+     */
+    private static String formatSize(long fileS) {
+        DecimalFormat df = new DecimalFormat("#.00");
+        String fileSizeString = "";
+        String wrongSize = "0B";
+        if (fileS == 0) {
+            return wrongSize;
+        }
+        if (fileS < 1024) {
+            fileSizeString = df.format((double) fileS) + "B";
+        } else if (fileS < 1048576) {
+            fileSizeString = df.format((double) fileS / 1024) + "KB";
+        } else if (fileS < 1073741824) {
+            fileSizeString = df.format((double) fileS / 1048576) + "MB";
+        } else {
+            fileSizeString = df.format((double) fileS / 1073741824) + "GB";
+        }
+        return fileSizeString;
+    }
+
 }

+ 11 - 0
blade-common/src/main/java/org/springblade/common/vo/FileSize.java

@@ -0,0 +1,11 @@
+package org.springblade.common.vo;
+
+import lombok.Data;
+
+@Data
+public class FileSize {
+
+    private String fileUrl;
+
+    private double fileSize;
+}

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

@@ -9,6 +9,8 @@ import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.multipart.MultipartFile;
 
+import java.util.List;
+
 @FeignClient(value = AppConstant.APPLICATION_RESOURCE_NAME)
 public interface NewIOSSClient {
 
@@ -29,5 +31,4 @@ public interface NewIOSSClient {
 
     @PostMapping(REMOVE_PDF_FILE)
     void removeFile(@RequestParam String fileName);
-
 }

+ 2 - 0
blade-ops-api/blade-resource-api/src/main/java/org/springblade/resource/vo/NewBladeFile.java

@@ -11,4 +11,6 @@ public class NewBladeFile {
     private String originalName;
     private Long attachId;
     private Integer page;
+    private Long fileSize;
+    private Long fileType;
 }

+ 3 - 2
blade-ops/blade-resource/src/main/java/org/springblade/resource/builder/oss/OssBuilder.java

@@ -25,6 +25,7 @@ import org.springblade.core.oss.OssTemplate;
 import org.springblade.core.oss.enums.OssEnum;
 import org.springblade.core.oss.enums.OssStatusEnum;
 import org.springblade.core.oss.props.OssProperties;
+import org.springblade.core.oss.rule.BladeOssRule;
 import org.springblade.core.oss.rule.OssRule;
 import org.springblade.core.secure.utils.AuthUtil;
 import org.springblade.core.tool.utils.*;
@@ -98,9 +99,9 @@ public class OssBuilder {
                          * @create 2023-03-31
                          * @deprecated 重写BladeOssRule-》BladeOssRuleRe 修改文件名UUID -》原始名
                          */
-                        ossRule = new BladeOssRuleRe(Boolean.TRUE);
+                        ossRule = new BladeOssRule(Boolean.TRUE);
                     } else {
-                        ossRule = new BladeOssRuleRe(Boolean.FALSE);
+                        ossRule = new BladeOssRule(Boolean.FALSE);
                     }
                     if (oss.getCategory() == OssEnum.MINIO.getCategory()) {
                         template = MinioOssBuilder.template(oss, ossRule);

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

@@ -276,27 +276,25 @@ public class LargeFileEndpoint {
 				System.out.println("jieshu===================================="+(l1-l));
 
 				File file1 = new File(filePath + param.getFilename());
-
+				MultipartFile multipartFile = getMultipartFile(file1);
 				NewBladeFile newBladeFile = new NewBladeFile();
 				if(param.getFilename().contains("pdf")){
-					FileInputStream inputStream1 = new FileInputStream(filePath + param.getFilename());
-					PDDocument document = PDDocument.load(inputStream1);
+//					FileInputStream inputStream1 = new FileInputStream(filePath + param.getFilename());
+					PDDocument document = PDDocument.load(multipartFile.getInputStream());
 					//获取文件页数
 					newBladeFile.setPage(document.getPages().getCount());
 					//pdf的路径就是文件上传的路径
 					newBladeFile.setPdfUrl(bladeFile.getLink());
 				}else if(param.getFilename().contains("xlsx") || param.getFilename().contains("xls")){
-					MultipartFile multipartFile = getMultipartFile(file1);
 					newBladeFile = this.commonFileClient.excelToPdf(multipartFile);
 				}else if(param.getFilename().contains("docx")){
-					MultipartFile multipartFile = getMultipartFile(file1);
 					newBladeFile = this.commonFileClient.wordToPdf(multipartFile);
 				}else if(param.getFilename().contains("png") || param.getFilename().contains("jpg")){
-					MultipartFile multipartFile = getMultipartFile(file1);
+
 					newBladeFile = this.commonFileClient.pngOrJpgToPdf(multipartFile);
 				}
 				BeanUtils.copyProperties(bladeFile, newBladeFile);
-
+				newBladeFile.setFileSize(multipartFile.getSize()/1024);
 				//删除本地文件
 				file1.delete();
 				iLargeFileService.updateLargeFileDeleted(param.getIdentifier());

+ 4 - 21
blade-ops/blade-resource/src/main/java/org/springblade/resource/endpoint/OssEndpoint.java

@@ -179,27 +179,8 @@ public class OssEndpoint {
 	@SneakyThrows
 	@PostMapping("/upload-file")
 	public synchronized R<NewBladeFile> uploadFile(@RequestParam MultipartFile file){
-		//设置大于3M的文件压缩
-		double targetSize = 3 * 1024 * 1024;
-		byte[] bytes = file.getBytes();
-		//压缩文件大小
-		while (bytes.length > targetSize) {
-			float reduceMultiple = 0.5f;
-			BufferedImage bi = ImageIO.read(new ByteArrayInputStream(bytes));
-			int width = (int) (bi.getWidth() * reduceMultiple);
-			int height = (int) (bi.getHeight() * reduceMultiple);
-			Image image = bi.getScaledInstance(width, height, Image.SCALE_SMOOTH);
-			BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
-			Graphics g = tag.getGraphics();
-			g.setColor(Color.RED);
-			g.drawImage(image, 0, 0, null);
-			g.dispose();
-			ByteArrayOutputStream bOut = new ByteArrayOutputStream();
-			ImageIO.write(tag, "JPEG", bOut);
-			bytes =bOut.toByteArray();
-		}
-		ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
-		//上传文件
+		//上传原图
+		ByteArrayInputStream inputStream = new ByteArrayInputStream(file.getBytes());
 		BladeFile bladeFile = ossBuilder.template().putFile(file.getOriginalFilename(),inputStream);
 
 		//处理PDF文件
@@ -226,6 +207,7 @@ public class OssEndpoint {
 		}
 
 		BeanUtils.copyProperties(bladeFile, newBladeFile);
+		newBladeFile.setFileSize(file.getSize()/1024);
 		return R.data(newBladeFile);
 	}
 
@@ -262,6 +244,7 @@ public class OssEndpoint {
 		}
 
 		BeanUtils.copyProperties(bladeFile, newBladeFile);
+		newBladeFile.setFileSize(file.getSize()/1024);
 		return R.data(newBladeFile.getPdfUrl());
 	}
 

+ 4 - 0
blade-ops/blade-resource/src/main/java/org/springblade/resource/feign/NewIOSSClientImpl.java

@@ -2,10 +2,12 @@ package org.springblade.resource.feign;
 
 import lombok.AllArgsConstructor;
 import org.springblade.core.oss.model.BladeFile;
+import org.springblade.core.oss.model.OssFile;
 import org.springblade.core.tenant.annotation.NonDS;
 import org.springblade.core.tool.api.R;
 import org.springblade.resource.builder.oss.OssBuilder;
 import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 import org.springframework.web.multipart.MultipartFile;
 
@@ -13,6 +15,8 @@ import java.io.ByteArrayInputStream;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
 
 @NonDS
 @RestController

+ 34 - 0
blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/entity/ArchiveFormulaConfig.java

@@ -0,0 +1,34 @@
+package org.springblade.archive.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import org.springblade.core.mp.base.BaseEntity;
+
+@Data
+@TableName("m_archive_formula_config")
+public class ArchiveFormulaConfig extends BaseEntity {
+
+    /**
+     * 名称,例如:“封面”
+     */
+    private String name;
+
+    /**
+     * r_Archives_back
+     */
+    private String number;
+
+    /**
+     * 公式
+     */
+    private String formula;
+    /**
+     * 公式名
+     */
+    private String formulaName;
+
+    /**
+     * 单元格
+     */
+    private String coords;
+}

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

@@ -21,6 +21,7 @@ import java.io.Serializable;
 import java.time.LocalDateTime;
 
 import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModelProperty;
 import org.springblade.core.mp.base.BaseEntity;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
@@ -144,6 +145,9 @@ public class ArchivesAuto extends BaseEntity {
 	private String mileage;
 	private Integer fileType;
 	private Integer size;
+	@ApiModelProperty("文件大小")
+	private Long fileSize;
+
 	private String treeSort;
 	private Integer isOpen;
 	private Integer ischeck;

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

@@ -47,6 +47,28 @@ public class ArchivesAutoVO extends ArchivesAuto {
 	@ApiModelProperty("当前页显示条数")
 	private Integer size;
 
+	/**
+	 * 搜索类型
+	 */
+	@ApiModelProperty("搜索类型1案卷2文件")
+	private Integer searchType;
+
+	/**
+	 * 年
+	 */
+	@ApiModelProperty("年")
+	private String year;
+
+	private List<String> years;
+
+	/**
+	 * 年
+	 */
+	@ApiModelProperty("月")
+	private String month;
+
+	private List<String> months;
+
 	/**
 	 * 输入框查询条件
 	 */
@@ -66,11 +88,31 @@ public class ArchivesAutoVO extends ArchivesAuto {
 	 */
 	private String secretLevelValue;
 
+	/**
+	 * 搜索密级集合
+	 */
+	private List<String> secretLevels;
+
 	/**
 	 * 保管期限(单位/年)
 	 */
 	private String storageTimeValue;
 
+	/**
+	 * 搜索期限集合
+	 */
+	private List<String> storageTimes;
+
+	/**
+	 * 搜索类别集合
+	 */
+	private List<String> carrierTypes;
+
+	/**
+	 * 案卷合同类型,C施工、S监理、空业主
+	 */
+	private String contractType;
+
 	@ApiModelProperty("批量保存")
 	private List<ArchivesAutoVO> list;
 	/**
@@ -134,5 +176,7 @@ public class ArchivesAutoVO extends ArchivesAuto {
 		 * 责任者
 		 */
 		private String dutyUser;
+
+		private  String archiveId;
 	}
 }

+ 9 - 1
blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/ArchiveFile.java

@@ -251,6 +251,14 @@ public class ArchiveFile extends BaseEntity {
 	@ApiModelProperty("是否组卷")
 	private Integer isArchive;
 
+	@ApiModelProperty("页号")
+	private String pageNum;
 
-
+	@ApiModelProperty("文件大小")
+	Long fileSize;
+	/**
+	 * 数据源类型,1原生,2数字化
+	 */
+	@ApiModelProperty("数据源类型,1原生,2数字化")
+	private Integer sourceType;
 }

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

@@ -47,6 +47,8 @@ public class TaskBatch extends BaseEntity {
 
     private String jsonData;
 
+    private String nickName;
+
     public TaskBatch(String taskParallelId, String jsonData){
         this.setId(SnowFlakeUtil.getId());
         this.taskParallelId = taskParallelId;

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

@@ -67,4 +67,10 @@ public interface ArchiveFileClient {
 
     @PostMapping(API_PREFIX + "/getListByProjectId")
     List<ArchiveFile> getListByProjectId(@RequestBody Long projectId);
+
+    @PostMapping(API_PREFIX + "/getAllArchiveFileByContractType")
+    List<Map<String,Object>> getAllArchiveFileByContractType(@RequestBody Long projectId);
+
+    @PostMapping(API_PREFIX + "/getAllArchiveFileSize")
+    String getAllArchiveFileSize(@RequestBody Long projectId);
 }

+ 0 - 2
blade-service-api/blade-business-api/src/main/java/org/springblade/business/feign/TrialSelfInspectionRecordClient.java

@@ -15,6 +15,4 @@ public interface TrialSelfInspectionRecordClient {
 
     @PostMapping(API_PREFIX + "/updateURL")
     void updateURL(@RequestParam String url, @RequestParam String pKeyId);
-
-
 }

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

@@ -80,4 +80,9 @@ public class ArchiveFileVO extends ArchiveFile {
 
 	private String sheetSourceValue;
 
+	/**
+	 * 案卷合同类型,C施工、S监理、空业主
+	 */
+	private String contractType;
+
 }

+ 14 - 4
blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/CopyContractTreeNodeVO.java

@@ -30,11 +30,18 @@ public class CopyContractTreeNodeVO {
     @ApiModelProperty("所属方,1=施工,2=监理,字符串拼接,复制数据")
     private String classify;
 
-    @ApiModelProperty("划分编号,单份复制")
+    @ApiModelProperty("所属方,1=施工,2=监理,字符串拼接,复制数据," +
+            "不知道之前的接口为什么会入参这个值,有个接口单独用的,懒得叫前端改了")
+    private String classifyType;
+
+    @ApiModelProperty("是否需要复制数据 0=否1=是")
+    private Integer isCopyData;
+
+    @ApiModelProperty("划分编号")
     private String partitionCode;
 
-    public void setCopyBatchToPaths(String primaryKeyId, String nodeName, String partitionCode) {
-        this.copyBatchToPaths.add(new CopyBatch(primaryKeyId, nodeName, partitionCode));
+    public void setCopyBatchToPaths(String primaryKeyId, String nodeName, String partitionCode, Integer isSameNode) {
+        this.copyBatchToPaths.add(new CopyBatch(primaryKeyId, nodeName, partitionCode, isSameNode));
     }
 
     @Data
@@ -46,13 +53,16 @@ public class CopyContractTreeNodeVO {
 
         private String partitionCode;
 
+        private Integer isSameNode; //是否同节点(多份复制 同节点=1,不同节点/跨节点=0)
+
         public CopyBatch() {
         }
 
-        public CopyBatch(String primaryKeyId, String nodeName, String partitionCode) {
+        public CopyBatch(String primaryKeyId, String nodeName, String partitionCode, Integer isSameNode) {
             this.primaryKeyId = primaryKeyId;
             this.nodeName = nodeName;
             this.partitionCode = partitionCode;
+            this.isSameNode = isSameNode;
         }
 
     }

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

@@ -157,7 +157,7 @@ public class ArchiveTree extends BaseEntity {
     private Long archiveAutoGroupId;
 
     /**
-     * 是否自动立卷规则选择设置的节点 选中的节点设为1 方便页面显示列表
+     * 是否自动立卷规则选择设置的节点 选中的节点设为1 方便页面显示列表,方便同步判断
      */
     @ApiModelProperty(value = "是否为设置的节点")
     private Integer archiveAutoGroupSelect;
@@ -220,6 +220,7 @@ public class ArchiveTree extends BaseEntity {
         this.archiveAutoType = archiveTree.getArchiveAutoType();
         this.archiveAutoNodeId = archiveTree.getArchiveAutoNodeId();
         this.archiveAutoGroupId = archiveTree.getArchiveAutoGroupId();
+        this.archiveAutoGroupSelect = archiveTree.getArchiveAutoGroupSelect();
         this.isUploadFileDisplayConfigurationTree = archiveTree.getIsDisplayTree();
     }
 }

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

@@ -15,7 +15,7 @@ public class ExcelEditCallback {
     private Integer status;
 
     // excel 的唯一标识
-    private Long key;
+    private String key;
 
     // 返回码
     private Integer error;

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

@@ -2,6 +2,7 @@ package org.springblade.manager.feign;
 
 import org.springblade.manager.entity.TableFile;
 import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestParam;
@@ -28,4 +29,7 @@ public interface TableFileClient {
     @PostMapping(API_PREFIX + "/saveBatch")
     boolean saveBatch(@RequestBody List<TableFile> newFiles);
 
+    @GetMapping(API_PREFIX + "/getTabFilesByTabIds")
+    List<TableFile> getTabFilesByTabIds(@RequestParam String tabFileIds);
+
 }

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

@@ -22,6 +22,9 @@ public interface WbsTreeContractClient {
      */
     String API_PREFIX = "/api/manager/WbsTreeContract";
 
+    @GetMapping(API_PREFIX + "/queryContractTreeNodeByPKeyId")
+    WbsTreeContract queryContractTreeNodeByPKeyId(@RequestParam Long toCopyNodePKeyId);
+
     @PostMapping(API_PREFIX + "/queryContractTreeNodeByPKIds")
     List<WbsTreeContract> queryContractTreeNodeByPKIds(@RequestParam List<Long> PKIds);
 
@@ -157,4 +160,10 @@ public interface WbsTreeContractClient {
     @PostMapping(API_PREFIX + "/queryContractFirstTab")
     List<WbsTreeContract> queryContractFirstTab(@RequestParam String contractId, @RequestParam String tabType);
 
+    @GetMapping(API_PREFIX + "/queryWbsTreeContractById")
+    WbsTreeContract queryWbsTreeContractById(@RequestParam String contractId, @RequestParam Long parseLong);
+
+    @GetMapping(API_PREFIX + "/queryWbsTreeContractTreeLazy")
+    List<WbsTreeContractTreeVOS> queryWbsTreeContractTreeLazy(@RequestParam String contractId,@RequestParam Long parseLong);
+
 }

+ 5 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/WbsTreePrivateVO.java

@@ -63,4 +63,9 @@ public class WbsTreePrivateVO extends WbsTreePrivate implements INode<WbsTreePri
      */
     private String title;
 
+    /**
+     * 勾选状态 0=未勾选 1=已勾选
+     */
+    private Integer checkStatus = 0;
+
 }

+ 42 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/WbsTreePrivateVO5.java

@@ -0,0 +1,42 @@
+package org.springblade.manager.vo;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+@Data
+public class WbsTreePrivateVO5 implements Serializable {
+
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long id;
+
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long parentId;
+
+    private String title;
+
+    private Integer checkStatus = 0;
+
+    private Integer nodeType;
+
+    private Integer wbsType;
+
+    @JsonInclude(JsonInclude.Include.NON_EMPTY)
+    private List<WbsTreePrivateVO5> children;
+
+    @JsonInclude(JsonInclude.Include.NON_EMPTY)
+    private Boolean hasChildren;
+
+    public List<WbsTreePrivateVO5> getChildren() {
+        if (this.children == null) {
+            this.children = new ArrayList<>();
+        }
+        return this.children;
+    }
+
+}

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

@@ -79,6 +79,12 @@ public class ArchiveFileAutoController extends BladeController {
                             saveVo.setIsCertification(new Integer("0").equals(saveVo.getIsNeedCertification()) ? 1 : 0);
                             saveVo.setArchiveId(archive.getId());
                             saveVo.setOriginId(archive.getId());
+                            if(saveVo.getFileUrl() != null && saveVo.getFileUrl().lastIndexOf(".") > -1
+                                    && (saveVo.getFileUrl().lastIndexOf(".")+1)<saveVo.getFileUrl().length()) {
+                                String name = saveVo.getFileUrl().substring(saveVo.getFileUrl().lastIndexOf(".") + 1);
+                                saveVo.setFileType((long) FileUtils.getFileType(name));
+                            }
+                            saveVo.setSourceType(2);
                             list.add(saveVo);
                             if(saveVo.getFilePage() != null && !saveVo.getFilePage().equals("")){
                                 pageN = pageN + saveVo.getFilePage();
@@ -93,6 +99,9 @@ public class ArchiveFileAutoController extends BladeController {
                     List<ArchiveTreeContract> archiveTreeContracts = this.archiveTreeContractClient.queryAllChildByAncestors(saveVos.getNodeId());
                     if(archiveTreeContracts != null && archiveTreeContracts.size() >0){
                         archive.setTreeSort(archiveTreeContracts.get(0).getTreeSort());
+                        if (archiveTreeContracts.get(0).getStorageType()!= null){
+                            archive.setCarrierType(archiveTreeContracts.get(0).getStorageType().toString());
+                        }
                     }
 
                     archive.setAutoFileSort(l+archive.getAutoFileSort());

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

@@ -87,6 +87,12 @@ public class ArchiveFileController extends BladeController {
                     saveVo.setSort(l+i);
                     saveVo.setStatus(new Integer("0").equals(saveVo.getIsApproval()) ? 2 : 0);
                     saveVo.setIsCertification(new Integer("0").equals(saveVo.getIsNeedCertification()) ? 1 : 0);
+                    if(saveVo.getFileUrl() != null && saveVo.getFileUrl().lastIndexOf(".") > -1
+                            && (saveVo.getFileUrl().lastIndexOf(".")+1)<saveVo.getFileUrl().length()) {
+                        String name = saveVo.getFileUrl().substring(saveVo.getFileUrl().lastIndexOf(".") + 1);
+                        saveVo.setFileType((long) FileUtils.getFileType(name));
+                    }
+                    saveVo.setSourceType(2);
                     i++;
                 }
             }
@@ -259,4 +265,26 @@ public class ArchiveFileController extends BladeController {
         }
 
     }
+
+    /**
+     * 档案统计-原生数字化文件数量
+     */
+    @GetMapping("/allArchiveFileByContractType")
+    @ApiOperationSupport(order = 3)
+    @ApiOperation(value = "档案统计-原生数字化文件数量")
+    public R allArchiveFileByContractType(Long projectId) {
+        List<Map<String, Object>> mapList = archiveFileClient.getAllArchiveFileByContractType(projectId);
+        return R.data(mapList);
+    }
+
+    /**
+     * 档案统计-档案总存储
+     */
+    @GetMapping("/allArchiveFileSize")
+    @ApiOperationSupport(order = 3)
+    @ApiOperation(value = "档案统计-档案总存储")
+    public R allArchiveFileSize(Long projectId) {
+        String fileSize = archiveFileClient.getAllArchiveFileSize(projectId);
+        return R.data(fileSize);
+    }
 }

+ 87 - 4
blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchivesAutoController.java

@@ -16,13 +16,12 @@
  */
 package org.springblade.archive.controller;
 
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
-import io.swagger.annotations.ApiParam;
+import io.swagger.annotations.*;
 import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
 import lombok.AllArgsConstructor;
 import javax.validation.Valid;
 
+import org.springblade.archive.service.IArchiveAutoPdfService;
 import org.springblade.core.mp.support.Condition;
 import org.springblade.core.mp.support.Query;
 import org.springblade.core.tool.api.R;
@@ -36,6 +35,9 @@ import org.springblade.archive.wrapper.ArchivesAutoWrapper;
 import org.springblade.archive.service.IArchivesAutoService;
 import org.springblade.core.boot.ctrl.BladeController;
 
+import java.util.List;
+import java.util.Map;
+
 /**
  *  控制器
  *
@@ -45,11 +47,13 @@ import org.springblade.core.boot.ctrl.BladeController;
 @RestController
 @AllArgsConstructor
 @RequestMapping("/archivesauto")
-@Api(value = "", tags = "接口")
+@Api(value = "", tags = "档案接口")
 public class ArchivesAutoController extends BladeController {
 
 	private final IArchivesAutoService archivesAutoService;
 
+	private final IArchiveAutoPdfService archiveAutoPdfService;
+
 	/**
 	 * 详情
 	 */
@@ -84,6 +88,60 @@ public class ArchivesAutoController extends BladeController {
 		return R.data(pages);
 	}
 
+	/**
+	 * 档案利用-档案查询
+	 */
+	@GetMapping("/pageByArchivesAuto")
+	@ApiOperationSupport(order = 3)
+	@ApiOperation(value = "档案利用-档案查询分页", notes = "传入archivesAuto")
+	@ApiImplicitParams({
+			@ApiImplicitParam(name = "projectId", value = "项目id", required = true),
+			@ApiImplicitParam(name = "year", value = "年"),
+			@ApiImplicitParam(name = "month", value = "yue"),
+			@ApiImplicitParam(name = "storageTime", value = "保管期限"),
+			@ApiImplicitParam(name = "secretLevel", value = "保密级别"),
+			@ApiImplicitParam(name = "carrierType", value = "类别"),
+			@ApiImplicitParam(name = "queryValue", value = "输入框模糊搜索"),
+			@ApiImplicitParam(name = "searchType", value = "搜索类型1案卷2文件")
+	})
+	public R<IPage<ArchivesAutoVO>> pageByArchivesAuto(ArchivesAutoVO archivesAuto) {
+		IPage<ArchivesAutoVO> pages = archivesAutoService.pageByArchivesAuto(archivesAuto);
+		return R.data(pages);
+	}
+
+	/**
+	 * 档案统计-已组案卷
+	 */
+	@GetMapping("/allArchiveByContractType")
+	@ApiOperationSupport(order = 3)
+	@ApiOperation(value = "档案统计-已组案卷")
+	public R allArchiveByContractType(Long projectId) {
+		Map<String, Integer> map = archivesAutoService.getAllArchiveByContractType(projectId,"0");
+		return R.data(map);
+	}
+
+	/**
+	 * 档案统计-已销毁案卷
+	 */
+	@GetMapping("/allDeletedArchiveByContractType")
+	@ApiOperationSupport(order = 3)
+	@ApiOperation(value = "档案统计-已销毁案卷")
+	public R allDeletedArchiveByContractType(Long projectId) {
+		Map<String, Integer> map = archivesAutoService.getAllArchiveByContractType(projectId,"1");
+		return R.data(map);
+	}
+
+	/**
+	 * 档案统计-档案年限占比
+	 */
+	@GetMapping("/allArchiveAgeByContractType")
+	@ApiOperationSupport(order = 3)
+	@ApiOperation(value = "档案统计-档案年限占比")
+	public R allArchiveAgeByContractType(Long projectId) {
+		List<Map<String, String>> list = archivesAutoService.getAllArchiveAgeByContractType(projectId);
+		return R.data(list);
+	}
+
 	/**
 	 * 新增 
 	 */
@@ -125,5 +183,30 @@ public class ArchivesAutoController extends BladeController {
 		return R.status(archivesAutoService.deleteLogic(Func.toLongList(ids)));
 	}
 
+
+	/**
+	 * 获取归档树同级节点
+	 */
+	@GetMapping("/test")
+	@ApiOperationSupport(order = 12)
+	@ApiOperation(value = "获取归档树同级节点", notes = "传入节点id")
+	public R test() {
+
+		archiveAutoPdfService.test();
+		return R.data("");
+	}
+
+	/**
+	 * 获取归档树同级节点
+	 */
+	@GetMapping("/test1")
+	@ApiOperationSupport(order = 12)
+	@ApiOperation(value = "获取归档树同级节点", notes = "传入节点id")
+	public R test1() {
+
+		archiveAutoPdfService.test1();
+		return R.data("");
+	}
+
 	
 }

+ 13 - 0
blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/ArchiveFormulaConfigMapper.java

@@ -0,0 +1,13 @@
+package org.springblade.archive.mapper;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.springblade.archive.entity.ArchiveFormulaConfig;
+
+/**
+ * <p>
+ * 档案号码公式配置 Mapper 接口
+ * </p>
+ *
+ * @since 2023-04-13
+ */
+public interface ArchiveFormulaConfigMapper extends BaseMapper<ArchiveFormulaConfig> {
+}

+ 5 - 0
blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/ArchiveFormulaConfigMapper.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.springblade.archive.mapper.ArchiveFormulaConfigMapper">
+
+</mapper>

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

@@ -16,6 +16,7 @@
  */
 package org.springblade.archive.mapper;
 
+import org.apache.ibatis.annotations.MapKey;
 import org.apache.ibatis.annotations.Param;
 import org.springblade.archive.dto.ArchivesAutoDTO;
 import org.springblade.archive.entity.ArchivesAuto;
@@ -23,6 +24,7 @@ import org.springblade.archive.vo.ArchivesAutoVO;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import java.util.List;
+import java.util.Map;
 
 /**
  *  Mapper 接口
@@ -56,4 +58,21 @@ public interface ArchivesAutoMapper extends BaseMapper<ArchivesAuto> {
 	 *  根据项目id获取所有档案
 	 */
 	List<ArchivesAutoDTO> getListByProjectId(@Param("projectId") Long projectId);
+
+	/**
+	 *  档案利用-档案查询
+	 */
+    List<ArchivesAutoVO> pageByArchivesAuto(IPage page, @Param("vo") ArchivesAutoVO vo);
+
+	/**
+	 * 获取当前项目所有案卷,并设置合同类型
+	 */
+	List<ArchivesAutoVO> getAllArchiveByContractType(@Param("projectId") Long projectId,@Param("type") String type);
+
+	/**
+	 * 获取所有案卷年限,并分组
+	 */
+	@MapKey("storage_time")
+	List<Map<String,String>> getAllArchiveAgeByContractType(@Param("projectId") Long projectId);
+
 }

+ 67 - 1
blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/ArchivesAutoMapper.xml

@@ -3,7 +3,7 @@
 <mapper namespace="org.springblade.archive.mapper.ArchivesAutoMapper">
 
     <!-- 通用查询映射结果 -->
-    <resultMap id="archivesAutoResultMap" type="org.springblade.archive.entity.ArchivesAuto">
+    <resultMap id="archivesAutoResultMap" type="org.springblade.archive.vo.ArchivesAutoVO">
         <result column="id" property="id"/>
         <result column="create_user" property="createUser"/>
         <result column="create_dept" property="createDept"/>
@@ -47,8 +47,19 @@
         <result column="is_auto_file" property="isAutoFile"/>
         <result column="auto_file_sort" property="autoFileSort"/>
         <result column="filing_unit" property="filingUnit"/>
+        <result column="file_size" property="fileSize"/>
+        <collection property="approvalFileList" javaType="java.util.List"
+                    select="approvalFile"
+                    column="{archiveId=id}">
+        </collection>
     </resultMap>
 
+    <select id="approvalFile" resultType="org.springblade.archive.vo.ArchivesAutoVO$ApprovalFile">
+        <if test="archiveId!=null">
+            select * from u_archive_file where archive_id = #{archiveId}
+        </if>
+    </select>
+
 
     <select id="selectArchivesAutoPage" resultMap="archivesAutoResultMap">
         select * from u_archives_auto where is_deleted = 0
@@ -124,6 +135,61 @@
         from u_archives_auto
         where project_id=#{projectId};
     </select>
+    <select id="pageByArchivesAuto" resultMap="archivesAutoResultMap">
+        select uaa.* from u_archives_auto uaa left join u_archive_file uaf on uaa.id = uaf.archive_id
+        where uaa.is_deleted = 0
+        <if test="vo.projectId != null and vo.projectId != ''">
+            and uaa.project_id = #{vo.projectId}
+        </if>
+        <if test="vo.searchType == 1 and vo.queryValue != null and vo.queryValue != ''">
+            and uaa.name like concat('%',#{vo.queryValue},'%')
+        </if>
+        <if test="vo.searchType == 2 and vo.queryValue != null and vo.queryValue != ''">
+            and uaf.file_name like concat('%',#{vo.queryValue},'%')
+        </if>
+        <if test="vo.storageTimes != null and vo.storageTimes != ''">
+            and uaa.storage_time in
+            <foreach collection="vo.storageTimes" item="storageTime" open="(" separator="," close=")">
+                #{storageTime}
+            </foreach>
+        </if>
+        <if test="vo.secretLevels != null and vo.secretLevels != ''">
+            and uaa.secret_level in
+            <foreach collection="vo.secretLevels" item="secretLevel" open="(" separator="," close=")">
+                #{secretLevel}
+            </foreach>
+        </if>
+        <if test="vo.carrierTypes != null and vo.carrierTypes != ''">
+            and uaa.carrier_type in
+            <foreach collection="vo.carrierTypes" item="carrierType" open="(" separator="," close=")">
+                #{carrierType}
+            </foreach>
+        </if>
+        <if test="vo.years != null and vo.years != ''">
+            and
+            <foreach collection="vo.years" item="year" separator=" or" open="(" close=")" >
+                #{year} BETWEEN  DATE_FORMAT(uaa.start_date,'%Y') and DATE_FORMAT(uaa.end_date ,'%Y')
+            </foreach>
+        </if>
+        <if test="vo.months != null and vo.months != ''">
+            and
+            <foreach collection="vo.months" item="month" separator=" or" open="(" close=")">
+                #{month} BETWEEN  DATE_FORMAT(uaa.start_date,'%c') and DATE_FORMAT(uaa.end_date ,'%c')
+            </foreach>
+        </if>
+        GROUP BY uaa.id
+    </select>
+    <select id="getAllArchiveByContractType" resultType="org.springblade.archive.vo.ArchivesAutoVO">
+        SELECT uaa.id,matc.tree_code as 'contractType'
+        FROM u_archives_auto uaa left join m_archive_tree_contract matc on uaa.node_id =matc.id
+        WHERE uaa.project_id =#{projectId} and uaa.is_deleted = #{type}
+    </select>
+    <select id="getAllArchiveAgeByContractType" resultType="java.util.Map">
+        SELECT CASE storage_time WHEN '10' THEN '10年' WHEN '30' THEN '30年' ELSE '永久' END as name,COUNT(storage_time) as value
+        FROM u_archives_auto uaa
+        WHERE project_id =#{projectId} and is_deleted =0
+        GROUP BY storage_time
+    </select>
 
 
 </mapper>

+ 25 - 0
blade-service/blade-archive/src/main/java/org/springblade/archive/service/IArchiveAutoPdfService.java

@@ -0,0 +1,25 @@
+package org.springblade.archive.service;
+
+import org.springblade.archive.entity.ArchivesAuto;
+import org.springblade.business.entity.ArchiveFile;
+
+import java.util.List;
+import java.util.Map;
+
+public interface IArchiveAutoPdfService {
+    public void test();
+
+    public void test1();
+
+    //生成四要素,信息会写入archivesAuto
+    void buildArchiveFrontPdfs(Long projectId, ArchivesAuto archivesAuto,List<ArchiveFile> archiveFileList);
+
+    //打码,信息写入waitArchiveFiles
+    void builtFilePageNo(ArchivesAuto archivesAuto, List<ArchiveFile> waitArchiveFiles);
+
+    // 单个pdf 生成
+    String getBussPdfInfo(String fileName, Map<String, Object> DataInfo, String excelUrl, String filePath )throws Exception;
+
+    //获取文件的pdf文件的url
+    String getPdfFileUrl(ArchiveFile file);
+}

+ 16 - 0
blade-service/blade-archive/src/main/java/org/springblade/archive/service/IArchiveFormulaConfigService.java

@@ -0,0 +1,16 @@
+package org.springblade.archive.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.springblade.archive.entity.ArchiveFormulaConfig;
+
+import java.util.List;
+
+public interface IArchiveFormulaConfigService extends IService<ArchiveFormulaConfig> {
+    /**
+     * 根据档案号码字符串获取对应的档案号码公式配置列表
+     *
+     * @param number 档案号码字符串,
+     * @return List<ArchiveFormulaConfig> 返回对应的档案号码公式配置列表
+     */
+    List<ArchiveFormulaConfig> getByNumber(String number);
+}

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

@@ -21,6 +21,9 @@ import org.springblade.archive.vo.ArchivesAutoVO;
 import org.springblade.core.mp.base.BaseService;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 
+import java.util.List;
+import java.util.Map;
+
 /**
  *  服务类
  *
@@ -38,7 +41,13 @@ public interface IArchivesAutoService extends BaseService<ArchivesAuto> {
 	 */
 	IPage<ArchivesAutoVO> selectArchivesAutoPage(IPage<ArchivesAutoVO> page, ArchivesAutoVO archivesAuto);
 
+	IPage<ArchivesAutoVO> pageByArchivesAuto(ArchivesAutoVO archivesAuto);
+
 	IPage<ArchivesAutoVO> selectArchivesAutoFilePage(ArchivesAutoVO queryVo);
 
 	boolean updateArchivesAutoFileByNodeId(String ids, String nodeId,String nodeSort);
+
+	Map<String,Integer> getAllArchiveByContractType(Long projectId,String type);
+
+	List<Map<String, String>> getAllArchiveAgeByContractType(Long projectId);
 }

+ 701 - 0
blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchiveAutoPdfServiceImpl.java

@@ -0,0 +1,701 @@
+package org.springblade.archive.service.impl;
+
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.itextpdf.text.Element;
+import com.itextpdf.text.pdf.*;
+import lombok.AllArgsConstructor;
+import org.apache.poi.ss.usermodel.*;
+import org.apache.poi.util.IOUtils;
+import org.springblade.archive.entity.ArchiveFormulaConfig;
+import org.springblade.archive.entity.ArchiveProjectConfig;
+import org.springblade.archive.entity.ArchivesAuto;
+import org.springblade.archive.service.IArchiveAutoPdfService;
+import org.springblade.archive.service.IArchiveFormulaConfigService;
+import org.springblade.archive.service.IArchiveProjectConfigService;
+import org.springblade.archive.utils.FileUtils;
+import org.springblade.archive.utils.FormulaUtil;
+import org.springblade.business.entity.ArchiveFile;
+import org.springblade.common.utils.CommonUtil;
+import org.springblade.common.utils.SnowFlakeUtil;
+import org.springblade.common.vo.DataVO;
+import org.springblade.common.vo.FileSize;
+import org.springblade.core.oss.model.BladeFile;
+import org.springblade.core.tool.utils.ObjectUtil;
+import org.springblade.core.tool.utils.ResourceUtil;
+import org.springblade.core.tool.utils.StringUtil;
+import org.springblade.resource.feign.NewIOSSClient;
+import org.springframework.stereotype.Service;
+
+
+import java.io.*;
+import java.net.URLEncoder;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Service
+@AllArgsConstructor
+public class ArchiveAutoPdfServiceImpl implements IArchiveAutoPdfService {
+
+    private final NewIOSSClient newIOSSClient;
+
+    private final IArchiveProjectConfigService archiveProjectConfigService;
+
+    private final IArchiveFormulaConfigService archiveFormulaConfigService;
+
+    public static final  String[] ARCHIVE_NUMBER = new String[]{"r_Archives_front","r_Archives_catalog","r_Archives_spare","r_Archives_back"};
+
+    public static final Map<String, String> URL_MAP = new HashMap<>();
+    public static final Map<String, String> NAME_MAP = new HashMap<>();
+
+    static {
+        URL_MAP.put("r_Archives_front", "https://bladex-chongqing-info.oss-cn-hangzhou.aliyuncs.com//upload/20230413/306c87ffc640699aa92d53a5f4e6d632.xlsx");
+        URL_MAP.put("r_Archives_catalog", "https://bladex-chongqing-info.oss-cn-hangzhou.aliyuncs.com//upload/20230413/f2a083fca685c646e4a47daaaa46f04b.xlsx");
+        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");
+
+        NAME_MAP.put("r_Archives_front", "封面");
+        NAME_MAP.put("r_Archives_catalog", "卷内目录");
+        NAME_MAP.put("r_Archives_spare", "备考表");
+        NAME_MAP.put("r_Archives_back", "脊背");
+    }
+
+
+    //测试数据
+    public void test1() {
+
+        Long pkeyId = SnowFlakeUtil.getId();
+//        String  file2 = "upload/20230413/306c87ffc640699aa92d53a5f4e6d632.xlsx";
+//        List<String> files = new ArrayList<>();
+//        files.add(file2);
+//        BladeFile bladeFile = newIOSSClient.uploadFile1(file2,"123");
+
+        String file_path = "D:\\tmp";
+        String excelUrl = file_path +  "\\备考表.xlsx";
+
+        Map<String, Object> DataInfo = new HashMap<>();
+
+        DataVO dataVO = FormulaUtil.convertCellToIndex("C2");
+        String key =  "1__"+ dataVO.getY() + "_" + dataVO.getX();
+        DataInfo.put(key,"档号123456");
+
+        DataVO dataVO1 = FormulaUtil.convertCellToIndex("A9");
+        String key1 =  "2__"+ dataVO1.getY() + "_" + dataVO1.getX();
+        DataInfo.put(key1,"hahahahaa");
+        try {
+            String url = getBussPdfInfo(pkeyId.toString(),DataInfo,excelUrl,file_path);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        System.out.println();
+
+
+    }
+
+    //测试
+    public void test() {
+
+        Long projectId = 1578599210897772545L;
+
+        ArchivesAuto archivesAuto = new ArchivesAuto();
+        archivesAuto.setId(SnowFlakeUtil.getId());
+        archivesAuto.setProjectId(projectId);
+        archivesAuto.setName("案卷提名");
+        archivesAuto.setFileNumber("档号");
+        archivesAuto.setMicron("缩微号");
+        archivesAuto.setUnit("单位");
+        archivesAuto.setQuantity("数量/单位");
+        archivesAuto.setSpecification("规格");
+        archivesAuto.setStorageTime("1");
+        archivesAuto.setSecretLevel("1");
+        archivesAuto.setCarrierType("载体类型");
+        archivesAuto.setKeywords("主题词");
+        archivesAuto.setReviewer("审核人");
+        archivesAuto.setReviewDate(LocalDateTime.now());
+        archivesAuto.setStartDate(LocalDateTime.now());
+        archivesAuto.setEndDate(LocalDateTime.now());
+        archivesAuto.setStorageLocation("存放位置");
+        archivesAuto.setIsArchive(0);
+        archivesAuto.setRemark("备注");
+        archivesAuto.setRollDate(LocalDateTime.now().minusDays(1));
+        archivesAuto.setRollor("立卷人");
+        archivesAuto.setNodeId(123L);
+        archivesAuto.setOutUrl("http://example.com");
+        archivesAuto.setCdId(456L);
+        archivesAuto.setFileN(2);
+        archivesAuto.setPageN(100);
+        archivesAuto.setMileage("统一里程信息");
+        archivesAuto.setFileType(1);
+        archivesAuto.setFileSize(1024L);
+        archivesAuto.setTreeSort("ABC");
+        archivesAuto.setIsOpen(1);
+        archivesAuto.setIscheck(1);
+        archivesAuto.setIsAutoFile(0);
+        archivesAuto.setAutoFileSort(1);
+        archivesAuto.setFilingUnit("立卷单位");
+        archivesAuto.setIsLock(0);
+
+        ArchiveFile archiveFile = new ArchiveFile();
+        archiveFile.setProjectId(projectId.toString());
+        archiveFile.setContractId("合同段ID");
+        archiveFile.setNodeId("文件绑定的节点ID");
+        archiveFile.setFileNumber("");
+        archiveFile.setFileName("文件名称");
+        archiveFile.setFileTime("20230413");
+        archiveFile.setFileUrl("http://example.com/file");
+        archiveFile.setPdfFileUrl("http://example.com/pdf");
+        archiveFile.setFilePage(10);
+        archiveFile.setIsApproval(1);
+        archiveFile.setIsNeedCertification(1);
+        archiveFile.setIsCertification(1);
+        archiveFile.setCertificationTime("2023-04-13 14:30:00");
+        archiveFile.setDutyUser("责任者");
+        archiveFile.setSheetType("图幅");
+        archiveFile.setSheetSource("图表来源");
+        archiveFile.setDrawingNo("图号");
+        archiveFile.setCiteChangeNumber("引用变更令编号");
+        archiveFile.setEVisaFile("http://example.com/evisa");
+        archiveFile.setNodeExtId(123L);
+        archiveFile.setFileType(1L);
+        archiveFile.setArchiveId(456L);
+        archiveFile.setOriginId(789L);
+        archiveFile.setFilmingTime(LocalDateTime.now().minusDays(2));
+        archiveFile.setFilmingorTime(LocalDateTime.now().minusDays(1));
+        archiveFile.setTagId("标签ID");
+        archiveFile.setPicCode("相片号");
+        archiveFile.setReferCode("参见号");
+        archiveFile.setFilmCode("底片号");
+        archiveFile.setWidth(800);
+        archiveFile.setHeight(600);
+
+        List<ArchiveFile> archiveFiles = new ArrayList<>();
+
+        for (int i = 0; i < 20;i++) {
+            archiveFiles.add(archiveFile);
+        }
+        buildArchiveFrontPdfs(projectId,archivesAuto,archiveFiles);
+    }
+
+
+    /**
+     *  生成四要素
+     * @param projectId
+     * @param archivesAuto, 会更新起始时间和结束时间,所以调用后要更新
+     * @param archiveFileList
+     */
+    public void buildArchiveFrontPdfs(Long projectId, ArchivesAuto archivesAuto,List<ArchiveFile> archiveFileList) {
+        // 调用 getByProjectIdOrNew 方法获取 ArchiveProjectConfig 对象,并从中取得 factorType 的值
+        ArchiveProjectConfig config = archiveProjectConfigService.getByProjectIdOrNew(projectId);
+
+        // 根据 factorType 字符串生成档案号码字符串链表
+        List<String> numberFronts = new ArrayList<>();
+        List<String> numberBacks = new ArrayList<>();
+        if (config.getFactorType().contains("1")) {
+            numberFronts.add(ARCHIVE_NUMBER[0]);
+        }
+        if (config.getFactorType().contains("2")) {
+            numberFronts.add(ARCHIVE_NUMBER[1]);
+        }
+        if (config.getFactorType().contains("3")) {
+            numberBacks.add(ARCHIVE_NUMBER[2]);
+        }
+        if (config.getFactorType().contains("4")) {
+            numberBacks.add(ARCHIVE_NUMBER[3]);
+        }
+
+        Map<String,Object> variables = dataSourceBuilder(archivesAuto,archiveFileList);
+
+        // 使用生成的档案号码字符串链表生成档案 PDF 文件
+        List<String> frontUrls = new ArrayList<>();
+        List<String> backUrls = new ArrayList<>();
+        for (String number : numberFronts) {
+            // 具体实现省略
+            buildFrontPdf(archivesAuto,number, variables,frontUrls);
+        }
+
+        for (String number : numberBacks) {
+            // 具体实现省略
+            buildFrontPdf(archivesAuto,number, variables,backUrls);
+        }
+
+        //将封面写入archivesAuto
+        frontUrls.addAll(backUrls);
+
+        //统计文件大小
+        flushFileSize(archivesAuto,archiveFileList,frontUrls);
+
+        String joinedUrls = String.join(", ", frontUrls);
+        archivesAuto.setOutUrl(joinedUrls);
+    }
+
+    /**
+     * 打码
+     * @param archivesAuto
+     * @param waitArchiveFiles
+     */
+    public void builtFilePageNo(ArchivesAuto archivesAuto,List<ArchiveFile> waitArchiveFiles){
+        //声影的要不要打码
+        if (archivesAuto.getCarrierType()!= null &&
+                archivesAuto.getCarrierType().equals("5")) {
+            return;
+        }
+
+        List<String> urls = new ArrayList<>();
+        for (ArchiveFile f: waitArchiveFiles) {
+            String url = getPdfFileUrl(f);
+            urls.add(url);
+        }
+
+        List<String> pageUrls = FileUtils.doForPageNumberUseItextpdf(urls,newIOSSClient);
+        for(int i=0;i<waitArchiveFiles.size();i++){
+            waitArchiveFiles.get(i).setPdfFileUrl(pageUrls.get(i));
+        }
+
+        return;
+    }
+
+
+
+    /**
+     *
+     * @param number  四要素的表名
+     * @param variables 参数集
+     * @param urls  返回的url
+     */
+    public void buildFrontPdf(ArchivesAuto archivesAuto,String number, Map<String,Object> variables,List<String> urls) {
+        // Step 1: Get the list of formulas using archiveFormulaConfigService
+        List<ArchiveFormulaConfig> formulaConfigs = archiveFormulaConfigService.getByNumber(number);
+
+        String file_path = FileUtils.LocalPath;
+        String excelUrl = getUrlByNumber(number);
+        Map<String, Object> dataInfo = new HashMap<>();
+
+        ArchiveFormulaConfig multiLineconfig = null;
+        String fileName = NAME_MAP.get(number)+ "-" + archivesAuto.getId();
+
+        for (ArchiveFormulaConfig config : formulaConfigs) {
+            String coords = config.getCoords();
+            String formula = config.getFormula();
+
+            if(variables.containsKey("ArchiveFile") && variables.get("ArchiveFile") instanceof List
+                    && formula.indexOf("ArchiveFile") >= 0){
+
+                multiLineconfig = config;
+                //handleArchiveFile(coords, formula, variables, file_path, excelUrl, dataInfo,urls);
+                continue;
+            }
+            else{
+                handleNonArchiveFile(config, coords, formula, variables, file_path, excelUrl, dataInfo);
+            }
+        }
+        //一起处理
+        if (multiLineconfig != null) {
+            String coords = multiLineconfig.getCoords();
+            String formula = multiLineconfig.getFormula();
+            handleArchiveFile(coords, formula, variables, file_path, excelUrl, dataInfo,urls,fileName);
+
+        }else {
+            try {
+                String url = getBussPdfInfo(fileName, dataInfo, excelUrl, file_path);
+                urls.add(url);
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+
+    }
+
+    /**
+     * 生成 卷内目录
+     * @param coords
+     * @param formula
+     * @param variables
+     * @param file_path
+     * @param excelUrl
+     * @param dataInfo
+     * @param urls
+     */
+    private void handleArchiveFile(String coords, String formula,
+                                   Map<String,Object> variables,String file_path,
+                                   String excelUrl, Map<String, Object> dataInfo,List<String> urls,String fileName){
+        //todo  目录多页合并一页,文件名带上
+
+
+        List<String> localUrls = new ArrayList<>();
+        String[] coordArr = coords.split("~");
+        if (coordArr.length == 2) {
+            DataVO dataVO1 = FormulaUtil.convertCellToIndex(coordArr[0]);
+            DataVO dataVO2 = FormulaUtil.convertCellToIndex(coordArr[1]);
+            Integer pageSize = dataVO2.getY() - dataVO1.getY() + 1;
+
+            List<Map<String,Object>> archiveFiles = (List<Map<String,Object>>)variables.get("ArchiveFile");
+
+            Map<String, Object> pageMap = new HashMap<>();
+            if(archiveFiles != null && archiveFiles.size() > 0){
+                int pageIndex = 0; // 当前页数
+                while (true) {
+                    List<Map<String,Object>> subList = archiveFiles.subList(pageIndex * pageSize,
+                            Math.min((pageIndex + 1) * pageSize, archiveFiles.size()));
+
+                    pageMap.clear();
+                    pageMap.putAll(dataInfo);
+
+                    int subIndex = 0;
+                    for (Map<String,Object> archiveMap : subList) {
+                        // 处理archiveFile逻辑
+                        int y = dataVO1.getY() + subIndex;
+                        List<Object> objects = FormulaUtil.expressionParseList(formula, archiveMap);
+                        int xIndex = 0;
+                        for (Object o: objects) {
+                            if (o == null) {
+                                xIndex++;
+                                continue;
+                            }
+                            int x = dataVO1.getX() + xIndex;
+                            String key = subIndex + "__" + y + "_" + x;
+                            pageMap.put(key, o);
+                            xIndex++;
+                        }
+
+                        subIndex++;
+                    }
+                    try {
+                        String url = getBussPdfInfo(fileName + subIndex, pageMap, excelUrl, file_path);
+                        localUrls.add(url);
+                    } catch (Exception e) {
+                        e.printStackTrace();
+                    }
+
+                    if (subList.size() < pageSize) {
+                        break;
+                    }
+
+                    pageIndex++;
+                }
+            }
+        }
+
+        //合并成一个
+        if (localUrls.size() > 1) {
+            Long id = SnowFlakeUtil.getId();
+            String trialPdf = file_path + "/pdf/" + id + ".pdf";
+
+            //合并当前所有选择的试验pdf
+            FileUtils.mergePdfPublicMethods(localUrls, trialPdf);
+            BladeFile bladeFile = this.newIOSSClient.uploadFile(fileName + ".pdf", trialPdf);
+
+
+//            ByteArrayOutputStream bos = new ByteArrayOutputStream();
+//            FileUtils.PdfCopyPublicMethods(bos, localUrls);
+//            BladeFile bladeFile = newIOSSClient.updateFile(bos.toByteArray(),fileName + ".pdf");
+            if (bladeFile!= null ) {
+                urls.add(bladeFile.getLink());
+            }
+        }
+    }
+
+    /**
+     * 生成 封面,备考表,脊背
+     * @param config
+     * @param coords
+     * @param formula
+     * @param variables 参数集
+     * @param file_path 本地路径
+     * @param excelUrl
+     * @param dataInfo  结果集
+     */
+    private void handleNonArchiveFile(ArchiveFormulaConfig config, String coords, String formula,
+                                      Map<String,Object> variables,String file_path,
+                                      String excelUrl, Map<String, Object> dataInfo) {
+        DataVO dataVO = FormulaUtil.convertCellToIndex(coords);
+        Object object = null;
+        if (formula.indexOf("~") > 0) {
+            String[] formulaArr = formula.split("~");
+            if (formulaArr.length == 2) {
+                Object object1 = FormulaUtil.expressionParse(formulaArr[0],variables);
+                Object object2 = FormulaUtil.expressionParse(formulaArr[1],variables);
+                object = object1 + "~" + object2;
+            }
+        }else {
+            object = FormulaUtil.expressionParse(formula,variables);
+        }
+
+
+        String key = config.getId() + "__" + dataVO.getY() + "_" + dataVO.getX();
+        dataInfo.put(key, object);
+    }
+
+
+    private static boolean isOssFilePath(String filePath) {
+        return filePath.contains("https") || filePath.contains("aliyun");
+    }
+
+    /**
+     * 生成单张pdf
+     * @param fileName   文件名
+     * @param DataInfo  excel和数据
+     * @param excelUrl  excel模板
+     * @param filePath  本地路径
+     * @return
+     * @throws Exception
+     */
+    public String getBussPdfInfo(String fileName,Map<String, Object> DataInfo,String excelUrl,String filePath) throws Exception{
+
+        if (fileName == null) {
+            fileName = SnowFlakeUtil.getId().toString();
+        }
+
+        String pdfPath = filePath + "/pdf//" + fileName + ".pdf";
+        String excelPath = filePath + "/pdf//" + fileName + ".xlsx";
+        File tabPdf = ResourceUtil.getFile(pdfPath);
+        if (tabPdf.exists()) {
+            tabPdf.delete();
+        }
+
+        // 获取excel流 和 html流
+        InputStream exceInp = null;
+        if ( isOssFilePath(excelUrl)){
+            exceInp = CommonUtil.getOSSInputStream(excelUrl);
+        }else {
+            exceInp = new FileInputStream(new File(excelUrl));
+        }
+
+        org.apache.poi.ss.usermodel.Workbook workbook = WorkbookFactory.create(exceInp);
+
+        //获取工作表
+        Sheet sheet = workbook.getSheetAt(0);
+        sheet.setHorizontallyCenter(true);
+        sheet.setVerticallyCenter(true);
+        sheet.setForceFormulaRecalculation(true);
+
+        if (ObjectUtil.isNotEmpty(DataInfo)) {
+            for (String val : DataInfo.keySet()) {
+                if (val.indexOf("__") >= 0) {
+                    String[] DataVal = val.split("__");
+                    String[] xy = DataVal[1].split("_");
+
+                    int x1 = 0;
+                    int y1 = 0;
+                    int x2 = 0;
+                    int y2 = 0;
+
+                    if (xy.length == 2 ) {
+                        x1 = Integer.parseInt(xy[1]);
+                        y1 = Integer.parseInt(xy[0]);
+                    }
+
+                    if (xy.length == 4 ) {
+                        x2 = Integer.parseInt(xy[3]);
+                        y2 = Integer.parseInt(xy[2]);
+                    }
+
+                    String myData = DataInfo.get(val) + "";
+
+                    //https:bladex-test-info.oss-cn-chengdu.aliyuncs.com//upload/20220819/b53cb6700db369381e3b03d7737bcdec.jpg__16_1
+                    if (myData.indexOf("https") >= 0 && myData.indexOf("aliyuncs") >= 0) {
+
+                        InputStream imageIn = CommonUtil.getOSSInputStream(myData);
+                        byte[] bytes = IOUtils.toByteArray(imageIn);
+                        // 这里根据实际需求选择图片类型
+                        int pictureIdx = workbook.addPicture(bytes, 6);
+
+                        CreationHelper helper = workbook.getCreationHelper();
+                        ClientAnchor anchor = helper.createClientAnchor();
+                        anchor.setCol1(x1); // param1是列号
+                        anchor.setCol2(x2);
+                        anchor.setRow1(y1); // param2是行号
+                        anchor.setRow2(y2); // param2是行号
+                        //
+                        Drawing drawing = sheet.createDrawingPatriarch();
+                        anchor.setAnchorType(ClientAnchor.AnchorType.MOVE_AND_RESIZE);
+                        // 插入图片
+                        Picture pict = drawing.createPicture(anchor, pictureIdx); // 调整图片占单元格百分比的大小,1.0就是100%
+                        pict.resize(1, 1);
+                        FileUtils.imageOrientation(sheet, anchor, new DataVO(x1 - 1, y1 - 1));
+
+                    }
+                    else {
+                        Row row = sheet.getRow(y1 );
+                        if (row != null) {
+                            Cell cell = row.getCell(x1 );
+                            if (cell != null || ObjectUtils.isNotEmpty(cell)) {
+                                cell.setCellValue(myData);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        FileOutputStream outputStream = new FileOutputStream(excelPath);
+        workbook.write(outputStream);
+        FileUtils.setExcelScaleToPdf(excelPath, pdfPath);
+        BladeFile bladeFile = newIOSSClient.uploadFile(fileName + ".pdf", pdfPath);
+
+        String pdfLink = "";
+        if (bladeFile!= null ){
+            pdfLink = bladeFile.getLink();
+        }
+        return pdfLink;
+    }
+
+    /**
+     *  生成四要素的数据源
+     * @param archive
+     * @param datas
+     * @return
+     */
+    public static  Map<String,Object> dataSourceBuilder(ArchivesAuto archive, List<ArchiveFile> datas){
+
+        //预处理
+        archive.setSecretLevel(FormulaUtil.securityLevelMap.get(archive.getSecretLevel()));
+        archive.setStorageTime(FormulaUtil.storageTimeMap.get(archive.getStorageTime()));
+        archive.setFileN(datas.size());
+
+        Integer idx = 0;
+        Integer iStartPage = 1;
+        List<Map<String, Object>> fileMapList = new ArrayList<>();
+
+        //todo  增加获取总大小
+        for (ArchiveFile file:  datas) {
+            idx++;
+            //设置序号
+            file.setId(idx.longValue());
+            //设置文件编号
+            if (StringUtil.isEmpty(file.getFileNumber())) {
+                file.setFileNumber("\\");
+            }
+            //设置页数
+            file.setPageNum(iStartPage.toString());
+
+            //最后一页
+            iStartPage +=   file.getFilePage();
+            if (idx >= datas.size() ) {
+                String lastPageNum = file.getPageNum() + "~" + iStartPage;
+                file.setPageNum(lastPageNum);
+            }
+
+
+
+            Map<String, Object> fileMap = new ObjectMapper().convertValue(file, Map.class);
+            fileMapList.add(fileMap);
+        }
+        //设置总页数
+        archive.setPageN(iStartPage - 1);
+
+        // 找出最小和最大日期
+        String minDate = "";
+        String maxDate = "";
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
+
+        for (ArchiveFile file : datas) {
+            String fileTime = file.getFileTime();
+            if (minDate.isEmpty() || fileTime.compareTo(minDate) < 0) {
+                minDate = fileTime;
+            }
+            if (maxDate.isEmpty() || fileTime.compareTo(maxDate) > 0) {
+                maxDate = fileTime;
+            }
+        }
+
+        // 将日期赋值给startDate和endDate
+        if (!minDate.isEmpty()) {
+            LocalDateTime localDateTime = FormulaUtil.parseStringToLocalDateTime(minDate,"yyyyMMdd");
+            archive.setStartDate(localDateTime);
+        }
+        if (!maxDate.isEmpty()) {
+            LocalDateTime localDateTime = FormulaUtil.parseStringToLocalDateTime(maxDate,"yyyyMMdd");
+            archive.setEndDate(localDateTime);
+        }
+
+        Map<String, Object> archivesAutoMap = new ObjectMapper().convertValue(archive, Map.class);
+        if (archive.getRollDate()!= null) {
+            archivesAutoMap.put("rollDate",FormulaUtil.formatLocalDateTime(archive.getRollDate(),"yyyy年MM月dd日"));
+        }
+
+        if (archive.getReviewDate()!= null) {
+            archivesAutoMap.put("reviewDate",FormulaUtil.formatLocalDateTime(archive.getReviewDate(),"yyyy年MM月dd日"));
+        }
+
+        if (archive.getStartDate()!= null) {
+            archivesAutoMap.put("startDate",FormulaUtil.formatLocalDateTime(archive.getStartDate(),"yyyyMMdd"));
+        }
+
+        if (archive.getEndDate()!= null) {
+            archivesAutoMap.put("endDate",FormulaUtil.formatLocalDateTime(archive.getEndDate(),"yyyyMMdd"));
+        }
+
+        Map<String,Object> variables = new HashMap<>();
+        variables.put("Archive",archivesAutoMap);
+
+        variables.put("ArchiveFile",fileMapList);
+        return  variables;
+    }
+
+    /**
+     * 获取四要素模板的url,这里写死,后续可以从清表的 ”归档“模板树下获取
+     * @param number
+     * @return
+     */
+    public String getUrlByNumber(String number) {
+        // Get the URL from the static map using the number as key
+        String url = URL_MAP.get(number);
+        return url;
+    }
+
+    /**
+     * 获取指定文件的pdf文件
+     * @param file
+     * @return
+     */
+    public String getPdfFileUrl(ArchiveFile file){
+        //
+        String url = file.getPdfFileUrl();
+        if (StringUtil.isEmpty(url)) {
+            url = file.getFileUrl();
+        }
+
+        //todo 生成相册内容,待补充
+
+
+        return url;
+    }
+
+    /**
+     * 刷新文件大小
+     * @param archive
+     * @param datas
+     * @param frontUrls
+     */
+    public void flushFileSize(ArchivesAuto archive,List<ArchiveFile> datas,List<String> frontUrls){
+
+        List<String> fileUrls = new ArrayList<>();
+        for (ArchiveFile file: datas) {
+            fileUrls.add(getPdfFileUrl(file));
+        }
+
+        fileUrls.addAll(frontUrls);
+        List<FileSize>  fileSizes = org.springblade.common.utils.FileUtils.getOssFileSize(fileUrls);
+
+        double totalSize = fileSizes.stream()
+                .mapToDouble(FileSize::getFileSize)
+                .sum();
+        Long total = (Long) Math.round(totalSize);
+        archive.setFileSize(total);
+
+        //todo 生成相册内容,待补充
+        int i = 0;
+        for (ArchiveFile file: datas) {
+            double size = fileSizes.get(i).getFileSize();
+            if (file.getFileSize()!= null) {
+                file.setFileSize(Math.round(size));
+            }
+        }
+    }
+
+}

+ 20 - 0
blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchiveFormulaConfigServiceImpl.java

@@ -0,0 +1,20 @@
+package org.springblade.archive.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import org.springblade.archive.entity.ArchiveFormulaConfig;
+import org.springblade.archive.mapper.ArchiveFormulaConfigMapper;
+import org.springblade.archive.service.IArchiveFormulaConfigService;
+import org.springblade.core.mp.base.BaseServiceImpl;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+public class ArchiveFormulaConfigServiceImpl extends BaseServiceImpl<ArchiveFormulaConfigMapper, ArchiveFormulaConfig> implements IArchiveFormulaConfigService {
+    @Override
+    public List<ArchiveFormulaConfig> getByNumber(String number) {
+        QueryWrapper<ArchiveFormulaConfig> wrapper = new QueryWrapper<>();
+        wrapper.lambda().eq(ArchiveFormulaConfig::getNumber, number);
+        return this.list(wrapper);
+    }
+}

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

@@ -18,7 +18,9 @@ package org.springblade.archive.service.impl;
 
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import lombok.AllArgsConstructor;
 import org.apache.commons.lang.StringUtils;
 import org.springblade.archive.entity.ArchivesAuto;
@@ -32,7 +34,12 @@ import org.springblade.core.mp.support.Condition;
 import org.springblade.core.mp.support.Query;
 import org.springblade.core.tool.utils.Func;
 import org.springblade.manager.entity.ArchiveTreeContract;
+import org.springblade.manager.entity.ContractInfo;
+import org.springblade.manager.entity.ProjectInfo;
 import org.springblade.manager.feign.ArchiveTreeContractClient;
+import org.springblade.manager.feign.ContractClient;
+import org.springblade.manager.feign.ProjectClient;
+import org.springblade.manager.feign.WbsInfoClient;
 import org.springblade.system.entity.DictBiz;
 import org.springblade.system.feign.IDictBizClient;
 import org.springframework.stereotype.Service;
@@ -40,6 +47,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
 
 import java.time.LocalDateTime;
 import java.util.*;
+import java.util.stream.Collectors;
 
 /**
  *  服务实现类
@@ -54,14 +62,46 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 	private final IDictBizClient iDictBizClient;
 	private ArchiveFileClient archiveFileClient;
 	private ArchiveTreeContractClient archiveTreeContractClient;
-
+	private ContractClient contractClient;
 	private Map<String,Integer> indexMap; //按立卷位区分和生成流水号
 
+
+
 	@Override
 	public IPage<ArchivesAutoVO> selectArchivesAutoPage(IPage<ArchivesAutoVO> page, ArchivesAutoVO archivesAuto) {
 		return page.setRecords(baseMapper.selectArchivesAutoPage(page, archivesAuto));
 	}
 
+	@Override
+	public IPage<ArchivesAutoVO> pageByArchivesAuto(ArchivesAutoVO vo) {
+		IPage<ArchivesAutoVO> page = new Page<>();
+		if (StringUtils.isNotBlank(vo.getStorageTime())) {
+			vo.setStorageTimes(Arrays.asList(vo.getStorageTime().split(",")));
+		}
+		if (StringUtils.isNotBlank(vo.getSecretLevel())){
+			vo.setSecretLevels(Arrays.asList(vo.getSecretLevel().split(",")));
+		}
+		if (StringUtils.isNotBlank(vo.getCarrierType())) {
+			vo.setCarrierTypes(Arrays.asList(vo.getCarrierType().split(",")));
+		}
+		if (StringUtils.isNotBlank(vo.getYear())) {
+			vo.setYears(Arrays.asList(vo.getYear().split(",")));
+		}
+		if (StringUtils.isNotBlank(vo.getMonth())) {
+			vo.setMonths(Arrays.asList(vo.getMonth().split(",")));
+		}
+		List<ArchivesAutoVO> archivesAutos = baseMapper.pageByArchivesAuto(page, vo);
+		archivesAutos.stream().forEach(aa->{
+			if (StringUtils.isNotBlank(aa.getStorageTime())){
+				aa.setStorageTimeValue("9999".equals(aa.getStorageTime())?"永久":("30".equals(aa.getStorageTime())?"30年":"10年"));
+			}
+			if (StringUtils.isNotBlank(aa.getSecretLevel())){
+				aa.setSecretLevelValue("1".equals(aa.getSecretLevel())?"机密":("2".equals(aa.getSecretLevel())?"绝密":"秘密"));
+			}
+		});
+		return page.setRecords(archivesAutos);
+	}
+
 	@Override
 	public IPage<ArchivesAutoVO> selectArchivesAutoFilePage(ArchivesAutoVO vo) {
 		Query query = new Query();
@@ -117,6 +157,53 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 		return true;
 	}
 
+	@Override
+	public Map<String, Integer> getAllArchiveByContractType(Long projectId,String typ) {
+		List<ArchivesAutoVO> list = baseMapper.getAllArchiveByContractType(projectId,typ);
+		List<ContractInfo> infos = contractClient.queryContractListByIds(Arrays.asList(projectId));
+		int key1=0,key2=0,key3=0;
+		//判断案卷属于1施工,2监理,还是3业主
+		for (ArchivesAutoVO l : list) {
+			String type = l.getContractType();
+			if (StringUtils.isBlank(type)){
+				//业主
+				key3++;
+			}else if ("S".equals(type)){
+				//监理
+				key2++;
+			}else if ("C".equals(type)){
+				//施工
+				key1++;
+			}else if (type.length() > 10){
+				for (ContractInfo info : infos) {
+					if (type.equals(info.getId()+"")){
+						Integer t = info.getContractType();
+						if (t == 1){
+							key1++;
+						}else if(t==2){
+							key2++;
+						}else {
+							key3++;
+						}
+						break;
+					}
+				}
+			}else {
+				System.out.println(type);
+			}
+		}
+		Map<String,Integer> map = new HashMap<>();
+		map.put("key1",key1);
+		map.put("key2",key2);
+		map.put("key3",key3);
+		return map;
+	}
+
+	@Override
+	public List<Map<String, String>> getAllArchiveAgeByContractType(Long projectId) {
+		List<Map<String,String>> list = baseMapper.getAllArchiveAgeByContractType(projectId);
+		return list;
+	}
 
 
 	public void archiveAutoMethod(Long projectId){

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

@@ -1,16 +1,30 @@
 package org.springblade.archive.utils;
 
+import com.aspose.cells.SaveFormat;
+import com.fasterxml.jackson.databind.ObjectMapper;
 import com.itextpdf.text.Document;
-import com.itextpdf.text.pdf.PdfCopy;
-import com.itextpdf.text.pdf.PdfReader;
+import com.itextpdf.text.Element;
+import com.itextpdf.text.pdf.*;
+import com.sun.image.codec.jpeg.JPEGCodec;
+import com.sun.image.codec.jpeg.JPEGImageEncoder;
+import org.apache.commons.collections4.ListUtils;
 import org.apache.commons.lang.StringUtils;
+import org.apache.poi.hssf.usermodel.HSSFPrintSetup;
 import org.apache.poi.ss.usermodel.ClientAnchor;
 import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.usermodel.WorkbookFactory;
 import org.apache.poi.ss.util.CellRangeAddress;
 import org.apache.poi.util.Units;
+import org.apache.poi.xssf.usermodel.XSSFPrintSetup;
+import org.apache.poi.xssf.usermodel.XSSFSheet;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+
 import org.springblade.common.utils.CommonUtil;
 import org.springblade.common.vo.DataVO;
+import org.springblade.core.oss.model.BladeFile;
 import org.springblade.core.tool.utils.IoUtil;
+import org.springblade.core.tool.utils.ResourceUtil;
+import org.springblade.resource.feign.NewIOSSClient;
 
 import javax.imageio.ImageIO;
 import javax.servlet.http.HttpServletResponse;
@@ -18,13 +32,22 @@ import java.awt.*;
 import java.awt.image.BufferedImage;
 import java.io.*;
 import java.net.URLEncoder;
-import java.util.Arrays;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
 import java.util.List;
 import java.util.regex.Matcher;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipOutputStream;
 
+
+
 public class FileUtils {
+    public static final String DOMAIN_REG = "https?://[^\\.]*\\.oss-cn-shenzhen\\.aliyuncs\\.com/";
+
+    public static final  String LocalPath = "/www/wwwroot/Users/hongchuangyanfa/Desktop/";
 
     public static void batchDownloadFileToZip(List<String> urls, HttpServletResponse response){
         // 设置压缩流:直接写入response,实现边压缩边下载
@@ -200,6 +223,13 @@ public class FileUtils {
 
             for(String urlStr : urlList){
                 try{
+                    if (urlStr.indexOf("https") >= 0 && urlStr.indexOf("aliyuncs") >= 0) {
+                        int lastIndexOf = urlStr.lastIndexOf("/");
+                        String prefix=urlStr.substring(0,lastIndexOf+1);
+                        String suffix=urlStr.substring(lastIndexOf+1);
+                        urlStr = prefix+ URLEncoder.encode(suffix,"UTF-8");
+                    }
+
                     //获取OSS文件输入流
                     reader = new PdfReader(CommonUtil.getOSSInputStream(urlStr));
 
@@ -229,4 +259,341 @@ public class FileUtils {
         }
     }
 
+    /**
+     * excel 转pdf
+     * @param exUrl
+     * @param pdfUrl
+     */
+    public static void excelToPdf(String exUrl,String pdfUrl){
+
+        org.apache.poi.ss.usermodel.Workbook ss = null;
+        ByteArrayInputStream byteArrayInputStream = null;
+        InputStream pdfInput = null;
+        ByteArrayOutputStream outReport = null, bos = null;
+        try{
+            File file1 = ResourceUtil.getFile(exUrl);
+            InputStream inputStream = new FileInputStream(file1);
+            ss = WorkbookFactory.create(inputStream);
+            for(int i = 0, l = ss.getNumberOfSheets(); i < l; i ++){
+                Sheet sheet = ss.getSheetAt(i);
+                //去掉表格虚线
+                sheet.setPrintGridlines(false);
+                //设置 整个工作表为一页
+                sheet.setFitToPage(true);
+
+            }
+            outReport = new ByteArrayOutputStream();
+            ss.write(outReport);
+            byteArrayInputStream = new ByteArrayInputStream(outReport.toByteArray());
+            com.aspose.cells.Workbook wb = new com.aspose.cells.Workbook(byteArrayInputStream);
+            File pdfFile = new File(pdfUrl);
+            if(!pdfFile.exists()){
+                pdfFile.mkdir();
+            }
+            wb.save(pdfUrl, SaveFormat.PDF);
+        }catch (Exception e){
+            e.printStackTrace();
+        } finally {
+            if(bos != null){
+                IoUtil.closeQuietly(bos);
+            }
+            if(outReport != null){
+                IoUtil.closeQuietly(outReport);
+            }
+            if(pdfInput != null){
+                IoUtil.closeQuietly(pdfInput);
+            }
+            if(byteArrayInputStream != null){
+                IoUtil.closeQuietly(byteArrayInputStream);
+            }
+            if(ss != null){
+                IoUtil.closeQuietly(ss);
+            }
+        }
+    }
+
+    /**
+     * 图片压缩
+     * @param imgUrl
+     */
+    public static void CompressImage(String imgUrl,InputStream img){
+        try {
+            //图片所在路径
+            BufferedImage templateImage = ImageIO.read(img);
+            //原始图片的长度和宽度
+            int height = templateImage.getHeight();
+            int width = templateImage.getWidth();
+
+            //通过比例压缩
+            float scale = 0.5f;
+
+            //通过固定长度压缩
+            /*int doWithHeight = 100;
+            int dowithWidth = 300;*/
+
+            //压缩之后的长度和宽度
+            int doWithHeight = (int) (scale * height);
+            int dowithWidth = (int) (scale * width);
+
+            BufferedImage finalImage = new BufferedImage(dowithWidth, doWithHeight, BufferedImage.TYPE_INT_RGB);
+
+            finalImage.getGraphics().drawImage(templateImage.getScaledInstance(dowithWidth, doWithHeight, java.awt.Image.SCALE_SMOOTH), 0, 0, null);
+
+
+            //图片输出路径,以及图片名
+            FileOutputStream  fileOutputStream = new FileOutputStream(imgUrl);
+            JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(fileOutputStream);
+            encoder.encode(finalImage);
+            fileOutputStream.close();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+
+
+    /**
+     * excel设置 打印缩放比例
+     *
+     * @param inputPath
+     * @param outPath
+     */
+    public static void setExcelScaleToPdf(String inputPath, String outPath) {
+        //读取excel文件
+        XSSFWorkbook workbook = null;
+        ByteArrayOutputStream outReport = null, bos = null;
+        ByteArrayInputStream byteArrayInputStream = null;
+        try {
+            workbook = new XSSFWorkbook(new FileInputStream(inputPath));
+        } catch (FileNotFoundException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        OutputStream fos = null;
+        try {
+            for (int i = 0; i < workbook.getNumberOfSheets(); i++) {//获取每个Sheet表
+                XSSFSheet sheet = workbook.getSheetAt(i);
+                //打印设置
+                XSSFPrintSetup print = sheet.getPrintSetup();
+                // print.setLandscape(true); // 打印方向,true:横向,false:纵向(默认)
+                //   print.setFitHeight((short)0);//设置高度为自动分页
+                print.setFitWidth((short)1);//设置宽度为一页
+                print.setPaperSize(HSSFPrintSetup.A4_PAPERSIZE); //纸张类型
+//                print.setScale((short)55);//自定义缩放①,此处100为无缩放
+                //启用“适合页面”打印选项的标志
+                sheet.setFitToPage(true);
+            }
+            // Excel文件生成后存储的位置。
+            outReport = new ByteArrayOutputStream();
+            workbook.write(outReport);
+            byteArrayInputStream = new ByteArrayInputStream(outReport.toByteArray());
+            com.aspose.cells.Workbook wb = new com.aspose.cells.Workbook(byteArrayInputStream);
+            File pdfFile = new File(outPath);
+            if(!pdfFile.exists()){
+                pdfFile.mkdir();
+            }
+            wb.save(outPath, SaveFormat.PDF);
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            if (fos != null) {
+                try {
+                    fos.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+            if (workbook != null) {
+                try {
+                    workbook.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+
+
+
+    /**
+     * @Description  给多个PDF添加页码,按顺序依次累加
+     * @Param [uris, storeName]
+     * @return java.util.List<java.lang.String>
+     * @Author yangyj
+     * @Date 2021.12.17 14:21
+     **/
+    public static List<String> doForPageNumberUseItextpdf(List<String> uris, NewIOSSClient newIOSSClient)  {
+        List<String> result = new ArrayList<>();
+        if(uris!= null && uris.size() > 0){
+            int cursor=0;
+            for(String url:uris) {
+                try {
+                    //todo 匿名访问特性
+
+                    String fileNameWithExtension = url.substring(url.lastIndexOf("/") + 1); // 获取带有扩展名的文件名
+
+                    String fileNameWithoutExtension = fileNameWithExtension.substring(0, fileNameWithExtension.lastIndexOf("."));
+
+                    if (url.indexOf("https") >= 0 && url.indexOf("aliyuncs") >= 0) {
+                          int lastIndexOf = url.lastIndexOf("/");
+                          String prefix=url.substring(0,lastIndexOf+1);
+                          String suffix=url.substring(lastIndexOf+1);
+                          url = prefix+ URLEncoder.encode(suffix,"UTF-8");
+                    }
+                    PdfReader pdfReader = new PdfReader(url);
+                    ByteArrayOutputStream out = new ByteArrayOutputStream();
+                    PdfStamper pdfStamper = new PdfStamper(pdfReader, out);
+                    int index = 1;
+                    boolean fi;
+//                    String path = u.replaceAll(FileUtils.DOMAIN_REG, "").replaceAll(".((?i)(pdf))$", "").replace("folderFile", FolderFileHelper.ARCHIVED_FILE).replace("showtmp",FolderFileHelper.ARCHIVED_FILE);
+                    FileOutputStream fos = null;
+                    String page = "page" + (cursor + 1);
+                    do {
+                        PdfContentByte over = pdfStamper.getOverContent(index);
+                        if (over != null) {
+                            over.beginText();
+                            BaseFont bf = BaseFont.createFont(BaseFont.HELVETICA, BaseFont.WINANSI, BaseFont.EMBEDDED);
+                            over.setFontAndSize(bf, 16);
+                            over.setTextMatrix(30, 300);
+
+
+                            PdfArray pa = pdfReader.getPageN(index).getAsArray(new PdfName("MediaBox"));
+                            int width = pa.getAsNumber(2).intValue();
+                            int heigh = pa.getAsNumber(3).intValue();
+
+                            if(width>heigh){
+                                //横表旋转270
+                                pdfReader.getPageN(index).put(PdfName.ROTATE, new PdfNumber(270)); // 顺时针旋转270°
+                                //横表旋转后打页码坐标不一样
+                                over.showTextAligned(Element.ALIGN_LEFT, String.valueOf(cursor + index), heigh - 35, 20, 0);
+                            }else{
+                                over.showTextAligned(Element.ALIGN_LEFT, String.valueOf(cursor + index), width - 35, 20, 0);
+                            }
+                            over.endText();
+                            index++;
+                            fi = true;
+                        } else {
+                            /*累加*/
+                            cursor += index-1;
+                            /*重置*/
+                            fi = false;
+                            index = 1;
+                        }
+                    } while (fi);
+                    pdfStamper.close();
+                    page = page + "-" + cursor + ".pdf";
+                    String fileName = fileNameWithoutExtension +  "-" +  page;
+                    String filePath = LocalPath + fileName;
+                    if (newIOSSClient!= null ) {
+                        BladeFile bladeFile  = newIOSSClient.updateFile(out.toByteArray(),fileName);
+                        result.add(bladeFile.getLink());
+                    }else {
+                        fos = new FileOutputStream(filePath);
+                        fos.write(out.toByteArray()); // 将数据写入到指定文件路径中
+                        result.add(filePath);
+                    }
+
+                    out.close();
+                }catch(Exception e){
+                    System.out.println(url+"文件不存在");
+                    /*用来占位置空*/
+                    result.add("");
+                    e.printStackTrace();
+                }
+            }
+        }
+        return result;
+    }
+
+
+
+    /**
+     * @Description 合并PDF
+     * @Param [bos:结果存在字节数组, uris:支持 file、http、jar等传输协议]
+     * @return void
+     * @Author yangyj
+     * @Date 2021.10.09 10:49
+     **/
+    public static void PdfCopyPublicMethods1(ByteArrayOutputStream bos,List<String> uris){
+        
+        PdfReader reader = null;
+        Document doc = new Document();
+        PdfCopy pdfCopy = null;
+        try{
+            pdfCopy = new PdfCopy(doc, bos);
+            int pageCount;
+            doc.open();
+
+            for(String urlStr : uris){
+
+                try{
+                    String url=urlStr;
+                    String fileNameWithExtension = url.substring(url.lastIndexOf("/") + 1); // 获取带有扩展名的文件名
+
+                    String fileNameWithoutExtension = fileNameWithExtension.substring(0, fileNameWithExtension.lastIndexOf("."));
+
+                    if (url.indexOf("https") >= 0 && url.indexOf("aliyuncs") >= 0) {
+                        int lastIndexOf = url.lastIndexOf("/");
+                        String prefix=url.substring(0,lastIndexOf+1);
+                        String suffix=url.substring(lastIndexOf+1);
+                        url = prefix+ URLEncoder.encode(suffix,"UTF-8");
+                    }
+
+                    reader = new PdfReader(url);
+                    pageCount = reader.getNumberOfPages();
+
+                    for(int i = 0; i < pageCount; ++i){
+                        int is = i + 1;
+                        pdfCopy.addPage(pdfCopy.getImportedPage(reader,is));
+                    }
+                }catch (Exception e){
+                    e.printStackTrace();
+                } finally {
+                    if(reader != null){
+                        reader.close();
+                    }
+                }
+            }
+            String filePath = "D:\\tmp\\aaa.pdf";
+            FileOutputStream fos = null;
+            fos = new FileOutputStream(filePath);
+            //bos.reset();
+            fos.write(bos.toByteArray()); // 将数据写入到指定文件路径中
+            //bos.flush();
+            //bos.close();
+            System.out.println();
+        }catch (Exception e){
+            e.printStackTrace();
+        } finally {
+            if(pdfCopy != null){
+                pdfCopy.flush();
+                pdfCopy.close();
+            }
+            doc.close();
+        }
+
+
+
+    }
+
+    public static final  String MAP4_AVI = "avi、wmv、mpeg、mp4、m4v、mov、asf、flv、f4v、rmvb、rm、3gp、vob";
+    public static final  String XLS_XLSX = "xlsx、xls";
+    public static final  String DOC_DOCX = "doc、docx";
+    public static final  String IMAGE_JPG = "bmp、jpg、png、tif、gif、pcx、tga、exif、fpx、svg、psd、cdr、pcd、dxf、ufo、eps、ai、raw、WMF、webp、avif、apng";
+    public static int getFileType(String fileName) {
+        fileName = fileName.toLowerCase();
+        if(IMAGE_JPG.contains(fileName)){
+            return 1;
+        }else if(MAP4_AVI.contains(fileName)){
+            return 2;
+        }else if(XLS_XLSX.contains(fileName)){
+            return 3;
+        }else if(DOC_DOCX.contains(fileName)){
+            return 4;
+        }else if("pdf".contains(fileName)){
+            return 5;
+        }
+        return 99;
+    }
 }

+ 184 - 0
blade-service/blade-archive/src/main/java/org/springblade/archive/utils/FormulaUtil.java

@@ -0,0 +1,184 @@
+package org.springblade.archive.utils;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.springblade.common.vo.DataVO;
+import org.springblade.manager.entity.ArchiveTree;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class FormulaUtil {
+
+    public static Map<String, String> securityLevelMap = new HashMap<>();
+    static {
+        securityLevelMap.put("1", "机密");
+        securityLevelMap.put("2", "绝密");
+        securityLevelMap.put("3", "秘密");
+        securityLevelMap.put("4", "公开");
+    }
+
+    public static Map<String, String> storageTimeMap = new HashMap<>();
+    static {
+        storageTimeMap.put("1", "10年");
+        storageTimeMap.put("2", "30年");
+        storageTimeMap.put("3", "永久");
+    }
+
+    /**
+     * 时间格式转化,传入"yyyy.MM.dd" 或者 "yyyyMMdd"
+     * @param dateTime
+     * @param pattern
+     * @return
+     */
+    public static String formatLocalDateTime(LocalDateTime dateTime, String pattern) {
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
+        return dateTime.format(formatter);
+    }
+
+    /**
+     *  传入 "20230413", "yyyyMMdd";
+     * @param strDate
+     * @param pattern
+     * @return
+     */
+    public static LocalDateTime parseStringToLocalDateTime(String strDate, String pattern) {
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
+        LocalDate date = LocalDate.parse(strDate, formatter);
+        return LocalDateTime.of(date, LocalTime.MIN);
+    }
+
+
+    /**
+     *  excel 左边转换成从0开始的x,y
+     * @param cellRef
+     * @return
+     */
+    public static DataVO convertCellToIndex(String cellRef) {
+        DataVO dataVO = new DataVO();
+        int idx = 0;
+        for (int i = 0; i < cellRef.length(); i++) {
+            char ch = Character.toUpperCase(cellRef.charAt(i));
+            if (Character.isLetter(ch)) {
+                // 计算字母对应的数字
+                idx = idx * 26 + (ch - 'A');
+                dataVO.setX(idx);
+
+            } else {
+                // 计算数字对应的行数
+                idx = Integer.parseInt(cellRef.substring(i)) - 1;
+                dataVO.setY(idx);
+                break;
+            }
+        }
+        return dataVO;
+    }
+
+
+    /**
+     *  解析单个如 Archive['fileNumber']
+     * @param formula
+     * @param variables
+     * @return
+     */
+    public static Object expressionParse(String formula, Map<String,Object> variables){
+
+        //后期转成Expression库,Object data = Expression.parse(formula).calculate(variables);
+        //需要将需要将Expression, 库放到公共位置
+
+
+        // 去除字符串中的引号
+        String key = formula.replaceAll("'", "");
+        // 以左中括号和右中括号进行字符串分割
+        String[] splittedKey = key.split("\\[|\\]");
+        // 确保分割后的数组长度为2
+        if (splittedKey.length < 2) {
+            return null;
+        }
+        // 获取对象名称和属性名称
+        String objectName = splittedKey[0];
+        String propertyName = splittedKey[1];
+        // 从map中获取名为objectName的Object
+        Object object = variables.get(objectName);
+        // 如果Object为null或不是Map类型,则返回null
+        if (object == null || !(object instanceof Map<?, ?>)) {
+            return null;
+        }
+        // 将Object转换为Map类型
+        Map<String, Object> objectMap = (Map<String, Object>) object;
+        // 使用propertyName作为key获取对应的属性值
+        Object propertyValue = objectMap.get(propertyName);
+        // 返回属性值
+        return propertyValue;
+
+    }
+
+    /**
+     * 解析多个,如ArchiveFile['id','fileNumber','dutyUser','fileName','fileTime','pageNum',' ']
+     * @param formula
+     * @param variables
+     * @return
+     */
+    public static List<Object> expressionParseList(String formula, Map<String, Object> variables) {
+        List<Object> result = new ArrayList<>();
+
+        Pattern pattern = Pattern.compile("([^\\[\\],']+)|'([^']*)'"); // 创建正则表达式模式
+        Matcher matcher = pattern.matcher(formula); // 匹配字符串
+
+        List<String> props = new ArrayList<>();
+        while (matcher.find()) { // 查找匹配的子串
+            for (int i = 1; i <= matcher.groupCount(); ++i) {
+                if (matcher.group(i) != null) {
+                    props.add(matcher.group(i));
+                }
+            }
+        }
+
+        int i = 0;
+        for (String prop1:props) {
+            if (i == 0) {
+                i++;
+                continue;
+            }
+            String prop = prop1.trim();
+            Object value = variables.get(prop);
+            if (value == null) { // handle null values
+                result.add("");
+            } else {
+                result.add(value);
+            }
+            if (prop.equals(" ")) { // handle empty string values
+                result.add("");
+            }
+        }
+
+        return result;
+    }
+
+    /*public static void main(String[] args) {
+
+        String formula = "ArchiveFile['id','fileNumber','fileName','dutyUser','fileTime','pageNum',' ']";
+        Pattern pattern = Pattern.compile("([^\\[\\],']+)|'([^']*)'"); // 创建正则表达式模式
+        Matcher matcher = pattern.matcher(formula); // 匹配字符串
+
+        List<String> props = new ArrayList<>();
+        while (matcher.find()) { // 查找匹配的子串
+            for (int i = 1; i <= matcher.groupCount(); ++i) {
+                if (matcher.group(i) != null) {
+                    props.add(matcher.group(i));
+                }
+            }
+        }
+
+        System.out.println();
+    }*/
+
+
+}

+ 5 - 0
blade-service/blade-business/pom.xml

@@ -155,6 +155,11 @@
             <artifactId>jsoup</artifactId>
             <version>1.10.2</version>
         </dependency>
+        <dependency>
+            <groupId>com.drewnoakes</groupId>
+            <artifactId>metadata-extractor</artifactId>
+            <version>2.16.0</version>
+        </dependency>
 
     </dependencies>
 

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

@@ -114,6 +114,72 @@ public class EVisaTaskCheckController {
         return R.data(300, false, "未选择审批人!!!");
     }
 
+    /**
+     * 资料查询批量上报,检查自定义流程,审批人权限
+     */
+    @PostMapping("/checkCustomFlowUserIsEVisaPermissions2")
+    @ApiOperation(value = "资料查询批量上报,检查自定义流程,审批人权限")
+    @ApiOperationSupport(order = 6)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "customFlowUserList", value = "所选的任务人集合,集合形式", required = true),
+            @ApiImplicitParam(name = "contractId", value = "合同段ID", required = true),
+            @ApiImplicitParam(name = "privatePKeyId", value = "表单列表中的isTypePrivatePid字段,集合形式"),
+            @ApiImplicitParam(name = "theLogPrimaryKeyId", value = "日志左侧所选的填报类型ID"),
+            @ApiImplicitParam(name = "firstId", value = "首件记录ID,列表批量上报时传任意一个即可")
+    })
+    public R<Boolean> batchCheckCustomFlowUserIsEVisaPermissions2(@RequestBody JSONObject json) {
+        if (json.containsKey("customFlowUserList") && !json.getJSONArray("customFlowUserList").isEmpty()) {
+            //获取审批人
+            List<Long> customFlowUserList = json.getJSONArray("customFlowUserList").toJavaList(Long.class);
+            //获取这些审批人在当前合同段的权限
+            List<JSONObject> userRoleList = this.saveUserInfoByProjectClient.queryUserContractRole(customFlowUserList, json.getString("contractId"));
+            if (userRoleList == null || userRoleList.size() <= 0) {
+                return R.data(300, false, "所选审批人均未找到当前表格所需要的签字岗位,请联系服务人员处理");
+            }
+
+            //获取电签配置
+            List<String> list = json.getJSONArray("wbsIds").toJavaList(String.class);
+            Set<String> userNameFail = new HashSet<>();
+            for (String nodeId : list) {
+                WbsTreeContract contract = wbsTreeContractClient.getContractWbsTreeByPrimaryKeyId(Long.valueOf(nodeId));
+                List<WbsTreeContract> node = wbsTreeContractClient.queryChildByParentId(contract,"", "");
+                List<Long> ids = new ArrayList<>();
+                for (WbsTreeContract treeContract : node) {
+                    WbsTreePrivate wbsTreePrivate = wbsTreePrivateClient.queryPeersNodeByProjectIdAndId(treeContract.getProjectId(), treeContract.getId());
+                    ids.add(wbsTreePrivate.getPKeyId());
+                }
+                JSONObject object = new JSONObject();
+                object.put("privatePKeyId",ids);
+                List<JSONObject> jsonList = this.queryTableEVisaConfig(object);
+                if (jsonList == null || jsonList.size() <= 0) {
+                    return R.data(300, false, "未找到符合电签配置的相关流程,请联系服务人员处理");
+                }
+
+                //汇总电签配置的审批角色
+                List<String> eVisaRoleList = jsonList.stream().map(jsonObject -> jsonObject.getString("sigRoleId")).distinct().collect(Collectors.toList());
+
+                //检查
+                //循环审批人的角色集合,并判断电签配置中是否含有这个角色
+                for (JSONObject userRole : userRoleList) {
+                    if (!eVisaRoleList.contains(userRole.getString("roleId"))) {
+                        User user = this.userClient.userInfoById(userRole.getLong("userId")).getData();
+                        userNameFail.add(user.getRealName());
+                    }
+                }
+
+            }
+            //批量提示
+            if (userNameFail.size() > 0) {
+                return R.data(300, false, "所选中的用户【" + StringUtils.join(userNameFail, ",") + "】不具备当前表格所需要的签字岗位,请联系维护人员处理或更换审批人员");
+            }
+
+            //均满足
+            return R.data(true);
+        }
+
+        return R.data(300, false, "未选择审批人!!!");
+    }
+
     /**
      * 获取符合条件的预设流程(三大填报页、日志列表的批量上报、首件列表的批量上报)
      */
@@ -363,7 +429,6 @@ public class EVisaTaskCheckController {
         } else {
             //资料填报
             //jsonList = this.eVisaConfigClient.queryEVisaConfigAllByTableIds(json.getJSONArray("privatePKeyId").toJavaList(String.class));
-
             List<String> ids = json.getJSONArray("privatePKeyId").toJavaList(String.class);
             String sql = "select * from m_textdict_info where tab_id in(" + StringUtils.join(ids, ",") + ")";
             List<TextdictInfo> query = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(TextdictInfo.class));

+ 4 - 7
blade-service/blade-business/src/main/java/org/springblade/business/controller/ImageClassificationFileController.java

@@ -173,7 +173,7 @@ public class ImageClassificationFileController extends BladeController {
                     List<String> removeList = new ArrayList<>();
 
                     //压缩到小于指定文件大小
-                    double targetSize = 200 * 1024;
+                    //double targetSize = 200 * 1024;
 
                     for (ImageClassificationFile file : fileResult) {
                         //获取图片文件流
@@ -214,14 +214,11 @@ public class ImageClassificationFileController extends BladeController {
                                             byte[] bytes = CommonUtil.InputStreamToBytes(CommonUtil.getOSSInputStream(urls.get(i)));
 
                                             //压缩文件大小
-                                            while (bytes.length > targetSize) {
-                                                float reduceMultiple = 0.5f;
-                                                bytes = FileUtils.resizeImage(bytes, reduceMultiple);
-                                            }
-                                            byte[] bytesNew = bytes;
+                                            byte[] byteNew = FileUtils.compressImage(bytes);
 
                                             //创建图片
-                                            drawing.createPicture(anchor, workbook.addPicture(bytesNew, Workbook.PICTURE_TYPE_PNG));
+                                            Picture picture = drawing.createPicture(anchor, workbook.addPicture(byteNew, Workbook.PICTURE_TYPE_PNG));
+                                            picture.resize();
 
                                             //图片定位
                                             FileUtils.imageOrientation(sheet, anchor, i == 1 ? new DataVO(1, 28) : new DataVO(0, 0));

+ 596 - 120
blade-service/blade-business/src/main/java/org/springblade/business/controller/InformationWriteQueryController.java

@@ -1,7 +1,5 @@
 package org.springblade.business.controller;
 
-import cn.hutool.core.lang.hash.Hash;
-import com.alibaba.excel.util.DateUtils;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
@@ -28,12 +26,9 @@ import org.springblade.business.service.*;
 import org.springblade.business.socket.WebSocket;
 import org.springblade.business.utils.FileUtils;
 import org.springblade.business.vo.*;
-import org.springblade.common.constant.BusinessConstant;
 import org.springblade.common.constant.CommonConstant;
-import org.springblade.common.constant.LauncherConstant;
 import org.springblade.common.utils.CommonUtil;
 import org.springblade.common.utils.SnowFlakeUtil;
-import org.springblade.core.cache.utils.CacheUtil;
 import org.springblade.core.log.exception.ServiceException;
 import org.springblade.core.mp.support.Condition;
 import org.springblade.core.mp.support.Query;
@@ -41,10 +36,7 @@ import org.springblade.core.oss.model.BladeFile;
 import org.springblade.core.secure.utils.AuthUtil;
 import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.node.ForestNodeMerger;
-import org.springblade.core.tool.utils.DateUtil;
-import org.springblade.core.tool.utils.Func;
-import org.springblade.core.tool.utils.ObjectUtil;
-import org.springblade.core.tool.utils.StringUtil;
+import org.springblade.core.tool.utils.*;
 import org.springblade.evisa.feign.EVisaClient;
 import org.springblade.evisa.vo.CertBeanVO;
 import org.springblade.manager.entity.*;
@@ -56,11 +48,6 @@ import org.springblade.system.entity.DictBiz;
 import org.springblade.system.feign.IDictBizClient;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.cache.annotation.CacheEvict;
-import org.springframework.cache.annotation.CachePut;
-import org.springframework.cache.annotation.Cacheable;
-import org.springframework.cache.annotation.Caching;
-import org.springframework.data.redis.core.RedisConnectionUtils;
 import org.springframework.data.redis.core.StringRedisTemplate;
 import org.springframework.jdbc.core.BeanPropertyRowMapper;
 import org.springframework.jdbc.core.JdbcTemplate;
@@ -73,8 +60,6 @@ import java.io.IOException;
 import java.util.*;
 import java.util.stream.Collectors;
 
-import static org.springblade.core.cache.constant.CacheConstant.SYS_CACHE;
-
 /**
  * 资料填报及查询控制器
  *
@@ -918,7 +903,7 @@ public class InformationWriteQueryController extends BladeController {
     @ApiOperation(value = "批量打印")
     public R<String> batchPrint(@RequestParam String ids) {
         //判断是否未生成文件
-        List<String> list = Arrays.asList(ids.split(","));
+        String[] list = ids.split(",");
         for (String s : list) {
             if (StringUtils.isBlank(s)) {
                 return R.fail("选择的资料未生成文件");
@@ -980,7 +965,7 @@ public class InformationWriteQueryController extends BladeController {
     public R<String> batchDownloadFileToZip(String ids, HttpServletResponse response) {
         if (StringUtils.isNotEmpty(ids)) {
             //判断是否未生成文件
-            List<String> list = Arrays.asList(ids.split(","));
+            String[] list = ids.split(",");
             for (String s : list) {
                 if (StringUtils.isBlank(s)) {
                     return R.fail("选择的资料未生成文件");
@@ -1339,104 +1324,556 @@ public class InformationWriteQueryController extends BladeController {
     @ApiOperationSupport(order = 15)
     @ApiOperation(value = "复制节点(新)")
     public R<Boolean> copyContractTreeNode(@RequestBody CopyContractTreeNodeVO vo) {
-        //首先查询需要复制的节点及其下级所有子节点的信息
-        WbsTreeContract needCopyNode = this.wbsTreeContractClient.getContractNodeByPrimaryKeyId(vo.getNeedCopyPrimaryKeyId());
-        // 获取当前节点的所有子节点
-        String vocational = SnowFlakeUtil.getId() + "";
-        //新增施工台账
-        List<WbsTreeContract> saveList = new ArrayList<>();
-        List<ConstructionLedger> saveLedger = new ArrayList<>();
-        // 获取附件
-        List<WbsTreeContract> nodeChildAll = informationQueryService.getNodeChildAllByNodeId(needCopyNode.getId() + "", needCopyNode.getContractId(), vo.getNeedCopyPrimaryKeyId());
-        // 获取实体表列对象
-        List<QueryProcessDataVO> nodeTabCols = informationQueryService.getNodeChildTabColsAllByNodeId(needCopyNode.getId() + "", needCopyNode.getContractId());
-        // 转化为map
-        Map<String, String> nodeTabColsMap = nodeTabCols.stream().collect(Collectors.toMap(QueryProcessDataVO::getQueryType, QueryProcessDataVO::getAncestors, (key1, key2) -> key2));
-        StringBuilder copeSql = new StringBuilder();
-
-        if (StringUtils.isNotEmpty(vo.getNeedCopyPrimaryKeyId())) {
-            WbsTreeContract parent = this.wbsTreeContractClient.getContractNodeByPrimaryKeyId(vo.getParentPrimaryKeyId());
-            //重塑关键信息
-            Map<Long, Long> oldToNewIdMap = new HashMap<>();
-            //节点信息
-            Map<String, WbsTreeContract> nodeMap = new HashMap<>();
-            nodeChildAll.forEach(node -> {
-                oldToNewIdMap.put(node.getId(), SnowFlakeUtil.getId());
-                nodeMap.put(node.getId().toString(), node);
-            });
+        //TODO 单份复制
+        if (("1").equals(vo.getCopyType())) {
+            //首先查询需要复制的节点及其下级所有子节点的信息
+            WbsTreeContract needCopyNode = this.wbsTreeContractClient.getContractNodeByPrimaryKeyId(vo.getNeedCopyPrimaryKeyId());
+            // 获取当前节点的所有子节点
+            String vocational = SnowFlakeUtil.getId() + "";
+            //新增施工台账
+            List<WbsTreeContract> saveList = new ArrayList<>();
+            List<ConstructionLedger> saveLedger = new ArrayList<>();
+            // 获取附件
+            List<WbsTreeContract> nodeChildAll = informationQueryService.getNodeChildAllByNodeId(needCopyNode.getId() + "", needCopyNode.getContractId(), vo.getNeedCopyPrimaryKeyId());
+            // 获取实体表列对象
+            List<QueryProcessDataVO> nodeTabCols = informationQueryService.getNodeChildTabColsAllByNodeId(needCopyNode.getId() + "", needCopyNode.getContractId());
+            // 转化为map
+            Map<String, String> nodeTabColsMap = nodeTabCols.stream().collect(Collectors.toMap(QueryProcessDataVO::getQueryType, QueryProcessDataVO::getAncestors, (key1, key2) -> key2));
+            StringBuilder copeSql = new StringBuilder();
 
-            //todo 单份复制
-            nodeChildAll.forEach(node -> {
-                WbsTreeContract newData = new WbsTreeContract();
-                BeanUtils.copyProperties(node, newData);
+            if (StringUtils.isNotEmpty(vo.getNeedCopyPrimaryKeyId())) {
+                WbsTreeContract parent = this.wbsTreeContractClient.getContractNodeByPrimaryKeyId(vo.getParentPrimaryKeyId());
                 //重塑关键信息
-                //重塑primaryKeyId
-                newData.setPKeyId(SnowFlakeUtil.getId());
-                //设置旧ID
-                if (StringUtils.isNotEmpty(node.getOldId())) {
-                    newData.setOldId(node.getOldId());
-                } else {
-                    newData.setOldId(node.getId().toString());
+                Map<Long, Long> oldToNewIdMap = new HashMap<>();
+                //节点信息
+                Map<String, WbsTreeContract> nodeMap = new HashMap<>();
+                nodeChildAll.forEach(node -> {
+                    oldToNewIdMap.put(node.getId(), SnowFlakeUtil.getId());
+                    nodeMap.put(node.getId().toString(), node);
+                });
+
+                nodeChildAll.forEach(node -> {
+                    WbsTreeContract newData = new WbsTreeContract();
+                    BeanUtils.copyProperties(node, newData);
+                    //重塑关键信息
+                    //重塑primaryKeyId
+                    newData.setPKeyId(SnowFlakeUtil.getId());
+                    //设置旧ID
+                    if (StringUtils.isNotEmpty(node.getOldId())) {
+                        newData.setOldId(node.getOldId());
+                    } else {
+                        newData.setOldId(node.getId().toString());
+                    }
+
+                    //设置新ID
+                    if (new Integer("1").equals(node.getType())) {
+                        //如果是节点类型才重塑ID
+                        newData.setId(oldToNewIdMap.containsKey(node.getId()) ? oldToNewIdMap.get(node.getId()) : SnowFlakeUtil.getId());
+                        //划分编号
+                        newData.setPartitionCode(StringUtils.isNotEmpty(vo.getPartitionCode()) ? vo.getPartitionCode() : null);
+                    }
+                    //设置父节点ID
+                    if (vo.getNeedCopyPrimaryKeyId().equals(node.getPKeyId().toString())) {
+                        //找到复制的节点,将parentId更改为 parent.getId()
+                        newData.setParentId(parent.getId());
+                        //设置新名称
+                        newData.setNodeName(vo.getNeedCopyNodeName());
+                        newData.setFullName(vo.getNeedCopyNodeName());
+                    } else {
+                        newData.setParentId(oldToNewIdMap.containsKey(node.getParentId()) ? oldToNewIdMap.get(node.getParentId()) : SnowFlakeUtil.getId());
+                    }
+                    newData.setCreateTime(new Date());
+                    newData.setUpdateTime(new Date());
+                    //初始化是否显示表格,默认显示
+                    newData.setIsBussShow(1);
+                    //初始化表格是否上传附件,默认未上传
+                    newData.setTabFileType(1);
+                    //初始化单表是否可以预览,默认不能
+                    newData.setIsTabPdf(1);
+                    //初始化PDF路径
+                    newData.setPdfUrl(null);
+                    newData.setCreateUser(AuthUtil.getUserId());
+                    //重塑父节点关联关系
+                    this.restoreParent(newData, oldToNewIdMap);
+                    //保存到集合中
+                    saveList.add(newData);
+                    if (new Integer("6").equals(node.getNodeType())) {
+                        //生成施工日志
+                        this.createLedger(newData, saveLedger, nodeMap, null);
+                    }
+
+                    // 组织复制值Sql
+                    if (nodeTabColsMap != null && node.getType() == 2) {
+                        String tableName = newData.getInitTableName();
+                        String col = nodeTabColsMap.get(tableName);
+                        String colVal = nodeTabColsMap.get(tableName);
+                        colVal = colVal.replaceAll("id,p_key_id,", "'" + SnowFlakeUtil.getId() + "' as id,'" + newData.getPKeyId() + "' as p_key_id,");
+                        copeSql.append("insert into " + tableName + "  (" + col + ") select " + colVal + " from " + tableName + " where p_key_id='" + node.getPKeyId() + "' ;");
+                    }
+                });
+            }
+            //保存节点信息
+            R<Boolean> booleanR = this.saveOrCopyNodeTree(saveList, saveLedger, 32, needCopyNode);
+
+            //复制数据逻辑
+            if (nodeTabColsMap != null && copeSql.length() >= 10) {
+                jdbcTemplate.execute(copeSql.toString());
+            }
+
+            //获取父节点信息
+            informationQueryService.AsyncWbsTree(needCopyNode.getParentId() + "", needCopyNode.getParentId() + "", needCopyNode.getContractId(), "", "1");
+            return booleanR;
+
+            /** TODO 多份复制
+             * @Author liuYC
+             * @Date 2023年4月10日18:06:53
+             * @Description
+             *  解析复制节点位置信息:
+             *  1:同节点复制(同一个父级下)
+             *      1.1 如果点击选择的是当前复制节点的父级,那么就新增一个当前需要复制的节点-新的子级-新的表-新的表数据(根据所属方查询对应数据)。
+             *      1.2 如果点击选择的是当前复制节点的同级节点(自己本身节点是无法点击进行复制的),那么复制对应表数据,如果没有对应表,那么跳过。
+             *  2:跨节点复制(不同父级下)
+             *      2.1 如果点击选择的是其他父级节点的父级,那么新增一个新的当前选择的复制的节点-新的表-新的表数据(根据所属方查询对应数据)。
+             *      2.2 如果点击选择的是当前复制节点本身的同等级节点,那么复制对应表数据,如果没有对应表,那么跳过。
+             */
+        } else if (("2").equals(vo.getCopyType())) {
+            //获取需要复制到的位置节点信息的集合
+            List<CopyContractTreeNodeVO.CopyBatch> copyBatches = vo.getCopyBatchToPaths();
+            if (copyBatches.size() > 0) {
+                //获取当前需要复制到的位置节点信息,判断同节点复制或跨节点复制
+                List<Long> toCopyNodePKeyIds = copyBatches.stream().map(CopyContractTreeNodeVO.CopyBatch::getPrimaryKeyId).map(Long::valueOf).collect(Collectors.toList());
+                List<WbsTreeContract> toCopyNodes = new ArrayList<>();
+                String contractId = "";
+                //选择的复制节点PKeyId可能一样(选择相同节点复制),所以循环分开查询
+                for (Long toCopyNodePKeyId : toCopyNodePKeyIds) {
+                    WbsTreeContract toCopyNode = wbsTreeContractClient.queryContractTreeNodeByPKeyId(toCopyNodePKeyId);
+                    toCopyNodes.add(toCopyNode);
+                    if (StringUtils.isEmpty(contractId)) {
+                        contractId = toCopyNode.getContractId();
+                    }
                 }
 
-                //设置新ID
-                if (new Integer("1").equals(node.getType())) {
-                    //如果是节点类型才重塑ID
-                    newData.setId(oldToNewIdMap.containsKey(node.getId()) ? oldToNewIdMap.get(node.getId()) : SnowFlakeUtil.getId());
-                    //划分编号
-                    newData.setPartitionCode(StringUtils.isNotEmpty(vo.getPartitionCode()) ? vo.getPartitionCode() : null);
+                //结果集
+                List<WbsTreeContract> addChildNodesAll = new ArrayList<>();
+                List<WbsTreeContract> addChildNodesTablesAll = new ArrayList<>();
+                Set<WbsTreeContract> addChildNodesTablesOldAll = new HashSet<>();
+                List<String> resultTablesData = new ArrayList<>();
+
+                //表单所属方
+                String tabOwner = "";
+                if (("1,2").equals(vo.getClassifyType()) || ("2,1").equals(vo.getClassifyType())) {
+                    tabOwner = "1,2,3,4,5,6";
+                } else if (("1").equals(vo.getClassifyType())) {
+                    tabOwner = "1,2,3";
+                } else if (("2").equals(vo.getClassifyType())) {
+                    tabOwner = "4,5,6";
                 }
-                //设置父节点ID
-                if (vo.getNeedCopyPrimaryKeyId().equals(node.getPKeyId().toString())) {
-                    //找到复制的节点,将parentId更改为 parent.getId()
-                    newData.setParentId(parent.getId());
-                    //设置新名称
-                    newData.setNodeName(vo.getNeedCopyNodeName());
-                    newData.setFullName(vo.getNeedCopyNodeName());
-                } else {
-                    newData.setParentId(oldToNewIdMap.containsKey(node.getParentId()) ? oldToNewIdMap.get(node.getParentId()) : SnowFlakeUtil.getId());
+
+                //解析位置信息,进行复制数据构造
+                if (toCopyNodes.size() == copyBatches.size()) {
+                    for (int i = 0; i < toCopyNodes.size(); i++) {
+                        //首先查询需要复制的节点的信息
+                        WbsTreeContract needCopyNode = this.wbsTreeContractClient.getContractNodeByPrimaryKeyId(vo.getNeedCopyPrimaryKeyId());
+                        WbsTreeContract toCopyNode = toCopyNodes.get(i);
+                        CopyContractTreeNodeVO.CopyBatch toCopyVO = copyBatches.get(i);
+
+                        if (toCopyNode != null && toCopyVO != null && needCopyNode != null) {
+                            //TODO 同节点复制
+                            if (new Integer(1).equals(toCopyVO.getIsSameNode())) {
+                                //1.1 选择当前节点的父级节点,新增
+                                if (needCopyNode.getParentId().equals(toCopyNode.getId())) {
+                                    toCopyNode.setNodeName(toCopyVO.getNodeName());
+                                    toCopyNode.setPartitionCode(toCopyVO.getPartitionCode());
+
+                                    //获取需要复制的所有子节点
+                                    List<WbsTreeContract> addChildNodes = this.getChildNodes(needCopyNode);
+
+                                    if (ObjectUtil.isEmpty(addChildNodes) || addChildNodes.size() == 0) {
+                                        //最下层级节点复制
+                                        addChildNodes = new ArrayList<>();
+                                        addChildNodes.add(needCopyNode);
+                                    }
+
+                                    //获取所有复制的表
+                                    List<WbsTreeContract> addChildNodesTables = this.getChildNodesTables(addChildNodes, toCopyNode.getContractId());
+
+                                    //复制数据源表,文件附件用
+                                    List<WbsTreeContract> oldTab = BeanUtil.copyProperties(addChildNodesTables, WbsTreeContract.class);
+                                    addChildNodesTablesOldAll.addAll(oldTab);
+
+                                    //构造新的节点、表、数据
+                                    this.addCopyNodesAndTabsBuildData(addChildNodes, addChildNodesTables, needCopyNode, toCopyNode, resultTablesData, 1, tabOwner, vo.getIsCopyData());
+
+                                    //返回结果集
+                                    addChildNodesAll.addAll(addChildNodes);
+                                    addChildNodesTablesAll.addAll(addChildNodesTables);
+
+                                    //1.2 选择同父级的同级节点,只复制数据
+                                } else if (needCopyNode.getParentId().equals(toCopyNode.getParentId())) {
+                                    //构造数据
+                                    this.addCopyTabData(needCopyNode, toCopyNode, tabOwner, resultTablesData, addChildNodesTablesOldAll, addChildNodesTablesAll, vo.getIsCopyData());
+                                }
+
+                                //TODO 跨节点复制
+                            } else if (new Integer(0).equals(toCopyVO.getIsSameNode())) {
+                                //获取需要复制节点的上级
+                                WbsTreeContract parentNodeNeed = wbsTreeContractClient.getContractWbsTreeByContractIdAndId(needCopyNode.getParentId(), Long.parseLong(needCopyNode.getContractId()));
+
+                                //2.1 选择的父级的同级的父级节点,新增(当复制节点父级与选择复制到的位置节点的父级id相同时,表示跨节点)
+                                if (parentNodeNeed != null && parentNodeNeed.getParentId().equals(toCopyNode.getParentId())) {
+                                    toCopyNode.setNodeName(toCopyVO.getNodeName());
+                                    toCopyNode.setPartitionCode(toCopyVO.getPartitionCode());
+
+                                    //获取需要复制的所有子节点
+                                    List<WbsTreeContract> addChildNodes = this.getChildNodes(needCopyNode);
+
+                                    //最下层级节点复制
+                                    if (ObjectUtil.isEmpty(addChildNodes) || addChildNodes.size() == 0) {
+                                        addChildNodes = new ArrayList<>();
+                                        addChildNodes.add(needCopyNode);
+                                    }
+
+                                    //获取所有复制的表
+                                    List<WbsTreeContract> addChildNodesTables = this.getChildNodesTables(addChildNodes, toCopyNode.getContractId());
+
+                                    //复制数据源表,文件附件用
+                                    List<WbsTreeContract> oldTab = BeanUtil.copyProperties(addChildNodesTables, WbsTreeContract.class);
+                                    addChildNodesTablesOldAll.addAll(oldTab);
+
+                                    //构造新的节点、表、数据
+                                    this.addCopyNodesAndTabsBuildData(addChildNodes, addChildNodesTables, needCopyNode, toCopyNode, resultTablesData, 0, tabOwner, vo.getIsCopyData());
+
+                                    //返回结果集
+                                    addChildNodesAll.addAll(addChildNodes);
+                                    addChildNodesTablesAll.addAll(addChildNodesTables);
+
+                                    //2.2 如果点击选择的是当前复制节点本身的同等级节点,那么就只复制数据。(如果是跨节点,类型相同的情况下,只复制数据)
+                                } else if (needCopyNode.getNodeType().equals(toCopyNode.getNodeType()) && !needCopyNode.getParentId().equals(toCopyNode.getParentId())) {
+                                    //构造数据
+                                    this.addCopyTabData(needCopyNode, toCopyNode, tabOwner, resultTablesData, addChildNodesTablesOldAll, addChildNodesTablesAll, vo.getIsCopyData());
+                                }
+                            }
+                        }
+                    }
                 }
-                newData.setCreateTime(new Date());
-                newData.setUpdateTime(new Date());
+
+                //节点
+                if (addChildNodesAll.size() > 0) {
+                    wbsTreeContractClient.saveBatch(addChildNodesAll);
+                    //更新redis缓存
+                    Map<Long, List<WbsTreeContract>> collect = addChildNodesAll.stream().filter(f -> new Integer(1).equals(f.getType()) && ObjectUtil.isNotEmpty(f.getParentId())).collect(Collectors.groupingBy(WbsTreeContract::getParentId));
+                    for (Map.Entry<Long, List<WbsTreeContract>> longListEntry : collect.entrySet()) {
+                        informationQueryService.AsyncWbsTree("", longListEntry.getKey().toString(), contractId, "", "1");
+                    }
+                }
+                //元素表
+                if (addChildNodesTablesAll.size() > 0) {
+                    wbsTreeContractClient.saveBatch(addChildNodesTablesAll);
+
+                    //表单文件附件
+                    if (addChildNodesTablesOldAll.size() > 0 && vo.getIsCopyData() == 1) {
+                        this.addCopyTabFile(addChildNodesTablesAll, addChildNodesTablesOldAll);
+                    }
+                }
+                //实体表数据
+                if (resultTablesData.size() > 0) {
+                    jdbcTemplate.execute(StringUtils.join(resultTablesData, ""));
+                }
+                return R.success("操作成功");
+            }
+        }
+        return R.fail("操作失败");
+    }
+
+    /**
+     * 新增复制的表单文件
+     */
+    @Async
+    public void addCopyTabFile(List<WbsTreeContract> addChildNodesTables, Set<WbsTreeContract> addChildNodesTablesOld) {
+        //获取所有数据源附件文件
+        List<Long> tabFileIds = addChildNodesTablesOld.stream().distinct().map(WbsTreeContract::getPKeyId).collect(Collectors.toList());
+        Map<String, List<TableFile>> tableFileOldMap = tableFileClient.getTabFilesByTabIds(StringUtils.join(tabFileIds, ",")).stream().collect(Collectors.groupingBy(TableFile::getTabId));
+        if (tableFileOldMap != null && tableFileOldMap.size() > 0) {
+            List<TableFile> resultFileData = new ArrayList<>();
+            for (WbsTreeContract tabOld : addChildNodesTablesOld) {
+                for (WbsTreeContract tabNew : addChildNodesTables) {
+                    //获取对应表
+                    if (tabOld.getNodeName().equals(tabNew.getNodeName()) && (ObjectUtil.isNotEmpty(tabOld.getHtmlUrl()) && ObjectUtil.isNotEmpty(tabNew.getHtmlUrl()) && tabOld.getHtmlUrl().equals(tabNew.getHtmlUrl()))) {
+                        //构建文件数据
+                        List<TableFile> tab = tableFileOldMap.get(tabOld.getPKeyId() + "");
+                        if (tab != null && tab.size() > 0) {
+                            tab.forEach(file -> {
+                                file.setTabId(tabNew.getPKeyId() + "");
+                                file.setId(SnowFlakeUtil.getId());
+                            });
+                            resultFileData.addAll(tab);
+                        }
+                    }
+                }
+            }
+            if (resultFileData.size() > 0) {
+                tableFileClient.saveBatch(resultFileData);
+            }
+        }
+    }
+
+    /**
+     * 新增复制的数据
+     */
+    private void addCopyTabData(WbsTreeContract needCopyNode, WbsTreeContract toCopyNode, String tabOwner, List<String> resultTablesData, Set<WbsTreeContract> addChildNodesTablesOldAll, List<WbsTreeContract> addChildNodesTablesAll, Integer isCopyData) {
+        List<WbsTreeContract> wbsTreeContractsNeed = Collections.singletonList(needCopyNode);
+        List<WbsTreeContract> wbsTreeContractsTo = Collections.singletonList(toCopyNode);
+        List<WbsTreeContract> needCopyNodeTabs = getChildNodesTables(wbsTreeContractsNeed, needCopyNode.getContractId());
+        List<WbsTreeContract> toCopyNodeTabs = getChildNodesTables(wbsTreeContractsTo, needCopyNode.getContractId());
+        if (needCopyNodeTabs.size() > 0) {
+            for (WbsTreeContract needTab : needCopyNodeTabs) {
+                for (WbsTreeContract toCopyNodeTab : toCopyNodeTabs) {
+                    //获取相同表单 nodeName 、HtmlUrl相同
+                    if (needTab.getNodeName().equals(toCopyNodeTab.getNodeName()) && (ObjectUtil.isNotEmpty(needTab.getHtmlUrl()) && ObjectUtil.isNotEmpty(toCopyNodeTab.getHtmlUrl()) && needTab.getHtmlUrl().equals(toCopyNodeTab.getHtmlUrl()))) {
+                        if (StringUtils.isEmpty(needTab.getInitTableName())) {
+                            //没有对应实体表,跳过
+                            continue;
+                        }
+                        Long oldPKeyId = needTab.getPKeyId();
+
+                        //表单所属方,只有勾选了对应的所属方权限才复制数据;勾选了复制数据才能复制,否则只是创建节点、表
+                        if (tabOwner.contains(needTab.getTableOwner()) && isCopyData == 1) {
+
+                            //源表obj对象,文件附件使用
+                            addChildNodesTablesOldAll.add(needTab);
+                            if (!needTab.getTabFileType().equals(toCopyNodeTab.getTabFileType())) {
+                                toCopyNodeTab.setTabFileType(needTab.getTabFileType()); //已上传
+                            }
+                            //目标表obj对象,文件附件使用
+                            addChildNodesTablesAll.add(toCopyNodeTab);
+
+                            //获取实体表列对象
+                            List<QueryProcessDataVO> nodeTabColOneTab = informationQueryService.getNodeChildTabColsAllByTabName(needTab.getInitTableName());
+                            //转化为map
+                            Map<String, String> nodeTabColsMap = nodeTabColOneTab.stream().collect(Collectors.toMap(QueryProcessDataVO::getQueryType, QueryProcessDataVO::getAncestors, (key1, key2) -> key2));
+                            //组织复制表的数据的sql
+                            if (nodeTabColsMap.size() > 0) {
+                                StringBuilder copyDataSql = new StringBuilder();
+                                String tableName = needTab.getInitTableName();
+                                String col = nodeTabColsMap.get(tableName);
+                                String colVal = nodeTabColsMap.get(tableName);
+                                colVal = colVal.replaceAll("id,p_key_id,", "'" + SnowFlakeUtil.getId() + "' as id,'" + toCopyNodeTab.getPKeyId() + "' as p_key_id,");
+                                //delete SQL (先删除旧数据,再新增)
+                                String delSql = "delete from " + tableName + " where p_key_id = " + toCopyNodeTab.getPKeyId() + " ; ";
+                                //insert into SQL
+                                copyDataSql.append(delSql).append("insert into ").append(tableName).append("  (").append(col).append(") select ").append(colVal).append(" from ").append(tableName).append(" where p_key_id='").append(oldPKeyId).append("' ;");
+                                resultTablesData.add(copyDataSql.toString());
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * 新增复制的节点、表的数据构造
+     */
+    private void addCopyNodesAndTabsBuildData(List<WbsTreeContract> needNodes, List<WbsTreeContract> needTabs, WbsTreeContract needCopyNode, WbsTreeContract toCopyNode, List<String> resultTablesData, Integer isSameNode, String tabOwner, Integer isCopyData) {
+        int var = 0;
+        if (needNodes.size() == 1) {
+            //判断是否为最下级节点
+            WbsTreeContract wbsTreeContract = needNodes.stream().filter(f -> f.getPKeyId().equals(needCopyNode.getPKeyId())).findAny().orElse(null);
+            if (wbsTreeContract != null) {
+                var = 1;
+            }
+        }
+
+        //最下层级节点复制
+        if (var == 1) {
+            //构造节点
+            Long id = SnowFlakeUtil.getId();
+            for (WbsTreeContract needNode : needNodes) {
+                if (isSameNode == 0) {
+                    //跨节点复制,更改父级id
+                    needNode.setParentId(toCopyNode.getId());
+                }
+                needNode.setOldId(needNode.getId() + "");
+                needNode.setPKeyId(SnowFlakeUtil.getId());
+                needNode.setId(id);
+                needNode.setNodeName(toCopyNode.getNodeName());
+                needNode.setFullName(toCopyNode.getNodeName());
+                needNode.setPartitionCode(toCopyNode.getPartitionCode());
+                break;
+            }
+            //构造当前节点下所有元素表
+            for (WbsTreeContract needTab : needTabs) {
+                if (StringUtils.isEmpty(needTab.getInitTableName())) {
+                    continue;
+                }
+                Long oldPKeyId = needTab.getPKeyId();
+
+                Long tabId = SnowFlakeUtil.getId();
+                needTab.setAncestors(needTab.getAncestors().replace(needTab.getParentId().toString(), id.toString()));
+                needTab.setId(tabId);
+                needTab.setParentId(id);
+                needTab.setPKeyId(SnowFlakeUtil.getId());
                 //初始化是否显示表格,默认显示
-                newData.setIsBussShow(1);
+                needTab.setIsBussShow(1);
                 //初始化表格是否上传附件,默认未上传
-                newData.setTabFileType(1);
+                needTab.setTabFileType(1);
                 //初始化单表是否可以预览,默认不能
-                newData.setIsTabPdf(1);
+                needTab.setIsTabPdf(1);
                 //初始化PDF路径
-                newData.setPdfUrl(null);
-                newData.setCreateUser(AuthUtil.getUserId());
-                //重塑父节点关联关系
-                this.restoreParent(newData, oldToNewIdMap);
-                //保存到集合中
-                saveList.add(newData);
-                if (new Integer("6").equals(node.getNodeType())) {
-                    //生成施工日志
-                    this.createLedger(newData, saveLedger, nodeMap, null);
+                needTab.setPdfUrl(null);
+
+                //表单所属方,只有勾选了对应的所属方权限才复制数据;勾选了复制数据才能复制,否则只是创建节点、表
+                if (tabOwner.contains(needTab.getTableOwner()) && isCopyData == 1) {
+                    //获取实体表列对象
+                    List<QueryProcessDataVO> nodeTabColOneTab = informationQueryService.getNodeChildTabColsAllByTabName(needTab.getInitTableName());
+                    //转化为map
+                    Map<String, String> nodeTabColsMap = nodeTabColOneTab.stream().collect(Collectors.toMap(QueryProcessDataVO::getQueryType, QueryProcessDataVO::getAncestors, (key1, key2) -> key2));
+                    //组织复制表的数据的sql
+                    if (nodeTabColsMap.size() > 0) {
+                        StringBuilder copyDataSql = new StringBuilder();
+                        String tableName = needTab.getInitTableName();
+                        String col = nodeTabColsMap.get(tableName);
+                        String colVal = nodeTabColsMap.get(tableName);
+                        colVal = colVal.replaceAll("id,p_key_id,", "'" + SnowFlakeUtil.getId() + "' as id,'" + needTab.getPKeyId() + "' as p_key_id,");
+                        copyDataSql.append("insert into ").append(tableName).append("  (").append(col).append(") select ").append(colVal).append(" from ").append(tableName).append(" where p_key_id='").append(oldPKeyId).append("' ;");
+                        resultTablesData.add(copyDataSql.toString());
+                    }
                 }
+            }
 
-                // 组织复制值Sql
-                if (nodeTabColsMap != null && node.getType() == 2) {
-                    String tableName = newData.getInitTableName();
-                    String col = nodeTabColsMap.get(tableName);
-                    String colVal = nodeTabColsMap.get(tableName);
-                    colVal = colVal.replaceAll("id,p_key_id,", "'" + SnowFlakeUtil.getId() + "' as id,'" + newData.getPKeyId() + "' as p_key_id,");
-                    copeSql.append("insert into " + tableName + "  (" + col + ") select " + colVal + " from " + tableName + " where p_key_id='" + node.getPKeyId() + "' ;");
+        } else { //多层级节点复制
+            //根节点id
+            Long toCopyNodeOldId = toCopyNode.getId();
+            toCopyNode.setId(SnowFlakeUtil.getId());
+
+            Map<Long, Long> parentIdToId = new HashMap<>();
+            Map<Long, List<WbsTreeContract>> tabMap = needTabs.stream().collect(Collectors.groupingBy(WbsTreeContract::getParentId));
+
+            for (WbsTreeContract node : needNodes) {
+                Long oldId = node.getId();
+                //构造节点
+                Long newParentId;
+                if (parentIdToId.size() > 0) {
+                    //去数据源节点获取父级id对应的新id,设置成重设后的新的父级id
+                    newParentId = parentIdToId.get(node.getParentId());
+                } else {
+                    //根节点
+                    newParentId = toCopyNode.getId();
                 }
-            });
+                if (ObjectUtils.isEmpty(newParentId)) {
+                    newParentId = toCopyNode.getId();
+                }
+                node.setPKeyId(SnowFlakeUtil.getId());
+                node.setOldId(node.getId().toString());
+                Long id = SnowFlakeUtil.getId();
+                //数据源节点的老id与新的id的Map,作为下一级的节点的父级id的替换
+                parentIdToId.put(node.getId(), id);
+                //重设祖级id
+                node.setAncestors(node.getAncestors().replace(node.getParentId().toString(), id.toString()));
+                //重设Id
+                node.setId(id);
+                node.setParentId(newParentId);
+
+                //构造当前节点下所有元素表
+                List<WbsTreeContract> tabs = tabMap.get(oldId);
+                //构造节点下的表
+                if (tabs != null && tabs.size() > 0) {
+                    for (WbsTreeContract needTab : tabs) {
+                        if (StringUtils.isEmpty(needTab.getInitTableName())) {
+                            continue;
+                        }
+                        Long oldPKeyId = needTab.getPKeyId();
+
+                        Long tabId = SnowFlakeUtil.getId();
+                        needTab.setAncestors(needTab.getAncestors().replace(needTab.getParentId().toString(), id.toString()));
+                        needTab.setId(tabId);
+                        needTab.setParentId(id);
+                        needTab.setPKeyId(SnowFlakeUtil.getId());
+                        //初始化是否显示表格,默认显示
+                        needTab.setIsBussShow(1);
+                        //初始化表格是否上传附件,默认未上传
+                        needTab.setTabFileType(1);
+                        //初始化单表是否可以预览,默认不能
+                        needTab.setIsTabPdf(1);
+                        //初始化PDF路径
+                        needTab.setPdfUrl(null);
+
+                        //表单所属方,只有勾选了对应的所属方权限才复制数据;勾选了复制数据才能复制,否则只是创建节点、表
+                        if (tabOwner.contains(needTab.getTableOwner()) && isCopyData == 1) {
+                            //获取实体表列对象
+                            List<QueryProcessDataVO> nodeTabColOneTab = informationQueryService.getNodeChildTabColsAllByTabName(needTab.getInitTableName());
+                            //转化为map
+                            Map<String, String> nodeTabColsMap = nodeTabColOneTab.stream().collect(Collectors.toMap(QueryProcessDataVO::getQueryType, QueryProcessDataVO::getAncestors, (key1, key2) -> key2));
+                            //组织复制表的数据的sql
+                            if (nodeTabColsMap.size() > 0) {
+                                StringBuilder copyDataSql = new StringBuilder();
+                                String tableName = needTab.getInitTableName();
+                                String col = nodeTabColsMap.get(tableName);
+                                String colVal = nodeTabColsMap.get(tableName);
+                                colVal = colVal.replaceAll("id,p_key_id,", "'" + SnowFlakeUtil.getId() + "' as id,'" + needTab.getPKeyId() + "' as p_key_id,");
+                                copyDataSql.append("insert into ").append(tableName).append("  (").append(col).append(") select ").append(colVal).append(" from ").append(tableName).append(" where p_key_id='").append(oldPKeyId).append("' ;");
+                                resultTablesData.add(copyDataSql.toString());
+                            }
+                        }
+                    }
+                }
+            }
+
+            //添加根节点
+            toCopyNode.setOldId(needCopyNode.getId() + "");
+            if (isSameNode == 1) {
+                //同节点
+                toCopyNode.setParentId(needCopyNode.getParentId());
+            } else {
+                //跨节点
+                toCopyNode.setParentId(toCopyNodeOldId);
+            }
+            toCopyNode.setPKeyId(SnowFlakeUtil.getId());
+            toCopyNode.setNodeName(toCopyNode.getNodeName());
+            toCopyNode.setFullName(toCopyNode.getNodeName());
+            toCopyNode.setPartitionCode(toCopyNode.getPartitionCode());
+            needNodes.add(toCopyNode);
         }
-        //保存节点信息
-        R<Boolean> booleanR = this.saveOrCopyNodeTree(saveList, saveLedger, 32, needCopyNode);
+    }
 
-        //复制数据逻辑
-        if (nodeTabColsMap != null && copeSql.length() >= 10) {
-            jdbcTemplate.execute(copeSql.toString());
+    /**
+     * 获取所有子级节点
+     */
+    private List<WbsTreeContract> getChildNodes(WbsTreeContract obj) {
+        if (obj != null) {
+            List<WbsTreeContract> wbsTreeContracts = Collections.singletonList(obj);
+            List<WbsTreeContract> result = new ArrayList<>();
+            this.recursionGetChildNodes(wbsTreeContracts, result, obj.getContractId());
+            if (result.size() > 0) {
+                return result;
+            }
         }
+        return null;
+    }
 
-        //获取父节点信息
-        informationQueryService.AsyncWbsTree(needCopyNode.getParentId() + "", needCopyNode.getParentId() + "", needCopyNode.getContractId(), "", "1");
-        return booleanR;
+    /**
+     * 递归获取所有子级节点
+     */
+    private void recursionGetChildNodes(List<WbsTreeContract> list, List<WbsTreeContract> result, String contractId) {
+        List<Long> ids = list.stream().map(WbsTreeContract::getId).collect(Collectors.toList());
+        if (ids.size() > 0) {
+            List<WbsTreeContract> query = jdbcTemplate.query("select * from m_wbs_tree_contract where type = 1 and parent_id in(" + StringUtils.join(ids, ",") + ") and status = 1 and is_deleted = 0 and contract_id = " + contractId, new BeanPropertyRowMapper<>(WbsTreeContract.class));
+            if (query.size() > 0) {
+                result.addAll(query);
+                recursionGetChildNodes(query, result, contractId);
+            }
+        }
+    }
+
+    /**
+     * 获取所有子级下的表
+     */
+    private List<WbsTreeContract> getChildNodesTables(List<WbsTreeContract> list, String contractId) {
+        if (list != null && list.size() > 0) {
+            List<Long> parentIds = list.stream().map(WbsTreeContract::getId).collect(Collectors.toList());
+            return jdbcTemplate.query("select * from m_wbs_tree_contract where type = 2 and is_deleted = 0 and status = 1 and parent_id in(" + StringUtils.join(parentIds, ",") + ") and contract_id = " + contractId, new BeanPropertyRowMapper<>(WbsTreeContract.class));
+        }
+        return null;
     }
 
 
@@ -1619,17 +2056,6 @@ public class InformationWriteQueryController extends BladeController {
                         newData.setPdfUrl(null);
 
                         //获取当前所有复制的节点的最大sort
-                        /*String sql = "select sort from m_wbs_tree_contract where contract_id = '" + node.getContractId() + "' and (id = '" + node.getId() + "' or old_id = '" + node.getId() + "')";
-                        List<WbsTreeContract> query = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(WbsTreeContract.class));
-                        List<Integer> collect = query.stream().filter(f -> ObjectUtils.isNotEmpty(f.getSort())).collect(Collectors.toList()).stream().map(WbsTreeContract::getSort).collect(Collectors.toList());
-                        Integer max = 1;
-                        if (collect.size() > 0) {
-                            max = collect.stream().reduce(collect.get(0), Integer::max);
-                        } else {
-                            max = 1;
-                        }
-                        //设置sort
-                        newData.setSort(max);*/
                         newData.setSort(ObjectUtils.isNotEmpty(node.getSort()) ? node.getSort() : 0);
 
                         //重塑父节点关联关系
@@ -1676,7 +2102,8 @@ public class InformationWriteQueryController extends BladeController {
     /**
      * 生成施工日志记录
      */
-    private void createLedger(WbsTreeContract newData, List<ConstructionLedger> saveLedger, Map<String, WbsTreeContract> contractNodeMap, Map<String, WbsTreePrivate> projectNodeMap) {
+    private void createLedger(WbsTreeContract
+                                      newData, List<ConstructionLedger> saveLedger, Map<String, WbsTreeContract> contractNodeMap, Map<String, WbsTreePrivate> projectNodeMap) {
         //工序,需要新增施工台账
         ConstructionLedger ledger = new ConstructionLedger();
         //获取这个节点的原始信息
@@ -1730,7 +2157,8 @@ public class InformationWriteQueryController extends BladeController {
      * @param parentList 父节点集合
      * @param childList  保存集合
      */
-    private void foreachQueryChildContract(List<WbsTreeContract> parentList, List<WbsTreeContract> childList, Map<String, List<WbsTreeContract>> contractAllNodeMap) {
+    private void foreachQueryChildContract
+    (List<WbsTreeContract> parentList, List<WbsTreeContract> childList, Map<String, List<WbsTreeContract>> contractAllNodeMap) {
         parentList.forEach(parent -> {
             List<WbsTreeContract> childs;
             if (contractAllNodeMap.containsKey(parent.getId().toString())) {
@@ -1771,7 +2199,8 @@ public class InformationWriteQueryController extends BladeController {
             @ApiImplicitParam(name = "wbsType", value = "模板类型, 1质检,2试验", required = true),
             @ApiImplicitParam(name = "contractId", value = "合同段ID", required = true)
     })
-    public R<List<WbsTreeContractTreeVOS>> queryMappingStructureTree(@RequestParam String parentId, @RequestParam String contractId, @RequestParam String contractIdRelation) {
+    public R<List<WbsTreeContractTreeVOS>> queryMappingStructureTree(@RequestParam String
+                                                                             parentId, @RequestParam String contractId, @RequestParam String contractIdRelation) {
         List<WbsTreeContractTreeVOS> result = this.informationQueryService.queryContractTree(parentId, contractId, contractIdRelation, null);
         if (result.size() == 1) {
             //只有一个子节点,继续向下
@@ -1823,7 +2252,8 @@ public class InformationWriteQueryController extends BladeController {
             @ApiImplicitParam(name = "nodeName", value = "节点的title", required = true),
             @ApiImplicitParam(name = "partitionCode", value = "划分编号")
     })
-    public R<Boolean> updateContractNodeParameter(@RequestParam Long pKeyId, @RequestParam String nodeName, @RequestParam String partitionCode) {
+    public R<Boolean> updateContractNodeParameter(@RequestParam Long pKeyId, @RequestParam String
+            nodeName, @RequestParam String partitionCode) {
         WbsTreeContract node = new WbsTreeContract();
         node.setPKeyId(pKeyId);
         node.setNodeName(nodeName);
@@ -2133,7 +2563,8 @@ public class InformationWriteQueryController extends BladeController {
         return booleanR;
     }
 
-    private List<WbsTreePrivate> unifiedCode(List<AddContractTreeNodeVO.Node> allSelectedNodeList, WbsTreeContract treeContract) {
+    private List<WbsTreePrivate> unifiedCode
+            (List<AddContractTreeNodeVO.Node> allSelectedNodeList, WbsTreeContract treeContract) {
         //获取主键
         List<String> halfSelectedList = allSelectedNodeList.stream().map(AddContractTreeNodeVO.Node::getPrimaryKeyId).distinct().collect(Collectors.toList());
         //查询数据
@@ -2145,7 +2576,9 @@ public class InformationWriteQueryController extends BladeController {
     }
 
     @NotNull
-    private R<Boolean> saveOrCopyNodeTree(List<WbsTreeContract> saveList, List<ConstructionLedger> saveLedger, Integer operationType, WbsTreeContract currentNode) {
+    private R<Boolean> saveOrCopyNodeTree
+            (List<WbsTreeContract> saveList, List<ConstructionLedger> saveLedger, Integer
+                    operationType, WbsTreeContract currentNode) {
 
         if (saveList.size() > 0) {
             StringBuilder str = new StringBuilder();
@@ -2199,7 +2632,8 @@ public class InformationWriteQueryController extends BladeController {
     /**
      * 处理半选集合
      */
-    private void disposeHalfSelectList(@RequestBody WbsTreeContract treeContract, List<AddContractTreeNodeVO.Node> allSelectedNodeList, List<WbsTreePrivate> selectedNodeList) {
+    private void disposeHalfSelectList(@RequestBody WbsTreeContract
+                                               treeContract, List<AddContractTreeNodeVO.Node> allSelectedNodeList, List<WbsTreePrivate> selectedNodeList) {
         if (allSelectedNodeList != null && allSelectedNodeList.size() > 0) {
             //获取主键
             List<String> allSelectedList = allSelectedNodeList.stream().map(AddContractTreeNodeVO.Node::getPrimaryKeyId).distinct().collect(Collectors.toList());
@@ -2245,7 +2679,8 @@ public class InformationWriteQueryController extends BladeController {
             @ApiImplicitParam(name = "projectId", value = "项目ID"),
             @ApiImplicitParam(name = "id", value = "点击节点ID")
     })
-    public R<List<WbsTreeContractTreeVOS>> queryWbsTreePrivateByProjectIdAndId(@RequestParam String projectId, @RequestParam String id) {
+    public R<List<WbsTreeContractTreeVOS>> queryWbsTreePrivateByProjectIdAndId(@RequestParam String
+                                                                                       projectId, @RequestParam String id) {
         List<WbsTreeContractTreeVOS> result = new ArrayList<>();
 
         if (StringUtils.isNotEmpty(id)) {
@@ -2268,6 +2703,44 @@ public class InformationWriteQueryController extends BladeController {
         return R.data(result);
     }
 
+    /**
+     * 懒加载项目级工程划分树
+     *
+     * @param contractId 合同段ID
+     * @param id         节点ID
+     * @return 结果集
+     */
+    @PostMapping("/queryWbsTreeContractByContractIdAndId")
+    @ApiOperationSupport(order = 9)
+    @ApiOperation(value = "懒加载合同段工程划分树")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "contractId", value = "合同段ID"),
+            @ApiImplicitParam(name = "id", value = "点击节点ID")
+    })
+    public R<List<WbsTreeContractTreeVOS>> queryWbsTreeContractByContractIdAndId(@RequestParam String contractId, @RequestParam String id) {
+        List<WbsTreeContractTreeVOS> result = new ArrayList<>();
+        if (StringUtils.isNotEmpty(id)) {
+            WbsTreeContractTreeVOS vos = new WbsTreeContractTreeVOS();
+            WbsTreeContract wbsTreeContract = this.wbsTreeContractClient.queryWbsTreeContractById(contractId, Long.parseLong(id));
+            if (wbsTreeContract != null) {
+                //设置参数
+                vos.setId(wbsTreeContract.getId());
+                vos.setKey(wbsTreeContract.getId().toString());
+                vos.setPrimaryKeyId(wbsTreeContract.getPKeyId().toString());
+                vos.setParentId(wbsTreeContract.getParentId());
+                vos.setTitle(wbsTreeContract.getNodeName());
+                vos.setType(wbsTreeContract.getType());
+                vos.setWbsType(wbsTreeContract.getWbsType());
+                //设置子级
+                vos.setChildren(this.wbsTreeContractClient.queryWbsTreeContractTreeLazy(contractId, Long.parseLong(id)));
+                //添加进结果集合中
+                result.add(vos);
+            }
+        }
+
+        return R.data(result);
+    }
+
     /**
      * 获取与当前节点平级的项目级节点
      *
@@ -2419,7 +2892,9 @@ public class InformationWriteQueryController extends BladeController {
             @ApiImplicitParam(name = "parentId", value = "父节点,为空则查询第一级节点"),
             @ApiImplicitParam(name = "contractId", value = "合同段ID", required = true)
     })
-    public R<List<WbsTreeContractTreeVOS>> queryStandingBookContractWbsTree(@RequestParam String primaryKeyId, @RequestParam String parentId, @RequestParam String contractId, @RequestParam String contractIdRelation) {
+    public R<List<WbsTreeContractTreeVOS>> queryStandingBookContractWbsTree(@RequestParam String
+                                                                                    primaryKeyId, @RequestParam String parentId, @RequestParam String contractId, @RequestParam String
+                                                                                    contractIdRelation) {
         if (StringUtils.isNotEmpty(primaryKeyId)) {
             parentId = primaryKeyId;
         }
@@ -2510,7 +2985,8 @@ public class InformationWriteQueryController extends BladeController {
             @ApiImplicitParam(name = "parentId", value = "父节点,为空则查询第一级节点"),
             @ApiImplicitParam(name = "contractId", value = "合同段ID", required = true)
     })
-    public R<List<WbsTreeContractTreeVOS>> queryContractWbsTreeByFirstInfo(@RequestParam String parentId, @RequestParam String contractId, @RequestParam String contractIdRelation) {
+    public R<List<WbsTreeContractTreeVOS>> queryContractWbsTreeByFirstInfo(@RequestParam String
+                                                                                   parentId, @RequestParam String contractId, @RequestParam String contractIdRelation) {
         List<WbsTreeContractTreeVOS> rootTreeNode = informationQueryService.queryContractTree(parentId, contractId, contractIdRelation, null);
         //查询被标记为首件的数据
         rootTreeNode = rootTreeNode.stream().filter(WbsTreeContractTreeVOS::getIsFirst).collect(Collectors.toList());

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

@@ -313,7 +313,6 @@ public class TaskController extends BladeController {
                             String projectId = projectAndContractId.split(",")[0];
                             String contractId = projectAndContractId.split(",")[1];
                             Map<String, String> stringMap = iTaskService.getTaskCount(projectId, contractId, userId);
-
                             webSocket.sendMessageByUserId(AuthUtil.getUserId().toString(), JSON.toJSONString(stringMap));
                         }
                     }

+ 81 - 2
blade-service/blade-business/src/main/java/org/springblade/business/feignClient/ArchiveFileClientImpl.java

@@ -6,15 +6,19 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import lombok.AllArgsConstructor;
+import org.apache.commons.lang.StringUtils;
 import org.springblade.business.entity.ArchiveFile;
 import org.springblade.business.feign.ArchiveFileClient;
 import org.springblade.business.mapper.ArchiveFileMapper;
 import org.springblade.business.service.IArchiveFileService;
 import org.springblade.business.vo.ArchiveFileVO;
+import org.springblade.common.utils.FileUtils;
+import org.springblade.common.vo.FileSize;
+import org.springblade.manager.entity.ContractInfo;
+import org.springblade.manager.feign.ContractClient;
 import org.springframework.web.bind.annotation.RestController;
 
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 
 
 @RestController
@@ -25,6 +29,9 @@ public class ArchiveFileClientImpl implements ArchiveFileClient {
 
     private final ArchiveFileMapper fileMapper;
 
+    private ContractClient contractClient;
+
+
 
     @Override
     public void saveArchiveFile(ArchiveFileVO vo) {
@@ -102,4 +109,76 @@ public class ArchiveFileClientImpl implements ArchiveFileClient {
     public List<ArchiveFile> getListByProjectId(Long projectId) {
         return fileMapper.getListByProjectId(projectId);
     }
+
+    @Override
+    public List<Map<String,Object>> getAllArchiveFileByContractType(Long projectId) {
+        List<ArchiveFileVO> list = fileMapper.getAllArchiveFileByContractType(projectId);
+        List<ContractInfo> infos = contractClient.queryContractListByIds(Arrays.asList(projectId));
+        int key1=0,key2=0,key3=0;
+        //判断案卷属于1施工,2监理,还是3业主
+        for (ArchiveFileVO l : list) {
+            String type = l.getContractType();
+            if (StringUtils.isBlank(type)){
+                //业主
+                key3++;
+            }else if ("S".equals(type)){
+                //监理
+                key2++;
+            }else if ("C".equals(type)){
+                //施工
+                key1++;
+            }else if (type.length() > 10){
+                for (ContractInfo info : infos) {
+                    if (type.equals(info.getId()+"")){
+                        Integer t = info.getContractType();
+                        if (t == 1){
+                            key1++;
+                        }else if(t==2){
+                            key2++;
+                        }else {
+                            key3++;
+                        }
+                        break;
+                    }
+                }
+            }else {
+                System.out.println(type);
+            }
+        }
+        List<Map<String,Object>> mapList = new ArrayList<>();
+        Map<String,Object> map = new HashMap<>();
+        map.put("title","施工");
+        map.put("key1",0);
+        map.put("key2",key1);
+        Map<String,Object> map2 = new HashMap<>();
+        map2.put("title","监理");
+        map2.put("key1",0);
+        map2.put("key2",key2);
+        Map<String,Object> map3 = new HashMap<>();
+        map3.put("title","业主");
+        map3.put("key1",0);
+        map3.put("key2",key3);
+        mapList.add(map);
+        mapList.add(map2);
+        mapList.add(map3);
+        return mapList;
+    }
+
+    @Override
+    public String getAllArchiveFileSize(Long projectId) {
+        //获取所有文件的url
+        List<ArchiveFile> archiveFileList = fileMapper.getAllArchiveFileUrl(projectId);
+        List<String> list = new ArrayList<>();
+        for (ArchiveFile file : archiveFileList) {
+            if (StringUtils.isNotBlank(file.getFileUrl())){
+                list.add(file.getFileUrl());
+            }
+            if (StringUtils.isNotBlank(file.getPdfFileUrl())){
+                list.add(file.getPdfFileUrl());
+            }
+        }
+        //从阿里云返回文件大小
+        String sizeCount = FileUtils.getOssFileSizeCount(list);
+        return sizeCount;
+    }
 }

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

@@ -68,4 +68,8 @@ public interface ArchiveFileMapper extends BaseMapper<ArchiveFile> {
 	List<ArchiveFile> getArchiveFileByFileIds(@Param("ids") List<Long> ids);
 
 	public List<ArchiveFile> getListByProjectId(@Param("projectId") Long projectId);
+
+	List<ArchiveFileVO> getAllArchiveFileByContractType(@Param("projectId")Long projectId);
+
+	List<ArchiveFile> getAllArchiveFileUrl(@Param("projectId")Long projectId);
 }

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

@@ -51,6 +51,9 @@
         <result column="box_number" property="boxNumber"/>
         <result column="is_auto_file" property="isAutoFile"/>
         <result column="is_archive" property="isArchive"/>
+        <result column="page_num" property="pageNum"/>
+        <result column="file_size" property="fileSize"/>
+        <result column="source_type" property="sourceType"/>
     </resultMap>
     <update id="recoveryByIds">
         update u_archive_file set is_deleted = 0 where
@@ -273,4 +276,15 @@
         from u_archive_file
         where project_id=#{projectId};
     </select>
+    <select id="getAllArchiveFileByContractType" resultType="org.springblade.business.vo.ArchiveFileVO">
+        SELECT uaf.*,matc.tree_code as 'contractType'
+        FROM u_archive_file uaf inner join m_archive_tree_contract matc on uaf.node_id =matc.id
+        WHERE  uaf.project_id = #{projectId};
+    </select>
+    <select id="getAllArchiveFileUrl" resultType="org.springblade.business.entity.ArchiveFile">
+        SELECT uaf.file_url ,uaf.pdf_file_url
+        FROM u_archive_file uaf
+        WHERE  uaf.project_id = #{projectId};
+    </select>
+
 </mapper>

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

@@ -111,4 +111,8 @@ public interface InformationQueryMapper extends BaseMapper<InformationQuery> {
 
 	// 获取当前节点下,所有表单的字段数据
 	List<QueryProcessDataVO> getNodeChildTabColsAllByNodeId(String nodeId, String contractId);
+
+	// 获取当前节点下,所有表单的字段数据,根据表名
+	List<QueryProcessDataVO> getNodeChildTabColsAllByTabName(String tabName);
+
 }

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 491 - 405
blade-service/blade-business/src/main/java/org/springblade/business/mapper/InformationQueryMapper.xml


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

@@ -14,6 +14,7 @@
         <result column="is_deleted" property="isDeleted"/>
         <result column="task_parallel_id" property="taskParallelId"/>
         <result column="json_data" property="jsonData"/>
+        <result column="nick_name" property="nickName"/>
     </resultMap>
 
     <delete id="deletedById">

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

@@ -126,6 +126,9 @@ public interface IInformationQueryService extends BaseService<InformationQuery>
     // 获取当前节点所有的表的字段信息
     List<QueryProcessDataVO> getNodeChildTabColsAllByNodeId(String nodeId, String contractId);
 
+    // 获取当前节点下,所有表单的字段数据,根据表名
+    List<QueryProcessDataVO> getNodeChildTabColsAllByTabName(String tabName);
+
     // 测试节点信息
     List<WbsTreeContractTreeVOS> queryContractTree(String parentId, String contractId, String contractIdRelation, String classifyType);
 

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

@@ -19,6 +19,8 @@ package org.springblade.business.service;
 import org.springblade.business.entity.TaskBatch;
 import org.springblade.core.mp.base.BaseService;
 
+import java.util.List;
+
 /**
  *  服务类
  *

+ 13 - 5
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/ImageClassificationFileServiceImpl.java

@@ -31,6 +31,7 @@ import org.springblade.business.vo.TreeVo;
 import org.springblade.common.utils.CommonUtil;
 import org.springblade.core.mp.base.BaseServiceImpl;
 import org.springblade.manager.entity.WbsParam;
+import org.springblade.manager.entity.WbsTree;
 import org.springblade.manager.entity.WbsTreeContract;
 import org.springblade.manager.feign.WbsTreeContractClient;
 import org.springframework.jdbc.core.BeanPropertyRowMapper;
@@ -158,8 +159,6 @@ public class ImageClassificationFileServiceImpl extends BaseServiceImpl<ImageCla
                 }
 
                 List<String> ancestors = Arrays.asList(wbsTreeContract.getAncestors().split(","));
-                /*ancestors = new ArrayList<>(ancestors); // 将固定大小的列表复制到新的可变列表中
-                ancestors.removeIf(("0")::equals); //删除根节点*/
 
                 List<String> ids = new ArrayList<>();
                 for (String index : nodeNumber) {
@@ -175,9 +174,18 @@ public class ImageClassificationFileServiceImpl extends BaseServiceImpl<ImageCla
                 }
 
                 List<WbsTreeContract> wbsTreeContractList = jdbcTemplate.query("select node_name from m_wbs_tree_contract where is_deleted = 0 and status = 1 and project_id = " + wbsTreeContract.getProjectId() + " and contract_id = " + wbsTreeContract.getContractId() + " and wbs_id = " + wbsTreeContract.getWbsId() + " and id in(" + StringUtils.join(ids, ",") + ")", new BeanPropertyRowMapper<>(WbsTreeContract.class));
-                List<String> nameList = wbsTreeContractList.stream().map(WbsTreeContract::getNodeName).collect(Collectors.toList());
-                if (nameList.size() > 0) {
-                    return StringUtils.join(nameList, "");
+                if (wbsTreeContractList.size() > 0) {
+                    List<String> nameList = wbsTreeContractList.stream().map(WbsTreeContract::getNodeName).collect(Collectors.toList());
+                    if (nameList.size() > 0) {
+                        return StringUtils.join(nameList, "");
+                    }
+                } else {
+                    //如果私有是空的,就去公有WBS找
+                    List<WbsTree> wbsTreeList = jdbcTemplate.query("select node_name from m_wbs_tree where is_deleted = 0 and status = 1 and id in(" + StringUtils.join(ids, ",") + ")", new BeanPropertyRowMapper<>(WbsTree.class));
+                    List<String> nameList = wbsTreeList.stream().map(WbsTree::getNodeName).collect(Collectors.toList());
+                    if (nameList.size() > 0) {
+                        return StringUtils.join(nameList, "");
+                    }
                 }
             }
         }

+ 5 - 2
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/InformationQueryServiceImpl.java

@@ -105,7 +105,7 @@ public class InformationQueryServiceImpl extends BaseServiceImpl<InformationQuer
             }
             if (tableList != null && tableList.size() > 0) {
                 //删除掉无法溯源的数据
-                tableList.removeIf(node -> node.getIsTypePrivatePid() == null || node.getIsTypePrivatePid() <= 0 || StringUtils.isEmpty(node.getIsTypePrivatePid().toString()));
+                tableList.removeIf(node -> node.getIsTypePrivatePid() == null || node.getIsTypePrivatePid() <= 0 || StringUtils.isEmpty(node.getIsTypePrivatePid().toString()) || node.getHtmlUrl()==null );
                 List<Long> privatePIdList = tableList.stream().map(WbsTreeContract::getIsTypePrivatePid).distinct().collect(Collectors.toList());
                 return JSONArray.parseArray(JSONObject.toJSONString(privatePIdList), String.class);
 
@@ -118,7 +118,6 @@ public class InformationQueryServiceImpl extends BaseServiceImpl<InformationQuer
                     return Func.toStrList(obj.getTableIds());
                 }
             }
-
         } else {
             //那么就可能是日志,检查是不是日志
             ContractLog log = this.contractLogService.getById(formDataId);
@@ -717,6 +716,10 @@ public class InformationQueryServiceImpl extends BaseServiceImpl<InformationQuer
         return baseMapper.getNodeChildTabColsAllByNodeId(nodeId, contractId);
     }
 
+    @Override
+    public List<QueryProcessDataVO> getNodeChildTabColsAllByTabName(String tabName) {
+        return baseMapper.getNodeChildTabColsAllByTabName(tabName);
+    }
 
     @Override
     public void AsyncWbsTree(String primaryKeyId, String parentId, String contractId, String contractIdRelation, String classifyType) {

+ 75 - 9
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TaskServiceImpl.java

@@ -1,5 +1,6 @@
 package org.springblade.business.service.impl;
 
+import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
@@ -38,10 +39,15 @@ import org.springblade.manager.entity.ContractInfo;
 import org.springblade.manager.entity.ProjectInfo;
 import org.springblade.manager.feign.ContractClient;
 import org.springblade.manager.feign.ProjectClient;
+import org.springblade.system.user.cache.UserCache;
+import org.springblade.system.user.entity.User;
 import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.StringRedisTemplate;
 import org.springframework.jdbc.core.BeanPropertyRowMapper;
 import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.scheduling.annotation.Async;
+import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -96,6 +102,9 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
 
     private final JdbcTemplate jdbcTemplate;
 
+    @Autowired
+    StringRedisTemplate RedisTemplate;
+
     private final ITrialSelfInspectionRecordService iTrialSelfInspectionRecordService;
 
     // 线程池
@@ -425,19 +434,71 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
                     .in(TaskParallel::getParallelProcessInstanceId, taskIds));
             //保存批次
         TaskBatch taskBatch = new TaskBatch(null, JSONObject.toJSONString(taskApprovalVOS));
-            taskBatch.setCreateUser(AuthUtil.getUserId());
+            taskBatch.setCreateUser(userId);
+            taskBatch.setNickName(nickName);
             taskBatch.setCreateTime(new Date());
 
             this.taskBatchService.save(taskBatch);
             String taskBatchId = taskBatch.getId().toString();
+
+            // 电签
+            Boolean istrue = true;
+            for (TaskApprovalVO taskApprovalVO : taskApprovalVOS) {
+                Boolean aBoolean = RedisTemplate.hasKey("sign-" + taskApprovalVO.getFormDataId());
+                if(aBoolean){
+                    istrue =false;
+                    break;
+                }
+            }
+
             // 添加到 线程中
-            CompletableFuture<Void> runAsync = CompletableFuture.runAsync(() -> {
-                try {
-                    this.checkIsExsitTaskBatch(taskApprovalVOS, taskBatchId,userId,nickName);
-                } catch (FileNotFoundException e) {
-                    e.printStackTrace();
+            if(istrue){
+                CompletableFuture<Void> runAsync = CompletableFuture.runAsync(() -> {
+                    try {
+                        this.checkIsExsitTaskBatch(taskApprovalVOS, taskBatchId,userId,nickName);
+                    } catch (FileNotFoundException e) {
+                        e.printStackTrace();
+                    }
+                }, executor);  
+            }
+    }
+
+
+    @Scheduled(cron = "0 */3 * * * ?")
+    public  void  SignInfo() {
+        //执行代码
+        logger.debug("扫描开始");
+        List<TaskBatch> maps = taskBatchService.getBaseMapper().selectList(Wrappers.<TaskBatch>lambdaQuery().eq(TaskBatch::getIsDeleted, 0));
+        if(maps!=null && maps.size()>=1){
+            for (TaskBatch dataInfo:maps){
+                String jsonData = dataInfo.getJsonData();
+                List<TaskApprovalVO> list=JSONArray.parseArray(jsonData,TaskApprovalVO.class);
+                String taskBatchId = dataInfo.getId().toString();
+                Long userId = dataInfo.getCreateUser();
+                String nickName = dataInfo.getNickName();
+
+                Boolean istrue = true;
+                for (TaskApprovalVO taskApprovalVO : list) {
+                    Boolean aBoolean = RedisTemplate.hasKey("sign-" + taskApprovalVO.getFormDataId());
+                    if(aBoolean){
+                        istrue =false;
+                        break;
+                    }
+                }
+
+                // 添加到 线程中
+                if(istrue){
+                    CompletableFuture<Void> runAsync = CompletableFuture.runAsync(() -> {
+                        try {
+                            this.checkIsExsitTaskBatch(list, taskBatchId,userId,nickName);
+                        } catch (FileNotFoundException e) {
+                            e.printStackTrace();
+                        }
+                    }, executor);
+                    runAsync.join();
                 }
-            }, executor);
+            }
+        }
     }
 
     private void checkIsExsitTaskBatch(List<TaskApprovalVO> taskApprovalVOS, String batchId,Long userId,String nickName) throws FileNotFoundException {
@@ -448,8 +509,9 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
             for (TaskApprovalVO taskApprovalVO : taskApprovalVOS) {
                 taskApprovalVO.setUserId(userId);
                 taskApprovalVO.setNickName(nickName);
-                String pdfUrlEVisa = this.completeApprovalTask(taskApprovalVO);
+                RedisTemplate.opsForValue().set("sign-"+taskApprovalVO.getFormDataId(),"1",300, TimeUnit.SECONDS);
 
+                String pdfUrlEVisa = this.completeApprovalTask(taskApprovalVO);
                 //TODO ============== 电签成功,修改试验状态,关联工程部位信息pdf(只有电签成功,才修改) liuYc 2023-03-16 ==============
                 if ("OK".equals(taskApprovalVO.getFlag()) && StringUtils.isNotEmpty(pdfUrlEVisa)) {
                     //已审批
@@ -460,8 +522,12 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
                     this.iTrialSelfInspectionRecordService.updateTrialSelfInspectionRecordStatusFC(taskApprovalVO);
                 }
             }
-            //删除掉对应批次
+
+            //executor删除掉对应批次
             this.taskBatchService.deletedById(batchId);
+            for (TaskApprovalVO taskApprovalVO : taskApprovalVOS) {
+                RedisTemplate.delete("sign-"+taskApprovalVO.getFormDataId());
+            }
             isContinue = false;
         }
     }

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

@@ -872,7 +872,7 @@ public class TrialSelfInspectionRecordServiceImpl extends BaseServiceImpl<TrialS
         return dto.getId().toString();
     }
 
-    private void initBuildNumber(TrialSelfInspectionRecordDTO dto) {
+    public void initBuildNumber(TrialSelfInspectionRecordDTO dto) {
         if (ObjectUtil.isEmpty(dto.getId()) && StringUtils.isNotEmpty(dto.getTableType())) {
             //构建记录表编号、报告单编号
             this.buildNumber(dto);
@@ -880,7 +880,7 @@ public class TrialSelfInspectionRecordServiceImpl extends BaseServiceImpl<TrialS
         }
     }
 
-    private void initTrialTabIds(TrialSelfInspectionRecordDTO dto) {
+    public void initTrialTabIds(TrialSelfInspectionRecordDTO dto) {
         JSONArray dataArray = dto.getDataInfo().getJSONArray("orderList");
         List<String> tableIds = new ArrayList<>();
         for (int i = 0; i < dataArray.size(); i++) {
@@ -892,11 +892,11 @@ public class TrialSelfInspectionRecordServiceImpl extends BaseServiceImpl<TrialS
         dto.setTableIds(join);
     }
 
-    private void reBuildNumber(TrialSelfInspectionRecord obj, TrialSelfInspectionRecordDTO dto) {
-        if (StringUtils.isEmpty(obj.getRecordNo()) && dto.getTableType().contains("1")) {
+    public void reBuildNumber(TrialSelfInspectionRecord obj, TrialSelfInspectionRecordDTO dto) {
+        if (StringUtils.isEmpty(obj.getRecordNo()) && (dto.getTableType().contains("1") || dto.getTableType().contains("9"))) {
             this.buildNumber(dto);
             this.saveOrUpdate(dto);
-        } else if (StringUtils.isEmpty(obj.getReportNo()) && dto.getTableType().contains("2")) {
+        } else if (StringUtils.isEmpty(obj.getReportNo()) && (dto.getTableType().contains("2") || dto.getTableType().contains("10"))) {
             this.buildNumber(dto);
             this.saveOrUpdate(dto);
         }
@@ -1028,11 +1028,11 @@ public class TrialSelfInspectionRecordServiceImpl extends BaseServiceImpl<TrialS
         List<TrialSelfInspectionRecord> trialSelfInspectionRecords = result.stream().filter(Objects::nonNull).collect(Collectors.toList());
 
         //两种类型同时生成
-        if (dto.getTableType().contains("1,2") || dto.getTableType().contains("2,1")) {
+        if (dto.getTableType().contains("1,2") || dto.getTableType().contains("2,1") || dto.getTableType().contains("9,10") || dto.getTableType().contains("10,9")) {
             String maxRecordNo = "";
             if (StringUtils.isEmpty(dto.getRecordNo())) {
                 //获取记录表最大编号
-                List<String> recordNos = trialSelfInspectionRecords.stream().filter(f -> ObjectUtils.isNotEmpty(f.getRecordNo())).map(TrialSelfInspectionRecord::getRecordNo).collect(Collectors.toList());
+                List<String> recordNos = trialSelfInspectionRecords.stream().map(TrialSelfInspectionRecord::getRecordNo).filter(ObjectUtils::isNotEmpty).collect(Collectors.toList());
                 if (recordNos.size() == 0 || ObjectUtil.isEmpty(recordNos)) {
                     maxRecordNo = "0001";
                 } else {
@@ -1053,7 +1053,7 @@ public class TrialSelfInspectionRecordServiceImpl extends BaseServiceImpl<TrialS
             String maxReportNo = "";
             if (StringUtils.isEmpty(dto.getReportNo())) {
                 //获取报告单最大编号
-                List<String> reportNos = trialSelfInspectionRecords.stream().filter(f -> ObjectUtils.isNotEmpty(f.getReportNo())).map(TrialSelfInspectionRecord::getReportNo).collect(Collectors.toList());
+                List<String> reportNos = trialSelfInspectionRecords.stream().map(TrialSelfInspectionRecord::getReportNo).filter(ObjectUtils::isNotEmpty).collect(Collectors.toList());
                 if (reportNos.size() == 0 || ObjectUtil.isEmpty(reportNos)) {
                     maxReportNo = "0001";
                 } else {
@@ -1101,10 +1101,10 @@ public class TrialSelfInspectionRecordServiceImpl extends BaseServiceImpl<TrialS
         }
 
         //记录表
-        if (("1").equals(dto.getTableType())) {
+        if (("1").equals(dto.getTableType()) || ("9").equals(dto.getTableType())) {
             if (StringUtils.isEmpty(dto.getRecordNo())) {
                 //获取记录表最大编号
-                List<String> recordNos = trialSelfInspectionRecords.stream().filter(f -> ObjectUtils.isNotEmpty(f.getRecordNo())).map(TrialSelfInspectionRecord::getRecordNo).collect(Collectors.toList());
+                List<String> recordNos = trialSelfInspectionRecords.stream().map(TrialSelfInspectionRecord::getRecordNo).filter(ObjectUtils::isNotEmpty).collect(Collectors.toList());
                 String maxRecordNo;
                 if (recordNos.size() == 0 || ObjectUtil.isEmpty(recordNos)) {
                     maxRecordNo = "0001";
@@ -1141,10 +1141,10 @@ public class TrialSelfInspectionRecordServiceImpl extends BaseServiceImpl<TrialS
         }
 
         //报告单
-        if (("2").equals(dto.getTableType())) {
+        if (("2").equals(dto.getTableType()) || ("10").equals(dto.getTableType())) {
             if (StringUtils.isEmpty(dto.getReportNo())) {
                 //获取报告单最大编号
-                List<String> reportNos = trialSelfInspectionRecords.stream().filter(f -> ObjectUtils.isNotEmpty(f.getReportNo())).map(TrialSelfInspectionRecord::getReportNo).collect(Collectors.toList());
+                List<String> reportNos = trialSelfInspectionRecords.stream().map(TrialSelfInspectionRecord::getReportNo).filter(ObjectUtils::isNotEmpty).collect(Collectors.toList());
                 String maxReportNo;
                 if (reportNos.size() == 0 || ObjectUtil.isEmpty(reportNos)) {
                     maxReportNo = "0001";

+ 100 - 15
blade-service/blade-business/src/main/java/org/springblade/business/utils/FileUtils.java

@@ -1,5 +1,12 @@
 package org.springblade.business.utils;
 
+import com.drew.imaging.ImageMetadataReader;
+import com.drew.imaging.ImageProcessingException;
+import com.drew.metadata.Directory;
+import com.drew.metadata.Metadata;
+import com.drew.metadata.MetadataException;
+import com.drew.metadata.exif.ExifIFD0Directory;
+import com.drew.metadata.exif.ExifSubIFDDirectory;
 import com.itextpdf.text.Document;
 import com.itextpdf.text.pdf.PdfCopy;
 import com.itextpdf.text.pdf.PdfReader;
@@ -11,14 +18,21 @@ import org.springblade.common.utils.CommonUtil;
 import org.springblade.common.vo.DataVO;
 import org.springblade.core.tool.utils.IoUtil;
 
+import javax.imageio.IIOImage;
 import javax.imageio.ImageIO;
+import javax.imageio.ImageWriteParam;
+import javax.imageio.ImageWriter;
+import javax.imageio.stream.ImageOutputStream;
 import javax.servlet.http.HttpServletResponse;
 import java.awt.*;
 import java.awt.Color;
+import java.awt.geom.AffineTransform;
+import java.awt.image.AffineTransformOp;
 import java.awt.image.BufferedImage;
 import java.io.*;
 import java.net.URLEncoder;
 import java.util.Arrays;
+import java.util.Iterator;
 import java.util.List;
 import java.util.regex.Matcher;
 import java.util.zip.ZipEntry;
@@ -100,21 +114,89 @@ public class FileUtils {
     }
 
     /**
-     * 压缩图片
+     * 图片缩放、压缩、旋转处理
+     * @param imageData
+     * @return
+     * @throws IOException
+     * @throws ImageProcessingException
+     * @throws MetadataException
      */
-    public static byte[] resizeImage(byte[] srcImgData, float reduceMultiple) throws IOException {
-        BufferedImage bi = ImageIO.read(new ByteArrayInputStream(srcImgData));
-        int width = (int) (bi.getWidth() * reduceMultiple);
-        int height = (int) (bi.getHeight() * reduceMultiple);
-        Image image = bi.getScaledInstance(width, height, Image.SCALE_SMOOTH);
-        BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
-        Graphics g = tag.getGraphics();
-        g.setColor(Color.RED);
-        g.drawImage(image, 0, 0, null);
-        g.dispose();
-        ByteArrayOutputStream bOut = new ByteArrayOutputStream();
-        ImageIO.write(tag, "JPEG", bOut);
-        return bOut.toByteArray();
+    public static byte[] compressImage(byte[] imageData) throws IOException, ImageProcessingException, MetadataException {
+        // 读取原始图像(处理旋转问题)
+        Metadata metadata = ImageMetadataReader.readMetadata(new ByteArrayInputStream(imageData));
+        if (metadata.containsDirectoryOfType(ExifIFD0Directory.class)) {
+            ExifIFD0Directory exifIFD0Directory = metadata.getFirstDirectoryOfType(ExifIFD0Directory.class);
+            if (exifIFD0Directory.containsTag(ExifIFD0Directory.TAG_ORIENTATION)) {
+                // 获取 Orientation 标签的值
+                int orientation = exifIFD0Directory.getInt(ExifIFD0Directory.TAG_ORIENTATION);
+                // 需要旋转图片
+                BufferedImage originalImage = ImageIO.read(new ByteArrayInputStream(imageData));
+                AffineTransform transform = new AffineTransform();
+                if (orientation == 6) {
+                    transform.rotate(Math.PI / 2, originalImage.getWidth() / 2, originalImage.getHeight() / 2);
+                } else if (orientation == 8) {
+                    transform.rotate(-Math.PI / 2, originalImage.getWidth() / 2, originalImage.getHeight() / 2);
+                }
+                AffineTransformOp op = new AffineTransformOp(transform, AffineTransformOp.TYPE_BILINEAR);
+                originalImage = op.filter(originalImage, null);
+                ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                ImageIO.write(originalImage, "jpg", baos);
+                imageData = baos.toByteArray();
+            }
+        }
+
+        // 缩放图像
+        String formatName = "JPEG";
+        ByteArrayInputStream bais = new ByteArrayInputStream(imageData);
+        BufferedImage originalImage = ImageIO.read(bais);
+        long sizeLimit = 366912; //358KB
+        int width = 768;
+        int height = 1024;
+        Image scaledImage = originalImage.getScaledInstance(width, height, Image.SCALE_SMOOTH);
+        BufferedImage resizedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
+        resizedImage.getGraphics().drawImage(scaledImage, 0, 0, null);
+
+        // 压缩图像
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ImageIO.write(resizedImage, formatName, baos);
+
+        if (baos.size() <= sizeLimit) {
+            // 图片大小已经小于等于目标大小,直接返回原始数据
+            return baos.toByteArray();
+        }
+
+        float quality = 0.9f; // 初始化压缩质量
+        int retries = 10; // 最多尝试 10 次
+
+        while (baos.size() > sizeLimit && retries > 0) {
+            // 压缩图像并重新计算压缩质量
+            byte[] data = baos.toByteArray();
+            bais = new ByteArrayInputStream(data);
+            BufferedImage compressedImage = ImageIO.read(bais);
+            baos.reset();
+
+            ImageWriter writer = null;
+            Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName(formatName);
+            if (writers.hasNext()) {
+                writer = writers.next();
+            } else {
+                throw new IllegalArgumentException("Unsupported image format: " + formatName);
+            }
+
+            ImageWriteParam writeParam = writer.getDefaultWriteParam();
+            writeParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
+            writeParam.setCompressionQuality(quality);
+
+            writer.setOutput(ImageIO.createImageOutputStream(baos));
+            writer.write(null, new IIOImage(compressedImage, null, null), writeParam);
+            writer.dispose();
+
+            float ratio = sizeLimit * 1.0f / baos.size();
+            quality *= Math.sqrt(ratio);
+            retries--;
+        }
+
+        return baos.toByteArray();
     }
 
     /**
@@ -126,7 +208,7 @@ public class FileUtils {
      */
     public static void imageOrientation(Sheet sheet, ClientAnchor anchor, DataVO dataVO) {
         // 设置图片距左边和上边的偏移量
-        anchor.setDx1(Units.pixelToEMU(5));
+        anchor.setDx1(Units.pixelToEMU(-90));
         anchor.setDy1(Units.pixelToEMU(5));
         // 设置图片右下角所在单元格的行列号与左上角一致
         anchor.setCol2(anchor.getCol1());
@@ -146,6 +228,9 @@ public class FileUtils {
         int dy = Units.pointsToPixel(sheet.getRow(anchor.getRow2()).getHeightInPoints()) - 5;
         anchor.setDx2(Units.pixelToEMU(dx));
         anchor.setDy2(Units.pixelToEMU(dy));
+
+        // 禁止旋转
+        anchor.setAnchorType(ClientAnchor.AnchorType.DONT_MOVE_AND_RESIZE);
     }
 
     /**

+ 12 - 3
blade-service/blade-e-visa/src/main/java/org/springblade/evisa/service/impl/EVisaServiceImpl.java

@@ -51,6 +51,8 @@ import org.springblade.manager.feign.ContractClient;
 import org.springblade.manager.feign.SignPfxClient;
 import org.springblade.resource.feign.NewIOSSClient;
 import org.springblade.system.cache.ParamCache;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.StringRedisTemplate;
 import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
 import org.springframework.http.converter.HttpMessageConverter;
 import org.springframework.http.converter.StringHttpMessageConverter;
@@ -100,6 +102,9 @@ public class EVisaServiceImpl implements EVisaService {
 
     private final ContractClient contractClient;
 
+    @Autowired
+    StringRedisTemplate RedisTemplate;
+
     @Override
     public String certification(String pdfUrl, String fileName, String contractId) {
         try {
@@ -311,6 +316,7 @@ public class EVisaServiceImpl implements EVisaService {
         TaskApprovalVO taskFile = this.taskClient.queryBusinessDataTask(JSONObject.parseObject(JSONObject.toJSONString(task), TaskApprovalVO.class));
         if (taskFile == null || taskFile.getApprovalFileList().size() <= 0) {
             //没有找到业务文件,取消签章
+            RedisTemplate.delete("sign-"+task.getFormDataId());
             return NOT_PFX_OR_FILE;
         }
 
@@ -318,6 +324,7 @@ public class EVisaServiceImpl implements EVisaService {
         List<JSONObject> eVisaConfigList = this.taskClient.queryBusinessTableEVisaConfig(task.getParallelProcessInstanceId(),task.getUserId(), "false");
         if (eVisaConfigList == null || eVisaConfigList.size() == 0) {
             //没有电签配置,默认当前任务为不签字审批,返回成功
+            RedisTemplate.delete("sign-"+task.getFormDataId());
             return SUCCESS + "@@@@" + taskFile.getApprovalFileList().get(0).getFileUrl();
         }
 
@@ -325,11 +332,12 @@ public class EVisaServiceImpl implements EVisaService {
         List<SignPfxFile> userPfxList = this.signPfxClient.querySignPfxByUserIdOrContractId(task.getUserId().toString(), "");
         if (userPfxList == null || userPfxList.size() <= 0) {
             //没有签章,不执行电签
+            RedisTemplate.delete("sign-"+task.getFormDataId());
             return NOT_PFX_OR_FILE;
         }
 
         //上锁
-        if (DistributedRedisLock.acquire(task.getUserId().toString(), batch)) {
+        //if (DistributedRedisLock.acquire(task.getUserId().toString(), batch)) {
             try {
                 //获取需要签章的数据
                 List<TaskApprovalVO.ApprovalFile> files = taskFile.getApprovalFileList();
@@ -383,11 +391,12 @@ public class EVisaServiceImpl implements EVisaService {
                     }
                 }
             } catch (Exception e) {
+                RedisTemplate.delete("sign-"+task.getFormDataId());
                 e.printStackTrace();
             }
-        }
+       // }
         //释放锁
-        DistributedRedisLock.release(task.getUserId().toString());
+      //  DistributedRedisLock.release(task.getUserId().toString());
 
         return resultMessage;
     }

+ 11 - 5
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ExcelTabController.java

@@ -282,8 +282,8 @@ public class ExcelTabController extends BladeController {
     })
     public R putFileAttach(@RequestParam("file") MultipartFile file, Long nodeId) {
 
-        String file_path = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
-        //String file_path = "/Users/hongchuangyanfa/Desktop/"; //ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
+        //String file_path = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
+        String file_path = "/Users/hongchuangyanfa/Desktop/"; //ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
 
         ExcelTab detail = excelTabService.getById(nodeId);
         // 上传excel文件
@@ -859,6 +859,9 @@ public class ExcelTabController extends BladeController {
 
             // 计算单元格坐标
             int x = 0;
+            if(i==9 || i==10){
+                System.out.println("1234");
+            }
             for (int j = 0; j < tds.size(); j++) {
                 {
                     Element data = tds.get(j);
@@ -971,7 +974,10 @@ public class ExcelTabController extends BladeController {
                                 int mx1 = Integer.parseInt(dataInfo3.split(":")[0]);
                                 int mx2 = Integer.parseInt(dataInfo3.split(":")[1]);
                                 if (mx2 + 1 == x1) {
-                                    dataInfo = StringUtils.join(ArrayUtils.remove(dataInfo2, dataInfo2.length - 1)); //removing element at index 2
+                                    String [] data3=new String[dataInfo2.length-1];
+                                    System.arraycopy(dataInfo2,0,data3,0,data3.length);
+                                    dataInfo = StringUtils.join(data3); //removing element at index 2
+
                                     if (dataInfo2.length == 1) {
                                         dataInfo = mx1 + ":" + x2;
                                     } else {
@@ -1679,9 +1685,9 @@ public class ExcelTabController extends BladeController {
         System.out.println("3=" + DateUtil.formatDateTime(DateUtil.now()));
         //单个 pdf加载
         for (TableInfo tableInfo : tableInfoList) {
-            if(!tableInfo.isToBeUpdated()){
+            //if(!tableInfo.isToBeUpdated()){
                 excelTabService.getBussPdfInfo(Long.parseLong(tableInfo.getPkeyId()));
-            }
+          //  }
 
         }
         System.out.println("4=" + DateUtil.formatDateTime(DateUtil.now()));

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

@@ -378,8 +378,24 @@ public class FirstController extends BladeController {
                 if (pdfUrls.size() > 0) {
                     try {
                         //关联的数据
-                        if (StringUtils.isNotEmpty(firstJson.getString("linkMergePdfUrl"))) {
-                            pdfUrls.add(firstJson.getString("linkMergePdfUrl"));
+//                        if (StringUtils.isNotEmpty(firstJson.getString("linkMergePdfUrl"))) {
+//                            pdfUrls.add(firstJson.getString("linkMergePdfUrl"));
+//                        }
+                        //获取所有工序节点的最新pdf
+                        String ids = firstJson.getString("sjRecordIds");
+                        if (StringUtils.isNotEmpty(ids)) {
+                            String[] strings = ids.split(",");
+                            for (String id : strings) {
+                                JSONObject info = informationQueryClient.queryFirstBusinessDataByFirstId(id);
+                                if (StringUtils.isNotEmpty(info.getString("eVisaPdfUrl"))){
+                                    pdfUrls.add(info.getString("eVisaPdfUrl"));
+                                }else if (StringUtils.isNotEmpty(info.getString("pdfUrl"))){
+                                    pdfUrls.add(info.getString("pdfUrl"));
+                                }
+                                if (StringUtils.isNotEmpty(info.getString("uploadFile"))) {
+                                    pdfUrls.add(info.getString("uploadFile"));
+                                }
+                            }
                         }
                         //总结报告
                         if (StringUtils.isNotEmpty(firstJson.getString("uploadFile"))) {

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

@@ -1,6 +1,8 @@
 package org.springblade.manager.controller;
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import io.swagger.annotations.*;
 import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
 import lombok.AllArgsConstructor;
@@ -10,9 +12,12 @@ 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.springblade.manager.dto.WbsTreeContractDTO;
 import org.springblade.manager.dto.ProjectInfoDTO;
 import org.springblade.manager.entity.ContractInfo;
+import org.springblade.manager.entity.WbsInfo;
+import org.springblade.manager.entity.WbsTreePrivate;
 import org.springblade.manager.service.*;
 import org.springblade.manager.vo.*;
 import org.springframework.jdbc.core.BeanPropertyRowMapper;
@@ -23,8 +28,11 @@ import org.springblade.manager.entity.ProjectInfo;
 import org.springblade.manager.wrapper.ProjectInfoWrapper;
 import org.springblade.core.boot.ctrl.BladeController;
 
+import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.stream.Collectors;
 
 @RestController
 @AllArgsConstructor
@@ -198,7 +206,7 @@ public class ProjectInfoController extends BladeController {
      */
     @GetMapping("/tree")
     @ApiOperationSupport(order = 11)
-    @ApiOperation(value = "查询项目私有wbs节点树形结构(多个接口复用)", notes = "wbsId、项目id")
+    @ApiOperation(value = "查询项目私有wbs节点树形结构", notes = "wbsId、项目id")
     @ApiImplicitParams(value = {
             @ApiImplicitParam(name = "projectId", value = "项目id", required = true),
             @ApiImplicitParam(name = "wbsId", value = "wbsId", required = true)
@@ -211,6 +219,25 @@ public class ProjectInfoController extends BladeController {
         return R.fail(200, "未查询到信息");
     }
 
+    /**
+     * 后管-试验-新增or编辑勾选相关联试验-获取试验配合比树
+     */
+    @GetMapping("/tree-record-trial")
+    @ApiOperationSupport(order = 11)
+    @ApiOperation(value = "后管-试验-新增or编辑勾选相关联试验-获取试验配合比树", notes = "wbsId、项目id、节点pKeyId")
+    @ApiImplicitParams(value = {
+            @ApiImplicitParam(name = "projectId", value = "项目id", required = true),
+            @ApiImplicitParam(name = "wbsId", value = "wbsId", required = true),
+            @ApiImplicitParam(name = "pKeyId", value = "节点pKeyId", required = true)
+    })
+    public R<Map<String, List<Object>>> treeRecordTrial(String wbsId, String projectId, String pKeyId) {
+        Map<String, List<Object>> map = wbsTreePrivateService.treeRecordTrial(wbsId, projectId, pKeyId);
+        if (map != null && map.size() > 0) {
+            return R.data(map);
+        }
+        return R.fail(200, "未查询到信息");
+    }
+
     /**
      * 保存或修改分配项目级wbs树
      */

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

@@ -130,7 +130,7 @@ public class TableFileController extends BladeController {
 
         Long pkeyId = Long.parseLong(tableFile.getTabId() + "");
         //单pdf
-        excelTabService.getBussPDFTrial(pkeyId, contractId, id, 0, 0);
+        excelTabService.getBussPDFTrial(pkeyId, contractId, id, 0, 0, null);
 
         WbsTreePrivate wbsTreePrivate = wbsTreePrivateService.getBaseMapper().selectOne(Wrappers.<WbsTreePrivate>query().lambda()
                 .eq(WbsTreePrivate::getPKeyId, pkeyId));
@@ -154,7 +154,7 @@ public class TableFileController extends BladeController {
         List<String> collect = query.stream().map(TrialSelfInspectionRecord::getTableIds).collect(Collectors.toList());
 
         //合并pdf
-        String bussPDFSTrial = excelTabService.getBussPDFSTrial(wbsTreePrivate1.getPKeyId() + "", tableType, classify, contractId, wbsTreePrivate.getProjectId(), id, org.apache.commons.lang.StringUtils.join(collect, ","));
+        String bussPDFSTrial = excelTabService.getBussPDFSTrial(wbsTreePrivate1.getPKeyId() + "", tableType, classify, contractId, wbsTreePrivate.getProjectId(), id, org.apache.commons.lang.StringUtils.join(collect, ","), null);
 
         if (StringUtils.isNotEmpty(bussPDFSTrial)) {
             //修改合并pdf

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

@@ -38,33 +38,33 @@ public class WbsTreeContractController extends BladeController {
     @ApiOperation(value = "查询当前节点下所有元素表信息", notes = "传入节点primaryKeyId、type、合同段id、项目id")
     public R searchNodeAllTable(String primaryKeyId, String type, String contractId, String projectId) {
         List<AppWbsTreeContractVO> list = iWbsTreeContractService.searchNodeAllTable(primaryKeyId, type, contractId, projectId);
-        boolean flag = false;
-        Set<Long> l1 = new HashSet<>();
-        for (AppWbsTreeContractVO vo : list) {
-            if (vo.getNodeName().contains("_PL_")){
-                l1.add(vo.getId());
-                flag = true;
-            }
-        }
-        if (flag){
-            for (Long aLong : l1) {
-                List<AppWbsTreeContractVO> vos = new ArrayList<>();
-                for (AppWbsTreeContractVO vo : list) {
-                    if (aLong.equals(vo.getId())){
-                        vos.add(vo);
-                    }
-                }
-                list = list.stream().filter(l -> {
-                    if (l.getId().equals(aLong)){
-                        return false;
-                    }else {
-                        return true;
-                    }
-                }).collect(Collectors.toList());
-                vos = vos.stream().sorted(Comparator.comparing(AppWbsTreeContractVO::getPKeyId)).collect(Collectors.toList());
-                list.addAll(vos);
-            }
-        }
+//        boolean flag = false;
+//        Set<Long> l1 = new HashSet<>();
+//        for (AppWbsTreeContractVO vo : list) {
+//            if (vo.getNodeName().contains("_PL_")){
+//                l1.add(vo.getId());
+//                flag = true;
+//            }
+//        }
+//        if (flag){
+//            for (Long aLong : l1) {
+//                List<AppWbsTreeContractVO> vos = new ArrayList<>();
+//                for (AppWbsTreeContractVO vo : list) {
+//                    if (aLong.equals(vo.getId())){
+//                        vos.add(vo);
+//                    }
+//                }
+//                list = list.stream().filter(l -> {
+//                    if (l.getId().equals(aLong)){
+//                        return false;
+//                    }else {
+//                        return true;
+//                    }
+//                }).collect(Collectors.toList());
+//                vos = vos.stream().sorted(Comparator.comparing(AppWbsTreeContractVO::getPKeyId)).collect(Collectors.toList());
+//                list.addAll(vos);
+//            }
+//        }
         if (list.size() > 0) {
             list.stream().forEach(l->{
                 if (StringUtils.isNotBlank(l.getHtmlUrl())){

+ 9 - 2
blade-service/blade-manager/src/main/java/org/springblade/manager/feign/ArchiveTreeContractImpl.java

@@ -46,18 +46,25 @@ public class ArchiveTreeContractImpl implements ArchiveTreeContractClient {
 
     @Override
     public List<ArchiveTreeContract> getListByProjectId(Long projectId) {
-        return archiveTreeContractMapper.getListByProjectId(projectId);
+        List<ArchiveTreeContract> list = archiveTreeContractMapper.getListByProjectId(projectId);
+        archiveTreeContractService.fillDefaultArchiveAutoInfo(list);
+        return list;
     }
 
     @Override
     public List<ArchiveTreeContract> getSelectNodeByGroupId(Long projectId,Long archiveAutoGroupId) {
         List<ArchiveTreeContract> list = archiveTreeContractMapper.getSelectNodeByGroupId(projectId,archiveAutoGroupId);
+        archiveTreeContractService.fillDefaultArchiveAutoInfo(list);
         return list;
     }
 
     @Override
     public ArchiveTreeContract getArchiveTreeContractById(Long id) {
-        return null;
+        ArchiveTreeContract archiveTreeContract = archiveTreeContractService.getById(id);
+        List<ArchiveTreeContract> list = new ArrayList<>();
+        list.add(archiveTreeContract);
+        archiveTreeContractService.fillDefaultArchiveAutoInfo(list);
+        return archiveTreeContract;
     }
 
 

+ 14 - 19
blade-service/blade-manager/src/main/java/org/springblade/manager/feign/ExcelTabClientImpl.java

@@ -76,14 +76,12 @@ public class ExcelTabClientImpl implements ExcelTabClient {
         if (isBatchSave == 0) {
             //------单表PDF保存------
             TableInfo tableInfo = tableInfoList.stream().findAny().orElse(null);
-            assert tableInfo != null;
-            if (tabIds.contains(tableInfo.getPkeyId())) {
+            if (tableInfo != null && tabIds.contains(tableInfo.getPkeyId())) {
                 //构造pdf
-                excelTabService.getBussPDFTrial(Long.valueOf(tableInfo.getPkeyId()), contractId, id, 0, 0);
+                excelTabService.getBussPDFTrial(Long.valueOf(tableInfo.getPkeyId()), contractId, id, 0, 0, dto);
 
                 //重新合并pdf
-                String sql = "select pdf_url from u_trial_self_data_record where record_id = " + id;
-                List<TrialSelfDataRecord> query = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(TrialSelfDataRecord.class));
+                List<TrialSelfDataRecord> query = jdbcTemplate.query("select pdf_url from u_trial_self_data_record where record_id = " + id, new BeanPropertyRowMapper<>(TrialSelfDataRecord.class));
                 List<String> pdfList = query.stream().map(TrialSelfDataRecord::getPdfUrl).collect(Collectors.toList());
 
                 String file_path = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
@@ -95,20 +93,17 @@ public class ExcelTabClientImpl implements ExcelTabClient {
                 FileUtils.mergePdfPublicMethods(pdfList, pdfPath);
                 BladeFile bladeFile = newIOSSClient.uploadFile(id + "2.pdf", pdfPath);
 
-                String sqlUpdate = "update u_trial_self_inspection_record set pdf_url = '" + bladeFile.getLink() + "' where id = " + id;
-                jdbcTemplate.execute(sqlUpdate);
+                jdbcTemplate.execute("update u_trial_self_inspection_record set pdf_url = '" + bladeFile.getLink() + "' where id = " + id);
 
                 //获取试验记录id的试验项目名称,重新合并pdf集合(解决单表保存后上报找不到题名问题)
-                String sql2 = "select trial_project_name from u_trial_self_inspection_record where id = " + id;
-                TrialSelfInspectionRecord obj = jdbcTemplate.query(sql2, new BeanPropertyRowMapper<>(TrialSelfInspectionRecord.class)).stream().findAny().orElse(null);
-                assert obj != null;
-                String querySql = "select id from u_information_query where classify ='" + type + "' and wbs_id ='" + id + "' and contract_id ='" + contractId + "'";
-                List<InformationQuery> query2 = jdbcTemplate.query(querySql, new BeanPropertyRowMapper<>(InformationQuery.class));
-                if (query2.size() > 0) {
-                    String updateSql = "update u_information_query set pdf_url ='" + bladeFile.getLink() + "', name ='" + obj.getTrialProjectName() + "'  where classify='" + type + "' and  wbs_id='" + id + "' and contract_id ='" + contractId + "'";
-                    jdbcTemplate.execute(updateSql);
+                TrialSelfInspectionRecord obj = jdbcTemplate.query("select trial_project_name from u_trial_self_inspection_record where id = " + id, new BeanPropertyRowMapper<>(TrialSelfInspectionRecord.class)).stream().findAny().orElse(null);
+                List<InformationQuery> query2 = jdbcTemplate.query("select id from u_information_query where classify ='" + type + "' and wbs_id ='" + id + "' and contract_id ='" + contractId + "'", new BeanPropertyRowMapper<>(InformationQuery.class));
+                if (obj != null && query2.size() > 0) {
+                    jdbcTemplate.execute("update u_information_query set pdf_url ='" + bladeFile.getLink() + "', name ='" + obj.getTrialProjectName() + "'  where classify='" + type + "' and  wbs_id='" + id + "' and contract_id ='" + contractId + "'");
                 } else {
-                    informationQueryClient.saveData(id.toString(), projectId, contractId, type.toString(), bladeFile.getLink(), obj.getTrialProjectName());
+                    if (obj != null) {
+                        informationQueryClient.saveData(id.toString(), projectId, contractId, type.toString(), bladeFile.getLink(), obj.getTrialProjectName());
+                    }
                 }
             }
 
@@ -122,7 +117,7 @@ public class ExcelTabClientImpl implements ExcelTabClient {
              * id=记录id
              * tabIds=表的pKeyIds
              */
-            pdfUrl = excelTabService.getBussPDFSTrial(nodeId, tableType, String.valueOf(type), contractId, projectId, id, tabIds);
+            pdfUrl = excelTabService.getBussPDFSTrial(nodeId, tableType, String.valueOf(type), contractId, projectId, id, tabIds,dto);
 
         }
         return pdfUrl;
@@ -130,12 +125,12 @@ public class ExcelTabClientImpl implements ExcelTabClient {
 
     @Override
     public void getBussPDFTrial(Long pkeyId, String contractId, String id) throws Exception {
-        excelTabService.getBussPDFTrial(pkeyId, contractId, Long.parseLong(id), 0, 0);
+        excelTabService.getBussPDFTrial(pkeyId, contractId, Long.parseLong(id), 0, 0, null);
     }
 
     @Override
     public String getBussPDFSTrial(String nodeId, String tableType, String classify, String contractId, String projectId, String id, String tabIds) throws Exception {
-        return excelTabService.getBussPDFSTrial(nodeId, tableType, classify, contractId, projectId, Long.parseLong(id), tabIds);
+        return excelTabService.getBussPDFSTrial(nodeId, tableType, classify, contractId, projectId, Long.parseLong(id), tabIds,null);
     }
 
 

+ 11 - 1
blade-service/blade-manager/src/main/java/org/springblade/manager/feign/TableFileClientImpl.java

@@ -1,7 +1,9 @@
 package org.springblade.manager.feign;
 
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import lombok.AllArgsConstructor;
 import org.springblade.common.utils.SnowFlakeUtil;
+import org.springblade.core.tool.utils.Func;
 import org.springblade.manager.entity.TableFile;
 import org.springblade.manager.service.ITableFileService;
 import org.springframework.web.bind.annotation.RestController;
@@ -13,7 +15,7 @@ import java.util.List;
 @AllArgsConstructor
 public class TableFileClientImpl implements TableFileClient {
 
-    private ITableFileService tableFileService;
+    private final ITableFileService tableFileService;
 
     @Override
     public void saveFile(TableFile tableFile) {
@@ -32,4 +34,12 @@ public class TableFileClientImpl implements TableFileClient {
     public boolean saveBatch(List<TableFile> newFiles) {
         return tableFileService.saveBatch(newFiles, 100);
     }
+
+    @Override
+    public List<TableFile> getTabFilesByTabIds(String tabFileIds) {
+        return tableFileService.getBaseMapper().selectList(Wrappers.<TableFile>lambdaQuery()
+                .in(TableFile::getTabId, Func.toLongList(tabFileIds))
+                .isNotNull(TableFile::getTabId)
+        );
+    }
 }

+ 49 - 9
blade-service/blade-manager/src/main/java/org/springblade/manager/feign/WbsTreeContractClientImpl.java

@@ -9,16 +9,12 @@ import com.mixsmart.utils.StringUtils;
 import lombok.AllArgsConstructor;
 import org.springblade.common.constant.CommonConstant;
 import org.springblade.common.utils.CommonUtil;
-import org.springblade.manager.entity.ContractInfo;
-import org.springblade.manager.entity.ContractRelationJlyz;
-import org.springblade.manager.entity.WbsTree;
-import org.springblade.manager.entity.WbsTreeContract;
+import org.springblade.core.tool.node.ForestNodeMerger;
+import org.springblade.manager.entity.*;
 import org.springblade.manager.service.IContractInfoService;
 import org.springblade.manager.service.IWbsTreeContractService;
 import org.springblade.manager.service.impl.WbsTreeContractServiceImpl;
-import org.springblade.manager.vo.WbsTreeContractTreeVO;
-import org.springblade.manager.vo.WbsTreeContractTreeVO3;
-import org.springblade.manager.vo.WbsTreeContractTreeVOS;
+import org.springblade.manager.vo.*;
 import org.springblade.system.entity.DictBiz;
 import org.springblade.system.feign.IDictBizClient;
 import org.springblade.system.feign.ISysClient;
@@ -40,6 +36,11 @@ public class WbsTreeContractClientImpl implements WbsTreeContractClient {
 
     private final ISysClient sysClient;
 
+    @Override
+    public WbsTreeContract queryContractTreeNodeByPKeyId(Long toCopyNodePKeyId) {
+        return this.wbsTreeContractService.getOne(Wrappers.<WbsTreeContract>lambdaQuery().eq(WbsTreeContract::getPKeyId, toCopyNodePKeyId));
+    }
+
     @Override
     public List<WbsTreeContract> queryContractTreeNodeByPKIds(List<Long> PKIds) {
         return this.wbsTreeContractService.list(Wrappers.<WbsTreeContract>lambdaQuery().in(WbsTreeContract::getPKeyId, PKIds));
@@ -106,7 +107,7 @@ public class WbsTreeContractClientImpl implements WbsTreeContractClient {
 
     @Override
     public Boolean saveBatch(List<WbsTreeContract> list) {
-        return this.wbsTreeContractServiceImpl.insertBatch(list,1000);
+        return this.wbsTreeContractServiceImpl.saveOrUpdateBatch(list, 1000);
     }
 
     @Override
@@ -156,7 +157,7 @@ public class WbsTreeContractClientImpl implements WbsTreeContractClient {
 
     @Override
     public WbsTreeContract getContractWbsTreeByContractIdAndId(Long id, Long contractId) {
-        return this.wbsTreeContractService.getOne(Wrappers.<WbsTreeContract>lambdaQuery().eq(WbsTreeContract::getId, id.toString()).eq(WbsTreeContract::getContractId, contractId.toString()));
+        return this.wbsTreeContractService.getOne(Wrappers.<WbsTreeContract>lambdaQuery().eq(WbsTreeContract::getId, id).eq(WbsTreeContract::getContractId, contractId.toString()));
     }
 
     @Override
@@ -239,6 +240,45 @@ public class WbsTreeContractClientImpl implements WbsTreeContractClient {
         return this.wbsTreeContractService.list(wrapper);
     }
 
+    @Override
+    public WbsTreeContract queryWbsTreeContractById(String contractId, Long parseLong) {
+        return this.wbsTreeContractService.getOne(Wrappers.<WbsTreeContract>lambdaQuery().eq(WbsTreeContract::getContractId, contractId).eq(WbsTreeContract::getId, parseLong).eq(WbsTreeContract::getStatus, 1));
+    }
+
+    @Override
+    public List<WbsTreeContractTreeVOS> queryWbsTreeContractTreeLazy(String contractId, Long parseLong) {
+        List<WbsTreeContract> result = this.wbsTreeContractService.list(Wrappers.<WbsTreeContract>lambdaQuery().eq(WbsTreeContract::getContractId, contractId).eq(WbsTreeContract::getType, 1).like(WbsTreeContract::getAncestors, parseLong));
+        if (result != null && result.size() > 0) {
+            //转换实体
+            List<WbsTreeContractVO> voList = ForestNodeMerger.merge(JSONArray.parseArray(JSONObject.toJSONString(result), WbsTreeContractVO.class));
+            List<WbsTreeContractTreeVOS> vosResult = new ArrayList<>();
+            this.foreachSetChildList(vosResult, voList);
+            return vosResult;
+        }
+        return null;
+    }
+
+    private void foreachSetChildList(List<WbsTreeContractTreeVOS> vosResult, List<WbsTreeContractVO> voList) {
+        voList.forEach(vo -> {
+            WbsTreeContractTreeVOS vos = new WbsTreeContractTreeVOS();
+            vos.setId(vo.getId());
+            vos.setKey(vo.getId().toString());
+            vos.setPrimaryKeyId(vo.getPKeyId().toString());
+            vos.setParentId(vo.getParentId());
+            vos.setTitle(vo.getNodeName());
+            vos.setType(vo.getType());
+            vos.setWbsType(vo.getWbsType());
+            vos.setNotExsitChild(vos.getChildren().size() == 0);
+
+            if (vo.getChildren().size() > 0) {
+                List<WbsTreeContractTreeVOS> child = new ArrayList<>();
+                this.foreachSetChildList(child, vo.getChildren());
+                vos.setChildren(child);
+            }
+            vosResult.add(vos);
+        });
+    }
+
     @Override
     public List<WbsTreeContractTreeVOS> queryCurrentContractLogList(String contractId) {
         ContractInfo contract = this.contractInfoService.getById(contractId);

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

@@ -426,7 +426,7 @@
                 #{tableOwnerList}
             </foreach>
         </if>
-        ORDER BY sort,node_name,create_time
+        ORDER BY sort,full_name,p_key_id,update_time
     </select>
 
     <select id="selectRoleInfo" resultType="org.springblade.manager.entity.SaveUserInfoByProject">

+ 5 - 2
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsTreeMapper.xml

@@ -347,7 +347,10 @@
             wt.id AS id,
             wt.node_name AS tableName,
             wt.sort AS sort,
-            wt.table_type AS tableType,
+            case when wt.table_type in(1,9) then 1
+                 when wt.table_type in(2,10) then 2
+                 else wt.table_type
+                    end as tableType,
             wt.`status` AS isCreateTable ,
             wt.table_owner as tableOwner,
             wt.is_link_table,
@@ -356,7 +359,7 @@
             wt.wbs_id AS "wbsId",
             wt.fill_rate AS "fillRate",
             wt.init_table_id AS initTableId,
-            (SELECT count(*) FROM m_wbs_form_element WHERE f_id = wt.init_table_id and is_deleted = 0 and status = 1) AS "elementTotal"
+            (SELECT count(1) FROM m_wbs_form_element WHERE f_id = wt.init_table_id and is_deleted = 0 and status = 1) AS "elementTotal"
         FROM
             m_wbs_tree AS wt
         WHERE

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

@@ -83,7 +83,7 @@ public interface WbsTreePrivateMapper extends EasyBaseMapper<WbsTreePrivate> {
 
     void delTabProjectById(String pKeyId, String projectId);
 
-    List<WbsTreePrivateVO4> selectWbsTreeTrialTabList(List<String> roleAndTabOwners, String tableType, String projectId, String wbsId, Long parentId, List<String> tableOwnerList, String contractId);
+    List<WbsTreePrivateVO4> selectWbsTreeTrialTabList(String tableType, String projectId, String wbsId, Long parentId, String contractId);
 
     //删除表单信息
     void delTableById(String pKeyId);
@@ -91,4 +91,7 @@ public interface WbsTreePrivateMapper extends EasyBaseMapper<WbsTreePrivate> {
     List<TableInfo> selectTabInfoAll();
 
     void updateBatchByPKeyId(@Param("list") List<WbsTreePrivate> wbsTreePrivateList);
+
+    List<WbsTreePrivateVO5> treeRecordTrial(String wbsId, String projectId, Integer wbsType);
+
 }

+ 29 - 12
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsTreePrivateMapper.xml

@@ -451,8 +451,12 @@
     <select id="selectByNodeTable" resultType="org.springblade.manager.vo.WbsNodeTableVO">
         SELECT wt.p_key_id AS "pKeyId",
                wt.id AS id,
+               wt.wbs_type AS wbsType,
                wt.node_name AS tableName,
-               wt.table_type AS tableType,
+               case when wt.table_type in(1,9) then 1
+                    when wt.table_type in(2,10) then 2
+                    else wt.table_type
+                       end as tableType,
                wt.`status` AS isCreateTable,
                wt.table_owner AS tableOwner,
                wt.is_link_table,
@@ -471,6 +475,7 @@
           AND wt.wbs_id = #{wbsId}
           AND wt.project_id = #{projectId}
           AND wt.trial_tab_contract_id is null
+          AND (wt.wbs_type != 2 OR wt.table_type IN (1,2,9,10))
         ORDER BY wt.sort, wt.node_name, wt.create_time
     </select>
     <select id="getByCondition" resultType="org.springblade.manager.entity.WbsTreePrivate">
@@ -701,7 +706,9 @@
             excel_id,
             project_id,
             type,
-            table_type,
+            case when table_type = 9 then 1
+                 when table_type = 10 then 2
+                 end as tableType,
             table_owner,
             init_table_name,
             init_table_id,
@@ -716,19 +723,11 @@
             AND wbs_id = #{wbsId}
             AND parent_id = #{parentId}
             AND table_type = #{tableType}
-            AND table_owner in
-        <foreach item="roleAndTabOwners" collection="roleAndTabOwners" open="(" close=")" separator=",">
-            #{roleAndTabOwners}
-        </foreach>
             AND type = 2
             AND status = 1
             AND is_deleted = 0
-        <if test="tableOwnerList != null and tableOwnerList!= ''">
-            AND table_owner in
-            <foreach item="tableOwnerList" collection="tableOwnerList" open="(" close=")" separator=",">
-                #{tableOwnerList}
-            </foreach>
-        </if>
+            /*试验所属方=7*/
+            AND table_owner = 7
         /*解决不同合同段中复制表问题*/
         <if test="contractId == null">
             -- 后管加载原始表
@@ -745,6 +744,24 @@
         select * from m_table_info
     </select>
 
+    <select id="treeRecordTrial" resultType="org.springblade.manager.vo.WbsTreePrivateVO5">
+        select  id, parent_id,
+                node_name as title,
+                node_type AS "nodeType",
+                wbs_type as "wbsType"
+        from m_wbs_tree_private
+        where
+        is_deleted = 0
+        and status = 1
+        and `type` = 1
+        and project_id = #{projectId}
+        and wbs_id = #{wbsId}
+        <if test="wbsType != null and wbsType != ''">
+            and wbs_type = #{wbsType}
+        </if>
+        ORDER BY sort
+    </select>
+
     <delete id="delTabProjectById">
         delete from m_wbs_tree_private WHERE p_key_id = #{pKeyId} and project_id=#{projectId}AND type = 10
     </delete>

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

@@ -90,4 +90,6 @@ public interface IArchiveTreeContractService extends BaseService<ArchiveTreeCont
 
 	void  fillDefaultArchiveAutoInfo(List<ArchiveTreeContractVO2> tree,Long projectId);
 
+	void  fillDefaultArchiveAutoInfo(List<ArchiveTreeContract> archiveTreeContracts);
+
 }

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

@@ -139,12 +139,12 @@ public interface IExcelTabService extends BaseService<ExcelTab> {
     /**
      * 单PDF 生成 - 试验
      */
-    String getBussPDFTrial(Long pKeyId, String contractId, Long id, int pageNumber, int pageNumberCount) throws Exception;
+    String getBussPDFTrial(Long pKeyId, String contractId, Long id, int pageNumber, int pageNumberCount, TrialSelfInspectionRecordDTO dto) throws Exception;
 
     /**
      * 多PDF 合并 - 试验
      */
-    String getBussPDFSTrial(String nodeId, String tableType, String classify, String contractId, String projectId, Long id, String tabIds) throws Exception;
+    String getBussPDFSTrial(String nodeId, String tableType, String classify, String contractId, String projectId, Long id, String tabIds, TrialSelfInspectionRecordDTO dto) throws Exception;
 
     /**
      * 保存 首件数据

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

@@ -12,10 +12,12 @@ import org.springblade.manager.vo.*;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.util.List;
+import java.util.Map;
 
 public interface IWbsTreePrivateService extends BaseService<WbsTreePrivate> {
 
     List<WbsTreePrivateVO> tree(String wbsId, String projectId);
+
     List<WbsTreeVO2> tree2(String wbsId, String projectId);
 
     boolean submit(WbsTreePrivate wbsTreePrivate);
@@ -84,4 +86,6 @@ public interface IWbsTreePrivateService extends BaseService<WbsTreePrivate> {
 
     List<WbsTreePrivateVO> getMixRatioTestTree(String pKeyId);
 
+    Map<String, List<Object>> treeRecordTrial(String wbsId, String projectId, String pKeyId);
+
 }

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

@@ -233,7 +233,7 @@ public class ArTreeContractInitServiceImpl {
      *
      * @param archiveTreeContracts
      */
-    public void InitTreeSort(List<ArchiveTreeContract> archiveTreeContracts) {
+    public void InitTreeSort(List<ArchiveTreeContract> archiveTreeContracts,List<ArchiveTreeVO2> proVo2Trees) {
         List<ArchiveTreeContractVO2> archiveTreeContractVO2List = new ArrayList<>();
 
         Map<Long,ArchiveTreeContractVO2> vo2Map = new LinkedHashMap<>();
@@ -245,7 +245,7 @@ public class ArTreeContractInitServiceImpl {
 
         InitTreeSort(trees.get(0), "");
 
-        archiveAutoRuleSync.syncArchiveTreeContractList(vo2Map);
+        archiveAutoRuleSync.syncArchiveTreeContractList(vo2Map,proVo2Trees);
 
         List<ArchiveTreeContract> upList = new ArrayList<>();
 
@@ -629,6 +629,11 @@ public class ArTreeContractInitServiceImpl {
      */
     public void getMap(List<ArchiveTreeContractVO2> vos,List<ArchiveTreeContract> addList,Map<Long,ArchiveTreeContractVO2> vo2Map){
 
+        if(vo2Map==null){
+            vo2Map=new HashMap<>();
+        }
+
+
         for (ArchiveTreeContractVO2 ar:vos) {
             vo2Map.put(ar.getId(),ar);
         }

+ 268 - 10
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ArchiveAutoRuleSyncImpl.java

@@ -22,7 +22,7 @@ public class ArchiveAutoRuleSyncImpl {
 
     }
 
-    public void syncArchiveTreeList(Map<Long,ArchiveTreeVO2> vo2Map){
+    public void syncArchiveTreeList(Map<Long,ArchiveTreeVO2> vo2Map,List<ArchiveTreeVO2> sysVo2Trees){
 
         List<ArchiveTreeVO2> normalList = new ArrayList<>();
         List<ArchiveTreeVO2> wbsList = new ArrayList<>();
@@ -32,19 +32,19 @@ public class ArchiveAutoRuleSyncImpl {
         }
 
 
-        ForestNodeMergerEx.setPropertyfromId(normalList,syncPropertyMap);
-
-
+        /*ForestNodeMergerEx.setPropertyfromId(normalList,syncPropertyMap);
         for (ArchiveTreeVO2 archiveTreeVO2 : vo2Map.values()) {
             if (archiveTreeVO2.getArchiveAutoNodeId() != null) {
                 archiveTreeVO2.setFlag(1);
             }
-        }
-        //todo group type
+        }*/
+
+        //组卷规则同步
+        syncRuleSysToProject(vo2Map,sysVo2Trees);
 
     }
 
-    public void syncArchiveTreeContractList(Map<Long,ArchiveTreeContractVO2> vo2Map){
+    public void syncArchiveTreeContractList(Map<Long,ArchiveTreeContractVO2> vo2Map,List<ArchiveTreeVO2> proVo2Trees){
 
         List<ArchiveTreeContractVO2> normalList = new ArrayList<>();
         List<ArchiveTreeContractVO2> wbsList = new ArrayList<>();
@@ -60,7 +60,7 @@ public class ArchiveAutoRuleSyncImpl {
         }
 
         //根据formId
-        ForestNodeMergerEx.setPropertyfromId(normalList,syncPropertyMap);
+        //ForestNodeMergerEx.setPropertyfromId(normalList,syncPropertyMap);
 
         //todo,这里补充上获取对应的wbsid
         List<Long> wbsIds = new ArrayList<>();
@@ -95,12 +95,270 @@ public class ArchiveAutoRuleSyncImpl {
         }
 
         //设置修改标识
-        for (ArchiveTreeContractVO2 archiveTreeContractVO2 : vo2Map.values()) {
+       /* for (ArchiveTreeContractVO2 archiveTreeContractVO2 : vo2Map.values()) {
             if (archiveTreeContractVO2.getArchiveAutoNodeId() != null) {
                 archiveTreeContractVO2.setFlag(1);
             }
+        }*/
+        //组卷规则同步
+        syncRuleProToContract(vo2Map,proVo2Trees);
+    }
+
+    /**
+     *
+     * @param vo2Map 项目级节点集合
+     * @param sysVo2Trees  系统级节点集合
+     */
+    private void syncRuleSysToProject(Map<Long,ArchiveTreeVO2> vo2Map,List<ArchiveTreeVO2> sysVo2Trees){
+        //同步规则
+        // archiveAutoType  与系统级一致  不用处理
+        // archiveAutoNodeId   需替换成对应项目级节点id
+        // archiveAutoGroupId     与系统级一致 不用处理
+        // archiveAutoGroupSelect  与系统级一致 不用处理
+        //系统初始化项目 vo2Map.values()里的规则字段值都是系统级的值
+        //初始化后项目级再次同步  vo2Map.values()里的规则字段值新加的是系统级的值,原来的是项目级的值
+
+        //准备系统级节点map
+        Map<Long,ArchiveTreeVO2> sysMap = new HashMap<>();
+        List<ArchiveTreeVO2> sysVo2TreeList = new ArrayList<>();
+        if(sysVo2Trees.size()==1){
+            ForestNodeMergerEx.getTreeList(sysVo2Trees.get(0),sysVo2TreeList);
+        }else{
+            sysVo2TreeList=sysVo2Trees;
+        }
+
+        for(ArchiveTreeVO2 sysVo2:sysVo2TreeList){
+            sysMap.put(sysVo2.getId(),sysVo2);
+        }
+        //准备在页面勾选设置的系统级节点ID_项目级节点Map   用于映射archiveAutoNodeId同步
+        Map<Long,List<ArchiveTreeVO2>> sysIdToPro_Map = new HashMap<>();
+        for(ArchiveTreeVO2 proVO2 : vo2Map.values()){
+            //只提取设置的节点,也就是select=1的节点
+            if(proVO2.getArchiveAutoGroupSelect()!=null && proVO2.getArchiveAutoGroupSelect()==1){
+                Long fromId = proVO2.getFromId();
+                if(sysIdToPro_Map.containsKey(fromId)){
+                    List<ArchiveTreeVO2> archiveTreeVO2s = sysIdToPro_Map.get(fromId);
+                    archiveTreeVO2s.add(proVO2);
+                    sysIdToPro_Map.put(fromId,archiveTreeVO2s);
+                }else{
+                    List<ArchiveTreeVO2> archiveTreeVO2s = new ArrayList<>();
+                    archiveTreeVO2s.add(proVO2);
+                    sysIdToPro_Map.put(fromId,archiveTreeVO2s);
+                }
+            }
+        }
+        //同步规则设置
+        for (ArchiveTreeVO2 archiveTreeVO2: vo2Map.values()) {
+            Integer archiveAutoType = archiveTreeVO2.getArchiveAutoType();
+            //过滤没有任何规则的节点
+            if(archiveAutoType!=null){
+                //步骤一:处理archiveAutoNodeId同步
+                Long archiveAutoNodeId = archiveTreeVO2.getArchiveAutoNodeId();
+                if(archiveAutoNodeId!=null){
+                    //判断规则值是系统级的还是项目级的
+                    if(sysMap.containsKey(archiveAutoNodeId)){
+                        //这个节点是刚从系统级同步过来,规则值还是系统级的。而这个archiveAutoNodeId是系统级设置的最高并卷节点的ID
+                        //用archiveAutoNodeId通过sysIdToPro_Map找出对应的项目级节点
+                        List<ArchiveTreeVO2> pro_select_vo2s = sysIdToPro_Map.get(archiveAutoNodeId);
+                        if(pro_select_vo2s.size()==1){
+                            //一个系统级节点对应了一个项目级节点
+                            Long pro_archiveAutoNodeId = pro_select_vo2s.get(0).getId();
+                            archiveTreeVO2.setArchiveAutoNodeId(pro_archiveAutoNodeId);//设置项目级的archiveAutoNodeId
+                            archiveTreeVO2.setFlag(1);
+                        }else{
+                            //一个系统级节点对应了多个项目级节点(项目级添加加节点的情况)
+                            for(ArchiveTreeVO2 pro_select_vo2:pro_select_vo2s){
+                                //系统级对应多个节点时,用当前节点的ancestors去对比pro_select_vo2中的id,当前节点的ancestors必有上级节点的id。或当前节点id=pro_select_vo2中的id
+                                String ancestorsPid = pro_select_vo2.getId().toString();
+                                String ancestors = archiveTreeVO2.getAncestors();
+                                Long pro_id = archiveTreeVO2.getId();
+
+                                if(ancestors.contains(ancestorsPid) ||  pro_id.equals(ancestorsPid)){
+                                    archiveTreeVO2.setArchiveAutoNodeId(pro_select_vo2.getId());//设置项目级的archiveAutoNodeId
+                                    archiveTreeVO2.setFlag(1);
+                                    break;
+                                }
+                            }
+                        }
+                    }else{
+                        //TODO 这个节点是已经初始化出来的节点,规则值是项目级的   已经是项目级好像不用处理了
+                        //Long fromId = archiveTreeVO2.getFromId();
+                        //ArchiveTreeVO2 sys_vo2 = sysMap.get(fromId);
+                        //ArchiveTreeVO2 sys_select_vo2 = sysMap.get(sys_vo2.getArchiveAutoNodeId());
+                    }
+                }
+            }
+
+
+            //archiveAutoType  与系统级一致  不用处理
+            //archiveAutoGroupSelect  与系统级一致 不用处理
+            //archiveAutoGroupId 与系统级一致 不用处理
+        }
+    }
+
+
+    /**
+     * 项目级同步客户级 组卷规则处理
+     * @param vo2Map  客户级节点集合
+     * @param proVo2Trees  项目级节点集合
+     */
+    private void syncRuleProToContract(Map<Long,ArchiveTreeContractVO2> vo2Map,List<ArchiveTreeVO2> proVo2Trees){
+        //同步规则
+        // archiveAutoType  与系统级一致  不用处理
+        // archiveAutoNodeId   需替换成对应项目级节点id
+        // archiveAutoGroupId     项目级同组的在 客户级有合同段的要按合同段分开
+        // archiveAutoGroupSelect  与系统级一致 不用处理
+        //系统初始化客户级 vo2Map.values()里的规则字段值都是项目级的值
+        //初始化后客户级再次同步  vo2Map.values()里的规则字段值新加的是项目的值,原来的是客户级的值
+
+
+        //准备项目级节点map
+        Map<Long,ArchiveTreeVO2> proMap = new HashMap<>();
+        List<ArchiveTreeVO2> proVo2TreeList = new ArrayList<>();
+        if(proVo2Trees.size()==1){
+            ForestNodeMergerEx.getTreeList(proVo2Trees.get(0),proVo2TreeList);
+        }else{
+            proVo2TreeList=proVo2Trees;
+        }
+
+        for(ArchiveTreeVO2 proVo2:proVo2TreeList){
+            proMap.put(proVo2.getId(),proVo2);
+        }
+        //准备在页面勾选设置的项目级节点ID_客户级节点Map   用于映射archiveAutoNodeId同步
+        Map<Long,List<ArchiveTreeContractVO2>> proIdToContact_Map = new HashMap<>();
+        for(ArchiveTreeContractVO2 contractVO2 : vo2Map.values()){
+            //只提取设置的节点,也就是select=1的节点
+            if(contractVO2.getArchiveAutoGroupSelect()!=null && contractVO2.getArchiveAutoGroupSelect()==1){
+                Long fromId = contractVO2.getFromId();
+                if(proIdToContact_Map.containsKey(fromId)){
+                    List<ArchiveTreeContractVO2> contractTreeVO2s = proIdToContact_Map.get(fromId);
+                    contractTreeVO2s.add(contractVO2);
+                    proIdToContact_Map.put(fromId,contractTreeVO2s);
+                }else{
+                    List<ArchiveTreeContractVO2> archiveTreeVO2s = new ArrayList<>();
+                    archiveTreeVO2s.add(contractVO2);
+                    proIdToContact_Map.put(fromId,archiveTreeVO2s);
+                }
+            }
+        }
+
+        //构建 合同段ID_项目级groupID,客户级groupID> 集合   用于映射archiveAutoGroupId同步
+        Map<String,Long> groupMap = new HashMap<>();
+        for(ArchiveTreeContractVO2 contractVO2 : vo2Map.values()){
+            Integer archiveAutoType = contractVO2.getArchiveAutoType();
+            Long fromId = contractVO2.getFromId();
+            //只处理普通节点,规则时分类并卷类型的
+            if (contractVO2.getExtType()== null && fromId!=null && archiveAutoType!=null && archiveAutoType==2){
+                Long contract_groupId = contractVO2.getArchiveAutoGroupId();
+                //如果当前contractVO2的groupID是客户级(19位数),需要先保存关联集合
+                if(contract_groupId.toString().length()==19){
+                    //1.通过fromid找出项目级
+                    ArchiveTreeVO2 proTreeVO2 = proMap.get(fromId);
+                    //2.获取项目级groupID
+                    Long pro_groupId = proTreeVO2.getArchiveAutoGroupId();
+                    //3.,那么保存到集合  合同段ID_项目级groupID,客户级groupID
+                    Long contractId = contractVO2.getContractId();
+                    if(contractId!=null){
+                        String key =contractId+"_"+pro_groupId;
+                        if(!groupMap.containsKey(key)){
+                            groupMap.put(key,contract_groupId);
+                        }
+                    }else{
+                        String key = pro_groupId.toString();
+                        if(!groupMap.containsKey(key)){
+                            groupMap.put(key,contract_groupId);
+                        }
+                    }
+                }
+            }
         }
-        //todo group type
 
+        //同步规则设置
+        for (ArchiveTreeContractVO2 contractVO2: vo2Map.values()) {
+
+            //只处理普通节点,wbs节点待客户级同步入库后,再根据项目级保存规则来设置
+            if (contractVO2.getExtType()== null){
+                Integer archiveAutoType = contractVO2.getArchiveAutoType();
+                //过滤没有任何规则的节点
+
+                if(archiveAutoType!=null){
+                    //步骤一:处理archiveAutoNodeId同步
+                    Long archiveAutoNodeId = contractVO2.getArchiveAutoNodeId();
+                    if(archiveAutoNodeId!=null){
+                        //判断规则值是项目级的还是客户级的
+                        if(proMap.containsKey(archiveAutoNodeId)){
+                            //这个节点是刚从项目级同步过来,规则值还是项目级的。而这个archiveAutoNodeId是项目级设置的最高并卷节点的ID
+                            //用archiveAutoNodeId通过proIdToContact_Map找出对应的客户级节点
+                            List<ArchiveTreeContractVO2> contract_select_vo2s = proIdToContact_Map.get(archiveAutoNodeId);
+                            if(contract_select_vo2s.size()==1){
+                                //一个系统级节点对应了一个项目级节点
+                                Long pro_archiveAutoNodeId = contract_select_vo2s.get(0).getId();
+                                contractVO2.setArchiveAutoNodeId(pro_archiveAutoNodeId);//设置项目级的archiveAutoNodeId
+                                contractVO2.setFlag(1);
+                            }else{
+                                //一个系统级节点对应了多个项目级节点(项目级添加加节点的情况)
+                                for(ArchiveTreeContractVO2 contract_select_vo2:contract_select_vo2s){
+                                    //系统级对应多个节点时,用当前节点的ancestors去对比pro_select_vo2中的id,当前节点的ancestors必有上级节点的id。或当前节点id=pro_select_vo2中的id
+                                    Long contract_select_id = contract_select_vo2.getId();//客户级的最高并卷节点id
+                                    String ancestors = contractVO2.getAncestors();//当前节点ancestors
+                                    Long contractVO2_id = contractVO2.getId();//当前节点id
+
+                                    if(ancestors.contains(contract_select_id.toString()) ||  contractVO2_id.equals(contract_select_id)){
+                                        contractVO2.setArchiveAutoNodeId(contract_select_vo2.getId());//设置客户级的archiveAutoNodeId
+                                        contractVO2.setFlag(1);
+                                        break;
+                                    }
+                                }
+                            }
+                        }else{
+                            //TODO 这个节点是已经初始化出来的节点,规则值是项目级的   已经是项目级好像不用处理了
+                            //Long fromId = archiveTreeVO2.getFromId();
+                            //ArchiveTreeVO2 sys_vo2 = sysMap.get(fromId);
+                            //ArchiveTreeVO2 sys_select_vo2 = sysMap.get(sys_vo2.getArchiveAutoNodeId());
+                        }
+                    }
+
+                    //步骤二:处理archiveAutoGroupId同步
+                    if(archiveAutoType==2){
+                        Long contractId = contractVO2.getContractId();
+                        //分合同段的 给archiveAutoGroupId
+                        Long groupId = contractVO2.getArchiveAutoGroupId();
+                        //客户级的groupID用19位数字  系统级和项目级用16位数字
+                        if(groupId.toString().length()==16){
+                            String key ="";
+                            if(contractId==null) {
+                                key =groupId+"";
+                            }else {
+                                key =contractId+"_"+groupId;
+                            }
+
+                            if(groupMap.containsKey(key)){
+                                Long contractGroupId = groupMap.get(key);
+                                contractVO2.setArchiveAutoGroupId(contractGroupId);
+                                contractVO2.setFlag(1);
+                            }else{
+                                //客户级的group用19位,在同步的时候方便判断是值是客户级还是项目级
+                                double v = Math.random();
+                                if(v<0.1){
+                                    v=v+0.1;
+                                }
+                                v=v*1000000;
+                                long ran = (long)v;
+                                Long contractGroupId=Long.parseLong(System.currentTimeMillis()+""+ran);
+                                groupMap.put(key,contractGroupId);
+                                contractVO2.setArchiveAutoGroupId(contractGroupId);
+                                contractVO2.setFlag(1);
+                            }
+                        }else {
+                            //已经是客户级了不用理
+                        }
+                    }
+                }
+            }
+            //archiveAutoType  与项目级一致  不用处理
+            //archiveAutoGroupSelect  与项目级一致 不用处理
+        }
     }
+
+
 }

+ 54 - 3
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ArchiveTreeContractServiceImpl.java

@@ -147,7 +147,7 @@ public class ArchiveTreeContractServiceImpl extends BaseServiceImpl<ArchiveTreeC
 		archiveTreeContracts.addAll(addNodes);
 
 		//初始化祖先节点和排序
-		arTreeContractInitService.InitTreeSort(archiveTreeContracts);
+		arTreeContractInitService.InitTreeSort(archiveTreeContracts,tree);
 		//todo 同步质检资料动态节点,处理文件提名
 
 		//todo 同步立卷规则
@@ -450,9 +450,10 @@ public class ArchiveTreeContractServiceImpl extends BaseServiceImpl<ArchiveTreeC
 		}
 
 		//更新排序,把排序,自动组卷这种变化,刷新到新增节点和修改节点上
-		archiveTreeContractSync.InitTreeSort(dstTree,saveContractList,upList);
-
+		//archiveTreeContractSync.InitTreeSort(dstTree,saveContractList,upList,srcTrees);
 		saveList.addAll(saveContractList);
+		archiveTreeContractSync.InitTreeSort(dstTree,saveContractList,upList,srcTrees,saveList);
+
 		//同步生成案卷
 		arTreeContractInitService.syncArchiveAutoList(saveList,contractInfos);
 
@@ -777,6 +778,7 @@ public class ArchiveTreeContractServiceImpl extends BaseServiceImpl<ArchiveTreeC
 
 	}
 
+
 	/**
 	 *
 	 * @param node
@@ -805,6 +807,55 @@ public class ArchiveTreeContractServiceImpl extends BaseServiceImpl<ArchiveTreeC
 		}
 	}
 
+	/**
+	 * 填充基本信息
+	 * @param archiveTreeContracts
+	 */
+	public  void  fillDefaultArchiveAutoInfo(List<ArchiveTreeContract> archiveTreeContracts){
+		Long projectId = archiveTreeContracts.get(0).getProjectId();
+		List<ContractInfo> contractInfos = contractInfoService.selectContractInfoPageByPid(projectId.toString());
+		if (contractInfos == null || contractInfos.size() == 0) {
+			return;
+		}
+		Map<Long,ContractInfo> contractMap = new LinkedHashMap<>();
+		for (ContractInfo contractInfo: contractInfos) {
+			if (contractInfo.getContractType() == 3) {
+				contractMap.put(0L,contractInfo);
+			}
+			contractMap.put(contractInfo.getId(),contractInfo);
+		}
+
+		for (ArchiveTreeContract node: archiveTreeContracts) {
+			Long contractId = 0L;
+			if (node.getContractId() != null ) {
+				contractId = node.getContractId();
+			}
+			ContractInfo contractInfo = contractMap.get(contractId);
+			if (contractInfo != null) {
+				if (StringUtils.isEmpty(node.getFileNumberPrefix())) {
+					node.setFileNumberPrefix(contractInfo.getPrefix());
+				}
+				if (StringUtils.isEmpty(node.getStorageTime()) && contractInfo.getStoragePeriod() != null) {
+					node.setStorageTime(contractInfo.getStoragePeriod().toString());
+				}
+				if (StringUtils.isEmpty(node.getRollor())) {
+					node.setRollor(contractInfo.getFiler());
+				}
+				if (StringUtils.isEmpty(node.getReviewer())) {
+					node.setReviewer(contractInfo.getReviewer());
+				}
+				if (StringUtils.isEmpty(node.getSpecification())) {
+					//默认30mm ,对应枚举 1
+					node.setSpecification("1");
+				}
+				//没有默认
+				if (StringUtils.isEmpty(node.getArchiveNameSuffix())) {
+					//node.setArchiveNameSuffix(contractInfo.getPrefix());
+				}
+			}
+		}
+	}
+
 
 
 

+ 6 - 3
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ArchiveTreeContractSyncImpl.java

@@ -90,8 +90,10 @@ public class ArchiveTreeContractSyncImpl {
         ForestNodeMergerEx.getTreeList(dstTree, contractVO2List);
 
         //获取所有节点的id -> ArchiveTreeContractVO2 的map
+
         arTreeContractInitService.getMap(contractVO2List,addList,vo2Map);
 
+
         List<ArchiveTreeContractVO2> trees = ForestNodeMergerEx.merge(contractVO2List);
         return trees.get(0);
     }
@@ -102,7 +104,8 @@ public class ArchiveTreeContractSyncImpl {
      * @param dstTree
      * @param addList
      */
-    public void InitTreeSort(ArchiveTreeContractVO2  dstTree,List<ArchiveTreeContract> addList,List<ArchiveTreeContract> upList)
+    public void InitTreeSort(ArchiveTreeContractVO2  dstTree,List<ArchiveTreeContract> addList,
+                             List<ArchiveTreeContract> upList,List<ArchiveTreeVO2> proVo2Trees,List<ArchiveTreeContract> allAddList)
     {
         Map<Long,ArchiveTreeContractVO2> vo2Map = new LinkedHashMap<>();
 
@@ -115,10 +118,10 @@ public class ArchiveTreeContractSyncImpl {
         ForestNodeMergerEx.InitTreeSort(tree, "");
 
         //更新自动组卷节点
-        archiveAutoRuleSync.syncArchiveTreeContractList(vo2Map);
+        archiveAutoRuleSync.syncArchiveTreeContractList(vo2Map,proVo2Trees);
 
         //根据vo的排序和自动组卷信息,刷新新增节点,根据修改标识生成更新节点
-        arTreeContractInitService.handleAddAndUpList(vo2Map,addList,upList);
+        arTreeContractInitService.handleAddAndUpList(vo2Map,allAddList,upList);
 
     }
 

+ 33 - 12
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ArchiveTreeServiceImpl.java

@@ -98,9 +98,20 @@ public class ArchiveTreeServiceImpl extends BaseServiceImpl<ArchiveTreeMapper, A
 
         Map<Long,ArchiveTree> archiveMap = new LinkedHashMap<>();
 
+        List<ArchiveTreeVO2> sysVo2Trees = new ArrayList<>();//用于规则同步
+
         for (ArchiveTree archiveTree :sysTrees) {
             oldNewMap.put(archiveTree.getId(), SnowFlakeUtil.getId());
             archiveMap.put(archiveTree.getId(), archiveTree);
+
+            //用于规则同步 ArchiveTree转换成ArchiveTreeVO2
+            ArchiveTreeVO2  vo2 = new ArchiveTreeVO2();
+            vo2.setId(archiveTree.getId());
+            vo2.setArchiveAutoType(archiveTree.getArchiveAutoType());
+            vo2.setArchiveAutoNodeId(archiveTree.getArchiveAutoNodeId());
+            vo2.setArchiveAutoGroupId(archiveTree.getArchiveAutoGroupId());
+            vo2.setArchiveAutoGroupSelect(archiveTree.getArchiveAutoGroupSelect());
+            sysVo2Trees.add(vo2);
         }
         oldNewMap.put(0L,0L);
 
@@ -138,7 +149,7 @@ public class ArchiveTreeServiceImpl extends BaseServiceImpl<ArchiveTreeMapper, A
         }
 
         //todo 同步立卷规则
-        InitAncestors(archiveTrees);
+        InitAncestors(archiveTrees,sysVo2Trees);
 
         this.saveBatch(archiveTrees);
 
@@ -444,7 +455,11 @@ public class ArchiveTreeServiceImpl extends BaseServiceImpl<ArchiveTreeMapper, A
             Long archiveAutoGroupId=null;
             //分类并卷规则的需要生成个随机数,作为同一个分类赋值archiveAutoNodeId
             if(archiveAutoType==2){
-                double v = Math.random() * 10000;
+                double v = Math.random();
+                if(v<0.1){
+                    v=v+0.1;
+                }
+                v=v*1000;
                 long ran = (long)v;
                 archiveAutoGroupId=Long.parseLong(System.currentTimeMillis()+""+ran);
             }
@@ -454,6 +469,7 @@ public class ArchiveTreeServiceImpl extends BaseServiceImpl<ArchiveTreeMapper, A
                 long nodeIdLong = Long.parseLong(nodeId);
                 ArchiveTree archiveTree = baseMapper.selectById(nodeIdLong);
                 archiveTree.setArchiveAutoType(archiveAutoType);
+                archiveTree.setArchiveAutoGroupSelect(1);
                 if(archiveAutoType==1){
                     //最高并卷规则 选择节点的ID
                     archiveTree.setArchiveAutoNodeId(nodeIdLong);
@@ -461,7 +477,6 @@ public class ArchiveTreeServiceImpl extends BaseServiceImpl<ArchiveTreeMapper, A
                 if(archiveAutoType==2){
                     //分类并卷规则 提交都是一个分类类型
                     archiveTree.setArchiveAutoGroupId(archiveAutoGroupId);
-                    archiveTree.setArchiveAutoGroupSelect(1);
                 }
                 baseMapper.updateById(archiveTree);
 
@@ -493,7 +508,11 @@ public class ArchiveTreeServiceImpl extends BaseServiceImpl<ArchiveTreeMapper, A
             Long archiveAutoGroupId=null;
             //分类并卷规则的需要生成个随机数,作为同一个分类赋值archiveAutoNodeId
             if(archiveAutoType==2){
-                double v = Math.random() * 10000;
+                double v = Math.random();
+                if(v<0.1){
+                    v=v+0.1;
+                }
+                v=v*1000;
                 long ran = (long)v;
                 archiveAutoGroupId=Long.parseLong(System.currentTimeMillis()+""+ran);
             }
@@ -544,7 +563,7 @@ public class ArchiveTreeServiceImpl extends BaseServiceImpl<ArchiveTreeMapper, A
                     Long groupId = dto.getArchiveAutoGroupId();
                     String selectNodeIds = dto.getSelectNodeIds();
                     List<String> selectNodeIdlist = Arrays.asList(selectNodeIds.split(","));
-                    //先将同一分组的节点删除配置,。
+                    //先将同一分组的节点删除配置
                     baseMapper.removeNodeForArchiveAutoRule_Group(groupId);
                     //然后再按照选择节点保存新的设置
                     for(String nodeId:selectNodeIdlist){
@@ -672,7 +691,7 @@ public class ArchiveTreeServiceImpl extends BaseServiceImpl<ArchiveTreeMapper, A
         if(iswbsNode){
             return getArchiveAutoRule_WbsTreeNode(id,projectId,wbsNode2ArchiveTreeNodeId,wbsId);
         }else{
-            return getArchiveAutoRule_ArchiveTreeNode(id);
+            return getArchiveAutoRule_ArchiveTreeNode(id,projectId);
         }
     }
 
@@ -681,7 +700,7 @@ public class ArchiveTreeServiceImpl extends BaseServiceImpl<ArchiveTreeMapper, A
      * @param id
      * @return
      */
-    private Map<String,Object> getArchiveAutoRule_ArchiveTreeNode(Long id) {
+    private Map<String,Object> getArchiveAutoRule_ArchiveTreeNode(Long id,Long projectId) {
         Map<String,Object> map= new HashMap<>();
         try{
             ArchiveTree archiveTree = baseMapper.selectById(id);
@@ -724,6 +743,7 @@ public class ArchiveTreeServiceImpl extends BaseServiceImpl<ArchiveTreeMapper, A
                     List<ArchiveTree> listGroup= baseMapper.selectList(Wrappers.<ArchiveTree>lambdaQuery()
                             .eq(ArchiveTree::getArchiveAutoGroupId, archiveTree.getArchiveAutoGroupId())
                             .eq(ArchiveTree::getArchiveAutoGroupSelect,1)
+                            .eq(ArchiveTree::getProjectId,projectId)
                             .orderByAsc(ArchiveTree::getSort));
                     StringBuffer nodeSelect = new StringBuffer();
 
@@ -962,7 +982,7 @@ public class ArchiveTreeServiceImpl extends BaseServiceImpl<ArchiveTreeMapper, A
         modifyBySrcTree(srcTree,dstTree);
 
         //刷新treeCode
-        InitAncestors(dstTree,saveList,upList);
+        InitAncestors(dstTree,saveList,upList,srcTrees);
 
         //相同的属性刷新?
         //updateDstArchiveTrees(srcTree,dstTree);
@@ -973,7 +993,7 @@ public class ArchiveTreeServiceImpl extends BaseServiceImpl<ArchiveTreeMapper, A
     }
 
 
-    public void InitAncestors(ArchiveTreeVO2  dstTree,List<ArchiveTree> addList,List<ArchiveTree> upList)
+    public void InitAncestors(ArchiveTreeVO2  dstTree,List<ArchiveTree> addList,List<ArchiveTree> upList,List<ArchiveTreeVO2> sysTrees)
     {
         Map<Long,ArchiveTreeVO2> vo2Map = new LinkedHashMap<>();
 
@@ -984,13 +1004,13 @@ public class ArchiveTreeServiceImpl extends BaseServiceImpl<ArchiveTreeMapper, A
         ForestNodeMergerEx.InitAncestors(tree,"0");
 
         //更新自动组卷节点
-        archiveAutoRuleSync.syncArchiveTreeList(vo2Map);
+        archiveAutoRuleSync.syncArchiveTreeList(vo2Map,sysTrees);
 
         //根据vo的排序和自动组卷信息,刷新新增节点,根据修改标识生成更新节点
         this.handleAddAndUpList(vo2Map,addList,upList);
     }
 
-    public void InitAncestors(List<ArchiveTree> archiveTrees) {
+    public void InitAncestors(List<ArchiveTree> archiveTrees,List<ArchiveTreeVO2> sysVo2Trees) {
         List<ArchiveTreeVO2> archiveTreeVO2List = new ArrayList<>();
 
         Map<Long,ArchiveTreeVO2> vo2Map = new LinkedHashMap<>();
@@ -1001,7 +1021,7 @@ public class ArchiveTreeServiceImpl extends BaseServiceImpl<ArchiveTreeMapper, A
         //重复
         //ForestNodeMergerEx.InitAncestors(trees.get(0),"0");
 
-        archiveAutoRuleSync.syncArchiveTreeList(vo2Map);
+        archiveAutoRuleSync.syncArchiveTreeList(vo2Map,sysVo2Trees);
 
         List<ArchiveTree> upList = new ArrayList<>();
 
@@ -1130,6 +1150,7 @@ public class ArchiveTreeServiceImpl extends BaseServiceImpl<ArchiveTreeMapper, A
             treeContractVO2.setArchiveAutoType(archiveTree.getArchiveAutoType());
             treeContractVO2.setArchiveAutoGroupId(archiveTree.getArchiveAutoGroupId());
             treeContractVO2.setArchiveAutoGroupSelect(archiveTree.getArchiveAutoGroupSelect());
+            treeContractVO2.setAncestors(archiveTree.getAncestors());
             vos.add(treeContractVO2);
             vo2Map.put(treeContractVO2.getId(),treeContractVO2);
         }

+ 84 - 46
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ExcelTabServiceImpl.java

@@ -1,24 +1,7 @@
-/*
- *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *
- *  Redistributions of source code must retain the above copyright notice,
- *  this list of conditions and the following disclaimer.
- *  Redistributions in binary form must reproduce the above copyright
- *  notice, this list of conditions and the following disclaimer in the
- *  documentation and/or other materials provided with the distribution.
- *  Neither the name of the dreamlu.net developer nor the names of its
- *  contributors may be used to endorse or promote products derived from
- *  this software without specific prior written permission.
- *  Author: Chill 庄骞 (smallchill@163.com)
- */
 package org.springblade.manager.service.impl;
 
 import cn.hutool.core.date.StopWatch;
 import cn.hutool.log.StaticLog;
-import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
@@ -43,6 +26,7 @@ import org.jsoup.Jsoup;
 import org.jsoup.nodes.Document;
 import org.jsoup.nodes.Element;
 import org.jsoup.select.Elements;
+import org.springblade.business.dto.TrialSelfInspectionRecordDTO;
 import org.springblade.business.entity.InformationQuery;
 import org.springblade.business.entity.TrialSelfInspectionRecord;
 import org.springblade.business.feign.ContractLogClient;
@@ -84,6 +68,7 @@ import org.springframework.transaction.support.DefaultTransactionDefinition;
 
 import java.io.*;
 import java.net.URL;
+import java.nio.charset.StandardCharsets;
 import java.text.SimpleDateFormat;
 import java.util.List;
 import java.util.*;
@@ -320,7 +305,9 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                         dataMap2.put(k, lastStr);
                     } else {
                         String dataVal = dataInfo2.getString(dataMap.get(k).get(0));
-                        dataMap2.put(k, dataVal + "_^_" + dataMap.get(k).get(0).split("__")[1]);
+                        if (StringUtils.isNotEmpty(dataVal)) {
+                            dataMap2.put(k, dataVal + "_^_" + dataMap.get(k).get(0).split("__")[1]);
+                        }
                     }
                 }
                 dataMap2.put("p_key_id", tableInfo.getPkeyId());
@@ -363,7 +350,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                     tec.before();
                     this.formulaService.execute(tec);
                     tec.after();
-                }else{
+                } else {
                     tec.getLog().append("【").append("没有执行任何公式").append("】");
                 }
                 stopWatch.stop();
@@ -376,7 +363,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                             "INSERT INTO m_formula_log (id,content) VALUES (" + wtc.getPKeyId() + ", '" + log + "')"
                     };
                     this.jdbcTemplate.batchUpdate(sql);
-                }catch (Exception e){
+                } catch (Exception e) {
                     e.printStackTrace();
                 }
             }
@@ -530,28 +517,41 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
             try {
                 //获取onlyOffice缓存中的文件流
                 URL url = new URL(downloadUri);
+                String file_path = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
+                String filecode = SnowFlakeUtil.getId() + "";
+                String dataUrl=file_path + "/excel/" + filecode + ".pdf";
                 java.net.HttpURLConnection connection = (java.net.HttpURLConnection) url.openConnection();
+                connection.setRequestMethod("GET");
+                connection.setConnectTimeout(5 * 1000);
                 InputStream inputStream = connection.getInputStream();
                 if (inputStream == null) {
                     throw new Exception("文件为空");
                 }
-                Long tabId = callback.getKey();
+                String tabId = callback.getKey();
                 if (tabId == null) {
                     throw new Exception("excel为空");
+                }else{
+                    tabId = tabId.substring(0,tabId.lastIndexOf("_"));
                 }
                 //获取数据库信息
-                ExcelTab excelTab = baseMapper.selectById(tabId);
+                ExcelTab excelTab = baseMapper.selectById(Long.parseLong(tabId));
                 //上传新文件到文件服务器
                 byte[] officeByte = IoUtil.readToByteArray(inputStream);
-                BladeFile bladeFile = this.newIOSSClient.updateFile(officeByte, excelTab.getExtension());
-                //修改本地数据信息
-                excelTab.setFileUrl(bladeFile.getLink());
+
+                FileOutputStream fs = new FileOutputStream(dataUrl);
+                fs.write(officeByte);
+                fs.flush();
+                BladeFile bladeFile = newIOSSClient.uploadFile(excelTab.getExtension(), dataUrl);
                 //获取文件大小
                 int size = connection.getContentLength() / 1024 / 1024; //单位M
                 excelTab.setAttachSize(Long.parseLong(size + ""));
                 excelTab.setStatus(3);
+                excelTab.setFileUrl(bladeFile.getLink());
                 baseMapper.updateById(excelTab);
-                connection.disconnect();
+                File file = new File(dataUrl);
+                if(file.exists()){
+                    file.delete();
+                }
                 System.out.println("123456");
             } catch (Exception e) {
                 editCallback.setError(1);
@@ -1126,7 +1126,12 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                     } else if (tabVal.indexOf("_^_") >= 0) {
                         String[] tabData = tabVal.split("_\\^_");
                         if (StringUtils.isNotEmpty(tabData[0])) {
-                            reData.put(key + "__" + tabData[1], tabData[0]);
+                            if (tabVal.contains("[") && tabVal.contains("年")) {
+                                String[] strings = StringUtils.strip(tabData[0], "[]").split(",");
+                                reData.put(key + "__" + tabData[1], strings);
+                            }else {
+                                reData.put(key + "__" + tabData[1], tabData[0]);
+                            }
                         }
                     } else {
                         reData.put(key, tabVal);
@@ -1168,8 +1173,8 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
 
     @Override
     public R getBussPdfInfo(Long pkeyId) throws Exception {
-       // String file_path = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
-        String file_path = "/Users/hongchuangyanfa/Desktop/";
+        String file_path = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
+        //String file_path = "/Users/hongchuangyanfa/Desktop/";
         WbsTreeContract wbsTreeContract = wbsTreeContractService.getBaseMapper().selectOne(Wrappers.<WbsTreeContract>query().lambda()
                 .eq(WbsTreeContract::getPKeyId, pkeyId));
 
@@ -1286,7 +1291,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                                                     x1 = 1;
                                                 }
                                                 String myData = DataInfo.get(val) + "";
-                                                if (myData.indexOf("T") >= 0 && myData.indexOf("-") >= 0) {
+                                                if ((myData.indexOf("T") >= 0 && myData.indexOf("-") >= 0) || (myData.indexOf(",") >= 0 && myData.indexOf("]") >= 0)){
                                                     SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
                                                     sdf.setTimeZone(TimeZone.getTimeZone("GTM+8"));
                                                     SimpleDateFormat formatStr = new SimpleDateFormat("yyyy年MM月dd日");
@@ -1414,8 +1419,6 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                 }
             }
         }
-
-        //wb.saveToFile(excelPath, ExcelVersion.Version2010);
         //输出流
         FileOutputStream outputStream = new FileOutputStream(excelPath);
         workbook.write(outputStream);
@@ -1473,8 +1476,8 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
 
     @Override
     public void getBussPdfs(String nodeId, String classify, String contractId, String projectId) throws Exception {
-        //String file_path = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
-        String file_path = "/Users/hongchuangyanfa/Desktop/";
+        String file_path = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
+        //String file_path = "/Users/hongchuangyanfa/Desktop/";
         // 获取有权限的节点信息
         List<AppWbsTreeContractVO> wbsTreeContractList = wbsTreeContractService.searchNodeAllTable(nodeId, classify, contractId, projectId);
         List<String> data = new ArrayList<>();
@@ -1950,8 +1953,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
      * 试验 单pdf
      */
     @Override
-    public String getBussPDFTrial(Long pkeyId, String contractId, Long id, int pageNumber, int pageNumberCount) throws
-            Exception {
+    public String getBussPDFTrial(Long pkeyId, String contractId, Long id, int pageNumber, int pageNumberCount, TrialSelfInspectionRecordDTO dto) throws Exception {
         String file_path = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
         WbsTreePrivate wbsTreePrivate = wbsTreePrivateService.getBaseMapper().selectOne(Wrappers.<WbsTreePrivate>query().lambda()
                 .eq(WbsTreePrivate::getPKeyId, pkeyId));
@@ -1978,7 +1980,10 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
 
         //获取数据信息info
         List<Map<String, Object>> bussDataInfoTrial = this.getBussDataInfoTrial(id, pkeyId, Long.parseLong(contractId));
-        Map<String, Object> DataInfo = bussDataInfoTrial.stream().findAny().orElse(null);
+        Map<String, Object> DataInfo = new HashMap<>();
+        if (bussDataInfoTrial.size() > 0) {
+            DataInfo.putAll(bussDataInfoTrial.stream().findAny().orElse(null));
+        }
 
         org.apache.poi.ss.usermodel.Workbook workbook = WorkbookFactory.create(CommonUtil.getOSSInputStream(excelTab.getFileUrl()));
         Sheet sheet = workbook.getSheetAt(0);
@@ -2031,6 +2036,26 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                 Document doc = Jsoup.parse(htmlString);
                 Element table = doc.select("table").first();
                 Elements trs = table.select("tr");
+
+                Elements bgHB = doc.select("el-input[placeholder~=报告编号.*]");
+                Elements jlBH = doc.select("el-input[placeholder~=记录编号.*]");
+                if (dto != null) {
+                    //报告编号
+                    if (bgHB.size() >= 1 && StringUtils.isNotEmpty(dto.getReportNo())) {
+                        for (Element element : bgHB) {
+                            DataInfo.put(element.attr("keyname"), "NUMBER-" + dto.getReportNo());
+                            break;
+                        }
+                    }
+                    //记录编号
+                    if (jlBH.size() >= 1 && StringUtils.isNotEmpty(dto.getRecordNo())) {
+                        for (Element element : jlBH) {
+                            DataInfo.put(element.attr("keyname"), "NUMBER-" + dto.getRecordNo());
+                            break;
+                        }
+                    }
+                }
+
                 if (ObjectUtil.isNotEmpty(DataInfo)) {
                     for (String val : Objects.requireNonNull(DataInfo).keySet()) {
                         if (val.contains("__")) {
@@ -2118,6 +2143,18 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                                                             ObjectUtils.isNotEmpty(cell);
                                                         }
                                                     }
+                                                } else if (myData.contains("NUMBER-JL-") || myData.contains("NUMBER-BG-")) {
+                                                    //记录表号、报告单号
+                                                    Row row = sheet.getRow(y1 - 1);
+                                                    if (row != null) {
+                                                        Cell cell = row.getCell(x1 - 1);
+                                                        if (cell != null) {
+                                                            String replace = myData.replace("NUMBER-", "");
+                                                            cell.setCellValue(replace);
+                                                        } else {
+                                                            ObjectUtils.isNotEmpty(cell);
+                                                        }
+                                                    }
                                                 } else {
                                                     Row row = sheet.getRow(y1 - 1);
                                                     if (row != null) {
@@ -2156,7 +2193,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                                 Elements tdsx = ytzData.select("td");
                                 if (Integer.parseInt(trtd[1]) < tdsx.size()) {
                                     Element data = ytzData.select("td").get(Integer.parseInt(trtd[1]));
-                                    if (data.html().indexOf("el-tooltip") >= 0) {
+                                    if (data.html().contains("el-tooltip")) {
                                         data = data.children().get(0);
                                     }
 
@@ -2169,7 +2206,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                                     Row row = sheet.getRow(y1 - 1);
                                     if (row != null) {
                                         Cell cell = sheet.getRow(y1 - 1).getCell(x1 - 1);
-                                        if (cell != null || ObjectUtils.isNotEmpty(cell)) {
+                                        if (cell != null) {
                                             short fontIndex = cell.getCellStyle().getFontIndex();
                                             Font oldfontAt = workbook.getFontAt(fontIndex);
 
@@ -2183,6 +2220,8 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                                             newStyle.setFont(redFont);
                                             cell.setCellStyle(newStyle);
                                             cell.setCellValue(e.getId() + "");
+                                        } else {
+                                            ObjectUtils.isNotEmpty(cell);
                                         }
                                     }
                                 }
@@ -2262,17 +2301,16 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
      */
     @Override
     public String getBussPDFSTrial(String nodeId, String tableType, String classify, String contractId, String
-            projectId, Long id, String tabIds) throws Exception {
+            projectId, Long id, String tabIds, TrialSelfInspectionRecordDTO dto) throws Exception {
         String file_path = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
         //获取有权限的表的信息
-        String sql = "select p_key_id,html_url,table_type,sort,node_name,create_time from m_wbs_tree_private where is_deleted = 0 and p_key_id in (" + tabIds + ") order by sort,node_name,create_time";
-        List<WbsTreePrivate> queryList = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(WbsTreePrivate.class));
+        List<WbsTreePrivate> queryList = jdbcTemplate.query("select p_key_id,html_url,table_type,sort,node_name,create_time from m_wbs_tree_private where is_deleted = 0 and p_key_id in (" + tabIds + ") order by sort,node_name,create_time", new BeanPropertyRowMapper<>(WbsTreePrivate.class));
         List<String> dataPdfUrls = new ArrayList<>();
 
         //报告单
-        List<WbsTreePrivate> reportTable = queryList.stream().filter(f -> f.getTableType() == 2).collect(Collectors.toList());
+        List<WbsTreePrivate> reportTable = queryList.stream().filter(f -> f.getTableType() == 10 || f.getTableType() == 2).collect(Collectors.toList());
         //记录表
-        List<WbsTreePrivate> recordTable = queryList.stream().filter(f -> f.getTableType() == 1).collect(Collectors.toList());
+        List<WbsTreePrivate> recordTable = queryList.stream().filter(f -> f.getTableType() == 9 || f.getTableType() == 1).collect(Collectors.toList());
 
         if (queryList.size() > 0) {
             int reportPageNumber = 1;
@@ -2282,7 +2320,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                     //没有excel表单的不生成pdf
                     if (StringUtils.isNotEmpty(report.getHtmlUrl())) {
                         //生成报告单pdf
-                        String bussPdfInfo = this.getBussPDFTrial(report.getPKeyId(), contractId, id, reportPageNumber++, reportPageNumberCount);
+                        String bussPdfInfo = this.getBussPDFTrial(report.getPKeyId(), contractId, id, reportPageNumber++, reportPageNumberCount, dto);
                         if (StringUtils.isNotEmpty(bussPdfInfo)) {
                             dataPdfUrls.add(bussPdfInfo);
                         }
@@ -2297,7 +2335,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                     //没有excel表单的不生成pdf
                     if (StringUtils.isNotEmpty(record.getHtmlUrl())) {
                         //生成记录表pdf
-                        String bussPdfInfo = this.getBussPDFTrial(record.getPKeyId(), contractId, id, recordPageNumber++, recordPageNumberCount);
+                        String bussPdfInfo = this.getBussPDFTrial(record.getPKeyId(), contractId, id, recordPageNumber++, recordPageNumberCount,null);
                         if (StringUtils.isNotEmpty(bussPdfInfo)) {
                             dataPdfUrls.add(bussPdfInfo);
                         }

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

@@ -413,7 +413,7 @@ public class WbsFormElementServiceImpl extends BaseServiceImpl<WbsFormElementMap
     @Override
     @Transactional(rollbackFor = Exception.class)
     public boolean submitExcelRelationWbsTreeAndElement(FormElementDTO2 formElementDTO) {
-        //新增元素表、实体表 2表示 创建 并关联 wbs 树节点信息   3 表示只创建
+        //1新增元素表、实体表 2表示 创建 并关联 wbs 树节点信息   3 表示只创建
         if (formElementDTO.getSubmitStatus() == 2 || formElementDTO.getSubmitStatus() == 3) {//
             this.saveFormElement(formElementDTO);
         } else if (formElementDTO.getSubmitStatus() == 1) { // 修改实体信息

+ 99 - 81
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeContractServiceImpl.java

@@ -12,6 +12,7 @@ import org.jsoup.Jsoup;
 import org.jsoup.nodes.Document;
 import org.springblade.business.entity.ConstructionLedger;
 import org.springblade.business.feign.ConstructionLedgerFeignClient;
+import org.springblade.business.feign.InformationQueryClient;
 import org.springblade.common.utils.FileUtils;
 import org.springblade.common.utils.SnowFlakeUtil;
 import org.springblade.core.log.exception.ServiceException;
@@ -41,6 +42,7 @@ import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.util.*;
+import java.util.function.Function;
 import java.util.stream.Collectors;
 
 @Service
@@ -51,6 +53,7 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
     private final WbsTreePrivateMapper wbsTreePrivateMapper;
     private final ContractInfoMapper contractInfoMapper;
     private final JdbcTemplate jdbcTemplate;
+    private final InformationQueryClient informationQueryClient;
 
     @Override
     public List<WbsTreeContract> selectQueryCurrentNodeByAncestors(List<String> ids, String contractId) {
@@ -86,7 +89,7 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
 
         //获取当前合同段所有节点、表单(不包括客户端新增或者复制节点)
         List<WbsTreeContract> list = baseMapper.selectList(Wrappers.<WbsTreeContract>lambdaQuery()
-                .select(WbsTreeContract::getId, WbsTreeContract::getType)
+                .select(WbsTreeContract::getId, WbsTreeContract::getType, WbsTreeContract::getParentId)
                 .eq(WbsTreeContract::getContractId, pawDTO.getContractId())
                 .eq(WbsTreeContract::getWbsId, pawDTO.getWbsId())
                 .eq(WbsTreeContract::getStatus, 1)
@@ -107,7 +110,7 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
 
         //TODO ---------节点未变只同步元素表---------
         if (saveIds.size() == 0 && delIds.size() == 0) {
-            List<WbsTreePrivate> wbsTreePrivateList2 = new ArrayList<>();
+            List<WbsTreePrivate> wbsTreePrivateListResult = new ArrayList<>();
             List<WbsTreePrivate> wbsTreePrivateList = wbsTreePrivateMapper.selectList(Wrappers.<WbsTreePrivate>query().lambda()
                     .eq(WbsTreePrivate::getProjectId, Long.parseLong(pawDTO.getProjectId()))
                     .eq(WbsTreePrivate::getWbsId, Long.parseLong(pawDTO.getWbsId()))
@@ -117,39 +120,40 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
             wbsTreePrivateList.forEach(wbsTreePrivate -> {
                 idList1.forEach(id -> {
                     if (Long.parseLong(id) == (wbsTreePrivate.getParentId()) && wbsTreePrivate.getType() == 2) {
-                        wbsTreePrivateList2.add(wbsTreePrivate);
+                        wbsTreePrivateListResult.add(wbsTreePrivate);
                     }
                 });
             });
 
-            List<String> collect = wbsTreePrivateList2.stream().map(WbsTreePrivate::getId).map(String::valueOf).collect(Collectors.toList());
-
-            List<String> diffRent1 = DiffListUtil.getDiffRent(collect, collect1);
+            //当前项目节点下的所有表单Ids
+            List<String> collect = wbsTreePrivateListResult.stream().map(WbsTreePrivate::getId).distinct().map(String::valueOf).collect(Collectors.toList());
 
             if (collect.size() == collect1.size()) {
                 return true;
             }
-            if (collect.size() > collect1.size()) {
-                List<WbsTreeContract> wbsTreeContracts = new ArrayList<>();
-                wbsTreePrivateList.forEach(wbsTreePrivate -> {
-                    diffRent1.forEach(id -> {
-                        if (Long.parseLong(id) == (wbsTreePrivate.getId())) {
-                            WbsTreeContract wbsTreeContract = BeanUtil.copyProperties(wbsTreePrivate, WbsTreeContract.class);
-                            if (wbsTreeContract != null) {
-                                wbsTreeContract.setPKeyId(SnowFlakeUtil.getId());
-                                wbsTreeContract.setWbsId(pawDTO.getWbsId());
-                                wbsTreeContract.setProjectId(pawDTO.getProjectId());
-                                wbsTreeContract.setContractId(pawDTO.getContractId());
-                                if (wbsTreePrivate.getType() == 2) {
-                                    wbsTreeContract.setIsTypePrivatePid(wbsTreePrivate.getPKeyId());
-                                }
-                            }
-                            wbsTreeContracts.add(wbsTreeContract);
-                        }
-                    });
-                });
 
-                this.insertBatch(wbsTreeContracts, 1000);
+            List<String> finalCollect = collect1;
+            Map<String, String> resultMapData = collect.stream().filter(f -> !finalCollect.contains(f)).collect(Collectors.toMap(Object::toString, Function.identity()));
+
+            List<WbsTreeContract> wbsTreeContractResultData = new ArrayList<>();
+            wbsTreePrivateList.forEach(wbsTreePrivate -> {
+                String resultObj = resultMapData.get(wbsTreePrivate.getId() + "");
+                if (resultObj != null) {
+                    WbsTreeContract wbsTreeContract = BeanUtil.copyProperties(wbsTreePrivate, WbsTreeContract.class);
+                    if (wbsTreeContract != null) {
+                        wbsTreeContract.setPKeyId(SnowFlakeUtil.getId());
+                        wbsTreeContract.setWbsId(pawDTO.getWbsId());
+                        wbsTreeContract.setProjectId(pawDTO.getProjectId());
+                        wbsTreeContract.setContractId(pawDTO.getContractId());
+                        if (wbsTreePrivate.getType() == 2) {
+                            wbsTreeContract.setIsTypePrivatePid(wbsTreePrivate.getPKeyId());
+                        }
+                        wbsTreeContractResultData.add(wbsTreeContract);
+                    }
+                }
+            });
+            if (wbsTreeContractResultData.size()>0){
+                this.insertBatch(wbsTreeContractResultData, 1000);
             }
 
         } else {
@@ -179,6 +183,14 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
                     throw new ServiceException(StringUtil.format("节点下的 {} 中存在填报数据,删除失败!", names));
                 }
                 baseMapper.deleteBatch(ids1, pawDTO.getWbsId(), pawDTO.getProjectId(), pawDTO.getContractId());
+
+                //更新redis缓存
+                List<WbsTreeContract> delObjList = list.stream().filter(f -> ids1.contains(f.getId())).collect(Collectors.toList());
+                Map<Long, List<WbsTreeContract>> collect = delObjList.stream().filter(f -> ObjectUtil.isNotEmpty(f.getParentId())).collect(Collectors.groupingBy(WbsTreeContract::getParentId));
+                for (Map.Entry<Long, List<WbsTreeContract>> longListEntry : collect.entrySet()) {
+                    informationQueryClient.AsyncWbsTree(longListEntry.getKey().toString() + "", longListEntry.getKey() + "", pawDTO.getContractId(), "", "1");
+                }
+
             }
 
             //TODO ---------新增---------
@@ -233,6 +245,12 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
 
                 this.insertBatch(wbsTreeContractList, 1000);
                 constructionLedgerFeign.initConstructionLedger(constructionLedgerList);
+
+                //更新redis缓存
+                Map<Long, List<WbsTreeContract>> collect = wbsTreeContractList.stream().filter(f -> new Integer(1).equals(f.getType()) && ObjectUtil.isNotEmpty(f.getParentId())).collect(Collectors.groupingBy(WbsTreeContract::getParentId));
+                for (Map.Entry<Long, List<WbsTreeContract>> longListEntry : collect.entrySet()) {
+                    informationQueryClient.AsyncWbsTree("", longListEntry.getKey().toString(), pawDTO.getContractId(), "", "1");
+                }
             }
         }
         return true;
@@ -359,7 +377,7 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
 
     // 频率添加表单
     @Override
-    public boolean addTabInfoByRan(RangeInfo info,List<Object> moreData,String[] excLenght){
+    public boolean addTabInfoByRan(RangeInfo info, List<Object> moreData, String[] excLenght) {
         WbsTreeContract wbsInfo = this.baseMapper.selectOne(Wrappers.<WbsTreeContract>query().lambda()
                 .eq(WbsTreeContract::getPKeyId, info.getPkId()));
 
@@ -369,7 +387,7 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
                 .eq(WbsTreeContract::getId, wbsInfo.getId())
                 .eq(WbsTreeContract::getContractId, wbsInfo.getContractId())
                 .eq(WbsTreeContract::getParentId, wbsInfo.getParentId()));
-        List<WbsTreeContract> wbsTreeContractList2 = wbsTreeContractList.stream().filter(wbsTreeContract -> wbsTreeContract.getIsCopeTab() ==null || wbsTreeContract.getIsCopeTab()==3).sorted(Comparator.comparing(WbsTreeContract::getCreateTime)).collect(Collectors.toList());
+        List<WbsTreeContract> wbsTreeContractList2 = wbsTreeContractList.stream().filter(wbsTreeContract -> wbsTreeContract.getIsCopeTab() == null || wbsTreeContract.getIsCopeTab() == 3).sorted(Comparator.comparing(WbsTreeContract::getCreateTime)).collect(Collectors.toList());
 
         int indexId = wbsTreeContractList2.indexOf(wbsInfo);
 
@@ -378,73 +396,73 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
         List<WbsTreeContract> addList = new ArrayList<>();
         StringBuilder addSql = new StringBuilder();
         //修改或新增数据
-        for(int i=indexId+1 ; i<wbsTreeContractList2.size();i++){
-             WbsTreeContract wbsTreeContract = wbsTreeContractList2.get(i);
-             List<Map<String, Object>> DataMap = jdbcTemplate.queryForList("select  * from " + wbsInfo.getInitTableName() + " where p_key_id=" + wbsTreeContract.getPKeyId());
-
-             int dataSize = 0;
-             if(moreData.size()>= excLenght.length){
-                 dataSize =excLenght.length;
-             }else{
-                 dataSize =moreData.size();
-                 if(dataSize<=0){
-                     break;
-                 }
-             }
-
-            if(DataMap!=null && DataMap.size()>=1){
+        for (int i = indexId + 1; i < wbsTreeContractList2.size(); i++) {
+            WbsTreeContract wbsTreeContract = wbsTreeContractList2.get(i);
+            List<Map<String, Object>> DataMap = jdbcTemplate.queryForList("select  * from " + wbsInfo.getInitTableName() + " where p_key_id=" + wbsTreeContract.getPKeyId());
+
+            int dataSize = 0;
+            if (moreData.size() >= excLenght.length) {
+                dataSize = excLenght.length;
+            } else {
+                dataSize = moreData.size();
+                if (dataSize <= 0) {
+                    break;
+                }
+            }
+
+            if (DataMap != null && DataMap.size() >= 1) {
                 String dataCol = "";
-                String updateSql = "update "+wbsInfo.getInitTableName()+" set "+info.getKey() +"=";
-                for(int j=0; j<dataSize;j++){
-                    if(j==dataSize-1){
-                        dataCol = dataCol + moreData.get(j) +"_^_"+excLenght[j];
-                    }else{
-                        dataCol = dataCol + moreData.get(j) +"_^_"+excLenght[j]+"☆";
+                String updateSql = "update " + wbsInfo.getInitTableName() + " set " + info.getKey() + "=";
+                for (int j = 0; j < dataSize; j++) {
+                    if (j == dataSize - 1) {
+                        dataCol = dataCol + moreData.get(j) + "_^_" + excLenght[j];
+                    } else {
+                        dataCol = dataCol + moreData.get(j) + "_^_" + excLenght[j] + "☆";
                     }
                 }
-                updateSql = updateSql + "'"+dataCol +"' where p_key_id=" + wbsTreeContract.getPKeyId() +" ;";
+                updateSql = updateSql + "'" + dataCol + "' where p_key_id=" + wbsTreeContract.getPKeyId() + " ;";
                 moreData = moreData.stream().skip(excLenght.length).map(com.mixsmart.utils.StringUtils::handleNull).collect(Collectors.toList());
                 addSql.append(updateSql);
-            }else{
+            } else {
                 long dataId = SnowFlakeUtil.getId();
-                String insertSql = "insert into "+wbsInfo.getInitTableName() +"(id,p_key_id,"+info.getKey()+") VALUES ("+dataId+","+ wbsTreeContract.getPKeyId()+",'";
+                String insertSql = "insert into " + wbsInfo.getInitTableName() + "(id,p_key_id," + info.getKey() + ") VALUES (" + dataId + "," + wbsTreeContract.getPKeyId() + ",'";
                 String dataCol = "";
-                for(int j=0; j<dataSize;j++){
-                    if(j==dataSize-1){
-                        dataCol = dataCol + moreData.get(j) +"_^_"+excLenght[j];
-                    }else{
-                        dataCol = dataCol + moreData.get(j) +"_^_"+excLenght[j]+"☆";
+                for (int j = 0; j < dataSize; j++) {
+                    if (j == dataSize - 1) {
+                        dataCol = dataCol + moreData.get(j) + "_^_" + excLenght[j];
+                    } else {
+                        dataCol = dataCol + moreData.get(j) + "_^_" + excLenght[j] + "☆";
                     }
                 }
-                insertSql =insertSql+dataCol+"');";
+                insertSql = insertSql + dataCol + "');";
                 moreData = moreData.stream().skip(excLenght.length).map(com.mixsmart.utils.StringUtils::handleNull).collect(Collectors.toList());
                 addSql.append(insertSql);
             }
         }
 
         //计算张数
-        double tabCount = moreData.size() / Double.parseDouble(excLenght.length+"") ;
-        double tabsCount  = Math.ceil(tabCount);//- wbsTreeContractList2.size()+indexId+1;
-        int maxIndex=0;
-        if(tabsCount>=1){
-            for(int i =0 ;i<tabsCount;i++){
+        double tabCount = moreData.size() / Double.parseDouble(excLenght.length + "");
+        double tabsCount = Math.ceil(tabCount);//- wbsTreeContractList2.size()+indexId+1;
+        int maxIndex = 0;
+        if (tabsCount >= 1) {
+            for (int i = 0; i < tabsCount; i++) {
                 long newPkId = SnowFlakeUtil.getId();
                 WbsTreeContract wbsTreeContract = new WbsTreeContract();
-                BeanUtil.copy(wbsInfo,wbsTreeContract);
+                BeanUtil.copy(wbsInfo, wbsTreeContract);
                 wbsTreeContract.setPKeyId(newPkId);
                 wbsTreeContract.setCreateTime(new Date());
                 wbsTreeContract.setTabGroupId(tabGroupId);
-                String nodeName = wbsTreeContractList2.get(wbsTreeContractList2.size()-1).getNodeName();
+                String nodeName = wbsTreeContractList2.get(wbsTreeContractList2.size() - 1).getNodeName();
 
                 if (nodeName.indexOf("_PL_") >= 0) {
                     String[] oldName = nodeName.split("_PL_");
-                    if(i==0){
+                    if (i == 0) {
                         maxIndex = Integer.parseInt(oldName[1]);
                     }
-                    maxIndex =maxIndex+1 ;
+                    maxIndex = maxIndex + 1;
                     nodeName = oldName[0] + "_PL_" + maxIndex;
                 } else {
-                    maxIndex =maxIndex+1 ;
+                    maxIndex = maxIndex + 1;
                     nodeName = nodeName + "_PL_" + maxIndex;
                 }
 
@@ -458,22 +476,22 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
                 addList.add(wbsTreeContract);
 
                 int dataSize = 0;
-                if(moreData.size()>= excLenght.length){
-                    dataSize =excLenght.length;
-                }else{
-                    dataSize =moreData.size();
+                if (moreData.size() >= excLenght.length) {
+                    dataSize = excLenght.length;
+                } else {
+                    dataSize = moreData.size();
                 }
                 long dataId = SnowFlakeUtil.getId();
-                String insertSql = "insert into "+wbsInfo.getInitTableName() +"(id,p_key_id,"+info.getKey()+") VALUES ("+dataId+","+ wbsTreeContract.getPKeyId()+",'";
+                String insertSql = "insert into " + wbsInfo.getInitTableName() + "(id,p_key_id," + info.getKey() + ") VALUES (" + dataId + "," + wbsTreeContract.getPKeyId() + ",'";
                 String dataCol = "";
-                for(int j=0; j<dataSize;j++){
-                    if(j==dataSize-1){
-                        dataCol = dataCol + moreData.get(j) +"_^_"+excLenght[j];
-                    }else{
-                        dataCol = dataCol + moreData.get(j) +"_^_"+excLenght[j]+"☆";
+                for (int j = 0; j < dataSize; j++) {
+                    if (j == dataSize - 1) {
+                        dataCol = dataCol + moreData.get(j) + "_^_" + excLenght[j];
+                    } else {
+                        dataCol = dataCol + moreData.get(j) + "_^_" + excLenght[j] + "☆";
                     }
                 }
-                insertSql =insertSql+dataCol+"');";
+                insertSql = insertSql + dataCol + "');";
                 moreData = moreData.stream().skip(excLenght.length).map(com.mixsmart.utils.StringUtils::handleNull).collect(Collectors.toList());
                 addSql.append(insertSql);
             }
@@ -482,12 +500,12 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
         }
 
         this.jdbcTemplate.execute(addSql.toString());
-        for(WbsTreeContract wbsTreeCont:wbsTreeContractList2){
+        for (WbsTreeContract wbsTreeCont : wbsTreeContractList2) {
             UpdateWrapper<WbsTreeContract> updateWrapper = new UpdateWrapper<>();
             updateWrapper.in("p_key_id", wbsTreeCont.getPKeyId() + "");
             updateWrapper.set("tab_group_id", tabGroupId);
             wbsTreeCont.setTabGroupId(tabGroupId);
-            this.getBaseMapper().update(wbsTreeCont,updateWrapper);
+            this.getBaseMapper().update(wbsTreeCont, updateWrapper);
         }
         return false;
     }

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

@@ -17,7 +17,6 @@ import org.springblade.business.feign.InformationQueryClient;
 import org.springblade.common.constant.CommonConstant;
 import org.springblade.common.utils.CommonUtil;
 import org.springblade.common.utils.SnowFlakeUtil;
-import org.springblade.common.utils.ThreadPoolMonitor;
 import org.springblade.core.log.exception.ServiceException;
 import org.springblade.core.mp.base.BaseServiceImpl;
 import org.springblade.core.mp.support.Condition;
@@ -1532,34 +1531,129 @@ public class WbsTreePrivateServiceImpl extends BaseServiceImpl<WbsTreePrivateMap
     public List<WbsTreePrivateVO> getMixRatioTestTree(String pKeyId) {
         WbsTreePrivate wbsTreePrivate = baseMapper.selectOne(Wrappers.<WbsTreePrivate>lambdaQuery().eq(WbsTreePrivate::getPKeyId, pKeyId));
         if (wbsTreePrivate != null && StringUtils.isNotEmpty(wbsTreePrivate.getMixRatioTestIds())) {
-            String ids = wbsTreePrivate.getMixRatioTestIds();
-            List<WbsTreePrivate> wbsTreePrivates = baseMapper.selectList(Wrappers.<WbsTreePrivate>lambdaQuery()
-                    .in(WbsTreePrivate::getId, Func.toLongList(ids))
-                    .eq(WbsTreePrivate::getProjectId, wbsTreePrivate.getProjectId())
-                    .eq(WbsTreePrivate::getWbsId, wbsTreePrivate.getWbsId())
-                    .eq(WbsTreePrivate::getWbsType, wbsTreePrivate.getWbsType())
-                    .eq(WbsTreePrivate::getStatus, 1));
-
-            WbsTreePrivate root = wbsTreePrivates.stream().filter(f -> f.getParentId() == 0L).findAny().orElse(null);
-            if (root == null) {
-                WbsTreePrivate rootNode = baseMapper.selectOne(Wrappers.<WbsTreePrivate>lambdaQuery()
-                        .eq(WbsTreePrivate::getParentId, 0L)
+            Set<String> idsSet = new HashSet<>();
+            List<String> ancestorsIds = Func.toStrList(wbsTreePrivate.getAncestors());
+            List<String> mixRatioTestIds = Func.toStrList(wbsTreePrivate.getMixRatioTestIds());
+            idsSet.addAll(ancestorsIds);
+            idsSet.addAll(mixRatioTestIds);
+
+            if (idsSet.size() > 0) {
+                //删除值为0根节点的元素
+                idsSet.removeIf("0"::equals);
+                List<WbsTreePrivate> wbsTreePrivates = baseMapper.selectList(Wrappers.<WbsTreePrivate>lambdaQuery()
+                        .in(WbsTreePrivate::getId, idsSet)
                         .eq(WbsTreePrivate::getProjectId, wbsTreePrivate.getProjectId())
                         .eq(WbsTreePrivate::getWbsId, wbsTreePrivate.getWbsId())
                         .eq(WbsTreePrivate::getWbsType, wbsTreePrivate.getWbsType())
                         .eq(WbsTreePrivate::getStatus, 1));
-                if (rootNode != null) {
-                    wbsTreePrivates.add(rootNode);
+
+                WbsTreePrivate root = wbsTreePrivates.stream().filter(f -> f.getParentId() == 0L).findAny().orElse(null);
+                if (root == null) {
+                    WbsTreePrivate rootNode = baseMapper.selectOne(Wrappers.<WbsTreePrivate>lambdaQuery()
+                            .eq(WbsTreePrivate::getParentId, 0L)
+                            .eq(WbsTreePrivate::getProjectId, wbsTreePrivate.getProjectId())
+                            .eq(WbsTreePrivate::getWbsId, wbsTreePrivate.getWbsId())
+                            .eq(WbsTreePrivate::getWbsType, wbsTreePrivate.getWbsType())
+                            .eq(WbsTreePrivate::getStatus, 1));
+                    if (rootNode != null) {
+                        wbsTreePrivates.add(rootNode);
+                    }
                 }
-            }
 
-            List<WbsTreePrivateVO> wbsTreePrivateVOS = BeanUtil.copyProperties(wbsTreePrivates, WbsTreePrivateVO.class);
-            return this.buildWbsTreeByStream(wbsTreePrivateVOS);
+                List<WbsTreePrivateVO> wbsTreePrivateVOS = BeanUtil.copyProperties(wbsTreePrivates, WbsTreePrivateVO.class);
+                return this.buildWbsTreeByStream(wbsTreePrivateVOS);
+            }
+            return null;
         } else {
             throw new ServiceException("当前节点下未配置勾选相关联试验的配合比节点");
         }
     }
 
+    @Override
+    public Map<String, List<Object>> treeRecordTrial(String wbsId, String projectId, String pKeyId) {
+        WbsInfo wbsInfo = wbsInfoMapper.selectOne(Wrappers.<WbsInfo>query().lambda().select(WbsInfo::getWbsType).eq(WbsInfo::getId, wbsId));
+        if (wbsInfo != null) {
+            WbsTreePrivate wbsTreePrivate = this.getBaseMapper().selectOne(Wrappers.<WbsTreePrivate>lambdaQuery()
+                    .select(WbsTreePrivate::getMixRatioTestIds)
+                    .eq(WbsTreePrivate::getPKeyId, pKeyId));
+            if (wbsTreePrivate != null && StringUtils.isNotEmpty(wbsTreePrivate.getMixRatioTestIds())) {
+                //公有引用
+                List<WbsTreePrivateVO5> wbsTreePrivateVO5s = baseMapper.treeRecordTrial(wbsId, projectId, wbsInfo.getWbsType());
+                List<String> strings = Func.toStrList(wbsTreePrivate.getMixRatioTestIds());
+                for (WbsTreePrivateVO5 wbsTreePrivateVO5 : wbsTreePrivateVO5s) {
+                    for (String id : strings) {
+                        if (id.equals(wbsTreePrivateVO5.getId().toString())) {
+                            wbsTreePrivateVO5.setCheckStatus(1);
+                            break;
+                        }
+                    }
+                }
+
+                List<Long> allStatusIds = wbsTreePrivateVO5s.stream().filter(f -> new Integer(1).equals(f.getCheckStatus())).map(WbsTreePrivateVO5::getId).collect(Collectors.toList());
+                List<Long> halfStatusIds = wbsTreePrivateVO5s.stream().filter(f -> !new Integer(1).equals(f.getCheckStatus())).map(WbsTreePrivateVO5::getId).collect(Collectors.toList());
+
+                Map<String, List<Object>> map = new HashMap<>();
+                map.put("allTree", Collections.singletonList(this.buildWbsTreeByStreamTrial(wbsTreePrivateVO5s)));
+                map.put("allStatusIds", Collections.singletonList(allStatusIds));
+                map.put("halfStatusIds", Collections.singletonList(halfStatusIds));
+                return map;
+            }
+
+        } else {
+            //私有引用
+            WbsTreePrivate nodeRoot = wbsTreePrivateMapper.selectOne(Wrappers.<WbsTreePrivate>lambdaQuery()
+                    .select(WbsTreePrivate::getWbsType)
+                    .eq(WbsTreePrivate::getWbsId, wbsId)
+                    .eq(WbsTreePrivate::getProjectId, projectId)
+                    .eq(WbsTreePrivate::getParentId, 0L));
+            if (nodeRoot != null) {
+                WbsTreePrivate wbsTreePrivate = this.getBaseMapper().selectOne(Wrappers.<WbsTreePrivate>lambdaQuery()
+                        .select(WbsTreePrivate::getMixRatioTestIds)
+                        .eq(WbsTreePrivate::getPKeyId, pKeyId));
+                if (wbsTreePrivate != null && StringUtils.isNotEmpty(wbsTreePrivate.getMixRatioTestIds())) {
+                    List<WbsTreePrivateVO5> wbsTreePrivateVO5s = baseMapper.treeRecordTrial(wbsId, projectId, Integer.valueOf(nodeRoot.getWbsType()));
+                    List<String> strings = Func.toStrList(wbsTreePrivate.getMixRatioTestIds());
+                    for (WbsTreePrivateVO5 wbsTreePrivateVO5 : wbsTreePrivateVO5s) {
+                        for (String id : strings) {
+                            if (id.equals(wbsTreePrivateVO5.getId().toString())) {
+                                wbsTreePrivateVO5.setCheckStatus(1);
+                                break;
+                            }
+                        }
+                    }
+
+                    List<Long> allStatusIds = wbsTreePrivateVO5s.stream().filter(f -> new Integer(1).equals(f.getCheckStatus())).map(WbsTreePrivateVO5::getId).collect(Collectors.toList());
+                    List<Long> halfStatusIds = wbsTreePrivateVO5s.stream().filter(f -> !new Integer(1).equals(f.getCheckStatus())).map(WbsTreePrivateVO5::getId).collect(Collectors.toList());
+
+                    Map<String, List<Object>> map = new HashMap<>();
+                    map.put("allTree", Collections.singletonList(this.buildWbsTreeByStreamTrial(wbsTreePrivateVO5s)));
+                    map.put("allStatusIds", Collections.singletonList(allStatusIds));
+                    map.put("halfStatusIds", Collections.singletonList(halfStatusIds));
+                    return map;
+                }
+            }
+        }
+        return null;
+    }
+
+    private List<WbsTreePrivateVO5> buildWbsTreeByStreamTrial(List<WbsTreePrivateVO5> wbsTreeVO2s) {
+        List<WbsTreePrivateVO5> list = wbsTreeVO2s.stream().filter(f -> f.getParentId() == 0L).collect(Collectors.toList());
+        Map<Long, List<WbsTreePrivateVO5>> map = wbsTreeVO2s.stream().collect(Collectors.groupingBy(WbsTreePrivateVO5::getParentId));
+        this.recursionFnTreeTrial(list, map);
+        return list;
+    }
+
+    private void recursionFnTreeTrial(List<WbsTreePrivateVO5> list, Map<Long, List<WbsTreePrivateVO5>> map) {
+        for (WbsTreePrivateVO5 wbsTreeVO2 : list) {
+            List<WbsTreePrivateVO5> childrenList = map.get(wbsTreeVO2.getId());
+            wbsTreeVO2.setChildren(childrenList);
+            if (childrenList != null && childrenList.size() > 0) {
+                wbsTreeVO2.setHasChildren(true);
+                recursionFnTreeTrial(childrenList, map);
+            }
+        }
+    }
+
     private List<WbsTreePrivateVO> buildWbsTreeByStream(List<WbsTreePrivateVO> wbsTreePrivateVOS) {
         List<WbsTreePrivateVO> list = wbsTreePrivateVOS.stream().filter(f -> f.getParentId() == 0L).collect(Collectors.toList());
         Map<Long, List<WbsTreePrivateVO>> map = wbsTreePrivateVOS.stream().collect(Collectors.groupingBy(WbsTreePrivateVO::getParentId));
@@ -1823,20 +1917,18 @@ public class WbsTreePrivateServiceImpl extends BaseServiceImpl<WbsTreePrivateMap
         }
         //角色权限
         List<String> roleAndTabOwners = wbsTableOwnerRoleList.stream().map(WbsTableOwnerRole::getTableOwnerNumber).collect(Collectors.toList());
-
-        //表单权限
-        List<String> tableOwnerList = null;
-        if (org.apache.commons.lang.StringUtils.isNotEmpty(tableOwner)) {
-            String tableOwners = "";
-            if (tableOwner.equals("1")) {
-                tableOwners = "1,2,3";
-            } else if (tableOwner.equals("2")) {
-                tableOwners = "4,5,6";
+        String roleAndTabOwner = roleAndTabOwners.stream().filter(("7")::equals).findAny().orElse(null);
+        if (StringUtils.isNotEmpty(roleAndTabOwner)) {
+            //试验tabOwner=7,默认加载全部tabOwner=7的表
+            if ("1".equals(tableType)) {
+                tableType = "9"; //记录表
+            } else if ("2".equals(tableType)) {
+                tableType = "10";  //报告单
             }
-            tableOwnerList = Func.toStrList(tableOwners);
+            return baseMapper.selectWbsTreeTrialTabList(tableType, wbsTreePrivate.getProjectId(), wbsTreePrivate.getWbsId(), wbsTreePrivate.getId(), contractId);
+        } else {
+            throw new ServiceException("当前用户角色未授权,请先分配角色查看元素表相对应的权限");
         }
-
-        return baseMapper.selectWbsTreeTrialTabList(roleAndTabOwners, tableType, wbsTreePrivate.getProjectId(), wbsTreePrivate.getWbsId(), wbsTreePrivate.getId(), tableOwnerList, contractId);
     }
 
     @Override

+ 0 - 46
blade-service/blade-manager/src/main/java/org/springblade/manager/utils/AsyncConfigurer.java

@@ -1,46 +0,0 @@
-package org.springblade.manager.utils;
-
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.scheduling.annotation.EnableAsync;
-
-import java.util.concurrent.*;
-
-@Slf4j
-@Configuration
-@EnableAsync
-public class AsyncConfigurer {
-
-    /**
-     * cpu 核心数量
-     */
-    public static final int cpuNum = Runtime.getRuntime().availableProcessors();
-
-    /**
-     * 线程池配置
-     *
-     * @return
-     */
-    @Bean("taskExecutor1")
-    public ThreadPoolExecutor getAsyncExecutor() {
-        return new ThreadPoolMonitor(cpuNum
-                , cpuNum * 2
-                , 60
-                , TimeUnit.SECONDS
-                , new LinkedBlockingQueue<>(2000)
-                , new ThreadPoolExecutor.DiscardOldestPolicy(), "manager-thread-pool");
-    }
-
-    /**
-     * 线程池配置
-     *
-     * @return
-     */
-    @Bean("singleExecutor")
-    public ExecutorService getSingleExecutor() {
-        log.info("线程池初始化......");
-        return Executors.newSingleThreadExecutor();
-    }
-
-}

+ 2 - 2
blade-service/blade-manager/src/main/java/org/springblade/manager/utils/test.java

@@ -19,11 +19,11 @@ import java.util.Map;
 
 public class test {
 
-    public static void main(String[] args) {
+    /*public static void main(String[] args) {
         Map<String, Map<String, String>> map = getWeather("chongqing", "202304");
 //        String str = LocalDateTime.now().minusDays(1L).format(DateTimeFormatter.ofPattern("yyyy年MM月dd日"));
 //        System.out.println(map.get(str));
-    }
+    }*/
     public static  Map<String,Map<String,String>> getWeather(String city,String month){
         String html = "http://www.tianqihoubao.com/lishi/"+city+"/month/"+month+".html";
         System.out.println(html);

Daži faili netika attēloti, jo izmaiņu fails ir pārāk liels