Răsfoiți Sursa

Merge branch 'master' of http://47.110.251.215:3000/java_org/bladex

“zhifk” 2 ani în urmă
părinte
comite
c6ea236416
69 a modificat fișierele cu 2436 adăugiri și 1549 ștergeri
  1. 5 0
      blade-common/src/main/java/org/springblade/common/constant/ArchiveConstant.java
  2. 1 0
      blade-ops/blade-flow/blade-flow.iml
  3. 0 7
      blade-ops/blade-xxljob-admin/src/main/resources/mybatis-mapper/XxlJobInfoMapper.xml
  4. 3 4
      blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/entity/ArchivesAuto.java
  5. 24 0
      blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/feign/ArchiveAutoClient.java
  6. 4 1
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/InformationQuery.java
  7. 1 1
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/TrialSelfInspectionRecord.java
  8. 7 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/NeiYeLedgerVO.java
  9. 2 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/QueryProcessDataVO.java
  10. 3 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/TrialSelfInspectionRecordVO.java
  11. 79 23
      blade-service-api/blade-manager-api/blade-manager-api.iml
  12. 1 1
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/FormulaOptionVo.java
  13. 3 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/ArchiveTreeContract.java
  14. 6 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/WbsTreeContract.java
  15. 3 3
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/feign/ExcelTabClient.java
  16. 1 5
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/feign/WbsTreePrivateClient.java
  17. 14 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/ArchiveTreeContractVO2.java
  18. 35 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/TrialRecordZJTreeVO.java
  19. 28 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/WbsTreeContractVO6.java
  20. 42 4
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/WbsTreePrivateVO4.java
  21. 29 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/WbsTreeVO2.java
  22. 26 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/feign/ArchiveAutoClientImpl.java
  23. 1 2
      blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/ArchivesAutoMapper.xml
  24. 19 2
      blade-service/blade-business/src/main/java/org/springblade/business/controller/InformationWriteQueryController.java
  25. 17 6
      blade-service/blade-business/src/main/java/org/springblade/business/controller/NeiYeController.java
  26. 544 535
      blade-service/blade-business/src/main/java/org/springblade/business/controller/TaskController.java
  27. 97 27
      blade-service/blade-business/src/main/java/org/springblade/business/controller/TrialDetectionController.java
  28. 7 2
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/InformationQueryMapper.xml
  29. 8 3
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/TrialSelfInspectionRecordMapper.java
  30. 1 1
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/TrialSelfInspectionRecordMapper.xml
  31. 5 7
      blade-service/blade-business/src/main/java/org/springblade/business/service/ITrialSelfInspectionRecordService.java
  32. 61 18
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TaskServiceImpl.java
  33. 3 1
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TrialDeviceUseServiceImpl.java
  34. 381 387
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TrialSelfInspectionRecordServiceImpl.java
  35. 95 88
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/service/impl/EVisaServiceImpl.java
  36. 1 0
      blade-service/blade-manager/blade-manager.iml
  37. 11 0
      blade-service/blade-manager/pom.xml
  38. 1 1
      blade-service/blade-manager/src/main/java/com/jfireel/expression/util/ValueUtil.java
  39. 5 0
      blade-service/blade-manager/src/main/java/com/mixsmart/utils/CustomFunction.java
  40. 56 0
      blade-service/blade-manager/src/main/java/com/mixsmart/utils/FormulaUtils.java
  41. 97 27
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ExcelTabController.java
  42. 3 3
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/FormulaController.java
  43. 7 7
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/TextdictInfoController.java
  44. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/WbsFormElementController.java
  45. 7 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/WbsTreeContractController.java
  46. 12 12
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/WbsTreePrivateController.java
  47. 35 51
      blade-service/blade-manager/src/main/java/org/springblade/manager/feign/ExcelTabClientImpl.java
  48. 10 25
      blade-service/blade-manager/src/main/java/org/springblade/manager/feign/WbsTreePrivateClientImpl.java
  49. 7 5
      blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/FormulaTurnPoint.java
  50. 1 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/ArchiveTreeContractMapper.xml
  51. 15 39
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/ContractInfoMapper.java
  52. 19 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/ContractInfoMapper.xml
  53. 2 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/ExcelTabMapper.xml
  54. 1 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsTreeContractMapper.xml
  55. 3 5
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsTreePrivateMapper.java
  56. 31 2
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsTreePrivateMapper.xml
  57. 4 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/IContractInfoService.java
  58. 6 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/IExcelTabService.java
  59. 1 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/IWbsTreeContractService.java
  60. 6 2
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/IWbsTreePrivateService.java
  61. 136 14
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ArTreeContractInitServiceImpl.java
  62. 4 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ArchiveTreeContractServiceImpl.java
  63. 5 7
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ArchiveTreeServiceImpl.java
  64. 63 18
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ContractInfoServiceImpl.java
  65. 200 103
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ExcelTabServiceImpl.java
  66. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormulaOptionServiceImpl.java
  67. 59 89
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormulaServiceImpl.java
  68. 68 5
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreePrivateServiceImpl.java
  69. 2 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeServiceImpl.java

+ 5 - 0
blade-common/src/main/java/org/springblade/common/constant/ArchiveConstant.java

@@ -0,0 +1,5 @@
+package org.springblade.common.constant;
+
+public interface ArchiveConstant {
+    String APPLICATION_WEATHER_NAME = "blade-archive";
+}

+ 1 - 0
blade-ops/blade-flow/blade-flow.iml

@@ -300,6 +300,7 @@
     <orderEntry type="library" scope="PROVIDED" name="Maven: org.springblade:blade-core-auto:2.9.1.RELEASE" level="project" />
     <orderEntry type="module" module-name="blade-user-api" />
     <orderEntry type="module" module-name="blade-manager-api" />
+    <orderEntry type="module" module-name="blade-business-api" />
     <orderEntry type="module" module-name="blade-flow-api" />
     <orderEntry type="library" name="Maven: org.springblade:blade-starter-flowable:2.9.1.RELEASE" level="project" />
     <orderEntry type="library" name="Maven: org.flowable:flowable-spring-boot-starter:6.4.2" level="project" />

+ 0 - 7
blade-ops/blade-xxljob-admin/src/main/resources/mybatis-mapper/XxlJobInfoMapper.xml

@@ -5,31 +5,24 @@
 
 	<resultMap id="XxlJobInfo" type="com.xxl.job.admin.core.model.XxlJobInfo" >
 		<result column="id" property="id" />
-
 		<result column="job_group" property="jobGroup" />
 	    <result column="job_cron" property="jobCron" />
 	    <result column="job_desc" property="jobDesc" />
-
 	    <result column="add_time" property="addTime" />
 	    <result column="update_time" property="updateTime" />
-
 	    <result column="author" property="author" />
 	    <result column="alarm_email" property="alarmEmail" />
-
 		<result column="executor_route_strategy" property="executorRouteStrategy" />
 		<result column="executor_handler" property="executorHandler" />
 	    <result column="executor_param" property="executorParam" />
 		<result column="executor_block_strategy" property="executorBlockStrategy" />
 		<result column="executor_timeout" property="executorTimeout" />
 		<result column="executor_fail_retry_count" property="executorFailRetryCount" />
-
 	    <result column="glue_type" property="glueType" />
 	    <result column="glue_source" property="glueSource" />
 	    <result column="glue_remark" property="glueRemark" />
 		<result column="glue_updatetime" property="glueUpdatetime" />
-
 		<result column="child_jobid" property="childJobId" />
-
 		<result column="trigger_status" property="triggerStatus" />
 		<result column="trigger_last_time" property="triggerLastTime" />
 		<result column="trigger_next_time" property="triggerNextTime" />

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

