Explorar el Código

完善详情页

yawuga hace 11 meses
padre
commit
825794321f

BIN
.DS_Store


+ 36 - 70
pages/device-list/detail-camera.vue

@@ -18,9 +18,7 @@
       <view class="device-meta-row">
         <view class="device-meta-item">
           <view class="meta-icon">
-            <svg width="16" height="16" viewBox="0 0 24 24">
-              <path fill="#3BB44A" d="M22,3H2C0.9,3,0,3.9,0,5v14c0,1.1,0.9,2,2,2h20c1.1,0,1.99-0.9,1.99-2L24,5C24,3.9,23.1,3,22,3z M9,17H6.5v-2.5h2.5V17z M9,13H6.5v-2.5h2.5V13z M9,9H6.5V6.5h2.5V9z M13.5,17H11v-2.5h2.5V17z M13.5,13H11v-2.5h2.5V13z M13.5,9H11V6.5h2.5V9z M18,17h-2.5v-2.5H18V17z M18,13h-2.5v-2.5H18V13z M18,9h-2.5V6.5H18V9z"/>
-            </svg>
+            <image src="/static/icons/device_icon.png" mode="aspectFit" style="width: 36rpx; height: 36rpx;"></image>
           </view>
           <text class="meta-label">设备编号:</text>
           <text class="meta-value">{{ deviceInfo.deviceId }}</text>
@@ -28,9 +26,7 @@
         
         <view class="device-meta-item">
           <view class="meta-icon">
-            <svg width="16" height="16" viewBox="0 0 24 24">
-              <path fill="#3BB44A" d="M12,2C8.13,2,5,5.13,5,9c0,5.25,7,13,7,13s7-7.75,7-13C19,5.13,15.87,2,12,2z M12,11.5c-1.38,0-2.5-1.12-2.5-2.5s1.12-2.5,2.5-2.5s2.5,1.12,2.5,2.5S13.38,11.5,12,11.5z"/>
-            </svg>
+            <image src="/static/icons/location_icon.png" mode="aspectFit" style="width: 36rpx; height: 36rpx;"></image>
           </view>
           <text class="meta-label">安装位置:</text>
           <text class="meta-value">{{ deviceInfo.location }}</text>
@@ -38,9 +34,7 @@
         
         <view class="device-meta-item">
           <view class="meta-icon">
-            <svg width="16" height="16" viewBox="0 0 24 24">
-              <path fill="#3BB44A" d="M11.99,2C6.47,2,2,6.48,2,12s4.47,10,9.99,10C17.52,22,22,17.52,22,12S17.52,2,11.99,2z M12,20c-4.42,0-8-3.58-8-8s3.58-8,8-8s8,3.58,8,8S16.42,20,12,20z M12.5,7H11v6l5.25,3.15l0.75-1.23l-4.5-2.67V7z"/>
-            </svg>
+            <image src="/static/icons/clock_icon.png" mode="aspectFit" style="width: 36rpx; height: 36rpx;"></image>
           </view>
           <text class="meta-label">最近更新:</text>
           <text class="meta-value">{{ deviceInfo.lastUpdate }}</text>
@@ -71,30 +65,22 @@
         <view class="video-controls">
           <view class="control-row top-controls">
             <view class="signal-indicator">
-              <svg width="16" height="16" viewBox="0 0 24 24">
-                <path fill="#FFFFFF" d="M1,21h20V1L1,21z M21,21h2v-2h-2V21z M19,7v12h-2V9L5,21H3L21,3v4H19z" />
-              </svg>
+              <image src="/static/icons/signal_icon.png" mode="aspectFit" style="width: 16px; height: 16px;"></image>
               <text class="signal-text">信号良好</text>
             </view>
             
             <view class="fullscreen-button" @click="toggleFullscreen">
-              <svg width="20" height="20" viewBox="0 0 24 24">
-                <path fill="#FFFFFF" d="M7,14H5v5h5v-2H7V14z M5,10h2V7h3V5H5V10z M17,17h-3v2h5v-5h-2V17z M14,5v2h3v3h2V5H14z" />
-              </svg>
+              <image src="/static/icons/resize_icon.png" mode="aspectFit" style="width: 20px; height: 20px;"></image>
             </view>
           </view>
           
           <view class="control-row center-controls">
             <view v-if="!isPlaying" class="play-button" @click="togglePlayState">
-              <svg width="32" height="32" viewBox="0 0 24 24">
-                <path fill="#4CAF50" d="M8,5v14l11-7L8,5z" />
-              </svg>
+              <image src="/static/icons/play_icon.png" mode="aspectFit" style="width: 32px; height: 32px;"></image>
             </view>
             <view v-else class="center-button-container" @click="togglePlayState">
               <view class="pause-icon">
-                <svg width="24" height="24" viewBox="0 0 24 24">
-                  <path fill="#FFFFFF" d="M6,19h4V5H6V19z M14,5v14h4V5H14z" />
-                </svg>
+                <image src="/static/icons/pause_icon.png" mode="aspectFit" style="width: 24px; height: 24px;"></image>
               </view>
             </view>
           </view>
@@ -115,58 +101,42 @@
         <view class="ptz-circle-container">
           <!-- 上箭头 -->
           <view class="ptz-arrow ptz-up" @touchstart="controlPTZ('up', true)" @touchend="controlPTZ('up', false)">
-            <svg width="24" height="24" viewBox="0 0 24 24">
-              <path fill="#3BB44A" d="M7,14l5-5l5,5H7z" />
-            </svg>
+            <image src="/static/icons/arrow_up_icon.png" mode="aspectFit" style="width: 24px; height: 24px;"></image>
           </view>
           
           <!-- 左箭头 -->
           <view class="ptz-arrow ptz-left" @touchstart="controlPTZ('left', true)" @touchend="controlPTZ('left', false)">
-            <svg width="24" height="24" viewBox="0 0 24 24">
-              <path fill="#3BB44A" d="M14,7l-5,5l5,5V7z" />
-            </svg>
+            <image src="/static/icons/arrow_left_icon.png" mode="aspectFit" style="width: 24px; height: 24px;"></image>
           </view>
           
           <!-- 中心拍照按钮 -->
           <view class="ptz-center" @click="takeScreenshot">
-            <svg width="24" height="24" viewBox="0 0 24 24">
-              <path fill="#3BB44A" d="M9,3L7.17,5H4C2.9,5,2,5.9,2,7v12c0,1.1,0.9,2,2,2h16c1.1,0,2-0.9,2-2V7c0-1.1-0.9-2-2-2h-3.17L15,3H9z M12,18c-2.76,0-5-2.24-5-5s2.24-5,5-5s5,2.24,5,5S14.76,18,12,18z M12,10c-1.66,0-3,1.34-3,3s1.34,3,3,3s3-1.34,3-3S13.66,10,12,10z" />
-            </svg>
+            <image src="/static/icons/camera_icon.png" mode="aspectFit" style="width: 24px; height: 24px;"></image>
           </view>
           
           <!-- 右箭头 -->
           <view class="ptz-arrow ptz-right" @touchstart="controlPTZ('right', true)" @touchend="controlPTZ('right', false)">
-            <svg width="24" height="24" viewBox="0 0 24 24">
-              <path fill="#3BB44A" d="M10,17l5-5l-5-5V17z" />
-            </svg>
+            <image src="/static/icons/arrow_right_icon.png" mode="aspectFit" style="width: 24px; height: 24px;"></image>
           </view>
           
           <!-- 下箭头 -->
           <view class="ptz-arrow ptz-down" @touchstart="controlPTZ('down', true)" @touchend="controlPTZ('down', false)">
