瀏覽代碼

流程全表单测试

wangliang 1 年之前
父節點
當前提交
667a93483f

+ 115 - 115
sop-business/src/main/java/com/qmth/sop/business/activiti/ProcessEventRejectCmd.java

@@ -1,115 +1,115 @@
-package com.qmth.sop.business.activiti;
-
-import com.qmth.sop.common.contant.SpringContextHolder;
-import com.qmth.sop.common.contant.SystemConstant;
-import org.activiti.bpmn.model.BpmnModel;
-import org.activiti.bpmn.model.FlowNode;
-import org.activiti.engine.HistoryService;
-import org.activiti.engine.ManagementService;
-import org.activiti.engine.RepositoryService;
-import org.activiti.engine.history.HistoricTaskInstance;
-import org.activiti.engine.impl.history.HistoryManager;
-import org.activiti.engine.impl.interceptor.Command;
-import org.activiti.engine.impl.interceptor.CommandContext;
-import org.activiti.engine.impl.persistence.entity.ExecutionEntity;
-import org.activiti.engine.impl.persistence.entity.TaskEntity;
-import org.activiti.engine.impl.persistence.entity.TaskEntityManager;
-import org.springframework.util.CollectionUtils;
-
-import java.util.*;
-
-/**
- * @Description: 驳回任意节点
- * @Param:
- * @return:
- * @Author: wangliang
- * @Date: 2023/7/22
- */
-public class ProcessEventRejectCmd implements Command {
-
-    /**
-     * 任务ID
-     */
-    private String taskId;
-
-    /**
-     * 目标任务节点key
-     */
-    private String destTaskKey;
-
-
-    private Map<String, Object> map = new HashMap<>();
-
-    /**
-     * @param taskId      任务ID
-     * @param destTaskKey 目标任务节点key
-     */
-    public ProcessEventRejectCmd(String taskId, String destTaskKey, Map<String, Object> map) {
-        this.taskId = taskId;
-        this.destTaskKey = destTaskKey;
-        this.map = map;
-    }
-
-    @Override
-    public Object execute(CommandContext commandContext) {
-        RepositoryService repositoryService = SpringContextHolder.getBean(RepositoryService.class);
-        HistoryService historyService = SpringContextHolder.getBean(HistoryService.class);
-        //获取任务实例管理类
-        TaskEntityManager taskEntityManager = commandContext.getTaskEntityManager();
-        //获取当前任务实例
-        TaskEntity currentTask = taskEntityManager.findById(taskId);
-
-        List<HistoricTaskInstance> historicTaskInstanceList = historyService.createHistoricTaskInstanceQuery()
-                .processInstanceId(currentTask.getProcessInstanceId()).orderByHistoricTaskInstanceEndTime().desc().list();
-
-        //获取当前节点的执行实例
-        List<String> rejectApproveIdList = new ArrayList<>();
-        if (!CollectionUtils.isEmpty(historicTaskInstanceList)) {
-            Integer index = null;
-            for (HistoricTaskInstance historicTaskInstance : historicTaskInstanceList) {
-                if (Objects.equals(historicTaskInstance.getTaskDefinitionKey(), destTaskKey)) {
-                    String formKey = historicTaskInstance.getFormKey();
-                    if (Objects.nonNull(formKey)) {
-                        index = Integer.valueOf(formKey.substring(formKey.indexOf(".") - 1, formKey.indexOf(".")));
-                    }
-                    rejectApproveIdList.add(historicTaskInstance.getAssignee());
-                }
-            }
-            map.put(SystemConstant.ASSIGNEE + index, rejectApproveIdList);
-            map.put(SystemConstant.DEFAULT_ASSIGNEE_LIST + index, rejectApproveIdList);
-        }
-        //获取当前节点的执行实例
-        ExecutionEntity execution = currentTask.getExecution();
-        execution.setVariables(map);
-
-        //获取流程定义id
-        String processDefinitionId = execution.getProcessDefinitionId();
-        //获取目标节点
-        BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
-        FlowNode flowElement = (FlowNode) bpmnModel.getMainProcess().getFlowElement(destTaskKey);
-
-        //获取历史管理
-        HistoryManager historyManager = commandContext.getHistoryManager();
-
-        //通知当前活动结束(更新act_hi_actinst)
-        historyManager.recordActivityEnd(execution, "jump to " + taskId);
-        //通知任务节点结束(更新act_hi_taskinst)
-        historyManager.recordTaskEnd(taskId, "jump to" + destTaskKey);
-        //删除正在执行的当前任务
-        taskEntityManager.delete(taskId);
-        //此时设置执行实例的当前活动节点为目标节点
-        execution.setCurrentFlowElement(flowElement);
-        //向operations中压入继续流程的操作类
-        commandContext.getAgenda().planContinueProcessOperation(execution);
-        return null;
-    }
-
-    /**
-     * 跳转任意节点
-     *
-     * @param managementService
-     */
-    public void jump(ManagementService managementService) {
-        managementService.executeCommand(this);
-    }
-}
+//package com.qmth.sop.business.activiti;
+//
+//import com.qmth.sop.common.contant.SpringContextHolder;
+//import com.qmth.sop.common.contant.SystemConstant;
+//import org.activiti.bpmn.model.BpmnModel;
+//import org.activiti.bpmn.model.FlowNode;
+//import org.activiti.engine.HistoryService;
+//import org.activiti.engine.ManagementService;
+//import org.activiti.engine.RepositoryService;
+//import org.activiti.engine.history.HistoricTaskInstance;
+//import org.activiti.engine.impl.history.HistoryManager;
+//import org.activiti.engine.impl.interceptor.Command;
+//import org.activiti.engine.impl.interceptor.CommandContext;
+//import org.activiti.engine.impl.persistence.entity.ExecutionEntity;
+//import org.activiti.engine.impl.persistence.entity.TaskEntity;
+//import org.activiti.engine.impl.persistence.entity.TaskEntityManager;
+//import org.springframework.util.CollectionUtils;
+//
+//import java.util.*;
+//
+///**
+// * @Description: 驳回任意节点
+// * @Param:
+// * @return:
+// * @Author: wangliang
+// * @Date: 2023/7/22
+// */
+//public class ProcessEventRejectCmd implements Command {
+//
+//    /**
+//     * 任务ID
+//     */
+//    private String taskId;
+//
+//    /**
+//     * 目标任务节点key
+//     */
+//    private String destTaskKey;
+//
+//
+//    private Map<String, Object> map = new HashMap<>();
+//
+//    /**
+//     * @param taskId      任务ID
+//     * @param destTaskKey 目标任务节点key
+//     */
+//    public ProcessEventRejectCmd(String taskId, String destTaskKey, Map<String, Object> map) {
+//        this.taskId = taskId;
+//        this.destTaskKey = destTaskKey;
+//        this.map = map;
+//    }
+//
+//    @Override
+//    public Object execute(CommandContext commandContext) {
+//        RepositoryService repositoryService = SpringContextHolder.getBean(RepositoryService.class);
+//        HistoryService historyService = SpringContextHolder.getBean(HistoryService.class);
+//        //获取任务实例管理类
+//        TaskEntityManager taskEntityManager = commandContext.getTaskEntityManager();
+//        //获取当前任务实例
+//        TaskEntity currentTask = taskEntityManager.findById(taskId);
+//
+//        List<HistoricTaskInstance> historicTaskInstanceList = historyService.createHistoricTaskInstanceQuery()
+//                .processInstanceId(currentTask.getProcessInstanceId()).orderByHistoricTaskInstanceEndTime().desc().list();
+//
+//        //获取当前节点的执行实例
+//        List<String> rejectApproveIdList = new ArrayList<>();
+//        if (!CollectionUtils.isEmpty(historicTaskInstanceList)) {
+//            Integer index = null;
+//            for (HistoricTaskInstance historicTaskInstance : historicTaskInstanceList) {
+//                if (Objects.equals(historicTaskInstance.getTaskDefinitionKey(), destTaskKey)) {
+//                    String formKey = historicTaskInstance.getFormKey();
+//                    if (Objects.nonNull(formKey)) {
+//                        index = Integer.valueOf(formKey.substring(formKey.indexOf(".") - 1, formKey.indexOf(".")));
+//                    }
+//                    rejectApproveIdList.add(historicTaskInstance.getAssignee());
+//                }
+//            }
+//            map.put(SystemConstant.ASSIGNEE + index, rejectApproveIdList);
+//            map.put(SystemConstant.DEFAULT_ASSIGNEE_LIST + index, rejectApproveIdList);
+//        }
+//        //获取当前节点的执行实例
+//        ExecutionEntity execution = currentTask.getExecution();
+//        execution.setVariables(map);
+//
+//        //获取流程定义id
+//        String processDefinitionId = execution.getProcessDefinitionId();
+//        //获取目标节点
+//        BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
+//        FlowNode flowElement = (FlowNode) bpmnModel.getMainProcess().getFlowElement(destTaskKey);
+//
+//        //获取历史管理
+//        HistoryManager historyManager = commandContext.getHistoryManager();
+//
+//        //通知当前活动结束(更新act_hi_actinst)
+//        historyManager.recordActivityEnd(execution, "jump to " + taskId);
+//        //通知任务节点结束(更新act_hi_taskinst)
+//        historyManager.recordTaskEnd(taskId, "jump to" + destTaskKey);
+//        //删除正在执行的当前任务
+//        taskEntityManager.delete(taskId);
+//        //此时设置执行实例的当前活动节点为目标节点
+//        execution.setCurrentFlowElement(flowElement);
+//        //向operations中压入继续流程的操作类
+//        commandContext.getAgenda().planContinueProcessOperation(execution);
+//        return null;
+//    }
+//
+//    /**
+//     * 跳转任意节点
+//     *
+//     * @param managementService
+//     */
+//    public void jump(ManagementService managementService) {
+//        managementService.executeCommand(this);
+//    }
+//}

