Skip to content

Commit de05928

Browse files
authored
Merge pull request #109 from codingapi/dev
Dev
2 parents 0afe169 + c4e6ee2 commit de05928

File tree

23 files changed

+433
-30
lines changed

23 files changed

+433
-30
lines changed

flow-engine-example/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<parent>
77
<groupId>com.codingapi.flow</groupId>
88
<artifactId>flow-engine-parent</artifactId>
9-
<version>0.0.9</version>
9+
<version>0.0.10</version>
1010
<relativePath>../pom.xml</relativePath>
1111
</parent>
1212

flow-engine-framework/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<parent>
77
<groupId>com.codingapi.flow</groupId>
88
<artifactId>flow-engine-parent</artifactId>
9-
<version>0.0.9</version>
9+
<version>0.0.10</version>
1010
</parent>
1111

1212
<name>flow-engine-framework</name>

flow-engine-framework/src/main/java/com/codingapi/flow/action/actions/PassAction.java

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,16 @@
33
import com.codingapi.flow.action.ActionDisplay;
44
import com.codingapi.flow.action.ActionType;
55
import com.codingapi.flow.action.BaseAction;
6+
import com.codingapi.flow.context.ActionResponseContext;
67
import com.codingapi.flow.event.FlowRecordDoneEvent;
78
import com.codingapi.flow.event.FlowRecordTodoEvent;
89
import com.codingapi.flow.event.IFlowEvent;
910
import com.codingapi.flow.manager.NodeStrategyManager;
1011
import com.codingapi.flow.node.BaseAuditNode;
1112
import com.codingapi.flow.node.IFlowNode;
13+
import com.codingapi.flow.node.nodes.ManualNode;
1214
import com.codingapi.flow.operator.IFlowOperator;
15+
import com.codingapi.flow.pojo.response.NodeOption;
1316
import com.codingapi.flow.record.FlowRecord;
1417
import com.codingapi.flow.session.FlowSession;
1518
import com.codingapi.flow.session.IRepositoryHolder;
@@ -71,10 +74,25 @@ public void run(FlowSession flowSession) {
7174
List<FlowRecord> recordList = new ArrayList<>();
7275
FlowRecord currentRecord = flowSession.getCurrentRecord();
7376
IFlowNode currentNode = flowSession.getCurrentNode();
77+
78+
// 如果下节点为手动节点时,提交流程时需要先选择节点
79+
List<IFlowNode> nextNodes = flowSession.matchNextNodes();
80+
if (nextNodes != null && nextNodes.size() == 1) {
81+
IFlowNode nextNode = nextNodes.get(0);
82+
if (nextNode.getType().equalsIgnoreCase(ManualNode.NODE_TYPE)) {
83+
IFlowNode manulNode = flowSession.getAdvice().getManualNode();
84+
if (manulNode == null && nextNode.blocks() != null) {
85+
List<NodeOption> options = nextNode.blocks().stream().map(NodeOption::new).toList();
86+
ActionResponseContext.getInstance().set(options);
87+
return;
88+
}
89+
}
90+
}
91+
7492
boolean isFinish = currentNode.isFinish(flowSession);
7593
currentRecord.update(flowSession, true);
7694
// 添加流程结束事件
77-
flowEvents.add(new FlowRecordDoneEvent(currentRecord,flowSession.isMock()));
95+
flowEvents.add(new FlowRecordDoneEvent(currentRecord, flowSession.isMock()));
7896
recordList.add(currentRecord);
7997

8098
// 激活下一个按顺序审批的记录数据
@@ -85,7 +103,7 @@ public void run(FlowSession flowSession) {
85103
if (record.getNodeOrder() == currentRecord.getNodeOrder() + 1) {
86104
record.show();
87105
recordList.add(record);
88-
flowEvents.add(new FlowRecordTodoEvent(record,flowSession.isMock()));
106+
flowEvents.add(new FlowRecordTodoEvent(record, flowSession.isMock()));
89107
}
90108
}
91109
}
@@ -98,7 +116,7 @@ public void run(FlowSession flowSession) {
98116
notifyRecord.notifyRecord(flowSession.updateSession(forwardOperator));
99117
// 如果不存储这个记录,若下一流程是结束流程时,无法更新流程状态为结束状态。
100118
repositoryHolder.saveRecord(notifyRecord);
101-
flowEvents.add(new FlowRecordDoneEvent(notifyRecord,flowSession.isMock()));
119+
flowEvents.add(new FlowRecordDoneEvent(notifyRecord, flowSession.isMock()));
102120
}
103121

