From c6159b0a5a424250adeca1bc2b475da5324fe038 Mon Sep 17 00:00:00 2001 From: web <candymxq888@outlook.com> Date: 星期五, 18 四月 2025 17:16:30 +0800 Subject: [PATCH] fix:对接报表数据 --- src/views/screen/flow/ecology/index.vue | 2 src/main.js | 4 src/views/screen/flow/warning/index.vue | 120 ++++--- src/api/screen/video.js | 36 ++ src/api/screen/warning/index.js | 12 src/utils/tool.js | 15 src/api/screen/statics/index.js | 24 + src/views/screen/flow/graphic/index.vue | 46 -- src/api/screen/graphic/index.js | 13 src/views/screen/temperature/statics/index.vue | 378 +++++++++++++++------- src/components/Quarter/index.vue | 1 src/views/screen/temperature/graphic/index.vue | 295 ++++++++++++------ 12 files changed, 623 insertions(+), 323 deletions(-) diff --git a/src/api/screen/graphic/index.js b/src/api/screen/graphic/index.js new file mode 100644 index 0000000..b414851 --- /dev/null +++ b/src/api/screen/graphic/index.js @@ -0,0 +1,13 @@ +import {publicRequest} from "@/utils/request.js"; + + +/** + * 获取水温监控报表 + */ +export const getGraphicData = (data) => { + return publicRequest({ + url: '/waterTemperature/getDataAnalyse', + method: 'post', + data + }) +} \ No newline at end of file diff --git a/src/api/screen/statics/index.js b/src/api/screen/statics/index.js new file mode 100644 index 0000000..7b157e0 --- /dev/null +++ b/src/api/screen/statics/index.js @@ -0,0 +1,24 @@ +import {publicRequest} from "@/utils/request.js"; + + +/** + * 获取水温统计数据 + */ +export const getStatisticsData = (data) => { + return publicRequest({ + url: '/waterTemperature/totalStatistics', + method: 'post', + data + }) +} + +/** + * 获取报警统计数据 + */ +export const getStatisticsAlarm = (data) => { + return publicRequest({ + url: '/waterTemperature/alarmTotalCount', + method: 'post', + data + }) +} \ No newline at end of file diff --git a/src/api/screen/video.js b/src/api/screen/video.js new file mode 100644 index 0000000..49a2848 --- /dev/null +++ b/src/api/screen/video.js @@ -0,0 +1,36 @@ +import { publicRequest } from '@/utils/request.js' + +// 根据小区id获取监控点 +export const getVideoList = (params) => { + return publicRequest({ + url: '/monitorVideoStreaming/getAllByPoint', + method: 'get', + params + }) +} + +// 开始视频点播 +export const getVideoMedia = (deviceId, channelId) => { + return publicRequest({ + url: `/monitorVideoStreaming/play/${deviceId}/${channelId}`, + method: 'get', + }) +} + + +// 视频停止点播 +export const stopVideoMedia = (deviceId, channelId) => { + return publicRequest({ + url: `/monitorVideoStreaming/stop/${deviceId}/${channelId}`, + method: 'get', + }) +} + + +// 继续点播 +export const renewVideoMedia = (deviceId, channelId) => { + return publicRequest({ + url: `/monitorVideoStreaming/updateEndTime/${deviceId}/${channelId}`, + method: 'get', + }) +} \ No newline at end of file diff --git a/src/api/screen/warning/index.js b/src/api/screen/warning/index.js index 5646bf6..735b2fd 100644 --- a/src/api/screen/warning/index.js +++ b/src/api/screen/warning/index.js @@ -35,4 +35,16 @@ method: 'get', params }) +} + + +/** + * 报警分析 + */ +export const getWarnChartsInfo = (data) => { + return publicRequest({ + url: '/waterFlow/alarmTotalCount', + method: 'post', + data + }) } \ No newline at end of file diff --git a/src/components/Quarter/index.vue b/src/components/Quarter/index.vue index a566bf3..abcd988 100644 --- a/src/components/Quarter/index.vue +++ b/src/components/Quarter/index.vue @@ -126,7 +126,6 @@ onMounted(() => { if (props.defaultValue) { - console.log(props.defaultValue) initDefaultValue(props.defaultValue); } }) diff --git a/src/main.js b/src/main.js index 5c07bd6..fcc2c55 100644 --- a/src/main.js +++ b/src/main.js @@ -36,12 +36,12 @@ // 按需引入echarts import * as echarts from 'echarts/core'; -import { GridComponent, ToolboxComponent, TooltipComponent, TitleComponent, VisualMapComponent, } from 'echarts/components'; +import { GridComponent, ToolboxComponent, TooltipComponent, TitleComponent, VisualMapComponent, LegendComponent } from 'echarts/components'; import { LineChart, BarChart } from 'echarts/charts'; import { UniversalTransition } from 'echarts/features'; import { CanvasRenderer } from 'echarts/renderers'; -echarts.use([GridComponent, LineChart, BarChart, CanvasRenderer, UniversalTransition, ToolboxComponent, TooltipComponent, TitleComponent, VisualMapComponent,]); +echarts.use([GridComponent, LineChart, BarChart, CanvasRenderer, UniversalTransition, ToolboxComponent, TooltipComponent, TitleComponent, VisualMapComponent, LegendComponent]); // 分页组件 import Pagination from '@/components/Pagination' diff --git a/src/utils/tool.js b/src/utils/tool.js new file mode 100644 index 0000000..ffc9bc7 --- /dev/null +++ b/src/utils/tool.js @@ -0,0 +1,15 @@ +//防抖(立即执行) +export function debounce(func, wait, immediate) { + let timeout; + return function(...args) { + const context = this; + const later = () => { + timeout = null; + if (!immediate) func.apply(context, args); + }; + const callNow = immediate && !timeout; + clearTimeout(timeout); + timeout = setTimeout(later, wait); + if (callNow) func.apply(context, args); + }; +} \ No newline at end of file diff --git a/src/views/screen/flow/ecology/index.vue b/src/views/screen/flow/ecology/index.vue index d274b14..e30b530 100644 --- a/src/views/screen/flow/ecology/index.vue +++ b/src/views/screen/flow/ecology/index.vue @@ -181,8 +181,8 @@ } onMounted(() => { - initCharts() getPoint() + initCharts() }) </script> diff --git a/src/views/screen/flow/graphic/index.vue b/src/views/screen/flow/graphic/index.vue index 8d5a773..4d3ba4d 100644 --- a/src/views/screen/flow/graphic/index.vue +++ b/src/views/screen/flow/graphic/index.vue @@ -124,49 +124,6 @@ </div> </div> </div> - <div class="item"> - <div class="title">新扎口流量监测点</div> - <div class="videoBox"></div> - <div class="info"> - <div class="info-list"> - <div class="info-item"> - <div class="name">水位:</div> - <div class="val"><span>2332</span>m</div> - </div> - <div class="info-item"> - <div class="name">表面流速:</div> - <div class="val"><span>4.5</span>m/s</div> - </div> - <div class="info-item"> - <div class="name">水面宽度:</div> - <div class="val"><span>100</span>m</div> - </div> - <div class="info-item"> - <div class="name">平均流速:</div> - <div class="val"><span>4.5</span>m/s</div> - </div> - <div class="info-item"> - <div class="name">过水面积:</div> - <div class="val"><span>30</span>㎡</div> - </div> - <div class="info-item"> - <div class="name">雷达流速:</div> - <div class="val"><span>4.5</span>m/s</div> - </div> - <div class="info-item"> - <div class="name">实时流速:</div> - <div class="val"><span>120</span>㎡/s</div> - </div> - <div class="info-item"> - <div class="name">起点距:</div> - <div class="val"><span>500</span>m</div> - </div> - </div> - <div class="info-btn"> - <el-button style="width: 6rem">抓拍</el-button> - </div> - </div> - </div> </div> </div> </div> @@ -264,8 +221,7 @@ .videoBox{ width: 100%; height: 60%; - background: url("@/assets/images/login_icon.png") no-repeat; - background-size: 100% 100%; + background-color: #000; } .info{ width: 100%; diff --git a/src/views/screen/flow/warning/index.vue b/src/views/screen/flow/warning/index.vue index be7ee3d..779de76 100644 --- a/src/views/screen/flow/warning/index.vue +++ b/src/views/screen/flow/warning/index.vue @@ -2,21 +2,24 @@ import {onMounted, ref, reactive} from "vue"; import * as echarts from 'echarts/core'; import Table from '@/components/Table/index.vue' -import { warnHistory, exportWarnHistory, editConfirm } from '@/api/screen/warning/index.js' +import { warnHistory, exportWarnHistory, editConfirm, getWarnChartsInfo } from '@/api/screen/warning/index.js' import { exportBlobFile } from '@/utils/index.js' import { ElMessage } from 'element-plus' const tableRef = ref(null) -const timeType = ref(0) +const timeType = ref(1) const warnChartRef = ref() const exportTime = ref() const searchData = reactive({ - createTimeRange: '' + createTimeRange: '', + monitorType: 2 }) const openDialog = ref(false) const dialogInfo = ref() const warnStatus = ref(0) + +const warnChartData = ref([]) let warnCharts = null; let tableHead = [ @@ -27,51 +30,60 @@ { prop: 'isConfirm', label: '报警确认', slot: true }, ] -const initWarnChart = () => { +const initWarnCgart = () => { if(warnChartRef.value) { warnCharts = echarts.init(warnChartRef.value); - const options = { - tooltip: { - trigger: 'axis', - }, - grid: { - top: 80, - left: 60, - right: 60, - bottom: 60 - }, - xAxis: { - type: 'category', - data: ['设备离线', '水位异常', '流量异常', '流速异常', '其他异常'], - axisLabel: { - color: '#fff', - fontSize: '1.2rem' - } - }, - yAxis: { - type: 'value', - name: '次', - nameTextStyle: { - color: '#fff', - fontSize: '1.2rem' - }, - axisLabel: { - color: '#fff', - fontSize: '1.2rem' - } - }, - series: [ - { - data: [36, 44, 38, 24, 63], - type: 'bar', - itemStyle: { - color: 'rgba(187,207,255,0.6)' - } - } - ] - } - warnCharts.setOption(options); } +} + +const updateWarnChart = () => { + let xdata = [] + let sdata = [] + warnChartData.value?.forEach(item => { + xdata.push(item.key) + sdata.push(item.value) + }) + const options = { + tooltip: { + trigger: 'axis', + }, + grid: { + top: 80, + left: 60, + right: 60, + bottom: 60 + }, + xAxis: { + type: 'category', + data: xdata, + axisLabel: { + color: '#fff', + fontSize: '1.2rem' + } + }, + yAxis: { + type: 'value', + name: '次', + nameTextStyle: { + color: '#fff', + fontSize: '1.2rem' + }, + axisLabel: { + color: '#fff', + fontSize: '1.2rem' + } + }, + series: [ + { + data: sdata, + type: 'bar', + itemStyle: { + color: 'rgba(187,207,255,0.6)' + } + } + ] + } + warnCharts.setOption(options); } const searchTable = () => { @@ -98,6 +110,7 @@ // 处理报警内容 const handleComfirm = () => { + if(!warnStatus.value) ElMessage.warning('请选择报警类型') editConfirm({ id: dialogInfo.value.id, status: warnStatus.value }).then(res => { ElMessage.success('提交成功') tableRef.value.getData() @@ -109,8 +122,17 @@ }) } +// 获取报警分析 +const getWarnCharts = () => { + getWarnChartsInfo({ type: timeType.value }).then(res => { + warnChartData.value = res.data + updateWarnChart() + }) +} + onMounted(() => { - initWarnChart() + initWarnCgart() + getWarnCharts() }) </script> @@ -120,10 +142,10 @@ <div class="item-t"> <div class="name">报警分析</div> <div class="select"> - <el-radio-group v-model="timeType"> + <el-radio-group v-model="timeType" @change="getWarnCharts"> <el-radio :value="1">日</el-radio> - <el-radio :value="2">月</el-radio> - <el-radio :value="3">年</el-radio> + <el-radio :value="3">月</el-radio> + <el-radio :value="5">年</el-radio> </el-radio-group> </div> </div> diff --git a/src/views/screen/temperature/graphic/index.vue b/src/views/screen/temperature/graphic/index.vue index 2fc797e..235ce02 100644 --- a/src/views/screen/temperature/graphic/index.vue +++ b/src/views/screen/temperature/graphic/index.vue @@ -1,56 +1,68 @@ <script setup> -import {ref, reactive, onMounted} from "vue"; +import {ref, onMounted, watch} from "vue"; import * as echarts from 'echarts/core'; -import html2canvas from "html2canvas"; import {getTemperaturePointList} from '@/api/screen/index.js' import Quarter from "@/components/Quarter"; import moment from "moment"; +import { getGraphicData } from '@/api/screen/graphic/index.js' const menuList = ref([]) -const timeType = ref('date') -const timeRange = ref() +const timeType = ref(1) //时间类型 1日 2周 3月 4季 5年 +const showTime = ref(moment().format('YYYY-MM-DD')); //展示时间 +const timeValue = ref(moment().format('YYYY-MM-DD')) //处理后得时间 const searchVal = ref() const graphicRef = ref(null) const chartsRef = ref([]) //动态生成图表ref +const chartData = ref([]) let charts = [] // 动态设置ref -const setChartsRef = (el ,index) => { - if(el){ +const setChartsRef = (el, index) => { + if (el) { chartsRef.value[index] = el charts[index] = 'charts' + index } } -const data = [ - [ {name: '一月', value: 22}, {name: '二月', value: 38}, {name: '三月', value: 31}, ], - [ {name: '一月', value: 22}, {name: '二月', value: 38}, {name: '三月', value: 31}, ], - [ {name: '一月', value: 22}, {name: '二月', value: 38}, {name: '三月', value: 31}, ], - [ {name: '一月', value: 22}, {name: '二月', value: 38}, {name: '三月', value: 31}, ], - [ {name: '一月', value: 22}, {name: '二月', value: 38}, {name: '三月', value: 31}, ], - [ {name: '一月', value: 22}, {name: '二月', value: 38}, {name: '三月', value: 31}, ], -] - // 获取图表配置 -const getChartsOptions = (data, unit, maxData, minData=0) => { +const getChartsOptions = (data, unit) => { let xdata = []; - let sdata = []; - if(data) { - data.forEach(item => { - xdata.push(item.name) - sdata.push(item.value); + let Hdata = []; + let Adata = []; + let Ldata = []; + if (data) { + data.dataVOList.forEach(item => { + xdata.push(item.dataTime) + Hdata.push(item.maxValue); + Adata.push(item.avgValue); + Ldata.push(item.minValue); }) } return { + title: { + text: data.pointName, + left: '3%', + textStyle: { + color: '#fff', + } + }, tooltip: { trigger: 'axis', }, + color: ['#D4B3E3FF', '#00DDFFFF', '#ABFA97FF'], + legend: { + top: 0, + data: ['最高水温', '平均水温', '最低水温'], + textStyle: { + color: '#fff' + } + }, grid: { - top: 50, - left: 50, - right: 50, - bottom: 40 + left: '4%', + right: '5%', + bottom: '3%', + containLabel: true }, xAxis: { type: 'category', @@ -64,6 +76,8 @@ yAxis: { type: 'value', name: unit, + max: 40, + min: 0, nameTextStyle: { color: '#fff', fontSize: '1rem' @@ -75,40 +89,75 @@ }, series: [ { - data: sdata, + name: '最高水温', + data: Hdata, type: 'line', - areaStyle: {}, - } - ], - visualMap: [ + areaStyle: { + opacity: 0.8, + color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ + { + offset: 0, + color: 'rgb(212,179,227)' + }, + { + offset: 1, + color: 'rgba(212,179,227,0)' + } + ]) + }, + }, { - type: 'piecewise', - show: false, - dimension: 1, - seriesIndex: 0, - pieces: [ - {max: minData, color: 'red'}, - { min: maxData, color: 'red'} - ], - outOfRange: { // 在选中范围外 的视觉元素,这里设置在正常范围内的图形颜色 - color: '#8EE5FA' - } + name: '平均水温', + data: Adata, + type: 'line', + areaStyle: { + opacity: 0.8, + color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ + { + offset: 0, + color: 'rgb(0, 221, 255)' + }, + { + offset: 1, + color: 'rgba(0,221,255,0)' + } + ]) + }, + }, + { + name: '最低水温', + data: Ldata, + type: 'line', + areaStyle: { + opacity: 0.8, + color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ + { + offset: 0, + color: 'rgb(171,250,151)' + }, + { + offset: 1, + color: 'rgba(171,250,151,0)' + } + ]) + }, } - ], + ] } } +// 选择时间类型 const changeType = (type) => { timeType.value = type; - timeRange.value = '' + showTime.value = '' } // 初始化图表 const initCharts = () => { - data.forEach((item, index) => { - if(chartsRef.value[index]) { + chartData.value.forEach((item, index) => { + if (chartsRef.value[index]) { charts[index] = echarts.init(chartsRef.value[index]) - const option = getChartsOptions(item, '℃', 35) + const option = getChartsOptions(item, '℃') charts[index].setOption(option) } }) @@ -121,19 +170,50 @@ // 一键导出 const handleExport = () => { - chartsRef.value?.forEach((item, index) => { - html2canvas(item, { - scale: 2, // 提高渲染质量 - useCORS: true, // 如果需要跨域资源 - allowTaint: true, // 如果需要处理跨域图片 - backgroundColor: 'rgba(23, 108, 229, 0.3)' //背景色 - }).then(canvas => { - const link = document.createElement("a"); - link.href = canvas.toDataURL("image/png"); - link.download = `图表分析${index}.png`; - link.click() - }) + charts?.forEach((chart, index) => { + const imgData = chart.getDataURL({ + type: 'png', // 也可以是 'jpeg' + pixelRatio: 2, // 提高导出图片的分辨率 + backgroundColor: 'rgba(23, 108, 229, 0.3)' + }); + + // 创建下载链接 + const link = document.createElement('a'); + link.href = imgData; + link.download = `chart_${index + 1}.png`; + link.click(); }) +} + +// 获取时间 +const getTime = (value) => { + const momentValue = moment(value) + const time = momentValue.format('YYYY-MM-DD') + let data = '' + switch (timeType.value) { + case 1: + data = '' + break; + case 2: + data = momentValue.add(1, 'week').format('YYYY-MM-DD') + break; + case 3: + data = momentValue.add(1, 'month').format('YYYY-MM-DD') + break; + case 4: + data = momentValue.add(1, 'quarter').format('YYYY-MM-DD') + break; + case 5: + data = momentValue.add(1, 'year').format('YYYY-MM-DD') + break; + default: + break; + } + if(data) { + timeValue.value = time + '~' + data + } else { + timeValue.value = time + } } // 获取水温监控点菜单 @@ -143,15 +223,24 @@ }) } -// 获取时间 -const getTime = (value) => { - const time = moment(value).format('YYYY-MM-DD') - console.log(time) +// 获取报表数据 +const getChartData = (point = '') => { + const data = { + type: timeType.value, + pointId: point, + pointName: searchVal.value, + dataTime: timeValue.value, + } + getGraphicData(data).then(async res => { + chartData.value = res.data + await nextTick() + initCharts() + }) } onMounted(() => { getTempMonitor() - initCharts() + getChartData() }) </script> @@ -160,7 +249,7 @@ <div class="graphic"> <div class="graphic-menu"> <div class="menu-t">监测点列表</div> - <el-menu class="el-menu"> + <el-menu class="el-menu" @select="getChartData"> <template v-for="(item, index) in menuList" :key="index+1"> <template v-if="item?.childrenList?.length === 0"> <el-menu-item :index="item.id">{{ item.pointName }}</el-menu-item> @@ -183,23 +272,28 @@ <div class="tool-l"> <div class="name">类型</div> <el-button-group class="ml-4"> - <el-button :type="timeType === 'date' ? 'primary' : ''" @click="changeType('date')">日</el-button> - <el-button :type="timeType === 'week' ? 'primary' : ''" @click="changeType('week')">周</el-button> - <el-button :type="timeType === 'month' ? 'primary' : ''" @click="changeType('month')">月</el-button> - <el-button :type="timeType === 'quarter' ? 'primary' : ''" @click="changeType('quarter')">季</el-button> - <el-button :type="timeType === 'year' ? 'primary' : ''" @click="changeType('year')">年</el-button> + <el-button :type="timeType === 1 ? 'primary' : ''" @click="changeType(1)">日 + </el-button> + <el-button :type="timeType === 2 ? 'primary' : ''" @click="changeType(2)">周 + </el-button> + <el-button :type="timeType === 3 ? 'primary' : ''" @click="changeType(3)">月 + </el-button> + <el-button :type="timeType === 4 ? 'primary' : ''" @click="changeType(4)">季 + </el-button> + <el-button :type="timeType === 5 ? 'primary' : ''" @click="changeType(5)">年 + </el-button> </el-button-group> <el-date-picker - v-if="timeType === 'date'" - v-model="timeRange" + v-if="timeType === 1" + v-model="showTime" type="date" placeholder="选择时间" style="width: 15rem" @change="getTime" /> <el-date-picker - v-if="timeType === 'week'" - v-model="timeRange" + v-if="timeType === 2" + v-model="showTime" type="week" format="YYYY年 ww[周]" placeholder="选择时间" @@ -207,43 +301,47 @@ @change="getTime" /> <el-date-picker - v-if="timeType === 'month'" - v-model="timeRange" + v-if="timeType === 3" + v-model="showTime" type="month" placeholder="选择时间" style="width: 15rem" @change="getTime" /> <Quarter - v-if="timeType === 'quarter'" + v-if="timeType === 4" placeholder="选择时间" - :default-value="timeRange" + :default-value="showTime" clearable style="width: 15rem" @change="getTime" /> <el-date-picker - v-if="timeType === 'year'" - v-model="timeRange" + v-if="timeType === 5" + v-model="showTime" type="year" placeholder="选择时间" style="width: 15rem" @change="getTime" /> - <el-input v-model="searchVal" style="width: 15rem" placeholder="请输入监测点名称" /> - <el-button><el-icon><Search /></el-icon>搜索</el-button> + <el-input v-model="searchVal" style="width: 15rem" clearable placeholder="请输入监测点名称"/> + <el-button @click="() => getChartData()"> + <el-icon> + <Search/> + </el-icon> + 搜索 + </el-button> <el-button type="success" @click="handleExport">一键导出</el-button> </div> <div class="tool-r" @click="handleFullScreen"> - <img src="@/assets/images/flow/fullscreen.png" /> + <img src="@/assets/images/flow/fullscreen.png"/> 全屏 </div> </div> <div class="graphic-box" ref="graphicRef"> <div class="chartList"> - <div class="chartItem" v-for="(item, index) in data"> + <div class="chartItem" v-for="(item, index) in chartData"> <div class="charts" :ref="el => setChartsRef(el, index)"></div> - <div class="name">标题</div> </div> </div> </div> @@ -255,6 +353,7 @@ .graphic { height: 100%; display: flex; + &-menu { flex-shrink: 0; width: 20%; @@ -294,10 +393,12 @@ } } } + .graphic-info { flex-shrink: 0; width: 80%; height: 100%; + .graphic-tool { width: 100%; height: 60px; @@ -327,29 +428,27 @@ } } } - .graphic-box{ + + .graphic-box { height: calc(100% - 60px); padding: 10px 30px; background: linear-gradient(180deg, #91BDDB 0%, rgba(102, 102, 102, 0.5) 100%); - .chartList{ + + .chartList { height: 100%; display: flex; flex-wrap: wrap; gap: 20px; - .chartItem{ - width: 32%; - height: 48%; - background: rgba(23,108,229,0.3); + + .chartItem { + width: 100%; + min-height: 48%; + background: rgba(23, 108, 229, 0.3); border: 1px solid #176CE5; border-radius: 8px; - .charts{ - height: 90%; - } - .name{ - height: 10%; - text-align: center; - font-size: 20px; - color: #fff; + + .charts { + height: 100%; } } } diff --git a/src/views/screen/temperature/statics/index.vue b/src/views/screen/temperature/statics/index.vue index bbc1fc9..e2a2350 100644 --- a/src/views/screen/temperature/statics/index.vue +++ b/src/views/screen/temperature/statics/index.vue @@ -1,133 +1,236 @@ <script setup> -import {onMounted, ref} from "vue"; +import {onMounted, ref, reactive} from "vue"; import * as echarts from 'echarts/core'; +import {getStatisticsData, getStatisticsAlarm} from '@/api/screen/statics/index.js' +import {getTemperaturePointList} from '@/api/screen/index.js' +import moment from "moment"; -const wenduType = ref(3) +const cascaderOption = { label: 'pointName', value: 'id', children: 'childrenList', expandTrigger: 'hover', emitPath: false }; //级联选择器配置 + +const menuList = ref([]) +const pointId = ref('') +const wendu = reactive({ + type: 1, + time: moment().format('YYYY-MM-DD'), + value: moment().format('YYYY-MM-DD'), + data: [] +}) +const warn = reactive({ + type: 1, + time: moment().format('YYYY-MM-DD'), + value: moment().format('YYYY-MM-DD'), + data: [] +}) + const wenduChartRef = ref() -let wenduCharts = null; -const wenduTimeValue = ref() -const shuiweiType = ref(3) const shuiweiChartRef = ref() +let wenduCharts = null; let shuiweiCharts = null -const shuiweiTimeValue = ref() const handleSelectType = (type) => { if(type === 'wendu') { - wenduTimeValue.value = 0 - } else if (type === 'shuiwei') { - shuiweiTimeValue.value = 0 + wendu.time = '' + wendu.value = '' + } else if (type === 'warn') { + warn.time = '' + warn.value = '' } } -const initwenduChart = () => { +const updatewenduChart = () => { + let xdata = [] + let sdata = [] + wendu.data[0]?.dataVOList?.length > 0 && wendu.data[0]?.dataVOList.forEach(item => { + xdata.push(item.dataTime) + sdata.push(item.avgValue) + }) + const options = { + tooltip: { + trigger: 'axis', + }, + grid: { + top: 80, + left: 60, + right: 60, + bottom: 60 + }, + xAxis: { + type: 'category', + boundaryGap: false, + data: xdata, + axisLabel: { + color: '#fff', + fontSize: '1.2rem' + } + }, + yAxis: { + type: 'value', + name: '℃', + nameTextStyle: { + color: '#fff', + fontSize: '1.2rem' + }, + axisLabel: { + color: '#fff', + fontSize: '1.2rem' + } + }, + series: [ + { + data: sdata, + type: 'line', + areaStyle: { + color: { + type: 'linear', + x: 0, + y: 0, + x2: 0, + y2: 1, + colorStops: [ + {offset: 0.2, color: 'rgba(0,255,255,0.5)' }, + {offset: 1, color: 'rgba(0,255,255,0.1)' }, + ], + global: false // 缺省为 false + } + } + } + ] + } + wenduCharts.setOption(options); +} + +const updatewarnChart = () => { + let xdata = [] + let sdata = [] + warn.data?.length > 0 && warn.data.forEach(item => { + xdata.push(item.key) + sdata.push(item.value) + }) + const options = { + tooltip: { + trigger: 'axis', + }, + grid: { + top: 80, + left: 60, + right: 60, + bottom: 60 + }, + xAxis: { + type: 'category', + data: xdata, + axisLabel: { + color: '#fff', + fontSize: '1.2rem' + } + }, + yAxis: { + type: 'value', + name: 'm', + nameTextStyle: { + color: '#fff', + fontSize: '1.2rem' + }, + axisLabel: { + color: '#fff', + fontSize: '1.2rem' + } + }, + series: [ + { + data: sdata, + type: 'bar', + itemStyle: { + color: '#BBCFFF' + } + } + ] + } + shuiweiCharts.setOption(options); +} + +// 获取时间 +const getTime = (value, type, types) => { + const momentValue = moment(value) + const time = momentValue.format('YYYY-MM-DD') + let data = '' + switch (type) { + case 1: + data = '' + break; + case 3: + data = momentValue.add(1, 'month').format('YYYY-MM-DD') + break; + case 5: + data = momentValue.add(1, 'year').format('YYYY-MM-DD') + break; + default: + break; + } + if(types === 'wendu') { + if(data) { + wendu.value = time + '~' + data + } else { + wendu.value = time + } + getTempData() + } else { + if(data) { + warn.value = time + '~' + data + } else { + warn.value = time + } + getalarmData() + } +} + +// 获取水温监控点菜单 +const getTempMonitor = () => { + getTemperaturePointList().then(res => { + menuList.value = res.data + pointId.value = res.data?.[0]?.childrenList?.[0]?.id + getTempData() + }) +} + +// 获取水温数据 +const getTempData = () => { + const data = { + type: wendu.type, + dataTime: wendu.value, + pointId: pointId.value + } + getStatisticsData(data).then(res => { + wendu.data = res.data + updatewenduChart() + }) +} + +// 获取报警数据 +const getalarmData = () => { + const data = { + type: warn.type, + dataTime: warn.value + } + getStatisticsAlarm(data).then(res => { + warn.data = res.data + updatewarnChart() + }) +} + +const initCharts = () => { if(wenduChartRef.value) { wenduCharts = echarts.init(wenduChartRef.value); - const options = { - tooltip: { - trigger: 'axis', - }, - grid: { - top: 80, - left: 60, - right: 60, - bottom: 60 - }, - xAxis: { - type: 'category', - boundaryGap: false, - data: ['设备离线', '水位异常', '流量异常', '流速异常', '其他异常'], - axisLabel: { - color: '#fff', - fontSize: '1.2rem' - } - }, - yAxis: { - type: 'value', - name: '℃', - nameTextStyle: { - color: '#fff', - fontSize: '1.2rem' - }, - axisLabel: { - color: '#fff', - fontSize: '1.2rem' - } - }, - series: [ - { - data: [36, 44, 38, 24, 36], - type: 'line', - areaStyle: { - color: { - type: 'linear', - x: 0, - y: 0, - x2: 0, - y2: 1, - colorStops: [ - {offset: 0.2, color: 'rgba(0,255,255,0.5)' }, - {offset: 1, color: 'rgba(0,255,255,0.1)' }, - ], - global: false // 缺省为 false - } - } - } - ] - } - wenduCharts.setOption(options); } -} - -const initshuiweiChart = () => { if(shuiweiChartRef.value) { shuiweiCharts = echarts.init(shuiweiChartRef.value); - const options = { - tooltip: { - trigger: 'axis', - }, - grid: { - top: 80, - left: 60, - right: 60, - bottom: 60 - }, - xAxis: { - type: 'category', - data: ['设备离线', '水位异常', '流量异常', '流速异常', '其他异常'], - axisLabel: { - color: '#fff', - fontSize: '1.2rem' - } - }, - yAxis: { - type: 'value', - name: 'm', - nameTextStyle: { - color: '#fff', - fontSize: '1.2rem' - }, - axisLabel: { - color: '#fff', - fontSize: '1.2rem' - } - }, - series: [ - { - data: [36, 44, 38, 24, 63], - type: 'bar', - itemStyle: { - color: '#BBCFFF' - } - } - ] - } - shuiweiCharts.setOption(options); } } onMounted(() => { - initwenduChart() - initshuiweiChart() + initCharts() + getTempMonitor() + getalarmData() }) </script> @@ -137,66 +240,73 @@ <div class="item-t"> <div class="name">水温汇总统计</div> <div class="select"> - <el-radio-group v-model="wenduType" @change="handleSelectType('wendu')"> + <el-cascader size="large" v-model="pointId" :options="menuList" :show-all-levels="false" :props="cascaderOption" clearable @change="getTempData" /> + <el-radio-group v-model="wendu.type" @change="handleSelectType('wendu')"> <el-radio :value="1">日</el-radio> - <el-radio :value="2">月</el-radio> - <el-radio :value="3">年</el-radio> + <el-radio :value="3">月</el-radio> + <el-radio :value="5">年</el-radio> </el-radio-group> </div> </div> <div class="charts" ref="wenduChartRef"></div> <div class="title"> <el-date-picker - v-if="wenduType === 1" - v-model="wenduTimeValue" + v-if="wendu.type === 1" + v-model="wendu.time" type="date" placeholder="请选择时间" + @change="(value) => getTime(value, wendu.type, 'wendu')" /> <el-date-picker - v-else-if="wenduType === 2" - v-model="wenduTimeValue" + v-else-if="wendu.type === 3" + v-model="wendu.time" type="month" placeholder="请选择时间" + @change="(value) => getTime(value, wendu.type, 'wendu')" /> <el-date-picker v-else - v-model="wenduTimeValue" + v-model="wendu.time" type="year" placeholder="请选择时间" + @change="(value) => getTime(value, wendu.type, 'wendu')" /> <div>电站平均水温汇总</div> </div> </div> <div class="item"> <div class="item-t"> - <div class="name">水位汇总统计</div> + <div class="name">报警汇总统计</div> <div class="select"> - <el-radio-group v-model="shuiweiType" @change="handleSelectType('shuiwei')"> + <el-radio-group v-model="warn.type" @change="handleSelectType('warn')"> <el-radio :value="1">日</el-radio> - <el-radio :value="2">月</el-radio> - <el-radio :value="3">年</el-radio> + <el-radio :value="3">月</el-radio> + <el-radio :value="5">年</el-radio> </el-radio-group> </div> </div> <div class="charts" ref="shuiweiChartRef"></div> <div class="title"> <el-date-picker - v-if="wenduType === 1" - v-model="shuiweiTimeValue" + v-if="warn.type === 1" + v-model="warn.time" type="date" placeholder="请选择时间" + @change="(value) => getTime(value, warn.type, 'warn')" /> <el-date-picker - v-else-if="wenduType === 2" - v-model="shuiweiTimeValue" + v-else-if="warn.type === 3" + v-model="warn.time" type="month" placeholder="请选择时间" + @change="(value) => getTime(value, warn.type, 'warn')" /> <el-date-picker v-else - v-model="shuiweiTimeValue" + v-model="warn.time" type="year" placeholder="请选择时间" + @change="(value) => getTime(value, warn.type, 'warn')" /> <div>电站平均水位汇总</div> </div> @@ -229,6 +339,20 @@ color: #fff; } .select{ + :deep(.el-cascader){ + margin-right: 2rem; + .el-input__wrapper{ + background-color: transparent; + box-shadow: none; + border: 1px solid #fff; + } + .el-input__inner{ + color: #fff; + &::placeholder{ + color: #fff; + } + } + } :deep(.el-radio){ color: #fff; } @@ -254,7 +378,7 @@ font-size: 26px; color: #fff; :deep(.el-date-editor){ - width: 10rem; + width: 12rem; } :deep(.el-input__wrapper){ background-color: transparent; -- Gitblit v1.9.3