Ver Fonte

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

LHB há 2 meses atrás
pai
commit
17071b658a
75 ficheiros alterados com 3712 adições e 1224 exclusões
  1. 6 0
      blade-common/pom.xml
  2. 1 1
      blade-common/src/main/java/org/springblade/common/utils/AsyncConfigurer.java
  3. 119 30
      blade-common/src/main/java/org/springblade/common/utils/CommonUtil.java
  4. 1 1
      blade-gateway/src/main/java/org/springblade/gateway/GateWayApplication.java
  5. 1 1
      blade-ops-api/blade-resource-api/src/main/java/org/springblade/resource/feign/IOSSClient.java
  6. 4 1
      blade-ops/blade-resource/src/main/java/org/springblade/resource/builder/oss/AmazonS3OssBuilder.java
  7. 1 0
      blade-ops/blade-resource/src/main/java/org/springblade/resource/builder/oss/OssBuilder.java
  8. 528 0
      blade-ops/blade-resource/src/main/java/org/springblade/resource/builder/ossre/S3Template2.java
  9. 6 3
      blade-ops/blade-resource/src/main/java/org/springblade/resource/endpoint/LargeFileEndpoint.java
  10. 1 1
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/Task.java
  11. 3 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/ScrSignInfoVO.java
  12. 5 0
      blade-service-api/blade-e-visa-api/src/main/java/org/springblade/evisa/vo/SealStrategyVO.java
  13. 11 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/feign/ExcelTabClient.java
  14. 19 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/feign/ExcelTabClientFallBack.java
  15. 11 1
      blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchiveFileController.java
  16. 8 1
      blade-service/blade-archive/src/main/java/org/springblade/archive/external/impl/ExternalDataArchiveFileService.java
  17. 202 3
      blade-service/blade-archive/src/main/java/org/springblade/archive/external/utils/TransUtil.java
  18. 7 1
      blade-service/blade-business/pom.xml
  19. 438 0
      blade-service/blade-business/src/main/java/org/springblade/business/chekPdf/PdfAddimgUtil.java
  20. 152 0
      blade-service/blade-business/src/main/java/org/springblade/business/controller/ChekSignData.java
  21. 150 54
      blade-service/blade-business/src/main/java/org/springblade/business/controller/InformationWriteQueryController.java
  22. 5 1
      blade-service/blade-business/src/main/java/org/springblade/business/controller/TaskController.java
  23. 1 1
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/InformationQueryMapper.java
  24. 4 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/InformationQueryMapper.xml
  25. 2 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/IInformationQueryService.java
  26. 47 1
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/InformationQueryServiceImpl.java
  27. 168 134
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TaskServiceImpl.java
  28. 32 0
      blade-service/blade-e-visa/pom.xml
  29. 151 0
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/controller/Chek.java
  30. 3 8
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/controller/ChekSignData.java
  31. 1 1
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/controller/EVController.java
  32. 0 227
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/controller/EVisaController.java
  33. 0 203
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/controller/EVisaController2.java
  34. 0 130
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/controller/EVisaController4.java
  35. 0 150
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/controller/synDataController.java
  36. 80 37
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/service/impl/EVDataServiceImpl.java
  37. 5 10
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/service/impl/EVisaServiceImpl.java
  38. 15 4
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/service/impl/ScrDataServiceImpl.java
  39. 1 1
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/utils/FileUtils.java
  40. 11 7
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/utils/PDFUtils.java
  41. 2 2
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/utils/SignFtpUtil.java
  42. 8 3
      blade-service/blade-manager/pom.xml
  43. 102 32
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ExcelTabController.java
  44. 101 2
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/NodeBaseInfoController.java
  45. 69 2
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/WbsTreeContractController.java
  46. 19 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/feign/ExcelTabClientImpl.java
  47. 46 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/TableInfoMapper.java
  48. 30 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/TableInfoMapper.xml
  49. 4 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ContractInfoServiceImpl.java
  50. 51 31
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ExcelTabServiceImpl.java
  51. 17 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormulaServiceImpl.java
  52. 5 4
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/NodeBaseInfoServiceImpl.java
  53. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/SignPfxFilePreServiceImpl.java
  54. 80 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/TableInfoServiceImpl.java
  55. 7 3
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsParamServiceImpl.java
  56. 153 93
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeContractServiceImpl.java
  57. 4 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/utils/FileUtils.java
  58. 377 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/utils/SignFtpUtil.java
  59. 1 1
      blade-service/blade-meter/src/main/java/org/springblade/meter/controller/APIController.java
  60. 27 10
      blade-service/blade-meter/src/main/java/org/springblade/meter/controller/TaskController.java
  61. 1 1
      blade-service/blade-meter/src/main/java/org/springblade/meter/mapper/MiddleMeterApplyMapper.java
  62. 1 1
      blade-service/blade-meter/src/main/java/org/springblade/meter/mapper/MiddleMeterApplyMapper.xml
  63. 2 2
      blade-service/blade-meter/src/main/java/org/springblade/meter/service/impl/InterimPayCertificateServiceImpl.java
  64. 1 1
      blade-service/blade-meter/src/main/java/org/springblade/meter/utils/PdfAddimgUtil.java
  65. 69 0
      blade-service/blade-repair/pom.xml
  66. 18 0
      blade-service/blade-repair/src/main/java/org/springblade/RepairApplication.java
  67. 134 0
      blade-service/blade-repair/src/main/java/org/springblade/repair/controller/CheckAndRepairController.java
  68. 107 0
      blade-service/blade-repair/src/main/java/org/springblade/repair/util/FileUtils.java
  69. 25 0
      blade-service/blade-repair/src/main/resources/application-dev.yml
  70. 11 0
      blade-service/blade-repair/src/main/resources/application-prod.yml
  71. 10 0
      blade-service/blade-repair/src/main/resources/application-test.yml
  72. 2 2
      blade-service/blade-user/src/main/java/org/springblade/system/user/controller/UserController.java
  73. 16 11
      blade-service/blade-user/src/main/java/org/springblade/system/user/mapper/UserMapper.xml
  74. 10 8
      blade-service/blade-user/src/main/java/org/springblade/system/user/service/impl/UserServiceImpl.java
  75. 1 0
      pom.xml

+ 6 - 0
blade-common/pom.xml

@@ -38,6 +38,11 @@
             <version>5.7.22</version>
             <scope>compile</scope>
         </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-imaging</artifactId>
+            <version>1.0-alpha3</version>
+        </dependency>
         <dependency>
             <groupId>com.aliyun.oss</groupId>
             <artifactId>aliyun-sdk-oss</artifactId>
@@ -75,6 +80,7 @@
                 <groupId>org.springframework.boot</groupId>
                 <artifactId>spring-boot-maven-plugin</artifactId>
                 <configuration>
+                    <fork>true</fork>
                     <skip>true</skip>
                     <finalName>${project.name}</finalName>
                 </configuration>

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

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

+ 119 - 30
blade-common/src/main/java/org/springblade/common/utils/CommonUtil.java

@@ -2,6 +2,7 @@ package org.springblade.common.utils;
 
 import cn.hutool.core.io.FileUtil;
 import cn.hutool.core.lang.func.Func;
+import cn.hutool.core.util.URLUtil;
 import cn.hutool.http.HttpUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
@@ -12,13 +13,12 @@ import com.drew.metadata.Metadata;
 import com.drew.metadata.exif.ExifIFD0Directory;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
+import org.apache.commons.imaging.ImageReadException;
+import org.apache.commons.imaging.Imaging;
 import org.apache.commons.lang.StringUtils;
 import org.springframework.util.CollectionUtils;
 
-import javax.imageio.IIOImage;
-import javax.imageio.ImageIO;
-import javax.imageio.ImageWriteParam;
-import javax.imageio.ImageWriter;
+import javax.imageio.*;
 import java.awt.*;
 import java.awt.color.ColorSpace;
 import java.awt.color.ICC_ColorSpace;
@@ -28,9 +28,7 @@ import java.awt.image.BufferedImage;
 import java.awt.image.ColorConvertOp;
 import java.io.*;
 import java.math.BigDecimal;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.net.URLConnection;
+import java.net.*;
 import java.time.LocalDate;
 import java.util.*;
 import java.util.List;
@@ -43,6 +41,7 @@ import java.util.zip.ZipOutputStream;
 
 import com.drew.metadata.MetadataException;
 import org.springframework.util.ResourceUtils;
+import org.springframework.web.util.UriUtils;
 
 /**
  * 通用工具类
@@ -141,20 +140,21 @@ public class CommonUtil {
     /**
      * 根据OSS文件路径获取文件输入流
      */
-    public static InputStream getOSSInputStream(String urlStr) {
+    public static synchronized InputStream getOSSInputStream(String urlStr) {
         try {
+            System.out.println("----前-------"+urlStr);
             urlStr = replaceOssUrl(urlStr);
+            int lastIndex = urlStr.lastIndexOf("/") + 1;
+            String fileName = urlStr.substring(lastIndex);
+            urlStr = urlStr.substring(0, lastIndex) + URLEncoder.encode(fileName, "UTF-8").replace("+", "%20");
             //获取OSS文件流
             URL url = new URL(urlStr);
             URLConnection conn = url.openConnection();
-      /*      // 设置连接超时时间
-            conn.setConnectTimeout(10000); // 5秒
-            // 设置读取超时时间
-            conn.setReadTimeout(10000); // 5秒*/
+
             conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
             return conn.getInputStream();
         } catch (Exception e) {
-            System.out.println("zw-----------");
+            System.out.println("-----------"+urlStr);
             return null;
         }
     }
@@ -523,26 +523,109 @@ public class CommonUtil {
      * @throws MetadataException
      */
 
-    public static void main(String[] args) throws IOException {
+/*    public static void main(String[] args) throws IOException, ImageProcessingException, MetadataException {
         // String imgurl = "/Users/hongchuangyanfa/Desktop/excel/432123.jpg";
         // String imgurl = "/Users/hongchuangyanfa/Desktop/excel/123.jpg";
-        String imgurl = "/Users/hongchuangyanfa/Downloads/bccb09f5e2caa85611d380f596d4febb.jpg";
-        File file = ResourceUtils.getFile(imgurl);
 
-        byte[] imageData = InputStreamToBytes(new FileInputStream(file));
 
+   //     String imgurl = "/Users/hongchuangyanfa/Downloads/03c1994653c4d59ab596e683a109e247 (1).jpg";
+        String imgurl = "http://183.247.216.148:9000/minio-oss-chongqing/upload/20250414/03c1994653c4d59ab596e683a109e247.jpg";
+
+        compressImage(imgurl);
+
+        System.out.println("图片转换并保存成功!");
+    }*/
+
+    public static byte[] compressImage(String url) throws IOException, ImageProcessingException, MetadataException{
+        // 读取原始图像(处理旋转问题)
+        InputStream file = CommonUtil.getOSSInputStream(url);
+        InputStream file2 = CommonUtil.getOSSInputStream(url);
+        byte[] imageData = InputStreamToBytes(file);
+
+        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);
+                // 需要旋转图片
+                // 1 无需纠正 2 水平翻转(镜像)3 垂直翻转(旋转180°) 4 水平翻转+垂直翻转 5 水平翻转+旋转90°
+                // 6 旋转90° 7 水平翻转+旋转270° 8 +旋转270°
+                if (orientation > 1) {
+                    BufferedImage originalImage = ImageIO.read(new ByteArrayInputStream(imageData));
+                    AffineTransform transform = new AffineTransform();
+                    if (orientation == 3) {
+                        transform.rotate(Math.PI, originalImage.getWidth() / 2, originalImage.getHeight() / 2);
+                    } else 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);
-        try {
-            ImageIO.setUseCache(false);
-            BufferedImage originalImage = ImageIO.read(bais);
-        } catch (IOException e) {
-            throw new RuntimeException(e);
+        BufferedImage   originalImage =ImageIO.read(file2);
+
+        long sizeLimit = 1024*1024*5; //5M 1920 ×1080
+        int width = 1080;
+        int height = 1920;
+        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();
         }
-        System.out.println("图片转换并保存成功!");
-    }
 
+        float quality = 0.9f; // 初始化压缩质量
+        int retries = 10; // 最多尝试 10 次
 
-    public static byte[] compressImage(byte[] imageData) throws IOException, ImageProcessingException, MetadataException {
+        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(1);
+
+            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();
+    }
+
+    public static byte[] compressImage(byte[] imageData) throws IOException, ImageProcessingException, MetadataException{
         // 读取原始图像(处理旋转问题)
         Metadata metadata = ImageMetadataReader.readMetadata(new ByteArrayInputStream(imageData));
         if (metadata.containsDirectoryOfType(ExifIFD0Directory.class)) {
@@ -575,10 +658,16 @@ public class CommonUtil {
         // 缩放图像
         String formatName = "JPEG";
         ByteArrayInputStream bais = new ByteArrayInputStream(imageData);
-        BufferedImage originalImage = ImageIO.read(bais);
-        long sizeLimit = 1024*1024*5; //5M
-        int width = 768;
-        int height = 1024;
+        BufferedImage   originalImage = null;
+        try {
+            originalImage = Imaging.getBufferedImage(imageData);
+        } catch (ImageReadException e) {
+
+        }
+
+        long sizeLimit = 1024*1024*5; //5M 1920 ×1080
+        int width = 1080;
+        int height = 1920;
         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);
@@ -612,7 +701,7 @@ public class CommonUtil {
 
             ImageWriteParam writeParam = writer.getDefaultWriteParam();
             writeParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
-            writeParam.setCompressionQuality(quality);
+            writeParam.setCompressionQuality(1);
 
             writer.setOutput(ImageIO.createImageOutputStream(baos));
             writer.write(null, new IIOImage(compressedImage, null, null), writeParam);

+ 1 - 1
blade-gateway/src/main/java/org/springblade/gateway/GateWayApplication.java

@@ -30,7 +30,7 @@ import org.springframework.scheduling.annotation.EnableScheduling;
 @EnableHystrix
 @EnableScheduling
 @SpringCloudApplication
-public class GateWayApplication {
+public class  GateWayApplication {
 
     public static void main(String[] args) {
         BladeApplication.run(AppConstant.APPLICATION_GATEWAY_NAME, GateWayApplication.class, args);

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

@@ -48,7 +48,7 @@ public interface IOSSClient {
      * @return R
      */
     @PostMapping(value = SEND_MESSAGE, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
-    R<BladeFile> addFileInfo(@RequestPart MultipartFile file);
+    R<BladeFile> addFileInfo(@RequestPart("file") MultipartFile file);
 
     /**
      * // 根据文件路径,获取当前路径下所有文件的大小

+ 4 - 1
blade-ops/blade-resource/src/main/java/org/springblade/resource/builder/oss/AmazonS3OssBuilder.java

@@ -31,6 +31,7 @@ import org.springblade.core.oss.S3Template;
 import org.springblade.core.oss.props.OssProperties;
 import org.springblade.core.oss.rule.OssRule;
 import org.springblade.core.tool.utils.StringUtil;
+import org.springblade.resource.builder.ossre.S3Template2;
 import org.springblade.resource.entity.Oss;
 
 /**
@@ -62,7 +63,9 @@ public class AmazonS3OssBuilder {
 			.withClientConfiguration(clientConfiguration)
 			.withCredentials(new AWSStaticCredentialsProvider(credentials))
 			.build();
-		return new S3Template(amazonS3, ossRule, ossProperties);
+
+
+		return new S3Template2(amazonS3, ossRule, ossProperties);
 
 	}
 

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

@@ -98,6 +98,7 @@ public class OssBuilder {
                 oss.setEndpoint("https://xinan1.zos.ctyun.cn");
             }
         }
+		System.out.println("oss111="+oss.getEndpoint());
 		Oss ossCached = ossPool.get(tenantId);
 		OssTemplate template = templatePool.get(tenantId);
 		// 若为空或者不一致,则重新加载

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

@@ -0,0 +1,528 @@
+/*
+ *      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.resource.builder.ossre;
+
+import com.amazonaws.services.s3.AmazonS3;
+import com.amazonaws.services.s3.model.*;
+import lombok.AllArgsConstructor;
+import lombok.SneakyThrows;
+import org.springblade.core.oss.OssTemplate;
+import org.springblade.core.oss.enums.PolicyType;
+import org.springblade.core.oss.model.BladeFile;
+import org.springblade.core.oss.model.OssFile;
+import org.springblade.core.oss.props.OssProperties;
+import org.springblade.core.oss.rule.OssRule;
+import org.springblade.core.tool.utils.Func;
+import org.springblade.core.tool.utils.StringPool;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.InputStream;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+/**
+ * S3Template
+ *
+ * @author fanjia2
+ * @version 1.0.0
+ * @ClassName S3Template.java
+ * @Description Aws {@link S3Template2 的代码实现}
+ * @createTime 2022年07月04日 11:17:00
+ */
+@AllArgsConstructor
+public class S3Template2 implements OssTemplate {
+
+
+	/**
+	 * S3客户端
+	 */
+	private final AmazonS3 client;
+
+	/**
+	 * 存储桶命名规则
+	 */
+	private final OssRule ossRule;
+
+	/**
+	 * 配置类
+	 */
+	private final OssProperties ossProperties;
+
+	/**
+	 * 创建 存储桶
+	 *
+	 * @param bucketName 存储桶名称
+	 */
+	@Override
+	public void makeBucket(String bucketName) {
+		if (
+			!client.doesBucketExistV2(
+				getBucketName(bucketName)
+			)
+		) {
+			client.createBucket(
+				getBucketName(bucketName));
+			client.setBucketPolicy(new SetBucketPolicyRequest(getBucketName(bucketName), getPolicyType(getBucketName(bucketName), PolicyType.READ)));
+		}
+	}
+
+	@SneakyThrows
+	public Bucket getBucket() {
+		return getBucket(getBucketName());
+	}
+
+	@SneakyThrows
+	public Bucket getBucket(String bucketName) {
+		Optional<Bucket> bucketOptional = client.listBuckets().stream().filter(bucket -> bucket.getName().equals(getBucketName(bucketName))).findFirst();
+		return bucketOptional.orElse(null);
+	}
+
+	@SneakyThrows
+	public List<Bucket> listBuckets() {
+		return client.listBuckets();
+	}
+
+	/**
+	 * 删除 存储桶
+	 *
+	 * @param bucketName 存储桶名称
+	 */
+	@Override
+	public void removeBucket(String bucketName) {
+		client.deleteBucket(new DeleteBucketRequest(getBucketName(bucketName)));
+	}
+
+	/**
+	 * 存储桶是否存在
+	 *
+	 * @param bucketName 存储桶名称
+	 * @return boolean
+	 */
+	@Override
+	public boolean bucketExists(String bucketName) {
+		return client.doesBucketExistV2(
+			getBucketName(bucketName));
+	}
+
+	/**
+	 * 拷贝文件
+	 *
+	 * @param bucketName     存储桶名称
+	 * @param fileName       存储桶文件名称
+	 * @param destBucketName 目标存储桶名称
+	 */
+	@Override
+	public void copyFile(String bucketName, String fileName, String destBucketName) {
+		copyFile(bucketName, fileName, destBucketName, fileName);
+
+	}
+
+	/**
+	 * 拷贝文件
+	 *
+	 * @param bucketName     存储桶名称
+	 * @param fileName       存储桶文件名称
+	 * @param destBucketName 目标存储桶名称
+	 * @param destFileName   目标存储桶文件名称
+	 */
+	@Override
+	public void copyFile(String bucketName, String fileName, String destBucketName, String destFileName) {
+
+		client.copyObject(new CopyObjectRequest(getBucketName(bucketName), fileName, getBucketName(destBucketName), destFileName));
+
+	}
+
+	/**
+	 * 获取文件信息
+	 *
+	 * @param fileName 存储桶文件名称
+	 * @return InputStream
+	 */
+	@Override
+	public OssFile statFile(String fileName) {
+		return statFile(ossProperties.getBucketName(), fileName);
+	}
+
+	/**
+	 * 获取文件信息
+	 *
+	 * @param bucketName 存储桶名称
+	 * @param fileName   存储桶文件名称
+	 * @return InputStream
+	 */
+	@Override
+	public OssFile statFile(String bucketName, String fileName) {
+		S3Object stat = client.getObject(new GetObjectRequest(getBucketName(bucketName), fileName));
+		OssFile ossFile = new OssFile();
+		ossFile.setName(Func.isEmpty(stat.getKey()) ? fileName : stat.getKey());
+		ossFile.setLink(fileLink(ossFile.getName()));
+		ossFile.setHash(String.valueOf(stat.hashCode()));
+		ossFile.setLength(stat.getObjectMetadata().getContentLength());
+		ossFile.setPutTime(stat.getObjectMetadata().getLastModified());
+		ossFile.setContentType(stat.getObjectMetadata().getContentType());
+		return ossFile;
+	}
+
+	/**
+	 * 获取文件信息
+	 *
+	 * @param fileName 存储桶文件名称
+	 * @return InputStream
+	 */
+	@Override
+	public InputStream statFileStream(String fileName) {
+		return statFileStream(getBucketName(), fileName);
+	}
+
+	/**
+	 * 获取文件信息
+	 *
+	 * @param bucketName 存储桶名称
+	 * @param fileName   存储桶文件名称
+	 * @return InputStream
+	 */
+	@Override
+	public InputStream statFileStream(String bucketName, String fileName) {
+		return client.getObject(new GetObjectRequest(getBucketName(bucketName), fileName)).getObjectContent();
+	}
+
+	/**
+	 * 获取文件相对路径
+	 *
+	 * @param fileName 存储桶对象名称
+	 * @return String
+	 */
+	@Override
+	public String filePath(String fileName) {
+		return getBucketName().concat(StringPool.SLASH).concat(fileName);
+	}
+
+	/**
+	 * 获取文件相对路径
+	 *
+	 * @param bucketName 存储桶名称
+	 * @param fileName   存储桶对象名称
+	 * @return String
+	 */
+	@Override
+	public String filePath(String bucketName, String fileName) {
+		return getBucketName(bucketName).concat(StringPool.SLASH).concat(fileName);
+	}
+
+	/**
+	 * 获取文件地址
+	 *
+	 * @param fileName 存储桶对象名称
+	 * @return String
+	 */
+	@Override
+	@SneakyThrows
+	public String fileLink(String fileName) {
+		String url = ossProperties.getEndpoint().concat(StringPool.SLASH).concat(getBucketName()).concat(StringPool.SLASH).concat(fileName);
+		if(url.indexOf("100.86.2.1:80/blade-oss-chongqing/")>=0){
+			url = url.replace("http://100.86.2.1:80/blade-oss-chongqing/","https://xinan1.zos.ctyun.cn/blade-oss-chongqing/");
+			System.out.println("123123123==2==转化结束");
+		}
+		return url;
+	}
+
+	/**
+	 * 获取文件地址
+	 *
+	 * @param bucketName 存储桶名称
+	 * @param fileName   存储桶对象名称
+	 * @return String
+	 */
+	@Override
+	@SneakyThrows
+	public String fileLink(String bucketName, String fileName) {
+		String url = ossProperties.getEndpoint().concat(StringPool.SLASH).concat(getBucketName(bucketName)).concat(StringPool.SLASH).concat(fileName);
+		if(url.indexOf("100.86.2.1:80/blade-oss-chongqing/")>=0){
+			url = url.replace("http://100.86.2.1:80/blade-oss-chongqing/","https://xinan1.zos.ctyun.cn/blade-oss-chongqing/");
+			System.out.println("123123123==1==转化结束");
+		}
+		return url;
+	}
+
+	/**
+	 * 上传文件
+	 *
+	 * @param file 上传文件类
+	 * @return BladeFile
+	 */
+	@Override
+	@SneakyThrows
+	public BladeFile putFile(MultipartFile file) {
+		return putFile(ossProperties.getBucketName(), file.getOriginalFilename(), file);
+	}
+
+	/**
+	 * 上传文件
+	 *
+	 * @param fileName 上传文件名
+	 * @param file     上传文件类
+	 * @return BladeFile
+	 */
+	@Override
+	@SneakyThrows
+	public BladeFile putFile(String fileName, MultipartFile file) {
+		return putFile(ossProperties.getBucketName(), fileName, file);
+	}
+
+	/**
+	 * 上传文件
+	 *
+	 * @param bucketName 存储桶名称
+	 * @param fileName   上传文件名
+	 * @param file       上传文件类
+	 * @return BladeFile
+	 */
+	@Override
+	@SneakyThrows
+	public BladeFile putFile(String bucketName, String fileName, MultipartFile file) {
+		return putFile(bucketName, file.getOriginalFilename(), file.getInputStream());
+	}
+
+	/**
+	 * 上传文件
+	 *
+	 * @param fileName 存储桶对象名称
+	 * @param stream   文件流
+	 * @return BladeFile
+	 */
+	@Override
+	public BladeFile putFile(String fileName, InputStream stream) {
+		return putFile(ossProperties.getBucketName(), fileName, stream);
+	}
+
+	/**
+	 * 上传文件
+	 *
+	 * @param bucketName 存储桶名称
+	 * @param fileName   存储桶对象名称
+	 * @param stream     文件流
+	 * @return BladeFile
+	 */
+	@Override
+	public BladeFile putFile(String bucketName, String fileName, InputStream stream) {
+		return putFile(bucketName, fileName, stream, "application/octet-stream");
+
+	}
+
+	@SneakyThrows
+	public BladeFile putFile(String bucketName, String fileName, InputStream stream, String contentType) {
+		makeBucket(bucketName);
+		String originalName = fileName;
+		ObjectMetadata objectMetadata = new ObjectMetadata();
+		objectMetadata.setContentType(contentType);
+		fileName = getFileName(fileName);
+		PutObjectRequest putObst = new PutObjectRequest(getBucketName(bucketName), fileName, stream, objectMetadata);
+
+		putObst.setCannedAcl(CannedAccessControlList.PublicReadWrite);
+		putObst.getRequestClientOptions().setReadLimit(1024 * 1024 * 1000);
+
+		client.putObject(putObst);
+		BladeFile file = new BladeFile();
+		file.setOriginalName(originalName);
+		file.setName(fileName);
+		file.setDomain(getOssHost(bucketName));
+		file.setLink(fileLink(bucketName, fileName));
+		return file;
+	}
+
+	/**
+	 * 删除文件
+	 *
+	 * @param fileName 存储桶对象名称
+	 */
+	@Override
+	public void removeFile(String fileName) {
+
+		removeFile(ossProperties.getBucketName(), fileName);
+	}
+
+	/**
+	 * 删除文件
+	 *
+	 * @param bucketName 存储桶名称
+	 * @param fileName   存储桶对象名称
+	 */
+	@Override
+	public void removeFile(String bucketName, String fileName) {
+		client.deleteObject(bucketName, fileName);
+	}
+
+	/**
+	 * 批量删除文件
+	 *
+	 * @param fileNames 存储桶对象名称集合
+	 */
+	@Override
+	public void removeFiles(List<String> fileNames) {
+
+		removeFiles(ossProperties.getBucketName(), fileNames);
+	}
+
+	/**
+	 * 批量删除文件
+	 *
+	 * @param bucketName 存储桶名称
+	 * @param fileNames  存储桶对象名称集合
+	 */
+	@Override
+	public void removeFiles(String bucketName, List<String> fileNames) {
+		List<DeleteObjectsRequest.KeyVersion> keyVersions = fileNames.stream().map(DeleteObjectsRequest.KeyVersion::new).collect(Collectors.toList());
+		DeleteObjectsRequest deleteObjectsRequest = new DeleteObjectsRequest(getBucketName());
+		client.deleteObjects(deleteObjectsRequest.withKeys(keyVersions));
+	}
+
+	/**
+	 * 根据规则生成存储桶名称规则
+	 *
+	 * @return String
+	 */
+	private String getBucketName() {
+		return getBucketName(ossProperties.getBucketName());
+	}
+
+	/**
+	 * 根据规则生成存储桶名称规则
+	 *
+	 * @param bucketName 存储桶名称
+	 * @return String
+	 */
+	private String getBucketName(String bucketName) {
+		return ossRule.bucketName(bucketName);
+	}
+
+	/**
+	 * 根据规则生成文件名称规则
+	 *
+	 * @param originalFilename 原始文件名
+	 * @return string
+	 */
+	private String getFileName(String originalFilename) {
+		return ossRule.fileName(originalFilename);
+	}
+
+	/**
+	 * 获取存储桶策略
+	 *
+	 * @param bucketName 存储桶名称
+	 * @param policyType 策略枚举
+	 * @return String
+	 */
+	public static String getPolicyType(String bucketName, PolicyType policyType) {
+		StringBuilder builder = new StringBuilder();
+		builder.append("{\n");
+		builder.append("    \"Statement\": [\n");
+		builder.append("        {\n");
+		builder.append("            \"Action\": [\n");
+
+		switch (policyType) {
+			case WRITE:
+				builder.append("                \"s3:GetBucketLocation\",\n");
+				builder.append("                \"s3:ListBucketMultipartUploads\"\n");
+				break;
+			case READ_WRITE:
+				builder.append("                \"s3:GetBucketLocation\",\n");
+				builder.append("                \"s3:ListBucket\",\n");
+				builder.append("                \"s3:ListBucketMultipartUploads\"\n");
+				break;
+			default:
+				builder.append("                \"s3:GetBucketLocation\"\n");
+				break;
+		}
+
+		builder.append("            ],\n");
+		builder.append("            \"Effect\": \"Allow\",\n");
+		builder.append("            \"Principal\": \"*\",\n");
+		builder.append("            \"Resource\": \"arn:aws:s3:::");
+		builder.append(bucketName);
+		builder.append("\"\n");
+		builder.append("        },\n");
+		if (PolicyType.READ.equals(policyType)) {
+			builder.append("        {\n");
+			builder.append("            \"Action\": [\n");
+			builder.append("                \"s3:ListBucket\"\n");
+			builder.append("            ],\n");
+			builder.append("            \"Effect\": \"Deny\",\n");
+			builder.append("            \"Principal\": \"*\",\n");
+			builder.append("            \"Resource\": \"arn:aws:s3:::");
+			builder.append(bucketName);
+			builder.append("\"\n");
+			builder.append("        },\n");
+
+		}
+		builder.append("        {\n");
+		builder.append("            \"Action\": ");
+
+		switch (policyType) {
+			case WRITE:
+				builder.append("[\n");
+				builder.append("                \"s3:AbortMultipartUpload\",\n");
+				builder.append("                \"s3:DeleteObject\",\n");
+				builder.append("                \"s3:ListMultipartUploadParts\",\n");
+				builder.append("                \"s3:PutObject\"\n");
+				builder.append("            ],\n");
+				break;
+			case READ_WRITE:
+				builder.append("[\n");
+				builder.append("                \"s3:AbortMultipartUpload\",\n");
+				builder.append("                \"s3:DeleteObject\",\n");
+				builder.append("                \"s3:GetObject\",\n");
+				builder.append("                \"s3:ListMultipartUploadParts\",\n");
+				builder.append("                \"s3:PutObject\"\n");
+				builder.append("            ],\n");
+				break;
+			default:
+				builder.append("\"s3:GetObject\",\n");
+				break;
+		}
+
+		builder.append("            \"Effect\": \"Allow\",\n");
+		builder.append("            \"Principal\": \"*\",\n");
+		builder.append("            \"Resource\": \"arn:aws:s3:::");
+		builder.append(bucketName);
+		builder.append("/*\"\n");
+		builder.append("        }\n");
+		builder.append("    ],\n");
+		builder.append("    \"Version\": \"2012-10-17\"\n");
+		builder.append("}\n");
+		return builder.toString();
+	}
+
+	/**
+	 * 获取域名
+	 *
+	 * @param bucketName 存储桶名称
+	 * @return String
+	 */
+	public String getOssHost(String bucketName) {
+		return ossProperties.getEndpoint() + StringPool.SLASH + getBucketName(bucketName);
+	}
+
+	/**
+	 * 获取域名
+	 *
+	 * @return String
+	 */
+	public String getOssHost() {
+		return getOssHost(ossProperties.getBucketName());
+	}
+}

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

@@ -283,10 +283,10 @@ public class LargeFileEndpoint {
             BladeFile bladeFile = ossBuilder.template().putFile(param.getFilename(), inputStream);
 //            File file1 = new File(filePath + param.getFilename());
             File file1 = new File(path);
-            MultipartFile multipartFile = getMultipartFile(file1);
+
             if (param.getFilename().contains("pdf") || param.getFilename().contains("PDF")) {
                 try {
-                    PdfReader pdfReader = new PdfReader(multipartFile.getInputStream());
+                    PdfReader pdfReader = new PdfReader(inputStream);
                     int pages = pdfReader.getNumberOfPages();
                     //获取文件页数
                     newBladeFile.setPage(pages);
@@ -296,14 +296,17 @@ public class LargeFileEndpoint {
                 //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);
+            newBladeFile.setFileSize(file1.length() / 1024);
             //删除本地文件
             file1.delete();
             iLargeFileService.updateLargeFileDeleted(param.getIdentifier());

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

@@ -119,7 +119,7 @@ public class Task extends BaseEntity {
     private Integer type;
 
     /**
-     * 上报类型,1填报资料,2工程文件
+     * 上报类型, 1=填报数据(质量填报) 2=工程文件(档案) 3=日志资料  4=档案数据   5=计量支付证书  6=计量 材料预付款  7= 计量 中间支付  8委托单 9试验上报 10 首件上报 11变更令
      */
     @ApiModelProperty("上报类型,1填报资料,2工程文件,3日志资料,4档案,5计量")
     private Integer approvalType;

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

@@ -39,4 +39,7 @@ public class ScrSignInfoVO implements Serializable {
     @ApiModelProperty("电签状态 1待审批 2已审批 3废除")
     private String status;
 
+    @ApiModelProperty("电签状态 1待审批 2已审批 3废除")
+    private String taskId;
+
 }

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

@@ -110,6 +110,11 @@ public class SealStrategyVO {
      */
     private String family;
 
+    /**
+     * 项目Id
+     */
+    private String projectId;
+
     /**
      * 为null时,电签接口默认设为0。
      * 采用坐标定位签章位置时

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

@@ -7,8 +7,10 @@ import org.springblade.core.tool.api.R;
 import org.springblade.manager.entity.ExcelTab;
 import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
 
 import java.io.IOException;
+import java.io.InputStream;
 import java.util.List;
 
 import static org.springblade.core.launch.constant.AppConstant.APPLICATION_NAME_PREFIX;
@@ -73,4 +75,13 @@ public interface ExcelTabClient {
 
     @GetMapping(API_PREFIX + "/pre-buss-pdfs")
     R getPdfS(@RequestParam String nodeId, @RequestParam String classify, @RequestParam String contractId) throws IOException;
+
+    @PostMapping(API_PREFIX + "/saveOrUpdate")
+    void saveOrUpdate(@RequestBody ExcelTab detail);
+
+    @PostMapping(API_PREFIX + "/expailHtmlInfo")
+    void expailHtmlInfo(@RequestParam String thmlUrl, @RequestParam Long id, @RequestParam String s) throws Exception;
+
+    @PostMapping(API_PREFIX + "/excelInfo")
+    void excelInfo(@RequestParam InputStream inputStream, @RequestParam String exceUrl, @RequestParam String thmlUrl, @RequestParam String number);
 }

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

@@ -10,8 +10,10 @@ import org.springblade.manager.entity.ExcelTab;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.stereotype.Component;
+import org.springframework.web.multipart.MultipartFile;
 
 import java.io.IOException;
+import java.io.InputStream;
 import java.util.List;
 
 @Component
@@ -73,4 +75,21 @@ public class ExcelTabClientFallBack implements ExcelTabClient {
     public R getPdfS(String nodeId, String classify, String contractId) throws IOException {
         return null;
     }
+
+    @Override
+    public void saveOrUpdate(ExcelTab detail) {
+
+    }
+
+    @Override
+    public void expailHtmlInfo(String thmlUrl, Long id, String s) throws Exception {
+
+    }
+
+    @Override
+    public void excelInfo(InputStream inputStream, String exceUrl, String thmlUrl, String number) {
+
+    }
+
+
 }

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

@@ -17,6 +17,7 @@ import org.springblade.business.feign.ArchiveFileClient;
 import org.springblade.business.feign.MetadataClassificationClient;
 import org.springblade.business.vo.ArchiveFileVO;
 import org.springblade.business.vo.MetadataClassificationVO;
+import org.springblade.common.utils.CommonUtil;
 import org.springblade.common.utils.SnowFlakeUtil;
 import org.springblade.core.boot.ctrl.BladeController;
 
@@ -29,6 +30,7 @@ import org.springblade.manager.entity.ContractInfo;
 import org.springblade.manager.feign.ArchiveTreeContractClient;
 import org.springblade.manager.feign.ContractClient;
 import org.springblade.manager.feign.WbsTreeContractClient;
+import org.springblade.resource.feign.CommonFileClient;
 import org.springblade.resource.feign.IOSSClient;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
@@ -61,7 +63,7 @@ public class ArchiveFileController extends BladeController {
     private final ContractClient contractClient;
     private final MetadataClassificationClient metadataClassificationClient;
     private final IArchivesAutoService autoService;
-
+    private final CommonFileClient commonFileClient;
     /**
      * 上传文件
      *
@@ -95,6 +97,14 @@ public class ArchiveFileController extends BladeController {
             if (saveList != null && saveList.size() > 0) {
                 int i = 1;
                 for (ArchiveFileVO saveVo : saveList) {
+                    try {
+                        if(StringUtils.isNotEmpty(saveVo.getPdfFileUrl())&&saveVo.getPageNum()==null){
+                            String num = commonFileClient.getPdfNum(saveVo.getPdfFileUrl());
+                            saveVo.setFilePage(Integer.valueOf(num));
+                        }
+                    }catch (Exception e){
+                        saveVo.setFilePage(0);
+                    }
                     saveVo.setId(SnowFlakeUtil.getId());
                     saveVo.setSort(l + i);
                     saveVo.setStatus(new Integer("0").equals(saveVo.getIsApproval()) ? 2 : 0);

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

@@ -98,7 +98,11 @@ public class ExternalDataArchiveFileService {
 
             //nodeId nodeSUB
             Long fileNodeId = archiveTreeOutIdMapping.get(archiveFileVo.getNodeId());
-            archiveFile.setNodeId(fileNodeId.toString());
+            if (fileNodeId!= null ){
+                archiveFile.setNodeId(fileNodeId.toString());
+            }else {
+                archiveFile.setNodeId(rootId.toString());
+            }
 
             Long fileNodeExtId = archiveTreeOutIdMapping.get(archiveFileVo.getNodeIdSub());
             if (fileNodeExtId!= null ) {
@@ -167,6 +171,8 @@ public class ExternalDataArchiveFileService {
         // 字符串严格比较:格式或内容不同即视为不一致
         return !Objects.equals(extUtimeStr, localUtimeStr)
                 || !Objects.equals(external.getPdfPageUrl(), local.getPdfPageUrl());
+                //|| !Objects.equals(external.getArchiveId(), local.getArchiveId());
+
     }
 
     /**
@@ -184,6 +190,7 @@ public class ExternalDataArchiveFileService {
         local.setFilePage(external.getFilePage());
         local.setFileSize(external.getFileSize());
         local.setUtime(external.getUtime());
+        //local.setArchiveId(external.getArchiveId());
     }
 
 

+ 202 - 3
blade-service/blade-archive/src/main/java/org/springblade/archive/external/utils/TransUtil.java

@@ -19,10 +19,209 @@ public class TransUtil {
     public static final Map<String, Long> EXTERNAL_TO_INTERNAL_NODE_ID_MAP = new LinkedHashMap<String, Long>() {{
         // 初始化默认映射关系(可按需添加)
 
-        //第四合同段 -1.施工项目部组建、印章启用、人员任命文件,进场人员资质报审文件,施工设备仪器进场报审文件、设备仪器校验、率定文件
-        put("0b0ac82851d7484bba414bb1ccbd", 1892759789415432263L);
-        //机电标 施工工序
+        //=================建设单位
+        //军教工验收文件
+        put("3b843c05e00c4b65a1e666db80cf", 1892759789381877760L);
+
+        //征地拆迁
+        put("ced7daa78cc040d1b731dfedd51f", 1892759789381877780L);
+
+        //工程文件
+        put("e18bd5c3b1f7489b87d27594dee9", 1892759789381877794L);
+
+        //决算和审计文件
+        put("442e7e595dce411abd984da1866d", 1892759789381877811L);
+
+        //====监理
+        //=========第一总监
+        //印章启用文件、监理人员变更的函和批复文件
+        put("465c2ebad85e44e9b4217d7ae415", 1892759789402849282L);
+        //工程监理月报(2022年1月至2023年2月)
+        put("ffce00c9bd7443d9b3d6ef63f885", 1902189729003851778L);
+        //监理日志(张换丽)
+        put("6e7ad41e5cd542f893a69ec7cebd", 1902189935200030722L);
+        //监理日志(钟兆革)
+        put("8d818ccbf39247cbb1f49ed3c7b0", 1902190429066743809L);
+
+        //原材料、设备及构件试验报告、记录 1902201113984880642
+        put("89aaa0372cc24d14b3efdd788141", 1902200995105722370L);
+
+
+        //试验检测汇总表
+        put("0b023c2125664791a0511fc587f8", 1902205006567428097L);
+        //原材料、半成品、成品报告
+        put("bbc75d54e5d14b1f8368ce6fb51f", 1902206555712638977L);
+        //机械连接、焊接报告
+        put("402d59509f78443b88923f9c6876", 1902206715393986562L);
+        //土工、配合比
+        put("3650e321d07845e3b1a0a38bc1c2", 1902206873229840386L);
+
+        //监理抽检资料
+        put("5d17cfbfcc134319b3bc2251d1cf", 1892759789402849302L);
+
+        //就安全生产印发的实施方案
+        put("eadf2038639446dcb40c4fe198c8", 1902198126172426241L);
+        //2020年至2023年业主就安全生产检查的通报及整改回复
+        put("9067f2889fbe42d0917f80d20978", 1902198303939612673L);
+
+
+        //=========第二总监
+
+        //原材料、设备及构件试验报告、记录
+        put("6dec0a4c4a8e42a0a2b138e6e4ff", 1902200181465272322L);
+
+
+        put("216663852e784ba1a96a2980d663", 1892759789407043606L);
+
+        //=========第三总监
+        put("05ac2ef4857f468483924d51f90a", 1902638005113028610L);
+
+
+        put("91aee6c9b92e4a10806266fa9513", 1892759789407043641L);
+
+        //=========第四总监
+        put("ad7896d5c0b74d988a02c342928c", 1892759789407043676L);
+
+        //交工验收质量评定
+        put("0679ddcea354420e893a00586737", 1892759789407043678L);
+
+        //管理文件
+        put("c46141f9c8dd4116b056a7db6a2d", 1892759789407043655L);
+        //计划文件
+        put("ae9523597eac403ca8d7eb096840", 1892759789407043679L);
+
+
+        //质量控制措施
+        put("2dafbff0d0ae43bfa6bb64f35cab", 1892759789407043671L);
+        //监理独立抽检
+        put("d1d5d934f6eb45eebb1616816cd5", 1892759789407043672L);
+        //监理独立报告
+        put("3a31de201c604f97a66c02836669", 1892759789407043673L);
+
+        //其他文件
+        put("2ae858ae006443258446ebe892b9", 1892759789407043686L);
+
+        //其他资料
+        put("8c6913b1dacc45fe966a56d2ff56", 1915963769346564097L);
+
+
+        //=========机电标总监
+        put("5b8da50309334dcbb8a02b3339bc", 1892759789407043711L);
+
+
+
+
+
+        //===========施工单位归档资料
+        //=========第四合同段
+          //二工程管理文件
+            //施工准备文件 -1.施工项目部组建、印章启用、人员任命文件,进场人员资质报审文件,施工设备仪器进场报审文件、设备仪器校验、率定文件
+            put("0b0ac82851d7484bba414bb1ccbd", 1892759789415432263L);
+
+            //施工准备文件 -5.工地试验室备案申请表及交通质监部门备案通知书、工地实验室成立、资质、授权
+            put("9144353d740c428ea46ca4228d22", 1892759789415432267L);
+         //三 施工质量控制文件
+            //原材
+            put("54dc995fc9814ecd81f6f25dc936", 1892759789415432282L);
+            //配合比
+             put("5f07af9ef5d14a2781cef179ef7c", 1892759789415432284L);
+            //试验报告
+             put("ffe1d44383ed4f438d29b73b7dbb", 1892759789415432285L);
+             //施工工序资料
+             put("075d3e8a3d48418f959283c55616", 1892759789415432286L);
+         //五 进度控制文件
+          //1 进度计划
+             put("31bc6b0a55cb4c408e292ee0fcdb", 1892759789415432296L);
+
+             //============================
+
+        //=========第三合同段
+            //二工程管理文件
+            //施工准备文件 -1.施工项目部组建、印章启用、人员任命文件,进场人员资质报审文件,施工设备仪器进场报审文件、设备仪器校验、率定文件
+            //put("0b0ac82851d7484bba414bb1ccbd", 1892759789415432263L);
+
+            //三 施工质量控制文件
+            //原材
+            put("da9434c6a86147c0979ef09624dd", 1892759789415432221L);
+            //配合比
+            put("3080795a07544c2c972cc938da1f", 1892759789415432223L);
+            //试验报告
+            //put("ffe1d44383ed4f438d29b73b7dbb", 1892759789415432285L);
+            //施工工序资料
+            put("a1a4ea5ea88549c09c57b6da8e9e", 1892759789415432225L);
+            //五 进度控制文件
+            //1 进度计划
+            //put("31bc6b0a55cb4c408e292ee0fcdb", 1892759789415432296L);
+
+
+        //=========机电标
+        //二工程管理文件
+        //施工准备文件 -1.施工项目部组建、印章启用、人员任命文件,进场人员资质报审文件,施工设备仪器进场报审文件、设备仪器校验、率定文件
+        //put("0b0ac82851d7484bba414bb1ccbd", 1892759789415432263L);
+
+        //三 施工质量控制文
+        //试验报告
+        //put("ffe1d44383ed4f438d29b73b7dbb", 1892759789415432285L);
+        //施工工序资料
         put("8a0aa647278548fa9edba59b78c4", 1892759789419626529L);
+
+
+        //=========第一合同段
+        //二工程管理文件
+        put("3f84d392080e4375b0f3a6467b22", 1892759789411237894L);
+
+        //施工质量文件
+        put("2f1c3a407b64441a83416def6c97", 1892759789411237906L);
+
+        //工地
+        put("f363c765bab44c6082731d529f7f", 1892759789411237916L);
+
+        //仪器
+        put("4ec32cc441394a48a608571a361f", 1892759789411237922L);
+
+        //材料标准试验
+        put("d5b62eb13097434fab99879ed98a", 1915971643921637377L);
+
+        //现场抽检
+        put("426db97ebf1a4de9b28153335342", 1915971747701301249L);
+
+        //安全文明
+        put("ff0f6b6962494df7b7b3f03539b2", 1892759789411237923L);
+
+        //进度管理文件
+        put("4fbcf1973adb481a89a36d8b9898", 1915965348099366914L);
+
+        //变更文件
+        put("2e203ab2574640c2895ac5196204", 1915965498528079873L);
+        //施工原始记录
+        put("f50cb7a3288848a88f99ee87e800", 1915965617583398913L);
+
+        //三 施工质量控制文件
+
+        //评定
+        put("1984907813174e698cb7d473911d", 1892759789411237907L);
+        //原材
+        put("4620774da89544e7b8d815d65c01", 1892759789411237917L);
+        //各种试验报告
+        put("1929194d06794a6a940a761561f9", 1892759789411237920L);
+        //配合比
+        put("c05b1ab104f44875b264c52e81eb", 1892759789411237919L);
+        //试验报告
+        //put("ffe1d44383ed4f438d29b73b7dbb", 1892759789415432285L);
+        //施工工序资料
+        put("a22abc54ff8446e59760309263f7", 1892759789411237921L);
+
+
+        //=========第二合同段
+        //二工程管理文件
+
+        //三 施工质量控制文件
+        //原材
+        put("87edcc42ba2b4859a1aec5191080", 1892759789411237978L);
+
+        //施工工序资料
+        put("4707eb84188443b481398a15e8cf", 1892759789411237982L);
+
     }};
 
 

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

@@ -175,6 +175,12 @@
             <version>2.9.1.RELEASE</version>
             <scope>compile</scope>
         </dependency>
+        <dependency>
+            <groupId>org.apache.pdfbox</groupId>
+            <artifactId>pdfbox</artifactId>
+            <version>2.0.24</version>
+            <scope>compile</scope>
+        </dependency>
     </dependencies>
 
     <build>
@@ -188,7 +194,7 @@
                     <target>${java.version}</target>
                     <encoding>${project.build.sourceEncoding}</encoding>
                     <compilerArguments>
-                        <bootclasspath>${java.home}/lib/rt.jar;${java.home}/lib/jce.jar;${java.home}/lib/jsse.jar
+                        <bootclasspath>${java.home}/lib/rt.jar:${java.home}/lib/jce.jar:${java.home}/lib/jsse.jar
                         </bootclasspath>
                     </compilerArguments>
                 </configuration>

+ 438 - 0
blade-service/blade-business/src/main/java/org/springblade/business/chekPdf/PdfAddimgUtil.java

@@ -0,0 +1,438 @@
+package org.springblade.business.chekPdf;
+
+import com.itextpdf.text.BaseColor;
+import com.itextpdf.text.Element;
+import com.itextpdf.text.Image;
+import com.itextpdf.text.Rectangle;
+import com.itextpdf.text.pdf.*;
+import com.itextpdf.text.pdf.parser.*;
+import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.text.PDFTextStripper;
+import org.springblade.common.constant.CommonConstant;
+import org.springblade.common.utils.CommonUtil;
+import org.springblade.core.tool.utils.Func;
+import org.springblade.evisa.vo.SignKeyVO;
+import org.springblade.manager.vo.PDFIndexInfo;
+import org.springblade.system.cache.ParamCache;
+
+import java.io.*;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+public class PdfAddimgUtil {
+
+    public static void pdfAddImgInfo(String pdfUrl, List<Map<String, Object>> data) throws Exception {
+        File pdfFile = new File(pdfUrl);
+        byte[] pdfData = new byte[(int) pdfFile.length()];
+        FileInputStream inputStream = null;
+        try {
+            inputStream = new FileInputStream(pdfFile);
+            inputStream.read(pdfData);
+        } catch (IOException e) {
+            throw e;
+        } finally {
+            if (inputStream != null) {
+                try {
+                    inputStream.close();
+                } catch (IOException e) {
+                    inputStream.close();
+                }
+            }
+        }
+
+        String keyword = data.stream().map(map -> map.get("id")+"").collect(Collectors.joining(","));
+        //根据map中的key分组
+        Map<Object, List<Map<String, Object>>> map = data.stream().collect(Collectors.groupingBy(item -> item.get("id")));
+
+        List<PDFIndexInfo> positions = findKeywordPostions(pdfData, keyword);
+
+        System.out.println("total:" + positions.size());
+        if (positions != null && positions.size() > 0) {
+
+            for (int i = 0; i < positions.size(); i++) {
+                PDFIndexInfo pdfIndexInfo = positions.get(i);
+                float[] position = pdfIndexInfo.getDataInfo();
+                List<Map<String, Object>> textdictInfo= map.get(Func.toLong(pdfIndexInfo.getPkeyid()));
+                float pyzbx = 0;
+                float pyzby = 0;
+                String type ="2";
+                String signImg = "";
+                if(textdictInfo!=null){
+                    pyzbx = Func.toFloat(textdictInfo.get(0).get("pyzbx"));
+                    pyzby = Func.toFloat(textdictInfo.get(0).get("pyzby"));
+                    signImg = textdictInfo.get(0).get("signature_file_url")+"";
+                }
+                gaizhang(pdfFile, new File(pdfUrl), (int) position[0], position[1], position[2], signImg,pyzbx,pyzby,type);
+            }
+        }
+    }
+
+    public static void gaizhang(File src, File dest, int page, float x, float y, String imagePath,float pyzbx,float pyzby,String type) throws Exception {
+        // 读取模板文件
+        InputStream input = new FileInputStream(src);
+        PdfReader reader = new PdfReader(input);
+        PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
+        Rectangle pageSize = reader.getPageSize(page);
+        float height = pageSize.getHeight();
+        float width = pageSize.getWidth();
+        if(type.equals("6")){
+            x = width * x - 27+pyzbx;
+            y = height - height * y - 30+pyzby;
+            imagePath = "/Users/hongchuangyanfa/Desktop/print/ht1234567890.png";
+        }else{
+            x = width * x - 33+pyzbx;
+            y = height - height * y - 12+pyzby;
+        }
+
+        // 读图片
+        Image image = Image.getInstance(imagePath);
+
+        // 获取操作的页面
+        PdfContentByte under = stamper.getOverContent(page);
+        // 添加图片
+
+        // 设置图片的新宽度和高度
+        float newWidth = 75f; // 新的宽度
+        float newHeight = image.getScaledHeight() * (newWidth / image.getScaledWidth()); // 根据宽度计算高度
+        image.scaleAbsolute(newWidth, newHeight); // 设置图片的新尺寸
+        //调整图片尺寸
+        image.setAbsolutePosition(x, y);
+        under.addImage(image);
+        // 假设的under.addImage方法,需要传入图片路径和大小参数
+        stamper.close();
+        reader.close();
+    }
+
+    /**
+     * 【功能描述:添加图片和文字水印】 【功能详细描述:功能详细描述】
+     *
+     * @param srcFile    待加水印文件
+     * @param destFile   加水印后存放地址
+     * @param text       加水印的文本内容
+     * @param textWidth  文字横坐标
+     * @param textHeight 文字纵坐标
+     * @throws Exception
+     */
+    public void addWaterMark(String srcFile, String destFile, String text,
+                             int textWidth, int textHeight) throws Exception {
+        // 待加水印的文件
+        PdfReader reader = new PdfReader(srcFile);
+        // 加完水印的文件
+        PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(
+                destFile));
+        int total = reader.getNumberOfPages() + 1;
+        PdfContentByte content;
+        // 设置字体
+        BaseFont font = BaseFont.createFont();
+        // 循环对每页插入水印
+        for (int i = 1; i < total; i++) {
+            // 水印的起始
+            content = stamper.getUnderContent(i);
+            // 开始
+            content.beginText();
+            // 设置颜色 默认为蓝色
+            content.setColorFill(BaseColor.BLUE);
+            // content.setColorFill(Color.GRAY);
+            // 设置字体及字号
+            content.setFontAndSize(font, 38);
+            // 设置起始位置
+            // content.setTextMatrix(400, 880);
+            content.setTextMatrix(textWidth, textHeight);
+            // 开始写入水印
+            content.showTextAligned(Element.ALIGN_LEFT, text, textWidth,
+                    textHeight, 45);
+            content.endText();
+        }
+        stamper.close();
+    }
+
+    /**
+     * findKeywordPostions
+     *
+     * @param pdfData
+     * @param keyword
+     * @return List<float [ ]> : float[0]:pageNum float[1]:x float[2]:y
+     * @throws IOException
+     */
+    public static List<PDFIndexInfo> findKeywordPostions(byte[] pdfData,
+                                                    String keyword) throws IOException {
+        List<PDFIndexInfo> result = new ArrayList<PDFIndexInfo>();
+        List<PdfPageContentPositions> pdfPageContentPositions = getPdfContentPostionsList(pdfData);
+
+        for (PdfPageContentPositions pdfPageContentPosition : pdfPageContentPositions) {
+            List<PDFIndexInfo> charPositions = findPositions(keyword,
+                    pdfPageContentPosition);
+            if (charPositions == null || charPositions.size() < 1) {
+                continue;
+            }
+            result.addAll(charPositions);
+        }
+        return result;
+    }
+
+
+    /**
+     * findKeywordPostions
+     *
+     * @param pdfData
+     * @return List<float [ ]> : float[0]:pageNum float[1]:x float[2]:y
+     * @throws IOException
+     */
+    public static List<PDFIndexInfo> findAllwordPostions(byte[] pdfData) throws IOException {
+        List<PDFIndexInfo> result = new ArrayList<PDFIndexInfo>();
+        List<PdfPageContentPositions> pdfPageContentPositions = getPdfContentPostionsList(pdfData);
+
+        for (PdfPageContentPositions pdfPageContentPosition : pdfPageContentPositions) {
+            PDFIndexInfo pdfIndexInfo = new PDFIndexInfo();
+            pdfIndexInfo.setListData(pdfPageContentPosition.getPositions());
+            pdfIndexInfo.setPkeyid(pdfPageContentPosition.getContent());
+            result.add(pdfIndexInfo);
+        }
+        return result;
+    }
+
+
+    static List<PdfPageContentPositions> getPdfContentPostionsList(
+            byte[] pdfData) throws IOException {
+        PdfReader reader = new PdfReader(pdfData);
+
+        List<PdfPageContentPositions> result = new ArrayList<PdfPageContentPositions>();
+
+        int pages = reader.getNumberOfPages();
+        for (int pageNum = 1; pageNum <= pages; pageNum++) {
+            float width = reader.getPageSize(pageNum).getWidth();
+            float height = reader.getPageSize(pageNum).getHeight();
+
+            PdfRenderListener pdfRenderListener = new PdfRenderListener(
+                    pageNum, width, height);
+
+            // 解析pdf,定位位置
+            PdfContentStreamProcessor processor = new PdfContentStreamProcessor(
+                    pdfRenderListener);
+            PdfDictionary pageDic = reader.getPageN(pageNum);
+            PdfDictionary resourcesDic = pageDic.getAsDict(PdfName.RESOURCES);
+            try {
+                processor.processContent(ContentByteUtils
+                        .getContentBytesForPage(reader, pageNum), resourcesDic);
+            } catch (IOException e) {
+                reader.close();
+                throw e;
+            }
+
+            String content = pdfRenderListener.getContent();
+            List<CharPosition> charPositions = pdfRenderListener
+                    .getcharPositions();
+
+            List<float[]> positionsList = new ArrayList<float[]>();
+            for (CharPosition charPosition : charPositions) {
+                float[] positions = new float[]{charPosition.getPageNum(),
+                        charPosition.getX(), charPosition.getY()};
+                positionsList.add(positions);
+            }
+
+            PdfPageContentPositions pdfPageContentPositions = new PdfPageContentPositions();
+            pdfPageContentPositions.setContent(content);
+            pdfPageContentPositions.setPostions(positionsList);
+
+            result.add(pdfPageContentPositions);
+        }
+        reader.close();
+        return result;
+    }
+
+
+    private static List<PDFIndexInfo> findPositions(String keyword,
+                                                    PdfPageContentPositions pdfPageContentPositions) {
+
+        List<PDFIndexInfo> result =new ArrayList<>();
+        String content = pdfPageContentPositions.getContent();
+        List<float[]> charPositions = pdfPageContentPositions.getPositions();
+
+        List<String> strList = Func.toStrList(keyword);
+        for (String text : strList) {
+            for (int pos = 0; pos < content.length(); ) {
+                PDFIndexInfo data= new PDFIndexInfo();
+                int positionIndex = content.indexOf(text, pos);
+                if (positionIndex == -1) {
+                    break;
+                }
+
+                float[] postions = charPositions.get(positionIndex);
+                data.setDataInfo(postions);
+                data.setPkeyid(text);
+                result.add(data);
+                pos = positionIndex + 1;
+            }
+        }
+        return result;
+    }
+
+
+    private static class PdfPageContentPositions {
+        private String content;
+        private List<float[]> positions;
+
+        public String getContent() {
+            return content;
+        }
+
+        public void setContent(String content) {
+            this.content = content;
+        }
+
+        public List<float[]> getPositions() {
+            return positions;
+        }
+
+        public void setPostions(List<float[]> positions) {
+            this.positions = positions;
+        }
+    }
+
+    private static class PdfRenderListener implements RenderListener {
+        private int pageNum;
+        private float pageWidth;
+        private float pageHeight;
+        private StringBuilder contentBuilder = new StringBuilder();
+        private List<CharPosition> charPositions = new ArrayList<CharPosition>();
+
+        public PdfRenderListener(int pageNum, float pageWidth, float pageHeight) {
+            this.pageNum = pageNum;
+            this.pageWidth = pageWidth;
+            this.pageHeight = pageHeight;
+        }
+
+        @Override
+        public void beginTextBlock() {
+
+        }
+
+        @Override
+        public void renderText(TextRenderInfo renderInfo) {
+            List<TextRenderInfo> characterRenderInfos = renderInfo
+                    .getCharacterRenderInfos();
+            for (TextRenderInfo textRenderInfo : characterRenderInfos) {
+                String word = textRenderInfo.getText();
+                if (word.length() > 1) {
+                    word = word.substring(word.length() - 1, word.length());
+                }
+                com.itextpdf.awt.geom.Rectangle2D.Float rectangle = textRenderInfo.getAscentLine()
+                        .getBoundingRectange();
+                double x = rectangle.getMinX();
+                double y = rectangle.getMaxY();
+
+                float xPercent = Math.round(x / pageWidth * 10000) / 10000f;
+                float yPercent = Math.round((1 - y / pageHeight) * 10000) / 10000f;//
+
+                CharPosition charPosition = new CharPosition(pageNum, xPercent,
+                        yPercent);
+                charPositions.add(charPosition);
+                contentBuilder.append(word);
+            }
+        }
+
+        @Override
+        public void endTextBlock() {
+
+        }
+
+        @Override
+        public void renderImage(ImageRenderInfo renderInfo) {
+
+        }
+
+        public String getContent() {
+            return contentBuilder.toString();
+        }
+
+        public List<CharPosition> getcharPositions() {
+            return charPositions;
+        }
+    }
+
+    private static class CharPosition {
+        private int pageNum = 0;
+        private float x = 0;
+        private float y = 0;
+
+        public CharPosition(int pageNum, float x, float y) {
+            this.pageNum = pageNum;
+            this.x = x;
+            this.y = y;
+        }
+
+        public int getPageNum() {
+            return pageNum;
+        }
+
+        public float getX() {
+            return x;
+        }
+
+        public float getY() {
+            return y;
+        }
+
+        @Override
+        public String toString() {
+            return "[pageNum=" + this.pageNum + ",x=" + this.x + ",y=" + this.y
+                    + "]";
+        }
+    }
+
+    public static String getNetUrl(String fileUrl){
+        String file_path = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
+        String sys_file_net_url = ParamCache.getValue(CommonConstant.SYS_FILE_NET_URL);
+        String path = sys_file_net_url + fileUrl.replaceAll("//", "/").replaceAll(file_path, "");
+        return path;
+    }
+
+
+    public static SignKeyVO getPdfSignIds(String pdfUrl) {
+        SignKeyVO signKeyVO = new SignKeyVO();
+        List<String> eVisaConfigList = new ArrayList<>();
+        Map<String,String> dataMap = new HashMap<>();
+        InputStream inputStream;
+        try  {
+            if(pdfUrl.indexOf("http")>=0){
+                inputStream = CommonUtil.getOSSInputStream(pdfUrl);
+            }else{
+                inputStream = new FileInputStream(new File(pdfUrl));
+            }
+            PDDocument document = PDDocument.load(inputStream);
+            PDFTextStripper stripper = new PDFTextStripper();
+            String text = stripper.getText(document);
+            String[] lines = text.split("[ \\n]+");
+            for(int k=0;k<lines.length;k++){
+                String textStr = lines[k];
+                if(textStr.indexOf("*")>=0){
+                    textStr = textStr.substring(textStr.lastIndexOf("*")+1,textStr.length());
+                }
+                String[] textS = Func.toStrArray("\\|\\|",textStr);
+                for(String txt : textS){
+                    for (int i = 0; i < txt.length(); i++) {
+                        if (!Character.isDigit(txt.charAt(i))) {
+                            txt=txt.substring(0,i);
+                        }
+                    }
+                    if (txt.length() >= 15 && Func.isNumeric(txt)) {
+                        eVisaConfigList.add(txt);
+                        dataMap.put(txt,textStr);
+                    }
+                }
+            }
+
+            List<String> unique = eVisaConfigList.stream().distinct().collect(Collectors.toList());
+            document.close();
+            signKeyVO.setEVisaConfigList(unique);
+            signKeyVO.setDataMap(dataMap);
+            return signKeyVO;
+        }catch (Exception e){
+            e.printStackTrace();
+            return null;
+        }
+    }
+}

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

@@ -0,0 +1,152 @@
+package org.springblade.business.controller;
+
+import io.swagger.annotations.Api;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springblade.business.chekPdf.PdfAddimgUtil;
+import org.springblade.business.service.ITaskService;
+import org.springblade.business.vo.ScrSignInfoVO;
+import org.springblade.core.tool.utils.Func;
+import org.springblade.evisa.vo.SignKeyVO;
+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.Scheduled;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+/**
+ * 清表基础数据表 控制器
+ *
+ * @author BladeX
+ * @since 2022-05-18
+ */
+@RestController
+@AllArgsConstructor
+@Api(value = "电签类", tags = "电签类接口")
+@RequestMapping("/archiveFile12312")
+@Slf4j
+public class ChekSignData {
+
+    @Autowired
+    StringRedisTemplate RedisTemplate;
+    // jdbc
+    private final JdbcTemplate jdbcTemplate;
+
+    // 线程池
+    @Resource(name = "taskExecutor1")
+    private ThreadPoolExecutor executor;
+
+    private final ITaskService taskService;
+
+   // @Scheduled(cron = "0/10 * * * * ?")
+    public void SignInfo() {
+        // 质检SQL
+        String sql = "SELECT a.id ,a.e_visa_pdf_url,b.process_instance_id,a.contract_id,a.project_id,c.remark_type,b.id as taskId from u_information_query a ,u_task b ,m_project_info c where a.project_id=1792760669353865218 and b.approval_type=1 and c.id=a.project_id  and a.`status` in(1,2) and a.is_deleted=0 and a.e_visa_pdf_url is not null  and b.form_data_id = a.id and b.`status` in(2) ";
+
+        List<ScrSignInfoVO> query = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(ScrSignInfoVO.class));
+        if (query != null && query.size() >= 1 ) {
+            for (ScrSignInfoVO dataInfo : query) {
+                if (executor.getQueue().size()<=6 ) {
+                    Long nodeId = dataInfo.getId();
+                    Boolean aBoolean = RedisTemplate.hasKey("sign-" + nodeId);
+
+                    if (!aBoolean) {
+                        RedisTemplate.opsForValue().set("sign-" + nodeId, "1",3600, TimeUnit.SECONDS);
+                        CompletableFuture<Void> runAsync = CompletableFuture.runAsync(() -> {
+                            try {
+                                /*===============执行批量任务===============*/
+                                sctTaskBatch2(dataInfo);
+                            } catch (Exception e) {
+                                e.printStackTrace();
+                            }
+                        }, executor);
+                    }
+                }
+            }
+        }
+        System.out.println("队列数量" + executor.getQueue().size());
+        System.out.println("活跃数量" + executor.getActiveCount());
+        System.out.println("总共数量" + executor.getTaskCount());
+        System.out.println("完成数量" + executor.getCompletedTaskCount());
+    }
+
+
+    public void sctTaskBatch2(ScrSignInfoVO taskApp) throws Exception {
+
+
+        String pdfUrl = taskApp.getEVisaPdfUrl();
+        SignKeyVO pdfSignIds = PdfAddimgUtil.getPdfSignIds(pdfUrl);
+        List<String> positions = pdfSignIds.getEVisaConfigList();
+
+        String ids = String.join(",", positions);
+        List<Map<String, Object>> strategyListByDFZX = getStrategyListByDFZX(taskApp, ids);
+
+    }
+
+
+    public List<Map<String, Object>> getStrategyListByDFZX(ScrSignInfoVO taskApp, String ids) {
+        List<Map<String, Object>> maps = new ArrayList<>();
+        List<Map<String, Object>> maps2 = new ArrayList<>();
+        String sql = "select * from u_task_parallel where process_instance_id = '" + taskApp.getProcessInstanceId() + "' and initiative=2 and status=2";
+        List<Map<String, Object>> mapList = jdbcTemplate.queryForList(sql);
+        if (mapList != null && mapList.size() > 0) {
+            for (Map<String, Object> task : mapList) {
+                String taskUserId = Func.toStr(task.get("task_user"));
+                String sqlinfo = " SELECT * from ( SELECT a.id as keyWord,a.project_id,a.pyzbx ,a.pyzby,(SELECT acc_code from blade_user where id='" + taskUserId + "' and is_deleted=0  ) as sealId from m_textdict_info a where  a.type =2 and a.id in (" + ids + ")  and sig_role_id in (SELECT DISTINCT c.role_id from m_project_assignment_user c  where c.contract_id=" + taskApp.getContractId() + " and user_id=" + taskUserId + " and c.is_deleted=0 ) ) x where x.sealId is not null ";
+                System.out.println("扫描-签字-sql=" + sqlinfo);
+                List<Map<String, Object>> maps3 = jdbcTemplate.queryForList(sqlinfo);
+                maps2.addAll(maps3);
+            }
+        }
+        // 添加章
+      //  if (taskApp.getStatus().equals("2")) {
+            String sqlinfo = "SELECT a.id as keyWord,a.pyzbx,a.pyzby,b.certificate_number as sealId from m_textdict_info a ,m_sign_pfx_file b where a.sig_role_id = b.pfx_type and b.project_contract_role like '%" + taskApp.getContractId() + "%' and a.is_deleted=0 and b.is_deleted=0 and a.type=6 and a.id in(" + ids + ") ";
+            System.out.println("扫描-签章-sql=" + sqlinfo);
+            List<Map<String, Object>> maps3 = jdbcTemplate.queryForList(sqlinfo);
+            if (mapList != null && mapList.size() > 0) {
+                maps2.addAll(maps3);
+            }
+      //  }
+        Map<String, List<Map<String, Object>>> peopleByAge = maps2.stream()
+                .collect(Collectors.groupingBy(hada -> (Func.toStr(hada.get("keyWord")))));
+        for (String keyId : peopleByAge.keySet()) {
+            int exId = 0;
+            List<Map<String, Object>> keyList = peopleByAge.get(keyId);
+            if (keyList != null && keyList.size() == 1) {
+                maps.addAll(keyList);
+                exId = 1;
+            } else if (keyList != null && keyList.size() >= 2) {
+                for (Map<String, Object> datax : keyList) {
+                    if ((datax.get("project_id") + "").equals(taskApp.getProjectId())) {
+                        maps.add(datax);
+                        exId = 1;
+                    }
+                }
+            }
+            if (exId == 0) {
+                maps.add(keyList.get(0));
+            }
+        }
+
+        if(maps!=null & maps.size()==0 && mapList.size()>=4 ){
+
+            String header = "bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0ZW5hbnRfaWQiOiIwMDAwMDAiLCJ1c2VyX25hbWUiOiJ6aHV3ZWkiLCJyZWFsX25hbWUiOiLnpZ3ngpwiLCJhdmF0YXIiOiIiLCJhdXRob3JpdGllcyI6WyJhZG1pbmlzdHJhdG9yIl0sImNsaWVudF9pZCI6ImNsaWVudCIsInJvbGVfbmFtZSI6ImFkbWluaXN0cmF0b3IiLCJsaWNlbnNlIjoicG93ZXJlZCBieSBibGFkZXgiLCJwb3N0X2lkIjoiIiwidXNlcl9pZCI6IjE3Mzk5NDQ2MTMyNjUxODY4MTgiLCJyb2xlX2lkIjoiMTEyMzU5ODgxNjczODY3NTIwMSIsInBob25lIjoiMTg5ODI4Nzc2MDciLCJzY29wZSI6WyJhbGwiXSwibmlja19uYW1lIjoi56Wd54KcIiwib2F1dGhfaWQiOiIiLCJkZXRhaWwiOnsidHlwZSI6IndlYiJ9LCJleHAiOjE3NDU1OTU2MDksImRlcHRfaWQiOiIxNTkyMzk0MTMxMTc3ODczNDEwIiwianRpIjoiZTMzN2QyNGMtNzkzZC00OTIwLTliMzEtZTU3MDYyNTIyZTBlIiwiYWNjb3VudCI6InpodXdlaSJ9.jihRZbcZrrCArbMcp6ON9H-1uCDn07juxlXPcHLU07A";
+            taskService.reSigningEVisa("1", taskApp.getTaskId(), taskApp.getContractId(), taskApp.getProjectId(), 1, header);
+            String sql2 = "update u_task set batch=10 where id="+taskApp.getTaskId();
+            jdbcTemplate.execute(sql2);
+        }
+
+        return maps;
+    }
+}

+ 150 - 54
blade-service/blade-business/src/main/java/org/springblade/business/controller/InformationWriteQueryController.java

@@ -612,16 +612,29 @@ public class InformationWriteQueryController extends BladeController {
     public R<Object> abolishOne(@RequestParam String primaryKeyId, @RequestParam String classify, @RequestParam String projectId, @RequestParam String contractId) {
         //查询填报状态
         InformationQuery businessData = this.informationQueryService.getOne(Wrappers.<InformationQuery>lambdaQuery().eq(InformationQuery::getWbsId, primaryKeyId)
-//                .eq(InformationQuery::getContractId, contractId)
+                .eq(InformationQuery::getContractId, contractId)
                 .eq(InformationQuery::getClassify, classify).eq(InformationQuery::getType, 1).in(InformationQuery::getStatus, 1,2));
+        if (businessData != null) {
+            //使用批量废除接口
+            return this.batchAbolish(businessData.getId().toString(), primaryKeyId + "*", projectId, contractId, "撤回成功");
+        }
+        WbsTreeContract obj = this.wbsTreeContractClient.getContractNodeByPrimaryKeyId(primaryKeyId);
+        if (obj != null) {
+            if (!contractId.equals(obj.getContractId())) {
+                contractId = obj.getContractId();
+            }
+            businessData = this.informationQueryService.getOne(Wrappers.<InformationQuery>lambdaQuery().eq(InformationQuery::getWbsId, primaryKeyId)
+                    .eq(InformationQuery::getContractId, contractId)
+                    .eq(InformationQuery::getClassify, classify).eq(InformationQuery::getType, 1).in(InformationQuery::getStatus, 1,2));
+        }
         primaryKeyId = primaryKeyId + "*";
         if (businessData != null) {
             //使用批量废除接口
-            return this.batchAbolish(businessData.getId().toString(), primaryKeyId, projectId, contractId, "撤回成功");
+            return this.batchAbolish(businessData.getId().toString(), primaryKeyId + "*", projectId, contractId, "撤回成功");
         } else {
             //试验
             InformationQuery businessDataTrial = this.informationQueryService.getOne(Wrappers.<InformationQuery>lambdaQuery().eq(InformationQuery::getWbsId, primaryKeyId).eq(InformationQuery::getClassify, classify)
-//                    .eq(InformationQuery::getContractId, contractId)
+                    .eq(InformationQuery::getContractId, contractId)
                     .eq(InformationQuery::getType, 2).in(InformationQuery::getStatus, 1,2));
             if (businessDataTrial != null) {
                 //使用批量废除接口
@@ -659,7 +672,18 @@ public class InformationWriteQueryController extends BladeController {
         //记录状态
         String status = "1";
         //查询填报状态,type=1资料填报
-        InformationQuery businessData = this.informationQueryService.getOne(Wrappers.<InformationQuery>lambdaQuery().eq(InformationQuery::getWbsId, primaryKeyId).eq(InformationQuery::getClassify, classify).eq(InformationQuery::getType, 1).last("order by id desc limit 1"));
+        WbsTreeContract obj = this.wbsTreeContractClient.getContractNodeByPrimaryKeyId(primaryKeyId);
+        if (obj == null) {
+            return R.data(status);
+        }
+        InformationQuery businessData = this.informationQueryService.getOne(Wrappers.<InformationQuery>lambdaQuery().eq(InformationQuery::getWbsId, primaryKeyId).eq(InformationQuery::getClassify, classify).eq(InformationQuery::getContractId, obj.getContractId()).eq(InformationQuery::getType, 1).last("order by id desc limit 1"));
+        if (businessData != null && businessData.getStatus() == 3) {
+            this.informationQueryService.createNewInformationQueriesByStatusForLock(Collections.singletonList(businessData.getId() + ""));
+            InformationQuery businessData1 = this.informationQueryService.getOne(Wrappers.<InformationQuery>lambdaQuery().eq(InformationQuery::getWbsId, primaryKeyId).eq(InformationQuery::getClassify, classify).eq(InformationQuery::getContractId, obj.getContractId()).eq(InformationQuery::getType, 1).in(InformationQuery::getStatus, 0,1,2).last("order by id desc limit 1"));
+            if (businessData1 != null) {
+                businessData = businessData1;
+            }
+        }
         if (businessData != null) {
             switch (businessData.getStatus()) {
                 case 0:
@@ -676,7 +700,7 @@ public class InformationWriteQueryController extends BladeController {
                     //如果不匹配,默认为未填报
                     status = "1";
                     //查询表格
-                    WbsTreeContract obj = this.wbsTreeContractClient.getContractNodeByPrimaryKeyId(primaryKeyId);
+//                    WbsTreeContract obj = this.wbsTreeContractClient.getContractNodeByPrimaryKeyId(primaryKeyId);
                     if (ObjectUtils.isNotEmpty(obj)) {
                         List<WbsTreeContract> tableList = this.wbsTreeContractClient.queryChildByParentId(obj, "queryTable", classify);
                         if (tableList != null && tableList.size() > 0) {
@@ -693,7 +717,7 @@ public class InformationWriteQueryController extends BladeController {
             }
         } else {
             //查询表格
-            WbsTreeContract obj = this.wbsTreeContractClient.getContractNodeByPrimaryKeyId(primaryKeyId);
+//            WbsTreeContract obj = this.wbsTreeContractClient.getContractNodeByPrimaryKeyId(primaryKeyId);
             if (ObjectUtils.isNotEmpty(obj)) {
                 List<WbsTreeContract> tableList = this.wbsTreeContractClient.queryChildByParentId(obj, "queryTable", classify);
                 if (tableList != null && tableList.size() > 0) {
@@ -722,7 +746,17 @@ public class InformationWriteQueryController extends BladeController {
         String status = "1";
         //查询填报状态,type=1资料填报
         WbsTreeContract obj = this.wbsTreeContractClient.getContractNodeByPrimaryKeyId(primaryKeyId);
+        if (obj == null) {
+            return R.data(status);
+        }
         InformationQuery businessData = this.informationQueryService.getOne(Wrappers.<InformationQuery>lambdaQuery().eq(InformationQuery::getWbsId, primaryKeyId).eq(InformationQuery::getClassify, classify).eq(InformationQuery::getContractId, obj.getContractId()).eq(InformationQuery::getType, 1).last("order by id desc limit 1"));
+        if (businessData != null && businessData.getStatus() == 3) {
+            this.informationQueryService.createNewInformationQueriesByStatusForLock(Collections.singletonList(businessData.getId() + ""));
+            InformationQuery businessData1 = this.informationQueryService.getOne(Wrappers.<InformationQuery>lambdaQuery().eq(InformationQuery::getWbsId, primaryKeyId).eq(InformationQuery::getClassify, classify).eq(InformationQuery::getContractId, obj.getContractId()).eq(InformationQuery::getType, 1).in(InformationQuery::getStatus, 0,1,2).last("order by id desc limit 1"));
+            if (businessData1 != null) {
+                businessData = businessData1;
+            }
+        }
         if (businessData != null) {
             switch (businessData.getStatus()) {
                 case 0:
@@ -784,11 +818,27 @@ public class InformationWriteQueryController extends BladeController {
     public R<String> queryNodeStatusSj(@RequestParam String primaryKeyId, @RequestParam String classify, String id) {
         //记录状态
         String status = "1";
+        WbsTreeContract obj = this.wbsTreeContractClient.getContractNodeByPrimaryKeyId(primaryKeyId);
+        if (obj == null) {
+            return R.data(status);
+        }
         //查询填报状态,type=3首件
         InformationQuery businessData = this.informationQueryService.getOne(Wrappers.<InformationQuery>lambdaQuery()
                 .eq(InformationQuery::getId, id)
+                .eq(InformationQuery::getContractId, obj.getContractId())
                 .eq(InformationQuery::getType, 3).last("order by id desc limit 1")
         );
+        if (businessData != null && businessData.getStatus() == 3) {
+            this.informationQueryService.createNewInformationQueriesByStatusForLock(Collections.singletonList(businessData.getId() + ""));
+            InformationQuery businessData1 = this.informationQueryService.getOne(Wrappers.<InformationQuery>lambdaQuery()
+                    .eq(InformationQuery::getId, id)
+                    .eq(InformationQuery::getContractId, obj.getContractId()).in(InformationQuery::getStatus, 0,1,2)
+                    .eq(InformationQuery::getType, 3).last("order by id desc limit 1")
+            );
+            if (businessData1 != null) {
+                businessData = businessData1;
+            }
+        }
         if (businessData != null) {
             switch (businessData.getStatus()) {
                 case 0:
@@ -805,7 +855,7 @@ public class InformationWriteQueryController extends BladeController {
                     //如果不匹配,默认为未填报
                     status = "1";
                     //查询表格
-                    WbsTreeContract obj = this.wbsTreeContractClient.getContractNodeByPrimaryKeyId(primaryKeyId);
+//                    WbsTreeContract obj = this.wbsTreeContractClient.getContractNodeByPrimaryKeyId(primaryKeyId);
                     if (ObjectUtils.isNotEmpty(obj)) {
                         List<WbsTreeContract> tableList = this.wbsTreeContractClient.queryChildByParentId(obj, "queryTable", classify);
                         if (tableList != null && tableList.size() > 0) {
@@ -822,7 +872,7 @@ public class InformationWriteQueryController extends BladeController {
             }
         } else {
             //查询表格
-            WbsTreeContract obj = this.wbsTreeContractClient.getContractNodeByPrimaryKeyId(primaryKeyId);
+//            WbsTreeContract obj = this.wbsTreeContractClient.getContractNodeByPrimaryKeyId(primaryKeyId);
             if (ObjectUtils.isNotEmpty(obj)) {
                 List<WbsTreeContract> tableList = this.wbsTreeContractClient.queryChildByParentId(obj, "queryTable", classify);
                 if (tableList != null && tableList.size() > 0) {
@@ -852,7 +902,15 @@ public class InformationWriteQueryController extends BladeController {
         String status = "1";
         //查询填报状态,type=2试验
         InformationQuery businessData = this.informationQueryService.getBaseMapper().selectList(Wrappers.<InformationQuery>lambdaQuery()
-                .eq(InformationQuery::getWbsId, id).eq(InformationQuery::getClassify, classify).eq(InformationQuery::getType, 2)).stream().findAny().orElse(null);
+                .eq(InformationQuery::getWbsId, id).eq(InformationQuery::getClassify, classify).eq(InformationQuery::getType, 2).last("order by id desc limit 1")).stream().findAny().orElse(null);
+        if (businessData != null && businessData.getStatus() == 3) {
+            this.informationQueryService.createNewInformationQueriesByStatusForLock(Collections.singletonList(businessData.getId() + ""));
+            InformationQuery businessData1 = this.informationQueryService.getBaseMapper().selectList(Wrappers.<InformationQuery>lambdaQuery().in(InformationQuery::getStatus, 0, 1, 2)
+                    .eq(InformationQuery::getWbsId, id).eq(InformationQuery::getClassify, classify).eq(InformationQuery::getType, 2).last("order by id desc limit 1")).stream().findAny().orElse(null);
+            if (businessData1 != null) {
+                businessData = businessData1;
+            }
+        }
         if (businessData != null) {
             switch (businessData.getStatus()) {
                 case 0:
@@ -1179,13 +1237,14 @@ public R<String> batchDownloadFileToZip(String ids, HttpServletResponse response
                         //更改状态为未上报
                         wrapper.set(InformationQuery::getStatus, 3);
                         //将电签的pdf路径置空
-                        wrapper.set(InformationQuery::getEVisaPdfUrl, null);
+//                        wrapper.set(InformationQuery::getEVisaPdfUrl, null);
                         //将上报批次置空
-                        wrapper.set(InformationQuery::getReportNumber, null);
+//                        wrapper.set(InformationQuery::getReportNumber, null);
                         //置空审批人
-                        wrapper.set(InformationQuery::getAuditUserIdAndName, null);
+//                        wrapper.set(InformationQuery::getAuditUserIdAndName, null);
 
                         this.informationQueryService.update(wrapper.in(InformationQuery::getId, Arrays.asList(task.getFormDataId().split(","))));
+                        this.informationQueryService.createNewInformationQueriesByStatusForLock(Arrays.asList(task.getFormDataId().split(",")));
                     }
 
                     List<InformationQuery> queries = this.informationQueryService.getBaseMapper().selectBatchIds(Arrays.asList(task.getFormDataId().split(",")));
@@ -1212,11 +1271,12 @@ public R<String> batchDownloadFileToZip(String ids, HttpServletResponse response
                         if (collect.size() > 0) {
                             context = "撤回成功".equals(context) ? context : "废除成功";
                             jdbcTemplate.execute("UPDATE u_task_parallel SET status = 3,e_visa_content = '" + context + "' WHERE id in(" + StringUtils.join(collect, ",") + ")");
+                            this.jdbcTemplate.execute("delete from u_task_batch where JSON_UNQUOTE(JSON_EXTRACT(json_data, '$.taskId'))="+task.getId());
                         }
 
                         for (InformationQuery query : queries) {
-                            if (query.getStatus() != null && query.getStatus() != 3) {
-                                this.informationQueryService.update(Wrappers.<InformationQuery>lambdaUpdate().eq(InformationQuery::getId, query.getId()).set(InformationQuery::getStatus, 3));
+                            if (query.getStatus() != 3) {
+                                this.informationQueryService.update(Wrappers.<InformationQuery>lambdaUpdate().in(InformationQuery::getId, query.getId()).set(InformationQuery::getStatus, 3));
                             }
                             if (StringUtils.isNotEmpty(query.getFileUserIdAndName())) {
                                 String[] userArray = query.getFileUserIdAndName().split(",");
@@ -1351,6 +1411,28 @@ public R<String> batchDownloadFileToZip(String ids, HttpServletResponse response
                 e.printStackTrace();
                 return R.data(300, false, "废除失败");
             }
+        } else {
+            List<String> list = Arrays.asList(ids.split(","));
+            if (!list.isEmpty()) {
+                List<InformationQuery> queryList = this.informationQueryService.list(Wrappers.<InformationQuery>lambdaQuery()
+                        .select(InformationQuery::getId, InformationQuery::getStatus).in(InformationQuery::getId, list));
+                if (queryList != null && !queryList.isEmpty()) {
+                    List<Long> ids1 = queryList.stream().map(InformationQuery::getId).collect(Collectors.toList());
+                    this.informationQueryService.update(Wrappers.<InformationQuery>lambdaUpdate().set(InformationQuery::getStatus, 0).in(InformationQuery::getId, ids1));
+                    return R.success("操作成功");
+                } else {
+                    // 试验
+                    List<InformationQuery> dataList = this.informationQueryService.getBaseMapper().selectList(Wrappers.<InformationQuery>lambdaQuery()
+                            .select(InformationQuery::getId)
+                            .eq(InformationQuery::getType, 2)
+                            .in(InformationQuery::getWbsId, Func.toStrList(ids)));
+                    if (!dataList.isEmpty()) {
+                        List<Long> dataIds = dataList.stream().map(InformationQuery::getId).collect(Collectors.toList());
+                        this.informationQueryService.update(Wrappers.<InformationQuery>lambdaUpdate().set(InformationQuery::getStatus, 0).in(InformationQuery::getId, dataIds));
+                        return R.success("操作成功");
+                    }
+                }
+            }
         }
         return R.data(300, false, "未获取到任务信息,废除失败");
     }
@@ -1391,35 +1473,38 @@ public R<Object> batchTask(@RequestBody StartTaskVO startTaskVO) {
             }
 
             Map<String, InformationQuery> queryMap = new HashMap<>();
-            List<InformationQuery> saveQueryList = new ArrayList<>();
             List<InformationQuery> queryTempList = new ArrayList<>();
             Map<String, InformationQuery> queryTempMap = new HashMap<>();
             queryList.forEach(query -> {
+                if (query.getStatus() != 0) {
+                    long count = this.informationQueryService.count(Wrappers.<InformationQuery>lambdaQuery().eq(InformationQuery::getWbsId, query.getWbsId()).eq(InformationQuery::getClassify, query.getClassify())
+                            .eq(InformationQuery::getContractId, query.getContractId()).in(InformationQuery::getStatus, 0,1, 2));
+                    if (count == 0) {
+                        if (query.getStatus() != null && query.getStatus() == 3) {
+                            query.setId(SnowFlakeUtil.getId());
+                            query.setStatus(0);
+                            this.informationQueryService.save(query);
+                        }
+                    } else {
+                        return;
+                    }
+                }
+                if (query.getType() == 3) {
+                    startTaskVO.setTrialSelfInspectionRecordId(3L);
+                }
                 InformationQuery temp = queryTempMap.get(query.getWbsId() + "," + query.getContractId() + "," + query.getClassify());
                 if (temp != null) {
                     return;
                 }
                 queryTempMap.put(query.getWbsId() + "," + query.getContractId() + "," + query.getClassify(), query);
-                // todo 待优化
-                long count = this.informationQueryService.count(Wrappers.<InformationQuery>lambdaQuery().eq(InformationQuery::getWbsId, query.getWbsId()).eq(InformationQuery::getClassify, query.getClassify())
-                        .eq(InformationQuery::getContractId, query.getContractId()).in(InformationQuery::getStatus, 1, 2));
-                if (count == 0) {
-                    queryTempList.add(query);
-                    if (query.getStatus() != null && query.getStatus() == 3) {
-                        query.setId(SnowFlakeUtil.getId());
-                        query.setStatus(0);
-                        saveQueryList.add(query);
-                    }
-                    queryMap.put(query.getId().toString(), query);
-                }
+                queryTempList.add(query);
+                queryMap.put(query.getId().toString(), query);
             });
             queryList = queryTempList;
             if (queryList.isEmpty()) {
                 return R.fail( "已上报,无需重复上报");
             }
-            if (!saveQueryList.isEmpty()) {
-                this.informationQueryService.saveBatch(saveQueryList);
-            }
+            appType = startTaskVO.getTrialSelfInspectionRecordId();
             ids = queryList.stream().map(InformationQuery::getId).map(String::valueOf).toArray(String[]::new);
             boolean var = false;
 
@@ -2998,29 +3083,36 @@ public R<Boolean> updateContractNodeParameter(@RequestParam Long pKeyId, @Reques
     WbsTreeContract nodee = wbsTreeContractClient.getContractNodeByPrimaryKeyId(pKeyId+"");
     String sql="Select * from m_wbs_tree_contract where id="+nodee.getParentId()+" and contract_id="+nodee.getContractId()+" and wbs_id="+nodee.getWbsId()+" and is_deleted=0";
     WbsTreeContract parentNode=jdbcTemplate.queryForObject(sql,new BeanPropertyRowMapper<>(WbsTreeContract.class));
-    if (parentNode != null) {
-        Integer targetType;//当前节点
-        Integer sourceType;//当前节点的父节点
-        if (parentNode.getNodeType() != 1) {
-            sourceType = parentNode.getNodeType() + 1;
-        } else {
-            sourceType = parentNode.getNodeType();
-        }
-        if (parentNode.getNodeType() == 18) {
-            sourceType = 2;
-        }
-        if (nodeType != 1) {
-            targetType = nodeType + 1;
-        } else {
-            targetType = nodeType;
-        }
-        if (nodeType == 18) {
-            targetType = 2;
-        }
-        if (sourceType >= targetType) {
-            throw new ServiceException("当前节点类型不能大于或等于父级节点类型");
+    Integer templateType = jdbcTemplate.queryForObject(
+        "select COALESCE(template_type, 0) from m_contract_info where id="+nodee.getContractId()+" and is_deleted=0",
+        Integer.class
+    );
+    if(templateType!=null&&templateType==2){
+        if (parentNode != null) {
+            Integer targetType;//当前节点
+            Integer sourceType;//当前节点的父节点
+            if (parentNode.getNodeType() != 1) {
+                sourceType = parentNode.getNodeType() + 1;
+            } else {
+                sourceType = parentNode.getNodeType();
+            }
+            if (parentNode.getNodeType() == 18) {
+                sourceType = 2;
+            }
+            if (nodeType != 1) {
+                targetType = nodeType + 1;
+            } else {
+                targetType = nodeType;
+            }
+            if (nodeType == 18) {
+                targetType = 2;
+            }
+            if (sourceType >= targetType) {
+                throw new ServiceException("当前节点类型不能大于或等于父级节点类型");
+            }
         }
     }
+
     WbsTreeContract queries = this.wbsTreeContractClient.getContractWbsTreeByPrimaryKeyId(pKeyId);
     if (ObjectUtil.isNotEmpty(className) || ObjectUtil.isNotEmpty(unitName)) {
         //查询当前节点的是否是子节点,以及当前节点父节点是否包含单元评定
@@ -3422,6 +3514,9 @@ public R<Boolean> saveContractTreeNode(@RequestBody AddContractTreeNodeVO vo) {
                 List<Long> lowNodeIds = selectedNodeList.stream().filter(f -> f.getLow() == 0).map(WbsTreePrivateAddVO::getId).collect(Collectors.toList()); //最底层节点id
                 List<WbsTreePrivateAddVO> childList = new ArrayList<>();
                 if (lowNodeIds.size() > 0) {
+                    if("3".equals(vo.getSaveType())){
+                        lowNodeIds=selectedNodeList.stream().filter(f -> f.getLow() == 0&&(f.getNodeType()==6||1==f.getMajorDataType()||2==f.getMajorDataType()||3==f.getMajorDataType()||4==f.getMajorDataType())).map(WbsTreePrivateAddVO::getId).collect(Collectors.toList());
+                    }
                     //只取原始表
                     this.foreachQueryChild(lowNodeIds, childList, treeContract);
                     //将表格数据设置
@@ -3433,6 +3528,7 @@ public R<Boolean> saveContractTreeNode(@RequestBody AddContractTreeNodeVO vo) {
                     Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(WbsTreePrivate::getId))),
                     ArrayList::new
                 ));
+
             }
             //处理半选
             this.disposeHalfSelectList(treeContract, halfSelectedNodeList, selectedNodeList, query);
@@ -3643,9 +3739,9 @@ public R<Boolean> saveContractTreeNode(@RequestBody AddContractTreeNodeVO vo) {
                 newData.setContractIdRelation(treeContract.getContractIdRelation());
                 newData.setContractType(treeContract.getContractType());
                 newData.setCreateTime(new Date());
-                if (Optional.ofNullable(half.getNodeType()).orElse(7) <= 6) {
+                //if (Optional.ofNullable(half.getNodeType()).orElse(7) <= 6) {
                     newData.setIsTypePrivatePid(half.getPKeyId());
-                }
+                //}
                 if (half.getType() != null && new Integer("2").equals(half.getType())) {
                     //2023年8月1日14:41:03更改需求,isBussShow默认=1
                     newData.setIsBussShow(1);
@@ -3766,7 +3862,7 @@ public R<Boolean> saveContractTreeNode(@RequestBody AddContractTreeNodeVO vo) {
 @ApiOperationSupport(order = 1)
 @ApiOperation(value = "获取底层节点文件题名")
 public R<String> getDICengNodeName(@RequestParam Long pKeyId,@RequestParam Long contractId,@RequestParam Integer classify){
-    InformationQuery informationQuery = informationQueryService.getBaseMapper().selectOne(new LambdaQueryWrapper<>(InformationQuery.class).eq(InformationQuery::getWbsId, pKeyId).eq(InformationQuery::getContractId, contractId).eq(InformationQuery::getClassify, classify).eq(InformationQuery::getType, 1));
+    InformationQuery informationQuery = informationQueryService.getBaseMapper().selectOne(new LambdaQueryWrapper<>(InformationQuery.class).eq(InformationQuery::getWbsId, pKeyId).eq(InformationQuery::getContractId, contractId).eq(InformationQuery::getClassify, classify).eq(InformationQuery::getType, 1).last("order by id desc limit 1"));
     if(informationQuery!=null){
         return R.data(informationQuery.getName());
     }

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

@@ -1273,7 +1273,7 @@ public class TaskController extends BladeController {
         int size = dto.getSize();
         //封装入参SQL
         List<Object> params = new ArrayList<>();
-        StringBuilder sqlString = new StringBuilder("SELECT * FROM u_task WHERE 1=1 AND is_deleted = 0 AND approval_type in(1,2,3,4,8)");
+        StringBuilder sqlString = new StringBuilder("SELECT * FROM u_task WHERE 1=1 AND is_deleted = 0 AND approval_type in(1,3,4,8,9,10)");
         if (ObjectUtil.isNotEmpty(dto.getTypeValue())) {
             sqlString.append(" AND type = ?");
             params.add(dto.getTypeValue());
@@ -1307,6 +1307,10 @@ public class TaskController extends BladeController {
                         Set<Long> ids = contractRelationJLYZ.stream().map(ContractRelationJlyz::getContractIdSg).collect(Collectors.toSet());
                         ids.add(dto.getCurrentContractId()); //把监理本身也加入查询
                         sqlString.append(" AND contract_id in(").append(StringUtils.join(ids, ",")).append(")");
+
+                        // 排除监理创建的数据
+                        sqlString.append(" AND form_data_id not in( SELECT id from u_information_query where type=1 and contract_id='"+dto.getCurrentContractId()+"' )");
+
                     } else {
                         //如果下拉框合同段选择框合同段!=当前用户登陆合同段,那么查询下拉框合同段数据
                         sqlString.append(" AND contract_id = ?");

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

@@ -76,7 +76,7 @@ public interface InformationQueryMapper extends BaseMapper<InformationQuery> {
      * @param classify 1施工2质检
      * @return 结果对象
      */
-    InformationQuery getInformationQueryByWbsId(@Param("wbsId") Long wbsId, @Param("classify") Integer classify);
+    InformationQuery getInformationQueryByWbsId(@Param("wbsId") Long wbsId, @Param("classify") Integer classify,@Param("contractId")String contractId);
 
     /**
      * 获取当前合同段下所有的上报批次

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

@@ -546,6 +546,8 @@
         where is_deleted = 0
           and wbs_id = #{wbsId}
           and classify = #{classify}
+          and status !=3
+          and contract_id=#{contractId}
     </select>
 
     <select id="getReportNumberByContractId" resultMap="intResultMap">
@@ -565,6 +567,8 @@
         where is_deleted = 0
           and contract_id = #{contractId}
           and classify = #{classify}
+          and status !=3
+          and contract_id = #{contractId}
     </select>
 
     <select id="countInformationQuery" resultType="java.lang.Integer">

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

@@ -27,6 +27,7 @@ import org.springblade.manager.entity.TabBusstimeInfo;
 import org.springblade.manager.entity.WbsTreeContract;
 import org.springblade.manager.vo.WbsTreeContractTreeVOS;
 
+import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 
@@ -160,4 +161,5 @@ public interface IInformationQueryService extends BaseService<InformationQuery>
     //根据wbsTreeContract主键集合获取已经审批的资料
     List<Long> getInfoByNodeIds(List<Long> ids);
 
+    void createNewInformationQueriesByStatusForLock(Collection<String> ids);
 }

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

@@ -27,6 +27,7 @@ import org.springblade.core.secure.utils.AuthUtil;
 import org.springblade.core.secure.utils.SecureUtil;
 import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.utils.*;
+import org.springblade.evisa.redissionUtil.DistributedRedisLock;
 import org.springblade.manager.entity.ContractInfo;
 import org.springblade.manager.entity.ContractRelationJlyz;
 import org.springblade.manager.entity.TabBusstimeInfo;
@@ -388,7 +389,7 @@ public class InformationQueryServiceImpl extends BaseServiceImpl<InformationQuer
             WbsTreeContract contractTree = this.wbsTreeContractClient.getContractWbsTreeByPrimaryKeyId(Long.parseLong(primaryKeyId));
 
             //判断当前填报节点下是否已经存在相应数据
-            InformationQuery oldData = this.baseMapper.getInformationQueryByWbsId(contractTree.getPKeyId(), classify);
+            InformationQuery oldData = this.baseMapper.getInformationQueryByWbsId(contractTree.getPKeyId(), classify,contractTree.getContractId());
 
             if (oldData != null) {
                 //存在记录,修改
@@ -1053,4 +1054,49 @@ public class InformationQueryServiceImpl extends BaseServiceImpl<InformationQuer
         return baseMapper.getInfoByNodeIds(ids);
     }
 
+    @Override
+    public void createNewInformationQueriesByStatusForLock(Collection<String> ids) {
+        if (ids == null || ids.isEmpty()) {
+            return;
+        }
+        List<InformationQuery> informationQueries = this.getBaseMapper().selectBatchIds(ids);
+        if (informationQueries != null && !informationQueries.isEmpty()) {
+            for (InformationQuery informationQuery : informationQueries) {
+                if (DistributedRedisLock.acquire("informationQueryLock_" + informationQuery.getWbsId() + "_" + informationQuery.getContractId() + "_" + informationQuery.getClassify() + "_" + informationQuery.getType(),5)) {
+                    try {
+                        List<InformationQuery> queryList = this.list(Wrappers.<InformationQuery>lambdaQuery().select(InformationQuery::getId, InformationQuery::getStatus)
+                                .eq(InformationQuery::getWbsId, informationQuery.getWbsId())
+                                .eq(InformationQuery::getContractId, informationQuery.getContractId())
+                                .eq(InformationQuery::getClassify, informationQuery.getClassify()).eq(InformationQuery::getType, informationQuery.getType()).in(InformationQuery::getStatus, 0, 1, 2));
+                        InformationQuery temp = new InformationQuery();
+                        if (queryList != null && !queryList.isEmpty()) {
+                            queryList.forEach(query -> {
+                                if (query.getStatus() == 0 && temp.getId() == null) {
+                                    temp.setId(query.getId());
+                                } else {
+                                    query.setStatus(3);
+                                }
+                            });
+                            List<Long> collect = queryList.stream().map(InformationQuery::getId).filter(id -> !id.equals(temp.getId())).collect(Collectors.toList());
+                            if (!collect.isEmpty()) {
+                                this.update(Wrappers.<InformationQuery>lambdaUpdate().set(InformationQuery::getStatus, 3).in(InformationQuery::getId, collect));
+                            }
+                        }
+                        if (temp.getId() != null) {
+                            continue;
+                        }
+                        informationQuery.setStatus(0);
+                        informationQuery.setId(SnowFlakeUtil.getId());
+                        informationQuery.setEVisaPdfUrl(null);
+                        informationQuery.setReportNumber(null);
+                        informationQuery.setAuditUserIdAndName(null);
+                        informationQuery.setTaskId(null);
+                        this.save(informationQuery);
+                    } finally {
+                        DistributedRedisLock.release("informationQueryLock_" + informationQuery.getWbsId() + "_" + informationQuery.getContractId() + "_" + informationQuery.getClassify() + "_" + informationQuery.getType());
+                    }
+                }
+            }
+        }
+    }
 }

+ 168 - 134
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TaskServiceImpl.java

@@ -198,6 +198,8 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
                 //日志资料
                 return this.queryTheLogFileBusinessData(taskApprovalVO.getFormDataId());
             case 8:
+            case 9:
+            case 10:
                 //委拖单
                 return this.queryProcessSubmitBusinessData(taskApprovalVO.getFormDataId(), false);
             default:
@@ -422,30 +424,30 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
     @Override
     public Boolean abolishTask(Task task) {
         //查询分支
-        List<TaskParallel> linkList = this.taskParallelService.list(Wrappers.<TaskParallel>lambdaQuery().eq(TaskParallel::getProcessInstanceId, task.getProcessInstanceId()));
-
-        //将所有分支流程执行结束
-        for (TaskParallel taskParallel : linkList) {
-            //根据实例ID获取任务ID
-            String linkTaskId = this.newFlowClient.queryTaskIdByProcessInstanceId(taskParallel.getParallelProcessInstanceId());
-            if (StringUtils.isNotEmpty(linkTaskId)) {
-                //结束分支流程
-                this.newFlowClient.completeApprovalTask(linkTaskId, taskParallel.getParallelProcessInstanceId(), "上报人主动废除");
-            }
-        }
-        //获取主流程的任务ID
-        String masterTaskId = this.newFlowClient.queryTaskIdByProcessInstanceId(task.getProcessInstanceId());
-        if (StringUtils.isNotEmpty(masterTaskId)) {
-            //结束主流程
-            this.newFlowClient.completeApprovalTask(masterTaskId, task.getProcessInstanceId(), "上报人主动废除");
-        }
+//        List<TaskParallel> linkList = this.taskParallelService.list(Wrappers.<TaskParallel>lambdaQuery().eq(TaskParallel::getProcessInstanceId, task.getProcessInstanceId()));
+//
+//        //将所有分支流程执行结束
+//        for (TaskParallel taskParallel : linkList) {
+//            //根据实例ID获取任务ID
+//            String linkTaskId = this.newFlowClient.queryTaskIdByProcessInstanceId(taskParallel.getParallelProcessInstanceId());
+//            if (StringUtils.isNotEmpty(linkTaskId)) {
+//                //结束分支流程
+//                this.newFlowClient.completeApprovalTask(linkTaskId, taskParallel.getParallelProcessInstanceId(), "上报人主动废除");
+//            }
+//        }
+//        //获取主流程的任务ID
+//        String masterTaskId = this.newFlowClient.queryTaskIdByProcessInstanceId(task.getProcessInstanceId());
+//        if (StringUtils.isNotEmpty(masterTaskId)) {
+//            //结束主流程
+//            this.newFlowClient.completeApprovalTask(masterTaskId, task.getProcessInstanceId(), "上报人主动废除");
+//        }
 
         //修改主流程状态为3
         this.update(Wrappers.<Task>lambdaUpdate().set(Task::getStatus, 3).eq(Task::getId, task.getId()));
         //修改业务数据状态为未上报
         // this.updateBusinessDataByFormDataId(task, 0, null);
-        this.updateBusinessDataByFormDataId(task, 0, null, -1L);
-
+        this.updateBusinessDataByFormDataId(task, 3, null, -1L);
+        this.informationQueryService.createNewInformationQueriesByStatusForLock(Arrays.asList(task.getFormDataId().split(",")));
         return true;
     }
 
@@ -677,11 +679,34 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
                     jdbcTemplate.execute(up_task);
 
                     if(taskApp.getApprovalType() == 3){
-                        jdbcTemplate.execute("update u_contract_log set status=0 where id='"+taskApp.getFormDataId()+"'");
+                        jdbcTemplate.execute("update u_contract_log set status=3 where id='"+taskApp.getFormDataId()+"'");
                     }else if (taskApp.getApprovalType()==8) {
                         this.jdbcTemplate.execute("update u_entrust_info set status=1 where id=(SELECT wbs_id from u_information_query where id='"+taskApp.getFormDataId()+"')");
                     }else {
                         jdbcTemplate.execute("update u_information_query set e_visa_pdf_url='',status=3 where id='"+taskApp.getFormDataId()+"'");
+                        InformationQuery informationQuery = informationQueryService.getById(taskApp.getFormDataId());
+                        Long primaryKeyId = informationQuery.getWbsId();
+                        informationQuery.setStatus(0);
+                        informationQuery.setId(SnowFlakeUtil.getId());
+                        informationQuery.setEVisaPdfUrl(null);
+                        informationQuery.setReportNumber(null);
+                        informationQuery.setAuditUserIdAndName(null);
+                        informationQuery.setTaskId(null);
+                        informationQueryService.save(informationQuery);
+                        if (taskApp.getApprovalType() == 9 && primaryKeyId != null) {
+                            //修改试验任务状态为未上报
+                            String sql = "update u_trial_self_inspection_record set task_status = '未上报' where id=" + primaryKeyId;
+                            String sql1 = "SELECT e.* from u_entrust_info e left join u_trial_self_inspection_record t on t.entrust_id=e.id where t.id=" + primaryKeyId;
+                            jdbcTemplate.execute(sql);
+                            List<EntrustInfo> query = jdbcTemplate.query(sql1, new BeanPropertyRowMapper<>(EntrustInfo.class));
+                            if (!query.isEmpty()) {
+                                String[] idss = query.stream()
+                                        .map(item -> String.valueOf(item.getId()))
+                                        .toArray(String[]::new);
+                                String update = "update u_entrust_info set status=3 where id in(" + String.join(",", idss) + ")";
+                                jdbcTemplate.execute(update);
+                            }
+                        }
                     }
                 }
             }
@@ -1408,26 +1433,26 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
             vo.setStartTime(DateUtil.format(nowTime, "yyyy-MM-dd"));
             vo.setEndTime(DateUtil.format(DateUtils.addDays(nowTime, vo.getRestrictDay()), "yyyy-MM-dd"));
 
-            Query query = new Query();
-            query.setCurrent(1);
-            query.setSize(999);
+//            Query query = new Query();
+//            query.setCurrent(1);
+//            query.setSize(999);
             //获取流程
-            List<FlowProcessVO> modeProcessVOS = this.newFlowClient.startFlowList("", query, 1);
-            if (modeProcessVOS == null || modeProcessVOS.size() == 0) {
-                return false;
-            }
+//            List<FlowProcessVO> modeProcessVOS = this.newFlowClient.startFlowList("", query, 1);
+//            if (modeProcessVOS == null || modeProcessVOS.size() == 0) {
+//                return false;
+//            }
             //获取当中的审批流程
-            String taskFlowId = null;
-            for (FlowProcessVO processVO : modeProcessVOS) {
-                if ("approval".equals(processVO.getKey())) {
-                    taskFlowId = processVO.getId();
-                    break;
-                }
-            }
-            //如果没有对应流程,直接返回
-            if (StringUtils.isEmpty(taskFlowId)) {
-                return false;
-            }
+            String taskFlowId = SnowFlakeUtil.getId() + "";
+//            for (FlowProcessVO processVO : modeProcessVOS) {
+//                if ("approval".equals(processVO.getKey())) {
+//                    taskFlowId = processVO.getId();
+//                    break;
+//                }
+//            }
+//            //如果没有对应流程,直接返回
+//            if (StringUtils.isEmpty(taskFlowId)) {
+//                return false;
+//            }
             //获取选择的固定流程
             List<FixedFlowLink> links = new ArrayList<>();
             if (Long.valueOf("0").equals(vo.getFixedFlowId())) {
@@ -1447,30 +1472,32 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
             }
 
             //启动主流程
-            R<BladeFlow> result = this.flowClient.startProcessInstanceById(taskFlowId, FlowUtil.getBusinessKey(businessTable, String.valueOf(vo.getId())),
-                    Kv.create().set(ProcessConstant.TASK_VARIABLE_CREATE_USER, AuthUtil.getUserName()).set("taskUser", TaskUtil.getTaskUser("")));
-            if (result.isSuccess()) {
-                log.debug("主流程已启动,流程ID:" + result.getData().getProcessInstanceId());
-                //拼接并行的实例ID
-                vo.setProcessInstanceId(result.getData().getProcessInstanceId());
-            } else {
-                throw new ServiceException("开启主流程失败");
-            }
+//            R<BladeFlow> result = this.flowClient.startProcessInstanceById(taskFlowId, FlowUtil.getBusinessKey(businessTable, String.valueOf(vo.getId())),
+//                    Kv.create().set(ProcessConstant.TASK_VARIABLE_CREATE_USER, AuthUtil.getUserName()).set("taskUser", TaskUtil.getTaskUser("")));
+//            if (result.isSuccess()) {
+//                log.debug("主流程已启动,流程ID:" + result.getData().getProcessInstanceId());
+//                //拼接并行的实例ID
+//                vo.setProcessInstanceId(result.getData().getProcessInstanceId());
+//            } else {
+//                throw new ServiceException("开启主流程失败");
+//            }
+            vo.setProcessInstanceId(SnowFlakeUtil.getId() + "");
 
             //根据所选择的固定流程所含有的环节发起审批任务
             List<TaskParallel> taskParallelArray = new ArrayList<>();
             for (FixedFlowLink link : links) {
                 //启动并行流程
-                Kv variables = Kv.create()
-                        //下一步流程审批人
-                        .set("taskUser", TaskUtil.getTaskUser(link.getFixedFlowLinkUser().toString()));
-                R<BladeFlow> linkResult = this.flowClient.startProcessInstanceById(taskFlowId, FlowUtil.getBusinessKey(businessTable, String.valueOf(vo.getId())), variables);
-                if (result.isSuccess()) {
-                    log.debug("并行流程已启动,流程ID:" + linkResult.getData().getProcessInstanceId());
-                    taskParallelArray.add(new TaskParallel(vo.getProcessInstanceId(), linkResult.getData().getProcessInstanceId(), link.getFixedFlowLinkUser().toString(), link.getFixedFlowLinkUserName()));
-                } else {
-                    throw new ServiceException("开启并行流程失败");
-                }
+//                Kv variables = Kv.create()
+//                        //下一步流程审批人
+//                        .set("taskUser", TaskUtil.getTaskUser(link.getFixedFlowLinkUser().toString()));
+//                R<BladeFlow> linkResult = this.flowClient.startProcessInstanceById(taskFlowId, FlowUtil.getBusinessKey(businessTable, String.valueOf(vo.getId())), variables);
+//                if (linkResult.isSuccess()) {
+//                    log.debug("并行流程已启动,流程ID:" + linkResult.getData().getProcessInstanceId());
+//                    taskParallelArray.add(new TaskParallel(vo.getProcessInstanceId(), linkResult.getData().getProcessInstanceId(), link.getFixedFlowLinkUser().toString(), link.getFixedFlowLinkUserName()));
+//                } else {
+//                    throw new ServiceException("开启并行流程失败");
+//                }
+                  taskParallelArray.add(new TaskParallel(vo.getProcessInstanceId(), SnowFlakeUtil.getId() + "", link.getFixedFlowLinkUser().toString(), link.getFixedFlowLinkUserName()));
             }
             //设置流程信息
             vo.setProcessDefinitionId(taskFlowId);
@@ -1546,6 +1573,10 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
                 //日志文件
                 this.updateContractLogBusinessDataStatus(task.getFormDataId(), status, newFileUrl);
                 break;
+            case 9:
+            case 10:
+                this.updateWriteBusinessDataStatus(task.getFormDataId(), status, newFileUrl, UserId);
+                break;
             default:
                 break;
         }
@@ -1558,8 +1589,8 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
     public void updateContractLogBusinessDataStatus(String formDataId, Integer status, String newFileUrl) {
         this.contractLogService.update(Wrappers.<ContractLog>lambdaUpdate().set(ContractLog::getStatus, status)
                 .set(ContractLog::getEVisaPdfUrl, newFileUrl)
-                .set(ContractLog::getAuditUserIdAndName, null)
-                .set(ContractLog::getBatch, null)
+//                .set(ContractLog::getAuditUserIdAndName, null)
+//                .set(ContractLog::getBatch, null)
                 .in(ContractLog::getId, Arrays.asList(formDataId.split(","))));
     }
 
@@ -1649,8 +1680,8 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
                 System.out.println("----- 电签成功--------==修改---=" + dateInfo);
                 this.informationQueryService.update(Wrappers.<InformationQuery>lambdaUpdate().set(InformationQuery::getStatus, status)
                         .set(InformationQuery::getEVisaPdfUrl, newFileUrl)
-                        .set(InformationQuery::getReportNumber, null)
-                        .set(InformationQuery::getAuditUserIdAndName, null)
+//                        .set(InformationQuery::getReportNumber, null)
+//                        .set(InformationQuery::getAuditUserIdAndName, null)
                         .set(InformationQuery::getEVisaPdfPage, pdfPage)
                         .set(InformationQuery::getEVisaPdfSize, pdfSize)
                         .set(InformationQuery::getBusinessTime, dateInfo)
@@ -1666,8 +1697,8 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
         } catch (Exception e) {
             this.informationQueryService.update(Wrappers.<InformationQuery>lambdaUpdate().set(InformationQuery::getStatus, status)
                     .set(InformationQuery::getEVisaPdfUrl, newFileUrl)
-                    .set(InformationQuery::getReportNumber, null)
-                    .set(InformationQuery::getAuditUserIdAndName, null)
+//                    .set(InformationQuery::getReportNumber, null)
+//                    .set(InformationQuery::getAuditUserIdAndName, null)
                     .set(InformationQuery::getEVisaPdfPage, pdfPage)
                     .set(InformationQuery::getEVisaPdfSize, pdfSize)
                     .set(InformationQuery::getBusinessTime, dateInfo)
@@ -1818,75 +1849,75 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
             archiveFileService.deleteLogic(ids);
         }
     }
+/*
+    @Override
+    public void reSigningEVisa(String taskIds, String contractId, String projectId,String header,HttpServletRequest request) {
+        List<Task> taskList = jdbcTemplate.query("select * from u_task where id in(" + taskIds + ")", new BeanPropertyRowMapper<>(Task.class));
+        if (taskList.size() > 0) {
+            List<String> dataIdList = taskList.stream().map(Task::getFormDataId).filter(ObjectUtil::isNotEmpty).collect(Collectors.toList());
+            List<InformationQuery> informationQueryList = jdbcTemplate.query("select * from u_information_query where id in(" + StringUtils.join(dataIdList, ",") + ")", new BeanPropertyRowMapper<>(InformationQuery.class));
+            if (informationQueryList.size() > 0) {
+                List<Long> nodePKeyIdList = informationQueryList.stream().map(InformationQuery::getWbsId).filter(ObjectUtil::isNotEmpty).collect(Collectors.toList());
+                if (nodePKeyIdList.size() > 0) {
+                    try {
+                      //  重新保存
+                        long startTime_1 = System.currentTimeMillis();
+                        R result = this.saveNodePdf( ,StringUtils.join(nodePKeyIdList, ","), contractId, projectId,header);
+                        long endTime_1 = System.currentTimeMillis();
+                        long executionTime_1 = endTime_1 - startTime_1;
+                        log.info("saveNodePdf执行时间:" + executionTime_1 + " 毫秒");
 
-//    @Override
-//    public void reSigningEVisa(String taskIds, String contractId, String projectId,String header) {
-//        List<Task> taskList = jdbcTemplate.query("select * from u_task where id in(" + taskIds + ")", new BeanPropertyRowMapper<>(Task.class));
-//        if (taskList.size() > 0) {
-//            List<String> dataIdList = taskList.stream().map(Task::getFormDataId).filter(ObjectUtil::isNotEmpty).collect(Collectors.toList());
-//            List<InformationQuery> informationQueryList = jdbcTemplate.query("select * from u_information_query where id in(" + StringUtils.join(dataIdList, ",") + ")", new BeanPropertyRowMapper<>(InformationQuery.class));
-//            if (informationQueryList.size() > 0) {
-//                List<Long> nodePKeyIdList = informationQueryList.stream().map(InformationQuery::getWbsId).filter(ObjectUtil::isNotEmpty).collect(Collectors.toList());
-//                if (nodePKeyIdList.size() > 0) {
-//                    try {
-//                        //重新保存
-//                        long startTime_1 = System.currentTimeMillis();
-//                        R result = this.saveNodePdf(StringUtils.join(nodePKeyIdList, ","), contractId, projectId,header);
-//                        long endTime_1 = System.currentTimeMillis();
-//                        long executionTime_1 = endTime_1 - startTime_1;
-//                        log.info("saveNodePdf执行时间:" + executionTime_1 + " 毫秒");
-//
-//                        //重新电签
-//                        if (result != null && "成功".equals(result.getData())) {
-//
-//                            List<TaskApprovalVO> taskApprovalVOS = new ArrayList<>();
-//                            //获取任务详情信息Map
-//                            Set<String> processInstanceIds = taskList.stream().map(Task::getProcessInstanceId).collect(Collectors.toSet());
-//                            Map<String, List<TaskParallel>> taskParallelGroupMap = new HashMap<>();
-//                            if (processInstanceIds.size() > 0) {
-//                                String resultIds = processInstanceIds.stream()
-//                                        .map(id -> "'" + id + "'")
-//                                        .collect(Collectors.joining(","));
-//                                taskParallelGroupMap = jdbcTemplate.query("select parallel_process_instance_id,process_instance_id,e_visa_status,task_user,task_user_name,status from u_task_parallel where process_instance_id in(" + resultIds + ") order by id", new BeanPropertyRowMapper<>(TaskParallel.class)).stream().collect(Collectors.groupingBy(TaskParallel::getProcessInstanceId));
-//                            }
-//                            Map<String, List<TaskParallel>> finalTaskParallelGroupMap = taskParallelGroupMap;
-//
-//                            for (Task task : taskList) {
-//                                List<TaskParallel> taskParallelList = finalTaskParallelGroupMap.get(task.getProcessInstanceId());
-//                                for (TaskParallel taskParallel : taskParallelList) {
-//                                    //待审批的不进行重签, 存在待审批,但是电签状态是失败的
-//                                    if (!(new Integer(1)).equals(taskParallel.getStatus()) || (taskParallel.getEVisaStatus() != null && taskParallel.getEVisaStatus() == 99)) {
-//                                        TaskApprovalVO approvalVO = new TaskApprovalVO();
-//                                        approvalVO.setTaskId(task.getId().toString());
-//                                        approvalVO.setFlag("OK");
-//                                        approvalVO.setComment("重新发起电签");
-//                                        approvalVO.setApprovalType(1);
-//                                        approvalVO.setFormDataId(task.getFormDataId());
-//                                        approvalVO.setParallelProcessInstanceId(taskParallel.getParallelProcessInstanceId());
-//                                        approvalVO.setYsNickName(taskParallel.getTaskUserName());
-//                                        approvalVO.setUserId(Long.parseLong(taskParallel.getTaskUser()));
-//                                        taskApprovalVOS.add(approvalVO);
-//                                    }
-//                                }
-//                            }
-//                            long startTime_2 = System.currentTimeMillis();
-//                            this.batchCompleteApprovalTask(taskApprovalVOS);
-//                            long endTime_2 = System.currentTimeMillis();
-//                            long executionTime_2 = endTime_2 - startTime_2;
-//                            log.info("batchCompleteApprovalTask执行时间:" + executionTime_2 + " 毫秒");
-//                        } else {
-//                            throw new ServiceException("重新保存PDF信息失败");
-//                        }
-//
-//                    } catch (Exception e) {
-//                        e.printStackTrace();
-//                        throw new ServiceException("重新保存PDF信息失败,原因:" + e.getMessage());
-//                    }
-//                }
-//            }
-//        }
-//        throw new ServiceException("未获取到任务信息,操作失败!");
-//    }
+                       // 重新电签
+                        if (result != null && "成功".equals(result.getData())) {
+
+                            List<TaskApprovalVO> taskApprovalVOS = new ArrayList<>();
+                           // 获取任务详情信息Map
+                            Set<String> processInstanceIds = taskList.stream().map(Task::getProcessInstanceId).collect(Collectors.toSet());
+                            Map<String, List<TaskParallel>> taskParallelGroupMap = new HashMap<>();
+                            if (processInstanceIds.size() > 0) {
+                                String resultIds = processInstanceIds.stream()
+                                        .map(id -> "'" + id + "'")
+                                        .collect(Collectors.joining(","));
+                                taskParallelGroupMap = jdbcTemplate.query("select parallel_process_instance_id,process_instance_id,e_visa_status,task_user,task_user_name,status from u_task_parallel where process_instance_id in(" + resultIds + ") order by id", new BeanPropertyRowMapper<>(TaskParallel.class)).stream().collect(Collectors.groupingBy(TaskParallel::getProcessInstanceId));
+                            }
+                            Map<String, List<TaskParallel>> finalTaskParallelGroupMap = taskParallelGroupMap;
+
+                            for (Task task : taskList) {
+                                List<TaskParallel> taskParallelList = finalTaskParallelGroupMap.get(task.getProcessInstanceId());
+                                for (TaskParallel taskParallel : taskParallelList) {
+                                    //待审批的不进行重签, 存在待审批,但是电签状态是失败的
+                                    if (!(new Integer(1)).equals(taskParallel.getStatus()) || (taskParallel.getEVisaStatus() != null && taskParallel.getEVisaStatus() == 99)) {
+                                        TaskApprovalVO approvalVO = new TaskApprovalVO();
+                                        approvalVO.setTaskId(task.getId().toString());
+                                        approvalVO.setFlag("OK");
+                                        approvalVO.setComment("重新发起电签");
+                                        approvalVO.setApprovalType(1);
+                                        approvalVO.setFormDataId(task.getFormDataId());
+                                        approvalVO.setParallelProcessInstanceId(taskParallel.getParallelProcessInstanceId());
+                                        approvalVO.setYsNickName(taskParallel.getTaskUserName());
+                                        approvalVO.setUserId(Long.parseLong(taskParallel.getTaskUser()));
+                                        taskApprovalVOS.add(approvalVO);
+                                    }
+                                }
+                            }
+                            long startTime_2 = System.currentTimeMillis();
+                            this.batchCompleteApprovalTask(taskApprovalVOS);
+                            long endTime_2 = System.currentTimeMillis();
+                            long executionTime_2 = endTime_2 - startTime_2;
+                            log.info("batchCompleteApprovalTask执行时间:" + executionTime_2 + " 毫秒");
+                        } else {
+                            throw new ServiceException("重新保存PDF信息失败");
+                        }
+
+                    } catch (Exception e) {
+                        e.printStackTrace();
+                        throw new ServiceException("重新保存PDF信息失败,原因:" + e.getMessage());
+                    }
+                }
+            }
+        }
+        throw new ServiceException("未获取到任务信息,操作失败!");
+    }*/
         @Override
         public R reSigningEVisaStatus0(List<reSigningEVisaStatus> dtos, String header) throws Exception {
          R result= new R();
@@ -1922,7 +1953,7 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
     }
 
     @Override
-    public void reSigningEVisa(String classify, String taskIds, String contractId, String projectId, Integer type, String header , HttpServletRequest request) {
+    public void reSigningEVisa(String classify, String taskIds, String contractId, String projectId, Integer type, String header,HttpServletRequest request ) {
         //查询任务信息
         List<Task> taskList = jdbcTemplate.query("select * from u_task where id in(" + taskIds + ")", new BeanPropertyRowMapper<>(Task.class));
         if (taskList.size() > 0) {
@@ -2081,11 +2112,14 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
             List<Dept> depts = jdbcTemplate.query(sqlforSkipDept, new BeanPropertyRowMapper<>(Dept.class));
             String roleId = user.getRoleId();
             String deptId = user.getDeptId();
+            if(roleId==null||deptId==null){
+                return true;
+            }
             //既是超级管理员同时是泓创下面的部门才允许跳过填报人赋值
-            if(roleId.contains(SUPER_ADMIN_ROLE_ID)){
+            if(roleId!=null&&roleId.contains(SUPER_ADMIN_ROLE_ID)){
                 Boolean flag = false;
                 for (Dept dept : depts) {
-                    if(deptId.contains(dept.getId().toString())){
+                    if(deptId!=null&&deptId.contains(dept.getId().toString())){
                         flag = true;
                         return flag;
                     }

+ 32 - 0
blade-service/blade-e-visa/pom.xml

@@ -275,6 +275,38 @@
             <artifactId>jsoup</artifactId>
         </dependency>
 
+            <!-- Apache POI for Excel -->
+            <dependency>
+                <groupId>org.apache.poi</groupId>
+                <artifactId>poi</artifactId>
+                <version>5.2.3</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.poi</groupId>
+                <artifactId>poi-ooxml</artifactId>
+                <version>5.2.3</version>
+            </dependency>
+
+        <!-- Apache POI 依赖 -->
+        <dependency>
+            <groupId>org.apache.poi</groupId>
+            <artifactId>poi-ooxml</artifactId>
+            <version>5.2.3</version>
+        </dependency>
+
+        <!-- Apache Commons IO 依赖 -->
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+            <version>2.11.0</version>
+        </dependency>
+
+            <!-- iText for PDF -->
+            <dependency>
+                <groupId>com.itextpdf</groupId>
+                <artifactId>itextpdf</artifactId>
+                <version>5.5.13.3</version>
+            </dependency>
         <!-- 电签相关 end -->
     </dependencies>
     <build>

+ 151 - 0
blade-service/blade-e-visa/src/main/java/org/springblade/evisa/controller/Chek.java

@@ -0,0 +1,151 @@
+package org.springblade.evisa.controller;
+
+import io.swagger.annotations.Api;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springblade.business.vo.ScrSignInfoVO;
+import org.springblade.business.vo.TaskSignInfoVO;
+import org.springblade.common.utils.CommonUtil;
+import org.springblade.common.utils.SnowFlakeUtil;
+import org.springblade.core.oss.model.BladeFile;
+import org.springblade.core.tool.utils.Func;
+import org.springblade.evisa.service.ScrDataService;
+import org.springblade.evisa.utils.FileUtils;
+import org.springblade.resource.feign.NewIOSSClient;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.jdbc.core.BeanPropertyRowMapper;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import java.io.ByteArrayInputStream;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * 清表基础数据表 控制器
+ *
+ * @author BladeX
+ * @since 2022-05-18
+ */
+@RestController
+@AllArgsConstructor
+@Api(value = "电签类", tags = "电签类接口")
+@Slf4j
+public class  Chek {
+
+    @Autowired
+    StringRedisTemplate RedisTemplate;
+    // jdbc
+    private final JdbcTemplate jdbcTemplate;
+    private final NewIOSSClient newIOSSClient;
+    // 线程池
+    @Resource(name = "taskExecutor1")
+    private ThreadPoolExecutor executor;
+
+
+
+    @Scheduled(cron = "0/10 * * * * ?")
+    public void SignInfo() {
+        // 质检SQL
+       // String sql = "select id,file_url as eVisaPdfUrl from u_archive_file where length(file_url)!=char_length(file_url) and file_name not in('封面.pdf','封面1.pdf','卷内目录.pdf','卷内目录1.pdf','背脊.pdf','背脊1.pdf','备考表.pdf','备考表1.pdf') and is_deleted<>10  and  contract_id in(1890322575534399490,1890328157624541186,1887771910584999937) and file_url is not null and file_url like '%.pdf%' LIMIT 30  ";
+        String sql = "select id,file_url as eVisaPdfUrl from u_archive_file where file_url like '%//卷内目录.pdf' and  file_url is not null and file_url like '%.pdf%' LIMIT 30  ";
+
+        List<ScrSignInfoVO> query = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(ScrSignInfoVO.class));
+        if (query != null && query.size() >= 1 ) {
+            for (ScrSignInfoVO dataInfo : query) {
+                if (executor.getQueue().size()<=60 ) {
+                    Long nodeId = dataInfo.getId();
+                    Boolean aBoolean = RedisTemplate.hasKey("sign-" + nodeId);
+
+                    if (!aBoolean) {
+                        RedisTemplate.opsForValue().set("sign-" + nodeId, "1",3600, TimeUnit.SECONDS);
+                        CompletableFuture<Void> runAsync = CompletableFuture.runAsync(() -> {
+                            try {
+                                /*===============执行批量任务===============*/
+                                signTaskBatch(dataInfo);
+                            } catch (Exception e) {
+                                String dsql = "update u_archive_file set is_deleted=9  where id="+nodeId;
+                                jdbcTemplate.execute(dsql);
+                                RedisTemplate.delete("sign-" +nodeId);
+                                e.printStackTrace();
+                            }
+                        }, executor);
+                    }
+                }
+            }
+        }
+        System.out.println("队列数量" + executor.getQueue().size());
+        System.out.println("活跃数量" + executor.getActiveCount());
+        System.out.println("总共数量" + executor.getTaskCount());
+        System.out.println("完成数量" + executor.getCompletedTaskCount());
+    }
+
+
+
+    public void signTaskBatch(ScrSignInfoVO taskApp) throws Exception {
+
+        String pdfurl  =taskApp.getEVisaPdfUrl();
+        Long id  =taskApp.getId();
+
+        InputStream inputStre =getOSSInputStream2(pdfurl);
+        String sysLocalFileUrl = FileUtils.getSysLocalFileUrl();
+        String filecode = SnowFlakeUtil.getId() + "";
+        String dataFileUrl = sysLocalFileUrl + "/pdf/" + filecode + ".pdf";
+
+
+        FileOutputStream fout = new FileOutputStream(dataFileUrl);
+        int bytesRead = 0;
+        byte[] buffer = new byte[8192];
+        while ((bytesRead = inputStre.read(buffer, 0, 8192)) != -1) {
+            fout.write(buffer, 0, bytesRead);
+        }
+        fout.close();
+
+        BladeFile bladeFile = this.newIOSSClient.uploadFile(SnowFlakeUtil.getId() + ".pdf", dataFileUrl);
+
+        if (bladeFile != null && Func.isNotEmpty(bladeFile.getLink())) {
+           String dsql = "update u_archive_file set file_url='"+bladeFile.getLink()+"' ,is_deleted=10  where id="+id;
+           jdbcTemplate.execute(dsql);
+            System.out.println("成功");
+            System.out.println(dsql);
+        }
+        RedisTemplate.delete("sign-" + taskApp.getId());
+    }
+
+    public static InputStream getOSSInputStream2(String urlStr) {
+        try {
+            //获取OSS文件流
+         //  String encodedUrl = URLEncoder.encode(urlStr, StandardCharsets.UTF_8.toString());
+
+            URL url = new URL(urlStr);
+            URLConnection conn = url.openConnection();
+            conn.setRequestProperty("User-Agent", "Mozilla/5.0");
+          //  conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
+            return conn.getInputStream();
+        } catch (Exception e) {
+            System.out.println("zw-----------");
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+
+/*    public static void main(String[] args) throws UnsupportedEncodingException {
+        String data ="https://xinan1.zos.ctyun.cn/huazheng2021/archivedFile/cover/6eae7ee55e6ca24a2cc819534715//卷内目录.pdf";
+
+        getOSSInputStream2(data);
+    }*/
+
+}

+ 3 - 8
blade-service/blade-e-visa/src/main/java/org/springblade/evisa/controller/ScrController.java → blade-service/blade-e-visa/src/main/java/org/springblade/evisa/controller/ChekSignData.java

@@ -1,13 +1,9 @@
 package org.springblade.evisa.controller;
 
-import com.alibaba.fastjson.JSON;
 import io.swagger.annotations.Api;
 import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springblade.business.vo.ScrSignInfoVO;
-import org.springblade.business.vo.TaskSignInfoVO;
-import org.springblade.core.tool.utils.Func;
-import org.springblade.evisa.service.EVDataService;
 import org.springblade.evisa.service.ScrDataService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.redis.core.StringRedisTemplate;
@@ -18,7 +14,6 @@ import org.springframework.web.bind.annotation.RestController;
 
 import javax.annotation.Resource;
 import java.util.List;
-import java.util.Map;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
@@ -33,7 +28,7 @@ import java.util.concurrent.TimeUnit;
 @AllArgsConstructor
 @Api(value = "电签类", tags = "电签类接口")
 @Slf4j
-public class ScrController {
+public class ChekSignData {
 
     @Autowired
     StringRedisTemplate RedisTemplate;
@@ -45,10 +40,10 @@ public class ScrController {
     @Resource(name = "taskExecutor1")
     private ThreadPoolExecutor executor;
 
-    //@Scheduled(cron = "0/10 * * * * ?")
+  //  @Scheduled(cron = "0/10 * * * * ?")
     public void SignInfo() {
         // 质检SQL
-        String sql = "SELECT a.id ,a.e_visa_pdf_url,b.process_instance_id,a.contract_id,a.project_id,c.remark_type,b.status  from u_information_query a ,u_task b ,m_project_info c where a.id=1878990827573747714 and c.id=a.project_id  and a.`status` in(1,2) and a.is_deleted=0 and a.e_visa_pdf_url is not null  and b.form_data_id = a.id and b.`status` in(1,2) ";
+        String sql = "SELECT a.id ,a.e_visa_pdf_url,b.process_instance_id,a.contract_id,a.project_id,c.remark_type from u_information_query a ,u_task b ,m_project_info c where b.id=1903019571036553216 and c.id=a.project_id  and a.`status` in(1,2) and a.is_deleted=0 and a.e_visa_pdf_url is not null  and b.form_data_id = a.id and b.`status` in(2) ";
 
         List<ScrSignInfoVO> query = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(ScrSignInfoVO.class));
         if (query != null && query.size() >= 1 ) {

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

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

+ 0 - 227
blade-service/blade-e-visa/src/main/java/org/springblade/evisa/controller/EVisaController.java

@@ -1,227 +0,0 @@
-package org.springblade.evisa.controller;
-
-import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.JSONObject;
-import io.swagger.annotations.Api;
-import lombok.AllArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.lang.StringUtils;
-import org.springblade.business.entity.Task;
-import org.springblade.business.feign.MessageWarningClient;
-import org.springblade.business.feign.TaskClient;
-import org.springblade.business.vo.TaskApprovalVO;
-import org.springblade.common.utils.SystemUtils;
-import org.springblade.evisa.service.EVisaService;
-import org.springblade.evisa.vo.EVisaTaskApprovalVO;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.data.redis.core.StringRedisTemplate;
-import org.springframework.jdbc.core.JdbcTemplate;
-import org.springframework.transaction.annotation.Transactional;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-import javax.annotation.Resource;
-import java.io.FileNotFoundException;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-
-
-/**
- * 清表基础数据表 控制器
- *
- * @author BladeX
- * @since 2022-05-18
- */
-@RestController
-@AllArgsConstructor
-@RequestMapping("/evisaInfo")
-@Api(value = "电签类", tags = "电签类接口")
-@Slf4j
-public class EVisaController {
-
-    @Autowired
-    StringRedisTemplate RedisTemplate;
-
-    // jdbc
-    private final JdbcTemplate jdbcTemplate;
-
-    //电签服务类
-    private final EVisaService eVisaService;
-
-    // 线程池
-    @Resource(name = "taskExecutor1")
-    private ThreadPoolExecutor executor;
-
-    private final TaskClient taskClient;
-
-    private final MessageWarningClient messageWarningClient;
-
-
-    // 电签主类
-
-   // @Scheduled(cron = "0/10 * * * * ?")
-    public void SignInfo() {
-        //执行代码
-        log.info("扫描开始");
-        String sql = "SELECT * from u_task_batch where is_deleted=0  and id in(SELECT max(id) as id from u_task_batch where is_deleted=0 GROUP BY JSON_EXTRACT(json_data, '$.formDataId')) LIMIT 10 ";
-        //String sql = "SELECT * from u_task_batch where is_deleted=5 and `status`=2";
-        List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql);
-        if (maps != null && maps.size() >= 1 && SystemUtils.isLinux()) {//&& SystemUtils.isLinux()
-            for (Map<String, Object> dataInfo : maps) {
-                if (executor.getQueue().size()<=40 ) {
-                    String jsonData = dataInfo.get("json_data") + "";
-                    TaskApprovalVO taskApprovalVO = JSON.parseObject(jsonData, TaskApprovalVO.class);
-                    String taskBatchId = dataInfo.get("id").toString();
-                    Long userId = Long.valueOf(dataInfo.get("create_user") + "");
-                    String nickName = dataInfo.get("nick_name") + "";
-                    Boolean aBoolean = RedisTemplate.hasKey("sign-" + taskApprovalVO.getFormDataId());
-                    taskApprovalVO.setId(taskBatchId);
-                    taskApprovalVO.setUserId(userId);
-                    taskApprovalVO.setNickName(nickName);
-
-                    if (!aBoolean) {
-                        RedisTemplate.opsForValue().set("sign-" + taskApprovalVO.getFormDataId(), "1",900, TimeUnit.SECONDS);
-                        CompletableFuture<Void> runAsync = CompletableFuture.runAsync(() -> {
-                            try {
-                                /*===============执行批量任务===============*/
-                                this.checkIsExsitTaskBatch(taskApprovalVO);
-                            } catch (Exception e) {
-                                e.printStackTrace();
-                            }
-                        }, executor);
-                    }
-                }
-            }
-        }
-        System.out.println("队列数量" + executor.getQueue().size());
-        System.out.println("活跃数量" + executor.getActiveCount());
-        System.out.println("总共数量" + executor.getTaskCount());
-        System.out.println("完成数量" + executor.getCompletedTaskCount());
-    }
-
-    @Transactional
-    public void checkIsExsitTaskBatch(TaskApprovalVO taskApprovalVO){
-        if ("OK".equals(taskApprovalVO.getFlag())) { // 同意
-            // 调用电签接口
-            String eVisaStatus = eVisaService.eVisa(JSONObject.parseObject(JSONObject.toJSONString(taskApprovalVO), EVisaTaskApprovalVO.class));
-
-            if (eVisaStatus == null || StringUtils.isEmpty(eVisaStatus)) {
-                //状态改为 == 4 --
-            } else if ("notpdfsgin".equals(eVisaStatus) || eVisaStatus.contains("notpdfsgin")) { //没有找到关键字Id
-               //状态改为 == 4 --
-                String up_task = "update u_task_batch set is_deleted=5 where id="+taskApprovalVO.getId();
-                jdbcTemplate.execute(up_task);
-                String up_task_par = "update u_task_parallel set e_visa_status=99,e_visa_content='pdf关键字与数据库中id不匹配' ,update_time=SYSDATE() where parallel_process_instance_id='"+taskApprovalVO.getParallelProcessInstanceId()+"'";
-                jdbcTemplate.execute(up_task_par);
-
-            } else if ("success".equals(eVisaStatus) || eVisaStatus.contains("success")) { //成功操作
-                //将 状态改为
-                String up_task_par = "update u_task_parallel set status=2, e_visa_status=1,e_visa_content='电签成功' ,update_time=SYSDATE() where parallel_process_instance_id='"+taskApprovalVO.getParallelProcessInstanceId()+"'";
-                jdbcTemplate.execute(up_task_par);
-
-                //获取状态为1(待审批)的分支流程
-                List<Task> tasks = taskClient.queryTaskListByFormDataId(taskApprovalVO.getFormDataId());
-                Task masterTask = tasks.get(0);
-
-                String  sql = "SELECT a.* from u_task_parallel a where a.process_instance_id=(SELECT process_instance_id from u_task_parallel b where  b.parallel_process_instance_id='"+taskApprovalVO.getParallelProcessInstanceId()+"') and is_deleted=0 and `status`=1 and sort not in(SELECT fixed_flow_branch_sort from u_fixed_flow_link where fixed_flow_id ="+masterTask.getFixedFlowId()+" and  flow_task_type=2 ) ";
-                List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql);
-                if (maps == null || maps.size() == 0 ) {
-                    // 最后修改计量数据
-                    //说明都审批完成,将主表状态更改为已完成
-                    String finalPdfUrl = null;
-                    if (eVisaStatus.contains("@@@@")) {
-                        finalPdfUrl = eVisaStatus.split("@@@@")[1];
-                    }
-                    //todo ===================== 执行合同章
-                    try {
-                        //执行合同章,返回的是盖有合同章的PDF路径
-                        finalPdfUrl = this.eVisaService.eVisaContractSeal(JSONObject.parseObject(JSONObject.toJSONString(taskApprovalVO), EVisaTaskApprovalVO.class), finalPdfUrl);
-                    } catch (Exception e) {
-                        e.printStackTrace();
-                    }
-                    //修改主流程状态为已完成
-                    String up_task = "update u_task set status=2,update_time=SYSDATE() where is_deleted=0 and id="+taskApprovalVO.getTaskId();
-                    jdbcTemplate.execute(up_task);
-                    //修改对应的业务数据状态为已审批
-                    int approvalType = taskApprovalVO.getApprovalType();
-
-                    if(approvalType<=4){ //质检 修改queryinfo 数据信息
-                        taskClient.updateBusinessDataByFormDataId(masterTask, 2, finalPdfUrl, taskApprovalVO.getUserId());
-                        //返回电签成功的pdf路径,给试验用
-                        try {
-                            taskClient.trialSelfTaskRelated(taskApprovalVO, finalPdfUrl, taskApprovalVO.getId());
-                        } catch (FileNotFoundException e) {
-                            throw new RuntimeException(e);
-                        }
-                    }else{
-                        UpMeterSignDataInfo(taskApprovalVO,finalPdfUrl,2);
-                    }
-                }else {
-                    //只更新PDF路径
-                    taskClient.updateBusinessDataByFormDataId(masterTask, 1, eVisaStatus.contains("@@@@") ? eVisaStatus.split("@@@@")[1] : null, taskApprovalVO.getUserId());
-                    String finalPdfUrl = eVisaStatus.contains("@@@@") ? eVisaStatus.split("@@@@")[1] : null;
-                    int approvalType = taskApprovalVO.getApprovalType();
-                    if(approvalType<=4){
-                        try {
-                            taskClient.trialSelfTaskRelated(taskApprovalVO, finalPdfUrl, taskApprovalVO.getId());
-                        } catch (FileNotFoundException e) {
-                            throw new RuntimeException(e);
-                        }
-                    }else{
-                        UpMeterSignDataInfo(taskApprovalVO,finalPdfUrl,1);
-                    }
-                }
-            }else if("eContractError".equals(eVisaStatus) || eVisaStatus.contains("eContractError")){ //合同段信息出错
-                this.jdbcTemplate.execute("delete from u_task_batch where id="+taskApprovalVO.getId());
-            }else if ("eVisaError".equals(eVisaStatus) || eVisaStatus.contains("eVisaError")) {
-                // 修改 主 任务 u_task 表 状态改为3
-                String up_task_par = "update u_task_parallel set status=2 ,e_visa_status=99 ,e_visa_content='"+eVisaStatus.split("####")[1]+"' where parallel_process_instance_id='"+taskApprovalVO.getParallelProcessInstanceId()+"'";
-                this.jdbcTemplate.execute("delete from u_task_batch where id="+taskApprovalVO.getId());
-                jdbcTemplate.execute(up_task_par);
-            }else {
-
-            }
-            RedisTemplate.delete("sign-" + taskApprovalVO.getFormDataId());
-        }else{ //废除
-            // 修改 主 任务 u_task 表 状态改为3
-            String up_task_par = "update u_task_parallel set status=3 where parallel_process_instance_id='"+taskApprovalVO.getParallelProcessInstanceId()+"'";
-            String up_task = "update u_task set status=3 where id='"+taskApprovalVO.getTaskId()+"'";
-            this.jdbcTemplate.execute("delete from u_task_batch where id="+taskApprovalVO.getId());
-            jdbcTemplate.execute(up_task_par);
-            jdbcTemplate.execute(up_task);
-
-            if(taskApprovalVO.getApprovalType() == 3){
-                jdbcTemplate.execute("update u_contract_log set status=0 where id='"+taskApprovalVO.getFormDataId()+"'");
-            }else if (taskApprovalVO.getApprovalType()==8) {
-                this.jdbcTemplate.execute("update u_entrust_info set status=1 where id=(SELECT wbs_id from u_information_query where id='"+taskApprovalVO.getFormDataId()+"')");
-            }else {
-                jdbcTemplate.execute("update u_information_query set e_visa_pdf_url='',status=0 where id='"+taskApprovalVO.getFormDataId()+"'");
-            }
-            RedisTemplate.delete("sign-" + taskApprovalVO.getFormDataId());
-        }
-    }
-
-    // 电签成功状态修改---计量系统
-    public void UpMeterSignDataInfo(TaskApprovalVO taskApprovalVO,String finalPdfUrl,int type){
-        if (taskApprovalVO.getApprovalType()==5) { //计量 -
-            this.jdbcTemplate.execute("update s_interim_pay_certificate set raw_url='"+finalPdfUrl+"' where contract_period_id = " + taskApprovalVO.getFormDataId());
-            this.jdbcTemplate.execute("delete from u_task_batch where id="+taskApprovalVO.getId());
-            RedisTemplate.delete("sign-" + taskApprovalVO.getFormDataId());
-        } else if (taskApprovalVO.getApprovalType()==6 || taskApprovalVO.getApprovalType()==7) { //计量 --材料 ,中间
-            this.jdbcTemplate.execute("update s_material_start_statement set raw_url='"+finalPdfUrl+"' where meter_period_id = " + taskApprovalVO.getFormDataId());
-            this.jdbcTemplate.execute("delete from u_task_batch where id="+taskApprovalVO.getId());
-            RedisTemplate.delete("sign-" + taskApprovalVO.getFormDataId());
-        } else if (taskApprovalVO.getApprovalType()==8) { // 委托单
-           if(type == 2){
-               this.jdbcTemplate.execute("update u_entrust_info set sample_status=2,status="+(type+1)+",entrust_e_pdf='"+finalPdfUrl+"' where id=(SELECT wbs_id from u_information_query where id='"+taskApprovalVO.getFormDataId()+"')");
-           }
-            jdbcTemplate.execute("update u_information_query set e_visa_pdf_url='"+finalPdfUrl+"',status="+type+" where id='"+taskApprovalVO.getFormDataId()+"'");
-
-            this.jdbcTemplate.execute("delete from u_task_batch where id="+taskApprovalVO.getId());
-            RedisTemplate.delete("sign-" + taskApprovalVO.getFormDataId());
-        }
-    }
-}

+ 0 - 203
blade-service/blade-e-visa/src/main/java/org/springblade/evisa/controller/EVisaController2.java

@@ -1,203 +0,0 @@
-package org.springblade.evisa.controller;
-
-import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.JSONObject;
-import io.swagger.annotations.Api;
-import lombok.AllArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import net.logstash.logback.encoder.org.apache.commons.lang3.ObjectUtils;
-import org.apache.commons.lang.StringUtils;
-import org.springblade.business.entity.Task;
-import org.springblade.business.entity.TaskParallel;
-import org.springblade.business.feign.TaskClient;
-import org.springblade.business.vo.TaskApprovalVO;
-import org.springblade.common.constant.CommonConstant;
-import org.springblade.common.utils.CommonUtil;
-import org.springblade.common.utils.SystemUtils;
-import org.springblade.core.oss.model.BladeFile;
-import org.springblade.core.tool.api.R;
-import org.springblade.core.tool.utils.Func;
-import org.springblade.evisa.service.EVisaService;
-import org.springblade.evisa.utils.FileUtils;
-import org.springblade.evisa.utils.PDFUtils;
-import org.springblade.evisa.utils.PdfAddimgUtil;
-import org.springblade.evisa.vo.EVisaTaskApprovalVO;
-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.jdbc.core.BeanPropertyRowMapper;
-import org.springframework.jdbc.core.JdbcTemplate;
-import org.springframework.scheduling.annotation.Async;
-import org.springframework.scheduling.annotation.Scheduled;
-import org.springframework.transaction.annotation.Transactional;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.RestController;
-
-import javax.annotation.Resource;
-import java.io.FileNotFoundException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
-
-
-/**
- * 清表基础数据表 控制器
- *
- * @author BladeX
- * @since 2022-05-18
- */
-@RestController
-@AllArgsConstructor
-@RequestMapping("/evisaInfo")
-@Api(value = "电签类", tags = "电签类接口")
-@Slf4j
-public class EVisaController2 {
-
-    @Autowired
-    StringRedisTemplate RedisTemplate;
-
-    // jdbc
-    private final JdbcTemplate jdbcTemplate;
-
-    //电签服务类
-    private final EVisaService eVisaService;
-
-    // 线程池
-    @Resource(name = "taskExecutor1")
-    private ThreadPoolExecutor executor;
-
-    private final TaskClient taskClient;
-
-    private final NewIOSSClient newIOSSClient;
-
-    // 电签主类
-   // @Scheduled(cron = "0/10 * * * * ?")
-    public void SignInfo() {
-        //执行代码
-        log.info("扫描开始");
-       // String sql = "SELECT c.* from (SELECT a.id,b.id as reportId,(SELECT COUNT(1) from u_task_parallel v where v.process_instance_id=a.process_instance_id and v.`status`=2) as count2  from u_task a , s_interim_pay_certificate b where a.meter_task_type=1 and a.is_deleted=0 and a.status=1 and a.form_data_id=b.contract_period_id and b.is_deleted=0 and b.pre_pdf_url is null) c where c.count2>=1 ";
-        //String sql = "SELECT * from u_task_batch where is_deleted=5 and `status`=2";
-        List<Map<String, Object>> maps = new ArrayList<>();//jdbcTemplate.queryForList(sql);
-
-        Map<String, Object> task = new HashMap<>();//taskClient.getTaskBatchList();
-        task.put("id","1869535635736363008");
-        task.put("reportId","1864482462625693696");
-
-        Map<String, Object> task1 = new HashMap<>();//taskClient.getTaskBatchList();
-        task.put("id","1871012255089295360");
-        task.put("reportId","1866674550960410625");
-
-        maps.add(task);
-      //  maps.add(task1);
-
-        if (maps != null && maps.size() >= 1) {//&& SystemUtils.isLinux()
-            for (Map<String, Object> dataInfo : maps) {
-                if (executor.getQueue().size()<=2 ) {
-                    String id = dataInfo.get("id") + "";
-                    String dataId = dataInfo.get("reportId") + "";
-
-                    Boolean aBoolean = RedisTemplate.hasKey("sign-" + dataId);
-
-                    if (!aBoolean) {
-                        RedisTemplate.opsForValue().set("sign-" + dataId, "1",900, TimeUnit.SECONDS);
-                        CompletableFuture<Void> runAsync = CompletableFuture.runAsync(() -> {
-                            try {
-                                /*===============执行批量任务===============*/
-                                this.taskMeterPdfInfo2(id,dataId,0);
-                            } catch (Exception e) {
-                                e.printStackTrace();
-                            }
-                        }, executor);
-                    }
-                }
-            }
-        }
-        System.out.println("队列数量" + executor.getQueue().size());
-        System.out.println("活跃数量" + executor.getActiveCount());
-        System.out.println("总共数量" + executor.getTaskCount());
-        System.out.println("完成数量" + executor.getCompletedTaskCount());
-    }
-
-    @Async
-    public void taskMeterPdfInfo2(@RequestParam String taskId, @RequestParam String reportId, @RequestParam Integer type) {
-        try {
-            Task task = jdbcTemplate.query("SELECT * FROM u_task WHERE id = ?", new Object[]{taskId}, new BeanPropertyRowMapper<>(Task.class)).stream().findAny().orElse(null);
-
-            String sql = "";
-            if (type == 0) {
-                sql = "select raw_url from s_interim_pay_certificate where id = ?";
-            } else {
-                sql = "select raw_url from s_material_start_statement where id = ?";
-            }
-            String pdfUrl = jdbcTemplate.queryForObject(sql, String.class, reportId);
-            if (StringUtils.isBlank(pdfUrl)) {
-            } else {
-                List<String> pdfSignIds = PDFUtils.getPdfSignIds(pdfUrl);
-                if (pdfSignIds.size() > 0) {
-                    String ids = String.join(",", pdfSignIds);
-                    String sqlp = "SELECT * from u_task_parallel WHERE process_instance_id = '" + task.getProcessInstanceId() + "' and `status`=2 and is_deleted=0";
-                    List<TaskParallel> taskParallels = jdbcTemplate.query(sqlp, new BeanPropertyRowMapper<>(TaskParallel.class));
-                    List<Map<String, Object>> maps = new ArrayList<>();
-                    for (TaskParallel parallel : taskParallels) {
-                        String sqlinfo = "SELECT * from ( SELECT DISTINCT a.id,a.pyzbx ,a.pyzby,a.project_id,(SELECT signature_file_url from m_sign_pfx_file where is_register=1 and certificate_user_id='" + parallel.getTaskUser() + "' and is_deleted=0  ) as signature_file_url,a.type from m_textdict_info a where  a.type =2 and a.id in (" + ids + ")  and sig_role_id in (SELECT DISTINCT c.role_id from m_project_assignment_user c  where c.contract_id=" + task.getContractId() + " and user_id=" + parallel.getTaskUser() + " and c.is_deleted=0 ) ) x where x.signature_file_url is not null ";
-                        List<Map<String, Object>> maps2 = jdbcTemplate.queryForList(sqlinfo);
-                        Map<String, List<Map<String, Object>>> peopleByAge = maps2.stream()
-                                .collect(Collectors.groupingBy(hada -> (Func.toStr(hada.get("id")))));
-
-                        for (String keyId : peopleByAge.keySet()) {
-                            int exId = 0;
-                            List<Map<String, Object>> keyList = peopleByAge.get(keyId);
-                            if (keyList != null && keyList.size() == 1) {
-                                maps.addAll(keyList);
-                                exId = 1;
-                            } else if (keyList != null && keyList.size() >= 2) {
-                                for (Map<String, Object> datax : keyList) {
-                                    if ((datax.get("project_id") + "").equals(task.getProjectId())) {
-                                        maps.add(datax);
-                                        exId = 1;
-                                    }
-                                }
-                            }
-                            if (exId == 0) {
-                                maps.add(keyList.get(0));
-                            }
-                        }
-                    }
-
-                    if (Func.isNotEmpty(maps) || maps.size() >= 1) {
-                        InputStream ossInputStream = CommonUtil.getOSSInputStream(pdfUrl);
-                        String localPdfPath = FileUtils.getSysLocalFileUrl() + "/pdf//" + task.getId() + ".pdf";
-                        CommonUtil.convert(ossInputStream, localPdfPath);
-                        PdfAddimgUtil.pdfAddImgInfo(localPdfPath, maps);
-                        String sys_isonline = ParamCache.getValue(CommonConstant.SYS_ISONLINE);
-
-                            BladeFile bladeFile = this.newIOSSClient.uploadFile(task.getId() + ".pdf", localPdfPath);
-                            if (bladeFile != null && ObjectUtils.isNotEmpty(bladeFile.getLink())) {
-                                if (type == 0) {
-                                    jdbcTemplate.update("update s_interim_pay_certificate set pre_pdf_url ='"+bladeFile.getLink()+"' where id="+reportId);
-                                } else {
-                                    jdbcTemplate.update("update s_material_start_statement set pre_pdf_url ='"+bladeFile.getLink()+"' where id="+reportId);
-                                }
-                            }
-
-                    } else {
-                        System.out.println("没有签字Key");
-                    }
-
-                } else {
-                    System.out.println("没有签字Id");
-                }
-            }
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-    }
-}

+ 0 - 130
blade-service/blade-e-visa/src/main/java/org/springblade/evisa/controller/EVisaController4.java

@@ -1,130 +0,0 @@
-package org.springblade.evisa.controller;
-
-import io.swagger.annotations.Api;
-import lombok.AllArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import net.logstash.logback.encoder.org.apache.commons.lang3.ObjectUtils;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang.StringUtils;
-import org.springblade.business.entity.Task;
-import org.springblade.business.entity.TaskParallel;
-import org.springblade.business.feign.TaskClient;
-import org.springblade.common.constant.CommonConstant;
-import org.springblade.common.utils.CommonUtil;
-import org.springblade.common.utils.SnowFlakeUtil;
-import org.springblade.core.oss.model.BladeFile;
-import org.springblade.core.tool.utils.Func;
-import org.springblade.evisa.service.EVisaService;
-import org.springblade.evisa.utils.FileUtils;
-import org.springblade.evisa.utils.PDFUtils;
-import org.springblade.evisa.utils.PdfAddimgUtil;
-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.jdbc.core.BeanPropertyRowMapper;
-import org.springframework.jdbc.core.JdbcTemplate;
-import org.springframework.mock.web.MockMultipartFile;
-import org.springframework.scheduling.annotation.Async;
-import org.springframework.scheduling.annotation.Scheduled;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.RestController;
-import org.springframework.web.multipart.MultipartFile;
-
-import javax.annotation.Resource;
-import java.io.ByteArrayInputStream;
-import java.io.FileOutputStream;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
-
-
-/**
- * 清表基础数据表 控制器
- *
- * @author BladeX
- * @since 2022-05-18
- */
-@RestController
-@AllArgsConstructor
-@RequestMapping("/evisaInfo")
-@Api(value = "电签类", tags = "电签类接口")
-@Slf4j
-public class EVisaController4 {
-
-    @Autowired
-    StringRedisTemplate RedisTemplate;
-
-    // jdbc
-    private final JdbcTemplate jdbcTemplate;
-
-    // 线程池
-    @Resource(name = "taskExecutor1")
-    private ThreadPoolExecutor executor;
-
-
-    private final NewIOSSClient newIOSSClient;
-
-    // 电签主类
-   // @Scheduled(cron = "0/10 * * * * ?")
-    public void SignInfo() {
-        //执行代码
-        log.info("扫描开始");
-        String sql = "SELECT * from u_archive_file where file_url LIKE '%//卷%' and LENGTH(id)<=10 ";
-        List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql);
-
-        if (maps != null && maps.size() >= 1) {//&& SystemUtils.isLinux()
-            for (Map<String, Object> dataInfo : maps) {
-                if (executor.getQueue().size()<=100 ) {
-                    String id = dataInfo.get("id") + "";
-                    String fileUrl = dataInfo.get("file_url") + "";
-
-                    Boolean aBoolean = RedisTemplate.hasKey("sign-" + id);
-
-                    if (!aBoolean) {
-                        RedisTemplate.opsForValue().set("sign-" + id, "1",900, TimeUnit.SECONDS);
-                        CompletableFuture<Void> runAsync = CompletableFuture.runAsync(() -> {
-                            try {
-                                /*===============执行批量任务===============*/
-                                this.taskMeterPdfInfo2(id,fileUrl);
-
-                            } catch (Exception e) {
-                                e.printStackTrace();
-                            }
-                        }, executor);
-                    }
-                }
-            }
-        }
-        System.out.println("队列数量" + executor.getQueue().size());
-        System.out.println("活跃数量" + executor.getActiveCount());
-        System.out.println("总共数量" + executor.getTaskCount());
-        System.out.println("完成数量" + executor.getCompletedTaskCount());
-    }
-
-    @Async
-    public void taskMeterPdfInfo2(@RequestParam String id, @RequestParam String fileUrl) throws Exception {
-        InputStream inputStreamByUrl = CommonUtil.getOSSInputStreamTow(fileUrl);
-        byte[] result = IOUtils.toByteArray(inputStreamByUrl);
-        String dataFileUrl = FileUtils.getSysLocalFileUrl() + "/privateUrl/" + id + ".pdf";
-        if (result != null) {
-            MultipartFile files = new MockMultipartFile("file", SnowFlakeUtil.getId() + ".pdf", "text/plain", IOUtils.toByteArray(new ByteArrayInputStream(result)));
-            //重新上传
-            BladeFile bladeFile = this.newIOSSClient.uploadFileByInputStream(files);
-            if (bladeFile != null) {
-                 String sql = "update u_archive_file set file_url='"+bladeFile.getLink()+"' , pdf_file_url='"+bladeFile.getLink()+"' where id="+id;
-                 jdbcTemplate.execute(sql);
-                System.out.println("11--"+bladeFile.getLink());
-            } else {
-                System.out.println("---四百--");
-            }
-        }
-    }
-}

+ 0 - 150
blade-service/blade-e-visa/src/main/java/org/springblade/evisa/controller/synDataController.java

@@ -1,150 +0,0 @@
-package org.springblade.evisa.controller;
-
-
-import io.swagger.annotations.Api;
-import lombok.AllArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.jsoup.Jsoup;
-import org.jsoup.nodes.Document;
-import org.jsoup.nodes.Element;
-import org.jsoup.select.Elements;
-import org.springblade.core.tool.utils.FileUtil;
-import org.springblade.core.tool.utils.IoUtil;
-import org.springblade.evisa.utils.SignFtpUtilBy210;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.data.redis.core.StringRedisTemplate;
-import org.springframework.jdbc.core.JdbcTemplate;
-import org.springframework.scheduling.annotation.Scheduled;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-import javax.annotation.Resource;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.InputStream;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-
-
-/**
- * 清表基础数据表 控制器
- *
- * @author BladeX
- * @since 2022-05-18
- */
-@RestController
-@AllArgsConstructor
-@RequestMapping("/evisaInfo")
-@Api(value = "电签类", tags = "电签类接口")
-@Slf4j
-public class synDataController {
-
-    @Autowired
-    StringRedisTemplate RedisTemplate;
-
-    // jdbc
-    private final JdbcTemplate jdbcTemplate;
-
-
-    // 线程池
-    @Resource(name = "taskExecutor1")
-    private ThreadPoolExecutor executor;
-
-
-
-    // 默认值定时器操作
-    //@Scheduled(cron = "0/10 * * * * ?")
-    public void SignInfo() {
-        //执行代码
-        log.info("扫描开始");
-        String sql = "SELECT MAX(p_key_id) as p_key_id,html_url from m_wbs_tree_private22 where type=2 and is_deleted=0 and wbs_type=1 and html_url is not null  GROUP BY html_url LIMIT 30";
-        List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql);
-        if (maps != null && maps.size() >= 1) {//&& SystemUtils.isLinux()
-            for (Map<String, Object> dataInfo : maps) {
-                if (executor.getQueue().size()<=40 ) {
-                    String pKeyId = dataInfo.get("p_key_id").toString();
-                    String htmlUrl = dataInfo.get("html_url") + "";
-                    Boolean aBoolean = RedisTemplate.hasKey("sign-" + pKeyId);
-
-                    if (!aBoolean) {
-                        RedisTemplate.opsForValue().set("sign-" + pKeyId, "1",100, TimeUnit.SECONDS);
-                        CompletableFuture<Void> runAsync = CompletableFuture.runAsync(() -> {
-                            try {
-                                /*===============执行批量任务===============*/
-                                this.checkIsExsitTaskBatch(pKeyId,htmlUrl );
-                            } catch (Exception e) {
-                                e.printStackTrace();
-                            }
-                        }, executor);
-                    }
-                }
-            }
-        }
-        System.out.println("队列数量" + executor.getQueue().size());
-        System.out.println("活跃数量" + executor.getActiveCount());
-        System.out.println("总共数量" + executor.getTaskCount());
-        System.out.println("完成数量" + executor.getCompletedTaskCount());
-    }
-
-    // 逻辑处理
-    private void checkIsExsitTaskBatch(String pKeyId, String htmlUrl) throws FileNotFoundException {
-        String textSql  = "SELECT * from m_textdict_info where tab_id='"+pKeyId+"' and type=4";
-        List<Map<String, Object>> mapList = jdbcTemplate.queryForList(textSql);
-        if(mapList.size()>=1){
-            String reHtml = "";
-            String htmlName = "";
-            if(htmlUrl.indexOf("hongchuangyanfa/Desktop")>=0){
-                reHtml = htmlUrl.substring(htmlUrl.lastIndexOf("hongchuangyanfa/Desktop/")+24,htmlUrl.length());
-            }
-            htmlName = htmlUrl.substring(htmlUrl.lastIndexOf("/")+1,htmlUrl.length());
-            String localUrl = "/Users/hongchuangyanfa/Desktop/pdf/"+htmlName;
-            SignFtpUtilBy210.downloadFile(localUrl, reHtml);
-
-            //读取html页面信息
-            InputStream inputStreamByUrl = new FileInputStream(new File(localUrl));
-            String htmlString = IoUtil.readToString(inputStreamByUrl);
-
-            //样式集合
-            Document doc = Jsoup.parse(htmlString);
-            //解析
-            Element table = doc.select("table").first();
-            if(table!=null) {
-                Elements trs = table.select("tr");
-                for (Map<String, Object> dataText : mapList) {
-                    String trindex = dataText.get("col_key") + "";
-                    String sigRoleName = dataText.get("sig_role_name") + "";
-
-                    Elements elementsByAttribute = table.getElementsByAttributeValue("keyname", trindex);
-                    if (elementsByAttribute.size() >= 1) {
-                        for (Element element : elementsByAttribute) {
-                            if (element.html().indexOf("el-input") >= 0) {
-                                if (!element.hasAttr("defText")) {
-                                    element.children().removeAttr("defText");
-                                    element.children().attr("defText", sigRoleName);
-                                }
-
-                            } else {
-                                if (!element.hasAttr("defText")) {
-                                    element.children().removeAttr("defText");
-                                    element.attr("defText", sigRoleName);
-                                }
-                            }
-                            File writeFile = new File(localUrl);
-                            FileUtil.writeToFile(writeFile, doc.html(), Boolean.parseBoolean("UTF-8"));
-                        }
-                    }
-                }
-                SignFtpUtilBy210.uploadFile(localUrl,reHtml);
-            }
-        }
-        String upSql  = "update m_wbs_tree_private22 set is_deleted=10 where p_key_id='"+pKeyId+"'";
-        jdbcTemplate.execute(upSql);
-        RedisTemplate.delete("sign-" + pKeyId);
-    }
-
-}

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

@@ -8,6 +8,7 @@ import cn.hutool.core.io.file.FileReader;
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import lombok.AllArgsConstructor;
+import lombok.Synchronized;
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang.StringUtils;
 import org.springblade.business.entity.InformationQuery;
@@ -22,11 +23,10 @@ import org.springblade.common.utils.CommonUtil;
 import org.springblade.common.utils.SnowFlakeUtil;
 import org.springblade.common.utils.SystemUtils;
 import org.springblade.core.launch.StartEventListener;
+import org.springblade.core.log.exception.ServiceException;
+import org.springblade.core.log.publisher.ErrorLogPublisher;
 import org.springblade.core.oss.model.BladeFile;
-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.ResourceUtil;
+import org.springblade.core.tool.utils.*;
 import org.springblade.evisa.service.EVDataService;
 import org.springblade.evisa.service.EVisaService;
 import org.springblade.evisa.utils.FileUtils;
@@ -76,6 +76,7 @@ public class EVDataServiceImpl implements EVDataService {
      */
 
     @Override
+    @Synchronized
     public void signTaskBatch(TaskSignInfoVO taskApp) {
         //获取pdf 文件
         if (taskApp.getFlag().equals("OK")) {
@@ -86,9 +87,7 @@ public class EVDataServiceImpl implements EVDataService {
             this.addSignatureTaskBatch(taskApp);
             //for循环 pdfUrl分割
             String fileUrl = CommonUtil.replaceOssUrl(taskApp.getSignPdfUrl());
-            System.out.println("s1231312"+fileUrl);
             List<String> eVisaConfigList = PDFUtils.getPdfSignIds(fileUrl, taskApp);
-            System.out.println("安心签关键字个数" + eVisaConfigList.size());
             if (eVisaConfigList == null || eVisaConfigList.size() == 0) {
                 //没有电签配置,默认当前任务为不签字审批,返回成功
                 taskApp.setSigState(2);
@@ -99,10 +98,8 @@ public class EVDataServiceImpl implements EVDataService {
             // 获取pdf上的电签Ids
             String ids = String.join(",", eVisaConfigList);
             if (taskApp.getRemarkType().equals("1")) { //安心签
-                System.out.println("进入安心签");
                 //添加电签策略
                 List<SealStrategyVO> strategyListByAXQ = getStrategyListByAXQ(taskApp, ids);
-                System.out.println("安心签策略个数" + strategyListByAXQ.size());
                 if (strategyListByAXQ == null || Func.isEmpty(strategyListByAXQ) || strategyListByAXQ.size() == 0) {
                     List<Map<String, Object>> mapList = jdbcTemplate.queryForList("SELECT * from m_textdict_info where type=6  and is_deleted=0 and id in(" + ids + ")");
                     if (mapList != null && mapList.size() > 0) {
@@ -123,7 +120,6 @@ public class EVDataServiceImpl implements EVDataService {
                 }
 
                 //调用签字逻辑
-                System.out.println("安心签完毕开始签字" );
                 signTaskBatchByAXQZ(strategyListByAXQ, taskApp);
                 if (taskApp.getSigState() != 1) {
                     return;
@@ -167,12 +163,14 @@ public class EVDataServiceImpl implements EVDataService {
             }
             RedisTemplate.delete("sign-" + taskApp.getFormDataId());
             // 添加废除通知
-            //messageWarningClient.
         }
         //循环结束
     }
 
 
+
+
+
     public void addSignatureTaskBatch(TaskSignInfoVO taskApp) {
         // 添加签字任务
         if (taskApp.getSigType() == 1) {
@@ -198,6 +196,7 @@ public class EVDataServiceImpl implements EVDataService {
     }
 
     // 获取pdf 文件
+
     @Transactional
     public void SignBackPdfInfo(TaskSignInfoVO taskApp) {
         Integer totalCount = this.jdbcTemplate.queryForObject("select min(exe_count) as exe_count from u_task_parallel where parallel_process_instance_id in(" + taskApp.getParallelProcessInstanceId() + ")", Integer.class);
@@ -211,7 +210,7 @@ public class EVDataServiceImpl implements EVDataService {
             //电签成功
             if (taskApp.getSigState() == 1) { //签字成功
                 String updateSql = "";
-                if (taskApp.getApprovalType() == 1) { //
+                if (taskApp.getApprovalType() == 1 || taskApp.getApprovalType() == 9) { //
                     //
                     String sys_isonline = ParamCache.getValue(CommonConstant.SYS_ISONLINE);
                     String pdfPage = "0";
@@ -260,7 +259,7 @@ public class EVDataServiceImpl implements EVDataService {
                         } else if (taskApp.getSigState() == 3) {
                             taskStatus = "已废除";
                         }
-                        String updTrial = "update u_trial_self_inspection_record set status=" + taskApp.getSigType() + ", task_status='" + taskStatus + "',pdf_url='" + taskApp.getLastFilePdfUrl() + "' where id=(select b.trial_self_inspection_record_id from u_task b,u_task_parallel c where b.process_instance_id=c.process_instance_id and b.is_deleted=0 and c.is_deleted=0 and b.status in(1,2) and parallel_process_instance_id='" + taskApp.getParallelProcessInstanceId() + "')";
+                        String updTrial = "update u_trial_self_inspection_record set status=" + taskApp.getSigType() + ", task_status='" + taskStatus + "',pdf_url='" + taskApp.getLastFilePdfUrl() + "' where id=(select b.trial_self_inspection_record_id from u_task b  where b.id = '" + taskApp.getTaskId() + "')";
                         jdbcTemplate.execute(updTrial);
 
                         /**
@@ -318,6 +317,12 @@ public class EVDataServiceImpl implements EVDataService {
                         }
                     }
                     updateSql = "update u_information_query set pdf_trial_url_position='" + pdfTrialUrlPosition + "',business_time='" + taskApp.getPdfDate() + "',node_pdf_url='" + nodePdfUrl + "',e_visa_pdf_page=" + pdfPage + ",e_visa_pdf_size=" + pdfSize + ",e_visa_pdf_url='" + taskApp.getLastFilePdfUrl() + "',status='" + taskApp.getSigType() + "',update_time=SYSDATE() where id='" + taskApp.getFormDataId() + "' ";
+                    //修改 计量 需要引用的 附件信息
+                    String updataFile = "update s_attachment_form set file_url='"+nodePdfUrl+"' ,file_pdf_url='"+nodePdfUrl+"' where select_id='"+taskApp.getFormDataId()+"' ";
+                    jdbcTemplate.execute(updataFile);
+
+                    String upTsk = "update s_attachment_form_task set file_url='"+nodePdfUrl+"' ,file_pdf_url='"+nodePdfUrl+"' where select_id='"+taskApp.getFormDataId()+"' ";
+                    jdbcTemplate.execute(upTsk);
                 } else if (taskApp.getApprovalType() == 2) {
                     updateSql = "update u_archive_file set e_visa_file='" + taskApp.getLastFilePdfUrl() + "',status='" + taskApp.getSigType() + "',update_time=SYSDATE() where id='" + taskApp.getFormDataId() + "' ";
                 } else if (taskApp.getApprovalType() == 3) { // 日志
@@ -346,11 +351,15 @@ public class EVDataServiceImpl implements EVDataService {
                 }
             }
             RedisTemplate.delete("sign-" + taskApp.getFormDataId());
+            Thread.sleep(1000);
         } catch (Exception e) {
+            RedisTemplate.delete("sign-" + taskApp.getFormDataId());
             taskApp.setSigState(2);
             taskApp.setSignSmg("修改业务数据异常-请联系开发人员");
             e.printStackTrace();
             SignBackPdfInfo(taskApp);
+            //发送服务异常事件
+            ErrorLogPublisher.publishEvent(e, null);
         }
     }
 
@@ -362,7 +371,7 @@ public class EVDataServiceImpl implements EVDataService {
         taskApp.setSigState(1);
         Map<String, Object> map = new HashMap<>();
         try {
-            if (taskApp.getApprovalType() == 1 || taskApp.getApprovalType() == 8) {
+            if (taskApp.getApprovalType() == 1 || taskApp.getApprovalType() == 8 || taskApp.getApprovalType() == 9) {
                 map = this.jdbcTemplate.queryForMap("select * from u_information_query where  is_deleted=0 and id = " + taskApp.getFormDataId());
                 String pdfTrialUrlPosition = map.get("pdf_trial_url_position") + ""; //关联工程部位信息后合并的pdf路径
                 String pdfTrialUrl = map.get("pdf_trial_url") + ""; //pdf路径,引用试验记录后合并的pdf
@@ -422,7 +431,8 @@ public class EVDataServiceImpl implements EVDataService {
                 map = this.jdbcTemplate.queryForMap("select * from s_interim_pay_certificate where  is_deleted=0 and contract_period_id = " + taskApp.getFormDataId());
                 String pdfUrl=map.get("raw_url") + "";
                 //中间计量用逗号拼接pagePdfUrl
-                if(StringUtils.isNotEmpty(map.get("page_pdf_url")+"")){
+               /* String pageUrl = map.get("page_pdf_url")+"";
+                if(StringUtils.isNotEmpty(pageUrl) && pageUrl.length()>=20 ){
                     String jsonStr=map.get("page_pdf_url")+"";
                     ObjectMapper mapper = new ObjectMapper();
                     JsonNode jsonNode = mapper.readTree(jsonStr);
@@ -436,7 +446,7 @@ public class EVDataServiceImpl implements EVDataService {
                         }
                     }
                     pdfUrl=result.toString();
-                }
+                }*/
                 taskApp.setSignPdfUrl(pdfUrl);
             } else if (taskApp.getApprovalType() == 6 || taskApp.getApprovalType() == 7) {
                 map = this.jdbcTemplate.queryForMap("select * from  s_material_start_statement where is_deleted=0 and meter_period_id = " + taskApp.getFormDataId());
@@ -483,13 +493,12 @@ public class EVDataServiceImpl implements EVDataService {
             taskApp.setSigState(2);
             taskApp.setSignSmg("获取pdf信息异常");
             SignBackPdfInfo(taskApp);
-            return;
+            ErrorLogPublisher.publishEvent(e, null);
         }
     }
 
     // 添加电签策略 -- 东方中讯
     public List<Map<String, Object>> getStrategyListByDFZX(TaskSignInfoVO task, String ids) {
-
         String[] strArray = Func.toStrArray(task.getUserId());
         String[] userNames = Func.toStrArray(task.getNickName());
         List<Map<String, Object>> maps = new ArrayList<>();
@@ -503,24 +512,26 @@ public class EVDataServiceImpl implements EVDataService {
                     System.out.println("东方中讯--签字--" + sqlinfo);
                 }
                 List<Map<String, Object>> maps2 = jdbcTemplate.queryForList(sqlinfo);
-                Map<String, List<Map<String, Object>>> peopleByAge = maps2.stream()
-                        .collect(Collectors.groupingBy(hada -> (Func.toStr(hada.get("keyWord")))));
-                for (String keyId : peopleByAge.keySet()) {
-                    int exId = 0;
-                    List<Map<String, Object>> keyList = peopleByAge.get(keyId);
-                    if (keyList != null && keyList.size() == 1) {
-                        maps.addAll(keyList);
-                        exId = 1;
-                    } else if (keyList != null && keyList.size() >= 2) {
-                        for (Map<String, Object> datax : keyList) {
-                            if ((datax.get("project_id") + "").equals(task.getProjectId())) {
-                                maps.add(datax);
-                                exId = 1;
+                if(CollectionUtil.isNotEmpty(maps2)) {
+                    Map<String, List<Map<String, Object>>> peopleByAge = maps2.stream()
+                            .collect(Collectors.groupingBy(hada -> (Func.toStr(hada.get("keyWord")))));
+                    for (String keyId : peopleByAge.keySet()) {
+                        int exId = 0;
+                        List<Map<String, Object>> keyList = peopleByAge.get(keyId);
+                        if (keyList != null && keyList.size() == 1) {
+                            maps.addAll(keyList);
+                            exId = 1;
+                        } else if (keyList != null && keyList.size() >= 2) {
+                            for (Map<String, Object> datax : keyList) {
+                                if ((datax.get("project_id") + "").equals(task.getProjectId())) {
+                                    maps.add(datax);
+                                    exId = 1;
+                                }
                             }
                         }
-                    }
-                    if (exId == 0) {
-                        maps.add(keyList.get(0));
+                        if (exId == 0) {
+                            maps.add(keyList.get(0));
+                        }
                     }
                 }
             }
@@ -535,6 +546,7 @@ public class EVDataServiceImpl implements EVDataService {
         String[] userNames = Func.toStrArray(task.getNickName());
         List<SealStrategyVO> sealStrategyVOS = new ArrayList<>();
 
+
         if(strArray!=null && strArray.length>0){
             for (int i =0 ;i < strArray.length;i++) {
                 String userId =strArray[i];
@@ -574,7 +586,6 @@ public class EVDataServiceImpl implements EVDataService {
                     if (maps == null || maps.size() <= 0) {
                         break;
                     }
-
                     //准备签章策略
                     for (Map<String, Object> eVisaConfig : maps) {
                         //设置签章策略
@@ -595,6 +606,7 @@ public class EVDataServiceImpl implements EVDataService {
                             vo.setOffSetY(eVisaConfig.get("pyzby") + "");
                             vo.setHeight(eVisaConfig.get("high") + "");
                             vo.setWidth(eVisaConfig.get("wide") + "");
+                            vo.setProjectId(eVisaConfig.get("project_id") + "");
                         } else if (task.getSigType() == 2) {
                             vo.setSealCode(EVisaConstant.SIGN_SEAL_CODE + eVisaConfig.get("sfId"));
                             vo.setSealPassword(eVisaConfig.get("certificate_password") + "");
@@ -608,12 +620,38 @@ public class EVDataServiceImpl implements EVDataService {
                             vo.setOffSetY(eVisaConfig.get("pyzby") + "");
                             vo.setHeight(eVisaConfig.get("high") + "");
                             vo.setWidth(eVisaConfig.get("wide") + "");
+                            vo.setProjectId(eVisaConfig.get("project_id") + "");
                         }
                         sealStrategyVOS.add(vo);
                     }
                 }
             }
         }
+
+        // 去掉 重复的数据
+        if(sealStrategyVOS!=null && sealStrategyVOS.size() > 0){
+            Map<String, List<SealStrategyVO>> groupByPriceMap = sealStrategyVOS.stream()
+                    .collect(Collectors.groupingBy(SealStrategyVO::getKeyword));
+            List<SealStrategyVO> sealStrategyVOS2 = new ArrayList<>();
+            for(String keval:groupByPriceMap.keySet()){
+                List<SealStrategyVO> sealStr = groupByPriceMap.get(keval);
+                if(sealStr!=null && sealStr.size()>0){
+                    int index = 0;
+                    for(int i=0;i<sealStr.size();i++){
+                        if ((sealStr.get(i).getProjectId()).equals(task.getProjectId())) {
+                            index = i;
+                        }
+                    }
+                    sealStrategyVOS2.add(sealStr.get(index));
+                }
+            }
+            if(sealStrategyVOS2!=null && sealStrategyVOS2.size() > 0){
+                Map<String, List<SealStrategyVO>> groupByPriceMap3 = sealStrategyVOS2.stream()
+                        .collect(Collectors.groupingBy(SealStrategyVO::getKeyword));
+                return sealStrategyVOS2;
+            }
+        }
+
         return sealStrategyVOS;
     }
 
@@ -715,8 +753,8 @@ public class EVDataServiceImpl implements EVDataService {
         Object[] result = null;
         String fileUrl = pdfUrl;
         if (list.size() >= 10 || fileByte.length > 10 * 1000 * 1000) {
-            String inUrl = "/inp/" + DateUtil.today();
-            String outUrl = "/out/" + DateUtil.today();
+            String inUrl = "inp/" + DateUtil.today();
+            String outUrl = "out/" + DateUtil.today();
             SignFtpUtil.FTPCreateDir(inUrl);
             SignFtpUtil.FTPCreateDir(outUrl);
             String locPdfUrl = inUrl + "/" + filecode + ".pdf";
@@ -745,6 +783,11 @@ public class EVDataServiceImpl implements EVDataService {
             //执行电签
             if (result != null) {
                 try {
+                    //对文件流做判断
+                    byte[] bytes = (byte[]) result[0];
+                    if(bytes.length < 50){
+                        throw new ServiceException("读取电签文件失败,文件字节长度小于100");
+                    }
                     ByteArrayInputStream inputStream = new ByteArrayInputStream((byte[]) result[0]);
                     FileOutputStream fout = new FileOutputStream(dataFileUrl);
                     int bytesRead = 0;
@@ -763,7 +806,7 @@ public class EVDataServiceImpl implements EVDataService {
             }
         }
 
-        if (fileUrl.indexOf("aliyuncs.com") >= 0 || fileUrl.indexOf("183.247.216.148") >= 0 || fileUrl.indexOf("152.168.2.15") >= 0) {
+        if (fileUrl.indexOf("xinan1.zos.ctyun.cn") >= 0 || fileUrl.indexOf("aliyuncs.com") >= 0 || fileUrl.indexOf("183.247.216.148") >= 0 || fileUrl.indexOf("152.168.2.15") >= 0) {
             taskApp.setSigState(2);
             taskApp.setSignSmg("电签后-无法读取本地文件");
             SignBackPdfInfo(taskApp);

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

@@ -467,7 +467,7 @@ public class EVisaServiceImpl implements EVisaService {
 
                 if (taskFile.getRemarkType().equals("2")) {
                     // 查询任务下所有
-                    String sqlinfo = " SELECT * from ( SELECT a.id as keyWord,a.project_id,a.pyzbx ,a.pyzby,(SELECT acc_code from blade_user where id='" + task.getUserId() + "' and is_deleted=0  ) as sealId from m_textdict_info a where  a.type =2 and a.id in (" + ids + ")  and sig_role_id in (SELECT DISTINCT c.role_id from m_project_assignment_user c  where c.contract_id=" + contractId + " and user_id=" + task.getUserId() + " and c.is_deleted=0 ) ) x where x.sealId is not null and project_id='"+projectId+"' ";
+                    String sqlinfo = " SELECT * from ( SELECT a.id as keyWord,a.project_id,a.pyzbx ,a.pyzby,(SELECT acc_code from blade_user where id='" + task.getUserId() + "' and is_deleted=0  ) as sealId from m_textdict_info a where  a.type =2 and a.id in (" + ids + ")  and sig_role_id in (SELECT DISTINCT c.role_id from m_project_assignment_user c  where c.contract_id=" + contractId + " and user_id=" + task.getUserId() + " and c.is_deleted=0 ) ) x where x.sealId is not null and project_id='" + projectId + "' ";
                     System.out.println("东方中讯-个人-user-id" + task.getUserId() + "--SQL=" + sqlinfo);
                     List<Map<String, Object>> maps2 = jdbcTemplate.queryForList(sqlinfo);
                     List<Map<String, Object>> maps = new ArrayList<>();
@@ -786,7 +786,6 @@ public class EVisaServiceImpl implements EVisaService {
 
     /**
      * 东方 中讯
-     *
      * @throws Exception
      */
     public String signPdfByDFZX(HashMap<String, Object> request) {
@@ -822,7 +821,7 @@ public class EVisaServiceImpl implements EVisaService {
             converterList.add(1, converter);
 
             HashMap<String, Object> retData = restTemplate.postForObject(url, request, HashMap.class);
-            System.out.println("东方中讯uRL"+url);
+            System.out.println("东方中讯uRL" + url);
             String code = retData.get("code").toString();
             String msg = retData.get("msg").toString();
 
@@ -854,7 +853,6 @@ public class EVisaServiceImpl implements EVisaService {
             if ("20".equals(sys_isonline) || SystemUtils.isWindows() || SystemUtils.isMacOs()) {
                 SIGN_HOST = "113.250.191.113";
             }
-            SIGN_HOST = "113.250.191.113";
             System.out.println("电签Ip===:" + SIGN_HOST);
             PaperlessClient paperlessClient = new PaperlessClient(SIGN_HOST, SIGN_PORT, 24000000, 81000000);
             System.out.println("paperlessClient创建成功");
@@ -893,7 +891,6 @@ public class EVisaServiceImpl implements EVisaService {
 
             requestBody.setPdfBeans(pdfBeans);
             //***********************构造机构章策略 ********************************
-            System.out.println("【电签模块】10" + pdfVO.getStrategyVoList().size());
             List<SealStrategy> sealStrategies = this.generateSealStrategies(pdfVO.getStrategyVoList());
             if (null == sealStrategies || sealStrategies.size() <= 0) {
                 logger.info("【电签模块】{}", "签章策略为空");
@@ -901,7 +898,6 @@ public class EVisaServiceImpl implements EVisaService {
             }
             requestBody.setSealStrategies(sealStrategies);
 
-            System.out.println("【电签模块】11" + sealStrategies.size());
             //签章后文件保存地址,不为空时,直接将签章文件保存在此地址,不再返回签章后文档数据;ftp:auto
             requestBody.setOutputFilepath("");
 
@@ -909,7 +905,6 @@ public class EVisaServiceImpl implements EVisaService {
             requestBody.setTimestampChannel(BaseConstants.TIME_STAMP_CHANNEL_CFCA);
             //获取场景证书的方式默认值为0;0:实时从CFCA CA服务申请下载场景证书;1:使用从CFCA CA服务预先申请下载并存储在本地的场景证书;
             requestBody.setSceneCertChannel(BaseConstants.SCEND_CERT_CHANNEL_REAL);
-            System.out.println("【电签模块】12" + sealStrategies.size());
             compoundSealPdfListDetachedRequest.setBody(requestBody);
             //****************************** 请求服务端进行签章 *********************************************
             System.out.println("-----------------------" + new Date().toString() + "开始" + transactionNo + "----------------------------");
@@ -1220,7 +1215,7 @@ public class EVisaServiceImpl implements EVisaService {
 
                 if (vo.getSealType().equals("2")) {
                     //设置PDF坐标原点,签章图片定位点,默认为PDF左下角,签章图片定位为左下角
-                   if (StringUtils.isNotEmpty(vo.getIsCenterCoordinate())) {
+                    if (StringUtils.isNotEmpty(vo.getIsCenterCoordinate())) {
                         sealStrategy.setIsCenterCoordinate(vo.getIsCenterCoordinate());
                     }
 
@@ -1708,7 +1703,7 @@ public class EVisaServiceImpl implements EVisaService {
             List<PdfBean> pdfBeans = new ArrayList<>();
             PdfBean pdfBean = new PdfBean();
             pdfBean.setBizSerialNo(GUIDUtil.generateId());
-            pdfBean.setInputSource("/data/sdc/signInfo" + loPdfurl);
+            pdfBean.setInputSource("/data/sdc/signInfo/" + loPdfurl);
             pdfBean.setInputType(BaseConstants.INPUT_TYPE_FILEPATH);
             pdfBeans.add(pdfBean);
             requestBody.setPdfBeans(pdfBeans);
@@ -1721,7 +1716,7 @@ public class EVisaServiceImpl implements EVisaService {
             requestBody.setSealStrategies(sealStrategies);
 
             //签章后文件保存地址,不为空时,直接将签章文件保存在此地址,不再返回签章后文档数据;ftp:auto
-            requestBody.setOutputFilepath("/data/sdc/signInfo" + outPdfUrl);
+            requestBody.setOutputFilepath("/data/sdc/signInfo/" + outPdfUrl);
 
             //时间戳方式,默认为0;0:实时访问CFCA 时间戳服务;1:使用从CFCA购置并在本地部署的时间戳服务器产品;
             requestBody.setTimestampChannel(BaseConstants.TIME_STAMP_CHANNEL_CFCA);

+ 15 - 4
blade-service/blade-e-visa/src/main/java/org/springblade/evisa/service/impl/ScrDataServiceImpl.java

@@ -33,6 +33,10 @@ public class ScrDataServiceImpl implements ScrDataService {
         this.sctTaskBatch2(taskApp);
     }
 
+
+
+
+
     /**
      * 电签检查
      */
@@ -55,11 +59,12 @@ public class ScrDataServiceImpl implements ScrDataService {
         String ids = String.join(",", positions);
         List<Map<String, Object>> strategyListByDFZX = getStrategyListByDFZX(taskApp, ids);
         if(strategyListByDFZX==null || strategyListByDFZX.size()==0){
+
             System.out.println("为获取到签字的关键字");
             return;
         }
 
-        positions = strategyListByDFZX.stream().map(map -> map.get("keyWord").toString()).collect(Collectors.toList());
+ /*       positions = strategyListByDFZX.stream().map(map -> map.get("keyWord").toString()).collect(Collectors.toList());
         String keyWord = String.join(",", positions);
         List<PDFIndexInfo> pdfIndexInfo = PdfAddimgUtil.findKeywordPostions(pdfData, keyWord);
 
@@ -139,7 +144,7 @@ public class ScrDataServiceImpl implements ScrDataService {
         // 使用retainAll方法来移除两个集合中相同的元素,留下不同的元素
         differentElements.removeAll(sucess);
 
-        System.out.println(taskApp.getId() +"-"+"总共:" + positions.size() + "-剩下-" + differentElements.size());
+        System.out.println(taskApp.getId() +"-"+"总共:" + positions.size() + "-剩下-" + differentElements.size());*/
     }
 
 
@@ -152,7 +157,7 @@ public class ScrDataServiceImpl implements ScrDataService {
         if (mapList != null && mapList.size() > 0) {
             for (Map<String, Object> task : mapList) {
                 String taskUserId = Func.toStr(task.get("task_user"));
-                String sqlinfo = " SELECT * from ( SELECT a.id as keyWord,a.project_id,a.pyzbx ,a.pyzby,(SELECT acc_code from blade_user where id='" + taskUserId + "' and is_deleted=0  ) as sealId from m_textdict_info a where  a.type =2 and a.id in (" + ids + ")  and sig_role_id in (SELECT DISTINCT c.role_id from m_project_assignment_user c  where c.contract_id=" + taskApp.getContractId() + " and user_id=" + taskUserId + " and c.is_deleted=0 ) ) x where x.sealId is not null and x.project_id='" + taskApp.getProjectId() + "'";
+                String sqlinfo = " SELECT * from ( SELECT a.id as keyWord,a.project_id,a.pyzbx ,a.pyzby,(SELECT acc_code from blade_user where id='" + taskUserId + "' and is_deleted=0  ) as sealId from m_textdict_info a where  a.type =2 and a.id in (" + ids + ")  and sig_role_id in (SELECT DISTINCT c.role_id from m_project_assignment_user c  where c.contract_id=" + taskApp.getContractId() + " and user_id=" + taskUserId + " and c.is_deleted=0 ) ) x where x.sealId is not null ";
                 System.out.println("扫描-签字-sql=" + sqlinfo);
                 List<Map<String, Object>> maps3 = jdbcTemplate.queryForList(sqlinfo);
                 maps2.addAll(maps3);
@@ -160,7 +165,7 @@ public class ScrDataServiceImpl implements ScrDataService {
         }
         // 添加章
         if (taskApp.getStatus().equals("2")) {
-            String sqlinfo = "SELECT a.id as keyWord,a.pyzbx,a.pyzby,b.certificate_number as sealId from m_textdict_info a ,m_sign_pfx_file b where a.sig_role_id = b.pfx_type and b.project_contract_role like '%" + taskApp.getContractId() + "%' and a.is_deleted=0 and b.is_deleted=0 and a.type=6 and a.id in(" + ids + ") and a.project_id=" + taskApp.getProjectId() + "";
+            String sqlinfo = "SELECT a.id as keyWord,a.pyzbx,a.pyzby,b.certificate_number as sealId from m_textdict_info a ,m_sign_pfx_file b where a.sig_role_id = b.pfx_type and b.project_contract_role like '%" + taskApp.getContractId() + "%' and a.is_deleted=0 and b.is_deleted=0 and a.type=6 and a.id in(" + ids + ")";
             System.out.println("扫描-签章-sql=" + sqlinfo);
             List<Map<String, Object>> maps3 = jdbcTemplate.queryForList(sqlinfo);
             if (mapList != null && mapList.size() > 0) {
@@ -187,6 +192,12 @@ public class ScrDataServiceImpl implements ScrDataService {
                 maps.add(keyList.get(0));
             }
         }
+
+        if(maps!=null & maps.size()==0 && mapList.size()>=4 ){
+            System.out.println("123");
+        }
+
+
         return maps;
     }
 

+ 1 - 1
blade-service/blade-e-visa/src/main/java/org/springblade/evisa/utils/FileUtils.java

@@ -117,7 +117,7 @@ public class FileUtils {
         } catch (Exception e) {
             e.printStackTrace();
         }
-        return "";
+        return "0";
     }
 
 }

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

@@ -71,19 +71,21 @@ public class PDFUtils {
         }
     }
 
-    public static void main1(String[] args) {
-        String pdfUrl = "/Users/hongchuangyanfa/Downloads/bacb5814950ae9268f67904912c571d0.pdf";
+    public static void mai123n(String[] args) {
+        String pdfUrl = "/Users/hongchuangyanfa/Desktop/22222/1278页.pdf";
         getPdfSignIds(pdfUrl);
     }
 
-    public static List<String>  getPdfSignIds(String pdfUrl) {
+    public static List<String>  getPdfSignIds(String pdfUr) {
         List<String> eVisaConfigList = new ArrayList<>();
         try  {
-            InputStream inputStream = new FileInputStream(new File(pdfUrl));//CommonUtil.getOSSInputStream(pdfUrl);
+            InputStream inputStream = new FileInputStream(new File(pdfUr));
             PDDocument document = PDDocument.load(inputStream);
             PDFTextStripper stripper = new PDFTextStripper();
             String text = stripper.getText(document);
             String[] lines = text.split("[ \\n]+");
+            String regex = "^\\d{4}年\\d{2}月\\d{2}日$";
+
             for(int k=0;k<lines.length;k++){
                 String textStr = lines[k];
                 if(textStr.indexOf("*")>=0){
@@ -98,11 +100,11 @@ public class PDFUtils {
                         }
                     }
                     if (txt.length() >= 15 && Func.isNumeric(txt)) {
-                        System.out.println(txt);
                         eVisaConfigList.add(txt);
                     }
                 }
-                //
+
+                // 特殊处理
                 if(textStr.indexOf("1")>=0){
                     String txt = textStr.substring(textStr.indexOf("1"));
                     if (txt.length() >= 15 && Func.isNumeric(txt)) {
@@ -112,12 +114,14 @@ public class PDFUtils {
                 }
             }
 
+
             List<String> unique = eVisaConfigList.stream().distinct().collect(Collectors.toList());
             document.close();
             return unique;
         }catch (Exception e){
             e.printStackTrace();
-            return null;
+            System.out.println("pdf大小为0");
+            return eVisaConfigList;
         }
     }
 

+ 2 - 2
blade-service/blade-e-visa/src/main/java/org/springblade/evisa/utils/SignFtpUtil.java

@@ -16,8 +16,8 @@ public class SignFtpUtil {
     private static final int PORT = 6233 ;
     private static final String USER = "signAdmin";
     private static final String PASS = "123456";
-    private static final int CONNECT_TIMEOUT = 9000000; // 30秒
-    private static final int DATA_TIMEOUT = 900000; // 30秒
+    private static final int CONNECT_TIMEOUT = 900000; // 30秒
+    private static final int DATA_TIMEOUT = 90000; // 30秒
 
     /**
      *  获取ftp 客户端

+ 8 - 3
blade-service/blade-manager/pom.xml

@@ -202,7 +202,12 @@
             <groupId>org.springframework</groupId>
             <artifactId>spring-test</artifactId>
         </dependency>
-
+        <dependency>
+            <groupId>com.itextpdf</groupId>
+            <artifactId>io</artifactId>
+            <version>7.2.4</version>
+            <scope>compile</scope>
+        </dependency>
     </dependencies>
     <build>
         <plugins>
@@ -229,11 +234,11 @@
                     <target>${java.version}</target>
                     <encoding>${project.build.sourceEncoding}</encoding>
                     <compilerArguments>
-                        <bootclasspath>${java.home}/lib/rt.jar;${java.home}/lib/jce.jar;${java.home}/lib/jsse.jar
+                        <bootclasspath>${java.home}/lib/rt.jar:${java.home}/lib/jce.jar:${java.home}/lib/jsse.jar
                         </bootclasspath>
                     </compilerArguments>
                 </configuration>
             </plugin>
         </plugins>
     </build>
-</project>
+</project>

+ 102 - 32
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ExcelTabController.java

@@ -1,5 +1,7 @@
 package org.springblade.manager.controller;
 
+import cn.hutool.core.io.resource.Resource;
+import cn.hutool.http.HttpUtil;
 import cn.hutool.log.StaticLog;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
@@ -69,6 +71,7 @@ import org.springframework.http.HttpHeaders;
 import org.springframework.http.MediaType;
 import org.springframework.jdbc.core.BeanPropertyRowMapper;
 import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.mock.web.MockMultipartFile;
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.bind.annotation.*;
@@ -85,6 +88,7 @@ import java.net.URLConnection;
 import java.net.URLEncoder;
 import java.nio.file.Files;
 import java.nio.file.Path;
+import java.nio.file.Paths;
 import java.nio.file.StandardCopyOption;
 import java.text.SimpleDateFormat;
 import java.util.List;
@@ -154,6 +158,8 @@ public class ExcelTabController extends BladeController {
 
     private final IContractInfoService contractInfoService;
 
+    private final  SignFtpUtil signFtpUtil;
+
 
     @Autowired
     StringRedisTemplate RedisTemplate;
@@ -335,6 +341,10 @@ public class ExcelTabController extends BladeController {
         return R.success("上传成功");
     }
 
+    public void checkHtml(){
+
+    }
+
 
     public static InputStream getOSSInputStream(String urlStr) throws Exception {
         //获取OSS文件流
@@ -1609,28 +1619,31 @@ public class ExcelTabController extends BladeController {
     public R copeBussTab(Long pkeyId) {
         WbsTreeContract wbsInfo = wbsTreeContractService.getBaseMapper().selectOne(Wrappers.<WbsTreeContract>query().lambda()
                 .eq(WbsTreeContract::getPKeyId, pkeyId));
-
+        String[] split = wbsInfo.getNodeName().split("__");
+        //查出当前节点里面本表的所有复制表
         List<WbsTreeContract> wbsTreeContractList = wbsTreeContractService.getBaseMapper().selectList(Wrappers.<WbsTreeContract>query().lambda()
-                .likeRight(WbsTreeContract::getNodeName, wbsInfo.getNodeName())
+                .likeRight(WbsTreeContract::getNodeName,split[0])
                 .eq(WbsTreeContract::getContractId, wbsInfo.getContractId())
                 .eq(WbsTreeContract::getParentId, wbsInfo.getParentId())
                 .eq(WbsTreeContract::getTableOwner, wbsInfo.getTableOwner()));
-        List<WbsTreeContract> wbsTreeContractList2 = wbsTreeContractList.stream().sorted(Comparator.comparing(WbsTreeContract::getCreateTime).reversed()).collect(Collectors.toList());
-        Set<String> strings = wbsTreeContractList2.stream().map(o -> o.getNodeName()).collect(Collectors.toSet());
-        List<WbsTreeContract> wbsTreeContractList3 = wbsTreeContractList.stream().sorted(Comparator.comparing(WbsTreeContract::getCreateTime)).collect(Collectors.toList());
-        Boolean flag = false;
-        if (strings.size() != wbsTreeContractList3.size()) {
-            flag = true;
-            for (int i = 0; i < wbsTreeContractList3.size(); i++) {
-                if (wbsTreeContractList3.get(i).getIsCopeTab() != null && wbsTreeContractList3.get(i).getIsCopeTab().equals(Integer.valueOf(2))) {
-                    String nodeName = wbsTreeContractList3.get(0).getNodeName();
+        //拿到所有的名字
+        Set<String> strings = wbsTreeContractList.stream().map(o -> o.getNodeName()).collect(Collectors.toSet());
+        //根据实际排序
+        List<WbsTreeContract> wbsTreeContractList2 = wbsTreeContractList.stream().sorted(Comparator.comparing(WbsTreeContract::getCreateTime)).collect(Collectors.toList());
+        //如果数量对不上说明有错的情况就进来,进行修改,现在wbsTreeContractList2就是正常的
+        if (strings.size() != wbsTreeContractList2.size()) {
+            for (int i = 0; i < wbsTreeContractList2.size(); i++) {
+                //是复制表
+                if (wbsTreeContractList2.get(i).getIsCopeTab() != null && wbsTreeContractList2.get(i).getIsCopeTab().equals(Integer.valueOf(2))) {
+                    String nodeName = wbsTreeContractList2.get(0).getNodeName().split("__")[0];
                     nodeName = nodeName + "__" + (i);
-                    wbsTreeContractList3.get(i).setNodeName(nodeName);
-                    String update = "UPDATE m_wbs_tree_contract Set node_name= " + "'" + wbsTreeContractList3.get(i).getNodeName() + "'" + " WHERE p_key_id=" + wbsTreeContractList3.get(i).getPKeyId();
+                    wbsTreeContractList2.get(i).setNodeName(nodeName);
+                    String update = "UPDATE m_wbs_tree_contract Set node_name= " + "'" + wbsTreeContractList2.get(i).getNodeName() + "'" + " WHERE p_key_id=" + wbsTreeContractList2.get(i).getPKeyId();
                     jdbcTemplate.update(update);
                 }
             }
         }
+
         //新增
         long tabGroupId = SnowFlakeUtil.getId();
         long newPkId = SnowFlakeUtil.getId();
@@ -1640,11 +1653,7 @@ public class ExcelTabController extends BladeController {
         wbsTreeContract.setCreateTime(new Date());
         wbsTreeContract.setTabGroupId(tabGroupId);
         String nodeName;
-        if (flag) {
-            nodeName = wbsTreeContractList3.get(wbsTreeContractList3.size() - 1).getNodeName();
-        } else {
-            nodeName = wbsTreeContractList2.get(0).getNodeName();
-        }
+        nodeName = wbsTreeContractList2.get(wbsTreeContractList2.size() - 1).getNodeName();
         if (nodeName.indexOf("__") >= 0) {
             String[] oldName = nodeName.split("__");
             nodeName = oldName[0] + "__" + (Integer.parseInt(oldName[1]) + 1);
@@ -1804,7 +1813,7 @@ public class ExcelTabController extends BladeController {
         }
 
         //获取节点下的所有表单,和附件,如果表单全是隐藏的,并且没有附件,则提示暂无数据
-        String sql = "select pdf_url,e_visa_pdf_url,pdf_trial_url,pdf_trial_url_position,status from u_information_query where classify='" + classify + "' and wbs_id='" + nodeId + "' and contract_id='" + contractId + "'";
+        String sql = "select pdf_url,e_visa_pdf_url,pdf_trial_url,pdf_trial_url_position,status from u_information_query where classify='" + classify + "' and wbs_id='" + nodeId + "' and contract_id='" + contractId + "'  and status<>3 ";
         List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql);
         if (maps.size() < 1) {
             //判断当前合同段的类型
@@ -1868,11 +1877,6 @@ public class ExcelTabController extends BladeController {
                         netUrl = bladeFile.getLink();
                     }
                     //数字化节点附件处理
-                    String sqll = "SELECT * FROM m_wbs_tree_contract WHERE p_key_id=" + nodeId;
-                    WbsTreeContract wbsTreeContract = jdbcTemplate.queryForObject(sqll, new BeanPropertyRowMapper<>(WbsTreeContract.class));
-                    //if(ObjectUtil.isNotEmpty(wbsTreeContract.getNodeClass())&&wbsTreeContract.getNodeClass().equals(2)){
-                   // InformationQuery iq = informationQueryClient.getInfoByWbsId(wbsTreeContract.getPKeyId());
-                  //  if (iq.getNodePdfUrl() == null || iq.getEVisaPdfPage() == null || iq.getEVisaPdfSize() == null || iq.getEVisaPdfPage() == 0  || !iq.getNodePdfUrl().equals(netUrl)) {
                         String pdfPage = FileUtils.getPdfNum(netUrl);
                         if (pdfPage != null && pdfPage.equals("")) {
                             pdfPage = "0";
@@ -1880,8 +1884,7 @@ public class ExcelTabController extends BladeController {
                         Long pdfSize = CommonUtil.getResourceLength(netUrl);
                         String sql1 = "update u_information_query set node_pdf_url='" + netUrl + "',e_visa_pdf_page=" + pdfPage + " ,e_visa_pdf_size=" + pdfSize + " where classify='" + classify + "' and wbs_id='" + nodeId + "' and contract_id='" + contractId + "'";
                         jdbcTemplate.execute(sql1);
-                   // }
-                    // }
+
                     return R.data(netUrl);
                 } else {
                     jdbcTemplate.execute(" update  u_information_query set node_pdf_url='" + pdfUrl + "' where classify='" + classify + "' and wbs_id='" + nodeId + "' and contract_id='" + contractId + "'");
@@ -2678,11 +2681,15 @@ public class ExcelTabController extends BladeController {
             dataIds = contractLogs.stream().map(ContractLog::getDataId).filter(Objects::nonNull).map(String::valueOf).collect(Collectors.joining(","));
         }
 
-        WbsTreePrivate node = this.wbsTreePrivateService.getOne(Wrappers.<WbsTreePrivate>lambdaQuery().eq(WbsTreePrivate::getPKeyId, nodePrimaryKeyId));
-        WbsTreePrivate tableNode2 = this.wbsTreePrivateService.getOne(Wrappers.<WbsTreePrivate>lambdaQuery()
+        WbsTreePrivate node;
+        WbsTreePrivate tableNode2;
+        try{
+            node = this.wbsTreePrivateService.getOne(Wrappers.<WbsTreePrivate>lambdaQuery().eq(WbsTreePrivate::getPKeyId, nodePrimaryKeyId));
+            tableNode2= this.wbsTreePrivateService.getOne(Wrappers.<WbsTreePrivate>lambdaQuery()
                 .eq(WbsTreePrivate::getParentId, node.getId()).eq(WbsTreePrivate::getProjectId, node.getProjectId()));
-
-
+        } catch (Exception e) {
+            throw new ServiceException("表单重复,请确认表单");
+        }
         if (StringUtils.isNotEmpty(dataIds)) {
             if (dataIds.startsWith(",")) {
                 dataIds = dataIds.substring(1);
@@ -3511,7 +3518,7 @@ public class ExcelTabController extends BladeController {
     @ApiImplicitParam(name = "fileId", value = "fileId")
     public void downGongChengExcelFile(HttpServletResponse response) throws Exception {
         String fileName = URLEncoder.encode("工程划分导入模版", Charsets.UTF_8.name());
-        String filePath="https://blade-oss-chongqing.oss-cn-shenzhen.aliyuncs.com//upload/20250327/a012e20cdf78a078d2db0e04d05bacd1.xlsx";
+        String filePath="https://xinan1.zos.ctyun.cn/blade-oss-chongqing/upload/20250508/bf69e3bd5a3fd3a216099238591948d9.xlsx";
         InputStream redio = CommonUtil.getOSSInputStream(filePath);
         byte[] buffer = IoUtil.readToByteArray(redio);
         OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
@@ -4417,7 +4424,7 @@ public class ExcelTabController extends BladeController {
         }
     }
 
-    @Scheduled(cron = "0 01 15 * * ?")
+    //@Scheduled(cron = "0 01 15 * * ?")
     //检查excel路径有错的
     public void cheackExcel() throws IOException {
         StringBuilder result=new StringBuilder("");
@@ -4444,6 +4451,69 @@ public class ExcelTabController extends BladeController {
             }
         }
     }
+
+    /**
+     * 检查清表html是否存在,不存在就下载重新上传
+     * 如果excel都不存在,就输出出来
+     * @throws Exception
+     */
+    //@Scheduled(cron = "00 13 10 * * ?")
+    public void checkHtmlIsExist() throws Exception {
+        StringBuilder result=new StringBuilder("");
+        StringBuilder result1=new StringBuilder("");
+        String sql = "Select * from m_excel_tab where parent_id=0 and is_deleted=0";
+        List<ExcelTab> query = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(ExcelTab.class));
+        String excelPath="E:\\excel\\";
+        try {
+            for (ExcelTab excelTab : query) {
+                String sql1 = "Select * from m_excel_tab where parent_id=" + excelTab.getId() + " and is_deleted=0";
+                List<ExcelTab> query1 = jdbcTemplate.query(sql1, new BeanPropertyRowMapper<>(ExcelTab.class));
+                for (ExcelTab tab : query1) {
+                    String sql2 = "Select * from m_excel_tab where parent_id=" + tab.getId() + " and is_deleted=0 and file_url is not null ";
+                    List<ExcelTab> query2 = jdbcTemplate.query(sql2, new BeanPropertyRowMapper<>(ExcelTab.class));
+                    for (ExcelTab excelTab1 : query2) {
+                        if(!signFtpUtil.isExist(excelTab1.getHtmlUrl())){
+                            if(excelTab1.getFileUrl() != null&&excelTab1.getFileUrl().endsWith(".xlsx") || excelTab1.getFileUrl().endsWith(".xls")){
+                                long resourceLength = CommonUtil.getResourceLength(excelTab1.getFileUrl());
+                                if(resourceLength>=500){
+                                    //先下载这个文件,再上传
+                                    String fileUrl = excelTab1.getFileUrl();
+                                    String localPath=excelPath+excelTab1.getId()+".xlsx";
+                                    InputStream inputStreamByUrl = FileUtils.getInputStreamByUrl(fileUrl);
+                                    FileUtils.saveFile(inputStreamByUrl,localPath);
+                                    File file = new File(localPath);
+                                    if(file.exists()){
+                                        Map<String, Object> paramMap = new HashMap<>();
+                                        paramMap.put("nodeId", excelTab1.getId());
+                                        paramMap.put("type",2);
+                                        HashMap<String,String> headers=new HashMap<>();
+                                        headers.put("Content-Type", "multipart/form-data; boundary=----WebKitFormBoundary4tcP4daRPIFDBRvm");
+                                        headers.put("Authorization","Basic c2FiZXI6c2FiZXJfc2VjcmV0");
+                                        headers.put("Blade-auth","bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0ZW5hbnRfaWQiOiIwMDAwMDAiLCJ1c2VyX25hbWUiOiJjciIsInJlYWxfbmFtZSI6IumZiOeEtiIsImF2YXRhciI6IiIsImF1dGhvcml0aWVzIjpbImFkbWluaXN0cmF0b3IiXSwiY2xpZW50X2lkIjoiY2xpZW50Iiwicm9sZV9uYW1lIjoiYWRtaW5pc3RyYXRvciIsImxpY2Vuc2UiOiJwb3dlcmVkIGJ5IGJsYWRleCIsInBvc3RfaWQiOiIiLCJ1c2VyX2lkIjoiMTkxMjcwMTM4Mzk4MjQyNDA2NSIsInJvbGVfaWQiOiIxMTIzNTk4ODE2NzM4Njc1MjAxIiwicGhvbmUiOiIxNTIxNTA1Mjc4NiIsInNjb3BlIjpbImFsbCJdLCJuaWNrX25hbWUiOiLpmYjnhLYiLCJvYXV0aF9pZCI6IiIsImRldGFpbCI6eyJ0eXBlIjoid2ViIn0sImV4cCI6MTc0NjY4ODQxOCwiZGVwdF9pZCI6IjE1MzY5ODMwNTYzNjIzODEzMTMiLCJqdGkiOiI3ZjEwY2U0NC1lOWE2LTRlYjMtYjBjYi1iYTJlY2U2MDk3ZjAiLCJhY2NvdW50IjoiY3IifQ.2v68wLgQvCUXanrNdXE6WPnXSrnjjW6mmepPgeWbAMo");
+                                        headers.put("Tenant-Id","000000");
+                                        String url="http://testmanger.hcxxy.com/api/blade-manager/exceltab/put-file-attach";
+                                        String body = HttpUtil.createPost(url).addHeaders(headers).form(paramMap).form("file", file).execute().body();
+                                        Map map = JSON.parseObject(body, Map.class);
+                                        if((int)map.get("code")!=200){
+                                            result1.append(excelTab.getName() + "--" + tab.getName() + "--" + excelTab1.getName()+"\n");
+                                        }
+                                    }
+                                }else {
+                                    result.append(excelTab.getName() + "--" + tab.getName() + "--" + excelTab1.getName()+"\n");
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+
+        System.out.println("完成");
+        System.out.println(result);
+        System.out.println(result1);
+    }
     @GetMapping("/checkParamElement")
     @ApiOperationSupport(order = 30)
     @ApiOperation(value = "检查参数元素", notes = "检查参数元素")

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

@@ -16,7 +16,12 @@
  */
 package org.springblade.manager.controller;
 
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.alibaba.nacos.shaded.io.opencensus.metrics.LongGauge;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.google.gson.Gson;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiParam;
@@ -24,10 +29,18 @@ import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
 import lombok.AllArgsConstructor;
 import javax.validation.Valid;
 
+import org.apache.commons.lang.StringUtils;
 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.entity.WbsTreeContract;
+import org.springblade.manager.service.IExcelTabService;
+import org.springblade.manager.service.IWbsTreeContractService;
+import org.springblade.manager.vo.AppWbsTreeContractVO;
+import org.springframework.jdbc.core.BeanPropertyRowMapper;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.core.SingleColumnRowMapper;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.bind.annotation.RequestParam;
 import com.baomidou.mybatisplus.core.metadata.IPage;
@@ -38,6 +51,8 @@ import org.springblade.core.boot.ctrl.BladeController;
 
 import java.math.BigDecimal;
 import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 /**
  *  控制器
@@ -52,6 +67,11 @@ import java.util.HashMap;
 public class NodeBaseInfoController extends BladeController {
 
 	private final INodeBaseInfoService nodeBaseInfoService;
+    private final JdbcTemplate jdbcTemplate;
+    private final IWbsTreeContractService wbsTreeContractService;
+    private final IExcelTabService excelTabService;
+    private final ExcelTabController controller;
+
 
 	/**
 	 * 详情
@@ -112,10 +132,89 @@ public class NodeBaseInfoController extends BladeController {
 	@PostMapping("/submit")
 	@ApiOperationSupport(order = 6)
 	@ApiOperation(value = "新增或修改", notes = "传入nodeBaseInfo")
-	public R submit(@Valid @RequestBody NodeBaseInfo nodeBaseInfo) {
-		return R.status(nodeBaseInfoService.saveOrUpdate(nodeBaseInfo));
+	public R submit(@Valid @RequestBody NodeBaseInfo nodeBaseInfo) throws Exception {
+        boolean update = nodeBaseInfoService.saveOrUpdate(nodeBaseInfo);
+        String s="Select project_id,contract_id from m_wbs_tree_contract where p_key_id="+nodeBaseInfo.getNodeId();
+        List<WbsTreeContract> wbsTreeContract = jdbcTemplate.query(s, new BeanPropertyRowMapper<>(WbsTreeContract.class));
+        if(update){
+            //施工部分
+            String sql1="select p_key_id from m_wbs_tree_contract where p_id="+nodeBaseInfo.getNodeId()+" and is_deleted=0 and table_owner in('1','2','3')";
+            List<Long> longs1 = jdbcTemplate.query(sql1, new SingleColumnRowMapper<>(Long.class));
+            Map<Long,Map<String, Object>>dataMap1=new HashMap<>();
+            if (longs1.size()>0){
+                for (Long pkeyId: longs1) {
+                    Map<String, Object> map1 = nodeBaseInfoService.getAllNodeBaseInfoByPkeyId(pkeyId, nodeBaseInfo.getNodeId());
+                    dataMap1.put(pkeyId,map1);
+                }
+                this.synPDFInfo(wbsTreeContract.get(0).getContractId(), nodeBaseInfo.getNodeId()+"", "1", wbsTreeContract.get(0).getProjectId(),dataMap1);
+            }
+            //监理部分
+            String sql2="select p_key_id from m_wbs_tree_contract where p_id="+nodeBaseInfo.getNodeId()+" and is_deleted=0 and table_owner in('4','5','6')";
+            List<Long> longs2 = jdbcTemplate.query(sql2, new SingleColumnRowMapper<>(Long.class));
+            Map<Long,Map<String, Object>>dataMap2=new HashMap<>();
+            if (longs2.size()>0){
+                for (Long pkeyId: longs2) {
+                    Map<String, Object> map2 = nodeBaseInfoService.getAllNodeBaseInfoByPkeyId(pkeyId, nodeBaseInfo.getNodeId());
+                    dataMap2.put(pkeyId,map2);
+                }
+                this.synPDFInfo(wbsTreeContract.get(0).getContractId(), nodeBaseInfo.getNodeId()+"", "2", wbsTreeContract.get(0).getProjectId(),dataMap2);
+            }
+        }
+        return R.status(update);
 	}
 
+    public R synPDFInfo(String contractId, String nodeId, String classify, String projectId,Map<Long,Map<String,Object>>dataMap) {
+
+        if (contractId == null && StringUtils.isEmpty(contractId)) {
+            return R.data("contractId不能为空");
+        }
+
+        if (nodeId == null && StringUtils.isEmpty(nodeId)) {
+            return R.data("nodeId不能为空");
+        }
+
+        if (classify == null && StringUtils.isEmpty(classify)) {
+            return R.data("classify不能为空");
+        }
+
+        if (projectId == null && StringUtils.isEmpty(projectId)) {
+            return R.data("projectId不能为空");
+        }
+        try {
+                JSONObject js = new JSONObject();
+                JSONObject js2 = new JSONObject();
+                List<AppWbsTreeContractVO> tableAll = wbsTreeContractService.searchNodeAllTable(nodeId, classify, contractId, projectId, null);
+                JSONArray array = new JSONArray();
+                if (tableAll != null && tableAll.size() >= 1) {
+                    /*只需加载第一张即可,生效会自动补全*/
+                    for (AppWbsTreeContractVO tab : tableAll) {
+                        Map<String, Object> jo = excelTabService.getBussDataInfo(tab.getPKeyId(), 0,true);
+                        if(dataMap.containsKey(tab.getPKeyId())){
+                            Map<String, Object> map = dataMap.get(tab.getPKeyId());
+                            map.forEach((key, value) -> jo.merge(key, value, (oldVal, newVal) -> newVal));
+                        }
+                        String s = new Gson().toJson(jo);
+                        //字符串转jsonobject
+                        JSONObject obj = JSON.parseObject(s);
+                        obj.put("classify", classify);
+                        obj.put("nodeId", nodeId);
+                        obj.put("contractId", contractId);
+                        obj.put("pkeyId", tab.getPKeyId());
+                        obj.put("projectId", projectId);
+                        obj.put("isCollapseLoad", true);
+                        obj.put("isRenderForm", true);
+                        array.add(obj);
+                    }
+                }
+                js2.put("orderList", array);
+                js.put("dataInfo", js2);
+                controller.saveBussData2(js);
+        } catch (Exception e) {
+            return null;
+        }
+        return R.data("成功");
+    }
+
 
 	/**
 	 * 删除

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

@@ -383,7 +383,57 @@ public class WbsTreeContractController extends BladeController {
                 Sheet poiSheet = poiWorkbook.getSheetAt(0); //获取第一个工作表
                 //存储需要修改的单元格和相关信息的列表
                 List<CellModificationInfo> cellsToModify = new ArrayList<>();
+                //解析html 获取合并单元格
+                InputStream inputStreamByUrl = FileUtils.getInputStreamByUrl(tab.getHtmlUrl());
+                String htmlString = IoUtil.readToString(inputStreamByUrl);
+                Document doc = Jsoup.parse(htmlString);
+                Element table = doc.select("table").first();
+                Elements rows = table.select("tr");
+                //最大列数
+                int maxColumns = calculateMaxColumns(rows);
+                List<CellRangeAddress> mergedRegions = new ArrayList<>();
+                // 保存需要保留的单元格内容和样式
+                Map<CellRangeAddress, String> data = new HashMap<>();
+                // 记录每个单元格的位置和合并信息
+                for (Element row1 : rows) {
+                    Elements cells = row1.select("td, th");
+                    for (Element cell : cells) {
+
+                        int rowspan = cell.hasAttr("rowspan") ? Integer.parseInt(cell.attr("rowspan")) : -1;
+                        int colspan = cell.hasAttr("colspan") ? Integer.parseInt(cell.attr("colspan")) : -1;
+                        int x1 = cell.hasAttr("x1") ? Integer.parseInt(cell.attr("x1")) - 1 : -1;//起始列
+                        int x2 = cell.hasAttr("x2") ? Integer.parseInt(cell.attr("x2")) - 1 : -1;//结束列
+                        int y1 = cell.hasAttr("y1") ? Integer.parseInt(cell.attr("y1")) - 1 : -1;//起始行
+                        int y2 = cell.hasAttr("y2") ? Integer.parseInt(cell.attr("y2")) - 1 : -1;//结束行
+                        // 记录合并区域
+                        if (x1 != -1 && x2 != -1 && y1 != -1 && y2 != -1) {
+                            if(rowspan != -1 || colspan != -1){
+                                CellRangeAddress region = new CellRangeAddress(y1, y2, x1, x2);
+                                mergedRegions.add(region);
+                                data.put(region, cell.text());
+                            }
+                        }
+                    }
+                }
+                // 按顺序合并单元格(从上到下、从左到右)
+                for (int i = poiSheet.getNumMergedRegions() - 1; i >= 0; i--) {
+                    poiSheet.removeMergedRegion(i);
+                }
+                for (CellRangeAddress region : mergedRegions) {
+                    poiSheet.addMergedRegion(region);
+                }
+
                 for (Row row : poiSheet) {
+                    //判断当前行是否是最大列 如果不是 就补充到最大列
+                    short lastCellNum = row.getLastCellNum();
+                    if(maxColumns > lastCellNum){
+                        for (int i = maxColumns - 1; i > lastCellNum; i--) {
+                            row.createCell(i);
+                            Cell cell = row.getCell(i);
+                            //设置新单元格的样式为第一个单元格的样式
+                            cell.setCellStyle(row.getCell(0).getCellStyle());
+                        }
+                    }
                     for (Cell cell : row) {
                         int cellType = cell.getCellType();
                         if (cellType == CellType.STRING.getCode() && ObjectUtil.isNotEmpty(cell.getStringCellValue())) {
@@ -393,6 +443,9 @@ public class WbsTreeContractController extends BladeController {
                         //获取单元格所属的合并单元格区域
                         CellRangeAddress mergedRegion = findMergedRegion(poiSheet, cell.getRowIndex(), cell.getColumnIndex());
                         if (mergedRegion != null) {
+                            //合并单元格的数据 为之前记录的数据
+                            cell.setCellValue(data.get(mergedRegion));
+
                             //存储需要修改的合并单元格信息
                             cellsToModify.add(new CellModificationInfo(cell, mergedRegion));
                         }
@@ -402,10 +455,10 @@ public class WbsTreeContractController extends BladeController {
                 //遍历结束后,实际修改单元格样式和内容
                 for (CellModificationInfo info : cellsToModify) {
                     Cell cell = info.getCell();
-                    if (info.hasStringContent()) {
+                    //只更新非合并单元格的数据
+                    if (info.getMergedRegion() == null && info.hasStringContent()) {
                         cell.setCellValue(info.getStringContent());
                     }
-
                     //复制单元格样式
                     CellStyle cellStyle = poiWorkbook.createCellStyle();
                     CellStyle sourceCellStyle = cell.getCellStyle(); //获取原单元格的样式
@@ -452,6 +505,20 @@ public class WbsTreeContractController extends BladeController {
             }
         }
     }
+    // 计算最大列数以对齐所有行
+    private static int calculateMaxColumns(Elements rows) {
+        return rows.stream()
+                .mapToInt(row -> row.select("td, th").stream()
+                        .mapToInt(c -> Math.max(getColspan(c), 1))
+                        .sum())
+                .max().orElse(0);
+    }
+
+    private static int getColspan(Element cell) {
+        String attr = cell.attr("colspan");
+        return attr.isEmpty() ? 1 : Integer.parseInt(attr);
+    }
+
 
     //在CellModificationInfo类中,根据需要存储单元格内容和合并单元格信息
     static class CellModificationInfo {

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

@@ -35,6 +35,7 @@ import org.springblade.manager.service.IContractInfoService;
 import org.springblade.manager.service.IExcelTabService;
 import org.springblade.manager.service.IProjectInfoService;
 import org.springblade.manager.service.IWbsTreePrivateService;
+import org.springblade.manager.utils.ExcelInfoUtils;
 import org.springblade.manager.utils.FileUtils;
 import org.springblade.manager.utils.RandomNumberHolder;
 import org.springblade.manager.vo.TrialSelfDataRecordVO1;
@@ -43,6 +44,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.jdbc.core.BeanPropertyRowMapper;
 import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
 
 import javax.imageio.ImageIO;
 import java.awt.*;
@@ -71,6 +73,7 @@ public class ExcelTabClientImpl implements ExcelTabClient {
     private final IProjectInfoService projectInfoService;
     private final IContractInfoService contractInfoService;
     private final EntrustInfoServiceClient entrustInfoServiceClient;
+
     @Override
     public ExcelTab getById(String id) {
         return this.excelTabService.getById(id);
@@ -477,6 +480,22 @@ public class ExcelTabClientImpl implements ExcelTabClient {
         return excelTabController.getPdfS(nodeId, classify, contractId);
     }
 
+    @Override
+    public void saveOrUpdate(ExcelTab detail) {
+        excelTabService.saveOrUpdate(detail);
+    }
+
+    @Override
+    public void expailHtmlInfo(String thmlUrl, Long id, String s) throws Exception {
+        excelTabController.expailHtmlInfo(thmlUrl, id, s);
+    }
+
+    @Override
+    public void excelInfo(InputStream inputStream, String exceUrl, String thmlUrl, String number) {
+        ExcelInfoUtils.excelInfo(inputStream, exceUrl, thmlUrl, number);
+    }
+
+
     private String getHtmlString(String pkeyId) throws Exception {
         WbsTreePrivate wbsTreePrivate = wbsTreePrivateMapper.selectOne(Wrappers.<WbsTreePrivate>query().lambda()
                 .select(WbsTreePrivate::getHtmlUrl)

+ 46 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/TableInfoMapper.java

@@ -16,12 +16,15 @@
  */
 package org.springblade.manager.mapper;
 
+import org.apache.ibatis.annotations.Param;
 import org.springblade.manager.entity.TableInfo;
+import org.springblade.manager.entity.WbsFormElement;
 import org.springblade.manager.vo.TableInfoVO;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 
 import java.util.List;
+import java.util.Map;
 
 /**
  * 实体主表信息 Mapper 接口
@@ -44,4 +47,47 @@ public interface TableInfoMapper extends BaseMapper<TableInfo> {
 
     TableInfo selectByTabEnName(String tabName);
 
+    /**
+     * 获取未更新过表中阿里云地址的表名
+     * @return
+     */
+    List<TableInfo> selectListByAliyunUrlState();
+
+    /**
+     * 查询指定表指定列是否包含指定数据
+     * @param tabEnName 表名
+     * @param fields 字段集合
+     * @return
+     */
+    List<String> countTableFields(@Param("tableName") String tabEnName,
+                                  @Param("fields") List<String> fields,
+                                  @Param("url") String url);
+
+    /**
+     * 替换阿里云地址
+     * @param tableName 表名
+     * @param errorUrl 阿里云地址
+     * @param correctUrl 正确地址
+     * @param fields 替换的字段集合
+     * @return
+     */
+    Integer updateALiYunUrl(@Param("tableName")String tableName,
+                            @Param("errorUrl") String errorUrl,
+                            @Param("correctUrl")String correctUrl,
+                            @Param("fields")List<String> fields);
+
+    /**
+     * 添加更新成功的表记录
+     * @param id
+     */
+    void insertAliyun(@Param("id") Long id,
+                      @Param("fields") String fields,
+                      @Param("updateCount") Integer updateCount);
+
+    /**
+     * 表是否存在
+     * @param tabEnName
+     * @return
+     */
+    int tableIsExist(@Param("tabEnName") String tabEnName);
 }

+ 30 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/TableInfoMapper.xml

@@ -18,6 +18,17 @@
         <result column="table_owner" property="tableOwner"/>
         <result column="fill_rate" property="fillRate"/>
     </resultMap>
+    <insert id="insertAliyun">
+        insert into m_table_info_aliyun(id,fields,update_count) values (#{id},#{fields},#{updateCount})
+    </insert>
+    <update id="updateALiYunUrl">
+        update ${tableName}
+        <set>
+            <foreach collection="fields" item="field" separator=",">
+                ${field} = REPLACE(${field},#{errorUrl},#{correctUrl})
+            </foreach>
+        </set>
+    </update>
 
 
     <select id="selectTableInfoPage" resultMap="tableInfoResultMap">
@@ -39,5 +50,24 @@
     <select id="selectByTabEnName" resultMap="tableInfoResultMap">
         select * from m_table_info where is_deleted = 0 and tab_ch_name=#{tabName}
     </select>
+    <select id="selectListByAliyunUrlState" resultType="org.springblade.manager.entity.TableInfo">
+        select a.id,a.tab_en_name from m_table_info a left JOIN m_table_info_aliyun b on a.id = b.id
+        where b.id is null and a.is_deleted = 0 limit 50;
+    </select>
+    <select id="countTableFields" resultType="java.lang.String">
+        select a.`key` from (
+            <foreach collection="fields" item="field" separator="UNION ALL">
+                select #{field} as `key`,count(0) count from ${tableName} where ${field} like concat(#{url},'%')
+            </foreach>
+        ) a where a.count > 0
+    </select>
+    <select id="tableIsExist" resultType="java.lang.Integer">
+        SELECT
+            COUNT( 0 ) AS table_exists
+        FROM
+            INFORMATION_SCHEMA.TABLES
+        WHERE
+            `TABLE_NAME` = #{tabEnName};
+    </select>
 
 </mapper>

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

@@ -1072,6 +1072,10 @@ public class ContractInfoServiceImpl extends BaseServiceImpl<ContractInfoMapper,
             projectContractArea.setCity(position.get("city"));
             projectContractArea.setCounty(position.get("district"));
             projectContractArea.setCity_code(position.get("adcode"));
+//            projectContractArea.setProvince("重庆");
+//            projectContractArea.setCity("重庆市");
+//            projectContractArea.setCounty("永川区");
+//            projectContractArea.setCity_code("500118");
             projectContractArea.setProjectId(contractInfo.getPId());
             projectContractArea.setIsDeleted(0);
             projectContractArea.setContractId(String.valueOf(contractInfo.getId()));

+ 51 - 31
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ExcelTabServiceImpl.java

@@ -1243,11 +1243,27 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
 
                     WbsTreeContract wbsTreeContractByP = wbsTreeContractService.getBaseMapper().selectOne(Wrappers.<WbsTreeContract>query().lambda()
                             .eq(WbsTreeContract::getId, wbsTreeContract.getParentId()).eq(WbsTreeContract::getContractId, tableInfo.getContractId()));
-
                     if (wbsTreeContractByP != null) {
                         //处理文件提名
                         String fileName = this.wbsParamService.createFileTitle(wbsTreeContractByP);
-
+                        String sql="select template_type from m_contract_info where id="+wbsTreeContractByP.getContractId();
+                        Integer type = jdbcTemplate.query(sql, rs -> {
+                            if (rs.next()) {
+                                return rs.getObject(1, Integer.class);
+                            } else {
+                                return 0; // 默认值
+                            }
+                        });
+                        if(type==2){
+                            if(wbsTreeContractByP.getMajorDataType()!=null&&wbsTreeContractByP.getMajorDataType()==4){
+                                if(tableInfo.getClassify()!=null&&tableInfo.getClassify().equals("1")){
+                                    //查询是否是底层节点
+                                    fileName=fileName+"检验申请批复单及附件";
+                                }else {
+                                    fileName=fileName+"抽检记录";
+                                }
+                            }
+                        }
                         //huangjn 保存成功后调用生成资料查询列表数据
                         this.informationQueryClient.saveOrUpdateInformationQueryData(wbsTreeContractByP.getPKeyId() + "", "首件使用字段", "业务ID(主要将来给首件使用)", fileName, Integer.parseInt(tableInfo.getClassify()), 2, "是否是首件(临时,暂时没用到)", "源文件(首件字段)", "pdf文件(首件字段)", "首件上传总结报告名称", new ArrayList<>());
                     }
@@ -1280,15 +1296,30 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
 
                 //获取节点
                 WbsTreeContract wbsTreeContract = this.wbsTreeContractService.getOne(Wrappers.<WbsTreeContract>lambdaQuery().eq(WbsTreeContract::getPKeyId, tableInfoList.get(0).getPkeyId()));
-
                 WbsTreeContract wbsTreeContractByP = wbsTreeContractService.getBaseMapper().selectOne(Wrappers.<WbsTreeContract>query().lambda()
                         .eq(WbsTreeContract::getId, wbsTreeContract.getParentId()).eq(WbsTreeContract::getContractId, wbsTreeContract.getContractId()));
                 //处理文件提名
                 fileName1= this.wbsParamService.createFileTitle(wbsTreeContractByP);
-
+                String sql="select template_type from m_contract_info where id="+wbsTreeContractByP.getContractId();
+                Integer type = jdbcTemplate.query(sql, rs -> {
+                    if (rs.next()) {
+                        return rs.getObject(1, Integer.class);
+                    } else {
+                        return 0; // 默认值
+                    }
+                });
+                if(type==2){
+                    if(wbsTreeContractByP.getMajorDataType()!=null&&wbsTreeContractByP.getMajorDataType()==4){
+                        if(tableInfoList.get(0).getClassify()!=null&&tableInfoList.get(0).getClassify().equals("1")){
+                            //查询是否是底层节点
+                            fileName1=fileName1+"检验申请批复单及附件";
+                        }else {
+                            fileName1=fileName1+"抽检记录";
+                        }
+                    }
+                }
                 //huangjn 保存成功后调用生成资料查询列表数据
                 this.informationQueryClient.saveOrUpdateInformationQueryData(wbsTreeContractByP.getPKeyId() + "", "首件使用字段", "业务ID(主要将来给首件使用)", fileName1, Integer.parseInt(tableInfoList.get(0).getClassify()), 2, "false", "源文件(首件字段)", "pdf文件(首件字段)", "首件上传总结报告名称", new ArrayList<>());
-
                 JSONObject json = new JSONObject();
                 json.put("operationObjIds", Func.toStrList(pkids));
                 json.put("operationObjName", wbsTreeContractByP.getNodeName() + "节点数据操作");
@@ -1448,12 +1479,15 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                 Elements bhtitle5 = doc.select("el-input[placeholder~=^单元工程编码]");
                 Elements bhtitle6 = doc.select("el-input[placeholder~=^编 号]");
                 Elements bhtitle7 = doc.select("el-input[placeholder~=^分项工程编号:]");
+                Elements bhtitle8 = doc.select("el-input[placeholder~=^分项工程编号:]");
+
                 bhtitle.addAll(bhtitle2);
                 bhtitle.addAll(bhtitle3);
                 bhtitle.addAll(bhtitle4);
                 bhtitle.addAll(bhtitle5);
                 bhtitle.addAll(bhtitle6);
                 bhtitle.addAll(bhtitle7);
+                bhtitle.addAll(bhtitle8);
             }
 
 
@@ -1689,7 +1723,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
         Map<String, Object> nodeBaseInfo = nodeBaseInfoService.getAllNodeBaseInfoByPkeyId(pkeyId, nodeId);
         if(nodeBaseInfo!=null){
             for (Map.Entry<String, Object> entry : nodeBaseInfo.entrySet()) {
-                reData.putIfAbsent(entry.getKey(), entry.getValue());
+                reData.put(entry.getKey(), entry.getValue());
             }
         }
 //        if(reData.size()>0){
@@ -2156,8 +2190,8 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                                     } catch (ParseException e) {
                                         throw new ServiceException("日期绑定错误");
                                     }
-                                    String StartDate = formatStr.format(Start_dataStr);
-                                    String endDate = formatStr.format(end_dataStr);
+                                    String StartDate = formatStr.format(Start_dataStr).trim().replace(" ","");
+                                    String endDate = formatStr.format(end_dataStr).trim().replace(" ","");
                                     if (StartDate.equals(endDate)) {
                                         myData = StartDate;
                                     } else {
@@ -2193,14 +2227,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                             if (myData.indexOf("http") >= 0 && (myData.indexOf("aliyuncs") >= 0 ||myData.indexOf("183.247.216.148") >= 0||myData.indexOf("xinan1.zos.ctyun.cn") >= 0)) {
                                 InputStream imageIn = CommonUtil.getOSSInputStream(myData);
                                 if (imageIn != null) {
-                                    byte[] bytes = null;
-                                    if (sys_isonline.equals("20")) {
-                                        bytes = IOUtils.toByteArray(imageIn);
-                                    } else {
-                                        byte[] byteNew = IOUtils.toByteArray(imageIn);
-                                        bytes = CommonUtil.compressImage(byteNew);
-                                      //  bytes = IOUtils.toByteArray(imageIn);
-                                    }
+                                    byte[] bytes = CommonUtil.compressImage(myData);
                                     // 这里根据实际需求选择图片类型
                                     int pictureIdx = workbook.addPicture(bytes, 6);
                                     CreationHelper helper = workbook.getCreationHelper();
@@ -2288,20 +2315,6 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                     if (row != null) {
                         Cell cell = row.getCell(x1 - 1);
                         if (cell != null || ObjectUtils.isNotEmpty(cell)) {
-//                            short fontIndex = cell.getCellStyle().getFontIndex();
-//                            Font oldfontAt = workbook.getFontAt(fontIndex);
-//                            Font redFont = workbook.createFont();
-//                            redFont.setColor(IndexedColors.WHITE.getIndex()); //设置字体颜色
-//                            redFont.setFontHeightInPoints(Short.valueOf("1"));//设置字体大小
-//                            redFont.setFontName(oldfontAt.getFontName());//设置字体
-//                            String CellValue = cell.getStringCellValue().trim();
-//
-//                            CellStyle newStyle = workbook.createCellStyle(); //创建单元格样式
-//                            newStyle.cloneStyleFrom(cell.getCellStyle());
-//                            newStyle.setFont(redFont);
-//                            newStyle.setShrinkToFit(true);
-//                            cell.setCellStyle(newStyle);
-//                            cell.setCellValue(dqid);
                              // 获取单元格的现有值
                             String existingValue = cell.getStringCellValue();
                             // 获取单元格的现有富文本字符串
@@ -3083,7 +3096,14 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                 for (int j = 0; j < cellNum; j++) {
                     Cell cell = row.getCell(j);
                     if (cell != null) {
-                        String cellValue = cell.getStringCellValue();
+                        String cellValue="";
+                        if (cell.getCellType() == 0) {
+                            double numValue = cell.getNumericCellValue();
+                            cellValue = String.valueOf(numValue);
+                        } else {
+                            cellValue = cell.getStringCellValue();
+                        }
+
                         if (cellValue != null && !cellValue.isEmpty()) {
                             if (cellValue.contains(oldContext)) {
                                 cell.setCellValue(newContext);

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

@@ -2498,7 +2498,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                 c9.setCellValue(contractInfo.getConstructionUnitName());
                 //监理单位
                 Cell c10 = getCellByAddress(sheet, "C10");
-                c10.setCellValue(contractInfo.getContractorUnitName());
+                c10.setCellValue(contractInfo.getSupervisionUnitName());
             }
             dianqian(htmlUrl, sheet, workbook);
             if (!periodId.equals(1867838908899852290L)) {
@@ -2818,6 +2818,10 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
             Cell d6 = getCellByAddress(sheet, "D6");
             d6.setCellValue(allMoney.toString());
             //------------------------------------------------------------上期末累计支付金额------------------------------------------------------------
+            //茶树至庙办 第一期特殊处理 第一期需要有上期末累计支付金额
+            if(periodId==1864938655997579266L){
+                lastEndPay=BigDecimal.valueOf(100000L);
+            }
             Cell e6 = getCellByAddress(sheet, "E6");
             e6.setCellValue(lastEndPay.toString());
             //------------------------------------------------------------本期计量金额------------------------------------------------------------
@@ -2834,6 +2838,10 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
             //------------------------------------------------------------本期支付金额------------------------------------------------------------
             BigDecimal currentPay = AllcurrentMeterTotal.multiply(blReserveFundsRatioNew).setScale(0, BigDecimal.ROUND_HALF_UP);
             Cell i6 = getCellByAddress(sheet, "I6");
+            //茶树至庙办 第一期特殊处理 第一期需要有上期末累计支付金额
+            if(periodId==1864938655997579266L){
+                currentPay=currentPay.subtract(BigDecimal.valueOf(100000L));
+            }
             i6.setCellValue(currentPay.toString());
             //------------------------------------------------------------本期末累计支付金额------------------------------------------------------------
             //上期末累计支付+本期支付
@@ -3190,6 +3198,10 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
             Cell a7 = getCellByAddress(sheet, "A7");
             a7.setCellValue(allMoney.toString());
             //---------------------------------------------------------------上期末累计支付---------------------------------------------------------------------------------------------------------
+            //茶树至庙办 第一期特殊处理 第一期需要有上期末累计支付金额
+            if(periodId==1864938655997579266L){
+                lastEndPay=BigDecimal.valueOf(100000L);
+            }
             Cell c7 = getCellByAddress(sheet, "C7");
             c7.setCellValue(lastEndPay.toString());
             //---------------------------------------------------------------本期计量-----------------------------------------------------------------------------------------------------------
@@ -3207,6 +3219,10 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
             //本期计量 *blReserveFundsRatioNew
             BigDecimal currentPay = AllcurrentMeterTotal.multiply(blReserveFundsRatioNew).setScale(0, BigDecimal.ROUND_HALF_UP);
             Cell i7 = getCellByAddress(sheet, "I7");
+            //茶树至庙办 第一期特殊处理 第一期需要有上期末累计支付金额
+            if(periodId==1864938655997579266L){
+                currentPay=currentPay.subtract(BigDecimal.valueOf(100000L));
+            }
             i7.setCellValue(currentPay.toString());
             //------------------------------------------------------------本期末累计支付------------------------------------------------------------
             //上期末累计支付+本期支付

+ 5 - 4
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/NodeBaseInfoServiceImpl.java

@@ -74,15 +74,16 @@ public class NodeBaseInfoServiceImpl extends BaseServiceImpl<NodeBaseInfoMapper,
         //查出当前节点的所有父节点
         WbsTreeContract wbsTreeContract = iWbsTreeContractService.getBaseMapper().selectOne(new LambdaQueryWrapper<>(WbsTreeContract.class).eq(WbsTreeContract::getPKeyId,pKeyId));
         if(wbsTreeContract!=null&&wbsTreeContract.getAncestors()!=null){
-            String ancestors = wbsTreeContract.getAncestors();
+            String ancestors = wbsTreeContract.getAncestorsPId();
+            if(ancestors==null){
+                return null;
+            }
             String[] nodeIds = ancestors.split(",");
             QueryWrapper<WbsTreeContract> queryWrapper = new QueryWrapper<>();
             queryWrapper.eq("project_id", wbsTreeContract.getProjectId())
                 .eq("contract_id", wbsTreeContract.getContractId())
                 .ne("parent_id", 0)
-                .and(wrapper -> wrapper.in("p_key_id", Arrays.asList(nodeIds))
-                    .or()
-                    .in("id", Arrays.asList(nodeIds)))
+                .and(wrapper -> wrapper.in("p_key_id", Arrays.asList(nodeIds)))
                 .groupBy("p_key_id");
             List<WbsTreeContract> wbsTreeContracts = iWbsTreeContractService.getBaseMapper().selectList(queryWrapper);
             if(wbsTreeContracts.size()>0){

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

@@ -41,7 +41,7 @@ public class SignPfxFilePreServiceImpl implements ISignPfxFilePreService {
     @Autowired
     private SignPfxFilePreMapper signPfxFilePreMapper;
 
-    private final String excelTabFileUrl = "https://blade-oss-chongqing.oss-cn-shenzhen.aliyuncs.com//upload/20240731/cf9534fd3ac688df5f9d7a802ba754c0.xlsx";
+    private final String excelTabFileUrl = "https://xinan1.zos.ctyun.cn/blade-oss-chongqing/upload/20240731/cf9534fd3ac688df5f9d7a802ba754c0.xlsx";
     private final String wbsHtmlUrl = "privateUrl/1771066158930198528.html";
     @Autowired
     private BeanUtil beanUtil;

+ 80 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/TableInfoServiceImpl.java

@@ -16,13 +16,24 @@
  */
 package org.springblade.manager.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import org.springblade.core.tool.utils.CollectionUtil;
 import org.springblade.manager.entity.TableInfo;
+import org.springblade.manager.entity.WbsFormElement;
+import org.springblade.manager.mapper.WbsFormElementMapper;
 import org.springblade.manager.vo.TableInfoVO;
 import org.springblade.manager.mapper.TableInfoMapper;
 import org.springblade.manager.service.ITableInfoService;
 import org.springblade.core.mp.base.BaseServiceImpl;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Service;
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.PostConstruct;
+import java.util.*;
+import java.util.stream.Collectors;
 
 /**
  * 实体主表信息 服务实现类
@@ -38,4 +49,73 @@ public class TableInfoServiceImpl extends BaseServiceImpl<TableInfoMapper, Table
         return page.setRecords(baseMapper.selectTableInfoPage(page, tableInfo));
     }
 
+    @Autowired
+    private WbsFormElementMapper wbsFormElementMapper;
+
+    /**
+     * 十分钟执行一次
+     * 替换动态表中的阿里云地址
+     */
+    @Scheduled(cron = "0 */10 * * * ?")
+//    @Scheduled(fixedDelay = 60000)
+    public void aliyunUrlReplace() {
+        System.out.println("执行阿里云地址替换-----------------------------开始");
+
+        String aliyunUrlOne = "https://blade-oss-chongqing.oss-cn-shenzhen.aliyuncs.com//upload";
+        String aliyunUrlTwo = "https://blade-oss-chongqing.oss-cn-shenzhen.aliyuncs.com/upload";
+        String correctUrl = "https://xinan1.zos.ctyun.cn/blade-oss-chongqing/upload";
+
+
+        List<TableInfo> tableInfos = baseMapper.selectListByAliyunUrlState();
+        if (CollectionUtil.isNotEmpty(tableInfos)) {
+            for (TableInfo tableInfo : tableInfos) {
+                //表 符合需求的字段
+                Set<String> createField = new HashSet<>();
+                Integer updateCount = 0;
+                //判断表是否存在
+                int exist = baseMapper.tableIsExist(tableInfo.getTabEnName());
+                if (exist > 0) {
+                    //获取字段
+                    List<WbsFormElement> wbsFormElements = wbsFormElementMapper.selectList(new QueryWrapper<WbsFormElement>().lambda().eq(WbsFormElement::getFId, tableInfo.getId()));
+
+                    if (CollectionUtil.isNotEmpty(wbsFormElements)) {
+                        List<String> fields = wbsFormElements.stream().map(WbsFormElement::getEKey).collect(Collectors.toList());
+                        //存在字段
+                        List<String> countTableFields = null;
+                        try {
+                            countTableFields = baseMapper.countTableFields(tableInfo.getTabEnName(), fields, aliyunUrlOne);
+                        } catch (Exception e) {
+                            System.out.println("执行阿里云地址替换-异常:表字段存在异常");
+                        }
+
+                        if (CollectionUtil.isNotEmpty(countTableFields)) {
+                            createField.addAll(countTableFields);
+                            //替换
+                            Integer count = baseMapper.updateALiYunUrl(tableInfo.getTabEnName(), aliyunUrlOne, correctUrl, countTableFields);
+                            updateCount += count;
+                        }
+                        //排查第二种类型的阿里云地址
+                        List<String> fieldsTwo = null;
+                        try {
+                            fieldsTwo = baseMapper.countTableFields(tableInfo.getTabEnName(), fields, aliyunUrlTwo);
+                        } catch (Exception e) {
+                            System.out.println("执行阿里云地址替换-异常:表字段存在异常");
+                        }
+                        if (CollectionUtil.isNotEmpty(fieldsTwo)) {
+                            createField.addAll(countTableFields);
+                            //替换
+                            Integer count = baseMapper.updateALiYunUrl(tableInfo.getTabEnName(), aliyunUrlTwo, correctUrl, fieldsTwo);
+                            updateCount += count;
+                        }
+                    }
+                }
+                //更新成功 把当前表的数据
+                baseMapper.insertAliyun(tableInfo.getId(), createField != null ? String.join(",", createField) : null, updateCount)
+                ;
+            }
+
+
+        }
+        System.out.println("执行阿里云地址替换-----------------------------结束");
+    }
 }

+ 7 - 3
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsParamServiceImpl.java

@@ -220,32 +220,36 @@ public class WbsParamServiceImpl extends BaseServiceImpl<WbsParamMapper, WbsPara
             if(wbsTreePrivate==null){
                 return R.success("暂无数据");
             }
-            String ancestor=wbsTreePrivate.getAncestors()+","+wbsTreePrivate.getAncestorsPId();
+            //拿到引用项目级节点的祖级节点
+            String ancestor=wbsTreePrivate.getAncestorsPId()+","+wbsTreePrivate.getPKeyId();
             String[] ancestors = ancestor.split(",");
             List<Long> list2 = Arrays.stream(ancestors)
                 .map(Long::parseLong)
                 .collect(Collectors.toList());
             String join = String.join(",", list2.stream().map(String::valueOf).collect(Collectors.toList()));
-            String sql11 = "SELECT * FROM m_wbs_tree_private WHERE node_type=1  AND project_id="+projectId+"  AND parent_id!=0 AND (p_key_id IN (" + join + ") or id IN ("+join+"))";
+            String sql11 = "SELECT * FROM m_wbs_tree_private WHERE node_type=1  AND project_id="+projectId+"  AND parent_id!=0 AND p_key_id IN (" + join + ")";
             List<WbsTreePrivate> nodeList = jdbcTemplate.query(sql11, new BeanPropertyRowMapper<>(WbsTreePrivate.class));
             //List<WbsTreePrivate> nodeList = wbsTreePrivateService.getBaseMapper().selectList(new LambdaQueryWrapper<>(WbsTreePrivate.class).select(WbsTreePrivate::getId).eq(WbsTreePrivate::getNodeType, 1).ne(WbsTreePrivate::getParentId, 0).in(WbsTreePrivate::getPKeyId, list2));
+            //那点祖级节点的Id
             List<Long> list3 = nodeList.stream().map(o -> o.getId()).collect(Collectors.toList());
             if(list3.size()<0){
                 return R.success("暂无数据");
             }
+            //查出这个项目所有的文件题名配置
             List<WbsParam> wbsParamList = this.getBaseMapper().selectList(new LambdaQueryWrapper<>(WbsParam.class).eq(WbsParam::getProjectId, projectId).eq(WbsParam::getK, "FILE_TITLE"));
             List<WbsParam> result=new ArrayList<>();
             if(wbsParamList.size()>0){
                 //筛选出包含当前单位工程节点的
                 for (WbsParam param : wbsParamList) {
+                    //祖级节点里有文件题名配置就加进去
                     if(list3.contains(param.getNodeId())){
                         result.add(param);
                     }
+                    //如果是全局的也加进去
                     if(param.getNameType()==1){
                         result.add(param);
                     }
                 }
-
                 if(result.size()>0){
                     //如果有部分节点优先部分
                     List<WbsParam> collect1 = result.stream().filter(o -> o.getNameType() == 2).collect(Collectors.toList());

+ 153 - 93
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeContractServiceImpl.java

@@ -652,10 +652,17 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
             // 如果 sort 相同,比较 nodeName
             String name1 = o1.getNodeName();
             String name2 = o2.getNodeName();
-
+            boolean flag=false;
             boolean hasUnderscore1 = name1.contains("__");
             boolean hasUnderscore2 = name2.contains("__");
-
+            if(name1.contains("PL")&&name2.contains("PL")){
+                flag=true;
+            }
+            if(flag){
+                int number1 = getPLNumberAfterUnderscore(name1);
+                int number2 = getPLNumberAfterUnderscore(name2);
+                return Integer.compare(number1, number2);
+            }
             if (!hasUnderscore1 && !hasUnderscore2) {
                 // 两个都不包含 __,按字母顺序排序
                 return name1.compareTo(name2);
@@ -665,7 +672,8 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
             } else if (!hasUnderscore2) {
                 // 第二个不包含 __,排在前面
                 return 1;
-            } else {
+            }
+            else {
                 // 两个都包含 __,按 __ 后面的数字排序
                 int number1 = getNumberAfterUnderscore(name1);
                 int number2 = getNumberAfterUnderscore(name2);
@@ -680,6 +688,25 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
             }
             return Integer.MAX_VALUE;
         }
+
+        private int getPLNumberAfterUnderscore(String name) {
+            if (!name.isEmpty()) {
+                int lastIndex = name.lastIndexOf("_"); // 找到最后一个 '_' 的位置
+                //如果有_
+                if (lastIndex != -1 && lastIndex < name.length() - 1) {
+                    String result = name.substring(lastIndex + 1); // 截取 '_' 后面的内容
+                    if (result.matches("\\d")) { // 判断是否为数字字符
+                        return Integer.parseInt(result);
+                    } else {
+                        return Integer.MAX_VALUE;
+                    }
+                } else {
+                    return Integer.MAX_VALUE;
+                }
+            } else {
+                return Integer.MAX_VALUE;
+            }
+        }
     }
 
 
@@ -2359,77 +2386,108 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
         //本次修改的节点
         List<String> updateList=new ArrayList<>();
 
+        //新增
+        String sqlList="Select parent_id,node_name from m_wbs_tree_contract where contract_id="+wbsTreeContractRoot.getContractId()+" and wbs_id="+wbsTreeContractRoot.getWbsId()+" and is_deleted=0";
+        List<WbsTreeContract> WbsTreeContractListupdate = jdbcTemplate.query(sqlList, new BeanPropertyRowMapper<>(WbsTreeContract.class));
         //导入节点与现有节点进行比较。进行修改编号
+        List<String>updateUnitNames=new ArrayList<>();
         for (ImportTreeDto dto : list) {
             for (WbsTreeContractVO vo : wbsTreeContractVOS) {
                 //wbs节点和单位工程的名称类型能对应上,并且编号不一样,就修改编号
                 if(vo.getNodeName().equals(dto.getUnitName())&&vo.getNodeType()==1){
-                    if(vo.getPartitionCode()==null||!vo.getPartitionCode().equals(dto.getUnitCode())){
-                        baseMapper.update(null,Wrappers.<WbsTreeContract>lambdaUpdate().set(WbsTreeContract::getPartitionCode,dto.getUnitCode()).eq(WbsTreeContract::getPKeyId,vo.getPrimaryKeyId()));
-                        updateList.add(vo.getNodeName());
+                    Boolean exist = this.isExist(dto, WbsTreeContractListupdate, 1, wbsTreeContractRoot);
+                    if(exist){
+                        if(vo.getPartitionCode()==null||!vo.getPartitionCode().equals(dto.getUnitCode())){
+                            if(updateUnitNames.size()>=1&&updateUnitNames.contains(vo.getNodeName())){
+                                continue;
+                            }
+                            baseMapper.update(null,Wrappers.<WbsTreeContract>lambdaUpdate().set(WbsTreeContract::getPartitionCode,dto.getUnitCode()).eq(WbsTreeContract::getPKeyId,vo.getPKeyId()));
+                            updateList.add(vo.getNodeName());
+                            updateUnitNames.add(vo.getNodeName());
+                            dto.setIsUnit(true);
+                        }
+                        continue;
                     }
-                    dto.setIsUnit(true);
-                    continue;
                 }
                 //wbs节点和子单位工程的名称类型能对应上,并且编号不一样,并且祖级节点也都能对应上,就修改编号
                 if(vo.getNodeName().equals(dto.getSubUnitName())&&vo.getNodeType()==18){
-                    if(isTrueNode(Arrays.asList(dto.getUnitName(),dto.getSubUnitName()),vo)){
-                        if(vo.getPartitionCode()==null||!vo.getPartitionCode().equals(dto.getSubUnitCode())){
-                            baseMapper.update(null,Wrappers.<WbsTreeContract>lambdaUpdate().set(WbsTreeContract::getPartitionCode,dto.getSubUnitCode()).eq(WbsTreeContract::getPKeyId,vo.getPrimaryKeyId()));
-                            updateList.add(vo.getNodeName());
+                    Boolean exist = this.isExist(dto, WbsTreeContractListupdate, 2, wbsTreeContractRoot);
+                    if(exist){
+                        if(isTrueNode(Arrays.asList(dto.getUnitName(),dto.getSubUnitName()),vo)){
+                            if(vo.getPartitionCode()==null||!vo.getPartitionCode().equals(dto.getSubUnitCode())){
+                                baseMapper.update(null,Wrappers.<WbsTreeContract>lambdaUpdate().set(WbsTreeContract::getPartitionCode,dto.getSubUnitCode()).eq(WbsTreeContract::getPKeyId,vo.getPKeyId()));
+                                updateList.add(vo.getNodeName());
+                                dto.setIsSubUnit(true);
+                            }
+
                         }
-                        dto.setIsSubUnit(true);
+                        continue;
                     }
-                    continue;
                 }
                 //wbs节点和分部工程的名称类型能对应上,并且编号不一样,并且祖级节点也都能对应上,就修改编号
-                if(vo.getNodeName().equals(dto.getDivisionName())&&vo.getNodeType()==2&&!vo.getPartitionCode().equals(dto.getDivisionName())){
-                    if(isTrueNode(Arrays.asList(dto.getUnitName(),dto.getSubUnitName(),dto.getDivisionName()),vo)){
-                        baseMapper.update(null,Wrappers.<WbsTreeContract>lambdaUpdate().set(WbsTreeContract::getPartitionCode,dto.getDivisionCode()).eq(WbsTreeContract::getPKeyId,vo.getPrimaryKeyId()));
-                        updateList.add(vo.getNodeName());
+                if(vo.getNodeName().equals(dto.getDivisionName())&&vo.getNodeType()==2&&!vo.getPartitionCode().equals(dto.getDivisionCode())){
+                    Boolean exist = this.isExist(dto, WbsTreeContractListupdate, 3, wbsTreeContractRoot);
+                    if(exist){
+                        if(isTrueNode(Arrays.asList(dto.getUnitName(),dto.getSubUnitName(),dto.getDivisionName()),vo)){
+                            baseMapper.update(null,Wrappers.<WbsTreeContract>lambdaUpdate().set(WbsTreeContract::getPartitionCode,dto.getDivisionCode()).eq(WbsTreeContract::getPKeyId,vo.getPKeyId()));
+                            updateList.add(vo.getNodeName());
+                            dto.setIsDivision(true);
+                        }
+
+                        continue;
                     }
-                    dto.setIsDivision(true);
-                    continue;
                 }
                 //wbs节点和子分部工程的名称类型能对应上,并且编号不一样,并且祖级节点也都能对应上,就修改编号
-                if(vo.getNodeName().equals(dto.getSubDivisionName())&&vo.getNodeType()==3&&(vo.getPartitionCode()==null||!vo.getPartitionCode().equals(dto.getSubDivisionName()))){
-                    if(isTrueNode(Arrays.asList(dto.getUnitName(),dto.getSubUnitName(),dto.getDivisionName(),dto.getSubDivisionName()),vo)){
-                        baseMapper.update(null,Wrappers.<WbsTreeContract>lambdaUpdate().set(WbsTreeContract::getPartitionCode,dto.getSubDivisionCode()).eq(WbsTreeContract::getPKeyId,vo.getPrimaryKeyId()));
-                        updateList.add(vo.getNodeName());
+                if(vo.getNodeName().equals(dto.getSubDivisionName())&&vo.getNodeType()==3&&(vo.getPartitionCode()==null||!vo.getPartitionCode().equals(dto.getSubDivisionCode()))){
+                    Boolean exist = this.isExist(dto, WbsTreeContractListupdate, 4, wbsTreeContractRoot);
+                    if(exist){
+                        if(isTrueNode(Arrays.asList(dto.getUnitName(),dto.getSubUnitName(),dto.getDivisionName(),dto.getSubDivisionName()),vo)){
+                            baseMapper.update(null,Wrappers.<WbsTreeContract>lambdaUpdate().set(WbsTreeContract::getPartitionCode,dto.getSubDivisionCode()).eq(WbsTreeContract::getPKeyId,vo.getPKeyId()));
+                            updateList.add(vo.getNodeName());
+                            dto.setIsSubDivision(true);
+                        }
+
+                        continue;
                     }
-                    dto.setIsSubDivision(true);
-                    continue;
                 }
                 //wbs节点和分项工程的名称类型能对应上,并且编号不一样,并且祖级节点也都能对应上,就修改编号
-                if(vo.getNodeName().equals(dto.getItemName())&&vo.getNodeType()==4&&(vo.getPartitionCode()==null||!vo.getPartitionCode().equals(dto.getItemName()))){
-                    if(isTrueNode(Arrays.asList(dto.getUnitName(),dto.getSubUnitName(),dto.getDivisionName(),dto.getSubDivisionName(),dto.getItemName()),vo)){
-                        baseMapper.update(null,Wrappers.<WbsTreeContract>lambdaUpdate().set(WbsTreeContract::getPartitionCode,dto.getItemCode()).eq(WbsTreeContract::getPKeyId,vo.getPrimaryKeyId()));
-                        updateList.add(vo.getNodeName());
+                if(vo.getNodeName().equals(dto.getItemName())&&vo.getNodeType()==4&&(vo.getPartitionCode()==null||!vo.getPartitionCode().equals(dto.getItemCode()))){
+                    Boolean exist = this.isExist(dto, WbsTreeContractListupdate, 5, wbsTreeContractRoot);
+                    if(exist){
+                        if(isTrueNode(Arrays.asList(dto.getUnitName(),dto.getSubUnitName(),dto.getDivisionName(),dto.getSubDivisionName(),dto.getItemName()),vo)){
+                            baseMapper.update(null,Wrappers.<WbsTreeContract>lambdaUpdate().set(WbsTreeContract::getPartitionCode,dto.getItemCode()).eq(WbsTreeContract::getPKeyId,vo.getPKeyId()));
+                            updateList.add(vo.getNodeName());
+                            dto.setIsItem(true);
+                        }
+
+                        continue;
                     }
-                    dto.setIsItem(true);
-                    continue;
                 }
                 //wbs节点和子分项工程的名称类型能对应上,并且编号不一样,并且祖级节点也都能对应上,就修改编号
-                if(vo.getNodeName().equals(dto.getSubItemName())&&vo.getNodeType()==5&&(vo.getPartitionCode()==null||!vo.getPartitionCode().equals(dto.getSubItemName()))){
-                    if(isTrueNode(Arrays.asList(dto.getUnitName(),dto.getSubUnitName(),dto.getDivisionName(),dto.getSubDivisionName(),dto.getItemName(),dto.getSubItemName()),vo)){
-                        baseMapper.update(null,Wrappers.<WbsTreeContract>lambdaUpdate().set(WbsTreeContract::getPartitionCode,dto.getSubItemCode()).eq(WbsTreeContract::getPKeyId,vo.getPrimaryKeyId()));
-                        updateList.add(vo.getNodeName());
+                if(vo.getNodeName().equals(dto.getSubItemName())&&vo.getNodeType()==5&&(vo.getPartitionCode()==null||!vo.getPartitionCode().equals(dto.getSubItemCode()))){
+                    Boolean exist = this.isExist(dto, WbsTreeContractListupdate, 6, wbsTreeContractRoot);
+                    if(exist){
+                        if(isTrueNode(Arrays.asList(dto.getUnitName(),dto.getSubUnitName(),dto.getDivisionName(),dto.getSubDivisionName(),dto.getItemName(),dto.getSubItemName()),vo)){
+                            baseMapper.update(null,Wrappers.<WbsTreeContract>lambdaUpdate().set(WbsTreeContract::getPartitionCode,dto.getSubItemCode()).eq(WbsTreeContract::getPKeyId,vo.getPKeyId()));
+                            updateList.add(vo.getNodeName());
+                            dto.setIsSubItem(true);
+                        }
+                        break;
                     }
-                    dto.setIsSubItem(true);
-                    break;
+
                 }
             }
         }
         int i=0;
-        //新增
         for (ImportTreeDto dto : list) {
+            //新增
+            String sqlList1="Select parent_id,node_name from m_wbs_tree_contract where contract_id="+wbsTreeContractRoot.getContractId()+" and wbs_id="+wbsTreeContractRoot.getWbsId()+" and is_deleted=0";
+            List<WbsTreeContract> WbsTreeContractList = jdbcTemplate.query(sqlList1, new BeanPropertyRowMapper<>(WbsTreeContract.class));
             i++;
             //单位工程:如果没有被处理过,说明需要新增
-            String sqlList="Select * from m_wbs_tree_contract where contract_id="+wbsTreeContractRoot.getContractId()+" and wbs_id="+wbsTreeContractRoot.getWbsId()+" and is_deleted=0";
-            List<WbsTreeContract> WbsTreeContractList = jdbcTemplate.query(sqlList, new BeanPropertyRowMapper<>(WbsTreeContract.class));
             if (!dto.getIsUnit()){
                 //检测是否已经存在,如果存在,就不需要新增了
-                Boolean exist = this.isExist(dto, WbsTreeContractList, 1, Long.valueOf(wbsTreeContractRoot.getContractId()));
+                Boolean exist = this.isExist(dto, WbsTreeContractList, 1, wbsTreeContractRoot);
                 if(!exist){
                     WbsTreeContract unit = new WbsTreeContract();
                     BeanUtil.copy(wbsTreeContractRoot,unit);
@@ -2444,14 +2502,16 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
                     unit.setFullName(dto.getUnitName());
                     unit.setIsTypePrivatePid(null);
                     unit.setSort(i);
+                    unit.setTreePId(null);
+                    unit.setPId(wbsTreeContractRoot.getPKeyId());
+                    unit.setAncestorsPId(wbsTreeContractRoot.getAncestorsPId() + "," + wbsTreeContractRoot.getPKeyId());
                     baseMapper.insert(unit);
                     insertList.add(unit);
                 }
-
             }
             //子单位工程:如果没有被处理过,说明需要新增,最重要是需要找到父节点。单位工程不会有相同的,所以直接根据名称查找
             if(!dto.getIsSubUnit()){
-                Boolean exist = this.isExist(dto, WbsTreeContractList, 2, Long.valueOf(wbsTreeContractRoot.getContractId()));
+                Boolean exist = this.isExist(dto, WbsTreeContractList, 2, wbsTreeContractRoot);
                 if(!exist){
                     WbsTreeContract fatherNode = baseMapper.selectOne(Wrappers.<WbsTreeContract>lambdaQuery().eq(WbsTreeContract::getNodeName, dto.getUnitName()).eq(WbsTreeContract::getProjectId, wbsTreeContractRoot.getProjectId())
                         .eq(WbsTreeContract::getContractId, wbsTreeContractRoot.getContractId()).eq(WbsTreeContract::getIsDeleted, 0).last("LIMIT 1"));
@@ -2468,6 +2528,9 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
                     subUnit.setFullName(dto.getSubUnitName());
                     subUnit.setIsTypePrivatePid(null);
                     subUnit.setSort(i);
+                    subUnit.setTreePId(null);
+                    subUnit.setPId(fatherNode.getPKeyId());
+                    subUnit.setAncestorsPId(fatherNode.getAncestorsPId() + "," + fatherNode.getPKeyId());
                     baseMapper.insert(subUnit);
                     insertList.add(subUnit);
                 }
@@ -2475,7 +2538,7 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
             }
             //分部工程:如果没有被处理过,说明需要新增,最重要是需要找到父节点。现在的办法是(通过祖级节点名称拼接的方式来判断)。
             if(!dto.getIsDivision()){
-                Boolean exist = this.isExist(dto, WbsTreeContractList, 3, Long.valueOf(wbsTreeContractRoot.getContractId()));
+                Boolean exist = this.isExist(dto, WbsTreeContractList, 3, wbsTreeContractRoot);
                 if(!exist){
                     String fatherNodeName="";
                     if(dto.getSubUnitName()!=null&&!dto.getSubUnitName().equals("")){
@@ -2487,7 +2550,7 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
                         .eq(WbsTreeContract::getContractId, wbsTreeContractRoot.getContractId()).eq(WbsTreeContract::getIsDeleted, 0));
                     if(list1.size()>0){
                         for (WbsTreeContract contract : list1) {
-                            String[] ids = contract.getAncestors().split(",");
+                            String[] ids = contract.getAncestorsPId().split(",");
                             ids=Arrays.stream(ids)
                                 .filter(id -> !id.equals("0")) // 过滤掉值为 "0" 的元素
                                 .toArray(String[]::new);
@@ -2510,6 +2573,9 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
                                 division.setFullName(dto.getDivisionName());
                                 division.setIsTypePrivatePid(null);
                                 division.setSort(i);
+                                division.setTreePId(null);
+                                division.setPId(contract.getPKeyId());
+                                division.setAncestorsPId(contract.getAncestorsPId() + "," + contract.getPKeyId());
                                 baseMapper.insert(division);
                                 insertList.add(division);
                                 break;
@@ -2521,7 +2587,7 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
             }
             //子分部工程:如果没有被处理过,说明需要新增,最重要是需要找到父节点。现在的办法是(通过祖级节点名称拼接的方式来判断)。
             if(!dto.getIsSubDivision()){
-                Boolean exist = this.isExist(dto, WbsTreeContractList, 4, Long.valueOf(wbsTreeContractRoot.getContractId()));
+                Boolean exist = this.isExist(dto, WbsTreeContractList, 4, wbsTreeContractRoot);
                 if(!exist){
                     String fatherNodeName="";
                     if(dto.getDivisionName()!=null&&!dto.getDivisionName().equals("")){
@@ -2535,7 +2601,7 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
                         .eq(WbsTreeContract::getContractId, wbsTreeContractRoot.getContractId()).eq(WbsTreeContract::getIsDeleted, 0));
                     if(list1.size()>0){
                         for (WbsTreeContract contract : list1) {
-                            String[] ids = contract.getAncestors().split(",");
+                            String[] ids = contract.getAncestorsPId().split(",");
                             ids=Arrays.stream(ids)
                                 .filter(id -> !id.equals("0")) // 过滤掉值为 "0" 的元素
                                 .toArray(String[]::new);
@@ -2559,6 +2625,9 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
                                 subDivision.setFullName(dto.getSubDivisionName());
                                 subDivision.setIsTypePrivatePid(null);
                                 subDivision.setSort(i);
+                                subDivision.setTreePId(null);
+                                subDivision.setPId(contract.getPKeyId());
+                                subDivision.setAncestorsPId(contract.getAncestorsPId() + "," + contract.getPKeyId());
                                 baseMapper.insert(subDivision);
                                 insertList.add(subDivision);
                                 break;
@@ -2570,7 +2639,7 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
             }
             //分项节点:如果没有被处理过,说明需要新增,最重要是需要找到父节点。现在的办法是(通过祖级节点名称拼接的方式来判断)。
             if(!dto.getIsItem()){
-                Boolean exist = this.isExist(dto, WbsTreeContractList, 5, Long.valueOf(wbsTreeContractRoot.getContractId()));
+                Boolean exist = this.isExist(dto, WbsTreeContractList, 5, wbsTreeContractRoot);
                 if(!exist){
                     String fatherNodeName="";
                     if(dto.getSubDivisionName()!=null&&!dto.getSubDivisionName().equals("")){
@@ -2587,7 +2656,7 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
                         .eq(WbsTreeContract::getContractId, wbsTreeContractRoot.getContractId()).eq(WbsTreeContract::getIsDeleted, 0));
                     if(list1.size()>0){
                         for (WbsTreeContract contract : list1) {
-                            String[] ids = contract.getAncestors().split(",");
+                            String[] ids = contract.getAncestorsPId().split(",");
                             ids=Arrays.stream(ids)
                                 .filter(id -> !id.equals("0")) // 过滤掉值为 "0" 的元素
                                 .toArray(String[]::new);
@@ -2612,6 +2681,9 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
                                 item.setFullName(dto.getItemName());
                                 item.setIsTypePrivatePid(null);
                                 item.setSort(i);
+                                item.setTreePId(null);
+                                item.setPId(contract.getPKeyId());
+                                item.setAncestorsPId(contract.getAncestorsPId() + "," + contract.getPKeyId());
                                 baseMapper.insert(item);
                                 insertList.add(item);
                                 break;
@@ -2623,7 +2695,7 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
             }
             //子分项节点:如果没有被处理过,说明需要新增,最重要是需要找到父节点。现在的办法是(通过祖级节点名称拼接的方式来判断)。
             if(!dto.getIsSubItem()){
-                Boolean exist = this.isExist(dto, WbsTreeContractList, 6, Long.valueOf(wbsTreeContractRoot.getContractId()));
+                Boolean exist = this.isExist(dto, WbsTreeContractList, 6, wbsTreeContractRoot);
                 if(!exist){
                     String fatherNodeName="";
                     if(dto.getItemName()!=null&&!dto.getItemName().equals("")){
@@ -2642,7 +2714,7 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
                         .eq(WbsTreeContract::getContractId, wbsTreeContractRoot.getContractId()).eq(WbsTreeContract::getIsDeleted, 0));
                     if(list1.size()>0){
                         for (WbsTreeContract contract : list1) {
-                            String[] ids = contract.getAncestors().split(",");
+                            String[] ids = contract.getAncestorsPId().split(",");
                             ids=Arrays.stream(ids)
                                 .filter(id -> !id.equals("0")) // 过滤掉值为 "0" 的元素
                                 .toArray(String[]::new);
@@ -2668,6 +2740,9 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
                                 subItem.setFullName(dto.getSubItemName());
                                 subItem.setIsTypePrivatePid(null);
                                 subItem.setSort(i);
+                                subItem.setTreePId(null);
+                                subItem.setPId(contract.getPKeyId());
+                                subItem.setAncestorsPId(contract.getAncestorsPId() + "," + contract.getPKeyId());
                                 baseMapper.insert(subItem);
                                 insertList.add(subItem);
                                 break;
@@ -2973,7 +3048,8 @@ public static boolean hasConflictingCodes(List<ImportTreeDto> list) {
             Objects.equals(fatherNodeType1, fatherNodeType2) &&
             !Objects.equals(dto1.getSubItemCode(), dto2.getSubItemCode());
     }
-    private Boolean isExist(ImportTreeDto dto, List<WbsTreeContract> wbsTreeContractList, int type,Long contractId) {
+    private Boolean isExist(ImportTreeDto dto, List<WbsTreeContract> wbsTreeContractList, int type,WbsTreeContract tree) {
+        Long contractId=Long.valueOf(tree.getContractId());
         String nodeName="";
         if(type==1){
             nodeName=dto.getUnitName();
@@ -2996,7 +3072,7 @@ public static boolean hasConflictingCodes(List<ImportTreeDto> list) {
         String finalNodeName = nodeName;
         List<Long> list = wbsTreeContractList.stream()
             .filter(item -> finalNodeName.equals(item.getNodeName()))
-            .map(item -> item.getParentId())
+            .map(item -> item.getPId())
             .collect(Collectors.toList());
         if(list.size()==0){
             return false;
@@ -3005,56 +3081,40 @@ public static boolean hasConflictingCodes(List<ImportTreeDto> list) {
                 return true;
             }
             //如果数据库中存在名称相同的节点,查询该节点的祖级节点
-            String sql="select node_name from m_wbs_tree_contract where is_deleted=0 and contract_id="+contractId+" and id in ("+String.join(",", list.stream().map(String::valueOf).collect(Collectors.toList()))+")";
-            List<String> nodeNames = jdbcTemplate.query(sql, new SingleColumnRowMapper<>(String.class));
+            String sql="select p_key_id,node_name from m_wbs_tree_contract where is_deleted=0 and contract_id="+contractId+" and p_key_id in ("+String.join(",", list.stream().map(String::valueOf).collect(Collectors.toList()))+")";
+            List<WbsTreeContract> wbsContracts = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(WbsTreeContract.class));
             String  fatherNodeName="";
             if(type==2){
-                fatherNodeName=dto.getUnitName();
+                fatherNodeName=tree.getNodeName()+dto.getUnitName();
             }
            else if(type==3){
-                if(dto.getSubUnitName()!=null&&!dto.getSubUnitName().equals("")){
-                    fatherNodeName=dto.getSubUnitName();
-                }else if(dto.getUnitName()!=null&&!dto.getUnitName().equals("")){
-                    fatherNodeName=dto.getUnitName();
-                }
+                fatherNodeName=tree.getNodeName()+dto.getUnitName()+dto.getSubUnitName();
             }
             else if(type==4){
-                if(dto.getDivisionName()!=null&&!dto.getDivisionName().equals("")){
-                    fatherNodeName=dto.getDivisionName();
-                } else if(dto.getSubUnitName()!=null&&!dto.getSubUnitName().equals("")){
-                    fatherNodeName=dto.getSubUnitName();
-                }else if(dto.getUnitName()!=null&&!dto.getUnitName().equals("")){
-                    fatherNodeName=dto.getUnitName();
-                }
+                fatherNodeName=tree.getNodeName()+dto.getUnitName()+dto.getSubUnitName()+dto.getDivisionName();
             }
             else if(type==5){
-                if(dto.getSubDivisionName()!=null&&!dto.getSubDivisionName().equals("")){
-                    fatherNodeName=dto.getSubDivisionName();
-                }
-                else if(dto.getDivisionName()!=null&&!dto.getDivisionName().equals("")){
-                    fatherNodeName=dto.getDivisionName();
-                } else if(dto.getSubUnitName()!=null&&!dto.getSubUnitName().equals("")){
-                    fatherNodeName=dto.getSubUnitName();
-                }else if(dto.getUnitName()!=null&&!dto.getUnitName().equals("")){
-                    fatherNodeName=dto.getUnitName();
-                }
+                fatherNodeName=tree.getNodeName()+dto.getUnitName()+dto.getSubUnitName()+dto.getDivisionName()+dto.getSubDivisionName();
             }
             else  if(type==6){
-                if(dto.getItemName()!=null&&!dto.getItemName().equals("")){
-                } else  if(dto.getSubDivisionName()!=null&&!dto.getSubDivisionName().equals("")){
-                    fatherNodeName=dto.getSubDivisionName();
-                }
-                else if(dto.getDivisionName()!=null&&!dto.getDivisionName().equals("")){
-                    fatherNodeName=dto.getDivisionName();
-                } else if(dto.getSubUnitName()!=null&&!dto.getSubUnitName().equals("")){
-                    fatherNodeName=dto.getSubUnitName();
-                }else if(dto.getUnitName()!=null&&!dto.getUnitName().equals("")){
-                    fatherNodeName=dto.getUnitName();
+                fatherNodeName=tree.getNodeName()+dto.getUnitName()+dto.getSubUnitName()+dto.getDivisionName()+dto.getSubDivisionName()+dto.getItemName();
+            }
+            if(wbsContracts.size()>0){
+                for (WbsTreeContract wbsContract : wbsContracts) {
+                        String Sql="select ancestors_p_id from m_wbs_tree_contract where p_key_id="+wbsContract.getPKeyId();
+                        String ancestors = jdbcTemplate.queryForObject(Sql, new SingleColumnRowMapper<>(String.class));
+                        String[] ids = ancestors.split(",");
+                        ids=Arrays.stream(ids)
+                            .filter(id -> !id.equals("0")) // 过滤掉值为 "0" 的元素
+                            .toArray(String[]::new);
+                        String sql1="Select node_name from m_wbs_tree_contract where p_key_id in("+String.join(",", ids)+")";
+                        List<String> nodeNames = jdbcTemplate.query(sql1, new SingleColumnRowMapper<>(String.class));
+                        String join = String.join("", nodeNames);
+                        if(join.equals(fatherNodeName)){
+                            return true;
+                        }
                 }
-            }
-
-            if(nodeNames.size()>0&&nodeNames.contains(fatherNodeName)){
-                return true;
+                return false;
             }
             return false;
         }

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

@@ -3,6 +3,7 @@ package org.springblade.manager.utils;
 import com.aspose.cells.PdfSaveOptions;
 import com.aspose.cells.SaveFormat;
 import com.aspose.cells.Workbook;
+import com.itextpdf.io.image.ImageType;
 import com.itextpdf.text.Document;
 import com.itextpdf.text.pdf.PdfCopy;
 import com.itextpdf.text.pdf.PdfReader;
@@ -1050,4 +1051,7 @@ public class FileUtils {
         return file;
     }
 
+
+
+
 }

+ 377 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/utils/SignFtpUtil.java

@@ -0,0 +1,377 @@
+package org.springblade.manager.utils;
+
+
+import com.mixsmart.utils.StringUtils;
+import lombok.AllArgsConstructor;
+import org.apache.commons.net.ftp.FTP;
+import org.apache.commons.net.ftp.FTPClient;
+import org.springblade.common.utils.CommonUtil;
+import org.springblade.manager.controller.ExcelTabController;
+import org.springblade.manager.entity.ExcelTab;
+import org.springblade.manager.entity.WbsTreePrivate;
+import org.springframework.jdbc.core.BeanPropertyRowMapper;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.mock.web.MockMultipartFile;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import java.io.*;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+@Component
+public class SignFtpUtil {
+
+    // -外网
+    private static String SERVER = "219.151.181.73";
+    private static final int PORT = 21 ;
+    private static final String USER = "chenran";
+    private static final String PASS = "123456";
+    private static final int CONNECT_TIMEOUT = 9000000; // 30秒
+    private static final int DATA_TIMEOUT = 9000000;
+    private static final String PATH = "/mnt/sdc/Users/hongchuangyanfa/Desktop";
+    @Resource
+    private  JdbcTemplate jdbcTemplate;
+
+    /**
+     *  获取ftp 客户端
+     * @return
+     */
+    public static FTPClient getFTPClinet() {
+        FTPClient ftp = new FTPClient();
+        try {
+            ftp.setControlEncoding("UTF-8");
+            // 设置连接超时时间
+            ftp.setConnectTimeout(CONNECT_TIMEOUT);
+            // 设置数据传输超时时间
+            ftp.setDataTimeout(DATA_TIMEOUT);
+            // 连接到FTP服务器
+            //String sys_isonline = ParamCache.getValue(CommonConstant.SYS_ISONLINE);
+            System.out.println("ftp上传ip地址:"+SERVER);
+            ftp.connect(SERVER, PORT);
+            ftp.setControlEncoding("UTF-8");
+            ftp.enterLocalPassiveMode();
+            ftp.setFileType(FTP.BINARY_FILE_TYPE);
+            ftp.enterLocalPassiveMode();//被动模式
+            //登录
+            boolean loginS = ftp.login(USER, PASS);
+            if (!loginS) {
+                return null;
+            } else {
+                return ftp;
+            }
+        } catch (IOException e) {
+            System.out.println("ftp连接失败");
+            return null;
+        }
+    }
+
+    /**
+     *  上传
+     * @return
+     */
+    public static int uploadFile(String localFilePath, String remoteFilePath) {
+        // 设置连接超时时间
+        FTPClient ftpClinet = SignFtpUtil.getFTPClinet();
+        try {
+            // 检查本地文件是否存在
+            File localFile = new File(localFilePath);
+            if (!localFile.exists()) {
+                return 2;
+            }
+            // 上传文件
+            FileInputStream inputStream = new FileInputStream(localFile);
+            try {
+                boolean done = ftpClinet.storeFile(remoteFilePath, inputStream);
+                if (done) {
+                    return 1;
+                } else {
+                    return 3;
+                }
+            } finally {
+                inputStream.close();
+            }
+
+        } catch (IOException e) {
+            e.printStackTrace();
+            return 4;
+        } finally {
+            try {
+                if (ftpClinet.isConnected()) {
+                    ftpClinet.logout();
+                    ftpClinet.disconnect();
+                }
+            } catch (IOException ex) {
+                ex.printStackTrace();
+                return 5;
+            }
+        }
+    }
+
+    /**
+     *  上传
+     * @return
+     */
+    public static int uploadFile(String remoteFilePath, InputStream inputStream) {
+        // 设置连接超时时间
+        FTPClient ftpClinet = SignFtpUtil.getFTPClinet();
+        try {
+            try {
+                System.out.println("上传文件中.....文件路径:" + remoteFilePath);
+                boolean done = ftpClinet.storeFile(remoteFilePath, inputStream);
+                if (done) {
+                    return 1;
+                } else {
+                    return 3;
+                }
+            } finally {
+                inputStream.close();
+            }
+
+        } catch (IOException e) {
+            e.printStackTrace();
+            return 4;
+        } finally {
+            try {
+                if (ftpClinet.isConnected()) {
+                    ftpClinet.logout();
+                    ftpClinet.disconnect();
+                }
+            } catch (IOException ex) {
+                ex.printStackTrace();
+                return 5;
+            }
+        }
+    }
+
+    /**
+     *  删除FTP文件
+     * @return
+     */
+    public static int FTPDeleteDir(String remoteFilePath) {
+        FTPClient ftpClinet = SignFtpUtil.getFTPClinet();
+        try {
+            if (ftpClinet.deleteFile(remoteFilePath)) {
+                System.out.println(remoteFilePath+"-s");
+                return 1;
+            } else {
+                System.out.println(remoteFilePath+"-f");
+                return 2;
+            }
+        } catch (Exception e) {
+            System.out.println(e+"-f");
+            e.printStackTrace();
+            return 2;
+        } finally {
+            try {
+                if (ftpClinet.isConnected()) {
+                    ftpClinet.logout();
+                    ftpClinet.disconnect();
+                }
+                return 1;
+            } catch (IOException ex) {
+                ex.printStackTrace();
+                return 5;
+            }
+        }
+    }
+    /**
+     *  创建文件路径
+     * @return
+     */
+    public static int FTPCreateDir(String remoteFilePath) {
+        FTPClient ftpClinet = SignFtpUtil.getFTPClinet();
+        try {
+            if (ftpClinet.makeDirectory(remoteFilePath)) {
+                return 1;
+            } else {
+                return 2;
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            return 2;
+        } finally {
+            try {
+                if (ftpClinet.isConnected()) {
+                    ftpClinet.logout();
+                    ftpClinet.disconnect();
+                }
+                return 1;
+            } catch (IOException ex) {
+                ex.printStackTrace();
+                return 5;
+            }
+        }
+    }
+
+
+    /**
+     *  下载
+     * @return
+     */
+    public static int downloadFile(String localFilePath, String remoteFilePath) {
+        // 设置连接超时时间
+        FTPClient ftpClinet = SignFtpUtil.getFTPClinet();
+        try {
+            // 上传文件
+            System.out.println("下载文件中.....路径:" + remoteFilePath);
+            OutputStream outputStream = new FileOutputStream(new File(localFilePath));
+            try {
+                boolean done = ftpClinet.retrieveFile(remoteFilePath, outputStream);
+                if (done) {
+                    return 1;
+                } else {
+                    return 3;
+                }
+            } finally {
+                outputStream.close();
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+            return 4;
+        } finally {
+            try {
+                if (ftpClinet.isConnected()) {
+                    ftpClinet.logout();
+                    ftpClinet.disconnect();
+                }
+            } catch (IOException ex) {
+                ex.printStackTrace();
+                return 5;
+            }
+        }
+    }
+
+    public void html() throws IOException {
+        String sql="SELECT p_key_id,project_id,html_url from m_wbs_tree_private where type=2 and is_deleted=0 and html_url NOT LIKE '%privateUrlCopy%'";
+        List<WbsTreePrivate> list = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(WbsTreePrivate.class));
+        int i=list.size();
+        for (WbsTreePrivate w : list) {
+            i--;
+            //数据库原始html路径
+            String htmlUrl = w.getHtmlUrl();
+            if(StringUtils.isNotEmpty(htmlUrl)){
+                //截取出的要下载的html
+                String DownLoadhtmlUrl=htmlUrl.substring(htmlUrl.lastIndexOf("/"));
+                String projectPath="E:\\html\\"+w.getProjectId();
+                File folder = new File(projectPath);
+                if(!folder.exists()){
+                    folder.mkdir();
+                }
+                //本地下载的路径
+                String localPath=projectPath+"\\"+htmlUrl.substring(htmlUrl.lastIndexOf("/")+1);
+                File folder1 = new File(localPath);
+                if(!folder1.exists()){
+                    //下载文件
+                    downloadFile(localPath,"/privateUrl"+DownLoadhtmlUrl);
+                }
+                File localFile = new File(localPath);
+                if (localFile.exists()) {
+                    String sqlPath="/mnt/sdc/Users/hongchuangyanfa/Desktop"+"/privateUrlCopy"+"/"+w.getProjectId()+DownLoadhtmlUrl;
+                   String update="update m_wbs_tree_private set html_url='"+sqlPath+"' where p_key_id="+w.getPKeyId();
+                   jdbcTemplate.update(update);
+                }
+            }
+            System.out.println("还有"+i+"条");
+        }
+    }
+
+       public void htm183l() throws Exception {
+           String sql="SELECT p_key_id,project_id,html_url from m_wbs_tree_private where type=2 and is_deleted=0 and html_url NOT LIKE '%privateUrlCopy%'";
+           List<WbsTreePrivate> list = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(WbsTreePrivate.class));
+           int i=list.size();
+           for (WbsTreePrivate w : list) {
+               i--;
+               String localUrl="E:\\html183\\"+w.getProjectId();
+               String htmlUrl = w.getHtmlUrl();
+               String htmlName=htmlUrl.substring(htmlUrl.lastIndexOf("/"));
+                InputStream inputStreamByUrl = FileUtils.getInputStreamByUrl(htmlUrl);
+                if(inputStreamByUrl!=null){
+                    File folder = new File(localUrl);
+                    if (!folder.exists()) {
+                        folder.mkdir();
+                    }
+                    File localFile = new File(localUrl+htmlName);
+                    if(!localFile.exists()){
+                        FileUtils.saveFile(inputStreamByUrl, localUrl+htmlName);
+                    }
+                    if(localFile.exists()){
+                        String sqlPath="/home/www/wwwroot/Users/hongchuangyanfa/Desktop/privateUrlCopy/"+w.getProjectId()+htmlName;
+                        String update="update m_wbs_tree_private set html_url='"+sqlPath+"' where p_key_id="+w.getPKeyId();
+                        jdbcTemplate.update(update);
+                    }
+                }
+               System.out.println("还有"+i+"条");
+           }
+        }
+
+        public void checkHtml() throws Exception {
+            StringBuilder result=new StringBuilder("");
+            String sql = "Select * from m_excel_tab where parent_id=0 and is_deleted=0";
+            List<ExcelTab> query = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(ExcelTab.class));
+            String excelPath="E\\excel\\";
+            for (ExcelTab excelTab : query) {
+                String sql1 = "Select * from m_excel_tab where parent_id=" + excelTab.getId() + " and is_deleted=0";
+                List<ExcelTab> query1 = jdbcTemplate.query(sql1, new BeanPropertyRowMapper<>(ExcelTab.class));
+                for (ExcelTab tab : query1) {
+                    String sql2 = "Select * from m_excel_tab where parent_id=" + tab.getId() + " and is_deleted=0";
+                    List<ExcelTab> query2 = jdbcTemplate.query(sql2, new BeanPropertyRowMapper<>(ExcelTab.class));
+
+                    for (ExcelTab excelTab1 : query2) {
+                        if(!isExist(excelTab1.getHtmlUrl())){
+                            if(excelTab1.getFileUrl() != null&&excelTab1.getFileUrl().endsWith(".xlsx") || excelTab1.getFileUrl().endsWith(".xls")){
+                                long resourceLength = CommonUtil.getResourceLength(excelTab1.getFileUrl());
+                                if(resourceLength>=500){
+                                    //先下载这个文件,再上传
+                                    String fileUrl = excelTab1.getFileUrl();
+                                    String url = fileUrl.substring(fileUrl.indexOf("Desktop") + "Desktop".length() + 1);
+                                    String localPath=excelPath+url;
+                                    downloadFile(localPath, url);
+                                    Path path = Paths.get(localPath);
+                                    byte[] content = Files.readAllBytes(path);
+                                    MockMultipartFile file = new MockMultipartFile("file", excelTab1.getName(), "application/vnd.ms-excel", content);
+
+                                }else {
+                                    result.append(excelTab.getName() + "--" + tab.getName() + "--" + excelTab1.getName()+"\n");
+                                }
+                            }
+                        }
+                    }
+                    System.out.println(result);
+                }
+            }
+        }
+
+        public Boolean isExist(String path){
+            String server = SERVER;
+            int port = PORT;
+            String user = USER;
+            String pass = PASS;
+            FTPClient ftpClient = new FTPClient();
+            try {
+                ftpClient.connect(server, port);
+                ftpClient.login(user, pass);
+                // 尝试获取文件状态
+                try {
+                    if (ftpClient.getStatus(path) != null) {
+                        return true;
+                    }
+                } catch (IOException e) {
+                    return false;
+                }
+
+                ftpClient.logout();
+                ftpClient.disconnect();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+            return false;
+        }
+}

+ 1 - 1
blade-service/blade-meter/src/main/java/org/springblade/meter/controller/APIController.java

@@ -76,7 +76,7 @@ public class APIController {
         int current = dto.getCurrent();
         int size = dto.getSize();
         List<Object> params = new ArrayList<>();
-        StringBuilder sqlString = new StringBuilder("SELECT * FROM u_task WHERE 1=1 AND is_deleted = 0 AND approval_type in (5,6,7,8) "); //approval_type = 5 计量任务
+        StringBuilder sqlString = new StringBuilder("SELECT * FROM u_task WHERE 1=1 AND is_deleted = 0 AND approval_type in (5,6,7,11) "); //approval_type = 5 计量任务
         if(dto.getContractId()!=null&&dto.getProjectId()!=null){
             ContractInfo contractInfo = jdbcTemplate.queryForObject("select contract_type from m_contract_info where id = " + dto.getContractId(), new BeanPropertyRowMapper<>(ContractInfo.class));
             if (contractInfo != null && Arrays.asList(1, 4).contains(contractInfo.getContractType())) {

+ 27 - 10
blade-service/blade-meter/src/main/java/org/springblade/meter/controller/TaskController.java

@@ -85,6 +85,7 @@ import org.springblade.system.user.entity.User;
 import org.springblade.system.user.feign.IUserClient;
 import org.springblade.websocket.feign.WebSocketClient;
 import org.springblade.websocket.vo.UserInfoVO;
+import org.springframework.dao.DataAccessException;
 import org.springframework.jdbc.core.BeanPropertyRowMapper;
 import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.jdbc.core.SingleColumnRowMapper;
@@ -1018,7 +1019,11 @@ public class TaskController extends BladeController {
                         } catch (Exception e) {
                             throw new ServiceException("删除业务复制数据taskVO失败");
                         }
-
+                        try {
+                            jdbcTemplate.execute("UPDATE s_material_start_statement SET pre_pdf_url = null WHERE meter_period_id = " + periodId + " and is_deleted = 0 and type = 1");
+                        } catch (Exception e) {
+                            throw new ServiceException("删除假电签地址失败");
+                        }
                     } else if (task.getMeterTaskType().equals(3)) {
                         /*==================== 开工预付款计量单 ====================*/
                         /*获取当前期数下的所有材料*/
@@ -1044,9 +1049,15 @@ public class TaskController extends BladeController {
                         /*删除业务复制数据taskVO*/
                         try {
                             jdbcTemplate.execute("DELETE FROM s_start_pay_meter_form_task WHERE meter_period_id = '" + periodId + "' AND task_id = " + taskRepealDTO.getTaskId());
+
                         } catch (Exception e) {
                             throw new ServiceException("删除业务复制数据taskVO失败");
                         }
+                        try {
+                            jdbcTemplate.execute("UPDATE s_material_start_statement SET pre_pdf_url = null WHERE meter_period_id = " + periodId + " and is_deleted = 0 and type = 2");
+                        } catch (Exception e) {
+                            throw new ServiceException("删除假电签地址失败");
+                        }
 
                     } else if (task.getMeterTaskType().equals(4)) {
                         for (String dataId : periodId.split(",")) {
@@ -1118,7 +1129,7 @@ public class TaskController extends BladeController {
     public R<Integer> getTaskCount(@RequestParam Long projectId,@RequestParam(required = false) Long contractId){
         /*封装入参SQL*/
         List<Object> params = new ArrayList<>();
-        StringBuilder sqlString = new StringBuilder("SELECT * FROM u_task WHERE 1=1 AND is_deleted = 0 AND approval_type in (5,6,7,8) "); //approval_type = 5 计量任务
+        StringBuilder sqlString = new StringBuilder("SELECT * FROM u_task WHERE 1=1 AND is_deleted = 0 AND approval_type in (5,6,7,11) "); //approval_type = 5 计量任务
         Long userId1 = SecureUtil.getUserId();
         List<Long> projectIdss = jdbcTemplate.query("select project_id from m_project_assignment_user where user_id=" + userId1, new SingleColumnRowMapper<>(Long.class));
         sqlString.append(" AND project_id in(").append(StringUtils.join(projectIdss, ",")).append(")");
@@ -1200,7 +1211,7 @@ public class TaskController extends BladeController {
         int current = dto.getCurrent();
         int size = dto.getSize();
         List<Object> params = new ArrayList<>();
-        StringBuilder sqlString = new StringBuilder("SELECT * FROM u_task WHERE 1=1 AND is_deleted = 0 AND approval_type in (5,6,7,8) "); //approval_type = 5 计量任务
+        StringBuilder sqlString = new StringBuilder("SELECT * FROM u_task WHERE 1=1 AND is_deleted = 0 AND approval_type in (5,6,7,11) "); //approval_type = 5 计量任务
         Long userId1 = SecureUtil.getUserId();
         List<Long> projectIdss = jdbcTemplate.query("select project_id from m_project_assignment_user where user_id=" + userId1, new SingleColumnRowMapper<>(Long.class));
         sqlString.append(" AND project_id in(").append(StringUtils.join(projectIdss, ",")).append(")");
@@ -2068,7 +2079,7 @@ public class TaskController extends BladeController {
                         vo.setBasicsInfo(middleMeterApplyTaskVO);
 
                         /*清单信息*/
-                        List<MeterInventoryVO> formToTask = middleMeterApplyMapper.getFormCopy(Long.parseLong(dataId), middleMeterApplyTask.getContractId(), middleMeterApplyTask.getContractUnitId());
+                        List<MeterInventoryVO> formToTask = middleMeterApplyMapper.getFormCopy(Long.parseLong(dataId), middleMeterApplyTask.getContractId(), middleMeterApplyTask.getContractUnitId(),Long.valueOf(id));
                         for (MeterInventoryVO inventoryVO : formToTask) {
                             inventoryVO.setCurrentMeterMoney(inventoryVO.getCurrentMeterMoney().setScale(0,BigDecimal.ROUND_HALF_UP));
                         }
@@ -2267,7 +2278,7 @@ public class TaskController extends BladeController {
                             jdbcTemplate.execute("DELETE FROM s_inventory_form_apply WHERE id = " + inventoryFormApplyTask.getId());
 
                             /*清单信息*/
-                            List<MeterInventoryVO> formToTask = middleMeterApplyMapper.getFormCopy(middleMeterApplyTask.getId(), middleMeterApplyTask.getContractId(), middleMeterApplyTask.getContractUnitId());
+                            List<MeterInventoryVO> formToTask = middleMeterApplyMapper.getFormCopy(middleMeterApplyTask.getId(), middleMeterApplyTask.getContractId(), middleMeterApplyTask.getContractUnitId(),Long .valueOf(dto.getTaskId()));
                             if (formToTask == null || formToTask.size() == 0) {
                                 /*删除该条中间计量的清单附件*/
                                 jdbcTemplate.execute("DELETE FROM s_attachment_form_task WHERE file_type = 2 AND master_id = " + dto.getDataId());
@@ -2395,7 +2406,7 @@ public class TaskController extends BladeController {
                 if (middleMeterApplyTask != null) {
 
                     /*清单信息*/
-                    List<MeterInventoryVO> formToTask = middleMeterApplyMapper.getFormCopy(middleMeterApplyTask.getId(), middleMeterApplyTask.getContractId(), middleMeterApplyTask.getContractUnitId());
+                    List<MeterInventoryVO> formToTask = middleMeterApplyMapper.getFormCopy(middleMeterApplyTask.getId(), middleMeterApplyTask.getContractId(), middleMeterApplyTask.getContractUnitId(),dto.getTaskId());
 
                     BigDecimal totalSumMoney = BigDecimal.ZERO;
                     for (MeterInventoryVO meterInventoryVO : formToTask) {
@@ -2483,7 +2494,7 @@ public class TaskController extends BladeController {
                     inventoryFormApplyServiceTask.saveBatch(formAppliesTask);
 
                     /*获取当前所有清单信息*/
-                    List<MeterInventoryVO> formToTask = middleMeterApplyMapper.getFormCopy(middleMeterApplyTask.getId(), middleMeterApplyTask.getContractId(), middleMeterApplyTask.getContractUnitId());
+                    List<MeterInventoryVO> formToTask = middleMeterApplyMapper.getFormCopy(middleMeterApplyTask.getId(), middleMeterApplyTask.getContractId(), middleMeterApplyTask.getContractUnitId(),dto.getTaskId());
 
                     BigDecimal totalSum = BigDecimal.ZERO;
                     for (MeterInventoryVO meterInventoryVO : formToTask) {
@@ -3918,10 +3929,16 @@ public class TaskController extends BladeController {
         try {
             String delTaskPall = "DELETE from u_task_parallel where process_instance_id in (SELECT process_instance_id from u_task where form_data_id ='" + periodId + "') ";
             String delTask = "DELETE from u_task where form_data_id ='" + periodId + "'";
-            Integer type1=type+5;
+            Integer type1;
+            if (type == 3) {
+                type1 = 11;
+            } else {
+                type1=type+5;
+            }
             //查询出当前计量期对应的任务
             String selectTask = "SELECT * from u_task WHERE approval_type =? and form_data_id = ? and is_deleted = 0 and status in (1,2)";
             List<Task> list = jdbcTemplate.query(selectTask, new BeanPropertyRowMapper<>(Task.class), type1,periodId);
+            System.out.println("wewecq"+selectTask);
             if (list.size() == 0){
                 return R.fail("撤销失败:未查出当前计量期对应任务信息");
             }
@@ -4146,11 +4163,11 @@ public class TaskController extends BladeController {
             stringBuilder.deleteCharAt(stringBuilder.length() - 1);
             stringBuilder.append("}");
             String string = stringBuilder.toString();
-            String sqlUpdate = "update s_interim_pay_certificate set file_url_list = '"+string +"',raw_url = '"+rawPdfUrL+"' where id = "+report.getId();
+            String sqlUpdate = "update s_interim_pay_certificate set file_url_list = '"+string +"',raw_url = '"+rawPdfUrL+"',pre_pdf_url = '"+rawPdfUrL+"' where id = "+report.getId();
             jdbcTemplate.execute(sqlUpdate);
             if (taskType != 10) {
-                interimPayCertificateService.taskMeterPdfInfo2("",report.getPeriodId()+"",report.getType());
                 addSignTaskBatch(report);
+                interimPayCertificateService.taskMeterPdfInfo2("",report.getPeriodId()+"",report.getType());
             }
             return R.data(rawPdfUrL);
         }else{

+ 1 - 1
blade-service/blade-meter/src/main/java/org/springblade/meter/mapper/MiddleMeterApplyMapper.java

@@ -62,7 +62,7 @@ public interface MiddleMeterApplyMapper extends BaseMapper<MiddleMeterApply> {
 
     List<MeterInventoryVO> getForm(@Param("id") Long id,@Param("contractId") Long contractId,@Param("nodeId") Long nodeId);
 
-    List<MeterInventoryVO> getFormCopy(@Param("id") Long id,@Param("contractId") Long contractId,@Param("nodeId") Long nodeId);
+    List<MeterInventoryVO> getFormCopy(@Param("id") Long id,@Param("contractId") Long contractId,@Param("nodeId") Long nodeId,@Param("taskId")Long taskId);
 
     ChangeTokenForm getTokenById(@Param("id") Long id);
 

+ 1 - 1
blade-service/blade-meter/src/main/java/org/springblade/meter/mapper/MiddleMeterApplyMapper.xml

@@ -196,7 +196,7 @@
                                                                                       and contract_meter_id = #{nodeId} and contract_form_id = ifa.contract_form_id),0)) as allMeterTotal
         from s_inventory_form_apply_task ifa
         where ifa.contract_id = #{contractId} and ifa.is_deleted = 0
-          AND ifa.middle_meter_id = #{id}
+          AND ifa.middle_meter_id = #{id} ANd  ifa.task_id = #{taskId}
     </select>
 
     <select id="getTokenById" resultType="org.springblade.meter.entity.ChangeTokenForm">

+ 2 - 2
blade-service/blade-meter/src/main/java/org/springblade/meter/service/impl/InterimPayCertificateServiceImpl.java

@@ -231,7 +231,7 @@ public class InterimPayCertificateServiceImpl extends BaseServiceImpl<InterimPay
            }
 
             if(task == null && reportId!=null && reportId.length()>=6){
-                task = jdbcTemplate.query("SELECT * FROM u_task WHERE form_data_id = ? ", new Object[]{reportId}, new BeanPropertyRowMapper<>(Task.class)).stream().findAny().orElse(null);
+                task = jdbcTemplate.query("SELECT * FROM u_task WHERE status in(1,2) and  form_data_id = ? ", new Object[]{reportId}, new BeanPropertyRowMapper<>(Task.class)).stream().findAny().orElse(null);
             }
 
             if (task == null) {
@@ -293,7 +293,7 @@ public class InterimPayCertificateServiceImpl extends BaseServiceImpl<InterimPay
 
                     if (Func.isNotEmpty(maps) || maps.size() >= 1) {
                         InputStream ossInputStream = CommonUtil.getOSSInputStream(pdfUrl);
-                        String localPdfPath = FileUtils.getSysLocalFileUrl() + "/pdf//" + task.getId() + ".pdf";
+                        String localPdfPath = FileUtils.getSysLocalFileUrl() + "/pdf/" + task.getId() + ".pdf";
                         CommonUtil.convert(ossInputStream, localPdfPath);
                         PdfAddimgUtil.pdfAddImgInfo(localPdfPath, maps);
                         BladeFile bladeFile = this.newIOSSClient.uploadFile(task.getId() + ".pdf", localPdfPath);

+ 1 - 1
blade-service/blade-meter/src/main/java/org/springblade/meter/utils/PdfAddimgUtil.java

@@ -67,7 +67,7 @@ public class PdfAddimgUtil {
                     pyzby = Func.toFloat(textdictInfo.get(0).get("pyzby"));
                     signImg = textdictInfo.get(0).get("signature_file_url")+"";
                 }
-                System.out.println("任务电器:"+i);
+                System.out.println(positions.size()+"j电签:"+i);
                 gaizhang(pdfFile, new File(pdfUrl), (int) position[0], position[1], position[2], signImg,pyzbx,pyzby,type);
             }
         }

+ 69 - 0
blade-service/blade-repair/pom.xml

@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.springblade</groupId>
+        <artifactId>BladeX</artifactId>
+        <version>2.9.1.RELEASE</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>blade-repair</artifactId>
+
+    <properties>
+        <maven.compiler.source>8</maven.compiler.source>
+        <maven.compiler.target>8</maven.compiler.target>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+    <dependencies>
+        <dependency>
+            <groupId>org.springblade</groupId>
+            <artifactId>blade-core-launch</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springblade</groupId>
+            <artifactId>blade-core-boot</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springblade</groupId>
+            <artifactId>blade-common</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springblade</groupId>
+            <artifactId>blade-core-cloud</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springblade</groupId>
+            <artifactId>blade-manager-api</artifactId>
+            <version>2.9.1.RELEASE</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springblade</groupId>
+            <artifactId>blade-manager-api</artifactId>
+            <version>2.9.1.RELEASE</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.springblade</groupId>
+            <artifactId>blade-starter-oss</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springblade</groupId>
+            <artifactId>blade-resource-api</artifactId>
+            <version>2.9.1.RELEASE</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.springblade</groupId>
+            <artifactId>blade-system-api</artifactId>
+            <version>2.9.1.RELEASE</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-test</artifactId>
+        </dependency>
+    </dependencies>
+</project>

+ 18 - 0
blade-service/blade-repair/src/main/java/org/springblade/RepairApplication.java

@@ -0,0 +1,18 @@
+package org.springblade;
+
+import org.springblade.common.constant.LauncherConstant;
+import org.springblade.core.cloud.feign.EnableBladeFeign;
+import org.springblade.core.launch.BladeApplication;
+import org.springframework.cache.annotation.EnableCaching;
+import org.springframework.cloud.client.SpringCloudApplication;
+import org.springframework.scheduling.annotation.EnableAsync;
+
+@EnableBladeFeign
+@SpringCloudApplication
+@EnableAsync
+@EnableCaching
+public class RepairApplication {
+    public static void main(String[] args) {
+        BladeApplication.run(LauncherConstant.APPLICATION_METER_NAME, RepairApplication.class, args);
+    }
+}

+ 134 - 0
blade-service/blade-repair/src/main/java/org/springblade/repair/controller/CheckAndRepairController.java

@@ -0,0 +1,134 @@
+package org.springblade.repair.controller;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.AllArgsConstructor;
+import org.springblade.common.utils.CommonUtil;
+import org.springblade.common.utils.SnowFlakeUtil;
+import org.springblade.core.oss.model.BladeFile;
+import org.springblade.core.tool.api.R;
+import org.springblade.core.tool.utils.ObjectUtil;
+import org.springblade.manager.entity.ExcelTab;
+import org.springblade.repair.util.FileUtils;
+import org.springblade.resource.feign.NewIOSSClient;
+import org.springframework.jdbc.core.BeanPropertyRowMapper;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.mock.web.MockMultipartFile;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import org.springblade.manager.feign.ExcelTabClient;
+import org.springframework.web.multipart.MultipartFile;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.util.List;
+
+
+@RestController
+@AllArgsConstructor
+@RequestMapping("/checkAndRepair")
+@Api(value = "checkAndRepair", tags = "定时自动检测修复")
+public class CheckAndRepairController {
+   private final JdbcTemplate jdbcTemplate;
+    private final ExcelTabClient excelTabClient;
+    private final NewIOSSClient newIOSSClient;
+
+    /**
+     * 每天晚上1点检查excelHtml是否存在,如果不存在就下载excel表格然后重新上传
+     */
+    @RequestMapping("/checkAndRepairExcelHtml")
+    @ApiOperation("定时检测修复ExcelHtml")
+    @Scheduled(cron = "0  15 16 * * ?")
+    public void checkAndRepairExcelHtml() {
+        StringBuilder result=new StringBuilder("");
+        StringBuilder result1=new StringBuilder("");
+        String sql = "Select * from m_excel_tab where parent_id=0 and is_deleted=0";
+        List<ExcelTab> query = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(ExcelTab.class));
+        //String excelPath="E:\\excel\\";
+        String excelPath="/mnt/sdc/Users/hongchuangyanfa/Desktop/excel/";
+        try {
+            for (ExcelTab excelTab : query) {
+                String sql1 = "Select * from m_excel_tab where parent_id=" + excelTab.getId() + " and is_deleted=0";
+                List<ExcelTab> query1 = jdbcTemplate.query(sql1, new BeanPropertyRowMapper<>(ExcelTab.class));
+                for (ExcelTab tab : query1) {
+                    String sql2 = "Select * from m_excel_tab where parent_id=" + tab.getId() + " and is_deleted=0 and file_url is not null ";
+                    List<ExcelTab> query2 = jdbcTemplate.query(sql2, new BeanPropertyRowMapper<>(ExcelTab.class));
+                    for (ExcelTab excelTab1 : query2) {
+                        File html = new File(excelTab1.getHtmlUrl());
+                        if(!html.exists()){
+                            System.out.println(excelTab.getName() + "--" + tab.getName() + "--" + excelTab1.getName()+"html不存在 id:"+excelTab1.getId());
+                            if(excelTab1.getFileUrl() != null&&excelTab1.getFileUrl().endsWith(".xlsx") || excelTab1.getFileUrl().endsWith(".xls")){
+                                long resourceLength = CommonUtil.getResourceLength(excelTab1.getFileUrl());
+                                if(resourceLength>=500){
+                                    //先下载这个文件,再上传
+                                    String fileUrl = excelTab1.getFileUrl();
+                                    String localPath=excelPath+excelTab1.getId()+".xlsx";
+                                    InputStream inputStreamByUrl = FileUtils.getInputStreamByUrl(fileUrl);
+                                    FileUtils.saveFile(inputStreamByUrl,localPath);
+                                    File htmlFile = new File(localPath);
+                                    if(htmlFile.exists()){
+                                        try {
+                                            MultipartFile file = convert(htmlFile, excelTab1);
+                                            this.putFileAttach(file, excelTab1.getId());
+                                        }catch (Exception e){
+                                            e.printStackTrace();
+                                        }
+                                    }
+                                }else {
+                                    result.append(excelTab.getName() + "--" + tab.getName() + "--" + excelTab1.getName()+"\n");
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+        System.out.println("完成");
+        System.out.println(result);
+        System.out.println(result1);
+    }
+
+    public static MultipartFile convert(File file,ExcelTab e) throws IOException {
+        String contentType = Files.probeContentType(file.toPath());
+        byte[] content = Files.readAllBytes(file.toPath());
+        return new MockMultipartFile(
+            "file",
+            e.getName(),
+            contentType,
+            content
+        );
+    }
+    public R putFileAttach(@RequestParam("file") MultipartFile file, Long nodeId) throws Exception {
+        String file_path = FileUtils.getSysLocalFileUrl();
+        String sql="Select * from m_excel_tab where id="+nodeId+" and is_deleted=0";
+        ExcelTab detail = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<>(ExcelTab.class));
+        String filecode = SnowFlakeUtil.getId() + "";
+        String thmlUrl = file_path + filecode + ".html";
+        String exceUrl = file_path + filecode + "123.xlsx";
+        excelTabClient.excelInfo(file.getInputStream(), exceUrl, thmlUrl, "1");
+        // 上传excel文件
+        BladeFile bladeFile = newIOSSClient.uploadFile(file.getOriginalFilename(), exceUrl);
+        if (bladeFile == null || ObjectUtil.isEmpty(bladeFile)) {
+            return R.fail("oss上传失败,请校验oss配置是否正确");
+        }
+        // 解析原始excel
+        detail.setExtension(file.getOriginalFilename());
+        detail.setFileUrl(bladeFile.getLink());
+        detail.setFileType(3); // 表示为清表信息  1 表示祖节点  2 表示为节点信息 3 表示清表
+        detail.setHtmlUrl(thmlUrl);
+        excelTabClient.saveOrUpdate(detail);
+        // 解析html
+        excelTabClient.expailHtmlInfo(thmlUrl, detail.getId(), detail.getTabType() + "");
+        return R.success("上传成功");
+    }
+
+    /**
+     * 每周天晚上2点定时更新private和contract的html,通过is_private_type_id;
+     */
+    public void checkAndRepairPrivateAndContractHtml() {}
+}

+ 107 - 0
blade-service/blade-repair/src/main/java/org/springblade/repair/util/FileUtils.java

@@ -0,0 +1,107 @@
+package org.springblade.repair.util;
+
+import org.springblade.common.constant.CommonConstant;
+import org.springblade.common.utils.CommonUtil;
+import org.springblade.common.utils.SystemUtils;
+import org.springblade.system.cache.ParamCache;
+
+import java.io.*;
+
+public class FileUtils {
+    // 获取本地 或 远程工作流ParamCache
+    public static InputStream getInputStreamByUrl(String fileUrl) throws Exception {
+        File file1 = new File(fileUrl);
+        InputStream fileInputStream = null;
+        if (file1.exists()) {
+            fileInputStream = new FileInputStream(file1);
+        } else {
+            String path = getNetUrl(fileUrl);
+            fileInputStream = CommonUtil.getOSSInputStream(path);
+        }
+        return fileInputStream;
+    }
+
+    //根据流存储文件到本地
+    public static void saveFile(InputStream inputStream, String filePath) {
+
+        String localFilePath = filePath; // 本地文件路径
+
+        try (
+            FileOutputStream outputStream = new FileOutputStream(localFilePath)) {
+
+            byte[] buffer = new byte[1024];
+            int length;
+
+            while ((length = inputStream.read(buffer)) > 0) {
+                outputStream.write(buffer, 0, length);
+            }
+
+            System.out.println("文件下载成功,保存路径: " + localFilePath);
+
+        } catch (IOException e) {
+            e.printStackTrace();
+            System.err.println("文件下载失败: " + e.getMessage());
+        }
+
+    }
+
+    public static String getNetUrl(String fileUrl) {
+        String file_path = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
+        String file_path2 = getSysLocalFileUrl();
+        String sys_file_net_url = ParamCache.getValue(CommonConstant.SYS_FILE_NET_URL);
+        String sys_isonline = ParamCache.getValue(CommonConstant.SYS_ISONLINE);
+        if(fileUrl.indexOf("aliyuncs.com") >= 0 || fileUrl.indexOf("xinan1.zos.ctyun.cn")>=0 || fileUrl.indexOf("/mnt/sdc/Users/hongchuangyanfa/Desktop/")>=0){
+            if(fileUrl.indexOf("/mnt/sdc/Users/hongchuangyanfa/Desktop/")>=0){
+                if(SystemUtils.isWindows() || SystemUtils.isMacOs()){
+                    file_path2 = file_path;
+                }else{
+                    return sys_file_net_url + fileUrl.replaceAll("//", "/").replaceAll(file_path2, "");
+                }
+            }else{
+                return fileUrl;
+            }
+        } else {
+            if("20".equals(sys_isonline)){
+                file_path2 = file_path;
+            }
+        }
+        String s1 = fileUrl.replaceAll("//", "/").replace("///","/");
+        file_path2= file_path2.replaceAll("//","/").replaceAll("///","/");
+        String s2= s1.replaceAll(file_path2, "");
+        String path = sys_file_net_url + s2;
+        return path;
+    }
+    public static String getSysLocalFileUrl() {
+        String file_path = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
+        String sys_isonline = ParamCache.getValue(CommonConstant.SYS_ISONLINE);
+
+        if (sys_isonline.equals("1")) { //正式环境
+            if (SystemUtils.isMacOs()) {
+                file_path = "/Users/hongchuangyanfa/Desktop/";
+            } else if (SystemUtils.isWindows()) {
+                file_path = "C://upload//";
+            }
+        } else if (sys_isonline.equals("2")) { //109测试环境
+            if (SystemUtils.isMacOs()) {
+                file_path = "/www/wwwroot/Users/hongchuangyanfa/Desktop/";
+            } else if (SystemUtils.isWindows()) {
+                file_path = "C://upload//";
+            }
+        } else if (sys_isonline.equals("20")) { //183
+            if (SystemUtils.isLinux()) {
+                file_path = "/home/www/wwwroot/Users/hongchuangyanfa/Desktop/";
+            } else if (SystemUtils.isMacOs()) {
+                file_path = "/Users/hongchuangyanfa/Desktop/";
+            } else if (SystemUtils.isWindows()) {
+                file_path = "C://upload//";
+            }
+        } else {  //本地环境
+            if (SystemUtils.isMacOs()) {
+                file_path = "/Users/hongchuangyanfa/Desktop/";
+            } else if (SystemUtils.isWindows()) {
+                file_path = "C://upload//";
+            }
+        }
+        return file_path;
+    }
+}

+ 25 - 0
blade-service/blade-repair/src/main/resources/application-dev.yml

@@ -0,0 +1,25 @@
+#服务器端口
+server:
+  port: 9876
+
+#数据源配置
+spring:
+  datasource:
+    url: ${blade.datasource.dev.url}
+    username: ${blade.datasource.dev.username}
+    password: ${blade.datasource.dev.password}
+
+
+#oss:
+#  enabled: true
+#  name: alioss
+#  tenant-mode: true
+#  endpoint: https://oss-cn-chengdu.aliyuncs.com/
+#  access-key: LTAI4FmSV1pWZAJ9xSvHg5rP
+#  secret-key: 5D3XQj4pBe8VbOAVFNqdioJA8riH4S
+#  bucket-name: bladex-test-info
+
+#Mybatis-plus配置
+#mybatis-plus:
+#  configuration:
+#    cache-enabled: true

+ 11 - 0
blade-service/blade-repair/src/main/resources/application-prod.yml

@@ -0,0 +1,11 @@
+#服务器端口
+server:
+  port: 9876
+
+#数据源配置
+spring:
+  datasource:
+    url: ${blade.datasource.prod.url}
+    username: ${blade.datasource.prod.username}
+    password: ${blade.datasource.prod.password}
+

+ 10 - 0
blade-service/blade-repair/src/main/resources/application-test.yml

@@ -0,0 +1,10 @@
+#服务器端口
+server:
+  port: 9876
+
+#数据源配置
+spring:
+  datasource:
+    url: ${blade.datasource.test.url}
+    username: ${blade.datasource.test.username}
+    password: ${blade.datasource.test.password}

+ 2 - 2
blade-service/blade-user/src/main/java/org/springblade/system/user/controller/UserController.java

@@ -495,7 +495,7 @@ public class UserController {
         HttpClient httpClient = HttpClientBuilder.create().build();
         HttpGet httpPost = new HttpGet("http://user.hcxxy.com:8090/blade-auth/oauth/user-info");
         if("20".equals(sys_isonline)){
-            httpPost =new HttpGet("http://127.0.0.1:8090/blade-auth/oauth/user-info");
+            httpPost =new HttpGet("http://152.168.2.11:8090/blade-auth/oauth/user-info");
         }
 
         httpPost.setHeader("Authorization", token); //这个需要 client:
@@ -589,7 +589,7 @@ public class UserController {
         String url = "http://user.hcxxy.com:8090/blade-auth/oauth/token";
         String sys_isonline = ParamCache.getValue(CommonConstant.SYS_ISONLINE);
         if("20".equals(sys_isonline)){
-            url = "http://127.0.0.1:8090/blade-auth/oauth/token";
+            url = "http://152.168.2.11:8090/blade-auth/oauth/token";
         }
         HttpPost httpPost = new HttpPost(url);
         httpPost.setHeader("Authorization", Authorization);

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

@@ -175,17 +175,22 @@
                 iq.is_deleted = 0
             AND iq.classify = #{query.classify}
             AND iq.contract_id = #{query.contractId}
-
-                <if test="query.taskStatus != null and query.taskStatus != ''">
-                    <choose>
-                        <when test="query.taskStatus == 0">
-                            AND (iq.status = 0 OR iq.status = 3)
-                        </when>
-                        <otherwise>
-                            AND iq.status = #{query.taskStatus}
-                        </otherwise>
-                    </choose>
-                </if>
+                <choose>
+                    <when test="query.taskStatus != null and query.taskStatus != ''">
+<!--                        <choose>-->
+<!--                            <when test="query.taskStatus == 0">-->
+<!--                                AND (iq.status = 0 OR iq.status = 3)-->
+<!--                            </when>-->
+<!--                            <otherwise>-->
+<!--                                AND iq.status = #{query.taskStatus}-->
+<!--                            </otherwise>-->
+<!--                        </choose>-->
+                        AND iq.status = #{query.taskStatus}
+                    </when>
+                    <otherwise>
+                        AND iq.status != 3
+                    </otherwise>
+                </choose>
                 <if test="query.sourceType != null and query.sourceType != ''">
                     AND iq.source_type = #{query.sourceType}
                 </if>

+ 10 - 8
blade-service/blade-user/src/main/java/org/springblade/system/user/service/impl/UserServiceImpl.java

@@ -768,7 +768,7 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
 
                         /*获取当前合同段节点对应的资料填报QueryInfo本地缓存信息*/
                         List<WbsTreeContractLazyQueryInfoVO> queryInfoList = this.getQueryInfoList(contractId, tableOwner);
-                        Map<Long, Integer> queryInfoMaps = queryInfoList.stream().filter(f -> cn.hutool.core.util.ObjectUtil.isNotEmpty(f.getWbsId()))
+                        Map<Long, Integer> queryInfoMaps = queryInfoList.stream().filter(f -> Func.isNotEmpty(f.getWbsId())&&Func.isNotEmpty(f.getStatus()))
                                 .collect(Collectors.toMap(WbsTreeContractLazyQueryInfoVO::getWbsId, WbsTreeContractLazyQueryInfoVO::getStatus, (existingValue, newValue) -> existingValue));
                         List<Long> pKeyIdList = new ArrayList<>(queryInfoMaps.keySet());
 
@@ -1346,11 +1346,7 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
         do {
             offset = (pageNumber - 1) * pageSize;
             queryInfoListPage = jdbcTemplate.query(
-                    "SELECT wbs_id, status FROM u_information_query " +
-                            "WHERE type = 1 " +
-                            "AND contract_id = ? " +
-                            "AND classify = ? " +
-                            "LIMIT ? OFFSET ?",
+                    "SELECT wbs_id, `status` FROM u_information_query WHERE id in (SELECT id from (SELECT max(id) as id FROM u_information_query WHERE type = 1 AND contract_id = ? AND classify = ? GROUP BY wbs_id LIMIT ? offset ?) as a)",
                     new Object[]{contractId, tableOwner, pageSize, offset},
                     new BeanPropertyRowMapper<>(WbsTreeContractLazyQueryInfoVO.class));
             queryInfoList.addAll(queryInfoListPage);
@@ -1638,6 +1634,9 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
             Map<String, List<Task>> finalTaskMaps = taskMaps;
             Map<String, List<TaskParallel>> finalTaskParallelMaps = taskParallelMaps;
             voResult.forEach(vor -> {
+                if(vor.getId()==1838134135841955842L){
+                    System.out.println("111");
+                }
                 if (ObjectUtil.isNotEmpty(vor.getCreateTime())) {
                     vor.setStartTime(DateUtil.format(vor.getCreateTime(), "yyyy-MM-dd"));
                 }
@@ -1801,11 +1800,14 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
             List<Dept> depts = jdbcTemplate.query(sqlforSkipDept, new BeanPropertyRowMapper<>(Dept.class));
             String roleId = user.getRoleId();
             String deptId = user.getDeptId();
+            if(roleId==null||deptId==null){
+                return true;
+            }
             //既是超级管理员同时是泓创下面的部门才允许跳过填报人赋值
-            if(roleId.contains("1123598816738675201")){
+            if(roleId!=null&&roleId.contains("1123598816738675201")){
                 Boolean flag = false;
                 for (Dept dept : depts) {
-                    if(deptId.contains(dept.getId().toString())){
+                    if(deptId!=null&&deptId.contains(dept.getId().toString())){
                         flag = true;
                         return flag;
                     }

+ 1 - 0
pom.xml

@@ -40,6 +40,7 @@
         <module>blade-plugin-api</module>
         <module>blade-service</module>
         <module>blade-service-api</module>
+        <module>blade-service/blade-repair</module>
     </modules>
 
     <dependencyManagement>