-            <svg width="24" height="24" viewBox="0 0 24 24">
-              <path fill="#3BB44A" d="M7,10l5,5l5-5H7z" />
-            </svg>
+            <image src="/static/icons/arrow_down_icon.png" mode="aspectFit" style="width: 24px; height: 24px;"></image>
           </view>
         </view>
         
         <!-- 底部操作按钮 -->
         <view class="ptz-bottom-controls">
           <view class="ptz-bottom-button" @touchstart="controlZoom('out', true)" @touchend="controlZoom('out', false)">
-            <svg width="24" height="24" viewBox="0 0 24 24">
-              <path fill="#3BB44A" d="M19,13H5v-2h14V13z" />
-            </svg>
+            <image src="/static/icons/zoom01_icon.png" mode="aspectFit" style="width: 24px; height: 24px;"></image>
           </view>
           
           <view class="ptz-bottom-button" @click="resetPTZ">
-            <svg width="24" height="24" viewBox="0 0 24 24">
-              <path fill="#3BB44A" d="M17.65,6.35C16.2,4.9,14.21,4,12,4c-4.42,0-7.99,3.58-7.99,8s3.57,8,7.99,8c3.73,0,6.84-2.55,7.73-6h-2.08 c-0.82,2.33-3.04,4-5.65,4c-3.31,0-6-2.69-6-6s2.69-6,6-6c1.66,0,3.14,0.69,4.22,1.78L13,12h7V5L17.65,6.35z" />
-            </svg>
+            <image src="/static/icons/resetPTZ_icon.png" mode="aspectFit" style="width: 24px; height: 24px;"></image>
           </view>
           
           <view class="ptz-bottom-button" @touchstart="controlZoom('in', true)" @touchend="controlZoom('in', false)">
-            <svg width="24" height="24" viewBox="0 0 24 24">
-              <path fill="#3BB44A" d="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6V13z" />
-            </svg>
+            <image src="/static/icons/zoom02_icon.png" mode="aspectFit" style="width: 24px; height: 24px;"></image>
           </view>
         </view>
       </view>
@@ -176,30 +146,22 @@
     <view class="quick-actions">
       <view class="action-button" @click="toggleVoiceIntercom">
         <view class="action-icon">
-          <svg width="24" height="24" viewBox="0 0 24 24">
-            <path fill="#3BB44A" d="M12,14c1.66,0,3-1.34,3-3V5c0-1.66-1.34-3-3-3S9,3.34,9,5v6C9,12.66,10.34,14,12,14z M11,5c0-0.55,0.45-1,1-1s1,0.45,1,1v6c0,0.55-0.45,1-1,1s-1-0.45-1-1V5z M17,11c0,2.76-2.24,5-5,5s-5-2.24-5-5H5c0,3.53,2.61,6.43,6,6.92V21h2v-3.08c3.39-0.49,6-3.39,6-6.92H17z" />
-          </svg>
+          <image src="/static/icons/Voice_icon.png" mode="aspectFit" style="width: 24px; height: 24px;"></image>
         </view>
         <text class="action-text">语音对讲</text>
       </view>
       
       <view class="action-button" @click="toggleMute">
         <view class="action-icon">
-          <svg v-if="isMuted" width="24" height="24" viewBox="0 0 24 24">
-            <path fill="#3BB44A" d="M16.5,12c0-1.77-1.02-3.29-2.5-4.03v2.21l2.45,2.45C16.46,12.43,16.5,12.22,16.5,12z M19,12c0,0.94-0.2,1.82-0.54,2.64l1.51,1.51C20.63,14.91,21,13.5,21,12c0-4.28-2.99-7.86-7-8.77v2.06c2.89,0.86,5,3.54,5,6.71z M4.27,3L3,4.27L7.73,9H3v6h4l5,5v-6.73l4.25,4.25c-0.67,0.52-1.42,0.93-2.25,1.18v2.06c1.38-0.31,2.63-0.95,3.69-1.81L19.73,21L21,19.73l-9-9L4.27,3z M12,4L9.91,6.09L12,8.18V4z" />
-          </svg>
-          <svg v-else width="24" height="24" viewBox="0 0 24 24">
-            <path fill="#3BB44A" d="M3,9v6h4l5,5V4L7,9H3z M16.5,12c0-1.77-1.02-3.29-2.5-4.03v8.05C15.48,15.29,16.5,13.77,16.5,12z M14,3.23v2.06c2.89,0.86,5,3.54,5,6.71s-2.11,5.85-5,6.71v2.06c4.01-0.91,7-4.49,7-8.77S18.01,4.14,14,3.23z" />
-          </svg>
+          <image v-if="isMuted" src="/static/icons/muted_icon.png" mode="aspectFit" style="width: 24px; height: 24px;"></image>
+          <image v-else src="/static/icons/unmuted_icon.png" mode="aspectFit" style="width: 24px; height: 24px;"></image>
         </view>
         <text class="action-text">{{ isMuted ? '取消静音' : '静音' }}</text>
       </view>
       
       <view class="action-button" @click="navigateToHistory">
         <view class="action-icon">
-          <svg width="24" height="24" viewBox="0 0 24 24">
-            <path fill="#3BB44A" d="M13,3c-4.97,0-9,4.03-9,9H1l3.89,3.89l0.07,0.14L9,12H6c0-3.87,3.13-7,7-7s7,3.13,7,7s-3.13,7-7,7c-1.93,0-3.68-0.79-4.94-2.06l-1.42,1.42C8.27,19.99,10.51,21,13,21c4.97,0,9-4.03,9-9S17.97,3,13,3z M12,8v5l4.28,2.54l0.72-1.21l-3.5-2.08V8H12z" />
-          </svg>
+          <image src="/static/icons/action_icon.png" mode="aspectFit" style="width: 24px; height: 24px;"></image>
         </view>
         <text class="action-text">视频回看</text>
       </view>
@@ -224,15 +186,9 @@
           }"
         >
           <view class="alert-item-icon">
-            <svg v-if="item.level === 'high'" width="24" height="24" viewBox="0 0 24 24">
-              <path fill="#F56C6C" d="M12,2L1,21h22L12,2z M12,6l7.53,13H4.47L12,6z M11,10v4h2v-4H11z M11,16v2h2v-2H11z" />
-            </svg>
-            <svg v-else-if="item.level === 'medium'" width="24" height="24" viewBox="0 0 24 24">
-              <path fill="#E6A23C" d="M11,15h2v2h-2V15z M11,7h2v6h-2V7z M11.99,2C6.47,2,2,6.48,2,12s4.47,10,9.99,10C17.52,22,22,17.52,22,12S17.52,2,11.99,2z M12,20c-4.42,0-8-3.58-8-8s3.58-8,8-8s8,3.58,8,8S16.42,20,12,20z" />
-            </svg>
-            <svg v-else width="24" height="24" viewBox="0 0 24 24">
-              <path fill="#67C23A" d="M11,7h2v2h-2V7z M11,11h2v6h-2V11z M12,2C6.48,2,2,6.48,2,12s4.48,10,10,10s10-4.48,10-10S17.52,2,12,2z M12,20c-4.41,0-8-3.59-8-8s3.59-8,8-8s8,3.59,8,8S16.41,20,12,20z" />
-            </svg>
+            <image v-if="item.level === 'high'" src="/static/icons/warning_icon.png" mode="aspectFit" style="width: 24px; height: 24px;"></image>
+            <image v-else-if="item.level === 'medium'" src="/static/icons/info_icon.png" mode="aspectFit" style="width: 24px; height: 24px;"></image>
+            <image v-else src="/static/icons/success_icon.png" mode="aspectFit" style="width: 24px; height: 24px;"></image>
           </view>
           
           <view class="alert-item-info">
