Skip to content

Commit 772fb94

Browse files
committed
add todo
1 parent db2dd1c commit 772fb94

15 files changed

Lines changed: 332 additions & 194 deletions

File tree

flow-engine-framework/src/main/java/com/codingapi/flow/builder/BaseNodeBuilder.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@
22

33
import com.codingapi.flow.action.IFlowAction;
44
import com.codingapi.flow.node.BaseFlowNode;
5+
import com.codingapi.flow.node.IFlowNode;
56
import com.codingapi.flow.strategy.node.INodeStrategy;
67

8+
import java.util.ArrayList;
9+
import java.util.Arrays;
710
import java.util.List;
811

912
public abstract class BaseNodeBuilder<B extends BaseNodeBuilder<B, N>, N extends BaseFlowNode> {
@@ -29,6 +32,17 @@ public B name(String name) {
2932
return (B) this;
3033
}
3134

35+
public B blocks(IFlowNode... nodes) {
36+
List<IFlowNode> nodeList = new ArrayList<>(Arrays.asList(nodes));
37+
node.setBlocks(nodeList);
38+
return (B) this;
39+
}
40+
41+
public B blocks(List<IFlowNode> nodes) {
42+
node.setBlocks(nodes);
43+
return (B) this;
44+
}
45+
3246
public B strategies(List<INodeStrategy> nodeStrategies) {
3347
node.setStrategies(nodeStrategies);
3448
return (B) this;

flow-engine-framework/src/main/java/com/codingapi/flow/builder/NodeMapBuilder.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import com.codingapi.flow.action.IFlowAction;
44
import com.codingapi.flow.action.factory.FlowActionFactory;
55
import com.codingapi.flow.form.permission.FormFieldPermission;
6+
import com.codingapi.flow.node.IFlowNode;
7+
import com.codingapi.flow.node.factory.NodeFactory;
68
import com.codingapi.flow.strategy.node.INodeStrategy;
79
import com.codingapi.flow.strategy.node.NodeStrategyFactory;
810

@@ -55,4 +57,19 @@ public static List<INodeStrategy> loadNodeStrategies(Map<String, Object> data) {
5557
}
5658

5759

60+
@SuppressWarnings("unchecked")
61+
public static List<IFlowNode> loadNodes(Map<String, Object> data){
62+
List<Map<String, Object>> nodes = (List<Map<String, Object>>) data.get("blocks");
63+
if (nodes != null) {
64+
List<IFlowNode> nodeList = new ArrayList<>();
65+
for (Map<String, Object> node : nodes) {
66+
IFlowNode flowNode = NodeFactory.getInstance().createNode(node);
67+
nodeList.add(flowNode);
68+
}
69+
return nodeList;
70+
}
71+
return null;
72+
}
73+
74+
5875
}

flow-engine-framework/src/main/java/com/codingapi/flow/edge/FlowEdge.java

Lines changed: 0 additions & 14 deletions
This file was deleted.
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
package com.codingapi.flow.manager;
2+
3+
import com.codingapi.flow.node.IFlowNode;
4+
import com.codingapi.flow.node.NodeType;
5+
6+
import java.util.ArrayList;
7+
import java.util.List;
8+
9+
/**
10+
* TODO 节点关系管理,寻找下一节点的路径上存在bug
11+
*/
12+
public class FlowNodeEdgeManager {
13+
14+
private final List<IFlowNode> nodes;
15+
16+
private final List<String> blockNodeTypes = new ArrayList<>();
17+
private final List<String> branchNodeTypes = new ArrayList<>();
18+
19+
public FlowNodeEdgeManager(List<IFlowNode> nodes) {
20+
this.nodes = nodes;
21+
22+
this.blockNodeTypes.add(NodeType.CONDITION.name());
23+
this.blockNodeTypes.add(NodeType.INCLUSIVE.name());
24+
this.blockNodeTypes.add(NodeType.PARALLEL.name());
25+
26+
this.branchNodeTypes.add(NodeType.CONDITION_BRANCH.name());
27+
this.branchNodeTypes.add(NodeType.INCLUSIVE_BRANCH.name());
28+
this.branchNodeTypes.add(NodeType.PARALLEL_BRANCH.name());
29+
}
30+
31+
public List<IFlowNode> getNextNodes(IFlowNode current) {
32+
return this.loadNextNodes(current);
33+
}
34+
35+
private List<IFlowNode> loadNextNodes(IFlowNode current) {
36+
if (isBlockNode(current)) {
37+
return current.blocks();
38+
}
39+
if (isBranchNode(current)) {
40+
List<IFlowNode> branchNodes = current.blocks();
41+
if (branchNodes != null && !branchNodes.isEmpty()) {
42+
return List.of(branchNodes.get(0));
43+
}
44+
}
45+
return this.fetchNextNode(current, this.nodes);
46+
}
47+
48+
49+
private boolean isBlockNode(IFlowNode node) {
50+
return blockNodeTypes.contains(node.getType());
51+
}
52+
53+
private boolean isBranchNode(IFlowNode node) {
54+
return branchNodeTypes.contains(node.getType());
55+
}
56+
57+
58+
private List<IFlowNode> fetchNextNode(IFlowNode current, List<IFlowNode> nodes) {
59+
List<IFlowNode> nextNodes = new ArrayList<>();
60+
boolean match = false;
61+
62+
for (int i = 0; i < nodes.size(); i++) {
63+
IFlowNode node = nodes.get(i);
64+
if (match) {
65+
nextNodes.add(node);
66+
break;
67+
}
68+
if (current.getId().equals(node.getId())) {
69+
match = true;
70+
}
71+
if (this.isBlockNode(node) || this.isBranchNode(node)) {
72+
List<IFlowNode> matchNodes = this.fetchNextNode(current, node.blocks());
73+
if (!matchNodes.isEmpty()) {
74+
nextNodes.addAll(matchNodes);
75+
} else {
76+
if (this.hasNodeBlocks(node, current)) {
77+
nextNodes.add(nodes.get(i + 1));
78+
break;
79+
}
80+
}
81+
}
82+
}
83+
return nextNodes;
84+
}
85+
86+
87+
private boolean hasNodeBlocks(IFlowNode node, IFlowNode current) {
88+
List<IFlowNode> blocks = node.blocks();
89+
return blocks != null && !blocks.isEmpty() && hasNodeBlocks(current, blocks);
90+
}
91+
92+
93+
private boolean hasNodeBlocks(IFlowNode current, List<IFlowNode> nodes) {
94+
for (IFlowNode node : nodes) {
95+
if (node.getId().equals(current.getId())) {
96+
return true;
97+
}
98+
if (this.isBlockNode(node) || this.isBranchNode(node)) {
99+
if (hasNodeBlocks(current, node.blocks())) {
100+
return true;
101+
}
102+
}
103+
}
104+
return false;
105+
}
106+
107+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package com.codingapi.flow.manager;
2+
3+
import com.codingapi.flow.node.IFlowNode;
4+
5+
import java.util.List;
6+
7+
public class FlowNodeManager {
8+
9+
private final List<IFlowNode> nodes;
10+
11+
12+
public FlowNodeManager(List<IFlowNode> nodes) {
13+
this.nodes = nodes;
14+
}
15+
16+
public IFlowNode getFlowNode(String nodeId) {
17+
return this.loadFlowNode(nodeId, this.nodes);
18+
}
19+
20+
21+
private IFlowNode loadFlowNode(String nodeId,List<IFlowNode> nodes) {
22+
for (IFlowNode node : nodes) {
23+
if (node.getId().equals(nodeId)) {
24+
return node;
25+
}
26+
List<IFlowNode> blocks = node.blocks();
27+
if(blocks!=null && !blocks.isEmpty()){
28+
IFlowNode flowNode = loadFlowNode(nodeId,blocks);
29+
if(flowNode!=null){
30+
return flowNode;
31+
}
32+
}
33+
}
34+
return null;
35+
}
36+
}

flow-engine-framework/src/main/java/com/codingapi/flow/node/BaseFlowNode.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,14 @@ public abstract class BaseFlowNode implements IFlowNode {
6060
protected List<INodeStrategy> strategies;
6161

6262

63+
/**
64+
* 节点块
65+
*/
66+
@Getter
67+
@Setter
68+
protected List<IFlowNode> blocks;
69+
70+
6371
/**
6472
* 节点策略
6573
*
@@ -139,6 +147,9 @@ public Map<String, Object> toMap() {
139147
map.put("name", name);
140148
map.put("type", getType());
141149
map.put("order", String.valueOf(order));
150+
if(this.blocks!=null && !this.blocks.isEmpty()) {
151+
map.put("blocks", blocks.stream().map(IFlowNode::toMap).toList());
152+
}
142153
map.put("actions", actions.stream().map(IFlowAction::toMap).toList());
143154
map.put("strategies", strategies.stream().map(INodeStrategy::toMap).toList());
144155
return map;
@@ -153,6 +164,7 @@ public static <T extends BaseFlowNode> T fromMap(Map<String, Object> map, Class<
153164
if(map.get("order")!=null) {
154165
node.setOrder(Integer.parseInt((String) map.get("order")));
155166
}
167+
node.setBlocks(NodeMapBuilder.loadNodes(map));
156168
node.setActions(NodeMapBuilder.loadActions(map));
157169
node.setStrategies(NodeMapBuilder.loadNodeStrategies(map));
158170
return node;
@@ -228,6 +240,11 @@ public void fillNewRecord(FlowSession session, FlowRecord flowRecord) {
228240

229241
}
230242

243+
@Override
244+
public List<IFlowNode> blocks() {
245+
return this.blocks;
246+
}
247+
231248
@Override
232249
public List<IFlowNode> filterBranches(List<IFlowNode> nodeList, FlowSession flowSession) {
233250
return nodeList;

flow-engine-framework/src/main/java/com/codingapi/flow/node/IFlowNode.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,12 @@ public interface IFlowNode extends IMapConvertor {
105105
void fillNewRecord(FlowSession session, FlowRecord flowRecord);
106106

107107

108+
/**
109+
* 获取当前节点下blocks数据,废弃edge的设计
110+
*/
111+
List<IFlowNode> blocks();
112+
113+
108114
/**
109115
* 过滤条件分支
110116
*

flow-engine-framework/src/main/java/com/codingapi/flow/node/factory/NodeFactory.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ private NodeFactory() {
2323

2424
private void initNodes() {
2525
nodesClasses.put(ApprovalNode.NODE_TYPE, ApprovalNode.class);
26+
nodesClasses.put(ConditionNode.NODE_TYPE, ConditionNode.class);
2627
nodesClasses.put(ConditionBranchNode.NODE_TYPE, ConditionBranchNode.class);
2728
nodesClasses.put(DelayNode.NODE_TYPE, DelayNode.class);
2829
nodesClasses.put(EndNode.NODE_TYPE, EndNode.class);

flow-engine-framework/src/main/java/com/codingapi/flow/node/nodes/ConditionBranchNode.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@
1515
import java.util.Map;
1616

1717
/**
18-
* 分支节点
18+
* 条件分支节点
1919
*/
2020
public class ConditionBranchNode extends BaseFlowNode {
2121

2222
public static final String NODE_TYPE = NodeType.CONDITION_BRANCH.name();
23-
public static final String DEFAULT_NAME = "条件节点节点";
23+
public static final String DEFAULT_NAME = "条件分支节点";
2424

2525
/**
2626
* 条件脚本
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package com.codingapi.flow.node.nodes;
2+
3+
import com.codingapi.flow.builder.BaseNodeBuilder;
4+
import com.codingapi.flow.node.BaseFlowNode;
5+
import com.codingapi.flow.node.IFlowNode;
6+
import com.codingapi.flow.node.NodeType;
7+
import com.codingapi.flow.session.FlowSession;
8+
import com.codingapi.flow.utils.RandomUtils;
9+
10+
import java.util.ArrayList;
11+
import java.util.Comparator;
12+
import java.util.List;
13+
import java.util.Map;
14+
15+
/**
16+
* 条件控制节点
17+
*/
18+
public class ConditionNode extends BaseFlowNode {
19+
20+
public static final String NODE_TYPE = NodeType.CONDITION.name();
21+
public static final String DEFAULT_NAME = "条件控制节点";
22+
23+
@Override
24+
public String getType() {
25+
return NODE_TYPE;
26+
}
27+
28+
public ConditionNode(String id, String name, int order) {
29+
super(id, name, order);
30+
}
31+
32+
public ConditionNode() {
33+
this(RandomUtils.generateStringId(), DEFAULT_NAME, 0);
34+
}
35+
36+
/**
37+
* 匹配条件
38+
*/
39+
@Override
40+
public boolean handle(FlowSession request) {
41+
return true;
42+
}
43+
44+
@Override
45+
public List<IFlowNode> filterBranches(List<IFlowNode> nodeList, FlowSession flowSession) {
46+
List<IFlowNode> nodes = new ArrayList<>();
47+
for (IFlowNode node : nodeList) {
48+
if (node.handle(flowSession)) {
49+
nodes.add(node);
50+
}
51+
}
52+
// 获取最小order的节点
53+
nodes.sort(Comparator.comparingInt(IFlowNode::getOrder));
54+
if (!nodes.isEmpty()) {
55+
return nodes.subList(0, 1);
56+
}
57+
return nodes;
58+
}
59+
60+
61+
public static ConditionNode formMap(Map<String, Object> map) {
62+
return BaseFlowNode.fromMap(map, ConditionNode.class);
63+
}
64+
65+
public static Builder builder() {
66+
return new Builder();
67+
}
68+
69+
public static class Builder extends BaseNodeBuilder<Builder, ConditionNode> {
70+
71+
public Builder() {
72+
super(new ConditionNode());
73+
}
74+
75+
}
76+
}

0 commit comments

Comments
 (0)