소스 검색

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

huangtf 2 년 전
부모
커밋
55ed3898ac
95개의 변경된 파일4316개의 추가작업 그리고 574개의 파일을 삭제
  1. 13 2
      blade-auth/src/main/java/org/springblade/auth/service/BladeUserDetailsServiceImpl.java
  2. 2 2
      blade-common/src/main/java/org/springblade/common/constant/LauncherConstant.java
  3. 5 2
      blade-ops/blade-swagger/src/main/resources/application-dev.yml
  4. 50 0
      blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/dto/ArchiveTaskDTO.java
  5. 44 0
      blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/vo/ArchiveTaskPageVO.java
  6. 17 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/dto/ArchiveTaskBatchRepealDTO.java
  7. 35 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/dto/ArchiveTaskBatchReportDTO.java
  8. 51 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/dto/BusinessTaskDTO.java
  9. 43 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/dto/TaskArchiveDTO.java
  10. 15 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/dto/TaskArchiveOuterLayerDTO.java
  11. 1 1
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/Task.java
  12. 3 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/feign/ArchiveFileClient.java
  13. 16 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/ArchiveFileTaskPDFVO.java
  14. 53 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/BusinessTaskPageVO.java
  15. 7 0
      blade-service-api/blade-e-visa-api/src/main/java/org/springblade/evisa/feign/EVisaClient.java
  16. 46 0
      blade-service-api/blade-e-visa-api/src/main/java/org/springblade/evisa/vo/TaskArchiveDTO.java
  17. 12 0
      blade-service-api/blade-land-api/pom.xml
  18. 21 0
      blade-service-api/blade-land-api/src/main/java/org/springblade/land/dto/CropsInfoDTO.java
  19. 24 0
      blade-service-api/blade-land-api/src/main/java/org/springblade/land/dto/PolicyInfoDTO.java
  20. 37 0
      blade-service-api/blade-land-api/src/main/java/org/springblade/land/dto/PolicyInfoSearchDTO.java
  21. 36 0
      blade-service-api/blade-land-api/src/main/java/org/springblade/land/entity/AttachmentInfo.java
  22. 45 0
      blade-service-api/blade-land-api/src/main/java/org/springblade/land/entity/CropsInfo.java
  23. 36 0
      blade-service-api/blade-land-api/src/main/java/org/springblade/land/entity/LandRole.java
  24. 37 0
      blade-service-api/blade-land-api/src/main/java/org/springblade/land/entity/LandTypeInfo.java
  25. 45 0
      blade-service-api/blade-land-api/src/main/java/org/springblade/land/entity/PolicyInfo.java
  26. 25 0
      blade-service-api/blade-land-api/src/main/java/org/springblade/land/vo/CropsInfoVO.java
  27. 27 0
      blade-service-api/blade-land-api/src/main/java/org/springblade/land/vo/LandRoleVO.java
  28. 5 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/TextdictInfo.java
  29. 12 6
      blade-service-api/blade-system-api/src/main/java/org/springblade/system/vo/CheckedTreeVO.java
  30. 7 1
      blade-service-api/blade-system-api/src/main/java/org/springblade/system/vo/GrantTreeVO.java
  31. 6 0
      blade-service-api/blade-system-api/src/main/java/org/springblade/system/vo/GrantVO.java
  32. 4 0
      blade-service/blade-archive/pom.xml
  33. 30 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchiveFileAutoController.java
  34. 1 3
      blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchiveFileController.java
  35. 310 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchiveFileTaskController.java
  36. 2 1
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchiveProjectConfigServiceImpl.java
  37. 1 1
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchivesAutoServiceImpl.java
  38. 2 2
      blade-service/blade-business/src/main/java/org/springblade/business/controller/ContractLogController.java
  39. 2 0
      blade-service/blade-business/src/main/java/org/springblade/business/controller/EVisaTaskCheckController.java
  40. 547 29
      blade-service/blade-business/src/main/java/org/springblade/business/controller/TaskController.java
  41. 5 0
      blade-service/blade-business/src/main/java/org/springblade/business/feignClient/ArchiveFileClientImpl.java
  42. 28 22
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/ArchiveFileMapper.xml
  43. 7 2
      blade-service/blade-business/src/main/java/org/springblade/business/service/ITaskService.java
  44. 74 1
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TaskServiceImpl.java
  45. 13 0
      blade-service/blade-e-visa/pom.xml
  46. 6 0
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/feign/EVisaClientImpl.java
  47. 5 0
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/service/EVisaService.java
  48. 265 40
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/service/impl/EVisaServiceImpl.java
  49. 117 0
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/utils/PDFUtils.java
  50. 35 0
      blade-service/blade-land/pom.xml
  51. 75 0
      blade-service/blade-land/src/main/java/org/springblade/land/controller/AttachmentInfoController.java
  52. 87 0
      blade-service/blade-land/src/main/java/org/springblade/land/controller/CropsInfoController.java
  53. 99 0
      blade-service/blade-land/src/main/java/org/springblade/land/controller/LandRoleController.java
  54. 92 0
      blade-service/blade-land/src/main/java/org/springblade/land/controller/LandTypeInfoController.java
  55. 92 0
      blade-service/blade-land/src/main/java/org/springblade/land/controller/PolicyInfoController.java
  56. 40 0
      blade-service/blade-land/src/main/java/org/springblade/land/mapper/AttachmentInfoMapper.java
  57. 21 0
      blade-service/blade-land/src/main/java/org/springblade/land/mapper/AttachmentInfoMapper.xml
  58. 43 0
      blade-service/blade-land/src/main/java/org/springblade/land/mapper/CropsInfoMapper.java
  59. 38 0
      blade-service/blade-land/src/main/java/org/springblade/land/mapper/CropsInfoMapper.xml
  60. 45 0
      blade-service/blade-land/src/main/java/org/springblade/land/mapper/LandRoleMapper.java
  61. 28 0
      blade-service/blade-land/src/main/java/org/springblade/land/mapper/LandRoleMapper.xml
  62. 37 0
      blade-service/blade-land/src/main/java/org/springblade/land/mapper/LandTypeInfoMapper.java
  63. 18 0
      blade-service/blade-land/src/main/java/org/springblade/land/mapper/LandTypeInfoMapper.xml
  64. 35 0
      blade-service/blade-land/src/main/java/org/springblade/land/mapper/PolicyInfoMapper.java
  65. 19 0
      blade-service/blade-land/src/main/java/org/springblade/land/mapper/PolicyInfoMapper.xml
  66. 44 0
      blade-service/blade-land/src/main/java/org/springblade/land/service/IAttachmentInfoService.java
  67. 47 0
      blade-service/blade-land/src/main/java/org/springblade/land/service/ICropsInfoService.java
  68. 44 0
      blade-service/blade-land/src/main/java/org/springblade/land/service/ILandRoleService.java
  69. 46 0
      blade-service/blade-land/src/main/java/org/springblade/land/service/ILandTypeInfoService.java
  70. 49 0
      blade-service/blade-land/src/main/java/org/springblade/land/service/IPolicyInfoService.java
  71. 98 0
      blade-service/blade-land/src/main/java/org/springblade/land/service/impl/AttachmentInfoServiceImpl.java
  72. 76 0
      blade-service/blade-land/src/main/java/org/springblade/land/service/impl/CropsInfoServiceImpl.java
  73. 62 0
      blade-service/blade-land/src/main/java/org/springblade/land/service/impl/LandRoleServiceImpl.java
  74. 37 0
      blade-service/blade-land/src/main/java/org/springblade/land/service/impl/LandTypeInfoServiceImpl.java
  75. 134 0
      blade-service/blade-land/src/main/java/org/springblade/land/service/impl/PolicyInfoServiceImpl.java
  76. 74 0
      blade-service/blade-land/src/main/java/org/springblade/land/utils/FileUtils.java
  77. 3 2
      blade-service/blade-manager/src/main/java/com/mixsmart/utils/CustomFunction.java
  78. 17 13
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/AppVersionDetailController.java
  79. 1 2
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ExcelTabController.java
  80. 6 2
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/FormulaController.java
  81. 49 61
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/TextdictInfoController.java
  82. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/formula/ITurnPointCalculator.java
  83. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/FormulaMileage.java
  84. 5 3
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/TextdictInfoMapper.xml
  85. 0 2
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/IWbsParamService.java
  86. 63 10
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ExcelTabServiceImpl.java
  87. 50 238
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormulaServiceImpl.java
  88. 20 23
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsParamServiceImpl.java
  89. 2 2
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreePrivateServiceImpl.java
  90. 0 71
      blade-service/blade-manager/src/main/java/org/springblade/manager/utils/ExcelInfoUtils.java
  91. 271 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/utils/ExcelInfoUtils2.java
  92. 45 13
      blade-service/blade-system/src/main/java/org/springblade/system/controller/MenuController.java
  93. 7 1
      blade-service/blade-system/src/main/java/org/springblade/system/controller/RoleController.java
  94. 18 8
      blade-service/blade-system/src/main/java/org/springblade/system/service/IRoleService.java
  95. 47 6
      blade-service/blade-system/src/main/java/org/springblade/system/service/impl/RoleServiceImpl.java

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