@@ -373,13 +329,23 @@ export default {
     
     // 全屏切换
     toggleFullscreen() {
-      if (this.videoContext) {
+      if (!this.isPlaying) {
+        // 如果视频未播放,先开始播放
+        this.togglePlayState();
+        // 延迟执行全屏操作,等待视频元素加载
+        setTimeout(() => {
+          if (this.videoContext) {
+            this.videoContext.requestFullScreen();
+            this.isFullscreen = true;
+          }
+        }, 500);
+      } else if (this.videoContext) {
         if (!this.isFullscreen) {
-          this.videoContext.requestFullScreen()
+          this.videoContext.requestFullScreen();
         } else {
-          this.videoContext.exitFullScreen()
+          this.videoContext.exitFullScreen();
         }
-        this.isFullscreen = !this.isFullscreen
+        this.isFullscreen = !this.isFullscreen;
       }
     },
     

+ 206 - 207
pages/device-list/detail-collector.vue

@@ -15,18 +15,14 @@
         </view>
         
         <view class="refresh-btn" :class="{'refreshing': isRefreshing}" @tap="refreshData">
-          <svg width="22" height="22" viewBox="0 0 24 24">
-            <path fill="#3BB44A" d="M17.65,6.35C16.2,4.9,14.21,4,12,4c-4.42,0-7.99,3.58-7.99,8s3.57,8,7.99,8c3.73,0,6.84-2.55,7.73-6h-2.08c-0.82,2.33-3.04,4-5.65,4c-3.31,0-6-2.69-6-6s2.69-6,6-6c1.66,0,3.14,0.69,4.22,1.78L13,11h7V4L17.65,6.35z"/>
-          </svg>
+          <image src="/static/icons/refresh_icon.png" mode="aspectFit" style="width: 22px; height: 22px;"></image>
         </view>
       </view>
       
       <view class="device-meta-row">
         <view class="device-meta-item">
           <view class="meta-icon">
-            <svg width="16" height="16" viewBox="0 0 24 24">
-              <path fill="#3BB44A" d="M22,3H2C0.9,3,0,3.9,0,5v14c0,1.1,0.9,2,2,2h20c1.1,0,1.99-0.9,1.99-2L24,5C24,3.9,23.1,3,22,3z M9,17H6.5v-2.5h2.5V17z M9,13H6.5v-2.5h2.5V13z M9,9H6.5V6.5h2.5V9z M13.5,17H11v-2.5h2.5V17z M13.5,13H11v-2.5h2.5V13z M13.5,9H11V6.5h2.5V9z M18,17h-2.5v-2.5H18V17z M18,13h-2.5v-2.5H18V13z M18,9h-2.5V6.5H18V9z"/>
-            </svg>
+            <image src="/static/icons/device_icon.png" mode="aspectFit" style="width: 36rpx; height: 36rpx;"></image>
           </view>
           <text class="meta-label">设备编号:</text>
           <text class="meta-value">{{ deviceInfo.deviceId }}</text>
@@ -34,9 +30,7 @@
         
         <view class="device-meta-item">
           <view class="meta-icon">
-            <svg width="16" height="16" viewBox="0 0 24 24">
-              <path fill="#3BB44A" d="M12,2C8.13,2,5,5.13,5,9c0,5.25,7,13,7,13s7-7.75,7-13C19,5.13,15.87,2,12,2z M12,11.5c-1.38,0-2.5-1.12-2.5-2.5s1.12-2.5,2.5-2.5s2.5,1.12,2.5,2.5S13.38,11.5,12,11.5z"/>
-            </svg>
+            <image src="/static/icons/location_icon.png" mode="aspectFit" style="width: 36rpx; height: 36rpx;"></image>
           </view>
           <text class="meta-label">安装位置:</text>
           <text class="meta-value">{{ deviceInfo.location }}</text>
@@ -44,9 +38,7 @@
         
         <view class="device-meta-item">
           <view class="meta-icon">
-            <svg width="16" height="16" viewBox="0 0 24 24">
-              <path fill="#3BB44A" d="M11.99,2C6.47,2,2,6.48,2,12s4.47,10,9.99,10C17.52,22,22,17.52,22,12S17.52,2,11.99,2z M12,20c-4.42,0-8-3.58-8-8s3.58-8,8-8s8,3.58,8,8S16.42,20,12,20z M12.5,7H11v6l5.25,3.15l0.75-1.23l-4.5-2.67V7z"/>
-            </svg>
+            <image src="/static/icons/clock_icon.png" mode="aspectFit" style="width: 36rpx; height: 36rpx;"></image>
           </view>
           <text class="meta-label">最近更新:</text>
           <text class="meta-value">{{ deviceInfo.lastUpdate }}</text>
@@ -56,72 +48,61 @@
     
     <!-- 采集数据展示区域 - 气象站 -->
     <view class="data-section" v-if="deviceInfo.deviceType === 'weather'">
-      <view class="section-title">
+      <view class="section-title data-title">
         <text>气象数据</text>
       </view>
       
       <view class="data-grid">
         <!-- 气温 -->
-        <view class="data-item">
-          <view class="data-icon" :class="{'no-data': !weatherData.temperature}">
-            <svg width="28" height="28" viewBox="0 0 24 24">
-              <path fill="#3BB44A" d="M15,13V5c0-1.66-1.34-3-3-3S9,3.34,9,5v8c-1.21,0.91-2,2.37-2,4c0,2.76,2.24,5,5,5s5-2.24,5-5C17,15.37,16.21,13.91,15,13z M11,5c0-0.55,0.45-1,1-1s1,0.45,1,1v3h-2V5z M12,19.5c-1.38,0-2.5-1.12-2.5-2.5c0-0.94,0.53-1.76,1.31-2.17L11.5,14.5v-4h1v4l0.69,0.33c0.78,0.41,1.31,1.23,1.31,2.17C14.5,18.38,13.38,19.5,12,19.5z"/>
-            </svg>
-          </view>
+        <view class="data-item" hover-class="data-item-hover">
           <text class="data-label">气温</text>
           <view class="data-value-container">
             <template v-if="weatherData.temperature">
-              <text class="data-value" :class="{'updated': updatedFields.weather && updatedFields.weather.temperature}">{{ weatherData.temperature }}</text>
+              <text class="data-value" :class="{
+                'updated': updatedFields.weather && updatedFields.weather.temperature,
+                'value-warning': parseFloat(weatherData.temperature) > 35 || parseFloat(weatherData.temperature) < 5
+              }">{{ weatherData.temperature }}</text>
               <text class="data-unit">℃</text>
             </template>
             <text v-else class="data-value no-data">暂无数据</text>
           </view>
-          <text class="data-time" v-if="weatherData.temperature">{{ weatherData.updateTime || '2分钟前更新' }}</text>
+          <text class="data-time">{{ weatherData.updateTime || '2分钟前' }}</text>
         </view>
         
         <!-- 湿度 -->
-        <view class="data-item">
-          <view class="data-icon" :class="{'no-data': !weatherData.humidity}">
-            <svg width="28" height="28" viewBox="0 0 24 24">
-              <path fill="#3BB44A" d="M12,2c-5.33,4.55-8,8.48-8,11.8c0,4.98,3.8,8.2,8,8.2s8-3.22,8-8.2C20,10.48,17.33,6.55,12,2z M12,20c-3.35,0-6-2.57-6-6.2c0-2.34,1.95-5.44,6-9.14c4.05,3.7,6,6.79,6,9.14C18,17.43,15.35,20,12,20z M7.83,14c0.37,0,0.67,0.26,0.74,0.62c0.41,2.22,2.28,2.98,3.64,2.87c0.43-0.02,0.79,0.32,0.79,0.75c0,0.4-0.32,0.73-0.72,0.75c-2.13,0.13-4.62-1.09-5.19-4.12C7.01,14.42,7.37,14,7.83,14z"/>
-            </svg>
-          </view>
+        <view class="data-item" hover-class="data-item-hover">
           <text class="data-label">湿度</text>
           <view class="data-value-container">
             <template v-if="weatherData.humidity">
-              <text class="data-value" :class="{'updated': updatedFields.weather && updatedFields.weather.humidity}">{{ weatherData.humidity }}</text>
+              <text class="data-value" :class="{
+                'updated': updatedFields.weather && updatedFields.weather.humidity,
+                'value-warning': parseFloat(weatherData.humidity) > 85
+              }">{{ weatherData.humidity }}</text>
               <text class="data-unit">%</text>
             </template>
             <text v-else class="data-value no-data">暂无数据</text>
           </view>
