餐饮油烟智能监测与监管一体化平台
riku
2026-03-18 8e8d00477b1f30183d0d09cd7ec744067595dc46
src/views/monitor/DataDashboard.vue
@@ -186,10 +186,10 @@
          </div>
        </div>
        <!-- 任务完成率 -->
        <!-- 巡查点次 -->
        <div class="metric-card">
          <div class="card-header">
            <div class="card-title">任务完成率</div>
            <div class="card-title">巡查点次</div>
            <div class="card-icon task-icon">
              <svg
                width="20"
@@ -215,18 +215,18 @@
              </svg>
            </div>
          </div>
          <div class="card-value">{{ metrics.taskCompletionRate }}%</div>
          <div class="card-value">{{ metrics.inspectionPoints }}</div>
          <div class="card-trend">
            <span
              class="trend-arrow"
              :class="{
                up: metrics.taskCompletionRateTrend > 0,
                down: metrics.taskCompletionRateTrend < 0,
                up: metrics.inspectionPointsTrend > 0,
                down: metrics.inspectionPointsTrend < 0,
              }"
            >
              {{ metrics.taskCompletionRateTrend > 0 ? '↑' : '↓' }}
              {{ metrics.inspectionPointsTrend > 0 ? '↑' : '↓' }}
            </span>
            <span class="trend-text">{{ Math.abs(metrics.taskCompletionRateTrend) }}%</span>
            <span class="trend-text">{{ Math.abs(metrics.inspectionPointsTrend) }}</span>
            <span class="trend-label">{{ getCompareLabel() }}</span>
          </div>
        </div>
@@ -306,6 +306,43 @@
      <!-- 设备状态饼图 -->
      <div class="device-status-chart">
        <canvas id="deviceStatusChart"></canvas>
      </div>
    </div>
    <!-- 地图图例 -->
    <div class="map-legend">
      <div class="legend-header">
        <h4>图例</h4>
      </div>
      <div class="legend-items">
        <div class="legend-item">
          <img src="@/assets/exceed.png" alt="油烟浓度超标" class="legend-icon" />
          <span class="legend-text">油烟浓度超标</span>
        </div>
        <div class="legend-item">
          <img src="@/assets/exception.png" alt="供电异常" class="legend-icon" />
          <span class="legend-text">供电异常</span>
        </div>
        <div class="legend-item">
          <img src="@/assets/offline.png" alt="设备或网络异常" class="legend-icon" />
          <span class="legend-text">设备或网络异常</span>
        </div>
        <div class="legend-item">
          <img
            src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIHZpZXdCb3g9IjAgMCAzMiAzMiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cmVjdCB4PSI1IiB5PSI4IiB3aWR0aD0iMjIiIGhlaWdodD0iMTYiIHJ4PSIzIiBmaWxsPSIjNTJjNDFhIiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjIiLz48cGF0aCBkPSJNNSA4IFEgMTYgMyAyNyA4IiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjIiIGZpbGw9IiMzODllMGQiLz48cGF0aCBkPSJNNSAyNCBRIDE2IDI5IDI3IDI0IiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjIiIGZpbGw9IiM2NjY2NjYiLz48cmVjdCB4PSI4IiB5PSIxMSIgd2lkdGg9IjE2IiBoZWlnaHQ9IjEwIiByeD0iMiIgZmlsbD0id2hpdGUiLz48cGF0aCBkPSJNMTIgMTQgTCAyMSAxNCIgc3Ryb2tlPSIjNTJjNDFhIiBzdHJva2Utd2lkdGg9IjEuNSIvPjxwYXRoIGQ9Ik0xMiAxNyBMIDE4IDE3IiBzdHJva2U9IiM1MmM0MWEiIHN0cm9rZS13aWR0aD0iMS41Ii8+PHBhdGggZD0iTTEyIDIwIEwgMTUgMjAiIHN0cm9rZT0iIzUyYzQxYSIgc3Ryb2tlLXdpZHRoPSIxLjUiLz48bGluZSB4MT0iMTYiIHkxPSI4IiB4Mj0iMTYiIHkyPSIzIiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjEuNSIvPjxjaXJjbGUgY3g9IjE2IiBjeT0iMyIgcj0iMS41IiBmaWxsPSJ3aGl0ZSIvPjxjaXJjbGUgY3g9IjI3IiBjeT0iMTYiIHI9IjMiIGZpbGw9IiNmZmZmZmYiLz48Y2lyY2xlIGN4PSIyNyIgY3k9IjE2IiByPSIxLjUiIGZpbGw9IiM1MmM0MWEiLz48bGluZSB4MT0iNSIgeTE9IjEzIiB4Mj0iNiIgeTI9IjEzIiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjEuNSIvPjxsaW5lIHgxPSI1IiB5MT0iMTkiIHgyPSI2IiB5Mj0iMTkiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMS41Ii8+PC9zdmc+"
            alt="在线状态"
            class="legend-icon"
          />
          <span class="legend-text">在线状态</span>
        </div>
        <div class="legend-item">
          <img
            src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIHZpZXdCb3g9IjAgMCAzMiAzMiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cmVjdCB4PSI1IiB5PSI4IiB3aWR0aD0iMjIiIGhlaWdodD0iMTYiIHJ4PSIzIiBmaWxsPSIjOGM4YzhjIiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjIiLz48cGF0aCBkPSJNNSA4IFEgMTYgMyAyNyA4IiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjIiIGZpbGw9IiM2NjY2NjYiLz48cGF0aCBkPSJNNSAyNCBRIDE2IDI5IDI3IDI0IiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjIiIGZpbGw9IiM2NjY2NjYiLz48cmVjdCB4PSI4IiB5PSIxMSIgd2lkdGg9IjE2IiBoZWlnaHQ9IjEwIiByeD0iMiIgZmlsbD0id2hpdGUiLz48bGluZSB4MT0iMTEiIHkxPSIxMiIgeDI9IjIxIiB5Mj0iMjIiIHN0cm9rZT0iIzhjOGM4YyIgc3Ryb2tlLXdpZHRoPSIyIi8+PGxpbmUgeDE9IjExIiB5MT0iMjIiIHgyPSIyMSIgeTI9IjEyIiBzdHJva2U9IiM4YzhjOGMiIHN0cm9rZS13aWR0aD0iMiIvPjxsaW5lIHgxPSIxNiIgeTE9IjgiIHgyPSIxNiIgeTI9IjMiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMS41Ii8+PGNpcmNsZSBjeD0iMTYiIGN5PSIzIiByPSIxLjUiIGZpbGw9IndoaXRlIi8+PGNpcmNsZSBjeD0iMjciIGN5PSIxNiIgcj0iMyIgZmlsbD0iI2ZmZmZmZiIvPjxjaXJjbGUgY3g9IjI3IiBjeT0iMTYiIHI9IjEuNSIgZmlsbD0iIzhjOGM4YyIvPjxsaW5lIHgxPSI1IiB5MT0iMTMiIHgyPSI2IiB5Mj0iMTMiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMS41Ii8+PGxpbmUgeDE9IjUiIHkxPSIxOSIgeDI9IjYiIHkyPSIxOSIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIxLjUiLz48L3N2Zz4="
            alt="离线状态"
            class="legend-icon"
          />
          <span class="legend-text">离线状态</span>
        </div>
      </div>
    </div>
    <!-- 巡查情况统计卡片 -->