104122
// 是否委托记录
@@ -109,17 +127,17 @@ public void run(FlowSession flowSession) {
109127
rebackRecord.clearDelegate();
110128

111129
recordList.add(rebackRecord);
112-
flowEvents.add(new FlowRecordTodoEvent(rebackRecord,flowSession.isMock()));
130+
flowEvents.add(new FlowRecordTodoEvent(rebackRecord, flowSession.isMock()));
113131
} else {
114132
this.triggerNode(flowSession, (triggerSession) -> {
115133
List<FlowRecord> records = this.generateRecords(triggerSession);
116134
if (!records.isEmpty()) {
117135
for (FlowRecord record : records) {
118136
if (record.isShow()) {
119137
if (record.isNotify()) {
120-
flowEvents.add(new FlowRecordDoneEvent(record,flowSession.isMock()));
138+
flowEvents.add(new FlowRecordDoneEvent(record, flowSession.isMock()));
121139
} else {
122-
flowEvents.add(new FlowRecordTodoEvent(record,flowSession.isMock()));
140+
flowEvents.add(new FlowRecordTodoEvent(record, flowSession.isMock()));
123141
}
124142
}
125143
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package com.codingapi.flow.context;
2+
3+
import com.codingapi.flow.pojo.response.ActionResponse;
4+
import com.codingapi.flow.pojo.response.NodeOption;
5+
import lombok.Getter;
6+
7+
import java.util.List;
8+
9+
public class ActionResponseContext {
10+
11+
@Getter
12+
private final static ActionResponseContext instance = new ActionResponseContext();
13+
14+
private final ThreadLocal<ActionResponse> threadLocal;
15+
16+
17+
private ActionResponseContext() {
18+
this.threadLocal = new InheritableThreadLocal<>();
19+
}
20+
21+
22+
public void clear() {
23+
this.threadLocal.remove();
24+
}
25+
26+
public void set(List<NodeOption> options) {
27+
this.threadLocal.set(new ActionResponse(options));
28+
}
29+
30+
public ActionResponse get() {
31+
return threadLocal.get();
32+
}
33+
34+
35+
}

flow-engine-framework/src/main/java/com/codingapi/flow/manager/FlowNodeState.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,12 @@ public FlowNodeState(IFlowNode node) {
2626
this.blockNodeTypes.add(NodeType.CONDITION.name());
2727
this.blockNodeTypes.add(NodeType.INCLUSIVE.name());
2828
this.blockNodeTypes.add(NodeType.PARALLEL.name());
29+
this.blockNodeTypes.add(NodeType.MANUAL.name());
2930

3031
this.branchNodeTypes.add(NodeType.CONDITION_BRANCH.name());
3132
this.branchNodeTypes.add(NodeType.INCLUSIVE_BRANCH.name());
3233
this.branchNodeTypes.add(NodeType.PARALLEL_BRANCH.name());
34+
this.branchNodeTypes.add(NodeType.MANUAL_BRANCH.name());
3335
}
3436

3537
public boolean isEndNode() {

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ public enum NodeType {
2020
INCLUSIVE,
2121
// 包容分支
2222
INCLUSIVE_BRANCH,
23+
// 人工控制
24+
MANUAL,
25+
// 人工分支
26+
MANUAL_BRANCH,
2327
// 抄送
2428
NOTIFY,
2529
// 并行控制

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ private void initNodes() {
3030
nodesClasses.put(HandleNode.NODE_TYPE, HandleNode.class);
3131
nodesClasses.put(InclusiveNode.NODE_TYPE, InclusiveNode.class);
3232
nodesClasses.put(InclusiveBranchNode.NODE_TYPE, InclusiveBranchNode.class);
33+
nodesClasses.put(ManualNode.NODE_TYPE, ManualNode.class);
34+
nodesClasses.put(ManualBranchNode.NODE_TYPE, ManualBranchNode.class);
3335
nodesClasses.put(NotifyNode.NODE_TYPE, NotifyNode.class);
3436
nodesClasses.put(RouterNode.NODE_TYPE, RouterNode.class);
3537
nodesClasses.put(ParallelNode.NODE_TYPE, ParallelNode.class);
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package com.codingapi.flow.node.nodes;
2+
3+
import com.codingapi.flow.builder.BaseNodeBuilder;
4+
import com.codingapi.flow.exception.FlowNotFoundException;
5+
import com.codingapi.flow.node.BaseFlowNode;
6+
import com.codingapi.flow.node.IFlowNode;
7+
import com.codingapi.flow.node.NodeType;
8+
import com.codingapi.flow.node.helper.ParallelNodeRelationHelper;
9+
import com.codingapi.flow.record.FlowRecord;
10+
import com.codingapi.flow.session.FlowSession;
11+
import com.codingapi.flow.utils.RandomUtils;
12+
import com.codingapi.flow.workflow.Workflow;
13+
14+
import java.util.List;
15+
import java.util.Map;
16+
17+
/**
18+
* 人工分支节点
19+
*/
20+
public class ManualBranchNode extends BaseFlowNode {
21+
22+
public static final String NODE_TYPE = NodeType.MANUAL_BRANCH.name();
23+
public static final String DEFAULT_NAME = "人工分支节点";
24+
25+
26+
@Override
27+
public String getType() {
28+
return NODE_TYPE;
29+
}
30+
31+
public ManualBranchNode(String id, String name, int order) {
32+
super(id, name, order);
33+
}
34+
35+
public ManualBranchNode() {
36+
this(RandomUtils.generateStringId(), DEFAULT_NAME, 0);
37+
}
38+
39+
/**
40+
* 匹配条件
41+
*/
42+
@Override
43+
public boolean handle(FlowSession request) {
44+
return true;
45+
}
46+
47+
48+
public static ManualBranchNode formMap(Map<String, Object> map) {
49+
return BaseFlowNode.fromMap(map, ManualBranchNode.class);
50+
}
51+
52+
53+
public static Builder builder() {
54+
return new Builder();
55+
}
56+
57+
public static class Builder extends BaseNodeBuilder<Builder, ManualBranchNode> {
58+
59+
public Builder() {
60+
super(new ManualBranchNode());
61+
}
62+
}
63+
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
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.IBlockNode;
6+
import com.codingapi.flow.node.IFlowNode;
7+
import com.codingapi.flow.node.NodeType;
8+
import com.codingapi.flow.session.FlowSession;
9+
import com.codingapi.flow.utils.RandomUtils;
10+
11+
import java.util.ArrayList;
12+
import java.util.List;
13+
import java.util.Map;
14+
15+
/**
16+
* 人工控制节点
17+
*/
18+
public class ManualNode extends BaseFlowNode implements IBlockNode {
19+
20+
public static final String NODE_TYPE = NodeType.MANUAL.name();
21+
public static final String DEFAULT_NAME = "人工控制节点";
22+
23+
24+
@Override
25+
public String getType() {
26+
return NODE_TYPE;
27+
}
28+
29+
30+
public ManualNode(String id, String name, int order) {
31+
super(id, name, order);
32+
}
33+
34+
public ManualNode() {
35+
this(RandomUtils.generateStringId(), DEFAULT_NAME, 0);
36+
}
37+
38+
/**
39+
* 匹配条件分支
40+
*
41+
* @param nodeList 当前节点下的所有条件
42+
* @param flowSession 当前会话
43+
* @return 匹配的节点
44+
*/
45+
public List<IFlowNode> filterBranches(List<IFlowNode> nodeList, FlowSession flowSession) {
46+
IFlowNode selectNode = flowSession.getAdvice().getManualNode();
47+
if (selectNode == null) {
48+
return nodeList;
49+
} else {
50+
List<IFlowNode> nextNodes = new ArrayList<>();
51+
nextNodes.add(selectNode);
52+
return nextNodes;
53+
}
54+
}
55+
56+
@Override
57+
public void addDefaultBranch(int count) {
58+
List<IFlowNode> branches = new ArrayList<>();
59+
for (int i = 0; i < count; i++) {
60+
ManualBranchNode branchNode = new ManualBranchNode();
61+
branchNode.setOrder(i + 1);
62+
branches.add(branchNode);
63+
}
64+
this.setBlocks(branches);
65+
}
66+
67+
68+
public static ManualNode formMap(Map<String, Object> map) {
69+
return BaseFlowNode.fromMap(map, ManualNode.class);
70+
}
71+
72+
73+
public static Builder builder() {
74+
return new Builder();
75+
}
76+
77+
public static class Builder extends BaseNodeBuilder<Builder, ManualNode> {
78+
79+
public Builder() {
80+
super(new ManualNode());
81+
}
82+
}
83+
}

flow-engine-framework/src/main/java/com/codingapi/flow/pojo/body/FlowAdviceBody.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import java.util.List;
1010

1111
/**
12-
* 流程审批意见
12+
* 流程审批意见
1313
*/
1414
@Data
1515
@NoArgsConstructor
@@ -24,6 +24,11 @@ public class FlowAdviceBody {
2424
*/
2525
private String advice;
2626

27+
/**
28+
* 人工选择节点
29+
*/
30+
private String manualNodeId;
31+
2732
/**
2833
* 签名key
2934
*/
@@ -57,6 +62,7 @@ public FlowAdviceBody(FlowSession flowSession) {
5762
this.operatorId = flowSession.getCurrentOperator().getUserId();
5863
this.signKey = flowSession.getAdvice().getSignKey();
5964
this.backNodeId = flowSession.getAdvice().getBackNode() != null ? flowSession.getAdvice().getBackNode().getId() : null;
65+
this.manualNodeId = flowSession.getAdvice().getManualNode() != null ? flowSession.getAdvice().getManualNode().getId() : null;
6066
this.forwardOperatorIds = flowSession.getAdvice().getForwardOperators() != null ? flowSession.getAdvice().getForwardOperators().stream().map(IFlowOperator::getUserId).toList() : null;
6167
}
6268

0 commit comments

Comments
 (0)