MPVN_CMP/frontend/src/views/EnergyOverview.vue

53 lines
2.2 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="overview">
<div class="hero">
<div class="number">{{ totalPower }}</div>
<div class="label">实时总功率 kW</div>
</div>
<div class="grid">
<div class="card"><EnergyChart :points="points" /></div>
<div class="card">
<h3>能耗排行榜</h3>
<ul>
<li v-for="(item,i) in ranking" :key="i">{{ item.name }} <b>{{ item.kw }}</b> kW</li>
</ul>
</div>
<div class="card">
<h3>地图</h3>
<div class="map">项目分布Mock</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import axios from 'axios'
import EnergyChart from '@/components/EnergyChart/index.vue'
const base = (import.meta as any).env.VITE_BACKEND_URL || 'http://localhost:3001'
const totalPower = ref(0)
const points = ref<{ t:number, v:number }[]>([])
const ranking = ref<{ name:string, kw:number }[]>([])
async function refresh() {
const { data } = await axios.get(`${base}/energy/realtime`)
totalPower.value = data.totalPower
points.value.push({ t: Date.now(), v: data.totalPower }); if (points.value.length > 50) points.value.shift()
ranking.value = data.subitems.map((s:any) => ({ name: s.name, kw: s.kw })).sort((a,b) => b.kw - a.kw)
}
function loop() { refresh(); setTimeout(loop, 3000) }
onMounted(loop)
</script>
<style scoped>
.overview { padding: 16px; background: #0b132b; color: #fff; min-height: 100%; }
.hero { text-align: center; margin-bottom: 16px; }
.number { font-size: 56px; font-weight: 800; letter-spacing: 2px; animation: roll 1s ease-in-out; }
@keyframes roll { from { transform: translateY(10px); opacity: 0 } to { transform: translateY(0); opacity: 1 } }
.grid { display: grid; grid-template-columns: 2fr 1fr; grid-template-rows: 320px 320px; gap: 16px; }
.card { background: #1c2541; border-radius: 12px; padding: 12px; }
.map { height: 280px; border-radius: 8px; background: linear-gradient(135deg,#162447,#1f4068); display: flex; align-items: center; justify-content: center; opacity: .85 }
ul { list-style: none; padding: 0; margin: 0; }
li { display: flex; justify-content: space-between; padding: 8px 12px; background: #243b55; margin-bottom: 8px; border-radius: 8px; }
</style>