Pārlūkot izejas kodu

工程文件批量认证等

huangjn 3 gadi atpakaļ
vecāks
revīzija
f636d370ce
29 mainītis faili ar 756 papildinājumiem un 128 dzēšanām
  1. 4 21
      .idea/encodings.xml
  2. 1 0
      blade-common/src/main/java/org/springblade/common/constant/EVisaConstant.java
  3. 5 0
      blade-ops-api/blade-resource-api/src/main/java/org/springblade/resource/feign/NewIOSSClient.java
  4. 13 0
      blade-ops/blade-resource/src/main/java/org/springblade/resource/feign/NewIOSSClientImpl.java
  5. 3 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/ArchiveFile.java
  6. 3 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/ContractLog.java
  7. 1 1
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/Task.java
  8. 2 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/ArchiveFileVO.java
  9. 3 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/ContractLogVO.java
  10. 2 1
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/StartTaskVO.java
  11. 0 47
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/WriteBatchTaskVO.java
  12. 7 0
      blade-service-api/blade-e-visa-api/src/main/java/org/springblade/evisa/feign/EVisaClient.java
  13. 22 0
      blade-service-api/blade-e-visa-api/src/main/java/org/springblade/evisa/vo/SealPdfVO.java
  14. 124 0
      blade-service-api/blade-e-visa-api/src/main/java/org/springblade/evisa/vo/SealStrategyVO.java
  15. 61 16
      blade-service/blade-business/src/main/java/org/springblade/business/controller/ArchiveFileController.java
  16. 75 17
      blade-service/blade-business/src/main/java/org/springblade/business/controller/ContractLogController.java
  17. 17 6
      blade-service/blade-business/src/main/java/org/springblade/business/controller/InformationWriteQueryController.java
  18. 1 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/ArchiveFileMapper.xml
  19. 4 1
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/ContractLogMapper.xml
  20. 0 1
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/UserOpinionMapper.xml
  21. 1 1
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/ContractLogServiceImpl.java
  22. 13 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TaskServiceImpl.java
  23. 12 2
      blade-service/blade-business/src/main/java/org/springblade/business/utils/FileUtils.java
  24. 6 0
      blade-service/blade-e-visa/pom.xml
  25. 12 0
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/feign/EVisaClientImpl.java
  26. 5 0
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/service/EVisaService.java
  27. 325 3
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/service/impl/EVisaServiceImpl.java
  28. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/ContractInfoMapper.xml
  29. 33 10
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/SignPfxFileServiceImpl.java

+ 4 - 21
.idea/encodings.xml

@@ -15,12 +15,8 @@
     <file url="file://$PROJECT_DIR$/blade-ops-api" charset="UTF-8" />
     <file url="file://$PROJECT_DIR$/blade-ops-api/blade-flow-api" charset="UTF-8" />
     <file url="file://$PROJECT_DIR$/blade-ops-api/blade-flow-api/src/main/java" charset="UTF-8" />
-    <file url="file://$PROJECT_DIR$/blade-ops-api/blade-flow-api/src/main/resources" charset="UTF-8" />
     <file url="file://$PROJECT_DIR$/blade-ops-api/blade-resource-api" charset="UTF-8" />
     <file url="file://$PROJECT_DIR$/blade-ops-api/blade-resource-api/src/main/java" charset="UTF-8" />
-    <file url="file://$PROJECT_DIR$/blade-ops-api/blade-resource-api/src/main/resources" charset="UTF-8" />
-    <file url="file://$PROJECT_DIR$/blade-ops-api/src/main/java" charset="UTF-8" />
-    <file url="file://$PROJECT_DIR$/blade-ops-api/src/main/resources" charset="UTF-8" />
     <file url="file://$PROJECT_DIR$/blade-ops/blade-admin" charset="UTF-8" />
     <file url="file://$PROJECT_DIR$/blade-ops/blade-admin/src/main/java" charset="UTF-8" />
     <file url="file://$PROJECT_DIR$/blade-ops/blade-admin/src/main/resources" charset="UTF-8" />
@@ -51,45 +47,34 @@
     <file url="file://$PROJECT_DIR$/blade-ops/blade-xxljob-admin/src/main/resources" charset="UTF-8" />
     <file url="file://$PROJECT_DIR$/blade-ops/blade-xxljob/src/main/java" charset="UTF-8" />
     <file url="file://$PROJECT_DIR$/blade-ops/blade-xxljob/src/main/resources" charset="UTF-8" />
-    <file url="file://$PROJECT_DIR$/blade-ops/src/main/java" charset="UTF-8" />
-    <file url="file://$PROJECT_DIR$/blade-ops/src/main/resources" charset="UTF-8" />
     <file url="file://$PROJECT_DIR$/blade-plugin" charset="UTF-8" />
     <file url="file://$PROJECT_DIR$/blade-plugin-api" charset="UTF-8" />
-    <file url="file://$PROJECT_DIR$/blade-plugin-api/src/main/java" charset="UTF-8" />
-    <file url="file://$PROJECT_DIR$/blade-plugin-api/src/main/resources" charset="UTF-8" />
-    <file url="file://$PROJECT_DIR$/blade-plugin/src/main/java" charset="UTF-8" />
-    <file url="file://$PROJECT_DIR$/blade-plugin/src/main/resources" charset="UTF-8" />
     <file url="file://$PROJECT_DIR$/blade-service" charset="UTF-8" />
     <file url="file://$PROJECT_DIR$/blade-service-api" charset="UTF-8" />
     <file url="file://$PROJECT_DIR$/blade-service-api/blade-business-api" charset="UTF-8" />
     <file url="file://$PROJECT_DIR$/blade-service-api/blade-business-api/src/main/java" charset="UTF-8" />
-    <file url="file://$PROJECT_DIR$/blade-service-api/blade-business-api/src/main/resources" charset="UTF-8" />
     <file url="file://$PROJECT_DIR$/blade-service-api/blade-desk-api" charset="UTF-8" />
     <file url="file://$PROJECT_DIR$/blade-service-api/blade-desk-api/src/main/java" charset="UTF-8" />
-    <file url="file://$PROJECT_DIR$/blade-service-api/blade-desk-api/src/main/resources" charset="UTF-8" />
     <file url="file://$PROJECT_DIR$/blade-service-api/blade-dict-api" charset="UTF-8" />
     <file url="file://$PROJECT_DIR$/blade-service-api/blade-dict-api/src/main/java" charset="UTF-8" />
-    <file url="file://$PROJECT_DIR$/blade-service-api/blade-dict-api/src/main/resources" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/blade-service-api/blade-e-visa-api/src/main/java" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/blade-service-api/blade-e-visa-api/src/main/resources" charset="UTF-8" />
     <file url="file://$PROJECT_DIR$/blade-service-api/blade-manager-api" charset="UTF-8" />
     <file url="file://$PROJECT_DIR$/blade-service-api/blade-manager-api/src/main/java" charset="UTF-8" />
-    <file url="file://$PROJECT_DIR$/blade-service-api/blade-manager-api/src/main/resources" charset="UTF-8" />
     <file url="file://$PROJECT_DIR$/blade-service-api/blade-scope-api" charset="UTF-8" />
     <file url="file://$PROJECT_DIR$/blade-service-api/blade-scope-api/src/main/java" charset="UTF-8" />
