Skip to content

Commit 2f66143

Browse files
authored
Merge pull request #52 from codingapi/dev
Dev
2 parents 7ee94e9 + fe55d2a commit 2f66143

29 files changed

Lines changed: 960 additions & 167 deletions

.tool-versions

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
default nodejs 22
2+
nodejs 22.22.0
3+
java openjdk-22

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

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import java.util.stream.Stream;
1010

1111
/**
12-
* 流程节点管理器,主要获取流程节点信息
12+
* 流程节点管理器,主要获取流程节点信息
1313
*/
1414
public class FlowNodeManager {
1515

@@ -29,9 +29,9 @@ private IFlowNode fetchNodes(String nodeId, List<IFlowNode> nodes) {
2929
return node;
3030
}
3131
List<IFlowNode> blocks = node.blocks();
32-
if(blocks!=null && !blocks.isEmpty()){
33-
IFlowNode flowNode = this.fetchNodes(nodeId,blocks);
34-
if(flowNode!=null){
32+
if (blocks != null && !blocks.isEmpty()) {
33+
IFlowNode flowNode = this.fetchNodes(nodeId, blocks);
34+
if (flowNode != null) {
3535
return flowNode;
3636
}
3737
}
@@ -74,12 +74,13 @@ public List<IFlowNode> getNextNodes(IFlowNode current) {
7474

7575
/**
7676
* 加载下一节点
77-
* @param current 当前节点状态
78-
* @param iterator 当前遍历的节点列表
77+
*
78+
* @param current 当前节点状态
79+
* @param iterator 当前遍历的节点列表
7980
* @return 下一节点列表
8081
*/
8182
private List<IFlowNode> loadNextNodes(FlowNodeState current, Iterator<FlowNodeState> iterator) {
82-
if(current.isEndNode()){
83+
if (current.isEndNode()) {
8384
return new ArrayList<>();
8485
}
8586
while (iterator.hasNext()) {
@@ -89,7 +90,17 @@ private List<IFlowNode> loadNextNodes(FlowNodeState current, Iterator<FlowNodeSt
8990
return node.getBlocks();
9091
}
9192
if (node.isBranchNode()) {
92-
return node.getFirstBlocks();
93+
List<IFlowNode> nextNodes = node.getFirstBlocks();
94+
if(!nextNodes.isEmpty()){
95+
return nextNodes;
96+
}else {
97+
// 跳过大循环,直接进入下一节点
98+
if (this.nodes.hasNext()) {
99+
return Stream.of(this.nodes.next().getNode()).toList();
100+
} else {
101+
throw FlowStateException.edgeConfigError(current.getName());
102+
}
103+
}
93104
}
94105
if (iterator.hasNext()) {
95106
FlowNodeState next = iterator.next();
@@ -98,19 +109,20 @@ private List<IFlowNode> loadNextNodes(FlowNodeState current, Iterator<FlowNodeSt
98109
// 跳过大循环,直接进入下一节点
99110
if (this.nodes.hasNext()) {
100111
return Stream.of(this.nodes.next().getNode()).toList();
101-
}else {
112+
} else {
102113
throw FlowStateException.edgeConfigError(current.getName());
103114
}
104115
}
105116
}
106117

107118
if (node.isBlockNode() || node.isBranchNode()) {
108-
List<IFlowNode> nextNodes = this.loadNextNodes(current, node.getBlocks().stream().map(FlowNodeState::new).toList().iterator());
109-
if (!nextNodes.isEmpty()) {
110-
return nextNodes;
119+
if (node.getBlocks() != null) {
120+
List<IFlowNode> nextNodes = this.loadNextNodes(current, node.getBlocks().stream().map(FlowNodeState::new).toList().iterator());
121+
if (!nextNodes.isEmpty()) {
122+
return nextNodes;
123+
}
111124
}
112125
}
113-
114126
}
115127
return new ArrayList<>();
116128
}

flow-engine-framework/src/main/java/com/codingapi/flow/pojo/response/ProcessNode.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
import java.util.ArrayList;
1111
import java.util.List;
12+
import java.util.Objects;
1213

1314
/**
1415
* 流程审批节点
@@ -81,6 +82,20 @@ public void setCurrentState() {
8182
}
8283

8384

85+
@Override
86+
public boolean equals(Object target) {
87+
if(target instanceof ProcessNode) {
88+
ProcessNode targetNode = (ProcessNode) target;
89+
return targetNode.getNodeId().equals(this.getNodeId());
90+
}
91+
return super.equals(target);
92+
}
93+
94+
@Override
95+
public int hashCode() {
96+
return Objects.hash(nodeId, nodeName, nodeType, state, operators);
97+
}
98+
8499
/**
85100
* 审批意见内容,仅当历史节点存在数据
86101
*/

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public class TriggerScript {
1414
public static final String SCRIPT_DEFAULT = """
1515
// @SCRIPT_TITLE 示例触发节点(打印触发日志)
1616
def run(request){
17-
print('hello trigger node.');
17+
print('hello trigger node.\\n');
1818
}
1919
""";
2020

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

Lines changed: 62 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import com.codingapi.flow.manager.NodeStrategyManager;
1111
import com.codingapi.flow.manager.OperatorManager;
1212
import com.codingapi.flow.node.IFlowNode;
13+
import com.codingapi.flow.node.NodeType;
1314
import com.codingapi.flow.node.nodes.StartNode;
1415
import com.codingapi.flow.operator.IFlowOperator;
1516
import com.codingapi.flow.pojo.request.FlowProcessNodeRequest;
@@ -21,6 +22,7 @@
2122
import com.codingapi.flow.session.FlowAdvice;
2223
import com.codingapi.flow.session.FlowSession;
2324
import com.codingapi.flow.workflow.Workflow;
25+
import lombok.Getter;
2426

2527
import java.util.ArrayList;
2628
import java.util.List;
@@ -45,6 +47,7 @@ public class FlowProcessNodeService {
4547
// 流程节点记录
4648
private final List<ProcessNode> nodeList;
4749

50+
4851
public FlowProcessNodeService(FlowProcessNodeRequest request) {
4952
this.request = request;
5053
this.currentOperator = RepositoryHolderContext.getInstance().getOperatorById(request.getOperatorId());
@@ -55,6 +58,7 @@ public FlowProcessNodeService(FlowProcessNodeRequest request) {
5558
this.loadWorkflow();
5659
}
5760

61+
5862
private void loadWorkflow() {
5963
String id = this.request.getId();
6064
if (this.request.isCreateWorkflow()) {
@@ -104,30 +108,70 @@ public List<ProcessNode> processNodes() {
104108
FlowAdvice.nullFlowAdvice()
105109
);
106110

107-
this.fetchNextNode(flowSession, List.of(this.currentNode));
111+
NextNodeLoader nextNodeLoader = new NextNodeLoader(this.currentNode);
112+
List<ProcessNode> nextNodes = nextNodeLoader.loadNextNode(flowSession);
108113

109-
// 推理后续
110-
return nodeList;
114+
this.nodeList.addAll(nextNodes);
115+
return this.nodeList;
111116
}
112117

113118

114-
private void fetchNextNode(FlowSession flowSession, List<IFlowNode> nexNodes) {
115-
for (IFlowNode flowNode : nexNodes) {
116-
List<IFlowOperator> operators = null;
117-
if(flowNode.getType().equals(StartNode.NODE_TYPE)){
118-
operators = List.of(flowSession.getCurrentOperator());
119-
}else {
120-
NodeStrategyManager nodeStrategyManager = flowNode.strategyManager();
121-
OperatorManager operatorManager = nodeStrategyManager.loadOperators(flowSession);
122-
operators = operatorManager.getOperators();
119+
private class NextNodeLoader {
120+
121+
@Getter
122+
private final List<ProcessNode> nodeList;
123+
private final IFlowNode currentNode;
124+
private final List<String> displayNodeTypes;
125+
126+
public NextNodeLoader(IFlowNode currentNode) {
127+
this.currentNode = currentNode;
128+
this.nodeList = new ArrayList<>();
129+
this.displayNodeTypes = new ArrayList<>();
130+
this.initDisplayNodeTypes();
131+
}
132+
133+
134+
private void initDisplayNodeTypes() {
135+
this.displayNodeTypes.add(NodeType.START.name());
136+
this.displayNodeTypes.add(NodeType.END.name());
137+
this.displayNodeTypes.add(NodeType.APPROVAL.name());
138+
this.displayNodeTypes.add(NodeType.NOTIFY.name());
139+
this.displayNodeTypes.add(NodeType.HANDLE.name());
140+
this.displayNodeTypes.add(NodeType.TRIGGER.name());
141+
this.displayNodeTypes.add(NodeType.SUB_PROCESS.name());
142+
}
143+
144+
private void fetchNextNode(FlowSession flowSession, List<IFlowNode> nexNodes) {
145+
for (IFlowNode flowNode : nexNodes) {
146+
List<IFlowOperator> operators = null;
147+
if (flowNode.getType().equals(StartNode.NODE_TYPE)) {
148+
operators = List.of(flowSession.getCurrentOperator());
149+
} else {
150+
NodeStrategyManager nodeStrategyManager = flowNode.strategyManager();
151+
OperatorManager operatorManager = nodeStrategyManager.loadOperators(flowSession);
152+
operators = operatorManager.getOperators();
153+
}
154+
ProcessNode processNode = new ProcessNode(flowNode, operators);
155+
if (processNode.isFlowNode(this.currentNode)) {
156+
processNode.setCurrentState();
157+
}
158+
this.nodeList.add(processNode);
159+
List<IFlowNode> nextNodes = workflow.nextNodes(flowNode);
160+
this.fetchNextNode(flowSession.updateSession(flowNode), nextNodes);
123161
}
124-
ProcessNode processNode = new ProcessNode(flowNode,operators);
125-
if(processNode.isFlowNode(this.currentNode)){
126-
processNode.setCurrentState();
162+
}
163+
164+
public List<ProcessNode> loadNextNode(FlowSession flowSession) {
165+
this.fetchNextNode(flowSession,List.of(this.currentNode));
166+
167+
List<ProcessNode> displayNodes = nodeList.stream().filter(node-> this.displayNodeTypes.contains(node.getNodeType())).toList();
168+
List<ProcessNode> processNodeList = new ArrayList<>();
169+
for (ProcessNode node:displayNodes){
170+
if(!processNodeList.contains(node)){
171+
processNodeList.add(node);
172+
}
127173
}
128-
this.nodeList.add(processNode);
129-
List<IFlowNode> nextNodes = workflow.nextNodes(flowNode);
130-
this.fetchNextNode(flowSession.updateSession(flowNode), nextNodes);
174+
return processNodeList;
131175
}
132176
}
133177

frontend/packages/flow-pc/flow-pc-design/package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,12 @@
2323
},
2424
"dependencies": {
2525
"@ant-design/icons": "~6.1.0",
26+
"@codemirror/commands": "^6.10.2",
2627
"@codemirror/lang-java": "^6.0.2",
28+
"@codemirror/language": "^6.12.2",
29+
"@codemirror/state": "^6.5.4",
2730
"@codemirror/theme-one-dark": "^6.1.3",
31+
"@codemirror/view": "^6.39.16",
2832
"@flow-engine/flow-core": "workspace:*",
2933
"@flow-engine/flow-pc-ui": "workspace:*",
3034
"@flow-engine/flow-types": "workspace:*",
@@ -34,6 +38,7 @@
3438
"@flowgram.ai/form-materials": "^1.0.7",
3539
"@flowgram.ai/minimap-plugin": "1.0.7",
3640
"@flowgram.ai/panel-manager-plugin": "^1.0.7",
41+
"@lezer/highlight": "^1.2.3",
3742
"@reduxjs/toolkit": "^2.11.2",
3843
"antd": "^6.2.1",
3944
"dayjs": "^1.11.19",

frontend/packages/flow-pc/flow-pc-design/src/components/design-editor/node-components/condition/index.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {Button, Form, Space} from "antd";
33
import React from "react";
44
import {GroovyScriptPreview} from "@/components/script/components/groovy-script-preview";
55
import {EditOutlined} from "@ant-design/icons";
6+
import {ConditionConfigModal} from "@/components/script/modal/condition-config-modal";
67

78
/**
89
* 条件配置
@@ -11,6 +12,7 @@ import {EditOutlined} from "@ant-design/icons";
1112
export const ConditionScript = ()=>{
1213

1314
const [form] = Form.useForm();
15+
const [visible,setVisible] = React.useState(false);
1416

1517
return (
1618
<Form
@@ -35,11 +37,19 @@ export const ConditionScript = ()=>{
3537
<Button
3638
icon={<EditOutlined/>}
3739
onClick={() => {
40+
setVisible(true);
3841
}}
3942
style={{borderRadius: '0 6px 6px 0'}}
4043
>
4144
编辑
4245
</Button>
46+
47+
<ConditionConfigModal
48+
open={visible}
49+
onCancel={()=>{setVisible(false);}}
50+
onConfirm={(value)=>{onChange(value)}}
51+
script={value}
52+
/>
4353
</Space.Compact>
4454
)}
4555
/>

frontend/packages/flow-pc/flow-pc-design/src/components/design-editor/node-components/strategy/error-trigger.tsx

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import React from "react";
2-
import {Button, Form,Input, Space} from "antd";
3-
import { Field, FieldRenderProps } from "@flowgram.ai/fixed-layout-editor";
2+
import {Button, Form, Space} from "antd";
3+
import {Field, FieldRenderProps} from "@flowgram.ai/fixed-layout-editor";
44
import {GroovyScriptPreview} from "@/components/script/components/groovy-script-preview";
5-
import { EditOutlined } from "@ant-design/icons";
5+
import {EditOutlined} from "@ant-design/icons";
6+
import {ErrorTriggerConfigModal} from "@/components/script/modal/error-trigger-config-modal";
67

78
/**
89
* 错误触发策略配置(没有匹配到人时)
@@ -11,6 +12,7 @@ import { EditOutlined } from "@ant-design/icons";
1112
export const ErrorTriggerStrategy: React.FC = () => {
1213

1314
const [form] = Form.useForm();
15+
const [visible,setVisible] = React.useState(false);
1416

1517
return (
1618
<Form
@@ -36,11 +38,19 @@ export const ErrorTriggerStrategy: React.FC = () => {
3638
<Button
3739
icon={<EditOutlined/>}
3840
onClick={() => {
41+
setVisible(true);
3942
}}
4043
style={{borderRadius: '0 6px 6px 0'}}
4144
>
4245
编辑
4346
</Button>
47+
48+
<ErrorTriggerConfigModal
49+
open={visible}
50+
onCancel={()=>{setVisible(false);}}
51+
onConfirm={(value)=>{onChange(value)}}
52+
script={value}
53+
/>
4454
</Space.Compact>
4555
)}
4656
/>

frontend/packages/flow-pc/flow-pc-design/src/components/design-editor/node-components/strategy/router.tsx

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
import React from "react";
2-
import {Button, Form, Input, Space} from "antd";
2+
import {Button, Form, Space} from "antd";
33
import {Field, FieldRenderProps} from "@flowgram.ai/fixed-layout-editor";
44
import {GroovyScriptPreview} from "@/components/script/components/groovy-script-preview";
5-
import { EditOutlined } from "@ant-design/icons";
5+
import {EditOutlined} from "@ant-design/icons";
6+
import {RouterConfigModal} from "@/components/script/modal/router-config-modal";
67

78
/**
89
* 路由策略配置
910
* @constructor
1011
*/
1112
export const RouterStrategy:React.FC = () => {
1213
const [form] = Form.useForm();
14+
const [visible,setVisible] = React.useState(false);
1315

1416
return (
1517
<Form
@@ -34,11 +36,21 @@ export const RouterStrategy:React.FC = () => {
3436
<Button
3537
icon={<EditOutlined/>}
3638
onClick={() => {
39+
setVisible(true);
3740
}}
3841
style={{borderRadius: '0 6px 6px 0'}}
3942
>
4043
编辑
4144
</Button>
45+
46+
<RouterConfigModal
47+
open={visible}
48+
script={value}
49+
onCancel={()=>{setVisible(false);}}
50+
onConfirm={(value)=>{
51+
onChange(value);
52+
}}
53+
/>
4254
</Space.Compact>
4355
)}
4456
/>

0 commit comments

Comments
 (0)