解决冲突

This commit is contained in:
zhoumengru
2025-09-04 13:44:31 +08:00
23 changed files with 1672 additions and 1365 deletions

8
web/package-lock.json generated
View File

@@ -13,6 +13,7 @@
"core-js": "^3.8.3", "core-js": "^3.8.3",
"echarts": "^6.0.0", "echarts": "^6.0.0",
"moment": "^2.30.1", "moment": "^2.30.1",
"qs": "^6.12.3",
"vue": "^3.2.13", "vue": "^3.2.13",
"vue-router": "^4.0.3", "vue-router": "^4.0.3",
"vuex": "^4.0.0" "vuex": "^4.0.0"
@@ -5236,7 +5237,6 @@
"version": "1.0.4", "version": "1.0.4",
"resolved": "https://registry.npmmirror.com/call-bound/-/call-bound-1.0.4.tgz", "resolved": "https://registry.npmmirror.com/call-bound/-/call-bound-1.0.4.tgz",
"integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"call-bind-apply-helpers": "^1.0.2", "call-bind-apply-helpers": "^1.0.2",
@@ -10779,7 +10779,6 @@
"version": "1.13.4", "version": "1.13.4",
"resolved": "https://registry.npmmirror.com/object-inspect/-/object-inspect-1.13.4.tgz", "resolved": "https://registry.npmmirror.com/object-inspect/-/object-inspect-1.13.4.tgz",
"integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
"dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">= 0.4" "node": ">= 0.4"
@@ -12124,7 +12123,6 @@
"version": "6.13.0", "version": "6.13.0",
"resolved": "https://registry.npmmirror.com/qs/-/qs-6.13.0.tgz", "resolved": "https://registry.npmmirror.com/qs/-/qs-6.13.0.tgz",
"integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==",
"dev": true,
"license": "BSD-3-Clause", "license": "BSD-3-Clause",
"dependencies": { "dependencies": {
"side-channel": "^1.0.6" "side-channel": "^1.0.6"
@@ -13125,7 +13123,6 @@
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmmirror.com/side-channel/-/side-channel-1.1.0.tgz", "resolved": "https://registry.npmmirror.com/side-channel/-/side-channel-1.1.0.tgz",
"integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"es-errors": "^1.3.0", "es-errors": "^1.3.0",
@@ -13145,7 +13142,6 @@
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmmirror.com/side-channel-list/-/side-channel-list-1.0.0.tgz", "resolved": "https://registry.npmmirror.com/side-channel-list/-/side-channel-list-1.0.0.tgz",
"integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"es-errors": "^1.3.0", "es-errors": "^1.3.0",
@@ -13162,7 +13158,6 @@
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmmirror.com/side-channel-map/-/side-channel-map-1.0.1.tgz", "resolved": "https://registry.npmmirror.com/side-channel-map/-/side-channel-map-1.0.1.tgz",
"integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"call-bound": "^1.0.2", "call-bound": "^1.0.2",
@@ -13181,7 +13176,6 @@
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmmirror.com/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", "resolved": "https://registry.npmmirror.com/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
"integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"call-bound": "^1.0.2", "call-bound": "^1.0.2",

View File

@@ -16,7 +16,8 @@
"moment": "^2.30.1", "moment": "^2.30.1",
"vue": "^3.2.13", "vue": "^3.2.13",
"vue-router": "^4.0.3", "vue-router": "^4.0.3",
"vuex": "^4.0.0" "vuex": "^4.0.0",
"qs": "^6.12.3"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.12.16", "@babel/core": "^7.12.16",

View File

@@ -6,7 +6,7 @@
<meta name="viewport" content="width=device-width,initial-scale=1.0" /> <meta name="viewport" content="width=device-width,initial-scale=1.0" />
<link rel="icon" href="<%= BASE_URL %>favicon.ico" /> <link rel="icon" href="<%= BASE_URL %>favicon.ico" />
<title><%= htmlWebpackPlugin.options.title %></title> <title><%= htmlWebpackPlugin.options.title %></title>
<link rel="stylesheet" href="http://at.alicdn.com/t/c/font_5010233_fpzrc14sfwj.css" /> <link rel="stylesheet" href="http://at.alicdn.com/t/c/font_5010233_di79okor5xs.css" />
</head> </head>
<body> <body>
<noscript> <noscript>

View File

@@ -15,6 +15,10 @@
export default { export default {
name: '', name: '',
props: { props: {
total:{
type:Object,
default:()=>{}
},
deviceInfo: { deviceInfo: {
type: Array, type: Array,
default: () => [] default: () => []
@@ -25,32 +29,32 @@ export default {
curList: [ curList: [
{ {
name: '日光伏设备告警', name: '日光伏设备告警',
key: 'key1', key: 'solar_num_err',
lineColor: '#22E4FF', lineColor: '#22E4FF',
value: 0, value: 1111,
d: '' d: ''
}, },
{ {
name: '日储能设备告警', name: '日储能设备告警',
key: 'key2', key: 'storage_num_err',
lineColor: '#0E68E4', lineColor: '#0E68E4',
value: 0, value: 0,
d: '' d: ''
}, },
{ {
name: '日充电设备告警', name: '日充电设备告警',
key: 'key3', key: 'charge_num_err',
lineColor: '#00BAAD', lineColor: '#00BAAD',
value: 0, value: 0,
d: '' d: ''
}, },
{ // {
name: '日负荷设备告警', // name: '日负荷设备告警',
key: 'key4', // key: 'key4',
lineColor: '#FF8D1A', // lineColor: '#FF8D1A',
value: 0, // value: 0,
d: '' // d: ''
} // }
], ],
faultChart: null, faultChart: null,
lineChartData: { lineChartData: {
@@ -62,15 +66,32 @@ export default {
watch: { watch: {
deviceInfo: { deviceInfo: {
handler(n) { handler(n) {
let that=this
this.$nextTick(() => { this.$nextTick(() => {
this.drawLineChart() this.drawLineChart()
}) })
} }
// immediate: true // immediate: true
},
total:{
handler(n){
if(n){
let that=this
that.curList.forEach((item)=>{
item.value=that.total[item.key]
})
}
},
deep: true, // 深度监听
immediate: true,
} }
}, },
mounted() {}, mounted() {},
onBeforeUnmount() { beforeUnmount() {
this.faultChart = null this.faultChart = null
window.removeEventListener('resize', this.handleResize) window.removeEventListener('resize', this.handleResize)
}, },
@@ -81,9 +102,9 @@ export default {
}, },
processData(data, keys) { processData(data, keys) {
data.sort((a, b) => { data.sort((a, b) => {
return new Date(a.date) - new Date(b.date) return new Date(a.dt) - new Date(b.dt)
}) })
const dates = data.map((item) => item.date) const dates = data.map((item) => item.dt)
const values = [] const values = []
keys.forEach((item, index) => { keys.forEach((item, index) => {
values[index] = data.map((dataValue) => dataValue[keys[index]]) values[index] = data.map((dataValue) => dataValue[keys[index]])
@@ -160,13 +181,13 @@ export default {
lineStyle: { type: 'dashed', color: '#435463' } lineStyle: { type: 'dashed', color: '#435463' }
}, },
axisLabel: { axisLabel: {
interval: 4,
color: '#fff' color: '#fff'
} }
}, },
series: this.lineChartData.ydata series: this.lineChartData.ydata
} }
option && faultChart.setOption(option) option && faultChart.setOption(option)
console.log(this.lineChartData, 'this.lineChartData')
window.addEventListener('resize', this.handleResize) window.addEventListener('resize', this.handleResize)
} }
} }

View File

@@ -1,13 +1,10 @@
<template> <template>
<div class="charge"> <div class="charge">
<div class="text_Cur"> <div class="text_Cur">
<div v-for="item in curList" :key="item.key"> <div v-for="item in curList" :key="item.key">
<div>{{ item.name }}</div> <div>{{ item.name }}</div>
<span class="mark">{{ <span class="mark">{{ item.value ? item.value : 0 }}</span>
item.value?item.value: 0 <span class="d">{{ item.d }}</span>
}}</span
>
<span class="d">{{ item.d }}</span>
</div> </div>
</div> </div>
<div id="charge-chart"></div> <div id="charge-chart"></div>
@@ -18,6 +15,10 @@
export default { export default {
name: '', name: '',
props: { props: {
total: {
type: Object,
default: () => {}
},
deviceInfo: { deviceInfo: {
type: Array, type: Array,
default: () => [] default: () => []
@@ -28,96 +29,110 @@ export default {
curList: [ curList: [
{ {
name: '日充电电量', name: '日充电电量',
key: 'key1', key: 'charge_elect',
lineColor: '#00BBA3', lineColor: '#00BBA3',
colorStart: ' rgba(10, 250, 106, 0.15)', colorStart: ' rgba(10, 250, 106, 0.15)',
colorEnd: ' rgba(171, 255, 249, 0.3)', colorEnd: ' rgba(171, 255, 249, 0.3)',
value:0, value: 0,
d:'kW·h' d: 'kW·h'
}, },
{ {
name: '日充电次数', name: '日充电次数',
key: 'key2', key: 'charge_num',
lineColor: '#3F80F2', lineColor: '#3F80F2',
colorStart: ' rgba(99, 151, 235, 0.3)', colorStart: ' rgba(99, 151, 235, 0.3)',
colorEnd: ' rgba(24, 109, 245, 0.3)', colorEnd: ' rgba(24, 109, 245, 0.3)',
value:0, value: 0,
d:'' d: ''
} }
], ],
curListEcharts: [ curListEcharts: [
{ {
name: '日充电电量', name: '日充电电量',
key: 'key1', key: 'charge_elect',
lineColor: '#00BBA3', lineColor: '#00BBA3',
colorStart: ' rgba(10, 250, 106, 0.15)', colorStart: ' rgba(10, 250, 106, 0.15)',
colorEnd: ' rgba(171, 255, 249, 0.3)', colorEnd: ' rgba(171, 255, 249, 0.3)',
value:0, value: 0,
d:'kW·h' d: 'kW·h'
}, },
{ {
name: '日充电收益', name: '日充电收益',
key: 'key2', key: 'income_charge',
lineColor: '#3F80F2', lineColor: '#3F80F2',
colorStart: ' rgba(99, 151, 235, 0.3)', colorStart: ' rgba(99, 151, 235, 0.3)',
colorEnd: ' rgba(24, 109, 245, 0.3)', colorEnd: ' rgba(24, 109, 245, 0.3)',
value:0, value: 0,
d:'' d: ''
} }
], ],
chargeChart: null, chargeChart: null,
lineChartData: { chargeChartData: {
ydata: [], ydata: [],
xdata: [] xdata: []
}, }
} }
}, },
watch: { watch: {
total: {
handler(newVal,oldVal) {
if (newVal!==oldVal) {
this.curList.forEach((item) => {
item.value = this.total[item.key]
})
}
},
},
deviceInfo: { deviceInfo: {
handler(n) { handler(newVal,oldVal) {
this.$nextTick(() => { if (JSON.stringify(newVal) !== JSON.stringify(oldVal)) {
this.drawLineChart() this.$nextTick(() => {
}) this.drawLineChart()
} })
// immediate: true }
},
deep: true // 确保深度比较
} }
}, },
mounted() {}, mounted() {},
onBeforeUnmount() { beforeUnmount() {
this.chargeChart = null
window.removeEventListener('resize', this.handleResize) window.removeEventListener('resize', this.handleResize)
if(this.chargeChart){
this.chargeChart.dispose()
this.chargeChart = null
}
}, },
methods: { methods: {
handleResize() { handleResize() {
this.chargeChart.resize() if(this.chargeChart){
this.chargeChart.resize()
}
}, },
processData(data, keys) { processData(data, keys) {
console.log(data, 'dddddddddddddddddddddddddddd')
data.sort((a, b) => { data.sort((a, b) => {
return new Date(a.date) - new Date(b.date) return new Date(a.dt) - new Date(b.dt)
}) })
const dates = data.map((item) => item.date) const dates = data.map((item) => item.dt)
const values=[] const values = []
keys.forEach((item,index)=>{ keys.forEach((item, index) => {
values[index] = data.map((dataValue) => dataValue[keys[index]])
values[index]= data.map((dataValue)=>dataValue[keys[index]])
}) })
return { return {
dates, dates,
values, values
} }
}, },
getChargeData() { getChargeData() {
const arr=this.curListEcharts const arr = this.curListEcharts
const keyList=this.curListEcharts.map((item)=>item.key) const keyList = this.curListEcharts.map((item) => item.key)
const result = this.processData(this.deviceInfo, keyList) const result = this.processData(this.deviceInfo, keyList)
this.lineChartData.xdata = result.dates this.chargeChartData.xdata = result.dates
arr.forEach((item, index) => { arr.forEach((item, index) => {
this.lineChartData.ydata[index] = { this.chargeChartData.ydata[index] = {
name: item.name, name: item.name,
smooth: true, smooth: true,
type: 'line', type: 'line',
@@ -139,21 +154,24 @@ export default {
y2: 1, y2: 1,
colorStops: [ colorStops: [
{ offset: 0, color: JSON.parse(JSON.stringify(item)).colorStart }, // 顶部颜色 { offset: 0, color: JSON.parse(JSON.stringify(item)).colorStart }, // 顶部颜色
{ offset: 1, color: JSON.parse(JSON.stringify(item)).colorEnd }, // 底部颜色 { offset: 1, color: JSON.parse(JSON.stringify(item)).colorEnd } // 底部颜色
] ]
} }
}, },
global: false, global: false,
showSymbol: false, showSymbol: false,
data:result.values[index] data: result.values[index]
} }
}) })
}, },
drawLineChart(activeKey) { drawLineChart(activeKey) {
this.getChargeData(activeKey) this.getChargeData(activeKey)
if(this.chargeChart){
this.chargeChart.dispose()
}
const chartDom = document.getElementById('charge-chart') const chartDom = document.getElementById('charge-chart')
if (!chartDom) return;
let chargeChart = this.$echarts.init(chartDom) let chargeChart = this.$echarts.init(chartDom)
this.chargeChart = chargeChart this.chargeChart = chargeChart
const option = { const option = {
@@ -177,7 +195,7 @@ export default {
}, },
xAxis: { xAxis: {
type: 'category', type: 'category',
data: this.lineChartData.xdata, data: this.chargeChartData.xdata,
axisLine: { axisLine: {
lineStyle: { type: 'dashed', color: '#435463' } lineStyle: { type: 'dashed', color: '#435463' }
}, },
@@ -191,13 +209,18 @@ export default {
lineStyle: { type: 'dashed', color: '#435463' } lineStyle: { type: 'dashed', color: '#435463' }
}, },
axisLabel: { axisLabel: {
interval: 4,
color: '#fff' color: '#fff'
} }
}, },
series: this.lineChartData.ydata series: this.chargeChartData.ydata
} }
option && chargeChart.setOption(option) option && chargeChart.setOption(option)
console.log(this.lineChartData, 'this.lineChartData') this.setupResizeListener()
},
setupResizeListener(){
window.removeEventListener('resize', this.handleResize);
window.addEventListener('resize', this.handleResize) window.addEventListener('resize', this.handleResize)
} }
} }
@@ -224,12 +247,12 @@ export default {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
& > div:last-child{ & > div:last-child {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
align-items: end; align-items: end;
} }
.mark { .mark {
font-size: 16px; font-size: 16px;
margin-right: 2px; margin-right: 2px;
@@ -241,7 +264,7 @@ export default {
rgba(61, 254, 250, 0.15) 49.2%, rgba(61, 254, 250, 0.15) 49.2%,
rgba(61, 254, 250, 0) 100% rgba(61, 254, 250, 0) 100%
); );
.d{ .d {
margin-left: 1px; margin-left: 1px;
font-size: 12px; font-size: 12px;
} }

View File

@@ -17,6 +17,10 @@
export default { export default {
name: '', name: '',
props: { props: {
total: {
type: Object,
default: () => {}
},
deviceInfo: { deviceInfo: {
type: Array, type: Array,
default: () => [] default: () => []
@@ -24,55 +28,75 @@ export default {
}, },
data() { data() {
return { return {
uid:'1',
curList: [ curList: [
{ {
name: '日充电电量', name: '日充电电量',
key: 'key1', key: 'storage_elect_in',
lineColor: '#22E4FF', lineColor: '#22E4FF',
value: 0, value: 0,
d: 'kW·h' d: 'kW·h'
}, },
{ {
name: '日放电电量', name: '日放电电量',
key: 'key2', key: 'storage_elect_out',
lineColor: '#0E68E4', lineColor: '#0E68E4',
value: 0, value: 0,
d: 'kW·h' d: 'kW·h'
} }
], ],
faultChart: null, energyChart: null,
lineChartData: { energyChartData: {
ydata: [], ydata: [],
xdata: [] xdata: []
} }
} }
}, },
watch: { watch: {
total: {
handler(newVal,oldVal) {
if (newVal!==oldVal) {
let that = this
that.curList.forEach((item) => {
item.value = that.total[item.key]
})
}
},
},
deviceInfo: { deviceInfo: {
handler(n) { handler(newVal,oldVal) {
this.$nextTick(() => { if (JSON.stringify(newVal) !== JSON.stringify(oldVal)) {
this.drawLineChart() this.$nextTick(() => {
}) this.drawLineChart()
} })
// immediate: true }
},
deep: true // 确保深度比较
} }
}, },
mounted() {}, mounted() {},
onBeforeUnmount() { beforeUnmount() {
this.faultChart = null
window.removeEventListener('resize', this.handleResize) window.removeEventListener('resize', this.handleResize)
if(this.energyChart){
this.energyChart.dispose()
this.energyChart = null
}
}, },
methods: { methods: {
handleResize() { handleResize() {
this.faultChart.resize() if(this.energyChart){
this.energyChart.resize()
}
}, },
processData(data, keys) { processData(data, keys) {
console.log(data, 'dddddddddddddddddddddddddddd')
data.sort((a, b) => { data.sort((a, b) => {
return new Date(a.date) - new Date(b.date) return new Date(a.dt) - new Date(b.dt)
}) })
const dates = data.map((item) => item.date) const dates = data.map((item) => item.dt)
const values = [] const values = []
keys.forEach((item, index) => { keys.forEach((item, index) => {
values[index] = data.map((dataValue) => dataValue[keys[index]]) values[index] = data.map((dataValue) => dataValue[keys[index]])
@@ -88,9 +112,9 @@ export default {
const keyList = this.curList.map((item) => item.key) const keyList = this.curList.map((item) => item.key)
const result = this.processData(this.deviceInfo, keyList) const result = this.processData(this.deviceInfo, keyList)
this.lineChartData.xdata = result.dates this.energyChartData.xdata = result.dates
arr.forEach((item, index) => { arr.forEach((item, index) => {
this.lineChartData.ydata[index] = { this.energyChartData.ydata[index] = {
name: item.name, name: item.name,
smooth: true, smooth: true,
type: 'bar', type: 'bar',
@@ -111,9 +135,13 @@ export default {
drawLineChart(activeKey) { drawLineChart(activeKey) {
this.getChargeData(activeKey) this.getChargeData(activeKey)
if(this.energyChart){
this.energyChart.dispose()
}
const chartDom = document.getElementById('energy-chart') const chartDom = document.getElementById('energy-chart')
let faultChart = this.$echarts.init(chartDom) if (!chartDom) return;
this.faultChart = faultChart let energyChart = this.$echarts.init(chartDom)
this.energyChart = energyChart
const option = { const option = {
tooltip: { tooltip: {
trigger: 'axis', trigger: 'axis',
@@ -130,12 +158,12 @@ export default {
grid: { grid: {
left: '3%', left: '3%',
right: '4%', right: '4%',
bottom: '5%', bottom: '3%',
containLabel: true containLabel: true
}, },
xAxis: { xAxis: {
type: 'category', type: 'category',
data: this.lineChartData.xdata, data: this.energyChartData.xdata,
axisLine: { axisLine: {
lineStyle: { type: 'dashed', color: '#435463' } lineStyle: { type: 'dashed', color: '#435463' }
}, },
@@ -149,13 +177,17 @@ export default {
lineStyle: { type: 'dashed', color: '#435463' } lineStyle: { type: 'dashed', color: '#435463' }
}, },
axisLabel: { axisLabel: {
interval: 4,
color: '#fff' color: '#fff'
} }
}, },
series: this.lineChartData.ydata series: this.energyChartData.ydata
} }
option && faultChart.setOption(option) option && energyChart.setOption(option)
console.log(this.lineChartData, 'this.lineChartData') this.setupResizeListener()
},
setupResizeListener(){
window.removeEventListener('resize', this.handleResize);
window.addEventListener('resize', this.handleResize) window.addEventListener('resize', this.handleResize)
} }
} }

View File

@@ -1,7 +1,7 @@
<template> <template>
<div class="map"> <div class="map">
<div> <div>
<div class="icon1" @click="showModal()"></div> <div class="icon1" @click="showModal(testVal)"></div>
<div class="icon"></div> <div class="icon"></div>
</div> </div>
<div ref="mapContent"></div> <div ref="mapContent"></div>
@@ -42,16 +42,21 @@ export default {
testVal: { testVal: {
name: '场站211', name: '场站211',
id: '124563' id: '124563'
} },
changeStationId:''
} }
}, },
mounted() {}, mounted() {},
methods: { methods: {
async showModal(currentVal) { async showModal(currentVal) {
this.changeStationId=currentVal.id
this.$emit('changeStation',this.changeStationId)
console.log(currentVal, 'cccccccccccccccccccccc') console.log(currentVal, 'cccccccccccccccccccccc')
this.showCtrModal = true this.showCtrModal = true
try { try {
const query = {} const query = {
// station_id:this.changeStationId
}
const res = await postReq(query, '') const res = await postReq(query, '')
if (res.code == 200) { if (res.code == 200) {
this.modalInfo = res.data.records this.modalInfo = res.data.records

View File

@@ -8,7 +8,8 @@
<span class="linear-text">{{ item.title }}</span> <span class="linear-text">{{ item.title }}</span>
</div> </div>
</div> </div>
<component :is="item.componentId" :device-info="deviceInfo[item.infoKey]"></component> <component :is="item.componentId" :props-total="deviceInfo.allTotal" :props-info="deviceInfo[item.infoKey]" ></component>
</div> </div>
</div> </div>
@@ -20,7 +21,7 @@
<span class="linear-text">{{ item.title }}</span> <span class="linear-text">{{ item.title }}</span>
</div> </div>
</div> </div>
<component :is="item.componentId" :device-info="deviceInfo[item.infoKey]"></component> <component :is="item.componentId" :props-total="deviceInfo.allTotal" :props-info="deviceInfo[item.infoKey]" ></component>
</div> </div>
</div> </div>
</div> </div>
@@ -33,16 +34,13 @@ import StatisticalInfo from '@/components/Home/Modal/StatisticalInfo.vue'
import Revenue from '@/components/Home/Modal/Revenue.vue' import Revenue from '@/components/Home/Modal/Revenue.vue'
import Utilization from '@/components/Home/Modal/Utilization.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 Operational from '@/components/Home/Operational.vue' import { getReq, postReq } from '@/request/api'
import Charge from '@/components/Home/Charge.vue'
import Alarm from '@/components/Home/Alarm.vue'
import Map from '@/components/Home/Map_tianditu.vue'
import EnvInfo from './Modal/EnvInfo.vue' import EnvInfo from './Modal/EnvInfo.vue'
export default { export default {
name: 'Home', name: 'Home',
components: {Map}, components: {},
data() { data() {
return { return {
deviceInfo: {}, deviceInfo: {},
@@ -105,222 +103,144 @@ export default {
} }
}, },
async mounted() { async mounted() {
this.deviceInfo = { await Promise.all([
alarm: [ this.getTotalList(),
{
date: '2025-08-30',
key1: 10,
key2: 0,
key3: 15,
key4: 5
},
{
date: '2025-08-29',
key1: 8,
key2: 5,
key3: 5,
key4: 7
},
{
date: '2025-08-28',
key1: 0,
key2: 10,
key3: 20,
key4: 4
},
{
date: '2025-08-27',
key1: 10,
key2: 0,
key3: 15,
key4: 5
},
{
date: '2025-08-26',
key1: 10,
key2: 0,
key3: 15,
key4: 5
},
{
date: '2025-08-25',
key1: 10,
key2: 0,
key3: 15,
key4: 5
},
{
date: '2025-08-24',
key1: 10,
key2: 0,
key3: 15,
key4: 5
},
{
date: '2025-08-23',
key1: 10,
key2: 0,
key3: 15,
key4: 5
},
{
date: '2025-08-22',
key1: 10,
key2: 0,
key3: 15,
key4: 5
},
{
date: '2025-08-21',
key1: 10,
key2: 0,
key3: 15,
key4: 5
},
{
date: '2025-08-20',
key1: 10,
key2: 0,
key3: 15,
key4: 5
},
{
date: '2025-08-19',
key1: 10,
key2: 0,
key3: 15,
key4: 5
},
{
date: '2025-08-18',
key1: 10,
key2: 0,
key3: 15,
key4: 5
},
{
date: '2025-08-17',
key1: 10,
key2: 0,
key3: 15,
key4: 5
}
],
energy: [
{
date: '2025-08-30',
key1: '2',
key2: '2'
},
{
date: '2025-08-29',
key1: '2',
key2: '2'
},
{
date: '2025-08-28',
key1: '2',
key2: '2'
},
{
date: '2025-08-27',
key1: '2',
key2: '2'
},
{
date: '2025-08-26',
key1: '2',
key2: '2'
},
{
date: '2025-08-25',
key1: '2',
key2: '2'
},
{
date: '2025-08-24',
key1: '2',
key2: '2'
}
],
charge: [
{
date: '2025-08-30',
key1: '2',
key2: '2'
},
{
date: '2025-08-29',
key1: '2',
key2: '2'
},
{
date: '2025-08-28',
key1: '2',
key2: '2'
},
{
date: '2025-08-27',
key1: '2',
key2: '2'
},
{
date: '2025-08-26',
key1: '2',
key2: '2'
},
{
date: '2025-08-25',
key1: '2',
key2: '2'
},
{
date: '2025-08-24',
key1: '2',
key2: '2'
}
],
pv: [
{
date: '2025-08-30',
key1: '2',
key2: '2'
},
{
date: '2025-08-29',
key1: '2',
key2: '2'
},
{
date: '2025-08-28',
key1: '2',
key2: '2'
},
{
date: '2025-08-27',
key1: '2',
key2: '2'
},
{
date: '2025-08-26',
key1: '2',
key2: '2'
},
{
date: '2025-08-25',
key1: '2',
key2: '2'
},
{
date: '2025-08-24',
key1: '2',
key2: '2'
}
]
}
},
methods: {} ( this.deviceInfo = {
alarm: [
{
dt: '2025-08-30',
key1: 10,
key2: 0,
key3: 15,
key4: 5
},
{
dt: '2025-08-29',
key1: 8,
key2: 5,
key3: 5,
key4: 7
},
{
dt: '2025-08-28',
key1: 0,
key2: 10,
key3: 20,
key4: 4
},
{
dt: '2025-08-27',
key1: 10,
key2: 0,
key3: 15,
key4: 5
},
{
dt: '2025-08-26',
key1: 10,
key2: 0,
key3: 15,
key4: 5
},
{
dt: '2025-08-25',
key1: 10,
key2: 0,
key3: 15,
key4: 5
},
{
dt: '2025-08-24',
key1: 10,
key2: 0,
key3: 15,
key4: 5
},
{
dt: '2025-08-23',
key1: 10,
key2: 0,
key3: 15,
key4: 5
},
{
dt: '2025-08-22',
key1: 10,
key2: 0,
key3: 15,
key4: 5
},
{
dt: '2025-08-21',
key1: 10,
key2: 0,
key3: 15,
key4: 5
},
{
dt: '2025-08-20',
key1: 10,
key2: 0,
key3: 15,
key4: 5
},
{
dt: '2025-08-19',
key1: 10,
key2: 0,
key3: 15,
key4: 5
},
{
dt: '2025-08-18',
key1: 10,
key2: 0,
key3: 15,
key4: 5
},
{
dt: '2025-08-17',
key1: 10,
key2: 0,
key3: 15,
key4: 5
}
],
}),
])
},
methods: {
async getTotalList(){
try {
// token: 用户TOKEN
const res = await getReq({}, '')
if (res.code === 200) {
this.deviceInfo.allTotal = res.data
} else {
throw res
}
} catch (error) {
this.deviceInfo.allTotal = {
tianshu:11,
shouyi:12,
shuliang:10,
fadianliang:15,
key2:11,
key1:12,
key3:10,
key4:15,
rongliang:15,
}
}
}
}
} }
</script> </script>

View File

@@ -8,7 +8,7 @@
export default { export default {
name: '', name: '',
props: { props: {
deviceInfo: { propsInfo: {
type: Array, type: Array,
default: () => [] default: () => []
} }
@@ -20,71 +20,75 @@ export default {
name: '日充电电量', name: '日充电电量',
key: 'key1', key: 'key1',
lineColor: '#9BD801', lineColor: '#9BD801',
value:0, value: 0,
d:'kW·h' d: 'kW·h'
}, },
{ {
name: '日放电电量', name: '日放电电量',
key: 'key2', key: 'key2',
lineColor: '#3DFEFA', lineColor: '#3DFEFA',
value:0, value: 0,
d:'kW·h' d: 'kW·h'
}, }
], ],
disChargeChart: null, disChargeChart: null,
lineChartData: { disChargeChartData: {
ydata: [], ydata: [],
xdata: [] xdata: []
}, }
} }
}, },
watch: { watch: {
deviceInfo: { propsInfo: {
handler(n) { handler(newVal, oldVal) {
this.$nextTick(() => { if (JSON.stringify(newVal) !== JSON.stringify(oldVal)) {
this.drawLineChart() this.$nextTick(() => {
}) this.drawLineChart()
} })
// immediate: true }
},
deep: true // 确保深度比较
} }
}, },
mounted() {}, mounted() {},
onBeforeUnmount() { beforeUnmount() {
this.disChargeChart = null
window.removeEventListener('resize', this.handleResize) window.removeEventListener('resize', this.handleResize)
if (this.disChargeChart) {
this.disChargeChart.dispose()
this.disChargeChart = null
}
}, },
methods: { methods: {
handleResize() { handleResize() {
this.disChargeChart.resize() if (this.disChargeChart) {
this.disChargeChart.resize()
}
}, },
processData(data, keys) { processData(data, keys) {
console.log(data, 'dddddddddddddddddddddddddddd')
data.sort((a, b) => { data.sort((a, b) => {
return new Date(a.date) - new Date(b.date) return new Date(a.date) - new Date(b.date)
}) })
const dates = data.map((item) => item.date) const dates = data.map((item) => item.dt)
const values=[] const values = []
keys.forEach((item,index)=>{ keys.forEach((item, index) => {
values[index] = data.map((dataValue) => dataValue[keys[index]])
values[index]= data.map((dataValue)=>dataValue[keys[index]])
}) })
return { return {
dates, dates,
values, values
} }
}, },
getDisChargeData() { getDisChargeData() {
const arr=this.curList const arr = this.curList
const keyList=this.curList.map((item)=>item.key) const keyList = this.curList.map((item) => item.key)
const result = this.processData(this.deviceInfo, keyList) const result = this.processData(this.propsInfo, keyList)
this.lineChartData.xdata = result.dates this.disChargeChartData.xdata = result.dates
arr.forEach((item, index) => { arr.forEach((item, index) => {
this.lineChartData.ydata[index] = { this.disChargeChartData.ydata[index] = {
name: item.name, name: item.name,
smooth: false, smooth: false,
type: 'line', type: 'line',
@@ -96,18 +100,21 @@ export default {
emphasis: { emphasis: {
focus: 'series' focus: 'series'
}, },
global: false, global: false,
showSymbol: false, showSymbol: false,
data:result.values[index] data: result.values[index]
} }
}) })
}, },
drawLineChart(activeKey) { drawLineChart(activeKey) {
this.getDisChargeData(activeKey) this.getDisChargeData(activeKey)
if (this.disChargeChart) {
this.disChargeChart.dispose()
}
const chartDom = document.getElementById('disCharge-chart') const chartDom = document.getElementById('disCharge-chart')
if (!chartDom) return
let disChargeChart = this.$echarts.init(chartDom) let disChargeChart = this.$echarts.init(chartDom)
this.disChargeChart = disChargeChart this.disChargeChart = disChargeChart
const option = { const option = {
@@ -131,7 +138,7 @@ export default {
}, },
xAxis: { xAxis: {
type: 'category', type: 'category',
data: this.lineChartData.xdata, data: this.disChargeChartData.xdata,
axisLine: { axisLine: {
lineStyle: { type: 'dashed', color: '#435463' } lineStyle: { type: 'dashed', color: '#435463' }
}, },
@@ -148,10 +155,13 @@ export default {
color: '#fff' color: '#fff'
} }
}, },
series: this.lineChartData.ydata series: this.disChargeChartData.ydata
} }
option && disChargeChart.setOption(option) option && disChargeChart.setOption(option)
console.log(this.lineChartData, 'this.lineChartData') this.setupResizeListener()
},
setupResizeListener() {
window.removeEventListener('resize', this.handleResize)
window.addEventListener('resize', this.handleResize) window.addEventListener('resize', this.handleResize)
} }
} }
@@ -160,8 +170,7 @@ export default {
<style lang="scss" scoped> <style lang="scss" scoped>
.disCharge { .disCharge {
height:calc(100% - 45px); height: calc(100% - 45px);
#disCharge-chart { #disCharge-chart {
height: 100%; height: 100%;
@@ -179,12 +188,12 @@ export default {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
& > div:last-child{ & > div:last-child {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
align-items: end; align-items: end;
} }
.mark { .mark {
font-size: 16px; font-size: 16px;
margin-right: 2px; margin-right: 2px;
@@ -196,7 +205,7 @@ export default {
rgba(61, 254, 250, 0.15) 49.2%, rgba(61, 254, 250, 0.15) 49.2%,
rgba(61, 254, 250, 0) 100% rgba(61, 254, 250, 0) 100%
); );
.d{ .d {
margin-left: 1px; margin-left: 1px;
font-size: 12px; font-size: 12px;
} }

View File

@@ -2,72 +2,71 @@
<div class="onLine"> <div class="onLine">
<div class="content"> <div class="content">
<div v-for="item in list" :key="item.key" :class="`item ${item.class}`"> <div v-for="item in list" :key="item.key" :class="`item ${item.class}`">
<a-image :preview="false" :src="item.iconPath" :width="25" class="left"> </a-image> <i
:class="`iconfont icon-${item.icon}`"
:style="`font-size:25px; cursor: pointer; color: ${item.color};`"
/>
<div class="right"> <div class="right">
<span>{{ item.label }}</span> <span>{{ item.label }}</span>
<span>{{ item.value }} {{ item.d }}</span <span>{{ item.value }} {{ item.d }}</span>
> </div>
</div>
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import { legacyLogicalPropertiesTransformer } from 'ant-design-vue'
export default { export default {
name: '', name: '',
props: { props: {
propsInfo: { propsTotal: {
type: Object, type: Object,
default: ()=>({ default: () => {}
name: '场站111', },
statusName:'充电' propsInfo: {
}) type: Array,
default: () => []
} }
}, },
data() { data() {
return { return {
list: [ list: [
{ {
key: 'tianshu', key: 'key1',
value: 26, value: '制冷',
d: 'Lux', d: '',
label: '光照', label: '冷机',
class: 'item-1', class: 'item-1',
iconPath: require('@/assets/home/guangzhao.png') icon: 'lengji',
color: '#F69B52'
}, },
{ {
key: 'shouyi', key: 'key2',
value: 25, value: '开机',
d: 'm/s', d: '',
label: '风速', label: '空调',
class: 'item-2', class: 'item-2',
iconPath: require('@/assets/home/fengsu.png') icon: 'kongdiaogongcheng',
color: '#9BD801'
}, },
{ {
key: 'shuliang', key: 'key3',
value: 24, value: 24,
d: '℃', d: '℃',
label: '环境温度', label: '环境温度',
class: 'item-3', class: 'item-3',
iconPath: require('@/assets/home/hj-wendu.png') icon: 'wenduji',
color: '#3DFEFA'
}, },
{ {
key: 'shuliang', key: 'key4',
value: 26, value: 26,
d: '%', d: '%',
label: '环境湿度', label: '环境湿度',
class: 'item-4', class: 'item-4',
iconPath: require('@/assets/home/hj-shidu.png') icon: 'shidu',
}, color: '#D83D6C'
}
] ]
} }
}, },
@@ -79,7 +78,17 @@ export default {
return this.list.filter((_, index) => index % 2 !== 0).slice(0, 3) // 右列取前3个奇数索引 return this.list.filter((_, index) => index % 2 !== 0).slice(0, 3) // 右列取前3个奇数索引
} }
}, },
watch: {}, watch: {
propsTotal: {
handler(newVal, oldVal) {
if (newVal !== oldVal) {
this.list.forEach((item) => {
item.value = this.propsTotal[item.key]
})
}
}
}
},
mounted() {}, mounted() {},
methods: {} methods: {}
} }
@@ -91,13 +100,11 @@ export default {
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
width:95%; width: 95%;
margin: auto; margin: auto;
} }
.content {
.content{
flex-wrap: wrap; flex-wrap: wrap;
width: 100%; width: 100%;
display: flex; display: flex;
@@ -105,35 +112,30 @@ export default {
justify-content: space-around; justify-content: space-around;
height: 100%; height: 100%;
.item{ .item {
height:50%; height: 50%;
width: 25%; width: 25%;
// height: 47px; // height: 47px;
box-sizing: border-box; box-sizing: border-box;
display: flex; display: flex;
align-items: center; align-items: center;
// justify-content: center; // justify-content: center;
// text-align: center; // text-align: center;
& > span:nth-child(1) { & > span:nth-child(1) {
font-size: 12px; font-size: 12px;
margin-bottom: 10px; margin-bottom: 10px;
}
.d {
margin-left: 1px;
font-size: 12px;
}
} }
.d {
margin-left: 1px;
font-size: 12px;
}
}
.right { .right {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
margin-left: 20px; margin-left: 20px;
}
} }
}
</style> </style>

View File

@@ -4,33 +4,27 @@
<div v-for="item in list" :key="item.key" :class="`item ${item.class}`"> <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> <a-image :preview="false" :src="item.iconPath" :width="50" class="left"> </a-image>
<div class="right"> <div class="right">
<span>{{ item.label }}</span> <span>{{ item.label }}</span>
<span>{{ item.value }} {{ item.d }}</span <span>{{ item.value }} {{ item.d }}</span>
> </div>
</div>
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import { legacyLogicalPropertiesTransformer } from 'ant-design-vue'
export default { export default {
name: '', name: '',
props: { props: {
propsInfo: { propsTotal: {
type: Object, type: Object,
default: ()=>({ default: () => {}
name: '场站111', },
statusName:'充电' propsInfo: {
}) type: Array,
} default: () => []
},
}, },
data() { data() {
return { return {
@@ -94,7 +88,18 @@ export default {
return this.list.filter((_, index) => index % 2 !== 0).slice(0, 3) // 右列取前3个奇数索引 return this.list.filter((_, index) => index % 2 !== 0).slice(0, 3) // 右列取前3个奇数索引
} }
}, },
watch: {}, watch: {
propsTotal: {
handler(newVal, oldVal) {
if (newVal !== oldVal) {
this.list.forEach((item) => {
item.value = this.propsTotal[item.key]
})
}
},
}
},
mounted() {}, mounted() {},
methods: {} methods: {}
} }
@@ -106,14 +111,11 @@ export default {
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
width:95%; width: 95%;
margin: auto; margin: auto;
} }
.content {
.content{
flex-wrap: wrap; flex-wrap: wrap;
width: 100%; width: 100%;
display: flex; display: flex;
@@ -121,35 +123,30 @@ export default {
justify-content: space-around; justify-content: space-around;
height: 100%; height: 100%;
.item{ .item {
height:50%; height: 50%;
width: 30%; width: 30%;
// height: 47px; // height: 47px;
box-sizing: border-box; box-sizing: border-box;
display: flex; display: flex;
align-items: center; align-items: center;
// justify-content: center; // justify-content: center;
// text-align: center; // text-align: center;
& > span:nth-child(1) { & > span:nth-child(1) {
font-size: 12px; font-size: 12px;
margin-bottom: 10px; margin-bottom: 10px;
}
.d {
margin-left: 1px;
font-size: 12px;
}
} }
.d {
margin-left: 1px;
font-size: 12px;
}
}
.right { .right {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
margin-left: 20px; margin-left: 20px;
}
} }
}
</style> </style>

View File

@@ -3,21 +3,21 @@
<div class="content-left"> <div class="content-left">
<div v-for="item in leftList" :key="item.key" :class="`item ${item.class}`"> <div v-for="item in leftList" :key="item.key" :class="`item ${item.class}`">
<div> <div>
<span>{{ item.value }}</span <span>{{ item.value ? item.value : 0 }}</span
><span class="d">{{ item.d }}</span> ><span class="d">{{ item.d }}</span>
</div> </div>
<span>{{ item.label }}</span> <span>{{ item.label }}</span>
</div> </div>
</div> </div>
<div style="text-align: center;font-weight: 500;"> <div style="text-align: center; font-weight: 500">
<div class="online-icon"></div> <div class="online-icon"></div>
<span>{{ propsInfo.statusName }}</span> <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 v-for="item in rightList" :key="item.key" :class="`item ${item.class}`">
<div> <div>
<span>{{ item.value }}</span <span>{{ item.value ? item.value : 0 }}</span
><span class="d">{{ item.d }}</span> ><span class="d">{{ item.d }}</span>
</div> </div>
<span>{{ item.label }}</span> <span>{{ item.label }}</span>
@@ -27,21 +27,21 @@
</template> </template>
<script> <script>
import { legacyLogicalPropertiesTransformer } from 'ant-design-vue'
export default { export default {
name: '', name: '',
props: { props: {
propsInfo: { propsTotal: {
type: Object, type: Object,
default: () => ({ default: () => {}
name: '场站111', },
statusName: '充电' propsInfo: {
}) type: Array,
default: () => []
} }
}, },
data() { data() {
return { return {
curStatus: '充电',
list: [ list: [
{ {
key: 'tianshu', key: 'tianshu',
@@ -96,7 +96,17 @@ export default {
return this.list.filter((_, index) => index % 2 !== 0).slice(0, 3) // 右列取前3个奇数索引 return this.list.filter((_, index) => index % 2 !== 0).slice(0, 3) // 右列取前3个奇数索引
} }
}, },
watch: {}, watch: {
propsTotal: {
handler(newVal, oldVal) {
if (newVal !== oldVal) {
this.list.forEach((item) => {
item.value = this.propsTotal[item.key]
})
}
}
}
},
mounted() {}, mounted() {},
methods: {} methods: {}
} }

View File

@@ -8,7 +8,7 @@
export default { export default {
name: '', name: '',
props: { props: {
deviceInfo: { propsInfo: {
type: Array, type: Array,
default: () => [] default: () => []
} }
@@ -29,7 +29,7 @@ export default {
], ],
revenueChart: null, revenueChart: null,
lineChartData: { RevenueChartData: {
ydata: [], ydata: [],
xdata: [] xdata: []
}, },
@@ -37,31 +37,38 @@ export default {
} }
}, },
watch: { watch: {
deviceInfo: { propsInfo: {
handler(n) { handler(newVal, oldVal) {
this.$nextTick(() => { if (JSON.stringify(newVal) !== JSON.stringify(oldVal)) {
this.drawLineChart() this.$nextTick(() => {
}) this.drawLineChart()
} })
// immediate: true }
},
deep: true // 确保深度比较
} }
}, },
mounted() {}, mounted() {},
onBeforeUnmount() { beforeUnmount() {
this.revenueChart = null
window.removeEventListener('resize', this.handleResize) window.removeEventListener('resize', this.handleResize)
if (this.revenueChart) {
this.revenueChart.dispose()
this.revenueChart = null
}
}, },
methods: { methods: {
handleResize() { handleResize() {
this.revenueChart.resize() if (this.revenueChart) {
this.revenueChart.resize()
}
}, },
processData(data, keys) { processData(data, keys) {
console.log(data, 'dddddddddddddddddddddddddddd')
data.sort((a, b) => { data.sort((a, b) => {
return new Date(a.date) - new Date(b.date) return new Date(a.date) - new Date(b.date)
}) })
const dates = data.map((item) => item.date) const dates = data.map((item) => item.dt)
const values=[] const values=[]
keys.forEach((item,index)=>{ keys.forEach((item,index)=>{
@@ -76,11 +83,11 @@ export default {
getRevenueData() { getRevenueData() {
const arr=this.curList const arr=this.curList
const keyList=this.curList.map((item)=>item.key) const keyList=this.curList.map((item)=>item.key)
const result = this.processData(this.deviceInfo, keyList) const result = this.processData(this.propsInfo, keyList)
this.lineChartData.xdata = result.dates this.RevenueChartData.xdata = result.dates
arr.forEach((item, index) => { arr.forEach((item, index) => {
this.lineChartData.ydata[index] = { this.RevenueChartData.ydata[index] = {
name: item.name, name: item.name,
smooth: true, smooth: true,
type: 'line', type: 'line',
@@ -116,7 +123,11 @@ export default {
drawLineChart(activeKey) { drawLineChart(activeKey) {
this.getRevenueData(activeKey) this.getRevenueData(activeKey)
if (this.revenueChart) {
this.revenueChart.dispose()
}
const chartDom = document.getElementById('revenue-chart') const chartDom = document.getElementById('revenue-chart')
if (!chartDom) return
let revenueChart = this.$echarts.init(chartDom) let revenueChart = this.$echarts.init(chartDom)
this.revenueChart = revenueChart this.revenueChart = revenueChart
const option = { const option = {
@@ -140,7 +151,7 @@ export default {
}, },
xAxis: { xAxis: {
type: 'category', type: 'category',
data: this.lineChartData.xdata, data: this.RevenueChartData.xdata,
axisLine: { axisLine: {
lineStyle: { type: 'dashed', color: '#435463' } lineStyle: { type: 'dashed', color: '#435463' }
}, },
@@ -157,10 +168,14 @@ export default {
color: '#fff' color: '#fff'
} }
}, },
series: this.lineChartData.ydata series: this.RevenueChartData.ydata
} }
option && revenueChart.setOption(option) option && revenueChart.setOption(option)
console.log(this.lineChartData, 'this.lineChartData') this.setupResizeListener()
},
setupResizeListener() {
window.removeEventListener('resize', this.handleResize)
window.addEventListener('resize', this.handleResize) window.addEventListener('resize', this.handleResize)
} }
} }

View File

@@ -2,7 +2,7 @@
<div class="onLine"> <div class="onLine">
<div class="content"> <div class="content">
<div v-for="item in list" :key="item.key" :class="`item ${item.class}`"> <div v-for="item in list" :key="item.key" :class="`item ${item.class}`">
<span>{{ item.value }} {{ item.d }}</span> <span>{{ item.value ? item.value : 0 }} {{ item.d }}</span>
<span>{{ item.label }}</span> <span>{{ item.label }}</span>
</div> </div>
</div> </div>
@@ -10,11 +10,13 @@
</template> </template>
<script> <script>
import { legacyLogicalPropertiesTransformer } from 'ant-design-vue'
export default { export default {
name: '', name: '',
props: { props: {
propsTotal: {
type: Object,
default: () => {}
},
propsInfo: { propsInfo: {
type: Object, type: Object,
default: () => ({ default: () => ({
@@ -77,7 +79,17 @@ export default {
return this.list.filter((_, index) => index % 2 !== 0).slice(0, 3) // 右列取前3个奇数索引 return this.list.filter((_, index) => index % 2 !== 0).slice(0, 3) // 右列取前3个奇数索引
} }
}, },
watch: {}, watch: {
propsTotal: {
handler(newVal, oldVal) {
if (newVal !== oldVal) {
this.list.forEach((item) => {
item.value = this.propsTotal[item.key]
})
}
}
}
},
mounted() {}, mounted() {},
methods: {} methods: {}
} }
@@ -89,7 +101,7 @@ export default {
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
width:95%; width: 95%;
margin: auto; margin: auto;
} }

View File

@@ -8,7 +8,7 @@
export default { export default {
name: '', name: '',
props: { props: {
deviceInfo: { propsInfo: {
type: Array, type: Array,
default: () => [] default: () => []
} }
@@ -20,65 +20,69 @@ export default {
name: '日设备利用率', name: '日设备利用率',
key: 'key1', key: 'key1',
lineColor: '#F69B52', lineColor: '#F69B52',
value:0, value: 0,
d:'kW·h' d: 'kW·h'
}, }
], ],
utilizationChart: null, utilizationChart: null,
lineChartData: { utilizationChartData: {
ydata: [], ydata: [],
xdata: [] xdata: []
}, }
} }
}, },
watch: { watch: {
deviceInfo: { propsInfo: {
handler(n) { handler(newVal, oldVal) {
this.$nextTick(() => { if (JSON.stringify(newVal) !== JSON.stringify(oldVal)) {
this.drawLineChart() this.$nextTick(() => {
}) this.drawLineChart()
} })
// immediate: true }
},
deep: true // 确保深度比较
} }
}, },
mounted() {}, mounted() {},
onBeforeUnmount() { beforeUnmount() {
this.utilizationChart = null
window.removeEventListener('resize', this.handleResize) window.removeEventListener('resize', this.handleResize)
if (this.utilizationChart) {
this.utilizationChart.dispose()
this.utilizationChart = null
}
}, },
methods: { methods: {
handleResize() { handleResize() {
this.utilizationChart.resize() if (this.utilizationChart) {
this.utilizationChart.resize()
}
}, },
processData(data, keys) { processData(data, keys) {
console.log(data, 'dddddddddddddddddddddddddddd')
data.sort((a, b) => { data.sort((a, b) => {
return new Date(a.date) - new Date(b.date) return new Date(a.date) - new Date(b.date)
}) })
const dates = data.map((item) => item.date) const dates = data.map((item) => item.dt)
const values=[] const values = []
keys.forEach((item,index)=>{ keys.forEach((item, index) => {
values[index] = data.map((dataValue) => dataValue[keys[index]])
values[index]= data.map((dataValue)=>dataValue[keys[index]])
}) })
return { return {
dates, dates,
values, values
} }
}, },
getUtilizationData() { getUtilizationData() {
const arr=this.curList const arr = this.curList
const keyList=this.curList.map((item)=>item.key) const keyList = this.curList.map((item) => item.key)
const result = this.processData(this.deviceInfo, keyList) const result = this.processData(this.propsInfo, keyList)
this.lineChartData.xdata = result.dates this.utilizationChartData.xdata = result.dates
arr.forEach((item, index) => { arr.forEach((item, index) => {
this.lineChartData.ydata[index] = { this.utilizationChartData.ydata[index] = {
name: item.name, name: item.name,
smooth: false, smooth: false,
type: 'line', type: 'line',
@@ -90,18 +94,21 @@ export default {
emphasis: { emphasis: {
focus: 'series' focus: 'series'
}, },
global: false, global: false,
showSymbol: false, showSymbol: false,
data:result.values[index] data: result.values[index]
} }
}) })
}, },
drawLineChart(activeKey) { drawLineChart(activeKey) {
this.getUtilizationData(activeKey) this.getUtilizationData(activeKey)
if (this.utilizationChart) {
this.utilizationChart.dispose()
}
const chartDom = document.getElementById('utilization-chart') const chartDom = document.getElementById('utilization-chart')
if (!chartDom) return
let utilizationChart = this.$echarts.init(chartDom) let utilizationChart = this.$echarts.init(chartDom)
this.utilizationChart = utilizationChart this.utilizationChart = utilizationChart
const option = { const option = {
@@ -125,7 +132,7 @@ export default {
}, },
xAxis: { xAxis: {
type: 'category', type: 'category',
data: this.lineChartData.xdata, data: this.utilizationChartData.xdata,
axisLine: { axisLine: {
lineStyle: { type: 'dashed', color: '#435463' } lineStyle: { type: 'dashed', color: '#435463' }
}, },
@@ -142,10 +149,13 @@ export default {
color: '#fff' color: '#fff'
} }
}, },
series: this.lineChartData.ydata series: this.utilizationChartData.ydata
} }
option && utilizationChart.setOption(option) option && utilizationChart.setOption(option)
console.log(this.lineChartData, 'this.lineChartData') this.setupResizeListener()
},
setupResizeListener() {
window.removeEventListener('resize', this.handleResize)
window.addEventListener('resize', this.handleResize) window.addEventListener('resize', this.handleResize)
} }
} }
@@ -154,10 +164,10 @@ export default {
<style lang="scss" scoped> <style lang="scss" scoped>
.utilization { .utilization {
height:calc(100% - 45px); height: calc(100% - 45px);
#utilization-chart { #utilization-chart {
height:100%; height: 100%;
} }
} }
@@ -172,12 +182,12 @@ export default {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
& > div:last-child{ & > div:last-child {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
align-items: end; align-items: end;
} }
.mark { .mark {
font-size: 16px; font-size: 16px;
margin-right: 2px; margin-right: 2px;
@@ -189,7 +199,7 @@ export default {
rgba(61, 254, 250, 0.15) 49.2%, rgba(61, 254, 250, 0.15) 49.2%,
rgba(61, 254, 250, 0) 100% rgba(61, 254, 250, 0) 100%
); );
.d{ .d {
margin-left: 1px; margin-left: 1px;
font-size: 12px; font-size: 12px;
} }

View File

@@ -2,12 +2,12 @@
<div class="Operational"> <div class="Operational">
<div class="oper-bg">{{ currentHoverNumber }}%</div> <div class="oper-bg">{{ currentHoverNumber }}%</div>
<div class="oper-right"> <div class="oper-right">
<div v-for="item in list" :key="item.key" class="oper-item" @mouseover="changeNumber(item)"> <div v-for="item in curList" :key="item.key" class="oper-item" @mouseover="changeNumber(item)">
<div style="display: flex"> <div style="display: flex">
<div :style="`background:${item.lineColor}`" class="item-icon"></div> <div :style="`background:${item.lineColor}`" class="item-icon"></div>
<span class="item-name">{{ item.name }}</span> <span class="item-name">{{ item.name }}</span>
</div> </div>
<span class="item-value">{{ item.value }}</span> <span class="item-value">{{ item.value?item.value:0 }}</span>
</div> </div>
</div> </div>
</div> </div>
@@ -17,6 +17,10 @@
export default { export default {
name: '', name: '',
props: { props: {
total:{
type:Object,
default:()=>{}
},
deviceInfo: { deviceInfo: {
type: Array, type: Array,
default: () => [] default: () => []
@@ -25,17 +29,17 @@ export default {
data() { data() {
return { return {
currentHoverNumber: 58, currentHoverNumber: 58,
list: [ curList: [
{ {
name: '收益', name: '收益',
key: 'connector_online', key: 'incomeTotal',
percentKey: 'connector_online_percent', percentKey: 'connector_online_percent',
lineColor: 'linear-gradient(90deg, rgba(13, 87, 144, 1) 0%, rgba(21, 153, 253, 1) 100%);', lineColor: 'linear-gradient(90deg, rgba(13, 87, 144, 1) 0%, rgba(21, 153, 253, 1) 100%);',
value: 0 value: 0
}, },
{ {
name: '利用率', name: '利用率',
key: 'connector_off', key: 'usage_rate',
percentKey: 'connector_off_percent', percentKey: 'connector_off_percent',
lineColor: lineColor:
'linear-gradient(90deg, rgba(53, 120, 124, 1) 0%, rgba(102, 225, 223, 1) 100%);', 'linear-gradient(90deg, rgba(53, 120, 124, 1) 0%, rgba(102, 225, 223, 1) 100%);',
@@ -44,7 +48,21 @@ export default {
] ]
} }
}, },
watch: {}, watch: {
total:{
handler(newVal,oldVal) {
if (newVal!==oldVal) {
let that=this
that.curList.forEach((item)=>{
item.value=that.total[item.key]
})
}
}
}
},
mounted() {}, mounted() {},
methods: { methods: {

View File

@@ -17,6 +17,10 @@
export default { export default {
name: '', name: '',
props: { props: {
total: {
type: Object,
default: () => {}
},
deviceInfo: { deviceInfo: {
type: Array, type: Array,
default: () => [] default: () => []
@@ -27,21 +31,21 @@ export default {
curList: [ curList: [
{ {
name: '日发电量', name: '日发电量',
key: 'key1', key: 'solar_elect_gen',
lineColor: '#22E4FF', lineColor: '#22E4FF',
value: 0, value: 0,
d: 'kW·h' d: 'kW·h'
}, },
{ {
name: '日入网电量', name: '日入网电量',
key: 'key2', key: 'solar_elect_grid',
lineColor: '#0E68E4', lineColor: '#0E68E4',
value: 0, value: 0,
d: 'kW·h' d: 'kW·h'
} }
], ],
faultChart: null, pvChart: null,
lineChartData: { pvChartData: {
ydata: [], ydata: [],
xdata: [] xdata: []
}, },
@@ -53,31 +57,47 @@ export default {
} }
}, },
watch: { watch: {
deviceInfo: { total: {
handler(n) { handler(newVal, oldVal) {
this.$nextTick(() => { if (newVal !== oldVal) {
this.drawLineChart() let that = this
}) that.curList.forEach((item) => {
item.value = that.total[item.key]
})
}
} }
// immediate: true },
deviceInfo: {
handler(newVal, oldVal) {
if (JSON.stringify(newVal) !== JSON.stringify(oldVal)) {
this.$nextTick(() => {
this.drawLineChart()
})
}
},
deep: true // 确保深度比较
} }
}, },
mounted() {}, mounted() {},
onBeforeUnmount() { beforeUnmount() {
this.faultChart = null
window.removeEventListener('resize', this.handleResize) window.removeEventListener('resize', this.handleResize)
if (this.pvChart) {
this.pvChart.dispose()
this.pvChart = null
}
}, },
methods: { methods: {
handleResize() { handleResize() {
this.faultChart.resize() if (this.pvChart) {
this.pvChart.resize()
}
}, },
processData(data, keys) { processData(data, keys) {
console.log(data, 'dddddddddddddddddddddddddddd')
data.sort((a, b) => { data.sort((a, b) => {
return new Date(a.date) - new Date(b.date) return new Date(a.dt) - new Date(b.dt)
}) })
const dates = data.map((item) => item.date) const dates = data.map((item) => item.dt)
const values = [] const values = []
keys.forEach((item, index) => { keys.forEach((item, index) => {
values[index] = data.map((dataValue) => dataValue[keys[index]]) values[index] = data.map((dataValue) => dataValue[keys[index]])
@@ -93,9 +113,9 @@ export default {
const keyList = this.curList.map((item) => item.key) const keyList = this.curList.map((item) => item.key)
const result = this.processData(this.deviceInfo, keyList) const result = this.processData(this.deviceInfo, keyList)
this.lineChartData.xdata = result.dates this.pvChartData.xdata = result.dates
arr.forEach((item, index) => { arr.forEach((item, index) => {
this.lineChartData.ydata[index] = { this.pvChartData.ydata[index] = {
name: item.name, name: item.name,
smooth: true, smooth: true,
type: 'bar', type: 'bar',
@@ -116,9 +136,13 @@ export default {
drawLineChart(activeKey) { drawLineChart(activeKey) {
this.getChargeData(activeKey) this.getChargeData(activeKey)
if (this.pvChart) {
this.pvChart.dispose()
}
const chartDom = document.getElementById('pv-chart') const chartDom = document.getElementById('pv-chart')
let faultChart = this.$echarts.init(chartDom) if (!chartDom) return
this.faultChart = faultChart let pvChart = this.$echarts.init(chartDom)
this.pvChart = pvChart
const option = { const option = {
tooltip: { tooltip: {
trigger: 'axis', trigger: 'axis',
@@ -140,7 +164,7 @@ export default {
}, },
xAxis: { xAxis: {
type: 'category', type: 'category',
data: this.lineChartData.xdata, data: this.pvChartData.xdata,
axisLine: { axisLine: {
lineStyle: { type: 'dashed', color: '#435463' } lineStyle: { type: 'dashed', color: '#435463' }
}, },
@@ -154,13 +178,17 @@ export default {
lineStyle: { type: 'dashed', color: '#435463' } lineStyle: { type: 'dashed', color: '#435463' }
}, },
axisLabel: { axisLabel: {
interval: 4,
color: '#fff' color: '#fff'
} }
}, },
series: this.lineChartData.ydata series: this.pvChartData.ydata
} }
option && faultChart.setOption(option) option && pvChart.setOption(option)
console.log(this.lineChartData, 'this.lineChartData') this.setupResizeListener()
},
setupResizeListener() {
window.removeEventListener('resize', this.handleResize)
window.addEventListener('resize', this.handleResize) window.addEventListener('resize', this.handleResize)
} }
} }

View File

@@ -3,14 +3,20 @@
<div class="content-left"> <div class="content-left">
<div v-for="item in leftList" :key="item.key" :class="`item ${item.class}`"> <div v-for="item in leftList" :key="item.key" :class="`item ${item.class}`">
<span>{{ item.label }}</span> <span>{{ item.label }}</span>
<div> <span>{{ item.value }}</span><span class="d">{{ item.d }}</span></div> <div>
<span>{{ item.value ? item.value : 0 }}</span
><span class="d">{{ item.d }}</span>
</div>
</div> </div>
</div> </div>
<div class="online-icon"></div> <div class="online-icon"></div>
<div class="content-right"> <div class="content-right">
<div v-for="item in rightList" :key="item.key" :class="`item ${item.class}`"> <div v-for="item in rightList" :key="item.key" :class="`item ${item.class}`">
<span>{{ item.label }}</span> <span>{{ item.label }}</span>
<div> <span>{{ item.value }}</span><span class="d">{{ item.d }}</span></div> <div>
<span>{{ item.value ? item.value : 0 }}</span
><span class="d">{{ item.d }}</span>
</div>
</div> </div>
</div> </div>
</div> </div>
@@ -20,6 +26,14 @@
export default { export default {
name: '', name: '',
props: { props: {
infoKey: {
type: String,
default:''
},
total: {
type: Object,
default: () => {}
},
deviceInfo: { deviceInfo: {
type: Array, type: Array,
default: () => [] default: () => []
@@ -27,44 +41,44 @@ export default {
}, },
data() { data() {
return { return {
list: [ curList: [
{ {
key: 'tianshu', key: 'runDays', //根据launch_date字段计算得出
value: 20, value: 20,
d: '天', d: '天',
label: '系统运行天数', label: '系统运行天数',
class: 'item-1' class: 'item-1'
}, },
{ {
key: 'shouyi', key: 'income_total',
value: 10, value: 10,
d: '元', d: '元',
label: '累计收益', label: '累计收益',
class: 'item-2' class: 'item-2'
}, },
{ {
key: 'shuliang', key: 'solar_device_num',
value: 20, value: 20,
d: '', d: '',
label: '光伏设备数量', label: '光伏设备数量',
class: 'item-3' class: 'item-3'
}, },
{ {
key: 'shuliang', key: 'storage_device_num',
value: 20, value: 20,
d: '', d: '',
label: '储能预制舱数量', label: '储能预制舱数量',
class: 'item-4' class: 'item-4'
}, },
{ {
key: 'fadianliang', key: 'solar_elect_gen',
value: 20, value: 20,
d: '', d: '',
label: '光伏设备累计发电量', label: '光伏设备累计发电量',
class: 'item-5' class: 'item-5'
}, },
{ {
key: 'rongliang', key: 'capacity_total',
value: 20, value: 20,
d: '', d: '',
label: '储能总容量', label: '储能总容量',
@@ -75,14 +89,29 @@ export default {
}, },
computed: { computed: {
leftList() { leftList() {
return this.list.filter((_, index) => index % 2 === 0).slice(0, 3) // 左列取前3个偶数索引 return this.curList.filter((_, index) => index % 2 === 0).slice(0, 3) // 左列取前3个偶数索引
}, },
rightList() { rightList() {
return this.list.filter((_, index) => index % 2 !== 0).slice(0, 3) // 右列取前3个奇数索引 return this.curList.filter((_, index) => index % 2 !== 0).slice(0, 3) // 右列取前3个奇数索引
} }
}, },
watch: {},
mounted() {}, watch: {
total: {
handler(newVal,oldVal) {
if (newVal&&newVal!==oldVal) {
this.curList.forEach((item) => {
item.value = newVal[item.key] || 0;
});
}
},
immediate: true,
deep: true
}
},
mounted() {
console.log(this.total,'total')
},
methods: {} methods: {}
} }
</script> </script>
@@ -111,12 +140,10 @@ export default {
font-size: 12px; font-size: 12px;
margin-bottom: 10px; margin-bottom: 10px;
} }
.d{ .d {
margin-left: 1px; margin-left: 1px;
font-size: 12px; font-size: 12px;
} }
} }
.content-left, .content-left,

View File

@@ -49,23 +49,23 @@ export default {
type: Object, type: Object,
default: () => ({}), // 默认空对象 default: () => ({}), // 默认空对象
required: false // 非必须 required: false // 非必须
},
tableData: {
type: Array,
default: () => ([]), // 默认空对象
} }
}, },
data() { data() {
return { return {
paramsDate: {}, paramsDate: {},
tableData: [],
tableOption: { tableOption: {
scroll: { scroll: {
x: 1500 x: 1500
} },
select: false,
}, },
tableH: 0, tableH: 0,
pageOption: {
current: 1,
pageSize: 15,
total: 1
},
// chartOptions: [ // chartOptions: [
// { // {
// title: '充放电分析', // title: '充放电分析',
@@ -233,50 +233,27 @@ export default {
chartInstances: [] // 存储 ECharts 实例 chartInstances: [] // 存储 ECharts 实例
} }
}, },
watch:{
chartData: {
handler(n) {
this.$nextTick(() => {
this.initCharts()
window.addEventListener('resize', this.handleResize)
})
}
}
},
mounted() { mounted() {
this.$nextTick(() => {
// 确保 DOM 完全渲染
this.initCharts()
window.addEventListener('resize', this.handleResize)
})
}, },
beforeUnmount() { beforeUnmount() {
window.removeEventListener('resize', this.handleResize) window.removeEventListener('resize', this.handleResize)
this.chartInstances.forEach((chart) => chart && chart.dispose()) this.chartInstances.forEach((chart) => chart && chart.dispose())
}, },
methods: { methods: {
async getList() {
let that = this
this.$refs.comTable.loading = true
const query = {
...this.paramsDate,
pageSize: this.pageOption.pageSize,
pageNumber: this.pageOption.current
}
try {
const res = await postReq(query, this.tableInfo.getUrl)
if (res.code === 200) {
this.$refs.comTable.loading = false
this.tableData = res.data.records
this.pageOption = {
current: res.data.pageNumber,
pageSize: res.data.pageSize,
total: res.data.totalRow
}
this.getScrollDateFail = false
} else {
throw res
}
} catch (error) {
that.tableData = []
that.$refs.comTable.loading = false
}
},
initCharts() { initCharts() {
this.chartOptions.forEach((option, index) => { this.chartOptions.forEach((option, index) => {
// Vue 2 的 $refs 在 v-for 中是数组,需要取 [0]
const dom = this.$refs[`chartContainer${index}`][0] const dom = this.$refs[`chartContainer${index}`][0]
console.log(dom, 'ddddddddddddddd')
if (!dom) return if (!dom) return
const chart = this.$echarts.init(dom) const chart = this.$echarts.init(dom)
@@ -363,17 +340,15 @@ export default {
}, },
processData(keysList, dataKey, data) { processData(keysList, dataKey, data) {
const keys = keysList.map((item) => item.key) const keys = keysList.map((item) => item.key)
console.log(keys, dataKey, data, 'dddddddddddddddddddddddddddd')
data.sort((a, b) => { data.sort((a, b) => {
return new Date(a.date) - new Date(b.date) return new Date(a.dt) - new Date(b.dt)
}) })
const dates = data.map((item) => item.date) const dates = data.map((item) => item.dt)
const values = [] const values = []
keys.forEach((item, index) => { keys.forEach((item, index) => {
values[index] = data.map((dataValue) => dataValue[keys[index]]) values[index] = data.map((dataValue) => dataValue[keys[index]])
}) })
console.log(dates, values, 'dates')
return { return {
dates, dates,
values values
@@ -384,9 +359,10 @@ export default {
}, },
handlePagesizeChange(pageOption) { handlePagesizeChange(pageOption) {
this.pageOption.pageSize = pageOption.pageSize this.$emit('pagesizeChange_energy',pageOption)
this.pageOption.current = pageOption.current // this.pageOption.pageSize = pageOption.pageSize
this.getList() // this.pageOption.current = pageOption.current
// this.getList()
} }
} }
} }
@@ -394,7 +370,7 @@ export default {
<style lang="scss" scoped> <style lang="scss" scoped>
.content { .content {
height: calc(100% - 38px); height: calc(100% - 10px);
overflow: scroll; overflow: scroll;
} }
.content-echarts { .content-echarts {

File diff suppressed because it is too large Load Diff

View File

@@ -1,28 +1,48 @@
<template> <template>
<div class="Home"> <div class="Home">
<div class="content-left"> <div class="content-left">
<div v-for="(item, i) in leftList" :key="i" :class="`grid-item ${item.class}`"> <div
v-for="item in leftList"
:key="item.componentId"
:class="`grid-item ${item.class}`"
>
<div class="tool"> <div class="tool">
<div class="title"> <div class="title">
<i class="iconfont icon-hebing linear-text"></i> <i class="iconfont icon-hebing linear-text"></i>
<span class="linear-text">{{ item.title }}</span> <span class="linear-text">{{ item.title }}</span>
</div> </div>
</div> </div>
<component :is="item.componentId" :device-info="deviceInfo[item.infoKey]"></component>
<component
:is="item.componentId"
:info-key="item.infoKey"
:device-info="deviceInfo[item.infoKey]"
:total="item.infoKey === 'onLineTotal' ? deviceInfo.onLine : deviceInfo.allTotal"
></component>
</div> </div>
</div> </div>
<div class="tianditu"> <div class="tianditu">
<Map></Map> <Map @changeStation="getCurrentStation"></Map>
</div> </div>
<div class="content-right"> <div class="content-right">
<div v-for="(item, i) in rightList" :key="i" :class="`grid-item ${item.class}`"> <div
v-for="item in rightList"
:key="item.componentId"
:class="`grid-item ${item.class}`"
>
<div class="tool"> <div class="tool">
<div class="title"> <div class="title">
<i class="iconfont icon-hebing linear-text"></i> <i class="iconfont icon-hebing linear-text"></i>
<span class="linear-text">{{ item.title }}</span> <span class="linear-text">{{ item.title }}</span>
</div> </div>
</div> </div>
<component :is="item.componentId" :device-info="deviceInfo[item.infoKey]"></component> <component
:is="item.componentId"
:device-info="deviceInfo[item.infoKey]"
:total="item.infoKey === 'onLineTotal' ? deviceInfo.onLine : deviceInfo.allTotal"
></component>
</div> </div>
</div> </div>
</div> </div>
@@ -36,25 +56,28 @@ import Charge from '@/components/Home/Charge.vue'
import Pv from '@/components/Home/Pv.vue' import Pv from '@/components/Home/Pv.vue'
import Alarm from '@/components/Home/Alarm.vue' import Alarm from '@/components/Home/Alarm.vue'
import Map from '@/components/Home/Map.vue' import Map from '@/components/Home/Map.vue'
import { getReq, postReq } from '@/request/api'
export default { export default {
name: 'Home', name: 'Home',
components: {Map}, components: { Map },
data() { data() {
return { return {
showFlag: false,
stationId: null,
deviceInfo: {}, deviceInfo: {},
list: [ list: [
{ {
title: '运行状况', title: '运行状况',
class: 'online-status', class: 'online-status',
componentId: onLine, componentId: onLine,
infoKey: 'onLine' infoKey: 'onLineTotal'
}, },
{ {
title: '运行分析', title: '运行分析',
class: 'stats-cards', class: 'stats-cards',
componentId: Operational, componentId: Operational,
infoKey: 'stats' infoKey: ''
}, },
{ {
title: '储能设备', title: '储能设备',
@@ -96,222 +119,343 @@ export default {
} }
}, },
async mounted() { async mounted() {
this.deviceInfo = { await Promise.all([
alarm: [ // (this.deviceInfo = {
{ // alarm: [
date: '2025-08-30', // {
key1: 10, // date: '2025-08-30',
key2: 0, // key1: 10,
key3: 15, // key2: 0,
key4: 5 // key3: 15,
}, // key4: 5
{ // },
date: '2025-08-29', // {
key1: 8, // date: '2025-08-29',
key2: 5, // key1: 8,
key3: 5, // key2: 5,
key4: 7 // key3: 5,
}, // key4: 7
{ // },
date: '2025-08-28', // {
key1: 0, // date: '2025-08-28',
key2: 10, // key1: 0,
key3: 20, // key2: 10,
key4: 4 // key3: 20,
}, // key4: 4
{ // },
date: '2025-08-27', // {
key1: 10, // date: '2025-08-27',
key2: 0, // key1: 10,
key3: 15, // key2: 0,
key4: 5 // key3: 15,
}, // key4: 5
{ // },
date: '2025-08-26', // {
key1: 10, // date: '2025-08-26',
key2: 0, // key1: 10,
key3: 15, // key2: 0,
key4: 5 // key3: 15,
}, // key4: 5
{ // },
date: '2025-08-25', // {
key1: 10, // date: '2025-08-25',
key2: 0, // key1: 10,
key3: 15, // key2: 0,
key4: 5 // key3: 15,
}, // key4: 5
{ // },
date: '2025-08-24', // {
key1: 10, // date: '2025-08-24',
key2: 0, // key1: 10,
key3: 15, // key2: 0,
key4: 5 // key3: 15,
}, // key4: 5
{ // },
date: '2025-08-23', // {
key1: 10, // date: '2025-08-23',
key2: 0, // key1: 10,
key3: 15, // key2: 0,
key4: 5 // key3: 15,
}, // key4: 5
{ // },
date: '2025-08-22', // {
key1: 10, // date: '2025-08-22',
key2: 0, // key1: 10,
key3: 15, // key2: 0,
key4: 5 // key3: 15,
}, // key4: 5
{ // },
date: '2025-08-21', // {
key1: 10, // date: '2025-08-21',
key2: 0, // key1: 10,
key3: 15, // key2: 0,
key4: 5 // key3: 15,
}, // key4: 5
{ // },
date: '2025-08-20', // {
key1: 10, // date: '2025-08-20',
key2: 0, // key1: 10,
key3: 15, // key2: 0,
key4: 5 // key3: 15,
}, // key4: 5
{ // },
date: '2025-08-19', // {
key1: 10, // date: '2025-08-19',
key2: 0, // key1: 10,
key3: 15, // key2: 0,
key4: 5 // key3: 15,
}, // key4: 5
{ // },
date: '2025-08-18', // {
key1: 10, // date: '2025-08-18',
key2: 0, // key1: 10,
key3: 15, // key2: 0,
key4: 5 // key3: 15,
}, // key4: 5
{ // },
date: '2025-08-17', // {
key1: 10, // date: '2025-08-17',
key2: 0, // key1: 10,
key3: 15, // key2: 0,
key4: 5 // key3: 15,
} // key4: 5
], // }
energy: [ // ],
{ // energy: [
date: '2025-08-30', // {
key1: '2', // date: '2025-08-30',
key2: '2' // key1: '2',
}, // key2: '2'
{ // },
date: '2025-08-29', // {
key1: '2', // date: '2025-08-29',
key2: '2' // key1: '2',
}, // key2: '2'
{ // },
date: '2025-08-28', // {
key1: '2', // date: '2025-08-28',
key2: '2' // key1: '2',
}, // key2: '2'
{ // },
date: '2025-08-27', // {
key1: '2', // date: '2025-08-27',
key2: '2' // key1: '2',
}, // key2: '2'
{ // },
date: '2025-08-26', // {
key1: '2', // date: '2025-08-26',
key2: '2' // key1: '2',
}, // key2: '2'
{ // },
date: '2025-08-25', // {
key1: '2', // date: '2025-08-25',
key2: '2' // key1: '2',
}, // key2: '2'
{ // },
date: '2025-08-24', // {
key1: '2', // date: '2025-08-24',
key2: '2' // key1: '2',
} // key2: '2'
], // }
charge: [ // ],
{ // charge: [
date: '2025-08-30', // {
key1: '2', // date: '2025-08-30',
key2: '2' // key1: '2',
}, // key2: '2'
{ // },
date: '2025-08-29', // {
key1: '2', // date: '2025-08-29',
key2: '2' // key1: '2',
}, // key2: '2'
{ // },
date: '2025-08-28', // {
key1: '2', // date: '2025-08-28',
key2: '2' // key1: '2',
}, // key2: '2'
{ // },
date: '2025-08-27', // {
key1: '2', // date: '2025-08-27',
key2: '2' // key1: '2',
}, // key2: '2'
{ // },
date: '2025-08-26', // {
key1: '2', // date: '2025-08-26',
key2: '2' // key1: '2',
}, // key2: '2'
{ // },
date: '2025-08-25', // {
key1: '2', // date: '2025-08-25',
key2: '2' // key1: '2',
}, // key2: '2'
{ // },
date: '2025-08-24', // {
key1: '2', // date: '2025-08-24',
key2: '2' // key1: '2',
} // key2: '2'
], // }
pv: [ // ],
{ // pv: [
date: '2025-08-30', // {
key1: '2', // date: '2025-08-30',
key2: '2' // key1: '2',
}, // key2: '2'
{ // },
date: '2025-08-29', // {
key1: '2', // date: '2025-08-29',
key2: '2' // key1: '2',
}, // key2: '2'
{ // },
date: '2025-08-28', // {
key1: '2', // date: '2025-08-28',
key2: '2' // key1: '2',
}, // key2: '2'
{ // },
date: '2025-08-27', // {
key1: '2', // date: '2025-08-27',
key2: '2' // key1: '2',
}, // key2: '2'
{ // },
date: '2025-08-26', // {
key1: '2', // date: '2025-08-26',
key2: '2' // key1: '2',
}, // key2: '2'
{ // },
date: '2025-08-25', // {
key1: '2', // date: '2025-08-25',
key2: '2' // key1: '2',
}, // key2: '2'
{ // },
date: '2025-08-24', // {
key1: '2', // date: '2025-08-24',
key2: '2' // key1: '2',
} // key2: '2'
] // }
} // ],
// allTotal: {}
// }),
this.getOnLineList(),
this.getStatTotalList(),
this.getStatDayList(1),
this.getStatDayList(2),
this.getStatDayList(3)
])
// this.showFlag=true
}, },
methods: {} methods: {
getCurrentStation(e) {
console.log(e, 'getCurrentStation')
this.stationId = e
},
// 查询系统统计信息
async getOnLineList() {
try {
// token: 用户TOKEN
const res = await getReq('/api/queryStatSystem')
if (res.errcode === 0) {
this.deviceInfo.onLine = JSON.parse(JSON.stringify(res.data))
this.deviceInfo.onLine.runDays = this.getRunDays(res.data.launch_date)
console.log(JSON.parse(JSON.stringify(res.data)), this.deviceInfo.onLine, '111111111111')
} else {
throw res
}
} catch (error) {
this.deviceInfo.onLine = {}
}
},
getRunDays(date) {
const launchDate = new Date(date)
const today = new Date() // 替换为当前日期
const timeDiff = today - launchDate // 毫秒差
const daysRun = Math.ceil(timeDiff / (1000 * 60 * 60 * 24)) // 转换为天数
console.log(`从 2023-01-01 到今天已经运行了 ${daysRun}`)
return daysRun
},
// 查询系统累计统计信息
async getStatTotalList() {
try {
// token: 用户TOKEN
// date:日期
// station_id:场站ID为0或不传查询所有场站总计
// category:类别1:储能设备,2:充电设备,3:光伏设备,为0或不传查询所有类别总计
const query = {
date: new Date(),
stationId: this.stationId,
category: 0
}
const res = await getReq('/api/queryStatTotal', query)
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
console.log(
this.deviceInfo.allTotal.incomeTotal,
incomeCharge,
incomeElect,
' this.deviceInfo.allTotal.incomeTotal'
)
} else {
throw res
}
} catch (error) {
this.deviceInfo.allTotal = {
storageElectIn: 2,
storageElectOut: 5,
chargeElect: 4,
chargeNum: 5,
incomeCharge: 7,
incomeElect: 7,
solarElectGen: 7,
solarElectGrid: 7
}
this.deviceInfo.allTotal.incomeTotal =
this.deviceInfo.allTotal.incomeCharge + this.deviceInfo.allTotal.incomeElect
}
},
getDateDaysAgo(daysAgo) {
const date = new Date()
date.setDate(date.getDate() - daysAgo)
const year = date.getFullYear()
const month = String(date.getMonth() + 1).padStart(2, '0')
const day = String(date.getDate()).padStart(2, '0')
return `${year}-${month}-${day}`
},
// 示例获取7天前的日期
// 查询场站日统计信息
async getStatDayList(category) {
try {
// station_id: 场站ID
// category: 类别: 1储能设备,2:充电设备,3:光伏设备
// start_date开始日期格式yyyy-mm-dd
// end_date结束日期格式yyyy-mm-dd
const query = {
stationId: this.stationId,
category,
start_date: this.getDateDaysAgo(7 - 1),
end_date: this.getDateDaysAgo(0)
}
const arr = { 1: 'energy', 2: 'charge', 3: 'pv' }
const res = await getReq('/api/queryStatDayList', query)
if (res.errcode === 0) {
this.list.forEach((item) => {
this.deviceInfo[arr[category]] = res.data
})
} else {
throw res
}
} catch (error) {
console.log(error)
}
}
}
} }
</script> </script>
@@ -325,10 +469,9 @@ export default {
} }
.tianditu { .tianditu {
width: calc(100% - 520px * 2) ; width: calc(100% - 520px * 2);
height: 100%; height: 100%;
margin: 0px 15px; margin: 0px 15px;
} }
.content-left, .content-left,

View File

@@ -9,27 +9,13 @@ module.exports = defineConfig({
// 静态资源目录 // 静态资源目录
assetsDir: 'static', assetsDir: 'static',
devServer: { devServer: {
hot: true, proxy: {
compress: true, '/api': {
allowedHosts: 'all', // 代理前缀,可以自定义(如 '/api'
headers: { target: 'http://192.168.0.187:19801', // 目标服务器地址
// 1. 允许开发环境跨域 changeOrigin: true, // 是否改变请求源(跨域必备)
'Access-Control-Allow-Origin': '*' pathRewrite: {
}, '^/api': '' // 重写路径,去掉 '/api' 前缀
historyApiFallback: true,
open: false,
port: 8080,
client: {
overlay: {
runtimeErrors: (error) => {
const ignoreErrors = [
'ResizeObserver loop limit exceeded',
'ResizeObserver loop completed with undelivered notifications.'
]
if (ignoreErrors.includes(error.message)) {
return false
}
return true
} }
} }
}, },