diff --git a/src/components/alarm/RealtimeAlarmModal.vue b/src/components/alarm/RealtimeAlarmModal.vue new file mode 100644 index 0000000..6f9b88a --- /dev/null +++ b/src/components/alarm/RealtimeAlarmModal.vue @@ -0,0 +1,482 @@ + + + + + diff --git a/src/utils/alarmRealtime.ts b/src/utils/alarmRealtime.ts new file mode 100644 index 0000000..e749924 --- /dev/null +++ b/src/utils/alarmRealtime.ts @@ -0,0 +1,88 @@ +import type { EmsRecordAlarmDataVO } from '@/api/ems/types'; + +export const EMS_REALTIME_ALARM_EVENT = 'ems:alarm:realtime'; +export const EMS_REALTIME_ALARM_PAYLOAD_TYPE = 'ems_alarm_realtime'; + +export interface EmsRealtimeAlarmEnvelope { + eventType: typeof EMS_REALTIME_ALARM_PAYLOAD_TYPE; + channel?: 'SSE' | 'WEBSOCKET' | 'UNKNOWN'; + source?: string; + generatedAt?: string; + alarms: EmsRecordAlarmDataVO[]; +} + +interface LegacyRealtimeAlarmEnvelope { + eventType?: string; + source?: string; + eventTime?: string; + payload?: { + records?: EmsRecordAlarmDataVO[]; + }; +} + +export interface ParsedAlarmMessage { + envelope: EmsRealtimeAlarmEnvelope | null; + displayMessage: string; +} + +export const useAlarmRealtimeBus = () => useEventBus(EMS_REALTIME_ALARM_EVENT); + +const isRealtimeAlarmEnvelope = (value: unknown): value is EmsRealtimeAlarmEnvelope => { + if (!value || typeof value !== 'object') { + return false; + } + const envelope = value as EmsRealtimeAlarmEnvelope; + return envelope.eventType === EMS_REALTIME_ALARM_PAYLOAD_TYPE && Array.isArray(envelope.alarms); +}; + +const normalizeLegacyEnvelope = (value: unknown): EmsRealtimeAlarmEnvelope | null => { + if (!value || typeof value !== 'object') { + return null; + } + const legacyEnvelope = value as LegacyRealtimeAlarmEnvelope; + const records = legacyEnvelope.payload?.records; + if (legacyEnvelope.eventType !== 'EMS_REALTIME_ALARM_BATCH' || !Array.isArray(records)) { + return null; + } + return { + eventType: EMS_REALTIME_ALARM_PAYLOAD_TYPE, + source: legacyEnvelope.source, + generatedAt: legacyEnvelope.eventTime, + alarms: records + }; +}; + +export const parseAlarmRealtimeMessage = (rawMessage: unknown): ParsedAlarmMessage => { + const fallbackMessage = typeof rawMessage === 'string' ? rawMessage : JSON.stringify(rawMessage ?? ''); + if (typeof rawMessage !== 'string') { + return { + envelope: null, + displayMessage: fallbackMessage + }; + } + try { + const parsed = JSON.parse(rawMessage); + const envelope = isRealtimeAlarmEnvelope(parsed) ? parsed : normalizeLegacyEnvelope(parsed); + if (!envelope) { + return { + envelope: null, + displayMessage: fallbackMessage + }; + } + const firstAlarm = envelope.alarms[0]; + const alarmCount = envelope.alarms.length; + const displayMessage = + alarmCount > 1 + ? `收到 ${alarmCount} 条实时告警,已进入待处置队列` + : `收到实时告警:${firstAlarm?.alarmTitle || firstAlarm?.monitorName || firstAlarm?.monitorId || '未命名告警'}`; + return { + envelope, + displayMessage + }; + } catch { + return { + envelope: null, + displayMessage: fallbackMessage + }; + } +}; diff --git a/src/views/ems/record/recordAlarmRule/index.vue b/src/views/ems/record/recordAlarmRule/index.vue index 0a1662b..db3035a 100644 --- a/src/views/ems/record/recordAlarmRule/index.vue +++ b/src/views/ems/record/recordAlarmRule/index.vue @@ -226,7 +226,14 @@ - + diff --git a/src/views/ems/report/components/AlarmTrendPanel.vue b/src/views/ems/report/components/AlarmTrendPanel.vue new file mode 100644 index 0000000..ad01f77 --- /dev/null +++ b/src/views/ems/report/components/AlarmTrendPanel.vue @@ -0,0 +1,99 @@ + + + + + diff --git a/src/views/ems/report/components/EfficiencyScoreBoard.vue b/src/views/ems/report/components/EfficiencyScoreBoard.vue new file mode 100644 index 0000000..76f1b27 --- /dev/null +++ b/src/views/ems/report/components/EfficiencyScoreBoard.vue @@ -0,0 +1,127 @@ + + + + + diff --git a/src/views/ems/report/components/IotReportWorkbench.vue b/src/views/ems/report/components/IotReportWorkbench.vue new file mode 100644 index 0000000..9b3340d --- /dev/null +++ b/src/views/ems/report/components/IotReportWorkbench.vue @@ -0,0 +1,1256 @@ + + + + + diff --git a/src/views/ems/report/components/MeterBalanceTopology.vue b/src/views/ems/report/components/MeterBalanceTopology.vue new file mode 100644 index 0000000..540c397 --- /dev/null +++ b/src/views/ems/report/components/MeterBalanceTopology.vue @@ -0,0 +1,104 @@ + + + + + diff --git a/src/views/ems/report/comprehensiveEnergyEfficiencyReport/index.vue b/src/views/ems/report/comprehensiveEnergyEfficiencyReport/index.vue new file mode 100644 index 0000000..3306354 --- /dev/null +++ b/src/views/ems/report/comprehensiveEnergyEfficiencyReport/index.vue @@ -0,0 +1,346 @@ + + + + + diff --git a/src/views/ems/report/energyAbnormalAlertReport/index.vue b/src/views/ems/report/energyAbnormalAlertReport/index.vue new file mode 100644 index 0000000..9e0429f --- /dev/null +++ b/src/views/ems/report/energyAbnormalAlertReport/index.vue @@ -0,0 +1,318 @@ + + + + + diff --git a/src/views/ems/report/instrumentConditionReport/index.vue b/src/views/ems/report/instrumentConditionReport/index.vue new file mode 100644 index 0000000..064fd08 --- /dev/null +++ b/src/views/ems/report/instrumentConditionReport/index.vue @@ -0,0 +1,510 @@ + + + + + diff --git a/src/views/ems/report/iotDeviceCompareReport/index.vue b/src/views/ems/report/iotDeviceCompareReport/index.vue new file mode 100644 index 0000000..23b5c7a --- /dev/null +++ b/src/views/ems/report/iotDeviceCompareReport/index.vue @@ -0,0 +1,15 @@ + + + diff --git a/src/views/ems/report/iotQualityReport/index.vue b/src/views/ems/report/iotQualityReport/index.vue new file mode 100644 index 0000000..db9b4a4 --- /dev/null +++ b/src/views/ems/report/iotQualityReport/index.vue @@ -0,0 +1,15 @@ + + + diff --git a/src/views/ems/report/iotTrendReport/index.vue b/src/views/ems/report/iotTrendReport/index.vue new file mode 100644 index 0000000..1112466 --- /dev/null +++ b/src/views/ems/report/iotTrendReport/index.vue @@ -0,0 +1,15 @@ + + + diff --git a/src/views/ems/report/meterBalanceReport/index.vue b/src/views/ems/report/meterBalanceReport/index.vue new file mode 100644 index 0000000..fd4dcac --- /dev/null +++ b/src/views/ems/report/meterBalanceReport/index.vue @@ -0,0 +1,385 @@ + + + + + diff --git a/src/views/ems/report/realtimeIOTCurve/index.vue b/src/views/ems/report/realtimeIOTCurve/index.vue new file mode 100644 index 0000000..d3c6565 --- /dev/null +++ b/src/views/ems/report/realtimeIOTCurve/index.vue @@ -0,0 +1,988 @@ + + + + +