-          <text class="data-time" v-if="weatherData.humidity">{{ weatherData.updateTime || '2分钟前更新' }}</text>
+          <text class="data-time">{{ weatherData.updateTime || '2分钟前' }}</text>
         </view>
         
         <!-- 降雨量 -->
-        <view class="data-item">
-          <view class="data-icon" :class="{'no-data': !weatherData.rainfall}">
-            <svg width="28" height="28" viewBox="0 0 24 24">
-              <path fill="#3BB44A" d="M12.01,6c2.61,0,4.89,1.86,5.4,4.43l0.3,1.5l1.52,0.11c1.56,0.11,2.78,1.41,2.78,2.96c0,1.65-1.35,3-3,3h-13c-2.21,0-4-1.79-4-4c0-2.05,1.53-3.76,3.56-3.97l1.07-0.11l0.5-0.95C8.08,7.14,9.95,6,12.01,6 M12,4C9.2,4,6.78,5.64,5.67,8.04C2.68,8.16,0.24,10.7,0.24,13.76c0,3.08,2.49,5.58,5.56,5.58h13.19c2.49,0,4.51-2.03,4.51-4.53c0-2.34-1.77-4.25-4.05-4.5C18.4,6.75,15.49,4,12,4L12,4z M14,11l-2-2l-2,2H8.5l3.5,3.5l3.5-3.5H14z"/>
-            </svg>
-          </view>
+        <view class="data-item" hover-class="data-item-hover">
           <text class="data-label">降雨量</text>
           <view class="data-value-container">
             <template v-if="weatherData.rainfall">
-              <text class="data-value" :class="{'updated': updatedFields.weather && updatedFields.weather.rainfall}">{{ weatherData.rainfall }}</text>
+              <text class="data-value" :class="{
+                'updated': updatedFields.weather && updatedFields.weather.rainfall,
+                'value-alert': parseFloat(weatherData.rainfall) > 10
+              }">{{ weatherData.rainfall }}</text>
               <text class="data-unit">mm</text>
             </template>
             <text v-else class="data-value no-data">暂无数据</text>
           </view>
-          <text class="data-time" v-if="weatherData.rainfall">{{ weatherData.updateTime || '2分钟前更新' }}</text>
+          <text class="data-time">{{ weatherData.updateTime || '2分钟前' }}</text>
         </view>
         
         <!-- 风向 -->
-        <view class="data-item">
-          <view class="data-icon" :class="{'no-data': !weatherData.windDirection}">
-            <svg width="28" height="28" viewBox="0 0 24 24">
-              <path fill="#3BB44A" d="M4,10H3L4,6L5,10H4z M22,10v2h-8v9l-2-1.6V19H9v1.4L7,22v-2.5c0-5.2,0-9.5,0-9.5H6v-2h16z M17,12v-1.5C17,9.7,16.3,9,15.5,9S14,9.7,14,10.5V12H17z M9,7.5C9,9.43,7.43,11,5.5,11S2,9.43,2,7.5S3.57,4,5.5,4S9,5.57,9,7.5z M6.5,7.5C6.5,8.33,6.02,9,5.5,9S4.5,8.33,4.5,7.5S4.98,6,5.5,6S6.5,6.67,6.5,7.5z"/>
-            </svg>
-          </view>
+        <view class="data-item" hover-class="data-item-hover">
           <text class="data-label">风向</text>
           <view class="data-value-container">
             <template v-if="weatherData.windDirection">
@@ -130,34 +111,28 @@
             </template>
             <text v-else class="data-value no-data">暂无数据</text>
           </view>
-          <text class="data-time" v-if="weatherData.windDirection">{{ weatherData.updateTime || '2分钟前更新' }}</text>
+          <text class="data-time">{{ weatherData.updateTime || '2分钟前' }}</text>
         </view>
         
         <!-- 风速 -->
-        <view class="data-item">
-          <view class="data-icon" :class="{'no-data': !weatherData.windSpeed}">
-            <svg width="28" height="28" viewBox="0 0 24 24">
-              <path fill="#3BB44A" d="M17.66,4.53L18.11,4.5c2.05,0.14,3.74,1.86,3.74,3.93c0,1.66-1.04,3.12-2.6,3.7H14v-2h5.56c0.47,0,0.87-0.39,0.87-0.89c0-0.5-0.4-0.89-0.87-0.89H8.5c-0.64,0-1.22,0.18-1.72,0.49c-0.53-0.34-1.14-0.5-1.66-0.51c-0.35,0-0.69,0.04-1.02,0.13c-0.97,0.37-1.69,1.33-1.69,2.38c0,1.44,1.22,2.61,2.72,2.61H9v2H5.14c-2.36,0-4.26-1.88-4.26-4.24c0-1.75,0.91-3.17,2.62-3.88C3.99,5.01,4.81,4.5,5.78,4.5c1.17,0,2.29,0.58,2.96,1.59c0.51-0.25,1.11-0.41,1.76-0.41h5.77L17.66,4.53z M21.11,14.5H17v-2h4.11c2.01,0,3.89,1.63,3.89,3.83c0,1.56-0.88,2.87-2.27,3.44c-0.38,0.14-0.77,0.23-1.21,0.23c-0.84,0-1.75-0.35-2.43-1.14l1.58-1.23c0.27,0.37,0.66,0.57,1.08,0.57c0.76,0,1.38-0.64,1.38-1.43C23.11,15.33,22.2,14.5,21.11,14.5z M13,18H4.69c-2.06,0-3.69-1.69-3.69-3.72c0-1.17,0.58-2.27,1.5-2.97C3.14,11.37,4,12.23,5,12.72V14h7v2H8v2h5V18z"/>
-            </svg>
-          </view>
+        <view class="data-item" hover-class="data-item-hover">
           <text class="data-label">风速</text>
           <view class="data-value-container">
             <template v-if="weatherData.windSpeed">
-              <text class="data-value" :class="{'updated': updatedFields.weather && updatedFields.weather.windSpeed}">{{ weatherData.windSpeed }}</text>
+              <text class="data-value" :class="{
+                'updated': updatedFields.weather && updatedFields.weather.windSpeed,
+                'value-alert': parseFloat(weatherData.windSpeed) > 8,
+                'value-warning': parseFloat(weatherData.windSpeed) > 5 && parseFloat(weatherData.windSpeed) <= 8
+              }">{{ weatherData.windSpeed }}</text>
               <text class="data-unit">m/s</text>
             </template>
             <text v-else class="data-value no-data">暂无数据</text>
           </view>
