<script lang="ts" setup name="GasDialog"> import { ElLoading, ElMessage, ElMessageBox } from 'element-plus' // import monitorDataGasList from './monitorDataGasList.vue' import dayjs from 'dayjs' // import { getMonitorData } from '@/api/home/pipeline/pipeline' import { getDeviceListPage } from '@/api/home/device/device' import { getDataSearch, getAlarmThresholdByCode } from '@/api/home/device/device' import { toHumpObject } from '@/utils/String' import { exportExcel } from '@/utils/exportXlsx' import { handlerListData, handlerSignalStrength } from '@/views/home/device/device/components/handlerData' const dialogFormVisible = ref(false) // 是否展示表格 const isShowTable = ref(true) const manufactureName = ref('') // 初始化对话框 const initDialog = (row: any) => { isShowTable.value = true if (row.deviceTypeName === '燃气智能监测终端') { columns.value = columns1.value columnsType.value = 'columns1' } else if (row.deviceTypeName.includes('管网哨兵')) { columns.value = columns2.value columnsType.value = 'columns2' // 获取设备信息 manufactureName.value = '' getDeviceListPage({ offset: 1, limit: 1, devCode: row.deviceCode }).then(res => { if (res.data.rows.length) { manufactureName.value = res.data.rows[0].manufactureName if (manufactureName.value.includes('百瑞生')) { columns.value = columns2BRS.value columnsType.value = 'columns2BRS' } else if (manufactureName.value.includes('麦哈克')) { columns.value = columns2MHK.value columnsType.value = 'columns2MHK' } } }) } else if (row.deviceTypeName === '智能警示桩') { columns.value = columns3.value columnsType.value = 'columns3' } else if (row.deviceTypeName === '场站监测云台') { columns.value = columns4.value columnsType.value = 'columns4' } dialogFormVisible.value = true listQuery.value.devcode = row.deviceCode listQuery.value.typeName = row.deviceTypeName datetimerange1.value = [ dayjs().subtract(7, 'day').format('YYYY-MM-DD HH:mm:ss'), dayjs().format('YYYY-MM-DD HH:mm:ss') ] setTimeout(() => { fetchData() }) } defineExpose({ initDialog }) const chartRef = ref() const cancel = () => { dialogFormVisible.value = false } // 列表loading const loadingTable = ref(true) // 列表展示数据 const list = ref<any[]>([]) const xAxisData = ref<any[]>([]) const chartData = ref<any[]>([]) // 列表展示列 const columns = ref<any>([]) const columnsType = ref('') // 燃气智能监测终端 const columns1 = ref<any>([ { text: '设备编号', value: 'devcode', align: 'center' }, { text: '燃气浓度(%LEL)', value: 'strength', align: 'center' }, { text: '电量(%)', value: 'cell', align: 'center' }, { text: '信号强度', value: 'rsrp', align: 'center' }, { text: '信号质量', value: 'rsrpName', align: 'center' }, { text: '采集时间', value: 'uptime', align: 'center' }, { text: '上传时间', value: 'logtime', align: 'center' } ]) // 管网哨兵 const columns2 = ref<any>([ { text: '设备编号', value: 'devcode', align: 'center' }, { text: '燃气浓度(%LEL)', value: 'gasval', align: 'center', isCustom: true }, { text: '电池电压(mV)', value: 'vbat', align: 'center' }, { text: '采集时间', value: 'uptime', align: 'center' }, { text: '上传时间', value: 'logtime', align: 'center' }, // { text: '设备状态', value: 'status', align: 'center', width: 90, isCustom: true }, ]) // 管网哨兵-百瑞生 const columns2BRS = ref<any>([ { text: '设备编号', value: 'devcode', align: 'center' }, { text: '燃气浓度(%LEL)', value: 'gasval', align: 'center', isCustom: true }, { text: '电池电压(mV)', value: 'vbat', align: 'center' }, { text: '传感器状态', value: 'ssState', align: 'center' }, { text: '温度(℃)', value: 'temp', align: 'center' }, { text: '信号质量', value: 'sig', align: 'center' }, { text: '采集时间', value: 'uptime', align: 'center' }, { text: '上传时间', value: 'logtime', align: 'center' }, // { text: '设备状态', value: 'status', align: 'center', width: 90, isCustom: true }, ]) // 管网哨兵-麦哈克 const columns2MHK = ref<any>([ { text: '设备编号', value: 'devcode', align: 'center' }, { text: '燃气浓度(%LEL)', value: 'gasval', align: 'center', isCustom: true }, { text: '电池电压(mV)', value: 'vbat', align: 'center' }, { text: '电池状态', value: 'ssState', align: 'center' }, { text: '信号质量', value: 'rsrp', align: 'center' }, { text: '采集时间', value: 'uptime', align: 'center' }, { text: '上传时间', value: 'logtime', align: 'center' }, // { text: '设备状态', value: 'status', align: 'center', width: 90, isCustom: true }, ]) // 智能警示桩 const columns3 = ref<any>([ { text: '左侧甲烷值', value: 'leftGas', align: 'center', width: '95' }, { text: '右侧甲烷值', value: 'rightGas', align: 'center', width: '95' }, { text: '电池电压(V)', value: 'vbat', align: 'center', width: '100' }, { text: '桩倾斜报警', value: 'pipeInclineAlarm', align: 'center', width: '95' }, { text: '桩拆卸报警', value: 'pipeBreakAlarm', align: 'center', width: '95' }, { text: '左断线报警', value: 'leftOffLineAlarm', align: 'center', width: '95' }, { text: '左振动报警', value: 'leftVibrateAlarm', align: 'center', width: '95' }, { text: '右断线报警', value: 'rightOffLineAlarm', align: 'center', width: '95' }, { text: '右振动报警', value: 'rightVibrateAlarm', align: 'center', width: '95' }, { text: '采集时间', value: 'uptime', align: 'center', width: '180' }, { text: '上传时间', value: 'logtime', align: 'center', width: '180' } ]) // 场站监测云台 const columns4 = ref<any>([ { text: '设备编号', value: 'deviceCode', align: 'center' }, { text: '浓度', value: 'concentration', align: 'center' }, { text: '水平位置', value: 'dircetion', align: 'center' }, { text: '垂直位置', value: 'pitch', align: 'center' }, { text: '采集时间', value: 'uptime', align: 'center' }, { text: '上传时间', value: 'logtime', align: 'center' } ]) const listQuery = ref({ devcode: '', logBegTime: '', logEndTime: '', typeName: '', upBegTime: '', upEndTime: '' }) // 开始结束时间 const datetimerange1 = ref() watch(() => datetimerange1.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 datetimerange2 = ref() watch(() => datetimerange2.value, newVal => { listQuery.value.logBegTime = '' listQuery.value.logEndTime = '' if (Array.isArray(newVal)) { if (newVal.length) { listQuery.value.logBegTime = `${newVal[0]}` listQuery.value.logEndTime = `${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.devcode = $route.query.deviceCode as string // listQuery.value.typeName = $route.query.typeName as string getDataSearch(listQuery.value).then(res => { list.value = res.data.map((item: any) => toHumpObject(item)) if (listQuery.value.typeName.includes('燃气智能监测终端')) { list.value = list.value.map((item: any) => ({ ...item, rsrpName: item.rsrp ? handlerSignalStrength(Number(item.rsrp)) : '-', rsrp: item.rsrp ? item.rsrp : '-' })) } else if (listQuery.value.typeName.includes('智能警示桩')) { const dict = { 0: '正常', 1: '报警' } as { [key: string]: string } list.value = list.value.map((item: any) => ({ ...item, pipeInclineAlarm: String(item.pipeInclineAlarm) === '1' || String(item.pipeInclineAlarm) === '0' ? dict[String(item.pipeInclineAlarm)] : item.pipeInclineAlarm, pipeBreakAlarm: String(item.pipeBreakAlarm) === '1' || String(item.pipeBreakAlarm) === '0' ? dict[String(item.pipeBreakAlarm)] : item.pipeBreakAlarm, leftOffLineAlarm: String(item.leftOffLineAlarm) === '1' || String(item.leftOffLineAlarm) === '0' ? dict[String(item.leftOffLineAlarm)] : item.leftOffLineAlarm, leftVibrateAlarm: String(item.leftVibrateAlarm) === '1' || String(item.leftVibrateAlarm) === '0' ? dict[String(item.leftVibrateAlarm)] : item.leftVibrateAlarm, rightOffLineAlarm: String(item.rightOffLineAlarm) === '1' || String(item.rightOffLineAlarm) === '0' ? dict[String(item.rightOffLineAlarm)] : item.rightOffLineAlarm, rightVibrateAlarm: String(item.rightVibrateAlarm) === '1' || String(item.rightVibrateAlarm) === '0' ? dict[String(item.rightVibrateAlarm)] : item.rightVibrateAlarm, })) } if (listQuery.value.typeName.includes('管网哨兵')) { // JSON.parse(JSON.stringify(list.value)).slice().reverse() xAxisData.value = JSON.parse(JSON.stringify(list.value)).slice().reverse().map(item => item.logtime) let markLineData = [] as any[] if (list.value.length) { getAlarmThresholdByCode({ devCode: list.value[0].devcode }).then(res1 => { if ((res1.data || []).length) { // 判断阈值 const handlerthresholdFun = (value: string, threshold: string[]) => { if (!threshold) { threshold = [] return '正常' } if (!threshold.length) { return '正常' } else { if (threshold.length === 1) { return Number(value) > Number(threshold[0]) ? '报警' : '正常' } else { // console.log(value, threshold) return Number(value) < Number(threshold[0]) && Number(value) < Number(threshold[threshold.length - 1]) ? '正常' : '报警' } } } list.value = list.value.map((item: any) => ({ ...item, status: handlerthresholdFun(item.gasval, (res1.data || []).map((item: any) => item.alarmThreshold)), }) as any) 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 } markLineData = (res1.data || []).map((item: any) => item.alarmThreshold).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}' } })) chartData.value = [ { name: '燃气浓度', data: JSON.parse(JSON.stringify(list.value)).slice().map(item => item.gasval || '0'), symbol: list.value.length > 1 ? 'none' : 'circle', markLine: { data: markLineData, silent: true, lineStyle: { color: 'red', join: 'round', cap: 'round', }, } }, ] setTimeout(() => { resizePage() }) } else { chartData.value = [ { name: '燃气浓度', data: JSON.parse(JSON.stringify(list.value)).slice().reverse().map(item => item.gasval || '0'), symbol: list.value.length > 1 ? 'none' : 'circle', }, ] setTimeout(() => { resizePage() }) } loadingTable.value = false }).catch(() => { chartData.value = [ { name: '燃气浓度', data: JSON.parse(JSON.stringify(list.value)).slice().reverse().map(item => item.gasval || '0'), symbol: list.value.length > 1 ? 'none' : 'circle', }, ] setTimeout(() => { resizePage() }) loadingTable.value = false }) // 处理列表字段 // 根据厂家判断 if (manufactureName.value) { handlerListData(manufactureName.value, list.value, (data: any) => { list.value = data }) } else { getDeviceListPage({ offset: 1, limit: 1, devCode: listQuery.value.devcode }).then(res => { if (res.data.rows.length) { manufactureName.value = res.data.rows[0].manufactureName handlerListData(manufactureName.value, list.value, (data: any) => { list.value = data }) } }) } } else { loadingTable.value = false } } else { loadingTable.value = false } }) .catch(() => { loadingTable.value = false }) } // onMounted(() => { // datetimerange1.value = [dayjs().subtract(7, 'day').format('YYYY-MM-DD HH:mm:ss'), dayjs().format('YYYY-MM-DD HH:mm:ss')] // datetimerange2.value = [dayjs().subtract(7, 'day').format('YYYY-MM-DD HH:mm:ss'), dayjs().format('YYYY-MM-DD HH:mm:ss')] // setTimeout(() => { // fetchData() // }) // }) // 切换视图 const switchView = () => { isShowTable.value = !isShowTable.value if (!isShowTable.value) { resizePage() } setTimeout(() => { fetchData() }) } // 导出 -- 前端 const exportList = () => { if (!list.value.length) { ElMessage.warning('暂无可导出数据') return } const loading = ElLoading.service({ lock: true, text: 'Loading', background: 'rgba(255, 255, 255, 0.8)', }) // 不同设备类型导出列 const exportDict = { columns1: { list: list.value.map((item: any, index: number) => ({ '1index': index + 1, '2devcode': item.devcode, '3strength': item.strength, '4cell': item.cell, '5rsrp': item.rsrp, '6rsrpName': item.rsrpName, '7uptime': item.uptime, '8logtime': item.logtime, })), columns: ['序号', '设备编号', '燃气浓度(%LEL)', '电量(%)', '信号强度', '信号质量', '采集时间', '上传时间'] }, columns2: { list: list.value.map((item: any, index: number) => ({ '1index': index + 1, '2devcode': item.devcode, '3gasval': item.gasval, '4vbat': item.vbat, '5uptime': item.uptime, '6logtime': item.logtime })), columns: ['序号', '设备编号', '燃气浓度(%LEL)', '电池电压(mV)', '采集时间', '上传时间'] }, columns2BRS: { list: list.value.map((item: any, index: number) => ({ '1index': index + 1, '2devcode': item.devcode, '3gasval': item.gasval, '4vbat': item.vbat, '5ssState': item.ssState, '6temp': item.temp, '7sig': item.sig, '8uptime': item.uptime, '9logtime': item.logtime })), columns: ['序号', '设备编号', '燃气浓度(%LEL)', '电池电压(mV)', '传感器状态', '温度(℃)', '信号质量', '采集时间', '上传时间'] }, columns2MHK: { list: list.value.map((item: any, index: number) => ({ 'index': index + 1, '2devcode': item.devcode, '3gasval': item.gasval, '4vbat': item.vbat, '5ssState': item.ssState, '6rsrp': item.rsrp, '7uptime': item.uptime, '8logtime': item.logtime })), columns: ['序号', '设备编号', '燃气浓度(%LEL)', '电池电压(mV)', '电池状态', '信号质量', '采集时间', '上传时间'] }, columns3: { list: list.value.map((item: any, index: number) => ({ '1index': index + 1, '2leftGas': item.leftGas, '3rightGas': item.rightGas, '4vbat': item.vbat, '5pipeInclineAlarm': item.pipeInclineAlarm, '6pipeBreakAlarm': item.pipeBreakAlarm, '7leftOffLineAlarm': item.leftOffLineAlarm, '8leftVibrateAlarm': item.leftVibrateAlarm, '9rightOffLineAlarm': item.rightOffLineAlarm, '10rightVibrateAlarm': item.rightVibrateAlarm, '11uptime': item.uptime, '12logtime': item.logtime })), columns: ['序号', '左侧甲烷值', '右侧甲烷值', '电池电压(V)', '桩倾斜报警', '桩拆卸报警', '左断线报警', '左振动报警', '右断线报警', '右振动报警', '采集时间', '上传时间'] }, columns4: { list: list.value.map((item: any, index: number) => ({ '1index': index + 1, '2concentration': item.concentration, '3dircetion': item.dircetion, '4pitch': item.pitch, '5uptime': item.uptime, '6logtime': item.logtime })), columns: ['序号', '浓度', '水平位置', '垂直位置', '采集时间', '上传时间'] } } as { [key: string]: any } exportExcel({ json: exportDict[columnsType.value]?.list || exportDict['columns1'].list, name: `燃气数据`, titleArr: exportDict[columnsType.value]?.columns || exportDict['columns1'].columns, sheetName: 'sheet1', }) loading.close() } </script> <template> <el-dialog v-model="dialogFormVisible" title="燃气浓度" append-to-body width="1300px"> <table-container title=""> <template #btns-left> <!-- 查询条件 --> <div style="display: flex; align-items: center"> <span style="margin-right: 5px; white-space: nowrap">采集时间:</span> <el-date-picker v-model="datetimerange1" type="datetimerange" range-separator="至" start-placeholder="采集开始时间" end-placeholder="采集结束时间" format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss" /> <span style="margin-right: 5px; margin-left: 10px; white-space: nowrap">上传时间:</span> <el-date-picker v-model="datetimerange2" type="datetimerange" range-separator="至" start-placeholder="上传开始时间" end-placeholder="上传结束时间" format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss" /> <el-button type="primary" style="margin-left: 10px" @click="fetchData"> 搜索 </el-button> <el-button v-if="listQuery.typeName?.includes('管网哨兵')" style="margin-left: 10px" @click="switchView"> 切换视图 </el-button> <el-button type="primary" style="margin-left: 10px" @click="exportList"> 导出 </el-button> </div> </template> <virtual-table v-show="isShowTable" :data="list" :columns="columns" :list-loading="loadingTable" :height="350"> <template #preColumns> <vxe-column title="序号" width="80" align="center"> <template #default="{ rowIndex }"> {{ rowIndex + 1 }} </template> </vxe-column> </template> <template #isCustom="{ scope, column }"> <span v-if="column.text === '燃气浓度(%LEL)'" :class="scope.row.status === '报警' ? 'red' : ''"> {{ scope.row[column.value] ? scope.row[column.value] : '-' }} </span> <span v-if="column.text === '设备状态'" :class="scope.row.status === '报警' ? 'red' : ''"> {{ scope.row[column.value] ? scope.row[column.value] : '-'}} </span> </template> </virtual-table> <!-- <normal-table v-show="isShowTable" :data="list" :total="0" :columns="columns" :height="350" :query="{}" :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] ? scope.row[column.value] : '-' }} </span> <span v-if="column.text === '设备状态'" :class="scope.row.status === '报警' ? 'red' : ''"> {{ scope.row[column.value] ? scope.row[column.value] : '-' }} </span> </template> </normal-table> --> <div v-loading="loadingTable" v-show="!isShowTable" style="height: 250px"> <line-chart ref="chartRef" v-show="xAxisData.length" v-loading="loadingTable" :x-axis-data="xAxisData" :data="chartData" :gradient="false" unit="%LEL" :legend="{ itemWidth: 8, itemHeight: 8, type: 'scroll', orient: 'horizontal', icon: 'roundRect', right: '60', top: '10' }" :grid="{ top: 50, left: 60, right: 130, bottom: 20, containLabel: true // 是否包含坐标轴的刻度标签 }" /> <el-empty v-show="!xAxisData.length" description="暂无数据" :image-size="100" /> </div> </table-container> <template #footer> <div class="dialog-footer"> <el-button @click="cancel"> 关闭 </el-button> </div> </template> </el-dialog> </template> <style lang="scss" scoped> .body { width: 100%; ::v-deep(.table-container) { .button-area { .custom { width: 100%; } } } } .el-dialog { width: 700px; } .el-select { width: 100%; } // .body { // ::v-deep(.button-left) { // width: 100%; // } // } ::v-deep(.table-container) { .button-left { width: 100%; } } .red { color: red; } </style>