Newer
Older
xc-metering-front / src / views / laboratory / data / list.vue
dutingting on 25 Sep 21 KB 环境修改
<!-- 数据列表 -->
<script lang="ts" setup name="LaboratoryDataList">
import type { Ref } from 'vue'
import { ElLoading, ElMessage, ElMessageBox } from 'element-plus'
import type { DateModelType } from 'element-plus'
import type {
  IElectricQuantityList,
  IListQuery,
  IOxygenList,
  ISmokeList,
  ITemperatureHumidityList,
  IUPSList,
} from './list-interface'
import upsMonitorDetailDialog from './dialog/upsMonitorDetailDialog.vue'
import type { TableColumn } from '@/components/NormalTable/table_interface'
import { exportFile } from '@/utils/exportUtils'
import useTemplateDownload from '@/utils/useTemplateDownload'
import { getDictByCode } from '@/api/system/dict'
import type { deptType, dictType } from '@/global'
import { getUserList } from '@/api/system/user'
import { exportDataList, getDataList } from '@/api/laboratory/data'
import { toTreeList } from '@/utils/structure'
import useUserStore from '@/store/modules/user'
import { getAllDeptList } from '@/api/system/dept'

const user = useUserStore() // 用户信息
const $router = useRouter()
const $route = useRoute()
const loadingTable = ref(false)
const listMap = {
  temperatureHumidityList: ref<ITemperatureHumidityList[]>([]), // 温湿度网络传感器
  electricQuantityList: ref<IElectricQuantityList[]>([]), // 智能电量仪
  oxygenList: ref<IOxygenList[]>([]), // 氧气传感器
  smokeList: ref<ISmokeList[]>([]), // 烟雾传感器
  upsList: ref<IUPSList[]>([]), // UPS电源间电池
  upsMonitorList: ref<IUPSList[]>([]), // UPS监测
}
const menu = ref([ // 菜单
  {
    id: 'temperatureHumidity',
    name: '温湿度网络传感器',
    columns: ref<TableColumn[]>([
      { text: '设备编号', value: 'deviceNo', align: 'center', width: '160' },
      { text: '设备名称', value: 'deviceName', align: 'center' },
      { text: '负责部门', value: 'deptName', align: 'center' },
      { text: '负责人', value: 'userName', align: 'center' },
      { text: '安装地点', value: 'locationName', align: 'center' },
      { text: '温度(℃)', value: 'temperature', align: 'center' },
      { text: '湿度(%)', value: 'humidity', align: 'center' },
      // { text: '状态', value: 'deviceStatusName', align: 'center', styleFilter: (row: ISmokeList) => { return `${row.deviceStatus}` === '0' ? 'color: red' : `${row.deviceStatus}` === '1' ? 'color: #00a846' : '' } },
      { text: '上传时间', value: 'uploadTime', align: 'center', width: '180' },
    ]),
    list: listMap.temperatureHumidityList,
  },
  {
    id: 'electricQuantity',
    name: '智能电量仪',
    columns: ref<TableColumn[]>([
      { text: '设备编号', value: 'deviceNo', align: 'center', width: '160' },
      { text: '设备名称', value: 'deviceName', align: 'center' },
      { text: '负责部门', value: 'deptName', align: 'center' },
      { text: '负责人', value: 'userName', align: 'center' },
      { text: '电压', value: 'voltageA', align: 'center' },
      // { text: 'A相电压', value: 'voltageA', align: 'center' },
      // { text: 'B相电压', value: 'voltageB', align: 'center' },
      // { text: 'C相电压', value: 'voltageC', align: 'center' },
      // { text: 'A相电流', value: 'currentA', align: 'center' },
      // { text: 'B相电流', value: 'currentB', align: 'center' },
      // { text: 'C相电流', value: 'currentC', align: 'center' },
      // { text: '电量(%)', value: 'electricQuantity', align: 'center' },
      { text: '状态', value: 'deviceStatusName', align: 'center', styleFilter: (row: ISmokeList) => { return `${row.deviceStatus}` === '0' ? 'color: red' : `${row.deviceStatus}` === '1' ? 'color: #00a846' : '' } },
      { text: '上传时间', value: 'uploadTime', align: 'center', width: '180' },
    ]),
    list: listMap.electricQuantityList,
  },
  {
    id: 'oxygen',
    name: '氧气传感器',
    columns: ref<TableColumn[]>([
      { text: '设备编号', value: 'deviceNo', align: 'center', width: '160' },
      { text: '设备名称', value: 'deviceName', align: 'center' },
      { text: '负责部门', value: 'deptName', align: 'center' },
      { text: '负责人', value: 'userName', align: 'center' },
      { text: '安装地点', value: 'locationName', align: 'center' },
      { text: '氧气浓度(ppm)', value: 'oxygenDensity', align: 'center' },
      { text: '电量(%)', value: 'electricQuantity', align: 'center' },
      // { text: '状态', value: 'deviceStatusName', align: 'center', styleFilter: (row: ISmokeList) => { return `${row.deviceStatus}` === '0' ? 'color: red' : `${row.deviceStatus}` === '1' ? 'color: #00a846' : '' } },
      { text: '上传时间', value: 'uploadTime', align: 'center', width: '180' },
    ]),
    list: listMap.oxygenList,
  },
  {
    id: 'smoke',
    name: '烟雾报警器',
    columns: ref<TableColumn[]>([
      { text: '设备编号', value: 'deviceNo', align: 'center', width: '160' },
      { text: '设备名称', value: 'deviceName', align: 'center' },
      { text: '负责部门', value: 'deptName', align: 'center' },
      { text: '负责人', value: 'userName', align: 'center' },
      { text: '安装地点', value: 'locationName', align: 'center' },
      { text: '状态', value: 'deviceStatusName', align: 'center', styleFilter: (row: ISmokeList) => { return `${row.deviceStatus}` === '0' ? 'color: red' : `${row.deviceStatus}` === '1' ? 'color: #00a846' : '' } },
      { text: '烟雾值', value: 'smokeValue', align: 'center' },
      { text: '电量(%)', value: 'electricQuantity', align: 'center' },
      { text: '上传时间', value: 'uploadTime', align: 'center', width: '180' },
    ]),
    list: listMap.smokeList,
  },
  {
    id: 'ups',
    name: 'UPS电源间电池',
    columns: ref<TableColumn[]>([
      { text: '设备编号', value: 'deviceNo', align: 'center', width: '160' },
      { text: '设备名称', value: 'deviceName', align: 'center' },
      { text: '负责部门', value: 'deptName', align: 'center' },
      { text: '负责人', value: 'userName', align: 'center' },
      { text: '安装地点', value: 'locationName', align: 'center' },
      { text: '所属实验室', value: 'labName', align: 'center', width: '120' },
      { text: '电压(V)', value: 'voltage', align: 'center' },
      { text: '内阻(mΩ)', value: 'resistance', align: 'center' },
      { text: '温度(℃)', value: 'temperature', align: 'center' },
      { text: '状态', value: 'deviceStatusName', align: 'center', styleFilter: (row: IUPSList) => { return `${row.deviceStatus}` === '0' ? 'color: red' : `${row.deviceStatus}` === '1' ? 'color: #00a846' : '' } },
      { text: '上传时间', value: 'uploadTime', align: 'center', width: '180' },
    ]),
    list: listMap.upsList,
  },
  {
    id: 'ups/monitor',
    name: 'UPS监测',
    columns: ref<TableColumn[]>([
      { text: '设备编号', value: 'deviceNo', align: 'center', width: '160' },
      { text: '设备名称', value: 'deviceName', align: 'center' },
      { text: '负责部门', value: 'deptName', align: 'center' },
      { text: '负责人', value: 'userName', align: 'center' },
      { text: '安装地点', value: 'locationName', align: 'center' },
      { text: '所属实验室', value: 'labName', align: 'center', width: '120' },
      { text: '参数', value: 'params', align: 'center', width: '160' },
      { text: '状态', value: 'upsMonitorDeviceStatusName', align: 'center', styleFilter: (row: IUPSList) => { return `${row.status}` === '1' ? 'color: red' : `${row.status}` === '0' ? 'color: #00a846' : '' } },
      { text: '上传时间', value: 'uploadTime', align: 'center', width: '180' },
    ]),
    list: listMap.upsMonitorList,
  },
])
const currentMenu = ref('temperatureHumidity') // 当前选中的菜单
const currentIndex = ref(0) // 当前选中的菜单索引
const buttonBoxActive = 'labEquipmentConfigList' // 存储在sessionstorage里面的字段名,用于记录右上角buttonbox点击状态

