CviLux_fe/src/views/headquarters/components/SysProgress.vue
ko1234 3427058cd2 MQTT publish topic 名稱修改 |
系統監控switch功能 | 總部地圖功能
2025-08-06 13:48:04 +08:00

152 lines
3.9 KiB
Vue

<script setup>
import { ref, computed, watch, onUnmounted } from "vue";
import { useRouter } from "vue-router";
import { getSystemStatus } from "@/apis/headquarters";
import useBuildingStore from "@/stores/useBuildingStore";
import SysProgressModal from "./SysProgressModal.vue";
import { useI18n } from "vue-i18n";
const { t } = useI18n();
const router = useRouter();
const store = useBuildingStore();
const equipmentData = ref([]);
const modalData = ref({});
let intervalId = null;
const openModal = (item) => {
modalData.value = item;
system_status_modal.showModal();
};
const onCancel = () => {
modalData.value = {};
system_status_modal.close();
};
const getAlarmsInfos = async () => {
try {
const res = await getSystemStatus({
building_ids: store.buildings.map((building) => building.building_guid),
});
const apiData = res.data;
// 轉換 equipmentData 的資料格式
if (apiData && apiData.alarm) {
equipmentData.value = apiData.alarm.map((item) => ({
label: item.system_name,
online: item.online || 0,
offline: item.offline || 0,
alarm: item.alarm || 0,
}));
}
} catch (error) {
console.error("Error fetching alarm info:", error);
}
};
watch(
() => store.buildings,
(newBuilding) => {
if (newBuilding) {
getAlarmsInfos();
if (intervalId) {
clearInterval(intervalId);
}
intervalId = setInterval(() => {
getAlarmsInfos();
}, 30000);
}
},
{ immediate: true }
);
onUnmounted(() => {
clearInterval(intervalId);
});
</script>
<template>
<SysProgressModal :onCancel="onCancel" :modalData="modalData" />
<div class="w-full state-box-col relative">
<div class="state-box">
<div class="title">
<img class="state-title01" src="@ASSET/img/state-title01.svg" />
<span class="">{{$t("dashboard.system_status")}}</span>
<img class="state-title02" src="@ASSET/img/state-title02.svg" />
</div>
<table class="table table-sm text-center">
<thead>
<tr class="border-cyan-400 text-cyan-100">
<th></th>
<th>{{ $t("alert.online") }}</th>
<th>{{ $t("alert.offline") }}</th>
<th>{{ $t("alert.alarm") }}</th>
</tr>
</thead>
<tbody>
<tr
v-for="(item, index) in equipmentData"
:key="index"
class="border-cyan-400 cursor-pointer hover:text-info"
@click.stop.prevent="openModal(item)"
>
<th class="px-0 text-start">{{ item.label }}</th>
<td>
{{ item.online.length }}
</td>
<td>
{{ item.offline.length }}
</td>
<td>
{{ item.alarm.length }}
</td>
</tr>
</tbody>
</table>
</div>
</div>
</template>
<style lang="scss" scoped>
.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);
}
.state-box-col {
@apply border border-light-info shadow-md shadow-blue-300 rounded-sm py-2 px-6 text-white relative;
}
.state-box:after {
@apply absolute right-3 top-3 w-4 h-4 bg-no-repeat bg-center z-10;
content: "";
background-image: url(@ASSET/img/state-title01.svg);
}
.state-box:before {
@apply absolute right-0.5 bottom-5 w-4 h-32 bg-no-repeat bg-center z-10;
content: "";
background-image: url(@ASSET/img/state-ul-background02.svg);
}
.state-box .title {
@apply relative flex items-center mb-1;
}
.state-box .title .state-title01 {
@apply w-4 mr-1.5;
}
.state-box .title .state-title02 {
@apply w-5 ml-1.5;
}
</style>