From b2f252602895157fddd458fa691a5e5a9a6a29de Mon Sep 17 00:00:00 2001 From: wangdongbo <949818794@qq.com> Date: Wed, 11 Feb 2026 09:51:02 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A7=A3=E5=86=B3=E6=9C=AA=E8=AF=BB=E6=B6=88?= =?UTF-8?q?=E6=81=AF=E6=98=BE=E7=A4=BA=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- App.vue | 3 + pages/message/index.vue | 16 +- pages/message/message.vue | 281 +++++++++++++++++++------------- store/account.js | 15 ++ utils/global-unread-listener.js | 146 +++++++++++++---- 5 files changed, 315 insertions(+), 146 deletions(-) diff --git a/App.vue b/App.vue index 0fa925e..b4a9dbf 100644 --- a/App.vue +++ b/App.vue @@ -1,6 +1,7 @@ diff --git a/store/account.js b/store/account.js index a48647a..0c62dd8 100644 --- a/store/account.js +++ b/store/account.js @@ -3,6 +3,7 @@ import { defineStore } from "pinia"; import api from '@/utils/api'; import { toast } from '@/utils/widget'; import { initGlobalTIM, globalTimChatManager } from "@/utils/tim-chat.js"; +import { globalUnreadListenerManager } from "@/utils/global-unread-listener.js"; const env = __VITE_ENV__; export default defineStore("accountStore", () => { @@ -76,6 +77,10 @@ export default defineStore("accountStore", () => { isIMInitialized.value = true; console.log('IM 初始化成功'); + + // IM 初始化成功后,设置全局未读消息监听 + globalUnreadListenerManager.setup(); + return true; } catch (error) { console.log('IM初始化异常,跳过 IM 初始化:', error.message); @@ -91,6 +96,11 @@ export default defineStore("accountStore", () => { await globalTimChatManager.destroy(); console.log('腾讯IM退出成功'); } + + // 清除全局未读监听 + if (globalUnreadListenerManager.isInitialized) { + globalUnreadListenerManager.destroy(); + } } catch (error) { console.error('退出腾讯IM失败:', error); } @@ -103,6 +113,11 @@ export default defineStore("accountStore", () => { // 清除本地存储 uni.removeStorageSync('account'); uni.removeStorageSync('openid'); + + // 清除 tabBar 徽章 + uni.removeTabBarBadge({ + index: 1 + }); } async function getExternalUserId(corpId) { diff --git a/utils/global-unread-listener.js b/utils/global-unread-listener.js index 5be30c6..1baff59 100644 --- a/utils/global-unread-listener.js +++ b/utils/global-unread-listener.js @@ -7,8 +7,11 @@ import { globalTimChatManager } from './tim-chat.js'; class GlobalUnreadListenerManager { constructor() { this.isInitialized = false; - this.originalConversationListCallback = null; - this.originalMessageReceivedCallback = null; + this.callbackChain = { + onConversationListUpdated: [], + onMessageReceived: [] + }; + this.updateTimer = null; // 防抖定时器 } /** @@ -25,39 +28,76 @@ class GlobalUnreadListenerManager { return; } - // 保存原始回调(在覆盖前保存) - this.originalConversationListCallback = globalTimChatManager.callbacks.onConversationListUpdated; - this.originalMessageReceivedCallback = globalTimChatManager.callbacks.onMessageReceived; + // 保存原始回调到回调链 + const originalConversationListCallback = globalTimChatManager.callbacks.onConversationListUpdated; + const originalMessageReceivedCallback = globalTimChatManager.callbacks.onMessageReceived; - console.log('保存原始回调:', { - hasConversationListCallback: !!this.originalConversationListCallback, - hasMessageReceivedCallback: !!this.originalMessageReceivedCallback + if (originalConversationListCallback && typeof originalConversationListCallback === 'function') { + this.callbackChain.onConversationListUpdated.push(originalConversationListCallback); + } + if (originalMessageReceivedCallback && typeof originalMessageReceivedCallback === 'function') { + this.callbackChain.onMessageReceived.push(originalMessageReceivedCallback); + } + + console.log('全局未读监听初始化,回调链长度:', { + onConversationListUpdated: this.callbackChain.onConversationListUpdated.length, + onMessageReceived: this.callbackChain.onMessageReceived.length }); // 监听会话列表更新事件(包括消息接收和已读状态变化) globalTimChatManager.setCallback('onConversationListUpdated', (eventData) => { - console.log('onConversationListUpdated 触发,调用原始回调'); - // 调用原始回调(如果存在) - if (this.originalConversationListCallback && typeof this.originalConversationListCallback === 'function') { - this.originalConversationListCallback(eventData); - } - // 更新 tabBar 徽章 - this.updateTabBarBadge(); + console.log('【全局未读监听】onConversationListUpdated 触发,回调链长度:', this.callbackChain.onConversationListUpdated.length); + + // 执行回调链中的所有回调 + this.callbackChain.onConversationListUpdated.forEach((callback, index) => { + try { + console.log(`【全局未读监听】执行回调链 #${index + 1}`); + callback(eventData); + } catch (error) { + console.error(`【全局未读监听】执行 onConversationListUpdated 回调 #${index + 1} 失败:`, error); + } + }); + + // 防抖更新 tabBar 徽章 + this.debouncedUpdateTabBarBadge(); }); // 监听消息接收事件 globalTimChatManager.setCallback('onMessageReceived', (message) => { - console.log('onMessageReceived 触发,调用原始回调'); - // 调用原始回调(如果存在) - if (this.originalMessageReceivedCallback && typeof this.originalMessageReceivedCallback === 'function') { - this.originalMessageReceivedCallback(message); - } - // 更新 tabBar 徽章 - this.updateTabBarBadge(); + console.log('【全局未读监听】onMessageReceived 触发,回调链长度:', this.callbackChain.onMessageReceived.length); + + // 执行回调链中的所有回调 + this.callbackChain.onMessageReceived.forEach((callback, index) => { + try { + console.log(`【全局未读监听】执行回调链 #${index + 1}`); + callback(message); + } catch (error) { + console.error(`【全局未读监听】执行 onMessageReceived 回调 #${index + 1} 失败:`, error); + } + }); + + // 防抖更新 tabBar 徽章 + this.debouncedUpdateTabBarBadge(); }); this.isInitialized = true; console.log('全局未读消息监听已设置'); + + // 初始化时立即更新一次徽章 + this.updateTabBarBadge(); + } + + /** + * 防抖更新 tabBar 徽章 + * 避免频繁更新导致性能问题 + */ + debouncedUpdateTabBarBadge() { + if (this.updateTimer) { + clearTimeout(this.updateTimer); + } + this.updateTimer = setTimeout(() => { + this.updateTabBarBadge(); + }, 200); // 减少到 200ms 防抖延迟,提高响应速度 } /** @@ -67,21 +107,22 @@ class GlobalUnreadListenerManager { async updateTabBarBadge() { try { if (!globalTimChatManager || !globalTimChatManager.tim) { - console.warn('globalTimChatManager 或 tim 未初始化'); + console.warn('【全局未读监听】globalTimChatManager 或 tim 未初始化'); return; } const response = await globalTimChatManager.tim.getConversationList(); if (!response || !response.data || !response.data.conversationList) { - console.warn('获取会话列表返回数据异常'); + console.warn('【全局未读监听】获取会话列表返回数据异常'); return; } const totalUnreadCount = this.calculateGroupUnreadCount(response.data.conversationList); + console.log('【全局未读监听】计算总未读数:', totalUnreadCount); this.setTabBarBadge(totalUnreadCount); } catch (error) { - console.error('更新 tabBar 徽章失败:', error); + console.error('【全局未读监听】更新 tabBar 徽章失败:', error); } } @@ -107,25 +148,68 @@ class GlobalUnreadListenerManager { index: tabIndex, text: count > 99 ? '99+' : String(count) }); - console.log(`已更新 tabBar 徽章(索引 ${tabIndex}):`, count); + console.log(`✓ 已更新 tabBar 徽章(索引 ${tabIndex}):`, count); } else { - // uni.removeTabBarBadge({ - // index: tabIndex - // }); - console.log(`已移除 tabBar 徽章(索引 ${tabIndex})`); + uni.removeTabBarBadge({ + index: tabIndex + }); + console.log(`✓ 已移除 tabBar 徽章(索引 ${tabIndex})`); } } - + /** + * 手动刷新徽章 + * 用于页面显示时强制刷新 + */ async refreshBadge() { console.log('手动刷新 tabBar 徽章'); await this.updateTabBarBadge(); } + /** + * 添加回调到回调链 + * @param {string} eventName - 事件名称 + * @param {Function} callback - 回调函数 + */ + addCallback(eventName, callback) { + if (this.callbackChain[eventName] && typeof callback === 'function') { + // 避免重复添加同一个回调 + if (!this.callbackChain[eventName].includes(callback)) { + this.callbackChain[eventName].push(callback); + console.log(`✓ 已添加回调到 ${eventName} 回调链,当前链长度:`, this.callbackChain[eventName].length); + } else { + console.log(`⚠️ 回调已存在于 ${eventName} 回调链中,跳过添加`); + } + } + } + + /** + * 从回调链中移除回调 + * @param {string} eventName - 事件名称 + * @param {Function} callback - 回调函数 + */ + removeCallback(eventName, callback) { + if (this.callbackChain[eventName]) { + const index = this.callbackChain[eventName].indexOf(callback); + if (index > -1) { + this.callbackChain[eventName].splice(index, 1); + console.log(`✓ 已从 ${eventName} 回调链移除回调,当前链长度:`, this.callbackChain[eventName].length); + } + } + } + /** * 清除监听(可选) */ destroy() { + if (this.updateTimer) { + clearTimeout(this.updateTimer); + this.updateTimer = null; + } + this.callbackChain = { + onConversationListUpdated: [], + onMessageReceived: [] + }; this.isInitialized = false; console.log('全局未读消息监听已清除'); }