<template> <!-- 监测告警弹窗 --> <div class="jcgjPopup" v-show="allData.popupShow"> <div class="title"> <div class="titleName"> {{ allData.dataList.stName }} <el-button size="small" type="warning" @click="handleWarn" style="margin-left: 30px">报警处理</el-button> </div> <div class="closePopup"> <el-icon :size="18" @click="closePopup"><Close /></el-icon> </div> </div> <div class="allContent"> <div class="basicInfo"> <div class="basicContent"> <div class="contentInfo"> <div class="contentName">站点编码:</div> <div class="contentValue">{{ allData.dataList.stCode }}</div> </div> <div class="contentInfo"> <div class="contentName">安装地址:</div> <div class="contentValue" :title="allData.dataList.address">{{ allData.dataList.address }}</div> </div> <div class="contentInfo"> <div class="contentName">经度:</div> <div class="contentValue">{{ allData.dataList.lonLat && allData.dataList.lonLat.split(',')[0] }}</div> </div> <div class="contentInfo"> <div class="contentName">纬度:</div> <div class="contentValue">{{ allData.dataList.lonLat && allData.dataList.lonLat.split(',')[1] }}</div> </div> <div class="contentInfo"> <div class="contentName">监测指标:</div> <div class="contentValue">{{ allData.dataList.dynamicTableMonitor }}</div> </div> <div class="contentInfo"> <div class="contentName">站点类型:</div> <div class="contentValue"><dict-tag :options="siteTypes" :value="allData.dataList.siteType" /></div> </div> </div> <el-image v-if="allData.dataList['coverPhotosFileList']" :src="allData.dataList['coverPhotosFileList'][0]" :preview-src-list="srcList" style="padding-left: 50px" /> </div> <div class="dividerLine"></div> <div class="trend"> <el-date-picker v-model="allData.dataTime1" type="date" value-format="YYYY-MM-DD" start-placeholder="开始时间" end-placeholder="结束时间" size="small" style="width: 120px; margin-left: 10px" @change="changeDate" /> - <el-date-picker v-model="allData.dataTime2" type="date" value-format="YYYY-MM-DD" start-placeholder="开始时间" end-placeholder="结束时间" size="small" style="width: 120px" @change="changeDate" /> <el-select v-model="selectCode" style="margin: 0px 0px 0px 10px; width: 120px" size="small" @change="changeSuperType"> <el-option v-for="(item, index) in dataOption" :key="index" :label="item.label" :value="item.value" /> </el-select> <div id="chartPopupJCGJ" v-if="propertyMonitorXList.length > 0"></div> <!-- 暂无数据 --> <el-empty :image-size="80" v-if="propertyMonitorXList.length == 0" style="margin-top: 50px" /> </div> </div> <!-- 故障报警详情弹窗 --> <el-dialog v-model="dialogShow" :title="allData.dataList.stName + '监测站点详情'" width="800px" append-to-body> <div class="publicDetail flex50"> <div class="part"> <p class="title">站点名称:</p> <p class="content">{{ allData.dataList.stName }}</p> </div> <div class="part"> <p class="title">站点编号:</p> <p class="content">{{ allData.dataList.stCode }}</p> </div> <div class="part" style="width: 100%"> <p class="title">辖区负责人:</p> <p class="content">{{ allData.dataList.chargeUser }}</p> </div> <el-radio-group v-model="warnType" @change="changeType"> <el-radio label="1">设备报警</el-radio> <el-radio label="2">指标报警</el-radio> </el-radio-group> <el-table :data="tableData" max-height="300"> <el-table-column prop="qdCode" label="故障类型" v-if="warnType == '1'"> <template #default="scope"> <span> {{ scope.row.faultType == 'low_battery' ? '低电压' : scope.row.faultType == 'low_signal' ? '低信号' : scope.row.faultType == 'exception' ? '异常值' : scope.row.faultType == 'offline' ? '离线' : '--' }} </span> </template> </el-table-column> <el-table-column prop="fromDatetime" label="开始时间" v-if="warnType == '1'" /> <el-table-column prop="toDatetime" label="结束时间" v-if="warnType == '1'" /> <el-table-column prop="durationTime" label="停留时长(h)" v-if="warnType == '1'" /> <el-table-column prop="warnFactorName" label="因子名称" v-if="warnType == '2'" /> <el-table-column prop="warnFactorValueName" label="监测值" v-if="warnType == '2'" /> <el-table-column prop="warnCount" label="报警次数" v-if="warnType == '2'" /> <el-table-column prop="updateTime" label="报警时间" v-if="warnType == '2'" /> <el-table-column prop="continueMinute" label="停留时长(min)" v-if="warnType == '2'" /> </el-table> <!-- 有数据时才显示 --> <div class="flex flex-justcontent-center" style="width: 100%; margin-top: 10px" v-if="tableData.length > 0"> <el-button size="small" type="primary" @click="goIgnore">误报忽略</el-button> <el-button size="small" type="warning" @click="goOrder">去处理</el-button> </div> </div> </el-dialog> <!-- 去处理转工单 --> <el-dialog v-model="dialogOrder" title="设备故障报警转维修工单" width="500px" append-to-body> <el-form ref="formRef" :model="formData" :rules="rulesForm" label-width="120px" class="publicForm"> <el-form-item label="维修人员" prop="rpUserNo"> <el-select v-model="formData.rpUserNo" placeholder="请选择" clearable> <el-option v-for="item in userList" :key="item.userName" :label="item.nickName" :value="item.userName" /> </el-select> </el-form-item> <el-form-item label="期望完成时间" prop="rpExpectTime"> <el-date-picker type="datetime" v-model="formData.rpExpectTime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择日期"> </el-date-picker> </el-form-item> <el-form-item label="事件紧急程度" prop="rpUrgency"> <el-select v-model="formData.rpUrgency" placeholder="请选择" clearable> <el-option v-for="item in urgencyType" :key="item.value" :label="item.label" :value="item.value" /> </el-select> </el-form-item> <el-form-item label="维修要求" prop="rpRequire"> <el-input type="textarea" v-model="formData.rpRequire" placeholder="请输入" /> </el-form-item> <el-form-item label="维修类型" prop="rpType"> <el-select v-model="formData.rpType" placeholder="请选择" clearable> <el-option v-for="item in repairType" :key="item.value" :label="item.label" :value="item.value" /> </el-select> </el-form-item> </el-form> <template #footer> <div class="dialog-footer"> <el-button type="info" @click="dialogOrder = false">取 消</el-button> <el-button type="primary" @click="goOrderSubmit">确 定</el-button> </div> </template> </el-dialog> </div> </template> <script setup name="commonjcgjPopup"> import bus from '@/bus'; import chartOption from '@/components/Echarts/pieChart_1.js'; import * as echarts from 'echarts'; import { graphicReport } from '@/api/dataAnalysis/syntherticData'; import { listUser } from '@/api/system/user'; import { transferWarnRepairOrder, transferDeviceFaultRepairOrder, warnOrderIgnore, deviceFaultOrderIgnore, rtuSiteInfoDetail, rtuWarnConfiglist, } from '@/api/floodSys/repair'; import { rtuWarnRecordRealtimeDetail, rtuFaultTimeSectionRealtimeDetail } from '@/api/floodSys/oneMap'; import { ref } from 'vue'; const { proxy } = getCurrentInstance(); const dialogShow = ref(false); const dialogOrder = ref(false); const siteTypes = proxy.fixDict['siteTypes']; //站点类型 const dataOption = ref([]); const selectData = ref([]); const selectCode = ref(''); const seleceName = ref(''); const unitName = ref(''); const siteWarnConfigList = ref([]); const propertyMonitorXList = ref([]); const allData = reactive({ popupShow: false, currentIndex: 1, dataTime1: proxy.moment(new Date()).subtract(3, 'days').format('YYYY-MM-DD'), dataTime2: proxy.moment(new Date()).format('YYYY-MM-DD'), dataList: {}, gaojingType: '', warnFormulaValue: '', formData: { eventRelationId: '', rpUserName: '', rpUserNo: '', rpUrgency: '', rpType: '', rpRequire: '', rpExpectTime: '', }, rulesForm: { rpUserNo: [{ required: true, message: '请输入', trigger: 'blur' }], rpUrgency: [{ required: true, message: '请输入', trigger: 'blur' }], }, }); const { formData, rulesForm } = toRefs(allData); const urgencyType = proxy.fixDict['urgencyType']; //事件紧急程度 const repairType = ref([ { label: '小修', value: 'minor' }, { label: '专项维修', value: 'special' }, ]); const userList = ref([]); const tableData = ref([]); const warnType = ref('1'); // 弹窗关闭 const closePopup = () => { allData.popupShow = false; allData.dataTime1 = proxy.moment(new Date()).subtract(3, 'days').format('YYYY-MM-DD'); allData.dataTime2 = proxy.moment(new Date()).format('YYYY-MM-DD'); newfiberMapbox.map.easeTo({ center: [114.312, 34.802], zoom: 12.9, pitch: 55, }); let clearSelectedFeature = []; newfiberMapbox.getLayers().forEach(feature => { if (feature.newfiberId == 'highlight_point') { clearSelectedFeature.push(feature); } }); if (!!clearSelectedFeature.length) { clearSelectedFeature[0].setData({ type: 'FeatureCollection', features: [] }); } }; // 报警点击 async function handleWarn() { dialogShow.value = true; warnType.value = allData.gaojingType.toString(); getWarnData(); } // 设备、指标切换 function changeType(val) { warnType.value = val; getWarnData(); } // 获取故障和指标报警数据 async function getWarnData() { if (warnType.value == '1') { // 设备 let res = await rtuFaultTimeSectionRealtimeDetail({ stCode: allData.dataList.stCode }); if (res && res.code == 200) { tableData.value = res.data || []; } } else { // 指标 let res = await rtuWarnRecordRealtimeDetail({ stCode: allData.dataList.stCode }); if (res && res.code == 200) { tableData.value = res.data || []; } } if (tableData.value.length > 0) { formData.value.eventRelationId = tableData.value[0].id; } else { formData.value.eventRelationId = ''; } } // 误报忽略点击 async function goIgnore() { let res = null; if (warnType.value == '1') { // 设备故障 res = await deviceFaultOrderIgnore({ stCode: allData.dataList.stCode }); } else { // 设备告警指标 res = await warnOrderIgnore({ stCode: allData.dataList.stCode }); } if (res && res.code == 200) { proxy.$modal.msgSuccess('忽略成功'); bus.emit('refreshGJ'); //主列表刷新数据 getWarnData(); dialogShow.value = false; } } // 工单处理点击 function goOrder() { proxy.resetForm('formRef'); //清空表单 dialogOrder.value = true; formData.value.stCode = allData.dataList.stCode; } // 工单处理提交确定 function goOrderSubmit() { proxy.$refs['formRef'].validate(valid => { if (valid) { formData.value.rpUserName = userList.value.filter(item => item.userName == formData.value.rpUserNo)[0].nickName; if (warnType.value == '1') { // 设备故障 transferDeviceFaultRepairOrder(formData.value).then(response => { proxy.$modal.msgSuccess('转维修工单成功'); dialogOrder.value = false; bus.emit('refreshGJ'); //主列表刷新数据 getWarnData(); dialogShow.value = false; }); } else { // 设备告警指标 transferWarnRepairOrder(formData.value).then(response => { proxy.$modal.msgSuccess('转维修工单成功'); dialogOrder.value = false; bus.emit('refreshGJ'); //主列表刷新数据 getWarnData(); dialogShow.value = false; }); } } }); } //时间格式化 const getYearMonthDay = time => { return proxy.moment(time).format('YYYY-MM-DD'); }; const changeDate = () => { getJCGJData(); }; function changeSuperType(val) { selectCode.value = val; let obj = dataOption.value.filter(item => item.value == val)[0]; selectCode.value = obj.value; seleceName.value = obj.label; unitName.value = obj.propertyUnit; selectData.value = obj.ylist; allData.warnFormulaValue = ''; if (Boolean(siteWarnConfigList.value.length) && seleceName.value) { let alist = siteWarnConfigList.value; alist.forEach(element => { if (element.warnFactorName.includes(seleceName.value)) { allData.warnFormulaValue = element.warnFormulaValue; } }); } initEcharts1(); } //获取监测数据 const getJCGJData = async () => { let params = { // startTime: '2024-01-01', // endTime: '2024-01-02', startTime: allData.dataTime1, endTime: allData.dataTime2, stCode: allData.dataList.stCode, }; let res = await graphicReport(params); if (res && res.code == 200) { let datas = res.data; dataOption.value = []; datas.propertyMonitorList.map(item => { dataOption.value.push({ value: item.stCode + item.monitorPropertyName, label: item.monitorPropertyName, propertyUnit: item.propertyUnit, ylist: item.ylist, }); }); propertyMonitorXList.value = datas.propertyMonitorXList; if (datas.propertyMonitorXList.length == 0) return; selectCode.value = dataOption.value[0].value; seleceName.value = dataOption.value[0].label; unitName.value = dataOption.value[0].propertyUnit; selectData.value = dataOption.value[0].ylist; if (Boolean(siteWarnConfigList.value.length) && seleceName.value) { let alist = siteWarnConfigList.value; alist.forEach(element => { if (element.warnFactorName.includes(seleceName.value)) { allData.warnFormulaValue = element.warnFormulaValue; } }); } setTimeout(() => { initEcharts1(); }); } }; //监测告警趋势图 let chartPopupSup = null; const initEcharts1 = () => { if (!!chartPopupSup) chartPopupSup.dispose(); chartPopupSup = echarts.init(document.getElementById('chartPopupJCGJ')); chartOption.floodOneMapPipeWarns.legend.data = [seleceName.value]; chartOption.floodOneMapPipeWarns.yAxis[0].name = unitName.value; chartOption.floodOneMapPipeWarns.yAxis[1].name = ''; chartOption.floodOneMapPipeWarns.xAxis[0].data = propertyMonitorXList.value; chartOption.floodOneMapPipeWarns.series[0].name = seleceName.value; chartOption.floodOneMapPipeWarns.series[0].data = selectData.value; chartOption.floodOneMapPipeWarns.series[1].data = []; if (allData.gaojingType == 2) { chartOption.floodOneMapPipeWarns.series[0].markLine = { symbol: 'none', label: { show: !!allData.warnFormulaValue, position: 'middle', formatter: seleceName.value + '警戒值:{c}', color: 'red', fontWeight: 'bold', }, lineStyle: { color: 'red', width: 2, type: 'solid', }, data: [ { name: '警戒值', yAxis: allData.warnFormulaValue, }, ], }; } else { chartOption.floodOneMapPipeWarns.series[0].markLine = ''; } // 设置鼠标滚轮放大缩小展示数据区间 chartOption.floodOneMapPipeWarns.dataZoom = [ { type: 'inside', startValue: propertyMonitorXList.value[propertyMonitorXList.value.length / 2] }, ]; if (propertyMonitorXList.value.length > 0) { chartOption.floodOneMapPipeWarns.graphic.invisible = true; //暂无数据 } else { chartOption.floodOneMapPipeWarns.graphic.invisible = false; //暂无数据 } chartPopupSup.clear(); chartPopupSup.setOption(chartOption.floodOneMapPipeWarns); }; //搜索维修人员列表 function getUserList() { listUser().then(res => { userList.value = res.data; }); } // 获取站点详情数据 async function getDetailData(stCode) { let res = await rtuSiteInfoDetail(stCode); if (res && res.code == 200) { allData.dataList = res.data; getJCGJData(); } } // 获取站点告警数据 async function getDetailwarnData(stCode) { console.log(stCode, 11111); let res = await rtuWarnConfiglist({ stCode: stCode }); if (res && res.code == 200) { siteWarnConfigList.value = res.data; } } onMounted(() => { getUserList(); bus.on('closeCommonPopup', closeCommonPopup => { allData.popupShow = closeCommonPopup; }); bus.on('popupJCGJData', data => { allData.popupShow = true; allData.gaojingType = data.gaojingType; if (allData.gaojingType == 2) { getDetailwarnData(data.stCode); } getDetailData(data.stCode); //获取详情数据 }); }); onBeforeUnmount(() => { bus.off('popupJCGJData'); bus.off('closeCommonPopup'); }); </script> <style lang="scss"> .jcgjPopup { width: 748px; height: 476px; background-image: url('@/assets/newImgs/layer1.png'); background-size: 100% 100%; z-index: 115; position: absolute; top: 80px; left: 330px; .title { padding-top: 30px; display: flex; align-items: center; justify-content: space-between; .titleName { display: flex; align-items: center; height: 22px; font-size: 16px; font-family: PingFang SC; font-weight: 400; color: #ccf1ff; line-height: 22px; padding-left: 80px; &:before { display: block; content: ''; width: 3px; height: 16px; background: #00d1ff; margin-right: 10px; } } .closePopup { padding-right: 40px; height: 22px; cursor: pointer; } } .allContent { display: flex; .basicInfo { width: 270px; margin-top: 10px; .basicContent { .contentInfo { display: flex; align-items: center; padding-left: 80px; .contentName { margin: 3px; height: 20px; width: 70px; font-size: 14px; font-weight: 400; line-height: 20px; color: #00d1ff; } .contentValue { width: 100px; font-size: 14px; font-weight: 400; color: #00d1ff; word-wrap: break-word; } } } } .dividerLine { width: 3px; height: 350px; position: absolute; left: 250px; border: 1px; background: linear-gradient(90deg, rgba(0, 115, 165, 0) 0.79%, #0073a5 20.43%, #0073a5 82.43%, rgba(0, 115, 165, 0) 100%); } .trend { width: 450px; #chartPopupJCGJ { width: 90%; height: 300px; margin-top: 20px; } } } } </style>