Newer
Older
adminAccountabilityFront / src / views / result / statistics / statistics.vue
wangxitong on 26 Sep 2023 6 KB 3,4
<script lang="ts" name="Statistics" setup>
import { getCurrentInstance, ref } from 'vue'
import type { Ref } from 'vue'
import type { DateModelType } from 'element-plus'
import dayjs from 'dayjs'
import BarChartVertical from '@/components/Echart/BarChartVertical.vue'
import type { lineDataI } from '@/components/Echart/echart-interface'
import PieChart from '@/components/Echart/PieChart.vue'
import { dataTotal, deptRanking, levelAnalysis } from '@/api/home/result/dept'

// 每个展示块高度
const blockHeight = ref(300)
const blockWidth = ref(400)
const tableLoading = ref(false)
const chartLoading = ref(false)
const showType = ref('柱状图')

const timeRange = ref<[DateModelType, DateModelType]>(['', ''])

// 默认查询条件
const defaultQuery = {
  stationId: '',
  monitorId: '',
  startTime: '',
  endTime: '',
}
const listQuery = reactive({ ...defaultQuery })
const data = ref({})

const tableData = ref<any[]>([])
// 设备台账检定提醒表头
const tableHead = [
  { text: '考核单位', value: 'assessedDeptName' },
  { text: '综合得分', value: 'score' },
  { text: '考核等级', value: 'recoRatingName' },
]

const total = ref(20)
const barXData: Ref<string[]> = ref([])
const barData: Ref<lineDataI[]> = ref([])
const alarmTypeYDataMax = ref()
const pieTypeData: Ref<any[]> = ref([])

// 搜索按钮
function search() {
  if (timeRange.value) {
    listQuery.startTime = timeRange.value[0] as string || ''
    listQuery.endTime = timeRange.value[1] as string || ''
  }
  // 排名
  deptRanking(listQuery).then((res) => {
    tableData.value = res.data
  })
  levelAnalysis(listQuery).then((res) => {
    console.log(res)
    const yValue = res.data.map((item: any) => Number(item.value))
    alarmTypeYDataMax.value = Math.max(yValue) > 10 ? Math.max(yValue) : 10
    barXData.value = res.data.map((item: any) => item.name)
    barData.value = [{ name: '个数', data: yValue }]
    pieTypeData.value = res.data
    chartLoading.value = false
  })
}

// 搜索重置
function clear() {
  Object.assign(listQuery, defaultQuery)
  listQuery.startTime = dayjs(Date.now() - 7 * 24 * 60 * 60 * 1000).format('YYYY-MM-DD')
  listQuery.endTime = dayjs().format('YYYY-MM-DD')
  timeRange.value = [listQuery.startTime, listQuery.endTime]
  search()
}

function calcBlockSize() {
  // 计算工作台区域高度 - 顶部-面包屑-边距
  const bodyHeight = document.body.clientHeight - 60 - 50 - 20
  blockHeight.value = bodyHeight - 160
  blockWidth.value = (document.body.clientWidth - 180 - 20 - 20)
}

window.addEventListener('resize', () => {
  calcBlockSize()
})

onBeforeMount(() => {
  calcBlockSize()
})
onMounted(() => {
  listQuery.startTime = dayjs(Date.now() - 7 * 24 * 60 * 60 * 1000).format('YYYY-MM-DD')
  listQuery.endTime = dayjs().format('YYYY-MM-DD')
  timeRange.value = [listQuery.startTime, listQuery.endTime]
  dataTotal({}).then((res) => {
    data.value = res.data
  })
  search()
})
</script>

<template>
  <app-container>
    <div class="top-statistics">
      <div class="item">
        <el-icon class="card-panel-icon">
          <svg-icon name="icon-log" />
        </el-icon>
        <div class="item-text">
          <div class="num">{{data.planNum}}</div>
          <div>考核方案数</div>
        </div>
      </div>
      <div class="item">
        <el-icon class="card-panel-icon">
          <svg-icon name="icon-certi" />
        </el-icon>
        <div class="item-text">
          <div class="num">{{data.quotaNum}}</div>
          <div >一级考核指标数</div>
        </div>
      </div>
      <div class="item">
        <el-icon class="card-panel-icon">
          <svg-icon name="icon-case" />
        </el-icon>
        <div class="item-text">
          <div class="num">{{data.quotaDeptNum}}</div>
          <div >考核结果总数</div>
        </div>
      </div>
    </div>
    <search-area @search="search">
      <search-item>
        <el-date-picker
          v-model="timeRange" clearable end-placeholder="结束日期" format="YYYY-MM-DD"
          range-separator="到" start-placeholder="开始日期" type="daterange" value-format="YYYY-MM-DD"/>
      </search-item>
    </search-area>
    <div class="ranking" style="margin-top: 10px;">
      <el-row :gutter="10">
        <el-col :span="8">
          <bench-col
            v-loading="tableLoading" :height="blockHeight" :style="{ height: blockHeight }" icon="icon-book" path-url="" title="考核得分排行榜">
            <el-table :data="tableData" :height="blockHeight - 60" class="bench-table" header-row-class-name="bench-table-header" row-class-name="bench-table-row" stripe style="width: 100%; height: 100%;">
              <el-table-column align="center" label="排名" type="index" width="55" />
              <el-table-column v-for="item in tableHead" :key="item.value" :label="item.text" :prop="item.value" :width="item.width" align="center"/>
            </el-table>
          </bench-col>
        </el-col>
        <el-col :span="16">
          <bench-col v-loading="chartLoading" :height="blockHeight" icon="icon-line" title="考核等级分析">
            <el-radio-group v-model="showType" size="small" style="position: absolute;right: 20px;top: 10px;">
              <el-radio-button label="柱状图"/>
              <el-radio-button label="饼状图"/>
            </el-radio-group>
            <bar-chart-vertical
              v-show="showType === '柱状图'"
              :data="barData"
              :height="`${blockHeight - 50}px`"
              :width="`${blockWidth * 2 / 3 - 10}px`"
              :x-axis-data="barXData"
              title="考核等级分析柱状图" unit=""
            />
            <pie-chart
              v-show="showType === '饼状图'"
              :data="pieTypeData"
              :height="`${blockHeight - 50}px`"
              :radius="['0%', '70%']"
              :width="`${blockWidth * 2 / 3 - 10}px`"
              title="考核等级分析饼状图"
            />
          </bench-col>
        </el-col>
      </el-row>
    </div>
  </app-container>
</template>

<style lang="scss" scoped>
.ranking {
  width: 100%;
  height: 100%;
  box-sizing: border-box;
}
.top-statistics {
  display: flex;
  flex-wrap: wrap;
  flex-direction: row;
  justify-content: center;
  background-color: white;
  border-radius: 10px;
  margin-bottom: 10px;
  padding: 10px 0px;
}
.item {
  width: 33%;
  display: flex;
  justify-content: center;
  .item-text {
    margin-left: 10px;
    font-weight: bold;
    color: #333;
  }
  .card-panel-icon {
    font-size: 58px;
    color: #3d7dfe;
  }
  .num {
    margin-bottom: 4px;
    font-size: 20px;
    text-align: center;
    color: #3d7dfe;
  }
}
</style>

<style lang="scss">
.bench-table {
  .el-table__header-wrapper {
    border-radius: 8px;
  }
}

.bench-table-header {
  th {
    font-weight: normal;
    font-size: 14px;
  }
}

.bench-table-row {
  border-radius: 8px;
}
</style>