Commit 222732f7e0c2f8c510d5d986ea48cd4b05b8b96b

Authored by cuicui
2 parents ed58667a 0a91864b

Merge branch 'feature/bpm-back' of https://gitee.com/zhijiantianya/ruoyi-vue-pro…

… into feature/bpm-back
Showing 18 changed files with 676 additions and 2 deletions
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java
@@ -76,4 +76,13 @@ public class BpmTaskController { @@ -76,4 +76,13 @@ public class BpmTaskController {
76 taskService.updateTaskAssignee(getLoginUserId(), reqVO); 76 taskService.updateTaskAssignee(getLoginUserId(), reqVO);
77 return success(true); 77 return success(true);
78 } 78 }
  79 + @PutMapping("/back")
  80 + @ApiOperation(value = "回退")
  81 +// @PreAuthorize("@ss.hasPermission('bpm:task:back')")
  82 + public CommonResult<Boolean> backTask(@Valid @RequestBody BpmTaskUpdateAssigneeReqVO reqVO) {
  83 + //先硬编码到 回退到第一个审批节点
  84 + String destinationTaskDefKey = "task01";
  85 + taskService.backTask(reqVO.getId(),destinationTaskDefKey);
  86 + return success(true);
  87 + }
79 } 88 }
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java
@@ -76,6 +76,12 @@ public interface BpmTaskService { @@ -76,6 +76,12 @@ public interface BpmTaskService {
76 * @param reqVO 不通过请求 76 * @param reqVO 不通过请求
77 */ 77 */
78 void rejectTask(Long userId, @Valid BpmTaskRejectReqVO reqVO); 78 void rejectTask(Long userId, @Valid BpmTaskRejectReqVO reqVO);
  79 + /**
  80 + * 回退任务
  81 + *
  82 + * @param taskId 任务编号
  83 + */
  84 + void backTask(String taskId,String destinationTaskDefKey);
79 85
80 /** 86 /**
81 * 将流程任务分配给指定用户 87 * 将流程任务分配给指定用户
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java
@@ -17,6 +17,7 @@ import cn.iocoder.yudao.module.system.api.user.AdminUserApi; @@ -17,6 +17,7 @@ import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
17 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; 17 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
18 import lombok.extern.slf4j.Slf4j; 18 import lombok.extern.slf4j.Slf4j;
19 import org.flowable.engine.HistoryService; 19 import org.flowable.engine.HistoryService;
  20 +import org.flowable.engine.RuntimeService;
20 import org.flowable.engine.TaskService; 21 import org.flowable.engine.TaskService;
21 import org.flowable.engine.history.HistoricProcessInstance; 22 import org.flowable.engine.history.HistoricProcessInstance;
22 import org.flowable.engine.runtime.ProcessInstance; 23 import org.flowable.engine.runtime.ProcessInstance;
@@ -51,6 +52,8 @@ public class BpmTaskServiceImpl implements BpmTaskService{ @@ -51,6 +52,8 @@ public class BpmTaskServiceImpl implements BpmTaskService{
51 @Resource 52 @Resource
52 private TaskService taskService; 53 private TaskService taskService;
53 @Resource 54 @Resource
  55 + private RuntimeService runtimeService;
  56 + @Resource
54 private HistoryService historyService; 57 private HistoryService historyService;
55 58
56 @Resource 59 @Resource
@@ -204,6 +207,16 @@ public class BpmTaskServiceImpl implements BpmTaskService{ @@ -204,6 +207,16 @@ public class BpmTaskServiceImpl implements BpmTaskService{
204 } 207 }
205 208
206 @Override 209 @Override
  210 + public void backTask(String taskId,String destinationTaskDefKey) {
  211 + Task currentTask = taskService.createTaskQuery().taskId(taskId).singleResult();
  212 +
  213 + runtimeService.createChangeActivityStateBuilder()
  214 + .processInstanceId(currentTask.getProcessInstanceId())
  215 + .moveActivityIdTo(currentTask.getTaskDefinitionKey(), destinationTaskDefKey)
  216 + .changeState();
  217 + }
  218 +
  219 + @Override
207 public void updateTaskAssignee(Long userId, BpmTaskUpdateAssigneeReqVO reqVO) { 220 public void updateTaskAssignee(Long userId, BpmTaskUpdateAssigneeReqVO reqVO) {
208 // 校验任务存在 221 // 校验任务存在
209 Task task = checkTask(userId, reqVO.getId()); 222 Task task = checkTask(userId, reqVO.getId());
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/java/cn/iocoder/yudao/module/bpm/LeaveFormKeyTest.java
@@ -88,6 +88,23 @@ public class LeaveFormKeyTest extends AbstractOATest { @@ -88,6 +88,23 @@ public class LeaveFormKeyTest extends AbstractOATest {
88 } 88 }
89 89
90 /** 90 /**
  91 + * 任意流程的跳转
  92 + */
  93 + @Test
  94 + public void taskJump(){
  95 + // 当前任务
  96 + String taskId="ddd";
  97 + Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
  98 + String assignee = "下一个自由跳转人";
  99 + taskService.setAssignee(taskId,assignee);
  100 + // 自由跳转
  101 + String taskDefKey="目标-任务名称";
  102 + //moveActivityIdTo的两个参数,源任务key,目标任务key
  103 + runtimeService.createChangeActivityStateBuilder().processInstanceId(task.getProcessInstanceId()).moveActivityIdTo(task.getTaskDefinitionKey(), taskDefKey).changeState();
  104 +
  105 + }
  106 +
  107 + /**
91 * 领导驳回后申请人取消申请 108 * 领导驳回后申请人取消申请
92 */ 109 */
93 @Test 110 @Test
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/java/cn/iocoder/yudao/module/bpm/MultiInstancesTest.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm;
  2 +
  3 +import org.flowable.engine.history.HistoricDetail;
  4 +import org.flowable.engine.history.HistoricFormProperty;
  5 +import org.flowable.engine.history.HistoricProcessInstance;
  6 +import org.flowable.engine.history.HistoricVariableUpdate;
  7 +import org.flowable.engine.repository.ProcessDefinition;
  8 +import org.flowable.engine.runtime.ProcessInstance;
  9 +import org.flowable.engine.test.Deployment;
  10 +import org.flowable.task.api.Task;
  11 +import org.junit.Test;
  12 +
  13 +import java.text.SimpleDateFormat;
  14 +import java.util.*;
  15 +
  16 +import static org.junit.Assert.assertEquals;
  17 +import static org.junit.Assert.assertNotNull;
  18 +
  19 +/**
  20 + * @author henryyan
  21 + * testMultiInstanceForUserTask 会签
  22 + * cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.BpmUserTaskActivityBehavior#handleAssignments(org.flowable.task.service.TaskService, java.lang.String, java.lang.String, java.util.List, java.util.List, org.flowable.task.service.impl.persistence.entity.TaskEntity, org.flowable.common.engine.impl.el.ExpressionManager, org.flowable.engine.delegate.DelegateExecution, org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl)
  23 + * 执行了两次,任务分配到了同一个人
  24 + */
  25 +public class MultiInstancesTest extends AbstractOATest {
  26 +
  27 + /**
  28 + * Java Service多实例(是否顺序结果一样)
  29 + */
  30 + @Test
  31 + @Deployment(resources = {"diagrams/chapter9/testMultiInstanceFixedNumbers.bpmn"})
  32 + public void testParallel() throws Exception {
  33 + Map<String, Object> variables = new HashMap<String, Object>();
  34 + long loop = 3;
  35 + variables.put("loop", loop);
  36 + variables.put("counter", 0); // 计数器
  37 + ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("testMultiInstanceFixedNumbers", variables);
  38 + Object variable = runtimeService.getVariable(processInstance.getId(), "counter");
  39 + assertEquals(loop, variable);
  40 + }
  41 +
  42 + /**
  43 + * 用户任务多实例--顺序
  44 + */
  45 + @Test
  46 + @Deployment(resources = {"diagrams/chapter9/testMultiInstanceForUserTask.sequential.bpmn"})
  47 + public void testForUserSequence() throws Exception {
  48 + ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("testMultiInstanceForUserTask");
  49 + long count = taskService.createTaskQuery().processInstanceId(processInstance.getId()).count();
  50 + assertEquals(1, count);
  51 +
  52 + Task task = taskService.createTaskQuery().singleResult();
  53 + taskService.complete(task.getId());
  54 + count = taskService.createTaskQuery().processInstanceId(processInstance.getId()).count();
  55 + assertEquals(1, count);
  56 +
  57 + task = taskService.createTaskQuery().singleResult();
  58 + taskService.complete(task.getId());
  59 + count = taskService.createTaskQuery().processInstanceId(processInstance.getId()).count();
  60 + assertEquals(1, count);
  61 +
  62 + task = taskService.createTaskQuery().singleResult();
  63 + taskService.complete(task.getId());
  64 + count = taskService.createTaskQuery().processInstanceId(processInstance.getId()).count();
  65 + assertEquals(0, count);
  66 + }
  67 +
  68 + /**
  69 + * 用户任务多实例--并行
  70 + */
  71 + @Test
  72 + @Deployment(resources = {"diagrams/chapter9/testMultiInstanceForUserTask.nosequential.bpmn"})
  73 + public void testForUserNoSequential() throws Exception {
  74 + ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("testMultiInstanceForUserTask");
  75 + long count = taskService.createTaskQuery().processInstanceId(processInstance.getId()).count();
  76 + assertEquals(3, count);
  77 + }
  78 +
  79 + /**
  80 + * 用户任务多实例,通过用户数量决定实例个数--并行
  81 + */
  82 + @Test
  83 + @Deployment(resources = {"diagrams/chapter9/testMultiInstanceForUserTask.users.nosequential.bpmn"})
  84 + public void testForUserCreateByUsersNoSequential() throws Exception {
  85 + Map<String, Object> variables = new HashMap<String, Object>();
  86 + List<String> users = Arrays.asList("user1", "user2", "user3");
  87 + variables.put("users", users);
  88 + runtimeService.startProcessInstanceByKey("testMultiInstanceForUserTask", variables);
  89 + for (String userId : users) {
  90 + assertEquals(1, taskService.createTaskQuery().taskAssignee(userId).count());
  91 + }
  92 + }
  93 +
  94 + /**
  95 + * 用户任务多实例,通过用户数量决定实例个数--顺序
  96 + */
  97 + @Test
  98 + @Deployment(resources = {"diagrams/chapter9/testMultiInstanceForUserTask.users.sequential.bpmn"})
  99 + public void testForUserCreateByUsersSequential() throws Exception {
  100 + Map<String, Object> variables = new HashMap<String, Object>();
  101 + List<String> users = Arrays.asList("user1", "user2", "user3");
  102 + variables.put("users", users);
  103 + runtimeService.startProcessInstanceByKey("testMultiInstanceForUserTask", variables);
  104 + for (String userId : users) {
  105 + Task task = taskService.createTaskQuery().taskAssignee(userId).singleResult();
  106 + taskService.complete(task.getId());
  107 + }
  108 + }
  109 +
  110 + /**
  111 + * 用户任务多实例,按照任务完成的百分比比率决定是否提前结束流程
  112 + */
  113 + @Test
  114 + @Deployment(resources = {"diagrams/chapter9/testMultiInstanceForUserTask.users.sequential.with.complete.conditon.bpmn"})
  115 + public void testForUserCreateByUsersSequentialWithCompleteCondition() throws Exception {
  116 + Map<String, Object> variables = new HashMap<String, Object>();
  117 + List<String> users = Arrays.asList("user1", "user2", "user3");
  118 + variables.put("users", users);
  119 + variables.put("rate", 0.6d);
  120 + runtimeService.startProcessInstanceByKey("testMultiInstanceForUserTask", variables);
  121 +
  122 + Task task = taskService.createTaskQuery().taskAssignee("user1").singleResult();
  123 + taskService.complete(task.getId());
  124 +
  125 + task = taskService.createTaskQuery().taskAssignee("user2").singleResult();
  126 + taskService.complete(task.getId());
  127 +
  128 + long count = historyService.createHistoricProcessInstanceQuery().finished().count();
  129 + assertEquals(1, count);
  130 +
  131 + }
  132 +
  133 + /**
  134 + * 用户任务多实例,按照任务完成的百分比比率决定是否提前结束流程
  135 + */
  136 + @Test
  137 + @Deployment(resources = {"diagrams/chapter9/testMultiInstanceForUserTask.exception.bpmn"})
  138 + public void testForUserCreateByUsersException() throws Exception {
  139 + Map<String, Object> variables = new HashMap<String, Object>();
  140 + List<String> users = Arrays.asList("user1", "user2", "user3");
  141 + variables.put("users", users);
  142 + runtimeService.startProcessInstanceByKey("testMultiInstanceForUserTask", variables);
  143 +
  144 + Task task = taskService.createTaskQuery().taskAssignee("user1").singleResult();
  145 + taskService.complete(task.getId());
  146 +
  147 + task = taskService.createTaskQuery().taskAssignee("user2").singleResult();
  148 + taskService.complete(task.getId());
  149 +
  150 + task = taskService.createTaskQuery().taskAssignee("user3").singleResult();
  151 + taskService.complete(task.getId());
  152 +
  153 + List<Task> list = taskService.createTaskQuery().list();
  154 + for (Task task2 : list) {
  155 + System.out.println("============" + task2.getName());
  156 + }
  157 +
  158 + }
  159 + /////////////////////////////////////////////////
  160 + /**
  161 + * 全部通过
  162 + */
  163 + @Test
  164 + @Deployment(resources = {"diagrams/chapter9/leave-countersign.bpmn"})
  165 + public void testAllApproved() throws Exception {
  166 + Map<String, Object> variables = new HashMap<String, Object>();
  167 + List<String> users = Arrays.asList("groupLeader", "deptLeader", "hr");
  168 + variables.put("users", users);
  169 + identityService.setAuthenticatedUserId("henryyan");
  170 + ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("leave-countersign", variables);
  171 + for (String user : users) {
  172 + Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).taskAssignee(user).singleResult();
  173 + Map<String, Object> taskVariables = new HashMap<String, Object>();
  174 + taskVariables.put("approved", "true");
  175 + taskService.complete(task.getId(), taskVariables);
  176 + }
  177 +
  178 + Task task = taskService.createTaskQuery().taskAssignee("henryyan").singleResult();
  179 + assertNotNull(task);
  180 + assertEquals("销假", task.getName());
  181 + }
  182 +
  183 + /**
  184 + * 部分通过
  185 + */
  186 + @Test
  187 + @Deployment(resources = {"diagrams/chapter9/leave-countersign.bpmn"})
  188 + public void testNotAllApproved() throws Exception {
  189 + Map<String, Object> variables = new HashMap<String, Object>();
  190 + List<String> users = Arrays.asList("groupLeader", "deptLeader", "hr");
  191 + variables.put("users", users);
  192 + identityService.setAuthenticatedUserId("henryyan");
  193 + ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("leave-countersign", variables);
  194 + for (String user : users) {
  195 + Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).taskAssignee(user).singleResult();
  196 + Map<String, Object> taskVariables = new HashMap<String, Object>();
  197 + taskVariables.put("approved", "false");
  198 + taskService.complete(task.getId(), taskVariables);
  199 + }
  200 +
  201 + Task task = taskService.createTaskQuery().taskAssignee("henryyan").singleResult();
  202 + assertNotNull(task);
  203 + assertEquals("调整申请", task.getName());
  204 + }
  205 +}
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/resources/diagrams/chapter9/leave-countersign.bpmn 0 → 100644
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3 + 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"
  4 + xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath"
  5 + targetNamespace="http://www.activiti.org/test">
  6 + <process id="leave-countersign" name="请假流程-会签" isExecutable="true">
  7 + <documentation>请假流程演示-会签</documentation>
  8 + <startEvent id="startevent1" name="Start" activiti:initiator="applyUserId">
  9 + <extensionElements>
  10 + <activiti:formProperty id="startDate" name="请假开始日期" type="date" datePattern="yyyy-MM-dd" required="true"></activiti:formProperty>
  11 + <activiti:formProperty id="endDate" name="请假结束日期" type="date" datePattern="yyyy-MM-dd" required="true"></activiti:formProperty>
  12 + <activiti:formProperty id="reason" name="请假原因" type="string" required="true"></activiti:formProperty>
  13 + <activiti:formProperty id="users" name="审批参与人" type="users" required="true"></activiti:formProperty>
  14 + <activiti:formProperty id="validScript" type="javascript" default="alert('表单已经加载完毕');"></activiti:formProperty>
  15 + </extensionElements>
  16 + </startEvent>
  17 + <userTask id="countersign" name="[部门/人事]联合会签" activiti:assignee="${user}">
  18 + <extensionElements>
  19 + <activiti:formProperty id="startDate" name="请假开始日期" type="date" datePattern="yyyy-MM-dd" writable="false"></activiti:formProperty>
  20 + <activiti:formProperty id="endDate" name="请假结束日期" type="date" datePattern="yyyy-MM-dd" writable="false"></activiti:formProperty>
  21 + <activiti:formProperty id="reason" name="请假原因" type="string" writable="false"></activiti:formProperty>
  22 + <activiti:formProperty id="approved" name="审批意见" type="enum" required="true">
  23 + <activiti:value id="true" name="同意"></activiti:value>
  24 + <activiti:value id="false" name="拒绝"></activiti:value>
  25 + </activiti:formProperty>
  26 + <activiti:taskListener event="complete" delegateExpression="${leaveCounterSignCompleteListener}"></activiti:taskListener>
  27 + </extensionElements>
  28 + <multiInstanceLoopCharacteristics isSequential="false" activiti:collection="users"
  29 + activiti:elementVariable="user"></multiInstanceLoopCharacteristics>
  30 + </userTask>
  31 + <userTask id="reportBack" name="销假" activiti:assignee="${applyUserId}">
  32 + <extensionElements>
  33 + <activiti:formProperty id="startDate" name="请假开始日期" type="date" datePattern="yyyy-MM-dd" writable="false"></activiti:formProperty>
  34 + <activiti:formProperty id="endDate" name="请假结束日期" type="date" datePattern="yyyy-MM-dd" writable="false"></activiti:formProperty>
  35 + <activiti:formProperty id="reason" name="请假原因" type="string" writable="false"></activiti:formProperty>
  36 + <activiti:formProperty id="reportBackDate" name="销假日期" type="date" default="${endDate}" datePattern="yyyy-MM-dd"
  37 + required="true"></activiti:formProperty>
  38 + </extensionElements>
  39 + </userTask>
  40 + <endEvent id="endevent1" name="End"></endEvent>
  41 + <sequenceFlow id="flow2" sourceRef="startevent1" targetRef="countersign">
  42 + <extensionElements>
  43 + <activiti:executionListener event="take" expression="${execution.setVariable('approvedCounter', 0)}"></activiti:executionListener>
  44 + </extensionElements>
  45 + </sequenceFlow>
  46 + <sequenceFlow id="flow8" name="销假" sourceRef="reportBack" targetRef="endevent1">
  47 + <extensionElements>
  48 + <activiti:executionListener event="take" expression="${execution.setVariable('result', 'ok')}"></activiti:executionListener>
  49 + </extensionElements>
  50 + </sequenceFlow>
  51 + <sequenceFlow id="flow13" name="全部通过" sourceRef="exclusivegateway1" targetRef="reportBack">
  52 + <conditionExpression xsi:type="tFormalExpression"><![CDATA[${approvedCounter == users.size()}]]></conditionExpression>
  53 + </sequenceFlow>
  54 + <exclusiveGateway id="exclusivegateway1" name="Exclusive Gateway"></exclusiveGateway>
  55 + <sequenceFlow id="flow14" sourceRef="countersign" targetRef="exclusivegateway1"></sequenceFlow>
  56 + <userTask id="modifyApply" name="调整申请" activiti:assignee="${applyUserId}">
  57 + <extensionElements>
  58 + <activiti:formProperty id="startDate" name="请假开始日期" type="date" datePattern="yyyy-MM-dd" required="true"></activiti:formProperty>
  59 + <activiti:formProperty id="endDate" name="请假结束日期" type="date" datePattern="yyyy-MM-dd" required="true"></activiti:formProperty>
  60 + <activiti:formProperty id="reason" name="请假原因" type="string" required="true"></activiti:formProperty>
  61 + <activiti:formProperty id="reApply" name="重新申请" type="enum" required="true">
  62 + <activiti:value id="true" name="重新申请"></activiti:value>
  63 + <activiti:value id="false" name="取消申请"></activiti:value>
  64 + </activiti:formProperty>
  65 + </extensionElements>
  66 + </userTask>
  67 + <sequenceFlow id="flow15" name="部分通过" sourceRef="exclusivegateway1" targetRef="modifyApply">
  68 + <conditionExpression xsi:type="tFormalExpression"><![CDATA[${approvedCounter < users.size()}]]></conditionExpression>
  69 + </sequenceFlow>
  70 + <exclusiveGateway id="exclusivegateway2" name="Exclusive Gateway"></exclusiveGateway>
  71 + <sequenceFlow id="flow16" sourceRef="modifyApply" targetRef="exclusivegateway2"></sequenceFlow>
  72 + <sequenceFlow id="flow17" sourceRef="exclusivegateway2" targetRef="endevent1">
  73 + <conditionExpression xsi:type="tFormalExpression"><![CDATA[${reApply == 'false'}]]></conditionExpression>
  74 + </sequenceFlow>
  75 + <sequenceFlow id="flow18" name="重新申请" sourceRef="exclusivegateway2" targetRef="countersign">
  76 + <extensionElements>
  77 + <activiti:executionListener event="take" expression="${execution.setVariable('approvedCounter', 0)}"></activiti:executionListener>
  78 + </extensionElements>
  79 + <conditionExpression xsi:type="tFormalExpression"><![CDATA[${reApply == 'true'}]]></conditionExpression>
  80 + </sequenceFlow>
  81 + </process>
  82 + <bpmndi:BPMNDiagram id="BPMNDiagram_leave-countersign">
  83 + <bpmndi:BPMNPlane bpmnElement="leave-countersign" id="BPMNPlane_leave-countersign">
  84 + <bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
  85 + <omgdc:Bounds height="35.0" width="35.0" x="10.0" y="30.0"></omgdc:Bounds>
  86 + </bpmndi:BPMNShape>
  87 + <bpmndi:BPMNShape bpmnElement="reportBack" id="BPMNShape_reportBack">
  88 + <omgdc:Bounds height="55.0" width="105.0" x="340.0" y="20.0"></omgdc:Bounds>
  89 + </bpmndi:BPMNShape>
  90 + <bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
  91 + <omgdc:Bounds height="35.0" width="35.0" x="375.0" y="203.0"></omgdc:Bounds>
  92 + </bpmndi:BPMNShape>
  93 + <bpmndi:BPMNShape bpmnElement="countersign" id="BPMNShape_countersign">
  94 + <omgdc:Bounds height="55.0" width="105.0" x="90.0" y="20.0"></omgdc:Bounds>
  95 + </bpmndi:BPMNShape>
  96 + <bpmndi:BPMNShape bpmnElement="exclusivegateway1" id="BPMNShape_exclusivegateway1">
  97 + <omgdc:Bounds height="40.0" width="40.0" x="220.0" y="27.0"></omgdc:Bounds>
  98 + </bpmndi:BPMNShape>
  99 + <bpmndi:BPMNShape bpmnElement="modifyApply" id="BPMNShape_modifyApply">
  100 + <omgdc:Bounds height="55.0" width="105.0" x="188.0" y="110.0"></omgdc:Bounds>
  101 + </bpmndi:BPMNShape>
  102 + <bpmndi:BPMNShape bpmnElement="exclusivegateway2" id="BPMNShape_exclusivegateway2">
  103 + <omgdc:Bounds height="40.0" width="40.0" x="220.0" y="200.0"></omgdc:Bounds>
  104 + </bpmndi:BPMNShape>
  105 + <bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
  106 + <omgdi:waypoint x="45.0" y="47.0"></omgdi:waypoint>
  107 + <omgdi:waypoint x="90.0" y="47.0"></omgdi:waypoint>
  108 + </bpmndi:BPMNEdge>
  109 + <bpmndi:BPMNEdge bpmnElement="flow8" id="BPMNEdge_flow8">
  110 + <omgdi:waypoint x="392.0" y="75.0"></omgdi:waypoint>
  111 + <omgdi:waypoint x="392.0" y="203.0"></omgdi:waypoint>
  112 + <bpmndi:BPMNLabel>
  113 + <omgdc:Bounds height="11.0" width="100.0" x="-22.0" y="-17.0"></omgdc:Bounds>
  114 + </bpmndi:BPMNLabel>
  115 + </bpmndi:BPMNEdge>
  116 + <bpmndi:BPMNEdge bpmnElement="flow13" id="BPMNEdge_flow13">
  117 + <omgdi:waypoint x="260.0" y="47.0"></omgdi:waypoint>
  118 + <omgdi:waypoint x="340.0" y="47.0"></omgdi:waypoint>
  119 + <bpmndi:BPMNLabel>
  120 + <omgdc:Bounds height="11.0" width="100.0" x="-29.0" y="-17.0"></omgdc:Bounds>
  121 + </bpmndi:BPMNLabel>
  122 + </bpmndi:BPMNEdge>
  123 + <bpmndi:BPMNEdge bpmnElement="flow14" id="BPMNEdge_flow14">
  124 + <omgdi:waypoint x="195.0" y="47.0"></omgdi:waypoint>
  125 + <omgdi:waypoint x="220.0" y="47.0"></omgdi:waypoint>
  126 + </bpmndi:BPMNEdge>
  127 + <bpmndi:BPMNEdge bpmnElement="flow15" id="BPMNEdge_flow15">
  128 + <omgdi:waypoint x="240.0" y="67.0"></omgdi:waypoint>
  129 + <omgdi:waypoint x="240.0" y="110.0"></omgdi:waypoint>
  130 + <bpmndi:BPMNLabel>
  131 + <omgdc:Bounds height="11.0" width="100.0" x="10.0" y="0.0"></omgdc:Bounds>
  132 + </bpmndi:BPMNLabel>
  133 + </bpmndi:BPMNEdge>
  134 + <bpmndi:BPMNEdge bpmnElement="flow16" id="BPMNEdge_flow16">
  135 + <omgdi:waypoint x="240.0" y="165.0"></omgdi:waypoint>
  136 + <omgdi:waypoint x="240.0" y="200.0"></omgdi:waypoint>
  137 + </bpmndi:BPMNEdge>
  138 + <bpmndi:BPMNEdge bpmnElement="flow17" id="BPMNEdge_flow17">
  139 + <omgdi:waypoint x="260.0" y="220.0"></omgdi:waypoint>
  140 + <omgdi:waypoint x="375.0" y="220.0"></omgdi:waypoint>
  141 + </bpmndi:BPMNEdge>
  142 + <bpmndi:BPMNEdge bpmnElement="flow18" id="BPMNEdge_flow18">
  143 + <omgdi:waypoint x="220.0" y="220.0"></omgdi:waypoint>
  144 + <omgdi:waypoint x="142.0" y="220.0"></omgdi:waypoint>
  145 + <omgdi:waypoint x="142.0" y="75.0"></omgdi:waypoint>
  146 + <bpmndi:BPMNLabel>
  147 + <omgdc:Bounds height="11.0" width="100.0" x="9.0" y="14.0"></omgdc:Bounds>
  148 + </bpmndi:BPMNLabel>
  149 + </bpmndi:BPMNEdge>
  150 + </bpmndi:BPMNPlane>
  151 + </bpmndi:BPMNDiagram>
  152 +</definitions>
