From 79ae68ce92c0e2a1960fbbbfeaf978a0bbc404b6 Mon Sep 17 00:00:00 2001 From: ZLY Date: Mon, 15 Sep 2025 17:45:56 +0800 Subject: [PATCH] =?UTF-8?q?feat(flowEditor):=20=E4=BC=98=E5=8C=96=E8=8A=82?= =?UTF-8?q?=E7=82=B9=E6=B7=BB=E5=8A=A0=E5=8A=9F=E8=83=BD=E5=92=8C=E7=95=8C?= =?UTF-8?q?=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增分组标签页,优化节点分类展示 - 改进边添加节点功能,支持在特定位置添加- 调整节点添加按钮样式和布局 - 优化画布点击事件处理,清除节点添加状态 --- .../flowEditor/components/addNodeMenu.tsx | 87 +++++++++++-------- .../flowEditor/components/customEdge.tsx | 22 ++--- .../components/edgeAddNodeButton.tsx | 20 ++--- .../flowEditor/components/paneContextMenu.tsx | 16 ++-- src/pages/flowEditor/index.tsx | 26 ++++-- 5 files changed, 93 insertions(+), 78 deletions(-) diff --git a/src/pages/flowEditor/components/addNodeMenu.tsx b/src/pages/flowEditor/components/addNodeMenu.tsx index 12525af..28858df 100644 --- a/src/pages/flowEditor/components/addNodeMenu.tsx +++ b/src/pages/flowEditor/components/addNodeMenu.tsx @@ -1,7 +1,9 @@ import React from 'react'; -import { Menu } from '@arco-design/web-react'; +import { Menu, Tabs } from '@arco-design/web-react'; import { localNodeData } from '@/pages/flowEditor/sideBar/config/localNodeData'; +const TabPane = Tabs.TabPane; + interface AddNodeMenuProps { onAddNode: (nodeType: string) => void; position?: { x: number; y: number }; // 用于画布上下文菜单 @@ -9,8 +11,8 @@ interface AddNodeMenuProps { } const AddNodeMenu: React.FC = ({ - onAddNode -}) => { + onAddNode + }) => { // 按分组组织节点数据 const groupedNodes = localNodeData.reduce((acc, node) => { if (!acc[node.nodeGroup]) { @@ -26,46 +28,55 @@ const AddNodeMenu: React.FC = ({ // 分组名称映射 const groupNames: Record = { - 'common': '系统组件' - // 可以根据需要添加更多分组 - // 'application': '应用组件', - // 'composite': '复合组件' + 'common': '系统组件', + 'application': '应用组件', + 'composite': '复合组件' }; return ( - - {Object.entries(groupedNodes).map(([group, nodes]) => ( - - {nodes.map((node) => ( - handleAddNode(node.nodeType)} - style={{ - padding: '0 16px', - height: 36, - lineHeight: '36px' - }} - > - {node.nodeName} - - ))} - - ))} - + + {Object.entries(groupedNodes).map(([group, nodes]) => ( + +
+ + {nodes.map((node) => ( + handleAddNode(node.nodeType)} + style={{ + padding: '0 16px', + height: 36, + lineHeight: '36px' + }} + > + {node.nodeName} + + ))} + +
+
+ ))} +
+ ); }; diff --git a/src/pages/flowEditor/components/customEdge.tsx b/src/pages/flowEditor/components/customEdge.tsx index b392d55..be0d343 100644 --- a/src/pages/flowEditor/components/customEdge.tsx +++ b/src/pages/flowEditor/components/customEdge.tsx @@ -15,7 +15,7 @@ const CustomEdge: React.FC = ({ selected, data }) => { - const [edgePath, labelX, labelY] = getBezierPath({ + const [edgePath, labelX, labelY, offsetX, offsetY] = getBezierPath({ sourceX, sourceY, sourcePosition, @@ -26,13 +26,12 @@ const CustomEdge: React.FC = ({ // 从数据中获取悬停状态 const hovered = data?.hovered || false; - + // 使用useReactFlow钩子获取setEdges方法 const { setEdges } = useReactFlow(); // 边点击处理函数 - const handleEdgeAddNode = () => { - console.log('handleEdgeAddNode called for edge:', id); + const handleEdgeAddNode = (e) => { // 更新边的数据,触发边上添加节点的流程 setEdges(eds => eds.map(edge => { if (edge.id === id) { @@ -40,7 +39,9 @@ const CustomEdge: React.FC = ({ ...edge, data: { ...edge.data, - addNodeTrigger: true + addNodeTrigger: true, + clientX: e.clientX, + clientY: e.clientY } }; } @@ -71,20 +72,11 @@ const CustomEdge: React.FC = ({ > {hovered && ( handleEdgeAddNode(e)} /> )} - {/* 悬停时显示的高亮线条 */} - {hovered && ( - - )} ); }; diff --git a/src/pages/flowEditor/components/edgeAddNodeButton.tsx b/src/pages/flowEditor/components/edgeAddNodeButton.tsx index 7fe1fcf..c81b957 100644 --- a/src/pages/flowEditor/components/edgeAddNodeButton.tsx +++ b/src/pages/flowEditor/components/edgeAddNodeButton.tsx @@ -3,16 +3,16 @@ import { Button } from '@arco-design/web-react'; import { IconPlus } from '@arco-design/web-react/icon'; interface EdgeAddNodeButtonProps { - onClick: () => void; + onClick: (e) => void; style?: React.CSSProperties; } -const EdgeAddNodeButton: React.FC = ({ - onClick, - style -}) => { +const EdgeAddNodeButton: React.FC = ({ + onClick, + style + }) => { return ( -
= ({ icon={} onClick={(e) => { e.stopPropagation(); - onClick(); + onClick(e); }} style={{ - width: 20, - height: 20, - minWidth: 20, + width: 12, + height: 12, + minWidth: 12, padding: 0, borderRadius: '50%', display: 'flex', diff --git a/src/pages/flowEditor/components/paneContextMenu.tsx b/src/pages/flowEditor/components/paneContextMenu.tsx index 2bd3ae5..c4a7b5c 100644 --- a/src/pages/flowEditor/components/paneContextMenu.tsx +++ b/src/pages/flowEditor/components/paneContextMenu.tsx @@ -2,6 +2,8 @@ import React from 'react'; import { Menu } from '@arco-design/web-react'; import AddNodeMenu from './addNodeMenu'; +const SubMenu = Menu.SubMenu; + interface PaneContextMenuProps { onAddNode: (nodeType: string, position: { x: number; y: number }) => void; position: { x: number; y: number }; @@ -18,7 +20,6 @@ const PaneContextMenu: React.FC = ({ return ( = ({ boxShadow: '0 2px 8px rgba(0, 0, 0, 0.15)' }} > - -
- -
-
+ +
); }; diff --git a/src/pages/flowEditor/index.tsx b/src/pages/flowEditor/index.tsx index c910c25..d3c9582 100644 --- a/src/pages/flowEditor/index.tsx +++ b/src/pages/flowEditor/index.tsx @@ -289,8 +289,10 @@ const FlowEditor: React.FC = () => { // 监听边的变化,处理添加节点的触发 useEffect(() => { const edgeToAddNode = edges.find(edge => edge.data?.addNodeTrigger); + const pane = reactFlowWrapper.current?.getBoundingClientRect(); if (edgeToAddNode) { - console.log('Triggering add node for edge:', edgeToAddNode.id); + edgeToAddNode.data.y = (edgeToAddNode.data.clientY as number) - pane.top; + edgeToAddNode.data.x = (edgeToAddNode.data.clientX as number) - pane.left; setEdgeForNodeAdd(edgeToAddNode); // 清除触发标志 @@ -380,7 +382,12 @@ const FlowEditor: React.FC = () => { ); // 点击画布其他区域关闭菜单 - const onPaneClick = useCallback(() => setMenu(null), [setMenu]); + const onPaneClick = useCallback(() => { + setMenu(null); + // 关闭添加节点菜单 + setEdgeForNodeAdd(null); + setPositionForNodeAdd(null); + }, [setMenu]); // 关闭编辑弹窗 const closeEditModal = useCallback(() => { @@ -546,7 +553,7 @@ const FlowEditor: React.FC = () => { else if (positionForNodeAdd) { addNodeOnPane(nodeType, positionForNodeAdd); } - + // 清除状态 setEdgeForNodeAdd(null); setPositionForNodeAdd(null); @@ -711,14 +718,19 @@ const FlowEditor: React.FC = () => {
{ + handleAddNode(nodeType); + // 关闭菜单 + setEdgeForNodeAdd(null); + setPositionForNodeAdd(null); + }} position={positionForNodeAdd || undefined} edgeId={edgeForNodeAdd?.id} />