楼宇能效监测控制系统
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.
 
 
 
 
 

769 lines
22 KiB

<template>
<div class="app-container">
<div class="special-div">
<div class="special-top">
<div class="special-title">项目简介</div>
</div>
<div class="project-all">
<img
class="project-img"
:src="imgUrl + projectObj.logo"
@click="showDialog"
alt="Base64 Image"
/>
<div class="project-li">
<div class="list-con">
<div class="project-left">
<img
class="left-icon"
src="../assets/images/project-icon1.png"
alt=""
/>
<div class="project-name">项目名称</div>
</div>
<div class="project-right">{{ projectObj.proName }}</div>
</div>
<div class="list-con">
<div class="project-left">
<img
class="left-icon"
src="../assets/images/project-icon2.png"
alt=""
/>
<div class="project-name">建筑面积</div>
</div>
<div class="project-right">{{ projectObj.buildingArea }}</div>
</div>
<div class="list-con">
<div class="project-left">
<img
class="left-icon"
src="../assets/images/project-icon3.png"
alt=""
/>
<div class="project-name">运营地址</div>
</div>
<div class="project-right">{{ projectObj.proAddr }}</div>
</div>
</div>
<div class="project-li">
<div class="list-con">
<div class="project-left">
<img
class="left-icon"
src="../assets/images/project-icon3.png"
alt=""
/>
<div class="project-name">项目运行开始时间</div>
</div>
<div class="project-right">{{ projectObj.operateStartTime }}</div>
</div>
</div>
</div>
</div>
<div class="project-data">
<div class="special-div" style="width: 60%">
<div class="special-top">
<div class="special-title">项目概况</div>
</div>
<div class="overview">
<div class="overview-li">
<div>总耗电量(kwh)</div>
<div class="overview-details">{{ projectView.totalEle }}</div>
</div>
<div class="overview-li">
<div>总热水补水()</div>
<div class="overview-details">
{{ projectView.totalWater }}
</div>
</div>
<div class="overview-li">
<div>总蒸汽流量()</div>
<div class="overview-details">
{{ projectView.totalGas }}
</div>
</div>
<div class="overview-li">
<div>总产冷量(kw)</div>
<div class="overview-details">
{{ projectView.totalCold }}
</div>
</div>
<div class="overview-li">
<div>今年耗电量(kwh)</div>
<div class="overview-details">
{{ projectView.yearEle }}
</div>
</div>
<div class="overview-li">
<div>今年热水补水()</div>
<div class="overview-details">
{{ projectView.yearWater }}
</div>
</div>
<div class="overview-li">
<div>今年蒸汽流量()</div>
<div class="overview-details">
{{ projectView.yearGas }}
</div>
</div>
<div class="overview-li">
<div>今年产冷量(kw)</div>
<div class="overview-details">
{{ projectView.yearCold }}
</div>
</div>
</div>
</div>
<div class="special-div" style="width: 39%">
<div class="special-top">
<div class="special-title">冷源系统</div>
</div>
<view-energy></view-energy>
</div>
</div>
<div class="project-bie">
<div class="special-div">
<div class="special-top">
<div class="special-title">冷源能耗</div>
</div>
<view-cold-sys :subData="coldSys"></view-cold-sys>
</div>
<div class="special-div">
<div class="special-top">
<div class="special-title">热水系统</div>
</div>
<hot-water :subData="hotWaterSys"></hot-water>
</div>
<div class="special-div">
<div class="special-top">
<div class="special-title">风柜系统</div>
</div>
<airc-and-windc-meter :subData="airAndWindSys"></airc-and-windc-meter>
</div>
<div class="special-div">
<div class="special-top">
<div class="special-title">温度系统</div>
</div>
<tem-meter :subData="temSys"></tem-meter>
</div>
</div>
<el-dialog
:visible.sync="dialogVisible"
title="上传图片"
width="500px"
@close="addExpenseClose"
>
<!-- 使用 el-upload 组件 -->
<el-upload
class="upload-demo"
ref="uploadComponent"
action="#"
list-type="picture-card"
:on-preview="handlePictureCardPreview"
:on-remove="handleRemove"
:before-upload="beforeUpload"
:limit="1"
:on-exceed="handleExceed"
:on-change="handleFileChange"
accept="image/png, image/jpeg"
:http-request="customHttpRequest"
>
<i class="el-icon-plus"></i>
</el-upload>
<div slot="footer" class="dialog-footer">
<!-- 取消按钮 -->
<el-button @click="dialogVisible = false">取消</el-button>
<!-- 确定按钮 -->
<el-button type="primary" @click="uploadFile">确定</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import * as echarts from "echarts";
import { imgUrl } from "@/utils/global";
import {
introduction,
changeLogo,
viewProfile,
viewMainParams,
} from "@/api/index";
import viewEnergy from "./components/viewEnergy.vue";
import ViewColdSys from "./components/viewColdSys.vue";
import HotWater from "./components/hotWater.vue";
import AircAndWindcMeter from "./components/aircAndWindcMeter.vue";
import TemMeter from "./components/temMeter.vue";
export default {
components: {
viewEnergy,
ViewColdSys,
HotWater,
AircAndWindcMeter,
TemMeter,
},
data() {
return {
imgUrl: "",
projectObj: {
proName: "",
logo: "",
proAddr: "",
buildingArea: "",
operateStartTime: "",
},
projectView: {
totalEle: "",
totalWater: "",
totalGas: "",
totalCold: "",
yearEle: "",
yearWater: "",
yearGas: "",
yearCold: "",
},
dialogVisible: false,
selectedFile: null,
viewImageUrl: "",
chartInstance: null,
data1: [],
data2: [],
xTable: [],
chartsData1: null,
chartsData2: null,
isShowHome: true,
//传给子组件的数据
coldSys: [],
hotWaterSys: [],
airAndWindSys: [],
temSys: [],
};
},
mounted() {
this.getProject();
this.getHomeData();
this.getSubData();
// // 在组件挂载后尝试进入全屏
// setTimeout(() => {
// this.requestFullscreen();
// }, 100); // 延迟 100 毫秒执行全屏操作
// this.initChart();
// window.addEventListener("resize", this.screenAdapter);
// this.screenAdapter();
// this.getChartsData();
},
destroyed() {
//与mounted中的监听对应,在组件销毁的时候,需要将监听器取消掉
// window.removeEventListener("resize", this.screenAdapter);
},
methods: {
// 全屏操作
requestFullscreen() {
const element = document.documentElement;
console.log("全屏了吗");
if (element.requestFullscreen) {
element.requestFullscreen();
} else if (element.mozRequestFullScreen) {
// Firefox
element.mozRequestFullScreen();
} else if (element.webkitRequestFullscreen) {
// Chrome, Safari and Opera
element.webkitRequestFullscreen();
} else if (element.msRequestFullscreen) {
// IE/Edge
element.msRequestFullscreen();
}
},
// 获取项目简介数据
getProject() {
this.imgUrl = imgUrl;
introduction().then((res) => {
console.log("项目资料", res);
if (res.code == 200) {
this.projectObj = res.rows[0];
}
});
},
// 显示上传图片弹框
showDialog() {
this.dialogVisible = true;
},
// 处理文件选择事件
handleFileChange(file, fileList) {
this.selectedFile = file.raw;
},
// 关闭弹框
addExpenseClose() {
// 清除上传文件
this.$refs.uploadComponent.clearFiles();
this.viewImageUrl = "";
},
// 重置
reset() {
this.dialogData = {};
// 清除上传文件
this.$refs.uploadComponent.clearFiles();
this.viewImageUrl = "";
},
// 图片移除
handleRemove(file, fileList) {
console.log(file, fileList);
this.selectedFile = {};
},
// 图片预览
handlePictureCardPreview(file) {
this.dialogVisible = true;
this.viewImageUrl = file.url;
},
// 上传成功
handleUploadSuccess(response, file, fileList) {},
// 处理文件
handleFileChange(file, fileList) {
console.log("file", file);
this.selectedFile = file.raw;
},
processFile(file) {
// 在这里你可以对 file.raw 进行任何本地处理
console.log("处理的文件", file);
// 例如:读取文件内容
const reader = new FileReader();
reader.onload = (event) => {
console.log("文件内容", event.target.result);
};
reader.readAsDataURL(file);
},
customHttpRequest(options) {
// 自定义上传逻辑,不进行实际的网络请求
const file = options.file;
},
beforeUpload(file) {
const isJpgOrPng =
file.type === "image/jpeg" || file.type === "image/png";
if (!isJpgOrPng) {
this.$message.error("上传图片只能是 JPG 或 PNG 格式!");
}
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isLt2M) {
this.$message.error("上传图片大小不能超过 2MB!");
}
return isJpgOrPng && isLt2M;
},
handleExceed(files, fileList) {
this.$message.warning(`上传文件数量超过限制, 当前限制为 1 张`);
},
// 上传
uploadFile() {
console.log("这里进行请求");
let data = {
proId: 0,
logo: this.selectedFile,
};
changeLogo(data).then((res) => {
if (res.code == 200) {
this.$modal.msgSuccess("上传成功");
this.getProject();
this.dialogVisible = false;
} else {
this.$message.error("上传失败");
this.dialogVisible = false;
}
});
},
// 项目概况
getHomeData() {
viewProfile().then((res) => {
if (res.code == 200) {
this.projectView = res.rows[0];
}
});
},
//初始化chartInstance对象
initChart() {
this.chartInstance = echarts.init(this.$refs.charts_ref);
this.option = {
tooltip: {
trigger: "axis",
},
grid: {
left: "3%",
right: "4%",
bottom: "3%",
containLabel: true,
},
legend: {
data: ["消费总金额(元)", "消费总次数(次)"],
icon: "cricle", //图例样式,可以自行查看样式选择
// //图例文字颜色
textStyle: {
color: "#ffff",
fontSize: 12, //这里改字体大小
},
left: "center",
top: "10",
//图例距离饼图的距离
itemGap: 5,
itemWidth: 10,
itemHeight: 5,
},
xAxis: {
type: "category",
//设置为true代表离零刻度间隔一段距离
boundaryGap: true,
// data: [
// "1栋",
// "2栋",
// "3栋",
// "4栋",
// "5栋",
// "6栋",
// "7栋",
// "8栋",
// "9栋",
// "10栋",
// "11栋",
// "12栋",
// "13栋",
// "14栋",
// "15栋",
// "16栋",
// "17栋",
// "18栋",
// "19栋",
// "20栋",
// "21栋",
// "22栋",
// "23栋",
// "24栋",
// ],
data: this.xTable,
// 修饰刻度标签的颜色即x坐标数据
axisLabel: {
// interval: 0, //强制显示所有x轴数据
// rotate: 30, //x轴坐标字体倾斜30度
color: "rgba(255, 255, 255, 1)",
},
axisTick: {
show: false, // 不显示坐标轴刻度线
},
// x坐标轴的颜色
axisLine: {
show: true,
lineStyle: {
// X 轴颜色配置
color: "#365576",
},
},
splitLine: {
lineStyle: {
color: "#e2e6f0",
},
}, //x轴分割线
},
yAxis: {
miniInterval: 5,
type: "value",
// name: "单位(吨)",
// 设置 name 的样式
nameTextStyle: {
color: "rgba(255, 255, 255, 1)",
fontSize: 12,
},
// 修饰刻度标签的颜色即y坐标数据
axisLabel: {
color: "rgba(255, 255, 255, 1)",
},
// 显示y坐标轴
axisLine: {
show: true,
lineStyle: {
color: "#365576", // 设置 y 轴线的颜色
},
},
//y轴分割线段数
// splitNumber: 10,
// 修改y轴分割线的颜色
splitLine: {
lineStyle: {
color: "#1a3d62", // 设置分割线的颜色
type: "dashed", // 设置分割线为虚线
},
},
},
series: [
{
name: "消费总金额(元)",
type: "line",
// data: [
// 20, 42, 12, 43, 22, 56, 22, 7, 88, 34, 62, 12, 23, 41, 23, 22, 87,
// 56, 54, 34, 33, 10, 32, 54, 39, 27,
// ],
data: this.data1,
itemStyle: {
color: " #08c8ff",
},
},
{
name: "消费总次数(次)",
type: "line",
// data: [
// 40, 42, 2, 45, 32, 16, 92, 7, 88, 34, 62, 12, 23, 41, 23, 22, 43,
// 56, 524, 32, 3, 11, 32, 54, 39, 27,
// ],
data: this.data2,
itemStyle: {
color: "#277dff",
},
},
],
};
//把配置项给实例对象
this.chartInstance.setOption(this.option, true);
},
// 图表自适应 + 折线图数据
screenAdapter() {
//自己定义的比较合适的适配大小,2.6 mes_ref是图表盒子
const titleFontSize = (this.$refs.charts_ref.offsetWidth / 100) * 0.8;
//因为option可以多次配置的,所以这里的option只需要写 需要配置大小的相关数据
const adapterOption = {};
//记得重新给配置项给实例对象。只要实例对象.chartInstance不变,option就可以多次配置不同的条件。也可以配置一个dataoption只写需要从后台请求的数据相关
this.chartInstance.setOption(adapterOption);
//手动的调用图标对象的resize才能产生效果
this.chartInstance.resize();
},
//
getChartsData() {
const now = new Date();
const startDate = new Date(
Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate() - 30)
);
const endDate = new Date(
Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate() - 1)
);
const startDateStr = startDate.toISOString().slice(0, 10);
const endDateStr = endDate.toISOString().slice(0, 10);
let params = {
page: 0,
limit: 10,
startDate: startDateStr,
endDate: endDateStr,
type: "projectDay",
buildingName: "",
};
// console.log("近30天楼栋用水参数", params)
findTableData(params).then((res) => {
// console.log("近30天楼栋用水返回", res)
if (res) {
(this.data1 = []),
(this.data2 = []),
(this.xTable = []),
res.data.forEach((item) => {
this.data1.push(item.AmountConsu);
this.data2.push(item.PersonTime);
this.xTable.push(item.DATE);
});
// console.log("xTable------------", this.xTable);
// console.log("data1--------------", this.data1);
// console.log("data2--------------", this.data2);
const adapterOption = {
xAxis: {
data: this.xTable,
},
series: [
{
data: this.data1,
},
{
data: this.data2,
},
],
};
//记得重新给配置项给实例对象。只要实例对象.chartInstance不变,option就可以多次配置不同的条件。也可以配置一个dataoption只写需要从后台请求的数据相关
this.chartInstance.setOption(adapterOption);
//手动的调用图标对象的resize才能产生效果
this.chartInstance.resize();
} else {
const adapterOption = {
xAxis: {
data: [],
},
series: [
{
data: [],
},
{
data: [],
},
],
};
//记得重新给配置项给实例对象。只要实例对象.chartInstance不变,option就可以多次配置不同的条件。也可以配置一个dataoption只写需要从后台请求的数据相关
this.chartInstance.setOption(adapterOption);
//手动的调用图标对象的resize才能产生效果
this.chartInstance.resize();
}
});
},
// 请求的数据
getSubData() {
viewMainParams().then((res) => {
console.log("系统参数返回", res);
console.log("冷源监控返回", res.rows[0]);
this.coldSys = [];
this.hotWaterSys = [];
this.airAndWindSys = [];
this.temSys = [];
if (res.code == 200 && res.rows) {
res.rows.forEach((val) => {
if (val.name.includes("冷源")) {
this.coldSys = val.values;
console.log("this.coldSys111111111111", this.coldSys);
}
if (val.name.includes("热水")) {
this.hotWaterSys = val.values;
}
if (val.name.includes("风柜")) {
this.airAndWindSys = val.values;
}
if (val.name.includes("温度")) {
this.temSys = val.values;
}
});
}
});
},
},
};
</script>
<style lang="scss" scoped>
.project-all {
width: 100%;
display: flex;
flex-direction: row;
align-items: flex-start;
padding: 0.35rem;
.project-img {
width: 1.4rem;
height: 1.4rem;
border-radius: 0.1rem;
border: solid 1px #0163a8;
margin-right: 0.4rem;
cursor: pointer;
}
.project-li {
width: calc((100% - 0.7rem) / 2);
display: flex;
flex-direction: column;
.list-con {
width: 100%;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
.project-left {
display: flex;
flex-direction: row;
align-items: center;
.left-icon {
width: 0.2rem;
height: 0.2rem;
}
.project-name {
font-family: SourceHanSansCN-Regular;
font-size: 0.18rem;
line-height: 0.4rem;
color: #ffffff;
opacity: 0.8;
margin-left: 0.15rem;
}
}
.project-right {
font-family: SourceHanSansCN-Regular;
font-size: 0.18rem;
line-height: 0.4rem;
color: #ffffff;
}
}
}
.project-li:nth-last-child(1) {
margin-left: 1.5rem;
}
}
.project-data {
display: flex;
flex-direction: row;
align-items: stretch;
justify-content: space-between;
margin: 16px 0;
.overview {
width: 100%;
padding-top: 0.32rem;
display: flex;
flex-direction: row;
align-items: center;
flex-wrap: wrap;
.overview-li {
width: calc(25%);
height: 1.65rem;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background-image: url(../assets/images/overview-img.png);
background-repeat: no-repeat;
background-size: 1.65rem 1.65rem;
background-position: center center;
margin-bottom: 0.3rem;
font-family: SourceHanSansCN-Regular;
font-size: 0.15rem;
color: #ffffff;
.overview-details {
font-family: DIN-Bold;
font-size: 0.2rem;
color: #15e1fd;
margin-top: 0.05rem;
}
}
}
}
.chartsDiv {
width: 100%;
height: 4rem;
}
.project-bie {
width: 100%;
display: flex;
flex-direction: row;
align-items: stretch;
justify-content: space-between;
.special-div {
width: 24.5%;
}
}
@media (max-width: 1485px) {
.overview-li {
width: calc(33.33%) !important;
height: 2.5rem !important;
background-size: 2.5rem 2.5rem !important;
margin-bottom: 0.3rem;
font-size: 0.22rem !important;
.overview-details {
font-size: 0.27rem !important;
}
}
.project-bie {
flex-wrap: wrap !important;
.special-div {
width: 49.5% !important;
margin-bottom: 0.25rem;
}
}
}
// 媒体查询,适配大于2000px分辨率的大屏样式
@media (min-width: 2000px) {
}
</style>