feat:反应器增加相关报警设置

This commit is contained in:
Asoka.Wang 2025-06-17 10:13:46 +08:00
parent adb93ecad5
commit f42b22dc0a
9 changed files with 213 additions and 9 deletions

View File

@ -0,0 +1,27 @@
import { RequestParams } from './http-client'
import { ContentType, HttpClient } from './http-client'
export class ReactorEPSettingApi extends HttpClient {
/**
*
*/
batchUpdate = (data: any[], params: RequestParams = {}) =>
this.request<any>({
path: `/api/admin/ep-setting-equ-reactor/batch-update`,
method: 'POST',
body: data,
type: ContentType.Json,
...params,
})
/**
* ID获取报警设置列表
*/
getListByEquReactor = (params: { equReactorId: number }, requestParams: RequestParams = {}) =>
this.request<any>({
path: `/api/admin/ep-setting-equ-reactor/get-list-by-equ-reactor`,
method: 'GET',
query: params,
...requestParams,
})
}

View File

@ -75,6 +75,8 @@ export interface ReactorDto {
createdTime?: string | null createdTime?: string | null
/** 修改时间 */ /** 修改时间 */
modifiedTime?: string | null modifiedTime?: string | null
/** 压力单位 */
pressureUnit?: string | null
} }
/** 反应器添加和更新输入接口 */ /** 反应器添加和更新输入接口 */

View File

@ -0,0 +1,38 @@
// 反应器报警设置类型定义
export interface ReactorEPSetting {
/** 主键ID */
id: number
/** 设备反应器ID */
equReactorId: number
/** EP定义ID */
epDefId: number
/** EP定义 */
epDefName: string
/** EP定义别名 */
epDefAlias: string
/** 告警下限 */
warningLowerLimit: number
/** 告警下限缓冲 */
warningLowerBuffer: number
/** 告警上限 */
warningUpperLimit: number
/** 告警上限缓冲 */
warningUpperBuffer: number
/** 动作下限 */
actionLowerLimit: number
/** 动作上限 */
actionUpperLimit: number
/** 动作时间缓冲 */
actionTimeBuffer: number
/** 预警时间缓冲 */
warningTimeBuffer: number
/** 是否启用 */
isEnable: boolean
/** 状态 */
status: boolean
/** 计量单位 */
unit: string
/** OPC名称 */
needConfig: boolean
}

View File

