feat(ems): 基础改造及相关页面功能

main
zangch@mesnac.com 3 months ago
parent df019a8f4b
commit 45878f8bf4

@ -1,5 +1,14 @@
import request from '@/utils/request';
import type { EmsActionResponse, EmsDetailResponse, EmsRecordAlarmDataVO, EmsId, EmsIdParam, EmsListResponse, EmsQuery } from '../types';
import type {
AlarmOverviewSummaryVO,
EmsActionResponse,
EmsDetailResponse,
EmsRecordAlarmDataVO,
EmsId,
EmsIdParam,
EmsListResponse,
EmsQuery
} from '../types';
// 查询异常数据记录列表
export function listRecordAlarmData(query?: EmsQuery): Promise<EmsListResponse<EmsRecordAlarmDataVO>> {
@ -18,6 +27,15 @@ export function getRecordAlarmData(objId: EmsId): Promise<EmsDetailResponse<EmsR
});
}
// 查询报警中心统计概览
export function getRecordAlarmDataSummary(query?: EmsQuery): Promise<EmsDetailResponse<AlarmOverviewSummaryVO>> {
return request({
url: '/ems/record/recordAlarmData/summary',
method: 'get',
params: query
});
}
// 新增异常数据记录
export function addRecordAlarmData(data: EmsRecordAlarmDataVO): Promise<EmsActionResponse<EmsRecordAlarmDataVO>> {
return request({

@ -214,6 +214,8 @@ export interface EmsEntity extends BaseEntity {
createdTime?: EmsDateValue;
updatedAt?: EmsDateValue;
updatedTime?: EmsDateValue;
createTime?: EmsDateValue;
updateTime?: EmsDateValue;
parentId?: EmsId;
parentName?: string;
orderNum?: number;
@ -563,6 +565,16 @@ export interface EmsRecordAlarmDataVO extends EmsEntity {
confirmRemark?: string;
}
export interface AlarmOverviewSummaryVO extends EmsEntity {
totalCount?: EmsId;
unhandledCount?: EmsId;
handledCount?: EmsId;
pushPendingCount?: EmsId;
pushProcessingCount?: EmsId;
pushSuccessCount?: EmsId;
pushFailCount?: EmsId;
}
export interface EmsRecordAlarmRuleVO extends EmsEntity {
objId?: EmsId;
ruleId?: string;
@ -592,6 +604,140 @@ export interface EmsRecordAlarmRuleVO extends EmsEntity {
isEnable?: string;
}
export interface AlarmNotifyGroupVO extends EmsEntity {
id?: EmsId;
groupName?: string;
notifyChannel?: string;
webhookUrl?: string;
isEnable?: string;
remark?: string;
createTime?: EmsDateValue;
}
export interface AlarmNotifyGroupUserVO extends EmsEntity {
id?: EmsId;
groupId?: EmsId;
groupName?: string;
userId?: EmsId;
userName?: string;
nickName?: string;
phone?: string;
email?: string;
isEnable?: string;
createTime?: EmsDateValue;
}
export interface AlarmPushLogVO extends EmsEntity {
id?: EmsId;
alarmObjId?: EmsId;
alarmTitle?: string;
monitorCode?: string;
monitorName?: string;
channelType?: string;
targetValue?: string;
alarmLevel?: string;
pushContent?: string;
pushStatus?: string;
responseMsg?: string;
pushTime?: EmsDateValue;
}
export interface MonitorMetricThresholdVO extends EmsEntity {
id?: EmsId;
monitorCode?: string;
monitorName?: string;
metricCode?: string;
warnUpper?: EmsDecimalValue;
warnLower?: EmsDecimalValue;
alarmUpper?: EmsDecimalValue;
alarmLower?: EmsDecimalValue;
hysteresis?: EmsDecimalValue;
durationSec?: EmsId;
alarmLevel?: string;
notifyGroupId?: EmsId;
notifyGroupName?: string;
isEnable?: string;
remark?: string;
createTime?: EmsDateValue;
}
export interface DataExportTaskVO extends EmsEntity {
id?: EmsId;
exportType?: string;
monitorCode?: string;
monitorName?: string;
metricCode?: string;
timeStart?: EmsDateValue;
timeEnd?: EmsDateValue;
exportCondition?: string;
fileFormat?: string;
fileName?: string;
fileUrl?: string;
exportStatus?: string;
remark?: string;
createTime?: EmsDateValue;
}
export interface IntegrationEndpointVO extends EmsEntity {
id?: EmsId;
endpointName?: string;
endpointType?: string;
accessMode?: string;
host?: string;
port?: EmsId;
configJson?: string;
status?: string;
createTime?: EmsDateValue;
}
export interface IntegrationPointMapVO extends EmsEntity {
id?: EmsId;
endpointId?: EmsId;
endpointName?: string;
monitorCode?: string;
monitorName?: string;
metricCode?: string;
sourcePointCode?: string;
targetPointCode?: string;
transformScript?: string;
dataFormat?: string;
isEnable?: string;
createTime?: EmsDateValue;
}
export interface ControlCommandLogVO extends EmsEntity {
id?: EmsId;
endpointId?: EmsId;
endpointName?: string;
monitorCode?: string;
monitorName?: string;
commandType?: string;
commandContent?: string;
executeStatus?: string;
responseContent?: string;
createTime?: EmsDateValue;
}
export interface ReportPeriodSummaryVO extends EmsEntity {
id?: EmsId;
monitorCode?: string;
monitorName?: string;
metricCode?: string;
metricName?: string;
periodType?: string;
periodStart?: EmsDateValue;
periodEnd?: EmsDateValue;
beginValue?: EmsDecimalValue;
endValue?: EmsDecimalValue;
avgValue?: EmsDecimalValue;
maxValue?: EmsDecimalValue;
minValue?: EmsDecimalValue;
consumeValue?: EmsDecimalValue;
overLimitDuration?: EmsId;
alarmCount?: EmsId;
sampleCount?: EmsId;
}
export interface EmsRecordDnbInstantVO extends EmsEntity {
objId?: EmsId;
monitorCode?: string;

@ -19,11 +19,26 @@ export const listUser = (query: UserQuery): AxiosPromise<UserVO[]> => {
/**
* ids
* @param userIds
*
* 1. ID Long[] userIds
* 2. ID便
*/
export const optionSelect = (userIds: (number | string)[]): AxiosPromise<UserVO[]> => {
export const optionSelect = (userIdsOrDeptId?: (number | string)[] | number | string, deptId?: number | string): AxiosPromise<UserVO[]> => {
const queryParts: string[] = [];
if (Array.isArray(userIdsOrDeptId)) {
if (userIdsOrDeptId.length > 0) {
queryParts.push('userIds=' + encodeURIComponent(userIdsOrDeptId.join(',')));
}
if (deptId !== undefined && deptId !== null && deptId !== '') {
queryParts.push('deptId=' + encodeURIComponent(String(deptId)));
}
} else if (userIdsOrDeptId !== undefined && userIdsOrDeptId !== null && userIdsOrDeptId !== '') {
queryParts.push('deptId=' + encodeURIComponent(String(userIdsOrDeptId)));
}
const url = queryParts.length > 0 ? `/system/user/optionselect?${queryParts.join('&')}` : '/system/user/optionselect';
return request({
url: '/system/user/optionselect?userIds=' + userIds,
url,
method: 'get'
});
};

@ -12,16 +12,16 @@
<el-form-item label="采集设备名称" prop="collectDeviceName">
<el-input v-model="queryParams.collectDeviceName" placeholder="请输入采集设备名称" clearable @keyup.enter="handleQuery" />
</el-form-item>
<!-- <el-form-item label="能源类型" prop="energyTypeId">-->
<!-- <el-select v-model="queryParams.energyTypeId" placeholder="请选择能源类型">-->
<!-- <el-option-->
<!-- v-for="item in energyTypeList"-->
<!-- :key="item.energyTypeId"-->
<!-- :label="item.energyName"-->
<!-- :value="item.energyTypeId"-->
<!-- ></el-option>-->
<!-- </el-select>-->
<!-- </el-form-item>-->
<el-form-item label="能源类型" prop="energyTypeId">
<el-select v-model="queryParams.energyTypeId" placeholder="请选择能源类型" clearable>
<el-option
v-for="item in energyTypeList"
:key="item.energyTypeId"
:label="item.energyName"
:value="item.energyTypeId"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="启用标识" prop="isFlag">
<el-select v-model="queryParams.isFlag" placeholder="请选择启用标识" clearable>
<el-option v-for="dict in dict.type.is_flag" :key="dict.value" :label="dict.label" :value="dict.value" />
@ -79,7 +79,7 @@
<el-table v-loading="loading" :data="baseCollectDeviceInfoList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="自增标识" align="center" prop="objId" v-if="columns[0].visible" />
<el-table-column label="序号" type="index" width="60" align="center" v-if="columns[0].visible" />
<el-table-column label="采集设备编号" align="center" prop="collectDeviceId" v-if="columns[1].visible" />
<el-table-column label="采集设备名称" align="center" prop="collectDeviceName" v-if="columns[2].visible" />
<el-table-column label="能源类型" align="center" prop="energyTypeName" v-if="columns[3].visible" />
@ -126,16 +126,16 @@
<el-form-item label="采集设备名称" prop="collectDeviceName">
<el-input v-model="form.collectDeviceName" placeholder="请输入采集设备名称" />
</el-form-item>
<!-- <el-form-item label="能源类型" prop="energyTypeId">-->
<!-- <el-select v-model="form.energyTypeId" placeholder="请选择能源类型编号">-->
<!-- <el-option-->
<!-- v-for="item in energyTypeList"-->
<!-- :key="item.energyTypeId"-->
<!-- :label="item.energyName"-->
<!-- :value="item.energyTypeId"-->
<!-- ></el-option>-->
<!-- </el-select>-->
<!-- </el-form-item>-->
<el-form-item label="能源类型" prop="energyTypeId">
<el-select v-model="form.energyTypeId" placeholder="请选择能源类型" style="width: 100%">
<el-option
v-for="item in energyTypeList"
:key="item.energyTypeId"
:label="item.energyName"
:value="item.energyTypeId"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="型号" prop="model">
<el-input v-model="form.model" placeholder="请输入型号" />
</el-form-item>
@ -356,16 +356,16 @@ const createFormData = (): BaseCollectDeviceInfoForm => ({
const form = ref<BaseCollectDeviceInfoForm>(createFormData());
const rules = reactive<ElFormRules>({
objId: [{ required: true, message: '自增标识不能为空', trigger: 'blur' }],
collectDeviceId: [{ required: true, message: '采集设备编号不能为空', trigger: 'blur' }],
collectDeviceName: [{ required: true, message: '采集设备名称不能为空', trigger: 'blur' }]
collectDeviceName: [{ required: true, message: '采集设备名称不能为空', trigger: 'blur' }],
energyTypeId: [{ required: true, message: '能源类型不能为空', trigger: 'change' }]
});
const columns: FieldOption[] = [
{ key: 0, label: '自增标识', visible: false },
{ key: 0, label: '序号', visible: true },
{ key: 1, label: '采集设备编号', visible: true },
{ key: 2, label: '采集设备名称', visible: true },
{ key: 3, label: '能源类型', visible: false },
{ key: 3, label: '能源类型', visible: true },
{ key: 4, label: '型号', visible: true },
{ key: 5, label: '生产厂家', visible: true },
{ key: 6, label: '通讯地址', visible: true },
@ -390,7 +390,7 @@ const getList = async () => {
/** 查询能源类型下拉选项,避免页面初始化时出现空白下拉 */
const getEnergyTypeList = async () => {
const response = await getBaseEnergyTypeList({});
energyTypeList.value = (response.rows ?? []) as EnergyTypeOption[];
energyTypeList.value = ((response.data ?? response.rows ?? []) as EnergyTypeOption[]) || [];
};
//

@ -63,7 +63,7 @@
:default-expand-all="isExpandAll"
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
>
<el-table-column label="父级编号" prop="parentId" v-if="columns[0].visible" />
<el-table-column label="序号" type="index" width="60" align="center" v-if="columns[0].visible" />
<el-table-column label="计量设备编号" align="center" prop="monitorCode" v-if="columns[1].visible" />
<el-table-column label="计量设备名称" align="center" prop="monitorName" v-if="columns[2].visible" />
<!-- <el-table-column label="能源类型" align="center" prop="monitorType" v-if="columns[4].visible">
@ -590,8 +590,8 @@ const state = reactive({
// { key: 0, label: ``, visible: false },
{
key: 0,
label: `父级编`,
visible: false
label: ``,
visible: true
},
{
key: 1,

@ -1,104 +1,86 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryFormRef" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="关联的报警规则ID (逻辑关联 ems_record_alarm_rule.obj_id)" prop="ruleObjId">
<el-input
v-model="queryParams.ruleObjId"
placeholder="请输入关联的报警规则ID (逻辑关联 ems_record_alarm_rule.obj_id)"
clearable
@keyup.enter="handleQuery"
/>
<el-form :model="queryParams" ref="queryFormRef" size="small" :inline="true" v-show="showSearch" label-width="88px">
<el-form-item label="关联规则" prop="ruleObjId">
<el-select v-model="queryParams.ruleObjId" placeholder="请选择关联规则" clearable filterable style="width: 260px">
<el-option v-for="item in recordAlarmRuleList" :key="item.objId" :label="item.ruleName" :value="item.objId" />
</el-select>
</el-form-item>
<el-form-item label="步骤顺序从1开始" prop="stepSequence">
<el-input v-model="queryParams.stepSequence" placeholder="请输入步骤顺序从1开始" clearable @keyup.enter="handleQuery" />
<el-form-item label="步骤顺序" prop="stepSequence">
<el-input-number v-model="queryParams.stepSequence" :min="1" :precision="0" controls-position="right" style="width: 180px" />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"></el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"></el-button>
<el-button type="primary" icon="el-icon-search" size="small" @click="handleQuery"></el-button>
<el-button icon="el-icon-refresh" size="small" @click="resetQuery"></el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd" v-hasPermi="['ems/base:emsAlarmActionStep:add']"
>新增</el-button
>
<el-button type="primary" plain icon="el-icon-plus" size="small" @click="handleAdd" v-hasPermi="['ems/base:emsAlarmActionStep:add']"></el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['ems/base:emsAlarmActionStep:edit']"
>修改</el-button
>
<el-button type="success" plain icon="el-icon-edit" size="small" :disabled="single" @click="handleUpdate" v-hasPermi="['ems/base:emsAlarmActionStep:edit']">
修改
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
size="small"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['ems/base:emsAlarmActionStep:remove']"
>删除</el-button
>
删除
</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport" v-hasPermi="['ems/base:emsAlarmActionStep:export']"
>导出</el-button
>
<el-button type="warning" plain icon="el-icon-download" size="small" @click="handleExport" v-hasPermi="['ems/base:emsAlarmActionStep:export']">
导出
</el-button>
</el-col>
<right-toolbar v-model:show-search="showSearch" @query-table="getList"></right-toolbar>
<right-toolbar v-model:show-search="showSearch" :columns="columns" @query-table="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="emsAlarmActionStepList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="主键ID" align="center" prop="objId" />
<el-table-column label="关联的报警规则ID (逻辑关联 ems_record_alarm_rule.obj_id)" align="center" prop="ruleObjId"> </el-table-column>
<el-table-column label="步骤顺序从1开始" align="center" prop="stepSequence"> </el-table-column>
<el-table-column label="步骤文字描述" align="center" prop="description"> </el-table-column>
<el-table-column label="备注" align="center" prop="remark"> </el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<el-table-column v-if="columns[0].visible" label="序号" type="index" width="60" align="center" />
<el-table-column v-if="columns[1].visible" label="关联规则" align="center" min-width="220" show-overflow-tooltip>
<template #default="scope">
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" v-hasPermi="['ems/base:emsAlarmActionStep:edit']"
>修改</el-button
>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['ems/base:emsAlarmActionStep:remove']"
>删除</el-button
>
{{ resolveRuleName(scope.row.ruleObjId) }}
</template>
</el-table-column>
<el-table-column v-if="columns[2].visible" label="步骤顺序" align="center" prop="stepSequence" width="120" />
<el-table-column v-if="columns[3].visible" label="步骤描述" align="center" prop="description" min-width="260" show-overflow-tooltip />
<el-table-column v-if="columns[4].visible" label="备注" align="center" prop="remark" min-width="220" show-overflow-tooltip />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="100">
<template #default="scope">
<el-button size="small" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" v-hasPermi="['ems/base:emsAlarmActionStep:edit']"></el-button>
<el-button size="small" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" v-hasPermi="['ems/base:emsAlarmActionStep:remove']"></el-button>
</template>
</el-table-column>
</el-table>
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
<!-- 添加或修改报警规则具体措施步骤对话框 -->
<el-dialog :title="title" v-model="open" width="500px" append-to-body>
<el-form ref="formRef" :model="form" :rules="rules" label-width="80px">
<el-form-item label="关联的报警规则ID (逻辑关联 ems_record_alarm_rule.obj_id)" prop="ruleObjId">
<!-- <el-input v-model="form.ruleObjId" placeholder="请输入关联的报警规则ID (逻辑关联 ems_record_alarm_rule.obj_id)" /> -->
<el-select v-model="form.ruleObjId" placeholder="请选择关联的报警规则ID (逻辑关联 ems_record_alarm_rule.obj_id)">
<el-dialog :title="title" v-model="open" width="560px" append-to-body>
<el-form ref="formRef" :model="form" :rules="rules" label-width="96px">
<el-form-item label="关联规则" prop="ruleObjId">
<el-select v-model="form.ruleObjId" placeholder="请选择关联规则" filterable style="width: 100%">
<el-option v-for="item in recordAlarmRuleList" :key="item.objId" :label="item.ruleName" :value="item.objId" />
</el-select>
</el-form-item>
<el-form-item label="步骤顺序从1开始" prop="stepSequence">
<el-input v-model="form.stepSequence" placeholder="请输入步骤顺序从1开始" />
<el-form-item label="步骤顺序" prop="stepSequence">
<el-input-number v-model="form.stepSequence" :min="1" :precision="0" controls-position="right" style="width: 100%" />
</el-form-item>
<el-form-item label="步骤文字描述" prop="description">
<el-input v-model="form.description" type="textarea" placeholder="请输入内容" />
<el-form-item label="步骤描述" prop="description">
<el-input v-model="form.description" type="textarea" :rows="4" placeholder="请输入步骤描述" />
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
<el-input v-model="form.remark" type="textarea" :rows="3" placeholder="请输入备注" />
</el-form-item>
</el-form>
<template #footer>
@ -112,14 +94,9 @@
</template>
<script setup lang="ts">
import {
listEmsAlarmActionStep,
getEmsAlarmActionStep,
delEmsAlarmActionStep,
addEmsAlarmActionStep,
updateEmsAlarmActionStep
} from '@/api/ems/base/emsAlarmActionStep';
import { listEmsAlarmActionStep, getEmsAlarmActionStep, delEmsAlarmActionStep, addEmsAlarmActionStep, updateEmsAlarmActionStep } from '@/api/ems/base/emsAlarmActionStep';
import { getEmsRecordAlarmRuleList } from '@/api/ems/record/recordAlarmRule';
import type { EmsAlarmActionStepVO, EmsRecordAlarmRuleVO } from '@/api/ems/types';
defineOptions({
name: 'EmsAlarmActionStep'
@ -130,11 +107,18 @@ const { proxy } = getCurrentInstance() as any;
const formRef = ref<any>();
const queryFormRef = ref<any>();
// /
const columns = ref<FieldOption[]>([
{ key: 0, label: '序号', visible: true, children: [] },
{ key: 1, label: '关联规则', visible: true, children: [] },
{ key: 2, label: '步骤顺序', visible: true, children: [] },
{ key: 3, label: '步骤描述', visible: true, children: [] },
{ key: 4, label: '备注', visible: true, children: [] }
]);
const createFormData = () => ({
objId: null,
ruleObjId: null,
stepSequence: null,
stepSequence: 1,
description: null,
createBy: null,
createTime: null,
@ -143,29 +127,17 @@ const createFormData = () => ({
remark: null
});
// EMS
const state = reactive({
//
loading: true,
//
ids: [],
//
recordAlarmRuleList: [],
//
recordAlarmRuleList: [] as EmsRecordAlarmRuleVO[],
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
emsAlarmActionStepList: [],
//
emsAlarmActionStepList: [] as EmsAlarmActionStepVO[],
title: '',
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
@ -173,42 +145,31 @@ const state = reactive({
stepSequence: null,
description: null
},
//
form: createFormData(),
//
rules: {
ruleObjId: [
{
required: true,
message: '关联的报警规则ID (逻辑关联 ems_record_alarm_rule.obj_id)不能为空',
trigger: 'blur'
}
],
stepSequence: [
{
required: true,
message: '步骤顺序从1开始不能为空',
trigger: 'blur'
}
]
ruleObjId: [{ required: true, message: '关联规则不能为空', trigger: 'change' }],
stepSequence: [{ required: true, message: '步骤顺序不能为空', trigger: 'blur' }],
description: [{ required: true, message: '步骤描述不能为空', trigger: 'blur' }]
}
} as any);
const { emsAlarmActionStepList, form, ids, loading, multiple, open, queryParams, recordAlarmRuleList, rules, showSearch, single, title, total } =
toRefs(state);
const { emsAlarmActionStepList, form, ids, loading, multiple, open, queryParams, recordAlarmRuleList, rules, showSearch, single, title, total } = toRefs(state);
const resolveRuleName = (ruleObjId?: string | number) =>
recordAlarmRuleList.value.find((item) => item.objId === ruleObjId)?.ruleName || (ruleObjId ? String(ruleObjId) : '-');
const getList = () => {
loading.value = true;
listEmsAlarmActionStep(queryParams.value).then((response) => {
emsAlarmActionStepList.value = response.rows;
total.value = response.total;
emsAlarmActionStepList.value = response.rows ?? [];
total.value = response.total ?? 0;
loading.value = false;
});
};
const getRecordAlarmRuleList = () => {
const loadRuleOptions = () => {
getEmsRecordAlarmRuleList().then((response) => {
recordAlarmRuleList.value = response.data;
recordAlarmRuleList.value = (response.data ?? response.rows ?? []) as EmsRecordAlarmRuleVO[];
});
};
@ -218,17 +179,7 @@ const cancel = () => {
};
const reset = () => {
form.value = {
objId: null,
ruleObjId: null,
stepSequence: null,
description: null,
createBy: null,
createTime: null,
updateBy: null,
updateTime: null,
remark: null
};
form.value = createFormData();
formRef.value?.resetFields();
};
@ -256,36 +207,43 @@ const handleAdd = () => {
const handleUpdate = (row) => {
reset();
const objId = row.objId || ids.value;
const objId = row?.objId || ids.value[0];
if (!objId) {
return;
}
getEmsAlarmActionStep(objId).then((response) => {
form.value = response.data;
form.value = {
...createFormData(),
...(response.data ?? {})
};
open.value = true;
title.value = '修改报警规则具体措施步骤';
});
};
const submitForm = () => {
formRef.value.validate((valid) => {
if (valid) {
if (form.value.objId != null) {
updateEmsAlarmActionStep(form.value).then((response) => {
proxy?.$modal.msgSuccess('修改成功');
open.value = false;
getList();
});
} else {
addEmsAlarmActionStep(form.value).then((response) => {
proxy?.$modal.msgSuccess('新增成功');
open.value = false;
getList();
});
}
formRef.value?.validate((valid) => {
if (!valid) {
return;
}
if (form.value.objId != null) {
updateEmsAlarmActionStep(form.value).then(() => {
proxy?.$modal.msgSuccess('修改成功');
open.value = false;
getList();
});
return;
}
addEmsAlarmActionStep(form.value).then(() => {
proxy?.$modal.msgSuccess('新增成功');
open.value = false;
getList();
});
});
};
const handleDelete = (row) => {
const objIds = row.objId || ids.value;
const objIds = row?.objId || ids.value;
proxy?.$modal
.confirm('是否确认删除报警规则具体措施步骤编号为"' + objIds + '"的数据项?')
.then(function () {
@ -310,6 +268,6 @@ const handleExport = () => {
onMounted(() => {
getList();
getRecordAlarmRuleList();
loadRuleOptions();
});
</script>

File diff suppressed because it is too large Load Diff

@ -68,39 +68,32 @@
<el-table v-loading="loading" :data="recordAlarmRuleList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="自增标识" align="center" prop="objId" v-if="columns[0].visible" />
<el-table-column label="规则编号" align="center" prop="ruleId" v-if="columns[1].visible" />
<el-table-column label="规则名称" align="center" prop="ruleName" v-if="columns[2].visible" />
<el-table-column label="计量设备" align="center" prop="monitorName" v-if="columns[3].visible" />
<el-table-column label="记录时间" align="center" prop="collectTime" width="180" v-if="columns[4].visible">
<template #default="scope">
<span>{{ parseTime(scope.row.collectTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
</template>
</el-table-column>
<el-table-column label="能源类型" align="center" prop="energyType" v-if="columns[5].visible" />
<el-table-column label="触发规则" align="center" prop="triggerRule" v-if="columns[6].visible">
<el-table-column label="序号" type="index" width="60" align="center" v-if="columns[0].visible" />
<el-table-column label="规则名称" align="center" prop="ruleName" v-if="columns[1].visible" />
<el-table-column label="计量设备" align="center" prop="monitorName" v-if="columns[2].visible" />
<el-table-column label="触发规则" align="center" prop="triggerRule" v-if="columns[3].visible">
<template #default="scope">
<dict-tag :options="dict.type.trigger_rule" :value="scope.row.triggerRule" />
</template>
</el-table-column>
<el-table-column label="监测字段" align="center" prop="monitorField" v-if="columns[7].visible">
<el-table-column label="监测字段" align="center" prop="monitorField" v-if="columns[4].visible">
<template #default="scope">
<dict-tag :options="dict.type.monitor_field" :value="scope.row.monitorField" />
</template>
</el-table-column>
<el-table-column label="告警上限" align="center" prop="alarmUpper" v-if="columns[8].visible" />
<el-table-column label="告警下限" align="center" prop="alarmLower" v-if="columns[9].visible" />
<el-table-column label="恢复上限" align="center" prop="recoverUpper" v-if="columns[10].visible" />
<el-table-column label="恢复下限" align="center" prop="recoverLower" v-if="columns[11].visible" />
<el-table-column label="回差" align="center" prop="hysteresis" v-if="columns[12].visible" />
<el-table-column label="持续秒数" align="center" prop="durationSec" v-if="columns[13].visible" />
<el-table-column label="告警级别" align="center" prop="alarmLevel" v-if="columns[14].visible" />
<el-table-column label="启用状态" align="center" prop="isEnable" v-if="columns[15].visible">
<el-table-column label="告警上限" align="center" prop="alarmUpper" v-if="columns[5].visible" />
<el-table-column label="告警下限" align="center" prop="alarmLower" v-if="columns[6].visible" />
<el-table-column label="恢复上限" align="center" prop="recoverUpper" v-if="columns[7].visible" />
<el-table-column label="恢复下限" align="center" prop="recoverLower" v-if="columns[8].visible" />
<el-table-column label="回差" align="center" prop="hysteresis" v-if="columns[9].visible" />
<el-table-column label="持续秒数" align="center" prop="durationSec" v-if="columns[10].visible" />
<el-table-column label="告警级别" align="center" prop="alarmLevel" v-if="columns[11].visible" />
<el-table-column label="启用状态" align="center" prop="isEnable" v-if="columns[12].visible">
<template #default="scope">
<dict-tag :options="dict.type.is_flag" :value="scope.row.isEnable" />
</template>
</el-table-column>
<el-table-column label="备注" align="center" prop="cause" v-if="columns[16].visible" />
<el-table-column label="备注" align="center" prop="cause" v-if="columns[13].visible" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="150">
<template #default="scope">
<el-button
@ -437,86 +430,71 @@ const state = reactive({
columns: [
{
key: 0,
label: `自增标识`,
visible: false
label: `序号`,
visible: true
},
{
key: 1,
label: `规则编号`,
visible: false
},
{
key: 2,
label: `规则名称`,
visible: true
},
{
key: 3,
key: 2,
label: `计量设备`,
visible: true
},
{
key: 4,
label: `记录时间`,
visible: false
},
{
key: 5,
label: `能源类型`,
visible: false
},
{
key: 6,
key: 3,
label: `触发规则`,
visible: true
},
{
key: 7,
key: 4,
label: `监测字段`,
visible: true
},
{
key: 8,
key: 5,
label: `告警上限`,
visible: true
},
{
key: 9,
key: 6,
label: `告警下限`,
visible: true
},
{
key: 10,
key: 7,
label: `恢复上限`,
visible: true
},
{
key: 11,
key: 8,
label: `恢复下限`,
visible: true
},
{
key: 12,
key: 9,
label: `回差`,
visible: true
},
{
key: 13,
key: 10,
label: `持续秒数`,
visible: true
},
{
key: 14,
key: 11,
label: `告警级别`,
visible: true
},
{
key: 15,
key: 12,
label: `启用状态`,
visible: true
},
{
key: 16,
key: 13,
label: `备注`,
visible: true
}

@ -189,7 +189,7 @@
<el-table-column type="selection" width="55" align="center" />
<!-- <el-table-column label="主键标识" align="center" prop="objid" v-if="columns[0].visible"/>-->
<el-table-column label="序号" type="index" width="55" align="center" v-if="columns[0].visible" />
<el-table-column label="计量设备编号" align="center" prop="monitorId" v-if="columns[1].visible"> </el-table-column>
<el-table-column label="点位名称" align="center" prop="monitorName" v-if="columns[1].visible"> </el-table-column>
<el-table-column label="温度" align="center" prop="temperature" v-if="columns[2].visible"> </el-table-column>
<el-table-column label="湿度" align="center" prop="humidity" v-if="columns[3].visible"> </el-table-column>
<el-table-column label="照度" align="center" prop="illuminance" v-if="columns[4].visible"> </el-table-column>
@ -230,35 +230,43 @@
<!-- 添加或修改物联网数据对话框 -->
<el-dialog :title="title" v-model="open" width="500px" append-to-body>
<el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
<el-form-item label="计量设备编号" prop="monitorId">
<el-input v-model="form.monitorId" placeholder="请输入计量设备编号" />
<el-form-item label="点位名称" prop="monitorId">
<el-tree-select
v-model="form.monitorId"
:data="monitorInfoOptions"
:props="monitorProps"
placeholder="请选择点位"
filterable
check-strictly
style="width: 100%"
/>
</el-form-item>
<el-form-item label="温度" prop="temperature">
<el-input v-model="form.temperature" placeholder="请输入温度" />
<el-input-number v-model="form.temperature" :precision="4" controls-position="right" style="width: 100%" />
</el-form-item>
<el-form-item label="湿度" prop="humidity">
<el-input v-model="form.humidity" placeholder="请输入湿度" />
<el-input-number v-model="form.humidity" :precision="4" controls-position="right" style="width: 100%" />
</el-form-item>
<el-form-item label="照度" prop="illuminance">
<el-input v-model="form.illuminance" placeholder="请输入照度" />
<el-input-number v-model="form.illuminance" :precision="4" controls-position="right" style="width: 100%" />
</el-form-item>
<el-form-item label="噪声" prop="noise">
<el-input v-model="form.noise" placeholder="请输入噪声" />
<el-input-number v-model="form.noise" :precision="4" controls-position="right" style="width: 100%" />
</el-form-item>
<el-form-item label="硫化氢浓度" prop="concentration">
<el-input v-model="form.concentration" placeholder="请输入硫化氢浓度" />
<el-input-number v-model="form.concentration" :precision="4" controls-position="right" style="width: 100%" />
</el-form-item>
<el-form-item label="振动-速度(mm/s)" prop="vibrationSpeed">
<el-input v-model="form.vibrationSpeed" placeholder="请输入振动-速度(mm/s)" />
<el-input-number v-model="form.vibrationSpeed" :precision="4" controls-position="right" style="width: 100%" />
</el-form-item>
<el-form-item label="振动-位移(um)" prop="vibrationDisplacement">
<el-input v-model="form.vibrationDisplacement" placeholder="请输入振动-位移(um)" />
<el-input-number v-model="form.vibrationDisplacement" :precision="4" controls-position="right" style="width: 100%" />
</el-form-item>
<el-form-item label="振动-加速度(g)" prop="vibrationAcceleration">
<el-input v-model="form.vibrationAcceleration" placeholder="请输入振动-加速度(g)" />
<el-input-number v-model="form.vibrationAcceleration" :precision="4" controls-position="right" style="width: 100%" />
</el-form-item>
<el-form-item label="振动-温度(℃)" prop="vibrationTemp">
<el-input v-model="form.vibrationTemp" placeholder="请输入振动-温度(℃)" />
<el-input-number v-model="form.vibrationTemp" :precision="4" controls-position="right" style="width: 100%" />
</el-form-item>
<el-form-item label="采集时间" prop="collectTime">
<el-date-picker clearable v-model="form.collectTime" type="date" value-format="yyyy-MM-dd" placeholder="请选择采集时间"> </el-date-picker>
@ -375,12 +383,12 @@ const state = reactive({
columns: [
{
key: 0,
label: `标识`,
label: `序号`,
visible: true
},
{
key: 1,
label: `计量设备编号`,
label: `点位名称`,
visible: true
},
{
@ -597,7 +605,7 @@ const handleUpdate = (row) => {
};
const submitForm = () => {
form.value.validate((valid) => {
formRef.value?.validate((valid) => {
if (valid) {
if (form.value.objid != null) {
updateRecordIotenvInstant(form.value).then((response) => {

@ -1,594 +0,0 @@
<template>
<div class="app-container">
<el-row :gutter="28">
<el-col :span="5" :xs="24">
<div class="head-container">
<el-input
v-model="workUnitName"
placeholder="请输入物联网设备名称"
clearable
size="small"
prefix-icon="el-icon-search"
style="margin-bottom: 20px"
/>
</div>
<div class="head-container">
<el-tree
:data="monitorInfoOptions"
:props="monitorProps"
:expand-on-click-node="false"
:filter-node-method="filterNode"
ref="tree"
node-key="id"
default-expand-all
highlight-current
@node-click="handleNodeClick"
/>
</div>
</el-col>
<el-col :span="19" :xs="24">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="100px">
<!-- <el-form-item label="计量设备编号" prop="monitorCode">-->
<!-- <el-input-->
<!-- v-model="queryParams.monitorCode"-->
<!-- placeholder="请输入计量设备编号"-->
<!-- clearable-->
<!-- @keyup.enter="handleQuery"-->
<!-- />-->
<!-- </el-form-item>-->
<el-form-item label="记录时间">
<el-date-picker
v-model="daterangeRecordTime"
style="width: 340px"
value-format="yyyy-MM-dd HH:mm:ss"
type="datetimerange"
range-separator="-"
start-placeholder="开始时间"
end-placeholder="结束时间"
></el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"></el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"></el-button>
</el-form-item>
</el-form>
<Chart ref="Chart1" class="chart1" />
<!-- <Chart ref="Chart2" class="chart2"/> -->
</el-col>
</el-row>
</div>
</template>
<script setup lang="ts">
import { useDict } from '@/utils/dict';
import { listRecordIOTInstant, getRecordIOTInstant, iotInstantList } from '@/api/ems/record/recordIOTInstant';
import { getMonitorInfoTree } from '@/api/ems/base/baseMonitorInfo';
import { parseTime } from '@/utils/ruoyi';
import Chart from '@/components/Charts/Chart';
import * as echarts from 'echarts';
defineOptions({
name: 'CurrentIOTCurve',
dicts: ['collect_type']
} as any);
const { proxy } = getCurrentInstance() as any;
const dict = reactive({
type: useDict('collect_type') as any
});
const Chart1 = ref<any>();
const Chart2 = ref<any>();
const queryForm = ref<any>();
const tree = ref<any>();
// /
const createFormData = () => ({
objId: null,
monitorId: null,
collectTime: null,
recordTime: null,
collectType: 1
});
// EMS
const state = reactive({
//List
baseMonitorInfoOptions: [],
//List
monitorInfoOptions: [],
workUnitName: undefined,
//
selectMonitorName: null,
//
baseMonitorInfoList: [],
//
daterangeRecordTime: [],
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
dataList: [],
//
title: '',
//
open: false,
//
queryParams: {
monitorId: null,
collectTime: null,
tempreture: null,
humidity: null,
illuminance: null,
noise: null,
concentration: null,
recordTime: null,
glys: null,
zxyg: null,
activePower: null,
reactivePower: null,
collectType: null
},
//
form: createFormData(),
monitorProps: {
children: 'children',
label: 'label'
},
//
rules: {
objId: [
{
required: true,
message: '编号不能为空',
trigger: 'blur'
}
]
},
columns: [
{
key: 0,
label: `主键标识`,
visible: false
},
{
key: 1,
label: `计量设备编号`,
visible: true
},
{
key: 2,
label: `采集时间`,
visible: true
},
{
key: 3,
label: `温度`,
visible: true
},
{
key: 4,
label: `湿度`,
visible: true
},
{
key: 5,
label: `照度`,
visible: true
},
{
key: 6,
label: `噪声`,
visible: true
},
{
key: 7,
label: `硫化氢浓度`,
visible: true
},
{
key: 8,
label: `记录时间`,
visible: true
},
{
key: 9,
label: `报警类型`,
visible: true
},
{
key: 10,
label: ``,
visible: true
},
{
key: 11,
label: ``,
visible: false
},
{
key: 12,
label: ``,
visible: false
},
{
key: 13,
label: ``,
visible: true
},
{
key: 14,
label: ``,
visible: true
}
]
} as any);
const {
baseMonitorInfoList,
baseMonitorInfoOptions,
columns,
dataList,
daterangeRecordTime,
form,
ids,
loading,
monitorInfoOptions,
monitorProps,
multiple,
open,
queryParams,
rules,
selectMonitorName,
showSearch,
single,
title,
total,
workUnitName
} = toRefs(state);
const normalizer = (node) => {
if (node.children && !node.children.length) {
delete node.children;
}
return {
id: node.monitorId,
label: node.monitorName,
children: node.children
};
};
const getList = () => {
loading.value = true;
queryParams.value.params = {};
if (null != daterangeRecordTime.value && '' != daterangeRecordTime.value) {
queryParams.value.params['beginRecordTime'] = daterangeRecordTime.value[0];
queryParams.value.params['endRecordTime'] = daterangeRecordTime.value[1];
}
console.log(monitorInfoOptions.value);
getChart();
};
const cancel = () => {
open.value = false;
reset();
};
const reset = () => {
form.value = {
objId: null,
monitorId: null,
collectTime: null,
recordTime: null,
collectType: 1
};
form.value?.resetFields();
};
const handleQuery = () => {
getList();
};
const resetQuery = () => {
queryParams.value.monitorId = null;
queryForm.value?.resetFields();
handleQuery();
};
const handleExport = () => {
proxy?.download(
'ems/record/recordIOTInstant/export',
{
...queryParams.value
},
`recordIOTInstant_${new Date().getTime()}.xlsx`
);
};
const getTreeselect = () => {
getMonitorInfoTree({
monitorTypeList: [5, 6, 7, 8, 9]
}).then((response) => {
monitorInfoOptions.value = response.data;
});
};
const filterNode = (value, data) => {
if (!value) return true;
return data.label.indexOf(value) !== -1;
};
const handleNodeClick = (data, type, a) => {
console.log(type.parent.data);
console.log(a);
// queryParams.value.monitorTypeList = type
queryParams.value.monitorId = data.code;
selectMonitorName.value = data.label;
handleQuery();
};
const getChart = async () => {
if (queryParams.value.monitorId == null) {
return;
}
const query = JSON.parse(JSON.stringify(queryParams.value));
const { data } = await iotInstantList(query);
const option1 = {
title: {
text: '物联网设备曲线',
// selectMonitorName.value
x: 'center'
},
legend: {
data: data.monitorTypeArr,
right: 0
},
grid: {
top: '15%',
bottom: '10%',
left: '3%',
right: '3%'
},
tooltip: {
trigger: 'axis'
// axisPointer: {
// type: 'shadow',
// label: {
// show: true
// }
// }
},
dataZoom: [
{
type: 'slider'
}
],
xAxis: {
data: data.dataList.map((e) => e.collectTime),
axisLine: {
show: true,
//X线
lineStyle: {
color: '#000'
}
},
// axisTick: {
// show: true //X
// },
axisLabel: {
show: true,
textStyle: {
color: '#000' //X
}
}
},
yAxis: [
{
type: 'value',
name: '数值',
nameTextStyle: {
color: '#000'
},
splitLine: {
show: false
},
axisTick: {
show: true
},
axisLine: {
show: true,
lineStyle: {
color: '#000'
}
},
axisLabel: {
show: true,
textStyle: {
color: '#000'
}
}
}
],
series: [
{
tooltip: {
show: data.monitorTypeArr.includes('温度') ? true : false
},
name: '温度',
type: data.type,
smooth: data.smooth,
//线
showAllSymbol: data.showAllSymbol,
//
symbol: data.symbol,
//
symbolSize: data.symbolSize,
//
// itemStyle: {
// //线
// color: "#058cff",
// },
// lineStyle: {
// color: "#058cff",
// },
// areaStyle: {
// color: "rgba(5,140,255, 0.2)",
// },
data: data.monitorTypeArr.includes('温度') ? data.dataList.map((e) => e.tempreture) : []
},
{
tooltip: {
show: data.monitorTypeArr.includes('湿度') ? true : false
},
name: '湿度',
type: data.type,
smooth: data.smooth,
//线
showAllSymbol: data.showAllSymbol,
//
symbol: data.symbol,
//
symbolSize: data.symbolSize,
//
// itemStyle: {
// //线
// color: "#058cff",
// },
// lineStyle: {
// color: "#058cff",
// },
// areaStyle: {
// color: "rgba(5,140,255, 0.2)",
// },
data: data.monitorTypeArr.includes('湿度') ? data.dataList.map((e) => e.humidity) : []
},
{
tooltip: {
show: data.monitorTypeArr.includes('噪声') ? true : false
},
name: '噪声',
type: data.type,
smooth: data.smooth,
//线
showAllSymbol: data.showAllSymbol,
//
symbol: data.symbol,
//
symbolSize: data.symbolSize,
//
// itemStyle: {
// //线
// color: "#058cff",
// },
// lineStyle: {
// color: "#058cff",
// },
// areaStyle: {
// color: "rgba(5,140,255, 0.2)",
// },
data: data.monitorTypeArr.includes('噪声') ? data.dataList.map((e) => e.noise) : []
},
{
tooltip: {
show: data.monitorTypeArr.includes('照度') ? true : false
},
name: '照度',
type: data.type,
smooth: data.smooth,
//线
showAllSymbol: data.showAllSymbol,
//
symbol: data.symbol,
//
symbolSize: data.symbolSize,
//
// itemStyle: {
// //线
// color: "#058cff",
// },
// lineStyle: {
// color: "#058cff",
// },
// areaStyle: {
// color: "rgba(5,140,255, 0.2)",
// },
data: data.monitorTypeArr.includes('照度') ? data.dataList.map((e) => e.illuminance) : []
},
{
tooltip: {
show: data.monitorTypeArr.includes('气体浓度') ? true : false
},
name: '气体浓度',
type: data.type,
smooth: data.smooth,
//线
showAllSymbol: data.showAllSymbol,
//
symbol: data.symbol,
//
symbolSize: data.symbolSize,
//
// itemStyle: {
// //线
// color: "#058cff",
// },
// lineStyle: {
// color: "#058cff",
// },
// areaStyle: {
// color: "rgba(5,140,255, 0.2)",
// },
data: data.monitorTypeArr.includes('气体浓度') ? data.dataList.map((e) => e.concentration) : []
}
]
};
console.log(option1);
Chart1.value.setData(option1);
echarts.connect(Chart1.value.chart);
// , Chart2.value.chart
Chart1.value.chart.on('datazoom', (e) => {
option1.dataZoom[0].start = e.start;
option1.dataZoom[0].end = e.end;
Chart1.value.setData(option1);
});
// Chart2.value.chart.on('datazoom', (e) => {
// option1.dataZoom[0].start = e.start
// option1.dataZoom[0].end = e.end
// Chart1.value.setData(option1)
// })
};
watch(workUnitName, (val) => {
tree.value.filter(val);
});
onMounted(() => {
const nowDate = parseTime(new Date(), '{y}-{m}-{d}');
daterangeRecordTime.value[0] = nowDate + ' 00:00:00';
daterangeRecordTime.value[1] = nowDate + ' 23:59:59';
getTreeselect();
getList();
});
</script>
<style scoped>
.chart1 {
width: 100%;
height: 75vh;
}
.chart2 {
width: 100%;
height: 40vh;
}
</style>

@ -85,7 +85,7 @@ import { ElMessage } from 'element-plus';
import { useDict } from '@/utils/dict';
import { getMonitorInfoTree } from '@/api/ems/base/baseMonitorInfo';
import { parseTime } from '@/utils/ruoyi';
import Chart from '@/components/Charts/Chart';
import Chart from '@/components/Charts/Chart.vue';
import * as echarts from 'echarts';
import { getRecordIotenvInstantList } from '@/api/ems/record/recordIotenvInstant';

@ -241,7 +241,7 @@
<script setup lang="ts">
import { ElMessage } from 'element-plus';
import Chart from '@/components/Charts/Chart';
import Chart from '@/components/Charts/Chart.vue';
import { getMonitorInfoTree } from '@/api/ems/base/baseMonitorInfo';
import { getRecordIotenvInstantReportData } from '@/api/ems/record/recordIotenvInstant';

Loading…
Cancel
Save