// src/views/Concept/hooks/useConceptEvents.js // 概念中心页面事件追踪 Hook import { useCallback, useEffect } from 'react'; import { usePostHogTrack } from '../../../hooks/usePostHogRedux'; import { RETENTION_EVENTS, REVENUE_EVENTS } from '../../../lib/constants'; import { logger } from '../../../utils/logger'; /** * 概念中心事件追踪 Hook * @param {Object} options - 配置选项 * @param {Function} options.navigate - 路由导航函数 * @returns {Object} 事件追踪处理函数集合 */ export const useConceptEvents = ({ navigate } = {}) => { const { track } = usePostHogTrack(); // 🎯 页面浏览事件 - 页面加载时触发 useEffect(() => { track(RETENTION_EVENTS.CONCEPT_PAGE_VIEWED, { timestamp: new Date().toISOString(), }); logger.debug('useConceptEvents', '📊 Concept Page Viewed'); }, [track]); /** * 追踪概念列表数据查看 * @param {Array} concepts - 概念列表 * @param {Object} filters - 当前筛选条件 */ const trackConceptListViewed = useCallback((concepts, filters = {}) => { track(RETENTION_EVENTS.CONCEPT_LIST_VIEWED, { concept_count: concepts.length, sort_by: filters.sortBy, view_mode: filters.viewMode, has_search_query: !!filters.searchQuery, selected_date: filters.selectedDate, page: filters.page, }); logger.debug('useConceptEvents', '📋 Concept List Viewed', { count: concepts.length, filters, }); }, [track]); /** * 追踪搜索开始 */ const trackSearchInitiated = useCallback(() => { track(RETENTION_EVENTS.SEARCH_INITIATED, { context: 'concept_center', }); logger.debug('useConceptEvents', '🔍 Search Initiated'); }, [track]); /** * 追踪搜索查询提交 * @param {string} query - 搜索查询词 * @param {number} resultCount - 搜索结果数量 */ const trackSearchQuerySubmitted = useCallback((query, resultCount = 0) => { if (!query) return; track(RETENTION_EVENTS.SEARCH_QUERY_SUBMITTED, { query, category: 'concept', result_count: resultCount, has_results: resultCount > 0, }); // 如果没有搜索结果,额外追踪 if (resultCount === 0) { track(RETENTION_EVENTS.SEARCH_NO_RESULTS, { query, context: 'concept_center', }); } logger.debug('useConceptEvents', '🔍 Search Query Submitted', { query, resultCount, }); }, [track]); /** * 追踪排序方式变化 * @param {string} sortBy - 新的排序方式 * @param {string} previousSortBy - 之前的排序方式 */ const trackSortChanged = useCallback((sortBy, previousSortBy = null) => { track(RETENTION_EVENTS.SEARCH_FILTER_APPLIED, { filter_type: 'sort', filter_value: sortBy, previous_value: previousSortBy, context: 'concept_center', }); logger.debug('useConceptEvents', '🔄 Sort Changed', { sortBy, previousSortBy, }); }, [track]); /** * 追踪视图模式切换 * @param {string} viewMode - 新的视图模式 (grid/list) * @param {string} previousViewMode - 之前的视图模式 */ const trackViewModeChanged = useCallback((viewMode, previousViewMode = null) => { track(RETENTION_EVENTS.SEARCH_FILTER_APPLIED, { filter_type: 'view_mode', filter_value: viewMode, previous_value: previousViewMode, context: 'concept_center', }); logger.debug('useConceptEvents', '👁️ View Mode Changed', { viewMode, previousViewMode, }); }, [track]); /** * 追踪日期选择变化 * @param {string} newDate - 新选择的日期 * @param {string} previousDate - 之前的日期 * @param {string} selectionMethod - 选择方式 (today/yesterday/week_ago/month_ago/custom) */ const trackDateChanged = useCallback((newDate, previousDate = null, selectionMethod = 'custom') => { track(RETENTION_EVENTS.SEARCH_FILTER_APPLIED, { filter_type: 'date', filter_value: newDate, previous_value: previousDate, selection_method: selectionMethod, context: 'concept_center', }); logger.debug('useConceptEvents', '📅 Date Changed', { newDate, previousDate, selectionMethod, }); }, [track]); /** * 追踪分页变化 * @param {number} page - 新的页码 * @param {Object} filters - 当前筛选条件 */ const trackPageChanged = useCallback((page, filters = {}) => { track(RETENTION_EVENTS.CONCEPT_LIST_VIEWED, { page, sort_by: filters.sortBy, view_mode: filters.viewMode, has_search_query: !!filters.searchQuery, }); logger.debug('useConceptEvents', '📄 Page Changed', { page, filters }); }, [track]); /** * 追踪概念卡片点击 * @param {Object} concept - 概念对象 * @param {number} position - 在列表中的位置 * @param {string} source - 来源 (list/stats_panel) */ const trackConceptClicked = useCallback((concept, position = 0, source = 'list') => { track(RETENTION_EVENTS.CONCEPT_CLICKED, { concept_name: concept.concept_name || concept.name, concept_code: concept.concept_code || concept.code, change_percent: concept.change_pct || concept.change_percent, stock_count: concept.stock_count, position, source, }); logger.debug('useConceptEvents', '🎯 Concept Clicked', { concept: concept.concept_name || concept.name, position, source, }); }, [track]); /** * 追踪概念下的股票标签点击 * @param {Object} stock - 股票对象 * @param {string} conceptName - 所属概念名称 */ const trackConceptStockClicked = useCallback((stock, conceptName) => { track(RETENTION_EVENTS.CONCEPT_STOCK_CLICKED, { stock_code: stock.code || stock.stock_code, stock_name: stock.name || stock.stock_name, concept_name: conceptName, source: 'concept_center_tag', }); logger.debug('useConceptEvents', '🏷️ Concept Stock Tag Clicked', { stock: stock.code || stock.stock_code, concept: conceptName, }); }, [track]); /** * 追踪概念详情查看(时间轴Modal) * @param {string} conceptName - 概念名称 * @param {string} conceptId - 概念ID */ const trackConceptDetailViewed = useCallback((conceptName, conceptId) => { track(RETENTION_EVENTS.CONCEPT_DETAIL_VIEWED, { concept_name: conceptName, concept_id: conceptId, source: 'concept_center', }); logger.debug('useConceptEvents', '📊 Concept Detail Viewed', { conceptName, conceptId, }); }, [track]); /** * 追踪股票详情Modal打开 * @param {string} stockCode - 股票代码 * @param {string} stockName - 股票名称 */ const trackStockDetailViewed = useCallback((stockCode, stockName) => { track(RETENTION_EVENTS.STOCK_DETAIL_VIEWED, { stock_code: stockCode, stock_name: stockName, source: 'concept_center_modal', }); logger.debug('useConceptEvents', '👁️ Stock Detail Modal Opened', { stockCode, stockName, }); }, [track]); /** * 追踪付费墙展示 * @param {string} feature - 需要付费的功能 * @param {string} requiredTier - 需要的订阅等级 */ const trackPaywallShown = useCallback((feature, requiredTier = 'pro') => { track(REVENUE_EVENTS.PAYWALL_SHOWN, { feature, required_tier: requiredTier, page: 'concept_center', }); logger.debug('useConceptEvents', '🔒 Paywall Shown', { feature, requiredTier, }); }, [track]); /** * 追踪升级按钮点击 * @param {string} feature - 触发升级的功能 * @param {string} targetTier - 目标订阅等级 */ const trackUpgradeClicked = useCallback((feature, targetTier = 'pro') => { track(REVENUE_EVENTS.PAYWALL_UPGRADE_CLICKED, { feature, target_tier: targetTier, source_page: 'concept_center', }); logger.debug('useConceptEvents', '⬆️ Upgrade Button Clicked', { feature, targetTier, }); }, [track]); // ========== 别名函数 - 为保持向后兼容性 ========== /** * 追踪概念搜索(别名函数) * @alias trackSearchQuerySubmitted */ const trackConceptSearched = useCallback((query, resultCount = 0) => { return trackSearchQuerySubmitted(query, resultCount); }, [trackSearchQuerySubmitted]); /** * 追踪筛选器应用(通用包装函数) * @param {string} filterType - 筛选类型 (sort/date/view_mode) * @param {any} filterValue - 筛选值 * @param {any} previousValue - 之前的值 */ const trackFilterApplied = useCallback((filterType, filterValue, previousValue = null) => { if (filterType === 'sort') { return trackSortChanged(filterValue, previousValue); } else if (filterType === 'date') { return trackDateChanged(filterValue, previousValue); } else if (filterType === 'view_mode') { return trackViewModeChanged(filterValue, previousValue); } }, [trackSortChanged, trackDateChanged, trackViewModeChanged]); /** * 追踪概念股票列表查看 * @param {string} conceptName - 概念名称 * @param {number} stockCount - 股票数量 */ const trackConceptStocksViewed = useCallback((conceptName, stockCount = 0) => { track(RETENTION_EVENTS.CONCEPT_DETAIL_VIEWED, { concept_name: conceptName, stock_count: stockCount, view_type: 'stocks_list', source: 'concept_center', }); logger.debug('useConceptEvents', '📈 Concept Stocks Viewed', { conceptName, stockCount, }); }, [track]); /** * 追踪概念时间轴查看(别名函数) * @alias trackConceptDetailViewed */ const trackConceptTimelineViewed = useCallback((conceptName, conceptId) => { return trackConceptDetailViewed(conceptName, conceptId); }, [trackConceptDetailViewed]); /** * 追踪分页变化(别名函数 - 不同时态) * @alias trackPageChanged */ const trackPageChange = useCallback((page, filters = {}) => { return trackPageChanged(page, filters); }, [trackPageChanged]); return { // 原有函数 trackConceptListViewed, trackSearchInitiated, trackSearchQuerySubmitted, trackSortChanged, trackViewModeChanged, trackDateChanged, trackPageChanged, trackConceptClicked, trackConceptStockClicked, trackConceptDetailViewed, trackStockDetailViewed, trackPaywallShown, trackUpgradeClicked, // 别名函数 - 为保持向后兼容性 trackConceptSearched, trackFilterApplied, trackConceptStocksViewed, trackConceptTimelineViewed, trackPageChange, }; };