// 查询条件
const listQuery: Ref<IListQuery> = ref({
  deptId: '', //	负责部门id(西昌组织下拉选择)
  deviceName: '', //	设备名称
  deviceNo: $route.query.deviceNo as string || '', //	设备编号
  labName: user.lab, //	所属实验室
  startResistance: undefined, //	起始内阻
  endResistance: undefined, //	结束内阻
  startTemperature: undefined, //	起始温度
  endTemperature: undefined, //	结束温度
  startVoltage: undefined, //	起始电压
  endVoltage: undefined, //	结束电压
  uploadEndTime: '', //	上传结束时间
  uploadStartTime: '', //	上传开始时间
  userId: '', //	负责人id(西昌组织下人员下拉选择)
  status: '', // 状态
  limit: 20,
  offset: 1,
})

const total = ref(0) // 数据总条数
const checkoutList = ref<string[]>([]) // 选中的内容
const dateRange = ref<[DateModelType, DateModelType]>(['', ''])// 筛选时间段数据
const normalTableRef = ref() // 表格ref
// -----------------------------------------字典--------------------------------------------------------------
const useDeptList = ref<deptType[]>([]) // 所属部门列表
const userList = ref<{ [key: string]: string }[]>([]) // 用户列表

const deptPid = ref('')
// 查询字典
const getDict = async () => {
  loadingTable.value = true
  // getDictByCode('bizFilterDeptId').then((response) => {
  //   // getDeptTreeList({ pid: response.data[0].value }).then((res) => {
  //   //   useDeptList.value = toTreeList(res.data, '0', true)
  //   // })
  //   deptPid.value = response.data[0].value // 此句话是甲方这边规定的计量站

  //   // deptPid.value = '0'
  // })
  // 获取用户列表
  getUserList({ offset: 1, limit: 999999 }).then((res: any) => {
    userList.value = res.data.rows
  })
  getAllDeptList().then((res) => {
    useDeptList.value = toTreeList(res.data.map((item: any) => ({ ...item, label: item.name, value: item.id }))) as any
  })
}
getDict()
// -----------------------------------------切换tab--------------------------------------------------------------
// 切换tab状态
const changeCurrentButton = (val: string) => {
  currentMenu.value = val // 当前
  currentIndex.value = menu.value.findIndex(item => item.id === val)
  console.log('当前选中的菜单', val, '当前选中菜单的索引', currentIndex.value)
  window.sessionStorage.setItem(buttonBoxActive, val)
  checkoutList.value = []
  // clearList()
  console.log('000111222')

  fetchData()
  if (normalTableRef.value) {
    normalTableRef.value!.clearMulti() // 清除多选选中
  }
}
// ------------------------------------------------------------------------------------------------------