+ 1 - 1
sop-common/src/main/java/com/qmth/sop/common/contant/SystemConstant.java

@@ -116,7 +116,7 @@ public class SystemConstant {
     public static final Integer END_TEMP_ID = 100000000;
     public static final String FORM_PROPERTIES = "formProperties";
     public static final String FLOW_DEPLOYMENT_ID = "flowDeploymentId";
-//    public static final String APPROVE = "approve";//流程审核变量
+    public static final String APPROVE = "approve";//流程审核变量
     public static final String DEFAULT_ASSIGNEE_LIST = "assigneeList";
     public static final String ASSIGNEE = "assignee";
     public static final String NR_OF_COMPLETED_INSTANCES = "nrOfCompletedInstances";

+ 36 - 15
sop-server/src/main/java/com/qmth/sop/server/api/ActivitiFromHtmlController.java

@@ -3,7 +3,6 @@ package com.qmth.sop.server.api;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.qmth.boot.api.exception.ApiException;
-import com.qmth.sop.business.activiti.ProcessEventRejectCmd;
 import com.qmth.sop.business.bean.FormPropertyBean;
 import com.qmth.sop.business.bean.result.FlowResult;
 import com.qmth.sop.business.bean.result.FlowTaskResult;
@@ -23,11 +22,8 @@ import io.swagger.annotations.*;
 import org.activiti.bpmn.model.BpmnModel;
 import org.activiti.bpmn.model.FlowNode;
 import org.activiti.bpmn.model.UserTask;
-import org.activiti.engine.FormService;
-import org.activiti.engine.RepositoryService;
-import org.activiti.engine.RuntimeService;
-import org.activiti.engine.TaskService;
-import org.activiti.engine.impl.TaskServiceImpl;
+import org.activiti.engine.*;
+import org.activiti.engine.history.HistoricTaskInstance;
 import org.activiti.engine.impl.bpmn.behavior.MultiInstanceActivityBehavior;
 import org.activiti.engine.repository.DeploymentBuilder;
 import org.activiti.engine.runtime.ProcessInstance;
@@ -85,6 +81,9 @@ public class ActivitiFromHtmlController {
     @Resource
     MemoryLock memoryLock;
 
+    @Resource
+    HistoryService historyService;
+
     @ApiOperation(value = "创建流程接口")
     @RequestMapping(value = "/createDeployment", method = RequestMethod.POST)
     @Transactional
@@ -170,11 +169,13 @@ public class ActivitiFromHtmlController {
         }
         map.putAll(formDataMap);
 
-        List<String> approveIdList = null;
+        List<String> approveIdList = new ArrayList<>();
         if (!CollectionUtils.isEmpty(approveUserIds)) {
             approveIdList = approveUserIds.stream().map(s -> String.valueOf(s)).collect(Collectors.toList());
         } else {
-            approveIdList.add("123");//否则是当前登录用户
+            if (approve == FlowApprovePassEnum.START || approve == FlowApprovePassEnum.DRAFT || approve == FlowApprovePassEnum.PASS) {
+                approveIdList.add("123");//否则是当前登录用户
+            }
         }
         String processFlowId = null;
         TFCustomFlowEntity tfCustomFlowEntity = null;
@@ -286,20 +287,40 @@ public class ActivitiFromHtmlController {
                                 approve,
                                 approveRemark);
                     }
+                    map.put(SystemConstant.APPROVE, nextFlowTaskResult.getTaskKey());
+                    map.put(SystemConstant.DEFAULT_ASSIGNEE_LIST + nextFlowTaskResult.getSetup(), approveIdList);
                     if (Objects.nonNull(formDataFlowTaskResult) && Objects.equals(task.getTaskDefinitionKey(), formDataFlowTaskResult.getTaskKey())) {
                         setupMap.put(task.getTaskDefinitionKey(), formDataFlowTaskResult);
                     }
                     flowResult.setSetupMap(setupMap);
                     tfCustomFlowEntity.setFlowProcessVar(JacksonUtil.parseJson(flowResult));
-                    if (approve != FlowApprovePassEnum.DRAFT && approve != FlowApprovePassEnum.REJECT) {
-                        taskService.complete(task.getId(), map);
-                    } else if (approve == FlowApprovePassEnum.REJECT) {
-                        ((TaskServiceImpl) taskService).getCommandExecutor().execute(new ProcessEventRejectCmd(task.getId(), nextFlowTaskResult.getTaskKey(), map));
-                        if (Objects.nonNull(map.get(SystemConstant.DEFAULT_ASSIGNEE_LIST + nextFlowTaskResult.getSetup()))) {
-                            List<String> rejectApproveIdList = (List<String>) map.get(SystemConstant.DEFAULT_ASSIGNEE_LIST + nextFlowTaskResult.getSetup());
-                            tfFlowLog.setPendApproveId(rejectApproveIdList.toString().replaceAll("\\[", "").replaceAll("\\]", ""));
+                    if (approve == FlowApprovePassEnum.START || approve == FlowApprovePassEnum.PASS
+                            || approve == FlowApprovePassEnum.CANCEL || approve == FlowApprovePassEnum.REJECT) {
+                        if (approve == FlowApprovePassEnum.CANCEL || approve == FlowApprovePassEnum.REJECT) {
+                            List<HistoricTaskInstance> historicTaskInstanceList = historyService.createHistoricTaskInstanceQuery()
+                                    .processInstanceId(task.getProcessInstanceId()).orderByHistoricTaskInstanceEndTime().desc().list();
+                            if (!CollectionUtils.isEmpty(historicTaskInstanceList)) {
+                                Set<String> approveIdSet = new LinkedHashSet<>();
+                                for (int i = historicTaskInstanceList.size() - 1; i >= 0; i--) {
+                                    HistoricTaskInstance historicTaskInstance = historicTaskInstanceList.get(i);
+                                    if (Objects.equals(historicTaskInstance.getTaskDefinitionKey(), nextFlowTaskResult.getTaskKey())) {
+                                        approveIdSet.add(historicTaskInstance.getAssignee());
+                                    }
+                                }
+                                map.put(SystemConstant.DEFAULT_ASSIGNEE_LIST + nextFlowTaskResult.getSetup(), new ArrayList<>(approveIdSet));
+                            }
                         }
+                        taskService.complete(task.getId(), map);
                     }
+//                    if (approve != FlowApprovePassEnum.DRAFT && approve != FlowApprovePassEnum.REJECT) {
+//                        taskService.complete(task.getId(), map);
+//                    } else if (approve == FlowApprovePassEnum.REJECT) {
+//                        ((TaskServiceImpl) taskService).getCommandExecutor().execute(new ProcessEventRejectCmd(task.getId(), nextFlowTaskResult.getTaskKey(), map));
+//                        if (Objects.nonNull(map.get(SystemConstant.DEFAULT_ASSIGNEE_LIST + nextFlowTaskResult.getSetup()))) {
+//                            List<String> rejectApproveIdList = (List<String>) map.get(SystemConstant.DEFAULT_ASSIGNEE_LIST + nextFlowTaskResult.getSetup());
+//                            tfFlowLog.setPendApproveId(rejectApproveIdList.toString().replaceAll("\\[", "").replaceAll("\\]", ""));
+//                        }
+//                    }
                     tfFlowLogList.add(tfFlowLog);
                 }
             }

+ 70 - 20
sop-server/src/main/resources/testform1.bpmn

@@ -7,13 +7,11 @@
       </multiInstanceLoopCharacteristics>
     </userTask>
     <endEvent id="f_usertask_jwc_end" name="结束"></endEvent>
-    <sequenceFlow id="_8" sourceRef="f_usertask_jwc_inside_approve" targetRef="f_usertask_jwc_end"></sequenceFlow>
     <userTask id="f_usertask_jwc_project" name="教务处sop_项目关键信息" activiti:assignee="${assignee2}" activiti:formKey="project_2.form">
       <multiInstanceLoopCharacteristics isSequential="false" activiti:collection="${assigneeList2}" activiti:elementVariable="assignee2">
         <completionCondition>${nrOfCompletedInstances/nrOfInstances==1 || reject2==1}</completionCondition>
       </multiInstanceLoopCharacteristics>
     </userTask>
-    <sequenceFlow id="flow3" sourceRef="f_usertask_jwc_project" targetRef="f_usertask_jwc_inside_approve"></sequenceFlow>
     <startEvent id="startevent1" name="Start"></startEvent>
     <userTask id="f_usertask_jwc_start" name="新增sop" activiti:assignee="${assignee1}" activiti:formKey="start_1.form">
       <multiInstanceLoopCharacteristics isSequential="false" activiti:collection="${assigneeList1}" activiti:elementVariable="assignee1">
@@ -21,40 +19,92 @@
       </multiInstanceLoopCharacteristics>
     </userTask>
     <sequenceFlow id="flow6" sourceRef="startevent1" targetRef="f_usertask_jwc_start"></sequenceFlow>
-    <sequenceFlow id="flow7" sourceRef="f_usertask_jwc_start" targetRef="f_usertask_jwc_project"></sequenceFlow>
+    <exclusiveGateway id="exclusivegateway2" name="Exclusive Gateway"></exclusiveGateway>
+    <sequenceFlow id="flow12" name="通过" sourceRef="exclusivegateway2" targetRef="f_usertask_jwc_inside_approve">
+      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${approve == 'f_usertask_jwc_inside_approve'}]]></conditionExpression>
+    </sequenceFlow>
+    <sequenceFlow id="flow14" sourceRef="f_usertask_jwc_start" targetRef="f_usertask_jwc_project"></sequenceFlow>
+    <sequenceFlow id="flow15" name="驳回" sourceRef="exclusivegateway2" targetRef="f_usertask_jwc_start">
+      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${approve == 'f_usertask_jwc_start'}]]></conditionExpression>
+    </sequenceFlow>
+    <sequenceFlow id="flow16" sourceRef="f_usertask_jwc_project" targetRef="exclusivegateway2"></sequenceFlow>
+    <exclusiveGateway id="exclusivegateway3" name="Exclusive Gateway"></exclusiveGateway>
+    <sequenceFlow id="flow17" sourceRef="f_usertask_jwc_inside_approve" targetRef="exclusivegateway3"></sequenceFlow>
+    <sequenceFlow id="flow18" name="通过" sourceRef="exclusivegateway3" targetRef="f_usertask_jwc_end">
+      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${approve == 'f_usertask_jwc_end'}]]></conditionExpression>
+    </sequenceFlow>
+    <sequenceFlow id="flow19" name="驳回" sourceRef="exclusivegateway3" targetRef="f_usertask_jwc_project">
+      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${approve == 'f_usertask_jwc_project'}]]></conditionExpression>
+    </sequenceFlow>
   </process>
   <bpmndi:BPMNDiagram id="BPMNDiagram_OFFICE_SOP_FLOW">
     <bpmndi:BPMNPlane bpmnElement="OFFICE_SOP_FLOW" id="BPMNPlane_OFFICE_SOP_FLOW">
       <bpmndi:BPMNShape bpmnElement="f_usertask_jwc_inside_approve" id="BPMNShape_f_usertask_jwc_inside_approve">
