Newer
Older
smartwell_front / src / views / home / device / count / components / bottom.vue
liyaguang on 16 Apr 7 KB 虚拟表格组件封装
<!--
  Description: 设备统计-管理单位设备统计和离线设备清单
  Author: 李亚光
  Date: 2023-08-22
 -->
<script lang="ts" setup name="DeptDeviceCount">
import { ElLoading, ElMessage, ElMessageBox } from 'element-plus'
import { getDeviceTypeListPage } from '@/api/home/device/type'
import { getDictByCode } from '@/api/system/dict'
import { exportOffDevice, getDeptDevice, getOfflineDevice } from '@/api/home/device/count'
import { exportFile } from '@/utils/exportUtils'
import layout from '@/views/home/alarm/count/components/layout.vue'
import useUserStore from '@/store/modules/user'
const userStore = useUserStore()
// 管理单位设备统计
const deptLoading = ref(true)
const xAxisData = ref([])
const data = ref<any[]>([])
// 获取数据
const fetchData = () => {
  deptLoading.value = true
  getDeptDevice().then((res) => {
    const deptList = [
      '高压管网',
      '第一分公司',
      '第二分公司',
      '第三分公司',
      '第四分公司',
      '第五分公司',
      '怀柔有限公司',
      '密云有限公司',
      '平谷有限公司',
      '延庆有限公司',
      '昌平有限公司',
      '房山有限公司',
    ]
    let arr = [] as any[]
    let data1 = []
    if (!userStore.roleTips.join().includes('admin')) {
      arr = res.data
      data1 = arr
    }
    else {
      arr = res.data.filter((item: any) => deptList.filter(citem => item.name.includes(citem)).length)
      data1 = [] as any[]
      deptList.forEach((item: string) => {
        const data = arr.filter((citem: any) => citem.name.includes(item))
        if (data.length) {
          data1.push(data[0])
        }
      })
    }

    xAxisData.value = data1.filter((item: any) => Number(item.value)).map((item: any) => item.name)
    data.value = [
      {
        name: '设备数量',
        data: data1.filter((item: any) => Number(item.value)).map((item: any) => item.value),
      },
    ]
    deptLoading.value = false
  }).catch(() => {
    deptLoading.value = false
  })
}
fetchData()

// 设备离线清单数据
const list = ref([])
const total = ref(0)
const loadingTable = ref(true)
const columns = ref([
  { text: '设备编号', value: 'devcode', align: 'center' },
  { text: '设备类型', value: 'devTypeName', align: 'center' },
  { text: '安装位号', value: 'tagNumber', align: 'center' },
  { text: '最新记录上传时间', value: 'lastTime', align: 'center', width: '185' },
  { text: '离线天数', value: 'offDays', align: 'center', width: '85' },
  { text: '离线原因预测', value: 'reasons', align: 'center', width: '120' },
])
const listQuery = ref({
  devcode: '',
  devTypeId: '',
  reasons: '',
  limit: 20,
  offset: 1,
})
// 查询列表
const fetchListData = () => {
  loadingTable.value = true
  getOfflineDevice(listQuery.value).then((res) => {
    list.value = []
    total.value = res.data.total
    list.value = res.data.rows
    loadingTable.value = false
  }).catch(() => {
    loadingTable.value = false
  })
}
fetchListData()
// 重置搜索条件
const reset = () => {
  listQuery.value = {
    devcode: '',
    devTypeId: '',
    reasons: '',
    limit: 20,
    offset: 1,
  }
  fetchListData()
}
// 页数发生变化后的操作,可能是页码变化,可能是每页容量变化,此函数必写
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
  }
  fetchListData()
}
const deviceTypeList = ref<{ id: string; name: string; value: string }[]>([]) // 设备类型
const reasonsList = ref<{ id: string; name: string; value: string }[]>([]) // 离线原因
// 获取字典
const fetchDict = () => {
  // 设备类型
  getDeviceTypeListPage({ limit: 9999, offset: 1 }).then((res) => {
    deviceTypeList.value = res.data.rows.map((item: any) => ({ id: item.id, name: item.typeName, value: item.id }))
  })
  getDictByCode('reasonsOffline').then((res) => {
    reasonsList.value = res.data
  })
}
fetchDict()
const { proxy } = getCurrentInstance() as any

// 导出列表
const exportList = () => {
  if (!list.value.length) {
    ElMessage.warning('暂无导出数据')
    return
  }
  const loading = ElLoading.service({
    lock: true,
    background: 'rgba(255, 255, 255, 0.8)',
  })
  exportOffDevice(listQuery.value).then((res) => {
    exportFile(res.data, '离线设备清单.xlsx')
    loading.close()
  }).catch(() => {
    loading.close()
  })
}
</script>

<template>
  <div class="header-container">
    <!-- 管理单位设备统计 -->
    <layout class="header-left" title="管理单位设备统计">
      <template #content>
        <div v-loading="deptLoading" class="content">
          <bar-chart-vertical :x-axis-data="xAxisData" :bar-coner="0" :data="data" :colors="[]" :bar-width="15"
            :legend="{ itemWidth: 8, itemHeight: 8, type: 'scroll', orient: 'horizontal', icon: 'roundRect', right: '0', top: '10' }" />
        </div>
      </template>
    </layout>
    <!-- 离线设备清单 -->
    <layout class="header-right" title="离线设备清单">
      <template #content>
        <div class="content">
          <search-area :need-clear="true" @search="fetchListData" @clear="reset">
            <search-item>
              <el-input v-model.trim="listQuery.devcode" placeholder="设备编号" clearable />
            </search-item>
            <search-item>
              <el-select v-model="listQuery.devTypeId" placeholder="设备类型" clearable class="select">
                <el-option v-for="item in deviceTypeList" :key="item.id" :label="item.name" :value="item.value" />
              </el-select>
            </search-item>
            <search-item>
              <el-select v-model="listQuery.reasons" placeholder="离线原因" clearable class="select">
                <el-option v-for="item in reasonsList" :key="item.id" :label="item.name" :value="item.value" />
              </el-select>
            </search-item>
          </search-area>
          <table-container>
            <template #btns-right>
              <!-- 操作 -->
              <div>
                <el-button v-if="proxy.hasPerm('/device/count/offline/export')" type="primary" @click="exportList">
                  导出
                </el-button>
              </div>
            </template>
            <normal-table :data="list" :total="total" :columns="columns" :height="200" :query="listQuery"
              :list-loading="loadingTable" @change="changePage">
              <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>
            </normal-table>
          </table-container>
        </div>
      </template>
    </layout>
  </div>
</template>

<style lang="scss" scoped>
.header-container {
  display: flex;
  justify-content: space-between;

  .header-left {
    width: 49%;
    box-sizing: border-box;
    padding: 10px;

    .title {
      font-weight: 700;
      font-size: 18px;
      border-bottom: 1px solid #ccc;
      padding-bottom: 5px;
    }

    .content {
      height: 370px;
    }
  }

  .header-right {
    width: 50%;
    box-sizing: border-box;
    padding: 10px;

    .title {
      font-weight: 700;
      font-size: 18px;
      border-bottom: 1px solid #ccc;
      padding-bottom: 5px;
    }

    // .content {
    //   // display: flex;
    //   // padding: 10px;
    // }
  }
}
</style>

<style>
.select {
  width: 162px !important;
}
</style>