168 lines
5.0 KiB
Vue
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>
|