import React, { useState, useCallback, useMemo } from 'react';
import {
Drawer,
Tabs,
Tag,
Space,
Typography,
Empty,
Card,
Tooltip,
Button,
Popconfirm,
} from 'antd';
import {
ApiOutlined,
CloudServerOutlined,
EnvironmentOutlined,
EditOutlined,
PlusCircleOutlined,
DeleteOutlined,
} from '@ant-design/icons';
import NetworkCardPanel from './NetworkCardPanel';
const { Text, Title } = Typography;
const designTokens = {
colors: {
primary: '#667eea',
success: '#10b981',
error: '#ef4444',
warning: '#f59e0b',
},
spacing: {
sm: 8,
md: 16,
},
};
function DeviceDetailDrawer({
device,
visible,
onClose,
cables,
onRefreshCables,
onEdit,
onAddNic,
onAddPort,
onAddCable,
onDeleteCable,
tooltipFields,
refreshTrigger,
}) {
const [activeTab, setActiveTab] = useState('ports');
const deviceCables = useMemo(() => {
if (!device || !cables) return [];
return cables.filter(
c => c.sourceDeviceId === device.deviceId || c.targetDeviceId === device.deviceId
);
}, [device, cables]);
const getStatusTag = useCallback(status => {
const config = {
running: { color: 'success', text: '运行中' },
normal: { color: 'success', text: '正常' },
warning: { color: 'warning', text: '警告' },
error: { color: 'error', text: '故障' },
fault: { color: 'error', text: '故障' },
offline: { color: 'default', text: '离线' },
maintenance: { color: 'processing', text: '维护中' },
};
const { color, text } = config[status] || { color: 'default', text: status };
return {text};
}, []);
const getDeviceTypeName = useCallback(type => {
const typeMap = {
server: '服务器',
switch: '交换机',
router: '路由器',
storage: '存储设备',
firewall: '防火墙',
ups: 'UPS',
pdu: 'PDU',
};
return typeMap[type?.toLowerCase()] || type || '未知设备';
}, []);
const renderFieldValue = useCallback(
(field, device) => {
const fieldKey = field.field;
if (fieldKey === 'status') return getStatusTag(device.status);
// 优先从device对象获取值,如果没有则从customFields中获取
let value = device[fieldKey];
if (
(value === undefined || value === null) &&
device.customFields &&
typeof device.customFields === 'object'
) {
value = device.customFields[fieldKey];
}
if (fieldKey === 'type') value = getDeviceTypeName(value);
else if (fieldKey === 'position')
value = `U${device.position} ${device.height ? `(${device.height}U)` : ''}`;
return (
{value !== undefined && value !== null ? value : '-'}
);
},
[getStatusTag, getDeviceTypeName]
);
const displayFields = useMemo(() => {
if (tooltipFields && Object.keys(tooltipFields).length > 0) {
return Object.values(tooltipFields).filter(f => f.enabled);
}
// Default fallback fields if no config
return [
{ field: 'deviceId', label: '设备ID' },
{ field: 'type', label: '设备类型' },
{ field: 'status', label: '设备状态' },
{ field: 'position', label: '位置' },
{ field: 'ipAddress', label: 'IP地址' },
{ field: 'brand', label: '品牌' },
];
}, [tooltipFields]);
const tabItems = [
{
key: 'ports',
label: (
端口与网卡
),
children: (
),
},
{
key: 'cables',
label: (
接线 ({deviceCables.length})
),
children: (
{deviceCables.length === 0 ? (
) : (
{deviceCables.map(cable => (
onDeleteCable?.(cable.cableId)}
okText="确定"
cancelText="取消"
>
} size="small" />
}
>
源设备:
{cable.sourceDevice?.name || '-'}
{cable.sourcePort}
目标设备:
{cable.targetDevice?.name || '-'}
{cable.targetPort}
{cable.status === 'normal'
? '正常'
: cable.status === 'fault'
? '故障'
: '未连接'}
{cable.cableType === 'ethernet'
? '网线'
: cable.cableType === 'fiber'
? '光纤'
: '铜缆'}
{cable.cableLength && {cable.cableLength}m}
{cable.description && (
{cable.description}
)}
))}
)}
),
},
];
if (!device) return null;
return (
设备详情 - {device.name}
}
placement="right"
width={600}
open={visible}
onClose={onClose}
extra={
} onClick={() => onEdit?.(device)} />
} onClick={() => onAddNic?.(device)}>
加网卡
} onClick={() => onAddPort?.(device)}>
加端口
} onClick={() => onAddCable?.(device)}>
加接线
}
styles={{ body: { padding: '16px 20px', overflow: 'auto' } }}
>
基本信息
{displayFields.map(field => (
{field.label}
{renderFieldValue(field, device)}
))}
);
}
export default React.memo(DeviceDetailDrawer);