-        <omgdc:Bounds height="55.0" width="85.0" x="215.0" y="360.0"></omgdc:Bounds>
+        <omgdc:Bounds height="55.0" width="85.0" x="450.0" y="330.0"></omgdc:Bounds>
       </bpmndi:BPMNShape>
       <bpmndi:BPMNShape bpmnElement="f_usertask_jwc_end" id="BPMNShape_f_usertask_jwc_end">
-        <omgdc:Bounds height="35.0" width="35.0" x="240.0" y="480.0"></omgdc:Bounds>
+        <omgdc:Bounds height="35.0" width="35.0" x="643.0" y="460.0"></omgdc:Bounds>
       </bpmndi:BPMNShape>
       <bpmndi:BPMNShape bpmnElement="f_usertask_jwc_project" id="BPMNShape_f_usertask_jwc_project">
-        <omgdc:Bounds height="55.0" width="85.0" x="215.0" y="240.0"></omgdc:Bounds>
+        <omgdc:Bounds height="55.0" width="85.0" x="450.0" y="130.0"></omgdc:Bounds>
       </bpmndi:BPMNShape>
       <bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
-        <omgdc:Bounds height="35.0" width="35.0" x="240.0" y="80.0"></omgdc:Bounds>
+        <omgdc:Bounds height="35.0" width="35.0" x="240.0" y="40.0"></omgdc:Bounds>
       </bpmndi:BPMNShape>
       <bpmndi:BPMNShape bpmnElement="f_usertask_jwc_start" id="BPMNShape_f_usertask_jwc_start">
