empower_front/src/views/dashboard/Dashboard.vue

195 lines
6.3 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.

<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 DashboardIndoor from "./components/DashboardIndoor.vue";
import DashboardElectricity from "./components/DashboardElectricity.vue";
import DashboardEmission from "./components/DashboardEmission.vue";
import DashboardAlert from "./components/DashboardAlert.vue";
import DashboardRefrig from "./components/DashboardRefrig.vue";
import { computed, inject, ref, watch, onMounted, onUnmounted } from "vue";
import useBuildingStore from "@/stores/useBuildingStore";
import { getSystemDevices, getSystemRealTime } from "@/apis/system";
// ⭐ 新增:引入 getSystemConfig
import { getSystemConfig } 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 productVisible = ref(false);
const productCompleteVisible = ref(false);
// ⭐ 新增:冷凍空調卡片顯示狀態(預設 false
const showRefrigeration = ref(false);
// ⭐ 新增:讀取系統配置
const loadSystemConfig = async () => {
const building_guid = buildingStore.selectedBuilding?.building_guid;
if (!building_guid) {
showRefrigeration.value = false;
return;
}
try {
const res = await getSystemConfig(building_guid);
// 你的 apiHandler 可能回傳 { data, code, msg } 或直接回 data兩者都兼容
const data = res?.data ?? res;
showRefrigeration.value = !!data?.show_refrigeration;
// 若未來還要控制其他區塊(如 show_room、show_production_indicator也可一併在這裡設定
} catch (err) {
console.error("[Dashboard] getSystemConfig error:", err);
showRefrigeration.value = false; // 失敗時保守處理:不顯示
}
};
// 取得設備資料(維持原本邏輯)
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,
brand: device.brand || "",
device_model: device.device_model,
operation_name: device.operation_name,
operation_contact_person: device.operation_contact_person,
buying_date: device.buying_date,
created_at: device.created_at,
bgSize: 50,
is_rtsp: device.is_rtsp === true,
rtsp_url: device.rtsp_url || "",
},
];
});
}
});
console.log("transformedData", transformedData);
systemData.value = transformedData;
};
// 每 5 秒輪詢設備資料(維持原本邏輯)
const startInterval = () => {
if (intervalId) clearInterval(intervalId);
intervalId = setInterval(() => {
getData();
}, 5000);
};
// 當切換建物時:同時載入系統設定 + 設備資料
watch(
() => buildingStore.selectedBuilding,
async (newBuilding) => {
if (newBuilding) {
await loadSystemConfig(); // ⭐ 先載設定(避免先渲染出不該顯示的卡片)
getData();
startInterval();
} else {
showRefrigeration.value = false;
}
},
{ 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 min-h-screen flex flex-col justify-start item-center z-10 border-dashboard gap-12"
>
<div class="flex flex-col gap-5">
<DashboardIndoor />
</div>
<!-- show_refrigeration 決定是否渲染 -->
<div class="flex flex-col gap-5" v-if="showRefrigeration">
<DashboardRefrig />
</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-last w-full lg:w-1/4 flex flex-col justify-start border-dashboard z-20 gap-12"
>
<div class="flex flex-col gap-5">
<DashboardElectricity />
</div>
<div class="flex flex-col gap-5">
<DashboardEmission />
</div>
<div class="flex flex-col gap-5">
<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 py-12 px-8 first:mt-0 last:mb-0;
}
</style>