Browse Source

电签功能

huangjn 2 years ago
parent
commit
7359f04587
34 changed files with 1049 additions and 92 deletions
  1. 23 0
      blade-common/src/main/java/org/springblade/common/constant/EVisaConstant.java
  2. 14 2
      blade-common/src/main/java/org/springblade/common/utils/CommonUtil.java
  3. 13 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/DefaultConfig.java
  4. 20 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/feign/TaskQueryBusinessFileClient.java
  5. 27 0
      blade-service-api/blade-e-visa-api/pom.xml
  6. 29 0
      blade-service-api/blade-e-visa-api/src/main/java/org/springblade/evisa/feign/EVisaClient.java
  7. 57 0
      blade-service-api/blade-e-visa-api/src/main/java/org/springblade/evisa/vo/EVisaMakeSealVO.java
  8. 66 0
      blade-service-api/blade-e-visa-api/src/main/java/org/springblade/evisa/vo/EVisaTaskApprovalVO.java
  9. 28 27
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/MakeSealDTO.java
  10. 22 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/feign/SignPfxClient.java
  11. 1 0
      blade-service-api/pom.xml
  12. 1 6
      blade-service/blade-business/src/main/java/org/springblade/business/controller/ArchiveFileController.java
  13. 6 0
      blade-service/blade-business/src/main/java/org/springblade/business/controller/DefaultConfigController.java
  14. 1 1
      blade-service/blade-business/src/main/java/org/springblade/business/controller/ImageClassificationFileController.java
  15. 6 38
      blade-service/blade-business/src/main/java/org/springblade/business/controller/TaskController.java
  16. 51 0
      blade-service/blade-business/src/main/java/org/springblade/business/feignClient/TaskQueryBusinessFileClientImpl.java
  17. 2 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/DefaultConfigMapper.xml
  18. 0 13
      blade-service/blade-business/src/main/java/org/springblade/business/utils/FileUtils.java
  19. 52 0
      blade-service/blade-e-visa/pom.xml
  20. 19 0
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/EVisaApplication.java
  21. 24 0
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/feign/EVisaClientImpl.java
  22. 23 0
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/redissionUtil/DistributedLock.java
  23. 100 0
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/redissionUtil/DistributedLockAspect.java
  24. 118 0
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/redissionUtil/DistributedRedisLock.java
  25. 28 0
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/redissionUtil/RedissonManager.java
  26. 18 0
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/service/EVisaService.java
  27. 175 0
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/service/impl/EVisaServiceImpl.java
  28. 14 0
      blade-service/blade-e-visa/src/main/resources/application-dev.yml
  29. 10 0
      blade-service/blade-e-visa/src/main/resources/application-prod.yml
  30. 10 0
      blade-service/blade-e-visa/src/main/resources/application-test.yml
  31. 12 0
      blade-service/blade-manager/pom.xml
  32. 29 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/feign/SignPfxClientImpl.java
  33. 49 5
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/SignPfxFileServiceImpl.java
  34. 1 0
      pom.xml

+ 23 - 0
blade-common/src/main/java/org/springblade/common/constant/EVisaConstant.java

@@ -0,0 +1,23 @@
+package org.springblade.common.constant;
+
+public interface EVisaConstant {
+
+    String APPLICATION_WEATHER_NAME = "blade-e-visa";
+
+    /**
+     * 电签签章命名规则
+     */
+    String SIGN_SEAL_CODE = "S_NEW_";
+    String SIGN_SEAL_NAME = "N_NEW_";
+    String SIGN_SEAL_CODE_VIEW = "SW_NEW_";
+    String SIGN_SEAL_NAME_VIEW = "NW_NEW_";
+    Integer USER_ID_SUB = 16;
+
+    //机构编号
+    String organizationCode ="002";
+    //操作员编码
+    String operationCode = "gy003";
+    //渠道编码
+    String channelCode = "c001";
+
+}

+ 14 - 2
blade-common/src/main/java/org/springblade/common/utils/CommonUtil.java

@@ -3,8 +3,7 @@ package org.springblade.common.utils;
 import cn.hutool.core.io.FileUtil;
 import org.apache.commons.lang.StringUtils;
 
-import java.io.File;
-import java.io.InputStream;
+import java.io.*;
 import java.math.BigDecimal;
 import java.net.HttpURLConnection;
 import java.net.URL;
@@ -86,6 +85,19 @@ public class CommonUtil {
         return conn.getInputStream();
     }
 
+    /**
+     * 获取字节数组
+     */
+    public static byte[] InputStreamToBytes(InputStream is) throws IOException {
+        BufferedInputStream bis = new BufferedInputStream(is);
+        ByteArrayOutputStream os = new ByteArrayOutputStream();
+        int date = -1;
+        while ((date = bis.read()) != -1) {
+            os.write(date);
+        }
+        return os.toByteArray();
+    }
+
     /**
      * 随机生成短信验证码
      * @param length 生成长度

+ 13 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/DefaultConfig.java

@@ -68,4 +68,17 @@ public class DefaultConfig extends BaseEntity {
      */
     @ApiModelProperty("电签短信验证超时时间")
     private String smsTimeOut;
+
+    /**
+     * 截图方式
+     */
+    @ApiModelProperty("截图方式")
+    private String shotWebRtc;
+
+    /**
+     * 全屏截图
+     */
+    @ApiModelProperty("全屏截图")
+    private String fullScreen;
+
 }

+ 20 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/feign/TaskQueryBusinessFileClient.java

@@ -0,0 +1,20 @@
+package org.springblade.business.feign;
+
+import org.springblade.business.vo.TaskApprovalVO;
+import org.springblade.common.constant.BusinessConstant;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+
+@FeignClient(value = BusinessConstant.APPLICATION_WEATHER_NAME)
+public interface TaskQueryBusinessFileClient {
+
+    /**
+     * 接口前缀
+     */
+    String API_PREFIX = "/api/business/taskQueryBusiness";
+
+    @GetMapping(API_PREFIX + "/queryBusinessData")
+    TaskApprovalVO queryBusinessData(@RequestBody TaskApprovalVO taskApprovalVO);
+
+}

+ 27 - 0
blade-service-api/blade-e-visa-api/pom.xml