-          <text class="data-time" v-if="weatherData.windSpeed">{{ weatherData.updateTime || '2分钟前更新' }}</text>
+          <text class="data-time">{{ weatherData.updateTime || '2分钟前' }}</text>
         </view>
         
         <!-- 气压 -->
-        <view class="data-item">
-          <view class="data-icon" :class="{'no-data': !weatherData.pressure}">
-            <svg width="28" height="28" viewBox="0 0 24 24">
-              <path fill="#3BB44A" d="M12,2C6.48,2,2,6.48,2,12s4.48,10,10,10s10-4.48,10-10S17.52,2,12,2z M12,20c-4.41,0-8-3.59-8-8c0-4.41,3.59-8,8-8s8,3.59,8,8C20,16.41,16.41,20,12,20z M13,8h-2v2h-2v2h2v2h2v-2h2v-2h-2V8z M14.5,14.5v-1h-1v1H14.5z M9.5,14.5v-1h-1v1H9.5z M14.5,10.5V10h-1v0.5H14.5z M9.5,10.5V10h-1v0.5H9.5z"/>
-            </svg>
-          </view>
+        <view class="data-item" hover-class="data-item-hover">
           <text class="data-label">气压</text>
           <view class="data-value-container">
             <template v-if="weatherData.pressure">
@@ -166,16 +141,11 @@
             </template>
             <text v-else class="data-value no-data">暂无数据</text>
           </view>
-          <text class="data-time" v-if="weatherData.pressure">{{ weatherData.updateTime || '2分钟前更新' }}</text>
+          <text class="data-time">{{ weatherData.updateTime || '2分钟前' }}</text>
         </view>
         
         <!-- 光照 -->
-        <view class="data-item">
-          <view class="data-icon" :class="{'no-data': !weatherData.illumination}">
-            <svg width="28" height="28" viewBox="0 0 24 24">
-              <path fill="#3BB44A" d="M6.76,4.84l-1.8-1.79-1.41,1.41l1.79,1.79L6.76,4.84z M4,10.5h-2v2h2V10.5z M13,0.55h-2V3.5h2V0.55z M20.45,4.46l-1.41-1.41-1.79,1.79l1.41,1.41L20.45,4.46z M17.24,18.16l1.79,1.8l1.41-1.41l-1.8-1.79L17.24,18.16z M20,10.5v2h2v-2H20z M12,5.5c-3.31,0-6,2.69-6,6s2.69,6,6,6s6-2.69,6-6S15.31,5.5,12,5.5z M11,22.45h2v-2.95h-2V22.45z M3.55,18.54l1.41,1.41l1.79-1.8l-1.41-1.41L3.55,18.54z"/>
-            </svg>
-          </view>
+        <view class="data-item" hover-class="data-item-hover">
           <text class="data-label">光照</text>
           <view class="data-value-container">
             <template v-if="weatherData.illumination">
@@ -184,142 +154,130 @@
             </template>
             <text v-else class="data-value no-data">暂无数据</text>
           </view>
-          <text class="data-time" v-if="weatherData.illumination">{{ weatherData.updateTime || '2分钟前更新' }}</text>
+          <text class="data-time">{{ weatherData.updateTime || '2分钟前' }}</text>
         </view>
       </view>
     </view>
     
     <!-- 采集数据展示区域 - 土壤墒情 -->
     <view class="data-section" v-if="deviceInfo.deviceType === 'soil'">
-      <view class="section-title">
+      <view class="section-title soil-title">
         <text>土壤数据</text>
       </view>
       
       <view class="data-grid">
         <!-- 土壤温度 -->
-        <view class="data-item">
-          <view class="data-icon" :class="{'no-data': !soilData.temperature}">
-            <svg width="28" height="28" viewBox="0 0 24 24">
-              <path fill="#3BB44A" d="M15,13V5c0-1.66-1.34-3-3-3S9,3.34,9,5v8c-1.21,0.91-2,2.37-2,4c0,2.76,2.24,5,5,5s5-2.24,5-5C17,15.37,16.21,13.91,15,13z M12,20c-1.65,0-3-1.35-3-3c0-1.12,0.61-2.1,1.5-2.61V5c0-0.83,0.67-1.5,1.5-1.5s1.5,0.67,1.5,1.5v9.38c0.9,0.52,1.5,1.49,1.5,2.62C15,18.65,13.65,20,12,20z"/>
-            </svg>
-          </view>
+        <view class="data-item" hover-class="data-item-hover">
           <text class="data-label">土壤温度</text>
           <view class="data-value-container">
             <template v-if="soilData.temperature">
-              <text class="data-value" :class="{'updated': updatedFields.soil && updatedFields.soil.temperature}">{{ soilData.temperature }}</text>
+              <text class="data-value" :class="{
+                'updated': updatedFields.soil && updatedFields.soil.temperature,
+                'value-warning': parseFloat(soilData.temperature) > 30 || parseFloat(soilData.temperature) < 5
+              }">{{ soilData.temperature }}</text>
               <text class="data-unit">℃</text>
             </template>
             <text v-else class="data-value no-data">暂无数据</text>
           </view>
-          <text class="data-time" v-if="soilData.temperature">{{ soilData.updateTime || '5分钟前更新' }}</text>
+          <text class="data-time">{{ soilData.updateTime || '5分钟前' }}</text>
         </view>
         
         <!-- 土壤湿度 -->
-        <view class="data-item">
-          <view class="data-icon" :class="{'no-data': !soilData.moisture}">
-            <svg width="28" height="28" viewBox="0 0 24 24">
-              <path fill="#3BB44A" d="M12,2c-5.33,4.55-8,8.48-8,11.8c0,4.98,3.8,8.2,8,8.2s8-3.22,8-8.2C20,10.48,17.33,6.55,12,2z M12,20c-3.35,0-6-2.57-6-6.2c0-2.34,1.95-5.44,6-9.14c4.05,3.7,6,6.79,6,9.14C18,17.43,15.35,20,12,20z"/>
-            </svg>
-          </view>
+        <view class="data-item" hover-class="data-item-hover">
           <text class="data-label">土壤湿度</text>
           <view class="data-value-container">
             <template v-if="soilData.moisture">
-              <text class="data-value" :class="{'updated': updatedFields.soil && updatedFields.soil.moisture}">{{ soilData.moisture }}</text>
+              <text class="data-value" :class="{
+                'updated': updatedFields.soil && updatedFields.soil.moisture,
+                'value-warning': parseFloat(soilData.moisture) < 20,
+                'value-alert': parseFloat(soilData.moisture) < 10
+              }">{{ soilData.moisture }}</text>
               <text class="data-unit">%</text>
             </template>
             <text v-else class="data-value no-data">暂无数据</text>
           </view>
-          <text class="data-time" v-if="soilData.moisture">{{ soilData.updateTime || '5分钟前更新' }}</text>
+          <text class="data-time">{{ soilData.updateTime || '5分钟前' }}</text>
         </view>
         
         <!-- 氮含量 -->
-        <view class="data-item">
-          <view class="data-icon" :class="{'no-data': !soilData.nitrogen}">
-            <svg width="28" height="28" viewBox="0 0 24 24">
-              <path fill="#3BB44A" d="M12,2L4.5,20.29l0.71,0.71L12,18l6.79,3l0.71-0.71L12,2z M12,15.3L7.46,16.97L12,6.69l4.54,10.28L12,15.3z"/>
-            </svg>
-          </view>
+        <view class="data-item" hover-class="data-item-hover">
           <text class="data-label">氮含量</text>
           <view class="data-value-container">
             <template v-if="soilData.nitrogen">
