<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>网络安全监控中心</title><script src="https://cdn.tailwindcss.com"></script><link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet"><script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script><!-- 配置Tailwind自定义颜色和字体 --><script>tailwind.config = {theme: {extend: {colors: {primary: '#165DFF',secondary: '#0E2E8B',accent: '#FF6B35',danger: '#E63946',darkBlue: '#0A2463',lightBlue: '#3E92CC',cardBlue: '#1A3A6B'},fontFamily: {sans: ['Inter', 'system-ui', 'sans-serif'],},}}}</script><style type="text/tailwindcss">@layer utilities {.content-auto {content-visibility: auto;}.scrollbar-hide {-ms-overflow-style: none;scrollbar-width: none;}.scrollbar-hide::-webkit-scrollbar {display: none;}.text-shadow {text-shadow: 0 2px 4px rgba(0,0,0,0.1);}.bg-gradient-blue {background: linear-gradient(135deg, #0A2463 0%, #165DFF 100%);}.card-hover {transition: all 0.3s ease;}.card-hover:hover {transform: translateY(-3px);box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);}}</style>
</head>
<body class="bg-gradient-to-br from-darkBlue to-primary min-h-screen text-gray-100 font-sans"><!-- 顶部导航栏 --><header class="bg-darkBlue/80 backdrop-blur-md border-b border-primary/30 sticky top-0 z-50"><div class="container mx-auto px-4 py-3 flex items-center justify-between"><div class="flex items-center space-x-3"><i class="fa fa-shield text-2xl text-accent"></i><h1 class="text-xl md:text-2xl font-bold text-shadow">网络安全监控中心</h1></div><div class="flex items-center space-x-4"><div class="hidden md:flex items-center space-x-2 text-sm"><span class="text-gray-300">当前时间:</span><span id="current-time" class="font-medium"></span></div><button class="bg-primary/20 hover:bg-primary/40 transition-colors p-2 rounded-full"><i class="fa fa-bell-o"></i></button><div class="h-8 w-8 rounded-full bg-accent flex items-center justify-center"><span class="text-xs font-bold">AD</span></div></div></div></header><!-- 主内容区 --><main class="container mx-auto px-4 py-6"><!-- 标签页导航 --><div class="mb-8 flex justify-center"><div class="inline-flex bg-secondary/30 p-1 rounded-lg"><button class="tab-button active px-6 py-2 rounded-md bg-primary font-medium transition-all" data-tab="threat">威胁态势</button><button class="tab-button px-6 py-2 rounded-md hover:bg-primary/50 font-medium transition-all" data-tab="compromise">失陷态势</button><button class="tab-button px-6 py-2 rounded-md hover:bg-primary/50 font-medium transition-all" data-tab="apt">APT情报</button></div></div><!-- 主要内容网格 --><div class="grid grid-cols-1 lg:grid-cols-3 gap-6"><!-- 左侧攻击事件列表 --><div class="lg:col-span-1"><div class="bg-cardBlue/60 backdrop-blur-sm rounded-xl shadow-lg overflow-hidden border border-primary/20"><div class="p-4 border-b border-primary/20 flex justify-between items-center"><h2 class="text-lg font-semibold">最近30日发生的网络攻击行为</h2><span class="text-xs bg-accent/20 text-accent px-2 py-1 rounded-full">实时更新</span></div><div class="flex border-b border-primary/20"><div class="w-1/3 py-2 px-4 bg-danger/80 text-center font-medium text-sm">攻击源地址</div><div class="w-2/3 py-2 px-4 bg-primary text-center font-medium text-sm">被攻击地址</div></div><div class="max-h-[600px] overflow-y-auto scrollbar-hide"><div id="attack-list" class="divide-y divide-primary/10"><!-- 攻击事件项将通过JavaScript动态生成 --></div></div></div></div><!-- 右侧世界地图 --><div class="lg:col-span-2"><div class="bg-cardBlue/60 backdrop-blur-sm rounded-xl shadow-lg overflow-hidden border border-primary/20 h-full flex flex-col"><div class="p-4 border-b border-primary/20"><h2 class="text-lg font-semibold">全球网络攻击分布</h2></div><div class="flex-1 p-4 relative"><div class="absolute top-4 right-4 bg-darkBlue/70 backdrop-blur-sm rounded-lg p-3 shadow-lg border border-primary/20 z-10"><div class="flex items-center space-x-2 mb-2"><div class="w-3 h-3 rounded-full bg-accent"></div><span class="text-sm">攻击路径</span></div><div class="flex items-center space-x-2 mb-2"><div class="w-3 h-3 rounded-full bg-danger"></div><span class="text-sm">攻击源</span></div><div class="flex items-center space-x-2"><div class="w-3 h-3 rounded-full bg-primary"></div><span class="text-sm">目标地址</span></div></div><div class="h-full relative"><!-- 地图容器 --><div id="world-map" class="w-full h-full"></div></div></div><!-- 统计数据卡片 --><div class="grid grid-cols-2 md:grid-cols-4 gap-4 p-4 border-t border-primary/20"><div class="bg-darkBlue/50 rounded-lg p-3 card-hover"><div class="text-xs text-gray-300 mb-1">总攻击次数</div><div class="text-2xl font-bold text-white">2,847</div><div class="text-xs text-green-400 mt-1 flex items-center"><i class="fa fa-arrow-up mr-1"></i> 12.5%</div></div><div class="bg-darkBlue/50 rounded-lg p-3 card-hover"><div class="text-xs text-gray-300 mb-1">攻击源IP</div><div class="text-2xl font-bold text-white">147</div><div class="text-xs text-green-400 mt-1 flex items-center"><i class="fa fa-arrow-up mr-1"></i> 3.2%</div></div><div class="bg-darkBlue/50 rounded-lg p-3 card-hover"><div class="text-xs text-gray-300 mb-1">目标IP</div><div class="text-2xl font-bold text-white">892</div><div class="text-xs text-red-400 mt-1 flex items-center"><i class="fa fa-arrow-down mr-1"></i> 2.1%</div></div><div class="bg-darkBlue/50 rounded-lg p-3 card-hover"><div class="text-xs text-gray-300 mb-1">高危攻击</div><div class="text-2xl font-bold text-white">346</div><div class="text-xs text-green-400 mt-1 flex items-center"><i class="fa fa-arrow-up mr-1"></i> 8.7%</div></div></div></div></div></div></main><script>// 实时时间更新function updateTime() {const now = new Date();const options = { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit' };document.getElementById('current-time').textContent = now.toLocaleString('zh-CN', options);}setInterval(updateTime, 1000);updateTime();// 标签页切换功能const tabButtons = document.querySelectorAll('.tab-button');tabButtons.forEach(button => {button.addEventListener('click', () => {// 移除所有活动状态tabButtons.forEach(btn => btn.classList.remove('active', 'bg-primary'));tabButtons.forEach(btn => btn.classList.add('hover:bg-primary/50'));// 添加当前活动状态button.classList.add('active', 'bg-primary');button.classList.remove('hover:bg-primary/50');// 这里可以添加不同标签页内容的切换逻辑const tabName = button.getAttribute('data-tab');console.log(`切换到${tabName}标签页`);});});// 攻击数据const attackData = [{ source: "172.192.38.118", sourceCountry: "au", target: "121.***.**.69", targetCountry: "cn", severity: "high" },{ source: "172.192.38.118", sourceCountry: "au", target: "121.***.**.75", targetCountry: "cn", severity: "high" },{ source: "172.192.38.118", sourceCountry: "au", target: "121.***.**.76", targetCountry: "cn", severity: "medium" },{ source: "172.192.38.118", sourceCountry: "au", target: "121.***.**.77", targetCountry: "cn", severity: "high" },{ source: "172.192.38.118", sourceCountry: "au", target: "121.***.**.78", targetCountry: "cn", severity: "medium" },{ source: "172.192.38.118", sourceCountry: "au", target: "121.***.**.79", targetCountry: "cn", severity: "low" },{ source: "172.192.38.118", sourceCountry: "au", target: "121.***.**.80", targetCountry: "cn", severity: "medium" },{ source: "172.192.38.118", sourceCountry: "au", target: "121.***.**.81", targetCountry: "cn", severity: "high" },{ source: "172.192.38.118", sourceCountry: "au", target: "121.***.**.82", targetCountry: "cn", severity: "medium" },{ source: "47.***.30.140", sourceCountry: "us", target: "218.***.**.102", targetCountry: "cn", severity: "high" },{ source: "64.***.12.89", sourceCountry: "de", target: "117.***.**.56", targetCountry: "cn", severity: "low" },{ source: "89.***.45.22", sourceCountry: "uk", target: "202.***.**.91", targetCountry: "cn", severity: "medium" },{ source: "103.***.76.15", sourceCountry: "jp", target: "180.***.**.143", targetCountry: "cn", severity: "high" },{ source: "212.***.33.77", sourceCountry: "fr", target: "58.***.**.207", targetCountry: "cn", severity: "medium" },];// 生成攻击列表const attackList = document.getElementById('attack-list');attackData.forEach(attack => {const attackItem = document.createElement('div');attackItem.className = 'flex hover:bg-primary/10 transition-colors';// 攻击源地址列const sourceCol = document.createElement('div');sourceCol.className = 'w-1/3 p-3';sourceCol.innerHTML = `<div class="flex items-center"><img src="https://flagcdn.com/w80/${attack.sourceCountry}.png" alt="${attack.sourceCountry}国旗" class="w-5 h-3 mr-2 rounded"><span class="text-sm truncate">${attack.source}</span></div>`;// 目标地址列const targetCol = document.createElement('div');targetCol.className = 'w-2/3 p-3 flex items-center justify-between';targetCol.innerHTML = `<div class="flex items-center"><img src="https://flagcdn.com/w80/${attack.targetCountry}.png" alt="${attack.targetCountry}国旗" class="w-5 h-3 mr-2 rounded"><span class="text-sm truncate">${attack.target}</span></div><span class="text-xs px-2 py-0.5 rounded-full ${attack.severity === 'high' ? 'bg-danger/80' :attack.severity === 'medium' ? 'bg-yellow-500/80' : 'bg-green-500/80'}">${attack.severity === 'high' ? '高危' :attack.severity === 'medium' ? '中危' : '低危'}</span>`;attackItem.appendChild(sourceCol);attackItem.appendChild(targetCol);attackList.appendChild(attackItem);});// 国家经纬度数据const countryCoordinates = {'au': { name: '澳大利亚', lng: 133.7751, lat: -25.2744 },'cn': { name: '中国', lng: 104.1954, lat: 35.8617 },'us': { name: '美国', lng: -95.7129, lat: 37.0902 },'de': { name: '德国', lng: 10.4515, lat: 51.1657 },'uk': { name: '英国', lng: -3.4360, lat: 55.3781 },'jp': { name: '日本', lng: 138.2529, lat: 36.2048 },'fr': { name: '法国', lng: 2.2137, lat: 46.2276 }};// 初始化地图window.addEventListener('load', function() {// 创建地图实例const chartDom = document.getElementById('world-map');const myChart = echarts.init(chartDom);// 处理地图数据function getAttackPaths() {return attackData.map(attack => {const source = countryCoordinates[attack.sourceCountry];const target = countryCoordinates[attack.targetCountry];return {source: {name: source.name,value: [source.lng, source.lat]},target: {name: target.name,value: [target.lng, target.lat]}};});}function getUniqueSources() {const sources = {};attackData.forEach(attack => {if (!sources[attack.sourceCountry]) {const country = countryCoordinates[attack.sourceCountry];sources[attack.sourceCountry] = {name: country.name,value: [country.lng, country.lat]};}});return Object.values(sources);}function getUniqueTargets() {const targets = {};attackData.forEach(attack => {if (!targets[attack.targetCountry]) {const country = countryCoordinates[attack.targetCountry];targets[attack.targetCountry] = {name: country.name,value: [country.lng, country.lat]};}});return Object.values(targets);}// 注册世界地图fetch('https://cdn.jsdelivr.net/npm/echarts/map/json/world.json').then(response => response.json()).then(worldJson => {echarts.registerMap('world', worldJson);// 设置地图配置const option = {backgroundColor: 'transparent',tooltip: {trigger: 'item',formatter: function(params) {return `${params.name}<br/>攻击次数: ${getAttackCount(params.name)}`;}},geo: {map: 'world',roam: true, // 开启缩放和平移label: {show: false},itemStyle: {areaColor: 'rgba(26, 58, 107, 0.6)',borderColor: 'rgba(22, 93, 255, 0.3)',borderWidth: 1},emphasis: {itemStyle: {areaColor: 'rgba(22, 93, 255, 0.5)'}}},series: [// 攻击路径{name: '攻击路径',type: 'lines',zlevel: 2,effect: {show: true,period: 6,trailLength: 0.3,symbol: 'arrow',symbolSize: 6,color: '#FF6B35'},lineStyle: {width: 2,color: '#FF6B35',curveness: 0.2,opacity: 0.7},data: getAttackPaths()},// 攻击源点{name: '攻击源',type: 'scatter',coordinateSystem: 'geo',zlevel: 3,symbol: 'circle',symbolSize: 10,itemStyle: {color: '#E63946',shadowBlur: 10,shadowColor: '#E63946'},data: getUniqueSources()},// 目标点{name: '目标地址',type: 'scatter',coordinateSystem: 'geo',zlevel: 3,symbol: 'circle',symbolSize: 10,itemStyle: {color: '#165DFF',shadowBlur: 10,shadowColor: '#165DFF'},data: getUniqueTargets()}]};// 计算每个国家的攻击次数function getAttackCount(countryName) {let count = 0;attackData.forEach(attack => {if (countryCoordinates[attack.sourceCountry]?.name === countryName ||countryCoordinates[attack.targetCountry]?.name === countryName) {count++;}});return count;}// 设置配置并渲染地图myChart.setOption(option);// 窗口大小变化时调整地图大小window.addEventListener('resize', function() {myChart.resize();});}).catch(error => {console.error('地图加载失败:', error);// 显示错误信息const mapContainer = document.getElementById('world-map');mapContainer.innerHTML = `<div class="flex items-center justify-center h-full text-red-400"><i class="fa fa-exclamation-triangle mr-2"></i>地图加载失败,请检查网络连接</div>`;});});</script>
</body>
</html>