0 \ No newline at end of file 153 \ No newline at end of file
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/resources/diagrams/chapter9/leave-countersign.png 0 → 100644

20 KB

yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/resources/diagrams/chapter9/testMultiInstanceFixedNumbers.bpmn 0 → 100644
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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">
  3 + <process id="testMultiInstanceFixedNumbers" name="testMultiInstanceFixedNumbers" isExecutable="true">
  4 + <startEvent id="startevent1" name="Start"></startEvent>
  5 + <serviceTask id="servicetask1" name="Service Task" activiti:expression="${counter + 1}" activiti:resultVariableName="counter">
  6 + <multiInstanceLoopCharacteristics isSequential="false">
  7 + <loopCardinality>${loop}</loopCardinality>
  8 + </multiInstanceLoopCharacteristics>
  9 + </serviceTask>
  10 + <sequenceFlow id="flow1" sourceRef="startevent1" targetRef="servicetask1"></sequenceFlow>
  11 + <endEvent id="endevent1" name="End"></endEvent>
  12 + <sequenceFlow id="flow2" sourceRef="receivetask1" targetRef="endevent1"></sequenceFlow>
  13 + <receiveTask id="receivetask1" name="Receive Task"></receiveTask>
  14 + <sequenceFlow id="flow3" sourceRef="servicetask1" targetRef="receivetask1"></sequenceFlow>
  15 + </process>
  16 + <bpmndi:BPMNDiagram id="BPMNDiagram_testMultiInstanceFixedNumbers">
  17 + <bpmndi:BPMNPlane bpmnElement="testMultiInstanceFixedNumbers" id="BPMNPlane_testMultiInstanceFixedNumbers">
  18 + <bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
  19 + <omgdc:Bounds height="35.0" width="35.0" x="50.0" y="50.0"></omgdc:Bounds>
  20 + </bpmndi:BPMNShape>
  21 + <bpmndi:BPMNShape bpmnElement="servicetask1" id="BPMNShape_servicetask1">
  22 + <omgdc:Bounds height="55.0" width="105.0" x="116.0" y="40.0"></omgdc:Bounds>
  23 + </bpmndi:BPMNShape>
  24 + <bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
  25 + <omgdc:Bounds height="35.0" width="35.0" x="410.0" y="50.0"></omgdc:Bounds>
  26 + </bpmndi:BPMNShape>
  27 + <bpmndi:BPMNShape bpmnElement="receivetask1" id="BPMNShape_receivetask1">
  28 + <omgdc:Bounds height="55.0" width="105.0" x="260.0" y="40.0"></omgdc:Bounds>
  29 + </bpmndi:BPMNShape>
  30 + <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
  31 + <omgdi:waypoint x="85.0" y="67.0"></omgdi:waypoint>
  32 + <omgdi:waypoint x="116.0" y="67.0"></omgdi:waypoint>
  33 + </bpmndi:BPMNEdge>
  34 + <bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
  35 + <omgdi:waypoint x="365.0" y="67.0"></omgdi:waypoint>
  36 + <omgdi:waypoint x="410.0" y="67.0"></omgdi:waypoint>
  37 + </bpmndi:BPMNEdge>
  38 + <bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3">
  39 + <omgdi:waypoint x="221.0" y="67.0"></omgdi:waypoint>
  40 + <omgdi:waypoint x="260.0" y="67.0"></omgdi:waypoint>
  41 + </bpmndi:BPMNEdge>
  42 + </bpmndi:BPMNPlane>
  43 + </bpmndi:BPMNDiagram>
  44 +</definitions>