-              <text class="data-value" :class="{'updated': updatedFields.soil && updatedFields.soil.nitrogen}">{{ soilData.nitrogen }}</text>
+              <text class="data-value" :class="{
+                'updated': updatedFields.soil && updatedFields.soil.nitrogen,
+                'value-warning': parseFloat(soilData.nitrogen) < 120
+              }">{{ soilData.nitrogen }}</text>
               <text class="data-unit">mg/kg</text>
             </template>
             <text v-else class="data-value no-data">暂无数据</text>
           </view>
-          <text class="data-time" v-if="soilData.nitrogen">{{ soilData.updateTime || '5分钟前更新' }}</text>
+          <text class="data-time">{{ soilData.updateTime || '5分钟前' }}</text>
         </view>
         
         <!-- 磷含量 -->
-        <view class="data-item">
-          <view class="data-icon" :class="{'no-data': !soilData.phosphorus}">
-            <svg width="28" height="28" viewBox="0 0 24 24">
-              <path fill="#3BB44A" d="M11,15H6.83l3.59-3.59L9,10l-6,6l6,6l1.41-1.41L6.83,17H11c4.42,0,8-3.58,8-8V3h-2v6C17,12.42,14.42,15,11,15z"/>
-            </svg>
-          </view>
+        <view class="data-item" hover-class="data-item-hover">
           <text class="data-label">磷含量</text>
           <view class="data-value-container">
             <template v-if="soilData.phosphorus">
-              <text class="data-value" :class="{'updated': updatedFields.soil && updatedFields.soil.phosphorus}">{{ soilData.phosphorus }}</text>
+              <text class="data-value" :class="{
+                'updated': updatedFields.soil && updatedFields.soil.phosphorus,
+                'value-warning': parseFloat(soilData.phosphorus) < 30
+              }">{{ soilData.phosphorus }}</text>
               <text class="data-unit">mg/kg</text>
             </template>
             <text v-else class="data-value no-data">暂无数据</text>
           </view>
-          <text class="data-time" v-if="soilData.phosphorus">{{ soilData.updateTime || '5分钟前更新' }}</text>
+          <text class="data-time">{{ soilData.updateTime || '5分钟前' }}</text>
         </view>
         
         <!-- 钾含量 -->
-        <view class="data-item">
-          <view class="data-icon" :class="{'no-data': !soilData.potassium}">
-            <svg width="28" height="28" viewBox="0 0 24 24">
-              <path fill="#3BB44A" d="M19,3H5C3.9,3,3,3.9,3,5v14c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2V5C21,3.9,20.1,3,19,3z M13.97,7.17l3.92,7.85C17.96,15.31,18.18,16,18.5,16c0.44,0,0.75-0.53,0.5-1l-4-8h-2l-2,4h-1.5L11,7H8.5L7,11H5.5l1-2l-2-4h10.72C16.42,5,16.97,6.17,13.97,7.17z"/>
-            </svg>
-          </view>
+        <view class="data-item" hover-class="data-item-hover">
           <text class="data-label">钾含量</text>
           <view class="data-value-container">
             <template v-if="soilData.potassium">
-              <text class="data-value" :class="{'updated': updatedFields.soil && updatedFields.soil.potassium}">{{ soilData.potassium }}</text>
+              <text class="data-value" :class="{
+                'updated': updatedFields.soil && updatedFields.soil.potassium,
+                'value-warning': parseFloat(soilData.potassium) < 150
+              }">{{ soilData.potassium }}</text>
               <text class="data-unit">mg/kg</text>
             </template>
             <text v-else class="data-value no-data">暂无数据</text>
           </view>
-          <text class="data-time" v-if="soilData.potassium">{{ soilData.updateTime || '5分钟前更新' }}</text>
+          <text class="data-time">{{ soilData.updateTime || '5分钟前' }}</text>
         </view>
         
         <!-- 土壤电导率 -->
-        <view class="data-item">
-          <view class="data-icon" :class="{'no-data': !soilData.conductivity}">
-            <svg width="28" height="28" viewBox="0 0 24 24">
-              <path fill="#3BB44A" d="M14.69,6.63L14.69,6.63c-0.35-0.35-0.92-0.35-1.27,0l-6.75,6.73c-0.35,0.35-0.35,0.92,0,1.27l0,0c0.35,0.35,0.92,0.35,1.27,0l6.75-6.73C15.04,7.55,15.04,6.98,14.69,6.63z M16.21,15.83l1.56-1.56c0.2-0.2,0.2-0.51,0-0.71c-0.2-0.2-0.51-0.2-0.71,0l-1.56,1.56c-0.2,0.2-0.2,0.51,0,0.71C15.7,16.02,16.02,16.02,16.21,15.83z M12.41,14.27c-0.2-0.2-0.51-0.2-0.71,0l-1.56,1.56c-0.2,0.2-0.2,0.51,0,0.71c0.2,0.2,0.51,0.2,0.71,0l1.56-1.56C12.61,14.78,12.61,14.47,12.41,14.27z M19,6.5C19,4.01,16.99,2,14.5,2c-1.82,0-3.53,1.15-4.27,2.64c-0.4-0.19-0.86-0.3-1.33-0.3C7.17,4.35,6,5.53,6,7c0,0.6,0.13,1.22,0.38,1.79C4.88,9.15,4,10.67,4,12.43C4,15.52,6.49,18,9.56,18h10.81c0.44,0,0.69-0.54,0.39-0.85l-1.56-1.56c-0.2-0.2-0.51-0.2-0.71,0c-0.2,0.2-0.2,0.51,0,0.71l0.63,0.63H9.56c-2.52,0-4.56-2.05-4.56-4.57c0-1.37,0.61-2.64,1.67-3.51L7.4,8.47c0.33,0.48,0.8,0.8,1.35,0.95C8.24,8.67,8,7.86,8,7c0-0.54,0.42-0.98,0.95-1c0.36-0.01,0.71,0.08,1.03,0.28l0.56,0.29l0.15-0.62C11.13,4.39,12.74,3,14.5,3C16.43,3,18,4.57,18,6.5v0.58c0,0.17,0.13,0.29,0.29,0.29c0.51,0.04,1.1,0.24,1.53,0.55C19.37,7.35,19,6.42,19,6.5z"/>
-            </svg>
-          </view>
+        <view class="data-item" hover-class="data-item-hover">
           <text class="data-label">电导率</text>
           <view class="data-value-container">
             <template v-if="soilData.conductivity">
-              <text class="data-value" :class="{'updated': updatedFields.soil && updatedFields.soil.conductivity}">{{ soilData.conductivity }}</text>
+              <text class="data-value" :class="{
+                'updated': updatedFields.soil && updatedFields.soil.conductivity,
+                'value-alert': parseFloat(soilData.conductivity) > 0.8
+              }">{{ soilData.conductivity }}</text>
               <text class="data-unit">μS/cm</text>
             </template>
             <text v-else class="data-value no-data">暂无数据</text>
           </view>
-          <text class="data-time" v-if="soilData.conductivity">{{ soilData.updateTime || '5分钟前更新' }}</text>
+          <text class="data-time">{{ soilData.updateTime || '5分钟前' }}</text>
         </view>
         
         <!-- PH值 -->
