From d837db46abb6f2355a933998232d9acec3445d87 Mon Sep 17 00:00:00 2001 From: ZLY Date: Thu, 28 Aug 2025 10:49:57 +0800 Subject: [PATCH] =?UTF-8?q?feat(flowEditor):=20=E9=87=8D=E6=9E=84=E8=8A=82?= =?UTF-8?q?=E7=82=B9=E5=8F=82=E6=95=B0=E5=A4=84=E7=90=86=E9=80=BB=E8=BE=91?= =?UTF-8?q?(=E7=8E=B0=E9=98=B6=E6=AE=B5=E6=95=B0=E6=8D=AE=E7=BB=93?= =?UTF-8?q?=E6=9E=84=E9=9C=80=E8=A6=81=E9=87=8D=E6=96=B0=E8=AE=BE=E8=AE=A1?= =?UTF-8?q?=EF=BC=8C=E6=97=A7=E6=95=B0=E6=8D=AE=E6=97=A0=E6=B3=95=E5=9B=9E?= =?UTF-8?q?=E6=98=BE=E8=BF=9E=E7=BA=BF)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../flowEditor/components/nodeContent.tsx | 158 +- src/pages/flowEditor/index.tsx | 28 +- src/pages/flowEditor/test/exampleFlowData.ts | 19739 +++++++++++++++- src/utils/convertFlowData.ts | 16 +- 4 files changed, 19653 insertions(+), 288 deletions(-) diff --git a/src/pages/flowEditor/components/nodeContent.tsx b/src/pages/flowEditor/components/nodeContent.tsx index f3a4444..9dbe978 100644 --- a/src/pages/flowEditor/components/nodeContent.tsx +++ b/src/pages/flowEditor/components/nodeContent.tsx @@ -1,12 +1,13 @@ import React from 'react'; import styles from '@/pages/flowEditor/node/style/base.module.less'; import { Handle, Position, useStore } from '@xyflow/react'; -import { Divider } from '@arco-design/web-react'; interface NodeContentData { parameters?: { - inputs?: any[]; - outputs?: any[]; + dataIns?: any[]; + dataOuts?: any[]; + apiIns?: any[]; + apiOuts?: any[]; }; showFooter?: boolean; type?: string; @@ -15,31 +16,54 @@ interface NodeContentData { } // 渲染特殊节点(开始/结束节点)的句柄 -const renderSpecialNodeHandles = (isStartNode: boolean, isEndNode: boolean, inputs: any[], outputs: any[]) => { +const renderSpecialNodeHandles = (isStartNode: boolean, isEndNode: boolean, dataIns: any[], dataOuts: any[], apiIns: any[], apiOuts: any[]) => { return ( <> - + {isStartNode ? + apiOuts.map((_, index) => ( + + )) + : + apiIns.map((_, index) => ( + + )) + } {/* 为特殊节点的参数也添加句柄 */} - {isStartNode && outputs.map((_, index) => ( + {isStartNode && dataOuts.map((_, index) => ( ))} - {isEndNode && inputs.map((_, index) => ( + {isEndNode && dataIns.map((_, index) => ( { +const renderRegularNodeHandles = (dataIns: any[], dataOuts: any[], apiIns: any[], apiOuts: any[]) => { return ( <> - - + {apiOuts.map((_, index) => ( + + ))} + {apiIns.map((_, index) => ( + + ))} {/* 输入参数连接端点 */} - {inputs.map((_, index) => ( + {dataIns.map((_, index) => ( { ))} {/* 输出参数连接端点 */} - {outputs.map((_, index) => ( + {dataOuts.map((_, index) => ( { }; const NodeContent = ({ data }: { data: NodeContentData }) => { - const inputs = data.parameters?.inputs || []; - const outputs = data.parameters?.outputs || []; + const apiIns = data.parameters?.apiIns || []; + const apiOuts = data.parameters?.apiOuts || []; + const dataIns = data.parameters?.dataIns || []; + const dataOuts = data.parameters?.dataOuts || []; const showFooter = data.showFooter || false; // 判断节点类型 @@ -161,9 +193,9 @@ const NodeContent = ({ data }: { data: NodeContentData }) => { <> {/*content栏*/}
- {inputs.length > 0 && !isStartNode && ( + {dataIns.length > 0 && !isStartNode && (
- {inputs.map((input, index) => ( + {dataIns.map((input, index) => (
{input.name || `输入${index + 1}`}
@@ -171,9 +203,9 @@ const NodeContent = ({ data }: { data: NodeContentData }) => {
)} - {outputs.length > 0 && !isEndNode && ( + {dataOuts.length > 0 && !isEndNode && (
- {outputs.map((output, index) => ( + {dataOuts.map((output, index) => (
{output.name || `输出${index + 1}`}
@@ -191,8 +223,8 @@ const NodeContent = ({ data }: { data: NodeContentData }) => { {/* 根据节点类型渲染不同的句柄 */} {isSpecialNode - ? renderSpecialNodeHandles(isStartNode, isEndNode, inputs, outputs) - : renderRegularNodeHandles(inputs, outputs)} + ? renderSpecialNodeHandles(isStartNode, isEndNode, dataIns, dataOuts, apiIns, apiOuts) + : renderRegularNodeHandles(dataIns, dataOuts, apiIns, apiOuts)} ); }; diff --git a/src/pages/flowEditor/index.tsx b/src/pages/flowEditor/index.tsx index 5f4bed4..19fb7fd 100644 --- a/src/pages/flowEditor/index.tsx +++ b/src/pages/flowEditor/index.tsx @@ -1,4 +1,4 @@ -import React, { useState, useCallback, useRef } from 'react'; +import React, { useState, useCallback, useRef, useEffect } from 'react'; import { ReactFlow, applyNodeChanges, @@ -12,7 +12,6 @@ import { useReactFlow, NodeTypes, EdgeTypes, - Panel, SelectionMode } from '@xyflow/react'; import '@xyflow/react/dist/style.css'; @@ -23,7 +22,7 @@ import DraggableNode from './node/draggableNode/DraggableNode'; import BasicNode from './node/basicNode/BasicNode'; import SideBar from './sideBar/sideBar'; import { convertFlowData } from '@/utils/convertFlowData'; -import { exampleFlowData } from '@/pages/flowEditor/test/exampleFlowData'; +import { exampleFlowData, mineList } from '@/pages/flowEditor/test/exampleFlowData'; import CustomEdge from './components/customEdge'; const nodeTypes: NodeTypes = { @@ -38,14 +37,6 @@ const edgeTypes: EdgeTypes = { custom: CustomEdge }; -const { nodes: convertedNodes, edges: convertedEdges } = convertFlowData(exampleFlowData); - -// 为所有边添加类型 -const initialEdges: Edge[] = convertedEdges.map(edge => ({ - ...edge, - type: 'custom' -})); - const FlowEditorWithProvider: React.FC = () => { return (
@@ -58,8 +49,8 @@ const FlowEditorWithProvider: React.FC = () => { }; const FlowEditor: React.FC = () => { - const [nodes, setNodes] = useState(convertedNodes); - const [edges, setEdges] = useState(initialEdges); + const [nodes, setNodes] = useState([]); + const [edges, setEdges] = useState([]); const reactFlowInstance = useReactFlow(); const reactFlowWrapper = useRef(null); @@ -109,6 +100,17 @@ const FlowEditor: React.FC = () => { [reactFlowInstance] ); + useEffect(() => { + const { nodes: convertedNodes, edges: convertedEdges } = convertFlowData(exampleFlowData); + // 为所有边添加类型 + const initialEdges: Edge[] = convertedEdges.map(edge => ({ + ...edge, + type: 'custom' + })); + setNodes(convertedNodes); + setEdges(initialEdges); + }, []); + return (
{ data: { title: nodeConfig.nodeName || nodeConfig.nodeId, parameters: { - inputs: nodeConfig.dataIns?.map((input: any) => ({ + apiIns: [{ + name: 'start', + desc: '', + dataType: '', + defaultValue: '' + }], + apiOuts: [{ + name: nodeConfig.nodeId === 'end' ? 'end' : 'done', + desc: '', + dataType: '', + defaultValue: '' + }], + dataIns: nodeConfig.dataIns?.map((input: any) => ({ name: input.id, desc: input.desc, dataType: input.dataType, defaultValue: input.defaultValue })) || [], - outputs: nodeConfig.dataOuts?.map((output: any) => ({ + dataOuts: nodeConfig.dataOuts?.map((output: any) => ({ name: output.id, desc: output.desc, dataType: output.dataType,