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

1094 lines
29 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">蒸汽锅炉监测</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="boiler">
<div class="boiler-top">
<div class="boiler-relative">
<!-- 锅炉定位 -->
<img
src="../../../assets/images/boiler.png"
class="boiler-img"
alt=""
/>
<!-- 其他文字定位 -->
<div class="status-div">
<div>当前工作状态</div>
<div class="status-text">
{{ getStatusText(getStatusValue("DB611658")) }}
</div>
</div>
<div class="fire-div">
<div>火焰强度</div>
<div class="fire-text">
{{ getStatusValue("DB611724") }}
</div>
</div>
<div class="runtime-div">
<div>设备运行时长</div>
<div class="fire-text">
{{ formatToOneDecimal(getStatusValue("DB8296") / 60) }}小时
</div>
</div>
<div class="other-div">
<div class="other-li">
<div>当前压力</div>
<div class="mpa">{{ getStatusValue("DB611500") }} Mpa</div>
</div>
<div class="other-li">
<div>设定压力</div>
<div class="mpa">{{ getStatusValue("DBW611598") }} Mpa</div>
</div>
<div class="other-li">
<div>启动压差</div>
<div class="mpa">{{ getStatusValue("DBW611600") }} Mpa</div>
</div>
<div class="other-li">
<div>停止压差</div>
<div class="mpa">{{ getStatusValue("DBW611602") }} Mpa</div>
</div>
</div>
<div class="flow-other-div">
<div class="other-li">
<div>温度瞬值</div>
<div class="mpa">{{ getStatusValue("PLC1500_DB8300") }} ℃</div>
</div>
<div class="other-li">
<div>压力瞬值</div>
<div class="mpa">{{ getStatusValue("PLC1500_DB8304") }} Mpa</div>
</div>
<div class="other-li">
<div>流量瞬值</div>
<div class="mpa">{{ getStatusValue("PLC1500_DB8308") }} t/h</div>
</div>
<div class="other-li">
<div>流量累计</div>
<div class="mpa">{{ getStatusValue("PLC1500_DB8320") }} t</div>
</div>
</div>
<div></div>
<div class="air">空气</div>
<div class="gas">燃气</div>
<div class="flue-div">
<div class="flue-text">{{ getStatusValue("DB611496") }}℃</div>
<div>烟气</div>
</div>
<!-- 锅炉上方百分比 -->
<div class="orange"></div>
<!-- 火焰 -->
<img
src="../../../assets/images/boilerWork.gif"
class="boilerWork"
:style="{
display: getStatusValue('DB611724') > 100 ? 'block' : 'none',
}"
alt=""
/>
<!-- 锅炉侧边水位 -->
<div class="level">{{ getStatusValue("DB611736") }}%</div>
<div class="waterlevel">
<div
class="progress"
:style="{ height: (getStatusValue('DB611736') || 0) + '%' }"
></div>
</div>
<!-- 燃气阀 -->
<img
class="gasValve-img"
:src="
getStatusValue('DBB611629') > 1
? require('../../../assets/images/gasWork.png')
: require('../../../assets/images/gasStop.png')
"
alt=""
/>
<div class="mainValve">主阀</div>
<img
class="mainValve-img"
:src="
getStatusValue('DBB611639') > 1
? require('../../../assets/images/workValve.png')
: require('../../../assets/images/stopValve.png')
"
alt=""
/>
<div class="auxiliaryValve">副阀</div>
<img
class="auxiliaryValve-img"
:src="
getStatusValue('DBB611640') > 1
? require('../../../assets/images/workValve.png')
: require('../../../assets/images/stopValve.png')
"
alt=""
/>
<div class="fan-div">
<div class="fan-text">{{ getStatusValue("DB611514") }}rpm</div>
<div>风机</div>
</div>
<img
class="blade1"
:class="{ move: getStatusValue('DB611514') > 0 }"
src="../../../assets/images/blade2.png"
alt=""
/>
<div class="waterPump-div">
<div>水泵</div>
<!-- <div class="pump-text">手动加水停</div> -->
</div>
<img
class="blade2"
:class="{
move:
getStatusValue('DBB611635') > 0 ||
getStatusValue('DBB611637') > 0,
}"
src="../../../assets/images/blade1.png"
alt=""
/>
<div class="waterBox">水箱</div>
</div>
<div class="special-div">
<div class="special-top">
<div class="special-title">
<div class="title-left">
<div>当前报警信息</div>
</div>
</div>
</div>
<div class="warn-list">
<div
class="warn-li"
v-for="(item, index) in steamBoilerData.alarmDatas"
:key="index"
>
<div
class="warn-left"
:class="item.curValue == 1 ? 'alarm-left' : ''"
>
<img
src="../../../assets/images/alarm.png"
class="alarm-icon"
alt=""
/>
</div>
<div class="warn-right">{{ item.otherName }}</div>
</div>
</div>
</div>
</div>
<div class="boiler-bottom">
<div class="special-div one">
<div class="special-top">
<div class="special-title">
<div class="title-left">
<div>模拟量监测</div>
</div>
</div>
</div>
<div class="boiler-monitor">
<div
class="monitor-li"
v-for="(item, index) in steamBoilerData.aoDatas"
:key="index"
>
{{ item.otherName }}:{{
item.curValue !== null && item.curValue !== undefined
? item.curValue
: "--"
}}{{ item.unit || "" }}
</div>
</div>
</div>
<div class="special-div two">
<div class="special-top">
<div class="special-title">
<div class="title-left">
<div>继电器</div>
</div>
</div>
</div>
<div class="relay">
<div
class="relay-li"
v-for="(item, index) in steamBoilerData.doDatas"
:key="index"
>
<div :class="[item.curValue == 1 ? 'relay-open' : 'relay-close']">
{{ item.curValue == 1 ? "ON" : "OFF" }}
</div>
<div>{{ item.otherName }}</div>
</div>
</div>
</div>
<div class="special-div three">
<div class="special-top">
<div class="special-title">
<div class="title-left">
<div>端口输入</div>
</div>
</div>
</div>
<div class="port">
<div
v-for="(item, index) in this.steamBoilerData.diDatas"
:key="index"
:class="[
'port-li',
item.curValue == 1 ? 'port-open' : 'port-close',
]"
>
{{ item.otherName }}
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import { runTime } from "@/api/centerairC/sysMonitor";
import { alarmRecordList } from "@/api/alarm/alarmRecord";
import { steamBoilerBoiler } from "@/api/boiler/steamBoiler";
import { getDay } from "@/utils/datetime";
export default {
name: "boilerMonitorDetails",
data() {
return {
loading: false,
currentDate: new Date(),
nowTimer: null,
isShowWarning: false, //是否有报警
dayData: "", //监测天数
currentWeekday: "",
// 蒸汽锅炉数据
// 蒸汽锅炉数据
steamBoilerData: {
diDatas: [],
doDatas: [],
aoDatas: [],
runDatas: [],
alarmDatas: [],
},
};
},
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();
// 在组件挂载后尝试进入全屏
setTimeout(() => {
this.requestFullscreen();
}, 100); // 延迟 100 毫秒执行全屏操作
// 获取蒸汽锅炉数据
this.getSteamBoiler();
},
beforeDestroy() {
// 组件销毁前清除定时器
if (this.nowTimer) {
clearInterval(this.nowTimer);
}
},
methods: {
// Format number to one decimal place
formatToOneDecimal(value) {
if (value === null || value === undefined) {
return null;
}
const num = parseFloat(value);
if (isNaN(num)) {
return value;
}
return num.toFixed(1);
},
// Get status value from runDatas where mtNum = DB611658
getStatusValue(mtNum) {
if (
!this.steamBoilerData.runDatas ||
!Array.isArray(this.steamBoilerData.runDatas)
) {
return null;
}
const statusItem = this.steamBoilerData.runDatas.find(
(item) =>
item.mtNum === mtNum &&
item.curValue !== null &&
item.curValue !== undefined
);
return statusItem ? statusItem.curValue : null;
},
// Get status text based on status value
getStatusText(statusValue) {
if (statusValue === null || statusValue === undefined) {
return "未知";
}
const statusMap = {
0: "上电延时",
1: "关机",
2: "待机",
3: "前清扫",
4: "预点火",
5: "点火",
6: "传火",
7: "工作",
8: "后清扫",
9: "故障",
10: "小火保持",
11: "自检",
12: "检漏",
13: "开点火器",
14: "启动等待中",
};
return statusMap[statusValue] || "未知";
},
getSteamBoiler() {
// type 0:代表查询动画界面数据,1:代表查询模拟量监测数据,2:代表查询继电器数据,3:查询端口输入数据,4:代表查询报警数据
// 0:代表查询动画界面数据
let queryData = {
systemType: "3",
type: 0,
};
steamBoilerBoiler(queryData).then((res) => {
if (res.code == 200) {
this.steamBoilerData.runDatas = res.rows;
console.log("蒸汽锅炉数据", this.steamBoilerData.runDatas);
}
});
// 1:代表查询模拟量监测数据
queryData.type = 1;
steamBoilerBoiler(queryData).then((res) => {
if (res.code == 200) {
this.steamBoilerData.aoDatas = res.rows;
console.log("蒸汽锅炉模拟量监测数据", this.steamBoilerData.aoDatas);
}
});
// 2:代表查询继电器数据
queryData.type = 2;
steamBoilerBoiler(queryData).then((res) => {
if (res.code == 200) {
this.steamBoilerData.doDatas = res.rows;
console.log("蒸汽锅炉继电器数据", this.steamBoilerData.doDatas);
}
});
// 3:代表查询端口输入数据
queryData.type = 3;
steamBoilerBoiler(queryData).then((res) => {
if (res.code == 200) {
this.steamBoilerData.diDatas = res.rows;
console.log("蒸汽锅炉端口输入数据", this.steamBoilerData.diDatas);
}
});
// 4:代表报警数据
queryData.type = 4;
steamBoilerBoiler(queryData).then((res) => {
if (res.code == 200) {
this.steamBoilerData.alarmDatas = res.rows;
console.log("蒸汽锅炉报警数据", this.steamBoilerData.alarmDatas);
}
});
},
// 全屏操作
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();
}
},
// 退出全屏
exitFullscreen() {
if (document.exitFullscreen) {
document.exitFullscreen();
} else if (document.mozCancelFullScreen) {
// Firefox
document.mozCancelFullScreen();
} else if (document.webkitExitFullscreen) {
// Chrome, Safari and Opera
document.webkitExitFullscreen();
} else if (document.msExitFullscreen) {
// IE/Edge
document.msExitFullscreen();
}
},
// 进入系统首页
goSys() {
// this.exitFullscreen();
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.exitFullscreen();
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;
}
.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;
}
}
.boiler {
width: 100%;
padding: 0.2rem;
display: flex;
flex-direction: column;
.boiler-top {
width: 100%;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: stretch;
flex-wrap: nowrap;
margin-bottom: 0.35rem;
.boiler-relative {
width: 58%;
position: relative;
height: 5.6rem;
font-size: 0.16rem;
color: #fff;
.boiler-img {
width: 8.9rem;
height: 4.5rem;
position: absolute;
bottom: 0;
left: 1.2rem;
}
.air {
position: absolute;
top: 1.2rem;
left: 1.1rem;
}
.gas {
position: absolute;
top: 1.2rem;
left: 2.4rem;
}
.mainValve {
position: absolute;
top: 2.9rem;
left: 2rem;
}
.auxiliaryValve {
position: absolute;
top: 3.8rem;
left: 2rem;
}
.gasValve-img {
position: absolute;
top: 1.73rem;
left: 2.6rem;
width: 0.5rem;
height: 0.4rem;
}
.mainValve-img {
position: absolute;
top: 2.81rem;
left: 2.6rem;
width: 0.6rem;
height: 0.5rem;
}
.auxiliaryValve-img {
position: absolute;
top: 3.67rem;
left: 2.6rem;
width: 0.6rem;
height: 0.5rem;
}
.other-div {
display: flex;
flex-direction: column;
align-items: center;
position: absolute;
top: -0.1rem;
left: 7.3rem;
.other-li {
display: flex;
flex-direction: row;
align-items: flex-end;
margin-bottom: 0.1rem;
.mpa {
color: #eb6912;
font-weight: bold;
margin-left: 0.2rem;
text-align: center;
}
}
}
.flow-other-div {
display: flex;
flex-direction: column;
align-items: center;
position: absolute;
top: -0.1rem;
left: 9.2rem;
.other-li {
display: flex;
flex-direction: row;
align-items: flex-end;
margin-bottom: 0.1rem;
.mpa {
color: #eb6912;
font-weight: bold;
margin-left: 0.2rem;
text-align: center;
}
}
}
.fan-div {
display: flex;
flex-direction: column;
align-items: center;
position: absolute;
top: 4.2rem;
left: 3.83rem;
.fan-text {
margin-bottom: 0.01rem;
font-weight: bold;
}
}
.blade1 {
position: absolute;
top: 4.67rem;
left: 3.76rem;
width: 0.8rem;
height: 0.8rem;
}
.blade2 {
position: absolute;
top: 3.34rem;
left: 7.74rem;
width: 0.6rem;
height: 0.6rem;
}
.move {
animation: continuousRotation 3s linear infinite;
}
@keyframes continuousRotation {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
.flue-div {
display: flex;
flex-direction: column;
align-items: center;
position: absolute;
top: 1rem;
left: 3.65rem;
.flue-text {
margin-bottom: 0.01rem;
color: #eb6912;
font-weight: bold;
}
}
.orange {
position: absolute;
top: 1.65rem;
left: 5.4rem;
font-weight: bold;
}
.level {
position: absolute;
top: 1.7rem;
left: 7.5rem;
font-weight: bold;
}
.waterlevel {
width: 0.46rem;
height: 1.425rem;
// background-color: #dff1fa;
margin-left: 2%;
position: absolute;
top: 1.15rem;
left: 6.71rem;
// border: solid 0.01rem #11aaea;
border-radius: 0.04rem;
overflow: hidden;
z-index: 3;
.progress {
background-color: #1167db;
width: 100%;
position: absolute;
bottom: 0;
z-index: 3;
}
}
.waterBox {
position: absolute;
top: 2.9rem;
right: 0.9rem;
}
.waterPump-div {
display: flex;
flex-direction: column;
align-items: center;
position: absolute;
top: 4.15rem;
right: 2.63rem;
.pump-text {
margin-top: 0.03rem;
padding: 0.02rem 0.05rem;
color: #575452;
font-weight: bold;
background: #b3b3b3;
/* 添加边框 */
border: 2px solid #c0c0c0;
/* 添加圆角 */
border-radius: 0.04rem;
/* 添加阴影 */
box-shadow: 0 0 10px rgba(2, 2, 2, 0.3);
}
}
.status-div {
display: flex;
flex-direction: column;
align-items: center;
position: absolute;
top: 0.2rem;
left: 0.7rem;
.status-text {
margin-top: 0.06rem;
color: #fa7217;
font-weight: bold;
}
}
.fire-div {
display: flex;
flex-direction: column;
align-items: center;
position: absolute;
top: 0.2rem;
left: 2.3rem;
.fire-text {
margin-top: 0.06rem;
color: #fa7217;
font-weight: bold;
}
}
.runtime-div {
display: flex;
flex-direction: column;
align-items: center;
position: absolute;
top: 0.2rem;
left: 3.5rem;
.fire-text {
margin-top: 0.06rem;
color: #fa7217;
font-weight: bold;
}
}
.boilerWork {
position: absolute;
top: 2.85rem;
left: 5.15rem;
width: 0.8rem;
height: 1.5rem;
}
}
.special-div {
width: 40%;
.warn-list {
width: 100%;
padding: 0.15rem;
display: flex;
flex-direction: row;
flex-wrap: wrap;
.warn-li {
width: 25%;
// padding: 0 0.1rem;
display: flex;
flex-direction: row;
align-items: center;
margin-bottom: 0.1rem;
}
.warn-left {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 0.3rem;
height: 0.3rem;
border-radius: 0.05rem;
background: linear-gradient(
to bottom,
white 0%,
gray 50%,
white 100%
);
margin-right: 0.1rem;
.alarm-icon {
width: 0.2rem;
height: 0.2rem;
}
}
.warn-right {
color: #fff;
font-size: 0.16rem;
}
.alarm-left {
background: linear-gradient(to bottom, #ff0000 0%, #ff0066 100%);
}
}
}
}
.boiler-bottom {
width: 100%;
display: flex;
flex-direction: row;
align-items: stretch;
justify-content: space-between;
.one {
width: 28%;
.boiler-monitor {
margin: 0.15rem;
width: calc(100% - 0.3rem);
display: flex;
flex-direction: row;
flex-wrap: wrap;
/* 防止子元素溢出 */
box-sizing: border-box;
font-size: 0.16rem;
color: #fff;
/* 添加左边框和上边框 */
border-left: 1px solid #999999;
border-top: 1px solid #999999;
.monitor-li {
width: 50%;
padding: 0.1rem 0;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
/* 只添加右边框和下边框 */
border-right: 1px solid #999999;
border-bottom: 1px solid #999999;
box-sizing: border-box;
background: #30303f;
}
}
}
.two {
width: 28%;
.relay {
width: 100%;
padding: 0.25rem 0.5rem;
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-between;
.relay-li {
display: flex;
flex-direction: row;
align-items: center;
width: 50%;
font-size: 0.16rem;
margin-bottom: 0.2rem;
color: #c9c6c6;
.relay-open {
width: 0.4rem;
height: 0.3rem;
color: #fff;
background: #1e60f0;
font-size: 0.16rem;
text-align: center;
line-height: 0.3rem;
margin-right: 0.15rem;
}
.relay-close {
width: 0.4rem;
height: 0.3rem;
color: #c2c2c2;
background: #474747;
font-size: 0.16rem;
text-align: center;
line-height: 0.3rem;
margin-right: 0.15rem;
}
}
}
}
.three {
width: 40%;
.port {
width: 100%;
padding: 0.25rem 0.5rem;
display: flex;
flex-direction: row;
flex-wrap: wrap;
// justify-content: space-between;
.port-li {
display: flex;
flex-direction: row;
align-items: center;
width: 33.33%;
font-size: 0.16rem;
margin-bottom: 0.2rem;
color: #c9c6c6;
position: relative;
padding-left: 0.25rem; /* 为伪元素留出空间 */
}
.port-open::before,
.port-close::before {
content: "";
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
width: 0.15rem;
height: 0.15rem;
border-radius: 50%;
border: 0.02rem solid white;
}
.port-open::before {
background-color: rgb(16, 184, 24);
}
.port-close::before {
background-color: gray;
}
}
}
}
}
}
</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>