Browse Source

签字文件并发控制

huangjn 2 years ago
parent
commit
1e23c26eac

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

@@ -60,6 +60,8 @@ public interface CommonConstant {
 
 	String SYS_LOCAL_URL = "sys.local.url";
 
+	String SYS_USER_TASK_BATCH = "sys.user.task.batch";
+
 	/**
 	 * 默认排序字段
 	 */

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

@@ -137,7 +137,7 @@ public class CommonUtil {
      */
     public static boolean checkIsBigDecimal(Object value){
         try{
-            if(StringUtils.isNotEmpty(String.valueOf(value))){
+            if(value != null && StringUtils.isNotEmpty(String.valueOf(value))){
                 new BigDecimal(String.valueOf(value));
                 return true;
             } else {

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

@@ -25,7 +25,7 @@ public interface TaskClient {
     String START_TASK = API_PREFIX + "/start-task";
     String ABOLISH_TASK = API_PREFIX + "/abolish-task";
     String QUERY_FORM_DATA_ID = API_PREFIX + "/query-form-data-id";
-    String QUERY_BUSINESS_DATA = API_PREFIX + "/query-business-data";
+    String QUERY_BUSINESS_DATA_TASK = API_PREFIX + "/query-business-data-task";
     String QUERY_APPROVAL_USER = API_PREFIX + "/query-approval-user";
     String QUERY_BUSINESS_TABLE_E_VISA_CONFIG = API_PREFIX + "/query-business-table-E_VISA_CONFIG";
 
@@ -44,8 +44,8 @@ public interface TaskClient {
     /**
      * 获取业务数据
      */
-    @PostMapping(QUERY_BUSINESS_DATA)
-    TaskApprovalVO queryBusinessData(@RequestBody TaskApprovalVO taskApprovalVO);
+    @PostMapping(QUERY_BUSINESS_DATA_TASK)
+    TaskApprovalVO queryBusinessDataTask(@RequestBody TaskApprovalVO taskApprovalVO);
 
     /**
      * 根据数据源ID获取任务实例

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

@@ -17,6 +17,14 @@
             <groupId>org.springblade</groupId>
             <artifactId>blade-common</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.redisson</groupId>
+            <artifactId>redisson</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>log4j</groupId>
+            <artifactId>log4j</artifactId>
+        </dependency>
 
     </dependencies>
     <packaging>jar</packaging>

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


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


+ 1 - 4
blade-service/blade-e-visa/src/main/java/org/springblade/evisa/redissionUtil/DistributedRedisLock.java → blade-service-api/blade-e-visa-api/src/main/java/org/springblade/evisa/redissionUtil/DistributedRedisLock.java

@@ -1,14 +1,12 @@
 package org.springblade.evisa.redissionUtil;
 
-import com.alibaba.csp.sentinel.util.StringUtil;
+import jodd.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
@@ -66,7 +64,6 @@ public class DistributedRedisLock {
             //获取所对象
             RLock myLock = getRedisson().getLock(key);
             if(myLock != null && myLock.isLocked()){
-                System.err.println("======判断锁是否存在======"+Thread.currentThread().getName());
                 return true;
             }
 

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


+ 3 - 0
blade-service/blade-business/src/main/java/org/springblade/business/controller/InformationWriteQueryController.java

@@ -1401,6 +1401,9 @@ public class InformationWriteQueryController extends BladeController {
 				newData.setContractIdRelation(treeContract.getContractIdRelation());
 				newData.setContractType(treeContract.getContractType());
 				newData.setCreateTime(new Date());
+				if(half.getType() != null && new Integer("2").equals(half.getType())){
+					newData.setIsTypePrivatePid(half.getPKeyId());
+				}
 
 				//设置节点名称
 				for(AddContractTreeNodeVO.Node addVO : selectList){

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

@@ -68,8 +68,8 @@ public class TaskClientImpl implements TaskClient {
     }
 
     @Override
-    public TaskApprovalVO queryBusinessData(TaskApprovalVO taskApprovalVO) {
-        return this.taskService.queryBusinessData(taskApprovalVO);
+    public TaskApprovalVO queryBusinessDataTask(TaskApprovalVO taskApprovalVO) {
+        return this.taskService.queryBusinessDataTask(taskApprovalVO);
     }
 
     @Override

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

@@ -34,6 +34,11 @@ public interface ITaskService extends BaseService<Task> {
 
     List<TaskParallel> queryApprovalUser(String formDataIds);
 
+    /**
+     * 任务专用
+     */
+    TaskApprovalVO queryBusinessDataTask(TaskApprovalVO taskApprovalVO);
+
     TaskApprovalVO queryBusinessData(TaskApprovalVO taskApprovalVO);
 
     List<Task> queryTaskListByFormDataId(String ids);

+ 73 - 7
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TaskServiceImpl.java

@@ -22,6 +22,7 @@ import org.springblade.core.tool.support.Kv;
 import org.springblade.core.tool.utils.DateUtil;
 import org.springblade.core.tool.utils.Func;
 import org.springblade.evisa.feign.EVisaClient;
+import org.springblade.evisa.redissionUtil.DistributedRedisLock;
 import org.springblade.evisa.vo.EVisaTaskApprovalVO;
 import org.springblade.flow.core.constant.ProcessConstant;
 import org.springblade.flow.core.entity.BladeFlow;
@@ -39,8 +40,9 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Date;
 import java.util.List;
+import java.util.concurrent.TimeUnit;
 
- /**
+/**
  * 任务审核主表 服务实现类
  *
  * @author BladeX
@@ -90,7 +92,40 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
         return result;
     }
 
-    @Override
+     /**
+      * 任务专用
+      */
+     @Override
+     public TaskApprovalVO queryBusinessDataTask(TaskApprovalVO taskApprovalVO) {
+         do {
+             //判断锁是否存在
+             if(!DistributedRedisLock.getLockStatus(taskApprovalVO.getFormDataId())){
+                 //如果不存在,直接获取并上锁,由于这个查询方法是任务方面使用,所以解锁需要在对应数据使用结束后
+                 DistributedRedisLock.acquire(taskApprovalVO.getFormDataId(), 20);
+                 switch (taskApprovalVO.getApprovalType()){
+                     case 1:
+                         //填报数据
+                         return this.queryProcessSubmitBusinessData(taskApprovalVO.getFormDataId());
+                     case 2:
+                         //工程文件
+                         return this.queryArchiveFileBusinessData(taskApprovalVO.getFormDataId());
+                     default:
+                         //未找到数据,解锁
+                         DistributedRedisLock.release(taskApprovalVO.getFormDataId());
+                         return null;
+                 }
+             } else {
+                try{
+                    //如果存在锁,则等待解锁
+                    TimeUnit.MILLISECONDS.sleep(5);
+                }catch (Exception e){
+                    e.printStackTrace();
+                }
+             }
+         } while (true);
+     }
+
+     @Override
     public TaskApprovalVO queryBusinessData(TaskApprovalVO taskApprovalVO) {
         switch (taskApprovalVO.getApprovalType()){
             case 1:
@@ -157,7 +192,7 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
         String[] formDataIdArray = formDataIds.split(",");
         for(String formDataId : formDataIdArray){
             Task task = this.baseMapper.queryTaskListByFormDataId(formDataId);
-            if(!record.contains(task.getId())){
+            if(task != null && !record.contains(task.getId())){
                 record.add(task.getId());
                 result.add(task);
             }
@@ -229,15 +264,22 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
                 //完成/审批当前分支流程
                 this.newFlowClient.completeApprovalTask(taskId, parallelProcessInstanceId, comment).getData();
                 //修改分支状态,改为已完成
-                this.taskParallelService.update(Wrappers.<TaskParallel>lambdaUpdate().set(TaskParallel::getStatus, 2).set(TaskParallel::getUpdateTime, new Date()).eq(TaskParallel::getParallelProcessInstanceId, parallelProcessInstanceId));
+                this.taskParallelService.update(Wrappers.<TaskParallel>lambdaUpdate()
+                        .set(TaskParallel::getStatus, 2)
+                        .set(TaskParallel::getEVisaStatus, 1)
+                        .set(TaskParallel::getEVisaContent, "电签成功")
+                        .set(TaskParallel::getUpdateTime, new Date())
+                        .eq(TaskParallel::getParallelProcessInstanceId, parallelProcessInstanceId)
+                );
 
                 //最后判断当前分支流程的主流程的其它分支是否都已经完成,如果都已完成则更改主流程状态并执行完成任务
 
                 //获取状态为1(待审批)的分支流程
                 List<TaskParallel> otherLink = this.taskParallelService.list(Wrappers.<TaskParallel>lambdaQuery().eq(TaskParallel::getProcessInstanceId, currentLink.getProcessInstanceId()).eq(TaskParallel::getIsDeleted, 0).eq(TaskParallel::getStatus, 1));
+                //获取主流程
+                Task task = this.getOne(Wrappers.<Task>lambdaQuery().eq(Task::getIsDeleted, 0).eq(Task::getProcessInstanceId, currentLink.getProcessInstanceId()));
                 if(otherLink == null || otherLink.size() == 0){
                     //说明都审批完成,将主表状态更改为已完成
-                    Task task = this.getOne(Wrappers.<Task>lambdaQuery().eq(Task::getIsDeleted, 0).eq(Task::getProcessInstanceId, currentLink.getProcessInstanceId()));
                     //根据主表的业务ID(processInstanceId)获取主流程的taskId
                     String masterTaskId = this.newFlowClient.queryTaskIdByProcessInstanceId(task.getProcessInstanceId());
                     if(StringUtils.isNotEmpty(masterTaskId)){
@@ -248,11 +290,33 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
                         //修改对应的业务数据状态为已审批
                         this.updateBusinessDataByFormDataId(task, 2, eVisaStatus.contains("@@@@") ? eVisaStatus.split("@@@@")[1] : null);
                     }
+                } else {
+                    //修改对应的业务数据状态为已审批
+                    this.updateBusinessDataByFormDataId(task, 1, eVisaStatus.contains("@@@@") ? eVisaStatus.split("@@@@")[1] : null);
+                }
+            } else if("eVisaError".equals(eVisaStatus) || eVisaStatus.contains("eVisaError")){
+                //电签失败,将对应分支任务的电签状态修改为99并添加错误信息
+                String message = "电签失败";
+                if(eVisaStatus.contains("####")){
+                    message = eVisaStatus.split("####")[1];
                 }
-            } else if("error".equals(eVisaStatus)) {
-                System.out.println("循环调用电签");
+                //修改
+                this.taskParallelService.update(Wrappers.<TaskParallel>lambdaUpdate()
+                        .set(TaskParallel::getEVisaStatus, 99)
+                        .set(TaskParallel::getEVisaContent, message)
+                        .set(TaskParallel::getUpdateTime, new Date())
+                        .eq(TaskParallel::getParallelProcessInstanceId, parallelProcessInstanceId)
+                );
+
             } else {
                 //notPfxOrFile,没有证书或证书文件过期等
+                //修改
+                this.taskParallelService.update(Wrappers.<TaskParallel>lambdaUpdate()
+                        .set(TaskParallel::getEVisaStatus, 99)
+                        .set(TaskParallel::getEVisaContent, "未找到证书或业务文件")
+                        .set(TaskParallel::getUpdateTime, new Date())
+                        .eq(TaskParallel::getParallelProcessInstanceId, parallelProcessInstanceId)
+                );
                 return false;
             }
         } else {
@@ -423,6 +487,8 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
      */
     private void updateWriteBusinessDataStatus(String formDataId, Integer status, String newFileUrl){
         this.informationQueryService.update(Wrappers.<InformationQuery>lambdaUpdate().set(InformationQuery::getStatus, status).set(InformationQuery::getEVisaPdfUrl, newFileUrl).in(InformationQuery::getId, Arrays.asList(formDataId.split(","))));
+        //解锁
+        DistributedRedisLock.release(formDataId);
     }
 
     /**

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

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

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

@@ -32,6 +32,7 @@ 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.CommonConstant;
 import org.springblade.common.constant.EVisaConstant;
 import org.springblade.common.utils.CommonUtil;
 import org.springblade.common.utils.SnowFlakeUtil;
@@ -48,6 +49,7 @@ import org.springblade.manager.entity.SignPfxFile;
 import org.springblade.manager.feign.ContractClient;
 import org.springblade.manager.feign.SignPfxClient;
 import org.springblade.resource.feign.NewIOSSClient;
+import org.springblade.system.cache.ParamCache;
 import org.springframework.mock.web.MockMultipartFile;
 import org.springframework.stereotype.Service;
 import org.springframework.web.multipart.MultipartFile;
@@ -77,12 +79,14 @@ public class EVisaServiceImpl implements EVisaService {
 
     private static final double INCH_2_CM = 2.54d;
 
-    private static final String ERROR = "error";
-
     private static final String NOT_PFX_OR_FILE = "notPfxOrFile";
 
+    private static final String ERROR = "error";
+
     private static final String SUCCESS = "success";
 
+    private static final String E_VISA_ERROR = "eVisaError";
+
     private static final Logger logger = LoggerFactory.getLogger(EVisaServiceImpl.class);
 
     private final SignPfxClient signPfxClient;
@@ -194,10 +198,15 @@ public class EVisaServiceImpl implements EVisaService {
 
     @Override
     public String eVisa(EVisaTaskApprovalVO task) {
-        String resultMessage = ERROR;
+        String resultMessage = E_VISA_ERROR;
+
+        //用户默认的电签批次参数
+        String sysBatch = ParamCache.getValue(CommonConstant.SYS_USER_TASK_BATCH);
+        int batch = 2;
+        if(CommonUtil.checkIsBigDecimal(sysBatch)){
+            batch = new Integer(sysBatch);
+        }
 
-        //todo 这里应当是配置限制参数,初版暂时写死
-        int batch = 20;
 
         //获取任务对应表格的电签配置
         List<JSONObject> eVisaConfigList = this.taskClient.queryBusinessTableEVisaConfig(task.getParallelProcessInstanceId());
@@ -215,7 +224,7 @@ public class EVisaServiceImpl implements EVisaService {
         }
 
         //根据任务类型获取对应的文件信息
-        TaskApprovalVO taskFile = this.taskClient.queryBusinessData(JSONObject.parseObject(JSONObject.toJSONString(task), TaskApprovalVO.class));
+        TaskApprovalVO taskFile = this.taskClient.queryBusinessDataTask(JSONObject.parseObject(JSONObject.toJSONString(task), TaskApprovalVO.class));
         if(taskFile == null || taskFile.getApprovalFileList().size() <= 0){
             //没有找到业务文件,取消签章
             return NOT_PFX_OR_FILE;
@@ -227,6 +236,7 @@ public class EVisaServiceImpl implements EVisaService {
 
                 //获取需要签章的数据
                 List<TaskApprovalVO.ApprovalFile> files = taskFile.getApprovalFileList();
+                //这里的文件只会是一张拼接好的PDF
                 for(TaskApprovalVO.ApprovalFile file : files){
                     //获取PDF文件
                     PDDocument document = PDDocument.load(CommonUtil.getOSSInputStream(file.getFileUrl()));
@@ -262,26 +272,28 @@ public class EVisaServiceImpl implements EVisaService {
                     //执行电签
                     Object[] result = this.signPdf(pdfVO, fileByte);
                     if(result != null){
-                        MultipartFile newFiles = new MockMultipartFile("file", SnowFlakeUtil.getId() + ".pdf", "text/plain", IOUtils.toByteArray(new ByteArrayInputStream((byte[])result[0])));
-                        //重新上传
-                        BladeFile bladeFile = this.newIOSSClient.uploadFileByInputStream(newFiles);
-                        if(bladeFile != null){
-                            resultMessage = SUCCESS + "@@@@" + bladeFile.getLink();
+                        if(result[0] != null){
+                            MultipartFile newFiles = new MockMultipartFile("file", SnowFlakeUtil.getId() + ".pdf", "text/plain", IOUtils.toByteArray(new ByteArrayInputStream((byte[])result[0])));
+                            //重新上传
+                            BladeFile bladeFile = this.newIOSSClient.uploadFileByInputStream(newFiles);
+                            if(bladeFile != null){
+                                resultMessage = SUCCESS + "@@@@" + bladeFile.getLink();
+                            } else {
+                                resultMessage = E_VISA_ERROR;
+                            }
                         } else {
-                            resultMessage = ERROR;
+                            resultMessage = E_VISA_ERROR + "####" + result[2];
                         }
                     } else {
-                        resultMessage = ERROR;
+                        resultMessage = E_VISA_ERROR;
                     }
 
                 }
 
-
             }catch (Exception e){
                 e.printStackTrace();
             }
         }
-
         //释放锁
         DistributedRedisLock.release(AuthUtil.getUserId().toString());
 
@@ -292,7 +304,7 @@ public class EVisaServiceImpl implements EVisaService {
      * 签章
      */
     private Object[] signPdf(SealPdfVO pdfVO, byte[] fileByte){
-        Object[] result = new Object[2];
+        Object[] result = new Object[3];
         try{
             PaperlessClient paperlessClient = new PaperlessClient(SIGN_HOST, SIGN_PORT, 300000, 36000000);
             paperlessClient.setSSL(false);
@@ -357,10 +369,11 @@ public class EVisaServiceImpl implements EVisaService {
                     result[0] = pdfBean4Response.getPdf();
                 }
             }else{
-                logger.info("【电签模块】{}","签章响应Response:"+compoundSealPdfListDetachedResponse);
-                logger.info("【电签模块】{}","签章响应code:"+responseHead.getCode());
+                logger.info("【电签模块】{}","签章响应Response:" + compoundSealPdfListDetachedResponse);
+                logger.info("【电签模块】{}","签章响应code:" + responseHead.getCode());
                 result[0] = null;
                 result[1] = compoundSealPdfListDetachedResponse.toString();
+                result[2] = responseHead.getMessage();
             }
 
         } catch (Exception e){