From 0c33d141d56b43a2a503d1f33a31e2c990a83fce Mon Sep 17 00:00:00 2001 From: jile1997 <1154416769@qq.com> Date: Thu, 19 Mar 2026 13:48:11 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E5=94=A4=E8=B5=B7?= =?UTF-8?q?=E8=8A=82=E7=82=B9=E6=8A=BD=E5=B1=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/x-flow/src/XFlow.tsx | 24 ++++++++++++++-- packages/x-flow/src/hooks/useFlow.ts | 8 ++++-- packages/x-flow/src/models/store.ts | 41 +++++++++++++++++++++++++++- packages/x-flow/src/types.ts | 2 ++ 4 files changed, 69 insertions(+), 6 deletions(-) diff --git a/packages/x-flow/src/XFlow.tsx b/packages/x-flow/src/XFlow.tsx index f828a2348..9cfd6a6f2 100644 --- a/packages/x-flow/src/XFlow.tsx +++ b/packages/x-flow/src/XFlow.tsx @@ -67,6 +67,12 @@ const XFlow: FC = memo(props => { isAddingNode, setMousePosition, copyNodes, + activeNode, + setActiveNode, + openPanel, + setOpenPanel, + openLogPanel, + setOpenLogPanel } = useStore( s => ({ nodes: s.nodes, @@ -82,20 +88,25 @@ const XFlow: FC = memo(props => { onEdgesChange: s.onEdgesChange, onConnect: s.onConnect, copyNodes: s.copyNodes, + activeNode:s.activeNode, + setActiveNode:s.setActiveNode, + openPanel:s.openPanel, + openLogPanel:s.openLogPanel, + setOpenPanel:s.setOpenPanel, + setOpenLogPanel:s.setOpenLogPanel }), shallow ); const { record } = useTemporalStore(); - const [activeNode, setActiveNode] = useState(null); const { settingMap, globalConfig, readOnly, logPanel } = useContext(ConfigContext); - const [openPanel, setOpenPanel] = useState(true); - const [openLogPanel, setOpenLogPanel] = useState(true); const { onNodeClick, onEdgeClick, onPasteCompleted, onCopyCompleted, + onMoveStart, + onMoveEnd, zoomOnScroll = true, panOnScroll = false, preventScrolling = true, @@ -308,6 +319,7 @@ const XFlow: FC = memo(props => { _nodeType, values: { ...restData }, _status, + _isCandidate:false }); if (!showPanel) { setOpenPanel(false); @@ -409,6 +421,12 @@ const XFlow: FC = memo(props => { minZoom={0.3} zoomOnScroll={zoomOnScroll} panOnScroll={panOnScroll} // 禁用滚动平移 + onMoveStart={(...rest)=>{ + onMoveStart && onMoveStart(...rest) + }} + onMoveEnd={(...rest)=>{ + onMoveEnd && onMoveEnd(...rest) + }} preventScrolling={preventScrolling} // 允许页面滚动 connectionLineComponent={connectionLineComponent} connectionRadius={100} diff --git a/packages/x-flow/src/hooks/useFlow.ts b/packages/x-flow/src/hooks/useFlow.ts index 5fb3fdbc5..4a30fdedd 100644 --- a/packages/x-flow/src/hooks/useFlow.ts +++ b/packages/x-flow/src/hooks/useFlow.ts @@ -16,7 +16,6 @@ import { message } from 'antd'; export const useFlow = () => { const storeApi = useStoreApi(); const instance = storeApi.getState(); - const { zoomIn, zoomOut, @@ -31,7 +30,7 @@ export const useFlow = () => { getNodes: _getNodes, getEdges, screenToFlowPosition, - flowToScreenPosition + flowToScreenPosition, } = useReactFlow(); const { record } = useTemporalStore(); @@ -255,6 +254,10 @@ export const useFlow = () => { setNodes(newNodes); }); + const setActiveNodePanel = (activeNode,openPanel:boolean) => { + instance.setActiveNodePanel(activeNode,openPanel) + } + return useMemo( () => ({ setNodes, @@ -284,6 +287,7 @@ export const useFlow = () => { deleteNode, copyFLowNodes, pasteFLowNodes, + setActiveNodePanel }), [instance] ); diff --git a/packages/x-flow/src/models/store.ts b/packages/x-flow/src/models/store.ts index ab10678bb..635dffba5 100644 --- a/packages/x-flow/src/models/store.ts +++ b/packages/x-flow/src/models/store.ts @@ -13,6 +13,14 @@ import isDeepEqual from 'fast-deep-equal'; import { temporal } from 'zundo'; import { createWithEqualityFn } from 'zustand/traditional'; +interface activeNode { + id: string; + _nodeType: string; + values: Record; + _status: string; + _isCandidate:boolean +} + export type FlowProps = { nodes?: Node[]; edges?: Edge[]; @@ -35,18 +43,25 @@ export type FlowState = { candidateNode: any; mousePosition: any; copyTimeoutId: NodeJS.Timeout | null; // 添加超时定时器ID + activeNode: activeNode | null; + openPanel:boolean + openLogPanel:boolean onNodesChange: OnNodesChange; onEdgesChange: OnEdgesChange; onConnect: OnConnect; setNodes: (nodes: FlowNode[], isTransform?: boolean) => void; setEdges: (edges: Edge[]) => void; - addNodes: (nodes: FlowNode[]| FlowNode, isTransform?: boolean) => void; + addNodes: (nodes: FlowNode[] | FlowNode, isTransform?: boolean) => void; addEdges: (edges: Edge[] | Edge) => void; setLayout: (layout: 'LR' | 'TB') => void; setIsAddingNode: (payload: boolean) => void; setCandidateNode: (candidateNode: any) => void; setMousePosition: (mousePosition: any) => void; setCopyTimeoutId: (timeoutId: NodeJS.Timeout | null) => void; // 添加设置超时定时器的方法 + setActiveNodePanel:(activeNode:activeNode,openPanel:boolean)=>void + setActiveNode:(activeNode:activeNode)=>void + setOpenPanel:(openPanel:boolean)=>void + setOpenLogPanel:(openLogPanel)=>void }; const createStore = (initProps?: Partial) => { @@ -69,6 +84,9 @@ const createStore = (initProps?: Partial) => { copyTimeoutId: null, // 添加超时定时器ID初始值 // nodeMenus: [], mousePosition: { pageX: 0, pageY: 0, elementX: 0, elementY: 0 }, + activeNode: null, + openPanel:true, + openLogPanel:true, onNodesChange: changes => { set({ nodes: applyNodeChanges(changes, get().nodes), @@ -117,6 +135,27 @@ const createStore = (initProps?: Partial) => { return; } set({ layout }); + }, + setActiveNodePanel: (activeNode:activeNode,openPanel:boolean) => { + set({ + activeNode, + openPanel + }) + }, + setActiveNode:(activeNode:activeNode)=>{ + set({ + activeNode + }) + }, + setOpenPanel:(openPanel:boolean)=>{ + set({ + openPanel + }) + }, + setOpenLogPanel:(openLogPanel:boolean)=>{ + set({ + openLogPanel + }) } }), { diff --git a/packages/x-flow/src/types.ts b/packages/x-flow/src/types.ts index 0c56bc173..b02866711 100644 --- a/packages/x-flow/src/types.ts +++ b/packages/x-flow/src/types.ts @@ -194,6 +194,8 @@ export interface FlowProps { onCopyCompleted?:(addNodes:node[])=>void onMenuItemClick?: (itemInfo: ItemInfo, defaultAction: () => void) => void; clickAddNode?: (type: string, nodeItem: TNodeItem, addNode: (initData?: Record) => void) => void; + onMoveStart?:ReactFlowProps['onMoveStart'] + onMoveEnd?:ReactFlowProps['onMoveEnd'] zoomOnScroll?: boolean; panOnScroll?: boolean; preventScrolling?: boolean;