0 \ No newline at end of file 45 \ No newline at end of file
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/resources/diagrams/chapter9/testMultiInstanceForUserTask.exception.bpmn 0 → 100644
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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">
  3 + <process id="testMultiInstanceForUserTask" name="testMultiInstanceForUserTask" isExecutable="true">
  4 + <startEvent id="startevent1" name="Start"></startEvent>
  5 + <userTask id="usertask1" name="User Task" activiti:assignee="${user}">
  6 + <multiInstanceLoopCharacteristics isSequential="false" activiti:collection="${users}" activiti:elementVariable="user"></multiInstanceLoopCharacteristics>
  7 + </userTask>
  8 + <sequenceFlow id="flow1" sourceRef="startevent1" targetRef="usertask1"></sequenceFlow>
  9 + <endEvent id="endevent1" name="End"></endEvent>
  10 + <sequenceFlow id="flow2" sourceRef="usertask2" targetRef="endevent1"></sequenceFlow>
  11 + <userTask id="usertask2" name="User Task2"></userTask>
  12 + <sequenceFlow id="flow3" sourceRef="usertask1" targetRef="usertask2"></sequenceFlow>
  13 + </process>
  14 + <bpmndi:BPMNDiagram id="BPMNDiagram_testMultiInstanceForUserTask">
  15 + <bpmndi:BPMNPlane bpmnElement="testMultiInstanceForUserTask" id="BPMNPlane_testMultiInstanceForUserTask">
  16 + <bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
  17 + <omgdc:Bounds height="35.0" width="35.0" x="90.0" y="80.0"></omgdc:Bounds>
  18 + </bpmndi:BPMNShape>
  19 + <bpmndi:BPMNShape bpmnElement="usertask1" id="BPMNShape_usertask1">
  20 + <omgdc:Bounds height="55.0" width="105.0" x="170.0" y="70.0"></omgdc:Bounds>
  21 + </bpmndi:BPMNShape>
  22 + <bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
  23 + <omgdc:Bounds height="35.0" width="35.0" x="340.0" y="190.0"></omgdc:Bounds>
  24 + </bpmndi:BPMNShape>
  25 + <bpmndi:BPMNShape bpmnElement="usertask2" id="BPMNShape_usertask2">
  26 + <omgdc:Bounds height="55.0" width="105.0" x="170.0" y="180.0"></omgdc:Bounds>
  27 + </bpmndi:BPMNShape>
  28 + <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
  29 + <omgdi:waypoint x="125.0" y="97.0"></omgdi:waypoint>
  30 + <omgdi:waypoint x="170.0" y="97.0"></omgdi:waypoint>
  31 + </bpmndi:BPMNEdge>
  32 + <bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
  33 + <omgdi:waypoint x="275.0" y="207.0"></omgdi:waypoint>
  34 + <omgdi:waypoint x="340.0" y="207.0"></omgdi:waypoint>
  35 + </bpmndi:BPMNEdge>
  36 + <bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3">
  37 + <omgdi:waypoint x="222.0" y="125.0"></omgdi:waypoint>
  38 + <omgdi:waypoint x="222.0" y="180.0"></omgdi:waypoint>
  39 + </bpmndi:BPMNEdge>
  40 + </bpmndi:BPMNPlane>
  41 + </bpmndi:BPMNDiagram>
  42 +</definitions>
