Browse Source

增加监控汇总页面卡片翻牌效果

yawuga 9 months ago
parent
commit
7b710cf6d9
1 changed files with 175 additions and 22 deletions
  1. 175 22
      src/views/base/device/device-monitor.vue

+ 175 - 22
src/views/base/device/device-monitor.vue

@@ -230,18 +230,32 @@
               </div>
             </div>
             <div class="device-location">{{ device.location }}</div>
-            <div class="device-metrics">
-              <div class="metric">
-                <div class="metric-label">{{ device.metrics[0].name }}</div>
-                <div class="metric-value" :class="{ 'metric-warning': device.status === 'warning' && device.metrics[0].isAlert }">
-                  {{ device.metrics[0].value }}{{ device.metrics[0].unit }}
-                </div>
-              </div>
-              <div class="metric">
-                <div class="metric-label">{{ device.metrics[1].name }}</div>
-                <div class="metric-value" :class="{ 'metric-warning': device.status === 'warning' && device.metrics[1].isAlert }">
-                  {{ device.metrics[1].value }}{{ device.metrics[1].unit }}
-                </div>
+            <div class="device-metrics" 
+                 @mouseenter="pauseCarousel(device.id)"
+                 @mouseleave="resumeCarousel(device.id)">
+              <div class="metrics-container">
+                <transition name="flip" mode="out-in">
+                  <div class="metric-pair" :key="getCurrentMetricIndex(device.id)">
+                    <div class="metric">
+                      <div class="metric-label">{{ getCurrentMetrics(device)[0].name }}</div>
+                      <div class="metric-value" :class="{ 
+                        'metric-warning': device.status === 'warning' && getCurrentMetrics(device)[0].isAlert,
+                        'metric-alert': getCurrentMetrics(device)[0].isAlert
+                      }">
+                        {{ getCurrentMetrics(device)[0].value }}{{ getCurrentMetrics(device)[0].unit }}
+                      </div>
+                    </div>
+                    <div class="metric" v-if="getCurrentMetrics(device)[1]">
+                      <div class="metric-label">{{ getCurrentMetrics(device)[1].name }}</div>
+                      <div class="metric-value" :class="{ 
+                        'metric-warning': device.status === 'warning' && getCurrentMetrics(device)[1].isAlert,
+                        'metric-alert': getCurrentMetrics(device)[1].isAlert
+                      }">
+                        {{ getCurrentMetrics(device)[1].value }}{{ getCurrentMetrics(device)[1].unit }}
+                      </div>
+                    </div>
+                  </div>
+                </transition>
               </div>
             </div>
             <div class="device-footer">
@@ -574,6 +588,10 @@ export default {
         { id: 12, name: '北区3号摄像头', location: '北区3号地块', status: 'online' }
       ],
       
