Files
admin-vben5/apps/web-antd/src/views/property/energyManagement/electricEnergy/electricTrend/index.vue

432 lines
10 KiB
Vue
Raw Normal View History

2025-07-25 15:41:29 +08:00
<script setup lang="ts">
import dayjs from 'dayjs';
2025-09-14 21:46:33 +08:00
import { Dayjs } from 'dayjs';
import * as echarts from 'echarts';
import { Page } from '@vben/common-ui';
import { DatePicker } from 'ant-design-vue';
2025-09-14 21:46:33 +08:00
import { onMounted, onUnmounted, ref } from 'vue';
import FloorTree from '../components/floor-tree.vue';
import { meterRecordTrend } from '#/api/property/energyManagement/meterRecord';
2025-07-26 17:10:01 +08:00
const currentDay = ref<Dayjs>(dayjs());
const currentMonth = ref<Dayjs>(dayjs());
const currentYear = ref<Dayjs>(dayjs());
2025-07-26 17:10:01 +08:00
const disabledDay = (current: Dayjs) => {
return current && current > dayjs().endOf('day');
};
2025-07-26 17:10:01 +08:00
const disabledMonth = (current: Dayjs) => {
return current && current > dayjs().endOf('month');
};
2025-07-26 17:10:01 +08:00
const disabledYear = (current: Dayjs) => {
return current && current > dayjs().endOf('year');
};
2025-07-25 15:41:29 +08:00
2025-09-14 21:46:33 +08:00
onMounted(() => {
setTimeout(() => {
initChart();
}, 300);
window.addEventListener('resize', resizeChart);
});
onUnmounted(() => {
window.removeEventListener('resize', resizeChart);
});
const chartInstances = {
day: null as echarts.ECharts | null,
month: null as echarts.ECharts | null,
year: null as echarts.ECharts | null,
};
2025-09-14 21:46:33 +08:00
function initChart() {
2025-07-26 17:10:01 +08:00
//day
const chartDay = document.getElementById('day');
chartInstances.day = echarts.init(chartDay);
2025-07-26 17:10:01 +08:00
const optionDay = {
2025-07-25 15:41:29 +08:00
tooltip: {
show: true,
trigger: 'axis',
2025-07-25 15:41:29 +08:00
},
toolbox: {
show: true,
feature: {
magicType: { show: true, type: ['line', 'bar'] },
},
2025-07-25 15:41:29 +08:00
},
calculable: true,
xAxis: [
{
type: 'category',
name: '时',
},
2025-07-25 15:41:29 +08:00
],
yAxis: [
{
type: 'value',
name: 'KW.h',
},
2025-07-25 15:41:29 +08:00
],
};
optionDay && chartInstances.day.setOption(optionDay);
2025-07-26 17:10:01 +08:00
//month
const chartMonth = document.getElementById('month');
chartInstances.month = echarts.init(chartMonth);
2025-07-26 17:10:01 +08:00
const optionMonth = {
tooltip: {
trigger: 'axis',
2025-07-26 17:10:01 +08:00
},
toolbox: {
show: true,
feature: {
magicType: { show: true, type: ['line', 'bar'] },
},
2025-07-26 17:10:01 +08:00
},
calculable: true,
xAxis: [
{
type: 'category',
name: '日',
},
2025-07-26 17:10:01 +08:00
],
yAxis: [
{
type: 'value',
name: 'KW.h',
},
2025-07-26 17:10:01 +08:00
],
dataZoom: [
{
type: 'inside',
2025-07-26 17:10:01 +08:00
xAxisIndex: 0,
zoomOnMouseWheel: true,
filterMode: 'filter',
2025-07-26 17:10:01 +08:00
},
],
};
optionMonth && chartInstances.month.setOption(optionMonth);
2025-07-26 17:10:01 +08:00
//year
const chartYear = document.getElementById('year');
chartInstances.year = echarts.init(chartYear);
2025-07-26 17:10:01 +08:00
const optionYear = {
tooltip: {
trigger: 'axis',
2025-07-26 17:10:01 +08:00
},
toolbox: {
show: true,
feature: {
magicType: { show: true, type: ['line', 'bar'] },
},
2025-07-26 17:10:01 +08:00
},
calculable: true,
xAxis: [
{
type: 'category',
name: '月',
},
2025-07-26 17:10:01 +08:00
],
yAxis: [
{
type: 'value',
name: 'KW.h',
},
2025-07-26 17:10:01 +08:00
],
dataZoom: [
{
type: 'inside',
2025-07-26 17:10:01 +08:00
xAxisIndex: 0,
zoomOnMouseWheel: true,
filterMode: 'filter',
2025-07-26 17:10:01 +08:00
},
],
};
optionYear && chartInstances.year.setOption(optionYear);
2025-07-26 17:10:01 +08:00
// 鼠标悬停时激活缩放
chartInstances.day.on('mouseover', { seriesIndex: 0 }, () => {
chartInstances.day.dispatchAction({
type: 'takeGlobalCursor',
key: 'dataZoomSelect',
2025-07-26 17:10:01 +08:00
dataZoomSelectActive: true,
});
});
2025-07-26 17:10:01 +08:00
// 鼠标离开时取消缩放
chartInstances.day.on('mouseout', { seriesIndex: 0 }, () => {
chartInstances.day.dispatchAction({
type: 'takeGlobalCursor',
key: 'dataZoomSelect',
2025-07-26 17:10:01 +08:00
dataZoomSelectActive: false,
});
});
2025-07-25 15:41:29 +08:00
2025-07-26 17:10:01 +08:00
// 鼠标悬停时激活缩放
chartInstances.year.on('mouseover', { seriesIndex: 0 }, () => {
chartInstances.year.dispatchAction({
type: 'takeGlobalCursor',
key: 'dataZoomSelect',
2025-07-26 17:10:01 +08:00
dataZoomSelectActive: true,
});
});
2025-07-26 17:10:01 +08:00
// 鼠标离开时取消缩放
chartInstances.year.on('mouseout', { seriesIndex: 0 }, () => {
chartInstances.year.dispatchAction({
type: 'takeGlobalCursor',
key: 'dataZoomSelect',
2025-07-26 17:10:01 +08:00
dataZoomSelectActive: false,
});
});
2025-07-26 17:10:01 +08:00
// 鼠标悬停时激活缩放
chartInstances.month.on('mouseover', { seriesIndex: 0 }, () => {
chartInstances.month.dispatchAction({
type: 'takeGlobalCursor',
key: 'dataZoomSelect',
2025-07-26 17:10:01 +08:00
dataZoomSelectActive: true,
});
});
2025-07-26 17:10:01 +08:00
// 鼠标离开时取消缩放
chartInstances.month.on('mouseout', { seriesIndex: 0 }, () => {
chartInstances.month.dispatchAction({
type: 'takeGlobalCursor',
key: 'dataZoomSelect',
2025-07-26 17:10:01 +08:00
dataZoomSelectActive: false,
});
});
2025-09-14 21:46:33 +08:00
}
function resizeChart() {
chartInstances.day && chartInstances.day.resize();
chartInstances.month && chartInstances.month.resize();
chartInstances.year && chartInstances.year.resize();
}
const hourTotal = ref<number>();
const dayTotal = ref<number>();
const monthTotal = ref<number>();
async function handleSelectFloor(selectedKeys, info) {
let data = {
day: currentDay.value.format('YYYY-MM-DD'),
month: currentMonth.value.format('YYYY-MM'),
year: currentYear.value.format('YYYY'),
meterType: 1,
meterId: null,
floorId: null,
};
if (info.node.level == 3) {
data.floorId = selectedKeys[0];
} else {
data.meterId = selectedKeys[0];
}
const trend = await meterRecordTrend(data);
// 更新日数据图表
if (chartInstances.day && trend.hour) {
2025-09-14 21:46:33 +08:00
const yesterday = currentDay.value
.clone()
.subtract(1, 'day')
.format('YYYY-MM-DD');
hourTotal.value = trend.hour.today.total;
chartInstances.day.setOption({
2025-09-14 21:46:33 +08:00
legend: {
data: [yesterday, data.day],
},
series: [
{
2025-09-14 21:46:33 +08:00
name: yesterday,
type: 'bar',
data: trend.hour.yesterday.data || [],
markPoint: {
data: [
{ type: 'max', name: 'Max' },
{ type: 'min', name: 'Min' },
],
},
markLine: {
data: [{ type: 'average', name: 'Avg' }],
},
},
{
2025-09-14 21:46:33 +08:00
name: data.day,
type: 'bar',
data: trend.hour.today.data || [],
markPoint: {
data: [
{ type: 'max', name: 'Max' },
{ type: 'min', name: 'Min' },
],
},
markLine: {
data: [{ type: 'average', name: 'Avg' }],
},
},
],
});
}
// 更新月数据图表
if (chartInstances.month && trend.day) {
2025-09-14 21:46:33 +08:00
const lastMonth = currentDay.value
.clone()
.subtract(1, 'month')
.format('YYYY-MM');
dayTotal.value = trend.day.nowMonth.total;
chartInstances.month.setOption({
2025-09-14 21:46:33 +08:00
legend: {
data: [lastMonth, data.month],
},
series: [
{
2025-09-14 21:46:33 +08:00
name: lastMonth,
type: 'bar',
data: trend.day.lastMonth.data || [],
markPoint: {
data: [
{ type: 'max', name: 'Max' },
{ type: 'min', name: 'Min' },
],
},
markLine: {
data: [{ type: 'average', name: 'Avg' }],
},
},
{
2025-09-14 21:46:33 +08:00
name: data.month,
type: 'bar',
data: trend.day.nowMonth.data || [],
markPoint: {
data: [
{ type: 'max', name: 'Max' },
{ type: 'min', name: 'Min' },
],
},
markLine: {
data: [{ type: 'average', name: 'Avg' }],
},
},
],
});
}
// 更新年数据图表
if (chartInstances.year && trend.month) {
2025-09-14 21:46:33 +08:00
const lastYear = currentDay.value
.clone()
.subtract(1, 'year')
.format('YYYY');
monthTotal.value = trend.month.nowYear.total;
chartInstances.year.setOption({
2025-09-14 21:46:33 +08:00
legend: {
data: [lastYear, data.year],
},
series: [
{
2025-09-14 21:46:33 +08:00
name: lastYear,
type: 'bar',
data: trend.month.lastYear.data || [],
markPoint: {
data: [
{ type: 'max', name: 'Max' },
{ type: 'min', name: 'Min' },
],
},
markLine: {
data: [{ type: 'average', name: 'Avg' }],
},
},
{
2025-09-14 21:46:33 +08:00
name: data.year,
type: 'bar',
data: trend.month.nowYear.data || [],
markPoint: {
data: [
{ type: 'max', name: 'Max' },
{ type: 'min', name: 'Min' },
],
},
markLine: {
data: [{ type: 'average', name: 'Avg' }],
},
},
],
});
}
}
2025-07-25 15:41:29 +08:00
</script>
<template>
<Page :auto-content-height="true">
<div class="flex h-full gap-[8px]">
<FloorTree class="w-[260px]" @select="handleSelectFloor"></FloorTree>
<div class="flex-1 overflow-hidden">
<div
style="
background: #fff;
border-radius: 8px;
padding: 10px;
height: 33%;
"
>
<div>
<div style="display: flex; justify-content: space-between">
<DatePicker
v-model:value="currentDay"
:disabled-date="disabledDay"
/>
<span>当日能耗总值{{ hourTotal }}KW.h</span>
</div>
</div>
<div id="day" style="height: 100%; width: 100%"></div>
</div>
<div
style="
background: #fff;
border-radius: 8px;
padding: 10px;
margin-top: 16px;
height: 33%;
"
>
<div>
<div style="display: flex; justify-content: space-between">
<DatePicker
v-model:value="currentMonth"
:disabled-date="disabledMonth"
picker="month"
/>
<span>当月能耗总值{{ dayTotal }}KW.h</span>
</div>
</div>
<div id="month" style="height: 100%; width: 100%"></div>
</div>
<div
style="
background: #fff;
border-radius: 8px;
padding: 10px;
margin-top: 16px;
height: 33%;
"
>
<div>
<div style="display: flex; justify-content: space-between">
<DatePicker
v-model:value="currentYear"
:disabled-date="disabledYear"
picker="year"
/>
<span>当年能耗总值{{ monthTotal }}KW.h</span>
</div>
</div>
<div id="year" style="height: 100%; width: 100%"></div>
</div>
2025-07-26 17:10:01 +08:00
</div>
</div>
</Page>
2025-07-25 15:41:29 +08:00
</template>