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

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

View File

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

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

View File

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

View File

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