@@ -469,8 +506,8 @@
        onlineRateTrend: 2,
        purifierEfficiency: 85,
        purifierEfficiencyTrend: -3,
        taskCompletionRate: 78,
        taskCompletionRateTrend: 10,
        inspectionPoints: 350,
        inspectionPointsTrend: 50,
      },
      overview: {
        totalShops: 245,
@@ -601,8 +638,8 @@
          onlineRateTrend: Math.floor(Math.random() * 10) - 5,
          purifierEfficiency: Math.floor(Math.random() * 30) + 70,
          purifierEfficiencyTrend: Math.floor(Math.random() * 10) - 5,
          taskCompletionRate: Math.floor(Math.random() * 40) + 60,
          taskCompletionRateTrend: Math.floor(Math.random() * 15) - 7,
          inspectionPoints: Math.floor(Math.random() * 100) + 300,
          inspectionPointsTrend: Math.floor(Math.random() * 100) - 50,
        }
        // 更新巡查统计数据
@@ -1263,6 +1300,51 @@
  animation: blink 1s infinite;
}
/* 地图图例样式 */
.map-legend {
  position: absolute;
  bottom: 4px;
  right: 4px;
  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;
  z-index: 10;
}
.legend-header {
  margin-bottom: 12px;
}
.legend-header h4 {
  font-size: 14px;
  font-weight: 600;
  color: #262626;
  margin: 0;
  text-align: center;
}
.legend-items {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.legend-item {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  color: #4e5969;
}
.legend-icon {
  width: 24px;
  height: 24px;
  object-fit: contain;
}
/* 响应式设计 */
/* @media (max-width: 1200px) {
  .top-cards {