Newer
Older
smartwell_front / src / views / home / pipeline / components / gasDataDialog.vue
liyaguang on 11 Feb 16 KB 需求修改
<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
  } else if (row.deviceTypeName.includes('管网哨兵')) {
    columns.value = columns2.value
    // 获取设备信息
    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
        }
        else if (manufactureName.value.includes('麦哈克')) {
          columns.value = columns2MHK.value
        }
      }
    })
  } else if (row.deviceTypeName === '智能警示桩') {
    columns.value = columns3.value
  } else if (row.deviceTypeName === '场站监测云台') {
    columns.value = columns4.value
  }
  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 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: '110' },
  { text: '右侧甲烷值', value: 'rightGas', align: 'center', width: '110' },
  { text: '电池电压(V)', value: 'vbat', align: 'center', width: '110' },
  {
    text: '桩倾斜报警',
    value: 'pipeInclineAlarm',
    align: 'center',
    width: '110'
  },
  {
    text: '桩拆卸报警',
    value: 'pipeBreakAlarm',
    align: 'center',
    width: '110'
  },
  {
    text: '左断线报警',
    value: 'leftOffLineAlarm',
    align: 'center',
    width: '110'
  },
  {
    text: '左振动报警',
    value: 'leftVibrateAlarm',
    align: 'center',
    width: '110'
  },
  {
    text: '右断线报警',
    value: 'rightOffLineAlarm',
    align: 'center',
    width: '110'
  },
  {
    text: '右振动报警',
    value: 'rightVibrateAlarm',
    align: 'center',
    width: '110'
  },
  { 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)).reverse()
    if(listQuery.value.typeName.includes('燃气智能监测终端')) {
      list.value = list.value.map((item:any) => ({
        ...item,
        rsrpName: item.rsrp ? handlerSignalStrength(Number(item.rsrp)) : ''
      }))
    }
    if (listQuery.value.typeName.includes('管网哨兵')) {
      xAxisData.value = list.value.slice().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: 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: list.value.slice().map(item => item.gasval || '0'),
                symbol: list.value.length > 1 ? 'none' : 'circle',
              },
            ]
            setTimeout(() => {
              resizePage()
            })
          }
          loadingTable.value = false
        }).catch(() => {
          chartData.value = [
            {
              name: '燃气浓度',
              data: list.value.slice().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)',
  })
  exportExcel({
    json: 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, '7status': item.status })),
    name: `管网哨兵${list.value[0].devcode}燃气数据`,
    titleArr: ['序号', '设备编号', '燃气浓度(%LEL)', '电池电压(mV)', '采集时间', '上传时间', '设备状态'],
    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 v-if="listQuery.typeName?.includes('管网哨兵')" type="primary" style="margin-left: 10px" @click="exportList">
            导出
          </el-button>
        </div>
      </template>
      <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] }}
          </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="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>