Files
emsfront/src/views/ems/dzjk/zxlt/index.vue

458 lines
12 KiB
Vue
Raw Normal View History

2025-07-11 00:14:58 +08:00
<template>
2025-08-18 18:13:24 +08:00
<div class="ems-dashboard-editor-container" v-loading="loading">
<div class="container" v-show="!empty">
<!-- 电脑 -->
<div class="top">
<div class="cloud-container">
<div class="cloud">
<span style="z-index: 2; position: relative"></span>
2025-07-13 20:10:30 +08:00
</div>
2025-07-11 00:14:58 +08:00
</div>
2025-08-18 18:13:24 +08:00
<div class="double-arrows">
<div class="top-arrows"></div>
<div class="bottom-arrows"></div>
</div>
<div class="computer">
<img src="@/assets/images/ems/computer.png" alt="" />
<span style="z-index: 2; position: relative">ems</span>
</div>
</div>
<div class="outer-border">
<!-- 电表-->
<div class="row-lists-container" v-if="showDb">
<div class="row-title">电表({{ db.length }})</div>
<div class="row-lists">
<div v-for="item in db" :key="item.deviceId" class="row-items">
<div
class="status"
:class="
item.communicationStatus === '0' ? 'status-running' : ''
"
>
{{ communicationStatusOptions[item.communicationStatus] }}
2025-07-11 00:14:58 +08:00
</div>
2025-08-18 18:13:24 +08:00
<div class="row-items-img">
<img
class="img-db"
:src="require('@/assets/images/ems/db.png')"
/>
<div class="name">{{ item.deviceName }}</div>
2025-07-11 00:14:58 +08:00
</div>
2025-07-13 20:10:30 +08:00
</div>
2025-08-18 18:13:24 +08:00
</div>
</div>
<!-- 液冷-->
<div class="row-lists-container" v-if="showLq">
<div class="row-title">冷却({{ lq.length }})</div>
<div class="row-lists">
<div v-for="item in lq" :key="item.deviceId" class="row-items">
<div
class="status"
:class="
item.communicationStatus === '0' ? 'status-running' : ''
"
>
{{ communicationStatusOptions[item.communicationStatus] }}
2025-07-19 14:14:21 +08:00
</div>
2025-08-18 18:13:24 +08:00
<div class="row-items-img">
<img
class="img-lq"
:src="require('@/assets/images/ems/lq.png')"
/>
<div class="name">{{ item.deviceName }}</div>
2025-07-11 00:14:58 +08:00
</div>
2025-07-13 20:10:30 +08:00
</div>
2025-08-18 18:13:24 +08:00
</div>
</div>
<!-- PCS-->
<div class="row-lists-container row-lists-container-pcs" v-if="showPcs">
<div class="row-title">PCS({{ pcs.length }})</div>
<div class="row-lists">
<div
v-for="item in pcs"
:key="item.deviceId"
class="row-items row-items-pcs"
>
<!-- pcs -->
<div class="parent-dash">
<div
class="status"
:class="
item.communicationStatus === '0' ? 'status-running' : ''
"
>
{{ communicationStatusOptions[item.communicationStatus] }}
</div>
<div class="row-items-img">
<img
class="img-pcs"
:src="require('@/assets/images/ems/pcs.png')"
/>
<div class="name">{{ item.deviceName }}</div>
2025-07-11 00:14:58 +08:00
</div>
</div>
2025-08-18 18:13:24 +08:00
<!-- 子设备 bms -->
<div
v-if="item.children && item.children.length > 0"
class="children-dash"
>
<div
v-for="(childrenItem, childrenIndex) in item.children"
:key="childrenIndex + 'childrenBms'"
></div>
</div>
2025-07-13 20:10:30 +08:00
</div>
</div>
2025-07-11 00:14:58 +08:00
</div>
</div>
</div>
2025-08-18 18:13:24 +08:00
<el-empty v-show="empty" :image-size="200"></el-empty>
</div>
2025-07-11 00:14:58 +08:00
</template>
2025-07-19 15:22:26 +08:00
<script>
2025-08-18 18:13:24 +08:00
import { getDeviceList } from "@/api/ems/site";
2025-07-19 15:22:26 +08:00
import getQuerySiteId from "@/mixins/ems/getQuerySiteId";
2025-08-18 18:13:24 +08:00
import { mapState } from "vuex";
2025-07-19 15:22:26 +08:00
export default {
2025-08-18 18:13:24 +08:00
name: "DzjkZxlt",
2025-07-19 15:22:26 +08:00
mixins: [getQuerySiteId],
data() {
return {
2025-08-18 18:13:24 +08:00
loading: false,
pcs: [],
bms: [],
db: [],
lq: [],
pcsHasChildren: [],
pcsNoChildren: [],
bmsNoParent: [],
};
2025-07-19 15:22:26 +08:00
},
2025-08-18 18:13:24 +08:00
computed: {
2025-07-19 15:22:26 +08:00
...mapState({
2025-08-18 18:13:24 +08:00
communicationStatusOptions: (state) =>
state.ems.communicationStatusOptions,
2025-07-19 15:22:26 +08:00
}),
2025-08-18 18:13:24 +08:00
showPcs() {
return this.pcs.length > 0;
2025-07-19 15:22:26 +08:00
},
2025-08-18 18:13:24 +08:00
showBms() {
return this.bms.length > 0;
2025-07-19 15:22:26 +08:00
},
2025-08-18 18:13:24 +08:00
showDb() {
return this.db.length > 0;
2025-07-19 15:22:26 +08:00
},
2025-08-18 18:13:24 +08:00
showLq() {
return this.lq.length > 0;
2025-07-19 15:22:26 +08:00
},
2025-08-18 18:13:24 +08:00
showPcsAndBms() {
return this.showPcs || this.showBms;
2025-07-19 15:22:26 +08:00
},
2025-08-18 18:13:24 +08:00
empty() {
return !this.showBms && !this.showPcs && !this.showDb && !this.showLq;
2025-07-19 15:22:26 +08:00
},
},
methods: {
2025-08-18 18:13:24 +08:00
init() {
this.pcs = [];
this.bms = [];
this.lq = [];
this.db = [];
this.bmsNoParent = [];
this.loading = true;
getDeviceList(this.siteId)
.then((response) => {
const data = JSON.parse(JSON.stringify(response?.data || []));
let pcs = [],
bms = [],
db = [],
lq = [],
bmsNoParent = [];
data.forEach((item) => {
// 电表
if (item.deviceCategory === "AMMETER") {
db.push({ ...item, children: [] });
} else if (item.deviceCategory === "PCS") {
// pcs
pcs.push({ ...item, children: [] });
} else if (item.deviceCategory === "STACK") {
// bms
bms.push({ ...item, children: [] });
} else if (item.deviceCategory === "COOLING") {
// 液冷
lq.push({ ...item, children: [] });
}
});
bms.forEach((item, index) => {
if (item.parentId) {
pcs
.find((pcsItem) => pcsItem.deviceId === item.parentId)
.children.push(item);
} else {
bmsNoParent.push(item);
}
});
this.pcs = pcs;
this.bms = bms;
this.lq = lq;
this.db = db;
this.pcsHasChildren = pcs.filter((item) => item.children.length > 0);
this.pcsNoChildren = pcs.filter((item) => item.children.length === 0);
this.bmsNoParent = bmsNoParent;
2025-07-19 15:22:26 +08:00
})
2025-08-18 18:13:24 +08:00
.finally(() => {
this.loading = false;
});
},
2025-07-19 15:22:26 +08:00
},
2025-08-18 18:13:24 +08:00
};
2025-07-19 15:22:26 +08:00
</script>
2025-07-11 00:14:58 +08:00
<style lang="scss" scoped>
2025-08-18 18:13:24 +08:00
$sqDistance: 30px;
$borderColor: #174a8e;
$lineColor: #86bcc7;
2025-07-11 00:14:58 +08:00
.ems-dashboard-editor-container {
background-color: #ffffff;
2025-08-18 18:13:24 +08:00
padding: 0;
color: #666666;
.container {
display: flex;
2025-07-11 00:14:58 +08:00
position: relative;
}
2025-07-19 14:14:21 +08:00
//云 、计算机 、箭头
2025-08-18 18:13:24 +08:00
.top {
z-index: 2;
width: fit-content;
2025-07-13 20:10:30 +08:00
display: flex;
2025-08-18 18:13:24 +08:00
justify-content: center;
align-items: center;
// position: absolute;
// top: 50%;
// left: 0;
// transform: translateY(-50%);
2025-07-13 20:10:30 +08:00
//云 样式
2025-08-18 18:13:24 +08:00
.cloud-container {
margin: 0 auto;
2025-07-13 20:10:30 +08:00
.cloud {
2025-08-18 18:13:24 +08:00
width: 60px;
height: 26px;
2025-07-13 20:10:30 +08:00
background: #cbebfd;
2025-08-18 18:13:24 +08:00
border-radius: 100px;
2025-07-13 20:10:30 +08:00
position: relative;
text-align: center;
2025-08-18 18:13:24 +08:00
font-weight: bold;
font-size: 14px;
line-height: 26px;
2025-07-13 20:10:30 +08:00
}
2025-08-18 18:13:24 +08:00
.cloud:before,
.cloud:after {
content: "";
2025-07-13 20:10:30 +08:00
position: absolute;
2025-08-18 18:13:24 +08:00
background: #cbebfd;
width: 30px;
height: 30px;
border-radius: 100%;
2025-07-13 20:10:30 +08:00
}
.cloud:before {
2025-08-18 18:13:24 +08:00
top: -9px;
left: 8px;
2025-07-13 20:10:30 +08:00
}
.cloud:after {
2025-08-18 18:13:24 +08:00
top: -6px;
right: 9px;
2025-07-13 20:10:30 +08:00
}
}
2025-07-16 22:23:28 +08:00
//双箭头
2025-07-13 20:10:30 +08:00
.double-arrows {
2025-08-18 18:13:24 +08:00
height: fit-content;
margin: 0 10px;
2025-07-16 22:23:28 +08:00
text-align: center;
2025-08-18 18:13:24 +08:00
.top-arrows,
.bottom-arrows {
height: 4px;
width: 30px;
background-color: #5ea9df;
2025-07-16 22:23:28 +08:00
margin: 0 10px;
2025-07-13 20:10:30 +08:00
position: relative;
&::after {
2025-08-18 18:13:24 +08:00
content: "";
2025-07-13 20:10:30 +08:00
position: absolute;
2025-08-18 18:13:24 +08:00
left: 0;
2025-07-13 20:10:30 +08:00
width: 0;
height: 0;
}
}
2025-08-18 18:13:24 +08:00
.top-arrows {
2025-07-16 22:23:28 +08:00
vertical-align: super;
}
2025-07-13 20:10:30 +08:00
.top-arrows::after {
2025-08-18 18:13:24 +08:00
top: -4px;
border-bottom: 6px solid transparent;
border-left: 6px solid transparent;
border-right: 6px solid #5ea9df;
border-top: 6px solid transparent;
left: -11px;
2025-07-13 20:10:30 +08:00
}
2025-08-18 18:13:24 +08:00
.bottom-arrows {
margin-top: 8px;
2025-07-13 20:10:30 +08:00
&::after {
2025-08-18 18:13:24 +08:00
top: -4px;
border-top: 6px solid transparent;
border-left: 6px solid #5ea9df;
border-right: 6px solid transparent;
border-bottom: 6px solid transparent;
right: -11px;
left: auto;
2025-07-13 20:10:30 +08:00
}
}
2025-07-11 00:14:58 +08:00
}
2025-07-13 20:10:30 +08:00
//电脑
2025-08-18 18:13:24 +08:00
.computer {
2025-07-13 20:10:30 +08:00
text-align: center;
2025-08-18 18:13:24 +08:00
font-size: 14px;
line-height: 16px;
font-weight: bold;
2025-07-13 20:10:30 +08:00
position: relative;
2025-08-18 18:13:24 +08:00
background: #fff;
2025-07-13 20:10:30 +08:00
img {
2025-08-18 18:13:24 +08:00
width: 80px;
height: auto;
2025-07-13 20:10:30 +08:00
display: block;
}
2025-07-16 22:23:28 +08:00
}
2025-07-11 00:14:58 +08:00
}
2025-08-18 18:13:24 +08:00
.outer-border {
position: relative;
width: fit-content;
border: 2px solid $borderColor;
padding-left: 120px;
margin-left: -40px;
}
// 设备列表
.row-lists-container {
font-size: 10px;
position: relative;
padding: 10px;
.row-title {
position: absolute;
left: -$sqDistance - 30px;
top: calc(50% + 10px);
transform: translateY(-50%);
color: #000;
font-weight: bolder;
}
.row-lists {
2025-07-13 20:10:30 +08:00
display: flex;
2025-07-16 22:23:28 +08:00
position: relative;
2025-08-18 18:13:24 +08:00
// width: fit-content;
// &::before {
// content: "";
// display: block;
// height: 3px;
// width: 100%;
// background: $lineColor;
// position: absolute;
// right: 60px;
// top: 50%;
// transform: scale(0.4, 1);
// }
.row-items {
2025-07-19 14:14:21 +08:00
position: relative;
2025-08-18 18:13:24 +08:00
padding: 5px 0;
&:not(:first-child) {
margin-left: $sqDistance; //和外层父元素上下padding一致
}
&::before {
content: "";
2025-07-16 22:23:28 +08:00
display: block;
2025-08-18 18:13:24 +08:00
height: 3px;
width: $sqDistance - 2px;
background: $lineColor;
2025-07-16 22:23:28 +08:00
position: absolute;
2025-08-18 18:13:24 +08:00
left: -$sqDistance;
top: calc(50% + 10px);
transform: scale(1, 0.4);
2025-07-16 22:23:28 +08:00
}
2025-08-18 18:13:24 +08:00
// 一列 第一个设备最上面的线
&:first-child {
&::before {
width: $sqDistance + 20px;
// top: -$sqDistance - 20px;
2025-07-16 22:23:28 +08:00
}
}
2025-08-18 18:13:24 +08:00
// 一列 最后一个设备最下面的线
// &:last-child {
// &::after {
// content: "";
// display: block;
// width: 3px;
// height: $sqDistance - 2px;
// background: $lineColor;
// position: absolute;
// bottom: -$sqDistance;
// left: 50%;
// transform: scale(0.4, 1);
// }
// }
// 设备状态
.status {
margin: 0 auto 4px;
width: fit-content;
height: 18px;
padding: 0 8px;
box-sizing: border-box;
text-align: center;
font-size: 8px;
line-height: 18px;
border: 1px solid #08ffff;
border-radius: 2px;
background: #aaaaaa;
color: #ffffff;
&.status-running {
background: #00c69c;
2025-07-19 14:14:21 +08:00
}
2025-08-18 18:13:24 +08:00
}
// 图片+设备名称
.row-items-img {
position: relative;
padding-top: 12px;
img {
width: 80px;
height: auto;
display: block;
&.img-lq {
width: 50px;
2025-07-13 20:10:30 +08:00
}
2025-08-18 18:13:24 +08:00
&.img-pcs {
width: 50px;
2025-07-19 14:14:21 +08:00
}
2025-08-18 18:13:24 +08:00
&.img-db {
width: 56px;
2025-07-13 20:10:30 +08:00
}
}
2025-08-18 18:13:24 +08:00
.name {
position: absolute;
top: 1px;
left: 0;
color: #666;
2025-07-19 15:22:26 +08:00
}
}
2025-07-11 00:14:58 +08:00
}
}
2025-08-18 18:13:24 +08:00
}
//pcs 特殊样式
.row-lists-container-pcs {
// margin-top: -100px;
2025-07-11 00:14:58 +08:00
}
}
</style>