From 17e751b24202b92c1fc59486741293ce199d6089 Mon Sep 17 00:00:00 2001
From: quanyawei <401863037@qq.com>
Date: Thu, 01 Feb 2024 10:18:14 +0800
Subject: [PATCH] fix:断线监控

---
 src/assets/icon/back.png           |    0 
 src/router/dynamicRouter.js        |    7 
 src/views/onlineRate/detailBox.vue |  462 +++++++++++++++++++++++++++++++++
 src/views/onlineRate/index.vue     |  354 +++++++++++++++++++++++++
 4 files changed, 823 insertions(+), 0 deletions(-)

diff --git a/src/assets/icon/back.png b/src/assets/icon/back.png
new file mode 100644
index 0000000..0d48b6e
--- /dev/null
+++ b/src/assets/icon/back.png
Binary files differ
diff --git a/src/router/dynamicRouter.js b/src/router/dynamicRouter.js
index b84d58a..933f131 100644
--- a/src/router/dynamicRouter.js
+++ b/src/router/dynamicRouter.js
@@ -161,6 +161,12 @@
   component: () => import('@/views/levelStatistic/index'),
   meta: { title: '���������������������', icon: 'example' }
 }
+const onlineRate = {
+  path: 'analyse/onlineRate',
+  name: 'onlineRate',
+  component: () => import('@/views/onlineRate/index'),
+  meta: { title: '������������', icon: 'example' }
+}
 
 const industryContributionRate = {
   path: 'analyse/industryContributionRate',
@@ -236,6 +242,7 @@
   showGovHourData: showGovHourData,
   cityAirRank: cityAirRank,
   levelStatistic: levelStatistic,
+  onlineRate: onlineRate,
   heatmap: heatmap,
   hexagon: hexagon,
   airPollutionCalendar: airPollutionCalendar,
diff --git a/src/views/onlineRate/detailBox.vue b/src/views/onlineRate/detailBox.vue
new file mode 100644
index 0000000..608c90c
--- /dev/null
+++ b/src/views/onlineRate/detailBox.vue
@@ -0,0 +1,462 @@
+<template>
+  <div>
+    <el-dialog
+      :title="title"
+      :visible.sync="visible"
+      top="30px"
+      width="1000px"
+      center
+      :before-close="close"
+      @closed="close"
+    >
+      <div>
+        <el-form
+          :inline="true"
+          style="text-align: center;"
+          :model="formInline"
+        >
+          <el-form-item>
+            <el-radio-group
+              v-model="time"
+              @change="changeDay"
+            >
+              <el-radio-button label="���" />
+              <el-radio-button label="������" />
+              <el-radio-button label="������" />
+            </el-radio-group>
+          </el-form-item>
+          <el-form-item label="������:">
+            <el-date-picker
+              v-model="selectTime"
+              type="datetimerange"
+              range-separator="���"
+              start-placeholder="������������"
+              end-placeholder="������������"
+              value-format="yyyy-MM-dd HH:mm"
+              :default-date="[macDate.startTime, macDate.endTime]"
+              :picker-options="pickerOptions"
+              @change="changeDay"
+            />
+          </el-form-item>
+        </el-form>
+      </div>
+      <div>
+        <div class="tit">
+          <p style="font-size:16px">
+            {{ macOnlineDetailData.code }}%
+          </p>
+          <div id="myPieChart" />
+        </div>
+
+        <div class="echartsBox">
+          <div class="myLineChartBox">
+            <div id="myLineChart" />
+            <div class="backIcon">
+              <img
+                v-if="lineType==='minute'"
+                src="../../assets/icon/back.png"
+                @click="renderBack"
+              >
+            </div>
+          </div>
+        </div>
+        <p style="margin-top: 0px;">
+          ������������������������������������������������������
+        </p>
+        <div>
+          <p style="font-size:16px">
+            ������
+          </p>
+          <el-table
+            :data="tableData"
+            border
+            max-height="200"
+            style="width: 100%"
+          >
+            <el-table-column
+              type="index"
+              label="������"
+              width="60"
+              align="center"
+              label-class-name="itemSpan"
+            />
+
+            <el-table-column
+              prop="endTime"
+              label="������������"
+              align="center"
+              label-class-name="itemSpan"
+            />
+            <el-table-column
+              prop="startTime"
+              label="������������"
+              align="center"
+              label-class-name="itemSpan"
+            />
+            <el-table-column
+              prop="mun"
+              label="������������"
+              align="center"
+              label-class-name="itemSpan"
+            />
+          </el-table>
+        </div>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import * as echarts from 'echarts'
+import dayjs from 'dayjs'
+export default {
+  props: {
+    visible: { type: Boolean, required: true },
+    macDate: { type: Object, required: true }
+  },
+  data () {
+    return {
+      title: '������',
+      formInline: {},
+      macOnlineDetailData: {},
+      time: '������',
+      selectTime: [],
+      startTime: '',
+      endTime: '',
+      tableData: [],
+      choiceDate: null,
+      chart: null,
+      pieChart: null,
+      type: 'hour',
+      lineType: 'hour',
+      // ������
+
+      pickerOptions: {
+        onPick: ({ maxDate, minDate }) => {
+          // ���������������������������������������������������
+          this.choiceDate = minDate.getTime()
+          // ������������������������������������������������������������
+          if (maxDate) this.choiceDate = ''
+        },
+        disabledDate: time => {
+          // ���������������������������
+          if (this.choiceDate) {
+            // 7���������������
+            const one = 6 * 24 * 3600 * 1000
+            // ������������ - one = 6���������
+            const minTime = this.choiceDate - one
+            // ������������ + one = 6���������
+            const maxTime = this.choiceDate + one
+            return (
+              time.getTime() < minTime ||
+              time.getTime() > maxTime ||
+              // ���������������������������������
+              time.getTime() > Date.now()
+            )
+          } else {
+            // ������������������������������������������������������������������
+            return time.getTime() > Date.now()
+          }
+        }
+      }
+    }
+  },
+  watch: {
+    time (newValue, oldValue) {
+      if (newValue === '���') {
+        this.type = 'day'
+      } else if (newValue === '������') {
+        this.type = 'hour'
+      } else if (newValue === '������') {
+        this.type = 'minute'
+      }
+    }
+  },
+  mounted () {
+    this.title = `${this.macDate.name}������`
+    this.startTime = this.macDate.startTime
+    this.endTime = this.macDate.endTime
+    this.$set(this.selectTime, 0, new Date(this.macDate.startTime))
+    this.$set(this.selectTime, 1, new Date(this.macDate.endTime))
+    this.getLineData()
+    this.getMacDetail()
+  },
+  beforeDestroy () {
+    if (!this.chart) {
+      return
+    }
+    this.chart.dispose()
+    this.myPieChart.dispose()
+    this.chart = null
+    this.myPieChart = null
+  },
+  methods: {
+    changeDay () {
+      this.startTime = !this.selectTime ? '' : dayjs(this.selectTime[0]).format('YYYY-MM-DD  HH:mm')
+      this.endTime = !this.selectTime ? '' : dayjs(this.selectTime[1]).format('YYYY-MM-DD  HH:mm')
+      this.getMacDetail()
+      if (this.type !== 'minute') {
+        this.getLineData()
+      }
+    },
+    initPieChart (pieChartData) {
+      let labelData = {
+        show: false,
+      }
+      if (pieChartData[0] > 0) {
+        labelData = {
+          show: true,
+          position: 'left',
+          normal: {
+            formatter: function (params) {
+              console.log('params22', params)
+              let onlineType = params.dataIndex === 0 ? '������' : '������'
+              return `${onlineType}: ${params.value}`
+            },
+            fontSize: 14, // ������������������
+            fontStyle: 'italic', // ������������������
+          },
+        }
+      }
+      let dom = document.getElementById('myPieChart')
+      let myChart = echarts.init(dom)
+      this.myPieChart = myChart
+      this.myPieChart.setOption({
+        grid: {
+          left: '40px', // ���������������
+          right: '5px', // ���������������
+        },
+        tooltip: {
+          trigger: 'item',
+          formatter: function (params) {
+            var value = params.value
+            let tip = params.dataIndex === 1 ? '������: ' + value : '������: ' + value
+            return tip
+          },
+        },
+        series: [
+          {
+            radius: 30,
+            center: ['30%', '50%'],
+            type: 'pie',
+            data: pieChartData,
+            label: labelData,
+          },
+        ],
+      }, true)
+    },
+    initChart (myChart, option, dom) {
+      myChart.setOption(option)
+      if (this.lineType === 'hour') {
+        myChart.on('click', (params) => {
+          console.log(params)
+          this.lineType = 'minute'
+          echarts.dispose(dom)
+          var myChart = echarts.init(dom)
+          let starTiem = params.data[0]
+          console.log('starTiem', dayjs(starTiem).format('YYYY.MM.DD  HH:mm:ss'))
+          let endTiem = dayjs(starTiem).add(1, 'hour')
+          this.getLineData(dayjs(starTiem).format('YYYY-MM-DD  HH:mm:ss'), dayjs(endTiem).format('YYYY-MM-DD  HH:mm:ss'), 'minute')
+          myChart.setOption(option, true)
+        })
+      }
+    },
+    renderBack () {
+      this.lineType = 'hour'
+      let dom = document.getElementById('myLineChart')
+      echarts.dispose(dom)
+      this.getLineData(this.startTime, this.endTime, this.lineType)
+    },
+    renderLine () {
+      let dom = document.getElementById('myLineChart')
+      let myChart = echarts.init(dom)
+      let option = this.getOption(
+        this.xData,
+        this.sData
+      )
+      this.initChart(myChart, option, dom)
+    },
+    getOption (xData, sData) {
+      let option = null
+      let minTime = xData[0]
+      let maxTime = xData[xData.length]
+      let interval = 3600 * 1000
+      if (this.type === 'minute') {
+        interval = 60 * 1000
+      }
+      console.log(minTime, maxTime)
+      option = {
+        grid: {
+          left: '40px', // ���������������
+          right: '5px', // ���������������
+        },
+        xAxis: {
+          type: 'time',
+          interval: interval,
+          axisTick: { show: false },
+          splitLine: { show: false },
+          axisLine: {
+            lineStyle: { width: 0 }
+          },
+          axisLabel: {
+            interval: interval,
+            interale: 0,
+          }
+        },
+        tooltip: {
+          trigger: 'item',
+          formatter: function (params) {
+            console.log(params)
+            var value = params.data[0]
+            let tip = params.value === 1 ? '������: ' + value : '������: ' + value
+            return tip
+          },
+        },
+        yAxis: {
+          axisLine: {show: true},
+          axisTick: {show: true},
+          splitLine: {show: true},
+          axisLabel: {
+            formatter: function (value) {
+              var texts = []
+              if (value === 0) {
+                texts.push('������')
+              } else if (value === 1) {
+                texts.push('������')
+              }
+              return texts
+            },
+          },
+          splitArea: {show: true},
+          show: true,
+          type: 'value',
+          splitNumber: 1,
+          min: 0,
+          max: 1,
+        },
+        dataZoom: [
+          {
+            height: 20, // ������������������������
+            type: 'slider', // type������������������������������������������slider������������������������������������inside���������������������������������������
+            xAxisIndex: 0, // ���������x���������������������x���������������������
+            filterMode: 'filter', // ���������������������������,'filter'���������������������������������������������������������������������������'weakFilter'���������������������������������������������������������������������������
+            start: 0, // ���������������������������������
+            end: 100, // ���������������������������������
+          },
+          {
+            type: 'inside',
+            xAxisIndex: 0,
+            filterMode: 'filter',
+            start: 0,
+            end: 100,
+          },
+        ],
+        series: [
+          {
+            data: sData,
+            type: 'line'
+          }
+        ]
+      }
+      return option
+    },
+    getLineData (startTime = this.startTime, endTime = this.endTime, type = this.type) {
+      this.$request({
+        url: '/onlineRate/detail',
+        method: 'get',
+        params: {
+          mac: this.macDate.mac,
+          startTime: startTime,
+          endTime: endTime,
+          type: type
+        }
+      })
+        .then(res => {
+          this.xData = res.data.lineChart1.map(item => {
+            return dayjs(item).format('YYYY-MM-DD HH:mm:ss')
+          })
+          let data = res.data.lineChart2
+          this.sData = data.map((item, index) => {
+            return [ this.xData[index], item ]
+          })
+          console.log(this.sData)
+          this.$nextTick(() => {
+            this.renderLine()
+          })
+        })
+        .catch(err => {
+          console.log(err)
+        })
+    },
+    getMacDetail () {
+      this.$request({
+        url: '/onlineRate/detail',
+        method: 'get',
+        params: {
+          mac: this.macDate.mac,
+          startTime: this.startTime,
+          endTime: this.endTime,
+          type: this.type
+        }
+      })
+        .then(res => {
+          this.macOnlineDetailData = res.data
+          this.tableData = res.data.tabulation
+          let pieChartData = [this.macOnlineDetailData.pieChart1, this.macOnlineDetailData.pieChart2]
+          this.initPieChart(pieChartData)
+        })
+        .catch(err => {
+          console.log(err)
+        })
+    },
+    close () {
+      this.$emit('update:visible', false)
+    }
+  }
+}
+</script>
+
+<style scoped lang="scss">
+.echartsBox{
+  // display: flex;
+   height: 360px;
+
+    .myLineChartBox {
+    width: 100%;
+    position: relative;
+    #myLineChart{
+      width: 100%!important;
+      height:360px;
+        left: -10px;
+        canvas {
+          width: 100%!important;
+        }
+    }
+  }
+}
+  #myPieChart {
+    height: 120px;
+    width: 400px!important;
+    canvas {
+      width: 100%!important;
+    }
+  }
+.backIcon{
+   position: absolute;
+    top: -10px;
+    right: 80px;
+    cursor: pointer;
+   img{
+    height: 40px;
+   }
+  }
+.tit{
+  position: relative;
+  #myPieChart{
+    float: right;
+    position: absolute;
+    left: 322px;
+    top: -40px;
+  }
+}
+</style>
diff --git a/src/views/onlineRate/index.vue b/src/views/onlineRate/index.vue
new file mode 100644
index 0000000..a8d6d0a
--- /dev/null
+++ b/src/views/onlineRate/index.vue
@@ -0,0 +1,354 @@
+<template>
+  <div class="main">
+    <div>
+      <el-form
+        :inline="true"
+        :model="formInline"
+        class="demo-form-inline"
+      >
+        <el-form-item label="������������:">
+          <el-select
+            v-model="formInline.organizationId"
+            placeholder="������������"
+          >
+            <el-option
+              v-for="(item,index) in orgData"
+              :key="index"
+              :label="item.name"
+              :value="item.id"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="������:">
+          <el-select
+            v-model="formInline.state"
+            clearable
+            placeholder="������������"
+          >
+            <el-option
+              label="������"
+              value="1"
+            />
+            <el-option
+              label="������"
+              value="0"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item>
+          <el-radio-group
+            v-model="time"
+          >
+            <el-radio-button label="������" />
+            <el-radio-button label="���1���" />
+            <el-radio-button label="���3���" />
+            <el-radio-button label="���5���" />
+            <el-radio-button label="���7���" />
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item label="������������:">
+          <el-date-picker
+            v-model="selectTime"
+            type="datetimerange"
+            range-separator="���"
+            start-placeholder="������������"
+            end-placeholder="������������"
+            value-format="yyyy-MM-dd HH:mm:ss"
+            :picker-options="pickerOptions"
+            @change="changeDay"
+          />
+        </el-form-item>
+        <el-form-item>
+          <el-button
+            type="primary"
+            @click="handleSearch"
+          >
+            ������
+          </el-button>
+        </el-form-item>
+      </el-form>
+    </div>
+    <div>
+      <p>���������������{{ tableData.length }}������������ {{ onlineData }}��������������� <span :class=" onlineRate<90 ?'redClor':'greenClor'">{{ onlineRate }}%</span></p>
+      <div>
+        <el-table
+          v-loading="loading"
+          :data="tableData"
+          max-height="700"
+          border
+          style="width: 100%"
+        >
+          <el-table-column
+            type="index"
+            label="������"
+            width="60"
+            align="center"
+            label-class-name="itemSpan"
+          />
+          <el-table-column
+            prop="mac"
+            label="mac���"
+            align="center"
+            label-class-name="itemSpan"
+          />
+          <el-table-column
+            prop="name"
+            label="������������"
+            align="center"
+            label-class-name="itemSpan"
+          >
+            <template #default="scope">
+              <el-button
+                type="text"
+                @click="handleDetail(scope.row)"
+              >
+                {{ scope.row.name }}
+              </el-button>
+            </template>
+          </el-table-column>
+          <el-table-column
+            prop="endTime"
+            label="������������������������"
+            align="center"
+            label-class-name="itemSpan"
+          />
+          <el-table-column
+            prop="startTime"
+            label="������������������������"
+            align="center"
+            label-class-name="itemSpan"
+          />
+          <el-table-column
+            prop="num"
+            label="������������"
+            width="90px"
+            label-class-name="itemSpan"
+            align="center"
+          />
+          <el-table-column
+            prop="onlineRate"
+            label-class-name="itemSpan"
+            label="���������"
+            width="100px"
+            align="center"
+          />
+          <el-table-column
+            prop="onlineTime"
+            label-class-name="itemSpan"
+            label="������������������"
+            width="120px"
+            align="center"
+          />
+          <el-table-column
+            prop="state"
+            label-class-name="itemSpan"
+            label="������"
+            width="80px"
+            align="center"
+          >
+            <template slot-scope="scope">
+              <el-button
+                v-if="scope.row.state === '0'"
+                style="color:red;font-size:15px"
+                type="text"
+              >
+                ������
+              </el-button>
+              <el-button
+                v-else
+                style="color:#67c23a;font-size:15px"
+                type="text"
+              >
+                ������
+              </el-button>
+            </template>
+          </el-table-column>
+          <!-- <el-table-column
+            prop="address"
+            align="center"
+            width="80px"
+            label-class-name="itemSpan"
+            label="������"
+          >
+            <template slot-scope="scope">
+              <el-button
+                size="mini"
+                type="text"
+                style="font-size:15px"
+                @click="handleDetail(scope.row)"
+              >
+                ������
+              </el-button>
+            </template>
+          </el-table-column> -->
+        </el-table>
+      </div>
+    </div>
+    <detailBox
+      v-if="handleShow"
+      :visible.sync="handleShow"
+      :mac-date="macDate"
+    />
+  </div>
+</template>
+
+<script>
+import dayjs from 'dayjs'
+import detailBox from '@/views/onlineRate/detailBox'
+export default {
+  components: {
+    detailBox
+  },
+  data () {
+    return {
+      formInline: {
+        organizationId: '',
+        startTime: dayjs().startOf('day').format('YYYY-MM-DD  HH:mm'),
+        endTime: dayjs().subtract(1, 'hour').format('YYYY-MM-DD  HH:mm')
+      },
+      time: '������',
+      selectTime: '',
+      macDate: {},
+      orgData: [],
+      tableData: [],
+      handleShow: false,
+      loading: false,
+      choiceDate: null,
+
+      // ������
+
+      pickerOptions: {
+        onPick: ({ maxDate, minDate }) => {
+          // ���������������������������������������������������
+          this.choiceDate = minDate.getTime()
+          // ������������������������������������������������������������
+          if (maxDate) this.choiceDate = ''
+        },
+        disabledDate: time => {
+          // ���������������������������
+          if (this.choiceDate) {
+            // 7���������������
+            const one = 6 * 24 * 3600 * 1000
+            // ������������ - one = 6���������
+            const minTime = this.choiceDate - one
+            // ������������ + one = 6���������
+            const maxTime = this.choiceDate + one
+            return (
+              time.getTime() < minTime ||
+              time.getTime() > maxTime ||
+              // ���������������������������������
+              time.getTime() > Date.now()
+            )
+          } else {
+            // ������������������������������������������������������������������
+            return time.getTime() > Date.now()
+          }
+        }
+      }
+    }
+  },
+  computed: {
+    onlineData () {
+      return this.tableData.filter(item => item.state !== '0').length || 0
+    },
+    onlineRate () {
+      return Math.floor((this.onlineData / this.tableData.length) * 100) || 0
+    }
+  },
+  watch: {
+    time (newValue, oldValue) {
+      let now = dayjs() // ������������������
+      if (newValue === '���1���') {
+        this.selectTime = []
+        this.formInline.startTime = now.subtract(1, 'day').format('YYYY-MM-DD  HH:mm') // ���������������������
+      } else if (newValue === '���3���') {
+        this.selectTime = []
+        this.formInline.startTime = now.subtract(3, 'day').format('YYYY-MM-DD  HH:mm') // ���������������������
+      } else if (newValue === '���5���') {
+        this.selectTime = []
+        this.formInline.startTime = now.subtract(5, 'day').format('YYYY-MM-DD  HH:mm') // ���������������������
+      } else if (newValue === '���7���') {
+        this.selectTime = []
+        this.formInline.startTime = now.subtract(7, 'day').format('YYYY-MM-DD  HH:mm') // ���������������������
+      } else if (newValue === '������') {
+        this.selectTime = []
+        this.formInline.startTime = now.format('YYYY-MM-DD  HH:mm')
+      }
+    }
+  },
+  created () {
+    this.getOrganizationId()
+  },
+  methods: {
+    changeDay () {
+      console.log(this.selectTime)
+      this.formInline.startTime = this.selectTime[0]
+      this.formInline.endTime = this.selectTime[1]
+      this.time = ''
+    },
+    handleDetail (row) {
+      console.log(row)
+      this.handleShow = true
+      this.macDate = row
+      this.macDate.startTime = this.formInline.startTime
+      this.macDate.endTime = this.formInline.endTime
+    },
+    handleSearch () {
+      if (this.formInline.organizationId !== '') {
+        this.loading = true
+        this.$request({
+          url: '/onlineRate/page',
+          method: 'post',
+          data: {
+            ...this.formInline
+          }
+        })
+          .then(res => {
+            this.tableData = res.data
+            this.loading = false
+          })
+          .catch(err => {
+            console.log(err)
+          })
+      } else {
+        this.$message.warning('���������������������������')
+      }
+    },
+    getOrganizationId () {
+      this.$request({
+        url: '/organization/getOrganizationId',
+        method: 'get'
+      })
+        .then(res => {
+          this.orgData = res.data
+        })
+        .catch(err => {
+          console.log(err)
+        })
+    },
+  },
+}
+</script>
+
+<style lang="scss" scoped>
+.main{
+  padding: 10px;
+  font-size: 18px;
+}
+/deep/.el-form-item__label{
+  font-size: 16px;
+}
+/deep/.itemSpan {
+  font-size: 15px;
+  color: rgba(16, 16, 16, 1);
+}
+ /deep/.cell{
+  font-size: 15px;
+}
+.redClor{
+  color: red;
+}
+.greenClor{
+  color:#67c23a;
+}
+</style>>

--
Gitblit v1.8.0