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