600 lines
17 KiB
Vue
600 lines
17 KiB
Vue
<template>
|
||
<ItemBox :title="$t('dashboard.stationTopo')" style="min-height: 560px;">
|
||
<div ref="svgLine" class="center-box">
|
||
<div v-loading="loading">
|
||
<svg
|
||
version="1.1"
|
||
xmlns="http://www.w3.org/2000/svg"
|
||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||
xml:space="preserve"
|
||
class="circle-load-rect-svg"
|
||
viewBox="0 0 800 500"
|
||
>
|
||
<defs>
|
||
<defs>
|
||
<radialGradient id="RadialGradient1">
|
||
<stop offset="0%" stop-color="#fff" />
|
||
<stop offset="30%" stop-color="#0171c1" />
|
||
<stop offset="50%" stop-color="#035088" />
|
||
<stop offset="100%" stop-color="#02395a" />
|
||
</radialGradient>
|
||
</defs>
|
||
<marker
|
||
id="markerCircle"
|
||
markerWidth="15"
|
||
markerHeight="15"
|
||
refX="5"
|
||
refY="5"
|
||
>
|
||
<circle
|
||
cx="5"
|
||
cy="5"
|
||
r="5"
|
||
style="stroke: none; fill: url(#RadialGradient1)"
|
||
/>
|
||
</marker>
|
||
|
||
<marker
|
||
id="markerArrow"
|
||
markerWidth="13"
|
||
markerHeight="13"
|
||
refX="2"
|
||
refY="6"
|
||
orient="auto"
|
||
>
|
||
<path d="M2,2 L2,11 L10,6 L2,2" style="fill: black" />
|
||
</marker>
|
||
</defs>
|
||
<!-- //线条 -->
|
||
<!-- top -->
|
||
<polyline
|
||
points="154,80 385,80"
|
||
fill="none"
|
||
class="g-rect-path"
|
||
stroke="#0094FF"
|
||
stroke-dasharray="3 3"
|
||
/>
|
||
<rect
|
||
x="152"
|
||
y="78"
|
||
width="233"
|
||
height="4"
|
||
:style="{ fill: 'rgba(100,100,100,0)', stroke: 'transparent',cursor: 'pointer' }"
|
||
@click="lookDeviceDetail('line-top-left')"
|
||
/>
|
||
|
||
<polyline
|
||
points="385,80 600,80"
|
||
fill="none"
|
||
class="g-rect-path"
|
||
stroke="#0094FF"
|
||
stroke-dasharray="3 3"
|
||
/>
|
||
<rect
|
||
x="383"
|
||
y="78"
|
||
width="217"
|
||
height="4"
|
||
:style="{ fill: 'rgba(100,100,100,0)', stroke: 'transparent',cursor: 'pointer' }"
|
||
@click="lookDeviceDetail('line-top-right')"
|
||
/>
|
||
<!-- center -->
|
||
<polyline
|
||
points="385,80 385,363"
|
||
fill="none"
|
||
class="g-rect-path"
|
||
stroke="#0094FF"
|
||
stroke-dasharray="3 3"
|
||
/>
|
||
<rect
|
||
x="385"
|
||
y="80"
|
||
width="4"
|
||
height="285"
|
||
:style="{ fill: 'rgba(100,100,100,0)', stroke: 'transparent',cursor: 'pointer' }"
|
||
@click="lookDeviceDetail('line-center')"
|
||
/>
|
||
|
||
<polyline
|
||
points="385,160 460,160"
|
||
fill="none"
|
||
class="g-rect-path"
|
||
stroke="#0094FF"
|
||
stroke-dasharray="3 3"
|
||
/>
|
||
|
||
<!-- bottom -->
|
||
<polyline
|
||
points="104,363 385,363"
|
||
fill="none"
|
||
class="g-rect-path"
|
||
stroke="#0094FF"
|
||
stroke-dasharray="3 3"
|
||
/>
|
||
<rect
|
||
x="104"
|
||
y="361"
|
||
width="285"
|
||
height="4"
|
||
:style="{ fill: 'rgba(100,100,100,0)', stroke: 'transparent',cursor: 'pointer' }"
|
||
@click="lookDeviceDetail('line-bottom-left')"
|
||
/>
|
||
<polyline
|
||
points="385,363 655,363"
|
||
fill="none"
|
||
class="g-rect-path"
|
||
stroke="#0094FF"
|
||
stroke-dasharray="3 3"
|
||
/>
|
||
<rect
|
||
x="385"
|
||
y="361"
|
||
width="270"
|
||
height="4"
|
||
:style="{ fill: 'rgba(100,100,100,0)', stroke: 'transparent',cursor: 'pointer' }"
|
||
@click="lookDeviceDetail('line-bottom-right')"
|
||
/>
|
||
|
||
<!-- top -->
|
||
<circle
|
||
cx="154"
|
||
cy="80"
|
||
r="8"
|
||
style="stroke: none; fill: url(#RadialGradient1)"
|
||
/>
|
||
<circle
|
||
cx="600"
|
||
cy="80"
|
||
r="8"
|
||
style="stroke: none; fill: url(#RadialGradient1)"
|
||
/>
|
||
|
||
<!-- 动点 -->
|
||
<circle
|
||
cx="154"
|
||
cy="80"
|
||
r="8"
|
||
style="stroke: none; fill: url(#RadialGradient1)"
|
||
>
|
||
<animateMotion
|
||
repeatCount="indefinite"
|
||
dur="4s"
|
||
begin="0s"
|
||
:path="dotData.lineTopLeft"
|
||
/>
|
||
</circle>
|
||
<circle
|
||
cx="385"
|
||
cy="363"
|
||
r="8"
|
||
style="stroke: none; fill: url(#RadialGradient1)"
|
||
>
|
||
<animateMotion
|
||
repeatCount="indefinite"
|
||
dur="4s"
|
||
begin="2s"
|
||
:path="dotData.lineCenter"
|
||
/>
|
||
</circle>
|
||
<circle
|
||
cx="600"
|
||
cy="80"
|
||
r="8"
|
||
style="stroke: none; fill: url(#RadialGradient1)"
|
||
>
|
||
<animateMotion
|
||
repeatCount="indefinite"
|
||
dur="4s"
|
||
begin="0s"
|
||
:path="dotData.lineTopRight"
|
||
/>
|
||
</circle>
|
||
|
||
<!-- bottom -->
|
||
<circle
|
||
cx="104"
|
||
cy="363"
|
||
r="8"
|
||
style="stroke: none; fill: url(#RadialGradient1)"
|
||
/>
|
||
<circle
|
||
cx="385"
|
||
cy="363"
|
||
r="8"
|
||
style="stroke: none; fill: url(#RadialGradient1)"
|
||
/>
|
||
<circle
|
||
cx="655"
|
||
cy="363"
|
||
r="8"
|
||
style="stroke: none; fill: url(#RadialGradient1)"
|
||
/>
|
||
|
||
<circle
|
||
cx="104"
|
||
cy="363"
|
||
r="8"
|
||
style="stroke: none; fill: url(#RadialGradient1)"
|
||
>
|
||
<animateMotion
|
||
repeatCount="indefinite"
|
||
dur="4s"
|
||
begin="2s"
|
||
:path="dotData.lineBottomLeft"
|
||
/>
|
||
</circle>
|
||
|
||
<circle
|
||
cx="655"
|
||
cy="363"
|
||
r="8"
|
||
style="stroke: none; fill: url(#RadialGradient1)"
|
||
>
|
||
<animateMotion
|
||
repeatCount="indefinite"
|
||
dur="4s"
|
||
begin="2s"
|
||
:path="dotData.lineBottomRight"
|
||
/>
|
||
</circle>
|
||
<!-- 图片和文字 -->
|
||
|
||
<!-- 市电 -->
|
||
<image
|
||
:xlink:href="configData.grid"
|
||
x="70"
|
||
y="30"
|
||
width="90"
|
||
height="117"
|
||
/>
|
||
<text x="90" y="160" fill="#ffffff" font-size="14"> {{ $t("dashboard.grid") }}</text>
|
||
|
||
<!-- {{ $t("dashboard.load") }} -->
|
||
<image
|
||
:xlink:href="configData.house"
|
||
x="610"
|
||
y="30"
|
||
width="90"
|
||
height="117"
|
||
/>
|
||
<text x="645" y="160" fill="#ffffff" font-size="14"> {{ $t("dashboard.load") }}</text>
|
||
|
||
<!-- 1#PCS -->
|
||
<image
|
||
:xlink:href="configData.pcs2"
|
||
x="65"
|
||
y="383"
|
||
width="90"
|
||
height="90"
|
||
style="cursor: pointer;"
|
||
@click="lookDeviceDetail('second-pcs-left')"
|
||
/>
|
||
<text x="86" y="490" fill="#ffffff" font-size="14">1#{{ $t("dashboard.cabinet") }}</text>
|
||
|
||
<image
|
||
:xlink:href="configData.pcs2"
|
||
x="594"
|
||
y="383"
|
||
width="90"
|
||
height="90"
|
||
style="cursor: pointer;"
|
||
@click="lookDeviceDetail('second-pcs-right')"
|
||
/>
|
||
<text x="614" y="490" fill="#ffffff" font-size="14">2#{{ $t("dashboard.cabinet") }}</text>
|
||
|
||
<!-- 变压器 -->
|
||
<image
|
||
:xlink:href="configData.gui"
|
||
x="320"
|
||
y="193"
|
||
width="140"
|
||
height="105"
|
||
/>
|
||
|
||
<!-- {{ $t("dashboard.ammeter") }} -->
|
||
<image
|
||
:xlink:href="ammeterImg"
|
||
x="455"
|
||
y="130"
|
||
width="100"
|
||
height="60"
|
||
style="cursor: pointer;"
|
||
@click="lookDeviceDetail('second-ammeter')"
|
||
/>
|
||
<!-- 瞬时总有功 -->
|
||
|
||
<g v-for="(item,index) in ammeterData" :key="item.id">
|
||
<text x="435" :y="220 + ( 20 * index)" fill="#ffffff" font-size="14">
|
||
{{ item.name }}
|
||
</text>
|
||
<text :x="countChineseAndEnglishCharacters(item.name,435)" :y="220 + ( 20 * index)" fill="#FFB800" font-size="14">
|
||
{{ item.value }}
|
||
</text>
|
||
</g>
|
||
<!-- <text x="435" y="220" fill="#ffffff" font-size="14">
|
||
{{ $t("dashboard.totalP") }}(kW):
|
||
</text>
|
||
<text x="545" y="220" fill="#ffb800" font-size="14">
|
||
{{ activePowerTotal.activePower }}
|
||
</text> -->
|
||
|
||
<!-- 左侧 -->
|
||
<!-- 1#PCS -->
|
||
<g v-for="(item,index) in pcsLeftData" :key="item.id">
|
||
<text x="85" :y="280 + ( 20 * index)" fill="#ffffff" font-size="14">
|
||
{{ item.name }}
|
||
</text>
|
||
<text :x="countChineseAndEnglishCharacters(item.name,85)" :y="280 + ( 20 * index)" fill="#FFB800" font-size="14">
|
||
{{ item.value }}
|
||
</text>
|
||
</g>
|
||
|
||
<!-- 中间 2PCS -->
|
||
|
||
<g v-for="(item,index) in pcsRightData" :key="item.id">
|
||
<text x="602" :y="280 + ( 20 * index)" fill="#ffffff" font-size="14">
|
||
{{ item.name }}
|
||
</text>
|
||
<text :x="countChineseAndEnglishCharacters(item.name,602)" :y="280 + ( 20 * index)" fill="#FFB800" font-size="14">
|
||
{{ item.value }}
|
||
</text>
|
||
</g>
|
||
|
||
</svg>
|
||
</div>
|
||
</div>
|
||
<DispositionPointData :disposition-show="show_point_dispostion" :max="4" :page-location="pageLocation" @close="closePoint" @getData="getDynamicPointData" />
|
||
</ItemBox>
|
||
</template>
|
||
|
||
<script>
|
||
import gridImg from '@/assets/images/wxjd/grid.png'
|
||
import ammeterImg from '@/assets/images/wxjd/ammeter.png'
|
||
import cabinetImg from '@/assets/images/wxjd/pcs-energy.png'
|
||
import chargingPileImg from '@/assets/images/home-office.png'
|
||
import distributionCabinetImg from '@/assets/images/wxjd/guiImg.png'
|
||
import frameImg from '@/assets/images/wxjd/frame.png'
|
||
import cangImg from '@/assets/images/home-cang.png'
|
||
import { DynamicConfigPoint } from '@/api/home-page/index'
|
||
import config from './config'
|
||
import { changeTheme } from '@/utils/index'
|
||
export default {
|
||
name: 'Index',
|
||
props: {
|
||
stationType: {
|
||
type: Number,
|
||
default: 0
|
||
},
|
||
stationId: {
|
||
type: Number,
|
||
default: 0
|
||
}
|
||
},
|
||
data() {
|
||
return {
|
||
gridImg,
|
||
ammeterImg,
|
||
cabinetImg,
|
||
chargingPileImg,
|
||
distributionCabinetImg,
|
||
cangImg,
|
||
frameImg,
|
||
dotData: {
|
||
lineTop: 'M 0,0 0,0',
|
||
lineBottomLeft: 'M 0,0 0,0 0,0',
|
||
lineBottomRight: 'M 0,0 0,0 0,0',
|
||
lineBottomLeftTwo: 'M 0,0 0,0 0,0',
|
||
lineBottomRightTwo: 'M 0,0 0,0 0,0'
|
||
},
|
||
|
||
partList: [
|
||
{ soc: 0, soh: 0, activePowerPCS: 0.0, reactivePowerPCS: 0.0 },
|
||
{ soc: 0, soh: 0, activePowerPCS: 0.0, reactivePowerPCS: 0.0 },
|
||
{ soc: 0, soh: 0, activePowerPCS: 0.0, reactivePowerPCS: 0.0 },
|
||
{ soc: 0, soh: 0, activePowerPCS: 0.0, reactivePowerPCS: 0.0 }
|
||
],
|
||
loading: false,
|
||
activePowerTotal: {},
|
||
show_point_dispostion: false,
|
||
pageLocation: '',
|
||
permissionId: null,
|
||
pcsLeftData: [],
|
||
pcsRightData: [],
|
||
ammeterData: [],
|
||
configData: {}
|
||
|
||
}
|
||
},
|
||
computed: {},
|
||
watch: {},
|
||
created() {
|
||
const result = changeTheme()
|
||
this.configData = config[result]
|
||
setTimeout(() => {
|
||
if (this.$store.getters.menuList.length) {
|
||
this.permissionId = this.$store.getters.menuList.find(item => {
|
||
return item.url === this.$route.path
|
||
}).id
|
||
}
|
||
}, 300)
|
||
},
|
||
mounted() {},
|
||
methods: {
|
||
countChineseAndEnglishCharacters(str, x) {
|
||
var chineseCount = str.match(/[\u4e00-\u9fa5]/g) ? str.match(/[\u4e00-\u9fa5]/g).length : 0
|
||
var englishCount = str.match(/[a-zA-Z]/g) ? str.match(/[a-zA-Z]/g).length : 0
|
||
var otherCount = str.length - chineseCount - englishCount
|
||
const obj = { otherCount: otherCount, chineseCount: chineseCount, englishCount: englishCount }
|
||
return (obj.englishCount * 11) + (obj.chineseCount * 16) + (obj.otherCount * 8) + x
|
||
},
|
||
lookDeviceDetail(val) { // 查看设备详情
|
||
this.pageLocation = val
|
||
this.show_point_dispostion = true
|
||
},
|
||
closePoint() {
|
||
this.show_point_dispostion = false
|
||
},
|
||
async getpcsLeft() {
|
||
this.loading = true
|
||
try {
|
||
const res = await DynamicConfigPoint({
|
||
pageLocation: 'second-pcs-left',
|
||
permissionId: this.permissionId,
|
||
stationId: this.stationId })
|
||
this.pcsLeftData = res.data
|
||
} catch (error) {
|
||
// console.log(error);
|
||
} finally {
|
||
this.loading = false
|
||
}
|
||
},
|
||
async getammeter() {
|
||
this.loading = true
|
||
try {
|
||
const res = await DynamicConfigPoint({
|
||
pageLocation: 'second-ammeter',
|
||
permissionId: this.permissionId,
|
||
stationId: this.stationId })
|
||
this.ammeterData = res.data
|
||
} catch (error) {
|
||
// console.log(error);
|
||
} finally {
|
||
this.loading = false
|
||
}
|
||
},
|
||
async getpcsRight() {
|
||
this.loading = true
|
||
try {
|
||
const res = await DynamicConfigPoint({
|
||
pageLocation: 'second-pcs-right',
|
||
permissionId: this.permissionId,
|
||
stationId: this.stationId })
|
||
this.pcsRightData = res.data
|
||
} catch (error) {
|
||
// console.log(error);
|
||
} finally {
|
||
this.loading = false
|
||
}
|
||
},
|
||
async getLineStatus(type) {
|
||
this.loading = true
|
||
try {
|
||
const res = await DynamicConfigPoint({
|
||
pageLocation: type,
|
||
permissionId: this.permissionId,
|
||
stationId: this.stationId })
|
||
|
||
if (type === 'line-bottom-left') {
|
||
if (res.data?.length) {
|
||
if (res.data[0].value > 0) {
|
||
this.dotData.lineBottomLeft = 'M 283,0, 280, 0, 0 ,0'
|
||
} else if (res.data[0].value < 0) {
|
||
this.dotData.lineBottomLeft = 'M 0,0 281,0 281,0'
|
||
} else {
|
||
this.dotData.lineBottomLeft = ''
|
||
}
|
||
} else {
|
||
this.dotData.lineBottomLeft = ''
|
||
}
|
||
} else if (type === 'line-bottom-right') {
|
||
if (res.data?.length) {
|
||
if (res.data[0].value > 0) {
|
||
this.dotData.lineBottomRight = 'M -271, 0 , -271 , 0 , 0 , 0'
|
||
} else if (res.data[0].value < 0) {
|
||
this.dotData.lineBottomRight = 'M 0,0 -271,0 -271,0'
|
||
} else {
|
||
this.dotData.lineBottomRight = ''
|
||
}
|
||
} else {
|
||
this.dotData.lineBottomRight = ''
|
||
}
|
||
} else if (type === 'line-center') {
|
||
if (res.data?.length) {
|
||
if (res.data[0].value > 0) {
|
||
this.dotData.lineCenter = 'M 0,-283,0,0,0,0'
|
||
} else if (res.data[0].value < 0) {
|
||
this.dotData.lineCenter = 'M 0,0,0,0,0,-283'
|
||
} else {
|
||
this.dotData.lineCenter = ''
|
||
}
|
||
} else {
|
||
this.dotData.lineCenter = ''
|
||
}
|
||
} else if (type === 'line-top-left') {
|
||
if (res.data?.length) {
|
||
if (res.data[0].value > 0) {
|
||
this.dotData.lineTopLeft = 'M 238,0 0,0'
|
||
} else if (res.data[0].value < 0) {
|
||
this.dotData.lineTopLeft = 'M 0,0 238,0'
|
||
} else {
|
||
this.dotData.lineTopLeft = ''
|
||
}
|
||
} else {
|
||
this.dotData.lineTopLeft = ''
|
||
}
|
||
} else if (type === 'line-top-right') {
|
||
if (res.data?.length) {
|
||
if (res.data[0].value > 0) {
|
||
this.dotData.lineTopRight = 'M -230,0 0,0'
|
||
} else if (res.data[0].value < 0) {
|
||
this.dotData.lineTopRight = 'M 0,0 -230,0'
|
||
} else {
|
||
this.dotData.lineTopRight = ''
|
||
}
|
||
} else {
|
||
this.dotData.lineTopRight = ''
|
||
}
|
||
}
|
||
} catch (error) {
|
||
// console.log(error);
|
||
} finally {
|
||
this.loading = false
|
||
}
|
||
},
|
||
|
||
getData() {
|
||
this.getpcsRight()
|
||
this.getpcsLeft()
|
||
this.getammeter()
|
||
this.getLineStatus('line-bottom-left')
|
||
this.getLineStatus('line-center')
|
||
this.getLineStatus('line-bottom-right')
|
||
this.getLineStatus('line-top-left')
|
||
this.getLineStatus('line-top-right')
|
||
},
|
||
getDynamicPointData() {
|
||
this.getData()
|
||
}
|
||
|
||
}
|
||
}
|
||
</script>
|
||
<style lang="scss" scoped>
|
||
.center-box {
|
||
width: 100%;
|
||
height: 100%;
|
||
}
|
||
|
||
@mixin move-round($duration, $delay) {
|
||
fill: none;
|
||
stroke-width: 5;
|
||
stroke-linejoin: round;
|
||
stroke-linecap: round;
|
||
stroke-dasharray: 3, 900;
|
||
stroke-dashoffset: 0;
|
||
animation: lineMove $duration $delay cubic-bezier(0, 0, 0.74, 0.74) infinite;
|
||
}
|
||
|
||
@keyframes lineMove {
|
||
0% {
|
||
stroke-dashoffset: -850;
|
||
}
|
||
100% {
|
||
stroke-dashoffset: -0;
|
||
}
|
||
}
|
||
.g-rect-fill-two {
|
||
@include move-round(3.5s, 1s);
|
||
}
|
||
</style>
|