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

1833 lines
57 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="host-detail">
<div class="detail-top">
<div class="detail-top-left">
<img
class="host-img1"
src="../../../assets/images/host-img3.png"
alt=""
v-if="isMagnetic === 'true'"
/>
<img
class="host-img1"
src="../../../assets/images/host-img4.png"
alt=""
v-else
/>
<div class="host-name">{{ deviceName }}</div>
<!-- 冷凝器蒸发器压力-->
<div class="outIn">
<!-- <div class="outIn-li in1">
<svg-icon slot="prefix" icon-class="arrow" class="arrow" />
<div class="kpa">冷凝器压力:{{ condenserPre }}kpa</div>
</div>
<div class="outIn-li out1">
<svg-icon slot="prefix" icon-class="arrow" class="arrow" />
<div class="kpa">蒸发器压力:{{ evaporatorPre }}kpa</div>
</div> -->
<!-- <div class="outIn-li in2">
<svg-icon slot="prefix" icon-class="arrow" class="arrow" />
<div class="kpa">566.6kpa</div>
</div>
<div class="outIn-li out2">
<svg-icon slot="prefix" icon-class="arrow" class="arrow" />
<div class="kpa">566.6kpa</div>
</div> -->
</div>
<!-- 运行状态 -->
<img
src="../../../assets/images/fan-img.png"
:class="{
moveClass: hostListClass('1'),
fanBlade: isMagnetic === 'true',
leftFan: isMagnetic === 'false',
}"
alt=""
/>
<!-- 启停状态 -->
<div class="startClass" v-if="hostListClass('2')"></div>
<!-- 冷冻冷却水流信号 -->
<div class="water-flow3">
<div class="water-flow-li">
<span>冷却水流:</span>
<span v-if="hostListClass('21')">接通</span>
<span v-else>断开</span>
<span
class="break"
:class="{ connect: hostListClass('21') }"
></span>
</div>
<div class="water-flow-li">
<span>冷冻水流:</span>
<span v-if="hostListClass('20')">接通</span>
<span v-else>断开</span>
<span
class="break"
:class="{ connect: hostListClass('20') }"
></span>
</div>
</div>
<div class="hostStatus">
<div class="hostStatus-li">
<span>远程开关机:</span>
<span class="automaticData">{{ onOffObj.curValue }}</span>
</div>
<div class="hostStatus-li">
<span>运行累计时间:</span>
<span class="timeData">{{ timeObj.curValue }}小时</span>
</div>
<div class="hostStatus-li">
<span>本地出水温度设定值:</span>
<span class="dotData">{{ coldWaterSetObj.curValue }}℃</span>
</div>
<div class="hostStatus-li">
<span>远程出水温度设定值:</span>
<span class="goodData">{{ coldWaterControlObj.curValue }}℃</span>
<!-- <span class="badData" v-else>{{ coldWaterControlObj.curValue }}</span> -->
</div>
<div class="hostStatus-li">
<span>冷水设定值偏移:</span>
<!-- <span class="goodData">{{ offsetValuerControlObj.curValue }}℃</span> -->
<span class="goodData">
<el-input
v-model="offsetValuerControlObj.curValue"
size="mini"
@keyup.enter.native="
handleEnter(offsetValuerControlObj, $event)
"
@input="handleInput(offsetValuerControlObj.curValue)"
@blur="handleBlur()"
>
<template #suffix>℃</template></el-input
></span
>
</div>
<div class="hostStatus-li2" @click="openTimeSwitch">
偏移值定时设置
</div>
</div>
<!-- 负载 -->
<LoadData class="loadData" :hostData="hostData"></LoadData>
</div>
<div class="detail-top-right">
<!-- 温度 -->
<host-chart :temArray="temArray"></host-chart>
</div>
</div>
<div class="detail-bottom">
<div class="detail-data hostparams">
<div class="detail-data-top">
<title-img></title-img>
<div class="details-title">主机参数</div>
<title-img></title-img>
</div>
<div class="detail-data-bottom">
<div
class="detail-data-li"
v-for="(item, index) in rightHostData"
:key="index"
>
<div class="rightDot">
<div class="leftDot">
<span>{{ item.otherName }}:</span>
<span
:class="{
dotData: !isSpecialValue(item.curValue),
goodData: isSpecialValue(item.curValue),
badData: item.curValue === '故障',
}"
>{{ item.curValue }}</span
>
<span>{{ item.unit }}</span>
</div>
</div>
</div>
</div>
</div>
<div class="detail-data compressor">
<div class="detail-data-top">
<title-img></title-img>
<div class="choice">
<div>{{ compressorData1.mtTypeName }}</div>
</div>
<title-img></title-img>
</div>
<div class="detail-data-bottom">
<div
class="detail-data-li"
v-for="(subItem, subIndex) in compressorData1.list"
:key="subIndex"
>
<div class="rightDot">
<div class="leftDot">
<span>{{ subItem.otherName }}:</span>
<span
:class="{
dotData: !isSpecialValue(subItem.curValue),
goodData: isSpecialValue(subItem.curValue),
badData: subItem.curValue === '故障',
}"
>{{ subItem.curValue }}</span
>
<span>{{ subItem.unit }}</span>
</div>
</div>
</div>
</div>
</div>
<div class="detail-data compressor">
<div class="detail-data-top">
<title-img></title-img>
<div class="choice">
<div>{{ compressorData2.mtTypeName }}</div>
</div>
<title-img></title-img>
</div>
<div class="detail-data-bottom">
<div
class="detail-data-li"
v-for="(subItem, subIndex) in compressorData2.list"
:key="subIndex"
>
<div class="rightDot">
<div class="leftDot">
<span>{{ subItem.otherName }}:</span>
<span
:class="{
dotData: !isSpecialValue(subItem.curValue),
goodData: isSpecialValue(subItem.curValue),
badData: subItem.curValue === '故障',
}"
>{{ subItem.curValue }}</span
>
<span>{{ subItem.unit }}</span>
</div>
</div>
</div>
</div>
</div>
<div class="detail-data compressor">
<div class="detail-data-top">
<title-img></title-img>
<div class="choice">
<div>{{ compressorData3.mtTypeName }}</div>
</div>
<title-img></title-img>
</div>
<div class="detail-data-bottom">
<div
class="detail-data-li"
v-for="(subItem, subIndex) in compressorData3.list"
:key="subIndex"
>
<div class="rightDot">
<div class="leftDot">
<span>{{ subItem.otherName }}:</span>
<span
:class="{
dotData: !isSpecialValue(subItem.curValue),
goodData: isSpecialValue(subItem.curValue),
badData: subItem.curValue === '故障',
}"
>{{ subItem.curValue }}</span
>
<span>{{ subItem.unit }}</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 定时开关内容 -->
<el-dialog
title="偏移值定时设置"
:visible.sync="isOpenTimeSwitch"
append-to-body
width="800px"
class="custom-dialog"
>
<div class="dialog-content">
<div class="device-container" v-loading="loading">
<div class="device-li">
<div class="device-name">定时名称</div>
<div class="device-name">设置时间1</div>
<div class="device-name">设置时间2</div>
<div class="device-name">偏移值</div>
<div class="device-name">当前设定值</div>
<div class="device-name">最终设定值</div>
<div class="device-name">启动状态</div>
</div>
<div
class="device-li"
v-for="(item, index) in delayList"
:key="index"
:class="{ highlight: item.name.includes(currentWeekday) }"
>
<div class="device-name">{{ item.name }}</div>
<div class="device-name">
<el-form @submit.native.prevent>
<el-form-item>
<el-input
size="mini"
v-model="item.delayOpenHour"
@keyup.enter.native="
handleSwitchEnter(item, 'openHour', $event)
"
@input="handleSwitchInput(item, 'delayOpenHour', 'hour')"
></el-input> </el-form-item
></el-form>
<div class="slip">:</div>
<el-form @submit.native.prevent>
<el-form-item>
<el-input
size="mini"
v-model="item.delayOpenMinute"
@keyup.enter.native="
handleSwitchEnter(item, 'openMinute', $event)
"
@input="
handleSwitchInput(item, 'delayOpenMinute', 'minute')
"
></el-input> </el-form-item
></el-form>
</div>
<div class="device-name">
<el-form @submit.native.prevent>
<el-form-item>
<el-input
size="mini"
v-model="item.delayCloseHour"
@keyup.enter.native="
handleSwitchEnter(item, 'closeHour', $event)
"
@input="handleSwitchInput(item, 'delayCloseHour', 'hour')"
></el-input></el-form-item
></el-form>
<div class="slip">:</div>
<el-form @submit.native.prevent>
<el-form-item>
<el-input
size="mini"
v-model="item.delayCloseMinute"
@keyup.enter.native="
handleSwitchEnter(item, 'closeMinute', $event)
"
@input="
handleSwitchInput(item, 'delayCloseMinute', 'minute')
"
></el-input></el-form-item
></el-form>
</div>
<!-- 三个值,偏移值可输入 -->
<div class="device-name">
<el-form @submit.native.prevent>
<el-form-item>
<el-input
size="mini"
v-model="item.offsetValue"
@keyup.enter.native="
handleSwitchEnter(item, 'offset', $event)
"
@input="handleSwitchInput(item, 'offsetValue', 'offset')"
></el-input></el-form-item
></el-form>
</div>
<div class="device-name">{{ item.curValue }}</div>
<div class="device-name">{{ item.finalOutWaterTemp }}</div>
<div class="device-name">
<el-switch
style="display: block"
active-color="#13ce66"
inactive-color="#ff4949"
active-text="开启"
inactive-text="停用"
v-model="item.delayStatus"
@change="handleSwitchStatus(item)"
>
</el-switch>
</div>
</div>
</div>
</div>
</el-dialog>
</div>
</template>
<script>
import {
hostDetailsData,
hostTemData,
runTime,
operationConrol,
} from "@/api/centerairC/sysMonitor";
import { policyListData } from "@/api/centerairC/strategy";
import { alarmRecordList } from "@/api/alarm/alarmRecord";
import { undateTime } from "@/api/aircAndWindc/index";
import { cpmList } from "@/api/device/gather";
import LoadData from "./components/loadData.vue";
import hostChart from "./components/hostChart.vue";
import titleImg from "./components/titleImg.vue";
import lineSquare from "./components/lineSquare.vue";
import { format } from "@/utils/datetime";
import { getDay } from "@/utils/datetime";
export default {
name: "sysControl",
components: { LoadData, hostChart, titleImg, lineSquare },
data() {
return {
loading: false,
currentDate: new Date(),
nowTimer: null,
deviceName: "", //主机名称
hostData: [], //主机参数
condenserPre: "", //冷凝器压力
evaporatorPre: "", //蒸发器压力
rightHostData: [], //右
onOffObj: {}, //远程开关机
timeObj: {}, //累计运行时间
coldWaterSetObj: {}, //本地出水温度设定值
coldWaterControlObj: {}, //远程出水温度设定值
offsetValuerControlObj: {}, //偏移值设定
compressorData1: [], //压缩机1参数
compressorData2: [],
compressorData3: [],
temArray: [], //冷冻冷却水温度
isMagnetic: false,
isShowWarning: false, //是否有报警
dayData: "", //监测天数
sharedIndex: 0,
isOpenTimeSwitch: false,
delayList: [],
currentWeekday: "",
timer: null, // 用于存储定时器 ID
};
},
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() {},
mounted() {
this.getHostDetailsData();
this.getAlarnStatus();
this.getDayData();
// 在组件挂载后尝试进入全屏
setTimeout(() => {
this.requestFullscreen();
}, 100); // 延迟 100 毫秒执行全屏操作
},
beforeDestroy() {
// 组件销毁前清除定时器
if (this.nowTimer) {
clearInterval(this.nowTimer);
}
},
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();
}
},
// 退出全屏
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() {
this.$router.back();
},
// 监测天数
getDayData() {
runTime().then((res) => {
if (res.code == 200) {
this.dayData = res.data.runTime;
}
});
},
getHostDetailsData() {
//判断当前的url是否有传参
// 获取查询字符串
const search = window.location.search;
// 判断是否有查询参数
const hasQueryParams = search.length > 1;
if (hasQueryParams) {
console.log("当前 URL 有传参");
// 解析查询字符串
const queryParams = {};
const params = search.slice(1).split("&");
params.forEach((param) => {
const [key, value] = param.split("=");
queryParams[key] = decodeURIComponent(value);
});
console.log("传递的参数:", queryParams);
// 获取特定参数
const deviceLedgerId = queryParams.hostId;
this.deviceName = queryParams.hostName;
this.isMagnetic = queryParams.isMagnetic;
console.log("是否是磁悬浮主机", this.isMagnetic);
// 请求主机参数、压缩机参数
this.getHostParams(deviceLedgerId);
// 请求采集位点
this.getCollect(deviceLedgerId);
} else {
}
},
// 主机参数、压缩机参数
getHostParams(id) {
hostDetailsData({ deviceLedgerId: id }).then((res) => {
console.log("主机参数返回", res);
if (res.code == 200) {
let data = res.rows;
data.forEach((item) => {
if (item.mtType === "0") {
// 主机参数
this.hostData = item.list;
// 主机参数分开两列
this.leftHostData = [];
this.rightHostData = [];
// 筛选去掉特定 paramType 的数据
// this.rightHostData = this.hostData.filter((item) => {
// return !["2", "21", "20", "6", "5", "22", "26"].includes(
// Number(item.paramType)
// );
// });
this.rightHostData = this.hostData.filter((item) => {
const specificParamTypes = [26];
// 检查是否属于需要排除的特定 paramType
const isSpecificParamType = specificParamTypes.includes(
Number(item.paramType)
);
const isCombinedCondition0 =
Number(item.paramType) === 2 &&
item.otherName.includes("手动启停");
// 检查是否满足 item.paramType 为 12 且 otherName 包含 "冷水控制设定值"
const isCombinedCondition1 =
Number(item.paramType) === 12 &&
item.otherName.includes("冷水控制设定值");
const isCombinedCondition2 =
Number(item.paramType) === 12 &&
item.otherName.includes("用户冷水设定值");
const isCombinedCondition3 =
Number(item.paramType) === 12 &&
item.otherName.includes("冷水设定值偏移");
// 返回 false 表示要排除该元素
return (
!isSpecificParamType &&
!isCombinedCondition0 &&
!isCombinedCondition1 &&
!isCombinedCondition2 &&
!isCombinedCondition3
);
});
// 根据 ordernum 进行排序
this.rightHostData.sort((a, b) => {
return Number(a.orderNum) - Number(b.orderNum);
});
this.hostData.forEach((item) => {
//左边主机参数 根据不同的 paramType 处理 showValue
if (
item.paramType === "2" &&
item.otherName.includes("手动启停")
) {
// 远程开关机-手动启停
// item.showValue =
// Number(item.curValue) === 0 ? "自动" : "手动";
this.onOffObj = item;
} else if (item.paramType === "26") {
// 累计运行时间
this.timeObj = item;
} else if (
item.paramType === "12" &&
item.otherName.includes("冷水控制设定值")
) {
// 本地出水温度设定值
this.coldWaterSetObj = item;
} else if (
item.paramType === "12" &&
item.otherName.includes("用户冷水设定值")
) {
// 远程出水温度设定值
this.coldWaterControlObj = item;
} else if (
item.paramType === "12" &&
item.otherName.includes("冷水设定值偏移")
) {
// 远程出水温度设定值
this.offsetValuerControlObj = item;
// 检查 curValue 属性是否存在且为有效的数字
if (
this.offsetValuerControlObj.curValue !== undefined &&
!isNaN(parseFloat(this.offsetValuerControlObj.curValue))
) {
// 将 curValue 转换为整数
this.offsetValuerControlObj.curValue = parseInt(
this.offsetValuerControlObj.curValue,
10
);
}
}
});
}
});
// 使用 filter 方法过滤掉 item 为 '0' 的对象
let compressorData = data.filter((obj) => obj.mtType !== "0");
console.log("压缩机数组", this.compressorData);
compressorData.forEach((item) => {
if (item.mtType === "9") {
// 压缩机1
this.compressorData1 = item;
// 根据 ordernum 进行排序
if (
this.compressorData1.list &&
Array.isArray(this.compressorData1.list)
) {
this.compressorData1.list.sort((a, b) => {
return Number(a.orderNum) - Number(b.orderNum);
});
}
}
if (item.mtType === "10") {
// 压缩机2
this.compressorData2 = item;
// 对 this.compressorData2 对象中的 list 数组进行排序
if (
this.compressorData2.list &&
Array.isArray(this.compressorData2.list)
) {
this.compressorData2.list.sort((a, b) => {
return Number(a.orderNum) - Number(b.orderNum);
});
}
}
if (item.mtType === "11") {
// 压缩机3
this.compressorData3 = item;
if (
this.compressorData3.list &&
Array.isArray(this.compressorData3.list)
) {
this.compressorData3.list.sort((a, b) => {
return Number(a.orderNum) - Number(b.orderNum);
});
}
}
});
}
});
},
// 采集参数列表
getCollect(id) {
let data = {
pageNum: 1,
pageSize: 10000,
deviceLedgerId: id,
};
cpmList(data).then((res) => {
console.log("采集位点返回", res);
if (res.code == 200) {
// 过滤掉结果,只保留冷冻冷却进出水温度
let data = res.rows;
let newDataArray = []; // 用于存储符合条件的对象的新数组
data.forEach((item) => {
if (
item.otherName.includes("冷冻回水温度") ||
item.otherName.includes("冷冻供水温度") ||
item.otherName.includes("冷却回水温度") ||
item.otherName.includes("冷却供水温度") ||
item.otherName.includes("负载")
) {
let dataItem = {
name: item.otherName,
value: item.id,
};
newDataArray.push(dataItem);
}
});
console.log("处理后的数组···", newDataArray);
// 请求温度
this.getTemData(newDataArray);
}
});
},
// 冷冻冷却进出水温度图表数据
getTemData(array) {
const start = new Date(new Date().setHours(0, 0, 0, 0));
const end = new Date(new Date().setHours(23, 59, 59, 59));
let data = {
timeType: "min",
startTime: format(start),
endTime: format(end),
pageNum: 0,
pageSize: 10,
searchParams: array,
systemType: "0",
};
hostTemData(data).then((res) => {
console.log("进出水温度返回值", res);
if (res.code == 200 && res.data.length > 0) {
this.temArray = res.data;
}
});
},
hostListClass(paramType) {
for (let i = 0; i < this.hostData.length; i++) {
const item = this.hostData[i];
if (
item.paramType === paramType &&
typeof item.curValue === "string" &&
/[\u4e00-\u9fa5]/.test(item.curValue)
) {
switch (item.paramType) {
case "1": // 运行状态
if (item.curValue === "运行") {
return true;
}
break;
case "2": // 启停
if (item.curValue === "启动" && item.otherName.includes("启停")) {
return true;
}
break;
case "5": // 故障
if (item.curValue === "正常") {
return true;
}
break;
case "6": // 手自动切换
if (item.curValue === "自动") {
return true;
}
break;
case "22": // 本地远程切换
if (item.curValue === "远程") {
return true;
}
break;
default:
return false;
break;
}
} else {
if (item.paramType === paramType && Number(item.curValue) !== 0) {
return true;
}
}
}
// 否则
return false;
},
// 报警列表
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");
},
// 判断 curValue 是否为特定值
isSpecialValue(value) {
const specialValues = ["运行", "启动", "正常"];
return specialValues.includes(value);
},
// 处理输入事件,过滤非数字字符
handleInput(item) {
console.log("校验");
// 实时校验并过滤非数字字符
let input = String(item).replace(/[^\d]/g, "");
// 检查输入是否以 0 开头且长度大于 1,如果是则去掉开头的 0
if (input.startsWith("0") && input.length > 1) {
input = input.replace(/^0+/, "");
}
this.offsetValuerControlObj.curValue = input;
},
// 失去焦点
handleBlur() {
// this.currentFocusIndex = "";
},
handleEnter(item, event) {
console.log("请求后端", item);
if (!item) {
this.$modal.msgError("请输入偏移值");
return;
}
// 失去焦点
event.target.blur();
this.$confirm(
`确定要修改冷水设定值偏移的温度为:${item.curValue} ℃吗?`,
"提示",
{
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}
)
.then(() => {
this.hadleOperationConrol(item.id, item.curValue);
})
.catch(() => {
// 用户取消操作,需要更新原来的频率
// this.$emit("upList");
this.getHostDetailsData();
});
},
// 操作
hadleOperationConrol(id, param) {
let data = {
id: id,
param: param,
};
console.log("操作参数", data);
operationConrol([data])
.then((res) => {
if (res.code == 200) {
this.$modal.msgSuccess("指令下发成功!");
// 开启 loading 效果
this.loading = true;
// 更新所有设备状态;
setTimeout(() => {
this.getHostDetailsData();
this.loading = false;
}, 5000);
} else {
// this.$modal.msgError("操作失败");
console.log("应该更新状态的");
// 更新所有设备状态;
this.getHostDetailsData();
}
})
.catch((error) => {
console.log("请求发生错误,更新设备状态", error);
// 更新所有设备状态;
this.getHostDetailsData();
});
},
// 打开定时开关弹框
openTimeSwitch() {
this.isOpenTimeSwitch = true;
this.getPolicyList();
},
// 请求列表
getPolicyList() {
return new Promise((resolve, reject) => {
let data = {
systemType: "0",
funPolicyType: "4",
};
policyListData(data)
.then((res) => {
console.log("设备定时开关返回res", res);
if (res.code === 200) {
let handleList = res.rows;
this.delayList = [];
handleList.forEach((element, index) => {
if (element.values && element.values.length > 0) {
// 初始化一个空对象来存储非蝶阀处理后的结果
let delayItem = {
name: element.name,
};
const limitedChildren = element.values;
limitedChildren.forEach((child) => {
// console.log("定时${index}开_时", `定时${index}开_时`);
// console.log("child.pointName", child.pointName);
if (child.pointName) {
// 时间设置1-小时
if (child.pointName.includes(`偏移值设置时间${index + 1}-开时1`)) {
// console.log("定时开机-时·························");
delayItem.delayOpenHour = child.curValue;
delayItem.delayOpenHourId = child.id;
}
// 时间设置1-分钟
else if (
child.pointName.includes(`偏移值设置时间${index + 1}-开分1`)
) {
delayItem.delayOpenMinute = child.curValue;
delayItem.delayOpenMinuteId = child.id;
}
// 时间设置2-小时
else if (
child.pointName.includes(`偏移值设置时间${index + 1}-关时2`)
) {
delayItem.delayCloseHour = child.curValue;
delayItem.delayCloseHourId = child.id;
}
// 时间设置2-分钟
else if (
child.pointName.includes(`偏移值设置时间${index + 1}-关分2`)
) {
delayItem.delayCloseMinute = child.curValue;
delayItem.delayCloseMinuteId = child.id;
}
// 偏移值
else if (child.pointName.includes(`偏移值${index + 1}`)) {
delayItem.offsetValue = child.curValue;
delayItem.offsetValueId = child.id;
}
// 当前出水温度设置
else if (child.pointName.includes("出水温度设置")) {
delayItem.curValue = child.curValue;
delayItem.curValueId = child.id;
}
// 启动状态
else if (child.pointName.includes(`启动标志`)) {
delayItem.delayStatus =
Number(child.curValue) == 0 ? false : true;
delayItem.delayStatusId = child.id;
}
}
});
// 计算最终出水温度设置值
const offsetValue =
delayItem.offsetValue !== null &&
delayItem.offsetValue !== ""
? parseFloat(delayItem.offsetValue)
: NaN;
const curValue =
delayItem.curValue !== null && delayItem.curValue !== ""
? parseFloat(delayItem.curValue)
: NaN;
if (!isNaN(offsetValue) && !isNaN(curValue)) {
delayItem.finalOutWaterTemp = offsetValue + curValue;
}
// 将处理后的对象添加到 delayList 中
if (Object.keys(delayItem).length > 1) {
this.delayList.push(delayItem);
}
}
});
console.log("处理后的数组", this.delayList);
// this.delayList = res.rows;
} else {
this.delayList = [];
}
// 成功时解析 Promise
resolve(res);
})
.catch((error) => {
// 失败时拒绝 Promise
reject(error);
});
});
},
// 处理输入事件,过滤非数字字符
handleSwitchInput(item, propertyName, name) {
console.log("校验", item[propertyName]);
// 如果值为空,不进行后续校验
if (item[propertyName] === "") {
return;
}
let isValid = true;
// 实时校验并过滤非数字字符
let inputValue = String(item[propertyName]).replace(/[^\d]/g, "");
if (name === "hour") {
isValid =
!isNaN(inputValue) &&
parseInt(inputValue) >= 0 &&
parseInt(inputValue) <= 23;
if (!isValid) {
this.$message.error("输入值在0-23区间,请重新输入");
item[propertyName] = "";
return;
}
} else if (name === "minute") {
isValid =
!isNaN(inputValue) &&
parseInt(inputValue) >= 0 &&
parseInt(inputValue) <= 59;
if (!isValid) {
this.$message.error("输入值在0-59区间,请重新输入");
item[propertyName] = "";
return;
}
} else if (name === "offset") {
isValid = !isNaN(inputValue) && parseInt(inputValue) >= 0;
if (!isValid) {
this.$message.error("输入值大于0,请重新输入");
item[propertyName] = "";
return;
}
}
item[propertyName] = inputValue;
},
handleSwitchEnter(item, name, event) {
console.log("item", item);
console.log("接收到的事件对象:", event);
// 阻止事件的默认行为
if (event && event.preventDefault) {
event.preventDefault();
}
// 失去焦点
event.target.blur();
let id = "";
let value = "";
let title = "";
let unit = "";
if (name === "openHour") {
id = item.delayOpenHourId;
value = item.delayOpenHour;
title = "设置时间1-小时";
unit = "时";
} else if (name === "openMinute") {
id = item.delayOpenMinuteId;
value = item.delayOpenMinute;
title = "设置时间1-分钟";
unit = "分";
} else if (name === "closeHour") {
id = item.delayCloseHourId;
value = item.delayCloseHour;
title = "设置时间2-小时";
unit = "时";
} else if (name === "closeMinute") {
id = item.delayCloseMinuteId;
value = item.delayCloseMinute;
title = "设置时间2-分钟";
unit = "分";
} else if (name === "offset") {
id = item.offsetValueId;
value = item.offsetValue;
title = "偏移值";
unit = "";
}
if (value === "") {
this.$message.warning("请输入当前设置值!");
return;
}
console.log("请求后端", item);
this.$confirm(
`确定要把"${item.name}"的${title}设置为:${value} ${unit}吗?`,
"提示",
{
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}
)
.then(() => {
// console.log("打印id",id)
this.handleSwitchOperationConrol(id, value);
})
.catch(() => {
// 用户取消操作,需要更新原来的值
this.getPolicyList();
});
},
handleSwitchOperationConrol(id, param) {
let data = {
policyId: id,
timeValue: param,
};
// console.log("操作参数", data);
// 开启 loading 效果
this.loading = true;
undateTime(data)
.then((res) => {
if (res.code == 200) {
this.$modal.msgSuccess("指令下发成功!");
// 开启 loading 效果
// this.loading = true;
// 更新所有设备状态;
setTimeout(() => {
this.getPolicyList();
// 关闭 loading 效果
this.loading = false;
}, 500);
} else {
// 关闭 loading 效果
this.loading = false;
// this.$modal.msgError("操作失败");
console.log("应该更新状态的");
// 更新所有设备状态;
this.getPolicyList();
}
})
.catch((error) => {
// 关闭 loading 效果
this.loading = false;
console.log("请求发生错误,更新设备状态", error);
// 更新所有设备状态;
this.getPolicyList();
});
},
// 启用状态
handleSwitchStatus(item) {
this.$confirm(
`确定要切换"${item.name}"的状态为:${
item.delayStatus ? "开启" : "停用 吗?"
}`,
"提示",
{
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}
)
.then(() => {
// 这里调用请求函数
console.log("请求后台", item.delayStatus);
let param = null;
if (item.delayStatus) {
param = 1;
} else {
param = 0;
}
this.handleSwitchOperationConrol(item.delayStatusId, param);
})
.catch(() => {
// 用户取消操作,恢复开关状态
item.delayStatus = !item.delayStatus;
console.log("不请求后台");
});
},
},
};
</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;
}
}
.host-detail {
padding: 0.2rem;
width: 100%;
display: flex;
flex-direction: column;
.detail-top {
width: 100%;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
.detail-top-left {
height: 4.8rem;
// background-color: aquamarine;
position: relative;
.host-img1 {
width: 4.48rem;
height: 3.57rem;
margin: 0.2rem 0 0 0.2rem;
}
.outIn {
position: absolute;
left: 4.8rem;
top: 1rem;
display: flex;
flex-direction: column;
.outIn-li {
display: flex;
flex-direction: row;
align-items: center;
width: 2rem;
height: 1rem;
font-weight: bold;
// background-color: #e2aeae;
.arrow {
font-size: 0.3rem;
z-index: 10;
}
.kpa {
font-size: 0.18rem;
z-index: 10;
}
}
.in1 {
position: absolute;
top: 1.3rem;
left: 0.2rem;
color: rgb(123, 212, 247);
}
.out1 {
position: absolute;
top: 1.6rem;
left: 0.18rem;
color: rgb(38, 122, 218);
.arrow {
transform: scaleX(-1);
}
}
.in2 {
position: absolute;
top: 1.9rem;
left: -0.4rem;
color: rgb(235, 120, 206);
}
.out2 {
position: absolute;
top: 2.2rem;
left: -0.4rem;
color: rgb(240, 56, 95);
.arrow {
transform: scaleX(-1);
}
}
}
/* 定义灯闪烁的动画 */
@keyframes blink {
0% {
opacity: 1;
}
50% {
opacity: 0.7;
}
100% {
opacity: 1;
}
}
.startClass {
z-index: 10;
position: absolute;
top: 2.2rem;
left: 2.7rem;
width: 0.18rem;
height: 0.18rem;
border-radius: 50%;
animation: blink 1s infinite;
background-color: #38fc52 !important;
}
.hostStatus {
z-index: 10;
position: absolute;
top: 0.6rem;
left: 4.9rem;
display: flex;
flex-direction: column;
justify-content: flex-start;
width: 2.8rem !important;
margin-top: 1.5rem;
.hostStatus-li {
background-color: #25455a;
color: #c0dffc;
font-size: 0.16rem;
margin-bottom: 0.1rem;
padding: 0.1rem;
letter-spacing: 0.02rem;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-items: flex-start;
span {
white-space: nowrap;
}
}
.hostStatus-li2 {
background-color: #136bf0;
color: #ffffff;
font-size: 0.16rem;
margin-bottom: 0.1rem;
padding: 0.1rem;
letter-spacing: 0.02rem;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
border-radius: 0.1rem;
cursor: pointer;
}
.hostStatus-li2:hover {
background-color: #217af0;
}
}
.water-flow3 {
z-index: 10;
position: absolute;
top: 3.5rem;
left: 1.2rem;
.water-flow-li {
margin-bottom: 0.04rem;
color: #46f1e3;
font-size: 0.18rem;
display: flex;
flex-direction: row;
align-items: center;
span {
background-color: rgba(0, 255, 255, 0.2);
border-radius: 0.1rem;
padding: 0.01rem 0.03rem;
}
.break {
margin-left: 0.07rem;
display: inline-block;
width: 0.18rem;
height: 0.18rem;
border-radius: 50%;
border: 1px solid #46f1e3;
background-color: transparent !important;
}
.connect {
animation: blink 1s infinite;
background-color: #38fc52 !important;
}
}
}
/* 定义 host 动画关键帧 */
@keyframes host {
0% {
/* 修改初始旋转角度 */
transform: translateX(-50%) rotateX(15deg) rotateZ(0deg);
}
100% {
/* 修改结束旋转角度 */
transform: translateX(-50%) rotateX(15deg) rotateZ(360deg);
}
}
.fanBlade {
z-index: 10;
position: absolute;
top: 2.5rem;
left: 4.1rem;
width: 0.5rem;
height: 0.5rem;
transform-style: preserve-3d;
transform: translateX(-50%) rotateX(15deg) rotateZ(20deg)
rotateY(40deg);
}
.leftFan {
z-index: 10;
position: absolute;
top: 2.29rem;
left: 0.53rem;
width: 0.5rem;
height: 0.5rem;
transform-style: preserve-3d;
transform: translateX(-50%) rotateX(0deg) rotateZ(0deg) rotateY(-0deg);
}
.moveClass {
animation: host 2s linear infinite;
}
.host-name {
z-index: 10;
position: absolute;
top: 1.6rem;
left: 1.44rem;
color: #2925f8;
font-weight: bold;
font-size: 0.18rem;
}
.loadData {
z-index: 10;
position: absolute;
top: 0rem;
left: 5rem;
}
}
.detail-top-right {
width: calc(100% - 7.6rem);
height: 4.8rem;
// background-color: rgb(127, 172, 255);
}
}
.detail-bottom {
// height: 5rem;
margin-top: 0.3rem;
margin-left: 0.25rem;
display: flex;
flex-direction: row;
justify-content: space-between;
.detail-data {
display: flex;
flex-direction: column;
// width: 4rem;
position: relative;
.detail-data-top {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
color: #c0dffc;
font-weight: bold;
font-size: 0.18rem;
width: 100%;
text-align: center;
z-index: 10;
.details-title {
margin: 0 0.15rem;
}
}
.detail-data-bottom {
width: 100%;
// padding: 0.1rem 0.3rem;
z-index: 0;
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: stretch;
justify-content: flex-start;
.detail-data-li {
// width: 100%;
margin-right: 0.1rem;
margin-bottom: 0.15rem !important;
position: relative;
color: #c0dffc;
font-family: Arial, sans-serif;
letter-spacing: 0.02rem;
font-size: 0.18rem;
position: relative;
margin-bottom: 0.2rem;
border-left: 0.01rem solid #217df5;
border-right: 0.01rem solid #217df5;
background-image: radial-gradient(
circle at left top,
#217df5 0.01rem,
transparent 0.01rem
),
radial-gradient(
circle at right top,
#217df5 0.01rem,
transparent 0.01rem
),
radial-gradient(
circle at left bottom,
#217df5 0.01rem,
transparent 0.01rem
),
radial-gradient(
circle at right bottom,
#217df5 0.01rem,
transparent 0.01rem
);
background-repeat: no-repeat;
background-position: left top, right top, left bottom, right bottom;
}
.detail-data-li::before,
.detail-data-li::after {
content: "";
position: absolute;
left: 0;
right: 0;
height: 0.01rem;
background-image: linear-gradient(
to right,
#217df5 0%,
rgba(41, 128, 185, 0) 50%,
#217df5 100%
);
}
.detail-data-li::before {
top: 0;
}
.detail-data-li::after {
bottom: 0;
}
.rightDot {
position: relative;
width: 100%;
height: 100%;
}
.leftDot {
position: relative;
width: 100%;
height: 100%;
padding: 0.04rem 0.1rem;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
}
.rightDot::before {
content: "";
position: absolute;
top: -0.03rem;
right: -0.03rem;
width: 0.06rem;
height: 0.06rem;
background-color: #217df5;
box-shadow: 0 0 0.1rem 0.02rem rgba(33, 125, 245, 0.9);
background-image: radial-gradient(
circle at 30% 30%,
rgba(255, 255, 255, 0.8) 0%,
rgba(255, 255, 255, 0) 70%
);
border-radius: 50%;
z-index: 10;
}
.rightDot::after {
content: "";
position: absolute;
bottom: -0.03rem;
right: -0.03rem;
width: 0.06rem;
height: 0.06rem;
background-color: #217df5;
box-shadow: 0 0 0.1rem 0.02rem rgba(33, 125, 245, 0.9);
background-image: radial-gradient(
circle at 30% 30%,
rgba(255, 255, 255, 0.8) 0%,
rgba(255, 255, 255, 0) 70%
);
border-radius: 50%;
z-index: 10;
}
.leftDot::before {
content: "";
position: absolute;
top: -0.03rem;
left: -0.03rem;
width: 0.06rem;
height: 0.06rem;
background-color: #217df5;
border-radius: 50%;
z-index: 10;
box-shadow: 0 0 0.1rem 0.02rem rgba(33, 125, 245, 0.9);
background-image: radial-gradient(
circle at 30% 30%,
rgba(255, 255, 255, 0.8) 0%,
rgba(255, 255, 255, 0) 70%
);
}
.leftDot::after {
content: "";
position: absolute;
bottom: -0.03rem;
left: -0.03rem;
width: 0.06rem;
height: 0.06rem;
background-color: #217df5;
z-index: 10;
box-shadow: 0 0 0.1rem 0.02rem rgba(33, 125, 245, 0.9);
background-image: radial-gradient(
circle at 30% 30%,
rgba(255, 255, 255, 0.8) 0%,
rgba(255, 255, 255, 0) 70%
);
border-radius: 50%;
}
}
.line1 {
position: absolute;
top: 0rem;
}
}
.hostparams {
width: 7rem;
.detail-data-bottom {
// padding-left: 0.5rem;
.detail-data-li {
// width: 3.2rem;
width: calc(50% - 0.2rem) !important;
margin: 0 0.1rem;
}
}
}
.compressor {
width: 3.5rem;
.detail-data-bottom {
// padding-left: 0.75rem;
.detail-data-li {
// width: 3.4rem;
width: calc(100%) !important;
margin: 0 0.1rem;
}
}
}
}
}
}
.choice {
margin-left: 0 !important;
}
.choice .mr20 {
width: 1rem !important;
color: #c0dffc;
font-weight: bold !important;
font-size: 0.18rem !important;
text-align: center !important;
background-color: transparent !important;
box-shadow: none !important;
}
.timeStyle {
color: #ffffff !important;
}
.dotData {
font-weight: bold;
margin: 0 0.06rem;
color: #3b80ff;
display: flex;
align-items: center;
}
.goodData {
font-weight: bold;
margin: 0 0.06rem;
color: #3df574;
}
.badData {
font-weight: bold;
margin: 0 0.06rem;
color: #cf3607;
}
.automaticData {
font-weight: bold;
margin: 0 0.06rem;
color: #da7b10;
}
.timeData {
font-weight: bold;
margin: 0 0.06rem;
color: #1df3e8;
}
</style>
<style scoped>
.goodData >>> .el-input--mini {
font-size: 0.16rem !important;
display: flex;
flex-direction: row;
align-items: center;
}
.goodData >>> .el-input {
width: 1rem !important;
}
.goodData >>> .el-input--mini .el-input__inner {
height: 0.28rem !important;
line-height: 20.28rem !important;
}
.goodData >>> .el-input__inner {
font-weight: bold;
box-shadow: none !important;
}
.goodData >>> .el-input__suffix {
font-weight: bold;
right: 0.05rem !important;
height: 100% !important;
top: -0.01rem !important;
}
.device-name:nth-child(3) {
margin-left: 30px !important;
}
.device-name {
justify-content: center !important;
align-items: center !important;
}
.device-name .slip {
margin: 0 5px;
}
.device-name >>> .el-form {
width: 50px !important;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
flex-wrap: nowrap;
}
.device-name >>> .el-form-item {
margin-bottom: 0 !important;
}
.device-name >>> .el-input {
width: 50px !important;
}
.device-name {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
flex-wrap: nowrap;
}
</style>