From 59af55dc3e72f8f2655ae06af9d1b6f766bac423 Mon Sep 17 00:00:00 2001
From: riku <risaku@163.com>
Date: 星期五, 20 三月 2026 16:02:19 +0800
Subject: [PATCH] 2026.3.20

---
 src/views/monitor/DataDashboard.vue |  751 +++++++++++++++++++++++++++++++++++++--------------------
 1 files changed, 490 insertions(+), 261 deletions(-)

diff --git a/src/views/monitor/DataDashboard.vue b/src/views/monitor/DataDashboard.vue
index 45fa087..705f2b5 100644
--- a/src/views/monitor/DataDashboard.vue
+++ b/src/views/monitor/DataDashboard.vue
@@ -4,7 +4,7 @@
     <div class="top-cards">
       <!-- 鏃堕棿鍛ㄦ湡閫夐」鍗$墖 -->
       <div class="time-period-card">
-        <div class="card-title">鏃堕棿閫夋嫨</div>
+        <!-- <div class="card-title">鏃堕棿閫夋嫨</div> -->
         <div class="time-controls">
           <div class="time-tab-container">
             <div
@@ -57,10 +57,97 @@
         </div>
       </div>
       <div class="cards-container">
-        <!-- 瓒呮爣鏁� -->
+        <!-- 璁惧鍦ㄧ嚎鐜� -->
+        <el-popover placement="right-start" title="璁惧鐩戞帶" width="400" trigger="click">
+          <div class="popover-content">
+            <div class="overview-items-container">
+              <div class="overview-item">
+                <div class="overview-label">椁愰ギ搴楅摵鎬绘暟</div>
+                <div class="overview-value">{{ overview.totalShops }}</div>
+              </div>
+
+              <div class="overview-item">
+                <div class="overview-label">鍦ㄧ嚎璁惧鏁�</div>
+                <div class="overview-value">{{ overview.onlineDevices }}</div>
+              </div>
+
+              <div class="overview-item">
+                <div class="overview-label">绂荤嚎璁惧鏁�</div>
+                <div class="overview-value">{{ overview.offlineDevices }}</div>
+              </div>
+            </div>
+
+            <!-- 璁惧鐘舵�侀ゼ鍥� -->
+            <div class="device-status-chart">
+              <canvas id="deviceStatusChart"></canvas>
+            </div>
+          </div>
+          <template #reference>
+            <div class="metric-card">
+              <div class="card-header">
+                <div class="card-title">璁惧鍦ㄧ嚎鐜�</div>
+                <div class="card-icon online-icon">
+                  <svg
+                    width="20"
+                    height="20"
+                    viewBox="0 0 24 24"
+                    fill="none"
+                    xmlns="http://www.w3.org/2000/svg"
+                  >
+                    <path
+                      d="M9 12L11 14L15 10"
+                      stroke="currentColor"
+                      stroke-width="2"
+                      stroke-linecap="round"
+                      stroke-linejoin="round"
+                    />
+                    <path
+                      d="M21 12C21 16.9706 16.9706 21 12 21C7.02944 21 3 16.9706 3 12C3 7.02944 7.02944 3 12 3C16.9706 3 21 7.02944 21 12Z"
+                      stroke="currentColor"
+                      stroke-width="2"
+                      stroke-linecap="round"
+                      stroke-linejoin="round"
+                    />
+                  </svg>
+                </div>
+              </div>
+              <div class="card-value">{{ metrics.onlineRate }}<el-text>%</el-text></div>
+              <div class="card-trend">
+                <span
+                  class="trend-arrow"
+                  :class="{ up: metrics.onlineRateTrend > 0, down: metrics.onlineRateTrend < 0 }"
+                >
+                  {{ metrics.onlineRateTrend > 0 ? '鈫�' : '鈫�' }}
+                </span>
+                <span class="trend-text">{{ Math.abs(metrics.onlineRateTrend) }}%</span>
+                <span class="trend-label">{{ getCompareLabel() }}</span>
+              </div>
+              <div class="view-details">
+                <span>璇︽儏</span>
+                <svg
+                  width="12"
+                  height="12"
+                  viewBox="0 0 24 24"
+                  fill="none"
+                  xmlns="http://www.w3.org/2000/svg"
+                >
+                  <path
+                    d="M9 18L15 12L9 6"
+                    stroke="currentColor"
+                    stroke-width="2"
+                    stroke-linecap="round"
+                    stroke-linejoin="round"
+                  />
+                </svg>
+              </div>
+            </div>
+          </template>
+        </el-popover>
+
+        <!-- 娴撳害棰勮 -->
         <div class="metric-card">
           <div class="card-header">
-            <div class="card-title">{{ getPeriodLabel() }}瓒呮爣鏁�</div>
+            <div class="card-title">{{ getPeriodLabel() }}娴撳害棰勮</div>
             <div class="card-icon warning-icon">
               <svg
                 width="20"
@@ -86,7 +173,7 @@
               </svg>
             </div>
           </div>
