empower_front/src/views/dashboard/Dashboard.vue
2025-07-25 17:07:55 +08:00

168 lines
5.0 KiB
Vue

<script setup>
import DashboardFloorBar from "./components/DashboardFloorBar.vue";
import DashboardEffectScatter from "./components/DashboardEffectScatter.vue";
import DashboardSysCard from "./components/DashboardSysCard.vue";
import DashboardProduct from "./components/DashboardProduct.vue";
import DashboardProductComplete from "./components/DashboardProductComplete.vue";
import DashboardTemp from "./components/DashboardTemp.vue";
import DashboardHumidity from "./components/DashboardHumidity.vue";
import DashboardRefrigTemp from "./components/DashboardRefrigTemp.vue";
import DashboardIndoorTemp from "./components/DashboardIndoorTemp.vue";
import DashboardElectricity from "./components/DashboardElectricity.vue";
import DashboardEmission from "./components/DashboardEmission.vue";
import DashboardAlert from "./components/DashboardAlert.vue";
import { computed, inject, ref, watch, onMounted, onUnmounted } from "vue";
import useBuildingStore from "@/stores/useBuildingStore";
import { getSystemDevices, getSystemRealTime } from "@/apis/system";
const FILE_BASEURL = import.meta.env.VITE_FILE_API_BASEURL;
const buildingStore = useBuildingStore()
const subscribeData = ref([]);
const systemData = ref({});
let intervalId = null;
// 開始定時器
const startInterval = () => {
// 清除之前的定時器(如果存在)
if (intervalId) {
clearInterval(intervalId);
}
// 每5秒呼叫一次 getData
intervalId = setInterval(() => {
getData();
}, 5000);
};
const getData = async () => {
const res = await getSystemDevices({
building_guid: buildingStore.selectedBuilding?.building_guid,
})
subscribeData.value = res.data
console.log("devices", subscribeData.value)
// 轉換資料格式
const transformedData = {};
subscribeData.value.forEach(floor => {
if (floor.device_list && floor.device_list.length > 0) {
const fullUrl = floor.floor_map_name;
const uuid = fullUrl ? fullUrl.replace(/\.svg$/, "") : "";
transformedData[uuid] = floor.device_list.map(device => {
// 解析座標
const coordinates = JSON.parse(device.device_coordinate || '[0,0]');
const x = coordinates[0];
const y = coordinates[1];
// 決定設備狀態和顏色
let state = "Online";
let bgColor = device.device_normal_color;
if (device.device_status === "Offline" || device.device_status === null) {
state = "Offline";
bgColor = device.device_close_color;
}
if (device.device_status === "Error") {
state = "Error";
bgColor = device.device_error_color;
}
return [
x,
y,
{
device_number: device.device_number || "", // 設備編號
device_coordinate: device.device_coordinate || "", // 設備座標
device_image_url: device.device_image_url,
full_name: device.full_name, // 設備名稱
main_id: device.main_id,
points: device.points || [],
floor: floor.full_name,
state: state,
icon: device.device_image ? `${FILE_BASEURL}/upload/device_icon/${device.device_image}` : '',
bgColor: bgColor,
Online_color: device.device_normal_color,
Offline_color: device.device_close_color,
Error_color: device.device_error_color,
bgSize: 50,
}
];
});
}
});
console.log("transformedData", transformedData);
systemData.value = transformedData;
}
watch(
() => buildingStore.selectedBuilding,
(newBuilding) => {
if (newBuilding) {
getData();
startInterval();
}
},
{
immediate: true
}
);
// 組件卸載時清除定時器
onUnmounted(() => {
if (intervalId) {
clearInterval(intervalId);
}
});
</script>
<template>
<div class="flex flex-wrap justify-between">
<div
class="order-3 lg:order-1 w-full lg:w-1/4 h-full flex flex-col justify-start z-10 border-dashboard px-12"
>
<div>
<DashboardProduct />
</div>
<div class="mt-6">
<DashboardProductComplete />
</div>
<div class="mt-6">
<DashboardTemp />
</div>
<div class="mt-10">
<DashboardHumidity />
</div>
</div>
<div
class="order-1 lg:order-2 w-full lg:w-2/4 relative lg:static min-h-[300px] lg:h-full"
>
<DashboardFloorBar />
<DashboardEffectScatter :data="systemData"/>
</div>
<div class="order-2 w-full lg:hidden my-3">
<DashboardSysCard :data="systemData"/>
</div>
<div
class="order-last w-full lg:w-1/4 flex flex-col justify-start border-dashboard z-20"
>
<div>
<DashboardElectricity />
</div>
<div class="mt-10">
<DashboardEmission />
</div>
<div class="mt-10">
<DashboardAlert />
</div>
</div>
</div>
</template>
<style lang="css" scoped>
.border-dashboard {
@apply lg:border lg:border-light-info bg-dark-info bg-opacity-70 lg:rounded-md p-3 first:mt-0 last:mb-0;
}
</style>