import React, { useState } from 'react'; import { Tooltip, Badge, Divider, Pagination } from 'antd'; import { LinkOutlined, SwapRightOutlined, AimOutlined, NodeIndexOutlined, CheckCircleOutlined } from '@ant-design/icons'; const PortPanel = ({ ports, deviceName, deviceId, cables = [], devices = [], onPortClick, compact = false, selectedPort = null, }) => { const [currentPage, setCurrentPage] = useState(1); const [pageSize, setPageSize] = useState(48); // 默认每页48个端口 // 按端口名称排序(升序) const sortedPorts = [...ports].sort((a, b) => { // 尝试按数字部分排序,支持格式如:1/0/1, eth0/1, GigabitEthernet1/0/1 等 const extractNumbers = str => { const matches = str.match(/\d+/g); return matches ? matches.map(Number) : []; }; const numsA = extractNumbers(a.portName); const numsB = extractNumbers(b.portName); // 逐个比较数字部分 for (let i = 0; i < Math.min(numsA.length, numsB.length); i++) { if (numsA[i] !== numsB[i]) { return numsA[i] - numsB[i]; } } // 如果数字部分相同,按字符串排序 return a.portName.localeCompare(b.portName); }); // 分页数据 const totalPorts = sortedPorts.length; const startIndex = (currentPage - 1) * pageSize; const endIndex = startIndex + pageSize; const paginatedPorts = sortedPorts.slice(startIndex, endIndex); // 获取端口状态颜色 const getPortStatusColor = status => { switch (status) { case 'free': return '#6b7280'; // 灰色 - 空闲 case 'occupied': return '#10b981'; // 绿色 - 占用 case 'fault': return '#ef4444'; // 红色 - 故障 case 'disabled': return '#374151'; // 深灰色 - 禁用 default: return '#6b7280'; } }; // 获取端口状态文本 const getPortStatusText = status => { switch (status) { case 'free': return '空闲'; case 'occupied': return '已连接'; case 'fault': return '故障'; case 'disabled': return '禁用'; default: return '空闲'; } }; // 获取端口类型图标 - 使用更真实的端口符号 const getPortTypeIcon = portType => { switch (portType) { case 'RJ45': return '⬡'; // 六边形表示网口 case 'SFP': case 'SFP+': case 'SFP28': return '▭'; // 矩形表示SFP case 'QSFP': case 'QSFP28': return '▯'; // 宽矩形表示QSFP default: return '⬡'; } }; // 获取简化端口显示名称(只显示数字) const getPortDisplayName = portName => { // 提取最后的数字 const match = portName.match(/(\d+)$/); if (match) { return match[1]; } // 如果没有数字,返回原名称 return portName; }; // 获取线缆类型文本 const getCableTypeText = cableType => { const typeMap = { ethernet: '网线', fiber: '光纤', copper: '铜缆', power: '电源线', }; return typeMap[cableType] || cableType || '未知'; }; // 获取线缆类型颜色 const getCableTypeColor = cableType => { const colorMap = { ethernet: '#52c41a', fiber: '#1890ff', copper: '#faad14', power: '#ff4d4f', }; return colorMap[cableType] || '#999'; }; // 查找端口关联的接线 const findPortCable = port => { if (!cables || cables.length === 0) return null; return cables.find( cable => (cable.sourceDeviceId === deviceId && cable.sourcePortId === port.portId) || (cable.targetDeviceId === deviceId && cable.targetPortId === port.portId) || (cable.sourceDeviceId === deviceId && cable.sourcePort === port.portName) || (cable.targetDeviceId === deviceId && cable.targetPort === port.portName) ); }; // 获取连接的对端信息 const getPeerInfo = (cable, currentPort) => { if (!cable) return null; const isSource = cable.sourceDeviceId === deviceId || (cable.sourcePortId && cable.sourcePortId === currentPort.portId) || cable.sourcePort === currentPort.portName; if (isSource) { // 当前是源端,返回目标端信息 const targetDevice = devices.find(d => d.deviceId === cable.targetDeviceId); return { deviceName: targetDevice?.name || cable.targetDeviceId, deviceId: cable.targetDeviceId, portName: cable.targetPort || cable.targetPortId, direction: 'out', }; } else { // 当前是目标端,返回源端信息 const sourceDevice = devices.find(d => d.deviceId === cable.sourceDeviceId); return { deviceName: sourceDevice?.name || cable.sourceDeviceId, deviceId: cable.sourceDeviceId, portName: cable.sourcePort || cable.sourcePortId, direction: 'in', }; } }; // 渲染端口详情提示 const renderPortTooltip = port => { const cable = findPortCable(port); const peerInfo = cable ? getPeerInfo(cable, port) : null; return (