0 \ No newline at end of file 43 \ No newline at end of file
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/resources/diagrams/chapter9/testMultiInstanceForUserTask.exception.png 0 → 100644

11.5 KB

yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/resources/diagrams/chapter9/testMultiInstanceForUserTask.nosequential.bpmn 0 → 100644
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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">
  3 + <process id="testMultiInstanceForUserTask" name="testMultiInstanceForUserTask" isExecutable="true">
  4 + <startEvent id="startevent1" name="Start"></startEvent>
  5 + <userTask id="usertask1" name="User Task">
  6 + <multiInstanceLoopCharacteristics isSequential="false">
  7 + <loopCardinality>3</loopCardinality>
  8 + </multiInstanceLoopCharacteristics>
  9 + </userTask>
  10 + <sequenceFlow id="flow1" sourceRef="startevent1" targetRef="usertask1"></sequenceFlow>
  11 + <endEvent id="endevent1" name="End"></endEvent>
  12 + <sequenceFlow id="flow2" sourceRef="usertask1" targetRef="endevent1"></sequenceFlow>
  13 + </process>
  14 + <bpmndi:BPMNDiagram id="BPMNDiagram_testMultiInstanceForUserTask">
  15 + <bpmndi:BPMNPlane bpmnElement="testMultiInstanceForUserTask" id="BPMNPlane_testMultiInstanceForUserTask">
  16 + <bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
  17 + <omgdc:Bounds height="35.0" width="35.0" x="90.0" y="80.0"></omgdc:Bounds>
  18 + </bpmndi:BPMNShape>
  19 + <bpmndi:BPMNShape bpmnElement="usertask1" id="BPMNShape_usertask1">
  20 + <omgdc:Bounds height="55.0" width="105.0" x="170.0" y="70.0"></omgdc:Bounds>
  21 + </bpmndi:BPMNShape>
  22 + <bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
  23 + <omgdc:Bounds height="35.0" width="35.0" x="330.0" y="80.0"></omgdc:Bounds>
  24 + </bpmndi:BPMNShape>
  25 + <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
  26 + <omgdi:waypoint x="125.0" y="97.0"></omgdi:waypoint>
  27 + <omgdi:waypoint x="170.0" y="97.0"></omgdi:waypoint>
  28 + </bpmndi:BPMNEdge>
  29 + <bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
  30 + <omgdi:waypoint x="275.0" y="97.0"></omgdi:waypoint>
  31 + <omgdi:waypoint x="330.0" y="97.0"></omgdi:waypoint>
  32 + </bpmndi:BPMNEdge>
  33 + </bpmndi:BPMNPlane>
  34 + </bpmndi:BPMNDiagram>
  35 +</definitions>
