楼宇能效监测控制系统
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

777 lines
24 KiB

<template>
<div class="main-body">
<div class="irregular-border">
<div class="main-content">
<div class="condition">
<div class="condition-left">
<div class="time-label">时间类型:</div>
<el-radio-group
v-model="dateType"
style="margin-right: 0.24rem"
@change="updateDateType"
>
<el-radio label="hour">小时</el-radio>
<el-radio label="day">日</el-radio>
<el-radio label="month">月</el-radio>
<el-radio label="year">年</el-radio>
</el-radio-group>
<el-date-picker
v-model="timeDate"
:default-time="['00:00:00', '23:59:59']"
type="datetimerange"
range-separator="至"
v-if="dateType == 'hour'"
placeholder="选择日期"
start-placeholder="开始日期"
end-placeholder="结束日期"
>
</el-date-picker>
<el-date-picker
v-model="dayDate"
type="daterange"
v-if="dateType == 'day'"
:key="this.dateType"
range-separator="至"
value-format="yyyy-MM-dd"
start-placeholder="开始日期"
end-placeholder="结束日期"
@change="dateChange"
>
</el-date-picker>
<el-date-picker
v-model="monthDate"
type="monthrange"
v-if="dateType == 'month'"
:key="this.dateType"
range-separator="至"
start-placeholder="开始月份"
end-placeholder="结束月份"
value-format="yyyy-MM"
@change="dateChange"
>
</el-date-picker>
<div
class="years-div"
v-if="dateType == 'year'"
:key="this.dateType"
>
<el-date-picker
v-model="startYear"
type="year"
placeholder="选择开始年份"
style="width: 180px"
value-format="yyyy"
>
</el-date-picker>
<div class="years-word">至</div>
<el-date-picker
v-model="endYear"
type="year"
placeholder="选择结束年份"
style="width: 180px"
value-format="yyyy"
>
</el-date-picker>
</div>
<div class="success-btn" style="margin-left: 0.24rem">
<el-button type="success" @click="findData">查询</el-button>
</div>
<div class="warning-btn">
<el-button type="warning" @click="goExport()">导出</el-button>
</div>
</div>
</div>
<div class="choice">
<div
class="mr20"
v-for="(item, index) in timeData2"
:key="index"
@click="handleEnter(index, $event)"
:class="{ timeStyle: currentIndex == index }"
>
{{ item.title }}
</div>
</div>
<div class="charts" ref="chart_ref"></div>
<el-table :data="tableData" stripe>
<el-table-column label="时间" align="center" prop="time" />
<el-table-column
label="总用电量(kwh)"
align="center"
prop="electValue"
/>
<el-table-column
label="总产冷量(kw)"
align="center"
prop="coldValue"
/>
<el-table-column
label="总热水补水量(t)"
align="center"
prop="hotValue"
/>
<el-table-column
label="总蒸汽流量(t)"
align="center"
prop="steamValue"
/>
</el-table>
<pagination
v-show="total > 0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getTableData"
/>
</div>
</div>
</div>
</template>
<script>
import { format2 } from "@/utils/datetime";
import * as echarts from "echarts";
import { compreReport } from "@/api/comprehensiveEnergy/systemEnergy";
export default {
data() {
return {
listLoading: false,
dateType: "hour", //默认选择小时
timeDate: [], //小时值
dayDate: [], //日值
monthDate: [], //月值
startYear: "", //开始年份
endYear: "", //结束年份
startTime: "", //开始日期
endTime: "", //结束日期
// 总条数
total: 0,
// 表格数据
tableData: [],
exportData: [],
// 查询参数
queryParams: {
pageNum: 1,
pageSize: 10,
startTime: "",
endTime: "",
},
brokenInstanc: null,
brokenOption: {},
timeData2: [
{ title: "总用电量" },
{ title: "总产冷量" },
{ title: "总热水补水量" },
{ title: "总蒸汽流量" },
],
currentIndex: 0,
brokenData1: [],
brokenData2: [],
brokenData3: [],
brokenData4: [],
brokenTime: [],
useWater: 0,
useWaterRadio: 0,
useElect: 0,
useElectRadio: 0,
useUnit: 0,
useUnitRadio: 0,
};
},
mounted() {
this.initializeTimeDate();
this.getTableData();
this.initChart();
window.addEventListener("resize", this.screenAdapter);
this.screenAdapter();
},
destroyed() {
//取消监听器
window.removeEventListener("resize", this.screenAdapter);
},
methods: {
// 初始化时间
initializeTimeDate() {
const start = new Date(new Date().setHours(0, 0, 0, 0));
const end = new Date(new Date().setHours(23, 59, 59, 59));
this.timeDate = [format2(start), format2(end)]; // 更新
this.titleDate = format2(start) + "" + format2(end);
},
// 选择时间类型
updateDateType() {
// this.dateType = this.radio;
console.log(this.dateType);
(this.timeDate = []), //小时值
(this.dayDate = []), //日值
(this.monthDate = []), //月值
(this.startYear = ""), //开始年份
(this.endYear = ""); //结束年份
},
// 选中日期事件
dateChange() {
// console.log("打印时间", this.timeform.time1);
if (!this.dayDate) {
this.$nextTick(() => {
this.dayDate = [];
});
}
if (!this.monthDate) {
this.$nextTick(() => {
this.monthDate = [];
});
}
},
// 查询
findData() {
console.log("this.dateType", this.dateType);
console.log("this.timeDate", this.timeDate);
switch (this.dateType) {
case "hour":
if (!this.timeDate) {
this.showMessage("请选择时间", "warning");
} else {
this.titleDate =
format2(this.timeDate[0]) + "" + format2(this.timeDate[1]);
this.getTableData();
}
break;
case "day":
if (this.dayDate.length === 0) {
this.showMessage("请选择时间", "warning");
} else {
const newLength =
new Date(this.dayDate[1]).getTime() -
new Date(this.dayDate[0]).getTime();
const dayDiff = Math.floor(newLength / (1000 * 60 * 60 * 24));
if (dayDiff > 31) {
this.showMessage(
"最多只能选择30天区间请重新选择再查询",
"warning"
);
} else {
this.titleDate = this.dayDate[0] + "" + this.dayDate[1];
this.getTableData();
}
}
break;
case "month":
if (this.monthDate.length === 0) {
this.showMessage("请选择时间", "warning");
} else {
const [start, end] = this.monthDate;
const startDate = new Date(start);
const endDate = new Date(end);
const startYear = startDate.getFullYear();
const startMonth = startDate.getMonth();
const endYear = endDate.getFullYear();
const endMonth = endDate.getMonth();
const monthDiff =
(endYear - startYear) * 12 + (endMonth - startMonth);
if (monthDiff > 12) {
this.showMessage(
"最多只能选择12个月区间请重新选择再查询",
"warning"
);
} else {
this.titleDate = this.monthDate[0] + "" + this.monthDate[1];
this.getTableData();
}
}
break;
case "year":
if (!this.startYear || !this.endYear) {
this.showMessage("请选择全年份区间", "warning");
} else if (this.startYear > this.endYear) {
this.showMessage("结束年份要大于开始年份", "warning");
} else {
this.titleDate = this.startYear + "" + this.endYear;
this.getTableData();
}
break;
default:
break;
}
},
// 显示消息的函数
showMessage(message, type) {
this.$message({
message: message,
type: type,
});
},
handleEnter(index) {
this.currentIndex = index;
this.renderingBroken();
},
//请求数据
getTableData() {
if (this.dateType == "hour") {
this.startTime = format2(this.timeDate[0]);
this.endTime = format2(this.timeDate[1]);
} else if (this.dateType == "day") {
this.startTime = this.dayDate.length > 0 ? this.dayDate[0] : "";
this.endTime = this.dayDate.length > 0 ? this.dayDate[1] : "";
} else if (this.dateType == "month") {
this.startTime = this.monthDate.length > 0 ? this.monthDate[0] : "";
this.endTime = this.monthDate.length > 0 ? this.monthDate[1] : "";
} else if (this.dateType == "year") {
(this.startTime = this.startYear), (this.endTime = this.endYear);
}
let data = {
timeType: this.dateType,
startTime: this.startTime,
endTime: this.endTime,
pageNum: this.queryParams.pageNum,
pageSize: this.queryParams.pageSize,
};
console.log("查询数据参数", data);
this.listLoading = true;
compreReport(data).then((res) => {
console.log("表格返回的数据", res);
if (res.code == 200 && res.rows.length > 0) {
this.tableData = res.rows;
this.total = res.total;
} else {
this.tableData = [];
this.total = 0;
}
this.getChartData();
});
// Just to simulate the time of the request
setTimeout(() => {
this.listLoading = false;
}, 1.0 * 1000);
},
//请求折线图数据
getChartData() {
if ((this.total == 10)) {
// 防止数据提交重复
console.log("不用请求");
this.brokenData1 = [];
this.brokenData2 = [];
this.brokenData3 = [];
this.brokenData4 = [];
this.brokenTime = [];
if (this.tableData.length > 0) {
this.exportData = this.tableData;
this.tableData.forEach((item) => {
this.brokenData1.push(item.electValue);
this.brokenData2.push(item.coldValue);
this.brokenData3.push(item.hotValue);
this.brokenData4.push(item.steamValue);
this.brokenTime.push(item.time);
});
this.renderingBroken();
} else {
this.brokenData1 = [];
this.brokenData2 = [];
this.brokenData3 = [];
this.brokenData4 = [];
this.brokenTime = [];
}
this.renderingBroken();
} else {
console.log("图表参数", this.queryParams);
if (this.dateType == "hour") {
this.startTime = format2(this.timeDate[0]);
this.endTime = format2(this.timeDate[1]);
} else if (this.dateType == "day") {
this.startTime = this.dayDate.length > 0 ? this.dayDate[0] : "";
this.endTime = this.dayDate.length > 0 ? this.dayDate[1] : "";
} else if (this.dateType == "month") {
this.startTime = this.monthDate.length > 0 ? this.monthDate[0] : "";
this.endTime = this.monthDate.length > 0 ? this.monthDate[1] : "";
} else if (this.dateType == "year") {
(this.startTime = this.startYear), (this.endTime = this.endYear);
}
let data = {
timeType: this.dateType,
startTime: this.startTime,
endTime: this.endTime,
pageNum: 1,
pageSize: this.total,
};
compreReport(data).then((res) => {
console.log("图表返回的数据", res);
this.brokenData1 = [];
this.brokenData2 = [];
this.brokenData3 = [];
this.brokenData4 = [];
this.brokenTime = [];
if (res.code == 200 && res.rows.length > 0) {
this.exportData = res.rows;
res.rows.forEach((item) => {
this.brokenData1.push(item.electValue);
this.brokenData2.push(item.coldValue);
this.brokenData3.push(item.hotValue);
this.brokenData4.push(item.steamValue);
this.brokenTime.push(item.time);
});
this.renderingBroken();
} else {
this.brokenData1 = [];
this.brokenData2 = [];
this.brokenData3 = [];
this.brokenData4 = [];
this.brokenTime = [];
}
this.renderingBroken();
});
}
},
renderingBroken() {
if (this.currentIndex === 0) {
this.brokenOption.yAxis.name = "kwh";
this.brokenOption.yAxis.nameTextStyle = {
color: "rgba(255, 255, 255, 1)",
fontSize: 12,
};
this.brokenOption.series[0].data = this.brokenData1;
this.brokenOption.series[0].itemStyle.color = "#d48e17";
this.brokenOption.series[0].areaStyle.color.colorStops = [
{
offset: 0,
color: "rgba(212, 142, 23, 0.3)", // 0% 处的颜色
},
{
offset: 0.8,
color: "rgba(212, 142, 23,0)", // 100% 处的颜色
},
];
} else if (this.currentIndex === 1) {
this.brokenOption.yAxis.name = "kw";
this.brokenOption.yAxis.nameTextStyle = {
color: "rgba(255, 255, 255, 1)",
fontSize: 12,
};
this.brokenOption.series[0].data = this.brokenData2;
this.brokenOption.series[0].itemStyle.color = "#1ab395";
this.brokenOption.series[0].areaStyle.color.colorStops = [
{
offset: 0,
color: "rgba(26, 179, 149, 0.3)", // 0% 处的颜色
},
{
offset: 0.8,
color: "rgba(26, 179, 149,0)", // 100% 处的颜色
},
];
} else if (this.currentIndex === 2) {
this.brokenOption.yAxis.name = "t";
this.brokenOption.yAxis.nameTextStyle = {
color: "rgba(255, 255, 255, 1)",
fontSize: 12,
};
this.brokenOption.series[0].data = this.brokenData3;
this.brokenOption.series[0].itemStyle.color = "#1f8dee";
this.brokenOption.series[0].areaStyle.color.colorStops = [
{
offset: 0,
color: "rgba(31, 141, 238, 0.3)", // 0% 处的颜色
},
{
offset: 0.8,
color: "rgba(31, 141, 238,0)", // 100% 处的颜色
},
];
} else if (this.currentIndex === 3) {
this.brokenOption.yAxis.name = "t";
this.brokenOption.yAxis.nameTextStyle = {
color: "rgba(255, 255, 255, 1)",
fontSize: 12,
};
this.brokenOption.series[0].data = this.brokenData4;
this.brokenOption.series[0].itemStyle.color = "#f1f524";
this.brokenOption.series[0].areaStyle.color.colorStops = [
{
offset: 0,
color: "rgba(241, 245, 36, 0.3)", // 0% 处的颜色
},
{
offset: 0.8,
color: "rgba(241, 245, 36,0)", // 100% 处的颜色
},
];
}
// 保存当前索引用于闭包
const currentIndex = this.currentIndex;
// 动态设置 tooltip 格式化函数
this.brokenOption.tooltip = {
trigger: "axis",
formatter: function (params) {
// 获取当前数据点信息
const data = params[0];
const month = data.name;
const value = data.value;
// 根据索引返回不同内容
if (currentIndex === 0) {
return `${month}<br/>总用电量: ${value} 度`;
} else if (currentIndex === 1) {
return `${month}<br/>总产冷量: ${value} 千瓦`;
} else if (currentIndex === 2) {
return `${month}<br/>总热水补水量: ${value} 吨`;
} else if (currentIndex === 3) {
return `${month}<br/>总蒸汽量: ${value} 吨`;
}
},
};
this.brokenOption.xAxis.data = this.brokenTime;
this.brokenInstanc.setOption(this.brokenOption);
},
// 导出
goExport() {
if (this.exportData) {
import("@/assets/excel/Export2Excel").then((excel) => {
// 导出的excel表头字段名,需要导出表格字段名
var tHeader = [
"时间",
"总用电量(kwh)",
"总产冷量(kw)",
"总热水补水量(t)",
"总蒸汽流量(t)",
]; // 导出的excel表头名信息 改参数
var filterVal = [
"time",
"electValue",
"coldValue",
"hotValue",
"steamValue",
];
const data = this.formatJson(filterVal, this.exportData);
const autoWidth = true;
excel.export_json_to_excel({
header: tHeader, //表头
data, //数据
filename: "系统能耗报表", //名称
autoWidth: true, //宽度自适应
});
});
this.$message({
type: "success",
message: "导出成功!",
});
} else {
this.$message.error("导出失败!");
}
},
//格式转换,不需要改动
formatJson(filterVal, jsonData) {
return jsonData.map((v) =>
filterVal.map((j) => {
if (j === "perWater") {
return (v[j] * 1000).toFixed(1);
} else {
return v[j];
}
})
);
},
// 折线图自适应+ 根据按钮切换图例仅限一条且不可点击+ 折线图数据
screenAdapter() {
//自己定义的比较合适的适配大小,2.6 mes_ref是图表盒子
const titleFontSize = this.$refs.chart_ref.offsetWidth / 130;
//因为option可以多次配置的,所以这里的option只需要写 需要配置大小的相关数据
const adapterOption = {};
//记得重新给配置项给实例对象。只要实例对象.chartInstance不变,option就可以多次配置不同的条件。也可以配置一个dataoption只写需要从后台请求的数据相关
this.brokenInstanc.setOption(adapterOption);
//手动的调用图标对象的resize才能产生效果
this.brokenInstanc.resize();
},
//初始化chartInstance对象
initChart() {
this.brokenInstanc = echarts.init(this.$refs.chart_ref);
this.brokenOption = {
tooltip: {
trigger: "axis",
},
legend: {
show: false,
selectedMode: false, // 是否允许图例进行点击
icon: "cricle", //图例样式,可以自行查看样式选择
//图例文字颜色
textStyle: {
color: "#ffff",
fontSize: 16, //这里改字体大小
},
// left: "73%",
left: "66%",
top: "0",
//图例距离饼图的距离
itemGap: 5,
itemWidth: 10,
itemHeight: 5,
},
grid: {
top: "10%",
left: "3%",
right: "4%",
bottom: "5%",
containLabel: true,
},
xAxis: {
type: "category",
//设置为true代表离零刻度间隔一段距离
boundaryGap: true,
// 修饰刻度标签的颜色即x坐标数据
axisLabel: {
// interval: 0, //强制显示所有x轴数据
// rotate: 30, //x轴坐标字体倾斜30度
color: "rgba(255, 255, 255, 1)",
fontSize: 14, // 设置字体大小,可根据需要调整
},
axisTick: {
show: false, // 不显示坐标轴刻度线
},
// x坐标轴的颜色
axisLine: {
show: true,
lineStyle: {
color: "#365576",
},
},
splitLine: {
lineStyle: {
color: "#e2e6f0",
},
}, //x轴分割线
data: this.brokenTime,
},
yAxis: {
min: 0,
// max:20,
// // // min:'dataMin',
// // // max:'dataMax',
// name: "kwh", // 第一个 y 轴的单位描述
// 设置 name 的样式
nameTextStyle: {
color: "rgba(255, 255, 255, 1)",
fontSize: 12,
},
miniInterval: 5,
type: "value",
// 修饰刻度标签的颜色即y坐标数据
axisLabel: {
color: "rgba(255, 255, 255, 1)",
},
// 显示y坐标轴
axisLine: {
show: true,
lineStyle: {
color: "#365576", // 设置 y 轴线的颜色
},
fontSize: 14, // 设置字体大小,可根据需要调整
},
//y轴分割线段数
// splitNumber: 10,
// 修改y轴分割线的颜色
splitLine: {
lineStyle: {
color: "#1a3d62", // 设置分割线的颜色
type: "dashed", // 设置分割线为虚线
},
},
},
series: [
{
type: "line",
// 拐点大小
symbolSize: 8,
smooth: true,
showSymbol: false,
data: this.brokenData1,
//折线颜色
itemStyle: {
color: "#d48e17", //折线点的颜色
lineStyle: {
color: "#d48e17", //折线的颜色
},
},
areaStyle: {
color: {
//线性渐变
type: "linear",
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [],
},
},
},
],
};
//把配置项给实例对象
this.brokenInstanc.setOption(this.brokenOption, true);
},
},
};
</script>
<style lang="scss" scoped>
.condition-left {
display: flex;
flex-direction: row;
align-items: center;
flex-wrap: wrap;
.years-div {
display: flex;
flex-direction: row;
align-items: center;
.years-word {
font-size: 14px;
margin: 0 5px;
color: #388ff3;
}
}
.time-label {
font-size: 16px;
line-height: 7px;
margin-right: 12px;
white-space: nowrap;
}
}
.main-content {
min-height: 6.6rem;
}
.choice {
margin: 20px 0;
.mr20 {
padding: 0.05rem 0.2rem;
white-space: nowrap;
width: auto;
}
}
.charts {
width: 100%;
height: 300px;
margin-bottom: 0.1rem;
}
// 媒体查询,适配大于2000px分辨率的大屏样式
@media (min-width: 2000px) {
.condition {
.condition-left {
.years-div {
.years-word {
font-size: 0.14rem !important;
margin: 0 0.05rem !important;
}
}
.time-label {
font-size: 0.16rem !important;
line-height: 0.07rem !important;
margin-right: 0.12rem !important;
}
}
}
}
</style>