解决冲突

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

View File

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

View File

@@ -6,7 +6,7 @@
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<link rel="icon" href="<%= BASE_URL %>favicon.ico" />
<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>
<body>
<noscript>

View File

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

View File

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

View File

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

View File

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

View File

@@ -8,7 +8,8 @@
<span class="linear-text">{{ item.title }}</span>
</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>
@@ -20,7 +21,7 @@
<span class="linear-text">{{ item.title }}</span>
</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>
@@ -33,16 +34,13 @@ import StatisticalInfo from '@/components/Home/Modal/StatisticalInfo.vue'
import Revenue from '@/components/Home/Modal/Revenue.vue'
import Utilization from '@/components/Home/Modal/Utilization.vue'
import DisCharge from '@/components/Home/Modal/DisCharge.vue'
import 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'
export default {
name: 'Home',
components: {Map},
components: {},
data() {
return {
deviceInfo: {},
@@ -105,222 +103,144 @@ export default {
}
},
async mounted() {
this.deviceInfo = {
await Promise.all([
this.getTotalList(),
( this.deviceInfo = {
alarm: [
{
date: '2025-08-30',
dt: '2025-08-30',
key1: 10,
key2: 0,
key3: 15,
key4: 5
},
{
date: '2025-08-29',
dt: '2025-08-29',
key1: 8,
key2: 5,
key3: 5,
key4: 7
},
{
date: '2025-08-28',
dt: '2025-08-28',
key1: 0,
key2: 10,
key3: 20,
key4: 4
},
{
date: '2025-08-27',
dt: '2025-08-27',
key1: 10,
key2: 0,
key3: 15,
key4: 5
},
{
date: '2025-08-26',
dt: '2025-08-26',
key1: 10,
key2: 0,
key3: 15,
key4: 5
},
{
date: '2025-08-25',
dt: '2025-08-25',
key1: 10,
key2: 0,
key3: 15,
key4: 5
},
{
date: '2025-08-24',
dt: '2025-08-24',
key1: 10,
key2: 0,
key3: 15,
key4: 5
},
{
date: '2025-08-23',
dt: '2025-08-23',
key1: 10,
key2: 0,
key3: 15,
key4: 5
},
{
date: '2025-08-22',
dt: '2025-08-22',
key1: 10,
key2: 0,
key3: 15,
key4: 5
},
{
date: '2025-08-21',
dt: '2025-08-21',
key1: 10,
key2: 0,
key3: 15,
key4: 5
},
{
date: '2025-08-20',
dt: '2025-08-20',
key1: 10,
key2: 0,
key3: 15,
key4: 5
},
{
date: '2025-08-19',
dt: '2025-08-19',
key1: 10,
key2: 0,
key3: 15,
key4: 5
},
{
date: '2025-08-18',
dt: '2025-08-18',
key1: 10,
key2: 0,
key3: 15,
key4: 5
},
{
date: '2025-08-17',
dt: '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: {}
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>

View File

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

View File

@@ -2,72 +2,71 @@
<div class="onLine">
<div class="content">
<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">
<span>{{ item.label }}</span>
<span>{{ item.value }} {{ item.d }}</span
>
</div>
<span>{{ item.value }} {{ item.d }}</span>
</div>
</div>
</div>
</div>
</template>
<script>
import { legacyLogicalPropertiesTransformer } from 'ant-design-vue'
export default {
name: '',
props: {
propsInfo: {
propsTotal: {
type: Object,
default: ()=>({
name: '场站111',
statusName:'充电'
})
default: () => {}
},
propsInfo: {
type: Array,
default: () => []
}
},
data() {
return {
list: [
{
key: 'tianshu',
value: 26,
d: 'Lux',
label: '光照',
key: 'key1',
value: '制冷',
d: '',
label: '冷机',
class: 'item-1',
iconPath: require('@/assets/home/guangzhao.png')
icon: 'lengji',
color: '#F69B52'
},
{
key: 'shouyi',
value: 25,
d: 'm/s',
label: '风速',
key: 'key2',
value: '开机',
d: '',
label: '空调',
class: 'item-2',
iconPath: require('@/assets/home/fengsu.png')
icon: 'kongdiaogongcheng',
color: '#9BD801'
},
{
key: 'shuliang',
key: 'key3',
value: 24,
d: '℃',
label: '环境温度',
class: 'item-3',
iconPath: require('@/assets/home/hj-wendu.png')
icon: 'wenduji',
color: '#3DFEFA'
},
{
key: 'shuliang',
key: 'key4',
value: 26,
d: '%',
label: '环境湿度',
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个奇数索引
}
},
watch: {},
watch: {
propsTotal: {
handler(newVal, oldVal) {
if (newVal !== oldVal) {
this.list.forEach((item) => {
item.value = this.propsTotal[item.key]
})
}
}
}
},
mounted() {},
methods: {}
}
@@ -91,13 +100,11 @@ export default {
display: flex;
justify-content: center;
align-items: center;
width:95%;
width: 95%;
margin: auto;
}
.content{
.content {
flex-wrap: wrap;
width: 100%;
display: flex;
@@ -105,8 +112,8 @@ export default {
justify-content: space-around;
height: 100%;
.item{
height:50%;
.item {
height: 50%;
width: 25%;
// height: 47px;
box-sizing: border-box;
@@ -125,15 +132,10 @@ export default {
}
}
.right {
display: flex;
flex-direction: column;
margin-left: 20px;
}
}
}
</style>

View File

@@ -5,32 +5,26 @@
<a-image :preview="false" :src="item.iconPath" :width="50" class="left"> </a-image>
<div class="right">
<span>{{ item.label }}</span>
<span>{{ item.value }} {{ item.d }}</span
>
</div>
<span>{{ item.value }} {{ item.d }}</span>
</div>
</div>
</div>
</div>
</template>
<script>
import { legacyLogicalPropertiesTransformer } from 'ant-design-vue'
export default {
name: '',
props: {
propsInfo: {
propsTotal: {
type: Object,
default: ()=>({
name: '场站111',
statusName:'充电'
})
}
default: () => {}
},
propsInfo: {
type: Array,
default: () => []
},
},
data() {
return {
@@ -94,7 +88,18 @@ export default {
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() {},
methods: {}
}
@@ -106,14 +111,11 @@ export default {
display: flex;
justify-content: center;
align-items: center;
width:95%;
width: 95%;
margin: auto;
}
.content{
.content {
flex-wrap: wrap;
width: 100%;
display: flex;
@@ -121,8 +123,8 @@ export default {
justify-content: space-around;
height: 100%;
.item{
height:50%;
.item {
height: 50%;
width: 30%;
// height: 47px;
box-sizing: border-box;
@@ -141,15 +143,10 @@ export default {
}
}
.right {
display: flex;
flex-direction: column;
margin-left: 20px;
}
}
}
</style>

View File

@@ -3,21 +3,21 @@
<div class="content-left">
<div v-for="item in leftList" :key="item.key" :class="`item ${item.class}`">
<div>
<span>{{ item.value }}</span
<span>{{ item.value ? item.value : 0 }}</span
><span class="d">{{ item.d }}</span>
</div>
<span>{{ item.label }}</span>
</div>
</div>
<div style="text-align: center;font-weight: 500;">
<div style="text-align: center; font-weight: 500">
<div class="online-icon"></div>
<span>{{ propsInfo.statusName }}</span>
<span>{{ curStatus }}</span>
</div>
<div class="content-right">
<div v-for="item in rightList" :key="item.key" :class="`item ${item.class}`">
<div>
<span>{{ item.value }}</span
<span>{{ item.value ? item.value : 0 }}</span
><span class="d">{{ item.d }}</span>
</div>
<span>{{ item.label }}</span>
@@ -27,21 +27,21 @@
</template>
<script>
import { legacyLogicalPropertiesTransformer } from 'ant-design-vue'
export default {
name: '',
props: {
propsInfo: {
propsTotal: {
type: Object,
default: () => ({
name: '场站111',
statusName: '充电'
})
default: () => {}
},
propsInfo: {
type: Array,
default: () => []
}
},
data() {
return {
curStatus: '充电',
list: [
{
key: 'tianshu',
@@ -96,7 +96,17 @@ export default {
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() {},
methods: {}
}

View File

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

View File

@@ -2,7 +2,7 @@
<div class="onLine">
<div class="content">
<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>
</div>
</div>
@@ -10,11 +10,13 @@
</template>
<script>
import { legacyLogicalPropertiesTransformer } from 'ant-design-vue'
export default {
name: '',
props: {
propsTotal: {
type: Object,
default: () => {}
},
propsInfo: {
type: Object,
default: () => ({
@@ -77,7 +79,17 @@ export default {
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() {},
methods: {}
}
@@ -89,7 +101,7 @@ export default {
display: flex;
justify-content: center;
align-items: center;
width:95%;
width: 95%;
margin: auto;
}

View File

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

View File

@@ -2,12 +2,12 @@
<div class="Operational">
<div class="oper-bg">{{ currentHoverNumber }}%</div>
<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="`background:${item.lineColor}`" class="item-icon"></div>
<span class="item-name">{{ item.name }}</span>
</div>
<span class="item-value">{{ item.value }}</span>
<span class="item-value">{{ item.value?item.value:0 }}</span>
</div>
</div>
</div>
@@ -17,6 +17,10 @@
export default {
name: '',
props: {
total:{
type:Object,
default:()=>{}
},
deviceInfo: {
type: Array,
default: () => []
@@ -25,17 +29,17 @@ export default {
data() {
return {
currentHoverNumber: 58,
list: [
curList: [
{
name: '收益',
key: 'connector_online',
key: 'incomeTotal',
percentKey: 'connector_online_percent',
lineColor: 'linear-gradient(90deg, rgba(13, 87, 144, 1) 0%, rgba(21, 153, 253, 1) 100%);',
value: 0
},
{
name: '利用率',
key: 'connector_off',
key: 'usage_rate',
percentKey: 'connector_off_percent',
lineColor:
'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() {},
methods: {

View File

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

View File

@@ -3,14 +3,20 @@
<div class="content-left">
<div v-for="item in leftList" :key="item.key" :class="`item ${item.class}`">
<span>{{ item.label }}</span>
<div> <span>{{ item.value }}</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 class="online-icon"></div>
<div class="content-right">
<div v-for="item in rightList" :key="item.key" :class="`item ${item.class}`">
<span>{{ item.label }}</span>
<div> <span>{{ item.value }}</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>
@@ -20,6 +26,14 @@
export default {
name: '',
props: {
infoKey: {
type: String,
default:''
},
total: {
type: Object,
default: () => {}
},
deviceInfo: {
type: Array,
default: () => []
@@ -27,44 +41,44 @@ export default {
},
data() {
return {
list: [
curList: [
{
key: 'tianshu',
key: 'runDays', //根据launch_date字段计算得出
value: 20,
d: '天',
label: '系统运行天数',
class: 'item-1'
},
{
key: 'shouyi',
key: 'income_total',
value: 10,
d: '元',
d: '元',
label: '累计收益',
class: 'item-2'
},
{
key: 'shuliang',
key: 'solar_device_num',
value: 20,
d: '',
label: '光伏设备数量',
class: 'item-3'
},
{
key: 'shuliang',
key: 'storage_device_num',
value: 20,
d: '',
label: '储能预制舱数量',
class: 'item-4'
},
{
key: 'fadianliang',
key: 'solar_elect_gen',
value: 20,
d: '',
label: '光伏设备累计发电量',
class: 'item-5'
},
{
key: 'rongliang',
key: 'capacity_total',
value: 20,
d: '',
label: '储能总容量',
@@ -75,14 +89,29 @@ export default {
},
computed: {
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() {
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: {}
}
</script>
@@ -111,12 +140,10 @@ export default {
font-size: 12px;
margin-bottom: 10px;
}
.d{
.d {
margin-left: 1px;
font-size: 12px;
}
}
.content-left,

View File

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

View File

@@ -1,6 +1,6 @@
<template>
<div class="statisicalAn">
<div style="display: flex; justify-content: space-between">
<div style="display: flex; justify-content: space-between; height: 50px">
<div class="tab-header">
<div v-for="item in tabList" :key="item.key" class="tab">
<span
@@ -20,12 +20,14 @@
>
</searchBox>
</div>
<div class="content">
<div class="main_content">
<energyEchart
:chart-options="echartsInfo[activeKey].chartOptions"
:chart-data="echartsInfo[activeKey].chartData"
:columns="tableList[activeKey].columns"
:table-info="tableList[activeKey].tableInfo"
:table-data="tableList[activeKey].tableData"
@pagesizeChange="pagesizeChange()"
></energyEchart>
</div>
</div>
@@ -34,14 +36,31 @@
<script>
import energyEchart from '@/components/statisticalAnalysis/energyEchart.vue'
import searchBox from '@/components/SearchBox.vue'
import { postReq } from '@/request/api'
export default {
name: 'StatisicalAnView',
components: { energyEchart, searchBox },
data() {
return {
categoryArr: [
{
type: 1,
label: '储能设备',
infoKey: 'energy'
},
{
type: 2,
label: '充电设备',
infoKey: 'charge'
},
{
type: 3,
label: '光伏设备',
infoKey: 'pv'
}
],
paramsDate: {},
searchOptions: [
{
label: '日期',
@@ -108,7 +127,142 @@ export default {
]
}
],
chartData: {
chartData: {}
}
},
activeKey: 0,
tabList: [
{
key: '0',
name: '储能设备'
},
{
key: '1',
name: '光伏设备'
},
{
key: '2',
name: '充电设备'
}
],
tableList: {
0: {
columns: [
{
title: '设备ID',
dataIndex: 'key1',
key: 'key1',
width: 120,
ellipsis: true
},
{
title: '设备名称',
dataIndex: 'key2',
key: 'key2',
width: 120,
ellipsis: true
},
{
title: '设备类型',
dataIndex: 'key3',
key: 'key3',
width: 120,
ellipsis: true
},
{
title: '充电电量',
dataIndex: 'key4',
key: 'key4',
width: 120,
ellipsis: true
},
{
title: '充电时长',
dataIndex: 'key5',
key: 'key5',
width: 120,
ellipsis: true
},
{
title: '放电时长',
dataIndex: 'key6',
key: 'key6',
width: 120,
ellipsis: true
},
{
title: '放电电量',
dataIndex: 'key7',
key: 'key7',
width: 120,
ellipsis: true
},
{
title: '故障次数',
dataIndex: 'key8',
key: 'key8',
width: 120,
ellipsis: true
},
{
title: '日期',
dataIndex: 'key9',
key: 'key9',
width: 120,
ellipsis: true
}
],
geturl: '',
tableData: [],
pageOption: {
current: 1,
pageSize: 10,
total: 1
}
}
}
}
},
async mounted() {
await Promise.all([
this.getTableList(),
this.getEchartsList()
])
},
beforeUnmount() {},
methods: {
pagesizeChange(e) {
console.log(e, 'eeeeeeeeeeeeeee')
this.tableList[this.activeKey].pageOption.pageSize = e.pageSize
this.tableList[this.activeKey].pageOption.current = e.current
this.getTableList()
},
onSearch(data) {
this.paramsDate.startTime = data.time ? data.time[0] : ''
this.paramsDate.endTime = data.time ? data.time[1] : ''
this.pageOption.current = 1
this.getTableList()
this.getEchartsList()
},
async getEchartsList() {
const currentInfo = this.echartsInfo[this.activeKey]
const query = {
...this.paramsDate,
category: this.categoryArr.map((item) => item.label == this.activeKey)[0].type
}
try {
const res = await postReq(query, '')
if (res.code === 200) {
this.echartsInfo[this.activeKey].chartData= res.data
} else {
throw res
}
} catch (error) {
this.echartsInfo[this.activeKey].chartData = {
sales: [
{
date: '2025-08-30',
@@ -512,151 +666,75 @@ export default {
}
}
},
activeKey: '0',
tabList: [
{
key: '0',
name: '储能设备'
},
{
key: '1',
name: '光伏设备'
},
{
key: '2',
name: '充电设备'
}
],
tableList: {
0: {
columns: [
{
title: '设备ID',
dataIndex: 'key1',
key: 'key1',
width: 120,
ellipsis: true
},
{
title: '设备名称',
dataIndex: 'key2',
key: 'key2',
width: 120,
ellipsis: true
},
{
title: '设备类型',
dataIndex: 'key3',
key: 'key3',
width: 120,
ellipsis: true
},
{
title: '充电电量',
dataIndex: 'key4',
key: 'key4',
width: 120,
ellipsis: true
},
{
title: '充电时长',
dataIndex: 'key5',
key: 'key5',
width: 120,
ellipsis: true
},
{
title: '放电时长',
dataIndex: 'key6',
key: 'key6',
width: 120,
ellipsis: true
},
{
title: '放电电量',
dataIndex: 'key7',
key: 'key7',
width: 120,
ellipsis: true
},
{
title: '故障次数',
dataIndex: 'key8',
key: 'key8',
width: 120,
ellipsis: true
},
{
title: '日期',
dataIndex: 'key9',
key: 'key9',
width: 120,
ellipsis: true
}
],
tableInfo: {
tableId: '',
geturl: ''
}
// tableData:[
// {
// key1:'1515151515',
// key2:'设备1111',
// key3:'类型',
// key4:'电量',
// key5:'时长',
// key6:'时长',
// key7:'dianl',
// key8:'时长',
// key9:'时长11',
// },
// {
// key1:'1515151515',
// key2:'设备1111',
// key3:'类型',
// key4:'电量',
// key5:'时长',
// key6:'时长',
// key7:'dianl',
// key8:'时长',
// key9:'时长11',
// },
// {
// key1:'1515151515',
// key2:'设备1111',
// key3:'类型',
// key4:'电量',
// key5:'时长',
// key6:'时长',
// key7:'dianl',
// key8:'时长',
// key9:'时长11',
// },
// {
// key1:'1515151515',
// key2:'设备1111',
// key3:'类型',
// key4:'电量',
// key5:'时长',
// key6:'时长',
// key7:'dianl',
// key8:'时长',
// key9:'时长11',
// },
// ]
async getTableList() {
const currentInfo = this.tableList[this.activeKey]
const query = {
...this.paramsDate,
category: this.categoryArr.map((item) => item.label == this.activeKey)[0].type,
pageSize: currentInfo.pageOption.pageSize,
pageNumber: currentInfo.pageOption.current
}
try {
const res = await postReq(query, currentInfo.getUrl)
if (res.code === 200) {
currentInfo.tableData = res.data.records
currentInfo.pageOption = {
current: res.data.pageNumber,
pageSize: res.data.pageSize,
total: res.data.totalRow
}
} else {
throw res
}
} catch (error) {
this.tableList[this.activeKey].tableData = [
{
key1: '1515151515',
key2: '设备1111',
key3: '类型',
key4: '电量',
key5: '时长',
key6: '时长',
key7: 'dianl',
key8: '时长',
key9: '时长11'
},
mounted() {},
beforeUnmount() {},
methods: {
onSearch(data) {
this.paramsDate.startTime = data.time ? data.time[0] : ''
this.paramsDate.endTime = data.time ? data.time[1] : ''
this.pageOption.current = 1
this.getList()
{
key1: '1515151515',
key2: '设备1111',
key3: '类型',
key4: '电量',
key5: '时长',
key6: '时长',
key7: 'dianl',
key8: '时长',
key9: '时长11'
},
{
key1: '1515151515',
key2: '设备1111',
key3: '类型',
key4: '电量',
key5: '时长',
key6: '时长',
key7: 'dianl',
key8: '时长',
key9: '时长11'
},
{
key1: '1515151515',
key2: '设备1111',
key3: '类型',
key4: '电量',
key5: '时长',
key6: '时长',
key7: 'dianl',
key8: '时长',
key9: '时长11'
}
]
}
}
}
}
@@ -696,9 +774,9 @@ export default {
background-color: $bg2-color;
}
}
.content {
.main_content {
overflow: scroll;
height: calc(100% - 15px);
margin-top: 10px;
// margin-top: 10px;
}
</style>

View File

@@ -1,28 +1,48 @@
<template>
<div class="Home">
<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="title">
<i class="iconfont icon-hebing linear-text"></i>
<span class="linear-text">{{ item.title }}</span>
</div>
</div>
<component :is="item.componentId" :device-info="deviceInfo[item.infoKey]"></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 class="tianditu">
<Map></Map>
<Map @changeStation="getCurrentStation"></Map>
</div>
<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="title">
<i class="iconfont icon-hebing linear-text"></i>
<span class="linear-text">{{ item.title }}</span>
</div>
</div>
<component :is="item.componentId" :device-info="deviceInfo[item.infoKey]"></component>
<component
:is="item.componentId"
:device-info="deviceInfo[item.infoKey]"
:total="item.infoKey === 'onLineTotal' ? deviceInfo.onLine : deviceInfo.allTotal"
></component>
</div>
</div>
</div>
@@ -36,25 +56,28 @@ import Charge from '@/components/Home/Charge.vue'
import Pv from '@/components/Home/Pv.vue'
import Alarm from '@/components/Home/Alarm.vue'
import Map from '@/components/Home/Map.vue'
import { getReq, postReq } from '@/request/api'
export default {
name: 'Home',
components: {Map},
components: { Map },
data() {
return {
showFlag: false,
stationId: null,
deviceInfo: {},
list: [
{
title: '运行状况',
class: 'online-status',
componentId: onLine,
infoKey: 'onLine'
infoKey: 'onLineTotal'
},
{
title: '运行分析',
class: 'stats-cards',
componentId: Operational,
infoKey: 'stats'
infoKey: ''
},
{
title: '储能设备',
@@ -96,222 +119,343 @@ export default {
}
},
async mounted() {
this.deviceInfo = {
alarm: [
{
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'
}
]
}
await Promise.all([
// (this.deviceInfo = {
// alarm: [
// {
// 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'
// }
// ],
// 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>
@@ -325,10 +469,9 @@ export default {
}
.tianditu {
width: calc(100% - 520px * 2) ;
width: calc(100% - 520px * 2);
height: 100%;
margin: 0px 15px;
}
.content-left,

View File

@@ -9,27 +9,13 @@ module.exports = defineConfig({
// 静态资源目录
assetsDir: 'static',
devServer: {
hot: true,
compress: true,
allowedHosts: 'all',
headers: {
// 1. 允许开发环境跨域
'Access-Control-Allow-Origin': '*'
},
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
proxy: {
'/api': {
// 代理前缀,可以自定义(如 '/api'
target: 'http://192.168.0.187:19801', // 目标服务器地址
changeOrigin: true, // 是否改变请求源(跨域必备)
pathRewrite: {
'^/api': '' // 重写路径,去掉 '/api' 前缀
}
}
},