quanyawei
2023-10-08 889cddc1cf0cbd5518c8b03d58f473db74e771a0
src/views/reportForm/index.vue
@@ -1,399 +1,44 @@
<template>
  <div style="width:100%">
    <div class="topSelect">
      <div>
        <el-select v-model="value" placeholder="选择站点" style="width: 300px;">
          <el-option
            v-for="item in options"
            :key="item.value"
            :label="item.label"
            :value="item.value"
          />
        </el-select>
        <el-radio-group v-model="radio1" style="margin-left:20px">
          <el-radio-button label="时报" />
          <el-radio-button label="日报" />
          <el-radio-button label="周报" />
          <el-radio-button label="月报" />
          <el-radio-button label="自定义" />
        </el-radio-group>
        <el-date-picker
          v-if="dateDisplay"
          v-model="value1"
          style="width:400px"
          type="daterange"
          range-separator="至"
          start-placeholder="开始日期"
          end-placeholder="结束日期"
          value-format="yyyy-MM-dd"
        />
      </div>
      <el-button type="primary" @click="exportExcel()">报表导出</el-button>
    </div>
    <div class="topTitle">
      <el-table
        id="exportTab"
        :default-sort="{prop: 'rank', order: 'ascending'}"
        :data="tableData"
        border
        style="width: 100%"
        :stripe="true"
        @sort-change="changeTableSort"
      >
        <el-table-column
          prop="rank"
          label="排名"
        />
        <el-table-column
          prop="deviceName"
          label="设备"
          width="180"
        />
        <el-table-column
          prop="responsibleUnit"
          label="责任单位"
          width="180"
        />
        <el-table-column
          prop="time"
          label="时间"
          width="180"
        />
        <el-table-column
          prop="aqi"
          label="AQI"
          sortable
        />
        <el-table-column
          prop="comIndex"
          label="综合指数"
          width="130"
          sortable
        />
        <el-table-column
          prop="a34004"
          label="PM2.5"
          sortable
        />
        <el-table-column
          prop="a34002"
          label="PM10"
          sortable
        />
        <el-table-column
          prop="a21026"
          label="SO2"
          sortable
        />
        <el-table-column
          prop="a21004"
          label="NO2"
          sortable
        />
        <el-table-column
          prop="a21005"
          label="CO"
          sortable
        />
        <el-table-column
          prop="a05024"
          label="O3_8H"
          sortable
        />
      </el-table>
    </div>
  </div>
  <el-tabs
    v-model="activeName"
    type="card"
    @tab-click="handleClick"
    style="height: 100%"
  >
    <el-tab-pane name="first" label="基于因子展示">
      <keep-alive>
        <sensor />
      </keep-alive>
    </el-tab-pane>
    <el-tab-pane label="监测站数据展示" name="second">
      <keep-alive>
        <sensorday />
      </keep-alive>
    </el-tab-pane>
  </el-tabs>