-          <div class="card-value">{{ metrics.overStandardCount }}</div>
+          <div class="card-value">{{ metrics.overStandardCount }}<el-text>娆�</el-text></div>
           <div class="card-trend">
             <span
               class="trend-arrow"
@@ -99,11 +186,160 @@
           </div>
         </div>
 
-        <!-- 鍦ㄧ嚎鐜� -->
+        <!-- 鐜板満宸℃煡 -->
+        <el-popover placement="right-start" title="鐜板満宸℃煡缁熻" width="350" trigger="click">
+          <div class="inspection-popover-content">
+            <!-- 宸℃煡閲忕粺璁� -->
+            <div class="inspection-metrics">
+              <div class="inspection-metric-item">
+                <div class="inspection-metric-label">搴楅摵鎬昏</div>
+                <div class="inspection-metric-value">{{ inspectionStats.totalShops }}</div>
+              </div>
+              <div class="inspection-metric-item">
+                <div class="inspection-metric-label">宸℃煡搴楅摵</div>
+                <div class="inspection-metric-value">{{ inspectionStats.inspectedShops }}</div>
+              </div>
+              <div class="inspection-metric-item">
+                <div class="inspection-metric-label">宸℃煡鐐规</div>
+                <div class="inspection-metric-value">{{ inspectionStats.inspectionPoints }}</div>
+              </div>
+              <div class="inspection-metric-item">
+                <div class="inspection-metric-label">澶嶆煡鐐规</div>
+                <div class="inspection-metric-value">{{ inspectionStats.reviewPoints }}</div>
+              </div>
+            </div>
+
+            <!-- 闂鏁存敼鎯呭喌 -->
+            <div class="inspection-chart-container">
+              <div class="section-header"><h3>闂鏁存敼</h3></div>
+              <canvas id="rectificationChart"></canvas>
+            </div>
+
+            <!-- 闂瀹℃牳鎯呭喌 -->
+            <div class="inspection-table-container" style="display: none">
+              <div class="section-header"><h3>瀹℃牳姹囨��</h3></div>
+              <div class="inspection-metric-label">闂瀹℃牳</div>
+              <div class="inspection-table">
+                <div class="inspection-metric-item">
+                  <div class="inspection-metric-label">鏃犻棶棰�</div>
+                  <div class="inspection-metric-value">{{ inspectionStats.noProblemShops }}</div>
+                </div>
+                <div class="inspection-metric-item">
+                  <div class="inspection-metric-label">鏈鏍�</div>
+                  <div class="inspection-metric-value">
+                    {{ inspectionStats.unreviewedProblemShops }}
+                  </div>
+                </div>
+                <div class="inspection-metric-item">
+                  <div class="inspection-metric-label">閮ㄥ垎瀹℃牳</div>
+                  <div class="inspection-metric-value">
+                    {{ inspectionStats.partiallyReviewedProblemShops }}
+                  </div>
+                </div>
+                <div class="inspection-metric-item">
+                  <div class="inspection-metric-label">鍏ㄩ儴瀹℃牳</div>
+                  <div class="inspection-metric-value">
+                    {{ inspectionStats.fullyReviewedProblemShops }}
+                  </div>
+                </div>
+              </div>
+              <div class="inspection-metric-label">鏁存敼瀹℃牳</div>
+              <div class="inspection-table">
+                <div class="inspection-metric-item">
+                  <div class="inspection-metric-label">鏈暣鏀�</div>
+                  <div class="inspection-metric-value">{{ inspectionStats.unrectifiedShops }}</div>
+                </div>
+                <div class="inspection-metric-item">
+                  <div class="inspection-metric-label">鏈鏍�</div>
+                  <div class="inspection-metric-value">
+                    {{ inspectionStats.unreviewedRectifiedShops }}
+                  </div>
+                </div>
+                <div class="inspection-metric-item">
+                  <div class="inspection-metric-label">閮ㄥ垎瀹℃牳</div>
+                  <div class="inspection-metric-value">
+                    {{ inspectionStats.partiallyReviewedRectifiedShops }}
+                  </div>
+                </div>
+                <div class="inspection-metric-item">
+                  <div class="inspection-metric-label">鍏ㄩ儴瀹℃牳</div>
+                  <div class="inspection-metric-value">
+                    {{ inspectionStats.fullyReviewedRectifiedShops }}
+                  </div>
+                </div>
+              </div>
+            </div>
+          </div>
+          <template #reference>
+            <div class="metric-card">
+              <div class="card-header">
+                <div class="card-title">鐜板満宸℃煡</div>
+                <div class="card-icon task-icon">
+                  <svg
+                    width="20"
+                    height="20"
+                    viewBox="0 0 24 24"
+                    fill="none"
+                    xmlns="http://www.w3.org/2000/svg"
+                  >
+                    <path
+                      d="M22 11.08V12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C15.7376 2 19.0503 4.16113 20.7748 7.33007"
+                      stroke="currentColor"
+                      stroke-width="2"
+                      stroke-linecap="round"
+                      stroke-linejoin="round"
+                    />
+                    <path
+                      d="M22 4L12 14.01L9 11.01"
+                      stroke="currentColor"
+                      stroke-width="2"
+                      stroke-linecap="round"
+                      stroke-linejoin="round"
+                    />
+                  </svg>
+                </div>
+              </div>
+              <div class="card-value">{{ metrics.inspectionPoints }}<el-text>鐐规</el-text></div>
+              <div class="card-trend">
+                <span
+                  class="trend-arrow"
+                  :class="{
+                    up: metrics.inspectionPointsTrend > 0,
+                    down: metrics.inspectionPointsTrend < 0,
+                  }"
+                >
+                  {{ metrics.inspectionPointsTrend > 0 ? '鈫�' : '鈫�' }}
+                </span>
+                <span class="trend-text">{{ Math.abs(metrics.inspectionPointsTrend) }}</span>
+                <span class="trend-label">{{ getCompareLabel() }}</span>
+              </div>
+              <div class="view-details">
+                <span>璇︽儏</span>
+                <svg
+                  width="12"
+                  height="12"
+                  viewBox="0 0 24 24"
+                  fill="none"
+                  xmlns="http://www.w3.org/2000/svg"
+                >
+                  <path
+                    d="M9 18L15 12L9 6"
+                    stroke="currentColor"
+                    stroke-width="2"
+                    stroke-linecap="round"
+                    stroke-linejoin="round"
+                  />
+                </svg>
+              </div>
+            </div>
+          </template>
+        </el-popover>
+
+        <!-- 淇¤鎶曡瘔 -->
         <div class="metric-card">
           <div class="card-header">