-        <omgdc:Bounds height="55.0" width="85.0" x="215.0" y="150.0"></omgdc:Bounds>
+        <omgdc:Bounds height="55.0" width="85.0" x="215.0" y="130.0"></omgdc:Bounds>
       </bpmndi:BPMNShape>
-      <bpmndi:BPMNEdge bpmnElement="_8" id="BPMNEdge__8">
-        <omgdi:waypoint x="257.0" y="415.0"></omgdi:waypoint>
-        <omgdi:waypoint x="257.0" y="480.0"></omgdi:waypoint>
+      <bpmndi:BPMNShape bpmnElement="exclusivegateway2" id="BPMNShape_exclusivegateway2">
+        <omgdc:Bounds height="40.0" width="40.0" x="472.0" y="240.0"></omgdc:Bounds>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape bpmnElement="exclusivegateway3" id="BPMNShape_exclusivegateway3">
+        <omgdc:Bounds height="40.0" width="40.0" x="640.0" y="337.0"></omgdc:Bounds>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNEdge bpmnElement="flow6" id="BPMNEdge_flow6">
+        <omgdi:waypoint x="257.0" y="75.0"></omgdi:waypoint>
+        <omgdi:waypoint x="257.0" y="130.0"></omgdi:waypoint>
       </bpmndi:BPMNEdge>
