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

690 lines
20 KiB

<template>
<div class="monitor" v-loading="loading">
<div class="monitor-top">
<img
class="title-left"
src="../../../assets/images/title-left.png"
alt=""
/>
<img
class="title-center"
src="../../../assets/images/title-center.png"
alt=""
/>
<img
class="title-right"
src="../../../assets/images/title-right.png"
alt=""
/>
<div class="sys-title" @click="goSys">热水锅炉监测</div>
<!-- logo -->
<img src="../../../assets/images/logo-3.png" class="sys-logo" alt="" />
<div class="nowTime">{{ formattedDate }}</div>
<div class="monitor-time">已监测时长:{{ dayData }}</div>
<img
class="icon_warning"
src="../../../assets/images/warning.png"
title="报警记录"
@click="goWarning"
v-if="isShowWarning"
alt=""
/>
<img
class="icon_home"
src="../../../assets/images/icon_home.png"
title="首页"
@click="goSys"
alt=""
/>
<img
class="back-icon"
src="../../../assets/images/back-icon.png"
title="返回"
@click="goBack"
alt=""
/>
</div>
<div class="hotWater-div">
<div
class="hotWater-li"
v-for="(boiler, index) in hotWaterBoilerData"
:key="index"
>
<div class="special-div one">
<div class="special-top">
<div class="special-title">
<div class="title-left">
<div>{{ boiler.name }}</div>
</div>
</div>
</div>
<div class="hotWater">
<img
class="hotWater-img"
src="../../../assets/images/hotWater.png"
alt=""
/>
</div>
<div class="info">
<div class="hotWater-tem">
<div class="pump-data-li">
<div>出水温度:</div>
<div class="pump-data-text">
{{ getTemperatureData(boiler, "出水温度") }}℃
</div>
</div>
<div class="pump-data-li">
<div>回水温度:</div>
<div class="pump-data-text">
{{ getTemperatureData(boiler, "回水温度") }}℃
</div>
</div>
<div class="pump-data-li">
<div>炉水温度:</div>
<div class="pump-data-text">
{{ getTemperatureData(boiler, "炉水温度") }}℃
</div>
</div>
<div class="pump-data-li">
<div>烟道温度:</div>
<div class="pump-data-text">
{{ getTemperatureData(boiler, "烟道温度") }}℃
</div>
</div>
</div>
<div class="port-right">
<div class="port">
<div :class="['port-li', getFireSignalClass(boiler, '大火')]">
大火控制信号发出
</div>
<div :class="['port-li', getFireSignalClass(boiler, '小火')]">
小火控制信号发出
</div>
<div class="port-li port-close">燃烧机电源</div>
</div>
<div class="bad-div">
故障信息:<span class="bad-text">{{
getFaultInfo(boiler)
}}</span>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- <div class="hotWater-div">
<div class="hotWater-li">
<div class="special-div one">
<div class="special-top">
<div class="special-title">
<div class="title-left">
<div>1号热水锅炉</div>
</div>
</div>
</div>
<div class="hotWater">
<img
class="hotWater-img"
src="../../../assets/images/hotWater.png"
alt=""
/>
</div>
<div class="info">
<div class="hotWater-tem">
<div class="pump-data-li">
<div>出水温度:</div>
<div class="pump-data-text">29.7℃</div>
</div>
<div class="pump-data-li">
<div>回水温度:</div>
<div class="pump-data-text">29.7℃</div>
</div>
<div class="pump-data-li">
<div>炉水温度:</div>
<div class="pump-data-text">29.7℃</div>
</div>
<div class="pump-data-li">
<div>烟道温度:</div>
<div class="pump-data-text">29.7℃</div>
</div>
</div>
<div class="port-right">
<div class="port">
<div class="port-li port-open">大火控制信号发出</div>
<div class="port-li port-close">小伙控制信号发出</div>
<div class="port-li port-close">燃烧机电源</div>
</div>
<div class="bad-div">
故障信息:<span class="bad-text">炉水温度传感器故障</span>
</div>
</div>
</div>
</div>
</div>
<div class="hotWater-li">
<div class="special-div one">
<div class="special-top">
<div class="special-title">
<div class="title-left">
<div>2号热水锅炉</div>
</div>
</div>
</div>
<div class="hotWater">
<img
class="hotWater-img"
src="../../../assets/images/hotWater.png"
alt=""
/>
</div>
<div class="info">
<div class="hotWater-tem">
<div class="pump-data-li">
<div>出水温度:</div>
<div class="pump-data-text">29.7℃</div>
</div>
<div class="pump-data-li">
<div>回水温度:</div>
<div class="pump-data-text">29.7℃</div>
</div>
<div class="pump-data-li">
<div>炉水温度:</div>
<div class="pump-data-text">29.7℃</div>
</div>
<div class="pump-data-li">
<div>烟道温度:</div>
<div class="pump-data-text">29.7℃</div>
</div>
</div>
<div class="port-right">
<div class="port">
<div class="port-li port-open">大火控制信号发出</div>
<div class="port-li port-close">小伙控制信号发出</div>
<div class="port-li port-close">燃烧机电源</div>
</div>
<div class="bad-div">
故障信息:<span class="bad-text">炉水温度传感器故障</span>
</div>
</div>
</div>
</div>
</div>
</div> -->
</div>
</template>
<script>
import { runTime } from "@/api/centerairC/sysMonitor";
import { alarmRecordList } from "@/api/alarm/alarmRecord";
import { hotWaterBoiler } from "@/api/boiler/hotwaterBoiler";
import { getDay } from "@/utils/datetime";
export default {
name: "boilerMonitorDetails",
data() {
return {
loading: false,
currentDate: new Date(),
nowTimer: null,
isShowWarning: false, //是否有报警
dayData: "", //监测天数
currentWeekday: "",
// 热水锅炉数据
hotWaterBoilerData: [],
};
},
computed: {
formattedDate() {
const year = this.currentDate.getFullYear();
const month = String(this.currentDate.getMonth() + 1).padStart(2, "0");
const day = String(this.currentDate.getDate()).padStart(2, "0");
const hours = String(this.currentDate.getHours()).padStart(2, "0");
const minutes = String(this.currentDate.getMinutes()).padStart(2, "0");
const seconds = String(this.currentDate.getSeconds()).padStart(2, "0");
const weekDays = [
"星期日",
"星期一",
"星期二",
"星期三",
"星期四",
"星期五",
"星期六",
];
const weekDay = weekDays[this.currentDate.getDay()];
return `${year}${month}${day}${hours}:${minutes}:${seconds} ${weekDay}`;
},
},
created() {
const weekdays = [
"星期日",
"星期一",
"星期二",
"星期三",
"星期四",
"星期五",
"星期六",
];
const date = new Date();
const dayIndex = date.getDay();
this.currentWeekday = weekdays[dayIndex];
console.log("今天是星期几", this.currentWeekday);
},
mounted() {
this.getAlarnStatus();
this.getDayData();
// 获取当前热水锅炉数据
this.getHotWaterBoiler();
},
beforeDestroy() {
// 组件销毁前清除定时器
if (this.nowTimer) {
clearInterval(this.nowTimer);
}
},
methods: {
// Get temperature data by type (keep as is)
getTemperatureData(boiler, type) {
if (!boiler || !boiler.values) return "--";
const item = boiler.values.find(
(v) => v.otherName && v.otherName.includes(type)
);
return item && item.curValue !== null ? item.curValue : "--";
},
// Get fire signal class for individual signals
getFireSignalClass(boiler, signalType) {
if (!boiler || !boiler.values) return "port-close";
// Get fire signal values
const fire1Item = boiler.values.find(
(v) => v.otherName && v.otherName.includes("火力1")
);
const fire2Item = boiler.values.find(
(v) => v.otherName && v.otherName.includes("火力2")
);
const fire1Value =
fire1Item && fire1Item.curValue !== null ? fire1Item.curValue : 0;
const fire2Value =
fire2Item && fire2Item.curValue !== null ? fire2Item.curValue : 0;
// Determine which signal should be open based on the logic:
// 大火: fire1=1 and fire2=1
// 小火: fire1=1 and fire2=0
if (signalType === "大火" && fire1Value == 1 && fire2Value == 1) {
return "port-open";
} else if (signalType === "小火" && fire1Value == 1 && fire2Value == 0) {
return "port-open";
} else {
return "port-close";
}
},
// Get fire status text based on both fire signals (for other uses if needed)
getFireStatusText(boiler) {
if (!boiler || !boiler.values) return "未开机";
const fire1Item = boiler.values.find(
(v) => v.otherName && v.otherName.includes("火力1")
);
const fire2Item = boiler.values.find(
(v) => v.otherName && v.otherName.includes("火力2")
);
const fire1Value =
fire1Item && fire1Item.curValue !== null ? fire1Item.curValue : 0;
const fire2Value =
fire2Item && fire2Item.curValue !== null ? fire2Item.curValue : 0;
// If both are 0, boiler is off
if (fire1Value == 0 && fire2Value == 0) {
return "无火信号";
}
// If fire1 is 1 and fire2 is 0, small fire
else if (fire1Value == 1 && fire2Value == 0) {
return "小火控制信号发出";
}
// If both fire1 and fire2 are 1, big fire
else if (fire1Value == 1 && fire2Value == 1) {
return "大火控制信号发出";
}
// Any other case
else {
return "未开机";
}
},
// Get fault information (placeholder implementation)
// Get fault information based on fault code
getFaultInfo(boiler) {
if (!boiler || !boiler.values) return "无故障";
// Find the fault item - you might need to adjust this based on actual data structure
const faultItem = boiler.values.find(
(v) => v.otherName && v.otherName.includes("故障")
);
if (!faultItem || faultItem.curValue === null) {
return "无故障";
}
// Convert fault code to descriptive text
const faultCode = parseInt(faultItem.curValue);
switch (faultCode) {
case 0:
return "无故障";
case 1:
return "炉水温度传感器故障";
case 2:
return "出水温度传感器故障";
case 3:
return "回水温度传感器故障";
case 4:
return "锅炉水位极低";
case 5:
return "燃烧机故障";
case 6:
return "炉水超温";
case 7:
return "循环水流故障";
case 9:
return "定时时间到关机(正常关机模式)";
case 11:
return "烟道传感器故障";
case 12:
return "烟道超温故障";
case 13:
return "检漏故障";
default:
return "未知故障";
}
},
// 获取热水锅炉数据
getHotWaterBoiler() {
let queryParams = {
systemType: "3",
type: "0",
};
hotWaterBoiler(queryParams).then((res) => {
if (res.code == 200) {
console.log("热水锅炉数据", res.rows);
if (res.rows.length > 0) {
this.hotWaterBoilerData = res.rows;
} else {
this.hotWaterBoilerData = [];
}
}
});
},
// 进入系统首页
goSys() {
this.$router.push("/");
},
// 返回上一页
goBack() {
window.history.go(-2);
},
// 监测天数
getDayData() {
runTime().then((res) => {
if (res.code == 200) {
this.dayData = res.data.runTime;
}
});
},
// 报警列表
getAlarnStatus() {
let data = {
pageNum: 1,
pageSize: 10,
status: "0",
};
let timeArr = [getDay(0), getDay(0)];
alarmRecordList(this.addDateRange(data, timeArr)).then((res) => {
if (res.code == 200 && res.rows.length > 0) {
this.isShowWarning = true;
} else {
this.isShowWarning = false;
}
});
},
goWarning() {
this.$router.push("/alarm/alarmRecord");
},
},
};
</script>
<style lang="scss" scoped>
.monitor {
width: 100%;
min-height: 100vh;
background-color: black;
color: #fff;
.monitor-top {
width: 100%;
display: flex;
flex-direction: row;
align-items: flex-start;
justify-content: space-between;
flex-wrap: nowrap;
padding: 0.1rem 0.2rem;
position: relative;
.title-left {
width: 3.41rem;
height: 0.8rem;
}
.title-center {
width: 9.46rem;
height: 0.69rem;
}
.title-right {
width: 5.04rem;
height: 0.78rem;
}
.sys-title {
position: absolute;
top: 40%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 0.28rem;
color: #ffffff;
font-weight: bold;
z-index: 100;
cursor: pointer;
}
.nowTime {
position: absolute;
top: 0.37rem;
right: 0.6rem;
font-size: 0.18rem;
color: #ffffff;
font-weight: bold;
z-index: 100;
}
.sys-logo {
width: 1.8rem;
height: 0.5rem;
position: absolute;
top: 0.26rem;
left: 0.8rem;
z-index: 10;
}
.monitor-time {
position: absolute;
top: 0.44rem;
left: 4.2rem;
z-index: 10;
font-size: 0.18rem;
color: #ffffff;
font-weight: bold;
}
.icon_warning {
position: absolute;
top: 0.39rem;
right: 4.4rem;
z-index: 10;
width: 0.35rem;
height: 0.32rem;
margin: 0 0.25rem 0 0.27rem;
cursor: pointer;
/* 添加闪烁动画 */
animation: blink 1s infinite;
}
@keyframes blink {
100% {
opacity: 1;
}
50% {
opacity: 0;
}
}
.icon_home {
position: absolute;
top: 0.39rem;
right: 4rem;
z-index: 10;
width: 0.35rem;
height: 0.32rem;
margin: 0 0.2rem 0 0.27rem;
cursor: pointer;
}
.back-icon {
position: absolute;
top: 0.39rem;
right: 3.7rem;
z-index: 10;
width: 0.35rem;
height: 0.32rem;
cursor: pointer;
}
}
.hotWater-div {
width: 100%;
padding: 0.2rem;
display: flex;
flex-direction: row;
align-content: stretch;
justify-content: space-between;
.hotWater-li {
width: 49%;
.hotWater {
width: 100%;
padding: 0.25rem 0.2rem;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
.hotWater-img {
width: 6.4rem;
height: 3.5rem;
}
}
.info {
display: flex;
flex-direction: row;
justify-content: center; /* Center content horizontally */
align-items: flex-start; /* Align to top */
width: 100%;
padding: 0 0.25rem 0.15rem 0.7rem;
gap: 0.5rem; /* Add space between elements */
.hotWater-tem {
flex: 1; /* Allow to grow */
min-width: 35%; /* Minimum width */
background: #262f58;
border-radius: 0.1rem;
font-size: 0.16rem;
display: flex;
flex-direction: column;
padding: 0.25rem 0;
.pump-data-li {
width: 100%;
padding: 0 0.4rem; /* Increase horizontal padding */
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
margin: 0.25rem 0;
.pump-data-text {
color: #05d120;
font-weight: bold;
}
}
}
.port-right {
flex: 1; /* Allow to grow */
display: flex;
flex-direction: column;
padding: 0.25rem 0.6rem; /* Increase horizontal padding */
min-width: 35%; /* Minimum width */
.port {
display: flex;
flex-direction: column;
gap: 0.3rem; /* Increase spacing between elements */
.port-li {
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
width: 100%;
font-size: 0.16rem;
color: #c9c6c6;
position: relative;
padding-left: 0.3rem; /* Increase left padding for indicator */
}
.port-open::before,
.port-close::before {
content: "";
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
width: 0.18rem; /* Slightly larger indicator */
height: 0.18rem;
border-radius: 50%;
border: 0.02rem solid white;
}
.port-open::before {
background-color: #00ff00; /* Brighter green for active */
}
.port-close::before {
background-color: #666; /* Darker gray for inactive */
}
}
.bad-div {
margin-top: 0.35rem; /* Increase spacing */
font-size: 0.16rem;
color: #db4d4d;
.bad-text {
margin-left: 0.15rem;
background: #5581c4;
border-radius: 0.15rem; /* Slightly larger radius */
padding: 0.15rem 0.2rem; /* More padding */
color: #fff;
display: inline-block; /* Better text wrapping */
}
}
}
}
}
}
}
</style>
<style scoped>
.special-div .special-title {
padding-left: 0.36rem !important;
font-size: 0.2rem !important;
line-height: 0.23rem !important;
background-size: 1.4rem 0.35rem !important;
background-position: 0px -0.03rem !important;
}
.special-div .special-top {
padding: 0.04rem 0.26rem 0.04rem 0px;
min-height: 0.37rem;
}
</style>