fix(flowEditor): 修复粘贴逻辑无效的问题

feature
钟良源 3 weeks ago
parent 755afe1483
commit abe0fc554a

@ -29,7 +29,7 @@ const PaneContextMenu: React.FC<PaneContextMenuProps> = ({
}, []);
// 检查是否有复制的节点数据
const hasCopiedNode = !!localStorage.getItem('copiedNode');
const hasCopiedNode = !!localStorage.getItem('copiedNode') || !!localStorage.getItem('copiedFlowData');
return (
<Menu

@ -12,7 +12,11 @@ import FlowEditorMain from './FlowEditorMain';
import { useFlowEditorState } from '@/hooks/useFlowEditorState';
import { useFlowCallbacks } from '@/hooks/useFlowCallbacks';
const FlowEditorWithProvider: React.FC<{ initialData?: any, useDefault?: boolean, readOnly?: boolean }> = ({ initialData, useDefault, readOnly }) => {
const FlowEditorWithProvider: React.FC<{
initialData?: any,
useDefault?: boolean,
readOnly?: boolean
}> = ({ initialData, useDefault, readOnly }) => {
return (
<div style={{ width: '100%', height: '91vh', display: 'flex' }} onContextMenu={(e) => e.preventDefault()}>
<ReactFlowProvider>
@ -22,7 +26,11 @@ const FlowEditorWithProvider: React.FC<{ initialData?: any, useDefault?: boolean
);
};
const FlowEditor: React.FC<{ initialData?: any, useDefault?: boolean, readOnly?: boolean }> = ({ initialData, useDefault, readOnly = false }) => {
const FlowEditor: React.FC<{ initialData?: any, useDefault?: boolean, readOnly?: boolean }> = ({
initialData,
useDefault,
readOnly = false
}) => {
const reactFlowInstance = useReactFlow();
const reactFlowWrapper = useRef<HTMLDivElement>(null);
const [menu, setMenu] = useState<{
@ -205,30 +213,56 @@ const FlowEditor: React.FC<{ initialData?: any, useDefault?: boolean, readOnly?:
setMenu(null);
}, [setMenu]);
// 添加处理粘贴事件的函数
// 存储最后的鼠标位置
const lastMousePositionRef = useRef<{ x: number; y: number } | null>(null);
// 跟踪鼠标位置
useEffect(() => {
const handleMouseMove = (event: MouseEvent) => {
const pane = reactFlowWrapper.current?.getBoundingClientRect();
if (pane && reactFlowInstance) {
const position = reactFlowInstance.screenToFlowPosition({
x: event.clientX,
y: event.clientY
});
lastMousePositionRef.current = position;
}
};
const canvasElement = reactFlowWrapper.current;
if (canvasElement) {
canvasElement.addEventListener('mousemove', handleMouseMove);
}
return () => {
if (canvasElement) {
canvasElement.removeEventListener('mousemove', handleMouseMove);
}
};
}, [reactFlowInstance]);
// 处理粘贴事件
const handlePasteNode = useCallback((event: ClipboardEvent) => {
// 检查是否是粘贴操作且在画布区域内
// 右键菜单触发的粘贴(有menu.position)
if (event.clipboardData?.getData('text') === 'paste-node' && menu?.type === 'pane' && menu.position) {
pasteNode(menu.position);
setMenu(null);
}
}, [menu, pasteNode]);
}, [menu, pasteNode, setMenu]);
// 添加键盘事件监听
useEffect(() => {
const handleKeyDown = (event: KeyboardEvent) => {
// 检查是否按下了 Ctrl+V (Windows/Linux) 或 Cmd+V (Mac)
if ((event.ctrlKey || event.metaKey) && event.key === 'v') {
// 触发自定义粘贴事件
const pasteEvent = new ClipboardEvent('paste', {
clipboardData: new DataTransfer()
});
pasteEvent.clipboardData?.setData('text', 'paste-node');
document.dispatchEvent(pasteEvent);
// 键盘快捷键粘贴,使用最后的鼠标位置
if (lastMousePositionRef.current) {
pasteNode(lastMousePositionRef.current);
}
}
};
// 为画布添加键盘事件监听
// 为画布添加键盘和粘贴事件监听
const canvasElement = reactFlowWrapper.current;
if (canvasElement) {
canvasElement.addEventListener('keydown', handleKeyDown);
@ -241,7 +275,7 @@ const FlowEditor: React.FC<{ initialData?: any, useDefault?: boolean, readOnly?:
}
document.removeEventListener('paste', handlePasteNode);
};
}, [handlePasteNode]);
}, [pasteNode, handlePasteNode]);
// 监听边的变化,处理添加节点的触发
useEffect(() => {
@ -281,8 +315,8 @@ const FlowEditor: React.FC<{ initialData?: any, useDefault?: boolean, readOnly?:
}
return (
<div
ref={reactFlowWrapper}
<div
ref={reactFlowWrapper}
style={{ width: '100%', height: '100%' }}
onContextMenu={(e) => e.preventDefault()}
tabIndex={0} // 使div可获得焦点以接收键盘事件

Loading…
Cancel
Save