|
|
|
|
@ -0,0 +1,507 @@
|
|
|
|
|
<template>
|
|
|
|
|
<div>
|
|
|
|
|
<el-dialog
|
|
|
|
|
title="⚠️ 实时告警通知"
|
|
|
|
|
:visible.sync="realtimeAlarmDialog"
|
|
|
|
|
width="900px"
|
|
|
|
|
append-to-body
|
|
|
|
|
:close-on-click-modal="false"
|
|
|
|
|
:close-on-press-escape="false"
|
|
|
|
|
class="realtime-alarm-dialog"
|
|
|
|
|
@close="closeRealtimeAlarmDialog"
|
|
|
|
|
>
|
|
|
|
|
<el-tabs v-model="realtimeActiveTab" type="card">
|
|
|
|
|
<!-- 告警详情标签页 -->
|
|
|
|
|
<el-tab-pane label="告警详情" name="alarmDetail">
|
|
|
|
|
<div v-if="currentRealtimeAlarm" class="alarm-content">
|
|
|
|
|
<!-- 设备信息 -->
|
|
|
|
|
<div class="alarm-section">
|
|
|
|
|
<h3 class="section-title">📟 设备信息</h3>
|
|
|
|
|
<el-row :gutter="16">
|
|
|
|
|
<el-col :span="12">
|
|
|
|
|
<div class="info-item">
|
|
|
|
|
<span class="label">设备ID:</span>
|
|
|
|
|
<span class="value">{{ currentRealtimeAlarm.monitorId }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
</el-col>
|
|
|
|
|
<el-col :span="12">
|
|
|
|
|
<div class="info-item">
|
|
|
|
|
<span class="label">告警时间:</span>
|
|
|
|
|
<span class="value">{{ formatAlarmTime(currentRealtimeAlarm.recordTime) }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
</el-col>
|
|
|
|
|
</el-row>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- 告警内容详情 -->
|
|
|
|
|
<div class="alarm-section"
|
|
|
|
|
v-if="currentRealtimeAlarm.alarmContents && currentRealtimeAlarm.alarmContents.length > 0">
|
|
|
|
|
<h3 class="section-title">📋 告警内容详情</h3>
|
|
|
|
|
<div class="alarm-contents">
|
|
|
|
|
<div
|
|
|
|
|
v-for="(content, index) in currentRealtimeAlarm.alarmContents"
|
|
|
|
|
:key="index"
|
|
|
|
|
class="content-item"
|
|
|
|
|
>
|
|
|
|
|
<el-alert
|
|
|
|
|
:title="content"
|
|
|
|
|
type="error"
|
|
|
|
|
:closable="false"
|
|
|
|
|
show-icon
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="alarm-section"
|
|
|
|
|
v-if="currentRealtimeAlarm.alarmContents && currentRealtimeAlarm.alarmContents.length > 0">
|
|
|
|
|
<h3 class="section-title">🔎 故障预测内容 </h3>
|
|
|
|
|
<div class="alarm-contents">
|
|
|
|
|
<el-alert
|
|
|
|
|
:title="PredictionContent()"
|
|
|
|
|
type="warning"
|
|
|
|
|
:closable="false"
|
|
|
|
|
show-icon
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</el-tab-pane>
|
|
|
|
|
|
|
|
|
|
<!-- 处置措施标签页 -->
|
|
|
|
|
<el-tab-pane label="处置措施" name="realtimeActionSteps">
|
|
|
|
|
<div v-if="currentRealtimeAlarm">
|
|
|
|
|
<el-alert
|
|
|
|
|
:title="`设备:${currentRealtimeAlarm.monitorId} | 告警时间:${formatAlarmTime(currentRealtimeAlarm.recordTime)}`"
|
|
|
|
|
type="warning"
|
|
|
|
|
:closable="false"
|
|
|
|
|
style="margin-bottom: 20px;"
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
<div v-loading="realtimeActionStepsLoading">
|
|
|
|
|
<div v-if="realtimeActionSteps.length === 0" class="no-steps">
|
|
|
|
|
<el-empty description="该告警规则暂无配置处置措施"></el-empty>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div v-else>
|
|
|
|
|
<el-timeline>
|
|
|
|
|
<el-timeline-item
|
|
|
|
|
v-for="(step, index) in realtimeActionSteps"
|
|
|
|
|
:key="step.objId"
|
|
|
|
|
:timestamp="`步骤 ${step.stepSequence}`"
|
|
|
|
|
placement="top"
|
|
|
|
|
type="primary"
|
|
|
|
|
size="large"
|
|
|
|
|
>
|
|
|
|
|
<el-card class="step-card">
|
|
|
|
|
<div slot="header" class="clearfix">
|
|
|
|
|
<span class="step-title">第{{ step.stepSequence }}步</span>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- 步骤描述 -->
|
|
|
|
|
<div class="step-description">
|
|
|
|
|
<p>{{ step.description }}</p>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- 步骤图片 -->
|
|
|
|
|
<div v-if="step.stepImages && step.stepImages.length > 0" class="step-images">
|
|
|
|
|
<div class="images-title">参考图片:</div>
|
|
|
|
|
<div class="image-gallery">
|
|
|
|
|
<div
|
|
|
|
|
v-for="image in step.stepImages"
|
|
|
|
|
:key="image.objId"
|
|
|
|
|
class="image-item"
|
|
|
|
|
@click="previewImage(getFullImageUrl(image.imageUrl))"
|
|
|
|
|
>
|
|
|
|
|
<img :src="getFullImageUrl(image.imageUrl)" :alt="image.description"/>
|
|
|
|
|
<div v-if="image.description" class="image-desc">{{ image.description }}</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- 步骤备注 -->
|
|
|
|
|
<div v-if="step.remark" class="step-remark">
|
|
|
|
|
<el-tag type="info" size="small">备注:{{ step.remark }}</el-tag>
|
|
|
|
|
</div>
|
|
|
|
|
</el-card>
|
|
|
|
|
</el-timeline-item>
|
|
|
|
|
</el-timeline>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</el-tab-pane>
|
|
|
|
|
</el-tabs>
|
|
|
|
|
|
|
|
|
|
<div slot="footer" class="dialog-footer">
|
|
|
|
|
<el-button
|
|
|
|
|
@click="closeRealtimeAlarmDialog"
|
|
|
|
|
:loading="alarmProcessing"
|
|
|
|
|
>
|
|
|
|
|
稍后处理
|
|
|
|
|
</el-button>
|
|
|
|
|
<el-button
|
|
|
|
|
type="primary"
|
|
|
|
|
@click="processRealtimeAlarm"
|
|
|
|
|
:loading="alarmProcessing"
|
|
|
|
|
>
|
|
|
|
|
我已处理
|
|
|
|
|
</el-button>
|
|
|
|
|
</div>
|
|
|
|
|
</el-dialog>
|
|
|
|
|
<div class="almReminder" @click="openAlm" v-if="almData.filter(e=>e.isWaiting).length>0"></div>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
import {getByAlarmInfo} from "@/api/board";
|
|
|
|
|
import {saveWebSocketAlarmData} from "@/api/ems/record/recordAlarmData";
|
|
|
|
|
import icon5 from "@/assets/images/icon5.jpg";
|
|
|
|
|
|
|
|
|
|
export default {
|
|
|
|
|
data() {
|
|
|
|
|
return {
|
|
|
|
|
icon5,
|
|
|
|
|
|
|
|
|
|
almData: [],
|
|
|
|
|
|
|
|
|
|
// 弹窗是否开启
|
|
|
|
|
realtimeAlarmDialog: false,
|
|
|
|
|
// tab页面Name
|
|
|
|
|
realtimeActiveTab: 'alarmDetail',
|
|
|
|
|
// 处置措施步骤
|
|
|
|
|
realtimeActionSteps: [],
|
|
|
|
|
// 处置措施loading
|
|
|
|
|
realtimeActionStepsLoading: false,
|
|
|
|
|
// 弹窗内容
|
|
|
|
|
currentRealtimeAlarm: null,
|
|
|
|
|
// 操作按钮loading
|
|
|
|
|
alarmProcessing: false,
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
mounted() {
|
|
|
|
|
this.$bus.$on('websocket-device-data', (e) => {
|
|
|
|
|
if (e.alarmContents.length > 0) {
|
|
|
|
|
e.alarmRules.forEach((item, index) => {
|
|
|
|
|
if (!this.almData.find(v => v.monitorId === e.monitorId && v.alarmRules[0].objid === item.objid)) {
|
|
|
|
|
this.almData.push({...e, alarmRules: [item], alarmContents: [e.alarmContents[index]], isWaiting: false})
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
// setInterval(() => {
|
|
|
|
|
// let e = {
|
|
|
|
|
// "monitorId": "T0002_0101",
|
|
|
|
|
// "isFlag": 1,
|
|
|
|
|
// "deviceParam": {
|
|
|
|
|
// "objid": 1927987087563427800,
|
|
|
|
|
// "monitorId": "T0002_0101",
|
|
|
|
|
// "temperature": 27.68,
|
|
|
|
|
// "humidity": 0,
|
|
|
|
|
// "illuminance": 0,
|
|
|
|
|
// "noise": 0,
|
|
|
|
|
// "concentration": 0,
|
|
|
|
|
// "VibrationSpeed": 0,
|
|
|
|
|
// "VibrationDisplacement": 0,
|
|
|
|
|
// "VibrationAcceleration": 0,
|
|
|
|
|
// "VibrationTemp": 0,
|
|
|
|
|
// "collectTime": "2024-09-03T04:47:06",
|
|
|
|
|
// "recordTime": "2025-05-29T15:15:16.3016212+08:00"
|
|
|
|
|
// },
|
|
|
|
|
// "alarmRules": [
|
|
|
|
|
// {
|
|
|
|
|
// "objid": 30020,
|
|
|
|
|
// "monitorId": "T0002_0101 ",
|
|
|
|
|
// "ruleId": null,
|
|
|
|
|
// "ruleName": "T0002_0101 表的温度大于阈值 20",
|
|
|
|
|
// "triggerRule": 0,
|
|
|
|
|
// "monitorField": 0,
|
|
|
|
|
// "triggerValue": 20,
|
|
|
|
|
// "cause": "温度过高-备注",
|
|
|
|
|
// "alarmId": 202506051636001,
|
|
|
|
|
// },
|
|
|
|
|
// {
|
|
|
|
|
// "objid": 30021,
|
|
|
|
|
// "monitorId": "T0002_0101 ",
|
|
|
|
|
// "ruleId": null,
|
|
|
|
|
// "ruleName": "T0002_0101表的温度小于阈值 30",
|
|
|
|
|
// "triggerRule": 1,
|
|
|
|
|
// "monitorField": 0,
|
|
|
|
|
// "triggerValue": 30,
|
|
|
|
|
// "cause": "温度过低-备注",
|
|
|
|
|
// "alarmId": 202506051636001,
|
|
|
|
|
// }
|
|
|
|
|
// ],
|
|
|
|
|
// "alarmContents": [
|
|
|
|
|
// "T0002_0101传感器数据在2025-05-29 15:15:16触发T0002_0101 表的温度大于阈值 20异常告警,告警规则:大于,阈值:20.00,详细信息:温度过高-备注",
|
|
|
|
|
// "T0002_0101传感器数据在2025-05-29 15:15:16触发T0002_0101表的温度小于阈值 30异常告警,告警规则:小于,阈值:30.00,详细信息:温度过低-备注"
|
|
|
|
|
// ],
|
|
|
|
|
// "recordTime": 1748566080572
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// if (e.alarmContents.length > 0) {
|
|
|
|
|
// e.alarmRules.forEach((item, index) => {
|
|
|
|
|
// if (!this.almData.find(v => v.monitorId === e.monitorId && v.alarmRules[0].objid === item.objid)) {
|
|
|
|
|
// this.almData.push({...e, alarmRules: [item], alarmContents: [e.alarmContents[index]], isWaiting: false})
|
|
|
|
|
// }
|
|
|
|
|
// })
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// }, 3000)
|
|
|
|
|
},
|
|
|
|
|
watch: {
|
|
|
|
|
almData: {
|
|
|
|
|
handler() {
|
|
|
|
|
if (this.almData.filter(e => !e.isWaiting).length > 0 && !this.realtimeAlarmDialog) {
|
|
|
|
|
let arr = this.almData.sort((a, b) => a.alarmRules[0].objid - b.alarmRules[0].objid)
|
|
|
|
|
let data = arr.filter(v => !v.isWaiting)
|
|
|
|
|
if (data.length > 0) {
|
|
|
|
|
this.currentRealtimeAlarm = data[0]
|
|
|
|
|
this.realtimeAlarmDialog = true
|
|
|
|
|
this.getAlm(data[0])
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
deep: true,
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
methods: {
|
|
|
|
|
openAlm() {
|
|
|
|
|
let arr = this.almData.sort((a, b) => a.alarmRules[0].objid - b.alarmRules[0].objid)
|
|
|
|
|
if (arr.length > 0) {
|
|
|
|
|
this.currentRealtimeAlarm = arr[0]
|
|
|
|
|
this.realtimeAlarmDialog = true
|
|
|
|
|
this.getAlm(arr[0])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
},
|
|
|
|
|
// 格式化告警时间
|
|
|
|
|
formatAlarmTime(time) {
|
|
|
|
|
if (!time) return '--'
|
|
|
|
|
try {
|
|
|
|
|
const date = new Date(time)
|
|
|
|
|
return date.toLocaleString('zh-CN')
|
|
|
|
|
} catch (error) {
|
|
|
|
|
return time
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
getActualValueFromDeviceParam(deviceParam, monitorField) {
|
|
|
|
|
if (!deviceParam || monitorField === null || monitorField === undefined) {
|
|
|
|
|
return null
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (monitorField) {
|
|
|
|
|
case 0: // 温度
|
|
|
|
|
return deviceParam.temperature
|
|
|
|
|
case 1: // 湿度
|
|
|
|
|
return deviceParam.humidity
|
|
|
|
|
case 2: // 振动-速度(mm/s)
|
|
|
|
|
return deviceParam.vibrationSpeed || deviceParam.VibrationSpeed
|
|
|
|
|
case 3: // 振动-位移(um)
|
|
|
|
|
return deviceParam.vibrationDisplacement || deviceParam.VibrationDisplacement
|
|
|
|
|
case 4: // 振动-加速度(g)
|
|
|
|
|
return deviceParam.vibrationAcceleration || deviceParam.VibrationAcceleration
|
|
|
|
|
case 5: // 振动-温度(℃)
|
|
|
|
|
return deviceParam.vibrationTemp || deviceParam.VibrationTemp
|
|
|
|
|
case 6: // 噪音
|
|
|
|
|
return deviceParam.noise
|
|
|
|
|
case 7: // 照度
|
|
|
|
|
return deviceParam.illuminance
|
|
|
|
|
case 8: // 气体浓度
|
|
|
|
|
return deviceParam.concentration
|
|
|
|
|
default:
|
|
|
|
|
console.warn('未知的监测字段:', monitorField)
|
|
|
|
|
return null
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
async saveRealtimeAlarmData(alarmData, alarmStatus = 1) {
|
|
|
|
|
try {
|
|
|
|
|
// 构建符合EmsRecordAlarmData实体的数据列表
|
|
|
|
|
// 每个触发的告警规则对应一条EmsRecordAlarmData记录
|
|
|
|
|
const alarmDataList = []
|
|
|
|
|
|
|
|
|
|
if (!alarmData.alarmRules || alarmData.alarmRules.length === 0) {
|
|
|
|
|
console.warn('告警数据中没有告警规则')
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取当前时间并格式化为后端期望的格式
|
|
|
|
|
const getCurrentTimeForBackend = () => {
|
|
|
|
|
const now = new Date()
|
|
|
|
|
const year = now.getFullYear()
|
|
|
|
|
const month = String(now.getMonth() + 1).padStart(2, '0')
|
|
|
|
|
const day = String(now.getDate()).padStart(2, '0')
|
|
|
|
|
const hours = String(now.getHours()).padStart(2, '0')
|
|
|
|
|
const minutes = String(now.getMinutes()).padStart(2, '0')
|
|
|
|
|
const seconds = String(now.getSeconds()).padStart(2, '0')
|
|
|
|
|
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 为每个触发的告警规则创建一条记录
|
|
|
|
|
for (const rule of alarmData.alarmRules) {
|
|
|
|
|
// 获取对应字段的实际数值
|
|
|
|
|
const actualValue = this.getActualValueFromDeviceParam(alarmData.deviceParam, rule.monitorField)
|
|
|
|
|
|
|
|
|
|
const alarmRecord = {
|
|
|
|
|
// 设备相关信息
|
|
|
|
|
monitorId: alarmData.monitorId,
|
|
|
|
|
collectTime: getCurrentTimeForBackend(), // 使用当前时间并格式化为后端期望格式
|
|
|
|
|
|
|
|
|
|
// 告警类型:根据规则的triggerRule设置(0=大于阈值,1=小于阈值)
|
|
|
|
|
alarmType: rule.triggerRule || 0,
|
|
|
|
|
|
|
|
|
|
// 告警状态:根据用户操作设置(0=已处理,1=未处理)
|
|
|
|
|
alarmStatus: alarmStatus,
|
|
|
|
|
|
|
|
|
|
// 告警数据:实际触发告警的数值
|
|
|
|
|
alarmData: actualValue ? String(actualValue) : '',
|
|
|
|
|
|
|
|
|
|
// 告警原因:使用字段名称
|
|
|
|
|
cause: this.getFieldName(rule.monitorField),
|
|
|
|
|
|
|
|
|
|
// 其他字段可以为空,后端会设置默认值
|
|
|
|
|
operationName: null,
|
|
|
|
|
operationTime: null,
|
|
|
|
|
notifyUser: null
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
alarmDataList.push(alarmRecord)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (alarmDataList.length === 0) {
|
|
|
|
|
console.warn('没有有效的告警记录可保存')
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 发送到后端保存
|
|
|
|
|
const response = await saveWebSocketAlarmData(alarmDataList)
|
|
|
|
|
if (response.code === 200) {
|
|
|
|
|
console.log('告警数据保存成功:', response.msg)
|
|
|
|
|
return true
|
|
|
|
|
} else {
|
|
|
|
|
this.$message.error('告警数据保存失败: ' + response.msg)
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
this.$message.error('保存告警数据异常')
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
async processRealtimeAlarm() {
|
|
|
|
|
this.alarmProcessing = true
|
|
|
|
|
try {
|
|
|
|
|
// 保存告警数据,状态为0(已处理)
|
|
|
|
|
const success = await this.saveRealtimeAlarmData(this.currentRealtimeAlarm, 0)
|
|
|
|
|
if (success) {
|
|
|
|
|
this.$message.success('告警已确认知晓并标记为已处理')
|
|
|
|
|
let data = this.currentRealtimeAlarm
|
|
|
|
|
let index = this.almData.findIndex(v => v.monitorId === data.monitorId && v.alarmRules[0].objid === data.alarmRules[0].objid)
|
|
|
|
|
|
|
|
|
|
this.almData.splice(index, 1)
|
|
|
|
|
this.realtimeAlarmDialog = false
|
|
|
|
|
this.currentRealtimeAlarm = null
|
|
|
|
|
this.realtimeActiveTab = 'alarmDetail'
|
|
|
|
|
this.realtimeActionSteps = []
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('处理告警失败:', error)
|
|
|
|
|
this.$message.error('处理告警失败')
|
|
|
|
|
} finally {
|
|
|
|
|
this.alarmProcessing = false
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
getFieldName(fieldCode) {
|
|
|
|
|
const fieldMap = {
|
|
|
|
|
0: '温度',
|
|
|
|
|
1: '湿度',
|
|
|
|
|
2: '振动-速度(mm/s)',
|
|
|
|
|
3: '振动-位移(um)',
|
|
|
|
|
4: '振动-加速度(g)',
|
|
|
|
|
5: '振动-温度(℃)',
|
|
|
|
|
6: '噪音',
|
|
|
|
|
7: '照度',
|
|
|
|
|
8: '气体浓度'
|
|
|
|
|
}
|
|
|
|
|
return fieldMap[fieldCode] || '未知字段'
|
|
|
|
|
},
|
|
|
|
|
getAlm(e) {
|
|
|
|
|
let cause = this.getFieldName(e.alarmRules[0].monitorField)
|
|
|
|
|
getByAlarmInfo({
|
|
|
|
|
monitorId: e.monitorId,
|
|
|
|
|
cause
|
|
|
|
|
}).then(v => {
|
|
|
|
|
console.log(v)
|
|
|
|
|
this.realtimeActionSteps = v.data || []
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
closeRealtimeAlarmDialog() {
|
|
|
|
|
let data = this.currentRealtimeAlarm
|
|
|
|
|
let index = this.almData.findIndex(v => v.monitorId === data.monitorId && v.alarmRules[0].objid === data.alarmRules[0].objid)
|
|
|
|
|
|
|
|
|
|
this.$set(this.almData[index], 'isWaiting', true)
|
|
|
|
|
this.realtimeAlarmDialog = false
|
|
|
|
|
this.currentRealtimeAlarm = null
|
|
|
|
|
this.realtimeActiveTab = 'alarmDetail'
|
|
|
|
|
this.realtimeActionSteps = []
|
|
|
|
|
},
|
|
|
|
|
PredictionContent() {
|
|
|
|
|
|
|
|
|
|
if (this.currentRealtimeAlarm.monitorId === 'E0012_4300' && this.currentRealtimeAlarm.alarmRules[0].monitorField === 1) {
|
|
|
|
|
return '故障预测:空气湿度过大'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let data = this.currentRealtimeAlarm.monitorId
|
|
|
|
|
if (data) {
|
|
|
|
|
let AA = data.split('_')[1].slice(0, 2)
|
|
|
|
|
const sortNum = parseInt(AA, 10)
|
|
|
|
|
const overloadTypes = [1, 2, 20, 17, 26, 10, 33, 5, 15, 9, 30, 27, 29, 18, 24, 22, 7, 31, 28, 6]
|
|
|
|
|
|
|
|
|
|
const electricalOverloadTypes = [14, 21, 23, 12, 13, 32, 4, 3, 8]
|
|
|
|
|
|
|
|
|
|
// 判断具体的故障预测类型
|
|
|
|
|
if (overloadTypes.includes(sortNum)) {
|
|
|
|
|
return '故障预测:过载'
|
|
|
|
|
} else if (electricalOverloadTypes.includes(sortNum)) {
|
|
|
|
|
return '故障预测:电器元器件过载'
|
|
|
|
|
} else if (sortNum >= 35 && sortNum <= 38) {
|
|
|
|
|
return '故障预测:轴承故障'
|
|
|
|
|
} else if (sortNum >= 39 && sortNum <= 41) {
|
|
|
|
|
return '故障预测:机械磨损'
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
return ''
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
</script>
|
|
|
|
|
<style lang="less">
|
|
|
|
|
.almReminder {
|
|
|
|
|
position: fixed;
|
|
|
|
|
top: calc(15% + 2vw);
|
|
|
|
|
display: none;
|
|
|
|
|
right: 4%;
|
|
|
|
|
transform: translate(50%, -50%);
|
|
|
|
|
width: 3vw;
|
|
|
|
|
height: 3vw;
|
|
|
|
|
background: url("~@/assets/images/icon5.jpg") no-repeat;
|
|
|
|
|
background-size: 100% 100%;
|
|
|
|
|
animation: Zoom 2s infinite;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@keyframes Zoom {
|
|
|
|
|
0% {
|
|
|
|
|
width: 3vw;
|
|
|
|
|
height: 3vw;
|
|
|
|
|
}
|
|
|
|
|
50% {
|
|
|
|
|
width: 4vw;
|
|
|
|
|
height: 4vw;
|
|
|
|
|
}
|
|
|
|
|
100% {
|
|
|
|
|
width: 3vw;
|
|
|
|
|
height: 3vw;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
</style>
|