@ -0,0 +1,125 @@
<template>
<el-dialog v-model="dialogVisible" title="报警设置" width="1200px" :close-on-click-modal="false" :close-on-press-escape="false" destroy-on-close draggable class="alarm-dialog-high">
<div style="margin-bottom: 16px; display: flex; justify-content: flex-end; gap: 8px;">
<el-button type="primary" @click="setAllAlarmStatus(true)">一键开启</el-button>
<el-button type="warning" @click="setAllAlarmStatus(false)">一键关闭</el-button>
</div>
<div class="alarm-table-wrapper">
<el-table :data="state.alarmSettingList" border style="width: 100%;" max-height="550px" :header-cell-style="{background:'#fafafa'}">
<el-table-column label="序号" width="60" align="center">
<template #default="{ $index }">
{{ $index + 1 }}
</template>
</el-table-column>
<el-table-column prop="epDefName" label="在线数据" min-width="120" align="center" />
<el-table-column prop="epDefAlias" label="OPC名称" min-width="120" align="center">
<template #default="{ row }">
<template v-if="row.needConfig">
<el-select v-model="row.epDefAlias" placeholder="-" style="width: 100%" filterable>
<el-option v-for="item in opcNameOptions" :key="item" :label="item" :value="item" />
</el-select>
</template>
<template v-else>
-
</template>
</template>
</el-table-column>
<el-table-column prop="warningLowerLimit" label="报警下限值" min-width="100" align="center">
<template #default="{ row }">
<el-input v-model="row.warningLowerLimit" size="small" />
</template>
</el-table-column>
<el-table-column prop="warningLowerBuffer" label="下限延时/s" min-width="100" align="center">
<template #default="{ row }">
<el-input v-model="row.warningLowerBuffer" size="small" />
</template>
</el-table-column>
<el-table-column prop="warningUpperLimit" label="报警上限值" min-width="100" align="center">
<template #default="{ row }">
<el-input v-model="row.warningUpperLimit" size="small" />
</template>
</el-table-column>
<el-table-column prop="warningUpperBuffer" label="上限延时/s" min-width="100" align="center">
<template #default="{ row }">
<el-input v-model="row.warningUpperBuffer" size="small" />
</template>
</el-table-column>
<el-table-column prop="unit" label="计量单位" min-width="80" align="center">
<template #default="{ row }">
{{ row.epDefName === 'Pressure' ? state.pressureUnit : row.unit }}
</template>
</el-table-column>
<el-table-column prop="isEnable" label="报警状态" min-width="100" align="center">
<template #default="{ row }">
<el-switch v-model="row.isEnable" />
</template>
</el-table-column>
</el-table>
</div>
<div class="alarm-dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="saveAlarmConfig">保存</el-button>
</div>
</el-dialog>
</template>
<script setup lang="ts">
import { ref, reactive } from 'vue'
import { ElMessage } from 'element-plus'
import { ReactorEPSettingApi } from '/@/api/admin/ReactorEPSettingApi'
import { ReactorEPSetting } from '/@/api/types/reactorEPSetting'
import { ReactorDto } from '/@/api/types/ReactorType'
defineOptions({ name: 'AlarmSettingForm' })
const dialogVisible = ref(false)
const state = reactive({
alarmSettingList: [] as ReactorEPSetting[],
pressureUnit: ''
})
const opcNameOptions = ['MFC1', 'MFC2', 'MFC3', 'MFC4', 'MFC5', 'MFC6']
function setAllAlarmStatus(status: boolean) {
state.alarmSettingList.forEach(item => item.isEnable = status)
}
async function saveAlarmConfig() {
const res = await new ReactorEPSettingApi().batchUpdate(state.alarmSettingList)
if (res.success) {
ElMessage.success('报警配置已保存')
dialogVisible.value = false
}
}
async function open(reactor: ReactorDto) {
console.log("Reactor", reactor.pressureUnit)
await getAlarmSettingList(reactor.id!)
state.pressureUnit = reactor.pressureUnit!
dialogVisible.value = true
}
const getAlarmSettingList = async (id: number) => {
const res = await new ReactorEPSettingApi().getListByEquReactor({ equReactorId: id })
state.alarmSettingList = res.data
}
defineExpose({ open })
</script>
<style scoped>
.alarm-table-wrapper {
max-height: 600px;
overflow: auto;
}
.alarm-dialog-footer {
position: sticky;
bottom: 0;
background: #fff;
padding: 16px 0 0 0;
text-align: right;
z-index: 10;
}
</style>

View File

@ -355,7 +355,7 @@
import { ref, reactive, onMounted, watch, getCurrentInstance } from 'vue' import { ref, reactive, onMounted, watch, getCurrentInstance } from 'vue'
import { ElMessage } from 'element-plus' import { ElMessage } from 'element-plus'
import type { FormInstance, FormRules } from 'element-plus' import type { FormInstance, FormRules } from 'element-plus'
import { ReactorApi } from '/@/api/admin/reactor' import { ReactorApi } from '../../../../api/admin/ReactorApi'
import { RoomApi } from '/@/api/admin/Room' import { RoomApi } from '/@/api/admin/Room'
import { UserApi } from '/@/api/admin/User' import { UserApi } from '/@/api/admin/User'
import { DictApi } from '/@/api/admin/Dict' import { DictApi } from '/@/api/admin/Dict'
@ -369,9 +369,9 @@ import {
MaintenanceFlagEnum, MaintenanceFlagEnum,
ReactorAddInputAndUpdateInput, ReactorAddInputAndUpdateInput,
PumpConfig, PumpConfig,
defaultPumpConfig defaultPumpConfig,
ReactorTypeEnumItem
} from '/@/api/types/ReactorType' } from '/@/api/types/ReactorType'
import type { ReactorTypeEnumItem } from '/@/api/types/ReactorType'
import { toOptionsByValue } from '/@/utils/enum' import { toOptionsByValue } from '/@/utils/enum'
import { EnumPressureUnit } from '/@/api/admin/enum-contracts' import { EnumPressureUnit } from '/@/api/admin/enum-contracts'
import eventBus from '/@/utils/mitt' import eventBus from '/@/utils/mitt'
@ -743,6 +743,9 @@ const submitForm = async () => {
state.sureLoading = false // state.sureLoading = false //
} }
} }
else {
ElMessage.warning('存在未填写的必填项')
}
}) })
} }

View File

