From b69da9a4e4a0f6759e038d9eb326c47fbfa1eb8e Mon Sep 17 00:00:00 2001 From: lanyuanxiaoyao Date: Fri, 3 Jan 2025 12:36:49 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=8C=82=E8=B5=B7=E6=93=8D?= =?UTF-8?q?=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/manager/FlowableManager.java | 5 ++++ .../flowable/core/model/FlowableAction.java | 1 + .../flowable/core/model/FlowableInstance.java | 2 +- .../flowable/core/model/FlowableNode.java | 8 +++-- .../flowable/test/TestFlowableManager.java | 22 ++++++++++++++ .../test/handler/TwoApproveHandler.java | 30 +++++++++++++++++++ 6 files changed, 65 insertions(+), 3 deletions(-) create mode 100644 flowable-example/src/main/java/com/lanyuanxiaoyao/flowable/test/handler/TwoApproveHandler.java diff --git a/flowable-core/src/main/java/com/lanyuanxiaoyao/flowable/core/manager/FlowableManager.java b/flowable-core/src/main/java/com/lanyuanxiaoyao/flowable/core/manager/FlowableManager.java index ac0a826..f37a915 100644 --- a/flowable-core/src/main/java/com/lanyuanxiaoyao/flowable/core/manager/FlowableManager.java +++ b/flowable-core/src/main/java/com/lanyuanxiaoyao/flowable/core/manager/FlowableManager.java @@ -129,6 +129,11 @@ public abstract class FlowableManager { throw new IllegalArgumentException("节点执行结果不能为空"); } + // 如果是挂起操作,就直接返回,不做操作 + if (FlowableAction.SUSPEND.equals(action)) { + return; + } + if (FlowableAction.TERMINAL.equals(action)) { saveInstance(instance, FlowableInstance.Status.ERROR, metadata, action, comment); return; diff --git a/flowable-core/src/main/java/com/lanyuanxiaoyao/flowable/core/model/FlowableAction.java b/flowable-core/src/main/java/com/lanyuanxiaoyao/flowable/core/model/FlowableAction.java index b669826..5ec2478 100644 --- a/flowable-core/src/main/java/com/lanyuanxiaoyao/flowable/core/model/FlowableAction.java +++ b/flowable-core/src/main/java/com/lanyuanxiaoyao/flowable/core/model/FlowableAction.java @@ -10,4 +10,5 @@ public enum FlowableAction { APPROVE, REJECT, TERMINAL, + SUSPEND, } diff --git a/flowable-core/src/main/java/com/lanyuanxiaoyao/flowable/core/model/FlowableInstance.java b/flowable-core/src/main/java/com/lanyuanxiaoyao/flowable/core/model/FlowableInstance.java index 1945bfe..760aa6f 100644 --- a/flowable-core/src/main/java/com/lanyuanxiaoyao/flowable/core/model/FlowableInstance.java +++ b/flowable-core/src/main/java/com/lanyuanxiaoyao/flowable/core/model/FlowableInstance.java @@ -17,7 +17,7 @@ public class FlowableInstance { private String currentNodeId; private Status status; - private LocalDateTime updatedTime = LocalDateTime.now(); + private LocalDateTime updatedTime; public FlowableInstance(String instanceId, String currentNodeId) { this(instanceId, currentNodeId, MapHelper.empty(), Status.RUNNING, LocalDateTime.now(), LocalDateTime.now()); diff --git a/flowable-core/src/main/java/com/lanyuanxiaoyao/flowable/core/model/FlowableNode.java b/flowable-core/src/main/java/com/lanyuanxiaoyao/flowable/core/model/FlowableNode.java index 4b91992..e0cf567 100644 --- a/flowable-core/src/main/java/com/lanyuanxiaoyao/flowable/core/model/FlowableNode.java +++ b/flowable-core/src/main/java/com/lanyuanxiaoyao/flowable/core/model/FlowableNode.java @@ -28,11 +28,15 @@ public class FlowableNode { private LocalDateTime updatedTime = LocalDateTime.now(); public FlowableNode(String nodeId, String name, String description, Map targets) { - this(nodeId, name, description, Type.MANUAL, FlowableHandler.DefaultFlowableHandler.class.getName(), targets, ListHelper.empty(), LocalDateTime.now()); + this(nodeId, name, description, Type.MANUAL, FlowableHandler.DefaultFlowableHandler.class, targets); } public FlowableNode(String nodeId, String name, String description, Class actionClass, Map targets) { - this(nodeId, name, description, Type.AUTOMATIC, actionClass.getName(), targets, ListHelper.empty(), LocalDateTime.now()); + this(nodeId, name, description, Type.AUTOMATIC, actionClass, targets); + } + + public FlowableNode(String nodeId, String name, String description, Type type, Class actionClass, Map targets) { + this(nodeId, name, description, type, actionClass.getName(), targets, ListHelper.empty(), LocalDateTime.now()); } public FlowableNode(String nodeId, String name, String description, Type type, String handler, Map targets, List listeners, LocalDateTime createdTime) { diff --git a/flowable-example/src/main/java/com/lanyuanxiaoyao/flowable/test/TestFlowableManager.java b/flowable-example/src/main/java/com/lanyuanxiaoyao/flowable/test/TestFlowableManager.java index 3553ce7..0864973 100644 --- a/flowable-example/src/main/java/com/lanyuanxiaoyao/flowable/test/TestFlowableManager.java +++ b/flowable-example/src/main/java/com/lanyuanxiaoyao/flowable/test/TestFlowableManager.java @@ -6,6 +6,7 @@ import com.lanyuanxiaoyao.flowable.core.model.FlowableAction; import com.lanyuanxiaoyao.flowable.core.model.FlowableHandler; import com.lanyuanxiaoyao.flowable.core.model.FlowableInstance; import com.lanyuanxiaoyao.flowable.core.model.FlowableNode; +import com.lanyuanxiaoyao.flowable.test.handler.TwoApproveHandler; import java.util.Map; import java.util.UUID; import lombok.extern.slf4j.Slf4j; @@ -121,6 +122,27 @@ public abstract class TestFlowableManager { Assertions.assertThrows(IllegalArgumentException.class, () -> manager.approve(instanceId)); } + @Test + public void testSuspend() { + FlowableManager manager = flowableManager(); + FlowableNode node = new FlowableNode( + "edf1b7b0-f45b-4256-b696-ce84857f03f7", + "edf1b7b0-f45b-4256-b696-ce84857f03f7", + "edf1b7b0-f45b-4256-b696-ce84857f03f7", + FlowableNode.Type.MANUAL, + TwoApproveHandler.class, + null + ); + manager.create(node); + + String instanceId = manager.start(node.getNodeId()); + Assertions.assertEquals(FlowableInstance.Status.RUNNING, manager.getInstance(instanceId).getStatus()); + manager.approve(instanceId); + Assertions.assertEquals(FlowableInstance.Status.RUNNING, manager.getInstance(instanceId).getStatus()); + manager.approve(instanceId); + Assertions.assertEquals(FlowableInstance.Status.COMPLETED, manager.getInstance(instanceId).getStatus()); + } + protected abstract Class getAutomaticNodeClass(); @Test diff --git a/flowable-example/src/main/java/com/lanyuanxiaoyao/flowable/test/handler/TwoApproveHandler.java b/flowable-example/src/main/java/com/lanyuanxiaoyao/flowable/test/handler/TwoApproveHandler.java new file mode 100644 index 0000000..5ab8d90 --- /dev/null +++ b/flowable-example/src/main/java/com/lanyuanxiaoyao/flowable/test/handler/TwoApproveHandler.java @@ -0,0 +1,30 @@ +package com.lanyuanxiaoyao.flowable.test.handler; + +import com.lanyuanxiaoyao.flowable.core.model.FlowableAction; +import com.lanyuanxiaoyao.flowable.core.model.FlowableHandler; +import com.lanyuanxiaoyao.flowable.core.model.FlowableInstance; +import com.lanyuanxiaoyao.flowable.core.model.FlowableNode; +import java.util.Map; +import lombok.extern.slf4j.Slf4j; + +/** + * 同意两次才能通过的自动节点 + * + * @author lanyuanxiaoyao + * @version 20250103 + */ +@Slf4j +public class TwoApproveHandler implements FlowableHandler { + private static final String KEY = "approve-times"; + + @Override + public FlowableAction handle(FlowableAction action, FlowableInstance instance, FlowableNode node, Map metadata) { + log.info("{}", metadata); + int approveCount = (int) metadata.getOrDefault(KEY, 0); + if (approveCount + 1 > 1) { + return FlowableAction.APPROVE; + } + metadata.put(KEY, approveCount + 1); + return FlowableAction.SUSPEND; + } +}