+      // 轮播控制状态
+      carouselStates: {},
+      carouselTimers: {},
+      
       deviceList: [
         {
           id: 1,
@@ -585,7 +603,9 @@ export default {
           type: 'soil',
           metrics: [
             { name: '土壤湿度', value: '32.5', unit: '%', isAlert: false },
-            { name: '土壤温度', value: '24.2', unit: '℃', isAlert: false }
+            { name: '土壤温度', value: '24.2', unit: '℃', isAlert: false },
+            { name: 'EC值', value: '1.8', unit: 'mS/cm', isAlert: false },
+            { name: 'N含量', value: '45', unit: 'mg/kg', isAlert: false }
           ]
         },
         {
@@ -598,7 +618,10 @@ export default {
           type: 'water',
           metrics: [
             { name: 'pH值', value: '8.5', unit: '', isAlert: true },
-            { name: '溶解氧', value: '6.2', unit: 'mg/L', isAlert: false }
+            { name: '溶解氧', value: '6.2', unit: 'mg/L', isAlert: false },
+            { name: '电导率', value: '1.2', unit: 'mS/cm', isAlert: false },
+            { name: '浊度', value: '15', unit: 'NTU', isAlert: false },
+            { name: '氨氮', value: '0.8', unit: 'mg/L', isAlert: false }
           ]
         },
         {
@@ -611,7 +634,11 @@ export default {
           type: 'weather',
           metrics: [
             { name: '温度', value: '26.5', unit: '℃', isAlert: false },
-            { name: '湿度', value: '68', unit: '%', isAlert: false }
+            { name: '湿度', value: '68', unit: '%', isAlert: false },
+            { name: '光照强度', value: '45000', unit: 'lux', isAlert: false },
+            { name: '风速', value: '2.3', unit: 'm/s', isAlert: false },
+            { name: '降雨量', value: '0', unit: 'mm', isAlert: false },
+            { name: '气压', value: '1013', unit: 'hPa', isAlert: false }
           ]
         },
         {
@@ -637,7 +664,9 @@ export default {
           type: 'water',
           metrics: [
             { name: 'pH值', value: '7.2', unit: '', isAlert: false },
-            { name: '溶解氧', value: '5.8', unit: 'mg/L', isAlert: false }
+            { name: '溶解氧', value: '5.8', unit: 'mg/L', isAlert: false },
+            { name: '电导率', value: '0.9', unit: 'mS/cm', isAlert: false },
+            { name: '浊度', value: '8', unit: 'NTU', isAlert: false }
           ]
         },
         {
@@ -650,7 +679,10 @@ export default {
           type: 'weather',
           metrics: [
             { name: '温度', value: '35.8', unit: '℃', isAlert: true },
-            { name: '湿度', value: '45', unit: '%', isAlert: false }
+            { name: '湿度', value: '45', unit: '%', isAlert: false },
+            { name: '光照强度', value: '52000', unit: 'lux', isAlert: false },
+            { name: '风速', value: '4.2', unit: 'm/s', isAlert: false },
+            { name: '降雨量', value: '2.5', unit: 'mm', isAlert: false }
           ]
         },
         {
@@ -663,7 +695,10 @@ export default {
           type: 'soil',
           metrics: [
             { name: '土壤湿度', value: '28.5', unit: '%', isAlert: false },
-            { name: '土壤温度', value: '22.8', unit: '℃', isAlert: false }
+            { name: '土壤温度', value: '22.8', unit: '℃', isAlert: false },
+            { name: 'EC值', value: '2.1', unit: 'mS/cm', isAlert: false },
+            { name: 'P含量', value: '38', unit: 'mg/kg', isAlert: false },
+            { name: 'K含量', value: '125', unit: 'mg/kg', isAlert: false }
           ]
         },
         {
@@ -676,7 +711,10 @@ export default {
           type: 'water',
           metrics: [
             { name: 'pH值', value: '7.1', unit: '', isAlert: false },
-            { name: '溶解氧', value: '6.5', unit: 'mg/L', isAlert: false }
+            { name: '溶解氧', value: '6.5', unit: 'mg/L', isAlert: false },
+            { name: '电导率', value: '1.1', unit: 'mS/cm', isAlert: false },
+            { name: '温度', value: '23.5', unit: '℃', isAlert: false },
+            { name: '浊度', value: '5', unit: 'NTU', isAlert: false }
           ]
         },
         {
@@ -702,7 +740,11 @@ export default {
           type: 'weather',
           metrics: [
             { name: '温度', value: '28.2', unit: '℃', isAlert: false },
-            { name: '湿度', value: '72', unit: '%', isAlert: false }
+            { name: '湿度', value: '72', unit: '%', isAlert: false },
+            { name: '光照强度', value: '38000', unit: 'lux', isAlert: false },
+            { name: '风速', value: '1.8', unit: 'm/s', isAlert: false },
+            { name: '气压', value: '1015', unit: 'hPa', isAlert: false },
+            { name: 'UV指数', value: '8', unit: '', isAlert: false }
           ]
         }
       ]
@@ -1155,6 +1197,65 @@ export default {
         rainfall: '降雨量'
       }
       return indicatorMap[value] || value
+    },
+    
+    // 轮播控制方法
+    initializeCarousels() {
+      this.deviceList.forEach(device => {
+        if (device.metrics.length > 2) {
+          this.$set(this.carouselStates, device.id, 0)
+          this.startCarouselTimer(device.id)
+        }
+      })
+    },
+    
+    startCarouselTimer(deviceId) {
+      if (this.carouselTimers[deviceId]) {
+        clearInterval(this.carouselTimers[deviceId])
+      }
+      
+      this.carouselTimers[deviceId] = setInterval(() => {
+        this.nextMetric(deviceId)
+      }, 3000) // 3秒切换一次
+    },
+    
+    pauseCarousel(deviceId) {
+      if (this.carouselTimers[deviceId]) {
+        clearInterval(this.carouselTimers[deviceId])
+        this.carouselTimers[deviceId] = null
+      }
+    },
+    
+    resumeCarousel(deviceId) {
+      const device = this.deviceList.find(d => d.id === deviceId)
+      if (device && device.metrics.length > 2) {
+        this.startCarouselTimer(deviceId)
+      }
+    },
+    
+    nextMetric(deviceId) {
+      const device = this.deviceList.find(d => d.id === deviceId)
+      if (!device || device.metrics.length <= 2) return
+      
+      const totalGroups = Math.ceil(device.metrics.length / 2)
+      const currentIndex = this.carouselStates[deviceId] || 0
+      const nextIndex = (currentIndex + 1) % totalGroups
+      
+      this.$set(this.carouselStates, deviceId, nextIndex)
+    },
+    
+    getCurrentMetricIndex(deviceId) {
+      return this.carouselStates[deviceId] || 0
+    },
+    
+    getCurrentMetrics(device) {
+      if (device.metrics.length <= 2) {
+        return device.metrics
+      }
+      
+      const currentIndex = this.carouselStates[device.id] || 0
+      const startIndex = currentIndex * 2
+      return device.metrics.slice(startIndex, startIndex + 2)
     }
   },
   
@@ -1172,6 +1273,9 @@ export default {
       appEl.style.backgroundColor = '#f8fafc'
     }
     
+    // 初始化轮播
+    this.initializeCarousels()
+    
     // 监听键盘事件
     document.addEventListener('keydown', (e) => {
       if (e.key === 'Escape') {
@@ -1202,6 +1306,14 @@ export default {
   },
   
   beforeDestroy() {
+    // 清理所有轮播定时器
+    Object.values(this.carouselTimers).forEach(timer => {
+      if (timer) {
+        clearInterval(timer)
+      }
+    })
+    this.carouselTimers = {}
+    
     // 恢复原始背景色
     document.body.style.backgroundColor = this.originalBodyBg
     document.body.style.color = this.originalBodyColor
@@ -1991,11 +2103,21 @@ export default {
 }
 
 .device-metrics {
+  margin-bottom: 1.5rem;
+  flex: 1;
+}
+
+.metrics-container {
+  position: relative;
+  min-height: 80px;
+  overflow: hidden;
+}
+
+.metric-pair {
   display: grid;
   grid-template-columns: 1fr 1fr;
   gap: 2rem;
-  margin-bottom: 1.5rem;
-  flex: 1;
+  width: 100%;
 }
 
 .metric {
@@ -2028,6 +2150,37 @@ export default {
   color: #ef4444;
 }
 
+.metric-value.metric-alert {
+  color: #ef4444;
+}
+
+/* 机场翻牌动画效果 */
+.flip-enter-active,
+.flip-leave-active {
+  transition: all 0.4s ease-in-out;
+  transform-style: preserve-3d;
+}
+
+.flip-enter {
+  transform: perspective(600px) rotateX(90deg);
+  opacity: 0;
+}
+
+.flip-enter-to {
+  transform: perspective(600px) rotateX(0deg);
+  opacity: 1;
+}
+
+.flip-leave {
+  transform: perspective(600px) rotateX(0deg);
+  opacity: 1;
+}
+
+.flip-leave-to {
+  transform: perspective(600px) rotateX(-90deg);
+  opacity: 0;
+}
+
 .device-card.offline .metric-value {
   color: #9ca3af;
 }