-        <view class="data-item">
-          <view class="data-icon" :class="{'no-data': !soilData.ph}">
-            <svg width="28" height="28" viewBox="0 0 24 24">
-              <path fill="#3BB44A" d="M12,2c-5.33,4.55-8,8.48-8,11.8c0,4.98,3.8,8.2,8,8.2s8-3.22,8-8.2C20,10.48,17.33,6.55,12,2z M8.83,16.29c-1.03-1.46-1.74-3.39-1.26-5.37c0.17-0.71,0.49-1.34,0.9-1.92c0.17-0.24,0.35-0.47,0.55-0.67c0.18-0.21,0.38-0.36,0.58-0.54c0.72-0.49,1.45-0.89,2.1-1.39c0.35-0.22,0.7-0.43,1.05-0.61c0.43-0.23,0.93-0.35,1.26-0.68c0.21-0.21,0.35-0.47,0.45-0.77c0.1-0.28,0.17-0.64,0.25-0.91C14.84,3.16,14.99,3,15.16,3c0.55,0,0.59,0.41,0.61,0.44l0.05,0.15c0.04,0.11,0.21,0.71,0.21,1.03c0,0.53-0.23,0.94-0.44,1.31c-0.52,0.88-1.31,1.25-1.92,1.84c-0.36,0.38-0.66,0.85-0.91,1.34c-0.27,0.5-0.47,1.07-0.49,1.66c-0.02,0.42,0.05,0.86,0.27,1.26c0.23,0.43,0.65,0.65,1.06,0.65c0.71,0,1.24-0.46,1.58-0.97c0.46-0.66,0.74-1.48,0.95-2.27c0.11-0.46,0.18-0.93,0.23-1.35c0.14-1.16,0.27-2.25,0.95-2.33c0.17-0.02,0.3,0.01,0.42,0.12c0.32,0.29,0.31,1.11,0.32,1.38c0,0.51-0.01,1.19-0.14,1.83c-0.07,0.32-0.17,0.64-0.28,0.95c-0.19,0.48-0.4,0.95-0.66,1.34C15.85,12.85,15.29,13.16,14.7,13.29z M12,19.8c-3.46,0-6-2.55-6-6c0-0.34,0.03-0.67,0.08-1l0.93,0.7c0.19,0.47,0.55,0.96,1.28,1.23c0.67,0.25,1.37,0.05,1.86-0.33c0.27-0.21,0.48-0.46,0.65-0.71c0.62-0.95,0.89-2.85,0.62-4.04C11.32,9.32,11.17,9.05,11,8.88c0.03-0.06,0.13-0.16,0.3-0.22c0.37-0.14,0.64,0.11,0.82,0.37c0.28,0.42,0.46,0.82,0.55,1.24c0.02,0.08,0.04,0.18,0.05,0.24c0.12,0.52,0.33,1.72-0.25,3.07c-0.52,1.2-1.45,2.25-2.92,2.25c-1.66,0-2.52-1.24-2.67-2.03c-0.19-1.01,0.04-2.33,0.55-3.37c0.44-0.89,1-1.69,1.68-2.35c0.82-0.79,1.73-1.45,2.73-1.99c0.29-0.16,0.6-0.32,0.84-0.44c-0.14,0.45-0.37,0.76-0.87,1.07c-0.54,0.36-1.17,0.67-1.71,1.01c-0.65,0.36-1.26,0.76-1.81,1.18c-0.38,0.28-0.78,0.59-1.15,0.97c-1.1,1.06-1.84,2.23-2.2,3.41c-0.27,0.86-0.37,1.75-0.29,2.6c0.09,0.92,0.38,1.81,0.88,2.58c0.91,1.38,2.45,2.28,4.28,2.28c4.12,0,6-4.27,6-7c0-0.45-0.04-0.85-0.12-1.22c-0.08-0.36-0.21-0.69-0.4-0.97c0,0,0.18-0.07,0.35,0c0.23,0.09,0.39,0.29,0.52,0.67c0.18,0.56,0.25,1.12,0.25,1.68C18,17.41,15.4,19.8,12,19.8z"/>
-            </svg>
-          </view>
+        <view class="data-item" hover-class="data-item-hover">
           <text class="data-label">PH值</text>
           <view class="data-value-container">
             <template v-if="soilData.ph">
-              <text class="data-value" :class="{'updated': updatedFields.soil && updatedFields.soil.ph}">{{ soilData.ph }}</text>
+              <text class="data-value" :class="{
+                'updated': updatedFields.soil && updatedFields.soil.ph,
+                'value-warning': parseFloat(soilData.ph) < 5.5 || parseFloat(soilData.ph) > 8.5,
+                'value-alert': parseFloat(soilData.ph) < 4.5 || parseFloat(soilData.ph) > 9
+              }">{{ soilData.ph }}</text>
               <text class="data-unit"></text>
             </template>
             <text v-else class="data-value no-data">暂无数据</text>
           </view>
-          <text class="data-time" v-if="soilData.ph">{{ soilData.updateTime || '5分钟前更新' }}</text>
+          <text class="data-time">{{ soilData.updateTime || '5分钟前' }}</text>
         </view>
       </view>
     </view>
@@ -343,15 +301,9 @@
           }"
         >
           <view class="alert-item-icon">
-            <svg v-if="item.level === 'high'" width="24" height="24" viewBox="0 0 24 24">
-              <path fill="#F56C6C" d="M12,2L1,21h22L12,2z M12,6l7.53,13H4.47L12,6z M11,10v4h2v-4H11z M11,16v2h2v-2H11z" />
-            </svg>
-            <svg v-else-if="item.level === 'medium'" width="24" height="24" viewBox="0 0 24 24">
-              <path fill="#E6A23C" d="M11,15h2v2h-2V15z M11,7h2v6h-2V7z M11.99,2C6.47,2,2,6.48,2,12s4.47,10,9.99,10C17.52,22,22,17.52,22,12S17.52,2,11.99,2z M12,20c-4.42,0-8-3.58-8-8s3.58-8,8-8s8,3.58,8,8S16.42,20,12,20z" />
-            </svg>
-            <svg v-else width="24" height="24" viewBox="0 0 24 24">
-              <path fill="#67C23A" d="M11,7h2v2h-2V7z M11,11h2v6h-2V11z M12,2C6.48,2,2,6.48,2,12s4.48,10,10,10s10-4.48,10-10S17.52,2,12,2z M12,20c-4.41,0-8-3.59-8-8c0-4.41,3.59-8,8-8s8,3.59,8,8C20,16.41,16.41,20,12,20z" />
-            </svg>
+            <image v-if="item.level === 'high'" src="/static/icons/warning_icon.png" mode="aspectFit" style="width: 24px; height: 24px;"></image>
+            <image v-else-if="item.level === 'medium'" src="/static/icons/info_icon.png" mode="aspectFit" style="width: 24px; height: 24px;"></image>
+            <image v-else src="/static/icons/success_icon.png" mode="aspectFit" style="width: 24px; height: 24px;"></image>
           </view>
           
           <view class="alert-item-info">
@@ -896,9 +848,9 @@ export default {
 .data-section {
   margin: 0 30rpx 30rpx;
   background-color: #FFFFFF;
-  border-radius: 20rpx;
+  border-radius: 24rpx;
   padding: 30rpx 24rpx;
-  box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.04);
+  box-shadow: 0 6rpx 20rpx rgba(0, 0, 0, 0.05);
   border: 1rpx solid rgba(210, 237, 217, 0.5);
 }
 
