Browse Source

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

huangtf 2 years ago
parent
commit
1f483fce17
78 changed files with 2635 additions and 1985 deletions
  1. 0 1
      blade-ops/blade-flow/blade-flow.iml
  2. 0 1
      blade-ops/blade-ops.iml
  3. 3 3
      blade-ops/blade-xxljob-admin/blade-xxljob-admin.iml
  4. 0 7
      blade-ops/blade-xxljob-admin/src/main/resources/mybatis-mapper/XxlJobInfoMapper.xml
  5. 3 3
      blade-ops/blade-xxljob/blade-xxljob.iml
  6. 0 6
      blade-service-api/blade-business-api/blade-business-api.iml
  7. 6 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/dto/TrialSelfInspectionRecordDTO.java
  8. 4 1
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/InformationQuery.java
  9. 9 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/feign/TaskClient.java
  10. 2 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/QueryProcessDataVO.java
  11. 3 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/TrialSelfInspectionRecordVO.java
  12. 3 3
      blade-service-api/blade-e-visa-api/blade-e-visa-api.iml
  13. 0 6
      blade-service-api/blade-manager-api/blade-manager-api.iml
  14. 2 2
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/FormData.java
  15. 1 1
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/FormulaOptionVo.java
  16. 6 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/WbsTreeContract.java
  17. 8 1
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/feign/WbsTreeContractClient.java
  18. 16 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/WbsTreePrivateVO4.java
  19. 0 5
      blade-service/blade-business/blade-business.iml
  20. 5 4
      blade-service/blade-business/src/main/java/org/springblade/business/controller/ImageClassificationFileController.java
  21. 63 73
      blade-service/blade-business/src/main/java/org/springblade/business/controller/InformationWriteQueryController.java
  22. 38 27
      blade-service/blade-business/src/main/java/org/springblade/business/controller/NeiYeController.java
  23. 544 529
      blade-service/blade-business/src/main/java/org/springblade/business/controller/TaskController.java
  24. 0 29
      blade-service/blade-business/src/main/java/org/springblade/business/controller/TestDemoController.java
  25. 84 24
      blade-service/blade-business/src/main/java/org/springblade/business/controller/TrialDetectionController.java
  26. 7 1
      blade-service/blade-business/src/main/java/org/springblade/business/feignClient/TaskClientImpl.java
  27. 6 1
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/InformationQueryMapper.java
  28. 17 5
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/InformationQueryMapper.xml
  29. 7 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/TaskMapper.java
  30. 30 1
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/TaskMapper.xml
  31. 7 3
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/TrialSelfInspectionRecordMapper.java
  32. 2 2
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/TrialSelfInspectionRecordMapper.xml
  33. 79 73
      blade-service/blade-business/src/main/java/org/springblade/business/service/IInformationQueryService.java
  34. 8 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/ITaskService.java
  35. 4 6
      blade-service/blade-business/src/main/java/org/springblade/business/service/ITrialSelfInspectionRecordService.java
  36. 6 1
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/ImageClassificationFileServiceImpl.java
  37. 49 25
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/InformationQueryServiceImpl.java
  38. 69 11
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TaskServiceImpl.java
  39. 1 2
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TrialContainerClassificationServiceImpl.java
  40. 12 10
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TrialDetectionDataServiceImpl.java
  41. 4 2
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TrialDeviceOverhaulServiceImpl.java
  42. 4 2
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TrialDeviceUseServiceImpl.java
  43. 6 6
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TrialMaterialMobilizationServiceImpl.java
  44. 15 13
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TrialSampleInfoServiceImpl.java
  45. 266 257
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TrialSelfInspectionRecordServiceImpl.java
  46. 3 3
      blade-service/blade-e-visa/blade-e-visa.iml
  47. 95 88
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/service/impl/EVisaServiceImpl.java
  48. 0 5
      blade-service/blade-manager/blade-manager.iml
  49. 8 2
      blade-service/blade-manager/src/main/java/com/jfireel/expression/node/impl/EqualNode.java
  50. 13 9
      blade-service/blade-manager/src/main/java/com/jfireel/expression/node/impl/GtEqNode.java
  51. 11 9
      blade-service/blade-manager/src/main/java/com/jfireel/expression/node/impl/GtNode.java
  52. 11 9
      blade-service/blade-manager/src/main/java/com/jfireel/expression/node/impl/LtEqNode.java
  53. 11 9
      blade-service/blade-manager/src/main/java/com/jfireel/expression/node/impl/LtNode.java
  54. 37 0
      blade-service/blade-manager/src/main/java/com/jfireel/expression/util/ValueUtil.java
  55. 23 46
      blade-service/blade-manager/src/main/java/com/mixsmart/utils/CustomFunction.java
  56. 56 0
      blade-service/blade-manager/src/main/java/com/mixsmart/utils/FormulaUtils.java
  57. 134 43
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ExcelTabController.java
  58. 3 3
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/FormulaController.java
  59. 0 10
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ProjectInfoController.java
  60. 15 15
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/TextdictInfoController.java
  61. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/WbsFormElementController.java
  62. 7 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/WbsTreeContractController.java
  63. 70 11
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/WbsTreePrivateController.java
  64. 29 46
      blade-service/blade-manager/src/main/java/org/springblade/manager/feign/ExcelTabClientImpl.java
  65. 8 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/feign/WbsTreeContractClientImpl.java
  66. 7 5
      blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/FormulaTurnPoint.java
  67. 1 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/ContractInfoMapper.xml
  68. 3 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/ExcelTabMapper.java
  69. 1 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsTreeContractMapper.xml
  70. 6 2
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/IExcelTabService.java
  71. 1 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/IWbsTreeContractService.java
  72. 2 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/IWbsTreePrivateService.java
  73. 18 18
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ContractInfoServiceImpl.java
  74. 247 46
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ExcelTabServiceImpl.java
  75. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormulaOptionServiceImpl.java
  76. 173 213
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormulaServiceImpl.java
  77. 111 52
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreePrivateServiceImpl.java
  78. 130 191
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeServiceImpl.java

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

@@ -6,7 +6,6 @@
         <setting name="validation-enabled" value="true" />
         <datasource-mapping>
           <factory-entry name="Entities" />
-          <factory-entry name="blade-flow" />
         </datasource-mapping>
         <naming-strategy-map />
       </configuration>

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

@@ -8,7 +8,6 @@
     </content>
     <orderEntry type="inheritedJdk" />
     <orderEntry type="sourceFolder" forTests="false" />
-    <orderEntry type="library" name="aspose-cells-20.4-c" level="project" />
     <orderEntry type="library" name="Maven: org.springblade:blade-starter-metrics:2.9.1.RELEASE" level="project" />
     <orderEntry type="library" name="Maven: io.micrometer:micrometer-core:1.6.3" level="project" />
     <orderEntry type="library" name="Maven: org.hdrhistogram:HdrHistogram:2.1.12" level="project" />

+ 3 - 3
blade-ops/blade-xxljob-admin/blade-xxljob-admin.iml

@@ -1,14 +1,14 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
   <component name="FacetManager">
+    <facet type="Spring" name="Spring">
+      <configuration />
+    </facet>
     <facet type="web" name="Web">
       <configuration>
         <webroots />
       </configuration>
     </facet>
-    <facet type="Spring" name="Spring">
-      <configuration />
-    </facet>
   </component>
   <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
     <output url="file://$MODULE_DIR$/target/classes" />

+ 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 - 3
blade-ops/blade-xxljob/blade-xxljob.iml

@@ -1,14 +1,14 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
   <component name="FacetManager">
+    <facet type="Spring" name="Spring">
+      <configuration />
+    </facet>
     <facet type="web" name="Web">
       <configuration>
         <webroots />
       </configuration>
     </facet>
-    <facet type="Spring" name="Spring">
-      <configuration />
-    </facet>
   </component>
   <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
     <output url="file://$MODULE_DIR$/target/classes" />

+ 0 - 6
blade-service-api/blade-business-api/blade-business-api.iml

@@ -7,10 +7,6 @@
     <facet type="web" name="Web">
       <configuration>
         <webroots />
-        <sourceRoots>
-          <root url="file://$MODULE_DIR$/src/main/java" />
-          <root url="file://$MODULE_DIR$/src/main/resources" />
-        </sourceRoots>
       </configuration>
     </facet>
   </component>
@@ -19,8 +15,6 @@
     <output-test url="file://$MODULE_DIR$/target/test-classes" />
     <content url="file://$MODULE_DIR$">
       <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
-      <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
-      <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
       <excludeFolder url="file://$MODULE_DIR$/target" />
     </content>
     <orderEntry type="inheritedJdk" />

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

