Prechádzať zdrojové kódy

Merge remote-tracking branch 'origin/test-merge' into test-merge

LHB 1 mesiac pred
rodič
commit
701176329c
100 zmenil súbory, kde vykonal 2329 pridanie a 761 odobranie
  1. 3 0
      blade-gateway/src/main/java/org/springblade/gateway/provider/AuthProvider.java
  2. 0 6
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/dto/TrialSystemDockingDTO.java
  3. 2 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/Task.java
  4. 0 5
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/TrialSystemDocking.java
  5. 3 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/BusinessTaskPageVO.java
  6. 17 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/WbsInfoDTO.java
  7. 6 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/ContractInfo.java
  8. 16 1
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/ProjectInfo.java
  9. 3 3
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/TextdictInfo.java
  10. 83 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/UserProjectInfoCollect.java
  11. 13 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/WbsInfo.java
  12. 1 1
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/feign/ExcelTabClient.java
  13. 2 2
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/feign/TableFileClient.java
  14. 2 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/feign/WbsParamClient.java
  15. 122 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/util/DataStructureFormatUtils.java
  16. 6 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/ContractInfoVO.java
  17. 3 1
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/ExceTabTreVO.java
  18. 19 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/ExcelTabVO.java
  19. 1 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/ExcelTabVo1.java
  20. 17 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/ProjectInfoVO.java
  21. 33 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/ProjectInfoVO3.java
  22. 4 1
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/TextdictInfoVO.java
  23. 6 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/TreeNodeVO.java
  24. 1 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/WbsNodeTableVO.java
  25. 39 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/WbsTreePrivateQueryVO.java
  26. 34 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/WbsTreePrivateTableVO.java
  27. 4 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/WbsTreePrivateVO.java
  28. 1 1
      blade-service/blade-archive/pom.xml
  29. 1 3
      blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchiveFileController.java
  30. 32 6
      blade-service/blade-business/src/main/java/org/springblade/business/controller/InformationWriteQueryController.java
  31. 2 2
      blade-service/blade-business/src/main/java/org/springblade/business/controller/MessageWarningController.java
  32. 19 2
      blade-service/blade-business/src/main/java/org/springblade/business/controller/RecycleBinController.java
  33. 2 2
      blade-service/blade-business/src/main/java/org/springblade/business/controller/StandardInfoController.java
  34. 28 7
      blade-service/blade-business/src/main/java/org/springblade/business/controller/TaskController.java
  35. 2 0
      blade-service/blade-business/src/main/java/org/springblade/business/controller/TrialDetectionController.java
  36. 2 0
      blade-service/blade-business/src/main/java/org/springblade/business/controller/TrialMaterialController.java
  37. 1 1
      blade-service/blade-business/src/main/java/org/springblade/business/controller/TrialSystemDockingController.java
  38. 28 6
      blade-service/blade-business/src/main/java/org/springblade/business/controller/UserViewProjectContractController.java
  39. 53 50
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/ImageClassificationFileMapper.xml
  40. 1 1
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/InformationQueryMapper.xml
  41. 1 1
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/StandardInfoMapper.java
  42. 5 4
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/StandardInfoMapper.xml
  43. 2 2
      blade-service/blade-business/src/main/java/org/springblade/business/scheduled/ChenYuTestScheduled.java
  44. 1 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/ITrialSelfInspectionRecordService.java
  45. 2 1
      blade-service/blade-business/src/main/java/org/springblade/business/service/StandardInfoService.java
  46. 3 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/InformationQueryServiceImpl.java
  47. 15 5
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TaskServiceImpl.java
  48. 22 1
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TrialMaterialMobilizationServiceImpl.java
  49. 1 2
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TrialSelfInspectionRecordServiceImpl.java
  50. 5 7
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TrialSystemDockingServiceImpl.java
  51. 2 2
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/UStandardInfoServiceImpl.java
  52. 3 3
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/WeatherInfoServiceImpl.java
  53. 11 1
      blade-service/blade-business/src/main/java/org/springblade/business/utils/PDFUtil.java
  54. 1 1
      blade-service/blade-e-visa/pom.xml
  55. 49 9
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/service/impl/EVDataServiceImpl.java
  56. 3 3
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/service/impl/EVisaServiceImpl.java
  57. 41 18
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/utils/PDFUtils.java
  58. 57 3
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ContractInfoController.java
  59. 44 11
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ExcelTabController.java
  60. 3 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/FirstController.java
  61. 110 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ProjectInfoController.java
  62. 249 57
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/TextdictInfoController.java
  63. 40 2
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/WbsInfoController.java
  64. 2 2
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/WbsTreeController.java
  65. 67 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/WbsTreePrivateController.java
  66. 2 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/feign/ExcelTabClientImpl.java
  67. 2 2
      blade-service/blade-manager/src/main/java/org/springblade/manager/feign/TableFileClientImpl.java
  68. 5 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/feign/WbsParamClientImpl.java
  69. 3 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/feign/WbsTreeContractClientImpl.java
  70. 2 2
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/ArchiveTreeContractMapper.xml
  71. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/ContractInfoMapper.xml
  72. 5 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/ExcelTabMapper.java
  73. 35 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/ExcelTabMapper.xml
  74. 2 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/ProjectInfoMapper.java
  75. 38 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/ProjectInfoMapper.xml
  76. 13 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/TextdictInfoMapper.java
  77. 15 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/TextdictInfoMapper.xml
  78. 12 2
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsFormElementMapper.xml
  79. 3 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsInfoMapper.java
  80. 2 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsInfoMapper.xml
  81. 7 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsTreePrivateMapper.xml
  82. 3 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/IExcelTabService.java
  83. 1 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/IProjectInfoService.java
  84. 2 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/ISignConfigService.java
  85. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/IWbsInfoService.java
  86. 2 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/IWbsTreeContractService.java
  87. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/IWbsTreeService.java
  88. 431 223
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ExcelTabServiceImpl.java
  89. 147 45
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormulaServiceImpl.java
  90. 31 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ProjectInfoServiceImpl.java
  91. 3 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ServicePlanServiceImpl.java
  92. 4 4
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/SignConfigServiceImpl.java
  93. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/TableInfoServiceImpl.java
  94. 28 46
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/TextdictInfoServiceImpl.java
  95. 91 155
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsFormElementServiceImpl.java
  96. 59 3
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsInfoServiceImpl.java
  97. 8 2
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeContractServiceImpl.java
  98. 0 15
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreePrivateServiceImpl.java
  99. 16 14
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeServiceImpl.java
  100. 2 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeSynchronousRecordServiceImpl.java

+ 3 - 0
blade-gateway/src/main/java/org/springblade/gateway/provider/AuthProvider.java

@@ -66,6 +66,9 @@ public class AuthProvider {
         DEFAULT_SKIP_URL.add("/getPk"); //成渝第三方登录获取公钥
         DEFAULT_SKIP_URL.add("/getQualityTestingToken"); //成渝第三方登录获取质检系统tokne
         DEFAULT_SKIP_URL.add("/getArchiveToken"); //成渝第三方登录获取档案系统tokne
+        DEFAULT_SKIP_URL.add("/trialclassificationtree/**"); //德飞第三方登录获取质检系统tokne
+        DEFAULT_SKIP_URL.add("/trialsystemdocking/**"); //德飞第三方登录获取档案系统tokne
+
     }
 
     /**

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

@@ -31,12 +31,6 @@ import javax.validation.constraints.NotNull;
 @Data
 public class TrialSystemDockingDTO {
 	private static final long serialVersionUID = 1L;
-
-	/**
-	 * 德飞数据ID
-	 */
-	private Long dataId;
-
 	/**
 	 * 项目Id
 	 */

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

@@ -178,4 +178,6 @@ public class Task extends BaseEntity {
     @ApiModelProperty("计量任务是否生成审计意见单 1是0否")
     private Integer isBuildAudit;
 
+    @ApiModelProperty("电签状态")
+    private Integer eStatus;
 }

+ 0 - 5
blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/TrialSystemDocking.java