// 多选发生改变时
function handleSelectionChange(e: any) {
  checkoutList.value = e.map((item: { id: string }) => item.id)
}

// 数据查询
function fetchData(isNowPage = false) {
  loadingTable.value = true
  if (!isNowPage) {
    // 是否显示当前页,否则跳转第一页
    listQuery.value.offset = 1
  }
  getDataList(listQuery.value, currentMenu.value).then((response) => {
    menu.value[currentIndex.value].list = response.data.rows.map((item: { deviceStatus: string; status: string; labName: string; resistance: string | number }) => {
      return {
        ...item,
        deviceStatusName: `${item.deviceStatus}` === '1' ? '在线' : `${item.deviceStatus}` === '0' ? '离线' : '未知',
        upsMonitorDeviceStatusName: `${item.status}` === '0' ? '正常' : `${item.status}` === '1' ? '异常' : '未知',
        params: '电池电压、电池电流...',
        resistance: item.labName === '海口实验室' ? '/' : item.resistance,
      }
    })
    total.value = parseInt(response.data.total)
    loadingTable.value = false
  })
}
// 清除条件
function clearList() {
  listQuery.value = {
    deptId: '', //	负责部门id(西昌组织下拉选择)
    deviceName: '', //	设备名称
    deviceNo: '', //	设备编号
    labName: user.lab, //	所属实验室
    startResistance: undefined, //	起始内阻
    endResistance: undefined, //	结束内阻
    startTemperature: undefined, //	起始温度
    endTemperature: undefined, //	结束温度
    startVoltage: undefined, //	起始电压
    endVoltage: undefined, //	结束电压
    uploadEndTime: '', //	上传结束时间
    uploadStartTime: '', //	上传开始时间
    userId: '', //	负责人id(西昌组织下人员下拉选择)
    status: '', // 状态
    limit: 20,
    offset: 1,
  }
  dateRange.value = ['', '']
  fetchData()
}
// 搜索
const searchList = () => {
  fetchData(true)
}

