主线路图样式

This commit is contained in:
白菜
2025-07-19 14:14:21 +08:00
parent 658fa5042c
commit fd9caf8da6

View File

@ -20,25 +20,19 @@
<div class="bottom"> <div class="bottom">
<!-- 四列设备--> <!-- 四列设备-->
<div class="zxlt-row"> <div class="zxlt-row">
<div class="col-items" v-if="bms.length>0"> <!-- 三列 下级和上级在一列 -->
<div class="row-lists pcs-row-lists">
<div class="item-square">
<div class="row-lists-title">PCS</div>
<div class="row-lists-title">BMS</div>
</div>
<!-- 上下级块 class区分-->
<div class="item-square pcs-has-children-item-square" v-for="(item,index) in pcsHasChildren" :key="index+'pcsHasChildren'">
<!-- 左边的上级 上级只有一个-->
<div class="item-lists"> <div class="item-lists">
<div class="items-title">bms</div> <!-- 上级设备-->
<div class="items" v-for="(item,index) in bms" :key="index+'bms'"> <div class="items normal-items-arrow">
<div class="items-line"></div> <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>
</div>
</div>
<div class="col-items" v-if="pcs.length>0">
<div class="item-lists">
<div class="items-title">pcs</div>
<div class="items" v-for="(item,index) in pcs" :key="index+'pcs'">
<div class="items-line"></div>
<div style="text-align: center;margin-bottom:10px;"> <div style="text-align: center;margin-bottom:10px;">
<div class="status" :class="item.communicationStatus === '0' ?'status-normal' : 'status-warn'">通讯状态:{{communicationStatusOptions[item.communicationStatus] || '-'}}</div> <div class="status" :class="item.communicationStatus === '0' ?'status-normal' : 'status-warn'">通讯状态:{{communicationStatusOptions[item.communicationStatus] || '-'}}</div>
</div> </div>
@ -48,100 +42,112 @@
</div> </div>
</div> </div>
</div> </div>
<div class="col-items" v-if="db.length>0"> <!-- 右边的下级 下级有多个-->
<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>
</div>
</div>
</div>
<div class="item-square">
<!-- 左边没有下级的pcs-->
<div class="item-lists"> <div class="item-lists">
<div class="items-title">电表</div> <div class="items normal-items-arrow" v-for="item in pcsNoChildren" :key="item.deviceId">
<div class="items" v-for="(item,index) in db" :key="index+'db'"> <div class="items-inner">
<div class="items-line"></div>
<div style="text-align: center;margin-bottom:10px;"> <div style="text-align: center;margin-bottom:10px;">
<div class="status" :class="item.communicationStatus === '0' ?'status-normal' : 'status-warn'">通讯状态:{{communicationStatusOptions[item.communicationStatus] || '-'}}</div> <div class="status" :class="item.communicationStatus === '0' ?'status-normal' : 'status-warn'">通讯状态:{{communicationStatusOptions[item.communicationStatus] || '-'}}</div>
</div> </div>
<img v-if="item.pictureUrl" :src="item.pictureUrl"> <img v-if="item.pictureUrl" :src="item.pictureUrl">
<img v-else :src="require('@/assets/images/ems/db.png')"/> <img v-else :src="require('@/assets/images/ems/pcs.png')"/>
<div class="name">{{item.deviceName}}</div> <div class="name">{{item.deviceName}}</div>
</div> </div>
</div> </div>
</div> </div>
<div class="col-items" v-if="lq.length>0"> <!-- 右边没有上级的bms-->
<div class="item-lists"> <div class="item-lists">
<div class="items-title">冷却</div> <!-- 下级设备 循环生成-->
<div class="items" v-for="(item,index) in lq" :key="index+'lq'"> <div class="items children-items-arrow" v-for="item in bms" :key="item.deviceId">
<div class="items-line"></div> <div class="items-inner">
<div style="text-align: center;margin-bottom:10px;"> <div style="text-align: center;margin-bottom:10px;">
<div class="status" :class="item.communicationStatus === '0' ?'status-normal' : 'status-warn'">通讯状态:{{communicationStatusOptions[item.communicationStatus] || '-'}}</div> <div class="status" :class="item.communicationStatus === '0' ?'status-normal' : 'status-warn'">通讯状态:{{communicationStatusOptions[item.communicationStatus] || '-'}}</div>
</div> </div>
<img v-if="item.pictureUrl" :src="item.pictureUrl"> <img v-if="item.pictureUrl" :src="item.pictureUrl">
<img v-else :src="require('@/assets/images/ems/lq.png')"/> <img v-else :src="require('@/assets/images/ems/bms.png')"/>
<div class="name">{{item.deviceName}}</div> <div class="name">{{item.deviceName}}</div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div>
<!-- -->
<div class="row-lists">
<div class="item-square">
<div class="row-lists-title" style="width:100%;">电表</div>
</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>
</div>
</div>
</div>
</div>
<div class="row-lists">
<div class="item-square">
<div class="row-lists-title" style="width:100%;">冷却</div>
</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>
</div>
</div>
</div>
</div>
</div>
</div> </div>
</div> </div>
<el-empty v-show="empty" :image-size="200"></el-empty> <el-empty v-show="empty" :image-size="200"></el-empty>
</div> </div>
</template> </template>
<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:[]
}
},
computed:{
...mapState({
communicationStatusOptions:(state)=>state.ems.communicationStatusOptions
}),
empty(){
const {pcs = [], bms = [], db = [], lq = []} =this
return pcs.length === 0 && bms.length === 0 && db.length === 0 && lq.length === 0
}
},
methods: {
init(){
this.pcs = []
this.bms = []
this.lq=[]
this.db=[]
this.loading = true
getDeviceList(this.siteId).then(response => {
const data =JSON.parse(JSON.stringify(response?.data || []))
const pcs = [],bms=[],db=[],lq=[]
data.forEach(item=>{
if(item.deviceCategory === 'AMMETER'){
db.push(item)
}else if(item.deviceCategory === 'PCS'){
pcs.push(item)
}else if(item.deviceCategory === 'STACK'){
bms.push(item)
}else if(item.deviceCategory === 'COOLING'){
lq.push(item)
}
})
this.pcs = pcs
this.bms = bms
this.lq=lq
this.db=db
}).finally(() => {
this.loading = false
})
}
},
}
</script>
<style lang="scss" scoped> <style lang="scss" scoped>
$distance:60px;
$arrowDistance:80px;//margin:60+quare的padding10
$arrowColoe:#5ea9df;
$lineColoe:#5ea9df;
.ems-dashboard-editor-container { .ems-dashboard-editor-container {
background-color: #ffffff; background-color: #ffffff;
padding:0; padding:0;
@ -149,6 +155,7 @@ export default {
position: relative; position: relative;
overflow-x: auto; overflow-x: auto;
} }
//云 、计算机 、箭头
.top{ .top{
width: 280px; width: 280px;
font-size: 30px; font-size: 30px;
@ -188,13 +195,13 @@ export default {
} }
//双箭头 //双箭头
.double-arrows { .double-arrows {
height: 95px; height: 50px;
margin:20px 0; margin:20px 0;
text-align: center; text-align: center;
.top-arrows,.bottom-arrows{ .top-arrows,.bottom-arrows{
height: 100%; height: 100%;
width: 6px; width: 6px;
background-color: #5ea9df; background-color: $arrowColoe;
display: inline-block; display: inline-block;
margin: 0 10px; margin: 0 10px;
position: relative; position: relative;
@ -216,7 +223,7 @@ export default {
border-bottom: 12px solid transparent; border-bottom: 12px solid transparent;
border-left: 12px solid transparent; border-left: 12px solid transparent;
border-right: 12px solid transparent; border-right: 12px solid transparent;
border-top: 14px solid #5ea9df; border-top: 14px solid $arrowColoe;
left: -9px; left: -9px;
} }
.bottom-arrows{ .bottom-arrows{
@ -226,7 +233,7 @@ export default {
border-top: 12px solid transparent; border-top: 12px solid transparent;
border-left: 12px solid transparent; border-left: 12px solid transparent;
border-right: 12px solid transparent; border-right: 12px solid transparent;
border-bottom: 14px solid #5ea9df; border-bottom: 14px solid $arrowColoe;
left: -9px; left: -9px;
} }
} }
@ -246,10 +253,10 @@ export default {
} }
} }
.arrow{ .arrow{
height: 95px; height: 50px;
width: 30px; width: 30px;
border-radius: 5px; border-radius: 5px;
background-color: #5ea9df; background-color: $arrowColoe;
position: relative; position: relative;
margin:0 auto; margin:0 auto;
&::after{ &::after{
@ -258,7 +265,7 @@ export default {
width: 0; width: 0;
height: 0; height: 0;
left: -9px; left: -9px;
border-top: 24px solid #5ea9df; border-top: 24px solid $arrowColoe;
border-left: 24px solid transparent; border-left: 24px solid transparent;
border-bottom: 24px solid transparent; border-bottom: 24px solid transparent;
border-right: 24px solid transparent; border-right: 24px solid transparent;
@ -270,76 +277,121 @@ export default {
.bottom{ .bottom{
z-index:1; z-index:1;
box-sizing: border-box; box-sizing: border-box;
margin-top:100px; margin-top:50px;
.zxlt-row{ .zxlt-row{
display: flex; display: flex;
} padding:20px $distance;
.col-items{
padding-right: 120px;
position: relative; position: relative;
&:before{ &:before{
content: ''; content: '';
display: block; display: block;
height: 2px; width:calc(100% - 120px);
width: 100%; height:1px;
background-color: #5ea9df; background-color: $lineColoe;
position:absolute; position:absolute;
top: -50px;//高出的50px top:0;
left: 0; left: $distance/2;
} }
&:last-child{ .row-lists{
margin-bottom: 0; height: fit-content;
&:before{
content: '';
display: block;
height: 2px;
width: calc(100% - 60px);
background-color: #5ea9df;
position: absolute;
top: -50px;//高出的50px
left: 0;
}
}
}
.item-lists{
position: relative; position: relative;
padding:25px;
background-color: #cbebfd;//#ffdc70;
border-radius: 10px;
&:before{ &:before{
content: ''; content: '';
display: block; display: block;
height: calc(100% + 50px); height: 100%;
width: 2px; width: 1px;
background-color: #5ea9df;
position: absolute; position: absolute;
top: -50px;//高出的50px left:-($distance/2);
right: -60px; top:-20px;
background-color: $lineColoe;
} }
//pcs列 bms右侧的边框
.items-title{ &.pcs-row-lists{
&:after{
content: '';
display: block;
height: 100%;
width: 1px;
position: absolute;
right:-(($distance/2) + 1);
top:-20px;
background-color: $lineColoe;
}
}
&:not(:last-child){
margin-right: $distance;
}
.item-square{
//左右 两列
display: flex;
vertical-align: middle;
align-items: flex-start;
padding:10px;
border-radius: 5px;
&:not(:last-child){
margin-bottom: 40px;
}
.row-lists-title{
font-size: 20px; font-size: 20px;
line-height: 30px; line-height: 20px;
color: #333333; color: #333333;
font-weight: 500; font-weight: 500;
text-align: center; text-align: center;
margin-bottom:20px; width: 50%;
} }
.item-lists{
position: relative;
&:not(:last-child){
margin-right: $distance;
}
//每个设备
.items{ .items{
background-color: #ffffff; background-color: #cbebfd;
position: relative; position: relative;
border-radius: 5px; border-radius: 5px;
padding: 20px 25px; padding: 10px;
margin-bottom: 20px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1), 0 0 0 rgba(0, 0, 0, 0.5); box-shadow: 0 0 10px rgba(0, 0, 0, 0.1), 0 0 0 rgba(0, 0, 0, 0.5);
.items-line{ //普通设备 箭头方向
&.normal-items-arrow{
&:before{
content: '';
display: block;
width:($arrowDistance/2) - 15;
height: 4px; height: 4px;
width: 66px; background-color: $arrowColoe;
background-color: #5ea9df;
position: absolute; position: absolute;
top:50%; top:50%;
right: -85px;//60+25 left: -($arrowDistance/2);
transform: translateY(-50%);
}
&:after{
content: '';
display: block;
height: 0;
width: 0;
border-left: 10px solid #5ea9df;
border-right: 10px solid transparent;
border-bottom: 10px solid transparent;
border-top: 10px solid transparent;
position: absolute;
top: 50%;
left: -15px;
transform: translateY(-50%);
}
}
//下级的箭头
&.children-items-arrow{
&:before{
content: '';
display: block;
width:($arrowDistance/2) - 15;
height: 4px;
background-color: $arrowColoe;
position: absolute;
top:50%;
right: -($arrowDistance/2);
transform: translateY(-50%);
}
&:after{ &:after{
content: ''; content: '';
display: block; display: block;
@ -350,16 +402,29 @@ export default {
border-bottom: 10px solid transparent; border-bottom: 10px solid transparent;
border-top: 10px solid transparent; border-top: 10px solid transparent;
position: absolute; position: absolute;
top: -8px; top: 50%;
left: -20px; right: -15px;
transform: translateY(-50%);
} }
} }
&:not(:last-child){
margin-bottom: 15px;
}
.items-inner{
background-color: #ffffff;
border-radius: 5px;
padding:10px;
width:130px;
text-align: center;
}
img{ img{
width: 120px; width: 80px;
height: auto; height: auto;
display: block; display: block;
z-index:2; z-index:2;
margin: 0 auto;
} }
.name{ .name{
text-align: center; text-align: center;
@ -407,7 +472,135 @@ export default {
} }
} }
} }
.children-item-lists{
//todo 手动修改
&:before{
content: '';
display: block;
width:40px;
height: 4px;
background-color: $arrowColoe;
position: absolute;
top:50%;
left: -50px;
transform:translateY(-50%);
}
&:after{
content: '';
display: block;
height: 0;
width: 0;
border-left: 10px solid #5ea9df;
border-right: 10px solid transparent;
border-bottom: 10px solid transparent;
border-top: 10px solid transparent;
position: absolute;
top: 50%;
left: -14px;
transform:translateY(-50%);
}
}
}
.pcs-has-children-item-square{
vertical-align: middle;
align-items: center;
background-color: #ffefad;
}
}
}
} }
} }
</style> </style>
<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:[],
list:{
pcs :[],
bms:[],
db:[],
lq:[],
}
}
},
computed:{
...mapState({
communicationStatusOptions:(state)=>state.ems.communicationStatusOptions
}),
empty(){
const {pcs = [], bms = [], db = [], lq = []} =this
return pcs.length === 0 && bms.length === 0 && db.length === 0 && lq.length === 0
}
},
methods: {
init(){
this.pcs = []
this.bms = []
this.lq=[]
this.db=[]
this.loading = true
getDeviceList(this.siteId).then(response => {
const data =JSON.parse(JSON.stringify(response?.data || []))
const pcs = [],bms=[],db=[],lq=[]
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){
//todo 删除第二个children
pcs.find(pcsItem=>pcsItem.deviceId === item.parentId).children.push(item)
pcs.find(pcsItem=>pcsItem.deviceId === item.parentId).children.push(item)
bms.splice(index,1)
}
})
// todo
// delete
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.list={
pcs,
bms,
lq,
db
}
}).finally(() => {
this.loading = false
})
}
},
}
</script>