fix: 調整告警紀錄查 UIUX,直接透過復歸 tabs 顯示資料,移除搜尋按鈕
This commit is contained in:
parent
3750e3c124
commit
feac20d519
@ -57,7 +57,7 @@ const columns = computed(() => [
|
|||||||
{
|
{
|
||||||
title: t("assetManagement.device_name"),
|
title: t("assetManagement.device_name"),
|
||||||
key: "full_name",
|
key: "full_name",
|
||||||
filter: true,
|
// filter: true,
|
||||||
class: "break-all",
|
class: "break-all",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -67,13 +67,13 @@ const columns = computed(() => [
|
|||||||
{
|
{
|
||||||
title: t("assetManagement.floor"),
|
title: t("assetManagement.floor"),
|
||||||
key: "floor",
|
key: "floor",
|
||||||
filter: true,
|
// filter: true,
|
||||||
sort: true,
|
// sort: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t("assetManagement.department"),
|
title: t("assetManagement.department"),
|
||||||
key: "department",
|
key: "department",
|
||||||
filter: true,
|
// filter: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t("assetManagement.device_coordinate"),
|
title: t("assetManagement.device_coordinate"),
|
||||||
@ -90,7 +90,7 @@ const columns = computed(() => [
|
|||||||
{
|
{
|
||||||
title: t("assetManagement.buying_date"),
|
title: t("assetManagement.buying_date"),
|
||||||
key: "buying_date",
|
key: "buying_date",
|
||||||
sort: true,
|
// sort: true,
|
||||||
},
|
},
|
||||||
// {
|
// {
|
||||||
// title: t("assetManagement.oriFile"),
|
// title: t("assetManagement.oriFile"),
|
||||||
@ -99,7 +99,7 @@ const columns = computed(() => [
|
|||||||
{
|
{
|
||||||
title: t("assetManagement.created_at"),
|
title: t("assetManagement.created_at"),
|
||||||
key: "created_at",
|
key: "created_at",
|
||||||
sort: true,
|
// sort: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t("assetManagement.operation"),
|
title: t("assetManagement.operation"),
|
||||||
|
@ -15,7 +15,7 @@ import useBuildingStore from "@/stores/useBuildingStore";
|
|||||||
|
|
||||||
const { searchParams } = useSearchParam();
|
const { searchParams } = useSearchParam();
|
||||||
const store = useBuildingStore();
|
const store = useBuildingStore();
|
||||||
const hasSearched = ref(false);
|
|
||||||
const tableLoading = ref(false);
|
const tableLoading = ref(false);
|
||||||
const dataSource = ref([]);
|
const dataSource = ref([]);
|
||||||
const model_data = ref({
|
const model_data = ref({
|
||||||
@ -25,6 +25,7 @@ const model_data = ref({
|
|||||||
|
|
||||||
const editRecord = ref(null);
|
const editRecord = ref(null);
|
||||||
|
|
||||||
|
// -------- Modal: detail 映射與開啟 --------
|
||||||
const updateEditRecord = (data) => {
|
const updateEditRecord = (data) => {
|
||||||
if (data?.lorf) {
|
if (data?.lorf) {
|
||||||
editRecord.value = {
|
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) => {
|
const openModal = async (record) => {
|
||||||
try {
|
try {
|
||||||
if (record.formId) {
|
if (record.formId) {
|
||||||
const res = await getOperationEditRecord(record.formId);
|
const res = await getOperationEditRecord(record.formId);
|
||||||
|
|
||||||
// 統一從物件中抓可能的影片位址
|
|
||||||
const pickVideo = (obj = {}) =>
|
const pickVideo = (obj = {}) =>
|
||||||
obj.video_url ?? obj.videoUrl ?? obj.video_path ?? obj.videoPath ?? "";
|
obj.video_url ?? obj.videoUrl ?? obj.video_path ?? obj.videoPath ?? "";
|
||||||
|
|
||||||
@ -92,59 +79,80 @@ const openModal = async (record) => {
|
|||||||
...res.data,
|
...res.data,
|
||||||
uuid: res.data.error_code,
|
uuid: res.data.error_code,
|
||||||
device_number: record.device_number ?? res.data.device_number ?? "",
|
device_number: record.device_number ?? res.data.device_number ?? "",
|
||||||
|
|
||||||
// 把影片欄位補齊(優先用詳細;沒有就用列表)
|
|
||||||
...(videoFromDetail
|
...(videoFromDetail
|
||||||
? { video_url: videoFromDetail }
|
? { video_url: videoFromDetail }
|
||||||
: videoFromRecord
|
: videoFromRecord
|
||||||
? { video_url: videoFromRecord }
|
? { video_url: videoFromRecord }
|
||||||
: {}),
|
: {}),
|
||||||
|
|
||||||
video_path: res.data.video_path ?? record.video_path ?? undefined,
|
video_path: res.data.video_path ?? record.video_path ?? undefined,
|
||||||
videoUrl: res.data.videoUrl ?? record.videoUrl ?? undefined,
|
videoUrl: res.data.videoUrl ?? record.videoUrl ?? undefined,
|
||||||
videoPath: res.data.videoPath ?? record.videoPath ?? undefined,
|
videoPath: res.data.videoPath ?? record.videoPath ?? undefined,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// 沒有 formId,直接把列表那筆 record(含 video_url)丟進去
|
|
||||||
updateEditRecord({
|
updateEditRecord({
|
||||||
...record,
|
...record,
|
||||||
uuid: record.id,
|
uuid: record.id,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
alert_action_item.showModal();
|
alert_action_item.showModal();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error opening modal:", 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(() => {
|
onMounted(() => {
|
||||||
getAllOptions();
|
getAllOptions();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 只針對會影響查詢結果的關鍵欄位監聽
|
||||||
watch(
|
watch(
|
||||||
() => ({
|
() => ({
|
||||||
isRecovery: searchParams.value.isRecovery,
|
isRecovery: searchParams.value?.isRecovery,
|
||||||
Start_date: searchParams.value.Start_date,
|
Start_date: searchParams.value?.Start_date,
|
||||||
End_date: searchParams.value.End_date,
|
End_date: searchParams.value?.End_date,
|
||||||
device_name_tag: searchParams.value.device_name_tag,
|
device_name_tag: searchParams.value?.device_name_tag,
|
||||||
}),
|
}),
|
||||||
(val) => {
|
() => {
|
||||||
// 判斷所有必要欄位都已經有值且是初始畫面未搜尋過
|
triggerAutoSearch();
|
||||||
if (
|
|
||||||
val.isRecovery !== undefined &&
|
|
||||||
val.Start_date &&
|
|
||||||
val.End_date &&
|
|
||||||
val.device_name_tag &&
|
|
||||||
!hasSearched.value
|
|
||||||
) {
|
|
||||||
hasSearched.value = true;
|
|
||||||
search();
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{ immediate: true, deep: true }
|
{ immediate: true, deep: true }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// -------- 對外提供 --------
|
||||||
provide("alert_modal", { model_data, search, updateEditRecord });
|
provide("alert_modal", { model_data, search, updateEditRecord });
|
||||||
provide("alert_table", {
|
provide("alert_table", {
|
||||||
openModal,
|
openModal,
|
||||||
|
@ -5,19 +5,15 @@ import AlertSearchTimeRange from "./AlertSearchTimeRange.vue";
|
|||||||
import AlertSearchTypesButton from "./AlertSearchTypesButton.vue";
|
import AlertSearchTypesButton from "./AlertSearchTypesButton.vue";
|
||||||
|
|
||||||
const { search } = inject("alert_table");
|
const { search } = inject("alert_table");
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<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 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 />
|
<AlertSearchNormalBtns />
|
||||||
<!-- <AlertSearchAckBtns /> -->
|
|
||||||
<AlertSearchTimeRange />
|
<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>
|
||||||
<div class="w-full flex flex-wrap items-center justify-start">
|
<div class="w-full flex flex-wrap items-center justify-start">
|
||||||
<AlertSearchTypesButton />
|
<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 { onMounted, watch } from "vue";
|
||||||
import useSearchParam from "@/hooks/useSearchParam";
|
import useSearchParam from "@/hooks/useSearchParam";
|
||||||
import { useI18n } from "vue-i18n";
|
import { useI18n } from "vue-i18n";
|
||||||
const { t, locale } = useI18n();
|
const { t } = useI18n();
|
||||||
const { searchParams, changeParams } = useSearchParam();
|
const { searchParams, changeParams } = useSearchParam();
|
||||||
const { items, changeActiveBtn, setItems, selectedBtn } = useActiveBtn();
|
const { items, changeActiveBtn, setItems, selectedBtn } = useActiveBtn();
|
||||||
|
|
||||||
const initializeItems = () => {
|
const initializeItems = () => {
|
||||||
setItems([
|
setItems([
|
||||||
{
|
{ title: t("alert.offnormal"), key: 1, active: true }, // 異常(未恢復)
|
||||||
title: t("alert.offnormal"),
|
{ title: t("alert.normal"), key: 2, active: false }, // 正常(已恢復)
|
||||||
key: 1,
|
|
||||||
active: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: t("alert.normal"),
|
|
||||||
key: 2,
|
|
||||||
active: false,
|
|
||||||
},
|
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -26,23 +18,24 @@ onMounted(() => {
|
|||||||
initializeItems();
|
initializeItems();
|
||||||
});
|
});
|
||||||
|
|
||||||
// 監聽按鈕變化
|
// 點擊 tab → 直接寫回 isRecovery;父層會偵測變更自動查詢
|
||||||
watch(
|
watch(
|
||||||
selectedBtn,
|
selectedBtn,
|
||||||
(newValue) => {
|
(newValue) => {
|
||||||
|
if (!newValue?.key) return;
|
||||||
changeParams({ ...searchParams.value, isRecovery: newValue.key });
|
changeParams({ ...searchParams.value, isRecovery: newValue.key });
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
// 監聽搜尋變化
|
// 初始化若缺 isRecovery,補預設 1,避免父層條件不齊
|
||||||
watch(
|
watch(
|
||||||
searchParams,
|
searchParams,
|
||||||
(newSearchParams) => {
|
(sp) => {
|
||||||
if (!newSearchParams.isRecovery) {
|
if (!sp.isRecovery) {
|
||||||
changeParams({ ...newSearchParams, isRecovery: 1 });
|
changeParams({ ...sp, isRecovery: 1 });
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ immediate: true } // 確保在初始化立即觸發
|
{ immediate: true }
|
||||||
);
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user