@@ -38,11 +38,6 @@ public class TrialSystemDocking extends BaseEntity {
 	* 主键
 	*/
 	private Long id;
-	/**
-	 * 德飞ID
-	 */
-	private Long dataId;
-
 	/**
 	 * 项目Id
 	 */

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

@@ -58,4 +58,7 @@ public class BusinessTaskPageVO implements Serializable {
     @ApiModelProperty(value = "签字人员集合")
     private List<TaskParallel> taskApproveUserNamesList;
 
+    @ApiModelProperty("电签状态,用来判断是否同意过")
+    private Integer eStatus;
+
 }

+ 17 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/WbsInfoDTO.java

@@ -4,8 +4,11 @@ import io.swagger.annotations.ApiModelProperty;
 import io.swagger.models.auth.In;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
+import org.springblade.manager.entity.ProjectInfo;
 import org.springblade.manager.entity.WbsInfo;
 
+import java.util.List;
+
 @Data
 @EqualsAndHashCode(callSuper = true)
 public class WbsInfoDTO extends WbsInfo {
@@ -27,5 +30,19 @@ public class WbsInfoDTO extends WbsInfo {
      */
     private Integer status;
 
+    /**
+     * 项目名称
+     */
+    @ApiModelProperty(value = "项目名称")
+    private String projectName;
+
+    /**
+     * 项目名称
+     */
+    @ApiModelProperty(value = "项目名称")
+    private String projectId;
+
+    List<ProjectInfo> projectInfoList;
+
 
 }

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

@@ -181,6 +181,12 @@ public class ContractInfo extends BaseEntity {
     @ApiModelProperty(value = "卷盒规格")
     private String specification;
 
+    /**
+     * 排序
+     */
+    @ApiModelProperty(value = "排序")
+    private Integer sort;
+
     public BigDecimal getProjectMileage() {
         if (projectMileage == null){
             return null;

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

@@ -215,5 +215,20 @@ public class ProjectInfo extends BaseEntity {
      *
      */
     @ApiModelProperty(value = "短信时间")
-    private int msTime;
+    private Double msTime;
+    /**
+     * 项目状态
+     */
+    @ApiModelProperty(value = "项目状态, 0:未开始, 1:配置中, 2: 进行中, 3: 已完成")
+    private Integer projectStatus;
+    /**
+     * 项目排序
+     */
+    @ApiModelProperty(value = "项目排序")
+    private Integer sort;
+    /**
+     * 项目负责人
+     */
+    @ApiModelProperty(value = "项目负责人")
+    private Long projectLeader;
 }

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

@@ -85,12 +85,12 @@ public class TextdictInfo implements Serializable {
     /**
      * 偏移坐标X
      */
-    private double pyzbx;
+    private Double pyzbx;
 
     /**
      * 偏移坐标Y
      */
-    private double pyzby;
+    private Double pyzby;
 
     /**
      * excelId
@@ -120,5 +120,5 @@ public class TextdictInfo implements Serializable {
     /**
      * 是否需要时间 1需要 0不需要
      */
-    private int timeState;
+    private Integer timeState;
 }

+ 83 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/UserProjectInfoCollect.java

@@ -0,0 +1,83 @@
+package org.springblade.manager.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springblade.core.mp.base.BaseEntity;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.util.Date;
+
+@Data
+@TableName("m_user_project_collect")
+public class UserProjectInfoCollect implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "主键id")
+    @JsonProperty(value = "id")
+    @TableId(type = IdType.ASSIGN_ID)
+    private Long id;
+
+    /**
+     * 项目Id
+     */
+    @JsonProperty(value = "projectId")
+    @ApiModelProperty(name = "projectId", value = "项目Id", required = true)
+    private Long projectId;
+
+    @ApiModelProperty("排序")
+    private Integer sort;
+
+    /**
+     * 用户id
+     */
+    @JsonProperty(value = "userId")
+    @ApiModelProperty(name = "userId", value = "用户id", required = true)
+    private Long userId;
+
+
+    @JsonProperty(value = "createUser")
+    @ApiModelProperty(name = "createUser", value = "创建人", required = true)
+    private Long createUser;
+
+    @JsonProperty(value = "updateUser")
+    @ApiModelProperty(name = "updateUser", value = "更新人", required = true)
+    private Long updateUser;
+
+    @DateTimeFormat(
+            pattern = "yyyy-MM-dd HH:mm:ss"
+    )
+    @JsonFormat(
+            pattern = "yyyy-MM-dd HH:mm:ss"
+    )
+    @ApiModelProperty("创建时间")
+    private Date createTime;
+
+
+
+    @DateTimeFormat(
+            pattern = "yyyy-MM-dd HH:mm:ss"
+    )
+    @JsonFormat(
+            pattern = "yyyy-MM-dd HH:mm:ss"
+    )
+
+    @ApiModelProperty("更新时间")
+    private Date updateTime = new Date();
+
+    @ApiModelProperty("状态")
+    private Integer status = 1;
+
+    @TableLogic
+    @ApiModelProperty("是否已删除")
+    private Integer isDeleted = 0;
+}

+ 13 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/WbsInfo.java

@@ -1,10 +1,13 @@
 package org.springblade.manager.entity;
 
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableName;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import org.springblade.core.mp.base.BaseEntity;
 
+import java.util.List;
+
 @Data
 @TableName("m_wbs_info")
 @EqualsAndHashCode(callSuper = true)
@@ -21,5 +24,15 @@ public class WbsInfo extends BaseEntity {
      */
     private Integer wbsType;
 
+    /**
+     * 排序
+     */
+    private Integer sort;
+
+    /**
+     * 项目列表
+     */
+    @TableField(exist = false)
+    private List<ProjectInfo> projectInfoList;
 
 }

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

@@ -95,7 +95,7 @@ public interface ExcelTabClient {
     void excelInfo(@RequestPart("file") MultipartFile file, @RequestParam String exceUrl, @RequestParam String thmlUrl, @RequestParam String number) throws IOException;
 
     @PostMapping(API_PREFIX + "/saveLinkTab")
-    void saveLinkTab(@RequestParam Long excelId,@RequestParam Long pKeyId) throws IOException;
+    void saveLinkTab(@RequestParam Long excelId,@RequestParam Long pKeyId) throws Exception;
 
     @PostMapping(API_PREFIX + "/getTheLogPdInfo")
     void getTheLogPdInfo(@RequestParam String logPkeyId,  @RequestParam String nodePrimaryKeyId, @RequestParam String recordTime, @RequestParam String contractId,@RequestParam Long createUser) throws Exception;

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

@@ -29,7 +29,7 @@ public interface TableFileClient {
     @PostMapping(API_PREFIX + "/saveBatch")
     boolean saveBatch(@RequestBody List<TableFile> newFiles);
 
-    @GetMapping(API_PREFIX + "/getTabFilesByTabIds")
-    List<TableFile> getTabFilesByTabIds(@RequestParam String tabFileIds);
+    @PostMapping(API_PREFIX + "/getTabFilesByTabIds")
+    List<TableFile> getTabFilesByTabIds(@RequestBody List<String> tabFileIds);
 
 }

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

@@ -27,6 +27,8 @@ public interface WbsParamClient {
     @GetMapping(API_PREFIX + "/getWbsParam")
     WbsParam getWbsParam(@RequestParam Long nodeId);
 
+    @PostMapping(API_PREFIX + "/saveWbsParams")
+    void saveWbsParams(@RequestBody List<WbsParam> wbsParamList);
     @PostMapping(API_PREFIX + "/createFileTitle")
     String createFileTitle(@RequestBody WbsTreeContract contract);
     @PostMapping(API_PREFIX + "/getNameRuleByPkeyId")

+ 122 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/util/DataStructureFormatUtils.java

@@ -0,0 +1,122 @@
+package org.springblade.manager.util;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * key:value$$key:value$$key:value
+ * 简单数据结构转换工具类
+ */
+public class DataStructureFormatUtils {
+
+    /**
+     * 将Map转换为自定义字符串格式
+     * @param map 输入的键值对映射
+     * @return 格式化后的字符串
+     */
+    public static String buildData(Map<String, String> map) {
+        if (map == null || map.isEmpty()) {
+            return "";
+        }
+        StringBuilder sb = new StringBuilder();
+        for (Map.Entry<String, String> entry : map.entrySet()) {
+            // 转义特殊字符以避免解析错误
+            String key = escapeSpecialChars(entry.getKey());
+            String value = escapeSpecialChars(entry.getValue());
+            sb.append(key).append(":").append(value).append("$$");
+        }
+        // 移除最后的分隔符
+        if (sb.length() > 0) {
+            sb.setLength(sb.length() - 2);
+        }
+        return sb.toString();
+    }
+
+    public static String buildDataObject(Map<String, Object> map) {
+        if (map == null || map.isEmpty()) {
+            return "";
+        }
+        StringBuilder sb = new StringBuilder();
+        for (Map.Entry<String, Object> entry : map.entrySet()) {
+            // 转义特殊字符以避免解析错误
+            String key = escapeSpecialChars(entry.getKey());
+            String value = escapeSpecialChars(entry.getValue() + "");
+            sb.append(key).append(":").append(value).append("$$");
+        }
+        // 移除最后的分隔符
+        if (sb.length() > 0) {
+            sb.setLength(sb.length() - 2);
+        }
+        return sb.toString();
+    }
+    
+    /**
+     * 将自定义字符串格式解析为Map
+     * @param dataStr 格式化字符串
+     * @return 键值对映射
+     */
+    public static Map<String, String> parseDataByKey(String dataStr) {
+        Map<String, String> map = new HashMap<>();
+        if (dataStr == null || dataStr.isEmpty()) {
+            return map;
+        }
+        String[] pairs = dataStr.split("\\$\\$");
+        if (pairs.length == 1 && !pairs[0].contains(":")) {
+            map.put("key_201", pairs[0]);
+            return map;
+        }
+        for (String pair : pairs) {
+            int index = pair.indexOf(':');
+            if (index > 0) {
+                String key = unescapeSpecialChars(pair.substring(0, index));
+                String value = unescapeSpecialChars(pair.substring(index + 1));
+                map.put(key, value);
+            }
+        }
+        return map;
+    }
+
+
+    /**
+     * 解析Map中 key_201 的自定义字符串格式,添加到Map中,并移除原有的key_201
+     * @param map 输入的键值对映射
+     * @return 键值对映射
+     */
+    public static void parseDataByKey(Map<String, Object> map) {
+        if (map == null || map.isEmpty() || !map.containsKey("key_201")) {
+            return ;
+        }
+        Object obj = map.get("key_201");
+        if (obj instanceof String) {
+            Map<String, String> map1 = parseDataByKey((String) obj);
+            map.remove("key_201");
+            map.putAll(map1);
+        }
+    }
+
+    public static void parseDataByKey(List<Map<String, Object>> map) {
+        if (map == null || map.isEmpty()) {
+            return ;
+        }
+        for (Map<String, Object> map1 : map) {
+            parseDataByKey(map1);
+        }
+    }
+    
+    /**
+     * 转义特殊字符
+     */
+    private static String escapeSpecialChars(String str) {
+        if (str == null) return null;
+        return str.replace("\\", "\\\\").replace(":", "\\:").replace("$$", "\\$\\$");
+    }
+    
+    /**
+     * 恢复转义的字符
+     */
+    private static String unescapeSpecialChars(String str) {
+        if (str == null) return null;
+        return str.replace("\\$\\$", "$$").replace("\\:", ":").replace("\\\\", "\\");
+    }
+}

+ 6 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/ContractInfoVO.java

@@ -40,5 +40,11 @@ public class ContractInfoVO extends ContractInfo {
     @ApiModelProperty("计量合同段-关联详情信息")
     private MeterContractInfo meterContractInfo;
 
+    /**
+     * 关联合同段
+     */
+    @ApiModelProperty("关联合同段")
+    private List<ContractInfo> relationContractInfo;
+
 
 }

+ 3 - 1
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/ExceTabTreVO.java

@@ -51,6 +51,9 @@ public class ExceTabTreVO extends ExcelTab implements INode<ExceTabTreVO> {
     @JsonSerialize(using = ToStringSerializer.class)
     private Long parentId;
 
+
+    private Integer tableOwner;
+
     /**
      * 子孙节点
      */
@@ -63,7 +66,6 @@ public class ExceTabTreVO extends ExcelTab implements INode<ExceTabTreVO> {
     @JsonInclude(JsonInclude.Include.NON_EMPTY)
     private Boolean hasChildren;
 
-    private Integer tableOwner;
 
     @Override
     public List<ExceTabTreVO> getChildren() {

+ 19 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/ExcelTabVO.java

@@ -20,6 +20,9 @@ import io.swagger.annotations.ApiModelProperty;
 import org.springblade.manager.entity.ExcelTab;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
+import org.springblade.manager.entity.ProjectInfo;
+
+import java.util.List;
 
 /**
  * 清表基础数据表视图实体类
@@ -35,4 +38,20 @@ public class ExcelTabVO extends ExcelTab {
     @ApiModelProperty(value = "清表模板类型名称")
     private String tableTemplateTypeName;
 
+    @ApiModelProperty(value = "项目id")
+    private Long projectId;
+
+    @ApiModelProperty(value = "项目名称")
+    private String projectName;
+
+    List<ProjectInfoVO1> projectInfoList;
+
+    @ApiModelProperty(value = "项目使用数量")
+    private Integer projectUseNumber;
+
+    @ApiModelProperty(value = "清表使用数量")
+    private Integer excelUseNumber;
+
+    @ApiModelProperty(value = "创建人名称")
+    private String createUserName;
 }

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

@@ -9,4 +9,5 @@ public class ExcelTabVo1 {
     private String htmlUrl;
     private String name;
     private String fileUrl;
+    private String tabName;
 }

+ 17 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/ProjectInfoVO.java

@@ -38,4 +38,21 @@ public class ProjectInfoVO extends ProjectInfo {
     @ApiModelProperty(value = "wbsType")
     private Integer wbsType;
 
+    /**
+     * 项目负责人
+     */
+    @ApiModelProperty(value = "项目负责人姓名")
+    private String projectLeaderName;
+
+    /**
+     * 是否收藏
+     */
+    @ApiModelProperty(value = "是否收藏 0 否, 1 是")
+    private Integer isCollect;
+
+    /**
+     * wbs 类型
+     */
+    @ApiModelProperty(value = "wbs 类型")
+    private List<Integer> wbsTypes;
 }

+ 33 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/ProjectInfoVO3.java

@@ -1,5 +1,38 @@
 package org.springblade.manager.vo;
 
+import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
+import org.springblade.manager.entity.ProjectInfo;
+import java.io.Serializable;
+@Data
+public class ProjectInfoVO3 implements Serializable {
+    private static final long serialVersionUID = 1L;
 
+    /**
+     * 项目名称、别名
+     */
+    @ApiModelProperty(value = "项目名称、别名")
+    private String name;
+    /**
+     * 项目状态, 0:未开始, 1:配置中, 2: 进行中, 3: 已完成, null: 全部
+     */
+    @ApiModelProperty(value = "项目状态, 0:未开始, 1:配置中, 2: 进行中, 3: 已完成, null: 全部。 默认值:null")
+    private Integer status;
+    /**
+     * 排序方式,0:默认排序, 1:收藏优先, 2:创建时间, 3:我负责的
+     */
+    @ApiModelProperty(value = "排序方式,0:默认排序, 1:收藏优先, 2:创建时间, 3:我负责的。默认值:0")
+    private Integer sort = 0;
+    /**
+     * 是否收藏,0:全部, 1:收藏
+     */
+    @ApiModelProperty(value = "是否收藏,0:全部, 1:收藏。 默认值:1")
+    private Integer isCollect = 1;
+    /**
+     * 用户id
+     */
+    @ApiModelProperty(value = "用户id, 可以不传值")
+    private Long userId;
+
+}
 

+ 4 - 1
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/TextdictInfoVO.java

@@ -36,6 +36,9 @@ public class TextdictInfoVO extends TextdictInfo {
     //1.电签配置 2.系统识别
     private Integer showType;
 
-    @ApiModelProperty("是否引用系统级电签配置,1 系统级,0 项目级")
+    @ApiModelProperty("本表配置 绿色0,电签库 蓝色1,项目匹配 橙色2")
     private Integer isSystem = 0;
+
+    @ApiModelProperty("元素是否匹配, 1:匹配, 0:不匹配")
+    private Integer isMatch = 1;
 }

+ 6 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/TreeNodeVO.java

@@ -6,6 +6,8 @@ import lombok.Data;
 import org.springblade.core.tool.node.BaseNode;
 import org.springblade.core.tool.node.TreeNode;
 
+import java.util.Date;
+
 @Data
 public class TreeNodeVO extends BaseNode<TreeNode> {
     private static final long serialVersionUID = 1L;
@@ -55,6 +57,10 @@ public class TreeNodeVO extends BaseNode<TreeNode> {
 
     private String erTreeId;
 
+    private Long updateUser;
+    private Date updateTime;
+    private String updateUserName;
+
     public TreeNodeVO() {
     }
 

+ 1 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/WbsNodeTableVO.java

@@ -92,5 +92,6 @@ public class WbsNodeTableVO implements Serializable {
     private String htmlUrl;
 
     private String nodeType;
+    private Integer wbsType;
 
 }

+ 39 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/WbsTreePrivateQueryVO.java

@@ -0,0 +1,39 @@
+package org.springblade.manager.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+
+@Data
+public class WbsTreePrivateQueryVO {
+
+    @ApiModelProperty(value = "wbs Id", required = true)
+    @NotBlank(message = "wbsId不能为空")
+    private String wbsId;
+
+    @ApiModelProperty(value = "项目id", required = true)
+    @NotBlank(message = "projectId不能为空")
+    private String projectId;
+
+    @ApiModelProperty("搜索内容")
+    private String queryValue;
+
+    @ApiModelProperty("节点类型")
+    private Integer nodeType;
+
+    @ApiModelProperty("内业资料类型")
+    private Integer majorDataType;
+
+    @ApiModelProperty("标准分类")
+    private Integer className;
+
+    @ApiModelProperty(value = "单元名称")
+    private Integer unitName;
+
+    @ApiModelProperty(value = "是否在客户端新增时隐藏,0否1是")
+    private Integer isAddConceal;
+
+    @ApiModelProperty("参数掩码")
+    private String uniqueCode;
+}

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

@@ -0,0 +1,34 @@
+package org.springblade.manager.vo;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springblade.core.tool.node.INode;
+import org.springblade.manager.entity.WbsTree;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+@Data
+public class WbsTreePrivateTableVO  implements Serializable {
+    private static final long serialVersionUID = 1L;
+    /**
+     * 标题
+     */
+    @ApiModelProperty(value = "标题")
+    private String title;
+
+    @ApiModelProperty(value = "表单list")
+    List<WbsNodeTableVO> list;
+
+    public WbsTreePrivateTableVO() {
+    }
+    public WbsTreePrivateTableVO(String title, List<WbsNodeTableVO> list) {
+        this.title = title;
+        this.list = list;
+    }
+}

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

@@ -76,5 +76,9 @@ public class WbsTreePrivateVO extends WbsTreePrivate implements INode<WbsTreePri
      */
     private List<String> tableFileTypes;
 
+    /**
+     * 项目名称
+     */
+    private String updateUserName;
 
 }

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

@@ -173,7 +173,7 @@
                     <target>${java.version}</target>
                     <encoding>${project.build.sourceEncoding}</encoding>
                     <compilerArguments>
-                        <bootclasspath>${java.home}/lib/rt.jar:${java.home}/lib/jce.jar:${java.home}/lib/jsse.jar
+                        <bootclasspath>${java.home}/lib/rt.jar${path.separator}${java.home}/lib/jce.jar${path.separator}${java.home}/lib/jsse.jar
                         </bootclasspath>
                     </compilerArguments>
                 </configuration>

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

@@ -467,9 +467,7 @@ public class ArchiveFileController extends BladeController {
         return R.success("操作成功");
     }
 
-
-
-   @PostMapping("/findAndReplace")
+    @PostMapping("/findAndReplace")
     @ApiOperationSupport(order = 12)
     @ApiOperation(value = "查找并替换", notes = "传入ids")
     public R findAndReplace(@RequestBody FindAndReplaceDto dto){

+ 32 - 6
blade-service/blade-business/src/main/java/org/springblade/business/controller/InformationWriteQueryController.java

@@ -29,7 +29,6 @@ import org.springblade.business.dto.CustomAddContractNodeDTO;
 import org.springblade.business.dto.ImportTreeDto;
 import org.springblade.business.dto.WbsTreeContractStatisticsDTO;
 import org.springblade.business.dto.FlushQueryNameDTO;
-import org.springblade.business.dto.FlushQueryNameDTO;
 import org.springblade.business.dto.PreviewNodeNameDTO;
 import org.springblade.business.dto.PreviewNodeNameDTO1;
 import org.springblade.business.entity.*;
@@ -62,6 +61,7 @@ import org.springblade.manager.dto.RangeInfo;
 import org.springblade.manager.dto.RangeJson;
 import org.springblade.manager.entity.*;
 import org.springblade.manager.feign.*;
+import org.springblade.manager.util.DataStructureFormatUtils;
 import org.springblade.manager.vo.NameRuleVo;
 import org.springblade.manager.vo.WbsTreeContractTreeVOS;
 import org.springblade.manager.vo.WbsTreeContractVO8;
@@ -1472,7 +1472,9 @@ public R<String> batchDownloadFileToZip(String ids, HttpServletResponse response
                     } else if (url != null && url.size() == 1) {
                         url_link = url.get(0);
                     }
-                    urls.add(url_link + "@@@" + result.get(i).getName() + "-" + result.get(i).getId());
+                    String fileName = result.get(i).getName();
+                    fileName = fileName == null ? "" : fileName.replaceAll("\\\\", "_").replaceAll("/", "_");
+                    urls.add(url_link + "@@@" + fileName);
                 }
 
                 //删除空数据
@@ -2042,7 +2044,6 @@ public R<Boolean> copyContractTreeNode(@RequestBody CopyContractTreeNodeVO vo) {
                         .filter(ObjectUtil::isNotEmpty)
                         .distinct()
                         .collect(Collectors.toList());
-                //表名集合转逗号拼接的字符串
                 if (!tabNames.isEmpty()) {
                     String inClausePlaceholders = String.join(",", Collections.nCopies(tabNames.size(), "?"));
                     String sql = "SELECT table_name AS queryType, GROUP_CONCAT(COLUMN_name) AS ancestors " +
@@ -2717,6 +2718,30 @@ private String reviseCols(Map<String, String> p2, String cols, Long pkeyId, Stri
                 Map<String, Object> origin = listMaps.get(0);
                 List<String> target = Arrays.stream(cols.split(",")).collect(Collectors.toList());
                 List<String> colsList = target.stream().filter(k -> k.startsWith("key")).collect(Collectors.toList());
+                Object key201 = origin.get("key_201");
+                if (key201 instanceof String) {
+                    Map<String, String> map = DataStructureFormatUtils.parseDataByKey(key201.toString());
+                    origin.remove("key_201");
+                    Map<String, Object> map1 = new HashMap<>();
+                    for (String k : colsList) {
+                        if (p2.containsKey(k)) {
+                            Object value = reviseValue(p2, k, map.get(k), pkeyId);
+                            if (value != null) {
+                                if (value.toString().contains("_^_")) {
+                                    map1.put(k, value);
+                                } else {
+                                    map1.put(k, StringPool.NULL);
+                                }
+                            }
+                        }
+                    }
+                    if (!map1.isEmpty()) {
+                        int i = target.indexOf("key_201");
+                        if (i >= 0) {
+                            target.set(i, DataStructureFormatUtils.buildDataObject(map1));
+                        }
+                    }
+                }
                 for (String k : colsList) {
                     if (p2.containsKey(k)) {
 //                        Object value = reviseValue(p2, k, origin.get(k));
@@ -2731,6 +2756,7 @@ private String reviseCols(Map<String, String> p2, String cols, Long pkeyId, Stri
                         }
                     }
                 }
+
                 cols = String.join(",", target);
             }
         }
@@ -2774,8 +2800,8 @@ private List<WbsTreeContract> reBuildAncestors(List<WbsTreeContract> list) {
 public void addCopyTabFile(Set<WbsTreeContract> addChildNodesTables,
                            Set<WbsTreeContract> addChildNodesTablesOld) {
     //获取所有数据源附件文件
-    List<Long> tabFileIds = addChildNodesTablesOld.stream().distinct().map(WbsTreeContract::getPKeyId).collect(Collectors.toList());
-    Map<String, List<TableFile>> tableFileOldMap = tableFileClient.getTabFilesByTabIds(StringUtils.join(tabFileIds, ",")).stream().collect(Collectors.groupingBy(TableFile::getTabId));
+    List<String> tabFileIds = addChildNodesTablesOld.stream().distinct().map(item -> item.getPKeyId() + "").collect(Collectors.toList());
+    Map<String, List<TableFile>> tableFileOldMap = tableFileClient.getTabFilesByTabIds(tabFileIds).stream().collect(Collectors.groupingBy(TableFile::getTabId));
     if (tableFileOldMap != null && tableFileOldMap.size() > 0) {
         List<TableFile> resultFileData = new ArrayList<>();
         Set<Long> updatePKeyIds = new HashSet<>();
@@ -3111,7 +3137,7 @@ private void addCopyNodesAndTabsBuildData(List<WbsTreeContract> addNodeList, Lis
         List<String> initTabNames = needTabs.stream().map(WbsTreeContract::getInitTableName).distinct().filter(ObjectUtil::isNotEmpty).collect(Collectors.toList());
         String joined = StringUtils.join(initTabNames, ",");
         joined = "'" + joined.replaceAll(",", "','") + "'";
-        Map<String, QueryProcessDataVO> tabColsAllByTabNameMaps = jdbcTemplate.query("SELECT table_name as queryType, GROUP_CONCAT(COLUMN_name) as ancestors from information_schema.COLUMNS where table_name in (" + joined + ") GROUP BY table_name", new BeanPropertyRowMapper<>(QueryProcessDataVO.class)).stream().collect(Collectors.toMap(QueryProcessDataVO::getQueryType, Function.identity()));
+        Map<String, QueryProcessDataVO> tabColsAllByTabNameMaps = jdbcTemplate.query("SELECT table_name as queryType, GROUP_CONCAT(DISTINCT COLUMN_name) as ancestors from information_schema.COLUMNS where table_name in (" + joined + ") GROUP BY table_name", new BeanPropertyRowMapper<>(QueryProcessDataVO.class)).stream().collect(Collectors.toMap(QueryProcessDataVO::getQueryType, Function.identity()));
         for (WbsTreeContract node : needNodes) {
             Long oldId = node.getId();
             //新节点

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

@@ -192,9 +192,9 @@ public class MessageWarningController extends BladeController {
             iPage.getRecords().forEach(reVO -> {
                 if (reVO.getType() != null && reVO.getType() == 3) {
                     if (reVO.getContent() != null && reVO.getContent().contains("驳回了")) {
-                        reVO.setTypeValue("驳回通知");
+                        reVO.setRepealType("驳回通知");
                     } else if (reVO.getContent() != null && reVO.getContent().contains("废除了")) {
-                        reVO.setTypeValue("废除通知");
+                        reVO.setRepealType("废除通知");
                     }
                     return;
                 }

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

@@ -3,6 +3,7 @@ package org.springblade.business.controller;
 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.toolkit.CollectionUtils;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
@@ -81,7 +82,7 @@ public class RecycleBinController extends BladeController {
         if (vo.getRegainIds() != null && vo.getRegainIds().size() > 0) {
             //获取数据
             List<Long> longs = vo.getRegainIds().stream().map(i -> i.getId()).collect(Collectors.toList());
-            List<RecycleBin> recycleBinList = this.recycleBinService.list(Wrappers.<RecycleBin>lambdaQuery().in(RecycleBin::getId, longs));
+            List<RecycleBin> recycleBinList = this.recycleBinService.list(Wrappers.<RecycleBin>lambdaQuery().eq(RecycleBin::getStatus,1).in(RecycleBin::getId, longs));
             //恢复数据成功后删除回收站对应记录
             List<String> recycleBinIds = new ArrayList<>();
             //划分数据类型
@@ -89,10 +90,26 @@ public class RecycleBinController extends BladeController {
             List<RecycleBin> nodeTypeList = recycleBinList.stream().filter(recycleBin -> new Integer("2").equals(recycleBin.getDelType())).distinct().collect(Collectors.toList());
             boolean regainNode = false, regainFile = false;
             if (nodeTypeList.size() > 0) {
+                List<RecycleBin> errorList = new ArrayList<>();
+                //筛选出项目级存在的节点
+                for (RecycleBin recycleBin : nodeTypeList) {
+                    //当前是否有节点在项目级被删除了  如果是标记当前节点不可用
+                    Integer count = this.wbsTreeContractClient.findIsExistTreeNode(Arrays.asList(recycleBin.getBusinessId().split(",")));
+                    if (count > 0){
+                        recycleBin.setStatus(2);
+                        errorList.add(recycleBin);
+                    }
+                }
+                if(CollectionUtils.isNotEmpty(errorList)){
+                    recycleBinService.updateBatchById(errorList);
+                    nodeTypeList.removeAll(errorList);
+                }
+
                 //恢复集合
                 List<String> processNodeList = new ArrayList<>();
                 this.foreachQueryData(nodeTypeList, recycleBinIds, processNodeList);
                 try {
+
                     //恢复数据
                     if (processNodeList.size() > 0) {
                         regainNode = this.wbsTreeContractClient.regainRemoveTreeByPrimaryKeyIds(processNodeList);
@@ -142,7 +159,7 @@ public class RecycleBinController extends BladeController {
 
     private void foreachQueryData(List<RecycleBin> recycleList, List<String> recycleBinIds, List<String> result) {
         for (RecycleBin recycleBin : recycleList) {
-            if (StringUtils.isNotEmpty(recycleBin.getBusinessId())) {
+            if (StringUtils.isNotEmpty(recycleBin.getBusinessId()) && recycleBin.getStatus() == 1) {
                 if (recycleBin.getBusinessId().contains(",")) {
                     result.addAll(new ArrayList<>(Arrays.asList(recycleBin.getBusinessId().split(","))));
                 } else {

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

@@ -47,8 +47,8 @@ public class StandardInfoController {
      */
     @GetMapping("page")
     @ApiOperation(value = "分页查询所有数据", notes = "传入分页对象和高级查询对象")
-    public R<IPage<StandardInfoDTO>> selectAll(Query query, StandardInfo standardInfo) {
-        IPage<StandardInfoDTO> page = this.uStandardInfoService.selectMyPage(query, standardInfo);
+    public R<IPage<StandardInfoDtoVo>> selectAll(Query query, StandardInfo standardInfo) {
+        IPage<StandardInfoDtoVo> page = this.uStandardInfoService.selectMyPage(query, standardInfo);
         return R.data(page);
     }
 

+ 28 - 7
blade-service/blade-business/src/main/java/org/springblade/business/controller/TaskController.java

@@ -123,12 +123,12 @@ public class TaskController extends BladeController {
         if (config != null) {
             if(projectId!=null && !projectId.equals("") && Func.isNotEmpty(projectId)){
                 ProjectInfo projectInfo = projectClient.getById(projectId);
-                addTime = projectInfo.getMsTime();
+                addTime = projectInfo.getMsTime() == null ? 60 : (int)(projectInfo.getMsTime() * 60);
             }
             //获取当前时间
             Date now = DateUtil.now();
             // 16 改为 1小时后超时
-            now = DateUtil.plusHours(now, addTime);
+            now = DateUtil.plusMinutes(now, addTime);
 
             LambdaUpdateWrapper<DefaultConfig> wrapper = new LambdaUpdateWrapper<>();
             wrapper.set(DefaultConfig::getSmsTimeOut, DateUtil.format(now, "yyyy-MM-dd HH:mm:ss"));
@@ -1303,7 +1303,8 @@ public class TaskController extends BladeController {
         int size = dto.getSize();
         //封装入参SQL
         List<Object> params = new ArrayList<>();
-        StringBuilder sqlString = new StringBuilder("SELECT * FROM u_task WHERE 1=1 AND is_deleted = 0 AND approval_type in(1,3,4,8,9,10)");
+        String sqlResult = "SELECT * ";
+        StringBuilder sqlString = new StringBuilder(" FROM u_task WHERE 1=1 AND is_deleted = 0 AND approval_type in(1,3,4,8,9,10)");
         if (ObjectUtil.isNotEmpty(dto.getTypeValue())) {
             sqlString.append(" AND type = ?");
             params.add(dto.getTypeValue());
@@ -1379,7 +1380,8 @@ public class TaskController extends BladeController {
                     sqlString.append("EXISTS (SELECT 1 FROM u_task_parallel WHERE u_task.process_instance_id = u_task_parallel.process_instance_id AND u_task_parallel.status = ? AND u_task_parallel.task_user = ?)");
                     params.add(1);
                     params.add(SecureUtil.getUserId());
-
+                    sqlResult = "SELECT *, (SELECT ifnull(e_visa_status, -1)  FROM u_task_parallel WHERE u_task.process_instance_id = u_task_parallel.process_instance_id AND u_task_parallel.STATUS = 1 " +
+                            "AND u_task_parallel.task_user = " + SecureUtil.getUserId() + " and is_deleted = 0 order by id desc limit 1) as e_status";
                     //如果是待办页面,且 任务状态下拉框 选择的不是 待审批状态 的任务,那么直接返回null
                 } else if (ObjectUtil.isNotEmpty(dto.getStatusValue()) && !dto.getStatusValue().equals(1)) {
                     return null;
@@ -1390,6 +1392,8 @@ public class TaskController extends BladeController {
                     params.add(1);
                     params.add(SecureUtil.getUserId());
                     sqlString.append(" AND status = 1");
+                    sqlResult = "SELECT *, (SELECT ifnull(e_visa_status, -1)  FROM u_task_parallel WHERE u_task.process_instance_id = u_task_parallel.process_instance_id AND u_task_parallel.STATUS = 1 " +
+                            "AND u_task_parallel.task_user = " + SecureUtil.getUserId() + " and is_deleted = 0 order by id desc limit 1) as e_status";
                 }
 
             } else if (dto.getSelectedType().equals(2)) { //已办页面
@@ -1407,7 +1411,7 @@ public class TaskController extends BladeController {
 //        sqlString.append(" AND (SELECT COUNT(1)  FROM u_information_query WHERE u_task.form_data_id = id and is_deleted=0) > 0");
 
         //总数量
-        String sqlCount = sqlString.toString().replace("*", "count(1)");
+        String sqlCount = "select count(1) " +  sqlString;
         Optional<Integer> totalCountOptional = Optional.ofNullable(jdbcTemplate.queryForObject(sqlCount, Integer.class, params.toArray()));
         int totalCount = totalCountOptional.orElse(0);
 
@@ -1423,13 +1427,17 @@ public class TaskController extends BladeController {
             }
         } else {
             //Web端默认倒叙
-            sqlString.append(" ORDER BY create_time DESC LIMIT ? OFFSET ?");
+            if (!sqlResult.equals("SELECT * ")) {
+                sqlString.append(" ORDER BY e_status asc, create_time DESC LIMIT ? OFFSET ?");
+            } else {
+                sqlString.append(" ORDER BY create_time DESC LIMIT ? OFFSET ?");
+            }
         }
         params.add(size);
         params.add((current - 1) * size);
 
         //执行SQL获取数据
-        String sqlPage = sqlString.toString();
+        String sqlPage = sqlResult + sqlString;
         List<Task> resultList = jdbcTemplate.query(
                 sqlPage,
                 new BeanPropertyRowMapper<>(Task.class),
@@ -1467,6 +1475,7 @@ public class TaskController extends BladeController {
                     vo.setApprovalType(task.getApprovalType());
                     vo.setFormDataId(task.getFormDataId());
                     vo.setProcessInstanceId(task.getProcessInstanceId());
+                    vo.setEStatus(task.getEStatus());
                     List<TaskParallel> taskParallelList = finalTaskParallelGroupMap.get(task.getProcessInstanceId());
                     if (taskParallelList != null && taskParallelList.size() > 0) {
                         //如果是垂直签,且是待办页面,判断是否是当前用户审批轮次,不是当前用户审批轮次就不显示该任务
@@ -2074,6 +2083,18 @@ public class TaskController extends BladeController {
         return taskService.reSigningEVisaStatus0(dtos,header);
     }
 
+    @GetMapping("/checkAndRepairPDFisNull")
+    @ApiOperation(value = "检查PDF是否为空")
+    @ApiOperationSupport(order = 3)
+    public void checkAndRepairPDFisNull(HttpServletRequest request) throws Exception {
+        String header = request.getHeader("Blade-Auth");
+        Long projectId=1904814720589430785L;
+        String sql="select id,wbs_id,project_id,contract_id from u_information_query where project_id="+projectId+" and pdf_url is null and node_pdf_url is null  and status in(0,1,2) and is_deleted=0";
+        List<reSigningEVisaStatus> query = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(reSigningEVisaStatus.class));
+        taskService.reSigningEVisaStatus0(query,header);
+        System.out.println("完成");
+    }
+
     @PostMapping("/reSigningEntrust")
     @ApiOperationSupport(order = 3)
     @ApiOperation(value = "委托单管理-一键重签", notes = "传入taskIds、下拉框的contractId、projectId")

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

@@ -179,6 +179,8 @@ public class TrialDetectionController extends BladeController {
         jdbcTemplate.execute(sql5);
         String sql6 = "delete from u_information_query where wbs_id in(" + ids + ") and type = 2";
         jdbcTemplate.execute(sql6);
+        String sql7="update u_trial_auto_number set is_deleted=0 where form_data_id in ("+ids+")";
+        jdbcTemplate.execute(sql7);
         return R.status(true);
     }
 

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

@@ -153,8 +153,10 @@ public class TrialMaterialController extends BladeController {
         if(b){
             //删除关联表中的额数据
             String sqlForDelTrailSampleRecord = "delete from u_trial_sampling_record where sample_info_id in ("+ids+")";
+            String update="update u_trial_auto_number set is_deleted=1 where form_data_id in ("+ids+")";
             try {
                 jdbcTemplate.execute(sqlForDelTrailSampleRecord);
+                jdbcTemplate.update(update);
             } catch (DataAccessException e) {
                 log.error("删除关联表中的额数据失败", e);
                 throw new RuntimeException(e);

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

@@ -119,7 +119,7 @@ public class TrialSystemDockingController extends BladeController {
 			//异步下载文件并且上传Oss
 			trialSystemDockingService.syncUpdateFile(list1);
 		}
-		Map<Long, Long> map = list1.stream().collect(Collectors.toMap(TrialSystemDocking::getDataId, TrialSystemDocking::getId));
+		Map<Long, String> map = list1.stream().collect(Collectors.toMap(TrialSystemDocking::getId, TrialSystemDocking::getReportName));
 		return R.data(map);
 	}
 

+ 28 - 6
blade-service/blade-business/src/main/java/org/springblade/business/controller/UserViewProjectContractController.java

@@ -23,6 +23,7 @@ import org.springblade.manager.dto.SaveUserInfoByProjectDTO;
 import org.springblade.manager.entity.ContractInfo;
 import org.springblade.manager.entity.ProjectInfo;
 import org.springblade.manager.entity.SignPfxFile;
+import org.springblade.manager.entity.UserProjectInfoCollect;
 import org.springblade.manager.feign.ContractClient;
 import org.springblade.manager.feign.ProjectAssignmentUserClient;
 import org.springblade.manager.feign.ProjectClient;
@@ -35,6 +36,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.jdbc.core.SingleColumnRowMapper;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -46,9 +48,7 @@ import java.io.InputStream;
 import java.math.BigDecimal;
 import java.net.URL;
 import java.net.URLConnection;
-import java.util.Comparator;
-import java.util.Iterator;
-import java.util.List;
+import java.util.*;
 import java.util.stream.Collectors;
 
 @RestController
@@ -268,18 +268,40 @@ public class UserViewProjectContractController {
                     contractInfoList.sort(Comparator.comparingInt(ContractInfoVO::getIsDefault).reversed());
                     vo.setContractInfoList(contractInfoList);
                 });
-                //排序项目
-                projectInfoVOS.sort(Comparator.comparingInt(ProjectInfoVO::getIsDefault).reversed());
             }
 
             //剔除没有合同段的项目
             projectInfoVOS.removeIf(next -> next.getContractInfoList().size() == 0);
+            //排序项目
+            List<Long> collectIds = new ArrayList<>();
+            if (!projectInfoVOS.isEmpty()) {
+                String pIds = projectInfoVOS.stream().map(projectInfoVO -> projectInfoVO.getId() + "").collect(Collectors.joining(","));
+                collectIds = jdbcTemplate.query("select project_id from m_user_project_collect where is_deleted = 0 and user_id = " + AuthUtil.getUserId() + " and project_id in ( " + pIds + ")",
+                        new SingleColumnRowMapper<>(Long.class));
+            }
+            Map<Long, Long> collect = collectIds.stream().collect(Collectors.toMap(v -> v, v -> v, (k1, k2) -> k1));
+            // 按是否收藏进行排序,然后按照sort 进行排序
+            projectInfoVOS.sort((o1, o2) -> {
+                if (collect.containsKey(o1.getId())) {
+                    if (!collect.containsKey(o2.getId())) {
+                        return -1;
+                    }
+                } else {
+                    if (collect.containsKey(o2.getId())) {
+                        return 1;
+                    }
+                }
+                if (o1.getSort() != null && o2.getSort() != null) {
+                    return o1.getSort().compareTo(o2.getSort());
+                }
+                return 0;
+            });
             //将合同段中业主合同段排在最前面
             if(ObjectUtil.isNotEmpty(projectInfoVOS)){
                 for (ProjectInfoVO projectInfoVO : projectInfoVOS) {
                     if(ObjectUtil.isNotEmpty(projectInfoVO.getContractInfoList())){
                         List<ContractInfoVO> contractInfoList = projectInfoVO.getContractInfoList();
-                        contractInfoList.sort(Comparator.comparingInt(contractInfo->contractInfo.getContractType() == 3 ? -1:0));
+                        contractInfoList.sort(Comparator.comparingInt(ContractInfoVO::getSort));
                     }
                 }
             }

+ 53 - 50
blade-service/blade-business/src/main/java/org/springblade/business/mapper/ImageClassificationFileMapper.xml

@@ -73,58 +73,61 @@
 
     <select id="selectImageClassificationFilePage" resultMap="imageClassificationFileResultMap">
         select
-            files.id,
-            files.title,
-            files.text_content,
-            files.shooting_user,
-            files.shooting_time,
-            files.file_size,
-            files.image_url,
-            files.pdf_url,
-            files.type,
-            files.marge_pdf_url,
-            files.create_time,
-            files.wbs_id
+        files.id,
+        files.title,
+        files.text_content,
+        files.shooting_user,
+        files.shooting_time,
+        files.file_size,
+        files.image_url,
+        files.pdf_url,
+        files.type,
+        files.marge_pdf_url,
+        files.create_time,
+        files.wbs_id
         from
         (
-            select
-                wbs_id,
-                create_time,
-                id,
-                title,
-                text_content,
-                shooting_user,
-                shooting_time,
-                file_size,
-                image_url,
-                pdf_url,
-                marge_pdf_url,
-                type,
-                date_format(shooting_time,'%Y-%m-%d') as shootingTimeStr
-            from u_image_classification_file
-            where is_deleted = 0 and status = 1
-                and project_id = #{param.projectId}
-                and classify_id = #{param.classifyId}
-            <if test="param.contractId != null and param.contractId != ''">
-                and contract_id = #{param.contractId}
-            </if>
-            <if test="param.queryStr != null and param.queryStr != ''">
-                and (title like concat('%',#{param.queryStr},'%') OR shooting_user like concat('%',#{param.queryStr},'%'))
-            </if>
-            <if test="param.wbsIds != null and param.wbsIds.size != 0">
-                and wbs_id in
-                <foreach collection="param.wbsIds" item="wbsId" open="(" separator="," close=")">
-                    #{wbsId}
-                </foreach>
-            </if>
-            <if test="param.staDate != null and param.staDate != ''">
-                <![CDATA[ and  shooting_time >= DATE_FORMAT(#{param.staDate}, '%Y-%m-%d %H:%i:%S') ]]>
-            </if>
-            <if test="param.endDate != null and param.endDate != ''">
-                <![CDATA[ and  shooting_time <= DATE_FORMAT(#{param.endDate}, '%Y-%m-%d %H:%i:%S') ]]>
-            </if>
-                order by shooting_time desc
-            ) as files
+        select
+        uicf.wbs_id,
+        uicf.create_time,
+        uicf.id,
+        uicf.title,
+        uicf.text_content,
+        uicf.shooting_user,
+        uicf.shooting_time,
+        uicf.file_size,
+        uicf.image_url,
+        uicf.pdf_url,
+        uicf.marge_pdf_url,
+        uicf.type,
+        date_format(uicf.shooting_time,'%Y-%m-%d') as shootingTimeStr
+        from u_image_classification_file uicf
+        <if test="param.wbsIds == null or param.wbsIds.size == 0">
+            JOIN m_wbs_tree_contract mwtc ON uicf.wbs_id = mwtc.p_key_id AND mwtc.is_deleted = 0
+        </if>
+        where uicf.is_deleted = 0 and uicf.status = 1
+        and uicf.project_id = #{param.projectId}
+        and uicf.classify_id = #{param.classifyId}
+        <if test="param.contractId != null and param.contractId != ''">
+            and uicf.contract_id = #{param.contractId}
+        </if>
+        <if test="param.queryStr != null and param.queryStr != ''">
+            and (uicf.title like concat('%',#{param.queryStr},'%') OR uicf.shooting_user like concat('%',#{param.queryStr},'%'))
+        </if>
+        <if test="param.wbsIds != null and param.wbsIds.size != 0">
+            and uicf.wbs_id in
+            <foreach collection="param.wbsIds" item="wbsId" open="(" separator="," close=")">
+                #{wbsId}
+            </foreach>
+        </if>
+        <if test="param.staDate != null and param.staDate != ''">
+            <![CDATA[ and uicf.shooting_time >= DATE_FORMAT(#{param.staDate}, '%Y-%m-%d %H:%i:%S') ]]>
+        </if>
+        <if test="param.endDate != null and param.endDate != ''">
+            <![CDATA[ and uicf.shooting_time <= DATE_FORMAT(#{param.endDate}, '%Y-%m-%d %H:%i:%S') ]]>
+        </if>
+        order by uicf.shooting_time desc
+        ) as files
         where
         1 = 1
         <if test="param.queryDate != null and param.queryDate != ''">

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

@@ -933,7 +933,7 @@
 
     <!--获取当前节点下,所有表单的字段数据-->
     <select id="getNodeChildTabColsAllByTabName" resultMap="queryProcessDataMap">
-        SELECT table_name as queryType, GROUP_CONCAT(COLUMN_name) as ancestors
+        SELECT table_name as queryType, GROUP_CONCAT(distinct COLUMN_name) as ancestors
         from information_schema.COLUMNS
         where table_name
                   in (#{tabName})

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

@@ -20,7 +20,7 @@ import java.util.List;
  */
 public interface StandardInfoMapper extends BaseMapper<StandardInfo> {
 
-    IPage<StandardInfoDTO> selectMyPage(Page<StandardInfoDTO> page, @Param("query") StandardInfo standardInfo);
+    IPage<StandardInfoDtoVo> selectMyPage(Page<StandardInfoDtoVo> page, @Param("query") StandardInfo standardInfo);
 
     StandardInfoDTO selectMyOne(@Param("id") Long id);
 

+ 5 - 4
blade-service/blade-business/src/main/java/org/springblade/business/mapper/StandardInfoMapper.xml

@@ -16,7 +16,7 @@
         <result property="updateTime" column="update_time"/>
         <result property="updateUser" column="update_user"/>
     </resultMap>
-    <resultMap id="BaseResultPageMap" type="org.springblade.business.dto.StandardInfoDTO">
+    <resultMap id="BaseResultPageMap" type="org.springblade.business.vo.StandardInfoDtoVo">
         <id property="id" column="id"/>
         <result property="name" column="name"/>
         <result property="symbol" column="symbol"/>
@@ -28,6 +28,7 @@
         <result property="createUser" column="create_user"/>
         <result property="updateTime" column="update_time"/>
         <result property="updateUser" column="update_user"/>
+        <result property="symbolName" column="symbolName"/>
         <collection property="info" ofType="org.springblade.business.entity.StandardInfo" select="findByParentId" column="{parentId=id}">
         </collection>
     </resultMap>
@@ -39,7 +40,7 @@
     </sql>
     <select id="selectMyPage" resultMap="BaseResultPageMap">
         SELECT
-            <include refid="Base_Column_List"/>
+            <include refid="Base_Column_List"/>,concat(symbol,name) symbolName
         FROM
             u_standard_info
         <where>
@@ -62,7 +63,7 @@
     </select>
     <select id="selectMyOne" resultMap="BaseResultPageMap">
         SELECT
-            <include refid="Base_Column_List"/>
+            <include refid="Base_Column_List"/>,concat(symbol,name) symbolName
         FROM
             u_standard_info
         WHERE
@@ -201,7 +202,7 @@
     </select>
     <select id="findRightByJoinLeftId" resultType="org.springblade.business.entity.StandardInfo">
         SELECT
-            <include refid="Base_Column_Join_List"/>
+            <include refid="Base_Column_Join_List"/>, c.name parentName
         FROM
             u_standard_info a
             INNER JOIN u_standard_info_join b ON a.id = b.standard_info_right_id AND a.is_deleted = b.is_deleted

+ 2 - 2
blade-service/blade-business/src/main/java/org/springblade/business/scheduled/ChenYuTestScheduled.java

@@ -271,7 +271,7 @@ public class ChenYuTestScheduled {
     /**
      * 获取已完成的检测报告
      */
-    @Scheduled(cron = "0 0 * * * ?")
+    @Scheduled(cron = "0 05 * * * ?")
     public void getFinishTestReport() {
         if (!SystemUtils.isLinux()) {
             return;
@@ -408,7 +408,7 @@ public class ChenYuTestScheduled {
     /**
      * 获取第三方报告
      */
-    @Scheduled(cron = "0 0 * * * ?")
+    @Scheduled(cron = "0 05 * * * ?")
     public void getThirdReport() {
         if (!SystemUtils.isLinux()) {
             return;

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

@@ -5,6 +5,7 @@ import org.springblade.business.dto.*;
 import org.springblade.business.entity.TrialSelfInspectionRecord;
 import org.springblade.business.vo.*;
 import org.springblade.core.mp.base.BaseService;
+import org.springblade.core.secure.BladeUser;
 import org.springblade.core.tool.api.R;
 import org.springframework.web.multipart.MultipartFile;
 

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

@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
 import org.springblade.business.dto.StandardInfoDTO;
 import org.springblade.business.dto.StandardInfoPrivateJoinDTO;
 import org.springblade.business.entity.StandardInfo;
+import org.springblade.business.vo.StandardInfoDtoVo;
 import org.springblade.business.vo.StandardInfoPrivateJoinVO;
 import org.springblade.business.vo.StandardInfoVO;
 import org.springblade.core.mp.support.Query;
@@ -18,7 +19,7 @@ import java.util.List;
  */
 public interface StandardInfoService extends IService<StandardInfo> {
 
-    IPage<StandardInfoDTO> selectMyPage(Query query, StandardInfo standardInfo);
+    IPage<StandardInfoDtoVo> selectMyPage(Query query, StandardInfo standardInfo);
 
     StandardInfoDTO selectOne(Long id);
 

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

@@ -422,6 +422,9 @@ public class InformationQueryServiceImpl extends BaseServiceImpl<InformationQuer
                         if (linkIds.size() > 0) {
                             oldData.setSjRecordIds(StringUtils.join(linkIds, ","));
                         }
+                        if (DateUtil.between(oldData.getCreateTime(), DateUtil.parse("2025-08-14 11:00:00", "yyyy-MM-dd HH:mm:ss")).getSeconds() > 0) {
+                            oldData.setCreateTime(new Date());
+                        }
                         //修改数据
                         this.baseMapper.updateById(oldData);
                     } else {

+ 15 - 5
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TaskServiceImpl.java

@@ -39,6 +39,7 @@ import org.springblade.core.tool.utils.Func;
 import org.springblade.core.tool.utils.ObjectUtil;
 import org.springblade.core.tool.utils.ResourceUtil;
 import org.springblade.evisa.feign.EVisaClient;
+import org.springblade.evisa.redissionUtil.DistributedRedisLock;
 import org.springblade.evisa.vo.EVisaTaskApprovalVO;
 import org.springblade.flow.core.constant.ProcessConstant;
 import org.springblade.flow.core.feign.IFlowClient;
@@ -1568,11 +1569,20 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
             //这里发起的默认为普通流程
             task.setType(1);
             task.setStatus(1);
-            //保存附表信息
-            this.taskParallelService.saveBatch(taskParallelArray);
-
-            //保存主表数据
-            this.save(task);
+            try {
+                if (DistributedRedisLock.acquire("TaskService_StartApproval_" + task.getFormDataId(), 5)) {
+                    long count = this.count(Wrappers.<Task>lambdaQuery().eq(Task::getFormDataId, task.getFormDataId()).ne(Task::getStatus, 3));
+                    if (count > 0) {
+                        return false;
+                    }
+                    //保存附表信息
+                    this.taskParallelService.saveBatch(taskParallelArray);
+                    //保存主表数据
+                    this.save(task);
+                }
+            } finally {
+                DistributedRedisLock.release("TaskService_StartApproval_" + task.getFormDataId());
+            }
         }
         return true;
     }

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

@@ -158,7 +158,24 @@ public class TrialMaterialMobilizationServiceImpl extends BaseServiceImpl<TrialM
 
         IPage<TrialMaterialMobilizationVO> trialMaterialMobilizationVOIPage = TrialMaterialMobilizationWarpper.build().pageVO(pages);
         List<TrialMaterialMobilizationVO> records = trialMaterialMobilizationVOIPage.getRecords();
-        Map<String, String> fileMaps = jdbcTemplate.query("select link,original_name from blade_attach", new BeanPropertyRowMapper<>(Attach.class)).stream().collect(Collectors.toMap(Attach::getLink, Attach::getOriginalName, (key1, key2) -> key2));
+        StringBuilder links = new StringBuilder();
+        records.forEach(record -> {
+            if (StringUtil.hasText(record.getOtherAccessories())) {
+                links.append("'").append(record.getOtherAccessories()).append("',");
+            }
+            if (StringUtil.hasText(record.getProductionCertificate())) {
+                links.append("'").append(record.getProductionCertificate()).append("',");
+            }
+            if (StringUtil.hasText(record.getQualityInspectionReport())) {
+                links.append("'").append(record.getQualityInspectionReport()).append("',");
+            }
+        });
+        Map<String, String> fileMaps = new HashMap<>();
+        if (links.length() > 1) {
+            links.deleteCharAt(links.length() - 1);
+            fileMaps = jdbcTemplate.query("select link,original_name from blade_attach where link in (" + links + ")", new BeanPropertyRowMapper<>(Attach.class))
+                    .stream().collect(Collectors.toMap(Attach::getLink, Attach::getOriginalName, (key1, key2) -> key2));
+        }
         for (TrialMaterialMobilizationVO record : records) {
             for (User user : userList) {
                 if (user.getId().equals(record.getUserId())) {
@@ -504,6 +521,10 @@ public class TrialMaterialMobilizationServiceImpl extends BaseServiceImpl<TrialM
             return R.fail("所选数据均存在取样记录,不允许删除");
         }
         boolean b = super.deleteLogic(newIdList);
+        if(b){
+          String update="update u_trial_auto_number set is_deleted=1 where form_data_id in ("+ids+")";
+          jdbcTemplate.update(update);
+        }
         return  b?R.success("删除成功"):R.fail("删除失败");
     }
 }

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

@@ -1140,7 +1140,7 @@ public class TrialSelfInspectionRecordServiceImpl extends BaseServiceImpl<TrialS
         //------初始当前填报的表pKeyIds------
         this.initTrialTabIds(dto);
 
-        if (!this.judgingParameters(dto)) {
+        if(!this.judgingParameters(dto)){
             //------初始编号信息------
             this.initBuildNumber(dto);
         }
@@ -1172,7 +1172,6 @@ public class TrialSelfInspectionRecordServiceImpl extends BaseServiceImpl<TrialS
             //------关联新增设备使用记录信息------
             this.trialDeviceUseService.addDeviceUseInfo(dto, obj.getId());
         }
-
         // ---- 修改样品单号信息 --------
         if (dto != null && Func.isNotEmpty(dto.getEntrustId())) {
             //修改项目节点基础信息

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

@@ -28,7 +28,6 @@ import org.springblade.core.mp.base.BaseServiceImpl;
 import org.springblade.core.oss.model.BladeFile;
 import org.springblade.resource.feign.NewIOSSClient;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
 import com.baomidou.mybatisplus.core.metadata.IPage;
@@ -52,8 +51,6 @@ public class TrialSystemDockingServiceImpl extends BaseServiceImpl<TrialSystemDo
 
     @Autowired
 	private  NewIOSSClient newIOSSClient;
-    @Autowired
-    private JdbcTemplate jdbcTemplate;
 
 	@Override
 	public IPage<TrialSystemDockingVO> selectTrialSystemDockingPage(IPage<TrialSystemDockingVO> page, TrialSystemDockingVO trialSystemDocking) {
@@ -72,7 +69,7 @@ public class TrialSystemDockingServiceImpl extends BaseServiceImpl<TrialSystemDo
 					//下载文件到本地路径
 					boolean b = downloadFileFromUrl(tsd.getFileUrl(), localFilePath);
 					if(b){
-						String fileName=tsd.getProjectId()+"|"+tsd.getId() + ".pdf";
+						String fileName=tsd.getProjectId()+"/"+tsd.getId() + ".pdf";
 						BladeFile bladeFile = newIOSSClient.uploadFile(fileName, localFilePath);
 						if(bladeFile!=null){
 							tsd.setFileUrlOss(bladeFile.getLink());
@@ -100,9 +97,10 @@ public class TrialSystemDockingServiceImpl extends BaseServiceImpl<TrialSystemDo
 
 	@Override
 	public void updatedelete(List<Long> longList) {
-		for (Long id : longList) {
-			String sql="delete from u_trial_system_docking where id="+id+" or data_id="+id;
-			jdbcTemplate.execute(sql);
+		if (longList != null && !longList.isEmpty()) {
+			this.update(new UpdateWrapper<TrialSystemDocking>()
+					.set("is_deleted", 1)
+					.in("id", longList));
 		}
 	}
 

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

@@ -56,8 +56,8 @@ public class UStandardInfoServiceImpl extends ServiceImpl<StandardInfoMapper, St
 
 
     @Override
-    public IPage<StandardInfoDTO> selectMyPage(Query query, StandardInfo standardInfo) {
-        return baseMapper.selectMyPage(new Page<StandardInfoDTO>(query.getCurrent(), query.getSize()), standardInfo);
+    public IPage<StandardInfoDtoVo> selectMyPage(Query query, StandardInfo standardInfo) {
+        return baseMapper.selectMyPage(new Page<StandardInfoDtoVo>(query.getCurrent(), query.getSize()), standardInfo);
     }
 
     @Override

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

@@ -298,9 +298,9 @@ public class WeatherInfoServiceImpl extends ServiceImpl<WeatherInfoMapper, Weath
     //去除重复天气,并填充每个合同段缺失的天气
     @Scheduled(cron = "0 0 9 * * ?")
     public void scanMissWeather(){
-        if (!SystemUtils.isLinux()) {
-            return;
-        }
+//        if (!SystemUtils.isLinux()) {
+//            return;
+//        }
         //获取所有项目的合同段
         List<ContractInfoVO> contractInfos = baseMapper.getAllContract();
         for (ContractInfoVO contract : contractInfos) {

+ 11 - 1
blade-service/blade-business/src/main/java/org/springblade/business/utils/PDFUtil.java

@@ -135,6 +135,11 @@ public class PDFUtil {
                 // 特殊处理
                 if(textStr.indexOf("1")>=0){
                     String txt = textStr.substring(textStr.indexOf("1"));
+                    for (int i = 0; i < txt.length(); i++) {
+                        if (!Character.isDigit(txt.charAt(i))) {
+                            txt=txt.substring(0,i);
+                        }
+                    }
                     if (txt.length() >= 15 && Func.isNumeric(txt)||(Func.isNumeric(txt)&&txt.length()==8&&txt.startsWith("123"))) {
                         System.out.println(txt);
                         eVisaConfigList.add(txt);
@@ -169,7 +174,12 @@ public class PDFUtil {
                         }
                     }
                     if(textString.startsWith("1")){
-                        if (textString.length() >= 15 && Func.isNumeric(textString)) {
+                        for (int i = 0; i < textString.length(); i++) {
+                            if (!Character.isDigit(textString.charAt(i))) {
+                                textString=textString.substring(0,i);
+                            }
+                        }
+                        if (textString.length() >= 15 && Func.isNumeric(textString)||(Func.isNumeric(textString)&&textString.length()==8&&textString.startsWith("123"))) {
                             eVisaConfigList.add("✹" + textString);
                         }
                     }

+ 1 - 1
blade-service/blade-e-visa/pom.xml

@@ -334,7 +334,7 @@
                     <target>${java.version}</target>
                     <encoding>${project.build.sourceEncoding}</encoding>
                     <compilerArguments>
-                        <bootclasspath>${java.home}/lib/rt.jar:${java.home}/lib/jce.jar:${java.home}/lib/jsse.jar
+                        <bootclasspath>${java.home}/lib/rt.jar${path.separator}${java.home}/lib/jce.jar${path.separator}${java.home}/lib/jsse.jar
                         </bootclasspath>
                     </compilerArguments>
                 </configuration>

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

@@ -87,8 +87,8 @@ public class EVDataServiceImpl implements EVDataService {
             this.addSignatureTaskBatch(taskApp);
             //for循环 pdfUrl分割
             String fileUrl = CommonUtil.replaceOssUrl(taskApp.getSignPdfUrl());
-            List<String> eVisaConfigList = PDFUtils.getPdfSignIds(fileUrl, taskApp);
-            if (eVisaConfigList == null || eVisaConfigList.size() == 0) {
+            Map<String, Integer> eVisaConfigMap = PDFUtils.getPdfSignIds(fileUrl, taskApp);
+            if (eVisaConfigMap == null || eVisaConfigMap.size() == 0) {
                 //没有电签配置,默认当前任务为不签字审批,返回成功
                 taskApp.setSigState(2);
                 taskApp.setSignSmg("pdf未获取到关键字Id");
@@ -96,7 +96,7 @@ public class EVDataServiceImpl implements EVDataService {
                 return;
             }
             // 获取pdf上的电签Ids
-            String ids = String.join(",", eVisaConfigList);
+            String ids = String.join(",", eVisaConfigMap.keySet());
             if (taskApp.getRemarkType().equals("1")) { //安心签
                 //添加电签策略
                 List<SealStrategyVO> strategyListByAXQ = getStrategyListByAXQ(taskApp, ids);
@@ -121,6 +121,15 @@ public class EVDataServiceImpl implements EVDataService {
                     }
                     SignBackPdfInfo(taskApp);
                     return;
+                } else {
+                    // 优先使用项目配置的电签
+                    Map<Integer, SealStrategyVO> map = new HashMap<>();
+                    strategyListByAXQ.forEach(item -> {
+                        if (!item.getKeyword().contains("✹")) {
+                            map.put(eVisaConfigMap.get(item.getKeyword()), item);
+                        }
+                    });
+                    strategyListByAXQ.removeIf(item -> item.getKeyword().contains("✹") && map.containsKey(eVisaConfigMap.get(item.getKeyword())));
                 }
                 // 保存电签策略
                 addSignatureDataByAXQZ(strategyListByAXQ, taskApp.getFormDataId(),taskApp.getRemarkType());
@@ -137,6 +146,17 @@ public class EVDataServiceImpl implements EVDataService {
             } else if (taskApp.getRemarkType().equals("2") || taskApp.getRemarkType().equals("3")) { //东方中讯
                 //添加电签策略
                 List<Map<String, Object>> strategyListByDFZX = getStrategyListByDFZX(taskApp, ids);
+                if (strategyListByDFZX != null && !strategyListByDFZX.isEmpty()) {
+                    // 优先使用项目配置的电签
+                    Map<Integer, Integer> map = new HashMap<>();
+                    strategyListByDFZX.forEach(item -> {
+                        String keyword = item.get("keyword") + "";
+                        if (!keyword.contains("✹")) {
+                            map.put(eVisaConfigMap.get(keyword), 1);
+                        }
+                    });
+                    strategyListByDFZX.removeIf(item -> (item.get("keyword") + "").contains("✹") && map.containsKey(eVisaConfigMap.get(item.get("keyword") + "")));
+                }
                 addSignatureDataByDFZX(strategyListByDFZX,taskApp.getFormDataId(),taskApp.getRemarkType());
                 //调用签字逻辑
                 String s = signTaskBatchByDFZX(strategyListByDFZX, fileUrl, taskApp.getSigType(),taskApp.getRemarkType(),taskApp.getContractId());
@@ -540,9 +560,19 @@ public class EVDataServiceImpl implements EVDataService {
             for (int i = 0; i < strArray.length; i++) {
                 List<Map<String, Object>> maps2 = null;
                 if (dqIds.length() > 0) {
-                    String sqlinfo = " SELECT * from ( SELECT a.id as keyWord,a.project_id,a.pyzbx ,a.pyzby,(SELECT acc_code from blade_user where id='" + strArray[i] + "' and is_deleted=0  ) as sealId,'1' as type,'"+strArray[i]+"' as userId from m_textdict_info a where  a.type =2 and a.id in (" + dqIds + ")  and sig_role_id in (SELECT DISTINCT c.role_id from m_project_assignment_user c  where c.contract_id=" + task.getContractId() + " and user_id=" + strArray[i] + " and c.is_deleted=0 ) ) x where x.sealId is not null ";
+                    String sqlinfo;
+                    long seconds = DateUtil.between(new Date(), DateUtil.parse("2025-08-14 11:00:00", "yyyy-MM-dd HH:mm:ss")).getSeconds();
+                    if (seconds < 0) {
+                        sqlinfo = " SELECT * from ( SELECT a.id as keyWord,a.project_id,a.pyzbx ,a.pyzby,(SELECT acc_code from blade_user where id='" + strArray[i] + "' and is_deleted=0  ) as sealId,'1' as type,'"+strArray[i]+"' as userId from m_textdict_info a where a.project_id = " + task.getProjectId() + " and a.type =2 and a.id in (" + dqIds + ")  and sig_role_id in (SELECT DISTINCT c.role_id from m_project_assignment_user c  where c.contract_id=" + task.getContractId() + " and user_id=" + strArray[i] + " and c.is_deleted=0 ) ) x where x.sealId is not null ";
+                    } else {
+                        sqlinfo = " SELECT * from ( SELECT a.id as keyWord,a.project_id,a.pyzbx ,a.pyzby,(SELECT acc_code from blade_user where id='" + strArray[i] + "' and is_deleted=0  ) as sealId,'1' as type,'"+strArray[i]+"' as userId from m_textdict_info a where a.type =2 and a.id in (" + dqIds + ")  and sig_role_id in (SELECT DISTINCT c.role_id from m_project_assignment_user c  where c.contract_id=" + task.getContractId() + " and user_id=" + strArray[i] + " and c.is_deleted=0 ) ) x where x.sealId is not null ";
+                    }
                     if (task.getSigType() == 2) {
-                        sqlinfo = "SELECT a.id as keyWord,a.pyzbx,a.pyzby,b.certificate_number as sealId,'2' as type,'"+strArray[i]+"' as userId from m_textdict_info a ,m_sign_pfx_file b where a.sig_role_id = b.pfx_type and b.project_contract_role like '%" + task.getContractId() + "%' and a.is_deleted=0 and b.is_deleted=0 and a.type=6 and a.id in(" + dqIds + ")";
+                        if (seconds < 0) {
+                            sqlinfo = "SELECT a.id as keyWord,a.pyzbx,a.pyzby,b.certificate_number as sealId from m_textdict_info a ,m_sign_pfx_file b where a.project_id = " + task.getProjectId() + " and a.sig_role_id = b.pfx_type and b.project_contract_role like '%" + task.getContractId() + "%' and a.is_deleted=0 and b.is_deleted=0 and a.type=6 and a.id in(" + dqIds + ")";
+                        } else {
+                            sqlinfo = "SELECT a.id as keyWord,a.pyzbx,a.pyzby,b.certificate_number as sealId,'2' as type,'"+strArray[i]+"' as userId from m_textdict_info a ,m_sign_pfx_file b where a.project_id = " + task.getProjectId() + " and a.sig_role_id = b.pfx_type and b.project_contract_role like '%" + task.getContractId() + "%' and a.is_deleted=0 and b.is_deleted=0 and a.type=6 and a.id in(" + dqIds + ")";
+                        }
                         System.out.println("东方中讯--签章--" + sqlinfo);
                     } else {
                         System.out.println("东方中讯--签字--" + sqlinfo);
@@ -578,7 +608,7 @@ public class EVDataServiceImpl implements EVDataService {
                     List<Map<String, Object>> maps3 = jdbcTemplate.queryForList(sql);
                     System.out.println("东方中讯--签字--key =" + sql);
                     if (!maps3.isEmpty()) {
-                        Map<String, List<Map<String, Object>>> peopleByAge = maps2.stream()
+                        Map<String, List<Map<String, Object>>> peopleByAge = maps3.stream()
                                 .collect(Collectors.groupingBy(hada -> (Func.toStr(hada.get("keyWord")))));
                         for (String keyId : peopleByAge.keySet()) {
                             List<Map<String, Object>> keyList = peopleByAge.get(keyId);
@@ -666,17 +696,27 @@ public class EVDataServiceImpl implements EVDataService {
                 String userId =strArray[i];
                 List<Map<String, Object>> maps2 = null;
                 if (dqIds.length() > 0) {
-                    String sqlinfo = "SELECT * from ( SELECT DISTINCT a.id,a.pyzbx ,a.pyzby,a.project_id,(SELECT signature_file_url from m_sign_pfx_file where is_register=1 and certificate_user_id='" + userId + "' and is_deleted=0  ) as signature_file_url, (SELECT wide from m_sign_pfx_file where is_register=1 and certificate_user_id='" + userId + "' and is_deleted=0  ) as wide ,(SELECT high from m_sign_pfx_file where is_register=1 and certificate_user_id='" + userId + "' and is_deleted=0  ) as high ,'"+userId+"' as userId from m_textdict_info a where  a.type =2 and a.id in (" + dqIds + ") and sig_role_id in (SELECT DISTINCT c.role_id from m_project_assignment_user c  where c.contract_id=" + task.getContractId() + " and user_id=" + userId + " and c.is_deleted=0 ) ) x where x.signature_file_url is not null ";
+                    long seconds = DateUtil.between(new Date(), DateUtil.parse("2025-08-14 11:00:00", "yyyy-MM-dd HH:mm:ss")).getSeconds();
+                    String sqlinfo;
+                    if (seconds < 0) {
+                        sqlinfo = "SELECT * from ( SELECT DISTINCT a.id,a.pyzbx ,a.pyzby,a.project_id,(SELECT signature_file_url from m_sign_pfx_file where is_register=1 and certificate_user_id='" + userId + "' and is_deleted=0  ) as signature_file_url, (SELECT wide from m_sign_pfx_file where is_register=1 and certificate_user_id='" + userId + "' and is_deleted=0  ) as wide ,(SELECT high from m_sign_pfx_file where is_register=1 and certificate_user_id='" + userId + "' and is_deleted=0  ) as high ,'"+userId+"' as userId from m_textdict_info a where a.project_id = " + task.getProjectId() + " and a.type =2 and a.id in (" + dqIds + ") and sig_role_id in (SELECT DISTINCT c.role_id from m_project_assignment_user c  where c.contract_id=" + task.getContractId() + " and user_id=" + userId + " and c.is_deleted=0 ) ) x where x.signature_file_url is not null ";
+                    } else {
+                        sqlinfo = "SELECT * from ( SELECT DISTINCT a.id,a.pyzbx ,a.pyzby,a.project_id,(SELECT signature_file_url from m_sign_pfx_file where is_register=1 and certificate_user_id='" + userId + "' and is_deleted=0  ) as signature_file_url, (SELECT wide from m_sign_pfx_file where is_register=1 and certificate_user_id='" + userId + "' and is_deleted=0  ) as wide ,(SELECT high from m_sign_pfx_file where is_register=1 and certificate_user_id='" + userId + "' and is_deleted=0  ) as high ,'"+userId+"' as userId from m_textdict_info a where  a.type =2 and a.id in (" + dqIds + ") and sig_role_id in (SELECT DISTINCT c.role_id from m_project_assignment_user c  where c.contract_id=" + task.getContractId() + " and user_id=" + userId + " and c.is_deleted=0 ) ) x where x.signature_file_url is not null ";
+                    }
                     if (task.getSigType() == 2) {
-                        sqlinfo = "SELECT a.id,a.pyzbx,a.pyzby,b.signature_file_url,b.id as sfId,a.project_id,b.certificate_password,b.certificate_user_name,b.certificate_number ,b.wide,b.high,'321987456' as userId from m_textdict_info a ,m_sign_pfx_file b where a.sig_role_id = b.pfx_type and b.project_contract_role like '%" + task.getContractId() + "%' and a.is_deleted=0 and b.is_deleted=0 and a.type=6 and a.id in(" + dqIds + ") ";
+                        if (seconds < 0 ) {
+                            sqlinfo = "SELECT a.id,a.pyzbx,a.pyzby,b.signature_file_url,b.id as sfId,a.project_id,b.certificate_password,b.certificate_user_name,b.certificate_number ,b.wide,b.high,'321987456' as userId from m_textdict_info a ,m_sign_pfx_file b where a.project_id = " + task.getProjectId() + " and a.sig_role_id = b.pfx_type and b.project_contract_role like '%" + task.getContractId() + "%' and a.is_deleted=0 and b.is_deleted=0 and a.type=6 and a.id in(" + dqIds + ") ";
+                        } else {
+                            sqlinfo = "SELECT a.id,a.pyzbx,a.pyzby,b.signature_file_url,b.id as sfId,a.project_id,b.certificate_password,b.certificate_user_name,b.certificate_number ,b.wide,b.high,'321987456' as userId from m_textdict_info a ,m_sign_pfx_file b where a.sig_role_id = b.pfx_type and b.project_contract_role like '%" + task.getContractId() + "%' and a.is_deleted=0 and b.is_deleted=0 and a.type=6 and a.id in(" + dqIds + ") ";
+                        }
                         System.out.println("安心签--签章--=" + sqlinfo);
                     } else {
                         System.out.println("安心签--签字--=" + sqlinfo);
                     }
                     maps2 = jdbcTemplate.queryForList(sqlinfo);
                 }
+                List<Map<String, Object>> maps = new ArrayList<>();
                 if (maps2 != null && maps2.size() > 0) {
-                    List<Map<String, Object>> maps = new ArrayList<>();
                     Map<String, List<Map<String, Object>>> peopleByAge = maps2.stream()
                             .collect(Collectors.groupingBy(hada -> (Func.toStr(hada.get("id")))));
 

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

@@ -797,9 +797,9 @@ public class EVisaServiceImpl implements EVisaService {
         if ("20".equals(sys_isonline) || SystemUtils.isWindows() || SystemUtils.isMacOs()) {
             url = "http://219.151.181.73:9125/FrontSys/SealServicezx/FileSignByKeyWord";
         }
-        if(signPdfByDFZX.equals("3")){
-            url = "http://10.0.0.4:9125/FrontSys/SealServicezx/FileSignByKeyWord";
-        }
+//        if(signPdfByDFZX.equals("3")){
+//            url = "http://10.0.0.4:9125/FrontSys/SealServicezx/FileSignByKeyWord";
+//        }
 
 
         String sysLocalFileUrl = FileUtils.getSysLocalFileUrl();

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

@@ -8,18 +8,15 @@ import org.springblade.common.utils.CommonUtil;
 import org.springblade.core.tool.utils.Func;
 
 import java.io.*;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Optional;
+import java.util.*;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 
 public class PDFUtils {
-
-
-    public static List<String>  getPdfSignIds(String pdfUrl, TaskSignInfoVO taskApp) {
-        List<String> eVisaConfigList = new ArrayList<>();
+    public static Map<String, Integer>  getPdfSignIds(String pdfUrl, TaskSignInfoVO taskApp) {
+//        List<String> eVisaConfigList = new ArrayList<>();
+        Map<String, Integer> eVisaConfigMap = new HashMap<>();
         try  {
             InputStream inputStream = CommonUtil.getOSSInputStream(pdfUrl);
             PDDocument document = PDDocument.load(inputStream);
@@ -45,7 +42,8 @@ public class PDFUtils {
                         }
                     }
                     if (txt.length() >= 15 && Func.isNumeric(txt)||(Func.isNumeric(txt)&&txt.length()==8&&txt.startsWith("123"))) {
-                        eVisaConfigList.add(txt);
+//                        eVisaConfigList.add(txt);
+                        eVisaConfigMap.put(txt,k);
                     }
                 }
                 if (taskApp.getPdfDate() == null || taskApp.getPdfDate().isEmpty()) {
@@ -62,16 +60,23 @@ public class PDFUtils {
                         }
                     }
                     if (txt.length() >= 15 && Func.isNumeric(txt)||(Func.isNumeric(txt)&&txt.length()==8&&txt.startsWith("123"))) {
-                        eVisaConfigList.add(txt);
+//                        eVisaConfigList.add(txt);
+                        eVisaConfigMap.put(txt,k);
                     }
                 }
 
                 // 特殊处理
                 if(textStr.indexOf("1")>=0){
                     String txt = textStr.substring(textStr.indexOf("1"));
+                    for (int i = 0; i < txt.length(); i++) {
+                        if (!Character.isDigit(txt.charAt(i))) {
+                            txt=txt.substring(0,i);
+                        }
+                    }
                     if (txt.length() >= 15 && Func.isNumeric(txt)||(Func.isNumeric(txt)&&txt.length()==8&&txt.startsWith("123"))) {
                         System.out.println(txt);
-                        eVisaConfigList.add(txt);
+//                        eVisaConfigList.add(txt);
+                        eVisaConfigMap.put(txt,k);
                     }
                 }
                 if (textStr.contains("✹") && textStr.indexOf("✹") + 1 < textStr.length()) {
@@ -85,7 +90,8 @@ public class PDFUtils {
                                 }
                             }
                             if (txt.length() >= 15 && Func.isNumeric(txt)||(Func.isNumeric(txt)&&txt.length()==8&&txt.startsWith("123"))) {
-                                eVisaConfigList.add("✹" + txt);
+//                                eVisaConfigList.add("✹" + txt);
+                                eVisaConfigMap.put("✹" + txt,k);
                             }
                         }
                     }
@@ -98,26 +104,33 @@ public class PDFUtils {
                                 }
                             }
                             if (txt.length() >= 15 && Func.isNumeric(txt)||(Func.isNumeric(txt)&&txt.length()==8&&txt.startsWith("123"))) {
-                                eVisaConfigList.add("✹" + txt);
+//                                eVisaConfigList.add("✹" + txt);
+                                eVisaConfigMap.put("✹" + txt,k);
                             }
                         }
                     }
                     if(textString.startsWith("1")){
-                        if (textString.length() >= 15 && Func.isNumeric(textString)) {
-                            eVisaConfigList.add("✹" + textString);
+                        for (int i = 0; i < textString.length(); i++) {
+                            if (!Character.isDigit(textString.charAt(i))) {
+                                textString=textString.substring(0,i);
+                            }
+                        }
+                        if (textString.length() >= 15 && Func.isNumeric(textString)||(Func.isNumeric(textString)&&textString.length()==8&&textString.startsWith("123"))) {
+//                            eVisaConfigList.add("✹" + textString);
+                            eVisaConfigMap.put("✹" + textString,k);
                         }
                     }
                 }
             }
 
 
-            List<String> unique = eVisaConfigList.stream().distinct().collect(Collectors.toList());
+//            List<String> unique = eVisaConfigList.stream().distinct().collect(Collectors.toList());
             document.close();
-            return unique;
+            return eVisaConfigMap;
         }catch (Exception e){
             e.printStackTrace();
             System.out.println("pdf大小为0");
-            return eVisaConfigList;
+            return eVisaConfigMap;
         }
     }
 
@@ -167,6 +180,11 @@ public class PDFUtils {
                 // 特殊处理
                 if(textStr.indexOf("1")>=0){
                     String txt = textStr.substring(textStr.indexOf("1"));
+                    for (int i = 0; i < txt.length(); i++) {
+                        if (!Character.isDigit(txt.charAt(i))) {
+                            txt=txt.substring(0,i);
+                        }
+                    }
                     if (txt.length() >= 15 && Func.isNumeric(txt)||(Func.isNumeric(txt)&&txt.length()==8&&txt.startsWith("123"))) {
                         System.out.println(txt);
                         eVisaConfigList.add(txt);
@@ -201,7 +219,12 @@ public class PDFUtils {
                         }
                     }
                     if(textString.startsWith("1")){
-                        if (textString.length() >= 15 && Func.isNumeric(textString)) {
+                        for (int i = 0; i < textString.length(); i++) {
+                            if (!Character.isDigit(textString.charAt(i))) {
+                                textString=textString.substring(0,i);
+                            }
+                        }
+                        if (textString.length() >= 15 && Func.isNumeric(textString)||(Func.isNumeric(textString)&&textString.length()==8&&textString.startsWith("123"))) {
                             eVisaConfigList.add("✹" + textString);
                         }
                     }

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

@@ -13,6 +13,7 @@ import org.springblade.common.utils.SnowFlakeUtil;
 import org.springblade.core.log.exception.ServiceException;
 import org.springblade.core.mp.support.Condition;
 import org.springblade.core.mp.support.Query;
+import org.springblade.core.secure.utils.AuthUtil;
 import org.springblade.core.secure.utils.SecureUtil;
 import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.utils.BeanUtil;
@@ -22,6 +23,7 @@ import org.springblade.manager.dto.FindAllUserByConditionDTO;
 import org.springblade.manager.dto.SaveUserInfoByProjectDTO;
 import org.springblade.manager.dto.WbsTreeContractDTO;
 import org.springblade.manager.entity.ContractRelationJlyz;
+import org.springblade.manager.entity.ProjectInfo;
 import org.springblade.manager.mapper.SaveUserInfoByProjectMapper;
 import org.springblade.manager.service.IWbsTreeContractService;
 import org.springblade.manager.service.SaveUserInfoByProjectService;
@@ -104,19 +106,71 @@ public class ContractInfoController extends BladeController {
     public R<List<ContractInfoVO>> findContractInfoByPid(String pid) {
         List<ContractInfo> contractInfoVOS = contractInfoService.selectContractInfoPageByPid(pid);
         List<ContractInfoVO> resultAll = new ArrayList<>();
+        String contractIds = contractInfoVOS.stream().filter(contractInfo -> contractInfo.getContractType().equals(4)).map(contractInfo -> contractInfo.getId() + "").collect(Collectors.joining(","));
+        Map<Long, List<MeterContractInfo>> collect = new HashMap<>();
+        if (StringUtils.isNotBlank(contractIds)) {
+            List<MeterContractInfo> meterContractInfoList = jdbcTemplate.query("SELECT * FROM s_meter_contract_info WHERE contract_id in ( " + contractIds + ")", new BeanPropertyRowMapper<>(MeterContractInfo.class));
+            collect = meterContractInfoList.stream().collect(Collectors.groupingBy(MeterContractInfo::getContractId));
+        }
+        String ids = contractInfoVOS.stream().map(contractInfo -> contractInfo.getId() + "").collect(Collectors.joining(","));
+        Map<Long, List<ContractRelationJlyz>> relationMap = new HashMap<>();
+        if (StringUtils.isNotBlank(ids)) {
+            List<ContractRelationJlyz> query = jdbcTemplate.query("select * from  m_contract_relation_jlyz where contract_id_jlyz in ( " + ids + ")", new BeanPropertyRowMapper<>(ContractRelationJlyz.class));
+            relationMap = query.stream().collect(Collectors.groupingBy(ContractRelationJlyz::getContractIdJlyz));
+        }
+        Map<Long, ContractInfo> contractInfoMap = contractInfoVOS.stream().collect(Collectors.toMap(ContractInfo::getId, vo -> vo));
         for (ContractInfo contractInfo : contractInfoVOS) {
             ContractInfoVO vo = new ContractInfoVO();
             BeanUtil.copyProperties(contractInfo, vo);
             if (contractInfo.getContractType().equals(4)) {
-                MeterContractInfo meterContractInfo = jdbcTemplate.query("SELECT * FROM s_meter_contract_info WHERE contract_id = " + contractInfo.getId(), new BeanPropertyRowMapper<>(MeterContractInfo.class)).stream().findAny().orElse(null);
-                if (meterContractInfo != null) {
-                    vo.setMeterContractInfo(meterContractInfo);
+                List<MeterContractInfo> meterContractInfoList1 = collect.get(contractInfo.getId());
+                if (meterContractInfoList1 != null && !meterContractInfoList1.isEmpty()) {
+                    vo.setMeterContractInfo(meterContractInfoList1.get(0));
+                }
+            }
+            List<ContractRelationJlyz> relationJlyzList = relationMap.get(contractInfo.getId());
+            if (relationJlyzList != null && !relationJlyzList.isEmpty()) {
+                List<ContractInfo> list = new ArrayList<>();
+                for (ContractRelationJlyz relation : relationJlyzList) {
+                    list.add(contractInfoMap.get(relation.getContractIdSg()));
                 }
+                vo.setRelationContractInfo(list);
             }
             resultAll.add(vo);
         }
+        resultAll.sort((o1, o2) -> o2.getSort().compareTo(o1.getSort()));
         return R.data(resultAll);
     }
+    /**
+     * 排序
+     */
+    @PostMapping("/sort")
+    @ApiOperationSupport(order = 9)
+    @ApiOperation(value = "排序", notes = "传入排序好的ids")
+    public R<Boolean> sort(@RequestBody List<Long> contractIds) {
+        int sort = 0;
+        if (contractIds == null || contractIds.isEmpty()) {
+            return R.data(false);
+        }
+        List<ContractInfo> updateList = new ArrayList<>(contractIds.size());
+        Long userId = AuthUtil.getUserId();
+        for (Long id : contractIds) {
+            ContractInfo temp = new ContractInfo();
+            temp.setSort(++sort);
+            temp.setUpdateUser(userId);
+            temp.setUpdateTime(new Date());
+            temp.setId(id);
+            updateList.add(temp);
+        }
+        try {
+            boolean result = contractInfoService.updateBatchById(updateList);
+            return R.data(result);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return R.fail(200, "排序保存失败");
+        }
+    }
+
 
     /**
      * 分页 合同段信息

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

@@ -22,7 +22,6 @@ import lombok.Data;
 import lombok.NoArgsConstructor;
 import lombok.SneakyThrows;
 import org.apache.commons.codec.Charsets;
-import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang3.ObjectUtils;
 import org.apache.poi.ss.usermodel.WorkbookFactory;
@@ -45,12 +44,14 @@ import org.springblade.core.log.exception.ServiceException;
 import org.springblade.core.mp.support.Condition;
 import org.springblade.core.mp.support.Query;
 import org.springblade.core.oss.model.BladeFile;
+import org.springblade.core.redis.cache.BladeRedis;
 import org.springblade.core.secure.BladeUser;
 import org.springblade.core.secure.utils.AuthUtil;
 import org.springblade.core.secure.utils.SecureUtil;
 import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.constant.BladeConstant;
 import org.springblade.core.tool.utils.*;
+import org.springblade.evisa.redissionUtil.DistributedRedisLock;
 import org.springblade.manager.bean.TableInfo;
 import org.springblade.manager.dto.AddBussFileSortDTO;
 import org.springblade.manager.dto.BatchAddNumbersDTO;
@@ -60,6 +61,7 @@ import org.springblade.manager.mapper.ExcelTabMapper;
 import org.springblade.manager.mapper.WbsTreeContractMapper;
 import org.springblade.manager.mapper.WbsTreePrivateMapper;
 import org.springblade.manager.service.*;
+import org.springblade.manager.util.DataStructureFormatUtils;
 import org.springblade.manager.utils.*;
 import org.springblade.manager.utils.FileUtils;
 import org.springblade.manager.vo.*;
@@ -75,14 +77,15 @@ import org.springframework.http.HttpHeaders;
 import org.springframework.http.MediaType;
 import org.springframework.jdbc.core.BeanPropertyRowMapper;
 import org.springframework.jdbc.core.JdbcTemplate;
-import org.springframework.mock.web.MockMultipartFile;
-import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.bind.annotation.*;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
 import org.springframework.web.multipart.MultipartFile;
 
 import javax.annotation.Resource;
 import javax.imageio.ImageIO;
+import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import javax.validation.Valid;
 import java.awt.*;
@@ -93,12 +96,14 @@ import java.net.URLConnection;
 import java.net.URLEncoder;
 import java.nio.file.Files;
 import java.nio.file.Path;
-import java.nio.file.Paths;
 import java.nio.file.StandardCopyOption;
+import java.sql.SQLException;
 import java.text.SimpleDateFormat;
 import java.util.List;
 import java.util.*;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -186,6 +191,17 @@ public class ExcelTabController extends BladeController {
         return R.data(ExcelTabWrapper.build().entityVO(detail));
     }
 
+    /**
+     * 详情
+     */
+    @GetMapping("/templateDetail")
+    @ApiOperationSupport(order = 1)
+    @ApiOperation(value = "详情", notes = "传入excelTab")
+    public R<ExcelTabVO> templateDetail(@RequestParam Long id) {
+        ExcelTabVO vo = excelTabService.templateDetail(id);
+        return R.data(vo);
+    }
+
     /**
      * 分页 清表基础数据表
      */
@@ -352,6 +368,9 @@ public class ExcelTabController extends BladeController {
         return R.success("上传成功");
     }
 
+    public void checkHtml(){
+
+    }
 
 
     public static InputStream getOSSInputStream(String urlStr) throws Exception {
@@ -465,7 +484,7 @@ public class ExcelTabController extends BladeController {
     @PostMapping("/sava-dataInfo")
     @ApiOperationSupport(order = 13)
     @ApiOperation(value = "编辑-保存", notes = "编辑-保存")
-    public R<List<WbsTreeVO>> savaDataInfo(@Valid @RequestBody WbsExclTabParmVO wbsExclTabParmVO, BladeUser bladeUser) throws IOException {
+    public R<List<WbsTreeVO>> savaDataInfo(@Valid @RequestBody WbsExclTabParmVO wbsExclTabParmVO, BladeUser bladeUser) throws Exception {
         // 保存节点信息
         ExcelTab excelTab = new ExcelTab();
         if (wbsExclTabParmVO.getId() != null) {// 修改
@@ -607,17 +626,20 @@ public class ExcelTabController extends BladeController {
 
                     for (WbsFormElement elementInfo : elementList) {
                         String ysName = elementInfo.getEName();
-                        if (titleName.equals(ysName)) {
+                         if (titleName.equals(ysName)) {
                             lastName = elementInfo.getEName();
                             attrInfo = elementInfo.getEKey() + "__" + i + "_" + j;
+
                             filedType = WbsElementUtil.getInitTableFiledType(elementInfo.getEType());
+
                             filedLength = elementInfo.getELength().toString();
 
                             maxScore = 100;
                             is_true = true;
                             break;
                         } else {
-                            if (MathUtil.sim(titleName, ysName) > maxScore) {
+                             List<String> list = Arrays.asList(titleName.split("_"));
+                             if (list.contains(ysName)) {
                                 attrInfo = elementInfo.getEKey() + "__" + i + "_" + j;
 
                                 filedType = WbsElementUtil.getInitTableFiledType(elementInfo.getEType());
@@ -627,6 +649,7 @@ public class ExcelTabController extends BladeController {
                                 lastName = ysName;
                                 maxScore = MathUtil.sim(titleName, ysName);
                                 is_true = true;
+                                break;
                             }
                         }
                     }
@@ -1861,9 +1884,13 @@ public class ExcelTabController extends BladeController {
         updateWrapper.in("p_key_id", pkeyId);
         updateWrapper.set("is_buss_show", status);
         wbsTreeContractService.update(updateWrapper);
-        excelTabService.getBussPdfInfo(pkeyId);
-        //重新生成PDF修改queryInfo
-        excelTabService.getBussPdfs(nodeId, classify, wbsTreeContract.getContractId(), wbsTreeContract.getProjectId());
+        try{
+            excelTabService.getBussPdfInfo(pkeyId);
+            //重新生成PDF修改queryInfo
+            excelTabService.getBussPdfs(nodeId, classify, wbsTreeContract.getContractId(), wbsTreeContract.getProjectId());
+        }catch (NullPointerException e){
+            throw new ServiceException("当前节点有表单不存在,操作失败");
+        }
         WbsTreeContract contract = wbsTreeContractService.getById(Long.parseLong(nodeId));
         wbsTreeContractService.checkNodeAllDate(contract);
         return R.data("成功");
@@ -2720,6 +2747,10 @@ public class ExcelTabController extends BladeController {
                             CellRange cellRange = sheet.getCellRange(y1, x1);
                             if (cellRange != null) {
                                 // 创建字体
+                                String text = cellRange.getText();
+                                if (StringUtil.hasText(text)) {
+                                    dqid = text + "*" + dqid;
+                                }
                                 cellRange.setText(dqid);
                                 cellRange.getCellStyle().getExcelFont().setSize(1);
                                 cellRange.getCellStyle().getExcelFont().setColor(Color.WHITE);
@@ -2827,6 +2858,7 @@ public class ExcelTabController extends BladeController {
                 List<Map<String, Object>> businessDataMap = this.jdbcTemplate.queryForList(querySql);
 
                 if (businessDataMap.size() > 0) {
+                    DataStructureFormatUtils.parseDataByKey(businessDataMap);
                     // 匹配关联
                     try {
                         if (tableNode2.getHtmlUrl() != null) {
@@ -3197,6 +3229,7 @@ public class ExcelTabController extends BladeController {
             List<Map<String, Object>> businessDataMap = this.jdbcTemplate.queryForList(querySql);
             Map<String, Object> reData=new HashMap<>();
             if (businessDataMap.size() > 0){
+                DataStructureFormatUtils.parseDataByKey(businessDataMap);
                 try {
                     if (tableNode2.getHtmlUrl() != null){
                         InputStream inputStreamByUrl = FileUtils.getInputStreamByUrl(tableNode2.getHtmlUrl());
@@ -3503,7 +3536,7 @@ public class ExcelTabController extends BladeController {
                         for (Map<String, Object> mysqlData : businessDataMapList) {
                             //数据结果
                             Map<String, Object> reData = new HashMap<>();
-
+                            DataStructureFormatUtils.parseDataByKey(mysqlData);
                             for (String key : mysqlData.keySet()) {
                                 String tabVal = mysqlData.get(key) + "";
                                 // 时间段处理

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

@@ -33,6 +33,7 @@ import org.springblade.manager.service.*;
 import org.springblade.manager.service.impl.ContractInfoServiceImpl;
 import org.springblade.manager.service.impl.TableInfoServiceImpl;
 import org.springblade.manager.service.impl.WbsTreePrivateServiceImpl;
+import org.springblade.manager.util.DataStructureFormatUtils;
 import org.springblade.manager.utils.FileUtils;
 import org.springblade.resource.feign.CommonFileClient;
 import org.springblade.resource.feign.IOSSClient;
@@ -555,6 +556,7 @@ public class FirstController extends BladeController {
                             List<Map<String, Object>> businessDataMapList = this.jdbcTemplate.queryForList("SELECT * FROM " + tableId.getTabEnName() + " WHERE group_id = " + json.getString("id"));
                             if (businessDataMapList.size() > 0) {
                                 for (Map<String, Object> mysqlData : businessDataMapList) {
+                                    DataStructureFormatUtils.parseDataByKey(mysqlData);
                                     for (String key : mysqlData.keySet()) {
                                         String tabVal = mysqlData.get(key) + "";
                                         // 时间段处理
@@ -719,6 +721,7 @@ public class FirstController extends BladeController {
                             List<Map<String, Object>> businessDataMapList = this.jdbcTemplate.queryForList("SELECT * FROM " + tableId.getTabEnName() + " WHERE group_id = " + json.getString("id"));
                             if (businessDataMapList.size() > 0) {
                                 for (Map<String, Object> mysqlData : businessDataMapList) {
+                                    DataStructureFormatUtils.parseDataByKey(mysqlData);
                                     for (String key : mysqlData.keySet()) {
                                         String tabVal = mysqlData.get(key) + "";
                                         // 时间段处理

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

@@ -8,12 +8,15 @@ import lombok.AllArgsConstructor;
 
 import javax.validation.Valid;
 
+import org.springblade.common.utils.SnowFlakeUtil;
 import org.springblade.core.mp.support.Condition;
 import org.springblade.core.mp.support.Query;
+import org.springblade.core.secure.utils.AuthUtil;
 import org.springblade.core.tool.api.R;
 import org.springblade.manager.dto.WbsTreeContractDTO;
 import org.springblade.manager.dto.ProjectInfoDTO;
 import org.springblade.manager.entity.ContractInfo;
+import org.springblade.manager.entity.UserProjectInfoCollect;
 import org.springblade.manager.service.*;
 import org.springblade.manager.vo.*;
 import org.springframework.dao.EmptyResultDataAccessException;
@@ -26,8 +29,10 @@ import org.springblade.manager.wrapper.ProjectInfoWrapper;
 import org.springblade.core.boot.ctrl.BladeController;
 
 import java.util.ArrayList;
+import java.util.Date;
 import java.util.List;
 import java.util.Map;
+import java.util.stream.Collectors;
 
 @RestController
 @AllArgsConstructor
@@ -258,5 +263,110 @@ public class ProjectInfoController extends BladeController {
         List<Map<String, Object>> result = wbsTreeService.findProjectAndContractList(userId);
         return R.data(result);
     }
+    /**
+     * 分页 项目表
+     */
+    @GetMapping("/pageList")
+    @ApiOperationSupport(order = 3)
+    @ApiOperation(value = "分页", notes = "传入projectInfo")
+    public R<IPage<ProjectInfoVO>> pageList(ProjectInfoVO3 vo, Query query) {
+        // 名称搜索,项目状态,收藏夹  排序
+        vo.setUserId(AuthUtil.getUserId());
+        IPage<ProjectInfoVO> pages = projectInfoService.pageList(Condition.getPage(query), vo);
+        return R.data(pages);
+    }
+
+    /**
+     * 收藏项目、取消收藏项目
+     */
+    @PostMapping("/collectProject")
+    @ApiOperationSupport(order = 14)
+    @ApiOperation(value = "收藏项目、取消收藏项目", notes = "传入项目id")
+    public R<Boolean> collectProject(@RequestParam Long projectId) {
+        Long userId = AuthUtil.getUserId();
+        if (userId == null) {
+            return R.fail("用户未登录");
+        }
+        if (projectId == null || projectId <= 0) {
+            return R.fail("项目不存在");
+        }
+        ProjectInfo projectInfo = projectInfoService.getById(projectId);
+        if (projectInfo == null || projectInfo.getIsDeleted() == 1) {
+            return R.fail("项目不存在或者已被删除");
+        }
+        List<UserProjectInfoCollect> query = jdbcTemplate.query("select * from m_user_project_collect where project_id = ? and user_id = ?", new Object[]{projectId, userId}, new BeanPropertyRowMapper<>(UserProjectInfoCollect.class));
+        if (query.isEmpty()) {
+            // 收藏该项目
+            String sql = "insert into m_user_project_collect (id,project_id,user_id,create_user,update_user) values (?,?,?,?,?)";
+            int result = jdbcTemplate.update(sql,SnowFlakeUtil.getId(), projectId, userId, userId, userId);
+            return R.data(result > 0);
+        } else {
+            UserProjectInfoCollect collect = query.get(0);
+            String sql = "update m_user_project_collect set is_deleted = if(is_deleted = 0, 1, 0), update_user = ? where id = ?";
+            int result = jdbcTemplate.update(sql, userId, collect.getId());
+            return R.data(result > 0);
+        }
+    }
+
+    /**
+     * 项目排序
+     */
+    @PostMapping("/sortProject")
+    @ApiOperationSupport(order = 14)
+    @ApiOperation(value = "项目排序", notes = "传入排序好的项目ids")
+    public R<Boolean> sortProject(@RequestBody List<Long> projectIds) {
+        int sort = 0;
+        if (projectIds == null || projectIds.isEmpty()) {
+            return R.data(false);
+        }
+        List<ProjectInfo> updateList = new ArrayList<>(projectIds.size());
+        Long userId = AuthUtil.getUserId();
+        for (Long id : projectIds) {
+            ProjectInfo temp = new ProjectInfo();
+            temp.setSort(++sort);
+            temp.setUpdateUser(userId);
+            temp.setUpdateTime(new Date());
+            temp.setId(id);
+            updateList.add(temp);
+        }
+        try {
+            boolean result = projectInfoService.updateBatchById(updateList);
+            return R.data(result);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return R.fail(200, "排序保存失败");
+        }
+    }
+
+    /**
+     * 收藏项目排序
+     */
+    @PostMapping("/sortProjectCollect")
+    @ApiOperationSupport(order = 14)
+    @ApiOperation(value = "收藏项目排序", notes = "传入排序好的项目ids")
+    public R<Boolean> sortProjectCollect(@RequestBody List<Long> projectIds) {
+        int sort = 0;
+        if (projectIds == null || projectIds.isEmpty()) {
+            return R.data(false);
+        }
+        String ids = projectIds.stream().filter(id -> id != null && id > 0).map(id -> id + "").collect(Collectors.joining(","));
+        Long userId = AuthUtil.getUserId();
+        List<UserProjectInfoCollect> query = jdbcTemplate.query("select id, project_id, user_id from m_user_project_collect where user_id = " + userId + " and project_id in (" + ids + ")",
+                new BeanPropertyRowMapper<>(UserProjectInfoCollect.class));
+        Map<Long, Long> map = query.stream().collect(Collectors.toMap(UserProjectInfoCollect::getProjectId, UserProjectInfoCollect::getId, (key1, key2) -> key2));
+        List<Object[]> batchArgs = new ArrayList<>(map.size());
+        for (Long id : projectIds) {
+            Long l = map.get(id);
+            if (l == null) {
+                continue;
+            }
+            Object[] args = new Object[]{++sort, userId, new Date(), l};
+            batchArgs.add(args);
+        }
+        if (!batchArgs.isEmpty()) {
+            jdbcTemplate.batchUpdate("update m_user_project_collect set sort = ?, update_user = ?, update_time = ? where id = ?", batchArgs);
+        }
+        return R.data(true);
+    }
 
 }

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

@@ -247,8 +247,10 @@ public class TextdictInfoController extends BladeController {
             param.put("ids", ids);
             param.put("tabId", tabId);
             dqOperationLogService.save(new DqOperationLog(wbsTreePrivate, AuthUtil.getUser(), String.join( ",", delIds), 2,param.toJSONString(), JSON.toJSONString(query), ""));
+            textdictInfoService.update(Wrappers.<TextdictInfo>lambdaUpdate().in(TextdictInfo::getId, delIds).eq(TextdictInfo::getProjectId, wbsTreePrivate.getProjectId()).set(TextdictInfo::getIsDeleted, 1));
+        } else {
+            textdictInfoService.getBaseMapper().deleteBatchIds(delIds);
         }
-        textdictInfoService.getBaseMapper().deleteBatchIds(delIds);
 
         return R.success("删除成功");
     }
@@ -419,19 +421,186 @@ public class TextdictInfoController extends BladeController {
         return R.success("操作成功");
     }
 
+    /**
+     * 保存电签
+     */
+//    @PostMapping("/save_sigInfo")
+//    @ApiOperationSupport(order = 7)
+//    @ApiOperation(value = "保存电签", notes = "保存电签")
+//    @Transactional
+//    public R<String> saveSigInfo(@Valid @RequestBody JSONObject dataInfo) throws Exception {
+//        String redisValue = bladeRedis.get("save-eVis-lock:" + SecureUtil.getUserId());
+//        if (StringUtils.isNotEmpty(redisValue) && redisValue.equals("1")) {
+//            throw new ServiceException("请勿重复提交,请3秒后再尝试");
+//        }
+//        JSONArray jsonArray = dataInfo.getJSONArray("dataInfo");
+//
+//        // -------- 移除所有html 的dqid -----
+//        Long tableId = dataInfo.getLong("tabId"); //节点pkid
+//        //当前清表信息
+//        WbsTreePrivate wbsTreePrivate = wbsTreePrivateMapper.getByPKeyId(tableId);
+//        InputStream inputStreamByUrl = FileUtils.getInputStreamByUrl(wbsTreePrivate.getHtmlUrl());
+//        String htmlString = IoUtil.readToString(inputStreamByUrl);
+//        // 样式集合
+//        Document doc = Jsoup.parse(htmlString);
+//        //解析
+//        Element table = doc.select("table").first();
+//        Elements trs = table.select("tr");
+//        //解析
+//        Elements onlyInfo = doc.select("[:readonly]");
+//        if (onlyInfo != null && onlyInfo.size() >= 1) {
+//            for (Element element : onlyInfo) {
+//                element.removeAttr(":readonly");
+//            }
+//        }
+//        Elements tryInfo = doc.select("td[dqid]");
+//        if (tryInfo != null && tryInfo.size() >= 1) {
+//            for (Element element : tryInfo) {
+//                element.removeAttr("dqid");
+//            }
+//        }
+//        if (jsonArray == null || jsonArray.size() == 0) {
+//            return R.success("操作成功");
+//        }
+//
+//        List<WbsTreePrivate> wbsTreePrivatesEqual = wbsTreePrivateMapper.selectList(Wrappers.<WbsTreePrivate>lambdaQuery()
+//                .eq(WbsTreePrivate::getProjectId, wbsTreePrivate.getProjectId())
+//                .eq(WbsTreePrivate::getIsDeleted, 0)
+//                .eq(WbsTreePrivate::getExcelId, wbsTreePrivate.getExcelId()));
+//        List<Long> pKeyIds = wbsTreePrivatesEqual.stream().map(WbsTreePrivate::getPKeyId).collect(Collectors.toList());
+//        String ids = StringUtils.join(pKeyIds, ",");
+//
+//        //删除历史数据
+//        String querySql = "select * from m_textdict_info where (tab_id in(SELECT p_key_id from m_wbs_tree_private where project_id='"+wbsTreePrivate.getProjectId()+"' and excel_id='"+wbsTreePrivate.getExcelId()+"' and type=2 and is_deleted=0) or (excel_id="+wbsTreePrivate.getExcelId()+" AND project_id='"+wbsTreePrivate.getProjectId()+"')) and project_id="+wbsTreePrivate.getProjectId()+" and type in(2,6) ";
+//        List<TextdictInfo> oldTextdictInfos = jdbcTemplate.query(querySql, new BeanPropertyRowMapper<>(TextdictInfo.class));
+//        String delSql = "delete from m_textdict_info where (tab_id in(SELECT p_key_id from m_wbs_tree_private where project_id='"+wbsTreePrivate.getProjectId()+"' and excel_id='"+wbsTreePrivate.getExcelId()+"' and type=2 and is_deleted=0) or (excel_id="+wbsTreePrivate.getExcelId()+" AND project_id='"+wbsTreePrivate.getProjectId()+"')) and project_id="+wbsTreePrivate.getProjectId()+" and type in(2,6) ";
+//        jdbcTemplate.execute(delSql);
+//
+//        // 由于要实现电签 一对多(1个key 对应多个电签Id)
+//        Map<String,String> keyMap = new HashMap<>();
+//
+//        // ------- 查询数据库是否存在 该该电签信息 ---------
+//        StringBuilder dqIds = new StringBuilder();
+//        List<TextdictInfo> newTextDictInfos = new ArrayList<>();
+//        for (int i = 0; i < jsonArray.size(); i++) {
+//            JSONObject jsonObject = jsonArray.getJSONObject(i);
+//            TextdictInfo textdictInfo = new TextdictInfo();
+//            String keky = jsonObject.getString("colKey");
+//
+//            String[] trtd = keky.split("__")[1].split("_");
+//            Element element = trs.get(Integer.parseInt(trtd[0])).select("td").get(Integer.parseInt(trtd[1]));
+//
+//            String id = element.children().get(0).attr("keyname");
+//            if (jsonObject.containsKey("id")) {
+//                textdictInfo.setId(jsonObject.getLong("id"));
+//            } else {
+//                textdictInfo.setId(SnowFlakeUtil.getId());
+//                textdictInfo.setIsDeleted(0);
+//            }
+//            textdictInfo.setName("电签位置配置");
+//            textdictInfo.setType(jsonObject.getInteger("type"));
+//            textdictInfo.setColKey(id);
+//            textdictInfo.setSigRoleId(jsonObject.getString("sigRoleId"));
+//
+//            textdictInfo.setTabId(tableId.toString());
+//            textdictInfo.setExcelId(wbsTreePrivate.getExcelId() + "");
+//
+//            textdictInfo.setColName(jsonObject.getString("colName"));
+//            textdictInfo.setSigRoleName(jsonObject.getString("sigRoleName"));
+//            textdictInfo.setPyzbx(jsonObject.getDouble("pyzbx"));
+//            textdictInfo.setPyzby(jsonObject.getDouble("pyzby"));
+//            Integer timeState = jsonObject.getInteger("timeState");
+//            textdictInfo.setTimeState(timeState);
+//            if(timeState!=null && timeState==1){
+//                textdictInfo.setTimeColKey(jsonObject.getString("timeColKey"));
+//                textdictInfo.setTimeName(jsonObject.getString("timeName"));
+//            }else{
+//                textdictInfo.setTimeColKey("");
+//                textdictInfo.setTimeName("");
+//            }
+//
+//            textdictInfo.setProjectId(wbsTreePrivate.getProjectId());
+//
+//            //由于使用联合主键
+//            TextdictInfo one = textdictInfoService.selectTextdictInfoOne(textdictInfo.getId()+"",textdictInfo.getSigRoleId(),textdictInfo.getProjectId());
+//            if(ObjectUtil.isNotEmpty(one)){
+//                textdictInfoService.saveOrUpdate(textdictInfo);
+//            }else{
+//                textdictInfoService.save(textdictInfo);
+//            }
+//            newTextDictInfos.add(textdictInfo);
+//            dqIds.append(textdictInfo.getId()).append( ",");
+//            String dqId = "";
+//            if(keyMap.containsKey(keky)){
+//                dqId = keyMap.get(keky)+"||"+textdictInfo.getId();
+//            }else{
+//                dqId=textdictInfo.getId()+"";
+//            }
+//            keyMap.put(keky,dqId);
+//            element.removeAttr("dqId");
+//            element.attr("dqId", keyMap.get(keky));
+//            if (jsonObject.getInteger("type") == 2) { //个人签字 不能用户输入
+//                if (element.html().indexOf("el-tooltip") >= 0) {
+//                    element.children().get(0).children().get(0).attr(":readonly", "true");
+//                } else {
+//                    element.children().get(0).attr(":readonly", "true");
+//                }
+//            }
+//        }
+//        File writeFile = new File(wbsTreePrivate.getHtmlUrl());
+////        File writeFile = new File("D:\\file\\downfile\\1792757075013533696.html");
+//        FileUtil.writeToFile(writeFile, doc.html(), Boolean.parseBoolean("UTF-8"));
+//
+//        String str1 = wbsTreePrivate.getHtmlUrl().replace("Desktop//privateUrl", "Desktop/privateUrl");
+//        String replace = str1.replace("\\", "\\\\");
+//
+//        //修改同几点的数据
+//        if(StringUtils.isNotBlank(ids)){
+//            String updateSqlP = "update m_wbs_tree_private set html_url = '" + replace + "' where p_key_id in ("+ids+") and project_id="+wbsTreePrivate.getProjectId()+"";
+//            jdbcTemplate.execute(updateSqlP);
+//        }
+//
+//        //修改对应合同段的htmlUrl,当前项目下对应合同段的节点
+//        List<Long> cIdsList = wbsTreePrivatesEqual.stream().map(WbsTreePrivate::getId).distinct().collect(Collectors.toList());
+//
+//        List<Long> cPkeyIds = wbsTreeContractService.getBaseMapper().selectList(Wrappers.<WbsTreeContract>lambdaQuery()
+//                .eq(WbsTreeContract::getProjectId, wbsTreePrivate.getProjectId())
+//                .eq(WbsTreeContract::getExcelId, wbsTreePrivate.getExcelId())
+//                .in(WbsTreeContract::getId, cIdsList)).stream().map(WbsTreeContract::getPKeyId).collect(Collectors.toList());
+//        String cPkeyIdsStr = StringUtils.join(cPkeyIds, ",");
+//
+//        if (StringUtils.isNotEmpty(cPkeyIdsStr)) {
+//            String updateSqlC = "update m_wbs_tree_contract set html_url = '" + replace + "' where p_key_id in (" + cPkeyIdsStr + ") and project_id="+wbsTreePrivate.getProjectId()+"";
+//            jdbcTemplate.execute(updateSqlC);
+//        }
+//        BladeUser user = AuthUtil.getUser();
+//        DqOperationLog log = new DqOperationLog(wbsTreePrivate, user, "", 1, dataInfo.toJSONString(), JSON.toJSONString(oldTextdictInfos), JSON.toJSONString(newTextDictInfos));
+//        if (dqIds.length() > 1) {
+//            log.setBusinessId(dqIds.deleteCharAt(dqIds.length() - 1).toString());
+//        }
+//        dqOperationLogService.save(log);
+//        bladeRedis.set("save-eVis-lock:" + SecureUtil.getUserId(), "1");
+//        bladeRedis.expire("save-eVis-lock:" + SecureUtil.getUserId(), 3);
+//
+//        return R.success("操作成功");
+//    }
+
     /**
      * 保存电签
      */
     @PostMapping("/save_sigInfo")
     @ApiOperationSupport(order = 7)
-    @ApiOperation(value = "保存电签", notes = "保存电签")
+    @ApiOperation(value = "保存电签(version 3.0)", notes = "保存电签(version 3.0)")
     @Transactional
-    public R<String> saveSigInfo(@Valid @RequestBody JSONObject dataInfo) throws Exception {
+    public R<String> saveSigInfoV3(@Valid @RequestBody JSONObject dataInfo) throws Exception {
         String redisValue = bladeRedis.get("save-eVis-lock:" + SecureUtil.getUserId());
         if (StringUtils.isNotEmpty(redisValue) && redisValue.equals("1")) {
             throw new ServiceException("请勿重复提交,请3秒后再尝试");
         }
         JSONArray jsonArray = dataInfo.getJSONArray("dataInfo");
+        if (jsonArray == null || jsonArray.isEmpty()) {
+            return R.success("操作成功");
+        }
 
         // -------- 移除所有html 的dqid -----
         Long tableId = dataInfo.getLong("tabId"); //节点pkid
@@ -442,101 +611,98 @@ public class TextdictInfoController extends BladeController {
         // 样式集合
         Document doc = Jsoup.parse(htmlString);
         //解析
-        Element table = doc.select("table").first();
-        Elements trs = table.select("tr");
-        //解析
         Elements onlyInfo = doc.select("[:readonly]");
-        if (onlyInfo != null && onlyInfo.size() >= 1) {
+        if (onlyInfo != null && !onlyInfo.isEmpty()) {
             for (Element element : onlyInfo) {
                 element.removeAttr(":readonly");
             }
         }
         Elements tryInfo = doc.select("td[dqid]");
-        if (tryInfo != null && tryInfo.size() >= 1) {
+        if (tryInfo != null && !tryInfo.isEmpty()) {
             for (Element element : tryInfo) {
                 element.removeAttr("dqid");
             }
         }
-        if (jsonArray == null || jsonArray.size() == 0) {
-            return R.success("操作成功");
-        }
-
-        List<WbsTreePrivate> wbsTreePrivatesEqual = wbsTreePrivateMapper.selectList(Wrappers.<WbsTreePrivate>lambdaQuery()
-                .eq(WbsTreePrivate::getProjectId, wbsTreePrivate.getProjectId())
-                .eq(WbsTreePrivate::getIsDeleted, 0)
-                .eq(WbsTreePrivate::getExcelId, wbsTreePrivate.getExcelId()));
-        List<Long> pKeyIds = wbsTreePrivatesEqual.stream().map(WbsTreePrivate::getPKeyId).collect(Collectors.toList());
-        String ids = StringUtils.join(pKeyIds, ",");
-
-        //删除历史数据
-        String querySql = "select * from m_textdict_info where (tab_id in(SELECT p_key_id from m_wbs_tree_private where project_id='"+wbsTreePrivate.getProjectId()+"' and excel_id='"+wbsTreePrivate.getExcelId()+"' and type=2 and is_deleted=0) or (excel_id="+wbsTreePrivate.getExcelId()+" AND project_id='"+wbsTreePrivate.getProjectId()+"')) and project_id="+wbsTreePrivate.getProjectId()+" and type in(2,6) ";
-        List<TextdictInfo> oldTextdictInfos = jdbcTemplate.query(querySql, new BeanPropertyRowMapper<>(TextdictInfo.class));
-        String delSql = "delete from m_textdict_info where (tab_id in(SELECT p_key_id from m_wbs_tree_private where project_id='"+wbsTreePrivate.getProjectId()+"' and excel_id='"+wbsTreePrivate.getExcelId()+"' and type=2 and is_deleted=0) or (excel_id="+wbsTreePrivate.getExcelId()+" AND project_id='"+wbsTreePrivate.getProjectId()+"')) and project_id="+wbsTreePrivate.getProjectId()+" and type in(2,6) ";
-        jdbcTemplate.execute(delSql);
 
+        // 查询历史数据
+        String querySql = String.format("SELECT * from m_textdict_info WHERE project_id = %d and excel_id = %d and type in (2, 6) and (SELECT 1 from m_wbs_tree_private WHERE p_key_id = tab_id and html_url = '%s' ) = 1"
+                    , Long.parseLong(wbsTreePrivate.getProjectId()), wbsTreePrivate.getExcelId(), wbsTreePrivate.getHtmlUrl());
+        List<TextdictInfo> oldTextDictInfos = jdbcTemplate.query(querySql, new BeanPropertyRowMapper<>(TextdictInfo.class));
+        Map<String, TextdictInfo> oldTextDictInfoMap;
+        if (!oldTextDictInfos.isEmpty()) {
+            oldTextDictInfoMap = oldTextDictInfos.stream().collect(Collectors.toMap(item -> item.getProjectId() + item.getExcelId()
+                    + (item.getColKey() != null && item.getColKey().contains("__") ? item.getColKey().split("__")[0] : item.getColKey())
+                    + item.getSigRoleId(), textdictInfo -> textdictInfo));
+        } else {
+            oldTextDictInfoMap = new HashMap<>();
+        }
         // 由于要实现电签 一对多(1个key 对应多个电签Id)
         Map<String,String> keyMap = new HashMap<>();
+        //解析
+        Element table = doc.select("table").first();
+        Elements trs = table.select("tr");
 
         // ------- 查询数据库是否存在 该该电签信息 ---------
         StringBuilder dqIds = new StringBuilder();
         List<TextdictInfo> newTextDictInfos = new ArrayList<>();
+        List<TextdictInfo> updateList = new ArrayList<>();
+        List<TextdictInfo> addList = new ArrayList<>();
         for (int i = 0; i < jsonArray.size(); i++) {
             JSONObject jsonObject = jsonArray.getJSONObject(i);
-            TextdictInfo textdictInfo = new TextdictInfo();
-            String keky = jsonObject.getString("colKey");
-
-            String[] trtd = keky.split("__")[1].split("_");
-            Element element = trs.get(Integer.parseInt(trtd[0])).select("td").get(Integer.parseInt(trtd[1]));
+            String key = jsonObject.getString("colKey");
+            String sigRoleId = jsonObject.getString("sigRoleId");
 
-            String id = element.children().get(0).attr("keyname");
-            if (jsonObject.containsKey("id")) {
-                textdictInfo.setId(jsonObject.getLong("id"));
+            TextdictInfo textdictInfo = new TextdictInfo();
+            Long id = jsonObject.getLong("id");
+            if (id != null && id > 0) {
+                textdictInfo.setId(id);
             } else {
                 textdictInfo.setId(SnowFlakeUtil.getId());
                 textdictInfo.setIsDeleted(0);
             }
             textdictInfo.setName("电签位置配置");
             textdictInfo.setType(jsonObject.getInteger("type"));
-            textdictInfo.setColKey(id);
-            textdictInfo.setSigRoleId(jsonObject.getString("sigRoleId"));
-
+            textdictInfo.setSigRoleId(sigRoleId);
             textdictInfo.setTabId(tableId.toString());
             textdictInfo.setExcelId(wbsTreePrivate.getExcelId() + "");
-
             textdictInfo.setColName(jsonObject.getString("colName"));
             textdictInfo.setSigRoleName(jsonObject.getString("sigRoleName"));
             textdictInfo.setPyzbx(jsonObject.getDouble("pyzbx"));
             textdictInfo.setPyzby(jsonObject.getDouble("pyzby"));
             Integer timeState = jsonObject.getInteger("timeState");
             textdictInfo.setTimeState(timeState);
-            if(timeState!=null && timeState==1){
+            if(timeState == 1){
                 textdictInfo.setTimeColKey(jsonObject.getString("timeColKey"));
                 textdictInfo.setTimeName(jsonObject.getString("timeName"));
             }else{
                 textdictInfo.setTimeColKey("");
                 textdictInfo.setTimeName("");
             }
-
             textdictInfo.setProjectId(wbsTreePrivate.getProjectId());
 
-            //由于使用联合主键
-            TextdictInfo one = textdictInfoService.selectTextdictInfoOne(textdictInfo.getId()+"",textdictInfo.getSigRoleId(),textdictInfo.getProjectId());
-            if(ObjectUtil.isNotEmpty(one)){
-                textdictInfoService.saveOrUpdate(textdictInfo);
-            }else{
-                textdictInfoService.save(textdictInfo);
+            String[] trtd = key.split("__")[1].split("_");
+            Element element = trs.get(Integer.parseInt(trtd[0])).select("td").get(Integer.parseInt(trtd[1]));
+            String colKey = element.children().get(0).attr("keyname");
+            textdictInfo.setColKey(colKey);
+
+            TextdictInfo info = oldTextDictInfoMap.get(wbsTreePrivate.getProjectId() + wbsTreePrivate.getExcelId() + (colKey != null && colKey.contains("__") ? colKey.split("__")[0] : colKey) + sigRoleId);
+            if (info != null) {
+                textdictInfo.setId(info.getId());
+                updateList.add(textdictInfo);
+            } else {
+                addList.add(textdictInfo);
             }
             newTextDictInfos.add(textdictInfo);
             dqIds.append(textdictInfo.getId()).append( ",");
             String dqId = "";
-            if(keyMap.containsKey(keky)){
-                dqId = keyMap.get(keky)+"||"+textdictInfo.getId();
+            if(keyMap.containsKey(key)){
+                dqId = keyMap.get(key)+"||"+textdictInfo.getId();
             }else{
                 dqId=textdictInfo.getId()+"";
             }
-            keyMap.put(keky,dqId);
+            keyMap.put(key,dqId);
             element.removeAttr("dqId");
-            element.attr("dqId", keyMap.get(keky));
+            element.attr("dqId", keyMap.get(key));
             if (jsonObject.getInteger("type") == 2) { //个人签字 不能用户输入
                 if (element.html().indexOf("el-tooltip") >= 0) {
                     element.children().get(0).children().get(0).attr(":readonly", "true");
@@ -546,25 +712,54 @@ public class TextdictInfoController extends BladeController {
             }
         }
         File writeFile = new File(wbsTreePrivate.getHtmlUrl());
-//        File writeFile = new File("D:\\file\\downfile\\1792757075013533696.html");
         FileUtil.writeToFile(writeFile, doc.html(), Boolean.parseBoolean("UTF-8"));
-
         String str1 = wbsTreePrivate.getHtmlUrl().replace("Desktop//privateUrl", "Desktop/privateUrl");
         String replace = str1.replace("\\", "\\\\");
+        if (!oldTextDictInfos.isEmpty()) {
+            Set<Long> set = oldTextDictInfos.stream().map(TextdictInfo::getId).collect(Collectors.toSet());
+            // 先逻辑删除然后修改
+            this.textdictInfoService.update(Wrappers.<TextdictInfo>lambdaUpdate().eq(TextdictInfo::getProjectId, wbsTreePrivate.getProjectId())
+                    .eq(TextdictInfo::getExcelId, wbsTreePrivate.getExcelId()).in(TextdictInfo::getType, 2, 6).in(TextdictInfo::getId, set).set(TextdictInfo::getIsDeleted, 1));
+        }
+        if (!updateList.isEmpty()) {
+            for (TextdictInfo info : updateList) {
+                this.textdictInfoService.update(Wrappers.<TextdictInfo>lambdaUpdate().eq(TextdictInfo::getId, info.getId()).eq(TextdictInfo::getProjectId, info.getProjectId())
+                        .eq(TextdictInfo::getExcelId, info.getExcelId()).eq(TextdictInfo::getSigRoleId, info.getSigRoleId())
+                        .set(info.getName() != null ,TextdictInfo::getName, info.getName())
+                        .set(info.getType() != null ,TextdictInfo::getType, info.getType())
+                        .set(info.getColName() != null, TextdictInfo::getColName, info.getColName())
+                        .set(info.getSigRoleName() != null, TextdictInfo::getSigRoleName, info.getSigRoleName())
+                        .set(info.getPyzbx() != null, TextdictInfo::getPyzbx, info.getPyzbx())
+                        .set(info.getPyzby() != null, TextdictInfo::getPyzby, info.getPyzby())
+                        .set(info.getTimeColKey() != null, TextdictInfo::getTimeColKey, info.getTimeColKey())
+                        .set(info.getTimeName() != null, TextdictInfo::getTimeName, info.getTimeName())
+                        .set(info.getColKey() != null, TextdictInfo::getColKey, info.getColKey())
+                        .set(info.getTabId() != null,TextdictInfo::getTabId, info.getTabId())
+                        .set(info.getTimeState() != null ,TextdictInfo::getTimeState, info.getTimeState()).set(TextdictInfo::getIsDeleted, 0));
+            }
+        }
+        if (!addList.isEmpty()) {
+            this.textdictInfoService.saveBatch(addList);
+        }
 
         //修改同几点的数据
+        List<WbsTreePrivate> wbsTreePrivatesEqual = wbsTreePrivateMapper.selectList(Wrappers.<WbsTreePrivate>lambdaQuery()
+                .eq(WbsTreePrivate::getProjectId, wbsTreePrivate.getProjectId())
+                .eq(WbsTreePrivate::getIsDeleted, 0)
+                .eq(WbsTreePrivate::getExcelId, wbsTreePrivate.getExcelId()).eq(WbsTreePrivate::getHtmlUrl, wbsTreePrivate.getHtmlUrl()));
+        List<Long> pKeyIds = wbsTreePrivatesEqual.stream().map(WbsTreePrivate::getPKeyId).collect(Collectors.toList());
+        String ids = StringUtils.join(pKeyIds, ",");
         if(StringUtils.isNotBlank(ids)){
             String updateSqlP = "update m_wbs_tree_private set html_url = '" + replace + "' where p_key_id in ("+ids+") and project_id="+wbsTreePrivate.getProjectId()+"";
             jdbcTemplate.execute(updateSqlP);
         }
 
         //修改对应合同段的htmlUrl,当前项目下对应合同段的节点
-        List<Long> cIdsList = wbsTreePrivatesEqual.stream().map(WbsTreePrivate::getId).distinct().collect(Collectors.toList());
-
+        List<Long> cIdsList = wbsTreePrivatesEqual.stream().map(WbsTreePrivate::getPKeyId).distinct().collect(Collectors.toList());
         List<Long> cPkeyIds = wbsTreeContractService.getBaseMapper().selectList(Wrappers.<WbsTreeContract>lambdaQuery()
                 .eq(WbsTreeContract::getProjectId, wbsTreePrivate.getProjectId())
                 .eq(WbsTreeContract::getExcelId, wbsTreePrivate.getExcelId())
-                .in(WbsTreeContract::getId, cIdsList)).stream().map(WbsTreeContract::getPKeyId).collect(Collectors.toList());
+                .in(WbsTreeContract::getIsTypePrivatePid, cIdsList)).stream().map(WbsTreeContract::getPKeyId).collect(Collectors.toList());
         String cPkeyIdsStr = StringUtils.join(cPkeyIds, ",");
 
         if (StringUtils.isNotEmpty(cPkeyIdsStr)) {
@@ -572,18 +767,15 @@ public class TextdictInfoController extends BladeController {
             jdbcTemplate.execute(updateSqlC);
         }
         BladeUser user = AuthUtil.getUser();
-        DqOperationLog log = new DqOperationLog(wbsTreePrivate, user, "", 1, dataInfo.toJSONString(), JSON.toJSONString(oldTextdictInfos), JSON.toJSONString(newTextDictInfos));
+        DqOperationLog log = new DqOperationLog(wbsTreePrivate, user, "", 1, dataInfo.toJSONString(), JSON.toJSONString(oldTextDictInfos), JSON.toJSONString(newTextDictInfos));
         if (dqIds.length() > 1) {
             log.setBusinessId(dqIds.deleteCharAt(dqIds.length() - 1).toString());
         }
         dqOperationLogService.save(log);
         bladeRedis.set("save-eVis-lock:" + SecureUtil.getUserId(), "1");
         bladeRedis.expire("save-eVis-lock:" + SecureUtil.getUserId(), 3);
-
         return R.success("操作成功");
     }
-
-
     /**
      * 保存默认值
      */

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

@@ -1,5 +1,6 @@
 package org.springblade.manager.controller;
 
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import io.swagger.annotations.*;
 import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
@@ -9,9 +10,12 @@ import javax.validation.Valid;
 
 import org.springblade.core.mp.support.Condition;
 import org.springblade.core.mp.support.Query;
+import org.springblade.core.secure.utils.AuthUtil;
 import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.utils.Func;
+import org.springblade.core.tool.utils.StringUtil;
 import org.springblade.manager.dto.WbsInfoDTO;
+import org.springblade.manager.entity.ContractInfo;
 import org.springblade.manager.entity.WbsInfo;
 import org.springblade.manager.entity.WbsTree;
 import org.springblade.manager.entity.WbsTreePrivate;
@@ -26,6 +30,8 @@ import org.springblade.manager.wrapper.WbsInfoWrapper;
 import org.springblade.manager.service.IWbsInfoService;
 import org.springblade.core.boot.ctrl.BladeController;
 
+import java.util.ArrayList;
+import java.util.Date;
 import java.util.List;
 
 @RestController
@@ -67,7 +73,9 @@ public class WbsInfoController extends BladeController {
     @ApiOperationSupport(order = 2)
     @ApiOperation(value = "分页", notes = "传入wbsInfo")
     public R<IPage<WbsInfoVO>> list(WbsInfoDTO wbsInfo, Query query) {
-        IPage<WbsInfo> pages = wbsInfoService.page(Condition.getPage(query), Condition.getQueryWrapper(wbsInfo));
+        QueryWrapper<WbsInfo> wrapper = Condition.getQueryWrapper(wbsInfo);
+        wrapper.orderByAsc("sort");
+        IPage<WbsInfo> pages = wbsInfoService.page(Condition.getPage(query), wrapper);
         return R.data(WbsInfoWrapper.build().pageVO(pages));
     }
 
@@ -82,7 +90,7 @@ public class WbsInfoController extends BladeController {
             @ApiImplicitParam(name = "current", value = "当前页", required = true),
             @ApiImplicitParam(name = "size", value = "每页的数量", required = true)
     })
-    public R<IPage<WbsInfo>> page(WbsInfo wbsInfo, Query query) {
+    public R<IPage<WbsInfo>> page(WbsInfoDTO wbsInfo, Query query) {
         IPage<WbsInfo> pages = wbsInfoService.selectWbsInfoPage(Condition.getPage(query), wbsInfo);
         return R.data(pages);
     }
@@ -179,5 +187,35 @@ public class WbsInfoController extends BladeController {
         return R.status(wbsInfoService.tabNodeSort(Func.toStrList(primaryKeyIds)));
     }
 
+    /**
+     * 排序
+     */
+    @PostMapping("/sort")
+    @ApiOperationSupport(order = 9)
+    @ApiOperation(value = "排序", notes = "传入排序好的ids")
+    public R<Boolean> sort(@RequestBody List<Long> wbsInfoIds) {
+        int sort = 0;
+        if (wbsInfoIds == null || wbsInfoIds.isEmpty()) {
+            return R.data(false);
+        }
+        List<WbsInfo> updateList = new ArrayList<>(wbsInfoIds.size());
+        Long userId = AuthUtil.getUserId();
+        for (Long id : wbsInfoIds) {
+            WbsInfo temp = new WbsInfo();
+            temp.setSort(++sort);
+            temp.setUpdateUser(userId);
+            temp.setUpdateTime(new Date());
+            temp.setId(id);
+            updateList.add(temp);
+        }
+        try {
+            boolean result = wbsInfoService.updateBatchById(updateList);
+            return R.data(result);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return R.fail(200, "排序保存失败");
+        }
+    }
+
 
 }

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

@@ -538,8 +538,8 @@ public class WbsTreeController extends BladeController {
     @GetMapping("/getQueryValueByNodeType")
     @ApiOperationSupport(order = 21)
     @ApiOperation(value = "根据节点类型,内业资料类型查询节点数据", notes = "传入wbsId、projectId、nodeType、majorDataType")
-    public Object getQueryValueByNodeType(@RequestParam String wbsId, @RequestParam String projectId, @RequestParam String queryValue, @RequestParam(required = false,defaultValue = "6") Integer nodeType, @RequestParam(required = false, defaultValue = "-1") Integer majorDataType) {
-        Object result = wbsTreeService.getQueryValueByNodeType(wbsId, projectId, queryValue, nodeType, majorDataType);
+    public Object getQueryValueByNodeType(WbsTreePrivateQueryVO vo) {
+        Object result = wbsTreeService.getQueryValueByNodeType(vo);
         return R.data(result);
     }
 

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

@@ -31,6 +31,8 @@ import org.springblade.manager.mapper.WbsTreePrivateMapper;
 import org.springblade.manager.service.*;
 import org.springblade.manager.vo.*;
 import org.springblade.manager.wrapper.WbsTreePrivateWrapper;
+import org.springblade.system.cache.DictCache;
+import org.springblade.system.user.entity.User;
 import org.springframework.beans.BeanUtils;
 import org.springframework.jdbc.core.BeanPropertyRowMapper;
 import org.springframework.jdbc.core.JdbcTemplate;
@@ -386,6 +388,63 @@ public class WbsTreePrivateController extends BladeController {
         return R.fail(200, "未查询到数据");
     }
 
+    /**
+     * 查询当前节点下所有表单(根据节点ID查询当前表单)
+     */
+    @GetMapping("/get-group-node-tables")
+    @ApiOperationSupport(order = 3)
+    @ApiOperation(value = "查询当前节点下所有元素表并分类", notes = "传入父节点id、wbsId、projectId")
+    public R<List<WbsTreePrivateTableVO>> findAndGroupNodeTableByCondition(@RequestParam("parentId") String parentId,
+                                                            @RequestParam("wbsId") String wbsId,
+                                                            @RequestParam("projectId") String projectId) {
+        R<List<WbsNodeTableVO>> r = findNodeTableByCondition(parentId, wbsId, projectId);
+        List<WbsNodeTableVO> data = r.getData();
+        List<WbsTreePrivateTableVO> list = new ArrayList<>();
+        if (data != null && !data.isEmpty()) {
+            Integer wbsType = data.get(0).getWbsType();
+            Map<Integer, List<WbsNodeTableVO>> groupMap;
+            if (wbsType != null && wbsType == 1) {
+                groupMap = data.stream().collect(Collectors.groupingBy(vo -> {
+                    String tableOwner = vo.getTableOwner();
+                    if (StringUtil.isNumeric(tableOwner)) {
+                        int i = Integer.parseInt(tableOwner);
+                        if (i > 0 && i <= 3) {
+                            return 1;
+                        } else if (i > 3 && i <= 6) {
+                            return 2;
+                        }
+                    }
+                    return 3;
+                }));
+            } else if (wbsType != null && wbsType == 2) {
+                groupMap = data.stream().collect(Collectors.groupingBy(vo -> {
+                    String tableType = vo.getTableType();
+                    if (StringUtil.isNumeric(tableType)) {
+                        int i = Integer.parseInt(tableType);
+                        if (i == 1 ) {
+                            return 2;
+                        } else if (i == 2 ) {
+                            return 1;
+                        }
+                    }
+                    return 3;
+                }));
+            } else {
+                list.add(new WbsTreePrivateTableVO("", data));
+                return R.data(list);
+            }
+            String[][] titles = {{"施工方", "监理方", "其他"}, {"报告表", "记录表", "其他"}};
+            for (int i = 1; i <= 3; i++) {
+                List<WbsNodeTableVO> wbsNodeTableVOS = groupMap.get(i);
+                if (wbsNodeTableVOS != null && !wbsNodeTableVOS.isEmpty()) {
+                    list.add(new WbsTreePrivateTableVO(titles[wbsType - 1][i - 1], wbsNodeTableVOS));
+                }
+            }
+            return R.data(list);
+        }
+        return R.fail(200, "未查询到数据");
+    }
+
 
     @GetMapping("/remove-table")
     @ApiOperationSupport(order = 4)
@@ -450,7 +509,14 @@ public class WbsTreePrivateController extends BladeController {
         WbsTreePrivate detail = wbsTreePrivateService.getOne(Condition.getQueryWrapper(wbsTree));
         if (detail != null) {
             detail.setFullName(detail.getImportMatchingInfo());
-            return R.data(WbsTreePrivateWrapper.build().entityVO(detail));
+            WbsTreePrivateVO wbsTreePrivateVO = WbsTreePrivateWrapper.build().entityVO(detail);
+            if (detail.getUpdateUser() != null) {
+                List<User> users = jdbcTemplate.query("select name from blade_user where id = " + detail.getUpdateUser(), new BeanPropertyRowMapper<>(User.class));
+                if (!users.isEmpty()) {
+                    wbsTreePrivateVO.setUpdateUserName(users.get(0).getName());
+                }
+            }
+            return R.data(wbsTreePrivateVO);
         }
         return R.fail(200, "未查询到信息");
     }

+ 2 - 1
blade-service/blade-manager/src/main/java/org/springblade/manager/feign/ExcelTabClientImpl.java

@@ -22,6 +22,7 @@ import org.springblade.business.feign.ContractLogClient;
 import org.springblade.business.feign.EntrustInfoServiceClient;
 import org.springblade.business.feign.InformationQueryClient;
 import org.springblade.common.utils.CommonUtil;
+import org.springblade.manager.util.DataStructureFormatUtils;
 import org.springblade.common.utils.SnowFlakeUtil;
 import org.springblade.core.oss.model.BladeFile;
 import org.springblade.core.tool.api.R;
@@ -38,7 +39,6 @@ import org.springblade.manager.service.IWbsTreePrivateService;
 import org.springblade.manager.utils.ExcelInfoUtils;
 import org.springblade.manager.utils.FileUtils;
 import org.springblade.manager.utils.RandomNumberHolder;
-import org.springblade.manager.vo.AppWbsTreeContractVO;
 import org.springblade.manager.vo.TrialSelfDataRecordVO1;
 import org.springblade.resource.feign.NewIOSSClient;
 import org.springframework.jdbc.core.BeanPropertyRowMapper;
@@ -583,6 +583,7 @@ public class ExcelTabClientImpl implements ExcelTabClient {
                 List<Map<String, Object>> businessDataMap = this.jdbcTemplate.queryForList(querySql);
 
                 if (businessDataMap.size() > 0) {
+                    DataStructureFormatUtils.parseDataByKey(businessDataMap);
                     // 匹配关联
                     try {
                         if (tableNode2.getHtmlUrl()!=null) {

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

@@ -36,9 +36,9 @@ public class TableFileClientImpl implements TableFileClient {
     }
 
     @Override
-    public List<TableFile> getTabFilesByTabIds(String tabFileIds) {
+    public List<TableFile> getTabFilesByTabIds(List<String> tabFileIds) {
         return tableFileService.getBaseMapper().selectList(Wrappers.<TableFile>lambdaQuery()
-                .in(TableFile::getTabId, Func.toLongList(tabFileIds))
+                .in(TableFile::getTabId, tabFileIds)
                 .ne(TableFile::getType, 1) //排除源文件
                 .isNotNull(TableFile::getTabId)
         );

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

@@ -26,6 +26,11 @@ public class WbsParamClientImpl implements WbsParamClient{
         return iWbsParamService.getBaseMapper().selectOne(Wrappers.lambdaQuery(WbsParam.class).eq(WbsParam::getNodeId, nodeId).eq(WbsParam::getType, 200).eq(WbsParam::getIsDeleted, 0).eq(WbsParam::getK,"FILE_TITLE"));
     }
 
+    @Override
+    public void saveWbsParams(List<WbsParam> wbsParamList) {
+        iWbsParamService.saveBatch(wbsParamList);
+    }
+
     @Override
     public String createFileTitle(WbsTreeContract contract) {
         return iWbsParamService.createFileTitle(contract);

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

@@ -507,6 +507,9 @@ public class WbsTreeContractClientImpl implements WbsTreeContractClient {
     }
 
 
+
+
+
     @Override
     public void saveNameRuleByPkeyId(Long pKeyId, String s, Long projectId) {
         wbsTreeContractController.saveContractNameRule(s,pKeyId,projectId);

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

@@ -373,13 +373,13 @@
 
     <!-- 文件收集 归档树的文件数量 -->
     <select id="selectFileNumber" resultType="java.lang.Integer">
-        SELECT  count(0)  FROM m_archive_tree_contract a
+        SELECT  sum(b.file_page)  FROM m_archive_tree_contract a
         inner join u_archive_file b on b.node_id = a.id and b.is_deleted = a.is_deleted and b.project_id = a.project_id and (b.is_auto_file is null or b.is_auto_file != 1)
         WHERE  a.is_deleted = 0
         and a.project_id = #{projectId}
         <choose>
             <when test="extType != null and extType == 1">
-                and (b.node_id in( select id from  m_archive_tree_contract where FIND_IN_SET(#{id},ancestors) or a.id = #{id}) OR
+                and ( 	b.node_id in( select id from  m_archive_tree_contract where FIND_IN_SET(#{id},ancestors) or a.id = #{id}) OR
                 b.node_ext_id in(  select id from  m_archive_tree_contract where FIND_IN_SET(#{id},ancestors) or a.id = #{id}))
             </when>
             <otherwise>

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

@@ -121,7 +121,7 @@
     </delete>
 
     <select id="selectContractByProjectIds" resultMap="contractInfoResultMap">
-        select id, p_id, contract_name, contract_number, contract_type ,template_type from m_contract_info where is_deleted = 0 and
+        select id, p_id, contract_name, contract_number, contract_type ,template_type, sort from m_contract_info where is_deleted = 0 and
         p_id in
         <foreach collection="ids" item="pId" open="(" separator="," close=")">
             #{pId}

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

@@ -28,6 +28,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
 import org.springblade.manager.vo.ExcelTabWbsTypeVO;
 import org.springblade.manager.vo.WbsTreeVO;
 
+import java.util.Collection;
 import java.util.List;
 import java.util.Set;
 
@@ -79,4 +80,8 @@ public interface ExcelTabMapper extends BaseMapper<ExcelTab> {
     ExcelTab getWaterByTableId(@Param("id") Long excelId);
 
     List<WbsFormElement> getUnMatchField(@Param("tabId") Long tabId, @Param("set") Set<String> set);
+
+    List<ExcelTabVO> selectRootExcelTab(IPage<ExcelTabVO> page, @Param("projectId") Long projectId,@Param("rootIds") Collection<Long> rootIds);
+
+    List<ExcelTabVO> getByIds(Collection<Long> ids);
 }

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

@@ -194,7 +194,7 @@
         ORDER BY dept.create_time
     </select>
     <select id="selectExcelTabPage" resultType="org.springblade.manager.vo.ExcelTabVO">
-        select x.id,x.create_time,x.name,x.table_template_type,
+        select x.id,x.create_time,x.name,x.table_template_type,x.tab_type,
         (SELECT bdb.dict_value from blade_dict_biz bdb WHERE code = 'table_template_type' AND dict_key = x.table_template_type) as tableTemplateTypeName,
         (SELECT count(1) from m_excel_tab a where FIND_IN_SET(x.id,a.alias) and a.is_deleted = 0 and a.file_type=3) as
         tab_cout
@@ -202,6 +202,15 @@
         <if test="excelTab.name!=null and excelTab.name!=''">
             AND x.name like concat(concat('%', #{excelTab.name}),'%')
         </if>
+        <if test="param2.parentId == null or param2.parentId == 0">
+            <if test="param2.tabType != null">
+                AND x.tab_type = #{param2.tabType}
+            </if>
+            <if test="param2.tableTemplateType != null">
+                AND x.table_template_type = #{param2.tableTemplateType}
+            </if>
+        </if>
+        order by x.sort
     </select>
     <select id="getWaterByTableId" resultType="org.springblade.manager.entity.ExcelTab">
         select * from m_excel_tab met WHERE met.parent_id = 0 AND met.table_template_type = 2 AND met.is_deleted = 0
@@ -215,6 +224,31 @@
             #{item}
         </foreach>
     </select>
+    <select id="selectRootExcelTab" resultType="org.springblade.manager.vo.ExcelTabVO">
+        SELECT project_id as projectId, project_name as projectName, root_id as id from m_project_info a RIGHT JOIN  (
+            SELECT project_id, SUBSTRING_INDEX(alias,',',1) as root_id from m_wbs_tree_private a LEFT JOIN m_excel_tab b on a.excel_id = b.id where a.type = 2 and a.is_deleted =0 and a.excel_id is not null
+            <if test="projectId !=null and projectId > 0">
+                and project_id = #{projectId}
+            </if>
+            GROUP BY root_id,project_id
+            <if test="rootIds !=null">
+                and root_id in
+                <foreach collection="rootIds" item="item" open="(" separator="," close=")">
+                    #{item}
+                </foreach>
+            </if>
+        ) as t on a.id = t.project_id where project_id is not null
+    </select>
+    <select id="getByIds" resultType="org.springblade.manager.vo.ExcelTabVO">
+        select *, (select name from blade_user where id = a.create_user) as createUserName, (SELECT bdb.dict_value from blade_dict_biz bdb WHERE code = 'table_template_type' AND dict_key = a.table_template_type) as tableTemplateTypeName
+        from m_excel_tab a where is_deleted = 0
+        <if test="ids !=null">
+            and id in
+            <foreach collection="ids" item="item" open="(" separator="," close=")">
+                #{item}
+            </foreach>
+        </if>
+    </select>
 
 
     <delete id="removeBussTabInfoById">

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

@@ -5,6 +5,7 @@ import org.springblade.manager.entity.ProjectInfo;
 import org.springblade.manager.vo.ProjectInfoVO;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import org.springblade.manager.vo.ProjectInfoVO3;
 import org.springblade.manager.vo.ProjectUserAmountVO;
 import org.springblade.manager.vo.SingPfxManagementVO;
 
@@ -30,4 +31,5 @@ public interface ProjectInfoMapper extends BaseMapper<ProjectInfo> {
 
     ProjectInfo selectOneAndWbsTypeById(Long id);
 
+    IPage<ProjectInfoVO> pageList(IPage<ProjectInfoVO> page, @Param("vo") ProjectInfoVO3 vo);
 }

+ 38 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/ProjectInfoMapper.xml

@@ -153,5 +153,43 @@
         FROM m_project_info
         WHERE id = #{id}
     </select>
+    <select id="pageList" resultType="org.springblade.manager.vo.ProjectInfoVO">
+        select distinct a.*, if(b.id is null , 0, 1) as isCollect, (select name from blade_user where id = a.project_leader) as projectLeaderName from m_project_info a left join m_user_project_collect b
+            on a.id = b.project_id and b.user_id = #{vo.userId} and b.is_deleted = 0 where a.is_deleted = 0
+        <if test="vo.name != null and vo.name != ''">
+            and (a.project_name like concat('%',#{vo.name},'%') or a.project_alias like concat('%',#{vo.name},'%'))
+        </if>
+        <if test="vo.status != null">
+            and a.project_status = #{vo.status}
+        </if>
+        <if test="vo.isCollect != null and vo.isCollect == 1">
+            and b.id is not null
+        </if>
+        <choose>
+            <when test="vo.sort == 0">
+                order by
+                IF(b.sort is null, 999, b.sort),
+                a.sort,
+                a.create_time desc
+            </when>
+            <when test="vo.sort == 1">
+                order by
+                IF(b.sort is null, 999, b.sort),
+                a.sort,
+                a.create_time desc
+            </when>
+            <when test="vo.sort == 2">
+                order by
+                    b.create_time desc
+            </when>
+            <when test="vo.sort == 3">
+                order by
+                    if(a.project_leader = #{vo.userId}, 0, 1 ),
+                    IF(b.sort is null, 999, b.sort),
+                    a.sort,
+                    a.create_time desc
+            </when>
+        </choose>
+    </select>
 
 </mapper>

+ 13 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/TextdictInfoMapper.java

@@ -16,13 +16,16 @@
  */
 package org.springblade.manager.mapper;
 
+import org.apache.ibatis.annotations.Select;
 import org.springblade.manager.entity.TextdictInfo;
+import org.springblade.manager.entity.WbsTreePrivate;
 import org.springblade.manager.injector.EasyBaseMapper;
 import org.springblade.manager.vo.TextdictInfoVO;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import org.springframework.data.repository.query.Param;
 
+import java.util.Collection;
 import java.util.List;
 
 /**
@@ -51,7 +54,17 @@ public interface TextdictInfoMapper extends EasyBaseMapper<TextdictInfo> {
 
     TextdictInfo selectTextdictInfoOne(@Param("id") String id,@Param("sigRoleId") String sigRoleId,@Param("projectId") String projectId);
 
+    void updateHtmlUrl(@Param("htmlUrl") String htmlUrl,@Param("projectId") String projectId, @Param("excelId") Long pKeyId);
+
+    List<TextdictInfoVO> selectTextdictInfoByExcelIdAndColKey(@Param("excelId") String excelId, @Param("colKeys") Collection<String> colKeys);
+
+    List<TextdictInfoVO> selectTextDictInfoByIdAndColKeyAndColName(@Param("list") List<TextdictInfo> textdictInfos);
     //通过表单Id 获取电签信息
     List<TextdictInfoVO> getTextdictListInfoByPkeyId(@Param("tabId") String tabId,@Param("projectId") String projectId);
 
+    @Select("select * from m_textdict_info where project_id = #{treePrivate.projectId} and tab_id = #{treePrivate.pKeyId} and type in (2,6) and is_deleted = 0")
+    List<TextdictInfoVO> selectTextDictInfoByProjectIdAndTabId(IPage<TextdictInfoVO> page, @Param("treePrivate") WbsTreePrivate treePrivate);
+
+    @Select("SELECT * from m_textdict_info WHERE project_id = #{treePrivate.projectId} and excel_id = #{treePrivate.excelId} and type in (2,6) and is_deleted = 0 and (SELECT 1 from m_wbs_tree_private WHERE p_key_id = tab_id and html_url = #{treePrivate.htmlUrl}) = 1")
+    List<TextdictInfoVO> selectTextdictInfoByExcelIdAndProjectIdAndHtmlUrl(IPage<TextdictInfoVO> page,@Param("treePrivate") WbsTreePrivate treePrivate);
 }

+ 15 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/TextdictInfoMapper.xml

@@ -65,6 +65,21 @@
             and sig_role_id = #{sigRoleId}
             and project_id= #{projectId}
     </select>
+    <select id="selectTextdictInfoByExcelIdAndColKey" resultMap="textdictInfoVoResultMap">
+        SELECT * from m_textdict_info where is_deleted = 0 and type in('2','6') and excel_id = #{excelId} and is_deleted = 0
+        <foreach collection="colKeys" item="key" separator="," open=" and col_key in ( " close=" )" >
+            #{key}
+        </foreach>
+    </select>
+    <select id="selectTextDictInfoByIdAndColKeyAndColName" resultMap="textdictInfoVoResultMap">
+        select * from m_textdict_info where is_deleted = 0
+        <foreach collection="list" item="item" separator="," open=" and (id,col_key) in ( " close=")">
+            (#{item.id},#{item.colKey})
+        </foreach>
+    </select>
+    <update id="updateHtmlUrl">
+        update m_wbs_tree_contract set html_url = #{htmlUrl} where type = 2 and project_id = #{projectId} and is_type_private_pid = #{pKeyId};
+    </update>
 
     <select id="getTextdictListInfoByPkeyId" resultMap="textdictInfoVoResultMap">
         SELECT a.* from m_textdict_info a where 1=0

+ 12 - 2
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsFormElementMapper.xml

@@ -167,10 +167,20 @@
         SELECT data_type FROM information_schema.columns WHERE table_name=#{initTableName} AND column_name = #{eKey}
     </select>
     <select id="selectFiledLength" resultType="java.util.Map">
-        select column_name `key`,character_octet_length length from INFORMATION_SCHEMA.COLUMNS  where table_name = #{initTableName}
+        select column_name `key`,character_maximum_length length from INFORMATION_SCHEMA.COLUMNS  where table_name = #{initTableName}
     </select>
     <select id="selectFiledDataMaxLength" resultType="java.lang.Integer">
-        select MAX(LENGTH(${key})) from ${tableName}
+        select IFNULL(MAX(CHAR_LENGTH(${key})),0) from ${tableName}
+    </select>
+    <select id="selectSumColumnLength" resultType="java.lang.Integer">
+        SELECT
+            SUM( CHARACTER_MAXIMUM_LENGTH )
+        FROM
+            information_schema.COLUMNS
+        WHERE
+            TABLE_SCHEMA = #{database}
+            AND TABLE_NAME = #{tableName}
+            AND DATA_TYPE = 'varchar'
     </select>
     <select id="selectSumColumnLength" resultType="java.lang.Integer">
         SELECT

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

@@ -2,13 +2,15 @@ package org.springblade.manager.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import io.lettuce.core.dynamic.annotation.Param;
+import org.springblade.manager.dto.WbsInfoDTO;
 import org.springblade.manager.entity.WbsInfo;
 
 import java.util.List;
 
 public interface WbsInfoMapper extends BaseMapper<WbsInfo> {
 
-    List<WbsInfo> selectWbsInfoPage(IPage page, WbsInfo wbsInfo);
+    List<WbsInfoDTO> selectWbsInfoPage(IPage page, @Param("wbsInfo") WbsInfo wbsInfo);
 
     List<WbsInfo> selectAll(Integer type);
 

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

@@ -14,6 +14,7 @@
         <result column="is_deleted" property="isDeleted"/>
         <result column="wbs_name" property="wbsName"/>
         <result column="wbs_type" property="wbsType"/>
+        <result column="sort" property="sort"/>
     </resultMap>
     <resultMap id="resultMap2" type="org.springblade.manager.vo.WbsInfoVO">
         <result column="id" property="id"/>
@@ -42,7 +43,7 @@
         GROUP BY
         wbs_name
         ORDER BY
-        create_time
+        sort,create_time
     </select>
 
     <select id="selectById2" resultMap="wbsInfoResultMap">

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

@@ -377,7 +377,12 @@
                 m_wbs_tree_private
                 WHERE
                 parent_id = d.id and is_deleted = 0 and type != 2
-            ) AS "has_children"
+            ) AS "has_children",
+            d.update_time AS "updateTime",
+            d.update_user AS "updateUser",
+            d.unique_code AS "uniqueCode",
+            d.partition_code AS "partitionCode",
+            (select name from blade_user where id = d.update_user) AS "updateUserName"
         FROM
             m_wbs_tree_private d
         WHERE
@@ -514,6 +519,7 @@
                wt.sort,
                wt.status,
                wt.node_type                                                                         AS nodeType,
+               wt.wbs_type                                                                          AS wbsType,
                wt.fill_rate                                                                         AS "fillRate",
                wt.html_url                                                                          AS htmlUrl,
                (SELECT count(1)

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

@@ -19,6 +19,7 @@ package org.springblade.manager.service;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import org.apache.ibatis.annotations.Param;
 import org.jsoup.nodes.Document;
 import org.springblade.business.dto.TrialSelfInspectionRecordDTO;
 import org.springblade.core.mp.base.BaseService;
@@ -222,4 +223,6 @@ public interface IExcelTabService extends BaseService<ExcelTab> {
     void expailHtmlInfo(String thmlUrl, Long id, String s) throws Exception ;
 
     R batchAddNumbers(BatchAddNumbersDTO dto) throws Exception;
+
+    ExcelTabVO templateDetail(Long id);
 }

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

@@ -27,4 +27,5 @@ public interface IProjectInfoService extends BaseService<ProjectInfo> {
 
     Long getProjectIdbyName(String projectName);
 
+    IPage<ProjectInfoVO> pageList(IPage<ProjectInfoVO> page, ProjectInfoVO3 vo);
 }

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

@@ -12,6 +12,7 @@ import org.springblade.manager.vo.WbsFormElementVO3;
 import org.springblade.system.vo.RoleVO;
 import org.springblade.system.vo.RoleVO2;
 
+import java.util.Collection;
 import java.util.List;
 
 public interface ISignConfigService extends BaseService<SignConfig> {
@@ -30,5 +31,5 @@ public interface ISignConfigService extends BaseService<SignConfig> {
 
     List<TableInfo> tableList(Integer tableType, String name);
 
-    List<TextdictInfoVO> hasSignConfig(String initTableName, List<String> keys, TextdictInfoVO vo);
+    List<TextdictInfoVO> hasSignConfig(String initTableName, Collection<String> keys, TextdictInfoVO vo);
 }

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

@@ -11,7 +11,7 @@ import java.util.List;
 
 public interface IWbsInfoService extends BaseService<WbsInfo> {
 
-    IPage<WbsInfo> selectWbsInfoPage(IPage<WbsInfo> page, WbsInfo wbsInfo);
+    IPage<WbsInfo> selectWbsInfoPage(IPage<WbsInfo> page, WbsInfoDTO wbsInfo);
 
     List<WbsInfo> findByWbsType(String type);
 

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

@@ -113,4 +113,6 @@ public interface IWbsTreeContractService extends BaseService<WbsTreeContract> {
     R<List<WbsTreeContract>> getSiblingWbsContract(Long pKeyId);
 
     R moveNode(MoveNodeDTO dto);
+
+    List<WbsTreeContract> queryListByPIds(List<Long> pIds);
 }

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

@@ -80,5 +80,5 @@ public interface IWbsTreeService extends BaseService<WbsTree> {
 
     List<WbsTreePrivate> getTitleRange(String projectId);
 
-    Object getQueryValueByNodeType(String wbsId, String projectId, String queryValue, Integer nodeType, Integer majorDataType);
+    Object getQueryValueByNodeType(WbsTreePrivateQueryVO vo);
 }

+ 431 - 223
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ExcelTabServiceImpl.java

@@ -11,6 +11,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.mixsmart.utils.FormulaUtils;
 import com.mixsmart.utils.ListUtils;
 import com.mixsmart.utils.RegexUtils;
@@ -33,7 +34,9 @@ import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 import org.jsoup.Jsoup;
 import org.jsoup.nodes.Document;
 import org.jsoup.nodes.Element;
+import org.jsoup.nodes.Entities;
 import org.jsoup.nodes.Node;
+import org.jsoup.parser.Parser;
 import org.jsoup.select.Elements;
 import org.springblade.business.dto.TrialSeleInspectionRecordBaseInfoDTO;
 import org.springblade.business.dto.TrialSelfInspectionRecordDTO;
@@ -45,6 +48,7 @@ import org.springblade.business.feign.TrialSelfInspectionRecordClient;
 import org.springblade.business.vo.SaveContractLogVO;
 import org.springblade.common.constant.CommonConstant;
 import org.springblade.common.utils.CommonUtil;
+import org.springblade.manager.util.DataStructureFormatUtils;
 import org.springblade.common.utils.SnowFlakeUtil;
 import org.springblade.common.vo.DataVO;
 import org.springblade.core.log.exception.ServiceException;
@@ -54,7 +58,6 @@ import org.springblade.core.mp.support.Query;
 import org.springblade.core.oss.model.BladeFile;
 import org.springblade.core.secure.BladeUser;
 import org.springblade.core.secure.utils.AuthUtil;
-import org.springblade.core.secure.utils.SecureUtil;
 import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.node.ForestNodeMerger;
 import org.springblade.core.tool.utils.DateUtil;
@@ -72,15 +75,14 @@ import org.springblade.manager.mapper.ExcelTabMapper;
 import org.springblade.manager.service.*;
 import org.springblade.manager.utils.*;
 import org.springblade.manager.vo.*;
+import org.springblade.manager.wrapper.ExcelTabWrapper;
 import org.springblade.resource.feign.NewIOSSClient;
 import org.springblade.system.cache.ParamCache;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Lazy;
 import org.springframework.dao.DataAccessException;
 import org.springframework.data.redis.core.StringRedisTemplate;
 import org.springframework.jdbc.core.BeanPropertyRowMapper;
 import org.springframework.jdbc.core.JdbcTemplate;
-import org.springframework.jdbc.core.RowCallbackHandler;
 import org.springframework.jdbc.datasource.DataSourceTransactionManager;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
@@ -92,7 +94,6 @@ import org.springframework.transaction.support.DefaultTransactionDefinition;
 import java.io.*;
 import java.net.HttpURLConnection;
 import java.net.URL;
-import java.nio.file.Files;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.util.*;
@@ -135,9 +136,10 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
     private final TableInfoServiceImpl tableInfoService;
     private final INodeBaseInfoService nodeBaseInfoService;
     private final TrialSelfInspectionRecordClient trialSelfInspectionRecordClient;
+    private final WbsTreeContractOldHtmlService wbsTreeContractOldHtmlService;
+
     // excel 解析结构
     private final IExctabCellService exctabCellService;
-    private final WbsTreeContractOldHtmlService wbsTreeContractOldHtmlService;
 
 
     @Autowired
@@ -145,7 +147,79 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
 
     @Override
     public IPage<ExcelTabVO> selectExcelTabPage(IPage<ExcelTabVO> page, ExcelTabVO excelTab) {
-        return page.setRecords(baseMapper.selectExcelTabPage(page, excelTab));
+        if (excelTab.getProjectId() != null && excelTab.getProjectId() > 0 && (excelTab.getParentId() == null || excelTab.getParentId() == 0)) {
+            List<ExcelTabVO> records  = baseMapper.selectRootExcelTab(page, excelTab.getProjectId(), null);
+            if (!records.isEmpty()) {
+                List<Long> ids = records.stream().map(ExcelTabVO::getId).collect(Collectors.toList());
+                List<ExcelTabVO> excelTabs = this.baseMapper.getByIds(ids);
+                Map<Long, ExcelTabVO> map = excelTabs.stream().collect(toMap(ExcelTabVO::getId, v -> v));
+                records.forEach(v -> {
+                    ProjectInfoVO1 projectInfoVO1 = new ProjectInfoVO1();
+                    projectInfoVO1.setProjectId(v.getProjectId());
+                    projectInfoVO1.setProjectName(v.getProjectName());
+                    if (map.get(v.getId()) != null) {
+                        BeanUtil.copyProperties(map.get(v.getId()), v);
+                    }
+                    v.setProjectInfoList(Collections.singletonList(projectInfoVO1));
+                });
+            }
+            return page.setRecords(records);
+        }
+        List<ExcelTabVO> records = baseMapper.selectExcelTabPage(page, excelTab);
+        if (!records.isEmpty() && (excelTab.getParentId() == null || excelTab.getParentId() == 0)) {
+            Set<Long> set = records.stream().map(ExcelTabVO::getId).collect(Collectors.toSet());
+            List<ExcelTabVO> projectInfoList  = baseMapper.selectRootExcelTab(new Page<>(), null, set);
+            Map<Long, List<ExcelTabVO>> collect = projectInfoList.stream().collect(Collectors.groupingBy(ExcelTabVO::getId));
+            records.forEach(v -> {
+                List<ExcelTabVO> excelTabVOS = collect.get(v.getId());
+                if (excelTabVOS != null) {
+                    List<ProjectInfoVO1> list = excelTabVOS.stream().map(vo -> {
+                        ProjectInfoVO1 projectInfoVO1 = new ProjectInfoVO1();
+                        projectInfoVO1.setProjectId(vo.getProjectId());
+                        projectInfoVO1.setProjectName(vo.getProjectName());
+                        return projectInfoVO1;
+                    }).collect(Collectors.toList());
+                    v.setProjectInfoList(list);
+                }
+            });
+        }
+        return page.setRecords(records);
+    }
+
+    @Override
+    public ExcelTabVO templateDetail(Long id) {
+        List<ExcelTabVO> excelTabVOs = this.baseMapper.getByIds(Collections.singleton(id));
+        if (excelTabVOs == null || excelTabVOs.isEmpty()) {
+            return new ExcelTabVO();
+        }
+        ExcelTabVO excelTabVO = excelTabVOs.get(0);
+        if (excelTabVO == null || (excelTabVO.getParentId() != null && excelTabVO.getParentId() > 0)) {
+            return excelTabVO;
+        }
+        Map<String, Object> map = jdbcTemplate.queryForMap("SELECT count(a.id) as total,count(t.id) as useNum from m_excel_tab a LEFT JOIN ( select excel_id as id from m_wbs_tree_private where type = 2 and is_deleted = 0 and excel_id is not null GROUP BY excel_id ) as t " +
+                "on a.id = t.id where a.is_deleted = 0 and file_type = 3 and alias like '" + id + "%'");
+        if (map.get("total") == null) {
+            excelTabVO.setTabCout(0);
+        } else {
+            excelTabVO.setTabCout(Integer.parseInt(map.get("total").toString()));
+        }
+        if (map.get("useNum") == null) {
+            excelTabVO.setExcelUseNumber(0);
+        } else {
+            excelTabVO.setExcelUseNumber(Integer.parseInt(map.get("useNum").toString()));
+        }
+        List<ExcelTabVO> projectInfoList  = baseMapper.selectRootExcelTab(new Page<>(), null, Collections.singleton(id));
+        if (projectInfoList != null && !projectInfoList.isEmpty()) {
+            List<ProjectInfoVO1> list = projectInfoList.stream().map(vo -> {
+                ProjectInfoVO1 projectInfoVO1 = new ProjectInfoVO1();
+                projectInfoVO1.setProjectId(vo.getProjectId());
+                projectInfoVO1.setProjectName(vo.getProjectName());
+                return projectInfoVO1;
+            }).collect(Collectors.toList());
+            excelTabVO.setProjectInfoList(list);
+            excelTabVO.setProjectUseNumber(list.size());
+        }
+        return excelTabVO;
     }
 
     @Override
@@ -738,19 +812,20 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
             String tabName = tableNode.getInitTableName();
 
             //拼接SQL
-            StringBuilder sql = new StringBuilder("INSERT INTO " + tabName),
-                    keySql = new StringBuilder("id, group_id"),
-                    valSql = new StringBuilder("" + tableInfo.getBusinessId() + ", " + tableInfo.getPkeyId());
+//            StringBuilder sql = new StringBuilder("INSERT INTO " + tabName),
+//                    keySql = new StringBuilder("id, group_id"),
+//                    valSql = new StringBuilder("" + tableInfo.getBusinessId() + ", " + tableInfo.getPkeyId());
 
             //参数
             LinkedHashMap<String, String> dataMap2 = tableInfo.getDataMap();
-            updateFieldLength(tabName, dataMap2);
-            for (String key : dataMap2.keySet()) {
-                keySql.append(", ").append(key);
-                valSql.append(", '").append(dataMap2.get(key)).append("'");
-            }
-
-            sql.append("(").append(keySql).append(")").append(" values(").append(valSql).append(")");
+            dataMap2.remove("p_key_id");
+            StringBuilder sql = buildMTableInsertSql(tabName, dataMap2, tableInfo.getBusinessId(), tableInfo.getPkeyId(), null);
+//            for (String key : dataMap2.keySet()) {
+//                keySql.append(", ").append(key);
+//                valSql.append(", '").append(dataMap2.get(key)).append("'");
+//            }
+//
+//            sql.append("(").append(keySql).append(")").append(" values(").append(valSql).append(")");
 
             //新增数据
             try {
@@ -1015,19 +1090,43 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
         Document doc = Jsoup.parse(htmlString);
         Element table = doc.select("table").first();
         Elements td = table.select("td");
-        Set<String> set = new HashSet<>();
+        Map<String, String> set = new HashMap<>();
         for (Element element : td) {
             if (element.childNodes().size() >= 2) {
                 String title = element.childNodes().get(1).attr("placeholder");
                 if (StringUtils.isNotBlank(title)) {
-                    set.add(title);
+                    if (title.contains("&")) {
+                        // 处理 &lt; 之类的转义字符
+                        if (title.contains("&amp;")) {
+                            title = Parser.unescapeEntities(title, false);
+                        }
+                        title = Parser.unescapeEntities(title, false);
+                    }
+                    set.put(title, title);
                 }
             }
         }
         //获取未匹配的字段
         List<WbsFormElement> list = new ArrayList<>();
         if (set != null && set.size() > 0) {
-            list = baseMapper.getUnMatchField(tabId, set);
+//            list = baseMapper.getUnMatchField(tabId, set);
+            List<WbsFormElement> elements = jdbcTemplate.query("select * from m_wbs_form_element where f_id = ? and is_deleted = 0", new Object[]{tabId}, new BeanPropertyRowMapper<>(WbsFormElement.class));
+            elements.forEach(wbsFormElement -> {
+                String name = wbsFormElement.getEName();
+                if (StringUtils.isNotBlank(name)) {
+                    if (name.contains("&")) {
+                        // 处理 &lt; 之类的转义字符
+                        if (name.contains("&amp;")) {
+                            name = Parser.unescapeEntities(name, false);
+                        }
+                        name = Parser.unescapeEntities(name, false);
+                    }
+                }
+                if (set.containsKey(name)) {
+                    return;
+                }
+                list.add(wbsFormElement);
+            });
         }
         return list;
     }
@@ -1116,18 +1215,17 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                         for (TableInfo tableInfo : tableInfoList) {
                             //获取字段信息
                             LinkedHashMap<String, String> dataMap2 = tableInfo.getDataMap();
-                            updateFieldLength(table.getTabEnName(),dataMap2);
-                            //拼接SQL
-                            StringBuilder sql = new StringBuilder("INSERT INTO " + table.getTabEnName()),
-                                    keySql = new StringBuilder("id, group_id"),
-                                    valSql = new StringBuilder("" + SnowFlakeUtil.getId() + ", " + firstId);
-
-                            for (String key : dataMap2.keySet()) {
-                                keySql.append(", ").append(key);
-                                valSql.append(", '").append(dataMap2.get(key)).append("'");
-                            }
-
-                            sql.append("(").append(keySql).append(")").append(" values(").append(valSql).append(")");
+                            StringBuilder sql = buildMTableInsertSql(table.getTabEnName(), dataMap2, SnowFlakeUtil.getId(), firstId, null);
+//                            // 拼接SQL
+//                            StringBuilder sql = new StringBuilder("INSERT INTO " + table.getTabEnName()),
+//                                    keySql = new StringBuilder("id, group_id"),
+//                                    valSql = new StringBuilder("" + SnowFlakeUtil.getId() + ", " + firstId);
+//                            for (String key : dataMap2.keySet()) {
+//                                keySql.append(", ").append(key);
+//                                valSql.append(", '").append(dataMap2.get(key)).append("'");
+//                            }
+//
+//                            sql.append("(").append(keySql).append(")").append(" values(").append(valSql).append(")");
 
                             //新增数据
                             try {
@@ -1244,21 +1342,21 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                     String delSql = "delete from " + tabName + " where p_key_id=" + tableInfo.getPkeyId();
                     String sqlInfo = "";
                     LinkedHashMap<String, String> dataMap2 = tableInfo.getDataMap();
-                    updateFieldLength(tabName, dataMap2);
                     /*检查发现有p_key_id缺失的情况,导致表单数据丢失,所以强制覆盖*/
                     dataMap2.put("p_key_id", tableInfo.getPkeyId());
+                    sqlInfo = buildMTableInsertSql(tabName, dataMap2, SnowFlakeUtil.getId(), null, null).toString();
                     //统计保存的字段
 
-                    sqlInfo = "INSERT INTO " + tabName + " ( ";
-                    String keyStr = "id,";
-                    String valStr = SnowFlakeUtil.getId() + ",";
-                    for (String keys : dataMap2.keySet()) {
-                        keyStr += keys + ",";
-                        valStr += "'" + dataMap2.get(keys) + "',";
-                    }
-                    keyStr = keyStr.substring(0, keyStr.lastIndexOf(","));
-                    valStr = valStr.substring(0, valStr.lastIndexOf(","));
-                    sqlInfo = sqlInfo + keyStr + ") VALUES (" + valStr + ")";
+//                    sqlInfo = "INSERT INTO " + tabName + " ( ";
+//                    String keyStr = "id,";
+//                    String valStr = SnowFlakeUtil.getId() + ",";
+//                    for (String keys : dataMap2.keySet()) {
+//                        keyStr += keys + ",";
+//                        valStr += "'" + dataMap2.get(keys) + "',";
+//                    }
+//                    keyStr = keyStr.substring(0, keyStr.lastIndexOf(","));
+//                    valStr = valStr.substring(0, valStr.lastIndexOf(","));
+//                    sqlInfo = sqlInfo + keyStr + ") VALUES (" + valStr + ")";
 
                     WbsTreeContract wbsTreeContractByP = wbsTreeContractService.getBaseMapper().selectOne(Wrappers.<WbsTreeContract>query().lambda()
                             .eq(WbsTreeContract::getId, wbsTreeContract.getParentId()).eq(WbsTreeContract::getContractId, tableInfo.getContractId()));
@@ -1342,7 +1440,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                 //保存操作记录
                 this.operationLogClient.saveUserOperationLog(1, "资料填报", "工序填报页面", json);
                 // 更新redis
-                informationQueryClient.AsyncWbsTree(wbsTreeContractByP.getParentId() + "", wbsTreeContractByP.getParentId() + "", wbsTreeContractByP.getContractId(), "", "1");
+//                informationQueryClient.AsyncWbsTree(wbsTreeContractByP.getParentId() + "", wbsTreeContractByP.getParentId() + "", wbsTreeContractByP.getContractId(), "", "1");
             } catch (Exception e) {
                 e.printStackTrace();
                 return R.fail("操作失败");
@@ -1354,60 +1452,6 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
        return R.data(tableInfoList2);
        // return R.success(fileName1);
     }
-
-    public void updateFieldLength(String tableName, Map<String, String> fieldNameAndLengthMap) {
-        if (fieldNameAndLengthMap == null || fieldNameAndLengthMap.isEmpty()) {
-            return;
-        }
-        String fields = fieldNameAndLengthMap.keySet().stream().filter(key -> !key.equals("id") && !key.equals("p_key_id") && !key.equals("group_id")).map(key -> "'" + key + "'").collect(Collectors.joining(","));
-        if (fields.isEmpty()) {
-            return;
-        }
-        List<Map<String, Object>> fieldMap = jdbcTemplate.queryForList("select distinct COLUMN_NAME as fieldName, CHARACTER_MAXIMUM_LENGTH as fieldLength from information_schema.COLUMNS where  TABLE_NAME = '" + tableName +
-                "' and COLUMN_NAME in (" + fields + ")");
-        Map<String, Integer> map = fieldMap.stream().collect(toMap(k -> k.get("fieldName") + "", v -> {
-            try {
-                return Integer.parseInt(v.get("fieldLength") + "");
-            } catch (Exception e) {
-                return 0;
-            }
-        }, Math::max));
-
-        List<WbsFormElement> elementList = jdbcTemplate.query("SELECT id,e_key,e_length from m_wbs_form_element WHERE f_id = (SELECT id from m_table_info WHERE tab_en_name = '" + tableName
-                        +"' and is_deleted = 0  limit 1) and is_deleted = 0 and e_key in ( " +  fields + ")", new BeanPropertyRowMapper<>(WbsFormElement.class));
-        StringBuilder sql = new StringBuilder();
-        sql.append("alter table ").append(tableName);
-        elementList.forEach(element -> {
-            String data = fieldNameAndLengthMap.get(element.getEKey());
-            Integer fieldLength = map.get(element.getEKey());
-            if (data != null && element.getELength() != null && data.length() > fieldLength) {
-                int length = data.length();
-                // 取整
-                length = (length / 10 + 1) * 10;
-                if (length < element.getELength()) {
-                    length = element.getELength();
-                    element.setELength(null);
-                } else {
-                    element.setELength(length);
-                }
-                sql.append(" modify column ").append(element.getEKey()).append(" ").append("varchar").append("(").append(length).append("),");
-            }
-        });
-        if (sql.indexOf("modify") > 0) {
-            sql.deleteCharAt(sql.length() - 1);
-            TransactionStatus transactionStatus = this.beginTransaction(transactionManager1);
-            try {
-                jdbcTemplate.batchUpdate("update m_wbs_form_element set e_length = ? where id = ?", elementList.stream().filter(element -> element.getELength() != null).map(element -> new Object[]{element.getELength(), element.getId()}).collect(Collectors.toList()));
-                jdbcTemplate.execute(sql.toString());
-                transactionManager1.commit(transactionStatus);
-            } catch (Exception e) {
-                transactionManager1.rollback(transactionStatus);
-                log.error("更新字段长度失败, error: " + e.getMessage());
-                throw new ServiceException("字段长度超出限制, 系统无法进行扩容,请尝试缩小字段长度或者联系系统管理员处理");
-            }
-        }
-    }
-
     public String reason(String log) {
         /*保存的时候错误提示例如:字段过短提示 yangyj*/
         StringBuilder sb = new StringBuilder();
@@ -1428,6 +1472,103 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
         }
         return sb.append("保存异常,请联系管理员").toString();
     }
+    public StringBuilder buildMTableInsertSql(String tabName, Map<String, String> dataMap2, Object id, Object groupId, Object pKeyId) {
+        if (dataMap2 == null || dataMap2.isEmpty() || tabName == null || tabName.isEmpty()) {
+            return new StringBuilder();
+        }
+        //拼接SQL
+        StringBuilder sql = new StringBuilder("INSERT INTO " + tabName),
+                keySql = new StringBuilder(),
+                valSql = new StringBuilder();
+        if (id == null) {
+            if (dataMap2.containsKey("id")) {
+                id = dataMap2.get("id");
+            }
+        }
+        keySql.append("id");
+        valSql.append(id == null ? SnowFlakeUtil.getId() : id);
+        if (groupId ==  null) {
+            groupId = dataMap2.get("group_id");
+        }
+        if (groupId != null) {
+            keySql.append(", group_id");
+            valSql.append(", ").append(groupId);
+        }
+        if (pKeyId == null) {
+            pKeyId = dataMap2.get("p_key_id");
+        }
+        if (pKeyId != null) {
+            keySql.append(", p_key_id");
+            valSql.append(", ").append(pKeyId);
+        }
+        //参数
+        Map<String, String> opsParamMap = new HashMap<>();
+        dataMap2.remove("id");
+        dataMap2.remove("group_id");
+        dataMap2.remove("p_key_id");
+        String fields = dataMap2.keySet().stream().map(key -> "'" + key + "'").collect(Collectors.joining(","));
+        Map<String, Integer> map = new HashMap<>();
+        if (!fields.isEmpty()) {
+            try {
+                fields = fields + ", 'key_201'";
+                List<Map<String, Object>> fieldMap = jdbcTemplate.queryForList("select distinct COLUMN_NAME as fieldName, CHARACTER_MAXIMUM_LENGTH as fieldLength from information_schema.COLUMNS where  TABLE_NAME = '" + tabName +
+                        "' and COLUMN_NAME in (" + fields + ")");
+                map = fieldMap.stream().collect(toMap(k -> k.get("fieldName") + "", v -> {
+                    try {
+                        return Integer.parseInt(v.get("fieldLength") + "");
+                    } catch (Exception e) {
+                        return 0;
+                    }
+                }, Math::min));
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+        for (String key : dataMap2.keySet()) {
+            String[] split = key.split("_");
+            if (split.length > 1 && Integer.parseInt(split[1]) > 80) {
+                // 大于80则保留在扩展字段中
+                opsParamMap.put(key, dataMap2.get(key));
+            } else {
+                String value = dataMap2.get(key);
+                if (value != null) {
+                    Integer i = map.get(key);
+                    // 长度超过数据库长度也保留在扩展字段中
+                    if (i != null &&  value.length() > i) {
+                        opsParamMap.put(key, dataMap2.get(key));
+                        continue;
+                    }
+                }
+                keySql.append(", ").append(key);
+                valSql.append(", '").append(value).append("'");
+            }
+        }
+        if (!opsParamMap.isEmpty()) {
+            keySql.append(", key_201");
+            String data = DataStructureFormatUtils.buildData(opsParamMap);
+            try {
+                if (!map.containsKey( "key_201")) {
+                    jdbcTemplate.execute("alter table " + tabName + " add column key_201 text");
+                } else  {
+                    Integer i = map.get("key_201");
+                    if (data.length() > i) {
+                        if (i < 10000) {
+                            // 65535 byte
+                            jdbcTemplate.execute("alter table " + tabName + " modify column key_201 text");
+                        }else {
+                            // 16777215 byte
+                            jdbcTemplate.execute("alter table " + tabName + " modify column key_201 mediumtext");
+                        }
+                    }
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+            valSql.append(", '").append(data).append("'");
+        }
+        sql.append("(").append(keySql).append(")").append(" values(").append(valSql).append(")");
+        return sql;
+    }
 
     // 获取用户
     @Override
@@ -1690,6 +1831,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
 
         if (dataIn != null && dataIn.size() >= 1) {
             Map<String, Object> mysqlData = dataIn.get(0);
+            DataStructureFormatUtils.parseDataByKey(mysqlData);
             for (String key : mysqlData.keySet()) {
                 String tabVal = mysqlData.get(key) + "";
                 // 时间段处理
@@ -1979,6 +2121,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
 
         if (dataIn != null && dataIn.size() >= 1) {
             Map<String, Object> mysqlData = dataIn.get(0);
+            DataStructureFormatUtils.parseDataByKey(mysqlData);
             for (String key : mysqlData.keySet()) {
                 String tabVal = mysqlData.get(key) + "";
                 // 时间段处理
@@ -3070,6 +3213,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                 reData1=new HashMap<>(reData);
                 if (dataIn.size() >= 1) {
                     Map<String, Object> mysqlData = dataIn.get(0);
+                    DataStructureFormatUtils.parseDataByKey(mysqlData);
                     for (String key : mysqlData.keySet()) {
                         String tabVal = mysqlData.get(key) + "";
 
@@ -3351,6 +3495,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
 
         if (dataIn.size() >= 1) {
             Map<String, Object> mysqlData = dataIn.get(0);
+            DataStructureFormatUtils.parseDataByKey(mysqlData);
             for (String key : mysqlData.keySet()) {
                 String tabVal = mysqlData.get(key) + "";
 
@@ -3793,37 +3938,65 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                         }
                     }
                 }
+            }
+        }
+        // 组装电签设置
+        Elements dqids = table.getElementsByAttribute("dqid");
+        // 电签组装2
+        String dqSql = "select e_key,GROUP_CONCAT(DISTINCT concat('*✹',id)) ids from u_sign_key_role_info where tab_en_name='" + wbsTreePrivate.getInitTableName() + "' GROUP BY e_key";
 
-                // 组装电签设置
-                Elements dqids = table.getElementsByAttribute("dqid");
-                for (Element element : dqids) {
-                    String dqid = element.attr("dqid");
-                    Elements x11 = element.getElementsByAttribute("x1");
-                    if (x11 != null && x11.size() >= 1) {
-                        Element element1 = x11.get(x11.size() - 1);
-                        int x1 = Func.toInt(element1.attr("x1"));
-                        int y1 = Func.toInt(element1.attr("y1"));
+        List<Map<String, Object>> mapList = jdbcTemplate.queryForList(dqSql);
 
-                        Row row = sheet.getRow(y1 - 1);
-                        if (row != null) {
-                            Cell cell = row.getCell(x1 - 1);
-                            if (cell != null || ObjectUtils.isNotEmpty(cell)) {
-                                short fontIndex = cell.getCellStyle().getFontIndex();
-                                Font oldfontAt = workbook.getFontAt(fontIndex);
-                                Font redFont = workbook.createFont();
-                                redFont.setColor(IndexedColors.WHITE.getIndex()); //设置字体颜色
-                                redFont.setFontHeightInPoints(Short.valueOf("1"));//设置字体大小
-                                redFont.setFontName(oldfontAt.getFontName());//设置字体
-                                String CellValue = cell.getStringCellValue().trim();
+        if(mapList!=null && mapList.size()>0){
+            for(Map<String, Object> map : mapList) {
+                Elements elementsBy = table.getElementsByAttributeValueStarting("keyname", map.get("e_key") + "_");
+                if(elementsBy!=null && elementsBy.size()>0){
+                    for(Element element : elementsBy){
+                        String ids = (String) map.get("ids");
+                        ids = ids.replace(",","");
+                        ids = ids.substring(1);
+                        element.attr("sign_type", ids);
+                        dqids.add(element);
+                    }
+                }
 
-                                CellStyle newStyle = workbook.createCellStyle(); //创建单元格样式
-                                newStyle.cloneStyleFrom(cell.getCellStyle());
-                                newStyle.setFont(redFont);
-                                newStyle.setShrinkToFit(true);
-                                cell.setCellStyle(newStyle);
-                                cell.setCellValue(dqid);
+            }
+        }
+        for (Element element : dqids) {
+            String dqid="";
+            if(element.hasAttr("sign_type")){
+                dqid = element.attr("sign_type");
+            }else{
+                dqid = element.attr("dqid");
+            }
+            Elements x11 = element.getElementsByAttribute("x1");
+            if (x11 != null && x11.size() >= 1) {
+                Element element1 = x11.get(x11.size() - 1);
+                int x1 = Func.toInt(element1.attr("x1"));
+                int y1 = Func.toInt(element1.attr("y1"));
+
+                Row row = sheet.getRow(y1 - 1);
+                if (row != null) {
+                    Cell cell = row.getCell(x1 - 1);
+                    if (cell != null || ObjectUtils.isNotEmpty(cell)) {
+                        short fontIndex = cell.getCellStyle().getFontIndex();
+                        Font oldfontAt = workbook.getFontAt(fontIndex);
+                        Font redFont = workbook.createFont();
+                        redFont.setColor(IndexedColors.WHITE.getIndex()); //设置字体颜色
+                        redFont.setFontHeightInPoints(Short.valueOf("1"));//设置字体大小
+                        redFont.setFontName(oldfontAt.getFontName());//设置字体
+                        CellStyle newStyle = workbook.createCellStyle(); //创建单元格样式
+                        newStyle.cloneStyleFrom(cell.getCellStyle());
+                        newStyle.setFont(redFont);
+                        newStyle.setShrinkToFit(true);
+                        cell.setCellStyle(newStyle);
+                        if (cell.getCellTypeEnum().equals(CellType.STRING)) {
+                            String value = cell.getStringCellValue();
+                            if (StringUtil.hasText(value) && !value.equals("/")) {
+                                dqid = value + "*" + dqid;
                             }
                         }
+                        cell.setCellValue(dqid);
                     }
                 }
             }
@@ -4013,22 +4186,22 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                 //新增SQL
                 String sqlInfo = "";
                 LinkedHashMap<String, String> dataMap2 = tableInfo.getDataMap();
-                updateFieldLength(wbsTreePrivate.getInitTableName() ,dataMap2);
                 if(!dataMap2.containsKey("p_key_id")){
                     if(tableInfo.getPkeyId()!=null&&!tableInfo.getPkeyId().equals("")){
                         dataMap2.put("p_key_id",tableInfo.getPkeyId());
                     }
                 }
-                sqlInfo = "INSERT INTO " + wbsTreePrivate.getInitTableName() + " ( ";
-                String keyStr = "id,group_id,";
-                String valStr = SnowFlakeUtil.getId() + "," + groupId + ",";
-                for (String keys : dataMap2.keySet()) {
-                    keyStr += keys + ",";
-                    valStr += "'" + dataMap2.get(keys) + "',";
-                }
-                keyStr = keyStr.substring(0, keyStr.lastIndexOf(","));
-                valStr = valStr.substring(0, valStr.lastIndexOf(","));
-                sqlInfo = sqlInfo + keyStr + ") VALUES (" + valStr + ")";
+                sqlInfo = buildMTableInsertSql(wbsTreePrivate.getInitTableName(), dataMap2, SnowFlakeUtil.getId(), groupId, tableInfo.getPkeyId()).toString();
+//                sqlInfo = "INSERT INTO " + wbsTreePrivate.getInitTableName() + " ( ";
+//                String keyStr = "id,group_id,";
+//                String valStr = SnowFlakeUtil.getId() + "," + groupId + ",";
+//                for (String keys : dataMap2.keySet()) {
+//                    keyStr += keys + ",";
+//                    valStr += "'" + dataMap2.get(keys) + "',";
+//                }
+//                keyStr = keyStr.substring(0, keyStr.lastIndexOf(","));
+//                valStr = valStr.substring(0, valStr.lastIndexOf(","));
+//                sqlInfo = sqlInfo + keyStr + ") VALUES (" + valStr + ")";
                 TransactionStatus transactionStatus = this.beginTransaction(transactionManager1);
                 try {
                     //删除
@@ -4987,56 +5160,89 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                         }
                     }
                 }
+            }
+        }
+        // 组装电签设置
+        QueryWrapper<TextdictInfo> queryWrapper = new QueryWrapper<>();
+        queryWrapper.select("col_key", "id");
+        queryWrapper.in("type", 2, 6);
+        queryWrapper.eq("tab_id", wbsTreePrivate.getPKeyId());
+        List<TextdictInfo> textdictInfos = textdictInfoService.getBaseMapper().selectList(queryWrapper);
+        String dqSql = "select e_key,GROUP_CONCAT(DISTINCT concat('*✹',id)) ids from u_sign_key_role_info where tab_en_name='" + wbsTreePrivate.getInitTableName() + "' GROUP BY e_key";
+        List<Map<String, Object>> mapList = jdbcTemplate.queryForList(dqSql);
+        if(!mapList.isEmpty()){
+            for(Map<String, Object> map : mapList) {
+                Elements elementsBy = table.getElementsByAttributeValueStarting("keyname", map.get("e_key") + "__");
+                if(elementsBy!=null && !elementsBy.isEmpty()){
+                    String ids = map.get("ids").toString();
+                    ids = ids.replace(",","");
+                    String[] split = ids.split("\\*✹");
+                    for(Element element : elementsBy){
+                        for (String s : split) {
+                            if (s.isEmpty()) {
+                                continue;
+                            }
+                            try {
+                                TextdictInfo info = new TextdictInfo();
+                                info.setColKey(element.attr("keyname"));
+                                info.setId(Long.parseLong(s));
+                                info.setType(-1);
+                                textdictInfos.add(info);
+                            } catch (Exception e) {
+                                e.printStackTrace();
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        if (textdictInfos != null && !textdictInfos.isEmpty()) {
+            for (TextdictInfo e : textdictInfos) {
+                String key = e.getColKey();
+                String[] keys = key.split("__");
+                String[] trtd = keys[1].split("_");
+                if (Integer.parseInt(trtd[0]) < trs.size()) {
+                    Element ytzData = trs.get(Integer.parseInt(trtd[0]));
+                    if (ytzData != null) {
+                        Elements tdsx = ytzData.select("td");
+                        if (Integer.parseInt(trtd[1]) < tdsx.size()) {
+                            Element data = ytzData.select("td").get(Integer.parseInt(trtd[1]));
+                            if (data.html().contains("el-tooltip")) {
+                                data = data.children().get(0);
+                            }
 
-                // 组装电签设置
-                QueryWrapper<TextdictInfo> queryWrapper = new QueryWrapper<>();
-                queryWrapper.select("col_key", "id");
-                queryWrapper.in("type", 2, 6);
-                queryWrapper.eq("tab_id", wbsTreePrivate.getPKeyId());
-
-                List<TextdictInfo> textdictInfos = textdictInfoService.getBaseMapper().selectList(queryWrapper);
-                if (textdictInfos != null && !textdictInfos.isEmpty()) {
-                    for (TextdictInfo e : textdictInfos) {
-                        String key = e.getColKey();
-                        String[] keys = key.split("__");
-                        String[] trtd = keys[1].split("_");
-                        if (Integer.parseInt(trtd[0]) < trs.size()) {
-                            Element ytzData = trs.get(Integer.parseInt(trtd[0]));
-                            if (ytzData != null) {
-                                Elements tdsx = ytzData.select("td");
-                                if (Integer.parseInt(trtd[1]) < tdsx.size()) {
-                                    Element data = ytzData.select("td").get(Integer.parseInt(trtd[1]));
-                                    if (data.html().contains("el-tooltip")) {
-                                        data = data.children().get(0);
-                                    }
-
-                                    int x1 = Integer.parseInt(data.children().get(0).attr("x1"));
-                                    if (x1 == 0) {
-                                        x1 = 1;
+                            int x1 = Integer.parseInt(data.children().get(0).attr("x1"));
+                            if (x1 == 0) {
+                                x1 = 1;
+                            }
+                            int y1 = Integer.parseInt(data.children().get(0).attr("y1"));
+
+                            Row row = sheet.getRow(y1 - 1);
+                            if (row != null) {
+                                Cell cell = sheet.getRow(y1 - 1).getCell(x1 - 1);
+                                if (cell != null) {
+                                    short fontIndex = cell.getCellStyle().getFontIndex();
+                                    Font oldfontAt = workbook.getFontAt(fontIndex);
+
+                                    Font redFont = workbook.createFont();
+                                    redFont.setColor(IndexedColors.WHITE.getIndex()); //设置字体颜色
+                                    redFont.setFontHeightInPoints(Short.valueOf("1"));//设置字体大小
+                                    redFont.setFontName(oldfontAt.getFontName());//设置字体
+
+                                    CellStyle newStyle = workbook.createCellStyle(); //创建单元格样式
+                                    newStyle.cloneStyleFrom(cell.getCellStyle());
+                                    newStyle.setFont(redFont);
+                                    cell.setCellStyle(newStyle);
+                                    String id = e.getId() + "";
+                                    if (e.getType() != null && e.getType() == -1) {
+                                        id = "✹" + id;
                                     }
-                                    int y1 = Integer.parseInt(data.children().get(0).attr("y1"));
-
-                                    Row row = sheet.getRow(y1 - 1);
-                                    if (row != null) {
-                                        Cell cell = sheet.getRow(y1 - 1).getCell(x1 - 1);
-                                        if (cell != null) {
-                                            short fontIndex = cell.getCellStyle().getFontIndex();
-                                            Font oldfontAt = workbook.getFontAt(fontIndex);
-
-                                            Font redFont = workbook.createFont();
-                                            redFont.setColor(IndexedColors.WHITE.getIndex()); //设置字体颜色
-                                            redFont.setFontHeightInPoints(Short.valueOf("1"));//设置字体大小
-                                            redFont.setFontName(oldfontAt.getFontName());//设置字体
-
-                                            CellStyle newStyle = workbook.createCellStyle(); //创建单元格样式
-                                            newStyle.cloneStyleFrom(cell.getCellStyle());
-                                            newStyle.setFont(redFont);
-                                            cell.setCellStyle(newStyle);
-                                            cell.setCellValue(e.getId() + "");
-                                        } else {
-                                            ObjectUtils.isNotEmpty(cell);
-                                        }
+                                    if (cell.getCellTypeEnum() == CellType.STRING && StringUtil.hasText(cell.getStringCellValue())) {
+                                        id = cell.getStringCellValue() + "*" + id;
                                     }
+                                    cell.setCellValue(id);
+                                } else {
+                                    ObjectUtils.isNotEmpty(cell);
                                 }
                             }
                         }
@@ -5281,6 +5487,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
 
             if (dataIn.size() >= 1) {
                 Map<String, Object> mysqlData = dataIn.get(0);
+                DataStructureFormatUtils.parseDataByKey(mysqlData);
                 for (String key : mysqlData.keySet()) {
                     String tabVal = mysqlData.get(key) + "";
                     // 时间段处理
@@ -5575,48 +5782,6 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
         }
     }
 
-    @Override
-    @Async("taskExecutor1")
-    public void synchronizedPdf(List<TableInfo> tableInfoList, String nodeId, String classify, String contractId, String projectId) {
-        try {
-            List<String> errorPKeyIds = new ArrayList<>();
-            //单个pdf加载
-            if (tableInfoList != null) {
-                tableInfoList.parallelStream().forEach(tableInfo -> {
-                    R bussPdfInfo = null;
-                    try {
-                        bussPdfInfo = this.getBussPdfInfo(Long.parseLong(tableInfo.getPkeyId()));
-                    } catch (Exception e) {
-                        e.printStackTrace();
-                    }
-                    if (ObjectUtil.isEmpty(bussPdfInfo) || bussPdfInfo.getCode() != 200) {
-                        //如果返回的单张pdfUrl为空,那么表示发生异常,返回异常信息
-                        errorPKeyIds.add(tableInfo.getPkeyId());
-                    }
-                });
-            }
-
-            //发生异常后直接返回,不进行合并
-//        if (errorPKeyIds.size() > 0) {
-//            List<AppWbsTreeContractVO> errorTabs = new LinkedList<>();
-//            for (AppWbsTreeContractVO appWbsTreeContractVO : tableAll) {
-//                if (errorPKeyIds.contains(appWbsTreeContractVO.getPKeyId().toString())) {
-//                    errorTabs.add(appWbsTreeContractVO);
-//                }
-//            }
-//            if (errorTabs.size() > 0) {
-//                List<String> names = errorTabs.stream().map(WbsTreeContract::getNodeName).collect(Collectors.toList());
-//                return R.fail("以下的表在生成pdf文件时发生了异常【" + StringUtils.join(names, "、") + "】");
-//            }
-//        }
-
-            //合并pdf加载
-            this.getBussPdfs(nodeId, classify, contractId, projectId);
-        } catch (Exception e) {
-            e.printStackTrace();
-            throw new ServiceException("问题");
-        }
-    }
 
     @Override
     public void cancelSample(Long groupId, Long pkeyId, Long contractId, Long sampleId1) throws Exception {
@@ -5705,6 +5870,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
 
             if (dataIn.size() >= 1) {
                 Map<String, Object> mysqlData = dataIn.get(0);
+                DataStructureFormatUtils.parseDataByKey(mysqlData);
                 for (String key : mysqlData.keySet()) {
                     String tabVal = mysqlData.get(key) + "";
                     // 时间段处理
@@ -5808,6 +5974,48 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
         jdbcTemplate.update(sql);
     }
 
+    @Override
+    @Async("taskExecutor1")
+    public void synchronizedPdf(List<TableInfo> tableInfoList, String nodeId, String classify, String contractId, String projectId) {
+        try {
+            List<String> errorPKeyIds = new ArrayList<>();
+            //单个pdf加载
+            if (tableInfoList != null) {
+                tableInfoList.parallelStream().forEach(tableInfo -> {
+                    R bussPdfInfo = null;
+                    try {
+                        bussPdfInfo = this.getBussPdfInfo(Long.parseLong(tableInfo.getPkeyId()));
+                    } catch (Exception e) {
+                        e.printStackTrace();
+                    }
+                    if (ObjectUtil.isEmpty(bussPdfInfo) || bussPdfInfo.getCode() != 200) {
+                        //如果返回的单张pdfUrl为空,那么表示发生异常,返回异常信息
+                        errorPKeyIds.add(tableInfo.getPkeyId());
+                    }
+                });
+            }
+
+            //发生异常后直接返回,不进行合并
+//        if (errorPKeyIds.size() > 0) {
+//            List<AppWbsTreeContractVO> errorTabs = new LinkedList<>();
+//            for (AppWbsTreeContractVO appWbsTreeContractVO : tableAll) {
+//                if (errorPKeyIds.contains(appWbsTreeContractVO.getPKeyId().toString())) {
+//                    errorTabs.add(appWbsTreeContractVO);
+//                }
+//            }
+//            if (errorTabs.size() > 0) {
+//                List<String> names = errorTabs.stream().map(WbsTreeContract::getNodeName).collect(Collectors.toList());
+//                return R.fail("以下的表在生成pdf文件时发生了异常【" + StringUtils.join(names, "、") + "】");
+//            }
+//        }
+
+            //合并pdf加载
+            this.getBussPdfs(nodeId, classify, contractId, projectId);
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new ServiceException("问题");
+        }
+    }
     @Override
     public void synPdfKeyInfo(String nodeId, String classify, String contractId, String projectId) throws Exception {
         // 获取有权限的节点信息

+ 147 - 45
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormulaServiceImpl.java

@@ -7,7 +7,6 @@ import cn.hutool.core.util.HashUtil;
 import cn.hutool.log.StaticLog;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
-import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
@@ -22,17 +21,14 @@ import lombok.RequiredArgsConstructor;
 import org.apache.poi.ss.usermodel.*;
 import org.apache.poi.ss.util.CellReference;
 import org.apache.poi.util.IOUtils;
-import org.apache.poi.xssf.usermodel.XSSFRichTextString;
 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.constant.MeasurementStorage;
 import org.springblade.common.utils.BaseUtils;
 import org.springblade.common.utils.CommonUtil;
 import org.springblade.common.utils.SnowFlakeUtil;
-import org.springblade.core.log.exception.ServiceException;
 import org.springblade.core.mp.base.BaseEntity;
 import org.springblade.core.mp.base.BaseServiceImpl;
 import org.springblade.core.mp.support.Condition;
@@ -49,6 +45,7 @@ import org.springblade.manager.formula.*;
 import org.springblade.manager.formula.impl.*;
 import org.springblade.manager.mapper.*;
 import org.springblade.manager.service.*;
+import org.springblade.manager.util.DataStructureFormatUtils;
 import org.springblade.manager.utils.*;
 import org.springblade.manager.vo.*;
 import org.springblade.meter.entity.*;
@@ -92,8 +89,6 @@ import java.util.stream.Collectors;
 import java.util.stream.IntStream;
 import java.util.stream.Stream;
 
-import static org.springblade.manager.utils.TableCoordinates.*;
-
 /**
  * @author yangyj
  * @Date 2022/6/9 14:29
@@ -409,12 +404,18 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                         itemsMap.values().stream().filter(Measurement::isMatching).forEach(t -> {
                             ElementBlock g = null;
                             FormData vfd = t.getValue();
+                            List<CurrentNode> nodeType46 = getNodeType46(tec);
+                            List<Long> ids = nodeType46.stream().map(CurrentNode::getPkId).collect(Collectors.toList());
                             if (vfd.executable() && vfd.getFormula().getRelyList() != null) {
                                 List<String> relyList = vfd.getFormula().getRelyList();
                                 /*先从公式去匹配*/
-                                Optional<ElementBlock> op = elementBlockList.stream().filter(e -> relyList.contains(e.getCode())).findAny();
-                                if (op.isPresent()) {
-                                    g = op.get();
+                                List<ElementBlock> list = elementBlockList.stream().filter(e -> relyList.contains(e.getCode())).collect(Collectors.toList());
+                                for (ElementBlock e : list) {
+                                    e.getList().removeIf(ik -> !ids.contains(ik.getPkeyId()));
+                                    if (!e.getList().isEmpty()) {
+                                        g = e;
+                                        break;
+                                    }
                                 }
                             } else {
                                 /*只有不存在配置的前提下才能尝试自动匹配*/
@@ -427,7 +428,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                             if (g != null) {
                                 /*手写部分的数据加载*/
                                 if (t.getPoint().contains("混凝土强度") && false) {
-                                    List<Long> ids = getNodeType46(tec).stream().map(CurrentNode::getPkId).collect(Collectors.toList());
+//                                    List<Long> ids = getNodeType46(tec).stream().map(CurrentNode::getPkId).collect(Collectors.toList());
                                     /*质检附表m_20230316104657_1636197331206406144*/
                                     List<Map<String, Object>> listMaps = this.jdbcTemplate.queryForList("select a.p_key_id,b.key_10 name,b.key_6 design,b.key_5 data from m_wbs_tree_contract a join m_20230316104657_1636197331206406144 b on a.p_key_id=b.p_key_id where  a.is_deleted=0 and a.parent_id =" + tec.getCurrentNode().getId());
                                     if (listMaps.size() > 0) {
@@ -467,8 +468,6 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
 
                                 List<ItemBlock> itemBlockList = g.getList();
                                 int originSize = itemBlockList.size();
-                                List<CurrentNode> nodeType46 = getNodeType46(tec);
-                                List<Long> ids = nodeType46.stream().map(CurrentNode::getPkId).collect(Collectors.toList());
 
                                 Map<Long, CurrentNode> sortInfoMap  = nodeType46.stream().collect(Collectors.toMap(CurrentNode::getPkId, info -> info,
                                         (oldInfo, newInfo) -> newInfo));
@@ -609,6 +608,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                             });
                         });
                         AtomicBoolean update = new AtomicBoolean(false);
+                        List<Long> ids = getNodeType46(tec).stream().map(CurrentNode::getPkId).collect(Collectors.toList());
                         itemsMap.values().stream().filter(Measurement::isMatching).forEach(t -> {
                             ElementBlock g = null;
                             FormData vfd = t.getValue();
@@ -630,7 +630,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                             if (g != null) {
                                 List<ItemBlock> itemBlockList = g.getList();
                                 int originSize = itemBlockList.size();
-                                List<Long> ids = getNodeType46(tec).stream().map(CurrentNode::getPkId).collect(Collectors.toList());
+
                                 /*清除那些已经不存在的工序*/
                                 itemBlockList.removeIf(ik -> !ids.contains(ik.getPkeyId()));
                                 if (itemBlockList.size() > 0) {
@@ -665,7 +665,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
         }
     }
 
-    public void descendantType46(Object id, List<Map<String, Object>> listMaps) {
+    public void descendantType46(Long id, Long contractId, List<Map<String, Object>> listMaps) {
         String sql = "select " +
                         "p_Key_id pkId," +
                         "id," +
@@ -674,15 +674,16 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                         "sort," +
                         "IFNULL(if(length(trim(full_name))>0,full_name,node_name),node_name) AS title," +
                         "create_time createTime " +
-                        "from m_wbs_tree_contract where parent_id =? and is_deleted=0";
-        List<Map<String, Object>> tmp = this.jdbcTemplate.queryForList(sql, id);
+                        "from m_wbs_tree_contract where  contract_id =  " + contractId + " and find_in_set( " + id + ",ancestors_p_id) and is_deleted=0";
+        List<Map<String, Object>> tmp = this.jdbcTemplate.queryForList(sql);
         if (tmp.size() > 0) {
             for (Map<String, Object> map : tmp) {
                 if (StringUtils.isEquals(map.get("nodeType"), 6)) {
                     listMaps.add(map);
-                } else {
-                    descendantType46(map.get("id"), listMaps);
                 }
+//                else {
+//                    descendantType46(map.get("id"), listMaps);
+//                }
             }
         }
     }
@@ -691,7 +692,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
         if (tec.getCurrentNode().getDivisional().size() == 0) {
             // List<Map<String,Object>> listMaps=this.jdbcTemplate.queryForList("select b.p_Key_id pkId,b.id from m_wbs_tree_contract a join m_wbs_tree_contract b on (a.contract_id=b.contract_id and b.ancestors like CONCAT(a.ancestors,'%')) where a.p_key_id="+tec.getCurrentNode().getPkId()+" and b.is_deleted=0 and b.node_type=6 ORDER BY b.sort");
             List<Map<String, Object>> listMaps = new ArrayList<>();
-            descendantType46(tec.getCurrentNode().getParentId(), listMaps);
+            descendantType46(tec.getCurrentNode().getParentPkeyId(),tec.getCurrentNode().getContractId(), listMaps);
             if (listMaps.size() > 0) {
                 tec.getCurrentNode().getDivisional().addAll(listMaps.stream().map(m -> BeanUtil.toBean(m, CurrentNode.class)).collect(Collectors.toList()));
             }
@@ -2374,6 +2375,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                     //不为空的元素
                     if (mapsList.size() > 0) {
                         for (Map<String, Object> stringObjectMap : mapsList) {
+                            DataStructureFormatUtils.parseDataByKey(stringObjectMap);
                             for (String s : stringObjectMap.keySet()) {
                                 if (ObjectUtil.isNotEmpty(stringObjectMap.get(s)) && !s.equals("id") && !s.equals("p_key_id")) {
                                     maps.put(s, stringObjectMap.get(s));
@@ -2513,7 +2515,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
         String sql = "Select * from s_contract_meter_period where contract_id=" + contractId + " and is_deleted=0" + " order by start_date";
         List<ContractMeterPeriod> list = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(ContractMeterPeriod.class));
         //获取所有excel报表源数据
-        String sqlForExcel = "SELECT p.p_key_id,e.name,e.id,p.html_url,e.file_url FROM m_wbs_tree_private as p LEFT JOIN m_excel_tab as e on p.excel_id=e.id where p.wbs_type=3 AND p.is_deleted=0 AND p.type=2" + " and p.project_id=" + projectId;
+        String sqlForExcel = "SELECT p.p_key_id,e.name,e.id,p.html_url,e.file_url,p.init_table_name as tabName FROM m_wbs_tree_private as p LEFT JOIN m_excel_tab as e on p.excel_id=e.id where p.wbs_type=3 AND p.is_deleted=0 AND p.type=2" + " and p.project_id=" + projectId;
         List<ExcelTabVo1> excelTabs = jdbcTemplate.query(sqlForExcel, new BeanPropertyRowMapper<>(ExcelTabVo1.class));
         ArrayList<ReportResult> reportResults = new ArrayList<>();
         //中期支付报表封面
@@ -2559,25 +2561,25 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
         String htmlUrl6 = excel6.get().getHtmlUrl();
         Long pKeyId6 = excel6.get().getPKeyId();
         // 获取中期支付报表封面的pdfurl
-        ReportResult CoverOfMidtermPaymentReportPDF = getCoverOfMidtermPaymentReportPDF(url, contractId, periodId, htmlUrl, projectName, list, pKeyId);
+        ReportResult CoverOfMidtermPaymentReportPDF = getCoverOfMidtermPaymentReportPDF(url, contractId, periodId, htmlUrl, projectName, list, pKeyId, excel.get().getTabName());
 
         //获取中间支付审核表的pdfurl
-        ReportResult intermediatePaymentPDF = getIntermediatePaymentPDF(url1, contractId, periodId, list, redisId, htmlUrl1, blReserveFundsRatioNew, projectName, changeMoneyNew, pKeyId1);
+        ReportResult intermediatePaymentPDF = getIntermediatePaymentPDF(url1, contractId, periodId, list, redisId, htmlUrl1, blReserveFundsRatioNew, projectName, changeMoneyNew, pKeyId1, excel1.get().getTabName());
 
         //获取补助款申请支付审核表pdfUrl
-        ReportResult subsidyApplicationPaymentReviewPDF = getSubsidyApplicationPaymentReviewPDF(url2, contractId, periodId, list, htmlUrl2, blReserveFundsRatioNew, projectName, projectId, reportId, pKeyId2);
+        ReportResult subsidyApplicationPaymentReviewPDF = getSubsidyApplicationPaymentReviewPDF(url2, contractId, periodId, list, htmlUrl2, blReserveFundsRatioNew, projectName, projectId, reportId, pKeyId2,excel2.get().getTabName());
 
         //获取中间计量支付证书pdfUrl
-        ReportResult intermediateMeasurementPaymentCertificatePDF = getIntermediateMeasurementPaymentCertificatePDF(url3, contractId, periodId, list, htmlUrl3, blReserveFundsRatioNew, projectName, pKeyId3);
+        ReportResult intermediateMeasurementPaymentCertificatePDF = getIntermediateMeasurementPaymentCertificatePDF(url3, contractId, periodId, list, htmlUrl3, blReserveFundsRatioNew, projectName, pKeyId3,excel3.get().getTabName());
 
         //获取清单支付报表PDF
-        ReportResult inventoryPayReportPDF = getInventoryPayReportPDF(url6, contractId, periodId, projectId, list, redisId, htmlUrl6, pKeyId6);
+        ReportResult inventoryPayReportPDF = getInventoryPayReportPDF(url6, contractId, periodId, projectId, list, redisId, htmlUrl6, pKeyId6, excel6.get().getTabName());
 
         //获取工程支付月报pdfUrl
-        ReportResult monthlyReportPDF = getMonthlyReportPDF(url5, reportId, contractId, periodId, projectId, list, redisId, htmlUrl5, pKeyId5);
+        ReportResult monthlyReportPDF = getMonthlyReportPDF(url5, reportId, contractId, periodId, projectId, list, redisId, htmlUrl5, pKeyId5, excel5.get().getTabName());
 
         //获取中间支付申请表pdfUrl
-        ReportResult intermediateApplyPDF = getIntermediateApplyPDF(url4, periodId, projectId, htmlUrl4, projectName, contractId, pKeyId4);
+        ReportResult intermediateApplyPDF = getIntermediateApplyPDF(url4, periodId, projectId, htmlUrl4, projectName, contractId, pKeyId4, excel4.get().getTabName());
 
         reportResults.add(CoverOfMidtermPaymentReportPDF);
         reportResults.add(intermediatePaymentPDF);
@@ -2595,7 +2597,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
     /**
      * 中期支付报表封面
      */
-    private ReportResult getCoverOfMidtermPaymentReportPDF(String url, Long contractId, Long periodId, String htmlUrl, String projectName, List<ContractMeterPeriod> list, Long pkeyId) {
+    private ReportResult getCoverOfMidtermPaymentReportPDF(String url, Long contractId, Long periodId, String htmlUrl, String projectName, List<ContractMeterPeriod> list, Long pkeyId, String tabName) {
 
         //获取本期计量期
         String sqlForMeterPeriodById = "SELECT id,period_number,start_date,end_date FROM s_contract_meter_period WHERE id=" + periodId + " and is_deleted = 0 ";
@@ -2646,7 +2648,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                 Cell c10 = getCellByAddress(sheet, "C10");
                 c10.setCellValue(contractInfo.getSupervisionUnitName());
             }
-            dianqian(htmlUrl, sheet, workbook);
+            dianqian(htmlUrl, sheet, workbook, tabName);
             if (!periodId.equals(1867838908899852290L)) {
                 dianqianTime(htmlUrl, sheet, workbook, pkeyId, periodId, contractId);
             }
@@ -2682,7 +2684,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
     }
 
     /*设置电签ID*/
-    public void dianqian(String htmlUrl, Sheet sheet, Workbook workbook) {
+    public void dianqian(String htmlUrl, Sheet sheet, Workbook workbook, String tabName) {
         try {
             InputStream inputStreamByUrl = FileUtils.getInputStreamByUrl(htmlUrl);
             String htmlString = IoUtil.readToString(inputStreamByUrl);
@@ -2690,8 +2692,30 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
             Element table = doc.select("table").first();
             // 组装电签设置
             Elements dqids = table.getElementsByAttribute("dqid");
+            // 电签组装2
+            String dqSql = "select e_key,GROUP_CONCAT(DISTINCT concat('*✹',id)) ids from u_sign_key_role_info where tab_en_name='" + tabName + "' GROUP BY e_key";
+            List<Map<String, Object>> mapList = jdbcTemplate.queryForList(dqSql);
+            if(mapList!=null && mapList.size()>0){
+                for(Map<String, Object> map : mapList) {
+                    Elements elementsBy = table.getElementsByAttributeValueStarting("keyname", map.get("e_key") + "_");
+                    if(elementsBy!=null && elementsBy.size()>0){
+                        for(Element element : elementsBy){
+                            String dqIds = (String) map.get("ids");
+                            dqIds = dqIds.replace(",","");
+                            dqIds = dqIds.substring(1);
+                            element.attr("sign_type", dqIds);
+                            dqids.add(element);
+                        }
+                    }
+                }
+            }
             for (Element element : dqids) {
-                String dqid = element.attr("dqid");
+                String dqid="";
+                if(element.hasAttr("sign_type")){
+                    dqid = element.attr("sign_type");
+                }else{
+                    dqid = element.attr("dqid");
+                }
 
                 int x1 = 0;
                 int y1 = 0;
@@ -2785,7 +2809,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
     /**
      * 中间计量支付证书获取PDFurl
      */
-    private ReportResult getIntermediateMeasurementPaymentCertificatePDF(String url3, Long contractId, Long periodId, List<ContractMeterPeriod> list, String htmlUrl, BigDecimal blReserveFundsRatioNew, String projectName, Long pkeyId) {
+    private ReportResult getIntermediateMeasurementPaymentCertificatePDF(String url3, Long contractId, Long periodId, List<ContractMeterPeriod> list, String htmlUrl, BigDecimal blReserveFundsRatioNew, String projectName, Long pkeyId, String tabName) {
         //判断当前是否是第一期
         Boolean isOnePeriod = false;
         ContractMeterPeriod contractMeterPeriod = list.get(0);
@@ -2866,7 +2890,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
             Cell c3 = getCellByAddress(sheet, "C3");
             c3.setCellValue(projectName);
 
-            dianqian(htmlUrl, sheet, workbook);
+            dianqian(htmlUrl, sheet, workbook, tabName);
             if (!periodId.equals(1867838908899852290L)) {
                 dianqianTime(htmlUrl, sheet, workbook, pkeyId, periodId, contractId);
             }
@@ -2912,7 +2936,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
     /**
      * 补助款申请支付审核表获取PDFurl
      */
-    private ReportResult getSubsidyApplicationPaymentReviewPDF(String url2, Long contractId, Long periodId, List<ContractMeterPeriod> list, String htmlUrl, BigDecimal blReserveFundsRatioNew, String projectName, Long projectId, Long reportId, Long pkeyId) {
+    private ReportResult getSubsidyApplicationPaymentReviewPDF(String url2, Long contractId, Long periodId, List<ContractMeterPeriod> list, String htmlUrl, BigDecimal blReserveFundsRatioNew, String projectName, Long projectId, Long reportId, Long pkeyId, String tabName) {
         //判断当前是否是只有1期计量
         Boolean isOnePeriod = false;
         ContractMeterPeriod contractMeterPeriod = list.get(0);
@@ -3186,7 +3210,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
             Cell a2 = getCellByAddress(sheet, "A2");
             a2.setCellValue(projectName);
             // 电签
-            dianqian(htmlUrl, sheet, workbook);
+            dianqian(htmlUrl, sheet, workbook, tabName);
             if (!periodId.equals(1867838908899852290L)) {
                 dianqianTime(htmlUrl, sheet, workbook, pkeyId, periodId, contractId);
             }
@@ -3226,7 +3250,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
     /**
      * 中间支付审核表获取PDFurl
      */
-    public ReportResult getIntermediatePaymentPDF(String url, Long contractId, Long periodId, List<ContractMeterPeriod> list, Long redisId, String htmlUrl, BigDecimal blReserveFundsRatioNew, String projectName, BigDecimal changeMoneyNew, Long pkeyId) {
+    public ReportResult getIntermediatePaymentPDF(String url, Long contractId, Long periodId, List<ContractMeterPeriod> list, Long redisId, String htmlUrl, BigDecimal blReserveFundsRatioNew, String projectName, BigDecimal changeMoneyNew, Long pkeyId, String tabName) {
         //判断当前是否是只有1期计量
         Boolean isOnePeriod = false;
         ContractMeterPeriod contractMeterPeriod1 = list.get(0);
@@ -3498,7 +3522,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
             //顶部项目名称
             Cell a1 = getCellByAddress(sheet, "A1");
             a1.setCellValue(projectName);
-            dianqian(htmlUrl, sheet, workbook);
+            dianqian(htmlUrl, sheet, workbook, tabName);
             if (!periodId.equals(1867838908899852290L)) {
                 dianqianTime(htmlUrl, sheet, workbook, pkeyId, periodId, contractId);
             }
@@ -3647,9 +3671,10 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
      * 中间支付申请表获取pdfUrl
      *
      * @param url
+     * @param tabName
      * @return
      */
-    public ReportResult getIntermediateApplyPDF(String url, Long periodId, Long projectId, String htmlUrl, String projectName, Long contractId, Long pkeyId) {
+    public ReportResult getIntermediateApplyPDF(String url, Long periodId, Long projectId, String htmlUrl, String projectName, Long contractId, Long pkeyId, String tabName) {
         InputStream modInput = null;
         FileInputStream excelFileInput = null;
         FileOutputStream outputStream = null;
@@ -3659,7 +3684,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
             modInput = CommonUtil.getOSSInputStream(url);
             workbook = WorkbookFactory.create(modInput);
             Sheet sheet = workbook.getSheetAt(0);
-            dianqian(htmlUrl, sheet, workbook);
+            dianqian(htmlUrl, sheet, workbook, tabName);
             if (!periodId.equals(1867838908899852290L)) {
                 dianqianTime(htmlUrl, sheet, workbook, pkeyId, periodId, contractId);
             }
@@ -3726,9 +3751,10 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
      * 工程支付月报获取pdfUrl
      *
      * @param url
+     * @param tabName
      * @return
      */
-    public ReportResult getMonthlyReportPDF(String url, Long reportId, Long contractId, Long periodId, Long projectId, List<ContractMeterPeriod> list, Long redisId, String htmlUrl, Long pkeyId) throws IllegalAccessException {
+    public ReportResult getMonthlyReportPDF(String url, Long reportId, Long contractId, Long periodId, Long projectId, List<ContractMeterPeriod> list, Long redisId, String htmlUrl, Long pkeyId, String tabName) throws IllegalAccessException {
         //获取本期计量期
         String sqlForMeterPeriodById = "SELECT id,period_number,start_date,end_date FROM s_contract_meter_period WHERE id=" + periodId + " and is_deleted = 0 ";
         ContractMeterPeriod contractMeterPeriodNow = jdbcTemplate.queryForObject(sqlForMeterPeriodById, new BeanPropertyRowMapper<>(ContractMeterPeriod.class));
@@ -4186,7 +4212,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                     m_3.setCellValue(formattedDate);
                 }
             }
-            dianqian(htmlUrl, sheet, workbook);
+            dianqian(htmlUrl, sheet, workbook, tabName);
             if (!periodId.equals(1867838908899852290L)) {
                 dianqianTime(htmlUrl, sheet, workbook, pkeyId, periodId, contractId);
             }
@@ -4222,10 +4248,11 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
      * 清单支付报表获取PDF
      *
      * @param url
+     * @param tabName
      * @return
      */
 
-    public ReportResult getInventoryPayReportPDF(String url, Long contractId, Long periodId, Long projectId, List<ContractMeterPeriod> list, Long redisId, String htmlUrl, Long pkeyId) throws FileNotFoundException, IllegalAccessException {
+    public ReportResult getInventoryPayReportPDF(String url, Long contractId, Long periodId, Long projectId, List<ContractMeterPeriod> list, Long redisId, String htmlUrl, Long pkeyId, String tabName) throws FileNotFoundException, IllegalAccessException {
         MiddleMeterApply middleMeterApply = new MiddleMeterApply();
         middleMeterApply.setContractId(contractId);
         middleMeterApply.setContractPeriodId(periodId);
@@ -4613,7 +4640,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                             l4.setCellStyle(cellStyle);
                             l4.setCellValue(contractInfo.getSupervisionUnitName());
                         }
-                        dianqian(htmlUrl, sheet, workbook);
+                        dianqian(htmlUrl, sheet, workbook, tabName);
                         if (!periodId.equals(1867838908899852290L)) {
                             dianqianTime(htmlUrl, sheet, workbook, pkeyId, periodId, contractId);
                         }
@@ -5542,6 +5569,8 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                 /*设计值可以是数值类型,或空(等效0)*/
                 if (dataFd != null) {
                     List<Object> values = dataFd.getRawValue();
+                    /*保留小数位,去除*/
+                    values = values.stream().map(e -> StringUtils.number2StringZero(e,8)).collect(Collectors.toList());
                     //boolean nonNumeric = values.stream().filter(StringUtils::isNotEmpty).anyMatch(e -> !StringUtils.isNumber(e));
                     boolean nonNumeric = values.stream()
                             .filter(StringUtils::isNotEmpty)
@@ -6233,6 +6262,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
         List<Map<String, Object>> mapList = jdbcTemplate.queryForList(sql);
         Map<String, String> remap = new HashMap<>();
         for (Map<String, Object> map : mapList) {
+            DataStructureFormatUtils.parseDataByKey(map);
             for (String key : map.keySet()) {
                 String[] keyData = (map.get(key)+"").split("☆");
                 if(keyData!=null && keyData.length>=1){
@@ -6288,7 +6318,10 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
             String initTableName = nt.getInitTableName();
             Document document = documentMap.get(nt.getInitTableName());
             coordinateMap.put(initTableName, FormulaUtils.getElementExcelCoords(document));
-            eSignMaps.put(initTableName, FormulaUtils.getESignMap(document));
+            Map<String, String> eSignMap = FormulaUtils.getESignMap(document);
+            eSignMaps.put(initTableName, eSignMap);
+            // 电签组装2
+            getSignMapBySignConfig(initTableName, document, eSignMap);
         });
         executionTime.info("坐标信息获取");
         /*额外单元格坐标配置*/
@@ -6344,6 +6377,74 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
         return tec.getReportResults();
     }
 
+    private void getSignMapBySignConfig(String initTableName, Document document, Map<String, String> eSignMap) {
+        String dqSql = "select e_key,GROUP_CONCAT(DISTINCT concat('*✹',id)) ids from u_sign_key_role_info where tab_en_name='" + initTableName + "' GROUP BY e_key";
+        List<Map<String, Object>> mapList = jdbcTemplate.queryForList(dqSql);
+        if(!mapList.isEmpty()){
+            for(Map<String, Object> map : mapList) {
+                Elements elementsBy = document.getElementsByAttributeValueStarting("keyname", map.get("e_key") + "_");
+                if(elementsBy!=null && !elementsBy.isEmpty()){
+                    for(Element element : elementsBy){
+                        String dqIds = (String) map.get("ids");
+                        dqIds = dqIds.replace(",","");
+                        dqIds = dqIds.substring(1);
+                        int x1 = -1,y1 = -1;
+                        try {
+                            if (element.hasAttr("x1") && element.hasAttr("y1")) {
+                                x1 = Integer.parseInt(element.attr("x1"));
+                                y1 = Integer.parseInt(element.attr("y1"));
+                            } else {
+                                if (element.tagName().equals("td")) {
+                                    Elements x11 = element.getElementsByAttribute("x1");
+                                    if (x11 != null && !x11.isEmpty()) {
+                                        x1 = Integer.parseInt(x11.attr("x1"));
+                                    }
+                                    Elements y11 = element.getElementsByAttribute("y1");
+                                    if (y11 != null && !y11.isEmpty()) {
+                                        y1 = Integer.parseInt(y11.attr("y1"));
+                                    }
+                                } else {
+                                    Elements parents = element.parents();
+                                    if (parents != null && !parents.isEmpty()) {
+                                        for (Element parent1 : parents) {
+                                            if (parent1.hasAttr("x1") && parent1.hasAttr("y1")) {
+                                                x1 = Integer.parseInt(parent1.attr("x1"));
+                                                y1 = Integer.parseInt(parent1.attr("y1"));
+                                                break;
+                                            }
+                                            if (parent1.tagName().equals("td")) {
+                                                break;
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        } catch (Exception e) {
+                            log.error("坐标获取异常", e);
+                        }
+                        if (x1 == -1 || y1 == -1) {
+                            String keyname = element.attr("keyname");
+                            String[] split = keyname.split("__");
+                            if (split.length > 1) {
+                                String value = eSignMap.get(y1 + "_" + x1);
+                                if (StringUtil.hasText(value)) {
+                                    dqIds = value + "*" + dqIds;
+                                }
+                                eSignMap.put(split[1], dqIds);
+                            }
+                        } else {
+                            String value = eSignMap.get(y1 + "_" + x1);
+                            if (StringUtil.hasText(value)) {
+                                dqIds = value + "*" + dqIds;
+                            }
+                            eSignMap.put(y1 + "_" + x1, dqIds);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
     public void saveInterimPayCertificateItems(List<InterimPayCertificateItem> items,Long reportId) {
         if (items != null && items.size() > 0) {
             this.certificateItemClient.saveOrUpdate(items,reportId);
@@ -6531,6 +6632,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
 
         if (dataIn != null && dataIn.size() >= 1) {
             Map<String, Object> mysqlData = dataIn.get(0);
+            DataStructureFormatUtils.parseDataByKey(mysqlData);
             for (String key : mysqlData.keySet()) {
                 String tabVal = mysqlData.get(key) + "";
                 // 时间段处理
@@ -7106,5 +7208,5 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
         }
         return wbsTreeContract;
     }
-    
+
 }

+ 31 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ProjectInfoServiceImpl.java

@@ -2,6 +2,7 @@ package org.springblade.manager.service.impl;
 
 import cn.hutool.core.util.ObjectUtil;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import lombok.Data;
 import org.apache.commons.lang.StringUtils;
 import org.springblade.manager.entity.ContractInfo;
@@ -12,12 +13,14 @@ import org.springblade.manager.entity.WbsTreePrivate;
 import org.springblade.manager.mapper.*;
 import org.springblade.manager.service.IProjectInfoService;
 import org.springblade.core.mp.base.BaseServiceImpl;
+import org.springblade.manager.wrapper.ProjectInfoWrapper;
 import org.springframework.jdbc.core.BeanPropertyRowMapper;
 import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.stereotype.Service;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 
 import javax.annotation.Resource;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -155,4 +158,32 @@ public class ProjectInfoServiceImpl extends BaseServiceImpl<ProjectInfoMapper, P
         return projectInfos.get(0).getId();
     }
 
+    @Override
+    public IPage<ProjectInfoVO> pageList(IPage<ProjectInfoVO> page, ProjectInfoVO3 vo) {
+        IPage<ProjectInfoVO> pagedList = baseMapper.pageList(page, vo);
+        List<ProjectInfoVO> records = pagedList.getRecords();
+        if (records != null && !records.isEmpty()) {
+            records.forEach(item -> {
+                List<Integer> wbsTypes = new ArrayList<>();
+                if (item.getReferenceWbsTemplateId() != null && item.getReferenceWbsTemplateId() > 0) {
+                    wbsTypes.add(1);
+                }
+                if (item.getReferenceWbsTemplateIdTrial() != null && item.getReferenceWbsTemplateIdTrial() > 0) {
+                    wbsTypes.add(2);
+                }
+                if (item.getReferenceLogWbsTemplateId() != null && item.getReferenceLogWbsTemplateId() > 0) {
+                    wbsTypes.add(3);
+                }
+                if (item.getReferenceWbsTemplateIdMeter() != null && item.getReferenceWbsTemplateIdMeter() > 0) {
+                    wbsTypes.add(4);
+                }
+                if (item.getReferenceWbsTemplateIdLar() != null && item.getReferenceWbsTemplateIdLar() > 0) {
+                    wbsTypes.add(5);
+                }
+                item.setWbsTypes(wbsTypes);
+            });
+        }
+        return pagedList;
+    }
+
 }

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

@@ -49,6 +49,7 @@ import org.springblade.manager.bean.TableInfo;
 import org.springblade.manager.dto.ServicePlanDTO;
 import org.springblade.manager.dto.ServiceUserDto;
 import org.springblade.manager.entity.*;
+import org.springblade.manager.util.DataStructureFormatUtils;
 import org.springblade.manager.utils.FileUtils;
 import org.springblade.manager.vo.ServicePlanVO;
 import org.springblade.manager.mapper.ServicePlanMapper;
@@ -518,6 +519,7 @@ public class ServicePlanServiceImpl extends BaseServiceImpl<ServicePlanMapper, S
         try {
             if (dataIn.size() >= 1) {
                 Map<String, Object> mysqlData = dataIn.get(0);
+                DataStructureFormatUtils.parseDataByKey(mysqlData);
                 for (String key : mysqlData.keySet()) {
                     String tabVal = mysqlData.get(key) + "";
                     // 时间段处理
@@ -801,6 +803,7 @@ public class ServicePlanServiceImpl extends BaseServiceImpl<ServicePlanMapper, S
             keyNames= getKeyNameList(doc);
                 if (dataIn.size() >= 1) {
                     Map<String, Object> mysqlData = dataIn.get(0);
+                    DataStructureFormatUtils.parseDataByKey(mysqlData);
                     for (String key : mysqlData.keySet()) {
                         String tabVal = mysqlData.get(key) + "";
                         // 时间段处理

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

@@ -146,7 +146,7 @@ public class SignConfigServiceImpl extends BaseServiceImpl<SignConfigMapper, Sig
                 }
             }
             List<String> tableIds = signConfigDTO.getTableIds();
-            if (tableIds != null && !tableIds.isEmpty()) {
+            if (tableIds != null && !tableIds.isEmpty() && (signConfigDTO.getTableType() == null || signConfigDTO.getTableType() != 0)) {
                 List<TableInfo> tableInfos = tableInfoService.list(Wrappers.<TableInfo>lambdaQuery().select(TableInfo::getTabChName, TableInfo::getId, TableInfo::getTabType).in(TableInfo::getId, tableIds));
                 if (tableInfos == null || tableInfos.isEmpty()) {
                     throw new ServiceException("获取元素表信息失败");
@@ -170,7 +170,7 @@ public class SignConfigServiceImpl extends BaseServiceImpl<SignConfigMapper, Sig
             transactionTemplate.execute(transactionStatus -> {
                 if (config.getId() !=  null) {
                     this.updateById(config);
-                    if (!signConfigRelationsByTables.isEmpty()) {
+                    if (!signConfigRelationsByTables.isEmpty() || config.getTableType() == 0) {
                         signConfigRelationService.remove(Wrappers.<SignConfigRelation>lambdaQuery().eq(SignConfigRelation::getConfId, config.getId()).eq(SignConfigRelation::getType, 0));
                     }
                     if (!signConfigRelationsByRoles.isEmpty()) {
@@ -293,7 +293,7 @@ public class SignConfigServiceImpl extends BaseServiceImpl<SignConfigMapper, Sig
     }
 
     @Override
-    public List<TextdictInfoVO> hasSignConfig(String initTableName, List<String> keyNames, TextdictInfoVO vo) {
+    public List<TextdictInfoVO> hasSignConfig(String initTableName, Collection<String> keyNames, TextdictInfoVO vo) {
         List<TextdictInfoVO> textdictInfoVOS = new ArrayList<>();
         if (keyNames == null || keyNames.isEmpty()) {
             return textdictInfoVOS;
@@ -304,7 +304,7 @@ public class SignConfigServiceImpl extends BaseServiceImpl<SignConfigMapper, Sig
             return textdictInfoVOS;
         }
         List<WbsFormElement> list = this.wbsFormElementMapper.selectList(Wrappers.<WbsFormElement>lambdaQuery().select(WbsFormElement::getEName, WbsFormElement::getEKey)
-                .eq(WbsFormElement::getFId, tableInfos.get(0).getId()).in(WbsFormElement::getEKey, keyMap.keySet()));
+                .eq(WbsFormElement::getFId, tableInfos.get(0).getId()).eq(WbsFormElement::getEType, 6).in(WbsFormElement::getEKey, keyMap.keySet()));
         if (list == null || list.isEmpty()) {
             return textdictInfoVOS;
         }

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

@@ -56,7 +56,7 @@ public class TableInfoServiceImpl extends BaseServiceImpl<TableInfoMapper, Table
      * 十分钟执行一次
      * 替换动态表中的阿里云地址
      */
-    @Scheduled(cron = "0 */10 * * * ?")
+    //@Scheduled(cron = "0 */10 * * * ?")
 //    @Scheduled(fixedDelay = 60000)
     public void aliyunUrlReplace() {
         System.out.println("执行阿里云地址替换-----------------------------开始");

+ 28 - 46
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/TextdictInfoServiceImpl.java

@@ -16,20 +16,32 @@
  */
 package org.springblade.manager.service.impl;
 
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.apache.commons.lang.StringUtils;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 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.CommonUtil;
+import org.springblade.common.utils.SnowFlakeUtil;
+import org.springblade.common.utils.SystemUtils;
+import org.springblade.core.tool.utils.*;
+import org.springblade.common.constant.CommonConstant;
+import org.springblade.common.utils.CommonUtil;
 import org.springblade.core.tool.utils.FileUtil;
 import org.springblade.core.tool.utils.Func;
 import org.springblade.core.tool.utils.IoUtil;
 import org.springblade.core.tool.utils.ResourceUtil;
 import org.springblade.manager.entity.TextdictInfo;
+import org.springblade.manager.entity.WbsTreeContract;
 import org.springblade.manager.entity.WbsTreePrivate;
 import org.springblade.manager.mapper.TextdictInfoMapper;
 import org.springblade.manager.mapper.WbsTreePrivateMapper;
@@ -39,7 +51,6 @@ import org.springblade.manager.utils.FileUtils;
 import org.springblade.manager.vo.TextdictBy345VO;
 import org.springblade.manager.vo.TextdictInfoVO;
 import org.springblade.system.cache.ParamCache;
-import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -48,7 +59,9 @@ import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.InputStream;
+import java.io.*;
 import java.util.*;
+import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.stream.Collectors;
 
 /**
@@ -71,53 +84,22 @@ public class TextdictInfoServiceImpl extends ServiceImpl<TextdictInfoMapper, Tex
             WbsTreePrivate privateInfo = wbsTreePrivateMapper.getByPKeyId(Func.toLong(textdictInfo.getTabId() + ""));
             String htmlUrl = privateInfo.getHtmlUrl();
             try {
-                InputStream fileInputStream = FileUtils.getInputStreamByUrl(htmlUrl);
-                String htmlString = IoUtil.readToString(fileInputStream);
-                Document doc = Jsoup.parse(htmlString);
-                Elements table = doc.getElementsByAttribute("dqid");
-                List<String> dqid = new ArrayList<>();
-                List<String> keys = new ArrayList<>();
-                for(Element ek:table){
-                    dqid.addAll(Func.toStrList("\\|\\|",ek.attr("dqid")));
-                    Elements keyNames = ek.getElementsByAttribute("keyname");
-                    if(Func.isNotEmpty(keyNames)){
-                        for(Element keyName:keyNames){
-                            keys.addAll(Func.toStrList("\\|\\|",keyName.attr("keyname")));
-                        }
-                    }
-                }
                 if(Func.isNotEmpty(textdictInfo.getShowType()) && textdictInfo.getShowType() == 1){
-                    if(Func.isNotEmpty(dqid) && dqid.size() > 0){
-                        textdict = baseMapper.selectTextdictBYIds(dqid,privateInfo.getProjectId());
-                    }else {
-                        textdict = new ArrayList<>();
+                    textdict = baseMapper.selectTextDictInfoByProjectIdAndTabId(page, privateInfo);
+                    if (textdict == null || textdict.isEmpty()) {
+                        textdict = baseMapper.selectTextdictInfoByExcelIdAndProjectIdAndHtmlUrl(page, privateInfo);
                     }
-                    if (!keys.isEmpty()) {
-                        // 查询系统级电签配置
-                        TextdictInfoVO temp = null;
-                        if (textdict != null && !textdict.isEmpty()) {
-                            temp = textdict.get(0);
-                        }
-                        if (temp == null) {
-                            temp = new TextdictInfoVO();
-                            temp.setProjectId(privateInfo.getProjectId());
-                            temp.setExcelId(privateInfo.getExcelId() + "");
-                            temp.setTabId(privateInfo.getPKeyId() + "");
-                            temp.setType(2);
-                        }
-                        List<TextdictInfoVO> textdictList = iSignConfigService.hasSignConfig(privateInfo.getInitTableName(), keys, temp);
-                        if (textdict == null || textdict.isEmpty()) {
-                            textdict = textdictList;
-                        } else {
-                            Map<String, Map<String, TextdictInfoVO>> map = textdict.stream().collect(Collectors.groupingBy(TextdictInfoVO::getColKey, Collectors.toMap(TextdictInfoVO::getSigRoleId, v -> v, (v1, v2) -> v1)));
-                            List<TextdictInfoVO> collect = textdictList.stream().filter(textdictInfoVO -> {
-                                Map<String, TextdictInfoVO> voMap = map.get(textdictInfoVO.getColKey());
-                                if (voMap != null && !voMap.isEmpty() ) {
-                                    return voMap.get(textdictInfoVO.getSigRoleId()) == null;
-                                }
-                                return true;
-                            }).collect(Collectors.toList());
-                            textdict.addAll(collect);
+                    if (textdict != null && !textdict.isEmpty()) {
+                        Map<String, TextdictInfoVO> map = textdict.stream().collect(Collectors.toMap(item -> item.getProjectId() + item.getTabId() + item.getColKey() + item.getColName(), item -> item, (v1, v2) -> v1));
+                        textdict = new ArrayList<>(map.values());
+                        InputStream fileInputStream = FileUtils.getInputStreamByUrl(htmlUrl);
+                        String htmlString = IoUtil.readToString(fileInputStream);
+                        Document doc = Jsoup.parse(htmlString);
+                        for (TextdictInfoVO vo : textdict) {
+                            Elements keyName = doc.getElementsByAttributeValue("keyname", vo.getColKey());
+                            if (keyName ==  null || keyName.isEmpty()) {
+                                vo.setIsMatch(0);
+                            }
                         }
                     }
                 }else{

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

@@ -147,6 +147,7 @@ public class WbsFormElementServiceImpl extends BaseServiceImpl<WbsFormElementMap
     }
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public WbsFormElement saveAndSyn(WbsFormElement wbsFormElement, String tableName) {
 
         String isExitSql = "select * from information_schema.TABLES where TABLE_NAME='" + tableName + "'";
@@ -164,28 +165,19 @@ public class WbsFormElementServiceImpl extends BaseServiceImpl<WbsFormElementMap
             tableName = tableInfo.getTabEnName();
         }
 
-
-        //当前表总字段长度
-        int sumLength = baseMapper.selectSumColumnLength(jdbcTemplate.queryForObject("SELECT DATABASE()", String.class), tableName);
-        if (sumLength + wbsFormElement.getELength() > MYSQL_MAX_COLUMN_LENGTH) {
-            updateTableFieldLength(tableName);
-            throw new ServiceException("无法添加字段,可用长度:" + (MYSQL_MAX_COLUMN_LENGTH - sumLength) + ",已自动调整其他字段长度,请重新添加");
-        }
         try {
-            // 删除 元素和实体表不匹配的字段
-            //baseMapper.deleteElementByfId2();
-
             //获取当前表单下所有元素
             List<WbsFormElement> wbsFormElements = baseMapper.selectList(Wrappers.<WbsFormElement>query().lambda().eq(WbsFormElement::getFId, wbsFormElement.getFId()));
             String substring = "";
             List<String> eKeyNum = new ArrayList<>();
+            long newFiled = 0;
             if (wbsFormElements.size() > 0) {
                 for (WbsFormElement formElement : wbsFormElements) {
                     String eKey = formElement.getEKey();
                     substring = eKey.split("_")[1];
                 }
                 if (StringUtils.isNotEmpty(substring)) {
-                    long newFiled = Long.parseLong(substring) + 1;
+                    newFiled = Long.parseLong(substring) + 1;
                     String substring1 = "key_" + newFiled;
                     eKeyNum.add(substring1);
                     if (wbsFormElement.getEType() == 4) {
@@ -201,75 +193,66 @@ public class WbsFormElementServiceImpl extends BaseServiceImpl<WbsFormElementMap
 
             StringBuilder sbr1 = new StringBuilder();
             String fieldType = WbsElementUtil.getInitTableFiledType(wbsFormElement.getEType());
-
-            if ("varchar".equals(fieldType)) {
-                if (wbsFormElement.getELength() > 1000 || wbsFormElement.getELength() < 10) {
-                    throw new ServiceException("请输入正确的长度,范围为10-1000");
-                } else {
-                    //新增
-                    wbsFormElement.setELength(DEFAULT_ELEMENT_LENGTH_VARCHAR);
-                    baseMapper.insert(wbsFormElement);
-
-                    //同步
-                    //sbr1.append(" ").append(fieldType).append("(").append(wbsFormElement.getELength()).append(")");
-
-                    sbr1.append(" ").append("varchar").append("(").append(DEFAULT_ELEMENT_LENGTH_VARCHAR).append(")");
-                    String sql = newName + " " + sbr1;
-                    baseMapper.alterAddFiled(sql, tableName);
-                    return wbsFormElement;
-                }
-
-            } else if ("bigint".equals(fieldType)) {
-                if (wbsFormElement.getELength() > 255 || wbsFormElement.getELength() < 10) {
-                    throw new ServiceException("请输入正确的长度,范围为10-255");
-                } else {
-                    //新增
-                    wbsFormElement.setELength(DEFAULT_ELEMENT_LENGTH_VARCHAR);
-                    baseMapper.insert(wbsFormElement);
-
-                    //同步
-                    //sbr1.append(" ").append(fieldType).append("(").append(wbsFormElement.getELength()).append(")");
-
-                    sbr1.append(" ").append("varchar").append("(").append(DEFAULT_ELEMENT_LENGTH_VARCHAR).append(")");
-                    String sql = newName + " " + sbr1;
-                    baseMapper.alterAddFiled(sql, tableName);
-                    return wbsFormElement;
-                }
-
-            } else if ("decimal".equals(fieldType)) {
-                if (wbsFormElement.getELength() > 65 || wbsFormElement.getELength() < 10) {
-                    throw new ServiceException("请输入正确的长度,范围为10-65");
-                } else {
-                    //新增
-                    baseMapper.insert(wbsFormElement);
-
-                    //同步
-                    //sbr1.append(" ").append(fieldType).append("(").append(wbsFormElement.getELength()).append(")");
-
-                    sbr1.append(" ").append("varchar").append("(").append(DEFAULT_ELEMENT_LENGTH_VARCHAR).append(")");
-                    String sql = newName + " " + sbr1;
-                    baseMapper.alterAddFiled(sql, tableName);
-                    return wbsFormElement;
-                }
-            } else if ("datetime".equals(fieldType)) {
-                if (wbsFormElement.getELength() > 100 || wbsFormElement.getELength() < 0) {
-                    throw new ServiceException("请输入正确的长度,范围为0-100");
-                } else {
-                    //新增
-                    wbsFormElement.setELength(DEFAULT_ELEMENT_LENGTH_VARCHAR);
-                    baseMapper.insert(wbsFormElement);
-
-                    //同步
-                    //sbr1.append(" ").append(fieldType).append("(").append(0).append(")");
-
-                    sbr1.append(" ").append("varchar").append("(").append(DEFAULT_ELEMENT_LENGTH_VARCHAR).append(")");
-                    String sql = newName + " " + sbr1;
-                    baseMapper.alterAddFiled(sql, tableName);
-                    return wbsFormElement;
+            if (newFiled > 80) {
+                alterMTableOpsFiled(tableName);
+            } else {
+                if ("varchar".equals(fieldType)) {
+                    if (wbsFormElement.getELength() > 1000 || wbsFormElement.getELength() < 10) {
+                        throw new ServiceException("请输入正确的长度,范围为10-1000");
+                    } else {
+                        //新增
+                        wbsFormElement.setELength(DEFAULT_ELEMENT_LENGTH_VARCHAR);
+                        baseMapper.insert(wbsFormElement);
+                        sbr1.append(" ").append("varchar").append("(").append(DEFAULT_ELEMENT_LENGTH_VARCHAR).append(")");
+                        String sql = newName + " " + sbr1;
+                        baseMapper.alterAddFiled(sql, tableName);
+                        return wbsFormElement;
+                    }
+                } else if ("bigint".equals(fieldType)) {
+                    if (wbsFormElement.getELength() > 255 || wbsFormElement.getELength() < 10) {
+                        throw new ServiceException("请输入正确的长度,范围为10-255");
+                    } else {
+                        //新增
+                        wbsFormElement.setELength(DEFAULT_ELEMENT_LENGTH_VARCHAR);
+                        baseMapper.insert(wbsFormElement);
+                        sbr1.append(" ").append("varchar").append("(").append(DEFAULT_ELEMENT_LENGTH_VARCHAR).append(")");
+                        String sql = newName + " " + sbr1;
+                        baseMapper.alterAddFiled(sql, tableName);
+                        return wbsFormElement;
+                    }
+                } else if ("decimal".equals(fieldType)) {
+                    if (wbsFormElement.getELength() > 65 || wbsFormElement.getELength() < 10) {
+                        throw new ServiceException("请输入正确的长度,范围为10-65");
+                    } else {
+                        //新增
+                        baseMapper.insert(wbsFormElement);
+                        sbr1.append(" ").append("varchar").append("(").append(DEFAULT_ELEMENT_LENGTH_VARCHAR).append(")");
+                        String sql = newName + " " + sbr1;
+                        baseMapper.alterAddFiled(sql, tableName);
+                        return wbsFormElement;
+                    }
+                } else if ("datetime".equals(fieldType)) {
+                    if (wbsFormElement.getELength() > 100 || wbsFormElement.getELength() < 0) {
+                        throw new ServiceException("请输入正确的长度,范围为0-100");
+                    } else {
+                        //新增
+                        wbsFormElement.setELength(DEFAULT_ELEMENT_LENGTH_VARCHAR);
+                        baseMapper.insert(wbsFormElement);
+                        sbr1.append(" ").append("varchar").append("(").append(DEFAULT_ELEMENT_LENGTH_VARCHAR).append(")");
+                        String sql = newName + " " + sbr1;
+                        baseMapper.alterAddFiled(sql, tableName);
+                        return wbsFormElement;
+                    }
                 }
             }
 
         } catch (Exception e) {
+            if (e.getMessage().contains("Duplicate column name")) {
+                return wbsFormElement;
+            }
+            if (e.getMessage().contains("Row size too large")) {
+                return wbsFormElement;
+            }
             baseMapper.deleteElement(wbsFormElement);
             throw new ServiceException("同步元素字段异常,操作失败:" + e.getMessage());
         }
@@ -360,6 +343,13 @@ public class WbsFormElementServiceImpl extends BaseServiceImpl<WbsFormElementMap
 //                } else if (eLength >= 0 && eLength <= 65) {
 //                    eLength = DEFAULT_ELEMENT_LENGTH_NUMBER;
 //                }
+                String[] split = eKey.split("_");
+                if (split.length > 1 && StringUtil.isNumeric(split[1])) {
+                    long index = Long.parseLong(split[1]);
+                    if (index > 80) {
+                        continue;
+                    }
+                }
                 Integer length = eLengthMap.get(wbsFormElement.getId());
                 if (length == null || !length.equals(eLength)) {
                     //判断是否存在该Key字段
@@ -368,6 +358,9 @@ public class WbsFormElementServiceImpl extends BaseServiceImpl<WbsFormElementMap
                         try {
                             baseMapper.updateFiledType(initTableName, eKey, "varchar", eLength);
                         } catch (Exception e) {
+                            if (e.getMessage().contains("Row size too large")) {
+                                continue;
+                            }
                             e.printStackTrace();
                             this.updateBatchById(beforeUpdateWbsFormElements);
                             return R.fail(eName + "长度范围超出总最大限制,请尝试缩小当前字段与其他字段长度或者联系系统管理员处理");
@@ -396,6 +389,7 @@ public class WbsFormElementServiceImpl extends BaseServiceImpl<WbsFormElementMap
                     try {
                         File writefile = new File(htmlurl);
                         FileUtil.writeToFile(writefile, doc.html(), Boolean.parseBoolean("UTF-8"));
+                        System.out.println("修改成功:"+ htmlurl);
                     }catch (Exception e){
                         System.out.println("修改html文件异常:"+ htmlurl);
                     }finally {
@@ -923,6 +917,13 @@ public class WbsFormElementServiceImpl extends BaseServiceImpl<WbsFormElementMap
             for (WbsFormElement listDatum : listData) {
                 // String initTableFiledType = getInitTableFiledType(listDatum.getEType());
                 // int elementLength = getElementLength(initTableFiledType);
+                String[] split = listDatum.getEKey().split("_");
+                if (split.length > 1 && StringUtil.isNumeric(split[1])) {
+                    long index = Long.parseLong(split[1]);
+                    if (index > 80)  {
+                        alterMTableOpsFiled(initTableName);
+                    };
+                }
                 //同步
                 //判断是否存在该Key字段
                 int row1 = wbsTreeMapper.isThereAField(initTableName, listDatum.getEKey());
@@ -970,87 +971,22 @@ public class WbsFormElementServiceImpl extends BaseServiceImpl<WbsFormElementMap
     }
 
 
-    /**
-     * 修改当前表所有字段的长度 (只用于字段缩减)
-     * 1、字段数量超过80 表数据超过500条 把数据长度为0的旧字段长度改为50
-     * 超过:新字段的默认长度改为150,并且
-     */
-    public void updateTableFieldLength(String tableName) {
-        TableInfo tableInfo = tableInfoMapper.selectOne(Wrappers.<TableInfo>lambdaQuery()
-                .eq(TableInfo::getTabEnName, tableName)
-                .last("limit 1"));
-
-        List<WbsFormElement> wbsFormElements = baseMapper.selectList(Wrappers.<WbsFormElement>lambdaQuery()
-                .eq(WbsFormElement::getFId, tableInfo.getId()));
-        //元素是否存在
-        if (CollectionUtil.isEmpty(wbsFormElements)) {
-            return;
-        }
-        //字段级字段长度缓存
-        Map<String, Integer> lengthMap = new HashMap<>();
-        //查询当前表的所有字段级字段长度
-        List<Map<String, Object>> filedLengths = baseMapper.selectFiledLength(tableName);
-        //表是否存在
-        if (CollectionUtil.isEmpty(filedLengths)) {
-            return;
-        }
-        for (Map<String, Object> filedLength : filedLengths) {
-            BigInteger length = (BigInteger) filedLength.get("length");
-            if (length == null) {
-                continue;
-            }
-            //记录字段与字段长度
-            lengthMap.put(filedLength.get("key").toString(), length.intValue());
-        }
-
-        //这张表是否拥有数据超过500条
-        Integer count = jdbcTemplate.queryForObject("select count(0) from " + tableName, Integer.class);
-
-
-        for (WbsFormElement wbsFormElement : wbsFormElements) {
-
-            String eKey = wbsFormElement.getEKey();
-            //字段不存在
-            if (lengthMap.get(eKey) == null) {
-                continue;
-            }
-            Integer dataLength = baseMapper.selectFiledDataMaxLength(tableName, eKey);
-
-            if (wbsFormElements.size() > 80 && count > 500) {
-                //数据长度
-                dataLength = dataLength == 0 ? 50 : lengthMap.get(eKey) + 100;
-                //如果当前需要设置的长度大于当前字段长度,则跳过
-                if (dataLength > wbsFormElement.getELength()) {
-                    continue;
-                }
-            } else if (wbsFormElements.size() > 80 && count < 500) {
-                //数据长度
-                dataLength = dataLength == 0 ? 100 : lengthMap.get(eKey) + 100;
-                //如果当前需要设置的长度大于当前字段长度,则跳过
-                if (dataLength > wbsFormElement.getELength()) {
-                    continue;
-                }
-            } else if (wbsFormElements.size() < 80 && count > 500) {
-                //数据长度
-                dataLength = dataLength == 0 ? 200 : lengthMap.get(eKey) + 100;
-                //如果当前需要设置的长度大于当前字段长度,则跳过
-                if (dataLength > wbsFormElement.getELength()) {
-                    continue;
-                }
-            } else {
-                //数据长度
-                dataLength = dataLength == 0 ? 200 : lengthMap.get(eKey) + 100;
-                //如果当前需要设置的长度大于当前字段长度,则跳过
-                if (dataLength > wbsFormElement.getELength()) {
-                    continue;
-                }
-                if (dataLength < 200) {
-                    dataLength = 200;
+    private void alterMTableOpsFiled(String initTableName) {
+        int row1 = wbsTreeMapper.isThereAField(initTableName, "key_201");
+        if (row1 == 0) {
+            //追加字段到实体表中
+            try {
+                jdbcTemplate.execute("ALTER TABLE " + initTableName + "  ADD COLUMN key_201 text");
+            } catch (Exception e) {
+                if (!e.getMessage().contains("Duplicate column name")) {
+                    log.error("新增字段异常:", e);
                 }
             }
-            baseMapper.updateFiledType(tableName, eKey, "varchar", dataLength);
-            wbsFormElement.setELength(dataLength);
-            baseMapper.updateById(wbsFormElement);
+            //判断是否追加成功
+            int row2 = wbsTreeMapper.isThereAField(initTableName, "key_201");
+            if (row2 != 1) {
+                throw new ServiceException("新增字段异常, 请联系后台管理员处理");
+            }
         }
     }
 }

+ 59 - 3
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsInfoServiceImpl.java

@@ -1,24 +1,28 @@
 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.toolkit.Wrappers;
 import lombok.AllArgsConstructor;
 import org.springblade.common.utils.SnowFlakeUtil;
 import org.springblade.core.secure.utils.AuthUtil;
 import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.utils.StringUtil;
 import org.springblade.manager.dto.WbsInfoDTO;
+import org.springblade.manager.entity.ProjectInfo;
 import org.springblade.manager.entity.WbsTree;
 import org.springblade.manager.mapper.WbsInfoMapper;
 import org.springblade.manager.service.IWbsInfoService;
 import org.springblade.core.mp.base.BaseServiceImpl;
 import org.springblade.manager.entity.WbsInfo;
 import org.springblade.manager.vo.WbsInfoVO;
+import org.springframework.jdbc.core.BeanPropertyRowMapper;
 import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.stereotype.Service;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import org.springframework.transaction.annotation.Transactional;
 
-import java.util.List;
+import java.util.*;
 
 @Service
 @AllArgsConstructor
@@ -28,8 +32,60 @@ public class WbsInfoServiceImpl extends BaseServiceImpl<WbsInfoMapper, WbsInfo>
     private final JdbcTemplate jdbcTemplate;
 
     @Override
-    public IPage<WbsInfo> selectWbsInfoPage(IPage<WbsInfo> page, WbsInfo wbsInfo) {
-        return page.setRecords(baseMapper.selectWbsInfoPage(page, wbsInfo));
+    public IPage<WbsInfo> selectWbsInfoPage(IPage<WbsInfo> page, WbsInfoDTO wbsInfo) {
+        Set<Long> wbsIds = new HashSet<>();
+        if (StringUtil.hasText(wbsInfo.getProjectName()) || wbsInfo.getProjectId() != null) {
+            List<ProjectInfo> projectInfoList;
+            if (wbsInfo.getProjectId() != null) {
+                projectInfoList = jdbcTemplate.query("select * from m_project_info where id = " + wbsInfo.getProjectId(), new BeanPropertyRowMapper<>(ProjectInfo.class));
+            } else {
+                projectInfoList = jdbcTemplate.query("select * from m_project_info where project_name like '%" + wbsInfo.getProjectName() + "%'", new BeanPropertyRowMapper<>(ProjectInfo.class));
+            }
+            if (projectInfoList.isEmpty()) {
+                return page;
+            }
+            for (ProjectInfo projectInfo : projectInfoList) {
+                if (projectInfo.getReferenceWbsTemplateId() != null) {
+                    wbsIds.add(projectInfo.getReferenceWbsTemplateId());
+                }
+                if (projectInfo.getReferenceWbsTemplateIdTrial() != null) {
+                    wbsIds.add(projectInfo.getReferenceWbsTemplateIdTrial());
+                }
+                if (projectInfo.getReferenceWbsTemplateIdLar() != null) {
+                    wbsIds.add(projectInfo.getReferenceWbsTemplateIdLar());
+                }
+                if (projectInfo.getReferenceWbsTemplateIdMeter() != null) {
+                    wbsIds.add(projectInfo.getReferenceWbsTemplateIdMeter());
+                }
+                if (projectInfo.getReferenceWbsTemplateIdLar() != null) {
+                    wbsIds.add(projectInfo.getReferenceWbsTemplateIdLar());
+                }
+            }
+        }
+        LambdaQueryWrapper<WbsInfo> query = Wrappers.lambdaQuery();
+        if (!wbsIds.isEmpty()) {
+            query.in(WbsInfo::getId, wbsIds);
+        }
+        if (StringUtil.hasText(wbsInfo.getWbsName())) {
+            query.like(WbsInfo::getWbsName, wbsInfo.getWbsName());
+        }
+        if (wbsInfo.getWbsType() != null) {
+            query.eq(WbsInfo::getWbsType, wbsInfo.getWbsType());
+        }
+        IPage<WbsInfo> infoIPage = baseMapper.selectPage(page, query);
+        List<WbsInfo> records = infoIPage.getRecords();
+        if (!records.isEmpty()) {
+            for (WbsInfo record : records) {
+                List<ProjectInfo> projectInfoList = jdbcTemplate.query("select id, project_name from m_project_info where reference_log_wbs_template_id = ? " +
+                                "or reference_wbs_template_id = ? or reference_wbs_template_id_trial = ? or reference_wbs_template_id_lar = ? or reference_wbs_template_id_meter = ?"
+                        ,new Object[]{record.getId(), record.getId(), record.getId(), record.getId(), record.getId()} ,new BeanPropertyRowMapper<>(ProjectInfo.class));
+                if (!projectInfoList.isEmpty()) {
+                    record.setProjectInfoList(projectInfoList);
+                }
+            }
+            records.sort(Comparator.comparing(WbsInfo::getSort));
+        }
+        return infoIPage;
     }
 
     @Override

+ 8 - 2
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeContractServiceImpl.java

@@ -3272,6 +3272,14 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
     }
 
 
+
+    @Override
+    public List<WbsTreeContract> queryListByPIds(List<Long> pIds) {
+        return baseMapper.selectList(Wrappers.<WbsTreeContract>lambdaQuery()
+                .in(WbsTreeContract::getPId, pIds)
+                .eq(WbsTreeContract::getIsDeleted, 0));
+    }
+
     /**
      * 展开所有合并单元格并将值填充到每个单元格
      *
@@ -4712,8 +4720,6 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
         }
     }
 
-
-
     @Override
     public R<List<WbsTreeContract>> getSiblingWbsContract(Long pKeyId) {
         return  R.data(wbsTreeContractMapper.getSiblingWbsContract(pKeyId));

+ 0 - 15
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreePrivateServiceImpl.java

@@ -437,21 +437,6 @@ public class WbsTreePrivateServiceImpl extends BaseServiceImpl<WbsTreePrivateMap
         for (WbsTreePrivateDTO2 wbsTreePrivate : wbsTreeDTO) {
             wbsTreePrivate.setSort(number);
             baseMapper.updateSortById2(wbsTreePrivate.getPKeyId(), wbsTreePrivate.getSort());
-
-            WbsTreePrivate objPrivate = baseMapper.selectOne(Wrappers.<WbsTreePrivate>query().lambda().eq(WbsTreePrivate::getPKeyId, wbsTreePrivate.getPKeyId()));
-            if (objPrivate != null) {
-                String projectId = objPrivate.getProjectId();
-                String wbsId = objPrivate.getWbsId();
-                Long id = objPrivate.getId();
-
-//                //合同段wbs树同步排序
-//                LambdaUpdateWrapper<WbsTreeContract> updateWrapper = new LambdaUpdateWrapper<>();
-//                updateWrapper.eq(WbsTreeContract::getWbsId, wbsId);
-//                updateWrapper.eq(WbsTreeContract::getProjectId, projectId);
-//                updateWrapper.eq(WbsTreeContract::getId, id);
-//                updateWrapper.set(WbsTreeContract::getSort, number);
-//                wbsTreeContractMapper.update(null, updateWrapper);
-            }
             number++;
         }
         return true;

+ 16 - 14
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeServiceImpl.java

@@ -557,25 +557,27 @@ public class WbsTreeServiceImpl extends BaseServiceImpl<WbsTreeMapper, WbsTree>
     }
 
     @Override
-    public Object getQueryValueByNodeType(String wbsId, String projectId, String queryValue, Integer nodeType, Integer majorDataType) {
-        Set<WbsTreePrivate> resultNodes = new HashSet<>();
-        LambdaQueryWrapper<WbsTreePrivate> wrapper = Wrappers.<WbsTreePrivate>lambdaQuery()
-                .eq(WbsTreePrivate::getType, 1).eq(WbsTreePrivate::getWbsId, wbsId).eq(WbsTreePrivate::getProjectId, projectId).eq(WbsTreePrivate::getNodeType, nodeType);
-        if (majorDataType != null) {
-            if (majorDataType > 0) {
-                wrapper.eq(WbsTreePrivate::getMajorDataType, majorDataType);
-            } else if (majorDataType == -1) {
-                wrapper.and(wrapper1 -> wrapper1.isNull(WbsTreePrivate::getMajorDataType).or().eq(WbsTreePrivate::getMajorDataType, 0));
+    public Object getQueryValueByNodeType(WbsTreePrivateQueryVO vo) {
+        LambdaQueryWrapper<WbsTreePrivate> wrapper = Wrappers.<WbsTreePrivate>lambdaQuery().eq(WbsTreePrivate::getType, 1).eq(WbsTreePrivate::getWbsId, vo.getWbsId()).eq(WbsTreePrivate::getProjectId, vo.getProjectId());
+        wrapper.eq(vo.getNodeType() != null, WbsTreePrivate::getNodeType, vo.getNodeType());
+        wrapper.eq(vo.getIsAddConceal() != null, WbsTreePrivate::getIsAddConceal, vo.getIsAddConceal());
+        wrapper.eq(vo.getClassName() != null, WbsTreePrivate::getClassName, vo.getClassName());
+        wrapper.eq(vo.getUnitName() != null, WbsTreePrivate::getUnitName, vo.getUnitName());
+        wrapper.like(vo.getQueryValue() != null && !vo.getQueryValue().isEmpty() ,WbsTreePrivate::getNodeName, vo.getQueryValue());
+        wrapper.like(vo.getUniqueCode() != null && !vo.getUniqueCode().isEmpty() ,WbsTreePrivate::getUniqueCode, vo.getUniqueCode());
+        if (vo.getMajorDataType() != null) {
+            if (vo.getMajorDataType() > 0) {
+                wrapper.eq(WbsTreePrivate::getMajorDataType, vo.getMajorDataType());
+            } else if (vo.getMajorDataType() == -1) {
+                wrapper.and( wrapper1 -> wrapper1.isNull(WbsTreePrivate::getMajorDataType).or().eq(WbsTreePrivate::getMajorDataType, 0));
             }
         }
-        if (queryValue != null && !queryValue.trim().isEmpty()) {
-            wrapper.like(WbsTreePrivate::getNodeName, queryValue);
-        }
         List<WbsTreePrivate> wbsTreePrivates = wbsTreePrivateMapper.selectList(wrapper);
-        this.getParentNodesPrivateWbs(wbsTreePrivates, resultNodes, projectId, wbsId);
+        Set<WbsTreePrivate> resultNodes = new HashSet<>();
+        this.getParentNodesPrivateWbs(wbsTreePrivates, resultNodes, vo.getProjectId(), vo.getWbsId());
         resultNodes.addAll(wbsTreePrivates);
         List<WbsTreePrivateQueryValueVO> wbsTreePrivateQueryValueVOS = BeanUtil.copyProperties(resultNodes, WbsTreePrivateQueryValueVO.class);
-        if (wbsTreePrivateQueryValueVOS.size() > 0) {
+        if (!wbsTreePrivateQueryValueVOS.isEmpty()) {
             List<WbsTreePrivateQueryValueVO> listRoot = wbsTreePrivateQueryValueVOS.stream().filter(f -> f.getParentId() == 0L).collect(Collectors.toList());
             Map<Long, List<WbsTreePrivateQueryValueVO>> mapAll = wbsTreePrivateQueryValueVOS.stream().collect(Collectors.groupingBy(WbsTreePrivateQueryValueVO::getParentId));
             this.buildWbsTreePrivateByGetQueryValueByType(listRoot, mapAll);

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

@@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import org.redisson.api.RedissonClient;
 import org.springblade.common.utils.SnowFlakeUtil;
+import org.springblade.common.utils.SystemUtils;
 import org.springblade.core.log.exception.ServiceException;
 import org.springblade.core.secure.BladeUser;
 import org.springblade.core.secure.utils.SecureUtil;
@@ -236,7 +237,7 @@ public class WbsTreeSynchronousRecordServiceImpl extends ServiceImpl<WbsTreeSync
      */
     @Scheduled(fixedDelay = 10000)
     public void syncInit() {
-        // 本地环境跳过执行(可添加日志输出)
+//         本地环境跳过执行(可添加日志输出)
         if (!schedulerEnabled) return;
 
         List<WbsTreeSynchronousRecord> wbsTreeSynchronousRecords = baseMapper.selectList(new QueryWrapper<WbsTreeSynchronousRecord>().lambda()

Niektoré súbory nie sú zobrazené, pretože je v týchto rozdielových dátach zmenené mnoho súborov