Преглед на файлове

新增工程安全页面

BAIPCHOME\15818 преди 2 седмици
родител
ревизия
3c01f0f595
променени са 5 файла, в които са добавени 340 реда и са изтрити 47 реда
  1. 20 22
      src/components/HydrologyForecastPanel.vue
  2. 34 0
      src/style.css
  3. 256 0
      src/views/EngineeringSafetyView.vue
  4. 13 3
      src/views/HomeView.vue
  5. 17 22
      src/views/OverviewView.vue

+ 20 - 22
src/components/HydrologyForecastPanel.vue

@@ -1291,7 +1291,7 @@ export default {
 }
 
 .card-header {
-  height: 50px;
+  height: 42px;
   background-image: url('/src/assets/images/数据小标题.png');
   background-size: 100% 100%;
   background-position: center;
@@ -1299,12 +1299,12 @@ export default {
   display: flex;
   align-items: flex-start;
   justify-content: space-between;
-  padding: 6px 20px 0;
+  padding: 4px 16px 0;
   cursor: pointer;
 }
 
 .card-title {
-  font-size: 18px;
+  font-size: var(--fs-card-title);
   font-weight: bold;
   color: #e0fcff;
   margin: 0;
@@ -1332,9 +1332,7 @@ export default {
 }
 
 .card-body {
-  padding: 12px;
-  min-height: auto;
-  font-size: 16px;
+  font-size: var(--fs-body);
   line-height: 1.6;
   margin-top: -10px;
 }
@@ -1873,7 +1871,7 @@ export default {
 
 .wq-param-name {
   color: #7bbef6;
-  font-size: 10px;
+    font-size: var(--fs-label);  font-weight: var(--fw-label);
   line-height: 1.2;
 }
 
@@ -1894,13 +1892,13 @@ export default {
 
 .wq-unit {
   color: #7bbef6;
-  font-size: 10px;
+    font-size: var(--fs-unit);  font-weight: var(--fw-normal);
   font-weight: normal;
   margin-left: 2px;
 }
 
 .wq-param-status {
-  font-size: 10px;
+    font-size: var(--fs-status);
   font-weight: bold;
   padding: 1px 5px;
   border-radius: 2px;
@@ -2060,17 +2058,17 @@ export default {
   background-size: 100% 100%;
   background-position: center;
   background-repeat: no-repeat;
-  padding: 4px 8px;
+  padding: 4px 6px;
   display: flex;
   flex-direction: row;
   align-items: center;
-  gap: 6px;
-  min-height: 40px;
+  gap: 4px;
+  min-height: 36px;
 }
 
 .compare-icon {
-  width: 40px;
-  height: 32px;
+  width: 32px;
+  height: 26px;
   flex-shrink: 0;
 }
 
@@ -2092,7 +2090,7 @@ export default {
 
 .compare-card-label {
   color: #7bbef6;
-  font-size: 10px;
+    font-size: var(--fs-label);  font-weight: var(--fw-label);
 }
 
 .compare-card-value {
@@ -2103,7 +2101,7 @@ export default {
 
 .compare-unit {
   color: #7bbef6;
-  font-size: 11px;
+    font-size: var(--fs-unit);  font-weight: var(--fw-normal);
   font-weight: normal;
 }
 
@@ -2117,7 +2115,7 @@ export default {
 }
 
 .compare-card-level {
-  font-size: 14px;
+    font-size: var(--fs-status);
   font-weight: bold;
   padding: 1px 5px;
   border-radius: 2px;
@@ -2179,7 +2177,7 @@ export default {
 
 .monitor-chart-label {
   color: #62f6fb;
-  font-size: 12px;
+    font-size: var(--fs-label);  font-weight: var(--fw-label);
   font-weight: bold;
   margin-bottom: 6px;
 }
@@ -2202,17 +2200,17 @@ export default {
   flex-direction: row;
   align-items: center;
   justify-content: space-between;
-  padding: 4px 16px;
+  padding: 3px 10px;
   background-image: url('/src/assets/images/卡片背景2.png');
   background-size: 100% 100%;
   background-position: center;
   background-repeat: no-repeat;
-  height: 50px;
+  height: 42px;
 }
 
 .water-stat-label {
   color: #62f6fb;
-  font-size: 13px;
+    font-size: var(--fs-label);  font-weight: var(--fw-label);
   margin-bottom: 0;
   text-align: left;
   line-height: 1.2;
@@ -2221,7 +2219,7 @@ export default {
 
 .water-stat-value {
   color: #ffffff;
-  font-size: 22px;
+    font-size: var(--fs-value-xl);  font-weight: var(--fw-value);
   font-weight: bold;
   text-shadow: 0 0 6px rgba(0, 212, 255, 0.5);
   line-height: 1.2;

+ 34 - 0
src/style.css

@@ -1,4 +1,21 @@
 :root {
+  /* ========================================
+   大屏数据可视化字体系统
+   ======================================== */
+  --fs-card-title: 16px;
+  --fs-section-title: 14px;
+  --fs-body: 13px;
+  --fs-value-xl: 22px;
+  --fs-value-lg: 18px;
+  --fs-value-md: 15px;
+  --fs-label: 12px;
+  --fs-unit: 11px;
+  --fs-status: 11px;
+  --fs-small: 10px;
+  --fw-title: 700;
+  --fw-value: 700;
+  --fw-label: 400;
+  --fw-normal: 400;
   font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
   line-height: 1.5;
   font-weight: 400;
@@ -66,6 +83,23 @@ button:focus-visible {
 
 @media (prefers-color-scheme: light) {
   :root {
+  /* ========================================
+   大屏数据可视化字体系统
+   ======================================== */
+  --fs-card-title: 16px;
+  --fs-section-title: 14px;
+  --fs-body: 13px;
+  --fs-value-xl: 22px;
+  --fs-value-lg: 18px;
+  --fs-value-md: 15px;
+  --fs-label: 12px;
+  --fs-unit: 11px;
+  --fs-status: 11px;
+  --fs-small: 10px;
+  --fw-title: 700;
+  --fw-value: 700;
+  --fw-label: 400;
+  --fw-normal: 400;
     color: #213547;
     background-color: #ffffff;
   }

+ 256 - 0
src/views/EngineeringSafetyView.vue

@@ -0,0 +1,256 @@
+<template>
+  <div class="safety-container">
+    <div class="tab-bar">
+      <div class="tab-item" :class="{ active: currentTab === 'dam' }" @click="currentTab = 'dam'">大坝整体</div>
+      <div class="tab-item" :class="{ active: currentTab === 'spillway' }" @click="currentTab = 'spillway'">泄洪设施</div>
+      <div class="tab-item" :class="{ active: currentTab === 'conveyance' }" @click="currentTab = 'conveyance'">输水设施</div>
+      <div class="tab-item" :class="{ active: currentTab === 'bank' }" @click="currentTab = 'bank'">库岸稳定</div>
+    </div>
+    <div class="safety-scroll-area">
+      <div v-if="currentTab === 'dam'" class="tab-content">
+        <div class="left-sidebar">
+          <div class="data-card">
+            <div class="card-header">
+              <h3 class="card-title">大坝变形监测</h3>
+              <div class="header-actions"><span class="update-time">单位:mm</span></div>
+            </div>
+            <div class="card-body chart-body">
+              <div class="monitor-chart-box">
+                <div class="monitor-chart-label">变形趋势</div>
+                <canvas id="deformationChart" width="320" height="170"></canvas>
+                <div class="chart-legend">
+                  <span class="legend-dot dot-horizontal"></span>水平位移
+                  <span class="legend-dot dot-vertical" style="margin-left:12px;"></span>垂直位移
+                </div>
+              </div>
+              <div class="water-stats-row" style="margin-top:4px;">
+                <div class="water-stat-card">
+                  <div class="water-stat-label">最大水平位移</div>
+                  <div class="water-stat-value">12.5</div>
+                </div>
+                <div class="water-stat-card">
+                  <div class="water-stat-label">最大垂直位移</div>
+                  <div class="water-stat-value">8.3</div>
+                </div>
+              </div>
+            </div>
+          </div>
+          <div class="data-card mt-10">
+            <div class="card-header">
+              <h3 class="card-title">渗流监测</h3>
+              <div class="header-actions"><span class="update-time">单位:L/s</span></div>
+            </div>
+            <div class="card-body chart-body">
+              <div class="water-stats-row">
+                <div class="water-stat-card">
+                  <div class="water-stat-label">渗流量</div>
+                  <div class="water-stat-value">3.5</div>
+                </div>
+                <div class="water-stat-card">
+                  <div class="water-stat-label">坝基扬压力</div>
+                  <div class="water-stat-value">18.2</div>
+                </div>
+              </div>
+              <div class="monitor-chart-box" style="margin-top:4px;">
+                <div class="monitor-chart-label">渗流趋势</div>
+                <canvas id="seepageChart" width="320" height="170"></canvas>
+                <div class="chart-legend">
+                  <span class="legend-dot dot-seepage"></span>渗流量
+                  <span class="legend-dot dot-pressure" style="margin-left:12px;"></span>渗流压力(kPa)
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+        <div class="right-sidebar">
+          <div class="data-card">
+            <div class="card-header">
+              <h3 class="card-title">安全状态评估</h3>
+            </div>
+            <div class="card-body chart-body">
+              <div class="safety-assessment-row">
+                <div class="safety-pie-section">
+                  <canvas id="statusPieChart" width="140" height="140"></canvas>
+                  <div class="pie-legend">
+                    <div class="pie-legend-item" v-for="item in pieData" :key="item.name">
+                      <span class="pie-dot" :style="{ background: item.color }"></span>
+                      <span class="pie-name">{{ item.name }}</span>
+                      <span class="pie-count">{{ item.count }}个</span>
+                    </div>
+                  </div>
+                </div>
+                <div class="safety-assessment-section">
+                  <div class="safety-assessment-bar">
+                    <div class="safety-assessment-grade">一类坝</div>
+                    <div class="safety-assessment-texts">
+                      <div class="safety-assessment-text">评估时间:2026-05-15</div>
+                      <div class="safety-assessment-text">运行正常,安全可靠</div>
+                    </div>
+                  </div>
+                  <div class="safety-assessment-tags">
+                    <div class="assess-tag good" v-for="item in assessmentIndicators" :key="item">{{ item }}</div>
+                  </div>
+                </div>
+              </div>
+            </div>
+          </div>
+          <div class="data-card mt-10">
+            <div class="card-header">
+              <h3 class="card-title">监测点状态</h3>
+              <div class="header-actions"><span class="update-time">共 {{ monitorList.length }} 个测点</span></div>
+            </div>
+            <div class="card-body card-body-tight">
+              <div class="monitor-table">
+                <div class="monitor-table-header">
+                  <span class="col-name">测点名称</span>
+                  <span class="col-value">当前值</span>
+                  <span class="col-status">状态</span>
+                  <span class="col-trend">趋势</span>
+                </div>
+                <div class="monitor-table-body">
+                  <div class="monitor-row" v-for="item in monitorList" :key="item.name">
+                    <span class="col-name">{{ item.name }}</span>
+                    <span class="col-value">{{ item.value }}{{ item.unit }}</span>
+                    <span class="col-status"><span class="status-tag" :class="item.status">{{ item.statusText }}</span></span>
+                    <span class="col-trend"><span class="trend-icon" :class="item.trend">{{ item.trend === 'up' ? '↑' : item.trend === 'down' ? '↓' : '→' }}</span></span>
+                  </div>
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+      <div v-if="currentTab === 'spillway'" class="tab-content tab-placeholder"><div class="placeholder-text">泄洪设施监测数据</div></div>
+      <div v-if="currentTab === 'conveyance'" class="tab-content tab-placeholder"><div class="placeholder-text">输水设施监测数据</div></div>
+      <div v-if="currentTab === 'bank'" class="tab-content tab-placeholder"><div class="placeholder-text">库岸稳定监测数据</div></div>
+    </div>
+  </div>
+</template>
+<script>
+import * as echarts from "echarts";
+export default {
+  name: "EngineeringSafetyView",
+  data() {
+    return {
+      currentTab: "dam",
+      monitorList: [
+        { name: "坝顶水平位移-01", value: "12.5", unit: "mm", status: "normal", statusText: "正常", trend: "up" },
+        { name: "坝顶水平位移-02", value: "11.8", unit: "mm", status: "normal", statusText: "正常", trend: "steady" },
+        { name: "坝基垂直位移-01", value: "8.3", unit: "mm", status: "normal", statusText: "正常", trend: "down" },
+        { name: "坝基垂直位移-02", value: "7.9", unit: "mm", status: "normal", statusText: "正常", trend: "steady" },
+        { name: "渗流压力-P01", value: "25.6", unit: "kPa", status: "normal", statusText: "正常", trend: "up" },
+        { name: "渗流压力-P02", value: "22.1", unit: "kPa", status: "normal", statusText: "正常", trend: "steady" },
+        { name: "绕坝渗流-S01", value: "1.2", unit: "L/s", status: "normal", statusText: "正常", trend: "steady" },
+        { name: "裂缝开合度-C01", value: "1.2", unit: "mm", status: "warning", statusText: "注意", trend: "up" },
+        { name: "钢筋应力-R01", value: "45.2", unit: "MPa", status: "normal", statusText: "正常", trend: "steady" },
+        { name: "库岸变形-B01", value: "3.2", unit: "mm", status: "normal", statusText: "正常", trend: "down" },
+      ],
+      pieData: [
+        { name: "正常", count: 8, color: "#22c55e" },
+        { name: "注意", count: 2, color: "#ffd93d" },
+        { name: "警戒", count: 0, color: "#f97316" },
+        { name: "危险", count: 0, color: "#ef4444" },
+      ],
+      assessmentIndicators: ["变形指标 合格", "渗流指标 合格", "结构指标 合格", "环境指标 合格"],
+      deformationChart: null,
+      seepageChart: null,
+      statusPieChart: null,
+    };
+  },
+  mounted() { this.$nextTick(() => this.initCharts()); },
+  beforeUnmount() {
+    if (this.deformationChart) this.deformationChart.dispose();
+    if (this.seepageChart) this.seepageChart.dispose();
+    if (this.statusPieChart) this.statusPieChart.dispose();
+  },
+  methods: {
+    initCharts() {
+      if (!echarts) return;
+      const dc = document.getElementById("deformationChart");
+      if (dc) {
+        if (this.deformationChart) this.deformationChart.dispose();
+        this.deformationChart = echarts.init(dc);
+        this.deformationChart.setOption({ animation: false, tooltip: { trigger: "axis" }, grid: { left: "8%", right: "5%", top: "8%", bottom: "12%" }, xAxis: { type: "category", data: ["1月","2月","3月","4月","5月","6月"], axisLine: { lineStyle: { color: "#7bbef6" } }, axisLabel: { color: "#7bbef6", fontSize: 9 } }, yAxis: { type: "value", name: "mm", nameTextStyle: { color: "#7bbef6", fontSize: 9 }, axisLine: { lineStyle: { color: "#7bbef6" } }, axisLabel: { color: "#7bbef6", fontSize: 9 }, splitLine: { lineStyle: { color: "rgba(123,190,246,0.15)" } } }, series: [{ name: "水平位移", type: "line", data: [8.2,9.5,10.8,11.2,12.0,12.5], smooth: true, symbol: "circle", symbolSize: 4, lineStyle: { color: "#62f6fb", width: 2 }, itemStyle: { color: "#62f6fb" }, areaStyle: { color: "rgba(98,246,251,0.1)" } }, { name: "垂直位移", type: "line", data: [5.1,6.2,7.0,7.5,8.0,8.3], smooth: true, symbol: "diamond", symbolSize: 4, lineStyle: { color: "#fbbf24", width: 2 }, itemStyle: { color: "#fbbf24" }, areaStyle: { color: "rgba(251,191,36,0.08)" } }] });
+      }
+      const sc = document.getElementById("seepageChart");
+      if (sc) {
+        if (this.seepageChart) this.seepageChart.dispose();
+        this.seepageChart = echarts.init(sc);
+        this.seepageChart.setOption({ animation: false, tooltip: { trigger: "axis" }, legend: { data: ["渗流量","渗流压力"], textStyle: { color: "#7bbef6", fontSize: 9 }, bottom: 0, itemWidth: 10, itemHeight: 8 }, grid: { left: "8%", right: "5%", top: "8%", bottom: "22%" }, xAxis: { type: "category", data: ["1月","2月","3月","4月","5月","6月"], axisLine: { lineStyle: { color: "#7bbef6" } }, axisLabel: { color: "#7bbef6", fontSize: 9 } }, yAxis: { type: "value", nameTextStyle: { color: "#7bbef6", fontSize: 9 }, axisLine: { lineStyle: { color: "#7bbef6" } }, axisLabel: { color: "#7bbef6", fontSize: 9 }, splitLine: { lineStyle: { color: "rgba(123,190,246,0.15)" } } }, series: [{ name: "渗流量", type: "line", data: [4.2,3.8,3.6,3.5,3.5,3.5], smooth: true, symbol: "circle", symbolSize: 4, lineStyle: { color: "#62f6fb", width: 2 }, itemStyle: { color: "#62f6fb" }, areaStyle: { color: "rgba(98,246,251,0.12)" } }, { name: "渗流压力", type: "line", data: [28.5,26.8,25.2,24.8,25.0,25.6], smooth: true, symbol: "diamond", symbolSize: 4, lineStyle: { color: "#a78bfa", width: 2 }, itemStyle: { color: "#a78bfa" }, areaStyle: { color: "rgba(167,139,250,0.08)" } }] });
+      }
+      const pc = document.getElementById("statusPieChart");
+      if (pc) {
+        if (this.statusPieChart) this.statusPieChart.dispose();
+        this.statusPieChart = echarts.init(pc);
+        this.statusPieChart.setOption({ animation: false, tooltip: { trigger: "item", formatter: "{b}: {c}个 ({d}%)" }, series: [{ type: "pie", radius: ["45%","75%"], center: ["50%","50%"], avoidLabelOverlap: false, itemStyle: { borderColor: "rgba(0,30,60,0.6)", borderWidth: 2 }, label: { show: false }, labelLine: { show: false }, data: [{ value: 8, name: "正常", itemStyle: { color: "#22c55e" } }, { value: 2, name: "注意", itemStyle: { color: "#ffd93d" } }, { value: 0, name: "警戒", itemStyle: { color: "#f97316" } }, { value: 0, name: "危险", itemStyle: { color: "#ef4444" } }] }] });
+      }
+    },
+  },
+};
+</script>
+<style scoped>
+.safety-container { width: 100%; height: 100%; display: flex; flex-direction: column; position: relative; overflow: hidden; }
+.tab-bar { position: absolute; left: 20px; top: 80px; z-index: 10; display: flex; gap: 4px; }
+.tab-item { padding: 6px 24px; font-size: 14px; font-weight: bold; color: #7bbef6; background: rgba(0,20,40,0.6); border: 1px solid rgba(0,212,255,0.25); border-radius: 3px 3px 0 0; cursor: pointer; transition: all 0.2s; user-select: none; }
+.tab-item:hover { background: rgba(0,40,80,0.7); color: #62f6fb; }
+.tab-item.active { background: rgba(0,20,40,0.85); color: #e0fcff; border-color: rgba(0,212,255,0.5); border-bottom-color: transparent; text-shadow: 0 0 5px rgba(0,212,255,0.3); }
+.safety-scroll-area { position: absolute; left: 0; right: 0; top: 110px; bottom: 0; overflow-y: auto; overflow-x: hidden; z-index: 5; padding-bottom: 40px; }
+.safety-scroll-area::-webkit-scrollbar { width: 4px; }
+.safety-scroll-area::-webkit-scrollbar-track { background: rgba(0,20,40,0.5); }
+.safety-scroll-area::-webkit-scrollbar-thumb { background: rgba(0,212,255,0.3); border-radius: 2px; }
+.tab-content { width: 100%; display: flex; justify-content: space-between; padding: 0 20px; box-sizing: border-box; }
+.left-sidebar { width: 350px; flex-shrink: 0; }
+.right-sidebar { width: 350px; flex-shrink: 0; }
+.tab-placeholder { justify-content: center; align-items: center; min-height: 300px; }
+.placeholder-text { color: #7bbef6; font-size: 18px; opacity: 0.6; padding: 80px 0; }
+.mt-10 { margin-top: 10px; }
+.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); }
+.card-header { height: 42px; 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: 4px 16px 0; }
+.card-title { font-size: var(--fs-card-title); font-weight: bold; color: #e0fcff; margin: 0; text-shadow: 0 0 5px rgba(0,212,255,0.5); padding-left: 20px; }
+.header-actions { display: flex; align-items: flex-start; gap: 10px; }
+.update-time { color: #7bbef6; font-size: 11px; font-family: monospace; }
+.card-body { padding: 8px; min-height: auto; font-size: 13px; line-height: 1.5; margin-top: -6px; }
+.card-body.chart-body { padding: 6px 8px 8px; }
+.card-body.card-body-tight { padding: 6px 8px; }
+.monitor-chart-box { background: rgba(0,20,40,0.4); border-radius: 4px; border: 1px solid rgba(0,212,255,0.15); padding: 6px; }
+.monitor-chart-label { color: #62f6fb; font-size: var(--fs-label); font-weight: bold; margin-bottom: 2px; }
+.chart-legend { text-align: center; margin-top: 3px; color: #7bbef6; font-size: 10px; }
+.legend-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 3px; vertical-align: middle; }
+.dot-horizontal { background: #62f6fb; } .dot-vertical { background: #fbbf24; } .dot-seepage { background: #62f6fb; } .dot-pressure { background: #a78bfa; }
+.water-stats-row { display: flex; gap: 6px; }
+.water-stat-card { flex: 1; display: flex; flex-direction: row; align-items: center; justify-content: space-between; padding: 3px 10px; background-image: url("/src/assets/images/卡片背景2.png"); background-size: 100% 100%; background-position: center; background-repeat: no-repeat; height: 42px; }
+.water-stat-label { color: #62f6fb; font-size: var(--fs-label); margin-bottom: 0; text-align: left; line-height: 1.2; white-space: nowrap; }
+.water-stat-value { color: #ffffff; font-size: var(--fs-value-xl); font-weight: bold; text-shadow: 0 0 6px rgba(0,212,255,0.5); line-height: 1.2; }
+.safety-assessment-row { display: flex; gap: 8px; align-items: stretch; }
+.safety-pie-section { flex-shrink: 0; width: 45%; text-align: center; }
+.pie-legend { margin-top: 4px; display: flex; flex-wrap: wrap; gap: 3px; }
+.pie-legend-item { display: flex; align-items: center; gap: 3px; flex: 1 1 45%; min-width: 70px; }
+.pie-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
+.pie-name { color: #7bbef6; font-size: 10px; }
+.pie-count { color: #e0fcff; font-size: 11px; font-weight: bold; margin-left: auto; }
+.safety-assessment-section { flex: 1; display: flex; flex-direction: column; gap: 4px; }
+.safety-assessment-bar { background: rgba(0,20,40,0.5); border-radius: 4px; border: 1px solid rgba(0,212,255,0.15); padding: 8px 10px; display: flex; flex-direction: column; align-items: center; gap: 4px; }
+.safety-assessment-grade { font-size: 20px; font-weight: bold; padding: 2px 16px; border-radius: 4px; background: rgba(34,197,94,0.25); color: #22c55e; border: 1px solid rgba(34,197,94,0.5); text-align: center; }
+.safety-assessment-texts { display: flex; flex-direction: column; align-items: center; gap: 1px; }
+.safety-assessment-text { color: #7bbef6; font-size: 11px; }
+.safety-assessment-tags { display: flex; flex-wrap: wrap; gap: 3px; justify-content: center; }
+.assess-tag { font-size: 10px; font-weight: bold; padding: 2px 8px; border-radius: 2px; }
+.assess-tag.good { background: rgba(34,197,94,0.15); color: #22c55e; border: 1px solid rgba(34,197,94,0.3); }
+.monitor-table { width: 100%; font-size: 11px; }
+.monitor-table-header { display: flex; padding: 4px 6px; background: rgba(0,212,255,0.1); border-bottom: 1px solid rgba(0,212,255,0.2); color: #7bbef6; font-weight: bold; }
+.monitor-table-body { max-height: 260px; overflow-y: auto; }
+.monitor-table-body::-webkit-scrollbar { width: 3px; }
+.monitor-table-body::-webkit-scrollbar-track { background: rgba(0,20,40,0.5); }
+.monitor-table-body::-webkit-scrollbar-thumb { background: rgba(0,212,255,0.3); border-radius: 2px; }
+.monitor-row { display: flex; padding: 4px 6px; border-bottom: 1px solid rgba(0,212,255,0.08); align-items: flex-start; color: #e0fcff; }
+.monitor-row:last-child { border-bottom: none; }
+.monitor-row:hover { background: rgba(0,212,255,0.05); }
+.col-name { flex: 2.5; } .col-value { flex: 1.5; text-align: center; } .col-status { flex: 1.2; text-align: center; } .col-trend { flex: 0.8; text-align: center; }
+.status-tag { font-size: var(--fs-status); font-weight: bold; padding: 1px 6px; border-radius: 2px; display: inline-block; }
+.status-tag.normal { background: rgba(34,197,94,0.2); color: #22c55e; }
+.status-tag.warning { background: rgba(255,217,61,0.2); color: #ffd93d; }
+.status-tag.danger { background: rgba(239,68,68,0.2); color: #ff6b6b; }
+.trend-icon { font-size: 12px; font-weight: bold; }
+.trend-icon.up { color: #f97316; } .trend-icon.down { color: #22c55e; } .trend-icon.steady { color: #7bbef6; }
+canvas { display: block; margin: 0 auto; }
+</style>

+ 13 - 3
src/views/HomeView.vue

@@ -1,4 +1,4 @@
-<template>
+<template>
   <div class="dashboard">
     <div class="background-image"></div>
     <div class="bottom-bg" v-if="!showMap"></div>
@@ -35,6 +35,10 @@
       @updateForecastData="handleUpdateForecastData"
     />
     
+    <!-- 工程安全视图 -->
+    <EngineeringSafetyView 
+      v-if="activeTab === '工程安全'" 
+    />
     <!-- 水资源调配视图 -->
     <WaterResourceAllocationView 
       v-if="activeTab === '水资源调配'" 
@@ -48,6 +52,7 @@ import HydrologyForecastView from './HydrologyForecastView.vue'
 import WaterResourceAllocationView from './WaterResourceAllocationView.vue'
 import CesiumMap from '../components/CesiumMap.vue'
 import GradientOverlay from '../components/gradient-overlay.vue'
+import EngineeringSafetyView from './EngineeringSafetyView.vue'
 import TopNav from '../components/TopNav.vue'
 
 export default {
@@ -56,6 +61,7 @@ export default {
     OverviewView,
     HydrologyForecastView,
     WaterResourceAllocationView,
+    EngineeringSafetyView,
     CesiumMap,
     GradientOverlay,
     TopNav
@@ -68,7 +74,8 @@ export default {
       loadEmbankmentWarning: false,
       navButtonMap: {
         '流域总览': '综合首页',
-        '水文四预': '水情测报'
+        '水文四预': '水情测报',
+        '工程安全': '工程安全'
       },
       simulationTime: 0,
       simulationData: {
@@ -97,6 +104,7 @@ export default {
     handleNav(button) {
       if (button === '综合首页') this.selectTab('流域总览')
       else if (button === '水情测报') this.selectTab('水文四预')
+      else if (button === '工程安全') this.selectTab('工程安全')
     },
     selectSecondaryTab(tab) {
       this.activeSecondaryTab = tab
@@ -297,4 +305,6 @@ export default {
   color: transparent;
 }
 
-</style>
+
+</style>
+

+ 17 - 22
src/views/OverviewView.vue

@@ -904,7 +904,7 @@ export default {
 }
 
 .card-title {
-  font-size: 18px;
+  font-size: var(--fs-card-title);
   font-weight: bold;
   color: #e0fcff;
   margin: 0;
@@ -940,9 +940,7 @@ export default {
 }
 
 .card-body {
-  padding: 8px;
-  min-height: auto;
-  font-size: 16px;
+  font-size: var(--fs-body);
   line-height: 1.6;
   margin-top: -10px;
 }
@@ -1384,7 +1382,7 @@ export default {
 }
 
 .dam-feature-grid .feature-name {
-  font-size: 10px;
+    font-size: var(--fs-label);  font-weight: var(--fw-label);
 }
 
 .dam-feature-grid .feature-value {
@@ -1440,8 +1438,7 @@ export default {
 
 .modal-header h3 {
   margin: 0;
-  font-size: 20px;
-  font-weight: bold;
+  font-size: var(--fs-value-lg);  font-weight: var(--fw-value);
   color: #e0fcff;
   text-shadow: 0 0 5px rgba(0, 212, 255, 0.5);
 }
@@ -1534,7 +1531,7 @@ export default {
 
 .feature-name {
   color: #62f6fb;
-  font-size: 10px;
+    font-size: var(--fs-label);  font-weight: var(--fw-label);
   font-weight: bold;
   line-height: 1.3;
 }
@@ -1554,7 +1551,7 @@ export default {
 
 .feature-unit {
   color: #62f6fb;
-  font-size: 13px;
+    font-size: var(--fs-unit);  font-weight: var(--fw-normal);
 }
 
 /* 水文站实时水情样式 */
@@ -1593,8 +1590,7 @@ export default {
 }
 
 .stat-value {
-  font-size: 20px;
-  font-weight: bold;
+  font-size: var(--fs-value-lg);  font-weight: var(--fw-value);
   text-shadow: 0 0 5px rgba(0, 212, 255, 0.5);
 }
 
@@ -1790,7 +1786,7 @@ export default {
 
 .dispatch-card-label {
   color: #62f6fb;
-  font-size: 11px;
+    font-size: var(--fs-label);  font-weight: var(--fw-label);
   font-weight: normal;
   text-align: center;
   white-space: nowrap;
@@ -1808,7 +1804,7 @@ export default {
 
 .dispatch-card-unit {
   color: #62f6fb;
-  font-size: 11px;
+    font-size: var(--fs-unit);  font-weight: var(--fw-normal);
   font-weight: normal;
   margin-left: 2px;
 }
@@ -1911,7 +1907,7 @@ export default {
 
 .water-stat-label {
   color: #62f6fb;
-  font-size: 13px;
+    font-size: var(--fs-label);  font-weight: var(--fw-label);
   margin-bottom: 0;
   text-align: left;
   line-height: 1.2;
@@ -1920,7 +1916,7 @@ export default {
 
 .water-stat-value {
   color: #ffffff;
-  font-size: 22px;
+    font-size: var(--fs-value-xl);  font-weight: var(--fw-value);
   font-weight: bold;
   text-shadow: 0 0 6px rgba(0, 212, 255, 0.5);
   line-height: 1.2;
@@ -1975,7 +1971,7 @@ export default {
 
 .monitor-chart-label {
   color: #7bbef6;
-  font-size: 12px;
+    font-size: var(--fs-label);  font-weight: var(--fw-label);
   font-weight: bold;
   margin-bottom: 2px;
 }
@@ -2003,7 +1999,7 @@ export default {
 
 .real-time-label {
   color: #7bbef6;
-  font-size: 12px;
+    font-size: var(--fs-label);  font-weight: var(--fw-label);
   margin-bottom: 4px;
 }
 
@@ -2016,7 +2012,7 @@ export default {
 
 .real-time-value {
   color: #ffffff;
-  font-size: 22px;
+    font-size: var(--fs-value-xl);  font-weight: var(--fw-value);
   font-weight: bold;
   text-shadow: 0 0 5px rgba(0, 212, 255, 0.5);
 }
@@ -2098,20 +2094,19 @@ export default {
 
 .volume-card-label {
   color: #62f6fb;
-  font-size: 12px;
+    font-size: var(--fs-label);  font-weight: var(--fw-label);
   margin-bottom: 2px;
 }
 
 .volume-card-value {
   color: #ffffff;
-  font-size: 20px;
-  font-weight: bold;
+  font-size: var(--fs-value-lg);  font-weight: var(--fw-value);
   text-shadow: 0 0 5px rgba(0, 212, 255, 0.5);
 }
 
 .volume-card-unit {
   color: #62f6fb;
-  font-size: 12px;
+    font-size: var(--fs-unit);  font-weight: var(--fw-normal);
   margin-left: 2px;
 }