@@ -156,8 +156,11 @@ public class BladeUserDetailsServiceImpl implements UserDetailsService {
                     || user.getUserType().contains(("3"))
                     || user.getUserType().contains(("4"))
                     || user.getUserType().contains(("5"))
-                    || user.getUserType().contains(("6"))) {
-                if (!("1,2,3,4,5,6").equals(user.getUserType())) {
+                    || user.getUserType().contains(("6"))
+                    || user.getUserType().contains(("7"))
+                    || user.getUserType().contains(("8"))
+            ) {
+                if (!("1,2,3,4,5,6,7,8").equals(user.getUserType())) {
                     //如果不是全部权限,那么分批校验登陆平台权限
                     this.judgeLoginPermission(user);
                 }
@@ -268,6 +271,12 @@ public class BladeUserDetailsServiceImpl implements UserDetailsService {
                 case "lar":
                     result = "6"; //lar = 征拆系统
                     break;
+                case "measure":
+                    result = "7"; //measure = 计量系统
+                    break;
+                case "secure":
+                    result = "8"; //secure = 安全
+                    break;
             }
         }
 
@@ -277,6 +286,8 @@ public class BladeUserDetailsServiceImpl implements UserDetailsService {
                 || (("4").equals(result) && user.getUserType().contains("4")) //后管
                 || (("5").equals(result)) // 成本管控系统
                 || (("6").equals(result)) // 征拆系统
+                || (("7").equals(result)) // 计量系统
+                || (("8").equals(result)) // 安全
         ) {
             //放行
             return;

+ 2 - 2
blade-common/src/main/java/org/springblade/common/constant/LauncherConstant.java

@@ -32,11 +32,11 @@ public interface LauncherConstant {
 
     String APPLICATION_ARCHIVE_NAME = APPLICATION_NAME_PREFIX + "archive";
 
-    String APPLICATION_LAND_NAME = APPLICATION_NAME_PREFIX + "land";
-
 
     String APPLICATION_VISUAL_NAME = APPLICATION_NAME_PREFIX + "visual";
 
+    String APPLICATION_LAND_NAME = APPLICATION_NAME_PREFIX + "land";
+
     /**
      * xxljob
      */

+ 5 - 2
blade-ops/blade-swagger/src/main/resources/application-dev.yml

@@ -22,6 +22,9 @@ knife4j:
       - name: 档案接口
         uri: 127.0.0.1:8090
         location: /blade-archive/v2/api-docs
-      - name: 内控系统
+#      - name: 内控系统
+#        uri: 127.0.0.1:8090
+#        location: /blade-control/v2/api-docs
+      - name: 征拆接口
         uri: 127.0.0.1:8090
-        location: /blade-control/v2/api-docs
+        location: /blade-land/v2/api-docs

+ 50 - 0
blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/dto/ArchiveTaskDTO.java

@@ -0,0 +1,50 @@
+package org.springblade.archive.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 档案-任务管理page分页查询DTO
+ */
+@Data
+public class ArchiveTaskDTO implements Serializable {
+
+    @ApiModelProperty(value = "选择菜单类型,1=待办,2=已办,3=我发起的")
+    private Integer selectedType;
+
+    @ApiModelProperty(value = "任务类型")
+    private Integer typeValue;
+
+    @ApiModelProperty(value = "任务状态")
+    private Integer statusValue;
+
+    @ApiModelProperty(value = "当前用户登陆选择的项目id")
+    private Long projectIdValue;
+
+    @ApiModelProperty(value = "下拉框合同段id")
+    private Long contractIdValue;
+
+    @ApiModelProperty(value = "当前用户登陆选择的合同段id(监理合同段使用)")
+    private Long currentContractId;
+
+    @ApiModelProperty(value = "上报批次")
+    private Integer batchValue;
+
+    @ApiModelProperty(value = "开始时间")
+    private String startTimeValue;
+
+    @ApiModelProperty(value = "结束时间")
+    private String endTimeValue;
+
+    @ApiModelProperty(value = "关键字查询输入框")
+    private String queryValue;
+
+    @ApiModelProperty(value = "每页条数")
+    private Integer size;
+
+    @ApiModelProperty(value = "当前页码")
+    private Integer current;
+
+}

+ 44 - 0
blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/vo/ArchiveTaskPageVO.java

@@ -0,0 +1,44 @@
+package org.springblade.archive.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class ArchiveTaskPageVO implements Serializable {
+
+    @ApiModelProperty(value = "任务id")
+    private Long id;
+
+    @ApiModelProperty(value = "任务名称")
+    private String taskName;
+
+    @ApiModelProperty(value = "任务类型")
+    private String taskTypeName;
+
+    @ApiModelProperty(value = "任务状态")
+    private String taskStatusName;
+
+    @ApiModelProperty(value = "开始时间")
+    private String startTime;
+
+    @ApiModelProperty(value = "限时时间")
+    private String endTime;
+
+    @ApiModelProperty(value = "任务描述")
+    private String taskDesc;
+
+    @ApiModelProperty(value = "上报人")
+    private String taskReportUserName;
+
+    @ApiModelProperty(value = "签字人员")
+    private String taskApproveUserNames;
+
+    @ApiModelProperty(value = "电签状态")
+    private String eVisaStatus;
+
+    @ApiModelProperty(value = "电签状态描述")
+    private String eVisaContents;
+
+}

+ 17 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/dto/ArchiveTaskBatchRepealDTO.java

@@ -0,0 +1,17 @@
+package org.springblade.business.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class ArchiveTaskBatchRepealDTO implements Serializable {
+
+    @ApiModelProperty(value = "数据类型,=1表示档案文件收集处的废除;=2时表示任务审批处的废除")
+    private Integer type;
+
+    @ApiModelProperty(value = "数据ids,type=1时表示档案收集数据的ids;type=2时表示审批任务的ids;字符串逗号分割拼接")
+    private String ids;
+
+}

+ 35 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/dto/ArchiveTaskBatchReportDTO.java

@@ -0,0 +1,35 @@
+package org.springblade.business.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class ArchiveTaskBatchReportDTO implements Serializable {
+
+    @ApiModelProperty(value = "档案上报的业务数据ids,字符串逗号分割拼接")
+    private String dataIds;
+
+    @ApiModelProperty(value = "项目id")
+    private String projectId;
+
+    @ApiModelProperty(value = "合同段id")
+    private String contractId;
+
+    @ApiModelProperty(value = "上报批次")
+    private Integer batch;
+
+    @ApiModelProperty(value = "任务名")
+    private String taskName;
+
+    @ApiModelProperty(value = "任务人ids,字符串逗号分割拼接")
+    private String userIds;
+
+    @ApiModelProperty(value = "任务描述")
+    private String taskContent;
+
+    @ApiModelProperty("限定审批时间(天)")
+    private Integer restrictDay;
+
+}

+ 51 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/dto/BusinessTaskDTO.java

@@ -0,0 +1,51 @@
+package org.springblade.business.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+
+/**
+ * 资料填报 - 任务管理page分页查询DTO
+ */
+@Data
+public class BusinessTaskDTO implements Serializable {
+
+    @ApiModelProperty(value = "选择菜单类型,1=待办,2=已办,3=我发起的")
+    private Integer selectedType;
+
+    @ApiModelProperty(value = "任务类型")
+    private Integer typeValue;
+
+    @ApiModelProperty(value = "任务状态")
+    private Integer statusValue;
+
+    @ApiModelProperty(value = "当前用户登陆选择的项目id")
+    private Long projectIdValue;
+
+    @ApiModelProperty(value = "下拉框合同段id")
+    private Long contractIdValue;
+
+    @ApiModelProperty(value = "当前用户登陆选择的合同段id")
+    private Long currentContractId;
+
+    @ApiModelProperty(value = "上报批次")
+    private Integer batchValue;
+
+    @ApiModelProperty(value = "开始时间")
+    private String startTimeValue;
+
+    @ApiModelProperty(value = "结束时间")
+    private String endTimeValue;
+
+    @ApiModelProperty(value = "关键字查询输入框")
+    private String queryValue;
+
+    @ApiModelProperty(value = "每页条数")
+    private Integer size;
+
+    @ApiModelProperty(value = "当前页码")
+    private Integer current;
+
+}

+ 43 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/dto/TaskArchiveDTO.java

@@ -0,0 +1,43 @@
+package org.springblade.business.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 档案审批DTO
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class TaskArchiveDTO implements Serializable {
+
+    @ApiModelProperty("所选taskId")
+    private String taskId;
+
+    @ApiModelProperty("同意传OK(大写),废除可传非OK外任意字符或传空")
+    private String flag;
+
+    @ApiModelProperty("审批意见")
+    private String comment;
+
+    @ApiModelProperty("签章定位集合")
+    private List<Sign> sealStrategy;
+
+    @Data
+    public static class Sign {
+        @ApiModelProperty("签章地址url")
+        private String url;
+        @ApiModelProperty("page页码")
+        private String page;
+        @ApiModelProperty("lx")
+        private String lx;
+        @ApiModelProperty("ly")
+        private String ly;
+    }
+
+}

+ 15 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/dto/TaskArchiveOuterLayerDTO.java

@@ -0,0 +1,15 @@
+package org.springblade.business.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+@Data
+public class TaskArchiveOuterLayerDTO implements Serializable {
+
+    @ApiModelProperty("档案批量审批入参集合")
+    private List<TaskArchiveDTO> taskArchiveDtoList;
+
+}

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

@@ -120,7 +120,7 @@ public class Task extends BaseEntity {
     /**
      * 上报类型,1填报资料,2工程文件
      */
-    @ApiModelProperty("上报类型,1填报资料,2工程文件,3日志资料")
+    @ApiModelProperty("上报类型,1填报资料,2工程文件,3日志资料,4档案")
     private Integer approvalType;
 
     @ApiModelProperty("项目ID")

+ 3 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/feign/ArchiveFileClient.java

@@ -134,4 +134,7 @@ public interface ArchiveFileClient {
 
     @PostMapping(API_PREFIX + "/getListByContractId")
     List<ArchiveFile> getListByContractId(@RequestParam Long contractId);
+
+    @PostMapping(API_PREFIX + "/updateById2")
+    void updateById2(@RequestBody ArchiveFile archiveFile);
 }

+ 16 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/ArchiveFileTaskPDFVO.java

@@ -0,0 +1,16 @@
+package org.springblade.business.vo;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class ArchiveFileTaskPDFVO implements Serializable {
+
+    private Long id;
+
+    private String pdfUrl;
+
+    private String fileName;
+
+}

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

@@ -0,0 +1,53 @@
+package org.springblade.business.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class BusinessTaskPageVO implements Serializable {
+
+    @ApiModelProperty(value = "任务id")
+    private Long id;
+
+    @ApiModelProperty(value = "任务名称")
+    private String taskName;
+
+    @ApiModelProperty(value = "任务类型")
+    private String taskTypeName;
+
+    @ApiModelProperty(value = "任务状态")
+    private String taskStatusName;
+
+    @ApiModelProperty(value = "开始时间")
+    private String startTime;
+
+    @ApiModelProperty(value = "限时时间")
+    private String endTime;
+
+    @ApiModelProperty(value = "任务描述")
+    private String taskDesc;
+
+    @ApiModelProperty(value = "上报人")
+    private String taskReportUserName;
+
+    @ApiModelProperty(value = "签字人员")
+    private String taskApproveUserNames;
+
+    @ApiModelProperty(value = "电签状态")
+    private String eVisaStatus;
+
+    @ApiModelProperty(value = "电签状态描述")
+    private String eVisaContents;
+
+    @ApiModelProperty(value = "上报类型")
+    private Integer approvalType;
+
+    @ApiModelProperty(value = "数据来源id")
+    private String formDataId;
+
+    @ApiModelProperty(value = "流程实例id")
+    private String processInstanceId;
+
+}

+ 7 - 0
blade-service-api/blade-e-visa-api/src/main/java/org/springblade/evisa/feign/EVisaClient.java

@@ -4,6 +4,7 @@ import org.springblade.common.constant.EVisaConstant;
 import org.springblade.evisa.vo.CertBeanVO;
 import org.springblade.evisa.vo.EVisaMakeSealVO;
 import org.springblade.evisa.vo.EVisaTaskApprovalVO;
+import org.springblade.evisa.vo.TaskArchiveDTO;
 import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
@@ -31,6 +32,12 @@ public interface EVisaClient {
     @PostMapping(API_PREFIX + "/eVisa")
     String eVisa(@RequestBody EVisaTaskApprovalVO task);
 
+    /**
+     * 电签(自定义签章)
+     */
+    @PostMapping(API_PREFIX + "/eVisa/custom")
+    void eVisaCustom(@RequestBody org.springblade.evisa.vo.TaskArchiveDTO eVisaObj);
+
     /**
      * 创建印模
      */

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

@@ -0,0 +1,46 @@
+package org.springblade.evisa.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 档案审批DTO
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class TaskArchiveDTO implements Serializable {
+
+    @ApiModelProperty("所选taskId")
+    private String taskId;
+
+    @ApiModelProperty("同意传OK(大写),废除可传非OK外任意字符或传空")
+    private String flag;
+
+    @ApiModelProperty("审批意见")
+    private String comment;
+
+    //1=审批任务,2=认证
+    private Integer type;
+
+    @ApiModelProperty("签章定位集合")
+    private List<Sign> sealStrategy;
+
+    @Data
+    public static class Sign {
+        @ApiModelProperty("签章地址url")
+        private String url;
+        @ApiModelProperty("page页码")
+        private String page;
+        @ApiModelProperty("lx")
+        private String lx;
+        @ApiModelProperty("ly")
+        private String ly;
+    }
+
+}

+ 12 - 0
blade-service-api/blade-land-api/pom.xml

@@ -19,4 +19,16 @@
         <maven.compiler.target>8</maven.compiler.target>
     </properties>
 
+    <dependencies>
+        <dependency>
+            <groupId>org.springblade</groupId>
+            <artifactId>blade-common</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springblade</groupId>
+            <artifactId>blade-user-api</artifactId>
+            <version>${bladex.project.version}</version>
+        </dependency>
+    </dependencies>
+
 </project>

+ 21 - 0
blade-service-api/blade-land-api/src/main/java/org/springblade/land/dto/CropsInfoDTO.java

@@ -0,0 +1,21 @@
+package org.springblade.land.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springblade.land.entity.CropsInfo;
+
+import java.util.List;
+
+/**
+ * @Param
+ * @Author wangwl
+ * @Date 2023/9/13 11:09
+ **/
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class CropsInfoDTO extends CropsInfo {
+
+    @ApiModelProperty(value = "子集合")
+    private List<CropsInfo> childrenList;
+}

+ 24 - 0
blade-service-api/blade-land-api/src/main/java/org/springblade/land/dto/PolicyInfoDTO.java

@@ -0,0 +1,24 @@
+package org.springblade.land.dto;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springblade.core.mp.base.BaseEntity;
+import org.springblade.land.entity.AttachmentInfo;
+import org.springblade.land.entity.PolicyInfo;
+
+import java.util.List;
+
+/**
+ * @Param  政策法规-附件表
+ * @Author wangwl
+ * @Date 2023/9/12 11:47
+ **/
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class PolicyInfoDTO extends PolicyInfo {
+
+    @ApiModelProperty(value = "附件集合")
+    private List<AttachmentInfo> list;
+}

+ 37 - 0
blade-service-api/blade-land-api/src/main/java/org/springblade/land/dto/PolicyInfoSearchDTO.java

@@ -0,0 +1,37 @@
+package org.springblade.land.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springblade.land.entity.AttachmentInfo;
+import org.springblade.land.entity.PolicyInfo;
+
+import java.time.LocalDate;
+import java.util.List;
+
+/**
+ * @Param  政策法规-附件表
+ * @Author wangwl
+ * @Date 2023/9/12 11:47
+ **/
+@Data
+public class PolicyInfoSearchDTO {
+
+    @ApiModelProperty(value = "项目id")
+    private Long projectId;
+
+    @ApiModelProperty(value = "名称")
+    private String name;
+
+    @ApiModelProperty(value = "区域id")
+    private Long areaId;
+
+    @ApiModelProperty(value = "1政策法规2双方协议")
+    private Integer type;
+
+    @ApiModelProperty(value = "开始时间")
+    private LocalDate startDate;
+
+    @ApiModelProperty(value = "结束时间")
+    private LocalDate endDate;
+}

+ 36 - 0
blade-service-api/blade-land-api/src/main/java/org/springblade/land/entity/AttachmentInfo.java

@@ -0,0 +1,36 @@
+package org.springblade.land.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springblade.core.mp.base.BaseEntity;
+
+/**
+ * @Param  政策法规-附件表
+ * @Author wangwl
+ * @Date 2023/9/12 11:47
+ **/
+@Data
+@TableName("l_attachment_info")
+@EqualsAndHashCode(callSuper = true)
+public class AttachmentInfo extends BaseEntity {
+
+    @ApiModelProperty(value = "项目id")
+    private Long projectId;
+
+    @ApiModelProperty(value = "主键id")
+    private Long masterId;
+
+    @ApiModelProperty(value = "附件名称")
+    private String name;
+
+    @ApiModelProperty(value = "附件路径")
+    private String domainUrl;
+
+    @ApiModelProperty(value = "附件后缀")
+    private String extension;
+
+    @ApiModelProperty(value = "附件PDF路径")
+    private String domainPdfUrl;
+}

+ 45 - 0
blade-service-api/blade-land-api/src/main/java/org/springblade/land/entity/CropsInfo.java

@@ -0,0 +1,45 @@
+package org.springblade.land.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springblade.core.mp.base.BaseEntity;
+
+/**
+ * @Param
+ * @Author wangwl
+ * @Date 2023/9/13 10:57
+ **/
+@Data
+@TableName("l_crops_info")
+@EqualsAndHashCode(callSuper = true)
+public class CropsInfo extends BaseEntity {
+
+    @ApiModelProperty(value = "项目id")
+    private Long projectId;
+
+    @ApiModelProperty(value = "父id")
+    private Long parentId;
+
+    @ApiModelProperty(value = "单位名称")
+    private String unitName;
+
+    @ApiModelProperty(value = "规格名称")
+    private String specificationName;
+
+    @ApiModelProperty(value = "区域id")
+    private Long areaId;
+
+    @ApiModelProperty(value = "名称")
+    private String name;
+
+    @ApiModelProperty(value = "补偿性质")
+    private Integer compensationType;
+
+    @ApiModelProperty(value = "政府补偿标准")
+    private String governmentStand;
+
+    @ApiModelProperty(value = "协定补偿标准")
+    private String agreementStand;
+}

+ 36 - 0
blade-service-api/blade-land-api/src/main/java/org/springblade/land/entity/LandRole.java

@@ -0,0 +1,36 @@
+package org.springblade.land.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springblade.core.mp.base.BaseEntity;
+
+/**
+ * @Param
+ * @Author wangwl
+ * @Date 2023/9/13 16:58
+ **/
+@Data
+@TableName("l_land_role")
+@EqualsAndHashCode(callSuper = true)
+public class LandRole extends BaseEntity {
+
+    @ApiModelProperty(value = "项目id")
+    private Long projectId;
+
+    @ApiModelProperty(value = "编号")
+    private String number;
+
+    @ApiModelProperty(value = "名称")
+    private String name;
+
+    @ApiModelProperty(value = "备注")
+    private String remark;
+
+    @ApiModelProperty(value = "角色用户")
+    private String allUser;
+
+    @ApiModelProperty(value = "区域id")
+    private Long areaId;
+}

+ 37 - 0
blade-service-api/blade-land-api/src/main/java/org/springblade/land/entity/LandTypeInfo.java

@@ -0,0 +1,37 @@
+package org.springblade.land.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springblade.core.mp.base.BaseEntity;
+
+/**
+ * @Param
+ * @Author wangwl
+ * @Date 2023/9/13 9:27
+ **/
+@Data
+@TableName("l_land_type_info")
+@EqualsAndHashCode(callSuper = true)
+public class LandTypeInfo extends BaseEntity {
+
+    @ApiModelProperty(value = "项目id")
+    private Long projectId;
+
+    @ApiModelProperty(value = "区域id")
+    private Long areaId;
+
+    @ApiModelProperty(value = "名称")
+    private String name;
+
+    @ApiModelProperty(value = "土地性质")
+    private Integer landNature;
+
+    @ApiModelProperty(value = "政府补偿标准")
+    private String governmentStand;
+
+    @ApiModelProperty(value = "协定赔偿标准")
+    private String agreementStand;
+
+}

+ 45 - 0
blade-service-api/blade-land-api/src/main/java/org/springblade/land/entity/PolicyInfo.java

@@ -0,0 +1,45 @@
+package org.springblade.land.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springblade.core.mp.base.BaseEntity;
+
+import java.time.LocalDate;
+
+/**
+ * @Param  政策法规,双方协议表
+ * @Author wangwl
+ * @Date 2023/9/12 11:03
+ **/
+@Data
+@TableName("l_policy_info")
+@EqualsAndHashCode(callSuper = true)
+public class PolicyInfo extends BaseEntity {
+
+    @ApiModelProperty(value = "项目id")
+    private Long projectId;
+
+    @ApiModelProperty(value = "业务编号")
+    private String number;
+
+    @ApiModelProperty(value = "名称")
+    private String name;
+
+    @ApiModelProperty(value = "区域id")
+    private Long areaId;
+
+    @ApiModelProperty(value = "备注")
+    private String remark;
+
+    @ApiModelProperty(value = "附件pdf路径")
+    private String pdfUrl;
+
+    @ApiModelProperty(value = "类型1政策法规2双方协议")
+    private Integer type;
+
+    @ApiModelProperty(value = "类型1政策法规2双方协议")
+    private LocalDate uploadDate;
+
+}

+ 25 - 0
blade-service-api/blade-land-api/src/main/java/org/springblade/land/vo/CropsInfoVO.java

@@ -0,0 +1,25 @@
+package org.springblade.land.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springblade.land.entity.CropsInfo;
+
+import java.util.List;
+
+/**
+ * @Param
+ * @Author wangwl
+ * @Date 2023/9/13 11:09
+ **/
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class CropsInfoVO extends CropsInfo {
+
+    @ApiModelProperty(value = "补偿性质名称")
+    private String compensationTypeName;
+
+    @ApiModelProperty(value = "子集合")
+    private List<CropsInfo> childrenList;
+
+}

+ 27 - 0
blade-service-api/blade-land-api/src/main/java/org/springblade/land/vo/LandRoleVO.java

@@ -0,0 +1,27 @@
+package org.springblade.land.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springblade.core.secure.BladeUser;
+import org.springblade.land.entity.CropsInfo;
+import org.springblade.land.entity.LandRole;
+import org.springblade.system.user.entity.User;
+import org.springframework.boot.autoconfigure.security.SecurityProperties;
+
+import java.util.List;
+
+/**
+ * @Param
+ * @Author wangwl
+ * @Date 2023/9/13 11:09
+ **/
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class LandRoleVO extends LandRole {
+
+    @ApiModelProperty(value = "用户集合")
+    private List<User> allUserList;
+
+
+}

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

@@ -92,6 +92,11 @@ public class TextdictInfo implements Serializable {
      */
     private double pyzby;
 
+    /**
+     * excelId
+     */
+    private String excelId;
+
     /**
      * 是否删除
      */

+ 12 - 6
blade-service-api/blade-system-api/src/main/java/org/springblade/system/vo/CheckedTreeVO.java

@@ -27,14 +27,20 @@ public class CheckedTreeVO implements Serializable {
     //表单
     private List<String> tableOwners;
 
-    private List<String> dataScope;
-
-    private List<String> apiScope;
-
-    // 内控系统
+    //内控系统
     private List<String> hacMenu;
 
-    // 征拆系统
+    //征拆系统
     private List<String> larMenu;
 
+    //计量系统
+    private List<String> measureMenu;
+
+    //安全系统
+    private List<String> secureMenu;
+
+    private List<String> dataScope;
+
+    private List<String> apiScope;
+
 }

+ 7 - 1
blade-service-api/blade-system-api/src/main/java/org/springblade/system/vo/GrantTreeVO.java

@@ -26,12 +26,18 @@ public class GrantTreeVO implements Serializable {
     //档案菜单
     private List<TreeNodeVO> archivesMenu;
 
-    // 内控系统
+    //内控系统
     private List<TreeNodeVO> hacMenu;
 
     //征拆系统
     private List<TreeNodeVO> larMenu;
 
+    //计量系统
+    private List<TreeNodeVO> measureMenu;
+
+    //安全系统
+    private List<TreeNodeVO> secureMenu;
+
     //数据
     private List<TreeNodeVO> dataScope;
 

+ 6 - 0
blade-service-api/blade-system-api/src/main/java/org/springblade/system/vo/GrantVO.java

@@ -33,6 +33,12 @@ public class GrantVO implements Serializable {
     @ApiModelProperty(value = "menuArchivesIds集合-征拆")
     private List<String> menularIds;
 
+    @ApiModelProperty(value = "menuMeasureIds集合-计量")
+    private List<String> menuMeasureIds;
+
+    @ApiModelProperty(value = "menuSecureIds集合-安全")
+    private List<String> menuSecureIds;
+
     @ApiModelProperty(value = "topMenuIds集合")
     private List<Long> topMenuIds;
 

+ 4 - 0
blade-service/blade-archive/pom.xml

@@ -132,6 +132,10 @@
             <version>2.9.1.RELEASE</version>
             <scope>compile</scope>
         </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-test</artifactId>
+        </dependency>
 
     </dependencies>
 

+ 30 - 0
blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchiveFileAutoController.java

@@ -96,6 +96,9 @@ ArchiveFileAutoController extends BladeController {
                             saveVo.setSourceType(2);
                             saveVo.setProjectId(archive.getProjectId() == null ? "" : archive.getProjectId().toString());
                             saveVo.setContractId(archive.getContractId() == null ? "" : archive.getContractId().toString());
+                            saveVo.setIsElement(0);
+                            saveVo.setDutyUser(archive.getUnit());
+                            saveVo.setFileName(archive.getName());
                             list.add(saveVo);
                             if (saveVo.getFilePage() != null && !saveVo.getFilePage().equals("")) {
                                 pageN = pageN + saveVo.getFilePage();
@@ -132,7 +135,34 @@ ArchiveFileAutoController extends BladeController {
                     if (archivesAuto!= null ) {
                         archive.setAutoFileSort(archivesAuto.getAutoFileSort());
                     }
+                    //如果有替换文件,则替换
+                    List<ArchivesAutoVO.ApprovalFile> list = archive.getApprovalFileList();
+                    if (list != null && list.size() > 0) {
+                        //修改档案下的文件
+                        ArchivesAutoVO.ApprovalFile file = list.get(0);
+                        List<ArchiveFile> files = archiveFileClient.getArchiveFileByArchiveID(archive.getId());
+                        if (files != null && files.size() > 0){
+                            //档案收集的只会生成一个文件
+                            ArchiveFile archiveFile = files.get(0);
+                            archiveFile.setFileUrl(file.getFileUrl());
+                            archiveFile.setPdfFileUrl(file.getPdfFileUrl());
+                            archiveFile.setFilePage(file.getFilePage());
+                            archiveFile.setFileSize(file.getFileSize());
+                            //因为案卷提名可能修改,所以修改文件的名称
+                            archiveFile.setFileName(archive.getName());
+                            archiveFile.setDutyUser(archive.getUnit());
+                            //如果当前档案状态为待整改,则修改为已整改
+                            if (archiveFile.getRectification() != null && archiveFile.getRectification() == 1){
+                                archiveFile.setRectification(2);
+                            }
+                            //只修改档案的文件大小和页数
+                            archive.setPageN(file.getFilePage());
+                            archive.setFileSize(file.getFileSize());
+                            archiveFileClient.updateById2(archiveFile);
+                        }
+                    }
                     archivesAutoService.updateById(archive);
+
                 }
             }
         } catch (NumberFormatException e) {

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

@@ -4,7 +4,6 @@ import com.alibaba.excel.util.DateUtils;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
-import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
 import io.swagger.annotations.*;
@@ -25,7 +24,6 @@ import org.springblade.core.oss.model.BladeFile;
 import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.utils.Func;
 import org.springblade.evisa.feign.EVisaClient;
-import org.springblade.manager.entity.ArchiveTree;
 import org.springblade.manager.entity.ArchiveTreeContract;
 import org.springblade.manager.entity.ContractInfo;
 import org.springblade.manager.feign.ArchiveTreeContractClient;
@@ -367,7 +365,7 @@ public class ArchiveFileController extends BladeController {
     public R getDutyUser(Long contractId, Long projectId) {
         ContractInfo contractById = null;
         if (contractId == null || contractId == -1) {
-            if(projectId == null || projectId == -1){
+            if (projectId == null || projectId == -1) {
                 return R.data(null);
             }
             List<Long> longs = new ArrayList<>();

+ 310 - 0
blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchiveFileTaskController.java

@@ -0,0 +1,310 @@
+package org.springblade.archive.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+import com.itextpdf.text.Image;
+import com.itextpdf.text.Rectangle;
+import com.itextpdf.text.pdf.PdfReader;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.AllArgsConstructor;
+import org.apache.commons.lang.StringUtils;
+import org.apache.poi.util.IOUtils;
+import org.springblade.archive.dto.ArchiveTaskDTO;
+import org.springblade.archive.vo.ArchiveTaskPageVO;
+import org.springblade.business.entity.ArchiveFile;
+import org.springblade.business.entity.Task;
+import org.springblade.business.entity.TaskParallel;
+import org.springblade.business.feign.ArchiveFileClient;
+import org.springblade.common.utils.CommonUtil;
+import org.springblade.core.boot.ctrl.BladeController;
+import org.springblade.core.log.exception.ServiceException;
+import org.springblade.core.secure.utils.SecureUtil;
+import org.springblade.core.tool.api.R;
+import org.springblade.core.tool.utils.ObjectUtil;
+import org.springblade.evisa.feign.EVisaClient;
+import org.springblade.evisa.vo.TaskArchiveDTO;
+import org.springblade.manager.entity.ContractInfo;
+import org.springblade.manager.entity.ContractRelationJlyz;
+import org.springblade.manager.entity.SignPfxFile;
+import org.springblade.manager.feign.SignPfxClient;
+import org.springblade.system.user.entity.User;
+import org.springframework.jdbc.core.BeanPropertyRowMapper;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.web.bind.annotation.*;
+
+import java.io.*;
+import java.util.*;
+import java.util.stream.Collectors;
+
+
+@RestController
+@AllArgsConstructor
+@RequestMapping("/archiveTask")
+@Api(value = "档案涉及任务相关接口", tags = "档案涉及任务相关接口")
+public class ArchiveFileTaskController extends BladeController {
+
+    private final JdbcTemplate jdbcTemplate;
+    private final SignPfxClient signPfxClient;
+    private final EVisaClient eVisaClient;
+
+    /**
+     * 批量认证(水印图片签章默认认证电签)
+     */
+    @PostMapping("/batchCertification")
+    @ApiOperationSupport(order = 1)
+    @ApiOperation(value = "批量认证(水印图片签章默认认证电签)")
+    public R<Boolean> batchCertification(@RequestParam String ids) throws Exception {
+        if (ObjectUtil.isEmpty(SecureUtil.getUser()) || ObjectUtil.isEmpty(SecureUtil.getUserId()) || SecureUtil.getUserId().equals(-1L)) {
+            throw new ServiceException("未获取到当前登陆的用户信息,操作失败");
+        }
+        if (StringUtils.isNotEmpty(ids)) {
+            //获取档案文件
+            List<ArchiveFile> archiveFileList = jdbcTemplate.query("select * from u_archive_file where id in(" + ids + ")", new BeanPropertyRowMapper<>(ArchiveFile.class));
+            if (archiveFileList.size() > 0) {
+                //固定水印图片章
+                String pngQzUrl = "https://bladex-chongqing-info.oss-cn-hangzhou.aliyuncs.com//upload/20230911/5b42583d931664b785ebf481c37d17bc.png";
+                for (ArchiveFile archiveFile : archiveFileList) {
+                    String pdfUrl = StringUtils.isNotEmpty(archiveFile.getEVisaFile()) ? archiveFile.getEVisaFile() : archiveFile.getPdfFileUrl();
+                    if (StringUtils.isEmpty(pdfUrl)) {
+                        continue;
+                    }
+                    InputStream ossInputStreamPNG = CommonUtil.getOSSInputStream(pngQzUrl);
+                    InputStream ossInputStreamPDF = CommonUtil.getOSSInputStream(pdfUrl);
+                    PdfReader reader = null;
+                    Image img = null;
+                    if (ossInputStreamPDF != null && ossInputStreamPNG != null) {
+                        reader = new PdfReader(ossInputStreamPDF);
+                        img = Image.getInstance(IOUtils.toByteArray(ossInputStreamPNG));
+                    }
+                    if (reader != null) {
+                        //封装签章定位入参dto
+                        org.springblade.evisa.vo.TaskArchiveDTO eVISATaskArchiveDTO = new TaskArchiveDTO();
+                        //每条档案业务数据对应的pdf签章集合
+                        List<TaskArchiveDTO.Sign> signList = new ArrayList<>();
+
+                        for (int i = 1; i <= reader.getNumberOfPages(); i++) {
+                            //计算当前页居中的位置坐标 TODO(有问题,坐标点不对,后续再算)
+                            Rectangle pageSize = reader.getPageSize(i);
+                            float x = (pageSize.getLeft() + pageSize.getRight()) / 2 - (img.getScaledWidth() / 2);
+                            float y = (pageSize.getTop() + pageSize.getBottom()) / 2 - (img.getScaledHeight() / 2);
+
+                            //构造签章对象
+                            TaskArchiveDTO.Sign sign = new TaskArchiveDTO.Sign();
+                            sign.setLx(String.valueOf(x)); //x轴
+                            sign.setLy(String.valueOf(y)); //y轴
+                            sign.setPage(String.valueOf(i)); //页码
+                            sign.setUrl(pngQzUrl); //签章图片url
+                            signList.add(sign);
+                        }
+                        eVISATaskArchiveDTO.setSealStrategy(signList);
+
+                        //TODO ============= 电签认证 =============
+                        eVISATaskArchiveDTO.setTaskId(archiveFile.getId().toString());
+                        eVISATaskArchiveDTO.setType(2); //认证
+                        this.eVisaClient.eVisaCustom(eVISATaskArchiveDTO);
+                    }
+                }
+                return R.data(true);
+            }
+        }
+        return R.data(300, false, "没有找到证书文件或PDF文件");
+    }
+
+
+    /**
+     * 检查任务人是否存在签字证书信息
+     */
+    @PostMapping("/checkTaskUserCertificateInfo")
+    @ApiOperationSupport(order = 2)
+    @ApiOperation(value = "检查任务人是否存在签字证书信息", notes = "传入用户userIds,字符串逗号分割拼接")
+    public R<Object> checkTaskUserCertificateInfo(@RequestParam String userIds) {
+        if (StringUtils.isNotEmpty(userIds)) {
+            Set<String> notCertificateUserInfoSet = new HashSet<>();
+            String[] split = userIds.split(",");
+            for (String userId : split) {
+                //获取用户的证书信息
+                List<SignPfxFile> userPfxList = this.signPfxClient.querySignPfxByUserIdOrContractId(userId, "");
+                if (userPfxList == null || userPfxList.size() <= 0) {
+                    notCertificateUserInfoSet.add(userId);
+                }
+            }
+            if (notCertificateUserInfoSet.size() > 0) {
+                Map<Long, String> nameMap = jdbcTemplate.query("select id,name from blade_user where is_deleted = 0", new BeanPropertyRowMapper<>(User.class)).stream().collect(Collectors.toMap(User::getId, User::getName, (key1, key2) -> key1));
+                List<String> names = new ArrayList<>();
+                for (String userId : notCertificateUserInfoSet) {
+                    String name = nameMap.get(Long.parseLong(userId));
+                    if (name != null) {
+                        names.add(name);
+                    }
+                }
+                throw new ServiceException("未获取到用户【" + StringUtils.join(names, "、") + "】的签字证书信息");
+            }
+        }
+        return R.data(true);
+    }
+
+    /**
+     * 档案-任务管理-任务查看分页查询
+     */
+    @PostMapping("/page")
+    @ApiOperationSupport(order = 3)
+    @ApiOperation(value = "档案-任务管理-任务查看分页查询", notes = "传入ArchiveTaskDTO")
+    public R<IPage<ArchiveTaskPageVO>> page(@RequestBody ArchiveTaskDTO dto) {
+        int current = dto.getCurrent();
+        int size = dto.getSize();
+        //封装入参SQL
+        List<Object> params = new ArrayList<>();
+        StringBuilder sqlString = new StringBuilder("SELECT * FROM u_task WHERE 1=1 AND approval_type = 4"); //approval_type = 4 表示档案任务
+        if (ObjectUtil.isNotEmpty(dto.getTypeValue())) {
+            sqlString.append(" AND type = ?");
+            params.add(dto.getTypeValue());
+        }
+        if (ObjectUtil.isNotEmpty(dto.getStatusValue())) {
+            sqlString.append(" AND status = ?");
+            params.add(dto.getStatusValue());
+        }
+
+        ContractInfo contractInfo = jdbcTemplate.queryForObject("select contract_type from m_contract_info where id = " + dto.getCurrentContractId(), new BeanPropertyRowMapper<>(ContractInfo.class));
+        if (contractInfo != null && contractInfo.getContractType().equals(1)) {
+            //施工合同段正常查询
+            if (ObjectUtil.isNotEmpty(dto.getContractIdValue())) {
+                sqlString.append(" AND contract_id = ?");
+                params.add(dto.getContractIdValue());
+            } else {
+                //如果合同段id=null,那么查询当前项目下所有合同段任务
+                if (ObjectUtil.isNotEmpty(dto.getProjectIdValue())) {
+                    sqlString.append(" AND project_id = ?");
+                    params.add(dto.getProjectIdValue());
+                } else {
+                    throw new ServiceException("未获取到项目信息,请联系管理员");
+                }
+            }
+        } else if (contractInfo != null && (contractInfo.getContractType().equals(2) || contractInfo.getContractType().equals(3))) {
+            //如果是监理合同段,那么默认查询关联的全部施工合同段+本身任务
+            List<ContractRelationJlyz> contractRelationJLYZ = jdbcTemplate.query("select contract_id_sg from m_contract_relation_jlyz where contract_id_jlyz = " + dto.getCurrentContractId(), new BeanPropertyRowMapper<>(ContractRelationJlyz.class));
+            Set<Long> ids = contractRelationJLYZ.stream().map(ContractRelationJlyz::getContractIdSg).collect(Collectors.toSet());
+            ids.add(dto.getCurrentContractId()); //把监理本身也加入查询
+            sqlString.append(" AND contract_id in(").append(StringUtils.join(ids, ",")).append(")");
+        }
+
+        if (ObjectUtil.isNotEmpty(dto.getBatchValue())) {
+            sqlString.append(" AND batch = ?");
+            params.add(dto.getBatchValue());
+        }
+        if (StringUtils.isNotBlank(dto.getStartTimeValue()) && StringUtils.isNotBlank(dto.getEndTimeValue())) {
+            sqlString.append(" AND start_time >= ?")
+                    .append(dto.getStartTimeValue())
+                    .append(" AND end_time <= ?");
+            params.add(dto.getStartTimeValue());
+            params.add(dto.getEndTimeValue());
+        }
+        if (StringUtils.isNotBlank(dto.getQueryValue())) {
+            sqlString.append(" AND task_name LIKE ?");
+            params.add("%" + dto.getQueryValue() + "%");
+        }
+        if (ObjectUtil.isNotEmpty(dto.getSelectedType())) {
+            sqlString.append(" AND (");
+            if (dto.getSelectedType().equals(1)) { //待办页面
+
+                //如果是待办页面,且 任务状态下拉框 选择的是 待审批状态 的任务,那么才查询数据
+                if (ObjectUtil.isNotEmpty(dto.getStatusValue()) && dto.getStatusValue().equals(1)) {
+                    sqlString.append("EXISTS (SELECT 1 FROM u_task_parallel WHERE u_task.process_instance_id = u_task_parallel.process_instance_id AND u_task_parallel.status = ? AND u_task_parallel.task_user = ?)");
+                    params.add(1);
+                    params.add(SecureUtil.getUserId());
+
+                    //如果是待办页面,且 任务状态下拉框 选择的不是 待审批状态 的任务,那么直接返回null
+                } else if (ObjectUtil.isNotEmpty(dto.getStatusValue()) && !dto.getStatusValue().equals(1)) {
+                    return null;
+
+                    //如果是待办页面,没选择 任务状态下拉框,那么就默认查询 待审批状态 任务
+                } else if (ObjectUtil.isEmpty(dto.getStatusValue())) {
+                    sqlString.append("EXISTS (SELECT 1 FROM u_task_parallel WHERE u_task.process_instance_id = u_task_parallel.process_instance_id AND u_task_parallel.status = ? AND u_task_parallel.task_user = ?)");
+                    params.add(1);
+                    params.add(SecureUtil.getUserId());
+                    sqlString.append(" AND status = 1");
+                }
+
+            } else if (dto.getSelectedType().equals(2)) { //已办页面
+                sqlString.append("EXISTS (SELECT 1 FROM u_task_parallel WHERE u_task.process_instance_id = u_task_parallel.process_instance_id AND u_task_parallel.status = ? AND u_task_parallel.task_user = ?)");
+                //当前自己的任务必须是已审批,才视为已办
+                params.add(2);
+                params.add(SecureUtil.getUserId());
+
+            } else if (dto.getSelectedType().equals(3)) { //我发起页面
+                sqlString.append("report_user = ?");
+                params.add(SecureUtil.getUserId());
+            }
+            sqlString.append(")");
+        }
+
+        //总数量
+        String sqlCount = sqlString.toString().replace("*", "count(1)");
+        Optional<Integer> totalCountOptional = Optional.ofNullable(jdbcTemplate.queryForObject(sqlCount, Integer.class, params.toArray()));
+        int totalCount = totalCountOptional.orElse(0);
+
+        //分页
+        sqlString.append(" ORDER BY create_time DESC LIMIT ? OFFSET ?");
+        params.add(size);
+        params.add((current - 1) * size);
+
+        //执行SQL获取数据
+        String sqlPage = sqlString.toString();
+        List<Task> resultList = jdbcTemplate.query(
+                sqlPage,
+                new BeanPropertyRowMapper<>(Task.class),
+                params.toArray()
+        );
+
+        //获取任务详情信息Map
+        Set<String> processInstanceIds = resultList.stream().map(Task::getProcessInstanceId).collect(Collectors.toSet());
+        Map<String, List<TaskParallel>> taskParallelGroupMap = new HashMap<>();
+        if (processInstanceIds.size() > 0) {
+            StringJoiner joiner = new StringJoiner(",", "'", "'");
+            processInstanceIds.forEach(joiner::add);
+            String joinedIds = joiner.toString();
+            taskParallelGroupMap = jdbcTemplate.query("select process_instance_id,task_user_name,e_visa_status,e_visa_content from u_task_parallel where process_instance_id in(" + joinedIds + ") order by id", new BeanPropertyRowMapper<>(TaskParallel.class)).stream().collect(Collectors.groupingBy(TaskParallel::getProcessInstanceId));
+        }
+        Map<String, List<TaskParallel>> finalTaskParallelGroupMap = taskParallelGroupMap;
+
+        //获取用户信息Map
+        Map<Long, String> nameMap = jdbcTemplate.query("select id,name from blade_user where is_deleted = 0", new BeanPropertyRowMapper<>(User.class)).stream().collect(Collectors.toMap(User::getId, User::getName, (key1, key2) -> key1));
+
+        //解析page分页数据
+        IPage<ArchiveTaskPageVO> page = new Page<>(current, size);
+        List<ArchiveTaskPageVO> pageList = resultList.stream()
+                .map(task -> {
+                    ArchiveTaskPageVO vo = new ArchiveTaskPageVO();
+                    vo.setId(task.getId());
+                    vo.setTaskName(task.getTaskName());
+                    vo.setTaskTypeName(task.getType().equals(1) ? "普通任务" : task.getType().equals(2) ? "验收任务" : "移交任务");
+                    vo.setTaskStatusName(task.getStatus().equals(1) ? "待审批" : task.getStatus().equals(2) ? "已审批" : "已废除");
+                    vo.setStartTime(task.getStartTime());
+                    vo.setEndTime(task.getEndTime());
+                    vo.setTaskDesc(task.getTaskContent());
+                    vo.setTaskReportUserName(nameMap.get(Long.parseLong(task.getReportUser())));
+                    List<TaskParallel> taskParallelList = finalTaskParallelGroupMap.get(task.getProcessInstanceId());
+                    if (taskParallelList != null && taskParallelList.size() > 0) {
+                        List<String> names = taskParallelList.stream().map(TaskParallel::getTaskUserName).collect(Collectors.toList());
+                        if (names.size() > 0) {
+                            vo.setTaskApproveUserNames(StringUtils.join(names, ","));
+                        }
+                        Set<Integer> eVisaStatus = taskParallelList.stream().map(TaskParallel::getEVisaStatus).collect(Collectors.toSet());
+                        if (eVisaStatus.size() > 0) {
+                            vo.setEVisaStatus(StringUtils.join(eVisaStatus, "、"));
+                        }
+                        Set<String> eVisaContents = taskParallelList.stream().map(TaskParallel::getEVisaContent).collect(Collectors.toSet());
+                        if (eVisaContents.size() > 0) {
+                            vo.setEVisaContents(StringUtils.join(eVisaContents, "、"));
+                        }
+                    }
+                    return vo;
+                })
+                .collect(Collectors.toList());
+        page.setRecords(pageList);
+        page.setTotal(totalCount);
+        return R.data(page);
+    }
+
+}

+ 2 - 1
blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchiveProjectConfigServiceImpl.java

@@ -6,6 +6,7 @@ import org.springblade.archive.mapper.ArchiveProjectConfigMapper;
 import org.springblade.archive.service.IArchiveProjectConfigService;
 import org.springblade.core.mp.base.BaseServiceImpl;
 import org.springblade.core.secure.utils.AuthUtil;
+import org.springblade.core.secure.utils.SecureUtil;
 import org.springframework.stereotype.Service;
 
 @Service
@@ -19,7 +20,7 @@ public class ArchiveProjectConfigServiceImpl extends BaseServiceImpl<ArchiveProj
      */
     @Override
     public ArchiveProjectConfig getByProjectIdOrNew(Long projectId) {
-        ArchiveProjectConfig config = baseMapper.selectOne(new LambdaQueryWrapper<ArchiveProjectConfig>().eq(ArchiveProjectConfig::getProjectId, projectId));
+        ArchiveProjectConfig config = baseMapper.selectOne(new LambdaQueryWrapper<ArchiveProjectConfig>().eq(ArchiveProjectConfig::getTenantId, SecureUtil.getTenantId()).eq(ArchiveProjectConfig::getProjectId, projectId));
         if (config == null) {
             // 创建新对象
             config = new ArchiveProjectConfig();

+ 1 - 1
blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchivesAutoServiceImpl.java

@@ -154,7 +154,7 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 		//根据用户在当前合同段的权限,判断返回
 		BladeUser user = AuthUtil.getUser();
 		String name = baseMapper.getUserRoleName(vo.getProjectId(),vo.getContractId(),user.getUserId());
-		if (name.contains("超级管理员") || contractType == 3) {
+		if ((StringUtils.isNotBlank(name) && name.contains("超级管理员")) || contractType == 3) {
 			vo.setContractId(null);
 		}
 		if (StringUtils.isNotBlank(vo.getNodeIds())) {

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

@@ -310,9 +310,9 @@ public class ContractLogController extends BladeController {
                     userId = json.getLong("userId");
                 }
                 //如果ids为空,说明是填报页上报,那么需要根据 nodePrimaryKeyId 和 recordTime 获取当前用户的填写记录
-                ContractLog log = this.contractLogService.getOne(Wrappers.<ContractLog>lambdaQuery().eq(ContractLog::getWbsNodeId, nodePrimaryKeyId)
+                ContractLog log = this.contractLogService.getBaseMapper().selectList(Wrappers.<ContractLog>lambdaQuery().eq(ContractLog::getWbsNodeId, nodePrimaryKeyId)
                         .eq(ContractLog::getRecordTime, recordTime).eq(ContractLog::getContractId, startTaskVO.getContractId())
-                        .eq(ContractLog::getCreateUser, userId));
+                        .eq(ContractLog::getCreateUser, userId)).stream().findAny().orElse(null);
                 if (log == null) {
                     return R.fail("未找到业务数据");
                 }

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

@@ -565,6 +565,8 @@ public class EVisaTaskCheckController {
             //资料填报
             //jsonList = this.eVisaConfigClient.queryEVisaConfigAllByTableIds(json.getJSONArray("privatePKeyId").toJavaList(String.class));
             List<String> ids = json.getJSONArray("privatePKeyId").toJavaList(String.class);
+            //指向项目级的ID有可能为null
+            ids = ids.stream().filter(Objects::nonNull).collect(Collectors.toList());
             String sql = "select * from m_textdict_info where tab_id in(" + StringUtils.join(ids, ",") + ")";
             List<TextdictInfo> query = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(TextdictInfo.class));
             jsonList = JSONArray.parseArray(JSONObject.toJSONString(query), JSONObject.class);

+ 547 - 29
blade-service/blade-business/src/main/java/org/springblade/business/controller/TaskController.java

@@ -5,24 +5,33 @@ import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiImplicitParam;
 import io.swagger.annotations.ApiImplicitParams;
 import io.swagger.annotations.ApiOperation;
-import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
 import lombok.AllArgsConstructor;
 import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang.time.DateUtils;
 import org.jetbrains.annotations.NotNull;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springblade.archive.dto.ArchiveTaskDTO;
+import org.springblade.archive.vo.ArchiveTaskPageVO;
+import org.springblade.business.dto.*;
 import org.springblade.business.entity.*;
 import org.springblade.business.service.*;
 import org.springblade.business.socket.WebSocket;
-import org.springblade.business.vo.BatchTaskVO;
-import org.springblade.business.vo.TaskApprovalVO;
-import org.springblade.business.vo.TaskQueryVO;
-import org.springblade.common.utils.CommonUtil;
+import org.springblade.business.vo.*;
+import org.springblade.common.utils.SnowFlakeUtil;
+import org.springblade.core.boot.ctrl.BladeController;
+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.BladeUser;
 import org.springblade.core.secure.utils.AuthUtil;
 import org.springblade.core.secure.utils.SecureUtil;
 import org.springblade.core.sms.model.SmsResponse;
@@ -31,6 +40,7 @@ import org.springblade.core.tool.jackson.JsonUtil;
 import org.springblade.core.tool.utils.DateUtil;
 import org.springblade.core.tool.utils.Func;
 import org.springblade.core.tool.utils.ObjectUtil;
+import org.springblade.evisa.feign.EVisaClient;
 import org.springblade.flow.core.entity.BladeFlow;
 import org.springblade.flow.core.feign.NewFlowClient;
 import org.springblade.flow.core.vo.SendPageVO;
@@ -41,22 +51,17 @@ import org.springblade.resource.feign.CommonFileClient;
 import org.springblade.resource.feign.NewISmsClient;
 import org.springblade.system.entity.DictBiz;
 import org.springblade.system.feign.IDictBizClient;
+import org.springblade.system.user.entity.User;
 import org.springframework.beans.BeanUtils;
 import org.springframework.jdbc.core.BeanPropertyRowMapper;
 import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.web.bind.annotation.*;
-import com.baomidou.mybatisplus.core.metadata.IPage;
-import org.springblade.business.vo.TaskVO;
-import org.springblade.core.boot.ctrl.BladeController;
 
-import javax.annotation.Resource;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.time.Duration;
 import java.util.*;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ThreadPoolExecutor;
 import java.util.function.Function;
 import java.util.stream.Collectors;
 
@@ -72,31 +77,21 @@ import java.util.stream.Collectors;
 @Api(value = "任务审核主表", tags = "任务审核主表接口")
 public class TaskController extends BladeController {
 
+    private static final Logger log = LoggerFactory.getLogger(TaskController.class);
     private final JdbcTemplate jdbcTemplate;
-
     private final ITaskService taskService;
-
     private final ITaskParallelService taskParallelService;
-
     private final NewFlowClient newFlowClient;
-
     private final IDictBizClient dictBizClient;
-
     private final NewISmsClient newSmsClient;
-
     private final IDefaultConfigService defaultConfigService;
-
     private final ITaskBatchService taskBatchService;
-
     private final ITaskService iTaskService;
-
     private final WebSocket webSocket;
-
     private final CommonFileClient commonFileClient;
-
     private final ContractClient contractClient;
-
     private final IInformationQueryService informationQueryService;
+    private final EVisaClient eVisaClient;
 
     /**
      * 记录短信验证码超时时间
@@ -301,7 +296,7 @@ public class TaskController extends BladeController {
     }
 
     /**
-     * 批量审批
+     * 批量审批(质检、试验 平行审批)
      */
     @PostMapping("/batch-complete-approval-task")
     @ApiOperationSupport(order = 8)
@@ -364,6 +359,359 @@ public class TaskController extends BladeController {
         return R.data(false);
     }
 
+    /**
+     * 批量上报-档案
+     */
+    @PostMapping("/batch-report-task-archive")
+    @ApiOperationSupport(order = 8)
+    @ApiOperation(value = "批量上报-档案")
+    public R<Object> batchReportTaskArchive(@RequestBody ArchiveTaskBatchReportDTO archiveTaskBatchReportDTO) throws IOException {
+        if (ObjectUtil.isEmpty(archiveTaskBatchReportDTO.getUserIds())
+                || ObjectUtil.isEmpty(archiveTaskBatchReportDTO.getDataIds())
+                || ObjectUtil.isEmpty(archiveTaskBatchReportDTO.getBatch())
+                || ObjectUtil.isEmpty(archiveTaskBatchReportDTO.getProjectId())
+                || ObjectUtil.isEmpty(archiveTaskBatchReportDTO.getContractId())
+                || ObjectUtil.isEmpty(archiveTaskBatchReportDTO.getRestrictDay())) {
+            throw new ServiceException("请求入参数据为空,操作失败");
+        }
+
+        Map<Long, String> nameMap = jdbcTemplate.query("select id,name from blade_user where is_deleted = 0", new BeanPropertyRowMapper<>(User.class)).stream().collect(Collectors.toMap(User::getId, User::getName, (key1, key2) -> key1));
+        Map<Long, String> fileNameMaps = jdbcTemplate.query("select id,file_name from u_archive_file where file_name is not null and id in (" + archiveTaskBatchReportDTO.getDataIds() + ")", new BeanPropertyRowMapper<>(ArchiveFile.class)).stream().collect(Collectors.toMap(ArchiveFile::getId, ArchiveFile::getFileName, (obj1, obj2) -> obj1));
+        String[] archiveIds = archiveTaskBatchReportDTO.getDataIds().split(",");
+        if (archiveIds.length > 0) {
+            for (String archiveId : archiveIds) {
+                //创建task审批任务
+                Long processInstanceId = SnowFlakeUtil.getId();
+                Task task = new Task();
+                task.setId(SnowFlakeUtil.getId());
+                Date nowTime = new Date();
+                task.setStartTime(DateUtil.format(nowTime, "yyyy-MM-dd"));
+                task.setEndTime(DateUtil.format(DateUtils.addDays(nowTime, archiveTaskBatchReportDTO.getRestrictDay()), "yyyy-MM-dd"));
+
+                task.setProcessDefinitionId(SnowFlakeUtil.getId().toString());
+                task.setProcessInstanceId(processInstanceId.toString()); //实例id
+
+                task.setReportUser(AuthUtil.getUserId().toString());
+                task.setReportUserName(AuthUtil.getNickName());
+
+                task.setCreateUser(AuthUtil.getUserId());
+                task.setCreateTime(nowTime);
+                task.setUpdateTime(nowTime);
+                task.setUpdateUser(AuthUtil.getUserId());
+                task.setCreateDept(null);
+
+                task.setTaskContent(ObjectUtil.isNotEmpty(archiveTaskBatchReportDTO.getTaskContent()) ? archiveTaskBatchReportDTO.getTaskContent() : null);
+                task.setTaskUser(null);
+                task.setFormDataId(archiveId); //数据指向
+                task.setTaskName(ObjectUtil.isNotEmpty(fileNameMaps.get(Long.parseLong(archiveId))) ? fileNameMaps.get(Long.parseLong(archiveId)) : "未获取到档案文件任务名");
+                task.setContractId(archiveTaskBatchReportDTO.getContractId());
+                task.setProjectId(archiveTaskBatchReportDTO.getProjectId());
+                task.setBatch(archiveTaskBatchReportDTO.getBatch());
+                task.setType(1);
+                task.setApprovalType(4); //档案审批
+                task.setFixedFlowId(0L);
+                task.setStatus(1); //待审批
+                task.setIsDeleted(0);
+                task.setTrialSelfInspectionRecordId(null);
+
+                taskService.save(task);
+
+                //创建任务相关信息
+                String[] userIds = archiveTaskBatchReportDTO.getUserIds().split(",");
+                for (String userId : userIds) {
+                    TaskParallel taskParallel = new TaskParallel();
+                    taskParallel.setId(SnowFlakeUtil.getId());
+                    taskParallel.setProcessInstanceId(processInstanceId.toString());
+                    taskParallel.setParallelProcessInstanceId(SnowFlakeUtil.getId().toString());
+                    taskParallel.setTaskUser(userId);
+                    if (nameMap.get(Long.parseLong(userId)) != null) {
+                        taskParallel.setTaskUserName(nameMap.get(Long.parseLong(userId)));
+                    }
+                    taskParallel.setInitiative(1);
+                    taskParallel.setCreateUser(AuthUtil.getUserId());
+                    taskParallel.setCreateTime(nowTime);
+                    taskParallel.setUpdateTime(nowTime);
+                    taskParallel.setUpdateUser(AuthUtil.getUserId());
+                    taskParallel.setCreateDept(null);
+                    taskParallel.setStatus(1);
+                    taskParallel.setIsDeleted(0);
+                    taskParallelService.save(taskParallel);
+                }
+
+                //修改档案业务数据任务状态为待审批
+                jdbcTemplate.execute("update u_archive_file set status = 1 where id = " + archiveId);
+            }
+
+            //WebSocket推送
+            if (ObjectUtil.isNotEmpty(AuthUtil.getUserId())) {
+                Map<String, String> webSocketMessageMap = WebSocket.getWebSocketMessageMap();
+                Set<Map.Entry<String, String>> message = webSocketMessageMap.entrySet();
+                for (Map.Entry<String, String> entry : message) {
+                    String userId = entry.getKey();
+                    if (userId.equals(AuthUtil.getUserId().toString())) { //只推送当前用户
+                        String projectAndContractId = entry.getValue();
+                        if (StringUtils.isNotEmpty(projectAndContractId) && StringUtils.isNotEmpty(userId)) {
+                            String projectId = projectAndContractId.split(",")[0];
+                            String contractId = projectAndContractId.split(",")[1];
+                            Map<String, String> stringMap = iTaskService.getTaskCountArchive(projectId, contractId, userId);
+                            webSocket.sendMessageByUserId(AuthUtil.getUserId().toString(), JSON.toJSONString(stringMap));
+                        }
+                    }
+                }
+            }
+            return R.success("上报成功");
+        }
+        return R.fail("操作失败");
+    }
+
+    /**
+     * 批量撤销(废除)-档案
+     */
+    @PostMapping("/batch-repeal-task-archive")
+    @ApiOperationSupport(order = 8)
+    @ApiOperation(value = "批量撤销(废除)-档案")
+    public R<Object> batchRepealTaskArchive(@RequestBody ArchiveTaskBatchRepealDTO repealDTO) throws IOException {
+        if (repealDTO.getType().equals(1)) { //文件收集废除
+            String[] archiveIds = repealDTO.getIds().split(",");
+            for (String archiveId : archiveIds) {
+                //判断现在的数据是否是待审批数据,只有待审批数据才能撤销
+                ArchiveFile archiveFile = jdbcTemplate.queryForObject("select * from u_archive_file where id = " + archiveId, new BeanPropertyRowMapper<>(ArchiveFile.class));
+                if (archiveFile != null && archiveFile.getStatus().equals(1)) {
+                    //修改档案文件收集业务数据状态=已废除
+                    jdbcTemplate.execute("update u_archive_file set status = 3 where id = " + archiveId);
+                    Task task = jdbcTemplate.queryForObject("select id,status,process_instance_id from u_task where form_data_id = " + archiveId, new BeanPropertyRowMapper<>(Task.class));
+                    if (task != null && task.getStatus().equals(1)) {
+                        //待审批审批任务=已废除
+                        jdbcTemplate.execute("update u_task set status = 3 where id = " + task.getId());
+                        //审批任务详情=已废除
+                        jdbcTemplate.execute("update u_task_parallel set status = 3 where process_instance_id = " + task.getProcessInstanceId());
+                    }
+                }
+            }
+            //WebSocket推送
+            if (ObjectUtil.isNotEmpty(AuthUtil.getUserId())) {
+                Map<String, String> webSocketMessageMap = WebSocket.getWebSocketMessageMap();
+                Set<Map.Entry<String, String>> message = webSocketMessageMap.entrySet();
+                for (Map.Entry<String, String> entry : message) {
+                    String userId = entry.getKey();
+                    if (userId.equals(AuthUtil.getUserId().toString())) { //只推送当前用户
+                        String projectAndContractId = entry.getValue();
+                        if (StringUtils.isNotEmpty(projectAndContractId) && StringUtils.isNotEmpty(userId)) {
+                            String projectId = projectAndContractId.split(",")[0];
+                            String contractId = projectAndContractId.split(",")[1];
+                            Map<String, String> stringMap = iTaskService.getTaskCountArchive(projectId, contractId, userId);
+                            webSocket.sendMessageByUserId(AuthUtil.getUserId().toString(), JSON.toJSONString(stringMap));
+                        }
+                    }
+                }
+            }
+            return R.success("操作成功");
+        } else if (repealDTO.getType().equals(2)) { //任务审批废除
+            String[] taskIds = repealDTO.getIds().split(",");
+            for (String taskId : taskIds) {
+                Task task = jdbcTemplate.queryForObject("select id,status,process_instance_id,form_data_id from u_task where id = " + taskId, new BeanPropertyRowMapper<>(Task.class));
+                if (task != null && task.getStatus().equals(1)) {
+                    //待审批审批任务=已废除
+                    jdbcTemplate.execute("update u_task set status = 3 where id = " + task.getId());
+                    //审批任务详情=已废除
+                    jdbcTemplate.execute("update u_task_parallel set status = 3 where process_instance_id = " + task.getProcessInstanceId());
+                    //修改档案文件收集业务数据状态
+                    jdbcTemplate.execute("update u_archive_file set status = 3 where id = " + task.getFormDataId());
+                }
+            }
+            //WebSocket推送
+            if (ObjectUtil.isNotEmpty(AuthUtil.getUserId())) {
+                Map<String, String> webSocketMessageMap = WebSocket.getWebSocketMessageMap();
+                Set<Map.Entry<String, String>> message = webSocketMessageMap.entrySet();
+                for (Map.Entry<String, String> entry : message) {
+                    String userId = entry.getKey();
+                    if (userId.equals(AuthUtil.getUserId().toString())) { //只推送当前用户
+                        String projectAndContractId = entry.getValue();
+                        if (StringUtils.isNotEmpty(projectAndContractId) && StringUtils.isNotEmpty(userId)) {
+                            String projectId = projectAndContractId.split(",")[0];
+                            String contractId = projectAndContractId.split(",")[1];
+                            Map<String, String> stringMap = iTaskService.getTaskCountArchive(projectId, contractId, userId);
+                            webSocket.sendMessageByUserId(AuthUtil.getUserId().toString(), JSON.toJSONString(stringMap));
+                        }
+                    }
+                }
+            }
+            return R.success("操作成功");
+        }
+        return R.fail(400, "操作失败");
+    }
+
+    /**
+     * 批量审批(档案 垂直审批)
+     */
+    @PostMapping("/batch-complete-approval-task-archive")
+    @ApiOperationSupport(order = 8)
+    @ApiOperation(value = "批量审批(档案 垂直审批)")
+    public R<Boolean> batchCompleteApprovalTaskArchive(@RequestBody TaskArchiveOuterLayerDTO taskArchiveOuterLayerDTO) throws IOException {
+        if (ObjectUtil.isEmpty(SecureUtil.getUser()) || ObjectUtil.isEmpty(SecureUtil.getUserId()) || SecureUtil.getUserId().equals(-1L)) {
+            throw new ServiceException("未获取到当前登陆的用户信息,操作失败");
+        }
+
+        String flag = taskArchiveOuterLayerDTO.getTaskArchiveDtoList().stream().map(TaskArchiveDTO::getFlag).findAny().orElse(null);
+        if (StringUtils.isEmpty(flag)) {
+            throw new ServiceException("请选择审批操作类型,【同意】或【废除任务】");
+        }
+
+        //同意审批
+        if (flag.equals("OK")) {
+            //检查审批人是否符合顺序
+            this.checkArchiveTaskUserByCurrent(taskArchiveOuterLayerDTO.getTaskArchiveDtoList());
+
+            //构造业务数据,修改业务数据
+            for (TaskArchiveDTO taskArchiveDTO : taskArchiveOuterLayerDTO.getTaskArchiveDtoList()) {
+                if (StringUtils.isNotEmpty(taskArchiveDTO.getTaskId())) {
+                    //通过checkArchiveTaskUserByCurrent检查,说明当前登陆用户是该条任务的审批人,修改审批任务状态
+                    Task task = jdbcTemplate.queryForObject("select process_instance_id,form_data_id from u_task where id = " + taskArchiveDTO.getTaskId(), new BeanPropertyRowMapper<>(Task.class));
+                    if (task != null) {
+                        //获取审批任务关联用户的详情
+                        List<TaskParallel> taskParallels = jdbcTemplate.query("select id,process_instance_id,task_user,task_user_name from u_task_parallel where process_instance_id = '" + task.getProcessInstanceId() + "'", new BeanPropertyRowMapper<>(TaskParallel.class));
+                        if (taskParallels.size() > 0) {
+                            //当前用户任务
+                            TaskParallel taskParallelCurrentUser = taskParallels.stream().filter(f -> f.getTaskUser().equals(SecureUtil.getUserId().toString())).findAny().orElse(null);
+                            if (taskParallelCurrentUser != null) {
+                                //修改当前用户任务为已审批
+                                jdbcTemplate.execute("update u_task_parallel set status = 2 where id = " + taskParallelCurrentUser.getId());
+                            }
+                        }
+
+                        //TODO ============ 档案电签推送(每个人都要电签,按照顺序) ============
+                        org.springblade.evisa.vo.TaskArchiveDTO eVisaObj = new org.springblade.evisa.vo.TaskArchiveDTO();
+                        BeanUtils.copyProperties(taskArchiveDTO, eVisaObj);
+                        eVisaObj.setType(1); //审批
+                        this.eVisaClient.eVisaCustom(eVisaObj);
+
+                        //获取最新任务状态,判断是否存在未完成的审批任务(最后一个人审批完成);如果没有就闭环,修改审批任务状态、业务数据状态
+                        List<TaskParallel> taskParallelsNow = jdbcTemplate.query("select status from u_task_parallel where process_instance_id = '" + task.getProcessInstanceId() + "'", new BeanPropertyRowMapper<>(TaskParallel.class));
+                        List<TaskParallel> pendingApprovalTask = taskParallelsNow.stream().filter(f -> f.getStatus() != 2).collect(Collectors.toList());
+                        if (pendingApprovalTask.size() == 0) {
+                            //修改审批任务状态
+                            jdbcTemplate.execute("update u_task set status = 2 where id = " + taskArchiveDTO.getTaskId());
+                            //修改业务数据状态
+                            jdbcTemplate.execute("update u_archive_file set status = 2 where id = " + task.getFormDataId());
+                        }
+                    }
+                }
+            }
+
+            //WebSocket推送
+            if (ObjectUtil.isNotEmpty(AuthUtil.getUserId())) {
+                Map<String, String> webSocketMessageMap = WebSocket.getWebSocketMessageMap();
+                Set<Map.Entry<String, String>> message = webSocketMessageMap.entrySet();
+                for (Map.Entry<String, String> entry : message) {
+                    String userId = entry.getKey();
+                    if (userId.equals(AuthUtil.getUserId().toString())) { //只推送当前用户
+                        String projectAndContractId = entry.getValue();
+                        if (StringUtils.isNotEmpty(projectAndContractId) && StringUtils.isNotEmpty(userId)) {
+                            String projectId = projectAndContractId.split(",")[0];
+                            String contractId = projectAndContractId.split(",")[1];
+                            Map<String, String> stringMap = iTaskService.getTaskCountArchive(projectId, contractId, userId);
+                            webSocket.sendMessageByUserId(AuthUtil.getUserId().toString(), JSON.toJSONString(stringMap));
+                        }
+                    }
+                }
+            }
+            return R.data(true);
+
+        } else {
+            //废除任务
+            List<String> taskIds = taskArchiveOuterLayerDTO.getTaskArchiveDtoList().stream().map(TaskArchiveDTO::getTaskId).filter(ObjectUtil::isNotEmpty).collect(Collectors.toList());
+            ArchiveTaskBatchRepealDTO dto = new ArchiveTaskBatchRepealDTO();
+            dto.setType(2);
+            dto.setIds(StringUtils.join(taskIds, ","));
+            R<Object> objectR = this.batchRepealTaskArchive(dto);
+            if (objectR.getCode() == 200) {
+                //WebSocket推送
+                if (ObjectUtil.isNotEmpty(AuthUtil.getUserId())) {
+                    Map<String, String> webSocketMessageMap = WebSocket.getWebSocketMessageMap();
+                    Set<Map.Entry<String, String>> message = webSocketMessageMap.entrySet();
+                    for (Map.Entry<String, String> entry : message) {
+                        String userId = entry.getKey();
+                        if (userId.equals(AuthUtil.getUserId().toString())) { //只推送当前用户
+                            String projectAndContractId = entry.getValue();
+                            if (StringUtils.isNotEmpty(projectAndContractId) && StringUtils.isNotEmpty(userId)) {
+                                String projectId = projectAndContractId.split(",")[0];
+                                String contractId = projectAndContractId.split(",")[1];
+                                Map<String, String> stringMap = iTaskService.getTaskCountArchive(projectId, contractId, userId);
+                                webSocket.sendMessageByUserId(AuthUtil.getUserId().toString(), JSON.toJSONString(stringMap));
+                            }
+                        }
+                    }
+                }
+                return R.data(true);
+            } else if (objectR.getCode() == 400) {
+                return R.data(false);
+            }
+        }
+        return R.data(false);
+    }
+
+    /**
+     * 批量审批-获取档案审批任务对应业务数据的pdf信息
+     */
+    @PostMapping("/getArchiveFileTaskPdfs")
+    @ApiOperationSupport(order = 8)
+    @ApiOperation(value = "批量审批-获取档案审批任务对应业务数据的pdf信息", notes = "传入任务id,封装成taskIds,字符串逗号分割拼接")
+    public R<List<ArchiveFileTaskPDFVO>> getArchiveFileTaskPdfs(@RequestParam String taskIds) {
+        if (StringUtils.isNotEmpty(taskIds)) {
+            List<Task> taskList = jdbcTemplate.query("select form_data_id from u_task where approval_type = 4 and id in(" + taskIds + ")", new BeanPropertyRowMapper<>(Task.class));
+            Set<String> formDataIds = taskList.stream().map(Task::getFormDataId).collect(Collectors.toSet());
+            if (formDataIds.size() > 0) {
+                List<ArchiveFile> archiveFiles = jdbcTemplate.query("select id,file_name,pdf_file_url,e_visa_file from u_archive_file where id in(" + StringUtils.join(formDataIds, ",") + ")", new BeanPropertyRowMapper<>(ArchiveFile.class));
+                List<ArchiveFileTaskPDFVO> collect = archiveFiles.stream()
+                        .map(obj -> {
+                            ArchiveFileTaskPDFVO vo = new ArchiveFileTaskPDFVO();
+                            vo.setId(obj.getId());
+                            vo.setPdfUrl(ObjectUtil.isNotEmpty(obj.getEVisaFile()) ? obj.getEVisaFile() : obj.getPdfFileUrl());
+                            vo.setFileName(obj.getFileName());
+                            return vo;
+                        }).collect(Collectors.toList());
+                return R.data(collect);
+            }
+        }
+        return R.data(null);
+    }
+
+    /**
+     * 检查档案审批是否按照顺序审批
+     *
+     * @param taskArchiveDTOList
+     */
+    private void checkArchiveTaskUserByCurrent(List<TaskArchiveDTO> taskArchiveDTOList) {
+        for (TaskArchiveDTO taskArchiveDTO : taskArchiveDTOList) {
+            if (ObjectUtil.isNotEmpty(taskArchiveDTO.getTaskId())) {
+                Task task = jdbcTemplate.queryForObject("select process_instance_id,task_name from u_task where id = '" + taskArchiveDTO.getTaskId() + "'", new BeanPropertyRowMapper<>(Task.class));
+                if (ObjectUtil.isNotEmpty(task)) {
+                    List<TaskParallel> taskParallelList = jdbcTemplate.query("select id,process_instance_id,task_user,task_user_name,status from u_task_parallel where process_instance_id ='" + task.getProcessInstanceId() + "'", new BeanPropertyRowMapper<>(TaskParallel.class));
+                    taskParallelList.sort(Comparator.comparing(TaskParallel::getId)); //根据id排序
+                    Map<String, List<TaskParallel>> taskParallelGroup = taskParallelList.stream().collect(Collectors.groupingBy(TaskParallel::getProcessInstanceId));
+                    for (Map.Entry<String, List<TaskParallel>> taskObj : taskParallelGroup.entrySet()) {
+                        //获取当前审批人前面的审批人信息
+                        List<TaskParallel> frontTaskUser = new LinkedList<>();
+                        for (TaskParallel taskParallel : taskObj.getValue()) {
+                            Long userId = SecureUtil.getUserId();
+                            if (!userId.toString().equals(taskParallel.getTaskUser())) {
+                                frontTaskUser.add(taskParallel);
+                            } else {
+                                //如果是当前的审批人,那么直接跳过
+                                break;
+                            }
+                        }
+                        List<TaskParallel> resultTaskStatus = frontTaskUser.stream().filter(f -> !f.getStatus().equals(2)).collect(Collectors.toList());
+                        if (resultTaskStatus.size() > 0) {
+                            String names = resultTaskStatus.stream().map(TaskParallel::getTaskUserName).collect(Collectors.joining("、"));
+                            throw new ServiceException("当前任务【" + task.getTaskName() + "】还有【" + names + "】未完成审批,请您稍后再试");
+                        }
+                    }
+                }
+            }
+        }
+    }
+
     /**
      * 获取当前合同段的上报批次
      *
@@ -411,8 +759,8 @@ public class TaskController extends BladeController {
     @GetMapping("/query-task-type-status")
     @ApiOperationSupport(order = 6)
     @ApiOperation(value = "获取任务类型或任务状态")
-    public R<List<DictBiz>> queryTaskTypeOrStatus(String typeOrStatus) {
-        return R.data(jdbcTemplate.query("select dict_key, dict_value from blade_dict_biz where code = '" + typeOrStatus + "' and parent_id > 0 and is_sealed = 0 and is_deleted = 0 order by sort", new BeanPropertyRowMapper<>(DictBiz.class)));
+    public R<List<DictBiz>> queryTaskTypeOrStatus(String typeOrStatus, BladeUser bladeUser) {
+        return R.data(jdbcTemplate.query("select dict_key, dict_value from blade_dict_biz where code = '" + typeOrStatus + "' and tenant_id=" + bladeUser.getTenantId() + " and parent_id > 0 and is_sealed = 0 and is_deleted = 0 order by sort", new BeanPropertyRowMapper<>(DictBiz.class)));
     }
 
     /**
@@ -482,7 +830,7 @@ public class TaskController extends BladeController {
         this.integrationMethod(queryVO, masterTaskMap, parallelMap, parallelProcessInstanceIds, "1");
 
         //如果为空直接返回
-        if (masterTaskMap.size() == 0 && parallelMap.size() == 0) {
+        if (masterTaskMap.size() == 0 && parallelMap.size() == 0 && ObjectUtil.isNotEmpty(queryVO.getContractId()) && ObjectUtil.isNotEmpty(queryVO.getProjectId())) {
             this.sendsWebSocketCount(null, 2, queryVO);
             return R.data(null);
         }
@@ -494,9 +842,9 @@ public class TaskController extends BladeController {
         R<IPage<TaskVO>> iPageR = this.integrationMethod(queryVO, rObject, masterTaskMap, parallelMap, true);
 
         //推送
-        if (ObjectUtil.isNotEmpty(iPageR.getData()) && ObjectUtil.isNotEmpty(iPageR.getData().getRecords())) {
+        if (ObjectUtil.isNotEmpty(iPageR.getData()) && ObjectUtil.isNotEmpty(iPageR.getData().getRecords()) && ObjectUtil.isNotEmpty(queryVO.getContractId()) && ObjectUtil.isNotEmpty(queryVO.getProjectId())) {
             this.sendsWebSocketCount(iPageR, 1, queryVO);
-        } else {
+        } else if (ObjectUtil.isNotEmpty(queryVO.getContractId()) && ObjectUtil.isNotEmpty(queryVO.getProjectId())) {
             this.sendsWebSocketCount(null, 2, queryVO);
         }
         return iPageR;
@@ -512,6 +860,10 @@ public class TaskController extends BladeController {
      */
     @Async
     public void sendsWebSocketCount(R<IPage<TaskVO>> iPageR, int type, TaskQueryVO queryVO) throws IOException {
+        if (ObjectUtil.isEmpty(queryVO.getCurrentContractId())) {
+            //如果getCurrentContractId=null,那么表示是APP的待办查询(web端不为null)
+            queryVO.setCurrentContractId(queryVO.getContractId());
+        }
         if (type == 1) {
             Map<String, String> stringMap = iTaskService.getTaskCount(queryVO.getProjectId(), queryVO.getCurrentContractId(), SecureUtil.getUserId().toString());
             stringMap.put("taskCount", String.valueOf(iPageR.getData().getTotal()));
@@ -715,4 +1067,170 @@ public class TaskController extends BladeController {
         return this.taskService.startApproval(taskVO) ? R.data(200, true, "操作成功") : R.data(200, false, "操作失败,请联系管理员");
     }
 
+    /**
+     * 资料填报-任务管理-任务查看分页查询
+     */
+    @PostMapping("/page")
+    @ApiOperationSupport(order = 1)
+    @ApiOperation(value = "资料填报-任务管理-任务查看分页查询", notes = "传入BusinessTaskDTO")
+    public R<IPage<BusinessTaskPageVO>> page(@RequestBody BusinessTaskDTO dto) {
+        int current = dto.getCurrent();
+        int size = dto.getSize();
+        //封装入参SQL
+        List<Object> params = new ArrayList<>();
+        StringBuilder sqlString = new StringBuilder("SELECT * FROM u_task WHERE 1=1 AND approval_type != 4"); //approval_type != 4 非档案的任务就是1填报资料,2工程文件,3日志资料
+        if (ObjectUtil.isNotEmpty(dto.getTypeValue())) {
+            sqlString.append(" AND type = ?");
+            params.add(dto.getTypeValue());
+        }
+        if (ObjectUtil.isNotEmpty(dto.getStatusValue())) {
+            sqlString.append(" AND status = ?");
+            params.add(dto.getStatusValue());
+        }
+
+        ContractInfo contractInfo = jdbcTemplate.queryForObject("select contract_type from m_contract_info where id = " + dto.getCurrentContractId(), new BeanPropertyRowMapper<>(ContractInfo.class));
+        if (contractInfo != null && contractInfo.getContractType().equals(1)) {
+            //施工合同段正常查询
+            if (ObjectUtil.isNotEmpty(dto.getContractIdValue())) {
+                sqlString.append(" AND contract_id = ?");
+                params.add(dto.getContractIdValue());
+            } else {
+                //如果合同段id=null,那么查询当前项目下所有合同段任务
+                if (ObjectUtil.isNotEmpty(dto.getProjectIdValue())) {
+                    sqlString.append(" AND project_id = ?");
+                    params.add(dto.getProjectIdValue());
+                } else {
+                    throw new ServiceException("未获取到项目信息,请联系管理员");
+                }
+            }
+        } else if (contractInfo != null && (contractInfo.getContractType().equals(2) || contractInfo.getContractType().equals(3))) {
+            //如果是监理合同段,那么默认查询关联的全部施工合同段+本身任务
+            List<ContractRelationJlyz> contractRelationJLYZ = jdbcTemplate.query("select contract_id_sg from m_contract_relation_jlyz where contract_id_jlyz = " + dto.getCurrentContractId(), new BeanPropertyRowMapper<>(ContractRelationJlyz.class));
+            Set<Long> ids = contractRelationJLYZ.stream().map(ContractRelationJlyz::getContractIdSg).collect(Collectors.toSet());
+            ids.add(dto.getCurrentContractId()); //把监理本身也加入查询
+            sqlString.append(" AND contract_id in(").append(StringUtils.join(ids, ",")).append(")");
+        }
+
+        if (ObjectUtil.isNotEmpty(dto.getBatchValue())) {
+            sqlString.append(" AND batch = ?");
+            params.add(dto.getBatchValue());
+        }
+        if (StringUtils.isNotBlank(dto.getStartTimeValue()) && StringUtils.isNotBlank(dto.getEndTimeValue())) {
+            sqlString.append(" AND start_time >= ?")
+                    .append(dto.getStartTimeValue())
+                    .append(" AND end_time <= ?");
+            params.add(dto.getStartTimeValue());
+            params.add(dto.getEndTimeValue());
+        }
+        if (StringUtils.isNotBlank(dto.getQueryValue())) {
+            sqlString.append(" AND task_name LIKE ?");
+            params.add("%" + dto.getQueryValue() + "%");
+        }
+        if (ObjectUtil.isNotEmpty(dto.getSelectedType())) {
+            sqlString.append(" AND (");
+            if (dto.getSelectedType().equals(1)) { //待办页面
+
+                //如果是待办页面,且 任务状态下拉框 选择的是 待审批状态 的任务,那么才查询数据
+                if (ObjectUtil.isNotEmpty(dto.getStatusValue()) && dto.getStatusValue().equals(1)) {
+                    sqlString.append("EXISTS (SELECT 1 FROM u_task_parallel WHERE u_task.process_instance_id = u_task_parallel.process_instance_id AND u_task_parallel.status = ? AND u_task_parallel.task_user = ?)");
+                    params.add(1);
+                    params.add(SecureUtil.getUserId());
+
+                    //如果是待办页面,且 任务状态下拉框 选择的不是 待审批状态 的任务,那么直接返回null
+                } else if (ObjectUtil.isNotEmpty(dto.getStatusValue()) && !dto.getStatusValue().equals(1)) {
+                    return null;
+
+                    //如果是待办页面,没选择 任务状态下拉框,那么就默认查询 待审批状态 任务
+                } else if (ObjectUtil.isEmpty(dto.getStatusValue())) {
+                    sqlString.append("EXISTS (SELECT 1 FROM u_task_parallel WHERE u_task.process_instance_id = u_task_parallel.process_instance_id AND u_task_parallel.status = ? AND u_task_parallel.task_user = ?)");
+                    params.add(1);
+                    params.add(SecureUtil.getUserId());
+                    sqlString.append(" AND status = 1");
+                }
+
+            } else if (dto.getSelectedType().equals(2)) { //已办页面
+                sqlString.append("EXISTS (SELECT 1 FROM u_task_parallel WHERE u_task.process_instance_id = u_task_parallel.process_instance_id AND u_task_parallel.status = ? AND u_task_parallel.task_user = ?)");
+                //当前自己的任务必须是已审批,才视为已办
+                params.add(2);
+                params.add(SecureUtil.getUserId());
+
+            } else if (dto.getSelectedType().equals(3)) { //我发起页面
+                sqlString.append("report_user = ?");
+                params.add(SecureUtil.getUserId());
+            }
+            sqlString.append(")");
+        }
+
+        //总数量
+        String sqlCount = sqlString.toString().replace("*", "count(1)");
+        Optional<Integer> totalCountOptional = Optional.ofNullable(jdbcTemplate.queryForObject(sqlCount, Integer.class, params.toArray()));
+        int totalCount = totalCountOptional.orElse(0);
+
+        //分页
+        sqlString.append(" ORDER BY create_time DESC LIMIT ? OFFSET ?");
+        params.add(size);
+        params.add((current - 1) * size);
+
+        //执行SQL获取数据
+        String sqlPage = sqlString.toString();
+        List<Task> resultList = jdbcTemplate.query(
+                sqlPage,
+                new BeanPropertyRowMapper<>(Task.class),
+                params.toArray()
+        );
+
+        //获取任务详情信息Map
+        Set<String> processInstanceIds = resultList.stream().map(Task::getProcessInstanceId).collect(Collectors.toSet());
+        Map<String, List<TaskParallel>> taskParallelGroupMap = new HashMap<>();
+        if (processInstanceIds.size() > 0) {
+            StringJoiner joiner = new StringJoiner(",", "'", "'");
+            processInstanceIds.forEach(joiner::add);
+            String joinedIds = joiner.toString();
+            taskParallelGroupMap = jdbcTemplate.query("select process_instance_id,task_user_name,e_visa_status,e_visa_content from u_task_parallel where process_instance_id in(" + joinedIds + ") order by id", new BeanPropertyRowMapper<>(TaskParallel.class)).stream().collect(Collectors.groupingBy(TaskParallel::getProcessInstanceId));
+        }
+        Map<String, List<TaskParallel>> finalTaskParallelGroupMap = taskParallelGroupMap;
+
+        //获取用户信息Map
+        Map<Long, String> nameMap = jdbcTemplate.query("select id,name from blade_user where is_deleted = 0", new BeanPropertyRowMapper<>(User.class)).stream().collect(Collectors.toMap(User::getId, User::getName, (key1, key2) -> key1));
+
+        //解析page分页数据
+        IPage<BusinessTaskPageVO> page = new Page<>(current, size);
+        List<BusinessTaskPageVO> pageList = resultList.stream()
+                .map(task -> {
+                    BusinessTaskPageVO vo = new BusinessTaskPageVO();
+                    vo.setId(task.getId());
+                    vo.setTaskName(task.getTaskName());
+                    vo.setTaskTypeName(task.getType().equals(1) ? "普通任务" : task.getType().equals(2) ? "验收任务" : "移交任务");
+                    vo.setTaskStatusName(task.getStatus().equals(1) ? "待审批" : task.getStatus().equals(2) ? "已审批" : "已废除");
+                    vo.setStartTime(task.getStartTime());
+                    vo.setEndTime(task.getEndTime());
+                    vo.setTaskDesc(task.getTaskContent());
+                    vo.setTaskReportUserName(nameMap.get(Long.parseLong(task.getReportUser())));
+                    vo.setApprovalType(task.getApprovalType());
+                    vo.setFormDataId(task.getFormDataId());
+                    vo.setProcessInstanceId(task.getProcessInstanceId());
+                    List<TaskParallel> taskParallelList = finalTaskParallelGroupMap.get(task.getProcessInstanceId());
+                    if (taskParallelList != null && taskParallelList.size() > 0) {
+                        List<String> names = taskParallelList.stream().map(TaskParallel::getTaskUserName).collect(Collectors.toList());
+                        if (names.size() > 0) {
+                            vo.setTaskApproveUserNames(StringUtils.join(names, ","));
+                        }
+                        Set<Integer> eVisaStatus = taskParallelList.stream().map(TaskParallel::getEVisaStatus).collect(Collectors.toSet());
+                        if (eVisaStatus.size() > 0) {
+                            vo.setEVisaStatus(StringUtils.join(eVisaStatus, "、"));
+                        }
+                        Set<String> eVisaContents = taskParallelList.stream().map(TaskParallel::getEVisaContent).collect(Collectors.toSet());
+                        if (eVisaContents.size() > 0) {
+                            vo.setEVisaContents(StringUtils.join(eVisaContents, "、"));
+                        }
+                    }
+                    return vo;
+                })
+                .collect(Collectors.toList());
+        page.setRecords(pageList);
+        page.setTotal(totalCount);
+        return R.data(page);
+    }
+
+
 }

+ 5 - 0
blade-service/blade-business/src/main/java/org/springblade/business/feignClient/ArchiveFileClientImpl.java

@@ -315,4 +315,9 @@ public class ArchiveFileClientImpl implements ArchiveFileClient {
         return fileMapper.getListByContractId(contractId);
     }
 
+    @Override
+    public void updateById2(ArchiveFile archiveFile) {
+        iArchiveFileService.updateById(archiveFile);
+    }
+
 }

+ 28 - 22
blade-service/blade-business/src/main/java/org/springblade/business/mapper/ArchiveFileMapper.xml

@@ -88,17 +88,20 @@
         <if test="vo.rectification != null and vo.rectification != ''">
             and u.rectification = #{vo.rectification}
         </if>
-        <choose>
-            <when test="vo.isArchive != null and vo.isArchive != ''">
-                and u.is_auto_file = #{vo.isArchive}
-            </when>
-            <when test="vo.archiveId != null and vo.archiveId != ''">
-                and 1=1
-            </when>
-            <otherwise>
-                and (u.is_auto_file is null or u.is_auto_file != 1)
-            </otherwise>
-        </choose>
+        <if test="vo.rectification == null and vo.archiveId == null">
+            and (u.is_auto_file is null or u.is_auto_file != 1)
+        </if>
+<!--        <choose>-->
+<!--            <when test="vo.isArchive != null and vo.isArchive != ''">-->
+<!--                and u.is_auto_file = #{vo.isArchive}-->
+<!--            </when>-->
+<!--            <when test="vo.archiveId != null and vo.archiveId != ''">-->
+<!--                and 1=1-->
+<!--            </when>-->
+<!--            <otherwise>-->
+<!--                and (u.is_auto_file is null or u.is_auto_file != 1)-->
+<!--            </otherwise>-->
+<!--        </choose>-->
         <if test="vo.nodeIds != null and vo.nodeIds != ''">
             and u.node_id in
             <foreach collection="vo.nodeIdArray" item="nodeId" open="(" separator="," close=")">
@@ -138,17 +141,20 @@
         <if test="vo.rectification != null and vo.rectification != ''">
             and u.rectification = #{vo.rectification}
         </if>
-        <choose>
-            <when test="vo.isArchive != null and vo.isArchive != ''">
-                and u.is_auto_file = #{vo.isArchive}
-            </when>
-            <when test="vo.archiveId != null and vo.archiveId != ''">
-                and 1=1
-            </when>
-            <otherwise>
-                and (u.is_auto_file is null or u.is_auto_file != 1)
-            </otherwise>
-        </choose>
+        <if test="vo.rectification == null and vo.archiveId == null">
+            and (u.is_auto_file is null or u.is_auto_file != 1)
+        </if>
+<!--        <choose>-->
+<!--            <when test="vo.isArchive != null and vo.isArchive != ''">-->
+<!--                and u.is_auto_file = #{vo.isArchive}-->
+<!--            </when>-->
+<!--            <when test="vo.archiveId != null and vo.archiveId != ''">-->
+<!--                and 1=1-->
+<!--            </when>-->
+<!--            <otherwise>-->
+<!--                and (u.is_auto_file is null or u.is_auto_file != 1)-->
+<!--            </otherwise>-->
+<!--        </choose>-->
         <if test="vo.nodeIds != null and vo.nodeIds != ''">
             and u.node_id in
             <foreach collection="vo.nodeIdArray" item="nodeId" open="(" separator="," close=")">

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

@@ -63,10 +63,15 @@ public interface ITaskService extends BaseService<Task> {
     Boolean abolishTask(Task task);
 
     /**
-     * 获取任务数量
+     * 获取任务数量 - 非档案,其他任务
      */
     Map<String, String> getTaskCount(String projectId, String contractId, String userId);
 
+    /**
+     * 获取任务数量 - 档案任务
+     */
+    Map<String, String> getTaskCountArchive(String projectId, String contractId, String userId);
+
     /**
      * 获取当前合同段有哪些上报批次
      */
@@ -87,5 +92,5 @@ public interface ITaskService extends BaseService<Task> {
     /**
      * 清除废除任务是的业务数据
      */
-    void delArchiveFileBusinessData(Long projectId,Long wbsId);
+    void delArchiveFileBusinessData(Long projectId, Long wbsId);
 }

+ 74 - 1
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TaskServiceImpl.java

@@ -372,6 +372,14 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
         return true;
     }
 
+    /**
+     * 非档案任务
+     *
+     * @param projectId
+     * @param contractId
+     * @param userId
+     * @return
+     */
     @Override
     public Map<String, String> getTaskCount(String projectId, String contractId, String userId) {
         if (StringUtils.isNotEmpty(projectId) && StringUtils.isNotEmpty(contractId)) {
@@ -379,7 +387,72 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
                     .select(Task::getProcessInstanceId)
                     .eq(Task::getProjectId, projectId)
                     .eq(Task::getContractId, contractId)
-                    .eq(Task::getStatus, 1)); //只获取待办任务数量
+                    .eq(Task::getStatus, 1) //只获取待办任务数量
+                    .ne(Task::getApprovalType, 4));//不等于4,不查档案的任务,档案单独处理
+
+            //任务主表相关数量
+            List<String> taskCountIds = tasks.stream().map(Task::getProcessInstanceId).collect(Collectors.toList());
+
+            //任务附表中当前用户的相关任务数量
+            long taskAllCount = 0;
+            if (taskCountIds.size() > 0) {
+                taskAllCount = taskParallelService.getBaseMapper().selectCount(Wrappers.<TaskParallel>lambdaQuery()
+                        .in(TaskParallel::getProcessInstanceId, taskCountIds)
+                        .eq(TaskParallel::getTaskUser, userId)
+                        .eq(TaskParallel::getStatus, 1));
+            }
+
+            //未读消息提醒数量
+            List<MessageWarning> messageWarnings = messageWarningService.getBaseMapper().selectList(Wrappers.<MessageWarning>lambdaQuery()
+                    .select(MessageWarning::getType)
+                    .eq(MessageWarning::getProjectId, projectId)
+                    .eq(MessageWarning::getContractId, contractId)
+                    .eq(MessageWarning::getPushUser, userId)
+                    .eq(MessageWarning::getIsRead, 0)
+            );
+
+            long messageCount1 = messageWarnings.stream().filter(f -> f.getType().equals(1)).count();
+            long messageCount2 = messageWarnings.stream().filter(f -> f.getType().equals(2)).count();
+            long messageCount3 = messageWarnings.stream().filter(f -> f.getType().equals(3)).count();
+            long messageCount4 = messageWarnings.stream().filter(f -> f.getType().equals(4)).count();
+            long messageCount5 = messageWarnings.stream().filter(f -> f.getType().equals(5)).count();
+            Map<String, String> map = new HashMap<>();
+            map.put("allCount", String.valueOf(taskAllCount + messageWarnings.size()));//任务管理
+            map.put("taskCount", String.valueOf(taskAllCount));//任务查看
+            map.put("messageCount", String.valueOf(messageWarnings.size()));//消息提醒
+            map.put("messageCount_1", String.valueOf(messageCount1));//任务催办
+            map.put("messageCount_2", String.valueOf(messageCount2));//监测预警
+            map.put("messageCount_3", String.valueOf(messageCount3));//废除通知
+            map.put("messageCount_4", String.valueOf(messageCount4));//工单反馈
+            map.put("messageCount_5", String.valueOf(messageCount5));//系统消息
+            map.put("userId", userId);
+            return map;
+        } else {
+            Map<String, String> map = new HashMap<>();
+            List<BusinessUserOpinionVO> businessUserOpinionVOS = userOpinionService.getBaseMapper().queryManageUserOpinionList(userId).stream().filter(f -> f.getIsCurrent().equals(false)).collect(Collectors.toList());
+            map.put("myMessageCount", String.valueOf(businessUserOpinionVOS.size()));//后管消息区-我的消息-未处理
+            map.put("userId", userId);
+            return map;
+        }
+    }
+
+    /**
+     * 档案任务相关
+     *
+     * @param projectId
+     * @param contractId
+     * @param userId
+     * @return
+     */
+    @Override
+    public Map<String, String> getTaskCountArchive(String projectId, String contractId, String userId) {
+        if (StringUtils.isNotEmpty(projectId) && StringUtils.isNotEmpty(contractId)) {
+            List<Task> tasks = this.baseMapper.selectList(Wrappers.<Task>lambdaQuery()
+                    .select(Task::getProcessInstanceId)
+                    .eq(Task::getProjectId, projectId)
+                    .eq(Task::getContractId, contractId)
+                    .eq(Task::getStatus, 1) //只获取待办任务数量
+                    .eq(Task::getApprovalType, 4));//只查询档案的任务,档案单独处理
 
             //任务主表相关数量
             List<String> taskCountIds = tasks.stream().map(Task::getProcessInstanceId).collect(Collectors.toList());

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

@@ -12,6 +12,14 @@
 
     <artifactId>blade-e-visa</artifactId>
 
+    <repositories>
+        <repository>
+            <id>com.e-iceblue</id>
+            <name>e-iceblue</name>
+            <url>https://repo.e-iceblue.cn/repository/maven-public/</url>
+        </repository>
+    </repositories>
+
     <dependencies>
         <dependency>
             <groupId>org.springblade</groupId>
@@ -195,6 +203,11 @@
             <version>2.0.20</version>
             <scope>compile</scope>
         </dependency>
+        <dependency>
+            <groupId>e-iceblue</groupId>
+            <artifactId>spire.office.free</artifactId>
+            <version>5.3.1</version>
+        </dependency>
         <dependency>
             <groupId>org.springblade</groupId>
             <artifactId>blade-system-api</artifactId>

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

@@ -8,6 +8,7 @@ import org.springblade.evisa.service.EVisaService;
 import org.springblade.evisa.vo.CertBeanVO;
 import org.springblade.evisa.vo.EVisaMakeSealVO;
 import org.springblade.evisa.vo.EVisaTaskApprovalVO;
+import org.springblade.evisa.vo.TaskArchiveDTO;
 import org.springframework.web.bind.annotation.RestController;
 
 import java.util.List;
@@ -46,6 +47,11 @@ public class EVisaClientImpl implements EVisaClient {
         return this.eVisaService.eVisa(task);
     }
 
+    @Override
+    public void eVisaCustom(org.springblade.evisa.vo.TaskArchiveDTO eVisaObj) {
+        this.eVisaService.eVisaCustom(eVisaObj);
+    }
+
     @Override
     public String createSeal(EVisaMakeSealVO vo) {
         return this.eVisaService.createSeal(vo);

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

@@ -23,6 +23,11 @@ public interface EVisaService {
      */
     String eVisa(EVisaTaskApprovalVO task);
 
+    /**
+     * 电签(档案-批量自定义)
+     */
+    void eVisaCustom(org.springblade.evisa.vo.TaskArchiveDTO eVisaObj);
+
     /**
      * 创建印模
      */

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

@@ -31,6 +31,8 @@ import org.apache.commons.lang.StringUtils;
 import org.apache.pdfbox.pdmodel.PDDocument;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springblade.business.entity.ArchiveFile;
+import org.springblade.business.entity.Task;
 import org.springblade.business.feign.TaskClient;
 import org.springblade.business.vo.TaskApprovalVO;
 import org.springblade.common.constant.CommonConstant;
@@ -39,13 +41,14 @@ import org.springblade.common.utils.CommonUtil;
 import org.springblade.common.utils.SnowFlakeUtil;
 import org.springblade.core.oss.model.BladeFile;
 import org.springblade.core.secure.utils.AuthUtil;
+import org.springblade.core.secure.utils.SecureUtil;
+import org.springblade.core.tool.utils.DateUtil;
 import org.springblade.core.tool.utils.FileUtil;
+import org.springblade.core.tool.utils.ObjectUtil;
 import org.springblade.evisa.redissionUtil.DistributedRedisLock;
 import org.springblade.evisa.service.EVisaService;
-import org.springblade.evisa.vo.EVisaMakeSealVO;
-import org.springblade.evisa.vo.EVisaTaskApprovalVO;
-import org.springblade.evisa.vo.SealPdfVO;
-import org.springblade.evisa.vo.SealStrategyVO;
+import org.springblade.evisa.utils.PDFUtils;
+import org.springblade.evisa.vo.*;
 import org.springblade.manager.entity.ContractInfo;
 import org.springblade.manager.entity.SignPfxFile;
 import org.springblade.manager.feign.ContractClient;
@@ -57,6 +60,8 @@ import org.springframework.data.redis.core.StringRedisTemplate;
 import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
 import org.springframework.http.converter.HttpMessageConverter;
 import org.springframework.http.converter.StringHttpMessageConverter;
+import org.springframework.jdbc.core.BeanPropertyRowMapper;
+import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.mock.web.MockMultipartFile;
 import org.springframework.stereotype.Service;
 import org.springframework.web.client.RestTemplate;
@@ -70,10 +75,7 @@ import javax.imageio.stream.ImageOutputStream;
 import java.awt.image.BufferedImage;
 import java.io.*;
 import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
+import java.util.*;
 
 @Service
 @AllArgsConstructor
@@ -106,6 +108,9 @@ public class EVisaServiceImpl implements EVisaService {
     @Autowired
     StringRedisTemplate RedisTemplate;
 
+    private final JdbcTemplate jdbcTemplate;
+
+
     @Override
     public String certification(String pdfUrl, String fileName, String contractId) {
         try {
@@ -213,6 +218,83 @@ public class EVisaServiceImpl implements EVisaService {
      */
     @Override
     public String eVisaContractSeal(EVisaTaskApprovalVO task, String finalPdfUrl) {
+
+        //获取任务对应表格的电签配置(合同张)
+        String sysBatch = ParamCache.getValue(CommonConstant.SYS_USER_TASK_BATCH);
+        int batch = 2;
+        if (CommonUtil.checkIsBigDecimal(sysBatch)) {
+            batch = new Integer(sysBatch);
+        }
+
+        if (DistributedRedisLock.acquire(AuthUtil.getUserId().toString(), batch)) {
+            try {
+
+                List<String> eVisaConfigList = PDFUtils.getPdfSignIds(finalPdfUrl);
+                if (eVisaConfigList == null || eVisaConfigList.size() == 0) {
+                    return finalPdfUrl;
+                }
+                String contractId = this.taskClient.queryTaskContractId(task.getParallelProcessInstanceId());
+
+                String ids = String.join(",", eVisaConfigList);
+                String sqlinfo = "SELECT a.id,a.pyzbx,a.pyzby,b.signature_file_url,b.id as sfId,b.certificate_password,b.certificate_user_name from m_textdict_info a ,m_sign_pfx_file b where a.sig_role_id = b.pfx_type and b.project_contract_role like '%" + contractId + "%' and a.is_deleted=0 and b.is_deleted=0 and a.type=6 and a.id in(" + ids + ")";
+                List<Map<String, Object>> maps = jdbcTemplate.queryForList(sqlinfo);
+                System.out.println("合同-"+contractId+"--"+sqlinfo);
+
+                //准备签章策略
+                List<SealStrategyVO> sealStrategyVOS = new ArrayList<>();
+                for (Map<String, Object> eVisaConfig : maps) {
+                    //设置签章策略
+                    SealStrategyVO vo = new SealStrategyVO();
+                    vo.setSealCode(EVisaConstant.SIGN_SEAL_CODE + eVisaConfig.get("sfId"));
+                    vo.setSealPassword(eVisaConfig.get("certificate_password")+"");
+                    vo.setSealPerson(eVisaConfig.get("certificate_user_name")+"" + System.currentTimeMillis());
+                    //设置签字文件
+                    vo.setImageUrl(eVisaConfig.get("signature_file_url")+"");
+                    vo.setSealType("3");
+                    vo.setCompanySeal(true);
+                    vo.setKeyword(eVisaConfig.get("id")+"");
+                    vo.setOffSetX(eVisaConfig.get("pyzbx")+"");
+                    vo.setOffSetY(eVisaConfig.get("pyzby")+"");
+                    sealStrategyVOS.add(vo);
+                }
+
+                SealPdfVO pdfVO = new SealPdfVO();
+                pdfVO.setStrategyVoList(sealStrategyVOS);
+
+                //获取字节
+                byte[] fileByte = CommonUtil.InputStreamToBytes(CommonUtil.getOSSInputStream(finalPdfUrl));
+                //执行电签
+                Object[] result = this.signPdfByAXQZ(pdfVO, fileByte);
+                if (result != null) {
+                    if (result[0] != null) {
+                        MultipartFile newFiles = new MockMultipartFile("file", SnowFlakeUtil.getId() + ".pdf", "text/plain", IOUtils.toByteArray(new ByteArrayInputStream((byte[]) result[0])));
+                        //重新上传
+                        BladeFile bladeFile = this.newIOSSClient.uploadFileByInputStream(newFiles);
+                        if (bladeFile != null) {
+                            finalPdfUrl = bladeFile.getLink();
+                        }
+                    }
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+        //释放锁
+        DistributedRedisLock.release(AuthUtil.getUserId().toString());
+
+        return finalPdfUrl;
+    }
+
+
+    /**
+     * 合同章 签字
+     *
+     * @param task
+     * @param finalPdfUrl
+     * @return
+     */
+
+    public String eVisaContractSeal222(EVisaTaskApprovalVO task, String finalPdfUrl) {
         //获取任务对应表格的电签配置(合同张)
         List<JSONObject> eVisaConfigList = this.taskClient.queryBusinessTableEVisaConfig(task.getParallelProcessInstanceId(), task.getUserId(), "true");
         if (eVisaConfigList == null || eVisaConfigList.size() == 0) {
@@ -320,22 +402,6 @@ public class EVisaServiceImpl implements EVisaService {
             return NOT_PFX_OR_FILE;
         }
 
-        //获取任务对应表格的电签配置
-        List<JSONObject> eVisaConfigList = this.taskClient.queryBusinessTableEVisaConfig(task.getParallelProcessInstanceId(), task.getUserId(), "false");
-        if (eVisaConfigList == null || eVisaConfigList.size() == 0) {
-            //没有电签配置,默认当前任务为不签字审批,返回成功
-            RedisTemplate.delete("sign-" + task.getFormDataId());
-            return SUCCESS + "@@@@" + taskFile.getApprovalFileList().get(0).getFileUrl();
-        }
-
-        //获取当前用户的证书信息
-        List<SignPfxFile> userPfxList = this.signPfxClient.querySignPfxByUserIdOrContractId(task.getUserId().toString(), "");
-        if (userPfxList == null || userPfxList.size() <= 0) {
-            //没有签章,不执行电签
-            RedisTemplate.delete("sign-" + task.getFormDataId());
-            return NOT_PFX_OR_FILE;
-        }
-
         //上锁
         //if (DistributedRedisLock.acquire(task.getUserId().toString(), batch)) {
         try {
@@ -348,42 +414,51 @@ public class EVisaServiceImpl implements EVisaService {
                     //TODO ============== 试验相关的关联文件不电签 liuYC 2023-03-17 ==============
                     continue;
                 }
-
+                String pdfUrl = file.getFileUrl();
+                List<String> eVisaConfigList = PDFUtils.getPdfSignIds(pdfUrl);
+                if (eVisaConfigList == null || eVisaConfigList.size() == 0) {
+                    //没有电签配置,默认当前任务为不签字审批,返回成功
+                    RedisTemplate.delete("sign-" + task.getFormDataId());
+                    return SUCCESS + "@@@@" + taskFile.getApprovalFileList().get(0).getFileUrl();
+                }
+                String contractId = this.taskClient.queryTaskContractId(task.getParallelProcessInstanceId());
+                String ids = String.join(",", eVisaConfigList);
+                String sqlinfo = " SELECT a.id,a.pyzbx ,a.pyzby,(SELECT signature_file_url from m_sign_pfx_file where is_register=1 and certificate_user_id='" + task.getUserId() + "' and is_deleted=0  ) as signature_file_url from m_textdict_info a where  a.type =2 and a.id in (" + ids + ")  and sig_role_id in (SELECT DISTINCT c.role_id from m_project_assignment_user c  where c.contract_id=" + contractId + " and user_id=" + task.getUserId() + " and c.is_deleted=0 )";
+                List<Map<String, Object>> maps = jdbcTemplate.queryForList(sqlinfo);
+                System.out.println("个人-user-id"+task.getUserId()+"--SQL="+sqlinfo);
+                if (maps == null || maps.size() <= 0) {
+                    //没有签章,不执行电签
+                    RedisTemplate.delete("sign-" + task.getFormDataId());
+                    return NOT_PFX_OR_FILE;
+                }
                 //准备签章策略
                 List<SealStrategyVO> sealStrategyVOS = new ArrayList<>();
-                for (JSONObject eVisaConfig : eVisaConfigList) {
+                for (Map<String, Object> eVisaConfig : maps) {
                     //设置签章策略
                     SealStrategyVO vo = new SealStrategyVO();
                     vo.setSealCode(EVisaConstant.SIGN_SEAL_CODE + task.getUserId());
                     vo.setSealPassword(task.getUserId().toString().substring(0, EVisaConstant.USER_ID_SUB));
                     vo.setSealPerson(task.getNickName());
                     //设置签字文件
-                    vo.setImageUrl(userPfxList.get(0).getSignatureFileUrl());
+                    vo.setImageUrl(eVisaConfig.get("signature_file_url") + "");
                     vo.setSealType("3");
-
-                    vo.setKeyword(eVisaConfig.getString("KEY"));
-                    vo.setOffSetX(eVisaConfig.getString("X"));
-                    vo.setOffSetY(eVisaConfig.getString("Y"));
+                    vo.setKeyword(eVisaConfig.get("id") + "");
+                    vo.setOffSetX(eVisaConfig.get("pyzbx") + "");
+                    vo.setOffSetY(eVisaConfig.get("pyzby") + "");
                     sealStrategyVOS.add(vo);
                 }
                 SealPdfVO pdfVO = new SealPdfVO();
                 pdfVO.setStrategyVoList(sealStrategyVOS);
 
                 //获取字节
-                byte[] fileByte = CommonUtil.InputStreamToBytes(CommonUtil.getOSSInputStream(file.getFileUrl()));
+                byte[] fileByte = CommonUtil.InputStreamToBytes(CommonUtil.getOSSInputStream(pdfUrl));
                 //执行电签
                 Object[] result = this.signPdfByAXQZ(pdfVO, fileByte);
                 if (result != null) {
                     if (result[0] != null) {
-
-                      //MultipartFile newFiles = new MockMultipartFile("file", SnowFlakeUtil.getId() + ".pdf", "text/plain", IOUtils.toByteArray(new ByteArrayInputStream((byte[]) result[0])));
-
-                        byte[] byteArray = IOUtils.toByteArray(new ByteArrayInputStream((byte[]) result[0]));
-                        String dataUrl = "/www/wwwroot/Users/hongchuangyanfa/Desktop/pdf/"+SnowFlakeUtil.getId() + ".pdf";
-                        File file1 =new File(dataUrl);
-                        FileUtil.copy(byteArray,file1);
+                        MultipartFile newFiles = new MockMultipartFile("file", SnowFlakeUtil.getId() + ".pdf", "text/plain", IOUtils.toByteArray(new ByteArrayInputStream((byte[]) result[0])));
                         //重新上传
-                        BladeFile bladeFile = this.newIOSSClient.uploadFile(SnowFlakeUtil.getId() + ".pdf",dataUrl);
+                        BladeFile bladeFile = this.newIOSSClient.uploadFileByInputStream(newFiles);
                         if (bladeFile != null) {
                             resultMessage = SUCCESS + "@@@@" + bladeFile.getLink();
                         } else {
@@ -407,6 +482,156 @@ public class EVisaServiceImpl implements EVisaService {
         return resultMessage;
     }
 
+    /**
+     * 自定义签章-电签信息
+     *
+     * @param taskArchiveDTO
+     */
+    public void eVisaCustom(org.springblade.evisa.vo.TaskArchiveDTO taskArchiveDTO) {
+        //type=1表示任务审批自定义签章,type=2表示认证电签签章(不涉及审批任务)
+        if (taskArchiveDTO.getSealStrategy().size() > 0 && taskArchiveDTO.getType() == 1) {
+            //获取档案任务
+            Task task = jdbcTemplate.queryForObject("select form_data_id from u_task where id = " + taskArchiveDTO.getTaskId(), new BeanPropertyRowMapper<>(Task.class));
+            if (task != null) {
+                //获取档案任务的文件信息
+                ArchiveFile archiveFile = jdbcTemplate.queryForObject("select pdf_file_url,e_visa_file from u_archive_file where id = " + task.getFormDataId(), new BeanPropertyRowMapper<>(ArchiveFile.class));
+                if (archiveFile != null && archiveFile.getPdfFileUrl() != null) {
+                    String signPdfUrl;
+                    if (ObjectUtil.isNotEmpty(archiveFile.getEVisaFile())) {
+                        //如果e_visa_file有值,那么证明之前有过其他人进行电签,那么获取e_visa_file进行追加电签
+                        signPdfUrl = archiveFile.getEVisaFile();
+                    } else {
+                        //否则使用原始pdf_file_url电签
+                        signPdfUrl = archiveFile.getPdfFileUrl();
+                    }
+
+                    try {
+                        //准备签章策略
+                        SealPdfVO pdfVO = new SealPdfVO();
+                        //获取当前用户的CA签字体证书信息、封装签章位置信息
+                        List<TaskArchiveDTO.Sign> signList = taskArchiveDTO.getSealStrategy();
+                        List<SealStrategyVO> sealStrategyVOS = new ArrayList<>();
+                        for (TaskArchiveDTO.Sign index : signList) {
+                            if (ObjectUtil.isNotEmpty(index.getUrl())) { //CA签字体证书不为空才签章
+                                SealStrategyVO signVO = new SealStrategyVO();
+                                signVO.setIsCenterCoordinate("1"); //左上角为原点
+                                signVO.setSealCode(EVisaConstant.SIGN_SEAL_CODE + SecureUtil.getUserId());
+                                signVO.setSealPassword(SecureUtil.getUserId().toString().substring(0, EVisaConstant.USER_ID_SUB));
+                                signVO.setSealPerson(SecureUtil.getNickName());
+
+                                //位置信息
+                                signVO.setImageUrl(index.getUrl()); //CA签字体
+                                signVO.setSealType("2");//坐标签章
+                                signVO.setLx(index.getLx()); //x轴
+                                signVO.setLy(index.getLy()); //y轴
+                                signVO.setPage(index.getPage()); //page页码
+                                sealStrategyVOS.add(signVO);
+                            }
+                        }
+                        pdfVO.setStrategyVoList(sealStrategyVOS);
+
+                        //获取档案pdfUrl
+                        byte[] fileByte = CommonUtil.InputStreamToBytes(CommonUtil.getOSSInputStream(signPdfUrl));
+
+                        //TODO ========== 执行电签 ==========
+                        Object[] result = this.signPdfByAXQZ(pdfVO, fileByte);
+
+                        //返回结果集
+                        if (result != null) {
+                            if (result[0] != null) {
+                                byte[] byteArray = IOUtils.toByteArray(new ByteArrayInputStream((byte[]) result[0]));
+
+                                /*String dataUrl = "C:\\pdfFiles\\" + SnowFlakeUtil.getId() + ".pdf";
+                                File file1 = new File(dataUrl);
+                                FileUtils.writeByteArrayToFile(file1, byteArray);*/
+
+                                BladeFile bladeFile = this.newIOSSClient.updateFile(byteArray, SnowFlakeUtil.getId() + ".pdf");
+                                if (bladeFile != null) {
+                                    //更新最新的电签pdfUrl
+                                    jdbcTemplate.execute("update u_archive_file set e_visa_file = '" + bladeFile.getLink() + "' where id = " + task.getFormDataId());
+                                    String successMsg = SUCCESS + "@@@@" + bladeFile.getLink();
+                                    logger.info(successMsg);
+                                }
+                            }
+                        }
+                    } catch (Exception e) {
+                        logger.error(e.getMessage());
+                        e.printStackTrace();
+                    }
+                }
+            }
+        } else if (taskArchiveDTO.getSealStrategy().size() > 0 && taskArchiveDTO.getType() == 2) {
+            //此时的taskArchiveDTO.taskId=档案数据业务id(档案认证不涉及审批流任务)
+            //获取档案任务的文件信息(这里根据id再查询一次,入参的时候不想重新构造入参的dto了)
+            ArchiveFile archiveFile = jdbcTemplate.queryForObject("select pdf_file_url,e_visa_file from u_archive_file where id = " + taskArchiveDTO.getTaskId(), new BeanPropertyRowMapper<>(ArchiveFile.class));
+            if (archiveFile != null && archiveFile.getPdfFileUrl() != null) {
+                String signPdfUrl;
+                if (ObjectUtil.isNotEmpty(archiveFile.getEVisaFile())) {
+                    //如果e_visa_file有值,那么证明之前有过其他人进行电签,那么获取e_visa_file进行追加电签
+                    signPdfUrl = archiveFile.getEVisaFile();
+                } else {
+                    //否则使用原始pdf_file_url电签
+                    signPdfUrl = archiveFile.getPdfFileUrl();
+                }
+
+                try {
+                    //准备签章策略
+                    SealPdfVO pdfVO = new SealPdfVO();
+                    //获取当前用户的CA签字体证书信息、封装签章位置信息
+                    List<TaskArchiveDTO.Sign> signList = taskArchiveDTO.getSealStrategy();
+                    List<SealStrategyVO> sealStrategyVOS = new ArrayList<>();
+                    for (TaskArchiveDTO.Sign index : signList) {
+                        if (ObjectUtil.isNotEmpty(index.getUrl())) { //CA签字体证书不为空才签章
+                            SealStrategyVO signVO = new SealStrategyVO();
+                            signVO.setIsCenterCoordinate("1"); //左上角为原点
+                            signVO.setSealCode(EVisaConstant.SIGN_SEAL_CODE + SecureUtil.getUserId());
+                            signVO.setSealPassword(SecureUtil.getUserId().toString().substring(0, EVisaConstant.USER_ID_SUB));
+                            signVO.setSealPerson(SecureUtil.getNickName());
+
+                            //位置信息
+                            signVO.setImageUrl(index.getUrl()); //CA签字体
+                            signVO.setSealType("2");//坐标签章
+                            signVO.setLx(index.getLx()); //x轴
+                            signVO.setLy(index.getLy()); //y轴
+                            signVO.setPage(index.getPage()); //page页码
+                            sealStrategyVOS.add(signVO);
+                        }
+                    }
+                    pdfVO.setStrategyVoList(sealStrategyVOS);
+
+                    //获取档案pdfUrl
+                    byte[] fileByte = CommonUtil.InputStreamToBytes(CommonUtil.getOSSInputStream(signPdfUrl));
+
+                    //TODO ========== 执行电签 ==========
+                    Object[] result = this.signPdfByAXQZ(pdfVO, fileByte);
+
+                    //返回结果集
+                    if (result != null) {
+                        if (result[0] != null) {
+                            byte[] byteArray = IOUtils.toByteArray(new ByteArrayInputStream((byte[]) result[0]));
+
+                            /*String dataUrl = "C:\\pdfFiles\\" + SnowFlakeUtil.getId() + ".pdf";
+                            File file1 = new File(dataUrl);
+                            FileUtils.writeByteArrayToFile(file1, byteArray);*/
+
+                            BladeFile bladeFile = this.newIOSSClient.updateFile(byteArray, SnowFlakeUtil.getId() + ".pdf");
+                            if (bladeFile != null) {
+                                //更新最新的认证电签pdfUrl
+                                jdbcTemplate.execute("update u_archive_file set is_certification = 1,e_visa_file = '" + bladeFile.getLink() + "',certification_time = '" + DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss") + "' where id = " + taskArchiveDTO.getTaskId());
+                                String successMsg = SUCCESS + "@@@@" + bladeFile.getLink();
+                                logger.info(successMsg);
+                            }
+                        }
+                    }
+                } catch (Exception e) {
+                    logger.error(e.getMessage());
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+
+
     /**
      * 东方 中讯
      *

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

@@ -0,0 +1,117 @@
+package org.springblade.evisa.utils;
+
+import com.spire.pdf.PdfDocument;
+import com.spire.pdf.PdfPageBase;
+import com.spire.pdf.general.find.PdfTextFind;
+import com.spire.pdf.general.find.PdfTextFindCollection;
+import com.spire.pdf.utilities.PdfTable;
+import com.spire.pdf.utilities.PdfTableExtractor;
+
+import org.springblade.common.utils.CommonUtil;
+import org.springblade.core.tool.utils.Func;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+
+public class PDFUtils {
+/*
+    public static List<String> getPdfSignIds(String pdfUrl) {
+        PdfDocument pdf = new PdfDocument();
+        List<String> eVisaConfigList = new ArrayList<>();
+
+        try {
+            InputStream ossInputStream = CommonUtil.getOSSInputStream(pdfUrl);
+            //加载PDF文档
+            pdf.loadFromStream(ossInputStream);
+            //创建PdfTableExtractor类的对象
+            PdfTableExtractor extractor = new PdfTableExtractor(pdf);
+            for (int page = 0; page < pdf.getPages().getCount(); page++) {
+                //提取页面中的表格存入PdfTable[]数组
+                PdfTable[] tableLists = extractor.extractTable(page);
+                if (tableLists != null && tableLists.length > 0) {
+                    //遍历表格
+                    for (PdfTable table : tableLists) {
+                        int row = table.getRowCount();//获取表格行
+                        int column = table.getColumnCount();//获取表格列
+                        for (int i = 0; i < row; i++) {
+                            for (int j = 0; j < column; j++) {
+                                //获取表格中的文本内容
+                                String text = table.getText(i, j);
+                                System.out.println(text);
+                                String textVal[] = text.split(" ");
+                                for (String textStr : textVal) {
+                                    if (textStr.length() >= 15 && Func.isNumeric(textStr)) {
+                                        eVisaConfigList.add(textStr);
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            ossInputStream.close();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+        return eVisaConfigList;
+    }
+*/
+
+
+    public static List<String> getPdfSignIds(String pdfUrl) {
+        PdfDocument pdf = new PdfDocument();
+        List<String> eVisaConfigList = new ArrayList<>();
+        try {
+            InputStream ossInputStream = CommonUtil.getOSSInputStream(pdfUrl);
+            //加载PDF文档
+            pdf.loadFromStream(ossInputStream);
+
+            for(int i= 0;i<pdf.getPages().getCount();i++){
+                PdfPageBase page = pdf.getPages().get(i);
+                PdfTextFindCollection allText = page.findAllText();
+                PdfTextFind[] finds = allText.getFinds();
+                for(int k=0;k<finds.length;k++){
+                    String textStr = finds[k].getMatchText();
+                    if (textStr.length() >= 15 && Func.isNumeric(textStr)) {
+                        System.out.println(textStr);
+                        eVisaConfigList.add(textStr);
+                    }
+                }
+            }
+            ossInputStream.close();
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+        return eVisaConfigList;
+    }
+
+    public static void main123(String[] args) {
+        String pdfUrl= "https://bladex-chongqing-info.oss-cn-hangzhou.aliyuncs.com//upload/20230913/0193a0611867a1828164bb0abc65584c.pdf";
+        List<String> eVisaConfigList = new ArrayList<>();
+        try {
+            PdfDocument pdf = new PdfDocument();
+            InputStream ossInputStream = CommonUtil.getOSSInputStream(pdfUrl);
+            //加载PDF文档
+            pdf.loadFromStream(ossInputStream);
+
+            for(int i= 0;i<pdf.getPages().getCount();i++){
+                PdfPageBase page = pdf.getPages().get(i);
+               // System.out.println( page.extractText(true));
+                String text= page.extractText(false);
+                PdfTextFindCollection allText = page.findAllText();
+                PdfTextFind[] finds = allText.getFinds();
+                for(int k=0;k<finds.length;k++){
+                    String textStr = finds[k].getMatchText();
+                    if (textStr.length() >= 15 && Func.isNumeric(textStr)) {
+                        System.out.println(textStr);
+                        eVisaConfigList.add(textStr);
+                    }
+                }
+            }
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+    }
+}

+ 35 - 0
blade-service/blade-land/pom.xml

@@ -28,6 +28,41 @@
             <artifactId>blade-land-api</artifactId>
             <version>${bladex.project.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.springblade</groupId>
+            <artifactId>blade-starter-oss</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springblade</groupId>
+            <artifactId>blade-resource-api</artifactId>
+            <version>2.9.1.RELEASE</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.itextpdf</groupId>
+            <artifactId>itextpdf</artifactId>
+            <version>5.5.13</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.itextpdf</groupId>
+            <artifactId>itextpdf</artifactId>
+            <version>5.5.13</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.springblade</groupId>
+            <artifactId>blade-system-api</artifactId>
+            <version>2.9.1.RELEASE</version>
+            <scope>compile</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springblade</groupId>
+            <artifactId>blade-user-api</artifactId>
+            <version>${bladex.project.version}</version>
+        </dependency>
+
     </dependencies>
 
     <properties>

+ 75 - 0
blade-service/blade-land/src/main/java/org/springblade/land/controller/AttachmentInfoController.java

@@ -0,0 +1,75 @@
+package org.springblade.land.controller;
+
+import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import lombok.AllArgsConstructor;
+import lombok.SneakyThrows;
+import org.springblade.common.constant.CommonConstant;
+import org.springblade.core.boot.ctrl.BladeController;
+import org.springblade.core.oss.model.BladeFile;
+import org.springblade.core.tool.api.R;
+import org.springblade.core.tool.utils.FileUtil;
+import org.springblade.land.entity.AttachmentInfo;
+import org.springblade.land.entity.PolicyInfo;
+import org.springblade.land.service.IAttachmentInfoService;
+import org.springblade.land.service.IPolicyInfoService;
+import org.springblade.resource.feign.IOSSClient;
+import org.springblade.resource.feign.NewIOSSClient;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.validation.Valid;
+
+/**
+ * @author yangyj
+ * @Date 2023/2/17 10:40
+ * @description TODO
+ */
+@RestController
+@AllArgsConstructor
+@RequestMapping("/attachmentInfo")
+@Api(value = "基础数据-政策法规附件", tags = "基础数据-政策法规附件")
+public class AttachmentInfoController extends BladeController {
+
+
+    private final IAttachmentInfoService attachmentInfoService;
+    /**
+     * 上传文件
+     *
+     * @param file 文件
+     * @return ObjectStat
+     */
+    @SneakyThrows
+    @PostMapping("/add-file")
+    @ApiOperationSupport(order = 1)
+    @ApiOperation(value = "附件上传", notes = "附件上传")
+    @ApiImplicitParams(value = {
+            @ApiImplicitParam(name = "file", value = "文件", required = true),
+            @ApiImplicitParam(name = "projectId", value = "projectId", required = true)
+    })
+    public R<AttachmentInfo> addFile(@RequestParam("file") MultipartFile file, Long projectId) {
+       return attachmentInfoService.addFile(file,projectId);
+
+    }
+
+    /**
+     * 删除文件
+     */
+    @GetMapping("delete")
+    @ApiOperationSupport(order = 2)
+    @ApiOperation(value = "删除文件", notes = "传入文件id")
+    @ApiImplicitParams(value = {
+            @ApiImplicitParam(name = "id", value = "文件id", required = true)
+    })
+    public R delete(Long id){
+        attachmentInfoService.delete(id);
+        return R.success("删除成功");
+    }
+
+
+
+
+}

+ 87 - 0
blade-service/blade-land/src/main/java/org/springblade/land/controller/CropsInfoController.java

@@ -0,0 +1,87 @@
+package org.springblade.land.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+import io.swagger.annotations.*;
+import lombok.AllArgsConstructor;
+import org.springblade.core.boot.ctrl.BladeController;
+import org.springblade.core.mp.support.Query;
+import org.springblade.core.tool.api.R;
+import org.springblade.land.dto.CropsInfoDTO;
+import org.springblade.land.entity.CropsInfo;
+import org.springblade.land.entity.LandTypeInfo;
+import org.springblade.land.service.ICropsInfoService;
+import org.springblade.land.service.ILandTypeInfoService;
+import org.springblade.land.vo.CropsInfoVO;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+import java.util.List;
+
+/**
+ * @author yangyj
+ * @Date 2023/2/17 10:40
+ * @description TODO
+ */
+@RestController
+@AllArgsConstructor
+@RequestMapping("/cropsInfo")
+@Api(value = "基础数据-青苗名库", tags = "基础数据-青苗名库")
+public class CropsInfoController extends BladeController {
+
+    private final ICropsInfoService cropsInfoService;
+    /**
+     * 分页
+     */
+    @GetMapping("page")
+    @ApiOperationSupport(order = 2)
+    @ApiOperation(value = "分页", notes = "传入搜索值")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "projectId", value = "项目id", required = true),
+            @ApiImplicitParam(name = "areaId", value = "区域id", required = true),
+            @ApiImplicitParam(name = "current", value = "当前页", required = true),
+            @ApiImplicitParam(name = "size", value = "每页的数量", required = true),
+            @ApiImplicitParam(name = "name", value = "名称", required = false),
+            @ApiImplicitParam(name = "compensationType", value = "补偿性质", required = false)
+    })
+    public R<IPage<CropsInfoVO>> page(Query query, CropsInfo info){
+        IPage<CropsInfoVO> iPage = cropsInfoService.page(query, info);
+        return R.data(iPage);
+    }
+
+    /**
+     * 新增或修改
+     */
+    @PostMapping("/addOrUpdate")
+    @ApiOperationSupport(order = 1)
+    @ApiOperation(value = "新增或修改", notes = "传入对象")
+    public R addOrUpdate(@Valid @RequestBody CropsInfoDTO dto) {
+        cropsInfoService.addOrUpdate(dto);
+        return R.success("操作成功");
+    }
+
+    /**
+     * 查询单个详情
+     */
+    @GetMapping("detail")
+    @ApiOperationSupport(order = 3)
+    @ApiOperation(value = "查询单个详情", notes = "传入单个id")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "id", required = true)
+    })
+    public R<CropsInfoVO> detail(Long id){
+        return R.data(cropsInfoService.detail(id));
+    }
+
+    /**
+     * 批量删除
+     */
+    @PostMapping("/remove")
+    @ApiOperationSupport(order = 4)
+    @ApiOperation(value = "批量逻辑删除", notes = "传入ids")
+    public R remove(@ApiParam(value = "主键集合", required = true) @RequestBody List<Long> ids) {
+        cropsInfoService.remove(ids);
+        return R.success("删除成功");
+    }
+
+}

+ 99 - 0
blade-service/blade-land/src/main/java/org/springblade/land/controller/LandRoleController.java

@@ -0,0 +1,99 @@
+package org.springblade.land.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+import io.swagger.annotations.*;
+import lombok.AllArgsConstructor;
+import org.springblade.core.boot.ctrl.BladeController;
+import org.springblade.core.mp.support.Query;
+import org.springblade.core.tool.api.R;
+import org.springblade.land.entity.LandRole;
+import org.springblade.land.entity.LandTypeInfo;
+import org.springblade.land.service.ILandRoleService;
+import org.springblade.land.service.ILandTypeInfoService;
+import org.springblade.land.vo.LandRoleVO;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+import java.util.List;
+
+/**
+ * @author yangyj
+ * @Date 2023/2/17 10:40
+ * @description TODO
+ */
+@RestController
+@AllArgsConstructor
+@RequestMapping("/landRole")
+@Api(value = "基础数据-区域权限", tags = "基础数据-区域权限")
+public class LandRoleController extends BladeController {
+
+    private final ILandRoleService roleService;
+    /**
+     * 分页
+     */
+    @GetMapping("page")
+    @ApiOperationSupport(order = 2)
+    @ApiOperation(value = "分页", notes = "传入搜索值")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "projectId", value = "项目id", required = true),
+            @ApiImplicitParam(name = "current", value = "当前页", required = true),
+            @ApiImplicitParam(name = "size", value = "每页的数量", required = true),
+            @ApiImplicitParam(name = "name", value = "名称", required = false),
+    })
+    public R<IPage<LandRole>> page(Query query, LandRole info){
+        IPage<LandRole> iPage = roleService.page(query, info);
+        return R.data(iPage);
+    }
+
+
+
+    /**
+     * 新增或修改
+     */
+    @PostMapping("/addOrUpdate")
+    @ApiOperationSupport(order = 1)
+    @ApiOperation(value = "新增或修改", notes = "传入对象")
+    public R addOrUpdate(@Valid @RequestBody LandRole landRole) {
+        roleService.addOrUpdate(landRole);
+        return R.success("操作成功");
+    }
+
+    /**
+     * 查询单个详情
+     */
+    @GetMapping("detail")
+    @ApiOperationSupport(order = 3)
+    @ApiOperation(value = "查询单个详情", notes = "传入单个id")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "id", required = true)
+    })
+    public R<LandRoleVO> detail(Long id){
+        return R.data(roleService.detail(id));
+    }
+
+    /**
+     * 批量删除
+     */
+    @PostMapping("/remove")
+    @ApiOperationSupport(order = 5)
+    @ApiOperation(value = "批量逻辑删除", notes = "传入ids")
+    public R remove(@ApiParam(value = "主键集合", required = true) @RequestBody List<Long> ids) {
+        roleService.deleteLogic(ids);
+        return R.success("删除成功");
+    }
+
+    /**
+     * 查询当前项目业主方合同段
+     */
+    @GetMapping("getOwnerId")
+    @ApiOperationSupport(order = 4)
+    @ApiOperation(value = "查询当前项目业主方合同段id", notes = "传入项目id")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "projectId", value = "项目id", required = true)
+    })
+    public R<Long> getOwnerId(Long projectId){
+        return R.data(roleService.getOwnerId(projectId));
+    }
+
+}

+ 92 - 0
blade-service/blade-land/src/main/java/org/springblade/land/controller/LandTypeInfoController.java

@@ -0,0 +1,92 @@
+package org.springblade.land.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+import io.swagger.annotations.*;
+import lombok.AllArgsConstructor;
+import lombok.SneakyThrows;
+import org.springblade.core.boot.ctrl.BladeController;
+import org.springblade.core.mp.support.Query;
+import org.springblade.core.tool.api.R;
+import org.springblade.land.dto.PolicyInfoDTO;
+import org.springblade.land.dto.PolicyInfoSearchDTO;
+import org.springblade.land.entity.AttachmentInfo;
+import org.springblade.land.entity.LandTypeInfo;
+import org.springblade.land.entity.PolicyInfo;
+import org.springblade.land.service.IAttachmentInfoService;
+import org.springblade.land.service.ILandTypeInfoService;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.validation.Valid;
+import java.io.FileNotFoundException;
+import java.util.List;
+
+/**
+ * @author yangyj
+ * @Date 2023/2/17 10:40
+ * @description TODO
+ */
+@RestController
+@AllArgsConstructor
+@RequestMapping("/landTypeInfo")
+@Api(value = "基础数据-地类名库", tags = "基础数据-地类名库")
+public class LandTypeInfoController extends BladeController {
+
+    private final ILandTypeInfoService landTypeInfoService;
+    /**
+     * 分页
+     */
+    @GetMapping("page")
+    @ApiOperationSupport(order = 2)
+    @ApiOperation(value = "分页", notes = "传入搜索值")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "projectId", value = "项目id", required = true),
+            @ApiImplicitParam(name = "areaId", value = "区域id", required = true),
+            @ApiImplicitParam(name = "current", value = "当前页", required = true),
+            @ApiImplicitParam(name = "size", value = "每页的数量", required = true),
+            @ApiImplicitParam(name = "name", value = "名称", required = false),
+            @ApiImplicitParam(name = "landNature", value = "土地性质", required = false)
+    })
+    public R<IPage<LandTypeInfo>> page(Query query, LandTypeInfo info){
+        IPage<LandTypeInfo> iPage = landTypeInfoService.page(query, info);
+        return R.data(iPage);
+    }
+
+
+    /**
+     * 新增或修改
+     */
+    @PostMapping("/addOrUpdate")
+    @ApiOperationSupport(order = 1)
+    @ApiOperation(value = "新增或修改", notes = "传入对象")
+    public R addOrUpdate(@Valid @RequestBody LandTypeInfo info) {
+        landTypeInfoService.addOrUpdate(info);
+        return R.success("操作成功");
+    }
+
+    /**
+     * 查询单个详情
+     */
+    @GetMapping("detail")
+    @ApiOperationSupport(order = 3)
+    @ApiOperation(value = "查询单个详情", notes = "传入单个id")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "id", required = true)
+    })
+    public R<LandTypeInfo> detail(Long id){
+        return R.data(landTypeInfoService.detail(id));
+    }
+
+    /**
+     * 批量删除
+     */
+    @PostMapping("/remove")
+    @ApiOperationSupport(order = 4)
+    @ApiOperation(value = "批量逻辑删除", notes = "传入ids")
+    public R remove(@ApiParam(value = "主键集合", required = true) @RequestBody List<Long> ids) {
+        landTypeInfoService.deleteLogic(ids);
+        return R.success("删除成功");
+    }
+
+}

+ 92 - 0
blade-service/blade-land/src/main/java/org/springblade/land/controller/PolicyInfoController.java

@@ -0,0 +1,92 @@
+package org.springblade.land.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+import io.swagger.annotations.*;
+import lombok.AllArgsConstructor;
+import org.springblade.core.boot.ctrl.BladeController;
+
+import org.springblade.core.mp.support.Query;
+import org.springblade.core.tool.api.R;
+import org.springblade.core.tool.utils.Func;
+import org.springblade.land.dto.PolicyInfoDTO;
+import org.springblade.land.dto.PolicyInfoSearchDTO;
+import org.springblade.land.entity.PolicyInfo;
+import org.springblade.land.service.IPolicyInfoService;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+import java.io.FileNotFoundException;
+import java.util.List;
+
+/**
+ * @author yangyj
+ * @Date 2023/2/17 10:40
+ * @description TODO
+ */
+@RestController
+@AllArgsConstructor
+@RequestMapping("/policyInfo")
+@Api(value = "基础数据-政策法规双方协议", tags = "基础数据-政策法规双方协议")
+public class PolicyInfoController extends BladeController {
+
+    private final IPolicyInfoService policyInfoService;
+
+    /**
+     * 新增或修改
+     */
+    @PostMapping("/addOrUpdate")
+    @ApiOperationSupport(order = 1)
+    @ApiOperation(value = "新增或修改", notes = "传入对象")
+    public R add(@Valid @RequestBody PolicyInfoDTO dto) throws FileNotFoundException {
+        policyInfoService.add(dto);
+        return R.success("操作成功");
+    }
+
+    /**
+     * 分页
+     */
+    @GetMapping("page")
+    @ApiOperationSupport(order = 2)
+    @ApiOperation(value = "分页", notes = "传入搜索值")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "projectId", value = "项目id", required = true),
+            @ApiImplicitParam(name = "type", value = "1政策法规2双方协议", required = true),
+            @ApiImplicitParam(name = "current", value = "当前页", required = true),
+            @ApiImplicitParam(name = "size", value = "每页的数量", required = true),
+            @ApiImplicitParam(name = "name", value = "名称", required = false),
+            @ApiImplicitParam(name = "areaId", value = "区域id", required = false),
+            @ApiImplicitParam(name = "startDate", value = "开始时间", required = false),
+            @ApiImplicitParam(name = "endDate", value = "结束时间", required = false)
+    })
+    public R<IPage<PolicyInfo>> page(Query query, PolicyInfoSearchDTO dto){
+        IPage<PolicyInfo> iPage = policyInfoService.page(query, dto);
+        return R.data(iPage);
+    }
+
+    /**
+     * 查询单个详情
+     */
+    @GetMapping("detail")
+    @ApiOperationSupport(order = 3)
+    @ApiOperation(value = "查询单个详情", notes = "传入单个id")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "id", required = true)
+    })
+    public R<PolicyInfoDTO> detail(Long id){
+        return R.data(policyInfoService.detail(id));
+    }
+
+
+    /**
+     * 批量删除
+     */
+    @PostMapping("/remove")
+    @ApiOperationSupport(order = 4)
+    @ApiOperation(value = "批量逻辑删除", notes = "传入ids")
+    public R remove(@ApiParam(value = "主键集合", required = true) @RequestBody List<Long> ids) {
+        policyInfoService.remove(ids);
+        return R.success("删除成功");
+    }
+
+}

+ 40 - 0
blade-service/blade-land/src/main/java/org/springblade/land/mapper/AttachmentInfoMapper.java

@@ -0,0 +1,40 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.land.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Param;
+import org.springblade.land.entity.AttachmentInfo;
+import org.springblade.land.entity.PolicyInfo;
+
+import java.util.List;
+
+
+/**
+ *  Mapper 接口
+ *
+ * @author BladeX
+ * @since 2023-02-17
+ */
+public interface AttachmentInfoMapper extends BaseMapper<AttachmentInfo> {
+
+    void deleteByMasterId(@Param("masterId") Long masterId);
+
+    void deleteByMasterIds(@Param("masterIds") List<Long> masterIds);
+
+    void delete(@Param("id") Long id);
+}

+ 21 - 0
blade-service/blade-land/src/main/java/org/springblade/land/mapper/AttachmentInfoMapper.xml

@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.springblade.land.mapper.AttachmentInfoMapper">
+
+
+    <delete id="deleteByMasterId">
+        delete from l_attachment_info
+        where master_id = #{masterId}
+    </delete>
+    <delete id="deleteByMasterIds">
+        delete from l_attachment_info
+        where master_id in
+        <foreach collection="masterIds" item="masterId" open="(" separator="," close=")">
+            #{masterId}
+        </foreach>
+    </delete>
+    <delete id="delete">
+        delete from l_attachment_info
+        where id = #{id}
+    </delete>
+</mapper>

+ 43 - 0
blade-service/blade-land/src/main/java/org/springblade/land/mapper/CropsInfoMapper.java

@@ -0,0 +1,43 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.land.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import org.apache.ibatis.annotations.Param;
+import org.springblade.land.entity.CropsInfo;
+import org.springblade.land.entity.LandTypeInfo;
+import org.springblade.land.vo.CropsInfoVO;
+
+import java.util.List;
+
+
+/**
+ *  Mapper 接口
+ *
+ * @author BladeX
+ * @since 2023-02-17
+ */
+public interface CropsInfoMapper extends BaseMapper<CropsInfo> {
+
+
+    CropsInfoVO detail(@Param("id") Long id);
+
+    IPage<CropsInfoVO> page(IPage<CropsInfoVO> iPage,@Param("info") CropsInfo info);
+
+    void remove(@Param("ids") List<Long> ids);
+}

+ 38 - 0
blade-service/blade-land/src/main/java/org/springblade/land/mapper/CropsInfoMapper.xml

@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.springblade.land.mapper.CropsInfoMapper">
+    <delete id="remove">
+        delete from l_crops_info
+        where id in
+        <foreach collection="ids" item="id" open="(" close=")" separator=",">
+            #{id}
+        </foreach>
+        or
+        parent_id in
+        <foreach collection="ids" item="id" open="(" close=")" separator=",">
+            #{id}
+        </foreach>
+    </delete>
+
+
+    <select id="detail" resultType="org.springblade.land.vo.CropsInfoVO">
+        select
+               lci.*,
+               (select dict_value from blade_dict where code = 'compensation_type' and dict_key = lci.compensation_type) as compensationTypeName
+        from l_crops_info lci where lci.is_deleted = 0 and lci.id = #{id}
+    </select>
+    <select id="page" resultType="org.springblade.land.vo.CropsInfoVO">
+        select
+            lci.*,
+            (select dict_value from blade_dict where code = 'compensation_type' and dict_key = lci.compensation_type) as compensationTypeName
+        from l_crops_info lci
+        where lci.is_deleted = 0 and lci.project_id = #{info.projectId} and lci.parent_id = 0
+        <if test="info.compensationType != null and info.compensationType != ''">
+            and compensation_type = #{info.compensationType}
+        </if>
+        <if test="info.name != null and info.name != ''">
+            and name like concat('%',#{info.name},'%')
+        </if>
+        and area_id in (select id from l_region_tree_info where is_deleted = 0 and (ancestors like concat('%',#{info.areaId},'%') or id = #{info.areaId}))
+    </select>
+</mapper>

+ 45 - 0
blade-service/blade-land/src/main/java/org/springblade/land/mapper/LandRoleMapper.java

@@ -0,0 +1,45 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.land.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import org.apache.ibatis.annotations.Param;
+import org.springblade.land.entity.LandRole;
+import org.springblade.land.entity.LandTypeInfo;
+import org.springblade.land.vo.LandRoleVO;
+import org.springblade.system.user.entity.User;
+
+import java.util.List;
+
+
+/**
+ *  Mapper 接口
+ *
+ * @author BladeX
+ * @since 2023-02-17
+ */
+public interface LandRoleMapper extends BaseMapper<LandRole> {
+
+    LandRoleVO detail(@Param("id") Long id);
+
+    List<User> getUserList(@Param("allUser") List<Long> allUser);
+
+    Long getOwnerId(@Param("projectId") Long projectId);
+
+    IPage<LandRole> page(IPage<LandRole> iPage,@Param("role") LandRole landRole);
+}

+ 28 - 0
blade-service/blade-land/src/main/java/org/springblade/land/mapper/LandRoleMapper.xml

@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.springblade.land.mapper.LandRoleMapper">
+
+
+    <select id="detail" resultType="org.springblade.land.vo.LandRoleVO">
+        select
+                llr.*
+        from l_land_role llr where llr.id = #{id}
+    </select>
+    <select id="getUserList" resultType="org.springblade.system.user.entity.User">
+        select * from blade_user where id in
+        <foreach collection="allUser" item="user" open="(" separator="," close=")">
+            #{user}
+        </foreach>
+    </select>
+    <select id="getOwnerId" resultType="java.lang.Long">
+        select id from m_contract_info
+        WHERE contract_type = 3 and is_deleted = 0 and p_id = #{projectId}
+    </select>
+    <select id="page" resultType="org.springblade.land.entity.LandRole">
+        SELECT * from l_land_role
+        WHERE project_id = #{role.projectId} and is_deleted = 0
+        <if test="role.name != null and role.name != ''">
+            and name like concat('%',#{role.name},'%')
+        </if>
+    </select>
+</mapper>

+ 37 - 0
blade-service/blade-land/src/main/java/org/springblade/land/mapper/LandTypeInfoMapper.java

@@ -0,0 +1,37 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.land.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import org.apache.ibatis.annotations.Param;
+import org.springblade.land.dto.PolicyInfoSearchDTO;
+import org.springblade.land.entity.LandTypeInfo;
+import org.springblade.land.entity.PolicyInfo;
+
+
+/**
+ *  Mapper 接口
+ *
+ * @author BladeX
+ * @since 2023-02-17
+ */
+public interface LandTypeInfoMapper extends BaseMapper<LandTypeInfo> {
+
+
+    IPage<LandTypeInfo> page(IPage<LandTypeInfo> iPage,@Param("info") LandTypeInfo info);
+}

+ 18 - 0
blade-service/blade-land/src/main/java/org/springblade/land/mapper/LandTypeInfoMapper.xml

@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.springblade.land.mapper.LandTypeInfoMapper">
+
+
+    <select id="page" resultType="org.springblade.land.entity.LandTypeInfo">
+        select *
+        from l_land_type_info
+        where is_deleted = 0 and project_id = #{info.projectId}
+        <if test="info.landNature != null and info.landNature != ''">
+            and land_nature = #{info.landNature}
+        </if>
+        <if test="info.name != null and info.name != ''">
+            and name like concat('%',#{info.name},'%')
+        </if>
+            and area_id in (select id from l_region_tree_info where is_deleted = 0 and (ancestors like concat('%',#{info.areaId},'%') or id = #{info.areaId}))
+    </select>
+</mapper>

+ 35 - 0
blade-service/blade-land/src/main/java/org/springblade/land/mapper/PolicyInfoMapper.java

@@ -0,0 +1,35 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.land.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import org.apache.ibatis.annotations.Param;
+import org.springblade.land.dto.PolicyInfoSearchDTO;
+import org.springblade.land.entity.PolicyInfo;
+
+
+/**
+ *  Mapper 接口
+ *
+ * @author BladeX
+ * @since 2023-02-17
+ */
+public interface PolicyInfoMapper extends BaseMapper<PolicyInfo> {
+
+    IPage<PolicyInfo> page(IPage<PolicyInfo> iPage,@Param("dto") PolicyInfoSearchDTO dto);
+}

+ 19 - 0
blade-service/blade-land/src/main/java/org/springblade/land/mapper/PolicyInfoMapper.xml

@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.springblade.land.mapper.PolicyInfoMapper">
+
+
+    <select id="page" resultType="org.springblade.land.entity.PolicyInfo">
+        select * from l_policy_info
+        where is_deleted = 0 and project_id = #{dto.projectId}
+        <if test="dto.areaId != null and dto.areaId != ''">
+            and area_id = #{dto.areaId}
+        </if>
+        <if test="dto.name != null and dto.name != ''">
+            and name like concat('%',#{dto.name},'%')
+        </if>
+        <if test="dto.startDate != null and dto.startDate != '' and dto.endDate != null and dto.endDate != '' ">
+            and upload_date between #{dto.startDate} and #{dto.endDate}
+        </if>
+    </select>
+</mapper>

+ 44 - 0
blade-service/blade-land/src/main/java/org/springblade/land/service/IAttachmentInfoService.java

@@ -0,0 +1,44 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.land.service;
+
+
+import org.springblade.core.mp.base.BaseService;
+import org.springblade.core.tool.api.R;
+import org.springblade.land.entity.AttachmentInfo;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.List;
+
+
+public interface IAttachmentInfoService extends BaseService<AttachmentInfo> {
+
+    //新增附件
+    R<AttachmentInfo> addFile(MultipartFile file, Long projectId);
+
+    //根据主件id查询所有附件
+    List<AttachmentInfo> getAllFile(Long masterId);
+
+    //根据主件id删除附件
+    void deleteByMasterId(Long id);
+
+    //根据主件id批量删除附件
+    void deleteByMasterIds(List<Long> ids);
+
+    //根据附件id删除附件
+    void delete(Long id);
+}

+ 47 - 0
blade-service/blade-land/src/main/java/org/springblade/land/service/ICropsInfoService.java

@@ -0,0 +1,47 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.land.service;
+
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import org.springblade.core.mp.base.BaseService;
+import org.springblade.core.mp.support.Query;
+import org.springblade.land.dto.CropsInfoDTO;
+import org.springblade.land.entity.CropsInfo;
+import org.springblade.land.entity.LandTypeInfo;
+import org.springblade.land.vo.CropsInfoVO;
+
+import java.util.List;
+
+
+/**
+ *  服务类
+ *
+ * @author BladeX
+ * @since 2023-02-17
+ */
+public interface ICropsInfoService extends BaseService<CropsInfo> {
+
+
+    void addOrUpdate(CropsInfoDTO dto);
+
+    CropsInfoVO detail(Long id);
+
+    IPage<CropsInfoVO> page(Query query,CropsInfo info);
+
+    void remove(List<Long> ids);
+}

+ 44 - 0
blade-service/blade-land/src/main/java/org/springblade/land/service/ILandRoleService.java

@@ -0,0 +1,44 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.land.service;
+
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import org.springblade.core.mp.base.BaseService;
+import org.springblade.core.mp.support.Query;
+import org.springblade.land.entity.LandRole;
+import org.springblade.land.entity.LandTypeInfo;
+import org.springblade.land.vo.LandRoleVO;
+
+
+/**
+ *  服务类
+ *
+ * @author BladeX
+ * @since 2023-02-17
+ */
+public interface ILandRoleService extends BaseService<LandRole> {
+
+
+    void addOrUpdate(LandRole landRole);
+
+    LandRoleVO detail(Long id);
+
+    Long getOwnerId(Long projectId);
+
+    IPage<LandRole> page(Query query,LandRole landRole);
+}

+ 46 - 0
blade-service/blade-land/src/main/java/org/springblade/land/service/ILandTypeInfoService.java

@@ -0,0 +1,46 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.land.service;
+
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import org.springblade.core.mp.base.BaseService;
+import org.springblade.core.mp.support.Query;
+import org.springblade.land.dto.PolicyInfoDTO;
+import org.springblade.land.dto.PolicyInfoSearchDTO;
+import org.springblade.land.entity.LandTypeInfo;
+import org.springblade.land.entity.PolicyInfo;
+
+import java.io.FileNotFoundException;
+import java.util.List;
+
+
+/**
+ *  服务类
+ *
+ * @author BladeX
+ * @since 2023-02-17
+ */
+public interface ILandTypeInfoService extends BaseService<LandTypeInfo> {
+
+
+    void addOrUpdate(LandTypeInfo info);
+
+    LandTypeInfo detail(Long id);
+
+    IPage<LandTypeInfo> page (Query query,LandTypeInfo info);
+}

+ 49 - 0
blade-service/blade-land/src/main/java/org/springblade/land/service/IPolicyInfoService.java

@@ -0,0 +1,49 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.land.service;
+
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import org.springblade.core.mp.base.BaseService;
+import org.springblade.core.mp.support.Query;
+import org.springblade.land.dto.PolicyInfoDTO;
+import org.springblade.land.dto.PolicyInfoSearchDTO;
+import org.springblade.land.entity.PolicyInfo;
+
+import java.io.FileNotFoundException;
+import java.util.List;
+
+
+/**
+ *  服务类
+ *
+ * @author BladeX
+ * @since 2023-02-17
+ */
+public interface IPolicyInfoService extends BaseService<PolicyInfo> {
+
+    //新增或修改
+    void add(PolicyInfoDTO dto) throws FileNotFoundException;
+
+    //分页查询
+    IPage<PolicyInfo> page(Query page, PolicyInfoSearchDTO dto);
+
+    //批量删除
+    void remove(List<Long> ids);
+
+    PolicyInfoDTO detail(Long id);
+}

+ 98 - 0
blade-service/blade-land/src/main/java/org/springblade/land/service/impl/AttachmentInfoServiceImpl.java

@@ -0,0 +1,98 @@
+package org.springblade.land.service.impl;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import lombok.AllArgsConstructor;
+import org.springblade.common.utils.SnowFlakeUtil;
+import org.springblade.core.log.exception.ServiceException;
+import org.springblade.core.mp.base.BaseServiceImpl;
+import org.springblade.core.oss.model.BladeFile;
+import org.springblade.core.tool.api.R;
+import org.springblade.core.tool.utils.FileUtil;
+import org.springblade.land.entity.AttachmentInfo;
+import org.springblade.land.entity.PolicyInfo;
+import org.springblade.land.mapper.AttachmentInfoMapper;
+import org.springblade.land.mapper.PolicyInfoMapper;
+import org.springblade.land.service.IAttachmentInfoService;
+import org.springblade.land.service.IPolicyInfoService;
+import org.springblade.resource.feign.CommonFileClient;
+import org.springblade.resource.feign.IOSSClient;
+import org.springblade.resource.feign.NewIOSSClient;
+import org.springblade.resource.vo.NewBladeFile;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.List;
+
+@Service
+@AllArgsConstructor
+public class AttachmentInfoServiceImpl extends BaseServiceImpl<AttachmentInfoMapper, AttachmentInfo> implements IAttachmentInfoService {
+
+    //上传文件
+    private final IOSSClient iossClient;
+
+
+    // pdf转换
+    private final CommonFileClient commonFileClient;
+
+    @Override
+    public R<AttachmentInfo> addFile(MultipartFile file, Long projectId) {
+        if (file.getSize() > 52428800L){
+            throw new ServiceException("上传失败,文件大小超过50MB");
+        }
+        String fileExtension = FileUtil.getFileExtension(file.getOriginalFilename()).toLowerCase();
+        if (fileExtension.contains("doc") || fileExtension.contains("pdf")) {
+            R<BladeFile> bladeFile = iossClient.addFileInfo(file);
+            BladeFile bladeFile1 = bladeFile.getData();
+            AttachmentInfo info = new AttachmentInfo();
+            info.setId(SnowFlakeUtil.getId());
+            info.setName(file.getOriginalFilename());
+            info.setDomainUrl(bladeFile1.getLink());
+            info.setMasterId(-1L);
+            info.setProjectId(projectId);
+            if (fileExtension.contains("doc")){
+                NewBladeFile newBladeFile = this.commonFileClient.wordToPdf(file);
+                info.setDomainPdfUrl(newBladeFile.getPdfUrl());
+            }else {
+                info.setDomainPdfUrl(bladeFile1.getLink());
+            }
+            this.save(info);
+            return R.data(info);
+        }else {
+            throw new ServiceException("上传失败,只能上传doc或pdf文件");
+        }
+    }
+
+    /**
+     * 根据主件id获取所有附件
+     * @param masterId
+     * @return
+     */
+    @Override
+    public List<AttachmentInfo> getAllFile(Long masterId) {
+        return this.list(new LambdaQueryWrapper<AttachmentInfo>().eq(AttachmentInfo::getMasterId,masterId));
+    }
+
+    /**
+     * 根据主件删除附件
+     * @param masterId
+     */
+    @Override
+    public void deleteByMasterId(Long masterId) {
+        baseMapper.deleteByMasterId(masterId);
+    }
+
+    /**
+     * 根据主件删除附件
+     * @param masterIds
+     */
+    @Override
+    public void deleteByMasterIds(List<Long> masterIds) {
+        baseMapper.deleteByMasterIds(masterIds);
+    }
+
+    @Override
+    public void delete(Long id) {
+        baseMapper.delete(id);
+    }
+}

+ 76 - 0
blade-service/blade-land/src/main/java/org/springblade/land/service/impl/CropsInfoServiceImpl.java

@@ -0,0 +1,76 @@
+package org.springblade.land.service.impl;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import lombok.AllArgsConstructor;
+import org.springblade.common.utils.SnowFlakeUtil;
+import org.springblade.core.mp.base.BaseServiceImpl;
+import org.springblade.core.mp.support.Query;
+import org.springblade.land.dto.CropsInfoDTO;
+import org.springblade.land.entity.CropsInfo;
+import org.springblade.land.entity.LandTypeInfo;
+import org.springblade.land.mapper.CropsInfoMapper;
+import org.springblade.land.service.ICropsInfoService;
+import org.springblade.land.vo.CropsInfoVO;
+import org.springframework.beans.BeanUtils;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+
+@Service
+@AllArgsConstructor
+public class CropsInfoServiceImpl extends BaseServiceImpl<CropsInfoMapper, CropsInfo> implements ICropsInfoService {
+
+
+    @Override
+    @Transactional
+    public void addOrUpdate(CropsInfoDTO dto) {
+        dto.setParentId(0L);
+        Boolean isExist = true;
+        if (dto.getId() == null) {
+            isExist = false;
+            dto.setId(SnowFlakeUtil.getId());
+        }else {
+            this.remove(new LambdaQueryWrapper<CropsInfo>().eq(CropsInfo::getParentId,dto.getId()));
+        }
+        CropsInfo cropsInfo = new CropsInfo();
+        BeanUtils.copyProperties(dto,cropsInfo);
+        if (isExist){
+            this.updateById(cropsInfo);
+        }else {
+            this.save(cropsInfo);
+        }
+        List<CropsInfo> childrenList = dto.getChildrenList();
+        if (childrenList != null && childrenList.size() > 0){
+            for (CropsInfo info : childrenList) {
+                info.setParentId(dto.getId());
+                info.setProjectId(dto.getProjectId());
+            }
+            this.saveBatch(childrenList);
+        }
+    }
+
+    @Override
+    public CropsInfoVO detail(Long id) {
+        CropsInfoVO vo = baseMapper.detail(id);
+        List<CropsInfo> list = this.list(new LambdaQueryWrapper<CropsInfo>().eq(CropsInfo::getParentId, id));
+        if (list != null && list.size() > 0){
+            vo.setChildrenList(list);
+        }
+        return vo;
+    }
+
+    @Override
+    public IPage<CropsInfoVO> page(Query query, CropsInfo info) {
+        IPage<CropsInfoVO> iPage = new Page<>(query.getCurrent(),query.getSize());
+        return baseMapper.page(iPage,info);
+    }
+
+    @Override
+    public void remove(List<Long> ids) {
+        baseMapper.remove(ids);
+    }
+}

+ 62 - 0
blade-service/blade-land/src/main/java/org/springblade/land/service/impl/LandRoleServiceImpl.java

@@ -0,0 +1,62 @@
+package org.springblade.land.service.impl;
+
+
+
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import lombok.AllArgsConstructor;
+import org.apache.commons.lang.StringUtils;
+import org.springblade.core.mp.base.BaseServiceImpl;
+import org.springblade.core.mp.support.Query;
+import org.springblade.core.tool.utils.Func;
+import org.springblade.land.entity.LandRole;
+import org.springblade.land.entity.LandTypeInfo;
+import org.springblade.land.mapper.LandRoleMapper;
+import org.springblade.land.service.ILandRoleService;
+import org.springblade.land.vo.LandRoleVO;
+import org.springblade.system.user.entity.User;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+
+@Service
+@AllArgsConstructor
+public class LandRoleServiceImpl extends BaseServiceImpl<LandRoleMapper, LandRole> implements ILandRoleService {
+
+
+    @Override
+    public void addOrUpdate(LandRole landRole) {
+        this.saveOrUpdate(landRole);
+    }
+
+    @Override
+    public LandRoleVO detail(Long id) {
+        LandRoleVO vo = baseMapper.detail(id);
+        String allUser = vo.getAllUser();
+        if (StringUtils.isNotBlank(allUser)){
+//            String[] split = allUser.split(",");
+            List<Long> userIdList = Func.toLongList(allUser);
+            List<User> userList = baseMapper.getUserList(userIdList);
+            vo.setAllUserList(userList);
+        }
+        return vo;
+    }
+
+    /**
+     * 获取当前项目指挥部合同段id
+     * @param projectId
+     * @return
+     */
+    @Override
+    public Long getOwnerId(Long projectId) {
+        return baseMapper.getOwnerId(projectId);
+    }
+
+    @Override
+    public IPage<LandRole> page(Query query, LandRole landRole) {
+        IPage<LandRole> iPage = new Page<>(query.getCurrent(),query.getSize());
+        return baseMapper.page(iPage,landRole);
+    }
+}

+ 37 - 0
blade-service/blade-land/src/main/java/org/springblade/land/service/impl/LandTypeInfoServiceImpl.java

@@ -0,0 +1,37 @@
+package org.springblade.land.service.impl;
+
+
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import lombok.AllArgsConstructor;
+import org.springblade.core.mp.base.BaseServiceImpl;
+import org.springblade.core.mp.support.Query;
+import org.springblade.land.entity.LandTypeInfo;
+import org.springblade.land.entity.PolicyInfo;
+import org.springblade.land.mapper.LandTypeInfoMapper;
+import org.springblade.land.service.ILandTypeInfoService;
+import org.springframework.stereotype.Service;
+
+
+@Service
+@AllArgsConstructor
+public class LandTypeInfoServiceImpl extends BaseServiceImpl<LandTypeInfoMapper, LandTypeInfo> implements ILandTypeInfoService {
+
+
+    @Override
+    public void addOrUpdate(LandTypeInfo info) {
+        this.saveOrUpdate(info);
+    }
+
+    @Override
+    public LandTypeInfo detail(Long id) {
+        return this.getById(id);
+    }
+
+    @Override
+    public IPage<LandTypeInfo> page(Query query, LandTypeInfo info) {
+        IPage<LandTypeInfo> iPage = new Page<>(query.getCurrent(),query.getSize());
+        return baseMapper.page(iPage,info);
+    }
+}

+ 134 - 0
blade-service/blade-land/src/main/java/org/springblade/land/service/impl/PolicyInfoServiceImpl.java

@@ -0,0 +1,134 @@
+package org.springblade.land.service.impl;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import lombok.AllArgsConstructor;
+import net.bytebuddy.asm.Advice;
+import org.springblade.common.utils.SnowFlakeUtil;
+import org.springblade.core.log.exception.ServiceException;
+import org.springblade.core.mp.base.BaseServiceImpl;
+import org.springblade.core.mp.support.Query;
+import org.springblade.core.oss.model.BladeFile;
+import org.springblade.core.tool.utils.Func;
+import org.springblade.core.tool.utils.ResourceUtil;
+import org.springblade.land.dto.PolicyInfoDTO;
+import org.springblade.land.dto.PolicyInfoSearchDTO;
+import org.springblade.land.entity.AttachmentInfo;
+import org.springblade.land.entity.PolicyInfo;
+import org.springblade.land.mapper.PolicyInfoMapper;
+import org.springblade.land.service.IAttachmentInfoService;
+import org.springblade.land.service.IPolicyInfoService;
+import org.springblade.land.utils.FileUtils;
+import org.springblade.resource.feign.NewIOSSClient;
+import org.springframework.beans.BeanUtils;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.time.LocalDate;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+@Service
+@AllArgsConstructor
+public class PolicyInfoServiceImpl extends BaseServiceImpl<PolicyInfoMapper, PolicyInfo> implements IPolicyInfoService {
+
+    private final IAttachmentInfoService attachmentInfoService;
+
+    private final NewIOSSClient newIOSSClient;
+
+    /**
+     * 新增法律法规
+     * @param dto
+     */
+    @Override
+    @Transactional
+    public void add(PolicyInfoDTO dto) throws FileNotFoundException {
+        String file_path = FileUtils.getSysLocalFileUrl();
+        PolicyInfo policyInfo = new PolicyInfo();
+        BeanUtils.copyProperties(dto,policyInfo);
+        Boolean isExist = true;
+        if (policyInfo.getId() == null){
+            isExist = false;
+            policyInfo.setId(SnowFlakeUtil.getId());
+            policyInfo.setUploadDate(LocalDate.now());
+            //删除之前的附件
+            attachmentInfoService.deleteByMasterId(-1L);
+        }else {
+            //删除之前的附件
+            attachmentInfoService.deleteByMasterId(policyInfo.getId());
+        }
+        List<AttachmentInfo> list = dto.getList();
+        if (list == null || list.size() == 0){
+            throw new ServiceException("请上传附件");
+        }
+        List<String> data = new ArrayList<>();
+        for (AttachmentInfo info : list) {
+            info.setMasterId(policyInfo.getId());
+            data.add(info.getDomainPdfUrl());
+        }
+        if (data.size() < 1){
+            throw new ServiceException("附件信息错误");
+        }
+        String listPdf = file_path + "/pdf/" + policyInfo.getId() + ".pdf";
+        File pdf2 = ResourceUtil.getFile(listPdf);
+        if (pdf2.exists()) {
+            pdf2.delete();
+        }
+        //pdf合并
+        FileUtils.mergePdfPublicMethods(data, listPdf);
+        BladeFile bladeFile = this.newIOSSClient.uploadFile( policyInfo.getId() + ".pdf", listPdf);
+        policyInfo.setPdfUrl(bladeFile.getLink());
+        if (isExist){
+            this.updateById(policyInfo);
+        }else {
+            this.save(policyInfo);
+        }
+        //修改附件的主件id
+        attachmentInfoService.saveBatch(list);
+    }
+
+    /**
+     * 分页查询
+     * @param page
+     * @param dto
+     * @return
+     */
+    @Override
+    public IPage<PolicyInfo> page(Query page, PolicyInfoSearchDTO dto) {
+        IPage<PolicyInfo> iPage = new Page<>(page.getCurrent(),page.getSize());
+        return baseMapper.page(iPage,dto);
+    }
+
+    /**
+     * 批量删除
+     * @param ids
+     */
+    @Override
+    public void remove(List<Long> ids) {
+        //删除附件
+        attachmentInfoService.deleteByMasterIds(ids);
+        //删除主件
+        baseMapper.deleteBatchIds(ids);
+    }
+
+    /**
+     * 根据id查询
+     * @param id
+     * @return
+     */
+    @Override
+    public PolicyInfoDTO detail(Long id) {
+        PolicyInfoDTO dto = new PolicyInfoDTO();
+        PolicyInfo info = this.getById(id);
+        BeanUtils.copyProperties(info,dto);
+        List<AttachmentInfo> list = attachmentInfoService.getAllFile(id);
+        dto.setList(list);
+        return dto;
+    }
+
+}

+ 74 - 0
blade-service/blade-land/src/main/java/org/springblade/land/utils/FileUtils.java

@@ -0,0 +1,74 @@
+package org.springblade.land.utils;
+
+
+import com.itextpdf.text.Document;
+import com.itextpdf.text.pdf.PdfCopy;
+import com.itextpdf.text.pdf.PdfReader;
+import lombok.extern.slf4j.Slf4j;
+import org.springblade.common.constant.CommonConstant;
+import org.springblade.common.utils.CommonUtil;
+import org.springblade.common.utils.SystemUtils;
+import org.springblade.system.cache.ParamCache;
+
+import java.io.FileOutputStream;
+import java.util.List;
+
+@Slf4j
+public class FileUtils {
+
+    /**
+     * 合并方法
+     */
+    public static void mergePdfPublicMethods(List<String> urlList, String localImgUrl) {
+        PdfReader reader = null;
+
+        Document doc = new Document();
+        PdfCopy pdfCopy = null;
+        try {
+            pdfCopy = new PdfCopy(doc, new FileOutputStream(localImgUrl));
+            int pageCount;
+            doc.open();
+
+            for (String urlStr : urlList) {
+                try {
+                    //获取OSS文件输入流
+                    reader = new PdfReader(CommonUtil.getOSSInputStream(urlStr));
+
+                    pageCount = reader.getNumberOfPages();
+
+                    for (int i = 0; i < pageCount; ++i) {
+                        int is = i + 1;
+                        pdfCopy.addPage(pdfCopy.getImportedPage(reader, is));
+                    }
+                } catch (Exception e) {
+                    e.printStackTrace();
+                } finally {
+                    if (reader != null) {
+                        reader.close();
+                    }
+                }
+            }
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            if (pdfCopy != null) {
+                pdfCopy.flush();
+                pdfCopy.close();
+            }
+            doc.close();
+        }
+    }
+
+    public static String getSysLocalFileUrl() {
+        String file_path = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
+        if (SystemUtils.isMacOs()) {
+            file_path = "/Users/hongchuangyanfa/Desktop/";
+        } else if (SystemUtils.isWindows()) {
+            file_path = "C://upload";
+        }
+        return file_path;
+    }
+
+
+}

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

@@ -2177,7 +2177,7 @@ public class CustomFunction {
 
     /**扩散*/
     public static List<Object> diffusion(List<Object> data) {
-        List<Object> result = new ArrayList<>();
+      /*  List<Object> result = new ArrayList<>();
         if (data != null) {
             Optional<Object> op = data.stream().filter(StringUtils::isNotEmpty).findFirst();
             if (op.isPresent()) {
@@ -2186,7 +2186,8 @@ public class CustomFunction {
                         .collect(Collectors.toList());
             }
         }
-        return result;
+        return result;*/
+        return follow(data);
     }
 
     /**元素内容永远跟随第一页*/

+ 17 - 13
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/AppVersionDetailController.java

@@ -12,6 +12,7 @@ import org.springblade.core.boot.ctrl.BladeController;
 import org.springblade.core.mp.base.BaseEntity;
 import org.springblade.core.mp.support.Query;
 import org.springblade.core.tool.api.R;
+import org.springblade.core.tool.utils.ObjectUtil;
 import org.springblade.manager.entity.AppVersion;
 import org.springblade.manager.entity.AppVersionDetail;
 import org.springblade.manager.service.IAppVersionDetailService;
@@ -36,14 +37,17 @@ public class AppVersionDetailController extends BladeController {
     @GetMapping("/getNewVersion")
     @ApiOperationSupport(order = 2)
     @ApiOperation(value = "获取最新版本", notes = "传入版本id与软件类型1安卓2IOS")
-    public R<AppVersionDetail> getNewVersion(String platform,Integer softwareType,Integer fileType){
+    public R<AppVersionDetail> getNewVersion(String platform, Integer softwareType, Integer fileType) {
         AppVersion one = versionService.getOne(new LambdaQueryWrapper<AppVersion>().eq(AppVersion::getPlatform, platform));
-        return R.data(versionDetailService.getOne(new LambdaQueryWrapper<AppVersionDetail>()
-                            .eq(AppVersionDetail::getVersionId,one.getId())
-                            .eq(AppVersionDetail::getSoftwareType,softwareType)
-                            .eq(AppVersionDetail::getFileType,fileType)
-                            .orderByDesc(AppVersionDetail::getUpdateDate)
-                            .last("limit 1")));
+        LambdaQueryWrapper<AppVersionDetail> queryWrapper = new LambdaQueryWrapper<>();
+        if (ObjectUtil.isNotEmpty(fileType)) {
+            queryWrapper.eq(AppVersionDetail::getFileType, fileType);
+        }
+        queryWrapper.eq(AppVersionDetail::getVersionId, one.getId())
+                .eq(AppVersionDetail::getSoftwareType, softwareType)
+                .orderByDesc(AppVersionDetail::getUpdateDate)
+                .last("limit 1");
+        return R.data(versionDetailService.getOne(queryWrapper));
     }
 
 
@@ -54,7 +58,7 @@ public class AppVersionDetailController extends BladeController {
     @ApiOperationSupport(order = 1)
     @ApiOperation(value = "新增", notes = "传入版本信息")
     @Transactional
-    public R add(@RequestBody AppVersionDetail detail){
+    public R add(@RequestBody AppVersionDetail detail) {
         detail.setUpdateDate(LocalDateTime.now());
         versionDetailService.save(detail);
         AppVersion appVersion = new AppVersion();
@@ -71,10 +75,10 @@ public class AppVersionDetailController extends BladeController {
     @GetMapping("/page")
     @ApiOperationSupport(order = 2)
     @ApiOperation(value = "分页", notes = "传入版本id与分页信息")
-    public R<IPage<AppVersionDetail>> page(Long versionId,Query query){
-        IPage<AppVersionDetail> page = new Page<>(query.getCurrent(),query.getSize());
+    public R<IPage<AppVersionDetail>> page(Long versionId, Query query) {
+        IPage<AppVersionDetail> page = new Page<>(query.getCurrent(), query.getSize());
         IPage<AppVersionDetail> iPage = versionDetailService.page(page,
-                new LambdaQueryWrapper<AppVersionDetail>().eq(AppVersionDetail::getVersionId,versionId).orderByDesc(BaseEntity::getCreateTime));
+                new LambdaQueryWrapper<AppVersionDetail>().eq(AppVersionDetail::getVersionId, versionId).orderByDesc(BaseEntity::getCreateTime));
         return R.data(iPage);
     }
 
@@ -84,7 +88,7 @@ public class AppVersionDetailController extends BladeController {
     @PostMapping("/update")
     @ApiOperationSupport(order = 3)
     @ApiOperation(value = "修改", notes = "传入版本详情")
-    public R update(@RequestBody AppVersionDetail detail){
+    public R update(@RequestBody AppVersionDetail detail) {
         versionDetailService.updateById(detail);
         return R.data("修改成功");
     }
@@ -95,7 +99,7 @@ public class AppVersionDetailController extends BladeController {
     @GetMapping("/delete")
     @ApiOperationSupport(order = 4)
     @ApiOperation(value = "删除", notes = "传入id")
-    public R page(Long id){
+    public R page(Long id) {
         versionDetailService.removeById(id);
         return R.data("删除成功");
     }

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

@@ -1959,8 +1959,7 @@ public class ExcelTabController extends BladeController {
         List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql);
         if (maps == null || maps.size() == 0) {
             WbsTreeContract contract = wbsTreeContractService.getOne(new LambdaQueryWrapper<WbsTreeContract>().eq(WbsTreeContract::getPKeyId,nodeId));
-            String fileName = this.wbsParamService.createFileTitle(Func.isNotEmpty(contract.getOldId()) ? Long.valueOf(contract.getOldId()) : contract.getId(), Long.parseLong(contract.getContractId()), contract);
-            fileName = StringUtils.isNotEmpty(fileName) ? fileName : "缺少文件提名配置";
+            String fileName = this.wbsParamService.createFileTitle(contract);
             InformationQuery query = new InformationQuery();
             query.setId(SnowFlakeUtil.getId());
             query.setWbsId(Long.parseLong(nodeId));

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

@@ -125,7 +125,6 @@ public class FormulaController {
                         WbsTree wbsTree = this.wbsTreeService.getById(f.getNodeId());
                         efm.setWbsId(Long.parseLong(wbsTree.getWbsId()));
                     }
-
                 }
                 this.elementFormulaMappingService.save(efm);
                 /*假如不存在projectId则认为是系统级模版公式,必须同步给所有项目TODO*/
@@ -468,7 +467,12 @@ public class FormulaController {
         result.put("serve",   System.getProperty("os.name"));
         if (Func.isNotEmpty(pkeyId)) {
             String sql="select * from m_formula_log where id=?";
-            result.put("执行情况", this.jdbcTemplate.queryForList(sql,pkeyId));
+            List<Map<String,Object>> data = this.jdbcTemplate.queryForList(sql,pkeyId);
+            if(data.size()>0){
+                Map<String,Object> map =data.get(0);
+                result.put("执行情况", JSON.parse(map.get("content").toString()));
+            }
+
         }
         return R.data(result);
     }

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

@@ -528,113 +528,101 @@ public class TextdictInfoController extends BladeController {
             throw new ServiceException("请勿重复提交,请3秒后再尝试");
         }
         JSONArray jsonArray = dataInfo.getJSONArray("dataInfo");
-        Long tableId = dataInfo.getLong("tabId");
 
+        // -------- 移除所有html 的dqid -----
+        Long tableId = dataInfo.getLong("tabId"); //节点pkid
         //当前清表信息
         WbsTreePrivate wbsTreePrivate = wbsTreePrivateMapper.getByPKeyId(tableId);
-
-        //获取当前项目下引用相同模板的元素表信息
-        List<WbsTreePrivate> wbsTreePrivatesEqual = wbsTreePrivateMapper.selectList(Wrappers.<WbsTreePrivate>lambdaQuery()
-                .eq(WbsTreePrivate::getProjectId, wbsTreePrivate.getProjectId())
-                .eq(WbsTreePrivate::getExcelId, wbsTreePrivate.getExcelId()));
-//                .eq(WbsTreePrivate::getStatus, 1));
-        List<Long> pKeyIds = wbsTreePrivatesEqual.stream().map(WbsTreePrivate::getPKeyId).collect(Collectors.toList());
-        String ids = StringUtils.join(pKeyIds, ",");
-        if (StringUtils.isNotEmpty(ids)) {
-            //删除引用当前模板所有电签信息
-            String delSql = "delete from m_textdict_info where tab_id in(" + ids + ") and type in(2,6)";
-            jdbcTemplate.execute(delSql);
-        }
-
-        // 读取html页面信息
-        // File file1 = ResourceUtil.getFile(wbsTreePrivate.getHtmlUrl());
-
         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("操作成功");
         }
 
-        //当前项目下引用相同清表,同步保存电签信息
-        for (Long pKeyId : pKeyIds) {
-            for (int i = 0; i < jsonArray.size(); i++) {
-                JSONObject jsonObject = jsonArray.getJSONObject(i);
-                TextdictInfo textdictInfo = new TextdictInfo();
-                String[] trtd = jsonObject.getString("colKey").split("__")[1].split("_");
-                Element element = trs.get(Integer.parseInt(trtd[0])).select("td").get(Integer.parseInt(trtd[1]));
+        //删除历史数据
+        String delSql = "delete from m_textdict_info where tab_id in(SELECT p_key_id from m_wbs_tree_contract where p_key_id!='"+tableId+"' and  project_id="+wbsTreePrivate.getProjectId()+" and excel_id="+wbsTreePrivate.getExcelId()+") and type in(2,6) and excel_id is null";
+        jdbcTemplate.execute(delSql);
 
-                String id = element.children().get(0).attr("keyname");
+        // ------- 查询数据库是否存在 该该电签信息 ---------
+        for (int i = 0; i < jsonArray.size(); i++) {
+            JSONObject jsonObject = jsonArray.getJSONObject(i);
+            TextdictInfo textdictInfo = new TextdictInfo();
 
-                textdictInfo.setId(SnowFlakeUtil.getId());
-                textdictInfo.setName("电签位置配置");
-                textdictInfo.setType(jsonObject.getInteger("type"));
-                textdictInfo.setColKey(id);
-                textdictInfo.setSigRoleId(jsonObject.getString("sigRoleId"));
+            String[] trtd = jsonObject.getString("colKey").split("__")[1].split("_");
+            Element element = trs.get(Integer.parseInt(trtd[0])).select("td").get(Integer.parseInt(trtd[1]));
 
-                textdictInfo.setTabId(pKeyId.toString());
-
-                textdictInfo.setColName(jsonObject.getString("colName"));
-                textdictInfo.setSigRoleName(jsonObject.getString("sigRoleName"));
-                textdictInfo.setPyzbx(jsonObject.getDouble("pyzbx"));
-                textdictInfo.setPyzby(jsonObject.getDouble("pyzby"));
+            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);
-                textdictInfoService.saveOrUpdate(textdictInfo);
-
-                element.removeAttr("dqId");
-                element.attr("dqId", textdictInfo.getId() + "");
-                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");
-                    }
+            }
+            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"));
+            textdictInfoService.saveOrUpdate(textdictInfo);
+            element.removeAttr("dqId");
+            element.attr("dqId", textdictInfo.getId() + "");
+            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");
                 }
             }
         }
 
-        //写入excel
-        FileUtils.getSysLocalFileUrl();
         File writeFile = new File(wbsTreePrivate.getHtmlUrl());
         FileUtil.writeToFile(writeFile, doc.html(), Boolean.parseBoolean("UTF-8"));
 
         String str1 = wbsTreePrivate.getHtmlUrl().replace("Desktop//privateUrl", "Desktop/privateUrl");
         String replace = str1.replace("\\", "\\\\");
-        if (StringUtils.isNotEmpty(ids)) {
-            //修改所有节点的htmlUrl
-            String updateSqlP = "update m_wbs_tree_private set html_url = '" + replace + "' where p_key_id in (" + ids + ")";
-            jdbcTemplate.execute(updateSqlP);
-        }
+
+        //修改同几点的数据
+        String updateSqlP = "update m_wbs_tree_private set html_url = '" + replace + "' where p_key_id in (SELECT p_key_id from m_wbs_tree_contract where project_id="+wbsTreePrivate.getProjectId()+" and excel_id="+wbsTreePrivate.getExcelId()+")";
+        jdbcTemplate.execute(updateSqlP);
+
+        List<WbsTreePrivate> wbsTreePrivatesEqual = wbsTreePrivateMapper.selectList(Wrappers.<WbsTreePrivate>lambdaQuery()
+                .eq(WbsTreePrivate::getProjectId, wbsTreePrivate.getProjectId())
+                .eq(WbsTreePrivate::getExcelId, wbsTreePrivate.getExcelId()));
 
         //修改对应合同段的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())
-//                .eq(WbsTreeContract::getStatus, 1)
                 .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 + ")";
             jdbcTemplate.execute(updateSqlC);
@@ -647,7 +635,7 @@ public class TextdictInfoController extends BladeController {
     }
 
     /**
-     * 保存电签
+     * 保存默认值
      */
     @PostMapping("/save_defaulVal")
     @ApiOperationSupport(order = 7)

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

@@ -17,7 +17,7 @@ import static org.springblade.manager.formula.TurnPoint.*;
  * @author yangyj
  */
 public interface ITurnPointCalculator {
-    Long VERSION=2309081800L;
+    Long VERSION=2309151430L;
      String ZD_REG="(?i)zd\\d+";
     static List<TurnPoint> create(List<Map<String, Object>> data, LinkedHashMap<String, String> configMap,LevelInfo levelInfo) {
         /*1.验证数据的合理性,如果已经合理则不需要计算

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

@@ -117,7 +117,7 @@ public class FormulaMileage implements FormulaStrategy {
             }
 
         }
-
+        cur.setFinished(Boolean.TRUE);
     }
 
     public static final Pattern MILE_P = Pattern.compile("(?<=T\\(com.mixsmart.utils.CustomFunction\\).MILE\\()([^,]+),([^,]+)(?=,)");

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

@@ -16,15 +16,17 @@
         <result column="sig_role_name" property="sigRoleName"/>
         <result column="pyzbx" property="pyzbx"/>
         <result column="pyzby" property="pyzby"/>
+        <result column="pyzby" property="pyzby"/>
+        <result column="excel_id" property="excelId"/>
     </resultMap>
 
     <select id="selectTextdictInfoPage" resultMap="textdictInfoResultMap">
-        select * from m_textdict_info where is_deleted = 0 and tab_id=#{param2.tabId}
+        select distinct * from m_textdict_info where is_deleted = 0
         <if test="param2.type== 2 ">
-            and type in('2','6')
+            and type in('2','6')    and (excel_id=#{param2.excelId} or tab_id=#{param2.tabId})
         </if>
         <if test="param2.type!= 2 ">
-            and type =#{param2.type}
+            and type =#{param2.type} and tab_id=#{param2.tabId}
         </if>
     </select>
 

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

@@ -21,8 +21,6 @@ public interface IWbsParamService extends BaseService<WbsParam> {
      * @Param [nodeId:当前节点id, contractId :当前合同段id]
      * @Author yangyj
      **/
-    String createFileTitle(Long nodeId, Long contractId, WbsTreeContract wbsTreeContract);
-    String createFileTitle(Long id, Long contractId);
     String createFileTitle(WbsTreeContract wbsTreeContract);
     String createFileTitle(Long pkeyId);
 

+ 63 - 10
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ExcelTabServiceImpl.java

@@ -1,5 +1,6 @@
 package org.springblade.manager.service.impl;
 
+import cn.hutool.core.date.DateTime;
 import cn.hutool.core.date.StopWatch;
 import cn.hutool.log.StaticLog;
 import com.alibaba.fastjson.JSON;
@@ -14,17 +15,19 @@ import com.mixsmart.utils.FormulaUtils;
 import com.mixsmart.utils.ListUtils;
 import com.mixsmart.utils.RegexUtils;
 import com.spire.xls.FileFormat;
-import com.spire.xls.Worksheet;
 import lombok.AllArgsConstructor;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang3.ObjectUtils;
+import org.apache.poi.hssf.usermodel.HSSFRichTextString;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 import org.apache.poi.ss.usermodel.CellStyle;
 import org.apache.poi.ss.usermodel.Font;
 import org.apache.poi.ss.usermodel.*;
 import org.apache.poi.ss.usermodel.Workbook;
 import org.apache.poi.ss.util.CellRangeAddress;
 import org.apache.poi.util.IOUtils;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 import org.jsoup.Jsoup;
 import org.jsoup.nodes.Document;
 import org.jsoup.nodes.Element;
@@ -426,9 +429,9 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
             };
             this.jdbcTemplate.batchUpdate(sql);*/
             String deleteSql = "DELETE FROM m_formula_log WHERE id = ?";
-            String insertSql = "INSERT INTO m_formula_log (id, content) VALUES (?, ?)";
+            String insertSql = "INSERT INTO m_formula_log (id, content,update_time) VALUES (?, ?,?)";
             jdbcTemplate.update(deleteSql, pKeyId);
-            jdbcTemplate.update(insertSql, pKeyId, log);
+            jdbcTemplate.update(insertSql, pKeyId, log, DateTime.now());
         } catch (Exception e) {
             e.printStackTrace();
         }
@@ -1010,8 +1013,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
 
                     if (wbsTreeContractByP != null) {
                         //处理文件提名
-                        String fileName = this.wbsParamService.createFileTitle(Func.isNotEmpty(wbsTreeContractByP.getOldId()) ? Long.valueOf(wbsTreeContractByP.getOldId()) : wbsTreeContractByP.getId(), Long.parseLong(wbsTreeContractByP.getContractId()), wbsTreeContractByP);
-                        fileName = StringUtils.isNotEmpty(fileName) ? fileName : "缺少文件提名配置";
+                        String fileName = this.wbsParamService.createFileTitle(wbsTreeContractByP);
 
                         //huangjn 保存成功后调用生成资料查询列表数据
                         this.informationQueryClient.saveOrUpdateInformationQueryData(wbsTreeContractByP.getPKeyId() + "", "首件使用字段", "业务ID(主要将来给首件使用)", fileName, Integer.parseInt(tableInfo.getClassify()), 2, "是否是首件(临时,暂时没用到)", "源文件(首件字段)", "pdf文件(首件字段)", "首件上传总结报告名称", new ArrayList<>());
@@ -1042,8 +1044,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                 WbsTreeContract wbsTreeContractByP = wbsTreeContractService.getBaseMapper().selectOne(Wrappers.<WbsTreeContract>query().lambda()
                         .eq(WbsTreeContract::getId, wbsTreeContract.getParentId()).eq(WbsTreeContract::getContractId, wbsTreeContract.getContractId()));
                 //处理文件提名
-                String fileName = this.wbsParamService.createFileTitle(Func.isNotEmpty(wbsTreeContractByP.getOldId()) ? Long.valueOf(wbsTreeContractByP.getOldId()) : wbsTreeContractByP.getId(), Long.parseLong(wbsTreeContractByP.getContractId()), wbsTreeContractByP);
-                fileName = StringUtils.isNotEmpty(fileName) ? fileName : "缺少文件提名配置";
+                String fileName = this.wbsParamService.createFileTitle( wbsTreeContractByP);
 
                 //huangjn 保存成功后调用生成资料查询列表数据
                 this.informationQueryClient.saveOrUpdateInformationQueryData(wbsTreeContractByP.getPKeyId() + "", "首件使用字段", "业务ID(主要将来给首件使用)", fileName, Integer.parseInt(tableInfoList.get(0).getClassify()), 2, "false", "源文件(首件字段)", "pdf文件(首件字段)", "首件上传总结报告名称", new ArrayList<>());
@@ -1402,7 +1403,16 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
 
         //获取excel流 和 html流
         InputStream exceInp = CommonUtil.getOSSInputStream(excelTab.getFileUrl());
-        Workbook workbook = WorkbookFactory.create(exceInp);
+
+        Workbook workbook=null;
+        int index = excelTab.getFileUrl().lastIndexOf(".");
+        String suffix = excelTab.getFileUrl().substring(index);
+
+        if (".xls".equals(suffix)) {
+            workbook = new HSSFWorkbook(exceInp);
+        } else if (".xlsx".equals(suffix)) {
+            workbook = new XSSFWorkbook(exceInp);
+        }
 
         //获取工作表
         Sheet sheet = workbook.getSheetAt(0);
@@ -1610,7 +1620,50 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
             }
 
             // 组装电签设置
-            QueryWrapper<TextdictInfo> queryWrapper = new QueryWrapper<>();
+
+            Elements dqids = table.getElementsByAttribute("dqid");
+
+            for (Element element : dqids){
+                String dqid = element.attr("dqid");
+               // if(element.hasAttr("x1") && element.hasAttr("y1")){
+                    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());//设置字体
+                                String CellValue = cell.getStringCellValue().trim();
+
+                               /* if(CellValue!=null && StringUtils.isNotEmpty(CellValue)){
+                                    RichTextString ts= new HSSFRichTextString(CellValue + "--"+dqid);
+                                   // ts.applyFont(0,CellValue.length(),oldfontAt);
+                                 //   ts.applyFont(10,ts.length(),redFont);
+                                    cell.setCellValue(ts);
+                                }else{*/
+                                    CellStyle newStyle = workbook.createCellStyle(); //创建单元格样式
+                                    newStyle.cloneStyleFrom(cell.getCellStyle());
+                                    newStyle.setFont(redFont);
+                                    newStyle.setShrinkToFit(true);
+                                    cell.setCellStyle(newStyle);
+                                    cell.setCellValue(dqid);
+                              //  }
+                            }
+                        }
+                    }
+               // }
+            }
+
+          /*  QueryWrapper<TextdictInfo> queryWrapper = new QueryWrapper<>();
             queryWrapper.in("type", 2, 6);
             queryWrapper.eq("tab_id", wbsTreeContract.getIsTypePrivatePid());
             List<TextdictInfo> textdictInfos = textdictInfoService.getBaseMapper().selectList(queryWrapper);
@@ -1663,7 +1716,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                         }
                     }
                 }
-            }
+            }*/
         }
 
         //输出流

+ 50 - 238
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormulaServiceImpl.java

@@ -46,7 +46,6 @@ import javax.validation.constraints.NotNull;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
-import java.math.BigDecimal;
 import java.util.*;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
@@ -276,8 +275,8 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                                 if (op.isPresent()) {
                                     g = op.get();
                                 }
-                            }
-                            if (g == null) {
+                            }else{
+                                /*只有不存在配置的前提下才能尝试自动匹配*/
                                 Optional<ElementBlock> op = elementBlockList.stream().filter(w -> FormulaUtils.similarity(w.getEName(), t.getPoint()) > 0.3).max(Comparator.comparingDouble((ElementBlock b) -> FormulaUtils.similarity(b.getEName(), t.getPoint())));
                                 /*相似匹配*/
                                 if (op.isPresent()) {
@@ -287,7 +286,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                             if (g != null) {
                                 List<ItemBlock> itemBlockList = g.getList();
                                 int originSize = itemBlockList.size();
-                                List<Long> ids =getNodeType46().stream().map(CurrentNode::getId).collect(Collectors.toList());
+                                List<Long> ids =getNodeType46().stream().map(CurrentNode::getPkId).collect(Collectors.toList());
                                 /*清除那些已经不存在的工序*/
                                 itemBlockList.removeIf(ik -> !ids.contains(ik.getPkeyId()));
                                 if (itemBlockList.size() > 0) {
@@ -338,9 +337,25 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
     }
 
 
+    public void  descendantType46(Object id, List<Map<String,Object>> listMaps){
+        String sql="select p_Key_id pkId,id,node_type nodeType,table_type tableType  from m_wbs_tree_contract where parent_id =? and is_deleted=0";
+        List<Map<String,Object>> tmp=this.jdbcTemplate.queryForList(sql,id);
+        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);
+                }
+            }
+        }
+    }
+
    public List<CurrentNode> getNodeType46(){
         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=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);
             if(listMaps.size()>0){
                 tec.getCurrentNode().getDivisional().addAll(listMaps.stream().map(m->BeanUtil.toBean(m,CurrentNode.class)).collect(Collectors.toList()));
             }
@@ -834,11 +849,11 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
         try {
             /*检验单附表处理*/
             List<FormData> inspectionList = new ArrayList<>();
-            /*0检验表1评定表*/
+            /*1检验表5评定表*/
             this.tec.getTableAll().stream().filter(e -> e.getTableType().equals(1) ||e.getTableType().equals(5)).forEach(e -> {
-                /*获取所有挂在表里的元素映射关系*/
+                /*获取所有挂在检验单、评定表里的元素映射关系*/
                 this.tec.getKeyMappers().stream().filter(p -> p.getPkId().equals(e.getPKeyId())).forEach(k -> {
-                    /*元素长度筛选超页的元素*/
+                    /*筛选元素长度超1页的元素*/
                     List<FormData> target = tec.formDataMap.values().stream().filter(f -> f.getCode().equals(k.getCode()) && f.getAddPages() > 0).collect(Collectors.toList());
                     if (Func.isNotEmpty(target)) {
                         inspectionList.addAll(target);
@@ -858,8 +873,8 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                         NodeTable one = this.tec.getTableAll().get(0);
                         WbsTreeContract wtc = this.wbsTreeContractService.getOne(Wrappers.<WbsTreeContract>lambdaQuery().eq(WbsTreeContract::getParentId, one.getParentId()).eq(WbsTreeContract::getContractId,tec.getContractId()).eq(WbsTreeContract::getWbsId, one.getWbsId()).and(e->e.eq(WbsTreeContract::getNodeName, pd?"质量检验评定表(附表)":"质量检验表(附表)").or().eq(WbsTreeContract::getFullName, pd?"质量检验评定表(附表)":"质量检验表(附表)")));
                         if (wtc != null) {
-                            /*附表的顺序在检验单或者评定表之后*/
-                            int sort=this.tec.getTableAll().stream().filter(e ->e.getTableType().equals(1) || e.getTableType().equals(5)).map(NodeTable::getSort).max(Integer::compareTo).orElse(30);
+                            /*附表的顺序在检验单或者评定表之后,默认最后*/
+                            int sort=this.tec.getTableAll().stream().filter(e ->e.getTableType().equals(1) || e.getTableType().equals(5)).map(NodeTable::getSort).max(Integer::compareTo).orElse(1000);
                             this.wbsTreeContractService.update(Wrappers.<WbsTreeContract>lambdaUpdate()
                                     .set(WbsTreeContract::getSort,sort).set(WbsTreeContract::getContractType,-1).set(WbsTreeContract::getAncestors,one.getAncestors())
                                     .set(WbsTreeContract::getIsCopeTab,2)
@@ -877,7 +892,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                     JSONArray dataArray = new JSONArray();
                     for (NodeTable data : subTabList) {
                         /*自动挂载附表情况下,装配TableInfo数据*/
-                        R bussDataInfo = this.getBussDataInfo(data.getPKeyId(), 1);
+                        R bussDataInfo = this.excelTabService.getBussDataInfo(data.getPKeyId(), 1);
                         @SuppressWarnings("unchecked")
                         Map<String, Object>  data1 = (Map<String, Object>) bussDataInfo.getData();
                         data1.put("pkeyId",data.getPKeyId());
@@ -895,7 +910,8 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                     });
                     tec.getTableInfoList().addAll(subTableInfo);
                     /*获取附表元素定位集*/
-                    tec.getCoordinateMap().put(subTabList.get(0).getInitTableName(), FormulaUtils.getElementCell(first.getHtmlUrl()));
+                    /*tec.getCoordinateMap().put(subTabList.get(0).getInitTableName(), FormulaUtils.getElementCell(first.getHtmlUrl()));*/
+                    tec.getCoordinateMap().computeIfAbsent(subTabList.get(0).getInitTableName(),k->FormulaUtils.getElementCell(first.getHtmlUrl()));
                     /*附表元素关键信息*/
                     List<Map<String, Object>> elementMaps = this.jdbcTemplate.queryForList("select b.e_name ename , CONCAT(a.tab_en_name,':',b.e_key) code , b.e_key ekey ,b.id fieldId,a.tab_en_name tableName from m_table_info a join m_wbs_form_element b on a.id = b.f_id where a.tab_en_name='" + first.getInitTableName() + "' and b.is_deleted=0 ");
                     if (Func.isNotEmpty(elementMaps)) {
@@ -934,6 +950,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                 /*根据行号排序*/
                 inspectionList.sort(Comparator.comparingInt(e->e.getCoordsList().get(0).getY()));
                 inspectionList.forEach(f -> {
+                    /*检验单、评定表不能超过一页,多余的需要删除并把检测项数据写人附表*/
                     /*检验单或者评定表存的超页数据汇总到附表对象*/
                     List<ElementData> overList = f.getValues().stream().skip(f.getCoordsList().size()).collect(Collectors.toList());
                     f.setValues(f.getValues().stream().limit(f.getCoordsList().size()).collect(Collectors.toList()));
@@ -951,6 +968,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                     /*把附表数据刷入对应的附表元素对象*/
                     sta.flush();
                 }
+                /*把主表的表头表尾信息拷贝*/
                 String mainTableName = this.tec.getTableAll().stream().filter(e -> e.getTableType().equals(1) || e.getTableType().equals(5)).map(NodeTable::getInitTableName).findFirst().orElse("");
                 if(Func.isNotBlank(mainTableName)){
                     List<FormData> sourceFds=tec.getFormDataMap().values().stream().filter(s->!s.empty()).filter(s->StringUtils.isEquals(s.getTableName(),mainTableName)).collect(Collectors.toList());
@@ -1043,7 +1061,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                     });
                 }
                 List<ElementBlock> finalElementBlockList = elementBlockList;
-                tec.checkItems.stream().filter(e -> !e.empty()).forEach(c -> {
+                tec.checkItems.forEach(c -> {
                     ElementBlock eb = elementBlockMap.get(c.getCode());
                     ItemBlock targetItem = itemBlockMap.get(c.getCode() + ":" + tec.getCurrentNode().getPkId());
                     List<Object> list = c.getValues().stream().map(ElementData::getValue).filter(StringUtils::isNotEmpty).collect(Collectors.toList());
@@ -1601,7 +1619,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                          /*表名+合同段+父节点*/
                          String findStr="OP['"+fd.getTableName()+"']['"+fd.getKey()+"']['RG']";
                           String rangeStr=StringUtils.handleNull(Expression.parse(findStr).calculate(tec.constantMap));
-                         System.out.println("随机值参数:"+rangeStr);
+                         //System.out.println("随机值参数:"+rangeStr);
                          if(false){
                           /*   Optional<RangeInfo> op=tableColKeyVal.stream().map(map-> BeanUtil.toBean(JSON.parseObject(map.get("val").toString()),RangeInfo.class)).findFirst();
                              if(op.isPresent()){
@@ -1665,6 +1683,24 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                              if(CustomFunction.containsZH(devStr)||StringUtils.isEmpty(devStr)||StringUtils.handleNull(devStr).contains("/")){
                                  devStr="±100000";
                              }
+                             if(devStr.contains("E[")){
+                                List<String> codes= getCodeByEl(devStr);
+                                Map<String,Object> map = new HashMap<>();
+                                boolean isNull=false;
+                                for (String c:codes){
+                                    FormData ffd= tec.getFormDataMap().get(c);
+                                    if(ffd.empty()){
+                                        isNull=true;
+                                        break;
+                                    } else{
+                                        map.put("E["+c+"]",ffd.getRawValue().stream().filter(StringUtils::isNotEmpty).findFirst().orElse(null)) ;
+                                    }
+                                }
+                               if(isNull){
+                                   devStr="±100000";
+                               }
+                               devStr= Arrays.stream(devStr.replaceAll("^\\[|\\]$","").split(",")).map(s->map.getOrDefault(s,s)).map(StringUtils::handleNull).collect(Collectors.joining(","));
+                             }
                              /*设计值可以是数值类型,或空(等效0)*/
                              if(dataFd!=null){
                                     List<Object> values= dataFd.getRawValue();
@@ -1811,231 +1847,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
         return new HashMap<>();
     }
 
-    public R getBussDataInfo(Long pkeyId, int type) {
-
-        Map<String, Object> reData = new HashMap<>();
-
-        WbsTreeContract wbsTreeContract = wbsTreeContractService.getBaseMapper().selectOne(Wrappers.<WbsTreeContract>query().lambda()
-                .eq(WbsTreeContract::getPKeyId, pkeyId));
-        if (wbsTreeContract == null) {
-            return R.data(reData);
-        }
-
-        if (wbsTreeContract.getHtmlUrl() == null) {
-            return R.data(reData);
-        }
-
-        //表单是否存储在
-        String tabName = wbsTreeContract.getInitTableName();
-        String isExitSql = " select * from information_schema.TABLES where TABLE_NAME='" + tabName + "'";
-        List<Map<String, Object>> tabList = jdbcTemplate.queryForList(isExitSql);
-        if (tabList.size() <= 0) {
-            return R.fail("无实体表对应");
-        }
-
-        String querySql = "select * from " + wbsTreeContract.getInitTableName() + " where p_key_id=" + pkeyId;
-        List<Map<String, Object>> dataIn = jdbcTemplate.queryForList(querySql);
-
-        // 匹配关联
-        try {
-            File file1 = ResourceUtil.getFile(wbsTreeContract.getHtmlUrl());
-            if (file1.exists()) {
-
-                String htmlString = IoUtil.readToString(new FileInputStream(file1));
-                Document doc = Jsoup.parse(htmlString);
-
-                // 解析
-                // 模糊匹配
-                Elements dwtitle = doc.select("el-input[placeholder~=.*承包单位]");
-                Elements sgtitle = doc.select("el-input[placeholder~=^施工单位]");
-                Elements sgtitle1 = doc.select("el-input[placeholder=安装单位]");
-                sgtitle.addAll(sgtitle1);
-
-                Elements htdtitle = doc.select("el-input[placeholder~=.*合同段.*]");
-                Elements htdtitle1 = doc.select("el-input[placeholder~=合同名称.*]");
-                htdtitle.addAll(htdtitle1);
-
-                Elements jltitle = doc.select("el-input[placeholder~=监理单位.*]");
-
-                Elements bhtitle = doc.select("el-input[placeholder~=^编号]");
-                Elements bhtitle1 = doc.select("el-input[placeholder~=合同编号.*]");
-                bhtitle.addAll(bhtitle1);
-
-
-                Elements xmtitle = doc.select("el-input[placeholder~=^项目名称]");
-
-
-                // Elements title = doc.select("el-input[placeholder~=^编号]");
-
-                /**
-                 * 承包单位 承包单位、施工单位:引用施工单位名称 ,
-                 * 监理单位:引用监理单位名称
-                 * 合同段、所属建设项目(合同段):引用合同段编号
-                 *
-                 * 施工单位:施工单位 和 安装单位
-                 *
-                 */
-                ContractInfo contractInfo = contractInfoService.getById(wbsTreeContract.getContractId());
-                // 施工单位名称
-                if (dwtitle.size() >= 1) {
-                    int y = Integer.parseInt(dwtitle.attr("trindex"));
-                    if (y <= 10) {
-                        reData.put(dwtitle.attr("keyName"), contractInfo.getConstructionUnitName());
-                    }
-
-                }
-                if (sgtitle.size() >= 1) {
-                    int y = Integer.parseInt(sgtitle.attr("trindex"));
-                    if (y <= 10) {
-                        reData.put(sgtitle.attr("keyName"), contractInfo.getConstructionUnitName());
-                    }
-                }
-
-                // 合同段名称
-                if (htdtitle.size() >= 1) {
-                    for (Element element : htdtitle) {
-                        int trindex = Integer.parseInt(element.attr("trindex"));
-                        if (trindex <= 8) {
-                            reData.put(element.attr("keyName"), contractInfo.getContractNumber());
-                        }
-                    }
-                }
-                // 监理单位名称
-                if (jltitle.size() >= 1) {
-
-                    for (Element element : jltitle) {
-                        int trindex = Integer.parseInt(element.attr("trindex"));
-                        if (trindex <= 10) {
-                            reData.put(element.attr("keyName"), contractInfo.getSupervisionUnitName());
-                        }
-                    }
-                }
-                //获取父节点划分编号
-                WbsTreeContract node = wbsTreeContractService.getBaseMapper().selectOne(Wrappers.<WbsTreeContract>query().lambda()
-                        .eq(WbsTreeContract::getId, wbsTreeContract.getParentId())
-                        .eq(WbsTreeContract::getContractId, wbsTreeContract.getContractId()));
-                // 编号
-                if (bhtitle.size() >= 1 && contractInfo.getIsReferenceNumber() == 1) {
-                    for (Element element : bhtitle) {
-                        int trindex = Integer.parseInt(element.attr("trindex"));
-                        if (trindex <= 10) {
-                            reData.put(element.attr("keyName"), node.getPartitionCode() == null ? "" : node.getPartitionCode());
-                        }
-                    }
-                }
-
-                // 项目名称
-                if (xmtitle.size() >= 1) {
-                    for (Element element : xmtitle) {
-                        int trindex = Integer.parseInt(element.attr("trindex"));
-                        if (trindex <= 6) {
-                            ProjectInfo projectInfo = projectInfoService.getById(wbsTreeContract.getProjectId());
-                            reData.put(element.attr("keyName"), projectInfo.getProjectName());
-                        }
-                    }
-                }
-            }
-        } catch (FileNotFoundException e) {
-            e.printStackTrace();
-        }
 
-        if (dataIn.size() >= 1) {
-            Map<String, Object> mysqlData = dataIn.get(0);
-            for (String key : mysqlData.keySet()) {
-                String tabVal = mysqlData.get(key) + "";
-                // 时间段处理
-                if (org.apache.commons.lang.StringUtils.isNotEmpty(tabVal) && tabVal.indexOf("null") < 0) {
-                    if (tabVal.contains("T") && tabVal.contains(".000Z]")) {
-                        String[] tabData = tabVal.split("_\\^_");
-
-                        if (reData.containsKey("pickerKey")) {
-                            String pickerKey = reData.get("pickerKey") + "," + key + "__" + tabData[1];
-                            reData.put("pickerKey", pickerKey);
-                        } else {
-                            reData.put("pickerKey", key + "__" + tabData[1]);
-                        }
-
-                        String sql = tabData[0];
-                        sql = sql.replaceAll("\\[", "['");
-                        sql = sql.replaceAll("]", "']");
-                        sql = sql.replaceAll("000Z,", "000Z',");
-                        sql = sql.replaceAll(", 20", ", '20");
-                        //   sql = sql.replaceAll("'", "");
-                        if (org.apache.commons.lang.StringUtils.isNotEmpty(tabData[0])) {
-                            reData.put(key + "__" + tabData[1], sql);
-                        }
-                    } else if (tabVal.contains("T") && tabVal.contains(".000Z")) { //时间
-                        // 时间和字符串合作
-                        if (tabVal.contains("☆")) {
-                            String[] mysql = tabVal.split("☆");
-                            for (String data : mysql) {
-                                String[] tabData = data.split("_\\^_");
-                                if (org.apache.commons.lang.StringUtils.isNotEmpty(tabData[0])) {
-                                    reData.put(key + "__" + tabData[1], tabData[0]);
-                                }
-                            }
-                        } else {
-                            String[] tabData = tabVal.split("_\\^_");
-                            if (org.apache.commons.lang.StringUtils.isNotEmpty(tabData[0])) {
-                                reData.put(key + "__" + tabData[1], tabData[0]);
-                            }
-                        }
-                    } else if (tabVal.contains("☆")) {
-                        String[] mysql = tabVal.split("☆");
-                        for (String data : mysql) {
-                            String[] tabData = data.split("_\\^_");
-                            if (org.apache.commons.lang.StringUtils.isNotEmpty(tabData[0])) {
-                                reData.put(key + "__" + tabData[1], tabData[0]);
-                            }
-                        }
-                    } else if (tabVal.contains("_^_")) {
-                        String[] tabData = tabVal.split("_\\^_");
-                        if (org.apache.commons.lang.StringUtils.isNotEmpty(tabData[0])) {
-                            if (tabVal.contains("[") && tabVal.contains("年")) {
-                                String[] strings = org.apache.commons.lang.StringUtils.strip(tabData[0], "[]").split(",");
-
-                                reData.put(key + "__" + tabData[1], strings);
-                            } else {
-                                reData.put(key + "__" + tabData[1], tabData[0]);
-                            }
-                        }
-                    } else {
-                        reData.put(key, tabVal);
-                    }
-                }
-            }
-        }
-
-        // 获取默认值
-        QueryWrapper<TextdictInfo> queryWrapper = new QueryWrapper<>();
-        queryWrapper.eq("type", 4);
-        queryWrapper.eq("tab_id", wbsTreeContract.getIsTypePrivatePid());
-        final List<TextdictInfo> textdictInfos = textDictInfoService.getBaseMapper().selectList(queryWrapper);
-        if (!textdictInfos.isEmpty()) {
-            for (TextdictInfo textdictInfo : textdictInfos) {
-                if (reData.containsKey(textdictInfo.getColKey())) {
-                    String keyVal = reData.get(textdictInfo.getColKey()) + "";
-                } else {
-                    reData.put(textdictInfo.getColKey() + "", textdictInfo.getSigRoleName());
-                }
-            }
-        }
-
-        // 移除Id 和 p_key_id
-        if (type == 0) {
-            reData.remove("id");
-            reData.remove("p_key_id");
-            reData.remove("classify");
-            reData.remove("contractId");
-            reData.remove("pkeyId");
-            reData.remove("projectId");
-        }
-        if (type == 1) {
-            reData.put("pkeyId", reData.get("p_key_id"));
-        }
-        reData.put("tabGroupId", wbsTreeContract.getTabGroupId());
-        return R.data(reData);
-    }
 
 }
 

+ 20 - 23
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsParamServiceImpl.java

@@ -45,39 +45,36 @@ public class WbsParamServiceImpl extends BaseServiceImpl<WbsParamMapper, WbsPara
      */
     public static final String FILE_TITLE = "FILE_TITLE";
 
+
+
     @Override
-    @Cacheable(cacheNames = "file_title", key = "#wbsTreeContract.pKeyId+'@'+T(System).currentTimeMillis()/(1000*100)")
-    public String createFileTitle(Long nodeId, Long contractId, WbsTreeContract wbsTreeContract) {
-        if (BaseUtils.isNotNull(nodeId, contractId)) {
-            StaticLog.info("获取节点{}文件题名", nodeId);
-            List<WbsTreeContract> nodes = tracing(wbsTreeContract.getPKeyId());
+    @Cacheable(cacheNames = "file_title", key = "#wtc.pKeyId+'@'+T(System).currentTimeMillis()/(1000*100)")
+    public String createFileTitle(WbsTreeContract wtc) {
+        if(wtc!=null&&wtc.getPKeyId()!=null){
+            List<WbsTreeContract> nodes = tracing(wtc.getPKeyId());
             if (Func.isNotEmpty(nodes)) {
-                /*优先取私有*/
-                WbsParam wp = this.getOne(Wrappers.<WbsParam>lambdaQuery().eq(WbsParam::getNodeId, wbsTreeContract.getPKeyId()).eq(WbsParam::getK, FILE_TITLE).last(" limit 1"));
-                if (wp == null) {
-                    wp = this.getOne(Wrappers.<WbsParam>lambdaQuery().eq(WbsParam::getNodeId, nodeId).eq(WbsParam::getK, FILE_TITLE).last(" limit 1 "));
-                }
-                if (Func.isNotEmpty(wp)) {
-                    return CustomFunction.tree(nodes.stream().map(w->StringUtils.isNotEmpty(w.getFullName())?w.getFullName():w.getNodeName()).collect(Collectors.toList()), wp.getV()).toString();
+                WbsTreePrivate wtp = this.formulaService.wtpId(wtc.getPKeyId());
+                if(wtp!=null){
+                    /*优先取私有*/
+                    WbsParam wp = this.getOne(Wrappers.<WbsParam>lambdaQuery().eq(WbsParam::getNodeId, wtp.getPKeyId()).eq(WbsParam::getK, FILE_TITLE).last(" limit 1"));
+                    if (wp == null) {
+                        WbsTreePrivate publicWtp = this.formulaService.getOriginWtp(wtp.getPKeyId());
+                        wp = this.getOne(Wrappers.<WbsParam>lambdaQuery().eq(WbsParam::getNodeId, publicWtp.getId()).eq(WbsParam::getK, FILE_TITLE).last(" limit 1 "));
+                    }
+                    if (Func.isNotEmpty(wp)) {
+                        return CustomFunction.tree(nodes.stream().map(w->StringUtils.isNotEmpty(w.getFullName())?w.getFullName():w.getNodeName()).collect(Collectors.toList()), wp.getV()).toString();
+                    }
                 }
+
             }
         }
         return NOT_SET;
     }
 
-    @Override
-    public String createFileTitle(Long id, Long contractId) {
-        return NOT_SET;
-    }
-
-    @Override
-    public String createFileTitle(WbsTreeContract wbsTreeContract) {
-        return NOT_SET;
-    }
-
     @Override
     public String createFileTitle(Long pkeyId) {
-        return NOT_SET;
+        WbsTreeContract wtc =this.treeContractService.getOne(Wrappers.<WbsTreeContract>lambdaQuery().eq(WbsTreeContract::getPKeyId,pkeyId));
+        return createFileTitle(wtc);
     }
 
     @Override

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

@@ -384,6 +384,7 @@ public class WbsTreePrivateServiceImpl extends BaseServiceImpl<WbsTreePrivateMap
             updateWrapper1
                     .eq(WbsTreePrivate::getPKeyId, pKeyId)
                     .set(WbsTreePrivate::getStatus, wbsTreePrivate.getStatus());
+            Integer statusPrivate = wbsTreePrivate.getStatus();
             baseMapper.update(null, updateWrapper1);
 
             //修改当前项目下所有合同段的该表状态
@@ -394,11 +395,10 @@ public class WbsTreePrivateServiceImpl extends BaseServiceImpl<WbsTreePrivateMap
             );
             if (wbsTreeContracts.size() > 0) {
                 for (WbsTreeContract wbsTreeContract : wbsTreeContracts) {
-                    wbsTreeContract.setStatus(wbsTreeContract.getStatus() == 1 ? 0 : 1);
                     LambdaUpdateWrapper<WbsTreeContract> updateWrapper2 = new LambdaUpdateWrapper<>();
                     updateWrapper2
                             .eq(WbsTreeContract::getPKeyId, wbsTreeContract.getPKeyId())
-                            .set(WbsTreeContract::getStatus, wbsTreeContract.getStatus());
+                            .set(WbsTreeContract::getStatus, statusPrivate);
                     wbsTreeContractMapper.update(null, updateWrapper2);
                 }
             }

+ 0 - 71
blade-service/blade-manager/src/main/java/org/springblade/manager/utils/ExcelInfoUtils.java

@@ -9,13 +9,11 @@ import org.apache.commons.lang.StringUtils;
 import org.apache.poi.ss.usermodel.Cell;
 import org.apache.poi.ss.usermodel.Row;
 import org.apache.poi.ss.usermodel.Sheet;
-import org.apache.poi.ss.usermodel.WorkbookFactory;
 import org.jsoup.Jsoup;
 import org.jsoup.nodes.Document;
 import org.jsoup.nodes.Element;
 import org.jsoup.select.Elements;
 
-import org.springblade.common.utils.CommonUtil;
 import org.springblade.common.utils.SnowFlakeUtil;
 import org.springblade.core.tool.utils.FileUtil;
 import org.springblade.core.tool.utils.Func;
@@ -33,75 +31,6 @@ import java.util.Map;
 
 public class ExcelInfoUtils {
 
-    public static void main1234(String[] args) throws Exception {
-        String fileUrl = "/Users/hongchuangyanfa/Downloads/29ed5438d62d301bf290b908acf3bdbb.xlsx";
-        InputStream exceInp = new FileInputStream(new File(fileUrl));
-
-        org.apache.poi.ss.usermodel.Workbook workbook = WorkbookFactory.create(exceInp);
-
-        //获取工作表
-        Sheet sheet = workbook.getSheetAt(0);
-        sheet.setForceFormulaRecalculation(true);
-
-        Row row = sheet.getRow(34);
-
-        Cell cell = sheet.getRow(34).getCell(1);
-
-        System.out.println(cell.getStringCellValue());
-        // 解析原始excel
-        Workbook wb = new Workbook();
-        wb.loadFromMHtml(fileUrl);
-        Worksheet sheet2 = wb.getWorksheets().get(0);
-
-        CellRange cellRange = sheet2.getCellRange(35, 2);
-        System.out.println(cellRange.getText());
-
-        //sheet.saveToHtml("/Users/hongchuangyanfa/Desktop/pdf/test.html");
-    }
-
-    public static void main123(String[] args) throws FileNotFoundException {
-        String excelUrl = "/Users/hongchuangyanfa/Downloads/C10.28隧道注浆施工记录表(1).xlsx";
-        String old_html = "/Users/hongchuangyanfa/Desktop/pdf/old_html.html";
-        String old_xlsx = "/Users/hongchuangyanfa/Desktop/pdf/old_html.xlsx";
-        File file = new File(excelUrl);
-        InputStream fileInputStream = new FileInputStream(file);
-      //  excelInfo(fileInputStream,old_xlsx,old_html,"1");
-
-
-        // 解析原始excel
-        Workbook wb = new Workbook();
-        wb.loadFromMHtml(excelUrl);
-        Worksheet sheet = wb.getWorksheets().get(0);
-
-        CellRange[] mergedCells = sheet.getCells();
-        for(int i=0;i<mergedCells.length;i++){
-            CellRange oldcell =mergedCells[i];
-           // sheet.get(oldcell.getRow(),oldcell.getColumn()).getDataValidation().setErrorMessage("");
-          //  sheet.get(oldcell.getRow(),oldcell.getColumn(),oldcell.getLastRow(),oldcell.getLastColumn()).getDataValidation().setErrorMessage("");
-            oldcell.getDataValidation().setErrorMessage("");
-        }
-
-
-        CellRange[] mergedCells1 = sheet.getMergedCells();
-        for(int i=0;i<mergedCells1.length;i++) {
-            CellRange oldcell = mergedCells1[i];
-            oldcell.getDataValidation().setErrorMessage(i+"");
-        }
-
-
-
-        CellRange[] cells = sheet.getCells();
-        for(int i=0;i< cells.length;i++){
-            CellRange oldcell = cells[i];
-            System.out.println(oldcell.getRow()+"---"+oldcell.getColumn()+"---="+oldcell.getText()+"---x="+oldcell.getDataValidation().getErrorMessage());
-        }
-
-
-
-        String new_html = "/Users/hongchuangyanfa/Desktop/pdf/new_html.html";
-        String new_xlsx = "/Users/hongchuangyanfa/Desktop/pdf/new_html.xlsx";
-       // excelInfo(old_xlsx,new_xlsx,new_html);
-    }
 
     public static void excelInfo(InputStream inputStream, String excelURL, String htmlUrl,String type) {
         try {

+ 271 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/utils/ExcelInfoUtils2.java

@@ -0,0 +1,271 @@
+package org.springblade.manager.utils;
+
+import com.spire.pdf.PdfDocument;
+import com.spire.pdf.utilities.PdfTable;
+import com.spire.pdf.utilities.PdfTableExtractor;
+import com.spire.xls.CellRange;
+import com.spire.xls.FileFormat;
+import com.spire.xls.Workbook;
+import com.spire.xls.Worksheet;
+import com.spire.xls.core.spreadsheet.HTMLOptions;
+import org.apache.commons.lang.StringUtils;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.usermodel.WorkbookFactory;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+import org.jsoup.select.Elements;
+import org.springblade.common.utils.CommonUtil;
+import org.springblade.common.utils.SnowFlakeUtil;
+import org.springblade.core.tool.utils.FileUtil;
+import org.springblade.core.tool.utils.Func;
+import org.springblade.core.tool.utils.IoUtil;
+import org.springblade.manager.vo.DateFormat;
+
+import java.io.*;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class ExcelInfoUtils2 {
+
+
+    public static void excelInfo(InputStream inputStream, String excelURL, String htmlUrl,String type) {
+        try {
+            String file_path = "/Users/hongchuangyanfa/Desktop//pdf/";
+            String filecode = SnowFlakeUtil.getId() + "";
+            String thmlUrl2 = file_path + filecode + "123.html";
+
+            // 解析原始excel
+            Workbook wb = new Workbook();
+            wb.loadFromMHtml(inputStream);
+            Worksheet sheet = wb.getWorksheets().get(0);
+
+            HTMLOptions options = new HTMLOptions();
+            options.setImageEmbedded(true);
+
+            //复制一份
+            wb.saveToFile(excelURL,FileFormat.Version2013);
+            // 操作
+            Workbook wb2 = new Workbook();
+            wb2.loadFromMHtml(excelURL);
+            Worksheet sheet2 = wb2.getWorksheets().get(0);
+
+            // 坐标map
+            Map<String, Map<String, Integer>> xyList = new HashMap<>();
+            int j = 0;
+            int maxVal = 0;
+            if(type.equals("2")){
+                CellRange[] sheet2Cells = sheet2.getCells();
+                for (int i = 0; i < sheet2Cells.length; i++) {
+                    CellRange oldcell = sheet2Cells[i];
+                    String data = oldcell.getDataValidation().getErrorMessage();
+                    int k = 0;
+                    if(Func.isNumeric(data)){
+                        k = Func.toInt(data);
+                    }
+                    if (maxVal < k) {
+                        maxVal = k;
+                    }
+                }
+            }else if(type.equals("1")){
+                CellRange[] sheet2Cells = sheet.getCells();
+                for (int i = 0; i < sheet2Cells.length; i++) {
+                    CellRange oldcell = sheet2Cells[i];
+                    oldcell.getDataValidation().setErrorMessage("");
+                    sheet.get(oldcell.getRow(),oldcell.getColumn()).getDataValidation().setErrorMessage("");
+                }
+            }
+
+            //合并单元格操作
+            CellRange[] mergedCells = sheet.getMergedCells();
+            for (int i = 0; i < mergedCells.length; i++) {
+                Map<String, Integer> dataMap = new HashMap<>();
+                CellRange oldcell = mergedCells[i];
+                CellRange mergedCell = sheet.getCellRange(oldcell.getRow(), oldcell.getColumn());
+                if(type.equals("2")){
+                    String data = mergedCell.getDataValidation().getErrorMessage();
+                    if (StringUtils.isEmpty(data)) {
+                        if(maxVal<=0){
+                            j = j + 1;
+                        }else{
+                            maxVal = maxVal+1;
+                            j=maxVal;
+                        }
+                    } else {
+                        j = Func.toInt(data);
+                    }
+                }else{
+                    j = j + 1;
+                }
+                // 目标表添加备注信息
+                mergedCell.getDataValidation().setErrorMessage(j+"");
+                oldcell.getDataValidation().setErrorMessage(j+"");
+                sheet2.getMergedCells()[i].setText(j+"");
+                dataMap.put("y1", oldcell.getRow());
+                dataMap.put("y2", oldcell.getLastRow());
+                dataMap.put("x1", oldcell.getColumn());
+                dataMap.put("x2", oldcell.getLastColumn());
+                xyList.put(j + "", dataMap);
+            }
+
+            //变更最大值
+            if(maxVal<=0){
+                maxVal = j;
+            }
+
+            // 单个
+            CellRange[] onCell = sheet.getCells();
+            // 单个cell
+            for (int i = 0; i < onCell.length; i++) {
+                CellRange oldcell = onCell[i];
+                String data = oldcell.getDataValidation().getErrorMessage();
+                System.out.println(oldcell.getRow()+"---"+oldcell.getColumn()+"---="+oldcell.getText()+"---x="+data);
+                if (StringUtils.isEmpty(data)) {
+                    if(maxVal<=0){
+                        j = j + 1;
+                    }else{
+                        maxVal = maxVal+1;
+                        j=maxVal;
+                    }
+                } else {
+                    j = Func.toInt(data);
+                }
+
+              /*  if(StringUtils.isEmpty(data)){
+                    oldcell.getDataValidation().setErrorMessage(j+"");
+                    sheet2.getCells()[i].setText(j+"");
+                }*/
+
+                if(!xyList.containsKey(j+"")){
+                    Map<String, Integer> dataMap = new HashMap<>();
+                    dataMap.put("y1", oldcell.getRow());
+                    dataMap.put("y2", oldcell.getLastRow());
+                    dataMap.put("x1", oldcell.getColumn());
+                    dataMap.put("x2", oldcell.getLastColumn());
+                    xyList.put(j + "", dataMap);
+                }
+            }
+
+            // 保存上传的excel
+            wb.saveToFile(excelURL,FileFormat.Version2013);
+           // sheet.saveToHtml(htmlUrl, options);
+            sheet2.saveToHtml(thmlUrl2);
+
+            // html 转换值
+
+            // 组装坐标
+            File html1 = new File(htmlUrl);  // 原始html
+            File html2 = new File(thmlUrl2); // 坐标html
+            InputStream inputStream1 = new FileInputStream(html1);
+            InputStream inputStream2 = new FileInputStream(html2);
+            String htmlString1 = IoUtil.readToString(inputStream1);
+            String htmlString2 = IoUtil.readToString(inputStream2);
+
+            Document doc1 = Jsoup.parse(htmlString1);
+            Element table1 = doc1.select("table").first();
+            Elements trs1 = table1.select("tr");
+            Document doc2 = Jsoup.parse(htmlString2);
+            Element table2 = doc2.select("table").first();
+            Elements trs2 = table2.select("tr");
+
+            for (int i = 0; i < trs1.size(); i++) {
+                Elements td1 = trs1.get(i).select("td");
+                Elements td2 = trs2.get(i).select("td");
+                for (int x = 0; x < td1.size(); x++) {
+                    Element cell1 = td1.get(x);
+                    Element cell2 = td2.get(x);
+                    String html = cell2.text();
+                    Map<String, Integer> xyMap = xyList.get(html);
+                    if (xyMap != null) {
+                        // td 添加坐标
+                        cell1.attr("x1", xyMap.get("x1") + "");
+                        cell1.attr("x2", xyMap.get("x2") + "");
+                        cell1.attr("y1", xyMap.get("y1") + "");
+                        cell1.attr("y2", xyMap.get("y2") + "");
+                        cell1.attr("exceVal",html);
+
+
+                        // 为下面对象添加坐标
+                        if(cell1.children().size()>=1){
+                            Element element = cell1.children().get(0);
+                            if(element.hasAttr("x1") && element.hasAttr("y1")){
+                                element.removeAttr("x1");
+                                element.removeAttr("x2");
+                                element.removeAttr("y1");
+                                element.removeAttr("y2");
+                                element.attr("x1", xyMap.get("x1") + "");
+                                element.attr("x2", xyMap.get("x2") + "");
+                                element.attr("y1", xyMap.get("y1") + "");
+                                element.attr("y2", xyMap.get("y2") + "");
+                            }else{
+                                if(element.children().size()>=1){
+                                    Element element2 = element.children().get(0);
+                                    if(element2.hasAttr("x1") && element2.hasAttr("y1")){
+                                        element2.removeAttr("x1");
+                                        element2.removeAttr("x2");
+                                        element2.removeAttr("y1");
+                                        element2.removeAttr("y2");
+                                        element2.attr("x1", xyMap.get("x1") + "");
+                                        element2.attr("x2", xyMap.get("x2") + "");
+                                        element2.attr("y1", xyMap.get("y1") + "");
+                                        element2.attr("y2", xyMap.get("y2") + "");
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+
+            FileUtil.writeToFile(html1, doc1.html(), Boolean.parseBoolean("UTF-8"));
+
+            if (html2.exists()) {
+                html2.delete();
+            }
+            wb2.dispose();
+            wb.dispose();
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+    }
+
+    public static void main123(String[] args) throws Exception {
+
+       /* String html="/Users/hongchuangyanfa/Desktop/privateUrl/1701131518073634816.html";
+        File html1 = new File(html);  // 原始html
+        InputStream inputStream1 = new FileInputStream(html1);
+
+        String htmlString1 = IoUtil.readToString(inputStream1);
+        Document doc1 = Jsoup.parse(htmlString1);
+        Element table1 = doc1.select("table").first();
+        Elements dqids = table1.getElementsByAttribute("dqid");
+        int x1=0;
+        int y1=0;
+        for (Element element : dqids){
+            if(element.hasAttr("x1") && element.hasAttr("y1")){
+                Elements x11 = element.getElementsByAttribute("x1");
+                Element element1 = x11.get(x11.size()-1);
+                x1 = Func.toInt(element1.attr("x1"));
+                y1 = Func.toInt(element1.attr("y1"));
+            }
+        }*/
+        String excelPath="/Users/hongchuangyanfa/Desktop/pdf/1234567.xlsx";
+        String data="https://bladex-chongqing-info.oss-cn-hangzhou.aliyuncs.com//upload/20230911/b63658909c268efeb753dcf673ce34ab.xlsx";
+        InputStream exceInp = CommonUtil.getOSSInputStream(data);
+        org.apache.poi.ss.usermodel.Workbook workbook = WorkbookFactory.create(exceInp);
+
+        //获取工作表
+        Sheet sheet = workbook.getSheetAt(0);
+        Row row = sheet.getRow(7-1);
+        Cell cell = row.getCell(5-1);
+        cell.setCellValue("123444");
+
+        FileOutputStream outputStream = new FileOutputStream(excelPath);
+        workbook.write(outputStream);
+    }
+
+}

+ 45 - 13
blade-service/blade-system/src/main/java/org/springblade/system/controller/MenuController.java

@@ -231,6 +231,9 @@ public class MenuController extends BladeController {
         List<TreeNodeVO> treeMenuArchives = new ArrayList<>(); //档案
         List<TreeNodeVO> treeMenuHac = new ArrayList<>(); //内控系统
         List<TreeNodeVO> treeMenuLar = new ArrayList<>(); //征拆系统
+        List<TreeNodeVO> treeMenuMeasure = new ArrayList<>(); //计量
+        List<TreeNodeVO> treeMenuSecure = new ArrayList<>(); //安全
+
         //获取所有菜单
         List<TreeNodeVO> treeNodesAll = menuService.grantTree(user);
         //获取AuthClient
@@ -258,17 +261,29 @@ public class MenuController extends BladeController {
                         }
                     }
                     if (("hac").equals(authClient.getClientId())) {
-                        //档案
+                        //内控
                         if (treeNode.getSysId().equals(authClient.getId())) {
                             treeMenuHac.add(treeNode);
                         }
                     }
                     if (("lar").equals(authClient.getClientId())) {
-                        //档案
+                        //征拆
                         if (treeNode.getSysId().equals(authClient.getId())) {
                             treeMenuLar.add(treeNode);
                         }
                     }
+                    if (("measure").equals(authClient.getClientId())) {
+                        //计量
+                        if (treeNode.getSysId().equals(authClient.getId())) {
+                            treeMenuMeasure.add(treeNode);
+                        }
+                    }
+                    if (("secure").equals(authClient.getClientId())) {
+                        //安全
+                        if (treeNode.getSysId().equals(authClient.getId())) {
+                            treeMenuSecure.add(treeNode);
+                        }
+                    }
                     //TODO 其他菜单权限
                 }
             }
@@ -291,6 +306,10 @@ public class MenuController extends BladeController {
         //表单
         List<DictVO02> ownerType = dictService.getList2("owner_type");
         vo.setTableOwners(ownerType);
+        //计量
+        vo.setMeasureMenu(treeMenuMeasure);
+        //安全
+        vo.setSecureMenu(treeMenuSecure);
 
         return R.data(vo);
     }
@@ -309,25 +328,38 @@ public class MenuController extends BladeController {
         //客户端
         vo.setUsermenu(menuService.roleTreeKeys(roleIds));
 
+        //表单
+        List<WbsTableOwnerRole> wbsTableOwnerRoles = roleMapper.selectRoleAndTableOwnerListByRoleId(Long.valueOf(roleIds));
+        List<String> collect = wbsTableOwnerRoles.stream().map(WbsTableOwnerRole::getTableOwnerNumber).collect(Collectors.toList());
+        vo.setTableOwners(collect);
+
         //档案
         vo.setArchivesMenu(menuService.roleTreeKeys(roleIds));
 
-        //数据源
-        vo.setDataScope(menuService.dataScopeTreeKeys(roleIds));
+        //内控系统
+        vo.setHacMenu(menuService.roleTreeKeys(roleIds));
 
-        //接口
-        vo.setApiScope(menuService.apiScopeTreeKeys(roleIds));
+        //征拆系统
+        vo.setLarMenu(menuService.roleTreeKeys(roleIds));
 
-        // 内控系统
-        vo.setHacMenu(menuService.apiScopeTreeKeys(roleIds));
+        //计量系统
+        vo.setMeasureMenu(menuService.roleTreeKeys(roleIds));
+
+        //安全系统
+        vo.setSecureMenu(menuService.roleTreeKeys(roleIds));
 
+        /*不清楚为什么其他开发要用menuService.apiScopeTreeKeys(roleIds)
+         * 现在把内控、征拆改为menuService.roleTreeKeys(roleIds)*/
+        /*//内控系统
+        vo.setHacMenu(menuService.apiScopeTreeKeys(roleIds));
         //征拆系统
-        vo.setLarMenu(menuService.apiScopeTreeKeys(roleIds));
+        vo.setLarMenu(menuService.apiScopeTreeKeys(roleIds));*/
 
-        //表单
-        List<WbsTableOwnerRole> wbsTableOwnerRoles = roleMapper.selectRoleAndTableOwnerListByRoleId(Long.valueOf(roleIds));
-        List<String> collect = wbsTableOwnerRoles.stream().map(WbsTableOwnerRole::getTableOwnerNumber).collect(Collectors.toList());
-        vo.setTableOwners(collect);
+        /*暂时没有使用到下面的数据源、接口菜单*/
+        /*//数据源
+        vo.setDataScope(menuService.dataScopeTreeKeys(roleIds));
+        //接口
+        vo.setApiScope(menuService.apiScopeTreeKeys(roleIds));*/
 
         return R.data(vo);
     }

+ 7 - 1
blade-service/blade-system/src/main/java/org/springblade/system/controller/RoleController.java

@@ -187,7 +187,13 @@ public class RoleController extends BladeController {
     public R grant(@RequestBody GrantVO grantVO) {
         CacheUtil.clear(SYS_CACHE);
         CacheUtil.clear(SYS_CACHE, Boolean.FALSE);
-        boolean temp = roleService.grant(grantVO.getRoleIds(), grantVO.getMenuIds(), grantVO.getMenuClientIds(), grantVO.getDataScopeIds(), grantVO.getApiScopeIds(), grantVO.getTableOwners(), grantVO.getMenuArchivesIds(), grantVO.getMenuHacIds(), grantVO.getMenularIds());
+        boolean temp = roleService.grant(grantVO.getRoleIds()
+                , grantVO.getMenuIds(), grantVO.getMenuClientIds()
+                , grantVO.getDataScopeIds(), grantVO.getApiScopeIds()
+                , grantVO.getTableOwners(), grantVO.getMenuArchivesIds()
+                , grantVO.getMenuHacIds(), grantVO.getMenularIds()
+                , grantVO.getMenuMeasureIds(), grantVO.getMenuSecureIds()
+        );
         return R.status(temp);
     }
 

+ 18 - 8
blade-service/blade-system/src/main/java/org/springblade/system/service/IRoleService.java

@@ -56,15 +56,25 @@ public interface IRoleService extends IService<Role> {
     /**
      * 权限配置
      *
-     * @param roleIds       角色id集合
-     * @param menuIds       菜单id集合
-     * @param menuClientIds 客户端菜单id集合
-     * @param tableOwners   表单id集合
-     * @param dataScopeIds  数据权限id集合
-     * @param apiScopeIds   接口权限id集合
-     * @return 是否成功
+     * @param roleIds
+     * @param menuIds
+     * @param menuClientIds
+     * @param dataScopeIds
+     * @param apiScopeIds
+     * @param tableOwners
+     * @param menuArchivesIds
+     * @param menuHacIds
+     * @param menuLarIds
+     * @param menuMeasureIds
+     * @param menuSecureIds
+     * @return
      */
-    boolean grant(@NotEmpty List<Long> roleIds, List<String> menuIds, List<String> menuClientIds, List<Long> dataScopeIds, List<Long> apiScopeIds, List<Long> tableOwners, List<String> menuArchivesIds, List<String> menuHacIds, List<String> menuLarIds);
+    boolean grant(@NotEmpty List<Long> roleIds, List<String> menuIds, List<String> menuClientIds
+            , List<Long> dataScopeIds, List<Long> apiScopeIds
+            , List<Long> tableOwners, List<String> menuArchivesIds
+            , List<String> menuHacIds, List<String> menuLarIds
+            , List<String> menuMeasureIds, List<String> menuSecureIds
+    );
 
     /**
      * 获取角色ID

+ 47 - 6
blade-service/blade-system/src/main/java/org/springblade/system/service/impl/RoleServiceImpl.java

@@ -87,11 +87,23 @@ public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements IR
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public boolean grant(@NotEmpty List<Long> roleIds, List<String> menuIds, List<String> menuClientIds, List<Long> dataScopeIds, List<Long> apiScopeIds, List<Long> tableOwners, List<String> menuArchivesIds, List<String> menuHacIds, List<String> menuLarIds) {
-        return grantRoleMenu(roleIds, menuIds, menuClientIds, menuArchivesIds, menuHacIds, menuLarIds) && grantDataScope(roleIds, dataScopeIds) && grantApiScope(roleIds, apiScopeIds) && submitRoleAndTableOwner(roleIds, tableOwners);
+    public boolean grant(@NotEmpty List<Long> roleIds, List<String> menuIds, List<String> menuClientIds
+            , List<Long> dataScopeIds, List<Long> apiScopeIds
+            , List<Long> tableOwners, List<String> menuArchivesIds
+            , List<String> menuHacIds, List<String> menuLarIds
+            , List<String> menuMeasureIds, List<String> menuSecureIds) {
+
+        return grantRoleMenu(roleIds, menuIds, menuClientIds, menuArchivesIds, menuHacIds, menuLarIds, menuMeasureIds, menuSecureIds)
+                && grantDataScope(roleIds, dataScopeIds)
+                && grantApiScope(roleIds, apiScopeIds)
+                && submitRoleAndTableOwner(roleIds, tableOwners);
     }
 
-    private boolean grantRoleMenu(List<Long> roleIds, List<String> menuIds, List<String> menuClientIds, List<String> menuArchivesIds, List<String> menuHacIds, List<String> menuLarIds) {
+    private boolean grantRoleMenu(List<Long> roleIds
+            , List<String> menuIds, List<String> menuClientIds, List<String> menuArchivesIds
+            , List<String> menuHacIds, List<String> menuLarIds
+            , List<String> menuMeasureIds, List<String> menuSecureIds
+    ) {
         // 防止越权配置超管角色
         Long administratorCount = baseMapper.selectCount(Wrappers.<Role>query().lambda().eq(Role::getRoleAlias, RoleConstant.ADMINISTRATOR).in(Role::getId, roleIds));
         if (!AuthUtil.isAdministrator() && administratorCount > 0L) {
@@ -156,9 +168,32 @@ public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements IR
                 roleMenus.add(roleMenu);
             }));
         }
+
+        // 组装配置-计量
+        if (menuMeasureIds != null && menuMeasureIds.size() >= 1) {
+            roleIds.forEach(roleId -> menuMeasureIds.forEach(menuIdC -> {
+                RoleMenu roleMenu = new RoleMenu();
+                roleMenu.setRoleId(roleId);
+                roleMenu.setMenuId(Long.valueOf(menuIdC.split("---")[0]));
+                roleMenu.setStatus(menuIdC.split("---")[1]);
+                roleMenus.add(roleMenu);
+            }));
+        }
+
+        // 组装配置-安全
+        if (menuSecureIds != null && menuSecureIds.size() >= 1) {
+            roleIds.forEach(roleId -> menuSecureIds.forEach(menuIdC -> {
+                RoleMenu roleMenu = new RoleMenu();
+                roleMenu.setRoleId(roleId);
+                roleMenu.setMenuId(Long.valueOf(menuIdC.split("---")[0]));
+                roleMenu.setStatus(menuIdC.split("---")[1]);
+                roleMenus.add(roleMenu);
+            }));
+        }
+
         // 新增配置
-        boolean b = roleMenuService.saveBatch(roleMenus);
-        System.out.println("ddd");
+        roleMenuService.saveBatch(roleMenus);
+
         // 递归设置下属角色菜单集合
         if (menuIds != null && menuIds.size() >= 1) {
             recursionRoleMenu(roleIds, menuIds);
@@ -175,6 +210,12 @@ public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements IR
         if (menuLarIds != null && menuLarIds.size() >= 1) {
             recursionRoleMenu(roleIds, menuLarIds); //征拆
         }
+        if (menuMeasureIds != null && menuMeasureIds.size() >= 1) {
+            recursionRoleMenu(roleIds, menuMeasureIds); //计量
+        }
+        if (menuSecureIds != null && menuSecureIds.size() >= 1) {
+            recursionRoleMenu(roleIds, menuSecureIds); //安全
+        }
 
         return true;
     }
@@ -187,7 +228,7 @@ public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements IR
             String id = split[0]; //id
             menuIds.add(Long.valueOf(id));
         }
-        //
+
         for (Long roleId : roleIds) {
             List<Role> roleList = roleMapper.getRoleDeptInfoByParentId(roleId + "");
             roleList.forEach(role -> {