增加告警页面(带bug)
This commit is contained in:
245
src/views/alarm/AlarmList.vue
Normal file
245
src/views/alarm/AlarmList.vue
Normal file
@@ -0,0 +1,245 @@
|
|||||||
|
<template>
|
||||||
|
<div class="alarm-list">
|
||||||
|
<el-card>
|
||||||
|
<template #header>
|
||||||
|
<div class="card-header">
|
||||||
|
<div class="title-container">
|
||||||
|
<h2 class="page-title">告警管理</h2>
|
||||||
|
<el-button type="text" @click="loadAlarms()" class="refresh-btn" title="刷新告警列表">
|
||||||
|
<el-icon :size="20"><Refresh /></el-icon>
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<el-tabs v-model="activeTab" @tab-click="handleTabClick">
|
||||||
|
<el-tab-pane label="未解决告警" name="unresolved"></el-tab-pane>
|
||||||
|
<el-tab-pane label="已解决告警" name="resolved"></el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
|
||||||
|
<!-- 加载状态 -->
|
||||||
|
<div v-if="loading" class="loading">
|
||||||
|
<el-skeleton animated />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 错误状态 -->
|
||||||
|
<div v-else-if="error" class="error">
|
||||||
|
<el-alert
|
||||||
|
title="获取告警数据失败"
|
||||||
|
:description="error"
|
||||||
|
type="error"
|
||||||
|
show-icon
|
||||||
|
closable
|
||||||
|
@close="error = null"
|
||||||
|
/>
|
||||||
|
<el-button type="primary" @click="loadAlarms()" class="retry-btn">重新加载</el-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 告警列表 -->
|
||||||
|
<el-table v-else :data="alarmData" style="width: 100%" :fit="true" table-layout="auto">
|
||||||
|
<el-table-column prop="alarm_summary" label="告警摘要" min-width="150" />
|
||||||
|
<el-table-column prop="level" label="告警级别" min-width="100">
|
||||||
|
<template #default="scope">{{ formatSeverity(scope.row.level) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="source_type" label="告警来源类型" min-width="120">
|
||||||
|
<template #default="scope">{{ formatSourceType(scope.row.source_type) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="source_id" label="告警来源ID" min-width="100" />
|
||||||
|
<el-table-column prop="trigger_time" label="触发时间" min-width="180">
|
||||||
|
<template #default="scope">{{ formatTime(scope.row.trigger_time) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column v-if="activeTab === 'resolved'" prop="resolve_time" label="解决时间" min-width="180">
|
||||||
|
<template #default="scope">{{ formatTime(scope.row.resolve_time) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column v-if="activeTab === 'unresolved'" label="操作" min-width="100" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button size="small" @click="handleIgnore(scope.row)" :disabled="scope.row.is_ignored">
|
||||||
|
{{ scope.row.is_ignored ? '已忽略' : '忽略' }}
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<!-- 分页 -->
|
||||||
|
<el-pagination
|
||||||
|
v-if="!loading && !error"
|
||||||
|
class="pagination-container"
|
||||||
|
:current-page="pagination.currentPage"
|
||||||
|
:page-size="pagination.pageSize"
|
||||||
|
:total="pagination.total"
|
||||||
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
|
@size-change="handleSizeChange"
|
||||||
|
@current-change="handlePageChange"
|
||||||
|
/>
|
||||||
|
</el-card>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { Refresh } from '@element-plus/icons-vue';
|
||||||
|
import { AlarmApi } from '../../api/alarm.js';
|
||||||
|
import { AlarmSourceType, SeverityLevel } from '../../enums.js';
|
||||||
|
import { ElMessageBox } from 'element-plus';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'AlarmList',
|
||||||
|
components: {
|
||||||
|
Refresh,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
alarmData: [],
|
||||||
|
loading: false,
|
||||||
|
error: null,
|
||||||
|
activeTab: 'unresolved',
|
||||||
|
pagination: {
|
||||||
|
currentPage: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
total: 0,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
async mounted() {
|
||||||
|
await this.loadAlarms();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/**
|
||||||
|
* 加载告警列表数据
|
||||||
|
* @param {string} [tabName] - 可选参数,当前激活的tab名称,用于确保调用正确的API
|
||||||
|
*/
|
||||||
|
async loadAlarms(tabName) {
|
||||||
|
this.loading = true;
|
||||||
|
this.error = null;
|
||||||
|
try {
|
||||||
|
const params = {
|
||||||
|
page: this.pagination.currentPage,
|
||||||
|
page_size: this.pagination.pageSize,
|
||||||
|
order_by: 'trigger_time DESC',
|
||||||
|
};
|
||||||
|
|
||||||
|
let response;
|
||||||
|
// 使用传入的tabName或组件的activeTab来判断
|
||||||
|
const currentTab = tabName || this.activeTab;
|
||||||
|
if (currentTab === 'unresolved') {
|
||||||
|
response = await AlarmApi.getActiveAlarms(params);
|
||||||
|
} else {
|
||||||
|
response = await AlarmApi.getHistoricalAlarms(params);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.alarmData = response.list || [];
|
||||||
|
this.pagination.total = response.pagination?.total || 0;
|
||||||
|
} catch (err) {
|
||||||
|
this.error = err.message || '未知错误';
|
||||||
|
console.error('加载告警列表失败:', err);
|
||||||
|
} finally {
|
||||||
|
this.loading = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 处理标签页切换事件
|
||||||
|
* @param {object} tab - 当前激活的tab对象
|
||||||
|
*/
|
||||||
|
handleTabClick(tab) {
|
||||||
|
this.pagination.currentPage = 1;
|
||||||
|
this.loadAlarms(tab.paneName); // 显式传递paneName
|
||||||
|
},
|
||||||
|
handleSizeChange(newSize) {
|
||||||
|
this.pagination.pageSize = newSize;
|
||||||
|
this.loadAlarms();
|
||||||
|
},
|
||||||
|
handlePageChange(newPage) {
|
||||||
|
this.pagination.currentPage = newPage;
|
||||||
|
this.loadAlarms();
|
||||||
|
},
|
||||||
|
async handleIgnore(alarm) {
|
||||||
|
try {
|
||||||
|
const { value } = await ElMessageBox.prompt('请输入忽略时长(分钟)', '忽略告警', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
inputType: 'number',
|
||||||
|
inputPattern: /^[1-9]\d*$/,
|
||||||
|
inputErrorMessage: '请输入正整数',
|
||||||
|
});
|
||||||
|
|
||||||
|
const duration = parseInt(value, 10);
|
||||||
|
await AlarmApi.snoozeAlarm(alarm.id, { duration_minutes: duration });
|
||||||
|
this.$message.success('告警已忽略');
|
||||||
|
await this.loadAlarms();
|
||||||
|
} catch (err) {
|
||||||
|
if (err !== 'cancel') {
|
||||||
|
this.$message.error('操作失败: ' + (err.message || '未知错误'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
formatTime(timeStr) {
|
||||||
|
if (!timeStr) return '-';
|
||||||
|
return new Date(timeStr).toLocaleString();
|
||||||
|
},
|
||||||
|
formatSeverity(level) {
|
||||||
|
return SeverityLevel[level] || level;
|
||||||
|
},
|
||||||
|
formatSourceType(type) {
|
||||||
|
return AlarmSourceType[type] || type;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.alarm-list {
|
||||||
|
padding: 20px;
|
||||||
|
max-width: 1200px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 15px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title-container {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-title {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
font-weight: bold;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.refresh-btn {
|
||||||
|
color: black;
|
||||||
|
background-color: transparent;
|
||||||
|
padding: 0;
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading {
|
||||||
|
padding: 20px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error {
|
||||||
|
padding: 20px 0;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.retry-btn {
|
||||||
|
margin-top: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination-container {
|
||||||
|
margin-top: 20px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
333
src/views/alarm/ThresholdAlarmList.vue
Normal file
333
src/views/alarm/ThresholdAlarmList.vue
Normal file
@@ -0,0 +1,333 @@
|
|||||||
|
<template>
|
||||||
|
<div class="threshold-alarm-list">
|
||||||
|
<el-card>
|
||||||
|
<template #header>
|
||||||
|
<div class="card-header">
|
||||||
|
<div class="title-container">
|
||||||
|
<h2 class="page-title">阈值告警配置</h2>
|
||||||
|
<el-button type="text" @click="loadData()" class="refresh-btn" title="刷新列表">
|
||||||
|
<el-icon :size="20"><Refresh /></el-icon>
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
<el-button type="primary" @click="handleAddRule">新增规则</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<el-tabs v-model="activeTab" @tab-click="handleTabClick">
|
||||||
|
<!-- 区域告警规则 -->
|
||||||
|
<el-tab-pane label="区域告警" name="area">
|
||||||
|
<el-table :data="areaAlarms.list" v-loading="loading">
|
||||||
|
<el-table-column prop="id" label="ID" width="80" />
|
||||||
|
<el-table-column prop="area_controller_id" label="区域主控ID" min-width="120" />
|
||||||
|
<el-table-column prop="sensor_type" label="传感器类型" min-width="120">
|
||||||
|
<template #default="scope">{{ formatSensorType(scope.row.sensor_type) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="level" label="告警等级" min-width="100">
|
||||||
|
<template #default="scope">{{ formatSeverity(scope.row.level) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="触发条件" min-width="150">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ `${scope.row.operator} ${scope.row.thresholds}` }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作" width="150" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button size="small" @click="handleEditRule(scope.row)">编辑</el-button>
|
||||||
|
<el-button size="small" type="danger" @click="handleDeleteRule(scope.row)">删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<el-pagination
|
||||||
|
class="pagination-container"
|
||||||
|
:current-page="areaAlarms.pagination.currentPage"
|
||||||
|
:page-size="areaAlarms.pagination.pageSize"
|
||||||
|
:total="areaAlarms.pagination.total"
|
||||||
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
|
@size-change="handleSizeChange"
|
||||||
|
@current-change="handlePageChange"
|
||||||
|
/>
|
||||||
|
</el-tab-pane>
|
||||||
|
|
||||||
|
<!-- 设备告警规则 -->
|
||||||
|
<el-tab-pane label="设备告警" name="device">
|
||||||
|
<el-table :data="deviceAlarms.list" v-loading="loading">
|
||||||
|
<el-table-column prop="id" label="ID" width="80" />
|
||||||
|
<el-table-column prop="device_id" label="设备ID" min-width="120" />
|
||||||
|
<el-table-column prop="sensor_type" label="传感器类型" min-width="120">
|
||||||
|
<template #default="scope">{{ formatSensorType(scope.row.sensor_type) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="level" label="告警等级" min-width="100">
|
||||||
|
<template #default="scope">{{ formatSeverity(scope.row.level) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="触发条件" min-width="150">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ `${scope.row.operator} ${scope.row.thresholds}` }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作" width="150" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button size="small" @click="handleEditRule(scope.row)">编辑</el-button>
|
||||||
|
<el-button size="small" type="danger" @click="handleDeleteRule(scope.row)">删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<el-pagination
|
||||||
|
class="pagination-container"
|
||||||
|
:current-page="deviceAlarms.pagination.currentPage"
|
||||||
|
:page-size="deviceAlarms.pagination.pageSize"
|
||||||
|
:total="deviceAlarms.pagination.total"
|
||||||
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
|
@size-change="handleSizeChange"
|
||||||
|
@current-change="handlePageChange"
|
||||||
|
/>
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
|
<!-- 新增/编辑对话框 -->
|
||||||
|
<el-dialog v-model="dialogVisible" :title="isEdit ? '编辑规则' : '新增规则'" width="500px" @close="resetForm">
|
||||||
|
<el-form :model="form" ref="ruleForm" label-width="100px">
|
||||||
|
<el-form-item v-if="activeTab === 'area'" label="区域主控ID" prop="area_controller_id" required>
|
||||||
|
<el-input v-model.number="form.area_controller_id" :disabled="isEdit"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item v-if="activeTab === 'device'" label="设备ID" prop="device_id" required>
|
||||||
|
<el-input v-model.number="form.device_id" :disabled="isEdit"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="传感器类型" prop="sensor_type" required>
|
||||||
|
<el-select v-model="form.sensor_type" placeholder="请选择" :disabled="isEdit">
|
||||||
|
<el-option v-for="(label, key) in SensorType" :key="key" :label="label" :value="key"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="告警等级" prop="level" required>
|
||||||
|
<el-select v-model="form.level" placeholder="请选择">
|
||||||
|
<el-option v-for="(label, key) in SeverityLevel" :key="key" :label="label" :value="key"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="操作符" prop="operator" required>
|
||||||
|
<el-select v-model="form.operator" placeholder="请选择">
|
||||||
|
<el-option v-for="(label, key) in Operator" :key="key" :label="label" :value="key"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="阈值" prop="thresholds" required>
|
||||||
|
<el-input-number v-model="form.thresholds"></el-input-number>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="dialogVisible = false">取消</el-button>
|
||||||
|
<el-button type="primary" @click="submitForm">确定</el-button>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { Refresh } from '@element-plus/icons-vue';
|
||||||
|
import { AlarmApi } from '../../api/alarm.js';
|
||||||
|
import { SensorType, SeverityLevel, Operator } from '../../enums.js';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'ThresholdAlarmList',
|
||||||
|
components: {
|
||||||
|
Refresh,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
SensorType,
|
||||||
|
SeverityLevel,
|
||||||
|
Operator,
|
||||||
|
activeTab: 'area',
|
||||||
|
loading: false,
|
||||||
|
areaAlarms: {
|
||||||
|
list: [],
|
||||||
|
pagination: { currentPage: 1, pageSize: 10, total: 0 },
|
||||||
|
},
|
||||||
|
deviceAlarms: {
|
||||||
|
list: [],
|
||||||
|
pagination: { currentPage: 1, pageSize: 10, total: 0 },
|
||||||
|
},
|
||||||
|
dialogVisible: false,
|
||||||
|
isEdit: false,
|
||||||
|
form: {
|
||||||
|
id: null,
|
||||||
|
area_controller_id: null,
|
||||||
|
device_id: null,
|
||||||
|
sensor_type: '',
|
||||||
|
level: '',
|
||||||
|
operator: '',
|
||||||
|
thresholds: 0,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
async mounted() {
|
||||||
|
await this.loadData();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/**
|
||||||
|
* 加载阈值告警数据
|
||||||
|
* @param {string} [tabName] - 可选参数,当前激活的tab名称,用于确保调用正确的API
|
||||||
|
*/
|
||||||
|
async loadData(tabName) {
|
||||||
|
this.loading = true;
|
||||||
|
try {
|
||||||
|
const currentTab = tabName || this.activeTab;
|
||||||
|
if (currentTab === 'area') {
|
||||||
|
const { currentPage, pageSize } = this.areaAlarms.pagination;
|
||||||
|
const response = await AlarmApi.getAreaThresholdAlarms({ page: currentPage, page_size: pageSize });
|
||||||
|
this.areaAlarms.list = response.list || [];
|
||||||
|
this.areaAlarms.pagination.total = response.pagination?.total || 0;
|
||||||
|
} else {
|
||||||
|
const { currentPage, pageSize } = this.deviceAlarms.pagination;
|
||||||
|
const response = await AlarmApi.getDeviceThresholdAlarms({ page: currentPage, page_size: pageSize });
|
||||||
|
this.deviceAlarms.list = response.list || [];
|
||||||
|
this.deviceAlarms.pagination.total = response.pagination?.total || 0;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
this.$message.error('加载告警规则失败: ' + (error.message || '未知错误'));
|
||||||
|
console.error('加载告警规则失败:', error);
|
||||||
|
} finally {
|
||||||
|
this.loading = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 处理标签页切换事件
|
||||||
|
* @param {object} tab - 当前激活的tab对象
|
||||||
|
*/
|
||||||
|
handleTabClick(tab) {
|
||||||
|
// 重置分页到第一页
|
||||||
|
if (tab.paneName === 'area') {
|
||||||
|
this.areaAlarms.pagination.currentPage = 1;
|
||||||
|
} else {
|
||||||
|
this.deviceAlarms.pagination.currentPage = 1;
|
||||||
|
}
|
||||||
|
this.loadData(tab.paneName); // 显式传递paneName
|
||||||
|
},
|
||||||
|
handleSizeChange(newSize) {
|
||||||
|
const pagination = this.activeTab === 'area' ? this.areaAlarms.pagination : this.deviceAlarms.pagination;
|
||||||
|
pagination.pageSize = newSize;
|
||||||
|
this.loadData();
|
||||||
|
},
|
||||||
|
handlePageChange(newPage) {
|
||||||
|
const pagination = this.activeTab === 'area' ? this.areaAlarms.pagination : this.deviceAlarms.pagination;
|
||||||
|
pagination.currentPage = newPage;
|
||||||
|
this.loadData();
|
||||||
|
},
|
||||||
|
handleAddRule() {
|
||||||
|
this.isEdit = false;
|
||||||
|
this.resetForm();
|
||||||
|
this.dialogVisible = true;
|
||||||
|
},
|
||||||
|
handleEditRule(rule) {
|
||||||
|
this.isEdit = true;
|
||||||
|
this.form = { ...rule };
|
||||||
|
this.dialogVisible = true;
|
||||||
|
},
|
||||||
|
async handleDeleteRule(rule) {
|
||||||
|
try {
|
||||||
|
await this.$confirm('确认删除这条规则吗?', '提示', { type: 'warning' });
|
||||||
|
if (this.activeTab === 'area') {
|
||||||
|
await AlarmApi.deleteAreaThresholdAlarm(rule.id);
|
||||||
|
} else {
|
||||||
|
// 注意:设备告警删除接口需要 sensor_type
|
||||||
|
await AlarmApi.deleteDeviceThresholdAlarm(rule.id, { sensor_type: rule.sensor_type });
|
||||||
|
}
|
||||||
|
this.$message.success('删除成功');
|
||||||
|
await this.loadData();
|
||||||
|
} catch (error) {
|
||||||
|
if (error !== 'cancel') {
|
||||||
|
this.$message.error('删除失败: ' + (error.message || '未知错误'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async submitForm() {
|
||||||
|
try {
|
||||||
|
await this.$refs.ruleForm.validate();
|
||||||
|
const apiCall = this.isEdit ? this.updateRule : this.createRule;
|
||||||
|
await apiCall();
|
||||||
|
this.dialogVisible = false;
|
||||||
|
this.$message.success(this.isEdit ? '更新成功' : '创建成功');
|
||||||
|
} catch (error) {
|
||||||
|
if (error) { // validation error
|
||||||
|
console.log('表单验证失败');
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
await this.loadData();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async createRule() {
|
||||||
|
const { id, ...requestBody } = this.form;
|
||||||
|
if (this.activeTab === 'area') {
|
||||||
|
await AlarmApi.createAreaThresholdAlarm(requestBody);
|
||||||
|
} else {
|
||||||
|
await AlarmApi.createDeviceThresholdAlarm(requestBody);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async updateRule() {
|
||||||
|
const { id, ...requestBody } = this.form;
|
||||||
|
if (this.activeTab === 'area') {
|
||||||
|
await AlarmApi.updateAreaThresholdAlarm(id, requestBody);
|
||||||
|
} else {
|
||||||
|
await AlarmApi.updateDeviceThresholdAlarm(id, requestBody);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
resetForm() {
|
||||||
|
this.form = {
|
||||||
|
id: null,
|
||||||
|
area_controller_id: null,
|
||||||
|
device_id: null,
|
||||||
|
sensor_type: '',
|
||||||
|
level: '',
|
||||||
|
operator: '',
|
||||||
|
thresholds: 0,
|
||||||
|
};
|
||||||
|
if (this.$refs.ruleForm) {
|
||||||
|
this.$refs.ruleForm.resetFields();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
formatSensorType(type) {
|
||||||
|
return SensorType[type] || type;
|
||||||
|
},
|
||||||
|
formatSeverity(level) {
|
||||||
|
return SeverityLevel[level] || level;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.threshold-alarm-list {
|
||||||
|
padding: 20px;
|
||||||
|
max-width: 1200px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
.card-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.title-container {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 5px;
|
||||||
|
}
|
||||||
|
.page-title {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.refresh-btn {
|
||||||
|
color: black;
|
||||||
|
background-color: transparent;
|
||||||
|
padding: 0;
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
.pagination-container {
|
||||||
|
margin-top: 20px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Reference in New Issue
Block a user