1
0

调整metadata的结构,使用更方便

This commit is contained in:
2025-01-03 15:27:40 +08:00
parent 57bc3fb2a8
commit 45ce5a2615
10 changed files with 134 additions and 37 deletions

View File

@@ -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<>();

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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;
}
}

View File

@@ -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;

View File

@@ -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);
}
}