Merge branch 'main' into feature/system
This commit is contained in:
commit
1cc2ab77fa
@ -9,7 +9,7 @@
|
||||
href="https://developer.api.autodesk.com/modelderivative/v2/viewers/7.*/style.css"
|
||||
/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>瀚荃監控系統</title>
|
||||
<title>Cvilux EMS</title>
|
||||
<script src="https://code.jquery.com/jquery-3.7.1.js"></script>
|
||||
<script src="https://code.jquery.com/ui/1.13.3/jquery-ui.js"></script>
|
||||
<script type="text/javascript" src="/requirejs/config.js"></script>
|
||||
|
@ -25,14 +25,14 @@ onMounted(() => {
|
||||
<div
|
||||
tabindex="0"
|
||||
role="button"
|
||||
class="text-white ml-8 text-xl font-semiLight "
|
||||
class="text-white ml-8 text-lg font-semiLight "
|
||||
>
|
||||
{{ store.selectedBuilding?.full_name }}
|
||||
<font-awesome-icon :icon="['fas', 'angle-down']" class="ml-1"/>
|
||||
</div>
|
||||
<ul
|
||||
tabindex="0"
|
||||
class="dropdown-content left-8 translate-y-2 z-[1] menu py-3 shadow rounded w-32 bg-[#4c625e] border text-center"
|
||||
class="dropdown-content left-8 translate-y-2 z-[1] menu py-3 shadow rounded bg-[#4c625e] border text-center"
|
||||
>
|
||||
<li
|
||||
class="text-white my-1 text-base"
|
||||
|
@ -115,12 +115,12 @@ onMounted(() => {
|
||||
color: #93c0dc;
|
||||
}
|
||||
|
||||
::v-deep .ant-menu-submenu-title:active {
|
||||
:deep(.ant-menu-submenu-title:active) {
|
||||
color: #35759d !important;
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
||||
::v-deep .ant-menu-item:not(.ant-menu-item-selected) {
|
||||
:deep .ant-menu-item:not(.ant-menu-item-selected) {
|
||||
&::before {
|
||||
@apply absolute w-[15px] h-[15px] bottom-3.5 left-7 bg-no-repeat z-10 grayscale;
|
||||
content: "";
|
||||
@ -132,7 +132,7 @@ onMounted(() => {
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep .ant-menu-item-selected {
|
||||
:deep .ant-menu-item-selected {
|
||||
@apply bg-transparent relative;
|
||||
|
||||
&::before {
|
||||
|
@ -23,11 +23,11 @@ provide("history_table_data", { tableData, updateTableData, loading, updateLoadi
|
||||
|
||||
<template>
|
||||
<h1 class="text-2xl font-extrabold mb-2">{{ $t('history.title') }}</h1>
|
||||
<div class="grid grid-cols-12 gap-2">
|
||||
<div class="col-span-2 pe-5">
|
||||
<div class="grid grid-cols-10 gap-2">
|
||||
<div class="col-span-2 ">
|
||||
<HistorySidebar />
|
||||
</div>
|
||||
<div class="col-span-10 ">
|
||||
<div class="col-span-8 ">
|
||||
<HistorySearch />
|
||||
<HistoryTable />
|
||||
</div>
|
||||
|
@ -1,26 +1,36 @@
|
||||
<script setup>
|
||||
import Collapse from "@/components/customUI/Collapse.vue";
|
||||
import Checkbox from "@/components/customUI/Checkbox.vue";
|
||||
import { computed, ref, watch } from "vue";
|
||||
import useBuildingStore from "@/stores/useBuildingStore";
|
||||
import useSearchParam from "@/hooks/useSearchParam";
|
||||
import { getHistorySideBar } from "@/apis/history";
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useI18n } from "vue-i18n";
|
||||
const { t } = useI18n();
|
||||
const { searchParams, changeParams } = useSearchParam();
|
||||
|
||||
// const store = useBuildingStore();
|
||||
const selectedBuilding = ref([]);
|
||||
const deviceData = ref([]);
|
||||
|
||||
const getDeviceData = async (sub_tag, renew) => {
|
||||
const res = await getHistorySideBar(sub_tag);
|
||||
deviceData.value = res.data.map((d) => ({
|
||||
...d,
|
||||
key: d.building_tag,
|
||||
deviceData.value = res.data.map((building) => ({
|
||||
building_tag: building.building_tag,
|
||||
building_name: building.building_name,
|
||||
floors: building.floor_list.map((floor) => ({
|
||||
floor_tag: floor.device_floor_tag,
|
||||
floor_name: floor.floor_name,
|
||||
devices: floor.device_list.map((device) => ({
|
||||
...device,
|
||||
key: device.device_number,
|
||||
})),
|
||||
})),
|
||||
}));
|
||||
|
||||
selectedBuilding.value = res.data.map((d) => d.building_tag);
|
||||
changeSelected([res.data[0]?.device_list[0]?.device_number], renew);
|
||||
changeSelected(
|
||||
[res.data[0]?.floor_list[0]?.device_list[0]?.device_number],
|
||||
renew
|
||||
);
|
||||
};
|
||||
|
||||
const sysIsExisted = (building_tag) => {
|
||||
@ -54,7 +64,6 @@ watch(
|
||||
}
|
||||
);
|
||||
|
||||
// 取得 checked 設備列表
|
||||
const selectedDeviceNumber = computed(() => {
|
||||
return typeof searchParams.value.Device_list === "string"
|
||||
? [searchParams.value.Device_list]
|
||||
@ -75,34 +84,66 @@ const isChecked = (device, checked) => {
|
||||
|
||||
const checkedBuilding = computed(() => {
|
||||
let selected = [];
|
||||
deviceData.value.forEach(({ building_tag, device_list }) => {
|
||||
deviceData.value.forEach(({ building_tag, floors }) => {
|
||||
let allDevices = [];
|
||||
floors.forEach((floor) => {
|
||||
allDevices = [...allDevices, ...floor.devices];
|
||||
});
|
||||
|
||||
if (
|
||||
selectedDeviceNumber.value?.filter(
|
||||
(d) => d.split("_")[1] === building_tag
|
||||
).length === device_list.length
|
||||
).length === allDevices.length
|
||||
) {
|
||||
selected.push(building_tag);
|
||||
}
|
||||
});
|
||||
return selected;
|
||||
});
|
||||
|
||||
const buildingCheck = (building_tag) => {
|
||||
const building = deviceData.value.find(
|
||||
(d) => d.building_tag === building_tag
|
||||
);
|
||||
const allDevicesInBuilding = building.floors.flatMap((floor) =>
|
||||
floor.devices.map((device) => device.device_number)
|
||||
);
|
||||
|
||||
if (checkedBuilding.value?.includes(building_tag)) {
|
||||
// 取消勾選該建築下的所有設備
|
||||
changeSelected(
|
||||
selectedDeviceNumber.value.filter(
|
||||
(device_number) => device_number.split("_")[1] !== building_tag
|
||||
(device_number) => !allDevicesInBuilding.includes(device_number)
|
||||
)
|
||||
);
|
||||
} else {
|
||||
// 勾選該建築下的所有設備
|
||||
changeSelected([
|
||||
...new Set(
|
||||
[
|
||||
...selectedDeviceNumber.value,
|
||||
...deviceData.value
|
||||
.find((d) => d.building_tag === building_tag)
|
||||
?.device_list.map(({ device_number }) => device_number),
|
||||
].filter((d) => d !== "")
|
||||
),
|
||||
...new Set([...selectedDeviceNumber.value, ...allDevicesInBuilding]),
|
||||
]);
|
||||
}
|
||||
};
|
||||
|
||||
const areAllDevicesCheckedInFloor = (devices) => {
|
||||
return devices.every((device) =>
|
||||
selectedDeviceNumber.value.includes(device.device_number)
|
||||
);
|
||||
};
|
||||
|
||||
const toggleFloorDevices = (devices) => {
|
||||
const allChecked = areAllDevicesCheckedInFloor(devices);
|
||||
|
||||
if (allChecked) {
|
||||
changeSelected(
|
||||
selectedDeviceNumber.value.filter(
|
||||
(device_number) =>
|
||||
!devices.some((device) => device.device_number === device_number)
|
||||
)
|
||||
);
|
||||
} else {
|
||||
const deviceNumbers = devices.map((device) => device.device_number);
|
||||
changeSelected([
|
||||
...new Set([...selectedDeviceNumber.value, ...deviceNumbers]),
|
||||
]);
|
||||
}
|
||||
};
|
||||
@ -132,50 +173,68 @@ const changeSelected = (Device_list, renew = false) => {
|
||||
:icon="['fas', 'search']"
|
||||
class="w-6 h-6 mr-2 text-info"
|
||||
/>
|
||||
<input type="text" :placeholder="t('button.enter_text')"
|
||||
class="text-white bg-transparent w-full" />
|
||||
<input
|
||||
type="text"
|
||||
:placeholder="t('button.enter_text')"
|
||||
class="text-white bg-transparent w-full"
|
||||
/>
|
||||
</label>
|
||||
<template v-for="d in deviceData" :key="d.building_tag">
|
||||
<Collapse
|
||||
:open="selectedBuilding.includes(d.building_tag)"
|
||||
:data="
|
||||
d.device_list?.map((device) => ({
|
||||
...device,
|
||||
key: device.device_number,
|
||||
}))
|
||||
"
|
||||
:toggle="() => toggleSelectedBuilding(d.building_tag)"
|
||||
>
|
||||
<!-- :checked="selectedDeviceNumber.includes(data.device_number)" -->
|
||||
<template #collapseTitle>
|
||||
<Checkbox
|
||||
:title="d.building_name"
|
||||
:checked="checkedBuilding.includes(d.building_tag)"
|
||||
:onClick="
|
||||
() => {
|
||||
buildingCheck(d.building_tag);
|
||||
}
|
||||
"
|
||||
/>
|
||||
</template>
|
||||
<template #collapseContent="{ data }">
|
||||
<span class="flex items-center text-xl">
|
||||
<Checkbox
|
||||
:title="data.device_name"
|
||||
:checked="selectedDeviceNumber.includes(data.device_number)"
|
||||
:onClick="
|
||||
() => {
|
||||
isChecked(
|
||||
data.device_number,
|
||||
!selectedDeviceNumber.includes(data.device_number)
|
||||
);
|
||||
}
|
||||
"
|
||||
/>
|
||||
</span>
|
||||
</template>
|
||||
</Collapse>
|
||||
</template>
|
||||
<ul class="menu text-lg">
|
||||
<template v-for="building in deviceData" :key="building.building_tag">
|
||||
<li>
|
||||
<details :open="selectedBuilding.includes(building.building_tag)">
|
||||
<summary>
|
||||
<Checkbox
|
||||
:title="building.building_name"
|
||||
:checked="checkedBuilding.includes(building.building_tag)"
|
||||
@click="() => buildingCheck(building.building_tag)"
|
||||
/>
|
||||
</summary>
|
||||
<ul>
|
||||
<template v-for="floor in building.floors" :key="floor.floor_tag">
|
||||
<li>
|
||||
<details open>
|
||||
<summary>
|
||||
<Checkbox
|
||||
:title="floor.floor_name"
|
||||
:checked="areAllDevicesCheckedInFloor(floor.devices)"
|
||||
@click="toggleFloorDevices(floor.devices)"
|
||||
/>
|
||||
</summary>
|
||||
<ul>
|
||||
<template
|
||||
v-for="device in floor.devices"
|
||||
:key="device.device_number"
|
||||
>
|
||||
<li class="flex items-start">
|
||||
<Checkbox
|
||||
:title="device.device_name"
|
||||
:checked="
|
||||
selectedDeviceNumber.includes(
|
||||
device.device_number
|
||||
)
|
||||
"
|
||||
@click="
|
||||
() =>
|
||||
isChecked(
|
||||
device.device_number,
|
||||
!selectedDeviceNumber.includes(
|
||||
device.device_number
|
||||
)
|
||||
)
|
||||
"
|
||||
/>
|
||||
</li>
|
||||
</template>
|
||||
</ul>
|
||||
</details>
|
||||
</li>
|
||||
</template>
|
||||
</ul>
|
||||
</details>
|
||||
</li>
|
||||
</template>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -17,7 +17,7 @@ const getFloors = async () => {
|
||||
let data = res.data.find(d => d.building_tag === store.selectedBuilding?.building_tag)
|
||||
data = [
|
||||
{
|
||||
title: "總覽",
|
||||
title: "All",
|
||||
key: "main",
|
||||
active: route.params.floor_id === "main",
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user