Files
yunrui_asset/frontend/src/components/PortAddGuideModal.jsx
T
zhang1106 ae315e2775 feat(网卡管理): 新增批量导入网卡功能及关联组件
refactor(端口管理): 优化端口批量导入逻辑,增加服务器端口网卡关联验证

feat(前端组件): 新增批量导入模态框、网卡导入模态框和端口导出模态框

style(设备管理): 优化设备表格加载性能,添加无限滚动功能

docs(.gitignore): 添加数据文件忽略规则
2026-03-27 17:52:35 +08:00

324 lines
11 KiB
React
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import React from 'react';
import { Modal, Button, Space, Divider, Alert } from 'antd';
import {
SwapOutlined,
CloudServerOutlined,
CheckCircleOutlined,
ExclamationCircleOutlined,
ArrowRightOutlined,
} from '@ant-design/icons';
import CloseButton from './CloseButton';
import { designTokens } from '../config/theme';
const PortAddGuideModal = ({ visible, onClose, onSelectType }) => {
const handleSelectSwitch = () => {
onSelectType('switch');
onClose();
};
const handleSelectServer = () => {
onSelectType('server');
onClose();
};
return (
<Modal
open={visible}
closeIcon={<CloseButton />}
onCancel={onClose}
footer={null}
width={560}
zIndex={1050}
style={{ borderRadius: '16px', top: 80 }}
styles={{ body: { padding: 0 } }}
destroyOnClose
>
<div style={{
background: `linear-gradient(135deg, ${designTokens.colors.primary.main} 0%, ${designTokens.colors.primary.dark} 100%)`,
padding: '28px 24px',
borderRadius: '16px 16px 0 0',
}}>
<div style={{
display: 'flex',
alignItems: 'center',
gap: '14px',
}}>
<div style={{
width: '52px',
height: '52px',
borderRadius: '14px',
background: 'rgba(255,255,255,0.2)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
color: '#fff',
}}>
<SwapOutlined style={{ fontSize: '26px' }} />
</div>
<div>
<h3 style={{
margin: 0,
color: '#fff',
fontSize: '20px',
fontWeight: 600,
}}>
选择端口类型
</h3>
<p style={{
margin: '4px 0 0',
color: 'rgba(255,255,255,0.85)',
fontSize: '13px',
}}>
请选择要添加的端口类型
</p>
</div>
</div>
</div>
<div style={{ padding: '24px' }}>
<div style={{
display: 'grid',
gridTemplateColumns: '1fr 1fr',
gap: '16px',
marginBottom: '20px',
}}>
<button
onClick={handleSelectSwitch}
style={{
padding: '24px 20px',
border: `2px solid ${designTokens.colors.success.light}40`,
borderRadius: '14px',
background: designTokens.colors.success.bg,
cursor: 'pointer',
transition: 'all 0.25s ease',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
gap: '12px',
}}
onMouseEnter={e => {
e.currentTarget.style.borderColor = designTokens.colors.success.main;
e.currentTarget.style.boxShadow = `0 4px 16px ${designTokens.colors.success.light}30`;
e.currentTarget.style.transform = 'translateY(-2px)';
}}
onMouseLeave={e => {
e.currentTarget.style.borderColor = `${designTokens.colors.success.light}40`;
e.currentTarget.style.boxShadow = 'none';
e.currentTarget.style.transform = 'translateY(0)';
}}
>
<div style={{
width: '56px',
height: '56px',
borderRadius: '14px',
background: designTokens.colors.success.gradient,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
color: '#fff',
boxShadow: '0 4px 12px rgba(16, 185, 129, 0.3)',
}}>
<SwapOutlined style={{ fontSize: '28px' }} />
</div>
<div style={{ textAlign: 'center' }}>
<div style={{
fontSize: '16px',
fontWeight: 600,
color: designTokens.colors.neutral[800],
marginBottom: '4px',
}}>
交换机端口
</div>
<div style={{
fontSize: '12px',
color: designTokens.colors.neutral[500],
}}>
直接添加端口
</div>
</div>
<div style={{
display: 'flex',
alignItems: 'center',
gap: '4px',
color: designTokens.colors.success.main,
fontSize: '13px',
fontWeight: 500,
}}>
<span>立即添加</span>
<ArrowRightOutlined style={{ fontSize: '11px' }} />
</div>
</button>
<button
onClick={handleSelectServer}
style={{
padding: '24px 20px',
border: `2px solid ${designTokens.colors.primary.light}40`,
borderRadius: '14px',
background: designTokens.colors.primary.bg,
cursor: 'pointer',
transition: 'all 0.25s ease',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
gap: '12px',
}}
onMouseEnter={e => {
e.currentTarget.style.borderColor = designTokens.colors.primary.main;
e.currentTarget.style.boxShadow = `0 4px 16px ${designTokens.colors.primary.light}30`;
e.currentTarget.style.transform = 'translateY(-2px)';
}}
onMouseLeave={e => {
e.currentTarget.style.borderColor = `${designTokens.colors.primary.light}40`;
e.currentTarget.style.boxShadow = 'none';
e.currentTarget.style.transform = 'translateY(0)';
}}
>
<div style={{
width: '56px',
height: '56px',
borderRadius: '14px',
background: designTokens.colors.primary.gradient,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
color: '#fff',
boxShadow: '0 4px 12px rgba(99, 102, 241, 0.3)',
}}>
<CloudServerOutlined style={{ fontSize: '28px' }} />
</div>
<div style={{ textAlign: 'center' }}>
<div style={{
fontSize: '16px',
fontWeight: 600,
color: designTokens.colors.neutral[800],
marginBottom: '4px',
}}>
服务器端口
</div>
<div style={{
fontSize: '12px',
color: designTokens.colors.neutral[500],
}}>
需关联网卡
</div>
</div>
<div style={{
display: 'flex',
alignItems: 'center',
gap: '4px',
color: designTokens.colors.primary.main,
fontSize: '13px',
fontWeight: 500,
}}>
<span>立即添加</span>
<ArrowRightOutlined style={{ fontSize: '11px' }} />
</div>
</button>
</div>
<Divider style={{ margin: '0 0 20px' }}>
<span style={{
fontSize: '12px',
color: designTokens.colors.neutral[400],
fontWeight: 400,
}}>
端口类型说明
</span>
</Divider>
<div style={{
background: designTokens.colors.neutral[50],
borderRadius: '12px',
padding: '16px',
border: `1px solid ${designTokens.colors.neutral[200]}`,
}}>
<div style={{ display: 'flex', flexDirection: 'column', gap: '12px' }}>
<div style={{ display: 'flex', alignItems: 'flex-start', gap: '10px' }}>
<CheckCircleOutlined style={{
color: designTokens.colors.success.main,
fontSize: '16px',
marginTop: '2px',
flexShrink: 0,
}} />
<div>
<div style={{
fontSize: '13px',
fontWeight: 600,
color: designTokens.colors.neutral[800],
marginBottom: '2px',
}}>
交换机端口
</div>
<div style={{
fontSize: '12px',
color: designTokens.colors.neutral[500],
lineHeight: 1.6,
}}>
交换机端口用于网络设备间的连接可以直接创建端口无需关联网卡适用于创建 Uplink 端口Trunk 端口等
</div>
</div>
</div>
<div style={{ display: 'flex', alignItems: 'flex-start', gap: '10px' }}>
<ExclamationCircleOutlined style={{
color: designTokens.colors.warning.main,
fontSize: '16px',
marginTop: '2px',
flexShrink: 0,
}} />
<div>
<div style={{
fontSize: '13px',
fontWeight: 600,
color: designTokens.colors.neutral[800],
marginBottom: '2px',
}}>
服务器端口
</div>
<div style={{
fontSize: '12px',
color: designTokens.colors.neutral[500],
lineHeight: 1.6,
}}>
服务器端口必须关联网卡Network Card),每个端口需要对应一个物理或虚拟网卡请先在网卡管理中添加网卡
</div>
</div>
</div>
</div>
</div>
<Alert
message=""
description={
<div style={{ fontSize: '12px', lineHeight: 1.6 }}>
<strong>提示</strong>如果服务器尚未添加网卡系统会引导您先前往网卡管理添加网卡后再创建端口
</div>
}
type="info"
showIcon
icon={<ExclamationCircleOutlined />}
style={{
marginTop: '16px',
borderRadius: '8px',
background: designTokens.colors.info.bg,
border: `1px solid ${designTokens.colors.info.light}40`,
}}
/>
<div style={{
display: 'flex',
justifyContent: 'flex-end',
marginTop: '20px',
}}>
<Button onClick={onClose} style={{ borderRadius: '8px' }}>
取消
</Button>
</div>
</div>
</Modal>
);
};
export default PortAddGuideModal;