@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>blade-service-api</artifactId>
+        <groupId>org.springblade</groupId>
+        <version>2.9.1.RELEASE</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>blade-e-visa-api</artifactId>
+    <name>${project.artifactId}</name>
+    <version>${bladex.project.version}</version>
+    <dependencies>
+        <dependency>
+            <groupId>org.springblade</groupId>
+            <artifactId>blade-common</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springblade</groupId>
+            <artifactId>blade-common</artifactId>
+        </dependency>
+    </dependencies>
+    <packaging>jar</packaging>
+
+</project>

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

@@ -0,0 +1,29 @@
+package org.springblade.evisa.feign;
+
+import org.springblade.common.constant.EVisaConstant;
+import org.springblade.evisa.vo.EVisaMakeSealVO;
+import org.springblade.evisa.vo.EVisaTaskApprovalVO;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.PostMapping;
+
+@FeignClient(value = EVisaConstant.APPLICATION_WEATHER_NAME)
+public interface EVisaClient {
+
+    /**
+     * 接口前缀
+     */
+    String API_PREFIX = "/api/e_visa";
+
+    /**
+     * 电签
+     */
+    @PostMapping(API_PREFIX + "/eVisa")
+    void eVisa(EVisaTaskApprovalVO task);
+
+    /**
+     * 创建印模
+     */
+    @PostMapping(API_PREFIX + "/createSeal")
+    String createSeal(EVisaMakeSealVO vo);
+
+}

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

@@ -0,0 +1,57 @@
+package org.springblade.evisa.vo;
+
+import lombok.Data;
+
+@Data
+public class EVisaMakeSealVO {
+
+    /**
+     * 签名文件
+     */
+    private String imageUrl;
+
+    /**
+     * 证书文件
+     */
+    private String pfxFileUrl;
+
+    /**
+     * 证书密码
+     */
+    private String pfxPassword;
+
+    /**
+     * 1:个人 2:企业
+     */
+    private String customerType = "1";
+
+    /**
+     * seal码
+     */
+    private String sealCode;
+
+    /**
+     * seal密码
+     */
+    private String sealPassword;
+
+    /**
+     * seal名
+     */
+    private String sealName;
+
+    /**
+     * 用户名
+     */
+    private String userName;
+
+    private String idType;
+
+    /**
+     * 身份证号
+     */
+    private String idNumber;
+
+    private String operationCode = "gy003";
+
+}

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

@@ -0,0 +1,66 @@
+package org.springblade.evisa.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class EVisaTaskApprovalVO {
+
+    /**
+     * 待审批列表中(TaskVO)对应的taskId字段值
+     */
+    @ApiModelProperty("待审批列表中对应的taskId字段值")
+    private String taskId;
+
+    /**
+     * 待审批列表中(TaskVO)对应的parallelProcessInstanceId字段值
+     */
+    @ApiModelProperty("待审批列表中对应的parallelProcessInstanceId字段值")
+    private String parallelProcessInstanceId;
+
+    @ApiModelProperty("数据源")
+    private String formDataId;
+
+    @ApiModelProperty("上报类型")
+    private Integer approvalType;
+
+    @ApiModelProperty("审批意见")
+    private String comment;
+
+    @ApiModelProperty("同意传OK(大写),废除可传非OK外任意字符或传空")
+    private String flag;
+
+    @ApiModelProperty("批量审批")
+    private String taskIds;
+
+    @ApiModelProperty("附件信息")
+    private List<ApprovalFile> approvalFileList = new ArrayList<>();
+
+    public void setApprovalFileList(String fileName, String fileUrl){
+        this.approvalFileList.add(new ApprovalFile(fileName, fileUrl));
+    }
+
+    @Data
+    public class ApprovalFile {
+
+        private String fileName;
+
+        private String fileUrl;
+
+        public ApprovalFile(String fileName, String fileUrl){
+            this.fileName = fileName;
+            this.fileUrl = fileUrl;
+        }
+
+    }
+
+    /**
+     * 获取是否通过
+     */
+    public boolean isPass() {
+        return "OK".equals(flag) || "同意".equals(comment);
+    }
+
+}

+ 28 - 27
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/MakeSealDTO.java

@@ -5,51 +5,52 @@ import lombok.Data;
 @Data
 public class MakeSealDTO {
 
-    //image地址
+    /**
+     * 签名文件
+     */
     private String imageUrl;
 
-    //证书文件地址
+    /**
+     * 证书文件
+     */
     private String pfxFileUrl;
 
-    //证书文件密码
+    /**
+     * 证书密码
+     */
     private String pfxPassword;
 
-    //1:个人 2:企业
+    /**
+     * 1:个人 2:企业
+     */
     private String customerType = "1";
 
-    // 构造seal码
+    /**
+     * seal码
+     */
     private String sealCode;
 
-    // 构造seal密码
+    /**
+     * seal密码
+     */
     private String sealPassword;
 
-    // 构造seal名
+    /**
+     * seal名
+     */
     private String sealName;
 
-    //签章名称
+    /**
+     * 用户名
+     */
     private String userName;
 
-    //签章名称  IdType.JUMINSHENFENZHENG.getCode()
     private String idType;
 
-    //签章名称
-    private String idNo;
+    /**
+     * 身份证号
+     */
+    private String idNumber;
 
     private String operationCode = "gy003";
-
-    @Override
-    public String toString() {
-        return "MakeSealDto{" +
-                "imageUrl='" + imageUrl + '\'' +
-                ", pfxFileUrl='" + pfxFileUrl + '\'' +
-                ", pfxPassword='" + pfxPassword + '\'' +
-                ", customerType='" + customerType + '\'' +
-                ", sealCode='" + sealCode + '\'' +
-                ", sealPassword='" + sealPassword + '\'' +
-                ", sealName='" + sealName + '\'' +
-                ", userName='" + userName + '\'' +
-                ", idType='" + idType + '\'' +
-                ", idNo='" + idNo + '\'' +
-                '}';
-    }
 }

+ 22 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/feign/SignPfxClient.java

