调整metadata的结构,使用更方便
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
package com.lanyuanxiaoyao.flowable.jpa.entity;
|
||||
|
||||
import com.lanyuanxiaoyao.flowable.core.model.FlowableMetadata;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Map;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.EntityListeners;
|
||||
@@ -82,7 +82,7 @@ public class FlowableInstance {
|
||||
return new com.lanyuanxiaoyao.flowable.core.model.FlowableInstance(
|
||||
instanceId,
|
||||
currentNodeId,
|
||||
(Map<String, Object>) bytesToObject(this.metadata),
|
||||
(FlowableMetadata) bytesToObject(this.metadata),
|
||||
status,
|
||||
createdTime,
|
||||
updatedTime
|
||||
|
||||
@@ -5,7 +5,6 @@ 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 javax.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@@ -19,7 +18,7 @@ public class SimpleAutoAction implements FlowableHandler {
|
||||
private FlowableManager flowableManager;
|
||||
|
||||
@Override
|
||||
public FlowableAction handle(FlowableAction action, FlowableInstance instance, FlowableNode node, Map<String, Object> metadata) {
|
||||
public FlowableAction handle(FlowableInstance instance, FlowableNode node, FlowableAction action) {
|
||||
log.info("Initial with spring: {}", flowableManager.listNodes());
|
||||
return FlowableAction.APPROVE;
|
||||
}
|
||||
|
||||
@@ -33,6 +33,10 @@ public class MapHelper {
|
||||
return Objects.isNull(map) || map.isEmpty();
|
||||
}
|
||||
|
||||
public static boolean isNotEmpty(Map<?, ?> map) {
|
||||
return !isEmpty(map);
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
public static <K, V> Map<K, V> concat(Map<K, V>... maps) {
|
||||
Map<K, V> result = new HashMap<>();
|
||||
|
||||
@@ -8,6 +8,7 @@ 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;
|
||||
import com.lanyuanxiaoyao.flowable.core.model.FlowableMetadata;
|
||||
import com.lanyuanxiaoyao.flowable.core.model.FlowableNode;
|
||||
import com.lanyuanxiaoyao.flowable.core.repository.FlowableRepository;
|
||||
import java.time.LocalDateTime;
|
||||
@@ -67,11 +68,11 @@ public abstract class FlowableManager {
|
||||
|
||||
public String start(String nodeId, Map<String, Object> metadata) {
|
||||
FlowableNode node = repository.getNode(nodeId);
|
||||
FlowableInstance instance = new FlowableInstance(createId(), node.getNodeId(), metadata);
|
||||
FlowableInstance instance = new FlowableInstance(createId(), node.getNodeId(), new FlowableMetadata(metadata));
|
||||
repository.saveInstance(instance);
|
||||
|
||||
if (FlowableNode.Type.AUTOMATIC.equals(node.getType())) {
|
||||
automaticAction(instance, node, MapHelper.empty());
|
||||
automaticAction(instance, node);
|
||||
}
|
||||
return instance.getInstanceId();
|
||||
}
|
||||
@@ -106,16 +107,18 @@ public abstract class FlowableManager {
|
||||
|
||||
private void manualAction(String instanceId, FlowableAction action, String comment, Map<String, Object> metadata) {
|
||||
FlowableInstance instance = repository.getInstance(instanceId);
|
||||
if (MapHelper.isNotEmpty(metadata)) {
|
||||
instance.getMetadata().putAll(metadata);
|
||||
}
|
||||
FlowableNode node = repository.getNode(instance.getCurrentNodeId());
|
||||
metadata = MapHelper.isEmpty(metadata) ? instance.getMetadata() : MapHelper.concat(metadata, instance.getMetadata());
|
||||
action(instance, node, action, comment, metadata);
|
||||
action(instance, node, action, comment);
|
||||
}
|
||||
|
||||
private void automaticAction(FlowableInstance instance, FlowableNode node, Map<String, Object> metadata) {
|
||||
action(instance, node, null, "系统自动执行", metadata);
|
||||
private void automaticAction(FlowableInstance instance, FlowableNode node) {
|
||||
action(instance, node, null, "系统自动执行");
|
||||
}
|
||||
|
||||
private void action(FlowableInstance instance, FlowableNode node, FlowableAction action, String comment, Map<String, Object> metadata) {
|
||||
private void action(FlowableInstance instance, FlowableNode node, FlowableAction action, String comment) {
|
||||
if (FlowableInstance.Status.COMPLETED.equals(instance.getStatus()) || FlowableInstance.Status.ERROR.equals(instance.getStatus())) {
|
||||
throw new IllegalArgumentException("ID为" + instance.getInstanceId() + "的流程已结束,无法操作");
|
||||
}
|
||||
@@ -125,42 +128,39 @@ public abstract class FlowableManager {
|
||||
throw new IllegalArgumentException("节点执行器为空");
|
||||
}
|
||||
FlowableHandler handler = createBean(handlerClass);
|
||||
action = handler.handle(action, instance, node, metadata);
|
||||
action = handler.handle(instance, node, action);
|
||||
if (Objects.isNull(action)) {
|
||||
throw new IllegalArgumentException("节点执行结果不能为空");
|
||||
}
|
||||
|
||||
// 如果是挂起操作,就直接返回,不做操作
|
||||
if (FlowableAction.SUSPEND.equals(action)) {
|
||||
saveInstance(instance, instance.getStatus(), metadata, action, comment);
|
||||
saveInstance(instance, instance.getStatus(), action, comment);
|
||||
return;
|
||||
}
|
||||
|
||||
if (FlowableAction.TERMINAL.equals(action)) {
|
||||
saveInstance(instance, FlowableInstance.Status.ERROR, metadata, action, comment);
|
||||
saveInstance(instance, FlowableInstance.Status.ERROR, action, comment);
|
||||
return;
|
||||
}
|
||||
if (Objects.isNull(node.getTargets())
|
||||
|| !node.getTargets().containsKey(action)
|
||||
|| StringHelper.isBlank(node.getTargets().get(action))) {
|
||||
saveInstance(instance, FlowableInstance.Status.COMPLETED, metadata, action, comment);
|
||||
saveInstance(instance, FlowableInstance.Status.COMPLETED, action, comment);
|
||||
return;
|
||||
}
|
||||
String nextNodeId = node.getTargets().get(action);
|
||||
FlowableNode nextNode = repository.getNode(nextNodeId);
|
||||
instance.setCurrentNodeId(nextNode.getNodeId());
|
||||
saveInstance(instance, FlowableInstance.Status.RUNNING, metadata, action, comment);
|
||||
saveInstance(instance, FlowableInstance.Status.RUNNING, action, comment);
|
||||
|
||||
if (FlowableNode.Type.AUTOMATIC.equals(nextNode.getType())) {
|
||||
automaticAction(instance, node, metadata);
|
||||
automaticAction(instance, node);
|
||||
}
|
||||
}
|
||||
|
||||
private void saveInstance(FlowableInstance instance, FlowableInstance.Status status, Map<String, Object> metadata, FlowableAction action, String comment) {
|
||||
private void saveInstance(FlowableInstance instance, FlowableInstance.Status status, FlowableAction action, String comment) {
|
||||
instance.setStatus(status);
|
||||
if (Objects.nonNull(metadata)) {
|
||||
instance.addMetadata(metadata);
|
||||
}
|
||||
instance.setUpdatedTime(LocalDateTime.now());
|
||||
|
||||
FlowableHistory history = new FlowableHistory(createId(), instance.getInstanceId(), action, comment);
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.lanyuanxiaoyao.flowable.core.model;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 权限校验
|
||||
*
|
||||
@@ -7,5 +9,5 @@ package com.lanyuanxiaoyao.flowable.core.model;
|
||||
* @version 20241231
|
||||
*/
|
||||
public interface FlowableAccessor {
|
||||
boolean access(Object accessor);
|
||||
boolean access(Map<String, Object> metadata);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package com.lanyuanxiaoyao.flowable.core.model;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 处理器
|
||||
*
|
||||
@@ -9,11 +7,11 @@ import java.util.Map;
|
||||
* @version 20250103
|
||||
*/
|
||||
public interface FlowableHandler {
|
||||
FlowableAction handle(FlowableAction action, FlowableInstance instance, FlowableNode node, Map<String, Object> metadata);
|
||||
FlowableAction handle(FlowableInstance instance, FlowableNode node, FlowableAction action);
|
||||
|
||||
class DefaultFlowableHandler implements FlowableHandler {
|
||||
@Override
|
||||
public FlowableAction handle(FlowableAction action, FlowableInstance instance, FlowableNode node, Map<String, Object> metadata) {
|
||||
public FlowableAction handle(FlowableInstance instance, FlowableNode node, FlowableAction action) {
|
||||
return action;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.lanyuanxiaoyao.flowable.core.model;
|
||||
|
||||
import com.lanyuanxiaoyao.flowable.core.helper.MapHelper;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Map;
|
||||
import lombok.Data;
|
||||
@@ -12,7 +11,7 @@ import lombok.Data;
|
||||
@Data
|
||||
public class FlowableInstance {
|
||||
private final String instanceId;
|
||||
private final Map<String, Object> metadata;
|
||||
private final FlowableMetadata metadata;
|
||||
private final LocalDateTime createdTime;
|
||||
|
||||
private String currentNodeId;
|
||||
@@ -20,14 +19,14 @@ public class FlowableInstance {
|
||||
private LocalDateTime updatedTime;
|
||||
|
||||
public FlowableInstance(String instanceId, String currentNodeId) {
|
||||
this(instanceId, currentNodeId, MapHelper.empty(), Status.RUNNING, LocalDateTime.now(), LocalDateTime.now());
|
||||
this(instanceId, currentNodeId, new FlowableMetadata(), Status.RUNNING, LocalDateTime.now(), LocalDateTime.now());
|
||||
}
|
||||
|
||||
public FlowableInstance(String instanceId, String currentNodeId, Map<String, Object> metadata) {
|
||||
public FlowableInstance(String instanceId, String currentNodeId, FlowableMetadata metadata) {
|
||||
this(instanceId, currentNodeId, metadata, Status.RUNNING, LocalDateTime.now(), LocalDateTime.now());
|
||||
}
|
||||
|
||||
public FlowableInstance(String instanceId, String currentNodeId, Map<String, Object> metadata, Status status, LocalDateTime createdTime, LocalDateTime updatedTime) {
|
||||
public FlowableInstance(String instanceId, String currentNodeId, FlowableMetadata metadata, Status status, LocalDateTime createdTime, LocalDateTime updatedTime) {
|
||||
this.instanceId = instanceId;
|
||||
this.metadata = metadata;
|
||||
this.createdTime = createdTime;
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
package com.lanyuanxiaoyao.flowable.core.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import lombok.Getter;
|
||||
import lombok.ToString;
|
||||
|
||||
/**
|
||||
* 节点流转上下文
|
||||
*
|
||||
* @author lanyuanxiaoyao
|
||||
* @version 20250103
|
||||
*/
|
||||
@ToString
|
||||
@Getter
|
||||
public class FlowableMetadata implements Serializable {
|
||||
private final Map<String, Object> metadata;
|
||||
|
||||
public FlowableMetadata() {
|
||||
this(new HashMap<>());
|
||||
}
|
||||
|
||||
public FlowableMetadata(Map<String, Object> metadata) {
|
||||
this.metadata = metadata;
|
||||
}
|
||||
|
||||
public Object put(String key, Object value) {
|
||||
return metadata.put(key, value);
|
||||
}
|
||||
|
||||
public Object get(String key) {
|
||||
return metadata.get(key);
|
||||
}
|
||||
|
||||
public <T> T get(String key, Class<T> clazz) {
|
||||
return clazz.cast(metadata.get(key));
|
||||
}
|
||||
|
||||
public Integer getInt(String key) {
|
||||
return get(key, Integer.class);
|
||||
}
|
||||
|
||||
public Long getLong(String key) {
|
||||
return get(key, Long.class);
|
||||
}
|
||||
|
||||
public Boolean getBoolean(String key) {
|
||||
return get(key, Boolean.class);
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return metadata.isEmpty();
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return metadata.size();
|
||||
}
|
||||
|
||||
public boolean containsKey(String key) {
|
||||
return metadata.containsKey(key);
|
||||
}
|
||||
|
||||
public boolean containsValue(String value) {
|
||||
return metadata.containsValue(value);
|
||||
}
|
||||
|
||||
public Object remove(String key) {
|
||||
return metadata.remove(key);
|
||||
}
|
||||
|
||||
public void putAll(Map<String, Object> m) {
|
||||
metadata.putAll(m);
|
||||
}
|
||||
|
||||
public Object getOrDefault(String key, Object defaultValue) {
|
||||
return metadata.getOrDefault(key, defaultValue);
|
||||
}
|
||||
|
||||
public <T> T getOrDefault(String key, Class<T> clazz, T defaultValue) {
|
||||
return clazz.cast(metadata.getOrDefault(key, defaultValue));
|
||||
}
|
||||
|
||||
public Integer getIntOrDefault(String key, Integer defaultValue) {
|
||||
return getOrDefault(key, Integer.class, defaultValue);
|
||||
}
|
||||
|
||||
public Long getLongOrDefault(String key, Long defaultValue) {
|
||||
return getOrDefault(key, Long.class, defaultValue);
|
||||
}
|
||||
|
||||
public Boolean getBooleanOrDefault(String key, Boolean defaultValue) {
|
||||
return getOrDefault(key, Boolean.class, defaultValue);
|
||||
}
|
||||
}
|
||||
@@ -3,8 +3,8 @@ 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.FlowableMetadata;
|
||||
import com.lanyuanxiaoyao.flowable.core.model.FlowableNode;
|
||||
import java.util.Map;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
@@ -18,9 +18,10 @@ public class TwoApproveHandler implements FlowableHandler {
|
||||
private static final String KEY = "approve-times";
|
||||
|
||||
@Override
|
||||
public FlowableAction handle(FlowableAction action, FlowableInstance instance, FlowableNode node, Map<String, Object> metadata) {
|
||||
log.info("{}", metadata);
|
||||
int approveCount = (int) metadata.getOrDefault(KEY, 0);
|
||||
public FlowableAction handle(FlowableInstance instance, FlowableNode node, FlowableAction action) {
|
||||
log.info("{}", instance.getMetadata());
|
||||
FlowableMetadata metadata = instance.getMetadata();
|
||||
int approveCount = metadata.getIntOrDefault(KEY, 0);
|
||||
if (approveCount + 1 > 1) {
|
||||
return FlowableAction.APPROVE;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ 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;
|
||||
|
||||
/**
|
||||
@@ -14,7 +13,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
@Slf4j
|
||||
public class SimpleAutoHandler implements FlowableHandler {
|
||||
@Override
|
||||
public FlowableAction handle(FlowableAction action, FlowableInstance instance, FlowableNode node, Map<String, Object> metadata) {
|
||||
public FlowableAction handle(FlowableInstance instance, FlowableNode node, FlowableAction action) {
|
||||
log.info("Simple handler initial");
|
||||
return FlowableAction.APPROVE;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user