2025-07-11 00:14:58 +08:00
< template >
< div class = "ems-dashboard-editor-container" v-loading = "loading" >
< div class = "container" v-show = "!empty" >
< div class = "top" >
2025-07-13 20:10:30 +08:00
< div class = "cloud-container" >
< div class = "cloud" >
< span style = "z-index:2;position: relative;" > 云 < / span >
< / div >
< / div >
< 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 >
2025-07-16 22:23:28 +08:00
< div class = "arrow" > < / div >
2025-07-11 00:14:58 +08:00
< / div >
< div class = "bottom" >
2025-07-13 20:10:30 +08:00
<!-- 四列设备 -- >
< div class = "zxlt-row" >
2025-07-19 15:22:26 +08:00
<!-- bms 、 pcs 下级和上级在一列 -- >
< div class = "row-lists pcs-row-lists" v-if = "showPcsAndBms" >
2025-07-19 14:14:21 +08:00
< div class = "item-square" >
2025-08-11 21:50:38 +08:00
< div class = "row-lists-title" v-if = "showPcs" > PCS ( {{ pcs.length }} ) < / div >
< div class = "row-lists-title" v-if = "showBms" > BMS ( {{ bms.length }} ) < / div >
2025-07-19 14:14:21 +08:00
< / div >
<!-- 上下级块 class区分 -- >
2025-07-19 15:22:26 +08:00
< div class = "item-square pcs-has-children-item-square" :class = "{'no-bms-list':!showBms}" v-for = "(item,index) in pcsHasChildren" :key="index+'pcsHasChildren'" >
2025-07-19 14:14:21 +08:00
<!-- 左边的上级 上级只有一个 -- >
2025-07-19 15:22:26 +08:00
< div class = "item-lists parent-item-lists" >
2025-07-19 14:14:21 +08:00
<!-- 上级设备 -- >
< div class = "items normal-items-arrow" >
< div class = "items-inner" >
< div style = "text-align: center;margin-bottom:10px;" >
< div class = "status" : class = "item.communicationStatus === '0' ?'status-normal' : 'status-warn'" > 通讯状态 : { { communicationStatusOptions [ item . communicationStatus ] || '-' } } < / div >
< / div >
< img v-if = "item.pictureUrl" :src="item.pictureUrl" >
< img v-else :src = "require('@/assets/images/ems/pcs.png')" / >
< div class = "name" > { { item . deviceName } } < / div >
< / div >
< / div >
< / div >
<!-- 右边的下级 下级有多个 -- >
< div class = "item-lists children-item-lists" >
<!-- 下级设备 循环生成 -- >
< div class = "items children-items-arrow bms-children-arrow" v-for = "children in item.children" :key="children.deviceId" >
< div class = "items-inner" >
< div style = "text-align: center;margin-bottom:10px;" >
< div class = "status" : class = "children.communicationStatus === '0' ?'status-normal' : 'status-warn'" > 通讯状态 : { { communicationStatusOptions [ children . communicationStatus ] || '-' } } < / div >
< / div >
< img v-if = "children.pictureUrl" :src="children.pictureUrl" >
< img v-else :src = "require('@/assets/images/ems/bms.png')" / >
< div class = "name" > { { children . deviceName } } < / div >
< / div >
2025-07-11 00:14:58 +08:00
< / div >
< / div >
2025-07-19 14:14:21 +08:00
2025-07-11 00:14:58 +08:00
< / div >
2025-07-19 15:22:26 +08:00
<!-- 没有上下级关系的bms 、 pcs -- >
< div class = "item-square" :class = "{'no-bms-list':!showBms}" >
2025-07-19 14:14:21 +08:00
<!-- 左边没有下级的pcs -- >
< div class = "item-lists" >
< div class = "items normal-items-arrow" v-for = "item in pcsNoChildren" :key="item.deviceId" >
< div class = "items-inner" >
< div style = "text-align: center;margin-bottom:10px;" >
< div class = "status" : class = "item.communicationStatus === '0' ?'status-normal' : 'status-warn'" > 通讯状态 : { { communicationStatusOptions [ item . communicationStatus ] || '-' } } < / div >
< / div >
< img v-if = "item.pictureUrl" :src="item.pictureUrl" >
< img v-else :src = "require('@/assets/images/ems/pcs.png')" / >
< div class = "name" > { { item . deviceName } } < / div >
< / div >
< / div >
< / div >
<!-- 右边没有上级的bms -- >
< div class = "item-lists" >
<!-- 下级设备 循环生成 -- >
2025-07-19 15:22:26 +08:00
< div class = "items children-items-arrow" v-for = "item in bmsNoParent" :key="item.deviceId" >
2025-07-19 14:14:21 +08:00
< div class = "items-inner" >
< div style = "text-align: center;margin-bottom:10px;" >
< div class = "status" : class = "item.communicationStatus === '0' ?'status-normal' : 'status-warn'" > 通讯状态 : { { communicationStatusOptions [ item . communicationStatus ] || '-' } } < / div >
< / div >
< img v-if = "item.pictureUrl" :src="item.pictureUrl" >
< img v-else :src = "require('@/assets/images/ems/bms.png')" / >
< div class = "name" > { { item . deviceName } } < / div >
< / div >
2025-07-11 00:14:58 +08:00
< / div >
< / div >
< / div >
2025-07-13 20:10:30 +08:00
< / div >
2025-07-19 15:22:26 +08:00
<!-- 电表 -- >
< div class = "row-lists" v-if = "showDb" >
2025-07-19 14:14:21 +08:00
< div class = "item-square" >
2025-08-11 21:50:38 +08:00
< div class = "row-lists-title" style = "width:100%;" > 电表 ( { { db . length } } ) < / div >
2025-07-19 14:14:21 +08:00
< / div >
< div class = "item-square" >
<!-- 左边的下级 下级有多个 -- >
< div class = "item-lists" >
<!-- 下级设备 循环生成 -- >
< div class = "items normal-items-arrow" v-for = "item in db" :key="item.deviceId" >
< div class = "items-inner" >
< div style = "text-align: center;margin-bottom:10px;" >
< div class = "status" : class = "item.communicationStatus === '0' ?'status-normal' : 'status-warn'" > 通讯状态 : { { communicationStatusOptions [ item . communicationStatus ] || '-' } } < / div >
< / div >
< img v-if = "item.pictureUrl" :src="item.pictureUrl" >
< img v-else :src = "require('@/assets/images/ems/bms.png')" / >
< div class = "name" > { { item . deviceName } } < / div >
< / div >
2025-07-11 00:14:58 +08:00
< / div >
< / div >
< / div >
2025-07-19 14:14:21 +08:00
2025-07-13 20:10:30 +08:00
< / div >
2025-07-19 15:22:26 +08:00
<!-- 冷却 -- >
< div class = "row-lists" v-if = "showLq" >
2025-07-19 14:14:21 +08:00
< div class = "item-square" >
2025-08-11 21:50:38 +08:00
< div class = "row-lists-title" style = "width:100%;" > 冷却 ( { { lq . length } } ) < / div >
2025-07-19 14:14:21 +08:00
< / div >
< div class = "item-square" >
< div class = "item-lists" >
< div class = "items normal-items-arrow" v-for = "item in lq" :key="item.deviceId" >
< div class = "items-inner" >
< div style = "text-align: center;margin-bottom:10px;" >
< div class = "status" : class = "item.communicationStatus === '0' ?'status-normal' : 'status-warn'" > 通讯状态 : { { communicationStatusOptions [ item . communicationStatus ] || '-' } } < / div >
< / div >
< img v-if = "item.pictureUrl" :src="item.pictureUrl" >
< img v-else :src = "require('@/assets/images/ems/bms.png')" / >
< div class = "name" > { { item . deviceName } } < / div >
< / div >
2025-07-11 00:14:58 +08:00
< / div >
< / div >
< / div >
2025-07-13 20:10:30 +08:00
< / div >
< / div >
2025-07-11 00:14:58 +08:00
< / div >
< / div >
< el-empty v-show = "empty" :image-size="200" > < / el -empty >
< / div >
< / template >
2025-07-19 15:22:26 +08:00
< script >
import { getDeviceList } from '@/api/ems/site'
import getQuerySiteId from "@/mixins/ems/getQuerySiteId" ;
import { mapState } from "vuex" ;
export default {
name : 'DzjkZxlt' ,
mixins : [ getQuerySiteId ] ,
data ( ) {
return {
loading : false ,
pcs : [ ] ,
bms : [ ] ,
db : [ ] ,
lq : [ ] ,
pcsHasChildren : [ ] ,
pcsNoChildren : [ ] ,
bmsNoParent : [ ]
}
} ,
computed : {
... mapState ( {
communicationStatusOptions : ( state ) => state . ems . communicationStatusOptions
} ) ,
showPcs ( ) {
return this . pcs . length > 0
} ,
showBms ( ) {
return this . bms . length > 0
} ,
showDb ( ) {
return this . db . length > 0
} ,
showLq ( ) {
return this . lq . length > 0
} ,
showPcsAndBms ( ) {
return this . showPcs || this . showBms
} ,
empty ( ) {
return ! this . showBms && ! this . showPcs && ! this . showDb && ! this . showLq
} ,
} ,
methods : {
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
} ) . finally ( ( ) => {
this . loading = false
} )
}
} ,
}
< / script >
2025-07-11 00:14:58 +08:00
< style lang = "scss" scoped >
2025-07-19 14:14:21 +08:00
$distance : 60 px ;
$arrowDistance : 80 px ; //margin:60+quare的padding10
$arrowColoe : # 5 ea9df ;
$lineColoe : # 5 ea9df ;
2025-07-11 00:14:58 +08:00
. ems - dashboard - editor - container {
background - color : # ffffff ;
padding : 0 ;
. container {
position : relative ;
2025-07-16 22:23:28 +08:00
overflow - x : auto ;
2025-07-11 00:14:58 +08:00
}
2025-07-19 14:14:21 +08:00
//云 、计算机 、箭头
2025-07-11 00:14:58 +08:00
. top {
2025-07-16 22:23:28 +08:00
width : 280 px ;
2025-07-11 00:14:58 +08:00
font - size : 30 px ;
line - height : 40 px ;
font - weight : 500 ;
2025-07-13 20:10:30 +08:00
display : flex ;
2025-07-16 22:23:28 +08:00
flex - direction : column ;
2025-07-13 20:10:30 +08:00
//云 样式
. cloud - container {
padding - top : 40 px ;
2025-07-16 22:23:28 +08:00
margin : 0 auto ;
2025-07-13 20:10:30 +08:00
. cloud {
width : 150 px ;
height : 60 px ;
background : # cbebfd ;
border - radius : 200 px ;
position : relative ;
text - align : center ;
color : # 666666 ;
}
. cloud : before , . cloud : after {
content : '' ;
position : absolute ;
background : # cbebfd ;
width : 80 px ;
height : 80 px ;
border - radius : 50 % ;
}
. cloud : before {
top : - 28 px ;
left : 20 px ;
}
. cloud : after {
top : - 31 px ;
right : 20 px ;
}
}
2025-07-16 22:23:28 +08:00
//双箭头
2025-07-13 20:10:30 +08:00
. double - arrows {
2025-07-19 14:14:21 +08:00
height : 50 px ;
2025-07-16 22:23:28 +08:00
margin : 20 px 0 ;
text - align : center ;
2025-07-13 20:10:30 +08:00
. top - arrows , . bottom - arrows {
2025-07-16 22:23:28 +08:00
height : 100 % ;
width : 6 px ;
2025-07-19 14:14:21 +08:00
background - color : $arrowColoe ;
2025-07-16 22:23:28 +08:00
display : inline - block ;
margin : 0 10 px ;
2025-07-13 20:10:30 +08:00
position : relative ;
2025-07-16 22:23:28 +08:00
vertical - align : super ;
2025-07-13 20:10:30 +08:00
& : : after {
content : '' ;
position : absolute ;
2025-07-16 22:23:28 +08:00
left : 0 ;
2025-07-13 20:10:30 +08:00
width : 0 ;
height : 0 ;
}
}
2025-07-16 22:23:28 +08:00
. top - arrows {
vertical - align : super ;
}
2025-07-13 20:10:30 +08:00
. top - arrows : : after {
2025-07-16 22:23:28 +08:00
bottom : - 24 px ;
border - bottom : 12 px solid transparent ;
border - left : 12 px solid transparent ;
border - right : 12 px solid transparent ;
2025-07-19 14:14:21 +08:00
border - top : 14 px solid $arrowColoe ;
2025-07-16 22:23:28 +08:00
left : - 9 px ;
2025-07-13 20:10:30 +08:00
}
. bottom - arrows {
margin - top : 12 px ;
& : : after {
2025-07-16 22:23:28 +08:00
top : - 24 px ;
border - top : 12 px solid transparent ;
border - left : 12 px solid transparent ;
border - right : 12 px solid transparent ;
2025-07-19 14:14:21 +08:00
border - bottom : 14 px solid $arrowColoe ;
2025-07-16 22:23:28 +08:00
left : - 9 px ;
2025-07-13 20:10:30 +08:00
}
}
2025-07-11 00:14:58 +08:00
}
2025-07-13 20:10:30 +08:00
//电脑
. computer {
2025-07-16 22:23:28 +08:00
margin : 20 px auto ;
2025-07-13 20:10:30 +08:00
text - align : center ;
color : # 666666 ;
position : relative ;
img {
width : auto ;
height : 100 px ;
display : block ;
}
2025-07-16 22:23:28 +08:00
}
. arrow {
2025-07-19 14:14:21 +08:00
height : 50 px ;
2025-07-16 22:23:28 +08:00
width : 30 px ;
border - radius : 5 px ;
2025-07-19 14:14:21 +08:00
background - color : $arrowColoe ;
2025-07-16 22:23:28 +08:00
position : relative ;
margin : 0 auto ;
& : : after {
content : "" ;
2025-07-13 20:10:30 +08:00
position : absolute ;
2025-07-16 22:23:28 +08:00
width : 0 ;
height : 0 ;
left : - 9 px ;
2025-07-19 14:14:21 +08:00
border - top : 24 px solid $arrowColoe ;
2025-07-16 22:23:28 +08:00
border - left : 24 px solid transparent ;
border - bottom : 24 px solid transparent ;
border - right : 24 px solid transparent ;
bottom : - 44 px ;
2025-07-13 20:10:30 +08:00
}
}
2025-07-11 00:14:58 +08:00
}
. bottom {
z - index : 1 ;
box - sizing : border - box ;
2025-07-19 14:14:21 +08:00
margin - top : 50 px ;
2025-07-13 20:10:30 +08:00
. zxlt - row {
display : flex ;
2025-07-19 14:14:21 +08:00
padding : 20 px $distance ;
2025-07-16 22:23:28 +08:00
position : relative ;
2025-07-19 15:22:26 +08:00
width : fit - content ;
2025-07-16 22:23:28 +08:00
& : before {
content : '' ;
display : block ;
2025-07-19 15:22:26 +08:00
width : calc ( 100 % - 100 px ) ;
2025-07-19 14:14:21 +08:00
height : 1 px ;
background - color : $lineColoe ;
position : absolute ;
top : 0 ;
left : $distance / 2 ;
2025-07-16 22:23:28 +08:00
}
2025-07-19 14:14:21 +08:00
. row - lists {
height : fit - content ;
position : relative ;
2025-07-16 22:23:28 +08:00
& : before {
content : '' ;
display : block ;
2025-07-19 14:14:21 +08:00
height : 100 % ;
width : 1 px ;
2025-07-16 22:23:28 +08:00
position : absolute ;
2025-07-19 14:14:21 +08:00
left : - ( $distance / 2 ) ;
top : - 20 px ;
background - color : $lineColoe ;
2025-07-16 22:23:28 +08:00
}
2025-07-19 14:14:21 +08:00
//pcs列 bms右侧的边框
& . pcs - row - lists {
2025-07-16 22:23:28 +08:00
& : after {
content : '' ;
display : block ;
2025-07-19 14:14:21 +08:00
height : 100 % ;
width : 1 px ;
2025-07-16 22:23:28 +08:00
position : absolute ;
2025-07-19 14:14:21 +08:00
right : - ( ( $distance / 2 ) + 1 ) ;
top : - 20 px ;
background - color : $lineColoe ;
2025-07-16 22:23:28 +08:00
}
}
2025-07-19 14:14:21 +08:00
& : not ( : last - child ) {
margin - right : $distance ;
2025-07-11 00:14:58 +08:00
}
2025-07-19 14:14:21 +08:00
. item - square {
//左右 两列
display : flex ;
vertical - align : middle ;
align - items : flex - start ;
padding : 10 px ;
border - radius : 5 px ;
& : not ( : last - child ) {
margin - bottom : 40 px ;
}
. row - lists - title {
font - size : 20 px ;
line - height : 20 px ;
color : # 333333 ;
font - weight : 500 ;
text - align : center ;
2025-07-19 15:22:26 +08:00
flex : 1 ;
2025-07-19 14:14:21 +08:00
}
. item - lists {
position : relative ;
& : not ( : last - child ) {
2025-07-19 15:22:26 +08:00
margin - right : $distance ;
2025-07-19 14:14:21 +08:00
}
2025-07-19 15:22:26 +08:00
//每个设备
2025-07-19 14:14:21 +08:00
. items {
background - color : # cbebfd ;
position : relative ;
border - radius : 5 px ;
padding : 10 px ;
box - shadow : 0 0 10 px rgba ( 0 , 0 , 0 , 0.1 ) , 0 0 0 rgba ( 0 , 0 , 0 , 0.5 ) ;
//普通设备 箭头方向
& . normal - items - arrow {
& : before {
content : '' ;
display : block ;
width : ( $arrowDistance / 2 ) - 15 ;
height : 4 px ;
background - color : $arrowColoe ;
position : absolute ;
top : 50 % ;
left : - ( $arrowDistance / 2 ) ;
transform : translateY ( - 50 % ) ;
}
& : after {
content : '' ;
display : block ;
height : 0 ;
width : 0 ;
border - left : 10 px solid # 5 ea9df ;
border - right : 10 px solid transparent ;
border - bottom : 10 px solid transparent ;
border - top : 10 px solid transparent ;
position : absolute ;
top : 50 % ;
left : - 15 px ;
transform : translateY ( - 50 % ) ;
}
}
//下级的箭头
& . children - items - arrow {
& : before {
content : '' ;
display : block ;
width : ( $arrowDistance / 2 ) - 15 ;
height : 4 px ;
background - color : $arrowColoe ;
position : absolute ;
top : 50 % ;
right : - ( $arrowDistance / 2 ) ;
transform : translateY ( - 50 % ) ;
}
& : after {
content : '' ;
display : block ;
height : 0 ;
width : 0 ;
border - right : 10 px solid # 5 ea9df ;
border - left : 10 px solid transparent ;
border - bottom : 10 px solid transparent ;
border - top : 10 px solid transparent ;
position : absolute ;
top : 50 % ;
right : - 15 px ;
transform : translateY ( - 50 % ) ;
}
}
& : not ( : last - child ) {
margin - bottom : 15 px ;
}
. items - inner {
background - color : # ffffff ;
border - radius : 5 px ;
padding : 10 px ;
width : 130 px ;
text - align : center ;
}
img {
width : 80 px ;
height : auto ;
display : block ;
z - index : 2 ;
margin : 0 auto ;
}
. name {
text - align : center ;
margin - top : 10 px ;
font - size : 14 px ;
line - height : 20 px ;
z - index : 2 ;
}
. status {
z - index : 2 ;
margin - top : 10 px ;
font - size : 14 px ;
line - height : 20 px ;
position : relative ;
padding - left : 20 px ;
display : inline ;
& . status - normal {
& : before {
content : "" ;
display : block ;
width : 15 px ;
height : 15 px ;
border - radius : 50 % ;
background - color : # 05 AEA3 ;
position : absolute ;
top : 50 % ;
left : 0 ;
transform : translate ( 0 , - 50 % ) ;
}
}
& . status - warn {
& : before {
content : "" ;
display : inline - block ;
width : 15 px ;
height : 15 px ;
border - radius : 50 % ;
background - color : # FC6B69 ;
position : absolute ;
top : 50 % ;
left : 0 ;
transform : translate ( 0 , - 50 % ) ;
}
}
}
2025-07-13 20:10:30 +08:00
}
}
2025-07-19 14:14:21 +08:00
. children - item - lists {
//todo 手动修改
2025-07-13 20:10:30 +08:00
& : before {
2025-07-19 14:14:21 +08:00
content : '' ;
display : block ;
width : 40 px ;
height : 4 px ;
background - color : $arrowColoe ;
2025-07-13 20:10:30 +08:00
position : absolute ;
top : 50 % ;
2025-07-19 14:14:21 +08:00
left : - 50 px ;
transform : translateY ( - 50 % ) ;
}
& : after {
content : '' ;
display : block ;
height : 0 ;
width : 0 ;
border - left : 10 px solid # 5 ea9df ;
border - right : 10 px solid transparent ;
border - bottom : 10 px solid transparent ;
border - top : 10 px solid transparent ;
position : absolute ;
top : 50 % ;
left : - 14 px ;
transform : translateY ( - 50 % ) ;
2025-07-13 20:10:30 +08:00
}
}
2025-07-11 00:14:58 +08:00
}
2025-07-19 14:14:21 +08:00
. pcs - has - children - item - square {
vertical - align : middle ;
align - items : center ;
background - color : # ffefad ;
}
2025-07-19 15:22:26 +08:00
. no - bms - list {
. item - lists {
& : not ( : last - child ) {
margin - right : 0 ;
}
}
}
2025-07-11 00:14:58 +08:00
}
}
2025-07-13 20:10:30 +08:00
2025-07-19 14:14:21 +08:00
2025-07-11 00:14:58 +08:00
}
}
< / style >
2025-07-19 14:14:21 +08:00