@@ -0,0 +1,22 @@
+package org.springblade.manager.feign;
+
+import org.springblade.manager.entity.SignPfxFile;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import java.util.List;
+
+import static org.springblade.core.launch.constant.AppConstant.APPLICATION_NAME_PREFIX;
+
+@FeignClient(value = APPLICATION_NAME_PREFIX + "manager")
+public interface SignPfxClient {
+
+    /**
+     * 接口前缀
+     */
+    String API_PREFIX = "/api/manager/signPfx";
+
+    @GetMapping(API_PREFIX + "/querySignPfxByUserIdOrContractId")
+    List<SignPfxFile> querySignPfxByUserIdOrContractId(@RequestParam String userId, @RequestParam String contractId);
+
+}

+ 1 - 0
blade-service-api/pom.xml

@@ -23,6 +23,7 @@
         <module>blade-user-api</module>
         <module>blade-business-api</module>
         <module>blade-manager-api</module>
+        <module>blade-e-visa-api</module>
     </modules>
 
     <dependencies>

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

@@ -13,8 +13,6 @@ import org.apache.commons.lang.StringUtils;
 import org.springblade.business.entity.Task;
 import org.springblade.business.feign.OperationLogClient;
 import org.springblade.business.feign.TaskClient;
-import org.springblade.business.service.IArchiveShowService;
-import org.springblade.business.utils.FileUtils;
 import org.springblade.business.vo.ArchiveTaskVO;
 import org.springblade.business.vo.TaskVO;
 import org.springblade.common.utils.CommonUtil;
@@ -34,7 +32,6 @@ import org.springblade.core.boot.ctrl.BladeController;
 
 import javax.servlet.http.HttpServletResponse;
 import java.io.BufferedOutputStream;
-import java.io.ByteArrayOutputStream;
 import java.io.DataOutputStream;
 import java.io.InputStream;
 import java.net.URLEncoder;
