Skip to content
Merged

Dev #52

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .tool-versions
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
default nodejs 22
nodejs 22.22.0
java openjdk-22
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import java.util.stream.Stream;

/**
* 流程节点管理器,主要获取流程节点信息
* 流程节点管理器,主要获取流程节点信息
*/
public class FlowNodeManager {

Expand All @@ -29,9 +29,9 @@ private IFlowNode fetchNodes(String nodeId, List<IFlowNode> nodes) {
return node;
}
List<IFlowNode> blocks = node.blocks();
if(blocks!=null && !blocks.isEmpty()){
IFlowNode flowNode = this.fetchNodes(nodeId,blocks);
if(flowNode!=null){
if (blocks != null && !blocks.isEmpty()) {
IFlowNode flowNode = this.fetchNodes(nodeId, blocks);
if (flowNode != null) {
return flowNode;
}
}
Expand Down Expand Up @@ -74,12 +74,13 @@ public List<IFlowNode> getNextNodes(IFlowNode current) {

/**
* 加载下一节点
* @param current 当前节点状态
* @param iterator 当前遍历的节点列表
*
* @param current 当前节点状态
* @param iterator 当前遍历的节点列表
* @return 下一节点列表
*/
private List<IFlowNode> loadNextNodes(FlowNodeState current, Iterator<FlowNodeState> iterator) {
if(current.isEndNode()){
if (current.isEndNode()) {
return new ArrayList<>();
}
while (iterator.hasNext()) {
Expand All @@ -89,7 +90,17 @@ private List<IFlowNode> loadNextNodes(FlowNodeState current, Iterator<FlowNodeSt
return node.getBlocks();
}
if (node.isBranchNode()) {
return node.getFirstBlocks();
List<IFlowNode> nextNodes = node.getFirstBlocks();
if(!nextNodes.isEmpty()){
return nextNodes;
}else {
// 跳过大循环,直接进入下一节点
if (this.nodes.hasNext()) {
return Stream.of(this.nodes.next().getNode()).toList();
} else {
throw FlowStateException.edgeConfigError(current.getName());
}
}
}
if (iterator.hasNext()) {
FlowNodeState next = iterator.next();
Expand All @@ -98,19 +109,20 @@ private List<IFlowNode> loadNextNodes(FlowNodeState current, Iterator<FlowNodeSt
// 跳过大循环,直接进入下一节点
if (this.nodes.hasNext()) {
return Stream.of(this.nodes.next().getNode()).toList();
}else {
} else {
throw FlowStateException.edgeConfigError(current.getName());
}
}
}

if (node.isBlockNode() || node.isBranchNode()) {
List<IFlowNode> nextNodes = this.loadNextNodes(current, node.getBlocks().stream().map(FlowNodeState::new).toList().iterator());
if (!nextNodes.isEmpty()) {
return nextNodes;
if (node.getBlocks() != null) {
List<IFlowNode> nextNodes = this.loadNextNodes(current, node.getBlocks().stream().map(FlowNodeState::new).toList().iterator());
if (!nextNodes.isEmpty()) {
return nextNodes;
}
}
}

}
return new ArrayList<>();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
* 流程审批节点
Expand Down Expand Up @@ -81,6 +82,20 @@ public void setCurrentState() {
}


@Override
public boolean equals(Object target) {
if(target instanceof ProcessNode) {
ProcessNode targetNode = (ProcessNode) target;
return targetNode.getNodeId().equals(this.getNodeId());
}
return super.equals(target);
}

@Override
public int hashCode() {
return Objects.hash(nodeId, nodeName, nodeType, state, operators);
}

/**
* 审批意见内容,仅当历史节点存在数据
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public class TriggerScript {
public static final String SCRIPT_DEFAULT = """
// @SCRIPT_TITLE 示例触发节点(打印触发日志)
def run(request){
print('hello trigger node.');
print('hello trigger node.\\n');
}
""";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import com.codingapi.flow.manager.NodeStrategyManager;
import com.codingapi.flow.manager.OperatorManager;
import com.codingapi.flow.node.IFlowNode;
import com.codingapi.flow.node.NodeType;
import com.codingapi.flow.node.nodes.StartNode;
import com.codingapi.flow.operator.IFlowOperator;
import com.codingapi.flow.pojo.request.FlowProcessNodeRequest;
Expand All @@ -21,6 +22,7 @@
import com.codingapi.flow.session.FlowAdvice;
import com.codingapi.flow.session.FlowSession;
import com.codingapi.flow.workflow.Workflow;
import lombok.Getter;

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


public FlowProcessNodeService(FlowProcessNodeRequest request) {
this.request = request;
this.currentOperator = RepositoryHolderContext.getInstance().getOperatorById(request.getOperatorId());
Expand All @@ -55,6 +58,7 @@ public FlowProcessNodeService(FlowProcessNodeRequest request) {
this.loadWorkflow();
}


private void loadWorkflow() {
String id = this.request.getId();
if (this.request.isCreateWorkflow()) {
Expand Down Expand Up @@ -104,30 +108,70 @@ public List<ProcessNode> processNodes() {
FlowAdvice.nullFlowAdvice()
);

this.fetchNextNode(flowSession, List.of(this.currentNode));
NextNodeLoader nextNodeLoader = new NextNodeLoader(this.currentNode);
List<ProcessNode> nextNodes = nextNodeLoader.loadNextNode(flowSession);

// 推理后续
return nodeList;
this.nodeList.addAll(nextNodes);
return this.nodeList;
}


private void fetchNextNode(FlowSession flowSession, List<IFlowNode> nexNodes) {
for (IFlowNode flowNode : nexNodes) {
List<IFlowOperator> operators = null;
if(flowNode.getType().equals(StartNode.NODE_TYPE)){
operators = List.of(flowSession.getCurrentOperator());
}else {
NodeStrategyManager nodeStrategyManager = flowNode.strategyManager();
OperatorManager operatorManager = nodeStrategyManager.loadOperators(flowSession);
operators = operatorManager.getOperators();
private class NextNodeLoader {

@Getter
private final List<ProcessNode> nodeList;
private final IFlowNode currentNode;
private final List<String> displayNodeTypes;

public NextNodeLoader(IFlowNode currentNode) {
this.currentNode = currentNode;
this.nodeList = new ArrayList<>();
this.displayNodeTypes = new ArrayList<>();
this.initDisplayNodeTypes();
}


private void initDisplayNodeTypes() {
this.displayNodeTypes.add(NodeType.START.name());
this.displayNodeTypes.add(NodeType.END.name());
this.displayNodeTypes.add(NodeType.APPROVAL.name());
this.displayNodeTypes.add(NodeType.NOTIFY.name());
this.displayNodeTypes.add(NodeType.HANDLE.name());
this.displayNodeTypes.add(NodeType.TRIGGER.name());
this.displayNodeTypes.add(NodeType.SUB_PROCESS.name());
}

private void fetchNextNode(FlowSession flowSession, List<IFlowNode> nexNodes) {
for (IFlowNode flowNode : nexNodes) {
List<IFlowOperator> operators = null;
if (flowNode.getType().equals(StartNode.NODE_TYPE)) {
operators = List.of(flowSession.getCurrentOperator());
} else {
NodeStrategyManager nodeStrategyManager = flowNode.strategyManager();
OperatorManager operatorManager = nodeStrategyManager.loadOperators(flowSession);
operators = operatorManager.getOperators();
}
ProcessNode processNode = new ProcessNode(flowNode, operators);
if (processNode.isFlowNode(this.currentNode)) {
processNode.setCurrentState();
}
this.nodeList.add(processNode);
List<IFlowNode> nextNodes = workflow.nextNodes(flowNode);
this.fetchNextNode(flowSession.updateSession(flowNode), nextNodes);
}
ProcessNode processNode = new ProcessNode(flowNode,operators);
if(processNode.isFlowNode(this.currentNode)){
processNode.setCurrentState();
}

public List<ProcessNode> loadNextNode(FlowSession flowSession) {
this.fetchNextNode(flowSession,List.of(this.currentNode));

List<ProcessNode> displayNodes = nodeList.stream().filter(node-> this.displayNodeTypes.contains(node.getNodeType())).toList();
List<ProcessNode> processNodeList = new ArrayList<>();
for (ProcessNode node:displayNodes){
if(!processNodeList.contains(node)){
processNodeList.add(node);
}
}
this.nodeList.add(processNode);
List<IFlowNode> nextNodes = workflow.nextNodes(flowNode);
this.fetchNextNode(flowSession.updateSession(flowNode), nextNodes);
return processNodeList;
}
}

Expand Down
5 changes: 5 additions & 0 deletions frontend/packages/flow-pc/flow-pc-design/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,12 @@
},
"dependencies": {
"@ant-design/icons": "~6.1.0",
"@codemirror/commands": "^6.10.2",
"@codemirror/lang-java": "^6.0.2",
"@codemirror/language": "^6.12.2",
"@codemirror/state": "^6.5.4",
"@codemirror/theme-one-dark": "^6.1.3",
"@codemirror/view": "^6.39.16",
"@flow-engine/flow-core": "workspace:*",
"@flow-engine/flow-pc-ui": "workspace:*",
"@flow-engine/flow-types": "workspace:*",
Expand All @@ -34,6 +38,7 @@
"@flowgram.ai/form-materials": "^1.0.7",
"@flowgram.ai/minimap-plugin": "1.0.7",
"@flowgram.ai/panel-manager-plugin": "^1.0.7",
"@lezer/highlight": "^1.2.3",
"@reduxjs/toolkit": "^2.11.2",
"antd": "^6.2.1",
"dayjs": "^1.11.19",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {Button, Form, Space} from "antd";
import React from "react";
import {GroovyScriptPreview} from "@/components/script/components/groovy-script-preview";
import {EditOutlined} from "@ant-design/icons";
import {ConditionConfigModal} from "@/components/script/modal/condition-config-modal";

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

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

return (
<Form
Expand All @@ -35,11 +37,19 @@ export const ConditionScript = ()=>{
<Button
icon={<EditOutlined/>}
onClick={() => {
setVisible(true);
}}
style={{borderRadius: '0 6px 6px 0'}}
>
编辑
</Button>

<ConditionConfigModal
open={visible}
onCancel={()=>{setVisible(false);}}
onConfirm={(value)=>{onChange(value)}}
script={value}
/>
</Space.Compact>
)}
/>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import React from "react";
import {Button, Form,Input, Space} from "antd";
import { Field, FieldRenderProps } from "@flowgram.ai/fixed-layout-editor";
import {Button, Form, Space} from "antd";
import {Field, FieldRenderProps} from "@flowgram.ai/fixed-layout-editor";
import {GroovyScriptPreview} from "@/components/script/components/groovy-script-preview";
import { EditOutlined } from "@ant-design/icons";
import {EditOutlined} from "@ant-design/icons";
import {ErrorTriggerConfigModal} from "@/components/script/modal/error-trigger-config-modal";

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

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

return (
<Form
Expand All @@ -36,11 +38,19 @@ export const ErrorTriggerStrategy: React.FC = () => {
<Button
icon={<EditOutlined/>}
onClick={() => {
setVisible(true);
}}
style={{borderRadius: '0 6px 6px 0'}}
>
编辑
</Button>

<ErrorTriggerConfigModal
open={visible}
onCancel={()=>{setVisible(false);}}
onConfirm={(value)=>{onChange(value)}}
script={value}
/>
</Space.Compact>
)}
/>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import React from "react";
import {Button, Form, Input, Space} from "antd";
import {Button, Form, Space} from "antd";
import {Field, FieldRenderProps} from "@flowgram.ai/fixed-layout-editor";
import {GroovyScriptPreview} from "@/components/script/components/groovy-script-preview";
import { EditOutlined } from "@ant-design/icons";
import {EditOutlined} from "@ant-design/icons";
import {RouterConfigModal} from "@/components/script/modal/router-config-modal";

/**
* 路由策略配置
* @constructor
*/
export const RouterStrategy:React.FC = () => {
const [form] = Form.useForm();
const [visible,setVisible] = React.useState(false);

return (
<Form
Expand All @@ -34,11 +36,21 @@ export const RouterStrategy:React.FC = () => {
<Button
icon={<EditOutlined/>}
onClick={() => {
setVisible(true);
}}
style={{borderRadius: '0 6px 6px 0'}}
>
编辑
</Button>

<RouterConfigModal
open={visible}
script={value}
onCancel={()=>{setVisible(false);}}
onConfirm={(value)=>{
onChange(value);
}}
/>
</Space.Compact>
)}
/>
Expand Down
Loading