<!-- Description: 报警管理-查看数据(监控数据) Author: 李亚光 Date: 2024-09-10 --> <script lang="ts" setup name="MonitorDataDialog"> import { ElLoading, ElMessage, ElMessageBox } from 'element-plus' import dayjs from 'dayjs' import { getMonitorData } from '@/api/home/pipeline/pipeline' import { exportExcel } from '@/utils/exportXlsx' import { handlerSignalStrength } from '@/views/home/device/device/components/handlerData' const emits = defineEmits(['refresh']) const dialogFormVisible = ref(false) // 对话框是否显示 const info = ref() // 列表loading const loadingTable = ref(true) // 列表展示数据 const list = ref<any[]>([]) // 图表数据 const xAxisData = ref<any[]>([]) const data = ref<any[]>([]) // 列表展示列 const columns = ref<any[]>([ { text: '燃气浓度(%LEL)', value: 'strength', align: 'center', isCustom: true }, { text: '信号强度', value: 'rsrp', align: 'center', width: 85 }, { text: '信号质量', value: 'rsrpName', align: 'center', width: 85 }, { text: '电量(%)', value: 'cell', align: 'center', width: 80 }, { text: '采集时间', value: 'uptime', align: 'center' }, { text: '上传时间', value: 'logtime', align: 'center' }, // { text: '设备状态', value: 'status', align: 'center', width: 85, isCustom: true }, ]) const listQuery = ref({ upBegTime: '', upEndTime: '', typeName: '', devcode: '', }) // 开始结束时间 const datetimerange = ref() watch(() => datetimerange.value, (newVal) => { listQuery.value.upBegTime = '' listQuery.value.upEndTime = '' if (Array.isArray(newVal)) { if (newVal.length) { listQuery.value.upBegTime = `${newVal[0]}` listQuery.value.upEndTime = `${newVal[1]}` } } }, { deep: true, immediate: true, }) const resizePage = () => { setTimeout(() => { const resize = new Event('resize') window.dispatchEvent(resize) }, 500) } const fetchData = () => { loadingTable.value = true listQuery.value.typeName = info.value.devTypeName listQuery.value.devcode = info.value.devcode getMonitorData(listQuery.value).then((res) => { list.value = res.data.filter((item: any) => !item.alarmRuleValue).map((item: any) => ({...item, rsrpName: item.rsrp ? handlerSignalStrength(Number(item.rsrp)) : ''})) // 设置设备状态和燃气浓度标红 const threshold = res.data.filter((item: any) => item.alarmRuleValue)[0] // console.log(threshold.alarmRuleValue, '阈值') // 判断阈值 const handlerthreshold = (value: string, threshold: string[]) => { if (!threshold) { threshold = [] return '正常' } if (!threshold.length) { return '正常' } else { if (threshold.length === 1) { return Number(value) > Number(threshold[0]) ? '报警' : '正常' } else { return Number(value) < Number(threshold[0]) && Number(value) < Number(threshold[threshold.length - 1]) ? '正常' : '报警' } } } // console.log(456) list.value = list.value.map((item: any) => ({ ...item, status: handlerthreshold(item.strength, threshold.alarmRuleValue), }) as any) setTimeout(() => { loadingTable.value = false }, 1500); xAxisData.value = JSON.parse(JSON.stringify(list.value)).slice().reverse().map((item: any) => item.logtime) const indexDict = { 1: '一', 2: '二', 3: '三', 4: '其它', 5: '其它', 6: '其它', 7: '其它', } as { [key: string]: any } const colorDict = { 1: '#f56c6c', 2: '#ee9611', 3: '#ffd700', 4: '#8dc6ea', 5: '#8dc6ea', 6: '#8dc6ea', 7: '#8dc6ea', } as { [key: string]: any } // threshold.alarmRuleValue = ['8', '40'] threshold.alarmRuleValue = threshold.alarmRuleValue.sort((a,b) => Number(b) - Number(a)) // console.log(threshold.alarmRuleValue) const markLineData = threshold.alarmRuleValue.map((item: string, index: number) => ({ name: `${indexDict[index+ 1]}级报警阈值:${Number(item)}%LEL`, yAxis: Number(item), lineStyle: { color: colorDict[index+ 1], join: 'round', cap: 'round', }, label: { show: true, formatter: '{b}' } })) // console.log('阈值线', markLineData) data.value = [ { name: '燃气浓度', data: JSON.parse(JSON.stringify(list.value)).slice().reverse().map((item: any) => item.strength).reverse(), symbol: list.value.length > 1 ? 'none' : 'circle', markLine: { data: markLineData, silent: true, lineStyle: { color: 'red', join: 'round', cap: 'round', }, } }, ] resizePage() }) .catch(() => { loadingTable.value = false }) } onMounted(() => { datetimerange.value = [ dayjs().subtract(7, 'day').format('YYYY-MM-DD HH:mm:ss'), dayjs().format('YYYY-MM-DD HH:mm:ss'), ] }) // 是否展示表格 const isShowTable = ref(false) // 切换视图 const switchView = () => { isShowTable.value = !isShowTable.value if (!isShowTable.value) { resizePage() } } // 初始化对话框 const initDialog = (row: any, timerange = []) => { dialogFormVisible.value = true info.value = row // datetimerange.value = [ // dayjs().subtract(7, 'day').format('YYYY-MM-DD HH:mm:ss'), // dayjs().format('YYYY-MM-DD HH:mm:ss'), // ] if(!timerange.length) { datetimerange.value = [dayjs().subtract(7, 'day').format('YYYY-MM-DD HH:mm:ss'), dayjs().format('YYYY-MM-DD HH:mm:ss')] } else { datetimerange.value = timerange } setTimeout(() => { fetchData() }) } defineExpose({ initDialog, switchView, }) const cancel = () => { dialogFormVisible.value = false } // 导出 -- 前端 const exportList = () => { if (!list.value.length) { ElMessage.warning('暂无可导出数据') return } const loading = ElLoading.service({ lock: true, text: 'Loading', background: 'rgba(255, 255, 255, 0.8)', }) exportExcel({ json: list.value.map((item: any, index: number) => ({ '1index': index + 1, '2strength': item.strength, '3pci': item.pci, '4cell': item.cell, '5uptime': item.uptime,'6logtime': item.logtime, })), name: '浓度数据', titleArr: ['序号', '燃气浓度(%LEL)', '信号强度', '电池电压(%)', '采集时间', '上传时间'], sheetName: 'sheet1', }) loading.close() } </script> <template> <el-dialog v-model="dialogFormVisible" title="查看数据" append-to-body width="1000px"> <table-container title=""> <template #btns-left> <!-- 查询条件 --> <div style="display: flex; align-items: center; white-space: nowrap;"> <span style="margin-right: 5px;">采集时间: </span> <el-date-picker v-model="datetimerange" type="datetimerange" range-separator="至" start-placeholder="采集开始时间" end-placeholder="采集结束时间" format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss" /> <!-- <el-date-picker v-model="timerang" type="datetimerange" range-separator="至" start-placeholder="上传开始时间" end-placeholder="上传结束时间" format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss" style="margin-left: 10px;" /> --> <el-button type="primary" style="margin-left: 10px;" @click="fetchData"> 搜索 </el-button> <el-button @click="switchView"> 切换视图 </el-button> <el-button type="primary" style="margin-left: 10px;" @click="exportList"> 导出 </el-button> </div> </template> <normal-table v-show="isShowTable" :data="list" :total="0" :columns="columns" :query="{}" :height="350" :list-loading="loadingTable" :pagination="false"> <template #preColumns> <el-table-column label="序号" width="55" align="center"> <template #default="scope"> {{ scope.$index + 1 }} </template> </el-table-column> </template> <template #isCustom="{ scope, column }"> <!-- 设备编号 --> <span v-if="column.text === '燃气浓度(%LEL)'" :class="scope.row.status === '报警' ? 'red' : ''"> {{ scope.row[column.value] }} </span> <!-- 设备状态 --> <span v-if="column.text === '设备状态'" :class="scope.row.status === '报警' ? 'red' : ''"> {{ scope.row[column.value] }} </span> </template> </normal-table> <div v-loading="loadingTable" v-show="!isShowTable" style="width: 100%; height: 240px;"> <line-chart v-show="xAxisData.length" :loading="loadingTable" :x-axis-data="xAxisData" :data="data" :gradient="false" :smooth="false" unit="%LEL" :legend="{ itemWidth: 8, itemHeight: 8, type: 'scroll', orient: 'horizontal', icon: 'roundRect', right: '60', top: '10', }" :showyAxisLine="true" :grid="{ top: 50, left: 60, right: 130, bottom: 20, containLabel: true, // 是否包含坐标轴的刻度标签 }" /> <el-empty v-show="!xAxisData.length" description="暂无数据" /> </div> </table-container> <template #footer> <div class="dialog-footer"> <el-button type="primary" @click="cancel"> 确认 </el-button> </div> </template> </el-dialog> </template> <style lang="scss" scoped> .el-dialog { width: 700px; } .el-select { width: 100%; } .red { color: red; } </style>