CviLux_fe/src/views/headquarters/components/ElecRank.vue

141 lines
3.6 KiB
Vue

<script setup>
import { ref, watch, computed, onUnmounted } from "vue";
import { getSystemEnergyCostRank } from "@/apis/headquarters";
import { useI18n } from "vue-i18n";
import useBuildingStore from "@/stores/useBuildingStore";
const store = useBuildingStore();
const { t } = useI18n();
const energyCostData = ref({});
const energyTypeList = ref([
{
title: t("dashboard.today_energy_consumption"),
key: "day",
},
{
title: t("dashboard.this_month_energy_consumption"),
key: "month",
},
]);
const currentEnergyType = ref({
name: "month",
});
let intervalId = null;
const currentEnergyData = computed(() => {
if (!energyCostData.value) {
return [];
}
return currentEnergyType.value.name === "month"
? energyCostData.value?.month || []
: energyCostData.value?.day || [];
});
const getEnergyRank = async () => {
try {
const res = await getSystemEnergyCostRank({
building_ids: store.buildings.map((building) => building.building_guid),
});
energyCostData.value = res.data;
} catch (error) {
console.error("Error fetching energy cost rank:", error);
}
};
watch(
() => store.buildings,
(newBuilding) => {
if (newBuilding) {
getEnergyRank();
if (intervalId) {
clearInterval(intervalId);
}
intervalId = setInterval(() => {
getEnergyRank();
}, 60 * 60 * 1000);
}
},
{ immediate: true }
);
onUnmounted(() => {
clearInterval(intervalId);
});
</script>
<template>
<div class="state-box-col relative">
<!-- 標題和切換按鈕 -->
<div class="flex justify-between items-center mb-2">
<h2 class="font-light relative">
{{ $t("dashboard.energy_ranking") }}
</h2>
<Select
:value="currentEnergyType"
class="!w-24"
selectClass="border-info focus-within:border-info btn-xs text-xs"
name="name"
Attribute="title"
:options="energyTypeList"
:isTopLabelExist="false"
:isBottomLabelExist="false"
>
</Select>
</div>
<!-- 能耗排名列表 -->
<div class="overflow-y-auto" style="height: 200px;">
<table class="table table-sm text-center">
<tbody>
<tr
v-for="(item, index) in currentEnergyData"
:key="index"
:class="[
{ 'text-red-300': index + 1 === 1 },
{ 'text-orange-300': index + 1 === 2 },
{ 'text-yellow-300': index + 1 === 3 },
{ 'text-teal-300': index + 1 > 3 },
]"
>
<td class="px-0 align-top">
<p class="flex items-center">
<font-awesome-icon :icon="['fas', 'crown']" class="me-1" />
{{ index + 1 }}
</p>
</td>
<td class="align-top whitespace-nowrap px-0">
{{ item.site_name }}
</td>
<td class="align-top">{{ item.name }}</td>
<td class="align-top ps-0">{{ item.value }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</template>
<style lang="scss" scoped>
.state-box-col {
@apply border-2 border-light-info rounded-sm p-2 text-white relative;
}
.state-box-col:before {
@apply absolute left-0 right-0 -top-0.5 m-auto h-2 w-36 bg-no-repeat bg-center z-10;
content: "";
background-image: url(@ASSET/img/state-box-top.png);
}
.state-box-col:after {
@apply absolute left-0 right-0 -bottom-0.5 m-auto h-2 w-36 bg-no-repeat bg-center z-10;
content: "";
background-image: url(@ASSET/img/state-box-bottom.png);
}
tr td {
@apply text-[13px] text-start;
}
</style>