<template> <!-- 在线监控 --> <div class="scada-monitor" style="padding: 0"> <tf-legend class="legend_dept" label="条件搜索" isopen="true" title="描述站位。"> <el-row> <div class="innerType"> <el-select v-model="type" size="small" clearable placeholder="请选择设备类型" style="float: left; width: 46%; margin-right: 4%;" > <el-option key="1" label="水厂" value="1" /> <el-option key="2" label="管网" value="2" /> <!-- <el-option key="3" label="泵站" value="3" /> <el-option key="4" label="泵组" value="4" /> <el-option key="5" label="污水厂" value="5" /> --> </el-select> <el-select v-model="deviceType" size="small" clearable multiple collapse-tags placeholder="请选择设备类型" style="float: left;margin-right: 4%; width: 50%;" > <el-option v-for="item in deviceTypes" :key="item.ccode" :label="item.cname" :value="item.ccode" /> </el-select> </div> <el-input v-model="querySiteName" class="helpInput" style="float: left; width: calc(100% - 46px); margin: 6px 0" clearable size="small" placeholder="请输入设备名称" > <template slot-scope="{ item }"> <i class="el-icon-location" /> <span class="name">{{ item.value }}</span> </template> </el-input> <el-button style=" float: left; height: 32px; margin-top: 6px; border-radius: 0px 4px 4px 0px; " type="primary" icon="el-icon-search" size="small" plain @click="querySite" /> </el-row> </tf-legend> <tf-legend class="legend_dept" label="监测列表" isopen="true" title="描述站位。" style="height: calc(100% - 124px); padding: 0" :can-change="false" > <div style="position: absolute;top: -28px;right: 20px;" class='warning'> <el-switch v-model="warning" active-text="关闭报警" inactive-text="开启报警"></el-switch> <video autoplay='autoplay' loop='loop' v-if='existWarnig&&warning' ref="videoMsg" :src="mp3" style="display: none" /> </div> <el-table v-loading="tableLoading" height="calc(100% - 26px)" :data="siteDataTable" stripe style="width: 100%"> <el-table-column prop="site" label="设备名称" align="center" show-overflow-tooltip /> <el-table-column fixed="right" label="操作" width="120" align="center"> <template slot-scope="scope"> <el-button type="text" size="small" @click="goto(scope.row)">查看</el-button> <el-button type="text" size="small" @click="getSiteHistroty(scope.row)">趋势图</el-button> <el-button v-if="scope.row.isCraft" type="text" size="small" @click="watchCraft(scope.row)">工艺图</el-button> </template> </el-table-column> </el-table> <div style="margin-top: 8px"> <div style="float: left; width: 80%"> <el-pagination ref="pagination" background layout="total, sizes, prev, next" :total="total" :page-sizes="[20, 30, 50, 80, 160]" @current-change="listRefersh(resData)" @size-change="listRefersh(resData)" /> </div> <div style="float: left; width: 20%" class="el-pagination is-background"> <span ref="pageLength" style="font-size: 13px" class="el-pagination__total">1/1 页</span> </div> <div style="clear: both" /> </div> </tf-legend> <el-dialog title="工艺图" :visible.sync="craftVisible" top="50px" @close="craftClose"> <div ref="craft" /> </el-dialog> <ScadaMapCom ref="scadaMapComAll" :map-view="mapView" :site-data="siteData" :isscadashow="true" :ismapok="false" maplayer-name="scadaAll" /> </div> </template> <script> import tfLegend from '@/views/zhpt/common/Legend' import TableItem from '@/components/Table' import request from '@/utils/request' import mp3 from '@/assets/images/home/msg.mp3'; import { getScadaMonitor, getScadaListAll, queryMonitorHistory } from '@/api/SCADAInfoApi' import Echarts from 'echarts' import { TF_craft } from './createSiteCraft' import { craftConfig, deviceConfig, deviceStateConfig } from './craftConfig' import { getSysCommonCode } from '@/api/dataCenter' import ScadaMapCom from '@/views/zhpt/scada/scadaMonitorAll/components/scadaMapCom' import MonitorCurve from './components/monitorcurve' export default { name: 'ScadaMonitor', components: { TableItem, tfLegend, Echarts, MonitorCurve, ScadaMapCom }, props: { data: Object }, data() { return { // 输入框 querySiteName: '', tableLoading: false, // 列表 siteDataTable: [], total: 0, warning:true,//报警开关 mp3:mp3, existWarnig:false,//是否存在报警 // 工艺图 craftVisible: false, // 测站历史 historyLoading: false, siteVisible: false, siteTitle: '', siteType: '', sites: [], timss: [], siteHistoryDataTable: [], total2: 0, dontShow: true, resData: [], deviceTypes: [], type: '', // 1=水厂,2=管网 // deviceType: ['1', '2', '3'], // 默认展示流量计 压力计 水厂 deviceType: [], // 默认展示流量计 压力计 水厂 mapView: {}, // 地图 siteData: [], // 时间监控站点 queryTimeOut:null, // tip 弹窗 layer: undefined, hitlayer: undefined, divs: [], mapClick: undefined } }, computed: { sidePanelOn() { return this.$store.state.map.P_editableTabsValue } }, watch: { sidePanelOn(newTab, oldTab) { if (newTab == oldTab) return if (newTab == 'scadaMonitorAll') { this.$nextTick(() => { // if(this.layer){ // this.layer.visible = true // } const scadalayer = this.data.mapView.map.findLayerById('scadaAll') const scadahitlayer = this.data.mapView.map.findLayerById('scadaAllhit') if (scadalayer !== null && scadalayer !== undefined) { scadalayer.visible = true } if (scadahitlayer !== null && scadahitlayer !== undefined) { scadahitlayer.visible = true } if(this.$refs.scadaMapComAll&&this.$refs.scadaMapComAll.divs){ for (var i = 0, il =this.$refs.scadaMapComAll.divs, ii = il.length; i < ii; i++) { il[i].div.style.display = '' } } this.addWatch&&this.addWatch() if (this.ids&&this.ids.length > 0) this.loadRealTimeSiteValue() }) } if (oldTab == 'scadaMonitorAll') { const scadalayer = this.data.mapView.map.findLayerById('scadaAll') const scadahitlayer = this.data.mapView.map.findLayerById('scadaAllhit') if (scadalayer !== null && scadalayer !== undefined) { scadalayer.visible = false } if (scadahitlayer !== null && scadahitlayer !== undefined) { scadahitlayer.visible = false } if(this.$refs.scadaMapComAll&&this.$refs.scadaMapComAll.divs){ for (var i = 0, il = this.$refs.scadaMapComAll.divs, ii = il.length; i < ii; i++) { il[i].div.style.display = 'none' } } if (this.watch) { this.watch.remove() this.watch = undefined } if (this.timeOut) window.clearTimeout(this.timeOut) } } }, created() { getSysCommonCode({ pCid: '53400' }).then((res) => { this.deviceTypes = res.result[0].codeList // 剔除噪音监测仪 this.deviceTypes.splice(this.deviceTypes.findIndex(item => item.ccode === '4'), 1) }) }, mounted() { var view = (this.mapView = this.data.mapView) this.floatDiv = view.TF_floatPanel const scadalayer = view.map.findLayerById('scadaAll') const scadahitlayer = view.map.findLayerById('scadaAllhit') if (scadalayer !== null && scadalayer !== undefined) { scadalayer.visible = false } if (scadahitlayer !== null && scadahitlayer !== undefined) { scadahitlayer.visible = false } this.querySite() }, destroyed() { this.siteData = [] if (this.queryTimeOut) window.clearTimeout(this.queryTimeOut) // this.clearSiteDiv(); var view = this.mapView const scadalayer = view.map.findLayerById('scadaAll') const scadahitlayer = view.map.findLayerById('scadaAllhit') if (scadalayer !== null && scadalayer !== undefined) { scadalayer.visible = true } if (scadahitlayer !== null && scadahitlayer !== undefined) { scadahitlayer.visible = true } // // view.map.remove(this.hitlayer); }, methods: { querySite() { const that = this var pages = that.$refs.pagination const data = { name: that.querySiteName } that.tableLoading = true if (that.type != '') { Object.assign(data, { type: that.type }) } if (that.deviceType != '') { // Object.assign(data, { deviceType: that.deviceType }); //单个 Object.assign(data, { deviceTypeIds: that.deviceType.join(',') }) // 单个 } var modulesFiles = require.context('./images', true, /\.png$/) getScadaMonitor(data).then((res) => { that.siteData = [] pages.internalCurrentPage = 1 if (res.code == 1) { // res = res.result.filter((item) => { // return item.allocations; // }); var result = res.result if (result) { this.existWarnig=false; this.resData = result // 保存所有站点数据,用于分页时调用 this.total = result.length for (var i = 0, ii = result.length; i < ii; i++) { var site = result[i] // 判断是否存在实时监控数据,数据类型 let isError = false // 是否报警 let monitorModel = {} if (site.allocations) { const allocationsAry = site.allocations.sort(compare('sortNumber')) if (allocationsAry.length > 0) { monitorModel = allocationsAry[0] } const allocationsFilter = site.allocations.filter(item => { return item.isAlarm == '1' }) if (allocationsFilter.length > 0) { isError = true; this.existWarnig=true; } } // 图片路径 const deviceTypeImg = modulesFiles('./' + (isError ? deviceConfig[site.deviceType].image_red : deviceConfig[site.deviceType].image)) // console.log("图片路径:"+deviceTypeImg) that.siteData.push({ id: site.id, site: site.name, x: site.longitude, y: site.latitude, isCraft: false, icon: deviceTypeImg, monitorModel: monitorModel, deviceType:site.deviceType, scadaEntity: site }) // site.iscraft == '1' }) } this.listRefersh(result) } else { that.siteDataTable = [] this.$refs.pageLength.innerHTML = '0/0 页' } } this.tableLoading = false }) function compare(key) { return function(value1, value2) { var val1 = value1[key] var val2 = value2[key] return val1 - val2 } } //定时更新报警内容 if(!this.queryTimeOut){ this.queryTimeOut = window.setTimeout(() => { window.clearTimeout(this.queryTimeOut); this.queryTimeOut=null; this.querySite() }, 1000 * 60 * 1) } }, listRefersh(res) { console.log('前端分页') // this.clearSiteDiv(); var pages = this.$refs.pagination var current = pages.internalCurrentPage var size = pages.internalPageSize var sites = this.siteData var firstIndex = (current - 1) * size var showSites = (this.siteDataTable = sites.slice( firstIndex, firstIndex + size )) this.$refs.pageLength.innerHTML = current + '/' + Math.ceil(sites.length / size) + ' 页' }, loadRealTimeSiteValue() { const data = { name: this.querySiteName } if (this.deviceType != '') { Object.assign(data, { deviceType: this.deviceType }) } getScadaMonitor(data).then((res) => { if (res.code == 1) { res = res.result.filter((item) => { return item.allocations }) setValue(res) } else { this.$message.error('获取测站指标失败!' + res.message) console.log(res) } }) var setValue = (res) => { var index = this.siteIndex for (var item in res) { if (!index.hasOwnProperty(res[item].id)) continue var di = index[res[item].id].children var dr = res[item].allocations for (const item2 in dr) { for (var i = 0, ii = di.length; i < ii; i++) { var ddi = di[i] var id = ddi.getAttribute('data') if (dr[item2].variableCode != id) continue var ddr = dr[item2].scada if (!ddr) continue var value = ddr.value ddi.children[1].innerHTML = value == 'null' ? '-' : value ddi.children[3].classList.value = 'scadaLayer-float-arrow' + (ddr.mark || 1) } } } this.timeOut = window.setTimeout( (_) => this.loadRealTimeSiteValue(), 1000 * 60 * 1 ) } }, goto(row) { if (row.x) { var mapView = this.mapView mapView.center = { x: row.x, y: row.y, spatialReference: mapView.spatialReference } mapView.zoom = 6 } else { this.$message('此测站无坐标信息') } }, getSiteHistroty(e) { this.$refs.scadaMapComAll.getSiteHistroty(e) // var stid, zbx; // stid = e.id; // this.siteVisible = true; // this.historyLoading = true; // var date = new Date(); // var date1 = new Date(date.getTime() - 1000 * 60 * 60 * 24); // this.timss = [ // [date1.getFullYear(), date1.getMonth() + 1, date1.getDate()].join("-") + // " 00:00:00", // [date.getFullYear(), date.getMonth() + 1, date.getDate()].join("-") + // " 00:00:00", // ]; // getScadaMonitor({ deviceId: stid }).then((res) => { // if (res.code == 1) { // res = res.result[0]; // this.selectSite = res; // var index = (this.selectZBXIndex = {}); // let allocations = res.allocations.sort((a, b) => { return parseInt(a.sortNumber) - parseInt(b.sortNumber) }) // this.sites = allocations.map((e) => { // index[e.variableCode] = [e.displayName, e.unit]; // return { value: e.variableCode, label: e.displayName }; // }); // this.siteType = zbx || this.sites[0].value; // this.chart = Echarts.init(this.$refs.chart); // idDone(); // } else { // this.$message.error("获取测站失败!"); // console.error(res); // this.siteVisible = false; // } // }); // var done = 0; // var idDone = () => { // if (++done == 1) this.showResult(); // }; }, /** * @dscription 显示 Scada 监测历史 */ showScadaHistory(e) { this.siteVisible = true this.getSiteHistroty(e) }, /** * @description scada 监测历史 */ showResult() { if (!this.timss) return this.$message.error('请选择时间范围') this.historyLoading = true this.$refs.pagination2.internalCurrentPage = 1 this.getAllData() this.siteHistiryQuery = [ this.selectZBXIndex[this.siteType][0], this.timss ] this.pagRefersh() }, getAllData() { var datt = this.selectZBXIndex[this.siteType] var times = this.timss var parm = this.siteType.replace(/\#/g, '%23') const params = { code: parm, start: times[0], end: times[1], isPage: false } getScadaListAll(params).then((res) => { var chart = this.chart chart.clear() if (res.code == 1) { res = res.result.records this.total2 = res.length var dontShow = this.dontShow var dataX = [] var dataY = [] var max = -Infinity var min = Infinity var Xmax = -Infinity var Xmin = Infinity var d var symbol = 'none' for (var i = 0, ii = res.length; i < ii; i++) { var v = parseFloat(res[i].value) if (dontShow && v == -9999) continue // var x = res[i].scadaTime.split(' ')[0] const x = res[i].scadaTime.substring(5) dataX.push(x) dataY.push(v) // if (v < min) min = v // if (v > max) max = v // if (x < Xmin) Xmin = x // if (x > Xmax) Xmax = x } // if (ii <= 1) symbol = Xmin = Xmax = max = min = undefined // else d = max - min, [max, min] = [max + d * 0.2, min - d * 0.2].map(e => parseFloat(e).toFixed(2)) var [type, unit] = datt chart.setOption({ title: { text: type, left: 'center', subtext: times[0] + '至' + times[1] }, color: 'rgb(45, 116, 231)', grid: { left: '50px', right: '50px', bottom: '80px' }, // dataZoom: [{ minSpan: 1, type: 'slider', labelFormatter: (i) => { // var date = new Date(i) // var time = [date.getHours(), date.getMinutes()] // if (time[0] < 10) time[0] = '0' + time[0] // if (time[1] < 10) time[1] = '0' + time[1] // return [date.getFullYear(), date.getMonth() + 1, date.getDate()].join('-') + '\n' + time.join(':') // } }], toolbox: { feature: { saveAsImage: {}}}, tooltip: { trigger: 'axis', formatter(a) { return ( '记录时间:' + a[0].axisValue + '<br>' + type + ' ' + a[0].data + ' ' + unit ) } }, xAxis: [ { name: '日期', type: 'category', data: dataX, axisTick: { show: false }, axisLine: { show: false } } ], yAxis: [{ name: unit, type: 'value' }], dataZoom: [ { type: 'inside', start: 0, end: 100 }, { start: 0, end: 100 } ], series: [ { type: 'line', symbol, smooth: true, data: dataY, markPoint: { data: [ { type: 'max', name: 'Max' }, { type: 'min', name: 'Min' } ] }, markLine: { data: [ { type: 'average', name: 'Avg', label: { show: true, formatter: '平均值:\n {c}' } } ] } } ] }) } else { this.$message.error('获取指标历史失败!' + res.message) console.error(res) } this.historyLoading = false }) }, pagRefersh() { this.tableLoading = true var pages = this.$refs.pagination2 var parm = this.siteType.replace(/\#/g, '%23') var [zbx, times] = this.siteHistiryQuery const params = { code: parm, start: times[0], end: times[1], current: pages.internalCurrentPage, size: pages.internalPageSize } queryMonitorHistory(params).then((res) => { if (res.code == 1) { res = res.result this.siteHistoryDataTable = res.records this.$refs.pageLength2.innerHTML = (pages.internalCurrentPage || 1) + '/' + Math.ceil(parseInt(res.total) / pages.internalPageSize) + ' 页' } else { this.$message.error(res.message) this.siteHistoryDataTable = [] this.$refs.pageLength2.innerHTML = '1/1 页' } this.tableLoading = false }) }, watchCraft(row) { var config = craftConfig[row.id] if (config) { this.craftVisible = true var image = new Image() var modulesFiles = require.context('./images', true, /\.png$/) image.src = modulesFiles('./' + config.craftImage) image.onload = () => { var craft = TF_craft({ div: this.$refs.craft, image: image, config: config.config, id: row.id }) this.craftRealTime(row.id, craft.index) craft.divs.map((e) => (e.onclick = this.getSiteHistroty)) } } else this.$message.error('工艺图未配置') }, craftRealTime(id, index) { request({ url: '/gis/customDisplay/getSiteInfos?stids=' + id, method: 'post' }).then((res) => { if (res.code == 1 && (res = res.result[id])) { for (var item in res) { if (!index.hasOwnProperty(item)) continue index[item].innerHTML = res[item].realVal } this.craftTimeOut = window.setTimeout(() => { this.craftRealTime(id, index) }, 1000 * 60 * 1) } else { this.$message.error('获取测站指标失败!' + res.message) console.log(res) } }) }, craftClose() { if (this.craftTimeOut) window.clearTimeout(this.craftTimeOut) }, /** * @description 判断数组是否为空 */ arrayIsNull(aryList) { return (typeof (aryList) === 'undefined' || aryList == null || aryList.length == 0) }, /** * @description 判断字符串是否为空 */ strIsNull(strVal) { strVal = strVal || '' return (typeof (strVal) === 'undefined' || strVal == null || strVal == '') } } } </script> <style lang='scss' scoped> .innerType { display: flex; width: 100%; // border: 1px red solid; } .legend_dept{ /deep/ .el-table tr { background-color: #FFFFFF; height: auto; } } </style>