This commit is contained in:
2025-08-11 17:34:39 +08:00
parent 7a13a73758
commit 9db3b4f9f7
9 changed files with 342 additions and 127 deletions

View File

@ -0,0 +1,94 @@
<template>
<div class="time-range">
<el-date-picker
v-model="dateRange"
type="daterange"
range-separator=""
start-placeholder="开始时间"
value-format="yyyy-MM-dd"
:clearable="false"
:picker-options="pickerOptions"
end-placeholder="结束时间">
</el-date-picker>
<el-button type="default" size="mini" style="margin-left: 10px;" :loading="loading" @click="reset">重置</el-button>
<el-button type="primary" size="mini" :loading="loading" @click="search">搜索</el-button>
<el-button type="primary" size="mini" :loading="loading" @click="timeLine('before')">上一时段</el-button>
<el-button type="primary" size="mini" :loading="loading" @click="timeLine('next')" :disabled="disabledNextBtn">下一时段</el-button>
</div>
</template>
<script>
import {formatDate} from '@/filters/ems'
export default {
computed:{
disabledNextBtn(){
return new Date(this.dateRange[1]) >= new Date(this.defaultDateRange[1])
}
},
data() {
return {
loading:false,
dateRange:[],
defaultDateRange:[],
pickerOptions:{
disabledDate(time) {
return time.getTime() > Date.now();
},
},
}
},
methods: {
init(){
const now = new Date(),formatNow = formatDate(now);
const weekAgo = formatDate(new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000))
this.dateRange = [weekAgo, formatNow];
this.defaultDateRange=[weekAgo, formatNow];
this.$emit('updateDate',this.dateRange)
},
showBtnLoading(status){
this.loading = status
},
resetDate(){
this.dateRange = this.defaultDateRange
},
//重置 设置时间范围为初始化时间段
reset(){
this.resetDate()
this.$emit('updateDate',this.dateRange)
},
// 搜索
search(){
this.$emit('updateDate',this.dateRange)
},
timeLine(type){
//baseTime,maxTime 毫秒数
let baseTime = new Date(this.dateRange[type === 'before' ? 0 : 1]).getTime(),maxTime = new Date(this.defaultDateRange[1]).getTime()
//updateTime 毫秒数
let updateTime = type === 'before' ? baseTime - 7 * 24 * 60 * 60 * 1000 : baseTime + 7 * 24 * 60 * 60 * 1000
if(type === 'next' && updateTime >= maxTime) updateTime = maxTime
const start = formatDate(type === 'before' ? updateTime : baseTime)
const end = formatDate(type === 'before' ? baseTime : updateTime)
this.dateRange = [start,end]
this.$emit('updateDate',this.dateRange)
},
}
}
</script>
<style lang="scss" scoped>
.time-range{
display: flex;
::v-deep {
.el-range-editor--medium.el-input__inner{
height: 30px;
}
.el-range-editor--medium .el-range-separator{
line-height: 24px;
}
.el-button--mini{
padding:3px 10px;
}
}
}
</style>

View File

@ -3,7 +3,7 @@
<el-card v-loading="loading" gshadow="always" class="common-card-container common-card-container-no-title-bg">
<!-- 搜索栏-->
<el-form :inline="true" class="select-container">
<el-form-item label="设备类型">
<el-form-item label="设备清单">
<el-select v-model="search.deviceType" clearable placeholder="请选择" :loading="loading" loading-text="正在加载数据">
<el-option :label="value" :value="key" v-for="(value,key) in $store.state.ems.deviceTypeOptions" :key="key+'deviceTypeOptions'"></el-option>
</el-select>

View File

