Browse Source

Merge branch 'master' of http://39.108.216.210:3000/zhuwei/bladex

huangtf 7 months ago
parent
commit
6fad29e1ab
100 changed files with 5900 additions and 944 deletions
  1. 1 1
      blade-auth/src/main/java/org/springblade/auth/service/BladeUserDetailsServiceImpl.java
  2. 15 0
      blade-common/src/main/java/org/springblade/common/constant/MeasurementStorage.java
  3. 3 3
      blade-common/src/main/java/org/springblade/common/utils/AsyncConfigurer.java
  4. 25 0
      blade-common/src/main/java/org/springblade/common/utils/Colour.java
  5. 47 13
      blade-common/src/main/java/org/springblade/common/utils/CommonUtil.java
  6. 10 0
      blade-ops/blade-resource/pom.xml
  7. 2 1
      blade-ops/blade-resource/src/main/java/org/springblade/resource/builder/oss/OssBuilder.java
  8. 10 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/dto/TrialResignDto.java
  9. 4 3
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/TaskParallel.java
  10. 6 1
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/SaveContractLogVO.java
  11. 1 1
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/TaskApprovalVO.java
  12. 89 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/TaskSignInfoVO.java
  13. 3 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/UserVO.java
  14. 0 26
      blade-service-api/blade-e-visa-api/src/main/java/org/springblade/evisa/vo/SigInfoVO.java
  15. 50 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/FormEndPayDTO.java
  16. 36 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/ChapterEndPay.java
  17. 61 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/FormEndPay.java
  18. 7 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/WbsTreePrivate.java
  19. 2 2
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/feign/FormulaClient.java
  20. 5 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/feign/WbsTreePrivateClient.java
  21. 12 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/ExcelTabVo1.java
  22. 34 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/FormEndPayVO.java
  23. 2 1
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/ReportResult.java
  24. 6 0
      blade-service-api/blade-meter-api/src/main/java/org/springblade/meter/entity/InterimPayCertificate.java
  25. 5 1
      blade-service-api/blade-meter-api/src/main/java/org/springblade/meter/entity/MaterialStartStatement.java
  26. 24 0
      blade-service-api/blade-meter-api/src/main/java/org/springblade/meter/feign/CollectionUtilsClient.java
  27. 22 0
      blade-service-api/blade-meter-api/src/main/java/org/springblade/meter/feign/IContractInventoryFormClient.java
  28. 23 0
      blade-service-api/blade-meter-api/src/main/java/org/springblade/meter/feign/InterimPayCertificateItemClient.java
  29. 25 0
      blade-service-api/blade-meter-api/src/main/java/org/springblade/meter/feign/MiddleMeterApplyClient.java
  30. 3 0
      blade-service-api/blade-meter-api/src/main/java/org/springblade/meter/vo/MeterInventoryDetailVO.java
  31. 102 0
      blade-service-api/blade-meter-api/src/main/java/org/springblade/meter/vo/MeterInventoryVO1.java
  32. 49 0
      blade-service-api/blade-meter-api/src/main/java/org/springblade/meter/vo/MonthlyReportVo.java
  33. 7 1
      blade-service/blade-archive/pom.xml
  34. 11 4
      blade-service/blade-business/src/main/java/org/springblade/business/controller/ContractLogController.java
  35. 94 56
      blade-service/blade-business/src/main/java/org/springblade/business/controller/InformationWriteQueryController.java
  36. 305 0
      blade-service/blade-business/src/main/java/org/springblade/business/controller/TaskController.java
  37. 16 7
      blade-service/blade-business/src/main/java/org/springblade/business/controller/TrialSummaryController.java
  38. 3 2
      blade-service/blade-business/src/main/java/org/springblade/business/controller/TrialSummaryMonthlyController.java
  39. 60 2
      blade-service/blade-business/src/main/java/org/springblade/business/controller/UserViewProjectContractController.java
  40. 33 2
      blade-service/blade-business/src/main/java/org/springblade/business/feignClient/ContractLogClientImpl.java
  41. 9 1
      blade-service/blade-business/src/main/java/org/springblade/business/feignClient/MileageClientImpl.java
  42. 1 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/TaskParallelMapper.xml
  43. 7 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/ITaskService.java
  44. 10 8
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/InformationQueryServiceImpl.java
  45. 161 2
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TaskServiceImpl.java
  46. 100 29
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TrialSelfInspectionRecordServiceImpl.java
  47. 16 0
      blade-service/blade-e-visa/pom.xml
  48. 35 25
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/controller/EVController.java
  49. 3 10
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/controller/EVisaController.java
  50. 203 0
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/controller/EVisaController2.java
  51. 16 0
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/service/EVDataService.java
  52. 6 0
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/service/EVisaService.java
  53. 712 0
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/service/impl/EVDataServiceImpl.java
  54. 130 56
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/service/impl/EVisaServiceImpl.java
  55. 74 2
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/utils/FileUtils.java
  56. 95 34
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/utils/PDFUtils.java
  57. 424 0
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/utils/PdfAddimgUtil.java
  58. 228 0
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/utils/SignFtpUtil.java
  59. 0 76
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/utils/ThreadPoolDemo.java
  60. 16 2
      blade-service/blade-manager/src/main/java/com/mixsmart/utils/CustomFunction.java
  61. 3 0
      blade-service/blade-manager/src/main/java/com/mixsmart/utils/FormulaUtils.java
  62. 14 0
      blade-service/blade-manager/src/main/java/com/mixsmart/utils/StringUtils.java
  63. 112 163
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ExcelTabController.java
  64. 127 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/FormEndPayController.java
  65. 2 2
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/FormulaController.java
  66. 27 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ScheduledTasks.java
  67. 27 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ScheduledTasks1.java
  68. 9 11
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/SignPfxFileController.java
  69. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/WbsTreePrivateController.java
  70. 4 4
      blade-service/blade-manager/src/main/java/org/springblade/manager/feign/FormulaClientImpl.java
  71. 63 5
      blade-service/blade-manager/src/main/java/org/springblade/manager/feign/WbsTreePrivateClientImpl.java
  72. 2 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/formula/FormulaStrategy.java
  73. 1 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/formula/FormulaStrategyFactory.java
  74. 3 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/ExecutorCalc.java
  75. 142 6
      blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/ExecutorMeter.java
  76. 2 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/FormulaMileage.java
  77. 2 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/FormulaTurnPoint.java
  78. 12 2
      blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/FormulaZhiZuo.java
  79. 27 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/TableElementConverter.java
  80. 44 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/FormEndPayMapper.java
  81. 14 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/FormEndPayMapper.xml
  82. 1 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsTreeContractMapper.xml
  83. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsTreePrivateMapper.java
  84. 2 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsTreePrivateMapper.xml
  85. 3 2
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/IExcelTabService.java
  86. 46 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/IFormEndPayService.java
  87. 3 2
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/IFormulaService.java
  88. 2 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/IWbsTreePrivateService.java
  89. 152 111
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ExcelTabServiceImpl.java
  90. 52 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormEndPayServiceImpl.java
  91. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormulaDaoImpl.java
  92. 1218 16
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormulaServiceImpl.java
  93. 16 9
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/SignPfxFilePreServiceImpl.java
  94. 14 7
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/TrialSummaryClassificationConfigurationServiceImpl.java
  95. 4 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsParamServiceImpl.java
  96. 97 4
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeContractServiceImpl.java
  97. 68 6
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreePrivateServiceImpl.java
  98. 107 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/utils/AmountToChineseConverter.java
  99. 16 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/utils/CompositeKey1.java
  100. 0 213
      blade-service/blade-manager/src/main/java/org/springblade/manager/utils/CreateDashedLine.java

+ 1 - 1
blade-auth/src/main/java/org/springblade/auth/service/BladeUserDetailsServiceImpl.java

@@ -118,7 +118,7 @@ public class BladeUserDetailsServiceImpl implements UserDetailsService {
         } else if (userType.equals(UserEnum.MANAGER.getName())) {
             result = userClient.userInfo(tenantId, username, UserEnum.MANAGER.getName());  //后管
         } else if (userType.equals(UserEnum.HAC.getName())) {
-            result = userClient.userInfo(tenantId, username, UserEnum.HAC.getName());  //后管
+            result = userClient.userInfo(tenantId, username, UserEnum.HAC.getName());  //内控
         }
 
 

+ 15 - 0
blade-common/src/main/java/org/springblade/common/constant/MeasurementStorage.java

@@ -0,0 +1,15 @@
+package org.springblade.common.constant;
+
+/**
+ * 计量系统计算值存储redis KEY
+ */
+public interface MeasurementStorage {
+    //上期末扣取保留金
+    String PRE_END_RESERVE_MONEY = "preEndReserveMoney-";
+    //本期扣取保留金
+    String CUR_END_RESERVE_MONEY = "curEndReserveMoney-";
+    //本期末累计扣取保留金
+    String CUR_END_RESERVE_MONEY_SUM = "curEndReserveMoneySum-";
+    //本期计量
+    String CUR_MEASUREMENT = "curMeasurement-";
+}

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

