Browse Source

1.完善中央空调界面

2.对接生活热水控制功能
dev
selia-zx 1 month ago
parent
commit
9d156389dc
  1. 4
      .env.development
  2. 4
      .env.production
  3. 10
      src/api/centerairC/strategy.js
  4. 8
      src/api/centerairC/sysMonitor.js
  5. 4
      src/api/hotWater/waterControl.js
  6. 1
      src/assets/icons/svg/delaySwitch.svg
  7. 1
      src/assets/icons/svg/deviceStrategy.svg
  8. 1
      src/assets/icons/svg/strategy.svg
  9. BIN
      src/assets/images/arrow-l.png
  10. BIN
      src/assets/images/border1.png
  11. BIN
      src/assets/images/border2.png
  12. BIN
      src/assets/images/border3.png
  13. BIN
      src/assets/images/butterflyValve.png
  14. BIN
      src/assets/images/butterflyValve1.png
  15. BIN
      src/assets/images/coolingPump.png
  16. BIN
      src/assets/images/coolingTower.png
  17. BIN
      src/assets/images/datatime.png
  18. BIN
      src/assets/images/freezingPump.png
  19. BIN
      src/assets/images/host.png
  20. BIN
      src/assets/images/left_line.png
  21. BIN
      src/assets/images/offOrON.png
  22. BIN
      src/assets/images/right_line.png
  23. BIN
      src/assets/images/start.png
  24. BIN
      src/assets/images/starthotpum.png
  25. BIN
      src/assets/images/startpum.png
  26. BIN
      src/assets/images/strategy-border.png
  27. BIN
      src/assets/images/waterBox.png
  28. BIN
      src/assets/images/wave.png
  29. BIN
      src/assets/images/yuan.png
  30. BIN
      src/assets/images/路径 1112.png
  31. 8
      src/assets/styles/element-ui.scss
  32. 2
      src/utils/global.js
  33. 433
      src/views/centerairC/delaySwitch/index.vue
  34. 348
      src/views/centerairC/deviceStrategy/index.vue
  35. 256
      src/views/centerairC/sysControl/index.vue
  36. 249
      src/views/centerairC/sysMonitor/index.vue
  37. 85
      src/views/components/dynamicArrow.vue
  38. 126
      src/views/components/waterTank.vue
  39. 631
      src/views/hotWater/waterControl/index.vue
  40. 377
      src/views/hotWater/waterMonitor/index.vue

4
.env.development

@ -7,7 +7,9 @@ ENV = 'development'
# 开发环境 # 开发环境
# VUE_APP_BASE_API = '/dev-api' # VUE_APP_BASE_API = '/dev-api'
# 后台 # 后台
VUE_APP_BASE_API = 'http://192.168.1.222:8080' # VUE_APP_BASE_API = 'http://192.168.1.222:8080'
# 云端
VUE_APP_BASE_API = 'http://106.55.173.225:8090'
# 路由懒加载 # 路由懒加载
VUE_CLI_BABEL_TRANSPILE_MODULES = true VUE_CLI_BABEL_TRANSPILE_MODULES = true

4
.env.production

@ -5,4 +5,6 @@ VUE_APP_TITLE = 铭汉能耗监测控制系统
ENV = 'production' ENV = 'production'
# 生产环境 # 生产环境
VUE_APP_BASE_API = '/prod-api' # VUE_APP_BASE_API = '/prod-api'
# 后台
VUE_APP_BASE_API = 'http://106.55.173.225:8090'

10
src/api/centerairC/strategy.js

@ -0,0 +1,10 @@
import request from "@/utils/request";
// 获取设备策略管理列表
export function policyListData(query) {
return request({
url: "/policy/list",
method: "get",
params: query,
});
}

8
src/api/centerairC/sysMonitor.js

