From d051fd8a9abb01ba5de89a24220ba394eb0ff1fe Mon Sep 17 00:00:00 2001 From: lorne <1991wangliang@gmail.com> Date: Wed, 16 Jul 2025 12:03:31 +0800 Subject: [PATCH 1/2] add FlowRemoveTest --- .../springboot/flow/test/FlowRemoveTest.java | 213 ++++++++++++++++++ 1 file changed, 213 insertions(+) create mode 100644 springboot-starter-flow/src/test/java/com/codingapi/springboot/flow/test/FlowRemoveTest.java diff --git a/springboot-starter-flow/src/test/java/com/codingapi/springboot/flow/test/FlowRemoveTest.java b/springboot-starter-flow/src/test/java/com/codingapi/springboot/flow/test/FlowRemoveTest.java new file mode 100644 index 00000000..902fe89c --- /dev/null +++ b/springboot-starter-flow/src/test/java/com/codingapi/springboot/flow/test/FlowRemoveTest.java @@ -0,0 +1,213 @@ +package com.codingapi.springboot.flow.test; + +import com.codingapi.springboot.flow.build.FlowWorkBuilder; +import com.codingapi.springboot.flow.domain.FlowWork; +import com.codingapi.springboot.flow.domain.Opinion; +import com.codingapi.springboot.flow.em.ApprovalType; +import com.codingapi.springboot.flow.flow.Leave; +import com.codingapi.springboot.flow.matcher.OperatorMatcher; +import com.codingapi.springboot.flow.record.FlowRecord; +import com.codingapi.springboot.flow.repository.*; +import com.codingapi.springboot.flow.service.FlowService; +import com.codingapi.springboot.flow.user.User; +import org.junit.jupiter.api.Test; +import org.springframework.data.domain.PageRequest; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +public class FlowRemoveTest { + + private final UserRepository userRepository = new UserRepository(); + private final FlowWorkRepository flowWorkRepository = new FlowWorkRepositoryImpl(); + private final FlowRecordRepositoryImpl flowRecordRepository = new FlowRecordRepositoryImpl(); + private final FlowBindDataRepositoryImpl flowBindDataRepository = new FlowBindDataRepositoryImpl(); + private final LeaveRepository leaveRepository = new LeaveRepository(); + private final FlowBackupRepository flowBackupRepository = new FlowBackupRepositoryImpl(); + private final FlowProcessRepository flowProcessRepository = new FlowProcessRepositoryImpl(flowBackupRepository, userRepository); + private final FlowService flowService = new FlowService(flowWorkRepository, flowRecordRepository, flowBindDataRepository, userRepository, flowProcessRepository, flowBackupRepository); + + /** + * 删除流程测试 (在未提交之前删除流程) + */ + @Test + void removeTest1() { + PageRequest pageRequest = PageRequest.of(0, 1000); + + User user = new User("张飞"); + userRepository.save(user); + + User dept = new User("刘备"); + userRepository.save(dept); + + User boss = new User("诸葛亮"); + userRepository.save(boss); + + FlowWork flowWork = FlowWorkBuilder.builder(user) + .title("请假流程") + .nodes() + .node("开始节点", "start", "default", ApprovalType.UN_SIGN, OperatorMatcher.anyOperatorMatcher()) + .node("部门领导审批", "dept", "default", ApprovalType.UN_SIGN, OperatorMatcher.specifyOperatorMatcher(dept.getUserId())) + .node("总经理审批", "manager", "default", ApprovalType.UN_SIGN, OperatorMatcher.specifyOperatorMatcher(boss.getUserId())) + .node("结束节点", "over", "default", ApprovalType.UN_SIGN, OperatorMatcher.anyOperatorMatcher()) + .relations() + .relation("部门领导审批", "start", "dept") + .relation("总经理审批", "dept", "manager") + .relation("结束节点", "manager", "over") + .build(); + + flowWorkRepository.save(flowWork); + + String workCode = flowWork.getCode(); + + Leave leave = new Leave("我要出去看看"); + leaveRepository.save(leave); + + // 创建流程 + flowService.startFlow(workCode, user, leave, "发起流程"); + + // 查看我的待办 + List userTodos = flowRecordRepository.findTodoByOperatorId(user.getUserId(), pageRequest).getContent(); + assertEquals(1, userTodos.size()); + + // 提交流程 + FlowRecord userTodo = userTodos.get(0); + assertEquals(0, userTodo.getTimeoutTime()); + // 保存流程 + leave.setTitle("我要出去看看~~"); + flowService.remove(userTodo.getId(), user); + + List records = flowRecordRepository.findFlowRecordByProcessId(userTodo.getProcessId()); + assertEquals(0, records.size()); + + } + + /** + * 删除流程测试 (提交以后删除异常) + */ + @Test + void removeTest2() { + PageRequest pageRequest = PageRequest.of(0, 1000); + + User user = new User("张飞"); + userRepository.save(user); + + User dept = new User("刘备"); + userRepository.save(dept); + + User boss = new User("诸葛亮"); + userRepository.save(boss); + + FlowWork flowWork = FlowWorkBuilder.builder(user) + .title("请假流程") + .nodes() + .node("开始节点", "start", "default", ApprovalType.UN_SIGN, OperatorMatcher.anyOperatorMatcher()) + .node("部门领导审批", "dept", "default", ApprovalType.UN_SIGN, OperatorMatcher.specifyOperatorMatcher(dept.getUserId())) + .node("总经理审批", "manager", "default", ApprovalType.UN_SIGN, OperatorMatcher.specifyOperatorMatcher(boss.getUserId())) + .node("结束节点", "over", "default", ApprovalType.UN_SIGN, OperatorMatcher.anyOperatorMatcher()) + .relations() + .relation("部门领导审批", "start", "dept") + .relation("总经理审批", "dept", "manager") + .relation("结束节点", "manager", "over") + .build(); + + flowWorkRepository.save(flowWork); + + String workCode = flowWork.getCode(); + + Leave leave = new Leave("我要出去看看"); + leaveRepository.save(leave); + + // 创建流程 + flowService.startFlow(workCode, user, leave, "发起流程"); + + // 查看我的待办 + List userTodos = flowRecordRepository.findTodoByOperatorId(user.getUserId(), pageRequest).getContent(); + assertEquals(1, userTodos.size()); + + // 提交流程 + FlowRecord userTodo = userTodos.get(0); + flowService.submitFlow(userTodo.getId(), user,leave, Opinion.pass("同意")); + + + List deptTodos = flowRecordRepository.findTodoByOperatorId(dept.getUserId(), pageRequest).getContent(); + assertEquals(1, deptTodos.size()); + + FlowRecord deptTodo = deptTodos.get(0); + assertThrows(Exception.class, () -> { + flowService.remove(deptTodo.getId(), dept); + }); + + List records = flowRecordRepository.findFlowRecordByProcessId(userTodo.getProcessId()); + assertEquals(2, records.size()); + + } + + + /** + * 删除流程测试 (提交以后再撤回然后继续删除) + */ + @Test + void removeTest3() { + PageRequest pageRequest = PageRequest.of(0, 1000); + + User user = new User("张飞"); + userRepository.save(user); + + User dept = new User("刘备"); + userRepository.save(dept); + + User boss = new User("诸葛亮"); + userRepository.save(boss); + + FlowWork flowWork = FlowWorkBuilder.builder(user) + .title("请假流程") + .nodes() + .node("开始节点", "start", "default", ApprovalType.UN_SIGN, OperatorMatcher.anyOperatorMatcher()) + .node("部门领导审批", "dept", "default", ApprovalType.UN_SIGN, OperatorMatcher.specifyOperatorMatcher(dept.getUserId())) + .node("总经理审批", "manager", "default", ApprovalType.UN_SIGN, OperatorMatcher.specifyOperatorMatcher(boss.getUserId())) + .node("结束节点", "over", "default", ApprovalType.UN_SIGN, OperatorMatcher.anyOperatorMatcher()) + .relations() + .relation("部门领导审批", "start", "dept") + .relation("总经理审批", "dept", "manager") + .relation("结束节点", "manager", "over") + .build(); + + flowWorkRepository.save(flowWork); + + String workCode = flowWork.getCode(); + + Leave leave = new Leave("我要出去看看"); + leaveRepository.save(leave); + + // 创建流程 + flowService.startFlow(workCode, user, leave, "发起流程"); + + // 查看我的待办 + List userTodos = flowRecordRepository.findTodoByOperatorId(user.getUserId(), pageRequest).getContent(); + assertEquals(1, userTodos.size()); + + // 提交流程 + FlowRecord userTodo = userTodos.get(0); + flowService.submitFlow(userTodo.getId(), user,leave, Opinion.pass("同意")); + + + List deptTodos = flowRecordRepository.findTodoByOperatorId(dept.getUserId(), pageRequest).getContent(); + assertEquals(1, deptTodos.size()); + + FlowRecord deptTod = deptTodos.get(0); + flowService.submitFlow(deptTod.getId(), dept,leave, Opinion.reject("不同意")); + + userTodos = flowRecordRepository.findTodoByOperatorId(user.getUserId(), pageRequest).getContent(); + assertEquals(1, userTodos.size()); + + userTodo = userTodos.get(0); + flowService.remove(userTodo.getId(), user); + + List records = flowRecordRepository.findFlowRecordByProcessId(userTodo.getProcessId()); + assertEquals(0, records.size()); + + } +} From 958ebcb4f5a374c868eaee377f9d5b435bbd98e9 Mon Sep 17 00:00:00 2001 From: lorne <1991wangliang@gmail.com> Date: Thu, 17 Jul 2025 20:58:40 +0800 Subject: [PATCH 2/2] fix flow bug --- .../example-app-cmd-domain/pom.xml | 2 +- .../example-app/example-app-cmd-meta/pom.xml | 2 +- example/example-app/example-app-query/pom.xml | 2 +- example/example-app/pom.xml | 2 +- .../example-domain-leave/pom.xml | 2 +- .../example-domain-user/pom.xml | 2 +- example/example-domain/pom.xml | 2 +- .../example-infra/example-infra-flow/pom.xml | 2 +- .../example-infra/example-infra-jpa/pom.xml | 2 +- .../example-infra-security/pom.xml | 2 +- example/example-infra/pom.xml | 2 +- example/example-interface/pom.xml | 2 +- example/example-server/pom.xml | 2 +- example/pom.xml | 2 +- pom.xml | 2 +- springboot-starter-data-authorization/pom.xml | 2 +- springboot-starter-data-fast/pom.xml | 2 +- springboot-starter-flow/pom.xml | 2 +- .../flow/service/FlowDirectionService.java | 26 -- .../flow/service/FlowNodeService.java | 22 -- .../flow/service/impl/FlowSubmitService.java | 6 +- .../springboot/flow/test/FlowRejectTest.java | 244 ++++++++++++++++++ .../flow/test/MultiRelationFlowTest.java | 21 +- springboot-starter-security/pom.xml | 2 +- springboot-starter/pom.xml | 2 +- .../src/main/resources/banner.txt | 2 +- 26 files changed, 271 insertions(+), 90 deletions(-) create mode 100644 springboot-starter-flow/src/test/java/com/codingapi/springboot/flow/test/FlowRejectTest.java diff --git a/example/example-app/example-app-cmd-domain/pom.xml b/example/example-app/example-app-cmd-domain/pom.xml index ce0ceaca..d7052b06 100644 --- a/example/example-app/example-app-cmd-domain/pom.xml +++ b/example/example-app/example-app-cmd-domain/pom.xml @@ -6,7 +6,7 @@ com.codingapi.springboot example-app - 3.4.10 + 3.4.11 ../pom.xml diff --git a/example/example-app/example-app-cmd-meta/pom.xml b/example/example-app/example-app-cmd-meta/pom.xml index 1b076a83..1182d4a4 100644 --- a/example/example-app/example-app-cmd-meta/pom.xml +++ b/example/example-app/example-app-cmd-meta/pom.xml @@ -6,7 +6,7 @@ com.codingapi.springboot example-app - 3.4.10 + 3.4.11 ../pom.xml diff --git a/example/example-app/example-app-query/pom.xml b/example/example-app/example-app-query/pom.xml index b5cddefb..eab53e59 100644 --- a/example/example-app/example-app-query/pom.xml +++ b/example/example-app/example-app-query/pom.xml @@ -6,7 +6,7 @@ com.codingapi.springboot example-app - 3.4.10 + 3.4.11 ../pom.xml diff --git a/example/example-app/pom.xml b/example/example-app/pom.xml index 64d9e6ca..72cd57f8 100644 --- a/example/example-app/pom.xml +++ b/example/example-app/pom.xml @@ -6,7 +6,7 @@ com.codingapi.springboot springboot-example - 3.4.10 + 3.4.11 ../pom.xml pom diff --git a/example/example-domain/example-domain-leave/pom.xml b/example/example-domain/example-domain-leave/pom.xml index 3cbc0754..dea0ea84 100644 --- a/example/example-domain/example-domain-leave/pom.xml +++ b/example/example-domain/example-domain-leave/pom.xml @@ -6,7 +6,7 @@ com.codingapi.springboot example-domain - 3.4.10 + 3.4.11 ../pom.xml diff --git a/example/example-domain/example-domain-user/pom.xml b/example/example-domain/example-domain-user/pom.xml index db50b8c8..f89d3dd5 100644 --- a/example/example-domain/example-domain-user/pom.xml +++ b/example/example-domain/example-domain-user/pom.xml @@ -6,7 +6,7 @@ com.codingapi.springboot example-domain - 3.4.10 + 3.4.11 ../pom.xml diff --git a/example/example-domain/pom.xml b/example/example-domain/pom.xml index 41fcf92e..fd892b13 100644 --- a/example/example-domain/pom.xml +++ b/example/example-domain/pom.xml @@ -5,7 +5,7 @@ com.codingapi.springboot springboot-example - 3.4.10 + 3.4.11 ../pom.xml 4.0.0 diff --git a/example/example-infra/example-infra-flow/pom.xml b/example/example-infra/example-infra-flow/pom.xml index c2cc6069..0779f65f 100644 --- a/example/example-infra/example-infra-flow/pom.xml +++ b/example/example-infra/example-infra-flow/pom.xml @@ -5,7 +5,7 @@ com.codingapi.springboot example-infra - 3.4.10 + 3.4.11 ../pom.xml diff --git a/example/example-infra/example-infra-jpa/pom.xml b/example/example-infra/example-infra-jpa/pom.xml index bf97b684..2373e13e 100644 --- a/example/example-infra/example-infra-jpa/pom.xml +++ b/example/example-infra/example-infra-jpa/pom.xml @@ -5,7 +5,7 @@ com.codingapi.springboot example-infra - 3.4.10 + 3.4.11 ../pom.xml diff --git a/example/example-infra/example-infra-security/pom.xml b/example/example-infra/example-infra-security/pom.xml index 934c186a..613f57a4 100644 --- a/example/example-infra/example-infra-security/pom.xml +++ b/example/example-infra/example-infra-security/pom.xml @@ -6,7 +6,7 @@ com.codingapi.springboot example-infra - 3.4.10 + 3.4.11 ../pom.xml diff --git a/example/example-infra/pom.xml b/example/example-infra/pom.xml index e48a5f39..c367a4a3 100644 --- a/example/example-infra/pom.xml +++ b/example/example-infra/pom.xml @@ -6,7 +6,7 @@ com.codingapi.springboot springboot-example - 3.4.10 + 3.4.11 ../pom.xml pom diff --git a/example/example-interface/pom.xml b/example/example-interface/pom.xml index d349f84d..95171712 100644 --- a/example/example-interface/pom.xml +++ b/example/example-interface/pom.xml @@ -6,7 +6,7 @@ com.codingapi.springboot springboot-example - 3.4.10 + 3.4.11 example-interface diff --git a/example/example-server/pom.xml b/example/example-server/pom.xml index 383059f1..5808fad3 100644 --- a/example/example-server/pom.xml +++ b/example/example-server/pom.xml @@ -5,7 +5,7 @@ springboot-example com.codingapi.springboot - 3.4.10 + 3.4.11 4.0.0 diff --git a/example/pom.xml b/example/pom.xml index b83fa97b..66b6004a 100644 --- a/example/pom.xml +++ b/example/pom.xml @@ -19,7 +19,7 @@ springboot-example - 3.4.10 + 3.4.11 springboot-example springboot-example project for Spring Boot diff --git a/pom.xml b/pom.xml index 07f35194..361acdea 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,7 @@ com.codingapi.springboot springboot-parent - 3.4.10 + 3.4.11 https://github.com/codingapi/springboot-framewrok springboot-parent diff --git a/springboot-starter-data-authorization/pom.xml b/springboot-starter-data-authorization/pom.xml index 0f81b41e..bbc312a5 100644 --- a/springboot-starter-data-authorization/pom.xml +++ b/springboot-starter-data-authorization/pom.xml @@ -6,7 +6,7 @@ com.codingapi.springboot springboot-parent - 3.4.10 + 3.4.11 springboot-starter-data-authorization diff --git a/springboot-starter-data-fast/pom.xml b/springboot-starter-data-fast/pom.xml index c9773635..2ff1e317 100644 --- a/springboot-starter-data-fast/pom.xml +++ b/springboot-starter-data-fast/pom.xml @@ -5,7 +5,7 @@ springboot-parent com.codingapi.springboot - 3.4.10 + 3.4.11 4.0.0 diff --git a/springboot-starter-flow/pom.xml b/springboot-starter-flow/pom.xml index 18fa58d3..401a3a87 100644 --- a/springboot-starter-flow/pom.xml +++ b/springboot-starter-flow/pom.xml @@ -6,7 +6,7 @@ springboot-parent com.codingapi.springboot - 3.4.10 + 3.4.11 springboot-starter-flow diff --git a/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/service/FlowDirectionService.java b/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/service/FlowDirectionService.java index 451b460f..5ed0216c 100644 --- a/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/service/FlowDirectionService.java +++ b/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/service/FlowDirectionService.java @@ -85,26 +85,6 @@ public boolean hasCurrentFlowNodeIsDone() { return historyRecords.stream().filter(item -> !item.isTransfer()).allMatch(FlowRecord::isDone); } - - /** - * 检测当前流程是否已经完成 - * 即流程已经进行到了最终节点且审批意见为同意 - */ - public boolean hasCurrentFlowIsFinish() { - if (flowSourceDirection == FlowSourceDirection.PASS && flowNode.isOverNode()) { - return true; - } - return false; - } - - - /** - * 判断当前流程是否为默认的驳回流程 - */ - public boolean isDefaultBackRecord() { - return flowSourceDirection == FlowSourceDirection.REJECT && !flowWork.hasBackRelation(); - } - /** * 判断当前流程是否为通过流程 */ @@ -112,11 +92,5 @@ public boolean isPassRecord() { return flowSourceDirection == FlowSourceDirection.PASS; } - /** - * 判断当前流程是否为自定义的驳回流程 - */ - public boolean isCustomBackRecord() { - return flowSourceDirection == FlowSourceDirection.REJECT && flowWork.hasBackRelation(); - } } diff --git a/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/service/FlowNodeService.java b/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/service/FlowNodeService.java index 7c7a3a87..2417a1e6 100644 --- a/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/service/FlowNodeService.java +++ b/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/service/FlowNodeService.java @@ -144,28 +144,6 @@ public void loadDefaultBackNode(FlowRecord currentRecord) { } - /** - * 加载自定义回退节点 - */ - public void loadCustomBackNode(FlowNode flowNode, long parentRecordId) { - FlowNode nextNode = this.matcherNextNode(flowNode, true); - if (nextNode == null) { - throw new IllegalArgumentException("next node not found"); - } - IFlowOperator flowOperator = currentOperator; - if (nextNode.isAnyOperatorMatcher()) { - // 如果是任意人员操作时则需要指定为当时审批人员为当前审批人员 - FlowRecord preFlowRecord = flowRecordRepository.getFlowRecordById(parentRecordId); - while (preFlowRecord.isTransfer() || !preFlowRecord.getNodeCode().equals(nextNode.getCode())) { - preFlowRecord = flowRecordRepository.getFlowRecordById(preFlowRecord.getPreId()); - } - flowOperator = preFlowRecord.getCurrentOperator(); - } - this.nextNode = nextNode; - this.nextOperator = flowOperator; - this.backOperator = null; - } - /** * 获取下一个节点 diff --git a/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/service/impl/FlowSubmitService.java b/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/service/impl/FlowSubmitService.java index 36322cc8..78d04444 100644 --- a/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/service/impl/FlowSubmitService.java +++ b/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/service/impl/FlowSubmitService.java @@ -191,12 +191,8 @@ private void loadNextNode(List historyRecords) { // 审批通过并进入下一节点 if (flowDirectionService.isPassRecord()) { flowNodeService.loadNextPassNode(flowNode); - // 审批拒绝返回上一节点 - } else if (flowDirectionService.isDefaultBackRecord()) { + } else { flowNodeService.loadDefaultBackNode(flowRecord); - } else { - // 审批拒绝,并且自定了返回节点 - flowNodeService.loadCustomBackNode(flowNode, flowRecord.getPreId()); } this.nextNode = flowNodeService.getNextNode(); } diff --git a/springboot-starter-flow/src/test/java/com/codingapi/springboot/flow/test/FlowRejectTest.java b/springboot-starter-flow/src/test/java/com/codingapi/springboot/flow/test/FlowRejectTest.java new file mode 100644 index 00000000..fdc5ca58 --- /dev/null +++ b/springboot-starter-flow/src/test/java/com/codingapi/springboot/flow/test/FlowRejectTest.java @@ -0,0 +1,244 @@ +package com.codingapi.springboot.flow.test; + +import com.codingapi.springboot.flow.bind.BindDataSnapshot; +import com.codingapi.springboot.flow.build.FlowWorkBuilder; +import com.codingapi.springboot.flow.domain.FlowWork; +import com.codingapi.springboot.flow.domain.Opinion; +import com.codingapi.springboot.flow.em.ApprovalType; +import com.codingapi.springboot.flow.flow.Leave; +import com.codingapi.springboot.flow.matcher.OperatorMatcher; +import com.codingapi.springboot.flow.pojo.FlowResult; +import com.codingapi.springboot.flow.record.FlowRecord; +import com.codingapi.springboot.flow.repository.*; +import com.codingapi.springboot.flow.service.FlowService; +import com.codingapi.springboot.flow.trigger.OutTrigger; +import com.codingapi.springboot.flow.user.User; +import org.junit.jupiter.api.Test; +import org.springframework.data.domain.PageRequest; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class FlowRejectTest { + + private final UserRepository userRepository = new UserRepository(); + private final FlowWorkRepository flowWorkRepository = new FlowWorkRepositoryImpl(); + private final FlowRecordRepositoryImpl flowRecordRepository = new FlowRecordRepositoryImpl(); + private final FlowBindDataRepositoryImpl flowBindDataRepository = new FlowBindDataRepositoryImpl(); + private final LeaveRepository leaveRepository = new LeaveRepository(); + private final FlowBackupRepository flowBackupRepository = new FlowBackupRepositoryImpl(); + private final FlowProcessRepository flowProcessRepository = new FlowProcessRepositoryImpl(flowBackupRepository, userRepository); + private final FlowService flowService = new FlowService(flowWorkRepository, flowRecordRepository, flowBindDataRepository, userRepository, flowProcessRepository, flowBackupRepository); + + /** + * 驳回测试 + */ + @Test + void reject1() { + PageRequest pageRequest = PageRequest.of(0, 1000); + + User lorne = new User("lorne"); + userRepository.save(lorne); + + User user = new User("张飞"); + userRepository.save(user); + + User dept = new User("刘备"); + userRepository.save(dept); + + User boss = new User("诸葛亮"); + userRepository.save(boss); + + FlowWork flowWork = FlowWorkBuilder.builder(user) + .title("请假流程") + .nodes() + .node("开始节点", "start", "default", ApprovalType.UN_SIGN, OperatorMatcher.anyOperatorMatcher()) + .node("部门领导审批", "dept", "default", ApprovalType.SIGN, OperatorMatcher.specifyOperatorMatcher(dept.getUserId(),lorne.getUserId())) + .node("总经理审批", "manager", "default", ApprovalType.SIGN, OperatorMatcher.specifyOperatorMatcher(boss.getUserId())) + .node("结束节点", "over", "default", ApprovalType.UN_SIGN, OperatorMatcher.anyOperatorMatcher()) + .relations() + .relation("部门领导审批", "start", "dept") + .relation("总经理审批", "dept", "manager") + .relation("总经理审批", "dept", "start",new OutTrigger(""" + def run(content) { + return false; + } + """),1,true) + .relation("结束节点", "manager", "over") + .build(); + + flowWorkRepository.save(flowWork); + + String workCode = flowWork.getCode(); + + Leave leave = new Leave("我要出去看看"); + leaveRepository.save(leave); + + // 创建流程 + flowService.startFlow(workCode, user, leave, "发起流程"); + + // 查看我的待办 + List userTodos = flowRecordRepository.findTodoByOperatorId(user.getUserId(), pageRequest).getContent(); + assertEquals(1, userTodos.size()); + + // 提交流程 + FlowRecord userTodo = userTodos.get(0); + assertEquals(0, userTodo.getTimeoutTime()); + + flowService.submitFlow(userTodo.getId(), user, leave, Opinion.pass("同意").specify(lorne.getUserId())); + + // 查看刘备经理的待办 + List deptTodos = flowRecordRepository.findTodoByOperatorId(dept.getUserId(), pageRequest).getContent(); + assertEquals(0, deptTodos.size()); + + List lorneTodos = flowRecordRepository.findTodoByOperatorId(lorne.getUserId(), pageRequest).getContent(); + assertEquals(1, lorneTodos.size()); + + // 提交委托lorne部门经理的审批 + FlowRecord lorneTodo = lorneTodos.get(0); + flowService.submitFlow(lorneTodo.getId(), lorne, leave, Opinion.pass("同意")); + + // 查看总经理的待办 + List bossTodos = flowRecordRepository.findTodoByOperatorId(boss.getUserId(), pageRequest).getContent(); + assertEquals(1, bossTodos.size()); + + // 提交总经理的审批 + FlowRecord bossTodo = bossTodos.get(0); + FlowResult flowResult = flowService.submitFlow(bossTodo.getId(), boss, leave, Opinion.reject("不同意")); + System.out.println(flowResult.getRecords()); + + deptTodos = flowRecordRepository.findTodoByOperatorId(dept.getUserId(), pageRequest).getContent(); + assertEquals(0, deptTodos.size()); + + lorneTodos = flowRecordRepository.findTodoByOperatorId(lorne.getUserId(), pageRequest).getContent(); + assertEquals(1, lorneTodos.size()); + + lorneTodo = lorneTodos.get(0); + flowService.submitFlow(lorneTodo.getId(), lorne, leave, Opinion.pass("同意")); + + bossTodos = flowRecordRepository.findTodoByOperatorId(boss.getUserId(), pageRequest).getContent(); + assertEquals(1, bossTodos.size()); + + bossTodo = bossTodos.get(0); + flowService.submitFlow(bossTodo.getId(), boss, leave, Opinion.pass("同意")); + + // 查看所有流程 + List records = flowRecordRepository.findAll(pageRequest).getContent(); + assertEquals(5, records.size()); + + records = flowRecordRepository.findAll(pageRequest).getContent(); + assertEquals(5, records.size()); + // 查看所有流程是否都已经结束 + assertTrue(records.stream().allMatch(FlowRecord::isFinish)); + + List snapshots = flowBindDataRepository.findAll(); + assertEquals(6, snapshots.size()); + + } + + + + /** + * 驳回测试 + */ + @Test + void reject2() { + PageRequest pageRequest = PageRequest.of(0, 1000); + + User lorne = new User("lorne"); + userRepository.save(lorne); + + User user = new User("张飞"); + userRepository.save(user); + + User dept = new User("刘备"); + userRepository.save(dept); + + User boss = new User("诸葛亮"); + userRepository.save(boss); + + FlowWork flowWork = FlowWorkBuilder.builder(user) + .title("请假流程") + .nodes() + .node("开始节点", "start", "default", ApprovalType.UN_SIGN, OperatorMatcher.anyOperatorMatcher()) + .node("部门领导审批", "dept", "default", ApprovalType.SIGN, OperatorMatcher.specifyOperatorMatcher(dept.getUserId(),lorne.getUserId())) + .node("总经理审批", "manager", "default", ApprovalType.SIGN, OperatorMatcher.specifyOperatorMatcher(boss.getUserId())) + .node("结束节点", "over", "default", ApprovalType.UN_SIGN, OperatorMatcher.anyOperatorMatcher()) + .relations() + .relation("部门领导审批", "start", "dept") + .relation("总经理审批", "dept", "manager") + .relation("结束节点", "manager", "over") + .build(); + + flowWorkRepository.save(flowWork); + + String workCode = flowWork.getCode(); + + Leave leave = new Leave("我要出去看看"); + leaveRepository.save(leave); + + // 创建流程 + flowService.startFlow(workCode, user, leave, "发起流程"); + + // 查看我的待办 + List userTodos = flowRecordRepository.findTodoByOperatorId(user.getUserId(), pageRequest).getContent(); + assertEquals(1, userTodos.size()); + + // 提交流程 + FlowRecord userTodo = userTodos.get(0); + assertEquals(0, userTodo.getTimeoutTime()); + + flowService.submitFlow(userTodo.getId(), user, leave, Opinion.pass("同意").specify(lorne.getUserId())); + + // 查看刘备经理的待办 + List deptTodos = flowRecordRepository.findTodoByOperatorId(dept.getUserId(), pageRequest).getContent(); + assertEquals(0, deptTodos.size()); + + List lorneTodos = flowRecordRepository.findTodoByOperatorId(lorne.getUserId(), pageRequest).getContent(); + assertEquals(1, lorneTodos.size()); + + // 提交委托lorne部门经理的审批 + FlowRecord lorneTodo = lorneTodos.get(0); + flowService.submitFlow(lorneTodo.getId(), lorne, leave, Opinion.pass("同意")); + + // 查看总经理的待办 + List bossTodos = flowRecordRepository.findTodoByOperatorId(boss.getUserId(), pageRequest).getContent(); + assertEquals(1, bossTodos.size()); + + // 提交总经理的审批 + FlowRecord bossTodo = bossTodos.get(0); + FlowResult flowResult = flowService.submitFlow(bossTodo.getId(), boss, leave, Opinion.reject("不同意")); + System.out.println(flowResult.getRecords()); + + deptTodos = flowRecordRepository.findTodoByOperatorId(dept.getUserId(), pageRequest).getContent(); + assertEquals(0, deptTodos.size()); + + lorneTodos = flowRecordRepository.findTodoByOperatorId(lorne.getUserId(), pageRequest).getContent(); + assertEquals(1, lorneTodos.size()); + + lorneTodo = lorneTodos.get(0); + flowService.submitFlow(lorneTodo.getId(), lorne, leave, Opinion.pass("同意")); + + bossTodos = flowRecordRepository.findTodoByOperatorId(boss.getUserId(), pageRequest).getContent(); + assertEquals(1, bossTodos.size()); + + bossTodo = bossTodos.get(0); + flowService.submitFlow(bossTodo.getId(), boss, leave, Opinion.pass("同意")); + + // 查看所有流程 + List records = flowRecordRepository.findAll(pageRequest).getContent(); + assertEquals(5, records.size()); + + records = flowRecordRepository.findAll(pageRequest).getContent(); + assertEquals(5, records.size()); + // 查看所有流程是否都已经结束 + assertTrue(records.stream().allMatch(FlowRecord::isFinish)); + + List snapshots = flowBindDataRepository.findAll(); + assertEquals(6, snapshots.size()); + + } + +} diff --git a/springboot-starter-flow/src/test/java/com/codingapi/springboot/flow/test/MultiRelationFlowTest.java b/springboot-starter-flow/src/test/java/com/codingapi/springboot/flow/test/MultiRelationFlowTest.java index dea70b23..b4c99b8a 100644 --- a/springboot-starter-flow/src/test/java/com/codingapi/springboot/flow/test/MultiRelationFlowTest.java +++ b/springboot-starter-flow/src/test/java/com/codingapi/springboot/flow/test/MultiRelationFlowTest.java @@ -272,33 +272,22 @@ void relationTest3(){ assertEquals(4, records.size()); // 用户修改确认 - userTodos = flowRecordRepository.findTodoByOperatorId(user.getUserId(), pageRequest).getContent(); - assertEquals(1, userTodos.size()); + deptTodos = flowRecordRepository.findTodoByOperatorId(dept.getUserId(), pageRequest).getContent(); + assertEquals(1, deptTodos.size()); // 用户调整为3天 leave.setDays(3); // 提交流程 - userTodo = userTodos.get(0); - flowService.submitFlow(userTodo.getId(), user, leave, Opinion.pass("同意")); - - records = flowRecordRepository.findAll(pageRequest).getContent(); - assertEquals(5, records.size()); - - deptTodos = flowRecordRepository.findTodoByOperatorId(dept.getUserId(), pageRequest).getContent(); - assertEquals(1, deptTodos.size()); - - // 提交部门经理的审批 deptTodo = deptTodos.get(0); flowService.submitFlow(deptTodo.getId(), dept, leave, Opinion.pass("同意")); - // 用户修改确认 - userTodos = flowRecordRepository.findTodoByOperatorId(user.getUserId(), pageRequest).getContent(); - assertEquals(0, userTodos.size()); + records = flowRecordRepository.findAll(pageRequest).getContent(); + assertEquals(4, records.size()); // 查看所有流程是否都已经结束 assertTrue(records.stream().allMatch(FlowRecord::isFinish)); List snapshots = flowBindDataRepository.findAll(); - assertEquals(6, snapshots.size()); + assertEquals(5, snapshots.size()); } } diff --git a/springboot-starter-security/pom.xml b/springboot-starter-security/pom.xml index 07116672..aed963a8 100644 --- a/springboot-starter-security/pom.xml +++ b/springboot-starter-security/pom.xml @@ -6,7 +6,7 @@ springboot-parent com.codingapi.springboot - 3.4.10 + 3.4.11 springboot-starter-security diff --git a/springboot-starter/pom.xml b/springboot-starter/pom.xml index d69d8ee3..ccd134e3 100644 --- a/springboot-starter/pom.xml +++ b/springboot-starter/pom.xml @@ -5,7 +5,7 @@ com.codingapi.springboot springboot-parent - 3.4.10 + 3.4.11 springboot-starter diff --git a/springboot-starter/src/main/resources/banner.txt b/springboot-starter/src/main/resources/banner.txt index 8cb31341..58a57869 100644 --- a/springboot-starter/src/main/resources/banner.txt +++ b/springboot-starter/src/main/resources/banner.txt @@ -1,4 +1,4 @@ ------------------------------------------------------ -CodingApi SpringBoot-Starter 3.4.10 +CodingApi SpringBoot-Starter 3.4.11 springboot version (${spring-boot.version}) ------------------------------------------------------