diff --git a/.tool-versions b/.tool-versions new file mode 100644 index 00000000..d13209df --- /dev/null +++ b/.tool-versions @@ -0,0 +1,3 @@ +default nodejs 22 +nodejs 22.22.0 +java openjdk-22 diff --git a/flow-engine-framework/src/main/java/com/codingapi/flow/manager/FlowNodeManager.java b/flow-engine-framework/src/main/java/com/codingapi/flow/manager/FlowNodeManager.java index 92b91f60..7bd56f6c 100644 --- a/flow-engine-framework/src/main/java/com/codingapi/flow/manager/FlowNodeManager.java +++ b/flow-engine-framework/src/main/java/com/codingapi/flow/manager/FlowNodeManager.java @@ -9,7 +9,7 @@ import java.util.stream.Stream; /** - * 流程节点管理器,主要获取流程节点信息 + * 流程节点管理器,主要获取流程节点信息 */ public class FlowNodeManager { @@ -29,9 +29,9 @@ private IFlowNode fetchNodes(String nodeId, List nodes) { return node; } List 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; } } @@ -74,12 +74,13 @@ public List getNextNodes(IFlowNode current) { /** * 加载下一节点 - * @param current 当前节点状态 - * @param iterator 当前遍历的节点列表 + * + * @param current 当前节点状态 + * @param iterator 当前遍历的节点列表 * @return 下一节点列表 */ private List loadNextNodes(FlowNodeState current, Iterator iterator) { - if(current.isEndNode()){ + if (current.isEndNode()) { return new ArrayList<>(); } while (iterator.hasNext()) { @@ -89,7 +90,17 @@ private List loadNextNodes(FlowNodeState current, Iterator 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(); @@ -98,19 +109,20 @@ private List loadNextNodes(FlowNodeState current, Iterator nextNodes = this.loadNextNodes(current, node.getBlocks().stream().map(FlowNodeState::new).toList().iterator()); - if (!nextNodes.isEmpty()) { - return nextNodes; + if (node.getBlocks() != null) { + List nextNodes = this.loadNextNodes(current, node.getBlocks().stream().map(FlowNodeState::new).toList().iterator()); + if (!nextNodes.isEmpty()) { + return nextNodes; + } } } - } return new ArrayList<>(); } diff --git a/flow-engine-framework/src/main/java/com/codingapi/flow/pojo/response/ProcessNode.java b/flow-engine-framework/src/main/java/com/codingapi/flow/pojo/response/ProcessNode.java index 5da9e391..00a1f89b 100644 --- a/flow-engine-framework/src/main/java/com/codingapi/flow/pojo/response/ProcessNode.java +++ b/flow-engine-framework/src/main/java/com/codingapi/flow/pojo/response/ProcessNode.java @@ -9,6 +9,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.Objects; /** * 流程审批节点 @@ -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); + } + /** * 审批意见内容,仅当历史节点存在数据 */ diff --git a/flow-engine-framework/src/main/java/com/codingapi/flow/script/node/TriggerScript.java b/flow-engine-framework/src/main/java/com/codingapi/flow/script/node/TriggerScript.java index e35af8ce..a19cd53c 100644 --- a/flow-engine-framework/src/main/java/com/codingapi/flow/script/node/TriggerScript.java +++ b/flow-engine-framework/src/main/java/com/codingapi/flow/script/node/TriggerScript.java @@ -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'); } """; diff --git a/flow-engine-framework/src/main/java/com/codingapi/flow/service/impl/FlowProcessNodeService.java b/flow-engine-framework/src/main/java/com/codingapi/flow/service/impl/FlowProcessNodeService.java index c3da7dd6..6083616d 100644 --- a/flow-engine-framework/src/main/java/com/codingapi/flow/service/impl/FlowProcessNodeService.java +++ b/flow-engine-framework/src/main/java/com/codingapi/flow/service/impl/FlowProcessNodeService.java @@ -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; @@ -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; @@ -45,6 +47,7 @@ public class FlowProcessNodeService { // 流程节点记录 private final List nodeList; + public FlowProcessNodeService(FlowProcessNodeRequest request) { this.request = request; this.currentOperator = RepositoryHolderContext.getInstance().getOperatorById(request.getOperatorId()); @@ -55,6 +58,7 @@ public FlowProcessNodeService(FlowProcessNodeRequest request) { this.loadWorkflow(); } + private void loadWorkflow() { String id = this.request.getId(); if (this.request.isCreateWorkflow()) { @@ -104,30 +108,70 @@ public List processNodes() { FlowAdvice.nullFlowAdvice() ); - this.fetchNextNode(flowSession, List.of(this.currentNode)); + NextNodeLoader nextNodeLoader = new NextNodeLoader(this.currentNode); + List nextNodes = nextNodeLoader.loadNextNode(flowSession); - // 推理后续 - return nodeList; + this.nodeList.addAll(nextNodes); + return this.nodeList; } - private void fetchNextNode(FlowSession flowSession, List nexNodes) { - for (IFlowNode flowNode : nexNodes) { - List 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 nodeList; + private final IFlowNode currentNode; + private final List 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 nexNodes) { + for (IFlowNode flowNode : nexNodes) { + List 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 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 loadNextNode(FlowSession flowSession) { + this.fetchNextNode(flowSession,List.of(this.currentNode)); + + List displayNodes = nodeList.stream().filter(node-> this.displayNodeTypes.contains(node.getNodeType())).toList(); + List processNodeList = new ArrayList<>(); + for (ProcessNode node:displayNodes){ + if(!processNodeList.contains(node)){ + processNodeList.add(node); + } } - this.nodeList.add(processNode); - List nextNodes = workflow.nextNodes(flowNode); - this.fetchNextNode(flowSession.updateSession(flowNode), nextNodes); + return processNodeList; } } diff --git a/frontend/packages/flow-pc/flow-pc-design/package.json b/frontend/packages/flow-pc/flow-pc-design/package.json index f833ae02..3074cb16 100644 --- a/frontend/packages/flow-pc/flow-pc-design/package.json +++ b/frontend/packages/flow-pc/flow-pc-design/package.json @@ -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:*", @@ -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", diff --git a/frontend/packages/flow-pc/flow-pc-design/src/components/design-editor/node-components/condition/index.tsx b/frontend/packages/flow-pc/flow-pc-design/src/components/design-editor/node-components/condition/index.tsx index ba8763e3..093d812d 100644 --- a/frontend/packages/flow-pc/flow-pc-design/src/components/design-editor/node-components/condition/index.tsx +++ b/frontend/packages/flow-pc/flow-pc-design/src/components/design-editor/node-components/condition/index.tsx @@ -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"; /** * 条件配置 @@ -11,6 +12,7 @@ import {EditOutlined} from "@ant-design/icons"; export const ConditionScript = ()=>{ const [form] = Form.useForm(); + const [visible,setVisible] = React.useState(false); return (
{ + + {setVisible(false);}} + onConfirm={(value)=>{onChange(value)}} + script={value} + /> )} /> diff --git a/frontend/packages/flow-pc/flow-pc-design/src/components/design-editor/node-components/strategy/error-trigger.tsx b/frontend/packages/flow-pc/flow-pc-design/src/components/design-editor/node-components/strategy/error-trigger.tsx index 3c4ed672..0ab0f316 100644 --- a/frontend/packages/flow-pc/flow-pc-design/src/components/design-editor/node-components/strategy/error-trigger.tsx +++ b/frontend/packages/flow-pc/flow-pc-design/src/components/design-editor/node-components/strategy/error-trigger.tsx @@ -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"; /** * 错误触发策略配置(没有匹配到人时) @@ -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 ( { + + {setVisible(false);}} + onConfirm={(value)=>{onChange(value)}} + script={value} + /> )} /> diff --git a/frontend/packages/flow-pc/flow-pc-design/src/components/design-editor/node-components/strategy/router.tsx b/frontend/packages/flow-pc/flow-pc-design/src/components/design-editor/node-components/strategy/router.tsx index f243b101..4e519903 100644 --- a/frontend/packages/flow-pc/flow-pc-design/src/components/design-editor/node-components/strategy/router.tsx +++ b/frontend/packages/flow-pc/flow-pc-design/src/components/design-editor/node-components/strategy/router.tsx @@ -1,8 +1,9 @@ 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"; /** * 路由策略配置 @@ -10,6 +11,7 @@ import { EditOutlined } from "@ant-design/icons"; */ export const RouterStrategy:React.FC = () => { const [form] = Form.useForm(); + const [visible,setVisible] = React.useState(false); return ( { + + {setVisible(false);}} + onConfirm={(value)=>{ + onChange(value); + }} + /> )} /> diff --git a/frontend/packages/flow-pc/flow-pc-design/src/components/design-editor/node-components/strategy/sub-process.tsx b/frontend/packages/flow-pc/flow-pc-design/src/components/design-editor/node-components/strategy/sub-process.tsx index b617f58d..8f590133 100644 --- a/frontend/packages/flow-pc/flow-pc-design/src/components/design-editor/node-components/strategy/sub-process.tsx +++ b/frontend/packages/flow-pc/flow-pc-design/src/components/design-editor/node-components/strategy/sub-process.tsx @@ -1,8 +1,9 @@ import React from "react"; -import {Button, Form, Input,Space,Switch} from "antd"; +import {Button, Form, Space, Switch} 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 {SubProcessConfigModal} from "@/components/script/modal/sub-process-config-modal"; /** * 子流程任务策略 @@ -10,6 +11,7 @@ import { EditOutlined } from "@ant-design/icons"; */ export const SubProcessStrategy:React.FC = () => { const [form] = Form.useForm(); + const [visible,setVisible] = React.useState(false); return ( { + + {setVisible(false);}} + onConfirm={(value)=>{ + onChange(value) + }} + script={value} + /> )} /> diff --git a/frontend/packages/flow-pc/flow-pc-design/src/components/design-editor/node-components/strategy/trigger.tsx b/frontend/packages/flow-pc/flow-pc-design/src/components/design-editor/node-components/strategy/trigger.tsx index d381f2db..b6d753a8 100644 --- a/frontend/packages/flow-pc/flow-pc-design/src/components/design-editor/node-components/strategy/trigger.tsx +++ b/frontend/packages/flow-pc/flow-pc-design/src/components/design-editor/node-components/strategy/trigger.tsx @@ -1,8 +1,9 @@ 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 {TriggerConfigModal} from "@/components/script/modal/trigger-config-modal"; /** * 触发策略配置 @@ -10,6 +11,7 @@ import { EditOutlined } from "@ant-design/icons"; */ export const TriggerStrategy:React.FC = () => { const [form] = Form.useForm(); + const [visible,setVisible] = React.useState(false); return ( { + + {setVisible(false);}} + onConfirm={(value)=>{onChange(value)}} + script={value} + /> )} /> diff --git a/frontend/packages/flow-pc/flow-pc-design/src/components/script/default-script.ts b/frontend/packages/flow-pc/flow-pc-design/src/components/script/default-script.ts index 5306cc8d..0a0bf3ba 100644 --- a/frontend/packages/flow-pc/flow-pc-design/src/components/script/default-script.ts +++ b/frontend/packages/flow-pc/flow-pc-design/src/components/script/default-script.ts @@ -1,26 +1,59 @@ // 默认发起人范围设置脚本,任意人员 -export const DEFAULT_OPERATOR_CREATE_SCRIPT = ` - // @SCRIPT_TITLE 任意人员 - def run(request){ - return true; - } - `; +export const DEFAULT_OPERATOR_CREATE_SCRIPT = `// @SCRIPT_TITLE 任意人员 +def run(request){ + return true; +} +`; // 默认操作人配置脚本,流程创建者 -export const DEFAULT_OPERATOR_LOAD_SCRIPT = ` - // @SCRIPT_TITLE 流程创建者 - def run(request){ - return [request.getCreatedOperator()] - } - `; +export const DEFAULT_OPERATOR_LOAD_SCRIPT = `// @SCRIPT_TITLE 流程创建者 +def run(request){ + return [request.getCreatedOperator()] +} +`; // 默认节点标题配置脚本,您有一条待办消息 -export const DEFAULT_NODE_TITLE_SCRIPT = ` - // @SCRIPT_TITLE 您有一条待办消息 - def run(request){ - return "您有一条待办消息" - } +export const DEFAULT_NODE_TITLE_SCRIPT = `// @SCRIPT_TITLE 您有一条待办消息 +def run(request){ + return "您有一条待办消息" +} ` + +// 默认异常触发,回退至开始节点 +export const DEFAULT_ERROR_TRIGGER_SCRIPT = `// @SCRIPT_TITLE 回退至开始节点 +def run(request){ + return $bind.createErrorThrow(request.getStartNode()); +} +` + +// 默认条件脚本,默认条件(允许执行) +export const DEFAULT_CONDITION_SCRIPT = `// @SCRIPT_TITLE 默认条件(允许执行) +def run(request){ + return true; +} +` + +// 默认路由脚本,发起节点 +export const DEFAULT_ROUTER_SCRIPT = `// @SCRIPT_TITLE 发起节点 +def run(request){ + return request.getStartNode().getId(); +} +` + +// 默认触发脚本,示例触发节点(打印触发日志) +export const DEFAULT_TRIGGER_SCRIPT = `// @SCRIPT_TITLE 示例触发节点(打印触发日志) +def run(request){ + print('hello trigger node.\\n'); +} +` + + +// 子流程脚本,创建当前流程 +export const DEFAULT_SUB_PROCESS_SCRIPT = `// @SCRIPT_TITLE 创建当前流程 +def run(request){ + return request.toCreateRequest() +} +` \ No newline at end of file diff --git a/frontend/packages/flow-pc/flow-pc-design/src/components/script/modal/condition-config-modal.tsx b/frontend/packages/flow-pc/flow-pc-design/src/components/script/modal/condition-config-modal.tsx new file mode 100644 index 00000000..c8bac6e8 --- /dev/null +++ b/frontend/packages/flow-pc/flow-pc-design/src/components/script/modal/condition-config-modal.tsx @@ -0,0 +1,57 @@ +import React from "react"; +import {GroovyVariableMapping, ScriptType} from "@/components/script/typings"; +import {GroovyScriptContent, GroovyScriptModal} from "@/components/script/components/groovy-script-modal"; +import {GroovyScriptConvertorUtil} from "@/components/script/utils/convertor"; +import {AdvancedScriptEditor} from "@/components/script/components/advanced-script-editor"; +import {DEFAULT_CONDITION_SCRIPT} from "@/components/script/default-script"; +import {ConditionPluginView} from "@/components/script/plugins/view/condition-view"; + +export interface ConditionConfigModalProps { + /** 是否展示 **/ + open: boolean; + /** 当前脚本 */ + script: string; + /** 表单字段(用于动态生成变量) */ + variables?: GroovyVariableMapping[]; + /** 取消回调 */ + onCancel: () => void; + /** 确认回调 */ + onConfirm: (script: string) => void; +} + + + +const ConditionConfigContent: React.FC = (props) => { + const isAdvance = GroovyScriptConvertorUtil.isCustomScript(props.script); + + return ( + <> + {isAdvance && ( + { + return DEFAULT_CONDITION_SCRIPT; + }} + /> + )} + {!isAdvance && ( + + )} + + ); +} + +export const ConditionConfigModal:React.FC = (props) => { + return ( + + ); +} \ No newline at end of file diff --git a/frontend/packages/flow-pc/flow-pc-design/src/components/script/modal/error-trigger-config-modal.tsx b/frontend/packages/flow-pc/flow-pc-design/src/components/script/modal/error-trigger-config-modal.tsx new file mode 100644 index 00000000..de9a8d7d --- /dev/null +++ b/frontend/packages/flow-pc/flow-pc-design/src/components/script/modal/error-trigger-config-modal.tsx @@ -0,0 +1,57 @@ +import React from "react"; +import {GroovyVariableMapping, ScriptType} from "@/components/script/typings"; +import {GroovyScriptContent, GroovyScriptModal} from "@/components/script/components/groovy-script-modal"; +import {GroovyScriptConvertorUtil} from "@/components/script/utils/convertor"; +import {AdvancedScriptEditor} from "@/components/script/components/advanced-script-editor"; +import {DEFAULT_ERROR_TRIGGER_SCRIPT} from "@/components/script/default-script"; +import {ErrorTriggerPluginView} from "@/components/script/plugins/view/error-trigger-view"; + +export interface ErrorTriggerConfigModalProps { + /** 是否展示 **/ + open: boolean; + /** 当前脚本 */ + script: string; + /** 表单字段(用于动态生成变量) */ + variables?: GroovyVariableMapping[]; + /** 取消回调 */ + onCancel: () => void; + /** 确认回调 */ + onConfirm: (script: string) => void; +} + + + +const ErrorTriggerConfigContent: React.FC = (props) => { + const isAdvance = GroovyScriptConvertorUtil.isCustomScript(props.script); + + return ( + <> + {isAdvance && ( + { + return DEFAULT_ERROR_TRIGGER_SCRIPT; + }} + /> + )} + {!isAdvance && ( + + )} + + ); +} + +export const ErrorTriggerConfigModal:React.FC = (props) => { + return ( + + ); +} \ No newline at end of file diff --git a/frontend/packages/flow-pc/flow-pc-design/src/components/script/modal/router-config-modal.tsx b/frontend/packages/flow-pc/flow-pc-design/src/components/script/modal/router-config-modal.tsx new file mode 100644 index 00000000..9eb27645 --- /dev/null +++ b/frontend/packages/flow-pc/flow-pc-design/src/components/script/modal/router-config-modal.tsx @@ -0,0 +1,57 @@ +import React from "react"; +import {GroovyVariableMapping, ScriptType} from "@/components/script/typings"; +import {GroovyScriptContent, GroovyScriptModal} from "@/components/script/components/groovy-script-modal"; +import {GroovyScriptConvertorUtil} from "@/components/script/utils/convertor"; +import {AdvancedScriptEditor} from "@/components/script/components/advanced-script-editor"; +import {DEFAULT_ROUTER_SCRIPT} from "@/components/script/default-script"; +import {RouterPluginView} from "@/components/script/plugins/view/router-view"; + +export interface RouterConfigModalProps { + /** 是否展示 **/ + open: boolean; + /** 当前脚本 */ + script: string; + /** 表单字段(用于动态生成变量) */ + variables?: GroovyVariableMapping[]; + /** 取消回调 */ + onCancel: () => void; + /** 确认回调 */ + onConfirm: (script: string) => void; +} + + + +const RouterConfigContent: React.FC = (props) => { + const isAdvance = GroovyScriptConvertorUtil.isCustomScript(props.script); + + return ( + <> + {isAdvance && ( + { + return DEFAULT_ROUTER_SCRIPT; + }} + /> + )} + {!isAdvance && ( + + )} + + ); +} + +export const RouterConfigModal:React.FC = (props) => { + return ( + + ); +} \ No newline at end of file diff --git a/frontend/packages/flow-pc/flow-pc-design/src/components/script/modal/sub-process-config-modal.tsx b/frontend/packages/flow-pc/flow-pc-design/src/components/script/modal/sub-process-config-modal.tsx new file mode 100644 index 00000000..9cdca7fd --- /dev/null +++ b/frontend/packages/flow-pc/flow-pc-design/src/components/script/modal/sub-process-config-modal.tsx @@ -0,0 +1,57 @@ +import React from "react"; +import {GroovyVariableMapping, ScriptType} from "@/components/script/typings"; +import {GroovyScriptContent, GroovyScriptModal} from "@/components/script/components/groovy-script-modal"; +import {GroovyScriptConvertorUtil} from "@/components/script/utils/convertor"; +import {AdvancedScriptEditor} from "@/components/script/components/advanced-script-editor"; +import {DEFAULT_SUB_PROCESS_SCRIPT} from "@/components/script/default-script"; +import {SubProcessPluginView} from "@/components/script/plugins/view/sub-process-view"; + +export interface SubProcessConfigModalProps { + /** 是否展示 **/ + open: boolean; + /** 当前脚本 */ + script: string; + /** 表单字段(用于动态生成变量) */ + variables?: GroovyVariableMapping[]; + /** 取消回调 */ + onCancel: () => void; + /** 确认回调 */ + onConfirm: (script: string) => void; +} + + + +const SubProcessConfigContent: React.FC = (props) => { + const isAdvance = GroovyScriptConvertorUtil.isCustomScript(props.script); + + return ( + <> + {isAdvance && ( + { + return DEFAULT_SUB_PROCESS_SCRIPT; + }} + /> + )} + {!isAdvance && ( + + )} + + ); +} + +export const SubProcessConfigModal:React.FC = (props) => { + return ( + + ); +} \ No newline at end of file diff --git a/frontend/packages/flow-pc/flow-pc-design/src/components/script/modal/trigger-config-modal.tsx b/frontend/packages/flow-pc/flow-pc-design/src/components/script/modal/trigger-config-modal.tsx new file mode 100644 index 00000000..d2ca9623 --- /dev/null +++ b/frontend/packages/flow-pc/flow-pc-design/src/components/script/modal/trigger-config-modal.tsx @@ -0,0 +1,57 @@ +import React from "react"; +import {GroovyVariableMapping, ScriptType} from "@/components/script/typings"; +import {GroovyScriptContent, GroovyScriptModal} from "@/components/script/components/groovy-script-modal"; +import {GroovyScriptConvertorUtil} from "@/components/script/utils/convertor"; +import {AdvancedScriptEditor} from "@/components/script/components/advanced-script-editor"; +import {DEFAULT_TRIGGER_SCRIPT} from "@/components/script/default-script"; +import {TriggerPluginView} from "@/components/script/plugins/view/trigger-view"; + +export interface TriggerConfigModalProps { + /** 是否展示 **/ + open: boolean; + /** 当前脚本 */ + script: string; + /** 表单字段(用于动态生成变量) */ + variables?: GroovyVariableMapping[]; + /** 取消回调 */ + onCancel: () => void; + /** 确认回调 */ + onConfirm: (script: string) => void; +} + + + +const TriggerConfigContent: React.FC = (props) => { + const isAdvance = GroovyScriptConvertorUtil.isCustomScript(props.script); + + return ( + <> + {isAdvance && ( + { + return DEFAULT_TRIGGER_SCRIPT; + }} + /> + )} + {!isAdvance && ( + + )} + + ); +} + +export const TriggerConfigModal:React.FC = (props) => { + return ( + + ); +} \ No newline at end of file diff --git a/frontend/packages/flow-pc/flow-pc-design/src/components/script/plugins/condition-view-type.ts b/frontend/packages/flow-pc/flow-pc-design/src/components/script/plugins/condition-view-type.ts new file mode 100644 index 00000000..bdf0de3e --- /dev/null +++ b/frontend/packages/flow-pc/flow-pc-design/src/components/script/plugins/condition-view-type.ts @@ -0,0 +1,14 @@ +import {GroovyVariableMapping, ScriptType} from "@/components/script/typings"; + +export const VIEW_KEY = 'ConditionViewPlugin'; + +export interface ConditionViewPlugin { + /** 脚本类型 */ + type: ScriptType; + /** 当前脚本 */ + script: string; + /** 变量映射列表 */ + variables: GroovyVariableMapping[]; + /** 确认回调 */ + onChange: (script: string) => void; +} \ No newline at end of file diff --git a/frontend/packages/flow-pc/flow-pc-design/src/components/script/plugins/error-trigger-view-type.ts b/frontend/packages/flow-pc/flow-pc-design/src/components/script/plugins/error-trigger-view-type.ts new file mode 100644 index 00000000..f6f92c6d --- /dev/null +++ b/frontend/packages/flow-pc/flow-pc-design/src/components/script/plugins/error-trigger-view-type.ts @@ -0,0 +1,14 @@ +import {GroovyVariableMapping, ScriptType} from "@/components/script/typings"; + +export const VIEW_KEY = 'ErrorTriggerViewPlugin'; + +export interface ErrorTriggerViewPlugin { + /** 脚本类型 */ + type: ScriptType; + /** 当前脚本 */ + script: string; + /** 变量映射列表 */ + variables: GroovyVariableMapping[]; + /** 确认回调 */ + onChange: (script: string) => void; +} \ No newline at end of file diff --git a/frontend/packages/flow-pc/flow-pc-design/src/components/script/plugins/router-view-type.ts b/frontend/packages/flow-pc/flow-pc-design/src/components/script/plugins/router-view-type.ts new file mode 100644 index 00000000..7af06524 --- /dev/null +++ b/frontend/packages/flow-pc/flow-pc-design/src/components/script/plugins/router-view-type.ts @@ -0,0 +1,14 @@ +import {GroovyVariableMapping, ScriptType} from "@/components/script/typings"; + +export const VIEW_KEY = 'RouterViewPlugin'; + +export interface RouterViewPlugin { + /** 脚本类型 */ + type: ScriptType; + /** 当前脚本 */ + script: string; + /** 变量映射列表 */ + variables: GroovyVariableMapping[]; + /** 确认回调 */ + onChange: (script: string) => void; +} \ No newline at end of file diff --git a/frontend/packages/flow-pc/flow-pc-design/src/components/script/plugins/sub-process-view-type.ts b/frontend/packages/flow-pc/flow-pc-design/src/components/script/plugins/sub-process-view-type.ts new file mode 100644 index 00000000..7f65ab27 --- /dev/null +++ b/frontend/packages/flow-pc/flow-pc-design/src/components/script/plugins/sub-process-view-type.ts @@ -0,0 +1,14 @@ +import {GroovyVariableMapping, ScriptType} from "@/components/script/typings"; + +export const VIEW_KEY = 'SubProcessViewPlugin'; + +export interface SubProcessViewPlugin { + /** 脚本类型 */ + type: ScriptType; + /** 当前脚本 */ + script: string; + /** 变量映射列表 */ + variables: GroovyVariableMapping[]; + /** 确认回调 */ + onChange: (script: string) => void; +} \ No newline at end of file diff --git a/frontend/packages/flow-pc/flow-pc-design/src/components/script/plugins/trigger-view-type.ts b/frontend/packages/flow-pc/flow-pc-design/src/components/script/plugins/trigger-view-type.ts new file mode 100644 index 00000000..0ed4276a --- /dev/null +++ b/frontend/packages/flow-pc/flow-pc-design/src/components/script/plugins/trigger-view-type.ts @@ -0,0 +1,14 @@ +import {GroovyVariableMapping, ScriptType} from "@/components/script/typings"; + +export const VIEW_KEY = 'TriggerViewPlugin'; + +export interface TriggerViewPlugin { + /** 脚本类型 */ + type: ScriptType; + /** 当前脚本 */ + script: string; + /** 变量映射列表 */ + variables: GroovyVariableMapping[]; + /** 确认回调 */ + onChange: (script: string) => void; +} \ No newline at end of file diff --git a/frontend/packages/flow-pc/flow-pc-design/src/components/script/plugins/view/condition-view.tsx b/frontend/packages/flow-pc/flow-pc-design/src/components/script/plugins/view/condition-view.tsx new file mode 100644 index 00000000..2f6c33f8 --- /dev/null +++ b/frontend/packages/flow-pc/flow-pc-design/src/components/script/plugins/view/condition-view.tsx @@ -0,0 +1,24 @@ +import React from "react"; +import {ConditionViewPlugin, VIEW_KEY} from "@/components/script/plugins/condition-view-type"; +import {ViewBindPlugin} from "@flow-engine/flow-types"; +import {AdvancedScriptEditor} from "@/components/script/components/advanced-script-editor"; +import {DEFAULT_CONDITION_SCRIPT} from "@/components/script/default-script"; + +export const ConditionPluginView: React.FC = (props) => { + const ConditionPluginViewComponent = ViewBindPlugin.getInstance().get(VIEW_KEY); + if(ConditionPluginViewComponent){ + return ( + + ); + } + + + return ( + { + return DEFAULT_CONDITION_SCRIPT; + }} + /> + ); +} diff --git a/frontend/packages/flow-pc/flow-pc-design/src/components/script/plugins/view/error-trigger-view.tsx b/frontend/packages/flow-pc/flow-pc-design/src/components/script/plugins/view/error-trigger-view.tsx new file mode 100644 index 00000000..2dae77f4 --- /dev/null +++ b/frontend/packages/flow-pc/flow-pc-design/src/components/script/plugins/view/error-trigger-view.tsx @@ -0,0 +1,79 @@ +import React from "react"; +import {NodeTitleGroovyConvertor} from "@/components/script/services/convertor/node-title"; +import {GroovyScriptConvertorUtil} from "@/components/script/utils/convertor"; +import {GroovyScriptPreview} from "@/components/script/components/groovy-script-preview"; +import {VariablePicker} from "@/components/script/components/variable-picker"; +import {Button, Input, Space} from "antd"; +import {CodeOutlined, ReloadOutlined} from "@ant-design/icons"; +import {ErrorTriggerViewPlugin, VIEW_KEY} from "@/components/script/plugins/error-trigger-view-type"; +import {ViewBindPlugin} from "@flow-engine/flow-types"; + +const {TextArea} = Input; + +// TODO 异常触发界面 +export const ErrorTriggerPluginView: React.FC = (props) => { + const nodeTitleGroovyConvertor = new NodeTitleGroovyConvertor(props.script, props.variables); + const ErrorTriggerPluginViewComponent = ViewBindPlugin.getInstance().get(VIEW_KEY); + if(ErrorTriggerPluginViewComponent){ + return ( + + ); + } + + const title = GroovyScriptConvertorUtil.getScriptTitle(props.script); + + return ( +
+
+ 预览 + +
+ + +
+ 内容 +