You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

591 lines
20 KiB
HTML

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>海洋生态实时监测智能预警平台</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: "Microsoft YaHei", sans-serif;
}
body {
background: linear-gradient(135deg, #0a1a3a 0%, #0c2a5d 100%);
color: #fff;
overflow-x: hidden;
}
.container {
width: 100%;
padding: 20px;
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 15px 0;
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
margin-bottom: 20px;
}
.title {
font-size: 32px;
font-weight: bold;
background: linear-gradient(90deg, #00c6ff, #0072ff);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
text-shadow: 0 0 10px rgba(0, 198, 255, 0.3);
}
.time-info {
font-size: 18px;
color: #a0c8ff;
}
.dashboard {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: auto;
gap: 20px;
margin-bottom: 20px;
}
.card {
background: rgba(16, 36, 71, 0.7);
border-radius: 10px;
padding: 20px;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
border: 1px solid rgba(64, 144, 255, 0.2);
transition: all 0.3s ease;
position: relative;
overflow: hidden;
}
.card:hover {
transform: translateY(-5px);
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.4);
}
.card::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 4px;
background: linear-gradient(90deg, #00c6ff, #0072ff);
}
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 15px;
}
.card-title {
font-size: 18px;
font-weight: bold;
color: #e0f0ff;
}
.card-icon {
width: 40px;
height: 40px;
background: rgba(0, 114, 255, 0.2);
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
color: #4dabff;
}
.data-value {
font-size: 28px;
font-weight: bold;
margin: 10px 0;
color: #4dabff;
}
.data-desc {
font-size: 14px;
color: #a0c8ff;
}
.trend {
display: flex;
align-items: center;
font-size: 14px;
margin-top: 5px;
}
.trend.up {
color: #00e396;
}
.trend.down {
color: #ff4560;
}
.main-content {
display: grid;
grid-template-columns: 2fr 1fr;
gap: 20px;
margin-bottom: 20px;
}
.map-container {
grid-column: 1 / 2;
height: 500px;
}
.charts-container {
display: grid;
grid-template-columns: 1fr;
gap: 20px;
}
.chart {
height: 240px;
}
.alert-container {
grid-column: 1 / -1;
height: 300px;
}
.alert-list {
height: 240px;
overflow-y: auto;
}
.alert-item {
display: flex;
align-items: center;
padding: 12px 15px;
border-bottom: 1px solid rgba(255, 255, 255, 0.05);
transition: background 0.3s;
}
.alert-item:hover {
background: rgba(255, 255, 255, 0.05);
}
.alert-level {
width: 10px;
height: 10px;
border-radius: 50%;
margin-right: 10px;
}
.level-high {
background: #ff4560;
box-shadow: 0 0 8px #ff4560;
}
.level-medium {
background: #ffa726;
box-shadow: 0 0 8px #ffa726;
}
.level-low {
background: #00e396;
box-shadow: 0 0 8px #00e396;
}
.alert-content {
flex: 1;
}
.alert-title {
font-weight: bold;
margin-bottom: 5px;
}
.alert-desc {
font-size: 13px;
color: #a0c8ff;
}
.alert-time {
font-size: 12px;
color: #7a9ccc;
}
.footer {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 20px;
}
.footer-card {
height: 150px;
}
/* 图表容器样式 */
.chart-container {
width: 100%;
height: 100%;
position: relative;
}
/* 地图样式 */
.map {
width: 100%;
height: 100%;
background: rgba(12, 42, 93, 0.8);
border-radius: 8px;
position: relative;
overflow: hidden;
}
.map-point {
position: absolute;
width: 12px;
height: 12px;
border-radius: 50%;
background: #00c6ff;
box-shadow: 0 0 10px #00c6ff;
transform: translate(-50%, -50%);
cursor: pointer;
}
.map-point::after {
content: '';
position: absolute;
width: 20px;
height: 20px;
border-radius: 50%;
border: 2px solid #00c6ff;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
animation: pulse 2s infinite;
}
@keyframes pulse {
0% {
width: 20px;
height: 20px;
opacity: 1;
}
100% {
width: 40px;
height: 40px;
opacity: 0;
}
}
/* 滚动条样式 */
::-webkit-scrollbar {
width: 6px;
}
::-webkit-scrollbar-track {
background: rgba(255, 255, 255, 0.05);
border-radius: 3px;
}
::-webkit-scrollbar-thumb {
background: rgba(0, 198, 255, 0.5);
border-radius: 3px;
}
::-webkit-scrollbar-thumb:hover {
background: rgba(0, 198, 255, 0.7);
}
/* 响应式调整 */
@media (max-width: 1600px) {
.dashboard {
grid-template-columns: repeat(2, 1fr);
}
.footer {
grid-template-columns: repeat(2, 1fr);
}
}
@media (max-width: 1200px) {
.main-content {
grid-template-columns: 1fr;
}
.map-container {
grid-column: 1 / -1;
}
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<div class="title">海洋生态实时监测智能预警平台</div>
<div class="time-info" id="current-time">2023年11月15日 14:30:25</div>
</div>
<div class="dashboard">
<div class="card">
<div class="card-header">
<div class="card-title">水质综合指数</div>
<div class="card-icon">🌊</div>
</div>
<div class="data-value">92.5</div>
<div class="data-desc">优良</div>
<div class="trend up">↑ 较上月提升 2.3%</div>
</div>
<div class="card">
<div class="card-header">
<div class="card-title">溶解氧含量</div>
<div class="card-icon">💧</div>
</div>
<div class="data-value">7.8 mg/L</div>
<div class="data-desc">正常范围</div>
<div class="trend up">↑ 稳定</div>
</div>
<div class="card">
<div class="card-header">
<div class="card-title">叶绿素浓度</div>
<div class="card-icon">🌿</div>
</div>
<div class="data-value">5.2 μg/L</div>
<div class="data-desc">正常范围</div>
<div class="trend down">↓ 较上周下降 0.5%</div>
</div>
<div class="card">
<div class="card-header">
<div class="card-title">在线监测设备</div>
<div class="card-icon">📡</div>
</div>
<div class="data-value">48/52</div>
<div class="data-desc">4台设备维护中</div>
<div class="trend up">↑ 在线率 92.3%</div>
</div>
</div>
<div class="main-content">
<div class="card map-container">
<div class="card-header">
<div class="card-title">黄河三角洲监测点分布</div>
<div class="card-icon">🗺️</div>
</div>
<div class="map" id="monitoring-map">
<!-- 地图监测点将通过JS动态添加 -->
</div>
</div>
<div class="charts-container">
<div class="card chart">
<div class="card-header">
<div class="card-title">主要污染物浓度趋势</div>
<div class="card-icon">📊</div>
</div>
<div class="chart-container" id="pollution-trend">
<!-- 图表将通过JS动态生成 -->
</div>
</div>
<div class="card chart">
<div class="card-header">
<div class="card-title">水质指标分布</div>
<div class="card-icon">📈</div>
</div>
<div class="chart-container" id="quality-distribution">
<!-- 图表将通过JS动态生成 -->
</div>
</div>
</div>
</div>
<div class="card alert-container">
<div class="card-header">
<div class="card-title">实时预警信息</div>
<div class="card-icon">⚠️</div>
</div>
<div class="alert-list">
<div class="alert-item">
<div class="alert-level level-high"></div>
<div class="alert-content">
<div class="alert-title">A3监测点溶解氧异常</div>
<div class="alert-desc">溶解氧含量低于阈值,可能影响海洋生物生存</div>
</div>
<div class="alert-time">10:25:36</div>
</div>
<div class="alert-item">
<div class="alert-level level-medium"></div>
<div class="alert-content">
<div class="alert-title">B7监测点营养盐超标</div>
<div class="alert-desc">氮磷含量超出正常范围,需关注藻类生长情况</div>
</div>
<div class="alert-time">09:42:15</div>
</div>
<div class="alert-item">
<div class="alert-level level-low"></div>
<div class="alert-content">
<div class="alert-title">C2监测设备通信异常</div>
<div class="alert-desc">设备数据传输中断,技术人员已前往处理</div>
</div>
<div class="alert-time">08:15:22</div>
</div>
<div class="alert-item">
<div class="alert-level level-medium"></div>
<div class="alert-content">
<div class="alert-title">D5区域叶绿素浓度升高</div>
<div class="alert-desc">叶绿素-a浓度较上周上升15%,需持续监测</div>
</div>
<div class="alert-time">昨天 16:38:44</div>
</div>
<div class="alert-item">
<div class="alert-level level-low"></div>
<div class="alert-content">
<div class="alert-title">A1监测点pH值波动</div>
<div class="alert-desc">pH值轻微波动处于正常范围边缘</div>
</div>
<div class="alert-time">昨天 14:20:33</div>
</div>
</div>
</div>
<div class="footer">
<div class="card footer-card">
<div class="card-header">
<div class="card-title">蓝绿藻密度</div>
<div class="card-icon">🔬</div>
</div>
<div class="data-value">126 cells/mL</div>
<div class="data-desc">安全范围</div>
<div class="trend up">↑ 稳定</div>
</div>
<div class="card footer-card">
<div class="card-header">
<div class="card-title">COD含量</div>
<div class="card-icon">🧪</div>
</div>
<div class="data-value">2.8 mg/L</div>
<div class="data-desc">优良</div>
<div class="trend down">↓ 较上月下降 0.2%</div>
</div>
<div class="card footer-card">
<div class="card-header">
<div class="card-title">电导率</div>
<div class="card-icon"></div>
</div>
<div class="data-value">45.2 mS/cm</div>
<div class="data-desc">正常范围</div>
<div class="trend up">↑ 稳定</div>
</div>
<div class="card footer-card">
<div class="card-header">
<div class="card-title">大气颗粒物</div>
<div class="card-icon">🌫️</div>
</div>
<div class="data-value">32 μg/m³</div>
<div class="data-desc">良好</div>
<div class="trend down">↓ 较上周下降 5%</div>
</div>
</div>
</div>
<script>
// 更新当前时间
function updateTime() {
const now = new Date();
const options = {
year: 'numeric',
month: 'long',
day: 'numeric',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false
};
document.getElementById('current-time').textContent = now.toLocaleDateString('zh-CN', options);
}
// 初始化时间
updateTime();
setInterval(updateTime, 1000);
// 创建监测点地图
function createMonitoringMap() {
const map = document.getElementById('monitoring-map');
const points = [
{ top: '30%', left: '35%', name: 'A1' },
{ top: '45%', left: '40%', name: 'A2' },
{ top: '60%', left: '45%', name: 'A3' },
{ top: '35%', left: '55%', name: 'B1' },
{ top: '50%', left: '60%', name: 'B2' },
{ top: '65%', left: '65%', name: 'B3' },
{ top: '40%', left: '70%', name: 'C1' },
{ top: '55%', left: '75%', name: 'C2' },
{ top: '70%', left: '80%', name: 'C3' }
];
points.forEach(point => {
const pointElement = document.createElement('div');
pointElement.className = 'map-point';
pointElement.style.top = point.top;
pointElement.style.left = point.left;
pointElement.setAttribute('data-name', point.name);
pointElement.addEventListener('click', function() {
alert(`查看${point.name}监测点详细信息`);
});
map.appendChild(pointElement);
});
}
// 创建简单图表使用CSS模拟
function createCharts() {
// 这里在实际项目中会使用ECharts、Chart.js等图表库
// 此处仅使用CSS创建简单示意
const pollutionTrend = document.getElementById('pollution-trend');
pollutionTrend.innerHTML = `
<div style="width:100%;height:100%;display:flex;align-items:flex-end;justify-content:space-around;padding:10px;">
<div style="width:8%;background:linear-gradient(to top, #ff4560, #ffa726);height:70%;border-radius:3px;"></div>
<div style="width:8%;background:linear-gradient(to top, #ff4560, #ffa726);height:65%;border-radius:3px;"></div>
<div style="width:8%;background:linear-gradient(to top, #ff4560, #ffa726);height:55%;border-radius:3px;"></div>
<div style="width:8%;background:linear-gradient(to top, #ff4560, #ffa726);height:45%;border-radius:3px;"></div>
<div style="width:8%;background:linear-gradient(to top, #ff4560, #ffa726);height:40%;border-radius:3px;"></div>
<div style="width:8%;background:linear-gradient(to top, #ff4560, #ffa726);height:35%;border-radius:3px;"></div>
<div style="width:8%;background:linear-gradient(to top, #00e396, #00c6ff);height:30%;border-radius:3px;"></div>
<div style="width:8%;background:linear-gradient(to top, #00e396, #00c6ff);height:25%;border-radius:3px;"></div>
<div style="width:8%;background:linear-gradient(to top, #00e396, #00c6ff);height:20%;border-radius:3px;"></div>
<div style="width:8%;background:linear-gradient(to top, #00e396, #00c6ff);height:15%;border-radius:3px;"></div>
</div>
`;
const qualityDistribution = document.getElementById('quality-distribution');
qualityDistribution.innerHTML = `
<div style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;">
<div style="width:150px;height:150px;border-radius:50%;background:conic-gradient(#00e396 0% 65%, #00c6ff 65% 85%, #ffa726 85% 95%, #ff4560 95% 100%);position:relative;">
<div style="position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:80px;height:80px;background:#0a1a3a;border-radius:50%;"></div>
</div>
</div>
`;
}
// 初始化页面
document.addEventListener('DOMContentLoaded', function() {
createMonitoringMap();
createCharts();
});
</script>
</body>
</html>