599 lines
15 KiB
JavaScript
599 lines
15 KiB
JavaScript
|
|
// 实时通知管理器 - 微信小程序专用
|
|||
|
|
// 处理WebSocket消息、本地通知、订阅消息等
|
|||
|
|
|
|||
|
|
const wsManager = require('./websocket-manager-v2.js');
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 微信小程序实时通知管理器
|
|||
|
|
* 功能:
|
|||
|
|
* 1. WebSocket消息处理和分发
|
|||
|
|
* 2. 本地通知提醒
|
|||
|
|
* 3. 订阅消息管理
|
|||
|
|
* 4. 消息状态同步
|
|||
|
|
* 5. 离线消息处理
|
|||
|
|
*/
|
|||
|
|
class NotificationManager {
|
|||
|
|
constructor() {
|
|||
|
|
this.isInitialized = false;
|
|||
|
|
this.messageHandlers = new Map();
|
|||
|
|
this.notificationQueue = [];
|
|||
|
|
this.unreadCounts = {
|
|||
|
|
messages: 0,
|
|||
|
|
friends: 0,
|
|||
|
|
system: 0
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// 订阅消息模板ID(需要在微信公众平台配置)
|
|||
|
|
this.subscribeTemplates = {
|
|||
|
|
newMessage: 'template_id_for_new_message',
|
|||
|
|
friendRequest: 'template_id_for_friend_request',
|
|||
|
|
systemNotice: 'template_id_for_system_notice'
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// 通知设置
|
|||
|
|
this.notificationSettings = {
|
|||
|
|
sound: true,
|
|||
|
|
vibrate: true,
|
|||
|
|
showBadge: true,
|
|||
|
|
quietHours: {
|
|||
|
|
enabled: false,
|
|||
|
|
start: '22:00',
|
|||
|
|
end: '08:00'
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
this.init();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 初始化通知管理器
|
|||
|
|
async init() {
|
|||
|
|
if (this.isInitialized) return;
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
// 加载通知设置
|
|||
|
|
await this.loadNotificationSettings();
|
|||
|
|
|
|||
|
|
// 注册WebSocket消息处理器
|
|||
|
|
this.registerWebSocketHandlers();
|
|||
|
|
|
|||
|
|
// 注册小程序生命周期事件
|
|||
|
|
this.registerAppLifecycleEvents();
|
|||
|
|
|
|||
|
|
// 初始化未读计数
|
|||
|
|
await this.loadUnreadCounts();
|
|||
|
|
|
|||
|
|
this.isInitialized = true;
|
|||
|
|
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('❌ 通知管理器初始化失败:', error);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 注册WebSocket消息处理器
|
|||
|
|
registerWebSocketHandlers() {
|
|||
|
|
// 新消息通知
|
|||
|
|
wsManager.on('message', (data) => {
|
|||
|
|
this.handleWebSocketMessage(data);
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 连接状态变化
|
|||
|
|
wsManager.on('connected', () => {
|
|||
|
|
|
|||
|
|
this.syncOfflineMessages();
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
wsManager.on('disconnected', () => {
|
|||
|
|
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 处理WebSocket消息
|
|||
|
|
async handleWebSocketMessage(data) {
|
|||
|
|
try {
|
|||
|
|
const message = typeof data === 'string' ? JSON.parse(data) : data;
|
|||
|
|
|
|||
|
|
switch (message.type) {
|
|||
|
|
case 'new_message':
|
|||
|
|
await this.handleNewMessage(message.data);
|
|||
|
|
break;
|
|||
|
|
case 'friend_request':
|
|||
|
|
await this.handleFriendRequest(message.data);
|
|||
|
|
break;
|
|||
|
|
case 'friend_accepted':
|
|||
|
|
await this.handleFriendAccepted(message.data);
|
|||
|
|
break;
|
|||
|
|
case 'system_notice':
|
|||
|
|
await this.handleSystemNotice(message.data);
|
|||
|
|
break;
|
|||
|
|
case 'message_read':
|
|||
|
|
await this.handleMessageRead(message.data);
|
|||
|
|
break;
|
|||
|
|
case 'user_online':
|
|||
|
|
await this.handleUserOnline(message.data);
|
|||
|
|
break;
|
|||
|
|
case 'user_offline':
|
|||
|
|
await this.handleUserOffline(message.data);
|
|||
|
|
break;
|
|||
|
|
default:
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 触发自定义事件
|
|||
|
|
this.triggerEvent('message_received', message);
|
|||
|
|
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('❌ 处理WebSocket消息失败:', error);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 处理新消息
|
|||
|
|
async handleNewMessage(messageData) {
|
|||
|
|
|
|||
|
|
// 更新未读计数
|
|||
|
|
this.unreadCounts.messages++;
|
|||
|
|
await this.saveUnreadCounts();
|
|||
|
|
|
|||
|
|
// 显示通知
|
|||
|
|
await this.showNotification({
|
|||
|
|
type: 'new_message',
|
|||
|
|
title: messageData.senderName || '新消息',
|
|||
|
|
content: this.formatMessageContent(messageData),
|
|||
|
|
data: messageData
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 触发页面更新
|
|||
|
|
this.triggerEvent('new_message', messageData);
|
|||
|
|
|
|||
|
|
// 更新tabBar徽章
|
|||
|
|
this.updateTabBarBadge();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 处理好友请求
|
|||
|
|
async handleFriendRequest(requestData) {
|
|||
|
|
|
|||
|
|
// 更新未读计数
|
|||
|
|
this.unreadCounts.friends++;
|
|||
|
|
await this.saveUnreadCounts();
|
|||
|
|
|
|||
|
|
// 显示通知
|
|||
|
|
await this.showNotification({
|
|||
|
|
type: 'friend_request',
|
|||
|
|
title: '新的好友请求',
|
|||
|
|
content: `${requestData.senderName} 请求添加您为好友`,
|
|||
|
|
data: requestData
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 触发页面更新
|
|||
|
|
this.triggerEvent('friend_request', requestData);
|
|||
|
|
|
|||
|
|
// 更新tabBar徽章
|
|||
|
|
this.updateTabBarBadge();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 处理好友请求被接受
|
|||
|
|
async handleFriendAccepted(acceptData) {
|
|||
|
|
|
|||
|
|
// 显示通知
|
|||
|
|
await this.showNotification({
|
|||
|
|
type: 'friend_accepted',
|
|||
|
|
title: '好友请求已接受',
|
|||
|
|
content: `${acceptData.friendName} 已接受您的好友请求`,
|
|||
|
|
data: acceptData
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 触发页面更新
|
|||
|
|
this.triggerEvent('friend_accepted', acceptData);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 处理系统通知
|
|||
|
|
async handleSystemNotice(noticeData) {
|
|||
|
|
|
|||
|
|
// 更新未读计数
|
|||
|
|
this.unreadCounts.system++;
|
|||
|
|
await this.saveUnreadCounts();
|
|||
|
|
|
|||
|
|
// 显示通知
|
|||
|
|
await this.showNotification({
|
|||
|
|
type: 'system_notice',
|
|||
|
|
title: '系统通知',
|
|||
|
|
content: noticeData.content,
|
|||
|
|
data: noticeData
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 触发页面更新
|
|||
|
|
this.triggerEvent('system_notice', noticeData);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 处理消息已读
|
|||
|
|
async handleMessageRead(readData) {
|
|||
|
|
|
|||
|
|
// 更新未读计数
|
|||
|
|
if (readData.count && this.unreadCounts.messages >= readData.count) {
|
|||
|
|
this.unreadCounts.messages -= readData.count;
|
|||
|
|
await this.saveUnreadCounts();
|
|||
|
|
this.updateTabBarBadge();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 触发页面更新
|
|||
|
|
this.triggerEvent('message_read', readData);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 显示通知
|
|||
|
|
async showNotification(notification) {
|
|||
|
|
try {
|
|||
|
|
// 检查是否在静默时间
|
|||
|
|
if (this.isInQuietHours()) {
|
|||
|
|
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 检查应用状态
|
|||
|
|
const appState = this.getAppState();
|
|||
|
|
|
|||
|
|
if (appState === 'foreground') {
|
|||
|
|
// 前台显示本地通知
|
|||
|
|
await this.showLocalNotification(notification);
|
|||
|
|
} else {
|
|||
|
|
// 后台尝试发送订阅消息
|
|||
|
|
await this.sendSubscribeMessage(notification);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 播放提示音
|
|||
|
|
if (this.notificationSettings.sound) {
|
|||
|
|
this.playNotificationSound();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 震动提醒
|
|||
|
|
if (this.notificationSettings.vibrate) {
|
|||
|
|
this.vibrateDevice();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('❌ 显示通知失败:', error);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 显示本地通知(前台)
|
|||
|
|
async showLocalNotification(notification) {
|
|||
|
|
// 只对已登录用户显示通知
|
|||
|
|
const app = getApp();
|
|||
|
|
const isLoggedIn = app?.globalData?.isLoggedIn || false;
|
|||
|
|
if (!isLoggedIn) return;
|
|||
|
|
|
|||
|
|
// 微信小程序没有原生的本地通知API
|
|||
|
|
// 这里使用自定义的通知组件或Toast
|
|||
|
|
|
|||
|
|
wx.showToast({
|
|||
|
|
title: notification.content,
|
|||
|
|
icon: 'none',
|
|||
|
|
duration: 3000
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 如果有自定义通知组件,可以在这里调用
|
|||
|
|
// this.triggerEvent('show_custom_notification', notification);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 发送订阅消息(后台)
|
|||
|
|
async sendSubscribeMessage(notification) {
|
|||
|
|
try {
|
|||
|
|
// 检查是否有订阅权限
|
|||
|
|
const templateId = this.getTemplateId(notification.type);
|
|||
|
|
if (!templateId) {
|
|||
|
|
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 这里需要调用后端API发送订阅消息
|
|||
|
|
// 因为订阅消息需要在服务端发送
|
|||
|
|
|
|||
|
|
// TODO: 调用后端API发送订阅消息
|
|||
|
|
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('❌ 发送订阅消息失败:', error);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 格式化消息内容
|
|||
|
|
formatMessageContent(messageData) {
|
|||
|
|
switch (messageData.msgType) {
|
|||
|
|
case 0: // 文本消息
|
|||
|
|
return messageData.content;
|
|||
|
|
case 1: // 图片消息
|
|||
|
|
return '[图片]';
|
|||
|
|
case 2: // 语音消息
|
|||
|
|
return '[语音]';
|
|||
|
|
case 3: // 视频消息
|
|||
|
|
return '[视频]';
|
|||
|
|
case 4: // 文件消息
|
|||
|
|
return '[文件]';
|
|||
|
|
default:
|
|||
|
|
return '[消息]';
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 获取模板ID
|
|||
|
|
getTemplateId(notificationType) {
|
|||
|
|
return this.subscribeTemplates[notificationType];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 检查是否在静默时间
|
|||
|
|
isInQuietHours() {
|
|||
|
|
if (!this.notificationSettings.quietHours.enabled) {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const now = new Date();
|
|||
|
|
const currentTime = `${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}`;
|
|||
|
|
const { start, end } = this.notificationSettings.quietHours;
|
|||
|
|
|
|||
|
|
if (start <= end) {
|
|||
|
|
return currentTime >= start && currentTime <= end;
|
|||
|
|
} else {
|
|||
|
|
return currentTime >= start || currentTime <= end;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 获取应用状态
|
|||
|
|
getAppState() {
|
|||
|
|
// 微信小程序中可以通过页面栈判断应用状态
|
|||
|
|
const pages = getCurrentPages();
|
|||
|
|
return pages.length > 0 ? 'foreground' : 'background';
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 播放提示音
|
|||
|
|
playNotificationSound() {
|
|||
|
|
try {
|
|||
|
|
// 微信小程序播放系统提示音
|
|||
|
|
wx.createInnerAudioContext().play();
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('❌ 播放提示音失败:', error);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 震动设备
|
|||
|
|
vibrateDevice() {
|
|||
|
|
try {
|
|||
|
|
wx.vibrateShort({
|
|||
|
|
type: 'medium'
|
|||
|
|
});
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('❌ 震动失败:', error);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 更新tabBar徽章
|
|||
|
|
updateTabBarBadge() {
|
|||
|
|
try {
|
|||
|
|
const totalUnread = this.unreadCounts.messages + this.unreadCounts.friends + this.unreadCounts.system;
|
|||
|
|
// 原生tabBar角标(兜底,部分机型自定义tabBar仍可用该API显示消息数)
|
|||
|
|
if (totalUnread > 0) {
|
|||
|
|
wx.setTabBarBadge({ index: 1, text: totalUnread > 99 ? '99+' : totalUnread.toString() });
|
|||
|
|
} else {
|
|||
|
|
wx.removeTabBarBadge({ index: 1 });
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 自定义tabBar同步:优先显示各自分类的数量
|
|||
|
|
const pages = getCurrentPages();
|
|||
|
|
const cur = pages[pages.length - 1];
|
|||
|
|
if (cur && typeof cur.getTabBar === 'function') {
|
|||
|
|
const tb = cur.getTabBar && cur.getTabBar();
|
|||
|
|
if (tb && typeof tb.setFriendsBadge === 'function' && typeof tb.setMessagesBadge === 'function') {
|
|||
|
|
tb.setFriendsBadge(this.unreadCounts.friends || 0);
|
|||
|
|
tb.setMessagesBadge(this.unreadCounts.messages || 0);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('❌ 更新tabBar徽章失败:', error);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 同步离线消息
|
|||
|
|
async syncOfflineMessages() {
|
|||
|
|
try {
|
|||
|
|
|
|||
|
|
// 获取最后同步时间
|
|||
|
|
const lastSyncTime = wx.getStorageSync('lastMessageSyncTime') || 0;
|
|||
|
|
|
|||
|
|
// 调用API获取离线消息
|
|||
|
|
const apiClient = require('./api-client.js');
|
|||
|
|
const response = await apiClient.request({
|
|||
|
|
url: '/api/v1/messages/offline',
|
|||
|
|
method: 'GET',
|
|||
|
|
data: {
|
|||
|
|
since: lastSyncTime
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
if (response.success && response.data.messages) {
|
|||
|
|
|
|||
|
|
// 处理离线消息
|
|||
|
|
for (const message of response.data.messages) {
|
|||
|
|
await this.handleNewMessage(message);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 更新同步时间
|
|||
|
|
wx.setStorageSync('lastMessageSyncTime', Date.now());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('❌ 同步离线消息失败:', error);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 注册小程序生命周期事件
|
|||
|
|
registerAppLifecycleEvents() {
|
|||
|
|
// 监听小程序显示
|
|||
|
|
wx.onAppShow(() => {
|
|||
|
|
|
|||
|
|
this.syncOfflineMessages();
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 监听小程序隐藏
|
|||
|
|
wx.onAppHide(() => {
|
|||
|
|
|
|||
|
|
this.saveUnreadCounts();
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 加载通知设置
|
|||
|
|
async loadNotificationSettings() {
|
|||
|
|
try {
|
|||
|
|
const settings = wx.getStorageSync('notificationSettings');
|
|||
|
|
if (settings) {
|
|||
|
|
this.notificationSettings = { ...this.notificationSettings, ...settings };
|
|||
|
|
}
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('❌ 加载通知设置失败:', error);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 保存通知设置
|
|||
|
|
async saveNotificationSettings() {
|
|||
|
|
try {
|
|||
|
|
wx.setStorageSync('notificationSettings', this.notificationSettings);
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('❌ 保存通知设置失败:', error);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 加载未读计数
|
|||
|
|
async loadUnreadCounts() {
|
|||
|
|
try {
|
|||
|
|
const counts = wx.getStorageSync('unreadCounts');
|
|||
|
|
if (counts) {
|
|||
|
|
this.unreadCounts = { ...this.unreadCounts, ...counts };
|
|||
|
|
this.updateTabBarBadge();
|
|||
|
|
}
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('❌ 加载未读计数失败:', error);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 保存未读计数
|
|||
|
|
async saveUnreadCounts() {
|
|||
|
|
try {
|
|||
|
|
wx.setStorageSync('unreadCounts', this.unreadCounts);
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('❌ 保存未读计数失败:', error);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 清除未读计数
|
|||
|
|
async clearUnreadCount(type) {
|
|||
|
|
if (this.unreadCounts[type] !== undefined) {
|
|||
|
|
this.unreadCounts[type] = 0;
|
|||
|
|
await this.saveUnreadCounts();
|
|||
|
|
this.updateTabBarBadge();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
// 显式设置未读计数(用于以服务端真实数量为准时校准)
|
|||
|
|
async setUnreadCount(type, value) {
|
|||
|
|
if (this.unreadCounts[type] === undefined) return;
|
|||
|
|
const v = Math.max(0, Number(value) || 0);
|
|||
|
|
this.unreadCounts[type] = v;
|
|||
|
|
await this.saveUnreadCounts();
|
|||
|
|
this.updateTabBarBadge();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
async setFriendsUnreadCount(value) { return this.setUnreadCount('friends', value); }
|
|||
|
|
async setMessagesUnreadCount(value) { return this.setUnreadCount('messages', value); }
|
|||
|
|
// 获取未读计数
|
|||
|
|
getUnreadCount(type) {
|
|||
|
|
return this.unreadCounts[type] || 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 获取总未读计数
|
|||
|
|
getTotalUnreadCount() {
|
|||
|
|
return Object.values(this.unreadCounts).reduce((total, count) => total + count, 0);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 更新通知设置
|
|||
|
|
updateNotificationSettings(settings) {
|
|||
|
|
this.notificationSettings = { ...this.notificationSettings, ...settings };
|
|||
|
|
this.saveNotificationSettings();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 请求订阅消息权限
|
|||
|
|
async requestSubscribeMessage(templateIds) {
|
|||
|
|
try {
|
|||
|
|
const result = await new Promise((resolve, reject) => {
|
|||
|
|
wx.requestSubscribeMessage({
|
|||
|
|
tmplIds: Array.isArray(templateIds) ? templateIds : [templateIds],
|
|||
|
|
success: resolve,
|
|||
|
|
fail: reject
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
return result;
|
|||
|
|
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('❌ 请求订阅消息权限失败:', error);
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 事件处理器
|
|||
|
|
eventHandlers = new Map();
|
|||
|
|
|
|||
|
|
// 注册事件监听器
|
|||
|
|
on(event, handler) {
|
|||
|
|
if (!this.eventHandlers.has(event)) {
|
|||
|
|
this.eventHandlers.set(event, []);
|
|||
|
|
}
|
|||
|
|
this.eventHandlers.get(event).push(handler);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 移除事件监听器
|
|||
|
|
off(event, handler) {
|
|||
|
|
const handlers = this.eventHandlers.get(event);
|
|||
|
|
if (handlers) {
|
|||
|
|
const index = handlers.indexOf(handler);
|
|||
|
|
if (index > -1) {
|
|||
|
|
handlers.splice(index, 1);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 触发事件
|
|||
|
|
triggerEvent(event, data) {
|
|||
|
|
const handlers = this.eventHandlers.get(event);
|
|||
|
|
if (handlers) {
|
|||
|
|
handlers.forEach(handler => {
|
|||
|
|
try {
|
|||
|
|
handler(data);
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error(`❌ 事件处理器错误 [${event}]:`, error);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 获取通知管理器状态
|
|||
|
|
getStatus() {
|
|||
|
|
return {
|
|||
|
|
isInitialized: this.isInitialized,
|
|||
|
|
unreadCounts: { ...this.unreadCounts },
|
|||
|
|
notificationSettings: { ...this.notificationSettings },
|
|||
|
|
totalUnread: this.getTotalUnreadCount()
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 重置通知管理器
|
|||
|
|
reset() {
|
|||
|
|
this.unreadCounts = {
|
|||
|
|
messages: 0,
|
|||
|
|
friends: 0,
|
|||
|
|
system: 0
|
|||
|
|
};
|
|||
|
|
this.saveUnreadCounts();
|
|||
|
|
this.updateTabBarBadge();
|
|||
|
|
this.eventHandlers.clear();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 创建全局实例
|
|||
|
|
const notificationManager = new NotificationManager();
|
|||
|
|
|
|||
|
|
module.exports = notificationManager;
|
|||
|
|
|