统一自动节点和手动节点的逻辑
This commit is contained in:
@@ -26,15 +26,14 @@ public class SpringFlowableManager extends FlowableManager {
|
||||
@Override
|
||||
protected <T> T createBean(String classpath) {
|
||||
Class<?> clazz = Class.forName(classpath);
|
||||
T targetObject = null;
|
||||
T targetObject;
|
||||
try {
|
||||
targetObject = (T) applicationContext.getBean(clazz);
|
||||
} catch (Exception springException) {
|
||||
log.warn("{} not found in spring context", springException);
|
||||
try {
|
||||
targetObject = (T) clazz.newInstance();
|
||||
} catch (Exception javaException) {
|
||||
throw new IllegalArgumentException(javaException);
|
||||
throw new IllegalArgumentException(javaException.initCause(springException));
|
||||
}
|
||||
}
|
||||
return targetObject;
|
||||
|
||||
@@ -47,12 +47,12 @@ public class JpaFlowableNode {
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(nullable = false)
|
||||
private FlowableNode.Type type;
|
||||
private String automaticAction;
|
||||
private String handler;
|
||||
@ElementCollection(fetch = javax.persistence.FetchType.EAGER)
|
||||
@MapKeyColumn(name = "action")
|
||||
@Column(name = "nodeId")
|
||||
@CollectionTable(name = "flowable_node_manual_actions", foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
|
||||
private Map<FlowableAction, String> manualActions;
|
||||
@CollectionTable(name = "flowable_node_targets", foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
|
||||
private Map<FlowableAction, String> targets;
|
||||
|
||||
@CreatedDate
|
||||
private LocalDateTime createdTime;
|
||||
@@ -64,12 +64,12 @@ public class JpaFlowableNode {
|
||||
this.name = node.getName();
|
||||
this.description = node.getDescription();
|
||||
this.type = node.getType();
|
||||
this.automaticAction = node.getAutomaticAction();
|
||||
this.manualActions = node.getManualActions();
|
||||
this.handler = node.getHandler();
|
||||
this.targets = node.getTargets();
|
||||
}
|
||||
|
||||
public FlowableNode toFlowableNode() {
|
||||
FlowableNode node = new FlowableNode(nodeId, name, description, type, automaticAction, manualActions, null, createdTime);
|
||||
FlowableNode node = new FlowableNode(nodeId, name, description, type, handler, targets, null, createdTime);
|
||||
node.setUpdatedTime(updateTime);
|
||||
return node;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.lanyuanxiaoyao.flowable.jpa;
|
||||
|
||||
import com.lanyuanxiaoyao.flowable.core.manager.FlowableManager;
|
||||
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;
|
||||
@@ -13,12 +14,12 @@ import lombok.extern.slf4j.Slf4j;
|
||||
* @version 20250102
|
||||
*/
|
||||
@Slf4j
|
||||
public class SimpleAutoAction implements FlowableNode.AutoAction {
|
||||
public class SimpleAutoAction implements FlowableHandler {
|
||||
@Resource
|
||||
private FlowableManager flowableManager;
|
||||
|
||||
@Override
|
||||
public FlowableAction action(FlowableInstance instance, FlowableNode node, Map<String, Object> metadata) {
|
||||
public FlowableAction handle(FlowableAction action, FlowableInstance instance, FlowableNode node, Map<String, Object> metadata) {
|
||||
log.info("Initial with spring: {}", flowableManager.listNodes());
|
||||
return FlowableAction.APPROVE;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.lanyuanxiaoyao.flowable.jpa;
|
||||
|
||||
import com.lanyuanxiaoyao.flowable.core.manager.FlowableManager;
|
||||
import com.lanyuanxiaoyao.flowable.core.model.FlowableHandler;
|
||||
import com.lanyuanxiaoyao.flowable.test.TestFlowableManager;
|
||||
import javax.annotation.Resource;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
@@ -20,7 +21,7 @@ public class TestSpringFlowableManager extends TestFlowableManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<?> getAutomaticNodeClass() {
|
||||
protected Class<? extends FlowableHandler> getAutomaticNodeClass() {
|
||||
return SimpleAutoAction.class;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.lanyuanxiaoyao.flowable.core.helper.ListHelper;
|
||||
import com.lanyuanxiaoyao.flowable.core.helper.MapHelper;
|
||||
import com.lanyuanxiaoyao.flowable.core.helper.StringHelper;
|
||||
import com.lanyuanxiaoyao.flowable.core.model.FlowableAction;
|
||||
import com.lanyuanxiaoyao.flowable.core.model.FlowableHandler;
|
||||
import com.lanyuanxiaoyao.flowable.core.model.FlowableHistory;
|
||||
import com.lanyuanxiaoyao.flowable.core.model.FlowableInstance;
|
||||
import com.lanyuanxiaoyao.flowable.core.model.FlowableListener;
|
||||
@@ -104,12 +105,7 @@ public abstract class FlowableManager {
|
||||
}
|
||||
|
||||
private void autoAction(FlowableInstance instance, FlowableNode node, Map<String, Object> metadata) {
|
||||
String actionClass = node.getAutomaticAction();
|
||||
if (StringHelper.isBlank(actionClass)) {
|
||||
throw new IllegalArgumentException("自动节点执行器为空");
|
||||
}
|
||||
FlowableNode.AutoAction autoAction = createBean(actionClass);
|
||||
action(instance, node, autoAction.action(instance, node, metadata), "系统自动执行", metadata);
|
||||
action(instance, node, null, "系统自动执行", metadata);
|
||||
}
|
||||
|
||||
private void action(String instanceId, FlowableAction action, String comment, Map<String, Object> metadata) {
|
||||
@@ -122,17 +118,25 @@ public abstract class FlowableManager {
|
||||
if (FlowableInstance.Status.COMPLETED.equals(instance.getStatus()) || FlowableInstance.Status.ERROR.equals(instance.getStatus())) {
|
||||
throw new IllegalArgumentException("ID为" + instance.getInstanceId() + "的流程已结束,无法操作");
|
||||
}
|
||||
|
||||
String handlerClass = node.getHandler();
|
||||
if (StringHelper.isBlank(handlerClass)) {
|
||||
throw new IllegalArgumentException("节点执行器为空");
|
||||
}
|
||||
FlowableHandler handler = createBean(handlerClass);
|
||||
action = handler.handle(action, instance, node, metadata);
|
||||
|
||||
if (FlowableAction.TERMINAL.equals(action)) {
|
||||
saveInstance(instance, FlowableInstance.Status.ERROR, metadata, action, comment);
|
||||
return;
|
||||
}
|
||||
if (Objects.isNull(node.getManualActions())
|
||||
|| !node.getManualActions().containsKey(action)
|
||||
|| StringHelper.isBlank(node.getManualActions().get(action))) {
|
||||
if (Objects.isNull(node.getTargets())
|
||||
|| !node.getTargets().containsKey(action)
|
||||
|| StringHelper.isBlank(node.getTargets().get(action))) {
|
||||
saveInstance(instance, FlowableInstance.Status.COMPLETED, metadata, action, comment);
|
||||
return;
|
||||
}
|
||||
String nextNodeId = node.getManualActions().get(action);
|
||||
String nextNodeId = node.getTargets().get(action);
|
||||
FlowableNode nextNode = flowableRepository.getNode(nextNodeId);
|
||||
instance.setCurrentNodeId(nextNode.getNodeId());
|
||||
saveInstance(instance, FlowableInstance.Status.RUNNING, metadata, action, comment);
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.lanyuanxiaoyao.flowable.core.model;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 处理器
|
||||
*
|
||||
* @author lanyuanxiaoyao
|
||||
* @version 20250103
|
||||
*/
|
||||
public interface FlowableHandler {
|
||||
FlowableAction handle(FlowableAction action, FlowableInstance instance, FlowableNode node, Map<String, Object> metadata);
|
||||
|
||||
class DefaultFlowableHandler implements FlowableHandler {
|
||||
@Override
|
||||
public FlowableAction handle(FlowableAction action, FlowableInstance instance, FlowableNode node, Map<String, Object> metadata) {
|
||||
return action;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,25 +19,29 @@ public class FlowableNode {
|
||||
private final String description;
|
||||
|
||||
private final Type type;
|
||||
private final String automaticAction;
|
||||
private final Map<FlowableAction, String> manualActions;
|
||||
private final String handler;
|
||||
private final Map<FlowableAction, String> targets;
|
||||
|
||||
private final List<String> listeners;
|
||||
private final LocalDateTime createdTime;
|
||||
|
||||
private LocalDateTime updatedTime = LocalDateTime.now();
|
||||
|
||||
public FlowableNode(String nodeId, String name, String description, Type type, String automaticAction, Map<FlowableAction, String> manualActions) {
|
||||
this(nodeId, name, description, type, automaticAction, manualActions, ListHelper.empty(), LocalDateTime.now());
|
||||
public FlowableNode(String nodeId, String name, String description, Map<FlowableAction, String> targets) {
|
||||
this(nodeId, name, description, Type.MANUAL, FlowableHandler.DefaultFlowableHandler.class.getName(), targets, ListHelper.empty(), LocalDateTime.now());
|
||||
}
|
||||
|
||||
public FlowableNode(String nodeId, String name, String description, Type type, String automaticAction, Map<FlowableAction, String> manualActions, List<String> listeners, LocalDateTime createdTime) {
|
||||
public FlowableNode(String nodeId, String name, String description, Class<? extends FlowableHandler> actionClass, Map<FlowableAction, String> targets) {
|
||||
this(nodeId, name, description, Type.AUTOMATIC, actionClass.getName(), targets, ListHelper.empty(), LocalDateTime.now());
|
||||
}
|
||||
|
||||
public FlowableNode(String nodeId, String name, String description, Type type, String handler, Map<FlowableAction, String> targets, List<String> listeners, LocalDateTime createdTime) {
|
||||
this.nodeId = nodeId;
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.type = type;
|
||||
this.automaticAction = automaticAction;
|
||||
this.manualActions = manualActions;
|
||||
this.handler = handler;
|
||||
this.targets = targets;
|
||||
this.listeners = listeners;
|
||||
this.createdTime = createdTime;
|
||||
}
|
||||
@@ -46,8 +50,4 @@ public class FlowableNode {
|
||||
AUTOMATIC,
|
||||
MANUAL,
|
||||
}
|
||||
|
||||
public interface AutoAction {
|
||||
FlowableAction action(FlowableInstance instance, FlowableNode node, Map<String, Object> metadata);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.lanyuanxiaoyao.flowable.test;
|
||||
import com.lanyuanxiaoyao.flowable.core.helper.MapHelper;
|
||||
import com.lanyuanxiaoyao.flowable.core.manager.FlowableManager;
|
||||
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;
|
||||
@@ -34,8 +35,6 @@ public abstract class TestFlowableManager {
|
||||
nodeId,
|
||||
UUID.randomUUID().toString(),
|
||||
UUID.randomUUID().toString(),
|
||||
FlowableNode.Type.MANUAL,
|
||||
null,
|
||||
nextNodes
|
||||
);
|
||||
}
|
||||
@@ -122,7 +121,7 @@ public abstract class TestFlowableManager {
|
||||
Assertions.assertThrows(IllegalArgumentException.class, () -> manager.approve(instanceId));
|
||||
}
|
||||
|
||||
protected abstract Class<?> getAutomaticNodeClass();
|
||||
protected abstract Class<? extends FlowableHandler> getAutomaticNodeClass();
|
||||
|
||||
@Test
|
||||
public void testAutomaticNode() {
|
||||
@@ -131,8 +130,7 @@ public abstract class TestFlowableManager {
|
||||
"2733d930-7a4b-491e-b1ca-4d5811435e9f",
|
||||
"自动节点",
|
||||
"自动节点",
|
||||
FlowableNode.Type.AUTOMATIC,
|
||||
getAutomaticNodeClass().getName(),
|
||||
getAutomaticNodeClass(),
|
||||
null
|
||||
);
|
||||
manager.create(node);
|
||||
|
||||
@@ -1,17 +1,21 @@
|
||||
package com.lanyuanxiaoyao.flowable.test;
|
||||
|
||||
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 20250102
|
||||
*/
|
||||
public class SimpleAutoAction implements FlowableNode.AutoAction {
|
||||
@Slf4j
|
||||
public class SimpleAutoHandler implements FlowableHandler {
|
||||
@Override
|
||||
public FlowableAction action(FlowableInstance instance, FlowableNode node, Map<String, Object> metadata) {
|
||||
public FlowableAction handle(FlowableAction action, FlowableInstance instance, FlowableNode node, Map<String, Object> metadata) {
|
||||
log.info("Simple handler initial");
|
||||
return FlowableAction.APPROVE;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.lanyuanxiaoyao.flowable.test;
|
||||
|
||||
import com.lanyuanxiaoyao.flowable.core.manager.FlowableManager;
|
||||
import com.lanyuanxiaoyao.flowable.core.model.FlowableHandler;
|
||||
|
||||
/**
|
||||
* @author lanyuanxiaoyao
|
||||
@@ -13,7 +14,7 @@ public class TestSimpleFlowableManager extends TestFlowableManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<?> getAutomaticNodeClass() {
|
||||
return SimpleAutoAction.class;
|
||||
protected Class<? extends FlowableHandler> getAutomaticNodeClass() {
|
||||
return SimpleAutoHandler.class;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user