@@ -132,16 +132,15 @@ public class ArchivesAuto extends BaseEntity {
 	/**
 	* 案卷内文件数量
 	*/
-		private Integer fileN;
+	private Integer fileN;
 	private Integer pageN;
 	/**
 	* 统一里程信息
 	*/
-		private String mileage;
+	private String mileage;
 	private Integer fileType;
 	private Integer size;
-	private String procsort;
-	private String nodeSort;
+	private String treeSort;
 	private Integer isOpen;
 	private Integer ischeck;
 

+ 24 - 0
blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/feign/ArchiveAutoClient.java

@@ -0,0 +1,24 @@
+package org.springblade.archive.feign;
+
+import org.springblade.archive.entity.ArchivesAuto;
+import org.springblade.archive.vo.ArchivesAutoVO;
+import org.springblade.common.constant.ArchiveConstant;
+import org.springblade.common.constant.EVisaConstant;
+import org.springblade.core.tool.api.R;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+
+import java.util.List;
+
+@FeignClient(value = ArchiveConstant.APPLICATION_WEATHER_NAME)
+public interface ArchiveAutoClient {
+    String API_PREFIX = "/api/ArchiveAuto";
+    /**
+     * 项目分配用户批量保存-项目合同分配人员
+     */
+    @PostMapping(API_PREFIX + "/saveListByNodes")
+    @Transactional(rollbackFor = Exception.class)
+    R saveArchiveAutoByNodes(@RequestBody List<ArchivesAuto> list);
+}

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

@@ -116,9 +116,12 @@ public class InformationQuery extends BaseEntity {
     @ApiModelProperty("排序")
     private Integer sort;
 
-    @ApiModelProperty("pdf路径,引用试验记录后合并的pdf")
+    @ApiModelProperty("关联试验文件后合并的pdf路径")
     private String pdfTrialUrl;
 
+    @ApiModelProperty("关联工程部位信息后合并的pdf路径")
+    private String pdfTrialUrlPosition;
+
     @ApiModelProperty("首件关联工序资料ids")
     private String sjRecordIds;
 

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

@@ -37,7 +37,7 @@ public class TrialSelfInspectionRecord extends BaseEntity {
     @ApiModelProperty(value = "检测类别")
     private Integer detectionCategory;
 
-    @ApiModelProperty(value = "是否上传合格证 '0'=是 ‘1’=否")
+    @ApiModelProperty(value = "是否上传合格证 '1'=是 '0'=否")
     private Integer isUploadCertificate;
 
     @ApiModelProperty(value = "合同段id")

+ 7 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/NeiYeLedgerVO.java

@@ -80,6 +80,12 @@ public class NeiYeLedgerVO {
     @ApiModelProperty(value = "是否关联试验 true为已关联")
     private Boolean isExperiment;
 
+    /**
+     *  资料主键
+     */
+    @ApiModelProperty(value = "information-query主键")
+    private String id;
+
     public NeiYeLedgerVO(String... values){
         this.unitProject = values[0];
         this.partProject = values[1];
@@ -93,6 +99,7 @@ public class NeiYeLedgerVO {
         this.isEvaluate = Boolean.parseBoolean(values[9]);
         this.isExperiment = Boolean.parseBoolean(values[10]);
         this.reportNumber = values[11];
+        this.id = values[12];
     }
 
     public NeiYeLedgerVO(){}

+ 2 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/QueryProcessDataVO.java

@@ -31,4 +31,6 @@ public class QueryProcessDataVO {
 
     private String reportNumber;
 
+    private String isExperiment;
+
 }

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

@@ -26,4 +26,7 @@ public class TrialSelfInspectionRecordVO extends TrialSelfInspectionRecord {
     @ApiModelProperty("样品信息ids")
     private String sampleIds;
 
+    @ApiModelProperty("原材料检测报告ids(试验记录id)")
+    private String rawMaterialIds;
+
 }

+ 79 - 23
blade-service-api/blade-manager-api/blade-manager-api.iml

@@ -20,6 +20,83 @@
     <orderEntry type="inheritedJdk" />
     <orderEntry type="sourceFolder" forTests="false" />
     <orderEntry type="library" name="Maven: com.alibaba:fastjson:1.2.80" level="project" />
+    <orderEntry type="module" module-name="blade-business-api" />
+    <orderEntry type="module" module-name="blade-common" />
+    <orderEntry type="library" name="Maven: org.springblade:blade-core-launch:2.9.1.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-web:2.3.12.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-json:2.3.12.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.11.4" level="project" />
+    <orderEntry type="library" name="Maven: com.fasterxml.jackson.module:jackson-module-parameter-names:2.11.4" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-webmvc:5.2.15.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-undertow:2.3.12.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: io.undertow:undertow-core:2.1.7.Final" level="project" />
+    <orderEntry type="library" name="Maven: org.jboss.logging:jboss-logging:3.4.2.Final" level="project" />
+    <orderEntry type="library" name="Maven: org.jboss.xnio:xnio-api:3.8.0.Final" level="project" />
+    <orderEntry type="library" name="Maven: org.wildfly.common:wildfly-common:1.5.2.Final" level="project" />
+    <orderEntry type="library" name="Maven: org.wildfly.client:wildfly-client-config:1.0.1.Final" level="project" />
+    <orderEntry type="library" scope="RUNTIME" name="Maven: org.jboss.xnio:xnio-nio:3.8.0.Final" level="project" />
+    <orderEntry type="library" name="Maven: org.jboss.threads:jboss-threads:3.1.0.Final" level="project" />
+    <orderEntry type="library" name="Maven: io.undertow:undertow-servlet:2.1.7.Final" level="project" />
+    <orderEntry type="library" name="Maven: org.jboss.spec.javax.annotation:jboss-annotations-api_1.3_spec:2.0.1.Final" level="project" />
+    <orderEntry type="library" name="Maven: io.undertow:undertow-websockets-jsr:2.1.7.Final" level="project" />
+    <orderEntry type="library" name="Maven: org.jboss.spec.javax.websocket:jboss-websocket-api_1.1_spec:2.0.0.Final" level="project" />
+    <orderEntry type="library" name="Maven: jakarta.servlet:jakarta.servlet-api:4.0.4" level="project" />
+    <orderEntry type="library" name="Maven: org.glassfish:jakarta.el:3.0.3" level="project" />
+    <orderEntry type="library" name="Maven: org.springblade:blade-starter-ribbon:2.9.1.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-netflix-ribbon:2.2.9.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-netflix-archaius:2.2.9.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: com.netflix.ribbon:ribbon:2.3.0" level="project" />
+    <orderEntry type="library" scope="RUNTIME" name="Maven: com.netflix.ribbon:ribbon-transport:2.3.0" level="project" />
+    <orderEntry type="library" scope="RUNTIME" name="Maven: io.reactivex:rxnetty-contexts:0.4.9" level="project" />
+    <orderEntry type="library" scope="RUNTIME" name="Maven: io.reactivex:rxnetty-servo:0.4.9" level="project" />
+    <orderEntry type="library" scope="RUNTIME" name="Maven: javax.inject:javax.inject:1" level="project" />
+    <orderEntry type="library" scope="RUNTIME" name="Maven: io.reactivex:rxnetty:0.4.9" level="project" />
+    <orderEntry type="library" name="Maven: com.netflix.ribbon:ribbon-core:2.3.0" level="project" />
+    <orderEntry type="library" name="Maven: com.netflix.ribbon:ribbon-httpclient:2.3.0" level="project" />
+    <orderEntry type="library" scope="RUNTIME" name="Maven: commons-collections:commons-collections:3.2.2" level="project" />
+    <orderEntry type="library" scope="RUNTIME" name="Maven: com.sun.jersey:jersey-client:1.19.1" level="project" />
+    <orderEntry type="library" scope="RUNTIME" name="Maven: com.sun.jersey:jersey-core:1.19.1" level="project" />
+    <orderEntry type="library" scope="RUNTIME" name="Maven: javax.ws.rs:jsr311-api:1.1.1" level="project" />
+    <orderEntry type="library" scope="RUNTIME" name="Maven: com.sun.jersey.contribs:jersey-apache-client4:1.19.1" level="project" />
+    <orderEntry type="library" scope="RUNTIME" name="Maven: com.netflix.servo:servo-core:0.12.21" level="project" />
+    <orderEntry type="library" scope="RUNTIME" name="Maven: com.netflix.netflix-commons:netflix-commons-util:0.3.0" level="project" />
+    <orderEntry type="library" name="Maven: com.netflix.ribbon:ribbon-loadbalancer:2.3.0" level="project" />
+    <orderEntry type="library" scope="RUNTIME" name="Maven: com.netflix.netflix-commons:netflix-statistics:0.1.1" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-discovery:2.2.7.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba.cloud:spring-cloud-alibaba-commons:2.2.7.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba.spring:spring-context-support:1.0.10" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-config:2.2.7.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba.nacos:nacos-client:2.0.4" level="project" />
+    <orderEntry type="library" name="Maven: commons-codec:commons-codec:1.14" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.httpcomponents:httpasyncclient:4.1.4" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.httpcomponents:httpcore-nio:4.4.14" level="project" />
+    <orderEntry type="library" name="Maven: org.reflections:reflections:0.9.11" level="project" />
+    <orderEntry type="library" name="Maven: org.javassist:javassist:3.21.0-GA" level="project" />
+    <orderEntry type="library" name="Maven: io.prometheus:simpleclient:0.5.0" level="project" />
+    <orderEntry type="library" name="Maven: cn.hutool:hutool-all:5.7.22" level="project" />
+    <orderEntry type="library" name="Maven: com.aliyun.oss:aliyun-sdk-oss:3.14.0" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.httpcomponents:httpclient:4.5.13" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.httpcomponents:httpcore:4.4.14" level="project" />
+    <orderEntry type="library" name="Maven: org.jdom:jdom2:2.0.6" level="project" />
+    <orderEntry type="library" name="Maven: org.codehaus.jettison:jettison:1.2" level="project" />
+    <orderEntry type="library" name="Maven: stax:stax-api:1.0.1" level="project" />
+    <orderEntry type="library" name="Maven: com.aliyun:aliyun-java-sdk-core:4.5.30" level="project" />
+    <orderEntry type="library" name="Maven: com.google.code.gson:gson:2.8.7" level="project" />
+    <orderEntry type="library" name="Maven: commons-logging:commons-logging:1.2" level="project" />
+    <orderEntry type="library" name="Maven: javax.xml.bind:jaxb-api:2.3.1" level="project" />
+    <orderEntry type="library" name="Maven: javax.activation:javax.activation-api:1.2.0" level="project" />
+    <orderEntry type="library" name="Maven: org.glassfish.jaxb:jaxb-runtime:2.3.4" level="project" />
+    <orderEntry type="library" name="Maven: org.glassfish.jaxb:txw2:2.3.4" level="project" />
+    <orderEntry type="library" name="Maven: com.sun.istack:istack-commons-runtime:3.0.12" level="project" />
+    <orderEntry type="library" scope="RUNTIME" name="Maven: com.sun.activation:jakarta.activation:1.2.2" level="project" />
+    <orderEntry type="library" name="Maven: org.bouncycastle:bcprov-jdk15on:1.68" level="project" />
+    <orderEntry type="library" name="Maven: org.jacoco:org.jacoco.agent:runtime:0.8.7" level="project" />
+    <orderEntry type="library" name="Maven: org.ini4j:ini4j:0.5.4" level="project" />
+    <orderEntry type="library" name="Maven: io.opentracing:opentracing-api:0.33.0" level="project" />
+    <orderEntry type="library" name="Maven: io.opentracing:opentracing-util:0.33.0" level="project" />
+    <orderEntry type="library" name="Maven: io.opentracing:opentracing-noop:0.33.0" level="project" />
+    <orderEntry type="library" name="Maven: com.aliyun:aliyun-java-sdk-ram:3.1.0" level="project" />
+    <orderEntry type="library" name="Maven: com.aliyun:aliyun-java-sdk-kms:2.11.0" level="project" />
     <orderEntry type="library" name="Maven: org.springblade:blade-starter-mybatis:2.9.1.RELEASE" level="project" />
     <orderEntry type="library" name="Maven: com.baomidou:mybatis-plus:3.5.1" level="project" />
     <orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-extension:3.5.1" level="project" />
@@ -47,24 +124,6 @@
     <orderEntry type="library" name="Maven: javax.annotation:javax.annotation-api:1.3.2" level="project" />
     <orderEntry type="library" name="Maven: org.springblade:blade-starter-auth:2.9.1.RELEASE" level="project" />
     <orderEntry type="library" name="Maven: org.springblade:blade-core-tool:2.9.1.RELEASE" level="project" />
-    <orderEntry type="library" name="Maven: org.springblade:blade-core-launch:2.9.1.RELEASE" level="project" />
-    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-web:2.3.12.RELEASE" level="project" />
-    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-json:2.3.12.RELEASE" level="project" />
-    <orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.11.4" level="project" />
-    <orderEntry type="library" name="Maven: com.fasterxml.jackson.module:jackson-module-parameter-names:2.11.4" level="project" />
-    <orderEntry type="library" name="Maven: org.springframework:spring-webmvc:5.2.15.RELEASE" level="project" />
-    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-undertow:2.3.12.RELEASE" level="project" />
-    <orderEntry type="library" name="Maven: io.undertow:undertow-core:2.1.7.Final" level="project" />
-    <orderEntry type="library" name="Maven: org.jboss.xnio:xnio-api:3.8.0.Final" level="project" />
-    <orderEntry type="library" name="Maven: org.wildfly.common:wildfly-common:1.5.2.Final" level="project" />
-    <orderEntry type="library" name="Maven: org.wildfly.client:wildfly-client-config:1.0.1.Final" level="project" />
-    <orderEntry type="library" scope="RUNTIME" name="Maven: org.jboss.xnio:xnio-nio:3.8.0.Final" level="project" />
-    <orderEntry type="library" name="Maven: org.jboss.threads:jboss-threads:3.1.0.Final" level="project" />
-    <orderEntry type="library" name="Maven: io.undertow:undertow-servlet:2.1.7.Final" level="project" />
-    <orderEntry type="library" name="Maven: org.jboss.spec.javax.annotation:jboss-annotations-api_1.3_spec:2.0.1.Final" level="project" />
-    <orderEntry type="library" name="Maven: io.undertow:undertow-websockets-jsr:2.1.7.Final" level="project" />
-    <orderEntry type="library" name="Maven: org.jboss.spec.javax.websocket:jboss-websocket-api_1.1_spec:2.0.0.Final" level="project" />
-    <orderEntry type="library" name="Maven: jakarta.servlet:jakarta.servlet-api:4.0.4" level="project" />
     <orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.11.4" level="project" />
     <orderEntry type="library" name="Maven: com.google.guava:guava:30.1.1-jre" level="project" />
     <orderEntry type="library" name="Maven: com.google.guava:failureaccess:1.0.1" level="project" />
@@ -80,10 +139,8 @@
     <orderEntry type="library" name="Maven: jakarta.xml.bind:jakarta.xml.bind-api:2.3.3" level="project" />
     <orderEntry type="library" name="Maven: jakarta.activation:jakarta.activation-api:1.2.2" level="project" />
     <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-validation:2.3.12.RELEASE" level="project" />
-    <orderEntry type="library" name="Maven: org.glassfish:jakarta.el:3.0.3" level="project" />
     <orderEntry type="library" name="Maven: org.hibernate.validator:hibernate-validator:6.1.7.Final" level="project" />
     <orderEntry type="library" name="Maven: jakarta.validation:jakarta.validation-api:2.0.2" level="project" />
-    <orderEntry type="library" name="Maven: org.jboss.logging:jboss-logging:3.4.2.Final" level="project" />
     <orderEntry type="library" name="Maven: org.springblade:blade-starter-jwt:2.9.1.RELEASE" level="project" />
     <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-data-redis:2.3.12.RELEASE" level="project" />
     <orderEntry type="library" name="Maven: org.springframework.data:spring-data-redis:2.3.9.RELEASE" level="project" />
@@ -118,7 +175,6 @@
     <orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-context:2.2.9.RELEASE" level="project" />
     <orderEntry type="library" name="Maven: org.springframework.security:spring-security-rsa:1.0.9.RELEASE" level="project" />
     <orderEntry type="library" name="Maven: org.bouncycastle:bcpkix-jdk15on:1.59" level="project" />
-    <orderEntry type="library" name="Maven: org.bouncycastle:bcprov-jdk15on:1.59" level="project" />
     <orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-openfeign-core:2.2.9.RELEASE" level="project" />
     <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-autoconfigure:2.3.12.RELEASE" level="project" />
     <orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-netflix-ribbon:2.2.9.RELEASE" level="project" />
@@ -136,8 +192,8 @@
     <orderEntry type="library" name="Maven: io.github.openfeign:feign-hystrix:10.12" level="project" />
     <orderEntry type="library" name="Maven: com.netflix.archaius:archaius-core:0.7.7" level="project" />
     <orderEntry type="library" name="Maven: com.google.code.findbugs:jsr305:3.0.2" level="project" />
-    <orderEntry type="library" scope="RUNTIME" name="Maven: commons-configuration:commons-configuration:1.8" level="project" />
-    <orderEntry type="library" scope="RUNTIME" name="Maven: commons-lang:commons-lang:2.6" level="project" />
+    <orderEntry type="library" name="Maven: commons-configuration:commons-configuration:1.8" level="project" />
+    <orderEntry type="library" name="Maven: commons-lang:commons-lang:2.6" level="project" />
     <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.11.4" level="project" />
     <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.11.4" level="project" />
     <orderEntry type="library" name="Maven: com.netflix.hystrix:hystrix-core:1.5.18" level="project" />

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

@@ -19,7 +19,7 @@ public class FormulaOptionVo {
     private String value;
     private Long pkeyId;
     private Integer scope;
-    private String name;
+    private String code;
     public boolean saveChecked(){
         if( Func.isNotBlank(value)&&contractId!=null&&parentId!=null&&pkeyId!=null&&key!=null&&scope!=null){
             if(scope==0){

+ 3 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/ArchiveTreeContract.java

@@ -176,6 +176,9 @@ public class ArchiveTreeContract extends BaseEntity {
 	//权限编码
 	private String treeCode;
 
+	//树形排序
+	private String treeSort;
+
 
 
 	public ArchiveTreeContract() {

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

@@ -258,4 +258,10 @@ public class WbsTreeContract extends BaseEntity {
     @ApiModelProperty(value = "是否为引用元素 1是 2否")
     private Integer isEle;
 
+    /**
+     * 数据分组
+     */
+    @ApiModelProperty(value = "数据分组Id")
+    private Long tabGroupId;
+
 }

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

@@ -1,6 +1,6 @@
 package org.springblade.manager.feign;
 
-import com.alibaba.fastjson.JSONObject;
+import org.springblade.business.dto.TrialSelfInspectionRecordDTO;
 import org.springblade.manager.entity.ExcelTab;
 import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.web.bind.annotation.PostMapping;
@@ -21,8 +21,8 @@ public interface ExcelTabClient {
     ExcelTab getById(@RequestParam String id);
 
     @PostMapping(API_PREFIX + "/saveTabData")
-    String saveTabData(@RequestParam Integer isBatchSave,
-                       @RequestBody JSONObject dataInfo,
+    String saveTabData(@RequestBody TrialSelfInspectionRecordDTO dto,
+                       @RequestParam Integer isBatchSave,
                        @RequestParam Integer type,
                        @RequestParam String tableType,
                        @RequestParam Long id,

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

@@ -1,6 +1,5 @@
 package org.springblade.manager.feign;
 
-import org.springblade.manager.entity.WbsTreeContract;
 import org.springblade.manager.entity.WbsTreePrivate;
 import org.springblade.manager.vo.WbsTreeContractTreeVOS;
 import org.springblade.manager.vo.WbsTreePrivateVO;
@@ -39,11 +38,8 @@ public interface WbsTreePrivateClient {
     @PostMapping(API_PREFIX + "/queryWbsTreePrivateByProjectIdAndId")
     List<WbsTreeContractTreeVOS> queryWbsTreePrivateByProjectIdAndId(@RequestParam String projectId, @RequestParam Long id);
 
-    @PostMapping(API_PREFIX + "/showBussTab")
-    boolean showBussTab(@RequestParam Long pkeyId, @RequestParam Integer status);
-
     @PostMapping(API_PREFIX + "/copyBussTab")
-    boolean copyBussTab(@RequestParam Long pKeyId);
+    boolean copyBussTab(@RequestParam Long pKeyId, @RequestParam Long id);
 
     @PostMapping(API_PREFIX + "/removeBussTabInfoById")
     boolean removeBussTabInfoById(@RequestParam Long pKeyId);

+ 14 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/ArchiveTreeContractVO2.java

@@ -182,6 +182,11 @@ public class ArchiveTreeContractVO2 implements INode<ArchiveTreeContractVO2> {
 	 */
 	private Integer archiveAutoGroupSelect;
 
+	private Integer sort;
+
+	//树形排序
+	private String treeSort;
+
 	public String toString() {
 		return "TreeNode(parentId=" + this.getParentId()
 				+ ",ancestors" + this.getAncestors()
@@ -213,4 +218,13 @@ public class ArchiveTreeContractVO2 implements INode<ArchiveTreeContractVO2> {
 		}
 	}
 
+	public Integer sortNum(){
+		if (getSort() != null ) {
+			return getSort() + 100;
+		}
+		return 100;
+	}
+
+
+
 }

+ 35 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/TrialRecordZJTreeVO.java

@@ -0,0 +1,35 @@
+package org.springblade.manager.vo;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import lombok.Data;
+import org.springblade.core.tool.node.INode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Data
+public class TrialRecordZJTreeVO implements INode<TrialRecordZJTreeVO> {
+
+    private Long id;
+
+    private String primaryKeyId;
+
+    private String fullName;
+
+    private Long parentId;
+
+    @JsonInclude(JsonInclude.Include.NON_EMPTY)
+    private Boolean hasChildren;
+
+    @JsonInclude(JsonInclude.Include.NON_EMPTY)
+    private List<TrialRecordZJTreeVO> children;
+
+    @Override
+    public List<TrialRecordZJTreeVO> getChildren() {
+        if (this.children == null) {
+            this.children = new ArrayList<>();
+        }
+        return this.children;
+    }
+
+}

+ 28 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/WbsTreeContractVO6.java

@@ -56,6 +56,34 @@ public class WbsTreeContractVO6 extends WbsTreeContract implements INode<WbsTree
         return this.children;
     }
 
+    public boolean isProcessType(){
+        if (this.getMajorDataType() != null ) {
+            if (this.getMajorDataType() == 1
+                    || this.getMajorDataType() == 2
+                    || this.getMajorDataType() == 3){
+                return false;
+            }
+        }
+
+        if (this.getTitle() != null ){
+            if (this.getTitle().contains("中间交工")
+                    || this.getTitle().contains("质量评定")
+                    || this.getTitle().contains("开工报告")
+                    || this.getTitle().contains("质量验收评定")) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    public boolean isMatchLevel(Long level){
+        if (this.getNodeType() != null && this.getNodeType() > level) {
+            return  false;
+        }
+        return true;
+    }
+
     @Override
     public Boolean getHasChildren() {
         return hasChildren;

+ 42 - 4
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/WbsTreePrivateVO4.java

@@ -1,16 +1,54 @@
 package org.springblade.manager.vo;
 
+import com.fasterxml.jackson.annotation.JsonProperty;
 import lombok.Data;
-import lombok.EqualsAndHashCode;
-import org.springblade.manager.entity.WbsTreePrivate;
 
+import java.io.Serializable;
 import java.util.Map;
 
 @Data
-@EqualsAndHashCode(callSuper = true)
-public class WbsTreePrivateVO4 extends WbsTreePrivate{
+public class WbsTreePrivateVO4 implements Serializable {
     private static final long serialVersionUID = 1L;
 
     private Map<String, Object> bussDataInfoTrial;
 
+    @JsonProperty(value = "pKeyId")
+    private Long pKeyId;
+
+    private String projectId;
+
+    private String wbsId;
+
+    private String wbsType;
+
+    private String nodeName;
+
+    private Integer nodeType;
+
+    private Integer type;
+
+    private Integer tableType;
+
+    private String tableOwner;
+
+    private String initTableName;
+
+    private String initTableId;
+
+    private Long excelId;
+
+    private String htmlUrl;
+
+    private String fillRate;
+
+    private Integer isTabPdf;
+
+    private String pdfUrl;
+
+    private Integer isBussShow;
+
+    private Integer tabFileType;
+
+    private Integer isLinkTable;
+
 }

+ 29 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/WbsTreeVO2.java

@@ -62,6 +62,35 @@ public class WbsTreeVO2 implements INode<WbsTreeVO2> {
         return this.children;
     }
 
+    public boolean isProcessType(){
+        if (this.getMajorDataType() != null ) {
+            if (this.getMajorDataType() == 1
+                    || this.getMajorDataType() == 2
+                    || this.getMajorDataType() == 3){
+                return false;
+            }
+        }
+
+        if (this.getTitle() != null ){
+            if (this.getTitle().contains("中间交工")
+                    || this.getTitle().contains("质量评定")
+                    || this.getTitle().contains("开工报告")
+                    || this.getTitle().contains("质量验收评定")) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    public boolean isMatchLevel(Long level){
+        if (this.getNodeType() != null && this.getNodeType() > level) {
+            return  false;
+        }
+        return true;
+    }
+
+
     @Override
     public Boolean getHasChildren() {
         return hasChildren;

+ 26 - 0
blade-service/blade-archive/src/main/java/org/springblade/archive/feign/ArchiveAutoClientImpl.java

@@ -0,0 +1,26 @@
+package org.springblade.archive.feign;
+
+import lombok.AllArgsConstructor;
+import org.springblade.archive.entity.ArchivesAuto;
+import org.springblade.archive.service.IArchivesAutoService;
+import org.springblade.archive.vo.ArchivesAutoVO;
+import org.springblade.core.tool.api.R;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@RestController
+@AllArgsConstructor
+public class ArchiveAutoClientImpl implements ArchiveAutoClient {
+
+    private IArchivesAutoService archivesAutoService;
+
+    @Override
+    public R saveArchiveAutoByNodes(@RequestBody List<ArchivesAuto> list){
+
+
+        return  R.status(archivesAutoService.saveBatch(list));
+    }
+}

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

@@ -41,8 +41,7 @@
         <result column="mileage" property="mileage"/>
         <result column="fileType" property="fileType"/>
         <result column="size" property="size"/>
-        <result column="procsort" property="procsort"/>
-        <result column="node_sort" property="nodeSort"/>
+        <result column="tree_sort" property="nodeSort"/>
         <result column="isOpen" property="isOpen"/>
         <result column="ischeck" property="ischeck"/>
     </resultMap>

+ 19 - 2
blade-service/blade-business/src/main/java/org/springblade/business/controller/InformationWriteQueryController.java

@@ -899,6 +899,13 @@ public class InformationWriteQueryController extends BladeController {
     @ApiOperationSupport(order = 20)
     @ApiOperation(value = "批量打印")
     public R<String> batchPrint(@RequestParam String ids) {
+        //判断是否未生成文件
+        List<String> list = Arrays.asList(ids.split(","));
+        for (String s : list) {
+            if (StringUtils.isBlank(s)){
+                return R.fail("选择的资料未生成文件");
+            }
+        }
         //获取勾选的数据
         List<InformationQuery> queries = this.informationQueryService.getBaseMapper().selectBatchIds(Arrays.asList(ids.split(",")));
         //pdf集合
@@ -952,8 +959,15 @@ public class InformationWriteQueryController extends BladeController {
     @PostMapping("/batchDownloadFileToZip")
     @ApiOperationSupport(order = 19)
     @ApiOperation(value = "批量下载")
-    public void batchDownloadFileToZip(String ids, HttpServletResponse response) {
+    public R<String> batchDownloadFileToZip(String ids, HttpServletResponse response) {
         if (StringUtils.isNotEmpty(ids)) {
+            //判断是否未生成文件
+            List<String> list = Arrays.asList(ids.split(","));
+            for (String s : list) {
+                if (StringUtils.isBlank(s)){
+                    return R.fail("选择的资料未生成文件");
+                }
+            }
             //获取文件
             List<InformationQuery> result = this.informationQueryService.list(Wrappers.<InformationQuery>lambdaQuery().in(InformationQuery::getId, Arrays.asList(ids.split(","))));
             if (result != null && result.size() > 0) {
@@ -968,6 +982,9 @@ public class InformationWriteQueryController extends BladeController {
                     FileUtils.batchDownloadFileToZip(urls, response);
                 }
             }
+            return R.success("下载成功");
+        }else {
+            return R.fail("选择的资料未生成文件");
         }
     }
 
@@ -2472,7 +2489,7 @@ public class InformationWriteQueryController extends BladeController {
             //施工合同段
             rootTreeNode = this.informationQueryService.queryContractTree(contractId, StringUtils.isNotEmpty(parentId) ? parentId : "0", 1);
             rootTreeNode.stream().forEach(rtn->{
-                if (rtn.getSubmitCounts() > 0L){
+                if (rtn.getSubmitCounts() > 0L && rtn.getColorStatus() <= 1 && rtn.getNotExsitChild() == false){
                     rtn.setColorStatus(2);
                 }
             });

+ 17 - 6
blade-service/blade-business/src/main/java/org/springblade/business/controller/NeiYeController.java

@@ -57,7 +57,10 @@ public class NeiYeController {
         if(queryVO.getWbsIds() != null && queryVO.getWbsIds().size() > 0){
             //生成列表
             List<NeiYeLedgerVO> neiYeLedgerVOList = new ArrayList<>();
-
+            Integer contractType=1;
+            if (StringUtils.isNotBlank(queryVO.getContractIdRelation())){
+                contractType = 2;
+            }
             ContractInfo contract = this.contractClient.getContractById(Long.parseLong(queryVO.getContractId()));
             String contractId = contract.getId().toString();
             if(!new Integer("1").equals(contract.getContractType())){
@@ -83,18 +86,24 @@ public class NeiYeController {
                     && !node.getNodeName().contains("开工报告")&& !node.getNodeName().contains("质量检验评定表")){
                 //非填报节点
                 if (node.getParentId() == 0){
-                        queryDataResult = this.informationQueryService.queryProcessDataByParentIdAndContractIdTwo("", contract.getContractType(), contractId);
+                        queryDataResult = this.informationQueryService.queryProcessDataByParentIdAndContractIdTwo("", contractType, contractId);
                 }else {
-                    queryDataResult = this.informationQueryService.queryProcessDataByParentIdAndContractIdTwo(node.getId().toString(), contract.getContractType(), contractId);
+                    queryDataResult = this.informationQueryService.queryProcessDataByParentIdAndContractIdTwo(node.getId().toString(), contractType, contractId);
                 }
             } else {
                 //填报节点
-                queryDataResult = this.informationQueryService.queryProcessDataByPrimaryKeyIdAndClassify(node.getPKeyId().toString(), contract.getContractType());
+                queryDataResult = this.informationQueryService.queryProcessDataByPrimaryKeyIdAndClassify(node.getPKeyId().toString(),contractType);
             }
 
             if (queryDataResult != null && queryDataResult.size() > 0) {
                 //删除掉首件
                 queryDataResult.removeIf(query -> StringUtils.isNotEmpty(query.getQueryType()) && "3".equals(query.getQueryType()));
+                //过滤试验
+                String isExperiment = queryVO.getIsExperiment()+"";
+                if (!"".equals(isExperiment) && !"null".equals(isExperiment) && isExperiment != null) {
+                    queryDataResult = queryDataResult.stream()
+                            .filter(qdr->isExperiment.equals(qdr.getIsExperiment())).collect(Collectors.toList());
+                }
                 //设置评定值
                 queryDataResult.stream().forEach(qdr->qdr.setEvaluate("false"));
                 List<QueryProcessDataVO> vos = queryDataResult.stream().filter(qdr -> qdr.getTitle().contains("质量检验评定表"))
@@ -233,8 +242,10 @@ public class NeiYeController {
                             map.get("detectionStartToEndTime"),
                             new Integer("1").equals(vo.getStatus()) ? "待审批" : new Integer("2").equals(vo.getStatus()) ? "已审批" : "未上报",
                             vo.getEvaluate(),
-                            "false",
-                            vo.getReportNumber()));
+                            vo.getIsExperiment(),
+                            vo.getReportNumber(),
+                            vo.getInformationQueryId())
+                    );
                 }
                 //转换为page信息
                 Query query = new Query();

+ 544 - 535
blade-service/blade-business/src/main/java/org/springblade/business/controller/TaskController.java

@@ -28,9 +28,12 @@ import org.springblade.core.sms.model.SmsResponse;
 import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.jackson.JsonUtil;
 import org.springblade.core.tool.utils.DateUtil;
+import org.springblade.core.tool.utils.Func;
 import org.springblade.core.tool.utils.ObjectUtil;
 import org.springblade.flow.core.entity.BladeFlow;
 import org.springblade.flow.core.feign.NewFlowClient;
+import org.springblade.manager.entity.ContractInfo;
+import org.springblade.manager.feign.ContractClient;
 import org.springblade.resource.feign.CommonFileClient;
 import org.springblade.resource.feign.NewISmsClient;
 import org.springblade.system.entity.DictBiz;
@@ -59,471 +62,483 @@ import java.util.stream.Collectors;
 @Api(value = "任务审核主表", tags = "任务审核主表接口")
 public class TaskController extends BladeController {
 
-	private final ITaskService taskService;
-
-	private final ITaskParallelService taskParallelService;
-
-	private final NewFlowClient newFlowClient;
-
-	private final IDictBizClient dictBizClient;
-
-	private final NewISmsClient newSmsClient;
-
-	private final IDefaultConfigService defaultConfigService;
-
-	private final ITaskBatchService taskBatchService;
-
-	private final ITaskService iTaskService;
-
-	private final WebSocket webSocket;
-
-	private final CommonFileClient commonFileClient;
-
-	private final ITrialSelfInspectionRecordService iTrialSelfInspectionRecordService;
-
-	/**
-	 * 记录短信验证码超时时间
-	 */
-	@GetMapping("/save-sms-timeout")
-	@ApiOperationSupport(order = 13)
-	@ApiOperation(value = "记录短信验证码超时时间")
-	public void saveSmsTimeout(@RequestParam String code){
-		//获取账户记录
-		DefaultConfig config = this.defaultConfigService.getOne(Wrappers.<DefaultConfig>lambdaQuery().eq(DefaultConfig::getCreateUser, AuthUtil.getUserId()));
-		if(config != null){
-			//获取当前时间
-			Date now = DateUtil.now();
-			//默认16小时后超时
-			now = DateUtil.plusHours(now, 16);
-
-			LambdaUpdateWrapper<DefaultConfig> wrapper = new LambdaUpdateWrapper<>();
-			wrapper.set(DefaultConfig::getSmsTimeOut, DateUtil.format(now, "yyyy-MM-dd HH:mm:ss"));
-			if(!StringUtils.equals(config.getSmsCode(), code)){
-				wrapper.set(DefaultConfig::getSmsCode, code);
-			}
-			//生成超时时间
-			this.defaultConfigService.update(wrapper.eq(DefaultConfig::getCreateUser, AuthUtil.getUserId()));
-		}
-	}
-
-	/**
-	 * 校验电签短信验证码
-	 */
-	@PostMapping("/check-sms-code")
-	@ApiOperationSupport(order = 12)
-	@ApiOperation(value = "校验电签短信验证码")
-	public R<String> checkSmsCode(){
-		//获取账户验证码
-		DefaultConfig config = this.defaultConfigService.getOne(Wrappers.<DefaultConfig>lambdaQuery().eq(DefaultConfig::getCreateUser, AuthUtil.getUserId()));
-
-		if(config != null){
-			if(StringUtils.isNotEmpty(config.getSmsTimeOut())){
-				//获取当前时间
-				Date now = DateUtil.now();
-				//先自行校验是否超时
-				Duration duration = DateUtil.between(DateUtil.parse(config.getSmsTimeOut(), "yyyy-MM-dd HH:mm:ss"), now);
-				if(duration.getSeconds() > 0){
-					//说明已经超时,清空短信验证记录
-					this.defaultConfigService.update(Wrappers.<DefaultConfig>lambdaUpdate().set(DefaultConfig::getSmsTimeOut, null).set(DefaultConfig::getSmsCode, null).eq(DefaultConfig::getId, config.getId()));
-				}
-			}
-			return R.data(config.getSmsTimeOut());
-		}
-
-		return R.data(null);
-	}
-
-	/**
-	 * 批量审批详情
-	 */
-	@GetMapping("/batch-approval-parameter")
-	@ApiOperationSupport(order = 11)
-	@ApiOperation(value = "批量页详情")
-	@ApiImplicitParams({
-			@ApiImplicitParam(name = "formDataId", value = "数据源", required = true),
-			@ApiImplicitParam(name = "approvalType", value = "上报类型", required = true)
-	})
-	public R<TaskApprovalVO> getBatchApprovalTaskParameter(@RequestParam String formDataId, @RequestParam Integer approvalType){
-		TaskApprovalVO result = new TaskApprovalVO();
-		result.setFormDataId(formDataId);
-		result.setApprovalType(approvalType);
-
-		return R.data(this.taskService.queryBusinessData(result));
-	}
-
-	/**
-	 * 短信验证
-	 */
-	@PostMapping("/send-notice")
-	@ApiOperationSupport(order = 10)
-	@ApiOperation(value = "短信验证")
-	public R<Boolean> sendNotice(@RequestParam String phone){
-		String code = CommonUtil.getCharAndNumber(4);
-		Map<String, String> params = new HashMap<>(3);
-		params.put("code", code);
-		R<SmsResponse> result = this.newSmsClient.sendMessage("test_code", JsonUtil.toJson(params), phone);
-		if(result.getData().isSuccess()){
-			//记录当前验证码
-			DefaultConfig config = this.defaultConfigService.getOne(Wrappers.<DefaultConfig>lambdaQuery().eq(DefaultConfig::getCreateUser, AuthUtil.getUserId()));
-			if(config != null){
-				//修改
-				config.setSmsCode(code);
-				this.defaultConfigService.updateById(config);
-			} else {
-				//新增
-				config = new DefaultConfig();
-				config.setSmsCode(code);
-				config.setCreateUser(AuthUtil.getUserId());
-				config.setCreateTime(new Date());
-				this.defaultConfigService.save(config);
-			}
-		}
-		return result.getData().isSuccess() ? R.data(200, true, code) : R.data(499, false, String.valueOf(JSONObject.parseObject(result.getData().getMsg(), Map.class).get("Message")));
-	}
-
-	/**
-	 * 获取发起
-	 */
-	@GetMapping("/query-user-start-flow")
-	@ApiOperationSupport(order =  9)
-	@ApiOperation(value = "获取发起")
-	public R<IPage<TaskVO>> queryUserStartFlow(TaskQueryVO queryVO){
-		//获取发起,只需要查询主表
-		//先查询符合条件的流程
-		LambdaQueryWrapper<Task> wrapper = Wrappers.<Task>lambdaQuery().eq(Task::getProjectId, queryVO.getProjectId()).eq(Task::getReportUser, AuthUtil.getUserId().toString());
-		//设置查询参数
-		this.integrationMethod(wrapper, queryVO);
-		//获取主流程
-		List<Task> masterTaskList = this.taskService.list(wrapper);
-		if(masterTaskList != null && masterTaskList.size() > 0){
-			//获取集合
-			List<String> processInstanceIds = masterTaskList.stream().map(Task::getProcessInstanceId).distinct().collect(Collectors.toList());
-			//设置主表map,方便获取
-			Map<String, Task> masterTaskMap = new HashMap<>();
-			masterTaskList.forEach(task -> masterTaskMap.put(task.getProcessInstanceId(), task));
-
-			R<Object> rObject = this.newFlowClient.selectSendPage(queryVO.getCurrent(), queryVO.getSize(),queryVO.getOrdType()==null?1:queryVO.getOrdType(), String.join(",", processInstanceIds));
-			if(rObject.isSuccess()){
-				Query query = new Query();
-				query.setCurrent(queryVO.getCurrent());
-				query.setSize(queryVO.getSize());
-				//新建一个IPage的实例
-				IPage<BladeFlow> newData = Condition.getPage(query);
-				//使用实例获取具体的类型进行转换
-				IPage flowIPage = JSONObject.parseObject(JSONObject.toJSONString(rObject.getData()), newData.getClass());
-				//本质上这里获取到的集合属于List<JSONObject>,所以需要在这进行一次类型转换,将JSONObject转为BladeFlow
-				List<BladeFlow> result = JSONArray.parseArray(JSONObject.toJSONString(flowIPage.getRecords()), BladeFlow.class);
-
-				//最终结果集合
-				List<TaskVO> finalResult = new ArrayList<>();
-				for(BladeFlow  flow : result) {
-					//获取实体
-					Task task = masterTaskMap.get(flow.getProcessInstanceId());
-					//类型转换
-					TaskVO vo = new TaskVO();
-					BeanUtils.copyProperties(task, vo);
-					//设置关键信息
-					vo.setTypeValue(new Integer("1").equals(vo.getType()) ? "普通任务" : new Integer("2").equals(vo.getType()) ? "验收任务" : "移交任务");
-					vo.setTaskId(flow.getTaskId());
-					vo.setTaskStatus(new Integer("1").equals(task.getStatus()) ? "待审批" : new Integer("2").equals(task.getStatus()) ? "已审批" : "已废除", task.getStatus());
-					//查询分支流程信息
-					List<TaskParallel> linkList = this.taskParallelService.list(Wrappers.<TaskParallel>lambdaQuery().eq(TaskParallel::getProcessInstanceId, task.getProcessInstanceId()));
-					if (linkList != null && !linkList.isEmpty()) {
-						this.integrationMethod(vo, linkList);
-					}
-					finalResult.add(vo);
-				}
-
-				// 手机app 需要排序接口
-				if(queryVO.getOrdType()!=null && queryVO.getOrdType()==1){ // 降序
-					finalResult.sort(Comparator.comparing(TaskVO::getCreateTime).reversed());
-				}
-				if(queryVO.getOrdType()!=null && queryVO.getOrdType()==2){ // 升序
-					finalResult.sort(Comparator.comparing(TaskVO::getCreateTime));
-				}
-
-				//最终分页数据
-				return this.getIPageR(query, flowIPage, finalResult);
-			}
-		}
-
-		return R.data(null);
-	}
-
-	/**
-	 * 统合方法
-	 */
-	private void integrationMethod(TaskVO vo, List<TaskParallel> linkList) {
-		linkList.forEach(link -> vo.setWaitingUserList(link.getTaskUserName(), new Integer("999").equals(link.getEVisaStatus()) ? 999 : new Integer("2").equals(link.getStatus()) ? 2 : new Integer("3").equals(link.getStatus()) && new Integer("1").equals(link.getInitiative()) ? 3 : 1));
-	}
-
-	/**
-	 * 批量审批
-	 */
-	@PostMapping("/batch-complete-approval-task")
-	@ApiOperationSupport(order = 8)
-	@ApiOperation(value = "批量审批")
-	public R<Boolean> batchCompleteApprovalTask(@RequestBody BatchTaskVO batchTaskVO) throws IOException {
-		String taskIds = batchTaskVO.getTaskIds();
-		String parallelProcessInstanceIds = batchTaskVO.getParallelProcessInstanceIds();
-		if(StringUtils.isNotEmpty(taskIds)){
-			String[] taskIdArray = taskIds.split(",");
-			String[] parallelProcessInstanceIdArray = parallelProcessInstanceIds.split(",");
-			String[] approvalType = batchTaskVO.getApprovalType().split(",");
-			String[] formDataId = batchTaskVO.getFormDataId().split(",");
-
-			List<TaskApprovalVO> taskApprovalVOS = new ArrayList<>();
-
-			for(int i = 0, l = taskIdArray.length; i < l; i ++){
-				TaskApprovalVO approvalVO = new TaskApprovalVO();
-				approvalVO.setTaskId(taskIdArray[i]);
-				approvalVO.setParallelProcessInstanceId(parallelProcessInstanceIdArray[i]);
-				approvalVO.setFlag(batchTaskVO.getFlag());
-				approvalVO.setComment(batchTaskVO.getComment());
-				approvalVO.setApprovalType(Integer.parseInt(approvalType[i]));
-				approvalVO.setFormDataId(formDataId[i]);
-
-				taskApprovalVOS.add(approvalVO);
-			}
-
-			//修改试验填报状态,关联工程部位信息pdf
-			this.iTrialSelfInspectionRecordService.updateTrialSelfInspectionRecordStatus(taskApprovalVOS);
-
-			//审批
-			this.taskService.batchCompleteApprovalTask(taskApprovalVOS,AuthUtil.getUserId());
-
-			//通过WebSocket推送数量条数
-			if (ObjectUtil.isNotEmpty(AuthUtil.getUserId())) {
-				Map<String, String> webSocketMessageMap = WebSocket.getWebSocketMessageMap();
-				Set<Map.Entry<String, String>> message = webSocketMessageMap.entrySet();
-				for (Map.Entry<String, String> entry : message) {
-					String userId = entry.getKey();
-					if (userId.equals(AuthUtil.getUserId().toString())) { //只推送当前用户
-						String projectAndContractId = entry.getValue();
-						if (StringUtils.isNotEmpty(projectAndContractId) && StringUtils.isNotEmpty(userId)) {
-							String projectId = projectAndContractId.split(",")[0];
-							String contractId = projectAndContractId.split(",")[1];
-							Map<String, String> stringMap = iTaskService.getTaskCount(projectId, contractId, userId);
-
-							webSocket.sendMessageByUserId(AuthUtil.getUserId().toString(), JSON.toJSONString(stringMap));
-						}
-					}
-				}
-			}
-
-			return R.data(true);
-		}
-		return R.data(false);
-	}
-
-	/**
-	 * 获取当前合同段的上报批次
-	 * @param projectId 项目ID
-	 * @param contractId 合同段ID
-	 */
-	@GetMapping("/query-batch-list")
-	@ApiOperationSupport(order = 7)
-	@ApiOperation(value = "获取当前合同段的上报批次")
-	@ApiImplicitParams({
-			@ApiImplicitParam(name = "projectId", value = "项目ID", required = true),
-			@ApiImplicitParam(name = "contractId", value = "合同段ID", required = true)
-	})
-	public R<List<Task>> queryBatchList(String projectId, String contractId){
-		return R.data(this.taskService.queryBatchList(projectId, contractId));
-	}
-
-	/**
-	 * 获取当前合同段有哪些上报批次
-	 * @param projectId 项目ID
-	 * @param contractId 合同段ID
-	 */
-	@GetMapping("/query-batch-list-two")
-	@ApiOperationSupport(order = 7)
-	@ApiOperation(value = "获取当前合同段的上报批次")
-	@ApiImplicitParams({
-			@ApiImplicitParam(name = "projectId", value = "项目ID", required = true),
-			@ApiImplicitParam(name = "contractId", value = "合同段ID", required = true)
-	})
-	public R<List<String>> queryBatchListTwo(String projectId, String contractId,String type){
-		if (StringUtils.isBlank(type)) {
-			//为空,以information为主表查询填报资料批次
-			return R.data(this.taskService.queryBatchListTwo(projectId, contractId));
-		}else{
-			//如果type为1内页台账不需要去查询首件批次,type为2只查标记为首件的,type为3只查首件
-			return R.data(this.taskService.queryBatchListThree(projectId, contractId,type));
-		}
-	}
-
-
-	/**
-	 * 获取任务类型或任务状态
-	 */
-	@GetMapping("/query-task-type-status")
-	@ApiOperationSupport(order = 6)
-	@ApiOperation(value = "获取任务类型或任务状态")
-	public R<List<DictBiz>> queryTaskTypeOrStatus(String typeOrStatus){
-		return this.dictBizClient.getList(typeOrStatus, "notRoot");
-	}
-
-	/**
-	 * 获取已办
-	 */
-	@GetMapping("/query-user-done-task-list")
-	@ApiOperationSupport(order = 5)
-	@ApiOperation(value = "获取已办")
-	public R<IPage<TaskVO>> queryUserDoneTaskList(TaskQueryVO queryVO){
-		//设置获取参数
-		Map<String,Task> masterTaskMap = new HashMap<>();
-		Map<String,TaskParallel> parallelMap = new HashMap<>();
-		List<String> parallelProcessInstanceIds = new ArrayList<>();
-		//统合查询方法
-		this.integrationMethod(queryVO, masterTaskMap, parallelMap, parallelProcessInstanceIds, "2,3");
-
-		//获取已办(基于原生已办)
-		R<Object> rObject = this.newFlowClient.selectDonePage(queryVO.getCurrent(), queryVO.getSize(),queryVO.getOrdType()==null?1:queryVO.getOrdType(), String.join(",", parallelProcessInstanceIds));
-		//处理参数
-		return this.integrationMethod(queryVO, rObject, masterTaskMap, parallelMap, false);
-	}
-
-	/**
-	 * 审批页详情
-	 */
-	@GetMapping("/query-approval-parameter")
-	@ApiOperationSupport(order = 4)
-	@ApiOperation(value = "审批页详情(单任务时)")
-	public R<TaskApprovalVO> getApprovalTaskParameter(@RequestParam String parallelProcessInstanceId, @RequestParam String formDataId, @RequestParam Integer approvalType){
-		TaskApprovalVO vo = new TaskApprovalVO();
-		vo.setFormDataId(formDataId);
-		vo.setApprovalType(approvalType);
-		//获取具体业务数据
-		return R.data(this.taskService.queryBusinessData(vo));
-	}
-	/**
-	 * 审批页pdf数量详情
-	 */
-	@GetMapping("/query-approval-parameter-pdf-num")
-	@ApiOperationSupport(order = 14)
-	@ApiOperation(value = "审批页pdf数量详情")
-	public R<Object> getApprovalTaskParameterPdfNum(@RequestParam String url){
-		String pdfNum = this.commonFileClient.getPdfNum(url);
-		return R.data(pdfNum);
-	}
-	/**
-	 * 获取当前用户待办流程
-	 */
-	@GetMapping("/user-to-do-task-list")
-	@ApiOperationSupport(order = 3)
-	@ApiOperation(value = "获取当前用户待办流程")
-	public R<IPage<TaskVO>> todoUserApprovalTask(TaskQueryVO queryVO){
-		//设置获取参数
-		Map<String,Task> masterTaskMap = new HashMap<>();
-		Map<String,TaskParallel> parallelMap = new HashMap<>();
-		List<String> parallelProcessInstanceIds = new ArrayList<>();
-		//统合查询方法
-		this.integrationMethod(queryVO, masterTaskMap, parallelMap, parallelProcessInstanceIds, "1");
-
-		//获取待办(基于原生待办)
-		R<Object> rObject = this.newFlowClient.selectTodoPage(queryVO.getCurrent(), queryVO.getSize(),queryVO.getOrdType()==null?1:queryVO.getOrdType(), String.join(",", parallelProcessInstanceIds));
-		//处理参数
-		return this.integrationMethod(queryVO, rObject, masterTaskMap, parallelMap, true);
-	}
-
-	/**
-	 * 统合查询方法
-	 */
-	private void integrationMethod(TaskQueryVO queryVO, Map<String,Task> masterTaskMap, Map<String,TaskParallel> parallelMap, List<String> parallelProcessInstanceIds, String status){
-		//先查询符合条件的流程
-		LambdaQueryWrapper<Task> wrapper = Wrappers.<Task>lambdaQuery().eq(Task::getIsDeleted, 0)
-				.eq(Task::getProjectId, queryVO.getProjectId()).eq(StringUtils.isNotBlank(queryVO.getBatch()),Task::getBatch,queryVO.getBatch());
-		this.integrationMethod(wrapper, queryVO);
-
-		//符合条件的集合
-		List<Task> masterTaskList = this.taskService.list(wrapper);
-		//根据主表获取附表且当前用户的记录
-		List<String> processInstanceIds = new ArrayList<>();
-		masterTaskList.forEach(task -> {
-			masterTaskMap.put(task.getProcessInstanceId(), task);
-			processInstanceIds.add(task.getProcessInstanceId());
-		});
-
-		if(processInstanceIds.size() > 0){
-			List<TaskParallel> parallelTaskList = this.taskParallelService.list(Wrappers.<TaskParallel>lambdaQuery().in(TaskParallel::getProcessInstanceId, processInstanceIds).eq(TaskParallel::getTaskUser, AuthUtil.getUserId().toString()).eq(TaskParallel::getIsDeleted, 0).in(TaskParallel::getStatus, Arrays.asList(status.split(","))));
-			parallelTaskList.forEach(parallel -> {
-				parallelMap.put(parallel.getParallelProcessInstanceId(), parallel);
-				parallelProcessInstanceIds.add(parallel.getParallelProcessInstanceId());
-			});
-		}
-	}
-
-	private void integrationMethod(LambdaQueryWrapper<Task> wrapper, TaskQueryVO queryVO){
-		//任务类型
-		if(StringUtils.isNotEmpty(queryVO.getTaskType())){
-			wrapper.eq(Task::getType, queryVO.getTaskType());
-		}
-		//任务状态
-		if(StringUtils.isNotEmpty(queryVO.getTaskStatus())){
-			wrapper.eq(Task::getStatus, queryVO.getTaskStatus());
-		}
-		//合同段ID
-		if(StringUtils.isNotEmpty(queryVO.getContractId())){
-			wrapper.eq(Task::getContractId, queryVO.getContractId());
-		}
-		//开始结束时间
-		if(StringUtils.isNotEmpty(queryVO.getStartTime()) && StringUtils.isNotEmpty(queryVO.getEndTime())){
-			wrapper.between(Task::getStartTime, queryVO.getStartTime(), queryVO.getEndTime());
-		}
-		//关键字查询
-		if(StringUtils.isNotEmpty(queryVO.getQueryValue())){
-			wrapper.like(Task::getTaskName, queryVO.getQueryValue());
-		}
-	}
-
-	/**
-	 * 统合处理方法
-	 */
-	private R<IPage<TaskVO>> integrationMethod(TaskQueryVO queryVO, R<Object> rObject, Map<String,Task> masterTaskMap, Map<String,TaskParallel> parallelMap, boolean isToDo){
-		Query query = new Query();
-		query.setCurrent(queryVO.getCurrent());
-		query.setSize(queryVO.getSize());
-		//最终集合
-		List<TaskVO> finalResult = new ArrayList<>();
-		if(rObject.isSuccess()){
-			//新建一个IPage的实例
-			IPage<BladeFlow> newData = Condition.getPage(query);
-			//使用实例获取具体的类型进行转换
-			IPage flowIPage = JSONObject.parseObject(JSONObject.toJSONString(rObject.getData()), newData.getClass());
-			//本质上这里获取到的集合属于List<JSONObject>,所以需要在这进行一次类型转换,将JSONObject转为BladeFlow
-			List<BladeFlow> result = JSONArray.parseArray(JSONObject.toJSONString(flowIPage.getRecords()), BladeFlow.class);
-
-			if(result != null && result.size() > 0){
-				//获取相关信息
-				result.forEach(flow -> {
-					TaskParallel taskParallel = parallelMap.get(flow.getProcessInstanceId());
-					if(taskParallel != null){
-						//查询主表数据
-						Task task = masterTaskMap.get(taskParallel.getProcessInstanceId());
-
-						if(task != null){
-							//复制数据
-							TaskVO vo = new TaskVO();
-							BeanUtils.copyProperties(task, vo);
-							//设置关键信息
-							vo.setTypeValue(new Integer("1").equals(vo.getType()) ? "普通任务" : new Integer("2").equals(vo.getType()) ? "验收任务" : "移交任务");
-							vo.setParallelProcessInstanceId(flow.getProcessInstanceId());
-							vo.setTaskId(flow.getTaskId());
-							vo.setTaskStatus(new Integer("1").equals(task.getStatus()) ? "待审批" : new Integer("2").equals(task.getStatus()) ? "已审批" : "已废除", task.getStatus());
-							vo.setEVisaContent(taskParallel.getEVisaContent());
-							//获取主流程下所有相关的审批人
-							List<TaskParallel> linkList = this.taskParallelService.list(Wrappers.<TaskParallel>lambdaQuery().eq(TaskParallel::getProcessInstanceId, task.getProcessInstanceId()).eq(TaskParallel::getIsDeleted, 0));
-							if(linkList != null && linkList.size() > 0){
-								this.integrationMethod(vo, linkList);
-							}
-
-							//设置最终集合
-							finalResult.add(vo);
-						}
-					}
-				});
+    private final ITaskService taskService;
+
+    private final ITaskParallelService taskParallelService;
+
+    private final NewFlowClient newFlowClient;
+
+    private final IDictBizClient dictBizClient;
+
+    private final NewISmsClient newSmsClient;
+
+    private final IDefaultConfigService defaultConfigService;
+
+    private final ITaskBatchService taskBatchService;
+
+    private final ITaskService iTaskService;
+
+    private final WebSocket webSocket;
+
+    private final CommonFileClient commonFileClient;
+
+    private final ContractClient contractClient;
+
+    /**
+     * 记录短信验证码超时时间
+     */
+    @GetMapping("/save-sms-timeout")
+    @ApiOperationSupport(order = 13)
+    @ApiOperation(value = "记录短信验证码超时时间")
+    public void saveSmsTimeout(@RequestParam String code) {
+        //获取账户记录
+        DefaultConfig config = this.defaultConfigService.getOne(Wrappers.<DefaultConfig>lambdaQuery().eq(DefaultConfig::getCreateUser, AuthUtil.getUserId()));
+        if (config != null) {
+            //获取当前时间
+            Date now = DateUtil.now();
+            //默认16小时后超时
+            now = DateUtil.plusHours(now, 16);
+
+            LambdaUpdateWrapper<DefaultConfig> wrapper = new LambdaUpdateWrapper<>();
+            wrapper.set(DefaultConfig::getSmsTimeOut, DateUtil.format(now, "yyyy-MM-dd HH:mm:ss"));
+            if (!StringUtils.equals(config.getSmsCode(), code)) {
+                wrapper.set(DefaultConfig::getSmsCode, code);
+            }
+            //生成超时时间
+            this.defaultConfigService.update(wrapper.eq(DefaultConfig::getCreateUser, AuthUtil.getUserId()));
+        }
+    }
+
+    /**
+     * 校验电签短信验证码
+     */
+    @PostMapping("/check-sms-code")
+    @ApiOperationSupport(order = 12)
+    @ApiOperation(value = "校验电签短信验证码")
+    public R<String> checkSmsCode() {
+        //获取账户验证码
+        DefaultConfig config = this.defaultConfigService.getOne(Wrappers.<DefaultConfig>lambdaQuery().eq(DefaultConfig::getCreateUser, AuthUtil.getUserId()));
+
+        if (config != null) {
+            if (StringUtils.isNotEmpty(config.getSmsTimeOut())) {
+                //获取当前时间
+                Date now = DateUtil.now();
+                //先自行校验是否超时
+                Duration duration = DateUtil.between(DateUtil.parse(config.getSmsTimeOut(), "yyyy-MM-dd HH:mm:ss"), now);
+                if (duration.getSeconds() > 0) {
+                    //说明已经超时,清空短信验证记录
+                    this.defaultConfigService.update(Wrappers.<DefaultConfig>lambdaUpdate().set(DefaultConfig::getSmsTimeOut, null).set(DefaultConfig::getSmsCode, null).eq(DefaultConfig::getId, config.getId()));
+                }
+            }
+            return R.data(config.getSmsTimeOut());
+        }
+
+        return R.data(null);
+    }
+
+    /**
+     * 批量审批详情
+     */
+    @GetMapping("/batch-approval-parameter")
+    @ApiOperationSupport(order = 11)
+    @ApiOperation(value = "批量页详情")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "formDataId", value = "数据源", required = true),
+            @ApiImplicitParam(name = "approvalType", value = "上报类型", required = true)
+    })
+    public R<List<TaskApprovalVO>> getBatchApprovalTaskParameter(@RequestParam String formDataId, @RequestParam Integer approvalType) {
+        List<String> longs = Func.toStrList(formDataId);
+        List<TaskApprovalVO> taskApprovalVOList = new ArrayList<>();
+        for (String aLong : longs) {
+            TaskApprovalVO result = new TaskApprovalVO();
+            result.setFormDataId(aLong);
+            result.setApprovalType(approvalType);
+            taskApprovalVOList.add(this.taskService.queryBusinessData(result));
+        }
+        return R.data(taskApprovalVOList);
+    }
+
+    /**
+     * 短信验证
+     */
+    @PostMapping("/send-notice")
+    @ApiOperationSupport(order = 10)
+    @ApiOperation(value = "短信验证")
+    public R<Boolean> sendNotice(@RequestParam String phone) {
+        String code = CommonUtil.getCharAndNumber(4);
+        Map<String, String> params = new HashMap<>(3);
+        params.put("code", code);
+        R<SmsResponse> result = this.newSmsClient.sendMessage("test_code", JsonUtil.toJson(params), phone);
+        if (result.getData().isSuccess()) {
+            //记录当前验证码
+            DefaultConfig config = this.defaultConfigService.getOne(Wrappers.<DefaultConfig>lambdaQuery().eq(DefaultConfig::getCreateUser, AuthUtil.getUserId()));
+            if (config != null) {
+                //修改
+                config.setSmsCode(code);
+                this.defaultConfigService.updateById(config);
+            } else {
+                //新增
+                config = new DefaultConfig();
+                config.setSmsCode(code);
+                config.setCreateUser(AuthUtil.getUserId());
+                config.setCreateTime(new Date());
+                this.defaultConfigService.save(config);
+            }
+        }
+        return result.getData().isSuccess() ? R.data(200, true, code) : R.data(499, false, String.valueOf(JSONObject.parseObject(result.getData().getMsg(), Map.class).get("Message")));
+    }
+
+    /**
+     * 获取发起
+     */
+    @GetMapping("/query-user-start-flow")
+    @ApiOperationSupport(order = 9)
+    @ApiOperation(value = "获取发起")
+    public R<IPage<TaskVO>> queryUserStartFlow(TaskQueryVO queryVO) {
+        //获取发起,只需要查询主表
+        //先查询符合条件的流程
+        LambdaQueryWrapper<Task> wrapper = Wrappers.<Task>lambdaQuery().eq(Task::getProjectId, queryVO.getProjectId()).eq(Task::getReportUser, AuthUtil.getUserId().toString());
+        //设置查询参数
+        this.integrationMethod(wrapper, queryVO);
+        //获取主流程
+        List<Task> masterTaskList = this.taskService.list(wrapper);
+        if (masterTaskList != null && masterTaskList.size() > 0) {
+            //获取集合
+            List<String> processInstanceIds = masterTaskList.stream().map(Task::getProcessInstanceId).distinct().collect(Collectors.toList());
+            //设置主表map,方便获取
+            Map<String, Task> masterTaskMap = new HashMap<>();
+            masterTaskList.forEach(task -> masterTaskMap.put(task.getProcessInstanceId(), task));
+
+            R<Object> rObject = this.newFlowClient.selectSendPage(queryVO.getCurrent(), queryVO.getSize(), queryVO.getOrdType() == null ? 1 : queryVO.getOrdType(), String.join(",", processInstanceIds));
+            if (rObject.isSuccess()) {
+                Query query = new Query();
+                query.setCurrent(queryVO.getCurrent());
+                query.setSize(queryVO.getSize());
+                //新建一个IPage的实例
+                IPage<BladeFlow> newData = Condition.getPage(query);
+                //使用实例获取具体的类型进行转换
+                IPage flowIPage = JSONObject.parseObject(JSONObject.toJSONString(rObject.getData()), newData.getClass());
+                //本质上这里获取到的集合属于List<JSONObject>,所以需要在这进行一次类型转换,将JSONObject转为BladeFlow
+                List<BladeFlow> result = JSONArray.parseArray(JSONObject.toJSONString(flowIPage.getRecords()), BladeFlow.class);
+
+                //最终结果集合
+                List<TaskVO> finalResult = new ArrayList<>();
+                for (BladeFlow flow : result) {
+                    //获取实体
+                    Task task = masterTaskMap.get(flow.getProcessInstanceId());
+                    //类型转换
+                    TaskVO vo = new TaskVO();
+                    BeanUtils.copyProperties(task, vo);
+                    //设置关键信息
+                    vo.setTypeValue(new Integer("1").equals(vo.getType()) ? "普通任务" : new Integer("2").equals(vo.getType()) ? "验收任务" : "移交任务");
+                    vo.setTaskId(flow.getTaskId());
+                    vo.setTaskStatus(new Integer("1").equals(task.getStatus()) ? "待审批" : new Integer("2").equals(task.getStatus()) ? "已审批" : "已废除", task.getStatus());
+                    //查询分支流程信息
+                    List<TaskParallel> linkList = this.taskParallelService.list(Wrappers.<TaskParallel>lambdaQuery().eq(TaskParallel::getProcessInstanceId, task.getProcessInstanceId()));
+                    if (linkList != null && !linkList.isEmpty()) {
+                        this.integrationMethod(vo, linkList);
+                    }
+                    finalResult.add(vo);
+                }
+
+                // 手机app 需要排序接口
+                if (queryVO.getOrdType() != null && queryVO.getOrdType() == 1) { // 降序
+                    finalResult.sort(Comparator.comparing(TaskVO::getCreateTime).reversed());
+                }
+                if (queryVO.getOrdType() != null && queryVO.getOrdType() == 2) { // 升序
+                    finalResult.sort(Comparator.comparing(TaskVO::getCreateTime));
+                }
+
+                //最终分页数据
+                return this.getIPageR(query, flowIPage, finalResult);
+            }
+        }
+
+        return R.data(null);
+    }
+
+    /**
+     * 统合方法
+     */
+    private void integrationMethod(TaskVO vo, List<TaskParallel> linkList) {
+        linkList.forEach(link -> vo.setWaitingUserList(link.getTaskUserName(), new Integer("999").equals(link.getEVisaStatus()) ? 999 : new Integer("2").equals(link.getStatus()) ? 2 : new Integer("3").equals(link.getStatus()) && new Integer("1").equals(link.getInitiative()) ? 3 : 1));
+    }
+
+    /**
+     * 批量审批
+     */
+    @PostMapping("/batch-complete-approval-task")
+    @ApiOperationSupport(order = 8)
+    @ApiOperation(value = "批量审批")
+    public R<Boolean> batchCompleteApprovalTask(@RequestBody BatchTaskVO batchTaskVO) throws IOException {
+        String taskIds = batchTaskVO.getTaskIds();
+        String parallelProcessInstanceIds = batchTaskVO.getParallelProcessInstanceIds();
+        if (StringUtils.isNotEmpty(taskIds)) {
+            String[] taskIdArray = taskIds.split(",");
+            String[] parallelProcessInstanceIdArray = parallelProcessInstanceIds.split(",");
+            String[] approvalType = batchTaskVO.getApprovalType().split(",");
+            String[] formDataId = batchTaskVO.getFormDataId().split(",");
+
+            List<TaskApprovalVO> taskApprovalVOS = new ArrayList<>();
+
+            for (int i = 0, l = taskIdArray.length; i < l; i++) {
+                TaskApprovalVO approvalVO = new TaskApprovalVO();
+                approvalVO.setTaskId(taskIdArray[i]);
+                approvalVO.setParallelProcessInstanceId(parallelProcessInstanceIdArray[i]);
+                approvalVO.setFlag(batchTaskVO.getFlag());
+                approvalVO.setComment(batchTaskVO.getComment());
+                approvalVO.setApprovalType(Integer.parseInt(approvalType[i]));
+                approvalVO.setFormDataId(formDataId[i]);
+
+                taskApprovalVOS.add(approvalVO);
+            }
+
+            //审批
+            this.taskService.batchCompleteApprovalTask(taskApprovalVOS, AuthUtil.getUserId());
+
+            //通过WebSocket推送数量条数
+            if (ObjectUtil.isNotEmpty(AuthUtil.getUserId())) {
+                Map<String, String> webSocketMessageMap = WebSocket.getWebSocketMessageMap();
+                Set<Map.Entry<String, String>> message = webSocketMessageMap.entrySet();
+                for (Map.Entry<String, String> entry : message) {
+                    String userId = entry.getKey();
+                    if (userId.equals(AuthUtil.getUserId().toString())) { //只推送当前用户
+                        String projectAndContractId = entry.getValue();
+                        if (StringUtils.isNotEmpty(projectAndContractId) && StringUtils.isNotEmpty(userId)) {
+                            String projectId = projectAndContractId.split(",")[0];
+                            String contractId = projectAndContractId.split(",")[1];
+                            Map<String, String> stringMap = iTaskService.getTaskCount(projectId, contractId, userId);
+
+                            webSocket.sendMessageByUserId(AuthUtil.getUserId().toString(), JSON.toJSONString(stringMap));
+                        }
+                    }
+                }
+            }
+
+            return R.data(true);
+        }
+        return R.data(false);
+    }
+
+    /**
+     * 获取当前合同段的上报批次
+     *
+     * @param projectId  项目ID
+     * @param contractId 合同段ID
+     */
+    @GetMapping("/query-batch-list")
+    @ApiOperationSupport(order = 7)
+    @ApiOperation(value = "获取当前合同段的上报批次")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "projectId", value = "项目ID", required = true),
+            @ApiImplicitParam(name = "contractId", value = "合同段ID", required = true)
+    })
+    public R<List<Task>> queryBatchList(String projectId, String contractId) {
+        return R.data(this.taskService.queryBatchList(projectId, contractId));
+    }
+
+    /**
+     * 获取当前合同段有哪些上报批次
+     *
+     * @param projectId  项目ID
+     * @param contractId 合同段ID
+     */
+    @GetMapping("/query-batch-list-two")
+    @ApiOperationSupport(order = 7)
+    @ApiOperation(value = "获取当前合同段的上报批次")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "projectId", value = "项目ID", required = true),
+            @ApiImplicitParam(name = "contractId", value = "合同段ID", required = true)
+    })
+    public R<List<String>> queryBatchListTwo(String projectId, String contractId, String type) {
+        if (StringUtils.isBlank(type)) {
+            //为空,以information为主表查询填报资料批次
+            return R.data(this.taskService.queryBatchListTwo(projectId, contractId));
+        } else {
+            //如果type为1内页台账不需要去查询首件批次,type为2只查标记为首件的,type为3只查首件
+            return R.data(this.taskService.queryBatchListThree(projectId, contractId, type));
+        }
+    }
+
+
+    /**
+     * 获取任务类型或任务状态
+     */
+    @GetMapping("/query-task-type-status")
+    @ApiOperationSupport(order = 6)
+    @ApiOperation(value = "获取任务类型或任务状态")
+    public R<List<DictBiz>> queryTaskTypeOrStatus(String typeOrStatus) {
+        return this.dictBizClient.getList(typeOrStatus, "notRoot");
+    }
+
+    /**
+     * 获取已办
+     */
+    @GetMapping("/query-user-done-task-list")
+    @ApiOperationSupport(order = 5)
+    @ApiOperation(value = "获取已办")
+    public R<IPage<TaskVO>> queryUserDoneTaskList(TaskQueryVO queryVO) {
+        //设置获取参数
+        Map<String, Task> masterTaskMap = new HashMap<>();
+        Map<String, TaskParallel> parallelMap = new HashMap<>();
+        List<String> parallelProcessInstanceIds = new ArrayList<>();
+        //统合查询方法
+        this.integrationMethod(queryVO, masterTaskMap, parallelMap, parallelProcessInstanceIds, "2,3");
+
+        //获取已办(基于原生已办)
+        R<Object> rObject = this.newFlowClient.selectDonePage(queryVO.getCurrent(), queryVO.getSize(), queryVO.getOrdType() == null ? 1 : queryVO.getOrdType(), String.join(",", parallelProcessInstanceIds));
+        //处理参数
+        return this.integrationMethod(queryVO, rObject, masterTaskMap, parallelMap, false);
+    }
+
+    /**
+     * 审批页详情
+     */
+    @GetMapping("/query-approval-parameter")
+    @ApiOperationSupport(order = 4)
+    @ApiOperation(value = "审批页详情(单任务时)")
+    public R<TaskApprovalVO> getApprovalTaskParameter(@RequestParam String parallelProcessInstanceId, @RequestParam String formDataId, @RequestParam Integer approvalType) {
+        TaskApprovalVO vo = new TaskApprovalVO();
+        vo.setFormDataId(formDataId);
+        vo.setApprovalType(approvalType);
+        //获取具体业务数据
+        return R.data(this.taskService.queryBusinessData(vo));
+    }
+
+    /**
+     * 审批页pdf数量详情
+     */
+    @GetMapping("/query-approval-parameter-pdf-num")
+    @ApiOperationSupport(order = 14)
+    @ApiOperation(value = "审批页pdf数量详情")
+    public R<Object> getApprovalTaskParameterPdfNum(@RequestParam String url) {
+        String pdfNum = this.commonFileClient.getPdfNum(url);
+        return R.data(pdfNum);
+    }
+
+    /**
+     * 获取当前用户待办流程
+     */
+    @GetMapping("/user-to-do-task-list")
+    @ApiOperationSupport(order = 3)
+    @ApiOperation(value = "获取当前用户待办流程")
+    public R<IPage<TaskVO>> todoUserApprovalTask(TaskQueryVO queryVO) {
+        //设置获取参数
+        Map<String, Task> masterTaskMap = new HashMap<>();
+        Map<String, TaskParallel> parallelMap = new HashMap<>();
+        List<String> parallelProcessInstanceIds = new ArrayList<>();
+        //统合查询方法
+        this.integrationMethod(queryVO, masterTaskMap, parallelMap, parallelProcessInstanceIds, "1");
+        if (masterTaskMap.size() == 0) {
+            return R.data(null);
+        }
+        //获取待办(基于原生待办)
+        R<Object> rObject = this.newFlowClient.selectTodoPage(queryVO.getCurrent(), queryVO.getSize(), queryVO.getOrdType() == null ? 1 : queryVO.getOrdType(), String.join(",", parallelProcessInstanceIds));
+        //处理参数
+        return this.integrationMethod(queryVO, rObject, masterTaskMap, parallelMap, true);
+    }
+
+    /**
+     * 统合查询方法
+     */
+    private void integrationMethod(TaskQueryVO queryVO, Map<String, Task> masterTaskMap, Map<String, TaskParallel> parallelMap, List<String> parallelProcessInstanceIds, String status) {
+        //先查询符合条件的流程
+        LambdaQueryWrapper<Task> wrapper = Wrappers.<Task>lambdaQuery().eq(Task::getIsDeleted, 0)
+                .eq(Task::getProjectId, queryVO.getProjectId()).eq(StringUtils.isNotBlank(queryVO.getBatch()), Task::getBatch, queryVO.getBatch());
+        this.integrationMethod(wrapper, queryVO);
+
+        //符合条件的集合
+        List<Task> masterTaskList = this.taskService.list(wrapper);
+        //根据主表获取附表且当前用户的记录
+        List<String> processInstanceIds = new ArrayList<>();
+        masterTaskList.forEach(task -> {
+            masterTaskMap.put(task.getProcessInstanceId(), task);
+            processInstanceIds.add(task.getProcessInstanceId());
+        });
+
+        if (processInstanceIds.size() > 0) {
+            List<TaskParallel> parallelTaskList = this.taskParallelService.list(Wrappers.<TaskParallel>lambdaQuery().in(TaskParallel::getProcessInstanceId, processInstanceIds).eq(TaskParallel::getTaskUser, AuthUtil.getUserId().toString()).eq(TaskParallel::getIsDeleted, 0).in(TaskParallel::getStatus, Arrays.asList(status.split(","))));
+            parallelTaskList.forEach(parallel -> {
+                parallelMap.put(parallel.getParallelProcessInstanceId(), parallel);
+                parallelProcessInstanceIds.add(parallel.getParallelProcessInstanceId());
+            });
+        }
+    }
+
+    private void integrationMethod(LambdaQueryWrapper<Task> wrapper, TaskQueryVO queryVO) {
+        //任务类型
+        if (StringUtils.isNotEmpty(queryVO.getTaskType())) {
+            wrapper.eq(Task::getType, queryVO.getTaskType());
+        }
+        //任务状态
+        if (StringUtils.isNotEmpty(queryVO.getTaskStatus())) {
+            wrapper.eq(Task::getStatus, queryVO.getTaskStatus());
+        }
+        //合同段ID
+        if (StringUtils.isNotEmpty(queryVO.getContractId())) {
+            ContractInfo contractInfo = contractClient.getContractById(Long.valueOf(queryVO.getContractId()));
+            if (contractInfo.getContractType() == 2) {
+                wrapper.eq(Task::getProjectId, queryVO.getProjectId());
+            } else {
+                wrapper.eq(Task::getContractId, queryVO.getContractId());
+            }
+        }
+        //开始结束时间
+        if (StringUtils.isNotEmpty(queryVO.getStartTime()) && StringUtils.isNotEmpty(queryVO.getEndTime())) {
+            wrapper.between(Task::getStartTime, queryVO.getStartTime(), queryVO.getEndTime());
+        }
+        //关键字查询
+        if (StringUtils.isNotEmpty(queryVO.getQueryValue())) {
+            wrapper.like(Task::getTaskName, queryVO.getQueryValue());
+        }
+    }
+
+    /**
+     * 统合处理方法
+     */
+    private R<IPage<TaskVO>> integrationMethod(TaskQueryVO queryVO, R<Object> rObject, Map<String, Task> masterTaskMap, Map<String, TaskParallel> parallelMap, boolean isToDo) {
+        Query query = new Query();
+        query.setCurrent(queryVO.getCurrent());
+        query.setSize(queryVO.getSize());
+        //最终集合
+        List<TaskVO> finalResult = new ArrayList<>();
+        if (rObject.isSuccess()) {
+            //新建一个IPage的实例
+            IPage<BladeFlow> newData = Condition.getPage(query);
+            //使用实例获取具体的类型进行转换
+            IPage flowIPage = JSONObject.parseObject(JSONObject.toJSONString(rObject.getData()), newData.getClass());
+            //本质上这里获取到的集合属于List<JSONObject>,所以需要在这进行一次类型转换,将JSONObject转为BladeFlow
+            List<BladeFlow> result = JSONArray.parseArray(JSONObject.toJSONString(flowIPage.getRecords()), BladeFlow.class);
+
+            if (result != null && result.size() > 0) {
+                //获取相关信息
+                result.forEach(flow -> {
+                    TaskParallel taskParallel = parallelMap.get(flow.getProcessInstanceId());
+                    if (taskParallel != null) {
+                        //查询主表数据
+                        Task task = masterTaskMap.get(taskParallel.getProcessInstanceId());
+
+                        if (task != null) {
+                            //复制数据
+                            TaskVO vo = new TaskVO();
+                            BeanUtils.copyProperties(task, vo);
+                            //设置关键信息
+                            vo.setTypeValue(new Integer("1").equals(vo.getType()) ? "普通任务" : new Integer("2").equals(vo.getType()) ? "验收任务" : "移交任务");
+                            vo.setParallelProcessInstanceId(flow.getProcessInstanceId());
+                            vo.setTaskId(flow.getTaskId());
+                            vo.setTaskStatus(new Integer("1").equals(task.getStatus()) ? "待审批" : new Integer("2").equals(task.getStatus()) ? "已审批" : "已废除", task.getStatus());
+                            vo.setEVisaContent(taskParallel.getEVisaContent());
+                            //获取主流程下所有相关的审批人
+                            List<TaskParallel> linkList = this.taskParallelService.list(Wrappers.<TaskParallel>lambdaQuery().eq(TaskParallel::getProcessInstanceId, task.getProcessInstanceId()).eq(TaskParallel::getIsDeleted, 0));
+                            if (linkList != null && linkList.size() > 0) {
+                                this.integrationMethod(vo, linkList);
+                            }
+
+                            //设置最终集合
+                            finalResult.add(vo);
+                        }
+                    }
+                });
 
 //				//待办的原生方法并没有对数据做分页,所以需要在这里进行手动分页,而已办的原生方法已经做了分页处理
 //				if(!isToDo){
@@ -539,76 +554,70 @@ public class TaskController extends BladeController {
 //					//最终分页数据
 //					return this.getIPageR(query, flowIPage, finalFlowList);
 //				} else {
-					//最终分页数据
-					return this.getIPageR(query, flowIPage, finalResult);
+                //最终分页数据
+                return this.getIPageR(query, flowIPage, finalResult);
 //				}
-			}
-		}
-		return R.data(null);
-	}
-
-	@NotNull
-	private R<IPage<TaskVO>> getIPageR(Query query, IPage flowIPage, List<TaskVO> finalFlowList) {
-		IPage<TaskVO> finalPage = Condition.getPage(query);
-		finalPage.setTotal(flowIPage.getTotal());
-		finalPage.setSize(query.getSize());
-		finalPage.setCurrent(query.getCurrent());
-		finalPage.setRecords(finalFlowList);
-
-		return R.data(finalPage);
-	}
-
-	/**
-	 * 完成/审批任务
-	 */
-	@PostMapping("/complete-approval-task")
-	@ApiOperationSupport(order = 2)
-	@ApiOperation(value = "完成/审批任务")
-	public R<Boolean> completeApprovalTask(@RequestBody TaskApprovalVO taskApprovalVO) throws FileNotFoundException {
-		//检查当前用户是否存在等待批次
-		//System.out.println(AuthUtil.getUserId());
-		long batchCount = this.taskBatchService.count(Wrappers.<TaskBatch>lambdaQuery().eq(TaskBatch::getCreateUser, AuthUtil.getUserId()));
-
-		if(batchCount > 0){
-			this.taskParallelService.update(Wrappers.<TaskParallel>lambdaUpdate()
-					.set(TaskParallel::getEVisaContent, "当前等待电签的批次较多,请等待几分钟后刷新页面查看........")
-					.eq(TaskParallel::getParallelProcessInstanceId, taskApprovalVO.getParallelProcessInstanceId()));
-
-			//生成等待批次,任务完成后删除
-			List<TaskApprovalVO> taskApprovalVOS = new ArrayList<>();
-			taskApprovalVOS.add(taskApprovalVO);
-
-			//存在批次,当前审批的追加进队列
-			TaskBatch taskBatch = new TaskBatch(taskApprovalVO.getParallelProcessInstanceId(), JSONObject.toJSONString(taskApprovalVOS));
-			taskBatch.setCreateUser(AuthUtil.getUserId());
-			taskBatch.setCreateTime(new Date());
-			this.taskBatchService.save(taskBatch);
-
-			//修改试验填报状态
-			this.iTrialSelfInspectionRecordService.updateTrialSelfInspectionRecordStatus(taskApprovalVOS);
-
-			return R.data(true, "当前等待电签的批次较多,请等待几分钟后刷新页面查看........");
-		} else {
-			//生成等待批次,任务完成后删除
-			List<TaskApprovalVO> taskApprovalVOS = new ArrayList<>();
-			taskApprovalVOS.add(taskApprovalVO);
-			this.taskService.batchCompleteApprovalTask(taskApprovalVOS,AuthUtil.getUserId());
-
-			//修改试验填报状态
-			this.iTrialSelfInspectionRecordService.updateTrialSelfInspectionRecordStatus(taskApprovalVOS);
-
-			return R.data(true, "提交成功");
-		}
-	}
-
-	/**
-	 * 上报
-	 */
-	@PostMapping("/start-approval")
-	@ApiOperationSupport(order = 1)
-	@ApiOperation(value = "上报", notes = "taskVO对象")
-	public R<Boolean> startApproval(@RequestBody TaskVO taskVO){
-		return this.taskService.startApproval(taskVO) ? R.data(200, true, "操作成功") : R.data(200, false, "操作失败,请联系管理员");
-	}
+            }
+        }
+        return R.data(null);
+    }
+
+    @NotNull
+    private R<IPage<TaskVO>> getIPageR(Query query, IPage flowIPage, List<TaskVO> finalFlowList) {
+        IPage<TaskVO> finalPage = Condition.getPage(query);
+        finalPage.setTotal(flowIPage.getTotal());
+        finalPage.setSize(query.getSize());
+        finalPage.setCurrent(query.getCurrent());
+        finalPage.setRecords(finalFlowList);
+
+        return R.data(finalPage);
+    }
+
+    /**
+     * 完成/审批任务
+     */
+    @PostMapping("/complete-approval-task")
+    @ApiOperationSupport(order = 2)
+    @ApiOperation(value = "完成/审批任务")
+    public R<Boolean> completeApprovalTask(@RequestBody TaskApprovalVO taskApprovalVO) throws FileNotFoundException {
+        //检查当前用户是否存在等待批次
+        //System.out.println(AuthUtil.getUserId());
+        long batchCount = this.taskBatchService.count(Wrappers.<TaskBatch>lambdaQuery().eq(TaskBatch::getCreateUser, AuthUtil.getUserId()));
+
+        if (batchCount > 0) {
+            this.taskParallelService.update(Wrappers.<TaskParallel>lambdaUpdate()
+                    .set(TaskParallel::getEVisaContent, "当前等待电签的批次较多,请等待几分钟后刷新页面查看........")
+                    .eq(TaskParallel::getParallelProcessInstanceId, taskApprovalVO.getParallelProcessInstanceId()));
+
+            //生成等待批次,任务完成后删除
+            List<TaskApprovalVO> taskApprovalVOS = new ArrayList<>();
+            taskApprovalVOS.add(taskApprovalVO);
+
+            //存在批次,当前审批的追加进队列
+            TaskBatch taskBatch = new TaskBatch(taskApprovalVO.getParallelProcessInstanceId(), JSONObject.toJSONString(taskApprovalVOS));
+            taskBatch.setCreateUser(AuthUtil.getUserId());
+            taskBatch.setCreateTime(new Date());
+            this.taskBatchService.save(taskBatch);
+
+            return R.data(true, "当前等待电签的批次较多,请等待几分钟后刷新页面查看........");
+        } else {
+            //生成等待批次,任务完成后删除
+            List<TaskApprovalVO> taskApprovalVOS = new ArrayList<>();
+            taskApprovalVOS.add(taskApprovalVO);
+            this.taskService.batchCompleteApprovalTask(taskApprovalVOS, AuthUtil.getUserId());
+
+            return R.data(true, "提交成功");
+        }
+    }
+
+    /**
+     * 上报
+     */
+    @PostMapping("/start-approval")
+    @ApiOperationSupport(order = 1)
+    @ApiOperation(value = "上报", notes = "taskVO对象")
+    public R<Boolean> startApproval(@RequestBody TaskVO taskVO) {
+        return this.taskService.startApproval(taskVO) ? R.data(200, true, "操作成功") : R.data(200, false, "操作失败,请联系管理员");
+    }
 
 }

+ 97 - 27
blade-service/blade-business/src/main/java/org/springblade/business/controller/TrialDetectionController.java

@@ -1,6 +1,8 @@
 package org.springblade.business.controller;
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiImplicitParam;
@@ -8,35 +10,43 @@ import io.swagger.annotations.ApiImplicitParams;
 import io.swagger.annotations.ApiOperation;
 import lombok.AllArgsConstructor;
 import lombok.SneakyThrows;
-import org.apache.commons.lang.StringUtils;
 import org.springblade.business.dto.*;
-import org.springblade.business.entity.InformationQuery;
 import org.springblade.business.entity.TrialDetectionData;
+import org.springblade.business.entity.TrialSelfInspectionRecord;
 import org.springblade.business.service.ITrialDetectionDataService;
 import org.springblade.business.service.ITrialSampleInfoService;
 import org.springblade.business.service.ITrialSelfInspectionRecordService;
+import org.springblade.business.utils.FileUtils;
 import org.springblade.business.vo.*;
+import org.springblade.common.constant.CommonConstant;
+import org.springblade.common.utils.SnowFlakeUtil;
 import org.springblade.core.boot.ctrl.BladeController;
 import org.springblade.core.mp.support.Condition;
 import org.springblade.core.mp.support.Query;
+import org.springblade.core.oss.model.BladeFile;
 import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.utils.Func;
-import org.springblade.core.tool.utils.ObjectUtil;
-import org.springblade.manager.entity.TableFile;
+import org.springblade.core.tool.utils.ResourceUtil;
 import org.springblade.manager.entity.TrialSelfDataRecord;
 import org.springblade.manager.entity.WbsTreePrivate;
 import org.springblade.manager.feign.WbsTreePrivateClient;
 import org.springblade.manager.vo.TableFileVO;
 import org.springblade.manager.vo.WbsTreePrivateVO;
+import org.springblade.resource.feign.NewIOSSClient;
+import org.springblade.system.cache.ParamCache;
 import org.springframework.jdbc.core.BeanPropertyRowMapper;
 import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
 
 import javax.validation.Valid;
+import java.io.File;
 import java.io.FileNotFoundException;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collectors;
 
 
 @RestController
@@ -50,6 +60,7 @@ public class TrialDetectionController extends BladeController {
     private final ITrialSelfInspectionRecordService iTrialSelfInspectionRecordService;
     private final WbsTreePrivateClient wbsTreePrivateClient;
     private final JdbcTemplate jdbcTemplate;
+    private final NewIOSSClient newIOSSClient;
 
     @GetMapping("/data/detail")
     @ApiOperationSupport(order = 1)
@@ -89,7 +100,7 @@ public class TrialDetectionController extends BladeController {
     @PostMapping("/self/page")
     @ApiOperationSupport(order = 6)
     @ApiOperation(value = "自检记录分页查询", notes = "传入TrialSelfInspectionRecordPageDTO")
-    public R<IPage<TrialSelfInspectionRecordVO>> selfPage(@RequestBody Query query, @RequestBody TrialSelfInspectionRecordPageDTO dto) {
+    public R<IPage<TrialSelfInspectionRecordVO>> selfPage(@RequestBody Query query, @RequestBody TrialSelfInspectionRecordPageDTO dto) throws FileNotFoundException {
         return R.data(iTrialSelfInspectionRecordService.selfPage(Condition.getPage(query), dto));
     }
 
@@ -139,21 +150,62 @@ public class TrialDetectionController extends BladeController {
     @ApiOperationSupport(order = 13)
     @ApiOperation(value = "自检记录批量删除", notes = "传入ids,字符串逗号分隔")
     public R<Object> selfRemove(@Valid @RequestParam String ids) {
-        return R.status(iTrialSelfInspectionRecordService.deleteLogic(Func.toLongList(ids)));
+        List<TrialSelfInspectionRecord> recordList = iTrialSelfInspectionRecordService.getBaseMapper().selectList(Wrappers.<TrialSelfInspectionRecord>lambdaQuery()
+                .select(TrialSelfInspectionRecord::getTaskStatus)
+                .ne(TrialSelfInspectionRecord::getTaskStatus, "未上报")
+                .in(TrialSelfInspectionRecord::getId, Func.toLongList(ids)));
+        if (recordList.size() > 0) {
+            return R.fail("只能删除未上报记录信息,操作失败");
+        }
+        //刪除按钮状态记录
+        String sql1 = "delete from u_trial_self_data_record where record_id in(" + ids + ")";
+        jdbcTemplate.execute(sql1);
+
+        //删除样品关联记录
+        String sql2 = "delete from u_trial_self_sample where self_id in(" + ids + ")";
+        jdbcTemplate.execute(sql2);
+
+        //删除工程部位关联记录
+        String sql3 = "delete from u_trial_raw_material_self_record where self_record_id in(" + ids + ")";
+        jdbcTemplate.execute(sql3);
+
+        //删除原材料检测报告关联记录
+        String sql4 = "delete from u_trial_self_quality_project where self_id in(" + ids + ")";
+        jdbcTemplate.execute(sql4);
+
+        //删除试验记录
+        String sql5 = "delete from u_trial_self_inspection_record where id in(" + ids + ")";
+        jdbcTemplate.execute(sql5);
+        return R.status(true);
     }
 
     @GetMapping("/self/show-buss-tab")
     @ApiOperationSupport(order = 14)
-    @ApiOperation(value = "自检隐藏表单", notes = "传入节点pKeyId,状态status(1显示 2隐藏)")
-    public R<Object> showBussTab(@RequestParam Long pKeyId, @RequestParam Integer status) {
-        return R.status(wbsTreePrivateClient.showBussTab(pKeyId, status));
+    @ApiOperation(value = "自检隐藏表单", notes = "传入试验记录id,传入节点pKeyId,状态status(1显示 2隐藏)")
+    public R<Object> showBussTab(@RequestParam Long id, @RequestParam Long pKeyId, @RequestParam Integer status) {
+        if (ObjectUtils.isNotEmpty(id)) {
+            //编辑,修改试验记录与按钮关系信息
+            jdbcTemplate.execute("update u_trial_self_data_record set is_buss_show = " + status + " where record_id = " + id + " and tab_id = " + pKeyId);
+
+            //获取当前试验记录信息中表的按钮状态
+            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 + " and tab_id = " + pKeyId;
+            List<TrialSelfDataRecord> query = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(TrialSelfDataRecord.class));
+            if (query.size() == 0) {
+                //如果编辑时,该表单没有在新增时就关联按钮记录信息,那么就修改该表单在项目wbs节点按钮状态
+                jdbcTemplate.execute("update m_wbs_tree_private set is_buss_show = " + status + " where p_key_id = " + pKeyId);
+            }
+        } else {
+            //新增,修改项目wbs节点按钮状态(通用)
+            jdbcTemplate.execute("update m_wbs_tree_private set is_buss_show = " + status + " where p_key_id = " + pKeyId);
+        }
+        return R.status(true);
     }
 
     @GetMapping("/self/copy-buss-tab")
     @ApiOperationSupport(order = 15)
-    @ApiOperation(value = "自检表单复制", notes = "传入节点pKeyId")
-    public R<Object> copyBussTab(@RequestParam Long pKeyId) {
-        return R.status(wbsTreePrivateClient.copyBussTab(pKeyId));
+    @ApiOperation(value = "自检表单复制", notes = "传入节点pKeyId,当前记录id")
+    public R<Object> copyBussTab(@RequestParam Long pKeyId, @RequestParam Long id) {
+        return R.status(wbsTreePrivateClient.copyBussTab(pKeyId, id));
     }
 
     @PostMapping("/self/remove-buss-tabInfo")
@@ -170,7 +222,7 @@ public class TrialDetectionController extends BladeController {
         String sql = "select * from u_trial_self_data_record where record_id = " + id + " and tab_id = " + pKeyId;
         List<TrialSelfDataRecord> query = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(TrialSelfDataRecord.class));
         TrialSelfDataRecord obj = query.stream().findAny().orElse(null);
-        if (obj != null){
+        if (obj != null) {
             return R.data(obj.getPdfUrl());
         }
         return R.data("");
@@ -178,20 +230,47 @@ public class TrialDetectionController extends BladeController {
 
     @GetMapping("/get-buss-pdfs")
     @ApiOperationSupport(order = 18)
-    @ApiOperation(value = "自检多表PDF预览", notes = "传入nodeId、classify、contractId、projectId")
-    public R<Object> getPDFs(String nodeId, String classify, String contractId, String projectId) {
-        String sql = "select pdf_url, e_visa_pdf_url from u_information_query where project_id ='" + projectId + "' and classify='" + classify + "' and  wbs_id='" + nodeId + "' and contract_id ='" + contractId + "'";
+    @ApiOperation(value = "自检多表PDF预览", notes = "传入nodeId=试验记录id、classify、contractId、projectId")
+    public R<Object> getPDFs(String nodeId, String classify, String contractId, String projectId) throws FileNotFoundException {
+        String sql = "select pdf_url,e_visa_pdf_url from u_information_query where project_id ='" + projectId + "' and classify='" + classify + "' and  wbs_id='" + nodeId + "' and contract_id ='" + contractId + "'";
         List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql);
         if (maps.size() >= 1) {
             Map<String, Object> stringObjectMap = maps.get(0);
             Object pdfUrl = stringObjectMap.get("pdf_url");
             if (stringObjectMap.get("e_visa_pdf_url") != null) {
-                //优先使用电签的PDF
+                //优先使用电签的pdf
                 pdfUrl = stringObjectMap.get("e_visa_pdf_url");
             }
+
+            //关联原材料检测报告的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);
+            if (pdfUrl != null && recordObj != null && recordObj.getOldPdfUrl() != null) {
+                String pdfUrlTrialRawMaterial = recordObj.getOldPdfUrl();
+                List<String> pdfList = new ArrayList<>();
+                //试验原始pdf
+                pdfList.add(pdfUrl.toString());
+                //材料检测报告pdf
+                pdfList.add(pdfUrlTrialRawMaterial);
+                //合并
+                String file_path = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
+                Long id = SnowFlakeUtil.getId();
+                String trialPdf = file_path + "/pdf/" + id + ".pdf";
+                File trialPdf2 = ResourceUtil.getFile(trialPdf);
+                if (trialPdf2.exists()) {
+                    trialPdf2.delete();
+                }
+                //合并当前所有选择的试验pdf
+                FileUtils.mergePdfPublicMethods(pdfList, trialPdf);
+                BladeFile bladeFile = this.newIOSSClient.uploadFile(id + ".pdf", trialPdf);
+                if (bladeFile != null && ObjectUtils.isNotEmpty(bladeFile.getLink())) {
+                    pdfUrl = bladeFile.getLink();
+                }
+            }
+
             return R.data(pdfUrl);
         } else {
-            return R.fail("无历史数据预览,请保存数据");
+            return R.fail("无历史数据预览请保存数据");
         }
     }
 
@@ -268,15 +347,6 @@ public class TrialDetectionController extends BladeController {
         return R.fail(200, "未查询到数据");
     }
 
-    @PostMapping("/self/project-position/submit")
-    @ApiOperationSupport(order = 26)
-    @ApiOperation(value = "自检记录关联工程部位信息保存", notes = "传入SelfProjectPositionSubmitDTO")
-    public R<Object> recordProjectPosition(@Valid @RequestBody SelfProjectPositionSubmitDTO dto) throws FileNotFoundException {
-        //TODO 已剥离,融合到批量审批中
-        //return R.status(iTrialSelfInspectionRecordService.recordProjectPosition(dto));
-        return R.status(true);
-    }
-
     @PostMapping("/self/record-sample/submit")
     @ApiOperationSupport(order = 27)
     @ApiOperation(value = "自检记录关联取样信息保存", notes = "传入RecordSampleSubmitDTO")

+ 7 - 2
blade-service/blade-business/src/main/java/org/springblade/business/mapper/InformationQueryMapper.xml

@@ -49,6 +49,7 @@
         <result column="nodeType" property="nodeType"/>
         <result column="evaluate" property="evaluate"/>
         <result column="queryType" property="queryType"/>
+        <result column="isExperiment" property="isExperiment"/>
     </resultMap>
 
     <resultMap id="queryContractTreeMap" type="org.springblade.manager.vo.WbsTreeContractTreeVOS">
@@ -285,7 +286,9 @@
                 and tc.contract_id = wtc.contract_id
                 and NOT EXISTS (select 1 from u_information_query as q where iq.id = q.id and q.status > iq.status) LIMIT 1
             ) AS evaluate,
-            uiq.type AS queryType
+            uiq.type AS queryType,
+            case WHEN uiq.pdf_trial_url is null then 'false'
+                ELSE 'true' end AS isExperiment
         FROM
             m_wbs_tree_contract AS wtc
         LEFT JOIN u_information_query AS uiq ON wtc.p_key_id = uiq.wbs_id AND uiq.classify = #{classify} and uiq.is_deleted = 0
@@ -560,7 +563,9 @@
             wtc.parent_id AS parentId,
             uiq.id AS informationQueryId,
             IFNULL(uiq.status,0) AS status,
-            uiq.type AS queryType
+            uiq.type AS queryType,
+            case WHEN uiq.pdf_trial_url is null then 'false'
+                 ELSE 'true' end AS isExperiment
         FROM
             m_wbs_tree_contract AS wtc
             LEFT JOIN u_information_query AS uiq ON wtc.p_key_id = uiq.wbs_id AND uiq.classify = #{classify} and uiq.is_deleted = 0

+ 8 - 3
blade-service/blade-business/src/main/java/org/springblade/business/mapper/TrialSelfInspectionRecordMapper.java

@@ -2,6 +2,7 @@ package org.springblade.business.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
 import org.springblade.business.entity.TrialSelfInspectionRecord;
 import org.springblade.manager.entity.WbsTreeContract;
 
@@ -9,7 +10,7 @@ import java.util.List;
 
 public interface TrialSelfInspectionRecordMapper extends BaseMapper<TrialSelfInspectionRecord> {
 
-    List<TrialSelfInspectionRecord> selectAll(Long nodeId,Long contractId);
+    List<TrialSelfInspectionRecord> selectAll(Long nodeId, Long contractId);
 
     void saveSelfSample(Long id, Long selfId, String samplingId);
 
@@ -23,13 +24,13 @@ public interface TrialSelfInspectionRecordMapper extends BaseMapper<TrialSelfIns
 
     void delSelfQuality(Long id);
 
-    void saveSelfQuality(Long id, Long selfId, String qualityNodeId);
+    void saveSelfQuality(Long id, Long selfId, Long qualityNodeId);
 
     List<String> selectQualityNodeId(String id);
 
     String selectInformationQuery(String id, String contractId, String classify);
 
-    void updateInformationQuery(String id, String contractId, String classify, String link);
+    void updateInformationQuery(Long id, Long contractId,String link);
 
     void deleteSeletedStatusByNodeId(String nodeId, Integer type, String recordId);
 
@@ -40,4 +41,8 @@ public interface TrialSelfInspectionRecordMapper extends BaseMapper<TrialSelfIns
     List<String> selectSelectedStatusList(Long nodeId, String type);
 
     List<WbsTreeContract> selectWbsTreeContractListByPKeyIds(@Param("idList") List<String> ids);
+
+    @Select("select self_id from u_trial_self_quality_project where quality_node_id = #{pKeyId}")
+    List<String> selectTrialIdByNodeId(Long pKeyId);
+
 }

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

@@ -45,7 +45,7 @@
     </insert>
 
     <update id="updateInformationQuery">
-        update u_information_query set pdf_url = #{link} where wbs_id = #{id} and classify = #{classify} and contract_id = #{contractId} and is_deleted = 0
+        update u_information_query set pdf_trial_url_position = #{link} where wbs_id = #{id} and contract_id = #{contractId} and is_deleted = 0
     </update>
 
     <delete id="delSelfSample">

+ 5 - 7
blade-service/blade-business/src/main/java/org/springblade/business/service/ITrialSelfInspectionRecordService.java

@@ -13,7 +13,7 @@ import java.util.List;
 
 public interface ITrialSelfInspectionRecordService extends BaseService<TrialSelfInspectionRecord> {
 
-    IPage<TrialSelfInspectionRecordVO> selfPage(IPage<TrialSelfInspectionRecord> page, TrialSelfInspectionRecordPageDTO dto);
+    IPage<TrialSelfInspectionRecordVO> selfPage(IPage<TrialSelfInspectionRecord> page, TrialSelfInspectionRecordPageDTO dto) throws FileNotFoundException;
 
     String selfSubmit(TrialSelfInspectionRecordDTO dto) throws FileNotFoundException;
 
@@ -27,14 +27,15 @@ public interface ITrialSelfInspectionRecordService extends BaseService<TrialSelf
 
     List<TrialSelfInspectionRecordVO2> getRawMaterialInfo(String nodeId, String contractId, String id);
 
-    boolean rawMaterialSubmitRelation(RawMaterialSubmitRelationDTO dto) throws FileNotFoundException;
-
     String selfPrintPdf(String ids) throws FileNotFoundException;
 
     String selfPrintNullPdf(String ids) throws Exception;
 
     @Async
-    void updateTrialSelfInspectionRecordStatus(List<TaskApprovalVO> obj) throws FileNotFoundException;
+    void updateTrialSelfInspectionRecordStatus(String pdfUrlEVisa, TaskApprovalVO obj) throws FileNotFoundException;
+
+    @Async
+    void updateTrialSelfInspectionRecordStatusFC(TaskApprovalVO obj);
 
     String addBussFile(MultipartFile file, Long pkeyId, String nodeId, String contractId, String projectId, String classify, String id, String tableType) throws Exception;
 
@@ -42,8 +43,5 @@ public interface ITrialSelfInspectionRecordService extends BaseService<TrialSelf
 
     boolean fileSubmit(TrialFileSubmitDTO dto) throws FileNotFoundException;
 
-    boolean recordProjectPosition(SelfProjectPositionSubmitDTO dto) throws FileNotFoundException;
-
-    boolean recordSampleSubmit(RecordSampleSubmitDTO dto);
 
 }

+ 61 - 18
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TaskServiceImpl.java

@@ -13,10 +13,7 @@ import org.slf4j.LoggerFactory;
 import org.springblade.business.entity.*;
 import org.springblade.business.mapper.TaskMapper;
 import org.springblade.business.service.*;
-import org.springblade.business.vo.BusinessUserOpinionVO;
-import org.springblade.business.vo.MessageWarningVO;
-import org.springblade.business.vo.TaskApprovalVO;
-import org.springblade.business.vo.TaskVO;
+import org.springblade.business.vo.*;
 import org.springblade.common.utils.SnowFlakeUtil;
 import org.springblade.core.log.exception.ServiceException;
 import org.springblade.core.mp.base.BaseServiceImpl;
@@ -42,6 +39,8 @@ import org.springblade.manager.entity.ProjectInfo;
 import org.springblade.manager.feign.ContractClient;
 import org.springblade.manager.feign.ProjectClient;
 import org.springframework.beans.BeanUtils;
+import org.springframework.jdbc.core.BeanPropertyRowMapper;
+import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -92,6 +91,10 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
 
     private final UserOpinionServiceImpl userOpinionService;
 
+    private final JdbcTemplate jdbcTemplate;
+
+    private final ITrialSelfInspectionRecordService iTrialSelfInspectionRecordService;
+
     @Override
     public List<TaskParallel> queryApprovalUser(String formDataIds) {
         //返回结果
@@ -216,9 +219,34 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
                     }
                 }
 
-            } else {
+            } else if (new Integer("1").equals(query.getType())) {
+                //资料填报
+                if (StringUtils.isNotEmpty(query.getEVisaPdfUrl()) || StringUtils.isNotEmpty(query.getPdfUrl()) || StringUtils.isNotEmpty(query.getPdfTrialUrl()) || StringUtils.isNotEmpty(query.getPdfTrialUrlPosition())) {
+                    //资料填报原始pdf
+                    vo.setApprovalFileList(query.getName(), StringUtils.isNotEmpty(query.getEVisaPdfUrl()) ? query.getEVisaPdfUrl() : query.getPdfUrl());
+
+                    //试验关联文件合并pdf
+                    if (StringUtils.isNotEmpty(query.getPdfTrialUrl())) {
+                        vo.setApprovalFileList(query.getName() + "(关联试验文件)", StringUtils.isNotEmpty(query.getPdfTrialUrl()) ? query.getPdfTrialUrl() : null);
+                    }
+
+                    //试验关联的工程部位信息合并pdf
+                    if (StringUtils.isNotEmpty(query.getPdfTrialUrlPosition())) {
+                        vo.setApprovalFileList(query.getName() + "(关联试验工程部位信息文件)", StringUtils.isNotEmpty(query.getPdfTrialUrlPosition()) ? query.getPdfTrialUrlPosition() : null);
+                    }
+                }
+            } else if (new Integer("2").equals(query.getType())) {
+                //试验
                 if (StringUtils.isNotEmpty(query.getEVisaPdfUrl()) || StringUtils.isNotEmpty(query.getPdfUrl())) {
+                    //试验原始pdf
                     vo.setApprovalFileList(query.getName(), StringUtils.isNotEmpty(query.getEVisaPdfUrl()) ? query.getEVisaPdfUrl() : query.getPdfUrl());
+
+                    //试验关联的原材料检测报告合并pdf (wbsId=试验记录id)
+                    String sqlRecord = "select old_pdf_url from u_trial_raw_material_self_record where self_record_id =" + query.getWbsId();
+                    TrialRawMaterialSelfRecord recordObj = jdbcTemplate.query(sqlRecord, new BeanPropertyRowMapper<>(TrialRawMaterialSelfRecord.class)).stream().findAny().orElse(null);
+                    if (recordObj != null) {
+                        vo.setApprovalFileList(query.getName() + "(原材料检测报告)", StringUtils.isNotEmpty(recordObj.getOldPdfUrl()) ? recordObj.getOldPdfUrl() : null);
+                    }
                 }
             }
         }
@@ -351,21 +379,21 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
     }
 
     @Override
-    public List<String> queryBatchListThree(String projectId, String contractId,String type) {
-        if ("1".equals(type)){
+    public List<String> queryBatchListThree(String projectId, String contractId, String type) {
+        if ("1".equals(type)) {
             return baseMapper.queryBatchListThree(projectId, contractId);
-        }else if ("2".equals(type)){
+        } else if ("2".equals(type)) {
             return baseMapper.queryBatchListFlagFirst(projectId, contractId);
-        }else {
+        } else {
             return baseMapper.queryBatchListFirst(projectId, contractId);
         }
     }
 
     @Override
     public Map<String, String> queryContractAllBatch(String contract) {
-        Map<String,String> map = new HashMap<>();
-        baseMapper.queryContractAllBatch(contract).stream().forEach(task->{
-            map.put(task.getFormDataId(),task.getBatch()+"");
+        Map<String, String> map = new HashMap<>();
+        baseMapper.queryContractAllBatch(contract).stream().forEach(task -> {
+            map.put(task.getFormDataId(), task.getBatch() + "");
         });
         return map;
     }
@@ -375,8 +403,6 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
         return this.baseMapper.queryBatchList(projectId, contract);
     }
 
-    //@Async
-
     /**
      * 批量电签接口
      *
@@ -416,13 +442,24 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
 
     }
 
-    private void checkIsExsitTaskBatch(List<TaskApprovalVO> taskApprovalVOS, String batchId) {
+    private void checkIsExsitTaskBatch(List<TaskApprovalVO> taskApprovalVOS, String batchId) throws FileNotFoundException {
         boolean isContinue = true;
         while (isContinue) {
             logger.info("【任务审核】当前批次开始电签。批次ID:" + batchId);
             //执行电签
             for (TaskApprovalVO taskApprovalVO : taskApprovalVOS) {
-                this.completeApprovalTask(taskApprovalVO);
+                String pdfUrlEVisa = this.completeApprovalTask(taskApprovalVO);
+
+                //TODO ============== 电签成功,修改试验状态,关联工程部位信息pdf(只有电签成功,才修改) liuYc 2023-03-16 ==============
+                if ("OK".equals(taskApprovalVO.getFlag()) && StringUtils.isNotEmpty(pdfUrlEVisa)) {
+                    //已审批
+                    this.iTrialSelfInspectionRecordService.updateTrialSelfInspectionRecordStatus(pdfUrlEVisa, taskApprovalVO);
+                }
+                if (!"OK".equals(taskApprovalVO.getFlag())) {
+                    //已废除
+                    this.iTrialSelfInspectionRecordService.updateTrialSelfInspectionRecordStatusFC(taskApprovalVO);
+                }
+
             }
             //删除掉对应批次
             this.taskBatchService.deletedById(batchId);
@@ -446,7 +483,7 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
     }
 
     // 电签主流程业务
-    private void completeApprovalTask(TaskApprovalVO taskApprovalVO) {
+    private String completeApprovalTask(TaskApprovalVO taskApprovalVO) {
         //获取流程ID
         String taskId = taskApprovalVO.getTaskId();
         //获取业务实例ID
@@ -459,7 +496,7 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
         //获取当前分支信息
         TaskParallel currentLink = this.taskParallelService.getOne(Wrappers.<TaskParallel>lambdaQuery().eq(TaskParallel::getParallelProcessInstanceId, parallelProcessInstanceId).eq(TaskParallel::getIsDeleted, 0));
         if (currentLink == null) {
-            return;
+            return "";
         }
         //获取主流程
         Task masterTask = this.getOne(Wrappers.<Task>lambdaQuery().eq(Task::getIsDeleted, 0).eq(Task::getProcessInstanceId, currentLink.getProcessInstanceId()));
@@ -514,10 +551,15 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
                         this.update(Wrappers.<Task>lambdaUpdate().set(Task::getStatus, 2).set(Task::getUpdateTime, new Date()).eq(Task::getId, masterTask.getId()));
                         //修改对应的业务数据状态为已审批
                         this.updateBusinessDataByFormDataId(masterTask, 2, finalPdfUrl);
+
+                        //返回电签成功的pdf路径,给试验用
+                        return finalPdfUrl;
                     }
                 } else {
                     //只更新PDF路径
                     this.updateBusinessDataByFormDataId(masterTask, 1, eVisaStatus.contains("@@@@") ? eVisaStatus.split("@@@@")[1] : null);
+
+                    return eVisaStatus.contains("@@@@") ? eVisaStatus.split("@@@@")[1] : null;
                 }
             } else if ("eVisaError".equals(eVisaStatus) || eVisaStatus.contains("eVisaError")) {
                 //电签失败,将对应分支任务的电签状态修改为99并添加错误信息
@@ -599,6 +641,7 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
             this.abolishMessage(masterTask, currentLink, comment);
 
         }
+        return "";
     }
 
     /**

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

@@ -38,6 +38,7 @@ import org.springblade.core.tool.utils.Func;
 import org.springblade.core.tool.utils.ObjectUtil;
 import org.springblade.manager.entity.WbsTreePrivate;
 import org.springblade.resource.feign.NewIOSSClient;
+import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
 
 import javax.servlet.http.HttpServletResponse;
@@ -72,7 +73,7 @@ public class TrialDeviceUseServiceImpl extends BaseServiceImpl<TrialDeviceUseMap
             dto.setFactoryNumber(trialDeviceInfo.getFactoryNumber());
         }
         TrialDeviceUse trialDeviceUse = BeanUtil.copyProperties(dto, TrialDeviceUse.class);
-        if (trialDeviceUse != null){
+        if (trialDeviceUse != null) {
             return this.saveOrUpdate(trialDeviceUse);
         }
         return false;
@@ -309,6 +310,7 @@ public class TrialDeviceUseServiceImpl extends BaseServiceImpl<TrialDeviceUseMap
         return this.saveBatch(listData, 1000);
     }
 
+    @Async
     public void addDeviceUseInfo(TrialSelfInspectionRecordDTO dto) {
         if (com.baomidou.mybatisplus.core.toolkit.StringUtils.isNotEmpty(dto.getDeviceUseIds())) {
             //获取进场记录

Fișier diff suprimat deoarece este prea mare
+ 381 - 387
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TrialSelfInspectionRecordServiceImpl.java


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

@@ -102,10 +102,10 @@ public class EVisaServiceImpl implements EVisaService {
 
     @Override
     public String certification(String pdfUrl, String fileName, String contractId) {
-        try{
+        try {
             //根据当前合同段获取相关的证书
             List<SignPfxFile> pfxFiles = this.signPfxClient.querySignPfxByUserIdOrContractId("", contractId);
-            if(pfxFiles == null || pfxFiles.size() <= 0){
+            if (pfxFiles == null || pfxFiles.size() <= 0) {
                 return NOT_PFX_OR_FILE;
             }
             //查询合同段信息
@@ -113,17 +113,17 @@ public class EVisaServiceImpl implements EVisaService {
 
             //找到合同章
             SignPfxFile contractPfx = null;
-            for(SignPfxFile pfxFile : pfxFiles){
-                if(new Integer("1").equals(contract.getContractType())){
+            for (SignPfxFile pfxFile : pfxFiles) {
+                if (new Integer("1").equals(contract.getContractType())) {
                     //施工方
-                    if("2".equals(pfxFile.getPfxType())){
+                    if ("2".equals(pfxFile.getPfxType())) {
                         //找到当前合同段的合同章类型
                         contractPfx = pfxFile;
                         break;
                     }
-                } else if(new Integer("2").equals(contract.getContractType())){
+                } else if (new Integer("2").equals(contract.getContractType())) {
                     //监理方
-                    if("3".equals(pfxFile.getPfxType())){
+                    if ("3".equals(pfxFile.getPfxType())) {
                         //找到当前合同段的合同章类型
                         contractPfx = pfxFile;
                         break;
@@ -131,7 +131,7 @@ public class EVisaServiceImpl implements EVisaService {
                 }
             }
             //没有找到合同章,直接返回
-            if(contractPfx == null){
+            if (contractPfx == null) {
                 return NOT_PFX_OR_FILE;
             }
 
@@ -144,7 +144,7 @@ public class EVisaServiceImpl implements EVisaService {
             //获取PDF文件
             PDDocument document = PDDocument.load(pdfInputStream);
             int page = document.getPages().getCount();
-            for(int i = 0; i < page; i ++){
+            for (int i = 0; i < page; i++) {
                 SealStrategyVO vo = new SealStrategyVO();
                 vo.setSealCode(EVisaConstant.SIGN_SEAL_CODE + contractPfx.getCertificatePassword());
                 vo.setSealPassword(contractPfx.getCertificatePassword());
@@ -155,7 +155,7 @@ public class EVisaServiceImpl implements EVisaService {
                 vo.setSealType("2");
                 vo.setLx("100");
                 vo.setLy("100");
-                vo.setPage(( i + 1) + "");
+                vo.setPage((i + 1) + "");
                 sealStrategyVOS.add(vo);
             }
             SealPdfVO pdfVO = new SealPdfVO();
@@ -166,33 +166,33 @@ public class EVisaServiceImpl implements EVisaService {
             //兼容大文件签章
             Object[] result;
             //大于50M的单个文件采用大文件签章处理
-            if(fileByte.length > 52428800){
+            if (fileByte.length > 52428800) {
                 result = null;
             } else {
                 //普通文件签章
                 result = this.signPdfByAXQZ(pdfVO, fileByte);
             }
-            if(result != null){
-                if(result[0] != null){
-                    byte[] newPdfData = (byte[])result[0];
+            if (result != null) {
+                if (result[0] != null) {
+                    byte[] newPdfData = (byte[]) result[0];
                     MultipartFile files = new MockMultipartFile("file", SnowFlakeUtil.getId() + ".pdf", "text/plain", IOUtils.toByteArray(new ByteArrayInputStream(newPdfData)));
                     //重新上传
                     BladeFile bladeFile = this.newIOSSClient.uploadFileByInputStream(files);
-                    if(bladeFile != null){
+                    if (bladeFile != null) {
                         return SUCCESS + "@@@@" + bladeFile.getLink();
                     } else {
                         return ERROR;
                     }
                 } else {
                     String s = result[1].toString();
-                    return s.contains("600619") ? "认证失败! " + fileName + "-文件存在无效签名。" : "认证失败!"+"原因:" + s;
+                    return s.contains("600619") ? "认证失败! " + fileName + "-文件存在无效签名。" : "认证失败!" + "原因:" + s;
                 }
             } else {
                 //电签失败 ,接口返回认证失败
                 return "认证失败!认证接口调用异常";
             }
 
-        }catch (Exception e){
+        } catch (Exception e) {
             e.printStackTrace();
         }
 
@@ -201,6 +201,7 @@ public class EVisaServiceImpl implements EVisaService {
 
     /**
      * 合同章 签字
+     *
      * @param task
      * @param finalPdfUrl
      * @return
@@ -209,36 +210,36 @@ public class EVisaServiceImpl implements EVisaService {
     public String eVisaContractSeal(EVisaTaskApprovalVO task, String finalPdfUrl) {
         //获取任务对应表格的电签配置(合同张)
         List<JSONObject> eVisaConfigList = this.taskClient.queryBusinessTableEVisaConfig(task.getParallelProcessInstanceId(), "true");
-        if(eVisaConfigList == null || eVisaConfigList.size() == 0){
+        if (eVisaConfigList == null || eVisaConfigList.size() == 0) {
             //没有电签配置,默认当前任务为不签字审批,返回成功
             return finalPdfUrl;
         }
 
         String sysBatch = ParamCache.getValue(CommonConstant.SYS_USER_TASK_BATCH);
         int batch = 2;
-        if(CommonUtil.checkIsBigDecimal(sysBatch)){
+        if (CommonUtil.checkIsBigDecimal(sysBatch)) {
             batch = new Integer(sysBatch);
         }
 
         //确定合同段并获取合同章
         List<SignPfxFile> userPfxList = this.signPfxClient.querySignPfxByUserIdOrContractId("", this.taskClient.queryTaskContractId(task.getParallelProcessInstanceId()));
-        if(userPfxList == null || userPfxList.size() <= 0){
+        if (userPfxList == null || userPfxList.size() <= 0) {
             //没有签章,不执行电签
             return finalPdfUrl;
         }
 
         //上锁
         System.out.println(AuthUtil.getUserId().toString());
-        if(DistributedRedisLock.acquire(AuthUtil.getUserId().toString(), batch)){
-            try{
+        if (DistributedRedisLock.acquire(AuthUtil.getUserId().toString(), batch)) {
+            try {
                 //准备签章策略
                 List<SealStrategyVO> sealStrategyVOS = new ArrayList<>();
-                for(JSONObject eVisaConfig : eVisaConfigList){
+                for (JSONObject eVisaConfig : eVisaConfigList) {
                     //找到类型与之对应的合同章
                     Iterator<SignPfxFile> iterator = userPfxList.iterator();
-                    while (iterator.hasNext()){
+                    while (iterator.hasNext()) {
                         SignPfxFile next = iterator.next();
-                        if(eVisaConfig.getString("type").equals(next.getPfxType())){
+                        if (eVisaConfig.getString("type").equals(next.getPfxType())) {
                             //设置签章策略
                             SealStrategyVO vo = new SealStrategyVO();
                             vo.setSealCode(EVisaConstant.SIGN_SEAL_CODE + next.getId());
@@ -268,17 +269,17 @@ public class EVisaServiceImpl implements EVisaService {
                 byte[] fileByte = CommonUtil.InputStreamToBytes(CommonUtil.getOSSInputStream(finalPdfUrl));
                 //执行电签
                 Object[] result = this.signPdfByAXQZ(pdfVO, fileByte);
-                if(result != null){
-                    if(result[0] != null){
-                        MultipartFile newFiles = new MockMultipartFile("file", SnowFlakeUtil.getId() + ".pdf", "text/plain", IOUtils.toByteArray(new ByteArrayInputStream((byte[])result[0])));
+                if (result != null) {
+                    if (result[0] != null) {
+                        MultipartFile newFiles = new MockMultipartFile("file", SnowFlakeUtil.getId() + ".pdf", "text/plain", IOUtils.toByteArray(new ByteArrayInputStream((byte[]) result[0])));
                         //重新上传
                         BladeFile bladeFile = this.newIOSSClient.uploadFileByInputStream(newFiles);
-                        if(bladeFile != null){
+                        if (bladeFile != null) {
                             finalPdfUrl = bladeFile.getLink();
                         }
                     }
                 }
-            }catch (Exception e){
+            } catch (Exception e) {
                 e.printStackTrace();
             }
         }
@@ -291,6 +292,7 @@ public class EVisaServiceImpl implements EVisaService {
 
     /**
      * 个人-电签信息
+     *
      * @param task
      * @return
      */
@@ -301,38 +303,44 @@ public class EVisaServiceImpl implements EVisaService {
         //用户默认的电签批次参数
         String sysBatch = ParamCache.getValue(CommonConstant.SYS_USER_TASK_BATCH);
         int batch = 2;
-        if(CommonUtil.checkIsBigDecimal(sysBatch)){
+        if (CommonUtil.checkIsBigDecimal(sysBatch)) {
             batch = new Integer(sysBatch);
         }
 
         //根据任务类型获取对应的文件信息
         TaskApprovalVO taskFile = this.taskClient.queryBusinessDataTask(JSONObject.parseObject(JSONObject.toJSONString(task), TaskApprovalVO.class));
-        if(taskFile == null || taskFile.getApprovalFileList().size() <= 0){
+        if (taskFile == null || taskFile.getApprovalFileList().size() <= 0) {
             //没有找到业务文件,取消签章
             return NOT_PFX_OR_FILE;
         }
 
         //获取任务对应表格的电签配置
         List<JSONObject> eVisaConfigList = this.taskClient.queryBusinessTableEVisaConfig(task.getParallelProcessInstanceId(), "false");
-        if(eVisaConfigList == null || eVisaConfigList.size() == 0){
+        if (eVisaConfigList == null || eVisaConfigList.size() == 0) {
             //没有电签配置,默认当前任务为不签字审批,返回成功
             return SUCCESS + "@@@@" + taskFile.getApprovalFileList().get(0).getFileUrl();
         }
 
         //获取当前用户的证书信息
         List<SignPfxFile> userPfxList = this.signPfxClient.querySignPfxByUserIdOrContractId(AuthUtil.getUserId().toString(), "");
-        if(userPfxList == null || userPfxList.size() <= 0){
+        if (userPfxList == null || userPfxList.size() <= 0) {
             //没有签章,不执行电签
             return NOT_PFX_OR_FILE;
         }
 
         //上锁
-        if(DistributedRedisLock.acquire(AuthUtil.getUserId().toString(), batch)){
-            try{
+        if (DistributedRedisLock.acquire(AuthUtil.getUserId().toString(), batch)) {
+            try {
                 //获取需要签章的数据
                 List<TaskApprovalVO.ApprovalFile> files = taskFile.getApprovalFileList();
                 //这里的文件只会是一张拼接好的PDF
-                for(TaskApprovalVO.ApprovalFile file : files){
+                for (TaskApprovalVO.ApprovalFile file : files) {
+
+                    if (file.getFileName().contains("(关联试验文件)") || file.getFileName().contains("(关联试验工程部位信息文件)") || file.getFileName().contains("(原材料检测报告)")) {
+                        //TODO ============== 试验相关的关联文件不电签 liuYC 2023-03-17 ==============
+                        continue;
+                    }
+
                     //准备签章策略
                     List<SealStrategyVO> sealStrategyVOS = new ArrayList<>();
                     for (JSONObject eVisaConfig : eVisaConfigList) {
@@ -357,12 +365,12 @@ public class EVisaServiceImpl implements EVisaService {
                     byte[] fileByte = CommonUtil.InputStreamToBytes(CommonUtil.getOSSInputStream(file.getFileUrl()));
                     //执行电签
                     Object[] result = this.signPdfByAXQZ(pdfVO, fileByte);
-                    if(result != null){
-                        if(result[0] != null){
-                            MultipartFile newFiles = new MockMultipartFile("file", SnowFlakeUtil.getId() + ".pdf", "text/plain", IOUtils.toByteArray(new ByteArrayInputStream((byte[])result[0])));
+                    if (result != null) {
+                        if (result[0] != null) {
+                            MultipartFile newFiles = new MockMultipartFile("file", SnowFlakeUtil.getId() + ".pdf", "text/plain", IOUtils.toByteArray(new ByteArrayInputStream((byte[]) result[0])));
                             //重新上传
                             BladeFile bladeFile = this.newIOSSClient.uploadFileByInputStream(newFiles);
-                            if(bladeFile != null){
+                            if (bladeFile != null) {
                                 resultMessage = SUCCESS + "@@@@" + bladeFile.getLink();
                             } else {
                                 resultMessage = E_VISA_ERROR;
@@ -373,10 +381,8 @@ public class EVisaServiceImpl implements EVisaService {
                     } else {
                         resultMessage = E_VISA_ERROR;
                     }
-
                 }
-
-            }catch (Exception e){
+            } catch (Exception e) {
                 e.printStackTrace();
             }
         }
@@ -388,6 +394,7 @@ public class EVisaServiceImpl implements EVisaService {
 
     /**
      * 东方 中讯
+     *
      * @throws Exception
      */
     public static void signPdfByDFZX(SealPdfVO pdfVO, byte[] fileByte) throws Exception {
@@ -452,13 +459,13 @@ public class EVisaServiceImpl implements EVisaService {
     /**
      * 安心 - 签章
      */
-    private Object[] signPdfByAXQZ(SealPdfVO pdfVO, byte[] fileByte){
+    private Object[] signPdfByAXQZ(SealPdfVO pdfVO, byte[] fileByte) {
         Object[] result = new Object[3];
-        try{
+        try {
             PaperlessClient paperlessClient = new PaperlessClient(SIGN_HOST, SIGN_PORT, 300000, 36000000);
             paperlessClient.setSSL(false);
             //*****************************************************************************
-            CompoundSealPdfListDetachedRequest compoundSealPdfListDetachedRequest = new  CompoundSealPdfListDetachedRequest();
+            CompoundSealPdfListDetachedRequest compoundSealPdfListDetachedRequest = new CompoundSealPdfListDetachedRequest();
 
             RequestHead requestHead = new RequestHead();
             //业务流水号 非空
@@ -471,7 +478,7 @@ public class EVisaServiceImpl implements EVisaService {
             String channelCode = "";
 
             //设置属性
-            requestHead.setBasicInfo(transactionNo, organizationCode,operatorCode,channelCode);
+            requestHead.setBasicInfo(transactionNo, organizationCode, operatorCode, channelCode);
 
             compoundSealPdfListDetachedRequest.setHead(requestHead);
 
@@ -489,8 +496,8 @@ public class EVisaServiceImpl implements EVisaService {
             requestBody.setPdfBeans(pdfBeans);
             //***********************构造机构章策略 ********************************
             List<SealStrategy> sealStrategies = this.generateSealStrategies(pdfVO.getStrategyVoList());
-            if(null == sealStrategies || sealStrategies.size() <= 0){
-                logger.info("【电签模块】{}","签章策略为空");
+            if (null == sealStrategies || sealStrategies.size() <= 0) {
+                logger.info("【电签模块】{}", "签章策略为空");
                 return null;
             }
             requestBody.setSealStrategies(sealStrategies);
@@ -508,26 +515,26 @@ public class EVisaServiceImpl implements EVisaService {
             ResponseDto responseDto = paperlessClient.execute(compoundSealPdfListDetachedRequest);
 
             //******************************解析响应结果 *********************************************
-            CompoundSealPdfListDetachedResponse compoundSealPdfListDetachedResponse = (CompoundSealPdfListDetachedResponse)responseDto;
-            ResponseHead  responseHead = compoundSealPdfListDetachedResponse.getHead();
+            CompoundSealPdfListDetachedResponse compoundSealPdfListDetachedResponse = (CompoundSealPdfListDetachedResponse) responseDto;
+            ResponseHead responseHead = compoundSealPdfListDetachedResponse.getHead();
             CompoundSealPdfListDetachedResponseBody responseBody = compoundSealPdfListDetachedResponse.getBody();
-            if(ClientConstants.CODE_SUCCESS.equals(responseHead.getCode())){
+            if (ClientConstants.CODE_SUCCESS.equals(responseHead.getCode())) {
                 List<PdfBean4Response> pdfBeanList = responseBody.getPdfBeans();
-                if(pdfBeanList!=null && pdfBeanList.size()>0){
+                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());
+            } else {
+                logger.info("【电签模块】{}", "签章响应Response:" + compoundSealPdfListDetachedResponse);
+                logger.info("【电签模块】{}", "签章响应code:" + responseHead.getCode());
                 result[0] = null;
                 result[1] = compoundSealPdfListDetachedResponse.toString();
                 result[2] = responseHead.getMessage();
             }
 
-        } catch (Exception e){
+        } catch (Exception e) {
             e.printStackTrace();
-            logger.info("【电签模块】{}","电签签章接口调用异常");
+            logger.info("【电签模块】{}", "电签签章接口调用异常");
             e.printStackTrace();
             return null;
         }
@@ -539,16 +546,16 @@ public class EVisaServiceImpl implements EVisaService {
      * 构造机构章签章策略
      * 使用 :1-印章绑定的图片
      */
-    private List<SealStrategy> generateSealStrategies(List<SealStrategyVO> strategyVoList){
+    private List<SealStrategy> generateSealStrategies(List<SealStrategyVO> strategyVoList) {
         List<SealStrategy> sealStrategies = new ArrayList<>();
 
-        if(strategyVoList == null || strategyVoList.size() <= 0){
+        if (strategyVoList == null || strategyVoList.size() <= 0) {
             return null;
         }
 
         //构建策略
-        for(SealStrategyVO vo : strategyVoList){
-            try{
+        for (SealStrategyVO vo : strategyVoList) {
+            try {
                 SealStrategy sealStrategy = new SealStrategy();
 
                 // 使用图片签章
@@ -572,9 +579,9 @@ public class EVisaServiceImpl implements EVisaService {
                 String visible = "1";
                 sealStrategy.setVisible(visible);
 
-                if(!"authentication".equals(vo.getImageUrl())){
+                if (!"authentication".equals(vo.getImageUrl())) {
                     String imageUrl = vo.getImageUrl();
-                    if(StringUtils.isEmpty(imageUrl)){
+                    if (StringUtils.isEmpty(imageUrl)) {
                         logger.info("签章图片url为null,签章人员:" + vo.getSealPerson());
                         return null;
                     }
@@ -584,10 +591,10 @@ public class EVisaServiceImpl implements EVisaService {
                     imageData = ImageUtil.transferAlpha(imageData);
 
                     //设置大小
-                    if(vo.isCompanySeal()){
-                        imageData = ImageUtil.resizeImage(imageData,540,540);
-                    }else {
-                        imageData = ImageUtil.resizeImage(imageData,480,132);
+                    if (vo.isCompanySeal()) {
+                        imageData = ImageUtil.resizeImage(imageData, 540, 540);
+                    } else {
+                        imageData = ImageUtil.resizeImage(imageData, 480, 132);
 //                        imageData = ImageUtil.resizeImage(imageData,540,540);
                     }
 
@@ -596,7 +603,7 @@ public class EVisaServiceImpl implements EVisaService {
 
                     if (imageData != null) {
                         //图片进行Base64编码/
-                        String imageDataString =  new String(Base64.encode(imageData), StandardCharsets.UTF_8);
+                        String imageDataString = new String(Base64.encode(imageData), StandardCharsets.UTF_8);
                         sealStrategy.setSealImage(imageDataString);
                     }
                 } else {
@@ -604,7 +611,7 @@ public class EVisaServiceImpl implements EVisaService {
                     sealStrategy.setSealImage(EVisaConstant.base64String);
                 }
 
-                sealStrategy.setSealMiscInfo(vo.getSealPerson(), vo.getSealLocation(),  vo.getSealReason());
+                sealStrategy.setSealMiscInfo(vo.getSealPerson(), vo.getSealLocation(), vo.getSealReason());
 
                 //关键字签章
                 sealStrategy.setSealType(vo.getSealType());
@@ -614,14 +621,14 @@ public class EVisaServiceImpl implements EVisaService {
                     sealStrategy.setOffsetY(vo.getOffSetY());
                 } else if (vo.getSealType().equals("2")) {
                     //设置PDF坐标原点,签章图片定位点   默认为PDF左下角,签章图片定位为左下角
-                    if(StringUtils.isNotEmpty(vo.getIsCenterCoordinate())){
+                    if (StringUtils.isNotEmpty(vo.getIsCenterCoordinate())) {
                         sealStrategy.setIsCenterCoordinate(vo.getIsCenterCoordinate());
                     }
                     sealStrategy.setSignWithCoordinate(vo.getPage(), vo.getLx(), vo.getLy());
                 }
 
                 sealStrategies.add(sealStrategy);
-            }catch (Exception e){
+            } catch (Exception e) {
                 e.printStackTrace();
             }
         }
@@ -635,7 +642,7 @@ public class EVisaServiceImpl implements EVisaService {
         BufferedImage gridImage = ImageIO.read(new ByteArrayInputStream(bytes));
         final String formatName = "png";
         byte[] result = new byte[0];
-        for (Iterator<ImageWriter> iw = ImageIO.getImageWritersByFormatName(formatName); iw.hasNext();) {
+        for (Iterator<ImageWriter> iw = ImageIO.getImageWritersByFormatName(formatName); iw.hasNext(); ) {
             ImageWriter writer = iw.next();
             ImageWriteParam writeParam = writer.getDefaultWriteParam();
             ImageTypeSpecifier typeSpecifier = ImageTypeSpecifier.createFromBufferedImageType(BufferedImage.TYPE_INT_RGB);
@@ -683,7 +690,7 @@ public class EVisaServiceImpl implements EVisaService {
      */
     @Override
     public String createSeal(EVisaMakeSealVO vo) {
-        try{
+        try {
             PaperlessClient paperlessClient = new PaperlessClient(SIGN_HOST, SIGN_PORT, 3000, 20000);
             paperlessClient.setSSL(false);
 
@@ -710,7 +717,7 @@ public class EVisaServiceImpl implements EVisaService {
             String privateKeyPassword = vo.getPfxPassword();
             String pkcs12Password = PwdEncryptUtil.encrypto(privateKeyPassword);
 
-            sealCertBean.setMakeSealWithPkcs12(pkcs12String, pkcs12Password, BaseConstants.KEY_ALG_RSA , BaseConstants.KEY_ALG_LENGTH_2048);
+            sealCertBean.setMakeSealWithPkcs12(pkcs12String, pkcs12Password, BaseConstants.KEY_ALG_RSA, BaseConstants.KEY_ALG_LENGTH_2048);
             sealCertBean.setUserInfo(vo.getUserName(), vo.getIdType(), vo.getIdNumber());
 
             // 构造sealInfo
@@ -727,27 +734,27 @@ public class EVisaServiceImpl implements EVisaService {
             MakeSealRequest requestBean = new MakeSealRequest();
             requestBean.setHead(requestHeadBean);
             requestBean.setBody(requestBodyBean);
-            logger.info("【电签模块】{}","创建印章请求Request:"+requestBean);
+            logger.info("【电签模块】{}", "创建印章请求Request:" + requestBean);
             // ------调用接口------
             ResponseDto responseDto = paperlessClient.execute(requestBean);
 
             // 接收响应报文对象
             MakeSealResponse responseBean = (MakeSealResponse) responseDto;
-            logger.info("【电签模块】{}","创建印章响应Response:"+requestBean);
+            logger.info("【电签模块】{}", "创建印章响应Response:" + requestBean);
 
             // 响应报文头
             ResponseHead responseHeadBean = responseBean.getHead();
             // 响应报文体
             MakeSealResponseBody responseBodyBean = responseBean.getBody();
-            if(responseBodyBean != null){
+            if (responseBodyBean != null) {
                 logger.info("【电签模块】{}", "创建印章成功==========certDn: " + responseBodyBean.getCertDn() + " ; message: " + responseHeadBean.getMessage());
                 //请求结果
                 return responseHeadBean.getMessage();
-            } else if(responseHeadBean.getMessage().contains("is exist")) {
+            } else if (responseHeadBean.getMessage().contains("is exist")) {
                 logger.info("【电签模块】{}", responseHeadBean.getMessage());
                 return "error";
             }
-        }catch (Exception e){
+        } catch (Exception e) {
             e.printStackTrace();
         }
 
@@ -756,7 +763,7 @@ public class EVisaServiceImpl implements EVisaService {
 
     @Override
     public List<CertBean> onlineCheckSeal(String pdfUrl) {
-        try{
+        try {
             PaperlessClient paperlessClient = new PaperlessClient(SIGN_HOST, SIGN_PORT, 300000, 1800000);
             paperlessClient.setSSL(false);
 
@@ -773,7 +780,7 @@ public class EVisaServiceImpl implements EVisaService {
             //渠道编码 可为空
             String channelCode = EVisaConstant.channelCode;
             //设置属性
-            requestHead.setBasicInfo(transactionNo, organizationCode,operatorCode,channelCode);
+            requestHead.setBasicInfo(transactionNo, organizationCode, operatorCode, channelCode);
 
             verifyPdfSealRequest.setHead(requestHead);
             /*==================================================================================*/
@@ -798,18 +805,18 @@ public class EVisaServiceImpl implements EVisaService {
             ResponseDto responseDto = paperlessClient.execute(verifyPdfSealRequest);
             /*==================================================================================*/
 
-            VerifyPdfSealResponse verifyPdfSealResponse = (VerifyPdfSealResponse)responseDto;
+            VerifyPdfSealResponse verifyPdfSealResponse = (VerifyPdfSealResponse) responseDto;
 
-            ResponseHead  responseHead = verifyPdfSealResponse.getHead();
+            ResponseHead responseHead = verifyPdfSealResponse.getHead();
             VerifyPdfSealResponseBody responseBody = verifyPdfSealResponse.getBody();
 
-            if(ClientConstants.CODE_SUCCESS.equals(responseHead.getCode())){
+            if (ClientConstants.CODE_SUCCESS.equals(responseHead.getCode())) {
                 return responseBody.getCertBeans();
             } else {
-                logger.info("【电签模块】{}","验签接口响应code:" + responseHead.getCode());
+                logger.info("【电签模块】{}", "验签接口响应code:" + responseHead.getCode());
                 return null;
             }
-        }catch (Exception e){
+        } catch (Exception e) {
             e.printStackTrace();
             return null;
         }

+ 1 - 0
blade-service/blade-manager/blade-manager.iml

@@ -215,6 +215,7 @@
     <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.11.4" level="project" />
     <orderEntry type="module" module-name="blade-user-api" />
     <orderEntry type="module" module-name="blade-business-api" />
+    <orderEntry type="module" module-name="blade-archive-api" />
     <orderEntry type="library" name="Maven: com.jfirer:baseutil:1.0" level="project" />
     <orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.13.1" level="project" />
     <orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:2.2" level="project" />

+ 11 - 0
blade-service/blade-manager/pom.xml

@@ -50,6 +50,11 @@
             <artifactId>blade-business-api</artifactId>
             <version>${bladex.project.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.springblade</groupId>
+            <artifactId>blade-archive-api</artifactId>
+            <version>${bladex.project.version}</version>
+        </dependency>
         <dependency>
             <groupId>com.jfirer</groupId>
             <artifactId>baseutil</artifactId>
@@ -144,6 +149,12 @@
             <version>20.4</version>
             <scope>compile</scope>
         </dependency>
+        <dependency>
+            <groupId>org.springblade</groupId>
+            <artifactId>blade-archive-api</artifactId>
+            <version>2.9.1.RELEASE</version>
+            <scope>compile</scope>
+        </dependency>
     </dependencies>
     <build>
         <plugins>

+ 1 - 1
blade-service/blade-manager/src/main/java/com/jfireel/expression/util/ValueUtil.java

@@ -21,7 +21,7 @@ public class ValueUtil {
                 right=sum(CustomFunction.obj2ListNe(right));
 
             }
-            if(!StringUtils.isNotEmpty(left,right)){
+            if(StringUtils.isNotEmpty(left)&&StringUtils.isNotEmpty(right)){
                 return new Object[]{left,right};
             }
         }

+ 5 - 0
blade-service/blade-manager/src/main/java/com/mixsmart/utils/CustomFunction.java

@@ -19,6 +19,10 @@ import org.jsoup.nodes.Document;
 import org.jsoup.nodes.Element;
 import org.jsoup.select.Elements;
 import org.springblade.core.tool.utils.*;
+import org.springblade.manager.dto.Coords;
+import org.springblade.manager.dto.ElementData;
+import org.springblade.manager.dto.FormData;
+import org.springblade.manager.entity.Formula;
 
 
 import java.io.File;
@@ -2795,4 +2799,5 @@ public class CustomFunction {
 
 
 
+
 }

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

@@ -1,10 +1,16 @@
 package com.mixsmart.utils;
 
 
+import org.springblade.manager.dto.Coords;
+import org.springblade.manager.dto.ElementData;
+import org.springblade.manager.dto.FormData;
+import org.springblade.manager.entity.Formula;
+
 import java.math.BigDecimal;
 import java.util.*;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
+import java.util.stream.Collectors;
 
 /**
  * @author yangyj
@@ -56,6 +62,56 @@ public class FormulaUtils {
         return result;
     }
 
+    public  static void write(FormData fd, Object data){
+        if(data instanceof List){
+            List<Object> values = (List<Object>) data;
+            if(values.size()>fd.getValues().size()){
+                /*当生成的数据超过实际容量的时候,会自动追加页数*/
+                if(fd.getCoordsList().size()==1){
+                    fd.getValues().get(0).setValue(values.stream().map(StringUtils::handleNull).collect(Collectors.joining("、")));
+                }else{
+                    // copy(fd,values);
+                    for(int n=0;n<fd.getValues().size();n++){
+                        fd.getValues().get(n).setValue(values.get(n));
+                    }
+                    List<Object> overList=values.stream().skip(fd.getValues().size()).collect(Collectors.toList());
+                    List<Coords> coordsList = fd.getCoordsList();
+                    int addPage=(int)Math.ceil((double)overList.size()/(double)coordsList.size());
+                    fd.setAddPages(addPage);
+                    ElementData last =fd.getValues().get(fd.getValues().size()-1);
+                    int indexBase=last.getIndex()+1;
+                    List<ElementData> addList= new ArrayList<>();
+                    for(int i=0;i<addPage;i++){
+                        for(int j=0;j<coordsList.size();j++){
+                            /*超页就尽管写进去,格式化阶段再加表*/
+                            Coords coords = coordsList.get(j);
+                            Object v=null;
+                            int st=i*coordsList.size()+j;
+                            if(st<overList.size()){
+                                v= overList.get(st);
+                            }
+                            addList.add(new ElementData(indexBase+i,last.getGroupId(),v,coords.getX(),coords.getY()));
+                        }
+                    }
+                    fd.getValues().addAll(addList);
+                }
+
+            }else{
+                for(int n=0;n<values.size();n++){
+                    fd.getValues().get(n).setValue(values.get(n));
+                }
+            }
+        }else{
+            if(Formula.FULL.equals(fd.getFormula().getOutm())){
+                /*填充策略*/
+                fd.getValues().forEach(e->e.setValue(data));
+            }else{
+                fd.getValues().get(0).setValue(data);
+            }
+        }
+
+    }
+
 
 
 }

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

@@ -18,10 +18,13 @@ import lombok.SneakyThrows;
 import org.apache.commons.codec.Charsets;
 import org.apache.commons.lang.ArrayUtils;
 import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang3.ObjectUtils;
 import org.jsoup.Jsoup;
 import org.jsoup.nodes.Document;
 import org.jsoup.nodes.Element;
 import org.jsoup.select.Elements;
+import org.springblade.business.dto.TrialSelfInspectionRecordDTO;
+import org.springblade.business.entity.TrialSelfInspectionRecord;
 import org.springblade.business.feign.ContractLogClient;
 import org.springblade.business.feign.InformationQueryClient;
 import org.springblade.business.vo.SaveContractLogVO;
@@ -54,6 +57,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.jdbc.core.BeanPropertyRowMapper;
 import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.bind.annotation.*;
@@ -1123,32 +1127,32 @@ public class ExcelTabController extends BladeController {
                                 objs.add(jsonObject);
                             }
 
-                            String checkbox = "<hc-form-checkbox-group @keyup.shift.up='keyupShiftUp' @keyup.shift.down='keyupShiftDown' @keyup.shift.left='keyupShiftLeft' @keyup.shift.right='keyupShiftRight' :objs='" + objs + "'  @change='checkboxGroupChange' @contextmenu.prevent.native='RightClick(" + parm + ")' trIndex=" + i + " tdIndex=" + j + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + " placeholder=''> </hc-form-checkbox-group>";
+                            String checkbox = "<hc-form-checkbox-group @keydown.shift.up='keyupShiftUp' @keydown.shift.down='keyupShiftDown' @keydown.shift.left='keyupShiftLeft' @keydown.shift.right='keyupShiftRight' :objs='" + objs + "'  @change='checkboxGroupChange' @contextmenu.prevent.native='RightClick(" + parm + ")' trIndex=" + i + " tdIndex=" + j + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + " placeholder=''> </hc-form-checkbox-group>";
                             data.empty().append(checkbox);
 
                         } else {
                             if (index_state) { // 区域内
                                 if (rowspan >= 1) {
-                                    data.empty().append("<el-input type='textarea' @keyup.shift.up='keyupShiftUp' @keyup.shift.down='keyupShiftDown' @keyup.shift.left='keyupShiftLeft'  @keyup.shift.right='keyupShiftRight'  @contextmenu.prevent.native='RightClick(" + parm + ")' trIndex=" + i + " tdIndex=" + j + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + " style='width:100%;height:100%;'   :rows=" + rowspan * 2 + " placeholder=''> </el-input>");
+                                    data.empty().append("<el-input type='textarea' @keydown.shift.up='keyupShiftUp' @keydown.shift.down='keyupShiftDown' @keydown.shift.left='keyupShiftLeft'  @keydown.shift.right='keyupShiftRight'  @contextmenu.prevent.native='RightClick(" + parm + ")' trIndex=" + i + " tdIndex=" + j + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + " style='width:100%;height:100%;'   :rows=" + rowspan * 2 + " placeholder=''> </el-input>");
                                 } else {
-                                    data.empty().append("<el-input type='text' @keyup.shift.up='keyupShiftUp' @keyup.shift.down='keyupShiftDown' @keyup.shift.left='keyupShiftLeft'  @keyup.shift.right='keyupShiftRight'  @contextmenu.prevent.native='RightClick(" + parm + ")' trIndex=" + i + " tdIndex=" + j + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + " style='width:100%;height:100%;' placeholder=''> </el-input>");
+                                    data.empty().append("<el-input type='text' @keydown.shift.up='keyupShiftUp' @keydown.shift.down='keyupShiftDown' @keydown.shift.left='keyupShiftLeft'  @keydown.shift.right='keyupShiftRight'  @contextmenu.prevent.native='RightClick(" + parm + ")' trIndex=" + i + " tdIndex=" + j + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + " style='width:100%;height:100%;' placeholder=''> </el-input>");
                                 }
                             } else { // 区域外
                                 if (j == 0) {
                                     if (colspan == maxCol && i >= 1) {
                                         if (rowspan >= 1) {
-                                            data.empty().append("<el-input @keyup.shift.up='keyupShiftUp' @keyup.shift.down='keyupShiftDown' @keyup.shift.left='keyupShiftLeft' @keyup.shift.right='keyupShiftRight' type='textarea'  @contextmenu.prevent.native='RightClick(" + parm + ")' trIndex=" + i + " tdIndex=" + j + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + " style='width:100%;height:100%;'   :rows=" + rowspan * 2 + " placeholder=''> </el-input>");
+                                            data.empty().append("<el-input @keydown.shift.up='keyupShiftUp' @keydown.shift.down='keyupShiftDown' @keydown.shift.left='keyupShiftLeft' @keydown.shift.right='keyupShiftRight' type='textarea'  @contextmenu.prevent.native='RightClick(" + parm + ")' trIndex=" + i + " tdIndex=" + j + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + " style='width:100%;height:100%;'   :rows=" + rowspan * 2 + " placeholder=''> </el-input>");
                                         } else {
-                                            data.empty().append("<el-input @keyup.shift.up='keyupShiftUp' @keyup.shift.down='keyupShiftDown' @keyup.shift.left='keyupShiftLeft' @keyup.shift.right='keyupShiftRight' type='text' @contextmenu.prevent.native='RightClick(" + parm + ")' trIndex=" + i + " tdIndex=" + j + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + " style='width:100%;height:100%;' placeholder=''> </el-input>");
+                                            data.empty().append("<el-input @keydown.shift.up='keyupShiftUp' @keydown.shift.down='keyupShiftDown' @keydown.shift.left='keyupShiftLeft' @keydown.shift.right='keyupShiftRight' type='text' @contextmenu.prevent.native='RightClick(" + parm + ")' trIndex=" + i + " tdIndex=" + j + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + " style='width:100%;height:100%;' placeholder=''> </el-input>");
                                         }
                                     }
                                 } else {
                                     Element bforData = tds.get(j - 1);
                                     if (!bforData.text().isEmpty() || bforData.html().indexOf("hc-form-checkbox-group") >= 0) {
                                         if (rowspan >= 1) {
-                                            data.empty().append("<el-input @keyup.shift.up='keyupShiftUp' @keyup.shift.down='keyupShiftDown' @keyup.shift.left='keyupShiftLeft' @keyup.shift.right='keyupShiftRight' type='textarea' @contextmenu.prevent.native='RightClick(" + parm + ")' trIndex=" + i + " tdIndex=" + j + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + " style='width:100%;height:100%;'   :rows=" + rowspan * 2 + " placeholder=''> </el-input>");
+                                            data.empty().append("<el-input @keydown.shift.up='keyupShiftUp' @keydown.shift.down='keyupShiftDown' @keydown.shift.left='keyupShiftLeft' @keydown.shift.right='keyupShiftRight' type='textarea' @contextmenu.prevent.native='RightClick(" + parm + ")' trIndex=" + i + " tdIndex=" + j + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + " style='width:100%;height:100%;'   :rows=" + rowspan * 2 + " placeholder=''> </el-input>");
                                         } else {
-                                            data.empty().append("<el-input @keyup.shift.up='keyupShiftUp' @keyup.shift.down='keyupShiftDown' @keyup.shift.left='keyupShiftLeft'  @keyup.shift.right='keyupShiftRight' type='text' @contextmenu.prevent.native='RightClick(" + parm + ")' trIndex=" + i + " tdIndex=" + j + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + " style='width:100%;height:100%;' placeholder=''> </el-input>");
+                                            data.empty().append("<el-input @keydown.shift.up='keyupShiftUp' @keydown.shift.down='keyupShiftDown' @keydown.shift.left='keyupShiftLeft'  @keydown.shift.right='keyupShiftRight' type='text' @contextmenu.prevent.native='RightClick(" + parm + ")' trIndex=" + i + " tdIndex=" + j + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + " style='width:100%;height:100%;' placeholder=''> </el-input>");
                                         }
                                     }
                                 }
@@ -1385,11 +1389,15 @@ public class ExcelTabController extends BladeController {
                 .eq(WbsTreeContract::getContractId, wbsTreeContract.getContractId())
                 .eq(WbsTreeContract::getParentId, wbsTreeContract.getParentId()));
         List<WbsTreeContract> wbsTreeContractList2 = wbsTreeContractList.stream().sorted(Comparator.comparing(WbsTreeContract::getCreateTime).reversed()).collect(Collectors.toList());
+        long tabGroupId = SnowFlakeUtil.getId();
+        // 添加所有
+        wbsTreeContractList2.forEach(WbsTreeContract -> WbsTreeContract.setTabGroupId(tabGroupId));
 
 
         long newPkId = SnowFlakeUtil.getId();
         wbsTreeContract.setPKeyId(newPkId);
         wbsTreeContract.setCreateTime(new Date());
+        wbsTreeContract.setTabGroupId(tabGroupId);
         String nodeName = wbsTreeContractList2.get(0).getNodeName();
 
         if (nodeName.indexOf("__") >= 0) {
@@ -1408,15 +1416,14 @@ public class ExcelTabController extends BladeController {
         String tabName = wbsTreeContract.getInitTableName();
         // 字段查询 并去掉公式字段
 
-        String colkeys = "SELECT GROUP_CONCAT(e_key) as colkeys from m_table_info a ,m_wbs_form_element b WHERE a.tab_en_name = '" + tabName + "' and a.id=b.f_id ";
+        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=" + pkeyId;
         jdbcTemplate.execute(querySql);
-
+        wbsTreeContractService.saveBatch(wbsTreeContractList2);
         wbsTreeContractService.save(wbsTreeContract);
         return R.data("成功");
     }
@@ -1514,24 +1521,22 @@ public class ExcelTabController extends BladeController {
     @ApiImplicitParams(value = {
             @ApiImplicitParam(name = "nodeId", value = "当前节点Id", required = true),
             @ApiImplicitParam(name = "classify", value = "填报的类型(施工或监理)", required = true),
-            @ApiImplicitParam(name = "projectId", value = "项目ID", required = true),
             @ApiImplicitParam(name = "contractId", value = "合同段Id", required = true)
     })
-    public R getpdfs(String nodeId, String classify, String contractId, String projectId) {
-        String sql = "select pdf_url, e_visa_pdf_url,pdf_trial_url from u_information_query  where classify='" + classify + "' and  wbs_id='" + nodeId + "' and contract_id ='" + contractId + "' ";
-
+    public R getPdfS(String nodeId, String classify, String contractId) throws FileNotFoundException {
+        String sql = "select pdf_url,e_visa_pdf_url,pdf_trial_url,pdf_trial_url_position from u_information_query where classify='" + classify + "' and wbs_id='" + nodeId + "' and contract_id='" + contractId + "'";
         List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql);
-        if (maps != null && maps.size() >= 1) {
+        if (maps.size() >= 1) {
             Map<String, Object> stringObjectMap = maps.get(0);
             Object pdfUrl = stringObjectMap.get("pdf_url");
             if (stringObjectMap.get("e_visa_pdf_url") != null) {
-                //优先使用电签的PDF
+                //优先使用电签的pdf
                 pdfUrl = stringObjectMap.get("e_visa_pdf_url");
             }
 
-            if (stringObjectMap.get("pdf_trial_url") != null) {
-                //优先使用试验合并的PDF
-                pdfUrl = stringObjectMap.get("pdf_trial_url");
+            if (stringObjectMap.get("pdf_trial_url") != null || stringObjectMap.get("pdf_trial_url_position") != null) {
+                //合并试验关联文件、试验工程部位信息的pdf
+                pdfUrl = this.mergePdfShow(pdfUrl, stringObjectMap);
             }
 
             if (StringUtils.isEmpty(pdfUrl + "")) {
@@ -1540,10 +1545,47 @@ public class ExcelTabController extends BladeController {
                 return R.data(pdfUrl);
             }
         } else {
-            return R.fail("无历史数据预览,请保存数据");
+            return R.fail("无历史数据预览请保存数据");
         }
     }
 
+    /**
+     * 合并pdf展示
+     */
+    private Object mergePdfShow(Object oldPdfUrl, Map<String, Object> stringObjectMap) throws FileNotFoundException {
+        Object pdfUrl = "";
+        List<String> pdfList = new ArrayList<>();
+        //施工填报的原始pdf
+        pdfList.add(oldPdfUrl.toString());
+        //关联试验的pdf
+        Object pdfTrialUrl = stringObjectMap.get("pdf_trial_url");
+        Object pdfTrialUrlPosition = stringObjectMap.get("pdf_trial_url_position");
+        if (pdfTrialUrl != null) {
+            pdfList.add(pdfTrialUrl.toString());
+        }
+        if (pdfTrialUrlPosition != null) {
+            pdfList.add(pdfTrialUrlPosition.toString());
+        }
+        //合并
+        if (pdfList.size() >= 2) {
+            String file_path = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
+            Long id = SnowFlakeUtil.getId();
+            String trialPdf = file_path + "/pdf/" + id + ".pdf";
+            File trialPdf2 = ResourceUtil.getFile(trialPdf);
+            if (trialPdf2.exists()) {
+                trialPdf2.delete();
+            }
+            //合并当前所有选择的试验pdf
+            FileUtils.mergePdfPublicMethods(pdfList, trialPdf);
+            BladeFile bladeFile = this.newIOSSClient.uploadFile(id + ".pdf", trialPdf);
+            if (bladeFile != null && ObjectUtils.isNotEmpty(bladeFile.getLink())) {
+                pdfUrl = bladeFile.getLink();
+            }
+        }
+        return pdfUrl;
+    }
+
+
     /**
      * 用户端删除复制信息表
      */
@@ -1563,17 +1605,48 @@ public class ExcelTabController extends BladeController {
     @ApiOperation(value = "填报页面数据保存", notes = "填报页面数据保存")
     public R<String> saveBussData(@Valid @RequestBody JSONObject dataInfo, BladeUser bladeUser) throws Exception {
         JSONArray dataArray = new JSONArray();
+
         if (dataInfo.containsKey("dataInfo")) { // 节点保存
             JSONObject jsonObject = dataInfo.getJSONObject("dataInfo");
             dataArray = jsonObject.getJSONArray("orderList");
         } else { // 单个保存
             dataArray.add(dataInfo);
         }
+
         JSONObject tableInfo1 = dataArray.getJSONObject(0);
         String nodeid = tableInfo1.getString("nodeId");
         String contractId = tableInfo1.getString("contractId");
         String projectId = tableInfo1.getString("projectId");
         String classify = tableInfo1.getString("classify");
+        String groupId = tableInfo1.getString("tabGroupId");
+        String pkeyId = tableInfo1.getString("pkeyId");
+
+        //
+        String pkeyIds = pkeyId;
+        String groupIds = groupId;
+        for (int i = 1; i < dataArray.size(); i++) {
+            JSONObject jsonObject = dataArray.getJSONObject(i);
+            pkeyIds += "," + jsonObject.getString("pkeyId");
+            ;
+            groupIds += "," + jsonObject.getString("tabGroupId");
+            ;
+        }
+        if (StringUtils.isNotEmpty(groupIds)) {
+            List<WbsTreeContract> wbsTreeContractList = this.wbsTreeContractService.getBaseMapper().selectList(
+                    Wrappers.<WbsTreeContract>lambdaQuery()
+                            .in(WbsTreeContract::getTabGroupId, groupIds)
+                            .notIn(WbsTreeContract::getPKeyId, pkeyIds)
+                            .eq(WbsTreeContract::getIsDeleted, BladeConstant.DB_NOT_DELETED)
+            );
+            if (wbsTreeContractList != null && wbsTreeContractList.size() >= 1) {
+                for (WbsTreeContract data : wbsTreeContractList) {
+                    R bussDataInfo = this.getBussDataInfo(data.getPKeyId());
+                    Object data1 = bussDataInfo.getData();
+                    dataArray.add(data1);
+                }
+            }
+        }
+
         List<TableInfo> tableInfoList = this.excelTabService.getTableInfoList(dataArray);
         try {
             this.excelTabService.formulaFillData(tableInfoList, Long.parseLong(nodeid));
@@ -1582,14 +1655,11 @@ public class ExcelTabController extends BladeController {
             e.printStackTrace();
         }
 
-        try{
-            R info = this.excelTabService.saveOrUpdateInfo(tableInfoList);
-            if (!info.isSuccess()) {
-                return info;
-            }
-        }catch (Exception e){
-            throw new ServiceException(e.getMessage());
+        R info = this.excelTabService.saveOrUpdateInfo(tableInfoList);
+        if (!info.isSuccess()) {
+            return info;
         }
+
         //单个 pdf加载
         for (TableInfo tableInfo : tableInfoList) {
             excelTabService.getBussPdfInfo(Long.parseLong(tableInfo.getPkeyId()));

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

@@ -362,12 +362,11 @@ public class FormulaController {
                   /*临时处理,等确定数据结构在优化*/
                    if(formula.getFormula().contains(".option")){
                        return R.data(createRadioPanel(0,"是否引用公式数据",data));
-                   }else if (StringUtils.isEquals("MILE",formula.getNumber())){
+                   }else if (StringUtils.isEquals("MILE",formula.getNumber())||StringUtils.isEquals("TURN_POINT",formula.getNumber())){
                       if(StringUtils.isEquals(key,formula.getRelyList().get(0).split(StringPool.COLON)[1])){
                           return R.data(createRadioPanel(1,"竖直方向",data));
                       }
                   }
-              }else{
                   R.success("暂无公式控件");
               }
              return R.data(result);
@@ -378,6 +377,7 @@ public class FormulaController {
         jo.put("scope",1);
         JSONObject info =jo.getJSONObject("info");
         info.put("label","竖直方向");
+        info.put("code","TF");
         if(Func.isNotEmpty(data)){
             info.put("data",data);
         }
@@ -394,7 +394,7 @@ public class FormulaController {
     @GetMapping("/log")
     public R<Object> log(Long pkeyId){
         Map<String,Object> result = new HashMap<>();
-        result.put("版本信息","202303101210");
+        result.put("版本信息","202303161800");
         if(Func.isNotEmpty(pkeyId)){
             result.put("执行情况",this.jdbcTemplate.queryForList("select * from m_formula_log where id="+pkeyId));
         }

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

@@ -257,12 +257,12 @@ public class TextdictInfoController extends BladeController {
 
         String vmode = "formData." + keyname;
         if (textdictInfo.getTextId().equals("input")) { // 文本框
-            element.empty().append("<el-input type='text'  @keyup.shift.up='keyupShiftUp' @keyup.shift.down='keyupShiftDown' @keyup.shift.left='keyupShiftLeft' @keyup.shift.right='keyupShiftRight' v-model=" + vmode + " placeholder=" + placeholder + " keyname=" + keyname + " weighing=" + weighing + "  @contextmenu.prevent.native='RightClick(" + parm + ")' trIndex=" + trindex + " tdIndex=" + tdindex + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + " style='width:100%;height:100%' > </el-input>");
+            element.empty().append("<el-input type='text' id=" + keyname + " @keydown.shift.up='keyupShiftUp' @keydown.shift.down='keyupShiftDown' @keydown.shift.left='keyupShiftLeft' @keydown.shift.right='keyupShiftRight' v-model=" + vmode + " placeholder=" + placeholder + " keyname=" + keyname + " weighing=" + weighing + "  @contextmenu.prevent.native='RightClick(" + parm + ")' trIndex=" + trindex + " tdIndex=" + tdindex + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + " style='width:100%;height:100%' > </el-input>");
         } else if (textdictInfo.getTextId().equals("textarea")) { // 文本域
             int rowspan = element.attr("ROWSPAN").equals("") ? 0 : Integer.parseInt(element.attr("ROWSPAN"));
-            element.empty().append("<el-input :rows=" + rowspan * 2 + "  @keyup.shift.up='keyupShiftUp' @keyup.shift.down='keyupShiftDown' @keyup.shift.left='keyupShiftLeft' @keyup.shift.right='keyupShiftRight'  type='textarea' placeholder=" + placeholder + " v-model=" + vmode + "    keyname=" + keyname + " weighing=" + weighing + "  @contextmenu.prevent.native='RightClick(" + parm + ")' trIndex=" + trindex + " tdIndex=" + tdindex + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + " style='width:100%;height:100%'  > </el-input>");
+            element.empty().append("<el-input :rows=" + rowspan * 2 + " id=" + keyname + " @keydown.shift.up='keyupShiftUp' @keydown.shift.down='keyupShiftDown' @keydown.shift.left='keyupShiftLeft' @keydown.shift.right='keyupShiftRight'  type='textarea' placeholder=" + placeholder + " v-model=" + vmode + "    keyname=" + keyname + " weighing=" + weighing + "  @contextmenu.prevent.native='RightClick(" + parm + ")' trIndex=" + trindex + " tdIndex=" + tdindex + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + " style='width:100%;height:100%'  > </el-input>");
         } else if (textdictInfo.getTextId().equals("select")) { // 下拉框
-            String selectText = " <el-select v-model=" + vmode + " @keyup.shift.up='keyupShiftUp' @keyup.shift.down='keyupShiftDown' @keyup.shift.left='keyupShiftLeft' @keyup.shift.right='keyupShiftRight' keyname=" + keyname + " weighing=" + weighing + " placeholder=" + placeholder + " trIndex=" + trindex + " tdIndex=" + tdindex + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + ">"; //v-model="+keyname+"
+            String selectText = " <el-select id=" + keyname + " v-model=" + vmode + " @keydown.shift.up='keyupShiftUp' @keydown.shift.down='keyupShiftDown' @keydown.shift.left='keyupShiftLeft' @keydown.shift.right='keyupShiftRight' keyname=" + keyname + " weighing=" + weighing + " placeholder=" + placeholder + " trIndex=" + trindex + " tdIndex=" + tdindex + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + ">"; //v-model="+keyname+"
             List<TextdictInfo_vo> optionList = textdictInfo.getTextInfo();
             if (optionList != null && optionList.size() >= 1) {
                 for (int i = 0; i < optionList.size(); i++)
@@ -272,7 +272,7 @@ public class TextdictInfoController extends BladeController {
             element.empty().append(selectText);
         } else if (textdictInfo.getTextId().equals("radio")) { // 单选按钮
 
-            String radioText = "<el-radio-group @keyup.shift.up='keyupShiftUp' @keyup.shift.down='keyupShiftDown' @keyup.shift.left='keyupShiftLeft' @keyup.shift.right='keyupShiftRight'  v-model=" + vmode + " keyname=" + keyname + " weighing=" + weighing + " placeholder=" + placeholder + " trIndex=" + trindex + " tdIndex=" + tdindex + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + ">";
+            String radioText = "<el-radio-group id=" + keyname + " @keyDowns='dateKeydown' v-model=" + vmode + " keyname=" + keyname + " weighing=" + weighing + " placeholder=" + placeholder + " trIndex=" + trindex + " tdIndex=" + tdindex + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + ">";
             List<TextdictInfo_vo> optionList = textdictInfo.getTextInfo();
             if (optionList != null && optionList.size() >= 1) {
                 for (int i = 0; i < optionList.size(); i++)
@@ -290,7 +290,7 @@ public class TextdictInfoController extends BladeController {
                     jsonObject.put("name", optionList.get(i).getDictValue());
                     objs.add(jsonObject);
                 }
-                String checkbox = "<hc-form-checkbox-group  @keyup.shift.up='keyupShiftUp' @keyup.shift.down='keyupShiftDown' @keyup.shift.left='keyupShiftLeft' @keyup.shift.right='keyupShiftRight' :objs='" + objs + "'  @change='checkboxGroupChange' :val=" + vmode + " v-model=" + vmode + " keyname=" + keyname + " weighing=" + weighing + " placeholder=" + placeholder + " trIndex=" + trindex + " tdIndex=" + tdindex + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + "> </hc-form-checkbox-group>";
+                String checkbox = "<hc-form-checkbox-group   @keyDowns='dateKeydown' :objs='" + objs + "'  @change='checkboxGroupChange' :val=" + vmode + " v-model=" + vmode + " keyname=" + keyname + " weighing=" + weighing + " placeholder=" + placeholder + " trIndex=" + trindex + " tdIndex=" + tdindex + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + "> </hc-form-checkbox-group>";
                 element.empty().append(checkbox);
             }
         } else if (textdictInfo.getTextId().equals("date")) { // 日期--年月日时分秒
@@ -313,9 +313,9 @@ public class TextdictInfoController extends BladeController {
             element.children().get(0).attr("@change", "datePickerChange($event,'" + keyname + "')");
 
         } else if (textdictInfo.getTextId().equals("img")) {
-            element.empty().append("<hc-table-form-upload @keyup.shift.up='keyupShiftUp' @keyup.shift.down='keyupShiftDown' @keyup.shift.left='keyupShiftLeft' @keyup.shift.right='keyupShiftRight'  :src='" + vmode + "' placeholder=" + placeholder + " v-model=" + vmode + "  keyName=" + keyname + " weighing=" + weighing + "  @success='formUploadSuccess' @del='delTableFormFile' trIndex=" + trindex + " tdIndex=" + tdindex + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + "></hc-table-form-upload> ");
+            element.empty().append("<hc-table-form-upload @keydown.shift.up='keyupShiftUp' @keydown.shift.down='keyupShiftDown' @keydown.shift.left='keyupShiftLeft' @keydown.shift.right='keyupShiftRight'  :src='" + vmode + "' placeholder=" + placeholder + " v-model=" + vmode + "  keyName=" + keyname + " weighing=" + weighing + "  @success='formUploadSuccess' @del='delTableFormFile' trIndex=" + trindex + " tdIndex=" + tdindex + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + "></hc-table-form-upload> ");
         } else if (textdictInfo.getTextId().equals("searchSelect")) { //搜索框
-            element.empty().append("<hc-form-select-search @keyup.shift.up='keyupShiftUp' @keyup.shift.down='keyupShiftDown' @keyup.shift.left='keyupShiftLeft' @keyup.shift.right='keyupShiftRight' type='dap_site_data' :val=" + vmode + " contractId=''  pkeyId='' @change='formRemoteChange' v-model=" + vmode + " placeholder=" + placeholder + " keyname=" + keyname + " weighing=" + weighing + "  @contextmenu.prevent.native='RightClick(" + parm + ")' trIndex=" + trindex + " tdIndex=" + tdindex + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + " style='width:100%;height:100%' > </hc-form-select-search>");
+            element.empty().append("<hc-form-select-search id=" + keyname + " @keydown.shift.up='keyupShiftUp' @keydown.shift.down='keyupShiftDown' @keydown.shift.left='keyupShiftLeft' @keydown.shift.right='keyupShiftRight' type='dap_site_data' :val=" + vmode + " contractId=''  pkeyId='' @change='formRemoteChange' v-model=" + vmode + " placeholder=" + placeholder + " keyname=" + keyname + " weighing=" + weighing + "  @contextmenu.prevent.native='RightClick(" + parm + ")' trIndex=" + trindex + " tdIndex=" + tdindex + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + " style='width:100%;height:100%' > </hc-form-select-search>");
         }
         element.attr("@click", "getInformation(" + oncklickText + ")");
         File writefile = new File(wbsTreePrivate.getHtmlUrl());

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

@@ -189,7 +189,7 @@ public class WbsFormElementController extends BladeController {
 
 
     /**
-     * 提交清表关联公有Wbs树并创建元素
+     * 提交@keydown公有Wbs树并创建元素
      */
     @ApiOperationSupport(order = 11)
     @ApiOperation(value = "提交清表关联公有Wbs树并创建元素", notes = "节点id、表名、元素DTO")

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

@@ -37,6 +37,13 @@ public class WbsTreeContractController extends BladeController {
     public R searchNodeAllTable(String primaryKeyId, String type, String contractId, String projectId) {
         List<AppWbsTreeContractVO> list = iWbsTreeContractService.searchNodeAllTable(primaryKeyId, type, contractId, projectId);
         if (list.size() > 0) {
+            list.stream().forEach(l->{
+                if (StringUtils.isNotBlank(l.getHtmlUrl())){
+                    l.setIsLinkTable(2);
+                }else {
+                    l.setIsLinkTable(1);
+                }
+            });
             return R.data(list);
         }
         return R.fail(200, "未查询到数据");

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

@@ -1,15 +1,13 @@
 package org.springblade.manager.controller;
 
-import com.alibaba.fastjson.JSONArray;
-import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
-import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
 import com.mixsmart.utils.StringUtils;
 import io.swagger.annotations.*;
 import lombok.AllArgsConstructor;
+import org.springblade.business.entity.TrialSelfInspectionRecord;
 import org.springblade.business.vo.SaveLogContractVO;
 import org.springblade.common.utils.SnowFlakeUtil;
 import org.springblade.core.boot.ctrl.BladeController;
@@ -20,10 +18,8 @@ import org.springblade.core.mp.support.Query;
 import org.springblade.core.secure.BladeUser;
 import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.support.Kv;
-import org.springblade.core.tool.utils.BeanUtil;
 import org.springblade.core.tool.utils.ObjectUtil;
 import org.springblade.core.tool.utils.StringUtil;
-import org.springblade.manager.bean.TableInfo;
 import org.springblade.manager.dto.WbsTreePrivateDTO2;
 import org.springblade.manager.dto.WbsTreePrivateDTO3;
 import org.springblade.manager.entity.*;
@@ -574,7 +570,7 @@ public class WbsTreePrivateController extends BladeController {
             @ApiImplicitParam(name = "primaryKeyIds", value = "表的注解ids(多个以,隔开)", required = true),
             @ApiImplicitParam(name = "projectId", value = "合同段Id", required = true),
     })
-    public R addProjectTabInfo(String primaryKeyIds, String projectId) {
+    public R addProjectTabInfo(String primaryKeyIds, String projectId) throws IOException {
         return wbsTreePrivateService.addWbsTreeProjectInfo(primaryKeyIds, projectId);
     }
 
@@ -615,19 +611,18 @@ public class WbsTreePrivateController extends BladeController {
     @ApiOperationSupport(order = 22)
     @ApiOperation(value = "试验-根据所属方查询当前节点表信息", notes = "传入节点primaryKeyId、所属方type=1施工/=2监理、表单类型tableType=1记录表/=2报告单、合同段id、项目id、isAdd=是否新增、试验记录id")
     public R<List<WbsTreePrivateVO4>> searchNodeAllTable(String primaryKeyId, String type, String tableType, String contractId, String projectId, Integer isAdd, Long id) {
-        List<WbsTreePrivate> wbsTreePrivates = wbsTreePrivateService.searchNodeAllTable(primaryKeyId, type, tableType, contractId, projectId, isAdd, id);
-        List<WbsTreePrivateVO4> wbsTreePrivateVO4s = BeanUtil.copyProperties(wbsTreePrivates, WbsTreePrivateVO4.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(1);
+                //treePrivate.setIsBussShow(1); //新增时通过项目wbs表的isBussShow字段单独控制
                 treePrivate.setIsTabPdf(1);
                 treePrivate.setTabFileType(1);
             }
 
-            //编辑
+            //试验编辑
             if (ObjectUtil.isNotEmpty(id)) {
                 //获取当前试验记录信息中表的按钮状态
                 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;
@@ -636,9 +631,14 @@ public class WbsTreePrivateController extends BladeController {
                 //按钮状态
                 TrialSelfDataRecord record = map.get(treePrivate.getPKeyId());
                 if (record != null) {
-                    treePrivate.setIsBussShow(record.getIsBussShow());
+                    treePrivate.setIsBussShow(record.getIsBussShow()); //编辑时通过试验记录关联关系控制
                     treePrivate.setIsTabPdf(record.getIsTabPdf());
                     treePrivate.setTabFileType(record.getIsTabFileType());
+                } else {
+                    treePrivate.setPdfUrl(null);
+                    //treePrivate.setIsBussShow(1); //没有记录的就根据项目wbs表的isBussShow字段单独控制
+                    treePrivate.setIsTabPdf(1);
+                    treePrivate.setTabFileType(1);
                 }
 
                 //表单数据

+ 35 - 51
blade-service/blade-manager/src/main/java/org/springblade/manager/feign/ExcelTabClientImpl.java

@@ -3,6 +3,7 @@ package org.springblade.manager.feign;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import lombok.AllArgsConstructor;
+import org.springblade.business.dto.TrialSelfInspectionRecordDTO;
 import org.springblade.business.entity.InformationQuery;
 import org.springblade.business.entity.TrialSelfInspectionRecord;
 import org.springblade.business.feign.InformationQueryClient;
@@ -10,6 +11,8 @@ import org.springblade.business.vo.TrialRawMaterialSelfRecord;
 import org.springblade.common.constant.CommonConstant;
 import org.springblade.common.utils.SnowFlakeUtil;
 import org.springblade.core.oss.model.BladeFile;
+import org.springblade.core.tool.beans.BeanProperty;
+import org.springblade.core.tool.utils.BeanUtil;
 import org.springblade.core.tool.utils.Func;
 import org.springblade.core.tool.utils.ObjectUtil;
 import org.springblade.core.tool.utils.ResourceUtil;
@@ -20,13 +23,17 @@ import org.springblade.manager.service.IExcelTabService;
 import org.springblade.manager.utils.FileUtils;
 import org.springblade.resource.feign.NewIOSSClient;
 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.RestController;
 
 import java.io.File;
+import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
 import java.util.stream.Collectors;
 
 @RestController
@@ -44,22 +51,22 @@ public class ExcelTabClientImpl implements ExcelTabClient {
     }
 
     @Override
-    public String saveTabData(Integer isBatchSave, JSONObject dataInfo, Integer type, String tableType, Long id, String tabIds) throws Exception {
+    public String saveTabData(TrialSelfInspectionRecordDTO dto, Integer isBatchSave,Integer type, String tableType, Long id, String tabIds) throws Exception {
         //通用参数
-        JSONArray dataArray = dataInfo.getJSONArray("orderList");
+        String pdfUrl = "";
+        JSONArray dataArray = dto.getDataInfo().getJSONArray("orderList");
         JSONObject table = dataArray.getJSONObject(0);
         String nodeId = table.getString("nodeId");
         String projectId = table.getString("projectId");
         String contractId = table.getString("contractId");
 
-        List<TableInfo> tableInfoList = this.excelTabService.getTableInfoList(dataArray);
-
-        String pdfUrl = "";
+        //获取表模板,已处理隐藏表问题
+        List<TableInfo> tableInfoList = this.excelTabService.getTableInfoListTrial(dataArray, tabIds);
 
-        //TODO ------入库-试验填报数据,当前记录id作为groupId------
+        //------试验填报数据保存,当前记录id作为groupId------
         this.excelTabService.saveOrUpdateInfoTrial(tableInfoList, id);
 
-        //TODO ------公式填充------
+        //------公式填充------
         try {
             this.excelTabService.formulaFillData(tableInfoList, Long.parseLong(nodeId));
         } catch (Exception e) {
@@ -67,11 +74,11 @@ public class ExcelTabClientImpl implements ExcelTabClient {
         }
 
         if (isBatchSave == 0) {
-            //TODO ------单表PDF保存------
+            //------单表PDF保存------
             TableInfo tableInfo = tableInfoList.stream().findAny().orElse(null);
             assert tableInfo != null;
             if (tabIds.contains(tableInfo.getPkeyId())) {
-
+                //构造pdf
                 excelTabService.getBussPDFTrial(Long.valueOf(tableInfo.getPkeyId()), contractId, id);
 
                 //重新合并pdf
@@ -80,22 +87,21 @@ public class ExcelTabClientImpl implements ExcelTabClient {
                 List<String> pdfList = query.stream().map(TrialSelfDataRecord::getPdfUrl).collect(Collectors.toList());
 
                 String file_path = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
-                String pdfPath2 = file_path + "/pdf//" + id + "_2.pdf";
-                File tabPdf2 = ResourceUtil.getFile(pdfPath2);
-                if (tabPdf2.exists()) {
-                    tabPdf2.delete();
+                String pdfPath = file_path + "/pdf//" + id + "_2.pdf";
+                File tabPdf = ResourceUtil.getFile(pdfPath);
+                if (tabPdf.exists()) {
+                    tabPdf.delete();
                 }
-                FileUtils.mergePdfPublicMethods(pdfList, pdfPath2);
-                BladeFile bladeFile = newIOSSClient.uploadFile(id + "2.pdf", pdfPath2);
+                FileUtils.mergePdfPublicMethods(pdfList, pdfPath);
+                BladeFile bladeFile = newIOSSClient.uploadFile(id + "2.pdf", pdfPath);
 
                 String sqlUpdate = "update u_trial_self_inspection_record set pdf_url = '" + bladeFile.getLink() + "' where id = " + id;
                 jdbcTemplate.execute(sqlUpdate);
 
-                //获取试验记录id的试验项目名称
+                //获取试验记录id的试验项目名称,重新合并pdf集合(解决单表保存后上报找不到题名问题)
                 String sql2 = "select trial_project_name from u_trial_self_inspection_record where id = " + id;
                 TrialSelfInspectionRecord obj = jdbcTemplate.query(sql2, new BeanPropertyRowMapper<>(TrialSelfInspectionRecord.class)).stream().findAny().orElse(null);
                 assert obj != null;
-                //重新合并pdf集合(解决单表保存后上报找不到题名问题)
                 String querySql = "select id from u_information_query where classify ='" + type + "' and wbs_id ='" + id + "' and contract_id ='" + contractId + "'";
                 List<InformationQuery> query2 = jdbcTemplate.query(querySql, new BeanPropertyRowMapper<>(InformationQuery.class));
                 if (query2.size() > 0) {
@@ -104,34 +110,20 @@ public class ExcelTabClientImpl implements ExcelTabClient {
                 } else {
                     informationQueryClient.saveData(id.toString(), projectId, contractId, type.toString(), bladeFile.getLink(), obj.getTrialProjectName());
                 }
-
-                //修改原材料检测报告原始pdfUrl
-                String sql3 = "select id from u_trial_raw_material_self_record where self_record_id =" + id;
-                TrialRawMaterialSelfRecord record = jdbcTemplate.query(sql3, new BeanPropertyRowMapper<>(TrialRawMaterialSelfRecord.class)).stream().findAny().orElse(null);
-                if (ObjectUtil.isNotEmpty(record)) {
-                    String sqlUpdate2 = "update u_trial_raw_material_self_record set old_pdf_url = '" + bladeFile.getLink() + "' where self_record_id =" + id;
-                    jdbcTemplate.execute(sqlUpdate2);
-                }
             }
 
         } else if (isBatchSave == 1) {
-            //TODO ------多表PDF保存------
-            pdfUrl = excelTabService.getBussPDFSTrial(nodeId,
-                    tableType, //tableType=表类型 1=记录表 2=报告单
-                    String.valueOf(type), //type=所属方 1=施工质检 2=监理抽检
-                    contractId, //合同段id
-                    projectId, //项目id
-                    id,  //记录id
-                    tabIds //新增的表的pKeyIds
-            );
-
-            //TODO ------修改原材料检测报告原始pdfUrl------
-            String sql = "select id from u_trial_raw_material_self_record where self_record_id =" + id;
-            TrialRawMaterialSelfRecord record = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(TrialRawMaterialSelfRecord.class)).stream().findAny().orElse(null);
-            if (ObjectUtil.isNotEmpty(record)) {
-                String sqlUpdate = "update u_trial_raw_material_self_record set old_pdf_url = '" + pdfUrl + "' where self_record_id =" + id;
-                jdbcTemplate.execute(sqlUpdate);
-            }
+            /**
+             * ------多表PDF保存------
+             * tableType=表类型 1=记录表 2=报告单
+             * type=所属方 1=施工质检 2=监理抽检
+             * contractId=合同段id
+             * projectId=项目id
+             * id=记录id
+             * tabIds=表的pKeyIds
+             */
+            pdfUrl = excelTabService.getBussPDFSTrial(nodeId, tableType, String.valueOf(type), contractId, projectId, id, tabIds);
+
         }
         return pdfUrl;
     }
@@ -143,15 +135,7 @@ public class ExcelTabClientImpl implements ExcelTabClient {
 
     @Override
     public String getBussPDFSTrial(String nodeId, String tableType, String classify, String contractId, String projectId, String id, String tabIds) throws Exception {
-        //合并PDF加载
-        return excelTabService.getBussPDFSTrial(nodeId,
-                tableType, //tableType=表类型 1=记录表 2=报告单
-                classify, //type=所属方 1=施工质检 2=监理抽检
-                contractId, //合同段id
-                projectId, //项目id
-                Long.parseLong(id), //记录id
-                tabIds //新增的表的pKeyIds
-        );
+        return excelTabService.getBussPDFSTrial(nodeId, tableType, classify, contractId, projectId, Long.parseLong(id), tabIds);
     }
 
 

+ 10 - 25
blade-service/blade-manager/src/main/java/org/springblade/manager/feign/WbsTreePrivateClientImpl.java

@@ -7,18 +7,19 @@ import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.mixsmart.utils.StringUtils;
 import lombok.AllArgsConstructor;
+import org.apache.commons.lang3.ObjectUtils;
 import org.springblade.common.utils.SnowFlakeUtil;
-import org.springblade.core.log.exception.ServiceException;
-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.WbsTreeContract;
+import org.springblade.manager.entity.TrialSelfDataRecord;
 import org.springblade.manager.entity.WbsTreePrivate;
 import org.springblade.manager.service.IWbsTreePrivateService;
 import org.springblade.manager.vo.WbsTreeContractTreeVOS;
 import org.springblade.manager.vo.WbsTreePrivateVO;
+import org.springframework.jdbc.core.BeanPropertyRowMapper;
 import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
 import java.util.*;
@@ -65,23 +66,8 @@ public class WbsTreePrivateClientImpl implements WbsTreePrivateClient {
     }
 
     @Override
-    public boolean showBussTab(Long pkeyId, Integer status) {
-        WbsTreePrivate wbsTreePrivate = wbsTreePrivateService.getBaseMapper().selectOne(Wrappers.<WbsTreePrivate>query().lambda()
-                .eq(WbsTreePrivate::getPKeyId, pkeyId));
-        if (wbsTreePrivate == null) {
-            throw new ServiceException("未找到当前表单");
-        }
-        UpdateWrapper<WbsTreePrivate> updateWrapper = new UpdateWrapper<>();
-        updateWrapper.in("p_key_id", pkeyId);
-        updateWrapper.set("is_buss_show", status);
-        wbsTreePrivateService.update(updateWrapper);
-        return true;
-    }
-
-    @Override
-    public boolean copyBussTab(Long pKeyId) {
-        WbsTreePrivate wbsTreePrivate = wbsTreePrivateService.getBaseMapper().selectOne(Wrappers.<WbsTreePrivate>query().lambda()
-                .eq(WbsTreePrivate::getPKeyId, pKeyId));
+    public boolean copyBussTab(Long pKeyId, Long id) {
+        WbsTreePrivate wbsTreePrivate = wbsTreePrivateService.getBaseMapper().selectOne(Wrappers.<WbsTreePrivate>query().lambda().eq(WbsTreePrivate::getPKeyId, pKeyId));
 
         List<WbsTreePrivate> wbsTreePrivateList = wbsTreePrivateService.getBaseMapper().selectList(Wrappers.<WbsTreePrivate>query().lambda()
                 .eq(WbsTreePrivate::getId, wbsTreePrivate.getId())
@@ -116,7 +102,7 @@ public class WbsTreePrivateClientImpl implements WbsTreePrivateClient {
         Map<String, Object> stringObjectMap = jdbcTemplate.queryForMap(colkeys);
         colkeys = stringObjectMap.get("colkeys") + "";
         //复制表数据
-        String querySql = "select " + colkeys + " from " + tabName + " where p_key_id=" + pKeyId;
+        String querySql = "select " + colkeys + " from " + tabName + " where p_key_id=" + pKeyId + " and group_id = " + id;
         List<Map<String, Object>> dataList = jdbcTemplate.queryForList(querySql);
         if (dataList != null && dataList.size() >= 1) {
             Map<String, Object> dataMap2 = dataList.get(0);
@@ -129,8 +115,8 @@ public class WbsTreePrivateClientImpl implements WbsTreePrivateClient {
 
             sqlInfo = "INSERT INTO " + tabName + " ( ";
 
-            String keyStr = "id,p_key_id,";
-            String valStr = SnowFlakeUtil.getId() + "," + wbsTreePrivate.getPKeyId() + ",";
+            String keyStr = "id,p_key_id,group_id";
+            String valStr = SnowFlakeUtil.getId() + "," + wbsTreePrivate.getPKeyId() + "," + id + ",";
 
             for (String keys : dataMap2.keySet()) {
                 if (!(dataMap2.get(keys) + "").equals("null")) {
@@ -143,7 +129,6 @@ public class WbsTreePrivateClientImpl implements WbsTreePrivateClient {
 
             sqlInfo = sqlInfo + keyStr + ") VALUES (" + valStr + ")";
 
-            //huangJN 保存成功后调用生成资料查询列表数据
             jdbcTemplate.execute(sqlInfo);
         }
         wbsTreePrivateService.save(wbsTreePrivate);
@@ -174,7 +159,7 @@ public class WbsTreePrivateClientImpl implements WbsTreePrivateClient {
     }
 
     @Override
-    public List<WbsTreePrivate> queryChildByParent(WbsTreePrivate nodeObj , String queryTable, String classify) {
+    public List<WbsTreePrivate> queryChildByParent(WbsTreePrivate nodeObj, String queryTable, String classify) {
         if ("queryTable".equals(queryTable)) {
             LambdaQueryWrapper<WbsTreePrivate> wrapper = Wrappers.lambdaQuery();
             wrapper.eq(WbsTreePrivate::getParentId, nodeObj.getId()).eq(WbsTreePrivate::getProjectId, nodeObj.getProjectId()).eq(WbsTreePrivate::getType, "2");

+ 7 - 5
blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/FormulaTurnPoint.java

@@ -1,6 +1,7 @@
 package org.springblade.manager.formula.impl;
 
 import cn.hutool.core.util.ReUtil;
+import com.mixsmart.utils.FormulaUtils;
 import com.mixsmart.utils.StringUtils;
 import lombok.Data;
 import org.springblade.core.tool.utils.Func;
@@ -77,13 +78,14 @@ public class FormulaTurnPoint implements FormulaStrategy {
                 ai.set(0);
                 dataSourceMap.forEach((k,v)->{
                     List<Object> dl =dataMap.get(ai.getAndIncrement());
-                    List<ElementData> list = v.getValues();
+//                    List<ElementData> list = v.getValues();
                     v.setUpdate(1);
                     v.setFinished(Boolean.TRUE);
-                    for(int n=0;n<dl.size();n++){
-                        ElementData ed = list.get(n);
-                        ed.setValue(dl.get(n));
-                    }
+                    FormulaUtils.write(v,dl);
+//                    for(int n=0;n<dl.size();n++){
+//                        ElementData ed = list.get(n);
+//                        ed.setValue(dl.get(n));
+//                    }
                 });
             }
 

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

@@ -29,6 +29,7 @@
         <result column="is_interface_node" property="isInterfaceNode"/>
         <result column="interface_type" property="interfaceType"/>
         <result column="sort" property="sort"/>
+        <result column="tree_sort" property="treeSort"/>
         <result column="remark" property="remark"/>
         <result column="project_type" property="projectType"/>
         <result column="storage_type" property="storageType"/>

+ 15 - 39
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/ContractInfoMapper.java

@@ -1,7 +1,6 @@
 package org.springblade.manager.mapper;
 
 import org.apache.ibatis.annotations.Param;
-import org.apache.ibatis.annotations.Select;
 import org.springblade.manager.dto.FindAllUserByConditionDTO;
 import org.springblade.manager.entity.ContractInfo;
 import org.springblade.manager.entity.ContractRelationJlyz;
@@ -19,8 +18,7 @@ public interface ContractInfoMapper extends BaseMapper<ContractInfo> {
 
     List<ContractInfo> selectContractByProjectIds(@Param("ids") List<Long> ids);
 
-    List<ContractInfoVO> selectContractInfoPage(IPage page,
-                                                ContractInfoVO contractInfo);
+    List<ContractInfoVO> selectContractInfoPage(IPage page, ContractInfoVO contractInfo);
 
     List<ContractlnfoCountVO> selectContractInfoCount();
 
@@ -28,44 +26,31 @@ public interface ContractInfoMapper extends BaseMapper<ContractInfo> {
 
     List<CRolePostVO> findJobByRoleId(@Param("id") String id);
 
-    List<UserVO2> findAllUserByCondition(IPage page,
-                                         @Param("Values") FindAllUserByConditionDTO values);
+    List<UserVO2> findAllUserByCondition(IPage page, @Param("Values") FindAllUserByConditionDTO values);
 
-    List<User> findUserListByCondition(IPage page,
-                                       @Param("Values") FindAllUserByConditionDTO values);
+    List<User> findUserListByCondition(IPage page, @Param("Values") FindAllUserByConditionDTO values);
 
-    List<User> findUserInfoByCondition(@Param("rId") String rId,
-                                       @Param("pId") String pId,
-                                       @Param("userName") String userName);
+    List<User> findUserInfoByCondition(@Param("rId") String rId, @Param("pId") String pId, @Param("userName") String userName);
 
     List<User> findUserList();
 
-    Integer updatePasswordByUserId(@Param("userId") String userId,
-                                   @Param("password") String password);
+    Integer updatePasswordByUserId(@Param("userId") String userId, @Param("password") String password);
 
     Boolean deleteFile(@Param("url") String url);
 
-    List<WbsTreeContractTreeVO> tree(@Param("wbsId") String wbsId,
-                                     @Param("projectId") String projectId,
-                                     @Param("contractId") String contractId,
-                                     @Param("wbsType") Integer wbsType,
-                                     @Param("parentId") String parentId);
+    List<WbsTreeContractTreeVO> tree(@Param("wbsId") String wbsId, @Param("projectId") String projectId, @Param("contractId") String contractId, @Param("wbsType") Integer wbsType, @Param("parentId") String parentId);
 
-    List<WbsTreeContractVO> tree2(@Param("wbsId") Long wbsId,
-                                  @Param("projectId") Long projectId,
-                                  @Param("contractId") Long contractId,
-                                  @Param("wbsType") Integer wbsType,
-                                  @Param("parentId") String parentId,
-                                  @Param("queryValue") String queryValue);
+    List<WbsTreeContractVO> tree2(@Param("wbsId") Long wbsId, @Param("projectId") Long projectId, @Param("contractId") Long contractId, @Param("wbsType") Integer wbsType, @Param("parentId") String parentId, @Param("queryValue") String queryValue);
 
-    List<WbsTreeContractVO> tree3(@Param("wbsId") String wbsId,
-                                  @Param("projectId") String projectId,
-                                  @Param("contractId") String contractId,
-                                  @Param("wbsType") Integer wbsType,
-                                  @Param("parentId") String parentId);
+    List<WbsTreeContractVO> tree3(@Param("wbsId") String wbsId, @Param("projectId") String projectId, @Param("contractId") String contractId, @Param("wbsType") Integer wbsType, @Param("parentId") String parentId);
 
-    List<WbsTreeContractVO> tree4(@Param("contractId") String contractId,
-                                  @Param("parentId") String parentId);
+    List<WbsTreeContractVO> tree4(@Param("contractId") String contractId, @Param("parentId") String parentId);
+
+    List<WbsTreeContractTreeAllVO> tree5(@Param("contractId") Long contractId);
+
+    List<WbsTreeContractVO6> tree6(@Param("wbsId") Long wbsId, @Param("projectId") Long projectId, @Param("contractId") Long contractId);
+
+    List<TrialRecordZJTreeVO> trialRelationTree(@Param("projectId") Long projectId, @Param("contractId") Long contractId, @Param("wbsId") Long wbsId);
 
     List<WbsTreeContractVO3> selectLists(@Param("contractInfo") ContractInfo contractInfo, @Param("contractType") Integer contractType);
 
@@ -81,13 +66,4 @@ public interface ContractInfoMapper extends BaseMapper<ContractInfo> {
 
     List<UserContractInfoVO> userListByIds(@Param("ids") List<String> ids);
 
-    @Select("select quality_node_id from u_trial_self_quality_project where self_id = #{selfId}")
-    List<String> queryList(@Param("selfId") String selfId);
-
-    List<WbsTreeContractTreeAllVO> tree5(@Param("contractId") Long contractId);
-
-    List<WbsTreeContractVO6> tree6(@Param("wbsId") Long wbsId,
-                                  @Param("projectId") Long projectId,
-                                  @Param("contractId") Long contractId);
-
 }

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

@@ -445,7 +445,7 @@
         d.node_name AS "nodeName",
         d.node_type AS "nodeType",
         d.id AS "value",
-        d.id AS "key"
+        d.id AS "key",
         sort
         FROM m_wbs_tree_contract d
         WHERE
@@ -464,4 +464,22 @@
         ORDER BY d.sort
     </select>
 
+    <select id="trialRelationTree" resultType="org.springblade.manager.vo.TrialRecordZJTreeVO">
+        SELECT
+            d.p_key_id AS "primaryKeyId",
+            d.id AS id,
+            d.full_name AS fullName,
+            d.parent_id AS "parentId"
+        FROM m_wbs_tree_contract d
+        WHERE
+            d.is_deleted = 0
+        AND d.status = 1
+        AND d.type = 1
+        AND wbs_type = 1
+        AND project_id = #{projectId}
+        AND contract_id = #{contractId}
+        AND wbs_id = #{wbsId}
+        ORDER BY d.sort,d.create_time
+    </select>
+
 </mapper>

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

@@ -100,7 +100,7 @@
         and a.parent_id = 0
         and a.project_id = b.id
         and b.is_deleted = 0
-        union ALL
+        union
         SELECT id, c.wbs_name, 1 as wbsType FROM m_wbs_info c where c.is_deleted = 0
         )d where 1=1
         <if test="wbstype!=null and wbstype!=''">
@@ -163,6 +163,7 @@
         AND dept.project_id = #{wbsId}
         /* AND dept.type = 1
         AND status = 1*/
+        GROUP BY dept.id
         ORDER BY dept.sort
     </select>
 

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

@@ -50,6 +50,7 @@
         <result column="import_matching_info" property="importMatchingInfo"/>
         <result column="is_concealed_works_node" property="isConcealedWorksNode"/>
         <result column="is_ele" property="isEle"/>
+        <result column="tab_group_id" property="tabGroupId"/>
     </resultMap>
 
 

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

@@ -8,10 +8,7 @@ import org.springblade.manager.entity.TableInfo;
 import org.springblade.manager.entity.WbsTree;
 import org.springblade.manager.entity.WbsTreePrivate;
 import org.springblade.manager.injector.EasyBaseMapper;
-import org.springblade.manager.vo.TreeNodeVOByTabType;
-import org.springblade.manager.vo.WbsNodeTableVO;
-import org.springblade.manager.vo.WbsTreePrivateVO;
-import org.springblade.manager.vo.WbsTreeVO2;
+import org.springblade.manager.vo.*;
 
 import java.util.List;
 
@@ -86,11 +83,12 @@ public interface WbsTreePrivateMapper extends EasyBaseMapper<WbsTreePrivate> {
 
     void delTabProjectById(String pKeyId,String projectId);
 
-    List<WbsTreePrivate> selectWbsTreeContractList(List<String> roleAndTabOwners,String tableType, String projectId, String wbsId, Long parentId, List<String> tableOwnerList);
+    List<WbsTreePrivateVO4> selectWbsTreeContractList(List<String> roleAndTabOwners, String tableType, String projectId, String wbsId, Long parentId, List<String> tableOwnerList);
 
     //删除表单信息
     void delTableById(String pKeyId);
 
     List<TableInfo> selectTabInfoAll();
 
+    void updateBatchByPKeyId(@Param("list")List<WbsTreePrivate> wbsTreePrivateList);
 }

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

@@ -312,6 +312,13 @@
             AND is_deleted = 0
         </foreach>
     </update>
+    <update id="updateBatchByPKeyId">
+        <foreach item="item" collection="list" separator=";">
+            UPDATE m_wbs_tree_private
+            <set>html_url = #{item.htmlUrl}</set>
+            where p_key_id = #{item.pKeyId}
+        </foreach>
+    </update>
 
     <select id="lazyTree" resultMap="treeNodeResultMap">
         SELECT
@@ -685,8 +692,30 @@
 
     </select>
 
-    <select id="selectWbsTreeContractList" resultType="org.springblade.manager.entity.WbsTreePrivate">
-        SELECT * FROM
+    <select id="selectWbsTreeContractList" resultType="org.springblade.manager.vo.WbsTreePrivateVO4">
+        SELECT
+            p_key_id,
+            node_name,
+            node_type,
+            is_link_table,
+            is_tab_pdf,
+            is_buss_show,
+            tab_file_type,
+            wbs_id,
+            wbs_type,
+            html_url,
+            excel_id,
+            project_id,
+            type,
+            table_type,
+            table_owner,
+            init_table_name,
+            init_table_id,
+            fill_rate,
+            pdf_url,
+            sort,
+            create_time
+        FROM
         m_wbs_tree_private
         WHERE project_id = #{projectId}
         AND wbs_id = #{wbsId}

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

@@ -48,6 +48,10 @@ public interface IContractInfoService extends BaseService<ContractInfo> {
 
     List<WbsTreeContractVO6> tree6List(String wbsId, String projectId, String contractId);
 
+    List<WbsTreeContractVO6> tree6(String wbsId, String projectId, String contractId);
+
+    List<WbsTreeContractVO6> tree8(String wbsId, String projectId, String contractId);
+
     List<WbsTreeContractVO2> treeTwo(String projectId);
 
     List<WbsTreeContractTreeVO> queryContractWbsTreeByContractIdAndType(String contractId, Integer wbsType, String parentId);

+ 6 - 1
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 org.springblade.business.dto.TrialSelfInspectionRecordDTO;
 import org.springblade.core.tool.api.R;
 import org.springblade.manager.bean.TableInfo;
 import org.springblade.manager.entity.ExcelEditCallback;
@@ -113,9 +114,13 @@ public interface IExcelTabService extends BaseService<ExcelTab> {
     // 多个pdf 合并
     void getBussPdfs(String nodeId, String classify, String contractId, String projectId) throws Exception;
 
-
     // 试验
 
+    /**
+     * 表格数据封装 - 试验
+     */
+    List<TableInfo> getTableInfoListTrial(JSONArray dataArray, String tabIds);
+
     /**
      * 结果信息持久化 - 试验
      */

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

@@ -11,6 +11,7 @@ import org.springframework.web.multipart.MultipartFile;
 
 import java.io.IOException;
 import java.util.List;
+import java.util.Map;
 
 public interface IWbsTreeContractService extends BaseService<WbsTreeContract> {
 

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

@@ -9,6 +9,7 @@ import org.springblade.manager.entity.WbsTree;
 import org.springblade.manager.entity.WbsTreePrivate;
 import org.springblade.manager.vo.*;
 
+import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.util.List;
 
@@ -60,7 +61,7 @@ public interface IWbsTreePrivateService extends BaseService<WbsTreePrivate> {
     R addWbsTreeContractInfo(String nodeId, String primaryKeyIds, long contractId);
 
     // 向项目添加元素
-    R addWbsTreeProjectInfo(String primaryKeyIds, String projectId);
+    R addWbsTreeProjectInfo(String primaryKeyIds, String projectId) throws IOException;
 
     R delTabProjectById(String primaryKeyIds, String projectId);
 
@@ -70,7 +71,7 @@ public interface IWbsTreePrivateService extends BaseService<WbsTreePrivate> {
     // 元素关联
     R saveLinkeTableInfo(String tabId, String linkids, String type, String wbsId);
 
-    List<WbsTreePrivate> searchNodeAllTable(String primaryKeyId, String type, String tableType, String contractId, String projectId, Integer isAdd, Long id);
+    List<WbsTreePrivateVO4> searchNodeAllTable(String primaryKeyId, String type, String tableType, String contractId, String projectId, Integer isAdd, Long id);
 
     Object getExcelHtml(String primaryKeyId) throws IOException;
 
@@ -78,4 +79,7 @@ public interface IWbsTreePrivateService extends BaseService<WbsTreePrivate> {
 
     void eVisInfoRepeatDel(String pid);
 
+    //批量重新保存文件htmlUrl
+    void batchResetHtmlUrl(List<WbsTreePrivate> wbsTreePrivateList) throws IOException, InterruptedException;
+
 }

+ 136 - 14
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ArTreeContractInitServiceImpl.java

@@ -3,6 +3,8 @@ package org.springblade.manager.service.impl;
 import com.mixsmart.utils.StringUtils;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.AllArgsConstructor;
+import org.springblade.archive.entity.ArchivesAuto;
+import org.springblade.archive.feign.ArchiveAutoClient;
 import org.springblade.common.utils.SnowFlakeUtil;
 import org.springblade.core.secure.utils.AuthUtil;
 import org.springblade.core.tool.utils.Func;
@@ -18,6 +20,7 @@ import org.springblade.manager.vo.*;
 import org.springframework.stereotype.Service;
 
 import java.util.*;
+import java.util.stream.Collectors;
 
 @Service
 @AllArgsConstructor
@@ -28,6 +31,8 @@ public class ArTreeContractInitServiceImpl {
 
     private final ProjectClient projectClient;
 
+    private final ArchiveAutoClient archiveAutoClient;
+
     /**
      *
      * @param tenantId
@@ -100,9 +105,6 @@ public class ArTreeContractInitServiceImpl {
         }
 
 
-        //设置祖先id
-        InitAncestors(archiveTreeContracts);
-
         return;
 
     }
@@ -223,7 +225,7 @@ public class ArTreeContractInitServiceImpl {
      *
      * @param archiveTreeContracts
      */
-    public void InitAncestors(List<ArchiveTreeContract> archiveTreeContracts) {
+    public void InitAncestorsAndTreeSort(List<ArchiveTreeContract> archiveTreeContracts) {
         List<ArchiveTreeContractVO2> archiveTreeContractVO2List = new ArrayList<>();
         Map<Long,ArchiveTreeContractVO2> vo2Map = new LinkedHashMap<>();
         for (ArchiveTreeContract archiveTreeContract:archiveTreeContracts) {
@@ -231,6 +233,7 @@ public class ArTreeContractInitServiceImpl {
             treeContractVO2.setId(archiveTreeContract.getId());
             treeContractVO2.setParentId(archiveTreeContract.getParentId());
             treeContractVO2.setTitle(archiveTreeContract.getNodeName());
+            treeContractVO2.setSort(archiveTreeContract.getSort());
             archiveTreeContractVO2List.add(treeContractVO2);
             vo2Map.put(treeContractVO2.getId(),treeContractVO2);
         }
@@ -239,10 +242,14 @@ public class ArTreeContractInitServiceImpl {
 
         InitAncestors(trees.get(0),"0");
 
+        InitTreeSort(trees.get(0), "");
+
         for (ArchiveTreeContract archiveTreeContract:archiveTreeContracts) {
             ArchiveTreeContractVO2 tmp = vo2Map.get(archiveTreeContract.getId());
             if (tmp != null ) {
                 archiveTreeContract.setAncestors(tmp.getAncestors());
+                archiveTreeContract.setTreeSort(tmp.getTreeSort());
+
             }
         }
     }
@@ -264,6 +271,22 @@ public class ArTreeContractInitServiceImpl {
         }
     }
 
+    /**
+     *
+     * @param tree
+     */
+    public void InitTreeSort(ArchiveTreeContractVO2 tree, String treeSort) {
+        String localTreeSort = treeSort + tree.sortNum() ;
+        tree.setTreeSort(localTreeSort);
+
+        List<ArchiveTreeContractVO2> childrens = tree.getChildren();
+        if (childrens!= null) {
+            for (ArchiveTreeContractVO2 child :childrens) {
+                InitTreeSort(child,localTreeSort);
+            }
+        }
+    }
+
 
     public ArchiveTreeContractVO2 getTree(List<ArchiveTreeContract> archiveTreeContracts) {
         List<ArchiveTreeContractVO2> archiveTreeContractVO2List = new ArrayList<>();
@@ -322,13 +345,22 @@ public class ArTreeContractInitServiceImpl {
         ForestNodeMerger.getTreeList(subTree,treeContractVO2s);
 
         //2. 获取对应合同的树
-        List<WbsTreeContractVO6> wbsTreeContractVO6s =  contractInfoService.tree6List(wbsId.toString(),subTree.toString(),contractId.toString());
+        //List<WbsTreeContractVO6> wbsTreeContractVO6s =  contractInfoService.tree6List(wbsId.toString(),projectId.toString(),contractId.toString());
+
+        List<WbsTreeContractVO6> wbsTrees =  contractInfoService.tree8(wbsId.toString(),projectId.toString(),contractId.toString());
+        if (wbsTrees == null || wbsTrees.size() == 0) {
+            return archiveTreeContracts;
+        }
+
+        List<WbsTreeContractVO6> wbsTreeContractVO6s = new ArrayList<>();
+        ForestNodeMerger.getTreeList(wbsTrees.get(0),wbsTreeContractVO6s);
 
         List<WbsTreeContractVO6> addWbsNodes = new ArrayList<>();
 
         //获取已经存在的
         Map<Long,ArchiveTreeContractVO2> extMap = new LinkedHashMap<>();
         Map<Long,Long> oldNewMap = new LinkedHashMap<>();
+        //Map<Long,WbsTreeContractVO6> wbsMap = new LinkedHashMap<>();
         for (ArchiveTreeContractVO2 ar :treeContractVO2s) {
             if (ar.getExtId() !=null ) {
                 extMap.put(ar.getExtId(),ar);
@@ -338,15 +370,13 @@ public class ArTreeContractInitServiceImpl {
 
         for (WbsTreeContractVO6 wbsTreeVO2:wbsTreeContractVO6s) {
             //不要中间交工,质量评定和开工报告作为目录节点
-            if (wbsTreeVO2.getMajorDataType() != null ) {
-                if (wbsTreeVO2.getMajorDataType() == 1
-                        || wbsTreeVO2.getMajorDataType() == 2
-                        || wbsTreeVO2.getMajorDataType() == 3){
-                    continue;
-                }
+            //wbsMap.put(wbsTreeVO2.getId(),wbsTreeVO2);
+            if (!wbsTreeVO2.isProcessType()) {
+                continue;
             }
+
             //只展示指定层级之上的
-            if (wbsTreeVO2.getNodeType() > level){
+            if (!wbsTreeVO2.isMatchLevel(level)){
                 continue;
             }
 
@@ -371,28 +401,120 @@ public class ArTreeContractInitServiceImpl {
             archiveTree.setContractId(contractId);
             archiveTree.setId(oldNewMap.get(wbsTreeVO2.getId()));
             if (wbsTreeVO2.getParentId() == 0) {
-                wbsTreeVO2.setParentId(subTree.getId());
+                archiveTree.setParentId(subTree.getId());
             }else {
                 archiveTree.setParentId(oldNewMap.get(wbsTreeVO2.getParentId()));
             }
 
+            if (archiveTree.getParentId() == null) {
+                continue;
+            }
+
             archiveTree.setNodeName(wbsTreeVO2.getTitle());
 
             //设置关联
             archiveTree.setExtType(1);
             archiveTree.setExtId(wbsTreeVO2.getId());
+            archiveTree.setSort(wbsTreeVO2.getSort());
             archiveTree.setExtAttachId(subTree.getId());
             archiveTree.setDisplayHierarchy(level.toString());
             archiveTree.setIsDeleted(0);
             //上传节点
-            if (wbsTreeVO2.getNodeType().longValue() ==  level) {
+            if (wbsTreeVO2.getNodeType() != null && wbsTreeVO2.getNodeType().longValue() ==  level) {
                 archiveTree.setIsStorageNode(1);
             }
             archiveTreeContracts.add(archiveTree);
 
         }
 
+        //ArchiveTreeContractVO2 ar = getTree(archiveTreeContracts);
+
         return archiveTreeContracts;
     }
 
+    void syncArchiveAutoList(List<ArchiveTreeContract> archiveTreeContracts,List<ContractInfo> contracts) {
+        List<ArchivesAuto> archivesAutos = new ArrayList<>();
+
+        Map<Long,ContractInfo> contractMap = new LinkedHashMap<>();
+
+        for (ContractInfo contractInfo: contracts) {
+            if (contractInfo.getContractType() == 1 && contractMap.get(0L) == null) {
+                contractMap.put(0L,contractInfo);
+            }
+
+            contractMap.put(contractInfo.getId(),contractInfo);
+        }
+
+
+        List<ArchiveTreeContract> storageList = archiveTreeContracts.stream()
+                .filter(e->e.getIsStorageNode()!= null && e.getIsStorageNode() == 1).collect(Collectors.toList());
+
+        for (ArchiveTreeContract storage: storageList) {
+
+
+            ArchivesAuto archivesAuto = new ArchivesAuto();
+            InitArchivesAuto(archivesAuto,storage,contractMap);
+            archivesAutos.add(archivesAuto);
+        }
+        archiveAutoClient.saveArchiveAutoByNodes(archivesAutos);
+    }
+
+    /**
+     *
+     * @param archivesAuto
+     * @param archiveTreeContract
+     */
+    public void InitArchivesAuto(ArchivesAuto archivesAuto,ArchiveTreeContract archiveTreeContract,Map<Long,ContractInfo> contractMap) {
+
+
+        archivesAuto.setName(archiveTreeContract.getNodeName());
+        archivesAuto.setNodeId(archiveTreeContract.getId());
+        archivesAuto.setProjectId(archiveTreeContract.getProjectId());
+        archivesAuto.setContractId(archiveTreeContract.getContractId());
+
+
+        archivesAuto.setUnit(getUnit(archiveTreeContract,contractMap));
+
+        //要设置对
+        archivesAuto.setTreeSort(archiveTreeContract.getTreeSort());
+
+        archivesAuto.setIsArchive(0);
+        archivesAuto.setIsDeleted(0);
+    }
+
+    /**
+     * 获取节点对应的单位
+     * @param archiveTreeContract
+     * @param contractInfo
+     * @return
+     */
+    public String getUnit(ArchiveTreeContract archiveTreeContract,Map<Long,ContractInfo> contractMap){
+
+        ContractInfo contractInfo = contractMap.get(archiveTreeContract.getContractId());
+        if (contractInfo == null ) {
+            contractInfo = contractMap.get(0L);
+        }
+
+        String unit = "";
+        if (StringUtils.isEmpty(archiveTreeContract.getTreeCode())) {
+            unit = contractInfo.getContractorUnitName();
+        }else {
+            if (archiveTreeContract.getTreeCode().equals("C")) {
+                unit = contractInfo.getConstructionUnitName();
+            }else if (archiveTreeContract.getTreeCode().equals("S")) {
+                unit = contractInfo.getSupervisionUnitName();
+            }else {
+                if (contractInfo.getContractType()== 2) {
+                    unit = contractInfo.getSupervisionUnitName();
+                }else if (contractInfo.getContractType() == 1) {
+                    unit = contractInfo.getConstructionUnitName();
+                }else {
+                    unit = contractInfo.getContractorUnitName();
+                }
+            }
+
+        }
+        return unit;
+    }
+
 }

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

@@ -109,11 +109,15 @@ public class ArchiveTreeContractServiceImpl extends BaseServiceImpl<ArchiveTreeC
 
 		List<ArchiveTreeContract> addNodes = arTreeContractInitService.getContractProcExtNodes(tenantId,projectId,wbsId,newTree);
 		archiveTreeContracts.addAll(addNodes);
+
+		//初始化祖先节点和排序
+		arTreeContractInitService.InitAncestorsAndTreeSort(archiveTreeContracts);
 		//todo 同步质检资料动态节点,处理文件提名
 
 		//todo 同步立卷规则
 
 		//todo 同步划分树节点到案卷列表
+		arTreeContractInitService.syncArchiveAutoList(archiveTreeContracts,contractInfoVOS);
 
 		this.saveBatch(archiveTreeContracts);
 		return true;

+ 5 - 7
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ArchiveTreeServiceImpl.java

@@ -398,14 +398,12 @@ public class ArchiveTreeServiceImpl extends BaseServiceImpl<ArchiveTreeMapper, A
         //遍历构建
         for (WbsTreeVO2 wbsTreeVO2:wbsTreeVO2List) {
             //只展示指定层级之上的
-            if (wbsTreeVO2.getMajorDataType() != null ) {
-                if (wbsTreeVO2.getMajorDataType() == 1
-                    || wbsTreeVO2.getMajorDataType() == 2
-                    || wbsTreeVO2.getMajorDataType() == 3){
-                    continue;
-                }
+
+            if (!wbsTreeVO2.isProcessType()) {
+                continue;
             }
-            if (wbsTreeVO2.getNodeType() > level){
+
+            if (!wbsTreeVO2.isMatchLevel(level)){
                 continue;
             }
             ArchiveTreeVO2 archiveTree = new ArchiveTreeVO2();

+ 63 - 18
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ContractInfoServiceImpl.java

@@ -195,6 +195,22 @@ public class ContractInfoServiceImpl extends BaseServiceImpl<ContractInfoMapper,
         return baseMapper.tree6(Long.parseLong(wbsId), Long.parseLong(projectId), Long.parseLong(contractId));
     }
 
+    @Override
+    public List<WbsTreeContractVO6> tree6(String wbsId, String projectId, String contractId) {
+        List<WbsTreeContractVO6> wbsTreeContractVOS = baseMapper.tree6(Long.parseLong(wbsId), Long.parseLong(projectId), Long.parseLong(contractId));
+        return buildWbsTreeByStream6(wbsTreeContractVOS);
+    }
+
+    @Override
+    public List<WbsTreeContractVO6> tree8(String wbsId, String projectId, String contractId) {
+        List<WbsTreeContractVO6> wbsTreeContractVOS = baseMapper.tree6(Long.parseLong(wbsId), Long.parseLong(projectId), Long.parseLong(contractId));
+        List<WbsTreeContractVO6> wbsTreeVO2s = ForestNodeMerger.merge(wbsTreeContractVOS);
+        List<WbsTreeContractVO6> list = wbsTreeVO2s.stream().filter(f -> f.getParentId() == 0L).collect(Collectors.toList());
+
+        return list;
+    }
+
+
     @Override
     public List<WbsTreeContractVO> tree(String wbsId, String projectId, String contractId) {
         List<WbsTreeContractVO> wbsTreeContractVOS = baseMapper.tree2(Long.parseLong(wbsId), Long.parseLong(projectId), Long.parseLong(contractId), null, null, null);
@@ -226,6 +242,25 @@ public class ContractInfoServiceImpl extends BaseServiceImpl<ContractInfoMapper,
         }
     }
 
+    public List<WbsTreeContractVO6> buildWbsTreeByStream6(List<WbsTreeContractVO6> wbsTreeVO2s) {
+        List<WbsTreeContractVO6> list = wbsTreeVO2s.stream().filter(f -> f.getParentId() == 0L).collect(Collectors.toList());
+        Map<Long, List<WbsTreeContractVO6>> map = wbsTreeVO2s.stream().collect(Collectors.groupingBy(WbsTreeContractVO6::getParentId));
+        this.recursionFnTree6(list, map);
+        return list;
+    }
+
+    public void recursionFnTree6(List<WbsTreeContractVO6> list, Map<Long, List<WbsTreeContractVO6>> map) {
+        for (WbsTreeContractVO6 wbsTreeContractVO : list) {
+            List<WbsTreeContractVO6> childrenList = map.get(wbsTreeContractVO.getId());
+            wbsTreeContractVO.setChildren(childrenList);
+            if (childrenList != null && childrenList.size() > 0) {
+                wbsTreeContractVO.setHasChildren(true);
+                recursionFnTree6(childrenList, map);
+            }
+        }
+    }
+
+
     public void recursionFnTreeAll(List<WbsTreeContractTreeAllVO> list, Map<Long, List<WbsTreeContractTreeAllVO>> map) {
         for (WbsTreeContractTreeAllVO wbsTreeContractVO : list) {
             List<WbsTreeContractTreeAllVO> childrenList = map.get(wbsTreeContractVO.getId());
@@ -484,28 +519,38 @@ public class ContractInfoServiceImpl extends BaseServiceImpl<ContractInfoMapper,
 
     @Override
     public Map<String, Object> trialRelationTree(String wbsId, String projectId, String contractId, String selfId) {
-        //合同段树
-        List<WbsTreeContractVO> wbsTreeContractVOS = baseMapper.tree2(null, Long.parseLong(projectId), Long.parseLong(contractId), null, null, null);
-        List<WbsTreeContractVO> wbsTreeContractVOList = buildWbsTreeByStream(wbsTreeContractVOS);
-        //是否勾选-试验关联工程部位信息
-        /*List<String> listResult = new ArrayList<>();
-        if (StringUtils.isNotEmpty(selfId)) {
-            List<String> list = baseMapper.queryList(selfId);
-            if (list.size() > 0) {
-                for (WbsTreeContractVO wbsTreeContractVO : wbsTreeContractVOS) {
-                    for (String s : list) {
-                        if (wbsTreeContractVO.getPrimaryKeyId().equals(s)) {
-                            listResult.add(s);
-                        }
-                    }
-                }
+        //当前合同段施工质检树
+        List<TrialRecordZJTreeVO> wbsTreeContractVOS = baseMapper.trialRelationTree(Long.parseLong(projectId), Long.parseLong(contractId), Long.parseLong(wbsId));
+        List<TrialRecordZJTreeVO> trialRecordZJTreeVOS = buildWbsTreeByStreamTrialRecordZJTree(wbsTreeContractVOS);
+        ContractInfo contractInfo = jdbcTemplate.query("select contract_name from m_contract_info where id = " + contractId, new BeanPropertyRowMapper<>(ContractInfo.class)).stream().findAny().orElse(null);
+        for (TrialRecordZJTreeVO node : trialRecordZJTreeVOS) {
+            if (node.getParentId() == 0 && contractInfo != null) {
+                node.setFullName(contractInfo.getContractName());
+                break;
             }
-        }*/
+        }
         Map<String, Object> maps = new HashMap<>();
-        maps.put("treeContractAll", wbsTreeContractVOList);
-        //maps.put("isSelectedStatus", listResult.stream().distinct().collect(Collectors.toList()));
+        maps.put("treeContractAll", trialRecordZJTreeVOS);
         return maps;
     }
 
+    private List<TrialRecordZJTreeVO> buildWbsTreeByStreamTrialRecordZJTree(List<TrialRecordZJTreeVO> wbsTreeVO2s) {
+        List<TrialRecordZJTreeVO> list = wbsTreeVO2s.stream().filter(f -> f.getParentId() == 0L).collect(Collectors.toList());
+        Map<Long, List<TrialRecordZJTreeVO>> map = wbsTreeVO2s.stream().collect(Collectors.groupingBy(TrialRecordZJTreeVO::getParentId));
+        this.recursionFnTreeTrialRecordZJTree(list, map);
+        return list;
+    }
+
+    private void recursionFnTreeTrialRecordZJTree(List<TrialRecordZJTreeVO> list, Map<Long, List<TrialRecordZJTreeVO>> map) {
+        for (TrialRecordZJTreeVO trialRecordZJTreeVO : list) {
+            List<TrialRecordZJTreeVO> childrenList = map.get(trialRecordZJTreeVO.getId());
+            if (childrenList != null && childrenList.size() > 0) {
+                trialRecordZJTreeVO.setChildren(childrenList);
+                trialRecordZJTreeVO.setHasChildren(true);
+                recursionFnTreeTrialRecordZJTree(childrenList, map);
+            }
+        }
+    }
+
 
 }

+ 200 - 103
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ExcelTabServiceImpl.java

@@ -26,6 +26,7 @@ import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.mixsmart.utils.ListUtils;
+import com.mixsmart.utils.RegexUtils;
 import com.spire.xls.*;
 import com.spire.xls.CellRange;
 import com.spire.xls.Workbook;
@@ -41,6 +42,7 @@ import org.jsoup.Jsoup;
 import org.jsoup.nodes.Document;
 import org.jsoup.nodes.Element;
 import org.jsoup.select.Elements;
+import org.springblade.business.dto.TrialSelfInspectionRecordDTO;
 import org.springblade.business.entity.InformationQuery;
 import org.springblade.business.entity.TrialSelfInspectionRecord;
 import org.springblade.business.feign.ContractLogClient;
@@ -93,6 +95,7 @@ import java.text.SimpleDateFormat;
 import java.util.List;
 import java.util.*;
 import java.util.function.Function;
+import java.util.regex.Matcher;
 import java.util.stream.Collectors;
 
 /**
@@ -718,6 +721,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
         if (ListUtils.isNotEmpty(tableInfoList)) {
             //施工资料填报
             String pkids = "";
+            StringBuilder log = new StringBuilder("异常:");
             try {
                 for (TableInfo tableInfo : tableInfoList) {
                     WbsTreeContract wbsTreeContract = wbsTreeContractService.getBaseMapper().selectOne(Wrappers.<WbsTreeContract>query().lambda()
@@ -768,6 +772,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                         transactionManager1.commit(transactionStatus);
                     } catch (Exception e) {
                         transactionManager1.rollback(transactionStatus);
+                        log.append(e.getMessage()).append("@@");
                         e.printStackTrace();
                     }
                 }
@@ -794,10 +799,29 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                 e.printStackTrace();
                 return R.fail("操作失败");
             }
+            if (log.length() > 5) {
+                return R.fail(reason(log.toString()));
+            }
         }
         return R.success("操作成功");
     }
 
+    public String reason(String log) {
+        /*字段过短提示*/
+        StringBuilder sb = new StringBuilder();
+        String[] part = log.split("@@");
+        for (String p : part) {
+            Matcher m = RegexUtils.matcher("(m_\\d{14}_\\d{19})\\((.+)\\)VALUES\\(([^)]+)\\).+column'(key_\\d{0,2})'", p.replaceAll("[\\n\\s]*", ""));
+            if (m.find()) {
+                List<Map<String, Object>> result = this.jdbcTemplate.queryForList("select CONCAT(a.tab_ch_name,'&',b.e_name) tf from m_table_info a join m_wbs_form_element b on b.f_id=a.id where a.tab_en_name='" + m.group(1) + "' and  b.e_key='" + m.group(4) + "'");
+                if (result.size() > 0) {
+                    sb.append("【").append(result.get(0).values().stream().map(String::valueOf).collect(Collectors.joining(","))).append("】");
+                }
+            }
+        }
+        return sb.append("数据库字段太短,请联系管理员").toString();
+    }
+
     // 获取用户
     @Override
     public Map<String, String> getTablbCols(String pkeyid, String colkey) throws FileNotFoundException {
@@ -1047,13 +1071,14 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
         reData.remove("contractId");
         reData.remove("pkeyId");
         reData.remove("projectId");
+        reData.put("tabGroupId", wbsTreeContract.getTabGroupId());
         return R.data(reData);
     }
 
     @Override
     public R getBussPdfInfo(Long pkeyId) throws Exception {
         String file_path = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
-        //String file_path = "/Users/hongchuangyanfa/Desktop/";
+        // String file_path = "/Users/hongchuangyanfa/Desktop/";
         WbsTreeContract wbsTreeContract = wbsTreeContractService.getBaseMapper().selectOne(Wrappers.<WbsTreeContract>query().lambda()
                 .eq(WbsTreeContract::getPKeyId, pkeyId));
 
@@ -1295,7 +1320,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
             }
         }
 
-        //  wb.saveToFile(excelPath, ExcelVersion.Version2010);
+        //wb.saveToFile(excelPath, ExcelVersion.Version2010);
         //输出流
         FileOutputStream outputStream = new FileOutputStream(excelPath);
         workbook.write(outputStream);
@@ -1380,40 +1405,110 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
             tabpdf2.delete();
         }
 
-        //TODO ------ 试验pdf关联部位工程及信息 liuYC 2023-03-13 ------
-        //获取试验记录id
-        List<String> recordIds = baseMapper.queryTrialRecordId(nodeId).stream().distinct().collect(Collectors.toList());
-        if (recordIds.size() > 0) {
-            String recordInfoSql = "select detection_category,detection_result,task_status,pdf_url from u_trial_self_inspection_record where pdf_url is not null and id in(" + StringUtils.join(recordIds, ",") + ")";
-            List<TrialSelfInspectionRecord> query = jdbcTemplate.query(recordInfoSql, new BeanPropertyRowMapper<>(TrialSelfInspectionRecord.class));
-            if (query.size() > 0) {
-                //只获取已审批合格自检记录,追加试验pdf到质检后面
-                List<String> pdfUrlsTrail = query.stream().filter(f -> ("已审批").equals(f.getTaskStatus())
-                        && (new Integer(1).equals(f.getDetectionResult()))
-                        && (new Integer(1).equals(f.getDetectionCategory()))).map(TrialSelfInspectionRecord::getPdfUrl).collect(Collectors.toList());
-                if (pdfUrlsTrail.size() > 0) {
-                    data.addAll(pdfUrlsTrail);
-                }
-            }
-        }
-
+        //资料填报原始pdf合并
         FileUtils.mergePdfPublicMethods(data, listPdf);
         BladeFile bladeFile = this.newIOSSClient.uploadFile(nodeId + ".pdf", listPdf);
 
         //获取当前填报节点sort
         WbsTreeContract wbsTreeContract = wbsTreeContractService.getBaseMapper().selectOne(Wrappers.<WbsTreeContract>lambdaQuery().eq(WbsTreeContract::getPKeyId, nodeId));
 
-        // 获取顺序
+        //获取顺序
         int sort = 0;
         if (ObjectUtil.isNotEmpty(wbsTreeContract)) {
             if (wbsTreeContract.getSort() != null) {
                 sort = wbsTreeContract.getSort();
             }
         }
+
         String sql = "update u_information_query set pdf_url ='" + bladeFile.getLink() + "' ,sort = " + sort + " where classify='" + classify + "' and  wbs_id='" + nodeId + "' and contract_id ='" + contractId + "' ";
         jdbcTemplate.execute(sql);
     }
 
+    @Override
+    public List<TableInfo> getTableInfoListTrial(JSONArray dataArray, String tabIds) {
+        if (dataArray != null && !dataArray.isEmpty()) {
+            List<TableInfo> result = new ArrayList<>();
+            for (int m = 0; m < dataArray.size(); m++) {
+                TableInfo tableInfo = new TableInfo();
+                JSONObject dataInfo2 = dataArray.getJSONObject(m);
+                tableInfo.setPkeyId(dataInfo2.getString("pkeyId"));
+
+                if (!tabIds.contains(tableInfo.getPkeyId())) {
+                    //隐藏表不做处理
+                    continue;
+                }
+
+                tableInfo.setContractId(dataInfo2.getString("contractId"));
+                tableInfo.setProjectId(dataInfo2.getString("projectId"));
+
+                //填报的类型,施工或监理
+                tableInfo.setClassify(dataInfo2.getString("classify"));
+                //设置首件信息
+                this.setFirstData(dataInfo2, tableInfo);
+                //设置日志信息
+                this.setTheLogData(dataInfo2, tableInfo);
+
+                dataInfo2.fluentRemove("contractId")
+                        .fluentRemove("pkeyId")
+                        .fluentRemove("p_key_id")
+                        .fluentRemove("projectId")
+                        .fluentRemove("classify")
+                        .fluentRemove("pickerKey")
+                        .fluentRemove("id")
+                        .fluentRemove("isFirst")
+                        .fluentRemove("firstNodeId")
+                        .fluentRemove("isTheLog")
+                        .fluentRemove("theLogId")
+                        .fluentRemove("linkTabIds")
+                        .fluentRemove("recordTime")
+                        .fluentRemove("businessId")
+                        .fluentRemove("sourceUrl")
+                        .fluentRemove("pdfUrl")
+                        .fluentRemove("firstFileName")
+                        .fluentRemove("");
+                //计算数据
+                LinkedHashMap<String, List<String>> dataMap = dataInfo2.keySet().stream().filter(e -> e.contains("__")).collect(Collectors.groupingBy(e -> e.split("__")[0], LinkedHashMap<String, List<String>>::new, Collectors.toList()));
+                LinkedHashMap<String, String> dataMap2 = new LinkedHashMap<>();
+                //字段组合
+                for (String k : dataMap.keySet()) {
+                    if (dataMap.get(k).size() > 1 && !dataMap.get(k).contains("000Z")) {
+                        String[] ziduan = dataMap.get(k).toArray(new String[]{});
+                        String temp = "";
+                        for (int i = 0; i < ziduan.length - 1; i++) {
+                            for (int j = 0; j < ziduan.length - i - 1; j++) {
+                                int tr = Integer.parseInt((ziduan[j].split("__")[1]).split("_")[0]);
+                                int td = Integer.parseInt(ziduan[j].split("__")[1].split("_")[1]);
+                                int tr_1 = Integer.parseInt(ziduan[j + 1].split("__")[1].split("_")[0]);
+                                int td_1 = Integer.parseInt(ziduan[j + 1].split("__")[1].split("_")[1]);
+                                if (tr > tr_1 && td == td_1) { //纵向排序
+                                    temp = ziduan[j];
+                                    ziduan[j] = ziduan[j + 1];
+                                    ziduan[j + 1] = temp;
+                                }
+                            }
+                        }
+                        StringBuilder lastStr = new StringBuilder(dataInfo2.getString(ziduan[0]) + "_^_" + ziduan[0].split("__")[1]);
+                        for (int i = 1; i < ziduan.length; i++) {
+                            String keyData = dataInfo2.getString(ziduan[i]);
+                            if (!keyData.equals("")) {
+                                lastStr.append("☆").append(dataInfo2.getString(ziduan[i])).append("_^_").append(ziduan[i].split("__")[1]);
+                            }
+
+                        }
+                        dataMap2.put(k, lastStr.toString());
+                    } else {
+                        String dataVal = dataInfo2.getString(dataMap.get(k).get(0));
+                        dataMap2.put(k, dataVal + "_^_" + dataMap.get(k).get(0).split("__")[1]);
+                    }
+                }
+                dataMap2.put("p_key_id", tableInfo.getPkeyId());
+                tableInfo.setDataMap(dataMap2);
+                result.add(tableInfo);
+            }
+            return result;
+        }
+        return null;
+    }
 
     /**
      * 试验 获取填报信息
@@ -1449,39 +1544,75 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
             File file1 = ResourceUtil.getFile(wbsTreePrivate.getHtmlUrl());
             String htmlString = IoUtil.readToString(new FileInputStream(file1));
             Document doc = Jsoup.parse(htmlString);
-        } catch (FileNotFoundException e) {
-            e.printStackTrace();
-        }
+            //匹配
+            Elements bgHB = doc.select("el-input[placeholder~=报告编号.*]");
+            Elements jlBH = doc.select("el-input[placeholder~=记录编号.*]");
+
+            TrialSelfInspectionRecord record = jdbcTemplate.query("select record_no,report_no from u_trial_self_inspection_record where id = " + groupId, new BeanPropertyRowMapper<>(TrialSelfInspectionRecord.class)).stream().findAny().orElse(null);
+            if (record != null) {
+                //报告编号
+                if (bgHB.size() >= 1) {
+                    for (Element element : bgHB) {
+                        int trIndex = Integer.parseInt(element.attr("trindex"));
+                        if (trIndex <= 6) {
+                            reData.put(element.attr("keyName"), ObjectUtils.isNotEmpty(record.getReportNo()) ? record.getReportNo() : "");
+                        }
+                    }
+                }
+                //记录编号
+                if (jlBH.size() >= 1) {
+                    for (Element element : jlBH) {
+                        int trIndex = Integer.parseInt(element.attr("trindex"));
+                        if (trIndex <= 6) {
+                            reData.put(element.attr("keyName"), ObjectUtils.isNotEmpty(record.getRecordNo()) ? record.getRecordNo() : "");
+                        }
+                    }
+                }
+            }
 
-        if (dataIn.size() >= 1) {
-            Map<String, Object> mysqlData = dataIn.get(0);
-            for (String key : mysqlData.keySet()) {
-                String tabVal = mysqlData.get(key) + "";
+            if (dataIn.size() >= 1) {
+                Map<String, Object> mysqlData = dataIn.get(0);
+                for (String key : mysqlData.keySet()) {
+                    String tabVal = mysqlData.get(key) + "";
 
-                // 时间段处理
-                if (StringUtils.isNotEmpty(tabVal) && !tabVal.equals("null")) {
-                    if (tabVal.contains("T") && tabVal.contains(".000Z]")) {
-                        String[] tabData = tabVal.split("_\\^_");
+                    // 时间段处理
+                    if (StringUtils.isNotEmpty(tabVal) && !tabVal.equals("null")) {
+                        if (tabVal.contains("T") && tabVal.contains(".000Z]")) {
+                            String[] tabData = tabVal.split("_\\^_");
 
-                        if (reData.containsKey("pickerKey")) {
-                            String pickerKey = reData.get("pickerKey") + "," + key + "__" + tabData[1];
-                            reData.put("pickerKey", pickerKey);
-                        } else {
-                            reData.put("pickerKey", key + "__" + tabData[1]);
-                        }
+                            if (reData.containsKey("pickerKey")) {
+                                String pickerKey = reData.get("pickerKey") + "," + key + "__" + tabData[1];
+                                reData.put("pickerKey", pickerKey);
+                            } else {
+                                reData.put("pickerKey", key + "__" + tabData[1]);
+                            }
 
-                        String sql = tabData[0];
-                        sql = sql.replaceAll("\\[", "['");
-                        sql = sql.replaceAll("]", "']");
-                        sql = sql.replaceAll("000Z,", "000Z',");
-                        sql = sql.replaceAll(", 20", ", '20");
-                        //   sql = sql.replaceAll("'", "");
-                        if (StringUtils.isNotEmpty(tabData[0])) {
-                            reData.put(key + "__" + tabData[1], sql);
-                        }
-                    } else if (tabVal.contains("T") && tabVal.contains(".000Z")) { //时间
-                        // 时间和字符串合作
-                        if (tabVal.contains("☆")) {
+                            String sql = tabData[0];
+                            sql = sql.replaceAll("\\[", "['");
+                            sql = sql.replaceAll("]", "']");
+                            sql = sql.replaceAll("000Z,", "000Z',");
+                            sql = sql.replaceAll(", 20", ", '20");
+                            //   sql = sql.replaceAll("'", "");
+                            if (StringUtils.isNotEmpty(tabData[0])) {
+                                reData.put(key + "__" + tabData[1], sql);
+                            }
+                        } else if (tabVal.contains("T") && tabVal.contains(".000Z")) { //时间
+                            // 时间和字符串合作
+                            if (tabVal.contains("☆")) {
+                                String[] mysql = tabVal.split("☆");
+                                for (String data : mysql) {
+                                    String[] tabData = data.split("_\\^_");
+                                    if (StringUtils.isNotEmpty(tabData[0])) {
+                                        reData.put(key + "__" + tabData[1], tabData[0]);
+                                    }
+                                }
+                            } else {
+                                String[] tabData = tabVal.split("_\\^_");
+                                if (StringUtils.isNotEmpty(tabData[0])) {
+                                    reData.put(key + "__" + tabData[1], tabData[0]);
+                                }
+                            }
+                        } else if (tabVal.contains("☆")) {
                             String[] mysql = tabVal.split("☆");
                             for (String data : mysql) {
                                 String[] tabData = data.split("_\\^_");
@@ -1489,30 +1620,19 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                                     reData.put(key + "__" + tabData[1], tabData[0]);
                                 }
                             }
-                        } else {
+                        } else if (tabVal.contains("_^_")) {
                             String[] tabData = tabVal.split("_\\^_");
                             if (StringUtils.isNotEmpty(tabData[0])) {
                                 reData.put(key + "__" + tabData[1], tabData[0]);
                             }
+                        } else {
+                            reData.put(key, tabVal);
                         }
-                    } else if (tabVal.contains("☆")) {
-                        String[] mysql = tabVal.split("☆");
-                        for (String data : mysql) {
-                            String[] tabData = data.split("_\\^_");
-                            if (StringUtils.isNotEmpty(tabData[0])) {
-                                reData.put(key + "__" + tabData[1], tabData[0]);
-                            }
-                        }
-                    } else if (tabVal.contains("_^_")) {
-                        String[] tabData = tabVal.split("_\\^_");
-                        if (StringUtils.isNotEmpty(tabData[0])) {
-                            reData.put(key + "__" + tabData[1], tabData[0]);
-                        }
-                    } else {
-                        reData.put(key, tabVal);
                     }
                 }
             }
+        } catch (FileNotFoundException e) {
+            e.printStackTrace();
         }
 
         // 获取默认值
@@ -1601,13 +1721,6 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
 
                         if (StringUtils.isNotEmpty(tabVal) && !tabVal.equals("null")) {
 
-                            //处理相同字段名称问题,同一个KeyName,那么拼接value
-                            Object oldValue = reData.get(key);
-                            if (oldValue != null) {
-                                reData.put(key, oldValue + "、" + tabVal);
-                                continue;
-                            }
-
                             //时间段处理
                             if (tabVal.contains("T") && tabVal.contains(".000Z]")) {
                                 String[] tabData = tabVal.split("_\\^_");
@@ -1649,7 +1762,13 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                                 for (String data : mysql) {
                                     String[] tabData = data.split("_\\^_");
                                     if (StringUtils.isNotEmpty(tabData[0])) {
-                                        reData.put(key, tabData[0]);
+                                        //处理相同字段名称问题,同一个KeyName,那么拼接value
+                                        Object oldValue = reData.get(key);
+                                        if (ObjectUtils.isNotEmpty(oldValue)) {
+                                            reData.put(key, oldValue + "、" + tabData[0]);
+                                        } else {
+                                            reData.put(key, tabData[0]);
+                                        }
                                     }
                                 }
                             } else if (tabVal.contains("_^_")) {
@@ -1728,7 +1847,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
         List<Map<String, Object>> bussDataInfoTrial = this.getBussDataInfoTrial(id, pkeyId);
         Map<String, Object> DataInfo = bussDataInfoTrial.stream().findAny().orElse(null);
 
-        // 获取excel流 和 html流
+        //获取excel流 和 html流
         Workbook wb = new Workbook();
         wb.loadFromMHtml(CommonUtil.getOSSInputStream(excelTab.getFileUrl()));
         //获取工作表
@@ -1800,31 +1919,6 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                                     }
                                 }
 
-                                /*if (myData.contains("T") && myData.contains("-") && myData.contains(":")) {
-                                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
-                                    sdf.setTimeZone(TimeZone.getTimeZone("GTM+8"));
-                                    SimpleDateFormat formatStr = new SimpleDateFormat("yyyy年MM月dd日");
-
-                                    if (myData.contains(",") && myData.contains("]")) {
-                                        myData = myData.replace("[", "").replace("]", "").replaceAll("'", "");
-                                        String[] dataVal = myData.split(",");
-                                        String[] Start_dataStr = dataVal[0].split("T")[0].split("-");
-                                        String StartDate = StringUtil.format("{}年{}月{}日", Start_dataStr[0], Start_dataStr[1], Integer.parseInt(Start_dataStr[2]) + 1).trim();
-
-                                        String[] end_dataStr = dataVal[1].split("T")[0].split("-");
-
-                                        String endDate = StringUtil.format("{}年{}月{}日", end_dataStr[0], end_dataStr[1], Integer.parseInt(end_dataStr[2]) + 1).trim();
-                                        if (StartDate.equals(endDate)) {
-                                            myData = StartDate;
-                                        } else {
-                                            myData = StartDate + "-" + endDate;
-                                        }
-                                    } else {
-                                        String[] dataStr = myData.split("T")[0].split("-");
-                                        myData = StringUtil.format("{}年{}月{}日", dataStr[0], dataStr[1], Integer.parseInt(dataStr[2]) + 1);
-                                    }
-                                }*/
-
                                 if (myData.contains("https") && myData.contains("aliyuncs")) {
                                     BufferedImage image = ImageIO.read(CommonUtil.getOSSInputStream(myData));
                                     int colspan = data.attr("COLSPAN").equals("") ? 0 : Integer.parseInt(data.attr("COLSPAN"));
@@ -1879,9 +1973,9 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                 }
                 // 组装电签设置
                 QueryWrapper<TextdictInfo> queryWrapper = new QueryWrapper<>();
+                queryWrapper.select("col_key", "id");
                 queryWrapper.eq("type", 2);
                 queryWrapper.eq("tab_id", wbsTreePrivate.getPKeyId());
-
                 List<TextdictInfo> textDictInfos = textdictInfoService.getBaseMapper().selectList(queryWrapper);
                 if (textDictInfos != null && !textDictInfos.isEmpty()) {
                     for (TextdictInfo e : textDictInfos) {
@@ -1974,15 +2068,17 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
         //获取有权限的节点信息
         String sql = "select p_key_id,html_url,table_type from m_wbs_tree_private where is_deleted = 0 and p_key_id in (" + tabIds + ")";
         List<WbsTreePrivate> queryList = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(WbsTreePrivate.class));
-        //合并pdfUrlsList,报告单在前记录表在后
         List<String> dataPdfUrls = new ArrayList<>();
+
         //报告单
         List<WbsTreePrivate> reportTable = queryList.stream().filter(f -> f.getTableType() == 2).collect(Collectors.toList());
         //记录表
         List<WbsTreePrivate> recordTable = queryList.stream().filter(f -> f.getTableType() == 1).collect(Collectors.toList());
+
         if (queryList.size() > 0) {
             for (WbsTreePrivate report : reportTable) {
-                if (StringUtils.isNotEmpty(report.getHtmlUrl())) { //没有excel表单的不生成pdf
+                //没有excel表单的不生成pdf
+                if (StringUtils.isNotEmpty(report.getHtmlUrl())) {
                     //生成报告单pdf
                     String bussPdfInfo = this.getBussPDFTrial(report.getPKeyId(), contractId, id);
                     if (StringUtils.isNotEmpty(bussPdfInfo)) {
@@ -1991,7 +2087,8 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                 }
             }
             for (WbsTreePrivate record : recordTable) {
-                if (StringUtils.isNotEmpty(record.getHtmlUrl())) { //没有excel表单的不生成pdf
+                //没有excel表单的不生成pdf
+                if (StringUtils.isNotEmpty(record.getHtmlUrl())) {
                     //生成记录表pdf
                     String bussPdfInfo = this.getBussPDFTrial(record.getPKeyId(), contractId, id);
                     if (StringUtils.isNotEmpty(bussPdfInfo)) {

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

@@ -63,7 +63,7 @@ public class FormulaOptionServiceImpl extends ServiceImpl<FormulaOptionMapper, F
             }
             JSONObject table = (JSONObject) root.computeIfAbsent(wbc.getInitTableName(),(k)->new JSONObject());
             JSONObject data = (JSONObject) table.computeIfAbsent(fo.createKey(),(k)->new JSONObject());
-            data.put(fo.getName(),fo.getValue());
+            data.put(fo.getCode(),fo.getValue());
             formulaOption.setVal(root.toJSONString());
             this.saveOrUpdate(formulaOption);
             return data;

+ 59 - 89
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormulaServiceImpl.java

@@ -8,10 +8,6 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.jfireel.expression.Expression;
 import com.mixsmart.utils.*;
 import lombok.RequiredArgsConstructor;
-import org.jsoup.Jsoup;
-import org.jsoup.nodes.Document;
-import org.jsoup.nodes.Element;
-import org.jsoup.select.Elements;
 import org.springblade.common.utils.SnowFlakeUtil;
 import org.springblade.core.mp.base.BaseServiceImpl;
 import org.springblade.core.tool.utils.*;
@@ -28,10 +24,6 @@ import org.springblade.manager.vo.AppWbsTreeContractVO;
 import org.springblade.manager.vo.CurrentNode;
 import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.stereotype.Service;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
 import java.util.*;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.regex.Matcher;
@@ -77,9 +69,12 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
     public static final String ELE_CODE_REG= "(?<=E\\[)[^]]+(?=])";
     public static final Pattern P = Pattern.compile(ELE_CODE_REG);
     public static final Pattern P2= Pattern.compile("(?<=E\\[)[^];]+:[^];]+:[^];]+(?=])");
-    public static final String POLY_REG= "(quantity)\\(([^)]+)\\)";
     public final static String CTI="ContractInfo";
     public final static String PJI="ProjectInfo";
+    /*元素标识*/
+    public final static String E="E";
+    /*公式参数*/
+    public final static String FMOT="FORMULA_OPTION";
     /**表单信息*/
     public final static String TEXT_INFO_MAP="textInfoMap";
 
@@ -217,7 +212,8 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
         /*公式参数*/
         FormulaOption formulaOption = this.formulaOptionService.getOne(Wrappers.<FormulaOption>lambdaQuery().eq(FormulaOption::getParentId,one.getId()).eq(FormulaOption::getContractId,contractId));
         if(formulaOption!=null){
-           LinkedHashMap linkedHashMap = JSON.parseObject(formulaOption.getVal(),LinkedHashMap.class);
+           /*数据格式 {tablename:{keyxxx:{option:[1|0]}}}*/
+           this.constantMap.put(FMOT,JSON.parseObject(formulaOption.getVal(),LinkedHashMap.class));
         }
         return this;
     }
@@ -417,7 +413,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
     public IFormulaService pre() {
         if(CollectionUtil.isNotEmpty(this.formDataList)){
             for(FormData fd:this.formDataList){
-                /*预处理公式脚本*/
+                /*预处理公式脚本,只做文本转换不做计算*/
                 if(!fd.executable()){
                     /*不存公式,则认为执行完成,不会再主动执行*/
                     fd.setFinished(Boolean.TRUE);
@@ -429,18 +425,17 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                 }
                 String tmp =fd.getFormula().getFormula();
                 tmp = tmp.replace(FC, CustomFunction.CLASS_CALL);
-                if(tmp.contains(CustomFunction.CLASS_CALL+"ifelse")){
-                    Matcher im =IF.matcher(tmp);
-                    while (im.find()){
-                        String rep =im.group();
-                        Matcher fm=P.matcher(rep);
-                        while (fm.find()){
-                            rep=rep.replace(fm.group(),"'"+fm.group()+"'");
-                        }
-                        tmp=tmp.replace(im.group(),rep);
-                    }
-                }
-
+//                if(tmp.contains(CustomFunction.CLASS_CALL+"ifelse")){
+//                    Matcher im =IF.matcher(tmp);
+//                    while (im.find()){
+//                        String rep =im.group();
+//                        Matcher fm=P.matcher(rep);
+//                        while (fm.find()){
+//                            rep=rep.replace(fm.group(),"'"+fm.group()+"'");
+//                        }
+//                        tmp=tmp.replace(im.group(),rep);
+//                    }
+//                }
                 if(tmp.contains("E[")||tmp.contains("WP[")){
                     Matcher am = AP.matcher(tmp);
                     while (am.find()){
@@ -474,9 +469,6 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
 
     @Override
     public IFormulaService calculate() {
-        /*公式执行*/
-        /*先处理聚合类的方法*/
-        /*每次执行都会构造一个只有依赖的的集合*/
         for(FormData fd:this.formDataList){
             if(fd.verify()){
                 Formula formula =fd.getFormula();
@@ -493,7 +485,6 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                             relyList.forEach(rely->{
                                 FormData formData=  this.tec.getFormDataMap().get(rely);
                                 if(formData!=null&&formData.getValues().size()>0){
-                                    /*formData.getValues().stream().anyMatch(Func::isNotEmpty)*/
                                     ele.add(formData);
                                 }
                             });
@@ -520,14 +511,14 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                                 while (cda.hasNext()){
                                     LinkedHashMap<String,ElementData> tip= cda.next();
                                     Map<String, Object> variable = new HashMap<>(this.constantMap);
-                                    Map<String,Object> E=getMap(variable,"E");
+                                    Map<String,Object> em= (Map<String, Object>) variable.computeIfAbsent(E, k->new HashMap<>());
                                     int index= new ArrayList<>(tip.values()).get(0).getIndex();
                                     for(Map.Entry<String,ElementData> se:tip.entrySet()){
                                         Object value=se.getValue().getValue();
                                         if(CustomFunction.isNumber(value)){
-                                            E.put(se.getKey(),StringUtils.obj2Double(value));
+                                            em.put(se.getKey(),StringUtils.obj2Double(value));
                                         }else{
-                                            E.put(se.getKey(),value);
+                                            em.put(se.getKey(),value);
                                         }
 
                                     }
@@ -536,19 +527,11 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                                 if(local.size()>0){
                                     List<Object> values = slice(local,this.constantMap,f);
                                     write(fd,values);
-//                                    if(values.size()>fd.getValues().size()){
-//                                        /*当生成的数据超过实际容量的时候,会自动合并到第一个单元格*/
-//                                        fd.getValues().get(0).setValue(values.stream().filter(Func::isNotEmpty).map(StringUtils::handleNull).collect(Collectors.joining("、")));
-//                                    }else{
-//                                        for(int n=0;n<values.size();n++){
-//                                            fd.getValues().get(n).setValue(values.get(n));
-//                                        }
-//                                    }
                                 }
                             }else{
-                                Map<String,Object> E = (Map<String, Object>) currentMap.computeIfAbsent("E",(k)-> new HashMap<>());
+                                Map<String,Object> em = (Map<String, Object>) currentMap.computeIfAbsent(E,(k)-> new HashMap<>());
                                 ele.forEach(e->{
-                                    E.put(e.getCode(),e.getValues().stream().map(ElementData::getValue).collect(Collectors.toList()));
+                                    em.put(e.getCode(),e.getValues().stream().map(ElementData::getValue).collect(Collectors.toList()));
                                 });
                                 Object data =Expression.parse(formula.getFormula()).calculate(currentMap);
                                 write(fd,data);
@@ -593,9 +576,9 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                               /*超页就尽管写进去,格式化阶段再加表*/
                               Coords coords = coordsList.get(j);
                               Object v=null;
-                              int st=i*coordsList.size()*j;
+                              int st=i*coordsList.size()+j;
                               if(st<overList.size()){
-                                 v= values.get(st);
+                                 v= overList.get(st);
                               }
                               addList.add(new ElementData(indexBase+i,last.getGroupId(),v,coords.getX(),coords.getY()));
                           }
@@ -627,53 +610,49 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
        KeyMapper last = kms.get(kms.size()-1);
        WbsTreeContract  origin =  this.wbsTreeContractService.getOne(Wrappers.<WbsTreeContract>lambdaQuery().eq(WbsTreeContract::getPKeyId,last.getPkId()));
        if(origin!=null){
-           Long mark =origin.getPKeyId();
            for(int i=0;i<pageAdd;i++){
                /*复制表*/
                WbsTreeContract target = new WbsTreeContract();
                BeanUtil.copy(origin,target);
                target.setPKeyId(SnowFlakeUtil.getId());
-               this.wbsTreeContractService.saveOrUpdate(target);
-               List<KeyMapper> allInTable=tec.getKeyMappers().stream().filter(e->e.getTableName().equals(fd.getTableName())).collect(Collectors.toList());
+               target.setCreateTime(new Date());
+               String nodeName = origin.getNodeName();
+               if (nodeName.contains("__")) {
+                   String[] oldName = nodeName.split("__");
+                   nodeName = oldName[0] + "__" + (Integer.parseInt(oldName[1]) + 1);
+               } else {
+                   nodeName = nodeName + "__" + 1;
+               }
+               target.setNodeName(nodeName);
+               target.setIsCopeTab(2);
+               target.setIsTabPdf(1); // pdf 不能预览
+               target.setIsBussShow(1); // 是否隐藏表
+               target.setTabFileType(1);//没有上传附件
+               target.setPdfUrl("");
+               this.wbsTreeContractService.save(target);
+               Long pkeyId=origin.getPKeyId();
+               List<KeyMapper> allInTable=tec.getKeyMappers().stream().filter(e->e.getPkId().equals(pkeyId)).collect(Collectors.toList());
                allInTable.forEach(e->{
                    KeyMapper km = new KeyMapper();
                    BeanUtil.copy(e,km);
                    km.setPkId(target.getPKeyId());
                    tec.getKeyMappers().add(km);
                });
-               tec.getTableInfoList().stream().filter(o->StringUtils.isEquals(o.getPkeyId(),mark)).findFirst().ifPresent(tb->{
+               tec.getTableInfoList().stream().filter(o->StringUtils.isEquals(o.getPkeyId(),pkeyId)).findFirst().ifPresent(tb->{
                    /*表单数据复制*/
                    TableInfo tableInfo = new TableInfo();
                    BeanUtil.copy(tb,tableInfo);
-                   tableInfo.setDataMap(new LinkedHashMap<>());
+                   tableInfo.setPkeyId(target.getPKeyId().toString());
+                   tableInfo.setDataMap(new LinkedHashMap<>(tb.getDataMap()));
+                   tableInfo.getDataMap().put("p_key_id",tableInfo.getPkeyId());
                    tec.getTableInfoList().add(tec.getTableInfoList().indexOf(tb)+1,tableInfo);
                });
+               origin=target;
            }
            //enlarge(fd,pageAdd);
        }
    }
 
-   public void enlarge(FormData fd,int pageAdd){
-       List<FormData> targetList = tec.getFormDataMap().values().stream().filter(e->StringUtils.isEquals(fd.getTableName(),e.getTableName())).collect(Collectors.toList());
-        targetList.forEach(tmp->{
-          if(tmp!=null){
-              List<Coords> list = tmp.getCoordsList();
-              ElementData last = tmp.getValues().get(tmp.getValues().size()-1);
-              int index =last.getIndex();
-              int groupId=last.getGroupId();
-              Object data=null;
-              if(Formula.FULL.equals(tmp.getFormula().getOutm())){
-                  data=tmp.getValues().get(tmp.getValues().size()-1);
-              }
-              for(int i=0;i<pageAdd;i++){
-                  int finalIndex = index;
-                  Object finalData = data;
-                  tmp.getValues().addAll(list.stream().map(c-> new ElementData(finalIndex,groupId, finalData,c.getX(),c.getY())).collect(Collectors.toList()));
-                  index++;
-              }
-          }
-        });
-   }
 
 
 
@@ -695,12 +674,9 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
             }
         }
         /*检查超页情况*/
-        LinkedHashMap<String,List<FormData>>  tableElementMaps=  this.formDataMap.values().stream().filter(e->e.getUpdate()==1&&e.getAddPages()>0).sorted(Comparator.comparing(FormData::getAddPages).reversed()).collect(Collectors.groupingBy(FormData::getTableName,LinkedHashMap::new,Collectors.toList()));
-        for(Map.Entry<String,List<FormData>> entry:tableElementMaps.entrySet()){
-            String  tableName=entry.getKey();
-            FormData max= entry.getValue().get(0);
-            copy(max);
-        }
+        this.formDataMap.values().stream().filter(e->e.getUpdate()==1&&e.getAddPages()>0).sorted(Comparator.comparing(FormData::getAddPages).reversed())
+                        .collect(Collectors.groupingBy(FormData::getTableName,LinkedHashMap::new,Collectors.toList())).values()
+                        .forEach(l->copy(l.get(0)));;
 
     }
 
@@ -752,14 +728,6 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
     }
 
 
-    public  Map<String,Object> getMap(Map<String,Object> main,String key){
-        Map<String,Object> CNDMap = (Map<String, Object>) main.get(key);
-        if(CNDMap==null){
-            CNDMap = new HashMap<>();
-            main.put(key,CNDMap);
-        }
-        return CNDMap;
-    }
 
 
     public  List<Object> slice(List<LocalVariable>  local,Map<String,Object> constantMap,String formula){
@@ -865,17 +833,19 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                      }
                  }
                  if(f.contains(".option")){
+                     /*FC.optionC?是无法嵌套的函数*/
                      Matcher m = RegexUtils.matcher(FC_REG+"(optionC?)\\(([^)]+)\\)",f);
                      while (m.find()){
                        String[] args= m.group(2).split(",");
                        String flag=args[0];
-                       if(flag.equals("OPTION")){
+                       /*radio控件,结果只有两个0,1 ,结果作为标识位,且为1才会执第二个参数的回调方法*/
+                       if("OPTION".equals(flag)){
                            Optional<KeyMapper> kOp=tec.getKeyMappers().stream().filter(e->StringUtils.isEquals(e.getCode(),fd.getCode())).findFirst();
                            if(kOp.isPresent()){
                                /*表名+合同段+父节点*/
-                               String findStr = "OP"+DigestUtil.md5Hex(fd.getCode()+ tec.getTableAll().stream().filter(t->StringUtils.isEquals(t.getPKeyId(),kOp.get().getPkId())).map(t->fd.getTableName()+t.getContractId()+t.getParentId()).collect(Collectors.joining()));
-                               Map<String,Object> dictMap = (Map<String, Object>) this.constantMap.computeIfAbsent("OPTION",k->new HashMap<>());
-                               flag=StringUtils.handleNull(dictMap.get(findStr));
+                               Map<String,Object> optionMap = (Map<String, Object>) this.constantMap.computeIfAbsent(FMOT,k->new HashMap<>());
+                               String findStr=fd.getTableName()+"['"+fd.getKey()+"']['TF']";
+                               flag=StringUtils.handleNull(Expression.parse(findStr).calculate(optionMap));
                            }
                        }else if(flag.contains("E[")){
                            List<FormData> target = getFormDataByCode(flag);
@@ -888,7 +858,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                            flag="0";
                        }
                        if(StringUtils.isEquals(flag,1)){
-                           f=f.replace(m.group(),m.group(2).replaceAll("^[0-1],",""));
+                           f=f.replace(m.group(),args[1]);
                        }else{
                            f=f.replace(m.group(),"''");
                        }
@@ -954,9 +924,9 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
          Map<String,Object> currentMap= new HashMap<String,Object>(this.constantMap);
          List<FormData> fds= getFormDataByCode(String.join(",", getCodeByEl(el)));
          if(Func.isNotEmpty(fds)){
-             Map<String,Object> E= (Map<String, Object>) currentMap.computeIfAbsent("E", k->new HashMap<String,Object>());
+             Map<String,Object> Em= (Map<String, Object>) currentMap.computeIfAbsent(E, k->new HashMap<String,Object>());
              fds.forEach(e->{
-                 E.put(e.getCode(),e.getValues().stream().map(ElementData::getValue).collect(Collectors.toList()));
+                 Em.put(e.getCode(),e.getValues().stream().map(ElementData::getValue).collect(Collectors.toList()));
              });
          }
         return currentMap;

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

@@ -1,5 +1,6 @@
 package org.springblade.manager.service.impl;
 
+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.metadata.IPage;
@@ -7,11 +8,13 @@ import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.baomidou.mybatisplus.core.toolkit.StringUtils;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.google.common.collect.Lists;
+import com.mysql.cj.x.protobuf.MysqlxDatatypes;
 import lombok.AllArgsConstructor;
 import org.jsoup.Jsoup;
 import org.jsoup.nodes.Document;
 import org.jsoup.nodes.Element;
 import org.jsoup.select.Elements;
+import org.springblade.common.constant.CommonConstant;
 import org.springblade.common.utils.SnowFlakeUtil;
 import org.springblade.core.log.exception.ServiceException;
 import org.springblade.core.mp.base.BaseServiceImpl;
@@ -28,8 +31,10 @@ import org.springblade.manager.mapper.*;
 import org.springblade.manager.service.ITableInfoService;
 import org.springblade.manager.service.IWbsTreePrivateService;
 import org.springblade.manager.vo.*;
+import org.springblade.system.cache.ParamCache;
 import org.springframework.jdbc.core.BeanPropertyRowMapper;
 import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.scheduling.annotation.Async;
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -37,6 +42,7 @@ import org.springframework.transaction.annotation.Transactional;
 import javax.annotation.Resource;
 import java.io.File;
 import java.io.FileInputStream;
+import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.util.*;
 import java.util.concurrent.Callable;
@@ -1508,6 +1514,32 @@ public class WbsTreePrivateServiceImpl extends BaseServiceImpl<WbsTreePrivateMap
 
     }
 
+    /**
+     * 批量重新保存文件htmlUrl
+     * @param wbsTreePrivateList
+     */
+    @Async
+    @Override
+    public void batchResetHtmlUrl(List<WbsTreePrivate> wbsTreePrivateList) throws IOException, InterruptedException {
+        if (wbsTreePrivateList != null) {
+            //存在htmlUrl才重新保存
+            wbsTreePrivateList = wbsTreePrivateList.stream().filter(wtp -> StringUtils.isNotBlank(wtp.getHtmlUrl())).collect(Collectors.toList());
+            String file_path = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
+            //批量复制保存html
+            for (WbsTreePrivate tree : wbsTreePrivateList) {
+                File file_in = ResourceUtil.getFile(tree.getHtmlUrl());
+                String fileCode = SnowFlakeUtil.getId() + "";
+                String htmlUrl = file_path + "/privateUrlCopy/" + fileCode + ".html";
+//                String htmlUrl = "C:\\Users\\泓创研发01\\Desktop\\privateUrlCopy\\" + fileCode + ".html";
+                File file_out = ResourceUtil.getFile(htmlUrl);
+                FileUtil.copy(file_in, file_out);
+                tree.setHtmlUrl(htmlUrl);
+            }
+            //批量修改
+            baseMapper.updateBatchByPKeyId(wbsTreePrivateList);
+        }
+    }
+
     @Override
     public R addWbsTreeContractInfo(String nodeId, String primaryKeyIds, long contractId) {
         if (com.alibaba.cloud.commons.lang.StringUtils.isEmpty(nodeId)) {
@@ -1535,7 +1567,7 @@ public class WbsTreePrivateServiceImpl extends BaseServiceImpl<WbsTreePrivateMap
     }
 
     @Override
-    public R addWbsTreeProjectInfo(String primaryKeyIds, String projectId) {
+    public R addWbsTreeProjectInfo(String primaryKeyIds, String projectId) throws IOException {
         if (com.alibaba.cloud.commons.lang.StringUtils.isEmpty(projectId)) {
             return R.fail("projectId不能为空");
         }
@@ -1545,11 +1577,44 @@ public class WbsTreePrivateServiceImpl extends BaseServiceImpl<WbsTreePrivateMap
 
         List<Long> longs = Func.toLongList(primaryKeyIds);
         for (Long id : longs) {
-
+            //获取添加的表信息
             TableInfo tableInfo = tableInfoService.getById(id);
             WbsTreePrivate wbsPrivate = new WbsTreePrivate();
             Long pKeyId1 = SnowFlakeUtil.getId();
             wbsPrivate.setPKeyId(pKeyId1);
+            //查询wbs_tree_contract当前项目下是否已存在相同表
+            WbsTreePrivate wbsTreePrivate = wbsTreePrivateMapper.selectOne(new LambdaQueryWrapper<WbsTreePrivate>()
+                    .eq(WbsTreePrivate::getProjectId, projectId)
+                    .eq(WbsTreePrivate::getInitTableName, tableInfo.getTabEnName())
+                    .orderByDesc(WbsTreePrivate::getUpdateTime)
+                    .last("limit 1"));
+            //如果存在则复制最新表的配置,调整表单的值
+            if (wbsTreePrivate != null) {
+                if (StringUtils.isNotEmpty(wbsTreePrivate.getExcelId().toString())) {
+                    wbsPrivate.setExcelId(wbsTreePrivate.getExcelId());
+                }
+                if (StringUtils.isNotEmpty(wbsTreePrivate.getHtmlUrl())){
+                    //复制生成html
+                    String file_path = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
+                    File file_in = ResourceUtil.getFile(wbsTreePrivate.getHtmlUrl());
+//                    File file_in = ResourceUtil.getFile("C:\\Users\\泓创研发01\\Desktop\\privateUrl\\1636553444422582272.html");
+                    String filecode = SnowFlakeUtil.getId() + "";
+                    String thmlUrl = file_path + "/privateUrl/" + filecode + ".html";
+//                    String thmlUrl =  "C:\\Users\\泓创研发01\\Desktop\\privateUrl\\9527.html";
+                    File file_out = ResourceUtil.getFile(thmlUrl);
+                    FileUtil.copy(file_in, file_out);
+                    wbsPrivate.setHtmlUrl(thmlUrl);
+                }
+                List<TextdictInfo> list = textDictInfoService.list(new LambdaQueryWrapper<TextdictInfo>()
+                        .eq(TextdictInfo::getTabId, wbsTreePrivate.getPKeyId()));
+                if (list.size() >= 0 ){
+                    list.stream().forEach(l->{
+                        l.setId(SnowFlakeUtil.getId());
+                        l.setTabId(wbsPrivate.getPKeyId().toString());
+                    });
+                    textDictInfoService.saveBatch(list);
+                }
+            }
 
             wbsPrivate.setTableOwner(tableInfo.getTableOwner());
             wbsPrivate.setInitTableId(tableInfo.getId() + "");
@@ -1633,9 +1698,7 @@ public class WbsTreePrivateServiceImpl extends BaseServiceImpl<WbsTreePrivateMap
             wbsTree.setInitTableId(tableInfo.getId());
             wbsTree.setFillRate(tableInfo.getFillRate());
             wbsTree.setTableOwner(tableInfo.getTableOwner());
-
             wbsTree.setWbsId(wbsId);
-
             wbsTreeMapper.updateById(wbsTree);
         } else if (type.equals("2")) {
             TableInfo tableInfo = tableInfoService.getById(tabId);
@@ -1695,7 +1758,7 @@ public class WbsTreePrivateServiceImpl extends BaseServiceImpl<WbsTreePrivateMap
     }
 
     @Override
-    public List<WbsTreePrivate> searchNodeAllTable(String primaryKeyId, String tableOwner, String tableType, String contractId, String projectId, Integer isAdd, Long id) {
+    public List<WbsTreePrivateVO4> searchNodeAllTable(String primaryKeyId, String tableOwner, String tableType, String contractId, String projectId, Integer isAdd, Long id) {
         WbsTreePrivate wbsTreePrivate = baseMapper.selectOne(Wrappers.<WbsTreePrivate>query().lambda()
                 .select(WbsTreePrivate::getProjectId, WbsTreePrivate::getWbsId, WbsTreePrivate::getId)
                 .eq(WbsTreePrivate::getPKeyId, primaryKeyId));

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

@@ -807,7 +807,8 @@ public class WbsTreeServiceImpl extends BaseServiceImpl<WbsTreeMapper, WbsTree>
                                     wbsTreePrivateService.insertBatch(addList, 1000);
                                 }, executor)).toArray(CompletableFuture[]::new));
                         handle.join();
-
+                        //异步修改htmlUrl ,数据都在inserData2里
+                        wbsTreePrivateService.batchResetHtmlUrl(insertData2);
                         //修改状态
                         if (pawDTO.getWbsType() == 1) {
                             projectInfoMapper.updateTemplateInfoQuality(pawDTO.getProjectId(), pawDTO.getPrimaryKeyId(), "private");

Unele fișiere nu au fost afișate deoarece prea multe fișiere au fost modificate în acest diff