@@ -14,6 +14,12 @@ public class TrialSelfInspectionRecordDTO extends TrialSelfInspectionRecord {
     @ApiModelProperty("样品信息ids")
     private String sampleIds;
 
+    @ApiModelProperty("原材料检测报告ids(试验记录id)")
+    private String rawMaterialIds;
+
+    @ApiModelProperty("项目id")
+    private String projectId;
+
     @ApiModelProperty(value = "表类型 1=记录表 2=报告单 ,字符串拼接")
     private String tableType;
 

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

+ 9 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/feign/TaskClient.java

@@ -14,6 +14,7 @@ import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestParam;
 
 import java.util.List;
+import java.util.Map;
 
 @FeignClient(value = BusinessConstant.APPLICATION_WEATHER_NAME)
 public interface TaskClient {
@@ -30,6 +31,14 @@ public interface TaskClient {
     String QUERY_APPROVAL_USER_TASK_ID = API_PREFIX + "/query-approval-user-by-task-id";
     String QUERY_BUSINESS_TABLE_E_VISA_CONFIG = API_PREFIX + "/query-business-table-e-visa-config";
     String QUERY_TASK_CONTRACT_ID = API_PREFIX + "/query-task-contract-id";
+    String QUERY_TASK_ALL_BATCH = API_PREFIX + "/query-contract-all-batch";
+
+
+    /**
+     * 获取当前合同段所有上报的资料批次信息
+     */
+    @GetMapping(QUERY_TASK_ALL_BATCH)
+    Map<String,String> queryContractAllBatch(@RequestParam String contract);
 
     /**
      * 获取当前任务所在的合同段

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

+ 3 - 3
blade-service-api/blade-e-visa-api/blade-e-visa-api.iml

@@ -1,14 +1,14 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
   <component name="FacetManager">
+    <facet type="Spring" name="Spring">
+      <configuration />
+    </facet>
     <facet type="web" name="Web">
       <configuration>
         <webroots />
       </configuration>
     </facet>
-    <facet type="Spring" name="Spring">
-      <configuration />
-    </facet>
   </component>
   <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
     <output url="file://$MODULE_DIR$/target/classes" />

+ 0 - 6
blade-service-api/blade-manager-api/blade-manager-api.iml

@@ -7,10 +7,6 @@
     <facet type="web" name="Web">
       <configuration>
         <webroots />
-        <sourceRoots>
-          <root url="file://$MODULE_DIR$/src/main/java" />
-          <root url="file://$MODULE_DIR$/src/main/resources" />
-        </sourceRoots>
       </configuration>
     </facet>
   </component>
@@ -19,8 +15,6 @@
     <output-test url="file://$MODULE_DIR$/target/test-classes" />
     <content url="file://$MODULE_DIR$">
       <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
-      <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
-      <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
       <excludeFolder url="file://$MODULE_DIR$/target" />
     </content>
     <orderEntry type="inheritedJdk" />

+ 2 - 2
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/FormData.java

@@ -58,9 +58,9 @@ public class FormData {
      */
     private Formula formula;
 
-    /**总共多少页,有些公式只生成一条数据,所以必须每一页复制一条
+    /**新增页
      * */
-    private Integer pages;
+    private Integer addPages=0;
     /**
      * 存储元素对应的表记录表Id
      */

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

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

+ 8 - 1
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/feign/WbsTreeContractClient.java

@@ -129,7 +129,14 @@ public interface WbsTreeContractClient {
      * @return 结果
      */
     @PostMapping(API_PREFIX + "/queryCurrentNodeAllChild")
-    List<WbsTreeContract> queryCurrentNodeAllChild(@RequestParam Long contractId, @RequestParam Long parentId);
+    List<WbsTreeContract> queryCurrentNodeAllChild(@RequestParam Long contractId, @RequestParam Long parentId);/**
+     * 获取所有子节点
+     *
+     * @param contractId 合同段ID
+     * @return 结果
+     */
+    @PostMapping(API_PREFIX + "/queryAllChild")
+    List<WbsTreeContract> queryAllChild(@RequestParam Long contractId);
 
     /**
      * 查询合同段树所有节点

+ 16 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/WbsTreePrivateVO4.java

@@ -0,0 +1,16 @@
+package org.springblade.manager.vo;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springblade.manager.entity.WbsTreePrivate;
+
+import java.util.Map;
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class WbsTreePrivateVO4 extends WbsTreePrivate{
+    private static final long serialVersionUID = 1L;
+
+    private Map<String, Object> bussDataInfoTrial;
+
+}

+ 0 - 5
blade-service/blade-business/blade-business.iml

@@ -7,10 +7,6 @@
     <facet type="web" name="Web">
       <configuration>
         <webroots />
-        <sourceRoots>
-          <root url="file://$MODULE_DIR$/src/main/java" />
-          <root url="file://$MODULE_DIR$/src/main/resources" />
-        </sourceRoots>
       </configuration>
     </facet>
   </component>
@@ -20,7 +16,6 @@
     <content url="file://$MODULE_DIR$">
       <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
       <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
-      <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
       <excludeFolder url="file://$MODULE_DIR$/target" />
     </content>
     <orderEntry type="inheritedJdk" />

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

@@ -164,7 +164,7 @@ public class ImageClassificationFileController extends BladeController {
                     List<String> removeList = new ArrayList<>();
 
                     //压缩到小于指定文件大小100kb
-                    //double targetSize = 100 * 1024;
+                    double targetSize = 200 * 1024;
 
                     for (ImageClassificationFile file : fileResult) {
                         //获取图片文件流
@@ -206,11 +206,12 @@ public class ImageClassificationFileController extends BladeController {
                                             byte[] bytes = CommonUtil.InputStreamToBytes(CommonUtil.getOSSInputStream(urls.get(i)));
 
                                             //压缩文件大小
-                                            /*while (bytes.length > targetSize) {
+                                            while (bytes.length > targetSize) {
                                                 float reduceMultiple = 0.5f;
                                                 bytes = FileUtils.resizeImage(bytes, reduceMultiple);
-                                            }*/
-                                            byte[] bytesNew = FileUtils.resizeImage(bytes, 0f);
+                                            }
+                                            //byte[] bytesNew = FileUtils.resizeImage(bytes, 0f);
+                                            byte[] bytesNew = bytes;
 
                                             //创建图片
                                             drawing.createPicture(anchor, workbook.addPicture(bytesNew, Workbook.PICTURE_TYPE_JPEG));

+ 63 - 73
blade-service/blade-business/src/main/java/org/springblade/business/controller/InformationWriteQueryController.java

@@ -793,7 +793,8 @@ public class InformationWriteQueryController extends BladeController {
         //记录状态
         String status = "1";
         //查询填报状态,type=2试验
-        InformationQuery businessData = this.informationQueryService.getOne(Wrappers.<InformationQuery>lambdaQuery().eq(InformationQuery::getWbsId, id).eq(InformationQuery::getClassify, classify).eq(InformationQuery::getType, 2));
+        InformationQuery businessData = this.informationQueryService.getBaseMapper().selectList(Wrappers.<InformationQuery>lambdaQuery()
+                .eq(InformationQuery::getWbsId, id).eq(InformationQuery::getClassify, classify).eq(InformationQuery::getType, 2)).stream().findAny().orElse(null);
         if (businessData != null) {
             switch (businessData.getStatus()) {
                 case 0:
@@ -1240,7 +1241,6 @@ public class InformationWriteQueryController extends BladeController {
     @ApiOperationSupport(order = 16)
     @ApiOperation(value = "自定义排序")
     public R<Boolean> diySort(@RequestBody DiySortVO vo) {
-        //对整棵树进行排序(资料查询需要同步显示排序)采用自增
         List<String> sortLists = vo.getSortList();
         return R.status(wbsTreeContractClient.diySort(sortLists));
     }
@@ -1248,29 +1248,27 @@ public class InformationWriteQueryController extends BladeController {
     /**
      * 复制节点
      */
-    @PostMapping("/copyContractTreeNode11")
+    @PostMapping("/copyContractTreeNode")
     @ApiOperationSupport(order = 15)
-    @ApiOperation(value = "复制节点")
-    public R<Boolean> copyContractTreeNode11(@RequestBody CopyContractTreeNodeVO vo) {
+    @ApiOperation(value = "复制节点(新)")
+    public R<Boolean> copyContractTreeNode(@RequestBody CopyContractTreeNodeVO vo) {
         //首先查询需要复制的节点及其下级所有子节点的信息
         WbsTreeContract needCopyNode = this.wbsTreeContractClient.getContractNodeByPrimaryKeyId(vo.getNeedCopyPrimaryKeyId());
         // 获取当前节点的所有子节点
-       String vocational = SnowFlakeUtil.getId()+"";
-        // 插入数据库
-        // informationQueryService.copeNodeData(needCopyNode.getId()+"",vocational);
-        // 修改
-        //
-        //
+        String vocational = SnowFlakeUtil.getId()+"";
         //新增施工台账
-        System.out.println("1="+DateUtil.formatDateTime(DateUtil.now()));
         List<WbsTreeContract>   saveList = new ArrayList<>();
         List<ConstructionLedger> saveLedger = new ArrayList<>();
-        System.out.println("2="+DateUtil.formatDateTime(DateUtil.now()));
+        // 获取附件
         List<WbsTreeContract> nodeChildAll = informationQueryService.getNodeChildAllByNodeId(needCopyNode.getId() + "", needCopyNode.getContractId(),vo.getNeedCopyPrimaryKeyId());
-        System.out.println("3="+DateUtil.formatDateTime(DateUtil.now()));
+       // 获取实体表列对象
+        List<QueryProcessDataVO> nodeTabCols = informationQueryService.getNodeChildTabColsAllByNodeId(needCopyNode.getId() + "", needCopyNode.getContractId());
+        // 转化为map
+        Map<String, String> nodeTabColsMap = nodeTabCols.stream().collect(Collectors.toMap(QueryProcessDataVO::getQueryType, QueryProcessDataVO::getAncestors, (key1, key2) -> key2));
+        StringBuilder copeSql = new StringBuilder();
+
         if (StringUtils.isNotEmpty(vo.getNeedCopyPrimaryKeyId())) {
             WbsTreeContract parent = this.wbsTreeContractClient.getContractNodeByPrimaryKeyId(vo.getParentPrimaryKeyId());
-
             //重塑关键信息
             Map<Long, Long> oldToNewIdMap = new HashMap<>();
             //节点信息
@@ -1280,12 +1278,10 @@ public class InformationWriteQueryController extends BladeController {
                 nodeMap.put(node.getId().toString(), node);
             });
 
-            System.out.println("4="+DateUtil.formatDateTime(DateUtil.now()));
             //todo 单份复制
             nodeChildAll.forEach(node -> {
                 WbsTreeContract newData = new WbsTreeContract();
                 BeanUtils.copyProperties(node, newData);
-
                 //重塑关键信息
                 //重塑primaryKeyId
                 newData.setPKeyId(SnowFlakeUtil.getId());
@@ -1300,7 +1296,6 @@ public class InformationWriteQueryController extends BladeController {
                 if (new Integer("1").equals(node.getType())) {
                     //如果是节点类型才重塑ID
                     newData.setId(oldToNewIdMap.containsKey(node.getId()) ? oldToNewIdMap.get(node.getId()) : SnowFlakeUtil.getId());
-
                     //划分编号
                     newData.setPartitionCode(StringUtils.isNotEmpty(vo.getPartitionCode()) ? vo.getPartitionCode() : null);
                 }
@@ -1325,34 +1320,31 @@ public class InformationWriteQueryController extends BladeController {
                 //初始化PDF路径
                 newData.setPdfUrl(null);
                 newData.setCreateUser(AuthUtil.getUserId());
-
-                //获取当前所有复制的节点的最大sort
-              //  String sql = "select sort from m_wbs_tree_contract where contract_id = '" + node.getContractId() + "' and (id = '" + node.getId() + "' or old_id = '" + node.getId() + "')";
-             //   List<WbsTreeContract> query = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(WbsTreeContract.class));
-            //    List<Integer> collect = query.stream().filter(f -> ObjectUtils.isNotEmpty(f.getSort())).collect(Collectors.toList()).stream().map(WbsTreeContract::getSort).collect(Collectors.toList());
-                Integer max = 1;
-             //   if (collect.size() > 0) {
-            //        max = collect.stream().reduce(collect.get(0), Integer::max);
-             //   } else {
-              //      max = 1;
-             //   }
-                //设置sort
-                newData.setSort(max);
                 //重塑父节点关联关系
                 this.restoreParent(newData, oldToNewIdMap);
-
                 //保存到集合中
                 saveList.add(newData);
-
                 if (new Integer("6").equals(node.getNodeType())) {
                     //生成施工日志
                     this.createLedger(newData, saveLedger, nodeMap, null);
                 }
+
+                // 组织复制值Sql
+                if(nodeTabColsMap!=null && node.getType()==2){
+                    String tableName = newData.getInitTableName();
+                    String col = nodeTabColsMap.get(tableName);
+                    String colVal = nodeTabColsMap.get(tableName);
+                    colVal = colVal.replaceAll("id,p_key_id,","'"+SnowFlakeUtil.getId()+"' as id,'"+newData.getPKeyId()+"' as p_key_id,");
+                    copeSql.append("insert into "+tableName+"  ("+col+") select "+colVal+" from "+tableName+" where p_key_id='"+node.getPKeyId()+"' ;");
+                }
             });
-            System.out.println("7="+DateUtil.formatDateTime(DateUtil.now()));
         }
+        //保存节点信息
+         R<Boolean> booleanR = this.saveOrCopyNodeTree(saveList, saveLedger, 32, needCopyNode);
 
-        return this.saveOrCopyNodeTree(saveList, saveLedger, 32, needCopyNode);
+        //复制数据逻辑
+         jdbcTemplate.execute(copeSql.toString());
+        return booleanR;
     }
 
 
@@ -1360,10 +1352,10 @@ public class InformationWriteQueryController extends BladeController {
     /**
      * 复制节点
      */
-    @PostMapping("/copyContractTreeNode")
+    @PostMapping("/copyContractTreeNode12313212")
     @ApiOperationSupport(order = 15)
     @ApiOperation(value = "复制节点")
-    public R<Boolean> copyContractTreeNode(@RequestBody CopyContractTreeNodeVO vo) {
+    public R<Boolean> copyContractTreeNode123131231(@RequestBody CopyContractTreeNodeVO vo) {
         //首先查询需要复制的节点及其下级所有子节点的信息
         WbsTreeContract needCopyNode = this.wbsTreeContractClient.getContractNodeByPrimaryKeyId(vo.getNeedCopyPrimaryKeyId());
         //获取当前合同段所有节点
@@ -1387,6 +1379,9 @@ public class InformationWriteQueryController extends BladeController {
                 }
             });
         }
+        //复制结构信息
+      //   R<Boolean> booleanR = this.saveOrCopyNodeTree(saveList, saveLedger, 32, needCopyNode);
+        // 复制表数据
 
         System.out.println("1="+DateUtil.formatDateTime(DateUtil.now()));
         List<WbsTreeContract> parentList = new ArrayList<>(), childList = new ArrayList<>(), allList = new ArrayList<>(), saveList = new ArrayList<>();
@@ -1463,7 +1458,7 @@ public class InformationWriteQueryController extends BladeController {
                     newData.setCreateUser(AuthUtil.getUserId());
 
                     //获取当前所有复制的节点的最大sort
-                    String sql = "select sort from m_wbs_tree_contract where contract_id = '" + node.getContractId() + "' and (id = '" + node.getId() + "' or old_id = '" + node.getId() + "')";
+                    /*String sql = "select sort from m_wbs_tree_contract where contract_id = '" + node.getContractId() + "' and (id = '" + node.getId() + "' or old_id = '" + node.getId() + "')";
                     List<WbsTreeContract> query = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(WbsTreeContract.class));
                     List<Integer> collect = query.stream().filter(f -> ObjectUtils.isNotEmpty(f.getSort())).collect(Collectors.toList()).stream().map(WbsTreeContract::getSort).collect(Collectors.toList());
                     Integer max = 1;
@@ -1473,7 +1468,8 @@ public class InformationWriteQueryController extends BladeController {
                         max = 1;
                     }
                     //设置sort
-                    newData.setSort(max);
+                    newData.setSort(max);*/
+                    newData.setSort(ObjectUtils.isNotEmpty(node.getSort()) ? node.getSort() : 0);
 
                     //重塑父节点关联关系
                     this.restoreParent(newData, oldToNewIdMap);
@@ -1544,7 +1540,7 @@ public class InformationWriteQueryController extends BladeController {
                         newData.setPdfUrl(null);
 
                         //获取当前所有复制的节点的最大sort
-                        String sql = "select sort from m_wbs_tree_contract where contract_id = '" + node.getContractId() + "' and (id = '" + node.getId() + "' or old_id = '" + node.getId() + "')";
+                        /*String sql = "select sort from m_wbs_tree_contract where contract_id = '" + node.getContractId() + "' and (id = '" + node.getId() + "' or old_id = '" + node.getId() + "')";
                         List<WbsTreeContract> query = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(WbsTreeContract.class));
                         List<Integer> collect = query.stream().filter(f -> ObjectUtils.isNotEmpty(f.getSort())).collect(Collectors.toList()).stream().map(WbsTreeContract::getSort).collect(Collectors.toList());
                         Integer max = 1;
@@ -1554,7 +1550,8 @@ public class InformationWriteQueryController extends BladeController {
                             max = 1;
                         }
                         //设置sort
-                        newData.setSort(max);
+                        newData.setSort(max);*/
+                        newData.setSort(ObjectUtils.isNotEmpty(node.getSort()) ? node.getSort() : 0);
 
                         //重塑父节点关联关系
                         this.restoreParent(newData, oldToNewIdMap);
@@ -1993,7 +1990,7 @@ public class InformationWriteQueryController extends BladeController {
                 }
 
                 //获取当前所有复制的节点的最大sort
-                String sql = "select sort from m_wbs_tree_contract where contract_id = '" + treeContract.getContractId() + "' and (id = '" + half.getId() + "' or old_id = '" + half.getId() + "')";
+                /*String sql = "select sort from m_wbs_tree_contract where contract_id = '" + treeContract.getContractId() + "' and (id = '" + half.getId() + "' or old_id = '" + half.getId() + "')";
                 List<WbsTreeContract> query = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(WbsTreeContract.class));
                 List<Integer> collect = query.stream().filter(f -> ObjectUtils.isNotEmpty(f.getSort())).collect(Collectors.toList()).stream().map(WbsTreeContract::getSort).collect(Collectors.toList());
                 Integer max = 1;
@@ -2003,7 +2000,9 @@ public class InformationWriteQueryController extends BladeController {
                     max = 1;
                 }
                 //设置sort
-                newData.setSort(max);
+                newData.setSort(max);*/
+                newData.setSort(ObjectUtils.isNotEmpty(half.getSort()) ? half.getSort() : 0);
+
                 //设置节点名称
                 for (AddContractTreeNodeVO.Node addVO : selectList) {
                     if (half.getPKeyId().toString().equals(addVO.getPrimaryKeyId())) {
@@ -2077,9 +2076,9 @@ public class InformationWriteQueryController extends BladeController {
                 this.constructionLedgerService.saveBatch(saveLedger, 1000);
                 str.append("-[");
                 for (ConstructionLedger ledger : saveLedger) {
-                    str.append(ledger.getSite()+",");
+                    str.append(ledger.getSite() + ",");
                 }
-                str.deleteCharAt(str.length()-1);
+                str.deleteCharAt(str.length() - 1);
                 str.append("]");
             }
 
@@ -2299,38 +2298,24 @@ public class InformationWriteQueryController extends BladeController {
         if (!new Integer("6").equals(node.getNodeType()) && !Arrays.asList("1,2,3,4".split(",")).contains(node.getMajorDataType().toString())) {
             //不是工序,则查询当前节点下的所有填报节点
             if (node.getParentId() == 0) {
-                String contractId = node.getContractId();
-                List<WbsTreeContract> treeS = wbsTreeContractClient.getContractWbsTreeByParentId(node.getId().toString(), contractId);
-                for (WbsTreeContract tree : treeS) {
-                    List<QueryProcessDataVO> Result = this.informationQueryService.queryProcessDataByParentIdAndContractIdTwo(tree.getId().toString(), contract.getContractType(), StringUtils.isNotEmpty(vo.getContractIdRelation()) ? vo.getContractIdRelation() : vo.getContractId().toString());
-                    if (Result != null && Result.size() > 0) {
-                        queryDataResult.addAll(Result);
-                        Result.clear();
-                    }
-                }
+                queryDataResult = this.informationQueryService.queryProcessDataByParentIdAndContractIdTwo("", contract.getContractType(), StringUtils.isNotEmpty(vo.getContractIdRelation()) ? vo.getContractIdRelation() : vo.getContractId().toString());
             } else {
-                List<QueryProcessDataVO> Result = this.informationQueryService.queryProcessDataByParentIdAndContractIdTwo(node.getId().toString(), contract.getContractType(), StringUtils.isNotEmpty(vo.getContractIdRelation()) ? vo.getContractIdRelation() : vo.getContractId().toString());
-                if (Result != null && Result.size() > 0) {
-                    queryDataResult.addAll(Result);
-                    Result.clear();
-                }
+                queryDataResult = this.informationQueryService.queryProcessDataByParentIdAndContractIdTwo(node.getId().toString(), contract.getContractType(), StringUtils.isNotEmpty(vo.getContractIdRelation()) ? vo.getContractIdRelation() : vo.getContractId().toString());
+
             }
             //如果是首件列表请求,则删掉没有标记为首件的数据
             if (queryDataResult != null && queryDataResult.size() > 0) {
                 if (StringUtils.isNotEmpty(vo.getIsFirst())) {
-                    List<String> treeIds = queryDataResult.stream().map(QueryProcessDataVO::getPrimaryKeyId).distinct().collect(Collectors.toList());
-                    //通过合同段主键在首件关联表中查询出所有数据
-                    List<TreeContractFirst> firstList = treeContractFirstService.list(new LambdaQueryWrapper<TreeContractFirst>().in(TreeContractFirst::getWbsNodeId, treeIds));
-                    List<String> list = firstList.stream().map(fl -> (fl.getWbsNodeId() + "")).collect(Collectors.toList());
-                    queryDataResult = queryDataResult.stream().filter(qdr -> list.contains(qdr.getPrimaryKeyId())).collect(Collectors.toList());
-//                    for (QueryProcessDataVO queryProcessDataVO : queryDataResult) {
-//                        TreeContractFirst first = treeContractFirstService.getOne(new LambdaQueryWrapper<TreeContractFirst>()
-//                                .eq(TreeContractFirst::getWbsNodeId, queryProcessDataVO.getPrimaryKeyId()));
-//                        if (first != null){
-//                            queryProcessDataVO.setFirstId(first.getId()+"");
-//                        }
-//                    }
-//                    queryDataResult.removeIf(data -> StringUtils.isEmpty(data.getFirstId()));
+                    if (StringUtils.isNotEmpty(vo.getFirstTitle())){
+                        queryDataResult = queryDataResult.stream().filter(qdr->"3".equals(qdr.getQueryType())).collect(Collectors.toList());
+                    }else {
+                        //节点主键集合
+                        List<String> treeIds = queryDataResult.stream().map(QueryProcessDataVO::getPrimaryKeyId).distinct().collect(Collectors.toList());
+                        //通过合同段主键在首件关联表中查询出所有数据
+                        List<TreeContractFirst> firstList = treeContractFirstService.list(new LambdaQueryWrapper<TreeContractFirst>().in(TreeContractFirst::getWbsNodeId, treeIds));
+                        List<String> list = firstList.stream().map(fl -> (fl.getWbsNodeId() + "")).collect(Collectors.toList());
+                        queryDataResult = queryDataResult.stream().filter(qdr -> list.contains(qdr.getPrimaryKeyId())).collect(Collectors.toList());
+                    }
                 }
                 submitNodeKeyIds.addAll(queryDataResult.stream().map(QueryProcessDataVO::getPrimaryKeyId).distinct().collect(Collectors.toList()));
             }
@@ -2459,7 +2444,7 @@ public class InformationWriteQueryController extends BladeController {
             if (contractIds.size() > 0) {
 
                 //监理复制加载树问题
-                if (StringUtils.isEmpty(classifyType)){
+                if (StringUtils.isEmpty(classifyType)) {
                     classifyType = "2";
                 }
 
@@ -2486,6 +2471,11 @@ public class InformationWriteQueryController extends BladeController {
         } else {
             //施工合同段
             rootTreeNode = this.informationQueryService.queryContractTree(contractId, StringUtils.isNotEmpty(parentId) ? parentId : "0", 1);
+            rootTreeNode.stream().forEach(rtn->{
+                if (rtn.getSubmitCounts() > 0L && rtn.getColorStatus() <= 1 && rtn.getNotExsitChild() == false){
+                    rtn.setColorStatus(2);
+                }
+            });
         }
 
         return rootTreeNode;

+ 38 - 27
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,26 +86,24 @@ public class NeiYeController {
                     && !node.getNodeName().contains("开工报告")&& !node.getNodeName().contains("质量检验评定表")){
                 //非填报节点
                 if (node.getParentId() == 0){
-                    String contractI = node.getContractId();
-                    List<WbsTreeContract> treeS = wbsTreeContractClient.getContractWbsTreeByParentId(node.getId().toString(),contractI);
-                    for (WbsTreeContract tree : treeS) {
-                        List<QueryProcessDataVO> dataResult = this.informationQueryService.queryProcessDataByParentIdAndContractIdTwo(tree.getId().toString(), contract.getContractType(), contractId);
-                        if (dataResult != null && dataResult.size() > 0) {
-                            queryDataResult.addAll(dataResult);
-                            dataResult.clear();
-                        }
-                    }
+                        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("质量检验评定表"))
@@ -163,21 +164,32 @@ public class NeiYeController {
                     return R.data(300, null, "未查询到数据");
                 }
                 //上报批次  ,保存节点的时候没有上传批次,只能去流程查
-                for (QueryProcessDataVO vo : queryDataResult) {
-                    if (vo.getInformationQueryId() != null && vo.getStatus() != 0){
-                        List<Task> tasks = taskClient.queryTaskListByFormDataId(vo.getInformationQueryId());
-                        Task task = new Task();
-                        if (tasks == null || tasks.size() <= 0){
-                            task.setBatch(0);
-                        }else {
-                            tasks = tasks.stream().sorted(Comparator.comparing(e -> e.getCreateTime())).collect(Collectors.toList());
-                            task = tasks.get(tasks.size() - 1);
-                        }
-                        vo.setReportNumber(task.getBatch()+"");
+                Map<String, String> tasks = taskClient.queryContractAllBatch(queryVO.getContractId());
+                Set<String> keySet = tasks.keySet();
+                queryDataResult.stream().forEach(qdr->{
+                    if (keySet.contains(qdr.getInformationQueryId())){
+                        qdr.setReportNumber(tasks.get(qdr.getInformationQueryId()));
                     }else {
-                        vo.setReportNumber("0");
+                        qdr.setReportNumber("0");
                     }
-                }
+                });
+//                for (QueryProcessDataVO vo : queryDataResult) {
+//                    if (vo.getInformationQueryId() != null && vo.getStatus() != 0){
+//                        List<Task> tasks = taskClient.queryTaskListByFormDataId(vo.getInformationQueryId());
+//                        Task task = new Task();
+//                        if (tasks == null || tasks.size() <= 0){
+//                            task.setBatch(0);
+//                        }else {
+//                            tasks = tasks.stream().sorted(Comparator.comparing(e -> e.getCreateTime())).collect(Collectors.toList());
+//                            task = tasks.get(tasks.size() - 1);
+//                        }
+//                        vo.setReportNumber(task.getBatch()+"");
+//                    }else {
+//                        vo.setReportNumber("0");
+//                    }
+//                }
+                List<String> collect = queryDataResult.stream().map(qdr -> qdr.getInformationQueryId()).collect(Collectors.toList());
+                System.out.println("\u001B[31m" + collect.contains("1584389365004500992") + "\u001B[0m");
                 String reportNumber = queryVO.getReportNumber();
                 if (!"".equals(reportNumber) && !"null".equals(reportNumber) && reportNumber != null) {
                     queryDataResult = queryDataResult.stream()
@@ -195,7 +207,6 @@ public class NeiYeController {
                 List<ConstructionLedger> ledgers = this.constructionLedgerService.list(Wrappers.<ConstructionLedger>lambdaQuery().in(ConstructionLedger::getWbsId, primaryKeyIds));
 
                 for (QueryProcessDataVO vo : groupQueryList) {
-
                     //处理父节点信息
                     Map<String, String> map = new HashMap<>();
                     this.foreachGetParent(map, idToNodeMap, vo.getParentId(), contractId);
@@ -231,7 +242,7 @@ public class NeiYeController {
                             map.get("detectionStartToEndTime"),
                             new Integer("1").equals(vo.getStatus()) ? "待审批" : new Integer("2").equals(vo.getStatus()) ? "已审批" : "未上报",
                             vo.getEvaluate(),
-                            "false",
+                            vo.getIsExperiment(),
                             vo.getReportNumber()));
                 }
                 //转换为page信息

+ 544 - 529
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,465 +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);
-			}
-
-			//修改试验填报状态
-			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){
-		return R.data(this.taskService.queryBatchListTwo(projectId, contractId));
-	}
-
-
-	/**
-	 * 获取任务类型或任务状态
-	 */
-	@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){
@@ -533,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);
-
-			//修改试验填报状态 TODO 暂时不清楚该接口是否需要
-			this.iTrialSelfInspectionRecordService.updateTrialSelfInspectionRecordStatus(taskApprovalVOS);
-
-			return R.data(true, "当前等待电签的批次较多,请等待几分钟后刷新页面查看........");
-		} else {
-			//生成等待批次,任务完成后删除
-			List<TaskApprovalVO> taskApprovalVOS = new ArrayList<>();
-			taskApprovalVOS.add(taskApprovalVO);
-			this.taskService.batchCompleteApprovalTask(taskApprovalVOS,AuthUtil.getUserId());
-
-			//修改试验填报状态 TODO 暂时不清楚该接口是否需要
-			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, "操作失败,请联系管理员");
+    }
 
 }

+ 0 - 29
blade-service/blade-business/src/main/java/org/springblade/business/controller/TestDemoController.java

@@ -1,29 +0,0 @@
-package org.springblade.business.controller;
-
-import lombok.AllArgsConstructor;
-import org.springblade.business.socket.WebSocket;
-import org.springblade.core.boot.ctrl.BladeController;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-import java.io.IOException;
-
-@RestController
-@AllArgsConstructor
-@RequestMapping("/task")
-public class TestDemoController extends BladeController {
-
-    private WebSocket webSocket;
-
-    @PostMapping("/sentMessage")
-    public void sentMessage(String userId,String message){
-        try {
-            webSocket.sendMessageByUserId(userId,message);
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-    }
-
-
-}

+ 84 - 24
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,33 +10,38 @@ 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;
 
@@ -50,6 +57,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 +97,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));
     }
 
@@ -124,7 +132,7 @@ public class TrialDetectionController extends BladeController {
     @PostMapping("/self/submit")
     @ApiOperationSupport(order = 11)
     @ApiOperation(value = "自检记录新增或修改", notes = "传入TrialSelfInspectionRecordDTO")
-    public R<Object> selfSubmit(@Valid @RequestBody TrialSelfInspectionRecordDTO dto) {
+    public R<Object> selfSubmit(@Valid @RequestBody TrialSelfInspectionRecordDTO dto) throws FileNotFoundException {
         return R.data(iTrialSelfInspectionRecordService.selfSubmit(dto));
     }
 
@@ -139,7 +147,33 @@ 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")
@@ -170,26 +204,55 @@ 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);
-        assert obj != null;
-        return R.data(obj.getPdfUrl());
+        if (obj != null) {
+            return R.data(obj.getPdfUrl());
+        }
+        return R.data("");
     }
 
     @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("无历史数据预览请保存数据");
         }
     }
 
@@ -213,7 +276,9 @@ public class TrialDetectionController extends BladeController {
     @ApiOperationSupport(order = 21)
     @ApiOperation(value = "关联原材检测报告保存或修改", notes = "传入RawMaterialSubmitRelationDTO")
     public R<Object> rawMaterialSubmitRelation(@RequestBody RawMaterialSubmitRelationDTO dto) throws FileNotFoundException {
-        return R.status(iTrialSelfInspectionRecordService.rawMaterialSubmitRelation(dto));
+        //TODO 已剥离,融合到自检记录保存中
+        //return R.status(iTrialSelfInspectionRecordService.rawMaterialSubmitRelation(dto));
+        return R.status(true);
     }
 
     @PostMapping("/self/print-pdf")
@@ -264,18 +329,13 @@ 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 {
-        return R.status(iTrialSelfInspectionRecordService.recordProjectPosition(dto));
-    }
-
     @PostMapping("/self/record-sample/submit")
     @ApiOperationSupport(order = 27)
     @ApiOperation(value = "自检记录关联取样信息保存", notes = "传入RecordSampleSubmitDTO")
     public R<Object> recordSampleSubmit(@Valid @RequestBody RecordSampleSubmitDTO dto) {
-        return R.status(iTrialSelfInspectionRecordService.recordSampleSubmit(dto));
+        //TODO 已剥离,融合到自检记录保存中
+        //return R.status(iTrialSelfInspectionRecordService.recordSampleSubmit(dto));
+        return R.status(true);
     }
 
 }

+ 7 - 1
blade-service/blade-business/src/main/java/org/springblade/business/feignClient/TaskClientImpl.java

@@ -16,6 +16,7 @@ import org.springblade.core.tool.api.R;
 import org.springblade.manager.feign.EVisaConfigClient;
 import org.springframework.web.bind.annotation.RestController;
 import java.util.List;
+import java.util.Map;
 
 @RestController
 @AllArgsConstructor
@@ -29,6 +30,11 @@ public class TaskClientImpl implements TaskClient {
 
     private final ITaskParallelService taskParallelService;
 
+    @Override
+    public Map<String,String> queryContractAllBatch(String contract) {
+        return taskService.queryContractAllBatch(contract);
+    }
+
     @Override
     public String queryTaskContractId(String taskId) {
         //找到任务
@@ -45,7 +51,7 @@ public class TaskClientImpl implements TaskClient {
         Task task = this.queryTask(taskId);
         if(task != null){
             //存在任务,根据formDataId查询(获取 私有项目的 p_key_ids)
-            List<String> privatePrimaryKeyIds = this.informationQueryService.queryBusinessTableData(task.getFormDataId());
+            List<String> privatePrimaryKeyIds = this.informationQueryService.queryBusinessTableData(task.getFormDataId(),task.getTrialSelfInspectionRecordId());
             if(privatePrimaryKeyIds != null && privatePrimaryKeyIds.size() > 0){
                 //查询这些表格的电签配置
                 return this.eVisaConfigClient.queryEVisaConfigByTableIds(privatePrimaryKeyIds, task.getContractId(), isFinal);

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

@@ -21,6 +21,8 @@ import org.springblade.business.vo.InformationQueryVO;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import java.util.List;
+import java.util.Map;
+
 import org.apache.ibatis.annotations.Param;
 import org.springblade.business.vo.QueryProcessDataVO;
 import org.springblade.manager.entity.WbsTreeContract;
@@ -104,6 +106,9 @@ public interface InformationQueryMapper extends BaseMapper<InformationQuery> {
 	// 节点复制数据
 	boolean copeNodeData(String nodeId, String vocationalId);
 
-
+	// 获取当前节点的子节点及自己
 	List<WbsTreeContract> getNodeChildAllByNodeId(String nodeId,String contractId,String pKeyId);
+
+	// 获取当前节点下,所有表单的字段数据
+	List<QueryProcessDataVO> getNodeChildTabColsAllByNodeId(String nodeId, String contractId);
 }

+ 17 - 5
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">
@@ -237,10 +238,10 @@
                     m_wbs_tree_contract AS wtc
                 <choose>
                     <when test="parentId == '0' || parentId == 0 || parentId == '' || parentId == null">
-                        LEFT JOIN m_wbs_tree_contract AS wtc1 ON wtc1.ancestors like concat('%', '0', '%') AND wtc1.is_deleted = 0 and wtc1.contract_id = wtc.contract_id AND wtc1.major_data_type IN(1,2,3,4)
+                        LEFT JOIN m_wbs_tree_contract AS wtc1 ON wtc1.ancestors like concat('%', '0', '%') AND wtc1.is_deleted = 0 and wtc1.contract_id = wtc.contract_id AND wtc1.major_data_type IN(0,1,2,3,4)
                     </when>
                     <otherwise>
-                        LEFT JOIN m_wbs_tree_contract AS wtc1 ON wtc1.ancestors like concat('%', wtc.id, '%') AND wtc1.is_deleted = 0 and wtc1.contract_id = wtc.contract_id AND wtc1.major_data_type IN(1,2,3,4)
+                        LEFT JOIN m_wbs_tree_contract AS wtc1 ON wtc1.ancestors like concat('%', wtc.id, '%') AND wtc1.is_deleted = 0 and wtc1.contract_id = wtc.contract_id AND wtc1.major_data_type IN(0,1,2,3,4)
                     </otherwise>
                 </choose>
                 LEFT JOIN u_information_query AS iq ON (iq.wbs_id = wtc1.p_key_id OR iq.wbs_id = wtc.p_key_id) AND iq.classify = #{classify} AND iq.type != 3
@@ -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,13 +563,15 @@
             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
         WHERE
             wtc.type = 1
-          AND wtc.major_data_type in(1,2,3,4)
+          AND wtc.major_data_type in(0,1,2,3,4)
           AND wtc.ancestors like concat('%',#{parentId},'%')
           AND wtc.contract_id = #{contractId}
           AND wtc.is_deleted = 0
@@ -608,4 +613,11 @@
             or wtc.p_key_id=#{pKeyId}
 
     </select>
+
+    <!--获取当前节点下,所有表单的字段数据-->
+    <select id="getNodeChildTabColsAllByNodeId" resultMap="queryProcessDataMap">
+        SELECT table_name as queryType,GROUP_CONCAT(COLUMN_name) as ancestors from information_schema.COLUMNS where table_name
+            in(SELECT init_table_name from m_wbs_tree_contract a WHERE a.ancestors like concat('%',#{nodeId},'%') and contract_id=#{contractId} and type=2 and is_deleted=0)
+        GROUP BY table_name
+    </select>
 </mapper>

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

@@ -36,4 +36,11 @@ public interface TaskMapper extends BaseMapper<Task> {
 
     List<String> queryBatchListTwo(@Param("projectId") String projectId, @Param("contractId") String contractId);
 
+    List<String> queryBatchListThree(@Param("projectId") String projectId, @Param("contractId") String contractId);
+
+    List<String> queryBatchListFirst(@Param("projectId") String projectId, @Param("contractId") String contractId);
+
+    List<String> queryBatchListFlagFirst(@Param("projectId") String projectId, @Param("contractId") String contractId);
+
+    List<Task> queryContractAllBatch(String contract);
 }

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

@@ -51,11 +51,40 @@
         group by batch
     </select>
     <select id="queryBatchListTwo" resultType="java.lang.String">
-        select DISTINCT batch from u_task where is_deleted = 0 and status in (1,2) and project_id = #{projectId}
+        select DISTINCT batch from u_task
+        where is_deleted = 0 and status in (1,2) and project_id = #{projectId} and approval_type = 1 and form_data_id in
+        (SELECT id from u_information_query WHERE type=1 and `status` in (1,2)
         <if test="contractId != null and contractId != ''">
             and contract_id = #{contractId}
+        </if>)
+        order by batch
+    </select>
+    <select id="queryBatchListThree" resultType="java.lang.String">
+        select DISTINCT u.batch from u_task u LEFT JOIN u_information_query iq on u.form_data_id=iq.id
+        where  u.is_deleted = 0 and iq.type = 1 and u.status in (1, 2) and u.project_id = #{projectId} and u.approval_type = 1
+        <if test="contractId != null and contractId != ''">
+            and u.contract_id = #{contractId}
+        </if>
+        order by u.batch;
+    </select>
+    <select id="queryBatchListFirst" resultType="java.lang.String">
+        select DISTINCT u.batch from u_task u LEFT JOIN u_information_query iq on u.form_data_id=iq.id
+        where  u.is_deleted = 0 and iq.type = 3 and u.status in (1, 2) and u.project_id = #{projectId} and u.approval_type = 1
+        <if test="contractId != null and contractId != ''">
+            and u.contract_id = #{contractId}
         </if>
+        order by u.batch;
+    </select>
+    <select id="queryBatchListFlagFirst" resultType="java.lang.String">
+        select DISTINCT batch from u_task
+        WHERE form_data_id IN
+              (SELECT id from u_information_query WHERE wbs_id in (select wbs_node_id from u_tree_contract_first WHERE contract_id = #{contractId}) and type = 1) and `status` in(1,2) and approval_type = 1
         order by batch
     </select>
+    <select id="queryContractAllBatch" resultMap="taskResultMap">
+        select form_data_id,batch  from u_task
+        where is_deleted = 0 and status in (1, 2) and contract_id =  #{contractId}
+        GROUP BY form_data_id ;
+    </select>
 
 </mapper>

+ 7 - 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);
 
@@ -41,4 +42,7 @@ public interface TrialSelfInspectionRecordMapper extends BaseMapper<TrialSelfIns
 
     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);
+
 }

+ 2 - 2
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">
@@ -64,7 +64,7 @@
     </delete>
 
     <select id="selectAll" resultType="org.springblade.business.entity.TrialSelfInspectionRecord">
-        select record_no,report_no from u_trial_self_inspection_record where node_id = #{nodeId} and contract_id = #{contractId}
+        select record_no,report_no from u_trial_self_inspection_record where node_id = #{nodeId} and contract_id = #{contractId} and is_deleted = 0
     </select>
 
     <select id="selectSelfSampleRecord" resultType="java.lang.String">

+ 79 - 73
blade-service/blade-business/src/main/java/org/springblade/business/service/IInformationQueryService.java

@@ -30,80 +30,83 @@ import java.util.List;
 import java.util.Map;
 
 /**
- *  服务类
+ * 服务类
  *
  * @author BladeX
  * @since 2022-06-08
  */
 public interface IInformationQueryService extends BaseService<InformationQuery> {
 
-	/**
-	 * 获取表格信息
-	 */
-	List<String> queryBusinessTableData(String formDataId);
-
-	/**
-	 * 获取合同段树(监理方)
-	 */
-	List<WbsTreeContractTreeVOS> queryContractTreeSupervision(List<String> contractIds, String parentId, Integer classify);
-
-	/**
-	 * 获取合同段树(施工方)
-	 */
-	List<WbsTreeContractTreeVOS> queryContractTree(String contractId, String parentId, Integer classify);
-
-	/**
-	 * 查询工序节点的填报记录
-	 */
-	List<QueryProcessDataVO> queryProcessDataByPrimaryKeyIdAndClassify(String primaryKeyId, Integer classify);
-
-	/**
-	 * 查询工序节点的填报记录
-	 */
-	List<QueryProcessDataVO> queryProcessDataByParentIdAndContractId(String parentId, Integer classify, String contractId);
-
-	/**
-	 * 查询工序节点的填报记录,简化
-	 */
-	List<QueryProcessDataVO> queryProcessDataByParentIdAndContractIdTwo(String parentId, Integer classify, String contractId);
-
-	/**
-	 * 查询工序节点的填报记录,status不默认为0,资料进度统计
-	 */
-	List<QueryProcessDataVO> queryProcessDataByParentIdAndContractIdThree(String parentId, Integer classify, String contractId);
-
-	/**
-	 * 保存填报时新增或修改填报资料记录表数据
-	 * @param wbsId 当前填报节点
-	 * @param fileName 文件题名
-	 * @param classify 1施工2质检
-	 * @param sourceType 1原生2数据化
-	 */
-	String saveOrUpdateInformationQueryData(String wbsId, String tableId,
-										  String businessId, String fileName,
-										  Integer classify, Integer sourceType,
-										  String isFirst, String sourceUrl, String pdfUrl, String firstFileName, List<JSONObject> linkDataList);
-
-	/**
-	 * 获取当前合同段下所有的上报批次
-	 * @param classify 合同段类型
-	 * @param contractId 合同段ID
-	 * @return 结果
-	 */
-	List<Integer> getReportNumberByContractId(Integer classify, String contractId);
-
-	/**
-	 * 根据合同段ID获取所有填报人
-	 * @param classify 合同段类型
-	 * @param contractId 合同段ID
-	 * @return 填报人集合
-	 */
-	List<FileUserVO> queryFileUserByContractId(Integer classify, String contractId);
-
-	/**
-	 * 自定义分页
-	 */
-	IPage<InformationQueryVO> selectInformationQueryPage(IPage<InformationQueryVO> page, InformationQueryVO vo);
+    /**
+     * 获取表格信息
+     */
+    List<String> queryBusinessTableData(String formDataId, Long trialSelfInspectionRecordId);
+
+    /**
+     * 获取合同段树(监理方)
+     */
+    List<WbsTreeContractTreeVOS> queryContractTreeSupervision(List<String> contractIds, String parentId, Integer classify);
+
+    /**
+     * 获取合同段树(施工方)
+     */
+    List<WbsTreeContractTreeVOS> queryContractTree(String contractId, String parentId, Integer classify);
+
+    /**
+     * 查询工序节点的填报记录
+     */
+    List<QueryProcessDataVO> queryProcessDataByPrimaryKeyIdAndClassify(String primaryKeyId, Integer classify);
+
+    /**
+     * 查询工序节点的填报记录
+     */
+    List<QueryProcessDataVO> queryProcessDataByParentIdAndContractId(String parentId, Integer classify, String contractId);
+
+    /**
+     * 查询工序节点的填报记录,简化
+     */
+    List<QueryProcessDataVO> queryProcessDataByParentIdAndContractIdTwo(String parentId, Integer classify, String contractId);
+
+    /**
+     * 查询工序节点的填报记录,status不默认为0,资料进度统计
+     */
+    List<QueryProcessDataVO> queryProcessDataByParentIdAndContractIdThree(String parentId, Integer classify, String contractId);
+
+    /**
+     * 保存填报时新增或修改填报资料记录表数据
+     *
+     * @param wbsId      当前填报节点
+     * @param fileName   文件题名
+     * @param classify   1施工2质检
+     * @param sourceType 1原生2数据化
+     */
+    String saveOrUpdateInformationQueryData(String wbsId, String tableId,
+                                            String businessId, String fileName,
+                                            Integer classify, Integer sourceType,
+                                            String isFirst, String sourceUrl, String pdfUrl, String firstFileName, List<JSONObject> linkDataList);
+
+    /**
+     * 获取当前合同段下所有的上报批次
+     *
+     * @param classify   合同段类型
+     * @param contractId 合同段ID
+     * @return 结果
+     */
+    List<Integer> getReportNumberByContractId(Integer classify, String contractId);
+
+    /**
+     * 根据合同段ID获取所有填报人
+     *
+     * @param classify   合同段类型
+     * @param contractId 合同段ID
+     * @return 填报人集合
+     */
+    List<FileUserVO> queryFileUserByContractId(Integer classify, String contractId);
+
+    /**
+     * 自定义分页
+     */
+    IPage<InformationQueryVO> selectInformationQueryPage(IPage<InformationQueryVO> page, InformationQueryVO vo);
 
 
     List<WbsTreeContract> getContractWbsTreeAll(WbsTreeContract wbsTreeContract);
@@ -111,11 +114,14 @@ public interface IInformationQueryService extends BaseService<InformationQuery>
     void updateBatchByPKeyId(List<WbsTreeContract> result);
 
     //获取当前合同所有填报表
-	public Map<String, Long> getTreeAllTable(String contractId);
+    public Map<String, Long> getTreeAllTable(String contractId);
 
-	// 复制节点数据
-	boolean copeNodeData(String nodeId,String vocationalId);
+    // 复制节点数据
+    boolean copeNodeData(String nodeId, String vocationalId);
 
-	// 获取当前节点下所有子节点
-	List<WbsTreeContract> getNodeChildAllByNodeId(String nodeId,String contractId,String pKeyId);
+    // 获取当前节点下所有子节点
+    List<WbsTreeContract> getNodeChildAllByNodeId(String nodeId, String contractId, String pKeyId);
+
+    // 获取当前节点所有的表的字段信息
+    List<QueryProcessDataVO> getNodeChildTabColsAllByNodeId(String nodeId, String contractId);
 }

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

@@ -71,5 +71,13 @@ public interface ITaskService extends BaseService<Task> {
      * 获取当前合同段有哪些上报批次
      */
     List<String> queryBatchListTwo(String projectId, String contractId);
+    /**
+     * 获取当前合同段有哪些上报批次,内页台账用
+     */
+    List<String> queryBatchListThree(String projectId, String contractId,String type);
 
+    /**
+     *  获取当前合同段所有上报资料的上报批次
+     */
+    Map<String,String> queryContractAllBatch(String contract);
 }

+ 4 - 6
blade-service/blade-business/src/main/java/org/springblade/business/service/ITrialSelfInspectionRecordService.java

@@ -13,9 +13,9 @@ 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) ;
+    String selfSubmit(TrialSelfInspectionRecordDTO dto) throws FileNotFoundException;
 
     List<TrialSampleInfoVO> selfSampleList(String id);
 
@@ -27,14 +27,14 @@ public interface ITrialSelfInspectionRecordService extends BaseService<TrialSelf
 
     List<TrialSelfInspectionRecordVO2> getRawMaterialInfo(String nodeId, String contractId, String id);
 
-    boolean rawMaterialSubmitRelation(RawMaterialSubmitRelationDTO dto) throws FileNotFoundException;
+    boolean rawMaterialSubmitRelation(RawMaterialSubmitRelationDTO dto, TrialSelfInspectionRecord obj) throws FileNotFoundException;
 
     String selfPrintPdf(String ids) throws FileNotFoundException;
 
     String selfPrintNullPdf(String ids) throws Exception;
 
     @Async
-    void updateTrialSelfInspectionRecordStatus(List<TaskApprovalVO> obj);
+    void updateTrialSelfInspectionRecordStatus(String pdfUrlEVisa, List<TaskApprovalVO> obj) throws FileNotFoundException;
 
     String addBussFile(MultipartFile file, Long pkeyId, String nodeId, String contractId, String projectId, String classify, String id, String tableType) throws Exception;
 
@@ -42,8 +42,6 @@ public interface ITrialSelfInspectionRecordService extends BaseService<TrialSelf
 
     boolean fileSubmit(TrialFileSubmitDTO dto) throws FileNotFoundException;
 
-    boolean recordProjectPosition(SelfProjectPositionSubmitDTO dto) throws FileNotFoundException;
-
     boolean recordSampleSubmit(RecordSampleSubmitDTO dto);
 
 }

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

@@ -76,7 +76,12 @@ public class ImageClassificationFileServiceImpl extends BaseServiceImpl<ImageCla
 			//查询下级节点信息
 //			imageClassificationFile.setWbsIds(JSONArray.parseArray(JSONObject.toJSONString(imageClassificationFile.getWbsIdsStr().split(",")), String.class));
 			WbsTreeContract node = wbsTreeContractClient.getContractWbsTreeByPrimaryKeyId(Long.valueOf(imageClassificationFile.getWbsIdsStr()));
-			List<WbsTreeContract> wbsTreeContracts = wbsTreeContractClient.queryCurrentNodeAllChild(imageClassificationFile.getContractId(), node.getId());
+			List<WbsTreeContract> wbsTreeContracts = new ArrayList<>();
+			if (node.getParentId()==0){
+				wbsTreeContracts = wbsTreeContractClient.queryAllChild(imageClassificationFile.getContractId());
+			}else {
+				wbsTreeContracts = wbsTreeContractClient.queryCurrentNodeAllChild(imageClassificationFile.getContractId(), node.getId());
+			}
 			wbsTreeContracts.add(node);
 			imageClassificationFile.setWbsIds(wbsTreeContracts.stream().map(wtc->wtc.getPKeyId()+"").collect(Collectors.toList()));
 		}

+ 49 - 25
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/InformationQueryServiceImpl.java

@@ -31,6 +31,8 @@ import org.springblade.resource.feign.NewIOSSClient;
 import org.springblade.system.cache.ParamCache;
 import org.springblade.system.user.entity.User;
 import org.springblade.system.user.feign.IUserClient;
+import org.springframework.jdbc.core.BeanPropertyRowMapper;
+import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.stereotype.Service;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 
@@ -65,29 +67,43 @@ public class InformationQueryServiceImpl extends BaseServiceImpl<InformationQuer
 
     private final ContractClient contractClient;
 
+    private final JdbcTemplate jdbcTemplate;
+
     @Override
-    public List<String> queryBusinessTableData(String formDataId) {
+    public List<String> queryBusinessTableData(String formDataId, Long trialSelfInspectionRecordId) {
         //获取具体业务数据
         InformationQuery query = this.getById(formDataId);
 
         //查询这个业务数据绑定的表格,需要区分监理和施工
         if (query != null) {
+            List<WbsTreeContract> tableList = new ArrayList<>();
+            if (query.getType() == 1) { //质检
                 // 获取wbs
                 WbsTreeContract tree = this.wbsTreeContractClient.getContractWbsTreeByPrimaryKeyId(query.getWbsId());
-                List<WbsTreeContract> tableList = new ArrayList<>();
-                if(query.getType()==1){ //质检
-                    // 获取 合同端信息表
-                    tableList= this.wbsTreeContractClient.queryChildByParentId(tree, "queryTable", String.valueOf(query.getClassify()));
-                }else if(query.getType()==3){ //首件数据
-                    // 获取首件 数据节点信息
-                   tableList = this.wbsTreeContractClient.queryContractFirstTab(tree.getContractId(), "111");
-                }
-                if (tableList != null && tableList.size() > 0) {
-                    //删除掉无法溯源的数据
-                    tableList.removeIf(node -> node.getIsTypePrivatePid() == null || node.getIsTypePrivatePid() <= 0 || StringUtils.isEmpty(node.getIsTypePrivatePid().toString()));
-                    List<Long> privatePIdList = tableList.stream().map(WbsTreeContract::getIsTypePrivatePid).distinct().collect(Collectors.toList());
-                    return JSONArray.parseArray(JSONObject.toJSONString(privatePIdList), String.class);
+                // 获取合同端信息表
+                tableList = this.wbsTreeContractClient.queryChildByParentId(tree, "queryTable", String.valueOf(query.getClassify()));
+            } else if (query.getType() == 3) { //首件数据
+                // 获取wbs
+                WbsTreeContract tree = this.wbsTreeContractClient.getContractWbsTreeByPrimaryKeyId(query.getWbsId());
+                // 获取首件数据节点信息
+                tableList = this.wbsTreeContractClient.queryContractFirstTab(tree.getContractId(), "111");
+            }
+            if (tableList != null && tableList.size() > 0) {
+                //删除掉无法溯源的数据
+                tableList.removeIf(node -> node.getIsTypePrivatePid() == null || node.getIsTypePrivatePid() <= 0 || StringUtils.isEmpty(node.getIsTypePrivatePid().toString()));
+                List<Long> privatePIdList = tableList.stream().map(WbsTreeContract::getIsTypePrivatePid).distinct().collect(Collectors.toList());
+                return JSONArray.parseArray(JSONObject.toJSONString(privatePIdList), String.class);
+
+                //TODO ------试验 2023-03-14 liuYC------
+            } else if (query.getType() == 2) { //试验
+                // 获取试验对应表pKeyIds
+                String sql = "select table_ids from u_trial_self_inspection_record where is_deleted = 0 and id = " + trialSelfInspectionRecordId;
+                TrialSelfInspectionRecord obj = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(TrialSelfInspectionRecord.class)).stream().findAny().orElse(null);
+                if (obj != null && StringUtils.isNotEmpty(obj.getTableIds())) {
+                    return Func.toStrList(obj.getTableIds());
                 }
+            }
+
         } else {
             //那么就可能是日志,检查是不是日志
             ContractLog log = this.contractLogService.getById(formDataId);
@@ -123,12 +139,14 @@ public class InformationQueryServiceImpl extends BaseServiceImpl<InformationQuer
         }
         return result;
     }
+
     //简化
     @Override
     public List<QueryProcessDataVO> queryProcessDataByParentIdAndContractIdTwo(String parentId, Integer classify, String contractId) {
         List<QueryProcessDataVO> result = this.baseMapper.queryProcessDataByParentIdAndContractIdTwo(parentId, classify, contractId);
         return result;
     }
+
     //资料进度统计使用
     @Override
     public List<QueryProcessDataVO> queryProcessDataByParentIdAndContractIdThree(String parentId, Integer classify, String contractId) {
@@ -554,33 +572,34 @@ public class InformationQueryServiceImpl extends BaseServiceImpl<InformationQuer
     /**
      * 获取当前合同所有填报表
      */
-    public Map<String, Long> getTreeAllTable(String contractId){
+    public Map<String, Long> getTreeAllTable(String contractId) {
         //总数据
         List<WbsTreeContractTreeVOS> list = new ArrayList<>();
-        this.getAllTable("",contractId,list);
-        Map<String,Long> map = new HashMap<>();
-        list.stream().forEach(li->map.put(li.getId()+"",li.getSubmitCounts()));
+        this.getAllTable("", contractId, list);
+        Map<String, Long> map = new HashMap<>();
+        list.stream().forEach(li -> map.put(li.getId() + "", li.getSubmitCounts()));
         return map;
     }
 
     @Override
     public boolean copeNodeData(String nodeId, String vocationalId) {
-        return baseMapper.copeNodeData(nodeId,vocationalId);
+        return baseMapper.copeNodeData(nodeId, vocationalId);
     }
 
     /**
      * 递归调用获取合同所有填报表
      */
-    public void getAllTable(String parentId,String contractId, List<WbsTreeContractTreeVOS> list){
+    public void getAllTable(String parentId, String contractId, List<WbsTreeContractTreeVOS> list) {
         List<WbsTreeContractTreeVOS> vos = this.queryContractTree(parentId, contractId, "", "1");
-        if (vos != null && vos.size() > 0){
-            vos = vos.stream().filter(vo->vo.getSubmitCounts()!=0).collect(Collectors.toList());
+        if (vos != null && vos.size() > 0) {
+            vos = vos.stream().filter(vo -> vo.getSubmitCounts() != 0).collect(Collectors.toList());
             list.addAll(vos);
             for (WbsTreeContractTreeVOS vo : vos) {
-                this.getAllTable(vo.getId()+"",contractId,list);
+                this.getAllTable(vo.getId() + "", contractId, list);
             }
         }
     }
+
     /**
      * 查询合同段划分树公共代码
      */
@@ -627,7 +646,12 @@ public class InformationQueryServiceImpl extends BaseServiceImpl<InformationQuer
     }
 
     @Override
-    public List<WbsTreeContract> getNodeChildAllByNodeId(String nodeId,String contractId,String pKeyId) {
-        return baseMapper.getNodeChildAllByNodeId(nodeId,contractId,pKeyId);
+    public List<WbsTreeContract> getNodeChildAllByNodeId(String nodeId, String contractId, String pKeyId) {
+        return baseMapper.getNodeChildAllByNodeId(nodeId, contractId, pKeyId);
+    }
+
+    @Override
+    public List<QueryProcessDataVO> getNodeChildTabColsAllByNodeId(String nodeId, String contractId) {
+        return baseMapper.getNodeChildTabColsAllByNodeId(nodeId, contractId);
     }
 }

+ 69 - 11
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);
+                    }
                 }
             }
         }
@@ -350,13 +378,31 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
         return baseMapper.queryBatchListTwo(projectId, contractId);
     }
 
+    @Override
+    public List<String> queryBatchListThree(String projectId, String contractId, String type) {
+        if ("1".equals(type)) {
+            return baseMapper.queryBatchListThree(projectId, contractId);
+        } else if ("2".equals(type)) {
+            return baseMapper.queryBatchListFlagFirst(projectId, contractId);
+        } 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() + "");
+        });
+        return map;
+    }
+
     @Override
     public List<Task> queryBatchList(String projectId, String contract) {
         return this.baseMapper.queryBatchList(projectId, contract);
     }
 
-    //@Async
-
     /**
      * 批量电签接口
      *
@@ -396,13 +442,19 @@ 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 (StringUtils.isNotEmpty(pdfUrlEVisa)){
+                    this.iTrialSelfInspectionRecordService.updateTrialSelfInspectionRecordStatus(pdfUrlEVisa, taskApprovalVOS);
+                }
+
             }
             //删除掉对应批次
             this.taskBatchService.deletedById(batchId);
@@ -426,7 +478,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
@@ -439,7 +491,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()));
@@ -494,10 +546,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并添加错误信息
@@ -579,6 +636,7 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
             this.abolishMessage(masterTask, currentLink, comment);
 
         }
+        return "";
     }
 
     /**

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

@@ -361,8 +361,7 @@ public class TrialContainerClassificationServiceImpl
             }
         } else {
             Map.Entry<Long, String> map = beanMap.entrySet().stream().filter(f -> f.getKey().equals(id)).findAny().orElse(null);
-            assert map != null;
-            if (!map.getValue().equals(bean.getFieldValue())) {
+            if (map != null && !map.getValue().equals(bean.getFieldValue())) {
                 String obj = values.stream().filter(f -> f.equals(bean.getFieldValue())).findAny().orElse(null);
                 if (obj != null) {
                     return "编号已存在,请重新输入";

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

@@ -88,22 +88,24 @@ public class TrialDetectionDataServiceImpl extends BaseServiceImpl<TrialDetectio
             List<TrialDetectionData> insertData = new ArrayList<>();
             for (TrialDetectionData trialDetectionDatum : trialDetectionData) {
                 TrialDetectionData obj = BeanUtil.copyProperties(trialDetectionDatum, TrialDetectionData.class);
-                assert obj != null;
-                obj.setId(SnowFlakeUtil.getId());
-                obj.setEntrustNo(String.valueOf(SnowFlakeUtil.getId()));
-                obj.setReportNo(String.valueOf(SnowFlakeUtil.getId()));
-                insertData.add(obj);
+                if (obj != null) {
+                    obj.setId(SnowFlakeUtil.getId());
+                    obj.setEntrustNo(String.valueOf(SnowFlakeUtil.getId()));
+                    obj.setReportNo(String.valueOf(SnowFlakeUtil.getId()));
+                    insertData.add(obj);
+                }
             }
             this.saveBatch(insertData);
 
         } else {
             //单条复制编辑新增保存
             TrialDetectionData obj = BeanUtil.copyProperties(dto, TrialDetectionData.class);
-            assert obj != null;
-            obj.setId(SnowFlakeUtil.getId());
-            obj.setEntrustNo(String.valueOf(SnowFlakeUtil.getId()));
-            obj.setReportNo(String.valueOf(SnowFlakeUtil.getId()));
-            this.save(obj);
+            if (obj != null){
+                obj.setId(SnowFlakeUtil.getId());
+                obj.setEntrustNo(String.valueOf(SnowFlakeUtil.getId()));
+                obj.setReportNo(String.valueOf(SnowFlakeUtil.getId()));
+                this.save(obj);
+            }
         }
         return true;
     }

+ 4 - 2
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TrialDeviceOverhaulServiceImpl.java

@@ -70,8 +70,10 @@ public class TrialDeviceOverhaulServiceImpl extends BaseServiceImpl<TrialDeviceO
             dto.setFactoryNumber(trialDeviceInfo.getFactoryNumber());
         }
         TrialDeviceOverhaul trialDeviceOverhaul = BeanUtil.copyProperties(dto, TrialDeviceOverhaul.class);
-        assert trialDeviceOverhaul != null;
-        return this.saveOrUpdate(trialDeviceOverhaul);
+        if (trialDeviceOverhaul != null){
+            return this.saveOrUpdate(trialDeviceOverhaul);
+        }
+        return false;
     }
 
     @Override

+ 4 - 2
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TrialDeviceUseServiceImpl.java

@@ -72,8 +72,10 @@ public class TrialDeviceUseServiceImpl extends BaseServiceImpl<TrialDeviceUseMap
             dto.setFactoryNumber(trialDeviceInfo.getFactoryNumber());
         }
         TrialDeviceUse trialDeviceUse = BeanUtil.copyProperties(dto, TrialDeviceUse.class);
-        assert trialDeviceUse != null;
-        return this.saveOrUpdate(trialDeviceUse);
+        if (trialDeviceUse != null){
+            return this.saveOrUpdate(trialDeviceUse);
+        }
+        return false;
     }
 
     @Override

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

@@ -67,8 +67,7 @@ public class TrialMaterialMobilizationServiceImpl extends BaseServiceImpl<TrialM
             return trialMaterialMobilization1 != null;
         } else {
             TrialMaterialMobilization trialMaterialMobilization = list.stream().filter(f -> f.getId().equals(Long.parseLong(id))).findAny().orElse(null);
-            assert trialMaterialMobilization != null;
-            if (!trialMaterialMobilization.getMaterialNumber().equals(number)) {
+            if (trialMaterialMobilization != null && !trialMaterialMobilization.getMaterialNumber().equals(number)) {
                 TrialMaterialMobilization trialMaterialMobilization1 = list.stream().filter(f -> f.getMaterialNumber().equals(number)).findAny().orElse(null);
                 return trialMaterialMobilization1 != null;
             }
@@ -148,10 +147,11 @@ public class TrialMaterialMobilizationServiceImpl extends BaseServiceImpl<TrialM
         }
         data.forEach(excel -> {
             TrialMaterialMobilization trialMaterialMobilization = BeanUtil.copyProperties(excel, TrialMaterialMobilization.class);
-            assert trialMaterialMobilization != null;
-            trialMaterialMobilization.setUserId(SecureUtil.getUserId());
-            trialMaterialMobilization.setContractId(contractId);
-            list.add(trialMaterialMobilization);
+            if (trialMaterialMobilization != null){
+                trialMaterialMobilization.setUserId(SecureUtil.getUserId());
+                trialMaterialMobilization.setContractId(contractId);
+                list.add(trialMaterialMobilization);
+            }
         });
         if (isCovered) {
             this.saveOrUpdateBatch(list);

+ 15 - 13
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TrialSampleInfoServiceImpl.java

@@ -66,8 +66,7 @@ public class TrialSampleInfoServiceImpl extends BaseServiceImpl<TrialSampleInfoM
             return trialSampleInfo != null;
         } else {
             TrialSampleInfo trialSampleInfo = list.stream().filter(f -> f.getId().equals(Long.parseLong(id))).findAny().orElse(null);
-            assert trialSampleInfo != null;
-            if (!trialSampleInfo.getSpecificationNumber().equals(specificationNumber)) {
+            if (trialSampleInfo != null && !trialSampleInfo.getSpecificationNumber().equals(specificationNumber)) {
                 TrialSampleInfo trialSampleInfo1 = list.stream().filter(f -> f.getSpecificationNumber().equals(specificationNumber)).findAny().orElse(null);
                 return trialSampleInfo1 != null;
             }
@@ -90,9 +89,10 @@ public class TrialSampleInfoServiceImpl extends BaseServiceImpl<TrialSampleInfoM
             for (User user : users) {
                 if (trialSampleInfo.getUserId().equals(user.getId())) {
                     TrialSampleInfoVO3 trialSampleInfoVO3 = BeanUtil.copyProperties(trialSampleInfo, TrialSampleInfoVO3.class);
-                    assert trialSampleInfoVO3 != null;
-                    trialSampleInfoVO3.setUserName(ObjectUtil.isNotEmpty(user.getName()) ? user.getName() : user.getRealName());
-                    list.add(trialSampleInfoVO3);
+                    if (trialSampleInfoVO3 != null) {
+                        trialSampleInfoVO3.setUserName(ObjectUtil.isNotEmpty(user.getName()) ? user.getName() : user.getRealName());
+                        list.add(trialSampleInfoVO3);
+                    }
                 }
             }
         }
@@ -240,11 +240,12 @@ public class TrialSampleInfoServiceImpl extends BaseServiceImpl<TrialSampleInfoM
         }
         data.forEach(excel -> {
             TrialSampleInfo trialSampleInfo = BeanUtil.copyProperties(excel, TrialSampleInfo.class);
-            assert trialSampleInfo != null;
-            trialSampleInfo.setUserId(SecureUtil.getUserId());
-            trialSampleInfo.setContractId(contractId);
-            trialSampleInfo.setNodeId(nodeId);
-            list.add(trialSampleInfo);
+            if (trialSampleInfo != null) {
+                trialSampleInfo.setUserId(SecureUtil.getUserId());
+                trialSampleInfo.setContractId(contractId);
+                trialSampleInfo.setNodeId(nodeId);
+                list.add(trialSampleInfo);
+            }
         });
         if (isCovered) {
             this.saveOrUpdateBatch(list);
@@ -281,9 +282,10 @@ public class TrialSampleInfoServiceImpl extends BaseServiceImpl<TrialSampleInfoM
                 for (User user : userList) {
                     if (trialSampleInfo.getUserId().equals(user.getId())) {
                         TrialSampleInfoVO trialSampleInfoVO = BeanUtil.copyProperties(trialSampleInfo, TrialSampleInfoVO.class);
-                        assert trialSampleInfoVO != null;
-                        trialSampleInfoVO.setUserName(user.getName());
-                        pdfData.add(trialSampleInfoVO);
+                        if (trialSampleInfoVO != null){
+                            trialSampleInfoVO.setUserName(user.getName());
+                            pdfData.add(trialSampleInfoVO);
+                        }
                     }
                 }
             }

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

@@ -3,8 +3,8 @@ package org.springblade.business.service.impl;
 import cn.hutool.core.date.LocalDateTimeUtil;
 import com.alibaba.fastjson.JSONArray;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
-import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.baomidou.mybatisplus.core.toolkit.StringUtils;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.spire.xls.*;
@@ -12,7 +12,6 @@ import lombok.AllArgsConstructor;
 import org.apache.commons.lang.time.DateUtils;
 import org.springblade.business.dto.*;
 import org.springblade.business.entity.*;
-import org.springblade.business.feign.InformationQueryClient;
 import org.springblade.business.mapper.TrialMaterialMobilizationMapper;
 import org.springblade.business.mapper.TrialSampleInfoMapper;
 import org.springblade.business.mapper.TrialSelfInspectionRecordMapper;
@@ -45,6 +44,7 @@ import org.springblade.system.user.entity.User;
 import org.springblade.system.user.feign.IUserClient;
 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;
 import org.springframework.web.multipart.MultipartFile;
@@ -53,6 +53,7 @@ import java.io.File;
 import java.io.FileNotFoundException;
 import java.util.*;
 import java.util.List;
+import java.util.function.Function;
 import java.util.stream.Collectors;
 
 @Service
@@ -66,12 +67,10 @@ public class TrialSelfInspectionRecordServiceImpl
     private final IUserClient iUserClient;
     private final ContractClient contractClient;
     private final WbsTreePrivateClient wbsTreePrivateClient;
-    private final WbsTreeContractClient wbsTreeContractClient;
     private final ExcelTabClient excelTabClient;
     private final IDictClient iDictClient;
     private final JdbcTemplate jdbcTemplate;
     private final NewIOSSClient newIOSSClient;
-    private final InformationQueryClient informationQueryClient;
     private final IOSSClient iossClient;
     private final CommonFileClient commonFileClient;
     private final TableFileClient tableFileClient;
@@ -80,7 +79,7 @@ public class TrialSelfInspectionRecordServiceImpl
     private final TrialDetectionDataServiceImpl trialDetectionDataService;
 
     @Override
-    public IPage<TrialSelfInspectionRecordVO> selfPage(IPage<TrialSelfInspectionRecord> page, TrialSelfInspectionRecordPageDTO dto) {
+    public IPage<TrialSelfInspectionRecordVO> selfPage(IPage<TrialSelfInspectionRecord> page, TrialSelfInspectionRecordPageDTO dto) throws FileNotFoundException {
         QueryWrapper<TrialSelfInspectionRecord> queryWrapper = Condition.getQueryWrapper(dto);
         if (StringUtils.isNotEmpty(dto.getQueryValue())) {
             queryWrapper.lambda().like(TrialSelfInspectionRecord::getTrialProjectName, dto.getQueryValue());
@@ -99,16 +98,18 @@ public class TrialSelfInspectionRecordServiceImpl
         IPage<TrialSelfInspectionRecord> pages = this.page(page, queryWrapper.lambda().orderByDesc(true, TrialSelfInspectionRecord::getCreateTime));
         IPage<TrialSelfInspectionRecordVO> trialSelfInspectionRecordVOIPage = TrialSelfInspectionRecordWarpper.build().pageVO(pages);
         List<TrialSelfInspectionRecordVO> records = trialSelfInspectionRecordVOIPage.getRecords();
-        List<Dict> trialDetectionCategory = iDictClient.getList("trial_detection_category").getData();
+        Map<String, Dict> map = iDictClient.getList("trial_detection_category").getData().stream().collect(Collectors.toMap(Dict::getDictKey, Function.identity()));
 
         for (TrialSelfInspectionRecordVO record : records) {
-            for (Dict dict : trialDetectionCategory) {
-                if (dict.getDictKey().equals(String.valueOf(record.getDetectionCategory()))) {
+            record.setIsUploadCertificateName((new Integer(1)).equals(record.getIsUploadCertificate()) ? "是" : "否");
+            record.setDetectionResultName((new Integer(1)).equals(record.getDetectionResult()) ? "合格" : "不合格");
+
+            if (ObjectUtils.isNotEmpty(record.getDetectionCategory())) {
+                Dict dict = map.get(String.valueOf(record.getDetectionCategory()));
+                if (dict != null) {
                     record.setDetectionCategoryName(dict.getDictValue());
                 }
             }
-            record.setIsUploadCertificateName(record.getIsUploadCertificate().equals(1) ? "是" : "否");
-            record.setDetectionResultName(record.getDetectionResult().equals(1) ? "合格" : "不合格");
 
             //工程部位及用途名称
             if (ObjectUtil.isNotEmpty(record.getProjectPosition())) {
@@ -129,10 +130,66 @@ public class TrialSelfInspectionRecordServiceImpl
             if (query.size() > 0) {
                 record.setSampleIds(org.apache.commons.lang.StringUtils.join(query, ","));
             }
+
+            //原材料检测报告ids
+            String sql1 = "select raw_material_record_id,old_pdf_url from u_trial_raw_material_self_record where self_record_id = " + record.getId();
+            List<TrialRawMaterialSelfRecord> query1 = jdbcTemplate.query(sql1, new BeanPropertyRowMapper<>(TrialRawMaterialSelfRecord.class));
+            if (query1.size() > 0) {
+                List<Long> ids = query1.stream().map(TrialRawMaterialSelfRecord::getRawMaterialRecordId).collect(Collectors.toList());
+                record.setRawMaterialIds(org.apache.commons.lang.StringUtils.join(ids, ","));
+            }
+
+            //合并的pdfUrl
+            String pdf = this.getMergePdfToTrial(record.getContractId(), record.getId());
+            record.setPdfUrl(pdf);
         }
         return trialSelfInspectionRecordVOIPage.setRecords(records);
     }
 
+    private String getMergePdfToTrial(Long contractId, Long nodeId) throws FileNotFoundException {
+        String sql = "select pdf_url,e_visa_pdf_url from u_information_query where 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
+                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 pdfUrl.toString();
+                }
+            }
+            assert pdfUrl != null;
+            return pdfUrl.toString();
+        }
+        return "";
+    }
+
     @Override
     public List<SampleAncillaryDocumentsVO> selfAncillaryDocumentsList(String id) {
         //获取材料附件信息
@@ -164,13 +221,13 @@ public class TrialSelfInspectionRecordServiceImpl
         List<Attach> query = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(Attach.class));
         for (SampleAncillaryDocumentsVO sampleAncillaryDocumentsVO : result) {
             for (Attach attach : query) {
-                if (sampleAncillaryDocumentsVO.getOtherAccessories().equals(attach.getLink())) {
+                if (StringUtils.isNotEmpty(sampleAncillaryDocumentsVO.getOtherAccessories()) && sampleAncillaryDocumentsVO.getOtherAccessories().equals(attach.getLink())) {
                     sampleAncillaryDocumentsVO.setOtherAccessoriesName(attach.getOriginalName());
                 }
-                if (sampleAncillaryDocumentsVO.getProductionCertificate().equals(attach.getLink())) {
+                if (StringUtils.isNotEmpty(sampleAncillaryDocumentsVO.getProductionCertificate()) && sampleAncillaryDocumentsVO.getProductionCertificate().equals(attach.getLink())) {
                     sampleAncillaryDocumentsVO.setProductionCertificateName(attach.getOriginalName());
                 }
-                if (sampleAncillaryDocumentsVO.getQualityInspectionReport().equals(attach.getLink())) {
+                if (StringUtils.isNotEmpty(sampleAncillaryDocumentsVO.getQualityInspectionReport()) && sampleAncillaryDocumentsVO.getQualityInspectionReport().equals(attach.getLink())) {
                     sampleAncillaryDocumentsVO.setQualityInspectionReportName(attach.getOriginalName());
                 }
             }
@@ -205,18 +262,19 @@ public class TrialSelfInspectionRecordServiceImpl
         List<TrialSelfInspectionRecord> trialSelfInspectionRecords = baseMapper.selectBatchIds(ids);
         for (TrialSelfInspectionRecord trialSelfInspectionRecord : trialSelfInspectionRecords) {
             TrialSelfInspectionRecordDTO dto = BeanUtil.copyProperties(trialSelfInspectionRecord, TrialSelfInspectionRecordDTO.class);
-            assert dto != null;
-            dto.setId(SnowFlakeUtil.getId());
-            if (StringUtils.isNotEmpty(dto.getRecordNo())) {
-                dto.setTableType("1");
-            } else if (StringUtils.isNotEmpty(dto.getReportNo())) {
-                dto.setTableType("2");
-            } else if (StringUtils.isNotEmpty(dto.getReportNo()) && StringUtils.isNotEmpty(dto.getRecordNo())) {
-                dto.setTableType("1,2");
+            if (dto != null) {
+                dto.setId(SnowFlakeUtil.getId());
+                if (StringUtils.isNotEmpty(dto.getRecordNo())) {
+                    dto.setTableType("1");
+                } else if (StringUtils.isNotEmpty(dto.getReportNo())) {
+                    dto.setTableType("2");
+                } else if (StringUtils.isNotEmpty(dto.getReportNo()) && StringUtils.isNotEmpty(dto.getRecordNo())) {
+                    dto.setTableType("1,2");
+                }
+                //重构编号
+                this.buildNumber(dto);
+                this.save(dto);
             }
-            //重构编号
-            this.buildNumber(dto);
-            this.save(dto);
         }
         return true;
     }
@@ -226,12 +284,16 @@ public class TrialSelfInspectionRecordServiceImpl
         List<TrialSelfInspectionRecordVO2> recordVO2s;
         //编辑
         if (StringUtils.isNotEmpty(id)) {
-            //获取nodeId节点下的记录信息(排除当前id记录)
+            //获取nodeId节点下的合格的记录信息(排除当前id记录)
             List<TrialSelfInspectionRecord> result = baseMapper.selectList(Wrappers.<TrialSelfInspectionRecord>lambdaQuery()
+                    .eq(TrialSelfInspectionRecord::getDetectionResult, 1)
+                    .eq(TrialSelfInspectionRecord::getStatus, 1)
                     .eq(TrialSelfInspectionRecord::getNodeId, nodeId)
                     .eq(TrialSelfInspectionRecord::getContractId, contractId)
                     .ne(TrialSelfInspectionRecord::getId, id)
-                    .eq(TrialSelfInspectionRecord::getStatus, 1));
+                    .isNotNull(TrialSelfInspectionRecord::getReportNo)
+                    .orderByDesc(TrialSelfInspectionRecord::getCreateTime)
+            );
 
             recordVO2s = BeanUtil.copyProperties(result, TrialSelfInspectionRecordVO2.class);
 
@@ -253,9 +315,12 @@ public class TrialSelfInspectionRecordServiceImpl
         } else {
             //新增
             List<TrialSelfInspectionRecord> result = baseMapper.selectList(Wrappers.<TrialSelfInspectionRecord>lambdaQuery()
+                    .eq(TrialSelfInspectionRecord::getDetectionResult, 1)
+                    .eq(TrialSelfInspectionRecord::getStatus, 1)
                     .eq(TrialSelfInspectionRecord::getNodeId, nodeId)
                     .eq(TrialSelfInspectionRecord::getContractId, contractId)
-                    .eq(TrialSelfInspectionRecord::getStatus, 1));
+                    .isNotNull(TrialSelfInspectionRecord::getReportNo)
+                    .orderByDesc(TrialSelfInspectionRecord::getCreateTime));
 
             recordVO2s = BeanUtil.copyProperties(result, TrialSelfInspectionRecordVO2.class);
         }
@@ -281,110 +346,59 @@ public class TrialSelfInspectionRecordServiceImpl
     }
 
     @Override
-    public boolean rawMaterialSubmitRelation(RawMaterialSubmitRelationDTO dto) throws FileNotFoundException {
+    @Async
+    public boolean rawMaterialSubmitRelation(RawMaterialSubmitRelationDTO dto, TrialSelfInspectionRecord obj) throws
+            FileNotFoundException {
         if (ObjectUtil.isEmpty(dto.getId())) {
             throw new ServiceException("请先保存填报数据后,再关联原材检测报告信息");
         } else {
-            TrialSelfInspectionRecord objMain = this.getBaseMapper().selectById(dto.getId());
-            if (ObjectUtil.isNotEmpty(objMain) && (("已审批").equals(objMain.getTaskStatus()) || ("待审批").equals(objMain.getTaskStatus()))) {
+            if (ObjectUtil.isNotEmpty(obj) && (("已审批").equals(obj.getTaskStatus()) || ("待审批").equals(obj.getTaskStatus()))) {
                 throw new ServiceException("当前填报数据已上报,无法进行关联操作");
             }
-            if (StringUtils.isNotEmpty(dto.getIds())) { //新增关系,合并pdf
-                List<String> idsList = Func.toStrList(dto.getIds());
-                //获取ids、id下的pdfUrl
-                List<String> ids = new ArrayList<>();
-                ids.add(dto.getId());
-                ids.addAll(idsList);
-                List<TrialSelfInspectionRecord> recordList = baseMapper.selectList(Wrappers.<TrialSelfInspectionRecord>lambdaQuery().in(TrialSelfInspectionRecord::getId, ids).eq(TrialSelfInspectionRecord::getStatus, 1));
-                TrialSelfInspectionRecord oldObj = recordList.stream().filter(f -> f.getId().equals(Long.parseLong(dto.getId()))).findAny().orElse(null);
-                List<TrialSelfInspectionRecord> oldOther = recordList.stream().filter(f -> !f.getId().equals(Long.parseLong(dto.getId()))).collect(Collectors.toList());
-
-                //获取原始pdfUrl
-                String sql = "select * from u_trial_raw_material_self_record where self_record_id =" + dto.getId();
-                TrialRawMaterialSelfRecord recordOld = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(TrialRawMaterialSelfRecord.class)).stream().findAny().orElse(null);
-                if (recordOld != null) {
-                    assert oldObj != null;
-                    oldObj.setPdfUrl(recordOld.getOldPdfUrl());
-                }
 
-                //当前记录pdfUrl置顶
-                List<TrialSelfInspectionRecord> recordList2 = new ArrayList<>();
-                recordList2.add(oldObj);
-                recordList2.addAll(oldOther);
-                List<String> listPdfUrl = recordList2.stream().map(TrialSelfInspectionRecord::getPdfUrl).collect(Collectors.toList());
+            //新增或编辑
+            if (StringUtils.isNotEmpty(dto.getIds())) {
+                //当前关联的原材料记录id
+                List<String> ids = Func.toStrList(dto.getIds());
+
+                //获取原材料的pdf
+                List<TrialSelfInspectionRecord> recordList = baseMapper.selectList(Wrappers.<TrialSelfInspectionRecord>lambdaQuery()
+                        .select(TrialSelfInspectionRecord::getPdfUrl, TrialSelfInspectionRecord::getId)
+                        .in(TrialSelfInspectionRecord::getId, ids).eq(TrialSelfInspectionRecord::getStatus, 1));
+                List<TrialSelfInspectionRecord> recordObjList = recordList.stream().filter(f -> !f.getId().equals(Long.parseLong(dto.getId()))).collect(Collectors.toList());
+                List<String> pdfUrlAll = new ArrayList<>();
+                if (recordObjList.size() > 0) {
+                    pdfUrlAll.addAll(recordObjList.stream().filter(f -> StringUtils.isNotEmpty(f.getPdfUrl())).map(TrialSelfInspectionRecord::getPdfUrl).collect(Collectors.toList()));
+                }
 
-                if (listPdfUrl.size() > 0) {
-                    //合并PDF
+                if (pdfUrlAll.size() > 0) {
                     String filePath = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
                     String listPdf = filePath + "/pdf/" + dto.getNodeId() + ".pdf";
                     File tabPDF = ResourceUtil.getFile(listPdf);
                     if (tabPDF.exists()) {
                         tabPDF.delete();
                     }
-                    FileUtils.mergePdfPublicMethods(listPdfUrl, listPdf);
+                    FileUtils.mergePdfPublicMethods(pdfUrlAll, listPdf);
                     BladeFile bladeFile = this.newIOSSClient.uploadFile(dto.getNodeId() + ".pdf", listPdf);
 
-                    //获取试验记录id的试验项目名称
-                    List<String> collect = recordList.stream().map(TrialSelfInspectionRecord::getTrialProjectName).collect(Collectors.toList());
-                    String name = collect.stream().findAny().orElse(null);
-                    String trialProjectName;
-                    if (collect.size() > 1) {
-                        trialProjectName = name + "等" + collect.size() + "个文件";
-                    } else {
-                        trialProjectName = name;
-                    }
-
-                    //删除当前记录关系信息
+                    //删除记录关系
                     String sql1 = "delete from u_trial_raw_material_self_record where self_record_id ='" + dto.getId() + "'";
                     jdbcTemplate.execute(sql1);
-                    //新增当前记录关系信息
-                    for (String s : idsList) {
-                        assert oldObj != null;
-                        String sql2 = "insert into u_trial_raw_material_self_record(id,self_record_id,raw_material_record_id,old_pdf_url) values(" + SnowFlakeUtil.getId() + "," + dto.getId() + "," + s + ",'" + oldObj.getPdfUrl() + "')";
-                        jdbcTemplate.execute(sql2);
-                    }
-
-                    if (ObjectUtil.isNotEmpty(bladeFile)) {
-                        //修改pdfURL
-                        String querySql = "select * from u_information_query where classify='" + dto.getType() + "' and wbs_id='" + dto.getId() + "' and contract_id ='" + dto.getContractId() + "'";
-                        List<Map<String, Object>> resultSQL = jdbcTemplate.queryForList(querySql);
-                        if (resultSQL.size() > 0) {
-                            String sql3 = "update u_information_query set pdf_url ='" + bladeFile.getLink() + "', name = '" + trialProjectName + "' where classify= '" + dto.getType() + "' and wbs_id='" + dto.getId() + "' and contract_id ='" + dto.getContractId() + "'";
-                            jdbcTemplate.execute(sql3);
-                        } else {
-                            informationQueryClient.saveData(dto.getId(), dto.getProjectId(), dto.getContractId(), String.valueOf(dto.getType()), bladeFile.getLink(), trialProjectName);
+                    //新增记录关系
+                    for (String recordId : ids) {
+                        if (!recordId.equals(dto.getId())) {
+                            String sql2 = "insert into u_trial_raw_material_self_record(id,self_record_id,raw_material_record_id,old_pdf_url) values(" + SnowFlakeUtil.getId() + "," + dto.getId() + "," + recordId + ",'" + bladeFile.getLink() + "')";
+                            jdbcTemplate.execute(sql2);
                         }
-
-                        //修改当前记录pdfUrl
-                        this.update(Wrappers.<TrialSelfInspectionRecord>lambdaUpdate().set(TrialSelfInspectionRecord::getPdfUrl, bladeFile.getLink()).eq(TrialSelfInspectionRecord::getId, dto.getId()));
-
-                        return true;
-                    } else {
-                        //删除关系
-                        jdbcTemplate.execute(sql1);
-                        return false;
                     }
+                    return true;
                 }
-            } else {
-                //删除关系,恢复当前记录的原始pdfUrl
-                TrialSelfInspectionRecord obj = baseMapper.selectById(dto.getId());
-                String sql = "select * from u_trial_raw_material_self_record where self_record_id =" + dto.getId();
-                TrialRawMaterialSelfRecord record = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(TrialRawMaterialSelfRecord.class)).stream().findAny().orElse(null);
-                if (record != null) {
-                    //修改pdfURL
-                    String querySql = "select * from u_information_query where classify='" + dto.getType() + "' and wbs_id='" + dto.getId() + "' and contract_id ='" + dto.getContractId() + "'";
-                    List<Map<String, Object>> resultSQL = jdbcTemplate.queryForList(querySql);
-                    if (resultSQL.size() > 0) {
-                        String sql3 = "update u_information_query set pdf_url ='" + record.getOldPdfUrl() + "', name = '" + obj.getTrialProjectName() + "' where classify= '" + dto.getType() + "' and wbs_id='" + dto.getId() + "' and contract_id ='" + dto.getContractId() + "'";
-                        jdbcTemplate.execute(sql3);
-                    } else {
-                        informationQueryClient.saveData(dto.getId(), dto.getProjectId(), dto.getContractId(), String.valueOf(dto.getType()), record.getOldPdfUrl(), obj.getTrialProjectName());
-                    }
 
-                    //修改当前记录pdfUrl
-                    this.update(Wrappers.<TrialSelfInspectionRecord>lambdaUpdate().set(TrialSelfInspectionRecord::getPdfUrl, record.getOldPdfUrl()).eq(TrialSelfInspectionRecord::getId, dto.getId()));
-
-                    //删除当前记录关系信息
+            } else {
+                //删除全部
+                String sql = "select id from u_trial_raw_material_self_record where self_record_id =" + dto.getId();
+                List<TrialRawMaterialSelfRecord> recordList = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(TrialRawMaterialSelfRecord.class));
+                if (recordList.size() > 0) {
                     String sql1 = "delete from u_trial_raw_material_self_record where self_record_id ='" + dto.getId() + "'";
                     jdbcTemplate.execute(sql1);
                 }
@@ -454,19 +468,69 @@ public class TrialSelfInspectionRecordServiceImpl
     }
 
     @Override
-    public void updateTrialSelfInspectionRecordStatus(List<TaskApprovalVO> obj){
+    @Async
+    public void updateTrialSelfInspectionRecordStatus(String pdfUrlEVisa, List<TaskApprovalVO> obj) throws FileNotFoundException {
         for (TaskApprovalVO taskApprovalVO : obj) {
             if (ObjectUtil.isNotEmpty(taskApprovalVO.getParallelProcessInstanceId())) {
                 String sql = "select process_instance_id from u_task_parallel where parallel_process_instance_id = '" + taskApprovalVO.getParallelProcessInstanceId() + "'";
                 TaskParallel taskParallel = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(TaskParallel.class)).stream().findAny().orElse(null);
-                assert taskParallel != null;
-                if (ObjectUtil.isNotEmpty(taskParallel.getProcessInstanceId())) {
+                if (taskParallel != null && ObjectUtil.isNotEmpty(taskParallel.getProcessInstanceId())) {
                     String trialSelfInspectionRecordId = baseMapper.selectTaskByTaskId(taskParallel.getProcessInstanceId());
                     if (StringUtils.isNotEmpty(trialSelfInspectionRecordId)) {
                         this.update(Wrappers.<TrialSelfInspectionRecord>lambdaUpdate()
                                 .set(TrialSelfInspectionRecord::getTaskStatus, "OK".equals(taskApprovalVO.getFlag()) ? "已审批" : "已废除")
+                                .set(TrialSelfInspectionRecord::getPdfUrl, pdfUrlEVisa) //pdfUrlEVisa=电签后的pdf
                                 .eq(TrialSelfInspectionRecord::getId, trialSelfInspectionRecordId)
                         );
+
+                        TrialSelfInspectionRecord record = baseMapper.selectById(trialSelfInspectionRecordId);
+                        //此时的record.getPdfUrl()为电签后的pdf信息
+                        if (("已审批").equals(record.getTaskStatus()) && (new Integer(1)).equals(record.getDetectionResult()) && (new Integer(1)).equals(record.getDetectionCategory())) {
+                            /**
+                             * 在资料填报工序-预览全部pdf时再拼接合并显示,当前只做储存(如果当前资料填报工序节点有其他多个试验记录pdf关联信息,那么合并存储,否则直接存储)
+                             */
+                            if (StringUtils.isNotEmpty(record.getProjectPosition())) {
+                                //有pdf的节点
+                                String sqlNodeAll = "select wbs_id from u_information_query where wbs_id in(" + record.getProjectPosition() + ") and contract_id = " + record.getContractId();
+                                List<Long> collect = jdbcTemplate.query(sqlNodeAll, new BeanPropertyRowMapper<>(InformationQuery.class)).stream().map(InformationQuery::getWbsId).collect(Collectors.toList());
+                                if (collect.size() > 0) {
+                                    //删除当前记录关联记录
+                                    baseMapper.delSelfQuality(record.getId());
+                                    for (Long pKeyId : collect) {
+                                        //新增当前记录关联信息
+                                        baseMapper.saveSelfQuality(SnowFlakeUtil.getId(), record.getId(), pKeyId);
+
+                                        //获取当前工程部位节点最新的关联试验记录ids
+                                        List<String> trialRecordIds = baseMapper.selectTrialIdByNodeId(pKeyId);
+
+                                        //如果当前工程部位节点的关联试验记录id只有一条,且等于当前关联试验记录id,那么不合并,直接存储该条试验记录的pdf
+                                        if (trialRecordIds.size() == 1 && trialRecordIds.get(0).equals(record.getId().toString())) {
+                                            //修改当前试验pdf到质检树节点的pdf_trial_url_position上存储
+                                            baseMapper.updateInformationQuery(pKeyId, record.getContractId(), record.getPdfUrl());
+                                            continue;
+                                        }
+
+                                        //如果当前工程部位节点的关联试验记录id有多条,那么合并
+                                        List<TrialSelfInspectionRecord> pdfUrlList = baseMapper.selectList(Wrappers.<TrialSelfInspectionRecord>lambdaQuery().select(TrialSelfInspectionRecord::getPdfUrl).in(TrialSelfInspectionRecord::getId, trialRecordIds));
+                                        List<String> pdfS = pdfUrlList.stream().filter(f -> StringUtils.isNotEmpty(f.getPdfUrl())).map(TrialSelfInspectionRecord::getPdfUrl).collect(Collectors.toList());
+
+                                        String filePath = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
+                                        String listPdf = filePath + "/pdf/" + pKeyId + ".pdf";
+                                        File tabPDF = ResourceUtil.getFile(listPdf);
+                                        if (tabPDF.exists()) {
+                                            tabPDF.delete();
+                                        }
+
+                                        FileUtils.mergePdfPublicMethods(pdfS, listPdf);
+                                        BladeFile bladeFile = this.newIOSSClient.uploadFile(pKeyId + ".pdf", listPdf);
+                                        if (bladeFile != null) {
+                                            //修改合并的试验pdf到质检树节点的pdf_trial_url_position上存储
+                                            baseMapper.updateInformationQuery(pKeyId, record.getContractId(), bladeFile.getLink());
+                                        }
+                                    }
+                                }
+                            }
+                        }
                     }
                 }
             }
@@ -474,7 +538,8 @@ public class TrialSelfInspectionRecordServiceImpl
     }
 
     @Override
-    public String addBussFile(MultipartFile file, Long pkeyId, String nodeId, String contractId, String projectId, String classify, String id, String tableType) throws Exception {
+    public String addBussFile(MultipartFile file, Long pkeyId, String nodeId, String contractId, String
+            projectId, String classify, String id, String tableType) throws Exception {
         R<BladeFile> bladeFile = iossClient.addFileInfo(file);
         BladeFile bladeFile1 = bladeFile.getData();
         TableFile tableFile = new TableFile();
@@ -588,16 +653,15 @@ public class TrialSelfInspectionRecordServiceImpl
         List<String> sampleIds = baseMapper.selectSelfSampleRecord(id);
         if (sampleIds.size() > 0) {
             List<TrialSampleInfo> trialSampleInfos = trialSampleInfoMapper.selectBatchIds(sampleIds);
-            List<User> users = iUserClient.selectUserAll();
+            Map<Long, User> map = iUserClient.selectUserAll().stream().collect(Collectors.toMap(User::getId, Function.identity()));
             if (trialSampleInfos.size() > 0) {
                 for (TrialSampleInfo trialSampleInfo : trialSampleInfos) {
-                    for (User user : users) {
-                        if (trialSampleInfo.getUserId().equals(user.getId())) {
-                            TrialSampleInfoVO trialSampleInfoVO = BeanUtil.copyProperties(trialSampleInfo, TrialSampleInfoVO.class);
-                            if (trialSampleInfoVO != null) {
-                                trialSampleInfoVO.setUserName(ObjectUtil.isNotEmpty(user.getName()) ? user.getName() : user.getRealName());
-                                result.add(trialSampleInfoVO);
-                            }
+                    User user = map.get(trialSampleInfo.getUserId());
+                    if (user != null) {
+                        TrialSampleInfoVO trialSampleInfoVO = BeanUtil.copyProperties(trialSampleInfo, TrialSampleInfoVO.class);
+                        if (trialSampleInfoVO != null) {
+                            trialSampleInfoVO.setUserName(ObjectUtil.isNotEmpty(user.getName()) ? user.getName() : user.getRealName());
+                            result.add(trialSampleInfoVO);
                         }
                     }
                 }
@@ -607,24 +671,24 @@ public class TrialSelfInspectionRecordServiceImpl
     }
 
     @Override
-    public String selfSubmit(TrialSelfInspectionRecordDTO dto) {
+    public String selfSubmit(TrialSelfInspectionRecordDTO dto) throws FileNotFoundException {
         if (ObjectUtil.isEmpty(dto.getId()) && StringUtils.isNotEmpty(dto.getTableType())) {
             //构建记录表编号、报告单编号
             this.buildNumber(dto);
 
             //任务流程状态初始化未上报
             dto.setTaskStatus("未上报");
+        }
 
-            //初始化tabIds
-            JSONArray dataArray = dto.getDataInfo().getJSONArray("orderList");
-            List<String> tableIds = new ArrayList<>();
-            for (int i = 0; i < dataArray.size(); i++) {
-                String pkeyId = dataArray.getJSONObject(i).getString("pkeyId");
-                tableIds.add(pkeyId);
-            }
-            String join = org.apache.commons.lang.StringUtils.join(tableIds, ",");
-            dto.setTableIds(join);
+        //初始化tabIds
+        JSONArray dataArray = dto.getDataInfo().getJSONArray("orderList");
+        List<String> tableIds = new ArrayList<>();
+        for (int i = 0; i < dataArray.size(); i++) {
+            String pkeyId = dataArray.getJSONObject(i).getString("pkeyId");
+            tableIds.add(pkeyId);
         }
+        String join = org.apache.commons.lang.StringUtils.join(tableIds, ",");
+        dto.setTableIds(join);
 
         this.saveOrUpdate(dto);
 
@@ -632,7 +696,7 @@ public class TrialSelfInspectionRecordServiceImpl
             //获取当前最新的试验记录信息
             TrialSelfInspectionRecord obj = baseMapper.selectById(dto.getId());
 
-            //如果新增时不是两种类型表都填报过,那么有一项编号为Null,所以编辑时生成记录表编号或报告单编号
+            //编辑时生成记录表编号或报告单编号,如果新增时不是两种类型表都填报过,那么有一项编号为Null
             if (StringUtils.isEmpty(obj.getRecordNo()) && dto.getTableType().contains("1")) {
                 this.buildNumber(dto);
                 this.saveOrUpdate(dto);
@@ -641,37 +705,53 @@ public class TrialSelfInspectionRecordServiceImpl
                 this.saveOrUpdate(dto);
             }
 
+            //------保存实体表数据、试验记录信息、生成pdf------
             try {
-                //保存实体表数据、试验记录信息、生成pdf
                 String pdfURL = excelTabClient.saveTabData(dto.getIsBatchSave(), dto.getDataInfo(), dto.getType(), dto.getTableType(), dto.getId(), obj.getTableIds());
                 if (StringUtils.isNotEmpty(pdfURL)) {
                     //修改合并pdf
-                    this.update(Wrappers.<TrialSelfInspectionRecord>lambdaUpdate()
-                            .set(TrialSelfInspectionRecord::getPdfUrl, pdfURL)
-                            .eq(TrialSelfInspectionRecord::getId, dto.getId()));
+                    this.update(Wrappers.<TrialSelfInspectionRecord>lambdaUpdate().set(TrialSelfInspectionRecord::getPdfUrl, pdfURL).eq(TrialSelfInspectionRecord::getId, dto.getId()));
                 }
             } catch (Exception e) {
-                throw new ServiceException("保存实体表数据生成pdf时发生异常 " + e.getMessage());
+                throw new ServiceException("保存实体表数据生成pdf时发生异常" + e.getMessage());
             }
 
-            //新增设备使用记录信息
+            //------关联原材料检测报告------
+            RawMaterialSubmitRelationDTO relationDTO = new RawMaterialSubmitRelationDTO();
+            relationDTO.setId(obj.getId().toString());
+            relationDTO.setIds(dto.getRawMaterialIds());
+            relationDTO.setNodeId(dto.getNodeId().toString());
+            relationDTO.setContractId(dto.getContractId().toString());
+            relationDTO.setProjectId(dto.getProjectId());
+            relationDTO.setType(dto.getType());
+            this.rawMaterialSubmitRelation(relationDTO, obj);
+
+            //------关联取样信息------
+            RecordSampleSubmitDTO recordSampleSubmitDTO = new RecordSampleSubmitDTO();
+            recordSampleSubmitDTO.setId(obj.getId());
+            recordSampleSubmitDTO.setSampleIds(dto.getSampleIds());
+            this.recordSampleSubmit(recordSampleSubmitDTO);
+
+            //------新增设备使用记录信息------
             this.trialDeviceUseService.addDeviceUseInfo(dto);
         }
 
+        //返回当前记录id
         return dto.getId().toString();
     }
 
     @Override
+    @Async
     public boolean recordSampleSubmit(RecordSampleSubmitDTO dto) {
         if (ObjectUtil.isEmpty(dto.getId())) {
             throw new ServiceException("请先保存填报数据后,再关联取样信息");
         }
-        //删除关联信息
+        //删除关联
         baseMapper.delSelfSample(dto.getId());
         if (StringUtils.isNotEmpty(dto.getSampleIds())) {
             List<String> ids = Func.toStrList(dto.getSampleIds());
             for (String id : ids) {
-                //新增关联信息
+                //新增关联
                 baseMapper.saveSelfSample(SnowFlakeUtil.getId(), dto.getId(), id);
             }
 
@@ -721,82 +801,17 @@ public class TrialSelfInspectionRecordServiceImpl
         return true;
     }
 
-    @Override
-    public boolean recordProjectPosition(SelfProjectPositionSubmitDTO dto) throws FileNotFoundException {
-        if (ObjectUtil.isEmpty(dto.getId())) {
-            throw new ServiceException("请先保存填报数据后,再关联工程部位及用途信息");
-        }
-        //已审批记录关联
-        if (StringUtils.isNotEmpty(dto.getProjectPosition())) {
-            TrialSelfInspectionRecord obj = baseMapper.selectById(dto.getId());
-            if (("已审批").equals(obj.getTaskStatus())) {
-                //删除关联信息
-                baseMapper.delSelfQuality(dto.getId());
-
-                List<String> ids = Func.toStrList(dto.getProjectPosition());
-                //新增关联信息
-                for (String id : ids) {
-                    baseMapper.saveSelfQuality(SnowFlakeUtil.getId(), dto.getId(), id);
-                }
-
-                //把当前试验的PDF合并关联到质检树节点下
-                List<String> contractNodePKeyIds = baseMapper.selectQualityNodeId(String.valueOf(dto.getId())); //获取合同段质检树的节点PkeyId
-                for (String pKeyId : contractNodePKeyIds) {
-                    WbsTreeContract wbsTreeContract = wbsTreeContractClient.getContractNodeByPrimaryKeyId(pKeyId);
-                    if (wbsTreeContract != null) {
-                        List<String> pdfUrlList = new ArrayList<>();
-                        String classify;
-                        if (wbsTreeContract.getTableOwner().contains("1") || wbsTreeContract.getTableOwner().contains("2") || wbsTreeContract.getTableOwner().contains("3")) {
-                            classify = "1";
-                        } else {
-                            classify = "2";
-                        }
-                        String pdfUrlNodeAll = baseMapper.selectInformationQuery(pKeyId, wbsTreeContract.getContractId(), classify);
-
-                        if (StringUtils.isEmpty(pdfUrlNodeAll) || StringUtils.isEmpty(obj.getPdfUrl())) {
-                            continue;
-                        }
-
-                        //质检节点合并pdfUrl
-                        pdfUrlList.add(pdfUrlNodeAll);
-                        //试验pdfUrl
-                        pdfUrlList.add(obj.getPdfUrl());
-
-                        //合并PDF
-                        String filePath = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
-                        String listPdf = filePath + "/pdf/" + pKeyId + ".pdf";
-                        File tabPDF = ResourceUtil.getFile(listPdf);
-                        if (tabPDF.exists()) {
-                            tabPDF.delete();
-                        }
-                        FileUtils.mergePdfPublicMethods(pdfUrlList, listPdf);
-                        BladeFile bladeFile = this.newIOSSClient.uploadFile(pKeyId + ".pdf", listPdf);
-                        if (bladeFile != null) {
-                            //修改质检树合并后的pdfURL
-                            baseMapper.updateInformationQuery(pKeyId, wbsTreeContract.getContractId(), classify, bladeFile.getLink());
-                        }
-                    }
-                }
-            } else {
-                throw new ServiceException("当前试验记录任务未上报审批,关联工程部位及用途信息失败");
-            }
-        } else {
-            //删除关联信息
-            baseMapper.delSelfQuality(dto.getId());
-        }
-        return true;
-    }
-
     private void buildNumber(TrialSelfInspectionRecordDTO dto) {
         StringSPUtils spUtils = new StringSPUtils();
-        List<TrialSelfInspectionRecord> trialSelfInspectionRecords = baseMapper.selectAll(dto.getNodeId(), dto.getContractId());
+        List<TrialSelfInspectionRecord> result = baseMapper.selectAll(dto.getNodeId(), dto.getContractId());
+        List<TrialSelfInspectionRecord> trialSelfInspectionRecords = result.stream().filter(Objects::nonNull).collect(Collectors.toList());
 
         //两种类型同时生成
         if (dto.getTableType().contains("1,2") || dto.getTableType().contains("2,1")) {
             String maxRecordNo = "";
             if (StringUtils.isEmpty(dto.getRecordNo())) {
                 //获取记录表最大编号
-                List<String> recordNos = trialSelfInspectionRecords.stream().map(TrialSelfInspectionRecord::getRecordNo).collect(Collectors.toList());
+                List<String> recordNos = trialSelfInspectionRecords.stream().filter(f -> ObjectUtils.isNotEmpty(f.getRecordNo())).map(TrialSelfInspectionRecord::getRecordNo).collect(Collectors.toList());
                 if (recordNos.size() == 0 || ObjectUtil.isEmpty(recordNos)) {
                     maxRecordNo = "0001";
                 } else {
@@ -817,7 +832,7 @@ public class TrialSelfInspectionRecordServiceImpl
             String maxReportNo = "";
             if (StringUtils.isEmpty(dto.getReportNo())) {
                 //获取报告单最大编号
-                List<String> reportNos = trialSelfInspectionRecords.stream().map(TrialSelfInspectionRecord::getReportNo).collect(Collectors.toList());
+                List<String> reportNos = trialSelfInspectionRecords.stream().filter(f -> ObjectUtils.isNotEmpty(f.getReportNo())).map(TrialSelfInspectionRecord::getReportNo).collect(Collectors.toList());
                 if (reportNos.size() == 0 || ObjectUtil.isEmpty(reportNos)) {
                     maxReportNo = "0001";
                 } else {
@@ -868,7 +883,7 @@ public class TrialSelfInspectionRecordServiceImpl
         if (("1").equals(dto.getTableType())) {
             if (StringUtils.isEmpty(dto.getRecordNo())) {
                 //获取记录表最大编号
-                List<String> recordNos = trialSelfInspectionRecords.stream().map(TrialSelfInspectionRecord::getRecordNo).collect(Collectors.toList());
+                List<String> recordNos = trialSelfInspectionRecords.stream().filter(f -> ObjectUtils.isNotEmpty(f.getRecordNo())).map(TrialSelfInspectionRecord::getRecordNo).collect(Collectors.toList());
                 String maxRecordNo;
                 if (recordNos.size() == 0 || ObjectUtil.isEmpty(recordNos)) {
                     maxRecordNo = "0001";
@@ -908,7 +923,7 @@ public class TrialSelfInspectionRecordServiceImpl
         if (("2").equals(dto.getTableType())) {
             if (StringUtils.isEmpty(dto.getReportNo())) {
                 //获取报告单最大编号
-                List<String> reportNos = trialSelfInspectionRecords.stream().map(TrialSelfInspectionRecord::getReportNo).collect(Collectors.toList());
+                List<String> reportNos = trialSelfInspectionRecords.stream().filter(f -> ObjectUtils.isNotEmpty(f.getReportNo())).map(TrialSelfInspectionRecord::getReportNo).collect(Collectors.toList());
                 String maxReportNo;
                 if (reportNos.size() == 0 || ObjectUtil.isEmpty(reportNos)) {
                     maxReportNo = "0001";
@@ -945,23 +960,20 @@ public class TrialSelfInspectionRecordServiceImpl
         }
     }
 
-    public IPage<TrialSelfInspectionRecordVO> trialDataPage(IPage<TrialSelfInspectionRecord> page, TrialSelfInspectionRecordPageDTO dto) {
+    public IPage<TrialSelfInspectionRecordVO> trialDataPage
+            (IPage<TrialSelfInspectionRecord> page, TrialSelfInspectionRecordPageDTO dto) {
         QueryWrapper<TrialSelfInspectionRecord> queryWrapper = Condition.getQueryWrapper(dto);
-
         if (org.apache.commons.lang.StringUtils.isNotEmpty(dto.getStartTime()) && org.apache.commons.lang.StringUtils.isNotEmpty(dto.getEndTime())) {
             String endTime = dto.getEndTime();
             endTime = DateUtil.format(DateUtils.addDays(DateUtil.parse(endTime, "yyyy-MM-dd"), 1), "yyyy-MM-dd");
             queryWrapper.lambda().between(TrialSelfInspectionRecord::getReportDate, dto.getStartTime(), endTime);
         }
-
         queryWrapper.lambda().eq(TrialSelfInspectionRecord::getTaskStatus, "已审批");
         queryWrapper.lambda().eq(TrialSelfInspectionRecord::getDetectionResult, 1); //合格
         queryWrapper.lambda().eq(TrialSelfInspectionRecord::getDetectionCategory, 1); //自检
-
-        IPage<TrialSelfInspectionRecord> pages = this.page(page, queryWrapper.lambda().orderBy(true, true, TrialSelfInspectionRecord::getCreateTime));
+        IPage<TrialSelfInspectionRecord> pages = this.page(page, queryWrapper.lambda().orderByDesc(TrialSelfInspectionRecord::getCreateTime));
         IPage<TrialSelfInspectionRecordVO> trialSelfInspectionRecordVOIPage = TrialSelfInspectionRecordWarpper.build().pageVO(pages);
         List<TrialSelfInspectionRecordVO> records = trialSelfInspectionRecordVOIPage.getRecords();
-
         //查询是否关联过
         if (ObjectUtil.isNotEmpty(dto.getQualityTestPKeyId())) {
             List<String> selectedIds = baseMapper.selectSelectedStatusList(Long.parseLong(dto.getQualityTestPKeyId()), "1");
@@ -972,7 +984,6 @@ public class TrialSelfInspectionRecordServiceImpl
                         record.setIsSelectedStatus(1);
                     }
                 }
-
                 record.setDetectionResultName(record.getDetectionResult().equals(1) ? "合格" : "不合格");
                 //工程部位及用途名称
                 if (ObjectUtil.isNotEmpty(record.getProjectPosition())) {
@@ -987,7 +998,6 @@ public class TrialSelfInspectionRecordServiceImpl
                     }
                 }
             }
-
         } else {
             for (TrialSelfInspectionRecordVO record : records) {
                 record.setDetectionResultName(record.getDetectionResult().equals(1) ? "合格" : "不合格");
@@ -1005,49 +1015,53 @@ public class TrialSelfInspectionRecordServiceImpl
                 }
             }
         }
-
         return trialSelfInspectionRecordVOIPage.setRecords(records);
     }
 
     @Override
     public boolean fileSubmit(TrialFileSubmitDTO dto) throws FileNotFoundException {
+        /**
+         * 在资料填报工序-预览全部pdf时再拼接合并显示,当前只做储存
+         */
         if (ObjectUtil.isEmpty(dto.getType())) {
             throw new ServiceException("请选择一个类型");
-        }
-        if (ObjectUtil.isEmpty(dto.getNodeId())) {
-            throw new ServiceException("未获取到当前节点的pKeyId");
+        } else if (ObjectUtil.isEmpty(dto.getNodeId())) {
+            throw new ServiceException("未获取到当前节点信息");
         }
 
         //获取当前节点的合并的pdfURL
-        InformationQuery informationQuery = informationQueryService.getBaseMapper().selectOne(Wrappers.<InformationQuery>lambdaQuery()
+        InformationQuery informationQuery = informationQueryService.getBaseMapper().selectList(Wrappers.<InformationQuery>lambdaQuery()
                 .eq(InformationQuery::getWbsId, dto.getNodeId())
                 .eq(InformationQuery::getProjectId, dto.getProjectId())
                 .eq(InformationQuery::getContractId, dto.getContractId())
-                .eq(InformationQuery::getType, 1) //质检
-        );
+                .eq(InformationQuery::getType, 1)).stream().findAny().orElse(null);
 
         if (StringUtils.isNotEmpty(dto.getIds())) {
-            if (ObjectUtil.isNotEmpty(informationQuery) && StringUtils.isNotEmpty(informationQuery.getPdfUrl())) {
-
+            if (informationQuery != null) {
                 List<String> pdfList = new ArrayList<>();
+                //------自检------
+                if (dto.getType().equals(1)) {
+                    if (informationQuery.getPdfTrialUrl() != null) {
+                        //如果当前存在第三方、外委的pdf,那么拼接
+                        pdfList.add(informationQuery.getPdfTrialUrl());
+                    }
 
-                if (StringUtils.isEmpty(informationQuery.getPdfTrialUrl())) {
-                    //如果PdfTrialUrl == null 说明是第一次关联
-                    pdfList.add(informationQuery.getPdfUrl());
-                } else {
-                    //如果PdfTrialUrl != null 说明是第二次以上操作关联,那么就在之前的上面做增量,主要解决不同类型提交时的问题
-                    pdfList.add(informationQuery.getPdfTrialUrl());
-                }
-
-                if (dto.getType().equals(1)) { //自检
-                    //获取自检的对应的数据pdf
-                    List<TrialSelfInspectionRecord> trialSelfInspectionRecords = baseMapper.selectList(Wrappers.<TrialSelfInspectionRecord>lambdaQuery().in(TrialSelfInspectionRecord::getId, dto.getIds()));
+                    //自检pdf
+                    List<TrialSelfInspectionRecord> trialSelfInspectionRecords = baseMapper.selectList(Wrappers.<TrialSelfInspectionRecord>lambdaQuery()
+                            .select(TrialSelfInspectionRecord::getPdfUrl)
+                            .in(TrialSelfInspectionRecord::getId, Func.toLongList(dto.getIds())));
                     List<String> pdfURLs = trialSelfInspectionRecords.stream().map(TrialSelfInspectionRecord::getPdfUrl).collect(Collectors.toList());
                     pdfList.addAll(pdfURLs);
 
-                } else if (dto.getType().equals(2) || dto.getType().equals(3)) { //第三方、外委
-                    //获取第三方、外委的对应的数据pdf
-                    List<TrialDetectionData> trialDetectionData = trialDetectionDataService.getBaseMapper().selectList(Wrappers.<TrialDetectionData>lambdaQuery().in(TrialDetectionData::getId, dto.getIds()));
+                    //------第三方、外委------
+                } else if (dto.getType().equals(2) || dto.getType().equals(3)) {
+                    if (informationQuery.getPdfTrialUrl() != null) {
+                        //如果当前存在试验自检的pdf,那么拼接
+                        pdfList.add(informationQuery.getPdfTrialUrl());
+                    }
+
+                    //第三方、外委pdf
+                    List<TrialDetectionData> trialDetectionData = trialDetectionDataService.getBaseMapper().selectList(Wrappers.<TrialDetectionData>lambdaQuery().in(TrialDetectionData::getId, Func.toLongList(dto.getIds())));
                     List<String> pdfURLs = new ArrayList<>();
                     for (TrialDetectionData trialDetectionDatum : trialDetectionData) {
                         if (StringUtils.isNotEmpty(trialDetectionDatum.getRecordTableUrl())) {
@@ -1058,11 +1072,10 @@ public class TrialSelfInspectionRecordServiceImpl
                         }
                     }
                     pdfList.addAll(pdfURLs);
-
                 }
 
                 if (pdfList.size() > 0) {
-                    //合并pdf把试验自检记录、第三方、外委的pdf追加到当前质检合同段树节点下的pdf后显示
+                    //合并试验自检、第三方、外委的pdf
                     List<String> collect = pdfList.stream().filter(Objects::nonNull).collect(Collectors.toList());
                     String filePath = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
                     String listPdf = filePath + "/pdf/" + informationQuery.getId() + ".pdf";
@@ -1076,9 +1089,7 @@ public class TrialSelfInspectionRecordServiceImpl
                         //修改当前节点的pdfTrialURL地址
                         if (informationQueryService.update(Wrappers.<InformationQuery>lambdaUpdate().set(InformationQuery::getPdfTrialUrl, bladeFile.getLink()).eq(InformationQuery::getId, informationQuery.getId()))) {
                             for (String recordId : Func.toStrList(dto.getIds())) {
-                                //修改选中状态记录信息(选中为勾选绿色)
                                 baseMapper.deleteSeletedStatusByNodeId(dto.getNodeId(), dto.getType(), recordId); //先删除对应记录
-
                                 baseMapper.insertSeletedStatus(SnowFlakeUtil.getId(), dto.getNodeId(), dto.getType(), recordId); //新增该类型选中的记录信息
                             }
                             return true;
@@ -1086,7 +1097,7 @@ public class TrialSelfInspectionRecordServiceImpl
                     }
                 }
             } else {
-                throw new ServiceException("当前节点还未上报,获取pdf信息失败,请先上报后再进行关联");
+                throw new ServiceException("当前质检节点还未保存生成pdf,请先保存后再进行试验文件关联");
             }
 
         } else {
@@ -1117,11 +1128,10 @@ public class TrialSelfInspectionRecordServiceImpl
                     List<TrialSelfInspectionRecord> trialSelfInspectionRecords = baseMapper.selectList(Wrappers.<TrialSelfInspectionRecord>lambdaQuery().in(TrialSelfInspectionRecord::getId, ids));
                     List<String> pdfURLs = trialSelfInspectionRecords.stream().map(TrialSelfInspectionRecord::getPdfUrl).collect(Collectors.toList());
                     pdfList.addAll(pdfURLs);
-
                 }
 
-                if (pdfList.size() > 0) {
-                    //合并pdf把试验自检记录、第三方、外委的pdf追加到当前质检合同段树节点下的pdf后显示
+                if (pdfList.size() > 0 && informationQuery != null) {
+                    //重新合并
                     List<String> collect = pdfList.stream().filter(Objects::nonNull).collect(Collectors.toList());
                     String filePath = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
                     String listPdf = filePath + "/pdf/" + informationQuery.getId() + ".pdf";
@@ -1132,12 +1142,10 @@ public class TrialSelfInspectionRecordServiceImpl
                     FileUtils.mergePdfPublicMethods(collect, listPdf);
                     BladeFile bladeFile = this.newIOSSClient.uploadFile(informationQuery.getId() + ".pdf", listPdf);
                     if (bladeFile != null) {
-                        //修改当前节点的pdfTrialURL地址
+                        //修改当前节点最新的pdfTrialURL地址
                         if (informationQueryService.update(Wrappers.<InformationQuery>lambdaUpdate().set(InformationQuery::getPdfTrialUrl, bladeFile.getLink()).eq(InformationQuery::getId, informationQuery.getId()))) {
                             for (String recordId : recordIds) {
-                                //修改选中状态记录信息(选中为勾选绿色)
                                 baseMapper.deleteSeletedStatusByNodeId(dto.getNodeId(), dto.getType(), recordId); //先删除对应记录
-
                                 baseMapper.insertSeletedStatus(SnowFlakeUtil.getId(), dto.getNodeId(), dto.getType(), recordId); //新增该类型选中的记录信息
                             }
                             return true;
@@ -1147,15 +1155,16 @@ public class TrialSelfInspectionRecordServiceImpl
 
             } else {
                 //修改pdfTrialUrl=null
-                informationQueryService.update(Wrappers.<InformationQuery>lambdaUpdate().set(InformationQuery::getPdfTrialUrl, null).eq(InformationQuery::getId, informationQuery.getId()));
+                if (informationQuery != null) {
+                    informationQueryService.update(Wrappers.<InformationQuery>lambdaUpdate().set(InformationQuery::getPdfTrialUrl, null).eq(InformationQuery::getId, informationQuery.getId()));
+                }
             }
             //删除该类型的所有记录信息
             baseMapper.deleteSeletedStatusByNodeId(dto.getNodeId(), dto.getType(), null);
-
             return true;
         }
-
         return false;
     }
 
+
 }

+ 3 - 3
blade-service/blade-e-visa/blade-e-visa.iml

@@ -1,14 +1,14 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
   <component name="FacetManager">
+    <facet type="Spring" name="Spring">
+      <configuration />
+    </facet>
     <facet type="web" name="Web">
       <configuration>
         <webroots />
       </configuration>
     </facet>
-    <facet type="Spring" name="Spring">
-      <configuration />
-    </facet>
   </component>
   <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
     <output url="file://$MODULE_DIR$/target/classes" />

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

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

@@ -7,10 +7,6 @@
     <facet type="web" name="Web">
       <configuration>
         <webroots />
-        <sourceRoots>
-          <root url="file://$MODULE_DIR$/src/main/java" />
-          <root url="file://$MODULE_DIR$/src/main/resources" />
-        </sourceRoots>
       </configuration>
     </facet>
   </component>
@@ -20,7 +16,6 @@
     <content url="file://$MODULE_DIR$">
       <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
       <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
-      <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
       <excludeFolder url="file://$MODULE_DIR$/target" />
     </content>
     <orderEntry type="inheritedJdk" />

+ 8 - 2
blade-service/blade-manager/src/main/java/com/jfireel/expression/node/impl/EqualNode.java

@@ -1,8 +1,11 @@
 package com.jfireel.expression.node.impl;
 
 import com.jfireel.expression.token.Operator;
+import com.jfireel.expression.util.ValueUtil;
 import com.jfireel.expression.util.number.EqUtil;
+import com.mixsmart.utils.StringUtils;
 
+import java.util.List;
 import java.util.Map;
 
 public class EqualNode extends OperatorResultNode {
@@ -17,13 +20,16 @@ public class EqualNode extends OperatorResultNode {
 		Object rightValue = rightOperand.calculate(variables);
 		if (leftValue == null && rightValue == null) {
 			return true;
-		} else if (leftValue == null && rightValue != null) {
+		} else if (leftValue == null) {
 			return false;
-		} else if (leftValue != null && rightValue == null) {
+		} else if (rightValue == null) {
 			return false;
 		} else {
 			if (leftValue instanceof Number && rightValue instanceof Number) {
 				return EqUtil.calculate((Number) leftValue, (Number) rightValue);
+			}else if(leftValue instanceof List ||rightValue instanceof List){
+				Object[] leftAndRight= ValueUtil.obtain(leftOperand.calculate(variables), rightOperand.calculate(variables));
+				return leftAndRight==null?null: StringUtils.isEquals(leftAndRight[0],leftAndRight[1]);
 			} else {
 				return leftValue.equals(rightValue);
 			}

+ 13 - 9
blade-service/blade-manager/src/main/java/com/jfireel/expression/node/impl/GtEqNode.java

@@ -1,8 +1,11 @@
 package com.jfireel.expression.node.impl;
 
 import com.jfireel.expression.token.Operator;
+import com.jfireel.expression.util.ValueUtil;
 import com.jfireel.expression.util.number.LtUtil;
+import com.mixsmart.utils.CustomFunction;
 
+import java.util.List;
 import java.util.Map;
 
 public class GtEqNode extends OperatorResultNode {
@@ -12,14 +15,15 @@ public class GtEqNode extends OperatorResultNode {
 
 	@Override
 	public Object calculate(Map<String, Object> variables) {
-		Object leftValue = leftOperand.calculate(variables);
-		if (leftValue == null) {
-			return null;
-		}
-		Object rightValue = rightOperand.calculate(variables);
-		if (rightValue == null) {
-			return null;
-		}
-		return (Boolean) LtUtil.calculate((Number) leftValue, (Number) rightValue) == false;
+//		Object leftValue = leftOperand.calculate(variables);
+//		if (leftValue == null) {
+//			return null;
+//		}
+//		Object rightValue = rightOperand.calculate(variables);
+//		if (rightValue == null) {
+//			return null;
+//		}
+		Object[] leftAndRight= ValueUtil.obtain(leftOperand.calculate(variables), rightOperand.calculate(variables));
+		return leftAndRight==null?null: !((Boolean) LtUtil.calculate((Number) leftAndRight[0], (Number) leftAndRight[1]));
 	}
 }

+ 11 - 9
blade-service/blade-manager/src/main/java/com/jfireel/expression/node/impl/GtNode.java

@@ -1,6 +1,7 @@
 package com.jfireel.expression.node.impl;
 
 import com.jfireel.expression.token.Operator;
+import com.jfireel.expression.util.ValueUtil;
 import com.jfireel.expression.util.number.GtUtil;
 
 import java.util.Map;
@@ -12,15 +13,16 @@ public class GtNode extends OperatorResultNode {
 
 	@Override
 	public Object calculate(Map<String, Object> variables) {
-		Object leftValue = leftOperand.calculate(variables);
-		if (leftValue == null) {
-			return null;
-		}
-		Object rightValue = rightOperand.calculate(variables);
-		if (rightValue == null) {
-			return null;
-		}
-		return GtUtil.calculate((Number) leftValue, (Number) rightValue);
+//		Object leftValue = leftOperand.calculate(variables);
+//		if (leftValue == null) {
+//			return null;
+//		}
+//		Object rightValue = rightOperand.calculate(variables);
+//		if (rightValue == null) {
+//			return null;
+//		}
+		Object[] leftAndRight= ValueUtil.obtain(leftOperand.calculate(variables), rightOperand.calculate(variables));
+		return leftAndRight==null?null:GtUtil.calculate((Number) leftAndRight[0], (Number) leftAndRight[1]);
 	}
 
 }

+ 11 - 9
blade-service/blade-manager/src/main/java/com/jfireel/expression/node/impl/LtEqNode.java

@@ -1,6 +1,7 @@
 package com.jfireel.expression.node.impl;
 
 import com.jfireel.expression.token.Operator;
+import com.jfireel.expression.util.ValueUtil;
 import com.jfireel.expression.util.number.GtUtil;
 
 import java.util.Map;
@@ -12,15 +13,16 @@ public class LtEqNode extends OperatorResultNode {
 
 	@Override
 	public Object calculate(Map<String, Object> variables) {
-		Object leftValue = leftOperand.calculate(variables);
-		if (leftValue == null) {
-			return null;
-		}
-		Object rightValue = rightOperand.calculate(variables);
-		if (rightValue == null) {
-			return null;
-		}
-		return (Boolean) GtUtil.calculate((Number) leftValue, (Number) rightValue) == false;
+//		Object leftValue = leftOperand.calculate(variables);
+//		if (leftValue == null) {
+//			return null;
+//		}
+//		Object rightValue = rightOperand.calculate(variables);
+//		if (rightValue == null) {
+//			return null;
+//		}
+		Object[] leftAndRight= ValueUtil.obtain(leftOperand.calculate(variables), rightOperand.calculate(variables));
+		return leftAndRight==null?null: !((Boolean) GtUtil.calculate((Number) leftAndRight[0], (Number) leftAndRight[1]));
 	}
 
 }

+ 11 - 9
blade-service/blade-manager/src/main/java/com/jfireel/expression/node/impl/LtNode.java

@@ -1,6 +1,7 @@
 package com.jfireel.expression.node.impl;
 
 import com.jfireel.expression.token.Operator;
+import com.jfireel.expression.util.ValueUtil;
 import com.jfireel.expression.util.number.LtUtil;
 
 import java.util.Map;
@@ -13,15 +14,16 @@ public class LtNode extends OperatorResultNode {
 
 	@Override
 	public Object calculate(Map<String, Object> variables) {
-		Object leftValue = leftOperand.calculate(variables);
-		if (leftValue == null) {
-			return null;
-		}
-		Object rightValue = rightOperand.calculate(variables);
-		if (rightValue == null) {
-			return null;
-		}
-		return LtUtil.calculate((Number) leftValue, (Number) rightValue);
+//		Object leftValue = leftOperand.calculate(variables);
+//		if (leftValue == null) {
+//			return null;
+//		}
+//		Object rightValue = rightOperand.calculate(variables);
+//		if (rightValue == null) {
+//			return null;
+//		}
+		Object[] leftAndRight= ValueUtil.obtain(leftOperand.calculate(variables), rightOperand.calculate(variables));
+		return leftAndRight==null?null:LtUtil.calculate((Number) leftAndRight[0], (Number) leftAndRight[1]);
 	}
 
 }

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

@@ -0,0 +1,37 @@
+package com.jfireel.expression.util;
+
+import com.mixsmart.utils.CustomFunction;
+import com.mixsmart.utils.ListUtils;
+import com.mixsmart.utils.StringUtils;
+
+import java.util.List;
+
+/**
+ * @author yangyj
+ * @Date 2023/3/10 16:41
+ * @description TODO
+ */
+public class ValueUtil {
+    public static Object[] obtain(Object left,Object right){
+        if(StringUtils.isNotEmpty(left,right)){
+            if(left instanceof List){
+                left=sum(CustomFunction.obj2ListNe(left));
+            }
+            if(right instanceof List){
+                right=sum(CustomFunction.obj2ListNe(right));
+
+            }
+            if(StringUtils.isNotEmpty(left)&&StringUtils.isNotEmpty(right)){
+                return new Object[]{left,right};
+            }
+        }
+        return null;
+    }
+
+    public static Object sum(List<Object> list){
+        if(ListUtils.isNotEmpty(list)){
+            return    (float)list.stream().filter(StringUtils::isNumber).map(StringUtils::handleNull).mapToDouble(Double::parseDouble).sum();
+        }
+        return 0;
+    }
+}

+ 23 - 46
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;
@@ -1178,23 +1182,7 @@ public class CustomFunction {
          return  Expression.parse(ari.toString()).calculate().toString();
 	}
 
-	public static Object ifelse(Object b,Object t,Object f){
-		if(b!=null&&Func.isNotBlank(b.toString())){
-			String s = b.toString();
-			boolean fi  = true;
-			if(s.contains("<")||s.contains(">")){
-				 String[] arr=s.split("&&");
-				 for(String e:arr){
-					 if(!(boolean)Expression.parse(e).calculate()){
-					 	fi=false;
-					 	break;
-					 };
-				 }
-			}
-			return fi?t:f;
-		}
-        return t;
-	}
+
 	/**
 	 * @Description  空白或者/都判断为空
 	 * @Param [data]
@@ -1982,33 +1970,25 @@ public class CustomFunction {
 	}
 
 
-	 public static Map<String, String> getTableCols(String uri) throws FileNotFoundException {
-		Map<String, String> dataMap = new HashMap<>();
-		File file1 = ResourceUtil.getFile(uri);
-		FileInputStream fileInputStream = new FileInputStream(file1);
-		String htmlString = IoUtil.readToString(fileInputStream);
-		Document doc = Jsoup.parse(htmlString);
-		Element table = doc.select("table").first();
-		Elements trs = table.select("tr");
-		for (int i = 0; i <= trs.size() - 1; i++) {
-			Element tr = trs.get(i);
-			Elements tds = tr.select("td");
-			for (int j = 0; j < tds.size(); j++) {
-				Element data = tds.get(j);
-				if (!data.children().isEmpty()) {
-					String keyVal = i + "_" + j;
-					Element input=data.children().get(0);
-					String keyname = input.attr("keyname");
-					String name=input.attr("placeholder");
-					if (StringUtils.isNotEmpty(keyname)) {
-						String[] keys = keyname.split("__");
-						String datakey = keys[0]+name;
-						dataMap.merge(datakey, keyVal, (v1, v2) -> v1 + ";" + v2);
-					}
-				}
-			}
+	 public static Map<String, String> getElementCell(String uri) {
+		try {
+			return  Jsoup.parse(IoUtil.readToString(new FileInputStream(ResourceUtil.getFile(uri))))
+					.select("table").first()
+					.select("tr").stream()
+					.flatMap(tr->tr.select("td").stream())
+					.filter(d->!d.children().isEmpty())
+					.map(d->d.children().get(0)).map(d->d.attr("keyname")).filter(StringUtils::isNotEmpty).map(e->e.split("__"))
+					.reduce(
+							new HashMap<>(),
+							(a,b)->{
+								a.merge(b[0], b[1], (v1, v2) -> v1 + ";" + v2);
+								return  a;},
+							(a,b)->null
+					);
+		}catch (Exception e){
+			e.printStackTrace();
+			return new HashMap<>();
 		}
-		return dataMap;
 	}
 
 
@@ -2816,9 +2796,6 @@ public class CustomFunction {
 		return "";
 	}
 
-	/*public static void main(String[] args) {
-		System.out.println();
-	}*/
 
 
 

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

+ 134 - 43
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ExcelTabController.java

@@ -18,6 +18,7 @@ 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;
@@ -445,7 +446,7 @@ public class ExcelTabController extends BladeController {
 
 
     /**
-     * 关联清表-保存1
+     * 关联清表-保存
      */
     @GetMapping("/save-linkTab")
     @ApiOperationSupport(order = 14)
@@ -455,7 +456,7 @@ public class ExcelTabController extends BladeController {
             @ApiImplicitParam(name = "tabId", value = "表Id", required = true),
     })
     public R<List<ExceTabTreVO>> saveLinkeTab(Long exceTabId, Long tabId) throws IOException {
-        String file_path =ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
+        String file_path = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
         //String file_path = "C:\\Users\\泓创开发\\Desktop";
 
         // 关联 私有项目 wbs 数据信息
@@ -492,11 +493,11 @@ public class ExcelTabController extends BladeController {
         //解析
         Element table = doc.select("table").first();
         Elements trs = table.select("tr");
-        if (aPrivate.getInitTableId() == null){
+        if (aPrivate.getInitTableId() == null) {
             org.springblade.manager.entity.TableInfo tableInfo = tableInfoService.getOne(new LambdaQueryWrapper<org.springblade.manager.entity.TableInfo>()
                     .eq(org.springblade.manager.entity.TableInfo::getTabEnName, aPrivate.getInitTableName()));
-            aPrivate.setInitTableId(tableInfo.getId()+"");
-            updateWrapper.set("init_table_id", tableInfo.getId()+"");
+            aPrivate.setInitTableId(tableInfo.getId() + "");
+            updateWrapper.set("init_table_id", tableInfo.getId() + "");
         }
 
         List<WbsFormElement> elementList = wbsFormElementService.selectElementListByFid(aPrivate.getInitTableId() + "");
@@ -1076,7 +1077,7 @@ public class ExcelTabController extends BladeController {
                         ExctabCell exctabCell = new ExctabCell();
                         if ((textInfo.indexOf("年") >= 0 && textInfo.indexOf("月") >= 0 && textInfo.indexOf("日") >= 0) || inputText.indexOf("日期") >= 0) {
                             if (inputText.indexOf("日期") >= 0) {
-                                data.empty().append("<el-date-picker type='date' popper-class='hc-table-form-date-picker'  @keydown.shift.up='keyupShiftUp' @keydown.shift.down='keyupShiftDown' @keydown.shift.left='keyupShiftLeft' format='YYYY年MM月DD日' value-format='YYYY年MM月DD日' @contextmenu.prevent.native='RightClick(" + parm + ")' trIndex=" + i + " tdIndex=" + j + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + " style='width:100%;height:100%;' placeholder='" + inputText + "'> </el-date-picker>");
+                                data.empty().append("<el-date-picker type='date' @keyDowns='dateKeydown' format='YYYY年MM月DD日' value-format='YYYY年MM月DD日' @contextmenu.prevent.native='RightClick(" + parm + ")' trIndex=" + i + " tdIndex=" + j + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + " style='width:100%;height:100%;' placeholder='" + inputText + "'> </el-date-picker>");
                             } else if (textInfo.indexOf("年") >= 0 && textInfo.indexOf("月") >= 0 && textInfo.indexOf("日") >= 0) {
                                 if (inputText.indexOf("专业监理工程师") >= 0) {
                                     inputText = "专业监理工程师_年月日";
@@ -1086,7 +1087,7 @@ public class ExcelTabController extends BladeController {
                                     inputText = "年月日";
                                 }
                             }
-                            data.empty().append("<el-date-picker  popper-class='hc-table-form-date-picker'  @keydown.shift.up='keyupShiftUp' @keydown.shift.down='keyupShiftDown' @keydown.shift.left='keyupShiftLeft' type='date' format='YYYY年MM月DD日' value-format='YYYY年MM月DD日' @contextmenu.prevent.native='RightClick(" + parm + ")' trIndex=" + i + " tdIndex=" + j + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + " style='width:100%;height:100%;' placeholder='年月日'> </el-date-picker>");
+                            data.empty().append("<el-date-picker @keyDowns='dateKeydown'  type='date' format='YYYY年MM月DD日' value-format='YYYY年MM月DD日' @contextmenu.prevent.native='RightClick(" + parm + ")' trIndex=" + i + " tdIndex=" + j + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + " style='width:100%;height:100%;' placeholder='年月日'> </el-date-picker>");
                             exctabCell.setTextInfo(inputText);
                             exctabCell.setExctabId(excelId);
                             exctabCell.setIsDeleted(0);
@@ -1123,32 +1124,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 (!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 +1386,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 +1413,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;
+        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,31 +1518,71 @@ 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 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(StringUtils.isEmpty(pdfUrl+"")){
-                return R.fail(300,"无数据");
-            }else{
-                return R.data(pdfUrl);
+
+            if (stringObjectMap.get("pdf_trial_url") != null || stringObjectMap.get("pdf_trial_url_position") != null) {
+                //合并试验关联文件、试验工程部位信息的pdf
+                pdfUrl = this.mergePdfShow(pdfUrl, stringObjectMap);
             }
 
+            if (StringUtils.isEmpty(pdfUrl + "")) {
+                return R.fail(300, "无数据");
+            } else {
+                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;
+    }
+
+
     /**
      * 用户端删除复制信息表
      */
@@ -1558,17 +1602,46 @@ 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));
@@ -1577,10 +1650,11 @@ public class ExcelTabController extends BladeController {
             e.printStackTrace();
         }
 
-        R info = this.excelTabService.saveOrUpdateInfo(tableInfoList);
-        if (!info.isSuccess()) {
-            return info;
-        }
+            R info = this.excelTabService.saveOrUpdateInfo(tableInfoList);
+            if (!info.isSuccess()) {
+                return info;
+            }
+
         //单个 pdf加载
         for (TableInfo tableInfo : tableInfoList) {
             excelTabService.getBussPdfInfo(Long.parseLong(tableInfo.getPkeyId()));
@@ -1645,7 +1719,7 @@ public class ExcelTabController extends BladeController {
     })
     public R<String> getTheLogPdInfo(String theLogId, String nodePrimaryKeyId, String recordTime, String contractId) throws Exception {
         //获取配置的路径
-        String file_path =ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
+        String file_path = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
 
         //获取对应的日志
         JSONObject theLogJson;
@@ -1797,7 +1871,7 @@ public class ExcelTabController extends BladeController {
                                 String key = e.getColKey();
                                 String[] keys = key.split("__");
                                 String[] trtd = keys[1].split("_");
-                                if ( trs.size() > (Integer.parseInt(trtd[0]))) {
+                                if (trs.size() > (Integer.parseInt(trtd[0]))) {
                                     Element trData = trs.get(Integer.parseInt(trtd[0]));
                                     Elements tdDatas = trData.select("td");
                                     if (tdDatas.size() > Integer.parseInt(trtd[1])) {
@@ -1816,7 +1890,8 @@ public class ExcelTabController extends BladeController {
                                         cellRange.getCellStyle().getFont().setColor(Color.white);
                                     }
 
-                            }});
+                                }
+                            });
                         }
                     }
                 }
@@ -1976,10 +2051,10 @@ public class ExcelTabController extends BladeController {
                     resultMapList.add(reData);
                 }
             }
-        }else {
+        } else {
             WbsTreePrivate node = this.wbsTreePrivateService.getOne(Wrappers.<WbsTreePrivate>lambdaQuery().eq(WbsTreePrivate::getPKeyId, nodePrimaryKeyId));
             WbsTreePrivate tableNode = this.wbsTreePrivateService.getOne(Wrappers.<WbsTreePrivate>lambdaQuery()
-                    .eq(WbsTreePrivate::getParentId, node.getId()).eq(WbsTreePrivate::getProjectId,node.getProjectId()));
+                    .eq(WbsTreePrivate::getParentId, node.getId()).eq(WbsTreePrivate::getProjectId, node.getProjectId()));
             Map<String, Object> reData = new HashMap<>();
             // 获取默认值
             QueryWrapper<TextdictInfo> queryWrapper = new QueryWrapper<>();
@@ -1995,7 +2070,6 @@ public class ExcelTabController extends BladeController {
         }
 
 
-
         return R.data(resultMapList);
     }
 
@@ -2735,12 +2809,27 @@ public class ExcelTabController extends BladeController {
             @ApiImplicitParam(name = "id", value = "记录id-当做groupId", required = true)
     })
     public R<List<Map<String, Object>>> getBussDataInfoTrial(Long id, Long pkeyId) {
-        List<Map<String, Object>> bussDataInfoTrial = excelTabService.getBussDataInfoTrial(id, pkeyId );
+        List<Map<String, Object>> bussDataInfoTrial = excelTabService.getBussDataInfoTrial(id, pkeyId);
         return R.data(bussDataInfoTrial);
     }
 
+    @GetMapping("/get-buss-dataInfo-list-trial")
+    @ApiOperationSupport(order = 34)
+    @ApiOperation(value = "获取试验用户保存数据-施工关联试验数据", notes = "获取试验用户保存数据-施工关联试验数据")
+    @ApiImplicitParams(value = {
+            @ApiImplicitParam(name = "pkeyId", value = "表id", required = true),
+            @ApiImplicitParam(name = "id", value = "记录id-当做groupId", required = true)
+    })
+    public R<Map<String, Object>> getBussDataInfoListTrial(Long id, Long pkeyId) {
+        List<Map<String, Object>> bussDataInfoTrial = excelTabService.getBussDataInfoTrialRecordSG(id, pkeyId);
+        Map<String, Object> map = bussDataInfoTrial.get(0);
+        map.remove("group_id");
+        return R.data(map);
+    }
+
     /**
      * 在线excel 修改回调
+     *
      * @throws IOException
      */
     @PostMapping(value = "/callbackSave")
@@ -2796,11 +2885,13 @@ public class ExcelTabController extends BladeController {
                     }
                 }
             }
-            redata.add(tdList) ;
+            if (tdList != null && tdList.size() >= 1) {
+                redata.add(tdList);
+            }
         }
 
         String[][] res = new String[redata.size()][]; // 存放转换结果的 二维数组
-        for(int i=0; i<res.length; i++){ // 转换方法
+        for (int i = 0; i < res.length; i++) { // 转换方法
             res[i] = redata.get(i).toArray(new String[redata.get(i).size()]);
         }
         return R.data(res);

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

+ 0 - 10
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ProjectInfoController.java

@@ -240,14 +240,4 @@ public class ProjectInfoController extends BladeController {
         return R.data(result);
     }
 
-    /**
-     * 同步节点树基本信息到项目下的合同段
-     */
-    @PostMapping("/sync-node-info")
-    @ApiOperationSupport(order = 14)
-    @ApiOperation(value = "同步节点树基本信息到项目下的合同段", notes = "传入节点pKeyId")
-    public R<Object> syncNodeInfo(@RequestParam Long pKeyId) {
-        return R.status(wbsTreeService.syncNodeInfo(pKeyId));
-    }
-
 }

+ 15 - 15
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,32 +290,32 @@ 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")) { // 日期--年月日时分秒
-            element.empty().append("<el-date-picker popper-class='hc-table-form-date-picker hc-form-id-"+keyname+"' @keydown.shift.up='keyupShiftUp' @keydown.shift.down='keyupShiftDown' @keydown.shift.left='keyupShiftLeft' @keydown.shift.right='keyupShiftRight' v-model=" + vmode + " type='datetime' format='YYYY年MM月DD日 HH:mm:ss' value-format='YYYY年MM月DD日 hh:mm:ss' 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%'   placeholder='" + placeholder + "'> </el-date-picker>");
+            element.empty().append("<el-date-picker @keyDowns='dateKeydown' v-model=" + vmode + " type='datetime' format='YYYY年MM月DD日 HH:mm:ss' value-format='YYYY年MM月DD日 hh:mm:ss' 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%'   placeholder='" + placeholder + "'> </el-date-picker>");
         } else if (textdictInfo.getTextId().equals("dateYMD")) { // 日期--年月日
-            element.empty().append("<el-date-picker popper-class='hc-table-form-date-picker hc-form-id-"+keyname+"' @keydown.shift.up='keyupShiftUp' @keydown.shift.down='keyupShiftDown' @keydown.shift.left='keyupShiftLeft' @keydown.shift.right='keyupShiftRight' v-model=" + vmode + " type='date' format='YYYY年MM月DD日' value-format='YYYY年MM月DD日' 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%'   placeholder='" + placeholder + "'> </el-date-picker>");
+            element.empty().append("<el-date-picker @keyDowns='dateKeydown' v-model=" + vmode + " type='date' format='YYYY年MM月DD日' value-format='YYYY年MM月DD日' 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%'   placeholder='" + placeholder + "'> </el-date-picker>");
         } else if (textdictInfo.getTextId().equals("dateHMS")) { // 日期--时分秒
-            element.empty().append("<el-time-picker popper-class='hc-table-form-date-picker hc-form-id-"+keyname+"' @keydown.shift.up='keyupShiftUp' @keydown.shift.down='keyupShiftDown' @keydown.shift.left='keyupShiftLeft' @keydown.shift.right='keyupShiftRight' v-model=" + vmode + " type='date' format='HH:mm:ss' value-format='HH:mm:ss' 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%'   placeholder='" + placeholder + "'> </el-time-picker>");
+            element.empty().append("<el-time-picker @keyDowns='dateKeydown' v-model=" + vmode + " type='date' format='HH:mm:ss' value-format='HH:mm:ss' 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%'   placeholder='" + placeholder + "'> </el-time-picker>");
         } else if (textdictInfo.getTextId().equals("dateSM")) { // 日期--时分
-            element.empty().append("<el-time-picker popper-class='hc-table-form-date-picker hc-form-id-"+keyname+"' @keydown.shift.up='keyupShiftUp' @keydown.shift.down='keyupShiftDown' @keydown.shift.left='keyupShiftLeft' @keydown.shift.right='keyupShiftRight' v-model=" + vmode + " type='date' format='HH:mm' value-format='HH:mm' 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%'   placeholder='" + placeholder + "'> </el-time-picker>");
+            element.empty().append("<el-time-picker @keyDowns='dateKeydown' v-model=" + vmode + " type='date' format='HH:mm' value-format='HH:mm' 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%'   placeholder='" + placeholder + "'> </el-time-picker>");
         } else if (textdictInfo.getTextId().equals("dateMDHM")) { // 日期--月日时分
-            element.empty().append("<el-date-picker popper-class='hc-table-form-date-picker hc-form-id-"+keyname+"' @keydown.shift.up='keyupShiftUp' @keydown.shift.down='keyupShiftDown' @keydown.shift.left='keyupShiftLeft' @keydown.shift.right='keyupShiftRight' v-model=" + vmode + " type='datetime' format='MM月DD日 HH:mm' value-format='MM月DD日 HH:mm' 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%'   placeholder='" + placeholder + "'> </el-time-picker>");
+            element.empty().append("<el-date-picker @keyDowns='dateKeydown' v-model=" + vmode + " type='datetime' format='MM月DD日 HH:mm' value-format='MM月DD日 HH:mm' 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%'   placeholder='" + placeholder + "'> </el-time-picker>");
         } else if (textdictInfo.getTextId().equals("dateDHM")) { // 日期--日时分
-            element.empty().append("<el-date-picker popper-class='hc-table-form-date-picker hc-form-id-"+keyname+"' @keydown.shift.up='keyupShiftUp' @keydown.shift.down='keyupShiftDown' @keydown.shift.left='keyupShiftLeft' @keydown.shift.right='keyupShiftRight' v-model=" + vmode + " type='datetime' format='DD日 HH:mm' value-format='DD日 HH:mm' 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%'   placeholder='" + placeholder + "'> </el-time-picker>");
+            element.empty().append("<el-date-picker @keyDowns='dateKeydown' v-model=" + vmode + " type='datetime' format='DD日 HH:mm' value-format='DD日 HH:mm' 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%'   placeholder='" + placeholder + "'> </el-time-picker>");
         } else if (textdictInfo.getTextId().equals("daterange")) { // 时间段
-            element.empty().append("<el-date-picker popper-class='hc-table-form-date-picker hc-form-id-"+keyname+"' @keydown.shift.up='keyupShiftUp' @keydown.shift.down='keyupShiftDown' @keydown.shift.left='keyupShiftLeft' @keydown.shift.right='keyupShiftRight' v-model=" + vmode + " type='datetimerange' placeholder=" + placeholder + "  start-placeholder='开始日期'  end-placeholder='结束日期' format='YYYY年MM月DD日' trIndex=" + trindex + " keyname=" + keyname + " weighing=" + weighing + " tdIndex=" + tdindex + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + ">");
+            element.empty().append("<el-date-picker @keyDowns='dateKeydown' v-model=" + vmode + " type='datetimerange' placeholder=" + placeholder + "  start-placeholder='开始日期'  end-placeholder='结束日期' format='YYYY年MM月DD日' trIndex=" + trindex + " keyname=" + keyname + " weighing=" + weighing + " tdIndex=" + tdindex + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + ">");
             element.children().get(0).attr("@change", "datePickerChange($event,'" + keyname + "')");
         } else if (textdictInfo.getTextId().equals("daterangeYMD")) { // 时间段 /
-            element.empty().append("<el-date-picker popper-class='hc-table-form-date-picker hc-form-id-"+keyname+"' @keydown.shift.up='keyupShiftUp' @keydown.shift.down='keyupShiftDown' @keydown.shift.left='keyupShiftLeft' @keydown.shift.right='keyupShiftRight' v-model=" + vmode + " type='datetimerange' range-separator='/' placeholder=" + placeholder + "  start-placeholder='开始日期'  end-placeholder='结束日期' format='YYYY年MM月DD日' trIndex=" + trindex + " keyname=" + keyname + " weighing=" + weighing + " tdIndex=" + tdindex + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + ">");
+            element.empty().append("<el-date-picker @keyDowns='dateKeydown' v-model=" + vmode + " type='datetimerange' range-separator='/' placeholder=" + placeholder + "  start-placeholder='开始日期'  end-placeholder='结束日期' format='YYYY年MM月DD日' trIndex=" + trindex + " keyname=" + keyname + " weighing=" + weighing + " tdIndex=" + tdindex + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + ">");
             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, "未查询到数据");

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

@@ -1,7 +1,10 @@
 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;
@@ -17,25 +20,28 @@ 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.*;
 import org.springblade.manager.mapper.WbsTreeContractMapper;
 import org.springblade.manager.mapper.WbsTreePrivateMapper;
-import org.springblade.manager.service.IProjectInfoService;
-import org.springblade.manager.service.IWbsFormElementService;
-import org.springblade.manager.service.IWbsTreePrivateService;
-import org.springblade.manager.service.IWbsTreeService;
+import org.springblade.manager.service.*;
 import org.springblade.manager.vo.*;
 import org.springblade.manager.wrapper.WbsTreePrivateWrapper;
 import org.springframework.beans.BeanUtils;
+import org.springframework.jdbc.core.BeanPropertyRowMapper;
+import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.web.bind.annotation.*;
 
 import javax.validation.Valid;
 
 import java.io.IOException;
 import java.util.*;
+import java.util.function.Function;
 import java.util.stream.Collectors;
 
 import static org.springblade.core.cache.constant.CacheConstant.SYS_CACHE;
@@ -52,6 +58,8 @@ public class WbsTreePrivateController extends BladeController {
     private final IWbsTreeService wbsTreeService;
     private final IProjectInfoService projectInfoService;
     private final IWbsFormElementService wbsFormElementService;
+    private final IExcelTabService iExcelTabService;
+    private final JdbcTemplate jdbcTemplate;
 
     /**
      * 保存项目日志划分
@@ -317,13 +325,13 @@ public class WbsTreePrivateController extends BladeController {
         List<WbsNodeTableVO> rs = wbsTreePrivateService.selectByNodeTable(parentId, wbsId, projectId);
         if (rs.size() > 0) {
             for (WbsNodeTableVO r : rs) {
-                if (StringUtil.isBlank(r.getHtmlUrl())){
+                if (StringUtil.isBlank(r.getHtmlUrl())) {
                     r.setIsLinkTable(1);
                 }
                 if (StringUtil.isBlank(r.getInitTableId())) {
                     WbsTree wbsTree = wbsTreeService.getById(r.getId());
                     if (wbsTree != null) {
-                        r.setInitTableId(wbsTree.getInitTableId().toString());
+                        r.setInitTableId(com.baomidou.mybatisplus.core.toolkit.ObjectUtils.isNotEmpty(wbsTree.getInitTableId()) ? wbsTree.getInitTableId().toString() : "");
                         r.setElementTotal(Math.toIntExact(wbsFormElementService.count(
                                 new LambdaQueryWrapper<WbsFormElement>().eq(WbsFormElement::getFId, r.getInitTableId()))));
                     }
@@ -495,6 +503,16 @@ public class WbsTreePrivateController extends BladeController {
         return R.status(wbsTreePrivateService.syncProjectEVisa(projectId));
     }
 
+    /**
+     * 同步节点树基本信息到项目下的合同段-包括同步表结构
+     */
+    @PostMapping("/sync-node-info")
+    @ApiOperationSupport(order = 14)
+    @ApiOperation(value = "同步节点树基本信息到项目下的合同段-包括同步表结构", notes = "传入节点pKeyId")
+    public R<Object> syncNodeInfo(@RequestParam Long pKeyId) {
+        return R.status(wbsTreeService.syncNodeInfo(pKeyId));
+    }
+
     /**
      * 同步项目下节点的元素表
      */
@@ -556,7 +574,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);
     }
 
@@ -583,7 +601,8 @@ public class WbsTreePrivateController extends BladeController {
     }
 
     /**
-     * 试验-根据所属方查询当前节点表信息
+     * 试验 - 根据所属方查询当前节点表信息
+     * 使用位置:1、客户端试验自检、施工关联试验数据
      *
      * @param primaryKeyId
      * @param type
@@ -594,9 +613,48 @@ public class WbsTreePrivateController extends BladeController {
      */
     @GetMapping("/search-node-tables")
     @ApiOperationSupport(order = 22)
-    @ApiOperation(value = "试验-根据所属方查询当前节点表信息", notes = "传入节点primaryKeyId;所属方type=1施工,=2监理 ;表单类型tableType=1记录表、=2报告单; 合同段id;项目id;isAdd=是否新增;记录id")
-    public R<List<WbsTreePrivate>> searchNodeAllTable(String primaryKeyId, String type, String tableType, String contractId, String projectId, Integer isAdd, Long id) {
-        return R.data(wbsTreePrivateService.searchNodeAllTable(primaryKeyId, type, tableType, contractId, projectId, isAdd, id));
+    @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);
+        for (WbsTreePrivateVO4 treePrivate : wbsTreePrivateVO4s) {
+            //新增
+            if ((new Integer(1).equals(isAdd)) && ObjectUtil.isEmpty(id)) {
+                //按钮状态
+                treePrivate.setPdfUrl(null);
+                treePrivate.setIsBussShow(1);
+                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;
+                Map<Long, TrialSelfDataRecord> map = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(TrialSelfDataRecord.class)).stream().collect(Collectors.toMap(TrialSelfDataRecord::getTabId, Function.identity()));
+
+                //按钮状态
+                TrialSelfDataRecord record = map.get(treePrivate.getPKeyId());
+                if (record != null) {
+                    treePrivate.setIsBussShow(record.getIsBussShow());
+                    treePrivate.setIsTabPdf(record.getIsTabPdf());
+                    treePrivate.setTabFileType(record.getIsTabFileType());
+                } else {
+                    treePrivate.setPdfUrl(null);
+                    treePrivate.setIsBussShow(1);
+                    treePrivate.setIsTabPdf(1);
+                    treePrivate.setTabFileType(1);
+                }
+
+                //表单数据
+                List<Map<String, Object>> bussDataInfoTrial = iExcelTabService.getBussDataInfoTrial(id, treePrivate.getPKeyId());
+                if (bussDataInfoTrial != null && bussDataInfoTrial.size() > 0) {
+                    bussDataInfoTrial.get(0).remove("group_id");
+                    treePrivate.setBussDataInfoTrial(bussDataInfoTrial.get(0));
+                }
+            }
+        }
+        return R.data(wbsTreePrivateVO4s);
     }
 
     /**
@@ -614,6 +672,7 @@ public class WbsTreePrivateController extends BladeController {
 
     /**
      * 解決项目电签信息重复问题接口
+     *
      * @param pid 当前项目id
      * @return
      */

+ 29 - 46
blade-service/blade-manager/src/main/java/org/springblade/manager/feign/ExcelTabClientImpl.java

@@ -52,20 +52,26 @@ public class ExcelTabClientImpl implements ExcelTabClient {
         String projectId = table.getString("projectId");
         String contractId = table.getString("contractId");
         List<TableInfo> tableInfoList = this.excelTabService.getTableInfoList(dataArray);
-
         String pdfUrl = "";
 
-        //保存数据到数据库-试验,当前记录id作为groupId
+        /**
+         * ------试验填报数据保存,当前记录id作为groupId------
+         */
         this.excelTabService.saveOrUpdateInfoTrial(tableInfoList, id);
+
+        /**
+         * ------公式填充------
+         */
         try {
-            //公式填充
             this.excelTabService.formulaFillData(tableInfoList, Long.parseLong(nodeId));
         } catch (Exception e) {
             e.printStackTrace();
         }
 
         if (isBatchSave == 0) {
-            //单表PDF保存
+            /**
+             * ------单表PDF保存------
+             */
             TableInfo tableInfo = tableInfoList.stream().findAny().orElse(null);
             assert tableInfo != null;
             if (tabIds.contains(tableInfo.getPkeyId())) {
@@ -78,22 +84,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) {
@@ -102,34 +107,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) {
-            //多表PDF保存
-            pdfUrl = excelTabService.getBussPDFSTrial(nodeId,
-                    tableType, //tableType=表类型 1=记录表 2=报告单
-                    String.valueOf(type), //type=所属方 1=施工质检 2=监理抽检
-                    contractId, //合同段id
-                    projectId, //项目id
-                    id,  //记录id
-                    tabIds //新增的表的pKeyIds
-            );
-
-            //修改原材料检测报告原始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;
     }
@@ -141,15 +132,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);
     }
 
 

+ 8 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/feign/WbsTreeContractClientImpl.java

@@ -199,6 +199,14 @@ public class WbsTreeContractClientImpl implements WbsTreeContractClient {
         return this.wbsTreeContractService.list(Wrappers.<WbsTreeContract>lambdaQuery().eq(WbsTreeContract::getContractId, contractId).like(WbsTreeContract::getAncestors, parentId).eq(WbsTreeContract::getIsDeleted, 0));
     }
 
+    @Override
+    public List<WbsTreeContract> queryAllChild(Long contractId) {
+        return this.wbsTreeContractService.list(Wrappers.<WbsTreeContract>lambdaQuery()
+                .eq(WbsTreeContract::getContractId, contractId)
+                .eq(WbsTreeContract::getType, 1)
+                .eq(WbsTreeContract::getIsDeleted, 0));
+    }
+
     @Override
     public List<WbsTreeContract> selectContractTreeAll(String contractId) {
         return this.wbsTreeContractService.selectContractTreeAll(Long.parseLong(contractId));

+ 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/ContractInfoMapper.xml

@@ -288,6 +288,7 @@
         d.is_deleted = 0
         AND d.status = 1
         AND d.type = 1
+        AND wbs_type = 1
         <if test="wbsId!=null and wbsId!=''">
             and wbs_id = #{wbsId}
         </if>

+ 3 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/ExcelTabMapper.java

@@ -71,4 +71,7 @@ public interface ExcelTabMapper extends BaseMapper<ExcelTab> {
 	@Select("select trial_project_name from u_trial_self_inspection_record where id = #{id}")
     String selectTrialRecordOne(@Param("id") Long id);
 
+	@Select("select self_id from u_trial_self_quality_project where quality_node_id = #{nodeId}")
+	List<String> queryTrialRecordId(String nodeId);
+
 }

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

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

@@ -126,6 +126,11 @@ public interface IExcelTabService extends BaseService<ExcelTab> {
      */
     List<Map<String, Object>> getBussDataInfoTrial(Long id, Long pkeyId);
 
+    /**
+     * 获取试验用户端 单个表单接口数据 - 关联施工
+     */
+    List<Map<String, Object>> getBussDataInfoTrialRecordSG(Long id, Long pkeyId);
+
     /**
      * 单PDF 生成 - 试验
      */
@@ -136,7 +141,6 @@ public interface IExcelTabService extends BaseService<ExcelTab> {
      */
     String getBussPDFSTrial(String nodeId, String tableType, String classify, String contractId, String projectId, Long id, String tabIds) throws Exception;
 
-
     /**
      * 保存 首件数据
      */
@@ -152,5 +156,5 @@ public interface IExcelTabService extends BaseService<ExcelTab> {
     /**
      * 在线excel 保存回调
      */
-    ExcelEditCallback callbackSave(ExcelEditCallback callback) ;
+    ExcelEditCallback callbackSave(ExcelEditCallback callback);
 }

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

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

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

@@ -136,22 +136,22 @@ public class ContractInfoServiceImpl extends BaseServiceImpl<ContractInfoMapper,
     public List<WbsTreeContractTreeAllVO> tree3(String contractId, Integer type) {
         List<WbsTreeContractTreeAllVO> wbsTreeContractVOS = baseMapper.tree5(Long.parseLong(contractId));
 //        if (ObjectUtils.isNotEmpty(type) && type == 1) {
-            //获取所有已填报信息
-            Map<String, Long> allTable = informationQueryClient.getTreeAllTable(contractId);
-            Set<String> keySet = allTable.keySet();
-            for (String key : keySet) {
-                for (WbsTreeContractTreeAllVO vo : wbsTreeContractVOS) {
-                    if (key.equals(vo.getId() + "")) {
-                        vo.setSubmitCounts(allTable.get(key));
-                        vo.setColorStatus(2);
-                    }
+        //获取所有已填报信息
+        Map<String, Long> allTable = informationQueryClient.getTreeAllTable(contractId);
+        Set<String> keySet = allTable.keySet();
+        for (String key : keySet) {
+            for (WbsTreeContractTreeAllVO vo : wbsTreeContractVOS) {
+                if (key.equals(vo.getId() + "")) {
+                    vo.setSubmitCounts(allTable.get(key));
+                    vo.setColorStatus(2);
                 }
             }
-            wbsTreeContractVOS.stream().forEach(wtc -> {
-                if (wtc.getSubmitCounts() == null) {
-                    wtc.setSubmitCounts(0L);
-                }
-            });
+        }
+        wbsTreeContractVOS.stream().forEach(wtc -> {
+            if (wtc.getSubmitCounts() == null) {
+                wtc.setSubmitCounts(0L);
+            }
+        });
 //        }
         return buildWbsTreeByStreamByTreeAll(wbsTreeContractVOS);
     }
@@ -521,10 +521,10 @@ 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(Long.parseLong(wbsId), Long.parseLong(projectId), Long.parseLong(contractId), null, null, null);
+        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<>();
+        /*List<String> listResult = new ArrayList<>();
         if (StringUtils.isNotEmpty(selfId)) {
             List<String> list = baseMapper.queryList(selfId);
             if (list.size() > 0) {
@@ -536,10 +536,10 @@ public class ContractInfoServiceImpl extends BaseServiceImpl<ContractInfoMapper,
                     }
                 }
             }
-        }
+        }*/
         Map<String, Object> maps = new HashMap<>();
         maps.put("treeContractAll", wbsTreeContractVOList);
-        maps.put("isSelectedStatus", listResult.stream().distinct().collect(Collectors.toList()));
+        //maps.put("isSelectedStatus", listResult.stream().distinct().collect(Collectors.toList()));
         return maps;
     }
 

+ 247 - 46
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;
@@ -42,6 +43,7 @@ import org.jsoup.nodes.Document;
 import org.jsoup.nodes.Element;
 import org.jsoup.select.Elements;
 import org.springblade.business.entity.InformationQuery;
+import org.springblade.business.entity.TrialSelfInspectionRecord;
 import org.springblade.business.feign.ContractLogClient;
 import org.springblade.business.feign.InformationQueryClient;
 import org.springblade.business.feign.OperationLogClient;
@@ -91,6 +93,8 @@ import java.net.URL;
 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;
 
 /**
@@ -707,17 +711,16 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
     public TransactionStatus beginTransaction(DataSourceTransactionManager transactionManager) {
         DefaultTransactionDefinition def = new DefaultTransactionDefinition();//事务定义类
         def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
-        TransactionStatus status = transactionManager.getTransaction(def);// 返回事务对象
-        return status;
+        return transactionManager.getTransaction(def);
     }
 
-
     @Override
     public R saveOrUpdateInfo(List<TableInfo> tableInfoList) {
 
         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 +771,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 +798,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 {
@@ -945,7 +968,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                 for (Element element : bhtitle) {
                     int trindex = Integer.parseInt(element.attr("trindex"));
                     if (trindex <= 10) {
-                        reData.put(element.attr("keyName"), node.getPartitionCode()==null?"":node.getPartitionCode());
+                        reData.put(element.attr("keyName"), node.getPartitionCode() == null ? "" : node.getPartitionCode());
                     }
                 }
             }
@@ -1047,6 +1070,7 @@ 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);
     }
 
@@ -1054,7 +1078,6 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
     public R getBussPdfInfo(Long pkeyId) throws Exception {
         String file_path = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
        // String file_path = "/Users/hongchuangyanfa/Desktop/";
-
         WbsTreeContract wbsTreeContract = wbsTreeContractService.getBaseMapper().selectOne(Wrappers.<WbsTreeContract>query().lambda()
                 .eq(WbsTreeContract::getPKeyId, pkeyId));
 
@@ -1114,13 +1137,12 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                 newStyle.cloneStyleFrom(cell.getCellStyle());
 
 
-
                 short fontHeightInPoints = redFont.getFontHeightInPoints();
-                if (fontHeightInPoints >= 14 && StringUtils.isEmpty(cell.getStringCellValue()) && fisRow<=8) {
+                if (fontHeightInPoints >= 14 && StringUtils.isEmpty(cell.getStringCellValue()) && fisRow <= 8) {
 
-                    String title=projectInfo.getProjectName();
-                    if(title.length()>=30){
-                        sheet.getRow(fisRow).setHeight((short)900);
+                    String title = projectInfo.getProjectName();
+                    if (title.length() >= 30) {
+                        sheet.getRow(fisRow).setHeight((short) 900);
                         newStyle.setWrapText(true);
                     }
                     redFont.setBold(true);
@@ -1147,7 +1169,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                         if (val.indexOf("__") >= 0) {
                             String[] DataVal = val.split("__");
                             String[] xy = DataVal[1].split("_");
-                            if (Integer.parseInt(xy[0])<trs.size()) {
+                            if (Integer.parseInt(xy[0]) < trs.size()) {
                                 Element ytzData = trs.get(Integer.parseInt(xy[0]));
                                 if (ytzData != null) {
                                     Elements tdsx = ytzData.select("td");
@@ -1258,11 +1280,11 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                         String key = e.getColKey();
                         String[] keys = key.split("__");
                         String[] trtd = keys[1].split("_");
-                        if (Integer.parseInt(trtd[0])<trs.size()) {
+                        if (Integer.parseInt(trtd[0]) < trs.size()) {
                             Element ytzData = trs.get(Integer.parseInt(trtd[0]));
                             if (ytzData != null) {
                                 Elements tdsx = ytzData.select("td");
-                                if (Integer.parseInt(trtd[1])<tdsx.size()) {
+                                if (Integer.parseInt(trtd[1]) < tdsx.size()) {
                                     Element data = ytzData.select("td").get(Integer.parseInt(trtd[1]));
                                     int x1 = Integer.parseInt(data.children().get(0).attr("x1"));
                                     if (x1 == 0) {
@@ -1297,7 +1319,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);
@@ -1381,24 +1403,26 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
         if (tabpdf2.exists()) {
             tabpdf2.delete();
         }
+
+        //资料填报原始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){
+        //获取顺序
+        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 + "' ";
+
+        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);
     }
 
-
     /**
      * 试验 获取填报信息
      */
@@ -1407,6 +1431,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
         List<Map<String, Object>> list = new ArrayList<>();
         Map<String, Object> reData = new HashMap<>();
         WbsTreePrivate wbsTreePrivate = wbsTreePrivateService.getBaseMapper().selectOne(Wrappers.<WbsTreePrivate>query().lambda()
+                .select(WbsTreePrivate::getInitTableName, WbsTreePrivate::getHtmlUrl, WbsTreePrivate::getPKeyId)
                 .eq(WbsTreePrivate::getPKeyId, pkeyId));
         if (wbsTreePrivate == null) {
             return list;
@@ -1417,12 +1442,13 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
 
         //表单是否存储在
         String tabName = wbsTreePrivate.getInitTableName();
-        String isExitSql = " select * from information_schema.TABLES where TABLE_NAME='" + tabName + "'";
+        String isExitSql = "select * from information_schema.TABLES where TABLE_NAME='" + tabName + "'";
         List<Map<String, Object>> tabList = jdbcTemplate.queryForList(isExitSql);
-        if (tabList == null || tabList.size() <= 0) {
-            throw new ServiceException("无实体表对应");
+        if (tabList.size() <= 0) {
+            return list;
         }
 
+        //实体数据
         String querySql = "select * from " + wbsTreePrivate.getInitTableName() + " where p_key_id=" + pkeyId + " and group_id = " + groupId;
         List<Map<String, Object>> dataIn = jdbcTemplate.queryForList(querySql);
 
@@ -1439,6 +1465,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
             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]")) {
@@ -1495,8 +1522,10 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                 }
             }
         }
+
         // 获取默认值
         QueryWrapper<TextdictInfo> queryWrapper = new QueryWrapper<>();
+        queryWrapper.select("col_key", "sig_role_name");
         queryWrapper.eq("type", 4);
         queryWrapper.eq("tab_id", wbsTreePrivate.getPKeyId());
         final List<TextdictInfo> textDictInfos = textdictInfoService.getBaseMapper().selectList(queryWrapper);
@@ -1521,6 +1550,158 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
         return list;
     }
 
+    /**
+     * 试验 获取填报信息 - 施工关联试验数据
+     */
+    @Override
+    public List<Map<String, Object>> getBussDataInfoTrialRecordSG(Long groupId, Long pkeyId) {
+        List<Map<String, Object>> list = new ArrayList<>();
+        Map<String, Object> reData = new HashMap<>();
+        WbsTreePrivate wbsTreePrivate = wbsTreePrivateService.getBaseMapper().selectOne(Wrappers.<WbsTreePrivate>query().lambda()
+                .select(WbsTreePrivate::getInitTableName, WbsTreePrivate::getHtmlUrl, WbsTreePrivate::getPKeyId, WbsTreePrivate::getInitTableId)
+                .eq(WbsTreePrivate::getPKeyId, pkeyId));
+        if (wbsTreePrivate == null) {
+            return list;
+        }
+        if (wbsTreePrivate.getHtmlUrl() == null) {
+            return list;
+        }
+
+        //表单是否存储在
+        String tabName = wbsTreePrivate.getInitTableName();
+        String isExitSql = "select * from information_schema.TABLES where TABLE_NAME='" + tabName + "'";
+        List<Map<String, Object>> tabList = jdbcTemplate.queryForList(isExitSql);
+        if (tabList.size() <= 0) {
+            return list;
+        }
+
+        //实体数据
+        String querySql = "select * from " + wbsTreePrivate.getInitTableName() + " where p_key_id=" + pkeyId + " and group_id = " + groupId;
+        List<Map<String, Object>> dataIn = jdbcTemplate.queryForList(querySql);
+
+        //对应实体表的对应Key字段的KeyName字段名
+        Map<String, WbsFormElement> elementMap = null;
+        if (StringUtils.isNotEmpty(wbsTreePrivate.getInitTableId())) {
+            String eleSql = "select e_key,e_name from m_wbs_form_element where f_id = " + wbsTreePrivate.getInitTableId();
+            elementMap = jdbcTemplate.query(eleSql, new BeanPropertyRowMapper<>(WbsFormElement.class)).stream().collect(Collectors.toMap(WbsFormElement::getEKey, Function.identity()));
+        }
+
+        // 匹配关联
+        try {
+            File file1 = ResourceUtil.getFile(wbsTreePrivate.getHtmlUrl());
+            String htmlString = IoUtil.readToString(new FileInputStream(file1));
+            Document doc = Jsoup.parse(htmlString);
+        } catch (FileNotFoundException e) {
+            e.printStackTrace();
+        }
+
+        if (dataIn.size() >= 1) {
+            Map<String, Object> mysqlData = dataIn.get(0);
+            for (String key : mysqlData.keySet()) {
+                String tabVal = mysqlData.get(key) + "";
+
+                //映射KeyName名称
+                if (elementMap != null && elementMap.size() > 0) {
+                    WbsFormElement wbsFormElement = elementMap.get(key);
+                    if (wbsFormElement != null) {
+
+                        key = wbsFormElement.getEName();
+
+                        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;
+                                    reData.put("pickerKey", pickerKey);
+                                } else {
+                                    reData.put("pickerKey", key);
+                                }
+
+                                String sql = tabData[0];
+                                sql = sql.replaceAll("\\[", "['");
+                                sql = sql.replaceAll("]", "']");
+                                sql = sql.replaceAll("000Z,", "000Z',");
+                                sql = sql.replaceAll(", 20", ", '20");
+                                if (StringUtils.isNotEmpty(tabData[0])) {
+                                    reData.put(key, 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[0]);
+                                        }
+                                    }
+                                } else {
+                                    String[] tabData = tabVal.split("_\\^_");
+                                    if (StringUtils.isNotEmpty(tabData[0])) {
+                                        reData.put(key, tabData[0]);
+                                    }
+                                }
+                            } else if (tabVal.contains("☆")) {
+                                String[] mysql = tabVal.split("☆");
+                                for (String data : mysql) {
+                                    String[] tabData = data.split("_\\^_");
+                                    if (StringUtils.isNotEmpty(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("_^_")) {
+                                String[] tabData = tabVal.split("_\\^_");
+                                if (StringUtils.isNotEmpty(tabData[0])) {
+                                    reData.put(key, tabData[0]);
+                                }
+                            } else {
+                                reData.put(key, tabVal);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        // 获取默认值
+        QueryWrapper<TextdictInfo> queryWrapper = new QueryWrapper<>();
+        queryWrapper.select("col_key", "sig_role_name");
+        queryWrapper.eq("type", 4);
+        queryWrapper.eq("tab_id", wbsTreePrivate.getPKeyId());
+        final List<TextdictInfo> textDictInfos = textdictInfoService.getBaseMapper().selectList(queryWrapper);
+        if (!textDictInfos.isEmpty()) {
+            for (TextdictInfo textdictInfo : textDictInfos) {
+                if (reData.containsKey(textdictInfo.getColKey())) {
+                    String keyVal = reData.get(textdictInfo.getColKey()) + "";
+                } else {
+                    reData.put(textdictInfo.getColKey() + "", textdictInfo.getSigRoleName());
+                }
+            }
+        }
+
+        // 移除Id 和 p_key_id
+        reData.remove("id");
+        reData.remove("p_key_id");
+        reData.remove("classify");
+        reData.remove("contractId");
+        reData.remove("pkeyId");
+        reData.remove("projectId");
+        list.add(reData);
+
+        return list;
+    }
+
+
     /**
      * 试验 单pdf
      */
@@ -1602,15 +1783,19 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                                     x1 = 1;
                                 }
                                 String myData = DataInfo.get(val) + "";
-                                if (myData.contains("T") && myData.contains("-")) {
+
+                                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();
+                                        Date Start_dataStr = sdf.parse(dataVal[0]);
+                                        Date end_dataStr = sdf.parse(dataVal[1]);
+                                        String StartDate = formatStr.format(Start_dataStr);
+                                        String endDate = formatStr.format(end_dataStr);
                                         if (StartDate.equals(endDate)) {
                                             myData = StartDate;
                                         } else {
@@ -1621,6 +1806,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                                         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"));
@@ -1675,9 +1861,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) {
@@ -1778,7 +1964,8 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
         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)) {
@@ -1787,7 +1974,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                 }
             }
             for (WbsTreePrivate record : recordTable) {
-                if (StringUtils.isNotEmpty(record.getHtmlUrl())) { //没有excel表单的不生成pdf
+                if (StringUtils.isNotEmpty(record.getHtmlUrl())) {
                     //生成记录表pdf
                     String bussPdfInfo = this.getBussPDFTrial(record.getPKeyId(), contractId, id);
                     if (StringUtils.isNotEmpty(bussPdfInfo)) {
@@ -1828,22 +2015,23 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
     public void saveOrUpdateInfoTrial(List<TableInfo> tableInfoList, Long groupId) {
         //试验填报
         if (ListUtils.isNotEmpty(tableInfoList)) {
-            try {
-                for (TableInfo tableInfo : tableInfoList) {
-                    WbsTreePrivate wbsTreePrivate = wbsTreePrivateService.getBaseMapper().selectOne(Wrappers.<WbsTreePrivate>query().lambda()
-                            .eq(WbsTreePrivate::getPKeyId, tableInfo.getPkeyId()));
-                    if (wbsTreePrivate == null) {
-                        continue;
-                    }
 
-                    String tabName = wbsTreePrivate.getInitTableName();
-                    //判读修改还是添加
-                    String delSql = "delete from " + tabName + " where p_key_id='" + tableInfo.getPkeyId() + "' and group_id = '" + groupId + "'";
-                    jdbcTemplate.execute(delSql);
+            for (TableInfo tableInfo : tableInfoList) {
+                WbsTreePrivate wbsTreePrivate = wbsTreePrivateService.getBaseMapper().selectOne(Wrappers.<WbsTreePrivate>query().lambda()
+                        .select(WbsTreePrivate::getInitTableName)
+                        .eq(WbsTreePrivate::getPKeyId, tableInfo.getPkeyId()));
+                if (wbsTreePrivate == null || StringUtils.isEmpty(wbsTreePrivate.getInitTableName())) {
+                    continue;
+                }
+
+                try {
+                    //删除SQL
+                    String delSql = "delete from " + wbsTreePrivate.getInitTableName() + " where p_key_id='" + tableInfo.getPkeyId() + "' and group_id = '" + groupId + "'";
 
+                    //新增SQL
                     String sqlInfo = "";
                     LinkedHashMap<String, String> dataMap2 = tableInfo.getDataMap();
-                    sqlInfo = "INSERT INTO " + tabName + " ( ";
+                    sqlInfo = "INSERT INTO " + wbsTreePrivate.getInitTableName() + " ( ";
                     String keyStr = "id,group_id,";
                     String valStr = SnowFlakeUtil.getId() + "," + groupId + ",";
                     for (String keys : dataMap2.keySet()) {
@@ -1854,10 +2042,23 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                     valStr = valStr.substring(0, valStr.lastIndexOf(","));
                     sqlInfo = sqlInfo + keyStr + ") VALUES (" + valStr + ")";
 
-                    jdbcTemplate.execute(sqlInfo);
+                    TransactionStatus transactionStatus = this.beginTransaction(transactionManager1);
+                    try {
+                        //删除
+                        jdbcTemplate.execute(delSql);
+                        //新增
+                        jdbcTemplate.execute(sqlInfo);
+                        //提交事务
+                        transactionManager1.commit(transactionStatus);
+                    } catch (Exception e) {
+                        //回滚
+                        transactionManager1.rollback(transactionStatus);
+
+                        throw new ServiceException("字段过长,新增失败");
+                    }
+                } catch (Exception e) {
+                    e.printStackTrace();
                 }
-            } catch (Exception e) {
-                e.printStackTrace();
             }
         }
     }

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

+ 173 - 213
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;
@@ -72,14 +64,17 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
     public final static String CHECK_ITEMS="CKI";
     public static final Pattern AP=Pattern.compile("(E|WP)\\[([^]']+)]");
     public static final String IF_REG= "(?<=T\\(com.mixsmart.utils.CustomFunction\\).ifelse\\()[^,]+(?=,)";
+    public static final String FC_REG="T\\(com.mixsmart.utils.CustomFunction\\)\\.";
     public static final Pattern IF = Pattern.compile(IF_REG);
     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 static final Pattern POLY = Pattern.compile(POLY_REG);
     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;
     }
@@ -234,14 +230,11 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                 String key =r.substring(r.indexOf(StringPool.COLON)+1);
                 List<AppWbsTreeContractVO> nodeList = this.tec.getTableAll().stream().filter(e->e.getInitTableName().equals(tn)).collect(Collectors.toList());
                 if(Func.isNotEmpty(nodeList)){
+                    removeList.add(r);
                     Map<String,Object> elementInfo= (Map<String, Object>) elementInfoMap.get(r);
                     String tableName = nodeList.get(0).getInitTableName();
-                    try {
-                        if(!this.tec.getCoordinateMap().containsKey(tableName)){
-                            this.tec.getCoordinateMap().put(tableName, getTableCols(nodeList.get(0).getHtmlUrl()));
-                        }
-                    } catch (FileNotFoundException e) {
-                        e.printStackTrace();
+                    if(!this.tec.getCoordinateMap().containsKey(tableName)){
+                        this.tec.getCoordinateMap().put(tableName, CustomFunction.getElementCell(nodeList.get(0).getHtmlUrl()));
                     }
                     List<Map<String,Object>> tableDatas= this.jdbcTemplate.queryForList("select * from "+tableName+" where p_key_id in("+nodeList.stream().map(AppWbsTreeContractVO::getPKeyId).map(StringUtils::handleNull).collect(Collectors.joining(","))+")");
                     fill(tableDatas,removeList,tn,key,StringUtils.handleNull(elementInfo.get("ename")));
@@ -265,11 +258,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                         if(Func.isNotEmpty(targetIds)){
                             if(!this.tec.getCoordinateMap().containsKey(tn)){
                                 tableNamePkIdsMaps.stream().filter(m->StringUtils.isEquals(m.get("tableName"),tn)).findAny().ifPresent(m->{
-                                    try {
-                                        this.tec.getCoordinateMap().put(tn,getTableCols(StringUtils.handleNull(m.get("url"))));
-                                    } catch (FileNotFoundException e) {
-                                        e.printStackTrace();
-                                    }
+                                    this.tec.getCoordinateMap().put(tn,CustomFunction.getElementCell(StringUtils.handleNull(m.get("url"))));
                                 });
                             }
                             List<Map<String,Object>> tableDatas= this.jdbcTemplate.queryForList("select * from "+tn+" where p_key_id in ("+targetIds+")");
@@ -302,7 +291,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
             if(StringUtils.isNotEmpty(values)){
                 FormData tmp=createFormDataFast(name,r,values);
                 if(tmp!=null){
-                    removeList.add(r);
+                    //removeList.add(r);
                     this.formDataMap.put(r,tmp);
                 }
             }
@@ -342,44 +331,12 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
 
             }
             FormData one=   new FormData(code,eds, null,StringPool.EMPTY);
-//            FormData one=   new FormData(code, Arrays.stream(values.split("☆")).map(s->{
-//                String[] t = s.split("_\\^_");
-//                String[] c =t[1].split("_");
-//                return  new ElementData(0,0,t[0],Func.toInt(c[1]),Func.toInt(c[0]));
-//            }).collect(Collectors.toList()), null,StringPool.EMPTY);
             one.setEName(name);
             return one;
         }
         return null;
     }
 
-    public Map<String, String> getTableCols(String  htmlUri) throws FileNotFoundException {
-        Map<String, String> dataMap = new HashMap<>();
-        File file1 = ResourceUtil.getFile(htmlUri);
-        FileInputStream fileInputStream = new FileInputStream(file1);
-        String htmlString = IoUtil.readToString(fileInputStream);
-        Document doc = Jsoup.parse(htmlString);
-        Element table = doc.select("table").first();
-        Elements trs = table.select("tr");
-       // trs.stream().flatMap(tr->tr.select("td").stream()).filter(d->!d.children().isEmpty()).reduce()
-        for (int i = 0; i <= trs.size() - 1; i++) {
-            Element tr = trs.get(i);
-            Elements tds = tr.select("td");
-            for (int j = 0; j < tds.size(); j++) {
-                Element data = tds.get(j);
-                if (!data.children().isEmpty()) {
-                    String keyVal = i + "_" + j;
-                    String keyname = data.children().get(0).attr("keyname");
-                    if (org.apache.commons.lang.StringUtils.isNotEmpty(keyname)) {
-                        String[] keys = keyname.split("__");
-                        String datakey = keys[0];
-                        dataMap.merge(datakey, keyVal, (v1, v2) -> v1 + ";" + v2);
-                    }
-                }
-            }
-        }
-        return dataMap;
-    }
 
 
 
@@ -456,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);
@@ -468,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()){
@@ -513,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();
@@ -532,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);
                                 }
                             });
@@ -559,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);
                                         }
 
                                     }
@@ -574,19 +526,12 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                                 }
                                 if(local.size()>0){
                                     List<Object> values = slice(local,this.constantMap,f);
-                                    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));
-                                        }
-                                    }
+                                    write(fd,values);
                                 }
                             }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);
@@ -619,6 +564,26 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                     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{
@@ -638,57 +603,56 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
     }
 
     /**加页增容*/
-   public void copy(FormData fd, List<Object> values){
-       WbsTreeContract  origin =  this.wbsTreeContractService.getOne(Wrappers.<WbsTreeContract>lambdaQuery().eq(WbsTreeContract::getPKeyId,fd.getTableIds().get(fd.getTableIds().size()-1)));
+   public void copy(FormData fd){
+       int pageAdd=fd.getAddPages();
+       LinkedHashMap<String,List<KeyMapper>> tabs = this.tec.getKeyMappers().stream().collect(Collectors.groupingBy(KeyMapper::getCode,LinkedHashMap::new,Collectors.toList()));
+       List<KeyMapper> kms = tabs.get(fd.getCode());
+       KeyMapper last = kms.get(kms.size()-1);
+       WbsTreeContract  origin =  this.wbsTreeContractService.getOne(Wrappers.<WbsTreeContract>lambdaQuery().eq(WbsTreeContract::getPKeyId,last.getPkId()));
        if(origin!=null){
-           int pageSize = fd.getCoordsList().size();
-           int pageAdd=(int)Math.ceil((double)(values.size()-fd.getValues().size())/(double) pageSize);
            for(int i=0;i<pageAdd;i++){
                /*复制表*/
                WbsTreeContract target = new WbsTreeContract();
                BeanUtil.copy(origin,target);
                target.setPKeyId(SnowFlakeUtil.getId());
-               this.wbsTreeContractService.saveOrUpdate(target);
-               tec.getKeyMappers().stream().filter(e->e.getPkId().equals(origin.getPKeyId())).findFirst().ifPresent(d->{
-                   /*添加KeyMapper映射关系*/
+               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(d,km);
+                   BeanUtil.copy(e,km);
                    km.setPkId(target.getPKeyId());
                    tec.getKeyMappers().add(km);
-                   tec.getTableInfoList().stream().filter(o->StringUtils.isEquals(o.getPkeyId(),origin.getPKeyId())).findFirst().ifPresent(tb->{
-                       /*表单数据复制*/
-                       TableInfo tableInfo = new TableInfo();
-                       BeanUtil.copy(tb,tableInfo);
-                       tableInfo.setDataMap(new LinkedHashMap<>());
-                       tec.getTableInfoList().add(tec.getTableInfoList().indexOf(tb)+1,tableInfo);
-                   });
                });
+               tec.getTableInfoList().stream().filter(o->StringUtils.isEquals(o.getPkeyId(),pkeyId)).findFirst().ifPresent(tb->{
+                   /*表单数据复制*/
+                   TableInfo tableInfo = new TableInfo();
+                   BeanUtil.copy(tb,tableInfo);
+                   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);
+           //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++;
-              }
-          }
-        });
-   }
 
 
 
@@ -709,6 +673,11 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                 }
             }
         }
+        /*检查超页情况*/
+        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)));;
+
     }
 
     @Override
@@ -725,9 +694,10 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
             /*当前节点的某个元素存在多种作用域的公式,作用域范围越小优先级越高*/
             List<KeyMapper> list= listMap.stream().map(m->BeanUtil.toBean(m,KeyMapper.class)).collect(Collectors.toList());
             String nodeIdStr=nodeIds.stream().map(Object::toString).collect(Collectors.joining(StringPool.COMMA));
-            StringBuilder sb = new StringBuilder("select element_id elementId,formula_id formulaId,scope from m_element_formula_mapping where element_id in("+list.stream().map(KeyMapper::getFieldId).map(Func::toStr).collect(Collectors.joining(","))+") and is_deleted=0 ");
-            sb.append(" and ( scope<2 or (scope=2 and node_id in(").append(nodeIdStr).append(")) or (scope =10 and project_id = ").append(projectId).append(") or (scope=20 and project_id =").append(projectId).append(" and node_id in (").append(nodeIdStr).append(")))");
-            List<Map<String,Object>> efMap= this.jdbcTemplate.queryForList(sb.toString());
+            List<Map<String,Object>> efMap= this.jdbcTemplate.queryForList("select element_id elementId,formula_id formulaId,scope " +
+                    "from m_element_formula_mapping " +
+                    "where element_id in(" + list.stream().map(KeyMapper::getFieldId).map(Func::toStr).collect(Collectors.joining(",")) + ") " +
+                    "and is_deleted=0 " + " and ( scope<2 or (scope=2 and node_id in(" + nodeIdStr + ")) or (scope =10 and project_id = " + projectId + ") or (scope=20 and project_id =" + projectId + " and node_id in (" + nodeIdStr + ")))");
             if(Func.isNotEmpty(efMap)){
                 Map<Long,List<Map<String,Object>>> efGroup= efMap.stream().collect(Collectors.groupingBy(e->Func.toLong(e.get("elementId"))));
                 list.forEach(e->{
@@ -758,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){
@@ -850,7 +812,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                  Formula formula=fd.getFormula();
                  String f=formula.getFormula();
                  if (f.contains("converge")){
-                     Matcher m = RegexUtils.matcher("T\\(com.mixsmart.utils.CustomFunction\\)\\.(converge)\\(([^)]+)\\)",f);
+                     Matcher m = RegexUtils.matcher(FC_REG+"(converge)\\(([^)]+)\\)",f);
                      while (m.find()){
                          List<FormData> target = getFormDataByCode(m.group(2));
                          Object data =target.stream().flatMap(e->e.getValues().stream()).map(ElementData::getValue).filter(StringUtils::isNotEmpty).collect(Collectors.toList());
@@ -858,7 +820,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                      }
                  }
                  if(f.contains("compound")){
-                     Matcher m = RegexUtils.matcher("T\\(com.mixsmart.utils.CustomFunction\\)\\.(compound)\\(([^)]+)\\)",f);
+                     Matcher m = RegexUtils.matcher(FC_REG+"(compound)\\(([^)]+)\\)",f);
                      while (m.find()){
                          List<FormData> target = getFormDataByCode(m.group(2));
                          List<List<Object>> values=target.stream().map(e->e.getValues().stream().map(ElementData::getValue).collect(Collectors.toList())).collect(Collectors.toList());
@@ -871,17 +833,19 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                      }
                  }
                  if(f.contains(".option")){
-                     Matcher m = RegexUtils.matcher("T\\(com.mixsmart.utils.CustomFunction\\)\\.(optionC?)\\(([^)]+)\\)",f);
+                     /*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);
@@ -894,15 +858,34 @@ 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(),"''");
                        }
                      }
                  }
+                 if(f.contains(".ifelse")){
+                     int max=0;
+                     do{
+                         Matcher m = RegexUtils.matcher(FC_REG+"(ifelse)\\(([^)]+)\\)",f);
+                         while (m.find()){
+                             String el=m.group();
+                             String pstr=el.replaceAll("^"+FC_REG+"ifelse\\(","").replaceAll("\\)$","");
+                             String pa[]=pstr.split(",");
+                             if(pa.length==3){
+                                 Object data = Expression.parse(pa[0]+"?"+pa[1]+":"+pa[2]).calculate(createCurrentMap(el));
+                                 f=f.replace(el,putDataWithKey(data));
+                             }else{
+                                 f=f.replace(el,"参数格式错误");
+                             }
+
+                         }
+                       max++;
+                     }while (f.contains("ifelse")&&max<20);
+                 }
                  if(f.contains("quantity")){
                      /*聚合*/
-                     Matcher m = RegexUtils.matcher("T\\(com.mixsmart.utils.CustomFunction\\)\\.(quantity)\\(([^)]+)\\)",f);
+                     Matcher m = RegexUtils.matcher(FC_REG+"(quantity)\\(([^)]+)\\)",f);
                      while (m.find()) {
                          Object data=null;
                          List<String> codeList = getCodeList(m.group(2));
@@ -937,64 +920,51 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
 
 
 
+   public Map<String,Object> createCurrentMap(String el){
+         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> Em= (Map<String, Object>) currentMap.computeIfAbsent(E, k->new HashMap<String,Object>());
+             fds.forEach(e->{
+                 Em.put(e.getCode(),e.getValues().stream().map(ElementData::getValue).collect(Collectors.toList()));
+             });
+         }
+        return currentMap;
+   }
+
     public void  tmpFc(FormData fd){
         /*临时代码,牛皮癣的存在,替代后删除*/
         Formula formula = fd.getFormula();
         if(Func.isNotEmpty(formula)){
             String f=formula.getFormula();
             try {
-                if(Func.isNotBlank(f)) {
-                     if(f.contains(CustomFunction.CLASS_CALL+"proportion(")||f.contains(CustomFunction.CLASS_CALL+"ladder(")||f.contains(CustomFunction.CLASS_CALL+"major(")||f.contains(CustomFunction.CLASS_CALL+"reasonable(") ||f.contains(CustomFunction.CLASS_CALL+"goodSize(")){
-                        String tf=f.replaceAll("^T\\(com.mixsmart.utils.CustomFunction\\)\\.\\w+\\(","").replaceAll("[)]$","");
-                        List<FormData> target = getFormDataByCode(tf);
-                        if(Func.isNotEmpty(target)){
-                            if(StringUtils.isEmpty(formula.getScale())){
-                                formula.setScale(2);
-                            }
-                            Object data=null;
-                            if(f.contains("proportion")){
-                                data= CustomFunction.proportion(target.stream().map(FormData::getValues).filter(Func::isNotEmpty).map(e->e.get(0).getValue()).collect(Collectors.toList()), "优良");
-                            }else if(f.contains("ladder")){
-                                data= CustomFunction.ladder(target.stream().map(FormData::getValues).filter(Func::isNotEmpty).map(e->e.get(0).getValue()).collect(Collectors.toList()));
-                            }else if(f.contains("major")){
-                                data= CustomFunction.major(target.stream().map(FormData::getValues).filter(Func::isNotEmpty).map(e->e.get(0).getValue()).collect(Collectors.toList()));
-                            }else if(f.contains("reasonable")){
-                                data= CustomFunction.reasonable(target.stream().map(FormData::getValues).filter(Func::isNotEmpty).map(e->e.get(0).getValue()).collect(Collectors.toList()));
-                            }else if(f.contains("goodSize")){
-                                data= CustomFunction.goodSize(target.stream().map(FormData::getValues).filter(Func::isNotEmpty).map(e->e.get(0).getValue()).collect(Collectors.toList()),"优良");
-                            }
-                            String key ="HA"+HashUtil.identityHashCode(data);
-                            fd.getFormula().setFormula(key);
-                            this.constantMap.put(key,data);
-                        }else{
-                            fd.getFormula().setFormula(StringPool.EMPTY);
+                if(f.contains(CustomFunction.CLASS_CALL+"proportion(")||f.contains(CustomFunction.CLASS_CALL+"ladder(")||f.contains(CustomFunction.CLASS_CALL+"major(")||f.contains(CustomFunction.CLASS_CALL+"reasonable(") ||f.contains(CustomFunction.CLASS_CALL+"goodSize(")){
+                    String tf=f.replaceAll("^T\\(com.mixsmart.utils.CustomFunction\\)\\.\\w+\\(","").replaceAll("[)]$","");
+                    List<FormData> target = getFormDataByCode(tf);
+                    if(Func.isNotEmpty(target)){
+                        if(StringUtils.isEmpty(formula.getScale())){
+                            formula.setScale(2);
                         }
-                    }else if(f.contains(CustomFunction.CLASS_CALL+"ifelse(")){
-                        Matcher im =IF.matcher(f);
-                        while (im.find()){
-                            String rep =im.group();
-                            Matcher fm=P.matcher(rep);
-                            while (fm.find()){
-                                FormData kf=  this.formDataMap.get(fm.group().replaceAll("'",""));
-                                if(kf!=null&&!kf.empty()){
-                                    ElementData ed= kf.getValues().get(0);
-                                    if(ed!=null&&Func.isNotEmpty(ed.getValue())){
-                                        rep= rep.replace("E["+fm.group()+"]",ed.getValue().toString());
-                                        rep="'"+rep+"'";
-                                        f=f.replace(im.group(),rep);
-                                    }else{
-                                        f="";
-                                    }
-                                }else{
-                                    f="";
-                                }
-                            }
+                        Object data=null;
+                        if(f.contains("proportion")){
+                            data= CustomFunction.proportion(target.stream().map(FormData::getValues).filter(Func::isNotEmpty).map(e->e.get(0).getValue()).collect(Collectors.toList()), "优良");
+                        }else if(f.contains("ladder")){
+                            data= CustomFunction.ladder(target.stream().map(FormData::getValues).filter(Func::isNotEmpty).map(e->e.get(0).getValue()).collect(Collectors.toList()));
+                        }else if(f.contains("major")){
+                            data= CustomFunction.major(target.stream().map(FormData::getValues).filter(Func::isNotEmpty).map(e->e.get(0).getValue()).collect(Collectors.toList()));
+                        }else if(f.contains("reasonable")){
+                            data= CustomFunction.reasonable(target.stream().map(FormData::getValues).filter(Func::isNotEmpty).map(e->e.get(0).getValue()).collect(Collectors.toList()));
+                        }else if(f.contains("goodSize")){
+                            data= CustomFunction.goodSize(target.stream().map(FormData::getValues).filter(Func::isNotEmpty).map(e->e.get(0).getValue()).collect(Collectors.toList()),"优良");
                         }
-                        formula.setFormula(f);
+                        String key ="HA"+HashUtil.identityHashCode(data);
+                        fd.getFormula().setFormula(key);
+                        this.constantMap.put(key,data);
+                    }else{
+                        fd.getFormula().setFormula(StringPool.EMPTY);
                     }
-                    relyParse(fd.getFormula());
-                    StaticLog.info("聚合处理");
                 }
+                relyParse(fd.getFormula());
             }catch (Exception e){
                 e.printStackTrace();
             }
@@ -1012,6 +982,18 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
         }
         return list;
     }
+
+    public List<String> getCodeByEl(String el){
+        List<String> l = new ArrayList<>();
+        if(Func.isNotBlank(el)){
+            Matcher m = P.matcher(el);
+            while (m.find()){
+                String tmp =m.group().replaceAll("'","");
+                l.add(tmp);
+            }
+        }
+        return l;
+    }
     /**把计算结果放入固定常量集,创建key来引用*/
     public String putDataWithKey(Object data){
         String key ="HA"+HashUtil.identityHashCode(data);
@@ -1050,29 +1032,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
         return new HashMap<>();
     }
 
-    public void batch(){
-        List<Map<String,Object>> list = this.jdbcTemplate.queryForList("select id,formula from m_formula where (formula like '%reasonable%' or formula like '%proportion%' or formula like '%goodSize%')");
-        if(ListUtils.isNotEmpty(list)){
-            Pattern p = Pattern.compile("^FC\\.(\\w+)\\(([^()]+)\\)");
-            for (Map<String,Object>map:list){
-                Long ident = (Long) map.get("id");
-                String formula = (String) map.get("formula");
-                Matcher m= p.matcher(formula);
-                if(m.find()){
-                    String change=m.group(2);
-                    String fn=m.group(1);
-                    List<String> args=Arrays.stream(change.split(",")).collect(Collectors.toList());
-                    if(args.size()<18){
-                        args.addAll(Collections.nCopies(18-args.size(),"''"));
-                        System.out.println("原:"+formula);
-                        String newFormula=("FC."+fn+"("+String.join(",",args)+")");
-                        System.out.println("改:"+newFormula);
-                        this.update(Wrappers.<Formula>lambdaUpdate().set(Formula::getFormula,newFormula).eq(Formula::getId,ident));
-                    }
-                }
-            }
-        }
-    }
+
 
 }
 

+ 111 - 52
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;
@@ -12,6 +13,7 @@ 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,6 +30,7 @@ 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.Scheduled;
@@ -37,6 +40,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;
@@ -457,10 +461,44 @@ public class WbsTreePrivateServiceImpl extends BaseServiceImpl<WbsTreePrivateMap
         List<WbsTreePrivate> listPrivate = new ArrayList<>();
         List<WbsTreeContract> listContract = new ArrayList<>();
         //获取当前项目下所有合同段信息
-        List<ContractInfo> contractInfos = contractInfoMapper.selectList(Wrappers.<ContractInfo>query().lambda().select(ContractInfo::getId).eq(ContractInfo::getPId, projectId));
+        List<ContractInfo> contractInfos = contractInfoMapper.selectList(Wrappers.<ContractInfo>query().lambda().select(ContractInfo::getId, ContractInfo::getContractType).eq(ContractInfo::getPId, projectId));
+        List<Long> contractInfosIds = contractInfos.stream().filter(f -> 1 == f.getContractType()).map(ContractInfo::getId).collect(Collectors.toList());
+
+        Map<Long, WbsTreePrivate> maps = wbsTreePrivatesAllNow.stream().collect(Collectors.toMap(WbsTreePrivate::getId, Function.identity()));
 
         for (WbsTreePrivate wbsTreePrivate : wbsTreePrivates) {
-            for (WbsTreePrivate treePrivateNow : wbsTreePrivatesAllNow) {
+            WbsTreePrivate treePrivateNow = maps.get(wbsTreePrivate.getId());
+            if (treePrivateNow != null) {
+                if (!wbsTreePrivate.getNodeName().equals(treePrivateNow.getNodeName())
+                        || (ObjectUtils.isNotEmpty(wbsTreePrivate.getNodeType()) && !wbsTreePrivate.getNodeType().equals(treePrivateNow.getNodeType()))
+                        || (ObjectUtils.isNotEmpty(wbsTreePrivate.getMajorDataType()) && !wbsTreePrivate.getMajorDataType().equals(treePrivateNow.getMajorDataType()))
+                        || (ObjectUtils.isNotEmpty(wbsTreePrivate.getTableType()) && !wbsTreePrivate.getTableType().equals(treePrivateNow.getTableType()))
+                        || (ObjectUtils.isNotEmpty(wbsTreePrivate.getTableOwner()) && !wbsTreePrivate.getTableOwner().equals(treePrivateNow.getTableOwner()))
+                        || (ObjectUtils.isNotEmpty(wbsTreePrivate.getImportMatchingInfo()) && !wbsTreePrivate.getImportMatchingInfo().equals(treePrivateNow.getImportMatchingInfo()))
+                        || (ObjectUtils.isNotEmpty(wbsTreePrivate.getMixRatioTestIds()) && !wbsTreePrivate.getMixRatioTestIds().equals(treePrivateNow.getMixRatioTestIds()))
+                        || (ObjectUtils.isNotEmpty(wbsTreePrivate.getInitTableId()) && !wbsTreePrivate.getInitTableId().equals(treePrivateNow.getInitTableId()))
+                        || (ObjectUtils.isNotEmpty(wbsTreePrivate.getInitTableName()) && !wbsTreePrivate.getInitTableName().equals(treePrivateNow.getInitTableName())
+                        || (ObjectUtils.isNotEmpty(wbsTreePrivate.getHtmlUrl()) && !wbsTreePrivate.getHtmlUrl().equals(treePrivateNow.getHtmlUrl())))) {
+                    //修改项目wbs信息
+                    WbsTreePrivate wbsPrivate = BeanUtil.copyProperties(wbsTreePrivate, WbsTreePrivate.class);
+                    if (wbsPrivate != null) {
+                        wbsPrivate.setWbsId(wbsId);
+                        wbsPrivate.setProjectId(projectId);
+                        listPrivate.add(wbsPrivate);
+                    }
+                    for (Long id : contractInfosIds) {
+                        //修改合同段wbs信息
+                        WbsTreeContract wbsContract = BeanUtil.copyProperties(wbsTreePrivate, WbsTreeContract.class);
+                        if (wbsContract != null) {
+                            wbsContract.setContractId(id.toString());
+                            wbsContract.setProjectId(projectId);
+                            listContract.add(wbsContract);
+                        }
+                    }
+                }
+            }
+
+           /*for (WbsTreePrivate treePrivateNow : wbsTreePrivatesAllNow) {
                 //判断相同节点基础信息、元素表类型、元素表所属方 是否发生改变
                 if (wbsTreePrivate.getId().equals(treePrivateNow.getId()) &&
                         (!wbsTreePrivate.getNodeName().equals(treePrivateNow.getNodeName())
@@ -490,7 +528,7 @@ public class WbsTreePrivateServiceImpl extends BaseServiceImpl<WbsTreePrivateMap
                         }
                     }
                 }
-            }
+            }*/
         }
 
         //修改到项目
@@ -500,9 +538,11 @@ public class WbsTreePrivateServiceImpl extends BaseServiceImpl<WbsTreePrivateMap
 
         //修改到合同段
         if (listContract.size() > 0) {
-            //获取合同段下的复制、新增节点
-            List<WbsTreeContract> wbsTreeContractsCopyOrAddAll = new ArrayList<>();
-            for (ContractInfo contractInfo : contractInfos) {
+            //获取当前项目下所有合同段下的复制、新增节点
+            String sql = "select id,old_id,project_id,contract_id from m_wbs_tree_contract where project_id = " + projectId + " and contract_id in(" + org.apache.commons.lang.StringUtils.join(contractInfosIds, ",") + ") and wbs_type = " + wbsType + " and type = 1 and status = 1 and is_deleted = 0 and old_id is not null";
+            List<WbsTreeContract> wbsTreeContractsCopyOrAddAll = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(WbsTreeContract.class));
+            Map<String, List<WbsTreeContract>> copyAddNodes = wbsTreeContractsCopyOrAddAll.stream().collect(Collectors.groupingBy(WbsTreeContract::getOldId));
+            /*for (ContractInfo contractInfo : contractInfos) {
                 List<WbsTreeContract> wbsTreeContractsCopyOrAdd = wbsTreeContractMapper.selectList(Wrappers.<WbsTreeContract>lambdaQuery()
                         .select(WbsTreeContract::getId, WbsTreeContract::getOldId, WbsTreeContract::getProjectId, WbsTreeContract::getContractId)
                         .eq(WbsTreeContract::getProjectId, projectId)
@@ -512,13 +552,14 @@ public class WbsTreePrivateServiceImpl extends BaseServiceImpl<WbsTreePrivateMap
                         .isNotNull(WbsTreeContract::getOldId)
                 );
                 wbsTreeContractsCopyOrAddAll.addAll(wbsTreeContractsCopyOrAdd);
-            }
+            }*/
 
             List<WbsTreeContract> listContractAdd = new ArrayList<>();
-
             for (WbsTreeContract obj1 : listContract) {
-                for (WbsTreeContract obj2 : wbsTreeContractsCopyOrAddAll) {
-                    if (obj1.getId().toString().equals(obj2.getOldId()) && obj1.getProjectId().equals(obj2.getProjectId()) && obj1.getContractId().equals(obj2.getContractId())) {
+                List<WbsTreeContract> copyAddNodesNow = copyAddNodes.get(obj1.getId().toString());
+                if (copyAddNodesNow.size() > 0) {
+                    WbsTreeContract obj2 = copyAddNodesNow.stream().filter(f -> f.getContractId().equals(obj1.getContractId()) && f.getProjectId().equals(obj1.getProjectId())).findAny().orElse(null);
+                    if (obj2 != null) {
                         obj2.setNodeName(obj1.getNodeName());
                         obj2.setNodeType(obj1.getNodeType());
                         obj2.setMajorDataType(obj1.getMajorDataType());
@@ -528,6 +569,17 @@ public class WbsTreePrivateServiceImpl extends BaseServiceImpl<WbsTreePrivateMap
                         listContractAdd.add(obj2);
                     }
                 }
+                /*for (WbsTreeContract obj2 : wbsTreeContractsCopyOrAddAll) {
+                    if (obj1.getId().toString().equals(obj2.getOldId()) && obj1.getProjectId().equals(obj2.getProjectId()) && obj1.getContractId().equals(obj2.getContractId())) {
+                        obj2.setNodeName(obj1.getNodeName());
+                        obj2.setNodeType(obj1.getNodeType());
+                        obj2.setMajorDataType(obj1.getMajorDataType());
+                        obj2.setTableType(obj1.getTableType());
+                        obj2.setTableOwner(obj1.getTableOwner());
+                        obj2.setHtmlUrl(obj1.getHtmlUrl());
+                        listContractAdd.add(obj2);
+                    }
+                }*/
             }
 
             listContractAdd.addAll(listContract);
@@ -1102,7 +1154,7 @@ public class WbsTreePrivateServiceImpl extends BaseServiceImpl<WbsTreePrivateMap
                             dataPrivate.setWbsType(wbsTreePrivate.getWbsType());
                             dataPrivate.setProjectId(wbsTreePrivate.getProjectId());
                             dataPrivate.setFullName(dataPrivate.getNodeName());
-                            dataPrivate.setInitTableId(tree.getInitTableId().toString());
+                            dataPrivate.setInitTableId(ObjectUtils.isNotEmpty(tree.getInitTableId()) ? tree.getInitTableId().toString() : null);
                             //新增
                             insertDataPrivateList.add(dataPrivate);
 
@@ -1226,7 +1278,7 @@ public class WbsTreePrivateServiceImpl extends BaseServiceImpl<WbsTreePrivateMap
                             dataPrivate.setWbsId(wbsTreePrivate.getWbsId());
                             dataPrivate.setWbsType(tree.getWbsType());
                             dataPrivate.setProjectId(wbsTreePrivate.getProjectId());
-                            dataPrivate.setInitTableId(tree.getInitTableId());
+                            dataPrivate.setInitTableId(ObjectUtils.isNotEmpty(tree.getInitTableId()) ? tree.getInitTableId() : null);
 
                             insertDataPrivateList.add(dataPrivate);
 
@@ -1357,10 +1409,11 @@ public class WbsTreePrivateServiceImpl extends BaseServiceImpl<WbsTreePrivateMap
                 for (WbsTreePrivate wbsTreePrivate : collect1) {
                     if (wbsTreePrivate.getType() == 2) {
                         WbsTreePrivate obj = nowNodeTreeAll.get(wbsTreePrivate.getParentId());
-                        assert obj != null;
-                        List<TextdictInfo> textDictInfos = collect3.get(String.valueOf(wbsTreePrivate.getPKeyId()));
-                        if (textDictInfos != null && textDictInfos.size() > 0) {
-                            textDictInfoData.put(wbsTreePrivate.getId(), textDictInfos);
+                        if (obj != null) {
+                            List<TextdictInfo> textDictInfos = collect3.get(String.valueOf(wbsTreePrivate.getPKeyId()));
+                            if (textDictInfos != null && textDictInfos.size() > 0) {
+                                textDictInfoData.put(wbsTreePrivate.getId(), textDictInfos);
+                            }
                         }
                     }
 
@@ -1385,10 +1438,11 @@ public class WbsTreePrivateServiceImpl extends BaseServiceImpl<WbsTreePrivateMap
                     if (textDictInfos != null) {
                         for (TextdictInfo textdictInfo : textDictInfos) {
                             TextdictInfo obj = BeanUtil.copyProperties(textdictInfo, TextdictInfo.class);
-                            assert obj != null;
-                            obj.setId(SnowFlakeUtil.getId());
-                            obj.setTabId(tree.getPKeyId().toString()); //重新赋值绑定到对应的表上
-                            insertData.add(obj);
+                            if (obj != null) {
+                                obj.setId(SnowFlakeUtil.getId());
+                                obj.setTabId(tree.getPKeyId().toString()); //重新赋值绑定到对应的表上
+                                insertData.add(obj);
+                            }
                         }
                     }
                 });
@@ -1485,7 +1539,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不能为空");
         }
@@ -1495,11 +1549,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() + "");
@@ -1583,9 +1670,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);
@@ -1647,6 +1732,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) {
         WbsTreePrivate wbsTreePrivate = baseMapper.selectOne(Wrappers.<WbsTreePrivate>query().lambda()
+                .select(WbsTreePrivate::getProjectId, WbsTreePrivate::getWbsId, WbsTreePrivate::getId)
                 .eq(WbsTreePrivate::getPKeyId, primaryKeyId));
         if (wbsTreePrivate == null) {
             return Collections.emptyList();
@@ -1679,34 +1765,7 @@ public class WbsTreePrivateServiceImpl extends BaseServiceImpl<WbsTreePrivateMap
             tableOwnerList = Func.toStrList(tableOwners);
         }
 
-        List<WbsTreePrivate> wbsTreePrivates = baseMapper.selectWbsTreeContractList(roleAndTabOwners, tableType, wbsTreePrivate.getProjectId(), wbsTreePrivate.getWbsId(), wbsTreePrivate.getId(), tableOwnerList);
-
-        if (ObjectUtil.isNotEmpty(id)) { //编辑
-            //获取当前试验记录信息中的表状态
-            String sql = "select * from u_trial_self_data_record where record_id = " + id;
-            List<TrialSelfDataRecord> query = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(TrialSelfDataRecord.class));
-
-            for (WbsTreePrivate treePrivate : wbsTreePrivates) {
-                for (TrialSelfDataRecord record : query) {
-                    if (treePrivate.getPKeyId().equals(record.getTabId())) {
-                        treePrivate.setIsBussShow(record.getIsBussShow());
-                        treePrivate.setIsTabPdf(record.getIsTabPdf());
-                        treePrivate.setTabFileType(record.getIsTabFileType());
-                    }
-                }
-            }
-            return wbsTreePrivates;
-        }
-
-        if (isAdd == 1 && ObjectUtil.isEmpty(id)) { //新增时处理按钮显示问题
-            for (WbsTreePrivate treePrivate : wbsTreePrivates) {
-                treePrivate.setPdfUrl(null);
-                treePrivate.setIsBussShow(1);
-                treePrivate.setIsTabPdf(1);
-                treePrivate.setTabFileType(1);
-            }
-        }
-        return wbsTreePrivates;
+        return baseMapper.selectWbsTreeContractList(roleAndTabOwners, tableType, wbsTreePrivate.getProjectId(), wbsTreePrivate.getWbsId(), wbsTreePrivate.getId(), tableOwnerList);
     }
 
     @Override

+ 130 - 191
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeServiceImpl.java

@@ -205,89 +205,90 @@ public class WbsTreeServiceImpl extends BaseServiceImpl<WbsTreeMapper, WbsTree>
             ArrayList<Map<String, String>> result = excelUtil.readExcelToObj(canonicalPath);
             List<Map<String, String>> result2 = WbsExcelBatchUtil.deepCopy(result);
             List<Map<String, String>> maps = WbsExcelBatchUtil.removeRepeatMapByKey(result, "表名");
-            assert maps != null;
-            List<WbsTreeBatchImportDTO> list = new ArrayList<>();
-
-            //初始化
-            wbsTree.setTenantId(wbsTree.getTenantId());
-            wbsTree.setNodeType(1);
-            wbsTree.setWbsId(wbsTree.getWbsId());
-            wbsTree.setParentId(wbsTree.getId());
-            String ancestors = wbsTree.getAncestors() + StringPool.COMMA + wbsTree.getId();
-            wbsTree.setAncestors(ancestors);
-            wbsTree.setType(2);
-            wbsTree.setIsDeleted(BladeConstant.DB_NOT_DELETED);
-            wbsTree.setStatus(1);
-
-            maps.forEach(map -> {
-                String tabName = map.get("表名");
-                wbsTree.setNodeName(tabName);
-                wbsTree.setTableType(WbsElementUtil.getTableType(map.get("表类型")));
-                Long id = SnowFlakeUtil.getId();
-                String initTableName = "m_" + DateUtil.time() + "_" + id;
-                wbsTree.setInitTableName(initTableName);
-                wbsTree.setId(id);
-                if (StringUtils.isEmpty(wbsTree.getFillRate())) {
-                    wbsTree.setFillRate("80%");
-                }
-                //新增表单
-                boolean b = submit3(wbsTree);
+            if (maps != null) {
+                List<WbsTreeBatchImportDTO> list = new ArrayList<>();
+                //初始化
+                wbsTree.setTenantId(wbsTree.getTenantId());
+                wbsTree.setNodeType(1);
+                wbsTree.setWbsId(wbsTree.getWbsId());
+                wbsTree.setParentId(wbsTree.getId());
+                String ancestors = wbsTree.getAncestors() + StringPool.COMMA + wbsTree.getId();
+                wbsTree.setAncestors(ancestors);
+                wbsTree.setType(2);
+                wbsTree.setIsDeleted(BladeConstant.DB_NOT_DELETED);
+                wbsTree.setStatus(1);
+
+                maps.forEach(map -> {
+                    String tabName = map.get("表名");
+                    wbsTree.setNodeName(tabName);
+                    wbsTree.setTableType(WbsElementUtil.getTableType(map.get("表类型")));
+                    Long id = SnowFlakeUtil.getId();
+                    String initTableName = "m_" + DateUtil.time() + "_" + id;
+                    wbsTree.setInitTableName(initTableName);
+                    wbsTree.setId(id);
+                    if (StringUtils.isEmpty(wbsTree.getFillRate())) {
+                        wbsTree.setFillRate("80%");
+                    }
+                    //新增表单
+                    boolean b = submit3(wbsTree);
 
-                if (b) {
-                    //新增实体表
-                    initTable(initTableName);
+                    if (b) {
+                        //新增实体表
+                        initTable(initTableName);
 
-                    WbsTreeBatchImportDTO wbsTreeBatchImportDTO = new WbsTreeBatchImportDTO();
-                    wbsTreeBatchImportDTO.setId(id);
-                    wbsTreeBatchImportDTO.setTableName(tabName);
-                    wbsTreeBatchImportDTO.setInitTableName(initTableName);
-                    list.add(wbsTreeBatchImportDTO);
+                        WbsTreeBatchImportDTO wbsTreeBatchImportDTO = new WbsTreeBatchImportDTO();
+                        wbsTreeBatchImportDTO.setId(id);
+                        wbsTreeBatchImportDTO.setTableName(tabName);
+                        wbsTreeBatchImportDTO.setInitTableName(initTableName);
+                        list.add(wbsTreeBatchImportDTO);
 
-                }
-            });
-
-            //新增元素
-            list.forEach(i -> {
-                Long elementTableId = i.getId();
-                String tableName = i.getTableName();
-                String initTableName = i.getInitTableName();
-                final int[] keyNumb = {0};
-
-                result2.forEach(map -> {
-                    if (tableName.equals(map.get("表名"))) {
-                        keyNumb[0]++;
-                        WbsFormElement wbsFormElement = new WbsFormElement();
-                        wbsFormElement.setEName(map.get("字段名"));
-                        String key = "key_" + keyNumb[0];
-                        wbsFormElement.setEKey(key);
-                        wbsFormElement.setFId(String.valueOf(elementTableId));
-                        wbsFormElement.setELength(WbsElementUtil.getElementLength(map.get("数据类型")));
-                        wbsFormElement.setEType(WbsElementUtil.getElementType(map.get("数据类型")));
-                        wbsFormElement.setEInspectionMethod(map.get("计算公式、方法或数值"));
-                        wbsFormElement.setEAllowDeviation(map.get("允许偏差范围"));
-                        wbsFormElement.setRemark(map.get("备注"));
-
-                        wbsFormElementService.save(wbsFormElement);
-
-                        baseMapper.alterTableFiled(initTableName, wbsFormElement.getEKey(), "varchar", WbsFormElementServiceImpl.DEFAULT_ELEMENT_LENGTH_VARCHAR);
                     }
-
                 });
-            });
-            return true;
 
+                //新增元素
+                list.forEach(i -> {
+                    Long elementTableId = i.getId();
+                    String tableName = i.getTableName();
+                    String initTableName = i.getInitTableName();
+                    final int[] keyNumb = {0};
+
+                    result2.forEach(map -> {
+                        if (tableName.equals(map.get("表名"))) {
+                            keyNumb[0]++;
+                            WbsFormElement wbsFormElement = new WbsFormElement();
+                            wbsFormElement.setEName(map.get("字段名"));
+                            String key = "key_" + keyNumb[0];
+                            wbsFormElement.setEKey(key);
+                            wbsFormElement.setFId(String.valueOf(elementTableId));
+                            wbsFormElement.setELength(WbsElementUtil.getElementLength(map.get("数据类型")));
+                            wbsFormElement.setEType(WbsElementUtil.getElementType(map.get("数据类型")));
+                            wbsFormElement.setEInspectionMethod(map.get("计算公式、方法或数值"));
+                            wbsFormElement.setEAllowDeviation(map.get("允许偏差范围"));
+                            wbsFormElement.setRemark(map.get("备注"));
+
+                            wbsFormElementService.save(wbsFormElement);
+
+                            baseMapper.alterTableFiled(initTableName, wbsFormElement.getEKey(), "varchar", WbsFormElementServiceImpl.DEFAULT_ELEMENT_LENGTH_VARCHAR);
+                        }
+
+                    });
+                });
+                return true;
+            }
         } catch (
                 IOException | ClassNotFoundException e) {
             throw new ServiceException("操作失败,请上传正确模板内容");
         } finally {
-            assert canonicalPath != null;
-            File file2 = new File(canonicalPath);
-            if (file2.isFile() && file2.exists()) {
-                if (file2.delete()) {
-                    System.gc();
+            if (canonicalPath != null){
+                File file2 = new File(canonicalPath);
+                if (file2.isFile() && file2.exists()) {
+                    if (file2.delete()) {
+                        System.gc();
+                    }
                 }
             }
         }
+        return false;
     }
 
     @Override
@@ -326,73 +327,74 @@ public class WbsTreeServiceImpl extends BaseServiceImpl<WbsTreeMapper, WbsTree>
         //获取当前项目引用
         String sql = "select reference_wbs_template_id,reference_wbs_template_type,reference_wbs_template_id_trial,reference_wbs_template_type_trial from m_project_info where id = " + wbsTreePrivate.getProjectId();
         ProjectInfo projectInfo = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(ProjectInfo.class)).stream().findAny().orElse(null);
-        assert projectInfo != null;
-        if (("1").equals(wbsTreePrivate.getWbsType())) {
-            //质检公有
-            if (ObjectUtil.isNotEmpty(projectInfo.getReferenceWbsTemplateId()) && (ObjectUtil.isNotEmpty(projectInfo.getReferenceWbsTemplateType()) && ("public").equals(projectInfo.getReferenceWbsTemplateType()))) {
-                //获取公有树
-                List<WbsTree> wbsTreeListAll = wbsTreeMapper.selectList(Wrappers.<WbsTree>lambdaQuery().eq(WbsTree::getWbsId, projectInfo.getReferenceWbsTemplateId()).eq(WbsTree::getType, 1).eq(WbsTree::getStatus, 1));
-                //获取项目私节点、元素表
-                List<WbsTreePrivate> wbsTreePrivatesAll = wbsTreePrivateMapper.selectList(Wrappers.<WbsTreePrivate>query().lambda().eq(WbsTreePrivate::getWbsId, projectInfo.getReferenceWbsTemplateId()).eq(WbsTreePrivate::getProjectId, wbsTreePrivate.getProjectId()).eq(WbsTreePrivate::getStatus, 1));
-                //同步修改
-                this.updateWbsInfoPrivateAsync(wbsTreeListAll, wbsTreePrivatesAll, wbsTreePrivate.getProjectId(), Integer.parseInt(wbsTreePrivate.getWbsType()));
-
-                //质检私有
-            } else if (ObjectUtil.isNotEmpty(projectInfo.getReferenceWbsTemplateId()) && ObjectUtil.isNotEmpty(projectInfo.getReferenceWbsTemplateType()) && ("private").equals(projectInfo.getReferenceWbsTemplateType())) {
-                //获取私有引用根节点
-                WbsTreePrivate wbsTreePrivateRecord = wbsTreePrivateMapper.selectOne(Wrappers.<WbsTreePrivate>query().lambda()
-                        .select(WbsTreePrivate::getProjectId, WbsTreePrivate::getWbsId)
-                        .eq(WbsTreePrivate::getPKeyId, projectInfo.getReferenceWbsTemplateId()));
-                //获取私有引用项目树
-                List<WbsTreePrivate> wbsTreePrivateAllOld = wbsTreePrivateMapper.selectList(Wrappers.<WbsTreePrivate>query().lambda()
-                        .select(WbsTreePrivate::getId, WbsTreePrivate::getNodeName, WbsTreePrivate::getNodeType, WbsTreePrivate::getMajorDataType, WbsTreePrivate::getTableType, WbsTreePrivate::getTableOwner, WbsTreePrivate::getImportMatchingInfo, WbsTreePrivate::getMixRatioTestIds, WbsTreePrivate::getInitTableId, WbsTreePrivate::getInitTableName, WbsTreePrivate::getHtmlUrl)
-                        .eq(WbsTreePrivate::getStatus, 1)
-                        .eq(WbsTreePrivate::getProjectId, Long.parseLong(wbsTreePrivateRecord.getProjectId()))
-                        .and(obj -> obj.eq(WbsTreePrivate::getWbsId, Long.parseLong(wbsTreePrivateRecord.getWbsId())).or().isNull(WbsTreePrivate::getWbsId))
-                );
-                //获取当前项目私有树、元素表
-                List<WbsTreePrivate> wbsTreePrivatesAllNow = wbsTreePrivateMapper.selectList(Wrappers.<WbsTreePrivate>query().lambda()
-                        .select(WbsTreePrivate::getId, WbsTreePrivate::getNodeName, WbsTreePrivate::getNodeType, WbsTreePrivate::getMajorDataType, WbsTreePrivate::getTableType, WbsTreePrivate::getTableOwner, WbsTreePrivate::getImportMatchingInfo, WbsTreePrivate::getMixRatioTestIds, WbsTreePrivate::getInitTableId, WbsTreePrivate::getInitTableName, WbsTreePrivate::getHtmlUrl)
-                        .eq(WbsTreePrivate::getStatus, 1)
-                        .eq(WbsTreePrivate::getProjectId, Long.parseLong(wbsTreePrivate.getProjectId()))
-                        .and(obj -> obj.eq(WbsTreePrivate::getWbsId, projectInfo.getReferenceWbsTemplateId()).or().isNull(WbsTreePrivate::getWbsId))
-                );
-                //同步修改
-                this.updateWbsInfoContractAsync(wbsTreePrivateAllOld, wbsTreePrivatesAllNow, wbsTreePrivate.getProjectId(), projectInfo.getReferenceWbsTemplateId().toString(), Integer.parseInt(wbsTreePrivate.getWbsType()));
-            }
+        if (projectInfo != null) {
+            if (("1").equals(wbsTreePrivate.getWbsType())) {
+                //质检公有
+                if (ObjectUtil.isNotEmpty(projectInfo.getReferenceWbsTemplateId()) && (ObjectUtil.isNotEmpty(projectInfo.getReferenceWbsTemplateType()) && ("public").equals(projectInfo.getReferenceWbsTemplateType()))) {
+                    //获取公有树
+                    List<WbsTree> wbsTreeListAll = wbsTreeMapper.selectList(Wrappers.<WbsTree>lambdaQuery().eq(WbsTree::getWbsId, projectInfo.getReferenceWbsTemplateId()).eq(WbsTree::getType, 1).eq(WbsTree::getStatus, 1));
+                    //获取项目私节点、元素表
+                    List<WbsTreePrivate> wbsTreePrivatesAll = wbsTreePrivateMapper.selectList(Wrappers.<WbsTreePrivate>query().lambda().eq(WbsTreePrivate::getWbsId, projectInfo.getReferenceWbsTemplateId()).eq(WbsTreePrivate::getProjectId, wbsTreePrivate.getProjectId()).eq(WbsTreePrivate::getStatus, 1));
+                    //同步修改
+                    this.updateWbsInfoPrivateAsync(wbsTreeListAll, wbsTreePrivatesAll, wbsTreePrivate.getProjectId(), Integer.parseInt(wbsTreePrivate.getWbsType()));
+
+                    //质检私有
+                } else if (ObjectUtil.isNotEmpty(projectInfo.getReferenceWbsTemplateId()) && ObjectUtil.isNotEmpty(projectInfo.getReferenceWbsTemplateType()) && ("private").equals(projectInfo.getReferenceWbsTemplateType())) {
+                    //获取私有引用根节点
+                    WbsTreePrivate wbsTreePrivateRecord = wbsTreePrivateMapper.selectOne(Wrappers.<WbsTreePrivate>query().lambda()
+                            .select(WbsTreePrivate::getProjectId, WbsTreePrivate::getWbsId)
+                            .eq(WbsTreePrivate::getPKeyId, projectInfo.getReferenceWbsTemplateId()));
+                    //获取私有引用项目树
+                    List<WbsTreePrivate> wbsTreePrivateAllOld = wbsTreePrivateMapper.selectList(Wrappers.<WbsTreePrivate>query().lambda()
+                            .select(WbsTreePrivate::getId, WbsTreePrivate::getNodeName, WbsTreePrivate::getNodeType, WbsTreePrivate::getMajorDataType, WbsTreePrivate::getTableType, WbsTreePrivate::getTableOwner, WbsTreePrivate::getImportMatchingInfo, WbsTreePrivate::getMixRatioTestIds, WbsTreePrivate::getInitTableId, WbsTreePrivate::getInitTableName, WbsTreePrivate::getHtmlUrl)
+                            .eq(WbsTreePrivate::getStatus, 1)
+                            .eq(WbsTreePrivate::getProjectId, Long.parseLong(wbsTreePrivateRecord.getProjectId()))
+                            .and(obj -> obj.eq(WbsTreePrivate::getWbsId, Long.parseLong(wbsTreePrivateRecord.getWbsId())).or().isNull(WbsTreePrivate::getWbsId))
+                    );
+                    //获取当前项目私有树、元素表
+                    List<WbsTreePrivate> wbsTreePrivatesAllNow = wbsTreePrivateMapper.selectList(Wrappers.<WbsTreePrivate>query().lambda()
+                            .select(WbsTreePrivate::getId, WbsTreePrivate::getNodeName, WbsTreePrivate::getNodeType, WbsTreePrivate::getMajorDataType, WbsTreePrivate::getTableType, WbsTreePrivate::getTableOwner, WbsTreePrivate::getImportMatchingInfo, WbsTreePrivate::getMixRatioTestIds, WbsTreePrivate::getInitTableId, WbsTreePrivate::getInitTableName, WbsTreePrivate::getHtmlUrl)
+                            .eq(WbsTreePrivate::getStatus, 1)
+                            .eq(WbsTreePrivate::getProjectId, Long.parseLong(wbsTreePrivate.getProjectId()))
+                            .and(obj -> obj.eq(WbsTreePrivate::getWbsId, projectInfo.getReferenceWbsTemplateId()).or().isNull(WbsTreePrivate::getWbsId))
+                    );
+                    //同步修改
+                    this.updateWbsInfoContractAsync(wbsTreePrivateAllOld, wbsTreePrivatesAllNow, wbsTreePrivate.getProjectId(), projectInfo.getReferenceWbsTemplateId().toString(), Integer.parseInt(wbsTreePrivate.getWbsType()));
+                }
 
-        } else if (("2").equals(wbsTreePrivate.getWbsType())) {
-            //试验公有
-            if (ObjectUtil.isNotEmpty(projectInfo.getReferenceWbsTemplateIdTrial()) && (ObjectUtil.isNotEmpty(projectInfo.getReferenceWbsTemplateTypeTrial()) && ("public").equals(projectInfo.getReferenceWbsTemplateTypeTrial()))) {
+            } else if (("2").equals(wbsTreePrivate.getWbsType())) {
+                //试验公有
+                if (ObjectUtil.isNotEmpty(projectInfo.getReferenceWbsTemplateIdTrial()) && (ObjectUtil.isNotEmpty(projectInfo.getReferenceWbsTemplateTypeTrial()) && ("public").equals(projectInfo.getReferenceWbsTemplateTypeTrial()))) {
 
-                List<WbsTree> wbsTreeListAll = wbsTreeMapper.selectList(Wrappers.<WbsTree>lambdaQuery().eq(WbsTree::getWbsId, projectInfo.getReferenceWbsTemplateId()).eq(WbsTree::getType, 1).eq(WbsTree::getStatus, 1));
+                    List<WbsTree> wbsTreeListAll = wbsTreeMapper.selectList(Wrappers.<WbsTree>lambdaQuery().eq(WbsTree::getWbsId, projectInfo.getReferenceWbsTemplateId()).eq(WbsTree::getType, 1).eq(WbsTree::getStatus, 1));
 
-                List<WbsTreePrivate> wbsTreePrivatesAll = wbsTreePrivateMapper.selectList(Wrappers.<WbsTreePrivate>query().lambda().eq(WbsTreePrivate::getWbsId, projectInfo.getReferenceWbsTemplateId()).eq(WbsTreePrivate::getProjectId, wbsTreePrivate.getProjectId()).eq(WbsTreePrivate::getStatus, 1));
+                    List<WbsTreePrivate> wbsTreePrivatesAll = wbsTreePrivateMapper.selectList(Wrappers.<WbsTreePrivate>query().lambda().eq(WbsTreePrivate::getWbsId, projectInfo.getReferenceWbsTemplateId()).eq(WbsTreePrivate::getProjectId, wbsTreePrivate.getProjectId()).eq(WbsTreePrivate::getStatus, 1));
 
-                this.updateWbsInfoPrivateAsync(wbsTreeListAll, wbsTreePrivatesAll, wbsTreePrivate.getProjectId(), Integer.parseInt(wbsTreePrivate.getWbsType()));
+                    this.updateWbsInfoPrivateAsync(wbsTreeListAll, wbsTreePrivatesAll, wbsTreePrivate.getProjectId(), Integer.parseInt(wbsTreePrivate.getWbsType()));
 
-                //试验私有
-            } else if (ObjectUtil.isNotEmpty(projectInfo.getReferenceWbsTemplateIdTrial()) && (ObjectUtil.isNotEmpty(projectInfo.getReferenceWbsTemplateTypeTrial()) && ("private").equals(projectInfo.getReferenceWbsTemplateTypeTrial()))) {
+                    //试验私有
+                } else if (ObjectUtil.isNotEmpty(projectInfo.getReferenceWbsTemplateIdTrial()) && (ObjectUtil.isNotEmpty(projectInfo.getReferenceWbsTemplateTypeTrial()) && ("private").equals(projectInfo.getReferenceWbsTemplateTypeTrial()))) {
 
-                WbsTreePrivate wbsTreePrivateRecord = wbsTreePrivateMapper.selectOne(Wrappers.<WbsTreePrivate>query().lambda()
-                        .select(WbsTreePrivate::getProjectId, WbsTreePrivate::getWbsId)
-                        .eq(WbsTreePrivate::getPKeyId, projectInfo.getReferenceWbsTemplateIdTrial()));
+                    WbsTreePrivate wbsTreePrivateRecord = wbsTreePrivateMapper.selectOne(Wrappers.<WbsTreePrivate>query().lambda()
+                            .select(WbsTreePrivate::getProjectId, WbsTreePrivate::getWbsId)
+                            .eq(WbsTreePrivate::getPKeyId, projectInfo.getReferenceWbsTemplateIdTrial()));
 
-                List<WbsTreePrivate> wbsTreePrivateAllOld = wbsTreePrivateMapper.selectList(Wrappers.<WbsTreePrivate>query().lambda()
-                        .select(WbsTreePrivate::getId, WbsTreePrivate::getNodeName, WbsTreePrivate::getNodeType, WbsTreePrivate::getMajorDataType, WbsTreePrivate::getTableType, WbsTreePrivate::getTableOwner, WbsTreePrivate::getImportMatchingInfo, WbsTreePrivate::getMixRatioTestIds, WbsTreePrivate::getInitTableId, WbsTreePrivate::getInitTableName, WbsTreePrivate::getHtmlUrl)
-                        .eq(WbsTreePrivate::getStatus, 1)
-                        .eq(WbsTreePrivate::getProjectId, Long.parseLong(wbsTreePrivate.getProjectId()))
-                        .and(obj -> obj.eq(WbsTreePrivate::getWbsId, Long.parseLong(wbsTreePrivateRecord.getWbsId())).or().isNull(WbsTreePrivate::getWbsId))
-                );
+                    List<WbsTreePrivate> wbsTreePrivateAllOld = wbsTreePrivateMapper.selectList(Wrappers.<WbsTreePrivate>query().lambda()
+                            .select(WbsTreePrivate::getId, WbsTreePrivate::getNodeName, WbsTreePrivate::getNodeType, WbsTreePrivate::getMajorDataType, WbsTreePrivate::getTableType, WbsTreePrivate::getTableOwner, WbsTreePrivate::getImportMatchingInfo, WbsTreePrivate::getMixRatioTestIds, WbsTreePrivate::getInitTableId, WbsTreePrivate::getInitTableName, WbsTreePrivate::getHtmlUrl)
+                            .eq(WbsTreePrivate::getStatus, 1)
+                            .eq(WbsTreePrivate::getProjectId, Long.parseLong(wbsTreePrivate.getProjectId()))
+                            .and(obj -> obj.eq(WbsTreePrivate::getWbsId, Long.parseLong(wbsTreePrivateRecord.getWbsId())).or().isNull(WbsTreePrivate::getWbsId))
+                    );
 
-                List<WbsTreePrivate> wbsTreePrivatesAllNow = wbsTreePrivateMapper.selectList(Wrappers.<WbsTreePrivate>query().lambda()
-                        .select(WbsTreePrivate::getId, WbsTreePrivate::getNodeName, WbsTreePrivate::getNodeType, WbsTreePrivate::getMajorDataType, WbsTreePrivate::getTableType, WbsTreePrivate::getTableOwner, WbsTreePrivate::getImportMatchingInfo, WbsTreePrivate::getMixRatioTestIds, WbsTreePrivate::getInitTableId, WbsTreePrivate::getInitTableName, WbsTreePrivate::getHtmlUrl)
-                        .eq(WbsTreePrivate::getStatus, 1)
-                        .eq(WbsTreePrivate::getProjectId, Long.parseLong(wbsTreePrivate.getProjectId()))
-                        .and(obj -> obj.eq(WbsTreePrivate::getWbsId, projectInfo.getReferenceWbsTemplateIdTrial()).or().isNull(WbsTreePrivate::getWbsId))
-                );
+                    List<WbsTreePrivate> wbsTreePrivatesAllNow = wbsTreePrivateMapper.selectList(Wrappers.<WbsTreePrivate>query().lambda()
+                            .select(WbsTreePrivate::getId, WbsTreePrivate::getNodeName, WbsTreePrivate::getNodeType, WbsTreePrivate::getMajorDataType, WbsTreePrivate::getTableType, WbsTreePrivate::getTableOwner, WbsTreePrivate::getImportMatchingInfo, WbsTreePrivate::getMixRatioTestIds, WbsTreePrivate::getInitTableId, WbsTreePrivate::getInitTableName, WbsTreePrivate::getHtmlUrl)
+                            .eq(WbsTreePrivate::getStatus, 1)
+                            .eq(WbsTreePrivate::getProjectId, Long.parseLong(wbsTreePrivate.getProjectId()))
+                            .and(obj -> obj.eq(WbsTreePrivate::getWbsId, projectInfo.getReferenceWbsTemplateIdTrial()).or().isNull(WbsTreePrivate::getWbsId))
+                    );
 
-                this.updateWbsInfoContractAsync(wbsTreePrivateAllOld, wbsTreePrivatesAllNow, wbsTreePrivate.getProjectId(), projectInfo.getReferenceWbsTemplateIdTrial().toString(), Integer.parseInt(wbsTreePrivate.getWbsType()));
+                    this.updateWbsInfoContractAsync(wbsTreePrivateAllOld, wbsTreePrivatesAllNow, wbsTreePrivate.getProjectId(), projectInfo.getReferenceWbsTemplateIdTrial().toString(), Integer.parseInt(wbsTreePrivate.getWbsType()));
+                }
             }
         }
         return true;
@@ -919,69 +921,6 @@ public class WbsTreeServiceImpl extends BaseServiceImpl<WbsTreeMapper, WbsTree>
         }
     }
 
-    @Async
-    public boolean insertTextDictInfoAsync(List<WbsTreePrivate> wbsTreePrivateOldTables, List<WbsTreePrivate> wbsTreePrivateNewTables) {
-        //wbsTreePrivateOldTables=原始引用的元素表+独立表 wbsTreePrivateNewTables=现在项目树的元素表+独立表
-        Map<Long, List<TextdictInfo>> textDictInfoData = new HashMap<>();
-        if (wbsTreePrivateOldTables.size() > 0) {
-            //只同步了独立库的元素表电签信息,type=2以前的节点下同步形式,现在type=10为独立库
-            List<Long> pIdsDL = wbsTreePrivateOldTables.stream().filter(f -> f.getType().equals(10) || f.getType().equals(2)).collect(Collectors.toList()).stream().map(WbsTreePrivate::getPKeyId).collect(Collectors.toList());
-            String ids = StringUtils.join(pIdsDL, ",");
-            String sql = "select `id`,`name`,`type`,tab_id,col_key,sig_role_id,is_deleted,sig_role_name,col_name,pyzbx,pyzby from m_textdict_info where tab_id in (" + ids + ") and is_deleted = 0";
-            List<TextdictInfo> textDictInfos = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(TextdictInfo.class));
-
-            for (WbsTreePrivate wbsTreePrivate : wbsTreePrivateOldTables) {
-                //私有引用-电签匹配数据、默认信息数据,根据元素表pKeyId,获取电签位置匹配信息、编辑默认信息
-                List<TextdictInfo> collect = textDictInfos.stream().filter(f -> f.getTabId().equals(String.valueOf(wbsTreePrivate.getPKeyId()))).collect(Collectors.toList());
-                if (collect.size() > 0) {
-                    textDictInfoData.put(wbsTreePrivate.getId(), collect);
-                }
-            }
-        }
-
-        if (textDictInfoData.size() > 0) {
-            //同步电签配置信息 构造电签位置配置信息、编辑默认信息数据
-            List<TextdictInfo> insertData = new ArrayList<>();
-            for (WbsTreePrivate wbsTreePrivateNewTable : wbsTreePrivateNewTables) {
-                textDictInfoData.forEach((k, v) -> {
-                    if (wbsTreePrivateNewTable.getId().equals(k)) {
-                        for (TextdictInfo textdictInfo : v) {
-                            TextdictInfo obj = BeanUtil.copyProperties(textdictInfo, TextdictInfo.class);
-                            assert obj != null;
-                            obj.setTabId(String.valueOf(wbsTreePrivateNewTable.getPKeyId()));
-                            obj.setId(SnowFlakeUtil.getId());
-                            insertData.add(obj);
-                        }
-                    }
-                });
-            }
-
-            //判断是否存在
-            List<Long> pIdsDLNew = wbsTreePrivateNewTables.stream().filter(f -> f.getType().equals(10) || f.getType().equals(2)).collect(Collectors.toList()).stream().map(WbsTreePrivate::getPKeyId).collect(Collectors.toList());
-            String ids = StringUtils.join(pIdsDLNew, ",");
-            String sql = "select `id`,`name`,`type`,tab_id,col_key,sig_role_id,is_deleted,sig_role_name,col_name,pyzbx,pyzby from m_textdict_info where tab_id in (" + ids + ") and is_deleted = 0";
-            List<TextdictInfo> textDictInfosNew = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(TextdictInfo.class));
-
-            Iterator<TextdictInfo> iterator = insertData.iterator();
-            while (iterator.hasNext()) {
-                TextdictInfo textDictInfo = iterator.next();
-                textDictInfosNew.stream().filter(f ->
-                        //判断每张表TabId的每个位置ColKey、类型Type唯一
-                        f.getColKey().equals(textDictInfo.getColKey())
-                                && f.getType().equals(textDictInfo.getType())
-                                && f.getTabId().equals(textDictInfo.getTabId())
-                ).findAny().ifPresent(textDict -> iterator.remove());
-            }
-
-            if (insertData.size() > 0) {
-                textDictInfoService.insertBatch(insertData, 1000);
-            }
-
-            return true;
-        }
-        return false;
-    }
-
     @Override
     public WbsTreeAllListVO findWbsTreeList(Integer type) {
         WbsTreeAllListVO wbsTreeAllListVO = new WbsTreeAllListVO();