告警頁面
This commit is contained in:
parent
502b4f3778
commit
b55ba4003d
@ -1,5 +1,6 @@
|
||||
export const POST_ACK_API = `/obix/alarm`;
|
||||
export const GET_ALERT_FORMID_API = `/Alert/AlertList`;
|
||||
export const GET_ALERT_LOG_API = `api/Alarm/GetAlarmLog`;
|
||||
export const POST_OPERATION_RECORD_API = `/operation/SavOpeRecord`;
|
||||
|
||||
export const GET_ALERT_SUB_LIST_API = `api/Device/GetMainSub`;
|
||||
@ -9,6 +10,7 @@ export const GET_ALERT_MEMBER = `api/Alarm/GetAlarmMember`;
|
||||
export const POST_ALERT_MEMBER = `api/Alarm/SaveAlarmMember`;
|
||||
export const DELETE_ALERT_MEMBER = `api/Alarm/DeleteAlarmMember`;
|
||||
export const GET_NOTICE_LIST_API = `api/Alarm/GetNotice`;
|
||||
export const GET_SHOW_ALERT_API = `api/Alarm/GetShowAlarm`; // 取得告警顯示清單
|
||||
|
||||
export const GET_OUTLIERS_LIST_API = `api/Alarm/GetAlarmSetting`;
|
||||
export const GET_OUTLIERS_DEVLIST_API = `api/Alarm/GetDevList`; // 取得設備
|
||||
@ -20,3 +22,5 @@ export const GET_FACTOR_API = `api/Alarm/GetFactor`; // 刪除
|
||||
export const GET_ALERT_SCHEDULE_LIST_API = `api/Alarm/GetAlarmSchedule`;
|
||||
export const POST_ALERT_SCHEDULE = `api/Alarm/SaveAlarmSchedule`;
|
||||
export const DELETE_ALERT_SCHEDULE = `api/Alarm/DeleteAlarmSchedule`;
|
||||
|
||||
export const POST_ALERT_MQTT_REFRESH = `api/Alarm/MQTTRefresh`;
|
@ -1,6 +1,7 @@
|
||||
import {
|
||||
POST_ACK_API,
|
||||
GET_ALERT_FORMID_API,
|
||||
GET_ALERT_LOG_API,
|
||||
POST_OPERATION_RECORD_API,
|
||||
GET_ALERT_SUB_LIST_API,
|
||||
GET_OUTLIERS_LIST_API,
|
||||
@ -14,40 +15,14 @@ import {
|
||||
POST_ALERT_MEMBER,
|
||||
DELETE_ALERT_MEMBER,
|
||||
GET_NOTICE_LIST_API,
|
||||
GET_SHOW_ALERT_API,
|
||||
GET_ALERT_SCHEDULE_LIST_API,
|
||||
POST_ALERT_SCHEDULE,
|
||||
DELETE_ALERT_SCHEDULE,
|
||||
POST_ALERT_MQTT_REFRESH
|
||||
} from "./api";
|
||||
import instance from "@/util/request";
|
||||
import apihandler from "@/util/apihandler";
|
||||
import axios from "axios";
|
||||
|
||||
export const postChgAck = async (uuid) => {
|
||||
try {
|
||||
const data =
|
||||
'<obj is="obix:AckAlarmIn"><str name="ackUser" val="obix" /></obj>';
|
||||
const res = await axios.post(`${POST_ACK_API}/${uuid}/ack`, data, {
|
||||
headers: {
|
||||
"Content-Type": "text/plain",
|
||||
},
|
||||
});
|
||||
|
||||
// 解析XML錯誤信息
|
||||
const parser = new DOMParser();
|
||||
const xmlDoc = parser.parseFromString(res.data, "text/xml");
|
||||
const errElement = xmlDoc.querySelector("err");
|
||||
|
||||
if (errElement) {
|
||||
console.error("Error in acknowledging alarm");
|
||||
return { isSuccess: false, msg: `Error in acknowledging alarm` };
|
||||
}
|
||||
|
||||
return { isSuccess: true };
|
||||
} catch (error) {
|
||||
console.error("Error in acknowledging alarm:", error);
|
||||
return { isSuccess: false, msg: "Error in acknowledging alarm" };
|
||||
}
|
||||
};
|
||||
|
||||
export const getAlertFormId = async (uuid) => {
|
||||
const res = await instance.post(GET_ALERT_FORMID_API, uuid);
|
||||
@ -57,6 +32,24 @@ export const getAlertFormId = async (uuid) => {
|
||||
});
|
||||
};
|
||||
|
||||
export const getAlertLog = async ({
|
||||
Start_date,
|
||||
End_date,
|
||||
isRecovery,
|
||||
device_name_tag,
|
||||
}) => {
|
||||
const res = await instance.post(GET_ALERT_LOG_API, {
|
||||
Start_date,
|
||||
End_date,
|
||||
isRecovery,
|
||||
device_name_tag,
|
||||
});
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const postOperationRecord = async (formData) => {
|
||||
const res = await instance.post(POST_OPERATION_RECORD_API, formData);
|
||||
|
||||
@ -66,11 +59,9 @@ export const postOperationRecord = async (formData) => {
|
||||
});
|
||||
};
|
||||
|
||||
export const getAlertSubList = async (
|
||||
building_guid
|
||||
) => {
|
||||
export const getAlertSubList = async (building_guid) => {
|
||||
const res = await instance.post(GET_ALERT_SUB_LIST_API, {
|
||||
building_guid
|
||||
building_guid,
|
||||
});
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
@ -186,6 +177,15 @@ export const delOutliersSetting = async (Id) => {
|
||||
});
|
||||
};
|
||||
|
||||
export const getShowAlarm = async () => {
|
||||
const res = await instance.post(GET_SHOW_ALERT_API);
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const getAlarmScheduleList = async () => {
|
||||
const res = await instance.post(GET_ALERT_SCHEDULE_LIST_API, {});
|
||||
|
||||
@ -216,3 +216,12 @@ export const deleteAlarmSchedule = async (id) => {
|
||||
return { isSuccess: false, msg: "API request failed" };
|
||||
}
|
||||
};
|
||||
|
||||
export const postMQTTRefresh = async () => {
|
||||
const res = await instance.post(POST_ALERT_MQTT_REFRESH);
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
@ -1,25 +1,41 @@
|
||||
<script setup>
|
||||
import { onMounted } from "vue";
|
||||
import useAlarmStore from "@/stores/useAlarmStore";
|
||||
import { ackSingleAlarm } from "@/apis/building";
|
||||
import { ref, onMounted, onUnmounted } from "vue";
|
||||
import { getAlertLog } from "@/apis/alert";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
const store = useAlarmStore();
|
||||
const dataSource = ref([]);
|
||||
let intervalId = null; // 用來儲存 setInterval 的 ID
|
||||
|
||||
const getAlarmData = async () => {
|
||||
const res = await getAlertLog({
|
||||
isRecovery: 1,
|
||||
Start_date: dayjs().format("YYYY-MM-DD"),
|
||||
End_date: dayjs().format("YYYY-MM-DD"),
|
||||
});
|
||||
dataSource.value = (res.data || []).map((d) => ({ ...d, key: d.id }));
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
store.getAlarmDataFromBaja();
|
||||
getAlarmData();
|
||||
|
||||
intervalId = setInterval(() => {
|
||||
getAlarmData();
|
||||
}, 30 * 1000);
|
||||
});
|
||||
|
||||
const ackedAlarm = async (uuid) => {
|
||||
const res = await ackSingleAlarm(uuid);
|
||||
console.log("ackedAlarm", res);
|
||||
};
|
||||
onUnmounted(() => {
|
||||
if (intervalId) {
|
||||
clearInterval(intervalId);
|
||||
intervalId = null;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<ul class="pr-4 min-h-full text-base-content">
|
||||
<!-- Sidebar content here -->
|
||||
<li class="my-3" v-for="alarm in store.alarmData" :key="alarm.uuid">
|
||||
<li class="my-3" v-for="alarm in dataSource" :key="alarm.id">
|
||||
<div
|
||||
class="w-full shadow-xl border border-success bg-body bg-opacity-80"
|
||||
>
|
||||
@ -34,30 +50,22 @@ const ackedAlarm = async (uuid) => {
|
||||
>
|
||||
<small>
|
||||
<span class="mr-4"
|
||||
>{{ alarm.timestamp_date }} {{ alarm.timestamp_time }}</span
|
||||
>{{ alarm.created_at }}</span
|
||||
>
|
||||
<font-awesome-icon
|
||||
<!-- <font-awesome-icon
|
||||
:icon="['fas', 'times']"
|
||||
size="lg"
|
||||
class="text-white"
|
||||
/>
|
||||
/> -->
|
||||
</small>
|
||||
</p>
|
||||
<div class="divider my-2"></div>
|
||||
<div>
|
||||
<p>{{ $t("alarm.number") }}:{{ alarm.uuid }}</p>
|
||||
<!-- <p>異常等級:255</p> -->
|
||||
<p>{{ $t("alarm.category") }}:{{ alarm.alarmClass }}</p>
|
||||
<p>{{ $t("alarm.device_name") }}:{{ alarm.full_name }}</p>
|
||||
<p>{{ $t("alarm.message") }}:{{ alarm.msg }}</p>
|
||||
</div>
|
||||
<div class="card-actions mt-1 justify-end">
|
||||
<button
|
||||
class="btn btn-sm btn-success"
|
||||
@click="() => ackedAlarm(alarm.uuid)"
|
||||
>
|
||||
{{ $t("alarm.confirm") }}
|
||||
</button>
|
||||
<p>{{ $t("alarm.number") }}:{{ alarm.id }}</p>
|
||||
<p>{{ $t("alert.alarmClass") }}:{{ alarm.factor }}</p>
|
||||
<p>{{ $t("alarm.device_name") }}:{{ alarm.device_number }}</p>
|
||||
<p>{{ $t("alert.device_point_name") }}:{{ alarm.points }}</p>
|
||||
<p>{{ $t("alert.error_msg") }}:{{ alarm.reason }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<script setup>
|
||||
import { defineProps, ref, computed, watch } from "vue";
|
||||
import { defineProps, ref, computed, watch, nextTick, watchEffect } from "vue";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
/* --------------------------------------------------------------
|
||||
options: [
|
||||
@ -68,14 +68,12 @@ const selectOption = (value) => {
|
||||
isOpen.value = false;
|
||||
};
|
||||
|
||||
watch(
|
||||
() => props.value[props.name],
|
||||
(newKey) => {
|
||||
watchEffect(() => {
|
||||
isOpen.value = false;
|
||||
selectedOption.value = props.options.find((option) => option.key == newKey);
|
||||
},
|
||||
{ immediate: true }
|
||||
selectedOption.value = props.options.find(
|
||||
(option) => option.key == props.value[props.name]
|
||||
);
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@ -88,7 +86,7 @@ watch(
|
||||
<div
|
||||
:class="
|
||||
twMerge(
|
||||
'select rounded-md text-lg cursor-pointer h-fit',
|
||||
'select rounded-md text-lg cursor-pointer pt-2',
|
||||
disabled ? 'text-gray-300' : 'bg-transparent border-info'
|
||||
)
|
||||
"
|
||||
|
@ -153,7 +153,7 @@
|
||||
"alarm": {
|
||||
"title": "显示警告",
|
||||
"notify": "异常通知",
|
||||
"number": "异常编号",
|
||||
"number": "异常ID",
|
||||
"category": "异常类别",
|
||||
"device_name": "设备名称",
|
||||
"message": "异常讯息",
|
||||
@ -171,9 +171,10 @@
|
||||
"end_date": "结束日期",
|
||||
"building_and_floor": "栋别-楼层",
|
||||
"uuid": "异常ID",
|
||||
"alarmClass": "异常类别",
|
||||
"alarmClass": "告警条件",
|
||||
"device_name": "设备名称",
|
||||
"device_number": "设备编号",
|
||||
"device_point_name":"点位名称",
|
||||
"date": "发生日期",
|
||||
"time": "发生时间",
|
||||
"error_msg": "异常原因",
|
||||
@ -229,7 +230,8 @@
|
||||
"friday": "星期五",
|
||||
"saturday": "星期六",
|
||||
"schedule_name": "时段名称",
|
||||
"schedule_content": "时段内容"
|
||||
"schedule_content": "时段内容",
|
||||
"reorganization": "MQTT 告警重整"
|
||||
},
|
||||
"operation": {
|
||||
"title": "运维管理",
|
||||
@ -384,7 +386,8 @@
|
||||
"sure_to_delete": "是否确认删除该项目?",
|
||||
"sure_to_delete_permanent": "是否确认永久删除该项目?",
|
||||
"delete_success": "删除成功",
|
||||
"delete_failed": "删除失败"
|
||||
"delete_failed": "删除失败",
|
||||
"mqtt_refresh":"重新设定成功"
|
||||
},
|
||||
"setting": {
|
||||
"MQTT_parse": "MQTT 解析",
|
||||
|
@ -153,7 +153,7 @@
|
||||
"alarm": {
|
||||
"title": "顯示警告",
|
||||
"notify": "異常通知",
|
||||
"number": "異常編號",
|
||||
"number": "異常ID",
|
||||
"category": "異常類別",
|
||||
"device_name": "設備名稱",
|
||||
"message": "異常訊息",
|
||||
@ -171,9 +171,10 @@
|
||||
"end_date": "結束日期",
|
||||
"building_and_floor": "棟別-樓層",
|
||||
"uuid": "異常ID",
|
||||
"alarmClass": "異常類別",
|
||||
"alarmClass": "告警條件",
|
||||
"device_name": "設備名稱",
|
||||
"device_number": "設備編號",
|
||||
"device_point_name":"點位名稱",
|
||||
"date": "發生日期",
|
||||
"time": "發生時間",
|
||||
"error_msg": "異常原因",
|
||||
@ -229,7 +230,8 @@
|
||||
"friday": "星期五",
|
||||
"saturday": "星期六",
|
||||
"schedule_name": "時段名稱",
|
||||
"schedule_content": "時段內容"
|
||||
"schedule_content": "時段內容",
|
||||
"reorganization": "MQTT 告警重整"
|
||||
},
|
||||
"operation": {
|
||||
"title": "運維管理",
|
||||
@ -384,7 +386,8 @@
|
||||
"sure_to_delete": "是否確認刪除該項目?",
|
||||
"sure_to_delete_permanent": "是否確認永久刪除該項目?",
|
||||
"delete_success": "刪除成功",
|
||||
"delete_failed": "刪除失敗"
|
||||
"delete_failed": "刪除失敗",
|
||||
"mqtt_refresh":"重新設定成功"
|
||||
},
|
||||
"setting": {
|
||||
"MQTT_parse": "MQTT 解析",
|
||||
|
@ -171,9 +171,10 @@
|
||||
"end_date": "End Date",
|
||||
"building_and_floor": "Building - Floor",
|
||||
"uuid": "Exception ID",
|
||||
"alarmClass": "Exception Category",
|
||||
"alarmClass": "Alarm Conditions",
|
||||
"device_name": "Device Name",
|
||||
"device_number": "Device Number",
|
||||
"device_point_name":"Point Name",
|
||||
"date": "Occurrence Date",
|
||||
"time": "Occurrence Time",
|
||||
"error_msg": "Abnormal Cause",
|
||||
@ -229,7 +230,8 @@
|
||||
"friday": "Friday",
|
||||
"saturday": "Saturday",
|
||||
"schedule_name": "Time period name",
|
||||
"schedule_content": "Time period content"
|
||||
"schedule_content": "Time period content",
|
||||
"reorganization": "MQTT Alarm Reorganization"
|
||||
},
|
||||
"operation": {
|
||||
"title": "Operation And Maintenance Management",
|
||||
@ -384,7 +386,8 @@
|
||||
"sure_to_delete": "Are you sure to delete this item?",
|
||||
"sure_to_delete_permanent": "Are you sure you want to permanently delete this item?",
|
||||
"delete_success": "Delete successfully",
|
||||
"delete_failed": "Delete failed"
|
||||
"delete_failed": "Delete failed",
|
||||
"mqtt_refresh":"MQTT reset successful"
|
||||
},
|
||||
"setting": {
|
||||
"MQTT_parse": "MQTT Parse",
|
||||
|
@ -4,8 +4,7 @@ import AlertTable from "./AlertTable.vue";
|
||||
import AlertTableModal from "./AlertTableModal.vue";
|
||||
import { ref, provide, onMounted } from "vue";
|
||||
import useSearchParam from "@/hooks/useSearchParam";
|
||||
import useAlarmData from "@/hooks/baja/useAlarmData";
|
||||
import { getAlertFormId } from "@/apis/alert";
|
||||
import { getAlertLog } from "@/apis/alert";
|
||||
import {
|
||||
getOperationDeviceList,
|
||||
getOperationCompanyList,
|
||||
@ -13,18 +12,14 @@ import {
|
||||
} from "@/apis/operation";
|
||||
import { getAccountUserList } from "@/apis/account";
|
||||
import useBuildingStore from "@/stores/useBuildingStore";
|
||||
import useAlarmStore from "@/stores/useAlarmStore";
|
||||
const storeAlarm = useAlarmStore();
|
||||
|
||||
const { searchParams } = useSearchParam();
|
||||
const { getAlarmByBaja, alarmData } = useAlarmData();
|
||||
const store = useBuildingStore();
|
||||
|
||||
const tableLoading = ref(false);
|
||||
const dataSource = ref([]);
|
||||
const model_data = ref({
|
||||
model_userList: [],
|
||||
model_devList: [],
|
||||
model_companyList: [],
|
||||
});
|
||||
|
||||
@ -49,23 +44,6 @@ const updateEditRecord = (data) => {
|
||||
}
|
||||
};
|
||||
|
||||
const getFormId = async (uuid) => {
|
||||
const res = await getAlertFormId(uuid);
|
||||
return res.data;
|
||||
};
|
||||
|
||||
const getModalDevList = async () => {
|
||||
const sub_system_tags = searchParams.value.system_tag.map(
|
||||
(tag) => tag.split("_")[1]
|
||||
);
|
||||
const res = await getOperationDeviceList({
|
||||
list_sub_system_tag: sub_system_tags,
|
||||
device_building_tag: store.buildings[0].building_tag,
|
||||
device_area_tag: "NTPC",
|
||||
});
|
||||
return res.data.map((d) => ({ ...d, key: d.device_number }));
|
||||
};
|
||||
|
||||
const getModalUserList = async () => {
|
||||
const res = await getAccountUserList({});
|
||||
return res.data.map((d) => ({ ...d, key: d.userinfo_guid }));
|
||||
@ -77,75 +55,41 @@ const getModalCompanyList = async () => {
|
||||
};
|
||||
|
||||
const getAllOptions = async () => {
|
||||
Promise.all([
|
||||
getModalDevList(),
|
||||
getModalUserList(),
|
||||
getModalCompanyList(),
|
||||
]).then(([devices, users, companies]) => {
|
||||
Promise.all([getModalUserList(), getModalCompanyList()]).then(
|
||||
([users, companies]) => {
|
||||
model_data.value.model_userList = users;
|
||||
model_data.value.model_devList = devices;
|
||||
model_data.value.model_companyList = companies;
|
||||
});
|
||||
};
|
||||
|
||||
const updateDataSource = (data) => {
|
||||
dataSource.value = (data || []).map((d) => ({ ...d, key: d.uuid }));
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
const search = async () => {
|
||||
tableLoading.value = true;
|
||||
if (Object.keys(searchParams.value).length !== 0) {
|
||||
storeAlarm.getAlarmDataFromBaja();
|
||||
updateDataSource(storeAlarm.alarmData);
|
||||
tableLoading.value = false;
|
||||
/*
|
||||
await getAlarmByBaja(
|
||||
searchParams.value.start_created_at,
|
||||
searchParams.value.end_created_at,
|
||||
searchParams.value.isRecover,
|
||||
searchParams.value.isAck,
|
||||
searchParams.value.system_tag,
|
||||
async (result) => {
|
||||
alarmData.value = result.data;
|
||||
// 確保所有 alarm 都包含 formId
|
||||
alarmData.value = alarmData.value.map((alarm) => ({
|
||||
...alarm,
|
||||
formId: null, // 初始設置 formId 為 null
|
||||
}));
|
||||
|
||||
const uuids = alarmData.value.map((alarm) => ({ uuid: alarm.uuid }));
|
||||
const formIds = await getFormId(uuids);
|
||||
|
||||
if (Array.isArray(formIds)) {
|
||||
formIds.forEach((form) => {
|
||||
if (form && form.uuid) {
|
||||
const index = alarmData.value.findIndex(
|
||||
(alarm) => alarm.uuid === form.uuid
|
||||
);
|
||||
if (index !== -1) {
|
||||
alarmData.value[index].formId = form.formId || null;
|
||||
}
|
||||
}
|
||||
const res = await getAlertLog({
|
||||
...searchParams.value,
|
||||
isRecovery: Number(searchParams.value.isRecovery),
|
||||
});
|
||||
}
|
||||
|
||||
updateDataSource(alarmData.value);
|
||||
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);
|
||||
updateEditRecord({ ...res.data, uuid: record.uuid });
|
||||
updateEditRecord({
|
||||
...res.data,
|
||||
uuid: res.data.error_code,
|
||||
device_number: record.device_number
|
||||
});
|
||||
} else {
|
||||
updateEditRecord(record);
|
||||
updateEditRecord({
|
||||
...record,
|
||||
uuid: record.id,
|
||||
});
|
||||
}
|
||||
await getAllOptions();
|
||||
alert_action_item.showModal();
|
||||
} catch (error) {
|
||||
console.error("Error opening modal:", error);
|
||||
@ -153,6 +97,7 @@ const openModal = async (record) => {
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
getAllOptions();
|
||||
if (Object.keys(searchParams.value).length !== 0) {
|
||||
search();
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
<script setup>
|
||||
import { inject } from "vue";
|
||||
import AlertSearchNormalBtns from "./AlertSearchNormalBtns.vue";
|
||||
import AlertSearchAckBtns from "./AlertSearchAckBtns.vue";
|
||||
import AlertSearchTimeRange from "./AlertSearchTimeRange.vue";
|
||||
import AlertSearchTypesButton from "./AlertSearchTypesButton.vue";
|
||||
|
||||
@ -13,7 +12,7 @@ const { search } = inject("alert_table");
|
||||
<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">
|
||||
<AlertSearchNormalBtns />
|
||||
<AlertSearchAckBtns />
|
||||
<!-- <AlertSearchAckBtns /> -->
|
||||
<AlertSearchTimeRange />
|
||||
<button class="btn btn-search ml-8" @click.stop.prevent="search">
|
||||
<font-awesome-icon :icon="['fas', 'search']" class=" text-lg" />
|
||||
|
@ -11,12 +11,12 @@ const initializeItems = () => {
|
||||
setItems([
|
||||
{
|
||||
title: t("alert.offnormal"),
|
||||
key: "offnormal",
|
||||
key: 1,
|
||||
active: true,
|
||||
},
|
||||
{
|
||||
title: t("alert.normal"),
|
||||
key: "normal",
|
||||
key: 2,
|
||||
active: false,
|
||||
},
|
||||
]);
|
||||
@ -34,7 +34,7 @@ watch(locale, () => {
|
||||
watch(
|
||||
selectedBtn,
|
||||
(newValue) => {
|
||||
changeParams({ ...searchParams.value, isRecover: newValue.key });
|
||||
changeParams({ ...searchParams.value, isRecovery: newValue.key });
|
||||
}
|
||||
);
|
||||
|
||||
@ -42,8 +42,8 @@ watch(
|
||||
watch(
|
||||
searchParams,
|
||||
(newSearchParams) => {
|
||||
if (!newSearchParams.isRecover) {
|
||||
changeParams({ ...newSearchParams, isRecover: "offnormal" });
|
||||
if (!newSearchParams.isRecovery) {
|
||||
changeParams({ ...newSearchParams, isRecovery: 1 });
|
||||
}
|
||||
},
|
||||
{ immediate: true } // 確保在初始化立即觸發
|
||||
|
@ -9,17 +9,17 @@ const { searchParams, changeParams } = useSearchParam();
|
||||
const dateRange = ref([
|
||||
{
|
||||
key: "start_at",
|
||||
value: searchParams.value.start_created_at
|
||||
? dayjs(searchParams.value.start_created_at).valueOf()
|
||||
: dayjs().subtract(30, "day").valueOf(),
|
||||
value: searchParams.value.Start_date
|
||||
? dayjs(searchParams.value.Start_date)
|
||||
: dayjs().subtract(30, "day"),
|
||||
dateFormat: "yyyy-MM-dd",
|
||||
placeholder: t("alert.start_date"),
|
||||
},
|
||||
{
|
||||
key: "end_at",
|
||||
value: searchParams.value.end_created_at
|
||||
? dayjs(searchParams.value.end_created_at).valueOf()
|
||||
: dayjs().valueOf(),
|
||||
value: searchParams.value.End_date
|
||||
? dayjs(searchParams.value.End_date)
|
||||
: dayjs(),
|
||||
dateFormat: "yyyy-MM-dd",
|
||||
placeholder: t("alert.end_date"),
|
||||
},
|
||||
@ -29,13 +29,13 @@ const changeTimeRange = () => {
|
||||
const newRange = [
|
||||
{
|
||||
key: "start_at",
|
||||
value: dayjs().subtract(30, "day").startOf("day").valueOf(), // 向前推30天並設置為當天的00:00:00.000
|
||||
value: dayjs().subtract(30, "day"),
|
||||
dateFormat: "yyyy-MM-dd",
|
||||
placeholder: t("alert.start_date"),
|
||||
},
|
||||
{
|
||||
key: "end_at",
|
||||
value: dayjs().endOf("day").valueOf(), // 設置為今日的23:59:59.999
|
||||
value: dayjs().endOf("day"),
|
||||
dateFormat: "yyyy-MM-dd",
|
||||
placeholder: t("alert.end_date"),
|
||||
},
|
||||
@ -45,16 +45,16 @@ const changeTimeRange = () => {
|
||||
|
||||
changeParams({
|
||||
...searchParams.value,
|
||||
start_created_at: newRange[0].value,
|
||||
end_created_at: newRange[1].value,
|
||||
Start_date: newRange[0].value,
|
||||
End_date: newRange[1].value,
|
||||
});
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
// 初始化日期範圍
|
||||
if (
|
||||
!searchParams.value.start_created_at ||
|
||||
!searchParams.value.end_created_at
|
||||
!searchParams.value.Start_date ||
|
||||
!searchParams.value.End_date
|
||||
) {
|
||||
changeTimeRange();
|
||||
}
|
||||
@ -66,10 +66,8 @@ watch(
|
||||
() => {
|
||||
changeParams({
|
||||
...searchParams.value,
|
||||
start_created_at: dayjs(dateRange.value[0].value)
|
||||
.startOf("day")
|
||||
.valueOf(),
|
||||
end_created_at: dayjs(dateRange.value[1].value).endOf("day").valueOf(),
|
||||
Start_date: dayjs(dateRange.value[0].value).format("YYYY-MM-DD"),
|
||||
End_date: dayjs(dateRange.value[1].value).format("YYYY-MM-DD"),
|
||||
});
|
||||
},
|
||||
{ deep: true } // 確保在初始化立即觸發
|
||||
|
@ -12,12 +12,12 @@ const changeCheckedItem = () => {
|
||||
if (checkedItem.value.length === store.subSys.length) {
|
||||
changeParams({
|
||||
...searchParams.value,
|
||||
system_tag: [],
|
||||
device_name_tag: [],
|
||||
});
|
||||
} else {
|
||||
changeParams({
|
||||
...searchParams.value,
|
||||
system_tag: store.subSys.map(({ main_system_tag, sub_system_tag }) => main_system_tag+`_`+sub_system_tag),
|
||||
device_name_tag: store.subSys.map(({ sub_system_tag }) => sub_system_tag),
|
||||
});
|
||||
}
|
||||
};
|
||||
@ -26,16 +26,16 @@ const onChange = (value, checked) => {
|
||||
if (checked) {
|
||||
changeParams({
|
||||
...searchParams.value,
|
||||
system_tag: searchParams.value.system_tag
|
||||
? typeof searchParams.value.system_tag === "string"
|
||||
? [searchParams.value.system_tag, value]
|
||||
: [...searchParams.value.system_tag, value]
|
||||
device_name_tag: searchParams.value.device_name_tag
|
||||
? typeof searchParams.value.device_name_tag === "string"
|
||||
? [searchParams.value.device_name_tag, value]
|
||||
: [...searchParams.value.device_name_tag, value]
|
||||
: [value],
|
||||
});
|
||||
} else {
|
||||
changeParams({
|
||||
...searchParams.value,
|
||||
sub_system_tag: searchParams.value.system_tag.filter(
|
||||
device_name_tag: searchParams.value.device_name_tag.filter(
|
||||
(sub) => sub !== value
|
||||
),
|
||||
});
|
||||
@ -43,18 +43,18 @@ const onChange = (value, checked) => {
|
||||
};
|
||||
|
||||
const checkedItem = computed(() =>
|
||||
searchParams.value.system_tag
|
||||
? typeof searchParams.value.system_tag === "string"
|
||||
? [searchParams.value.system_tag]
|
||||
: searchParams.value.system_tag
|
||||
searchParams.value.device_name_tag
|
||||
? typeof searchParams.value.device_name_tag === "string"
|
||||
? [searchParams.value.device_name_tag]
|
||||
: searchParams.value.device_name_tag
|
||||
: []
|
||||
);
|
||||
|
||||
watch(searchParams, (newValue) => {
|
||||
if (!newValue.system_tag) {
|
||||
if (!newValue.device_name_tag) {
|
||||
changeParams({
|
||||
...newValue,
|
||||
system_tag: [store.subSys[0]?.main_system_tag+`_`+store.subSys[0]?.sub_system_tag],
|
||||
device_name_tag: [store.subSys[0]?.sub_system_tag],
|
||||
});
|
||||
}
|
||||
});
|
||||
@ -75,8 +75,8 @@ watch(searchParams, (newValue) => {
|
||||
v-for="sub in store.subSys"
|
||||
:key="sub.key"
|
||||
:title="sub.full_name"
|
||||
:value="sub.main_system_tag+`_`+sub.sub_system_tag"
|
||||
:checked="checkedItem.includes(sub.main_system_tag+`_`+sub.sub_system_tag)"
|
||||
:value="sub.sub_system_tag"
|
||||
:checked="checkedItem.includes(sub.sub_system_tag)"
|
||||
class="mx-3 my-3 xl:my-0 text-lg"
|
||||
:onChange="onChange"
|
||||
/>
|
||||
|
@ -1,6 +1,5 @@
|
||||
<script setup>
|
||||
import { inject, computed } from "vue";
|
||||
import { postChgAck } from "@/apis/alert";
|
||||
import { Button } from "ant-design-vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
const { t } = useI18n();
|
||||
@ -8,71 +7,39 @@ const { dataSource, openModal, search, tableLoading } = inject("alert_table");
|
||||
|
||||
const columns = computed(() => [
|
||||
{
|
||||
key: "building_tag",
|
||||
title: t("alert.building_and_floor"),
|
||||
},
|
||||
{
|
||||
key: "uuid",
|
||||
key: "id",
|
||||
title: t("alert.uuid"),
|
||||
},
|
||||
{
|
||||
key: "alarmClass",
|
||||
key: "factor",
|
||||
title: t("alert.alarmClass"),
|
||||
},
|
||||
{
|
||||
key: "full_name",
|
||||
key: "device_number",
|
||||
title: t("alert.device_name"),
|
||||
},
|
||||
{
|
||||
key: "device_number",
|
||||
title: t("alert.device_number"),
|
||||
key: "points",
|
||||
title: t("alert.device_point_name"),
|
||||
},
|
||||
{
|
||||
key: "timestamp_date",
|
||||
title: t("alert.date"),
|
||||
},
|
||||
{
|
||||
key: "timestamp_time",
|
||||
key: "created_at",
|
||||
title: t("alert.time"),
|
||||
},
|
||||
{
|
||||
key: "msg",
|
||||
key: "reason",
|
||||
title: t("alert.error_msg"),
|
||||
},
|
||||
{
|
||||
key: "ackState",
|
||||
title: t("alert.ack_state"),
|
||||
},
|
||||
{
|
||||
key: "repairOrder",
|
||||
title: t("alert.repair_order_number"),
|
||||
},
|
||||
]);
|
||||
|
||||
const chgAck = async (devUuid) => {
|
||||
const res = await postChgAck(devUuid);
|
||||
if (res.isSuccess) {
|
||||
search?.();
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Table :loading="tableLoading" :columns="columns" :dataSource="dataSource">
|
||||
<template #bodyCell="{ record, column, index }">
|
||||
<template v-if="column.key === 'ackState'">
|
||||
<template v-if="record.ackState === 'Unacked'">
|
||||
<button
|
||||
class="btn btn-sm btn-success text-white whitespace-nowrap mr-2"
|
||||
@click.stop.prevent="() => chgAck(record.uuid)"
|
||||
>
|
||||
{{ $t("alert.unacked") }}
|
||||
</button>
|
||||
</template>
|
||||
<template v-else>
|
||||
{{ record.ackedTime }}
|
||||
</template>
|
||||
</template>
|
||||
<template v-if="column.key === 'repairOrder'">
|
||||
<button
|
||||
class="btn btn-sm btn-success text-white whitespace-nowrap mr-2"
|
||||
|
@ -27,12 +27,13 @@ const dateItem = ref([
|
||||
|
||||
const formState = ref({
|
||||
formId: null,
|
||||
uuid: "",
|
||||
uuid: null,
|
||||
work_type: 2,
|
||||
fix_do: "",
|
||||
fix_do_code: "",
|
||||
fix_firm: "",
|
||||
status: 0,
|
||||
device_number: "",
|
||||
work_person_id: "",
|
||||
start_time: dayjs().format("YYYY-MM-DD"),
|
||||
notice: "",
|
||||
@ -49,7 +50,6 @@ const { model_data, updateEditRecord, search } = inject("alert_modal") || {
|
||||
let alertSchema = yup.object({
|
||||
start_time: yup.date().required(t("button.required")),
|
||||
fix_do: yup.string().required(t("button.required")),
|
||||
fix_do_code: yup.string().required(t("button.required")),
|
||||
fix_firm: yup.string().required(t("button.required")),
|
||||
status: yup.number().required(t("button.required")),
|
||||
work_person_id: yup.string().required(t("button.required")),
|
||||
@ -88,12 +88,12 @@ const onOk = async () => {
|
||||
props.editRecord.uuid && formData.append("error_code", props.editRecord.uuid);
|
||||
|
||||
formData.append("work_type", 2);
|
||||
|
||||
if (props.editRecord.device_number) {
|
||||
formData.append("fix_do_code", props.editRecord.device_number);
|
||||
} else if (props.editRecord.fix_do_code) {
|
||||
formData.append("fix_do_code", props.editRecord.fix_do_code);
|
||||
}
|
||||
formData.append(
|
||||
"fix_do_code",
|
||||
props.editRecord.main_id
|
||||
? props.editRecord.main_id
|
||||
: props.editRecord.fix_do_code
|
||||
);
|
||||
|
||||
try {
|
||||
const value = await handleSubmit(alertSchema, formState.value);
|
||||
@ -110,12 +110,13 @@ const onOk = async () => {
|
||||
const onCancel = () => {
|
||||
formState.value = {
|
||||
formId: null,
|
||||
uuid: "",
|
||||
uuid: null,
|
||||
work_type: 2,
|
||||
fix_do: "",
|
||||
fix_do_code: "",
|
||||
fix_firm: "",
|
||||
status: 0,
|
||||
device_number: "",
|
||||
work_person_id: "",
|
||||
start_time: dayjs().format("YYYY-MM-DD"),
|
||||
notice: "",
|
||||
@ -147,10 +148,6 @@ watch(
|
||||
if (key === "full_name") {
|
||||
formState.value.fix_do = value;
|
||||
}
|
||||
// 維修項目代碼
|
||||
if (key === "device_number" || key === "fix_do_code") {
|
||||
formState.value.fix_do_code = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -168,7 +165,7 @@ watch(
|
||||
<template #modalContent>
|
||||
<form ref="form" class="mt-5 w-full flex flex-wrap justify-between">
|
||||
<Input
|
||||
v-if="formState.value && formState.value.formId"
|
||||
v-if="formState && formState.formId"
|
||||
class="my-2"
|
||||
:value="formState"
|
||||
name="formId"
|
||||
@ -223,13 +220,10 @@ watch(
|
||||
</span>
|
||||
</template>
|
||||
</Input>
|
||||
<Select
|
||||
:value="formState"
|
||||
<Input
|
||||
class="my-2"
|
||||
selectClass="border-info focus-within:border-info"
|
||||
name="fix_do_code"
|
||||
Attribute="full_name"
|
||||
:options="model_data.model_devList"
|
||||
:value="formState"
|
||||
name="device_number"
|
||||
:required="true"
|
||||
:disabled="true"
|
||||
>
|
||||
@ -239,7 +233,7 @@ watch(
|
||||
{{ formErrorMsg.fix_do_code }}
|
||||
</span></template
|
||||
>
|
||||
</Select>
|
||||
</Input>
|
||||
<Select
|
||||
:value="formState"
|
||||
class="my-2"
|
||||
|
@ -6,6 +6,7 @@ import {
|
||||
getOutliersPoints,
|
||||
getFactors,
|
||||
delOutliersSetting,
|
||||
postMQTTRefresh,
|
||||
} from "@/apis/alert";
|
||||
import useSearchParam from "@/hooks/useSearchParam";
|
||||
import AlertOutliersTableAddModal from "./AlertOutliersTableAddModal.vue";
|
||||
@ -66,11 +67,11 @@ const columns = computed(() => [
|
||||
title: t("alert.warning_method"),
|
||||
key: "warning_method",
|
||||
},
|
||||
{
|
||||
title: t("alert.warning_time"),
|
||||
key: "warning_time",
|
||||
width: 150,
|
||||
},
|
||||
// {
|
||||
// title: t("alert.warning_time"),
|
||||
// key: "warning_time",
|
||||
// width: 150,
|
||||
// },
|
||||
{
|
||||
title: t("alert.operation"),
|
||||
key: "operation",
|
||||
@ -140,14 +141,18 @@ const getOutliersData = async () => {
|
||||
points_name: matchedPoints ? matchedPoints.full_name : "",
|
||||
factor_name: matchedFactor ? matchedFactor.full_name : "",
|
||||
warning_method: warningMethodKeys,
|
||||
warning_time: matchedTime ? matchedTime.schedule_name : "",
|
||||
// warning_time: matchedTime ? matchedTime.schedule_name : "",
|
||||
};
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const getAllOptions = async () => {
|
||||
const [devices, points, factors] = await Promise.all([getDevList(), getAlarmPoints(), getFactor()]);
|
||||
const [devices, points, factors] = await Promise.all([
|
||||
getDevList(),
|
||||
getAlarmPoints(),
|
||||
getFactor(),
|
||||
]);
|
||||
dev_data.value.devList = devices;
|
||||
dev_data.value.alarmPoints = points;
|
||||
dev_data.value.alarmFactors = factors;
|
||||
@ -173,6 +178,15 @@ const openModal = (record) => {
|
||||
outliers_add_table_item.showModal();
|
||||
};
|
||||
|
||||
const refreshMQTT = async () => {
|
||||
const res = await postMQTTRefresh();
|
||||
if (res.isSuccess) {
|
||||
openToast("success", t("msg.mqtt_refresh"));
|
||||
} else {
|
||||
openToast("error", res.msg, "#outliers_add_table_item");
|
||||
}
|
||||
};
|
||||
|
||||
const remove = async (Id) => {
|
||||
openToast("warning", t("msg.sure_to_delete"), "body", async () => {
|
||||
await cancelToastOpen();
|
||||
@ -193,7 +207,8 @@ const onCancel = () => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex justify-start items-center mt-10">
|
||||
<div class="flex items-center justify-between mt-10">
|
||||
<div class="flex">
|
||||
<h3 class="text-xl mr-5">{{ $t("alert.alarm_settings") }}</h3>
|
||||
<AlertOutliersTableAddModal
|
||||
:openModal="openModal"
|
||||
@ -203,6 +218,10 @@ const onCancel = () => {
|
||||
:OptionsData="dev_data"
|
||||
/>
|
||||
</div>
|
||||
<button class="btn btn-sm btn-add" @click.prevent="refreshMQTT">
|
||||
<font-awesome-icon :icon="['fas', 'cog']" />{{ $t("alert.reorganization") }}
|
||||
</button>
|
||||
</div>
|
||||
<Table :columns="columns" :dataSource="tableData" class="mt-3">
|
||||
<template #bodyCell="{ record, column, index }">
|
||||
<template v-if="column.key === 'operation'">
|
||||
@ -225,9 +244,9 @@ const onCancel = () => {
|
||||
<template v-else-if="column.key === 'warning_method'">
|
||||
<span class="whitespace-pre">{{ record.warning_method }}</span>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'warning_time'">
|
||||
<!-- <template v-else-if="column.key === 'warning_time'">
|
||||
<span class="whitespace-pre">{{ record.warning_time }}</span>
|
||||
</template>
|
||||
</template> -->
|
||||
<template v-else>
|
||||
{{ record[column.key] }}
|
||||
</template>
|
||||
|
@ -214,7 +214,7 @@ const closeModal = () => {
|
||||
<template #topLeft>{{ $t("alert.warning_value") }}</template>
|
||||
</Input>
|
||||
</template>
|
||||
<Select
|
||||
<!-- <Select
|
||||
:value="formState"
|
||||
class="my-2"
|
||||
selectClass="border-info focus-within:border-info"
|
||||
@ -239,7 +239,7 @@ const closeModal = () => {
|
||||
/>{{ $t("alert.clear") }}
|
||||
</button>
|
||||
</template>
|
||||
</Select>
|
||||
</Select> -->
|
||||
<div class="w-full mt-5">
|
||||
<p class="text-light text-lg ml-1">
|
||||
{{ $t("alert.warning_method") }}
|
||||
|
@ -43,7 +43,7 @@ provide("notify_table", { timesList, noticeList, timesListData });
|
||||
<div>
|
||||
<AlertSubList />
|
||||
<AlertOutliersTable />
|
||||
<AlertTimeTable />
|
||||
<!-- <AlertTimeTable /> -->
|
||||
<AlertNotifyTable />
|
||||
</div>
|
||||
</template>
|
||||
|
@ -16,8 +16,6 @@ const navigateToSubSystem = (mainSystemId, subSystemId) => {
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
// console.log("subSys", store.subSys);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
Loading…
Reference in New Issue
Block a user