diff --git a/src/hooks/useFlowCallbacks.ts b/src/hooks/useFlowCallbacks.ts index b6e7a53..c7ea3e8 100644 --- a/src/hooks/useFlowCallbacks.ts +++ b/src/hooks/useFlowCallbacks.ts @@ -501,7 +501,79 @@ export const useFlowCallbacks = ( // region 节点/边操作 // 删除节点函数 const deleteNode = useCallback((node: Node) => { + // 开始和结束节点不允许删除 + if (node.type === 'start' || node.type === 'end') { + console.warn('开始和结束节点不允许删除'); + return; + } + + // 处理循环节点删除逻辑 + if (node.data?.type === 'LOOP_START' || node.data?.type === 'LOOP_END') { + // 获取关联的另一个循环节点 + let relatedNodeId = null; + + // 类型断言,将component从unknown转换为具有customDef属性的对象 + const component = node.data?.component as { customDef?: string } | undefined; + + if (node.data?.type === 'LOOP_START' && component?.customDef) { + try { + const customDef = JSON.parse(component.customDef); + relatedNodeId = customDef.loopEndNodeId; + } catch (e) { + console.error('解析循环开始节点数据失败:', e); + } + } else if (node.data?.type === 'LOOP_END' && component?.customDef) { + try { + const customDef = JSON.parse(component.customDef); + relatedNodeId = customDef.loopStartNodeId; + } catch (e) { + console.error('解析循环结束节点数据失败:', e); + } + } + + // 删除两个节点及相关边 + setNodes((nds: Node[]) => { + const updatedNodes = nds.filter((n) => + n.id !== node.id && n.id !== relatedNodeId + ); + return updatedNodes; + }); + + setEdges((eds: Edge[]) => { + const updatedEdges = eds.filter((e) => + e.source !== node.id && + e.target !== node.id && + e.source !== relatedNodeId && + e.target !== relatedNodeId + ); + return updatedEdges; + }); + + // 删除节点后记录历史 + setTimeout(() => { + const updatedNodes = nodes.filter((n) => + n.id !== node.id && n.id !== relatedNodeId + ); + const updatedEdges = edges.filter((e) => + e.source !== node.id && + e.target !== node.id && + e.source !== relatedNodeId && + e.target !== relatedNodeId + ); + + const event = new CustomEvent('takeSnapshot', { + detail: { + nodes: [...updatedNodes], + edges: [...updatedEdges] + } + }); + document.dispatchEvent(event); + }, 0); + + return; + } + // 普通节点删除逻辑 setNodes((nds: Node[]) => nds.filter((n) => n.id !== node.id)); setEdges((eds: Edge[]) => eds.filter((e) => e.source !== node.id && e.target !== node.id)); diff --git a/src/pages/flowEditor/FlowEditorMain.tsx b/src/pages/flowEditor/FlowEditorMain.tsx index 6e02e39..8f178cf 100644 --- a/src/pages/flowEditor/FlowEditorMain.tsx +++ b/src/pages/flowEditor/FlowEditorMain.tsx @@ -35,7 +35,7 @@ interface FlowEditorMainProps { nodeTypes: NodeTypes; setNodes: React.Dispatch>; setEdges: React.Dispatch>; - useDefault:boolean; + useDefault: boolean; reactFlowInstance: any; reactFlowWrapper: React.RefObject; menu: any; @@ -184,8 +184,79 @@ const FlowEditorMain: React.FC = (props) => { edgeTypes={edgeTypes} snapToGrid={true} snapGrid={[2, 2]} + onBeforeDelete={async ({ nodes }) => { + // 检查是否有开始或结束节点 + const hasStartOrEndNode = nodes.some(node => node.type === 'start' || node.type === 'end'); + if (hasStartOrEndNode) { + console.warn('开始和结束节点不允许删除'); + return false; // 阻止删除操作 + } + + // 检查是否有循环节点(这里只是检查,实际删除逻辑在onNodesDelete中处理) + const loopNodes = nodes.filter(node => + node.data?.type === 'LOOP_START' || node.data?.type === 'LOOP_END' + ); + + // 允许删除操作继续进行 + return true; + }} onNodesDelete={(deleted) => { - setNodes((nds) => nds.filter((n) => !deleted.find((d) => d.id === n.id))); + console.log('deleted:', deleted); + + // 检查是否有循环节点 + const loopNodes = deleted.filter(node => + node.data?.type === 'LOOP_START' || node.data?.type === 'LOOP_END' + ); + + if (loopNodes.length > 0) { + // 处理循环节点删除 + let nodesToRemove = [...deleted]; + + // 为每个循环节点找到其配对节点 + loopNodes.forEach(loopNode => { + const component = loopNode.data?.component as { customDef?: string } | undefined; + + if (loopNode.data?.type === 'LOOP_START' && component?.customDef) { + try { + const customDef = JSON.parse(component.customDef); + const relatedNodeId = customDef.loopEndNodeId; + // 添加关联的结束节点到删除列表 + const relatedNode = nodes.find(n => n.id === relatedNodeId); + if (relatedNode) { + nodesToRemove.push(relatedNode); + } + } catch (e) { + console.error('解析循环开始节点数据失败:', e); + } + } + else if (loopNode.data?.type === 'LOOP_END' && component?.customDef) { + try { + const customDef = JSON.parse(component.customDef); + const relatedNodeId = customDef.loopStartNodeId; + // 添加关联的开始节点到删除列表 + const relatedNode = nodes.find(n => n.id === relatedNodeId); + if (relatedNode) { + nodesToRemove.push(relatedNode); + } + } catch (e) { + console.error('解析循环结束节点数据失败:', e); + } + } + }); + + // 去重 + nodesToRemove = nodesToRemove.filter((node, index, self) => + index === self.findIndex(n => n.id === node.id) + ); + + // 删除所有相关节点 + setNodes((nds) => nds.filter((n) => !nodesToRemove.find((d) => d.id === n.id))); + } + else { + // 普通节点删除 + setNodes((nds) => nds.filter((n) => !deleted.find((d) => d.id === n.id))); + } + setIsEditModalOpen(false); }} onNodesChange={onNodesChange}