Jelajahi Sumber

新增自定义流程属性-动态驳回网关

wangliang 3 tahun lalu
induk
melakukan
3b7cb4de03

+ 50 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/flow/CustomFlowGatewayDto.java

@@ -0,0 +1,50 @@
+package com.qmth.distributed.print.business.bean.flow;
+
+import io.swagger.annotations.ApiModelProperty;
+
+import java.io.Serializable;
+
+/**
+ * @Description: 自定义流程网关 dto
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2022/2/10
+ */
+public class CustomFlowGatewayDto implements Serializable {
+
+    @ApiModelProperty(value = "流程节点id")
+    String flowTaskId;
+
+    @ApiModelProperty(value = "条件表达式")
+    String conditionExp;
+
+    public CustomFlowGatewayDto() {
+
+    }
+
+    public CustomFlowGatewayDto(String flowTaskId) {
+        this.flowTaskId = flowTaskId;
+    }
+
+    public CustomFlowGatewayDto(String flowTaskId, String conditionExp) {
+        this.flowTaskId = flowTaskId;
+        this.conditionExp = conditionExp;
+    }
+
+    public String getFlowTaskId() {
+        return flowTaskId;
+    }
+
+    public void setFlowTaskId(String flowTaskId) {
+        this.flowTaskId = flowTaskId;
+    }
+
+    public String getConditionExp() {
+        return conditionExp;
+    }
+
+    public void setConditionExp(String conditionExp) {
+        this.conditionExp = conditionExp;
+    }
+}

+ 51 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/flow/CustomFlowVarDto.java

@@ -0,0 +1,51 @@
+package com.qmth.distributed.print.business.bean.flow;
+
+import io.swagger.annotations.ApiModelProperty;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * @Description: 自定义流程节点变量 dto
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2022/2/10
+ */
+public class CustomFlowVarDto implements Serializable {
+
+    @ApiModelProperty(value = "流程节点变量")
+    String flowTaskVar;
+
+    @ApiModelProperty(value = "审批人")
+    List<String> approveIds;
+
+    public CustomFlowVarDto() {
+
+    }
+
+    public CustomFlowVarDto(String flowTaskVar) {
+        this.flowTaskVar = flowTaskVar;
+    }
+
+    public CustomFlowVarDto(String flowTaskVar, List<String> approveIds) {
+        this.flowTaskVar = flowTaskVar;
+        this.approveIds = approveIds;
+    }
+
+    public String getFlowTaskVar() {
+        return flowTaskVar;
+    }
+
+    public void setFlowTaskVar(String flowTaskVar) {
+        this.flowTaskVar = flowTaskVar;
+    }
+
+    public List<String> getApproveIds() {
+        return approveIds;
+    }
+
+    public void setApproveIds(List<String> approveIds) {
+        this.approveIds = approveIds;
+    }
+}

+ 11 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/params/FlowTaskApproveParam.java

