Files
emsfront/src/views/ems/zddt/index.vue

285 lines
8.2 KiB
Vue
Raw Normal View History

<template>
2025-06-28 14:52:49 +08:00
<div class="ems-dashboard-editor-container" v-loading="loading">
<zd-info></zd-info>
2026-02-17 21:44:12 +08:00
<div class="ems-content-container">
<div class="map-container">
2026-02-17 21:44:12 +08:00
<div class="site-cards-wrapper" v-if="allSites.length > 0">
<button
class="site-cards-arrow site-cards-arrow--left"
type="button"
:disabled="!canScrollLeft"
@click="scrollSiteCards('left')"
>
<i class="el-icon-arrow-left"></i>
</button>
<div ref="siteCards" class="site-cards" @scroll="updateScrollButtons">
<div
v-for="item in allSites"
:key="item.siteId"
class="site-card"
:class="{ active: isSameSite(item.siteId, singleSiteId) }"
@click="submitSite(item.siteId)"
>
<div class="site-card-name">{{ item.siteName || '-' }}</div>
<div class="site-card-info-row">
<span class="site-card-label">电站位置</span>
<span class="site-card-value site-card-value--address">{{ formatSiteCardField(item.siteAddress) }}</span>
</div>
<div class="site-card-info-row">
<span class="site-card-label">投运时间</span>
<span class="site-card-value">{{ formatSiteCardDate(item.runningTime) }}</span>
</div>
<div class="site-card-info-row">
2026-04-01 14:27:35 +08:00
<span class="site-card-label">装机功率(MWh)</span>
2026-02-17 21:44:12 +08:00
<span class="site-card-value">{{ formatSiteCardField(item.installPower) }}</span>
</div>
<div class="site-card-info-row">
2026-04-01 14:27:35 +08:00
<span class="site-card-label">装机容量(MWh)</span>
2026-02-17 21:44:12 +08:00
<span class="site-card-value">{{ formatSiteCardField(item.installCapacity) }}</span>
</div>
</div>
2026-02-17 21:44:12 +08:00
</div>
<button
class="site-cards-arrow site-cards-arrow--right"
type="button"
:disabled="!canScrollRight"
@click="scrollSiteCards('right')"
>
<i class="el-icon-arrow-right"></i>
</button>
</div>
<div class="map-view">
<map-chart ref="mapChart"/>
</div>
</div>
</div>
</div>
</template>
<script>
import ZdInfo from '@/components/Ems/ZdBaseInfo/index.vue'
import MapChart from './MapChart.vue'
2026-02-17 21:44:12 +08:00
import { getAllSites } from '@/api/ems/zddt'
export default {
2026-02-17 21:44:12 +08:00
components: { ZdInfo, MapChart },
data() {
return {
2026-02-17 21:44:12 +08:00
loading: false,
singleSiteId: '',
singleSiteName: '',
2026-04-01 14:27:35 +08:00
singleSiteAddress: '',
2026-02-17 21:44:12 +08:00
singleSiteLocation: [],
allSites: [],
canScrollLeft: false,
canScrollRight: false
}
},
2026-02-17 21:44:12 +08:00
mounted() {
this.loadSites()
window.addEventListener('resize', this.updateScrollButtons)
},
beforeDestroy() {
window.removeEventListener('resize', this.updateScrollButtons)
},
methods:{
2026-02-17 21:44:12 +08:00
isSameSite(siteId, selectedId) {
return String(siteId) === String(selectedId)
},
formatSiteCardField(value) {
if (value === null || value === undefined || value === '') {
return '-'
}
return value
},
formatSiteCardDate(value) {
if (!value) {
return '-'
}
const text = String(value)
if (text.includes('T')) {
return text.slice(0, 10)
}
return text.length > 10 ? text.slice(0, 10) : text
},
loadSites() {
this.loading = true
getAllSites().then(response => {
this.allSites = response?.data || []
if (this.allSites.length > 0) {
this.submitSite(this.allSites[0].siteId)
} else {
this.updateMapMarkers()
}
this.$nextTick(() => {
this.updateScrollButtons()
})
}).finally(() => {
this.loading = false
})
},
updateScrollButtons() {
const container = this.$refs.siteCards
if (!container) {
this.canScrollLeft = false
this.canScrollRight = false
return
}
const maxScrollLeft = container.scrollWidth - container.clientWidth
this.canScrollLeft = container.scrollLeft > 0
this.canScrollRight = maxScrollLeft > 0 && container.scrollLeft < maxScrollLeft - 1
},
scrollSiteCards(direction) {
const container = this.$refs.siteCards
if (!container) {
return
}
const amount = Math.max(container.clientWidth * 0.8, 240)
const delta = direction === 'left' ? -amount : amount
container.scrollBy({ left: delta, behavior: 'smooth' })
},
updateMapMarkers(){
this.$refs.mapChart && this.$refs.mapChart.setOption({
2026-04-01 14:27:35 +08:00
selected: {name:this.singleSiteName,address:this.singleSiteAddress,value:this.singleSiteLocation},
2026-02-17 21:44:12 +08:00
sites:this.allSites
})
},
// 站点选中
submitSite(id){
this.singleSiteId = id
2026-02-17 21:44:12 +08:00
const currentSite = this.allSites.find(item => this.isSameSite(item.siteId, id)) || {}
this.singleSiteName = currentSite.siteName || ''
2026-04-01 14:27:35 +08:00
this.singleSiteAddress = currentSite.siteAddress || ''
2026-02-17 21:44:12 +08:00
this.singleSiteLocation = currentSite.siteLocation || []
if (!this.singleSiteLocation.length) {
this.singleSiteLocation = [currentSite.longitude, currentSite.latitude].filter(item => item !== undefined && item !== null)
}
this.$nextTick(() => {
this.updateMapMarkers()
})
}
},
}
</script>
<style lang="scss" scoped>
.ems-content-container{
display: flex;
padding:24px;
.map-container{
flex:auto;
2026-02-17 21:44:12 +08:00
min-width: 0;
display: flex;
flex-direction: column;
gap: 12px;
.site-cards-wrapper{
display: flex;
align-items: center;
gap: 8px;
.site-cards-arrow{
width: 28px;
height: 28px;
border: none;
border-radius: 50%;
background: #ffffff;
box-shadow: 0 0 0 1px #dcdfe6 inset;
color: #606266;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
transition: all .2s ease;
&:hover:not(:disabled){
color: #2b74ff;
box-shadow: 0 0 0 1px #2b74ff inset;
}
&:disabled{
cursor: not-allowed;
color: #c0c4cc;
box-shadow: 0 0 0 1px #ebeef5 inset;
}
}
}
2026-02-17 21:44:12 +08:00
.site-cards{
display: flex;
gap: 10px;
overflow-x: auto;
padding-bottom: 2px;
scrollbar-width: none;
-ms-overflow-style: none;
&::-webkit-scrollbar{
display: none;
}
.site-card{
flex: 0 0 360px;
height: 166px;
border-radius: 8px;
background: #ffffff;
border: 1px solid #e4e7ed;
padding: 10px;
box-sizing: border-box;
cursor: pointer;
transition: all .2s ease;
.site-card-name{
font-size: 14px;
font-weight: 600;
color: #303133;
line-height: 22px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.site-card-info-row{
display: flex;
align-items: flex-start;
gap: 8px;
margin-top: 6px;
font-size: 12px;
line-height: 18px;
}
.site-card-label{
flex: 0 0 84px;
font-size: 12px;
color: #909399;
white-space: nowrap;
}
.site-card-value{
flex: 1;
color: #606266;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.site-card-value--address{
white-space: normal;
word-break: break-all;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
text-overflow: unset;
min-height: 36px;
}
&:hover{
border-color: #c0d3ff;
}
&.active{
border-color: #2b74ff;
box-shadow: 0 0 0 1px rgba(43,116,255,.15) inset;
background: #f5f9ff;
.site-card-name{
color: #2b74ff;
}
.site-card-value{
color: #5f8ee3;
}
}
}
}
2026-02-17 21:44:12 +08:00
.map-view{
height: 70vh;
min-height: 520px;
}
}
}
</style>