From bc0e595efa0fa31d7ba45be4220a41c12d1a052b Mon Sep 17 00:00:00 2001 From: asp_ly Date: Sat, 14 Dec 2024 13:52:47 +0800 Subject: [PATCH] 1 --- .../Workflow/Definition/Design/index.less | 49 ++++ .../Workflow/Definition/Design/index.tsx | 217 ++++++++---------- 2 files changed, 140 insertions(+), 126 deletions(-) diff --git a/frontend/src/pages/Workflow/Definition/Design/index.less b/frontend/src/pages/Workflow/Definition/Design/index.less index 0da3cccf..9b565082 100644 --- a/frontend/src/pages/Workflow/Definition/Design/index.less +++ b/frontend/src/pages/Workflow/Definition/Design/index.less @@ -111,4 +111,53 @@ } } } + + :global { + .node-selected { + > rect { + stroke: #1890ff; + stroke-width: 2px; + } + > path { + stroke: #1890ff; + stroke-width: 2px; + } + } + + .x6-node-selected { + rect { + stroke: #1890ff; + stroke-width: 2px; + } + } + + .x6-edge-selected { + path { + stroke: #1890ff; + stroke-width: 2px !important; + } + } + + // 右键菜单样式 + .x6-context-menu { + background: #fff; + border-radius: 4px; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); + padding: 4px 0; + min-width: 120px; + + &-item { + padding: 5px 16px; + cursor: pointer; + user-select: none; + transition: all 0.3s; + color: rgba(0, 0, 0, 0.85); + font-size: 14px; + + &:hover { + background: #f5f5f5; + } + } + } + } } diff --git a/frontend/src/pages/Workflow/Definition/Design/index.tsx b/frontend/src/pages/Workflow/Definition/Design/index.tsx index 9fb36486..0ec79bfb 100644 --- a/frontend/src/pages/Workflow/Definition/Design/index.tsx +++ b/frontend/src/pages/Workflow/Definition/Design/index.tsx @@ -49,6 +49,96 @@ const WorkflowDesign: React.FC = () => { const [nodeDefinitions, setNodeDefinitions] = useState([]); const [isNodeDefinitionsLoaded, setIsNodeDefinitionsLoaded] = useState(false); + // 注册事件处理器 + const registerEventHandlers = (graph: Graph) => { + // 显示/隐藏连接桩 + graph.on('node:mouseenter', ({node}) => { + const ports = document.querySelectorAll(`[data-cell-id="${node.id}"] .x6-port-body`); + ports.forEach((port) => { + port.setAttribute('style', 'visibility: visible'); + }); + }); + + graph.on('node:mouseleave', ({node}) => { + const ports = document.querySelectorAll(`[data-cell-id="${node.id}"] .x6-port-body`); + ports.forEach((port) => { + port.setAttribute('style', 'visibility: hidden'); + }); + }); + + // 节点双击事件 + graph.on('node:dblclick', ({node}) => { + const nodeType = node.getProp('type'); + console.log(nodeType) + // 从节点定义列表中找到对应的定义 + const nodeDefinition = nodeDefinitions.find(def => def.type === nodeType); + if (nodeDefinition) { + setSelectedNode(node); + setSelectedNodeDefinition(nodeDefinition); + setConfigModalVisible(true); + } + }); + + // 添加右键菜单 + graph.on('node:contextmenu', ({cell, view, e}) => { + e.preventDefault(); + graph.cleanSelection(); + graph.select(cell); + + const menuItems = [ + { + label: '编辑', + onClick: () => { + setSelectedNode(cell); + setSelectedNodeDefinition(nodeDefinitions.find(def => def.type === cell.getProp('type'))); + setConfigModalVisible(true); + } + }, + { + label: '删除', + onClick: () => { + Modal.confirm({ + title: '确认删除', + content: '确定要删除该节点吗?', + onOk: () => { + graph.removeCell(cell); + } + }); + } + } + ]; + + const menu = document.createElement('div'); + menu.className = 'x6-context-menu'; + menu.style.position = 'fixed'; + menu.style.left = `${e.clientX}px`; + menu.style.top = `${e.clientY}px`; + menu.style.zIndex = '1000'; + + menuItems.forEach(item => { + const menuItem = document.createElement('div'); + menuItem.className = 'x6-context-menu-item'; + menuItem.innerText = item.label; + menuItem.onclick = () => { + item.onClick(); + menu.remove(); + }; + menu.appendChild(menuItem); + }); + + document.body.appendChild(menu); + + const removeMenu = (e: MouseEvent) => { + if (!menu.contains(e.target as Node)) { + menu.remove(); + document.removeEventListener('click', removeMenu); + } + }; + + document.addEventListener('click', removeMenu); + }); + }; + // 首先加载节点定义列表 useEffect(() => { const loadNodeDefinitions = async () => { @@ -127,132 +217,7 @@ const WorkflowDesign: React.FC = () => { ); } - // 添加右键菜单 - graph.on('node:contextmenu', ({cell, view, e}) => { - e.preventDefault(); - graph.cleanSelection(); - graph.select(cell); - - const menuItems = [ - { - label: '编辑', - onClick: () => { - setSelectedNode(cell); - setSelectedNodeDefinition(nodeDefinitions.find(def => def.type === cell.getProp('type'))); - setConfigModalVisible(true); - } - }, - { - label: '删除', - onClick: () => { - Modal.confirm({ - title: '确认删除', - content: '确定要删除该节点吗?', - onOk: () => { - graph.removeCell(cell); - } - }); - } - } - ]; - - const menu = document.createElement('div'); - menu.className = 'x6-context-menu'; - menu.style.position = 'fixed'; - menu.style.left = `${e.clientX}px`; - menu.style.top = `${e.clientY}px`; - menu.style.zIndex = '1000'; - - menuItems.forEach(item => { - const menuItem = document.createElement('div'); - menuItem.className = 'x6-context-menu-item'; - menuItem.innerText = item.label; - menuItem.onclick = () => { - item.onClick(); - menu.remove(); - }; - menu.appendChild(menuItem); - }); - - document.body.appendChild(menu); - - const removeMenu = (e: MouseEvent) => { - if (!menu.contains(e.target as Node)) { - menu.remove(); - document.removeEventListener('click', removeMenu); - } - }; - - document.addEventListener('click', removeMenu); - }); - - // 添加样式 - const style = document.createElement('style'); - style.textContent = ` - .node-selected > rect { - stroke: #1890ff; - stroke-width: 2px; - } - .node-selected > path { - stroke: #1890ff; - stroke-width: 2px; - } - .x6-node-selected rect { - stroke: #1890ff; - stroke-width: 2px; - } - .x6-edge-selected path { - stroke: #1890ff; - stroke-width: 2px !important; - } - .x6-context-menu { - background: #fff; - border-radius: 4px; - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); - padding: 4px 0; - min-width: 120px; - } - .x6-context-menu-item { - padding: 5px 16px; - cursor: pointer; - user-select: none; - transition: all 0.3s; - color: rgba(0, 0, 0, 0.85); - font-size: 14px; - } - .x6-context-menu-item:hover { - background: #f5f5f5; - } - `; - document.head.appendChild(style); - - // 显示/隐藏连接桩 - graph.on('node:mouseenter', ({node}) => { - const ports = document.querySelectorAll(`[data-cell-id="${node.id}"] .x6-port-body`); - ports.forEach((port) => { - port.setAttribute('style', 'visibility: visible'); - }); - }); - - graph.on('node:mouseleave', ({node}) => { - const ports = document.querySelectorAll(`[data-cell-id="${node.id}"] .x6-port-body`); - ports.forEach((port) => { - port.setAttribute('style', 'visibility: hidden'); - }); - }); - - // 节点双击事件 - graph.on('node:dblclick', ({node}) => { - const nodeType = node.getProp('type'); - console.log(nodeType) - // 从节点定义列表中找到对应的定义 - const nodeDefinition = nodeDefinitions.find(def => def.type === nodeType); - if (nodeDefinition) { - setSelectedNode(node); - setSelectedNodeDefinition(nodeDefinition); - setConfigModalVisible(true); - } - }); + registerEventHandlers(graph); setGraph(graph);