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