| | |
| | | <!-- e:\VSprojects\fume-supervision-vue\src\views\monitor\DataDashboard.vue --> |
| | | <template> |
| | | <el-container class="data-dashboard"> |
| | | <el-main> |
| | | <!-- 设备在线情况区域 --> |
| | | <DeviceStatus |
| | | :online-count="onlineCount" |
| | | :offline-count="offlineCount" |
| | | :normal-count="normalCount" |
| | | :fault-count="faultCount" |
| | | /> |
| | | |
| | | <!-- 设备实时数据区域 --> |
| | | <RealTimeData :current-device="currentDevice" :hourly-data="hourlyData" /> |
| | | |
| | | <!-- 分区数据排名区域 --> |
| | | <DistrictRanking |
| | | :selected-month="selectedMonth" |
| | | :ranking-type="rankingType" |
| | | :ranking-data="rankingData" |
| | | :sorted-ranking-data="sortedRankingData" |
| | | @month-change="handleMonthChange" |
| | | @type-change="handleTypeChange" |
| | | /> |
| | | <div class="grid-container"> |
| | | <div class="left-section"> |
| | | <!-- 设备在线情况区域 --> |
| | | <DeviceStatus |
| | | :online-count="onlineCount" |
| | | :offline-count="offlineCount" |
| | | :normal-count="normalCount" |
| | | :fault-count="faultCount" |
| | | /> |
| | | <!-- 分区数据排名区域 --> |
| | | <DistrictRanking |
| | | style="flex: 1" |
| | | :selected-month="selectedMonth" |
| | | :ranking-type="rankingType" |
| | | :ranking-data="rankingData" |
| | | :sorted-ranking-data="sortedRankingData" |
| | | @month-change="handleMonthChange" |
| | | @type-change="handleTypeChange" |
| | | /> |
| | | </div> |
| | | <div class="right-section"> |
| | | <!-- 设备实时数据区域 --> |
| | | <RealTimeData style="flex: 1" :devices="devices" /> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- 在线设备和店铺清单区域 --> |
| | | <ShopList |
| | |
| | | faultCount: 0, |
| | | |
| | | // 设备实时数据 |
| | | currentDevice: null, |
| | | hourlyData: [], |
| | | devices: [], |
| | | |
| | | // 分区数据排名 |
| | | selectedMonth: '2023-12', |
| | |
| | | |
| | | 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 }, |
| | | ] |
| | | |
| | | // 排序 |
| | |
| | | padding: 20px; |
| | | } |
| | | |
| | | .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; |
| | | } |
| | | |
| | | /* 响应式设计 */ |
| | | @media (max-width: 768px) { |
| | | .el-row { |
| | | flex-direction: column; |
| | | .grid-container { |
| | | grid-template-columns: 1fr; |
| | | } |
| | | |
| | | .el-col { |
| | | width: 100% !important; |
| | | .left-section, |
| | | .right-section { |
| | | margin-bottom: 10px; |
| | | } |
| | | } |