// 页数发生变化后的操作,可能是页码变化,可能是每页容量变化,此函数必写
const changePage = (val: { size?: number; page?: number }) => {
  if (val && val.size) {
    listQuery.value.limit = val.size
  }
  if (val && val.page) {
    listQuery.value.offset = val.page
  }
  fetchData(true)
}

// 导出
const exportAll = () => {
  const loading = ElLoading.service({
    lock: true,
    text: '下载中请稍后',
    background: 'rgba(255, 255, 255, 0.8)',
  })
  if (menu.value[currentIndex.value].list.length > 0) {
    const params = {
      deptId: listQuery.value.deptId, //	负责部门id(西昌组织下拉选择)
      deviceName: listQuery.value.deviceName, //	设备名称
      deviceNo: listQuery.value.deviceNo, //	设备编号
      labName: listQuery.value.labName, //	所属实验室
      startResistance: listQuery.value.startResistance, //	起始内阻
      endResistance: listQuery.value.endResistance, //	结束内阻
      startTemperature: listQuery.value.startTemperature, //	起始温度
      endTemperature: listQuery.value.endTemperature, //	结束温度
      startVoltage: listQuery.value.startVoltage, //	起始电压
      endVoltage: listQuery.value.endVoltage, //	结束电压
      uploadEndTime: listQuery.value.uploadEndTime, //	上传结束时间
      uploadStartTime: listQuery.value.uploadStartTime, //	上传开始时间
      userId: listQuery.value.userId, //	负责人id(西昌组织下人员下拉选择)
      status: listQuery.value.status, // ups监测列表状态
      offset: 1,
      limit: 20,
      ids: checkoutList.value,
    }
    exportDataList(params, currentMenu.value).then((res) => {
      const blob = new Blob([res.data])
      loading.close()
      exportFile(blob, `${menu.value[currentIndex.value].name}数据列表.xlsx`)
    })
  }
  else {
    loading.close()
    ElMessage.warning('无数据可导出数据')
  }
}

// ---------------------------------ups检测详情------------------------------------------------
const upsMonitorDetailDialogRef = ref() // ups检测详情组件ref
// 点击详情
const checkDetail = (id: string) => {
  upsMonitorDetailDialogRef.value.initDialog(id)
}

// 点击列表单元格
const cellClick = (row: any, column: any) => {
  if (column.property === 'params' && row.id) {
    upsMonitorDetailDialogRef.value.initDialog(row.id)
  }
}
// ---------------------------------------钩子----------------------------------------------
watch(dateRange, (val) => {
  if (val) {
    listQuery.value.uploadStartTime = `${val[0]}`
    listQuery.value.uploadEndTime = `${val[1]}`
  }
  else {
    listQuery.value.uploadStartTime = ''
    listQuery.value.uploadEndTime = ''
  }
})
onMounted(async () => {
  listQuery.value.deviceNo = $route.query.deviceNo ? $route.query.deviceNo as string : ''
  if ($route.query.deviceTypeName === '烟雾报警器') {
    currentMenu.value = 'smoke' // 当前选中的菜单
    currentIndex.value = 3 // 当前选中的菜单索引
  }
  else if ($route.query.deviceTypeName === '温湿度网络传感器') {
    currentMenu.value = 'temperatureHumidity' // 当前选中的菜单
    currentIndex.value = 0 // 当前选中的菜单索引
  }
  else if ($route.query.deviceTypeName === '智能电量仪') {
    currentMenu.value = 'electricQuantity' // 当前选中的菜单
    currentIndex.value = 1 // 当前选中的菜单索引
  }
  else if ($route.query.deviceTypeName === '氧气传感器') {
    currentMenu.value = 'oxygen' // 当前选中的菜单
    currentIndex.value = 2 // 当前选中的菜单索引
  }
  else if ($route.query.deviceTypeName === 'UPS电源') {
    currentMenu.value = 'ups' // 当前选中的菜单
    currentIndex.value = 4// 当前选中的菜单索引
  }
  else if ($route.query.deviceTypeName === 'UPS检测') {
    currentMenu.value = 'ups/monitor' // 当前选中的菜单
    currentIndex.value = 5// 当前选中的菜单索引
  }
  // setTimeout(() => {
  //   fetchData()
  // }, 3000)
})
</script>

