|
|
@ -8,7 +8,7 @@ |
|
|
<div class="container-left" style="height: 100%;margin: 0; position: relative;"> |
|
|
<div class="container-left" style="height: 100%;margin: 0; position: relative;"> |
|
|
<span class="right-top-line" /> |
|
|
<span class="right-top-line" /> |
|
|
<span class="left-bottom-line" /> |
|
|
<span class="left-bottom-line" /> |
|
|
<h3 class=" table-title" style="margin-bottom: 26px;"> |
|
|
|
|
|
|
|
|
<h3 class=" table-title" style="margin-bottom:26px;"> |
|
|
<p class="title-arrow"> |
|
|
<p class="title-arrow"> |
|
|
档案检索 |
|
|
档案检索 |
|
|
</p> |
|
|
</p> |
|
|
@ -26,49 +26,87 @@ |
|
|
</p> |
|
|
</p> |
|
|
</h3> |
|
|
</h3> |
|
|
<div class="home-floor-tab"> |
|
|
<div class="home-floor-tab"> |
|
|
<p :class="{ 'active-floor': floorEnvIndex == 0 }" @click="changeFloorEnvTab(0)">3楼</p> |
|
|
|
|
|
|
|
|
<!-- :class="{ 'active-floor': floorEnvIndex == 0 }" @click="changeFloorEnvTab(0)" --> |
|
|
|
|
|
<p :class="{ 'active-floor': floorEnvIndex == 0 || floorEnvIndex == 1 }">3楼</p> |
|
|
</div> |
|
|
</div> |
|
|
<el-carousel ref="carouselEnvRef" trigger="click" :interval="10000" indicator-position="none" height="110px" arrow="never" @change="handleEnvChange"> |
|
|
|
|
|
|
|
|
<!-- 环境数据轮播容器:隐藏指示器,分屏展示温湿度 + 其他指标 --> |
|
|
|
|
|
<el-carousel |
|
|
|
|
|
ref="carouselEnvRef" |
|
|
|
|
|
trigger="click" |
|
|
|
|
|
:interval="5000" |
|
|
|
|
|
indicator-position="none" |
|
|
|
|
|
height="110px" |
|
|
|
|
|
arrow="hover" |
|
|
|
|
|
@change="handleEnvChange" |
|
|
|
|
|
> |
|
|
|
|
|
<!-- 第一屏:温湿度 --> |
|
|
<el-carousel-item> |
|
|
<el-carousel-item> |
|
|
<div class="warehouse-tab" style="display: flex; justify-content: center; align-items: center; height: calc(100%); "> |
|
|
|
|
|
<div class="five-bottom"> |
|
|
|
|
|
<!-- <p class="env-title">档案库</p> --> |
|
|
|
|
|
<!-- <ul class="leakage-list"> |
|
|
|
|
|
<li :class="{ 'leakage-warn': topDisplayData.DAK_DIV_TOP_001.curstatus > 0 }"> |
|
|
|
|
|
<p>温度</p> |
|
|
|
|
|
<span>{{ topDisplayData.DAK_DIV_TOP_001.curValue }}</span> |
|
|
|
|
|
|
|
|
<div class="warehouse-tab" style="display: flex; justify-content: center; align-items: center; height: 100%;"> |
|
|
|
|
|
<div v-if="hasValidData" class="env-alarm-container env-humiture-container"> |
|
|
|
|
|
<ul class="env-alarm-list env-humiture-list"> |
|
|
|
|
|
<li> |
|
|
|
|
|
<svg-icon icon-class="temperature" class-name="msg-list-svg" /> |
|
|
|
|
|
<div> |
|
|
|
|
|
<span>{{ avgData.temperature }} </span> |
|
|
|
|
|
<p>温度 {{ avgData.temperatureUnit }}</p> |
|
|
|
|
|
</div> |
|
|
|
|
|
</li> |
|
|
|
|
|
<li> |
|
|
|
|
|
<svg-icon icon-class="shidu" class-name="msg-list-svg" /> |
|
|
|
|
|
<div> |
|
|
|
|
|
<span>{{ avgData.humidity }}</span> |
|
|
|
|
|
<p>湿度 {{ avgData.humidityUnit }}</p> |
|
|
|
|
|
</div> |
|
|
</li> |
|
|
</li> |
|
|
<li :class="{ 'leakage-warn': topDisplayData.DAK_DIV_TOP_002.curstatus > 0 }"> |
|
|
|
|
|
<p>湿度</p> |
|
|
|
|
|
<span>{{ topDisplayData.DAK_DIV_TOP_002.curValue }}</span> |
|
|
|
|
|
|
|
|
</ul> |
|
|
|
|
|
</div> |
|
|
|
|
|
<div v-else class="empty-main" style="height: 100%; display: flex; align-items: center; justify-content: center;"> |
|
|
|
|
|
<svg-icon icon-class="empty" class-name="empty-img" /> |
|
|
|
|
|
</div> |
|
|
|
|
|
</div> |
|
|
|
|
|
</el-carousel-item> |
|
|
|
|
|
|
|
|
|
|
|
<!-- 第二屏:env-alarm-list-second 内容 --> |
|
|
|
|
|
<el-carousel-item> |
|
|
|
|
|
<div class="warehouse-tab" style="display: flex; justify-content: center; align-items: center; height: 100%;"> |
|
|
|
|
|
<div v-if="hasValidData" class="env-alarm-container"> |
|
|
|
|
|
<ul class="leakage-list env-alarm-list-second"> |
|
|
|
|
|
<li :class="alarmStatus.infrared === '告警' ? 'leakage-warn' : ''"> |
|
|
|
|
|
<p>红外</p> |
|
|
|
|
|
<span>{{ alarmStatus.infrared }}</span> |
|
|
</li> |
|
|
</li> |
|
|
<li :class="{ 'leakage-warn': topDisplayData.DAK_DIV_TOP_003.curstatus > 0 }"> |
|
|
|
|
|
<p>CO2</p> |
|
|
|
|
|
<span>{{ topDisplayData.DAK_DIV_TOP_003.curValue }}</span> |
|
|
|
|
|
|
|
|
<li :class="alarmStatus.fire === '告警' ? 'leakage-warn' : ''"> |
|
|
|
|
|
<p>消防</p> |
|
|
|
|
|
<span>{{ alarmStatus.fire }}</span> |
|
|
</li> |
|
|
</li> |
|
|
<li :class="{ 'leakage-warn': topDisplayData.DAK_DIV_TOP_005.curstatus > 0 }"> |
|
|
|
|
|
<p>PM2.5</p> |
|
|
|
|
|
<span>{{ topDisplayData.DAK_DIV_TOP_005.curValue }}</span> |
|
|
|
|
|
|
|
|
<li :class="alarmStatus.waterLeak === '告警' ? 'leakage-warn' : ''"> |
|
|
|
|
|
<p>漏水</p> |
|
|
|
|
|
<span>{{ alarmStatus.waterLeak }}</span> |
|
|
</li> |
|
|
</li> |
|
|
<li :class="{ 'leakage-warn': topDisplayData.DAK_DIV_TOP_006.curstatus > 0 }"> |
|
|
|
|
|
<p>PM10</p> |
|
|
|
|
|
<span>{{ topDisplayData.DAK_DIV_TOP_006.curValue }}</span> |
|
|
|
|
|
|
|
|
<li> |
|
|
|
|
|
<p>PM2.5浓度</p> |
|
|
|
|
|
<span>{{ avgData.pm25 }}{{ avgData.pm25Unit }}</span> |
|
|
</li> |
|
|
</li> |
|
|
<li :class="{ 'leakage-warn': topDisplayData.DAK_DIV_TOP_004.curstatus > 0 }"> |
|
|
|
|
|
|
|
|
<li> |
|
|
<p>TVOC</p> |
|
|
<p>TVOC</p> |
|
|
<span>{{ topDisplayData.DAK_DIV_TOP_004.curValue }}</span> |
|
|
|
|
|
|
|
|
<span>{{ avgData.tvoc }}{{ avgData.tvocUnit }}</span> |
|
|
</li> |
|
|
</li> |
|
|
</ul> --> |
|
|
|
|
|
|
|
|
|
|
|
<ul v-if="newAlarm && newAlarm.length !== 0" class="leakage-list"> |
|
|
|
|
|
<li v-for="item in newAlarm" :key="item.SUBID"> |
|
|
|
|
|
<div class="msg-txt"> |
|
|
|
|
|
<p>{{ item.subName }}</p> |
|
|
|
|
|
<span>{{ item.value }}</span> |
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
<li> |
|
|
|
|
|
<p>PM10浓度</p> |
|
|
|
|
|
<span>{{ avgData.pm10 }}{{ avgData.pm10Unit }}</span> |
|
|
|
|
|
</li> |
|
|
|
|
|
<li> |
|
|
|
|
|
<p>二氧化碳</p> |
|
|
|
|
|
<span>{{ avgData.co2 }}{{ avgData.co2Unit }}</span> |
|
|
|
|
|
</li> |
|
|
|
|
|
<li> |
|
|
|
|
|
<p>甲醛</p> |
|
|
|
|
|
<span>{{ avgData.formaldehyde }}{{ avgData.formaldehydeUnit }}</span> |
|
|
</li> |
|
|
</li> |
|
|
</ul> |
|
|
</ul> |
|
|
|
|
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
<div v-else class="empty-main" style="height: 100%; display: flex; align-items: center; justify-content: center;"> |
|
|
|
|
|
<svg-icon icon-class="empty" class-name="empty-img" /> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</el-carousel-item> |
|
|
</el-carousel-item> |
|
|
@ -86,7 +124,6 @@ |
|
|
</h3> |
|
|
</h3> |
|
|
<div class="home-floor-tab"> |
|
|
<div class="home-floor-tab"> |
|
|
<p :class="{ 'active-floor': floorIndex == 0 }" @click="changeFloorTab(0)">3楼</p> |
|
|
<p :class="{ 'active-floor': floorIndex == 0 }" @click="changeFloorTab(0)">3楼</p> |
|
|
<!-- <p :class="{ 'active-floor': floorIndex == 1 }" @click="changeFloorTab(1)">7楼</p> --> |
|
|
|
|
|
</div> |
|
|
</div> |
|
|
<el-carousel ref="carouselRef" trigger="click" :interval="4000" indicator-position="none" height="110px" arrow="never" @change="handleChange"> |
|
|
<el-carousel ref="carouselRef" trigger="click" :interval="4000" indicator-position="none" height="110px" arrow="never" @change="handleChange"> |
|
|
<el-carousel-item> |
|
|
<el-carousel-item> |
|
|
@ -132,8 +169,7 @@ |
|
|
</el-col> |
|
|
</el-col> |
|
|
<el-col :xs="24" :sm="24" :lg="8"> |
|
|
<el-col :xs="24" :sm="24" :lg="8"> |
|
|
<!-- 门禁记录 --> |
|
|
<!-- 门禁记录 --> |
|
|
<!-- <security-door :height="'calc(100% - 40px)'" /> --> |
|
|
|
|
|
<AccessDoor :height="'calc(100% - 40px)'" /> |
|
|
|
|
|
|
|
|
<AccessDoor :height="'calc(100% - 40px)'" size="5" /> |
|
|
</el-col> |
|
|
</el-col> |
|
|
<el-col :xs="24" :sm="24" :lg="8"> |
|
|
<el-col :xs="24" :sm="24" :lg="8"> |
|
|
<!-- 报警记录 --> |
|
|
<!-- 报警记录 --> |
|
|
@ -195,17 +231,15 @@ import lendAcross from '@/views/components/echarts/lendAcross.vue' |
|
|
import catePie from '@/views/components/echarts/catePie.vue' |
|
|
import catePie from '@/views/components/echarts/catePie.vue' |
|
|
import typePie from '@/views/components/echarts/typePie.vue' |
|
|
import typePie from '@/views/components/echarts/typePie.vue' |
|
|
import WarehouseWarning from '@/views/components/WarehouseWarning' |
|
|
import WarehouseWarning from '@/views/components/WarehouseWarning' |
|
|
// import SecurityDoor from '@/views/components/SecurityDoor' |
|
|
|
|
|
import AccessDoor from '@/views/components/AccessDoor' |
|
|
import AccessDoor from '@/views/components/AccessDoor' |
|
|
import SearchAcrives from '@/views/archivesManage/archivesSearch/index' |
|
|
import SearchAcrives from '@/views/archivesManage/archivesSearch/index' |
|
|
import { statisticsCrud } from '@/views/system/archiveStatistics/mixins/statistics' |
|
|
import { statisticsCrud } from '@/views/system/archiveStatistics/mixins/statistics' |
|
|
import { FetchWaitBorrower } from '@/api/archivesManage/lendManage' |
|
|
import { FetchWaitBorrower } from '@/api/archivesManage/lendManage' |
|
|
// import displayConfigApi from '@/api/storeManage/displayConfig' |
|
|
|
|
|
// import thirdApi from '@/api/thirdApi' |
|
|
|
|
|
import alarmApi from '@/api/home/alarm' |
|
|
import alarmApi from '@/api/home/alarm' |
|
|
|
|
|
import { mapGetters } from 'vuex' |
|
|
|
|
|
|
|
|
// import { allDeviceData, mockIpData } from '@/views/environmentalScreen/index.js' |
|
|
// import { allDeviceData, mockIpData } from '@/views/environmentalScreen/index.js' |
|
|
|
|
|
|
|
|
// 同步mock方法 |
|
|
|
|
|
// const mockFetchDataForIP = (params) => { |
|
|
// const mockFetchDataForIP = (params) => { |
|
|
// return new Promise((resolve) => { |
|
|
// return new Promise((resolve) => { |
|
|
// setTimeout(() => { |
|
|
// setTimeout(() => { |
|
|
@ -215,13 +249,11 @@ import alarmApi from '@/api/home/alarm' |
|
|
// }, 500) |
|
|
// }, 500) |
|
|
// }) |
|
|
// }) |
|
|
// } |
|
|
// } |
|
|
import { mapGetters } from 'vuex' |
|
|
|
|
|
|
|
|
|
|
|
export default { |
|
|
export default { |
|
|
name: 'Dashboard', |
|
|
name: 'Dashboard', |
|
|
components: { |
|
|
components: { |
|
|
WarehouseWarning, |
|
|
WarehouseWarning, |
|
|
// SecurityDoor, |
|
|
|
|
|
AccessDoor, |
|
|
AccessDoor, |
|
|
PanelGroup, |
|
|
PanelGroup, |
|
|
lendAcross, |
|
|
lendAcross, |
|
|
@ -240,78 +272,58 @@ export default { |
|
|
allDisplayConfigData: [], |
|
|
allDisplayConfigData: [], |
|
|
displayConfigData: [], |
|
|
displayConfigData: [], |
|
|
url: '', |
|
|
url: '', |
|
|
allDeviceIds: [], |
|
|
|
|
|
oaoMessage: { |
|
|
|
|
|
ZLS_MO_OAO_001: { |
|
|
|
|
|
show: false, |
|
|
|
|
|
wendu: '', |
|
|
|
|
|
sidu: '', |
|
|
|
|
|
alarmState: 0 |
|
|
|
|
|
}, |
|
|
|
|
|
YLS_MO_OAO_001: { |
|
|
|
|
|
show: false, |
|
|
|
|
|
wendu: '', |
|
|
|
|
|
sidu: '', |
|
|
|
|
|
alarmState: 0 |
|
|
|
|
|
} |
|
|
|
|
|
}, |
|
|
|
|
|
topDisplayData: { |
|
|
|
|
|
DAK_DIV_TOP_001: { |
|
|
|
|
|
show: false, |
|
|
|
|
|
curValue: '', |
|
|
|
|
|
unit: '', |
|
|
|
|
|
curstatus: 0 |
|
|
|
|
|
}, |
|
|
|
|
|
DAK_DIV_TOP_002: { |
|
|
|
|
|
show: false, |
|
|
|
|
|
curValue: '', |
|
|
|
|
|
unit: '', |
|
|
|
|
|
curstatus: 0 |
|
|
|
|
|
}, |
|
|
|
|
|
DAK_DIV_TOP_003: { |
|
|
|
|
|
show: false, |
|
|
|
|
|
curValue: '', |
|
|
|
|
|
unit: '', |
|
|
|
|
|
curstatus: 0 |
|
|
|
|
|
}, |
|
|
|
|
|
DAK_DIV_TOP_004: { |
|
|
|
|
|
show: false, |
|
|
|
|
|
curValue: '', |
|
|
|
|
|
unit: '', |
|
|
|
|
|
curstatus: 0 |
|
|
|
|
|
}, |
|
|
|
|
|
DAK_DIV_TOP_005: { |
|
|
|
|
|
show: false, |
|
|
|
|
|
curValue: '', |
|
|
|
|
|
unit: '', |
|
|
|
|
|
curstatus: 0 |
|
|
|
|
|
}, |
|
|
|
|
|
DAK_DIV_TOP_006: { |
|
|
|
|
|
show: false, |
|
|
|
|
|
curValue: '', |
|
|
|
|
|
unit: '', |
|
|
|
|
|
curstatus: 0 |
|
|
|
|
|
} |
|
|
|
|
|
}, |
|
|
|
|
|
// 同步FullView的核心数据 |
|
|
|
|
|
newAlarm: [], |
|
|
|
|
|
|
|
|
allDeviceIds: [], // 所有设备IP(仅过滤空IP) |
|
|
|
|
|
// 环境数据核心配置 |
|
|
|
|
|
newAlarm: [], // 所有设备的原始数据 |
|
|
aqiValue: 45, |
|
|
aqiValue: 45, |
|
|
aqiStatus: '健康', |
|
|
|
|
|
|
|
|
aqiStatus: '优', |
|
|
keepIndicators: [ |
|
|
keepIndicators: [ |
|
|
'二氧化碳', |
|
|
'二氧化碳', |
|
|
|
|
|
'CO2浓度', |
|
|
'甲醛', |
|
|
'甲醛', |
|
|
'综合气体', |
|
|
'综合气体', |
|
|
'PM2.5浓度', |
|
|
'PM2.5浓度', |
|
|
'PM10浓度', |
|
|
'PM10浓度', |
|
|
'温度', |
|
|
'温度', |
|
|
'湿度', |
|
|
'湿度', |
|
|
'空气质量' |
|
|
|
|
|
|
|
|
'空气质量', |
|
|
|
|
|
'TVOC', |
|
|
|
|
|
'红外', |
|
|
|
|
|
'消防', |
|
|
|
|
|
'漏水' |
|
|
], |
|
|
], |
|
|
ipToNameMap: {}, // IP到设备名称映射 |
|
|
|
|
|
currentDeviceName: '', // 当前显示设备名称 |
|
|
|
|
|
currentIpIndex: 0, // IP轮询索引 |
|
|
|
|
|
excludeIpList: ['192.168.99.101:6003'], // 排除IP列表 |
|
|
|
|
|
dataTimer: null // 数据轮询定时器 |
|
|
|
|
|
|
|
|
// 平均值数据 |
|
|
|
|
|
avgData: { |
|
|
|
|
|
temperature: '0.00', |
|
|
|
|
|
temperatureUnit: '', |
|
|
|
|
|
humidity: '0.00', |
|
|
|
|
|
humidityUnit: '', |
|
|
|
|
|
pm25: '0.00', |
|
|
|
|
|
pm25Unit: '', |
|
|
|
|
|
tvoc: '0.00', |
|
|
|
|
|
tvocUnit: '', |
|
|
|
|
|
pm10: '0.00', |
|
|
|
|
|
pm10Unit: '', |
|
|
|
|
|
co2: '0.00', |
|
|
|
|
|
co2Unit: '', |
|
|
|
|
|
formaldehyde: '0.00', |
|
|
|
|
|
formaldehydeUnit: '' |
|
|
|
|
|
}, |
|
|
|
|
|
// 告警状态 |
|
|
|
|
|
alarmStatus: { |
|
|
|
|
|
infrared: '正常', |
|
|
|
|
|
fire: '正常', |
|
|
|
|
|
waterLeak: '正常' |
|
|
|
|
|
}, |
|
|
|
|
|
aqiGradeStandard: [ |
|
|
|
|
|
{ aqiMin: 0, aqiMax: 50, level: '优', colorKey: 'excellent' }, |
|
|
|
|
|
{ aqiMin: 51, aqiMax: 100, level: '良', colorKey: 'good' }, |
|
|
|
|
|
{ aqiMin: 101, aqiMax: 150, level: '轻度污染', colorKey: 'lightPollution' }, |
|
|
|
|
|
{ aqiMin: 151, aqiMax: 200, level: '中度污染', colorKey: 'mediumPollution' }, |
|
|
|
|
|
{ aqiMin: 201, aqiMax: 300, level: '重度污染', colorKey: 'heavyPollution' }, |
|
|
|
|
|
{ aqiMin: 301, aqiMax: 500, level: '严重污染', colorKey: 'severePollution' } |
|
|
|
|
|
], |
|
|
|
|
|
hasValidData: false // 是否有有效环境数据 |
|
|
} |
|
|
} |
|
|
}, |
|
|
}, |
|
|
computed: { |
|
|
computed: { |
|
|
@ -320,130 +332,302 @@ export default { |
|
|
]) |
|
|
]) |
|
|
}, |
|
|
}, |
|
|
beforeDestroy() { |
|
|
beforeDestroy() { |
|
|
if (this.dataTimer) { |
|
|
|
|
|
clearInterval(this.dataTimer) |
|
|
|
|
|
this.dataTimer = null |
|
|
|
|
|
console.log('轮询定时器已清除') |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// 清理定时器(已移除轮询,此处仅做兼容) |
|
|
}, |
|
|
}, |
|
|
async created() { |
|
|
async created() { |
|
|
|
|
|
// 获取待办事项 |
|
|
this.getWaitBorrower() |
|
|
this.getWaitBorrower() |
|
|
|
|
|
|
|
|
// 真实请求请替换: |
|
|
|
|
|
await alarmApi.FetchYpGetSite().then((data) => { |
|
|
|
|
|
if (data && data.length > 0) { |
|
|
|
|
|
this.allDisplayConfigData = data |
|
|
|
|
|
// 处理设备IP列表 |
|
|
|
|
|
this.handleDeviceIpList() |
|
|
|
|
|
} else { |
|
|
|
|
|
this.allDisplayConfigData = [] |
|
|
|
|
|
} |
|
|
|
|
|
// this.allDisplayConfigData = allDeviceData |
|
|
|
|
|
// this.handleDeviceIpList() |
|
|
|
|
|
}) |
|
|
|
|
|
|
|
|
// 加载所有设备配置数据 |
|
|
|
|
|
await this.loadAllDeviceConfig() |
|
|
|
|
|
|
|
|
// 初始加载+创建定时器 |
|
|
|
|
|
|
|
|
// 获取所有设备的环境数据 |
|
|
if (this.allDeviceIds.length > 0) { |
|
|
if (this.allDeviceIds.length > 0) { |
|
|
this.currentDeviceName = this.ipToNameMap[this.allDeviceIds[0]] || '' |
|
|
|
|
|
await this.getRealTimeData(this.allDeviceIds[0]) |
|
|
|
|
|
|
|
|
|
|
|
// 移到这里创建定时器 |
|
|
|
|
|
this.dataTimer = setInterval(async() => { |
|
|
|
|
|
const currentIp = this.getNextIp() |
|
|
|
|
|
this.currentDeviceName = this.ipToNameMap[currentIp] || '' |
|
|
|
|
|
await this.getRealTimeData(currentIp) |
|
|
|
|
|
}, 10000) |
|
|
|
|
|
console.log(`启动IP轮询,共${this.allDeviceIds.length}个有效IP:`, this.allDeviceIds) |
|
|
|
|
|
|
|
|
await this.getAllDevicesData() |
|
|
|
|
|
// 计算平均值和AQI |
|
|
|
|
|
this.calcAllAvgData() |
|
|
|
|
|
this.calcAQIByAvg() |
|
|
} else { |
|
|
} else { |
|
|
console.warn('无有效设备IP,停止轮询') |
|
|
|
|
|
this.newAlarm = [] |
|
|
|
|
|
|
|
|
console.warn('无有效设备IP数据') |
|
|
|
|
|
this.hasValidData = false |
|
|
} |
|
|
} |
|
|
}, |
|
|
}, |
|
|
mounted() { |
|
|
mounted() { |
|
|
// if (this.allDeviceIds.length > 0) { |
|
|
|
|
|
// this.dataTimer = setInterval(async() => { |
|
|
|
|
|
// const currentIp = this.getNextIp() |
|
|
|
|
|
// this.currentDeviceName = this.ipToNameMap[currentIp] || '' |
|
|
|
|
|
// await this.getRealTimeData(currentIp) |
|
|
|
|
|
// }, 10000) |
|
|
|
|
|
// console.log(`启动IP轮询,共${this.allDeviceIds.length}个有效IP:`, this.allDeviceIds) |
|
|
|
|
|
// } |
|
|
|
|
|
}, |
|
|
}, |
|
|
methods: { |
|
|
methods: { |
|
|
/** |
|
|
/** |
|
|
* 处理设备IP列表(去重+排除+名称映射) |
|
|
|
|
|
|
|
|
* 加载所有设备配置数据 |
|
|
|
|
|
*/ |
|
|
|
|
|
async loadAllDeviceConfig() { |
|
|
|
|
|
// this.allDisplayConfigData = allDeviceData |
|
|
|
|
|
// this.handleDeviceIpList() |
|
|
|
|
|
try { |
|
|
|
|
|
const data = await alarmApi.FetchYpGetSite() |
|
|
|
|
|
if (data && data.length > 0) { |
|
|
|
|
|
this.allDisplayConfigData = data |
|
|
|
|
|
// 处理设备IP列表(仅过滤空IP,无其他排除) |
|
|
|
|
|
this.handleDeviceIpList() |
|
|
|
|
|
} else { |
|
|
|
|
|
this.allDisplayConfigData = [] |
|
|
|
|
|
this.allDeviceIds = [] |
|
|
|
|
|
} |
|
|
|
|
|
} catch (error) { |
|
|
|
|
|
console.error('加载设备配置失败:', error) |
|
|
|
|
|
this.allDisplayConfigData = [] |
|
|
|
|
|
this.allDeviceIds = [] |
|
|
|
|
|
} |
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 处理设备IP列表(仅过滤空IP,无其他排除逻辑) |
|
|
*/ |
|
|
*/ |
|
|
handleDeviceIpList() { |
|
|
handleDeviceIpList() { |
|
|
const ipSet = new Set() |
|
|
const ipSet = new Set() |
|
|
this.ipToNameMap = {} |
|
|
|
|
|
|
|
|
|
|
|
this.allDisplayConfigData.forEach(element => { |
|
|
this.allDisplayConfigData.forEach(element => { |
|
|
const ip = (element.IP || '').trim() |
|
|
const ip = (element.IP || '').trim() |
|
|
if (ip && !this.excludeIpList.includes(ip)) { |
|
|
|
|
|
|
|
|
if (ip) { // 仅过滤空IP,不排除任何IP |
|
|
ipSet.add(ip) |
|
|
ipSet.add(ip) |
|
|
this.ipToNameMap[ip] = element.Name || `未知设备(${ip})` |
|
|
|
|
|
console.log('有效设备IP:', ip, '设备名称:', element.Name) |
|
|
console.log('有效设备IP:', ip, '设备名称:', element.Name) |
|
|
} else if (this.excludeIpList.includes(ip)) { |
|
|
|
|
|
console.log('排除指定IP:', ip, '设备名称:', element.Name) |
|
|
|
|
|
} else if (!ip) { |
|
|
|
|
|
console.log('过滤空IP:', element.Name) |
|
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
console.log('过滤空IP设备:', element.Name) |
|
|
} |
|
|
} |
|
|
}) |
|
|
}) |
|
|
this.allDeviceIds = Array.from(ipSet) |
|
|
this.allDeviceIds = Array.from(ipSet) |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* 获取下一个轮询IP(循环切换) |
|
|
|
|
|
|
|
|
* 获取所有设备的实时环境数据 |
|
|
*/ |
|
|
*/ |
|
|
getNextIp() { |
|
|
|
|
|
if (this.allDeviceIds.length === 0) return '' |
|
|
|
|
|
// 先重置索引(防止数组长度变化导致越界) |
|
|
|
|
|
this.currentIpIndex = this.currentIpIndex % this.allDeviceIds.length |
|
|
|
|
|
const ip = this.allDeviceIds[this.currentIpIndex] |
|
|
|
|
|
this.currentIpIndex = (this.currentIpIndex + 1) % this.allDeviceIds.length |
|
|
|
|
|
console.log(`轮询切换 - 当前IP:${ip},下一个索引:${this.currentIpIndex}`) |
|
|
|
|
|
return ip |
|
|
|
|
|
|
|
|
async getAllDevicesData() { |
|
|
|
|
|
const allData = [] |
|
|
|
|
|
for (const ip of this.allDeviceIds) { |
|
|
|
|
|
try { |
|
|
|
|
|
console.log(`请求IP【${ip}】的环境数据`) |
|
|
|
|
|
// 真实接口请求 |
|
|
|
|
|
const data = await alarmApi.FetchDataForIP({ ip }) |
|
|
|
|
|
// const data = await mockFetchDataForIP({ ip }) |
|
|
|
|
|
|
|
|
|
|
|
// 过滤需要的指标并统一CO2名称 |
|
|
|
|
|
const filteredData = data.filter(item => |
|
|
|
|
|
this.keepIndicators.includes(item.subName) |
|
|
|
|
|
).map(item => { |
|
|
|
|
|
// 统一CO2浓度名称 |
|
|
|
|
|
if (item.subName === 'CO2浓度') { |
|
|
|
|
|
return { ...item, subName: '二氧化碳' } |
|
|
|
|
|
} |
|
|
|
|
|
return item |
|
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
if (filteredData.length > 0) { |
|
|
|
|
|
allData.push(...filteredData) |
|
|
|
|
|
} |
|
|
|
|
|
} catch (error) { |
|
|
|
|
|
console.error(`获取IP【${ip}】数据失败:`, error) |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
this.newAlarm = allData |
|
|
|
|
|
this.hasValidData = allData.length > 0 |
|
|
|
|
|
console.log('所有设备环境数据汇总:', allData) |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* 请求指定IP的实时数据(过滤+AQI计算) |
|
|
|
|
|
|
|
|
* 计算所有设备指标的平均值(包含单位处理) |
|
|
*/ |
|
|
*/ |
|
|
async getRealTimeData(targetIp) { |
|
|
|
|
|
if (!targetIp) { |
|
|
|
|
|
this.newAlarm = [] |
|
|
|
|
|
this.currentDeviceName = '' |
|
|
|
|
|
return |
|
|
|
|
|
|
|
|
calcAllAvgData() { |
|
|
|
|
|
if (!this.hasValidData) return |
|
|
|
|
|
|
|
|
|
|
|
const sumMap = { |
|
|
|
|
|
temperature: { sum: 0, count: 0, unit: '' }, // 温度 |
|
|
|
|
|
humidity: { sum: 0, count: 0, unit: '' }, // 湿度 |
|
|
|
|
|
pm25: { sum: 0, count: 0, unit: '' }, // PM2.5 |
|
|
|
|
|
tvoc: { sum: 0, count: 0, unit: '' }, // TVOC |
|
|
|
|
|
pm10: { sum: 0, count: 0, unit: '' }, // PM10 |
|
|
|
|
|
co2: { sum: 0, count: 0, unit: '' }, // 二氧化碳 |
|
|
|
|
|
formaldehyde: { sum: 0, count: 0, unit: '' }, // 甲醛 |
|
|
|
|
|
infrared: [], // 红外状态 |
|
|
|
|
|
fire: [], // 消防状态 |
|
|
|
|
|
waterLeak: [] // 漏水状态 |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
try { |
|
|
|
|
|
console.log(`开始请求IP【${targetIp}】的实时数据(模拟)`) |
|
|
|
|
|
// 模拟 |
|
|
|
|
|
// const data = await mockFetchDataForIP({ ip: targetIp }) |
|
|
|
|
|
// 真实请求 |
|
|
|
|
|
const data = await alarmApi.FetchDataForIP({ ip: targetIp }) |
|
|
|
|
|
|
|
|
|
|
|
// 过滤需要的指标 |
|
|
|
|
|
const filteredData = data.filter(item => |
|
|
|
|
|
this.keepIndicators.includes(item.subName) |
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
if (filteredData.length > 0) { |
|
|
|
|
|
this.newAlarm = filteredData |
|
|
|
|
|
console.log(`IP【${targetIp}】(${this.currentDeviceName}) 过滤后的数据:`, filteredData) |
|
|
|
|
|
} else { |
|
|
|
|
|
this.newAlarm = [] |
|
|
|
|
|
this.aqiValue = 45 |
|
|
|
|
|
this.aqiStatus = '健康' |
|
|
|
|
|
console.log(`IP【${targetIp}】(${this.currentDeviceName}) 无需要的指标数据`) |
|
|
|
|
|
|
|
|
// 遍历所有数据累加 |
|
|
|
|
|
this.newAlarm.forEach(item => { |
|
|
|
|
|
const value = parseFloat(item.value) || 0 |
|
|
|
|
|
// 提取单位(优先使用数据中的dw字段) |
|
|
|
|
|
const unit = item.dw || this.getDefaultUnit(item.subName) |
|
|
|
|
|
|
|
|
|
|
|
switch (item.subName) { |
|
|
|
|
|
case '温度': |
|
|
|
|
|
sumMap.temperature.sum += value |
|
|
|
|
|
sumMap.temperature.count++ |
|
|
|
|
|
if (!sumMap.temperature.unit && unit) sumMap.temperature.unit = unit |
|
|
|
|
|
break |
|
|
|
|
|
case '湿度': |
|
|
|
|
|
sumMap.humidity.sum += value |
|
|
|
|
|
sumMap.humidity.count++ |
|
|
|
|
|
if (!sumMap.humidity.unit && unit) sumMap.humidity.unit = unit |
|
|
|
|
|
break |
|
|
|
|
|
case '二氧化碳': |
|
|
|
|
|
sumMap.co2.sum += value |
|
|
|
|
|
sumMap.co2.count++ |
|
|
|
|
|
if (!sumMap.co2.unit && unit) sumMap.co2.unit = unit |
|
|
|
|
|
break |
|
|
|
|
|
case 'PM2.5浓度': |
|
|
|
|
|
sumMap.pm25.sum += value |
|
|
|
|
|
sumMap.pm25.count++ |
|
|
|
|
|
if (!sumMap.pm25.unit && unit) sumMap.pm25.unit = unit |
|
|
|
|
|
break |
|
|
|
|
|
case 'TVOC': |
|
|
|
|
|
sumMap.tvoc.sum += value |
|
|
|
|
|
sumMap.tvoc.count++ |
|
|
|
|
|
if (!sumMap.tvoc.unit && unit) sumMap.tvoc.unit = unit |
|
|
|
|
|
break |
|
|
|
|
|
case 'PM10浓度': |
|
|
|
|
|
sumMap.pm10.sum += value |
|
|
|
|
|
sumMap.pm10.count++ |
|
|
|
|
|
if (!sumMap.pm10.unit && unit) sumMap.pm10.unit = unit |
|
|
|
|
|
break |
|
|
|
|
|
case '甲醛': |
|
|
|
|
|
sumMap.formaldehyde.sum += value |
|
|
|
|
|
sumMap.formaldehyde.count++ |
|
|
|
|
|
if (!sumMap.formaldehyde.unit && unit) sumMap.formaldehyde.unit = unit |
|
|
|
|
|
break |
|
|
|
|
|
// 告警类指标 |
|
|
|
|
|
case '红外': |
|
|
|
|
|
sumMap.infrared.push(item.value) |
|
|
|
|
|
break |
|
|
|
|
|
case '消防': |
|
|
|
|
|
sumMap.fire.push(item.value) |
|
|
|
|
|
break |
|
|
|
|
|
case '漏水': |
|
|
|
|
|
sumMap.waterLeak.push(item.value) |
|
|
|
|
|
break |
|
|
} |
|
|
} |
|
|
} catch (error) { |
|
|
|
|
|
this.newAlarm = [] |
|
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
// 计算平均值(保留两位小数) |
|
|
|
|
|
this.avgData = { |
|
|
|
|
|
temperature: sumMap.temperature.count ? (sumMap.temperature.sum / sumMap.temperature.count).toFixed(2) : '0.00', |
|
|
|
|
|
temperatureUnit: sumMap.temperature.unit || '℃', |
|
|
|
|
|
humidity: sumMap.humidity.count ? (sumMap.humidity.sum / sumMap.humidity.count).toFixed(2) : '0.00', |
|
|
|
|
|
humidityUnit: sumMap.humidity.unit || '%', |
|
|
|
|
|
pm25: sumMap.pm25.count ? (sumMap.pm25.sum / sumMap.pm25.count).toFixed(2) : '0.00', |
|
|
|
|
|
pm25Unit: sumMap.pm25.unit || 'ug/立方米', |
|
|
|
|
|
tvoc: sumMap.tvoc.count ? (sumMap.tvoc.sum / sumMap.tvoc.count).toFixed(2) : '0.00', |
|
|
|
|
|
tvocUnit: sumMap.tvoc.unit || 'LuK', |
|
|
|
|
|
pm10: sumMap.pm10.count ? (sumMap.pm10.sum / sumMap.pm10.count).toFixed(2) : '0.00', |
|
|
|
|
|
pm10Unit: sumMap.pm10.unit || 'ug/立方米', |
|
|
|
|
|
co2: sumMap.co2.count ? (sumMap.co2.sum / sumMap.co2.count).toFixed(2) : '0.00', |
|
|
|
|
|
co2Unit: sumMap.co2.unit || 'ppm', |
|
|
|
|
|
formaldehyde: sumMap.formaldehyde.count ? (sumMap.formaldehyde.sum / sumMap.formaldehyde.count).toFixed(2) : '0.00', |
|
|
|
|
|
formaldehydeUnit: sumMap.formaldehyde.unit || 'ppm' |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 处理告警状态(只要有一个ON就显示告警) |
|
|
|
|
|
this.alarmStatus = { |
|
|
|
|
|
infrared: sumMap.infrared.some(s => s === 'ON') ? '告警' : '正常', |
|
|
|
|
|
fire: sumMap.fire.some(s => s === 'ON') ? '告警' : '正常', |
|
|
|
|
|
waterLeak: sumMap.waterLeak.some(s => s === 'ON') ? '告警' : '正常' |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 兼容无数据的情况 |
|
|
|
|
|
if (sumMap.infrared.length === 0) this.alarmStatus.infrared = '正常' |
|
|
|
|
|
if (sumMap.fire.length === 0) this.alarmStatus.fire = '正常' |
|
|
|
|
|
if (sumMap.waterLeak.length === 0) this.alarmStatus.waterLeak = '正常' |
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 获取指标默认单位(兜底用) |
|
|
|
|
|
*/ |
|
|
|
|
|
getDefaultUnit(subName) { |
|
|
|
|
|
const unitMap = { |
|
|
|
|
|
'温度': '℃', |
|
|
|
|
|
'湿度': '%', |
|
|
|
|
|
'PM2.5浓度': 'ug/立方米', |
|
|
|
|
|
'TVOC': 'LuK', |
|
|
|
|
|
'PM10浓度': 'ug/立方米', |
|
|
|
|
|
'二氧化碳': 'ppm', |
|
|
|
|
|
'CO2浓度': 'ppm', |
|
|
|
|
|
'甲醛': 'ppm', |
|
|
|
|
|
'综合气体': '无量纲' |
|
|
|
|
|
} |
|
|
|
|
|
return unitMap[subName] || '' |
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 根据所有设备的平均值计算AQI(空气质量指数) |
|
|
|
|
|
*/ |
|
|
|
|
|
calcAQIByAvg() { |
|
|
|
|
|
if (!this.hasValidData) { |
|
|
this.aqiValue = 45 |
|
|
this.aqiValue = 45 |
|
|
this.aqiStatus = '健康' |
|
|
|
|
|
this.currentDeviceName = '' |
|
|
|
|
|
console.error(`IP【${targetIp}】数据请求失败:`, error) |
|
|
|
|
|
|
|
|
this.aqiStatus = '优' |
|
|
|
|
|
return |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 提取PM2.5、PM10数值(转数字,兜底0) |
|
|
|
|
|
const pm25 = parseFloat(this.avgData.pm25) || 0 |
|
|
|
|
|
const pm10 = parseFloat(this.avgData.pm10) || 0 |
|
|
|
|
|
|
|
|
|
|
|
// 国标AQI浓度限值区间(24小时平均,μg/m³) |
|
|
|
|
|
const aqiBpTable = { |
|
|
|
|
|
pm25: [ |
|
|
|
|
|
{ iaqiLo: 0, iaqiHi: 50, bpLo: 0, bpHi: 35 }, // 优 |
|
|
|
|
|
{ iaqiLo: 50, iaqiHi: 100, bpLo: 35, bpHi: 75 }, // 良 |
|
|
|
|
|
{ iaqiLo: 100, iaqiHi: 150, bpLo: 75, bpHi: 115 }, // 轻度污染 |
|
|
|
|
|
{ iaqiLo: 150, iaqiHi: 200, bpLo: 115, bpHi: 150 }, // 中度污染 |
|
|
|
|
|
{ iaqiLo: 200, iaqiHi: 300, bpLo: 150, bpHi: 250 }, // 重度污染 |
|
|
|
|
|
{ iaqiLo: 300, iaqiHi: 500, bpLo: 250, bpHi: 500 } // 严重污染 |
|
|
|
|
|
], |
|
|
|
|
|
pm10: [ |
|
|
|
|
|
{ iaqiLo: 0, iaqiHi: 50, bpLo: 0, bpHi: 50 }, // 优 |
|
|
|
|
|
{ iaqiLo: 50, iaqiHi: 100, bpLo: 50, bpHi: 150 }, // 良 |
|
|
|
|
|
{ iaqiLo: 100, iaqiHi: 150, bpLo: 150, bpHi: 250 }, // 轻度污染 |
|
|
|
|
|
{ iaqiLo: 150, iaqiHi: 200, bpLo: 250, bpHi: 350 }, // 中度污染 |
|
|
|
|
|
{ iaqiLo: 200, iaqiHi: 300, bpLo: 350, bpHi: 420 }, // 重度污染 |
|
|
|
|
|
{ iaqiLo: 300, iaqiHi: 500, bpLo: 420, bpHi: 500 } // 严重污染 |
|
|
|
|
|
] |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 计算单污染物分指数(IAQI) |
|
|
|
|
|
const calculateIAQI = (conc, pollutantType) => { |
|
|
|
|
|
const bpTable = aqiBpTable[pollutantType] |
|
|
|
|
|
// 浓度超过上限,直接返回500 |
|
|
|
|
|
if (conc > bpTable[bpTable.length - 1].bpHi) { |
|
|
|
|
|
return 500 |
|
|
|
|
|
} |
|
|
|
|
|
// 匹配浓度所在区间 |
|
|
|
|
|
const matchedBp = bpTable.find(item => conc >= item.bpLo && conc <= item.bpHi) || bpTable[0] |
|
|
|
|
|
// 国标IAQI计算公式 |
|
|
|
|
|
const iaqi = ((matchedBp.iaqiHi - matchedBp.iaqiLo) / (matchedBp.bpHi - matchedBp.bpLo)) * (conc - matchedBp.bpLo) + matchedBp.iaqiLo |
|
|
|
|
|
// 四舍五入,且不超过500 |
|
|
|
|
|
return Math.min(Math.round(iaqi), 500) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 计算PM2.5、PM10的分指数 |
|
|
|
|
|
const iaqiPm25 = calculateIAQI(pm25, 'pm25') |
|
|
|
|
|
const iaqiPm10 = calculateIAQI(pm10, 'pm10') |
|
|
|
|
|
|
|
|
|
|
|
// AQI取分指数最大值 |
|
|
|
|
|
const finalAQI = Math.max(iaqiPm25, iaqiPm10) |
|
|
|
|
|
this.aqiValue = finalAQI |
|
|
|
|
|
|
|
|
|
|
|
// 匹配AQI对应的空气质量等级 |
|
|
|
|
|
const matchedGrade = this.aqiGradeStandard.find(grade => |
|
|
|
|
|
finalAQI >= grade.aqiMin && finalAQI <= grade.aqiMax |
|
|
|
|
|
) |
|
|
|
|
|
this.aqiStatus = matchedGrade ? matchedGrade.level : '严重污染' |
|
|
|
|
|
|
|
|
|
|
|
console.log('AQI计算结果:', { |
|
|
|
|
|
pm25, |
|
|
|
|
|
pm10, |
|
|
|
|
|
iaqiPm25, |
|
|
|
|
|
iaqiPm10, |
|
|
|
|
|
finalAQI, |
|
|
|
|
|
aqiStatus: this.aqiStatus |
|
|
|
|
|
}) |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
// 以下为原有方法,无修改 |
|
|
handleChange(index) { |
|
|
handleChange(index) { |
|
|
this.floorIndex = index |
|
|
this.floorIndex = index |
|
|
}, |
|
|
}, |
|
|
@ -460,9 +644,6 @@ export default { |
|
|
const carousel = this.$refs.carouselEnvRef |
|
|
const carousel = this.$refs.carouselEnvRef |
|
|
carousel.setActiveItem(index) |
|
|
carousel.setActiveItem(index) |
|
|
}, |
|
|
}, |
|
|
// handleSetLineChartData(type) { |
|
|
|
|
|
// this.lineChartData = lineChartData[type] |
|
|
|
|
|
// }, |
|
|
|
|
|
getWaitBorrower() { |
|
|
getWaitBorrower() { |
|
|
FetchWaitBorrower().then(data => { |
|
|
FetchWaitBorrower().then(data => { |
|
|
if (data) { |
|
|
if (data) { |
|
|
@ -488,10 +669,6 @@ export default { |
|
|
}, |
|
|
}, |
|
|
handleToWaiting(item) { |
|
|
handleToWaiting(item) { |
|
|
if (this.roles.includes('admin') || this.roles.includes('lendManage:list')) { |
|
|
if (this.roles.includes('admin') || this.roles.includes('lendManage:list')) { |
|
|
// 待借档案:到“待借档案” 0 |
|
|
|
|
|
// 借出确认:到“借出确认” 1 |
|
|
|
|
|
// 逾期警告:到“归还确认” 2 |
|
|
|
|
|
// 即将到期:到“归还确认” 3 |
|
|
|
|
|
let locationIndex = 0 |
|
|
let locationIndex = 0 |
|
|
if (item.title.includes('待借档案')) { |
|
|
if (item.title.includes('待借档案')) { |
|
|
locationIndex = 0 |
|
|
locationIndex = 0 |
|
|
@ -599,7 +776,6 @@ export default { |
|
|
.container-wrap { |
|
|
.container-wrap { |
|
|
min-height: auto; |
|
|
min-height: auto; |
|
|
height: 100%; |
|
|
height: 100%; |
|
|
// overflow: hidden; |
|
|
|
|
|
} |
|
|
} |
|
|
.todo-list { |
|
|
.todo-list { |
|
|
padding: 0 20px; |
|
|
padding: 0 20px; |
|
|
@ -631,7 +807,6 @@ export default { |
|
|
float: right; |
|
|
float: right; |
|
|
padding-right: 10px; |
|
|
padding-right: 10px; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
::v-deep |
|
|
::v-deep |
|
|
@ -697,27 +872,257 @@ export default { |
|
|
font-size: 12px; |
|
|
font-size: 12px; |
|
|
margin: 10px 10px 0 0; |
|
|
margin: 10px 10px 0 0; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 环境数据展示样式 |
|
|
|
|
|
.env-alarm-container { |
|
|
|
|
|
position: relative; |
|
|
|
|
|
width: 100%; |
|
|
|
|
|
padding: 0 10px; |
|
|
|
|
|
box-sizing: border-box; |
|
|
|
|
|
} |
|
|
|
|
|
// 温湿度列表样式(独占一屏) |
|
|
|
|
|
.env-humiture-container { |
|
|
|
|
|
height: 100%; |
|
|
|
|
|
display: flex; |
|
|
|
|
|
align-items: center; |
|
|
|
|
|
justify-content: center; |
|
|
|
|
|
} |
|
|
|
|
|
.env-humiture-list { |
|
|
|
|
|
width: 80% !important; |
|
|
|
|
|
justify-content: space-around !important; |
|
|
|
|
|
li { |
|
|
|
|
|
width: 45% !important; |
|
|
|
|
|
height: 66px !important; |
|
|
|
|
|
flex-direction: row !important; |
|
|
|
|
|
.msg-list-svg { |
|
|
|
|
|
font-size: 24px !important; |
|
|
|
|
|
margin-right: 10px !important; |
|
|
|
|
|
} |
|
|
|
|
|
div { |
|
|
|
|
|
span { |
|
|
|
|
|
font-size: 20px !important; |
|
|
|
|
|
font-weight: bold; |
|
|
|
|
|
margin-top: 0 !important; |
|
|
|
|
|
} |
|
|
|
|
|
p { |
|
|
|
|
|
font-size: 12px !important; |
|
|
|
|
|
color: #339CFF; |
|
|
|
|
|
margin-top: 4px; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
.env-alarm-list{ |
|
|
|
|
|
display: flex; |
|
|
|
|
|
justify-content: flex-start; |
|
|
|
|
|
width: 100%; |
|
|
|
|
|
padding: 0; |
|
|
|
|
|
margin: 0; |
|
|
|
|
|
list-style: none; |
|
|
|
|
|
li{ |
|
|
|
|
|
display: flex; |
|
|
|
|
|
flex-direction: column; |
|
|
|
|
|
align-items: center; |
|
|
|
|
|
align-content: center; |
|
|
|
|
|
justify-content: center; |
|
|
|
|
|
height: 70px; |
|
|
|
|
|
margin-right: 10px; |
|
|
|
|
|
background: url('~@/assets/images/data_border_default.png') no-repeat; |
|
|
|
|
|
background-size: 100% 100%; |
|
|
|
|
|
position: relative; |
|
|
|
|
|
color: #fff; |
|
|
|
|
|
font-size: 14px; |
|
|
|
|
|
&.li-warn{ |
|
|
|
|
|
background: url('~@/assets/images/data_border_warn.png') no-repeat; |
|
|
|
|
|
background-size: 100% 100%; |
|
|
|
|
|
} |
|
|
|
|
|
p{ |
|
|
|
|
|
color: #339CFF; |
|
|
|
|
|
margin: 0; |
|
|
|
|
|
} |
|
|
|
|
|
span{ |
|
|
|
|
|
display: block; |
|
|
|
|
|
margin-top: 12px; |
|
|
|
|
|
font-weight: bold; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
.env-alarm-list-second { |
|
|
|
|
|
flex-wrap: wrap !important; |
|
|
|
|
|
align-items: center; |
|
|
|
|
|
justify-content: center; |
|
|
|
|
|
li { |
|
|
|
|
|
width: calc(100% / 4 - 20px) !important; |
|
|
|
|
|
height: 40px !important; |
|
|
|
|
|
font-size: 10px !important; |
|
|
|
|
|
margin-bottom: 6px; |
|
|
|
|
|
p { |
|
|
|
|
|
font-size: 10px !important; |
|
|
|
|
|
} |
|
|
|
|
|
span { |
|
|
|
|
|
margin-top: 6px !important; |
|
|
|
|
|
font-size: 12px !important; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
// 轮播箭头样式优化(保留悬浮箭头) |
|
|
|
|
|
::v-deep .el-carousel__arrow { |
|
|
|
|
|
width: 24px; |
|
|
|
|
|
height: 24px; |
|
|
|
|
|
background-color: rgba(51, 156, 255, 0.3); |
|
|
|
|
|
&:hover { |
|
|
|
|
|
background-color: rgba(51, 156, 255, 0.6); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
.air-quality{ |
|
|
|
|
|
position: absolute; |
|
|
|
|
|
bottom: 0; |
|
|
|
|
|
right: 10px; |
|
|
|
|
|
color: #fff; |
|
|
|
|
|
padding: 10px; |
|
|
|
|
|
background-image: linear-gradient(to top, rgba(24, 176, 143, .5), rgba(24, 176, 143, 0)); |
|
|
|
|
|
border-radius: 5px; |
|
|
|
|
|
z-index: 9999; |
|
|
|
|
|
width: 200px; |
|
|
|
|
|
h3{ |
|
|
|
|
|
padding: 5px 0; |
|
|
|
|
|
font-size: 12px; |
|
|
|
|
|
margin: 0; |
|
|
|
|
|
text-align: center; |
|
|
|
|
|
} |
|
|
|
|
|
.air-params{ |
|
|
|
|
|
display: flex; |
|
|
|
|
|
justify-content: space-between; |
|
|
|
|
|
align-items: last baseline; |
|
|
|
|
|
flex-wrap: wrap; |
|
|
|
|
|
.air-left{ |
|
|
|
|
|
width: 100%; |
|
|
|
|
|
.air-title{ |
|
|
|
|
|
position: relative; |
|
|
|
|
|
padding-left: 8px; |
|
|
|
|
|
font-size: 10px; |
|
|
|
|
|
&::before{ |
|
|
|
|
|
content: ""; |
|
|
|
|
|
position: absolute; |
|
|
|
|
|
left: 0; |
|
|
|
|
|
top: 50%; |
|
|
|
|
|
width: 4px; |
|
|
|
|
|
height: 4px; |
|
|
|
|
|
background-color: #18B08F; |
|
|
|
|
|
border-radius: 50%; |
|
|
|
|
|
transform: translateY(-50%); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
.air-result{ |
|
|
|
|
|
display: flex; |
|
|
|
|
|
justify-content: flex-start; |
|
|
|
|
|
align-items: last baseline; |
|
|
|
|
|
padding-top: 5px; |
|
|
|
|
|
p{ |
|
|
|
|
|
font-size: 18px; |
|
|
|
|
|
font-weight: 600; |
|
|
|
|
|
padding: 0 4px 0 8px; |
|
|
|
|
|
margin: 0; |
|
|
|
|
|
} |
|
|
|
|
|
span{ |
|
|
|
|
|
display: block; |
|
|
|
|
|
font-size: 8px; |
|
|
|
|
|
opacity: .6; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
.air-right{ |
|
|
|
|
|
width: 100%; |
|
|
|
|
|
text-align: center; |
|
|
|
|
|
margin-top: 5px; |
|
|
|
|
|
span{ |
|
|
|
|
|
display: block; |
|
|
|
|
|
font-size: 10px; |
|
|
|
|
|
} |
|
|
|
|
|
p{ |
|
|
|
|
|
font-size: 12px; |
|
|
|
|
|
font-weight: 600; |
|
|
|
|
|
padding: 5px 10px; |
|
|
|
|
|
margin: 5px 0 0 0; |
|
|
|
|
|
background-color: rgba(24, 176, 143, .2); |
|
|
|
|
|
border-radius: 3px; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
&.air-excellent { |
|
|
|
|
|
background-image: linear-gradient(to top, rgba(40, 180, 40, .5), rgba(40, 180, 40, 0)); |
|
|
|
|
|
.air-params .air-right p { |
|
|
|
|
|
background-color: rgba(40, 180, 40, .2); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
&.air-good { |
|
|
|
|
|
background-image: linear-gradient(to top, rgba(255, 200, 0, .5), rgba(255, 200, 0, 0)); |
|
|
|
|
|
.air-params .air-right p { |
|
|
|
|
|
background-color: rgba(255, 200, 0, .2); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
&.air-lightPollution { |
|
|
|
|
|
background-image: linear-gradient(to top, rgba(255, 140, 0, .5), rgba(255, 140, 0, 0)); |
|
|
|
|
|
.air-params .air-right p { |
|
|
|
|
|
background-color: rgba(255, 140, 0, .2); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
&.air-mediumPollution { |
|
|
|
|
|
background-image: linear-gradient(to top, rgba(255, 0, 0, .5), rgba(255, 0, 0, 0)); |
|
|
|
|
|
.air-params .air-right p { |
|
|
|
|
|
background-color: rgba(255, 0, 0, .2); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
&.air-heavyPollution { |
|
|
|
|
|
background-image: linear-gradient(to top, rgba(150, 0, 200, .5), rgba(150, 0, 200, 0)); |
|
|
|
|
|
.air-params .air-right p { |
|
|
|
|
|
background-color: rgba(150, 0, 200, .2); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
&.air-severePollution { |
|
|
|
|
|
background-image: linear-gradient(to top, rgba(120, 0, 0, .5), rgba(120, 0, 0, 0)); |
|
|
|
|
|
.air-params .air-right p { |
|
|
|
|
|
background-color: rgba(120, 0, 0, .2); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
.empty-main { |
|
|
|
|
|
display: flex; |
|
|
|
|
|
flex-direction: column; |
|
|
|
|
|
align-items: center; |
|
|
|
|
|
justify-content: center; |
|
|
|
|
|
color: #fff; |
|
|
|
|
|
.empty-img { |
|
|
|
|
|
width: 40px; |
|
|
|
|
|
height: 40px; |
|
|
|
|
|
margin-bottom: 10px; |
|
|
|
|
|
} |
|
|
|
|
|
p { |
|
|
|
|
|
font-size: 12px; |
|
|
|
|
|
margin: 0; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
.leakage-list { |
|
|
.leakage-list { |
|
|
display: flex; |
|
|
display: flex; |
|
|
justify-content:flex-start; |
|
|
|
|
|
flex-wrap: wrap; |
|
|
|
|
|
|
|
|
justify-content: center; |
|
|
|
|
|
align-items: center; |
|
|
flex: 1; |
|
|
flex: 1; |
|
|
text-align: left; |
|
|
text-align: left; |
|
|
font-size: 10px; |
|
|
font-size: 10px; |
|
|
padding-left: 10px; |
|
|
|
|
|
li { |
|
|
li { |
|
|
position: relative; |
|
|
position: relative; |
|
|
display: flex; |
|
|
display: flex; |
|
|
justify-content: flex-start; |
|
|
justify-content: flex-start; |
|
|
flex-wrap: wrap; |
|
|
flex-wrap: wrap; |
|
|
align-items: center; |
|
|
align-items: center; |
|
|
width: 72px; |
|
|
|
|
|
|
|
|
width: 60px; |
|
|
height: 40px; |
|
|
height: 40px; |
|
|
border: 1px solid #3581cc; |
|
|
border: 1px solid #3581cc; |
|
|
background-color: #02255f; |
|
|
background-color: #02255f; |
|
|
border-radius: 2px; |
|
|
border-radius: 2px; |
|
|
padding: 4px; |
|
|
|
|
|
margin: 6px 10px 0 0; |
|
|
|
|
|
|
|
|
padding: 4px 6px; |
|
|
|
|
|
margin: 0 10px 10px 0; |
|
|
font-size: 12px; |
|
|
font-size: 12px; |
|
|
&::before { |
|
|
&::before { |
|
|
content: ""; |
|
|
content: ""; |
|
|
@ -751,13 +1156,4 @@ export default { |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
.five-bottom{ |
|
|
|
|
|
display: flex; |
|
|
|
|
|
justify-content: flex-start; |
|
|
|
|
|
align-items: center; |
|
|
|
|
|
.env-title{ |
|
|
|
|
|
line-height: 40px; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
</style> |
|
|
</style> |