@ -1,26 +1,29 @@
<template>
<el-row style="background:#fff;margin-top:30px;">
<el-col :xs="24" :sm="24" :lg="24">
<el-card shadow="always" class="common-card-container common-card-container-body-no-padding">
<div slot="header">
<span class="card-title">当日功率曲线</span>
</div>
<div style="height: 310px" id="activeChart"></div>
</el-card>
</el-col>
</el-row>
<el-card shadow="always" class="common-card-container common-card-container-body-no-padding time-range-card">
<div slot="header" class="time-range-header">
<span class="card-title">当日功率曲线</span>
<date-range-select ref="dateRangeSelect" @updateDate="updateDate"/>
</div>
<div style="height: 310px" id="activeChart"></div>
</el-card>
</template>
<script>
import * as echarts from 'echarts'
import resize from '@/mixins/ems/resize'
import DateRangeSelect from '@/components/Ems/DateRangeSelect.vue'
import {getPcsNameList, getPowerData} from '@/api/ems/dzjk'
export default {
mixins: [resize],
components: {DateRangeSelect},
data() {
return {
chart: null
chart: null,
timeRange:[],
siteId:'',
deviceId:''
}
},
mounted() {
@ -36,22 +39,56 @@ export default {
this.chart = null
},
methods: {
// 更新时间范围 重置图表
updateDate(data){
this.timeRange=data
this.getGVQXData()
},
getGVQXData(){
this.showLoading()
const {siteId,deviceId,timeRange}=this
if(!deviceId) return this.hideLoading()
getPowerData({siteId,deviceId,startDate:timeRange[0],endDate:timeRange[1],dataType:'1'}).then(response => {
this.setOption(response?.data || [])
}).finally(()=>this.hideLoading())
},
init(siteId){
//初始化 清空数据
this.siteId = siteId
this.timeRange=[]
this.deviceId=''
this.$refs.dateRangeSelect.init()
this.showLoading()
getPcsNameList(siteId).then(response=>{
const data=response?.data || [];
if(data.length>0){
this.deviceId=data[0].id
//接口调用完成之后 设置图表、结束loading
this.getGVQXData()
}else{
this.hideLoading()
}
})
},
initChart() {
this.chart = echarts.init(document.querySelector('#activeChart'))
},
showLoading(){
this.chart && this.chart.showLoading()
},
hideLoading(){
this.chart && this.chart.hideLoading()
},
setOption(data) {
const source = [['日期','电网功率']]
data.forEach((item)=>{
this.chart && data.forEach((item)=>{
source.push([item.statisDate,item.gridPower])
})
this.chart.setOption({
color:['#FFBD00','#3C81FF'],
legend: {
left: 'center',
bottom: '10',
bottom: '15',
},
tooltip: {
trigger: 'axis',
@ -76,7 +113,6 @@ export default {
}
]
})
this.chart.hideLoading()
},
}

View File

@ -0,0 +1,80 @@
<template>
<el-card shadow="always" class="common-card-container common-card-container-body-no-padding">
<div slot="header">
<span class="card-title">当前报警</span>
</div>
<div class="ssgj-container">
<el-table
class="common-table"
:data="tableData"
height="100%"
stripe
style="width: 100%">
<el-table-column
prop="deviceName"
label="名称">
</el-table-column>
<el-table-column
label="状态"
>
<template slot-scope="scope">
<span :class="{'circle warning-status' : scope.row.status !== 0}">{{ $store.state.ems.warnOptions[scope.row.status]}}</span>
</template>
</el-table-column>
<el-table-column
class-name="alarm-content"
prop="alarmContent"
show-overflow-tooltip
label="告警内容">
</el-table-column>
<el-table-column
label="工单"
fixed="right"
show-overflow-tooltip
>
<template slot-scope="scope">
<el-button type="text" size="mini" v-if="scope.row.ticketNo" @click="toTicket">已生成工单(工单号:{{scope.row.ticketNo}})</el-button>
<el-button type="primary" size="mini" v-else @click="toTicket">生成工单</el-button>
</template>
</el-table-column>
</el-table>
</div>
</el-card>
</template>
<script>
export default{
props:{
tableData:{
require:true,
type:Array,
default:()=>{
return []
}
}
},
data(){
return {
}
},
methods:{
toTicket(){
this.$router.push({path:'/ticket'})
},
}
}
</script>
<style lang="scss" scoped>
//实时告警
.ssgj-container{
padding:20px;
height: 250px;
box-sizing: border-box;
::v-deep{
.el-table .el-table__header-wrapper th, .el-table .el-table__fixed-header-wrapper th{
background:#FFF2CB ;
}
}
}
</style>

View File

@ -1,26 +1,27 @@
<template>
<el-row style="background:#fff;margin-top:30px;">
<el-col :xs="24" :sm="24" :lg="24">
<el-card shadow="always" class="common-card-container common-card-container-body-no-padding">
<div slot="header">
<el-card shadow="always" class="common-card-container common-card-container-body-no-padding time-range-card">
<div slot="header" class="time-range-header">
<span class="card-title">一周充放曲线</span>
<date-range-select ref="dateRangeSelect" @updateDate="updateDate"/>
</div>
<div style="height: 310px" id="weekChart"></div>
</el-card>
</el-col>
</el-row>
</template>
<script>
import * as echarts from 'echarts'
import resize from '@/mixins/ems/resize'
import DateRangeSelect from '@/components/Ems/DateRangeSelect.vue'
// import {getPcsNameList, getPowerData} from '@/api/ems/dzjk'
export default {
mixins: [resize],
components: {DateRangeSelect},
data() {
return {
chart: null
chart: null,
timeRange:[],
siteId:'',
}
},
mounted() {
@ -36,18 +37,43 @@ export default {
this.chart = null
},
methods: {
// 更新时间范围 重置图表
updateDate(data){
this.timeRange=data
this.getWeekKData()
},
getWeekKData(){
this.showLoading()
const {siteId,timeRange}=this
//todo delete
this.hideLoading()
// todo({siteId,startDate:timeRange[0],endDate:timeRange[1]}).then(response => {
// this.setOption(response?.data || [])
// }).finally(()=>this.hideLoading())
},
init(siteId){
//初始化 清空数据
this.siteId = siteId
this.timeRange=[]
this.deviceId=''
this.$refs.dateRangeSelect.init()
this.getWeekKData()
},
initChart() {
this.chart = echarts.init(document.querySelector('#weekChart'))
},
showLoading(){
this.chart && this.chart.showLoading()
},
hideLoading(){
this.chart && this.chart.hideLoading()
},
setOption(data,unit) {
const source = [['日期','充电量','放电量']]
data.forEach(item=>{
source.push([item.ammeterDate, item.chargedCap,item.disChargedCap])
})
this.chart.setOption({
this.chart && this.chart.setOption({
color:['#FFBD00','#3C81FF','#05AEA3'],
tooltip: {
trigger: 'axis',
@ -57,7 +83,7 @@ export default {
},
legend: {
left: 'center',
bottom: '10',
bottom: '15',
},
xAxis: {
type: 'category',
@ -88,10 +114,7 @@ export default {
},
]
})
this.chart.hideLoading()
}
}
}
</script>

View File

@ -1,6 +1,9 @@
<template>
<div v-loading="loading">
<el-row :gutter="15" style="background:#fff;">
<el-row style="background:#fff;" class="row-container">
<el-col v-if="tableData.length>0" :xs="24" :sm="24" :lg="24">
<alarm-table :tableData="tableData"/>
</el-col>
<el-col :xs="24" :sm="24" :lg="6">
<el-card shadow="always" class="common-card-container common-card-container-body-no-padding">
<div slot="header">
@ -22,7 +25,7 @@
<el-row :gutter="20">
<el-col :span="12" v-for="(item,index) in sjglData" :key="index+'sjglData'" class="sjgl-data">
<div class="sjgl-title">{{item.title}}</div>
<div class="sjgl-value">{{item.value | formatNumber}}</div>
<div class="sjgl-value">{{runningInfo[item.attr] | formatNumber}}</div>
</el-col>
</el-row>
</div>
@ -31,70 +34,35 @@
<el-col :xs="24" :sm="24" :lg="10">
<el-card shadow="always" class="common-card-container common-card-container-body-no-padding">
<div slot="header">
<span class="card-title">当前报警</span>
<!-- <el-button style="float: right; padding: 3px 0" type="text" size="small">通讯状态<span style="color:red">超时</span></el-button>-->
<span class="card-title">策略信息</span>
</div>
<div class="ssgj-container">
<el-table
class="common-table"
:data="tableData"
height="100%"
stripe
style="width: 100%">
<el-table-column
prop="deviceName"
label="名称">
</el-table-column>
<el-table-column
label="状态"
>
<template slot-scope="scope">
<span :class="{'circle warning-status' : scope.row.status !== 0}">{{ $store.state.ems.warnOptions[scope.row.status]}}</span>
</template>
</el-table-column>
<el-table-column
class-name="alarm-content"
prop="alarmContent"
show-overflow-tooltip
label="告警内容">
</el-table-column>
<el-table-column
label="工单"
fixed="right"
show-overflow-tooltip
>
<template slot-scope="scope">
<el-button type="text" size="mini" v-if="scope.row.ticketNo" @click="toTicket">已生成工单(工单号:{{scope.row.ticketNo}})</el-button>
<el-button type="primary" size="mini" v-else @click="toTicket">生成工单</el-button>
</template>
</el-table-column>
</el-table>
<div style="box-sizing: border-box; height: 250px;padding:20px 15px;" >
</div>
</el-card>
</el-col>
</el-row>
<el-row :gutter="15" style="background:#fff;">
<el-col :xs="24" :sm="24" :lg="12">
<el-col :xs="24" :sm="24" :lg="24">
<week-chart ref="weekChart"/>
</el-col>
<el-col :xs="24" :sm="24" :lg="12">
<el-col :xs="24" :sm="24" :lg="24">
<active-chart ref="activeChart"/>
</el-col>
</el-row>
</div>
</template>
<script>
import {getSingleSiteBaseInfo} from '@/api/ems/zddt'
import {getDzjkHomeView, getPcsNameList, getPowerData} from '@/api/ems/dzjk'
import {getDzjkHomeView} from '@/api/ems/dzjk'
import WeekChart from "./WeekChart.vue";
import ActiveChart from "./ActiveChart.vue";
import AlarmTable from "./AlarmTable.vue";
import getQuerySiteId from '@/mixins/ems/getQuerySiteId'
import {formatDate} from "@/filters/ems";
export default {
name:'DzjkSbjkHome',
components: {WeekChart,ActiveChart},
components: {WeekChart,ActiveChart,AlarmTable},
mixins: [getQuerySiteId],
data() {
return {
@ -114,67 +82,50 @@ export default {
}],
sjglData:[{
title:'今日充电量MWh',
value:'',
attr:'dayChargedCap'
},{
title:'今日放电量MWh',
value:'',
attr:'dayDisChargedCap'
},{
title:'总充电量MWh',
value:'',
attr:'totalChargedCap'
},{
title:'总放电量MWh',
value:'',
attr:'totalDischargedCap'
}],
tableData:[],
info:{}
info:{},//基本信息
runningInfo:{},//总累计运行数据+报警表格
}
},
computed:{
tableData(){
console.log('this.runningInfo?.siteMonitorHomeAlarmVo ',this.runningInfo?.siteMonitorHomeAlarmVo )
return this.runningInfo?.siteMonitorHomeAlarmVo || []
}
},
methods:{
toTicket(){
this.$router.push({path:'/ticket'})
},
getGVQXData(){
this.$refs.activeChart.showLoading()
const {siteId}=this,now=new Date()
getPcsNameList(this.siteId).then(response=>{
const data=response?.data || [];
if(data.length>0){
//接口调用完成之后 设置图表、结束loading
getPowerData({siteId,deviceId:data[0].id,startDate:formatDate(now),endDate:formatDate(now),dataType:'1'}).then(response => {
this.$refs.activeChart.setOption(response?.data || [])
})
}
})
},
getBaseInfo(){
this.$refs.weekChart.showLoading()
getSingleSiteBaseInfo(this.siteId).then(response => {
return getSingleSiteBaseInfo(this.siteId).then(response => {
this.info = response?.data || {}
const {sevenDayDisChargeStats=[],unit=''} = this.info
this.$refs.weekChart.setOption(sevenDayDisChargeStats,unit)
})
},
getTableData(){
getDzjkHomeView(this.siteId).then(response => {
getRunningInfo(){
return getDzjkHomeView(this.siteId).then(response => {
const data = response?.data || {}
this.sjglData.forEach(item=>{
item.value =data[item.attr]
})
this.tableData = data?.siteMonitorHomeAlarmVo || []
}).finally(() => {this.loading = false})
this.runningInfo = data
})
},
init(){
this.loading = true
// 功率曲线
this.getGVQXData()
// 基本信息+冲放曲线
this.getBaseInfo()
//其他数据
this.getTableData()
this.$refs.activeChart.init(this.siteId)
// 一周冲放曲线
this.$refs.weekChart.init(this.siteId)
// 静态信息 this.getBaseInfo()
// 总累计运行数据+故障告警 this.getRunningInfo()
Promise.all([this.getBaseInfo(),this.getRunningInfo()]).finally(()=>{
this.loading = false
})
}
},
@ -182,6 +133,11 @@ export default {
</script>
<style scoped lang="scss">
.row-container{
&>.el-col{
margin-bottom: 20px;
}
}
//数据概览
.sjgl-data{
text-align: center;
@ -201,16 +157,25 @@ export default {
word-wrap: break-word;
}
}
//实时告警
.ssgj-container{
padding:20px;
height: 250px;
box-sizing: border-box;
::v-deep{
.el-table .el-table__header-wrapper th, .el-table .el-table__fixed-header-wrapper th{
background:#FFF2CB ;
</style>
<style lang="scss">
/* card标题里的时间选择器 */
.time-range-card{
&.common-card-container .el-card__header{
padding-top: 0;
padding-bottom: 0;
.time-range-header{
height: 40px;
display: flex;
justify-content: space-between;
align-items: center;
.card-title{
line-height: 40px;
}
}
}
</style>
}
</style>

View File

@ -2,7 +2,7 @@
<template>
<!-- 6个方块-->
<el-row :gutter="10">
<el-col :xs="12" :sm="8" :lg="4" class="single-square-box-container" v-for="(item,index) in singleZdSqaure" :key="index+'singleSquareBox'">
<el-col :xs="12" :sm="8" :lg="4" style="margin-bottom: 10px;" class="single-square-box-container" v-for="(item,index) in singleZdSqaure" :key="index+'singleSquareBox'">
<single-square-box :data="{...item,value:formatNumber(data[item.attr])}" ></single-square-box>
</el-col>
</el-row>

View File

@ -61,6 +61,10 @@
<span>{{scope.row.maxCellVoltage}} V</span>
</template>
</el-table-column>
<el-table-column
prop="maxVoltage"
label="电池号码">
</el-table-column>
<el-table-column
prop="minVoltage"
label="单体最低电压">
@ -68,12 +72,20 @@
<span>{{scope.row.minCellVoltage}} V</span>
</template>
</el-table-column>
<el-table-column
prop="maxVoltage"
label="电池号码">
</el-table-column>
<el-table-column
label="单体最高温度">
<template slot-scope="scope">
<span>{{scope.row.maxCellTemp}} &#8451;</span>
</template>
</el-table-column>
<el-table-column
prop="maxVoltage"
label="电池号码">
</el-table-column>
<el-table-column
prop="minTemperature"
label="单体最低温度">
@ -81,6 +93,10 @@
<span>{{scope.row.minCellTemp}} &#8451;</span>
</template>
</el-table-column>
<el-table-column
prop="maxVoltage"
label="电池号码">
</el-table-column>
</el-table>
</el-card>

View File

@ -12,10 +12,11 @@
<div>{{$store.state.ems.communicationStatusOptions[pcsItem.communicationStatus]}}</div>
<div>数据更新时间{{pcsItem.dataUpdateTime}}</div>
</div>
<!-- <div class="pcs-btns">-->
<!-- <el-button type="warning" size="small" @click="problemSaved">故障复位</el-button>-->
<!-- <el-button size="small" @click="machineClosed">关机</el-button>-->
<!-- </div>-->
<div class="pcs-btns">
<el-badge :value="0" class="item">
<i class="el-icon-message-solid" style="font-size: 26px;color: #fff;display: block;"></i>
</el-badge>
</div>
</el-header>
<el-main style="padding: 0">
<div class="descriptions-main">