餐饮油烟智能监测与监管一体化平台
riku
2026-03-04 49e2b7ea866695957633855f71f9e2f943b11ec7
src/views/monitor/DataDashboard.vue
@@ -1,7 +1,8 @@
<!-- e:\VSprojects\fume-supervision-vue\src\views\monitor\DataDashboard.vue -->
<template>
  <el-container class="data-dashboard">
    <el-main>
      <div class="grid-container">
        <div class="left-section">
      <!-- 设备在线情况区域 -->
      <DeviceStatus
        :online-count="onlineCount"
@@ -9,12 +10,9 @@
        :normal-count="normalCount"
        :fault-count="faultCount"
      />
      <!-- 设备实时数据区域 -->
      <RealTimeData :current-device="currentDevice" :hourly-data="hourlyData" />
      <!-- 分区数据排名区域 -->
      <DistrictRanking
            style="flex: 1"
        :selected-month="selectedMonth"
        :ranking-type="rankingType"
        :ranking-data="rankingData"
@@ -22,6 +20,12 @@
        @month-change="handleMonthChange"
        @type-change="handleTypeChange"
      />
        </div>
        <div class="right-section">
          <!-- 设备实时数据区域 -->
          <RealTimeData style="flex: 1" :devices="devices" />
        </div>
      </div>
      <!-- 在线设备和店铺清单区域 -->
      <ShopList
@@ -58,8 +62,7 @@
      faultCount: 0,
      // 设备实时数据
      currentDevice: null,
      hourlyData: [],
      devices: [],
      // 分区数据排名
      selectedMonth: '2023-12',