-      <bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3">
-        <omgdi:waypoint x="257.0" y="295.0"></omgdi:waypoint>
-        <omgdi:waypoint x="257.0" y="360.0"></omgdi:waypoint>
+      <bpmndi:BPMNEdge bpmnElement="flow12" id="BPMNEdge_flow12">
+        <omgdi:waypoint x="492.0" y="280.0"></omgdi:waypoint>
+        <omgdi:waypoint x="492.0" y="330.0"></omgdi:waypoint>
+        <bpmndi:BPMNLabel>
+          <omgdc:Bounds height="16.0" width="22.0" x="492.0" y="280.0"></omgdc:Bounds>
+        </bpmndi:BPMNLabel>
       </bpmndi:BPMNEdge>
-      <bpmndi:BPMNEdge bpmnElement="flow6" id="BPMNEdge_flow6">
-        <omgdi:waypoint x="257.0" y="115.0"></omgdi:waypoint>
-        <omgdi:waypoint x="257.0" y="150.0"></omgdi:waypoint>
+      <bpmndi:BPMNEdge bpmnElement="flow14" id="BPMNEdge_flow14">
+        <omgdi:waypoint x="300.0" y="157.0"></omgdi:waypoint>
+        <omgdi:waypoint x="450.0" y="157.0"></omgdi:waypoint>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="flow15" id="BPMNEdge_flow15">
+        <omgdi:waypoint x="472.0" y="260.0"></omgdi:waypoint>
+        <omgdi:waypoint x="257.0" y="260.0"></omgdi:waypoint>
+        <omgdi:waypoint x="257.0" y="185.0"></omgdi:waypoint>
+        <bpmndi:BPMNLabel>
+          <omgdc:Bounds height="16.0" width="100.0" x="472.0" y="260.0"></omgdc:Bounds>
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="flow16" id="BPMNEdge_flow16">
+        <omgdi:waypoint x="492.0" y="185.0"></omgdi:waypoint>
+        <omgdi:waypoint x="492.0" y="240.0"></omgdi:waypoint>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="flow17" id="BPMNEdge_flow17">
+        <omgdi:waypoint x="535.0" y="357.0"></omgdi:waypoint>
+        <omgdi:waypoint x="640.0" y="357.0"></omgdi:waypoint>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="flow18" id="BPMNEdge_flow18">
+        <omgdi:waypoint x="660.0" y="377.0"></omgdi:waypoint>
+        <omgdi:waypoint x="660.0" y="460.0"></omgdi:waypoint>
+        <bpmndi:BPMNLabel>
+          <omgdc:Bounds height="16.0" width="100.0" x="660.0" y="377.0"></omgdc:Bounds>
+        </bpmndi:BPMNLabel>
       </bpmndi:BPMNEdge>
-      <bpmndi:BPMNEdge bpmnElement="flow7" id="BPMNEdge_flow7">
-        <omgdi:waypoint x="257.0" y="205.0"></omgdi:waypoint>
-        <omgdi:waypoint x="257.0" y="240.0"></omgdi:waypoint>
+      <bpmndi:BPMNEdge bpmnElement="flow19" id="BPMNEdge_flow19">
+        <omgdi:waypoint x="660.0" y="337.0"></omgdi:waypoint>
+        <omgdi:waypoint x="660.0" y="158.0"></omgdi:waypoint>
+        <omgdi:waypoint x="535.0" y="157.0"></omgdi:waypoint>
+        <bpmndi:BPMNLabel>
+          <omgdc:Bounds height="16.0" width="100.0" x="660.0" y="337.0"></omgdc:Bounds>
+        </bpmndi:BPMNLabel>
       </bpmndi:BPMNEdge>
     </bpmndi:BPMNPlane>
   </bpmndi:BPMNDiagram>

二進制
sop-server/src/main/resources/testform1.zip