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

1470 lines
48 KiB

<template>
<div class="app-container" v-loading="loading">
<div class="left-tree">
<!-- el-tree 设置一个固定的高度和滚动条 -->
<div style="height: 7.5rem; overflow-y: auto">
<el-tree
ref="tree"
:data="treeData"
node-key="id"
:default-expand-all="false"
:default-expanded-keys="expandedKeys"
:auto-expand-parent="true"
icon-class="none"
@node-expand="handleNodeExpand"
@node-collapse="handleNodeCollapse"
:highlight-current="true"
@node-click="handleNodeClick"
>
<template #default="{ node }">
<span class="custom-tree-node">
<!-- 根据节点状态动态设置图标类名 -->
<div class="tree-left">
<i :class="getIconClass(node)" class="custom-tree-icon"></i>
<span class="tree-label">{{ node.label }}</span>
</div>
</span>
</template>
</el-tree>
</div>
</div>
<div class="right-monitor">
<div class="buildingDiv">
<img
class="title-bg"
src="../../../assets/images/title-bg.png"
alt=""
/>
<div class="title-word">楼层{{ currentName }}</div>
</div>
<div class="details-header">
<el-tabs v-model="activeName" @tab-click="handleClick">
<!-- 使用 v-for 指令遍历 tabsList 数组 -->
<el-tab-pane
v-for="device in tabsList"
:key="device.id"
:label="device.name"
:name="device.name"
>
<!-- 这里可以添加每个 tab 对应的内容 -->
</el-tab-pane>
</el-tabs>
</div>
<div class="monitor-context">
<div
class="monitor-li"
v-for="item in devicesList"
:key="item.deviceId"
>
<div class="monitor-title">{{ item.name }}</div>
<div class="monitor-flex">
<!-- 热泵 -->
<div class="monitor-flex-left" v-if="activeName.includes('热泵')">
<div class="control-top">
<img
class="monitor-img1"
src="../../../assets/images/starthotpum.png"
/>
<div class="monitor-words">
<div class="words-li">
<div class="ash">开关状态:</div>
<div class="white">
<el-select
v-model="item.hotPumpStatus"
placeholder="请选择"
@change="handleHotPump(item)"
>
<el-option
v-for="item in hotPumpOptions"
:key="item.value"
:label="item.label"
:value="item.value"
>
</el-option>
</el-select>
</div>
</div>
<div class="words-li">
<div class="ash">故障信息:</div>
<el-tag
size="mini"
v-if="item.alarmStatus === '无故障'"
type="success"
>{{ item.alarmStatus }}</el-tag
>
<el-tag size="mini" v-else type="danger">{{
item.alarmStatus
}}</el-tag>
</div>
<div class="words-li">
<div class="ash">实际温度:</div>
<div class="white">{{ item.temp }}℃</div>
</div>
<div class="words-li">
<div class="ash">设定温度:</div>
<div class="white">
<el-input
size="mini"
v-model="item.tempSet"
placeholder="请输入"
@keyup.enter.native="
handleEnter(
item,
item.tempSet,
item.tempSetId,
'设定温度',
'℃'
)
"
@input="handleInput(item)"
@blur="handleBlur()"
></el-input>
</div>
</div>
</div>
</div>
</div>
<!-- 裙楼供水泵、高区供水泵、中厨供水泵 -->
<div class="monitor-flex-left" v-if="activeName.includes('供水泵')">
<div class="control-top">
<img
class="monitor-img2"
src="../../../assets/images/startpum.png"
/>
<div class="monitor-words">
<div class="words-li">
<div class="ash" style="letter-spacing: 5px">
频率手自动:
</div>
<div class="white">
<el-switch
style="display: block"
v-model="item.handAutomaticSwitch"
active-color="#13ce66"
active-text="手动"
inactive-text="自动"
@change="handAutomatic(item)"
>
</el-switch>
</div>
</div>
<div class="words-li">
<div class="ash" style="letter-spacing: 7px">
启停&nbsp;控制:
</div>
<div class="white">
<el-switch
style="display: block"
v-model="item.switchStatus"
active-color="#13ce66"
active-text="开启"
inactive-text="停止"
@change="handleSwitch(item)"
>
</el-switch>
</div>
</div>
</div>
</div>
<div class="control-bottom">
<div class="words-li">
<div class="ash">故障信息:</div>
<el-tag
size="mini"
v-if="item.alarmStatus === '无故障'"
type="success"
>{{ item.alarmStatus }}</el-tag
>
<el-tag size="mini" v-else type="danger">{{
item.alarmStatus
}}</el-tag>
</div>
<div class="words-li">
<div class="ash">运行状态:</div>
<el-tag
size="mini"
v-if="item.runningStatus === '运行'"
type="success"
>{{ item.runningStatus }}</el-tag
>
<el-tag size="mini" v-else type="danger">{{
item.runningStatus
}}</el-tag>
</div>
<div class="words-li">
<div class="ash">当前频率:</div>
<div class="white">{{ item.frequency }}Hz</div>
</div>
<div class="words-li">
<div class="ash">频率设置:</div>
<el-input
v-model="item.frequencySet"
@keyup.enter.native="
handleEnter(
item,
item.frequencySet,
item.frequencySetId,
'频率设置',
'Hz'
)
"
@input="handleInput(item)"
@blur="handleBlur()"
size="mini"
></el-input>
<div class="white">Hz</div>
</div>
<div class="words-li">
<div class="ash">压力设置:</div>
<el-input
v-model="item.pressureSet"
@keyup.enter.native="
handleEnter(
item,
item.pressureSet,
item.pressureSetId,
'压力设置',
'bar'
)
"
@input="handleInput(item)"
@blur="handleBlur()"
size="mini"
></el-input>
<div class="white">bar</div>
</div>
<div class="words-li">
<div class="ash">停机延时:</div>
<el-input
v-model="item.delayTimeSet"
@keyup.enter.native="
handleEnter(
item,
item.delayTimeSet,
item.delayTimeSetId,
'停机延时',
'S'
)
"
@input="handleInput(item)"
@blur="handleBlur()"
size="mini"
></el-input>
<div class="white">S</div>
</div>
<div class="words-li">
<div class="ash">换机时间:</div>
<el-input
v-model="item.counterSet"
@keyup.enter.native="
handleEnter(
item,
item.counterSet,
item.counterSetId,
'换机时间',
'次'
)
"
@input="handleInput(item)"
@blur="handleBlur()"
size="mini"
></el-input>
<div class="white">次</div>
</div>
<div class="words-li">
<div class="white">一次50分钟</div>
</div>
</div>
</div>
<!-- 裙楼供水泵、高区供水泵、中厨回水泵 -->
<div class="monitor-flex-left" v-if="activeName.includes('回水')">
<div class="control-top">
<img
class="monitor-img3"
src="../../../assets/images/pump.png"
/>
<div class="monitor-words">
<div class="words-li">
<div class="ash">回水温度:</div>
<div class="white">{{ item.temp }}℃</div>
</div>
<div class="words-li">
<div class="ash">回水温度设置:</div>
<el-input
v-model="item.tempSet"
@keyup.enter.native="
handleEnter(
item,
item.tempSet,
item.tempSetId,
'回水温度',
'℃'
)
"
@input="handleInput(item)"
@blur="handleBlur()"
size="mini"
></el-input>
<div class="white">℃</div>
</div>
<div class="words-li">
<div class="ash">回水温度设定差值:</div>
<el-input
v-model="item.diffValueSet"
@keyup.enter.native="
handleEnter(
item,
item.diffValueSet,
item.diffValueSetId,
'回水温度设定差值',
'℃'
)
"
@input="handleInput(item)"
@blur="handleBlur()"
size="mini"
></el-input>
<div class="white">℃</div>
</div>
<div class="words-li">
<div class="ash">回水温度设定延时时间:</div>
<el-input
v-model="item.delayTimeSet"
@keyup.enter.native="
handleEnter(
item,
item.delayTimeSet,
item.delayTimeSetId,
'回水温度设定延时时间',
'S'
)
"
@input="handleInput(item)"
@blur="handleBlur()"
size="mini"
></el-input>
<div class="white">min</div>
</div>
</div>
</div>
</div>
<!-- 水箱 -->
<div class="monitor-flex-left" v-if="activeName.includes('水箱')">
<div class="control-top">
<water-tank :waterLevel="item.waterLevel"></water-tank>
<div class="monitor-words">
<div class="words-li">
<div class="ash">补水阀启停:</div>
<div class="white">
<el-switch
style="display: block"
v-model="item.switchStatus"
active-color="#13ce66"
active-text="开启"
inactive-text="停止"
@change="handleSwitch(item)"
>
</el-switch>
</div>
</div>
</div>
</div>
<div class="control-bottom">
<div class="words-li words-li5">
<div class="ash">实际液位:</div>
<div class="white">{{ item.waterLevel }} %</div>
</div>
<div class="words-li words-li5">
<div class="ash ash2">设置液位:</div>
<el-input
size="mini"
v-model="item.waterLevelSet"
placeholder="请输入"
@keyup.enter.native="
handleEnter(
item,
item.waterLevelSet,
item.waterLevelSetId,
'液位设置',
'%'
)
"
@input="handleWaterInput(item)"
></el-input>
<div class="white">%</div>
</div>
<div class="words-li words-li6">
<div class="ash">液位设定延时时间:</div>
<el-input
size="mini"
v-model="item.delayTimeSet"
placeholder="请输入"
@keyup.enter.native="
handleEnter(
item,
item.delayTimeSet,
item.delayTimeSetId,
'液位设定延时时间',
'min'
)
"
@input="handleWaterInput(item)"
></el-input>
<div class="white">min</div>
</div>
<div class="words-li words-li2">
<div class="ash ash2">液位误差值:</div>
<el-input
size="mini"
v-model="item.diffValueSet"
placeholder="请输入"
@keyup.enter.native="
handleEnter(
item,
item.diffValueSet,
item.diffValueSetId,
'液位误差值',
'%'
)
"
@input="handleWaterInput(item)"
></el-input>
<div class="white">%</div>
</div>
<div class="words-li words-li2">
<div class="ash">时间:</div>
<div class="white">{{ item.curTime }}</div>
</div>
</div>
</div>
<!-- 高区、中厨、中区、裙楼 -->
<div
class="monitor-flex-left"
v-if="
activeName === '裙楼' ||
activeName === '中厨' ||
activeName === '高区' ||
activeName === '中区'
"
>
<div class="control-top">
<img
class="monitor-img2"
src="../../../assets/images/startpum.png"
/>
<div class="monitor-words">
<div class="words-li">
<div class="ash" style="letter-spacing: 8px">一键启动:</div>
<div class="white">
<el-switch
style="display: block"
v-model="item.openSwitch"
active-color="#13ce66"
active-text="开启"
inactive-text="停止"
@change="handleAllStart(item)"
>
</el-switch>
</div>
</div>
<!-- <div class="words-li">
<div class="ash">停止:</div>
<div class="white">
<el-switch
style="display: block"
v-model="item.closeSwitch"
active-color="#13ce66"
active-text=""
inactive-text=""
@change="handleAllEnd(item)"
>
</el-switch>
</div>
</div> -->
</div>
</div>
<div class="control-bottom">
<div class="words-li words-li3">
<div class="ash">供水温度:</div>
<div class="white">{{ item.temp }}℃</div>
</div>
<div class="words-li words-li4">
<div class="ash">供水温度设定:</div>
<el-input
v-model="item.tempSet"
size="mini"
@keyup.enter.native="
handleEnter(
item,
item.tempSet,
item.tempSetId,
'供水温度设定',
'℃'
)
"
@input="handleInput(item)"
@blur="handleBlur()"
></el-input>
<div class="white">℃</div>
</div>
<div class="words-li words-li3">
<div class="ash">供水压力</div>
<div class="white">{{ item.pressure }}bar</div>
</div>
<div class="words-li words-li4">
<div class="ash">温度偏差值:</div>
<el-input
v-model="item.diffValueSet"
@keyup.enter.native="
handleEnter(
item,
item.diffValueSet,
item.diffValueSetId,
'温度偏差值',
'℃'
)
"
@input="handleInput(item)"
@blur="handleBlur()"
size="mini"
></el-input>
<div class="white">℃</div>
</div>
<div class="words-li words-li3">
<div class="ash">故障信息:</div>
<el-tag
size="mini"
v-if="item.alarmStatus === '无故障'"
type="success"
>{{ item.alarmStatus }}</el-tag
>
<el-tag size="mini" v-else type="danger">{{
item.alarmStatus
}}</el-tag>
</div>
<!-- <div class="words-li words-li4">
<div class="ash">补水延时时间设定:</div>
<el-input
v-model="item.delayTimeSet"
@keyup.enter.native="
handleEnter(
item,
item.delayTimeSet,
item.delayTimeSetId,
'补水延时时间设定',
'S'
)
"
@input="handleInput(item)"
@blur="handleBlur()"
size="mini"
></el-input>
<div class="white">S</div>
</div> -->
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import { spaceTree } from "@/api/region";
import { waterOperateList, operationConrol } from "@/api/hotWater/waterControl";
import waterTank from "../../components/waterTank.vue";
export default {
name: "WaterControl",
components: { waterTank },
data() {
return {
loading: false,
treeData: [],
defaultProps: {
children: "children",
label: "label",
},
tabsList: [],
expandedKeys: [],
hotPumpOptions: [
{
label: "关机",
value: 0,
},
{
label: "制冷",
value: 2,
},
{
label: "制热",
value: 3,
},
{
label: "热水",
value: 4,
},
],
currentId: "", //当前选中高亮的id
currentName: "", //当前选中的名称
currentLevel: "", //当前节点的层级
activeName: "", //默认选中
tabsList: [], //tab列表
devicesList: [], //设备列表
isInitialPage: true, //记录是否初始页面
isNodeClicked: false, //记录是否点击了tree
};
},
mounted() {
this.getSysBuild();
},
methods: {
getSysBuild() {
spaceTree().then((res) => {
if (res.code == 200) {
// 只需要保留热水的系统
console.log("楼栋返回值", res);
let newRes = { ...res };
if (newRes.data && newRes.data[0] && newRes.data[0].children) {
newRes.data[0].children = newRes.data[0].children.filter((item) => {
// 假设子项有一个 label属性,用于检查是否包含 "热水"
return item.label && item.label.includes("热水");
});
}
// 指定要保留的最大层级(从 1 开始计数),这里假设指定为第 4 级
const targetLevel = 4;
// 从 data[0] 开始处理,当前层级为 1
if (newRes.data[0]) {
this.removeChildrenAfterLevel(newRes.data[0], 1, targetLevel);
}
console.log("筛选后的新结果", newRes);
this.treeData = newRes.data;
this.$nextTick(() => {
// 默认展开节点
this.getExpandedKeys(this.treeData, 2);
if (this.treeData.length > 0) {
// 找到最后一层的第一个子节点
const lastLevelFirstChild = this.findLastLevelFirstChild(
this.treeData[0]
);
// this.$refs.tree.setCurrentKey(
// this.treeData[0].children[0].children[0].children[0].id
// );
// 设置当前选中的节点,默认高亮
this.$refs.tree.setCurrentKey(lastLevelFirstChild.id);
// 更新当前节点的信息
this.currentId = lastLevelFirstChild.id;
this.currentLevel = lastLevelFirstChild.level;
this.currentName = lastLevelFirstChild.label;
console.log("当前选中节点ID", this.currentId);
console.log("当前选中节点层级", this.currentLevel);
console.log("当前选中节点名称", this.currentName);
this.getWaterList();
}
});
}
});
},
// 递归函数,用于去除指定层级往后的 children 数据
removeChildrenAfterLevel(obj, currentLevel, targetLevel) {
if (currentLevel >= targetLevel) {
// 当达到指定层级时,将 children 属性置为空数组
obj.children = [];
return;
}
if (obj.children && obj.children.length > 0) {
// 若存在 children 数组,则递归处理每个子项
for (let i = 0; i < obj.children.length; i++) {
this.removeChildrenAfterLevel(
obj.children[i],
currentLevel + 1,
targetLevel
);
}
}
},
// 递归函数,找到最后一层的第一个子节点
findLastLevelFirstChild(node, level = 1) {
if (!node.children || node.children.length === 0) {
return {
id: node.id,
level,
label: node.label,
};
}
return this.findLastLevelFirstChild(node.children[0], level + 1);
},
// 默认只展示一二级菜单
getExpandedKeys(nodes, level) {
nodes.forEach((node) => {
if (level <= this.currentId + 4) {
this.expandedKeys.push(node.id);
}
if (node.children) {
this.getExpandedKeys(node.children, level + 1);
}
});
},
// 更换图标
getIconClass(node) {
// console.log("当前图标的节点内容", node);
if (node.level === 4) {
// 4级菜单时的图标
if (node.expanded) {
return "el-icon-document-opened"; // 三级菜单展开时的图标类名
}
return "el-icon-document"; // 三级菜单收缩时的图标类名
}
if (node.expanded) {
return "el-icon-folder-opened"; // 非三级菜单展开时的图标类名
}
return "el-icon-folder-add"; // 非三级菜单收缩时的图标类名
},
handleNodeExpand(node) {
// 节点展开时触发
},
handleNodeCollapse(node) {
// 节点收缩时触发
},
// 点击当前节点,保存节点内容
handleNodeClick(node, data) {
console.log("点击的当前节点", node, data);
this.isNodeClicked = true; // 设置标志位为 true,表示节点被点击
if (data.level !== 4) {
console.log("不是第4层000");
// 设置当前选中的节点,默认高亮
this.$refs.tree.setCurrentKey(this.currentId);
console.log("当前选中节点ID", this.currentId);
console.log("当前选中节点层级", this.currentLevel);
console.log("当前选中节点名称", this.currentName);
} else {
console.log("第4层111");
this.currentId = node.id;
this.currentLevel = data.level;
this.currentName = node.label;
// 设置当前选中的节点,默认高亮
this.$refs.tree.setCurrentKey(this.currentId);
console.log("当前选中节点ID", this.currentId);
console.log("当前选中节点层级", this.currentLevel);
console.log("当前选中节点名称", this.currentName);
this.getWaterList();
}
},
handleClick(tab, event) {
this.isNodeClicked = false; // 表示切换tab但并未点击tree
console.log(tab, event);
console.log("activeName", this.activeName);
// 根据 tab 的 name 从 tabsList 中找到对应的 item,处理得到devicesList
const currentItem = this.tabsList.find((item) => item.name === tab.name);
console.log("currentItem--=----", currentItem);
if (currentItem.children.length > 0) {
this.devicesList = [];
currentItem.children.forEach((item) => {
if (item.name) {
// 在每次迭代时创建一个新的 deviceItem 对象
let deviceItem = {
...item,
waterLevel: Number(item.waterLevel),
runningStatus: Number(item.runningStatus) == 0 ? "停止" : "运行", //运行状态
hotPumpStatus: item.switchStatus, //热泵开关状态
switchStatus: Number(item.switchStatus) == 0 ? false : true, //启停控制
alarmStatus: Number(item.alarmStatus) == 0 ? "无故障" : "故障", //故障状态
handAutomaticSwitch:
Number(item.handAutomaticSwitch) == 1 ? false : true, //手自动状态
openSwitch: Number(item.openSwitch) == 0 ? false : true, //一键启动
closeSwitch: Number(item.closeSwitch) == 0 ? false : true, //一键停止
};
// 将处理后的对象添加到 devicesList 中
this.devicesList.push(deviceItem);
}
});
console.log("当前楼层water列表", this.devicesList);
}
},
// 失去焦点
handleBlur() {},
// 获取热水设备列表
getWaterList() {
return new Promise((resolve, reject) => {
let data = {
systemType: "1",
floorId: this.currentId,
};
waterOperateList(data)
.then((res) => {
if (res.code == 200 && res.rows.length > 0) {
console.log("页面请求数据了~~~~~~~~~~~", res.rows);
this.tabsList = res.rows;
// 初始页面的时候默认选择第一个tabs,否则不设置
if (this.isInitialPage) {
this.activeName = res.rows[0].name;
this.isInitialPage = false;
console.log("初始页面默认tabs", this.activeName);
} else {
console.log("非初始页面默认tabs", this.activeName);
// 判断是勾选了tree还是tabs控制更新,
if (this.isNodeClicked) {
// tree
this.activeName = res.rows[0].name;
console.log("非初始页面默认tabs-点击tree", this.activeName);
} else {
this.activeName = this.activeName;
console.log("非初始页面默认tabs-tabs中更新", this.activeName);
}
}
// 根据 tab 的 name 从 tabsList 中找到对应的 item,处理得到devicesList
const currentItem = this.tabsList.find(
(item) => item.name === this.activeName
);
console.log("currentItem--=----", currentItem);
if (currentItem.children.length > 0) {
this.devicesList = [];
currentItem.children.forEach((item) => {
if (item.name) {
// 在每次迭代时创建一个新的 deviceItem 对象
let deviceItem = {
...item,
waterLevel: Number(item.waterLevel),
runningStatus:
Number(item.runningStatus) == 0 ? "运行" : "停止", //运行状态
hotPumpStatus: item.switchStatus, //热泵开关状态
switchStatus:
Number(item.switchStatus) == 0 ? false : true, //启停控制
alarmStatus:
Number(item.alarmStatus) == 0 ? "无故障" : "故障", //故障状态
handAutomaticSwitch:
Number(item.handAutomaticSwitch) == 0 ? false : true, //手自动状态
openSwitch: Number(item.openSwitch) == 0 ? false : true, //一键启动
closeSwitch: Number(item.closeSwitch) == 0 ? false : true, //一键停止
};
// 将处理后的对象添加到 devicesList 中
this.devicesList.push(deviceItem);
}
});
console.log("当前楼层water列表", this.devicesList);
}
} else {
this.tabsList = [];
this.devicesList = [];
this.activeName = "";
}
// 成功时解析 Promise
resolve(res);
})
.catch((error) => {
// 失败时拒绝 Promise
reject(error);
});
});
},
// 一键启动
handleAllStart(item) {
this.$confirm(
`确定要 ${item.openSwitch ? "一键开启" : "关闭一键开启"} ${
item.name
}的设备吗?`,
"提示",
{
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}
)
.then(() => {
console.log("请求后台", item.openSwitch);
let param = null;
if (item.openSwitch) {
param = 1;
} else {
param = 0;
}
this.hadleOperationConrol(item.openSwitchId, param);
})
.catch(() => {
// 用户取消操作,恢复开关状态
item.openSwitch = !item.openSwitch;
});
},
// 一键停止
handleAllEnd(item) {
this.$confirm(
`确定要 ${item.closeSwitch ? "一键停止" : "关闭一键停止"} ${
item.name
}的设备吗?`,
"提示",
{
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}
)
.then(() => {
console.log("请求后台", item.closeSwitch);
let param = null;
if (item.closeSwitch) {
param = 1;
} else {
param = 0;
}
this.hadleOperationConrol(item.closeSwitchId, param);
})
.catch(() => {
// 用户取消操作,恢复开关状态
item.closeSwitch = !item.closeSwitch;
});
},
// input设置
handleEnter(item, value, id, set, unit) {
this.$confirm(
`确定要修改"${item.name}"的${set}为:${value} ${unit}吗?`,
"提示",
{
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}
)
.then(() => {
this.hadleOperationConrol(id, value);
})
.catch(() => {});
},
// 设置热泵开关状态
handleHotPump(item) {
// 记录原始状态
const originalStatus = item.hotPumpStatus;
// 根据 value 值获取对应的 label
let statusLabel = "";
switch (item.hotPumpStatus) {
case 0:
statusLabel = "关机";
break;
case 2:
statusLabel = "制冷";
break;
case 3:
statusLabel = "制热";
break;
case 4:
statusLabel = "热水";
break;
}
this.$confirm(
`确定要切换设备"${item.name}"的状态为:${statusLabel} 吗?"`,
"提示",
{
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}
)
.then(() => {
this.hadleOperationConrol(item.switchStatusId, item.hotPumpStatus);
})
.catch(() => {
// 用户取消操作,恢复状态
item.hotPumpStatus = originalStatus;
});
},
// 设置供水泵手自动状态
handAutomatic(item) {
this.$confirm(
`确定要切换设备"${item.name}"的状态为:${
item.handAutomaticSwitch ? "手动" : "自动 吗?"
}`,
"提示",
{
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}
)
.then(() => {
// 这里调用请求函数,示例中只是简单打印信息
console.log("请求后台", item.handAutomaticSwitch);
let param = null;
if (item.handAutomaticSwitch) {
param = 0;
} else {
param = 1;
}
this.hadleOperationConrol(item.handAutomaticSwitchId, param);
})
.catch(() => {
// 用户取消操作,恢复开关状态
item.handAutomaticSwitch = !item.handAutomaticSwitch;
});
},
// 设置启停控制
handleSwitch(item) {
this.$confirm(
`确定要切换设备"${item.name}"的状态为:${
item.switchStatus ? "开启" : "停止 吗?"
}`,
"提示",
{
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}
)
.then(() => {
// 这里调用请求函数,示例中只是简单打印信息
console.log("请求后台", item.switchStatus);
let param = null;
if (item.switchStatus) {
param = 1;
} else {
param = 0;
}
this.hadleOperationConrol(item.switchStatusId, param);
})
.catch(() => {
// 用户取消操作,恢复开关状态
item.switchStatus = !item.switchStatus;
});
},
// 处理输入事件,过滤非数字字符
handleInput(item) {
console.log("校验");
// 实时校验并过滤非数字和非小数点字符
item.tempSet = String(item.tempSet).replace(/[^\d.]/g, "");
// 确保只有一个小数点
const parts = item.tempSet.split(".");
if (parts.length > 2) {
// 如果有多个小数点,只保留第一个小数点及之前的部分和第一个小数点之后的部分
item.tempSet = parts[0] + "." + parts[1];
}
// 确保小数点后最多两位
if (parts.length === 2) {
item.tempSet = parts[0] + "." + parts[1].slice(0, 2);
}
},
handleWaterInput(item) {
item.waterLevelSet = String(item.waterLevelSet).replace(/[^\d.]/g, "");
// 确保只有一个小数点
const parts = item.waterLevelSet.split(".");
if (parts.length > 2) {
// 如果有多个小数点,只保留第一个小数点及之前的部分和第一个小数点之后的部分
item.waterLevelSet = parts[0] + "." + parts[1];
}
// 确保小数点后最多两位
if (parts.length === 2) {
item.waterLevelSet = parts[0] + "." + parts[1].slice(0, 2);
}
},
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.getWaterList().finally(() => {
// 关闭 loading 效果
this.loading = false;
});
}, 5000);
} else {
// this.$modal.msgError("操作失败");
console.log("应该更新状态的");
// 更新所有设备状态;
this.getWaterList();
}
})
.catch((error) => {
console.log("请求发生错误,更新设备状态", error);
// 更新所有设备状态;
this.getWaterList();
});
},
},
};
</script>
<style lang="scss" scoped>
.app-container {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: stretch;
height: 100%;
.left-tree {
width: 256px;
padding: 15px 10px;
border: 1px solid #004b8c;
min-height: 800px;
.status {
display: flex;
flex-direction: row;
justify-content: space-between;
flex-wrap: wrap;
margin-top: 20px;
.status-li {
width: 50%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
margin-bottom: 15px;
}
.status1,
.status2,
.status3,
.status4 {
display: flex;
flex-direction: row;
align-items: center;
margin-bottom: 5px;
}
.status1::before {
content: "";
width: 10px;
height: 10px;
border-radius: 50%;
background-color: #00d2ff;
margin-right: 5px;
}
.status2::before {
content: "";
width: 10px;
height: 10px;
border-radius: 50%;
background-color: #ff2f2f;
margin-right: 5px;
}
.status3::before {
content: "";
width: 10px;
height: 10px;
border-radius: 50%;
background-color: #ff9908;
margin-right: 5px;
}
.status4::before {
content: "";
width: 10px;
height: 10px;
border-radius: 50%;
background-color: #7398c7;
margin-right: 5px;
}
}
}
.right-monitor {
width: calc(100% - 280px);
display: flex;
flex-direction: column;
justify-content: flex-start;
.buildingDiv {
padding-left: 54px;
display: flex;
flex-direction: row;
align-items: center;
margin-bottom: 20px;
position: relative;
.title-bg {
width: 208px;
height: 38px;
position: absolute;
left: 0;
z-index: 0;
}
.title-word {
z-index: 10;
font-family: YouSheBiaoTiHei;
font-size: 24px;
color: #ffffff;
white-space: nowrap;
}
}
.monitor-context {
height: 640px;
width: 100%;
overflow-y: auto;
display: flex;
flex-direction: row;
align-items: flex-start;
justify-content: flex-start;
flex-wrap: wrap;
align-content: flex-start;
}
}
.monitor-context {
height: 650px;
width: 100%;
overflow-y: auto;
display: flex;
flex-direction: row;
align-items: flex-start;
justify-content: flex-start;
flex-wrap: wrap;
align-content: flex-start;
.monitor-li {
display: flex;
flex-direction: column;
align-items: center;
min-height: 160px;
width: calc(33.33% - 20px);
margin: 0 10px;
padding-bottom: 25px;
margin-bottom: 16px !important;
background: linear-gradient(
to top,
rgba(0, 94, 173, 0.6) 0%,
rgba(0, 94, 173, 0.1) 100%
);
overflow: hidden;
position: relative;
border-radius: 10px;
.monitor-title {
width: 100%;
height: 50px;
background-image: url(../../../assets/images/gate-title.png);
background-size: 100% 100%;
background-repeat: no-repeat;
font-family: SourceHanSansCN-Bold;
font-size: 18px;
line-height: 40px;
letter-spacing: 0px;
color: #ffffff;
text-align: center;
}
.monitor-flex {
width: 100%;
display: flex;
flex: 1;
flex-direction: row;
align-items: center;
justify-content: space-between;
margin-top: 20px;
.monitor-flex-left {
padding: 0 0.2rem;
display: flex;
flex-direction: column;
width: 100%;
.control-top {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
width: 100%;
.monitor-img1 {
width: 1.2rem;
height: 1.2rem;
}
.monitor-img2 {
width: 1.2rem;
height: 0.8rem;
}
.monitor-img3 {
width: 1.2rem;
height: 0.8rem;
}
}
.control-bottom {
width: 100%;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
margin-top: 20px;
}
.ash {
color: #b8bfcb;
white-space: nowrap;
margin-right: 8px;
}
.white {
color: #ffffff;
}
.words-li {
display: flex;
flex-direction: row;
align-items: center;
font-family: SourceHanSansCN-Regular;
font-size: 16px;
line-height: 28px;
margin-bottom: 10px;
}
.monitor-words {
flex-wrap: wrap;
.words-li {
width: 100%;
}
}
.control-bottom {
flex-wrap: wrap;
.words-li {
width: 45%;
flex-wrap: nowrap;
}
.words-li2 {
width: 100%;
display: flex;
flex-direction: row;
align-items: center;
}
.words-li3 {
width: 36%;
}
.words-li4 {
width: 60%;
.ash {
width: 130px;
}
}
.words-li5 {
width: 45%;
.ash2 {
width: 100px;
}
}
.words-li6 {
width: 70%;
.ash2 {
width: 100px;
}
}
}
.sigClass {
width: 40%;
flex-wrap: wrap;
.words-li {
width: 100%;
}
}
}
}
}
.monitor-li::before {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
border-radius: 10px;
border: 1px solid transparent;
background: linear-gradient(
0deg,
#0088f0 0%,
rgba(19, 213, 255, 0.2) 100%
)
border-box;
mask: linear-gradient(#fff 0 0) padding-box,
/* 内部透明 */ linear-gradient(#fff 0 0); /* 填充整个区域 */
mask-composite: exclude; /* 关键属性 */
pointer-events: none; /* 防止遮挡点击事件 */
}
}
}
.tree-container {
height: 300px; /* 设置固定高度 */
overflow-y: auto; /* 启用垂直滚动条 */
}
// 滚动条
:-webkit-scrollbar {
width: 10px; /* 滚动条宽度 */
}
::-webkit-scrollbar-track {
background: transparent !important; /* 滚动条轨道背景色 */
}
.custom-tree-node {
flex: 1;
display: flex;
align-items: center;
justify-content: space-between;
font-size: 14px;
padding-right: 8px;
.tree-left {
.custom-tree-icon {
margin-right: 5px;
}
}
}
@media (min-width: 1350px) and (max-width: 1460px) {
.monitor-img3 {
}
}
@media (min-width: 1350px) and (max-width: 1850px) {
.monitor-li {
width: calc(49% - 10px) !important;
margin: 0 5px !important;
}
.monitor-img1 {
width: 100px !important;
height: 100px !important;
}
.monitor-img2 {
width: 100px !important;
height: 60px !important;
}
.monitor-img3 {
width: 1.2rem !important;
height: 0.9rem !important;
}
}
@media (max-width: 1350px) {
.monitor-li {
width: 100% !important;
margin: 0 !important;
margin-right: 10px !important;
.monitor-img1 {
width: 100px !important;
height: 100px !important;
}
.monitor-img2 {
width: 100px !important;
height: 80px !important;
}
.monitor-img3 {
width: 100px !important;
height: 80px !important;
}
.monitor-flex-left {
padding: 0 30px !important;
}
}
}
</style>
<style scoped>
/* 自定义高亮颜色 */
.left-tree
>>> .el-tree--highlight-current
.el-tree-node.is-current
> .el-tree-node__content {
background-color: #285b9e !important;
/* color: #f56c6c; */
color: #25f1f8;
}
.monitor-flex-left >>> .el-input {
width: 80px !important;
margin: 0 5px;
}
.monitor-flex-left >>> .el-input__inner {
background-color: #04193a;
border: 1px solid #1262db;
color: #3ef0fd;
font-weight: 700;
text-align: center;
padding: 0 0.1rem !important;
}
/* // 媒体查询,适配大于2000px分辨率的大屏样式 */
@media (min-width: 2000px) {
.monitor-flex-left >>> .el-input {
width: 0.8rem !important;
margin: 0 0.15rem 0 0.05rem !important;
}
}
</style>