229 lines
6.5 KiB
Vue
229 lines
6.5 KiB
Vue
<script setup>
|
|
import { computed, inject, watch } from "vue";
|
|
import useSystemShowData from "@/hooks/useSystemShowData";
|
|
|
|
const { getCurrentInfoModalData, selected_dbid } = inject(
|
|
"system_selectedDevice"
|
|
);
|
|
const { subscribeData, realtimeData } = inject("system_deviceList");
|
|
|
|
const { showData } = useSystemShowData();
|
|
|
|
const FILE_BASEURL = import.meta.env.VITE_FILE_API_BASEURL;
|
|
|
|
|
|
// 根據設備編號取得即時狀態
|
|
const getDeviceRealtimeState = (deviceNumber) => {
|
|
const realtimeDevice = realtimeData.value?.find(
|
|
(item) => item.device_number === deviceNumber
|
|
);
|
|
return realtimeDevice?.state || '';
|
|
};
|
|
|
|
// 狀態顏色
|
|
const getDeviceStatusColor = (device) => {
|
|
if (device.full_name === 'SmartSocket-AA001') return 'red';
|
|
if (device.full_name === 'SmartSocket-AA003' || device.full_name === 'SmartSocket-AA004') return 'gray';
|
|
const state = getDeviceRealtimeState(device.device_number);
|
|
if (state === 'offnormal' || state === '') return device.device_close_color || '#9D9D9D';
|
|
return device.device_normal_color || '#009100';
|
|
};
|
|
|
|
// 狀態文字
|
|
const getDeviceStatusText = (device) => {
|
|
if (device.full_name === 'SmartSocket-AA001') return 'Error';
|
|
if (device.full_name === 'SmartSocket-AA003' || device.full_name === 'SmartSocket-AA004') return 'Offline';
|
|
const state = getDeviceRealtimeState(device.device_number);
|
|
if (state === 'offnormal' || state === '') return 'Offline';
|
|
if (state === 'normal') return 'Online';
|
|
return state || device.device_status || 'Online';
|
|
};
|
|
|
|
const fitToView = (forge_dbid, spriteDbId) => {
|
|
selected_dbid.value = [forge_dbid, spriteDbId];
|
|
};
|
|
|
|
const openDialog = () => {
|
|
document.getElementById("iframe_modal").showModal();
|
|
};
|
|
const cancelDialog = () => {
|
|
document.getElementById("iframe_modal").close();
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<dialog
|
|
id="iframe_modal"
|
|
className="modal w-[590px] h-[490px] my-auto rounded-lg mx-auto"
|
|
>
|
|
<iframe
|
|
src="https://app.mockplus.cn/p/zNB4y8k5L"
|
|
frameborder="0"
|
|
class="w-full h-full"
|
|
></iframe>
|
|
<button
|
|
type="link"
|
|
class="btn-link btn-text-without-border z-20 absolute right-[2.3rem] top-[2.2rem]"
|
|
@click="cancelDialog"
|
|
>
|
|
<font-awesome-icon
|
|
:icon="['fas', 'times']"
|
|
class="text-[#a5abb1] text-2xl"
|
|
/>
|
|
</button>
|
|
</dialog>
|
|
|
|
<template v-if="showData.length > 0">
|
|
<div class="equipment-show" v-for="d in showData" :key="d.full_name">
|
|
<template v-if="d.device_list.length > 0">
|
|
<p class="title">{{ d.full_name }}</p>
|
|
<div class="grid grid-cols-1 lg:grid-cols-2 gap-5">
|
|
<div
|
|
class="col-auto relative"
|
|
v-for="device in d.device_list"
|
|
:key="device.device_guid"
|
|
>
|
|
<div
|
|
class="item h-full cursor-pointer"
|
|
@click="() => fitToView(device.forge_dbid, device.spriteDbId)"
|
|
>
|
|
<div class="left h-full flex flex-wrap justify-center">
|
|
<div class="sec02 w-full">
|
|
<img
|
|
v-if="device.device_image_url"
|
|
:src="`${FILE_BASEURL}/upload/device_icon/${device.device_image}`"
|
|
:alt="device.device_image"
|
|
/>
|
|
<span v-else></span>
|
|
<span>{{ device.full_name }}</span>
|
|
</div>
|
|
<div class="flex justify-between w-full self-end">
|
|
<div class="sec03">
|
|
<span
|
|
class="w-5 h-5 rounded-full"
|
|
:style="{ backgroundColor: getDeviceStatusColor(device) }"
|
|
></span>
|
|
<span class="mx-2">{{ $t("system.status") }}:</span>
|
|
<span>{{ getDeviceStatusText(device) }}</span>
|
|
</div>
|
|
<button
|
|
class="btn-text border-0"
|
|
@click.prevent="
|
|
(e) => {
|
|
if (device.full_name === 'SmartSocket-AA001') {
|
|
openDialog();
|
|
} else {
|
|
getCurrentInfoModalData(
|
|
e,
|
|
{ left: e.clientX, top: e.clientY },
|
|
device
|
|
);
|
|
}
|
|
}
|
|
"
|
|
>
|
|
{{ $t("system.details") }}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</div>
|
|
</template>
|
|
</template>
|
|
|
|
<style lang="css" scoped>
|
|
/*設備顯示*/
|
|
.title {
|
|
@apply text-lg text-white relative inline-block mb-5 after:absolute after:-bottom-2 after:left-1/4 after:w-4/5 after:h-[1px] after:bg-info;
|
|
}
|
|
|
|
.item {
|
|
@apply flex items-center border border-success rounded shadow-emerald-600 shadow-inner py-4 px-5 relative mb-5 after:absolute after:right-0 after:top-3 after:w-6 after:h-10 after:bg-[url(/src/assets/img/equipment/state-background.svg)] after:z-10;
|
|
}
|
|
|
|
.item .btn-text {
|
|
@apply hover:bg-transparent focus-within:bg-transparent !important;
|
|
}
|
|
|
|
.equipment-show .item .sec01 span:nth-child(1) {
|
|
font-size: 1rem;
|
|
position: relative;
|
|
margin-right: 50px;
|
|
}
|
|
|
|
.equipment-show .item .sec01 span:nth-child(1)::after {
|
|
content: "";
|
|
position: absolute;
|
|
bottom: 5px;
|
|
right: -47px;
|
|
display: block;
|
|
transform: translateY(50%);
|
|
width: 45px;
|
|
height: 1px;
|
|
background-color: #35eded;
|
|
border-radius: 25px;
|
|
z-index: 10;
|
|
}
|
|
|
|
.equipment-show .item .sec01 span:nth-child(2) {
|
|
font-size: 0.6rem;
|
|
}
|
|
|
|
.equipment-show .item .sec02 {
|
|
display: flex;
|
|
align-items: center;
|
|
position: relative;
|
|
margin-bottom: 15px;
|
|
}
|
|
|
|
.equipment-show .item .sec02::after {
|
|
content: "";
|
|
background: url(/src/assets/img/equipment/state-title.svg) center center;
|
|
position: absolute;
|
|
right: 0;
|
|
bottom: -18px;
|
|
height: 25px;
|
|
width: 105px;
|
|
background-repeat: no-repeat;
|
|
z-index: 1;
|
|
}
|
|
|
|
.equipment-show .item .sec02 img {
|
|
margin-right: 10px;
|
|
width: 2rem !important;
|
|
height: 2rem;
|
|
}
|
|
|
|
.equipment-show .item .sec02 span:nth-child(1) {
|
|
background-color: #31afdf;
|
|
border: 3px solid #fff;
|
|
display: block;
|
|
border-radius: 5px;
|
|
margin-right: 10px;
|
|
width: 2rem !important;
|
|
height: 2rem;
|
|
}
|
|
|
|
.equipment-show .item .sec02 span:nth-child(2) {
|
|
font-size: 1.4rem;
|
|
width: calc(100% - 2rem);
|
|
word-break: break-all;
|
|
}
|
|
|
|
.equipment-show .item .sec03 {
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
|
|
/* .equipment-show .item .sec03 span:nth-child(1) {
|
|
width: 15px;
|
|
height: 15px;
|
|
border-radius: 100%;
|
|
display: block;
|
|
margin-right: 10px;
|
|
} */
|
|
</style>
|