@@ -35,6 +35,17 @@ public class FlowTaskApproveParam implements Serializable {
     @JsonSerialize(using = ToStringSerializer.class)
     private List<Long> approveUserIds;
 
+    @ApiModelProperty(value = "流程节点id")
+    private String usertaskId;
+
+    public String getUsertaskId() {
+        return usertaskId;
+    }
+
+    public void setUsertaskId(String usertaskId) {
+        this.usertaskId = usertaskId;
+    }
+
     public String getTaskId() {
         return taskId;
     }

+ 12 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/entity/TFCustomFlow.java

@@ -61,6 +61,10 @@ public class TFCustomFlow extends BaseEntity implements Serializable {
     @ApiModelProperty(value = "流程过程变量数据")
     private String flowProcessVar;
 
+    @ApiModelProperty(value = "流程id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long flowId;
+
     public Long getSchoolId() {
         return schoolId;
     }
@@ -80,6 +84,14 @@ public class TFCustomFlow extends BaseEntity implements Serializable {
         insertInfo(userId);
     }
 
+    public Long getFlowId() {
+        return flowId;
+    }
+
+    public void setFlowId(Long flowId) {
+        this.flowId = flowId;
+    }
+
     public String getFlowProcessVar() {
         return flowProcessVar;
     }

+ 75 - 29
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ActivitiServiceImpl.java

@@ -2,12 +2,11 @@ package com.qmth.distributed.print.business.service.impl;
 
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.google.gson.Gson;
 import com.qmth.boot.api.exception.ApiException;
 import com.qmth.distributed.print.business.activiti.custom.service.DefaultInstanceConvertToMultiInstance;
 import com.qmth.distributed.print.business.activiti.custom.service.MultiWorkFlow;
-import com.qmth.distributed.print.business.bean.flow.CustomFlowDto;
-import com.qmth.distributed.print.business.bean.flow.CustomFlowPropertyDto;
-import com.qmth.distributed.print.business.bean.flow.CustomFlowSaveDto;
+import com.qmth.distributed.print.business.bean.flow.*;
 import com.qmth.distributed.print.business.bean.flow.link.FlowTaskLink;
 import com.qmth.distributed.print.business.bean.flow.link.FlowTaskNode;
 import com.qmth.distributed.print.business.bean.result.*;
@@ -198,6 +197,13 @@ public class ActivitiServiceImpl implements ActivitiService {
         String id = (String) map.get(SystemConstant.ID);
         BpmnModel model = (BpmnModel) map.get(SystemConstant.MODEL);
         Map flowProcessVarMap = (Map) map.get(SystemConstant.FLOW_PROCESS_VAR_MAP);
+        Map<String, Object> varMap = new HashMap<>();
+        flowProcessVarMap.forEach((k, v) -> {
+            if (v instanceof CustomFlowVarDto) {
+                CustomFlowVarDto customFlowVarDto = (CustomFlowVarDto) v;
+                varMap.computeIfAbsent(customFlowVarDto.getFlowTaskVar(), s -> customFlowVarDto.getApproveIds().size() == 1 ? customFlowVarDto.getApproveIds().get(0) : customFlowVarDto.getApproveIds());
+            }
+        });
 
         //部署流程
         String bpmnName = id + DefaultInstanceConvertToMultiInstance.FLOW_BPMN_MODEL_NAME;
@@ -207,7 +213,7 @@ public class ActivitiServiceImpl implements ActivitiService {
         Deployment deployment = repositoryService.createDeployment().addBpmnModel(bpmnName, model).name(bpmnDeploymentName).deploy();
 
         //启动流程
-        ProcessInstance processInstance = flowProcessVarMap.size() > 0 ? runtimeService.startProcessInstanceByKey(id, flowProcessVarMap) : runtimeService.startProcessInstanceByKey(id);
+        ProcessInstance processInstance = varMap.size() > 0 ? runtimeService.startProcessInstanceByKey(id, varMap) : runtimeService.startProcessInstanceByKey(id);
 
         //保存png图片和xml文件(这一步可做可不做)
         InputStream processDiagram = repositoryService.getProcessDiagram(processInstance.getProcessDefinitionId());
@@ -388,15 +394,36 @@ public class ActivitiServiceImpl implements ActivitiService {
 
             Map<String, Object> objectMap = new HashMap<>();
             TFFlowLog tfFlowLog = null;
+
+            QueryWrapper<TFCustomFlow> tfCustomFlowQueryWrapper = new QueryWrapper<>();
+            tfCustomFlowQueryWrapper.lambda().eq(TFCustomFlow::getFlowId, SystemConstant.convertIdToLong(processInstanceId));
+            TFCustomFlow tfCustomFlow = tfCustomFlowService.getOne(tfCustomFlowQueryWrapper);
+            Map<String, Object> flowProcessVarMap = this.getFlowProcessVarMap(tfCustomFlow);
+
             if (currFlow instanceof UserTask) {
                 UserTask userTask = (UserTask) currFlow;
                 String remark = Objects.nonNull(map.get(SystemConstant.APPROVE_REMARK)) ? map.get(SystemConstant.APPROVE_REMARK).toString() : null;
                 //流程流水日志
                 tfFlowLog = new TFFlowLog(sysUser.getSchoolId(), sysUser.getOrgId(), SystemConstant.convertIdToLong(processInstanceId), examTask.getId(), sysUser.getId(), sysUser.getId(), remark);
-                FlowApproveSetupEnum setupEnum = FlowApproveSetupEnum.convertToInstance(userTask.getId());
+//                FlowApproveSetupEnum setupEnum = FlowApproveSetupEnum.convertToInstance(userTask.getId());
                 if (Objects.isNull(tfFlowApproveLog)) {
                     tfFlowApproveLog = new TFFlowApproveLog(sysUser.getSchoolId(), sysUser.getOrgId(), SystemConstant.convertIdToLong(processInstanceId), examTask.getId(), sysUser.getId(), sysUser.getId());
                 }
+                FlowApprovePassEnum approvePass = (FlowApprovePassEnum) map.get(SystemConstant.APPROVE_OPERATION);
+                if (Objects.nonNull(map.get(SystemConstant.USER_TASK_ID)) && !Objects.equals(map.get(SystemConstant.USER_TASK_ID), "")) {
+                    String usertaskId = (String) map.get(SystemConstant.USER_TASK_ID);
+                    if (Objects.nonNull(flowProcessVarMap.get(usertaskId))) {
+                        List<Object> tempMap = (List<Object>) flowProcessVarMap.get(usertaskId);
+                        Gson gson = new Gson();
+                        CustomFlowVarDto customFlowVarDto = gson.fromJson(gson.toJson(tempMap.get(0)), CustomFlowVarDto.class);
+                        map.computeIfAbsent(SystemConstant.APPROVE, v -> usertaskId);
+                        map.computeIfAbsent(customFlowVarDto.getFlowTaskVar(), v -> customFlowVarDto.getApproveIds().size() == 1 ? customFlowVarDto.getApproveIds().get(0) : customFlowVarDto.getApproveIds());
+                    } else {
+                        map.computeIfAbsent(SystemConstant.APPROVE, v -> "end");
+                    }
+                } else {
+                    map.computeIfAbsent(SystemConstant.APPROVE, v -> "end");
+                }
 //                //广东医科大学流程
 //                if (Objects.nonNull(processDefinitionEntity) && (processDefinitionEntity.getKey().contains(SystemConstant.GDYKDX_FLOW_KEY)
 //                        || processDefinitionEntity.getKey().contains(SystemConstant.GDYKDX_SUB_FLOW_KEY))) {
@@ -1484,7 +1511,8 @@ public class ActivitiServiceImpl implements ActivitiService {
         Map<CustomFlowTypeEnum, CustomFlowDto> customFlowTypeEnumCustomFlowDtoMap = new HashMap<>();
         FlowTaskLink flowTaskLink = new FlowTaskLink();
         Map<String, Object> flowProcessVarMap = new HashMap<>();
-        Map<String, Map<String, List<String>>> gatewayMap = new HashMap<>();
+        Map<String, Map<String, List<CustomFlowGatewayDto>>> gatewayMap = new HashMap<>();
+        flowProcessVarMap.computeIfAbsent(SystemConstant.GATEWAY_MAP, v -> gatewayMap);
         AtomicInteger gatewayId = new AtomicInteger(1);
         AtomicInteger sequenceId = new AtomicInteger(1);
         CustomFlowDto customFlowDefaultDto = null;
@@ -1503,7 +1531,7 @@ public class ActivitiServiceImpl implements ActivitiService {
                     process.addFlowElement(createStartEvent());
                     //默认在开始节点后新增一个审批节点
                     customFlowDefaultDto = multiWorkFlow.createDefaultUserTask(customFlowDto, flowTaskLink, DefaultInstanceConvertToMultiInstance.DEFAULT_USER_TASK);
-                    flowProcessVarMap.computeIfAbsent(SystemConstant.APPROVE_ID, v -> "");
+                    flowProcessVarMap.computeIfAbsent(customFlowDefaultDto.getFlowTaskId(), v -> new CustomFlowVarDto(SystemConstant.APPROVE_ID, Arrays.asList("")));
                     process.addFlowElement(createUserTask(CustomFlowDynamicBuildEnum.USER_TASK.getId() + DefaultInstanceConvertToMultiInstance.DEFAULT_USER_TASK, Objects.nonNull(flowTaskLink.getLast().getTask().getContent()) && !Objects.equals(flowTaskLink.getLast().getTask().getContent(), "") ? flowTaskLink.getLast().getTask().getContent() : DefaultInstanceConvertToMultiInstance.DEFAULT_USER_TASK_NAME, DefaultInstanceConvertToMultiInstance.APPROVE_ID_EXP));
                     break;
                 case PROCESS://过程节点
@@ -1532,7 +1560,8 @@ public class ActivitiServiceImpl implements ActivitiService {
                         switch (customFlowPropertyDto.getMultipleUserApproveType()) {
                             case ORDER://依次审批
                             case ALL://会签审批
-                                flowProcessVarMap.computeIfAbsent(DefaultInstanceConvertToMultiInstance.DEFAULT_ASSIGNEE_LIST + i, v -> approveUserIds);
+                                int finalI = i;
+                                flowProcessVarMap.computeIfAbsent(node.getTask().getFlowTaskId(), v -> new CustomFlowVarDto(DefaultInstanceConvertToMultiInstance.DEFAULT_ASSIGNEE_LIST + finalI, approveUserIds));
                                 break;
                             default:
                                 break;
@@ -1542,12 +1571,12 @@ public class ActivitiServiceImpl implements ActivitiService {
                             switch (customFlowPropertyDto.getRejectType()) {
                                 case PREV://上一节点
                                     FlowTaskNode flowTaskNode = node.getBefore();
-                                    List<String> flowTaskIds = new ArrayList<>();
+                                    List<CustomFlowGatewayDto> flowTaskIds = new ArrayList<>();
                                     boolean isProcess = false;
                                     while (!isProcess) {
                                         if (flowTaskNode.getTask().getType() == CustomFlowTypeEnum.PROCESS) {
                                             isProcess = true;
-                                            flowTaskIds.add(flowTaskNode.getTask().getFlowTaskId());
+                                            flowTaskIds.add(new CustomFlowGatewayDto(flowTaskNode.getTask().getFlowTaskId(), "${" + SystemConstant.APPROVE + "=='" + flowTaskNode.getTask().getFlowTaskId() + "'}"));
                                         }
                                         flowTaskNode = flowTaskNode.getBefore();
                                     }
@@ -1564,14 +1593,14 @@ public class ActivitiServiceImpl implements ActivitiService {
                                             process,
                                             gatewayId,
                                             customFlowDto.getFlowTaskId(),
-                                            Arrays.asList(customFlowDefaultDto.getFlowTaskId()));
+                                            Arrays.asList(new CustomFlowGatewayDto(customFlowDefaultDto.getFlowTaskId(), "${" + SystemConstant.APPROVE + "=='" + customFlowDefaultDto.getFlowTaskId() + "'}")));
                                     break;
                                 case PREV_ALL://该节点前全部节点
                                     flowTaskNode = node.getBefore();
                                     flowTaskIds = new ArrayList<>();
                                     while (Objects.nonNull(flowTaskNode)) {
                                         if (flowTaskNode.getTask().getType() == CustomFlowTypeEnum.PROCESS) {
-                                            flowTaskIds.add(flowTaskNode.getTask().getFlowTaskId());
+                                            flowTaskIds.add(new CustomFlowGatewayDto(flowTaskNode.getTask().getFlowTaskId(), "${" + SystemConstant.APPROVE + "=='" + flowTaskNode.getTask().getFlowTaskId() + "'}"));
                                         }
                                         flowTaskNode = flowTaskNode.getBefore();
                                     }
@@ -1621,19 +1650,23 @@ public class ActivitiServiceImpl implements ActivitiService {
             FlowTaskNode flowTaskNode = flowTaskLink.get(i);
             normalSequenceId = DefaultInstanceConvertToMultiInstance.SEQUENCE_NAME + sequenceId.getAndIncrement();
             log.info("1 start:{},end:{}", flowTaskNode.getBefore().getTask().getFlowTaskId(), flowTaskNode.getTask().getFlowTaskId());
-            process.addFlowElement(createSequenceFlow(flowTaskNode.getBefore().getTask().getFlowTaskId(), flowTaskNode.getTask().getFlowTaskId(), normalSequenceId, normalSequenceId, null));
+            if (flowTaskNode.getBefore().getTask().getType() == CustomFlowTypeEnum.EXCLUSIVE_GATE_WAY) {
+                process.addFlowElement(createSequenceFlow(flowTaskNode.getBefore().getTask().getFlowTaskId(), flowTaskNode.getTask().getFlowTaskId(), normalSequenceId, FlowApprovePassEnum.PASS.getTitle(), "${" + SystemConstant.APPROVE + "=='" + flowTaskNode.getTask().getFlowTaskId() + "'}"));
+            } else {
+                process.addFlowElement(createSequenceFlow(flowTaskNode.getBefore().getTask().getFlowTaskId(), flowTaskNode.getTask().getFlowTaskId(), normalSequenceId, FlowApprovePassEnum.PASS.getTitle(), null));
+            }
             if (Objects.nonNull(gatewayMap.get(flowTaskNode.getTask().getFlowTaskId()))) {
-                Map<String, List<String>> map = gatewayMap.get(flowTaskNode.getTask().getFlowTaskId());
-                List<String> gatewayList = map.get(CustomFlowTypeEnum.EXCLUSIVE_GATE_WAY.name());
+                Map<String, List<CustomFlowGatewayDto>> map = gatewayMap.get(flowTaskNode.getTask().getFlowTaskId());
+                List<CustomFlowGatewayDto> gatewayList = map.get(CustomFlowTypeEnum.EXCLUSIVE_GATE_WAY.name());
                 map.remove(CustomFlowTypeEnum.EXCLUSIVE_GATE_WAY.name());
                 if (Objects.nonNull(map) && map.size() > 0) {
                     map.forEach((k, v) -> {
                         String gatewaySequenceId = null;
                         if (Objects.equals(k, CustomFlowElementEnum.REJECT.getId())) {
-                            for (String s : v) {
+                            for (CustomFlowGatewayDto c : v) {
                                 gatewaySequenceId = DefaultInstanceConvertToMultiInstance.SEQUENCE_NAME + sequenceId.getAndIncrement();
-                                log.info("2 start:{},end:{}", gatewayList.get(0), s);
-                                process.addFlowElement(createSequenceFlow(gatewayList.get(0), s, gatewaySequenceId, gatewaySequenceId, null));
+                                log.info("2 start:{},end:{}", gatewayList.get(0).getFlowTaskId(), c.getFlowTaskId());
+                                process.addFlowElement(createSequenceFlow(gatewayList.get(0).getFlowTaskId(), c.getFlowTaskId(), gatewaySequenceId, FlowApprovePassEnum.REJECT.getTitle(), c.getConditionExp()));
                             }
                         }
                     });
@@ -1664,18 +1697,18 @@ public class ActivitiServiceImpl implements ActivitiService {
      * @return
      */
     protected CustomFlowDto createCustomFlowExclusiveGateway(FlowTaskLink flowTaskLink,
-                                                             Map<String, Map<String, List<String>>> gatewayMap,
+                                                             Map<String, Map<String, List<CustomFlowGatewayDto>>> gatewayMap,
                                                              Process process,
                                                              AtomicInteger gatewayId,
                                                              String currentFlowTaskId,
-                                                             List<String> flowTaskIds) {
+                                                             List<CustomFlowGatewayDto> flowTaskIds) {
         int exclusiveGatewayId = gatewayId.getAndIncrement();
         CustomFlowDto customFlowExclusiveGatewayDto = new CustomFlowDto(DefaultInstanceConvertToMultiInstance.GATEWAY_NAME + exclusiveGatewayId, CustomFlowTypeEnum.EXCLUSIVE_GATE_WAY, CustomFlowTypeEnum.EXCLUSIVE_GATE_WAY.getTitle(), CustomFlowDynamicBuildEnum.EXCLUSIVE_GATE_WAY.getId() + exclusiveGatewayId);
         FlowTaskNode exclusiveGatewayNode = new FlowTaskNode(customFlowExclusiveGatewayDto);
         flowTaskLink.add(exclusiveGatewayNode);
-        Map<String, List<String>> sequenceFlowMap = new HashMap<>();
+        Map<String, List<CustomFlowGatewayDto>> sequenceFlowMap = new HashMap<>();
         sequenceFlowMap.put(CustomFlowElementEnum.REJECT.getId(), flowTaskIds);
-        sequenceFlowMap.put(CustomFlowTypeEnum.EXCLUSIVE_GATE_WAY.name(), Arrays.asList(customFlowExclusiveGatewayDto.getFlowTaskId()));
+        sequenceFlowMap.put(CustomFlowTypeEnum.EXCLUSIVE_GATE_WAY.name(), Arrays.asList(new CustomFlowGatewayDto(customFlowExclusiveGatewayDto.getFlowTaskId())));
         gatewayMap.put(currentFlowTaskId, sequenceFlowMap);
         process.addFlowElement(createExclusiveGateway(customFlowExclusiveGatewayDto.getFlowTaskId(), CustomFlowTypeEnum.EXCLUSIVE_GATE_WAY.getTitle()));
         return customFlowExclusiveGatewayDto;
@@ -1691,19 +1724,32 @@ public class ActivitiServiceImpl implements ActivitiService {
     @Transactional
     public void customFlowStartUpdateApproveId(Long customFlowId, Long approveId) {
         TFCustomFlow tfCustomFlow = tfCustomFlowService.getById(customFlowId);
-        Optional.ofNullable(tfCustomFlow).orElseThrow(() -> ExceptionResultEnum.ERROR.exception("未找到自定义流程数据"));
-        Map<String, Object> map = JacksonUtil.readJson(tfCustomFlow.getFlowProcessVar(), Map.class);
-        Optional.ofNullable(map).orElseThrow(() -> ExceptionResultEnum.ERROR.exception("自定义流程变量数据为空"));
-        Task task = taskService.createTaskQuery().processInstanceId(String.valueOf(map.get(SystemConstant.FLOW_ID))).singleResult();
+        Task task = taskService.createTaskQuery().processInstanceId(String.valueOf(tfCustomFlow.getFlowId())).singleResult();
         task.setAssignee(String.valueOf(approveId));
         taskService.saveTask(task);
-        Map<String, Object> flowProcessVarMap = (Map<String, Object>) map.get(SystemConstant.FLOW_PROCESS_VAR_MAP);
-        Optional.ofNullable(map).orElseThrow(() -> ExceptionResultEnum.ERROR.exception("自定义流程节点变量数据为空"));
-        flowProcessVarMap.put(SystemConstant.APPROVE_ID, approveId);
+        Map<String, Object> flowProcessVarMap = this.getFlowProcessVarMap(tfCustomFlow);
+        Map<String, Object> map = JacksonUtil.readJson(tfCustomFlow.getFlowProcessVar(), Map.class);
+        flowProcessVarMap.put(CustomFlowDynamicBuildEnum.USER_TASK.getId() + DefaultInstanceConvertToMultiInstance.DEFAULT_USER_TASK, Arrays.asList(new CustomFlowVarDto(SystemConstant.APPROVE_ID, Arrays.asList(String.valueOf(approveId)))));
+        map.put(SystemConstant.FLOW_PROCESS_VAR_MAP, flowProcessVarMap);
         tfCustomFlow.setFlowProcessVar(JacksonUtil.parseJson(map));
         tfCustomFlowService.updateById(tfCustomFlow);
     }
 
+    /**
+     * 获取流程变量
+     *
+     * @param tfCustomFlow
+     * @return
+     */
+    protected Map<String, Object> getFlowProcessVarMap(TFCustomFlow tfCustomFlow) {
+        Optional.ofNullable(tfCustomFlow).orElseThrow(() -> ExceptionResultEnum.ERROR.exception("未找到自定义流程数据"));
+        Map<String, Object> varMap = JacksonUtil.readJson(tfCustomFlow.getFlowProcessVar(), Map.class);
+        Optional.ofNullable(varMap).orElseThrow(() -> ExceptionResultEnum.ERROR.exception("自定义流程变量数据为空"));
+        Map<String, Object> flowProcessVarMap = (Map<String, Object>) varMap.get(SystemConstant.FLOW_PROCESS_VAR_MAP);
+        Optional.ofNullable(flowProcessVarMap).orElseThrow(() -> ExceptionResultEnum.ERROR.exception("自定义流程节点变量数据为空"));
+        return flowProcessVarMap;
+    }
+
     /**
      * 开始任务节点
      *

+ 1 - 0
distributed-print/src/main/java/com/qmth/distributed/print/api/TFCustomFlowController.java

@@ -91,6 +91,7 @@ public class TFCustomFlowController {
             Map<String, Object> map = activitiService.dynamicBuildBpmn(customFlowSaveDto, flowBpmnId);
             tfCustomFlow.setFlowProcessVar(JacksonUtil.parseJson(map));
             tfCustomFlow.setActFlowId((String) map.get(SystemConstant.PROCESS_DEFINITION_ID));
+            tfCustomFlow.setFlowId(SystemConstant.convertIdToLong((String) map.get(SystemConstant.FLOW_ID)));
             tfCustomFlowService.save(tfCustomFlow);
         } catch (Exception e) {
             log.error(SystemConstant.LOG_ERROR, e);

+ 1 - 0
distributed-print/src/main/java/com/qmth/distributed/print/api/TFFlowController.java

@@ -177,6 +177,7 @@ public class TFFlowController {
         map.computeIfAbsent(SystemConstant.APPROVE_REMARK, v -> flowTaskApproveParam.getRemark());
         map.computeIfAbsent(SystemConstant.APPROVE_SETUP, v -> flowTaskApproveParam.getSetup());
         map.computeIfAbsent(SystemConstant.APPROVE_USER_IDS, v -> flowTaskApproveParam.getApproveUserIds());
+        map.computeIfAbsent(SystemConstant.USER_TASK_ID, v -> flowTaskApproveParam.getUsertaskId());
         Map<String, Object> objectMap = activitiService.taskApprove(map);
         if (Objects.nonNull(objectMap)) {
             TFFlowApprove tfFlowApprove = (TFFlowApprove) objectMap.get("tfFlowApprove");

+ 64 - 0
distributed-print/src/main/resources/processes/test-school-2_6beee68c2fa24de59ce5b5d6d77689db-multiple-process.bpmn

@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test">
+  <process id="test-school-2_6beee68c2fa24de59ce5b5d6d77689db" isExecutable="true">
+    <startEvent id="start" name="开始节点"></startEvent>
+    <userTask id="usertask_default" name="提交试卷" activiti:assignee="${approveId}"></userTask>
+    <exclusiveGateway id="exclusivegateway1" name="排他网关"></exclusiveGateway>
+    <userTask id="usertask1" name="审批人" activiti:candidateUsers="190416342040444928,190416459858444288,190416551696924672"></userTask>
+    <endEvent id="end" name="结束节点"></endEvent>
+    <sequenceFlow id="sequence1" name="通过" sourceRef="start" targetRef="usertask_default"></sequenceFlow>
+    <sequenceFlow id="sequence2" name="通过" sourceRef="usertask_default" targetRef="usertask1"></sequenceFlow>
+    <sequenceFlow id="sequence3" name="驳回" sourceRef="exclusivegateway1" targetRef="usertask_default">
+      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${approve==0}]]></conditionExpression>
+    </sequenceFlow>
+    <sequenceFlow id="sequence4" name="通过" sourceRef="usertask1" targetRef="exclusivegateway1"></sequenceFlow>
+    <sequenceFlow id="sequence5" name="通过" sourceRef="exclusivegateway1" targetRef="end">
+      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${approve==1}]]></conditionExpression>
+    </sequenceFlow>
+  </process>
+  <bpmndi:BPMNDiagram id="BPMNDiagram_test-school-2_6beee68c2fa24de59ce5b5d6d77689db">
+    <bpmndi:BPMNPlane bpmnElement="test-school-2_6beee68c2fa24de59ce5b5d6d77689db" id="BPMNPlane_test-school-2_6beee68c2fa24de59ce5b5d6d77689db">
+      <bpmndi:BPMNShape bpmnElement="usertask_default" id="BPMNShape_usertask_default">
+        <omgdc:Bounds height="60.0" width="100.0" x="80.0" y="63.0"></omgdc:Bounds>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape bpmnElement="start" id="BPMNShape_start">
+        <omgdc:Bounds height="30.0" width="30.0" x="0.0" y="78.0"></omgdc:Bounds>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape bpmnElement="end" id="BPMNShape_end">
+        <omgdc:Bounds height="30.0" width="30.0" x="470.0" y="78.0"></omgdc:Bounds>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape bpmnElement="usertask1" id="BPMNShape_usertask1">
+        <omgdc:Bounds height="60.0" width="100.0" x="230.0" y="0.0"></omgdc:Bounds>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape bpmnElement="exclusivegateway1" id="BPMNShape_exclusivegateway1">
+        <omgdc:Bounds height="40.0" width="40.0" x="380.0" y="73.0"></omgdc:Bounds>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNEdge bpmnElement="sequence5" id="BPMNEdge_sequence5">
+        <omgdi:waypoint x="420.0" y="93.0"></omgdi:waypoint>
+        <omgdi:waypoint x="470.0" y="93.0"></omgdi:waypoint>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="sequence3" id="BPMNEdge_sequence3">
+        <omgdi:waypoint x="380.0" y="100.5"></omgdi:waypoint>
+        <omgdi:waypoint x="368.0" y="100.5"></omgdi:waypoint>
+        <omgdi:waypoint x="368.0" y="93.0"></omgdi:waypoint>
+        <omgdi:waypoint x="80.0" y="93.0"></omgdi:waypoint>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="sequence4" id="BPMNEdge_sequence4">
+        <omgdi:waypoint x="330.0" y="30.0"></omgdi:waypoint>
+        <omgdi:waypoint x="342.0" y="30.0"></omgdi:waypoint>
+        <omgdi:waypoint x="342.0" y="93.0"></omgdi:waypoint>
+        <omgdi:waypoint x="380.0" y="93.0"></omgdi:waypoint>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="sequence1" id="BPMNEdge_sequence1">
+        <omgdi:waypoint x="30.0" y="93.0"></omgdi:waypoint>
+        <omgdi:waypoint x="80.0" y="93.0"></omgdi:waypoint>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="sequence2" id="BPMNEdge_sequence2">
+        <omgdi:waypoint x="180.0" y="80.5"></omgdi:waypoint>
+        <omgdi:waypoint x="192.0" y="80.5"></omgdi:waypoint>
+        <omgdi:waypoint x="192.0" y="30.000000000000007"></omgdi:waypoint>
+        <omgdi:waypoint x="230.0" y="30.000000000000007"></omgdi:waypoint>
+      </bpmndi:BPMNEdge>
+    </bpmndi:BPMNPlane>
+  </bpmndi:BPMNDiagram>
+</definitions>

+ 2 - 0
teachcloud-common/src/main/java/com/qmth/teachcloud/common/contant/SystemConstant.java

@@ -209,12 +209,14 @@ public class SystemConstant {
     public static final String FLOW_ID = "flowId";//流程id
     public static final String FLOW_TASK_ID = "flowTaskId";//流程任务id
     public static final String APPROVE = "approve";//流程审核变量
+    public static final String GATEWAY_MAP = "gatewayMap";//流程网关变量
     public static final String APPROVE_SETUP = "approveSetup";//流程节点
     public static final String APPROVE_USER_IDS = "approveUserIds";//流程审批人列表
     public static final String APPROVE_DIRECTOR_USER_IDS = "approveDirectorUserIds";//流程主任审批人列表
     public static final String APPROVE_PRESIDENT_USER_IDS = "approvePresidentUserIds";//流程院长审批人列表
     public static final String APPROVE_PRINT_USER_IDS = "approvePrintUserIds";//印刷人员审批人列表
     public static final String APPROVE_OPERATION = "approveOperation";//流程操作
+    public static final String USER_TASK_ID = "usertaskId";//流程节点id
     public static final String APPROVE_CANCEL = "cancel";//流程撤销操作
     public static final String APPROVE_CANCEL_USER = "approveCancelUserId";//流程撤销用户id操作
     public static final Long APPROVE_CANCEL_USER_ID = -1L;//流程撤销用户id操作