diff --git a/frontend/src/pages/Workflow/Definition/Design/index.tsx b/frontend/src/pages/Workflow/Definition/Design/index.tsx index e1a31849..dc1ec963 100644 --- a/frontend/src/pages/Workflow/Definition/Design/index.tsx +++ b/frontend/src/pages/Workflow/Definition/Design/index.tsx @@ -311,17 +311,57 @@ const WorkflowDesign: React.FC = () => { // 注册事件处理器 const registerEventHandlers = (graph: Graph) => { - // 显示/隐藏连接桩和高亮 + // 定义悬停样式 + const hoverStyle = { + strokeWidth: 2, + stroke: '#52c41a' // 绿色 + }; + + // 保存节点的原始样式 + const saveNodeOriginalStyle = (node: any) => { + const data = node.getData(); + if (!data?.originalStyle) { + const originalStyle = { + stroke: node.getAttrByPath('body/stroke') || '#5F95FF', + strokeWidth: node.getAttrByPath('body/strokeWidth') || 1 + }; + node.setData({ + ...data, + originalStyle + }); + } + }; + + // 获取节点的原始样式 + const getNodeOriginalStyle = (node: any) => { + const data = node.getData(); + return data?.originalStyle || { + stroke: '#5F95FF', + strokeWidth: 1 + }; + }; + + // 恢复节点的原始样式 + const resetNodeStyle = (node: any) => { + const originalStyle = getNodeOriginalStyle(node); + node.setAttrByPath('body/stroke', originalStyle.stroke); + node.setAttrByPath('body/strokeWidth', originalStyle.strokeWidth); + }; + + // 节点悬停事件 graph.on('node:mouseenter', ({node}) => { + // 保存原始样式 + saveNodeOriginalStyle(node); + // 显示连接桩 const ports = document.querySelectorAll(`[data-cell-id="${node.id}"] .x6-port-body`); ports.forEach((port) => { port.setAttribute('style', 'visibility: visible'); }); - // 高亮当前节点 - node.setAttrByPath('body/stroke', '#ff4d4f'); - node.setAttrByPath('body/strokeWidth', 2); + // 显示悬停样式 + node.setAttrByPath('body/stroke', hoverStyle.stroke); + node.setAttrByPath('body/strokeWidth', hoverStyle.strokeWidth); }); graph.on('node:mouseleave', ({node}) => { @@ -331,26 +371,53 @@ const WorkflowDesign: React.FC = () => { port.setAttribute('style', 'visibility: hidden'); }); - // 取消高亮(除非是选中状态) - if (!node.hasTools()) { - node.setAttrByPath('body/stroke', '#5B8FF9'); - node.setAttrByPath('body/strokeWidth', 1); - } + // 恢复原始样式 + resetNodeStyle(node); }); - // 节点点击时的高亮 + // 节点拖动开始时记录状态 + graph.on('node:drag:start', ({node}) => { + // 保存原始样式,以防还没保存过 + saveNodeOriginalStyle(node); + }); + + // 节点拖动结束后恢复样式 + graph.on('node:moved', ({node}) => { + resetNodeStyle(node); + // 隐藏连接桩 + const ports = document.querySelectorAll(`[data-cell-id="${node.id}"] .x6-port-body`); + ports.forEach((port) => { + port.setAttribute('style', 'visibility: hidden'); + }); + }); + + // 节点点击事件 graph.on('node:click', ({ node }) => { - node.setAttrByPath('body/stroke', '#ff4d4f'); - node.setAttrByPath('body/strokeWidth', 2); + // 获取当前选中的节点 + const selectedNode = graph.getSelectedCells()[0]; + + // 如果有其他节点被选中,恢复其样式 + if (selectedNode && selectedNode.isNode() && selectedNode.id !== node.id) { + resetNodeStyle(selectedNode); + } + + // 更新选中状态 + graph.resetSelection(); + graph.select(node); }); - // 点击空白处取消高亮 + // 点击空白处事件 graph.on('blank:click', () => { + // 获取当前选中的节点 const selectedNode = graph.getSelectedCells()[0]; + + // 如果有节点被选中,恢复其样式 if (selectedNode && selectedNode.isNode()) { - selectedNode.setAttrByPath('body/stroke', '#5B8FF9'); - selectedNode.setAttrByPath('body/strokeWidth', 1); + resetNodeStyle(selectedNode); } + + // 清除选中状态 + graph.resetSelection(); }); // 节点双击事件