MrShi
昨天 39fc2d6754953e41a7334a2166347baacfcfb40a
admin/src/views/business/dangerStatic.vue
@@ -1,23 +1,76 @@
<template>
  <div class="main_app">
    <QueryForm v-model="filters" :query-form-config="queryFormConfig" @handleQuery="getData(1)" @clear="clear"
      @changeForm='changeForm'>
      <template #fastdate>
        <el-radio-group v-model="filters.fastdate" size="small" @input="changeForm">
          <el-radio-button label="0">当天</el-radio-button>
          <el-radio-button label="6">近7天</el-radio-button>
          <el-radio-button label="29">近30天</el-radio-button>
        </el-radio-group>
      </template>
    </QueryForm>
  <div class="main_app1">
    <div class="main_head">
      <div class="main_head_item blue">
        <span>{{totalList.total}}</span>
        <span>总隐患数</span>
      </div>
      <div class="main_head_item red">
        <span>{{totalList.waitDeal}}</span>
        <span>待处理</span>
      </div>
      <div class="main_head_item yellow">
        <span>{{totalList.dealFinish}}</span>
        <span>已整改</span>
      </div>
      <div class="main_head_item orange">
        <span>{{totalList.back}}</span>
        <span>已退回</span>
      </div>
      <div class="main_head_item darkBlue">
        <span>{{totalList.todayNew}}</span>
        <span>今日新增</span>
      </div>
    </div>
<!--    <QueryForm v-model="filters" :query-form-config="queryFormConfig" @handleQuery="getData(1)" @clear="clear"-->
<!--      @changeForm='changeForm'>-->
<!--      <template #fastdate>-->
<!--        <el-radio-group v-model="filters.fastdate" size="small" @input="changeRadio">-->
<!--          <el-radio-button label="0">当天</el-radio-button>-->
<!--          <el-radio-button label="6">近7天</el-radio-button>-->
<!--          <el-radio-button label="29">近30天</el-radio-button>-->
<!--        </el-radio-group>-->
<!--      </template>-->
<!--    </QueryForm>-->
    <div class="main_content">
      <div class="type_wrap">
        <div class="title">隐患类型统计</div>
        <div class="type" ref="typeRef"></div>
        <div class="title">本月隐患类型统计</div>
        <div v-show="typeList && typeList.length > 0" class="echart1" ref="typeRef"></div>
        <div v-show="typeList.length == 0" style="width: 100%;height: 100%;display: flex;align-items: center;justify-content: center;">
          <img style="width: 240px;" src="@/assets/images/default_homeimg.png" alt="">
        </div>
      </div>
      <div class="dept_wrap">
        <div class="title">隐患归属部门统计</div>
        <div class="dept" ref="deptRef"></div>
        <div class="title">本月隐患归属部门统计</div>
        <div v-show="deptList && deptList.length > 0" class="echart2" ref="deptRef"></div>
        <div v-show="deptList.length == 0" style="width: 100%;height: 100%;display: flex;align-items: center;justify-content: center;">
          <img style="width: 240px;" src="@/assets/images/default_homeimg.png" alt="">
        </div>
      </div>
    </div>
    <div class="main_table">
      <div class="main_table_echart">
        <div class="title">本年隐患趋势</div>
        <div id="echart3" v-show="yearList.length > 0"></div>
        <div style="width: 100%;height: 100%;display: flex;align-items: center;justify-content: center;" v-show="yearList.length === 0">
          <img style="width: 240px;" src="@/assets/images/default_homeimg.png" alt="">
        </div>
      </div>
      <div class="main_table_list">
        <div class="title">本月频繁发生隐患区域Top10</div>
        <div class="list_head">
          <div class="list_head_item">责任部门</div>
          <div class="list_head_item">隐患区域</div>
          <div class="list_head_item">隐患数量</div>
        </div>
        <div class="table_box">
          <div class="list_content" v-for="(item, index) in departmentList" :key="index">
            <div class="list_head_item">{{item.name}}</div>
            <div class="list_head_item">{{item.categoryName}}</div>
            <div class="list_head_item">{{item.total}}</div>
          </div>
        </div>
      </div>
    </div>
  </div>