<template>
  <!-- 布局 -->
  <app-container>
    <search-area :need-clear="true" @search="searchList" @clear="clearList">
      <search-item>
        <el-input v-model.trim="listQuery.deviceNo" placeholder="设备编号" class="short-input" clearable />
      </search-item>
      <!-- <search-item>
        <el-input v-model.trim="listQuery.deviceName" placeholder="设备名称" class="short-input" clearable />
      </search-item> -->
      <search-item>
        <!-- <dept-select
          v-model="listQuery.deptId"
          :data="useDeptList"
          placeholder="负责部门"
          class="short-input"
          :need-top="false"
          clearable
          filterable
        /> -->
        <el-tree-select
          v-model="listQuery.deptId"
          :data="useDeptList"
          :render-after-expand="false"
          check-strictly
          class="short-input"
          placeholder="负责部门"
          clearable
        />
      </search-item>
      <search-item>
        <el-select
          v-model="listQuery.userId"
          placeholder="负责人"
          class="short-input"
          filterable
          clearable
        >
          <el-option v-for="item in userList" :key="item.id" :label="item.name" :value="item.id" />
        </el-select>
      </search-item>
      <search-item v-if="currentMenu === 'ups' || currentMenu === 'ups/monitor'">
        <el-select
          v-model="listQuery.labName"
          placeholder="所属实验室"
          class="short-input"
          filterable
          clearable
        >
          <el-option v-for="item in ['西昌实验室', '海口实验室']" :key="item" :label="item" :value="item" />
        </el-select>
      </search-item>
      <search-item v-if="currentMenu === 'ups'">
        <el-input-number v-model="listQuery.startVoltage" placeholder="电压下限" :step="1" :precision="0" />
      </search-item>
      <search-item v-if="currentMenu === 'ups'">
        <el-input-number v-model="listQuery.endVoltage" placeholder="电压上限" :step="1" :precision="0" />
      </search-item>
      <search-item v-if="currentMenu === 'ups'">
        <el-input-number v-model="listQuery.startResistance" placeholder="内阻下限" :step="1" :precision="0" />
      </search-item>
      <search-item v-if="currentMenu === 'ups'">
        <el-input-number v-model="listQuery.endResistance" placeholder="内阻上限" :step="1" :precision="0" />
      </search-item>
      <search-item v-if="currentMenu === 'ups'">
        <el-input-number v-model="listQuery.startTemperature" placeholder="温度下限" :step="1" :precision="0" />
      </search-item>
      <search-item v-if="currentMenu === 'ups'">
        <el-input-number v-model="listQuery.endTemperature" placeholder="温度上限" :step="1" :precision="0" />
      </search-item>
      <search-item v-if="currentMenu === 'ups/monitor'">
        <el-select
          v-model="listQuery.status"
          placeholder="状态"
          class="short-input"
          filterable
          clearable
        >
          <el-option v-for="item in [{ name: '正常', value: '0' }, { name: '异常', value: '1' }]" :key="item.value" :label="item.name" :value="item.value" />
        </el-select>
      </search-item>
      <search-item>
        <el-date-picker
          v-model="dateRange"
          class="short-input"
          type="datetimerange"
          range-separator="至"
          format="YYYY-MM-DD HH:mm:ss"
          value-format="YYYY-MM-DD HH:mm:ss"
          start-placeholder="上传时间(开始)"
          end-placeholder="上传时间(结束)"
        />
      </search-item>
    </search-area>
    <table-container>
      <template #btns-right>
        <icon-button icon="icon-export" title="导出" type="primary" @click="exportAll" />
      </template>
      <normal-table
        ref="normalTableRef"
        :data="menu[currentIndex].list"
        :total="total"
        :columns="menu[currentIndex].columns"
        :query="listQuery"
        :list-loading="loadingTable"
        is-showmulti-select
        @change="changePage"
        @multi-select="handleSelectionChange"
        @cell-click="cellClick"
      >
        <template #preColumns>
          <el-table-column label="序号" width="80" align="center">
            <template #default="scope">
              {{ (listQuery.offset - 1) * listQuery.limit + scope.$index + 1 }}
            </template>
          </el-table-column>
        </template>
        <template v-if="currentMenu === 'ups/monitor'" #columns>
          <el-table-column
            label="操作"
            align="center"
            fixed="right"
            width="110"
          >
            <template #default="{ row }">
              <el-button
                size="small"
                link
                type="primary"
                @click="checkDetail(row.id)"
              >
                详情
              </el-button>
            </template>
          </el-table-column>
        </template>
      </normal-table>
    </table-container>
  </app-container>
  <!-- 右上角按钮集合 -->
  <button-box :active="currentMenu" :menu="menu" @change-current-button="changeCurrentButton" />
  <!-- ups监测详情 -->
  <ups-monitor-detail-dialog ref="upsMonitorDetailDialogRef" />
</template>