fix: 調整告警紀錄查 UIUX,直接透過復歸 tabs 顯示資料,移除搜尋按鈕
This commit is contained in:
parent
3750e3c124
commit
feac20d519
@ -57,7 +57,7 @@ const columns = computed(() => [
|
||||
{
|
||||
title: t("assetManagement.device_name"),
|
||||
key: "full_name",
|
||||
filter: true,
|
||||
// filter: true,
|
||||
class: "break-all",
|
||||
},
|
||||
{
|
||||
@ -67,13 +67,13 @@ const columns = computed(() => [
|
||||
{
|
||||
title: t("assetManagement.floor"),
|
||||
key: "floor",
|
||||
filter: true,
|
||||
sort: true,
|
||||
// filter: true,
|
||||
// sort: true,
|
||||
},
|
||||
{
|
||||
title: t("assetManagement.department"),
|
||||
key: "department",
|
||||
filter: true,
|
||||
// filter: true,
|
||||
},
|
||||
{
|
||||
title: t("assetManagement.device_coordinate"),
|
||||
@ -90,7 +90,7 @@ const columns = computed(() => [
|
||||
{
|
||||
title: t("assetManagement.buying_date"),
|
||||
key: "buying_date",
|
||||
sort: true,
|
||||
// sort: true,
|
||||
},
|
||||
// {
|
||||
// title: t("assetManagement.oriFile"),
|
||||
@ -99,7 +99,7 @@ const columns = computed(() => [
|
||||
{
|
||||
title: t("assetManagement.created_at"),
|
||||
key: "created_at",
|
||||
sort: true,
|
||||
// sort: true,
|
||||
},
|
||||
{
|
||||
title: t("assetManagement.operation"),
|
||||
|
@ -15,7 +15,7 @@ import useBuildingStore from "@/stores/useBuildingStore";
|
||||
|
||||
const { searchParams } = useSearchParam();
|
||||
const store = useBuildingStore();
|
||||
const hasSearched = ref(false);
|
||||
|
||||
const tableLoading = ref(false);
|
||||
const dataSource = ref([]);
|
||||
const model_data = ref({
|
||||
@ -25,6 +25,7 @@ const model_data = ref({
|
||||
|
||||
const editRecord = ref(null);
|
||||
|
||||
// -------- Modal: detail 映射與開啟 --------
|
||||
const updateEditRecord = (data) => {
|
||||
if (data?.lorf) {
|
||||
editRecord.value = {
|
||||
@ -63,25 +64,11 @@ const getAllOptions = async () => {
|
||||
);
|
||||
};
|
||||
|
||||
const search = async () => {
|
||||
tableLoading.value = true;
|
||||
if (Object.keys(searchParams.value).length !== 0) {
|
||||
const res = await getAlertLog({
|
||||
...searchParams.value,
|
||||
isRecovery: Number(searchParams.value.isRecovery),
|
||||
});
|
||||
dataSource.value = (res.data || []).map((d) => ({ ...d, key: d.id }));
|
||||
tableLoading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const openModal = async (record) => {
|
||||
try {
|
||||
if (record.formId) {
|
||||
const res = await getOperationEditRecord(record.formId);
|
||||
|
||||
// 統一從物件中抓可能的影片位址
|
||||
const pickVideo = (obj = {}) =>
|
||||
obj.video_url ?? obj.videoUrl ?? obj.video_path ?? obj.videoPath ?? "";
|
||||
|
||||
@ -92,59 +79,80 @@ const openModal = async (record) => {
|
||||
...res.data,
|
||||
uuid: res.data.error_code,
|
||||
device_number: record.device_number ?? res.data.device_number ?? "",
|
||||
|
||||
// 把影片欄位補齊(優先用詳細;沒有就用列表)
|
||||
...(videoFromDetail
|
||||
? { video_url: videoFromDetail }
|
||||
: videoFromRecord
|
||||
? { video_url: videoFromRecord }
|
||||
: {}),
|
||||
|
||||
video_path: res.data.video_path ?? record.video_path ?? undefined,
|
||||
videoUrl: res.data.videoUrl ?? record.videoUrl ?? undefined,
|
||||
videoPath: res.data.videoPath ?? record.videoPath ?? undefined,
|
||||
});
|
||||
} else {
|
||||
// 沒有 formId,直接把列表那筆 record(含 video_url)丟進去
|
||||
updateEditRecord({
|
||||
...record,
|
||||
uuid: record.id,
|
||||
});
|
||||
}
|
||||
|
||||
alert_action_item.showModal();
|
||||
} catch (error) {
|
||||
console.error("Error opening modal:", error);
|
||||
}
|
||||
};
|
||||
|
||||
// -------- 查詢 API --------
|
||||
const search = async () => {
|
||||
// 防呆:必要條件才打(避免 undefined 造成多餘請求)
|
||||
const params = searchParams.value || {};
|
||||
const ready =
|
||||
params.isRecovery !== undefined &&
|
||||
!!params.Start_date &&
|
||||
!!params.End_date &&
|
||||
!!params.device_name_tag;
|
||||
|
||||
if (!ready) return;
|
||||
|
||||
tableLoading.value = true;
|
||||
try {
|
||||
const res = await getAlertLog({
|
||||
...params,
|
||||
isRecovery: Number(params.isRecovery),
|
||||
});
|
||||
dataSource.value = (res.data || []).map((d) => ({ ...d, key: d.id }));
|
||||
} finally {
|
||||
tableLoading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// -------- 監聽條件 -> 立即搜尋(含 debounce)--------
|
||||
const autoSearchTimer = ref(null);
|
||||
const triggerAutoSearch = () => {
|
||||
if (autoSearchTimer.value) clearTimeout(autoSearchTimer.value);
|
||||
// 輕微 debounce,避免連動欄位連續觸發
|
||||
autoSearchTimer.value = setTimeout(() => {
|
||||
search();
|
||||
}, 250);
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
getAllOptions();
|
||||
});
|
||||
|
||||
// 只針對會影響查詢結果的關鍵欄位監聽
|
||||
watch(
|
||||
() => ({
|
||||
isRecovery: searchParams.value.isRecovery,
|
||||
Start_date: searchParams.value.Start_date,
|
||||
End_date: searchParams.value.End_date,
|
||||
device_name_tag: searchParams.value.device_name_tag,
|
||||
isRecovery: searchParams.value?.isRecovery,
|
||||
Start_date: searchParams.value?.Start_date,
|
||||
End_date: searchParams.value?.End_date,
|
||||
device_name_tag: searchParams.value?.device_name_tag,
|
||||
}),
|
||||
(val) => {
|
||||
// 判斷所有必要欄位都已經有值且是初始畫面未搜尋過
|
||||
if (
|
||||
val.isRecovery !== undefined &&
|
||||
val.Start_date &&
|
||||
val.End_date &&
|
||||
val.device_name_tag &&
|
||||
!hasSearched.value
|
||||
) {
|
||||
hasSearched.value = true;
|
||||
search();
|
||||
}
|
||||
() => {
|
||||
triggerAutoSearch();
|
||||
},
|
||||
{ immediate: true, deep: true }
|
||||
);
|
||||
|
||||
// -------- 對外提供 --------
|
||||
provide("alert_modal", { model_data, search, updateEditRecord });
|
||||
provide("alert_table", {
|
||||
openModal,
|
||||
|
@ -5,19 +5,15 @@ import AlertSearchTimeRange from "./AlertSearchTimeRange.vue";
|
||||
import AlertSearchTypesButton from "./AlertSearchTypesButton.vue";
|
||||
|
||||
const { search } = inject("alert_table");
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="w-full flex flex-wrap flex-col custom-border px-4 pt-0 pb-4 mb-4">
|
||||
<div class="w-full flex flex-wrap items-center justify-start gap-4 mt-4 lg:mt-0">
|
||||
<div
|
||||
class="w-full flex flex-wrap items-center justify-start gap-4 mt-4 lg:mt-0"
|
||||
>
|
||||
<AlertSearchNormalBtns />
|
||||
<!-- <AlertSearchAckBtns /> -->
|
||||
<AlertSearchTimeRange />
|
||||
<button class="btn btn-search lg:ml-8" @click.stop.prevent="search">
|
||||
<font-awesome-icon :icon="['fas', 'search']" class=" text-lg" />
|
||||
{{ $t("button.search")}}
|
||||
</button>
|
||||
</div>
|
||||
<div class="w-full flex flex-wrap items-center justify-start">
|
||||
<AlertSearchTypesButton />
|
||||
|
@ -1,63 +0,0 @@
|
||||
<script setup>
|
||||
import { onMounted, watch } from "vue";
|
||||
import useActiveBtn from "@/hooks/useActiveBtn";
|
||||
import useSearchParam from "@/hooks/useSearchParam";
|
||||
import { useI18n } from "vue-i18n";
|
||||
const { t, locale } = useI18n();
|
||||
const { searchParams, changeParams } = useSearchParam();
|
||||
const {
|
||||
items,
|
||||
changeActiveBtn,
|
||||
setItems,
|
||||
selectedBtn
|
||||
} = useActiveBtn();
|
||||
|
||||
const initializeItems = () => {
|
||||
setItems([
|
||||
{
|
||||
title: t("alert.unacked"),
|
||||
key: "unacked",
|
||||
active: true,
|
||||
},
|
||||
{
|
||||
title: t("alert.acked"),
|
||||
key: "acked",
|
||||
active: false,
|
||||
},
|
||||
]);
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
initializeItems();
|
||||
});
|
||||
|
||||
watch(locale, () => {
|
||||
initializeItems();
|
||||
});
|
||||
|
||||
watch(
|
||||
selectedBtn,
|
||||
(newValue) => {
|
||||
changeParams({ ...searchParams.value, isAck: newValue.key });
|
||||
},
|
||||
);
|
||||
|
||||
// 監聽搜尋變化
|
||||
watch(
|
||||
searchParams,
|
||||
(newSearchParams) => {
|
||||
if (!newSearchParams.isAck) {
|
||||
changeParams({ ...newSearchParams, isAck: "unacked" });
|
||||
}
|
||||
},
|
||||
{ immediate: true } // 確保在初始化立即觸發
|
||||
);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ButtonGroup :items="items" :withLine="true" class="mr-5" :onclick="(e, item) => {
|
||||
changeActiveBtn(item);
|
||||
}" />
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped></style>
|
@ -3,22 +3,14 @@ import useActiveBtn from "@/hooks/useActiveBtn";
|
||||
import { onMounted, watch } from "vue";
|
||||
import useSearchParam from "@/hooks/useSearchParam";
|
||||
import { useI18n } from "vue-i18n";
|
||||
const { t, locale } = useI18n();
|
||||
const { t } = useI18n();
|
||||
const { searchParams, changeParams } = useSearchParam();
|
||||
const { items, changeActiveBtn, setItems, selectedBtn } = useActiveBtn();
|
||||
|
||||
const initializeItems = () => {
|
||||
setItems([
|
||||
{
|
||||
title: t("alert.offnormal"),
|
||||
key: 1,
|
||||
active: true,
|
||||
},
|
||||
{
|
||||
title: t("alert.normal"),
|
||||
key: 2,
|
||||
active: false,
|
||||
},
|
||||
{ title: t("alert.offnormal"), key: 1, active: true }, // 異常(未恢復)
|
||||
{ title: t("alert.normal"), key: 2, active: false }, // 正常(已恢復)
|
||||
]);
|
||||
};
|
||||
|
||||
@ -26,23 +18,24 @@ onMounted(() => {
|
||||
initializeItems();
|
||||
});
|
||||
|
||||
// 監聽按鈕變化
|
||||
// 點擊 tab → 直接寫回 isRecovery;父層會偵測變更自動查詢
|
||||
watch(
|
||||
selectedBtn,
|
||||
(newValue) => {
|
||||
if (!newValue?.key) return;
|
||||
changeParams({ ...searchParams.value, isRecovery: newValue.key });
|
||||
}
|
||||
);
|
||||
|
||||
// 監聽搜尋變化
|
||||
// 初始化若缺 isRecovery,補預設 1,避免父層條件不齊
|
||||
watch(
|
||||
searchParams,
|
||||
(newSearchParams) => {
|
||||
if (!newSearchParams.isRecovery) {
|
||||
changeParams({ ...newSearchParams, isRecovery: 1 });
|
||||
(sp) => {
|
||||
if (!sp.isRecovery) {
|
||||
changeParams({ ...sp, isRecovery: 1 });
|
||||
}
|
||||
},
|
||||
{ immediate: true } // 確保在初始化立即觸發
|
||||
{ immediate: true }
|
||||
);
|
||||
</script>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user