From bfe24c7dfc84e582070dc78439e18b0dc07adfe5 Mon Sep 17 00:00:00 2001 From: ZLY Date: Fri, 17 Oct 2025 17:08:06 +0800 Subject: [PATCH] =?UTF-8?q?refactor(flow):=20=E9=87=8D=E6=9E=84=E8=BF=9E?= =?UTF-8?q?=E6=8E=A5=E8=BE=B9=E7=AE=97=E6=B3=95=EF=BC=8C=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?SWITCH=E8=8A=82=E7=82=B9=E7=9A=84=E6=95=B0=E6=8D=AE=E6=94=AF?= =?UTF-8?q?=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/convertFlowData.ts | 235 ++++++++++++++++++++++++++++++----- 1 file changed, 203 insertions(+), 32 deletions(-) diff --git a/src/utils/convertFlowData.ts b/src/utils/convertFlowData.ts index 6a673eb..335d796 100644 --- a/src/utils/convertFlowData.ts +++ b/src/utils/convertFlowData.ts @@ -2,6 +2,7 @@ import { nodeTypeMap, registerNodeType } from '@/components/FlowEditor/node'; import LocalNode from '@/components/FlowEditor/node/localNode/LocalNode'; import LoopNode from '@/components/FlowEditor/node/loopNode/LoopNode'; import store from '@/store/index'; +import SwitchNode from '@/components/FlowEditor/node/switchNode/SwitchNode'; /** * 将提供的数据结构转换为适用于 flow editor 的 nodes 和 edges @@ -117,7 +118,7 @@ export const convertFlowData = (flowData: any, useDefault = true) => { // 注册其他节点类型 const nodeMap = Array.from(Object.values(nodeTypeMap).map(key => key)); if (!nodeMap.includes(nodeType) && nodeType !== 'start' && nodeType !== 'end' && nodeType !== 'LOOP') { - registerNodeType(nodeType, LocalNode, nodeConfig.componentName); + registerNodeType(nodeType, nodeType === 'SWITCH' ? SwitchNode : LocalNode, nodeConfig.componentName); } nodes.push(node); @@ -126,47 +127,41 @@ export const convertFlowData = (flowData: any, useDefault = true) => { // 用于存储已添加的边,避免重复 const addedEdges = new Set(); - // 处理连接关系 - 只处理下游连接,避免重复创建连接线 + // 创建一个映射来存储所有连接信息 + const connections = new Map(); + + // 遍历所有节点,收集连接信息 for (const entry of nodeEntries) { const nodeId: string = entry[0]; const nodeConfig: any = entry[1]; - // 处理 API 下游连接 + // 处理 API 下游连接 - 确定目标节点信息 if (nodeConfig.apiDownstream && Array.isArray(nodeConfig.apiDownstream)) { nodeConfig.apiDownstream.forEach((targetArray: string[]) => { - // 确保 targetArray 是数组并且包含字符串元素 if (Array.isArray(targetArray)) { targetArray.forEach(target => { if (typeof target === 'string' && target.includes('$$')) { const [targetNodeId, targetHandle] = target.split('$$'); - - // 动态获取源句柄,而不是使用默认值 - const sourceNode = flowData[nodeId]; - // 统一旧版本逻辑,开始节点的输出句柄是start - let sourceHandle = sourceNode.id === 'start' ? 'start' : 'done'; // 默认值 - if (sourceNode && sourceNode.component && sourceNode.component.type) { - // 根据节点类型获取正确的源句柄 - sourceHandle = getNodeApiOutHandle(nodeId, sourceNode); + const connectionKey = `${nodeId}-${targetNodeId}`; + + // 存储连接信息 + if (connections.has(connectionKey)) { + // 如果连接已存在,更新目标句柄 + const existing = connections.get(connectionKey); + if (existing) { + connections.set(connectionKey, { + ...existing, + targetHandle: targetHandle + }); + } } - else if (sourceNode && sourceNode.data && sourceNode.data.parameters && - sourceNode.data.parameters.apiOuts && sourceNode.data.parameters.apiOuts.length > 0) { - // 从apiOuts中获取第一个句柄 - sourceHandle = sourceNode.data.parameters.apiOuts[0].name || - sourceNode.data.parameters.apiOuts[0].id || sourceHandle; - } - - // 创建边的唯一标识符 - const edgeId = `${nodeId}-${targetNodeId}-${sourceHandle}-${targetHandle}`; - - // 检查是否已添加此边 - if (!addedEdges.has(edgeId)) { - addedEdges.add(edgeId); - edges.push({ - id: `${edgeId}`, + else { + // 创建新的连接信息 + connections.set(connectionKey, { source: nodeId, target: targetNodeId, - sourceHandle, - targetHandle + sourceHandle: '', // 将根据节点信息填充 + targetHandle: targetHandle }); } } @@ -175,7 +170,132 @@ export const convertFlowData = (flowData: any, useDefault = true) => { }); } - // 处理数据下游连接 + // 处理 API 上游连接 - 确定源节点信息 + if (nodeConfig.apiUpstream && Array.isArray(nodeConfig.apiUpstream)) { + nodeConfig.apiUpstream.forEach((sourceArray: string[]) => { + if (Array.isArray(sourceArray)) { + sourceArray.forEach(source => { + if (typeof source === 'string' && source.includes('$$')) { + const [sourceNodeId, sourceHandle] = source.split('$$'); + const connectionKey = `${sourceNodeId}-${nodeId}`; + + // 存储连接信息 + if (connections.has(connectionKey)) { + // 如果连接已存在,更新源句柄 + const existing = connections.get(connectionKey); + if (existing) { + connections.set(connectionKey, { + ...existing, + sourceHandle: sourceHandle + }); + } + } + else { + // 创建新的连接信息 + connections.set(connectionKey, { + source: sourceNodeId, + target: nodeId, + sourceHandle: sourceHandle, + targetHandle: '' // 将根据节点信息填充 + }); + } + } + }); + } + }); + } + } + + // 根据收集的连接信息生成实际的边 + const connectionEntries = Array.from(connections.entries()); + for (const [connectionKey, connectionInfo] of connectionEntries) { + const { source, target, sourceHandle, targetHandle } = connectionInfo; + + // 获取源节点和目标节点 + const sourceNode = flowData[source]; + const targetNode = flowData[target]; + + // 确定最终的源句柄 + let finalSourceHandle = sourceHandle; + // 如果源句柄未指定,则根据源节点信息确定 + if (!finalSourceHandle) { + if (source === 'start') { + finalSourceHandle = 'start'; + } + else if (sourceNode && sourceNode.data && sourceNode.data.parameters && + sourceNode.data.parameters.apiOuts && sourceNode.data.parameters.apiOuts.length > 0) { + // 查找匹配的目标句柄 + const matchingApiOut = sourceNode.data.parameters.apiOuts.find( + (apiOut: any) => apiOut.name === targetHandle + ); + + if (matchingApiOut) { + finalSourceHandle = matchingApiOut.name; + } + else { + // 如果没有精确匹配,使用第一个apiOut + finalSourceHandle = sourceNode.data.parameters.apiOuts[0].name; + } + } + else if (sourceNode && sourceNode.component && sourceNode.component.type) { + // 根据节点类型获取正确的源句柄 + finalSourceHandle = getNodeApiOutHandle(source, sourceNode); + } + else { + // 默认句柄 + finalSourceHandle = 'done'; + } + } + + // 确定最终的目标句柄 + let finalTargetHandle = targetHandle; + // 如果目标句柄未指定,则根据目标节点信息确定 + if (!finalTargetHandle) { + if (target === 'end') { + finalTargetHandle = 'end'; + } + else if (targetNode && targetNode.data && targetNode.data.parameters && + targetNode.data.parameters.apiIns && targetNode.data.parameters.apiIns.length > 0) { + // 查找匹配的源句柄 + const matchingApiIn = targetNode.data.parameters.apiIns.find( + (apiIn: any) => apiIn.name === sourceHandle + ); + + if (matchingApiIn) { + finalTargetHandle = matchingApiIn.name; + } + else { + // 如果没有精确匹配,使用第一个apiIn + finalTargetHandle = targetNode.data.parameters.apiIns[0].name; + } + } + else { + // 默认句柄 + finalTargetHandle = 'start'; + } + } + + // 创建边的唯一标识符 + const edgeId = `${source}-${target}-${finalSourceHandle}-${finalTargetHandle}`; + + // 检查是否已添加此边 + if (!addedEdges.has(edgeId)) { + addedEdges.add(edgeId); + edges.push({ + id: `${edgeId}`, + source: source, + target: target, + sourceHandle: finalSourceHandle, + targetHandle: finalTargetHandle + }); + } + } + + // 处理数据下游连接 + for (const entry of nodeEntries) { + const nodeId: string = entry[0]; + const nodeConfig: any = entry[1]; + if (nodeConfig.dataDownstream && Array.isArray(nodeConfig.dataDownstream)) { nodeConfig.dataDownstream.forEach((connectionGroup: string[]) => { // 确保 connectionGroup 是数组并且至少包含两个元素 @@ -382,7 +502,58 @@ const getNodeApiOuts = (nodeId: string, nodeConfig: any, currentProjectCompData: return [{ name: 'done', desc: '', dataType: '', defaultValue: '' }]; } else if (nodeConfig.component?.type === 'LOOP_END') { - return [{ name: 'break', desc: '', dataType: '', defaultValue: '' }]; + // 从customDef中获取apiOutIds数组 + try { + const customDef = JSON.parse(nodeConfig.component?.customDef || '{}'); + const apiOutIds = customDef.apiOutIds || []; + + // 从"break"开始的所有项都应该作为apiOut返回 + const breakIndex = apiOutIds.indexOf('break'); + if (breakIndex !== -1) { + // 返回从"break"开始的所有项 + return apiOutIds.slice(breakIndex).map(id => ({ + name: id, + id: id, + desc: id, + dataType: '', + defaultValue: '' + })); + } + else { + // 如果没有找到"break",则返回默认值 + return [{ name: 'break', desc: '', dataType: '', defaultValue: '' }]; + } + } catch (e) { + // 解析失败时返回默认值 + return [{ name: 'break', desc: '', dataType: '', defaultValue: '' }]; + } + } + else if (nodeConfig.component?.type === 'SWITCH') { + // 从customDef中获取apiOutIds数组 + try { + const customDef = JSON.parse(nodeConfig.component?.customDef || '{}'); + const apiOutIds = customDef.apiOutIds || []; + + // 从"break"开始的所有项都应该作为apiOut返回 + const breakIndex = apiOutIds.indexOf('default'); + if (breakIndex !== -1) { + // 返回从"break"开始的所有项 + return apiOutIds.slice(breakIndex).map(id => ({ + name: id, + id: id, + desc: id, + dataType: '', + defaultValue: '' + })); + } + else { + // 如果没有找到"break",则返回默认值 + return [{ name: 'default', desc: '', dataType: '', defaultValue: '' }]; + } + } catch (e) { + // 解析失败时返回默认值 + return [{ name: 'done', desc: '', dataType: '', defaultValue: '' }]; + } } else if (nodeId === 'start') { return [{ name: 'start', desc: '', dataType: '', defaultValue: '' }]; @@ -400,11 +571,11 @@ const getNodeApiOuts = (nodeId: string, nodeConfig: any, currentProjectCompData: return [{ name: 'done', desc: '', dataType: '', defaultValue: '' }]; } } - }; // 获取节点的API输出句柄名称 const getNodeApiOutHandle = (nodeId: string, nodeConfig: any) => { + console.log('nodeConfig:', nodeConfig); if (nodeConfig.component?.type === 'LOOP_START') { return 'done'; }