0 \ No newline at end of file 36 \ No newline at end of file
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/resources/diagrams/chapter9/testMultiInstanceForUserTask.sequential.bpmn 0 → 100644
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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">
  3 + <process id="testMultiInstanceForUserTask" name="testMultiInstanceForUserTask" isExecutable="true">
  4 + <startEvent id="startevent1" name="Start"></startEvent>
  5 + <userTask id="usertask1" name="User Task">
  6 + <multiInstanceLoopCharacteristics isSequential="true">
  7 + <loopCardinality>3</loopCardinality>
  8 + </multiInstanceLoopCharacteristics>
  9 + </userTask>
  10 + <sequenceFlow id="flow1" sourceRef="startevent1" targetRef="usertask1"></sequenceFlow>
  11 + <endEvent id="endevent1" name="End"></endEvent>
  12 + <sequenceFlow id="flow2" sourceRef="usertask1" targetRef="endevent1"></sequenceFlow>
  13 + </process>
  14 + <bpmndi:BPMNDiagram id="BPMNDiagram_testMultiInstanceForUserTask">
  15 + <bpmndi:BPMNPlane bpmnElement="testMultiInstanceForUserTask" id="BPMNPlane_testMultiInstanceForUserTask">
  16 + <bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
  17 + <omgdc:Bounds height="35.0" width="35.0" x="90.0" y="80.0"></omgdc:Bounds>
  18 + </bpmndi:BPMNShape>
  19 + <bpmndi:BPMNShape bpmnElement="usertask1" id="BPMNShape_usertask1">
  20 + <omgdc:Bounds height="55.0" width="105.0" x="170.0" y="70.0"></omgdc:Bounds>
  21 + </bpmndi:BPMNShape>
  22 + <bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
  23 + <omgdc:Bounds height="35.0" width="35.0" x="330.0" y="80.0"></omgdc:Bounds>
  24 + </bpmndi:BPMNShape>
  25 + <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
  26 + <omgdi:waypoint x="125.0" y="97.0"></omgdi:waypoint>
  27 + <omgdi:waypoint x="170.0" y="97.0"></omgdi:waypoint>
  28 + </bpmndi:BPMNEdge>
  29 + <bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
  30 + <omgdi:waypoint x="275.0" y="97.0"></omgdi:waypoint>
  31 + <omgdi:waypoint x="330.0" y="97.0"></omgdi:waypoint>
  32 + </bpmndi:BPMNEdge>
  33 + </bpmndi:BPMNPlane>
  34 + </bpmndi:BPMNDiagram>
  35 +</definitions>