@@ -25,14 +78,20 @@
<script>
import QueryForm from '@/components/common/QueryForm'
import echarts from 'echarts'
import * as echarts from 'echarts'
import { hiddenDangerDataPost } from '@/api/business/hiddenDanger'
import dayjs from 'dayjs'
export default {
  components: {
    QueryForm,
  },
  data() {
    return {
      filters: {},
      filters: {
        fastdate: '29',
        queryStartTime: '',
        queryEndTime: ''
      },
      queryFormConfig: {
        formItems: [
          {
@@ -40,16 +99,14 @@
            type: 'select',
            label: '状态',
            options: [
              { label: '访客申请', value: '0' },
              { label: '访客报备', value: '1' },
              { label: '用车申请', value: '2' },
              { label: '隐患随手拍', value: '3' },
              { label: '物流车申请', value: '6' }
              { label: '待处理', value: '0' },
              { label: '已处理', value: '1' },
              { label: '已退回', value: '2' },
            ]
          },
          {
            filed1: 'startDate',
            filed2: 'endDate',
            filed1: 'queryStartTime',
            filed2: 'queryEndTime',
            type: 'datetime',
            label: '提报时间'
          },
@@ -61,17 +118,297 @@
        ],
        online: true
      },
      typeList: [],
      deptList: [],
      totalList: {
        total: 0,
        waitDeal: 0,
        dealFinish: 0,
        back: 0,
        todayNew: 0
      },
      yearList: [],
      departmentList: []
    }
  },
  mounted() {
    this.changeRadio('29')
    this.initDept3()
    // this.getData()
  },
  methods: {
    getData(page) {
      console.log(this.filters)
    changeRadio(day) {
      const arr = [dayjs().subtract(day, 'day').format('YYYY-MM-DD') + ' 00:00:00', dayjs().format('YYYY-MM-DD') + ' 23:59:59']
      this.filters.queryStartTime = arr[0]
      this.filters.queryEndTime = arr[1]
      this.getData()
    },
    changeForm(form) {
      console.log(form)
    getData(page) {
      hiddenDangerDataPost({ ...this.filters }).then(res => {
        if (res) {
          this.totalList.total = res.total || 0
          this.totalList.waitDeal = res.waitDeal || 0
          this.totalList.dealFinish = res.dealFinish || 0
          this.totalList.back = res.back || 0
          this.totalList.todayNew = res.todayNew || 0
          this.yearList = res.yearList
          this.departmentList = res.departmentList.slice(0, 10)
          this.typeList = res.cateList || []
          this.deptList = res.departmentList || []
          this.$nextTick(() => {
            this.initType()
            this.initDept()
            this.initDept3()
          })
        }
      })
    },
    changeForm(e) {
      this.getData()
    },
    initType() {
      const myChart = echarts.init(document.querySelector('.echart1'))
      let total = 0
      this.typeList.forEach(i => {
        total += i.total
      })
      let colors = ['#d75a44', '#e39f4d', '#f0d05f', '#7ac7f6', '#4469ee', '#698af0','#86a2f1','#a1b4f6','#a0b5f5', '#9fb5f4', '#b6c7f7', '#c8d5f8']
      let option = {
        grid: {
          left: '0%',
          right: '0%',
          bottom: '0%',
          top: '0%',
          containLabel: true
        },
        title: [
          {
            text: '隐患总数',
            top: '46%',
            left: '45%',
            textStyle: {
              color: '#666666',
              fontSize: 13,
            },
          }, {
            text: total,
            top: '50%',
            left: '47.6%',
            textStyle: {
              color: '#080404',
              fontSize: 16,
              fontWeight: 'bold',
            },
          }],
        legend: {
          left: 'center',
          bottom: '8%',
          itemGap: 30,
          itemWidth: 30,
          icon: 'circle',
          formatter: (name) => {
            const item = this.typeList.filter((item) => item.name === name)[0]
            if (item) {
              return ` ${name} ${item.total} | ${item.rata}%`
            } else {
              return ` ${name} 0 | 0%`
            }
          }
        },
        series: [
          {
            type: 'pie',
            radius: ['34%', '50%'],
            label: {
              formatter: "{a|{b}}\n\n{c} | {d}%",
              rich: {
                a: {
                  color: '#333333',
                  fontSize: 14,
                  fontWeight: 500
                }
              }
            },
            labelLine: {
              showAbove: true,
              show: true,
              length: 24,
              length2: 64,
              lineStyle: {
                width: 2      // 线条宽度
              }
            },
            data: this.typeList.map((i, index) => {
              return {
                value: i.total,
                name: i.name,
                itemStyle: {
                  color: colors[index]
                }
              }
            })
          }
        ]
      }
      myChart.setOption(option)
      window.addEventListener('resize', function () { // 执行
        myChart.resize()
      })
    },
    initDept() {
      const myChart = echarts.init(document.querySelector('.echart2'))
      let option = {
        grid: {
          left: '10%',
          right: '10%',
          bottom: '10%',
          top: '20%',
          containLabel: true
        },
        xAxis: {
          type: 'category',
          data: this.deptList.map(i => i.name),
          axisLabel: {
            color: '#333333',
            fontSize: 14,
            fontWeight: 'bold'
          }
        },
        yAxis: {
          type: 'value',
          name: '隐患数',
          minInterval: 1,
          axisLine: {
            show: true,
          }
        },
        series: [
          {
            data: this.deptList.map(i => i.total),
            type: 'bar',
            barWidth: 40,
            itemStyle: {
              color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                { offset: 0, color: '#d75e45' }, // 渐变起始色
                { offset: 1, color: '#db924c' }  // 渐变终止色
              ])
            },
            label: {
              show: true,      // 显示标签
              position: 'top', // 让标签显示在柱子顶部
              color: '#666666',   // 文字颜色
              fontSize: 14,    // 文字大小
            }
          }
        ]
      }
      myChart.setOption(option)
      window.addEventListener('resize', function () { // 执行
        myChart.resize()
      })
    },
    initDept3() {
      if (this.yearList.length === 0) return
      const myChart = echarts.init(document.querySelector('#echart3'))
      let names = this.yearList.map(item => item.name)
      let datas = this.yearList.map(item => item.total)
      let option = {
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'line'
          }
        },
        grid: {
          left: '5%',
          right: '10%',
          bottom: '0%',
          top: '20%',
          containLabel: true
        },
        xAxis: {
          type: 'category',
          data: names
        },
        yAxis: {
          type: 'value',
          axisLine: {
            show: true
          },
          axisLabel: {
            formatter: function (value) {
              // 四舍五入到最近的整数
              return Math.round(value);
            }
          }
        },
        series: [
          {
            data: datas,
            type: 'line',
            areaStyle: {
              normal: {
                color: {
                  x: 0,
                  y: 0,
                  x2: 0,
                  y2: 1,
                  colorStops: [{
                    offset: 0,
                    color: '#207FF7' // 0% 处的颜色
                  }, {
                    offset: 1,
                    color: 'rgba(255,255,255,.2)' // 100% 处的颜色
                  }],
                  globalCoord: false // 缺省为 false
                }
              }
            },
            lineStyle: { // 线条样式
              color: {
                type: 'linear',
                x: 0,
                y: 0,
                x2: 0,
                y2: 1,
                colorStops: [{
                  offset: 0, color: '#207FF7' // 0% 处的颜色
                }, {
                  offset: 1, color: '#207FF7' // 100% 处的颜色
                }]
              },
              width: 2 // 线条粗细
            },
            symbol: 'circle',
            symbolSize: 10,
            itemStyle: {
              borderWidth: 1,
              borderColor: '#fff',
              color: '#207FF7'
            },
            smooth: false
          }
        ]
      }
      myChart.setOption(option)
      window.addEventListener('resize', function () { // 执行
        myChart.resize()
      })
    },
    clear() {
      this.filters = {}
      this.getData()
    }
  }
}
@@ -81,32 +418,181 @@
/*.main_app {
  height: 100%;
}*/
.main_content {
  display: flex;
  height: calc(100% - 110px);
  .title {
    font-weight: 600;
    font-size: 16px;
    color: #222222;
    margin-bottom: 20px;
    margin-top: 20px;
.main_app1 {
  width: 100%;
  height: calc(100% - 44px);
  overflow-y: auto;
  overflow-x: hidden;
  padding: 15px;
  box-sizing: border-box;
  background-color: #F4F7FC;
  .main_head {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 10px;
    background-color: #ffffff;
    padding: 20px;
    box-sizing: border-box;
    .blue {
      border-left: 8px solid #12BB8B;
    }
    .red {
      border-left: 8px solid #F6CF46;
    }
    .yellow {
      border-left: 8px solid #5DC9FB;
    }
    .orange {
      border-left: 8px solid #FF9E56;
    }
    .darkBlue {
      border-left: 8px solid #6B6EFF;
    }
    .main_head_item {
      width: 19%;
      height: 112px;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      box-sizing: border-box;
      border-radius: 5px;
      background: #F4F7FC;
      span {
        &:nth-child(1) {
          font-weight: 600;
          font-size: 30px;
          color: #222222;
        }
        &:nth-child(2) {
          font-weight: 400;
          font-size: 14px;
          color: #222222;
          margin-top: 10px;
        }
      }
    }
  }
  .type_wrap {
    flex: 5;
    flex-shrink: 0;
    border: 1px solid #E5E5E5;
    height: 100%;
    border-right: 12px solid #f7f7f7;
  .main_table {
    display: flex;
    align-items: start;
    justify-content: space-between;
    .main_table_echart {
      width: 64%;
      height: 400px;
      background-color: #ffffff;
      padding: 20px;
      box-sizing: border-box;
      .title {
        font-weight: 600;
        font-size: 16px;
        color: #222222;
      }
      #echart3 {
        width: 100%;
        height: calc(100% - 33px);
      }
    }
    .main_table_list {
      flex-shrink: 0;
      width: 35%;
      padding: 20px;
      box-sizing: border-box;
      background-color: #ffffff;
      .title {
        font-weight: 600;
        font-size: 16px;
        color: #222222;
      }
      .list_head {
        width: 100%;
        height: 50px;
        display: flex;
        align-items: center;
        background-color: #F7F7F7;
        border-left: 1px solid #DFE2E8;
        border-top: 1px solid #DFE2E8;
        margin-top: 15px;
        .list_head_item {
          flex: 1;
          height: 100%;
          display: flex;
          align-items: center;
          justify-content: center;
          font-size: 13px;
          color: #222222;
          border-right: 1px solid #DFE2E8;
        }
      }
      .table_box {
        width: 100%;
        border-bottom: 1px solid #DFE2E8;
        .list_content {
          width: 100%;
          height: 50px;
          display: flex;
          align-items: center;
          border-left: 1px solid #DFE2E8;
          border-top: 1px solid #DFE2E8;
          .list_head_item {
            flex: 1;
            height: 100%;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 13px;
            color: #222222;
            border-right: 1px solid #DFE2E8;
          }
        }
      }
    }
  }
  .dept_wrap {
    flex: 4;
    flex-shrink: 0;
    border: 1px solid #E5E5E5;
    height: 100%;
    padding-left: 20px;
  .main_content {
    display: flex;
    align-items: start;
    justify-content: space-between;
    height: 500px;
    margin-bottom: 10px;
    .title {
      font-weight: 600;
      font-size: 16px;
      color: #222222;
      /*margin-bottom: 20px;*/
    }
    .type_wrap {
      width: 49.5%;
      flex-shrink: 0;
      height: 100%;
      /*border-right: 12px solid #f7f7f7;*/
      background-color: #ffffff;
      padding: 20px;
      box-sizing: border-box;
      .echart1 {
        width: 100%;
        height: 100%;
      }
    }
    .dept_wrap {
      width: 49.5%;
      flex-shrink: 0;
      height: 100%;
      background-color: #ffffff;
      padding: 20px;
      box-sizing: border-box;
      .echart2 {
        width: 100%;
        height: 100%;
      }
    }
  }
}
</style>