@@ -147,45 +150,80 @@
    updateRealTimeData() {
      // 模拟数据 - 实际应从API获取
      const devices = [
      this.devices = [
        {
          deviceId: 'DEV-001',
          supplier: '供应商A',
          油烟浓度: (Math.random() * 2).toFixed(2),
          风机电流: (Math.random() * 5 + 1).toFixed(2),
          净化器电流: (Math.random() * 3 + 0.5).toFixed(2),
          status: '正常',
          monitorTime: new Date().toLocaleString(),
          smokeDensity: (Math.random() * 2).toFixed(2),
          fanCurrent: (Math.random() * 5 + 1).toFixed(2),
          purifierCurrent: (Math.random() * 3 + 0.5).toFixed(2),
          hourlyData: this.generateHourlyData(),
        },
        {
          deviceId: 'DEV-002',
          supplier: '供应商B',
          status: '正常',
          monitorTime: new Date().toLocaleString(),
          smokeDensity: (Math.random() * 2).toFixed(2),
          fanCurrent: (Math.random() * 5 + 1).toFixed(2),
          purifierCurrent: (Math.random() * 3 + 0.5).toFixed(2),
          hourlyData: this.generateHourlyData(),
        },
        {
          deviceId: 'DEV-003',
          supplier: '供应商C',
          status: '异常',
          monitorTime: new Date().toLocaleString(),
          smokeDensity: (Math.random() * 15 + 5).toFixed(2),
          fanCurrent: (Math.random() * 3 + 4).toFixed(2),
          purifierCurrent: (Math.random() * 2 + 2).toFixed(2),
          hourlyData: this.generateHourlyData(),
        },
        {
          deviceId: 'DEV-004',
          supplier: '供应商D',
          status: '异常',
          monitorTime: new Date().toLocaleString(),
          smokeDensity: (Math.random() * 15 + 5).toFixed(2),
          fanCurrent: (Math.random() * 3 + 4).toFixed(2),
          purifierCurrent: (Math.random() * 2 + 2).toFixed(2),
          hourlyData: this.generateHourlyData(),
        },
      ]
    },
      this.currentDevice = devices[0]
    generateHourlyData() {
      // 生成模拟的近一小时数据
      this.hourlyData = []
      const hourlyData = []
      for (let i = 59; i >= 0; i--) {
        const time = new Date()
        time.setMinutes(time.getMinutes() - i)
        this.hourlyData.push({
        hourlyData.push({
          time: time.toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' }),
          油烟浓度: (Math.random() * 2).toFixed(2),
          风机电流: (Math.random() * 5 + 1).toFixed(2),
          净化器电流: (Math.random() * 3 + 0.5).toFixed(2),
          smokeDensity: (Math.random() * 2).toFixed(2),
          fanCurrent: (Math.random() * 5 + 1).toFixed(2),
          purifierCurrent: (Math.random() * 3 + 0.5).toFixed(2),
        })
      }
      return hourlyData
    },
    updateRankingData() {
      // 模拟数据 - 实际应从API获取
      this.rankingData = [
        { name: '东城区', value: (Math.random() * 1.5 + 0.5).toFixed(2), rankChange: 0 },
        { name: '西城区', value: (Math.random() * 1.5 + 0.5).toFixed(2), rankChange: -1 },
        { name: '朝阳区', value: (Math.random() * 1.5 + 0.5).toFixed(2), rankChange: 1 },
        { name: '海淀区', value: (Math.random() * 1.5 + 0.5).toFixed(2), rankChange: 0 },
        { name: '丰台区', value: (Math.random() * 1.5 + 0.5).toFixed(2), rankChange: -2 },
        { name: '石景山区', value: (Math.random() * 1.5 + 0.5).toFixed(2), rankChange: 2 },
        { name: '通州区', value: (Math.random() * 1.5 + 0.5).toFixed(2), rankChange: 0 },
        { name: '顺义区', value: (Math.random() * 1.5 + 0.5).toFixed(2), rankChange: 1 },
        { name: '昌平区', value: (Math.random() * 1.5 + 0.5).toFixed(2), rankChange: -1 },
        { name: '大兴区', value: (Math.random() * 1.5 + 0.5).toFixed(2), rankChange: 0 },
        { name: '玄武区', value: (Math.random() * 1.5 + 0.5).toFixed(2), rankChange: 0 },
        { name: '秦淮区', value: (Math.random() * 1.5 + 0.5).toFixed(2), rankChange: -1 },
        { name: '建邺区', value: (Math.random() * 1.5 + 0.5).toFixed(2), rankChange: 1 },
        { name: '鼓楼区', value: (Math.random() * 1.5 + 0.5).toFixed(2), rankChange: 0 },
        { name: '浦口区', value: (Math.random() * 1.5 + 0.5).toFixed(2), rankChange: -2 },
        { name: '栖霞区', value: (Math.random() * 1.5 + 0.5).toFixed(2), rankChange: 2 },
        { name: '雨花台区', value: (Math.random() * 1.5 + 0.5).toFixed(2), rankChange: 0 },
        { name: '江宁区', value: (Math.random() * 1.5 + 0.5).toFixed(2), rankChange: 1 },
        { name: '六合区', value: (Math.random() * 1.5 + 0.5).toFixed(2), rankChange: -1 },
        { name: '溧水区', value: (Math.random() * 1.5 + 0.5).toFixed(2), rankChange: 0 },
        { name: '高淳区', value: (Math.random() * 1.5 + 0.5).toFixed(2), rankChange: 1 },
      ]
      // 排序
@@ -240,14 +278,35 @@
  padding: 20px;
}
/* 响应式设计 */
@media (max-width: 768px) {
  .el-row {
.grid-container {
  display: flex;
  /* display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: min-content; */
  gap: 20px;
}
.left-section {
  flex: 2;
  display: flex;
  flex-direction: column;
  gap: 20px;
}
.right-section {
  width: 670px;
  display: flex;
    flex-direction: column;
  }
  .el-col {
    width: 100% !important;
/* 响应式设计 */
@media (max-width: 768px) {
  .grid-container {
    grid-template-columns: 1fr;
  }
  .left-section,
  .right-section {
    margin-bottom: 10px;
  }
}