|
|
@@ -0,0 +1,641 @@
|
|
|
+<template>
|
|
|
+ <div class="dashboard">
|
|
|
+ <div class="bottom-bg"></div>
|
|
|
+ <div class="station-bg"></div>
|
|
|
+ <div class="top-title"></div>
|
|
|
+ <div class="system-title">数字孪生黑林小流域</div>
|
|
|
+
|
|
|
+ <!-- 返回按钮 -->
|
|
|
+ <button class="back-btn" @click="goBack">返回</button>
|
|
|
+
|
|
|
+ <!-- 主要内容区域 -->
|
|
|
+ <div class="main-content">
|
|
|
+ <!-- 左侧面板区域 -->
|
|
|
+ <div class="left-sidebar">
|
|
|
+ <!-- 左侧面板1:水文站介绍 -->
|
|
|
+ <div class="data-card station-intro">
|
|
|
+ <div class="panel-header">
|
|
|
+ <h3>水文站介绍</h3>
|
|
|
+ </div>
|
|
|
+ <div class="panel-content">
|
|
|
+ <div class="image-section">
|
|
|
+ <div class="thumbnail-list">
|
|
|
+ <img src="/src/assets/images/Heilin/图2.jpeg" alt="水文站图片2" @click="changeMainImage('/src/assets/images/Heilin/图2.jpeg')" />
|
|
|
+ <img src="/src/assets/images/Heilin/图3.jpeg" alt="水文站图片3" @click="changeMainImage('/src/assets/images/Heilin/图3.jpeg')" />
|
|
|
+ <img src="/src/assets/images/Heilin/图4.jpeg" alt="水文站图片4" @click="changeMainImage('/src/assets/images/Heilin/图4.jpeg')" />
|
|
|
+ <img src="/src/assets/images/Heilin/图5.jpeg" alt="水文站图片5" @click="changeMainImage('/src/assets/images/Heilin/图5.jpeg')" />
|
|
|
+ <img src="/src/assets/images/Heilin/图6.png" alt="水文站图片6" @click="changeMainImage('/src/assets/images/Heilin/图6.png')" />
|
|
|
+ </div>
|
|
|
+ <div class="main-image">
|
|
|
+ <img :src="mainImageUrl" :alt="mainImageAlt" />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="station-text">
|
|
|
+ <p>黑林水文站位于江苏省连云港市赣榆区黑林镇,是沭河上游的重要水文监测站点。</p>
|
|
|
+ <p>建站于1958年,占地面积约2000平方米,主要负责监测沭河上游的水位、流量、降雨量等水文要素。</p>
|
|
|
+ <p>该站配备了先进的水文监测设备,包括自动水位计、流量计、雨量计等,实现了数据的自动采集和传输。</p>
|
|
|
+ <p>多年来,黑林水文站为当地的防洪抗旱、水资源管理和水环境保护提供了重要的科学依据。</p>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 左侧面板2:视频监控 -->
|
|
|
+ <div class="data-card mt-20 video-monitor">
|
|
|
+ <div class="panel-header">
|
|
|
+ <h3>视频监控</h3>
|
|
|
+ </div>
|
|
|
+ <div class="panel-content">
|
|
|
+ <div class="video-image">
|
|
|
+ <img src="/src/assets/images/Heilin/图5.jpeg" alt="视频监控画面" />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 中间空间 -->
|
|
|
+ <div class="center-space"></div>
|
|
|
+
|
|
|
+ <!-- 右侧面板区域 -->
|
|
|
+ <div class="right-sidebar">
|
|
|
+ <!-- 右侧面板1:历史事件 -->
|
|
|
+ <div class="data-card">
|
|
|
+ <div class="panel-header">
|
|
|
+ <h3>历史事件</h3>
|
|
|
+ </div>
|
|
|
+ <div class="panel-content">
|
|
|
+ <div class="event-item">
|
|
|
+ <div class="event-date">2023-07-21</div>
|
|
|
+ <div class="event-title">暴雨洪水</div>
|
|
|
+ <div class="event-desc">受台风影响,黑林地区出现强降雨,沭河水位迅速上涨,本站测得最大流量120m³/s。</div>
|
|
|
+ </div>
|
|
|
+ <div class="event-item">
|
|
|
+ <div class="event-date">2022-06-15</div>
|
|
|
+ <div class="event-title">设备升级</div>
|
|
|
+ <div class="event-desc">完成水文监测设备升级,实现了数据的实时传输和远程监控。</div>
|
|
|
+ </div>
|
|
|
+ <div class="event-item">
|
|
|
+ <div class="event-date">2021-08-05</div>
|
|
|
+ <div class="event-title">洪水过程</div>
|
|
|
+ <div class="event-desc">沭河上游出现持续降雨,本站监测到完整的洪水过程,为防洪决策提供了重要依据。</div>
|
|
|
+ </div>
|
|
|
+ <div class="event-item">
|
|
|
+ <div class="event-date">2020-05-10</div>
|
|
|
+ <div class="event-title">水质监测</div>
|
|
|
+ <div class="event-desc">开展水质监测工作,各项指标均符合国家地表水标准。</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 右侧面板2:设备状态 -->
|
|
|
+ <div class="data-card mt-20">
|
|
|
+ <div class="panel-header">
|
|
|
+ <h3>设备状态</h3>
|
|
|
+ </div>
|
|
|
+ <div class="panel-content">
|
|
|
+ <div class="device-item">
|
|
|
+ <span class="label">水位计</span>
|
|
|
+ <span class="status online">在线</span>
|
|
|
+ </div>
|
|
|
+ <div class="device-item">
|
|
|
+ <span class="label">流量计</span>
|
|
|
+ <span class="status online">在线</span>
|
|
|
+ </div>
|
|
|
+ <div class="device-item">
|
|
|
+ <span class="label">雨量计</span>
|
|
|
+ <span class="status online">在线</span>
|
|
|
+ </div>
|
|
|
+ <div class="device-item">
|
|
|
+ <span class="label">水质监测仪</span>
|
|
|
+ <span class="status online">在线</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 右侧面板3:实时数据 -->
|
|
|
+ <div class="data-card mt-20">
|
|
|
+ <div class="panel-header">
|
|
|
+ <h3>实时数据</h3>
|
|
|
+ </div>
|
|
|
+ <div class="panel-content">
|
|
|
+ <div class="realtime-item">
|
|
|
+ <span class="label">当前水位</span>
|
|
|
+ <span class="value">3.25m</span>
|
|
|
+ </div>
|
|
|
+ <div class="realtime-item">
|
|
|
+ <span class="label">当前流量</span>
|
|
|
+ <span class="value">12.5m³/s</span>
|
|
|
+ </div>
|
|
|
+ <div class="realtime-item">
|
|
|
+ <span class="label">当前降雨量</span>
|
|
|
+ <span class="value">0.5mm/h</span>
|
|
|
+ </div>
|
|
|
+ <div class="realtime-item">
|
|
|
+ <span class="label">水温</span>
|
|
|
+ <span class="value">18.5°C</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 渐变装饰层(四周暗角) -->
|
|
|
+ <GradientOverlay />
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup>
|
|
|
+import { ref, onMounted } from 'vue'
|
|
|
+import { useRouter } from 'vue-router'
|
|
|
+import GradientOverlay from '../components/gradient-overlay.vue'
|
|
|
+
|
|
|
+const router = useRouter()
|
|
|
+const flowChart = ref(null)
|
|
|
+const mainImageUrl = ref('/src/assets/images/Heilin/图1.jpeg')
|
|
|
+const mainImageAlt = ref('水文站图片1')
|
|
|
+
|
|
|
+const goBack = () => {
|
|
|
+ router.push('/')
|
|
|
+}
|
|
|
+
|
|
|
+const changeMainImage = (imageUrl) => {
|
|
|
+ mainImageUrl.value = imageUrl
|
|
|
+ // 提取图片名称作为alt文本
|
|
|
+ const parts = imageUrl.split('/')
|
|
|
+ const imageName = parts[parts.length - 1]
|
|
|
+ mainImageAlt.value = `水文站图片${imageName.split('.')[0]}`
|
|
|
+}
|
|
|
+
|
|
|
+const drawFlowChart = () => {
|
|
|
+ const canvas = flowChart.value
|
|
|
+ if (!canvas) return
|
|
|
+
|
|
|
+ const ctx = canvas.getContext('2d')
|
|
|
+ ctx.clearRect(0, 0, canvas.width, canvas.height)
|
|
|
+
|
|
|
+ // 模拟流量数据
|
|
|
+ const data = [8, 12, 15, 10, 18, 22, 25, 20, 15, 12, 10, 14]
|
|
|
+ const labels = ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']
|
|
|
+
|
|
|
+ // 计算画布尺寸
|
|
|
+ const width = canvas.width
|
|
|
+ const height = canvas.height
|
|
|
+ const padding = 40
|
|
|
+ const chartWidth = width - 2 * padding
|
|
|
+ const chartHeight = height - 2 * padding
|
|
|
+
|
|
|
+ // 计算数据范围
|
|
|
+ const maxValue = Math.max(...data)
|
|
|
+ const minValue = Math.min(...data)
|
|
|
+ const valueRange = maxValue - minValue
|
|
|
+
|
|
|
+ // 绘制网格
|
|
|
+ ctx.strokeStyle = 'rgba(0, 213, 255, 0.2)'
|
|
|
+ ctx.lineWidth = 1
|
|
|
+
|
|
|
+ // 绘制水平网格线
|
|
|
+ for (let i = 0; i <= 5; i++) {
|
|
|
+ const y = padding + (chartHeight / 5) * i
|
|
|
+ ctx.beginPath()
|
|
|
+ ctx.moveTo(padding, y)
|
|
|
+ ctx.lineTo(width - padding, y)
|
|
|
+ ctx.stroke()
|
|
|
+
|
|
|
+ // 绘制刻度
|
|
|
+ const value = maxValue - (valueRange / 5) * i
|
|
|
+ ctx.fillStyle = 'rgba(255, 255, 255, 0.7)'
|
|
|
+ ctx.font = '12px Arial'
|
|
|
+ ctx.textAlign = 'right'
|
|
|
+ ctx.fillText(value.toFixed(1), padding - 10, y + 4)
|
|
|
+ }
|
|
|
+
|
|
|
+ // 绘制垂直网格线
|
|
|
+ for (let i = 0; i < labels.length; i++) {
|
|
|
+ const x = padding + (chartWidth / (labels.length - 1)) * i
|
|
|
+ ctx.beginPath()
|
|
|
+ ctx.moveTo(x, padding)
|
|
|
+ ctx.lineTo(x, height - padding)
|
|
|
+ ctx.stroke()
|
|
|
+
|
|
|
+ // 绘制刻度
|
|
|
+ ctx.fillStyle = 'rgba(255, 255, 255, 0.7)'
|
|
|
+ ctx.font = '12px Arial'
|
|
|
+ ctx.textAlign = 'center'
|
|
|
+ ctx.fillText(labels[i], x, height - padding + 20)
|
|
|
+ }
|
|
|
+
|
|
|
+ // 绘制流量曲线
|
|
|
+ ctx.strokeStyle = 'rgba(0, 255, 255, 1)'
|
|
|
+ ctx.lineWidth = 2
|
|
|
+ ctx.beginPath()
|
|
|
+
|
|
|
+ for (let i = 0; i < data.length; i++) {
|
|
|
+ const x = padding + (chartWidth / (data.length - 1)) * i
|
|
|
+ const y = padding + chartHeight - ((data[i] - minValue) / valueRange) * chartHeight
|
|
|
+
|
|
|
+ if (i === 0) {
|
|
|
+ ctx.moveTo(x, y)
|
|
|
+ } else {
|
|
|
+ ctx.lineTo(x, y)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ ctx.stroke()
|
|
|
+
|
|
|
+ // 填充曲线下方区域
|
|
|
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.2)'
|
|
|
+ ctx.lineTo(width - padding, height - padding)
|
|
|
+ ctx.lineTo(padding, height - padding)
|
|
|
+ ctx.closePath()
|
|
|
+ ctx.fill()
|
|
|
+}
|
|
|
+
|
|
|
+onMounted(() => {
|
|
|
+ drawFlowChart()
|
|
|
+
|
|
|
+ // 监听窗口 resize 事件,重新绘制图表
|
|
|
+ window.addEventListener('resize', drawFlowChart)
|
|
|
+})
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+.dashboard {
|
|
|
+ width: 1920px;
|
|
|
+ height: 1080px;
|
|
|
+ overflow: hidden;
|
|
|
+ position: relative;
|
|
|
+}
|
|
|
+
|
|
|
+.bottom-bg {
|
|
|
+ position: absolute;
|
|
|
+ bottom: 0;
|
|
|
+ left: 0;
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ background-image: url('/src/assets/images/Heilin/WPS图片(1).jpeg');
|
|
|
+ background-size: 100% 100%;
|
|
|
+ background-position: center;
|
|
|
+ background-repeat: no-repeat;
|
|
|
+ pointer-events: none;
|
|
|
+ z-index: 3;
|
|
|
+}
|
|
|
+
|
|
|
+.station-bg {
|
|
|
+ position: absolute;
|
|
|
+ top: 0;
|
|
|
+ left: 0;
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ background-image: url('/src/assets/images/Heilin/水文站图.jpeg');
|
|
|
+ background-size: cover;
|
|
|
+ background-position: center;
|
|
|
+ background-repeat: no-repeat;
|
|
|
+ pointer-events: none;
|
|
|
+ z-index: 2;
|
|
|
+}
|
|
|
+
|
|
|
+.top-title {
|
|
|
+ position: absolute;
|
|
|
+ top: 0;
|
|
|
+ left: 0;
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ background-image: url('/src/assets/images/顶部大标题.png');
|
|
|
+ background-size: 100% 100%;
|
|
|
+ background-position: center;
|
|
|
+ background-repeat: no-repeat;
|
|
|
+ pointer-events: none;
|
|
|
+ z-index: 4;
|
|
|
+}
|
|
|
+
|
|
|
+.system-title {
|
|
|
+ position: absolute;
|
|
|
+ top: 20px;
|
|
|
+ left: 50%;
|
|
|
+ transform: translateX(-50%);
|
|
|
+ font-size: 36px;
|
|
|
+ font-weight: bold;
|
|
|
+ background: linear-gradient(to bottom, #ffffff 50%, #00d5ff 100%);
|
|
|
+ -webkit-background-clip: text;
|
|
|
+ background-clip: text;
|
|
|
+ color: transparent;
|
|
|
+ text-shadow: 0 0 1px rgba(2, 217, 255, 0.205);
|
|
|
+ z-index: 4;
|
|
|
+ pointer-events: none;
|
|
|
+}
|
|
|
+
|
|
|
+.back-btn {
|
|
|
+ position: absolute;
|
|
|
+ top: 20px;
|
|
|
+ left: 30px;
|
|
|
+ background: linear-gradient(90deg, rgba(0, 60, 120, 0.9), rgba(0, 100, 150, 0.7));
|
|
|
+ border: 1px solid rgba(0, 213, 255, 0.5);
|
|
|
+ color: #ffffff;
|
|
|
+ padding: 8px 16px;
|
|
|
+ border-radius: 4px;
|
|
|
+ cursor: pointer;
|
|
|
+ font-size: 14px;
|
|
|
+ transition: all 0.3s ease;
|
|
|
+ z-index: 4;
|
|
|
+}
|
|
|
+
|
|
|
+.back-btn:hover {
|
|
|
+ background: linear-gradient(90deg, rgba(0, 80, 160, 0.9), rgba(0, 120, 180, 0.7));
|
|
|
+ box-shadow: 0 0 10px rgba(0, 213, 255, 0.5);
|
|
|
+}
|
|
|
+
|
|
|
+.main-content {
|
|
|
+ position: relative;
|
|
|
+ display: flex;
|
|
|
+ height: calc(100% - 80px);
|
|
|
+ padding: 80px 20px 20px;
|
|
|
+ gap: 20px;
|
|
|
+ overflow: auto;
|
|
|
+ z-index: 4;
|
|
|
+}
|
|
|
+
|
|
|
+.left-sidebar {
|
|
|
+ width: 350px;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ gap: 20px;
|
|
|
+}
|
|
|
+
|
|
|
+.center-space {
|
|
|
+ flex: 1;
|
|
|
+}
|
|
|
+
|
|
|
+.right-sidebar {
|
|
|
+ width: 350px;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ gap: 20px;
|
|
|
+}
|
|
|
+
|
|
|
+.data-card {
|
|
|
+ width: 100%;
|
|
|
+ background: rgba(0, 20, 40, 0.7);
|
|
|
+ border-radius: 4px;
|
|
|
+ overflow: hidden;
|
|
|
+ box-shadow: 0 0 10px rgba(0, 212, 255, 0.2);
|
|
|
+}
|
|
|
+
|
|
|
+.panel-header {
|
|
|
+ height: 50px;
|
|
|
+ background-image: url('/src/assets/images/数据小标题.png');
|
|
|
+ background-size: 100% 100%;
|
|
|
+ background-position: center;
|
|
|
+ background-repeat: no-repeat;
|
|
|
+ display: flex;
|
|
|
+ align-items: flex-start;
|
|
|
+ justify-content: space-between;
|
|
|
+ padding: 6px 20px 0;
|
|
|
+ cursor: pointer;
|
|
|
+}
|
|
|
+
|
|
|
+.panel-header h3 {
|
|
|
+ margin: 0;
|
|
|
+ font-size: 18px;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #e0fcff;
|
|
|
+ text-shadow: 0 0 5px rgba(0, 212, 255, 0.5);
|
|
|
+ padding-left: 20px;
|
|
|
+}
|
|
|
+
|
|
|
+.panel-content {
|
|
|
+ padding: 12px;
|
|
|
+ min-height: auto;
|
|
|
+ font-size: 16px;
|
|
|
+ line-height: 1.6;
|
|
|
+ margin-top: -10px;
|
|
|
+ color: #e0fcff;
|
|
|
+}
|
|
|
+
|
|
|
+.station-intro {
|
|
|
+ min-height: 500px;
|
|
|
+}
|
|
|
+
|
|
|
+.station-intro .panel-content {
|
|
|
+ padding: 15px;
|
|
|
+}
|
|
|
+
|
|
|
+.image-section {
|
|
|
+ display: flex;
|
|
|
+ gap: 10px;
|
|
|
+ margin-bottom: 15px;
|
|
|
+ height: 250px;
|
|
|
+}
|
|
|
+
|
|
|
+.thumbnail-list {
|
|
|
+ width: 80px;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ gap: 5px;
|
|
|
+}
|
|
|
+
|
|
|
+.thumbnail-list img {
|
|
|
+ width: 100%;
|
|
|
+ height: 45px;
|
|
|
+ object-fit: cover;
|
|
|
+ border-radius: 4px;
|
|
|
+ border: 1px solid rgba(0, 212, 255, 0.2);
|
|
|
+ cursor: pointer;
|
|
|
+ transition: all 0.3s ease;
|
|
|
+}
|
|
|
+
|
|
|
+.thumbnail-list img:hover {
|
|
|
+ border-color: rgba(0, 212, 255, 0.8);
|
|
|
+ box-shadow: 0 0 5px rgba(0, 212, 255, 0.5);
|
|
|
+}
|
|
|
+
|
|
|
+.main-image {
|
|
|
+ flex: 1;
|
|
|
+ border-radius: 4px;
|
|
|
+ overflow: hidden;
|
|
|
+ border: 1px solid rgba(0, 212, 255, 0.2);
|
|
|
+}
|
|
|
+
|
|
|
+.main-image img {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ object-fit: cover;
|
|
|
+}
|
|
|
+
|
|
|
+.station-text {
|
|
|
+ font-size: 12px;
|
|
|
+ line-height: 1.4;
|
|
|
+}
|
|
|
+
|
|
|
+.station-text p {
|
|
|
+ margin-bottom: 6px;
|
|
|
+}
|
|
|
+
|
|
|
+.station-text p:last-child {
|
|
|
+ margin-bottom: 0;
|
|
|
+}
|
|
|
+
|
|
|
+.video-monitor {
|
|
|
+ min-height: 350px;
|
|
|
+}
|
|
|
+
|
|
|
+.video-image {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ border-radius: 4px;
|
|
|
+ overflow: hidden;
|
|
|
+ border: 1px solid rgba(0, 212, 255, 0.2);
|
|
|
+}
|
|
|
+
|
|
|
+.video-image img {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ object-fit: cover;
|
|
|
+}
|
|
|
+
|
|
|
+.mt-20 {
|
|
|
+ margin-top: 20px;
|
|
|
+}
|
|
|
+
|
|
|
+.event-item {
|
|
|
+ padding: 10px;
|
|
|
+ background: rgba(0, 20, 40, 0.5);
|
|
|
+ border-radius: 4px;
|
|
|
+ border: 1px solid rgba(0, 212, 255, 0.2);
|
|
|
+ margin-bottom: 8px;
|
|
|
+}
|
|
|
+
|
|
|
+.event-item:last-child {
|
|
|
+ margin-bottom: 0;
|
|
|
+}
|
|
|
+
|
|
|
+.event-date {
|
|
|
+ font-size: 12px;
|
|
|
+ color: #62f6fb;
|
|
|
+ margin-bottom: 5px;
|
|
|
+}
|
|
|
+
|
|
|
+.event-title {
|
|
|
+ font-size: 14px;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #00ffff;
|
|
|
+ margin-bottom: 5px;
|
|
|
+ text-shadow: 0 0 3px rgba(0, 212, 255, 0.5);
|
|
|
+}
|
|
|
+
|
|
|
+.event-desc {
|
|
|
+ font-size: 13px;
|
|
|
+ color: #e0fcff;
|
|
|
+ line-height: 1.4;
|
|
|
+}
|
|
|
+
|
|
|
+.device-item {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ padding: 8px 12px;
|
|
|
+ background: rgba(0, 20, 40, 0.5);
|
|
|
+ border-radius: 4px;
|
|
|
+ border: 1px solid rgba(0, 212, 255, 0.2);
|
|
|
+ margin-bottom: 8px;
|
|
|
+}
|
|
|
+
|
|
|
+.device-item:last-child {
|
|
|
+ margin-bottom: 0;
|
|
|
+}
|
|
|
+
|
|
|
+.device-item .label {
|
|
|
+ font-size: 14px;
|
|
|
+ color: #62f6fb;
|
|
|
+}
|
|
|
+
|
|
|
+.device-item .status {
|
|
|
+ font-size: 14px;
|
|
|
+ font-weight: bold;
|
|
|
+ padding: 2px 8px;
|
|
|
+ border-radius: 10px;
|
|
|
+}
|
|
|
+
|
|
|
+.device-item .status.online {
|
|
|
+ color: #00ff00;
|
|
|
+ background: rgba(0, 255, 0, 0.2);
|
|
|
+ border: 1px solid rgba(0, 255, 0, 0.5);
|
|
|
+}
|
|
|
+
|
|
|
+.device-item .status.offline {
|
|
|
+ color: #ff0000;
|
|
|
+ background: rgba(255, 0, 0, 0.2);
|
|
|
+ border: 1px solid rgba(255, 0, 0, 0.5);
|
|
|
+}
|
|
|
+
|
|
|
+.realtime-item {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ padding: 8px 12px;
|
|
|
+ background: rgba(0, 20, 40, 0.5);
|
|
|
+ border-radius: 4px;
|
|
|
+ border: 1px solid rgba(0, 212, 255, 0.2);
|
|
|
+ margin-bottom: 8px;
|
|
|
+}
|
|
|
+
|
|
|
+.realtime-item:last-child {
|
|
|
+ margin-bottom: 0;
|
|
|
+}
|
|
|
+
|
|
|
+.realtime-item .label {
|
|
|
+ font-size: 14px;
|
|
|
+ color: #62f6fb;
|
|
|
+}
|
|
|
+
|
|
|
+.realtime-item .value {
|
|
|
+ font-size: 16px;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #00ffff;
|
|
|
+ text-shadow: 0 0 3px rgba(0, 212, 255, 0.5);
|
|
|
+}
|
|
|
+
|
|
|
+/* 响应式设计 */
|
|
|
+@media (max-width: 1200px) {
|
|
|
+ .dashboard {
|
|
|
+ width: 100%;
|
|
|
+ height: 100vh;
|
|
|
+ }
|
|
|
+
|
|
|
+ .main-content {
|
|
|
+ flex-direction: column;
|
|
|
+ }
|
|
|
+
|
|
|
+ .left-sidebar,
|
|
|
+ .center-space,
|
|
|
+ .right-sidebar {
|
|
|
+ flex: 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ .center-space {
|
|
|
+ height: 50px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .data-card {
|
|
|
+ max-height: none;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+@media (max-width: 768px) {
|
|
|
+ .system-title {
|
|
|
+ font-size: 24px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .back-btn {
|
|
|
+ top: 15px;
|
|
|
+ left: 20px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .main-content {
|
|
|
+ padding: 70px 10px 10px;
|
|
|
+ gap: 10px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .panel-content {
|
|
|
+ padding: 15px;
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|