-    <file url="file://$PROJECT_DIR$/blade-service-api/blade-scope-api/src/main/resources" charset="UTF-8" />
     <file url="file://$PROJECT_DIR$/blade-service-api/blade-system-api" charset="UTF-8" />
     <file url="file://$PROJECT_DIR$/blade-service-api/blade-system-api/src/main/java" charset="UTF-8" />
-    <file url="file://$PROJECT_DIR$/blade-service-api/blade-system-api/src/main/resources" charset="UTF-8" />
     <file url="file://$PROJECT_DIR$/blade-service-api/blade-user-api" charset="UTF-8" />
     <file url="file://$PROJECT_DIR$/blade-service-api/blade-user-api/src/main/java" charset="UTF-8" />
-    <file url="file://$PROJECT_DIR$/blade-service-api/blade-user-api/src/main/resources" charset="UTF-8" />
-    <file url="file://$PROJECT_DIR$/blade-service-api/src/main/java" charset="UTF-8" />
-    <file url="file://$PROJECT_DIR$/blade-service-api/src/main/resources" charset="UTF-8" />
     <file url="file://$PROJECT_DIR$/blade-service/blade-business" charset="UTF-8" />
     <file url="file://$PROJECT_DIR$/blade-service/blade-business/src/main/java" charset="UTF-8" />
     <file url="file://$PROJECT_DIR$/blade-service/blade-business/src/main/resources" charset="UTF-8" />
     <file url="file://$PROJECT_DIR$/blade-service/blade-desk" charset="UTF-8" />
     <file url="file://$PROJECT_DIR$/blade-service/blade-desk/src/main/java" charset="UTF-8" />
     <file url="file://$PROJECT_DIR$/blade-service/blade-desk/src/main/resources" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/blade-service/blade-e-visa/src/main/java" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/blade-service/blade-e-visa/src/main/resources" charset="UTF-8" />
     <file url="file://$PROJECT_DIR$/blade-service/blade-manager" charset="UTF-8" />
     <file url="file://$PROJECT_DIR$/blade-service/blade-manager/src/main/java" charset="UTF-8" />
     <file url="file://$PROJECT_DIR$/blade-service/blade-manager/src/main/resources" charset="UTF-8" />
@@ -101,7 +86,5 @@
     <file url="file://$PROJECT_DIR$/blade-service/blade-user/src/main/resources" charset="UTF-8" />
     <file url="file://$PROJECT_DIR$/blade-service/src/main/java" charset="UTF-8" />
     <file url="file://$PROJECT_DIR$/blade-service/src/main/resources" charset="UTF-8" />
-    <file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
-    <file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
   </component>
 </project>

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1 - 0
blade-common/src/main/java/org/springblade/common/constant/EVisaConstant.java


+ 5 - 0
blade-ops-api/blade-resource-api/src/main/java/org/springblade/resource/feign/NewIOSSClient.java

@@ -4,6 +4,7 @@ import org.springblade.core.launch.constant.AppConstant;
 import org.springblade.core.oss.model.BladeFile;
 import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestParam;
 
 @FeignClient(value = AppConstant.APPLICATION_RESOURCE_NAME)
@@ -11,8 +12,12 @@ public interface NewIOSSClient {
 
     String API_PREFIX = "/newOSSClient";
     String UPLOAD_FILE_INFO = API_PREFIX + "/uploadFileInfo";
+    String UPLOAD_FILE_INFO_BYTE = API_PREFIX + "/uploadFileInfoByte";
 
     @PostMapping(UPLOAD_FILE_INFO)
     BladeFile uploadFile(@RequestParam String fileName, @RequestParam String localFileUrl);
 
+    @PostMapping(UPLOAD_FILE_INFO_BYTE)
+    BladeFile updateFile(@RequestBody byte[] fileByte, @RequestParam String fileName);
+
 }

+ 13 - 0
blade-ops/blade-resource/src/main/java/org/springblade/resource/feign/NewIOSSClientImpl.java

@@ -6,6 +6,7 @@ import org.springblade.core.tenant.annotation.NonDS;
 import org.springblade.resource.builder.oss.OssBuilder;
 import org.springframework.web.bind.annotation.RestController;
 
