Skip to content

Commit d158fe1

Browse files
committed
add manual node
1 parent 3562cdd commit d158fe1

13 files changed

Lines changed: 293 additions & 49 deletions

File tree

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/nodes/ManualBranchNode.java

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ public String getType() {
2828
return NODE_TYPE;
2929
}
3030

31-
3231
public ManualBranchNode(String id, String name, int order) {
3332
super(id, name, order);
3433
}
@@ -46,34 +45,10 @@ public boolean handle(FlowSession request) {
4645
}
4746

4847

49-
5048
public static ManualBranchNode formMap(Map<String, Object> map) {
5149
return BaseFlowNode.fromMap(map, ManualBranchNode.class);
5250
}
5351

54-
/**
55-
* 匹配条件分支
56-
*
57-
* @param nodeList 当前节点下的所有条件
58-
* @param flowSession 当前会话
59-
* @return 匹配的节点
60-
*/
61-
public List<IFlowNode> filterBranches(List<IFlowNode> nodeList, FlowSession flowSession) {
62-
Workflow workflow = flowSession.getWorkflow();
63-
IFlowNode currentNode = flowSession.getCurrentNode();
64-
ParallelNodeRelationHelper helper = new ParallelNodeRelationHelper(workflow,currentNode,nodeList);
65-
// 分析并行分支的结束汇聚节点
66-
IFlowNode overNode = helper.fetchMargeNode();
67-
if (overNode == null) {
68-
throw FlowNotFoundException.parallelEndNodeNotNull();
69-
}
70-
71-
// 在流程记录中记录,合并的条件信息。
72-
FlowRecord flowRecord = flowSession.getCurrentRecord();
73-
flowRecord.parallelBranchNode(overNode.getId(), nodeList.size(), RandomUtils.generateStringId());
74-
75-
return nodeList;
76-
}
7752

7853
public static Builder builder() {
7954
return new Builder();

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

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import com.codingapi.flow.node.IBlockNode;
66
import com.codingapi.flow.node.IFlowNode;
77
import com.codingapi.flow.node.NodeType;
8+
import com.codingapi.flow.session.FlowSession;
89
import com.codingapi.flow.utils.RandomUtils;
910

1011
import java.util.ArrayList;
@@ -34,13 +35,30 @@ public ManualNode() {
3435
this(RandomUtils.generateStringId(), DEFAULT_NAME, 0);
3536
}
3637

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+
}
3755

3856
@Override
39-
public void addDefaultBranch(int count){
57+
public void addDefaultBranch(int count) {
4058
List<IFlowNode> branches = new ArrayList<>();
41-
for (int i=0;i<count;i++){
59+
for (int i = 0; i < count; i++) {
4260
ManualBranchNode branchNode = new ManualBranchNode();
43-
branchNode.setOrder(i+1);
61+
branchNode.setOrder(i + 1);
4462
branches.add(branchNode);
4563
}
4664
this.setBlocks(branches);

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

flow-engine-framework/src/main/java/com/codingapi/flow/pojo/request/FlowActionRequest.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ public FlowAdvice toFlowAdvice(Workflow workflow, IFlowAction flowAction) {
5050
flowAdvice.setBackNode(workflow.getFlowNode(advice.getBackNodeId()));
5151
}
5252

53+
if (StringUtils.hasText(advice.getManualNodeId())) {
54+
flowAdvice.setManualNode(workflow.getFlowNode(advice.getManualNodeId()));
55+
}
56+
5357
return flowAdvice;
5458
}
5559

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.codingapi.flow.pojo.response;
2+
3+
import lombok.Getter;
4+
5+
import java.util.List;
6+
7+
@Getter
8+
public class ActionResponse {
9+
10+
/**
11+
* 可选节点
12+
*/
13+
private final List<NodeOption> options;
14+
15+
public ActionResponse(List<NodeOption> options) {
16+
this.options = options;
17+
}
18+
}

flow-engine-framework/src/main/java/com/codingapi/flow/service/FlowService.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.codingapi.flow.service;
22

33
import com.codingapi.flow.pojo.request.*;
4+
import com.codingapi.flow.pojo.response.ActionResponse;
45
import com.codingapi.flow.pojo.response.FlowContent;
56
import com.codingapi.flow.pojo.response.ProcessNode;
67
import com.codingapi.flow.service.impl.*;
@@ -60,9 +61,9 @@ public long create(FlowCreateRequest request) {
6061
*
6162
* @param request 审批请求
6263
*/
63-
public void action(FlowActionRequest request) {
64+
public ActionResponse action(FlowActionRequest request) {
6465
FlowActionService flowActionService = new FlowActionService(request,this.repositoryHolder);
65-
flowActionService.action();
66+
return flowActionService.action();
6667
}
6768

6869
/**

flow-engine-framework/src/main/java/com/codingapi/flow/service/impl/FlowActionService.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.codingapi.flow.service.impl;
22

33
import com.codingapi.flow.action.IFlowAction;
4+
import com.codingapi.flow.context.ActionResponseContext;
45
import com.codingapi.flow.exception.FlowNotFoundException;
56
import com.codingapi.flow.exception.FlowStateException;
67
import com.codingapi.flow.form.FormData;
@@ -9,6 +10,7 @@
910
import com.codingapi.flow.node.IFlowNode;
1011
import com.codingapi.flow.operator.IFlowOperator;
1112
import com.codingapi.flow.pojo.request.FlowActionRequest;
13+
import com.codingapi.flow.pojo.response.ActionResponse;
1214
import com.codingapi.flow.record.FlowRecord;
1315
import com.codingapi.flow.service.FlowRecordService;
1416
import com.codingapi.flow.service.WorkflowService;
@@ -38,8 +40,9 @@ public FlowActionService(FlowActionRequest request,IRepositoryHolder repositoryH
3840
this.repositoryHolder = repositoryHolder;
3941
}
4042

41-
public void action() {
43+
public ActionResponse action() {
4244

45+
ActionResponseContext.getInstance().clear();
4346
request.verify();
4447
// 验证当前用户
4548
IFlowOperator currentOperator = flowOperatorGateway.get(request.getAdvice().getOperatorId());
@@ -88,6 +91,7 @@ public void action() {
8891
// 执行动作
8992
flowAction.run(session);
9093

94+
return ActionResponseContext.getInstance().get();
9195
}
9296
}
9397

0 commit comments

Comments
 (0)