pcs、bms接口联调

This commit is contained in:
白菜
2025-06-28 14:52:49 +08:00
parent 13310948c3
commit d0d4c25377
15 changed files with 455 additions and 306 deletions

View File

@ -7,3 +7,50 @@ export function getDzjkHomeView(siteId) {
method: 'get' method: 'get'
}) })
} }
//获取pcs、实时运行头部的设备信息
export function getRunningHeadInfo(siteId) {
return request({
url: `/ems/siteMonitor/runningHeadInfo?siteId=${siteId}`,
method: 'get'
})
}
//获取pcs列表
export function getPcsDetailInfo(siteId) {
return request({
url: `/ems/siteMonitor/getPcsDetailInfo?siteId=${siteId}`,
method: 'get'
})
}
//获取BMS总览数据
export function getBMSOverView(siteId) {
return request({
url: `/ems/siteMonitor/getBMSOverView?siteId=${siteId}`,
method: 'get'
})
}
//获取BMS电池簇总览数据
export function getBMSBatteryCluster(siteId) {
return request({
url: `/ems/siteMonitor/getBMSBatteryCluster?siteId=${siteId}`,
method: 'get'
})
}
//获取单体电池 电池堆列表数据
export function getStackNameList(siteId) {
return request({
url: `/ems/siteMonitor/getStackNameList?siteId=${siteId}`,
method: 'get'
})
}
//获取单体电池 电池簇列表数据
export function getClusterNameList(stackDeviceId) {
return request({
url: `/ems/siteMonitor/getClusterNameList?stackDeviceId=${stackDeviceId}`,
method: 'get'
})
}

View File

@ -2,7 +2,7 @@
<template> <template>
<el-card shadow="always" class="single-square-box" :style="{background: 'linear-gradient(180deg, '+data.bgColor+' 0%,rgba(255,255,255,0) 100%)'}"> <el-card shadow="always" class="single-square-box" :style="{background: 'linear-gradient(180deg, '+data.bgColor+' 0%,rgba(255,255,255,0) 100%)'}">
<div class="single-square-box-title">{{ data.title }}</div> <div class="single-square-box-title">{{ data.title }}</div>
<div class="single-square-box-value">{{ data.value }}</div> <div class="single-square-box-value">{{ data.value | formatNumber }}</div>
</el-card> </el-card>
</template> </template>

View File