@@ -15,7 +15,7 @@ public class AsyncConfigurer {
     /**
      * cpu 核心数量
      */
-    public static final int cpuNum = 10 ;//Runtime.getRuntime().availableProcessors();
+    public static final int cpuNum = 3 ;//Runtime.getRuntime().availableProcessors();
 
     /**
      * 线程池配置
@@ -24,8 +24,8 @@ public class AsyncConfigurer {
     @Bean("taskExecutor1")
     public ThreadPoolExecutor getAsyncExecutor() {
         return new ThreadPoolMonitor(cpuNum
-                , 15
-                , 30
+                , 5
+                , 180
                 , TimeUnit.SECONDS
                 , new LinkedBlockingQueue<>(2000)
                 , new ThreadPoolExecutor.DiscardOldestPolicy(), "manager-thread-pool");

+ 25 - 0
blade-common/src/main/java/org/springblade/common/utils/Colour.java

@@ -0,0 +1,25 @@
+package org.springblade.common.utils;
+
+import lombok.Data;
+
+public enum Colour {
+    RESET("\u001B[0m"),
+    BOLD("\u001B[1m"),
+    UNDERLINE("\u001B[4m"),
+    BLACK("\u001B[30m"),
+    RED("\u001B[31m"),
+    GREEN("\u001B[32m"),
+    YELLOW("\u001B[33m"),
+    BLUE("\u001B[34m"),
+    PURPLE("\u001B[35m"),
+    CYAN("\u001B[36m"),
+    WHITE("\u001B[37m");
+    private final String code;
+
+    Colour(String code) {
+        this.code = code;
+    }
+    public String getCode() {
+        return code;
+    }
+}

+ 47 - 13
blade-common/src/main/java/org/springblade/common/utils/CommonUtil.java

@@ -1,6 +1,7 @@
 package org.springblade.common.utils;
 
 import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.lang.func.Func;
 import cn.hutool.http.HttpUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
@@ -45,8 +46,8 @@ import org.springframework.util.ResourceUtils;
  *
  * @author Chill
  */
-public class CommonUtil {
 
+public class CommonUtil {
     public static Boolean checkBigDecimal(Object value) {
         try {
             if (value != null && StringUtils.isNotEmpty(value.toString())) {
@@ -111,6 +112,27 @@ public class CommonUtil {
         return pattern.matcher(value);
     }
 
+    /**
+     * 文件流转化为File
+     */
+    public static void convert(InputStream inputStream, String targetFile) throws IOException {
+        // 创建文件输出流
+        FileOutputStream outputStream = new FileOutputStream(targetFile);
+
+        // 创建缓冲区
+        byte[] buffer = new byte[1024];
+        int bytesRead;
+
+        // 从输入流读取数据并写入输出流
+        while ((bytesRead = inputStream.read(buffer)) != -1) {
+            outputStream.write(buffer, 0, bytesRead);
+        }
+
+        // 关闭流
+        outputStream.close();
+        inputStream.close();
+    }
+
     /**
      * 根据OSS文件路径获取文件输入流
      */
@@ -608,9 +630,9 @@ public class CommonUtil {
         String formatName = "JPEG";
         ByteArrayInputStream bais = new ByteArrayInputStream(imageData);
         BufferedImage originalImage = ImageIO.read(bais);
-        long sizeLimit = 102400; //358KB
-        int width = 1500;
-        int height = 400;
+        long sizeLimit = 512000; //358KB
+        int width = originalImage.getWidth() ;
+        int height = originalImage.getHeight();
         Image scaledImage = originalImage.getScaledInstance(width, height, Image.SCALE_SMOOTH);
         BufferedImage resizedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
         resizedImage.getGraphics().drawImage(scaledImage, 0, 0, null);
@@ -624,11 +646,28 @@ public class CommonUtil {
             return baos.toByteArray();
         }
 
-        float quality = 0.5f; // 初始化压缩质量
+        float quality = 0.7f; // 初始化压缩质量
         int retries = 10; // 最多尝试 10 次
 
         while (baos.size() > sizeLimit && retries > 0) {
             // 压缩图像并重新计算压缩质量
+            bais = new ByteArrayInputStream(imageData);
+            originalImage = ImageIO.read(bais);
+            float width2 = originalImage.getWidth() * quality;
+            float height2 = originalImage.getHeight() * quality;
+             scaledImage = originalImage.getScaledInstance(width, height, Image.SCALE_SMOOTH);
+             resizedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
+            resizedImage.getGraphics().drawImage(scaledImage, 0, 0, null);
+
+            // 压缩图像
+            baos = new ByteArrayOutputStream();
+            ImageIO.write(resizedImage, formatName, baos);
+
+            if (baos.size() <= sizeLimit) {
+                // 图片大小已经小于等于目标大小,直接返回原始数据
+                return baos.toByteArray();
+            }
+
             byte[] data = baos.toByteArray();
             bais = new ByteArrayInputStream(data);
             BufferedImage compressedImage = ImageIO.read(bais);
@@ -695,15 +734,10 @@ public class CommonUtil {
     }
 
     public static String replaceOssUrl(String url) {
-        String osName = System.getProperty("os.name");
-        if (osName != null && osName.toLowerCase().contains("Cloud Linux")) {
-            // 如果当前操作系统是Linux系统
-            Map<String, String> envMap = System.getenv();
-            if (!envMap.containsKey("linuxtesttest") && url.indexOf("-internal")<0) {
+      /*  if(url.indexOf("-internal")<0 && url.indexOf(".aliyuncs.com")>=0) {
                 // 如果当前环境变量不包含linuxtesttest,则替换URL中的oss路径
-                url = url.replace(".aliyuncs.com", "-internal.aliyuncs.com");
-            }
-        }
+            url = url.replace(".aliyuncs.com", "-internal.aliyuncs.com");
+        }*/
         //本地部署- 甬台温
         if (url.indexOf("183.247.216.148")>=0) {
             // 如果当前环境变量不包含linuxtesttest,则替换URL中的oss路径

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

@@ -121,6 +121,16 @@
             <artifactId>pdfbox</artifactId>
             <version>2.0.20</version>
         </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <scope>provided</scope>
+        </dependency>
 
     </dependencies>
 

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

@@ -85,7 +85,8 @@ public class OssBuilder {
         String tenantId = AuthUtil.getTenantId();
         Oss oss = getOss(tenantId, code);
         oss.setEndpoint("http://183.247.216.148:9000/");
-       //oss.setEndpoint("https://oss-cn-shenzhen.aliyuncs.com/");
+       // oss.setEndpoint("https://oss-cn-shenzhen.aliyuncs.com/");
+        System.out.println("3333333"+oss.getEndpoint());
         Oss ossCached = ossPool.get(tenantId);
         OssTemplateRe template = templatePool.get(tenantId);
         // 若为空或者不一致,则重新加载

+ 10 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/dto/TrialResignDto.java

@@ -0,0 +1,10 @@
+package org.springblade.business.dto;
+
+import lombok.Data;
+
+@Data
+public class TrialResignDto {
+    private String trialIds;
+    private Integer type;
+    private String projectId;
+}

+ 4 - 3
blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/TaskParallel.java

@@ -67,11 +67,12 @@ public class TaskParallel extends BaseEntity {
      */
     private String taskUserName;
 
-    /**
-     * 主动审批
-     */
+    @ApiModelProperty(value = "是否电签,2是,其他 否")
     private Integer initiative;
 
+    @ApiModelProperty(value = "是否是主动审批,1是,0否")
+    private Integer exeCount;
+
     /**
      * 排序
      */

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

@@ -34,8 +34,12 @@ public class SaveContractLogVO {
     private List<JSONObject> correlationIds;
     @ApiModelProperty("源数据的日志id")
     private  String oldDataId;
+    //这里只是为了解决事务导致的表锁 把这个参数传到保存日志关联工序信息的地方去删除
+    @ApiModelProperty("对应实体表的数据id = businessIds")
+    private  String businessIds;
 
-    public SaveContractLogVO(String businessId, String projectId, String contractId, Long wbsNodeId, Long tableId, Integer wbsNodeType, String recordTime, List<JSONObject> correlationIds, String oldDataId) {
+
+    public SaveContractLogVO(String businessId, String projectId, String contractId, Long wbsNodeId, Long tableId, Integer wbsNodeType, String recordTime, List<JSONObject> correlationIds, String oldDataId,String businessIds) {
         this.dataId = businessId;
         this.projectId = Long.parseLong(projectId);
         this.contractId = Long.parseLong(contractId);
@@ -45,6 +49,7 @@ public class SaveContractLogVO {
         this.recordTime = recordTime;
         this.correlationIds = correlationIds;
         this.oldDataId = oldDataId;
+        this.businessIds = businessIds;
     }
 
     public SaveContractLogVO() {

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

@@ -26,7 +26,7 @@ public class TaskApprovalVO {
     @ApiModelProperty("数据源")
     private String formDataId;
 
-    // 1=填报数据(质量填报,试验上报) 2=工程文件 3=日志资料 4=档案数据   5=计量支付证书  6=计量 材料  7= 计量 中间支付  8委托单
+    // 1=填报数据(质量填报,试验上报) 2=工程文件 3=日志资料 4=档案数据   5=计量支付证书  6=计量 材料预付款  7= 计量 中间支付  8委托单
     @ApiModelProperty("上报类型")
     private Integer approvalType;
 

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

@@ -0,0 +1,89 @@
+package org.springblade.business.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Data
+public class TaskSignInfoVO {
+
+    @ApiModelProperty("id")
+    private String id;
+    /**
+     * 待审批列表中(TaskVO)对应的taskId字段值
+     */
+    @ApiModelProperty("待审批列表中对应的taskId字段值")
+    private String taskId;
+
+    /**
+     * parallelProcessInstanceId字段值
+     */
+    @ApiModelProperty("待审批列表中对应的parallelProcessInstanceId字段值")
+    private String parallelProcessInstanceId;
+
+    @ApiModelProperty("数据源")
+    private String formDataId;
+
+    // 1=填报数据(质量填报,试验上报) 2=工程文件 3=日志资料 4=档案数据   5=计量支付证书  6=计量 材料预付款  7= 计量 中间支付  8委托单
+    @ApiModelProperty("上报类型")
+    private Integer approvalType;
+
+    @ApiModelProperty("同意传OK(大写)")
+    private String flag;
+
+    @ApiModelProperty("同意传OK(大写)")
+    private String comment;
+
+    @ApiModelProperty("用户ID")
+    private Long userId;
+
+    @ApiModelProperty("签字人名")
+    private String nickName;
+
+    @ApiModelProperty("电签类型")
+    private String remarkType;
+
+    @ApiModelProperty("项目Id")
+    private String projectId;
+
+    @ApiModelProperty("合同段Id")
+    private String contractId;
+
+    @ApiModelProperty("签字文件")
+    private String signPdfUrl;
+
+    @ApiModelProperty("电签格式")
+    private String signFormat;
+
+    @ApiModelProperty("pdf上的时间")
+    private String pdfDate;
+
+    @ApiModelProperty("数据类型")
+    private String pdfDataType;
+
+    /**
+     * 获取是否通过
+     */
+    public boolean isPass() {
+        return "OK".equals(flag) || "同意".equals(comment);
+    }
+
+    /**
+     * 电签中的对象数据
+     */
+
+    @ApiModelProperty("电签后的PDf")
+    private String lastFilePdfUrl;
+
+    @ApiModelProperty("电签内型 1:个人签字 2:签章")
+    private Integer sigType;
+
+    @ApiModelProperty("电签状态 1:成功 2:失败")
+    private Integer sigState;
+
+    @ApiModelProperty("电签内容")
+    private String signSmg;
+
+}

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

@@ -91,4 +91,7 @@ public class UserVO {
     @ApiModelProperty(value = "签名url")
     private String signatureUrl;
 
+    private Double wide;
+    private Double high;
+
 }

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

@@ -1,26 +0,0 @@
-package org.springblade.evisa.vo;
-
-import lombok.Data;
-
-import java.util.List;
-
-/**
- * @Param   批量电签传参- userSig是自定义的签字编号,code和password是账号密码
- * @Author wangwl
- * @Date 2024/1/18 17:21
- **/
-@Data
-public class SigInfoVO {
-
-    private String pdfUrl;
-    private List<SigInfo> list;
-
-    @Data
-    public static class SigInfo{
-        private String userName;
-        private String userSig;
-        private String sigPic;
-        private String sealCode;
-        private String sealPassword;
-    }
-}

+ 50 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/FormEndPayDTO.java

@@ -0,0 +1,50 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.manager.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.NoArgsConstructor;
+import org.springblade.manager.entity.FormEndPay;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 数据传输对象实体类
+ *
+ * @author BladeX
+ * @since 2024-12-02
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AllArgsConstructor
+@NoArgsConstructor
+public class FormEndPayDTO extends FormEndPay {
+	private static final long serialVersionUID = 1L;
+    /**
+     * 计量期数ID
+     */
+    private Long periodId;
+    /**
+     * 计量合同ID
+     */
+    private Long contractId;
+    /**
+     * 计量项目ID
+     */
+    private Long projectId;
+
+}

+ 36 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/ChapterEndPay.java

@@ -0,0 +1,36 @@
+package org.springblade.manager.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.math.BigDecimal;
+
+@Data
+@TableName("s_meter_chapter_end_pay")
+public class ChapterEndPay {
+
+    private static final long serialVersionUID = 1L;
+    private Long id;
+    /**
+     * 项目ID
+     */
+    private Long projectId;
+    /**
+     * 期数ID
+     */
+    private Long periodId;
+
+    /**
+     * 合同段ID
+     */
+    private Long contractId;
+    /**
+     * 清单编号
+     */
+    private String formNumber;
+    /**
+     * 到本期末完成金额
+     */
+    private BigDecimal currentPeriodEndPay;
+}

+ 61 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/FormEndPay.java

@@ -0,0 +1,61 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.manager.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import java.io.Serializable;
+import java.math.BigDecimal;
+import org.springblade.core.mp.base.BaseEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 实体类
+ *分项支付清单到本期末支付
+ * @author BladeX
+ * @since 2024-12-02
+ */
+@Data
+@TableName("s_meter_form_end_pay")
+@EqualsAndHashCode(callSuper = true)
+public class FormEndPay extends BaseEntity {
+
+	private static final long serialVersionUID = 1L;
+	/**
+	 * 项目ID
+	 */
+	private Long projectId;
+	/**
+	 * 期数ID
+	 */
+	private Long periodId;
+
+	/**
+	 * 合同段ID
+	 */
+	private Long contractId;
+	/**
+	 * 清单编号
+	 */
+	private String formNumber;
+	/**
+	 * 到本期末完成金额
+	 */
+	private BigDecimal currentPeriodEndPay;
+
+
+}

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

@@ -23,6 +23,13 @@ public class WbsTreePrivate extends BaseEntity {
     @JsonProperty(value = "pKeyId")
     private Long pKeyId;
 
+    @ApiModelProperty(value = "pid")
+    private Long pId;
+
+    //m_wbs_tree 的主键Id
+    @JsonProperty(value = "treePId")
+    private Long treePId;
+
     /**
      * 项目Id
      */

+ 2 - 2
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/feign/FormulaClient.java

@@ -34,9 +34,9 @@ public interface FormulaClient {
 
     //计量公式执行体
     @PostMapping(API_PREFIX + "execute3")
-    List<ReportResult> formulaExecute3(@RequestParam Long contractId, @RequestParam Long periodId,@RequestParam Integer type);
+    List<ReportResult> formulaExecute3(@RequestParam Long contractId, @RequestParam Long periodId,@RequestParam Integer type,@RequestParam Long perIodId1,@RequestParam Long projectId);
 
     //万盛计量专用
     @PostMapping(API_PREFIX + "execute4")
-    List<ReportResult> formulaExecute4(@RequestParam Long contractId, @RequestParam Long periodId,@RequestParam Integer type);
+    List<ReportResult> formulaExecute4(@RequestParam Long reportId,@RequestParam Long contractId, @RequestParam Long periodId,@RequestParam Integer type,@RequestParam Long projectId) throws FileNotFoundException, IllegalAccessException;
 }

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

@@ -6,6 +6,7 @@ import org.springblade.manager.entity.WbsTreeContract;
 import org.springblade.manager.entity.WbsTreePrivate;
 import org.springblade.manager.vo.WbsTreeContractTreeVOS;
 import org.springblade.manager.vo.WbsTreePrivateVO;
+import org.springblade.manager.vo.WbsTreePrivateVO4;
 import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PostMapping;
@@ -80,4 +81,8 @@ public interface WbsTreePrivateClient {
     @GetMapping(API_PREFIX + "/getProjectOpinionNode")
     R<WbsTreePrivate> getProjectOpinionNode(@RequestParam Long projectId);
 
+
+    @GetMapping("/search-node-tables")
+     R<List<WbsTreePrivateVO4>> searchNodeAllTable(@RequestParam String primaryKeyId,@RequestParam String type,@RequestParam String tableType, @RequestParam String contractId,@RequestParam String projectId,@RequestParam Integer isAdd,@RequestParam Long id) ;
+
 }

+ 12 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/ExcelTabVo1.java

@@ -0,0 +1,12 @@
+package org.springblade.manager.vo;
+
+import lombok.Data;
+
+@Data
+public class ExcelTabVo1 {
+    private Long pKeyId;
+    private String id;
+    private String htmlUrl;
+    private String name;
+    private String fileUrl;
+}

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

@@ -0,0 +1,34 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.manager.vo;
+
+import org.springblade.manager.entity.FormEndPay;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 视图实体类
+ *
+ * @author BladeX
+ * @since 2024-12-02
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class FormEndPayVO extends FormEndPay {
+	private static final long serialVersionUID = 1L;
+
+}

+ 2 - 1
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/ReportResult.java

@@ -3,7 +3,6 @@ package org.springblade.manager.vo;
 import lombok.Data;
 import org.apache.poi.ss.usermodel.*;
 import org.apache.poi.ss.util.CellRangeAddress;
-import org.springblade.common.utils.SnowFlakeUtil;
 import org.springblade.core.tool.utils.Func;
 import org.springblade.core.tool.utils.StringPool;
 
@@ -51,6 +50,8 @@ public class ReportResult {
     private String deleteRow;
     /**模板类型*/
     private Integer modelType=MeterInfo.MB_GX;
+    /**pdfOssPath字段String类型*/
+    private String ossPdfUrl;
 
     public String getPdfPath(){
         return this.pdfPath;

+ 6 - 0
blade-service-api/blade-meter-api/src/main/java/org/springblade/meter/entity/InterimPayCertificate.java

@@ -125,6 +125,12 @@ InterimPayCertificate extends BaseEntity {
     @ApiModelProperty(value = "原始PDF地址")
     private String rawUrl;
 
+    /**
+     * 电签前-预览pdf
+     */
+    @ApiModelProperty(value = "电签前-预览pdf")
+    private String prePdfUrl;
+
     /**
      * 每份表格独立的PDF地址
      */

+ 5 - 1
blade-service-api/blade-meter-api/src/main/java/org/springblade/meter/entity/MaterialStartStatement.java

@@ -102,6 +102,10 @@ public class MaterialStartStatement extends BaseEntity {
 
     @ApiModelProperty(value = "pdfUrl")
     private String rawUrl;
-
+    /**
+     * 电签前-预览pdf
+     */
+    @ApiModelProperty(value = "电签前-预览pdf")
+    private String prePdfUrl;
 
 }

+ 24 - 0
blade-service-api/blade-meter-api/src/main/java/org/springblade/meter/feign/CollectionUtilsClient.java

@@ -0,0 +1,24 @@
+package org.springblade.meter.feign;
+
+import org.springblade.common.constant.LauncherConstant;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import java.util.List;
+
+@FeignClient(value = LauncherConstant.APPLICATION_METER_NAME)
+public interface CollectionUtilsClient {
+     /**
+     * 接口前缀
+     */
+    String API_PREFIX = "/CertificateItem";
+
+    /**
+     * 保存中期证书项目详情
+     */
+    @PostMapping(API_PREFIX + "/mergePdfPublicMethods")
+    public void mergePdfPublicMethods(@RequestBody List<String> urlList, @RequestParam String localImgUrl);
+
+}

+ 22 - 0
blade-service-api/blade-meter-api/src/main/java/org/springblade/meter/feign/IContractInventoryFormClient.java

@@ -0,0 +1,22 @@
+package org.springblade.meter.feign;
+
+import org.springblade.common.constant.LauncherConstant;
+import org.springblade.meter.vo.InventoryFormDetailVO;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+@FeignClient(value = LauncherConstant.APPLICATION_METER_NAME)
+public interface IContractInventoryFormClient {
+      /**
+     * 接口前缀
+     */
+    String API_PREFIX = "/ContractInventoryForm";
+
+     /**
+     * 保存中期证书项目详情
+     */
+    @PostMapping(API_PREFIX + "/detail")
+    InventoryFormDetailVO detail(@RequestParam Long id);
+
+}

+ 23 - 0
blade-service-api/blade-meter-api/src/main/java/org/springblade/meter/feign/InterimPayCertificateItemClient.java

@@ -0,0 +1,23 @@
+package org.springblade.meter.feign;
+
+import org.springblade.common.constant.LauncherConstant;
+import org.springblade.meter.entity.InterimPayCertificateItem;
+import org.springblade.meter.vo.MonthlyReportVo;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import java.util.List;
+
+@FeignClient(value = LauncherConstant.APPLICATION_METER_NAME)
+public interface InterimPayCertificateItemClient {
+
+    String API_PREFIX = "/InterimPayCertificateItem";
+
+    @PostMapping("/addInterimPayCertificateItem")
+    void addInterimPayCertificateItem(@RequestParam Long certificateId, @RequestBody List<MonthlyReportVo> values);
+
+    @PostMapping("/updateInterimPayCertificateItem")
+    void updateInterimPayCertificateItem(@RequestBody List<InterimPayCertificateItem> list4);
+}

+ 25 - 0
blade-service-api/blade-meter-api/src/main/java/org/springblade/meter/feign/MiddleMeterApplyClient.java

@@ -0,0 +1,25 @@
+package org.springblade.meter.feign;
+
+import org.springblade.common.constant.LauncherConstant;
+import org.springblade.meter.entity.MiddleMeterApply;
+import org.springblade.meter.vo.MeterInventoryDetailVO;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+
+import java.util.List;
+
+@FeignClient(value = LauncherConstant.APPLICATION_METER_NAME)
+public interface MiddleMeterApplyClient {
+    /**
+     * 接口前缀
+     */
+    String API_PREFIX = "/MiddleMeterApply";
+
+    /**
+     * 保存中期证书项目详情
+     */
+    @PostMapping(API_PREFIX + "/formDetail")
+    List<MeterInventoryDetailVO> formDetail(@RequestBody MiddleMeterApply middleMeterApply);
+
+}

+ 3 - 0
blade-service-api/blade-meter-api/src/main/java/org/springblade/meter/vo/MeterInventoryDetailVO.java

@@ -39,6 +39,9 @@ public class MeterInventoryDetailVO {
     @ApiModelProperty(value = "清单名称")
     private String formName;
 
+    @ApiModelProperty(value = "单位")
+    private String unit;
+
     @ApiModelProperty(value = "单价")
     private BigDecimal currentPrice;
 

+ 102 - 0
blade-service-api/blade-meter-api/src/main/java/org/springblade/meter/vo/MeterInventoryVO1.java

@@ -0,0 +1,102 @@
+package org.springblade.meter.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * 清单支付报表对象
+ */
+@Data
+public class MeterInventoryVO1 {
+    @ApiModelProperty(value = "id")
+    private Long id;
+
+    @ApiModelProperty(value = "清单编号")
+    private String formNumber;
+
+    @ApiModelProperty(value = "清单名称")
+    private String formName;
+
+    @ApiModelProperty(value = "单位")
+    private String unit;
+
+    @ApiModelProperty(value = "原合同工程量")
+    private BigDecimal currentMeterTotal;
+
+    @ApiModelProperty(value = "原合同单价")
+    private BigDecimal currentMeterPrice;
+
+    @ApiModelProperty(value = "原合同金额")
+    private BigDecimal currentMeterMoney;
+
+    @ApiModelProperty(value = "工程变更工程量")
+    private BigDecimal changeTotal;
+
+    @ApiModelProperty(value = "工程变更单价")
+    private BigDecimal changeMeterPrice;
+
+    @ApiModelProperty(value = "工程变更金额")
+    private BigDecimal changeMeterMoney;
+
+    @ApiModelProperty(value = "变更后合同工程量")
+    private BigDecimal afterCurrentTotal;
+
+    @ApiModelProperty(value = "变更后合同金额")
+    private BigDecimal afterCurrentMeterMoney;
+
+    @ApiModelProperty(value = "到上期末完成工程量")
+    private BigDecimal beforeEndTotal;
+
+    @ApiModelProperty(value = "到上期末完成金额")
+    private BigDecimal beforeEndMoney;
+
+    @ApiModelProperty(value = "本期完成工程量")
+    private BigDecimal nowTotal;
+
+    @ApiModelProperty(value = "本期完成金额")
+    private BigDecimal nowMoney;
+
+    @ApiModelProperty(value = "到本期末完成工程量")
+    private BigDecimal nowEndTotal;
+
+    @ApiModelProperty(value = "到本期末完成金额")
+    private BigDecimal nowEndMoney;
+
+    @ApiModelProperty(value = "排序")
+    private Integer sort;
+
+    @ApiModelProperty(value = "导入编号")
+    private String importNumber;
+
+
+   public static int getFirstThreeCharsAsInt(MeterInventoryVO1 vo1) {
+       String name = vo1.getFormNumber();
+        if (!name.isEmpty() && name.length() < 3 ) {
+            String num1 = name.substring(0, 1);
+            if(isNumeric(num1)){
+                return Integer.parseInt(num1);
+            }
+        }
+       if (!name.isEmpty() && name.length() >3) {
+           String num2 = name.substring(0, 3);
+           if(isNumeric(num2)){
+               return Integer.parseInt(num2);
+           }
+       }
+       return 0;
+    }
+    private static boolean isNumeric(String str) {
+        if (str == null || str.length() == 0) {
+            return false;
+        }
+        for (char c : str.toCharArray()) {
+            if (!Character.isDigit(c)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+}

+ 49 - 0
blade-service-api/blade-meter-api/src/main/java/org/springblade/meter/vo/MonthlyReportVo.java

@@ -0,0 +1,49 @@
+package org.springblade.meter.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+public class MonthlyReportVo {
+
+    @ApiModelProperty(value = "清单编号")
+    private String formNumber;
+
+     @ApiModelProperty(value = "项目内容")
+    private String formName;
+
+     @ApiModelProperty(value = "原合同总金额")
+    private BigDecimal currentMeterMoney;
+
+     @ApiModelProperty(value = "工程变更总金额")
+    private BigDecimal changeMeterMoney;
+
+     @ApiModelProperty(value = "变更后合同总金额")
+    private BigDecimal afterCurrentMeterMoney;
+
+      @ApiModelProperty(value = "到上期末完成金额")
+    private BigDecimal beforeEndMoney;
+
+      @ApiModelProperty(value = "到上期末占C的%")
+    private String beforeEndC;
+
+      @ApiModelProperty(value = "本期完成金额")
+    private BigDecimal nowMoney;
+
+      @ApiModelProperty(value = "本期占C的%")
+    private String nowC;
+
+      @ApiModelProperty(value = "到本期末完成金额")
+     private BigDecimal nowEndMoney;
+
+       @ApiModelProperty(value = "到本期末完成占C的%")
+      private String nowEndC;
+
+       @ApiModelProperty(value = "章编号")
+       private String chapterSeq;
+
+
+
+}

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

@@ -35,6 +35,12 @@
 <!--            <version>2.13.1</version>-->
 <!--        </dependency>-->
         <!--sqlite-->
+
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpclient</artifactId>
+            <version>4.5.13</version>
+        </dependency>
         <dependency>
             <groupId>org.xerial</groupId>
             <artifactId>sqlite-jdbc</artifactId>
@@ -166,7 +172,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>

+ 11 - 4
blade-service/blade-business/src/main/java/org/springblade/business/controller/ContractLogController.java

@@ -11,6 +11,7 @@ import io.swagger.annotations.ApiImplicitParam;
 import io.swagger.annotations.ApiImplicitParams;
 import io.swagger.annotations.ApiOperation;
 import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang.StringUtils;
 import org.springblade.business.entity.*;
 import org.springblade.business.feign.MessageWarningClient;
@@ -42,6 +43,7 @@ import org.springblade.system.cache.ParamCache;
 import org.springframework.beans.BeanUtils;
 import org.springframework.jdbc.core.BeanPropertyRowMapper;
 import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.bind.annotation.*;
 
 import java.io.IOException;
@@ -54,6 +56,7 @@ import java.util.stream.Collectors;
  * @author BladeX
  * @since 2022-06-15
  */
+@Slf4j
 @RestController
 @AllArgsConstructor
 @RequestMapping("/contractLog")
@@ -113,12 +116,13 @@ public class ContractLogController extends BladeController {
     }
 
     /**
-     * 删除日志
+     *
      */
     @PostMapping("/removeByIds")
     @ApiOperationSupport(order = 12)
     @ApiOperation(value = "删除日志")
     @ApiImplicitParam(name = "ids", value = "删除的数据ID", required = true)
+    @Transactional
     public R<Boolean> removeByIds(@RequestBody JSONObject json) {
         if (json.containsKey("ids")) {
             Object ids = json.get("ids");
@@ -150,13 +154,16 @@ public class ContractLogController extends BladeController {
 
                 for (ContractLog log : contractLogList) {
                     //删除施工日志记录信息
-                    jdbcTemplate.execute("delete from u_contract_log where data_id = " + log.getDataId());
+                    jdbcTemplate.execute("delete from u_contract_log where data_id = '" + log.getDataId()+"'");
                     //删除关联的工序wbs信息
-                    jdbcTemplate.execute("delete from u_contract_log_wbs where business_id = " + log.getDataId() + " and contract_log_id = " + log.getId());
+                    jdbcTemplate.execute("delete from u_contract_log_wbs where contract_log_id = " + log.getId());
 
                     if (tableTemp != null && StringUtils.isNotEmpty(tableTemp.getInitTableName())) {
                         //删除实体表对应的数据信息
-                        jdbcTemplate.execute("delete from " + tableTemp.getInitTableName() + " where id = " + log.getDataId());
+                        String[] split = log.getDataId().split(",");
+                        for (String dataId : split) {
+                            jdbcTemplate.execute("delete from " + tableTemp.getInitTableName() + " where id = " + dataId);
+                        }
                     }
                 }
             }

+ 94 - 56
blade-service/blade-business/src/main/java/org/springblade/business/controller/InformationWriteQueryController.java

@@ -1246,16 +1246,10 @@ public class InformationWriteQueryController extends BladeController {
                 }
 
                 //修改试验任务状态为未上报
-                String sql;
-                if (StringUtils.isNotEmpty(primaryKeyId)) {
-                    //单个废除
-                    sql = "update u_trial_self_inspection_record set task_status = '已废除' where id = " + primaryKeyId;
-                } else {
-                    //批量废除直接调的该接口,primaryKeyId为null,ids=当前试验记录的ids
-                    sql = "update u_trial_self_inspection_record set task_status = '已废除' where id in(" + ids + ")";
-                }
-                jdbcTemplate.execute(sql);
 
+                //批量废除直接调的该接口,primaryKeyId为null,ids=当前试验记录的ids
+                 String sql = "update u_trial_self_inspection_record set task_status = '已废除' where id in(" + ids + ")";
+                jdbcTemplate.execute(sql);
                 return R.data(200, aopParamsSet, "废除成功");
 
             } catch (Exception e) {
@@ -1508,8 +1502,8 @@ public class InformationWriteQueryController extends BladeController {
                 Map<Long, Long> oldToNewIdMap = new HashMap<>();
                 Map<String, WbsTreeContract> nodeMap = new HashMap<>();
                 nodeChildAll.forEach(node -> {
-                    oldToNewIdMap.put(node.getId(), SnowFlakeUtil.getId());
-                    nodeMap.put(node.getId().toString(), node);
+                    oldToNewIdMap.put(node.getPKeyId(), SnowFlakeUtil.getId());
+                    nodeMap.put(node.getPKeyId().toString(), node);
                 });
 
                 /*获取元素表数据*/
@@ -1562,7 +1556,9 @@ public class InformationWriteQueryController extends BladeController {
                     WbsTreeContract newData = new WbsTreeContract();
                     BeanUtils.copyProperties(nodeOld, newData);
 
-                    newData.setPKeyId(SnowFlakeUtil.getId());
+                    newData.setPKeyId(oldToNewIdMap.get(nodeOld.getPKeyId()));
+                    newData.setId(newData.getPKeyId());
+
                     if (nodeOld.getNodeType() != null && nodeOld.getNodeType() == 6) {
                         peerMap.put(newData.getPKeyId(), nodeOld.getPKeyId());
                     }
@@ -1572,17 +1568,20 @@ public class InformationWriteQueryController extends BladeController {
                     } else {
                         newData.setOldId(nodeOld.getId().toString());
                     }
-
                     if (new Integer("1").equals(nodeOld.getType())) {
-                        newData.setId(oldToNewIdMap.containsKey(nodeOld.getId()) ? oldToNewIdMap.get(nodeOld.getId()) : SnowFlakeUtil.getId());
+                       // newData.setId(oldToNewIdMap.containsKey(nodeOld.getPKeyId()) ? oldToNewIdMap.get(nodeOld.getPKeyId()) : SnowFlakeUtil.getId());
                         newData.setPartitionCode(StringUtils.isNotEmpty(vo.getPartitionCode()) ? vo.getPartitionCode() : null);
                     }
+                    //如果被复制的是节点,parendID等于父节点的PkeyID
                     if (vo.getNeedCopyPrimaryKeyId().equals(nodeOld.getPKeyId().toString())) {
-                        newData.setParentId(parent.getId());
+                        newData.setParentId(parent.getPKeyId());
+                        newData.setPId(parent.getPKeyId());
                         newData.setNodeName(vo.getNeedCopyNodeName());
                         newData.setFullName(vo.getNeedCopyNodeName());
                     } else {
-                        newData.setParentId(oldToNewIdMap.containsKey(nodeOld.getParentId()) ? oldToNewIdMap.get(nodeOld.getParentId()) : SnowFlakeUtil.getId());
+                        //如果是复制的表格,parentID 他父节点的pkeyId
+                        newData.setParentId(oldToNewIdMap.containsKey(nodeOld.getPId()) ? oldToNewIdMap.get(nodeOld.getPId()) : SnowFlakeUtil.getId());
+                        newData.setPId(oldToNewIdMap.containsKey(nodeOld.getPId()) ? oldToNewIdMap.get(nodeOld.getPId()) : SnowFlakeUtil.getId());
                     }
                     newData.setCreateTime(new Date());
                     newData.setUpdateTime(new Date());
@@ -1591,9 +1590,7 @@ public class InformationWriteQueryController extends BladeController {
                     newData.setPdfUrl(null);
                     newData.setCreateUser(AuthUtil.getUserId());
                     newData.setSort(ObjectUtil.isNotEmpty(nodeOld.getSort()) ? nodeOld.getSort() : 0);
-
                     this.restoreParent(newData, oldToNewIdMap);
-
                     saveList.add(newData);
 
                     /*生成工序节点施工日志*/
@@ -1769,6 +1766,7 @@ public class InformationWriteQueryController extends BladeController {
 
                                     boolean var = false;
                                     //2.1 选择的父级的同级的父级节点,新增(当复制节点父级与选择复制到的位置节点的父级id相同时,表示跨节点新增)
+
                                     if (parentNodeNeed != null) {
                                         //2.1.1 如果是跨一级的情况下:parentNodeNeed.getParentId() == toCopyNode.getParentId() ,且 parentNodeNeed.getAncestors() == toCopyNode.getAncestors() ,且节点类型必须一样
                                         if (parentNodeNeed.getParentId().equals(toCopyNode.getParentId()) && parentNodeNeed.getAncestors().equals(toCopyNode.getAncestors()) && parentNodeNeed.getNodeType().equals(toCopyNode.getNodeType())) {
@@ -1794,6 +1792,18 @@ public class InformationWriteQueryController extends BladeController {
 
                                             this.addCopyNodesAndTabsBuildData(addNodeList, addTabList, needCopyNodes, needCopyTab, needCopyNode, toCopyNode, resultTablesData, 0, tabOwner, vo.getIsCopyData(), peerMap);
 
+                                            addNewFileTabs.addAll(addTabList);
+                                            var = true;
+                                        }else if(parentNodeNeed.getParentId().equals(toCopyNode.getParentId()) && !parentNodeNeed.getAncestors().equals(toCopyNode.getAncestors())&& parentNodeNeed.getNodeType().equals(toCopyNode.getNodeType())){
+                                            //2.1.2 如果一级的情况下父级id相同 parentNodeNeed.getParentId() != toCopyNode.getParentId() ,且 parentNodeNeed.getAncestors() != toCopyNode.getAncestors() ,且节点类型必须一样
+                                            toCopyNode.setNodeName(toCopyVO.getNodeName());
+                                            toCopyNode.setPartitionCode(toCopyVO.getPartitionCode());
+
+                                            List<WbsTreeContract> needCopyNodes = needCopyNodeAndTabMap.get("node:" + needCopyNodeRoot.getPKeyId());
+                                            List<WbsTreeContract> needCopyTab = needCopyNodeAndTabMap.get("tab:" + needCopyNodeRoot.getPKeyId());
+
+                                            this.addCopyNodesAndTabsBuildData(addNodeList, addTabList, needCopyNodes, needCopyTab, needCopyNode, toCopyNode, resultTablesData, 0, tabOwner, vo.getIsCopyData(), peerMap);
+
                                             addNewFileTabs.addAll(addTabList);
                                             var = true;
                                         }
@@ -2070,15 +2080,15 @@ public class InformationWriteQueryController extends BladeController {
 
         Map<Long, WbsTreeContract> newMap = BeanUtil.copyProperties(result, WbsTreeContract.class).stream().collect(Collectors.toMap(WbsTreeContract::getId, Function.identity()));
         for (WbsTreeContract obj : sortedResult) {
-            if (obj != null && ObjectUtil.isNotEmpty(obj.getParentId())) {
+            if (obj != null && ObjectUtil.isNotEmpty(obj.getPId())) {
                 if (newMap.size() > 0) {
-                    WbsTreeContract parentObj = newMap.get(obj.getParentId());
-                    if (parentObj != null && ObjectUtil.isNotEmpty(obj.getAncestors()) && ObjectUtil.isNotEmpty(obj.getParentId()) && !obj.getAncestors().contains(obj.getParentId().toString())) {
+                    WbsTreeContract parentObj = newMap.get(obj.getPId());
+                    if (parentObj != null && ObjectUtil.isNotEmpty(obj.getAncestors()) && ObjectUtil.isNotEmpty(obj.getPId()) && !obj.getAncestors().contains(obj.getPId().toString())) {
                         String parentAncestors = parentObj.getAncestors();
-                        obj.setAncestors(parentAncestors + "," + obj.getParentId());
+                        obj.setAncestors(parentAncestors + "," + obj.getPId());
                     }
                 }
-                newMap.put(obj.getId(), obj);
+                newMap.put(obj.getPKeyId(), obj);
                 result.add(obj);
             }
         }
@@ -2357,14 +2367,18 @@ public class InformationWriteQueryController extends BladeController {
         } else { //多层级节点复制
             //根节点id
             Long needCopyNodeOldId = needCopyNode.getId();
-            needCopyNode.setId(SnowFlakeUtil.getId());
+            Long needCopyNodeOldPKeyId = needCopyNode.getPKeyId();
             needCopyNode.setPKeyId(SnowFlakeUtil.getId());
+            needCopyNode.setId(needCopyNode.getPKeyId());
+            needCopyNode.setPId(needCopyNodeOldPKeyId);
+
             needCopyNode.setNodeName(toCopyNode.getNodeName());
             needCopyNode.setFullName(toCopyNode.getNodeName());
             needCopyNode.setPartitionCode(toCopyNode.getPartitionCode());
             needCopyNode.setCreateTime(new Date());
 
             Map<Long, Long> parentIdToId = new HashMap<>();
+            Map<Long,Long>pidToPkeyId=new HashMap<>();
             Map<Long, List<WbsTreeContract>> tabMap = needTabs.stream().collect(Collectors.groupingBy(WbsTreeContract::getParentId));
 
             //获取节点下所有表的key
@@ -2378,6 +2392,7 @@ public class InformationWriteQueryController extends BladeController {
                 if (obj != null) {
                     //构造节点
                     Long newParentId;
+                    Long newPid;
                     if (parentIdToId.size() > 0) {
                         //去数据源节点获取父级id对应的新id,设置成重设后的新的父级id
                         newParentId = parentIdToId.get(node.getParentId());
@@ -2385,9 +2400,22 @@ public class InformationWriteQueryController extends BladeController {
                         //根节点
                         newParentId = needCopyNode.getId();
                     }
+                    if(pidToPkeyId.size()>0){
+                        //去数据源节点获取父级id对应的新id,设置成重设后的新的父级Pid
+                        newPid = pidToPkeyId.get(node.getPId());
+                    }else{
+                        //根节点
+                        newPid = needCopyNode.getPKeyId();
+                    }
+
                     if (ObjectUtils.isEmpty(newParentId)) {
                         newParentId = needCopyNode.getId();
                     }
+                    if(ObjectUtils.isEmpty(newPid)){
+                        newPid=needCopyNode.getPKeyId();
+                    }
+
+
                     obj.setPKeyId(SnowFlakeUtil.getId());
 
                     if (ObjectUtil.isNotEmpty(node.getOldId())) {
@@ -2399,8 +2427,10 @@ public class InformationWriteQueryController extends BladeController {
                     Long id = SnowFlakeUtil.getId();
                     //数据源节点的老id与新的id的Map,作为下一级的节点的父级id的替换
                     parentIdToId.put(node.getId(), id);
+                    pidToPkeyId.put(node.getPId(),newPid);
                     //重设Id
                     obj.setId(id);
+                    obj.setPId(newPid);
                     obj.setParentId(newParentId);
                     obj.setCreateTime(new Date());
                     //获取当前复制的节点的sort
@@ -2423,6 +2453,7 @@ public class InformationWriteQueryController extends BladeController {
                                 Long oldPKeyId = needTab.getPKeyId();
                                 String tableName = needTab.getInitTableName();
                                 Long tabId = SnowFlakeUtil.getId();
+                                objTab.setPId(obj.getPKeyId());
                                 objTab.setId(tabId);
                                 objTab.setParentId(id);
                                 objTab.setPKeyId(SnowFlakeUtil.getId());
@@ -2472,9 +2503,12 @@ public class InformationWriteQueryController extends BladeController {
             if (isSameNode == 1) {
                 //同节点
                 needCopyNode.setParentId(needCopyNode.getParentId());
+                needCopyNode.setPId(needCopyNode.getPId());
             } else {
                 //跨节点
                 needCopyNode.setParentId(toCopyNode.getId());
+                needCopyNode.setPId(toCopyNode.getPKeyId());
+                needCopyNode.setAncestors(toCopyNode.getAncestors()+","+needCopyNode.getPId());
             }
             addNodeList.add(0, needCopyNode);
         }
@@ -3027,8 +3061,8 @@ public class InformationWriteQueryController extends BladeController {
             Map<String, WbsTreePrivate> nodeMap = new HashMap<>();
             Map<String, WbsTreeContract> nodeMapContract = new HashMap<>();
             selectedNodeList.forEach(half -> {
-                OldIdToNewIdMap.put(half.getId(), SnowFlakeUtil.getId());
-                nodeMap.put(half.getId().toString(), half);
+                OldIdToNewIdMap.put(half.getPKeyId(), SnowFlakeUtil.getId());
+                nodeMap.put(half.getPKeyId().toString(), half);
 
                 WbsTreeContract wbsTreeContract = BeanUtil.copyProperties(half, WbsTreeContract.class);
                 nodeMapContract.put(half.getId().toString(), wbsTreeContract);
@@ -3041,25 +3075,28 @@ public class InformationWriteQueryController extends BladeController {
                 BeanUtils.copyProperties(half, newData);
 
                 //重塑pKeyId、id和parentId
-                newData.setPKeyId(SnowFlakeUtil.getId());
+                newData.setPKeyId(OldIdToNewIdMap.get(half.getPKeyId()));
+                newData.setId(newData.getPKeyId());
                 if (new Integer("1").equals(half.getType())) {
-                    newData.setId(OldIdToNewIdMap.containsKey(half.getId()) ? OldIdToNewIdMap.get(half.getId()) : SnowFlakeUtil.getId());
+                    newData.setPId(OldIdToNewIdMap.containsKey(half.getPId()) ? OldIdToNewIdMap.get(half.getPId()) : treeContract.getPKeyId());
                 }
 
                 //设置父级id
                 boolean var = true;
                 if ("1".equals(vo.getSaveType())) {
                     //当前节点及其子节点操作
-                    if (OldIdToNewIdMap.containsKey(half.getParentId())) {
+                    if (OldIdToNewIdMap.containsKey(half.getPId())) {
                         //跨节点
-                        WbsTreePrivate wbsTreePrivate = nodeMap.get(half.getParentId() + "");
+                        WbsTreePrivate wbsTreePrivate = nodeMap.get(half.getPId() + "");
                         if (treeContract.getNodeType().equals(wbsTreePrivate.getNodeType()) && treeContract.getNodeName().equals(wbsTreePrivate.getNodeName())) {
                             newData.setParentId(treeContract.getId());
+                            newData.setPId(treeContract.getPKeyId());
                             var = false;
 
                             //从复制or新增节点开始操作-》选择新增节点,根节点会走到这里
                         } else if (treeContract.getNodeType().equals(wbsTreePrivate.getNodeType()) && ObjectUtil.isNotEmpty(treeContract.getOldId()) && treeContract.getOldId().equals(wbsTreePrivate.getId().toString())) {
                             newData.setParentId(treeContract.getId());
+                            newData.setPId(treeContract.getPKeyId());
                             var = false;
                         }
                     }
@@ -3076,11 +3113,7 @@ public class InformationWriteQueryController extends BladeController {
                         } else {
                             //非自定义节点
                             //同节点
-                            newData.setParentId(OldIdToNewIdMap.containsKey(half.getParentId())
-                                ? OldIdToNewIdMap.get(half.getParentId()) : treeContract.getId().equals(half.getParentId())
-                                ||
-                                treeContract.getOldId().equals(half.getParentId().toString())
-                                ? treeContract.getId() : SnowFlakeUtil.getId());
+                            newData.setPId(OldIdToNewIdMap.containsKey(half.getPId())?OldIdToNewIdMap.get(half.getPId()):treeContract.getPKeyId());
                         }
                     }
 
@@ -3092,16 +3125,19 @@ public class InformationWriteQueryController extends BladeController {
                             if (("1").equals(node.getIsPeer())) {
                                 //同级
                                 newData.setParentId(treeContract.getParentId());
+                                newData.setPId(treeContract.getPKeyId());
 
                             } else if (("2").equals(node.getIsPeer())) {
                                 //下一级
                                 newData.setParentId(treeContract.getId());
+                                newData.setPId(treeContract.getPKeyId());
 
                             }
                         }
                     } else if (new Integer("2").equals(half.getType())) {
                         //表
                         newData.setParentId(OldIdToNewIdMap.containsKey(half.getParentId()) ? OldIdToNewIdMap.get(half.getParentId()) : treeContract.getId().equals(half.getParentId()) || treeContract.getOldId().equals(half.getParentId().toString()) ? treeContract.getId() : SnowFlakeUtil.getId());
+                        newData.setPId(OldIdToNewIdMap.containsKey(half.getPId())?OldIdToNewIdMap.get(half.getPId()):half.getPId());
                     }
                 }
 
@@ -3127,24 +3163,18 @@ public class InformationWriteQueryController extends BladeController {
                 //设置节点名称
                 newData.setFullName(ObjectUtil.isNotEmpty(idAndNodeNameMaps.get(half.getId())) ? idAndNodeNameMaps.get(half.getId()) : half.getFullName());
 
-                /*//重塑父节点关联关系
-                String ancestors = newData.getAncestors();
+                //重塑父节点关联关系
+                String sql="Select ancestors from m_wbs_tree_contract where p_key_id="+newData.getPId();
+                String ancestors = jdbcTemplate.query(sql, (rs, rowNum) -> rs.getString(1))
+                    .stream()
+                    .findFirst()
+                    .orElse(null);
                 if (StringUtils.isNotEmpty(ancestors)) {
-                    //重组后的链表
-                    StringBuilder stringBuilder = new StringBuilder();
-                    //拆分重组
-                    String[] ancestorsArray = ancestors.split(",");
-                    for (String oldParentId : ancestorsArray) {
-                        if (StringUtils.isNotEmpty(oldParentId)) {
-                            //获取新的
-                            Long newParentId = OldIdToNewIdMap.get(Long.parseLong(oldParentId));
-                            //如果新的id为空,说明不变
-                            stringBuilder.append(",").append(newParentId == null ? oldParentId : newParentId);
-                        }
-                    }
                     //将新链表设置进对象中
-                    newData.setAncestors(stringBuilder.substring(1));
-                }*/
+                    newData.setAncestors(ancestors+","+newData.getPId());
+                }else {
+                    newData.setAncestors(null);
+                }
 
                 //设置到保存集合中
                 saveList.add(newData);
@@ -3204,6 +3234,15 @@ public class InformationWriteQueryController extends BladeController {
                 }
             }
         }
+        //设置ancestors
+        for (WbsTreeContract wbsTreeContract : saveList) {
+            if(wbsTreeContract.getAncestors()==null){
+                WbsTreeContract wbsTreeContract1 = saveList.stream().filter(s -> s.getPKeyId().equals(wbsTreeContract.getPId())).findFirst().orElse(null);
+                if(wbsTreeContract1!=null&&wbsTreeContract1.getAncestors()!=null){
+                    wbsTreeContract.setAncestors(wbsTreeContract1.getAncestors()+","+wbsTreeContract.getPId());
+                }
+            }
+        }
         R<Boolean> booleanR = this.saveOrCopyNodeTree(saveList, saveLedger, 2, treeContract);
 
         List<WbsTreeContract> nowTabs = saveList.stream().filter(f -> new Integer(2).equals(f.getType())).collect(Collectors.toList());
@@ -3973,10 +4012,10 @@ public class InformationWriteQueryController extends BladeController {
             if (parentNode.getNodeType() < parentNode.getNodeType()) {
                 throw new ServiceException("当前新增选择的节点类型不能大于父级节点类型");
             }
-
             WbsTreeContract obj = new WbsTreeContract();
             obj.setPKeyId(SnowFlakeUtil.getId());
-            obj.setId(SnowFlakeUtil.getId());
+            obj.setId(obj.getPKeyId());
+            obj.setPId(parentNode.getPKeyId());
             obj.setProjectId(parentNode.getProjectId());
             obj.setContractId(parentNode.getContractId());
             obj.setContractType(ObjectUtil.isNotEmpty(parentNode.getContractType()) ? parentNode.getContractType() : null);
@@ -3986,7 +4025,7 @@ public class InformationWriteQueryController extends BladeController {
             obj.setFullName(dto.getNodeName());
 
             if (ObjectUtil.isNotEmpty(parentNode.getNodeType())) {
-                if (parentNode.getParentId().equals(0L)) {
+                if (parentNode.getPId().equals(0L)) {
                     obj.setNodeType(1);
                 } else {
                     obj.setNodeType(parentNode.getNodeType().equals(6) ? 6 : dto.getNodeType());
@@ -3994,7 +4033,7 @@ public class InformationWriteQueryController extends BladeController {
             }
             obj.setPartitionCode(dto.getPartitionCode());
             obj.setParentId(parentNode.getId());
-            obj.setAncestors(parentNode.getAncestors() + "," + parentNode.getId());
+            obj.setAncestors(parentNode.getAncestors() + "," + parentNode.getPKeyId());
             obj.setType(1);
             obj.setStatus(1);
             obj.setIsDeleted(0);
@@ -4032,7 +4071,6 @@ public class InformationWriteQueryController extends BladeController {
                         obj.setIsClassifition(dto.getIsClassifition());
                         obj.setExcellentNum(dto.getExcellentNum());
                         obj.setUnitNum(dto.getUnitNum());
-
                     } else {
                         throw new ServiceException("标准分类或单元名称选择有误");
                     }

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

@@ -1497,6 +1497,296 @@ public class TaskController extends BladeController {
         return R.data(page);
     }
 
+    @PostMapping("/pageset")
+    @ApiOperationSupport(order = 1)
+    @ApiOperation(value = "电签显示等待 batch中没有 用于跑电签数据的接口 手动调用", notes = "传入BusinessTaskDTO")
+    public R<IPage<BusinessTaskPageVO>> pageset(@RequestBody BusinessTaskDTO dto) throws IOException {
+        if (ObjectUtil.isEmpty(SecureUtil.getUser())) {
+            throw new ServiceException("未获取到当前用户信息,请联系管理员");
+        }
+        if (ObjectUtil.isEmpty(dto.getProjectIdValue())) {
+            throw new ServiceException("未获取到当前用户所在的项目信息,请联系管理员");
+        }
+        if (ObjectUtil.isEmpty(dto.getCurrentContractId())) {
+            throw new ServiceException("未获取到当前用户所在的合同段信息,请联系管理员");
+        }
+        ProjectInfo projectInfo = jdbcTemplate.query("select approval_type from m_project_info where id = " + dto.getProjectIdValue(), new BeanPropertyRowMapper<>(ProjectInfo.class)).stream().findAny().orElse(null);
+        int current = dto.getCurrent();
+        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 not in(4,5)");
+        if (ObjectUtil.isNotEmpty(dto.getTypeValue())) {
+            sqlString.append(" AND type = ?");
+            params.add(dto.getTypeValue());
+        }
+        if (ObjectUtil.isNotEmpty(dto.getStatusValue())) {
+            sqlString.append(" AND status = ?");
+            params.add(dto.getStatusValue());
+        }
+
+        ContractInfo contractInfo = jdbcTemplate.queryForObject("select contract_type from m_contract_info where id = " + dto.getCurrentContractId(), new BeanPropertyRowMapper<>(ContractInfo.class));
+        if (contractInfo != null && contractInfo.getContractType().equals(1)) {
+            //施工合同段正常查询
+            if (ObjectUtil.isNotEmpty(dto.getContractIdValue())) {
+                sqlString.append(" AND contract_id = ?");
+                params.add(dto.getContractIdValue());
+            } else {
+                //如果合同段id=null,那么查询当前项目下所有合同段任务
+                if (ObjectUtil.isNotEmpty(dto.getProjectIdValue())) {
+                    sqlString.append(" AND project_id = ?");
+                    params.add(dto.getProjectIdValue());
+                } else {
+                    throw new ServiceException("未获取到当前用户所在的项目信息,请联系管理员");
+                }
+            }
+        } else if (contractInfo != null && (contractInfo.getContractType().equals(2) || contractInfo.getContractType().equals(3))) {
+            if (ObjectUtil.isEmpty(dto.getOrdType())) { //Web端根据合同段查询
+                if (ObjectUtil.isNotEmpty(dto.getContractIdValue())) {
+                    if (dto.getContractIdValue().equals(dto.getCurrentContractId())) {
+                        //如果下拉框合同段选择框合同段=当前用户登陆合同段,那么查询全部合同段的数据
+                        List<ContractRelationJlyz> contractRelationJLYZ = jdbcTemplate.query("select contract_id_sg from m_contract_relation_jlyz where contract_id_jlyz = " + dto.getCurrentContractId(), new BeanPropertyRowMapper<>(ContractRelationJlyz.class));
+                        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(")");
+                    } else {
+                        //如果下拉框合同段选择框合同段!=当前用户登陆合同段,那么查询下拉框合同段数据
+                        sqlString.append(" AND contract_id = ?");
+                        params.add(dto.getContractIdValue());
+                    }
+                } else {
+                    //如果下拉框合同段id=null,那么查询当前整个项目的数据
+                    sqlString.append(" AND project_id = ?");
+                    params.add(dto.getProjectIdValue());
+                }
+            } else { //App直接查询全部合同段,整个项目
+                sqlString.append(" AND project_id = ?");
+                params.add(dto.getProjectIdValue());
+            }
+        }
+        if (ObjectUtil.isNotEmpty(dto.getBatchValue())) {
+            sqlString.append(" AND batch = ?");
+            params.add(dto.getBatchValue());
+        }
+        if (StringUtils.isNotBlank(dto.getStartTimeValue()) && StringUtils.isNotBlank(dto.getEndTimeValue())) {
+            sqlString.append(" AND start_time >= ?")
+                    .append(" AND end_time <= ?");
+            params.add(dto.getStartTimeValue());
+            params.add(dto.getEndTimeValue());
+        }
+        if (StringUtils.isNotBlank(dto.getQueryValue())) {
+            sqlString.append(" AND task_name LIKE ?");
+            params.add("%" + dto.getQueryValue() + "%");
+        }
+        if (ObjectUtil.isNotEmpty(dto.getSelectedType())) {
+            sqlString.append(" AND (");
+            if (dto.getSelectedType().equals(1)) { //待办页面
+
+                //如果是待办页面,且 任务状态下拉框 选择的是 待审批状态 的任务,那么才查询数据
+                if (ObjectUtil.isNotEmpty(dto.getStatusValue()) && dto.getStatusValue().equals(1)) {
+                    sqlString.append("EXISTS (SELECT 1 FROM u_task_parallel WHERE u_task.process_instance_id = u_task_parallel.process_instance_id AND u_task_parallel.status = ? AND u_task_parallel.task_user = ?)");
+                    params.add(1);
+                    params.add(SecureUtil.getUserId());
+
+                    //如果是待办页面,且 任务状态下拉框 选择的不是 待审批状态 的任务,那么直接返回null
+                } else if (ObjectUtil.isNotEmpty(dto.getStatusValue()) && !dto.getStatusValue().equals(1)) {
+                    return null;
+
+                    //如果是待办页面,没选择 任务状态下拉框,那么就默认查询 待审批状态 任务
+                } else if (ObjectUtil.isEmpty(dto.getStatusValue())) {
+                    sqlString.append("EXISTS (SELECT 1 FROM u_task_parallel WHERE u_task.process_instance_id = u_task_parallel.process_instance_id AND u_task_parallel.status = ? AND u_task_parallel.task_user = ?)");
+                    params.add(1);
+                    params.add(SecureUtil.getUserId());
+                    sqlString.append(" AND status = 1");
+                }
+
+            } else if (dto.getSelectedType().equals(2)) { //已办页面
+                sqlString.append("EXISTS (SELECT 1 FROM u_task_parallel WHERE u_task.process_instance_id = u_task_parallel.process_instance_id AND u_task_parallel.status in(2,3) AND u_task_parallel.task_user = ?)");
+                //当前自己的任务必须是已审批、已废除 status = 2,3 ,才视为已办
+                params.add(SecureUtil.getUserId());
+
+            } else if (dto.getSelectedType().equals(3)) { //我发起页面
+                sqlString.append("report_user = ?");
+                params.add(SecureUtil.getUserId());
+            }
+            sqlString.append(")");
+        }
+
+        //总数量
+        String sqlCount = sqlString.toString().replace("*", "count(1)");
+        Optional<Integer> totalCountOptional = Optional.ofNullable(jdbcTemplate.queryForObject(sqlCount, Integer.class, params.toArray()));
+        int totalCount = totalCountOptional.orElse(0);
+
+        //分页
+        if (ObjectUtil.isNotEmpty(dto.getOrdType())) {
+            //App端排序
+            if (dto.getOrdType() == 1) {
+                sqlString.append(" ORDER BY create_time DESC LIMIT ? OFFSET ?");
+            } else if (dto.getOrdType() == 2) {
+                sqlString.append(" ORDER BY create_time ASC LIMIT ? OFFSET ?");
+            } else {
+                sqlString.append(" ORDER BY create_time DESC LIMIT ? OFFSET ?");
+            }
+        } else {
+            //Web端默认倒叙
+            sqlString.append(" ORDER BY create_time DESC LIMIT ? OFFSET ?");
+        }
+        params.add(size);
+        params.add((current - 1) * size);
+
+        //执行SQL获取数据
+        String sqlPage = sqlString.toString();
+        List<Task> resultList = jdbcTemplate.query(
+                sqlPage,
+                new BeanPropertyRowMapper<>(Task.class),
+                params.toArray()
+        );
+
+        //获取任务详情信息Map
+        Set<String> processInstanceIds = resultList.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 process_instance_id,task_user,task_user_name,e_visa_status,e_visa_content,parallel_process_instance_id,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;
+        //获取用户信息Map
+        Map<Long, String> nameMap = jdbcTemplate.query("select id,name from blade_user where is_deleted = 0", new BeanPropertyRowMapper<>(User.class)).stream().collect(Collectors.toMap(User::getId, User::getName, (key1, key2) -> key1));
+
+        //解析page分页数据
+        IPage<BusinessTaskPageVO> page = new Page<>(current, size);
+        List<BusinessTaskPageVO> pageList = resultList.stream()
+                .map(task -> {
+                    BusinessTaskPageVO vo = new BusinessTaskPageVO();
+                    vo.setId(task.getId());
+                    vo.setTaskId(task.getId());
+                    vo.setTaskName(task.getTaskName());
+                    vo.setTaskTypeName(task.getType().equals(1) ? "普通任务" : task.getType().equals(2) ? "验收任务" : "移交任务");
+                    vo.setTaskStatusName(task.getStatus().equals(1) ? "待审批" : task.getStatus().equals(2) ? "已审批" : "已废除");
+                    vo.setStartTime(task.getStartTime());
+                    vo.setEndTime(task.getEndTime());
+                    vo.setTaskDesc(task.getTaskContent());
+                    vo.setTaskReportUserName(nameMap.get(Long.parseLong(task.getReportUser())));
+                    vo.setApprovalType(task.getApprovalType());
+                    vo.setFormDataId(task.getFormDataId());
+                    vo.setProcessInstanceId(task.getProcessInstanceId());
+                    List<TaskParallel> taskParallelList = finalTaskParallelGroupMap.get(task.getProcessInstanceId());
+                    if (taskParallelList != null && taskParallelList.size() > 0) {
+                        //如果是垂直签,且是待办页面,判断是否是当前用户审批轮次,不是当前用户审批轮次就不显示该任务
+                        if (projectInfo != null && projectInfo.getApprovalType() == 1 && dto.getSelectedType() == 1) {
+                            boolean shouldDisplayTask = false; //标记是否显示当前任务
+                            for (TaskParallel taskParallel : taskParallelList) {
+                                if (SecureUtil.getUserId().equals(Long.parseLong(taskParallel.getTaskUser()))) {
+                                    shouldDisplayTask = true; //当前用户是审批人,需要显示任务
+                                    break;
+                                } else if (taskParallel.getStatus() != 2) {
+                                    //之前的审批人员任务未完成,不显示任务
+                                    break;
+                                }
+                            }
+                            if (!shouldDisplayTask) {
+                                //跳过当前任务
+                                return null;
+                            }
+                        }
+
+                        List<String> names = taskParallelList.stream().map(TaskParallel::getTaskUserName).collect(Collectors.toList());
+                        if (names.size() > 0) {
+                            vo.setTaskApproveUserNames(StringUtils.join(names, ","));
+                        }
+
+                        //电签状态(始终只获取自己的电签任务状态信息)
+                        TaskParallel taskParallel = taskParallelList.stream().filter(f -> ObjectUtil.isNotEmpty(f.getTaskUser()) && f.getTaskUser().equals(SecureUtil.getUserId().toString())).findAny().orElse(null);
+                        if (taskParallel != null) {
+                            vo.setEVisaStatus(taskParallel.getEVisaContent() != null ? taskParallel.getEVisaContent() : "");
+                            vo.setParallelProcessInstanceId(taskParallel.getParallelProcessInstanceId());
+                        }
+                        if (vo.getTaskStatusName().equals("已废除")) {
+                            vo.setEVisaStatus("废除成功");
+                        }
+
+                        //判断签字人的验证 2=绿色 3=黄色 999=红色 其他代表=灰色
+                        List<TaskParallel> statList = new ArrayList<>();
+                        for (TaskParallel taskPa : taskParallelList) {
+                            if (taskPa.getStatus() == 2 && ObjectUtil.isNotEmpty(taskPa.getEVisaStatus()) && taskPa.getEVisaStatus() == 1) {
+                                taskPa.setEVisaStatus(2);
+                            } else if (taskPa.getStatus() == 3 && taskPa.getTaskUser().equals(SecureUtil.getUserId().toString())) {
+                                taskPa.setEVisaStatus(3);
+                            } else if (ObjectUtil.isNotEmpty(taskPa.getEVisaStatus()) && taskPa.getEVisaStatus() == 99) {
+                                taskPa.setEVisaStatus(999);
+                            } else {
+                                taskPa.setEVisaStatus(1);
+                            }
+                            statList.add(taskPa);
+                        }
+                        vo.setTaskApproveUserNamesList(statList);
+                    }
+                    return vo;
+                })
+                .filter(Objects::nonNull) //过滤掉为null的任务
+                .collect(Collectors.toList());
+        //所有满足条件的任务 转map
+        Map<Long, Task> taskMap = new HashMap<>();
+        Map<String, List<OperationLog>> operationLogMap = new HashMap<>();
+        List<Long> taskIds = pageList.stream().filter(b -> "已废除".equals(b.getTaskStatusName())).map(BusinessTaskPageVO::getTaskId).collect(Collectors.toList());
+        if (ObjectUtil.isNotEmpty(taskIds)){
+            String joinTaskIds = StringUtils.join(taskIds, ",");
+            List<Task> tasks = jdbcTemplate.query("select id, create_time,form_data_id from u_task where id in ( " + joinTaskIds+")", new BeanPropertyRowMapper<>(Task.class));
+            taskMap = tasks.stream()
+                    .collect(Collectors.toMap(
+                            Task::getId,
+                            task -> task));
+        }
+        //所有满足条件的日志 转map
+        String logQuery = "select business_id,create_user_name ,create_time from u_operation_log where  operation_content like '%废除%'";
+        List<OperationLog> operationLogs = jdbcTemplate.query(logQuery, new BeanPropertyRowMapper<>(OperationLog.class));
+        if(ObjectUtil.isNotEmpty(operationLogs)){
+            operationLogMap = operationLogs.stream().collect(Collectors.groupingBy(OperationLog::getBusinessId));
+        }
+        for (BusinessTaskPageVO businessTaskPageVO : pageList) {
+            if("已废除".equals(businessTaskPageVO.getTaskStatusName())){
+                Long taskId = businessTaskPageVO.getTaskId();
+                Task task = taskMap.get(taskId);
+                if (ObjectUtil.isEmpty(task)){
+                    continue;
+                }
+                //任务创建时间
+                Date createTime = task.getCreateTime();
+                //废除时间肯定在任务创建时间之后  选择距离当前任务创建时间最近的一条数据
+                List<OperationLog> operationLogsF = operationLogMap.get(task.getFormDataId());
+                /*List<OperationLog> operationLogs = jdbcTemplate.query("select create_user_name ,create_time from u_operation_log where business_id = '" +
+                                task.getFormDataId() + "'and operation_content like '%废除%' and create_time >= '"+format+"' ORDER BY ABS(TIMESTAMPDIFF(SECOND, '"+format+"', create_time)) LIMIT 1"
+                        , new BeanPropertyRowMapper<>(OperationLog.class));*/
+                if(ObjectUtil.isNotEmpty(operationLogsF)){
+                    Optional<OperationLog> min = operationLogsF.stream().filter(o -> o.getCreateTime().compareTo(createTime) >= 0)
+                            .min(Comparator.comparing(t -> t.getCreateTime().getTime() - createTime.getTime()));
+                    if (min.isPresent()){
+                        OperationLog operationLog = min.get();
+                        businessTaskPageVO.setEVisaStatus(businessTaskPageVO.getEVisaStatus()+":"+operationLog.getCreateUserName()+"-"+operationLog.getCreateTime());
+                    }
+                }
+            }
+        }
+        int i = 10;
+        for (BusinessTaskPageVO businessTaskPageVO : pageList) {
+            List<TaskParallel> taskApproveUserNamesList = businessTaskPageVO.getTaskApproveUserNamesList();
+            for (TaskParallel taskParallel : taskApproveUserNamesList) {
+                String eVisaContent = taskParallel.getEVisaContent();
+                if(ObjectUtil.isNotEmpty(eVisaContent) && eVisaContent.contains("当前等待电签的批次较多")){
+                    String sql = "INSERT INTO  `u_task_batch` (id,json_data,create_user,update_user,nick_name)VALUES("+i+",'{\"approvalFileList\":[],\"approvalType\":"+businessTaskPageVO.getApprovalType()+",\"comment\":\"OK\",\"flag\":\"OK\",\"formDataId\":\""+businessTaskPageVO.getFormDataId()+"\",\"parallelProcessInstanceId\":\""+taskParallel.getParallelProcessInstanceId()+"\",\"pass\":true,\"taskId\":\""+businessTaskPageVO.getTaskId()+"\"}',"+taskParallel.getTaskUser()+","+taskParallel.getTaskUser()+",'"+taskParallel.getTaskUserName()+"')";
+                    jdbcTemplate.execute(sql);
+                    i++;
+                }
+            }
+        }
+        page.setRecords(pageList);
+        page.setTotal(totalCount);
+        return R.data(page);
+    }
+
 
 
 
@@ -1672,6 +1962,21 @@ public class TaskController extends BladeController {
         return R.success("任务已经成功提交重签,请耐心等待!");
     }
 
+    /**
+     * 试验系统-试验检测(自检)-一键重签
+     */
+    @PostMapping("/reSigningTrial")
+    @ApiOperationSupport(order = 3)
+    @ApiOperation(value = "试验检测(自检)-一键重签", notes = "传入试验自检id")
+    public R<Object> reSigningTrial(@RequestBody TrialResignDto dto,  HttpServletRequest request) {
+        if (ObjectUtil.isEmpty(dto.getTrialIds())) {
+            return R.fail("请选择一条记录");
+        }
+        String header = request.getHeader("Blade-Auth");
+        taskService.reSigningTrial(dto,request);
+        return R.success("任务已经成功提交重签,请耐心等待!");
+    }
+
     /**
      * 质检-日志-一键重签
      */

+ 16 - 7
blade-service/blade-business/src/main/java/org/springblade/business/controller/TrialSummaryController.java

@@ -177,7 +177,6 @@ public class TrialSummaryController {
         if (ObjectUtil.isEmpty(sn)) {
             throw new ServiceException("汇总编号构造异常");
         }
-
         String sql_1 = "SELECT * FROM m_trial_summary_classification_configuration WHERE is_deleted = 0 AND status = 1 AND id = ?";
         TrialSummaryClassificationConfiguration classC = jdbcTemplate.query(sql_1, new Object[]{dto.getClassId()}, new BeanPropertyRowMapper<>(TrialSummaryClassificationConfiguration.class)).stream().findAny().orElse(null);
         if (classC != null && ObjectUtil.isNotEmpty(classC.getExcelId())
@@ -312,8 +311,21 @@ public class TrialSummaryController {
                 }
             }
 
+
+            Map<String, Object> map2 = new HashMap<>();
+             for(String mapKey : map.keySet()){
+                 for(TrialSummaryExcelTabReflection data: excelTabReflections){
+                    if(mapKey.equals((data.getElementKey()+"__"))){
+                        map2.put(data.getHtmlKeyName().split("__")[0]+"__",map.get(mapKey));
+                    }
+                 }
+             }
+
+
+
             String htmlString = this.html(classC.getHtmlUrl());
-            Map<String, String> indexMap = this.indexMap(htmlString, map);
+            Map<String, String> indexMap = this.indexMap(htmlString, map2);
+
             if (indexMap.size() > 0) {
                 ExcelTab excelTab = jdbcTemplate.query("SELECT file_url FROM m_excel_tab WHERE id = ?", new Object[]{classC.getExcelId()}, new BeanPropertyRowMapper<>(ExcelTab.class)).stream().findAny().orElse(null);
                 if (excelTab != null) {
@@ -429,6 +441,7 @@ public class TrialSummaryController {
             cell.setCellValue(value);
 
             CellStyle style = sheet.getWorkbook().createCellStyle();
+            style.setWrapText(true);
             style.setAlignment(HorizontalAlignment.CENTER);
             style.setVerticalAlignment(VerticalAlignment.CENTER);
 
@@ -448,7 +461,6 @@ public class TrialSummaryController {
                 CellRangeAddress mergedRegion = new CellRangeAddress(y1, y2, x1, x2);
                 sheet.addMergedRegion(mergedRegion);
             }
-
             Row row = sheet.getRow(y1);
             if (row == null) {
                 row = sheet.createRow(y1);
@@ -458,9 +470,9 @@ public class TrialSummaryController {
             cell.setCellValue(value);
 
             CellStyle style = sheet.getWorkbook().createCellStyle();
+            style.setWrapText(true);
             style.setAlignment(HorizontalAlignment.CENTER);
             style.setVerticalAlignment(VerticalAlignment.CENTER);
-
             style.setBorderBottom(BorderStyle.THIN);
             style.setBottomBorderColor(IndexedColors.BLACK.getIndex());
             style.setBorderTop(BorderStyle.THIN);
@@ -525,13 +537,11 @@ public class TrialSummaryController {
                 "hc-table-form-upload", "hc-form-checkbox-group", "el-radio-group", "el-select"};
         for (String tagName : tagNames) {
             Elements matchedElements = doc.select(tagName);
-
             for (Map.Entry<String, Object> map : values.entrySet()) {
                 /*key:key_1__*/
                 String key = map.getKey();
                 String value = (String) map.getValue();
                 String[] data = value.split("@@@###");
-
                 /*排序,取data[]个数标签,依次构造数据*/
                 Elements keyElementGroup = new Elements();
                 for (Element element : matchedElements) {
@@ -540,7 +550,6 @@ public class TrialSummaryController {
                         keyElementGroup.add(element);
                     }
                 }
-
                 if (keyElementGroup.size() <= 0) {
                     continue;
                 }

+ 3 - 2
blade-service/blade-business/src/main/java/org/springblade/business/controller/TrialSummaryMonthlyController.java

@@ -71,8 +71,9 @@ public class TrialSummaryMonthlyController {
             params.add(dto.getEndTime());
         }
         if (StringUtils.isNotEmpty(dto.getIds())) {
-            sqlString.append(" AND node_id in(?)");
-            params.add(dto.getIds());
+            sqlString.append(" AND node_id in("+dto.getIds()+")");
+            //参数拼接sql变成 node_id in('123,456'),会多个'',只能查出第一个id
+           // params.add(dto.getIds());
         }
 
         String sqlPage = sqlString.append(" ORDER BY create_time;").toString();

+ 60 - 2
blade-service/blade-business/src/main/java/org/springblade/business/controller/UserViewProjectContractController.java

@@ -40,6 +40,12 @@ import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
+import javax.imageio.ImageIO;
+import java.awt.image.BufferedImage;
+import java.io.InputStream;
+import java.math.BigDecimal;
+import java.net.URL;
+import java.net.URLConnection;
 import java.util.Comparator;
 import java.util.Iterator;
 import java.util.List;
@@ -66,6 +72,7 @@ public class UserViewProjectContractController {
     private final ISysClient sysClient;
 
     private final SignPfxClient signPfxClient;
+    private static final double INCH_TO_CM = 2.54;
 
     /**
      * 获取用户信息
@@ -73,7 +80,7 @@ public class UserViewProjectContractController {
     @PostMapping("/queryCurrentUserData")
     @ApiOperationSupport(order = 2)
     @ApiOperation(value = "获取用户信息")
-    public R<UserVO> queryCurrentUserData() {
+    public R<UserVO> queryCurrentUserData() throws Exception {
         User user = this.userClient.userInfoById(AuthUtil.getUserId()).getData();
         if (user != null) {
             //获取部门
@@ -88,7 +95,49 @@ public class UserViewProjectContractController {
             //获取个人签字文件
             List<SignPfxFile> pfxFiles = this.signPfxClient.querySignPfxByUserIdOrContractId(user.getId().toString(), "");
             if (pfxFiles != null && pfxFiles.size() > 0) {
-                userVO.setSignatureUrl(pfxFiles.get(0).getSignatureFileUrl());
+                SignPfxFile signPfxFile = pfxFiles.get(0);
+                String signatureFileUrl = pfxFiles.get(0).getSignatureFileUrl();
+                userVO.setSignatureUrl(signatureFileUrl);
+                Double wide = signPfxFile.getWide();
+                Double high = signPfxFile.getHigh();
+                if(ObjectUtil.isNotEmpty(wide) && ObjectUtil.isNotEmpty(high)){
+                    int w = cmToPx(wide);
+                    int h = cmToPx(high);
+                    BigDecimal wideBigDecimal = new BigDecimal(w);
+                    BigDecimal highBigDecimal = new BigDecimal(h);
+                    //分别乘以1.29 保留两位小数
+                    BigDecimal wideDecima = wideBigDecimal.multiply(new BigDecimal(1.29)).setScale(2, BigDecimal.ROUND_HALF_UP);
+                    BigDecimal highDecima = highBigDecimal.multiply(new BigDecimal(1.29)).setScale(2, BigDecimal.ROUND_HALF_UP);
+                    wide = wideDecima.doubleValue();
+                    high = highDecima.doubleValue();
+                }else {
+                    //获取图片本身大小 设置默认值
+                    URL url = new URL(signatureFileUrl);
+                    URLConnection urlConnection = url.openConnection();
+                    InputStream inputStreamByUrl = urlConnection.getInputStream();
+                    //InputStream inputStreamByUrl = FileUtils.getInputStreamByUrl(signatureFileUrl);
+                    BufferedImage image = ImageIO.read(inputStreamByUrl);
+                     wide = Double.valueOf(image.getWidth());
+                     high = Double.valueOf(image.getHeight());
+                    BigDecimal wideBigDecimal = new BigDecimal(wide);
+                    BigDecimal highBigDecimal = new BigDecimal(high);
+                     if(wide.equals(high)){
+                         wide = 170.00;
+                         high = 170.00;
+                     }else if(Double.compare(wide, high) > 0 ){
+                         BigDecimal ratio = new BigDecimal(30);
+                         BigDecimal scaleFactor = ratio.divide(highBigDecimal,2, BigDecimal.ROUND_HALF_UP);
+                         wide = wideBigDecimal.multiply(scaleFactor).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
+                         high = 30.00;
+                     }else {
+                         BigDecimal ratio = new BigDecimal(170);
+                         BigDecimal scaleFactor = ratio.divide(highBigDecimal,2, BigDecimal.ROUND_HALF_UP);
+                         wide = wideBigDecimal.multiply(scaleFactor).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
+                         high = 170.00;
+                     }
+                }
+                userVO.setWide(wide);
+                userVO.setHigh(high);
             }
             //获取角色信息
             if (StringUtils.isNotEmpty(userVO.getRoleId())) {
@@ -238,5 +287,14 @@ public class UserViewProjectContractController {
         }
         return R.data(-1, null, "数据查询失败");
     }
+    public static int cmToPx(double cm) {
+        double pixelsPerCm = 90 / INCH_TO_CM;
+        return (int) Math.round(cm * pixelsPerCm);
+    }
+    public static double pxToCm(int px) {
+        double cmPerPixel = INCH_TO_CM / 90;
+        //保留两位小数
+        return Math.round(px * cmPerPixel * 100) / 100.0;
+    }
 
 }

+ 33 - 2
blade-service/blade-business/src/main/java/org/springblade/business/feignClient/ContractLogClientImpl.java

@@ -4,6 +4,8 @@ import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang.StringUtils;
 import org.springblade.business.entity.ContractLog;
 import org.springblade.business.entity.ContractLogWbs;
 import org.springblade.business.feign.ContractLogClient;
@@ -18,12 +20,14 @@ import org.springblade.core.tool.utils.Func;
 import org.springblade.manager.entity.WbsTreePrivate;
 import org.springblade.manager.feign.WbsTreePrivateClient;
 import org.springframework.beans.BeanUtils;
+import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.web.bind.annotation.RestController;
 
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 
+@Slf4j
 @RestController
 @AllArgsConstructor
 @NonDS
@@ -34,6 +38,7 @@ public class ContractLogClientImpl implements ContractLogClient {
     private final IContractLogWbsService contractLogWbsService;
 
     private final WbsTreePrivateClient wbsTreePrivateClient;
+    private final JdbcTemplate jdbcTemplate;
 
     @Override
     public List<JSONObject> queryContractLogWbsByBusinessId(String businessId) {
@@ -136,6 +141,14 @@ public class ContractLogClientImpl implements ContractLogClient {
 
     @Override
     public String saveContractLog(SaveContractLogVO saveContractLogVO) {
+        String businessIds = saveContractLogVO.getBusinessIds();
+        //删除旧数据
+        if (StringUtils.isNotEmpty(businessIds)) {
+            //删除关联工序信息
+            String delSql = " delete from u_contract_log_wbs where business_id in(" + businessIds + ")";
+            this.jdbcTemplate.execute(delSql);
+        }
+
         ContractLog contractLog = new ContractLog();
         //复制数据
         BeanUtils.copyProperties(saveContractLogVO, contractLog);
@@ -159,8 +172,26 @@ public class ContractLogClientImpl implements ContractLogClient {
             this.contractLogWbsService.saveBatch(logWbsList);
         }
 
-        this.contractLogService.save(contractLog);
-
+        try {
+            this.contractLogService.save(contractLog);
+        } catch (Exception e) {
+            return "新增异常";
+        }
+        try {
+            StringBuilder saveSql = new StringBuilder("INSERT INTO u_contract_log(id,project_id,contract_id,wbs_node_id,wbs_node_type" +
+                    ",record_time,data_id,create_user,create_user_name,update_user,status,file_name,pdf_url,table_id,old_data_id) VALUES ");
+            saveSql.append("(" + contractLog.getId() + "," + contractLog.getProjectId() + "," + contractLog.getContractId() + "," +
+                    contractLog.getWbsNodeId() + "," + contractLog.getWbsNodeType() + ",'" + contractLog.getRecordTime() + "','" +
+                    contractLog.getDataId()+ "'," + contractLog.getCreateUser() + ",'" +contractLog.getCreateUserName()+ "'," +
+                    contractLog.getUpdateUser()+ "," + contractLog.getStatus() + ",'" + contractLog.getFileName() + "','" + contractLog.getPdfUrl() + "'," +
+                    contractLog.getTableId() + ",'" + contractLog.getOldDataId() + "')");
+            StringBuilder logSql = new StringBuilder("INSERT INTO blade_log_sql (contract_log_id,user_id,create_time,sql_info) VALUES " );
+            String replaceSql = saveSql.toString().replace("\"", "'");
+            logSql.append("("+contractLog.getId()+","+contractLog.getCreateUser()+",SYSDATE(),\"" + replaceSql + "\")");
+            jdbcTemplate.execute(logSql.toString());
+        } catch (Exception e) {
+            return contractLog.getId().toString();
+        }
         return contractLog.getId().toString();
     }
 

+ 9 - 1
blade-service/blade-business/src/main/java/org/springblade/business/feignClient/MileageClientImpl.java

@@ -1,5 +1,6 @@
 package org.springblade.business.feignClient;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import lombok.AllArgsConstructor;
 import org.springblade.business.entity.MileagePart;
@@ -35,7 +36,14 @@ public class MileageClientImpl implements MileageClient {
         Map<String, List<String>> group = mileages.stream().collect(Collectors.groupingBy(e -> e.replaceAll("K.+", StringPool.EMPTY)));
         for (Map.Entry<String, List<String>> entry : group.entrySet()) {
             String part = entry.getKey();
-            MileagePart mileagePart=this.partService.getOne(Wrappers.<MileagePart>lambdaQuery().eq(MileagePart::getContractId,contractId.toString()).eq(MileagePart::getPrefix,part).last(" limit 1 "));
+            LambdaQueryWrapper<MileagePart> lambdaQuery = new LambdaQueryWrapper<>();
+            lambdaQuery.eq(MileagePart::getIsDeleted, 0)
+                .eq(MileagePart::getContractId, contractId)
+                .and(wrapper -> wrapper.eq(MileagePart::getPrefix, part)
+                    .or()
+                    .isNull(MileagePart::getPrefix))
+                .last("limit 1");
+            MileagePart   mileagePart = partService.getOne(lambdaQuery);
             if(mileagePart!=null) {
                 List<Mileagexy> target = this.service.list(Wrappers.<Mileagexy>lambdaQuery().eq(Mileagexy::getPartId, mileagePart.getId()).orderByAsc(Mileagexy::getValue));
                 if (CollectionUtil.isNotEmpty(target)) {

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

@@ -19,6 +19,7 @@
         <result column="task_user" property="taskUser"/>
         <result column="task_user_name" property="taskUserName"/>
         <result column="initiative" property="initiative"/>
+        <result column="exe_count" property="exeCount"/>
     </resultMap>
 
     <select id="queryApprovalUser" resultMap="taskParallelResultMap">

+ 7 - 0
blade-service/blade-business/src/main/java/org/springblade/business/service/ITaskService.java

@@ -16,6 +16,7 @@
  */
 package org.springblade.business.service;
 
+import org.springblade.business.dto.TrialResignDto;
 import org.springblade.business.entity.Task;
 import org.springblade.business.entity.TaskParallel;
 import org.springblade.business.vo.TaskApprovalVO;
@@ -119,4 +120,10 @@ public interface ITaskService extends BaseService<Task> {
      */
     @Async
     void logReSigningEVisa(String logIds,Long logPkeyId,Long nodePrimaryKeyId, String contractId,HttpServletRequest request, Integer type);
+
+    /**
+     * 试验-resign-一键重签
+     */
+    @Async
+    void reSigningTrial(TrialResignDto dto, HttpServletRequest request);
 }

+ 10 - 8
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/InformationQueryServiceImpl.java

@@ -486,15 +486,17 @@ public class InformationQueryServiceImpl extends BaseServiceImpl<InformationQuer
                 HashSet<String> hashSet = new HashSet<>(userList);
                 List<String> users = new ArrayList<>();
                 hashSet.forEach(user -> {
-                    String[] array = user.split("-");
-                    if (!users.contains(array[0])) {
-                        User bUser = this.userClient.userInfoById(Long.parseLong(array[0])).getData();
-                        if (bUser != null) {
-                            result.add(new FileUserVO(array[0], bUser.getRealName()));
-                        } else {
-                            result.add(new FileUserVO(array[0], array[1]));
+                    if(Func.isNotEmpty(user) && user.contains("-") && user.length() > 1) {
+                        String[] array = user.split("-");
+                        if (!users.contains(array[0]) ) {
+                            User bUser = this.userClient.userInfoById(Long.parseLong(array[0])).getData();
+                            if (bUser != null) {
+                                result.add(new FileUserVO(array[0], bUser.getRealName()));
+                            } else {
+                                result.add(new FileUserVO(array[0], array[1]));
+                            }
+                            users.add(array[0]);
                         }
-                        users.add(array[0]);
                     }
                 });
             }

+ 161 - 2
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TaskServiceImpl.java

@@ -12,8 +12,11 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springblade.archive.entity.ArchiveProjectConfig;
 import org.springblade.archive.feign.ArchiveAutoClient;
+import org.springblade.business.dto.TrialResignDto;
+import org.springblade.business.dto.TrialSelfInspectionRecordDTO;
 import org.springblade.business.entity.*;
 import org.springblade.business.mapper.TaskMapper;
+import org.springblade.business.mapper.TrialSelfInspectionRecordMapper;
 import org.springblade.business.service.*;
 import org.springblade.business.vo.*;
 import org.springblade.common.constant.CommonConstant;
@@ -46,6 +49,7 @@ import org.springblade.manager.entity.TabBusstimeInfo;
 import org.springblade.manager.entity.WbsTreeContract;
 import org.springblade.manager.feign.*;
 import org.springblade.manager.vo.AppWbsTreeContractVO;
+import org.springblade.manager.vo.WbsTreePrivateVO4;
 import org.springblade.resource.feign.CommonFileClient;
 import org.springblade.resource.feign.NewIOSSClient;
 import org.springblade.system.cache.ParamCache;
@@ -122,6 +126,8 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
     private final ExcelTabClient excelTabClient;
 
     private final NewIOSSClient newIOSSClient;
+    private final WbsTreePrivateClient wbsTreePrivateClient;
+    private final TrialSelfInspectionRecordMapper trialSelfInspectionRecordMapper;
     //超级管理员的角色id
     private final String SUPER_ADMIN_ROLE_ID ="1123598816738675201";
     //泓创智诚公司的部门id
@@ -265,8 +271,14 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
                     //资料填报原始pdf
 //                    String approvalPdf = StringUtils.isNotEmpty(query.getEVisaPdfUrl()) ? query.getEVisaPdfUrl() : query.getPdfUrl();
                     /** 修改需求,任务查看时,附件不在列表中显示,需要拼接在电签后面。如果此处修改影响其他地方,则到时候再说*/
-                    String approvalPdf = StringUtils.isNotEmpty(query.getEVisaPdfUrl()) ? query.getEVisaPdfUrl() : query.getPdfUrl();
-                    vo.setApprovalFileList(query.getName(), this.getHppsToHttp(approvalPdf));
+                    if(isTask){
+                        String approvalPdf = StringUtils.isNotEmpty(query.getEVisaPdfUrl()) ? query.getEVisaPdfUrl() : query.getPdfUrl();
+                        vo.setApprovalFileList(query.getName(), this.getHppsToHttp(approvalPdf));
+                    }else{
+                        String approvalPdf = StringUtils.isNotEmpty(query.getNodePdfUrl()) ? query.getNodePdfUrl() : query.getEVisaPdfUrl();
+                        String approvalPdf2 = StringUtils.isNotEmpty(approvalPdf) ? approvalPdf : query.getPdfUrl();
+                        vo.setApprovalFileList(query.getName(), this.getHppsToHttp(approvalPdf2));
+                    }
 
                     //试验关联文件合并pdf
                     if (StringUtils.isNotEmpty(query.getPdfTrialUrl())) {
@@ -583,6 +595,7 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
                 .set(TaskParallel::getEVisaContent, "当前等待电签的批次较多,请等待几分钟后刷新页面查看........")
                 .set(TaskParallel::getStatus, 1)
                 .set(TaskParallel::getEVisaStatus, 0)
+                        .set(TaskParallel::getInitiative, 1)
                 .in(TaskParallel::getParallelProcessInstanceId, taskIds));
 
         List<TaskBatch> taskList = new ArrayList<>();
@@ -1060,6 +1073,152 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
         }
     }
 
+    @Override
+    public void reSigningTrial(TrialResignDto dto, HttpServletRequest request) {
+        int type = dto.getType();
+        //查询任务信息
+        List<Task> taskList = jdbcTemplate.query("select * from u_task where trial_self_inspection_record_id in(" + dto.getTrialIds() + ") and is_deleted  = 0 and (status = 1 or status =2)", new BeanPropertyRowMapper<>(Task.class));
+        if (taskList.size() > 0) {
+            //获取任务详情信息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;
+            //获取每条任务对应的节点信息
+            List<String> dataIdList = taskList.stream().map(Task::getFormDataId).filter(ObjectUtil::isNotEmpty).collect(Collectors.toList());
+            Map<String, String> queryMap = jdbcTemplate.query("select * from u_information_query where id in(" + StringUtils.join(dataIdList, ",") + ")", new BeanPropertyRowMapper<>(InformationQuery.class)).stream().collect(Collectors.toMap(l -> l.getId() + "", l -> l.getWbsId() + ""));
+            Map<String, String> typeMap = jdbcTemplate.query("select * from u_information_query where id in(" + StringUtils.join(dataIdList, ",") + ")", new BeanPropertyRowMapper<>(InformationQuery.class)).stream().collect(Collectors.toMap(l -> l.getId() + "", l -> l.getClassify() + ""));
+
+            try {
+                for (Task task : taskList) {
+                    R result = new R();
+                    jdbcTemplate.execute("DELETE from u_task_batch where json_data like '%"+task.getId()+"%'");
+                    boolean b = false;
+                    if(type == 1){
+                        b = informationQueryService.update(new LambdaUpdateWrapper<InformationQuery>()
+                                .eq(InformationQuery::getId, task.getFormDataId())
+                                .set(InformationQuery::getEVisaPdfUrl, null));
+                    }else {
+                        b = informationQueryService.update(new LambdaUpdateWrapper<InformationQuery>()
+                                .eq(InformationQuery::getId, task.getFormDataId())
+                                .set(InformationQuery::getEVisaPdfUrl, null));
+                    }
+
+                    if (type == 1) {
+                        //重新保存
+                        long startTime_1 = System.currentTimeMillis();
+                        result = this.saveTrialSelfNodePdf(dto,queryMap.get(task.getFormDataId()));
+                        long endTime_1 = System.currentTimeMillis();
+                        long executionTime_1 = endTime_1 - startTime_1;
+                        log.info("saveNodePdf执行时间:" + executionTime_1 + " 毫秒");
+                    }else{
+                        if (!b){
+                            throw new ServiceException("清空电签PDF失败");
+                        }
+                        result.setData("成功");
+                    }
+                    //重新电签
+                    if (result != null && "成功".equals(result.getData())) {
+                        List<TaskApprovalVO> taskApprovalVOS = new ArrayList<>();
+                        List<TaskParallel> taskParallelList = finalTaskParallelGroupMap.get(task.getProcessInstanceId());
+                        for (TaskParallel taskParallel : taskParallelList) {
+                            //待审批的不进行重签, 存在待审批,但是电签状态是失败的
+                            if ((new Integer(2)).equals(taskParallel.getStatus()) || Func.isNotEmpty(taskParallel.getEVisaStatus()) || Func.isNotEmpty(taskParallel.getEVisaContent()) ) {
+                                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();
+                        if(taskApprovalVOS!=null && taskApprovalVOS.size()>=1){
+                            this.batchCompleteApprovalTask(taskApprovalVOS);
+                        }
+                        long endTime_2 = System.currentTimeMillis();
+                        long executionTime_2 = endTime_2 - startTime_2;
+                        log.info("batchCompleteApprovalTask执行时间:" + executionTime_2 + " 毫秒");
+                    } else {
+                        //修改重签状态为保存PDF失败
+                        this.taskParallelService.update(Wrappers.<TaskParallel>lambdaUpdate()
+                                .set(TaskParallel::getEVisaContent, "重新保存PDF失败")
+                                .eq(TaskParallel::getProcessInstanceId, task.getProcessInstanceId()));
+                    }
+                }
+                //获取当前操作人
+                /*Long userId = AuthUtil.getUserId(request);
+                String userName = AuthUtil.getNickName(request);
+                //判断是否是超级管理员并且是泓创智诚下的部门
+                if(judgeRoleIdAndDeptId(userId)){
+                    //满足去除当前填报人的条件 去除当前任务的填报人中当前操作人的信息
+                    String taskIds = StringUtils.join(taskList, ",");
+                    removeUserAndName(taskIds, userId, userName);
+                }*/
+            } catch (Exception e) {
+                e.printStackTrace();
+                throw new ServiceException("重新保存PDF信息失败,原因:" + e.getMessage());
+            }
+        }else {
+            throw new ServiceException("未获取到任务信息,操作失败!");
+        }
+
+
+    }
+
+    private R saveTrialSelfNodePdf(TrialResignDto dto,String trialId) {
+        //试验记录id
+        String trialIds = dto.getTrialIds();
+        TrialSelfInspectionRecord tRecord = trialSelfInspectionRecordMapper.selectById(trialIds);
+
+        //调用获取实验记录表和报告单的方法 "1,9,2,10" 查询记录表和报告单  isAdd 2 非新增
+        R<List<WbsTreePrivateVO4>> listR = wbsTreePrivateClient.searchNodeAllTable(tRecord.getNodeId().toString(), tRecord.getType().toString(), "1,9,2,10", tRecord.getContractId().toString(), dto.getProjectId(), 2, Long.parseLong(trialId));
+        List<WbsTreePrivateVO4> data = listR.getData();
+        //构造dataInfo
+        JSONArray orderList = new JSONArray();
+        for (WbsTreePrivateVO4 datum : data) {
+            Map<String, Object> bussDataInfoTrial = datum.getBussDataInfoTrial();
+            bussDataInfoTrial.put("nodeId", tRecord.getNodeId());
+            bussDataInfoTrial.put("pkeyId", datum.getPKeyId());
+            bussDataInfoTrial.put("projectId", datum.getProjectId());
+            bussDataInfoTrial.put("isCollapseLoad", datum.getIsCopyTab());
+            bussDataInfoTrial.put("isBussShow", datum.getIsBussShow());
+            bussDataInfoTrial.put("contractId", tRecord.getContractId());
+            bussDataInfoTrial.put("type", datum.getTableType());
+            JSONObject jsonObject = new JSONObject(bussDataInfoTrial);
+            orderList.add(jsonObject);
+        }
+        Map<String, Object> stringObjectMap = new HashMap<>();
+        stringObjectMap.put("orderList", orderList);
+        JSONObject dataInfo = new JSONObject(stringObjectMap);
+        //构造trialSelfInspectionRecordDTO数据
+        TrialSelfInspectionRecordDTO trialSelfInspectionRecordDTO = new TrialSelfInspectionRecordDTO();
+        trialSelfInspectionRecordDTO.setContractId(tRecord.getContractId());
+        trialSelfInspectionRecordDTO.setDataInfo(dataInfo);
+        trialSelfInspectionRecordDTO.setDetectionCategory(tRecord.getDetectionCategory());
+        trialSelfInspectionRecordDTO.setDetectionResult(tRecord.getDetectionResult());
+        trialSelfInspectionRecordDTO.setEntrustId(tRecord.getEntrustId());
+        trialSelfInspectionRecordDTO.setId(Long.parseLong(trialId));
+        trialSelfInspectionRecordDTO.setIsBatchSave(1);
+        trialSelfInspectionRecordDTO.setNodeId(tRecord.getNodeId());
+        trialSelfInspectionRecordDTO.setReportDate(tRecord.getReportDate());
+        trialSelfInspectionRecordDTO.setTableType("1,2");
+        trialSelfInspectionRecordDTO.setTrialUserName(tRecord.getTrialUserName());
+        trialSelfInspectionRecordDTO.setTrialProjectName(tRecord.getTrialProjectName());
+        trialSelfInspectionRecordDTO.setType(tRecord.getType());
+        String pdfUrl = excelTabClient.saveTabData(trialSelfInspectionRecordDTO, 1, tRecord.getType(), "1,2", Long.parseLong(trialId), tRecord.getTableIds());
+        return R.data("成功");
+    }
+
     @Override
     public Boolean startApproval(TaskVO vo) {
         if (ObjectUtil.isEmpty(vo.getReportUserId()) || ObjectUtil.isEmpty(vo.getReportUserName())) {

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

@@ -14,6 +14,7 @@ import com.spire.xls.Workbook;
 import com.spire.xls.Worksheet;
 import lombok.AllArgsConstructor;
 import org.apache.commons.lang.time.DateUtils;
+import org.jetbrains.annotations.NotNull;
 import org.jsoup.Jsoup;
 import org.jsoup.nodes.Document;
 import org.jsoup.nodes.Element;
@@ -58,6 +59,7 @@ import org.springblade.system.user.feign.IUserClient;
 import org.springframework.dao.DataAccessException;
 import org.springframework.jdbc.core.BeanPropertyRowMapper;
 import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.core.SingleColumnRowMapper;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -287,7 +289,7 @@ public class TrialSelfInspectionRecordServiceImpl extends BaseServiceImpl<TrialS
                     entrustPdfUrl = "";
                 }
             }
-            
+
             //关联原材料检测报告的pdf(合并后的dpf都一样,取其一)
             String sqlRecord = "select old_pdf_url from u_trial_raw_material_self_record where self_record_id =" + nodeId;
             TrialRawMaterialSelfRecord recordObj = jdbcTemplate.query(sqlRecord, new BeanPropertyRowMapper<>(TrialRawMaterialSelfRecord.class)).stream().findAny().orElse(null);
@@ -343,8 +345,9 @@ public class TrialSelfInspectionRecordServiceImpl extends BaseServiceImpl<TrialS
                         return pdfUrl.toString();
                     }
             }}
-
-            return pdfUrl.toString();
+            if(ObjectUtil.isNotEmpty(pdfUrl)){
+                return pdfUrl.toString();
+            }
         }
         return "";
     }
@@ -1127,31 +1130,39 @@ public class TrialSelfInspectionRecordServiceImpl extends BaseServiceImpl<TrialS
     private void updateRecordNoOrReportNo(TrialSelfInspectionRecord obj, TrialSelfInspectionRecordDTO dto) {
             JSONArray dataArray = dto.getDataInfo().getJSONArray("orderList");
             //获取第一张表的数据  编号以第一张表为准
-            JSONObject jsonObject = dataArray.getJSONObject(0);
-            String pkeyId = jsonObject.getString("pkeyId");
-            String sql = "select * from m_wbs_tree_private where p_key_id =" + pkeyId;
-            WbsTreePrivate table = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<>(WbsTreePrivate.class));
-            String fileUrl = table.getHtmlUrl();
-            try {
-                InputStream fileInputStream = FileUtils.getInputStreamByUrl(fileUrl);
-                String htmlString = IoUtil.readToString(fileInputStream);
-                htmlString = htmlString.replaceAll("placeholder", "placeholderxx");
-                Document doc = Jsoup.parse(htmlString);
-                // 查找所有具有 placeholderxx 属性的元素
-                //表类型 1,9=记录表 2,10=报告单
-                if(table.getTableType() == 9 || table.getTableType() == 1){
-                    //记录表  以第一张表为准
-                     this.updateRecordNoOrReportNo(dto, jsonObject, doc, "记录编 号:", "record_no");
-                     this.updateRecordNoOrReportNo(dto, jsonObject, doc, "记录编号:", "record_no");
-                }else if(table.getTableType() == 10 || table.getTableType() == 2){
-                    //报告单
-                    this.updateRecordNoOrReportNo(dto,jsonObject,doc,"报告编号:","report_no");
-                    //:不一样 一个中文一个英文
-                    this.updateRecordNoOrReportNo(dto,jsonObject,doc,"报告编号:","report_no");
-                }
-            } catch (Exception e) {
-                log.error(e.getMessage());
-            }
+            List<JSONObject> dataList = dataArray.toJavaList(JSONObject.class);
+           // 根据 type 字段进行分组
+             Map<String, List<JSONObject>> groupedByType = dataList.stream()
+            .collect(Collectors.groupingBy(jsonObject -> jsonObject.getString("type")));
+          for (Map.Entry<String, List<JSONObject>> entry : groupedByType.entrySet()) {
+              List<JSONObject> jsonObjects = groupedByType.get(entry.getKey());
+              JSONObject   jsonObject = jsonObjects.get(0);
+              String pkeyId = jsonObject.getString("pkeyId");
+              String sql = "select * from m_wbs_tree_private where p_key_id =" + pkeyId;
+              WbsTreePrivate table = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<>(WbsTreePrivate.class));
+              String fileUrl = table.getHtmlUrl();
+              try {
+                  InputStream fileInputStream = FileUtils.getInputStreamByUrl(fileUrl);
+                  String htmlString = IoUtil.readToString(fileInputStream);
+                  htmlString = htmlString.replaceAll("placeholder", "placeholderxx");
+                  Document doc = Jsoup.parse(htmlString);
+                  // 查找所有具有 placeholderxx 属性的元素
+                  //表类型 1,9=记录表 2,10=报告单
+                  if(table.getTableType() == 9 || table.getTableType() == 1){
+                      //记录表  以第一张表为准
+                      this.updateRecordNoOrReportNo(dto, jsonObject, doc, "记录编 号:", "record_no");
+                      this.updateRecordNoOrReportNo(dto, jsonObject, doc, "记录编号:", "record_no");
+                  }else if(table.getTableType() == 10 || table.getTableType() == 2){
+                      //报告单
+                      this.updateRecordNoOrReportNo(dto,jsonObject,doc,"报告编号:","report_no");
+                      //  :不一样 一个中文一个英文
+                      this.updateRecordNoOrReportNo(dto,jsonObject,doc,"报告编号:","report_no");
+                  }
+              } catch (Exception e) {
+                  log.error(e.getMessage());
+              }
+          }
+
 
     }
 
@@ -1273,12 +1284,72 @@ public class TrialSelfInspectionRecordServiceImpl extends BaseServiceImpl<TrialS
     public void submitTrialData(TrialSelfInspectionRecord obj, TrialSelfInspectionRecordDTO dto) {
         String pdfURL = excelTabClient.saveTabData(dto, dto.getIsBatchSave(), dto.getType(), dto.getTableType(), dto.getId(), obj.getTableIds());
         if (StringUtils.isNotEmpty(pdfURL) && !pdfURL.equals("500")) {
-            this.update(Wrappers.<TrialSelfInspectionRecord>lambdaUpdate().set(TrialSelfInspectionRecord::getPdfUrl, pdfURL).eq(TrialSelfInspectionRecord::getId, dto.getId()));
+            String file_path = FileUtils.getSysLocalFileUrl();
+            Long snowId = SnowFlakeUtil.getId();
+            String listPdf = file_path + "/pdf/" + snowId + ".pdf";
+            JSONArray dataArray = dto.getDataInfo().getJSONArray("orderList");
+            boolean recordDataTable = false;
+            boolean reportDataTable = false;
+            for (int i = 0; i < dataArray.size(); i++) {
+                JSONObject jsonObject = dataArray.getJSONObject(i);
+                String type = jsonObject.getString("type");
+                if(ObjectUtil.isEmpty(type)){
+                    throw new RuntimeException("请点击表单后再进行保存");
+                }
+                if (type.equals("1")) {
+                    //记录表
+                    recordDataTable = true;
+                }
+                if (type.equals("2")) {
+                    //报告表
+                    reportDataTable = true;
+                }
+            }
+            String updateSql = null;
+            if (recordDataTable && !reportDataTable) {
+                //单独保存记录表 查询报告单pdf是否有值 如果有值就合并 合并存到pdf_url
+                updateSql = getUpdateSql(dto, pdfURL, listPdf, snowId, "report_pdf_url", 1, "record_pdf_url");
+
+            } else if (!recordDataTable && reportDataTable) {
+                //单独保存报告表 查询记录表pdf是否有值 如果有值就合并 合并存到pdf_url
+                updateSql = getUpdateSql(dto, pdfURL, listPdf, snowId, "record_pdf_url", 2, "report_pdf_url");
+            } else {
+                //一起保存的数据  只改变pdf_url
+                this.update(Wrappers.<TrialSelfInspectionRecord>lambdaUpdate().set(TrialSelfInspectionRecord::getPdfUrl, pdfURL).eq(TrialSelfInspectionRecord::getId, dto.getId()));
+            }
+            if (ObjectUtil.isNotEmpty(updateSql)) {
+                jdbcTemplate.execute(updateSql);
+            }
         } else if (pdfURL.equals("500")) {
             throw new ServiceException("试验填报保存操作失败");
         }
     }
 
+    @NotNull
+    private String getUpdateSql(TrialSelfInspectionRecordDTO dto, String pdfURL, String listPdf, Long snowId,String param1,int type,String param2) {
+        String updateSql;
+        String sqlForAntherPDF = "SELECT "+param1+ " from u_trial_self_inspection_record where id =  " + dto.getId() + " and is_deleted = 0";
+        String AntherPDFUrl = jdbcTemplate.queryForObject(sqlForAntherPDF, new SingleColumnRowMapper<String>(String.class));
+        if(ObjectUtil.isNotEmpty(AntherPDFUrl)){
+            //合并后保存  把报告单合并在前面
+            if(type == 1){
+                FileUtils.mergePdfPublicMethods(Arrays.asList(AntherPDFUrl, pdfURL), listPdf);
+            }else {
+                FileUtils.mergePdfPublicMethods(Arrays.asList(pdfURL,AntherPDFUrl), listPdf);
+            }
+
+            BladeFile bladeFile = this.newIOSSClient.uploadFile(snowId + ".pdf", listPdf);
+            updateSql = "update u_trial_self_inspection_record set pdf_url = '" + bladeFile.getLink() + "',"+param2+ "= '"+ pdfURL + "' where id='" + dto.getId()+"'";
+            //合并后更新queryInfo表的pdfurl
+            String updateForQurtyInfo = "update u_information_query set pdf_url ='" + bladeFile.getLink() + "' where classify='" + dto.getType() + "' and  wbs_id='" + dto.getId() + "' and contract_id ='" + dto.getContractId() + "' ";
+            jdbcTemplate.execute(updateForQurtyInfo);
+        }else {
+            updateSql = "update u_trial_self_inspection_record set "+param2+" = '"+ pdfURL + "' where id='" + dto.getId()+"'";
+        }
+        return updateSql;
+    }
+
+
     public boolean recordSampleSubmit(TrialSelfInspectionRecordDTO dto1, TrialSelfInspectionRecord obj) {
         RecordSampleSubmitDTO dto = new RecordSampleSubmitDTO();
         dto.setId(obj.getId());

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

@@ -62,6 +62,12 @@
             <artifactId>commons.codec</artifactId>
             <version>1.10</version>
         </dependency>
+        <dependency>
+            <groupId>com.itextpdf</groupId>
+            <artifactId>itextpdf</artifactId>
+            <version>5.5.13</version>
+            <scope>compile</scope>
+        </dependency>
         <dependency>
             <groupId>com.e.visa</groupId>
             <artifactId>commons.compress</artifactId>
@@ -147,6 +153,11 @@
             <artifactId>paperless.http.framework</artifactId>
             <version>4.6.0.2</version>
         </dependency>
+        <dependency>
+            <groupId>commons-net</groupId>
+            <artifactId>commons-net</artifactId>
+            <version>3.8.0</version>
+        </dependency>
         <dependency>
             <groupId>com.e.visa</groupId>
             <artifactId>paperless.sadk.ext</artifactId>
@@ -197,6 +208,11 @@
             <groupId>org.springframework</groupId>
             <artifactId>spring-test</artifactId>
         </dependency>
+        <dependency>
+            <groupId>commons-net</groupId>
+            <artifactId>commons-net</artifactId>
+            <version>3.8.0</version>
+        </dependency>
         <dependency>
             <groupId>org.apache.pdfbox</groupId>
             <artifactId>pdfbox</artifactId>

+ 35 - 25
blade-service/blade-e-visa/src/main/java/org/springblade/evisa/controller/EVisaJLController.java → blade-service/blade-e-visa/src/main/java/org/springblade/evisa/controller/EVController.java

@@ -9,6 +9,10 @@ import org.apache.commons.lang.StringUtils;
 import org.springblade.business.entity.Task;
 import org.springblade.business.feign.TaskClient;
 import org.springblade.business.vo.TaskApprovalVO;
+import org.springblade.business.vo.TaskSignInfoVO;
+import org.springblade.common.utils.SystemUtils;
+import org.springblade.core.tool.utils.Func;
+import org.springblade.evisa.service.EVDataService;
 import org.springblade.evisa.service.EVisaService;
 import org.springblade.evisa.vo.EVisaTaskApprovalVO;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -36,52 +40,63 @@ import java.util.concurrent.TimeUnit;
  */
 @RestController
 @AllArgsConstructor
-@RequestMapping("/evisaInfo")
 @Api(value = "电签类", tags = "电签类接口")
 @Slf4j
-public class EVisaJLController {
+public class EVController {
 
     @Autowired
     StringRedisTemplate RedisTemplate;
-
     // jdbc
     private final JdbcTemplate jdbcTemplate;
 
     //电签服务类
-    private final EVisaService eVisaService;
+    private final EVDataService evDataService;
 
     // 线程池
     @Resource(name = "taskExecutor1")
     private ThreadPoolExecutor executor;
 
-    private final TaskClient taskClient;
-
-    // 电签主类
+     @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=0 and id in(SELECT DISTINCT id from u_task_batch where  is_deleted=0 GROUP BY JSON_EXTRACT(json_data, '$.formDataId') ORDER BY sign_type ASC) LIMIT 10 ";
+
+        //String sql = "SELECT * from u_task_batch where is_deleted=0 and id=1871438158680403970 ORDER BY sign_type ASC ";
+
         List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql);
-        if (maps != null && maps.size() >= 1 ) {//&& SystemUtils.isLinux()
+        if (maps != null && maps.size() >= 1 ) {
             for (Map<String, Object> dataInfo : maps) {
-                if (executor.getQueue().size()<=40 ) {
+                if (executor.getQueue().size()<=6 ) {
                     String jsonData = dataInfo.get("json_data") + "";
-                    TaskApprovalVO taskApprovalVO = JSON.parseObject(jsonData, TaskApprovalVO.class);
+                    String signFormat = dataInfo.get("sign_format") + "";
+                    String sigType = dataInfo.get("sign_type") + "";
+                    TaskSignInfoVO taskSignInfoVO = JSON.parseObject(jsonData, TaskSignInfoVO.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);
-
+                    Boolean aBoolean = RedisTemplate.hasKey("sign-" + taskSignInfoVO.getFormDataId());
+                    taskSignInfoVO.setId(taskBatchId);
+                    taskSignInfoVO.setUserId(userId);
+                    taskSignInfoVO.setNickName(nickName);
+                    taskSignInfoVO.setSignFormat(signFormat);
+                    if(sigType.equals("2")){
+                        taskSignInfoVO.setSigType(2);
+                      String sql12 = "SELECT a.* from u_task a,u_task_parallel b where a.process_instance_id=b.process_instance_id and b.initiative=1 and  a.is_deleted=0 and b.is_deleted=0 and a.`status` in(1,2) and a.id="+taskSignInfoVO.getTaskId()+"";
+                      List<Map<String, Object>> maps12 = jdbcTemplate.queryForList(sql12);
+                      if(maps12!=null && maps12.size()>=1){
+                          jdbcTemplate.execute("delete from u_task_batch where id="+taskBatchId+"");
+                          aBoolean = true;
+                      }
+                    }else{
+                        taskSignInfoVO.setSigType(1);
+                    }
                     if (!aBoolean) {
-                        RedisTemplate.opsForValue().set("sign-" + taskApprovalVO.getFormDataId(), "1",1800, TimeUnit.SECONDS);
+                        RedisTemplate.opsForValue().set("sign-" + taskSignInfoVO.getFormDataId(), "1",1800, TimeUnit.SECONDS);
                         CompletableFuture<Void> runAsync = CompletableFuture.runAsync(() -> {
                             try {
                                 /*===============执行批量任务===============*/
-                                this.checkIsExsitTaskBatch(taskApprovalVO);
+                                evDataService.signTaskBatch(taskSignInfoVO);
                             } catch (Exception e) {
                                 e.printStackTrace();
                             }
@@ -90,15 +105,10 @@ public class EVisaJLController {
                 }
             }
         }
+
         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){
-
-    }
-
 }

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

@@ -61,14 +61,11 @@ public class EVisaController {
 
     // 电签主类
 
-    @Scheduled(cron = "0/30 * * * * ?")
+   // @Scheduled(cron = "0/10 * * * * ?")
     public void SignInfo() {
         //执行代码
-
         log.info("扫描开始");
-       // String sql = "SELECT * from u_task_batch where json_data like '%1840658122872455168%' a
-        // nd is_deleted<>5  LIMIT 10";
-        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=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()
@@ -85,7 +82,7 @@ public class EVisaController {
                     taskApprovalVO.setNickName(nickName);
 
                     if (!aBoolean) {
-                        RedisTemplate.opsForValue().set("sign-" + taskApprovalVO.getFormDataId(), "1",1800, TimeUnit.SECONDS);
+                        RedisTemplate.opsForValue().set("sign-" + taskApprovalVO.getFormDataId(), "1",900, TimeUnit.SECONDS);
                         CompletableFuture<Void> runAsync = CompletableFuture.runAsync(() -> {
                             try {
                                 /*===============执行批量任务===============*/
@@ -112,7 +109,6 @@ public class EVisaController {
 
             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();
@@ -178,9 +174,7 @@ public class EVisaController {
                     }
                 }
             }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()+"'";
@@ -206,7 +200,6 @@ public class EVisaController {
                 jdbcTemplate.execute("update u_information_query set e_visa_pdf_url='',status=0 where id='"+taskApprovalVO.getFormDataId()+"'");
             }
             RedisTemplate.delete("sign-" + taskApprovalVO.getFormDataId());
-
         }
     }
 

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

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

+ 16 - 0
blade-service/blade-e-visa/src/main/java/org/springblade/evisa/service/EVDataService.java

@@ -0,0 +1,16 @@
+package org.springblade.evisa.service;
+
+import cfca.paperless.dto.bean.CertBean;
+import org.springblade.business.vo.TaskApprovalVO;
+import org.springblade.business.vo.TaskSignInfoVO;
+import org.springblade.core.tool.api.R;
+import org.springblade.evisa.vo.EVisaMakeSealVO;
+import org.springblade.evisa.vo.EVisaTaskApprovalVO;
+import org.springblade.evisa.vo.SealPdfVO;
+
+import java.util.List;
+
+public interface EVDataService {
+
+   void signTaskBatch(TaskSignInfoVO taskSignInfoVO);
+}

+ 6 - 0
blade-service/blade-e-visa/src/main/java/org/springblade/evisa/service/EVisaService.java

@@ -6,6 +6,7 @@ import org.springblade.evisa.vo.EVisaMakeSealVO;
 import org.springblade.evisa.vo.EVisaTaskApprovalVO;
 import org.springblade.evisa.vo.SealPdfVO;
 
+import java.util.HashMap;
 import java.util.List;
 
 public interface EVisaService {
@@ -45,4 +46,9 @@ public interface EVisaService {
      */
     R<String> batchEVisa(SealPdfVO pdfVO);
 
+    Object[] signPdfByAXQZ(SealPdfVO pdfVO, byte[] fileByte);
+
+    Object[] signPdfByAXQZ(SealPdfVO pdfVO, String loPdfurl,String outPdfUrl);
+
+    String signPdfByDFZX(HashMap<String, Object> daMa);
 }

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

@@ -0,0 +1,712 @@
+package org.springblade.evisa.service.impl;
+
+
+import cfca.paperless.base.util.Base64;
+import cn.hutool.core.io.file.FileReader;
+import lombok.AllArgsConstructor;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang.StringUtils;
+import org.springblade.business.entity.InformationQuery;
+import org.springblade.business.entity.TrialSelfInspectionRecord;
+import org.springblade.business.feign.TaskClient;
+import org.springblade.business.vo.TaskSignInfoVO;
+import org.springblade.business.vo.TrialRawMaterialSelfRecord;
+import org.springblade.common.constant.CommonConstant;
+import org.springblade.common.constant.EVisaConstant;
+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.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.evisa.service.EVDataService;
+import org.springblade.evisa.service.EVisaService;
+import org.springblade.evisa.utils.FileUtils;
+import org.springblade.evisa.utils.PDFUtils;
+import org.springblade.evisa.utils.SignFtpUtil;
+import org.springblade.evisa.vo.SealPdfVO;
+import org.springblade.evisa.vo.SealStrategyVO;
+import org.springblade.manager.entity.ProjectInfo;
+import org.springblade.manager.feign.ProjectClient;
+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.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+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.stream.Collectors;
+
+@Service
+@AllArgsConstructor
+public class EVDataServiceImpl implements EVDataService {
+
+    //jdbc对象
+    private final JdbcTemplate jdbcTemplate;
+    private final ProjectClient projectClient;
+    private final TaskClient taskClient;
+    private final NewIOSSClient newIOSSClient;
+    //电签服务类
+    private final EVisaService eVisaService;
+
+    @Autowired
+    StringRedisTemplate RedisTemplate;
+    @Autowired
+    private StartEventListener startEventListener;
+
+    /**
+     * 电签主要流程
+     *
+     * @param taskApp
+     */
+    @Override
+    public void signTaskBatch(TaskSignInfoVO taskApp) {
+        //获取pdf 文件
+        this.getSignPdfInfo(taskApp);
+        this.addSignatureTaskBatch(taskApp);
+        if (taskApp.getSigState() != 1) {
+            return;
+        }
+
+        String fileUrl = CommonUtil.replaceOssUrl(taskApp.getSignPdfUrl());
+        List<String> eVisaConfigList = PDFUtils.getPdfSignIds(fileUrl, taskApp);
+        if (eVisaConfigList == null || eVisaConfigList.size() == 0) {
+            //没有电签配置,默认当前任务为不签字审批,返回成功
+            taskApp.setSigState(2);
+            taskApp.setSignSmg("pdf未获取到关键字Id");
+            SignBackPdfInfo(taskApp);
+            return;
+        }
+        // 获取pdf上的电签Ids
+        String ids = String.join(",", eVisaConfigList);
+        if (taskApp.getRemarkType().equals("1")) { //安心签
+            //添加电签策略
+            List<SealStrategyVO> strategyListByAXQ = getStrategyListByAXQ(taskApp, ids);
+            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){
+                    taskApp.setSigState(2);
+                    taskApp.setSignSmg("未获取到签字证书信息");
+                }else{
+                    if(taskApp.getSigType()==1){
+                        taskApp.setSigState(2);
+                        taskApp.setSignSmg("未获取到签字证书信息");
+                    }else if(taskApp.getSigType()==2){
+                        taskApp.setSigState(1);
+                        taskApp.setSignSmg("签字成功");
+                        taskApp.setLastFilePdfUrl(taskApp.getSignPdfUrl());
+                    }
+                }
+                SignBackPdfInfo(taskApp);
+                return;
+            }
+
+            //调用签字逻辑
+            signTaskBatchByAXQZ(strategyListByAXQ, taskApp);
+            if (taskApp.getSigState() != 1) {
+                return;
+            }
+            // 回归处理
+            SignBackPdfInfo(taskApp);
+            if (taskApp.getSigState() != 1) {
+                return;
+            }
+        } else if (taskApp.getRemarkType().equals("2")) { //东方中讯
+            //添加电签策略
+            List<Map<String, Object>> strategyListByDFZX = getStrategyListByDFZX(taskApp, ids);
+            //调用签字逻辑
+            String s = signTaskBatchByDFZX(strategyListByDFZX, fileUrl,taskApp.getSigType());
+            if (s.contains("sucess")) {
+                taskApp.setLastFilePdfUrl(s.split("@@@@")[1]);
+                taskApp.setSigState(1);
+                taskApp.setSignSmg("电签成功");
+            } else {
+                taskApp.setSigState(2);
+                taskApp.setSignSmg("电签中失败");
+                SignBackPdfInfo(taskApp);
+            }
+            // 回归处理
+            SignBackPdfInfo(taskApp);
+        }
+    }
+
+
+    public void addSignatureTaskBatch(TaskSignInfoVO taskApp) {
+        if(taskApp.getSigType()==1){
+            String sql = "SELECT * from u_task_batch where JSON_EXTRACT(json_data, '$.taskId')="+taskApp.getTaskId()+" and sign_type=2";
+            List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql);
+            String id = SnowFlakeUtil.getId()+"";
+            if(maps==null || maps.size()==0){
+                String sql2 ="INSERT into u_task_batch(id,task_parallel_id,json_data,create_user,create_dept,create_time,update_user,update_time,status,is_deleted,nick_name,sign_format,sign_type)" +
+                        "SELECT "+id+" as id,task_parallel_id,json_data,create_user,create_dept,create_time,update_user,update_time,status,is_deleted,nick_name,sign_format,2 as sign_type from u_task_batch where id="+taskApp.getId()+"";
+                jdbcTemplate.execute(sql2);
+            }
+        }
+    }
+
+    // 获取pdf 文件
+    @Transactional
+    public void SignBackPdfInfo(TaskSignInfoVO taskApp) {
+        Integer totalCount = this.jdbcTemplate.queryForObject("select exe_count from u_task_parallel where parallel_process_instance_id='" + taskApp.getParallelProcessInstanceId() + "'", Integer.class);
+        //上报类型: 1填报资料,2工程文件,3日志资料
+        //档案:4档案数据 ,
+        //计量: 5中间计量申请,6材料计量单 ,7开工预付款计量单, 8变更令
+        try {
+            //电签成功
+            if (taskApp.getSigState() == 1) { //签字成功
+                String updateSql = "";
+                if (taskApp.getApprovalType() == 1) { //
+                    //
+                    String sys_isonline = ParamCache.getValue(CommonConstant.SYS_ISONLINE);
+                    String pdfPage = "0";
+                    Long pdfSize = 0L;
+                    String nodePdfUrl = "";
+
+                    List<Map<String, Object>> mapList = jdbcTemplate.queryForList("select *,domain_url as url from m_table_file where is_deleted = 0 and type in (10,11,12) and tab_id = (select wbs_id from u_information_query WHERE id = + " + taskApp.getFormDataId() + ")");
+                    if (Func.isNotEmpty(mapList) && mapList.size() >= 1) {
+                        String file_path = FileUtils.getSysLocalFileUrl();
+                        List<String> datainfo = new ArrayList<>();
+                        datainfo.add(taskApp.getLastFilePdfUrl());
+                        for (Map<String, Object> tabsx : mapList) {
+                            datainfo.add(tabsx.get("url") + "");
+                        }
+                        String listPdf = file_path + "/nodePDF/" + taskApp.getFormDataId() + ".pdf";
+                        File tabpdf2 = ResourceUtil.getFile(listPdf);
+                        if (tabpdf2.exists()) {
+                            tabpdf2.delete();
+                        }
+
+                        FileUtils.mergePdfPublicMethods(datainfo, listPdf);
+                        if("20".equals(sys_isonline) || SystemUtils.isWindows() || SystemUtils.isMacOs()){
+                            BladeFile bladeFile = this.newIOSSClient.uploadFile(taskApp.getFormDataId() + ".pdf", listPdf);
+                            if (bladeFile != null && Func.isNotEmpty(bladeFile.getLink())) {
+                                nodePdfUrl = bladeFile.getLink();
+                            }
+                        } else {
+                            nodePdfUrl = FileUtils.getNetUrl(listPdf);
+                        }
+
+                    } else {
+                        nodePdfUrl = taskApp.getLastFilePdfUrl();
+                    }
+
+                    pdfPage = FileUtils.getPdfNum(nodePdfUrl);
+                    pdfSize = CommonUtil.getResourceLength(nodePdfUrl);
+
+                    // 实验时
+                    String pdfTrialUrlPosition = "";
+                    if ("2".equals(taskApp.getPdfDataType())) {
+                        String taskStatus = "";
+                        if (taskApp.getSigState() == 1 && taskApp.getSigType()==1) {
+                            taskStatus = "待审批";
+                        } else if (taskApp.getSigState() == 1 && taskApp.getSigType()==2) {
+                            taskStatus = "已审批";
+                        } 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() + "')";
+                        jdbcTemplate.execute(updTrial);
+
+                        /**
+                         * 在资料填报工序-预览全部pdf时再拼接合并显示,当前只做储存(如果当前资料填报工序节点有其他多个试验记录pdf关联信息,那么合并存储,否则直接存储)
+                         */
+
+                        String redoe = " select * from  u_trial_self_inspection_record 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() + "')";
+                        TrialSelfInspectionRecord record = jdbcTemplate.query(redoe, new BeanPropertyRowMapper<>(TrialSelfInspectionRecord.class)).stream().findAny().orElse(null);
+                        if (("已审批").equals(record.getTaskStatus()) && (new Integer(1)).equals(record.getDetectionResult()) && (new Integer(1)).equals(record.getDetectionCategory())) {
+                            if (com.baomidou.mybatisplus.core.toolkit.StringUtils.isNotEmpty(record.getProjectPosition())) {
+                                //有pdf的节点
+                                String sqlNodeAll = "select wbs_id from u_information_query where wbs_id in(" + record.getProjectPosition() + ") and contract_id = " + record.getContractId();
+                                List<Long> collect = jdbcTemplate.query(sqlNodeAll, new BeanPropertyRowMapper<>(InformationQuery.class)).stream().map(InformationQuery::getWbsId).collect(Collectors.toList());
+                                if (collect.size() > 0) {
+                                    //删除当前记录关联记录
+                                    jdbcTemplate.execute("delete from u_trial_self_quality_project where self_id = " + record.getId() + "");
+                                    for (Long pKeyId : collect) {
+                                        //新增当前记录关联信息
+                                        jdbcTemplate.execute("insert into u_trial_self_quality_project(id,self_id,quality_node_id) values(" + SnowFlakeUtil.getId() + "," + record.getId() + "," + pKeyId + ") ");
+
+                                        //获取当前工程部位节点最新的关联试验记录ids
+                                        String sqlIds = "select self_id from u_trial_self_quality_project where quality_node_id = '" + pKeyId + "'";
+                                        List<Map<String, Object>> trialRecordIds = jdbcTemplate.queryForList(sqlNodeAll);
+
+
+                                        //如果当前工程部位节点的关联试验记录id只有一条,且等于当前关联试验记录id,那么不合并,直接存储该条试验记录的pdf
+                                        if (trialRecordIds.size() == 1 && (trialRecordIds.get(0).get("self_id")).equals(record.getId().toString())) {
+                                            //修改当前试验pdf到质检树节点的pdf_trial_url_position上存储
+                                            pdfTrialUrlPosition = record.getPdfUrl();
+                                            continue;
+                                        }
+
+                                        //如果当前工程部位节点的关联试验记录id有多条,那么合并
+                                        String dataSql = "select * from  u_trial_self_inspection_record where id in(select self_id from u_trial_self_quality_project where quality_node_id = '" + pKeyId + "')";
+                                        List<TrialSelfInspectionRecord> pdfUrlList = jdbcTemplate.queryForList(redoe, TrialSelfInspectionRecord.class);
+                                        List<String> pdfS = pdfUrlList.stream().filter(f -> com.baomidou.mybatisplus.core.toolkit.StringUtils.isNotEmpty(f.getPdfUrl())).map(TrialSelfInspectionRecord::getPdfUrl).collect(Collectors.toList());
+                                        if (ObjectUtil.isNotEmpty(pdfS) && pdfS.size() > 0) {
+                                            String filePath = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
+                                            String listPdf = filePath + "/pdf/" + pKeyId + ".pdf";
+                                            File tabPDF = ResourceUtil.getFile(listPdf);
+                                            if (tabPDF.exists()) {
+                                                tabPDF.delete();
+                                            }
+
+                                            FileUtils.mergePdfPublicMethods(pdfS, listPdf);
+                                            BladeFile bladeFile = this.newIOSSClient.uploadFile(pKeyId + ".pdf", listPdf);
+                                            if (bladeFile != null) {
+                                                //修改合并的试验pdf到质检树节点的pdf_trial_url_position上存储
+                                                pdfTrialUrlPosition = bladeFile.getLink();
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                    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() + "' ";
+                } 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) { // 日志
+                    updateSql = "update u_contract_log set e_visa_pdf_url='" + taskApp.getLastFilePdfUrl() + "',status='" + taskApp.getSigType() + "',update_time=SYSDATE() where id='" + taskApp.getFormDataId() + "' ";
+                } else if (taskApp.getApprovalType() == 5) { //中期计量支付证书
+                    updateSql = "update s_interim_pay_certificate set approve_status=" + taskApp.getSigType() + ",update_time=SYSDATE(), raw_url='" + taskApp.getLastFilePdfUrl() + "' where contract_period_id = " + taskApp.getFormDataId();
+                } else if (taskApp.getApprovalType() == 6 || taskApp.getApprovalType() == 7) {
+                    updateSql = "update s_material_start_statement set raw_url='" + taskApp.getLastFilePdfUrl() + "' where meter_period_id = " + taskApp.getFormDataId();
+                } else if (taskApp.getApprovalType() == 8) {
+                    if (taskApp.getSigType() == 2) {
+                        this.jdbcTemplate.execute("update u_entrust_info set sample_status=2,status=" + (taskApp.getSigType() + 1) + ",entrust_e_pdf='" + taskApp.getLastFilePdfUrl() + "' where id=(SELECT wbs_id from u_information_query where id='" + taskApp.getFormDataId() + "')");
+                    }
+                    updateSql = "update u_information_query set e_visa_pdf_url='" + taskApp.getLastFilePdfUrl() + "',status=" + taskApp.getSigType() + " where id='" + taskApp.getFormDataId() + "'";
+                }
+                this.jdbcTemplate.execute(updateSql);
+                this.jdbcTemplate.execute("update u_task_parallel set e_visa_status=1,e_visa_content='" + taskApp.getSignSmg() + "' , status=2 , initiative=2 ,update_time=SYSDATE() where parallel_process_instance_id='" + taskApp.getParallelProcessInstanceId() + "'");
+                this.jdbcTemplate.execute("update u_task set status=" + taskApp.getSigType() + " ,update_time=SYSDATE() where id='" + taskApp.getTaskId() + "'");
+                this.jdbcTemplate.execute("delete from u_task_batch where id=" + taskApp.getId());
+
+            } else { //签字失败
+                this.jdbcTemplate.execute("update u_task_parallel set exe_count=(exe_count+1), e_visa_status=99,e_visa_content='" + taskApp.getSignSmg() + "' ,update_time=SYSDATE() where parallel_process_instance_id='" + taskApp.getParallelProcessInstanceId() + "'");
+                this.jdbcTemplate.execute("update u_task set status=1 ,update_time=SYSDATE() where id='" + taskApp.getTaskId() + "'");
+                if (totalCount >= 3) {
+                    this.jdbcTemplate.execute("delete from u_task_batch where id=" + taskApp.getId());
+                }
+            }
+            RedisTemplate.delete("sign-" + taskApp.getFormDataId());
+        } catch (Exception e) {
+            taskApp.setSigState(2);
+            taskApp.setSignSmg("修改业务数据异常-请联系开发人员");
+            SignBackPdfInfo(taskApp);
+            e.printStackTrace();
+        }
+    }
+
+    // 获取pdf 文件
+    public void getSignPdfInfo(TaskSignInfoVO taskApp) {
+        //上报类型: 1填报资料,2工程文件,3日志资料
+        //档案:4档案数据 ,
+        //计量: 5中间计量申请,6材料计量单 ,7开工预付款计量单, 8变更令
+        taskApp.setSigState(1);
+        Map<String, Object> map = new HashMap<>();
+        try {
+            if (taskApp.getApprovalType() == 1 || taskApp.getApprovalType() == 8) {
+                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
+                String eVisaPdfUrl = map.get("e_visa_pdf_url") + ""; //签字的PDF路径
+                String pdfUrl = map.get("pdf_url") + ""; //合并后的PDF路径
+                String type = map.get("type") + ""; //资料类型,1资料填报,2试验,3首件
+                taskApp.setPdfDataType(type);
+                if (StringUtils.isNotEmpty(pdfTrialUrlPosition) || StringUtils.isNotEmpty(pdfTrialUrl) || StringUtils.isNotEmpty(eVisaPdfUrl) || StringUtils.isNotEmpty(pdfUrl)) {
+                    if ("1".equals(type)) {
+                        String approvalPdf = eVisaPdfUrl.length() >= 10 ? eVisaPdfUrl : pdfUrl;
+                        approvalPdf = pdfTrialUrl.length() >= 10 ? pdfTrialUrl : approvalPdf;
+                        approvalPdf = pdfTrialUrl.length() >= 10 ? pdfTrialUrlPosition : approvalPdf;
+                        taskApp.setSignPdfUrl(getHppsToHttp(approvalPdf));
+                    } else if ("2".equals(type)) {
+                        if (StringUtils.isNotEmpty(eVisaPdfUrl) || StringUtils.isNotEmpty(pdfUrl)) {
+                            //试验原始pdf
+                            String approvalPdf = eVisaPdfUrl.length() >= 10 ? eVisaPdfUrl : pdfUrl;
+                            taskApp.setSignPdfUrl(getHppsToHttp(approvalPdf));
+
+                            //试验关联的原材料检测报告合并pdf (wbsId=试验记录id)TrialSelfInspectionRecord
+                            String sqlRecord = "select old_pdf_url from u_trial_raw_material_self_record where self_record_id =" + map.get("wbs_id");
+                            TrialRawMaterialSelfRecord recordObj = jdbcTemplate.query(sqlRecord, new BeanPropertyRowMapper<>(TrialRawMaterialSelfRecord.class)).stream().findAny().orElse(null);
+                            if (recordObj != null) {
+                                if (StringUtils.isNotEmpty(recordObj.getOldPdfUrl())) {
+                                    taskApp.setSignPdfUrl(getHppsToHttp(approvalPdf));
+                                }
+                            }
+                        }
+                    } else if ("3".equals(type)) {
+                        //首件,首件的资料由三个部分组成:封面、关联资料、总结报告
+                        if (StringUtils.isNotEmpty(eVisaPdfUrl) || StringUtils.isNotEmpty(pdfUrl)) {
+                            String url = eVisaPdfUrl.length()>=10 ? eVisaPdfUrl : pdfUrl;
+                            String s = getHppsToHttp(url);
+                            taskApp.setSignPdfUrl(s);
+                        }
+                    }
+                }
+            } else if (taskApp.getApprovalType() == 2) { //档案
+                map = this.jdbcTemplate.queryForMap("select * from u_archive_file where is_deleted=0 and id =(" + taskApp.getFormDataId() + ")");
+                String eVisaPdfUrl = map.get("pdf_file_url") + ""; //签字的PDF路径
+                String pdfUrl = map.get("file_url") + ""; //合并后的PDF路径
+                if (StringUtils.isNotEmpty(eVisaPdfUrl) || StringUtils.isNotEmpty(pdfUrl)) {
+                    String url = eVisaPdfUrl.length()>=10 ? eVisaPdfUrl : pdfUrl;
+                    taskApp.setSignPdfUrl(url);
+                }
+            } else if (taskApp.getApprovalType() == 3) {
+                map = this.jdbcTemplate.queryForMap("select * from u_contract_log where  is_deleted=0 and id = " + taskApp.getFormDataId());
+                String eVisaPdfUrl = map.get("e_visa_pdf_url") + ""; //签字的PDF路径
+                String pdfUrl = map.get("pdf_url") + ""; //合并后的PDF路径
+                if (StringUtils.isNotEmpty(eVisaPdfUrl) || StringUtils.isNotEmpty(pdfUrl)) {
+                    String url = eVisaPdfUrl.length()>=10 ? eVisaPdfUrl : pdfUrl;
+                    taskApp.setSignPdfUrl(url);
+                }
+            } else if (taskApp.getApprovalType() == 4) { //档案走自定义 搓章的问题
+
+            } else if (taskApp.getApprovalType() == 5) {
+                map = this.jdbcTemplate.queryForMap("select * from s_interim_pay_certificate where  is_deleted=0 and contract_period_id = " + taskApp.getFormDataId());
+                taskApp.setSignPdfUrl(map.get("raw_url") + "");
+
+            } 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());
+                taskApp.setSignPdfUrl(map.get("raw_url") + "");
+            }
+
+
+            // 验证数据
+            taskApp.setContractId(map.get("contract_id") + "");
+            taskApp.setProjectId(map.get("project_id") + "");
+            if (taskApp.getSignPdfUrl() == null || taskApp.getSignPdfUrl() == "" || Func.isEmpty(taskApp.getSignPdfUrl()) || taskApp.getSignPdfUrl().length() <= 10) {
+                taskApp.setSigState(2);
+                taskApp.setSignSmg("未获取到PDF信息");
+                SignBackPdfInfo(taskApp);
+                return;
+            }
+            if (taskApp.getContractId() == null || taskApp.getContractId() == "" || Func.isEmpty(taskApp.getContractId()) || taskApp.getContractId().length() <= 10) {
+                taskApp.setSigState(2);
+                taskApp.setSignSmg("未获取到合同段Id");
+                SignBackPdfInfo(taskApp);
+                return;
+            }
+            if (taskApp.getProjectId() == null || taskApp.getProjectId() == "" || Func.isEmpty(taskApp.getProjectId()) || taskApp.getProjectId().length() <= 10) {
+                taskApp.setSigState(2);
+                taskApp.setSignSmg("未获取项目Id");
+                SignBackPdfInfo(taskApp);
+                return;
+            }
+            ProjectInfo projectInfo = projectClient.getById(taskApp.getProjectId());
+            if (projectInfo == null || Func.isEmpty(projectInfo)) {
+                taskApp.setSigState(2);
+                taskApp.setSignSmg("未获取项目信息");
+                SignBackPdfInfo(taskApp);
+                return;
+            } else {
+                Integer remarkType = projectInfo.getRemarkType();
+                if (remarkType != null && Func.isNotEmpty(remarkType) && remarkType == 2) {
+                    taskApp.setRemarkType("2");
+                } else {
+                    taskApp.setRemarkType("1");
+                }
+            }
+        } catch (Exception e) {
+            taskApp.setSigState(2);
+            taskApp.setSignSmg("获取pdf信息异常");
+            SignBackPdfInfo(taskApp);
+            return;
+        }
+    }
+
+    // 添加电签策略 -- 东方中讯
+    public List<Map<String, Object>> getStrategyListByDFZX(TaskSignInfoVO task, String ids) {
+
+        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=" + task.getContractId() + " and user_id=" + task.getUserId() + " and c.is_deleted=0 ) ) x where x.sealId is not null ";
+        if (task.getSigType() == 2) {
+            sqlinfo = "SELECT a.id as keyWord,a.pyzbx,a.pyzby,b.certificate_number as sealId from m_textdict_info a ,m_sign_pfx_file b where a.sig_role_id = b.pfx_type and b.project_contract_role like '%" + task.getContractId() + "%' and a.is_deleted=0 and b.is_deleted=0 and a.type=6 and a.id in(" + ids + ")";
+            System.out.println("东方中讯--签章--"+sqlinfo);
+        }else{
+            System.out.println("东方中讯--签字--"+sqlinfo);
+        }
+
+        List<Map<String, Object>> maps2 = jdbcTemplate.queryForList(sqlinfo);
+        List<Map<String, Object>> maps = new ArrayList<>();
+        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));
+            }
+        }
+        return maps;
+    }
+
+    // 添加电签策略 -- 安心签
+    public List<SealStrategyVO> getStrategyListByAXQ(TaskSignInfoVO task, String ids) {
+        List<SealStrategyVO> sealStrategyVOS = new ArrayList<>();
+        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='" + task.getUserId() + "' and is_deleted=0  ) as signature_file_url 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=" + task.getUserId() + " and c.is_deleted=0 ) ) x where x.signature_file_url is not null ";
+        if (task.getSigType() == 2) {
+            sqlinfo = "SELECT a.id,a.pyzbx,a.pyzby,b.signature_file_url,b.id as sfId,a.project_id,b.certificate_password,b.certificate_user_name,b.certificate_number from m_textdict_info a ,m_sign_pfx_file b where a.sig_role_id = b.pfx_type and b.project_contract_role like '%" + task.getContractId() + "%' and a.is_deleted=0 and b.is_deleted=0 and a.type=6 and a.id in(" + ids + ")";
+            System.out.println("安心签--签章--=" + sqlinfo);
+        }else{
+            System.out.println("安心签--签字--=" + sqlinfo);
+        }
+        List<Map<String, Object>> maps2 = jdbcTemplate.queryForList(sqlinfo);
+        if (maps2 == null && maps2.size() <= 0) {
+            return sealStrategyVOS;
+        }
+
+        List<Map<String, Object>> maps = new ArrayList<>();
+        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 (maps == null || maps.size() <= 0) {
+            return sealStrategyVOS;
+        }
+        //准备签章策略
+
+        for (Map<String, Object> eVisaConfig : maps) {
+            //设置签章策略
+            SealStrategyVO vo = new SealStrategyVO();
+            if (task.getSigType() == 1) {
+                String userId = task.getUserId() + "";
+                vo.setSealCode(EVisaConstant.SIGN_SEAL_CODE + userId);
+                if (userId.length() <= EVisaConstant.USER_ID_SUB) {
+                    vo.setSealPassword(task.getUserId().toString());
+                } else {
+                    vo.setSealPassword(task.getUserId().toString().substring(0, EVisaConstant.USER_ID_SUB));
+                }
+                vo.setSealPerson(task.getNickName());
+                //设置签字文件
+                vo.setImageUrl(eVisaConfig.get("signature_file_url") + "");
+                vo.setSealType("3");
+                vo.setKeyword(eVisaConfig.get("id") + "");
+                vo.setOffSetX(eVisaConfig.get("pyzbx") + "");
+                vo.setOffSetY(eVisaConfig.get("pyzby") + "");
+            } else if (task.getSigType() == 2) {
+                vo.setSealCode(EVisaConstant.SIGN_SEAL_CODE + eVisaConfig.get("sfId"));
+                vo.setSealPassword(eVisaConfig.get("certificate_password") + "");
+                vo.setSealPerson(eVisaConfig.get("certificate_user_name") + "" + System.currentTimeMillis());
+                //设置签字文件
+                vo.setImageUrl(eVisaConfig.get("signature_file_url") + "");
+                vo.setSealType("3");
+                vo.setCompanySeal(true);
+                vo.setKeyword(eVisaConfig.get("id") + "");
+                vo.setOffSetX(eVisaConfig.get("pyzbx") + "");
+                vo.setOffSetY(eVisaConfig.get("pyzby") + "");
+            }
+            sealStrategyVOS.add(vo);
+        }
+        return sealStrategyVOS;
+    }
+
+    // 添加电签策略 -- 东方中讯
+    public String signTaskBatchByDFZX(List<Map<String, Object>> maps, String pdfUrl,int type) {
+        if (maps != null && maps.size() > 0) {
+            String fileUrl = pdfUrl;
+            for (Map<String, Object> dataMap : maps) {
+                HashMap<String, Object> daMa = new HashMap<>();
+                daMa.put("keyWord", dataMap.get("keyWord"));
+                daMa.put("sealId", dataMap.get("sealId"));
+                // 设置图片显示大小
+                if(type!=2){ //章
+                    daMa.put("showHeight", 30);
+                    daMa.put("showWidth", 60);
+                }
+                //设置显示签字体的位置
+                String yzx = dataMap.get("pyzby") + "";
+                String xzx = dataMap.get("pyzbx") + "";
+                Double sealOffsetY = Func.toDouble(yzx) - 15;
+                Double sealOffsetX = Func.toDouble(xzx) - 30;
+                daMa.put("sealOffsetX", sealOffsetX);
+                daMa.put("sealOffsetY", sealOffsetY);
+                byte[] fileByte = new byte[0];
+                if (fileUrl.indexOf("aliyuncs.com") >= 0 || fileUrl.indexOf("183.247.216.148") >= 0 || fileUrl.indexOf("152.168.2.15") >= 0) {
+                    try {
+                        InputStream inputStreamByUrl = FileUtils.getInputStreamByUrl(pdfUrl);
+                        fileByte = IOUtils.toByteArray(inputStreamByUrl);
+                    } catch (Exception e) {
+                        System.out.println("123");
+                    }
+                } else {
+                    FileReader fileReader = new FileReader(fileUrl);
+                    fileByte = fileReader.readBytes();
+                }
+
+                try {
+                    String originalFileB64 = Base64.toBase64String(fileByte);
+                    daMa.put("fileB64", originalFileB64);
+                    daMa.put("lastSignFlag", false);
+                } catch (Exception e) {
+                    throw new RuntimeException(e);
+                }
+                String reData = eVisaService.signPdfByDFZX(daMa);
+                if (reData.indexOf("success@") >= 0) {
+                    fileUrl = reData.split("@@@@")[1];
+                } else {
+                    return reData;
+                }
+            }
+            if (fileUrl.indexOf("aliyuncs.com") >= 0) {
+                System.out.println("电签失败");
+            } else {
+                BladeFile bladeFile = this.newIOSSClient.uploadFile(fileUrl.substring(fileUrl.lastIndexOf("/") + 1, fileUrl.length()), fileUrl);
+                if (bladeFile != null) {
+                    System.out.println("pdf上传=" + bladeFile.getLink());
+                    return "sucess@@@@" + bladeFile.getLink();
+                } else {
+                    return "电签成功";
+                }
+            }
+        } else {
+            return "sucess@@@@" + pdfUrl;
+        }
+        return "sucess@@@@" + pdfUrl;
+    }
+
+    // 安心签 - 关键字策略
+    public void signTaskBatchByAXQZ(List<SealStrategyVO> list, TaskSignInfoVO taskApp) {
+
+        String pdfUrl = Func.notNull(taskApp.getLastFilePdfUrl()) ? taskApp.getLastFilePdfUrl() : taskApp.getSignPdfUrl();
+
+        if (Func.isEmpty(pdfUrl) || list == null) {
+            taskApp.setLastFilePdfUrl(pdfUrl);
+        }
+        String sysLocalFileUrl = FileUtils.getSysLocalFileUrl();
+        String filecode = SnowFlakeUtil.getId() + "";
+        String dataFileUrl = sysLocalFileUrl + "/pdf/" + filecode + ".pdf";
+
+        SealPdfVO pdfVO = new SealPdfVO();
+        pdfVO.setStrategyVoList(list);
+        byte[] fileByte;
+        if (pdfUrl.indexOf("aliyuncs.com") >= 0 || pdfUrl.indexOf("183.247.216.148") >= 0 || pdfUrl.indexOf("152.168.2.15") >= 0) {
+            try {
+                InputStream inputStreamByUrl = CommonUtil.getOSSInputStreamTow(pdfUrl);
+                fileByte = IOUtils.toByteArray(inputStreamByUrl);
+            } catch (Exception e) {
+                taskApp.setSigState(2);
+                taskApp.setSignSmg("获取PDF字符流失败");
+                SignBackPdfInfo(taskApp);
+                return;
+            }
+        } else {
+            FileReader fileReader = new FileReader(pdfUrl);
+            fileByte = fileReader.readBytes();
+        }
+
+        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();
+            SignFtpUtil.FTPCreateDir(inUrl);
+            SignFtpUtil.FTPCreateDir(outUrl);
+            String locPdfUrl = inUrl + "/" + filecode + ".pdf";
+            String OutPdfUrl = outUrl + "/" + filecode + ".pdf";
+            SignFtpUtil.FTPDeleteDir(locPdfUrl);
+            SignFtpUtil.FTPDeleteDir(OutPdfUrl);
+
+            InputStream inputStream = new ByteArrayInputStream(fileByte);
+            int i = SignFtpUtil.uploadFile(locPdfUrl, inputStream);
+            if (i == 1) {
+                result = eVisaService.signPdfByAXQZ(pdfVO, locPdfUrl, OutPdfUrl);
+                int i1 = SignFtpUtil.downloadFile(dataFileUrl, OutPdfUrl);
+                fileUrl = dataFileUrl;
+                SignFtpUtil.FTPDeleteDir(locPdfUrl);
+                SignFtpUtil.FTPDeleteDir(OutPdfUrl);
+            }
+        } else {
+            result = eVisaService.signPdfByAXQZ(pdfVO, fileByte);
+            //执行电签
+            if (result != null) {
+                try {
+                    ByteArrayInputStream inputStream = new ByteArrayInputStream((byte[]) result[0]);
+                    FileOutputStream fout = new FileOutputStream(dataFileUrl);
+                    int bytesRead = 0;
+                    byte[] buffer = new byte[8192];
+                    while ((bytesRead = inputStream.read(buffer, 0, 8192)) != -1) {
+                        fout.write(buffer, 0, bytesRead);
+                    }
+                    fout.close();
+                    fileUrl = dataFileUrl;
+                } catch (Exception e) {
+                    taskApp.setSigState(2);
+                    taskApp.setSignSmg("二进制流读取本地失败");
+                    SignBackPdfInfo(taskApp);
+                    return;
+                }
+            }
+        }
+
+        if (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);
+            return;
+        } else {
+            BladeFile bladeFile = this.newIOSSClient.uploadFile(SnowFlakeUtil.getId() + ".pdf", fileUrl);
+            if (bladeFile != null) {
+                taskApp.setLastFilePdfUrl(bladeFile.getLink());
+                taskApp.setSignSmg("电签成功");
+            } else {
+                taskApp.setSigState(2);
+                taskApp.setSignSmg("上传OSS失败" + fileUrl);
+                SignBackPdfInfo(taskApp);
+                System.out.println("上传OSS失败");
+                return;
+            }
+        }
+    }
+
+    public String getHppsToHttp(String url) {
+        String sys_isonline = ParamCache.getValue(CommonConstant.SYS_ISONLINE);
+        if (Func.isNotEmpty(sys_isonline) &&url.contains("https:") && sys_isonline.equals("20")) {
+            return url.replace("https:", "http:");
+        }
+        return url;
+    }
+
+
+}

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

@@ -44,6 +44,7 @@ import org.springblade.common.constant.CommonConstant;
 import org.springblade.common.constant.EVisaConstant;
 import org.springblade.common.utils.CommonUtil;
 import org.springblade.common.utils.SnowFlakeUtil;
+import org.springblade.common.utils.SystemUtils;
 import org.springblade.core.log.exception.ServiceException;
 import org.springblade.core.oss.model.BladeFile;
 import org.springblade.core.secure.utils.AuthUtil;
@@ -95,8 +96,7 @@ import java.util.stream.Collectors;
 @AllArgsConstructor
 public class EVisaServiceImpl implements EVisaService {
 
- //   private static final String SIGN_HOST = "172.30.224.79";
-    private static final String SIGN_HOST = "47.115.117.246";
+    private static String SIGN_HOST = "172.30.224.79";
 
     private static final String SIGN_PORT = "8183";
 
@@ -410,15 +410,20 @@ public class EVisaServiceImpl implements EVisaService {
             taskFile = this.taskClient.queryBusinessDataTask(JSONObject.parseObject(JSONObject.toJSONString(task), TaskApprovalVO.class));
         } else if ( task.getApprovalType()>=5) {
            // 计量任务类型  5 = 中间计量申请,6 = 材料计量单,7 = 开工预付款计量单,8 = 变更令
-            Map<String, Object> map =new HashMap<>();
-            if(task.getApprovalType()==6 || task.getApprovalType()==7){
-                map = this.jdbcTemplate.queryForMap("select * from  s_material_start_statement where is_deleted=0 and meter_period_id = " + task.getFormDataId());
-                taskFile.setApprovalFileList(map.get("period_number")+"", map.get("raw_url")+"");
-            }else if (task.getApprovalType()==5) {
-                map = this.jdbcTemplate.queryForMap("select * from s_interim_pay_certificate where  is_deleted=0 and contract_period_id = " + task.getFormDataId());
-                taskFile.setApprovalFileList(map.get("period_number")+"", map.get("raw_url")+"");
+            try {
+                Map<String, Object> map = new HashMap<>();
+                if (task.getApprovalType() == 6 || task.getApprovalType() == 7) {
+                    map = this.jdbcTemplate.queryForMap("select * from  s_material_start_statement where is_deleted=0 and meter_period_id = " + task.getFormDataId());
+                    taskFile.setApprovalFileList(map.get("period_number") + "", map.get("raw_url") + "");
+                } else if (task.getApprovalType() == 5) {
+                    map = this.jdbcTemplate.queryForMap("select * from s_interim_pay_certificate where  is_deleted=0 and contract_period_id = " + task.getFormDataId());
+                    taskFile.setApprovalFileList(map.get("period_number") + "", map.get("raw_url") + "");
+                }
+                taskFile.setRemarkType("1");
+            }catch (Exception e) {
+                RedisTemplate.delete("sign-" + task.getFormDataId());
+                return NOT_PFX_SGIN;
             }
-            taskFile.setRemarkType("1");
         }
 
         if (taskFile == null || taskFile.getApprovalFileList().size() <= 0) {
@@ -439,6 +444,7 @@ public class EVisaServiceImpl implements EVisaService {
                 }
                 String pdfUrl = file.getFileUrl();
                 pdfUrl = CommonUtil.replaceOssUrl(pdfUrl);
+                System.out.println("11111111"+pdfUrl);
                 List<String> eVisaConfigList = PDFUtils.getPdfSignIds(pdfUrl);
                 if (eVisaConfigList == null || eVisaConfigList.size() == 0) {
                     //没有电签配置,默认当前任务为不签字审批,返回成功
@@ -500,6 +506,7 @@ public class EVisaServiceImpl implements EVisaService {
                            // daMa.put("sealOffsetX",-30);
                             byte[] fileByte;
                             if (fileUrl.indexOf("aliyuncs.com") >= 0 || fileUrl.indexOf("183.247.216.148") >= 0 || fileUrl.indexOf("152.168.2.15") >= 0) {
+                                System.out.println("2222222"+pdfUrl);
                                 URL url =new URL(pdfUrl);
                                 fileByte = IOUtils.toByteArray(url);
                             } else {
@@ -588,11 +595,13 @@ public class EVisaServiceImpl implements EVisaService {
                         vo.setOffSetX(eVisaConfig.get("pyzbx") + "");
                         vo.setOffSetY(eVisaConfig.get("pyzby") + "");
                         sealStrategyVOS.add(vo);
+
                     }
                     SealPdfVO pdfVO = new SealPdfVO();
                     pdfVO.setStrategyVoList(sealStrategyVOS);
 
                     //获取字节
+
                     URL url = new URL(pdfUrl);
                     byte[] fileByte;
                     try {
@@ -623,7 +632,6 @@ public class EVisaServiceImpl implements EVisaService {
                 }
             }
         } catch (Exception e) {
-            System.out.println("------5------");
             RedisTemplate.delete("sign-" + task.getFormDataId());
             e.printStackTrace();
         }
@@ -774,52 +782,13 @@ public class EVisaServiceImpl implements EVisaService {
         return "";
     }
 
-    public static void main22(String[] args) throws Exception {
-       // String pdfPath ="/Users/hongchuangyanfa/Desktop/pdf/1788120810012016640123.pdf";
-        String pdfPath ="/Users/hongchuangyanfa/Desktop/pdf/outPdf.pdf";
-        String sealId ="0ff724e095fc4a16b9c9c25ebe44e68f";
-        String formDataId ="vv";
-        List<Map<String,Object>> maps = new ArrayList<>();
-        Map<String,Object> daMap = new HashMap<>();
-        daMap.put("keyWord","12345");
-        daMap.put("sealId",sealId);
-        //设置显示签字体的宽高
-        daMap.put("showHeight",30);
-        daMap.put("showWidth",60);
-        //设置显示签字体的位置
-       // daMap.put("sealOffsetY",-15);
-       // daMap.put("sealOffsetX",-30);
-
-        maps.add(daMap);
-
-        String fileUrl =pdfPath;
-        for(int i=0;i<maps.size();i++){
-            HashMap daMa  = (HashMap) maps.get(i);
-            FileReader fileReader = new FileReader(fileUrl);
-            String originalFileB64 = Base64.toBase64String(fileReader.readBytes());
-            daMa.put("fileB64", originalFileB64);
-            daMa.put("lastSignFlag", false);
-
-            if(maps.size()==1){
-                 signPdfByDFZX(daMa);
-            }else{
-              String reData =  signPdfByDFZX(daMa);
-              if(reData.indexOf("success@")>=0){
-                  fileUrl = reData.split("@@@@")[1];
-              }
-
-            }
-            System.out.println(fileUrl);
-        }
-    }
-
 
     /**
      * 东方 中讯
      *
      * @throws Exception
      */
-    public static String signPdfByDFZX(HashMap<String, Object> request) {
+    public String signPdfByDFZX(HashMap<String, Object> request) {
         String url = "http://39.108.216.210:9125/FrontSys/SealServicezx/FileSignByKeyWord";
 
         String sysLocalFileUrl = FileUtils.getSysLocalFileUrl();
@@ -870,13 +839,19 @@ public class EVisaServiceImpl implements EVisaService {
     }
 
 
+
     /**
      * 安心 - 签章
      */
-    private Object[] signPdfByAXQZ(SealPdfVO pdfVO, byte[] fileByte) {
+    public Object[] signPdfByAXQZ(SealPdfVO pdfVO, byte[] fileByte) {
         Object[] result = new Object[3];
         try {
-            PaperlessClient paperlessClient = new PaperlessClient(SIGN_HOST, SIGN_PORT, 18000000, 72000000);
+            String sys_isonline = ParamCache.getValue(CommonConstant.SYS_ISONLINE);
+            if("20".equals(sys_isonline) || SystemUtils.isWindows() || SystemUtils.isMacOs()){
+                SIGN_HOST = "47.115.117.246";
+            }
+
+            PaperlessClient paperlessClient = new PaperlessClient(SIGN_HOST, SIGN_PORT, 240000000, 810000000);
             paperlessClient.setSSL(false);
             //*****************************************************************************
             CompoundSealPdfListDetachedRequest compoundSealPdfListDetachedRequest = new CompoundSealPdfListDetachedRequest();
@@ -905,6 +880,8 @@ public class EVisaServiceImpl implements EVisaService {
             pdfBean.setInputType(BaseConstants.INPUT_TYPE_FILEDATA);
             logger.info("【电签模块】pdf{}", "长度"+fileByte.length);
             pdfBean.setPdfData(fileByte);
+           // pdfBean.set
+            //pdfBean.set
             pdfBeans.add(pdfBean);
 
             requestBody.setPdfBeans(pdfBeans);
@@ -1056,7 +1033,11 @@ public class EVisaServiceImpl implements EVisaService {
     private Object[] signPdfByAXQZ_2(SealPdfVO pdfVO, byte[] fileByte, int typeGenerate) {
         Object[] result = new Object[3];
         try {
-            PaperlessClient paperlessClient = new PaperlessClient(SIGN_HOST, SIGN_PORT, 300000, 36000000);
+            String sys_isonline = ParamCache.getValue(CommonConstant.SYS_ISONLINE);
+            if("20".equals(sys_isonline) || SystemUtils.isWindows() || SystemUtils.isMacOs()){
+                SIGN_HOST = "47.115.117.246";
+            }
+            PaperlessClient paperlessClient = new PaperlessClient(SIGN_HOST, SIGN_PORT, 240000000, 810000000);
             paperlessClient.setSSL(false);
             //*****************************************************************************
             CompoundSealPdfListDetachedRequest compoundSealPdfListDetachedRequest = new CompoundSealPdfListDetachedRequest();
@@ -1314,7 +1295,11 @@ public class EVisaServiceImpl implements EVisaService {
     @Override
     public String createSeal(EVisaMakeSealVO vo) {
         try {
-            PaperlessClient paperlessClient = new PaperlessClient(SIGN_HOST, SIGN_PORT, 3000, 20000);
+            String sys_isonline = ParamCache.getValue(CommonConstant.SYS_ISONLINE);
+            if("20".equals(sys_isonline) || SystemUtils.isWindows() || SystemUtils.isMacOs()){
+                SIGN_HOST = "47.115.117.246";
+            }
+            PaperlessClient paperlessClient = new PaperlessClient(SIGN_HOST, SIGN_PORT, 240000000, 810000000);
             paperlessClient.setSSL(false);
 
             // ------构造请求报文头------
@@ -1388,7 +1373,11 @@ public class EVisaServiceImpl implements EVisaService {
     @Override
     public List<CertBean> onlineCheckSeal(String pdfUrl) {
         try {
-            PaperlessClient paperlessClient = new PaperlessClient(SIGN_HOST, SIGN_PORT, 300000, 1800000);
+            String sys_isonline = ParamCache.getValue(CommonConstant.SYS_ISONLINE);
+            if("20".equals(sys_isonline) || SystemUtils.isWindows() || SystemUtils.isMacOs()){
+                SIGN_HOST = "47.115.117.246";
+            }
+            PaperlessClient paperlessClient = new PaperlessClient(SIGN_HOST, SIGN_PORT, 240000000, 810000000);
             paperlessClient.setSSL(false);
 
             /*==================================================================================*/
@@ -1659,4 +1648,89 @@ public class EVisaServiceImpl implements EVisaService {
             return R.fail("电签解析失败");
         }
     }
+
+    /**
+     * 安心 - 签章
+     */
+    public Object[] signPdfByAXQZ(SealPdfVO pdfVO, String loPdfurl,String outPdfUrl) {
+        Object[] result = new Object[3];
+        try {
+            String sys_isonline = ParamCache.getValue(CommonConstant.SYS_ISONLINE);
+            if("20".equals(sys_isonline) || SystemUtils.isWindows() || SystemUtils.isMacOs()){
+                SIGN_HOST = "47.115.117.246";
+            }
+            PaperlessClient paperlessClient = new PaperlessClient(SIGN_HOST, SIGN_PORT, 240000000, 810000000);
+            paperlessClient.setSSL(false);
+            //*****************************************************************************
+            CompoundSealPdfListDetachedRequest compoundSealPdfListDetachedRequest = new CompoundSealPdfListDetachedRequest();
+
+            RequestHead requestHead = new RequestHead();
+            //业务流水号 非空
+            String transactionNo = GUIDUtil.generateId();
+            //机构编码非空
+            String organizationCode = EVisaConstant.organizationCode;
+            //操作员编码 可为空(企业类型不能为空)
+            String operatorCode = EVisaConstant.operationCode;
+            //渠道编码 可为空
+            String channelCode = "";
+            //设置属性
+            requestHead.setBasicInfo(transactionNo, organizationCode, operatorCode, channelCode);
+
+            compoundSealPdfListDetachedRequest.setHead(requestHead);
+
+            //*****************************************************************************
+            CompoundSealPdfListRequestBody requestBody = new CompoundSealPdfListRequestBody();
+
+            List<PdfBean> pdfBeans = new ArrayList<>();
+            PdfBean pdfBean = new PdfBean();
+            pdfBean.setBizSerialNo(GUIDUtil.generateId());
+            pdfBean.setInputSource("/mnt/bladesign"+loPdfurl);
+            pdfBean.setInputType(BaseConstants.INPUT_TYPE_FILEPATH);
+            pdfBeans.add(pdfBean);
+            requestBody.setPdfBeans(pdfBeans);
+            //***********************构造机构章策略 ********************************
+            List<SealStrategy> sealStrategies = generateSealStrategies(pdfVO.getStrategyVoList());
+            if (null == sealStrategies || sealStrategies.size() <= 0) {
+                logger.info("【电签模块】{}", "签章策略为空");
+                return null;
+            }
+            requestBody.setSealStrategies(sealStrategies);
+
+            //签章后文件保存地址,不为空时,直接将签章文件保存在此地址,不再返回签章后文档数据;ftp:auto
+            requestBody.setOutputFilepath("/mnt/bladesign"+outPdfUrl);
+
+            //时间戳方式,默认为0;0:实时访问CFCA 时间戳服务;1:使用从CFCA购置并在本地部署的时间戳服务器产品;
+            requestBody.setTimestampChannel(BaseConstants.TIME_STAMP_CHANNEL_CFCA);
+            //获取场景证书的方式默认值为0;0:实时从CFCA CA服务申请下载场景证书;1:使用从CFCA CA服务预先申请下载并存储在本地的场景证书;
+            requestBody.setSceneCertChannel(BaseConstants.SCEND_CERT_CHANNEL_REAL);
+
+            compoundSealPdfListDetachedRequest.setBody(requestBody);
+            //****************************** 请求服务端进行签章 *********************************************
+            System.out.println("-----------------------" + new Date().toString() + "开始" + transactionNo + "----------------------------");
+
+            ResponseDto responseDto = paperlessClient.execute(compoundSealPdfListDetachedRequest);
+
+            System.out.println("-----------------------" + new Date().toString() + "结束" + transactionNo + "----------------------------");
+            //******************************解析响应结果 *********************************************
+            CompoundSealPdfListDetachedResponse compoundSealPdfListDetachedResponse = (CompoundSealPdfListDetachedResponse) responseDto;
+            ResponseHead responseHead = compoundSealPdfListDetachedResponse.getHead();
+            CompoundSealPdfListDetachedResponseBody responseBody = compoundSealPdfListDetachedResponse.getBody();
+            if (ClientConstants.CODE_SUCCESS.equals(responseHead.getCode())) {
+                List<PdfBean4Response> pdfBeanList = responseBody.getPdfBeans();
+                if (pdfBeanList != null && pdfBeanList.size() > 0) {
+                    PdfBean4Response pdfBean4Response = pdfBeanList.get(0);
+                    result[0] = pdfBean4Response.getPdf();
+                }
+            } else {
+                logger.info("【电签模块】{}", "签章响应Response:" + compoundSealPdfListDetachedResponse);
+                logger.info("【电签模块】{}", "签章响应code:" + responseHead.getCode());
+                result[0] = null;
+                result[1] = compoundSealPdfListDetachedResponse.toString();
+                result[2] = responseHead.getMessage();
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return result;
+    }
 }

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

@@ -2,6 +2,10 @@ package org.springblade.evisa.utils;
 
 
 
+import com.itextpdf.text.Document;
+import com.itextpdf.text.pdf.PdfCopy;
+import com.itextpdf.text.pdf.PdfReader;
+import org.apache.pdfbox.pdmodel.PDDocument;
 import org.springblade.common.constant.CommonConstant;
 import org.springblade.common.utils.CommonUtil;
 
@@ -10,6 +14,7 @@ import org.springblade.common.utils.SystemUtils;
 import org.springblade.system.cache.ParamCache;
 
 import java.io.*;
+import java.util.List;
 
 
 public class FileUtils {
@@ -19,13 +24,18 @@ public class FileUtils {
         String file_path = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
         String sys_file_net_url = ParamCache.getValue(CommonConstant.SYS_FILE_NET_URL);
 
+
         File file1 = new File(fileUrl);
         InputStream fileInputStream = null;
         if (file1.exists()) {
             fileInputStream = new FileInputStream(file1);
         } else {
-            String path = sys_file_net_url + fileUrl.replaceAll("//", "/").replaceAll(file_path, "");
-            fileInputStream = CommonUtil.getOSSInputStream(path);
+            if(fileUrl.indexOf("http:")>=0 || fileUrl.indexOf("https:")>=0){
+                fileInputStream = CommonUtil.getOSSInputStream(fileUrl);
+            }else {
+                String path = sys_file_net_url + fileUrl.replaceAll("//", "/").replaceAll(file_path, "");
+                fileInputStream = CommonUtil.getOSSInputStream(fileUrl);
+            }
         }
         return fileInputStream;
     }
@@ -48,4 +58,66 @@ public class FileUtils {
         return file_path;
     }
 
+    /**
+     * 合并方法
+     */
+    public static void mergePdfPublicMethods(List<String> urlList, String localImgUrl) {
+        PdfReader reader = null;
+
+        Document doc = new Document();
+        PdfCopy pdfCopy = null;
+        try {
+            pdfCopy = new PdfCopy(doc, new FileOutputStream(localImgUrl));
+            int pageCount;
+            doc.open();
+
+            for (String urlStr : urlList) {
+                try {
+                    //获取OSS文件输入流
+                    reader = new PdfReader(CommonUtil.getOSSInputStream(urlStr));
+
+                    pageCount = reader.getNumberOfPages();
+
+                    for (int i = 0; i < pageCount; ++i) {
+                        int is = i + 1;
+                        pdfCopy.addPage(pdfCopy.getImportedPage(reader, is));
+                    }
+                } catch (Exception e) {
+                    e.printStackTrace();
+                } finally {
+                    if (reader != null) {
+                        reader.close();
+                    }
+                }
+            }
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            if (pdfCopy != null) {
+                pdfCopy.flush();
+                pdfCopy.close();
+            }
+            doc.close();
+        }
+    }
+
+
+    public static String getPdfNum(String url) {
+        try {
+            if (url.isEmpty() || url.equals("")) {
+                return "0";
+            }
+            InputStream pdfInputStream = CommonUtil.getOSSInputStream(url);
+            //获取这份文件的页数并设置签章策略
+            //获取PDF文件
+            PDDocument document = PDDocument.load(pdfInputStream);
+            int page = document.getPages().getCount();
+            return page + "";
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return "";
+    }
+
 }

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

@@ -1,61 +1,122 @@
 package org.springblade.evisa.utils;
 
-import com.spire.pdf.PdfDocument;
-import com.spire.pdf.PdfPageBase;
-import com.spire.pdf.general.find.PdfTextFind;
-import com.spire.pdf.general.find.PdfTextFindCollection;
-import com.spire.pdf.utilities.PdfTable;
-import com.spire.pdf.utilities.PdfTableExtractor;
-
-import org.apache.commons.io.IOUtils;
+import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.text.PDFTextStripper;
+import org.springblade.business.vo.TaskSignInfoVO;
 import org.springblade.common.utils.CommonUtil;
 import org.springblade.core.tool.utils.Func;
-import org.springblade.core.tool.utils.ResourceUtil;
 
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.InputStream;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.net.URLConnection;
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
 import java.util.List;
+import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 
-
 public class PDFUtils {
-    public static synchronized List<String>  getPdfSignIds(String pdfUrl) {
-        PdfDocument pdf = new PdfDocument();
+    public static List<String>  getPdfSignIds(String pdfUrl, TaskSignInfoVO taskApp) {
         List<String> eVisaConfigList = new ArrayList<>();
-        try {
-            pdfUrl = CommonUtil.replaceOssUrl(pdfUrl);
-            URL url =new URL(pdfUrl);
-            byte[] byteArray = IOUtils.toByteArray(url);
-            pdf.loadFromBytes(byteArray);
-            for(int i= 0;i<pdf.getPages().getCount();i++){
-                PdfPageBase page = pdf.getPages().get(i);
-                PdfTextFindCollection allText = page.findAllText();
-                PdfTextFind[] finds = allText.getFinds();
-                for(int k=0;k<finds.length;k++){
-                    String textStr = finds[k].getMatchText();
-                    if(textStr.indexOf("*")>=0){
-                        textStr = textStr.substring(textStr.lastIndexOf("*")+1,textStr.length());
+        try  {
+            InputStream inputStream = CommonUtil.getOSSInputStream(pdfUrl);
+            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){
+                    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);
+                    }
+
+                    Pattern pattern = Pattern.compile(regex);
+                    if(pattern.matcher(txt).matches()){
+                        taskApp.setPdfDate(txt);
                     }
-                    String[] textS = Func.toStrArray("\\|\\|",textStr);
-                    for(String txt : textS){
-                        if (txt.length() >= 15 && Func.isNumeric(txt)) {
-                            eVisaConfigList.add(txt);
+                }
+
+                // 特殊处理
+                if(textStr.indexOf("1")>=0){
+                    String txt = textStr.substring(textStr.indexOf("1"));
+                    if (txt.length() >= 15 && Func.isNumeric(txt)) {
+                        System.out.println(txt);
+                        eVisaConfigList.add(txt);
+                    }
+                }
+            }
+
+
+            List<String> unique = eVisaConfigList.stream().distinct().collect(Collectors.toList());
+            document.close();
+            return unique;
+        }catch (Exception e){
+            e.printStackTrace();
+            System.out.println("pdf大小为0");
+            return eVisaConfigList;
+        }
+    }
+
+    public static List<String>  getPdfSignIds(String pdfUrl) {
+        List<String> eVisaConfigList = new ArrayList<>();
+        try  {
+            InputStream inputStream = new FileInputStream(new File(pdfUrl));//CommonUtil.getOSSInputStream(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());
+                }
+                if(textStr.indexOf("1867379428376444928")>=0){
+                    System.out.println("");
+                }
+
+                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)) {
+                        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)) {
+                        System.out.println(txt);
+                        eVisaConfigList.add(txt);
+                    }
+                }
+
             }
+
             List<String> unique = eVisaConfigList.stream().distinct().collect(Collectors.toList());
+            document.close();
             return unique;
         }catch (Exception e){
             e.printStackTrace();
             return null;
-        }finally {
-            pdf.close();
         }
     }
 

+ 424 - 0
blade-service/blade-e-visa/src/main/java/org/springblade/evisa/utils/PdfAddimgUtil.java

@@ -0,0 +1,424 @@
+package org.springblade.evisa.utils;
+
+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.manager.vo.PDFIndexInfo;
+import org.springblade.system.cache.ParamCache;
+
+import java.io.*;
+import java.util.ArrayList;
+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 List<String>  getPdfSignIds(String pdfUrl) {
+        List<String> eVisaConfigList = new ArrayList<>();
+        try  {
+            InputStream inputStream = CommonUtil.getOSSInputStream(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)) {
+                        System.out.println(txt);
+                        eVisaConfigList.add(txt);
+                    }
+                }
+            }
+
+            List<String> unique = eVisaConfigList.stream().distinct().collect(Collectors.toList());
+            document.close();
+            return unique;
+        }catch (Exception e){
+            e.printStackTrace();
+            return null;
+        }
+    }
+}

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

@@ -0,0 +1,228 @@
+package org.springblade.evisa.utils;
+
+import org.apache.commons.net.ftp.FTP;
+import org.apache.commons.net.ftp.FTPClient;
+import org.springblade.common.constant.CommonConstant;
+import org.springblade.common.utils.SystemUtils;
+import org.springblade.system.cache.ParamCache;
+
+import java.io.*;
+
+public class SignFtpUtil {
+
+    // -外网
+   // private static final String SERVER = "47.115.117.246";
+    // 内网210
+    private static String SERVER = "172.30.224.79";
+    private static final int PORT = 6233;
+    private static final String USER = "signAdmin";
+    private static final String PASS = "123456";
+    private static final int CONNECT_TIMEOUT = 900000; // 30秒
+    private static final int DATA_TIMEOUT = 90000; // 30秒
+
+    /**
+     *  获取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);
+            if("20".equals(sys_isonline) || SystemUtils.isWindows() || SystemUtils.isMacOs()){
+                SERVER = "47.115.117.246";
+            }
+            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 {
+                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)) {
+                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 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 {
+            // 上传文件
+            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;
+            }
+        }
+    }
+}

+ 0 - 76
blade-service/blade-e-visa/src/main/java/org/springblade/evisa/utils/ThreadPoolDemo.java

@@ -1,76 +0,0 @@
-package org.springblade.evisa.utils;
-import com.alibaba.fastjson.JSON;
-import org.springblade.business.vo.TaskApprovalVO;
-import org.springframework.scheduling.annotation.Scheduled;
-
-import java.io.FileNotFoundException;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.*;
-
-public class ThreadPoolDemo {
-
-    ThreadPoolDemo(){
-        System.out.println("-----------------------");
-        System.out.println("----------启动-------------");
-        System.out.println("-----------------------");
-    }
-
-
-
-    public static void main11(String[] args) throws InterruptedException {
-
-        // 准备创建线程池所需要的7个参数
-        int corePoolSize = 3;
-        int maximumPoolSize = 3;
-        int keepLiveTime = 0;
-        TimeUnit timeUnit = TimeUnit.SECONDS;
-        ThreadFactory threadFactory = Executors.defaultThreadFactory();
-        ArrayBlockingQueue queue = new ArrayBlockingQueue<>(30);
-
-        RejectedExecutionHandler policy =
-                new ThreadPoolExecutor.DiscardOldestPolicy();
-        // 创建线程池对象
-        ThreadPoolExecutor myThreadPool = new ThreadPoolExecutor(
-                corePoolSize,
-                maximumPoolSize,
-                keepLiveTime,
-                timeUnit,
-                queue,
-                threadFactory,
-                policy);
-
-        for (int i=0;i<10;i++){
-            final int index = i;
-            String index2 = "1";
-            if(i%3==0){
-                index2="2";
-            }
-
-
-            String finalIndex = index2;
-            myThreadPool.execute(new Runnable() {
-
-                @Override
-                public void run() {
-                    try {
-                        synchronized (finalIndex) {
-                            System.out.println(index+"------"+finalIndex);
-                            if(finalIndex.equals("2")){
-                                System.out.println(index+"--2--开始");
-                                Thread.sleep(20000);
-                                System.out.println(index+"--2--结束");
-                            }else{
-                                Thread.sleep(1000);
-                            }
-                        }
-                    } catch (InterruptedException e) {
-                        // TODO Auto-generated catch block
-                        e.printStackTrace();
-                    }
-                }
-            });
-        }
-    }
-
-}

+ 16 - 2
blade-service/blade-manager/src/main/java/com/mixsmart/utils/CustomFunction.java

@@ -522,8 +522,22 @@ public class CustomFunction {
     private static Object dateCp(Object d1, Object d2, Boolean isAsc) {
         if (d1 != null && d2 != null) {
             Map<DateTime, Object> map = new HashMap<>();
-            DateTime dt1 = new DateTime(d1.toString());
-            DateTime dt2 = new DateTime(d2.toString());
+            String day1 = d1.toString();
+            day1=day1.replace("年","-");
+            day1=day1.replace("月","-");
+            if(day1.indexOf("日")>0){
+                day1= day1.substring(0,day1.indexOf("日"));
+            }
+            String day2 = d2.toString();
+            day2= day2.replace("年","-");
+            day2= day2.replace("月","-");
+            if(day2.indexOf("日")>0){
+                day2=day2.substring(0,day2.indexOf("日"));
+            }
+            day1=day1.replace("\"", "");
+            day2=day2.replace("\"", "");
+            DateTime dt1 = new DateTime(day1);
+            DateTime dt2 = new DateTime(day2);
             map.put(dt1, d1);
             map.put(dt2, d2);
             List<DateTime> list = new ArrayList<>();

+ 3 - 0
blade-service/blade-manager/src/main/java/com/mixsmart/utils/FormulaUtils.java

@@ -1068,6 +1068,9 @@ public class FormulaUtils {
         if(t!=null&&Pattern.matches(RANGE_DATE_REG,t)){
             t=t.replaceAll("^\\[|]$","").split(",")[1].trim();
         }
+        if(StringUtils.isNotEmpty(t)){
+            t=t.replace("\"", "");
+        }
         return t;
     }
 

+ 14 - 0
blade-service/blade-manager/src/main/java/com/mixsmart/utils/StringUtils.java

@@ -966,6 +966,20 @@ public class StringUtils {
         Matcher m = r.matcher(String.valueOf(value));
         return m.matches();
     }
+    /**
+     * @Description 是否包含双引号
+     * @Param [value]
+     * @return boolean
+     * @Author chenr
+     * @Date 2024.12.24 15:24
+     **/
+    public static boolean isDoubleQuotationMarks(Object value) {
+        if (value == null || value.toString().length() < 2) {
+            return false;
+        }
+        return value.toString().matches("^\"[^\"]*\"$");
+    }
+
 
     public static boolean isDouble(Object value) {
         return isNumber(value) && value.toString().contains(".");

+ 112 - 163
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ExcelTabController.java

@@ -10,6 +10,7 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.fasterxml.jackson.annotation.JsonProperty;
 import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
 import com.google.gson.Gson;
 import com.spire.xls.*;
@@ -43,6 +44,7 @@ import org.springblade.core.log.exception.ServiceException;
 import org.springblade.core.mp.support.Condition;
 import org.springblade.core.mp.support.Query;
 import org.springblade.core.oss.model.BladeFile;
+import org.springblade.core.redis.cache.BladeRedis;
 import org.springblade.core.secure.BladeUser;
 import org.springblade.core.secure.utils.AuthUtil;
 import org.springblade.core.secure.utils.SecureUtil;
@@ -55,10 +57,7 @@ import org.springblade.manager.enums.ExecuteType;
 import org.springblade.manager.mapper.ExcelTabMapper;
 import org.springblade.manager.mapper.WbsTreePrivateMapper;
 import org.springblade.manager.service.*;
-import org.springblade.manager.utils.ExcelInfoUtils;
-import org.springblade.manager.utils.FileUtils;
-import org.springblade.manager.utils.RegularExpressionUtil;
-import org.springblade.manager.utils.WbsElementUtil;
+import org.springblade.manager.utils.*;
 import org.springblade.manager.vo.*;
 import org.springblade.manager.wrapper.ExcelTabWrapper;
 import org.springblade.resource.feign.CommonFileClient;
@@ -67,6 +66,7 @@ import org.springblade.resource.feign.NewIOSSClient;
 import org.springblade.resource.vo.NewBladeFile;
 import org.springblade.system.cache.ParamCache;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Lazy;
 import org.springframework.data.redis.core.StringRedisTemplate;
 import org.springframework.http.HttpHeaders;
 import org.springframework.http.MediaType;
@@ -131,6 +131,7 @@ public class ExcelTabController extends BladeController {
     // 元素信息表-
     private final IWbsFormElementService wbsFormElementService;
 
+
     // 元素信息表-
     private final IWbsTreeContractService wbsTreeContractService;
 
@@ -164,6 +165,8 @@ public class ExcelTabController extends BladeController {
 
     private final TaskClient taskClient;
 
+    private final BladeRedis bladeRedis;
+
 
 
 
@@ -1633,7 +1636,8 @@ public class ExcelTabController extends BladeController {
         List<WbsTreeContract> wbsTreeContractList = wbsTreeContractService.getBaseMapper().selectList(Wrappers.<WbsTreeContract>query().lambda()
                 .likeRight(WbsTreeContract::getNodeName,wbsInfo.getNodeName())
                 .eq(WbsTreeContract::getContractId, wbsInfo.getContractId())
-                .eq(WbsTreeContract::getParentId, wbsInfo.getParentId()));
+                .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());
@@ -1864,7 +1868,7 @@ public class ExcelTabController extends BladeController {
              if(ObjectUtil.isEmpty(nodeClass)){
                  nodeClass=1;
              }
-             if ((StringUtils.isEmpty(pdfUrl) || pdfUrl.equals("null"))&&!nodeClass.equals(2)) {
+             if ((StringUtils.isEmpty(pdfUrl) || pdfUrl.equals("null")) && !nodeClass.equals(2)) {
                     return R.fail("暂无PDF数据");
              } else {
                 // 由于独立附件 需要追加最后
@@ -1978,8 +1982,21 @@ public class ExcelTabController extends BladeController {
         List<TableInfo> tableInfoList = this.excelTabService.getTableInfoList(dataArray);
 
         executionTime.info("公式前");
+        try {
+            Long pKeyId = Long.parseLong(tableInfoList.get(0).getPkeyId());
+            String sql="SELECT node_name from m_wbs_tree_contract where p_key_id="+pKeyId;
+            String nodeName = jdbcTemplate.queryForObject(sql, String.class);
+            HashMap<Long, String> map = new HashMap<>();
+            map.put(pKeyId,nodeName);
+            RandomNumberHolder.setRandomNumber(map);
+        } catch (NumberFormatException e) {
+            throw new RuntimeException(e);
+        }
+
+
         //公式填充
         this.excelTabService.formulaFillData(tableInfoList, Long.parseLong(nodeId), ExecuteType.INSPECTION);
+        RandomNumberHolder.clear();
         assert tableInfoList != null;
         if(tableInfoList.size()==0){
             R.success("数据未发生变化");
@@ -2359,6 +2376,7 @@ public class ExcelTabController extends BladeController {
         if (ids.size() > 0) {
             //PDF路径
             List<String> pdfUrls = new ArrayList<>();
+
             for (String dataId : ids) {
                 //查询对应的html
                 WbsTreePrivate tableNode = this.wbsTreePrivateService.getOne(Wrappers.<WbsTreePrivate>lambdaQuery().eq(WbsTreePrivate::getPKeyId, pkeyId));
@@ -2392,21 +2410,56 @@ public class ExcelTabController extends BladeController {
                     Document doc = Jsoup.parse(htmlString);
                     Element table = doc.select("table").first();
                     Elements trs = table.select("tr");
+
                     //添加标题
-                    CellRange[] columns = sheet.getMergedCells();
-                    for (int i = 0; i < columns.length; i++) {
-                        CellRange cellRange = columns[i];
-
-                        if (cellRange.getStyle().getFont().getSize() >= 12 && (Func.isNotEmpty(cellRange.getValue2()) || Func.isNotEmpty(cellRange.getValue()))) {
-                            String title = projectInfo.getProjectName();
-                            if (title.length() >= 30) {
-                                cellRange.setRowHeight(40);
-                                cellRange.getStyle().setWrapText(true);
+                    String sys_isonline = ParamCache.getValue(CommonConstant.SYS_ISONLINE);
+                    if("20".equals(sys_isonline)){ //甬台温
+                        CellRange[] columns = sheet.getMergedCells();
+                        for (int i = 0; i < columns.length; i++) {
+                            CellRange cellRange = columns[i];
+                            if (cellRange.getStyle().getFont().getSize() >= 12 && (Func.isNotEmpty(cellRange.getValue2()) || Func.isNotEmpty(cellRange.getValue()))) {
+                                String title = projectInfo.getProjectName();
+                                if (title.length() >= 30) {
+                                    cellRange.setRowHeight(40);
+                                    cellRange.getStyle().setWrapText(true);
+                                }
+                                cellRange.getStyle().getFont().setSize(18);
+                                cellRange.getStyle().setHorizontalAlignment(HorizontalAlignType.Center);
+                                cellRange.setText(projectInfo.getProjectName());
+                                break;
+                            }
+                        }
+                    }else{
+                        for (int i = 1; i < 6; i++) {
+                            Element tr = trs.get(i);
+                            Elements tds = tr.select("td");
+                            for (int j = 0; j < tds.size(); j++) {
+                                Element data = tds.get(j);
+                                String style = data.attr("style");
+                                if (style.contains("font-size")) {
+                                    int fontsize = Integer.parseInt(style.substring(style.indexOf("font-size:") + 10, style.indexOf(".0pt")));
+                                    if (StringUtils.isNotEmpty(data.text()) && fontsize >= 12) {
+                                        Element element = trs.get(i - 1).select("td").get(0);
+                                        String textainfo = element.text();
+                                        if(textainfo ==null || textainfo == "" || Func.isEmpty(textainfo)){
+                                            int x1, y1;
+                                            if (element.html().indexOf("el-tooltip") >= 0) {
+                                                x1 = Integer.parseInt(element.children().get(0).children().get(0).attr("x1"));
+                                                y1 = Integer.parseInt(element.children().get(0).children().get(0).attr("y1"));
+                                            } else {
+                                                x1 = Integer.parseInt(element.children().get(0).attr("x1"));
+                                                y1 = Integer.parseInt(element.children().get(0).attr("y1"));
+                                            }
+                                            if (x1 == 0) {
+                                                x1 = 1;
+                                            }
+                                            final CellRange cellRange = sheet.getCellRange(y1, x1);
+                                            cellRange.setText(projectInfo.getProjectName());
+                                            break;
+                                        }
+                                    }
+                                }
                             }
-                            cellRange.getStyle().getFont().setSize(18);
-                            cellRange.getStyle().setHorizontalAlignment(HorizontalAlignType.Center);
-                            cellRange.setText(projectInfo.getProjectName());
-                            break;
                         }
                     }
 
@@ -2633,6 +2686,9 @@ public class ExcelTabController extends BladeController {
 
 
         if (StringUtils.isNotEmpty(dataIds)) {
+            if(dataIds.startsWith(",")){
+                dataIds=dataIds.substring(1);
+            }
             for (String dataId : dataIds.split(",")) {
                 Map<String, Object> reData = new HashMap<>();
                 reData.put("",logId2);
@@ -3062,7 +3118,8 @@ public class ExcelTabController extends BladeController {
                                 objLog.getWbsNodeType(),
                                 currentTime,
                                 logWbsList,
-                                theLogId
+                                theLogId,
+                                null
                         ));
                         logIds.add(id);
                     }else {
@@ -3085,7 +3142,8 @@ public class ExcelTabController extends BladeController {
                                     contractLog.getWbsNodeType(),
                                     currentTime,
                                     logWbsList,
-                                    theLogId
+                                    theLogId,
+                                    null
                             );
                             this.contractLogClient.saveLogWbsList(saveContractLogVO);
                         }
@@ -3722,8 +3780,9 @@ public class ExcelTabController extends BladeController {
             @ApiImplicitParam(name = "id", value = "记录id-当做groupId", required = true),
             @ApiImplicitParam(name = "contractId", value = "合同段id", required = true)
     })
-    public R<List<Map<String, Object>>> getBussDataInfoTrial(Long id, Long pkeyId, Long contractId, Long entrustId ,Integer type,Long nodeId ) {
-        List<Map<String, Object>> bussDataInfoTrial = excelTabService.getBussDataInfoTrial(id, pkeyId, contractId, entrustId, type, nodeId);
+    public R<List<Map<String, Object>>> getBussDataInfoTrial(Long id, Long pkeyId, Long contractId, Long entrustId ,Integer type,Long nodeId,String formData) {
+        JSONObject jsonObject = JSONObject.parseObject(formData);
+        List<Map<String, Object>> bussDataInfoTrial = excelTabService.getBussDataInfoTrial(id, pkeyId, contractId, entrustId, type, nodeId,jsonObject);
         return R.data(bussDataInfoTrial);
     }
 
@@ -4246,8 +4305,9 @@ public class ExcelTabController extends BladeController {
             @ApiImplicitParam(name = "id", value = "记录id-当做groupId", required = true),
             @ApiImplicitParam(name = "contractId", value = "合同段id", required = true)
     })
-    public R<List<Map<String, Object>>> getBussDataInfoTrialentrust(Long id, Long pkeyId, Long contractId, Long sampleId) {
-        List<Map<String, Object>> bussDataInfoTrial = excelTabService.getBussDataInfoTrialentrust(id, pkeyId, contractId,sampleId);
+    public R<List<Map<String, Object>>> getBussDataInfoTrialentrust(Long id, Long pkeyId, Long contractId, Long sampleId, String formData) {
+        JSONObject jsonObject = JSONObject.parseObject(formData);
+        List<Map<String, Object>> bussDataInfoTrial = excelTabService.getBussDataInfoTrialentrust(id, pkeyId, contractId,sampleId,jsonObject);
         return R.data(bussDataInfoTrial);
     }
 
@@ -4407,143 +4467,32 @@ public class ExcelTabController extends BladeController {
                  }
             }
         }
-   /* @Scheduled(cron = "0/20 * * * * ?")
-    public void SignInfo() {
-        //执行代码
-        String sql = "SELECT a.* from u_information_query a,m_wbs_tree_contract b  where a.wbs_id=b.p_key_id and  a.project_id='1681859557657550850' and  a.create_dept=100 LIMIT 5";
-        List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql);
-        if (maps != null && maps.size() >= 1) {
-            for (Map<String, Object> dataInfo : maps) {
-                if (executor.getQueue().size()<=40 ) {
-                    String idkey = dataInfo.get("id")+"";
-                    Boolean aBoolean = RedisTemplate.hasKey("sign-" + idkey);
-                    if(!aBoolean){
-                        RedisTemplate.opsForValue().set("sign-" + idkey, "1",30, TimeUnit.SECONDS);
-                        CompletableFuture<Void> runAsync = CompletableFuture.runAsync(() -> {
-                            try {
-                                *//*===============执行批量任务===============*//*
-                                this.checkIsExsitTaskBatch(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 checkIsExsitTaskBatch(Map<String, Object> dataInfo) {
-        // 数据
-        String file_path = "/Users/hongchuangyanfa/Desktop/";
-        String nodeId = dataInfo.get("wbs_id")+"";
-        String classify = dataInfo.get("classify")+"";
-        String contractId = dataInfo.get("contract_id")+"";
-        String projectId = dataInfo.get("project_id")+"";
-        String pdfUrl = dataInfo.get("pdf_url") + "";
-        try {
 
-            if (dataInfo.get("e_visa_pdf_url") != null) {
-                //优先使用电签的pdf
-                pdfUrl = dataInfo.get("e_visa_pdf_url") + "";
-            }
-
-            if (dataInfo.get("pdf_trial_url") != null || dataInfo.get("pdf_trial_url_position") != null) {
-                //合并试验关联文件、试验工程部位信息的pdf
-                pdfUrl = this.mergePdfShow(pdfUrl, dataInfo) + "";
-            }
-
-            if (StringUtils.isEmpty(pdfUrl) || pdfUrl.equals("null")) {
-                System.out.println("");
-            } else {
-                // 由于独立附件 需要追加最后
-                List<TableFileVO> data = tableFileService.selectTableFileListByTen(Long.valueOf(nodeId + ""));
-                List<String> datainfo = new ArrayList<>();
-                datainfo.add(pdfUrl);
-                if (data != null && data.size() >= 1) {
-                    for (TableFileVO tabsx : data) {
-                        datainfo.add(tabsx.getUrl());
-                    }
-                    String listPdf = file_path + "/nodePDF/" + nodeId + ".pdf";
-                    File tabpdf2 = ResourceUtil.getFile(listPdf);
-                    if (tabpdf2.exists()) {
-                        tabpdf2.delete();
-                    }
-
-                    FileUtils.mergePdfPublicMethods(datainfo, listPdf);
-                    String netUrl = "";
-
-                    BladeFile bladeFile = this.newIOSSClient.uploadFile(nodeId + ".pdf", listPdf);
-                    if (bladeFile != null && ObjectUtils.isNotEmpty(bladeFile.getLink())) {
-                            netUrl = bladeFile.getLink();
-                    }
-                }
-            }
-
-
-            List<String> list = Arrays.asList(nodeId.split(","));
-            Long userId = 1777156889464066049L;
-            String dateInfo = "";
-            for (String iId : list) {
-                //获取
-                if(StringUtils.isNotBlank(dataInfo.get("file_user_id_and_name")+"")){
-                    String userIdAndName = dataInfo.get("file_user_id_and_name")+"";
-                    String[] split = userIdAndName.split("-");
-                    userId = Long.parseLong(split[0]);
-                }
-
-                List<AppWbsTreeContractVO> WbsTreeContract = wbsTreeContractService.searchNodeAllTable(nodeId+":"+userId, classify, contractId, projectId ,null);
-
-                Map<String, String> idMap = new HashMap<>();
-                String wbsSql  = "select * from m_tab_busstime_info where is_deleted = 0 and tab_en_name IN('111111'";
-
-                for (AppWbsTreeContractVO appWbsTreeContractVO : WbsTreeContract) {
-
-                    wbsSql+=",'"+appWbsTreeContractVO.getInitTableName()+"'";
-                    idMap.put(appWbsTreeContractVO.getInitTableName(), appWbsTreeContractVO.getPKeyId() + "");
-                }
-                wbsSql+=")";
-                List<Map<String, Object>> tabussTimeInfo = jdbcTemplate.queryForList(wbsSql);
-
-
-                if (tabussTimeInfo != null && tabussTimeInfo.size() >= 1) {
-                    Map<String, Object> tabBusstimeInfo = tabussTimeInfo.get(0);
-
-                    String querySql = "select " + tabBusstimeInfo.get("col_key") + " from " + tabBusstimeInfo.get("tab_en_name") + " where p_key_id=" + idMap.get(tabBusstimeInfo.get("tab_en_name"));
-                    Map<String, Object> maps = jdbcTemplate.queryForMap(querySql);
-                    if (maps != null) {
-                        String keyData = maps.get(tabBusstimeInfo.get("col_key")) + "";
-                        if (StringUtils.isNotEmpty(keyData)) {
-                            dateInfo = keyData.split("_\\^_")[0];
-                            if (dateInfo.indexOf("年") >= 0) {
-                                dateInfo = dateInfo.replace("年", "-");
-                            }
-                            if (dateInfo.indexOf("月") >= 0) {
-                                dateInfo = dateInfo.replace("月", "-");
-                            }
-                            if (dateInfo.indexOf("日") >= 0) {
-                                dateInfo = dateInfo.replace("日", "");
-                            }
-                        }
-                    }
-                }
-            }
-
-            if(pdfUrl!=null && pdfUrl.length()>=20){
-                String pdfPage = commonFileClient.getPdfNum(pdfUrl);
-                long  pdfSize = CommonUtil.getResourceLength(pdfUrl);
-                jdbcTemplate.execute(" update  u_information_query set e_visa_pdf_size="+pdfSize+",e_visa_pdf_page="+pdfPage+", node_pdf_url='" + pdfUrl + "',create_dept=11 where classify='" + classify + "' and wbs_id='" + nodeId + "' and contract_id='" + contractId + "'");
-            }
-        }catch (Exception e) {
-             throw new RuntimeException(e);
-        }
-    }*/
+        //@Scheduled(fixedDelay = 1000*60*60*24)
+       //检查excel路径有错的
+        public void cheackExcel() throws IOException {
+            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));
+             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));
+                     List<String>names=new ArrayList<>();
+                     for (ExcelTab excelTab1 : query2) {
+                         if(excelTab1.getFileUrl()!=null){
+                             if(excelTab1.getFileUrl().endsWith(".xlsx")||excelTab1.getFileUrl().endsWith(".xls")){
+                                 long resourceLength = CommonUtil.getResourceLength(excelTab1.getFileUrl());
+                                 if(resourceLength<=500){
+                                     names.add(excelTab1.getName());
+                                     System.out.println(excelTab.getName()+"--"+tab.getName()+"--"+excelTab1.getName());
+                                 }
+                             }
+                         }
+                     }
+                 }
+             }
+            System.out.println("检查完毕");
+         }
 }

+ 127 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/FormEndPayController.java

@@ -0,0 +1,127 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.manager.controller;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+import lombok.AllArgsConstructor;
+import javax.validation.Valid;
+
+import org.springblade.core.mp.support.Condition;
+import org.springblade.core.mp.support.Query;
+import org.springblade.core.tool.api.R;
+import org.springblade.core.tool.utils.Func;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.bind.annotation.RequestParam;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import org.springblade.manager.entity.FormEndPay;
+import org.springblade.manager.vo.FormEndPayVO;
+import org.springblade.manager.service.IFormEndPayService;
+import org.springblade.core.boot.ctrl.BladeController;
+
+/**
+ *  控制器
+ *
+ * @author BladeX
+ * @since 2024-12-02
+ */
+@RestController
+@AllArgsConstructor
+@RequestMapping("/formendpay")
+@Api(value = "", tags = "接口")
+public class FormEndPayController extends BladeController {
+
+	private final IFormEndPayService formEndPayService;
+
+	/**
+	 * 详情
+	 */
+	@GetMapping("/detail")
+	@ApiOperationSupport(order = 1)
+	@ApiOperation(value = "详情", notes = "传入formEndPay")
+	public R<FormEndPay> detail(FormEndPay formEndPay) {
+		FormEndPay detail = formEndPayService.getOne(Condition.getQueryWrapper(formEndPay));
+		return R.data(detail);
+	}
+
+	/**
+	 * 分页 
+	 */
+	@GetMapping("/list")
+	@ApiOperationSupport(order = 2)
+	@ApiOperation(value = "分页", notes = "传入formEndPay")
+	public R<IPage<FormEndPay>> list(FormEndPay formEndPay, Query query) {
+		IPage<FormEndPay> pages = formEndPayService.page(Condition.getPage(query), Condition.getQueryWrapper(formEndPay));
+		return R.data(pages);
+	}
+
+	/**
+	 * 自定义分页 
+	 */
+	@GetMapping("/page")
+	@ApiOperationSupport(order = 3)
+	@ApiOperation(value = "分页", notes = "传入formEndPay")
+	public R<IPage<FormEndPayVO>> page(FormEndPayVO formEndPay, Query query) {
+		IPage<FormEndPayVO> pages = formEndPayService.selectFormEndPayPage(Condition.getPage(query), formEndPay);
+		return R.data(pages);
+	}
+
+	/**
+	 * 新增 
+	 */
+	@PostMapping("/save")
+	@ApiOperationSupport(order = 4)
+	@ApiOperation(value = "新增", notes = "传入formEndPay")
+	public R save(@Valid @RequestBody FormEndPay formEndPay) {
+		return R.status(formEndPayService.save(formEndPay));
+	}
+
+	/**
+	 * 修改 
+	 */
+	@PostMapping("/update")
+	@ApiOperationSupport(order = 5)
+	@ApiOperation(value = "修改", notes = "传入formEndPay")
+	public R update(@Valid @RequestBody FormEndPay formEndPay) {
+		return R.status(formEndPayService.updateById(formEndPay));
+	}
+
+	/**
+	 * 新增或修改 
+	 */
+	@PostMapping("/submit")
+	@ApiOperationSupport(order = 6)
+	@ApiOperation(value = "新增或修改", notes = "传入formEndPay")
+	public R submit(@Valid @RequestBody FormEndPay formEndPay) {
+		return R.status(formEndPayService.saveOrUpdate(formEndPay));
+	}
+
+	
+	/**
+	 * 删除 
+	 */
+	@PostMapping("/remove")
+	@ApiOperationSupport(order = 7)
+	@ApiOperation(value = "逻辑删除", notes = "传入ids")
+	public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
+		return R.status(formEndPayService.deleteLogic(Func.toLongList(ids)));
+	}
+
+	
+}

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

@@ -895,9 +895,9 @@ public class FormulaController {
     }
 
     @GetMapping("/test")
-    public R<Object> meter(Long contractId,Long reportId ,Integer type){
+    public R<Object> meter(Long contractId,Long reportId ,Integer type,Long periodId,Long projectId){
         /*合同段id,报表Id,报表类型中间计量0,材料1,开工2*/
-        return R.data(this.service.execute3(contractId,reportId,type));
+        return R.data(this.service.execute3(contractId,reportId,type,periodId,projectId));
     }
 
 

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

@@ -0,0 +1,27 @@
+package org.springblade.manager.controller;
+
+import org.springblade.manager.service.IWbsTreeContractService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+@Component
+public class ScheduledTasks {
+    private int i = 0;  //18
+    private final IWbsTreeContractService iWbsTreeContractService;
+
+    @Autowired
+    public ScheduledTasks(IWbsTreeContractService iWbsTreeContractService) {
+        this.iWbsTreeContractService = iWbsTreeContractService;
+    }
+    /**递归设置m_wbs_tree_contract 的 p_id 和 ancestors*/
+    //@Scheduled(fixedDelay = 5000) // 上一次任务执行完毕后等待5秒再执行下一次
+    public void runTask() {
+        //246 i=88,183 i=83
+        if(i==88){
+            return;
+        }
+        iWbsTreeContractService.diGuiWbs(i);
+        i++;
+    }
+}

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

@@ -0,0 +1,27 @@
+package org.springblade.manager.controller;
+
+import org.springblade.manager.service.IWbsTreePrivateService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+@Component
+public class ScheduledTasks1 {
+    private int i = 0;
+    private final IWbsTreePrivateService iWbsTreePrivateService;
+
+    @Autowired
+    public ScheduledTasks1(IWbsTreePrivateService iWbsTreePrivateService) {
+        this.iWbsTreePrivateService = iWbsTreePrivateService;
+    }
+    /**递归设置m_wbs_tree_private 的 p_id 和 ancestors*/
+    //@Scheduled(fixedDelay = 5000) // 上一次任务执行完毕后等待5秒再执行下一次
+    public void runTask() {
+        //246 i=105, 183 i=88
+        if(i==89){
+            return;
+        }
+        iWbsTreePrivateService.diGuiWbs(i);
+        i++;
+    }
+}

+ 9 - 11
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/SignPfxFileController.java

@@ -25,6 +25,7 @@ import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
 import io.swagger.annotations.*;
 import lombok.AllArgsConstructor;
 import okhttp3.OkHttpClient;
+import org.springblade.common.utils.CommonUtil;
 import org.springblade.common.utils.SnowFlakeUtil;
 import org.springblade.core.boot.ctrl.BladeController;
 import org.springblade.core.mp.support.Condition;
@@ -467,12 +468,13 @@ public class SignPfxFileController extends BladeController {
     }*/
 
     /**
-     * 根据用户设定尺寸压缩图片后上传至oss
+     * 单纯的 上传文件到oss
      */
     @PostMapping("/compressAndUpload")
     public R<BladeFile> compressAndUpload(@RequestParam MultipartFile file, @RequestParam double wide,@RequestParam double high) throws Exception {
+        Long id = SnowFlakeUtil.getId();
         String file_path = FileUtils.getSysLocalFileUrl();
-        String localImgPath = file_path + "print//" + SnowFlakeUtil.getId() + ".png";
+        String localImgPath = file_path + "print//" +id + ".png";
         // 检查文件是否存在
         File newFile = new File(localImgPath);
         if (!newFile.exists()) {
@@ -484,11 +486,8 @@ public class SignPfxFileController extends BladeController {
         }
         // 保存文件
         file.transferTo(newFile);
-        //图片压缩后的地址
-        Long id = SnowFlakeUtil.getId();
-        String compressImgPath = file_path + "/print//" + id + ".png";
-        FileUtils.compressImage(localImgPath, compressImgPath, wide, high);
-        return R.data(newIOSSClient.uploadFile(id+".png", compressImgPath));
+        //FileUtils.compressImage(localImgPath, compressImgPath, wide, high);
+        return R.data(newIOSSClient.uploadFile(id+".png", localImgPath));
     }
 
     @PostMapping ("/prePicture")
@@ -527,7 +526,7 @@ public class SignPfxFileController extends BladeController {
             }
 
         }
-        vo.setSignatureFileUrl(compressionAndUpload(vo.getSignatureFileUrl(), vo.getWide(), vo.getHigh()));
+        //vo.setSignatureFileUrl(compressionAndUpload(vo.getSignatureFileUrl(), vo.getWide(), vo.getHigh()));
         return R.status(this.signPfxFileService.updateById(vo));
     }
 
@@ -575,7 +574,8 @@ public class SignPfxFileController extends BladeController {
     }
     public String compressionAndUpload(String fileStr, double wide, double high) throws Exception {
         String file_path = FileUtils.getSysLocalFileUrl();
-        InputStream inputStreamByUrl = FileUtils.getInputStreamByUrl(fileStr);
+        InputStream inputStreamByUrl = CommonUtil.getOSSInputStream(fileStr);
+        //InputStream inputStreamByUrl = FileUtils.getInputStreamByUrl(fileStr);
         //图片压缩后的地址
         Long id = SnowFlakeUtil.getId();
         String compressImgPath = file_path + "/print//" + id + ".png";
@@ -583,6 +583,4 @@ public class SignPfxFileController extends BladeController {
         BladeFile bladeFile = newIOSSClient.uploadFile(id + ".png", compressImgPath);
         return bladeFile.getLink();
     }
-
-
 }

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

@@ -707,7 +707,7 @@ public class WbsTreePrivateController extends BladeController {
                 }
 
                 //表单数据
-                List<Map<String, Object>> bussDataInfoTrial = iExcelTabService.getBussDataInfoTrial(id, treePrivate.getPKeyId(), Long.parseLong(contractId),null,null,null);
+                List<Map<String, Object>> bussDataInfoTrial = iExcelTabService.getBussDataInfoTrial(id, treePrivate.getPKeyId(), Long.parseLong(contractId),null,null,null,null);
                 if (bussDataInfoTrial != null && bussDataInfoTrial.size() > 0) {
                     bussDataInfoTrial.get(0).remove("group_id");
                     treePrivate.setBussDataInfoTrial(bussDataInfoTrial.get(0));

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

@@ -68,13 +68,13 @@ public class FormulaClientImpl implements FormulaClient {
     }
 
     @Override
-    public List<ReportResult> formulaExecute3(Long contractId, Long periodId, Integer type) {
-       return service.execute3(contractId,periodId,type);
+    public List<ReportResult> formulaExecute3(Long contractId, Long periodId, Integer type,Long perIodId1,Long projectId) {
+       return service.execute3(contractId,periodId,type,perIodId1,projectId);
     }
 
     @Override
-    public List<ReportResult> formulaExecute4(Long contractId, Long periodId, Integer type) {
-        return service.execute4(contractId,periodId,type);
+    public List<ReportResult> formulaExecute4(Long reportId,Long contractId, Long periodId, Integer type,Long projectId) throws FileNotFoundException, IllegalAccessException {
+        return service.execute4(reportId,contractId,periodId,type,projectId);
     }
 
 

+ 63 - 5
blade-service/blade-manager/src/main/java/org/springblade/manager/feign/WbsTreePrivateClientImpl.java

@@ -8,27 +8,29 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.mixsmart.utils.StringUtils;
 import lombok.AllArgsConstructor;
 import org.apache.commons.lang3.ObjectUtils;
+import org.springblade.business.entity.TrialSelfInspectionRecord;
 import org.springblade.common.utils.SnowFlakeUtil;
 import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.node.ForestNodeMerger;
 import org.springblade.core.tool.utils.BeanUtil;
 import org.springblade.core.tool.utils.Func;
-import org.springblade.manager.entity.TableFile;
-import org.springblade.manager.entity.TextdictInfo;
-import org.springblade.manager.entity.WbsTreeContract;
-import org.springblade.manager.entity.WbsTreePrivate;
+import org.springblade.core.tool.utils.ObjectUtil;
+import org.springblade.manager.entity.*;
 import org.springblade.manager.mapper.WbsTreePrivateMapper;
+import org.springblade.manager.service.IExcelTabService;
 import org.springblade.manager.service.IWbsTreePrivateService;
 import org.springblade.manager.service.impl.ExcelTabServiceImpl;
 import org.springblade.manager.service.impl.TextdictInfoServiceImpl;
 import org.springblade.manager.service.impl.WbsTreeContractServiceImpl;
 import org.springblade.manager.vo.WbsTreeContractTreeVOS;
 import org.springblade.manager.vo.WbsTreePrivateVO;
+import org.springblade.manager.vo.WbsTreePrivateVO4;
 import org.springframework.jdbc.core.BeanPropertyRowMapper;
 import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.web.bind.annotation.RestController;
 
 import java.util.*;
+import java.util.function.Function;
 import java.util.stream.Collectors;
 
 @RestController
@@ -42,6 +44,7 @@ public class WbsTreePrivateClientImpl implements WbsTreePrivateClient {
     private final TextdictInfoServiceImpl textDictInfoService;
     private final WbsTreeContractServiceImpl wbsTreeContractService;
     private final WbsTreePrivateMapper privateMapper;
+    private final IExcelTabService iExcelTabService;
 
     @Override
     public List<WbsTreePrivate> queryAllNodeByProjectId(String projectId) {
@@ -215,7 +218,7 @@ public class WbsTreePrivateClientImpl implements WbsTreePrivateClient {
 
     @Override
     public List<Map<String, Object>> getTrialDataInfo(String pKeyId, Long id) {
-        return excelTabServiceImpl.getBussDataInfoTrial(id, Long.parseLong(pKeyId), null,null,null,null);
+        return excelTabServiceImpl.getBussDataInfoTrial(id, Long.parseLong(pKeyId), null,null,null,null,null);
     }
 
     @Override
@@ -262,6 +265,61 @@ public class WbsTreePrivateClientImpl implements WbsTreePrivateClient {
         return R.data(node);
     }
 
+    @Override
+    public R<List<WbsTreePrivateVO4>> searchNodeAllTable(String primaryKeyId, String type, String tableType, String contractId, String projectId, Integer isAdd, Long id) {
+        // 获取试验记录信息实体 从而获取委托单编号
+        TrialSelfInspectionRecord trialSelfInspectionRecord = null;
+        if(ObjectUtil.isNotEmpty(id)){
+            String sqlForInspectionRecord = "select entrust_id from u_trial_self_inspection_record  where id=" + id;
+            trialSelfInspectionRecord = jdbcTemplate.queryForObject(sqlForInspectionRecord, new BeanPropertyRowMapper<>(TrialSelfInspectionRecord.class));
+        }
+
+        List<WbsTreePrivateVO4> wbsTreePrivateVO4s = wbsTreePrivateService.searchNodeAllTable(primaryKeyId, type, tableType, contractId, projectId, isAdd, id);
+        for (WbsTreePrivateVO4 treePrivate : wbsTreePrivateVO4s) {
+            //试验新增
+            if ((new Integer(1).equals(isAdd)) && ObjectUtil.isEmpty(id)) {
+                //按钮状态
+                treePrivate.setPdfUrl(null);
+                treePrivate.setIsBussShow(ObjectUtil.isNotEmpty(treePrivate.getIsBussShow()) ? treePrivate.getIsBussShow() : 1); //新增时通过项目wbs表的isBussShow字段单独控制
+                treePrivate.setIsTabPdf(1);
+                treePrivate.setTabFileType(1);
+            }
+
+            //试验编辑
+            else if (ObjectUtil.isNotEmpty(id)) {
+                //返回委托单id
+                treePrivate.setEntrustId(trialSelfInspectionRecord.getEntrustId());
+                //获取当前试验记录信息中表的按钮状态
+                String sql = "select tab_id,is_buss_show,is_tab_pdf,is_tab_file_type from u_trial_self_data_record where record_id = " + id;
+                Map<Long, TrialSelfDataRecord> map = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(TrialSelfDataRecord.class)).stream().collect(Collectors.toMap(TrialSelfDataRecord::getTabId, Function.identity()));
+
+                //按钮状态
+                TrialSelfDataRecord record = map.get(treePrivate.getPKeyId());
+                if (record != null) {
+                    treePrivate.setIsBussShow(record.getIsBussShow()); //编辑时通过试验记录关联关系控制
+                    treePrivate.setIsTabPdf(record.getIsTabPdf());
+                    treePrivate.setTabFileType(record.getIsTabFileType());
+                } else {
+                    treePrivate.setPdfUrl(null);
+                    treePrivate.setIsBussShow(ObjectUtil.isNotEmpty(treePrivate.getIsBussShow()) ? treePrivate.getIsBussShow() : 1); //没有记录的就根据项目wbs表的isBussShow字段单独控制
+                    treePrivate.setIsTabPdf(1);
+                    treePrivate.setTabFileType(1);
+                }
+
+                //表单数据
+                List<Map<String, Object>> bussDataInfoTrial = iExcelTabService.getBussDataInfoTrial(id, treePrivate.getPKeyId(), Long.parseLong(contractId),null,null,null,null);
+                if (bussDataInfoTrial != null && bussDataInfoTrial.size() > 0) {
+                    bussDataInfoTrial.get(0).remove("group_id");
+                    treePrivate.setBussDataInfoTrial(bussDataInfoTrial.get(0));
+                    if(bussDataInfoTrial.get(0)!=null && Func.isNotEmpty(bussDataInfoTrial.get(0))){
+                        treePrivate.setLoadDataId(bussDataInfoTrial.get(0).get("loadDataId")+"");
+                    }
+                }
+            }
+        }
+        return R.data(wbsTreePrivateVO4s);
+    }
+
     private void foreachSetChildList(List<WbsTreeContractTreeVOS> vosResult, List<WbsTreePrivateVO> voList) {
         voList.forEach(wbsTreePrivateVO -> {
             WbsTreeContractTreeVOS vos = new WbsTreeContractTreeVOS();

+ 2 - 1
blade-service/blade-manager/src/main/java/org/springblade/manager/formula/FormulaStrategy.java

@@ -1,5 +1,6 @@
 package org.springblade.manager.formula;
 
+import org.springblade.core.secure.BladeUser;
 import org.springblade.manager.dto.FormData;
 import org.springblade.manager.formula.impl.TableElementConverter;
 
@@ -10,5 +11,5 @@ import java.util.Map;
  * @author yangyj
  */
 public interface FormulaStrategy extends IStrategy {
-    void execute(FormData cur,TableElementConverter tec);
+    void execute(FormData cur, TableElementConverter tec);
 }

+ 1 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/formula/FormulaStrategyFactory.java

@@ -1,6 +1,7 @@
 package org.springblade.manager.formula;
 
 import lombok.Data;
+import org.springblade.core.secure.BladeUser;
 import org.springblade.manager.dto.FormData;
 import org.springblade.manager.formula.impl.TableElementConverter;
 import org.springframework.stereotype.Component;

+ 3 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/ExecutorCalc.java

@@ -75,6 +75,9 @@ public class ExecutorCalc extends FormulaExecutor {
         /*并发说明:有依赖关系,需要按顺序执行,否则有可能取不到内容*/
         ExecuteFlow executeFlow=createExecuteFlow();
         for(FormData fd:tec.formDataList){
+            if(fd.getId().equals(1760570626336096285L)){
+                System.out.println("");
+            }
             if(fd.verify()){
                 try {
                     /*自定义脚本预处理*/

+ 142 - 6
blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/ExecutorMeter.java

@@ -2,26 +2,36 @@ package org.springblade.manager.formula.impl;
 
 import cn.hutool.log.StaticLog;
 import com.alibaba.fastjson.annotation.JSONField;
+import com.itextpdf.text.Chapter;
 import com.mixsmart.utils.CustomFunction;
 import com.mixsmart.utils.FormulaUtils;
 import com.mixsmart.utils.StringUtils;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
+import lombok.extern.slf4j.Slf4j;
 import org.springblade.common.utils.BaseUtils;
+import org.springblade.manager.dto.FormEndPayDTO;
+import org.springblade.manager.entity.ChapterEndPay;
+import org.springblade.manager.utils.PeriodContractUtil;
 import org.springblade.common.utils.SnowFlakeUtil;
 import org.springblade.core.oss.model.BladeFile;
 import org.springblade.core.tool.utils.Func;
+import org.springblade.core.tool.utils.ObjectUtil;
 import org.springblade.core.tool.utils.RegexUtil;
 import org.springblade.core.tool.utils.StringPool;
 import org.springblade.manager.dto.ElementData;
 import org.springblade.manager.dto.FormData;
 import org.springblade.manager.dto.TreeNode;
+import org.springblade.manager.entity.FormEndPay;
 import org.springblade.manager.formula.ElementWriter;
 import org.springblade.manager.formula.NodeTable;
+import org.springblade.manager.service.impl.FormEndPayServiceImpl;
+import org.springblade.manager.utils.FormEndPayUtil;
 import org.springblade.manager.vo.*;
+import org.springblade.meter.entity.ContractMeterPeriod;
 import org.springblade.meter.entity.InterimPayCertificateItem;
 import org.springframework.beans.BeanUtils;
-
+import org.springframework.transaction.annotation.Transactional;
 
 import java.math.BigDecimal;
 import java.math.RoundingMode;
@@ -31,7 +41,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.function.*;
-import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 import java.util.stream.IntStream;
 
@@ -40,6 +49,7 @@ import java.util.stream.IntStream;
  * @Date 2023/12/19 17:40
  * @description 计量相关报表计算
  */
+@Slf4j
 @EqualsAndHashCode(callSuper = true)
 @Data
 public class ExecutorMeter extends FormulaExecutor {
@@ -1035,6 +1045,29 @@ public class ExecutorMeter extends FormulaExecutor {
 
         @Override
         public void parse() {
+            FormEndPayDTO dto = PeriodContractUtil.get();
+            //本期期数ID
+            Long periodId=dto.getPeriodId();
+            //合同段ID
+            Long contractId=dto.getContractId();
+            //项目ID
+            Long projectId=dto.getProjectId();
+            //上期期数ID
+            Long prePeriodId = null;
+            List<ContractMeterPeriod> contractMeterPeriodList =FormEndPayUtil.selectList(contractId);
+            if(contractMeterPeriodList.size()>0){
+                OptionalInt index=IntStream.range(0, contractMeterPeriodList.size())
+                    .filter(i -> contractMeterPeriodList.get(i).getId().equals(periodId))
+                    .findFirst();
+                //i大于0 说明需要有上期
+                if(index.isPresent()){
+                    int j = index.getAsInt();
+                    if(j>0){
+                        prePeriodId=contractMeterPeriodList.get(j-1).getId();
+                    }
+                }
+            }
+            Long finalPrePeriodId = prePeriodId;
             builderFormDatas(InterimPaymentCertificate.class);
             /*数据获取start*/
              /*合同计量清单*/
@@ -1077,8 +1110,19 @@ public class ExecutorMeter extends FormulaExecutor {
                          ipc.setContractAmount(bmMoney[0].toString());
                          ipc.setRevisedAmount(bmMoney[1].toString());
                          ipc.setPreviousPeriodEndPay(StringUtils.handleNullZero(previousMoney.get(cm.getKey()),tec.getScale()));
+                         String k=cm.getKey();
+                         if(finalPrePeriodId!=null){
+                             if(BaseUtils.isNumber(cm.getKey())){
+                                 k=k+"章";
+                             }
+                             ChapterEndPay chapterEndPay= FormEndPayUtil.selectChapterEndPay(finalPrePeriodId, contractId, k);
+                             if(ObjectUtil.isNotEmpty(chapterEndPay)){
+                                 if(null!=chapterEndPay.getCurrentPeriodEndPay()){
+                                     ipc.setPreviousPeriodEndPay(chapterEndPay.getCurrentPeriodEndPay().toPlainString());
+                                 }
+                             }
+                         }
                          ipc.setCurrentPeriodPay(StringUtils.handleNull(currentMoney.get(cm.getKey())));
-
                          ipc.setCurrentPeriodChangeMoney(StringUtils.handleNullZero(sumChangeMoneyForChapter(changeTokenList0,ch)
                                  ,tec.getPayRadicScale()));
                          ipc.setPreviousPeriodEndChangeMoney(StringUtils.handleNullZero(sumChangeMoneyForChapter(changeTokenList1,ch)
@@ -1590,6 +1634,7 @@ public class ExecutorMeter extends FormulaExecutor {
     @Data
     @EqualsAndHashCode(callSuper = true)
     public  class SubIPaySum extends   BaseSpecial<SubprojectInterimPaymentSummary> implements Special{
+        private FormEndPayServiceImpl formEndPayService;
         /*分项工程中期支付汇总表*/
         @Override
         public boolean ready() {
@@ -1678,7 +1723,31 @@ public class ExecutorMeter extends FormulaExecutor {
 
        /*分项工程中期支付汇总表*/
         @Override
+        @Transactional
         public void parse() {
+            FormEndPayDTO dto = PeriodContractUtil.get();
+            //本期期数ID
+            Long periodId=dto.getPeriodId();
+            //合同段ID
+            Long contractId=dto.getContractId();
+            //项目ID
+            Long projectId=dto.getProjectId();
+            //上期期数ID
+            Long prePeriodId = null;
+            List<ContractMeterPeriod> list =FormEndPayUtil.selectList(contractId);
+            if(list.size()>0){
+                OptionalInt index=IntStream.range(0, list.size())
+                    .filter(i -> list.get(i).getId().equals(periodId))
+                    .findFirst();
+                //i大于0 说明需要有上期
+                if(index.isPresent()){
+                    int j = index.getAsInt();
+                    if(j>0){
+                        prePeriodId=list.get(j-1).getId();
+                    }
+                }
+            }
+            Long finalPrePeriodId = prePeriodId;
             builderFormDatas(SubprojectInterimPaymentSummary.class);
             LinkedHashMap<String,Summary> endSummary = toSummary(paymentsPeriodEnd);
             LinkedHashMap<String,Summary> preSummary = toSummary(previous);
@@ -1686,9 +1755,9 @@ public class ExecutorMeter extends FormulaExecutor {
             List<SubprojectInterimPaymentSummary> totalList = new ArrayList<>();
            /* List<String> numbers=  paymentsPeriodEnd.stream().map(Payment::getNumber).distinct().collect(Collectors.toList());*/
             LinkedHashMap<String,InventoryForm> numbersGroup=  tec.meterInfo.getInventoryForms().stream().filter(e->!tec.meterInfo.getChapter().contains(e)&&StringUtils.isNotEquals(0,e.getParentId())).collect(Collectors.toMap(InventoryForm::getFormNumber,e->e,(v1,v2)->v1,LinkedHashMap::new));
-            numbersGroup.forEach((number,itf)->{
+            numbersGroup.forEach((number, itf)->{
                 SubprojectInterimPaymentSummary sis = new SubprojectInterimPaymentSummary();
-                /*期汇总*/
+                /*期汇总*/
                 Summary pre =preSummary.get(number);
                 /*本期末汇总*/
                 Summary end = endSummary.get(number);
@@ -1701,6 +1770,9 @@ public class ExecutorMeter extends FormulaExecutor {
                 sis.setContractMoney(itf.getContractMoney());
                 sis.setChangeMoney(itf.getChangeMoney());
                 sis.setPrice(itf.getBidPrice());
+                if(sis.getFormNumber().equals("202-3-3")){
+                    System.out.println("111");
+                }
                 /*只要存在累计就显示*/
                 if(end!=null&&end.getContractMoney()!=null) {
                     if(cur!=null) {
@@ -1737,8 +1809,45 @@ public class ExecutorMeter extends FormulaExecutor {
                         sis.setPreviousPeriodPay(pre.getMoney().toPlainString());
                         sis.setPreviousPeriodCompleted(pre.getCompleted().toPlainString());
                     }
+                    if(finalPrePeriodId !=null){
+                        FormEndPay preFormEndPay = FormEndPayUtil.selectFoemEndPay(finalPrePeriodId,contractId,sis.getFormNumber());
+                        if(ObjectUtil.isNotEmpty(preFormEndPay)){
+                            if (preFormEndPay.getCurrentPeriodEndPay() != null) {
+                                sis.setPreviousPeriodPay(preFormEndPay.getCurrentPeriodEndPay().toPlainString());
+                            }
+                        }
+                    }
                     sis.setCompleted(end.getCompleted().toPlainString());
-                    sis.setCurrentPeriodEndPay(end.getMoney().toPlainString());
+                    //本期汇总的到本期末完成  //原来=(本期末汇总的本期支付金额) 现在=(上期末汇总的到本期末金额+本期汇总的金额)
+                    BigDecimal add;
+                    if(sis.getCurrentPeriodPay()!=null&&sis.getPreviousPeriodPay()!=null){
+                        add= new BigDecimal(sis.getCurrentPeriodPay()).add(new BigDecimal(sis.getPreviousPeriodPay()));
+                    }else if(sis.getCurrentPeriodPay() != null){
+                        add=new BigDecimal(sis.getCurrentPeriodPay());
+                    }else if(sis.getPreviousPeriodPay() != null){
+                        add=new BigDecimal(sis.getPreviousPeriodPay());
+                    } else {
+                        add=end.getMoney();
+                    }
+                    sis.setCurrentPeriodEndPay(add.toPlainString());
+                    FormEndPay formEndPay =FormEndPayUtil.selectFoemEndPay(periodId,contractId, sis.getFormNumber());
+                    if(ObjectUtil.isNotEmpty(formEndPay)){
+                        if(!add.equals(formEndPay.getCurrentPeriodEndPay())){
+                            formEndPay.setCurrentPeriodEndPay(add);
+                            FormEndPayUtil.updateFormEndPay(formEndPay);
+                        }
+                    }else {
+                        if(!BigDecimal.ZERO.equals(add)){
+                            formEndPay=new FormEndPay();
+                            formEndPay.setId(SnowFlakeUtil.getId());
+                            formEndPay.setProjectId(projectId);
+                            formEndPay.setPeriodId(periodId);
+                            formEndPay.setContractId(contractId);
+                            formEndPay.setFormNumber(sis.getFormNumber());
+                            formEndPay.setCurrentPeriodEndPay(add);
+                            FormEndPayUtil.insertFormEndPay(formEndPay);
+                        }
+                    }
                     BigDecimal percent= BaseUtils.str2BigDecimal(ratioFc.apply(sis.getCurrentPeriodEndPay(), sis.getChangeMoney()));
                     if(BigDecimal.ZERO.compareTo(percent)<0) {
                         /*百分比大于零才显示*/
@@ -1795,6 +1904,33 @@ public class ExecutorMeter extends FormulaExecutor {
                     if(m>1) {
                         /*本章小结*/
                         subtotal(new SubprojectInterimPaymentSummary("章合计"),tmp,v,tec.getScale());
+                        //把每章的到本期末合计金额存入数据库
+                        if(BaseUtils.isNumber(k)){
+                            k=k+"章";
+                        }
+                        ChapterEndPay chapterEndPay = FormEndPayUtil.selectChapterEndPay(periodId, contractId, k);
+                        SubprojectInterimPaymentSummary sm = tmp.get(tmp.size() - 1);
+                        BigDecimal money=BigDecimal.ZERO;
+                        if(null!=sm.getCurrentPeriodEndPay()){
+                            money=new BigDecimal(sm.getCurrentPeriodEndPay());
+                        }
+                        if(money.compareTo(BigDecimal.ZERO)!=0){
+                            if(ObjectUtil.isNotEmpty(chapterEndPay)){
+                                if(!chapterEndPay.getCurrentPeriodEndPay().equals(money)){
+                                    chapterEndPay.setCurrentPeriodEndPay(money);
+                                    FormEndPayUtil.updateChapterEndPay(chapterEndPay);
+                                }
+                            }else {
+                                chapterEndPay=new ChapterEndPay();
+                                chapterEndPay.setId(SnowFlakeUtil.getId());
+                                chapterEndPay.setProjectId(projectId);
+                                chapterEndPay.setPeriodId(periodId);
+                                chapterEndPay.setContractId(contractId);
+                                chapterEndPay.setFormNumber(k);
+                                chapterEndPay.setCurrentPeriodEndPay(money);
+                                FormEndPayUtil.insertChapterEndPay(chapterEndPay);
+                            }
+                        }
                     }
                     if(m>2){
                         /*所有章合计*/

+ 2 - 1
blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/FormulaMileage.java

@@ -6,6 +6,7 @@ import com.mixsmart.utils.ListUtils;
 import com.mixsmart.utils.StringUtils;
 import lombok.Data;
 import org.springblade.business.feign.MileageClient;
+import org.springblade.core.secure.BladeUser;
 import org.springblade.core.tool.utils.Func;
 import org.springblade.manager.dto.ElementData;
 import org.springblade.manager.dto.FormData;
@@ -44,7 +45,7 @@ public class FormulaMileage implements FormulaStrategy {
 
 
     @Override
-    public void execute(FormData cur,TableElementConverter tec) {
+    public void execute(FormData cur, TableElementConverter tec) {
         List<String> relyList = cur.getFormula().getRelyList();
         if (relyList.size() < KEYS.size()) {
             return;

+ 2 - 1
blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/FormulaTurnPoint.java

@@ -6,6 +6,7 @@ import com.mixsmart.utils.CustomFunction;
 import com.mixsmart.utils.FormulaUtils;
 import com.mixsmart.utils.StringUtils;
 import lombok.Data;
+import org.springblade.core.secure.BladeUser;
 import org.springblade.core.tool.utils.BeanUtil;
 import org.springblade.core.tool.utils.Func;
 import org.springblade.core.tool.utils.StringPool;
@@ -50,7 +51,7 @@ public class FormulaTurnPoint implements FormulaStrategy {
     }
 
     @Override
-    public void execute(FormData cur,TableElementConverter tec) {
+    public void execute(FormData cur, TableElementConverter tec) {
         cur.setFinished(Boolean.TRUE);
         LinkedHashMap<String, FormData> dataSourceMap = new LinkedHashMap<>();
         String funArgs = ReUtil.getGroup1(TURN_REG, cur.getFormula().getFormula());

+ 12 - 2
blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/FormulaZhiZuo.java

@@ -1,24 +1,34 @@
 package org.springblade.manager.formula.impl;
 
 import cn.hutool.core.util.ObjectUtil;
-import com.mixsmart.utils.StringUtils;
+
 import lombok.Data;
+import org.springblade.core.redis.cache.BladeRedis;
+
+import org.springblade.core.secure.BladeUser;
 import org.springblade.manager.bean.TableInfo;
 import org.springblade.manager.dto.ElementData;
 import org.springblade.manager.dto.FormData;
 import org.springblade.manager.entity.Formula;
 import org.springblade.manager.formula.FormulaStrategy;
+
+import org.springblade.manager.utils.RandomNumberHolder;
 import org.springframework.stereotype.Component;
 
 import java.util.*;
 
+
 @Component
 @Data
 public class FormulaZhiZuo implements FormulaStrategy {
+
     @Override
     public void execute(FormData cur, TableElementConverter tec) {
         String key = cur.getFormula().getRely().substring(cur.getFormula().getRely().indexOf(':') + 1);
-        String s = tec.getTableInfoList().get(0).getDataMap().get(key);
+        HashMap<Long, String> randomNumber = RandomNumberHolder.getRandomNumber();
+        Map.Entry<Long, String> firstMap = randomNumber.entrySet().iterator().next();
+        Optional<TableInfo> firstTableInfo = tec.getTableInfoList().stream().filter(tableInfo->tableInfo.getPkeyId().equals(firstMap.getKey().toString())).findFirst();
+        String s = firstTableInfo.get().getDataMap().get(key);
         String[] strings = s.split("☆");
         Map<Integer, Double> list = new HashMap<>();
         for (int i = 0; i < strings.length; i++) {

+ 27 - 1
blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/TableElementConverter.java

@@ -2,6 +2,7 @@ package org.springblade.manager.formula.impl;
 
 
 import cn.hutool.core.util.HashUtil;
+import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.log.StaticLog;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
@@ -21,8 +22,10 @@ import org.springblade.manager.formula.FormulaLog;
 import org.springblade.manager.formula.ITableElementConverter;
 import org.springblade.manager.formula.KeyMapper;
 import org.springblade.manager.formula.NodeTable;
+import org.springblade.manager.utils.RandomNumberHolder;
 import org.springblade.manager.vo.*;
 import org.springblade.resource.feign.NewIOSSClient;
+import org.springframework.jdbc.core.JdbcTemplate;
 
 import java.util.*;
 import java.util.function.Predicate;
@@ -426,12 +429,35 @@ public class TableElementConverter implements ITableElementConverter {
                                 }
                             }
                             LinkedHashMap<Integer, List<ElementData>> pages = elementDataList.stream().collect(Collectors.groupingBy(ElementData::getIndex, LinkedHashMap::new, Collectors.toList()));
-                            for (int i = 0; i < pages.size(); i++) {
+                            if(ObjectUtil.isNotEmpty(fd.getFormula())&&ObjectUtil.isNotEmpty(fd.getFormula().getNumber())&&"ZHIZUO".equals(fd.getFormula().getNumber())){
+                                HashMap<Long, String> map = RandomNumberHolder.getRandomNumber();
+                                if(!map.entrySet().isEmpty()){
+                                    String nodeName = map.entrySet().iterator().next().getValue();
+                                    if(nodeName.indexOf("__")!=-1){
+                                        String num = nodeName.substring(nodeName.indexOf("__") + 2);
+                                        int i = Integer.parseInt(num);
+                                        List<ElementData> p = pages.get(0);
+                                        TableInfo info = tables.get(i);
+                                        info.setToBeUpdated(true);
+                                        info.getDataMap().put(fd.getKey(), FormulaUtils.recovery(p));
+                                    }else {
+                                        for (int i = 0; i < pages.size(); i++) {
+                                        /*每一页映射一个tableInfo*/
+                                        List<ElementData> p = pages.get(i);
+                                        TableInfo info = tables.get(i);
+                                        info.setToBeUpdated(true);
+                                        info.getDataMap().put(fd.getKey(), FormulaUtils.recovery(p));
+                                        }
+                                    }
+                                }
+                            }else {
+                                for (int i = 0; i < pages.size(); i++) {
                                 /*每一页映射一个tableInfo*/
                                 List<ElementData> p = pages.get(i);
                                 TableInfo info = tables.get(i);
                                 info.setToBeUpdated(true);
                                 info.getDataMap().put(fd.getKey(), FormulaUtils.recovery(p));
+                                }
                             }
                         } catch (Exception e) {
                             StaticLog.error("元素{}回写报错", fd.getCode());

+ 44 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/FormEndPayMapper.java

@@ -0,0 +1,44 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.manager.mapper;
+
+import feign.Param;
+import org.springblade.manager.entity.FormEndPay;
+import org.springblade.manager.vo.FormEndPayVO;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import java.util.List;
+
+/**
+ *  Mapper 接口
+ *
+ * @author BladeX
+ * @since 2024-12-02
+ */
+public interface FormEndPayMapper extends BaseMapper<FormEndPay> {
+
+	/**
+	 * 自定义分页
+	 *
+	 * @param page
+	 * @param formEndPay
+	 * @return
+	 */
+	List<FormEndPayVO> selectFormEndPayPage(IPage page, FormEndPayVO formEndPay);
+
+
+}

+ 14 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/FormEndPayMapper.xml

@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.springblade.manager.mapper.FormEndPayMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="formEndPayResultMap" type="org.springblade.manager.entity.FormEndPay">
+        <result column="id" property="id"/>
+        <result column="period_id" property="periodId"/>
+        <result column="contract_id" property="contractId"/>
+        <result column="form_number" property="formNumber"/>
+        <result column="current_period_end_pay" property="currentPeriodEndPay"/>
+    </resultMap>
+
+</mapper>

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

@@ -796,6 +796,7 @@
         </foreach>
         AND project_id = #{projectId}
         AND wbs_id = #{wbsId}
+        AND is_deleted = 0
     </select>
 
 

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

@@ -123,7 +123,7 @@ public interface WbsTreePrivateMapper extends EasyBaseMapper<WbsTreePrivate> {
 
     List<Long> linkNodeTreeBynodeId(@Param("pkeyid") String pkeyid);
 
-    void batchUpdateIsAddConceal(@Param("private") WbsTreePrivate wbsTreePrivate);
+    void batchUpdateIsAddConceal(@Param("private") WbsTreePrivate wbsTreePrivate,@Param("pId") Long pId);
 
     List<ArchiveSyncLogVO> getContractAllLog(@Param("contractId") Long contractId);
 }

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

@@ -7,6 +7,7 @@
         <result column="project_id" property="projectId"/>
         <result column="p_key_id" property="pKeyId"/>
         <result column="id" property="id"/>
+        <result column="tree_p_id" property="treePId"/>
         <result column="w_id" property="wbsId"/>
         <result column="is_deleted" property="isDeleted"/>
         <result column="status" property="status"/>
@@ -895,7 +896,7 @@
         update m_wbs_tree_private
         set is_add_conceal = #{private.isAddConceal}
         where project_id = #{private.projectId}
-            and FIND_IN_SET(#{private.id},ancestors) > 0
+            and FIND_IN_SET(#{pId},ancestors) > 0
     </update>
 
     <select id="linkNodeTreeBynodeId" resultType="java.lang.Long" >

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

@@ -17,6 +17,7 @@
 package org.springblade.manager.service;
 
 import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import org.jsoup.nodes.Document;
 import org.springblade.business.dto.TrialSelfInspectionRecordDTO;
@@ -136,7 +137,7 @@ public interface IExcelTabService extends BaseService<ExcelTab> {
     /**
      * 获取试验用户端 单个表单接口数据
      */
-    List<Map<String, Object>> getBussDataInfoTrial(Long id, Long pkeyId, Long contractId, Long entrustId, Integer type,Long nodeId);
+    List<Map<String, Object>> getBussDataInfoTrial(Long id, Long pkeyId, Long contractId, Long entrustId, Integer type,Long nodeId,JSONObject jsonObject);
 
     /**
      * 获取试验用户端 单个表单接口数据 - 关联施工
@@ -209,5 +210,5 @@ public interface IExcelTabService extends BaseService<ExcelTab> {
      * @param contractId
      * @return
      */
-    List<Map<String, Object>> getBussDataInfoTrialentrust(Long id, Long pkeyId, Long contractId, Long sampleId);
+    List<Map<String, Object>> getBussDataInfoTrialentrust(Long id, Long pkeyId, Long contractId, Long sampleId, JSONObject jsonObject);
 }

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

@@ -0,0 +1,46 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.manager.service;
+
+import org.springblade.manager.entity.FormEndPay;
+import org.springblade.manager.vo.FormEndPayVO;
+import org.springblade.core.mp.base.BaseService;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import org.springblade.meter.entity.ContractMeterPeriod;
+
+import java.util.List;
+
+/**
+ *  服务类
+ *
+ * @author BladeX
+ * @since 2024-12-02
+ */
+public interface IFormEndPayService extends BaseService<FormEndPay> {
+
+	/**
+	 * 自定义分页
+	 *
+	 * @param page
+	 * @param formEndPay
+	 * @return
+	 */
+	IPage<FormEndPayVO> selectFormEndPayPage(IPage<FormEndPayVO> page, FormEndPayVO formEndPay);
+
+
+
+}

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

@@ -11,6 +11,7 @@ import org.springblade.manager.formula.impl.TableElementConverter;
 import org.springblade.manager.vo.ReportResult;
 
 import javax.validation.constraints.NotNull;
+import java.io.FileNotFoundException;
 import java.util.List;
 import java.util.Map;
 
@@ -90,7 +91,7 @@ public interface IFormulaService extends BaseService<Formula> {
     /**获取当前节点的参数wbsNodeId:WBS级id ,wtpPkeyId:项目级PkeyId*/
     List<WbsParam> getNodeWps(Long wbsNodeId,Long wtpPkeyId);
     /**计量公式执行 0中间,1材料,2开工*/
-    List<ReportResult> execute3(Long contractId, Long periodId, Integer type);
+    List<ReportResult> execute3(Long contractId, Long periodId, Integer type,Long perIodId1,Long projectId);
 
    /**获取当前节点的所有元素执行公式,可以按表和元素名筛选*/
     R<Object>formulasForNode(Long pkeyId,String tableName,String elementName);
@@ -100,5 +101,5 @@ public interface IFormulaService extends BaseService<Formula> {
     R<Object> syncWorkDate(@NotNull(message = "节点ID不能为空") Long nodeId);
 
     /** 万盛计量专用统计数据*/
-    List<ReportResult> execute4(Long contractId, Long periodId, Integer type);
+    List<ReportResult> execute4 (Long reportId,Long contractId, Long periodId, Integer type,Long projectId) throws FileNotFoundException, IllegalAccessException;
 }

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

@@ -105,4 +105,6 @@ public interface IWbsTreePrivateService extends BaseService<WbsTreePrivate> {
     List<Long> linkNodeTreeBynodeId(String pkeyId);
 
     List<ArchiveSyncLogVO> getContractAllLog(Long contractId);
+
+    void diGuiWbs(int i);
 }

+ 152 - 111
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ExcelTabServiceImpl.java

@@ -23,6 +23,8 @@ import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 import org.apache.poi.ss.usermodel.*;
 import org.apache.poi.ss.util.CellRangeAddress;
 import org.apache.poi.util.IOUtils;
+import org.apache.poi.xssf.usermodel.XSSFFont;
+import org.apache.poi.xssf.usermodel.XSSFRichTextString;
 import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 import org.jsoup.Jsoup;
 import org.jsoup.nodes.Document;
@@ -67,6 +69,7 @@ import org.springblade.manager.vo.*;
 import org.springblade.resource.feign.NewIOSSClient;
 import org.springblade.system.cache.ParamCache;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Lazy;
 import org.springframework.dao.DataAccessException;
 import org.springframework.data.redis.core.StringRedisTemplate;
 import org.springframework.jdbc.core.BeanPropertyRowMapper;
@@ -75,6 +78,7 @@ import org.springframework.jdbc.datasource.DataSourceTransactionManager;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.TransactionDefinition;
 import org.springframework.transaction.TransactionStatus;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.transaction.support.DefaultTransactionDefinition;
 
 import java.io.*;
@@ -639,6 +643,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
      * 保存日志
      */
     @Override
+    @Transactional
     public String saveOrUpdateTheLog(List<TableInfo> tableInfoList) {
         //查询绑定的节点
         WbsTreePrivate tableNode = this.wbsTreePrivateService.getOne(Wrappers.<WbsTreePrivate>lambdaQuery().eq(WbsTreePrivate::getPKeyId, tableInfoList.get(0).getPkeyId()));
@@ -678,8 +683,8 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
 
         //删除旧数据
         if (StringUtils.isNotEmpty(businessIds)) {
-            //删除实体表数据、关联工序信息
-            String delSql = "delete from " + tableNode.getInitTableName() + " where id in(" + businessIds + "); delete from u_contract_log_wbs where business_id in(" + businessIds + ")";
+            //删除实体表数据、
+            String delSql = "delete from " + tableNode.getInitTableName() + " where id in(" + businessIds + ")";
             this.jdbcTemplate.execute(delSql);
         }
         if (StringUtils.isNotEmpty(ids)) {
@@ -687,17 +692,21 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
             String delSql = "delete from u_contract_log where id in(" + ids + ")";
             this.jdbcTemplate.execute(delSql);
             //添加操作日志
-            String delSqlNew = delSql.replace("\"", "'");
-            StringBuffer sb = new StringBuffer();
-            sb.append("insert into blade_log_sql (p_key_id,contract_log_id,user_id,create_time,sql_info) VALUES");
-            sb.append("(" + tableNode.getPKeyId());
-            sb.append("," + ids);
-            sb.append(","+ AuthUtil.getUserId());
-            sb.append(",SYSDATE()");
-            sb.append(",\"");
-            sb.append(delSqlNew);
-            sb.append("\")");
-            jdbcTemplate.execute(sb.toString());
+            try {
+                String delSqlNew = delSql.replace("\"", "'");
+                StringBuffer sb = new StringBuffer();
+                sb.append("insert into blade_log_sql (p_key_id,contract_log_id,user_id,create_time,sql_info) VALUES");
+                sb.append("(" + tableNode.getPKeyId());
+                sb.append(",\"" + ids+"\"");
+                sb.append(","+ AuthUtil.getUserId());
+                sb.append(",SYSDATE()");
+                sb.append(",\"");
+                sb.append(delSqlNew);
+                sb.append("\")");
+                jdbcTemplate.execute(sb.toString());
+            } catch (DataAccessException e) {
+                log.error("添加操作日志异常:ExcelTabServiceImpl-saveOrUpdateTheLog() 搜索代码:jdbcTemplate.execute(sb.toString());");
+            }
         }
 
         List<String> dataIds = new LinkedList<>();
@@ -734,6 +743,9 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                 String errorMessage = e.getMessage();
                 if (StringUtils.isNotEmpty(errorMessage)) {
                     String errorKey = null;
+                    if(errorMessage.contains("bad SQL grammar")){
+                        throw new ServiceException("存在不规则特殊字符,新增失败");
+                    }
                     if (errorMessage.contains("long for column ") && errorMessage.contains(" at ")) {
                         errorKey = errorMessage.split("long for column ")[1].split(" at ")[0];
                     }
@@ -747,6 +759,8 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                                 errorKeyName = tabElement.getEName();
                             }
                         }
+                    }else {
+                        throw new RuntimeException("新增数据异常");
                     }
                 }
                 e.printStackTrace();
@@ -778,22 +792,30 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                 parentNode.getMajorDataType(),
                 recordTime,
                 logWbsList,
-                oldDataId
+                oldDataId,
+                businessIds
         ));
+        if("新增异常".equals(dataId)){
+            throw new ServiceException("日志文件新增异常");
+        }
         if (StringUtils.isNotEmpty(dataId)) {
-            for (String insterTataSql : insterTataSqls) {
-                //添加操作日志
-                String sqlNew = insterTataSql.toString().replace("\"", "'");
-                StringBuffer sb = new StringBuffer();
-                sb.append("insert into blade_log_sql (p_key_id,contract_log_id,user_id,create_time,sql_info) VALUES ");
-                sb.append("("+tableNode.getPKeyId());
-                sb.append(","+dataId);
-                sb.append(","+AuthUtil.getUserId());
-                sb.append(",SYSDATE()");
-                sb.append(",\"");
-                sb.append(sqlNew);
-                sb.append("\")");
-                jdbcTemplate.execute(sb.toString());
+            try {
+                for (String insterTataSql : insterTataSqls) {
+                    //添加操作日志
+                    String sqlNew = insterTataSql.toString().replace("\"", "'");
+                    StringBuffer sb = new StringBuffer();
+                    sb.append("insert into blade_log_sql (p_key_id,contract_log_id,user_id,create_time,sql_info) VALUES ");
+                    sb.append("("+tableNode.getPKeyId());
+                    sb.append(","+dataId);
+                    sb.append(","+AuthUtil.getUserId());
+                    sb.append(",SYSDATE()");
+                    sb.append(",\"");
+                    sb.append(sqlNew);
+                    sb.append("\")");
+                    jdbcTemplate.execute(sb.toString());
+                }
+            } catch (DataAccessException e) {
+                log.error("添加操作日志异常 ExcelTabServiceImpl-saveOrUpdateTheLog()方法 搜索代码:for (String insterTataSql : insterTataSqls) { ");
             }
             dataIds.add(dataId);
         }
@@ -2026,10 +2048,6 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                 }
             }
         }
-
-        if (pkeyId == 1783397446617923584L) {
-            System.out.println("1231");
-        }
         //数据不为空
         if (StringUtils.isNotEmpty(wbsTreeContract.getHtmlUrl())) {
             InputStream inputStreamByUrl = FileUtils.getInputStreamByUrl(wbsTreeContract.getHtmlUrl());
@@ -2236,20 +2254,59 @@ 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);
+//                            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();
+                            // 获取单元格的现有富文本字符串
+                            RichTextString existingRichTextString = cell.getRichStringCellValue();
+                             // 创建一个新的副文本字符串,原有值+电签ID
+                            RichTextString richTextString = workbook.getCreationHelper().createRichTextString(existingValue + dqid);
+                            // 复制原有部分的字体格式
+                            if (existingRichTextString instanceof XSSFRichTextString) {
+                                XSSFRichTextString xssfRichTextString = (XSSFRichTextString) existingRichTextString;
+                                for (int i = 0; i < xssfRichTextString.numFormattingRuns(); i++) {
+                                    XSSFFont runFont = xssfRichTextString.getFontOfFormattingRun(i);
+                                    Font font = workbook.createFont();
+                                    font.setColor(runFont.getXSSFColor().getIndexed());
+                                    font.setFontHeightInPoints(runFont.getFontHeightInPoints());
+                                    font.setBold(runFont.getBold());
+                                    font.setItalic(runFont.getItalic());
+                                    font.setUnderline(runFont.getUnderline());
+                                    font.setTypeOffset(runFont.getTypeOffset());
+                                    font.setCharSet(runFont.getCharSet());
+                                    font.setStrikeout(runFont.getStrikeout());
+                                    font.setFontName(runFont.getFontName());
+                                    int startIdx = xssfRichTextString.getIndexOfFormattingRun(i);
+                                    int endIdx = Math.min(startIdx + xssfRichTextString.getLengthOfFormattingRun(i), existingValue.length());
+                                    //根据原有值的长度,起始位置和结束位置设置成原有的文本格式
+                                    richTextString.applyFont(startIdx, endIdx, font);
+                                }
+                            } else {
+                                // 如果没有富文本格式,则使用默认字体
+                                Font defaultFont = workbook.createFont();
+                                richTextString.applyFont(0, existingValue.length(), defaultFont);
+                            }
+                            // 设置新增部分的字体
+                            Font newFont = workbook.createFont();
+                            newFont.setColor(IndexedColors.WHITE.getIndex());
+                            newFont.setFontHeightInPoints(Short.valueOf("1")); // 可根据需要调整字体大小
+                            //从原有值之后,电签ID开始设置成新的格式。
+                            richTextString.applyFont(existingValue.length(), existingValue.length() + dqid.length(), newFont);
+                             // 将副文本字符串设置到单元格
+                            cell.setCellValue(richTextString);
                         }
                     }
                 }
@@ -2470,7 +2527,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
      * 试验 获取填报信息
      */
     @Override
-    public List<Map<String, Object>> getBussDataInfoTrial(Long groupId, Long pkeyId, Long contractId, Long entrustId, Integer type,Long nodeId) {
+    public List<Map<String, Object>> getBussDataInfoTrial(Long groupId, Long pkeyId, Long contractId, Long entrustId, Integer type,Long nodeId,JSONObject jsonObject) {
         String file_path = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
         String sys_file_net_url = ParamCache.getValue(CommonConstant.SYS_FILE_NET_URL);
         List<Map<String, Object>> list = new ArrayList<>();
@@ -2484,7 +2541,6 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
         if (wbsTreePrivate.getHtmlUrl() == null) {
             return list;
         }
-
         //表单是否存储在
         String tabName = wbsTreePrivate.getInitTableName();
         String isExitSql = "select * from information_schema.TABLES where TABLE_NAME='" + tabName + "'";
@@ -2763,6 +2819,15 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
         reData.remove("pkeyId");
         reData.remove("projectId");
         chart(reData, wbsTreePrivate);
+        if(ObjectUtil.isNotEmpty(jsonObject)){
+            for (Map.Entry<String, Object> entry : jsonObject.entrySet()) {
+                if(entry.getKey().contains("key")){
+                    if(!reData.containsKey(entry.getKey())){
+                        reData.put(entry.getKey(),entry.getValue());
+                    }
+                }
+            }
+        }
         list.add(reData);
         return list;
     }
@@ -2973,7 +3038,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
         }
 
         //获取数据信息info
-        List<Map<String, Object>> bussDataInfoTrial = this.getBussDataInfoTrial(id, pkeyId, Long.parseLong(contractId),null,null,null);
+        List<Map<String, Object>> bussDataInfoTrial = this.getBussDataInfoTrial(id, pkeyId, Long.parseLong(contractId),null,null,null,null);
         Map<String, Object> DataInfo = new HashMap<>();
         if (bussDataInfoTrial.size() > 0) {
             DataInfo.putAll(bussDataInfoTrial.stream().findAny().orElse(null));
@@ -2994,9 +3059,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
         ProjectInfo projectInfo = projectInfoService.getById(wbsTreePrivate.getProjectId());
         int all = sheet.getRow(0).getLastCellNum();
         int mergedCellCnt = sheet.getNumMergedRegions();
-        for (
-                int i = 0;
-                i < mergedCellCnt - 1; i++) {
+        for (int i = 0; i < mergedCellCnt - 1; i++) {
             CellRangeAddress mergedCell = sheet.getMergedRegion(i);
             int xx = mergedCell.getNumberOfCells();
             if (xx <= all) {
@@ -3129,15 +3192,6 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                                         }
 
                                         // 特殊处理多选框
-                                      /*  if(data.toString().indexOf("el-select")>=0 && myData.indexOf("[")>=0 && myData.indexOf(",")<0){
-                                            System.out.println("123123");
-                                            myData = myData.replace("[","").replace("]","");
-                                        }*/
-
-
-
-                                        //https:bladex-test-info.oss-cn-chengdu.aliyuncs.com//upload/20220819/b53cb6700db369381e3b03d7737bcdec.jpg__16_1
-                                        //http:bladex-test-info.oss-cn-chengdu.aliyuncs.com//upload/20220819/b53cb6700db369381e3b03d7737bcdec.jpg__16_1 可能是http
                                         if (myData.contains("http") && myData.contains("aliyuncs")) {
                                             InputStream imageIn = CommonUtil.getOSSInputStream(myData);
                                             byte[] byteNew = new byte[0];
@@ -3207,55 +3261,33 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                 }
 
                 // 组装电签设置
-                QueryWrapper<TextdictInfo> queryWrapper = new QueryWrapper<>();
-                queryWrapper.select("col_key", "id");
-                queryWrapper.in("type", 2, 6);
-                queryWrapper.eq("tab_id", wbsTreePrivate.getPKeyId());
-
-                List<TextdictInfo> textdictInfos = textdictInfoService.getBaseMapper().selectList(queryWrapper);
-                if (textdictInfos != null && !textdictInfos.isEmpty()) {
-                    for (TextdictInfo e : textdictInfos) {
-                        String key = e.getColKey();
-                        String[] keys = key.split("__");
-                        String[] trtd = keys[1].split("_");
-                        if (Integer.parseInt(trtd[0]) < trs.size()) {
-                            Element ytzData = trs.get(Integer.parseInt(trtd[0]));
-                            if (ytzData != null) {
-                                Elements tdsx = ytzData.select("td");
-                                if (Integer.parseInt(trtd[1]) < tdsx.size()) {
-                                    Element data = ytzData.select("td").get(Integer.parseInt(trtd[1]));
-                                    if (data.html().contains("el-tooltip")) {
-                                        data = data.children().get(0);
-                                    }
-
-                                    int x1 = Integer.parseInt(data.children().get(0).attr("x1"));
-                                    if (x1 == 0) {
-                                        x1 = 1;
-                                    }
-                                    int y1 = Integer.parseInt(data.children().get(0).attr("y1"));
-
-                                    Row row = sheet.getRow(y1 - 1);
-                                    if (row != null) {
-                                        Cell cell = sheet.getRow(y1 - 1).getCell(x1 - 1);
-                                        if (cell != null) {
-                                            short fontIndex = cell.getCellStyle().getFontIndex();
-                                            Font oldfontAt = workbook.getFontAt(fontIndex);
+                Elements dqids = table.getElementsByAttribute("dqid");
+                for (Element element : dqids) {
+                    String dqid = element.attr("dqid");
+                    Elements x11 = element.getElementsByAttribute("x1");
+                    if (x11 != null && x11.size() >= 1) {
+                        Element element1 = x11.get(x11.size() - 1);
+                        int x1 = Func.toInt(element1.attr("x1"));
+                        int y1 = Func.toInt(element1.attr("y1"));
 
-                                            Font redFont = workbook.createFont();
-                                            redFont.setColor(IndexedColors.WHITE.getIndex()); //设置字体颜色
-                                            redFont.setFontHeightInPoints(oldfontAt.getFontHeightInPoints());//设置字体大小
-                                            redFont.setFontName(oldfontAt.getFontName());//设置字体
+                        Row row = sheet.getRow(y1 - 1);
+                        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);
-                                            cell.setCellStyle(newStyle);
-                                            cell.setCellValue(e.getId() + "");
-                                        } else {
-                                            ObjectUtils.isNotEmpty(cell);
-                                        }
-                                    }
-                                }
+                                CellStyle newStyle = workbook.createCellStyle(); //创建单元格样式
+                                newStyle.cloneStyleFrom(cell.getCellStyle());
+                                newStyle.setFont(redFont);
+                                newStyle.setShrinkToFit(true);
+                                cell.setCellStyle(newStyle);
+                                cell.setCellValue(dqid);
                             }
                         }
                     }
@@ -3940,9 +3972,9 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
         int index = excelTab.getFileUrl().lastIndexOf(".");
         String suffix = excelTab.getFileUrl().substring(index);
 
-        if (".xls".equals(suffix)) {
+        if (".xls".equalsIgnoreCase(suffix)) {
             workbook = new XSSFWorkbook(exceInp);
-        } else if (".xlsx".equals(suffix)) {
+        } else if (".xlsx".equalsIgnoreCase(suffix)) {
             workbook = new XSSFWorkbook(exceInp);
         }
 
@@ -4060,7 +4092,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
         }
 
         //获取数据信息info
-        List<Map<String, Object>> bussDataInfoTrial = this.getBussDataInfoTrial(groupId, pkeyId, Long.parseLong(contractId),null,null,null);
+        List<Map<String, Object>> bussDataInfoTrial = this.getBussDataInfoTrial(groupId, pkeyId, Long.parseLong(contractId),null,null,null,null);
         Map<String, Object> DataInfo = new HashMap<>();
         if (bussDataInfoTrial.size() > 0) {
             DataInfo.putAll(bussDataInfoTrial.stream().findAny().orElse(null));
@@ -4441,7 +4473,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
      * 试验 委托单获取填报信息  groupId和sampleId1必须传其中一个
      */
     @Override
-    public List<Map<String, Object>> getBussDataInfoTrialentrust(Long groupId, Long pkeyId, Long contractId,Long sampleId1) {
+    public List<Map<String, Object>> getBussDataInfoTrialentrust(Long groupId, Long pkeyId, Long contractId,Long sampleId1,JSONObject jsonObject) {
         String file_path = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
         String sys_file_net_url = ParamCache.getValue(CommonConstant.SYS_FILE_NET_URL);
         List<Map<String, Object>> list = new ArrayList<>();
@@ -4618,6 +4650,15 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
         reData.remove("pkeyId");
         reData.remove("projectId");
         chart(reData, wbsTreePrivate);
+        if(ObjectUtil.isNotEmpty(jsonObject)){
+            for (Map.Entry<String, Object> entry : jsonObject.entrySet()) {
+                if(entry.getKey().contains("key")){
+                    if(!reData.containsKey(entry.getKey())){
+                        reData.put(entry.getKey(),entry.getValue());
+                    }
+                }
+            }
+        }
         list.add(reData);
         return list;
     }

+ 52 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormEndPayServiceImpl.java

@@ -0,0 +1,52 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.manager.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.springblade.manager.entity.FormEndPay;
+import org.springblade.manager.vo.FormEndPayVO;
+import org.springblade.manager.mapper.FormEndPayMapper;
+import org.springblade.manager.service.IFormEndPayService;
+import org.springblade.core.mp.base.BaseServiceImpl;
+import org.springblade.meter.entity.ContractMeterPeriod;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.jdbc.core.BeanPropertyRowMapper;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Service;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+
+import javax.annotation.Resource;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ *  服务实现类
+ *
+ * @author BladeX
+ * @since 2024-12-02
+ */
+@Service
+public class FormEndPayServiceImpl extends BaseServiceImpl<FormEndPayMapper, FormEndPay> implements IFormEndPayService {
+
+    @Override
+	public IPage<FormEndPayVO> selectFormEndPayPage(IPage<FormEndPayVO> page, FormEndPayVO formEndPay) {
+		return page.setRecords(baseMapper.selectFormEndPayPage(page, formEndPay));
+	}
+
+
+}

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

@@ -117,7 +117,7 @@ public class FormulaDaoImpl implements IFormulaDao {
     @Override
     public Function<Long, MeterApproveOpinion> getApproveOpinionFc() {
         return  periodId-> {
-            List<MeterApproveOpinion> beans = this.jdbcTemplate.query("select b.* from u_task  a join s_meter_approve_opinion b on a.id=b.task_id where a.form_data_id="+periodId, new BeanPropertyRowMapper<>(MeterApproveOpinion.class));
+            List<MeterApproveOpinion> beans = this.jdbcTemplate.query("select b.* from u_task  a join s_meter_approve_opinion b on a.id=b.task_id where  a.form_data_id="+periodId, new BeanPropertyRowMapper<>(MeterApproveOpinion.class));
             if(beans.size()>0){
                 return beans.get(0);
             }

File diff suppressed because it is too large
+ 1218 - 16
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormulaServiceImpl.java


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

@@ -75,22 +75,23 @@ public class SignPfxFilePreServiceImpl implements ISignPfxFilePreService {
     @Override
     public R prePicture(SignPfxFilePreVo vo) throws Exception {
 //        SignPfxFilePre spr = signPfxFilePreMapper.selectByPrimaryKey(vo.getId());
-        InputStream inputStreamByUrl1 = FileUtils.getInputStreamByUrl(vo.getFileStr());
         MultipartFile file1 = vo.getFile();
         //宽度
         Double wide = vo.getWide();
         //高度
         Double high = vo.getHigh();
+
         if(ObjectUtil.isEmpty(wide) && ObjectUtil.isEmpty(high)){
             if(ObjectUtil.isEmpty(file1)){
+                InputStream inputStreamByUrl1 = FileUtils.getInputStreamByUrl(vo.getFileStr());
                 Map imageSize = FileUtils.getImageSize(inputStreamByUrl1);
                 Integer width = (Integer) imageSize.get("width");
                 Integer height = (Integer) imageSize.get("height");
-                wide = width.doubleValue();
-                high = height.doubleValue();
+                wide = PdfAddimgUtil.pxToCm(width);
+                high = PdfAddimgUtil.pxToCm(height);
             }else {
-                wide = FileUtils.getImageWidth(file1).doubleValue();
-                high = FileUtils.getImageHeight(file1).doubleValue();
+                wide = PdfAddimgUtil.pxToCm(FileUtils.getImageWidth(file1));
+                high =PdfAddimgUtil.pxToCm(FileUtils.getImageHeight(file1));
             }
         }
         //图片地址
@@ -172,13 +173,19 @@ public class SignPfxFilePreServiceImpl implements ISignPfxFilePreService {
         FileOutputStream outputStream = new FileOutputStream(excelPath);
         workbook.write(outputStream);
         FileUtils.excelToPdf(excelPath, pdfPath);
+        //把图片存储到本地
+
         if(ObjectUtil.isEmpty(file1)){
-            InputStream inputStreamByUrl2 = FileUtils.getInputStreamByUrl(vo.getFileStr());
-            FileUtils.compressImage(inputStreamByUrl2,compressImgPath, wide,high);
+            InputStream inputStreamByUrl2 = CommonUtil.getOSSInputStream(vo.getFileStr());
+            FileUtils.saveFile(inputStreamByUrl2,compressImgPath);
+            PdfAddimgUtil.PrepdfAddImgInfoNew(pdfPath, String.join(",", sign),textMap,compressImgPath,wide, high);
+           // FileUtils.compressImage(inputStreamByUrl2,compressImgPath, wide,high);
         }else {
-            FileUtils.compressImage(file1.getInputStream(),compressImgPath, wide,high);
+            FileUtils.saveFile(file1.getInputStream(),compressImgPath);
+            PdfAddimgUtil.PrepdfAddImgInfoNew(pdfPath, String.join(",", sign),textMap,compressImgPath,wide, high);
+            //FileUtils.compressImage(file1.getInputStream(),compressImgPath, wide,high);
         }
-        PdfAddimgUtil.PrepdfAddImgInfoNew(pdfPath, String.join(",", sign),textMap,compressImgPath);
+        //PdfAddimgUtil.PrepdfAddImgInfoNew(pdfPath, String.join(",", sign),textMap,compressImgPath,wide.intValue(), high.intValue());
         //压缩后的图片上传oss
         SignPfxFilePreVo signPfxFilePreVo = new SignPfxFilePreVo();
         signPfxFilePreVo.setWide(wide);

+ 14 - 7
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/TrialSummaryClassificationConfigurationServiceImpl.java

@@ -1,5 +1,6 @@
 package org.springblade.manager.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import lombok.AllArgsConstructor;
@@ -26,13 +27,12 @@ import org.springblade.manager.utils.WbsElementUtil;
 import org.springblade.manager.vo.TrialTreeVO;
 import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 import java.util.stream.Collectors;
 
 @Service
@@ -78,7 +78,14 @@ public class TrialSummaryClassificationConfigurationServiceImpl
         if (ObjectUtil.isNotEmpty(dto.getExcelId()) && ObjectUtil.isNotEmpty(dto.getClassId())) {
             /*上传excel清表模板后,需要元素识别并添加到元素库;
             然后调该接口关联清表,重新生成html,重构定位信息*/
-            ExcelTab excelTab = excelTabService.getById(dto.getExcelId());
+            List<String> idsList=new ArrayList<>();
+            if(dto.getExcelId().indexOf(",")>0){
+                String[] ids = dto.getExcelId().split(",");
+                idsList= Arrays.asList(ids);
+            }else {
+                idsList.add(dto.getExcelId());
+            }
+            ExcelTab excelTab = excelTabService.getOne(new LambdaQueryWrapper<>(ExcelTab.class).in(ExcelTab::getId, idsList).eq(ExcelTab::getFileType,3));
             if (ObjectUtil.isEmpty(excelTab)) {
                 throw new ServiceException("未获取到清表信息");
             }
@@ -91,14 +98,14 @@ public class TrialSummaryClassificationConfigurationServiceImpl
             }
 
             //复制模版htmlURL
-            //File file_in = ResourceUtil.getFile("C:\\Users\\泓创开发\\Desktop\\fsdownload\\1717821792510279680.html");
+            //File file_in = ResourceUtil.getFile("C:\\upload\\1866675230773084160.html");
             File file_in = ResourceUtil.getFile(excelTab.getHtmlUrl());
             String fileCode = SnowFlakeUtil.getId() + "";
+            //正式环境
             String file_path = FileUtils.getSysLocalFileUrl();
             String htmlUrl = file_path + "/privateUrl/" + fileCode + ".html";
             File file_out = ResourceUtil.getFile(htmlUrl);
             FileUtil.copy(file_in, file_out);
-
             File file1 = ResourceUtil.getFile(htmlUrl);
             String htmlString = IoUtil.readToString(new FileInputStream(file1));
             Document doc = Jsoup.parse(htmlString);
@@ -172,7 +179,7 @@ public class TrialSummaryClassificationConfigurationServiceImpl
             FileUtil.writeToFile(writeFile, doc.html(), false);
 
             String updateSql = "UPDATE m_trial_summary_classification_configuration SET excel_id = ?,html_url = ? WHERE id = ?";
-            Object[] delParams = {dto.getExcelId(), htmlUrl, dto.getClassId()};
+            Object[] delParams = {excelTab.getId(), htmlUrl, dto.getClassId()};
             jdbcTemplate.update(updateSql, delParams);
             return true;
         }

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

@@ -61,6 +61,9 @@ public class WbsParamServiceImpl extends BaseServiceImpl<WbsParamMapper, WbsPara
                     if (wp == null) {
                         WbsTreePrivate publicWtp = this.getOriginWtp(wtp.getPKeyId());
                         wp = this.getOne(Wrappers.<WbsParam>lambdaQuery().eq(WbsParam::getNodeId, publicWtp.getId()).eq(WbsParam::getK, FILE_TITLE).last(" limit 1 "));
+                        if(wp==null){
+                            wp = this.getOne(Wrappers.<WbsParam>lambdaQuery().eq(WbsParam::getNodeId, publicWtp.getTreePId()).eq(WbsParam::getK, FILE_TITLE).last(" limit 1 "));
+                        }
                     }
                     if (Func.isNotEmpty(wp)) {
                         return CustomFunction.tree(nodes.stream().map(w->StringUtils.isNotEmpty(w.getFullName())?w.getFullName():w.getNodeName()).collect(Collectors.toList()), wp.getV()).toString();
@@ -110,7 +113,7 @@ public class WbsParamServiceImpl extends BaseServiceImpl<WbsParamMapper, WbsPara
                 if(wtc.getIsTypePrivatePid()!=null){
                     return this.wbsTreePrivateMapper.selectOne(Wrappers.<WbsTreePrivate>lambdaQuery().eq(WbsTreePrivate::getPKeyId,wtc.getIsTypePrivatePid()));
                 }else{
-                return this.wbsTreePrivateMapper.selectOne(Wrappers.<WbsTreePrivate>lambdaQuery().eq(WbsTreePrivate::getId,wtc.getOldId()).eq(WbsTreePrivate::getProjectId,wtc.getProjectId()).last(" limit 1 "));
+                    return this.wbsTreePrivateMapper.selectOne(Wrappers.<WbsTreePrivate>lambdaQuery().eq(WbsTreePrivate::getId,wtc.getOldId()).eq(WbsTreePrivate::getProjectId,wtc.getProjectId()).last(" limit 1 "));
                 }
             }else{
                 wtc=tmp;

+ 97 - 4
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeContractServiceImpl.java

@@ -24,6 +24,7 @@ import org.springblade.business.feign.ConstructionLedgerFeignClient;
 import org.springblade.business.feign.InformationQueryClient;
 import org.springblade.business.vo.QueryProcessDataVO;
 import org.springblade.common.constant.CommonConstant;
+import org.springblade.common.utils.Colour;
 import org.springblade.common.utils.CommonUtil;
 import org.springblade.common.utils.FileUtils;
 import org.springblade.common.utils.SnowFlakeUtil;
@@ -35,6 +36,7 @@ import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.node.ForestNodeMerger;
 import org.springblade.core.tool.utils.*;
 import org.springblade.manager.bean.NodeVO;
+import org.springblade.manager.controller.ExcelTabController;
 import org.springblade.manager.dto.*;
 import org.springblade.manager.entity.*;
 import org.springblade.manager.excel.WbsExcelBatchUtil;
@@ -49,6 +51,7 @@ import org.springblade.manager.utils.CompositeKey;
 import org.springblade.manager.vo.*;
 import org.springblade.system.cache.ParamCache;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Lazy;
 import org.springframework.data.redis.core.StringRedisTemplate;
 import org.springframework.jdbc.BadSqlGrammarException;
 import org.springframework.jdbc.core.BeanPropertyRowMapper;
@@ -1232,10 +1235,94 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
             List<WbsTreeContract> tabs = baseMapper.selectList(Wrappers.<WbsTreeContract>lambdaQuery().eq(WbsTreeContract::getParentId, node.getId())
                     .eq(WbsTreeContract::getContractId, node.getContractId()).eq(WbsTreeContract::getType, 2)
                     .eq(WbsTreeContract::getWbsId, node.getWbsId())
+                    .eq(WbsTreeContract::getIsDeleted,0)
                     .apply("(wbs_type is null OR wbs_type = " + node.getWbsType() + ")")
                     .eq(WbsTreeContract::getStatus, 1)
                     .ne(WbsTreeContract::getIsBussShow, 2)); //隐藏的表单不操作
-
+            //临时处理,先复制一张表,将施工有编号问题的表更正。
+            Map<String, List<WbsTreeContract>> collect = tabs.stream().collect(Collectors.groupingBy(WbsTreeContract::getNodeName));
+            for (Map.Entry<String, List<WbsTreeContract>> stringListEntry : collect.entrySet()) {
+                if(stringListEntry.getValue().size()>1){
+                    List<WbsTreeContract> list = stringListEntry.getValue();
+                    for (WbsTreeContract wbsTreeContract : list) {
+                        if(wbsTreeContract.getIsCopeTab()==null||wbsTreeContract.getIsCopeTab()!=2){
+                            WbsTreeContract wbsInfo = this.getBaseMapper().selectOne(Wrappers.<WbsTreeContract>query().lambda()
+                                .eq(WbsTreeContract::getPKeyId, wbsTreeContract.getPKeyId()));
+                            List<WbsTreeContract> wbsTreeContractList = this.getBaseMapper().selectList(Wrappers.<WbsTreeContract>query().lambda()
+                                .likeRight(WbsTreeContract::getNodeName,wbsInfo.getNodeName())
+                                .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();
+                                        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();
+                                        jdbcTemplate.update(update);
+                                    }
+                                }
+                            }
+                            //新增
+                            long tabGroupId = SnowFlakeUtil.getId();
+                            long newPkId = SnowFlakeUtil.getId();
+                            WbsTreeContract wbsTreeContract1 = new WbsTreeContract();
+                            BeanUtil.copy(wbsInfo, wbsTreeContract1);
+                            wbsTreeContract1.setPKeyId(newPkId);
+                            wbsTreeContract1.setCreateTime(new Date());
+                            wbsTreeContract1.setTabGroupId(tabGroupId);
+                            String nodeName;
+                            if(flag){
+                                nodeName=wbsTreeContractList3.get(wbsTreeContractList3.size()-1).getNodeName();
+                            }else {
+                                nodeName=  wbsTreeContractList2.get(0).getNodeName();
+                            }
+                            if (nodeName.indexOf("__") >= 0) {
+                                String[] oldName = nodeName.split("__");
+                                nodeName = oldName[0] + "__" + (Integer.parseInt(oldName[1]) + 1);
+                            } else {
+                                nodeName = nodeName + "__" + 1;
+                            }
+                            wbsTreeContract1.setNodeName(nodeName);
+                            wbsTreeContract1.setIsCopeTab(2);
+                            wbsTreeContract1.setIsTabPdf(1); // pdf 不能预览
+                            wbsTreeContract1.setIsBussShow(1); // 是否隐藏表
+                            wbsTreeContract1.setTabFileType(1);//没有上传附件
+                            wbsTreeContract1.setPdfUrl("");
+                            String tabName = wbsTreeContract.getInitTableName();
+                            // 字段查询 并去掉公式字段
+                            String colkeys = "SELECT GROUP_CONCAT(COLUMN_NAME) as colkeys from information_schema.COLUMNS c where c.table_name='" + tabName + "' and COLUMN_NAME not in('id','p_key_id')";
+                            Map<String, Object> stringObjectMap = jdbcTemplate.queryForMap(colkeys);
+                            colkeys = stringObjectMap.get("colkeys") + "";
+                            // 复制表数据
+                            String querySql = "insert into " + tabName + " (id,p_key_id," + colkeys + ") select '" + newPkId + "','" + newPkId + "'," + colkeys + " from " + tabName + " where p_key_id=" + wbsTreeContract1.getPKeyId();
+                            jdbcTemplate.execute(querySql);
+                            this.save(wbsTreeContract1);
+                            String delsql="delete from m_wbs_tree_contract where p_key_id="+wbsTreeContract1.getPKeyId();
+                            jdbcTemplate.execute(delsql);
+                            for (WbsTreeContract wbsTreeCont : wbsTreeContractList2) {
+                                UpdateWrapper<WbsTreeContract> updateWrapper = new UpdateWrapper<>();
+                                updateWrapper.in("p_key_id", wbsTreeCont.getPKeyId() + "");
+                                updateWrapper.set("tab_group_id", tabGroupId);
+                                this.update(updateWrapper);
+                            }
+                        }
+                    }
+                }
+            }
+            tabs = baseMapper.selectList(Wrappers.<WbsTreeContract>lambdaQuery().eq(WbsTreeContract::getParentId, node.getId())
+                .eq(WbsTreeContract::getContractId, node.getContractId()).eq(WbsTreeContract::getType, 2)
+                .eq(WbsTreeContract::getWbsId, node.getWbsId())
+                .eq(WbsTreeContract::getIsDeleted,0)
+                .apply("(wbs_type is null OR wbs_type = " + node.getWbsType() + ")")
+                .eq(WbsTreeContract::getStatus, 1)
+                .ne(WbsTreeContract::getIsBussShow, 2)); //隐藏的表单不操作
             Map<Long, WbsTreeContract> tabMaps = tabs.stream().collect(Collectors.toMap(WbsTreeContract::getPKeyId, Function.identity()));
 
             //初始化表
@@ -2601,11 +2688,18 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
         System.out.println("66666666666");
     }
     public void diGuiWbs(int i) {
+        List<Long>contractIds=new ArrayList<>();
+        contractIds.add(1750755552044064769L);
+        contractIds.add(1750756463776702465L);
+        contractIds.add(1750756833940807682L);
+        contractIds.add(1750757133997121538L);
+        contractIds.add(1750757280558686209L);
+        contractIds.add(1750757576810766337L);
         QueryWrapper<WbsTreeContract> wbsTreeContractQueryWrapper = new QueryWrapper<>();
         wbsTreeContractQueryWrapper.select("p_key_id","id","p_id","wbs_id","contract_id","parent_id","ancestors");
         wbsTreeContractQueryWrapper.eq("parent_id",0);
         wbsTreeContractQueryWrapper.eq("is_deleted",0);
-        wbsTreeContractQueryWrapper.isNotNull("contract_id");
+        wbsTreeContractQueryWrapper.in("contract_id",contractIds);
         wbsTreeContractQueryWrapper.isNotNull("wbs_id");
         List<WbsTreeContract> list = this.list(wbsTreeContractQueryWrapper);
         if(!list.isEmpty()){
@@ -2619,7 +2713,6 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
 
             //递归设置pid和ancestors
             setPidAndAncestors(map,wbsTreeContract,updateList);
-            System.out.println("第"+i+"次递归:"+updateList.size());
             for (WbsTreeContract contract : updateList) {
                 UpdateWrapper wrapper=new UpdateWrapper();
                 wrapper.set("p_id",contract.getPId());
@@ -2628,7 +2721,7 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
                 this.update(wrapper);
             }
         }
-        System.out.println("第"+i+"次递归完成");
+        System.out.println(Colour.RED.getCode()+"第"+i+"次递归完成============================================================================================="+Colour.RESET.getCode());
 
 
     }

+ 68 - 6
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreePrivateServiceImpl.java

@@ -6,6 +6,7 @@ import cn.hutool.log.StaticLog;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.baomidou.mybatisplus.core.toolkit.StringUtils;
@@ -18,6 +19,7 @@ import org.jsoup.nodes.Element;
 import org.jsoup.select.Elements;
 import org.springblade.business.feign.InformationQueryClient;
 import org.springblade.common.constant.CommonConstant;
+import org.springblade.common.utils.Colour;
 import org.springblade.common.utils.CommonUtil;
 import org.springblade.common.utils.SnowFlakeUtil;
 import org.springblade.core.log.exception.ServiceException;
@@ -37,6 +39,7 @@ import org.springblade.manager.service.IElementFormulaMappingService;
 import org.springblade.manager.service.IFormulaService;
 import org.springblade.manager.service.ITableInfoService;
 import org.springblade.manager.service.IWbsTreePrivateService;
+import org.springblade.manager.utils.CompositeKey1;
 import org.springblade.manager.utils.FileUtils;
 import org.springblade.manager.vo.*;
 import org.springblade.system.cache.ParamCache;
@@ -138,7 +141,6 @@ public class WbsTreePrivateServiceImpl extends BaseServiceImpl<WbsTreePrivateMap
                 }
                 wbsTreePrivate.setIsClassifition(1);
             }
-            int row = baseMapper.updateByPKeyId(pKeyId, wbsTreePrivate);
             /** 同步当前节点下所有节点的新增是否隐藏*/
             //如果父节点为隐藏,则子节点不能修改为显示
             if (wbsTreePrivate.getIsAddConceal() == 0){
@@ -149,9 +151,9 @@ public class WbsTreePrivateServiceImpl extends BaseServiceImpl<WbsTreePrivateMap
                     throw new ServiceException("修改失败:父节点为新增隐藏,子节点不能改为显示");
                 }
             }
-            //批量修改状态-因为结构问题,可能会有漏网之鱼
-            baseMapper.batchUpdateIsAddConceal(wbsTreePrivate);
-
+            int row = baseMapper.updateByPKeyId(pKeyId, wbsTreePrivate);
+            Long pId = baseMapper.getByPKeyId(wbsTreePrivate.getPKeyId()).getPId();
+            baseMapper.batchUpdateIsAddConceal(wbsTreePrivate,pId);
             if (row > 0) {
                 WbsTreePrivate wbsTreePrivate1 = baseMapper.getByPKeyId(pKeyId);
                 wbsTreePrivate1.setFullName(wbsTreePrivate1.getNodeName());
@@ -159,7 +161,6 @@ public class WbsTreePrivateServiceImpl extends BaseServiceImpl<WbsTreePrivateMap
                 wbsTreeContractMapper.updateByCondition1(wbsTreePrivate1);
                 return true;
             }
-
             //新增
         } else {
             wbsTreePrivate.setIsDeleted(0);
@@ -2668,7 +2669,10 @@ public class WbsTreePrivateServiceImpl extends BaseServiceImpl<WbsTreePrivateMap
         if (wbsTreePrivate == null) {
             return Collections.emptyList();
         }
-
+        //试验一键重签专用  会传这个四个参数 只是为了重签查询数据  直接查了返回就行 不用校验角色
+        if(tableType.equals("1,9,2,10")){
+            return baseMapper.selectWbsTreeTrialTabList(tableType, wbsTreePrivate.getProjectId(), wbsTreePrivate.getWbsId(), wbsTreePrivate.getId(), contractId);
+        }
         //当前项目合同段只会存在一个角色roleId
         SaveUserInfoByProject userInfo = wbsTreeContractMapper.selectRoleInfo(AuthUtil.getUserId(), contractId, projectId);
         if (userInfo == null) {
@@ -2974,4 +2978,62 @@ public class WbsTreePrivateServiceImpl extends BaseServiceImpl<WbsTreePrivateMap
         return baseMapper.getContractAllLog(contractId);
     }
 
+    public void diGuiWbs(int i) {
+        QueryWrapper<WbsTreePrivate> wbsTreePrivateQueryWrapper = new QueryWrapper<>();
+        wbsTreePrivateQueryWrapper.select("p_key_id","id","p_id","wbs_id","project_id","parent_id","ancestors");
+        wbsTreePrivateQueryWrapper.eq("parent_id",0);
+        wbsTreePrivateQueryWrapper.eq("is_deleted",0);
+        wbsTreePrivateQueryWrapper.isNotNull("project_id");
+        wbsTreePrivateQueryWrapper.isNotNull("wbs_id");
+        List<WbsTreePrivate> list = this.list(wbsTreePrivateQueryWrapper);
+        if(!list.isEmpty()){
+            WbsTreePrivate wbsTreePrivate = list.get(i);
+            //通过parentID,projectID,wbsId分组,映射map
+            Map<CompositeKey1, List<WbsTreePrivate>> map = findAllContract(wbsTreePrivate).stream()
+                .collect(Collectors.groupingBy(
+                    item -> new CompositeKey1(item.getParentId(),item.getProjectId(),item.getWbsId())
+                ));
+            List<WbsTreePrivate>updateList=new ArrayList<>();
+
+            //递归设置pid和ancestors
+            setPidAndAncestors(map,wbsTreePrivate,updateList);
+            for (WbsTreePrivate wbsTreePrivate1 : updateList) {
+               UpdateWrapper<WbsTreePrivate>wrapper=new UpdateWrapper<>();
+                wrapper.set("p_id",wbsTreePrivate1.getPId());
+                wrapper.set("ancestors",wbsTreePrivate1.getAncestors());
+                wrapper.eq("p_key_id",wbsTreePrivate1.getPKeyId());
+                this.update(wrapper);
+            }
+        }
+        System.out.println(Colour.RED.getCode()+"第"+i+"次递归完成======================================================================================="+Colour.RESET.getCode());
+
+
+    }
+    public  List<WbsTreePrivate> findAllContract(WbsTreePrivate wbsTreePrivate){
+        QueryWrapper<WbsTreePrivate> wbsTreeContractQueryWrapper = new QueryWrapper<>();
+        wbsTreeContractQueryWrapper.select("p_key_id","id","p_id","wbs_id","project_id","parent_id","ancestors");
+        wbsTreeContractQueryWrapper.eq("project_id",wbsTreePrivate.getProjectId());
+        wbsTreeContractQueryWrapper.eq("wbs_id",wbsTreePrivate.getWbsId());
+        return this.list(wbsTreeContractQueryWrapper);
+    }
+    public  void setPidAndAncestors(Map<CompositeKey1, List<WbsTreePrivate>> map,WbsTreePrivate wbsTreePrivate,List<WbsTreePrivate>updateList){
+        CompositeKey1 key = new CompositeKey1(wbsTreePrivate.getId(),wbsTreePrivate.getProjectId(),wbsTreePrivate.getWbsId());
+        //拿到当前节点的子节点
+        List<WbsTreePrivate> childrens = map.get(key);
+        if(ObjectUtil.isNotEmpty(childrens)){
+            for (WbsTreePrivate children : childrens) {
+                if(children.getParentId().equals(wbsTreePrivate.getId())){
+                    //设置祖级节点和pid
+                    String ancestors=wbsTreePrivate.getAncestors()+",";
+                    ancestors=ancestors+wbsTreePrivate.getPKeyId();
+                    children.setAncestors(ancestors);
+                    children.setPId(wbsTreePrivate.getPKeyId());
+                    updateList.add(children);
+                    //递归调用自己继续将一个合同段的子节点设置完
+                    setPidAndAncestors(map,children,updateList);
+                }
+            }
+        }
+    }
+
 }

+ 107 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/utils/AmountToChineseConverter.java

@@ -0,0 +1,107 @@
+package org.springblade.manager.utils;
+
+import java.text.NumberFormat;
+
+public class AmountToChineseConverter {
+
+    public static String upperCase2(double money){
+        String[] upNum = {"零","壹","贰","叁","肆","伍","陆","柒","捌","玖"};
+        String[] danwei = {"元","拾","佰","仟","万","拾","佰","仟","亿","拾","佰","仟"};
+        //取消科学记数法
+        NumberFormat numFormat = NumberFormat.getInstance();
+        numFormat.setMaximumFractionDigits(2);//设置小数位个数
+        numFormat.setGroupingUsed(false);//取消科学技术发
+        String formatNum = numFormat.format(money);
+        String strmoney = formatNum + "";//浮点型转为字符型
+        String lastUpNum = "null"; //用于存放上个参数的值
+        String result = "";//返回的结果
+        String[] split = strmoney.split("\\.");
+        String strMoney = split[0];
+        String point = "";
+        //小数部分取值处理。
+        if(split.length>1){
+            point = split[1];
+            if(point.length()==1){
+                point = point.concat("0");
+            }
+        }else {
+            point = "0";
+        }
+        //大于12位就直接返回。
+        int moneyLen = strMoney.length();
+        if(money==0){
+            return "零元整";
+        }
+        if(moneyLen>12){
+            return "金额:"+money+"元,超出大写转换范围。最大金额:999999999999.99元";
+        }
+        //整数(integer)部分处理。
+        if(!"0".equals(strMoney)){
+            for (int i = 0; i < moneyLen; i++) {
+                String strNum = strMoney.charAt(i)+"";
+                int singleNum = Integer.parseInt(strNum);
+                String upSingleNum = upNum[singleNum];
+                //上一为不等于0的情况
+                if(!"零".equals(lastUpNum)){
+                    if(!"零".equals(upSingleNum)){
+                        result = result.concat(upSingleNum).concat(danwei[moneyLen-i-1]);
+                    }else
+                        //为零但是在万、亿位上要加单位 (moneyLen-i)==9 指的是单位:亿。  (moneyLen-i)==5指的是单位:万
+                        if( (moneyLen-i)==5 || (moneyLen-i)==9 ){
+                            lastUpNum="";
+                        }else {
+                            result=result.concat(upSingleNum);
+                        }
+                }
+                //上一位为0的情况
+                if("零".equals(lastUpNum) && !"零".equals(upSingleNum)){
+                    result = result.concat(upSingleNum).concat(danwei[moneyLen-i-1]);
+                }
+                //捕捉上一位数(lastUpNum)为零的情况做优化。
+                if((moneyLen-i)==5 || (moneyLen-i)==9 ){
+                    //排除加单位时前面为"零"的情况。如:两百零万
+                    if("零".equals(lastUpNum)||"null".equals(lastUpNum)){
+                        result = result.substring(0,result.length()-1);
+                    }
+                    if(!result.endsWith("亿")){
+                        result = result.concat(danwei[moneyLen-i-1]);
+                    }
+                    lastUpNum="";
+                }else {
+                    //把当前大写数字复制给 lastUpNum 用于下次判断
+                    lastUpNum = upSingleNum;
+                }
+            }
+            //对几万元整和几亿元整(result:五万零或者五亿零零)做优化。
+            result=result.replaceAll("零零","零");
+            if(result.endsWith("零")){
+                String substring = result.substring(0,result.length() - 1);
+                result = substring;
+            }
+            result = result.concat("元");
+            result = result.replaceAll("元元","元");
+            result = result.replaceAll("万万","万");
+
+        }
+
+        //小数(point)部分处理
+        if("0".equals(point)){
+            result =  result+"整";
+        }else {
+            //去 整
+//            if(result.endsWith("整")){
+//                result = result.substring(0,result.length()-1);
+//            }
+            if((point.charAt(0)+"").equals("0")){
+                result = result.concat(upNum[Integer.parseInt(point.charAt(1)+"")]+"分");
+            }else if((point.charAt(1)+"").equals("0")){
+                result = result.concat(upNum[Integer.parseInt(point.charAt(0)+"")]+"角");
+            }else {
+                result = result.concat(upNum[Integer.parseInt(point.charAt(0)+"")]+"角").concat(upNum[Integer.parseInt(point.charAt(1)+"")]+"分");
+            }
+        }
+        return result;
+    }
+
+
+}

+ 16 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/utils/CompositeKey1.java

@@ -0,0 +1,16 @@
+package org.springblade.manager.utils;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+@Data
+@EqualsAndHashCode
+@AllArgsConstructor
+@NoArgsConstructor
+public class CompositeKey1 {
+    private Long id;
+    private String projectId;
+    private String wbsId;
+}

+ 0 - 213
blade-service/blade-manager/src/main/java/org/springblade/manager/utils/CreateDashedLine.java

@@ -1,213 +0,0 @@
-package org.springblade.manager.utils;
-
-import com.spire.ms.System.Collections.ArrayList;
-import com.sun.xml.bind.v2.util.FlattenIterator;
-import org.apache.pdfbox.pdmodel.PDDocument;
-import org.apache.pdfbox.pdmodel.PDPage;
-import org.apache.pdfbox.pdmodel.common.PDRectangle;
-import org.apache.pdfbox.pdmodel.graphics.state.PDExtendedGraphicsState;
-import org.apache.pdfbox.pdmodel.PDPageContentStream;
-import org.apache.pdfbox.pdmodel.graphics.PDLineDashPattern;
-import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotation;
-import org.apache.pdfbox.pdmodel.interactive.measurement.PDViewportDictionary;
-import org.apache.pdfbox.text.PDFTextStripper;
-import org.apache.pdfbox.text.PDFTextStripperByArea;
-import org.apache.pdfbox.text.TextPosition;
-import org.springblade.common.utils.CommonUtil;
-import org.springblade.common.utils.FileUtils;
-import org.springblade.core.tool.utils.Func;
-import org.springblade.core.tool.utils.ResourceUtil;
-import org.springblade.manager.vo.PDFIndexInfo;
-
-import java.awt.geom.Point2D;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.*;
-
-public class CreateDashedLine {
-
-    public static void mai1n(String[] args) throws Exception {
-        // 获取值的坐标
-      //  List<String> s_data39 = new java.util.ArrayList<>();
-
-        List<String> s_data34 = new java.util.ArrayList<>();
-        s_data34.add("2.8");
-        s_data34.add("7.66");
-/*        s_data34.add("14.03");
-        s_data34.add("14.56");
-        s_data34.add("16.28");
-        s_data34.add("");
-        s_data34.add("16.42");
-        s_data34.add("16.57");
-        s_data34.add("16.73");
-        s_data34.add("16.9");
-        s_data34.add("17.07");
-        s_data34.add("17.26");*/
-
-        String pdfUrl = "/Users/hongchuangyanfa/Desktop/excel/1750071431349174274.pdf";
-
-      //  getPDFInfo(pdfUrl,s_data39,"1");
-        getPDFInfo(pdfUrl,s_data34,"2");
-
-        System.out.println("");
-    }
-
-
-    public static void getPDFInfo(String pdfUrl,List<String> s_data,String type) throws Exception {
-        PDDocument document = PDDocument.load(new File(pdfUrl));
-        //获取文件流
-        InputStream inputStream = new FileInputStream(new File(pdfUrl));
-        //转换
-        byte[] bytes = CommonUtil.InputStreamToBytes(inputStream);
-        List<PDFIndexInfo> keywordPostions = PdfAddimgUtil.findKeywordPostions(bytes, "累计%");
-
-        // 获取  实际完成=累计% 的坐标
-        PDFIndexInfo pdfIndexInfo = keywordPostions.get(0);
-        float s_with = pdfIndexInfo.getDataInfo()[1];
-        float s_heiht = pdfIndexInfo.getDataInfo()[2];
-
-        // 获取  计划完成 = 累计% 的坐标
-        PDFIndexInfo jPdf = keywordPostions.get(1);
-        float j_with = jPdf.getDataInfo()[1];
-        float j_heiht = jPdf.getDataInfo()[2];
-
-        System.out.println(s_with+"__"+s_heiht);
-        System.out.println(j_with+"__"+j_heiht);
-
-        List<PDFIndexInfo> allwordPostions = PdfAddimgUtil.findAllwordPostions(bytes);
-        PDFIndexInfo pdfIndex = allwordPostions.get(0);
-        List<float[]> listData = pdfIndex.getListData();
-        String context = pdfIndex.getPkeyid();
-
-        // 获取月份的y轴
-        int moth_y = context.indexOf("1234567891011121");
-        float[] moth = listData.get(moth_y);
-        System.out.println(moth[2]);
-        List<PDFIndexInfo> bf_list = PdfAddimgUtil.findKeywordPostions(bytes, "%");
-         float bf_x = 0f;
-         float bf_y = 0f;
-        for(PDFIndexInfo bf:bf_list){
-           if(bf.getDataInfo()[2]==moth[2]){
-               bf_x =   bf.getDataInfo()[1];
-               bf_y =   bf.getDataInfo()[2];
-               break;
-           }
-        }
-        System.out.println("百分"+bf_x);
-        System.out.println("百分"+bf_y);
-
-        Map<String , float[]> data = new HashMap<>();
-        for(int i=20 ; i>=0 ; i--){
-            //测试数据
-            String key = i * 5 +"";
-            List<String> strList = Func.toStrList(key);
-            for (String text : strList) {
-                for (int pos = 0; pos < context.length(); ) {
-                    int positionIndex = context.indexOf(text, pos);
-                    if (positionIndex == -1) {
-                        break;
-                    }
-                    float[] postions = listData.get(positionIndex);
-                    if((postions[1]==bf_x || Math.abs(postions[1]-bf_x)<=0.002) && postions[2]>bf_y){
-                        data.put(key,postions);
-                        bf_y =postions[2];
-                        break;
-                    }
-                    pos = positionIndex + 1;
-                }
-            }
-        }
-
-
-
-        Map<String , float[]> s_data_xy = new HashMap<>();
-
-        for(String sval:s_data){
-            //测试数据
-            List<String> strList = Func.toStrList(sval);
-            for (String text : strList) {
-                for (int pos = 0; pos < context.length(); ) {
-                    int positionIndex = context.indexOf(text, pos);
-                    if (positionIndex == -1) {
-                        break;
-                    }
-                    float[] postions = listData.get(positionIndex);
-                    if("1".equals(type)){
-                        if((postions[2]==s_heiht || Math.abs(postions[2]-s_heiht)<=0.002 ) && postions[1]>s_with){
-                            s_data_xy.put(sval,postions);
-                            s_with = postions[1];
-                            break;
-                        }
-                    }
-                    if("2".equals(type)){
-                        if((postions[2]==j_heiht || Math.abs(postions[2]-j_heiht)<=0.002 ) && postions[1]>s_with){
-                            s_data_xy.put(sval,postions);
-                            s_with = postions[1];
-                            break;
-                        }
-                    }
-                    pos = positionIndex + 1;
-                }
-            }
-        }
-
-        float pageHeight = document.getPage(0).getMediaBox().getHeight();
-        float pageWidth = document.getPage(0).getMediaBox().getWidth();
-        float oney = (data.get("0")[2] -data.get("5")[2])/5 * pageHeight;
-        //实线坐标
-        List<Float> points = new ArrayList();
-        for(String sval:s_data){
-            float[] floats = s_data_xy.get(sval);
-            if(floats!=null){
-                points.add( pageWidth * (floats[1])+2);
-                Double floor = Math.floor(Func.toDouble(sval) / 5)*5;
-
-                float add = (float) ((Func.toDouble(sval)-floor ) * oney);
-
-                String da2 = floor.intValue()+"";
-                float[] floats1 = data.get(da2);
-                points.add( pageHeight- pageHeight * (floats1[2]) + add );
-            }
-        }
-        PDFFill(points,pdfUrl,type);
-    }
-
-    public static void PDFFill(List<Float> points,String fileUrl,String type) throws Exception {
-        // 创建一个PDF文档
-        PDDocument document = PDDocument.load(new File(fileUrl));
-
-        // 创建一个页面
-        PDPage page = document.getPage(0);
-        // 纸张大小
-
-        try (PDPageContentStream contentStream = new PDPageContentStream(document, page,PDPageContentStream.AppendMode.APPEND, true, true)) {
-            // 设置线宽和颜色
-            PDExtendedGraphicsState extendedGraphicsState = new PDExtendedGraphicsState();
-            extendedGraphicsState.setLineWidth(1f);
-            contentStream.setGraphicsStateParameters(extendedGraphicsState);
-            float[] a={4,2};
-            contentStream.setLineDashPattern(a, 2);
-
-            // 定义点集合,表示折线上的点
-            List<Point2D.Float> points1 = new java.util.ArrayList<>();
-            for (int i = 0; i < points.size(); i += 2) {
-                points1.add(new Point2D.Float(points.get(i), points.get(i + 1)));
-            }
-
-            // 绘制折线
-            Point2D.Float current = null;
-            for (Point2D.Float point : points1) {
-                if (current != null) {
-                    contentStream.drawLine(current.x, current.y, point.x, point.y);
-                }
-                current = point;
-            }
-        }
-
-        document.save("/Users/hongchuangyanfa/Desktop/excel/test_info.pdf");
-        document.close();
-        System.out.println("完成");
-    }
-}

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