@ -16,6 +16,14 @@ export function runTime() {
}); });
} }
//获取一键启停信息
export function oneKeyButton(query) {
return request({
url: "/device/cs/oneKeyButton",
method: "get",
params: query,
});
}
// 获取系统性能数据 // 获取系统性能数据
export function sysPerformance() { export function sysPerformance() {
return request({ return request({

4
src/api/hotWater/waterControl.js

@ -1,6 +1,6 @@
import request from "@/utils/request"; import request from "@/utils/request";
// 控制列表 // 热水设备列表
export function waterOperateList(query) { export function waterOperateList(query) {
return request({ return request({
url: "/device/hotWater/operateList", url: "/device/hotWater/operateList",
@ -8,7 +8,7 @@ export function waterOperateList(query) {
params: query, params: query,
}); });
} }
// 系统控制 // 热水设备控制
export function operationConrol(data) { export function operationConrol(data) {
return request({ return request({
url: "/device/operation", url: "/device/operation",

1
src/assets/icons/svg/delaySwitch.svg

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1743573886437" class="icon" viewBox="0 0 1204 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5669" xmlns:xlink="http://www.w3.org/1999/xlink" width="235.15625" height="200"><path d="M1009.02402 931.913517c-10.119394-1.542003-20.588147-1.481768-30.864151-1.481768-253.659469-0.060234-507.27075-0.060234-760.906124 0.048188-11.444552 0-25.97311-3.059912-33.610843 2.770786-14.215339 10.830161-33.309671 26.924815-33.815641 41.393139-0.50597 14.661074 17.154782 32.273638 30.599119 44.139831 6.926966 6.143918 21.961494 3.30085 33.357859 3.30085 128.540394 0.15661 257.056694 0.096375 385.621181 0.096376h382.151674c9.191783 0 18.672691 1.120361 27.466926-0.843283 24.093795-5.336775 39.031947-20.371303 37.995914-46.741962-0.951705-24.298592-14.335808-39.152416-37.995914-42.682157zM864.533534 0.013733L1133.010687 0.061921c49.27181 0.024094 60.812737 11.68549 60.897065 62.306553 0.108422 239.974193 0.108422 479.960433 0 719.946673-0.048188 48.464668-14.022588 63.125742-61.487363 63.173929-355.720782 0.168657-711.393377 0.168657-1067.114159 0-51.01861 0-65.197808-14.757449-65.233949-67.510812-0.120469-236.444452-0.096375-472.925045 0-709.369498C0.084328 11.48238 11.324083 0.013733 65.932669 0.013733h530.09962c179.016893 0 357.985599-0.048188 536.990445 0.036141z m272.199644 61.981287H66.932561v713.200411h1069.800617V61.99502z" fill="" p-id="5670"></path><path d="M609.042938 757.944274c-186.293219 0-337.313123-151.019904-337.313124-337.313123s151.019904-337.313123 337.313124-337.313123 337.313123 151.019904 337.313123 337.313123c-0.168657 186.232985-151.092185 337.156513-337.313123 337.313123z m0-615.993997a278.789296 278.789296 0 1 0 278.777249 278.680874c-0.216844-153.862972-124.926325-278.524264-278.777249-278.680874z" fill="" p-id="5671"></path><path d="M560.855349 239.927692c16.058514 0 24.093795 9.480908 24.093794 28.430678v196.147581c0 18.937722-8.03528 28.406584-24.093794 28.406584-16.070561 0-24.093795-9.468861-24.093795-28.406584V268.346323c0-18.937722 8.023234-28.418631 24.093795-28.418631z" fill="" p-id="5672"></path><path d="M548.808451 480.865637c0-16.058514 9.950737-24.093795 29.852212-24.093794h169.174578c19.913521 0 29.864258 8.03528 29.864258 24.093794 0 16.070561-9.950737 24.093795-29.864258 24.093795H578.660663c-19.901474 0-29.852211-8.023234-29.852212-24.093795z" fill="" p-id="5673"></path></svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

1
src/assets/icons/svg/deviceStrategy.svg

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.1 KiB

1
src/assets/icons/svg/strategy.svg

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1743497868451" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4336" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M922.112 825.344h-153.088c-13.312 0-22.016 8.704-22.016 22.016v148.992c0 17.408 26.112 30.72 39.424 17.408l153.088-148.992c13.312-17.408 0-39.424-17.408-39.424zM509.952 400.896c45.568 0 81.92-36.352 81.92-81.92s-36.352-81.92-81.92-81.92-81.92 36.352-81.92 81.92 36.352 81.92 81.92 81.92z" p-id="4337"></path><path d="M944.128 737.792v-650.24c0-61.44-26.112-82.432-91.648-82.432H169.984c-66.048 0-92.16 16.384-92.16 86.528v834.56c0 61.44 26.112 91.648 91.648 91.648h498.688V860.16c0-87.552 30.72-122.368 118.272-122.368h157.696zM270.848 272.384V271.36c3.584-8.192 8.192-13.824 15.36-17.408 1.024-1.024 1.024-1.024 2.56-1.024 20.992-5.632 38.4-18.432 47.616-34.816 10.752-18.432 12.8-39.424 7.168-61.952-3.584-9.216 0-19.968 8.192-25.6C373.76 112.128 399.36 96.768 430.08 83.968c7.168-2.56 16.384-3.584 25.6 5.632 16.384 16.384 34.816 25.6 54.784 25.6 22.016 0 41.984-8.192 54.784-24.576 8.192-8.192 17.408-10.752 25.6-7.168 30.208 10.752 57.344 26.624 79.36 47.616 8.192 7.168 10.752 17.408 7.168 25.6-7.168 19.968-3.584 41.984 7.168 59.392 11.776 19.968 26.624 31.744 47.616 36.352h1.024c10.752 2.56 16.384 10.752 17.408 19.968 3.584 15.36 4.608 31.744 5.632 47.616 0 15.36-1.024 30.208-4.608 47.616v1.024c-3.584 8.192-8.192 13.824-15.36 17.408-1.024 1.024-1.024 1.024-2.56 1.024-20.992 5.632-38.4 18.432-47.616 34.816-10.752 18.432-12.8 39.424-7.168 61.952 3.584 9.216 0 20.992-8.192 25.6-22.016 18.432-47.616 33.792-78.336 46.592-2.56 1.024-5.632 1.024-8.192 1.024-5.632 0-11.776-3.584-16.384-8.192-16.384-16.384-34.816-25.6-54.784-25.6-22.016 0-41.984 9.216-54.784 24.576-5.632 5.632-12.8 8.192-18.432 8.192h-3.584c-2.56 0-3.584-1.024-4.608-1.024-31.744-10.752-58.368-26.624-80.384-47.616-8.192-7.168-10.752-17.408-7.168-25.6 7.168-19.968 3.584-41.984-7.168-59.392-11.776-19.968-26.624-31.744-47.616-36.352h-1.024c-10.752-2.56-16.384-10.752-17.408-19.968-3.584-13.824-4.608-31.744-4.608-46.592 0-14.336 1.024-29.696 4.608-47.104z m250.88 605.184h-286.72c-15.36 0-28.672-8.192-36.352-20.48-4.608-5.632-7.68-12.8-7.68-20.992 0-6.144 1.536-11.264 4.608-16.384 6.144-15.872 21.504-27.136 39.424-27.136h286.72c23.552 0 42.496 18.944 42.496 42.496s-18.944 42.496-42.496 42.496z m-286.72-172.032c-20.992 0-38.912-15.36-41.984-35.84-1.536-3.584-2.048-7.168-2.048-11.264 0-13.312 7.68-24.576 18.944-29.696 7.168-5.12 15.36-8.192 24.576-8.192h551.936c9.216 0 17.92 3.072 24.576 8.192 11.264 5.12 18.944 16.384 18.944 29.696 0 4.096-0.512 7.68-2.048 11.264-3.072 20.48-20.48 35.84-41.984 35.84H235.008z" p-id="4338"></path></svg>

After

Width:  |  Height:  |  Size: 2.8 KiB

BIN
src/assets/images/arrow-l.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 513 B

BIN
src/assets/images/border1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

BIN
src/assets/images/border2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
src/assets/images/border3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

BIN
src/assets/images/butterflyValve.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 317 KiB

BIN
src/assets/images/butterflyValve1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 277 KiB

BIN
src/assets/images/coolingPump.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 205 KiB

BIN
src/assets/images/coolingTower.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 285 KiB

BIN
src/assets/images/datatime.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

BIN
src/assets/images/freezingPump.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 217 KiB

BIN
src/assets/images/host.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

BIN
src/assets/images/left_line.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
src/assets/images/offOrON.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

BIN
src/assets/images/right_line.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

BIN
src/assets/images/start.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
src/assets/images/starthotpum.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

BIN
src/assets/images/startpum.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

BIN
src/assets/images/strategy-border.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
src/assets/images/waterBox.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 KiB

BIN
src/assets/images/wave.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

BIN
src/assets/images/yuan.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 317 B

BIN
src/assets/images/路径 1112.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 783 B

8
src/assets/styles/element-ui.scss

@ -1351,10 +1351,14 @@
.el-upload-list__item-actions { .el-upload-list__item-actions {
border: solid 1px #0163a8 !important; border: solid 1px #0163a8 !important;
} }
.el-upload--picture-card{ .el-upload--picture-card {
background-color: transparent !important; background-color: transparent !important;
border: 1px dashed #0163a8 !important; border: 1px dashed #0163a8 !important;
} }
.el-switch__label{ .el-switch__label {
color: #d1cfcf; color: #d1cfcf;
} }
.el-switch__core {
border: 1px solid #ff4949;
background: #ff4949;
}

2
src/utils/global.js

@ -1,6 +1,6 @@
// 图片url // 图片url
export const imgUrl = "http://192.168.1.222:8080"; export const imgUrl = "http://106.55.173.225:8090";
export default { export default {

433
src/views/centerairC/delaySwitch/index.vue

@ -0,0 +1,433 @@
<template>
<div class="app-container">
<img
class="right-line"
src="../../../assets/images/right_line.png"
alt=""
/>
<div class="delay-title">自动开关机时间设置</div>
<div class="delaySwitch">
<div class="delay-li" v-for="(item, index) in delayList" :key="index">
<div class="buildingDiv">
<img
class="title-bg"
src="../../../assets/images/title-bg.png"
alt=""
/>
<div class="title-word">{{ item.name }}:</div>
</div>
<div class="delay-bottom">
<div class="start">
<div>初始化</div>
<img
class="start-img"
src="../../../assets/images/start.png"
alt=""
/>
</div>
<div class="delay-right">
<div
class="delay-context"
v-for="(children, subIndex) in item.values"
:key="subIndex + 1"
>
<div class="device-arrow">
<div class="delay-input">
<el-input
size="mini"
v-model="children.curValue"
@keyup.enter.native="handleEnter(children, $event)"
@input="handleInput(children)"
@focus="handleFocus(index, subIndex)"
@blur="handleBlur()"
></el-input
>S
</div>
<!-- isHovered 状态传递给 dynamic-arrow 组件 -->
<dynamic-arrow
:is-hovered="currentFocusIndex === `${index}-${subIndex}`"
></dynamic-arrow>
</div>
<div class="device-body">
<div>{{ children.pointName }}</div>
<img
v-if="children.pointName === '冷却泵'"
src="../../../assets/images/coolingPump.png"
class="butterflyValve"
alt=""
/>
<img
v-if="children.pointName === '冷冻泵'"
src="../../../assets/images/freezingPump.png"
class="butterflyValve"
alt=""
/>
<img
v-if="children.pointName.includes('主机')"
src="../../../assets/images/host.png"
class="butterflyValve"
alt=""
/>
<img
v-if="children.pointName.includes('塔')"
src="../../../assets/images/coolingTower.png"
class="butterflyValve"
alt=""
/>
<img
v-if="children.pointName.includes('阀')"
src="../../../assets/images/butterflyValve.png"
class="butterflyValve"
alt=""
/>
</div>
</div>
</div>
</div>
</div>
</div>
<img class="left-line" src="../../../assets/images/left_line.png" alt="" />
</div>
</template>
<script>
import { policyListData } from "@/api/centerairC/strategy";
import dynamicArrow from "../../components/dynamicArrow.vue";
import { operationConrol } from "@/api/hotWater/waterControl";
export default {
components: { dynamicArrow },
data() {
return {
delayList: [],
currentFocusIndex: -1, //
};
},
mounted() {
this.getPolicyList();
},
methods: {
//
getPolicyList() {
let data = {
systemType: "0",
funPolicyType: "2",
};
policyListData(data).then((res) => {
console.log("设备延时开关返回res", res);
if (res.code == 200) {
this.delayList = res.rows;
}
});
},
handleFocus(index, subIndex) {
console.log("index", index);
// el-input focusedIndex
this.currentFocusIndex = `${index}-${subIndex}`;
},
//
handleBlur() {
this.currentFocusIndex = "";
},
//
handleInput(item) {
console.log("校验");
//
item.curValue = String(item.curValue).replace(/[^\d.]/g, "");
//
const parts = item.curValue.split(".");
if (parts.length > 2) {
//
item.curValue = parts[0] + "." + parts[1];
}
//
if (parts.length === 2) {
item.curValue = parts[0] + "." + parts[1].slice(0, 2);
}
},
//
handleEnter(item, event) {
console.log("item", item);
console.log("event", event);
this.$confirm(
`确定要修改"${item.pointName}"的延迟时间为:${item.curValue} S吗?`,
"提示",
{
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}
)
.then(() => {
this.hadleOperationConrol(item.cpmId, item.curValue);
//
event.target.blur();
this.currentFocusIndex = "";
})
.catch(() => {
// //
// event.target.blur();
// this.currentFocusIndex = "";
});
},
hadleOperationConrol(id, param) {
let data = {
id: id,
param: param,
};
console.log("操作参数", data);
operationConrol([data])
.then((res) => {
if (res.code == 200) {
this.$modal.msgSuccess("操作成功");
// ;
this.getPolicyList();
} else {
// this.$modal.msgError("");
console.log("应该更新状态的");
// ;
this.getPolicyList();
}
})
.catch((error) => {
console.log("请求发生错误,更新设备状态", error);
// ;
this.getPolicyList();
});
},
},
};
</script>
<style lang="scss" scoped>
.app-container {
position: relative;
padding: 0.2rem;
.delay-title {
/* 基础样式 */
display: inline-block;
padding: 0.1rem;
font-family: "Arial Rounded MT Bold", sans-serif;
font-size: 0.18rem;
font-weight: 700;
color: #e6f3ff;
text-shadow: 0 2px 4px rgba(0, 60, 120, 0.4);
letter-spacing: 2px;
position: relative;
overflow: hidden;
cursor: default;
/* 双背景叠加 */
background: linear-gradient(
65deg,
rgba(1, 11, 24, 0.8) 0%,
rgba(36, 91, 146, 0.6) 50%,
rgba(18, 53, 95, 0.5) 100%
),
linear-gradient(-25deg, #0b274b 20%, #2b4d6b 80%);
background-blend-mode: overlay;
/* 动态边框 */
border: 2px solid;
border-image: linear-gradient(45deg, #026bbb, transparent) 1;
/* 主流光动画 */
&::before {
content: "";
position: absolute;
top: -50%;
left: -100%;
width: 250%;
height: 200%;
background: linear-gradient(
60deg,
transparent 20%,
rgba(255, 255, 255, 0.3) 50%,
transparent 80%
);
animation: shine 2.5s infinite linear;
}
/* 副流光动画 */
&::after {
content: "";
position: absolute;
top: -30%;
left: -50%;
width: 200%;
height: 160%;
background: linear-gradient(
-30deg,
transparent 30%,
rgba(255, 255, 255, 0.2) 50%,
transparent 70%
);
animation: shineReverse 3s infinite linear;
animation-delay: 0.8s;
}
}
/* 主流光动画 */
@keyframes shine {
0% {
transform: translateX(-20%) rotate(60deg);
}
100% {
transform: translateX(120%) rotate(60deg);
}
}
/* 反向副流光 */
@keyframes shineReverse {
0% {
transform: translateX(20%) rotate(-30deg);
}
100% {
transform: translateX(-120%) rotate(-30deg);
}
}
.right-line {
position: absolute;
top: 0;
left: 0;
width: 1.7rem;
height: 0.4rem;
}
.left-line {
position: absolute;
right: 0;
bottom: 0;
width: 0.5rem;
height: 2.2rem;
}
}
.delaySwitch {
display: flex;
flex-direction: column;
background-color: #142c4e;
border-radius: 10px;
padding: 0 20px;
font-size: 18px;
color: rgb(166, 217, 252);
.delay-li {
display: flex;
flex-direction: column;
align-items: flex-start;
padding: 40px 0;
border-bottom: 1px dashed #0349ac;
.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;
}
}
.delay-bottom {
display: flex;
flex-direction: row;
align-items: flex-start;
.start {
margin-right: 20px;
margin-top: 10px;
white-space: nowrap;
display: flex;
flex-direction: column;
align-items: center;
.start-img {
width: 70px;
height: 70px;
margin-top: 10px;
animation: rotateZ 5s linear infinite;
transition: 0.6s; /* 设置过渡时间,控制翻转速度 */
transform-style: preserve-3d; /* 保持子元素的 3D 效果 */
position: relative;
}
}
/* 定义旋转动画 */
@keyframes rotateZ {
0% {
transform: rotateY(0deg); /* 初始状态,不旋转 */
}
50% {
transform: rotateY(180deg); /* 旋转到 180 度,呈现翻面效果 */
}
100% {
transform: rotateY(360deg); /* 旋转回 360 度,回到初始状态 */
}
}
.delay-right {
display: flex;
flex-direction: row;
align-items: center;
flex-wrap: wrap;
}
.delay-context {
display: flex;
flex-direction: row;
align-items: center;
margin-bottom: 20px;
min-width: 150px;
.device-arrow {
display: flex;
flex-direction: column;
align-items: center;
}
.device-body {
display: flex;
flex-direction: column;
align-items: center;
margin: 0px 30px;
padding: 10px;
}
.butterflyValve {
width: 70px;
height: 70px;
margin-top: 10px;
padding: 5px;
border-radius: 5px;
background-color: #2c4970;
}
}
.delay-input {
display: flex;
flex-direction: row;
align-items: center;
flex-wrap: nowrap;
margin-bottom: 10px;
}
}
}
.delay-li:nth-last-child(1) {
border-bottom: none;
}
}
</style>
<style scoped>
.delay-input >>> .el-input {
width: 80px !important;
margin: 0 15px 0 5px;
}
.delay-input >>> .el-input__inner {
background-color: #04193a;
border: 1px solid #1262db;
color: #3ef0fd;
font-weight: 700;
text-align: center;
padding: 0 0.1rem !important;
}
</style>

348
src/views/centerairC/deviceStrategy/index.vue

@ -0,0 +1,348 @@
<template>
<div class="app-container policy-flex">
<div
class="policy"
:class="{ 'radio-style': hasRadioInput(item.values) }"
v-for="(item, index) in policyList"
:key="index"
>
<div class="policy-title">{{ item.name }}</div>
<div
class="policy-li"
v-for="(children, index) in item.values"
:key="index + 1"
>
<template v-if="children.inputType === 'text'">
<div>{{ children.pointName }}:</div>
<div class="right-data">
<el-input
v-if="children.inputType === 'text'"
v-model="children.curValue"
placeholder="请输入"
size="mini"
@keyup.enter.native="handleEnter(children)"
@input="handleInput(children)"
></el-input>
<div v-if="children.inputType === 'radio'">
<el-radio-group
v-model="children.curValue"
@change="handleRadioChange(children, item)"
>
<el-radio
:label="option.pointName"
v-for="option in item.values"
:key="option.id"
>{{ option.pointName }}</el-radio
>
</el-radio-group>
</div>
<div class="unit">{{ children.unit }}</div>
</div>
</template>
<template v-if="children.inputType === 'radio'">
<div class="right-data">
<el-radio-group
v-model="children.curValue"
@change="handleRadioChange(children, item)"
>
<el-radio border :label="children.pointName">{{
children.pointName
}}</el-radio>
</el-radio-group>
</div>
</template>
</div>
</div>
</div>
</template>
<script>
import { policyListData } from "@/api/centerairC/strategy";
import { operationConrol } from "@/api/hotWater/waterControl";
export default {
name: "deviceStrategy",
data() {
return {
policyList: [],
policyDetails: [],
value: "",
};
},
mounted() {
this.getPolicyList();
},
methods: {
// radio,policy
hasRadioInput(values) {
return values.some((child) => child.inputType === "radio");
},
//
getPolicyList() {
let data = {
systemType: "0",
funPolicyType: "1",
};
policyListData(data).then((res) => {
console.log("策略返回res", res);
if (res.code == 200) {
this.policyList = res.rows;
this.initRadioSelection();
}
});
},
// radio
initRadioSelection() {
this.policyList.forEach((item) => {
item.values.forEach((children) => {
if (children.inputType === "radio") {
if (Number(children.curValue) == 0) {
// console.log("0", children.curValue);
children.curValue = null; // null radio
} else {
console.log("当前项是1", children.curValue);
const selectedOption = item.values.find(
(option) => option.curValue === 1
);
// pointName
if (selectedOption) {
children.curValue = selectedOption.pointName;
}
}
}
});
});
},
//
handleInput(children) {
console.log("校验");
//
children.curValue = String(children.curValue).replace(/[^\d.]/g, "");
//
const parts = children.curValue.split(".");
if (parts.length > 2) {
//
children.curValue = parts[0] + "." + parts[1];
}
//
if (parts.length === 2) {
children.curValue = parts[0] + "." + parts[1].slice(0, 2);
}
},
handleEnter(children) {
console.log("请求后端", children);
this.$confirm(
`确定要修改"${children.pointName}"的数据为:${children.curValue} ${children.unit}吗?`,
"提示",
{
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}
)
.then(() => {
this.hadleOperationConrol(children.cpmId, children.curValue);
})
.catch(() => {
//
// this.getOperationList();
});
},
handleRadioChange(children, item) {
this.$confirm(
`确定要修改"${item.name}"的数据为:${children.curValue} ${children.unit}吗?`,
"提示",
{
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}
)
.then(() => {
console.log("children.curValue", children.curValue);
if (children.curValue) {
this.hadleOperationConrol(children.cpmId, "1");
}
})
.catch(() => {
//
children.curValue = "0";
});
},
hadleOperationConrol(id, param) {
let data = {
id: id,
param: param,
};
console.log("操作参数", data);
operationConrol([data])
.then((res) => {
if (res.code == 200) {
this.$modal.msgSuccess("操作成功");
// ;
this.getPolicyList();
} else {
// this.$modal.msgError("");
console.log("应该更新状态的");
// ;
this.getPolicyList();
}
})
.catch((error) => {
console.log("请求发生错误,更新设备状态", error);
// ;
this.getPolicyList();
});
},
},
};
</script>
<style lang="scss" scoped>
.policy-flex {
margin-top: 15px;
width: 100%;
display: flex;
flex-direction: row;
flex-wrap: wrap;
.policy {
display: flex;
flex-direction: column;
position: relative;
width: calc(33.33% - 40px);
margin: 0 20px;
min-height: 300px;
background-image: url(../../../assets/images/strategy-border.png);
background-size: 100% 100%;
border-bottom: 1px solid #1587cc;
border-left: 1px solid #1587cc;
margin-bottom: 25px;
padding: 70px 60px 20px 40px;
.policy-title {
font-size: 0.18rem;
font-weight: bold;
position: absolute;
top: 15px;
left: 25px;
margin-bottom: 25px;
}
.policy-li {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
z-index: 0;
font-size: 0.16rem;
color: #94b8ce;
margin-bottom: 10px;
.right-data {
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
flex-wrap: wrap;
// max-width: 2.5rem;
.unit {
width: 25px;
white-space: nowrap;
}
}
.el-input {
width: 80px !important;
margin: 0 15px 0 5px;
}
}
}
.radio-style {
display: flex;
flex-direction: row !important;
align-items: flex-start !important;
flex-wrap: wrap;
align-content: flex-start; /* 调整多行元素的对齐方式 */
.policy-li {
margin: 10px;
width: calc(50% - 20px) !important;
}
}
}
@media (min-width: 1560px) and (max-width: 1670px) {
.policy {
padding: 70px 0.3rem 20px 40px !important;
}
}
@media (min-width: 1400px) and (max-width: 1560px) {
.policy {
padding: 70px 0.3rem 20px 40px !important;
width: calc(33.33% - 20px) !important;
margin: 0 10px 25px 10px !important;
}
.policy-li {
font-size: 14px !important;
}
}
@media (min-width: 1340px) and (max-width: 1400px) {
.policy {
padding: 70px 0.3rem 20px 40px !important;
width: calc(33.33% - 20px) !important;
margin: 0 10px 25px 10px !important;
}
.policy-li {
font-size: 14px !important;
}
.radio-style {
padding: 70px 0.3rem 20px 20px !important;
.policy-li {
width: calc(50% - 20px) !important;
}
}
}
@media (min-width: 1025px) and (max-width: 1340px) {
.policy {
width: calc(49% - 20px) !important;
margin: 0 10px 25px 10px !important;
padding: 70px 30px 15px 40px !important;
}
.policy-title {
font-size: 16px !important;
}
.policy-li {
font-size: 14px !important;
}
}
@media (max-width: 1240px) {
.policy {
width: calc(80% - 20px) !important;
margin: 0 10px 25px 10px !important;
padding: 70px 60px 15px 40px !important;
}
.policy-title {
font-size: 16px !important;
left: 40px !important;
}
.policy-li {
font-size: 14px !important;
}
}
</style>
<style scoped>
.policy-li >>> .el-input__inner {
background-color: #04193a;
border: 1px solid #1262db;
color: #3ef0fd;
font-weight: 700;
text-align: center;
padding: 0 0.1rem !important;
}
.policy-li >>> .el-radio {
margin-bottom: 5px;
}
.policy-li >>> .el-radio__label {
color: #3ef0fd;
}
.policy-li >>> .el-radio__inner {
border: 1px solid #042063;
/* background-color: transparent !important; */
}
.policy-li >>> .el-radio.is-bordered {
border: 1px solid #2c6afa;
}
</style>

256
src/views/centerairC/sysControl/index.vue

@ -5,26 +5,22 @@
<div class="status-card"> <div class="status-card">
<div class="status-label">运行设备</div> <div class="status-label">运行设备</div>
<div class="status-value-running"> <div class="status-value-running">
{{ statistics.running }}/{{ deviceList.length }} {{ statistics.running }}/{{ total }}
</div> </div>
</div> </div>
<div class="status-card"> <div class="status-card">
<div class="status-label">手动模式</div> <div class="status-label">手动模式</div>
<div class="status-value-auto"> <div class="status-value-auto">{{ statistics.manual }}/{{ total }}</div>
{{ statistics.manual }}/{{ deviceList.length }}
</div>
</div> </div>
<div class="status-card"> <div class="status-card">
<div class="status-label">自动模式</div> <div class="status-label">自动模式</div>
<div class="status-value-maintenance"> <div class="status-value-maintenance">
{{ statistics.auto }}/{{ deviceList.length }} {{ statistics.auto }}/{{ total }}
</div> </div>
</div> </div>
<div class="status-card"> <div class="status-card">
<div class="status-label">故障设备</div> <div class="status-label">故障设备</div>
<div class="status-value-error"> <div class="status-value-error">{{ statistics.warn }}/{{ total }}</div>
{{ statistics.warn }}/{{ deviceList.length }}
</div>
</div> </div>
</div> </div>
<!-- 非蝶阀控制列表 --> <!-- 非蝶阀控制列表 -->
@ -34,6 +30,7 @@
<div class="device-name">运行状态</div> <div class="device-name">运行状态</div>
<div class="device-name">手动控制</div> <div class="device-name">手动控制</div>
<div class="device-name">手自动切换</div> <div class="device-name">手自动切换</div>
<div class="device-name">本地远程状态</div>
<div class="device-name">故障报警</div> <div class="device-name">故障报警</div>
<div class="device-name">频率调节</div> <div class="device-name">频率调节</div>
<div class="device-name">频率反馈</div> <div class="device-name">频率反馈</div>
@ -60,14 +57,24 @@
> >
</el-switch> </el-switch>
</div> </div>
<div class="device-name">
<el-switch
style="display: block"
v-model="item.automaticText"
active-color="#13ce66"
inactive-color="#ff4949"
active-text="自动"
inactive-text="手动"
@change="handleAutomaticText(item)"
>
</el-switch>
</div>
<div class="device-name"> <div class="device-name">
<span <span
:class=" :class="
item.automaticText === '手动' item.localRemote === '远程' ? 'strong-electric' : 'auto-electric'
? 'strong-electric'
: 'auto-electric'
" "
>{{ item.automaticText }}</span >{{ item.localRemote }}</span
> >
</div> </div>
<div class="device-name"> <div class="device-name">
@ -95,6 +102,8 @@
<div class="device-container second"> <div class="device-container second">
<div class="device-li"> <div class="device-li">
<div class="device-name">设备名称</div> <div class="device-name">设备名称</div>
<div class="device-name">手自动切换</div>
<div class="device-name">本地远程状态</div>
<div class="device-name">手动阀关控制</div> <div class="device-name">手动阀关控制</div>
<div class="device-name">阀关反馈</div> <div class="device-name">阀关反馈</div>
<div class="device-name">手动阀开控制</div> <div class="device-name">手动阀开控制</div>
@ -102,6 +111,26 @@
</div> </div>
<div class="device-li" v-for="(item, index) in valveList" :key="index"> <div class="device-li" v-for="(item, index) in valveList" :key="index">
<div class="device-name">{{ item.name }}</div> <div class="device-name">{{ item.name }}</div>
<div class="device-name">
<el-switch
style="display: block"
v-model="item.automaticText"
active-color="#13ce66"
inactive-color="#ff4949"
active-text="自动"
inactive-text="手动"
@change="handleValveControlText(item)"
>
</el-switch>
</div>
<div class="device-name">
<span
:class="
item.localRemote === '远程' ? 'strong-electric' : 'auto-electric'
"
>{{ item.localRemote }}</span
>
</div>
<div class="device-name"> <div class="device-name">
<el-switch <el-switch
style="display: block" style="display: block"
@ -171,15 +200,28 @@ export default {
closeStatus: "", closeStatus: "",
}, },
], ],
total: null,
}; };
}, },
computed: { computed: {
statistics() { statistics() {
const deviceManual = this.deviceList.filter(
(d) => d.automaticText === false
).length;
const deviceAuto = this.deviceList.filter(
(d) => d.automaticText === true
).length;
const valveManual = this.valveList.filter(
(v) => v.automaticText === false
).length;
const valveAuto = this.valveList.filter(
(v) => v.automaticText === true
).length;
return { return {
running: this.deviceList.filter((d) => d.runStatus === "运行").length, running: this.deviceList.filter((d) => d.runStatus === "运行").length,
manual: this.deviceList.filter((d) => d.automaticText === "手动") manual: deviceManual + valveManual,
.length, auto: deviceAuto + valveAuto,
auto: this.deviceList.filter((d) => d.automaticText === "自动").length,
warn: this.deviceList.filter((d) => d.warnText === "故障").length, warn: this.deviceList.filter((d) => d.warnText === "故障").length,
}; };
}, },
@ -188,6 +230,7 @@ export default {
this.getOperationList(); this.getOperationList();
}, },
methods: { methods: {
//
getOperationList() { getOperationList() {
operationList({ systemType: 0 }).then((res) => { operationList({ systemType: 0 }).then((res) => {
console.log("列表返回res", res); console.log("列表返回res", res);
@ -206,48 +249,94 @@ export default {
name: element.name, name: element.name,
}; };
//
const limitedChildren = element.children; const limitedChildren = element.children;
limitedChildren.forEach((child) => { limitedChildren.forEach((child) => {
if (child.name) { if (child.name) {
if (child.name.includes("运行状态")) { //
if (child.paramType === "1" && !child.name.includes("阀")) {
deviceItem.runStatus = deviceItem.runStatus =
child.value === "0.000" ? "不运行" : "运行"; Number(child.value) == 0 ? "不运行" : "运行";
} else if (child.name.includes("启停控制")) { //
} else if (
child.paramType === "2" &&
!child.name.includes("阀")
) {
deviceItem.controlText = deviceItem.controlText =
child.value === "0.000" ? false : true; Number(child.value) == 0 ? false : true;
deviceItem.controlId = child.id; deviceItem.controlId = child.id;
} else if (child.name.includes("手自动状态")) { // 0
} else if (
child.paramType === "6" &&
!child.name.includes("阀")
) {
deviceItem.automaticText = deviceItem.automaticText =
child.value === "0.000" ? "自动" : "手动"; Number(child.value) == 0 ? false : true;
} else if (child.name.includes("故障报警")) { deviceItem.automaticId = child.id;
//
} else if (
child.paramType === "5" &&
!child.name.includes("阀")
) {
deviceItem.warnText = deviceItem.warnText =
child.value === "0.000" ? "未故障" : "故障"; Number(child.value) == 0 ? "未故障" : "故障";
} else if (child.name.includes("频率调节")) { //
} else if (
child.paramType === "22" &&
!child.name.includes("阀")
) {
deviceItem.localRemote =
Number(child.value) == 0 ? "本地" : "远程";
} else if (
child.paramType === "3" &&
!child.name.includes("阀")
) {
deviceItem.frequencySet = deviceItem.frequencySet =
child.value === "0.000" ? "0" : child.value; Number(child.value) == 0 ? "0" : child.value;
deviceItem.frequencyId = child.id; deviceItem.frequencyId = child.id;
} else if (child.name.includes("频率反馈")) { //
} else if (child.paramType === "4") {
deviceItem.frequency = child.value; deviceItem.frequency = child.value;
//
} else if (child.name.includes("阀开反馈")) { } else if (child.name.includes("阀开反馈")) {
valveItem.openStauts = valveItem.openStauts =
child.value === "0.000" ? "关闭" : "开启"; Number(child.value) == 0 ? "关闭" : "开启";
//
} else if ( } else if (
child.name.includes("阀开") && child.name.includes("阀开") &&
!child.name.includes("反馈") !child.name.includes("反馈")
) { ) {
valveItem.openText = child.value === "0.000" ? false : true; valveItem.openText =
Number(child.value) == 0 ? false : true;
valveItem.openId = child.id; valveItem.openId = child.id;
//
} else if ( } else if (
child.name.includes("阀关") && child.name.includes("阀关") &&
!child.name.includes("反馈") !child.name.includes("反馈")
) { ) {
valveItem.colseText = valveItem.colseText =
child.value === "0.000" ? false : true; (child.value === Number(child.value)) == 0 ? false : true;
valveItem.closeId = child.id; valveItem.closeId = child.id;
//
} else if (child.name.includes("阀关反馈")) { } else if (child.name.includes("阀关反馈")) {
valveItem.closeStatus = valveItem.closeStatus =
child.value === "0.000" ? "关闭" : "开启"; (child.value === Number(child.value)) == 0
? "关闭"
: "开启";
// -
} else if (
child.paramType === "22" &&
child.name.includes("阀")
) {
valveItem.localRemote =
Number(child.value) == 0 ? "本地" : "远程";
// -
} else if (
child.paramType === "6" &&
child.name.includes("阀")
) {
valveItem.automaticText =
Number(child.value) == 0 ? false : true;
valveItem.automaticId = child.id;
} }
} }
}); });
@ -264,6 +353,7 @@ export default {
}); });
console.log("处理过的this.deviceList", this.deviceList); console.log("处理过的this.deviceList", this.deviceList);
console.log("处理过的this.valveList", this.valveList); console.log("处理过的this.valveList", this.valveList);
this.total = this.deviceList.length + this.valveList.length;
} }
}); });
}, },
@ -276,7 +366,7 @@ export default {
handleEnter(item) { handleEnter(item) {
console.log("请求后端"); console.log("请求后端");
this.$confirm( this.$confirm(
`确定要修改"${item.name}"的频率为:${item.frequencySet} Hz吗?"`, `确定要修改"${item.name}"的频率为:${item.frequencySet} Hz吗?`,
"提示", "提示",
{ {
confirmButtonText: "确定", confirmButtonText: "确定",
@ -285,14 +375,14 @@ export default {
} }
) )
.then(() => { .then(() => {
this.operationConrol(item.frequencyId, item.frequencySet); this.hadleOperationConrol(item.frequencyId, item.frequencySet);
}) })
.catch(() => { .catch(() => {
// //
this.getOperationList(); this.getOperationList();
}); });
}, },
// //
handleControlText(item) { handleControlText(item) {
this.$confirm( this.$confirm(
`确定要切换设备"${item.name}"的状态为:${ `确定要切换设备"${item.name}"的状态为:${
@ -306,7 +396,7 @@ export default {
} }
) )
.then(() => { .then(() => {
// //
console.log("请求后台", item.controlText); console.log("请求后台", item.controlText);
let param = null; let param = null;
if (item.controlText) { if (item.controlText) {
@ -314,7 +404,7 @@ export default {
} else { } else {
param = 0; param = 0;
} }
this.operationConrol(item.controlId, param); this.hadleOperationConrol(item.controlId, param);
}) })
.catch(() => { .catch(() => {
// //
@ -322,6 +412,36 @@ export default {
console.log("不请求后台"); console.log("不请求后台");
}); });
}, },
//
handleAutomaticText(item) {
this.$confirm(
`确定要切换设备"${item.name}"的状态为:${
item.automaticText ? "自动" : "手动 吗?"
}`,
"提示",
{
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}
)
.then(() => {
//
console.log("请求后台", item.automaticText);
let param = null;
if (item.automaticText) {
param = 1;
} else {
param = 0;
}
this.hadleOperationConrol(item.automaticId, param);
})
.catch(() => {
//
item.automaticText = !item.automaticText;
console.log("不请求后台");
});
},
// //
handleValveClose(item) { handleValveClose(item) {
this.$confirm( this.$confirm(
@ -342,7 +462,7 @@ export default {
} else { } else {
param = 0; param = 0;
} }
this.operationConrol(item.closeId, param); this.hadleOperationConrol(item.closeId, param);
}) })
.catch(() => { .catch(() => {
// //
@ -370,7 +490,7 @@ export default {
} else { } else {
param = 0; param = 0;
} }
this.operationConrol(item.openId, param); this.hadleOperationConrol(item.openId, param);
}) })
.catch(() => { .catch(() => {
// //
@ -378,23 +498,60 @@ export default {
console.log("不请求后台"); console.log("不请求后台");
}); });
}, },
operationConrol(id, param) { // -
handleValveControlText(item) {
this.$confirm(
`确定要切换设备"${item.name}"的状态为:${
item.automaticText ? "自动" : "手动 吗?"
}`,
"提示",
{
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}
)
.then(() => {
//
console.log("请求后台", item.automaticText);
let param = null;
if (item.automaticText) {
param = 1;
} else {
param = 0;
}
this.hadleOperationConrol(item.automaticId, param);
})
.catch(() => {
//
item.automaticText = !item.automaticText;
console.log("不请求后台");
});
},
hadleOperationConrol(id, param) {
let data = { let data = {
id: id, id: id,
param: param, param: param,
}; };
console.log("操作参数", data); console.log("操作参数", data);
operationConrol([data]).then((res) => { operationConrol([data])
if (res.code == 200) { .then((res) => {
this.$modal.msgSuccess("操作成功"); if (res.code == 200) {
// ; this.$modal.msgSuccess("操作成功");
this.getOperationList(); // ;
} else { this.getOperationList();
this.$modal.msgError("操作失败"); } else {
// this.$modal.msgError("");
console.log("应该更新状态的");
// ;
this.getOperationList();
}
})
.catch((error) => {
console.log("请求发生错误,更新设备状态", error);
// ; // ;
this.getOperationList(); this.getOperationList();
} });
});
}, },
}, },
}; };
@ -421,6 +578,9 @@ export default {
.device-name { .device-name {
flex: 1; flex: 1;
white-space: nowrap; white-space: nowrap;
.el-switch{
width: 120px !important;
}
.run { .run {
display: flex; display: flex;
flex-direction: row; flex-direction: row;

249
src/views/centerairC/sysMonitor/index.vue

@ -10,17 +10,17 @@
</div> </div>
<div class="weather-li"> <div class="weather-li">
<span>室外湿度</span> <span>室外湿度</span>
<span class="deepColor">{{ weatherObj.humidityRatio }}</span> <span class="deepColor">{{ weatherObj.humidity }}</span>
<span>%</span> <span>%</span>
</div> </div>
<div class="weather-li"> <div class="weather-li">
<span>室外含湿</span> <span>室外含湿</span>
<span class="deepColor">{{ weatherObj.humidity }}</span> <span class="deepColor">{{ weatherObj.humidityRatio }}</span>
<span>g/kg</span> <span>g/kg</span>
</div> </div>
<div class="weather-li"> <div class="weather-li">
<span>室外焓值</span> <span>室外焓值</span>
<span class="deepColor">{{ weatherObj.wetBulbTemp }}</span> <span class="deepColor">{{ weatherObj.enthalpy }}</span>
<span>kj/kg</span> <span>kj/kg</span>
</div> </div>
<div class="weather-li"> <div class="weather-li">
@ -30,48 +30,50 @@
</div> </div>
<div class="weather-li"> <div class="weather-li">
<span>室外湿球</span> <span>室外湿球</span>
<span class="deepColor">{{ weatherObj.enthalpy }}</span> <span class="deepColor">{{ weatherObj.wetBulbTemp }}</span>
<span></span> <span></span>
</div> </div>
</div> </div>
<!-- 系统性能数据 --> <!-- 系统性能数据 -->
<div class="performance"> <div class="performance">
<div class="title">系统性能</div> <div class="perdformance-bg">
<div class="weather-li"> <div class="weather-li">
<span>实时EER</span> <span>实时EER</span>
<span class="deepColor">{{ performanceObj.realEER }}</span> <span class="deepColor">{{ performanceObj.realEER }}</span>
<span>kw/kw</span> <span>kw/kw</span>
</div> </div>
<div class="weather-li"> <div class="weather-li">
<span>实时功率</span> <span>实时功率</span>
<span class="deepColor">{{ performanceObj.realPower }}</span> <span class="deepColor">{{ performanceObj.realPower }}</span>
<span>kw</span> <span>kw</span>
</div> </div>
<div class="weather-li"> <div class="weather-li">
<span>实时冷量</span> <span>实时冷量</span>
<span class="deepColor">{{ performanceObj.realCold }}</span> <span class="deepColor">{{ performanceObj.realCold }}</span>
<span>kw</span> <span>kw</span>
</div> </div>
<div class="weather-li"> <div class="weather-li">
<span>全年EER</span> <span>全年EER</span>
<span class="deepColor">{{ performanceObj.yearEER }}</span> <span class="deepColor">{{ performanceObj.yearEER }}</span>
<span>kw</span> <span>kw</span>
</div> </div>
<div class="weather-li"> <div class="weather-li">
<span>全年用电</span> <span>全年用电</span>
<span class="deepColor">{{ performanceObj.yearPower }}</span> <span class="deepColor">{{ performanceObj.yearPower }}</span>
<span>kw/h</span> <span>kw/h</span>
</div> </div>
<div class="weather-li"> <div class="weather-li">
<span>全年产冷</span> <span>全年产冷</span>
<span class="deepColor">{{ performanceObj.yearCold }}</span> <span class="deepColor">{{ performanceObj.yearCold }}</span>
<span>kw</span> <span>kw</span>
</div>
</div> </div>
<div class="title">系统性能</div>
</div> </div>
<!-- 一键启停 --> <!-- 一键启停 -->
<div class="offClass"> <div class="offClass" @click="handleOneKeyButton">
<img src="../../../assets/images/offOrON.png" class="off-img" alt="" /> <div v-if="isShowOn" class="off-bg">ON</div>
<div>OFF</div> <div v-else class="off-bg">OFF</div>
</div> </div>
<!-- 整体图 --> <!-- 整体图 -->
<img <img
@ -341,7 +343,9 @@
import { import {
weatherData, weatherData,
sysPerformance, sysPerformance,
oneKeyButton,
monitorList, monitorList,
operationConrol,
} from "@/api/centerairC/sysMonitor"; } from "@/api/centerairC/sysMonitor";
import LineChildren from "./lineChildren.vue"; import LineChildren from "./lineChildren.vue";
export default { export default {
@ -359,11 +363,14 @@ export default {
coolingValue: [], // coolingValue: [], //
coolingTowerInlet: [], // coolingTowerInlet: [], //
coolingTowerOutlet: [], // coolingTowerOutlet: [], //
isShowOn: false, //,falseOff,trueOn
oneKeyButtonId: "",
}; };
}, },
created() { created() {
this.getWeatherData(); this.getWeatherData();
this.getPerformance(); this.getPerformance();
this.getOneKeyButton();
this.getMonitorList(); this.getMonitorList();
}, },
methods: { methods: {
@ -383,6 +390,63 @@ export default {
} }
}); });
}, },
//
getOneKeyButton() {
let data = {
systemType: 0,
paramType: "23",
};
oneKeyButton(data).then((res) => {
if (res.code == 200) {
console.log("一键启停返回信息", res);
this.oneKeyButtonId = res.data.id;
if (Number(res.data.curValue) == 0) {
this.isShowOn = false;
} else {
this.isShowOn = true;
}
}
});
},
//
handleOneKeyButton() {
let param = "";
let paramText = "";
if (this.isShowOn) {
// this.isShowOntrueON,OFF
param = 0;
paramText = "一键关闭";
} else {
param = 1;
paramText = "一键开启";
}
this.$confirm(`确定要${paramText}吗?`, "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
let data = {
id: this.oneKeyButtonId,
param: param,
};
operationConrol([data])
.then((res) => {
if (res.code == 200) {
this.$modal.msgSuccess("操作成功");
// ;
this.getOneKeyButton();
} else {
this.getOneKeyButton();
}
})
.catch((error) => {
console.log("请求发生错误,更新设备状态", error);
this.ggetOneKeyButton();
});
})
.catch(() => {});
},
// //
getMonitorList() { getMonitorList() {
monitorList({ systemType: 0 }).then((res) => { monitorList({ systemType: 0 }).then((res) => {
@ -744,7 +808,7 @@ export default {
Number(item.collectValue) === 0 Number(item.collectValue) === 0
) { ) {
valveCloseFeedbackFound = true; valveCloseFeedbackFound = true;
console.log("冷冻蝶阀阀关反馈应该是true才对呀"); // console.log("true");
} }
} }
} }
@ -1261,70 +1325,69 @@ export default {
} }
} }
.weather { .weather {
min-width: 2.5rem;
z-index: 10;
position: absolute; position: absolute;
top: 0.2rem; top: 0rem;
left: -1rem; left: -0.8rem;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: flex-start; align-items: flex-start;
justify-content: flex-start; justify-content: flex-start;
font-size: 0.16rem; font-size: 0.16rem;
color: rgb(18, 155, 209); color: rgb(18, 155, 209);
background-image: url(../../../assets/images/border1.png);
background-size: 100% 100%;
background-repeat: no-repeat;
padding: 0.15rem 0 0.25rem 0rem;
} }
.weather-li { .weather-li {
width: 2rem; width: 100%;
padding: 0.05rem 0 0.05rem 0.1rem; padding: 0.05rem 0 0.05rem 0.3rem;
/* 初始设置上下边框宽度为 1px,颜色和样式可以先设为透明,后续由 border-image 覆盖 */ /* 初始设置上下边框宽度为 1px,颜色和样式可以先设为透明,后续由 border-image 覆盖 */
border-top: 1px solid transparent; border-top: 1px solid transparent;
border-bottom: 1px solid transparent; border-bottom: 1px dashed #1a3f8f;
/* 使用线性渐变创建 border-image,这里颜色 A 以 #ff0000(红色)为例 */
border-image: linear-gradient(to right, #576ef0, transparent 50%, #576ef0);
/* 设置 border-image 的切片,这里设置为 1 0,即上下边框应用渐变,左右不应用 */
border-image-slice: 1 0;
/* 设置 border-image 的宽度,这里设置为 1,与 border-width 对应 */
border-image-width: 1;
position: relative; position: relative;
.deepColor { .deepColor {
display: inline-block; display: inline-block;
margin: 0 0.1rem 0 0.05rem; margin: 0 0.1rem 0 0.05rem;
color: rgb(95, 161, 247); color: #20ebfa;
font-weight: bold; font-weight: bold;
font-family: DIN;
font-size: 0.20rem;
} }
} }
.weather-li::before,
.weather-li::after {
content: "";
position: absolute;
top: 0;
bottom: 0;
width: 1px;
background-color: rgb(95, 161, 247);
}
.weather-li::before {
left: 0;
background-color: rgb(95, 161, 247);
}
.weather-li::after {
right: 0;
background-color: rgb(95, 161, 247);
}
.performance { .performance {
position: absolute; position: absolute;
top: 5.2rem !important; top: 4.7rem !important;
right: 0 !important; right: -1rem !important;
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: flex-start;
font-size: 0.16rem;
color: rgb(18, 155, 209);
}
.perdformance-bg {
min-width: 2.5rem;
z-index: 10;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: flex-start; align-items: flex-start;
justify-content: flex-start; justify-content: flex-start;
font-size: 0.16rem; font-size: 0.16rem;
color: rgb(18, 155, 209); color: rgb(18, 155, 209);
background-image: url(../../../assets/images/border1.png);
background-size: 100% 100%;
background-repeat: no-repeat;
padding: 0.15rem 0 0.25rem 0rem;
} }
.title { .title {
width: 100%; width: 100%;
background-image: url(../../../assets/images/text_img_title.png); background-image: url(../../../assets/images/text_img_title.png);
background-repeat: no-repeat; background-repeat: no-repeat;
background-repeat: no-repeat;
background-size: 3rem 0.45rem; background-size: 3rem 0.45rem;
background-position: bottom left; background-position: bottom left;
font-family: SourceHanSansCN-Medium; font-family: SourceHanSansCN-Medium;
@ -1333,11 +1396,15 @@ export default {
line-height: 0.6rem; line-height: 0.6rem;
color: rgba(209, 214, 223, 1); color: rgba(209, 214, 223, 1);
padding-left: 0.6rem; padding-left: 0.6rem;
margin-top: -0.15rem;
} }
.offClass { .offClass {
position: absolute; position: absolute;
width: 1.4rem; width: 1.4rem;
height: 1.2rem; height: 1.4rem;
background-image: url(../../../assets/images/border2.png);
background-repeat: no-repeat;
background-size: 100% 100%;
top: 0; top: 0;
right: 0rem; right: 0rem;
z-index: 10; z-index: 10;
@ -1345,16 +1412,42 @@ export default {
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
font-size: 0.18rem;
color: #2fbda5;
cursor: pointer; cursor: pointer;
.off-img { .off-bg {
width: 1.4rem;
height: 1.2rem;
position: absolute; position: absolute;
top: 0; left: 0.38rem;
left: 0; top: 0.3rem;
width: 0.8rem;
height: 0.8rem;
background-image: url(../../../assets/images/border3.png);
background-repeat: no-repeat;
background-size: 100% 100%;
text-align: center;
line-height: 0.8rem;
font-family: DIN;
font-size: 0.24rem;
color: #20ebfa;
font-weight: bold;
animation: rotateZ 5s linear infinite;
transition: 0.6s; /* 设置过渡时间,控制翻转速度 */
transform-style: preserve-3d; /* 保持子元素的 3D 效果 */
}
/* 定义旋转动画 */
@keyframes rotateZ {
0% {
transform: rotateY(0deg); /* 初始状态,不旋转 */
}
50% {
transform: rotateY(180deg); /* 旋转到 180 度,呈现翻面效果 */
}
100% {
transform: rotateY(360deg); /* 旋转回 360 度,回到初始状态 */
}
} }
} }
/* 鼠标悬停时移除动画 */
.offClass:hover .off-bg {
animation: none;
}
} }
</style> </style>

85
src/views/components/dynamicArrow.vue

@ -0,0 +1,85 @@
<template>
<div class="arrow">
<!-- 循环渲染 5 个圆点图片 -->
<img
v-for="i in 5"
:key="i"
class="yuan"
src="../../assets/images/yuan.png"
alt=""
:class="{ 'animate-yuan': isHovered }"
/>
<!-- 渲染右箭头图片 -->
<img
class="arrow-l"
src="../../assets/images/arrow-l.png"
alt=""
:class="{ 'animate-arrow': isHovered }"
/>
</div>
</template>
<script>
export default {
props: {
isHovered: {
type: Boolean,
default: false,
},
},
};
</script>
<style lang="scss" scoped>
.arrow {
display: flex;
flex-direction: row;
align-items: center;
.yuan {
width: 6px;
height: 6px;
margin-right: 10px;
}
.arrow-l {
width: 15px;
height: 20px;
}
}
/* 圆点动画 */
@keyframes yuanAnimation {
0% {
transform: scale(1) translateX(0);
opacity: 1;
}
50% {
transform: scale(1.2) translateX(5px); /* 增加向右移动 5px,可按需调整 */
opacity: 0.6;
}
100% {
transform: scale(1) translateX(0);
opacity: 1;
}
}
/* 箭头动画 */
@keyframes arrowAnimation {
0% {
transform: translateX(0);
}
50% {
transform: translateX(10px); /* 根据实际情况调整移动距离 */
}
100% {
transform: translateX(0);
}
}
/* 应用圆点动画的类 */
.animate-yuan {
animation: yuanAnimation 1s infinite;
}
/* 应用箭头动画的类 */
.animate-arrow {
animation: arrowAnimation 1s infinite;
}
</style>

126
src/views/components/waterTank.vue

@ -0,0 +1,126 @@
<template>
<div class="monitor-container">
<!-- 水箱图片 -->
<img class="monitor-img3" src="../../assets/images/waterBox.png" />
<!-- 表示水的 div -->
<div class="waves" :style="{ height: waterHeight + '%' }">
<div class="wave wave1"></div>
<div class="wave wave2"></div>
<div class="wave wave3"></div>
<div class="wave wave4"></div>
</div>
</div>
</template>
<script>
export default {
//
props: {
waterLevel: {
type: Number,
default: 0,
validator: (value) => {
// 0 100
return value >= 0 && value <= 100;
},
},
},
computed: {
//
waterHeight() {
return this.waterLevel;
},
},
};
</script>
<style lang="scss" scoped>
.monitor-container {
position: relative;
display: inline-block;
}
.monitor-img3 {
width: 1.2rem;
height: 1.3rem;
}
.waves {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
/* 修改颜色表示,添加透明度 */
background-color: rgba(23, 106, 201, 0.1);
overflow: hidden;
.wave {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: url(../../assets/images/wave.png);
background-size: 200% 100%;
}
.wave1 {
opacity: 1;
top: 0;
z-index: 1000;
animation: animate 4s linear infinite;
}
.wave2 {
opacity: 0.5;
top: 0.2rem;
z-index: 999;
animation: animate2 4s linear infinite;
}
.wave3 {
opacity: 0.2;
top: 0.3rem;
z-index: 999;
animation: animate 2s linear infinite;
}
.wave4 {
opacity: 0.7;
top: 0.4rem;
z-index: 999;
animation: animate2 2s linear infinite;
}
}
@keyframes animate{
0%{
background-position-x: 110px;
}
100%{
background-position-x: 0px;
}
}
@keyframes animate2{
0%{
background-position-x: 0px;
}
100%{
background-position-x: 110px;
}
}
@media (min-width: 1400px) and (max-width: 1620px) {
.monitor-img3 {
width: 110px !important;
height: 120px !important;
}
}
@media (min-width: 1240px) and (max-width: 1400px) {
.monitor-img3 {
width: 90px !important;
height: 100px !important;
}
}
@media (max-width: 1240px) {
.monitor-img3 {
width: 100px !important;
height: 110px !important;
}
}
</style>

631
src/views/hotWater/waterControl/index.vue

@ -2,7 +2,7 @@
<div class="app-container"> <div class="app-container">
<div class="left-tree"> <div class="left-tree">
<!-- el-tree 设置一个固定的高度和滚动条 --> <!-- el-tree 设置一个固定的高度和滚动条 -->
<div style="height: 550px; overflow-y: auto"> <div style="height: 750px; overflow-y: auto">
<el-tree <el-tree
ref="tree" ref="tree"
:data="treeData" :data="treeData"
@ -27,36 +27,155 @@
</template> </template>
</el-tree> </el-tree>
</div> </div>
<div class="status">
<div class="status-li">
<div class="status1">正常</div>
<div>0</div>
</div>
<div class="status-li">
<div class="status2">报警</div>
<div>0</div>
</div>
<div class="status-li">
<div class="status3">异常</div>
<div>0</div>
</div>
<div class="status-li">
<div class="status4">离线</div>
<div>0</div>
</div>
</div>
</div> </div>
<div class="right-monitor"> <div class="right-monitor">
<div> <div class="buildingDiv">
<div class="buildingDiv"> <img
<img class="title-bg"
class="title-bg" src="../../../assets/images/title-bg.png"
src="../../../assets/images/title-bg.png" alt=""
alt="" />
/> <div class="title-word">楼层{{ currentName }}</div>
<div class="title-word">{{ buildingName }}</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('水泵')">
<img
class="monitor-img2"
src="../../../assets/images/startpum.png"
/>
<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="handleWaterPump(item)"
>
</el-switch>
</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.frequency }}Hz</div>
</div>
</div>
</div>
<!-- 热泵 -->
<div class="monitor-flex-left" v-if="activeName.includes('热泵')">
<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-switch
style="display: block"
v-model="item.switchStatus"
active-color="#13ce66"
active-text="开启"
inactive-text="停止"
@change="handleHotPump(item)"
>
</el-switch>
</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"
style="width: 100px"
v-model="item.tempSet"
placeholder="请输入"
@keyup.enter.native="handleEnter(item)"
@input="handleInput(item)"
></el-input>
</div>
</div>
</div>
</div>
<!-- 水箱 -->
<div class="monitor-flex-left" v-if="activeName.includes('水箱')">
<water-tank :waterLevel="50"></water-tank>
<div class="monitor-words">
<div class="words-li">
<div class="ash">实际液位:</div>
<div class="white">{{ item.waterLevel }} %</div>
</div>
<div class="words-li">
<div class="ash">设置液位:</div>
<el-input
size="mini"
style="width: 100px"
v-model="item.waterLevelSet"
placeholder="请输入"
@keyup.enter.native="handleWaterEnter(item)"
@input="handleWaterInput(item)"
></el-input>
</div>
<div class="words-li">
<div class="ash">采集时间:</div>
<div class="white">{{ item.curTime }}</div>
</div>
</div>
</div>
</div>
</div> </div>
<div class="monitor-context" v-loading="loading"></div>
</div> </div>
</div> </div>
</div> </div>
@ -65,22 +184,26 @@
<script> <script>
import { spaceTree } from "@/api/region"; import { spaceTree } from "@/api/region";
import { waterOperateList, operationConrol } from "@/api/hotWater/waterControl"; import { waterOperateList, operationConrol } from "@/api/hotWater/waterControl";
import waterTank from "../../components/waterTank.vue";
export default { export default {
components: { waterTank },
data() { data() {
return { return {
loading: false, loading: false,
buildingName: "",
treeData: [], treeData: [],
defaultProps: { defaultProps: {
children: "children", children: "children",
label: "label", label: "label",
}, },
deviceList: [], tabsList: [],
expandedKeys: [], expandedKeys: [],
currentId: "", //id currentId: "", //id
currentName: "", // currentName: "", //
currentLevel: "", // currentLevel: "", //
currentParentId: "", //id
activeName: "", //
tabsList: [], //tab
devicesList: [], //
}; };
}, },
mounted() { mounted() {
@ -89,7 +212,6 @@ export default {
methods: { methods: {
getSysBuild() { getSysBuild() {
spaceTree().then((res) => { spaceTree().then((res) => {
console.log("楼栋返回值", res);
if (res.code == 200) { if (res.code == 200) {
// //
console.log("楼栋返回值", res); console.log("楼栋返回值", res);
@ -101,7 +223,7 @@ export default {
return item.label && item.label.includes("热水"); return item.label && item.label.includes("热水");
}); });
} }
// 1 2 // 1 4
const targetLevel = 4; const targetLevel = 4;
// data[0] 1 // data[0] 1
if (newRes.data[0]) { if (newRes.data[0]) {
@ -110,14 +232,28 @@ export default {
console.log("筛选后的新结果", newRes); console.log("筛选后的新结果", newRes);
this.treeData = newRes.data; this.treeData = newRes.data;
this.$nextTick(() => { this.$nextTick(() => {
this.$refs.tree.setCurrentKey(this.treeData[0].id); //
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();
}
}); });
console.log("this.treeData[0].id", this.treeData[0].id);
console.log("this.treeData[0].label", this.treeData[0].label);
this.currentId = this.treeData[0].id;
this.currentLevel = this.treeData[0].nodeType;
this.currentName = this.treeData[0].label;
this.getExpandedKeys(this.treeData, 2);
} }
}); });
}, },
@ -139,6 +275,17 @@ export default {
} }
} }
}, },
//
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) { getExpandedKeys(nodes, level) {
nodes.forEach((node) => { nodes.forEach((node) => {
@ -152,9 +299,9 @@ export default {
}, },
// //
getIconClass(node) { getIconClass(node) {
console.log("当前图标的节点内容", node); // console.log("", node);
if (node.level === 5) { if (node.level === 4) {
// // 4
if (node.expanded) { if (node.expanded) {
return "el-icon-document-opened"; // return "el-icon-document-opened"; //
} }
@ -174,9 +321,244 @@ export default {
// //
handleNodeClick(node, data) { handleNodeClick(node, data) {
console.log("点击的当前节点", node, data); console.log("点击的当前节点", node, data);
this.currentId = node.id; if (data.level !== 4) {
this.currentLevel = node.nodeType; console.log("不是第4层000");
this.currentName = node.label; // ,
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) {
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 = {
id: item.id,
name: item.name,
temp: item.temp,
tempSet: item.tempSet,
frequency: item.frequency,
frequencySet: item.frequencySet,
waterLevel: item.waterLevel,
waterLevelSet: item.waterLevelSet,
curTime: item.curTime,
alarmStatus: Number(item.alarmStatus) == 0 ? "无故障" : "故障",
switchStatus: Number(item.switchStatus) == 0 ? false : true,
};
// devicesList
this.devicesList.push(deviceItem);
}
});
console.log("当前楼层water列表", this.devicesList);
}
},
//
getWaterList() {
let data = {
systemType: "1",
floorId: this.currentId,
};
waterOperateList(data).then((res) => {
if (res.code == 200 && res.rows.length > 0) {
this.tabsList = res.rows;
this.activeName = res.rows[0].name;
// 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 = {
id: item.id,
name: item.name,
temp: item.temp,
tempSet: item.tempSet,
frequency: item.frequency,
frequencySet: item.frequencySet,
waterLevel: item.waterLevel,
waterLevelSet: item.waterLevelSet,
curTime: item.curTime,
alarmStatus:
Number(item.alarmStatus) == 0 ? "无故障" : "故障",
switchStatus: Number(item.switchStatus) == 0 ? false : true,
};
// devicesList
this.devicesList.push(deviceItem);
}
});
console.log("当前楼层water列表", this.devicesList);
}
}
});
},
//
handleWaterPump(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.id, param);
})
.catch(() => {
//
item.switchStatus = !item.switchStatus;
});
},
//
handleHotPump(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.id, param);
})
.catch(() => {
//
item.switchStatus = !item.switchStatus;
});
},
//
handleEnter(item) {
this.$confirm(
`确定要修改"${item.name}"的温度为:${item.tempSet} ℃吗?`,
"提示",
{
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}
)
.then(() => {
this.hadleOperationConrol(item.id, item.tempSet);
})
.catch(() => {});
},
//
handleWaterEnter(item) {
console.log("请求后端");
this.$confirm(
`确定要修改"${item.name}"的水位为:${item.waterLevelSet} %吗?`,
"提示",
{
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}
)
.then(() => {
this.hadleOperationConrol(item.id, item.waterLevelSet);
})
.catch(() => {});
},
//
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("操作成功");
// ;
this.getWaterList();
} else {
// this.$modal.msgError("");
console.log("应该更新状态的");
// ;
this.getWaterList();
}
})
.catch((error) => {
console.log("请求发生错误,更新设备状态", error);
// ;
this.getWaterList();
});
}, },
}, },
}; };
@ -255,7 +637,7 @@ export default {
width: calc(100% - 240px); width: calc(100% - 240px);
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: space-between; justify-content: flex-start;
.buildingDiv { .buildingDiv {
padding-left: 54px; padding-left: 54px;
display: flex; display: flex;
@ -290,6 +672,112 @@ export default {
align-content: flex-start; 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 {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
width: 100%;
padding: 0 0.2rem;
.monitor-img1 {
width: 1.2rem;
height: 1.2rem;
}
.monitor-img2 {
width: 1.2rem;
height: 0.8rem;
}
.monitor-words {
.words-li {
display: flex;
flex-direction: row;
align-items: center;
font-family: SourceHanSansCN-Regular;
font-size: 16px;
line-height: 28px;
margin-bottom: 10px;
.ash {
color: #b8bfcb;
white-space: nowrap;
margin-right: 8px;
}
.white {
color: #ffffff;
}
}
}
}
}
}
.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 { .tree-container {
height: 300px; /* 设置固定高度 */ height: 300px; /* 设置固定高度 */
@ -316,6 +804,55 @@ export default {
} }
} }
} }
@media (min-width: 1400px) and (max-width: 1620px) {
.monitor-li {
width: calc(49% - 40px) !important;
margin: 0 20px !important;
.monitor-img1 {
width: 120px !important;
height: 120px !important;
}
.monitor-img2 {
width: 120px !important;
height: 80px !important;
}
.monitor-flex-left {
padding: 0 0.3rem !important;
}
}
}
@media (min-width: 1240px) and (max-width: 1400px) {
.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;
}
}
@media (max-width: 1240px) {
.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-flex-left {
padding: 0 30px !important;
}
}
}
</style> </style>
<style scoped> <style scoped>
/* 自定义高亮颜色 */ /* 自定义高亮颜色 */