@ -56,7 +56,7 @@ export default {
mounted() { mounted() {
getSiteTotalInfo().then(response => { getSiteTotalInfo().then(response => {
console.log('单个站点基本信息返回数据',response) console.log('单个站点基本信息返回数据',response)
this.setData(response.data || {}) this.setData(response?.data || {})
}).catch(()=>{ }).catch(()=>{
this.setData({}) this.setData({})
}) })

6
src/filters/ems.js Normal file
View File

@ -0,0 +1,6 @@
export const formatNumber = (val) => {
if(val || [0,'0'].includes(val)) {
return val
}else {return '-'}
}

View File

@ -36,6 +36,8 @@ import DictTag from '@/components/DictTag'
// 字典数据组件 // 字典数据组件
import DictData from '@/components/DictData' import DictData from '@/components/DictData'
import {formatNumber} from '@/filters/ems'
// 全局方法挂载 // 全局方法挂载
Vue.prototype.getDicts = getDicts Vue.prototype.getDicts = getDicts
Vue.prototype.getConfigKey = getConfigKey Vue.prototype.getConfigKey = getConfigKey
@ -74,7 +76,7 @@ Vue.use(Element, {
}) })
Vue.config.productionTip = false Vue.config.productionTip = false
Vue.filter('formatNumber', formatNumber)
new Vue({ new Vue({
el: '#app', el: '#app',
router, router,

View File

@ -0,0 +1,25 @@
// 用于单站监控二级菜单页面获取路由中的站点ID
const getQuerySiteId= {
data: function () {
return {
siteId:''
}
},
watch: {
'$route.query':{
handler (newQuery,oldQuery) {
// 参数变化处理
this.$nextTick(() => {
const {siteId} =newQuery
if(siteId){
this.siteId = siteId
siteId && this.init(newQuery.siteId)
console.log('mixin=>getQuerySiteId=>页面参数siteId发生了变化,this.siteId=',this.siteId)
}
})
},
immediate: true,
}
},
}
export default getQuerySiteId

View File

@ -36,7 +36,7 @@ export default {
this.chart = null this.chart = null
}, },
methods: { methods: {
initChart(data) { initChart() {
this.chart = echarts.init(document.querySelector('#nllzChart')) this.chart = echarts.init(document.querySelector('#nllzChart'))
}, },
setOption(data) { setOption(data) {
@ -129,6 +129,7 @@ export default {
}, },
dataset:{ dataset:{
source source
// source: [['日期','充电量','放电量']]
}, },
series: [ series: [
{ {

View File

@ -1,5 +1,5 @@
<template> <template>
<div> <div v-loading="loading">
<el-row :gutter="32" style="background:#fff;"> <el-row :gutter="32" style="background:#fff;">
<el-col :xs="24" :sm="24" :lg="10"> <el-col :xs="24" :sm="24" :lg="10">
<el-card shadow="always" class="common-card-container common-card-container-body-no-padding"> <el-card shadow="always" class="common-card-container common-card-container-body-no-padding">
@ -57,24 +57,19 @@
<script> <script>
import {getDzjkHomeView} from '@/api/ems/dzjk' import {getDzjkHomeView} from '@/api/ems/dzjk'
import NllzChart from "./NllzChart.vue"; import NllzChart from "./NllzChart.vue";
import getQuerySiteId from '@/mixins/ems/getQuerySiteId'
export default { export default {
name:'DzjkSbjkHome', name:'DzjkSbjkHome',
components: {NllzChart}, computed: {
watch: { loader() {
'$route.query':{ return loader
handler (newQuery,oldQuery) {
// 参数变化处理
console.log('单站监控=>首页=>页面地址发生变化',newQuery,oldQuery)
this.$nextTick(() => {
const {siteId} =newQuery
siteId && this.getData(newQuery.siteId)
})
},
immediate: true,
} }
}, },
components: {NllzChart},
mixins: [getQuerySiteId],
data() { data() {
return { return {
loading:false,
sjglData:[{ sjglData:[{
title:'今日充电量MWh', title:'今日充电量MWh',
value:'', value:'',
@ -97,15 +92,16 @@ export default {
} }
}, },
methods:{ methods:{
getData(siteId){ init(){
getDzjkHomeView(siteId).then(response => { this.loading = true
const data = response.data || {} getDzjkHomeView(this.siteId).then(response => {
const data = response?.data || {}
this.sjglData.forEach(item=>{ this.sjglData.forEach(item=>{
item.value = (data[item.attr] || data[item.attr] === 0) ? data[item.attr] : '-' item.value = (data[item.attr] || data[item.attr] === 0) ? data[item.attr] : '-'
}) })
this.tableData = data?.siteMonitorHomeAlarmVo || [] this.tableData = data?.siteMonitorHomeAlarmVo || []
this.$refs.nllzChart.setOption(data) this.$refs.nllzChart.setOption(data)
}) }).finally(() => {this.loading = false})
} }
}, },
} }

View File

@ -3,7 +3,7 @@
<!-- 6个方块--> <!-- 6个方块-->
<el-row :gutter="10"> <el-row :gutter="10">
<el-col :xs="12" :sm="8" :lg="4" class="single-square-box-container" v-for="(item,index) in singleZdSqaure" :key="index+'singleSquareBox'"> <el-col :xs="12" :sm="8" :lg="4" class="single-square-box-container" v-for="(item,index) in singleZdSqaure" :key="index+'singleSquareBox'">
<single-square-box :data="item"></single-square-box> <single-square-box :data="{...item,value:Object.values(data).length ? data[item.attr] || '-' : '-'}" ></single-square-box>
</el-col> </el-col>
</el-row> </el-row>
</template> </template>
@ -14,33 +14,46 @@ import SingleSquareBox from "@/components/Ems/SingleSquareBox/index.vue";
export default { export default {
components:{SingleSquareBox}, components:{SingleSquareBox},
props:{
data:{
type:Object,
required:false,
default:()=>{return {}}
},
},
data() { data() {
return { return {
// 单个电站 四个方块数据 // 单个电站 四个方块数据
singleZdSqaure:[{ singleZdSqaure:[{
title:'实时有功功率kW', title:'实时有功功率kW',
value:'22.74', value:'',
bgColor:'#FFF2CB' bgColor:'#FFF2CB',
attr:'totalActivePower'
},{ },{
title:'实时无功功率kVar', title:'实时无功功率kVar',
value:'22.74', value:'',
bgColor:'#CBD6FF' bgColor:'#CBD6FF',
attr:'totalReactivePower'
},{ },{
title:'电池催SOC', title:'电池催SOC',
value:'22.74', value:'',
bgColor:'#DCCBFF' bgColor:'#DCCBFF',
attr:'soc'
},{ },{
title:'电池堆SOH', title:'电池堆SOH',
value:'22.74', value:'',
bgColor:'#FFD4CB' bgColor:'#FFD4CB',
attr:'soh'
},{ },{
title:'今日充电量kWh', title:'今日充电量kWh',
value:'22.74', value:'',
bgColor:'#FFD6F8' bgColor:'#FFD6F8',
attr:'dayChargedCap'
},{ },{
title:'今日放电量kWh', title:'今日放电量kWh',
value:'22.74', value:'',
bgColor:'#E1FFCA' bgColor:'#E1FFCA',
attr:'dayDisChargedCap'
}] }]
} }
}, },

View File

@ -1,94 +1,109 @@
<template> <template>
<div> <div v-loading="loading">
<div v-for="(baseInfo,index) in baseInfoList" :key="index+'bmsdccContainer'" style="margin-bottom:25px;">
<el-card shadow="always" class="common-card-container common-card-container-body-no-padding common-card-container-no-title-bg"> <el-card shadow="always" class="common-card-container common-card-container-body-no-padding common-card-container-no-title-bg">
<div slot="header"> <div slot="header">
<span class="large-title">1#电池簇</span> <span class="large-title">{{index+1}}#{{baseInfo.deviceName}}</span>
</div> </div>
<div class="descriptions-main"> <div class="descriptions-main">
<el-descriptions direction="vertical" :column="3" :colon="false"> <el-descriptions direction="vertical" :column="3" :colon="false">
<el-descriptions-item labelClassName="descriptions-label" contentClassName="descriptions-direction keep" :span="1" label="工作状态" >放电</el-descriptions-item> <el-descriptions-item labelClassName="descriptions-label" contentClassName="descriptions-direction keep" :span="1" label="工作状态" >{{baseInfo.workStatus}}</el-descriptions-item>
<el-descriptions-item labelClassName="descriptions-label" contentClassName="descriptions-direction" :span="1" label="与PCS通信">正常</el-descriptions-item> <el-descriptions-item labelClassName="descriptions-label" contentClassName="descriptions-direction" :span="1" label="与PCS通信">{{baseInfo.pcsCommunicationStatus}}</el-descriptions-item>
<el-descriptions-item labelClassName="descriptions-label" contentClassName="descriptions-direction" :span="1" label="与EMS通信">正常</el-descriptions-item> <el-descriptions-item labelClassName="descriptions-label" contentClassName="descriptions-direction" :span="1" label="与EMS通信">{{baseInfo.emsCommunicationStatus}}</el-descriptions-item>
</el-descriptions> </el-descriptions>
</div> </div>
<div class="descriptions-main descriptions-main-bg-color"> <div class="descriptions-main descriptions-main-bg-color">
<el-descriptions direction="vertical" :column="3" :colon="false"> <el-descriptions direction="vertical" :column="3" :colon="false">
<el-descriptions-item labelClassName="descriptions-label" contentClassName="descriptions-direction" v-for="(item,index) in infoData" :key="index+'pcsInfoData'" :span="1" :label="item.label">{{item.value}} <span v-if="item.unit" v-html="item.unit"></span></el-descriptions-item> <el-descriptions-item labelClassName="descriptions-label" contentClassName="descriptions-direction" v-for="(item,index) in infoData" :key="index+'pcsInfoData'" :span="1" :label="item.label">{{baseInfo[item.attr] | formatNumber}} <span v-if="item.unit" v-html="item.unit"></span></el-descriptions-item>
</el-descriptions> </el-descriptions>
<!-- 进度--> <!-- 进度-->
<div class="process-container"> <div class="process-container">
<div class="process-line-bg"> <div class="process-line-bg">
<div class="process-line"></div> <div class="process-line":style="{height:baseInfo.currentSoc+'%'}"></div>
</div> </div>
<div class="process">当前SOC : 25%</div> <div class="process">当前SOC : {{baseInfo.currentSoc}}%</div>
</div> </div>
</div> </div>
</el-card>
<el-table <el-table
class="common-table" class="common-table"
:data="tableData" :data="baseInfo.batteryDataList"
stripe stripe
style="width: 100%;margin-top:25px;"> style="width: 100%;margin-top:25px;">
<el-table-column <el-table-column
prop="" prop="dataName"
label="名称"> label="名称">
<template slot-scope="scope"> <template slot-scope="scope">
<span v-html="scope.row.name"></span> <span v-html="scope.row.dataName+''+unitObj[scope.row.dataName]+''"></span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column
prop="average" prop="avgData"
label="单体平均值" label="单体平均值"
> >
</el-table-column> </el-table-column>
<el-table-column <el-table-column
prop="min" prop="minData"
label="单体最小值"> label="单体最小值">
</el-table-column> </el-table-column>
<el-table-column <el-table-column
prop="minID" prop="minDataID"
label="单体最小值ID"> label="单体最小值ID">
</el-table-column> </el-table-column>
<el-table-column <el-table-column
prop="max" prop="maxData"
label="单体最大值"> label="单体最大值">
</el-table-column> </el-table-column>
<el-table-column <el-table-column
prop="maxID" prop="maxDataID"
label="单体最大值ID"> label="单体最大值ID">
</el-table-column> </el-table-column>
</el-table> </el-table>
</el-card>
</div> </div>
<el-empty v-show="baseInfoList.length<=0" :image-size="200"></el-empty>
</div>
</template> </template>
<script> <script>
import {getBMSBatteryCluster} from '@/api/ems/dzjk'
import getQuerySiteId from "@/mixins/ems/getQuerySiteId";
export default { export default {
name:'DzjkSbjkBmsdcc', name:'DzjkSbjkBmsdcc',
mixins:[getQuerySiteId],
components:{}, components:{},
data() { data() {
return { return {
loading:false,
unitObj:{
'电压':'V',
'温度':'&#8451;',
'SOC':'%'
},
baseInfoList:[],
infoData:[ infoData:[
{label:'簇电压',value:'742',attr:'',unit:'V'}, {label:'簇电压',attr:'clusterVoltage',unit:'V'},
{label:'可充电量',value:'100',attr:'',unit:'kWh'}, {label:'可充电量',attr:'chargeableCapacity',unit:'kWh'},
{label:'累计充电量',value:'100',attr:'',unit:'kWh'}, {label:'累计充电量',attr:'totalChargedCapacity',unit:'kWh'},
{label:'簇电流',value:'12.7',attr:'',unit:'A'}, {label:'簇电流',attr:'clusterCurrent',unit:'A'},
{label:'可放电量',value:'300',attr:'',unit:'kWh'}, {label:'可放电量',attr:'dischargeableCapacity',unit:'kWh'},
{label:'累计放电量',value:'300',attr:'',unit:'kWh'}, {label:'累计放电量',attr:'totalDischargedCapacity',unit:'kWh'},
{label:'SOH',value:'98',attr:'',unit:'%'}, {label:'SOH',attr:'soh',unit:'%'},
{label:'平均温度',value:'11',attr:'',unit:'&#8451;'}, {label:'平均温度',attr:'averageTemperature',unit:'&#8451;'},
{label:'绝缘电阻',value:'2000',attr:'',unit:'&Omega;'}, {label:'绝缘电阻',attr:'insulationResistance',unit:'&Omega;'},
], ],
tableData:[
{name:'电压V',average:'20',min:10,minID:'1',max:'30',maxID:'2'},
{name:'温度(&#8451;',average:'20',min:10,minID:'1',max:'30',maxID:'2'},
{name:'SOC%',average:'20',min:10,minID:'1',max:'30',maxID:'2'},
]
} }
}, },
methods:{
init(){
this.loading = true
getBMSBatteryCluster(this.siteId).then(response => {
this.baseInfoList = JSON.parse(JSON.stringify(response?.data || []));
}).finally(() => {this.loading = false})
}
}
} }
</script> </script>

View File

@ -1,58 +1,57 @@
<template> <template>
<div> <div v-loading="loading">
<div v-for="(baseInfo,index) in baseInfoList" :key="index+'bmszlContainer'" style="margin-bottom:25px;">
<el-card shadow="always" class="common-card-container common-card-container-body-no-padding common-card-container-no-title-bg"> <el-card shadow="always" class="common-card-container common-card-container-body-no-padding common-card-container-no-title-bg">
<div slot="header"> <div slot="header">
<span class="large-title">电池堆一</span> <span class="large-title">{{index+1}}#{{baseInfo.deviceName}}</span>
</div> </div>
<div class="descriptions-main"> <div class="descriptions-main">
<el-descriptions direction="vertical" :column="3" :colon="false"> <el-descriptions direction="vertical" :column="3" :colon="false">
<el-descriptions-item labelClassName="descriptions-label" contentClassName="descriptions-direction keep" :span="1" label="工作状态" >放电</el-descriptions-item> <el-descriptions-item labelClassName="descriptions-label" contentClassName="descriptions-direction keep" :span="1" label="工作状态" >{{baseInfo.workStatus}}</el-descriptions-item>
<el-descriptions-item labelClassName="descriptions-label" contentClassName="descriptions-direction" :span="1" label="与PCS通信">正常</el-descriptions-item> <el-descriptions-item labelClassName="descriptions-label" contentClassName="descriptions-direction" :span="1" label="与PCS通信">{{baseInfo.pcsCommunicationStatus}}</el-descriptions-item>
<el-descriptions-item labelClassName="descriptions-label" contentClassName="descriptions-direction" :span="1" label="与EMS通信">正常</el-descriptions-item> <el-descriptions-item labelClassName="descriptions-label" contentClassName="descriptions-direction" :span="1" label="与EMS通信">{{baseInfo.emsCommunicationStatus}}</el-descriptions-item>
</el-descriptions> </el-descriptions>
</div> </div>
<div class="descriptions-main descriptions-main-bg-color"> <div class="descriptions-main descriptions-main-bg-color">
<el-descriptions direction="vertical" :column="3" :colon="false"> <el-descriptions direction="vertical" :column="3" :colon="false">
<el-descriptions-item labelClassName="descriptions-label" contentClassName="descriptions-direction" v-for="(item,index) in infoData" :key="index+'pcsInfoData'" :span="1" :label="item.label">{{item.value}} <span v-if="item.unit" v-html="item.unit"></span></el-descriptions-item> <el-descriptions-item labelClassName="descriptions-label" contentClassName="descriptions-direction" v-for="(item,index) in infoData" :key="index+'pcsInfoData'" :span="1" :label="item.label">{{baseInfo[item.attr] | formatNumber}} <span v-if="item.unit" v-html="item.unit"></span></el-descriptions-item>
</el-descriptions> </el-descriptions>
<!-- 进度--> <!-- 进度-->
<div class="process-container"> <div class="process-container">
<div class="process-line-bg"> <div class="process-line-bg">
<div class="process-line"></div> <div class="process-line" :style="{height:baseInfo.currentSoc+'%'}"></div>
</div> </div>
<div class="process">当前SOC : 25%</div> <div class="process">当前SOC : {{baseInfo.currentSoc}}%</div>
</div> </div>
</div> </div>
</el-card>
<el-table <el-table
class="common-table" class="common-table"
:data="tableData" :data="baseInfo.batteryDataList"
stripe stripe
max-height="500" max-height="500"
style="width: 100%;margin-top:25px;"> style="width: 100%;margin-top:25px;">
<el-table-column <el-table-column
prop="name" prop="clusterId"
width="190"
label="簇号"> label="簇号">
</el-table-column> </el-table-column>
<el-table-column <el-table-column
label="簇电压" label="簇电压"
> >
<template slot-scope="scope"> <template slot-scope="scope">
<span>{{scope.row.voltage}} V</span> <span>{{scope.row.clusterVoltage}} V</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column
label="簇电流"> label="簇电流">
<template slot-scope="scope"> <template slot-scope="scope">
<span>{{scope.row.electric}} A</span> <span>{{scope.row.clusterCurrent}} A</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column
label="簇SOC"> label="簇SOC">
<template slot-scope="scope"> <template slot-scope="scope">
<span>{{scope.row.soc}} %</span> <span>{{scope.row.currentSoc}} %</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column
@ -84,41 +83,44 @@
</el-table-column> </el-table-column>
</el-table> </el-table>
</el-card>
</div>
<el-empty v-show="baseInfoList.length<=0" :image-size="200"></el-empty>
</div> </div>
</template> </template>
<script> <script>
import {getBMSOverView} from '@/api/ems/dzjk'
import getQuerySiteId from "@/mixins/ems/getQuerySiteId";
export default { export default {
name:'DzjkSbjkBmszl', name:'DzjkSbjkBmszl',
components:{}, mixins:[getQuerySiteId],
data() { data() {
return { return {
statusData:[ loading:false,
{label:'工作状态',value:'',attr:''}, baseInfoList:[],
{label:'与PCS通信',value:'',attr:''},
{label:'与EMS通信',value:'',attr:''},
],
infoData:[ infoData:[
{label:'电池堆总电压',value:'742',attr:'',unit:'V'}, {label:'电池堆总电压',attr:'totalVoltage',unit:'V'},
{label:'可充电量',value:'100',attr:'',unit:'kWh'}, {label:'可充电量',attr:'chargeableCapacity',unit:'kWh'},
{label:'累计充电量',value:'100',attr:'',unit:'kWh'}, {label:'累计充电量',attr:'totalChargedCapacity',unit:'kWh'},
{label:'电池堆总电流',value:'-12.7',attr:'',unit:'A'}, {label:'电池堆总电流',attr:'totalCurrent',unit:'A'},
{label:'可放电量',value:'300',attr:'',unit:'kWh'}, {label:'可放电量',attr:'dischargeableCapacity',unit:'kWh'},
{label:'累计放电量',value:'300',attr:'',unit:'kWh'}, {label:'累计放电量',attr:'totalDischargedCapacity',unit:'kWh'},
{label:'SOH',value:'99',attr:'',unit:'%'}, {label:'SOH',attr:'soh',unit:'%'},
{label:'平均温度',value:'20',attr:'',unit:'&#8451;'}, {label:'平均温度',attr:'averageTemperature',unit:'&#8451;'},
{label:'绝缘电阻',value:'1000',attr:'',unit:'&Omega;'}, {label:'绝缘电阻',attr:'insulationResistance',unit:'&Omega;'},
],
tableData:[
{name:'1#电池堆-1#电池簇',voltage:'742.8',electric:'-4.4',soc:'98',maxVoltage:'3.301',minVoltage:'3.102',maxTemperature:'12.8',minTemperature:'11.3'},
{name:'1#电池堆-2#电池簇',voltage:'790.1',electric:'-4.2',soc:'90',maxVoltage:'3.391',minVoltage:'3.192',maxTemperature:'13.5',minTemperature:'11.4'},
{name:'1#电池堆-3#电池簇',voltage:'740.3',electric:'-4.5',soc:'94',maxVoltage:'3.101',minVoltage:'3.198',maxTemperature:'10.9',minTemperature:'11.5'},
{name:'1#电池堆-4#电池簇',voltage:'744.9',electric:'-4.5',soc:'99',maxVoltage:'3.221',minVoltage:'3.234',maxTemperature:'11.4',minTemperature:'11.6'},
] ]
} }
}, },
methods:{
init(){
this.loading=true;
getBMSOverView(this.siteId).then(response => {
this.baseInfoList = JSON.parse(JSON.stringify(response?.data || []));
}).finally(() => {this.loading = false})
}
}
} }
</script> </script>
@ -152,7 +154,7 @@ export default {
left: 0; left: 0;
bottom: 0; bottom: 0;
width: 100%; width: 100%;
height: 25%; height: 0;
background-color: #fc6c6c; background-color: #fc6c6c;
border-radius: 0 0 6px 6px; border-radius: 0 0 6px 6px;
box-shadow: 0 0 10px rgb(252 108 108), 0 0 0 rgba(252, 108, 108, 0.5); box-shadow: 0 0 10px rgb(252 108 108), 0 0 0 rgba(252, 108, 108, 0.5);

View File

@ -27,10 +27,11 @@ export default {
this.chart = echarts.init(document.querySelector('#dtdcChart')) this.chart = echarts.init(document.querySelector('#dtdcChart'))
}, },
setOption() { setOption() {
const source = [['日期','电压','温度','SOC','SOH']]
source.push(['1月','12','13','14','15'],['2月','12','13','14','15'])
this.chart.setOption({ this.chart.setOption({
color:['#FFBD00','#3C81FF'], color:['#FFBD00','#3C81FF','#05AEA3','#F86F70'],
legend: { legend: {
left: 'center',
bottom: '10', bottom: '10',
}, },
tooltip: { tooltip: {
@ -43,26 +44,37 @@ export default {
color:"#333333", color:"#333333",
}, },
xAxis: { xAxis: {
data: ['1月','2月','3月','4月','5月','6月','7月','8月','9月','10月','11月','12月'], type: 'category',
}, },
yAxis: { yAxis: {
type: 'value', type: 'value',
}, },
dataset:{
source
// source: [['日期','充电量','放电量']]
},
series: [ series: [
{ {
name:'昨天', name:'电压',
data: [80,92,1,34,90,130,320,80,9,91,34,90],
type: 'bar', type: 'bar',
},{ },{
name:'今天', name:'温度',
data: [820,932,901,934,1290,1330,1320,820,932,901,934,1290], type: 'bar',
},
{
name:'SOC',
type: 'bar',
},{
name:'SOH',
type: 'bar', type: 'bar',
}] }]
}) })
this.chart.hideLoading()
} }
},
mounted() {
this.initChart()
} }
} }

View File

@ -1,19 +1,19 @@
<template> <template>
<el-card shadow="always" class="common-card-container common-card-container-no-title-bg"> <el-card v-loading="loading" shadow="always" class="common-card-container common-card-container-no-title-bg">
<div slot="header"> <div slot="header">
<span class="large-title">单体电池实时数据</span> <span class="large-title">单体电池实时数据</span>
</div> </div>
<!-- 搜索栏--> <!-- 搜索栏-->
<el-form :inline="true" class="select-container"> <el-form :inline="true" class="select-container">
<el-form-item label="电池堆"> <el-form-item label="电池堆">
<el-select v-model="search.dcd" placeholder="请选择" :loading="loading" loading-text="正在加载数据"> <el-select v-model="search.stackId" placeholder="请选择" @change="changeStackId">
<el-option :label="item.name" :value="item.id" v-for="(item,index) in dcdOptions" :key="index+'dcdOptions'"></el-option> <el-option :label="item.deviceName" :value="item.id" v-for="(item,index) in stackOptions" :key="index+'stackOptions'"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="电池簇"> <el-form-item label="电池簇">
<el-select v-model="search.dcc" placeholder="请选择" :loading="loading" loading-text="正在加载数据"> <el-select v-model="search.clusterId" :no-data-text="!search.stackId && stackOptions.length > 0 ? '请先选择电池堆':'无数据'" placeholder="请选择" :loading="clusterloading" loading-text="正在加载数据">
<el-option :label="item.name" :value="item.id" v-for="(item,index) in dccOptions" :key="index+'dccOptions'"></el-option> <el-option :label="item.deviceName" :value="item.id" v-for="(item,index) in clusterOptions" :key="index+'clusterOptions'"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
@ -24,14 +24,6 @@
</el-form-item> </el-form-item>
</el-form> </el-form>
<div style="margin:30px 0;box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);"> <div style="margin:30px 0;box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);">
<!-- 四个选择按钮-->
<el-row style="">
<el-col :xs="24" :sm="24" :lg="24">
<el-button-group class="ems-btns-group">
<el-button v-for="(item,index) in btnList" :key="index+'dtdcBtns'" :class="{'activeBtn' : activeBtn === item.id}" @click="changeDataType(item.id)">{{item.name}}</el-button>
</el-button-group>
</el-col>
</el-row>
<!-- 图表--> <!-- 图表-->
<el-row style="background:#fff;margin:30px 0;"> <el-row style="background:#fff;margin:30px 0;">
<el-col :xs="24" :sm="24" :lg="24"> <el-col :xs="24" :sm="24" :lg="24">
@ -45,59 +37,66 @@
<script> <script>
import BarChart from './BarChart' import BarChart from './BarChart'
import {getStackNameList,getClusterNameList} from '@/api/ems/dzjk'
import getQuerySiteId from "@/mixins/ems/getQuerySiteId";
export default { export default {
name:'DzjkSbjkDtdc', name:'DzjkSbjkDtdc',
mixins:[getQuerySiteId],
components:{BarChart}, components:{BarChart},
data() { data() {
return { return {
btnList:[
{name:'电压',id:'dy'},
{name:'温度',id:'wd'},
{name:'SOC',id:'soc'},
{name:'SOH',id:'soh'},
],
activeBtn:'dy',
loading:false, loading:false,
search:{dcd:'',dcc:''}, clusterloading:false,
dcdOptions:[ search:{stackId:'',clusterId:''},
{name:'电池堆1',id:1}, stackOptions:[],//{id:'',deviceName:''}
{name:'电池堆2',id:2}, clusterOptions:[]//{id:'',deviceName:''}
{name:'电池堆3',id:3},
],
dccOptions:[
{name:'电池簇1',id:1},
{name:'电池簇2',id:2},
]
} }
}, },
methods:{ methods:{
// 搜索 // 搜索
onSearch(){ onSearch(){
this.getData() this.init(false)
}, },
// 重置 // 重置
// 清空搜索栏选中数据
// 清空电池簇列表,保留电池堆列表
onReset(){ onReset(){
this.search.dcd='' this.search={stackId:'',clusterId:''}
this.search.dcc='' this.clusterOptions=[]
this.getData() this.init(false)
}, },
// 获取数据 changeStackId(val){
getData(){ if(val){
this.$refs.barChart.chart.showLoading() console.log('选择了电池堆,需要获取对应的电池簇',val,this.search.stackId)
//获取完成后 传入data todo传参 this.search.clusterId=''
this.$refs.barChart.setOption() this.getClusterList()
},
changeDataType(id){
if(id !== this.activeBtn){
console.log('点击了不同的菜单,更新数据')
this.activeBtn=id;
} }
}, },
getStackList(){
getStackNameList(this.siteId).then(response => {
this.stackOptions = JSON.parse(JSON.stringify(response?.data || []))
})
},
getClusterList(){
this.clusterloading =true
getClusterNameList(this.search.stackId).then(response => {
this.clusterOptions = JSON.parse(JSON.stringify(response?.data || []))
}).finally(() => {this.clusterloading =false})
},
init(mounted = true){
this.loading=true;
// todo 获取单体电池数据
this.loading=false;
this.$refs.barChart.setOption()
// 只有页面初次加载的时候调用电池堆列表,其他情况不需要
if(mounted){
this.getStackList()
}
}
}, },
mounted(){ mounted(){
this.$refs.barChart.initChart()
this.getData()
} }
} }

View File

@ -1,13 +1,15 @@
<template> <template>
<div class="pcs-ems-dashboard-editor-container"> <div class="pcs-ems-dashboard-editor-container" v-loading="loading">
<real-time-base-info/> <!-- 顶部六个方块-->
<el-container class="pcs-container"> <real-time-base-info :data="runningHeadData"/>
<!-- 内容-->
<el-container class="pcs-container" v-for="(pcsItem,pcsIndex) in pcsList" :key="pcsIndex+'PcsHome'">
<el-header class="pcs-header"> <el-header class="pcs-header">
<div class="pcs-title">PCS</div> <div class="pcs-title">{{pcsItem.deviceName}}</div>
<div class="pcs-status"> <div class="pcs-status">
<div>通信中断</div> <div>{{pcsItem.communicationStatus}}</div>
<div>数据更新时间2024-10-11 12:00:00</div> <div>数据更新时间{{pcsItem.dataUpdateTime}}</div>
</div> </div>
<div class="pcs-btns"> <div class="pcs-btns">
<el-button type="warning" size="small" @click="problemSaved">故障复位</el-button> <el-button type="warning" size="small" @click="problemSaved">故障复位</el-button>
@ -17,55 +19,63 @@
<el-main style="padding: 0"> <el-main style="padding: 0">
<div class="descriptions-main"> <div class="descriptions-main">
<el-descriptions direction="vertical" :column="4" :colon="false"> <el-descriptions direction="vertical" :column="4" :colon="false">
<el-descriptions-item labelClassName="descriptions-label" contentClassName="descriptions-direction danger" :span="1" label="工作状态">停止</el-descriptions-item> <el-descriptions-item labelClassName="descriptions-label" contentClassName="descriptions-direction danger" :span="1" label="工作状态">{{pcsItem.workStatus}}</el-descriptions-item>
<el-descriptions-item labelClassName="descriptions-label" contentClassName="descriptions-direction" :span="1" label="并网状态">并网</el-descriptions-item> <el-descriptions-item labelClassName="descriptions-label" contentClassName="descriptions-direction" :span="1" label="并网状态">{{pcsItem.gridStatus}}</el-descriptions-item>
<el-descriptions-item labelClassName="descriptions-label" contentClassName="descriptions-direction save" :span="1" label="设备状态">在线</el-descriptions-item> <el-descriptions-item labelClassName="descriptions-label" contentClassName="descriptions-direction save" :span="1" label="设备状态">{{pcsItem.deviceStatus}}</el-descriptions-item>
<el-descriptions-item labelClassName="descriptions-label" contentClassName="descriptions-direction" :span="1" label="控制模式">远程</el-descriptions-item> <el-descriptions-item labelClassName="descriptions-label" contentClassName="descriptions-direction" :span="1" label="控制模式">{{pcsItem.controlMode}}</el-descriptions-item>
</el-descriptions> </el-descriptions>
</div> </div>
<div class="descriptions-main descriptions-main-bg-color"> <div class="descriptions-main descriptions-main-bg-color">
<el-descriptions labelClassName="descriptions-label" contentClassName="descriptions-direction" direction="vertical" :column="4" :colon="false"> <el-descriptions labelClassName="descriptions-label" contentClassName="descriptions-direction" direction="vertical" :column="4" :colon="false">
<el-descriptions-item v-for="(item,index) in infoData" :key="index+'pcsInfoData'" :span="1" :label="item.label">{{item.value}} <span v-if="item.unit" v-html="item.unit"></span></el-descriptions-item> <el-descriptions-item v-for="(item,index) in infoData" :key="index+'pcsInfoData'" :span="1" :label="item.label">{{pcsItem[item.attr] | formatNumber}} <span v-if="item.unit" v-html="item.unit"></span></el-descriptions-item>
</el-descriptions> </el-descriptions>
</div> </div>
<div class="descriptions-main"> <div class="descriptions-main" v-for="(item,index) in pcsItem.pcsBranchInfoList" :key="index+'pcsBranchInfoList'">
<el-descriptions labelClassName="descriptions-label" contentClassName="descriptions-direction keep" direction="vertical" :column="4" :colon="false"> <el-descriptions labelClassName="descriptions-label" contentClassName="descriptions-direction keep" direction="vertical" :column="4" :colon="false">
<el-descriptions-item labelClassName="descriptions-label" contentClassName="descriptions-direction keep" :span="4" label="支路一">放电中</el-descriptions-item> <el-descriptions-item labelClassName="descriptions-label" contentClassName="descriptions-direction keep" :span="4" :label="'支路'+(index+1)">{{item.dischargeStatus}}</el-descriptions-item>
<el-descriptions-item labelClassName="descriptions-label" contentClassName="descriptions-direction" :span="1" label="直流功率">-9.8kW</el-descriptions-item> <el-descriptions-item labelClassName="descriptions-label" contentClassName="descriptions-direction" :span="1" label="直流功率">{{item.dcPower}}kW</el-descriptions-item>
<el-descriptions-item labelClassName="descriptions-label" contentClassName="descriptions-direction" :span="1" label="直流电压">720.4V</el-descriptions-item> <el-descriptions-item labelClassName="descriptions-label" contentClassName="descriptions-direction" :span="1" label="直流电压">{{item.dcVoltage}}V</el-descriptions-item>
<el-descriptions-item labelClassName="descriptions-label" contentClassName="descriptions-direction" :span="1" label="直流电流">-13.1A</el-descriptions-item> <el-descriptions-item labelClassName="descriptions-label" contentClassName="descriptions-direction" :span="1" label="直流电流">{{item.dcCurrent}}A</el-descriptions-item>
</el-descriptions> </el-descriptions>
</div> </div>
</el-main> </el-main>
</el-container> </el-container>
<el-empty v-show="pcsList.length<=0" :image-size="200"></el-empty>
</div> </div>
</template> </template>
<script> <script>
import RealTimeBaseInfo from "./../RealTimeBaseInfo.vue"; import RealTimeBaseInfo from "./../RealTimeBaseInfo.vue";
import getQuerySiteId from "@/mixins/ems/getQuerySiteId";
import {getRunningHeadInfo,getPcsDetailInfo} from '@/api/ems/dzjk'
export default { export default {
name:'DzjkSbjkPcs', name:'DzjkSbjkPcs',
components:{RealTimeBaseInfo}, components:{RealTimeBaseInfo},
mixins:[getQuerySiteId],
data() { data() {
return { return {
loading:false,
runningHeadData:{},//运行信息
pcsList:[],
infoData:[ infoData:[
{label:'总交流有功电率',value:'-7.2',attr:'',unit:'kW'}, {label:'总交流有功电率',attr:'totalActivePower',unit:'kW'},
{label:'当天交流充电量',value:'0',attr:'',unit:'kWh'}, {label:'当天交流充电量',attr:'dailyAcChargeEnergy',unit:'kWh'},
{label:'A相电压',value:'12',attr:'',unit:'V'}, {label:'A相电压',attr:'aPhaseVoltage',unit:'V'},
{label:'A相电流',value:'20',attr:'',unit:'A'}, {label:'A相电流',attr:'aPhaseCurrent',unit:'A'},
{label:'总交流无功电率',value:'-0.1',attr:'',unit:'kVar'}, {label:'总交流无功电率',attr:'totalReactivePower',unit:'kVar'},
{label:'当天交流放电量',value:'145',attr:'',unit:'kWh'}, {label:'当天交流放电量',attr:'dailyAcDischargeEnergy',unit:'kWh'},
{label:'B相电压',value:'12',attr:'',unit:'V'}, {label:'B相电压',attr:'bPhaseVoltage',unit:'V'},
{label:'B相电流',value:'20',attr:'',unit:'A'}, {label:'B相电流',attr:'bPhaseCurrent',unit:'A'},
{label:'总交流视在功率',value:'8',attr:'',unit:'kVA'}, {label:'总交流视在功率',attr:'totalApparentPower',unit:'kVA'},
{label:'PCS模块温度',value:'40',attr:'',unit:'&#8451;'}, {label:'PCS模块温度',attr:'pcsModuleTemperature',unit:'&#8451;'},
{label:'C相电压',value:'12',attr:'',unit:'V'}, {label:'C相电压',attr:'cPhaseVoltage',unit:'V'},
{label:'C相电流',value:'20',attr:'',unit:'A'}, {label:'C相电流',attr:'cPhaseCurrent',unit:'A'},
{label:'总交流功率因数',value:'-0.9',attr:'',unit:''}, {label:'总交流功率因数',attr:'totalPowerFactor',unit:''},
{label:'PCS环境温度',value:'12',attr:'',unit:'&#8451;'}, {label:'PCS环境温度',attr:'pcsEnvironmentTemperature',unit:'&#8451;'},
{label:'交流频率',value:'102',attr:'',unit:'Hz'} {label:'交流频率',attr:'acFrequency',unit:'Hz'}
], ],
pcsBranchList:[]//pcs的支路列表
} }
}, },
methods:{ methods:{
@ -130,8 +140,25 @@ export default {
}).catch(() => { }).catch(() => {
//取消关机 //取消关机
}); });
},
//6个方块数据
getRunningHeadData(){
getRunningHeadInfo(this.siteId).then(response => {
this.runningHeadData = response?.data || {}
})
},
getPcsList(){
this.loading = true
getPcsDetailInfo(this.siteId).then(response => {
const data = response?.data || {}
this.pcsList = JSON.parse(JSON.stringify(data))
}).finally(()=>this.loading = false)
},
init(){
this.getRunningHeadData()
this.getPcsList()
} }
} },
} }
</script> </script>
@ -139,6 +166,8 @@ export default {
<style scoped lang="scss"> <style scoped lang="scss">
.pcs-container{ .pcs-container{
margin-top: 25px; margin-top: 25px;
border:1px solid #eeeeee;
border-radius: 6px 6px 0 0;
//红色标题 //红色标题
.pcs-header{ .pcs-header{
background: #FC6B69; background: #FC6B69;

View File

@ -1,5 +1,5 @@
<template> <template>
<div class="ems-dashboard-editor-container"> <div class="ems-dashboard-editor-container" v-loading="loading">
<zd-info></zd-info> <zd-info></zd-info>
<div class="ems-content-container "> <div class="ems-content-container ">
<div class="map-container"> <div class="map-container">
@ -22,7 +22,7 @@
</el-row> </el-row>
<!-- 基本信息 --> <!-- 基本信息 -->
<el-descriptions class="single-zd-info-container" :column="1" > <el-descriptions class="single-zd-info-container" :column="1" >
<el-descriptions-item v-for="(item,index) in singleZdInfo" :key="index+'singleZdInfo'" :label="item.title">{{item.value}}</el-descriptions-item> <el-descriptions-item v-for="(item,index) in singleZdInfo" :key="index+'singleZdInfo'" :label="item.title">{{item.value | formatNumber }}</el-descriptions-item>
</el-descriptions> </el-descriptions>
<!-- echarts柱状图--> <!-- echarts柱状图-->
<bar-chart ref="barChart"></bar-chart> <bar-chart ref="barChart"></bar-chart>
@ -45,6 +45,7 @@ export default {
components:{ZdSelect,ZdInfo,SingleSquareBox,BarChart,MapChart}, components:{ZdSelect,ZdInfo,SingleSquareBox,BarChart,MapChart},
data() { data() {
return { return {
loading:false,
singleSiteId:'', singleSiteId:'',
singleSiteName:'', singleSiteName:'',
singleSiteLocation:[], singleSiteLocation:[],
@ -97,23 +98,24 @@ export default {
// 站点选中 // 站点选中
submitSite(id){ submitSite(id){
if(this.singleSiteId === id){return console.log(`点击搜索按钮 搜索相同的站点id= ${id}不再调用获取基本信息接口`)} if(this.singleSiteId === id){return console.log(`点击搜索按钮 搜索相同的站点id= ${id}不再调用获取基本信息接口`)}
this.loading=true
console.log('点击搜索按钮 选中的站点id',id) console.log('点击搜索按钮 选中的站点id',id)
this.singleSiteId = id this.singleSiteId = id
this.$refs.zdSelect.searchLoading = true this.$refs.zdSelect.searchLoading = true
getSingleSiteBaseInfo(id).then(response => { getSingleSiteBaseInfo(id).then(response => {
console.log('单个站点详情数据',response) console.log('单个站点详情数据',response)
const res = response.data || {} const res = response?.data || {}
this.singleSiteName = res?.siteName || ''//站点名称 this.singleSiteName = res?.siteName || ''//站点名称
this.singleSiteLocation = res?.siteLocation || []//站点坐标 this.singleSiteLocation = res?.siteLocation || []//站点坐标
this.singleZdSqaure.forEach(item=>{ this.singleZdSqaure.forEach(item=>{
item.value =( res[item.attr] || res[item.attr] === 0 ) ? res[item.attr] : '-' item.value =res[item.attr]
}) })
this.singleZdInfo.forEach(item=>{ this.singleZdInfo.forEach(item=>{
item.value = ( res[item.attr] || res[item.attr] === 0 ) ? res[item.attr] : '-' item.value = res[item.attr]
}) })
this.$refs.barChart.setOption(res?.sevenDayDisChargeStats || []) this.$refs.barChart.setOption(res?.sevenDayDisChargeStats || [])
this.$refs.mapChart.setOption([{name:this.singleSiteName,value:this.singleSiteLocation}]) this.$refs.mapChart.setOption([{name:this.singleSiteName,value:this.singleSiteLocation}])
}).finally(() => {this.$refs.zdSelect.searchLoading = false}) }).finally(() => {this.$refs.zdSelect.searchLoading = false;this.loading=false})
}, },
//跳转单站监控页面 //跳转单站监控页面
toDzjk(){ toDzjk(){