@ -56,10 +56,11 @@
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="createdTime" label="创建时间" min-width="160" show-overflow-tooltip /> <el-table-column prop="createdTime" label="创建时间" min-width="160" show-overflow-tooltip />
<el-table-column label="操作" width="180" fixed="right" header-align="center" align="center"> <el-table-column label="操作" width="240" fixed="right" header-align="center" align="center">
<template #default="{ row }"> <template #default="{ row }">
<el-button v-auth="'api:admin:equ-reactor:update'" icon="ele-EditPen" size="small" text type="primary" <el-button v-auth="'api:admin:equ-reactor:update'" icon="ele-EditPen" size="small" text type="primary"
@click="handleEdit(row)">编辑</el-button> @click="handleEdit(row)">编辑</el-button>
<el-button icon="ele-Bell" size="small" text type="warning" @click="openAlarmSetting(row)">报警设置</el-button>
<el-button v-auth="'api:admin:equ-reactor:soft-delete'" icon="ele-Delete" size="small" text type="danger" <el-button v-auth="'api:admin:equ-reactor:soft-delete'" icon="ele-Delete" size="small" text type="danger"
@click="handleDelete(row)">删除</el-button> @click="handleDelete(row)">删除</el-button>
</template> </template>
@ -73,13 +74,14 @@
</el-card> </el-card>
<reactor-form ref="formRef" :title="state.formTitle" @ok="getList" /> <reactor-form ref="formRef" :title="state.formTitle" @ok="getList" />
<alarm-setting-form ref="alarmSettingRef" />
</my-layout> </my-layout>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, reactive, onMounted, onBeforeMount, defineAsyncComponent } from 'vue' import { ref, reactive, onMounted, onBeforeMount, defineAsyncComponent } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus' import { ElMessage, ElMessageBox } from 'element-plus'
import { ReactorApi } from '/@/api/admin/reactor' import { ReactorApi } from '../../../api/admin/ReactorApi'
import { RoomApi } from '/@/api/admin/Room' import { RoomApi } from '/@/api/admin/Room'
import { UserApi } from '/@/api/admin/User' import { UserApi } from '/@/api/admin/User'
import { DictApi } from '/@/api/admin/Dict' import { DictApi } from '/@/api/admin/Dict'
@ -89,10 +91,13 @@ import type {
ReactorDto, ReactorDto,
ReactorTypeEnumItem ReactorTypeEnumItem
} from '/@/api/types/ReactorType' } from '/@/api/types/ReactorType'
const AlarmSettingForm = defineAsyncComponent(() => import('./components/alarm-setting-form.vue'))
const ReactorForm = defineAsyncComponent(() => import('./components/reactor-form.vue')) const ReactorForm = defineAsyncComponent(() => import('./components/reactor-form.vue'))
const loading = ref(false) const loading = ref(false)
const formRef = ref() const formRef = ref()
const alarmSettingRef = ref()
const state = reactive({ const state = reactive({
loading: false, loading: false,
@ -265,6 +270,10 @@ const getPrincipalName = (value: number) => {
return item?.name || '未知' return item?.name || '未知'
} }
function openAlarmSetting(row: ReactorDto) {
alarmSettingRef.value?.open(row)
}
onMounted(() => { onMounted(() => {
getRoomOptions() getRoomOptions()
getPrincipalOptions() getPrincipalOptions()

View File

@ -28,8 +28,8 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, reactive, onMounted } from 'vue' import { ref, reactive, onMounted } from 'vue'
import { ElMessage } from 'element-plus' import { ElMessage } from 'element-plus'
import { ReactorApi } from '/@/api/admin/reactor' import { ReactorApi } from '../../../../api/admin/ReactorApi'
import type { ReactorDto, ReactorTypeEnumItem } from '/@/api/types/ReactorType' import type { ReactorDto, ReactorTypeEnumItem } from '../../../../api/types/reactorType'
const props = defineProps<{ const props = defineProps<{
title: string title: string

View File

@ -71,13 +71,13 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, reactive, onMounted, onBeforeMount } from 'vue' import { ref, reactive, onMounted, onBeforeMount } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus' import { ElMessage, ElMessageBox } from 'element-plus'
import { ReactorApi } from '/@/api/admin/reactor' import { ReactorApi } from '../../../api/admin/ReactorApi'
import eventBus from '/@/utils/mitt' import eventBus from '/@/utils/mitt'
import type { import type {
ReactorPageInput, ReactorPageInput,
ReactorDto, ReactorDto,
ReactorTypeEnumItem ReactorTypeEnumItem
} from '/@/api/types/ReactorType' } from '../../../api/types/reactorType'
import ReactorForm from './components/reactor-form.vue' import ReactorForm from './components/reactor-form.vue'