-            <div class="card-title">鍦ㄧ嚎鐜�</div>
-            <div class="card-icon online-icon">
+            <div class="card-title">淇¤鎶曡瘔</div>
+            <div class="card-icon warning-icon">
               <svg
                 width="20"
                 height="20"
@@ -112,14 +348,28 @@
                 xmlns="http://www.w3.org/2000/svg"
               >
                 <path
-                  d="M9 12L11 14L15 10"
+                  d="M21 6H3C2.46957 6 1.96086 6.21071 1.58579 6.58579C1.21071 6.96086 1 7.46957 1 8V18C1 19.1046 1.89543 20 3 20H21C22.1046 20 23 19.1046 23 18V8C23 7.46957 22.7893 6.96086 22.4142 6.58579C22.0391 6.21071 21.5304 6 21 6Z"
                   stroke="currentColor"
                   stroke-width="2"
                   stroke-linecap="round"
                   stroke-linejoin="round"
                 />
                 <path
-                  d="M21 12C21 16.9706 16.9706 21 12 21C7.02944 21 3 16.9706 3 12C3 7.02944 7.02944 3 12 3C16.9706 3 21 7.02944 21 12Z"
+                  d="M8 12H16"
+                  stroke="currentColor"
+                  stroke-width="2"
+                  stroke-linecap="round"
+                  stroke-linejoin="round"
+                />
+                <path
+                  d="M8 16H16"
+                  stroke="currentColor"
+                  stroke-width="2"
+                  stroke-linecap="round"
+                  stroke-linejoin="round"
+                />
+                <path
+                  d="M8 8H16"
                   stroke="currentColor"
                   stroke-width="2"
                   stroke-linecap="round"
@@ -128,23 +378,23 @@
               </svg>
             </div>
           </div>
-          <div class="card-value">{{ metrics.onlineRate }}%</div>
+          <div class="card-value">{{ metrics.overStandardCount }}<el-text>浠�</el-text></div>
           <div class="card-trend">
             <span
               class="trend-arrow"
-              :class="{ up: metrics.onlineRateTrend > 0, down: metrics.onlineRateTrend < 0 }"
+              :class="{ up: metrics.overStandardTrend > 0, down: metrics.overStandardTrend < 0 }"
             >
-              {{ metrics.onlineRateTrend > 0 ? '鈫�' : '鈫�' }}
+              {{ metrics.overStandardTrend > 0 ? '鈫�' : '鈫�' }}
             </span>
-            <span class="trend-text">{{ Math.abs(metrics.onlineRateTrend) }}%</span>
+            <span class="trend-text">{{ Math.abs(metrics.overStandardTrend) }}%</span>
             <span class="trend-label">{{ getCompareLabel() }}</span>
           </div>
         </div>
 
-        <!-- 鍑�鍖栧櫒杩愯鏁堢巼 -->
+        <!-- 鐜俊鐮� -->
         <div class="metric-card">
           <div class="card-header">
-            <div class="card-title">鍑�鍖栧櫒杩愯鏁堢巼</div>
+            <div class="card-title">鐜俊鐮�</div>
             <div class="card-icon efficiency-icon">
               <svg
                 width="20"
@@ -154,14 +404,21 @@
                 xmlns="http://www.w3.org/2000/svg"
               >
                 <path
