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