@@ -57,8 +54,6 @@ public class ArchiveFileController extends BladeController {
 
 	private final IArchiveFileService archiveFileService;
 
-	private final IArchiveShowService archiveShowService;
-
 	private final ArchiveTreeClient archiveTreeClient;
 
 	private final TaskClient taskClient;
@@ -114,7 +109,7 @@ public class ArchiveFileController extends BladeController {
 							//获取文件流
 							inputStream = CommonUtil.getOSSInputStream(file.getFileUrl());
 							//转换
-							byte[] bytes = FileUtils.InputStreamToBytes(inputStream);
+							byte[] bytes = CommonUtil.InputStreamToBytes(inputStream);
 
 							String suffix = file.getFileUrl().substring(file.getFileUrl().lastIndexOf("."));
 							zipos.putNextEntry(new ZipEntry(file.getFileName()+suffix));

+ 6 - 0
blade-service/blade-business/src/main/java/org/springblade/business/controller/DefaultConfigController.java

@@ -61,6 +61,12 @@ public class DefaultConfigController extends BladeController {
 			if(StringUtils.isNotEmpty(newConfig.getTheme())){
 				oldConfig.setTheme(newConfig.getTheme());
 			}
+			if(StringUtils.isNotEmpty(newConfig.getShotWebRtc())){
+				oldConfig.setShotWebRtc(newConfig.getShotWebRtc());
+			}
+			if(StringUtils.isNotEmpty(newConfig.getFullScreen())){
+				oldConfig.setFullScreen(newConfig.getFullScreen());
+			}
 			oldConfig.setOpinionView(newConfig.getOpinionView());
 			return R.data(this.defaultConfigService.updateById(oldConfig));
 		}

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

@@ -131,7 +131,7 @@ public class ImageClassificationFileController extends BladeController {
 									anchor.setCol1(0);
 
 									//创建图片
-									drawing.createPicture(anchor, workbook.addPicture(FileUtils.InputStreamToBytes(CommonUtil.getOSSInputStream(uri)), Workbook.PICTURE_TYPE_PNG));
+									drawing.createPicture(anchor, workbook.addPicture(CommonUtil.InputStreamToBytes(CommonUtil.getOSSInputStream(uri)), Workbook.PICTURE_TYPE_PNG));
 									//图片定位
 									FileUtils.imageOrientation(sheet, anchor, new DataVO(0, 0));
 

+ 6 - 38
blade-service/blade-business/src/main/java/org/springblade/business/controller/TaskController.java

@@ -15,6 +15,7 @@ import org.jetbrains.annotations.NotNull;
 import org.springblade.business.entity.ArchiveFile;
 import org.springblade.business.entity.DefaultConfig;
 import org.springblade.business.entity.TaskParallel;
+import org.springblade.business.feign.TaskQueryBusinessFileClient;
 import org.springblade.business.service.IArchiveFileService;
 import org.springblade.business.service.IDefaultConfigService;
 import org.springblade.business.service.ITaskParallelService;
@@ -72,12 +73,12 @@ public class TaskController extends BladeController {
 
 	private final NewISmsClient newSmsClient;
 
-	private final IArchiveFileService archiveFileService;
-
 	private final NewIOSSClient newIOSSClient;
 
 	private final IDefaultConfigService defaultConfigService;
 
+	private final TaskQueryBusinessFileClient taskQueryBusinessFileClient;
+
 	/**
 	 * 校验电签短信验证码
 	 */
@@ -120,7 +121,7 @@ public class TaskController extends BladeController {
 		result.setFormDataId(formDataId);
 		result.setApprovalType(approvalType);
 
-		TaskApprovalVO vo = this.queryBusinessData(result);
+		TaskApprovalVO vo = this.taskQueryBusinessFileClient.queryBusinessData(result);
 		//所有文件集合
 		List<String> urlList = new ArrayList<>();
 		if(vo != null && vo.getApprovalFileList().size() > 0){
@@ -331,7 +332,7 @@ public class TaskController extends BladeController {
 		vo.setApprovalType(approvalType);
 
 		////获取具体业务数据
-		vo = this.queryBusinessData(vo);
+		vo = this.taskQueryBusinessFileClient.queryBusinessData(vo);
 
 		return R.data(vo);
 	}
@@ -487,7 +488,7 @@ public class TaskController extends BladeController {
 	@ApiOperation(value = "完成/审批任务")
 	public R<Boolean> completeApprovalTask(@RequestBody TaskApprovalVO taskApprovalVO){
 		//工程文件
-		TaskApprovalVO archiveFileVO = this.queryBusinessData(taskApprovalVO);
+		TaskApprovalVO archiveFileVO = this.taskQueryBusinessFileClient.queryBusinessData(taskApprovalVO);
 		if(archiveFileVO != null){
 			//获取相关联的pdf
 			taskApprovalVO.setApprovalFileList(archiveFileVO.getApprovalFileList());
@@ -506,37 +507,4 @@ public class TaskController extends BladeController {
 		return this.taskService.startApproval(taskVO) ? R.data(200, true, "操作成功") : R.data(200, false, "操作失败,请联系管理员");
 	}
 
-	/**
-	 * 查询业务数据对外接口
-	 * @param taskApprovalVO 上报信息
-	 */
-	private TaskApprovalVO queryBusinessData(TaskApprovalVO taskApprovalVO){
-		switch (taskApprovalVO.getApprovalType()){
-			case 1:
-				//填报数据
-				return null;
-			case 2:
-				//工程文件
-				return this.queryArchiveFileBusinessData(taskApprovalVO.getFormDataId());
-			default:
-				return null;
-		}
-	}
-
-	/**
-	 * 查询工程文件
-	 */
-	private TaskApprovalVO queryArchiveFileBusinessData(String formDataId){
-		List<ArchiveFile> archiveFileList = this.archiveFileService.list(Wrappers.<ArchiveFile>lambdaQuery().in(ArchiveFile::getId, Arrays.asList(formDataId.split(","))).eq(ArchiveFile::getIsDeleted, 0));
-		if(archiveFileList != null && archiveFileList.size() > 0){
-			//转换数据
-			TaskApprovalVO vo = new TaskApprovalVO();
-			for(ArchiveFile archiveFile : archiveFileList){
-				vo.setApprovalFileList(archiveFile.getFileName(), StringUtils.isEmpty(archiveFile.getPdfFileUrl()) ? archiveFile.getFileUrl() : archiveFile.getPdfFileUrl());
-			}
-			return vo;
-		}
-		return null;
-	}
-
 }

+ 51 - 0
blade-service/blade-business/src/main/java/org/springblade/business/feignClient/TaskQueryBusinessFileClientImpl.java

@@ -0,0 +1,51 @@
+package org.springblade.business.feignClient;
+
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import lombok.AllArgsConstructor;
+import org.apache.commons.lang.StringUtils;
+import org.springblade.business.entity.ArchiveFile;
+import org.springblade.business.feign.TaskQueryBusinessFileClient;
+import org.springblade.business.service.IArchiveFileService;
+import org.springblade.business.vo.TaskApprovalVO;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Arrays;
+import java.util.List;
+
+@RestController
+@AllArgsConstructor
+public class TaskQueryBusinessFileClientImpl implements TaskQueryBusinessFileClient {
+
+    private final IArchiveFileService archiveFileService;
+
+    @Override
+    public TaskApprovalVO queryBusinessData(TaskApprovalVO taskApprovalVO) {
+        switch (taskApprovalVO.getApprovalType()){
+            case 1:
+                //填报数据
+                return null;
+            case 2:
+                //工程文件
+                return this.queryArchiveFileBusinessData(taskApprovalVO.getFormDataId());
+            default:
+                return null;
+        }
+    }
+
+    /**
+     * 查询工程文件
+     */
+    private TaskApprovalVO queryArchiveFileBusinessData(String formDataId){
+        List<ArchiveFile> archiveFileList = this.archiveFileService.list(Wrappers.<ArchiveFile>lambdaQuery().in(ArchiveFile::getId, Arrays.asList(formDataId.split(","))).eq(ArchiveFile::getIsDeleted, 0));
+        if(archiveFileList != null && archiveFileList.size() > 0){
+            //转换数据
+            TaskApprovalVO vo = new TaskApprovalVO();
+            for(ArchiveFile archiveFile : archiveFileList){
+                vo.setApprovalFileList(archiveFile.getFileName(), StringUtils.isEmpty(archiveFile.getPdfFileUrl()) ? archiveFile.getFileUrl() : archiveFile.getPdfFileUrl());
+            }
+            return vo;
+        }
+        return null;
+    }
+
+}

+ 2 - 0
blade-service/blade-business/src/main/java/org/springblade/business/mapper/DefaultConfigMapper.xml

@@ -18,6 +18,8 @@
         <result column="opinion_view" property="opinionView"/>
         <result column="sms_code" property="smsCode"/>
         <result column="sms_time_out" property="smsTimeOut"/>
+        <result column="shot_web_rtc" property="shotWebRtc"/>
+        <result column="full_screen" property="fullScreen"/>
     </resultMap>
 
 </mapper>

+ 0 - 13
blade-service/blade-business/src/main/java/org/springblade/business/utils/FileUtils.java

@@ -110,19 +110,6 @@ public class FileUtils {
         return -1;
     }
 
-    /**
-     * 获取字节数组
-     */
-    public static byte[] InputStreamToBytes(InputStream is) throws IOException {
-        BufferedInputStream bis = new BufferedInputStream(is);
-        ByteArrayOutputStream os = new ByteArrayOutputStream();
-        int date = -1;
-        while ((date = bis.read()) != -1) {
-            os.write(date);
-        }
-        return os.toByteArray();
-    }
-
     /**
      * 合并方法
      */

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

@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>BladeX</artifactId>
+        <groupId>org.springblade</groupId>
+        <version>2.9.1.RELEASE</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>blade-e-visa</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.springblade</groupId>
+            <artifactId>blade-core-boot</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springblade</groupId>
+            <artifactId>blade-starter-swagger</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springblade</groupId>
+            <artifactId>blade-e-visa-api</artifactId>
+            <version>${bladex.project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springblade</groupId>
+            <artifactId>blade-core-cloud</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>log4j</groupId>
+            <artifactId>log4j</artifactId>
+            <version>1.2.17</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springblade</groupId>
+            <artifactId>blade-business-api</artifactId>
+            <version>2.9.1.RELEASE</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.springblade</groupId>
+            <artifactId>blade-manager-api</artifactId>
+            <version>2.9.1.RELEASE</version>
+            <scope>compile</scope>
+        </dependency>
+    </dependencies>
+
+</project>

+ 19 - 0
blade-service/blade-e-visa/src/main/java/org/springblade/evisa/EVisaApplication.java

@@ -0,0 +1,19 @@
+package org.springblade.evisa;
+
+import org.springblade.common.constant.EVisaConstant;
+import org.springblade.core.cloud.feign.EnableBladeFeign;
+import org.springblade.core.launch.BladeApplication;
+import org.springframework.cloud.client.SpringCloudApplication;
+
+/**
+ * 电签服务启动类
+ */
+@EnableBladeFeign
+@SpringCloudApplication
+public class EVisaApplication {
+
+    public static void main(String[] args){
+        BladeApplication.run(EVisaConstant.APPLICATION_WEATHER_NAME, EVisaApplication.class, args);
+    }
+
+}

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

@@ -0,0 +1,24 @@
+package org.springblade.evisa.feign;
+
+import lombok.AllArgsConstructor;
+import org.springblade.evisa.service.EVisaService;
+import org.springblade.evisa.vo.EVisaMakeSealVO;
+import org.springblade.evisa.vo.EVisaTaskApprovalVO;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@AllArgsConstructor
+public class EVisaClientImpl implements EVisaClient {
+
+    private final EVisaService eVisaService;
+
+    @Override
+    public void eVisa(EVisaTaskApprovalVO task) {
+        this.eVisaService.eVisa(task);
+    }
+
+    @Override
+    public String createSeal(EVisaMakeSealVO vo) {
+        return this.eVisaService.createSeal(vo);
+    }
+}

+ 23 - 0
blade-service/blade-e-visa/src/main/java/org/springblade/evisa/redissionUtil/DistributedLock.java

@@ -0,0 +1,23 @@
+package org.springblade.evisa.redissionUtil;
+
+import java.lang.annotation.*;
+
+
+/**
+* @author zhifk
+* @version 创建时间:2021-08-09
+* operteContent() 
+* 锁注解
+*/
+
+@Target({ElementType.PARAMETER,ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface DistributedLock {
+   //分布式锁的关键字
+   String lockKey() default "NONE";
+   //提示信息
+   String tip() default "正在操作中";
+   //锁存在的时间
+   String datetime() default "180";
+}

+ 100 - 0
blade-service/blade-e-visa/src/main/java/org/springblade/evisa/redissionUtil/DistributedLockAspect.java

@@ -0,0 +1,100 @@
+package org.springblade.evisa.redissionUtil;
+
+//import cn.com.smart.utils.ArchivesLogAspect;
+//import cn.com.smart.utils.LogAopUtil;
+import com.alibaba.fastjson.JSONArray;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.Signature;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Pointcut;
+import org.aspectj.lang.reflect.MethodSignature;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.lang.reflect.Method;
+
+
+/**
+ *
+ * @Description:操作日志aop
+ * @author:chenfei
+ * @time:2020年3月12日 下午3:54:01
+ * @version 1.0
+ */
+
+public class DistributedLockAspect {
+
+    private static final Logger logger = LoggerFactory.getLogger(DistributedLockAspect.class);
+
+    @Pointcut("@annotation(DistributedLock)")
+    public void distributedControllerAspect() {
+        System.out.println("切入点...");
+    }
+
+    @Around("distributedControllerAspect()")
+    public Object around(ProceedingJoinPoint pjp) throws Throwable {
+//        // 拦截的实体类,就是当前正在执行的controller
+//        Object target = pjp.getTarget();
+//        // 拦截的方法名称。当前正在执行的方法
+//        String methodName = pjp.getSignature().getName();
+//        // 拦截的方法参数
+//        Object[] args = pjp.getArgs();
+//
+//        // 获取参数名称和值
+//        String classType = pjp.getTarget().getClass().getName();
+//        Class<?> clazz = Class.forName(classType);
+//        String clazzName = clazz.getName();
+//
+//        JSONArray operateParamArray = LogAopUtil.getNameAndArgs(ArchivesLogAspect.class, clazzName, methodName, args);
+//        //  logger.info("请求类方法参数名称和值:" + operateParamArray.toString());
+//
+//        //设置请求参数
+////       log.setOperateParams(operateParamArray.toJSONString());
+//        // 拦截的放参数类型
+//        Signature sig = pjp.getSignature();
+//        MethodSignature msig = null;
+//        if (!(sig instanceof MethodSignature)) {
+//            throw new IllegalArgumentException("该注解只能用于方法");
+//        }
+//        msig = (MethodSignature) sig;
+//
+//        Class[] parameterTypes = msig.getMethod().getParameterTypes();
+//        Object object = null;
+//        // 获得被拦截的方法
+//        Method method = null;
+//        try {
+//            method = target.getClass().getMethod(methodName, parameterTypes);
+//        } catch (NoSuchMethodException e1) {
+////            logger.error("ControllerLogAopAspect around error",e1);
+//        } catch (SecurityException e1) {
+////            logger.error("ControllerLogAopAspect around error",e1);
+//        }
+//
+//        if (null != method) {
+//            if (method.isAnnotationPresent(DistributedLock.class)) {
+//                DistributedLock systemlog = method.getAnnotation(DistributedLock.class);
+//                boolean getlockstatus = DistributedRedisLock.getlockstatus(systemlog.lockKey());
+//                if(!getlockstatus){
+//                    DistributedRedisLock.acquire(systemlog.lockKey(), Integer.parseInt(systemlog.datetime()));
+//                }
+//                try {
+//                    if(!getlockstatus) {
+//                        //执行页面请求模块方法,并返回
+//                        object = pjp.proceed();
+//                        DistributedRedisLock.release(systemlog.lockKey());
+//                    }
+//                } catch (Throwable e) {
+//
+//                }
+//            }
+//            else {
+//                //没有包含注解
+//                object = pjp.proceed();
+//            }
+//        } else {
+//            //不需要拦截直接执行
+//            object = pjp.proceed();
+//        }
+        return null;
+    }
+}

+ 118 - 0
blade-service/blade-e-visa/src/main/java/org/springblade/evisa/redissionUtil/DistributedRedisLock.java

@@ -0,0 +1,118 @@
+package org.springblade.evisa.redissionUtil;
+
+import com.alibaba.csp.sentinel.util.StringUtil;
+import org.apache.log4j.Logger;
+import org.redisson.Redisson;
+import org.redisson.api.RLock;
+import org.redisson.api.RSet;
+import org.redisson.config.Config;
+import org.springframework.stereotype.Component;
+
+import java.util.Date;
+import java.util.concurrent.TimeUnit;
+
+@Component
+public class DistributedRedisLock {
+
+    private static final Logger _log = Logger.getLogger(DistributedRedisLock.class);
+
+    private static final Config config = new Config();
+
+    private static final String LOCK_TITLE = "redisLock_";
+
+    /**
+     * 加锁
+     */
+    public static boolean acquire(String lockName,Integer time){
+        //声明key对象
+        String key = LOCK_TITLE + lockName;
+        //获取锁对象
+        RLock myLock = getRedisson().getLock(key);
+        //加锁,并且设置锁过期时间,防止死锁的产生
+        if(time == null || time == 0){
+            time = 180;
+        }
+        _log.info("======lock==="+lockName+"===" + time + "=="+new Date() +"=="+Thread.currentThread().getName());
+        myLock.lock(time, TimeUnit.SECONDS);
+        _log.info("======lock==="+lockName+"===" + time + "=="+new Date() +"=="+Thread.currentThread().getName());
+        //加锁成功
+        return true;
+    }
+
+    /**
+     * 锁的释放
+     */
+    public static void release(String lockName){
+        //必须是和加锁时的同一个key
+        try {
+            String key = LOCK_TITLE + lockName;
+            //获取所对象
+            RLock myLock = getRedisson().getLock(key);
+            if(myLock != null && myLock.isHeldByCurrentThread()){
+                //释放锁(解锁)
+                myLock.unlock();
+                _log.info("======unlock==="+lockName+"======"+Thread.currentThread().getName());
+            }
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 判断锁是否存在
+     */
+    public static boolean getLockStatus(String lockName){
+        try {
+            String key = LOCK_TITLE + lockName;
+            //获取所对象
+            RLock myLock = getRedisson().getLock(key);
+            if(myLock != null && myLock.isLocked()){
+                System.err.println("======判断锁是否存在======"+Thread.currentThread().getName());
+                return true;
+            }
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return  false;
+    }
+    /**
+     * 存入分布式set对象中
+     */
+    public static RSet<String> setSet(String name, String value){
+        RSet<String> set = getRedisson().getSet(name);
+        set.add(value);
+        return  set;
+    }
+    /**
+     * 分布式set对象中删除
+     */
+    public static RSet<String> removeSet(String name, String value){
+        RSet<String> set = getRedisson().getSet(name);
+        set.remove(value);
+        return  set;
+    }
+    /**
+     * 检查分布式对象是否存在
+     */
+    public static Boolean existSet(String name){
+        RSet<String> set = getRedisson().getSet(name);
+        if (!set.isEmpty()) {
+            return  true;
+        }
+        return  false;
+    }
+
+    private static Redisson getRedisson(){
+        config.useSingleServer()
+                .setAddress("" + RedissonManager.SPRING_REDIS_HOST + ":" + RedissonManager.SPRING_REDIS_PORT)
+                .setConnectionPoolSize(500);
+        if (StringUtil.isNotEmpty(RedissonManager.SPRING_REDIS_PASSWORD)) {
+            config.useSingleServer().setPassword(RedissonManager.SPRING_REDIS_PASSWORD);
+        }
+        return (Redisson) Redisson.create(config);
+    }
+
+}
+

+ 28 - 0
blade-service/blade-e-visa/src/main/java/org/springblade/evisa/redissionUtil/RedissonManager.java

@@ -0,0 +1,28 @@
+package org.springblade.evisa.redissionUtil;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+@Component
+public class RedissonManager {
+
+    public static String SPRING_REDIS_HOST;
+    public static String SPRING_REDIS_PORT;
+    public static String SPRING_REDIS_PASSWORD;
+
+    @Value("${spring.redis.host}")
+    public void getSpringRedisHost(String host) {
+        RedissonManager.SPRING_REDIS_HOST = host;
+    }
+
+    @Value("${spring.redis.port}")
+    public void getSpringRedisPort(String port) {
+        RedissonManager.SPRING_REDIS_PORT = port;
+    }
+
+    @Value("${spring.redis.password}")
+    public void getSpringRedisPassword(String password) {
+        RedissonManager.SPRING_REDIS_PASSWORD = password;
+    }
+}
+

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

@@ -0,0 +1,18 @@
+package org.springblade.evisa.service;
+
+import org.springblade.evisa.vo.EVisaMakeSealVO;
+import org.springblade.evisa.vo.EVisaTaskApprovalVO;
+
+public interface EVisaService {
+
+    /**
+     * 电签
+     */
+    void eVisa(EVisaTaskApprovalVO task);
+
+    /**
+     * 创建印模
+     */
+    String createSeal(EVisaMakeSealVO makeSealDto);
+
+}

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

@@ -0,0 +1,175 @@
+package org.springblade.evisa.service.impl;
+
+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.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.request.requestbody.tx20.MakeSealRequestBody;
+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.tx20.MakeSealResponse;
+import com.alibaba.fastjson.JSONObject;
+import lombok.AllArgsConstructor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springblade.business.feign.TaskQueryBusinessFileClient;
+import org.springblade.business.vo.TaskApprovalVO;
+import org.springblade.common.constant.EVisaConstant;
+import org.springblade.common.utils.CommonUtil;
+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.manager.entity.SignPfxFile;
+import org.springblade.manager.feign.SignPfxClient;
+import org.springframework.stereotype.Service;
+import java.util.List;
+
+@Service
+@AllArgsConstructor
+public class EVisaServiceImpl implements EVisaService {
+
+    private static final Logger logger = LoggerFactory.getLogger(EVisaServiceImpl.class);
+
+    private final SignPfxClient signPfxClient;
+
+    private final TaskQueryBusinessFileClient taskQueryBusinessFileClient;
+
+    @Override
+    public void eVisa(EVisaTaskApprovalVO task) {
+        //todo 这里应当是配置限制参数,初版暂时写死
+        int batch = 20;
+
+        //首先获取当前用户的证书信息
+        List<SignPfxFile> userPfxList = this.signPfxClient.querySignPfxByUserIdOrContractId(AuthUtil.getUserId().toString(), "");
+        if(userPfxList == null || userPfxList.size() <= 0){
+            //没有签章,不执行电签
+            return;
+        }
+
+        //根据任务类型获取对应的文件信息
+        TaskApprovalVO taskFile = this.taskQueryBusinessFileClient.queryBusinessData(JSONObject.parseObject(JSONObject.toJSONString(task), TaskApprovalVO.class));
+        if(taskFile == null || taskFile.getApprovalFileList().size() <= 0){
+            //没有找到业务文件,取消签章
+            return;
+        }
+
+        //上锁
+        if(DistributedRedisLock.acquire(AuthUtil.getUserId().toString(), batch)){
+
+        }
+
+    }
+
+    /**
+     * 签章
+     */
+    private boolean signPdf(){
+        StringBuffer stringbuffer = new StringBuffer();
+        try{
+            PaperlessClient paperlessClient = new PaperlessClient("host", "port", 3000, 20000);
+
+            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);
+            //*****************************************************************************
+
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+
+        return false;
+    }
+
+    @Override
+    public String createSeal(EVisaMakeSealVO vo) {
+        try{
+            PaperlessClient paperlessClient = new PaperlessClient("host", "port", 3000, 20000);
+            paperlessClient.setSSL(false);
+
+            // ------构造请求报文头------
+            // 请求报文头
+            RequestHead requestHeadBean = new RequestHead();
+            requestHeadBean.setTransactionNo(GUIDUtil.generateId());
+            requestHeadBean.setOrganizationCode(EVisaConstant.organizationCode);
+            requestHeadBean.setOperatorCode(EVisaConstant.operationCode);
+            // ------构造请求报文体------
+            //获取签字图片的字节数据
+            byte[] sealImage = CommonUtil.InputStreamToBytes(CommonUtil.getOSSInputStream(vo.getImageUrl()));
+            String sealImageString = Base64.encode(sealImage, ClientConstants.CHARACTER_ENCODING);
+
+            // 构造sealCert
+            SealCertBean sealCertBean = new SealCertBean(vo.getCustomerType());
+
+            // PFX文件数据
+            // 外部传入预先生成的PFX文件数据,需要保证前面的这些信息准确无误
+            byte[] pfxFileData = CommonUtil.InputStreamToBytes(CommonUtil.getOSSInputStream(vo.getPfxFileUrl()));
+            String pkcs12String = Base64.encode(pfxFileData, ClientConstants.CHARACTER_ENCODING);
+
+            //加密证书密码
+            String privateKeyPassword = vo.getPfxPassword();
+            String pkcs12Password = PwdEncryptUtil.encrypto(privateKeyPassword);
+
+            sealCertBean.setMakeSealWithPkcs12(pkcs12String, pkcs12Password, BaseConstants.KEY_ALG_RSA , BaseConstants.KEY_ALG_LENGTH_2048);
+            sealCertBean.setUserInfo(vo.getUserName(), vo.getIdType(), vo.getIdNumber());
+
+            // 构造sealInfo
+            SealInfoBean sealInfoBean = new SealInfoBean(vo.getSealCode(), PwdEncryptUtil.encrypto(vo.getSealPassword()), vo.getSealName());
+
+            // 请求报文体
+            MakeSealRequestBody requestBodyBean = new MakeSealRequestBody();
+            requestBodyBean.setSealImage(sealImageString);
+            requestBodyBean.setSealImageData(sealImage);
+            requestBodyBean.setSealCert(sealCertBean);
+            requestBodyBean.setSealInfo(sealInfoBean);
+
+            // ------构造请求报文对象------
+            MakeSealRequest requestBean = new MakeSealRequest();
+            requestBean.setHead(requestHeadBean);
+            requestBean.setBody(requestBodyBean);
+            logger.info("【电签模块】{}","创建印章请求Request:"+requestBean);
+            // ------调用接口------
+            ResponseDto responseDto = paperlessClient.execute(requestBean);
+
+            // 接收响应报文对象
+            MakeSealResponse responseBean = (MakeSealResponse) responseDto;
+            logger.info("【电签模块】{}","创建印章响应Response:"+requestBean);
+
+            // 响应报文头
+            ResponseHead responseHeadBean = responseBean.getHead();
+            // 响应报文体
+            MakeSealResponseBody responseBodyBean = responseBean.getBody();
+            logger.info("【电签模块】{}", "创建印章成功==========certDn: " + responseBodyBean.getCertDn() + " ; message: " + responseHeadBean.getMessage());
+            //请求结果
+            return responseHeadBean.getCode();
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+
+        return null;
+    }
+}

+ 14 - 0
blade-service/blade-e-visa/src/main/resources/application-dev.yml

@@ -0,0 +1,14 @@
+#服务器端口
+server:
+  port: 5678
+
+#数据源配置
+spring:
+  datasource:
+    url: ${blade.datasource.dev.url}
+    username: ${blade.datasource.dev.username}
+    password: ${blade.datasource.dev.password}
+  redis:
+    host: ${blade.spring.redis.host}
+    port: ${blade.spring.redis.port}
+    password: ${blade.spring.redis.password}

+ 10 - 0
blade-service/blade-e-visa/src/main/resources/application-prod.yml

@@ -0,0 +1,10 @@
+#服务器端口
+server:
+  port: 5399
+
+#数据源配置
+spring:
+  datasource:
+    url: ${blade.datasource.prod.url}
+    username: ${blade.datasource.prod.username}
+    password: ${blade.datasource.prod.password}

+ 10 - 0
blade-service/blade-e-visa/src/main/resources/application-test.yml

@@ -0,0 +1,10 @@
+#服务器端口
+server:
+  port: 5399
+
+#数据源配置
+spring:
+  datasource:
+    url: ${blade.datasource.test.url}
+    username: ${blade.datasource.test.username}
+    password: ${blade.datasource.test.password}

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

@@ -102,6 +102,18 @@
             <version>2.9.1.RELEASE</version>
             <scope>compile</scope>
         </dependency>
+        <dependency>
+            <groupId>org.springblade</groupId>
+            <artifactId>blade-e-visa-api</artifactId>
+            <version>2.9.1.RELEASE</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.springblade</groupId>
+            <artifactId>blade-e-visa-api</artifactId>
+            <version>2.9.1.RELEASE</version>
+            <scope>compile</scope>
+        </dependency>
 
 
     </dependencies>

+ 29 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/feign/SignPfxClientImpl.java

@@ -0,0 +1,29 @@
+package org.springblade.manager.feign;
+
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.mixsmart.utils.StringUtils;
+import lombok.AllArgsConstructor;
+import org.springblade.manager.entity.SignPfxFile;
+import org.springblade.manager.service.ISignPfxFileService;
+import org.springframework.web.bind.annotation.RestController;
+import java.util.List;
+
+@RestController
+@AllArgsConstructor
+public class SignPfxClientImpl implements SignPfxClient {
+
+    private final ISignPfxFileService signPfxFileService;
+
+    @Override
+    public List<SignPfxFile> querySignPfxByUserIdOrContractId(String userId, String contractId) {
+
+        if(StringUtils.isNotEmpty(userId)){
+            //查询个人章
+            return this.signPfxFileService.list(Wrappers.<SignPfxFile>lambdaQuery().eq(SignPfxFile::getCertificateUserId, userId));
+        } else if(StringUtils.isNotEmpty(contractId)){
+            //查询项目章
+            return this.signPfxFileService.list(Wrappers.<SignPfxFile>lambdaQuery().like(SignPfxFile::getProjectContractRole, contractId));
+        }
+        return null;
+    }
+}

+ 49 - 5
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/SignPfxFileServiceImpl.java

@@ -18,10 +18,14 @@ package org.springblade.manager.service.impl;
 
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
+import cfca.paperless.base.enums.IdType;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import lombok.AllArgsConstructor;
 import org.apache.commons.lang.StringUtils;
+import org.springblade.common.constant.EVisaConstant;
 import org.springblade.core.tool.api.R;
+import org.springblade.evisa.feign.EVisaClient;
+import org.springblade.evisa.vo.EVisaMakeSealVO;
 import org.springblade.manager.dto.MakeSealDTO;
 import org.springblade.manager.dto.SaveUserInfoByProjectDTO;
 import org.springblade.manager.entity.ProjectInfo;
@@ -37,7 +41,8 @@ import org.springblade.system.user.entity.User;
 import org.springblade.system.user.feign.IUserClient;
 import org.springframework.stereotype.Service;
 import com.baomidou.mybatisplus.core.metadata.IPage;
-
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import java.util.List;
 import java.util.stream.Collectors;
 
@@ -51,12 +56,16 @@ import java.util.stream.Collectors;
 @AllArgsConstructor
 public class SignPfxFileServiceImpl extends BaseServiceImpl<SignPfxFileMapper, SignPfxFile> implements ISignPfxFileService {
 
+	private static final Logger logger = LoggerFactory.getLogger(SignPfxFileServiceImpl.class);
+
 	private final IUserClient userClient;
 
 	private final IProjectInfoService projectInfoService;
 
 	private final SaveUserInfoByProjectService saveUserInfoByProjectService;
 
+	private final EVisaClient eVisaClient;
+
 	@Override
 	public IPage<SingPfxManagementVO> singPfxManagementPage(IPage<SingPfxManagementVO> page, SingPfxManagementVO vo) {
 		//获取项目列表
@@ -91,22 +100,57 @@ public class SignPfxFileServiceImpl extends BaseServiceImpl<SignPfxFileMapper, S
 
 			//判断是否存在个人签名文件
 			if(StringUtils.isNotEmpty(singPfx.getSignatureFileUrl()) && !"null".equals(singPfx.getSignatureFileUrl())){
-				if(!singPfx.getSignatureFileUrl().contains("png")){
-					return R.data(-1, false, "用户签名不是PNG图片");
+				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");
+				//签名文件
+				makeSeal.setImageUrl(singPfx.getSignatureFileUrl());
+				//居民身份证
+				makeSeal.setIdType(IdType.JUMINSHENFENZHENG.getCode());
+				//证书文件
+				makeSeal.setPfxFileUrl(singPfx.getCertificateFileUrl());
+				//证书密码
+				makeSeal.setPfxPassword(singPfx.getCertificatePassword());
+				//身份证号
+				makeSeal.setIdNumber(user.getIdNumber());
+				//构造seal码
+				makeSeal.setSealCode(EVisaConstant.SIGN_SEAL_CODE + user.getId());
+				//构建seal名
+				makeSeal.setSealName(EVisaConstant.SIGN_SEAL_NAME + user.getAccount());
+				makeSeal.setSealPassword(user.getId().toString().substring(0, EVisaConstant.USER_ID_SUB));
+				//注册印模
+				this.pfxMakeSeal(makeSeal, "个人签名印章", id.toString());
 			}
 
+		} else {
+
 		}
 
 		return null;
 	}
 
+	/**
+	 * 注册印模
+	 */
+	public void pfxMakeSeal(MakeSealDTO makeSeal, String msg, String pfxFileId){
+		try{
+			//调用接口创建印模
+			String resultCode = this.eVisaClient.createSeal(JSONObject.parseObject(JSONObject.toJSONString(makeSeal), EVisaMakeSealVO.class));
+			if(StringUtils.isNotEmpty(resultCode) && "1".equals(resultCode)){
+				logger.info("【电签模块】{}", "创建" + msg + "成功");
+				//修改状态为已注册
+				this.update(Wrappers.<SignPfxFile>lambdaUpdate().set(SignPfxFile::getIsRegister, 1).eq(SignPfxFile::getId, pfxFileId));
+			}
+		}catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+
 	@Override
 	public IPage<SignPfxFileVO> selectSignPfxFilePage(IPage<SignPfxFileVO> page, SignPfxFileVO vo) {
 		long current = (page.getCurrent() - 1L) * page.getSize();

+ 1 - 0
pom.xml

@@ -39,6 +39,7 @@
         <module>blade-plugin-api</module>
         <module>blade-service</module>
         <module>blade-service-api</module>
+        <module>blade-service/blade-e-visa</module>
     </modules>
 
     <dependencyManagement>