</template>
<script>
// 这里可以导入其他文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)
// 例如:import《组件名称》from'《组件路径》';
import FileSaver from 'file-saver'
import XLSX from 'xlsx'
import sensor from '@/views/reportForm/sensor'
import sensorday from '@/views/reportForm/sensorday'
export default {
// import 引入的组件需要注入到对象中才能使用
  components: {},
  props: {},
  components: {
    sensor,
    sensorday,
  },
  data() {
    // 这里存放数据
    return {
      options: [],
      radio1: '',
      value: '',
      value1: '',
      reportType: 0,
      monitorPointId: 0,
      tableData: [],
      dateDisplay: false,
      newKey: 0,
      timearr: null
      // pickerOptions1: {
      //   disabledDate(time) {
      //     console.log(time)
      //     const curDate = this.value1[0] ? this.value1[0] : (new Date()).getTime()//  获取当前时间点
      //     const seven = 7 * 24 * 60 * 60 * 1000 // 设定7天日期  7天 * 24小时 * 60分钟 * 60秒 * 1000 = 7天的时间戳
      //     const sevenDays = curDate + seven//  当前时间点后的七天所处的日期
      //     return time.getTime() < Date.now() + 8.64e7 || time.getTime() > sevenDays + 8.64e7// 8.64e7 表示一天,明天之前包括明天不可选,只可选七天
      //   }
      // }
      activeName: 'first',
    }
  },
  // 计算属性 类似于data概念
  computed: {},
  // 监控data中的数据变化
  watch: {
    value(n, o) {
      this.monitorPointId = n
    },
    value1(n, o) {
      var timearr = this.getAll(n[0], n[1])
      if (timearr.length <= 7) {
        this.getReportForm(this.newKey)
      } else {
        this.$message({
          message: '日期天数不能大于7天',
          type: 'warning'
        })
      }
    },
    radio1(n, o) {
      // var newKey
      switch (n) {
        case '时报':
          this.newKey = 0
          break
        case '日报':
          this.newKey = 1
          break
        case '周报':
          this.newKey = 2
          break
        case '月报':
          this.newKey = 3
          break
        case '自定义':
          this.newKey = 4
          break
        default:
          this.newKey = 4
          break
      }
      if (this.newKey === 4) {
        this.dateDisplay = true
      } else {
        this.dateDisplay = false
      }
      // if (!this.newKey === 'custom') {
      this.getReportForm(this.newKey)
      // }
    }
  },
  // 生命周期 - 创建完成(可以访问当前 this 实例)
  created() {
    this.getMonitorPointId()
  },
  // 生命周期 - 挂载完成(可以访问 DOM 元素)
  mounted() {
  },
  beforeCreate() {}, // 生命周期 - 创建之前
  beforeMount() {}, // 生命周期 - 挂载之前
  beforeUpdate() {}, // 生命周期 - 更新之前
  updated() {}, // 生命周期 - 更新之后
  beforeDestroy() {}, // 生命周期 - 销毁之前
  destroyed() {}, // 生命周期 - 销毁完成
  activated() {},
  // 方法集合
  created() {},
  methods: {
    // 重新添加rank排名(当表格的排序条件发生变化的时候会触发该事件)
    changeTableSort() {
      var sortTableData = this.$refs.mytable.tableData
      // console.log(this.$refs.mytable.tableData, 111)
      for (let i = 0; i < sortTableData.length; i++) {
        sortTableData[i].rank = i + 1
      }
    handleClick(tab, event) {
      // console.log(tab, event)
    },
    // changeTableSort({ column, prop, order }) {
    //   var sortTableData = this.$refs.mytable.tableData
    //   for (let i = 0; i < sortTableData.length; i++) {
    //     sortTableData[i].rank = i + 1
    //   }
    // },
    // 计算自定义天数
    // 计算续住的总日期列表
    getAll(begin, end) {
      const arr1 = begin.split('-') // 这里可以换成/  就2020/01/1 这种
      const arr2 = end.split('-')
      const arr1_ = new Date()
      const arrTime = []
      // console.log(arr1, arr2, arr1_)
      arr1_.setUTCFullYear(arr1[0], arr1[1] - 1, arr1[2])
      const arr2_ = new Date()
      arr2_.setUTCFullYear(arr2[0], arr2[1] - 1, arr2[2])
      const unixDb = arr1_.getTime()
      const unixDe = arr2_.getTime()
      for (let k = unixDb; k <= unixDe;) {
        arrTime.push(this.datetimeparse(k, 'YY-MM-DD'))
        k = k + 24 * 60 * 60 * 1000
      }
      return arrTime
    },
    // 时间格式处理
    datetimeparse(timestamp, format, prefix) {
      if (typeof timestamp === 'string') {
        timestamp = Number(timestamp)
      }
      // 转换时区
      const currentZoneTime = new Date(timestamp)
      let currentTimestamp = currentZoneTime.getTime()
      const offsetZone = currentZoneTime.getTimezoneOffset() / 60 // 如果offsetZone>0是西区,西区晚
      let offset = null
      // 客户端时间与服务器时间保持一致,固定北京时间东八区。
      offset = offsetZone + 8
      currentTimestamp = currentTimestamp + offset * 3600 * 1000
      let newtimestamp = null
      if (currentTimestamp) {
        if (currentTimestamp.toString().length === 13) {
          newtimestamp = currentTimestamp.toString()
        } else if (currentTimestamp.toString().length === 10) {
          newtimestamp = currentTimestamp + '000'
        } else {
          newtimestamp = null
        }
      } else {
        newtimestamp = null
      }
      const dateobj = newtimestamp ? new Date(parseInt(newtimestamp)) : new Date()
      const YYYY = dateobj.getFullYear()
      const MM = dateobj.getMonth() > 8 ? dateobj.getMonth() + 1 : '0' + (dateobj.getMonth() + 1)
      const DD = dateobj.getDate() > 9 ? dateobj.getDate() : '0' + dateobj.getDate()
      const HH = dateobj.getHours() > 9 ? dateobj.getHours() : '0' + dateobj.getHours()
      const mm = dateobj.getMinutes() > 9 ? dateobj.getMinutes() : '0' + dateobj.getMinutes()
      const ss = dateobj.getSeconds() > 9 ? dateobj.getSeconds() : '0' + dateobj.getSeconds()
      let output = ''
      let separator = '/'
      if (format) {
        separator = format.match(/-/) ? '-' : '/'
        output += format.match(/yy/i) ? YYYY : ''
        output += format.match(/MM/) ? (output.length ? separator : '') + MM : ''
        output += format.match(/dd/i) ? (output.length ? separator : '') + DD : ''
        output += format.match(/hh/i) ? (output.length ? ' ' : '') + HH : ''
        output += format.match(/mm/) ? (output.length ? ':' : '') + mm : ''
        output += format.match(/ss/i) ? (output.length ? ':' : '') + ss : ''
      } else {
        output += YYYY + separator + MM + separator + DD
      }
      output = prefix ? (prefix + output) : output
      return newtimestamp ? output : ''
    },
    getTime() {
      if (this.form.beginTime && this.form.endTime) {
        var beginTime = this.formatTime(this.form.beginTime, 1)
        var endTime = this.formatTime(this.form.endTime, 1)
        var dateBegin = new Date(beginTime)
        var dateEnd = new Date(endTime)
        if (dateBegin.getTime() > dateEnd.getTime()) {
          this.form.beginTime = null
          this.form.endTime = null
          alert('开始时间不能大于结束时间!')
          return
        }
        this.difference(dateBegin, dateEnd)
      }
    },
    difference(dateBegin, dateEnd) {
      var dateDiff = dateEnd.getTime() - dateBegin.getTime()// 时间差的毫秒数
      var dayDiff = Math.ceil(dateDiff / (24 * 3600 * 1000))// 计算出相差天数
      this.form.alltime = dayDiff
    },
    // 导出报表
    exportExcel() {
      /* generate workbook object from table */
      var xlsxParam = { raw: true } // 导出的内容只做解析,不进行格式转换
      var wb = XLSX.utils.table_to_book(document.querySelector('#exportTab'), xlsxParam)
      /* get binary string as output */
      var wbout = XLSX.write(wb, { bookType: 'xlsx', bookSST: true, type: 'array' })
      try {
        FileSaver.saveAs(new Blob([wbout], { type: 'application/octet-stream' }), '站点数据表.xlsx')
      } catch (e) {
        if (typeof console !== 'undefined') {
          console.log(e, wbout)
        }
      }
      return wbout
    },
    // 请求站点信息
    getMonitorPointId() {
      this.$request({
        url: '/monitorPoint/queryAllMonitorPoints',
        method: 'get',
        params: {
          organizationId: this.$store.state.orgId
        }
      }).then((res) => {
        // console.log('请求站点的信息')
        // console.log(res)
        for (let i = 0; i < res.data.length; i++) {
          this.options.push({ value: res.data[i].id, label: res.data[i].name })
        }
      }).catch((err) => {
        console.log(err)
      })
    },
    // 请求报表数据
    getReportForm(key) {
      this.$request({
        url: '/dataDisplay/monitorPointDataDisplay',
        method: 'get',
        params: {
          monitorPointId: this.monitorPointId,
          reportType: key === 4 ? null : key,
          startTime: key === 4 ? this.value1[0] : null,
          endTime: key === 4 ? this.value1[1] : null
        }
      }).then((res) => {
        // console.log(res)
        if (res.code !== 0) {
          return
        }
        var tempData = res.data
        for (let i = 0; i < tempData.length; i++) {
          tempData[i].rank = i + 1
        }
        this.tableData = tempData
        // for (let i = 0; i < res.data.data.length; i++) {
        //   this.tableData.push({ ranking: this.defaultData[i].rank, name: this.defaultData[i].name, responsibleUnit: this.defaultData[i].responsibleUnit, time: this.defaultData[i].time, AQI: this.defaultData[i].AQI, compositeIndex: this.defaultData[i].compositeIndex, PM2_5: this.defaultData[i].PM2_5, PM10: this.defaultData[i].PM10, SO2: this.defaultData[i].SO2, NO2: this.defaultData[i].NO2, CO: this.defaultData[i].CO, O3: this.defaultData[i].O3 })
        // }
      }).catch((err) => {
        console.log(err)
      })
    }
  } // 如果页面有keep-alive缓存功能,这个函数会触发
  },
}
</script>
<style scoped lang="scss">
.topSelect{
    display: flex;
    margin-bottom: 20px;
    padding: 20px 15px 0 15px;
    display: flex;
    justify-content: space-between;
    span:first-child{
        flex: 1;
    }
    // div:last-child{
    //     width: 300px;
    //     line-height: 40px;
    //     padding-left: 6px;
    // }
}
.topTitle{
    display: flex;
    justify-content: space-between;
    margin-bottom: 20px;
    padding: 0 15px;
}
<style scoped>
</style>