0 \ No newline at end of file 36 \ No newline at end of file
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/resources/diagrams/chapter9/testMultiInstanceForUserTask.users.nosequential.bpmn 0 → 100644
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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">
  3 + <process id="testMultiInstanceForUserTask" name="testMultiInstanceForUserTask" isExecutable="true">
  4 + <startEvent id="startevent1" name="Start"></startEvent>
  5 + <userTask id="usertask1" name="User Task" activiti:assignee="${user}">
  6 + <multiInstanceLoopCharacteristics isSequential="false" activiti:collection="${users}" activiti:elementVariable="user"></multiInstanceLoopCharacteristics>
  7 + </userTask>
  8 + <sequenceFlow id="flow1" sourceRef="startevent1" targetRef="usertask1"></sequenceFlow>
  9 + <endEvent id="endevent1" name="End"></endEvent>
  10 + <sequenceFlow id="flow2" sourceRef="usertask1" targetRef="endevent1"></sequenceFlow>
  11 + </process>
  12 + <bpmndi:BPMNDiagram id="BPMNDiagram_testMultiInstanceForUserTask">
  13 + <bpmndi:BPMNPlane bpmnElement="testMultiInstanceForUserTask" id="BPMNPlane_testMultiInstanceForUserTask">
  14 + <bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
  15 + <omgdc:Bounds height="35.0" width="35.0" x="50.0" y="90.0"></omgdc:Bounds>
  16 + </bpmndi:BPMNShape>
  17 + <bpmndi:BPMNShape bpmnElement="usertask1" id="BPMNShape_usertask1">
  18 + <omgdc:Bounds height="55.0" width="105.0" x="130.0" y="80.0"></omgdc:Bounds>
  19 + </bpmndi:BPMNShape>
  20 + <bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
  21 + <omgdc:Bounds height="35.0" width="35.0" x="290.0" y="90.0"></omgdc:Bounds>
  22 + </bpmndi:BPMNShape>
  23 + <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
  24 + <omgdi:waypoint x="85.0" y="107.0"></omgdi:waypoint>
  25 + <omgdi:waypoint x="130.0" y="107.0"></omgdi:waypoint>
  26 + </bpmndi:BPMNEdge>
  27 + <bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
  28 + <omgdi:waypoint x="235.0" y="107.0"></omgdi:waypoint>
  29 + <omgdi:waypoint x="290.0" y="107.0"></omgdi:waypoint>
  30 + </bpmndi:BPMNEdge>
  31 + </bpmndi:BPMNPlane>
  32 + </bpmndi:BPMNDiagram>
  33 +</definitions>