@@ -906,7 +858,7 @@ export default {
   font-size: 32rpx;
   font-weight: 600;
   color: #333333;
-  margin-bottom: 30rpx;
+  margin-bottom: 20rpx;
   padding: 0 10rpx 16rpx;
   display: flex;
   align-items: center;
@@ -922,7 +874,7 @@ export default {
   transform: translateY(-50%);
   width: 8rpx;
   height: 32rpx;
-  background-color: #3BB44A;
+  background: linear-gradient(to bottom, #4CAF50, #81C784);
   border-radius: 4rpx;
   margin-right: 10rpx;
 }
@@ -946,26 +898,28 @@ export default {
 .data-grid {
   display: flex;
   flex-wrap: wrap;
-  padding: 10rpx 0;
+  padding: 16rpx 0;
   width: 100%;
-  margin: 0 -10rpx;
+  margin: 0 -12rpx;
 }
 
 .data-item {
-  width: calc(50% - 20rpx);
-  margin: 0 10rpx 20rpx;
+  width: calc(50% - 24rpx);
+  margin: 0 12rpx 24rpx;
   display: flex;
   flex-direction: column;
-  align-items: center;
-  background-color: #F6FCF7;
-  border-radius: 16rpx;
-  padding: 24rpx 16rpx;
+  align-items: flex-start;
+  justify-content: space-between;
+  background: linear-gradient(to bottom right, #F9FFFB, #FFFFFF);
+  border-radius: 24rpx;
+  padding: 28rpx 24rpx;
   box-sizing: border-box;
-  box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.06);
+  box-shadow: 0 6rpx 18rpx rgba(0, 0, 0, 0.06), inset 0 1rpx 3rpx rgba(255, 255, 255, 0.8);
   position: relative;
   border: 1rpx solid rgba(210, 237, 217, 0.6);
   transition: all 0.25s ease;
   overflow: hidden;
+  min-height: 180rpx;
 }
 
 .data-item::before {
@@ -973,79 +927,119 @@ export default {
   position: absolute;
   top: 0;
   left: 0;
-  width: 6rpx;
+  width: 8rpx;
   height: 100%;
-  background: linear-gradient(to bottom, #4CAF50, #8BC34A);
-  opacity: 0.8;
+  background: linear-gradient(to bottom, #4CAF50, #81C784);
+  opacity: 0.9;
+  border-radius: 4rpx 0 0 4rpx;
 }
 
-.data-item:active {
-  transform: translateY(2rpx);
-  box-shadow: 0 1rpx 6rpx rgba(0, 0, 0, 0.1);
-  border-color: rgba(76, 175, 80, 0.8);
-}
-
-.data-icon {
-  width: 40rpx;
-  height: 40rpx;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  margin-bottom: 16rpx;
-  background-color: rgba(76, 175, 80, 0.08);
-  border-radius: 50%;
-  padding: 20rpx;
-  transition: transform 0.3s ease;
-}
-
-.data-icon:active {
-  transform: scale(1.1);
-}
-
-.data-icon.no-data {
-  opacity: 0.5;
+.data-item-hover {
+  transform: scale(1.02);
+  box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.08), inset 0 1rpx 3rpx rgba(255, 255, 255, 0.8);
+  background: linear-gradient(to bottom right, #F7FFF9, #FFFFFF);
 }
 
 .data-label {
   font-size: 26rpx;
-  color: #555555;
-  margin-bottom: 12rpx;
+  color: #666666;
+  margin-bottom: 22rpx;
   font-weight: 500;
-  text-align: center;
+  align-self: flex-start;
 }
 
 .data-value-container {
   display: flex;
   align-items: flex-end;
-  justify-content: center;
-  margin-bottom: 10rpx;
+  width: 100%;
+  margin-bottom: 18rpx;
 }
 
 .data-value {
-  font-size: 36rpx;
-  color: #333333;
-  font-weight: 600;
+  font-size: 40rpx;
+  color: #222222;
+  font-weight: 700;
+  line-height: 1;
 }
 
 .data-value.no-data {
-  font-size: 26rpx;
+  font-size: 28rpx;
   color: #999999;
   font-weight: normal;
 }
 
 .data-unit {
-  font-size: 22rpx;
-  color: #888888;
-  margin-left: 4rpx;
+  font-size: 24rpx;
+  color: #999999;
+  margin-left: 6rpx;
   padding-bottom: 6rpx;
+  align-self: flex-end;
 }
 
 .data-time {
   font-size: 20rpx;
   color: #AAAAAA;
-  margin-top: 8rpx;
-  text-align: right;
   width: 100%;
+  text-align: right;
+}
+
+/* 数据更新动画 */
+@keyframes fadeNumberChange {
+  0% {
+    opacity: 0.6;
+    transform: scale(0.95);
+  }
+  50% {
+    opacity: 1;
+    transform: scale(1.05);
+  }
+  100% {
+    opacity: 1;
+    transform: scale(1);
+  }
+}
+
+.data-value.updated {
+  animation: fadeNumberChange 0.8s ease;
+}
+
+/* 异常值样式 */
+.value-warning {
+  color: #E6A23C !important;
+}
+
+.value-alert {
+  color: #F56C6C !important;
+}
+
+/* 点击波纹效果(可选)*/
+@keyframes ripple {
+  0% {
+    transform: scale(0);
+    opacity: 0.6;
+  }
+  100% {
+    transform: scale(2);
+    opacity: 0;
+  }
+}
+
+.data-item::after {
+  content: '';
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  background-color: rgba(76, 175, 80, 0.1);
+  border-radius: 24rpx;
+  opacity: 0;
+  transition: opacity 0.3s;
+  z-index: -1;
+}
+
+.data-item-hover::after {
+  opacity: 1;
 }
 
 /* 告警信息列表 */
@@ -1144,26 +1138,6 @@ export default {
   color: #999999;
 }
 
-/* 数据更新动画 */
-@keyframes fadeNumberChange {
-  0% {
-    opacity: 0.6;
-    transform: scale(0.95);
-  }
-  50% {
-    opacity: 1;
-    transform: scale(1.05);
-  }
-  100% {
-    opacity: 1;
-    transform: scale(1);
-  }
-}
-
-.data-value.updated {
-  animation: fadeNumberChange 0.8s ease;
-}
-
 /* 刷新按钮旋转动画 */
 @keyframes spin {
   0% {
@@ -1177,4 +1151,29 @@ export default {
 .refresh-btn.refreshing {
   animation: spin 1.2s linear infinite;
 }
+
+/* 土壤数据标题样式调整 */
+.soil-title, .data-title {
+  display: flex;
+  align-items: center;
+  position: relative;
+  padding-left: 24rpx;
+}
+
+.soil-title::before, .data-title::before {
+  content: '';
+  position: absolute;
+  left: 0;
+  top: 50%;
+  transform: translateY(-50%);
+  width: 8rpx;
+  height: 36rpx;
+  background: linear-gradient(to bottom, #4CAF50, #81C784);
+  border-radius: 4rpx;
+}
+
+.soil-title text, .data-title text {
+  margin-left: 16rpx;
+  font-weight: 600;
+}
 </style> 

BIN
static/.DS_Store


BIN
static/icons/.DS_Store


BIN
static/icons/Voice_icon.png


BIN
static/icons/action_icon.png


BIN
static/icons/arrow_down_icon.png


BIN
static/icons/arrow_left_icon.png


BIN
static/icons/arrow_right_icon.png


BIN
static/icons/arrow_up_icon.png


BIN
static/icons/camera_icon.png


BIN
static/icons/clock_icon.png


BIN
static/icons/device_icon.png


BIN
static/icons/info_icon.png


BIN
static/icons/location_icon.png


BIN
static/icons/muted_icon.png


BIN
static/icons/pause_icon.png


BIN
static/icons/play_icon.png


BIN
static/icons/refresh_icon.png


BIN
static/icons/resetPTZ_icon.png


BIN
static/icons/resize_icon.png


BIN
static/icons/signal_icon.png


BIN
static/icons/success_icon.png


BIN
static/icons/unmuted_icon.png


BIN
static/icons/warning_icon.png


BIN
static/icons/zoom01_icon.png


BIN
static/icons/zoom02_icon.png