import React, { memo } from 'react'; import { Handle, Position, NodeProps } from '@xyflow/react'; import { BaseNodeDefinition, NodeType, NodeCategory } from './types'; import type { FlowNodeData } from '../types'; /** * 结束事件节点定义(元数据) */ export const EndEventNodeDefinition: BaseNodeDefinition = { nodeCode: "END_EVENT", nodeName: "结束", nodeType: NodeType.END_EVENT, category: NodeCategory.EVENT, description: "工作流的结束节点", uiConfig: { size: { width: 80, height: 50 }, style: { fill: '#ff4d4f', stroke: '#cf1322', strokeWidth: 2, icon: 'stop-circle', iconColor: '#fff' } }, configSchema: { type: "object", title: "基本配置", description: "节点的基本信息", properties: { nodeName: { type: "string", title: "节点名称", description: "节点在流程图中显示的名称", default: "结束" }, nodeCode: { type: "string", title: "节点编码", description: "节点的唯一标识符", default: "END_EVENT" }, description: { type: "string", title: "节点描述", description: "节点的详细说明", default: "工作流的结束节点" } }, required: ["nodeName", "nodeCode"] } }; /** * 结束事件节点渲染组件 */ const EndEventNode: React.FC = ({ data, selected }) => { const nodeData = data as FlowNodeData; const [isHovered, setIsHovered] = React.useState(false); return (
setIsHovered(true)} onMouseLeave={() => setIsHovered(false)} style={{ padding: '12px', borderRadius: '50%', border: `3px solid ${selected ? '#3b82f6' : '#ef4444'}`, background: selected ? 'linear-gradient(135deg, #fee2e2 0%, #fecaca 100%)' : 'linear-gradient(135deg, #fef2f2 0%, #fee2e2 100%)', minWidth: '70px', minHeight: '70px', display: 'flex', alignItems: 'center', justifyContent: 'center', position: 'relative', boxShadow: selected ? '0 8px 16px rgba(59, 130, 246, 0.25), 0 2px 4px rgba(59, 130, 246, 0.15)' : isHovered ? '0 6px 12px rgba(239, 68, 68, 0.2), 0 2px 4px rgba(239, 68, 68, 0.1)' : '0 2px 8px rgba(0,0,0,0.08)', cursor: 'pointer', transition: 'all 0.3s cubic-bezier(0.4, 0, 0.2, 1)', transform: isHovered ? 'scale(1.05)' : 'scale(1)', }} > {/* 图标 */}
⏹️
{/* 输入连接点 */} {/* 节点标签 */}
{nodeData.label || '结束'}
); }; export default memo(EndEventNode);