0 \ No newline at end of file 34 \ No newline at end of file
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/resources/diagrams/chapter9/testMultiInstanceForUserTask.users.sequential.bpmn 0 → 100644
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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">
  3 + <process id="testMultiInstanceForUserTask" name="testMultiInstanceForUserTask" isExecutable="true">
  4 + <startEvent id="startevent1" name="Start"></startEvent>
  5 + <userTask id="usertask1" name="User Task" activiti:assignee="${user}">
  6 + <multiInstanceLoopCharacteristics isSequential="true" activiti:collection="${users}" activiti:elementVariable="user"></multiInstanceLoopCharacteristics>
  7 + </userTask>
  8 + <sequenceFlow id="flow1" sourceRef="startevent1" targetRef="usertask1"></sequenceFlow>
  9 + <endEvent id="endevent1" name="End"></endEvent>
  10 + <sequenceFlow id="flow2" sourceRef="usertask1" targetRef="endevent1"></sequenceFlow>
  11 + </process>
  12 + <bpmndi:BPMNDiagram id="BPMNDiagram_testMultiInstanceForUserTask">
  13 + <bpmndi:BPMNPlane bpmnElement="testMultiInstanceForUserTask" id="BPMNPlane_testMultiInstanceForUserTask">
  14 + <bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
  15 + <omgdc:Bounds height="35.0" width="35.0" x="50.0" y="90.0"></omgdc:Bounds>
  16 + </bpmndi:BPMNShape>
  17 + <bpmndi:BPMNShape bpmnElement="usertask1" id="BPMNShape_usertask1">
  18 + <omgdc:Bounds height="55.0" width="105.0" x="130.0" y="80.0"></omgdc:Bounds>
  19 + </bpmndi:BPMNShape>
  20 + <bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
  21 + <omgdc:Bounds height="35.0" width="35.0" x="290.0" y="90.0"></omgdc:Bounds>
  22 + </bpmndi:BPMNShape>
  23 + <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
  24 + <omgdi:waypoint x="85.0" y="107.0"></omgdi:waypoint>
  25 + <omgdi:waypoint x="130.0" y="107.0"></omgdi:waypoint>
  26 + </bpmndi:BPMNEdge>
  27 + <bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
  28 + <omgdi:waypoint x="235.0" y="107.0"></omgdi:waypoint>
  29 + <omgdi:waypoint x="290.0" y="107.0"></omgdi:waypoint>
  30 + </bpmndi:BPMNEdge>
  31 + </bpmndi:BPMNPlane>
  32 + </bpmndi:BPMNDiagram>
  33 +</definitions>