-                  d="M12 2C6.48 2 2 6.48 2 12C2 17.52 6.48 22 12 22C17.52 22 22 17.52 22 12C22 6.48 17.52 2 12 2Z"
+                  d="M12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22Z"
                   stroke="currentColor"
                   stroke-width="2"
                   stroke-linecap="round"
                   stroke-linejoin="round"
                 />
                 <path
-                  d="M12 6V12L16 14"
+                  d="M12 8V16"
+                  stroke="currentColor"
+                  stroke-width="2"
+                  stroke-linecap="round"
+                  stroke-linejoin="round"
+                />
+                <path
+                  d="M8 12H16"
                   stroke="currentColor"
                   stroke-width="2"
                   stroke-linecap="round"
@@ -170,7 +427,14 @@
               </svg>
             </div>
           </div>
-          <div class="card-value">{{ metrics.purifierEfficiency }}%</div>
+          <div class="card-value" style="color: #52c41a">
+            <div>{{ metrics.purifierEfficiency }}<el-text>%</el-text></div>
+            <div class="card-subvalues">
+              <span style="color: #faad14; font-size: 14px">榛勭爜锛�3%</span>
+              <span style="color: #f5222d; font-size: 14px; margin-left: 12px">绾㈢爜锛�2%</span>
+            </div>
+          </div>
+
           <div class="card-trend">
             <span
               class="trend-arrow"
@@ -186,11 +450,11 @@
           </div>
         </div>
 
-        <!-- 宸℃煡鐐规 -->
+        <!-- 琛屾斂澶勭綒 -->
         <div class="metric-card">
           <div class="card-header">
-            <div class="card-title">宸℃煡鐐规</div>
-            <div class="card-icon task-icon">
+            <div class="card-title">琛屾斂澶勭綒</div>
+            <div class="card-icon warning-icon">
               <svg
                 width="20"
                 height="20"
@@ -199,14 +463,28 @@
                 xmlns="http://www.w3.org/2000/svg"
               >
                 <path
-                  d="M22 11.08V12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C15.7376 2 19.0503 4.16113 20.7748 7.33007"
+                  d="M12 15C15.866 15 19 11.866 19 8C19 4.13401 15.866 1 12 1C8.13401 1 5 4.13401 5 8C5 11.866 8.13401 15 12 15Z"
                   stroke="currentColor"
                   stroke-width="2"
                   stroke-linecap="round"
                   stroke-linejoin="round"
                 />
                 <path
-                  d="M22 4L12 14.01L9 11.01"
+                  d="M12 15C12 15 15 21 15 21H9C9 21 12 15 12 15Z"
+                  stroke="currentColor"
+                  stroke-width="2"
+                  stroke-linecap="round"
+                  stroke-linejoin="round"
+                />
+                <path
+                  d="M11 8H13"
+                  stroke="currentColor"
+                  stroke-width="2"
+                  stroke-linecap="round"
+                  stroke-linejoin="round"
+                />
+                <path
+                  d="M11 11H13"
                   stroke="currentColor"
                   stroke-width="2"
                   stroke-linecap="round"
@@ -215,18 +493,15 @@
               </svg>
             </div>
           </div>
-          <div class="card-value">{{ metrics.inspectionPoints }}</div>
+          <div class="card-value">{{ metrics.overStandardCount }}<el-text>娆�</el-text></div>
           <div class="card-trend">
             <span
               class="trend-arrow"
-              :class="{
-                up: metrics.inspectionPointsTrend > 0,
-                down: metrics.inspectionPointsTrend < 0,
-              }"
+              :class="{ up: metrics.overStandardTrend > 0, down: metrics.overStandardTrend < 0 }"
             >
-              {{ metrics.inspectionPointsTrend > 0 ? '鈫�' : '鈫�' }}
+              {{ metrics.overStandardTrend > 0 ? '鈫�' : '鈫�' }}
             </span>
-            <span class="trend-text">{{ Math.abs(metrics.inspectionPointsTrend) }}</span>
+            <span class="trend-text">{{ Math.abs(metrics.overStandardTrend) }}%</span>
             <span class="trend-label">{{ getCompareLabel() }}</span>
           </div>
         </div>
@@ -238,75 +513,30 @@
       <!-- 涓儴GIS鍦板浘鍖� -->
       <div class="map-section">
         <div id="map" class="map-container">
-          <BaseMap :showSatellite="true"></BaseMap>
+          <BaseMap :showSatellite="false"></BaseMap>
         </div>
