refactor(flow):重构流程回调钩子和画布数据处理逻辑

- 移除冗余的节点类型导入和相关组件引用
- 抽取画布数据处理逻辑到独立工具函数- 新增应用编排和项目编排处理工具文件
- 整合节点和边变更处理逻辑
- 优化保存流程数据到服务器的逻辑- 添加节点编辑、复制和边编辑功能
- 改进流程运行和事件更新处理机制
- 统一处理节点拖拽和对齐线显示逻辑
master
钟良源 4 months ago
parent f61fdf2b28
commit cf8d56ac9f

@ -8,56 +8,38 @@ import {
Edge Edge
} from '@xyflow/react'; } from '@xyflow/react';
import { setMainFlow } from '@/api/appRes'; import { setMainFlow } from '@/api/appRes';
import { getUserToken } from '@/api/user';
import { Message } from '@arco-design/web-react'; import { Message } from '@arco-design/web-react';
import { nodeTypeMap, registerNodeType } from '@/components/FlowEditor/node'; import { nodeTypeMap, registerNodeType } from '@/components/FlowEditor/node';
import { convertFlowData, revertFlowData } from '@/utils/convertFlowData'; import { convertFlowData, revertFlowData } from '@/utils/convertFlowData';
import { localNodeData } from '@/pages/flowEditor/sideBar/config/localNodeData'; import { localNodeData } from '@/pages/flowEditor/sideBar/config/localNodeData';
import { defaultNodeTypes } from '@/components/FlowEditor/node/types/defaultType';
import useWebSocket from '@/hooks/useWebSocket';
import { useAlignmentGuidelines } from '@/hooks/useAlignmentGuidelines'; import { useAlignmentGuidelines } from '@/hooks/useAlignmentGuidelines';
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 BasicNode from '@/components/FlowEditor/node/basicNode/BasicNode';
import SwitchNode from '@/components/FlowEditor/node/switchNode/SwitchNode';
import ImageNode from '@/components/FlowEditor/node/imageNode/ImageNode';
import CodeNode from '@/components/FlowEditor/node/codeNode/CodeNode';
import RestNode from '@/components/FlowEditor/node/restNode/RestNode';
import { updateCanvasDataMap } from '@/store/ideContainer'; import { updateCanvasDataMap } from '@/store/ideContainer';
import { import {
validateAllNodes, validateAllNodes,
showValidationErrors, showValidationErrors,
validateAllEdges validateAllEdges
} from '@/components/FlowEditor/nodeEditors/validators/nodeValidators'; } from '@/components/FlowEditor/nodeEditors/validators/nodeValidators';
import {
getHandleType,
validateDataType,
getNodeComponent
} from '@/utils/flowCommon';
import { projectFlowHandle } from '@/pages/flowEditor/utils/projectFlowHandle';
import { appFLowHandle } from '@/pages/flowEditor/utils/appFlowhandle';
import { Dispatch } from 'redux'; import { Dispatch } from 'redux';
import { runMainFlow } from '@/api/apps'; import { runMainFlow } from '@/api/apps';
import store from '@/store'; import store from '@/store';
import { updateAppEvent } from '@/api/appEvent'; import { updateAppEvent } from '@/api/appEvent';
// 根据节点类型获取对应的节点组件
const getNodeComponent = (nodeType: string) => {
switch (nodeType) {
case 'BASIC':
return BasicNode;
case 'SWITCH':
return SwitchNode;
case 'IMAGE':
return ImageNode;
case 'CODE':
return CodeNode;
case 'REST':
return RestNode;
default:
return LocalNode;
}
};
export const useFlowCallbacks = ( export const useFlowCallbacks = (
nodes: Node[], nodes: Node[],
setNodes: React.Dispatch<React.SetStateAction<Node[]>>, setNodes: React.Dispatch<React.SetStateAction<Node[]>>,
edges: Edge[], edges: Edge[],
setEdges: React.Dispatch<React.SetStateAction<Edge[]>>, setEdges: React.Dispatch<React.SetStateAction<Edge[]>>,
useDefault: boolean,
reactFlowInstance: any, reactFlowInstance: any,
canvasDataMap: any, canvasDataMap: any,
dispatch: Dispatch<any>, dispatch: Dispatch<any>,
@ -82,278 +64,188 @@ export const useFlowCallbacks = (
setIsRunning: React.Dispatch<React.SetStateAction<boolean>> setIsRunning: React.Dispatch<React.SetStateAction<boolean>>
) => { ) => {
const { getGuidelines, clearGuidelines } = useAlignmentGuidelines(); const { getGuidelines, clearGuidelines } = useAlignmentGuidelines();
// region 画布操作
// 节点变更处理,添加防抖机制
const onNodesChange = useCallback((changes: any) => {
// 深度克隆节点数组以避免修改冻结的对象
const clonedNodes = JSON.parse(JSON.stringify(nodes));
const newNodes = applyNodeChanges(changes, clonedNodes);
setNodes(newNodes);
// 如果需要在节点变化时执行某些操作,可以在这里添加
// 只有当变化是节点位置变化时才不立即记录历史
const isPositionChange = changes.some((change: any) =>
change.type === 'position' && change.dragging === false
);
// 如果是位置变化结束或者不是位置变化,则记录历史
if (isPositionChange || !changes.some((change: any) => change.type === 'position')) {
// 清除之前的定时器
if (historyTimeoutRef.current) {
clearTimeout(historyTimeoutRef.current);
}
// 获取handle类型 (api或data) // 设置新的定时器,延迟记录历史记录
const getHandleType = (handleId: string, nodeParams: any) => { historyTimeoutRef.current = setTimeout(() => {
// 检查是否为api类型的handle const event = new CustomEvent('takeSnapshot', {
const apiOuts = nodeParams.apiOuts || []; detail: { nodes: [...newNodes], edges: [...edges] }
const apiIns = nodeParams.apiIns || []; });
document.dispatchEvent(event);
if (apiOuts.some((api: any) => (api.name || api.id) === handleId) || }, 100);
apiIns.some((api: any) => (api.name || api.id) === handleId) || (handleId.includes('loop'))) {
return 'api';
} }
}, [nodes, edges]);
// 边变更处理
const onEdgesChange = useCallback((changes: any) => {
const newEdges = applyEdgeChanges(changes, edges);
setEdges(newEdges);
// 如果需要在边变化时执行某些操作,可以在这里添加
// 检查是否为data类型的handle // 边的变化立即记录历史
const dataOuts = nodeParams.dataOuts || []; const event = new CustomEvent('takeSnapshot', {
const dataIns = nodeParams.dataIns || []; detail: { nodes: [...nodes], edges: [...newEdges] }
});
document.dispatchEvent(event);
}, [edges, nodes]);
// 节点删除处理
const onNodesDelete = useCallback((deletedNodes: any) => {
setIsDelete(true);
}, []);
// 边连接处理
const onConnect = useCallback((params: any) => {
// 获取源节点和目标节点
const sourceNode = nodes.find(node => node.id === params.source);
const targetNode = nodes.find(node => node.id === params.target);
if (dataOuts.some((data: any) => (data.name || data.id) === handleId) || // 如果找不到节点,不创建连接
dataIns.some((data: any) => (data.name || data.id) === handleId)) { if (!sourceNode || !targetNode) {
return 'data'; return;
} }
// 默认为data类型 // 获取源节点和目标节点的参数信息
return 'data';
};
// 验证数据类型是否匹配
const validateDataType = (sourceNode: defaultNodeTypes, targetNode: defaultNodeTypes, sourceHandleId: string, targetHandleId: string) => {
const sourceParams = sourceNode.data?.parameters || {}; const sourceParams = sourceNode.data?.parameters || {};
const targetParams = targetNode.data?.parameters || {}; const targetParams = targetNode.data?.parameters || {};
// 获取源节点的输出参数 // 获取源handle和目标handle的类型 (api或data)
let sourceDataType = ''; const sourceHandleType = getHandleType(params.sourceHandle, sourceParams);
const sourceApiOuts = sourceParams.apiOuts || []; const targetHandleType = getHandleType(params.targetHandle, targetParams);
const sourceDataOuts = sourceParams.dataOuts || [];
// 查找源handle的数据类型
const sourceApi = sourceApiOuts.find((api: any) => api.name === sourceHandleId);
const sourceData = sourceDataOuts.find((data: any) => data.name === sourceHandleId);
if (sourceApi) { // 验证连接类型是否匹配 (api只能连api, data只能连data)
sourceDataType = sourceApi.dataType || ''; if (sourceHandleType !== targetHandleType) {
} console.warn('连接类型不匹配: ', sourceHandleType, targetHandleType);
else if (sourceData) { return;
sourceDataType = sourceData.dataType || '';
}
// 获取目标节点的输入参数
let targetDataType = '';
const targetApiIns = targetParams.apiIns || [];
const targetDataIns = targetParams.dataIns || [];
// 查找目标handle的数据类型
const targetApi = targetApiIns.find((api: any) => api.name === targetHandleId);
const targetData = targetDataIns.find((data: any) => data.name === targetHandleId);
if (targetApi) {
targetDataType = targetApi.dataType || '';
}
else if (targetData) {
targetDataType = targetData.dataType || '';
} }
// 如果任一数据类型为空,则允许连接 // 验证数据类型是否匹配
if (!sourceDataType || !targetDataType) { if (!validateDataType(sourceNode, targetNode, params.sourceHandle, params.targetHandle)) {
return true; console.warn('数据类型不匹配');
return;
} }
// 比较数据类型是否匹配 // 如果验证通过,创建连接
return sourceDataType === targetDataType; setEdges((edgesSnapshot: Edge[]) => {
}; const newEdges = addEdge({ ...params, type: 'custom' }, edgesSnapshot);
// onNodesChange 函数,添加防抖机制
const onNodesChange = useCallback(
(changes: any) => {
// 深度克隆节点数组以避免修改冻结的对象
const clonedNodes = JSON.parse(JSON.stringify(nodes));
const newNodes = applyNodeChanges(changes, clonedNodes);
setNodes(newNodes);
// 如果需要在节点变化时执行某些操作,可以在这里添加
// 只有当变化是节点位置变化时才不立即记录历史
const isPositionChange = changes.some((change: any) =>
change.type === 'position' && change.dragging === false
);
// 如果是位置变化结束或者不是位置变化,则记录历史
if (isPositionChange || !changes.some((change: any) => change.type === 'position')) {
// 清除之前的定时器
if (historyTimeoutRef.current) {
clearTimeout(historyTimeoutRef.current);
}
// 设置新的定时器,延迟记录历史记录
historyTimeoutRef.current = setTimeout(() => {
const event = new CustomEvent('takeSnapshot', {
detail: { nodes: [...newNodes], edges: [...edges] }
});
document.dispatchEvent(event);
}, 100);
}
},
[nodes, edges]
);
// onEdgesChange 函数
const onEdgesChange = useCallback(
(changes: any) => {
const newEdges = applyEdgeChanges(changes, edges);
setEdges(newEdges);
// 如果需要在边变化时执行某些操作,可以在这里添加
// 边的变化立即记录历史
const event = new CustomEvent('takeSnapshot', {
detail: { nodes: [...nodes], edges: [...newEdges] }
});
document.dispatchEvent(event);
},
[edges, nodes]
);
const onNodesDelete = useCallback((deletedNodes: any) => {
setIsDelete(true);
}, []);
// onConnect 函数
const onConnect = useCallback(
(params: any) => {
// 获取源节点和目标节点
const sourceNode = nodes.find(node => node.id === params.source);
const targetNode = nodes.find(node => node.id === params.target);
// 如果找不到节点,不创建连接
if (!sourceNode || !targetNode) {
return;
}
// 获取源节点和目标节点的参数信息
const sourceParams = sourceNode.data?.parameters || {};
const targetParams = targetNode.data?.parameters || {};
// 获取源handle和目标handle的类型 (api或data)
const sourceHandleType = getHandleType(params.sourceHandle, sourceParams);
const targetHandleType = getHandleType(params.targetHandle, targetParams);
// 验证连接类型是否匹配 (api只能连api, data只能连data)
if (sourceHandleType !== targetHandleType) {
console.warn('连接类型不匹配: ', sourceHandleType, targetHandleType);
return;
}
// 验证数据类型是否匹配 // 连接建立后记录历史
if (!validateDataType(sourceNode, targetNode, params.sourceHandle, params.targetHandle)) { setTimeout(() => {
console.warn('数据类型不匹配'); const event = new CustomEvent('takeSnapshot', {
return; detail: { nodes: [...nodes], edges: [...newEdges] }
} });
document.dispatchEvent(event);
// 如果验证通过,创建连接 }, 0);
setEdges((edgesSnapshot: Edge[]) => {
const newEdges = addEdge({ ...params, type: 'custom' }, edgesSnapshot);
// 连接建立后记录历史
setTimeout(() => {
const event = new CustomEvent('takeSnapshot', {
detail: { nodes: [...nodes], edges: [...newEdges] }
});
document.dispatchEvent(event);
}, 0);
return newEdges;
});
},
[nodes]
);
return newEdges;
});
}, [nodes]);
// 边重新连接处理 // 边重新连接处理
const onReconnect = useCallback( const onReconnect = useCallback((oldEdge: Edge, newConnection: any) => {
(oldEdge: Edge, newConnection: any) => { // 获取源节点和目标节点
// 获取源节点和目标节点 const sourceNode = nodes.find(node => node.id === newConnection.source);
const sourceNode = nodes.find(node => node.id === newConnection.source); const targetNode = nodes.find(node => node.id === newConnection.target);
const targetNode = nodes.find(node => node.id === newConnection.target);
// 如果找不到节点,不创建连接
if (!sourceNode || !targetNode) {
return;
}
// 获取源节点和目标节点的参数信息 // 如果找不到节点,不创建连接
const sourceParams = sourceNode.data?.parameters || {}; if (!sourceNode || !targetNode) {
const targetParams = targetNode.data?.parameters || {}; return;
}
// 获取源handle和目标handle的类型 (api或data) // 获取源节点和目标节点的参数信息
const sourceHandleType = getHandleType(newConnection.sourceHandle, sourceParams); const sourceParams = sourceNode.data?.parameters || {};
const targetHandleType = getHandleType(newConnection.targetHandle, targetParams); const targetParams = targetNode.data?.parameters || {};
// 验证连接类型是否匹配 (api只能连api, data只能连data) // 获取源handle和目标handle的类型 (api或data)
if (sourceHandleType !== targetHandleType) { const sourceHandleType = getHandleType(newConnection.sourceHandle, sourceParams);
console.warn('连接类型不匹配: ', sourceHandleType, targetHandleType); const targetHandleType = getHandleType(newConnection.targetHandle, targetParams);
return;
}
// 验证数据类型是否匹配 // 验证连接类型是否匹配 (api只能连api, data只能连data)
if (!validateDataType(sourceNode, targetNode, newConnection.sourceHandle, newConnection.targetHandle)) { if (sourceHandleType !== targetHandleType) {
console.warn('数据类型不匹配'); console.warn('连接类型不匹配: ', sourceHandleType, targetHandleType);
return; return;
} }
// 如果验证通过,重新连接 // 验证数据类型是否匹配
setEdges((els) => reconnectEdge(oldEdge, newConnection, els)); if (!validateDataType(sourceNode, targetNode, newConnection.sourceHandle, newConnection.targetHandle)) {
}, console.warn('数据类型不匹配');
[nodes] return;
); }
// 如果验证通过,重新连接
setEdges((els) => reconnectEdge(oldEdge, newConnection, els));
}, [nodes]);
// 拖动处理
const onDragOver = useCallback((event: React.DragEvent) => { const onDragOver = useCallback((event: React.DragEvent) => {
event.preventDefault(); event.preventDefault();
event.dataTransfer.dropEffect = 'move'; event.dataTransfer.dropEffect = 'move';
}, []); }, []);
// 侧边栏节点实例 // 侧边栏节点实例
const onDrop = useCallback( const onDrop = useCallback((event: React.DragEvent) => {
(event: React.DragEvent) => { event.preventDefault();
event.preventDefault();
if (!reactFlowInstance) return;
const callBack = event.dataTransfer.getData('application/reactflow'); if (!reactFlowInstance) return;
const nodeData = JSON.parse(callBack);
if (typeof nodeData.nodeType === 'undefined' || !nodeData.nodeType) {
return;
}
const position = reactFlowInstance.screenToFlowPosition({ const callBack = event.dataTransfer.getData('application/reactflow');
x: event.clientX, const nodeData = JSON.parse(callBack);
y: event.clientY if (typeof nodeData.nodeType === 'undefined' || !nodeData.nodeType) {
}); return;
}
// 特殊处理循环节点,添加开始和结束节点 const position = reactFlowInstance.screenToFlowPosition({
if (nodeData.nodeType === 'LOOP') { x: event.clientX,
addLoopNodeWithStartEnd(position, nodeData); y: event.clientY
return; });
}
const newNode = { // 特殊处理循环节点,添加开始和结束节点
id: `${nodeData.nodeType}-${Date.now()}`, if (nodeData.nodeType === 'LOOP') {
type: nodeData.nodeType, addLoopNodeWithStartEnd(position, nodeData);
position, return;
data: { ...nodeData.data, title: nodeData.nodeName, type: nodeData.nodeType } }
};
// 将未定义的节点动态追加进nodeTypes const newNode = {
const nodeMap = Array.from(Object.values(nodeTypeMap).map(key => key)); id: `${nodeData.nodeType}-${Date.now()}`,
// 目前默认添加的都是系统组件/本地组件 type: nodeData.nodeType,
if (!nodeMap.includes(nodeData.nodeType)) { position,
registerNodeType(nodeData.nodeType, LocalNode, nodeData.nodeName); data: { ...nodeData.data, title: nodeData.nodeName, type: nodeData.nodeType }
} };
setNodes((nds: Node[]) => { // 将未定义的节点动态追加进nodeTypes
const newNodes = nds.concat(newNode); const nodeMap = Array.from(Object.values(nodeTypeMap).map(key => key));
// 目前默认添加的都是系统组件/本地组件
if (!nodeMap.includes(nodeData.nodeType)) {
registerNodeType(nodeData.nodeType, LocalNode, nodeData.nodeName);
}
// 添加节点后记录历史 setNodes((nds: Node[]) => {
setTimeout(() => { const newNodes = nds.concat(newNode);
const event = new CustomEvent('takeSnapshot', {
detail: { nodes: [...newNodes], edges: [...edges] }
});
document.dispatchEvent(event);
}, 0);
return newNodes; // 添加节点后记录历史
}); setTimeout(() => {
}, const event = new CustomEvent('takeSnapshot', {
[reactFlowInstance, edges] detail: { nodes: [...newNodes], edges: [...edges] }
); });
document.dispatchEvent(event);
}, 0);
return newNodes;
});
}, [reactFlowInstance, edges]);
// 添加循环节点及其开始和结束节点 // 添加循环节点及其开始和结束节点
const addLoopNodeWithStartEnd = useCallback((position: { x: number, y: number }, nodeData: any) => { const addLoopNodeWithStartEnd = useCallback((position: { x: number, y: number }, nodeData: any) => {
// 创建循环开始节点 // 创建循环开始节点
@ -458,21 +350,19 @@ export const useFlowCallbacks = (
return updatedEdges; return updatedEdges;
}); });
}, [nodes, edges]); }, [nodes, edges]);
// 节点拖拽处理
const onNodeDrag = useCallback( const onNodeDrag = useCallback((_: any, node: Node) => {
(_: any, node: Node) => { // 获取对齐线
// 获取对齐线 getGuidelines(node, nodes);
getGuidelines(node, nodes); }, [nodes, getGuidelines]);
},
[nodes, getGuidelines]
);
// 节点拖拽结束处理 // 节点拖拽结束处理
const onNodeDragStop = useCallback(() => { const onNodeDragStop = useCallback(() => {
// 清除对齐线 // 清除对齐线
clearGuidelines(); clearGuidelines();
}, [clearGuidelines]); }, [clearGuidelines]);
// endregion
// region 画布数据处理
// 初始化画布数据 // 初始化画布数据
const initializeCanvasData = useCallback(() => { const initializeCanvasData = useCallback(() => {
if (canvasDataMap[initialData?.appId]) { if (canvasDataMap[initialData?.appId]) {
@ -482,30 +372,13 @@ export const useFlowCallbacks = (
} }
else { else {
// 首次进入 // 首次进入
const { nodes: convertedNodes, edges: convertedEdges } = convertFlowData(initialData?.main.components, true); if (useDefault) projectFlowHandle(initialData, useDefault, setNodes, setEdges, dispatch, canvasDataMap);
else appFLowHandle(initialData, useDefault, setNodes, setEdges, dispatch);
// return;
// 为所有边添加类型
const initialEdges: Edge[] = convertedEdges.map(edge => ({
...edge,
type: 'custom'
}));
setNodes(convertedNodes);
setEdges(initialEdges);
if (initialData?.appId) {
dispatch(updateCanvasDataMap({
...canvasDataMap,
[initialData.appId]: { nodes: convertedNodes, edges: initialEdges }
}));
}
} }
// 标记历史记录已初始化 // 标记历史记录已初始化
setHistoryInitialized(true); setHistoryInitialized(true);
}, [initialData, canvasDataMap]); }, [initialData, canvasDataMap]);
// 实时更新 canvasDataMap // 实时更新 canvasDataMap
const updateCanvasDataMapEffect = useCallback(() => { const updateCanvasDataMapEffect = useCallback(() => {
if (initialData?.appId) { if (initialData?.appId) {
@ -517,13 +390,11 @@ export const useFlowCallbacks = (
// 取消防抖函数 // 取消防抖函数
}; };
}, [nodes, edges, initialData?.appId, dispatch, canvasDataMap]); }, [nodes, edges, initialData?.appId, dispatch, canvasDataMap]);
// 关闭编辑弹窗 // 关闭编辑弹窗
const closeEditModal = useCallback(() => { const closeEditModal = useCallback(() => {
setIsEditModalOpen(false); setIsEditModalOpen(false);
setEditingNode(null); setEditingNode(null);
}, []); }, []);
// 保存节点编辑 // 保存节点编辑
const saveNodeEdit = useCallback((updatedData: any) => { const saveNodeEdit = useCallback((updatedData: any) => {
console.log('updatedData:', updatedData); console.log('updatedData:', updatedData);
@ -540,7 +411,24 @@ export const useFlowCallbacks = (
setNodes(updatedNodes); setNodes(updatedNodes);
closeEditModal(); closeEditModal();
}, [nodes, editingNode, closeEditModal]); }, [nodes, editingNode, closeEditModal]);
// 编辑节点
const editNode = useCallback((node: Node) => {
setEditingNode(node);
setIsEditModalOpen(true);
}, []);
// 编辑边
const editEdge = useCallback((edge: Edge) => {
// 这里可以实现边编辑逻辑
console.log('编辑边:', edge);
}, []);
// 复制节点
const copyNode = useCallback((node: Node) => {
// 这里可以实现节点复制逻辑
console.log('复制节点:', node);
}, []);
// endregion
// region 节点/边操作
// 删除节点函数 // 删除节点函数
const deleteNode = useCallback((node: Node) => { const deleteNode = useCallback((node: Node) => {
@ -558,7 +446,6 @@ export const useFlowCallbacks = (
document.dispatchEvent(event); document.dispatchEvent(event);
}, 0); }, 0);
}, [nodes, edges]); }, [nodes, edges]);
// 删除边函数 // 删除边函数
const deleteEdge = useCallback((edge: Edge) => { const deleteEdge = useCallback((edge: Edge) => {
setEdges((eds: Edge[]) => eds.filter((e) => e.id !== edge.id)); setEdges((eds: Edge[]) => eds.filter((e) => e.id !== edge.id));
@ -574,25 +461,6 @@ export const useFlowCallbacks = (
document.dispatchEvent(event); document.dispatchEvent(event);
}, 0); }, 0);
}, [nodes, edges]); }, [nodes, edges]);
// 编辑节点
const editNode = useCallback((node: Node) => {
setEditingNode(node);
setIsEditModalOpen(true);
}, []);
// 编辑边
const editEdge = useCallback((edge: Edge) => {
// 这里可以实现边编辑逻辑
console.log('编辑边:', edge);
}, []);
// 复制节点
const copyNode = useCallback((node: Node) => {
// 这里可以实现节点复制逻辑
console.log('复制节点:', node);
}, []);
// 在边上添加节点的具体实现 // 在边上添加节点的具体实现
const addNodeOnEdge = useCallback((nodeType: string, node: any) => { const addNodeOnEdge = useCallback((nodeType: string, node: any) => {
if (!edgeForNodeAdd || !reactFlowInstance) return; if (!edgeForNodeAdd || !reactFlowInstance) return;
@ -859,7 +727,6 @@ export const useFlowCallbacks = (
document.dispatchEvent(event); document.dispatchEvent(event);
}, 0); }, 0);
}, [edgeForNodeAdd, nodes, reactFlowInstance, edges, addLoopNodeWithStartEnd]); }, [edgeForNodeAdd, nodes, reactFlowInstance, edges, addLoopNodeWithStartEnd]);
// 在画布上添加节点 // 在画布上添加节点
const addNodeOnPane = useCallback((nodeType: string, position: { x: number; y: number }, node?: any) => { const addNodeOnPane = useCallback((nodeType: string, position: { x: number; y: number }, node?: any) => {
if (!reactFlowInstance) return; if (!reactFlowInstance) return;
@ -926,7 +793,6 @@ export const useFlowCallbacks = (
return newNodes; return newNodes;
}); });
}, [reactFlowInstance, edges, addLoopNodeWithStartEnd]); }, [reactFlowInstance, edges, addLoopNodeWithStartEnd]);
// 处理添加节点的统一方法 // 处理添加节点的统一方法
const handleAddNode = useCallback((nodeType: string, node: any) => { const handleAddNode = useCallback((nodeType: string, node: any) => {
// 如果是通过边添加节点 // 如果是通过边添加节点
@ -942,43 +808,9 @@ export const useFlowCallbacks = (
setEdgeForNodeAdd(null); setEdgeForNodeAdd(null);
setPositionForNodeAdd(null); setPositionForNodeAdd(null);
}, [edgeForNodeAdd, positionForNodeAdd, addNodeOnEdge, addNodeOnPane]); }, [edgeForNodeAdd, positionForNodeAdd, addNodeOnEdge, addNodeOnPane]);
// endregion
// 保存所有节点和边数据到服务器 // 保存所有节点和边数据到服务器,更新事件相关数据
const saveFlowDataToServer = useCallback(async () => {
try {
// 首先校验所有节点数据是否完整
const nodeValidation = validateAllNodes(nodes);
if (!nodeValidation.isValid) {
showValidationErrors(nodeValidation.errors);
return;
}
// 然后校验所有连接线是否有效
const edgeValidation = validateAllEdges(edges, nodes);
if (!edgeValidation.isValid) {
showValidationErrors(edgeValidation.errors);
return;
}
// 转换会原始数据类型
const revertedData = revertFlowData(nodes, edges);
console.log('revertedData(中断):', revertedData);
// return;
updateEvent(revertedData.nodeConfigs);
const res: any = await setMainFlow(revertedData, initialData.appId);
if (res.code === 200) {
Message.success('保存成功');
}
else {
Message.error(res.message);
}
} catch (error) {
console.error('Error saving flow data:', error);
Message.error('保存失败');
}
}, [nodes, edges, initialData?.appId]);
const updateEvent = (revertedData) => { const updateEvent = (revertedData) => {
// 初始化参数对象 // 初始化参数对象
const params: any = { const params: any = {
@ -1034,8 +866,49 @@ export const useFlowCallbacks = (
updateAppEvent(initialData.appId, params); updateAppEvent(initialData.appId, params);
} }
}; };
const saveFlowDataToServer = useCallback(async () => {
if (useDefault) {
try {
// 首先校验所有节点数据是否完整
const nodeValidation = validateAllNodes(nodes);
if (!nodeValidation.isValid) {
showValidationErrors(nodeValidation.errors);
return;
}
// 然后校验所有连接线是否有效
const edgeValidation = validateAllEdges(edges, nodes);
if (!edgeValidation.isValid) {
showValidationErrors(edgeValidation.errors);
return;
}
// 转换会原始数据类型
const revertedData = revertFlowData(nodes, edges);
console.log('revertedData(中断):', revertedData);
// return;
updateEvent(revertedData.nodeConfigs);
const res: any = await setMainFlow(revertedData, initialData.appId);
if (res.code === 200) {
Message.success('保存成功');
}
else {
Message.error(res.message);
}
} catch (error) {
console.error('Error saving flow data:', error);
Message.error('保存失败');
}
}
else {
const params = {
nodes,
edges
};
console.log('params:', params);
}
}, [nodes, edges, initialData?.appId]);
// 运行处理函数 // 运行处理函数
const handleRun = useCallback(async (running: boolean) => { const handleRun = useCallback(async (running: boolean) => {
if (running) { if (running) {
@ -1084,10 +957,6 @@ export const useFlowCallbacks = (
// Actions // Actions
saveFlowDataToServer, saveFlowDataToServer,
handleRun, handleRun
// Utilities
getHandleType,
validateDataType
}; };
}; };

@ -0,0 +1,35 @@
/*
*
* */
import { convertAppFlowData } from '@/utils/convertAppFlowData';
import { convertFlowData } from '@/utils/convertFlowData';
import { Edge } from '@xyflow/react';
import { updateCanvasDataMap } from '@/store/ideContainer';
export const appFLowHandle = (initialData, useDefault, setNodes, setEdges, dispatch) => {
console.log('应用编排处理', initialData);
const {
nodes: convertedNodes,
edges: convertedEdges
} = convertAppFlowData(initialData);
console.log('nodes:', convertedNodes);
console.log('edges:', convertedEdges);
// 为所有边添加类型
const initialEdges: Edge[] = convertedEdges.map(edge => ({
...edge,
type: 'custom'
}));
setNodes(convertedNodes);
setEdges(initialEdges);
// if (initialData?.appId) {
// dispatch(updateCanvasDataMap({
// ...canvasDataMap,
// [initialData.appId]: { nodes: convertedNodes, edges: initialEdges }
// }));
// }
};

@ -0,0 +1,30 @@
/*
*
* */
// 组件编排画布数据处理(组件编排)
import { convertFlowData } from '@/utils/convertFlowData';
import { Edge } from '@xyflow/react';
import { updateCanvasDataMap } from '@/store/ideContainer';
export const projectFlowHandle = (initialData, useDefault, setNodes, setEdges, dispatch, canvasDataMap) => {
const {
nodes: convertedNodes,
edges: convertedEdges
} = convertFlowData(initialData?.main.components, useDefault);
// 为所有边添加类型
const initialEdges: Edge[] = convertedEdges.map(edge => ({
...edge,
type: 'custom'
}));
setNodes(convertedNodes);
setEdges(initialEdges);
if (initialData?.appId) {
dispatch(updateCanvasDataMap({
...canvasDataMap,
[initialData.appId]: { nodes: convertedNodes, edges: initialEdges }
}));
}
};
Loading…
Cancel
Save