map/ui/dasadmin/src/views/backend/dashboard.vue
2024-10-24 09:04:51 +08:00

870 lines
31 KiB
Vue

<template>
<div class="default-main">
<el-row :gutter="20">
<el-col :span="6">
<div class="grid-content ep-bg-purple">
<!--风场概览-->
<div class="overview panelBg">
<el-text class="mx-1 homelabel">风场概览</el-text>
<el-row :gutter="10">
<el-col :span="12">
<div :sm="12" :lg="6" class="small-panel" style="margin-bottom: 10px;">
<img class="small-panel-pic" src="~assets/dashboard/viewP.png" alt="">
<div class="small-base">
<div><span class="content-number">{{overviewData.power}}</span> <span>MW</span></div>
<div>功率</div>
</div>
</div>
<div :sm="12" :lg="6" class="small-panel">
<img class="small-panel-pic" src="~assets/dashboard/viewW.png" alt="">
<div class="small-base">
<div><span class="content-number">{{overviewData.windSpeed}}</span> <span>m/s</span></div>
<div>风速</div>
</div>
</div>
</el-col>
<el-col :span="12">
<div :sm="12" :lg="6" class="small-panel" style="margin-bottom: 10px;">
<img class="small-panel-pic" src="~assets/dashboard/viewR.png" alt="">
<div class="small-base">
<div><span class="content-number">{{overviewData.dailyUsageHours}}</span> <span>H</span></div>
<div>日利用小时</div>
</div>
</div>
<div :sm="12" :lg="6" class="small-panel">
<img class="small-panel-pic" src="~assets/dashboard/viewY.png" alt="">
<div class="small-base">
<div><span class="content-number">{{overviewData.monthlyUsageHours}}</span> <span>H</span></div>
<div>月利用小时</div>
</div>
</div>
</el-col>
</el-row>
</div>
<!--今日运行状态-->
<div class="status panelBg">
<el-text class="mx-1 homelabel">今日运行状态</el-text>
<el-row :gutter="10" class="statusrow">
<el-col :span="12">
<div class="status-panel">
<img class="status-panel-pic" src="~assets/dashboard/status1.png" alt="">
<div class="status-base">
<div><span class="content-number">{{currentDayStatus.windTurbineNum}}</span> <span></span></div>
<div>风机台数</div>
</div>
</div>
</el-col>
<el-col :span="12">
<div class="status-panel">
<img class="status-panel-pic" src="~assets/dashboard/status2.png" alt="">
<div class="status-base">
<div><span class="content-number">{{currentDayStatus.installedCapacity}}</span> <span>MW</span></div>
<div>装机容量</div>
</div>
</div>
</el-col>
</el-row>
<el-row :gutter="10" class="statusrow">
<el-col :span="12">
<div class="status-panel status-con">
<div>
<img class="status-panel-piczt" src="~assets/dashboard/run.png" alt="">
<p>运行</p>
</div>
<div class="status-base">
<div><span>容量</span> <span class="content-number">{{currentDayStatus.runCapacity}}</span> <span>MW</span></div>
<div><span>台数</span> <span class="content-number">{{currentDayStatus.runNum}}</span> <span></span></div>
</div>
</div>
</el-col>
<el-col :span="12">
<div class="status-panel status-con">
<div>
<img class="status-panel-piczt" src="~assets/dashboard/Standby.png" alt="">
<p>待机</p>
</div>
<div class="status-base">
<div><span>容量</span> <span class="content-number">{{currentDayStatus.standbyCapacity}}</span> <span>MW</span></div>
<div><span>台数</span> <span class="content-number">{{currentDayStatus.standbyNum}}</span> <span></span></div>
</div>
</div>
</el-col>
</el-row>
<el-row :gutter="10">
<el-col :span="12">
<div class="status-panel status-con">
<div>
<img class="status-panel-piczt" src="~assets/dashboard/fault.png" alt="">
<p>故障</p>
</div>
<div class="status-base">
<div><span>容量</span> <span class="content-number">{{currentDayStatus.faultCapacity}}</span> <span>MW</span></div>
<div><span>台数</span> <span class="content-number">{{currentDayStatus.faultNum}}</span> <span></span></div>
</div>
</div>
</el-col>
<el-col :span="12">
<div class="status-panel status-con">
<div>
<img class="status-panel-piczt" src="~assets/dashboard/offline.png" alt="">
<p>离线</p>
</div>
<div class="status-base">
<div><span>容量</span> <span class="content-number">{{currentDayStatus.offlineCapacity}}</span> <span>MW</span></div>
<div><span>台数</span> <span class="content-number">{{currentDayStatus.offlineNum}}</span> <span></span></div>
</div>
</div>
</el-col>
</el-row>
</div>
<!--功率趋势-->
<div class="power panelBg" style="margin-bottom: 0;">
<el-text class="mx-1 homelabel">功率趋势</el-text>
<el-row :gutter="10">
<el-col class="lg-mb-20" :span="24">
<div class="power-chart" :ref="chartRefs.set"></div>
</el-col>
</el-row>
</div>
</div>
</el-col>
<el-col :span="12">
<div class="grid-content ep-bg-purple-light">
<!--风机矩阵-->
<div class="matrix panelBg">
<el-text class="mx-1 homelabel">风机矩阵</el-text>
<WindContent></WindContent>
</div>
</div>
</el-col>
<el-col :span="6">
<div class="grid-content ep-bg-purple">
<!--发电量概况-->
<div class="summarize panelBg">
<div class="summarize-title">
<el-text class="mx-1 homelabel">发电量概况</el-text>
<el-text class="mx-1" style="margin-bottom: 20px;">
当日发电量
<span class="content-number" style="color: #0277B3;">{{generationOverview.dailyGeneration}}</span>
kWh
</el-text>
</div>
<el-row :gutter="5">
<el-col :span="6">
<div class="summarize-panel">
<div class="summarize-panel-pic">
<img src="~assets/dashboard/fdl1.png" alt="">
</div>
<div class="summarize-panel-base">
<div><span class="content-number">{{generationOverview.dayGeneration}}</span></div>
<div><span>kWh</span></div>
<div><span>日发电量</span></div>
</div>
</div>
</el-col>
<el-col :span="6">
<div class="summarize-panel">
<div class="summarize-panel-pic">
<img src="~assets/dashboard/fdl2.png" alt="">
</div>
<div class="summarize-panel-base">
<div><span class="content-number">{{generationOverview.monthGeneration}}</span></div>
<div><span>万kWh</span></div>
<div><span>月发电量</span></div>
</div>
</div>
</el-col>
<el-col :span="6">
<div class="summarize-panel">
<div class="summarize-panel-pic">
<img src="~assets/dashboard/fdl3.png" alt="">
</div>
<div class="summarize-panel-base">
<div><span class="content-number">{{generationOverview.yearGeneration}}</span></div>
<div><span>万kWh</span></div>
<div><span>年发电量</span></div>
</div>
</div>
</el-col>
<el-col :span="6">
<div class="summarize-panel">
<div class="summarize-panel-pic">
<img src="~assets/dashboard/fdl4.png" alt="">
</div>
<div class="summarize-panel-base">
<div><span class="content-number">{{generationOverview.totalGeneration}}</span></div>
<div><span>万kWh</span></div>
<div><span>总发电量</span></div>
</div>
</div>
</el-col>
</el-row>
</div>
<!--发电量趋势-->
<div class="trend panelBg">
<el-text class="mx-1 homelabel">发电量趋势</el-text>
<el-row :gutter="10">
<el-col :span="24">
<el-tabs v-model="activeName" class="demo-tabs trend-tabs" @tab-click="tabhandleClick" ref="userTab">
<el-tab-pane label="日" name="first">
<div class="trend-chart" :ref="chartRefs.set"></div>
</el-tab-pane>
<el-tab-pane label="月" name="second">
<div class="trend-chart" :ref="chartRefs.set"></div>
</el-tab-pane>
</el-tabs>
</el-col>
</el-row>
</div>
<!--实时告警-->
<div class="trend panelBg" style="margin-bottom: 0;">
<el-text class="mx-1 homelabel">实时告警</el-text>
<el-row :gutter="10">
<el-col :span="24">
<el-table :data="tableData"
class="tablePart"
height="250"
ref="myTable"
@mouseover.native="clearScroll"
@mouseleave.native="createScroll">
<el-table-column fixed prop="time" label="时间" />
<el-table-column prop="name" label="风机" />
<el-table-column prop="alertcontent" label="告警内容" />
<el-table-column label="操作">
<template #default="scope">
<a @click="">确认</a>
</template>
</el-table-column>
</el-table>
</el-col>
</el-row>
</div>
</div>
</el-col>
</el-row>
</div>
</template>
<script setup lang="ts">
import {nextTick, onActivated, onMounted, reactive, ref,onBeforeMount} from "vue";
import * as echarts from 'echarts'
import { useTemplateRefsList,useEventListener } from '@vueuse/core'
import {useI18n} from "vue-i18n";
import WindContent from '/@/views/backend/home/windMatrix.vue'
const d = new Date()
const { t } = useI18n()
let timer = null
let myTable = ref(null)
const overviewData=ref({
"power": 56.2,
"windSpeed": 45.3,
"dailyUsageHours": 20,
"monthlyUsageHours": 78
})
const currentDayStatus=ref({
"windTurbineNum": 40,
"installedCapacity": 45.32,
"runCapacity": 20.2,
"runNum": 78,
"standbyCapacity": 63.2,
"standbyNum": 35,
"faultCapacity": 56.4,
"faultNum": 53,
"offlineCapacity": 16.4,
"offlineNum": 20
})
const generationOverview=ref({
"dailyGeneration": 63.2,
"dayGeneration": 56.2,
"monthGeneration": 60.2,
"yearGeneration": 200.6,
"totalGeneration": 500.6
})
const chartRefs = useTemplateRefsList<HTMLDivElement>()
const state: {
charts: any[]
remark: string
workingTimeFormat: string
pauseWork: boolean
} = reactive({
charts: [],
remark: 'dashboard.Loading',
workingTimeFormat: '',
pauseWork: false,
})
const powerChartData = [
{
"power": 12.6,
"windSpeed": 56.3,
"dataTime": "2024-10-17 00:00:00"
},
{
"power": 10.6,
"windSpeed": 16.3,
"dataTime": "2024-10-17 00:05:00"
}
]
const initpowerChart = () => {
const initpowerChart = echarts.init(chartRefs.value[0] as HTMLElement)
const xAxisdata=[];
const powerData=[];
const windSpeedData=[]
powerChartData.forEach((item, index) => {
const dataTime=item.dataTime
const dataTimearr=dataTime.split(' ')
xAxisdata.push(dataTimearr[1])
powerData.push(item.power)
windSpeedData.push(item.windSpeed)
const option = {
grid: {
top: 50,
right: 10,
bottom: 20,
left: 10,
containLabel:true
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
xAxis: {
type: 'category',
axisLine:{
show:true,
lineStyle: {
color: '#dadada',
width: 1,
type: "solid"
}
},
axisLabel: {//x轴文字的配置
show: true,
textStyle: {
color: '#4E5969',
},
interval: 0,
//rotate: 45
},
splitLine: {//分割线配置
show:false,
lineStyle: {
color: '#999999',
}
},
data: xAxisdata,
},
yAxis: [
{
type: 'value',
name: '功率MW',
nameTextStyle:{
color: '#4E5969',
},
axisLine:{
show:false,
lineStyle: {
color: "#dadada",
width: 0,
type: "solid"
}
},
axisLabel: {//x轴文字的配置
show: true,
textStyle: {
color: '#4E5969',
}
},
axisTick:{show:false},
splitLine: {
interval: 50,
lineStyle: {
type: 'dashed',
color: '#dadada',
}
}
},
{
type: 'value',
name: '风速m/s',
nameTextStyle:{
color: '#4E5969',
},
axisLine:{
show:false,
lineStyle: {
color: "#dadada",
width: 0,
type: "solid"
}
},
axisLabel: {//x轴文字的配置
show: true,
textStyle: {
color: '#4E5969',
}
},
axisTick:{show:false},
splitLine: {
interval: 50,
lineStyle: {
type: 'dashed',
color: '#dadada',
}
},
}
],
legend: {
data: ['功率','风速'],
textStyle: {
color: '#73767a'
},
},
series:[
{
name: '功率',
type: 'bar',
barWidth: 20,
itemStyle: {
color: '#00A7EB',
barBorderRadius: 2
},
data: powerData
},{
name: '风速',
type: 'line',
yAxisIndex: 1,
itemStyle: {
color: '#FF7E00',
barBorderRadius: 2
},
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: 'rgba(255,126,0,0.8)'
}
])
},
data: windSpeedData
}
]
}
initpowerChart.setOption(option)
state.charts.push(initpowerChart)
});
}
const TrendData=[
{
"currentPeriod": 56.3,
"samePeriod": 63.5,
"generationTime": "2024-10-01"
},
{
"currentPeriod": 66.3,
"samePeriod": 73.5,
"generationTime": "2024-10-02"
},
{
"currentPeriod": 66.3,
"samePeriod": 73.5,
"generationTime": "2024-10-03"
}
]
const timeType="日"
const inittrendChart = (t,u) => {
const currentPeriod=[];
const samePeriod=[]
const xAxisdata=[]
TrendData.forEach((item, index) => {
const generationTime=item.generationTime
const generationTimearr=generationTime.split('-')
xAxisdata.push(generationTimearr[2])
currentPeriod.push(item.currentPeriod)
samePeriod.push(item.samePeriod)
const inittrendChart = echarts.init(chartRefs.value[u] as HTMLElement)
const option = {
grid: {
top: 30,
right: 10,
bottom: 20,
left: 25,
borderColor:'#dadada'
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
xAxis: {
type: 'category',
axisLine:{
show:true,
lineStyle: {
color: '#dadada',
width: 1,
type: "solid"
}
},
axisLabel: {//x轴文字的配置
show: true,
textStyle: {
color: '#4E5969',
}
},
splitLine: {//分割线配置
show:false,
lineStyle: {
color: '#999999',
}
},
data: xAxisdata,
},
yAxis: [
{
type: 'value',
name: 'kWh',
nameTextStyle:{
color: '#4E5969',
},
axisLine:{
show:false,
lineStyle: {
color: "#dadada",
width: 0,
type: "solid"
}
},
axisLabel: {//x轴文字的配置
show: true,
textStyle: {
color: '#4E5969',
}
},
axisTick:{show:false},
splitLine: {
interval: 50,
lineStyle: {
type: 'dashed',
color: '#dadada',
}
}
},
],
legend: {
data: ['本期','同期'],
textStyle: {
color: '#73767a',
},
},
series:
[
{
name: '本期',
data: currentPeriod,
type: 'bar',
smooth: true,
itemStyle: {
color: '#0277B3'
}
},{
name: '同期',
data: samePeriod,
type: 'bar',
smooth: true,
itemStyle: {
color: '#00A096'
}
},
],
}
inittrendChart.setOption(option)
state.charts.push(inittrendChart)
})
}
const echartsResize = () => {
nextTick(() => {
for (const key in state.charts) {
state.charts[key].resize()
}
})
}
onActivated(() => {
echartsResize()
})
const tableData = ref([
{
time: '2016-05-03',
name: 'SC-01',
alertcontent: '故障',
},
{
time: '2016-05-02',
name: 'SC-02',
alertcontent: '待机',
},
{
time: '2016-05-04',
name: 'SC-03',
alertcontent: '停机',
},
{
time: '2016-05-01',
name: 'SC-04',
alertcontent: '变桨叶1伺服驱动器故障',
},
{
time: '2016-05-03',
name: 'SC-01',
alertcontent: '故障',
},
{
time: '2016-05-02',
name: 'SC-02',
alertcontent: '待机',
},
{
time: '2016-05-04',
name: 'SC-03',
alertcontent: '停机',
},
{
time: '2016-05-01',
name: 'SC-04',
alertcontent: '变桨叶1伺服驱动器故障',
}
])
const clearScroll = () => {
clearInterval(timer)
timer = null
}
const createScroll = () => {
clearScroll()
const table = myTable.value.layout.table.refs
const tableWrapper = table.bodyWrapper.firstElementChild.firstElementChild
timer = setInterval(() => {
tableWrapper.scrollTop += 1
if (tableWrapper.clientHeight + tableWrapper.scrollTop == tableWrapper.scrollHeight) {
tableWrapper.scrollTop = 0
}
}, 30)
}
onMounted(() => {
inittrendChart('日','1')
initpowerChart()
createScroll()
useEventListener(window, 'resize', echartsResize)
})
onBeforeMount(() => {
for (const key in state.charts) {
state.charts[key].dispose()
}
})
const activeName = ref('first')
const tabhandleClick = (tabName) => {
setTimeout(() => {
echartsResize()
}, 10)
debugger
if(tabName.props.label=="日"){
inittrendChart('日','1')
}else if(tabName.props.label=="月"){
inittrendChart('月','2')
}
}
</script>
<style scoped lang="scss">
.default-main {
padding: 0;
margin: 0;
color: #4E5969;
background-color: #F2F3F5;
.content-number{
color: #333333;
font-size: 20px;
}
.homelabel{
font-family: PingFangSC-Semibold;
font-size: 18px;
color: #4E5969;
letter-spacing: 0;
line-height: 18px;
font-weight: 600;
margin-bottom: 20px;
display: block;
}
.grid-content{
height: 100%;
.panelBg{
background-color: #ffffff;
padding: 20px;
border-radius: 5px;
margin-bottom: 20px;
}
.overview{
.small-panel{
display: flex;
border: 1px solid #E1EDF6;
border-radius: 10px;
padding: 10px;
.small-panel-pic{
width: 36px;
height: 36px;
}
.small-base{
margin-left: 10px;
color: #2c3f5d;
}
}
}
.status{
.statusrow{
margin-bottom: 10px;
}
.status-con{
padding-left: 20px !important;
background: #F0F6FF;
border-radius: 10px;
}
.status-panel{
display: flex;
padding: 10px;
font-size: 12px;
.status-panel-pic{
width: 60px;
height: 60px;
}
.status-base{
margin-left: 10px;
line-height: 23px;
padding-top: 6px;
}
.status-panel-piczt{
width: 36px;
height: 36px;
}
}
}
.power{
.power-chart{
width: 100%;
height: 300px;
}
}
.matrix{
background: url("/@/assets/dashboard/bg1.png") no-repeat #ffffff;
background-size: 100% 100%;
height: 100%;
}
.summarize{
.summarize-title{
display: flex;
justify-content: space-between;
}
.summarize-panel{
background: #F0F6FF;
border-radius: 10px;
margin: 5px;
padding: 10px;
.summarize-panel-pic{
text-align: center;
}
.summarize-panel-base{
text-align: center;
}
}
}
.trend{
height: 350px;
overflow: hidden;
.trend-tabs{
:deep(.el-tabs__item){
border: none;
text-align: center;
width: 40px;
padding: 0;
line-height: 24px;
height: 24px;
}
:deep(.el-tabs__header .el-tabs__nav){
border-radius: 0;
border: none;
}
:deep(.el-tabs__header){
border-bottom: 0;
float: right;
margin-top:-43px
}
:deep(.el-tabs__content){
clear: both;
}
:deep(.el-tabs__item.is-active){
background: rgba(2,119,179,0.20);
border-radius: 4px;
border: none;
}
:deep(.el-tabs__nav-wrap:after){
background: none;
}
:deep(.el-tabs__active-bar){
background: none;
}
}
.trend-chart{
width: 100%;
height: 260px;
}
}
}
}
</style>