-
-        <!-- 鍦板浘鐐逛綅寮圭獥 -->
-        <el-dialog v-model="dialogVisible" title="浼佷笟瀹炴椂鏁版嵁" width="400px">
-          <div class="dialog-content">
-            <el-descriptions :column="1" border>
-              <el-descriptions-item label="浼佷笟鍚嶇О">{{
-                selectedPoint.enterpriseName
-              }}</el-descriptions-item>
-              <el-descriptions-item label="璁惧缂栧彿">{{
-                selectedPoint.deviceId
-              }}</el-descriptions-item>
-              <el-descriptions-item label="娌圭儫娴撳害"
-                >{{ selectedPoint.oilSmokeConcentration }} mg/m鲁</el-descriptions-item
-              >
-              <el-descriptions-item label="棰楃矑鐗�"
-                >{{ selectedPoint.particulateMatter }} mg/m鲁</el-descriptions-item
-              >
-              <el-descriptions-item label="闈炵敳鐑锋�荤儍"
-                >{{ selectedPoint.nonMethaneHydrocarbon }} mg/m鲁</el-descriptions-item
-              >
-              <el-descriptions-item label="鐩戞祴鏃堕棿">{{
-                selectedPoint.monitoringTime
-              }}</el-descriptions-item>
-              <el-descriptions-item label="瓒呮爣鎯呭喌">
-                <el-tag :type="selectedPoint.isOverStandard ? 'danger' : 'success'">
-                  {{ selectedPoint.isOverStandard ? '瓒呮爣' : '姝e父' }}
-                </el-tag>
-              </el-descriptions-item>
-            </el-descriptions>
-          </div>
-          <template #footer>
-            <span class="dialog-footer">
-              <el-button @click="dialogVisible = false">鍏抽棴</el-button>
-              <el-button type="primary" @click="viewDetails">鏌ョ湅璇︽儏</el-button>
-            </span>
-          </template>
-        </el-dialog>
       </div>
     </div>
-    <!-- 鍙充晶瀹炴椂鐩戞祴鎬昏鍖� -->
-    <div class="overview-section">
-      <div class="section-header">
-        <h3>璁惧鐩戞帶</h3>
-        <!-- <span class="view-more">鏌ョ湅鏇村</span> -->
-      </div>
 
-      <div class="overview-items-container">
-        <div class="overview-item">
-          <div class="overview-label">椁愰ギ搴楅摵鎬绘暟</div>
-          <div class="overview-value">{{ overview.totalShops }}</div>
+    <!--  -->
+    <div class="monitor-control-container">
+      <el-button size="large" @click="toggleMonitorControl" class="push-btn">
+        <div style="display: flex; flex-direction: column">
+          <el-icon>
+            <ArrowRight v-if="isMonitorControlExpanded" />
+            <ArrowLeft v-else />
+          </el-icon>
+          <!-- <div>鐜�</div>
+          <div>鍦�</div>
+          <div>宸�</div>
+          <div>鏌�</div> -->
         </div>
-
-        <div class="overview-item">
-          <div class="overview-label">鍦ㄧ嚎璁惧鏁�</div>
-          <div class="overview-value">{{ overview.onlineDevices }}</div>
-        </div>
-
-        <div class="overview-item">
-          <div class="overview-label">绂荤嚎璁惧鏁�</div>
-          <div class="overview-value">{{ overview.offlineDevices }}</div>
-        </div>
-      </div>
-
-      <!-- 璁惧鐘舵�侀ゼ鍥� -->
-      <div class="device-status-chart">
-        <canvas id="deviceStatusChart"></canvas>
-      </div>
+      </el-button>
+      <MonitorControl
+        v-if="isMonitorControlExpanded"
+        :class="{ 'monitor-control': true, collapsed: !isMonitorControlExpanded }"
+        style="height: calc(90vh - 40px)"
+      />
     </div>
 
     <!-- 鍦板浘鍥句緥 -->
@@ -345,129 +575,6 @@
         </div>
       </div>
     </div>
