From 16d04a6d2884028f4b542c20a70c27675f233693 Mon Sep 17 00:00:00 2001 From: zzlgreat Date: Fri, 24 Oct 2025 14:22:30 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B0=83=E6=95=B4socket=E5=AF=B9=E5=BA=94?= =?UTF-8?q?=E7=9A=84=E6=B5=8F=E8=A7=88=E5=99=A8=E9=80=9A=E7=9F=A5=E5=A4=84?= =?UTF-8?q?=E7=90=86=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .claude/settings.local.json | 3 +- src/hooks/useEventNotifications.js | 27 +++++++++++--- src/views/Community/components/EventList.js | 41 +++++++++++++++++++++ 3 files changed, 65 insertions(+), 6 deletions(-) diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 3ff26080..b240878e 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -5,7 +5,8 @@ "Bash(npm run lint:check)", "Bash(npm run build)", "Bash(chmod +x /Users/qiye/Desktop/jzqy/vf_react/scripts/*.sh)", - "Bash(node scripts/parseIndustryCSV.js)" + "Bash(node scripts/parseIndustryCSV.js)", + "Bash(cat:*)" ], "deny": [], "ask": [] diff --git a/src/hooks/useEventNotifications.js b/src/hooks/useEventNotifications.js index e23de785..ec1a13e0 100644 --- a/src/hooks/useEventNotifications.js +++ b/src/hooks/useEventNotifications.js @@ -60,30 +60,47 @@ export const useEventNotifications = (options = {}) => { // 连接状态监听 const handleConnect = () => { console.log('[useEventNotifications DEBUG] ✓ WebSocket 已连接'); + logger.info('useEventNotifications', 'WebSocket connected'); setIsConnected(true); setError(null); }; const handleDisconnect = () => { console.log('[useEventNotifications DEBUG] ⚠️ WebSocket 已断开'); + logger.warn('useEventNotifications', 'WebSocket disconnected'); setIsConnected(false); }; const handleConnectError = (err) => { console.error('[useEventNotifications ERROR] WebSocket 连接错误:', err); + logger.error('useEventNotifications', 'WebSocket connect error', err); setError(err); setIsConnected(false); }; - // 连接 WebSocket - console.log('[useEventNotifications DEBUG] 准备连接 WebSocket...'); - socketService.connect(); - - // 监听连接事件 + // 监听连接事件(必须在connect之前设置,否则可能错过事件) socketService.on('connect', handleConnect); socketService.on('disconnect', handleDisconnect); socketService.on('connect_error', handleConnectError); + // 连接 WebSocket + console.log('[useEventNotifications DEBUG] 准备连接 WebSocket...'); + logger.info('useEventNotifications', 'Initializing WebSocket connection'); + + // 先检查是否已经连接 + const alreadyConnected = socketService.isConnected(); + console.log('[useEventNotifications DEBUG] 当前连接状态:', alreadyConnected); + logger.info('useEventNotifications', 'Pre-connection check', { isConnected: alreadyConnected }); + + if (alreadyConnected) { + // 如果已经连接,直接更新状态 + console.log('[useEventNotifications DEBUG] Socket已连接,直接更新状态'); + setIsConnected(true); + } else { + // 否则建立新连接 + socketService.connect(); + } + // 新事件处理函数 - 使用 ref 中的回调 const handleNewEvent = (eventData) => { console.log('\n[useEventNotifications DEBUG] ========== Hook 收到新事件 =========='); diff --git a/src/views/Community/components/EventList.js b/src/views/Community/components/EventList.js index fbdaf461..0cca9438 100644 --- a/src/views/Community/components/EventList.js +++ b/src/views/Community/components/EventList.js @@ -56,6 +56,7 @@ import { logger } from '../../../utils/logger'; import { getApiBase } from '../../../utils/apiConfig'; import { useEventNotifications } from '../../../hooks/useEventNotifications'; import { getImportanceConfig, getAllImportanceLevels } from '../../../constants/importanceLevels'; +import { browserNotificationService } from '../../../services/browserNotificationService'; // ========== 工具函数定义在组件外部 ========== // 涨跌颜色配置(中国A股配色:红涨绿跌)- 分档次显示 @@ -136,6 +137,19 @@ const EventList = ({ events, pagination, onPageChange, onEventClick, onViewDetai const [followingMap, setFollowingMap] = useState({}); const [followCountMap, setFollowCountMap] = useState({}); const [localEvents, setLocalEvents] = useState(events); // 用于实时更新的本地事件列表 + const [notificationPermission, setNotificationPermission] = useState('default'); + + // 请求浏览器通知权限 + useEffect(() => { + const requestPermission = async () => { + if (browserNotificationService.isSupported()) { + const permission = await browserNotificationService.requestPermission(); + setNotificationPermission(permission); + logger.info('EventList', '浏览器通知权限状态', { permission }); + } + }; + requestPermission(); + }, []); // 实时事件推送集成 const { isConnected } = useEventNotifications({ @@ -162,6 +176,33 @@ const EventList = ({ events, pagination, onPageChange, onEventClick, onViewDetai }); console.log('[EventList DEBUG] ✓ Toast 通知已调用,ID:', toastId); + // 发送浏览器原生通知 + console.log('[EventList DEBUG] 准备发送浏览器原生通知'); + const currentPermission = browserNotificationService.getPermissionStatus(); + console.log('[EventList DEBUG] 通知权限状态:', currentPermission); + if (currentPermission === 'granted') { + const importance = getImportanceConfig(event.importance); + const notification = browserNotificationService.sendNotification({ + title: `🔔 ${importance.label}级事件`, + body: event.title, + tag: `event_${event.id}`, + data: { + link: `/event-detail/${event.id}`, + eventId: event.id, + }, + autoClose: 10000, // 10秒后自动关闭 + }); + + if (notification) { + browserNotificationService.setupClickHandler(notification, navigate); + console.log('[EventList DEBUG] ✓ 浏览器原生通知已发送'); + } else { + console.log('[EventList DEBUG] ⚠️ 浏览器原生通知发送失败'); + } + } else { + console.log('[EventList DEBUG] ⚠️ 浏览器通知权限未授予,跳过原生通知'); + } + console.log('[EventList DEBUG] 准备更新事件列表'); // 将新事件添加到列表顶部(防止重复) setLocalEvents((prevEvents) => {