調整異常設定表單,新增限定條件欄位

This commit is contained in:
koko 2025-09-05 16:50:49 +08:00
parent be4ff70043
commit 30b3cb586b
5 changed files with 216 additions and 150 deletions

View File

@ -16,6 +16,7 @@ export const GET_OUTLIERS_DEVLIST_API = `api/Alarm/GetDevList`; // 取得設備
export const GET_OUTLIERS_POINTS_API = `api/Alarm/GetAlarmPoints`; // 取得點位
export const POST_OUTLIERS_SETTING_API = `api/Alarm/SaveAlarmSetting`; // 新增與修改
export const DELETE_OUTLIERS_SETTING_API = `api/Alarm/DeleteAlarmSetting`; // 刪除
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`;

View File

@ -16,7 +16,8 @@ import {
GET_SHOW_ALERT_API,
GET_ALERT_SCHEDULE_LIST_API,
POST_ALERT_SCHEDULE,
DELETE_ALERT_SCHEDULE
DELETE_ALERT_SCHEDULE,
GET_FACTOR_API
} from "./api";
import instance from "@/util/request";
import apihandler from "@/util/apihandler";
@ -153,6 +154,15 @@ export const getOutliersPoints = async (id) => {
});
};
export const getFactors = async () => {
const res = await instance.post(GET_FACTOR_API);
return apihandler(res.code, res.data, {
msg: res.msg,
code: res.code,
});
};
export const postOutliersSetting = async (data) => {
const res = await instance.post(POST_OUTLIERS_SETTING_API, data);

View File

@ -1,6 +1,12 @@
<script setup>
import { onMounted, ref, watch, inject } from "vue";
import { getOutliersList, getOutliersDevList, getOutliersPoints, delOutliersSetting } from "@/apis/alert";
import {
getOutliersList,
getOutliersDevList,
getOutliersPoints,
getFactors,
delOutliersSetting,
} from "@/apis/alert";
import useSearchParam from "@/hooks/useSearchParam";
import AlertOutliersTableAddModal from "./AlertOutliersTableAddModal.vue";
@ -13,6 +19,7 @@ const tableData = ref([]);
const dev_data = ref({
devList: [],
alarmPoints: [],
alarmFactors: [],
});
const editRecord = ref(null);
@ -39,31 +46,10 @@ const columns = [
title: "限定條件",
key: "factor_name",
},
{
title: "上限(>=)",
key: "highLimit",
},
{
title: "下限(<=)",
key: "lowLimit",
},
{
title: "上限持續秒數",
key: "highDelay",
},
{
title: "下限持續秒數",
key: "lowDelay",
},
{
title: "警示方式",
key: "warning_method",
},
{
title: "警示時間",
key: "warning_time",
width: 150,
},
{
title: "功能",
key: "operation",
@ -73,48 +59,64 @@ const columns = [
const getDevList = async () => {
const res = await getOutliersDevList({
device_name_tag: searchParams.value?.subSys_id
device_name_tag: searchParams.value?.subSys_id,
});
return res.data.map((d) => ({
...d,
key: d.device_number
key: d.device_number,
}));
};
const getAlarmPoints = async () => {
const res = await getOutliersPoints({
device_name_tag: searchParams.value?.subSys_id
device_name_tag: searchParams.value?.subSys_id,
});
return res.data.map((d) => ({
...d,
key: d.points
key: d.points,
}));
};
const getFactor = async () => {
const res = await getFactors();
return res.data.map((d) => ({
...d,
key: d.id,
}));
};
const getOutliersData = async () => {
const res = await getOutliersList({
device_name_tag: searchParams.value?.subSys_id
device_name_tag: searchParams.value?.subSys_id,
});
loading.value = true;
if (res.isSuccess) {
tableData.value = res.data.map(item => {
const matchedDevice = dev_data.value.devList.find(dev => dev.device_number === item.device_number);
const matchedPoints = dev_data.value.alarmPoints.find(p => p.points === item.points);
const matchedFactor = matchedPoints?.factor && item.factor ? matchedPoints?.factor?.find(f => f.id === item.factor) : null;
const matchedTime = timesList.value.find(t => t.id === item.schedule_id);
const warningMethodKeys = item.notices?.map(noticeValue => {
const matchedNotice = noticeList.value.find(n => n.system_value === noticeValue);
return matchedNotice ? matchedNotice.system_key : '';
}).filter(key => key !== '').join('\n');
tableData.value = res.data.map((item) => {
const matchedDevice = dev_data.value.devList.find(
(dev) => dev.device_number === item.device_number
);
const matchedPoints = dev_data.value.alarmPoints.find(
(p) => p.points === item.points
);
const matchedFactor = dev_data.value.alarmFactors.find(
(p) => p.id === item.factor
);
const warningMethodKeys = item.notices
?.map((noticeValue) => {
const matchedNotice = noticeList.value.find(
(n) => n.system_value === noticeValue
);
return matchedNotice ? matchedNotice.system_key : "";
})
.filter((key) => key !== "")
.join("\n");
return {
...item,
device_name: matchedDevice ? matchedDevice.device_name : '',
points: matchedPoints ? matchedPoints.full_name : '',
is_bool: matchedPoints ? matchedPoints.is_bool : 1,
factor_name: matchedFactor ? matchedFactor.full_name : '',
device_name: matchedDevice ? matchedDevice.device_name : "",
points_name: matchedPoints ? matchedPoints.full_name : "",
factor_name: matchedFactor ? matchedFactor.full_name : "",
warning_method: warningMethodKeys,
warning_time: matchedTime ? matchedTime.schedule_name : '',
};
});
loading.value = false;
@ -122,12 +124,14 @@ const getOutliersData = async () => {
};
const getAllOptions = async () => {
const [devices, points] = await Promise.all([
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;
};
watch(
@ -167,7 +171,6 @@ const onCancel = () => {
editRecord.value = null;
outliers_add_table_item.close();
};
</script>
<template>
@ -181,7 +184,12 @@ const onCancel = () => {
:OptionsData="dev_data"
/>
</div>
<Table :loading="loading" :columns="columns" :dataSource="tableData" class="mt-3">
<Table
:loading="loading"
:columns="columns"
:dataSource="tableData"
class="mt-3"
>
<template #bodyCell="{ record, column, index }">
<template v-if="column.key === 'operation'">
<button
@ -198,14 +206,11 @@ const onCancel = () => {
</button>
</template>
<template v-else-if="column.key === 'enable'">
{{ record.enable === 1 ? '是' : '否' }}
{{ record.enable === 1 ? "是" : "否" }}
</template>
<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'">
<span class="whitespace-pre">{{ record.warning_time }}</span>
</template>
<template v-else>
{{ record[column.key] }}
</template>

View File

@ -20,18 +20,19 @@ const props = defineProps({
const form = ref(null);
const formState = ref({
"id": 0,
"device_number": "",
"device_name_tag": searchParams.value?.subSys_id,
"points": "",
"enable": 0,
"is_bool": 1,
"factor": null,
"highLimit": null,
"lowLimit": null,
"highDelay": null,
"lowDelay": null,
"notices": []
id: 0,
device_number: "",
device_name_tag: searchParams.value?.subSys_id,
points: "",
enable: 0,
factor: 1,
alarm_value: "",
delay: 0,
highLimit: null,
lowLimit: null,
highDelay: null,
lowDelay: null,
notices: [],
});
let scheme = yup.object({
@ -45,12 +46,12 @@ let scheme = yup.object({
lowDelay: yup.number().nullable(),
});
const { formErrorMsg, handleSubmit, handleErrorReset } =
useFormErrorMessage(scheme.value);
const { formErrorMsg, handleSubmit, handleErrorReset } = useFormErrorMessage(
scheme.value
);
const SaveCheckAuth = ref([]);
const isBool = ref(1);
const factorData = ref([]);
const factorNum = ref(1);
watch(
() => props.editRecord,
@ -61,28 +62,15 @@ watch(
};
SaveCheckAuth.value = newValue.notices ? [...newValue.notices] : [];
if (newValue.points) {
onPointsChange(newValue.points);
if (newValue.factor) {
onFactorsChange(newValue.factor);
}
}
}
);
const onPointsChange = (selectedPoint) => {
const pointData = props.OptionsData.alarmPoints.find(p => p.points === selectedPoint);
if (pointData) {
isBool.value = pointData.is_bool;
formState.value.is_bool = pointData.is_bool;
if (pointData.factor && Array.isArray(pointData.factor)) {
factorData.value = pointData.factor.map((d) => ({
...d,
key: d.id
}));;
} else {
factorData.value = [];
formState.value.factor = 0;
}
}
const onFactorsChange = (selectedFactor) => {
factorNum.value = selectedFactor;
};
const onNoticesChange = (value, checked) => {
@ -117,34 +105,69 @@ const closeModal = () => {
formState.value = {};
handleErrorReset();
props.onCancel();
factorData.value = [];
isBool.value = 1;
factorNum.value = 1;
};
</script>
<template>
<button class="btn btn-sm btn-success mr-3" @click.stop.prevent="openModal">
<font-awesome-icon :icon="['fas', 'plus']" />新增
</button>
<Modal id="outliers_add_table_item" title="異常設定" :open="open" :onCancel="closeModal" width="710">
<Modal
id="outliers_add_table_item"
title="異常設定"
:open="open"
:onCancel="closeModal"
:width="710"
>
<template #modalContent>
<form ref="form" class="mt-5 w-full flex flex-wrap justify-between">
<Select :value="formState" class="my-2" selectClass="border-info focus-within:border-info" name="device_number"
Attribute="device_name" :options="OptionsData.devList">
<Select
:value="formState"
class="my-2"
selectClass="border-info focus-within:border-info"
name="device_number"
Attribute="device_name"
:options="OptionsData.devList"
>
<template #topLeft>設備名稱</template>
<template #bottomLeft><span class="text-error text-base">
<template #bottomLeft
><span class="text-error text-base">
{{ formErrorMsg.device_number }}
</span></template>
</span></template
>
</Select>
<Select :value="formState" class="my-2" selectClass="border-info focus-within:border-info" name="points"
Attribute="full_name" :options="OptionsData.alarmPoints" :onChange="onPointsChange">
<Select
:value="formState"
class="my-2"
selectClass="border-info focus-within:border-info"
name="points"
Attribute="full_name"
:options="OptionsData.alarmPoints"
>
<template #topLeft>項目</template>
<template #bottomLeft><span class="text-error text-base">
<template #bottomLeft
><span class="text-error text-base">
{{ formErrorMsg.points }}
</span></template>
</span></template
>
</Select>
<RadioGroup class="my-2" name="enable" :value="formState" :items="[
<Select
:value="formState"
class="my-2"
selectClass="border-info focus-within:border-info"
name="factor"
Attribute="full_name"
:options="OptionsData.alarmFactors"
:onChange="onFactorsChange"
>
<template #topLeft>限定條件</template>
</Select>
<RadioGroup
class="my-2"
name="enable"
:value="formState"
:items="[
{
key: 1,
value: 1,
@ -155,51 +178,78 @@ const closeModal = () => {
value: 0,
title: '不啟用',
},
]" :required="true">
]"
:required="true"
>
<template #topLeft>狀態</template>
</RadioGroup>
<Select :value="formState" class="my-2" selectClass="border-info focus-within:border-info" name="schedule_id"
Attribute="schedule_name" :options="timesList">
<template #topLeft>警示時間</template>
<template #topRight><button v-if="formState.schedule_id" class="text-base btn-text-without-border"
@click="() => {formState.schedule_id = null}"><font-awesome-icon
:icon="['fas', 'times']"
class="text-[#a5abb1] me-1"
/></button></template>
</Select>
<Select :value="formState" class="my-2" selectClass="border-info focus-within:border-info" name="factor"
Attribute="full_name" :options="factorData" v-if="factorData.length !== 0">
<template #topLeft>限定條件</template>
</Select>
<template v-if="factorNum == 2">
<div class="flex gap-4 w-full">
<InputNumber :value="formState" class="" name="highLimit" v-if="!isBool">
<InputNumber
:value="formState"
class=""
name="highLimit"
v-if="!isBool"
>
<template #topLeft>上限(>=)</template>
</InputNumber>
<InputNumber :value="formState" class="" name="lowLimit" v-if="!isBool">
<InputNumber
:value="formState"
class=""
name="lowLimit"
v-if="!isBool"
>
<template #topLeft>下限(&lt;=)</template>
</InputNumber>
</div>
<div class="flex gap-4 w-full">
<InputNumber :value="formState" class="my-2" name="highDelay" v-if="!isBool">
<InputNumber
:value="formState"
class="my-2"
name="highDelay"
v-if="!isBool"
>
<template #topLeft>上限持續秒數</template>
</InputNumber>
<InputNumber :value="formState" class="my-2" name="lowDelay" v-if="!isBool">
<InputNumber
:value="formState"
class="my-2"
name="lowDelay"
v-if="!isBool"
>
<template #topLeft>下限持續秒數</template>
</InputNumber>
</div>
</template>
<template v-if="factorNum == 1">
<Input :value="formState" class="my-2" name="alarm_value">
<template #topLeft>警示值</template>
</Input>
</template>
<div class="w-full mt-5">
<p class="text-light text-lg ml-1">
警示方式
</p>
<AlertNoticesTable :SaveCheckAuth="SaveCheckAuth" :NoticeData="noticeList" :onChange="onNoticesChange" />
<p class="text-light text-lg ml-1">警示方式</p>
<AlertNoticesTable
:SaveCheckAuth="SaveCheckAuth"
:NoticeData="noticeList"
:onChange="onNoticesChange"
/>
</div>
</form>
</template>
<template #modalAction>
<button type="reset" class="btn btn-outline-success mr-2" @click.prevent="closeModal">
<button
type="reset"
class="btn btn-outline-success mr-2"
@click.prevent="closeModal"
>
取消
</button>
<button type="submit" class="btn btn-outline-success" @click.prevent="onOk">
<button
type="submit"
class="btn btn-outline-success"
@click.prevent="onOk"
>
確定
</button>
</template>

View File

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