-    <!-- 宸℃煡鎯呭喌缁熻鍗$墖 -->
-    <el-scrollbar class="inspection-section">
-      <div class="section-header">
-        <h3>宸℃煡姹囨��</h3>
-      </div>
-
-      <!-- 宸℃煡閲忕粺璁� -->
-      <div class="inspection-metrics">
-        <div class="inspection-metric-item">
-          <div class="inspection-metric-label">搴楅摵鎬昏</div>
-          <div class="inspection-metric-value">{{ inspectionStats.totalShops }}</div>
-        </div>
-        <div class="inspection-metric-item">
-          <div class="inspection-metric-label">宸℃煡搴楅摵</div>
-          <div class="inspection-metric-value">{{ inspectionStats.inspectedShops }}</div>
-        </div>
-        <div class="inspection-metric-item">
-          <div class="inspection-metric-label">宸℃煡鐐规</div>
-          <div class="inspection-metric-value">{{ inspectionStats.inspectionPoints }}</div>
-        </div>
-        <div class="inspection-metric-item">
-          <div class="inspection-metric-label">澶嶆煡鐐规</div>
-          <div class="inspection-metric-value">{{ inspectionStats.reviewPoints }}</div>
-        </div>
-      </div>
-
-      <!-- 闂鏁存敼鎯呭喌 -->
-      <div class="inspection-chart-container">
-        <div class="section-header"><h3>鏁存敼姹囨��</h3></div>
-        <canvas id="rectificationChart"></canvas>
-      </div>
-
-      <!-- 闂瀹℃牳鎯呭喌 -->
-      <div class="inspection-table-container">
-        <div class="section-header"><h3>瀹℃牳姹囨��</h3></div>
-        <div class="inspection-metric-label">闂瀹℃牳</div>
-        <div class="inspection-table">
-          <div class="inspection-metric-item">
-            <div class="inspection-metric-label">鏃犻棶棰�</div>
-            <div class="inspection-metric-value">{{ inspectionStats.noProblemShops }}</div>
-          </div>
-          <div class="inspection-metric-item">
-            <div class="inspection-metric-label">鏈鏍�</div>
-            <div class="inspection-metric-value">
-              {{ inspectionStats.unreviewedProblemShops }}
-            </div>
-          </div>
-          <div class="inspection-metric-item">
-            <div class="inspection-metric-label">閮ㄥ垎瀹℃牳</div>
-            <div class="inspection-metric-value">
-              {{ inspectionStats.partiallyReviewedProblemShops }}
-            </div>
-          </div>
-          <div class="inspection-metric-item">
-            <div class="inspection-metric-label">鍏ㄩ儴瀹℃牳</div>
-            <div class="inspection-metric-value">
-              {{ inspectionStats.fullyReviewedProblemShops }}
-            </div>
-          </div>
-        </div>
-        <div class="inspection-metric-label">鏁存敼瀹℃牳</div>
-        <div class="inspection-table">
-          <div class="inspection-metric-item">
-            <div class="inspection-metric-label">鏈暣鏀�</div>
-            <div class="inspection-metric-value">{{ inspectionStats.unrectifiedShops }}</div>
-          </div>
-          <div class="inspection-metric-item">
-            <div class="inspection-metric-label">鏈鏍�</div>
-            <div class="inspection-metric-value">
-              {{ inspectionStats.unreviewedRectifiedShops }}
-            </div>
-          </div>
-          <div class="inspection-metric-item">
-            <div class="inspection-metric-label">閮ㄥ垎瀹℃牳</div>
-            <div class="inspection-metric-value">
-              {{ inspectionStats.partiallyReviewedRectifiedShops }}
-            </div>
-          </div>
-          <div class="inspection-metric-item">
-            <div class="inspection-metric-label">鍏ㄩ儴瀹℃牳</div>
-            <div class="inspection-metric-value">
-              {{ inspectionStats.fullyReviewedRectifiedShops }}
-            </div>
-          </div>
-          <!-- <div class="table-row">
-            <div class="table-cell">鏃犻棶棰樺簵閾烘暟閲�</div>
-            <div class="table-cell value">{{ inspectionStats.noProblemShops }}</div>
-          </div>
-          <div class="table-row">
-            <div class="table-cell">闂鏈鏍稿簵閾烘暟閲�</div>
-            <div class="table-cell value">{{ inspectionStats.unreviewedProblemShops }}</div>
-          </div>
-          <div class="table-row">
-            <div class="table-cell">闂閮ㄥ垎瀹℃牳搴楅摵鏁伴噺</div>
-            <div class="table-cell value">
-              {{ inspectionStats.partiallyReviewedProblemShops }}
-            </div>
-          </div>
-          <div class="table-row">
-            <div class="table-cell">闂鍏ㄩ儴瀹℃牳搴楅摵鏁伴噺</div>
-            <div class="table-cell value">{{ inspectionStats.fullyReviewedProblemShops }}</div>
-          </div>
-          <div class="table-row">
-            <div class="table-cell">鏈暣鏀瑰簵閾烘暟</div>
-            <div class="table-cell value">{{ inspectionStats.unrectifiedShops }}</div>
-          </div>
-          <div class="table-row">
-            <div class="table-cell">鏁存敼鏈鏍稿簵閾烘暟</div>
-            <div class="table-cell value">{{ inspectionStats.unreviewedRectifiedShops }}</div>
-          </div>
-          <div class="table-row">
-            <div class="table-cell">鏁存敼閮ㄥ垎瀹℃牳搴楅摵鏁�</div>
-            <div class="table-cell value">
-              {{ inspectionStats.partiallyReviewedRectifiedShops }}
-            </div>
-          </div>
-          <div class="table-row">
-            <div class="table-cell">鏁存敼鍏ㄩ儴瀹℃牳搴楅摵鏁�</div>
-            <div class="table-cell value">{{ inspectionStats.fullyReviewedRectifiedShops }}</div>
-          </div> -->
-        </div>
-      </div>
-    </el-scrollbar>
   </div>
 </template>
 
@@ -477,19 +584,22 @@
 import districtSearch from '@/utils/map/districtsearch.js'
 import marks from '@/utils/map/marks.js'
 import { generateTestShops } from '@/debug/debugdata'
