157 lines
4.0 KiB
Plaintext
157 lines
4.0 KiB
Plaintext
<template>
|
||
<view class="alert-container">
|
||
<view class="top-bar">
|
||
<button @click="goHistory" style="margin-right: 16rpx;">历史告警</button>
|
||
<text class="title">健康告警推送</text>
|
||
</view>
|
||
<scroll-view style="height: 600rpx; border: 1px solid #ccc; padding: 8rpx;" direction="vertical" scroll-with-animation>
|
||
<view v-for="(msg, idx) in messages" :key="idx"
|
||
style="font-size: 26rpx; color: #333; margin-bottom: 12rpx;">
|
||
<text>{{ msg.timeStr }}:</text>
|
||
<text>{{ msg.content }}</text>
|
||
</view>
|
||
</scroll-view>
|
||
</view>
|
||
</template>
|
||
|
||
<script lang="uts">
|
||
import { parseAlertMessage } from './alertparse.uts';
|
||
import { AkSupaRealtime } from '@/components/supadb/aksuparealtime.uts';
|
||
import { SUPA_KEY, WS_URL } from '@/ak/config.uts';
|
||
|
||
export default {
|
||
data() {
|
||
return {
|
||
wsUrl: WS_URL,
|
||
channel: 'realtime:public:ps_push_msg_raw',
|
||
messages: [] as Array<{ content : string; timeStr : string }>,
|
||
realtime: null as AkSupaRealtime | null
|
||
};
|
||
},
|
||
onLoad() {
|
||
this.initRealtime();
|
||
},
|
||
onUnload() {
|
||
if (this.realtime) {
|
||
this.realtime.close({});
|
||
this.realtime = null;
|
||
}
|
||
},
|
||
onShow() {
|
||
// 页面回到前台时检查 WebSocket 连接状态,必要时重连
|
||
if (!this.realtime || !this.realtime.isOpen) {
|
||
console.log('onShow: WebSocket未连接,尝试重连');
|
||
// this.initRealtime();
|
||
}
|
||
},
|
||
methods: {
|
||
goHistory() {
|
||
uni.navigateTo({ url: '/pages/ec/health/ecalert-history' });
|
||
},
|
||
// 重连相关参数
|
||
reconnectDelay: 3000,
|
||
reconnectMax: 10,
|
||
reconnectCount: 0,
|
||
reconnectTimer: null as any,
|
||
initRealtime() {
|
||
if (this.realtime) {
|
||
this.realtime.close({});
|
||
this.realtime = null;
|
||
}
|
||
const wsUrl: string = this.wsUrl as string;
|
||
const channel: string = this.channel;
|
||
const self = this;
|
||
this.reconnectCount = 0;
|
||
const createRealtime = () => {
|
||
const newRealtime = new AkSupaRealtime({
|
||
url: wsUrl,
|
||
channel: channel,
|
||
apikey: SUPA_KEY,
|
||
onOpen() {
|
||
self.reconnectCount = 0;
|
||
if (self.reconnectTimer) {
|
||
clearTimeout(self.reconnectTimer);
|
||
self.reconnectTimer = null;
|
||
}
|
||
},
|
||
onClose() {
|
||
// 断开后自动重连
|
||
self.tryReconnect();
|
||
},
|
||
onError(err) {
|
||
// 错误后也尝试重连
|
||
self.tryReconnect();
|
||
},
|
||
onMessage(data) {
|
||
console.log(data)
|
||
if (data && typeof data === 'object' && data.event === 'INSERT' && data.payload && data.payload.record) {
|
||
const payload = data.payload;
|
||
let content = '';
|
||
let timeStr = '';
|
||
const record = payload.record;
|
||
if (record.raw_data) {
|
||
content = record.raw_data;
|
||
} else if (record.message) {
|
||
content = record.message;
|
||
} else {
|
||
content = JSON.stringify(record);
|
||
}
|
||
if (record.created_at) {
|
||
try {
|
||
const d = new Date(record.created_at);
|
||
timeStr = d.toLocaleString();
|
||
} catch (e) {
|
||
timeStr = record.created_at;
|
||
}
|
||
}
|
||
const parseResult = parseAlertMessage(record.raw_data ? record.raw_data : record);
|
||
console.log(parseResult)
|
||
console.log(this.messages, self.messages)
|
||
self.messages.unshift({
|
||
content: (parseResult.mid ? `[${parseResult.mid}] ` : '') + parseResult.title + (parseResult.content ? (': ' + parseResult.content) : ''),
|
||
timeStr: timeStr || parseResult.time || ''
|
||
});
|
||
if (self.messages.length > 100) self.messages.length = 100;
|
||
}
|
||
}
|
||
});
|
||
self.realtime = newRealtime;
|
||
newRealtime.connect();
|
||
};
|
||
createRealtime();
|
||
},
|
||
tryReconnect() {
|
||
if (this.reconnectCount >= this.reconnectMax) {
|
||
console.warn('WebSocket重连已达最大次数');
|
||
return;
|
||
}
|
||
if (this.reconnectTimer) {
|
||
clearTimeout(this.reconnectTimer);
|
||
this.reconnectTimer = null;
|
||
}
|
||
this.reconnectCount++;
|
||
this.reconnectTimer = setTimeout(() => {
|
||
console.log('WebSocket重连中...', this.reconnectCount);
|
||
// this.initRealtime();
|
||
}, this.reconnectDelay);
|
||
}
|
||
}
|
||
};
|
||
</script>
|
||
|
||
<style>
|
||
.alert-container {
|
||
padding: 32rpx;
|
||
}
|
||
|
||
.title {
|
||
font-size: 36rpx;
|
||
font-weight: bold;
|
||
margin-bottom: 32rpx;
|
||
}
|
||
.top-bar {
|
||
display: flex;
|
||
align-items: center;
|
||
margin-bottom: 24rpx;
|
||
}
|
||
</style> |