diff --git a/src/pages/flowEditor/index.tsx b/src/pages/flowEditor/index.tsx index 6f8048a..b759790 100644 --- a/src/pages/flowEditor/index.tsx +++ b/src/pages/flowEditor/index.tsx @@ -18,6 +18,9 @@ import { ConnectionLineType } from '@xyflow/react'; import '@xyflow/react/dist/style.css'; +import { useSelector, useDispatch } from 'react-redux'; +import { updateCanvasDataMap } from '@/store/ideContainer'; +import { debounce } from 'lodash'; import { nodeTypeMap, nodeTypes, registerNodeType } from '@/components/FlowEditor/node'; import SideBar from './sideBar/sideBar'; import { convertFlowData, revertFlowData } from '@/utils/convertFlowData'; @@ -55,6 +58,7 @@ const FlowEditorWithProvider: React.FC<{ initialData?: any }> = ({ initialData } const FlowEditor: React.FC<{ initialData?: any }> = ({ initialData }) => { const [nodes, setNodes] = useState([]); const [edges, setEdges] = useState([]); + const { canvasDataMap } = useSelector(state => state.ideContainer); const reactFlowInstance = useReactFlow(); const reactFlowWrapper = useRef(null); const [menu, setMenu] = useState<{ @@ -65,6 +69,7 @@ const FlowEditor: React.FC<{ initialData?: any }> = ({ initialData }) => { position?: { x: number; y: number }; } | null>(null); const store = useStoreApi(); + const dispatch = useDispatch(); // 添加编辑弹窗相关状态 const [editingNode, setEditingNode] = useState(null); @@ -77,6 +82,15 @@ const FlowEditor: React.FC<{ initialData?: any }> = ({ initialData }) => { const { getGuidelines, clearGuidelines, AlignmentGuides } = useAlignmentGuidelines(); + const updateCanvasDataMapDebounced = useRef( + debounce((dispatch, canvasDataMap, id, nodes, edges) => { + dispatch(updateCanvasDataMap({ + ...canvasDataMap, + [id]: { nodes, edges } + })); + }, 500) + ).current; + // 获取handle类型 (api或data) const getHandleType = (handleId: string, nodeParams: any) => { // 检查是否为api类型的handle @@ -310,17 +324,44 @@ const FlowEditor: React.FC<{ initialData?: any }> = ({ initialData }) => { }, [clearGuidelines]); useEffect(() => { - const { nodes: convertedNodes, edges: convertedEdges } = convertFlowData(initialData); - // 为所有边添加类型- - const initialEdges: Edge[] = convertedEdges.map(edge => ({ - ...edge, - type: 'custom' - })); - - setNodes(convertedNodes); - setEdges(initialEdges); + if (canvasDataMap[initialData?.id]) { + const { edges, nodes } = canvasDataMap[initialData?.id]; + setNodes(nodes); + setEdges(edges); + } + else { + // 首次进入 + const { nodes: convertedNodes, edges: convertedEdges } = convertFlowData(initialData); + // 为所有边添加类型- + const initialEdges: Edge[] = convertedEdges.map(edge => ({ + ...edge, + type: 'custom' + })); + + setNodes(convertedNodes); + setEdges(initialEdges); + + if (initialData?.id) { + dispatch(updateCanvasDataMap({ + ...canvasDataMap, + [initialData.id]: { convertedNodes, initialEdges } + })); + } + } }, [initialData]); + // 实时更新 canvasDataMap + useEffect(() => { + if (initialData?.id) { + updateCanvasDataMapDebounced(dispatch, canvasDataMap, initialData.id, nodes, edges); + } + + // 清理函数,在组件卸载时取消防抖 + return () => { + updateCanvasDataMapDebounced.cancel(); + }; + }, [nodes, edges, initialData?.id, dispatch, canvasDataMap]); + // 监听边的变化,处理添加节点的触发 useEffect(() => { const edgeToAddNode = edges.find(edge => edge.data?.addNodeTrigger); diff --git a/src/store/ideContainer.ts b/src/store/ideContainer.ts index 6cda04c..969041f 100644 --- a/src/store/ideContainer.ts +++ b/src/store/ideContainer.ts @@ -4,6 +4,7 @@ interface IDEContainerState { info: any; menuData: any; flowData: any; + canvasDataMap: any; logBarStatus?: boolean; } @@ -11,6 +12,7 @@ const initialState: IDEContainerState = { info: {}, menuData: {}, flowData: {}, + canvasDataMap: {}, logBarStatus: false }; @@ -27,12 +29,21 @@ const ideContainerSlice = createSlice({ updateFlowData(state, action) { state.flowData = { ...state.flowData, ...action.payload }; }, + updateCanvasDataMap(state, action) { + state.canvasDataMap = { ...state.canvasDataMap, ...action.payload }; + }, updateLogBarStatus(state, action) { state.logBarStatus = action.payload; } } }); -export const { updateInfo, updateMenuData, updateFlowData, updateLogBarStatus } = ideContainerSlice.actions; +export const { + updateInfo, + updateMenuData, + updateFlowData, + updateCanvasDataMap, + updateLogBarStatus +} = ideContainerSlice.actions; export default ideContainerSlice.reducer; \ No newline at end of file