From 56eedfd14761762bd6b2386d0f79e04dc099cdc1 Mon Sep 17 00:00:00 2001 From: cuicui20210817 Date: Tue, 15 Mar 2022 17:39:16 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E5=9B=9E=E9=80=80-=E4=BB=BB=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/task/BpmTaskController.java | 9 +++++++++ .../module/bpm/service/task/BpmTaskService.java | 6 ++++++ .../bpm/service/task/BpmTaskServiceImpl.java | 13 +++++++++++++ .../yudao/module/bpm/LeaveFormKeyTest.java | 17 +++++++++++++++++ yudao-ui-admin/src/api/bpm/task.js | 7 +++++++ .../src/views/bpm/processInstance/detail.vue | 12 ++++++++++-- 6 files changed, 62 insertions(+), 2 deletions(-) diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java index 52b16297d..d3318c963 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java +++ b/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 { taskService.updateTaskAssignee(getLoginUserId(), reqVO); return success(true); } + @PutMapping("/back") + @ApiOperation(value = "回退") +// @PreAuthorize("@ss.hasPermission('bpm:task:back')") + public CommonResult backTask(@Valid @RequestBody BpmTaskUpdateAssigneeReqVO reqVO) { + //先硬编码到 回退到第一个审批节点 + String destinationTaskDefKey = "task01"; + taskService.backTask(reqVO.getId(),destinationTaskDefKey); + return success(true); + } } diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java index e8aab6aa8..00a0a8662 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java +++ b/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 { * @param reqVO 不通过请求 */ void rejectTask(Long userId, @Valid BpmTaskRejectReqVO reqVO); + /** + * 回退任务 + * + * @param taskId 任务编号 + */ + void backTask(String taskId,String destinationTaskDefKey); /** * 将流程任务分配给指定用户 diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java index 5c004977c..0660576f0 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java +++ b/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; import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; import lombok.extern.slf4j.Slf4j; import org.flowable.engine.HistoryService; +import org.flowable.engine.RuntimeService; import org.flowable.engine.TaskService; import org.flowable.engine.history.HistoricProcessInstance; import org.flowable.engine.runtime.ProcessInstance; @@ -51,6 +52,8 @@ public class BpmTaskServiceImpl implements BpmTaskService{ @Resource private TaskService taskService; @Resource + private RuntimeService runtimeService; + @Resource private HistoryService historyService; @Resource @@ -203,6 +206,16 @@ public class BpmTaskServiceImpl implements BpmTaskService{ .setResult(BpmProcessInstanceResultEnum.REJECT.getResult()).setComment(reqVO.getComment())); } + @Override + public void backTask(String taskId,String destinationTaskDefKey) { + Task currentTask = taskService.createTaskQuery().taskId(taskId).singleResult(); + + runtimeService.createChangeActivityStateBuilder() + .processInstanceId(currentTask.getProcessInstanceId()) + .moveActivityIdTo(currentTask.getTaskDefinitionKey(), destinationTaskDefKey) + .changeState(); + } + @Override public void updateTaskAssignee(Long userId, BpmTaskUpdateAssigneeReqVO reqVO) { // 校验任务存在 diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/java/cn/iocoder/yudao/module/bpm/LeaveFormKeyTest.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/java/cn/iocoder/yudao/module/bpm/LeaveFormKeyTest.java index 90105af2e..da99fec3d 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/java/cn/iocoder/yudao/module/bpm/LeaveFormKeyTest.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/java/cn/iocoder/yudao/module/bpm/LeaveFormKeyTest.java @@ -87,6 +87,23 @@ public class LeaveFormKeyTest extends AbstractOATest { } + /** + * 任意流程的跳转 + */ + @Test + public void taskJump(){ + // 当前任务 + String taskId="ddd"; + Task task = taskService.createTaskQuery().taskId(taskId).singleResult(); + String assignee = "下一个自由跳转人"; + taskService.setAssignee(taskId,assignee); + // 自由跳转 + String taskDefKey="目标-任务名称"; + //moveActivityIdTo的两个参数,源任务key,目标任务key + runtimeService.createChangeActivityStateBuilder().processInstanceId(task.getProcessInstanceId()).moveActivityIdTo(task.getTaskDefinitionKey(), taskDefKey).changeState(); + + } + /** * 领导驳回后申请人取消申请 */ diff --git a/yudao-ui-admin/src/api/bpm/task.js b/yudao-ui-admin/src/api/bpm/task.js index 177a7dfc9..aa32263f3 100644 --- a/yudao-ui-admin/src/api/bpm/task.js +++ b/yudao-ui-admin/src/api/bpm/task.js @@ -39,6 +39,13 @@ export function rejectTask(data) { data: data }) } +export function backTask(data) { + return request({ + url: '/bpm/task/back', + method: 'PUT', + data: data + }) +} export function updateTaskAssignee(data) { return request({ diff --git a/yudao-ui-admin/src/views/bpm/processInstance/detail.vue b/yudao-ui-admin/src/views/bpm/processInstance/detail.vue index f5d4992c2..6311ae0a5 100644 --- a/yudao-ui-admin/src/views/bpm/processInstance/detail.vue +++ b/yudao-ui-admin/src/views/bpm/processInstance/detail.vue @@ -109,7 +109,7 @@ import store from "@/store"; import {decodeFields} from "@/utils/formGenerator"; import Parser from '@/components/parser/Parser' import {createProcessInstance, getProcessInstance} from "@/api/bpm/processInstance"; -import {approveTask, getTaskListByProcessInstanceId, rejectTask, updateTaskAssignee} from "@/api/bpm/task"; +import {approveTask, getTaskListByProcessInstanceId, rejectTask, updateTaskAssignee,backTask} from "@/api/bpm/task"; import {getDate} from "@/utils/dateUtils"; import {listSimpleUsers} from "@/api/system/user"; import {getActivityList} from "@/api/bpm/activity"; @@ -406,7 +406,15 @@ export default { }, /** 处理审批退回的操作 */ handleBack(task) { - this.$modal.msgError("暂不支持【退回】功能!"); + const data = { + id: task.id, + assigneeUserId: 1 + } + // this.$modal.msgError("暂不支持【--退回】功能!"); + backTask(data).then(response => { + this.$modal.msgSuccess("回退成功!"); + this.getDetail(); // 获得最新详情 + }); } } }; From d85c74cbece5af3aa9381bd2e67a2a8b59cb3cfc Mon Sep 17 00:00:00 2001 From: cuicui20210817 Date: Fri, 25 Mar 2022 15:02:36 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E4=BC=9A=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yudao/module/bpm/MultiInstancesTest.java | 203 ++++++++++++++++++ .../diagrams/chapter9/leave-countersign.bpmn | 152 +++++++++++++ .../diagrams/chapter9/leave-countersign.png | Bin 0 -> 20431 bytes .../testMultiInstanceFixedNumbers.bpmn | 44 ++++ ...estMultiInstanceForUserTask.exception.bpmn | 42 ++++ ...testMultiInstanceForUserTask.exception.png | Bin 0 -> 11790 bytes ...MultiInstanceForUserTask.nosequential.bpmn | 35 +++ ...stMultiInstanceForUserTask.sequential.bpmn | 35 +++ ...nstanceForUserTask.users.nosequential.bpmn | 33 +++ ...iInstanceForUserTask.users.sequential.bpmn | 33 +++ ...ers.sequential.with.complete.conditon.bpmn | 35 +++ ...sers.sequential.with.complete.conditon.png | Bin 0 -> 8007 bytes 12 files changed, 612 insertions(+) create mode 100644 yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/java/cn/iocoder/yudao/module/bpm/MultiInstancesTest.java create mode 100644 yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/resources/diagrams/chapter9/leave-countersign.bpmn create mode 100644 yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/resources/diagrams/chapter9/leave-countersign.png create mode 100644 yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/resources/diagrams/chapter9/testMultiInstanceFixedNumbers.bpmn create mode 100644 yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/resources/diagrams/chapter9/testMultiInstanceForUserTask.exception.bpmn create mode 100644 yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/resources/diagrams/chapter9/testMultiInstanceForUserTask.exception.png create mode 100644 yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/resources/diagrams/chapter9/testMultiInstanceForUserTask.nosequential.bpmn create mode 100644 yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/resources/diagrams/chapter9/testMultiInstanceForUserTask.sequential.bpmn create mode 100644 yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/resources/diagrams/chapter9/testMultiInstanceForUserTask.users.nosequential.bpmn create mode 100644 yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/resources/diagrams/chapter9/testMultiInstanceForUserTask.users.sequential.bpmn create mode 100644 yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/resources/diagrams/chapter9/testMultiInstanceForUserTask.users.sequential.with.complete.conditon.bpmn create mode 100644 yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/resources/diagrams/chapter9/testMultiInstanceForUserTask.users.sequential.with.complete.conditon.png diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/java/cn/iocoder/yudao/module/bpm/MultiInstancesTest.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/java/cn/iocoder/yudao/module/bpm/MultiInstancesTest.java new file mode 100644 index 000000000..f0672b028 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/java/cn/iocoder/yudao/module/bpm/MultiInstancesTest.java @@ -0,0 +1,203 @@ +package cn.iocoder.yudao.module.bpm; + +import org.flowable.engine.history.HistoricDetail; +import org.flowable.engine.history.HistoricFormProperty; +import org.flowable.engine.history.HistoricProcessInstance; +import org.flowable.engine.history.HistoricVariableUpdate; +import org.flowable.engine.repository.ProcessDefinition; +import org.flowable.engine.runtime.ProcessInstance; +import org.flowable.engine.test.Deployment; +import org.flowable.task.api.Task; +import org.junit.Test; + +import java.text.SimpleDateFormat; +import java.util.*; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +/** + * @author henryyan + * testMultiInstanceForUserTask 会签 + */ +public class MultiInstancesTest extends AbstractOATest { + + /** + * Java Service多实例(是否顺序结果一样) + */ + @Test + @Deployment(resources = {"diagrams/chapter9/testMultiInstanceFixedNumbers.bpmn"}) + public void testParallel() throws Exception { + Map variables = new HashMap(); + long loop = 3; + variables.put("loop", loop); + variables.put("counter", 0); // 计数器 + ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("testMultiInstanceFixedNumbers", variables); + Object variable = runtimeService.getVariable(processInstance.getId(), "counter"); + assertEquals(loop, variable); + } + + /** + * 用户任务多实例--顺序 + */ + @Test + @Deployment(resources = {"diagrams/chapter9/testMultiInstanceForUserTask.sequential.bpmn"}) + public void testForUserSequence() throws Exception { + ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("testMultiInstanceForUserTask"); + long count = taskService.createTaskQuery().processInstanceId(processInstance.getId()).count(); + assertEquals(1, count); + + Task task = taskService.createTaskQuery().singleResult(); + taskService.complete(task.getId()); + count = taskService.createTaskQuery().processInstanceId(processInstance.getId()).count(); + assertEquals(1, count); + + task = taskService.createTaskQuery().singleResult(); + taskService.complete(task.getId()); + count = taskService.createTaskQuery().processInstanceId(processInstance.getId()).count(); + assertEquals(1, count); + + task = taskService.createTaskQuery().singleResult(); + taskService.complete(task.getId()); + count = taskService.createTaskQuery().processInstanceId(processInstance.getId()).count(); + assertEquals(0, count); + } + + /** + * 用户任务多实例--并行 + */ + @Test + @Deployment(resources = {"diagrams/chapter9/testMultiInstanceForUserTask.nosequential.bpmn"}) + public void testForUserNoSequential() throws Exception { + ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("testMultiInstanceForUserTask"); + long count = taskService.createTaskQuery().processInstanceId(processInstance.getId()).count(); + assertEquals(3, count); + } + + /** + * 用户任务多实例,通过用户数量决定实例个数--并行 + */ + @Test + @Deployment(resources = {"diagrams/chapter9/testMultiInstanceForUserTask.users.nosequential.bpmn"}) + public void testForUserCreateByUsersNoSequential() throws Exception { + Map variables = new HashMap(); + List users = Arrays.asList("user1", "user2", "user3"); + variables.put("users", users); + runtimeService.startProcessInstanceByKey("testMultiInstanceForUserTask", variables); + for (String userId : users) { + assertEquals(1, taskService.createTaskQuery().taskAssignee(userId).count()); + } + } + + /** + * 用户任务多实例,通过用户数量决定实例个数--顺序 + */ + @Test + @Deployment(resources = {"diagrams/chapter9/testMultiInstanceForUserTask.users.sequential.bpmn"}) + public void testForUserCreateByUsersSequential() throws Exception { + Map variables = new HashMap(); + List users = Arrays.asList("user1", "user2", "user3"); + variables.put("users", users); + runtimeService.startProcessInstanceByKey("testMultiInstanceForUserTask", variables); + for (String userId : users) { + Task task = taskService.createTaskQuery().taskAssignee(userId).singleResult(); + taskService.complete(task.getId()); + } + } + + /** + * 用户任务多实例,按照任务完成的百分比比率决定是否提前结束流程 + */ + @Test + @Deployment(resources = {"diagrams/chapter9/testMultiInstanceForUserTask.users.sequential.with.complete.conditon.bpmn"}) + public void testForUserCreateByUsersSequentialWithCompleteCondition() throws Exception { + Map variables = new HashMap(); + List users = Arrays.asList("user1", "user2", "user3"); + variables.put("users", users); + variables.put("rate", 0.6d); + runtimeService.startProcessInstanceByKey("testMultiInstanceForUserTask", variables); + + Task task = taskService.createTaskQuery().taskAssignee("user1").singleResult(); + taskService.complete(task.getId()); + + task = taskService.createTaskQuery().taskAssignee("user2").singleResult(); + taskService.complete(task.getId()); + + long count = historyService.createHistoricProcessInstanceQuery().finished().count(); + assertEquals(1, count); + + } + + /** + * 用户任务多实例,按照任务完成的百分比比率决定是否提前结束流程 + */ + @Test + @Deployment(resources = {"diagrams/chapter9/testMultiInstanceForUserTask.exception.bpmn"}) + public void testForUserCreateByUsersException() throws Exception { + Map variables = new HashMap(); + List users = Arrays.asList("user1", "user2", "user3"); + variables.put("users", users); + runtimeService.startProcessInstanceByKey("testMultiInstanceForUserTask", variables); + + Task task = taskService.createTaskQuery().taskAssignee("user1").singleResult(); + taskService.complete(task.getId()); + + task = taskService.createTaskQuery().taskAssignee("user2").singleResult(); + taskService.complete(task.getId()); + + task = taskService.createTaskQuery().taskAssignee("user3").singleResult(); + taskService.complete(task.getId()); + + List list = taskService.createTaskQuery().list(); + for (Task task2 : list) { + System.out.println("============" + task2.getName()); + } + + } + ///////////////////////////////////////////////// + /** + * 全部通过 + */ + @Test + @Deployment(resources = {"diagrams/chapter9/leave-countersign.bpmn"}) + public void testAllApproved() throws Exception { + Map variables = new HashMap(); + List users = Arrays.asList("groupLeader", "deptLeader", "hr"); + variables.put("users", users); + identityService.setAuthenticatedUserId("henryyan"); + ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("leave-countersign", variables); + for (String user : users) { + Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).taskAssignee(user).singleResult(); + Map taskVariables = new HashMap(); + taskVariables.put("approved", "true"); + taskService.complete(task.getId(), taskVariables); + } + + Task task = taskService.createTaskQuery().taskAssignee("henryyan").singleResult(); + assertNotNull(task); + assertEquals("销假", task.getName()); + } + + /** + * 部分通过 + */ + @Test + @Deployment(resources = {"diagrams/chapter9/leave-countersign.bpmn"}) + public void testNotAllApproved() throws Exception { + Map variables = new HashMap(); + List users = Arrays.asList("groupLeader", "deptLeader", "hr"); + variables.put("users", users); + identityService.setAuthenticatedUserId("henryyan"); + ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("leave-countersign", variables); + for (String user : users) { + Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).taskAssignee(user).singleResult(); + Map taskVariables = new HashMap(); + taskVariables.put("approved", "false"); + taskService.complete(task.getId(), taskVariables); + } + + Task task = taskService.createTaskQuery().taskAssignee("henryyan").singleResult(); + assertNotNull(task); + assertEquals("调整申请", task.getName()); + } +} diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/resources/diagrams/chapter9/leave-countersign.bpmn b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/resources/diagrams/chapter9/leave-countersign.bpmn new file mode 100644 index 000000000..bdb56857d --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/resources/diagrams/chapter9/leave-countersign.bpmn @@ -0,0 +1,152 @@ + + + + 请假流程演示-会签 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/resources/diagrams/chapter9/leave-countersign.png b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/resources/diagrams/chapter9/leave-countersign.png new file mode 100644 index 0000000000000000000000000000000000000000..e2a6f2ca2e59fc15fc8891bfc7cfe824e99846b1 GIT binary patch literal 20431 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 literal 0 HcmV?d00001 diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/resources/diagrams/chapter9/testMultiInstanceFixedNumbers.bpmn b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/resources/diagrams/chapter9/testMultiInstanceFixedNumbers.bpmn new file mode 100644 index 000000000..998570919 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/resources/diagrams/chapter9/testMultiInstanceFixedNumbers.bpmn @@ -0,0 +1,44 @@ + + + + + + + ${loop} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/resources/diagrams/chapter9/testMultiInstanceForUserTask.exception.bpmn b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/resources/diagrams/chapter9/testMultiInstanceForUserTask.exception.bpmn new file mode 100644 index 000000000..05a87d939 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/resources/diagrams/chapter9/testMultiInstanceForUserTask.exception.bpmn @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/resources/diagrams/chapter9/testMultiInstanceForUserTask.exception.png b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/resources/diagrams/chapter9/testMultiInstanceForUserTask.exception.png new file mode 100644 index 0000000000000000000000000000000000000000..5ac829387533a40644db4840941dde200d37ba6b GIT binary patch literal 11790 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 UyGMZ|)gYVmj=z+jy>ah<0npM + + + + + + 3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/resources/diagrams/chapter9/testMultiInstanceForUserTask.sequential.bpmn b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/resources/diagrams/chapter9/testMultiInstanceForUserTask.sequential.bpmn new file mode 100644 index 000000000..c7bc82b4f --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/resources/diagrams/chapter9/testMultiInstanceForUserTask.sequential.bpmn @@ -0,0 +1,35 @@ + + + + + + + 3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/resources/diagrams/chapter9/testMultiInstanceForUserTask.users.nosequential.bpmn b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/resources/diagrams/chapter9/testMultiInstanceForUserTask.users.nosequential.bpmn new file mode 100644 index 000000000..ca117190c --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/resources/diagrams/chapter9/testMultiInstanceForUserTask.users.nosequential.bpmn @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/resources/diagrams/chapter9/testMultiInstanceForUserTask.users.sequential.bpmn b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/resources/diagrams/chapter9/testMultiInstanceForUserTask.users.sequential.bpmn new file mode 100644 index 000000000..5dbd39676 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/resources/diagrams/chapter9/testMultiInstanceForUserTask.users.sequential.bpmn @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/resources/diagrams/chapter9/testMultiInstanceForUserTask.users.sequential.with.complete.conditon.bpmn b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/resources/diagrams/chapter9/testMultiInstanceForUserTask.users.sequential.with.complete.conditon.bpmn new file mode 100644 index 000000000..d8fc63a55 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/resources/diagrams/chapter9/testMultiInstanceForUserTask.users.sequential.with.complete.conditon.bpmn @@ -0,0 +1,35 @@ + + + + + + + ${nrOfCompletedInstances / nrOfInstances >= rate} + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/resources/diagrams/chapter9/testMultiInstanceForUserTask.users.sequential.with.complete.conditon.png b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/resources/diagrams/chapter9/testMultiInstanceForUserTask.users.sequential.with.complete.conditon.png new file mode 100644 index 0000000000000000000000000000000000000000..c20f451b89426ef0a1482d247f18b36e7aaed126 GIT binary patch literal 8007 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 Date: Fri, 25 Mar 2022 15:44:44 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E4=BC=9A=E7=AD=BE-=E6=89=A7=E8=A1=8C?= =?UTF-8?q?=E4=BA=86=E4=B8=A4=E6=AC=A1,=E4=BB=BB=E5=8A=A1=E5=88=86?= =?UTF-8?q?=E9=85=8D=E5=88=B0=E4=BA=86=E5=90=8C=E4=B8=80=E4=B8=AA=E4=BA=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/cn/iocoder/yudao/module/bpm/MultiInstancesTest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/java/cn/iocoder/yudao/module/bpm/MultiInstancesTest.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/java/cn/iocoder/yudao/module/bpm/MultiInstancesTest.java index f0672b028..2640e7456 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/java/cn/iocoder/yudao/module/bpm/MultiInstancesTest.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/test/java/cn/iocoder/yudao/module/bpm/MultiInstancesTest.java @@ -19,6 +19,8 @@ import static org.junit.Assert.assertNotNull; /** * @author henryyan * testMultiInstanceForUserTask 会签 + * 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) + * 执行了两次,任务分配到了同一个人 */ public class MultiInstancesTest extends AbstractOATest {