+import java.io.ByteArrayInputStream;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.InputStream;
@@ -20,6 +21,18 @@ public class NewIOSSClientImpl implements NewIOSSClient {
      */
     private final OssBuilder ossBuilder;
 
+    @Override
+    public BladeFile updateFile(byte[] fileByte, String fileName) {
+        try{
+            //获取文件流
+            InputStream inputStream = new ByteArrayInputStream(fileByte);
+            return this.ossBuilder.template().putFile(fileName, inputStream);
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+        return null;
+    }
+
     @Override
     public BladeFile uploadFile(String fileName, String localFileUrl) {
         try{

+ 3 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/ArchiveFile.java

@@ -110,6 +110,9 @@ public class ArchiveFile extends BaseEntity {
 	@ApiModelProperty("是否已经认证")
 	private Integer isCertification;
 
+	@ApiModelProperty("认证时间")
+	private String certificationTime;
+
     /**
      * 责任者
      */

+ 3 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/ContractLog.java

@@ -86,4 +86,7 @@ public class ContractLog extends BaseEntity {
     @ApiModelProperty("关联工序的ids")
     private String correlationId;
 
+    @ApiModelProperty("文件名称")
+    private String fileName;
+
 }

+ 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工程文件")
+    @ApiModelProperty("上报类型,1填报资料,2工程文件,3日志资料")
     private Integer approvalType;
 
     @ApiModelProperty("项目ID")

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

@@ -76,6 +76,8 @@ public class ArchiveFileVO extends ArchiveFile {
 
 	private List<String> nodeIdArray;
 
+	private List<String> ids;
+
 	private String sheetSourceValue;
 
 }

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

@@ -32,4 +32,7 @@ public class ContractLogVO extends ContractLog {
 	@ApiModelProperty("关键字查询")
 	private String queryValue;
 
+	@ApiModelProperty("流程状态")
+	private String statusValue;
+
 }

+ 2 - 1
blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/ArchiveTaskVO.java → blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/StartTaskVO.java

@@ -4,7 +4,8 @@ import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
 @Data
-public class ArchiveTaskVO {
+public class StartTaskVO {
+
     /**
      * 数据指向
      */

+ 0 - 47
blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/WriteBatchTaskVO.java

@@ -1,47 +0,0 @@
-package org.springblade.business.vo;
-
-import io.swagger.annotations.ApiModelProperty;
-import lombok.Data;
-
-@Data
-public class WriteBatchTaskVO {
-    /**
-     * 数据指向
-     */
-    @ApiModelProperty("列表数据的id字段,多数据时用英文逗号拼接")
-    private String ids;
-
-    /**
-     * 固定流程ID
-     */
-    @ApiModelProperty("固定流程ID")
-    private Long fixedFlowId;
-
-    /**
-     * 上报批次
-     */
-    @ApiModelProperty("上报批次")
-    private Integer batch;
-
-    /**
-     * 任务名称
-     */
-    @ApiModelProperty("任务名称")
-    private String taskName;
-
-    /**
-     * 任务内容
-     */
-    @ApiModelProperty("任务内容")
-    private String taskContent;
-
-    @ApiModelProperty("限定审批时间(天)")
-    private Integer restrictDay;
-
-    @ApiModelProperty("项目ID")
-    private String projectId;
-
-    @ApiModelProperty("合同段ID")
-    private String contractId;
-
-}

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

@@ -6,6 +6,7 @@ import org.springblade.evisa.vo.EVisaTaskApprovalVO;
 import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestParam;
 
 @FeignClient(value = EVisaConstant.APPLICATION_WEATHER_NAME)
 public interface EVisaClient {
@@ -27,4 +28,10 @@ public interface EVisaClient {
     @PostMapping(API_PREFIX + "/createSeal")
     String createSeal(@RequestBody EVisaMakeSealVO vo);
 
+    /**
+     * 认证
+     */
+    @PostMapping(API_PREFIX + "/certification")
+    String certification(@RequestParam String pdfUrl, @RequestParam String fileName, @RequestParam String contractId);
+
 }

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

@@ -0,0 +1,22 @@
+package org.springblade.evisa.vo;
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class SealPdfVO {
+
+    /**
+     * pdf地址
+     */
+    private String pdfFileUrl;
+
+    /**
+     * 文件名称唯一
+     */
+    private String fileName;
+
+    private List<SealStrategyVO> strategyVoList;
+
+}

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

@@ -0,0 +1,124 @@
+package org.springblade.evisa.vo;
+
+import lombok.Data;
+
+@Data
+public class SealStrategyVO {
+
+    private boolean isCompanySeal;
+
+    /**
+     * 签章类型,0,图片,1,文字
+     */
+    private String type;
+
+    /**
+     * 签名码
+     */
+    private String sealCode;
+
+    /**
+     * 密码
+     */
+    private String sealPassword;
+
+    /**
+     * 签章地址
+     */
+    private String imageUrl;
+
+    /**
+     * 签署类型,默认3 关键字搜索签章,1是空白签章,2是坐标签章
+     */
+    private String sealType = "3";
+
+    /**
+     * 关键字签章开始,关键字
+     */
+    private String keyword;
+
+    /**
+     * x轴偏移,默认0
+     */
+    private String offSetX = "0";
+
+    /**
+     * y轴偏移,默认0
+     */
+    private String offSetY = "0";
+    //关键字签章结束 ======================================
+
+    /**
+     * 坐标签章开始  签章页码
+     */
+    private String page;
+
+    /**
+     * x轴坐标
+     */
+    private String lx;
+
+    /**
+     * y轴坐标
+     */
+    private String ly;
+
+    /**
+     * 签章人姓名,必填
+     */
+    private String sealPerson;
+
+    /**
+     * 签章地点,可以为空
+     */
+    private String sealLocation;
+
+    /**
+     * 签章原因,可以为空
+     */
+    private String sealReason;
+    //坐标签章结束 ======================================
+
+    /**
+     * 文本签章内容
+     */
+    private String sealText;
+
+    /**
+     * 外传文本样式
+     * 生成文本框宽度(控制字体框大小)默认100
+     */
+    private String width = "100";
+
+    /**
+     * 生成文本框高度(控制字体框大小)默认100
+     */
+    private String height = "100";
+
+    /**
+     * 字体大小,默认12
+     */
+    private String fontSize = "12";
+
+    /**
+     * 文本颜色,默认黑色
+     */
+    private String fontColor;
+
+    /**
+     * 字体,默认宋体
+     */
+    private String family;
+
+    /**
+     * 为null时,电签接口默认设为0。
+     * 采用坐标定位签章位置时
+     * 0:PDF左下角坐标为(0,0),签章图片定位是用签章图片的左下角点定位。
+     * 1:pdf左上角坐标为(0,0),签章图片定位是用签章图片的中心点定位
+     */
+    private String isCenterCoordinate;
+
+    private String identificationNo;
+
+    private boolean isCompany;
+}

+ 61 - 16
blade-service/blade-business/src/main/java/org/springblade/business/controller/ArchiveFileController.java

@@ -1,7 +1,9 @@
 package org.springblade.business.controller;
 
+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.toolkit.Wrappers;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
@@ -14,12 +16,11 @@ import org.springblade.business.entity.Task;
 import org.springblade.business.feign.OperationLogClient;
 import org.springblade.business.feign.TaskClient;
 import org.springblade.business.utils.FileUtils;
-import org.springblade.business.vo.ArchiveTaskVO;
+import org.springblade.business.vo.StartTaskVO;
 import org.springblade.business.vo.TaskVO;
-import org.springblade.common.utils.CommonUtil;
 import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.utils.Func;
-import org.springblade.core.tool.utils.IoUtil;
+import org.springblade.evisa.feign.EVisaClient;
 import org.springblade.manager.feign.ArchiveTreeClient;
 import org.springblade.manager.vo.ArchiveTreeVO;
 import org.springframework.beans.BeanUtils;
@@ -32,15 +33,10 @@ import org.springblade.business.service.IArchiveFileService;
 import org.springblade.core.boot.ctrl.BladeController;
 
 import javax.servlet.http.HttpServletResponse;
-import java.io.BufferedOutputStream;
-import java.io.DataOutputStream;
-import java.io.InputStream;
-import java.net.URLEncoder;
+import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Date;
 import java.util.List;
-import java.util.stream.Collectors;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipOutputStream;
 
 /**
  *  控制器
@@ -62,6 +58,51 @@ public class ArchiveFileController extends BladeController {
 
 	private final OperationLogClient operationLogClient;
 
+	private final EVisaClient eVisaClient;
+
+	/**
+	 * 批量认证(特殊签章 签个透明空白图片,主要目的是在验签的时候有验签信息 )
+	 */
+	@PostMapping("/batchCertification")
+	@ApiOperationSupport(order = 9)
+	@ApiOperation(value = "批量认证")
+	public R<Boolean> batchCertification(@RequestBody ArchiveFileVO vo){
+		List<String> list = new ArrayList<>();
+		if(vo.getIds() != null && vo.getIds().size() > 0){
+			//获取文件
+			List<ArchiveFile> archiveFileList = this.archiveFileService.list(Wrappers.<ArchiveFile>lambdaQuery().in(ArchiveFile::getId, vo.getIds()));
+			if(archiveFileList != null && archiveFileList.size() > 0){
+				for(ArchiveFile archiveFile : archiveFileList){
+					//获取文件地址并调用接口认证
+					String result = this.eVisaClient.certification(archiveFile.getPdfFileUrl(), archiveFile.getFileName(), archiveFile.getContractId());
+					if(StringUtils.isNotEmpty(result) && result.contains("success") && result.startsWith("success")){
+						//成功,更改状态
+						//签章成功后的文件路径,如果与原pdf文件路径不匹配则更新
+						String newPdfUrl = null;
+						if(result.contains("@@@@")){
+							newPdfUrl = result.split("@@@@")[1];
+						}
+						LambdaUpdateWrapper<ArchiveFile> wrappers = Wrappers.lambdaUpdate();
+						if(StringUtils.isNotEmpty(newPdfUrl) && !archiveFile.getPdfFileUrl().equals(newPdfUrl)){
+							//不为空且不匹配时,更新
+							wrappers.set(ArchiveFile::getPdfFileUrl, newPdfUrl);
+						}
+						//修改认证状态为已认证
+						wrappers.set(ArchiveFile::getIsCertification, 1);
+						//添加认证时间
+						wrappers.set(ArchiveFile::getCertificationTime, DateUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss"));
+
+						//修改状态
+						this.archiveFileService.update(wrappers.eq(ArchiveFile::getId, archiveFile.getId()));
+					} else {
+						list.add(archiveFile.getId().toString());
+					}
+				}
+			}
+		}
+		return list.size() == 0 ? R.data(true) : R.data(300, false, "操作失败");
+	}
+
 	/**
 	 * 批量下载
 	 */
@@ -73,9 +114,13 @@ public class ArchiveFileController extends BladeController {
 		if(StringUtils.isNotEmpty(ids)){
 			//获取文件
 			List<ArchiveFile> result = this.archiveFileService.list(Wrappers.<ArchiveFile>lambdaQuery().in(ArchiveFile::getId, Arrays.asList(ids.split(","))));
-			List<String> urls = result.stream().map(ArchiveFile::getFileUrl).distinct().collect(Collectors.toList());
-			//打包下载
-			FileUtils.batchDownloadFileToZip(urls, response);
+			if(result != null && result.size() > 0){
+				List<String> urls = new ArrayList<>();
+				result.forEach(archiveFile -> urls.add(archiveFile.getFileUrl() + "@@@" + archiveFile.getFileName()));
+
+				//打包下载
+				FileUtils.batchDownloadFileToZip(urls, response);
+			}
 		}
 
 	}
@@ -117,12 +162,12 @@ public class ArchiveFileController extends BladeController {
 	@PostMapping("/batchApproval")
 	@ApiOperationSupport(order = 6)
 	@ApiOperation(value = "批量上报")
-	public R<Boolean> batchApproval(@RequestBody ArchiveTaskVO archiveTaskVO){
-		String archiveTaskIds = archiveTaskVO.getIds();
+	public R<Boolean> batchApproval(@RequestBody StartTaskVO startTaskVO){
+		String archiveTaskIds = startTaskVO.getIds();
 		if(StringUtils.isNotEmpty(archiveTaskIds)){
 			//生成流程实体
 			TaskVO taskVO = new TaskVO();
-			BeanUtils.copyProperties(archiveTaskVO, taskVO);
+			BeanUtils.copyProperties(startTaskVO, taskVO);
 			taskVO.setFormDataId(archiveTaskIds);
 			taskVO.setApprovalType(2);
 

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

@@ -1,38 +1,31 @@
-/*
- *      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.business.controller;
 
 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.Api;
 import io.swagger.annotations.ApiImplicitParam;
 import io.swagger.annotations.ApiImplicitParams;
 import io.swagger.annotations.ApiOperation;
 import lombok.AllArgsConstructor;
+import org.apache.commons.lang.StringUtils;
 import org.springblade.business.entity.ContractLog;
+import org.springblade.business.entity.Task;
+import org.springblade.business.feign.OperationLogClient;
+import org.springblade.business.feign.TaskClient;
 import org.springblade.business.vo.ContractLogVO;
 import org.springblade.business.vo.FileUserVO;
-import org.springblade.core.mp.support.Query;
+import org.springblade.business.vo.StartTaskVO;
+import org.springblade.business.vo.TaskVO;
 import org.springblade.core.tool.api.R;
 import org.springblade.manager.feign.WbsTreeContractClient;
 import org.springblade.manager.vo.WbsTreeContractTreeVOS;
+import org.springframework.beans.BeanUtils;
 import org.springframework.web.bind.annotation.*;
 import org.springblade.business.service.IContractLogService;
 import org.springblade.core.boot.ctrl.BladeController;
+
+import java.util.Arrays;
 import java.util.List;
 
 /**
@@ -51,6 +44,71 @@ public class ContractLogController extends BladeController {
 
 	private final WbsTreeContractClient wbsTreeContractClient;
 
+	private final TaskClient taskClient;
+
+	private final OperationLogClient operationLogClient;
+
+	/**
+	 * 批量废除
+	 */
+	@PostMapping("/batchAbolish")
+	@ApiOperationSupport(order = 5)
+	@ApiOperation(value = "批量废除")
+	public R<Boolean> batchAbolish(@RequestParam String ids){
+		//获取所有相关任务记录
+		List<Task> taskList =  this.taskClient.queryTaskListByFormDataId(ids);
+		if(taskList != null && taskList.size() > 0){
+			//执行废除
+			for(Task task : taskList){
+				if(new Integer("1").equals(task.getStatus())){
+					//正在审批,调用废除
+					this.taskClient.abolishTask(task);
+				} else if(new Integer("2").equals(task.getStatus())) {
+					//已审批的任务,修改业务数据的审批状态为未上报并撤签即可
+					this.contractLogService.update(Wrappers.<ContractLog>lambdaUpdate().set(ContractLog::getStatus, 3).in(ContractLog::getId, Arrays.asList(task.getFormDataId().split(","))));
+					// todo ================== 调用撤签
+					// todo ================== 调用撤签
+				}
+				//保存操作记录
+				this.operationLogClient.saveUserOperationLog(9, "台账日志", "日志填报", task.getFormDataId());
+			}
+		}
+		return R.data(true);
+	}
+
+	/**
+	 * 批量上报
+	 */
+	@PostMapping("/batchTask")
+	@ApiOperationSupport(order = 4)
+	@ApiOperation(value = "批量上报")
+	public R<Boolean> batchTask(@RequestBody StartTaskVO startTaskVO){
+		if(StringUtils.isNotEmpty(startTaskVO.getIds())){
+			//获取数据源id
+			String[] ids = startTaskVO.getIds().split(",");
+			if(ids.length > 0){
+				for(String id : ids){
+					//生成任务实体
+					TaskVO taskVO = new TaskVO();
+					BeanUtils.copyProperties(startTaskVO, taskVO);
+					//设置数据源指向
+					taskVO.setFormDataId(id);
+					//设置上报类型
+					taskVO.setApprovalType(3);
+					//上报
+					if(this.taskClient.startTask(taskVO).getData()){
+						//修改记录
+						this.contractLogService.update(Wrappers.<ContractLog>lambdaUpdate().set(ContractLog::getStatus, 1).eq(ContractLog::getId, id));
+					}
+				}
+				//保存操作记录
+				this.operationLogClient.saveUserOperationLog(8, "台账日志", "日志填报", startTaskVO.getIds());
+				return R.data(true);
+			}
+		}
+		return R.data(false);
+	}
+
 	/**
 	 * 获取当前日志类型的填报人
 	 * @return 结果

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

@@ -169,15 +169,15 @@ public class InformationWriteQueryController extends BladeController {
 	@PostMapping("/batchTask")
 	@ApiOperationSupport(order = 17)
 	@ApiOperation(value = "批量上报")
-	public R<Boolean> batchTask(@RequestBody WriteBatchTaskVO batchTaskVO){
-		if(StringUtils.isNotEmpty(batchTaskVO.getIds())){
+	public R<Boolean> batchTask(@RequestBody StartTaskVO startTaskVO){
+		if(StringUtils.isNotEmpty(startTaskVO.getIds())){
 			//获取数据源id
-			String[] ids = batchTaskVO.getIds().split(",");
+			String[] ids = startTaskVO.getIds().split(",");
 			if(ids.length > 0){
 				for(String id : ids){
 					//生成任务实体
 					TaskVO taskVO = new TaskVO();
-					BeanUtils.copyProperties(batchTaskVO, taskVO);
+					BeanUtils.copyProperties(startTaskVO, taskVO);
 					//设置数据源指向
 					taskVO.setFormDataId(id);
 					//设置上报类型
@@ -196,7 +196,7 @@ public class InformationWriteQueryController extends BladeController {
 					}
 				}
 				//保存操作记录
-				this.operationLogClient.saveUserOperationLog(5, "资料管理", "工序资料", batchTaskVO.getIds());
+				this.operationLogClient.saveUserOperationLog(5, "资料管理", "工序资料", startTaskVO.getIds());
 				return R.data(true);
 			}
 		}
@@ -826,6 +826,17 @@ public class InformationWriteQueryController extends BladeController {
 		if(new Integer("2").equals(contractInfo.getContractType())){
 			//监理合同段,需要获取关联的施工方合同段根节点数据
 			rootTreeNode = this.wbsTreeContractClient.lazyTree(StringUtils.isNotEmpty(parentId) ? Long.parseLong(parentId) : 0, contractId, contractIdRelation, contractInfo.getContractType());
+			if(StringUtils.isEmpty(parentId)){
+				if(rootTreeNode != null && rootTreeNode.size() > 0){
+					rootTreeNode.forEach(treeNode -> {
+						ContractInfo clientContract = this.contractClient.getContractById(Long.parseLong(treeNode.getContractIdRelation()));
+						if(clientContract != null){
+							treeNode.setTitle(clientContract.getContractName());
+						}
+					});
+				}
+			}
+
 		} else {
 			if(com.alibaba.nacos.common.utils.StringUtils.isEmpty(parentId)){
 				//为空,说明初始化
@@ -838,7 +849,7 @@ public class InformationWriteQueryController extends BladeController {
 		}
 
 		//其他参数
-		if(rootTreeNode != null && rootTreeNode.size() != 0){
+		if(rootTreeNode != null && rootTreeNode.size() > 0){
 			rootTreeNode.forEach(vo -> {
 				String primaryKeyId = new Integer("2").equals(contractInfo.getContractType()) ? vo.getId() : vo.getPrimaryKeyId();
 				//获取上传的图纸

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

@@ -22,6 +22,7 @@
         <result column="file_page" property="filePage"/>
         <result column="is_approval" property="isApproval"/>
         <result column="is_certification" property="isCertification"/>
+        <result column="certification_time" property="certificationTime"/>
         <result column="is_need_certification" property="isNeedCertification"/>
         <result column="duty_user" property="dutyUser"/>
         <result column="pdf_file_url" property="pdfFileUrl"/>

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

@@ -22,6 +22,7 @@
         <result column="project_part" property="projectPart"/>
         <result column="data_id" property="dataId"/>
         <result column="create_user_name" property="createUserName"/>
+        <result column="file_name" property="fileName"/>
     </resultMap>
 
     <select id="queryFillUser" resultMap="contractLogResultMap">
@@ -36,7 +37,9 @@
           project_pileno,
           project_part,
           data_id,
-          create_user_name
+          create_user_name,
+          file_name,
+          status
         from
           u_contract_log
         where

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

@@ -65,7 +65,6 @@
                 </if>
                 and sort = 4 order by number DESC
             ) as uof
-            limit 1
         ) as uof on uof.user_opinion_id = uo.id
         where uo.is_deleted = 0 order by uo.create_time DESC
     </select>

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

@@ -18,7 +18,6 @@ package org.springblade.business.service.impl;
 
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
-import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import org.springblade.business.entity.ContractLog;
 import org.springblade.business.vo.ContractLogVO;
 import org.springblade.business.mapper.ContractLogMapper;
@@ -70,6 +69,7 @@ public class ContractLogServiceImpl extends BaseServiceImpl<ContractLogMapper, C
 		}
 		//有数据,转换成VO
 		List<ContractLogVO> voResult = JSONArray.parseArray(JSONObject.toJSONString(result), ContractLogVO.class);
+		voResult.forEach(vo -> vo.setStatusValue(new Integer("0").equals(vo.getStatus()) ? "未上报" : new Integer("1").equals(vo.getStatus()) ? "待审批" : new Integer("2").equals(vo.getStatus()) ? "已审批" : "已废除"));
 
 		IPage<ContractLogVO> iPage = Condition.getPage(query);
 		iPage.setTotal(count);

+ 13 - 0
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TaskServiceImpl.java

@@ -62,6 +62,8 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
 
     private final IInformationQueryService informationQueryService;
 
+    private final IContractLogService contractLogService;
+
     @Override
     public List<TaskParallel> queryApprovalUser(String formDataIds) {
         //返回结果
@@ -366,11 +368,22 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
                 //工程文件
                 this.updateArchiveFileBusinessDataStatus(task.getFormDataId(), status);
                 break;
+            case 3:
+                //工程文件
+                this.updateContractLogBusinessDataStatus(task.getFormDataId(), status);
+                break;
             default:
                 break;
         }
     }
 
+    /**
+     * 施工日志等
+     */
+    private void updateContractLogBusinessDataStatus(String formDataId, Integer status){
+        this.contractLogService.update(Wrappers.<ContractLog>lambdaUpdate().set(ContractLog::getStatus, status).in(ContractLog::getId, Arrays.asList(formDataId.split(","))));
+    }
+
     /**
      * 资料填报
      */

+ 12 - 2
blade-service/blade-business/src/main/java/org/springblade/business/utils/FileUtils.java

@@ -57,14 +57,24 @@ public class FileUtils {
             for(String url : urls){
                 if(StringUtils.isNotEmpty(url)){
                     try{
+                        String fileName = null, symbol = "";
+                        if(url.contains("@@@")){
+                            String[] array = url.split("@@@");
+                            url = array[0];
+                            fileName = array[1];
+                            symbol = url.substring(url.lastIndexOf("."));
+                        }
 
                         //获取文件流
                         inputStream = CommonUtil.getOSSInputStream(url);
                         //转换
                         byte[] bytes = CommonUtil.InputStreamToBytes(inputStream);
 
-                        String fileName = url.substring(url.lastIndexOf("/") + 1);
-                        zipos.putNextEntry(new ZipEntry(fileName));
+                        if(StringUtils.isEmpty(fileName)){
+                            fileName = url.substring(url.lastIndexOf("/") + 1);
+                            symbol = "";
+                        }
+                        zipos.putNextEntry(new ZipEntry(fileName + symbol));
 
                         os = new DataOutputStream(zipos);
                         os.write(bytes);

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

@@ -179,6 +179,12 @@
             <artifactId>UARC</artifactId>
             <version>3.0.1.1</version>
         </dependency>
+        <dependency>
+            <groupId>org.springblade</groupId>
+            <artifactId>blade-resource-api</artifactId>
+            <version>2.9.1.RELEASE</version>
+            <scope>compile</scope>
+        </dependency>
         <!-- 电签相关 end -->
 
     </dependencies>

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

@@ -1,17 +1,29 @@
 package org.springblade.evisa.feign;
 
 import lombok.AllArgsConstructor;
+import org.springblade.common.constant.EVisaConstant;
+import org.springblade.core.secure.utils.AuthUtil;
 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.springframework.web.bind.annotation.RestController;
 
+import java.util.ArrayList;
+import java.util.List;
+
 @RestController
 @AllArgsConstructor
 public class EVisaClientImpl implements EVisaClient {
 
     private final EVisaService eVisaService;
 
+    @Override
+    public String certification(String pdfUrl, String fileName, String contractId) {
+        return this.eVisaService.certification(pdfUrl, fileName, contractId);
+    }
+
     @Override
     public String eVisa(EVisaTaskApprovalVO task) {
         return this.eVisaService.eVisa(task);

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

@@ -5,6 +5,11 @@ import org.springblade.evisa.vo.EVisaTaskApprovalVO;
 
 public interface EVisaService {
 
+    /**
+     * 认证
+     */
+    String certification(String pdfUrl, String fileName, String contractId);
+
     /**
      * 电签
      */

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

@@ -4,34 +4,55 @@ import cfca.paperless.ClientConstants;
 import cfca.paperless.base.BaseConstants;
 import cfca.paperless.base.util.Base64;
 import cfca.paperless.base.util.GUIDUtil;
+import cfca.paperless.base.util.ImageUtil;
 import cfca.paperless.base.util.PwdEncryptUtil;
 import cfca.paperless.client.PaperlessClient;
 import cfca.paperless.dto.RequestHead;
 import cfca.paperless.dto.ResponseDto;
 import cfca.paperless.dto.ResponseHead;
-import cfca.paperless.dto.bean.SealCertBean;
-import cfca.paperless.dto.bean.SealInfoBean;
+import cfca.paperless.dto.bean.*;
 import cfca.paperless.dto.request.requestbody.tx20.MakeSealRequestBody;
+import cfca.paperless.dto.request.requestbody.tx40.CompoundSealPdfListRequestBody;
 import cfca.paperless.dto.request.tx20.MakeSealRequest;
 import cfca.paperless.dto.request.tx40.CompoundSealPdfListDetachedRequest;
 import cfca.paperless.dto.response.responsebody.tx20.MakeSealResponseBody;
+import cfca.paperless.dto.response.responsebody.tx40.CompoundSealPdfListDetachedResponseBody;
 import cfca.paperless.dto.response.tx20.MakeSealResponse;
+import cfca.paperless.dto.response.tx40.CompoundSealPdfListDetachedResponse;
 import com.alibaba.fastjson.JSONObject;
 import lombok.AllArgsConstructor;
+import org.apache.commons.lang.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springblade.business.feign.TaskClient;
 import org.springblade.business.vo.TaskApprovalVO;
 import org.springblade.common.constant.EVisaConstant;
 import org.springblade.common.utils.CommonUtil;
+import org.springblade.core.oss.model.BladeFile;
 import org.springblade.core.secure.utils.AuthUtil;
 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.manager.entity.SignPfxFile;
 import org.springblade.manager.feign.SignPfxClient;
+import org.springblade.resource.feign.NewIOSSClient;
 import org.springframework.stereotype.Service;
+
+import javax.imageio.*;
+import javax.imageio.metadata.IIOInvalidTreeException;
+import javax.imageio.metadata.IIOMetadata;
+import javax.imageio.metadata.IIOMetadataNode;
+import javax.imageio.stream.ImageOutputStream;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Iterator;
 import java.util.List;
 
 @Service
@@ -42,12 +63,82 @@ public class EVisaServiceImpl implements EVisaService {
 
     private static final String SIGN_PORT = "8183";
 
+    private static final double INCH_2_CM = 2.54d;
+
     private static final Logger logger = LoggerFactory.getLogger(EVisaServiceImpl.class);
 
     private final SignPfxClient signPfxClient;
 
     private final TaskClient taskClient;
 
+    private final NewIOSSClient newIOSSClient;
+
+    @Override
+    public String certification(String pdfUrl, String fileName, String contractId) {
+        try{
+            //准备签章策略
+            List<SealStrategyVO> sealStrategyVOS = new ArrayList<>();
+            //根据当前合同段获取相关的证书
+            List<SignPfxFile> pfxFiles = this.signPfxClient.querySignPfxByUserIdOrContractId("", contractId);
+            if(pfxFiles == null || pfxFiles.size() <= 0){
+                return "error";
+            }
+            SealStrategyVO vo = new SealStrategyVO();
+            vo.setSealCode(EVisaConstant.SIGN_SEAL_CODE + AuthUtil.getUserId().toString().substring(0, EVisaConstant.USER_ID_SUB));
+            vo.setSealPassword(AuthUtil.getUserId().toString().substring(0, EVisaConstant.USER_ID_SUB));
+            vo.setSealPerson(AuthUtil.getUserAccount());
+            //使用默认写死的透明图片
+            vo.setImageUrl("authentication");
+            //使用坐标定位 ,坐标固定
+            vo.setSealType("2");
+            vo.setLx("100");
+            vo.setLy("100");
+            vo.setPage("1");
+            sealStrategyVOS.add(vo);
+
+            SealPdfVO pdfVO = new SealPdfVO();
+            pdfVO.setStrategyVoList(sealStrategyVOS);
+
+            //获取认证文件
+            byte[] fileByte = CommonUtil.InputStreamToBytes(CommonUtil.getOSSInputStream(pdfUrl));
+            //兼容大文件签章
+            Object[] result;
+            //大于50M的单个文件采用大文件签章处理
+            if(fileByte.length > 52428800){
+                result = null;
+
+            } else {
+                //普通文件签章
+                result = this.signPdf(pdfVO, fileByte);
+            }
+            if(result != null){
+                if(result[0] != null){
+                    byte[] newPdfData = (byte[])result[0];
+                    //重新上传覆盖
+                    BladeFile bladeFile = this.newIOSSClient.updateFile(newPdfData, pdfUrl.substring(pdfUrl.lastIndexOf("/") + 1, pdfUrl.lastIndexOf(".")));
+                    if(bladeFile != null){
+                        return "success" + "@@@@" + bladeFile.getLink();
+                    } else {
+                        return "error";
+                    }
+                } else {
+                    String s = result[1].toString();
+                    return s.contains("600619") ? "认证失败! " + fileName + "-文件存在无效签名。" : "认证失败!"+"原因:" + s;
+                }
+            } else {
+                //电签失败 ,接口返回认证失败
+                return "认证失败!认证接口调用异常";
+            }
+
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+
+        return null;
+    }
+
+
+
     @Override
     public String eVisa(EVisaTaskApprovalVO task) {
         //todo 这里应当是配置限制参数,初版暂时写死
@@ -76,7 +167,235 @@ public class EVisaServiceImpl implements EVisaService {
     }
 
     /**
-     * 签章
+     * 签章(坐标方式)
+     */
+    private Object[] signPdf(SealPdfVO pdfVO, byte[] fileByte){
+        Object[] result = new Object[2];
+        try{
+            PaperlessClient paperlessClient = new PaperlessClient(SIGN_HOST, SIGN_PORT, 300000, 36000000);
+            paperlessClient.setSSL(false);
+            //*****************************************************************************
+            CompoundSealPdfListDetachedRequest compoundSealPdfListDetachedRequest = new  CompoundSealPdfListDetachedRequest();
+
+            RequestHead requestHead = new RequestHead();
+            //业务流水号 非空
+            String transactionNo = GUIDUtil.generateId();
+            //机构编码非空
+            String organizationCode = EVisaConstant.organizationCode;
+
+            //操作员编码 可为空(企业类型不能为空)
+            String operatorCode = EVisaConstant.operationCode;
+            //渠道编码 可为空
+            String channelCode = "";
+            //设置属性
+            requestHead.setBasicInfo(transactionNo, organizationCode,operatorCode,channelCode);
+
+            compoundSealPdfListDetachedRequest.setHead(requestHead);
+
+            //*****************************************************************************
+            CompoundSealPdfListRequestBody requestBody = new CompoundSealPdfListRequestBody();
+
+            List<PdfBean> pdfBeans = new ArrayList<>();
+            PdfBean pdfBean = new PdfBean();
+            pdfBean.setBizSerialNo(GUIDUtil.generateId());
+            pdfBean.setInputSource("");
+            pdfBean.setInputType(BaseConstants.INPUT_TYPE_FILEDATA);
+            pdfBean.setPdfData(fileByte);
+            pdfBeans.add(pdfBean);
+
+            requestBody.setPdfBeans(pdfBeans);
+            //***********************构造机构章策略 ********************************
+            List<SealStrategy> sealStrategies = this.generateSealStrategies(pdfVO.getStrategyVoList());
+            if(null == sealStrategies || sealStrategies.size() <= 0){
+                logger.info("【电签模块】{}","签章策略为空");
+                return null;
+            }
+            requestBody.setSealStrategies(sealStrategies);
+
+            //签章后文件保存地址,不为空时,直接将签章文件保存在此地址,不再返回签章后文档数据;ftp:auto
+            requestBody.setOutputFilepath("");
+
+            //时间戳方式,默认为0;0:实时访问CFCA 时间戳服务;1:使用从CFCA购置并在本地部署的时间戳服务器产品;
+            requestBody.setTimestampChannel(BaseConstants.TIME_STAMP_CHANNEL_CFCA);
+            //获取场景证书的方式默认值为0;0:实时从CFCA CA服务申请下载场景证书;1:使用从CFCA CA服务预先申请下载并存储在本地的场景证书;
+            requestBody.setSceneCertChannel(BaseConstants.SCEND_CERT_CHANNEL_REAL);
+
+            compoundSealPdfListDetachedRequest.setBody(requestBody);
+            //****************************** 请求服务端进行签章 *********************************************
+            ResponseDto responseDto = paperlessClient.execute(compoundSealPdfListDetachedRequest);
+
+            //******************************解析响应结果 *********************************************
+            CompoundSealPdfListDetachedResponse compoundSealPdfListDetachedResponse = (CompoundSealPdfListDetachedResponse)responseDto;
+            ResponseHead  responseHead = compoundSealPdfListDetachedResponse.getHead();
+            CompoundSealPdfListDetachedResponseBody responseBody = compoundSealPdfListDetachedResponse.getBody();
+            if(ClientConstants.CODE_SUCCESS.equals(responseHead.getCode())){
+                List<PdfBean4Response> pdfBeanList = responseBody.getPdfBeans();
+                if(pdfBeanList!=null && pdfBeanList.size()>0){
+                    PdfBean4Response pdfBean4Response =pdfBeanList.get(0);
+                    result[0] = pdfBean4Response.getPdf();
+                }
+            }else{
+                logger.info("【电签模块】{}","签章响应Response:"+compoundSealPdfListDetachedResponse);
+                logger.info("【电签模块】{}","签章响应code:"+responseHead.getCode());
+                result[0] = null;
+                result[1] = compoundSealPdfListDetachedResponse.toString();
+            }
+
+        } catch (Exception e){
+            e.printStackTrace();
+            logger.info("【电签模块】{}","电签签章接口调用异常");
+            e.printStackTrace();
+            return null;
+        }
+
+        return result;
+    }
+
+    /**
+     * 构造机构章签章策略
+     * 使用 :1-印章绑定的图片
+     */
+    private List<SealStrategy> generateSealStrategies(List<SealStrategyVO> strategyVoList){
+        List<SealStrategy> sealStrategies = new ArrayList<>();
+
+        if(strategyVoList == null || strategyVoList.size() <= 0){
+            return null;
+        }
+
+        //构建策略
+        for(SealStrategyVO vo : strategyVoList){
+            try{
+                SealStrategy sealStrategy = new SealStrategy();
+
+                // 使用图片签章
+                String type = BaseConstants.SEAL_TYPE_IMAGE;
+
+                String sealCode = vo.getSealCode();
+                String sealPassword = PwdEncryptUtil.encrypto(vo.getSealPassword());
+                sealStrategy.setSealInfo(type, sealCode, sealPassword);
+
+                //单笔业务流水号 非空
+                String serialNo = GUIDUtil.generateId();
+                sealStrategy.setSerialNo(serialNo);
+
+                //算法
+                String hashAlg = BaseConstants.HASHALG_SHA256;
+                sealStrategy.setHashAlg(hashAlg);
+                //透明度,0-1.0f,默认1.0f,不透明
+                String fillOpacity = "1";
+                sealStrategy.setFillOpacity(fillOpacity);
+                //是否显示,默认1 显示
+                String visible = "1";
+                sealStrategy.setVisible(visible);
+
+                byte[] imageData = null;
+                if(!"authentication".equals(vo.getImageUrl())){
+                    String imageUrl = vo.getImageUrl();
+                    if(StringUtils.isEmpty(imageUrl)){
+                        logger.info("签章图片url为null,签章人员:" + vo.getSealPerson());
+                        return null;
+                    }
+                    //获取字节
+                    imageData = CommonUtil.InputStreamToBytes(CommonUtil.getOSSInputStream(imageUrl));
+                    //对图片进行扣白底
+                    imageData = ImageUtil.transferAlpha(imageData);
+
+                    //设置大小
+                    if(vo.isCompanySeal()){
+                        imageData = ImageUtil.resizeImage(imageData,540,540);
+                    }else {
+                        imageData = ImageUtil.resizeImage(imageData,480,132);
+                    }
+
+                    //图片dpi设置
+                    imageData = this.handleDpi(imageData);
+                }
+                if (imageData != null) {
+                    //图片进行Base64编码/
+                    String imageDataString =  new String(Base64.encode(imageData), StandardCharsets.UTF_8);
+                    sealStrategy.setSealImage(imageDataString);
+                }
+
+                if("authentication".equals(vo.getImageUrl())){
+                    //工程文件认证的 是要用透明图片
+                    sealStrategy.setSealImage(EVisaConstant.base64String);
+                }
+                sealStrategy.setSealMiscInfo(vo.getSealPerson(), vo.getSealLocation(),  vo.getSealReason());
+
+                //关键字签章
+                sealStrategy.setSealType(vo.getSealType());
+                if (vo.getSealType().equals("3")) {
+                    sealStrategy.setKeyword(vo.getKeyword());
+                    sealStrategy.setOffsetX(vo.getOffSetX());
+                    sealStrategy.setOffsetY(vo.getOffSetY());
+                } else if (vo.getSealType().equals("2")) {
+                    //设置PDF坐标原点,签章图片定位点   默认为PDF左下角,签章图片定位为左下角
+                    if(StringUtils.isNotEmpty(vo.getIsCenterCoordinate())){
+                        sealStrategy.setIsCenterCoordinate(vo.getIsCenterCoordinate());
+                    }
+                    sealStrategy.setSignWithCoordinate(vo.getPage(), vo.getLx(), vo.getLy());
+                }
+
+                sealStrategies.add(sealStrategy);
+            }catch (Exception e){
+                e.printStackTrace();
+            }
+        }
+        return sealStrategies;
+    }
+
+    /**
+     * 设置图片的dpi
+     */
+    private byte[] handleDpi(byte[] bytes) throws IOException {
+        BufferedImage gridImage = ImageIO.read(new ByteArrayInputStream(bytes));
+        final String formatName = "png";
+        byte[] result = new byte[0];
+        for (Iterator<ImageWriter> iw = ImageIO.getImageWritersByFormatName(formatName); iw.hasNext();) {
+            ImageWriter writer = iw.next();
+            ImageWriteParam writeParam = writer.getDefaultWriteParam();
+            ImageTypeSpecifier typeSpecifier = ImageTypeSpecifier.createFromBufferedImageType(BufferedImage.TYPE_INT_RGB);
+            IIOMetadata metadata = writer.getDefaultImageMetadata(typeSpecifier, writeParam);
+            if (metadata.isReadOnly() || !metadata.isStandardMetadataFormatSupported()) {
+                continue;
+            }
+            //设置图片的dpi
+            this.setDPI(metadata);
+            ByteArrayOutputStream output = new ByteArrayOutputStream();
+            try (ImageOutputStream stream = ImageIO.createImageOutputStream(output)) {
+                writer.setOutput(stream);
+                writer.write(metadata, new IIOImage(gridImage, null, metadata), writeParam);
+                result = output.toByteArray();
+            }
+            break;
+        }
+        return result;
+    }
+
+    /**
+     * 设置图片的dpi
+     */
+    private void setDPI(IIOMetadata metadata) throws IIOInvalidTreeException {
+        // for PMG, it's dots per millimeter
+        double dotsPerMilli = 1.0 * 300 / 10 / INCH_2_CM;
+        IIOMetadataNode horiz = new IIOMetadataNode("HorizontalPixelSize");
+        horiz.setAttribute("value", Double.toString(dotsPerMilli));
+
+        IIOMetadataNode vert = new IIOMetadataNode("VerticalPixelSize");
+        vert.setAttribute("value", Double.toString(dotsPerMilli));
+
+        IIOMetadataNode dim = new IIOMetadataNode("Dimension");
+        dim.appendChild(horiz);
+        dim.appendChild(vert);
+
+        IIOMetadataNode root = new IIOMetadataNode("javax_imageio_1.0");
+        root.appendChild(dim);
+
+        metadata.mergeTree("javax_imageio_1.0", root);
+    }
+
+    /**
+     * 签章(线程方式)
      */
     private boolean signPdf(){
         StringBuffer stringbuffer = new StringBuffer();
@@ -110,6 +429,9 @@ public class EVisaServiceImpl implements EVisaService {
         return false;
     }
 
+    /**
+     * 创建印模
+     */
     @Override
     public String createSeal(EVisaMakeSealVO vo) {
         try{

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

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

+ 33 - 10
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/SignPfxFileServiceImpl.java

@@ -95,16 +95,11 @@ public class SignPfxFileServiceImpl extends BaseServiceImpl<SignPfxFileMapper, S
 				return R.data(-1, false, "用户身份证号为空");
 			}
 
-			boolean ust = false;
-			boolean usw = false;
-
 			//判断是否存在个人签名文件
 			if(StringUtils.isNotEmpty(singPfx.getSignatureFileUrl()) && !"null".equals(singPfx.getSignatureFileUrl())){
 				if(!singPfx.getSignatureFileUrl().contains("png") && !singPfx.getSignatureFileUrl().contains("jpg")){
 					return R.data(-1, false, "用户签名不是PNG/JPG图片");
 				}
-
-				ust = true;
 				//设置信息
 				MakeSealDTO makeSeal = new MakeSealDTO();
 				makeSeal.setCustomerType("1");
@@ -124,31 +119,59 @@ public class SignPfxFileServiceImpl extends BaseServiceImpl<SignPfxFileMapper, S
 				makeSeal.setSealName(EVisaConstant.SIGN_SEAL_NAME + user.getAccount());
 				makeSeal.setSealPassword(user.getId().toString().substring(0, EVisaConstant.USER_ID_SUB));
 				//注册印模
-				this.pfxMakeSeal(makeSeal, "个人签名印章", id.toString());
+				return R.data(this.pfxMakeSeal(makeSeal, "个人签名印章", id.toString()));
 			}
 
 		} else {
-
+			//企业章
+			if(StringUtils.isNotEmpty(singPfx.getSignatureFileUrl()) && !"null".equals(singPfx.getSignatureFileUrl())){
+				if(!singPfx.getSignatureFileUrl().contains("png") && !singPfx.getSignatureFileUrl().contains("jpg")){
+					return R.data(-1, false, "用户签名不是PNG/JPG图片");
+				}
+				//设置信息
+				MakeSealDTO makeSeal = new MakeSealDTO();
+				makeSeal.setCustomerType("2");
+				//签名文件
+				makeSeal.setImageUrl(singPfx.getSignatureFileUrl());
+				//组织机构代码
+				makeSeal.setIdType(IdType.ZUZHIJIGOU.getCode());
+				//企业统一社会信用代码
+				makeSeal.setIdNumber(singPfx.getEnterpriseUnifiedCode());
+				//证书文件
+				makeSeal.setPfxFileUrl(singPfx.getCertificateFileUrl());
+				//证书密码
+				makeSeal.setPfxPassword(singPfx.getCertificatePassword());
+				//构造seal码
+				makeSeal.setSealCode(EVisaConstant.SIGN_SEAL_CODE + singPfx.getCertificatePassword());
+				//构建seal名
+				makeSeal.setSealName(EVisaConstant.SIGN_SEAL_NAME + singPfx.getCertificatePassword());
+				makeSeal.setSealPassword(singPfx.getCertificatePassword());
+				//签章名称
+				makeSeal.setUserName(singPfx.getCertificateUserName() + System.currentTimeMillis());
+				//注册印模
+				return R.data(this.pfxMakeSeal(makeSeal, "企业签名印章", id.toString()));
+			}
 		}
 
-		return null;
+		return R.data(false);
 	}
 
 	/**
 	 * 注册印模
 	 */
-	public void pfxMakeSeal(MakeSealDTO makeSeal, String msg, String pfxFileId){
+	public Boolean pfxMakeSeal(MakeSealDTO makeSeal, String msg, String pfxFileId){
 		try{
 			//调用接口创建印模
 			String resultCode = this.eVisaClient.createSeal(JSONObject.parseObject(JSONObject.toJSONString(makeSeal), EVisaMakeSealVO.class));
 			if(StringUtils.isNotEmpty(resultCode) && ("successfully".equals(resultCode) || "success".equals(resultCode) || "1".equals(resultCode))){
 				logger.info("【电签模块】{}", "创建" + msg + "成功");
 				//修改状态为已注册
-				this.update(Wrappers.<SignPfxFile>lambdaUpdate().set(SignPfxFile::getIsRegister, 1).eq(SignPfxFile::getId, pfxFileId));
+				return this.update(Wrappers.<SignPfxFile>lambdaUpdate().set(SignPfxFile::getIsRegister, 1).eq(SignPfxFile::getId, pfxFileId));
 			}
 		}catch (Exception e){
 			e.printStackTrace();
 		}
+		return false;
 	}
 
 	@Override

Daži faili netika attēloti, jo izmaiņu fails ir pārāk liels