0 \ No newline at end of file 34 \ No newline at end of file
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/resources/diagrams/chapter9/testMultiInstanceForUserTask.users.sequential.with.complete.conditon.bpmn 0 → 100644
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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">
  3 + <process id="testMultiInstanceForUserTask" name="testMultiInstanceForUserTask" isExecutable="true">
  4 + <startEvent id="startevent1" name="Start"></startEvent>
  5 + <userTask id="usertask1" name="User Task" activiti:assignee="${user}">
  6 + <multiInstanceLoopCharacteristics isSequential="false" activiti:collection="${users}" activiti:elementVariable="user">
  7 + <completionCondition>${nrOfCompletedInstances / nrOfInstances &gt;= rate}</completionCondition>
  8 + </multiInstanceLoopCharacteristics>
  9 + </userTask>
  10 + <sequenceFlow id="flow1" sourceRef="startevent1" targetRef="usertask1"></sequenceFlow>
  11 + <endEvent id="endevent1" name="End"></endEvent>
  12 + <sequenceFlow id="flow2" sourceRef="usertask1" targetRef="endevent1"></sequenceFlow>
  13 + </process>
  14 + <bpmndi:BPMNDiagram id="BPMNDiagram_testMultiInstanceForUserTask">
  15 + <bpmndi:BPMNPlane bpmnElement="testMultiInstanceForUserTask" id="BPMNPlane_testMultiInstanceForUserTask">
  16 + <bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
  17 + <omgdc:Bounds height="35.0" width="35.0" x="50.0" y="90.0"></omgdc:Bounds>
  18 + </bpmndi:BPMNShape>
  19 + <bpmndi:BPMNShape bpmnElement="usertask1" id="BPMNShape_usertask1">
  20 + <omgdc:Bounds height="55.0" width="105.0" x="130.0" y="80.0"></omgdc:Bounds>
  21 + </bpmndi:BPMNShape>
  22 + <bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
  23 + <omgdc:Bounds height="35.0" width="35.0" x="290.0" y="90.0"></omgdc:Bounds>
  24 + </bpmndi:BPMNShape>
  25 + <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
  26 + <omgdi:waypoint x="85.0" y="107.0"></omgdi:waypoint>
  27 + <omgdi:waypoint x="130.0" y="107.0"></omgdi:waypoint>
  28 + </bpmndi:BPMNEdge>
  29 + <bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
  30 + <omgdi:waypoint x="235.0" y="107.0"></omgdi:waypoint>
  31 + <omgdi:waypoint x="290.0" y="107.0"></omgdi:waypoint>
  32 + </bpmndi:BPMNEdge>
  33 + </bpmndi:BPMNPlane>
  34 + </bpmndi:BPMNDiagram>
  35 +</definitions>
0 \ No newline at end of file 36 \ No newline at end of file
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/resources/diagrams/chapter9/testMultiInstanceForUserTask.users.sequential.with.complete.conditon.png 0 → 100644

7.82 KB

yudao-ui-admin/src/api/bpm/task.js
@@ -39,6 +39,13 @@ export function rejectTask(data) { @@ -39,6 +39,13 @@ export function rejectTask(data) {
39 data: data 39 data: data
40 }) 40 })
41 } 41 }
  42 +export function backTask(data) {
  43 + return request({
  44 + url: '/bpm/task/back',
  45 + method: 'PUT',
  46 + data: data
  47 + })
  48 +}
42 49
43 export function updateTaskAssignee(data) { 50 export function updateTaskAssignee(data) {
44 return request({ 51 return request({
yudao-ui-admin/src/views/bpm/processInstance/detail.vue
@@ -109,7 +109,7 @@ import store from &quot;@/store&quot;; @@ -109,7 +109,7 @@ import store from &quot;@/store&quot;;
109 import {decodeFields} from "@/utils/formGenerator"; 109 import {decodeFields} from "@/utils/formGenerator";
110 import Parser from '@/components/parser/Parser' 110 import Parser from '@/components/parser/Parser'
111 import {createProcessInstance, getProcessInstance} from "@/api/bpm/processInstance"; 111 import {createProcessInstance, getProcessInstance} from "@/api/bpm/processInstance";
112 -import {approveTask, getTaskListByProcessInstanceId, rejectTask, updateTaskAssignee} from "@/api/bpm/task"; 112 +import {approveTask, getTaskListByProcessInstanceId, rejectTask, updateTaskAssignee,backTask} from "@/api/bpm/task";
113 import {getDate} from "@/utils/dateUtils"; 113 import {getDate} from "@/utils/dateUtils";
114 import {listSimpleUsers} from "@/api/system/user"; 114 import {listSimpleUsers} from "@/api/system/user";
115 import {getActivityList} from "@/api/bpm/activity"; 115 import {getActivityList} from "@/api/bpm/activity";
@@ -406,7 +406,15 @@ export default { @@ -406,7 +406,15 @@ export default {
406 }, 406 },
407 /** 处理审批退回的操作 */ 407 /** 处理审批退回的操作 */
408 handleBack(task) { 408 handleBack(task) {
409 - this.$modal.msgError("暂不支持【退回】功能!"); 409 + const data = {
  410 + id: task.id,
  411 + assigneeUserId: 1
  412 + }
  413 + // this.$modal.msgError("暂不支持【--退回】功能!");
  414 + backTask(data).then(response => {
  415 + this.$modal.msgSuccess("回退成功!");
  416 + this.getDetail(); // 获得最新详情
  417 + });
410 } 418 }
411 } 419 }
412 }; 420 };