主线路图

This commit is contained in:
2025-08-20 17:26:01 +08:00
parent c3d64e4d04
commit a0790b100a
2 changed files with 895 additions and 181 deletions

View File

@ -21,89 +21,174 @@
<!-- 电表-->
<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] }}
<div
class="row-lists"
v-for="outter in Math.ceil(db.length / 3)"
:key="outter + 'row'"
>
<template v-for="(item, index) in handlerList('db', outter)">
<div :key="index" class="row-items">
<div
style="position: relative; z-index: 2; background-color: #fff"
>
<div
class="status"
:class="
item.communicationStatus === '0' ? 'status-running' : ''
"
>
{{ communicationStatusOptions[item.communicationStatus] }}
</div>
<div class="row-items-img">
<img
class="img-db"
:src="require('@/assets/images/ems/db.png')"
/>
<div class="name">{{ item.deviceName }}</div>
</div>
</div>
</div>
<div class="row-items-img">
<img
class="img-db"
:src="require('@/assets/images/ems/db.png')"
/>
<div class="name">{{ item.deviceName }}</div>
</div>
</div>
</template>
</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] }}
<div
class="row-lists"
v-for="outter in Math.ceil(lq.length / 3)"
:key="outter + 'row'"
>
<template v-for="(item, index) in handlerList('lq', outter)">
<div :key="index" class="row-items">
<div
style="position: relative; z-index: 2; background-color: #fff"
>
<div
class="status"
:class="
item.communicationStatus === '0' ? 'status-running' : ''
"
>
{{ communicationStatusOptions[item.communicationStatus] }}
</div>
<div class="row-items-img">
<img
class="img-lq"
:src="require('@/assets/images/ems/lq.png')"
/>
<div class="name">{{ item.deviceName }}</div>
</div>
</div>
</div>
<div class="row-items-img">
<img
class="img-lq"
:src="require('@/assets/images/ems/lq.png')"
/>
<div class="name">{{ item.deviceName }}</div>
</div>
</div>
</template>
</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"
<!-- 没有上级设备的bms -->
<div
class="row-lists-container"
v-if="bmsHasParentLength !== bms.length"
>
<div class="row-title">BMS({{ bmsNoParent.length }})</div>
<div
class="row-lists"
v-for="outter in Math.ceil(bmsNoParent.length / 3)"
:key="outter + 'row'"
>
<template
v-for="(item, index) in handlerList('bmsNoParent', outter)"
>
<!-- pcs -->
<div class="parent-dash">
<div :key="index" class="row-items">
<div
class="status"
:class="
item.communicationStatus === '0' ? 'status-running' : ''
"
style="position: relative; z-index: 2; background-color: #fff"
>
{{ 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>
<div
class="status"
:class="
item.communicationStatus === '0' ? 'status-running' : ''
"
>
{{ communicationStatusOptions[item.communicationStatus] }}
</div>
<div class="row-items-img">
<img
class="img-bms"
:src="require('@/assets/images/ems/bms.png')"
/>
<div class="name">{{ item.deviceName }}</div>
</div>
</div>
</div>
<!-- 子设备 bms -->
<div
v-if="item.children && item.children.length > 0"
class="children-dash"
>
</template>
</div>
</div>
<!-- pcs -->
<div
class="row-lists-container row-lists-container-with-children"
v-if="showPcs"
>
<div class="row-title">
PCS({{ pcs.length }}){{
pcsHasChildren.length > 0 ? `、BMS(${pcsHasChildren.length})` : ""
}}
</div>
<div
class="row-lists"
v-for="outter in Math.ceil(pcs.length / 3)"
:key="outter + 'row'"
>
<template v-for="(item, index) in handlerList('pcs', outter)">
<div :key="index" class="row-items">
<!-- 上级设备 -->
<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>
</div>
</div>
<!-- 下级设备 -->
<div
v-for="(childrenItem, childrenIndex) in item.children"
:key="childrenIndex + 'childrenBms'"
></div>
class="children-dash"
v-if="item.children && item.children.length > 0"
>
<div
class="status"
:class="
item.children[0].communicationStatus === '0'
? 'status-running'
: ''
"
>
{{
communicationStatusOptions[
item.children[0].communicationStatus
]
}}
</div>
<div class="row-items-img">
<img
class="img-pcs"
:src="require('@/assets/images/ems/bms.png')"
/>
<div class="name">{{ item.children[0].deviceName }}</div>
</div>
</div>
</div>
</div>
</template>
</div>
</div>
</div>
@ -126,8 +211,6 @@ export default {
bms: [],
db: [],
lq: [],
pcsHasChildren: [],
pcsNoChildren: [],
bmsNoParent: [],
};
},
@ -149,14 +232,30 @@ export default {
showLq() {
return this.lq.length > 0;
},
showPcsAndBms() {
return this.showPcs || this.showBms;
bmsHasParentLength() {
let count = 0;
this.pcs.forEach((item) => (count += item.children.length));
return count;
},
pcsHasChildren() {
return this.pcs.filter(
(item) => item.children && item.children.length > 0
);
},
empty() {
return !this.showBms && !this.showPcs && !this.showDb && !this.showLq;
},
},
methods: {
handlerList(type, index) {
const arr = this[type];
const max = index * 3 > arr.length ? arr.length % 3 : 3;
let result = [];
for (let i = 1; i <= max; i++) {
result.push(arr[i - 1 + 3 * (index - 1)]);
}
return result;
},
init() {
this.pcs = [];
this.bms = [];
@ -200,8 +299,6 @@ export default {
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;
})
.finally(() => {
@ -332,126 +429,166 @@ $lineColor: #86bcc7;
.outer-border {
position: relative;
width: fit-content;
border: 2px solid $borderColor;
padding-left: 120px;
border: 1.5px solid $borderColor;
padding-left: 40px;
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 {
display: flex;
display: flex;
// 设备列表
.row-lists-container {
font-size: 10px;
position: relative;
// 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 {
padding: 10px 20px;
display: flex;
&:not(:first-child) {
background: linear-gradient(
to top,
transparent 0%,
transparent 50%,
#ccc 50%,
#ccc 100%
);
background-size: 1px 10px;
background-repeat: repeat-y;
}
.row-title {
position: absolute;
left: -$sqDistance - 30px;
top: -20px;
left: 50%;
transform: translateX(-50%);
color: #000;
font-weight: bolder;
}
.row-lists {
position: relative;
padding: 5px 0;
&:not(:first-child) {
margin-left: $sqDistance; //和外层父元素上下padding一致
}
&::before {
content: "";
display: block;
height: 3px;
width: $sqDistance - 2px;
background: $lineColor;
position: absolute;
left: -$sqDistance;
top: calc(50% + 10px);
transform: scale(1, 0.4);
}
// 一列 第一个设备最上面的线
&:first-child {
&::before {
width: $sqDistance + 20px;
// top: -$sqDistance - 20px;
}
}
// 一列 最后一个设备最下面的线
// &: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;
}
}
// 图片+设备名称
.row-items-img {
.row-items {
position: relative;
padding-top: 12px;
img {
width: 80px;
height: auto;
padding: 5px 0;
background: #fff;
// &:not(:first-child) {
padding-top: 20px; //todo
// }
&::after {
z-index: 1;
content: "";
display: block;
&.img-lq {
width: 50px;
}
&.img-pcs {
width: 50px;
}
&.img-db {
width: 56px;
height: 25px;
width: 3px;
background: $lineColor;
position: absolute;
left: 50%;
top: -10px;
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;
}
}
.name {
position: absolute;
top: 1px;
left: 0;
color: #666;
// 图片+设备名称
.row-items-img {
position: relative;
padding-top: 12px;
img {
width: 80px;
height: auto;
display: block;
&.img-lq {
width: 50px;
}
&.img-pcs {
width: 50px;
}
&.img-db {
width: 56px;
}
}
.name {
position: absolute;
top: 1px;
left: 0;
color: #666;
white-space: nowrap;
}
}
}
}
}
// 有下级设备
.row-lists-container-with-children {
.row-lists {
&:not(:last-child) {
margin-right: 30px;
}
.row-items {
display: flex;
&::after {
display: none;
}
.parent-dash {
position: relative;
z-index: 2;
background-color: #fff;
> div {
z-index: 2;
position: inherit;
}
&::after {
z-index: 1;
content: "";
display: block;
height: 45px;
width: 3px;
background: $lineColor;
position: absolute;
left: 50%;
top: -30px;
transform: scale(0.4, 1);
}
}
.children-dash {
position: relative;
z-index: 2;
background-color: #fff;
margin: -20px 0 0 26px;
height: fit-content;
> div {
z-index: 2;
position: inherit;
}
&::after {
z-index: 1;
content: "";
display: block;
width: 44px;
height: 1px;
background: #ec7f8c;
position: absolute;
left: -33px;
bottom: -10px;
transform: rotate(-34deg);
}
}
}
}
}
}
//pcs 特殊样式
.row-lists-container-pcs {
// margin-top: -100px;
}
}
</style>