// src/views/EventDetail/hooks/useEventDetailEvents.js // 事件详情页面事件追踪 Hook import { useCallback, useEffect } from 'react'; import { usePostHogTrack } from '../../../hooks/usePostHogRedux'; import { RETENTION_EVENTS } from '../../../lib/constants'; import { logger } from '../../../utils/logger'; /** * 事件详情(EventDetail)事件追踪 Hook * @param {Object} options - 配置选项 * @param {Object} options.event - 事件对象 * @param {number} options.event.id - 事件ID * @param {string} options.event.title - 事件标题 * @param {string} options.event.importance - 重要性等级 * @param {Function} options.navigate - 路由导航函数 * @returns {Object} 事件追踪处理函数集合 */ export const useEventDetailEvents = ({ event, navigate } = {}) => { const { track } = usePostHogTrack(); // 🎯 页面浏览事件 - 页面加载时触发 useEffect(() => { if (!event || !event.id) { logger.warn('useEventDetailEvents', 'Event object is required for page view tracking'); return; } track(RETENTION_EVENTS.EVENT_DETAIL_VIEWED, { event_id: event.id, event_title: event.title || '', importance: event.importance || 'unknown', timestamp: new Date().toISOString(), }); logger.debug('useEventDetailEvents', '📄 Event Detail Page Viewed', { eventId: event.id, }); }, [track, event]); /** * 追踪事件分析内容查看 * @param {Object} analysisData - 分析数据 * @param {string} analysisData.type - 分析类型 ('market_impact' | 'stock_correlation' | 'timeline') * @param {number} analysisData.relatedStockCount - 相关股票数量 * @param {number} analysisData.timelineEventCount - 时间线事件数量 */ const trackEventAnalysisViewed = useCallback((analysisData = {}) => { if (!event || !event.id) { logger.warn('useEventDetailEvents', 'Event object is required for analysis tracking'); return; } track(RETENTION_EVENTS.EVENT_ANALYSIS_VIEWED, { event_id: event.id, analysis_type: analysisData.type || 'overview', related_stock_count: analysisData.relatedStockCount || 0, timeline_event_count: analysisData.timelineEventCount || 0, has_market_impact: Boolean(analysisData.marketImpact), timestamp: new Date().toISOString(), }); logger.debug('useEventDetailEvents', '📊 Event Analysis Viewed', { eventId: event.id, analysisType: analysisData.type, }); }, [track, event]); /** * 追踪事件时间线点击 * @param {Object} timelineItem - 时间线项目 * @param {string} timelineItem.id - 时间线项目ID * @param {string} timelineItem.date - 时间线日期 * @param {string} timelineItem.title - 时间线标题 * @param {number} position - 在时间线中的位置 */ const trackEventTimelineClicked = useCallback((timelineItem, position = 0) => { if (!timelineItem || !timelineItem.id) { logger.warn('useEventDetailEvents', 'Timeline item is required'); return; } if (!event || !event.id) { logger.warn('useEventDetailEvents', 'Event object is required for timeline tracking'); return; } track(RETENTION_EVENTS.EVENT_TIMELINE_CLICKED, { event_id: event.id, timeline_item_id: timelineItem.id, timeline_date: timelineItem.date || '', timeline_title: timelineItem.title || '', position, timestamp: new Date().toISOString(), }); logger.debug('useEventDetailEvents', '⏰ Event Timeline Clicked', { eventId: event.id, timelineItemId: timelineItem.id, position, }); }, [track, event]); /** * 追踪相关股票点击(从事件详情) * @param {Object} stock - 股票对象 * @param {string} stock.code - 股票代码 * @param {string} stock.name - 股票名称 * @param {number} position - 在列表中的位置 */ const trackRelatedStockClicked = useCallback((stock, position = 0) => { if (!stock || !stock.code) { logger.warn('useEventDetailEvents', 'Stock object is required'); return; } if (!event || !event.id) { logger.warn('useEventDetailEvents', 'Event object is required for stock tracking'); return; } track(RETENTION_EVENTS.STOCK_CLICKED, { stock_code: stock.code, stock_name: stock.name || '', source: 'event_detail_related_stocks', event_id: event.id, position, timestamp: new Date().toISOString(), }); logger.debug('useEventDetailEvents', '🎯 Related Stock Clicked', { stockCode: stock.code, eventId: event.id, position, }); }, [track, event]); /** * 追踪相关概念点击(从事件详情) * @param {Object} concept - 概念对象 * @param {string} concept.code - 概念代码 * @param {string} concept.name - 概念名称 * @param {number} position - 在列表中的位置 */ const trackRelatedConceptClicked = useCallback((concept, position = 0) => { if (!concept || !concept.code) { logger.warn('useEventDetailEvents', 'Concept object is required'); return; } if (!event || !event.id) { logger.warn('useEventDetailEvents', 'Event object is required for concept tracking'); return; } track(RETENTION_EVENTS.CONCEPT_CLICKED, { concept_code: concept.code, concept_name: concept.name || '', source: 'event_detail_related_concepts', event_id: event.id, position, timestamp: new Date().toISOString(), }); logger.debug('useEventDetailEvents', '🏷️ Related Concept Clicked', { conceptCode: concept.code, eventId: event.id, position, }); }, [track, event]); /** * 追踪标签页切换 * @param {string} tabName - 标签名称 ('overview' | 'related_stocks' | 'related_concepts' | 'timeline') */ const trackTabClicked = useCallback((tabName) => { if (!tabName) { logger.warn('useEventDetailEvents', 'Tab name is required'); return; } if (!event || !event.id) { logger.warn('useEventDetailEvents', 'Event object is required for tab tracking'); return; } track(RETENTION_EVENTS.NEWS_TAB_CLICKED, { tab_name: tabName, event_id: event.id, context: 'event_detail', timestamp: new Date().toISOString(), }); logger.debug('useEventDetailEvents', '📑 Tab Clicked', { tabName, eventId: event.id, }); }, [track, event]); /** * 追踪事件收藏/取消收藏 * @param {boolean} isFavorited - 是否收藏 */ const trackEventFavoriteToggled = useCallback((isFavorited) => { if (!event || !event.id) { logger.warn('useEventDetailEvents', 'Event object is required for favorite tracking'); return; } const eventName = isFavorited ? 'Event Favorited' : 'Event Unfavorited'; track(eventName, { event_id: event.id, event_title: event.title || '', action: isFavorited ? 'add' : 'remove', timestamp: new Date().toISOString(), }); logger.debug('useEventDetailEvents', `${isFavorited ? '⭐' : '☆'} Event Favorite Toggled`, { eventId: event.id, isFavorited, }); }, [track, event]); /** * 追踪事件分享 * @param {string} shareMethod - 分享方式 ('wechat' | 'link' | 'qrcode') */ const trackEventShared = useCallback((shareMethod) => { if (!shareMethod) { logger.warn('useEventDetailEvents', 'Share method is required'); return; } if (!event || !event.id) { logger.warn('useEventDetailEvents', 'Event object is required for share tracking'); return; } track(RETENTION_EVENTS.CONTENT_SHARED, { content_type: 'event', content_id: event.id, content_title: event.title || '', share_method: shareMethod, timestamp: new Date().toISOString(), }); logger.debug('useEventDetailEvents', '📤 Event Shared', { eventId: event.id, shareMethod, }); }, [track, event]); /** * 追踪评论点赞/取消点赞 * @param {string} commentId - 评论ID * @param {boolean} isLiked - 是否点赞 */ const trackCommentLiked = useCallback((commentId, isLiked) => { if (!commentId) { logger.warn('useEventDetailEvents', 'Comment ID is required'); return; } track(isLiked ? 'Comment Liked' : 'Comment Unliked', { comment_id: commentId, event_id: event?.id, action: isLiked ? 'like' : 'unlike', timestamp: new Date().toISOString(), }); logger.debug('useEventDetailEvents', `${isLiked ? '❤️' : '🤍'} Comment ${isLiked ? 'Liked' : 'Unliked'}`, { commentId, eventId: event?.id, }); }, [track, event]); /** * 追踪添加评论 * @param {string} commentId - 评论ID * @param {number} contentLength - 评论内容长度 */ const trackCommentAdded = useCallback((commentId, contentLength = 0) => { if (!event || !event.id) { logger.warn('useEventDetailEvents', 'Event object is required for comment tracking'); return; } track('Comment Added', { comment_id: commentId, event_id: event.id, content_length: contentLength, timestamp: new Date().toISOString(), }); logger.debug('useEventDetailEvents', '💬 Comment Added', { commentId, eventId: event.id, contentLength, }); }, [track, event]); /** * 追踪删除评论 * @param {string} commentId - 评论ID */ const trackCommentDeleted = useCallback((commentId) => { if (!commentId) { logger.warn('useEventDetailEvents', 'Comment ID is required'); return; } track('Comment Deleted', { comment_id: commentId, event_id: event?.id, timestamp: new Date().toISOString(), }); logger.debug('useEventDetailEvents', '🗑️ Comment Deleted', { commentId, eventId: event?.id, }); }, [track, event]); return { // 页面级事件 trackEventAnalysisViewed, // 交互事件 trackEventTimelineClicked, trackRelatedStockClicked, trackRelatedConceptClicked, trackTabClicked, // 用户行为事件 trackEventFavoriteToggled, trackEventShared, // 社交互动事件 trackCommentLiked, trackCommentAdded, trackCommentDeleted, }; }; export default useEventDetailEvents;