告警頁面

This commit is contained in:
koko 2025-04-11 17:35:18 +08:00
parent 502b4f3778
commit b55ba4003d
18 changed files with 232 additions and 284 deletions

View File

@ -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`;

View File

@ -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,
});
};

View File

@ -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>
@ -68,12 +76,12 @@ const ackedAlarm = async (uuid) => {
<style lang="scss" scoped>
.card::before {
@apply absolute h-5 w-5 top-1 left-1 bg-no-repeat z-10 bg-[url('../../assets/img/table/content-box-background01.svg')] bg-center;
@apply absolute h-5 w-5 top-1 left-1 bg-no-repeat z-10 bg-[url('../../assets/img/table/content-box-background01.svg')] bg-center;
content: "";
}
.card::after {
@apply absolute bottom-1 right-1 h-5 w-5 bg-no-repeat z-10 bg-[url('../../assets/img/table/content-box-background05.svg')] bg-center;
@apply absolute bottom-1 right-1 h-5 w-5 bg-no-repeat z-10 bg-[url('../../assets/img/table/content-box-background05.svg')] bg-center;
content: "";
}
</style>

View File

@ -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) => {
isOpen.value = false;
selectedOption.value = props.options.find((option) => option.key == newKey);
},
{ immediate: true }
);
watchEffect(() => {
isOpen.value = false;
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'
)
"

View File

@ -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 解析",

View File

@ -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 解析",

View File

@ -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",

View File

@ -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,63 +55,23 @@ const getModalCompanyList = async () => {
};
const getAllOptions = async () => {
Promise.all([
getModalDevList(),
getModalUserList(),
getModalCompanyList(),
]).then(([devices, 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 }));
Promise.all([getModalUserList(), getModalCompanyList()]).then(
([users, companies]) => {
model_data.value.model_userList = users;
model_data.value.model_companyList = companies;
}
);
};
const search = async () => {
tableLoading.value = true;
if (Object.keys(searchParams.value).length !== 0) {
storeAlarm.getAlarmDataFromBaja();
updateDataSource(storeAlarm.alarmData);
const res = await getAlertLog({
...searchParams.value,
isRecovery: Number(searchParams.value.isRecovery),
});
dataSource.value = (res.data || []).map((d) => ({ ...d, key: d.id }));
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;
}
}
});
}
updateDataSource(alarmData.value);
tableLoading.value = false;
}
);
*/
}
};
@ -141,11 +79,17 @@ 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();
}

View File

@ -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" />

View File

@ -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 } //

View File

@ -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(), // 3000: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 } //

View File

@ -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"
/>

View File

@ -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"

View File

@ -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"
@ -323,7 +317,7 @@ watch(
class="btn btn-outline-success"
@click.stop.prevent="onOk"
>
{{ $t("button.submit")}}
{{ $t("button.submit") }}
</button>
</template>
</Modal>

View File

@ -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,15 +207,20 @@ const onCancel = () => {
</script>
<template>
<div class="flex justify-start items-center mt-10">
<h3 class="text-xl mr-5">{{ $t("alert.alarm_settings") }}</h3>
<AlertOutliersTableAddModal
:openModal="openModal"
:onCancel="onCancel"
:editRecord="editRecord"
:getData="getOutliersData"
:OptionsData="dev_data"
/>
<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"
:onCancel="onCancel"
:editRecord="editRecord"
:getData="getOutliersData"
: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 }">
@ -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>

View File

@ -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") }}

View File

@ -43,7 +43,7 @@ provide("notify_table", { timesList, noticeList, timesListData });
<div>
<AlertSubList />
<AlertOutliersTable />
<AlertTimeTable />
<!-- <AlertTimeTable /> -->
<AlertNotifyTable />
</div>
</template>

View File

@ -16,8 +16,6 @@ const navigateToSubSystem = (mainSystemId, subSystemId) => {
},
});
};
// console.log("subSys", store.subSys);
</script>
<template>