mirror of
https://gitee.com/js-yhsec/energy_storage.git
synced 2026-05-28 03:09:24 +08:00
南瑞意见修改:前端页面和后端接口
This commit is contained in:
@@ -218,18 +218,18 @@ export const columnList = [
|
||||
dataIndex: 'operation_date',
|
||||
key: 'operation_date'
|
||||
},
|
||||
{
|
||||
title: '场站运行模式',
|
||||
dataIndex: 'work_mode',
|
||||
key: 'work_mode',
|
||||
scopedSlots: { customRender: 'work_mode' }
|
||||
},
|
||||
{
|
||||
title: '场站运行策略',
|
||||
dataIndex: 'policy_id',
|
||||
key: 'policy_id',
|
||||
scopedSlots: { customRender: 'policy_id' }
|
||||
},
|
||||
// {
|
||||
// title: '场站运行模式',
|
||||
// dataIndex: 'work_mode',
|
||||
// key: 'work_mode',
|
||||
// scopedSlots: { customRender: 'work_mode' }
|
||||
// },
|
||||
// {
|
||||
// title: '场站运行策略',
|
||||
// dataIndex: 'policy_id',
|
||||
// key: 'policy_id',
|
||||
// scopedSlots: { customRender: 'policy_id' }
|
||||
// },
|
||||
{
|
||||
title: '操作',
|
||||
dataIndex: 'operate',
|
||||
|
||||
@@ -18,6 +18,24 @@ const locale = ref(zhCN)
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
*{
|
||||
-webkit-touch-callout:none; /*系统默认菜单被禁用*/
|
||||
-webkit-user-select:none; /*webkit浏览器*/
|
||||
-khtml-user-select:none; /*早期浏览器*/
|
||||
-moz-user-select:none;/*火狐*/
|
||||
-ms-user-select:none; /*IE10*/
|
||||
user-select:none;
|
||||
}
|
||||
input{
|
||||
-webkit-user-select:auto; /*webkit浏览器*/
|
||||
user-select:auto;
|
||||
}
|
||||
textarea{
|
||||
-webkit-user-select:auto; /*webkit浏览器*/
|
||||
user-select:auto;
|
||||
}
|
||||
|
||||
#app {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<template>
|
||||
<div class="alarm">
|
||||
<div class="text_Cur">
|
||||
<!-- <div class="text_Cur">
|
||||
<div v-for="item in curList" :key="item.key">
|
||||
<div>{{ item.name }}</div>
|
||||
<span class="mark">{{ item.value ? item.value : 0 }}</span>
|
||||
<span class="d">{{ item.d }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
<div id="alarm-chart"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<template>
|
||||
<div class="charge">
|
||||
<div class="text_Cur">
|
||||
<!-- <div class="text_Cur">
|
||||
<div v-for="item in curList" :key="item.key">
|
||||
<div>{{ item.name }}</div>
|
||||
<span class="mark">{{ item.value ? item.value : 0 }}</span>
|
||||
<span class="d">{{ item.d }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
<div id="charge-chart"></div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -24,6 +24,10 @@ export default {
|
||||
deviceInfo: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
myData: {
|
||||
type: Number,
|
||||
default: () => -1
|
||||
}
|
||||
},
|
||||
data() {
|
||||
@@ -95,6 +99,10 @@ export default {
|
||||
}
|
||||
},
|
||||
deep: true // 确保深度比较
|
||||
},
|
||||
myData: {
|
||||
handler(newVal,oldVal) {
|
||||
},
|
||||
}
|
||||
},
|
||||
mounted() {},
|
||||
@@ -122,34 +130,33 @@ export default {
|
||||
arr.forEach((item, index) => {
|
||||
this.chargeChartData.ydata[index] = {
|
||||
name: item.name,
|
||||
smooth: true,
|
||||
type: 'line',
|
||||
barWidth: 10,
|
||||
itemStyle: {
|
||||
borderRadius: 10,
|
||||
color: item.lineColor
|
||||
},
|
||||
emphasis: {
|
||||
focus: 'series'
|
||||
},
|
||||
areaStyle: {
|
||||
global: false,
|
||||
color: {
|
||||
type: 'linear',
|
||||
x: 0,
|
||||
y: 0,
|
||||
x2: 0,
|
||||
y2: 1,
|
||||
colorStops: [
|
||||
{ offset: 0, color: JSON.parse(JSON.stringify(item)).colorStart }, // 顶部颜色
|
||||
{ offset: 1, color: JSON.parse(JSON.stringify(item)).colorEnd } // 底部颜色
|
||||
]
|
||||
}
|
||||
},
|
||||
global: false,
|
||||
showSymbol: false,
|
||||
yAxisIndex: index,
|
||||
data: result.values[index]
|
||||
// smooth: true,
|
||||
// type: 'line',
|
||||
// barWidth: 10,
|
||||
// itemStyle: {
|
||||
// borderRadius: 10,
|
||||
// color: item.lineColor
|
||||
// },
|
||||
// emphasis: {
|
||||
// focus: 'series'
|
||||
// },
|
||||
// areaStyle: {
|
||||
// global: false,
|
||||
// color: {
|
||||
// type: 'linear', x: 0, y: 0, x2: 0, y2: 1,
|
||||
// colorStops: [
|
||||
// { offset: 0, color: JSON.parse(JSON.stringify(item)).colorStart }, // 顶部颜色
|
||||
// { offset: 1, color: JSON.parse(JSON.stringify(item)).colorEnd } // 底部颜色
|
||||
// ]
|
||||
// }
|
||||
// },
|
||||
// global: false,
|
||||
// showSymbol: false,
|
||||
// yAxisIndex: index,
|
||||
// data: result.values[index]
|
||||
type: 'bar',
|
||||
data: [18,25,39,17,37,41,62],
|
||||
color: item.lineColor
|
||||
}
|
||||
})
|
||||
},
|
||||
@@ -196,8 +203,9 @@ export default {
|
||||
},
|
||||
yAxis: [
|
||||
{
|
||||
name: '充电电量(kW·h)',
|
||||
name: '充电电量(kWh)',
|
||||
type: 'value',
|
||||
splitNumber: 2,
|
||||
nameTextStyle: {
|
||||
color: '#fff' // 绿色名称
|
||||
},
|
||||
@@ -205,15 +213,16 @@ export default {
|
||||
lineStyle: { type: 'dashed', color: '#435463' }
|
||||
},
|
||||
axisLabel: {
|
||||
interval: 4,
|
||||
// interval: 2,
|
||||
color: '#fff',
|
||||
fontSize:12
|
||||
|
||||
},
|
||||
// axisLine : {show: true, color: '#f00'}
|
||||
},
|
||||
{
|
||||
name: '充电收益(元)',
|
||||
type: 'value',
|
||||
splitNumber: 2,
|
||||
splitLine: {
|
||||
lineStyle: { type: 'dashed', color: '#435463' }
|
||||
},
|
||||
@@ -221,14 +230,18 @@ export default {
|
||||
color: '#fff' // 绿色名称
|
||||
},
|
||||
axisLabel: {
|
||||
interval: 4,
|
||||
// interval: 4,
|
||||
color: '#fff',
|
||||
fontSize:12
|
||||
},
|
||||
// axisLine : {show: true, lineStyle: { color: '#ff0000', width: 2 } }
|
||||
},
|
||||
|
||||
],
|
||||
series: this.chargeChartData.ydata
|
||||
// serise: [
|
||||
// { name: '2011', type: 'bar', data: [18, 23, 29, 10, 13, 63] }
|
||||
// ]
|
||||
}
|
||||
option && chargeChart.setOption(option)
|
||||
this.setupResizeListener()
|
||||
@@ -244,10 +257,10 @@ export default {
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.charge {
|
||||
height: calc(100% - 45px);
|
||||
|
||||
height: calc(100% - 35px);
|
||||
background-color: #50505050;
|
||||
#charge-chart {
|
||||
height: calc(100% - 45px);
|
||||
height: calc(100% - 5px);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="energy">
|
||||
<div class="text_Cur">
|
||||
<!-- <div class="text_Cur">
|
||||
<div v-for="item in curList" :key="item.key">
|
||||
<div>{{ item.name }}</div>
|
||||
<div>
|
||||
@@ -8,7 +8,7 @@
|
||||
<span class="d">{{ item.d }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
<div id="energy-chart"></div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -104,19 +104,22 @@ export default {
|
||||
arr.forEach((item, index) => {
|
||||
this.energyChartData.ydata[index] = {
|
||||
name: item.name,
|
||||
smooth: true,
|
||||
type: 'line',
|
||||
barWidth: 5,
|
||||
itemStyle: {
|
||||
borderRadius: [5, 5, 0, 0],
|
||||
color: item.lineColor
|
||||
},
|
||||
emphasis: {
|
||||
focus: 'series'
|
||||
},
|
||||
global: false,
|
||||
showSymbol: false,
|
||||
data: result.values[index]
|
||||
// type: 'line',
|
||||
// smooth: true,
|
||||
// barWidth: 5,
|
||||
// itemStyle: {
|
||||
// borderRadius: [5, 5, 0, 0],
|
||||
// color: item.lineColor
|
||||
// },
|
||||
// emphasis: {
|
||||
// focus: 'series'
|
||||
// },
|
||||
// global: false,
|
||||
// showSymbol: false,
|
||||
// data: result.values[index]
|
||||
type: 'bar',
|
||||
data: [5,3,6,3,8,4,6],
|
||||
color: item.lineColor
|
||||
}
|
||||
})
|
||||
},
|
||||
@@ -164,6 +167,7 @@ export default {
|
||||
name: '电量(kW·h)',
|
||||
nameTextStyle: { color: '#fff' },
|
||||
type: 'value',
|
||||
splitNumber: 2,
|
||||
splitLine: {
|
||||
lineStyle: { type: 'dashed', color: '#435463' }
|
||||
},
|
||||
@@ -189,10 +193,10 @@ export default {
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.energy {
|
||||
height: calc(100% - 45px);
|
||||
|
||||
height: calc(100% - 35px);
|
||||
background-color: #50505030;
|
||||
#energy-chart {
|
||||
height: calc(100% - 45px);
|
||||
height: calc(100% - 5px);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
:position="[marker.lon, marker.lat]"
|
||||
:key="marker.id"
|
||||
:icon="marker.iconMap"
|
||||
style="width: 20px;height: auto"
|
||||
style="height: auto"
|
||||
@click="clickArrayMarker(marker)"
|
||||
:title="marker.name"
|
||||
>
|
||||
@@ -235,7 +235,8 @@ export default {
|
||||
}
|
||||
|
||||
:deep(.tdt-marker-icon){
|
||||
height:auto!important;
|
||||
width: 40px !important;
|
||||
height:auto !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,27 +1,25 @@
|
||||
<template>
|
||||
<div class="Home">
|
||||
<div class="content-left">
|
||||
<div v-for="item in leftList" :key="item.componentId" :class="`grid-item ${item.class}`">
|
||||
<div v-for="item in listLeft" :key="item.componentId" :class="`grid-item ${item.class}`">
|
||||
<div class="tool">
|
||||
<div class="title">
|
||||
<span class="linear-text">{{ item.title }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<component
|
||||
:is="item.componentId"
|
||||
:props-info="modalInfo[item.infoKey]"
|
||||
:props-total="
|
||||
['prefab', 'envTotal'].includes(item.infoKey)
|
||||
? item.infoKey == 'prefab'
|
||||
? modalInfo.prefabTotal
|
||||
: modalInfo.envInfoTotal
|
||||
: modalInfo.allTotal
|
||||
"
|
||||
></component>
|
||||
<component :is="item.componentId" :prop-key="item.infoKey"
|
||||
:prop-data="compData[item.infoKey]"
|
||||
:props-info="modalInfo[item.infoKey]"
|
||||
:props-total="['prefab', 'envTotal'].includes(item.infoKey)
|
||||
? item.infoKey == 'prefab'
|
||||
? modalInfo.prefabTotal
|
||||
: modalInfo.envInfoTotal
|
||||
: modalInfo.allTotal
|
||||
"></component>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content-right">
|
||||
<div v-for="item in rightList" :key="item.componentId" :class="`grid-item ${item.class}`">
|
||||
<div v-for="item in listRight" :key="item.componentId" :class="`grid-item ${item.class}`">
|
||||
<div class="tool">
|
||||
<div class="title">
|
||||
<span class="linear-text">{{ item.title }}</span>
|
||||
@@ -43,12 +41,14 @@ import OperationalInfo from '@/components/Home/Modal/OperationalInfo.vue'
|
||||
import StatisticalInfo from '@/components/Home/Modal/StatisticalInfo.vue'
|
||||
import Revenue from '@/components/Home/Modal/Revenue.vue'
|
||||
import Utilization from '@/components/Home/Modal/Utilization.vue'
|
||||
import DisCharge from '@/components/Home/Modal/DisCharge.vue'
|
||||
// import DisCharge from '@/components/Home/Modal/DisCharge.vue'
|
||||
import { getReq, postReq } from '@/request/api'
|
||||
import { getRunDays, getDateDaysAgo } from '@/utils/dealWithData'
|
||||
import EnvInfo from './Modal/EnvInfo.vue'
|
||||
import { markRaw } from 'vue';
|
||||
|
||||
import StationVoltage from '@/components/Home/Modal/StationVoltage.vue'
|
||||
import StationCurrent from '@/components/Home/Modal/StationCurrent.vue'
|
||||
import StationPower from '@/components/Home/Modal/StationPower.vue'
|
||||
export default {
|
||||
name: 'Home',
|
||||
components: {},
|
||||
@@ -63,62 +63,79 @@ export default {
|
||||
refreshInterval:null,
|
||||
|
||||
modalInfo: {},
|
||||
list: [
|
||||
{
|
||||
title: '预制舱信息',
|
||||
class: '',
|
||||
componentId: markRaw( PrefabCabin),
|
||||
infoKey: 'prefab'
|
||||
},
|
||||
{
|
||||
title: '储能充放电量',
|
||||
class: 'stats-cards',
|
||||
componentId:markRaw( DisCharge),
|
||||
infoKey: 'energy'
|
||||
},
|
||||
{
|
||||
title: '运行信息',
|
||||
class: 'operation-status',
|
||||
componentId:markRaw( OperationalInfo),
|
||||
infoKey: 'envTotal'
|
||||
},
|
||||
{
|
||||
title: '场站收益情况',
|
||||
class: 'revenue',
|
||||
componentId:markRaw( Revenue),
|
||||
infoKey: 'energy'
|
||||
},
|
||||
compData: {},
|
||||
|
||||
{
|
||||
title: '统计信息',
|
||||
class: 'statistical',
|
||||
componentId:markRaw( StatisticalInfo),
|
||||
infoKey: ''
|
||||
},
|
||||
{
|
||||
title: '设备利用率',
|
||||
class: '',
|
||||
componentId:markRaw( Utilization),
|
||||
infoKey: 'energy'
|
||||
},
|
||||
{
|
||||
title: '环境信息',
|
||||
class: 'envInfo',
|
||||
componentId:markRaw( EnvInfo),
|
||||
infoKey: 'envTotal'
|
||||
}
|
||||
listLeft: [
|
||||
{ title: '场站信息', class: '', componentId: markRaw( PrefabCabin), infoKey: 'prefab' },
|
||||
{ title: '储能运行信息', class: 'operation-status', componentId: markRaw(OperationalInfo), infoKey: 'storage' },
|
||||
{ title: '充电运行信息', class: 'operation-status', componentId: markRaw(OperationalInfo), infoKey: 'charge' },
|
||||
{ title: '光伏运行信息', class: 'operation-status', componentId: markRaw(OperationalInfo), infoKey: 'pv' },
|
||||
{ title: '电网侧运行信息', class: 'operation-status', componentId: markRaw(OperationalInfo), infoKey: 'grid' },
|
||||
{ title: '环境信息', class: 'envInfo', componentId:markRaw( EnvInfo), infoKey: 'envTotal' }
|
||||
],
|
||||
|
||||
listRight: [
|
||||
{ title: '今日电压曲线', class: 'stats-cards', componentId:markRaw(StationVoltage), infoKey: 'voltage' },
|
||||
{ title: '今日电流曲线', class: 'revenue', componentId:markRaw(StationCurrent), infoKey: 'current' },
|
||||
{ title: '今日功率曲线', class: '', componentId:markRaw(StationPower), infoKey: 'power' },
|
||||
],
|
||||
|
||||
// list: [
|
||||
// {
|
||||
// title: '场站信息',
|
||||
// class: '',
|
||||
// componentId: markRaw( PrefabCabin),
|
||||
// infoKey: 'prefab'
|
||||
// },
|
||||
// {
|
||||
// title: '储能充放电量',
|
||||
// class: 'stats-cards',
|
||||
// componentId:markRaw( DisCharge),
|
||||
// infoKey: 'energy'
|
||||
// },
|
||||
// {
|
||||
// title: '运行信息',
|
||||
// class: 'operation-status',
|
||||
// componentId:markRaw( OperationalInfo),
|
||||
// infoKey: 'envTotal'
|
||||
// },
|
||||
// {
|
||||
// title: '场站收益情况',
|
||||
// class: 'revenue',
|
||||
// componentId:markRaw( Revenue),
|
||||
// infoKey: 'energy'
|
||||
// },
|
||||
|
||||
// {
|
||||
// title: '统计信息',
|
||||
// class: 'statistical',
|
||||
// componentId:markRaw( StatisticalInfo),
|
||||
// infoKey: ''
|
||||
// },
|
||||
// {
|
||||
// title: '设备利用率',
|
||||
// class: '',
|
||||
// componentId:markRaw( Utilization),
|
||||
// infoKey: 'energy'
|
||||
// },
|
||||
// {
|
||||
// title: '环境信息',
|
||||
// class: 'envInfo',
|
||||
// componentId:markRaw( EnvInfo),
|
||||
// infoKey: 'envTotal'
|
||||
// }
|
||||
// ],
|
||||
sysName: '',
|
||||
user: JSON.parse(localStorage.getItem('permission')) || {}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
leftList() {
|
||||
return this.list.filter((_, index) => index % 2 === 0).slice(0, 4) // 左列取前3个偶数索引
|
||||
},
|
||||
rightList() {
|
||||
return this.list.filter((_, index) => index % 2 !== 0).slice(0, 3) // 右列取前3个奇数索引
|
||||
}
|
||||
// leftList() {
|
||||
// return this.list.filter((_, index) => index % 2 === 0).slice(0, 4) // 左列取前3个偶数索引
|
||||
// },
|
||||
// rightList() {
|
||||
// return this.list.filter((_, index) => index % 2 !== 0).slice(0, 3) // 右列取前3个奇数索引
|
||||
// }
|
||||
},
|
||||
beforeUnmount() {
|
||||
if(this.refreshInterval){
|
||||
@@ -140,7 +157,9 @@ export default {
|
||||
this.getStatTotalList(),
|
||||
this.queryStationInfo(),
|
||||
this.queryStationData(),
|
||||
this.getStatDayList(1)
|
||||
this.getStatDayList(1),
|
||||
this.getStatDayList(2),
|
||||
this.getStatDayList(3),
|
||||
])
|
||||
},
|
||||
// 查询系统累计统计信息
|
||||
@@ -157,10 +176,12 @@ export default {
|
||||
}
|
||||
const res = await getReq('/queryStatTotal', query)
|
||||
if (res.errcode === 0) {
|
||||
this.modalInfo.allTotal = res.data
|
||||
this.modalInfo.allTotal.runDays = getRunDays(res.data.launch_date)
|
||||
const { income_charge: incomeCharge, income_elect: incomeElect } = this.modalInfo.allTotal
|
||||
this.modalInfo.allTotal.incomeTotal = +incomeCharge + +incomeElect
|
||||
this.compData.prefab = { stats: res.data }
|
||||
// this.compData.prefab.run_days = getRunDays(res.data.launch_date)
|
||||
// this.modalInfo.allTotal = res.data
|
||||
// this.modalInfo.allTotal.run_days = getRunDays(res.data.launch_date)
|
||||
// const { income_charge: incomeCharge, income_elect: incomeElect } = this.modalInfo.allTotal
|
||||
// this.modalInfo.allTotal.incomeTotal = +incomeCharge + +incomeElect
|
||||
} else {
|
||||
throw res
|
||||
}
|
||||
@@ -171,37 +192,32 @@ export default {
|
||||
// 查询场站实时数据
|
||||
async queryStationData() {
|
||||
try {
|
||||
// station_id:场站ID
|
||||
|
||||
const query = {
|
||||
station_id: this.stationId
|
||||
}
|
||||
const res = await getReq('/queryStationData', query)
|
||||
const res = await getReq('/queryStationData', { station_id: this.stationId })
|
||||
if (res.errcode === 0) {
|
||||
this.modalInfo.envInfoTotal = res.data
|
||||
// this.compData.prefab = { data: res.data }
|
||||
this.compData.storage = res.data['storage']
|
||||
this.compData.charge = res.data['charge']
|
||||
this.compData.pv = res.data['pv']
|
||||
this.compData.grid = res.data['grid']
|
||||
} else {
|
||||
throw res
|
||||
}
|
||||
} catch (error) {
|
||||
this.modalInfo.envInfoTotal = {}
|
||||
this.compData.storage = this.compData.charge = this.compData.pv = this.compData.grid = {}
|
||||
}
|
||||
},
|
||||
// 查询场站信息
|
||||
async queryStationInfo() {
|
||||
try {
|
||||
// station_id:场站ID
|
||||
|
||||
const query = {
|
||||
station_id: this.stationId
|
||||
}
|
||||
const res = await getReq('/queryStationInfo', query)
|
||||
const res = await getReq('/queryStationInfo', { station_id: this.stationId })
|
||||
if (res.errcode === 0) {
|
||||
this.modalInfo.prefabTotal = res.data
|
||||
this.compData.prefab = { info: res.data }
|
||||
this.compData.prefab.info.run_days = getRunDays(res.data.launch_date)
|
||||
} else {
|
||||
throw res
|
||||
}
|
||||
} catch (error) {
|
||||
this.modalInfo.allTotal = {}
|
||||
this.compData.prefab = { info: {}}
|
||||
}
|
||||
},
|
||||
// 查询场站日统计信息
|
||||
@@ -214,19 +230,27 @@ export default {
|
||||
const query = {
|
||||
station_id: this.stationId,
|
||||
category,
|
||||
start_date: getDateDaysAgo(7 - 1),
|
||||
end_date: getDateDaysAgo(0)
|
||||
// start_date: getDateDaysAgo(7 - 1),
|
||||
// end_date: getDateDaysAgo(0)
|
||||
}
|
||||
const categoryObj = { 1: 'energy' }
|
||||
const res = await getReq('/queryStatDayList', query)
|
||||
// const res = await getReq('/queryStatDayList', query)
|
||||
const res = await getReq('/queryStationTodayU', query)
|
||||
if (res.errcode === 0) {
|
||||
this.modalInfo[categoryObj[category]] = res.data.map((item) => {
|
||||
const { income_charge: incomeCharge, income_elect: incomeElect } = item
|
||||
return {
|
||||
...item,
|
||||
incomeTotal: +incomeCharge + +incomeElect
|
||||
}
|
||||
})
|
||||
if (category === 1) {
|
||||
this.modalInfo.voltage = [{ index: 0, data: res.data.U }]
|
||||
this.modalInfo.current = [{ index: 0, data: res.data.I }]
|
||||
this.modalInfo.power = [{ index: 0, data: res.data.P }]
|
||||
}
|
||||
else if (category === 2){
|
||||
this.modalInfo.voltage = [{ index: 1, data: res.data.U }]
|
||||
this.modalInfo.current = [{ index: 1, data: res.data.I }]
|
||||
this.modalInfo.power = [{ index: 1, data: res.data.P }]
|
||||
}
|
||||
else if (category === 3){
|
||||
this.modalInfo.voltage = [{ index: 2, data: res.data.U }]
|
||||
this.modalInfo.current = [{ index: 2, data: res.data.I }]
|
||||
this.modalInfo.power = [{ index: 2, data: res.data.P }]
|
||||
}
|
||||
} else {
|
||||
throw res
|
||||
}
|
||||
@@ -284,7 +308,7 @@ export default {
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
font-size: 18px;
|
||||
font-weight: 400;
|
||||
font-weight: 1000;
|
||||
margin-left: 28px;
|
||||
}
|
||||
|
||||
@@ -315,7 +339,7 @@ export default {
|
||||
.text {
|
||||
margin-left: 20px;
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
font-weight: 1000;
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
rgba(0, 186, 173, 0.15) 0%,
|
||||
@@ -330,7 +354,7 @@ export default {
|
||||
}
|
||||
}
|
||||
.operation-status {
|
||||
height: calc(25% - 10px);
|
||||
height: calc(15% - 10px);
|
||||
}
|
||||
.statistical {
|
||||
height: calc(18% - 10px);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
/>
|
||||
<div class="right">
|
||||
<span>{{ item.label }}</span>
|
||||
<span>{{ item.value }} {{ item.d }}</span>
|
||||
<span style="color: #a0f0a0; font-size: 16px;">{{ item.value }} {{ item.d }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -4,8 +4,11 @@
|
||||
<div v-for="item in list" :key="item.key" :class="`item ${item.class}`">
|
||||
<a-image :preview="false" :src="item.iconPath" :width="50" class="left"> </a-image>
|
||||
<div class="right">
|
||||
<span>{{ item.label }}</span>
|
||||
<span>{{ item.value }} {{ item.d }}</span>
|
||||
<span class="k">{{ item.label }}</span>
|
||||
<div>
|
||||
<span class="v">{{ item.value }}</span>
|
||||
<span class="d">{{ item.d }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -16,86 +19,48 @@
|
||||
export default {
|
||||
name: '',
|
||||
props: {
|
||||
propsTotal: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
propsInfo: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
|
||||
propKey: { type: String, default: '' },
|
||||
propData: { type: Object, default: () => { } },
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
list: [
|
||||
// {
|
||||
// key: 'tianshu',
|
||||
// value: 26,
|
||||
// d: '℃',
|
||||
// label: '舱内温度',
|
||||
// class: 'item-1',
|
||||
// iconPath: require('@/assets/home/wendu.png')
|
||||
// },
|
||||
// {
|
||||
// key: 'shouyi',
|
||||
// value: 25,
|
||||
// d: '%',
|
||||
// label: '舱内湿度',
|
||||
// class: 'item-2',
|
||||
// iconPath: require('@/assets/home/shidu.png')
|
||||
// },
|
||||
{
|
||||
key: 'voltage',
|
||||
value: 24,
|
||||
d: 'V',
|
||||
label: '电压',
|
||||
class: 'item-3',
|
||||
iconPath: require('@/assets/home/dianya.png')
|
||||
},
|
||||
{
|
||||
key: 'current',
|
||||
value: 26,
|
||||
d: 'A',
|
||||
label: '电流',
|
||||
class: 'item-4',
|
||||
iconPath: require('@/assets/home/dianliu.png')
|
||||
},
|
||||
{
|
||||
key: 'power',
|
||||
value: 20,
|
||||
d: 'kW',
|
||||
label: '功率',
|
||||
class: 'item-5',
|
||||
iconPath: require('@/assets/home/gonglv.png')
|
||||
},
|
||||
{
|
||||
key: 'powerFactor',
|
||||
value: 100,
|
||||
d: '',
|
||||
label: '功率因数',
|
||||
class: 'item-6',
|
||||
iconPath: require('@/assets/home/gonglv.png')
|
||||
}
|
||||
]
|
||||
itemDef: {
|
||||
U: { key: 'U', value: '--', d: 'V', label: '电压', class: 'item-3', iconPath: require('@/assets/home/dianya.png') },
|
||||
I: { key: 'I', value: '--', d: 'A', label: '电流', class: 'item-4', iconPath: require('@/assets/home/dianliu.png') },
|
||||
P: { key: 'P', value: '--', d: 'kW', label: '功率', class: 'item-5', iconPath: require('@/assets/home/gonglv.png') },
|
||||
// PF: { key: 'PF', value: '--', d: '', label: '功率因数', class: 'item-6', iconPath: require('@/assets/home/gonglv.png') }
|
||||
},
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
||||
|
||||
},
|
||||
watch: {
|
||||
propsTotal: {
|
||||
propKey: {
|
||||
handler(newVal, oldVal) {
|
||||
if (this.propKey === 'grid') {
|
||||
this.list = [this.itemDef.P]
|
||||
}
|
||||
else if (this.propKey === 'pv') {
|
||||
this.list = [this.itemDef.P]
|
||||
}
|
||||
else {
|
||||
this.list = [this.itemDef.U, this.itemDef.I, this.itemDef.P]
|
||||
}
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
propData: {
|
||||
handler(newVal, oldVal) {
|
||||
if (newVal !== oldVal) {
|
||||
this.list.forEach((item) => {
|
||||
item.value = this.propsTotal[item.key]||0
|
||||
item.value = this.propData[item.key] || 0
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {},
|
||||
mounted() { },
|
||||
methods: {}
|
||||
}
|
||||
</script>
|
||||
@@ -104,44 +69,51 @@ export default {
|
||||
.operationlInfo {
|
||||
height: calc(100% - 45px);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
// justify-content: center;
|
||||
align-items: center;
|
||||
width: 95%;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.content {
|
||||
|
||||
flex-wrap: wrap;
|
||||
width: 90%;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-around;
|
||||
// align-items: center;
|
||||
// justify-content: space-around;
|
||||
height: 100%;
|
||||
padding-left: calc(10%);
|
||||
|
||||
.item {
|
||||
height: 50%;
|
||||
width: 45%;
|
||||
// height: 47px;
|
||||
width: 30%;
|
||||
height: 50px;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
// align-items: center;
|
||||
// justify-content: center;
|
||||
// text-align: center;
|
||||
|
||||
& > span:nth-child(1) {
|
||||
font-size: 12px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.d {
|
||||
margin-left: 1px;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-left: 20px;
|
||||
margin-left: 10px;
|
||||
|
||||
.k {
|
||||
color: #e0e0e0;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.v {
|
||||
color: #a0f0a0;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.d {
|
||||
margin-left: 8px;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
@@ -1,6 +1,18 @@
|
||||
<template>
|
||||
<div class="prefabCabin">
|
||||
<div class="content-left">
|
||||
<div style="display: flex; flex-direction: row; flex-wrap: wrap;" >
|
||||
<div v-for="item in [...myItemsInfo, ...myItemsStats]" :key="item.key" :class="`item ${item.class}`">
|
||||
<div style="display: flex; flex-direction: column; justify-items: flex-start;">
|
||||
<span style="color: #e0e0e0;">{{ item.label }}</span>
|
||||
<div style="display: flex; justify-content: flex-end; line-height: 1;">
|
||||
<span class="v">{{ item.value ? item.value : 0 }}</span>
|
||||
<span class="d">{{ item.d }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- <div class="content-left">
|
||||
<div v-for="item in leftList" :key="item.key" :class="`item ${item.class}`">
|
||||
<div>
|
||||
<span>{{ item.value ? item.value : 0 }}</span
|
||||
@@ -8,13 +20,13 @@
|
||||
</div>
|
||||
<span>{{ item.label }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div style="text-align: center; font-weight: 500">
|
||||
</div> -->
|
||||
<!-- <div style="text-align: center; font-weight: 500">
|
||||
<div class="prefabCabin-icon"></div>
|
||||
<span>{{ curStatus }}</span>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<div class="content-right">
|
||||
<!-- <div class="content-right">
|
||||
<div v-for="item in rightList" :key="item.key" :class="`item ${item.class}`">
|
||||
<div>
|
||||
<span>{{ item.value ? item.value : 0 }}</span
|
||||
@@ -22,7 +34,7 @@
|
||||
</div>
|
||||
<span>{{ item.label }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -30,6 +42,7 @@
|
||||
export default {
|
||||
name: '',
|
||||
props: {
|
||||
propData: { type: Object, default: () => {} },
|
||||
propsTotal: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
@@ -42,6 +55,24 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
curStatus: '充电',
|
||||
myItemsInfo: [
|
||||
{ key: 'capacity', value: '', label: '电池储能容量', d: 'kWh' },
|
||||
{ key: 'voltage_rated', value: '', label: '电池额定总电压', d: 'V' },
|
||||
{ key: 'cooling_type', value: '', label: '冷却方式', d: '' },
|
||||
{ key: 'batttey_type', value: '', label: '电池类型', d: '' },
|
||||
{ key: 'run_days', value: '', label: '场站运行天数', d: '天' },
|
||||
],
|
||||
myItemsStats: [
|
||||
{ key: 'storage_device_num', value: '', label: '储能设备数量', d: '个' },
|
||||
{ key: 'solar_device_num', value: '', label: '光伏设备数量', d: '个' },
|
||||
{ key: 'charge_device_num', value: '', label: '充电设备数量', d: '个' },
|
||||
{ key: 'solar_elect_grid', value: '', label: '上网总电量', d: 'kWh' },
|
||||
{ key: 'storage_elect_in', value: '', label: '储能充电总电量', d: 'kWh' },
|
||||
{ key: 'solar_elect_gen', value: '', label: '光伏发电总电量', d: 'kWh' },
|
||||
{ key: 'charge_elect', value: '', label: '充电桩充电总电量', d: 'kWh' },
|
||||
{ key: 'income_elect', value: '', label: '收益总金额', d: '元' },
|
||||
{ key: 'storage_elect_out', value: '', label: '储能放电总电量', d: 'kWh' },
|
||||
],
|
||||
list: [
|
||||
{
|
||||
key: 'batttey_type',
|
||||
@@ -123,20 +154,41 @@ export default {
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
propData: {
|
||||
handler(newVal, oldVal) {
|
||||
if (newVal !== oldVal) {
|
||||
if (this.propData.stats) {
|
||||
this.myItemsStats.forEach((item) => {
|
||||
item.value = this.propData.stats[item.key] != undefined ? this.propData.stats[item.key] : '--'
|
||||
});
|
||||
}
|
||||
if (this.propData.info) {
|
||||
this.myItemsInfo.forEach((item) => {
|
||||
item.value = this.propData.info[item.key] != undefined ? this.propData.info[item.key] : '--'
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
propsTotal: {
|
||||
handler(newVal, oldVal) {
|
||||
if (newVal !== oldVal) {
|
||||
|
||||
|
||||
|
||||
|
||||
// 0正常 1故障
|
||||
this.curStatus=['故障','正常'][this.propsTotal.status]
|
||||
this.list.forEach((item) => {
|
||||
if(item.key=='work_mode'){
|
||||
item.value = ['手动','峰谷套利','配网增容','应急供电','并网保电','自定时段'][this.propsTotal[item.key]]
|
||||
// console.log(item.list.map((item)=>this.propsTotal[item.key]==item.value)[0].label,"145",item.list.map((item)=>this.propsTotal[item.key]==item.value))
|
||||
// item.value =item.list.map((item)=>==item.value)[0].label
|
||||
}else {
|
||||
item.value = this.propsTotal[item.key]
|
||||
}
|
||||
})
|
||||
// this.list.forEach((item) => {
|
||||
// if(item.key=='work_mode'){
|
||||
// item.value = ['手动','峰谷套利','配网增容','应急供电','并网保电','自定时段'][this.propsTotal[item.key]]
|
||||
// // console.log(item.list.map((item)=>this.propsTotal[item.key]==item.value)[0].label,"145",item.list.map((item)=>this.propsTotal[item.key]==item.value))
|
||||
// // item.value =item.list.map((item)=>==item.value)[0].label
|
||||
// }else {
|
||||
// item.value = this.propsTotal[item.key]
|
||||
// }
|
||||
// })
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -152,29 +204,48 @@ export default {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-left: 10px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.item {
|
||||
height: 57px;
|
||||
background: linear-gradient(
|
||||
180deg,
|
||||
rgba(15, 227, 255, 0.3) 0%,
|
||||
rgba(15, 227, 255, 0.09) 45.6%,
|
||||
rgba(15, 227, 255, 0.3) 100%
|
||||
);
|
||||
padding: 10px 8px;
|
||||
height: 40px;
|
||||
width: calc(25% - 5px);
|
||||
margin-right: 5px;
|
||||
margin-bottom: 5px;
|
||||
background: url('@/assets/home/onLineBg.png');
|
||||
background-size: contain;
|
||||
background-size: 100% 100%;
|
||||
background-repeat: no-repeat;
|
||||
// background: linear-gradient(
|
||||
// 180deg,
|
||||
// rgba(15, 227, 255, 0.3) 0%,
|
||||
// rgba(15, 227, 255, 0.09) 45.6%,
|
||||
// rgba(15, 227, 255, 0.3) 100%
|
||||
// );
|
||||
// padding: 10px 8px;
|
||||
min-width: 115px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
|
||||
& > span:nth-child(1) {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
font-size: 12px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.v {
|
||||
color: #a0f0a0;
|
||||
line-height: 1;
|
||||
}
|
||||
.d {
|
||||
margin-left: 1px;
|
||||
display: block;
|
||||
text-align: left;
|
||||
margin-left: 5px;
|
||||
font-size: 12px;
|
||||
min-width: 40px;
|
||||
height: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
177
web/src/components/Home/Modal/StationCurrent.vue
Normal file
177
web/src/components/Home/Modal/StationCurrent.vue
Normal file
@@ -0,0 +1,177 @@
|
||||
<template>
|
||||
<div class="mychart">
|
||||
<div id="chart-current"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {processData} from '@/utils/dealWithData'
|
||||
|
||||
export default {
|
||||
name: '',
|
||||
props: {
|
||||
propsInfo: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
curList: [
|
||||
{
|
||||
name: '储能设备',
|
||||
key: 'storage_elect_in',
|
||||
lineColor: '#9BD801',
|
||||
value: 0,
|
||||
d: 'kW·h'
|
||||
},
|
||||
{
|
||||
name: '充电设备',
|
||||
key: 'storage_elect_out',
|
||||
lineColor: '#3DFEFA',
|
||||
value: 0,
|
||||
d: 'kW·h'
|
||||
}
|
||||
],
|
||||
|
||||
myChart: null,
|
||||
chartData: {
|
||||
ydata: [],
|
||||
xdata: []
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
propsInfo: {
|
||||
handler(newVal, oldVal) {
|
||||
if (JSON.stringify(newVal) !== JSON.stringify(oldVal)) {
|
||||
this.$nextTick(() => {
|
||||
this.updateChart()
|
||||
})
|
||||
}
|
||||
},
|
||||
deep: true // 确保深度比较
|
||||
}
|
||||
},
|
||||
mounted() {},
|
||||
beforeUnmount() {
|
||||
window.removeEventListener('resize', this.handleResize)
|
||||
if (this.myChart) {
|
||||
this.myChart.dispose()
|
||||
this.myChart = null
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
handleResize() {
|
||||
if (this.myChart) {
|
||||
this.myChart.resize()
|
||||
}
|
||||
},
|
||||
|
||||
createChartXData()
|
||||
{
|
||||
const timeArray = [];
|
||||
const dateZero = new Date();
|
||||
dateZero.setHours(0, 0, 0, 0); // 重置为当天0点
|
||||
for (let i=0; i<144; ++i)
|
||||
{
|
||||
// 累加10分钟
|
||||
const currentTime = new Date(dateZero.getTime() + i * 600 * 1000);
|
||||
// 格式化为 HH:mm
|
||||
const hours = currentTime.getHours().toString().padStart(2, '0');
|
||||
const minutes = currentTime.getMinutes().toString().padStart(2, '0');
|
||||
timeArray.push(`${hours}:${minutes}`);
|
||||
}
|
||||
return timeArray
|
||||
},
|
||||
|
||||
initChart() {
|
||||
const chartDom = document.getElementById('chart-current')
|
||||
if (!chartDom) return
|
||||
|
||||
if (this.myChart) this.myChart.dispose()
|
||||
this.myChart = this.$echarts.init(chartDom)
|
||||
|
||||
const xdata = this.createChartXData();
|
||||
const option = {
|
||||
tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' } },
|
||||
legend: { top: 0, textStyle: { color: '#fff' } },
|
||||
grid: { left: '3%', right: '4%', top: '40px', bottom: '5%', },
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: xdata,
|
||||
axisLine: { lineStyle: { type: 'dashed', color: '#435463' } },
|
||||
axisLabel: { color: '#fff' }
|
||||
},
|
||||
yAxis: {
|
||||
name: "电流(A)",
|
||||
type: 'value',
|
||||
nameTextStyle: { color: '#fff' },
|
||||
splitLine: {
|
||||
lineStyle: { type: 'dashed', color: '#435463' }
|
||||
},
|
||||
axisLabel: { color: '#fff', fontSize: 12 },
|
||||
},
|
||||
series: []
|
||||
}
|
||||
this.curList.forEach((item, index) => {
|
||||
option.series.push({
|
||||
name: item.name,
|
||||
index: index,
|
||||
smooth: true,
|
||||
type: 'line',
|
||||
barWidth: 10,
|
||||
itemStyle: { borderRadius: 10, color: item.lineColor },
|
||||
emphasis: { focus: 'series' },
|
||||
global: false,
|
||||
showSymbol: false,
|
||||
data: []
|
||||
})
|
||||
})
|
||||
option && this.myChart.setOption(option)
|
||||
},
|
||||
|
||||
updateChart(activeKey) {
|
||||
if (!this.myChart) {
|
||||
this.initChart()
|
||||
}
|
||||
|
||||
if (this.propsInfo) {
|
||||
let series = []
|
||||
this.propsInfo.forEach((item)=> {
|
||||
if (item.index != undefined && item.index < this.curList.length) {
|
||||
series.push({
|
||||
name: this.curList[item.index].name,
|
||||
data: item.data
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
if (series.length > 0) {
|
||||
this.myChart.setOption({
|
||||
xAxis: { data: this.createChartXData() },
|
||||
series: series
|
||||
});
|
||||
this.setupResizeListener()
|
||||
}
|
||||
}
|
||||
},
|
||||
setupResizeListener() {
|
||||
window.removeEventListener('resize', this.handleResize)
|
||||
window.addEventListener('resize', this.handleResize)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.mychart {
|
||||
height: calc(100% - 35px);
|
||||
|
||||
#chart-current {
|
||||
height: calc(100% - 5px);
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
191
web/src/components/Home/Modal/StationPower.vue
Normal file
191
web/src/components/Home/Modal/StationPower.vue
Normal file
@@ -0,0 +1,191 @@
|
||||
<template>
|
||||
<div class="mychart">
|
||||
<div id="chart-power"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {processData} from '@/utils/dealWithData'
|
||||
|
||||
export default {
|
||||
name: '',
|
||||
props: {
|
||||
propsInfo: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
curList: [
|
||||
{
|
||||
name: '储能设备',
|
||||
key: 'storage_elect_in',
|
||||
lineColor: '#9BD801',
|
||||
value: 0,
|
||||
d: 'kW·h'
|
||||
},
|
||||
{
|
||||
name: '充电设备',
|
||||
key: 'storage_elect_out',
|
||||
lineColor: '#3DFEFA',
|
||||
value: 0,
|
||||
d: 'kW·h'
|
||||
},
|
||||
{
|
||||
name: '光伏设备',
|
||||
key: 'storage_elect_out',
|
||||
lineColor: '#3DFEFA',
|
||||
value: 0,
|
||||
d: 'kW·h'
|
||||
},
|
||||
{
|
||||
name: '电网侧',
|
||||
key: 'storage_elect_out',
|
||||
lineColor: '#3DFEFA',
|
||||
value: 0,
|
||||
d: 'kW·h'
|
||||
}
|
||||
],
|
||||
|
||||
myChart: null,
|
||||
chartData: {
|
||||
ydata: [],
|
||||
xdata: []
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
propsInfo: {
|
||||
handler(newVal, oldVal) {
|
||||
if (JSON.stringify(newVal) !== JSON.stringify(oldVal)) {
|
||||
this.$nextTick(() => {
|
||||
this.updateChart()
|
||||
})
|
||||
}
|
||||
},
|
||||
deep: true // 确保深度比较
|
||||
}
|
||||
},
|
||||
mounted() {},
|
||||
beforeUnmount() {
|
||||
window.removeEventListener('resize', this.handleResize)
|
||||
if (this.myChart) {
|
||||
this.myChart.dispose()
|
||||
this.myChart = null
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
handleResize() {
|
||||
if (this.myChart) {
|
||||
this.myChart.resize()
|
||||
}
|
||||
},
|
||||
|
||||
createChartXData()
|
||||
{
|
||||
const timeArray = [];
|
||||
const dateZero = new Date();
|
||||
dateZero.setHours(0, 0, 0, 0); // 重置为当天0点
|
||||
for (let i=0; i<144; ++i)
|
||||
{
|
||||
// 累加10分钟
|
||||
const currentTime = new Date(dateZero.getTime() + i * 600 * 1000);
|
||||
// 格式化为 HH:mm
|
||||
const hours = currentTime.getHours().toString().padStart(2, '0');
|
||||
const minutes = currentTime.getMinutes().toString().padStart(2, '0');
|
||||
timeArray.push(`${hours}:${minutes}`);
|
||||
}
|
||||
return timeArray
|
||||
},
|
||||
|
||||
initChart() {
|
||||
const chartDom = document.getElementById('chart-power')
|
||||
if (!chartDom) return
|
||||
|
||||
if (this.myChart) this.myChart.dispose()
|
||||
this.myChart = this.$echarts.init(chartDom)
|
||||
|
||||
const xdata = this.createChartXData();
|
||||
const option = {
|
||||
tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' } },
|
||||
legend: { top: 0, textStyle: { color: '#fff' } },
|
||||
grid: { left: '3%', right: '4%', top: '40px', bottom: '5%', },
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: xdata,
|
||||
axisLine: { lineStyle: { type: 'dashed', color: '#435463' } },
|
||||
axisLabel: { color: '#fff' }
|
||||
},
|
||||
yAxis: {
|
||||
name: "功率(kW)",
|
||||
type: 'value',
|
||||
nameTextStyle: { color: '#fff' },
|
||||
splitLine: {
|
||||
lineStyle: { type: 'dashed', color: '#435463' }
|
||||
},
|
||||
axisLabel: { color: '#fff', fontSize: 12 },
|
||||
},
|
||||
series: []
|
||||
}
|
||||
this.curList.forEach((item, index) => {
|
||||
option.series.push({
|
||||
name: item.name,
|
||||
index: index,
|
||||
smooth: true,
|
||||
type: 'line',
|
||||
barWidth: 10,
|
||||
itemStyle: { borderRadius: 10, color: item.lineColor },
|
||||
emphasis: { focus: 'series' },
|
||||
global: false,
|
||||
showSymbol: false,
|
||||
data: []
|
||||
})
|
||||
})
|
||||
option && this.myChart.setOption(option)
|
||||
},
|
||||
|
||||
updateChart(activeKey) {
|
||||
if (!this.myChart) {
|
||||
this.initChart()
|
||||
}
|
||||
|
||||
if (this.propsInfo) {
|
||||
let series = []
|
||||
this.propsInfo.forEach((item)=> {
|
||||
if (item.index != undefined && item.index < this.curList.length) {
|
||||
series.push({
|
||||
name: this.curList[item.index].name,
|
||||
data: item.data
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
if (series.length > 0) {
|
||||
this.myChart.setOption({
|
||||
xAxis: { data: this.createChartXData() },
|
||||
series: series
|
||||
});
|
||||
this.setupResizeListener()
|
||||
}
|
||||
}
|
||||
},
|
||||
setupResizeListener() {
|
||||
window.removeEventListener('resize', this.handleResize)
|
||||
window.addEventListener('resize', this.handleResize)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.mychart {
|
||||
height: calc(100% - 35px);
|
||||
|
||||
#chart-power {
|
||||
height: calc(100% - 5px);
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
178
web/src/components/Home/Modal/StationVoltage.vue
Normal file
178
web/src/components/Home/Modal/StationVoltage.vue
Normal file
@@ -0,0 +1,178 @@
|
||||
<template>
|
||||
<div class="mychart">
|
||||
<div id="chart-voltage"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {processData} from '@/utils/dealWithData'
|
||||
|
||||
export default {
|
||||
name: '',
|
||||
props: {
|
||||
propsInfo: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
curList: [
|
||||
{
|
||||
name: '储能设备',
|
||||
key: 'storage_elect_in',
|
||||
lineColor: '#9BD801',
|
||||
value: 0,
|
||||
d: 'kW·h'
|
||||
},
|
||||
{
|
||||
name: '充电设备',
|
||||
key: 'storage_elect_out',
|
||||
lineColor: '#3DFEFA',
|
||||
value: 0,
|
||||
d: 'kW·h'
|
||||
}
|
||||
],
|
||||
|
||||
myChart: null,
|
||||
chartData: {
|
||||
ydata: [],
|
||||
xdata: []
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
propsInfo: {
|
||||
handler(newVal, oldVal) {
|
||||
if (JSON.stringify(newVal) !== JSON.stringify(oldVal)) {
|
||||
this.$nextTick(() => {
|
||||
this.updateChart()
|
||||
})
|
||||
}
|
||||
},
|
||||
deep: true // 确保深度比较
|
||||
}
|
||||
},
|
||||
mounted() {},
|
||||
beforeUnmount() {
|
||||
window.removeEventListener('resize', this.handleResize)
|
||||
if (this.myChart) {
|
||||
this.myChart.dispose()
|
||||
this.myChart = null
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
handleResize() {
|
||||
if (this.myChart) {
|
||||
this.myChart.resize()
|
||||
}
|
||||
},
|
||||
|
||||
createChartXData()
|
||||
{
|
||||
const timeArray = [];
|
||||
const dateZero = new Date();
|
||||
dateZero.setHours(0, 0, 0, 0); // 重置为当天0点
|
||||
for (let i=0; i<144; ++i)
|
||||
{
|
||||
// 累加10分钟
|
||||
const currentTime = new Date(dateZero.getTime() + i * 600 * 1000);
|
||||
// 格式化为 HH:mm
|
||||
const hours = currentTime.getHours().toString().padStart(2, '0');
|
||||
const minutes = currentTime.getMinutes().toString().padStart(2, '0');
|
||||
timeArray.push(`${hours}:${minutes}`);
|
||||
}
|
||||
return timeArray
|
||||
},
|
||||
|
||||
initChart() {
|
||||
const chartDom = document.getElementById('chart-voltage')
|
||||
if (!chartDom) return
|
||||
|
||||
if (this.myChart) this.myChart.dispose()
|
||||
this.myChart = this.$echarts.init(chartDom)
|
||||
|
||||
const xdata = this.createChartXData();
|
||||
const option = {
|
||||
tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' } },
|
||||
legend: { top: 0, textStyle: { color: '#fff' } },
|
||||
grid: { left: '3%', right: '4%', top: '40px', bottom: '5%', },
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: xdata,
|
||||
axisLine: { lineStyle: { type: 'dashed', color: '#435463' } },
|
||||
axisLabel: { color: '#fff' }
|
||||
},
|
||||
yAxis: {
|
||||
name: '电压(V)',
|
||||
type: 'value',
|
||||
nameTextStyle: { color: '#fff' },
|
||||
splitLine: {
|
||||
lineStyle: { type: 'dashed', color: '#435463' }
|
||||
},
|
||||
axisLabel: { color: '#fff', fontSize: 12 },
|
||||
},
|
||||
series: []
|
||||
}
|
||||
|
||||
this.curList.forEach((item, index) => {
|
||||
option.series.push({
|
||||
name: item.name,
|
||||
index: index,
|
||||
smooth: true,
|
||||
type: 'line',
|
||||
barWidth: 10,
|
||||
itemStyle: { borderRadius: 10, color: item.lineColor },
|
||||
emphasis: { focus: 'series' },
|
||||
global: false,
|
||||
showSymbol: false,
|
||||
data: []
|
||||
})
|
||||
})
|
||||
option && this.myChart.setOption(option)
|
||||
},
|
||||
|
||||
updateChart(activeKey) {
|
||||
if (!this.myChart) {
|
||||
this.initChart()
|
||||
}
|
||||
|
||||
if (this.propsInfo) {
|
||||
let series = []
|
||||
this.propsInfo.forEach((item)=> {
|
||||
if (item.index != undefined && item.index < this.curList.length) {
|
||||
series.push({
|
||||
name: this.curList[item.index].name,
|
||||
data: item.data
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
if (series.length > 0) {
|
||||
this.myChart.setOption({
|
||||
xAxis: { data: this.createChartXData() },
|
||||
series: series
|
||||
});
|
||||
this.setupResizeListener()
|
||||
}
|
||||
}
|
||||
},
|
||||
setupResizeListener() {
|
||||
window.removeEventListener('resize', this.handleResize)
|
||||
window.addEventListener('resize', this.handleResize)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.mychart {
|
||||
height: calc(100% - 35px);
|
||||
|
||||
#chart-voltage {
|
||||
height: calc(100% - 5px);
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
173
web/src/components/Home/MyChartBar.vue
Normal file
173
web/src/components/Home/MyChartBar.vue
Normal file
@@ -0,0 +1,173 @@
|
||||
<template>
|
||||
<div class="mychart">
|
||||
<!-- <div class="text_Cur">
|
||||
<div v-for="item in curList" :key="item.key">
|
||||
<div>{{ item.name }}</div>
|
||||
<span class="mark">{{ item.value ? item.value : 0 }}</span>
|
||||
<span class="d">{{ item.d }}</span>
|
||||
</div>
|
||||
</div> -->
|
||||
<div :id="myChartId" class="mychart"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { processData } from '@/utils/dealWithData'
|
||||
|
||||
export default {
|
||||
name: '',
|
||||
props: {
|
||||
propKey: { type: String, default: '' },
|
||||
propData: { type: Array, default: () => [] },
|
||||
propOption: { type: Object, default: { series: [] } }
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
myChartId: 'mychart' + Math.floor(Math.random() * 9999),
|
||||
myEchart: null,
|
||||
xData: [], // EChart的 x 轴 option
|
||||
yData: [], // EChart的 y 轴 option
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
propData: {
|
||||
handler(newVal, oldVal) {
|
||||
if (JSON.stringify(newVal) !== JSON.stringify(oldVal)) {
|
||||
this.$nextTick(() => {
|
||||
this.drawLineChart()
|
||||
})
|
||||
}
|
||||
},
|
||||
immediate: true, // 初始化时更新
|
||||
deep: true // 确保深度比较
|
||||
},
|
||||
propOption: {
|
||||
handler(newVal, oldVal) {
|
||||
},
|
||||
immediate: true,
|
||||
}
|
||||
},
|
||||
mounted() { },
|
||||
beforeUnmount() {
|
||||
window.removeEventListener('resize', this.handleResize)
|
||||
if (this.myEchart) {
|
||||
this.myEchart.dispose()
|
||||
this.myEchart = null
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
handleResize() {
|
||||
if (this.myEchart) {
|
||||
this.myEchart.resize()
|
||||
}
|
||||
},
|
||||
|
||||
getChartData() {
|
||||
const keyList = this.propOption.series.map((item) => item.key)
|
||||
const result = processData(this.propData, keyList)
|
||||
this.xData = result.dates
|
||||
this.yData = result.values
|
||||
|
||||
if (this.xData.length == 0) {
|
||||
const today = new Date();
|
||||
for (let i = 6; i >= 0; i--) {
|
||||
const date = new Date(today); // 每次创建新日期实例(避免修改原日期)
|
||||
date.setDate(today.getDate() - i); // 往前推 i 天
|
||||
const year = date.getFullYear();
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0'); // 月份 0-11,需 +1
|
||||
const day = String(date.getDate()).padStart(2, '0');
|
||||
this.xData.push(`${month}-${day}`);
|
||||
|
||||
for (let j = 0; j < keyList.length; j++) {
|
||||
if (j == 0) this.yData.push([])
|
||||
else this.yData[j].push(0)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
drawLineChart(activeKey) {
|
||||
|
||||
this.getChartData(activeKey)
|
||||
if (this.myEchart) {
|
||||
this.myEchart.dispose()
|
||||
}
|
||||
const chartDom = document.getElementById(this.myChartId)
|
||||
if (!chartDom) return;
|
||||
let myEchart = this.$echarts.init(chartDom)
|
||||
this.myEchart = myEchart
|
||||
let option = {
|
||||
animation: false,
|
||||
tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' } },
|
||||
legend: { top: 10, textStyle: { color: '#fff' } },
|
||||
grid: { left: '3%', right: '4%', bottom: '1%', top: '32%' },
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: this.xData,
|
||||
axisLine: { lineStyle: { type: 'dashed', color: '#435463' } },
|
||||
axisLabel: { color: '#fff' }
|
||||
},
|
||||
yAxis: [],
|
||||
series: []
|
||||
}
|
||||
|
||||
const yAxisItem = {
|
||||
name: '',
|
||||
type: 'value',
|
||||
min: 0,
|
||||
max: 2,
|
||||
//interval: 1, // 强制步长
|
||||
splitNumber: 2, // 分段数
|
||||
nameTextStyle: { color: '#fff' },
|
||||
splitLine: { lineStyle: { type: 'dashed', color: '#435463' } },
|
||||
axisLabel: { color: '#fff', fontSize: 12 },
|
||||
}
|
||||
|
||||
if (this.propOption.yAxis) {
|
||||
this.propOption.yAxis.forEach((item, index) => {
|
||||
const maxVal = Math.max(...this.yData[index]);
|
||||
if (maxVal && maxVal > 0) {
|
||||
yAxisItem.min = undefined
|
||||
yAxisItem.max = maxVal
|
||||
}
|
||||
yAxisItem.name = item
|
||||
option.yAxis.push(yAxisItem)
|
||||
})
|
||||
}
|
||||
|
||||
if (this.propOption.series) {
|
||||
this.propOption.series.forEach((item, index) => {
|
||||
option.series.push({
|
||||
name: item.name,
|
||||
type: 'bar',
|
||||
color: item.color,
|
||||
data: this.yData[index],
|
||||
barWidth: '20%'
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
if (option.yAxis.length == 0) { option.yAxis.push(yAxisItem) }
|
||||
option && myEchart.setOption(option)
|
||||
this.setupResizeListener()
|
||||
|
||||
},
|
||||
setupResizeListener() {
|
||||
window.removeEventListener('resize', this.handleResize);
|
||||
window.addEventListener('resize', this.handleResize)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.mychart {
|
||||
height: calc(100% - 35px);
|
||||
background-color: #80808010;
|
||||
|
||||
.mychart {
|
||||
height: calc(100% - 5px);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -166,6 +166,7 @@ export default {
|
||||
{
|
||||
name: '收益(元)',
|
||||
type: 'value',
|
||||
splitNumber: 2,
|
||||
splitLine: {
|
||||
lineStyle: { type: 'dashed', color: '#435463' }
|
||||
},
|
||||
@@ -173,7 +174,7 @@ export default {
|
||||
color: '#fff' // 绿色名称
|
||||
},
|
||||
axisLabel: {
|
||||
interval: 4,
|
||||
// interval: 4,
|
||||
color: '#fff',
|
||||
fontSize:12
|
||||
|
||||
@@ -182,6 +183,7 @@ export default {
|
||||
{
|
||||
name: '利用率(%)',
|
||||
type: 'value',
|
||||
splitNumber: 2,
|
||||
nameTextStyle: {
|
||||
color: '#fff' // 绿色名称
|
||||
},
|
||||
@@ -189,10 +191,9 @@ export default {
|
||||
lineStyle: { type: 'dashed', color: '#435463' }
|
||||
},
|
||||
axisLabel: {
|
||||
interval: 4,
|
||||
// interval: 4,
|
||||
color: '#fff',
|
||||
fontSize:12
|
||||
|
||||
},
|
||||
},
|
||||
],
|
||||
@@ -212,7 +213,7 @@ export default {
|
||||
<style lang="scss" scoped>
|
||||
.operational {
|
||||
height: calc(100% - 45px);
|
||||
|
||||
background-color: #50505030;
|
||||
#operational-chart {
|
||||
height: 100%;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="pv">
|
||||
<div class="text_Cur">
|
||||
<!-- <div class="text_Cur">
|
||||
<div v-for="item in curList" :key="item.key">
|
||||
<div>{{ item.name }}</div>
|
||||
<div>
|
||||
@@ -8,7 +8,7 @@
|
||||
<span class="d">{{ item.d }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
<div id="pv-chart"></div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -37,13 +37,13 @@ export default {
|
||||
value: 0,
|
||||
d: 'kW·h'
|
||||
},
|
||||
{
|
||||
name: '入网电量',
|
||||
key: 'solar_elect_grid',
|
||||
lineColor: '#0E68E4',
|
||||
value: 0,
|
||||
d: 'kW·h'
|
||||
}
|
||||
// {
|
||||
// name: '入网电量',
|
||||
// key: 'solar_elect_grid',
|
||||
// lineColor: '#0E68E4',
|
||||
// value: 0,
|
||||
// d: 'kW·h'
|
||||
// }
|
||||
],
|
||||
pvChart: null,
|
||||
pvChartData: {
|
||||
@@ -164,6 +164,7 @@ export default {
|
||||
name: '电量(kW·h)',
|
||||
nameTextStyle: { color: '#fff' },
|
||||
type: 'value',
|
||||
splitNumber: 2,
|
||||
splitLine: {
|
||||
lineStyle: { type: 'dashed', color: '#435463' }
|
||||
},
|
||||
@@ -189,10 +190,10 @@ export default {
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.pv {
|
||||
height: calc(100% - 45px);
|
||||
|
||||
height: calc(100% - 35px);
|
||||
background-color: #50505050;
|
||||
#pv-chart {
|
||||
height: calc(100% - 45px);
|
||||
height: calc(100% - 5px);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
177
web/src/components/Home/TotalStation.vue
Normal file
177
web/src/components/Home/TotalStation.vue
Normal file
@@ -0,0 +1,177 @@
|
||||
<template>
|
||||
<div class="total-station">
|
||||
<div class="content-my">
|
||||
<div v-for="item in myItems" :key="item.key" :class="`item ${item.class}`" >
|
||||
<span style="color:#d0d0d0; margin: 0 0 0 0">{{ item.label }}</span>
|
||||
<div style="margin-left: 20%;">
|
||||
<span :style="{ 'color': item.color, 'font-size':'16px', 'font-weight':600}">{{ item.value ? item.value : (item.d ? 0 : '--') }}</span>
|
||||
<span style="font-size:16px; margin-left: 8px;">{{ item.d }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- <div class="content-left">
|
||||
<div v-for="item in leftList" :key="item.key" :class="`item ${item.class}`">
|
||||
<span>{{ item.label }}</span>
|
||||
<div>
|
||||
<span>{{ item.value ? item.value : 0 }}</span
|
||||
><span class="d">{{ item.d }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
<!-- <div class="online-icon"></div> -->
|
||||
<!-- <div class="content-right">
|
||||
<div v-for="item in rightList" :key="item.key" :class="`item ${item.class}`">
|
||||
<span>{{ item.label }}</span>
|
||||
<div>
|
||||
<span>{{ item.value ? item.value : 0 }}</span
|
||||
><span class="d">{{ item.d }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: '',
|
||||
props: {
|
||||
propKey: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
propData: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
deviceInfo: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
myItems: [
|
||||
{ color:'#a0f0a0', key: 'runDays', value: 0, label:'场站运行天数', d:'天'},
|
||||
// { color:'#a0f0a0', key: 'storage_device_num', value: 0, label:'储能设备数量', d:'个'},
|
||||
// { color:'#a0f0a0', key: 'charge_device_num', value: 0, label:'充电设备数量', d:'个'},
|
||||
// { color:'#a0f0a0', key: 'solar_device_num', value: 0, label:'光伏设备数量', d:'个'},
|
||||
// { color:'#a0f0a0', key: 'solar_elect_grid', value: 0, label:'上网总电量', d:'kWh'},
|
||||
{ color:'#a0f0a0', key: 'storage_elect_in', value: 0, label:'累计储能总电量', d:'kWh'},
|
||||
// { color:'#a0f0a0', key: 'charge_elect_out', value: 0, label:'充电桩充电总电量', d:'kWh'},
|
||||
// { color:'#a0f0a0', key: 'solar_elect_gen', value: 0, label:'光伏发电总电量', d:'kWh'},
|
||||
{ color:'#a0f0a0', key: 'income_elect', value: 0, label:'累计收益总金额', d:'元'},
|
||||
// { color:'#a0f0a0', key: 'storage_elect_out', value: 0, label:'储能放电总电量', d:'kWh'},
|
||||
{ color:'#a0f0a0', key: 'storage_status', value: '空闲', label:'储能状态'},
|
||||
{ color:'#a0f0a0', key: 'charge_status', value: '空闲', label:'充电状态'},
|
||||
{ color:'#a0f0a0', key: 'pv_status', value: '离线', label:'光伏状态'},
|
||||
],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
},
|
||||
|
||||
watch: {
|
||||
propKey: {
|
||||
handler(newVal, oldVal) {
|
||||
// if (this.propKey === 'totalStation') this.myItems[0].label = '场站运行天数'
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
propData: {
|
||||
handler(newVal, oldVal) {
|
||||
if (newVal && newVal !== oldVal) {
|
||||
this.myItems.forEach((item) => {
|
||||
item.value = newVal[item.key] || (item.d ? 0 : '')
|
||||
if (item.value === '离线' || item.value === '故障') item.color = '#f08080'
|
||||
else if (item.value === '空闲') item.color = '#f0f0a0'
|
||||
else if (item.value === '充电' || item.value === '放电' || item.value === '发电') item.color = '#f0f0a0'
|
||||
})
|
||||
}
|
||||
},
|
||||
immediate: true,
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
mounted() {},
|
||||
methods: {}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.total-station {
|
||||
height: calc(100% - 45px);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding-left: 0px;
|
||||
}
|
||||
|
||||
.item {
|
||||
height: calc(50% - 10px);
|
||||
background: url('../../assets//home/onLineBg.png');
|
||||
background-size: contain;
|
||||
background-size: 100% 100%;
|
||||
background-repeat: no-repeat;
|
||||
padding: 8px 3px;
|
||||
min-width: 115px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: #072d42;
|
||||
& > span:nth-child(1) {
|
||||
font-size: 12px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.d {
|
||||
margin-left: 1px;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
.content-my {
|
||||
// background-color: chocolate;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
// align-items: center;
|
||||
justify-content: flex-start;
|
||||
height: 100%;
|
||||
.item {
|
||||
width: calc(33% - 6px);
|
||||
margin-left: 3px;
|
||||
margin-right: 3px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.content-left,
|
||||
.content-right {
|
||||
width: 40%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: space-around;
|
||||
height: 100%;
|
||||
.item {
|
||||
align-items: flex-start;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
.online-icon {
|
||||
width: 20%;
|
||||
height: 130px;
|
||||
background-image: url('@/assets/home/onLineIcon.png');
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
}
|
||||
|
||||
.item-3 {
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.item-4 {
|
||||
margin-left: auto;
|
||||
}
|
||||
</style>
|
||||
@@ -1,6 +1,16 @@
|
||||
<template>
|
||||
<div class="onLine">
|
||||
<div class="content-left">
|
||||
<div class="content-my">
|
||||
<div v-for="item in myItems" :key="item.key" :class="`item ${item.class}`" >
|
||||
<span style="height: 50%; color:#d0d0d0; margin:0 0 0 0">{{ item.label }}</span>
|
||||
<div style="height: 50%; margin-left: 20%;">
|
||||
<span style="color:#a0f0a0; font-size:16px; font-weight:600;">{{ item.value ? item.value : 0 }}</span>
|
||||
<span style="font-size:16px; margin-left: 8px;">{{ item.d }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- <div class="content-left">
|
||||
<div v-for="item in leftList" :key="item.key" :class="`item ${item.class}`">
|
||||
<span>{{ item.label }}</span>
|
||||
<div>
|
||||
@@ -8,9 +18,9 @@
|
||||
><span class="d">{{ item.d }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="online-icon"></div>
|
||||
<div class="content-right">
|
||||
</div> -->
|
||||
<!-- <div class="online-icon"></div> -->
|
||||
<!-- <div class="content-right">
|
||||
<div v-for="item in rightList" :key="item.key" :class="`item ${item.class}`">
|
||||
<span>{{ item.label }}</span>
|
||||
<div>
|
||||
@@ -18,7 +28,7 @@
|
||||
><span class="d">{{ item.d }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -26,11 +36,11 @@
|
||||
export default {
|
||||
name: '',
|
||||
props: {
|
||||
infoKey: {
|
||||
propKey: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
total: {
|
||||
propData: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
@@ -41,13 +51,26 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
myItems: [
|
||||
{ key: 'runDays', value: 0, label:'系统运行天数', d:'天'},
|
||||
{ key: 'storage_device_num', value: 0, label:'储能设备数量', d:'个'},
|
||||
{ key: 'charge_device_num', value: 0, label:'充电设备数量', d:'个'},
|
||||
{ key: 'solar_device_num', value: 0, label:'光伏设备数量', d:'个'},
|
||||
{ key: 'solar_elect_grid', value: 0, label:'上网总电量', d:'kWh'},
|
||||
{ key: 'storage_elect_in', value: 0, label:'储能充电总电量', d:'kWh'},
|
||||
{ key: 'charge_elect_out', value: 0, label:'充电桩充电总电量', d:'kWh'},
|
||||
{ key: 'solar_elect_gen', value: 0, label:'光伏发电总电量', d:'kWh'},
|
||||
{ key: 'income_elect', value: 0, label:'累计收益总金额', d:'元'},
|
||||
{ key: 'storage_elect_out', value: 0, label:'储能放电总电量', d:'kWh'},
|
||||
],
|
||||
|
||||
curList: [
|
||||
{
|
||||
key: 'runDays', //根据launch_date字段计算得出
|
||||
value: 20,
|
||||
d: '天',
|
||||
label: '系统运行天数',
|
||||
class: 'item-1'
|
||||
class: 'item-2'
|
||||
},
|
||||
{
|
||||
key: 'income_total',
|
||||
@@ -97,10 +120,16 @@ export default {
|
||||
},
|
||||
|
||||
watch: {
|
||||
total: {
|
||||
propKey: {
|
||||
handler(newVal, oldVal) {
|
||||
if (this.propKey === 'totalStation') this.myItems[0].label = '场站运行天数'
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
propData: {
|
||||
handler(newVal, oldVal) {
|
||||
if (newVal && newVal !== oldVal) {
|
||||
this.curList.forEach((item) => {
|
||||
this.myItems.forEach((item) => {
|
||||
item.value = newVal[item.key] || 0
|
||||
})
|
||||
}
|
||||
@@ -128,8 +157,8 @@ export default {
|
||||
background-size: contain;
|
||||
background-size: 100% 100%;
|
||||
background-repeat: no-repeat;
|
||||
padding: 10px 8px;
|
||||
min-width: 115px;
|
||||
padding: 3px 3px;
|
||||
// min-width: 100px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: #072d42;
|
||||
@@ -143,6 +172,22 @@ export default {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
.content-my {
|
||||
// background-color: chocolate;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
// align-items: center;
|
||||
justify-content: flex-start;
|
||||
height: 100%;
|
||||
.item {
|
||||
width: calc(25% - 6px);
|
||||
margin-left: 3px;
|
||||
margin-right: 3px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.content-left,
|
||||
.content-right {
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
<template>
|
||||
<div class="device" ref="device">
|
||||
<div class="device-item" v-for="item in deviceList" :key="item">
|
||||
<div class="device" ref="device" :style="{ width: systemType==2 ? '420px': '100%'}">
|
||||
<div class="device-item"
|
||||
v-for="item in deviceList" :key="item.device_id"
|
||||
@click="chooseItem(item)"
|
||||
:class="systemType==2 && selectedDeviceId==item.device_id ? 'active' : ''"
|
||||
:style="{minWidth: systemType==2 ? '420px' : '380px'}"
|
||||
>
|
||||
<div class="item-header">
|
||||
<div style="display: flex; width: 50%">
|
||||
<div class="icon-bg">
|
||||
@@ -9,7 +14,7 @@
|
||||
<div class="title">
|
||||
<span class="number type">{{ item.typename }}</span>
|
||||
<span class="name" :title="item.name">{{ item.name }}</span>
|
||||
<span class="number">{{ item.device_id }}</span>
|
||||
<span class="number"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -18,60 +23,31 @@
|
||||
<a-tag :color="item.is_online == 1 ? 'green' : 'red'">{{
|
||||
['离线', '在线'][item.is_online]
|
||||
}}</a-tag>
|
||||
<span class="text">在线状态</span>
|
||||
</div>
|
||||
<div class="status-item">
|
||||
<a-tag :color="item.is_error == 0 ? 'green' : 'red'">{{
|
||||
['正常', '错误'][item.is_error]
|
||||
}}</a-tag>
|
||||
|
||||
<span class="text">故障状态</span>
|
||||
<!-- <span class="text">在线状态</span> -->
|
||||
</div>
|
||||
<div class="status-item">
|
||||
<a-tag :color="item.is_running == 0 ? 'orange' : 'green'">{{
|
||||
['空闲', '工作'][item.is_running]
|
||||
}}</a-tag>
|
||||
|
||||
<span class="text">工作状态</span>
|
||||
<!-- <span class="text">工作状态</span> -->
|
||||
</div>
|
||||
<div class="status-item">
|
||||
<a-tag :color="item.is_error == 0 ? 'green' : 'red'">{{
|
||||
['正常', '故障'][item.is_error]
|
||||
}}</a-tag>
|
||||
<!-- <span class="text">故障状态</span> -->
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="item-gun" v-if="item.type == 106">
|
||||
<div class="gun">
|
||||
<div class="header">
|
||||
<div class="verline"></div>
|
||||
<span>枪:1</span>
|
||||
</div>
|
||||
<div class="gun-content">
|
||||
<div v-for="info in item.params" :key="info.k" class="gun-info">
|
||||
<span class="text">{{ info.k }}:</span>
|
||||
|
||||
<span class="value">{{ info.v }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gun">
|
||||
<div class="header">
|
||||
<div class="verline"></div>
|
||||
<span>枪:2</span>
|
||||
</div>
|
||||
<div class="gun-content">
|
||||
<div v-for="info in item.params1" :key="info.k" class="gun-info">
|
||||
<span class="text">{{ info.k }}:</span>
|
||||
|
||||
<span class="value">{{ info.v }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item-content" v-else>
|
||||
|
||||
<div class="item-content" v-if="systemType!=2">
|
||||
<div v-for="info in item.params" :key="info.k" class="item-info">
|
||||
<span class="text">{{ info.k }}:</span>
|
||||
|
||||
<span class="value">{{ info.v }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item-button">
|
||||
<div class="item-button" v-if="systemType!=2">
|
||||
<div v-if="item.view == 1">
|
||||
<span class="text">实时数据:</span>
|
||||
<a-button type="primary" size="small" @click="openModal(item, 1)">查看</a-button>
|
||||
@@ -82,54 +58,82 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<a-modal
|
||||
v-model:open="modalOpen"
|
||||
@ok="handleOk"
|
||||
width="60%"
|
||||
class="modal-device"
|
||||
:get-container="() => $refs.device"
|
||||
>
|
||||
<div v-if="modalComponent == 1" class="modal-content">
|
||||
<div class="item">
|
||||
<div class="title">
|
||||
电流电压
|
||||
<!-- <div>电流电压</div>
|
||||
<img src="@/assets/images/titleLine.png" alt="" /> -->
|
||||
</div>
|
||||
<div class="echarts">
|
||||
<predictEcharts
|
||||
:chart-options="chartOptions[0]"
|
||||
:chart-data="chartData"
|
||||
ref="chartRef1"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="title">功率</div>
|
||||
<div class="echarts">
|
||||
<predictEcharts
|
||||
:chart-options="chartOptions[1]"
|
||||
:chart-data="chartData"
|
||||
ref="chartRef2"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="content-table" style="height: 600px" v-else>
|
||||
<a-table
|
||||
:columns="columns"
|
||||
:data-source="tableData"
|
||||
size="small"
|
||||
:scroll="{ y: 500 }"
|
||||
:pagination="false"
|
||||
row-class-name="no-hover-row"
|
||||
row-key="id"
|
||||
>
|
||||
</a-table>
|
||||
</div>
|
||||
</a-modal>
|
||||
</div>
|
||||
<div style="width: calc(100% - 500px);" v-if="systemType==2">
|
||||
<div class="item-gun" >
|
||||
<div class="gun">
|
||||
<div class="header">
|
||||
<div class="verline"></div>
|
||||
<span style="font-size: 16px; font-weight: 1000; color: #5bcdd1">枪:1</span>
|
||||
</div>
|
||||
<div class="gun-content">
|
||||
<div v-for="info in (selectedItem ? selectedItem.params : [])" :key="info.k" class="gun-info">
|
||||
<span class="text">{{ info.k }}:</span>
|
||||
<span class="value">{{ info.v }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gun">
|
||||
<div class="header">
|
||||
<div class="verline"></div>
|
||||
<span style="font-size: 16px; font-weight: 1000; color: #5bcdd1">枪:2</span>
|
||||
</div>
|
||||
<div class="gun-content">
|
||||
<div v-for="info in (selectedItem ? selectedItem.params1 : [])" :key="info.k" class="gun-info">
|
||||
<span class="text">{{ info.k }}:</span>
|
||||
<span class="value">{{ info.v }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<a-modal
|
||||
v-model:open="modalOpen"
|
||||
@ok="handleOk"
|
||||
width="60%"
|
||||
class="modal-device"
|
||||
:get-container="() => $refs.device"
|
||||
>
|
||||
<div v-if="modalComponent == 1" class="modal-content">
|
||||
<div class="item">
|
||||
<div class="title">
|
||||
电流电压
|
||||
<!-- <div>电流电压</div>
|
||||
<img src="@/assets/images/titleLine.png" alt="" /> -->
|
||||
</div>
|
||||
<div class="echarts">
|
||||
<predictEcharts
|
||||
:chart-options="chartOptions[0]"
|
||||
:chart-data="chartData"
|
||||
ref="chartRef1"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="title">功率</div>
|
||||
<div class="echarts">
|
||||
<predictEcharts
|
||||
:chart-options="chartOptions[1]"
|
||||
:chart-data="chartData"
|
||||
ref="chartRef2"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="content-table" style="height: 600px" v-else>
|
||||
<a-table
|
||||
:columns="columns"
|
||||
:data-source="tableData"
|
||||
size="small"
|
||||
:scroll="{ y: 500 }"
|
||||
:pagination="false"
|
||||
row-class-name="no-hover-row"
|
||||
row-key="id"
|
||||
>
|
||||
</a-table>
|
||||
</div>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@@ -147,13 +151,15 @@ export default {
|
||||
systemType: {
|
||||
type: Number,
|
||||
default: 1
|
||||
}
|
||||
},
|
||||
propType: { type: Number, default: 1 }
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
modalOpen: false,
|
||||
deviceList: [],
|
||||
|
||||
selectedDeviceId: undefined,
|
||||
selectedItem: undefined,
|
||||
chartOptions: [
|
||||
{
|
||||
type: 'line',
|
||||
@@ -270,11 +276,16 @@ export default {
|
||||
// 监听父组件数据变化
|
||||
stationId(newVal) {
|
||||
if (newVal) {
|
||||
this.selectedItem = undefined
|
||||
this.selectedDeviceId = undefined
|
||||
this.getDeviceList()
|
||||
}
|
||||
},
|
||||
systemType(newVal, oldVal) {
|
||||
if (newVal !== oldVal) {
|
||||
this.selectedItem = undefined
|
||||
this.selectedDeviceId = undefined
|
||||
this.deviceList = []
|
||||
this.getDeviceList()
|
||||
}
|
||||
}
|
||||
@@ -282,7 +293,7 @@ export default {
|
||||
mounted() {
|
||||
this.getDeviceList()
|
||||
this.timer=setInterval(() => {
|
||||
this.getDeviceList()
|
||||
// this.getDeviceList()
|
||||
}, 20000)
|
||||
|
||||
},
|
||||
@@ -291,6 +302,10 @@ export default {
|
||||
|
||||
},
|
||||
methods: {
|
||||
chooseItem(item) {
|
||||
this.selectedItem = item
|
||||
this.selectedDeviceId = item.device_id
|
||||
},
|
||||
handlePagesizeChange(pageOption) {
|
||||
this.pageOption.pageSize = pageOption.pageSize
|
||||
this.pageOption.page = pageOption.page
|
||||
@@ -313,7 +328,6 @@ export default {
|
||||
// 格式化小时和分钟,确保两位数
|
||||
const formattedHour = hour.toString().padStart(2, '0')
|
||||
const formattedMinute = minute.toString().padStart(2, '0')
|
||||
|
||||
timePoints.push(`${formattedHour}:${formattedMinute}`)
|
||||
}
|
||||
}
|
||||
@@ -363,13 +377,19 @@ export default {
|
||||
//请求运行监控系统设备信息
|
||||
async getDeviceList() {
|
||||
try {
|
||||
|
||||
const res = await getReq('/queryDevicByCategory', {
|
||||
station_id: this.stationId,
|
||||
category: this.systemType
|
||||
})
|
||||
|
||||
if (this.selectedDeviceId == undefined) {
|
||||
if (res.data.length > 0) {
|
||||
this.selectedItem = res.data[0]
|
||||
this.selectedDeviceId = this.selectedItem.device_id
|
||||
}
|
||||
}
|
||||
this.deviceList = res.data
|
||||
|
||||
|
||||
this.$emit('updateGatewayData', res.gateway);
|
||||
} catch (error) {
|
||||
this.deviceList = []
|
||||
@@ -395,12 +415,13 @@ export default {
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.device {
|
||||
// background-color: #08a5ff;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin-left: 20px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
grid-gap: 20px;
|
||||
grid-gap: 15px;
|
||||
overflow-y: auto;
|
||||
align-content: flex-start;
|
||||
// grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
|
||||
@@ -408,10 +429,16 @@ export default {
|
||||
border-radius: 15px;
|
||||
background: $bg2-color;
|
||||
padding: 15px;
|
||||
min-width: 390px;
|
||||
min-width: 380px;
|
||||
max-width: 450px;
|
||||
width: calc(25% - 15px);
|
||||
// height: 260px;
|
||||
flex: 1;
|
||||
// flex: 1;
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
border: 1px solid #aaa;
|
||||
}
|
||||
|
||||
.item-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -491,47 +518,6 @@ export default {
|
||||
height: 24px;
|
||||
}
|
||||
}
|
||||
.item-gun {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 20px;
|
||||
width: 100%;
|
||||
.gun {
|
||||
border: 1px solid #37d6d970;
|
||||
border-radius: 5px;
|
||||
margin: 5px 0;
|
||||
}
|
||||
.header {
|
||||
height: 20px;
|
||||
font-size: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin: 5px;
|
||||
.verline {
|
||||
margin-right: 10px;
|
||||
background: linear-gradient(
|
||||
180deg,
|
||||
rgba(0, 230, 172, 1) 0%,
|
||||
rgba(0, 210, 255, 1) 98.78%,
|
||||
rgba(0, 210, 255, 1) 100%
|
||||
),
|
||||
rgba(1, 223, 239, 1);
|
||||
width: 4px;
|
||||
height: 15px;
|
||||
border-radius: 6px;
|
||||
}
|
||||
}
|
||||
.gun-content {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
height: 120px;
|
||||
padding: 0 5px;
|
||||
overflow-y: auto;
|
||||
.gun-info {
|
||||
height: 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.item-button {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
@@ -550,6 +536,12 @@ export default {
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.active {
|
||||
// background: #012036;
|
||||
border: 1px solid #aaa;
|
||||
}
|
||||
|
||||
.content-table {
|
||||
height: 700px;
|
||||
margin-top: 40px;
|
||||
@@ -564,6 +556,60 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.item-gun {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 20px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
.gun {
|
||||
border: 1px solid #37d6d970;
|
||||
border-radius: 5px;
|
||||
margin: 5px 0;
|
||||
}
|
||||
.header {
|
||||
height: 20px;
|
||||
font-size: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin: 5px;
|
||||
.verline {
|
||||
margin-right: 10px;
|
||||
background: linear-gradient(
|
||||
180deg,
|
||||
rgba(0, 230, 172, 1) 0%,
|
||||
rgba(0, 210, 255, 1) 98.78%,
|
||||
rgba(0, 210, 255, 1) 100%
|
||||
),
|
||||
rgba(1, 223, 239, 1);
|
||||
width: 4px;
|
||||
height: 15px;
|
||||
border-radius: 6px;
|
||||
}
|
||||
}
|
||||
.gun-content {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
height: 200px;
|
||||
padding: 0 5px;
|
||||
overflow-y: auto;
|
||||
.gun-info {
|
||||
height: 30px;
|
||||
|
||||
.text {
|
||||
margin-left: 20px;
|
||||
color: $text-color;
|
||||
font-size: 14px;
|
||||
}
|
||||
.value {
|
||||
font-weight: 700;
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.environment {
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="videosPage" id="videosPage">
|
||||
<!-- <div class="videosPage" id="videosPage">
|
||||
<div
|
||||
class="content"
|
||||
:class="videosPageWidth < 900 ? 'con-w2' : 'con-w1'"
|
||||
@@ -8,9 +8,29 @@
|
||||
>
|
||||
<haikang :index="index" :item="item" class="video"></haikang>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
<div class="environment">
|
||||
<div class="tab-header">
|
||||
<!-- <div style="display: flex; flex-direction: row;"> -->
|
||||
<!-- <div style="background-color: chocolate; width: 24%; height: 100px; margin: 5px 5px 5px 5px;"> </div>
|
||||
<div style="background-color: chocolate; width: 24%; height: 100px; margin: 5px 5px 5px 5px;"> </div>
|
||||
<div style="background-color: chocolate; width: 24%; height: 100px; margin: 5px 5px 5px 5px;"> </div>
|
||||
<div style="background-color: chocolate; width: 24%; height: 100px; margin: 5px 5px 5px 5px;"> </div> -->
|
||||
<div class="env-content">
|
||||
<div v-for="item in tabList" :key="item.key" class="env-item">
|
||||
<div class="tab">
|
||||
<span :class="['uactived']" @click="activeTab = item.key">{{ item.name
|
||||
}}</span>
|
||||
</div>
|
||||
<div class="table-content">
|
||||
<ComTable :columns="columns[item.key]" :table-data="tableDatas[item.key]" ref="comTable"
|
||||
:table-option="{ page: false, select: false }">
|
||||
</ComTable>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- </div> -->
|
||||
|
||||
<!-- <div class="tab-header">
|
||||
<div v-for="item in tabList" :key="item.key" class="tab">
|
||||
<span
|
||||
:class="[activeTab == item.key ? 'actived' : 'uactived']"
|
||||
@@ -27,7 +47,7 @@
|
||||
:table-option="{ page: false, select: false }"
|
||||
>
|
||||
</ComTable>
|
||||
</div>
|
||||
</div> -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -128,15 +148,14 @@ export default {
|
||||
key: 'cooling',
|
||||
name: '冷机信息'
|
||||
},
|
||||
|
||||
{
|
||||
key: 'fire40',
|
||||
name: '消防信息'
|
||||
},
|
||||
{
|
||||
key: 'airc',
|
||||
name: '空调信息'
|
||||
},
|
||||
{
|
||||
key: 'fire40',
|
||||
name: '消防信息'
|
||||
}
|
||||
],
|
||||
tableDatas: {},
|
||||
|
||||
@@ -161,9 +180,9 @@ export default {
|
||||
},
|
||||
mounted() {
|
||||
this.$nextTick(() => {
|
||||
const div = document.getElementById('videosPage')
|
||||
const width = div.offsetWidth
|
||||
this.videosPageWidth = width
|
||||
// const div = document.getElementById('videosPage')
|
||||
// const width = div.offsetWidth
|
||||
// this.videosPageWidth = width
|
||||
})
|
||||
|
||||
this.getEnvironment()
|
||||
@@ -233,10 +252,42 @@ export default {
|
||||
}
|
||||
}
|
||||
.environment {
|
||||
width: 430px;
|
||||
width: 100%; //430px;
|
||||
margin-left: 20px;
|
||||
color: #fff;
|
||||
|
||||
|
||||
.env-content {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
.env-item {
|
||||
width: 24%;
|
||||
|
||||
.tab {
|
||||
&>span {
|
||||
font-size: 14px;
|
||||
margin-right: 15px;
|
||||
display: inline-block;
|
||||
padding: 10px;
|
||||
// cursor: pointer;
|
||||
border: 1px solid $tab-border;
|
||||
border-radius: 4px;
|
||||
text-align: center;
|
||||
width: 50%;
|
||||
}
|
||||
}
|
||||
.actived {
|
||||
color: #ffffff;
|
||||
background-color: $green;
|
||||
}
|
||||
.uactived {
|
||||
color: #a6b8dd;
|
||||
background-color: $bg2-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 24px;
|
||||
font-weight: 700;
|
||||
@@ -291,6 +342,7 @@ export default {
|
||||
}
|
||||
.table-content {
|
||||
margin-top: 20px;
|
||||
margin-right: 10px;
|
||||
height: calc(100% - 60px);
|
||||
:deep(.ant-table) {
|
||||
border-radius: 10px 10px 0 0 !important;
|
||||
|
||||
@@ -128,6 +128,7 @@ export default {
|
||||
getCommonOption(option, dataKeys, isLineChart = false) {
|
||||
console.log(option,"ooooooooooooo")
|
||||
return {
|
||||
animation: false,
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: { type: 'shadow' },
|
||||
@@ -197,9 +198,9 @@ export default {
|
||||
series: option.infoKeys.map((info, i) => ({
|
||||
name: info.label,
|
||||
type: 'bar',
|
||||
barWidth: 10,
|
||||
barWidth: '20%',
|
||||
itemStyle: {
|
||||
borderRadius: [10, 10, 0, 0],
|
||||
borderRadius: [0, 0, 0, 0],
|
||||
color: info.lineColor,
|
||||
},
|
||||
index:option.yAxisOption&&option.yAxisOption.length?i:1,
|
||||
|
||||
@@ -8,9 +8,9 @@ export function getRunDays(date) {
|
||||
return daysRun
|
||||
}
|
||||
export function processData(data, keys) {
|
||||
data.sort((a, b) => {
|
||||
return new Date(a.dt) - new Date(b.dt)
|
||||
})
|
||||
// data.sort((a, b) => {
|
||||
// return new Date(a.dt) - new Date(b.dt)
|
||||
// })
|
||||
const dates = data.map((item) => item.dt)
|
||||
const values = []
|
||||
keys.forEach((item, index) => {
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
>{{ station.name }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
<a-button type="primary" @click="handleMessage" style="margin-left: 20px">查看预制舱参数</a-button>
|
||||
<a-button type="primary" @click="openDispatchModeModal" style="margin-left: 20px">模式设置</a-button>
|
||||
<a-button type="primary" @click="openDispatchParamModal" style="margin-left: 20px">参数设置</a-button>
|
||||
<a-button type="primary" @click="handleMessage" style="margin-left: 20px">运行参数查看</a-button>
|
||||
<a-button type="primary" @click="openDispatchModeModal" style="margin-left: 20px">运行模式设置</a-button>
|
||||
<a-button type="primary" @click="openDispatchParamModal" style="margin-left: 20px">运行参数设置</a-button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="right">
|
||||
@@ -133,11 +133,11 @@ export default {
|
||||
msgModal: false,
|
||||
systems: [
|
||||
{
|
||||
name: '储能系统',
|
||||
name: '储能设备',
|
||||
titles: [
|
||||
{ v: '运行模式', key: 'workmode' },
|
||||
{ v: '储能EMU状态', key: 'emu' },
|
||||
{ v: '充电桩状态', key: 'cdz' }
|
||||
// { v: '运行模式', key: 'workmode' },
|
||||
// { v: '储能EMU状态', key: 'emu' },
|
||||
// { v: '充电桩状态', key: 'cdz' }
|
||||
//{ v: '总有功功率(台区)', key: 'power', sufix: 'kW' }
|
||||
],
|
||||
power: 60,
|
||||
@@ -145,33 +145,33 @@ export default {
|
||||
systemType: 1
|
||||
},
|
||||
{
|
||||
name: '充电系统',
|
||||
name: '充电设备',
|
||||
power: 60,
|
||||
num: 62,
|
||||
systemType: 2,
|
||||
titles: [
|
||||
//{ v: '总功率', key: 'power', sufix: 'kW' },
|
||||
{ v: '数量', key: 'num' }
|
||||
// { v: '数量', key: 'num' }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: '光伏系统',
|
||||
name: '光伏设备',
|
||||
power: 60,
|
||||
num: 62,
|
||||
systemType: 3,
|
||||
titles: [
|
||||
//{ v: '总功率', key: 'power', sufix: 'kW' },
|
||||
{ v: '数量', key: 'num' }
|
||||
// { v: '数量', key: 'num' }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: '安防系统',
|
||||
name: '辅助设备',
|
||||
power: 60,
|
||||
num: 62,
|
||||
systemType: 4,
|
||||
titles: [
|
||||
// { v: '总功率', key: 'power', sufix: 'kW' },
|
||||
{ v: '数量', key: 'num' }
|
||||
// { v: '数量', key: 'num' }
|
||||
]
|
||||
}
|
||||
// {
|
||||
@@ -203,7 +203,7 @@ export default {
|
||||
},
|
||||
{
|
||||
value: 5,
|
||||
label: '自定时段'
|
||||
label: '运营支撑'
|
||||
}
|
||||
],
|
||||
deviceGroup: [],
|
||||
@@ -224,7 +224,7 @@ export default {
|
||||
{ value: '2', label: '配网增容' },
|
||||
{ value: '3', label: '应急供电' },
|
||||
{ value: '4', label: '并网保电' },
|
||||
{ value: '5', label: '自定时段' }
|
||||
{ value: '5', label: '运营支撑' }
|
||||
],
|
||||
options: { label: 'label', value: 'value' }
|
||||
}
|
||||
@@ -509,7 +509,6 @@ export default {
|
||||
|
||||
chooseStation(system) {
|
||||
console.log(system, 'system')
|
||||
|
||||
this.systemType = system.systemType
|
||||
}
|
||||
}
|
||||
@@ -551,40 +550,43 @@ export default {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
.stations {
|
||||
display: grid;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
//grid-template-rows: repeat(auto-fit, minmax(140px, 4fr));
|
||||
border-radius: 12px;
|
||||
background: $bg2-color;
|
||||
padding-top: 15px;
|
||||
grid-template-rows: repeat(auto-fit, minmax(140px, 4fr));
|
||||
.station-item {
|
||||
flex: 1;
|
||||
// flex: 1;
|
||||
margin: 0 15px 15px 15px;
|
||||
border-radius: 12px;
|
||||
border-radius: 10px;
|
||||
width: 180px;
|
||||
height: 50px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
color: #fff;
|
||||
padding: 10px 10px;
|
||||
// color: #fff;
|
||||
// padding: 10px 10px;
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
background: $table-bg;
|
||||
}
|
||||
|
||||
.name {
|
||||
padding-left: 20px;
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
line-height: 50px;
|
||||
}
|
||||
.des {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
line-height: 30px;
|
||||
display: inline-block;
|
||||
max-width: 160px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
// .des {
|
||||
// font-size: 14px;
|
||||
// font-weight: 600;
|
||||
// line-height: 30px;
|
||||
// display: inline-block;
|
||||
// max-width: 160px;
|
||||
// white-space: nowrap;
|
||||
// overflow: hidden;
|
||||
// text-overflow: ellipsis;
|
||||
// }
|
||||
}
|
||||
.active {
|
||||
background: $bg3-color;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="Home">
|
||||
<div class="content-left">
|
||||
<div v-for="item in leftList" :key="item.componentId" :class="`grid-item ${item.class}`">
|
||||
<div v-for="item in listLeft" :key="item.componentId" :class="`grid-item ${item.class}`">
|
||||
<div class="tool">
|
||||
<div class="title">
|
||||
<i class="iconfont icon-hebing linear-text"></i>
|
||||
@@ -9,30 +9,32 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<component
|
||||
:is="item.componentId"
|
||||
:info-key="item.infoKey"
|
||||
:device-info="deviceInfo[item.infoKey]"
|
||||
:total="item.infoKey === 'onLineTotal' ? deviceInfo.onLine : deviceInfo.allTotal"
|
||||
></component>
|
||||
<component :is="item.componentId" :prop-key="item.infoKey" :prop-option="compInfo[item.infoKey]"
|
||||
:prop-data="compData[item.infoKey]">
|
||||
</component>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tianditu">
|
||||
<Map @changeStation="getCurrentStation"></Map>
|
||||
</div>
|
||||
<div class="content-right">
|
||||
<div v-for="item in rightList" :key="item.componentId" :class="`grid-item ${item.class}`">
|
||||
<div style="width:100%; height:32px;">
|
||||
<span style="width:120px">场站选择</span>
|
||||
<a-select v-model:value="selectStationId" style="margin-left: 10px; width: 200px;" @change="getStationChange">
|
||||
<a-select-option v-for="station in stationList" :value="station['station_id']">{{ station.name }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</div>
|
||||
<div v-for="item in listRight" :key="item.componentId" :class="`grid-item ${item.class}`">
|
||||
<div class="tool">
|
||||
<div class="title">
|
||||
<i class="iconfont icon-hebing linear-text"></i>
|
||||
<span class="linear-text">{{ item.title }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<component
|
||||
:is="item.componentId"
|
||||
:device-info="deviceInfo[item.infoKey]"
|
||||
:total="item.infoKey === 'onLineTotal' ? deviceInfo.onLine : deviceInfo.allTotal"
|
||||
></component>
|
||||
<component :is="item.componentId" :prop-key="item.infoKey" :prop-option="compInfo[item.infoKey]"
|
||||
:prop-data="compDataStation[item.infoKey]">
|
||||
</component>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -40,12 +42,14 @@
|
||||
|
||||
<script>
|
||||
import onLine from '@/components/Home/onLine.vue'
|
||||
import TotalStation from '@/components/Home/TotalStation.vue'
|
||||
import Operational from '@/components/Home/Operational.vue'
|
||||
import Energy from '@/components/Home/Energy.vue'
|
||||
import Charge from '@/components/Home/Charge.vue'
|
||||
import Pv from '@/components/Home/Pv.vue'
|
||||
import Alarm from '@/components/Home/Alarm.vue'
|
||||
import Map from '@/components/Home/Map.vue'
|
||||
import MyChartBar from '@/components/Home/MyChartBar.vue'
|
||||
import { getReq, postReq } from '@/request/api'
|
||||
import { getRunDays, getDateDaysAgo } from '@/utils/dealWithData'
|
||||
import { markRaw } from 'vue'
|
||||
@@ -54,13 +58,70 @@ export default {
|
||||
components: { Map },
|
||||
data() {
|
||||
return {
|
||||
refreshInterval:null,
|
||||
refreshInterval: null,
|
||||
showFlag: false,
|
||||
stationId: null,
|
||||
deviceInfo: {},
|
||||
compData: {
|
||||
total: {},
|
||||
energy: [],
|
||||
charge: [],
|
||||
pv: [],
|
||||
stateGrid: [],
|
||||
},
|
||||
compDataStation: {
|
||||
totalStation: {},
|
||||
energy: [],
|
||||
charge: [],
|
||||
pv: [],
|
||||
stateGrid: [],
|
||||
},
|
||||
compInfo: {
|
||||
total: {},
|
||||
energy: {
|
||||
yAxis: ['电量(kWh)'],
|
||||
series: [
|
||||
{ name: '日充电电量', key: 'storage_elect_in', color: '#22E4FF' },
|
||||
{ name: '日放电电量', key: 'storage_elect_out', color: '#0E68E4' },
|
||||
]
|
||||
},
|
||||
pv: {
|
||||
yAxis: ['电量(kWh)'],
|
||||
series: [
|
||||
{ name: '日发电电量', key: 'solar_elect_gen', color: '#22E4FF' },
|
||||
]
|
||||
},
|
||||
charge: {
|
||||
yAxis: ['电量(kWh)'],
|
||||
series: [
|
||||
{ name: '日充电电量', key: 'charge_elect', color: '#22E4FF' },
|
||||
]
|
||||
},
|
||||
stateGrid: {
|
||||
yAxis: ['电量(kWh)'],
|
||||
series: [
|
||||
{ name: '日上网电量', key: 'solar_elect_grid', color: '#22E4FF' },
|
||||
]
|
||||
}
|
||||
},
|
||||
listLeft: [
|
||||
{ title: '系统运行统计', class: 'online-status', componentId: markRaw(onLine), infoKey: 'total' },
|
||||
{ title: '储能设备', class: 'energy-status', componentId: markRaw(MyChartBar), infoKey: 'energy' },
|
||||
{ title: '充电设备', class: 'charge-analysis', componentId: markRaw(MyChartBar), infoKey: 'charge' },
|
||||
{ title: '光伏设备', class: 'work-order', componentId: markRaw(MyChartBar), infoKey: 'pv' },
|
||||
{ title: '电网侧', class: 'work-order', componentId: markRaw(MyChartBar), infoKey: 'stateGrid' },
|
||||
],
|
||||
listRight: [
|
||||
{ title: '场站运行统计', class: 'online-status', componentId: markRaw(TotalStation), infoKey: 'totalStation' },
|
||||
{ title: '储能设备', class: 'energy-status', componentId: markRaw(MyChartBar), infoKey: 'energy' },
|
||||
{ title: '充电设备', class: 'charge-analysis', componentId: markRaw(MyChartBar), infoKey: 'charge' },
|
||||
{ title: '光伏设备', class: 'work-order', componentId: markRaw(MyChartBar), infoKey: 'pv' },
|
||||
{ title: '电网侧', class: 'work-order', componentId: markRaw(MyChartBar), infoKey: 'stateGrid' },
|
||||
],
|
||||
stationList: [],
|
||||
selectStationId: '',
|
||||
list: [
|
||||
{
|
||||
title: '运行状态',
|
||||
title: '系统运行统计',
|
||||
class: 'online-status',
|
||||
componentId: markRaw(onLine),
|
||||
infoKey: 'onLineTotal'
|
||||
@@ -83,7 +144,6 @@ export default {
|
||||
componentId: markRaw(Charge),
|
||||
infoKey: 'charge'
|
||||
},
|
||||
|
||||
{
|
||||
title: '光伏设备',
|
||||
class: 'work-order',
|
||||
@@ -104,93 +164,96 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
leftList() {
|
||||
return this.list.filter((_, index) => index % 2 === 0).slice(0, 3) // 左列取前3个偶数索引
|
||||
return {} //this.list.filter((_, index) => index % 2 === 0).slice(0, 3) // 左列取前3个偶数索引
|
||||
},
|
||||
rightList() {
|
||||
return this.list.filter((_, index) => index % 2 !== 0).slice(0, 3) // 右列取前3个奇数索引
|
||||
return {} //this.list.filter((_, index) => index % 2 !== 0).slice(0, 3) // 右列取前3个奇数索引
|
||||
}
|
||||
},
|
||||
beforeUnmount() {
|
||||
if(this.refreshInterval){
|
||||
if (this.refreshInterval) {
|
||||
clearInterval(this.refreshInterval)
|
||||
this.refreshInterval=null
|
||||
this.refreshInterval = null
|
||||
}
|
||||
},
|
||||
async mounted() {
|
||||
await this.getStationList()
|
||||
await this.loadAllData()
|
||||
this.refreshInterval=setInterval(async()=>{
|
||||
this.refreshInterval = setInterval(async () => {
|
||||
await this.loadAllData()
|
||||
},30000) //30s刷新一次
|
||||
|
||||
}, 30000) //30s刷新一次
|
||||
|
||||
},
|
||||
|
||||
methods: {
|
||||
async loadAllData(){
|
||||
async loadAllData() {
|
||||
await Promise.all([
|
||||
this.getOnLineList(),
|
||||
this.getStatTotalList(),
|
||||
this.getOperTotalList(),
|
||||
this.getStatDayList(1),
|
||||
this.getStatDayList(2),
|
||||
this.getStatDayList(3)
|
||||
this.queryStatTotal(),
|
||||
this.queryStatTotal(this.selectStationId),
|
||||
// this.getOperTotalList(),
|
||||
this.getStatDayList(),
|
||||
this.getStatDayList(this.selectStationId),
|
||||
// this.getStatDayList(1),
|
||||
// this.getStatDayList(2),
|
||||
// this.getStatDayList(3)
|
||||
]).then((r) => {
|
||||
if (
|
||||
this.deviceInfo.energy &&
|
||||
this.deviceInfo.charge &&
|
||||
this.deviceInfo.pv
|
||||
) {
|
||||
const newArr = this.mergedArray(
|
||||
this.deviceInfo.energy,
|
||||
this.deviceInfo.charge,
|
||||
this.deviceInfo.pv
|
||||
)
|
||||
this.deviceInfo.alarm = newArr
|
||||
}
|
||||
// if (
|
||||
// this.compData.energy &&
|
||||
// this.compData.charge &&
|
||||
// this.compData.pv
|
||||
// ) {
|
||||
// const newArr = this.mergedArray(
|
||||
// this.compData.energy,
|
||||
// this.compData.charge,
|
||||
// this.compData.pv
|
||||
// )
|
||||
// this.compData.alarm = newArr
|
||||
// }
|
||||
})
|
||||
},
|
||||
getCurrentStation(e) {
|
||||
this.stationId = e
|
||||
},
|
||||
// 查询系统统计信息
|
||||
async getOnLineList() {
|
||||
// 查询系统的场站列表
|
||||
async getStationList() {
|
||||
try {
|
||||
// token: 用户TOKEN
|
||||
const res = await getReq('/queryStatSystem')
|
||||
const res = await getReq('/queryStationList', { page: 0, page_size: 100 })
|
||||
if (res.errcode === 0) {
|
||||
this.deviceInfo.onLine = JSON.parse(JSON.stringify(res.data))
|
||||
this.deviceInfo.onLine.runDays = getRunDays(res.data.launch_date)
|
||||
// 设置场站下拉列表,默认选中第一项
|
||||
this.stationList = res.data
|
||||
this.selectStationId = this.stationList[0]['station_id']
|
||||
} else {
|
||||
throw res
|
||||
}
|
||||
} catch (error) {
|
||||
this.deviceInfo.onLine = {}
|
||||
this.stationList = []
|
||||
this.selectStationId = ''
|
||||
}
|
||||
},
|
||||
|
||||
// 查询系统累计统计信息
|
||||
async getStatTotalList() {
|
||||
// 查询系统累计统计信息, 不传参数 curStationId 时查询所有场站数据
|
||||
async queryStatTotal(curStationId) {
|
||||
|
||||
try {
|
||||
// token: 用户TOKEN
|
||||
// date:日期
|
||||
// station_id:场站ID,为0或不传查询所有场站总计
|
||||
// category:类别,1:储能设备,2:充电设备,3:光伏设备,为0或不传查询所有类别总计
|
||||
const query = {
|
||||
date: getDateDaysAgo(0),
|
||||
station_id: this.stationId,
|
||||
category: 0
|
||||
}
|
||||
const res = await getReq('/queryStatTotal', query)
|
||||
const res = await getReq('/queryStatTotal', { station_id: curStationId })
|
||||
if (res.errcode === 0) {
|
||||
this.deviceInfo.allTotal = res.data
|
||||
const { income_charge: incomeCharge, income_elect: incomeElect } =
|
||||
this.deviceInfo.allTotal
|
||||
this.deviceInfo.allTotal.incomeTotal = +incomeCharge + +incomeElect
|
||||
// this.compData.total = res.data
|
||||
// const { income_charge: incomeCharge, income_elect: incomeElect } =
|
||||
// this.compData.total
|
||||
// this.compData.total.incomeTotal = +incomeCharge + +incomeElect
|
||||
// this.compData.total.runDays = getRunDays(res.data.launch_date)
|
||||
if (curStationId === undefined) {
|
||||
this.compData.total = res.data
|
||||
this.compData.total.runDays = getRunDays(res.data.launch_date)
|
||||
} else {
|
||||
this.compDataStation.totalStation = res.data
|
||||
this.compDataStation.totalStation.runDays = getRunDays(res.data.launch_date)
|
||||
}
|
||||
} else {
|
||||
throw res
|
||||
}
|
||||
} catch (error) {
|
||||
this.deviceInfo.allTotal = {}
|
||||
this.deviceInfo.allTotal.incomeTotal = 0
|
||||
this.compData.total = {}
|
||||
this.compData.total.incomeTotal = 0
|
||||
}
|
||||
},
|
||||
// 运行分析 联调
|
||||
@@ -198,35 +261,56 @@ export default {
|
||||
try {
|
||||
const res = await getReq('/queryStatStation', {})
|
||||
if (res.errcode === 0) {
|
||||
this.deviceInfo.operationTotal = res.data
|
||||
this.compData.operationTotal = res.data
|
||||
} else {
|
||||
throw res
|
||||
}
|
||||
} catch (error) {
|
||||
this.deviceInfo.operationTotal = [ ]
|
||||
this.compData.operationTotal = []
|
||||
}
|
||||
},
|
||||
|
||||
// 示例:获取7天前的日期
|
||||
// 查询场站日统计信息
|
||||
async getStatDayList(category) {
|
||||
|
||||
// 查询近7日的统计信息,
|
||||
async getStatDayList(curStationId) {
|
||||
try {
|
||||
if (curStationId === '') {
|
||||
return
|
||||
}
|
||||
// station_id: 场站ID
|
||||
// category: 类别: 1:储能设备,2:充电设备,3:光伏设备
|
||||
// start_date:开始日期,格式:yyyy-mm-dd
|
||||
// end_date:结束日期,格式:yyyy-mm-dd
|
||||
const query = {
|
||||
station_id: this.stationId,
|
||||
category,
|
||||
let query = {
|
||||
//station_id: this.stationId,
|
||||
// category,
|
||||
start_date: getDateDaysAgo(7 - 1),
|
||||
end_date: getDateDaysAgo(0)
|
||||
}
|
||||
const arr = { 1: 'energy', 2: 'charge', 3: 'pv' }
|
||||
if (curStationId) {
|
||||
query.station_id = curStationId
|
||||
}
|
||||
//const arr = { 1: 'energy', 2: 'charge', 3: 'pv' }
|
||||
const res = await getReq('/queryStatDayList', query)
|
||||
if (res.errcode === 0) {
|
||||
this.list.forEach((item) => {
|
||||
this.deviceInfo[arr[category]] = res.data
|
||||
})
|
||||
if (curStationId) {
|
||||
this.compDataStation.energy
|
||||
= this.compDataStation.charge
|
||||
= this.compDataStation.pv
|
||||
= this.compDataStation.stateGrid
|
||||
= res.data
|
||||
} else {
|
||||
this.compData.energy
|
||||
= this.compData.pv
|
||||
= this.compData.stateGrid
|
||||
= this.compData.charge
|
||||
= res.data
|
||||
}
|
||||
// this.list.forEach((item) => {
|
||||
// //this.compData[arr[category]] = res.data
|
||||
// alert(JSON.stringify(item))
|
||||
// return
|
||||
// })
|
||||
} else {
|
||||
throw res
|
||||
}
|
||||
@@ -251,6 +335,10 @@ export default {
|
||||
})
|
||||
})
|
||||
return newArr
|
||||
},
|
||||
getStationChange() {
|
||||
this.queryStatTotal(this.selectStationId),
|
||||
this.getStatDayList(this.selectStationId)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -278,13 +366,13 @@ export default {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.grid-item {
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
height: calc(33% - 10px);
|
||||
height: calc(25% - 10px);
|
||||
z-index: 20;
|
||||
|
||||
.tool {
|
||||
@@ -295,7 +383,7 @@ export default {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
height: 45px;
|
||||
height: 32px;
|
||||
|
||||
.linear-text {
|
||||
background: linear-gradient(180deg, rgba(255, 255, 255, 1) 0%, rgba(40, 235, 231, 1) 100%);
|
||||
@@ -335,12 +423,10 @@ export default {
|
||||
margin-left: 20px;
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
rgba(0, 186, 173, 0.15) 0%,
|
||||
rgba(61, 254, 250, 0.15) 49.2%,
|
||||
rgba(61, 254, 250, 0) 100%
|
||||
);
|
||||
background: linear-gradient(90deg,
|
||||
rgba(0, 186, 173, 0.15) 0%,
|
||||
rgba(61, 254, 250, 0.15) 49.2%,
|
||||
rgba(61, 254, 250, 0) 100%);
|
||||
-webkit-background-clip: text;
|
||||
display: inline-block;
|
||||
background-clip: text;
|
||||
|
||||
@@ -2,30 +2,38 @@
|
||||
<div class="device">
|
||||
<searchBox :btn-option-list="btnOptionList" @operateForm="operateForm"></searchBox>
|
||||
|
||||
<div class="content-table">
|
||||
<ComTable
|
||||
:columns="columns"
|
||||
:table-data="tableData"
|
||||
@handlePagesizeChange="handlePagesizeChange"
|
||||
ref="comTable"
|
||||
:table-option="tableOption"
|
||||
:page-option="pageOption"
|
||||
>
|
||||
<template #type="record">
|
||||
<span>{{ getType(record.type) }}</span>
|
||||
</template>
|
||||
<template #isEnable="record">
|
||||
<span
|
||||
><a-tag :color="record.is_open == 1 ? 'green' : 'red'">{{
|
||||
record.is_open == 1 ? '启用' : '禁用'
|
||||
}}</a-tag></span
|
||||
>
|
||||
</template>
|
||||
<div style="display: flex; height: calc(100% - 40px); ">
|
||||
<div style="display: block; min-width:200px; width: 200px; height: 100%; overflow-y: auto; background-color: #08365c; border-radius: 5px; padding-top: 10px;">
|
||||
<a-tree v-model:expandedKeys="expandedKeys" v-model:selectedKeys="selectedKeys"
|
||||
v-model:checkedKeys="checkedKeys" :tree-data="stationTreeData" @select="onSelectStation">
|
||||
</a-tree>
|
||||
</div>
|
||||
|
||||
<template #action="record">
|
||||
<OperateCom :record="record" :operate-list="operateList" @operateForm="operateForm" />
|
||||
</template>
|
||||
</ComTable>
|
||||
<div class="content-table">
|
||||
<ComTable
|
||||
:columns="columns"
|
||||
:table-data="tableData"
|
||||
@handlePagesizeChange="handlePagesizeChange"
|
||||
ref="comTable"
|
||||
:table-option="tableOption"
|
||||
:page-option="pageOption"
|
||||
>
|
||||
<template #type="record">
|
||||
<span>{{ getType(record.type) }}</span>
|
||||
</template>
|
||||
<template #isEnable="record">
|
||||
<span
|
||||
><a-tag :color="record.is_open == 1 ? 'green' : 'red'">{{
|
||||
record.is_open == 1 ? '启用' : '禁用'
|
||||
}}</a-tag></span
|
||||
>
|
||||
</template>
|
||||
|
||||
<template #action="record">
|
||||
<OperateCom :record="record" :operate-list="operateList" @operateForm="operateForm" />
|
||||
</template>
|
||||
</ComTable>
|
||||
</div>
|
||||
</div>
|
||||
<a-modal v-model:open="formModal" width="750px" style="top: 80px" :footer="null">
|
||||
<!-- action:edit add -->
|
||||
@@ -75,7 +83,9 @@ export default {
|
||||
paramsDate: {},
|
||||
tableData: [],
|
||||
tableOption: {},
|
||||
stations: [] //场站列表
|
||||
stations: [], //场站列表
|
||||
stationTreeData: [],
|
||||
selectedStationId: undefined
|
||||
}
|
||||
},
|
||||
computed: {},
|
||||
@@ -93,8 +103,8 @@ export default {
|
||||
mounted() {
|
||||
this.operateList = this.$getBtns(['查看', '修改', '删除'])
|
||||
this.btnOptionList = this.$getBtns(['新增'])
|
||||
this.getList()
|
||||
this.getStations()
|
||||
//this.getList()
|
||||
},
|
||||
|
||||
methods: {
|
||||
@@ -103,8 +113,11 @@ export default {
|
||||
this.stations = []
|
||||
try {
|
||||
const res = await getReq('/queryStationList', { page: 0, page_size: 10000 })
|
||||
|
||||
this.stations = res.data
|
||||
this.stationTreeData = []
|
||||
res.data.forEach((item)=>{
|
||||
this.stationTreeData.push( { title: item.name, key: item.station_id})
|
||||
})
|
||||
} catch (error) {
|
||||
this.stations = []
|
||||
}
|
||||
@@ -122,6 +135,7 @@ export default {
|
||||
const { page, pageSize } = this.pageOption
|
||||
|
||||
const params = {
|
||||
station_id: this.selectedStationId,
|
||||
...this.paramsDate,
|
||||
page_size: pageSize,
|
||||
page
|
||||
@@ -216,6 +230,10 @@ export default {
|
||||
this.pageOption.pageSize = pageOption.pageSize
|
||||
this.pageOption.page = pageOption.page
|
||||
this.getList()
|
||||
},
|
||||
onSelectStation(selectedKey, ) {
|
||||
this.selectedStationId = selectedKey
|
||||
this.getList()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -229,6 +247,26 @@ export default {
|
||||
.content-table {
|
||||
width: 100%;
|
||||
height: calc(100% - 52px);
|
||||
margin-left: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
:deep(.ant-tree-list) {
|
||||
background-color: #08365c;
|
||||
font-size: 16px;
|
||||
color: white;
|
||||
}
|
||||
:deep(.ant-tree-treenode ) {
|
||||
width: 100%;
|
||||
height: 30px;
|
||||
}
|
||||
:deep(.ant-tree-node-content-wrapper) {
|
||||
width: calc(100% - 34px);
|
||||
height: 30px;
|
||||
}
|
||||
:deep(.ant-tree-node-selected) {
|
||||
background-color: #27a188 !important;
|
||||
border-radius: 5px !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user