123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643 |
- <template>
- <customHeader :options="options" @change="getSelectRow" :optionValue="optionValue"> 粉尘监测预警 </customHeader>
- <div class="dustWarn">
- <div class="top-dust">
- <a-button
- v-if="!hasPermission('dustWarn:return')"
- preIcon="ant-design:rollback-outlined"
- type="text"
- size="small"
- style="position: absolute; left: 15px; top: 15px; color: #fff"
- @click="getBack"
- >返回</a-button
- >
- <div class="alarm-menu">
- <div class="card-btn">
- <div :class="activeIndex1 == ind ? 'btn1' : 'btn'" v-for="(item, ind) in menuList" :key="ind" @click="cardClick(ind, item)">
- <div class="text">{{ item.name }}</div>
- <div class="warn">{{ item.warn }}</div>
- </div>
- </div>
- </div>
- <div class="dust-content">
- <div class="content-left">
- <div
- :class="activeIndex == index ? 'content-left-item' : 'content-left-item1'"
- v-for="(item, index) in topAreaList"
- :key="index"
- @click="topAreaClick(index)"
- >
- <div class="content-title">{{ item.title }}</div>
- <div class="content-items" v-for="(ite, ind) in item.content" :key="ind">
- <span>{{ ite.label }}</span>
- <span style="color: var(--vent-table-action-link)">{{ ite.value }}</span>
- </div>
- </div>
- </div>
- <div class="content-right">
- <div class="title-t">
- <div class="text-t">粉尘信息状态监测</div>
- </div>
- <div class="echart-boxd">
- <echartLine :echartDataGq="echartDataFc" :maxY="maxY" :echartDw="echartDw" :gridV="gridV" />
- </div>
- </div>
- </div>
- </div>
- <div class="bot-dust">
- <div class="bot-area">
- <MeasurePoint title="粉尘监控测点信息" :cards="cardListTf" :charts="chartListTf" chartWidth="420px" />
- </div>
- </div>
- </div>
- </template>
- <script setup lang="ts">
- import { ref, reactive, onMounted, onUnmounted } from 'vue';
- import { sysTypeWarnList, sysWarn, getDevice } from '../common.api';
- import echartLine from '../common/echartLine.vue';
- import { useSystemSelect } from '/@/hooks/vent/useSystemSelect';
- import { useRouter } from 'vue-router';
- import CustomHeader from '/@/components/vent/customHeader.vue';
- import { usePermission } from '/@/hooks/web/usePermission';
- import MeasurePoint from '../common/measurePoint.vue';
- import moment from 'moment';
- const { hasPermission } = usePermission();
- const { options, optionValue, getSelectRow, getSysDataSource } = useSystemSelect('sys_surface_caimei'); // 参数为场景类型(设备类型管理中可以查询到)
- //左侧数据列表
- let menuList = ref<any[]>([]);
- //当前左侧激活菜单的索引
- let activeIndex1 = ref(0);
- //顶部区域激活选项
- let activeIndex = ref(0);
- //顶部区域数据
- let topAreaList = reactive<any[]>([]);
- let choiceData = reactive<any[]>([]);
- //粉尘图表数据
- let echartDataFc = reactive({
- maxData: {
- lengedData: '实时值(mg/m³)',
- data: [],
- },
- minData: {
- lengedData: '预测值(mg/m³)',
- data: [],
- },
- aveValue: {
- lengedData: '预警值(mg/m³)',
- data: [],
- },
- xData: [],
- });
- let maxY = ref<any>(0);
- let echartDw = ref('(mg/m³)');
- let gridV = reactive({
- top: '12%',
- left: '1%',
- bottom: '5%',
- right: '5%',
- containLabel: true,
- });
- const cardListTf = ref<any[]>([]);
- const chartListTf = ref<any[]>([]);
- let router = useRouter();
- let echartNow = ref<any[]>([]);
- let echartYc = reactive<any[]>([]);
- let flag = ref(true);
- // https获取监测数据
- let timer: null | NodeJS.Timeout = null;
- function getMonitor(deviceID, flag?) {
- timer = setTimeout(
- async () => {
- await getSysWarnList(deviceID, 'dust');
- await getWindDeviceList();
- if (timer) {
- timer = null;
- }
- getMonitor(deviceID);
- },
- flag ? 0 : 3000
- );
- }
- //返回首页
- function getBack() {
- router.push('/monitorChannel/monitor-alarm-home');
- }
- //菜单选项切换
- function cardClick(ind, item) {
- activeIndex1.value = ind;
- clearTimeout(timer);
- getMonitor(item.deviceID, true);
- }
- //顶部区域选项切换
- function topAreaClick(index) {
- activeIndex.value = index;
- echartDataFc.maxData.data.length = 0;
- echartDataFc.minData.data.length = 0;
- echartDataFc.aveValue.data.length = 0;
- echartDataFc.xData.length = 0;
- echartYc.length = 0;
- flag.value = true;
- if (flag.value) {
- echartNow.value = JSON.parse(choiceData[index].readData.expectInfo)['list'];
- flag.value = false;
- }
- echartYc.push({
- time: JSON.parse(choiceData[index].readData.expectInfo)['nowTime'],
- value: JSON.parse(choiceData[index].readData.expectInfo)['nowVal'],
- });
- let setData = [...echartNow.value, ...echartYc].sort((a, b) => Date.parse(new Date(a.time)) - Date.parse(new Date(b.time)));
- setData.forEach((el) => {
- if (el.value && el.value != '0') {
- echartDataFc.xData.push(el.time);
- echartDataFc.maxData.data.push(el.value);
- echartDataFc.minData.data.push(JSON.parse(choiceData[index].readData.expectInfo)['aveVal']);
- echartDataFc.aveValue.data.push(
- JSON.parse(choiceData[activeIndex.value].readData.expectInfo)['fmin']
- ? JSON.parse(choiceData[activeIndex.value].readData.expectInfo)['fmin']
- : 0
- );
- }
- });
- }
- //获取左侧菜单列表
- async function getMenuList() {
- let res = await sysTypeWarnList({ type: 'dust' });
- if (res.length != 0) {
- const menuListTemp: any[] = [];
- res.forEach((el) => {
- menuListTemp.push({
- name: el.systemname,
- warn: '低风险',
- deviceID: el.id,
- strtype: el.strtype,
- });
- });
- menuList.value = menuListTemp;
- getMonitor(menuList.value[0].deviceID, true);
- }
- }
- //获取预警详情弹窗右侧数据
- function getSysWarnList(id, type) {
- sysWarn({ sysid: id, type: type }).then((res) => {
- // listData.common = res;
- topAreaList.length = 0;
- if (JSON.stringify(res) != '{}') {
- res.dust.forEach((el) => {
- topAreaList.push({
- title: el.strinstallpos,
- content: [
- { ids: 0, label: '温度(°C)', value: el.readData.temperature || '--' },
- { ids: 1, label: '粉尘浓度(mg/m³)', value: el.readData.dustval || '--' },
- { ids: 2, label: '喷雾水压(MPa)', value: el.readData.waterPressure || '--' },
- { ids: 3, label: '喷雾状态', value: el.readData.atomizingState || '--' },
- ],
- });
- });
- choiceData = res.dust;
- if (choiceData[activeIndex.value]) {
- if (flag.value) {
- echartNow.value = JSON.parse(choiceData[activeIndex.value].readData.expectInfo)['list'];
- flag.value = false;
- }
- echartYc.push({
- time: JSON.parse(choiceData[activeIndex.value].readData.expectInfo)['nowTime'],
- value: JSON.parse(choiceData[activeIndex.value].readData.expectInfo)['nowVal'],
- });
- let setData = [...echartNow.value, ...echartYc].sort((a, b) => Date.parse(new Date(a.time)) - Date.parse(new Date(b.time)));
- echartDataFc.maxData.data.length = 0;
- echartDataFc.minData.data.length = 0;
- echartDataFc.aveValue.data.length = 0;
- echartDataFc.xData.length = 0;
- setData.forEach((el) => {
- if (el.value && el.value != '0') {
- echartDataFc.xData.push(el.time);
- echartDataFc.maxData.data.push(el.value);
- echartDataFc.minData.data.push(JSON.parse(choiceData[activeIndex.value].readData.expectInfo)['aveVal']);
- echartDataFc.aveValue.data.push(
- JSON.parse(choiceData[activeIndex.value].readData.expectInfo)['fmin']
- ? JSON.parse(choiceData[activeIndex.value].readData.expectInfo)['fmin']
- : 0
- );
- }
- });
- maxY.value = echartDataFc.maxData.data.reduce((acr, cur) => {
- return acr > cur ? acr : cur;
- });
- maxY.value =
- maxY.value.toString().indexOf('.') == -1 ? maxY.value.toString() : maxY.value.toString().substring(0, maxY.value.toString().indexOf('.'));
- if (maxY.value.length < 2 && Number(maxY.value) < 1) {
- maxY.value = 1;
- } else if (maxY.value.length < 2 && Number(maxY.value) >= 1) {
- maxY.value = 10;
- } else if (maxY.value.length < 3) {
- maxY.value = (Number(maxY.value[0]) + 1) * 10;
- } else if (maxY.value.length < 4) {
- maxY.value = (Number(maxY.value[0]) + 1) * 100;
- } else if (maxY.value.length < 5) {
- maxY.value = (Number(maxY.value[0]) + 1) * 1000;
- } else if (maxY.value.length < 6) {
- maxY.value = (Number(maxY.value[0]) + 1) * 10000;
- }
- } else {
- activeIndex.value = 0;
- if (flag.value) {
- echartNow.value = JSON.parse(choiceData[activeIndex.value].readData.expectInfo)['list'];
- flag.value = false;
- }
- echartYc.push({
- time: JSON.parse(choiceData[activeIndex.value].readData.expectInfo)['nowTime'],
- value: JSON.parse(choiceData[activeIndex.value].readData.expectInfo)['nowVal'],
- });
- let setData = [...echartNow.value, ...echartYc].sort((a, b) => Date.parse(new Date(a.time)) - Date.parse(new Date(b.time)));
- echartDataFc.maxData.data.length = 0;
- echartDataFc.minData.data.length = 0;
- echartDataFc.aveValue.data.length = 0;
- echartDataFc.xData.length = 0;
- setData.forEach((el) => {
- if (el.value && el.value != '0') {
- echartDataFc.xData.push(el.time);
- echartDataFc.maxData.data.push(el.value);
- echartDataFc.minData.data.push(JSON.parse(choiceData[activeIndex.value].readData.expectInfo)['aveVal']);
- echartDataFc.aveValue.data.push(
- JSON.parse(choiceData[activeIndex.value].readData.expectInfo)['fmin']
- ? JSON.parse(choiceData[activeIndex.value].readData.expectInfo)['fmin']
- : 0
- );
- }
- });
- maxY.value = echartDataFc.maxData.data.reduce((acr, cur) => {
- return acr > cur ? acr : cur;
- });
- maxY.value =
- maxY.value.toString().indexOf('.') == -1 ? maxY.value.toString() : maxY.value.toString().substring(0, maxY.value.toString().indexOf('.'));
- if (maxY.value.length < 2) {
- maxY.value = 10;
- } else if (maxY.value.length < 3) {
- maxY.value = (Number(maxY.value[0]) + 1) * 10;
- } else if (maxY.value.length < 4) {
- maxY.value = (Number(maxY.value[0]) + 1) * 100;
- } else if (maxY.value.length < 5) {
- maxY.value = (Number(maxY.value[0]) + 1) * 1000;
- } else if (maxY.value.length < 6) {
- maxY.value = (Number(maxY.value[0]) + 1) * 10000;
- }
- }
- }
- });
- }
- //获取粉尘监控测点信息
- async function getWindDeviceList() {
- // cardListTf.length = 0;
- const cardListTfTemp: any[] = [];
- const chartListTfTemp: any[] = [];
- let res = await getDevice({ devicetype: 'dusting', pagetype: 'normal' });
- if (res && res.msgTxt[0]) {
- let list = res.msgTxt[0].datalist || [];
- if (list.length > 0) {
- list.forEach((el: any) => {
- const readData = el.readData;
- el = Object.assign(el, readData);
- cardListTfTemp.push({
- label: '通信状态',
- value: el.netStatus == '0' ? '断开' : '连接',
- listR: [
- { id: 0, label: '安装位置', dw: '', value: el.strinstallpos || '-' },
- { id: 1, label: '粉尘浓度', dw: '(mg/m³)', value: el.dustval || '-' },
- {
- id: 2,
- label: '巷道湿度',
- dw: el.humidity && Number(el.humidity) < 1 ? '(RH)' : el.humidity && Number(el.humidity) > 1 ? '(%RH)' : '',
- value: el.humidity || '-',
- },
- { id: 4, label: '巷道温度', dw: el.humidity ? '(℃)' : '', value: el.temperature || '-' },
- {
- id: 3,
- label: '是否报警',
- dw: '',
- value: el.warnFlag == '0' ? '正常' : el.warnFlag == 1 ? '报警' : el.warnFlag == 2 ? '断开' : '未监测',
- },
- ],
- });
- // 初始化预测曲线配置,分别为x轴时间、平均、最大、最小、实时
- const avgParam = el.avgParam || {
- avg_dusting_value: 0,
- max_dusting_value: 0,
- min_dusting_value: 0,
- };
- chartListTfTemp.push({
- label: el.strinstallpos,
- time: new Date(),
- data: [avgParam.avg_dusting_value, avgParam.max_dusting_value, avgParam.min_dusting_value, el.readData.dustval],
- });
- });
- }
- }
- cardListTf.value = cardListTfTemp;
- chartListTf.value = chartListTfTemp;
- }
- onMounted(() => {
- getMenuList();
- // getWindDeviceList();
- });
- onUnmounted(() => {
- if (timer) {
- clearTimeout(timer);
- timer = undefined;
- }
- });
- </script>
- <style lang="less" scoped>
- @import '/@/design/theme.less';
- @{theme-deepblue} {
- .dustWarn {
- --image-border: url('/@/assets/images/themify/deepblue/fire/border.png');
- --image-no-choice: url('/@/assets/images/themify/deepblue/fire/no-choice.png');
- --image-choice: url('/@/assets/images/themify/deepblue/fire/choice.png');
- --image-dust-choice: url('/@/assets/images/themify/deepblue/fire/dust-choice.png');
- --image-dust-content: url('/@/assets/images/themify/deepblue/fire/dust-content.png');
- --image-dust-choice1: url('/@/assets/images/themify/deepblue/fire/dust-choice1.png');
- --image-dust-content: url('/@/assets/images/themify/deepblue/fire/dust-content.png');
- --image-bj1: url('/@/assets/images/themify/deepblue/fire/bj1.png');
- }
- }
- .dustWarn {
- --image-border: url('/@/assets/images/fire/border.png');
- --image-no-choice: url('/@/assets/images/fire/no-choice.png');
- --image-choice: url('/@/assets/images/fire/choice.png');
- --image-dust-choice: url('/@/assets/images/fire/dust-choice.png');
- --image-dust-content: url('/@/assets/images/fire/dust-content.png');
- --image-dust-choice1: url('/@/assets/images/fire/dust-choice1.png');
- --image-dust-content: url('/@/assets/images/fire/dust-content.png');
- --image-bj1: url('/@/assets/images/fire/bj1.png');
- width: 100%;
- height: 100%;
- padding: 80px 10px 15px 10px;
- box-sizing: border-box;
- .top-dust {
- display: flex;
- justify-content: space-between;
- height: 50%;
- margin-bottom: 15px;
- background: var(--image-border) no-repeat center;
- background-size: 100% 100%;
- .alarm-menu {
- height: 100%;
- width: 15%;
- padding: 10px;
- box-sizing: border-box;
- .card-btn {
- width: 100%;
- height: 100%;
- overflow-y: auto;
- .btn {
- position: relative;
- width: 81%;
- height: 24%;
- margin-bottom: 6%;
- font-family: 'douyuFont';
- background: var(--image-no-choice) no-repeat;
- background-size: 100% 100%;
- cursor: pointer;
- .text {
- width: 80%;
- position: absolute;
- left: 50%;
- top: 28px;
- font-size: 14px;
- color: var(--vent-table-action-link);
- text-align: center;
- transform: translate(-50%, 0);
- }
- .warn {
- width: 100%;
- position: absolute;
- left: 50%;
- bottom: 11px;
- font-size: 12px;
- color: #fff;
- text-align: center;
- transform: translate(-50%, 0);
- }
- }
- .btn1 {
- position: relative;
- width: 100%;
- height: 24%;
- margin-bottom: 6%;
- font-family: 'douyuFont';
- background: var(--image-choice) no-repeat;
- background-size: 100% 100%;
- cursor: pointer;
- .text {
- width: 80%;
- position: absolute;
- left: 50%;
- top: 28px;
- font-size: 14px;
- color: var(--vent-table-action-link);
- text-align: center;
- transform: translate(-62%, 0);
- }
- .warn {
- width: 100%;
- position: absolute;
- left: 50%;
- bottom: 11px;
- font-size: 14px;
- color: #fff;
- text-align: center;
- transform: translate(-60%, 0);
- }
- }
- }
- }
- .dust-content {
- display: flex;
- justify-content: space-between;
- height: 100%;
- width: 85%;
- padding: 10px 0px;
- box-sizing: border-box;
- .content-left {
- width: 280px;
- height: 100%;
- display: flex;
- flex-direction: column;
- // justify-content: space-around;
- align-items: flex-start;
- overflow-y: auto;
- overflow-x: hidden;
- .content-left-item {
- position: relative;
- width: 272px;
- height: 173px;
- flex-shrink: 0;
- background: var(--image-dust-choice) no-repeat center;
- background-size: 100% 100%;
- margin: 5px 0px;
- .content-title {
- width: 85%;
- position: absolute;
- top: 2px;
- left: 50%;
- transform: translate(-55%, 0);
- font-size: 14px;
- color: #fff;
- text-align: center;
- }
- .content-items {
- position: absolute;
- left: 50%;
- transform: translate(-54%, 0);
- display: flex;
- justify-content: space-between;
- align-items: center;
- width: 240px;
- height: 26px;
- color: #fff;
- font-size: 14px;
- padding: 0px 5px;
- box-sizing: border-box;
- background: var(--image-dust-content) no-repeat center;
- background-size: 100% 100%;
- &:nth-child(2) {
- top: 32px;
- }
- &:nth-child(3) {
- top: 67px;
- }
- &:nth-child(4) {
- top: 102px;
- }
- &:nth-child(5) {
- top: 136px;
- }
- }
- }
- .content-left-item1 {
- position: relative;
- width: 250px;
- height: 173px;
- flex-shrink: 0;
- background: var(--image-dust-choice1) no-repeat center;
- background-size: 100% 100%;
- margin: 5px 0px;
- .content-title {
- width: 85%;
- position: absolute;
- top: 2px;
- left: 50%;
- transform: translate(-50%, 0);
- font-size: 14px;
- color: #fff;
- text-align: center;
- }
- .content-items {
- position: absolute;
- left: 50%;
- transform: translate(-54%, 0);
- display: flex;
- justify-content: space-between;
- align-items: center;
- width: 215px;
- height: 26px;
- color: #fff;
- font-size: 14px;
- padding: 0px 5px;
- box-sizing: border-box;
- background: var(--image-dust-content) no-repeat center;
- background-size: 100% 100%;
- &:nth-child(2) {
- top: 32px;
- }
- &:nth-child(3) {
- top: 67px;
- }
- &:nth-child(4) {
- top: 102px;
- }
- &:nth-child(5) {
- top: 136px;
- }
- }
- }
- }
- .content-right {
- width: calc(100% - 280px);
- height: 100%;
- .title-t {
- height: 30px;
- margin-bottom: 10px;
- display: flex;
- justify-content: space-between;
- align-items: center;
- .text-t {
- font-family: 'douyuFont';
- font-size: 14px;
- color: #fff;
- }
- }
- .echart-boxd {
- width: 100%;
- height: calc(100% - 40px);
- }
- }
- }
- }
- .bot-dust {
- height: calc(50% - 15px);
- background: var(--image-border) no-repeat center;
- background-size: 100% 100%;
- padding: 10px;
- box-sizing: border-box;
- .bot-area {
- height: 100%;
- padding: 10px;
- background: var(--image-bj1) no-repeat center;
- background-size: 100% 100%;
- box-sizing: border-box;
- }
- }
- }
- </style>
|