From a00b8bb73da16e5be081c64a2ef553ed9ad65acd Mon Sep 17 00:00:00 2001 From: zzlgreat Date: Mon, 10 Nov 2025 12:45:34 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BA=8B=E4=BB=B6=E4=B8=AD=E5=BF=83ui?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/contexts/NotificationContext.js | 40 +++++++++++---- src/index.js | 4 ++ src/services/browserNotificationService.js | 58 ++++++++++++++++++++-- 3 files changed, 88 insertions(+), 14 deletions(-) diff --git a/src/contexts/NotificationContext.js b/src/contexts/NotificationContext.js index b6d4853b..13e09aa4 100644 --- a/src/contexts/NotificationContext.js +++ b/src/contexts/NotificationContext.js @@ -292,8 +292,13 @@ export const NotificationProvider = ({ children }) => { * 发送浏览器通知 */ const sendBrowserNotification = useCallback((notificationData) => { + console.log('[NotificationContext] 🔔 sendBrowserNotification 被调用'); + console.log('[NotificationContext] 通知数据:', notificationData); + console.log('[NotificationContext] 当前浏览器权限:', browserPermission); + if (browserPermission !== 'granted') { logger.warn('NotificationContext', 'Browser permission not granted'); + console.warn('[NotificationContext] ❌ 浏览器权限未授予,无法发送通知'); return; } @@ -305,6 +310,14 @@ export const NotificationProvider = ({ children }) => { // 判断是否需要用户交互(紧急通知不自动关闭) const requireInteraction = priority === PRIORITY_LEVELS.URGENT; + console.log('[NotificationContext] ✅ 准备发送浏览器通知:', { + title, + body: content, + tag, + requireInteraction, + link + }); + // 发送浏览器通知 const notification = browserNotificationService.sendNotification({ title: title || '新通知', @@ -315,17 +328,24 @@ export const NotificationProvider = ({ children }) => { autoClose: requireInteraction ? 0 : 8000, }); - // 设置点击处理(聚焦窗口并跳转) - if (notification && link) { - notification.onclick = () => { - window.focus(); - // 使用 window.location 跳转(不需要 React Router) - window.location.hash = link; - notification.close(); - }; - } + if (notification) { + console.log('[NotificationContext] ✅ 通知对象创建成功:', notification); - logger.info('NotificationContext', 'Browser notification sent', { title, tag }); + // 设置点击处理(聚焦窗口并跳转) + if (link) { + notification.onclick = () => { + console.log('[NotificationContext] 通知被点击,跳转到:', link); + window.focus(); + // 使用 window.location 跳转(不需要 React Router) + window.location.hash = link; + notification.close(); + }; + } + + logger.info('NotificationContext', 'Browser notification sent', { title, tag }); + } else { + console.error('[NotificationContext] ❌ 通知对象创建失败!'); + } }, [browserPermission]); /** diff --git a/src/index.js b/src/index.js index 39aa8161..c4350120 100755 --- a/src/index.js +++ b/src/index.js @@ -9,6 +9,10 @@ import './styles/brainwave-colors.css'; // Import the main App component import App from './App'; +// 导入通知服务并挂载到 window(用于调试) +import { browserNotificationService } from './services/browserNotificationService'; +window.browserNotificationService = browserNotificationService; + // 注册 Service Worker(用于支持浏览器通知) function registerServiceWorker() { // ⚠️ Mock 模式下跳过 Service Worker 注册(避免与 MSW 冲突) diff --git a/src/services/browserNotificationService.js b/src/services/browserNotificationService.js index 5eb8615b..a7291a5c 100644 --- a/src/services/browserNotificationService.js +++ b/src/services/browserNotificationService.js @@ -30,6 +30,14 @@ class BrowserNotificationService { return Notification.permission; } + /** + * 检查是否有通知权限 + * @returns {boolean} + */ + hasPermission() { + return this.isSupported() && Notification.permission === 'granted'; + } + /** * 请求通知权限 * @returns {Promise} 权限状态 @@ -77,57 +85,99 @@ class BrowserNotificationService { data = {}, autoClose = 0, }) { + // 详细日志:检查支持状态 if (!this.isSupported()) { logger.warn('browserNotificationService', 'Notifications not supported'); + console.warn('[browserNotificationService] ❌ 浏览器不支持通知 API'); return null; } - if (this.permission !== 'granted') { - logger.warn('browserNotificationService', 'Permission not granted'); + // 详细日志:检查权限状态 + const currentPermission = Notification.permission; + console.log('[browserNotificationService] 当前权限状态:', currentPermission); + + if (currentPermission !== 'granted') { + logger.warn('browserNotificationService', 'Permission not granted', { permission: currentPermission }); + console.warn(`[browserNotificationService] ❌ 权限未授予: ${currentPermission}`); return null; } + console.log('[browserNotificationService] ✅ 准备发送通知:', { title, body, tag, requireInteraction, autoClose }); + try { // 关闭相同 tag 的旧通知 if (tag && this.activeNotifications.has(tag)) { const oldNotification = this.activeNotifications.get(tag); oldNotification.close(); + console.log('[browserNotificationService] 关闭旧通知:', tag); } // 创建通知 + const finalTag = tag || `notification_${Date.now()}`; + console.log('[browserNotificationService] 创建通知对象...'); + const notification = new Notification(title, { body, icon, badge: '/badge.png', - tag: tag || `notification_${Date.now()}`, + tag: finalTag, requireInteraction, data, silent: false, // 允许声音 }); + console.log('[browserNotificationService] ✅ 通知对象已创建:', notification); + // 存储通知引用 if (tag) { this.activeNotifications.set(tag, notification); + console.log('[browserNotificationService] 通知已存储到活跃列表'); } // 自动关闭 if (autoClose > 0 && !requireInteraction) { + console.log(`[browserNotificationService] 设置自动关闭: ${autoClose}ms`); setTimeout(() => { notification.close(); + console.log('[browserNotificationService] 通知已自动关闭'); }, autoClose); } // 通知关闭时清理引用 notification.onclose = () => { + console.log('[browserNotificationService] 通知被关闭:', finalTag); if (tag) { this.activeNotifications.delete(tag); } }; - logger.info('browserNotificationService', 'Notification sent', { title, tag }); + // 通知点击事件 + notification.onclick = (event) => { + console.log('[browserNotificationService] 通知被点击:', finalTag, data); + }; + + // 通知显示事件 + notification.onshow = () => { + console.log('[browserNotificationService] ✅ 通知已显示:', finalTag); + }; + + // 通知错误事件 + notification.onerror = (error) => { + console.error('[browserNotificationService] ❌ 通知显示错误:', error); + }; + + logger.info('browserNotificationService', 'Notification sent', { title, tag: finalTag }); + console.log('[browserNotificationService] ✅ 通知发送成功!'); + return notification; } catch (error) { logger.error('browserNotificationService', 'sendNotification', error); + console.error('[browserNotificationService] ❌ 发送通知时发生错误:', error); + console.error('[browserNotificationService] 错误详情:', { + name: error.name, + message: error.message, + stack: error.stack + }); return null; } }