377
src/views/hotWater/waterMonitor/index.vue

@ -1,18 +1,361 @@
<template> <template>
<div>热水监测</div> <div class="app-container">
</template> <div class="left-tree">
<!-- el-tree 设置一个固定的高度和滚动条 -->
<script> <div style="height: 750px; overflow-y: auto">
import { monitorList } from "@/api/centerairC/sysMonitor"; <el-tree
export default { ref="tree"
data() { :data="treeData"
return { node-key="id"
deviceList: [], :default-expand-all="false"
}; :default-expanded-keys="expandedKeys"
}, :auto-expand-parent="true"
mounted() {}, icon-class="none"
methods: {}, @node-expand="handleNodeExpand"
}; @node-collapse="handleNodeCollapse"
</script> :highlight-current="true"
@node-click="handleNodeClick"
<style></style> >
<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">
<el-tab-pane label="热泵" name="first"> </el-tab-pane>
<el-tab-pane label="高区水泵" name="second"> </el-tab-pane>
<el-tab-pane label="低区水泵" name="three"> </el-tab-pane>
<el-tab-pane label="水箱" name="four"> </el-tab-pane>
</el-tabs>
</div>
</div>
</div>
</template>
<script>
import { spaceTree } from "@/api/region";
import { waterOperateList, operationConrol } from "@/api/hotWater/waterControl";
export default {
data() {
return {
loading: false,
treeData: [],
defaultProps: {
children: "children",
label: "label",
},
deviceList: [],
expandedKeys: [],
currentId: "", //id
currentName: "", //
currentLevel: "", //
currentParentId: "", //id
activeName: "first", //
};
},
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);
}
});
}
});
},
// 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);
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);
return;
}
},
handleClick(tab, event) {
console.log(tab, event);
console.log("activeName", this.activeName);
},
},
};
</script>
<style lang="scss" scoped>
.app-container {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: stretch;
height: 100%;
.left-tree {
width: 216px;
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% - 240px);
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;
}
}
}
.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;
}
}
}
</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;
}
</style>

Loading…
Cancel
Save