+import MonitorControl from '@/views/inspection/MonitorControl.vue'
 
 export default {
   name: 'DataDashboard',
+  components: {
+    MonitorControl,
+  },
   data() {
     return {
       activeTime: 'day',
-      currentDate: new Date(),
+      currentDate: new Date('2023-08-01'),
       timeTabs: [
         { label: '鏃�', value: 'day' },
         { label: '鍛�', value: 'week' },
         { label: '鏈�', value: 'month' },
       ],
-      dialogVisible: false,
       selectedPoint: {
         enterpriseName: '',
         deviceId: '',
@@ -504,8 +614,8 @@
         overStandardTrend: 5,
         onlineRate: 92,
         onlineRateTrend: 2,
-        purifierEfficiency: 85,
-        purifierEfficiencyTrend: -3,
+        purifierEfficiency: 95,
+        purifierEfficiencyTrend: 2,
         inspectionPoints: 350,
         inspectionPointsTrend: 50,
       },
@@ -536,19 +646,20 @@
       },
       map: null,
       refreshTimer: null,
+      isMonitorControlExpanded: true,
     }
   },
   computed: {
     currentTimeDisplay() {
       const date = this.currentDate
+      let weekStart = new Date(date)
+      let weekEnd = new Date(date)
       switch (this.activeTime) {
         case 'day':
           return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`
         case 'week':
           // 绠�鍗曡绠楀懆鏄剧ず锛屽疄闄呴」鐩腑鍙兘闇�瑕佹洿澶嶆潅鐨勫懆璁$畻閫昏緫
-          let weekStart = new Date(date)
           weekStart.setDate(date.getDate() - date.getDay() + 1)
-          let weekEnd = new Date(date)
           weekEnd.setDate(date.getDate() + (7 - date.getDay()))
           return `${weekStart.getFullYear()}-${String(weekStart.getMonth() + 1).padStart(2, '0')}-${String(weekStart.getDate()).padStart(2, '0')} ~ ${weekEnd.getFullYear()}-${String(weekEnd.getMonth() + 1).padStart(2, '0')}-${String(weekEnd.getDate()).padStart(2, '0')}`
         case 'month':
@@ -562,7 +673,7 @@
     this.initMap()
     this.initDeviceStatusChart()
     this.initRectificationChart()
-    this.startAutoRefresh()
+    // this.startAutoRefresh()
   },
   beforeUnmount() {
     if (this.refreshTimer) {
@@ -570,6 +681,9 @@
     }
   },
   methods: {
+    toggleMonitorControl() {
+      this.isMonitorControlExpanded = !this.isMonitorControlExpanded
+    },
     handleTimeChange(tab) {
       this.activeTime = tab.value
       // 妯℃嫙鍒囨崲鏃堕棿鍛ㄦ湡鍚庣殑鏁版嵁鏇存柊
@@ -631,12 +745,18 @@
       // 杩欓噷搴旇鏍规嵁閫夋嫨鐨勬椂闂村懆鏈熶粠鎺ュ彛鑾峰彇鏁版嵁
       // 妯℃嫙鏁版嵁鏇存柊
       setTimeout(() => {
+        const m = Math.floor(Math.random() * 50) + 150
+        this.overview = {
+          totalShops: 245,
+          onlineDevices: m,
+          offlineDevices: 245 - m,
+        }
         this.metrics = {
           overStandardCount: Math.floor(Math.random() * 30),
           overStandardTrend: Math.floor(Math.random() * 20) - 10,
-          onlineRate: Math.floor(Math.random() * 20) + 80,
+          onlineRate: ((this.overview.onlineDevices / this.overview.totalShops) * 100).toFixed(0),
           onlineRateTrend: Math.floor(Math.random() * 10) - 5,
-          purifierEfficiency: Math.floor(Math.random() * 30) + 70,
+          purifierEfficiency: Math.floor(Math.random() * 20) + 80,
           purifierEfficiencyTrend: Math.floor(Math.random() * 10) - 5,
           inspectionPoints: Math.floor(Math.random() * 100) + 300,
           inspectionPointsTrend: Math.floor(Math.random() * 100) - 50,
@@ -662,6 +782,7 @@
         }
 
         // 鏇存柊鍥捐〃
+        this.initDeviceStatusChart()
         this.initRectificationChart()
       }, 300)
     },
@@ -779,6 +900,7 @@
             left: '3%',
             right: '4%',
             bottom: '3%',
+            top: '5%',
             containLabel: true,
           },
           xAxis: {
@@ -878,6 +1000,34 @@
   /* padding: 16px; */
   border-radius: 8px;
   /* box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); */
+}
+
+/* 鐩戞帶鎺у埗鍗$墖 */
+.monitor-control {
+  /* position: absolute; */
+  width: 400px;
+  transition: all 0.3s ease;
+  /* top: 0px; */
+  /* right: 0px; */
+  /* z-index: 10; */
+}
+
+.push-btn {
+  z-index: 1;
+  width: 2.5rem;
+  height: 40px;
+  margin: initial;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  /* background-color: white; */
+  /* border-color: white; */
+  /* border-top: 1px solid;
+  border-left: 1px solid;
+  border-bottom: 1px solid; */
+  border-top-right-radius: 0px;
+  border-bottom-right-radius: 0px;
+  /* box-shadow: var(--el-box-shadow-light); */
 }
 
 /* 鏃堕棿鍛ㄦ湡鍗$墖 */
@@ -993,6 +1143,7 @@
 .metric-card:hover {
   transform: translateY(-2px);
   box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
+  cursor: pointer;
 }
 
 .card-header {
@@ -1024,7 +1175,7 @@
 }
 
 .efficiency-icon {
-  color: #722ed1;
+  color: #52c41a;
 }
 
 .task-icon {
@@ -1037,6 +1188,16 @@
   margin: 12px 0;
   color: #262626;
   line-height: 1.2;
+  /* display: flex;
+  justify-content: space-between;
+  align-items: flex-end; */
+}
+
+.card-subvalues {
+  display: flex;
+  align-items: center;
+  margin: 8px 0;
+  font-weight: 500;
 }
 
 .card-trend {
@@ -1133,19 +1294,63 @@
 }
 
 /* 鍙充晶瀹炴椂鐩戞祴鎬昏鍖� */
-.overview-section {
-  position: absolute;
-  bottom: 4px;
-  left: 4px;
-  width: 320px;
-  background-color: rgba(255, 255, 255, 0.9);
-  border-radius: 8px;
-  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
-  padding: 20px;
+.popover-content {
+  padding: 10px;
+}
+
+.overview-items-container {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding-bottom: 16px;
+  border-bottom: 1px solid #f0f0f0;
+  margin-bottom: 20px;
+}
+
+.overview-item {
   display: flex;
   flex-direction: column;
-  z-index: 10;
-  max-height: calc(100vh - 220px);
+  align-items: center;
+  flex: 1;
+  text-align: center;
+}
+
+.overview-label {
+  font-size: 12px;
+  color: #86909c;
+  font-weight: 500;
+  margin-bottom: 8px;
+}
+
+.overview-value {
+  font-size: 24px;
+  font-weight: bold;
+  color: #262626;
+}
+
+.device-status-chart {
+  flex: 1;
+  min-height: 200px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  margin-bottom: 16px;
+}
+
+.view-details {
+  position: absolute;
+  bottom: 12px;
+  right: 16px;
+  display: flex;
+  align-items: center;
+  gap: 4px;
+  font-size: 12px;
+  color: #1890ff;
+  cursor: pointer;
+}
+
+.view-details:hover {
+  text-decoration: underline;
 }
 
 .overview-items-container {
@@ -1177,30 +1382,51 @@
   color: #262626;
 }
 
-.device-status-chart {
-  flex: 1;
-  min-height: 100px;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  margin-bottom: 16px;
+/* 宸℃煡鎯呭喌缁熻 */
+.inspection-popover-content {
+  padding: 10px;
+  max-height: 400px;
+  overflow-y: auto;
 }
 
-/* 宸℃煡鎯呭喌缁熻 */
-.inspection-section {
+.monitor-control-container {
   position: absolute;
   top: 4px;
   right: 4px;
-  width: 320px;
-  background-color: rgba(255, 255, 255, 0.9);
-  border-radius: 8px;
-  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
-  padding: 20px;
-  display: flex;
-  flex-direction: column;
   z-index: 10;
-  max-height: calc(70vh);
-  border-top: 1px solid #f0f0f0;
+  transition: all 0.3s ease;
+  /* background-color: rgba(255, 255, 255, 0.9); */
+  display: flex;
+  border-radius: 8px;
+  /* box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); */
+  overflow: hidden;
+}
+
+.monitor-control-container.collapsed {
+  width: 60px;
+}
+
+.monitor-control-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 10px 15px;
+  border-bottom: 1px solid #e8e8e8;
+  height: 40px;
+  position: relative;
+}
+
+.monitor-control-header span {
+  font-weight: 600;
+  color: #333;
+  writing-mode: vertical-rl;
+  text-orientation: mixed;
+  letter-spacing: 2px;
+  white-space: nowrap;
+}
+
+.collapse-btn {
+  /* transform: translateY(-50%); */
 }
 
 .inspection-metrics {
@@ -1303,18 +1529,21 @@
 /* 鍦板浘鍥句緥鏍峰紡 */
 .map-legend {
   position: absolute;
+  display: flex;
+  align-items: center;
   bottom: 4px;
-  right: 4px;
-  width: 200px;
+  left: 50%;
+  transform: translateX(-50%);
+  /* width: 200px; */
   background-color: rgba(255, 255, 255, 0.9);
   border-radius: 8px;
   box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
-  padding: 16px;
+  padding: 4px;
   z-index: 10;
 }
 
 .legend-header {
-  margin-bottom: 12px;
+  margin-right: 12px;
 }
 
 .legend-header h4 {
@@ -1327,7 +1556,7 @@
 
 .legend-items {
   display: flex;
-  flex-direction: column;
+  flex-direction: row;
   gap: 8px;
 }
 

--
Gitblit v1.9.3