refactor(flow): 重构连接边算法,增加SWITCH节点的数据支持

master
钟良源 4 months ago
parent e6f5f035bb
commit bfe24c7dfc

@ -2,6 +2,7 @@ import { nodeTypeMap, registerNodeType } from '@/components/FlowEditor/node';
import LocalNode from '@/components/FlowEditor/node/localNode/LocalNode'; import LocalNode from '@/components/FlowEditor/node/localNode/LocalNode';
import LoopNode from '@/components/FlowEditor/node/loopNode/LoopNode'; import LoopNode from '@/components/FlowEditor/node/loopNode/LoopNode';
import store from '@/store/index'; import store from '@/store/index';
import SwitchNode from '@/components/FlowEditor/node/switchNode/SwitchNode';
/** /**
* flow editor nodes edges * 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)); const nodeMap = Array.from(Object.values(nodeTypeMap).map(key => key));
if (!nodeMap.includes(nodeType) && nodeType !== 'start' && nodeType !== 'end' && nodeType !== 'LOOP') { 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); nodes.push(node);
@ -126,56 +127,175 @@ export const convertFlowData = (flowData: any, useDefault = true) => {
// 用于存储已添加的边,避免重复 // 用于存储已添加的边,避免重复
const addedEdges = new Set<string>(); const addedEdges = new Set<string>();
// 处理连接关系 - 只处理下游连接,避免重复创建连接线 // 创建一个映射来存储所有连接信息
const connections = new Map<string, { source: string; target: string; sourceHandle: string; targetHandle: string }>();
// 遍历所有节点,收集连接信息
for (const entry of nodeEntries) { for (const entry of nodeEntries) {
const nodeId: string = entry[0]; const nodeId: string = entry[0];
const nodeConfig: any = entry[1]; const nodeConfig: any = entry[1];
// 处理 API 下游连接 // 处理 API 下游连接 - 确定目标节点信息
if (nodeConfig.apiDownstream && Array.isArray(nodeConfig.apiDownstream)) { if (nodeConfig.apiDownstream && Array.isArray(nodeConfig.apiDownstream)) {
nodeConfig.apiDownstream.forEach((targetArray: string[]) => { nodeConfig.apiDownstream.forEach((targetArray: string[]) => {
// 确保 targetArray 是数组并且包含字符串元素
if (Array.isArray(targetArray)) { if (Array.isArray(targetArray)) {
targetArray.forEach(target => { targetArray.forEach(target => {
if (typeof target === 'string' && target.includes('$$')) { if (typeof target === 'string' && target.includes('$$')) {
const [targetNodeId, targetHandle] = target.split('$$'); const [targetNodeId, targetHandle] = target.split('$$');
const connectionKey = `${nodeId}-${targetNodeId}`;
// 存储连接信息
if (connections.has(connectionKey)) {
// 如果连接已存在,更新目标句柄
const existing = connections.get(connectionKey);
if (existing) {
connections.set(connectionKey, {
...existing,
targetHandle: targetHandle
});
}
}
else {
// 创建新的连接信息
connections.set(connectionKey, {
source: nodeId,
target: targetNodeId,
sourceHandle: '', // 将根据节点信息填充
targetHandle: targetHandle
});
}
}
});
}
});
}
// 动态获取源句柄,而不是使用默认值 // 处理 API 上游连接 - 确定源节点信息
const sourceNode = flowData[nodeId]; if (nodeConfig.apiUpstream && Array.isArray(nodeConfig.apiUpstream)) {
// 统一旧版本逻辑开始节点的输出句柄是start nodeConfig.apiUpstream.forEach((sourceArray: string[]) => {
let sourceHandle = sourceNode.id === 'start' ? 'start' : 'done'; // 默认值 if (Array.isArray(sourceArray)) {
if (sourceNode && sourceNode.component && sourceNode.component.type) { sourceArray.forEach(source => {
// 根据节点类型获取正确的源句柄 if (typeof source === 'string' && source.includes('$$')) {
sourceHandle = getNodeApiOutHandle(nodeId, sourceNode); 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 && else if (sourceNode && sourceNode.data && sourceNode.data.parameters &&
sourceNode.data.parameters.apiOuts && sourceNode.data.parameters.apiOuts.length > 0) { sourceNode.data.parameters.apiOuts && sourceNode.data.parameters.apiOuts.length > 0) {
// 从apiOuts中获取第一个句柄 // 查找匹配的目标句柄
sourceHandle = sourceNode.data.parameters.apiOuts[0].name || const matchingApiOut = sourceNode.data.parameters.apiOuts.find(
sourceNode.data.parameters.apiOuts[0].id || sourceHandle; (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 = `${nodeId}-${targetNodeId}-${sourceHandle}-${targetHandle}`; const edgeId = `${source}-${target}-${finalSourceHandle}-${finalTargetHandle}`;
// 检查是否已添加此边 // 检查是否已添加此边
if (!addedEdges.has(edgeId)) { if (!addedEdges.has(edgeId)) {
addedEdges.add(edgeId); addedEdges.add(edgeId);
edges.push({ edges.push({
id: `${edgeId}`, id: `${edgeId}`,
source: nodeId, source: source,
target: targetNodeId, target: target,
sourceHandle, sourceHandle: finalSourceHandle,
targetHandle targetHandle: finalTargetHandle
});
}
}
}); });
} }
});
} }
// 处理数据下游连接 // 处理数据下游连接
for (const entry of nodeEntries) {
const nodeId: string = entry[0];
const nodeConfig: any = entry[1];
if (nodeConfig.dataDownstream && Array.isArray(nodeConfig.dataDownstream)) { if (nodeConfig.dataDownstream && Array.isArray(nodeConfig.dataDownstream)) {
nodeConfig.dataDownstream.forEach((connectionGroup: string[]) => { nodeConfig.dataDownstream.forEach((connectionGroup: string[]) => {
// 确保 connectionGroup 是数组并且至少包含两个元素 // 确保 connectionGroup 是数组并且至少包含两个元素
@ -382,8 +502,59 @@ const getNodeApiOuts = (nodeId: string, nodeConfig: any, currentProjectCompData:
return [{ name: 'done', desc: '', dataType: '', defaultValue: '' }]; return [{ name: 'done', desc: '', dataType: '', defaultValue: '' }];
} }
else if (nodeConfig.component?.type === 'LOOP_END') { else if (nodeConfig.component?.type === 'LOOP_END') {
// 从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: '' }]; 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') { else if (nodeId === 'start') {
return [{ name: 'start', desc: '', dataType: '', defaultValue: '' }]; return [{ name: 'start', desc: '', dataType: '', defaultValue: '' }];
} }
@ -400,11 +571,11 @@ const getNodeApiOuts = (nodeId: string, nodeConfig: any, currentProjectCompData:
return [{ name: 'done', desc: '', dataType: '', defaultValue: '' }]; return [{ name: 'done', desc: '', dataType: '', defaultValue: '' }];
} }
} }
}; };
// 获取节点的API输出句柄名称 // 获取节点的API输出句柄名称
const getNodeApiOutHandle = (nodeId: string, nodeConfig: any) => { const getNodeApiOutHandle = (nodeId: string, nodeConfig: any) => {
console.log('nodeConfig:', nodeConfig);
if (nodeConfig.component?.type === 'LOOP_START') { if (nodeConfig.component?.type === 'LOOP_START') {
return 'done'; return 'done';
} }

Loading…
Cancel
Save