// src/hooks/useSearchEvents.js // 全局搜索功能事件追踪 Hook import { useCallback } from 'react'; import { usePostHogTrack } from './usePostHogRedux'; import { RETENTION_EVENTS } from '../lib/constants'; import { logger } from '../utils/logger'; /** * 全局搜索事件追踪 Hook * @param {Object} options - 配置选项 * @param {string} options.context - 搜索上下文 ('global' | 'stock' | 'news' | 'concept' | 'simulation') * @returns {Object} 事件追踪处理函数集合 */ export const useSearchEvents = ({ context = 'global' } = {}) => { const { track } = usePostHogTrack(); /** * 追踪搜索开始(聚焦搜索框) * @param {string} placeholder - 搜索框提示文本 */ const trackSearchInitiated = useCallback((placeholder = '') => { track(RETENTION_EVENTS.SEARCH_INITIATED, { context, placeholder, timestamp: new Date().toISOString(), }); logger.debug('useSearchEvents', '🔍 Search Initiated', { context, placeholder, }); }, [track, context]); /** * 追踪搜索查询提交 * @param {string} query - 搜索查询词 * @param {number} resultCount - 搜索结果数量 * @param {Object} filters - 应用的筛选条件 */ const trackSearchQuerySubmitted = useCallback((query, resultCount = 0, filters = {}) => { if (!query) { logger.warn('useSearchEvents', 'trackSearchQuerySubmitted: query is required'); return; } track(RETENTION_EVENTS.SEARCH_QUERY_SUBMITTED, { query, query_length: query.length, result_count: resultCount, has_results: resultCount > 0, context, filters: filters, filter_count: Object.keys(filters).length, timestamp: new Date().toISOString(), }); // 如果没有搜索结果,额外追踪 if (resultCount === 0) { track(RETENTION_EVENTS.SEARCH_NO_RESULTS, { query, context, filters, timestamp: new Date().toISOString(), }); logger.debug('useSearchEvents', '❌ Search No Results', { query, context, }); } else { logger.debug('useSearchEvents', '✅ Search Query Submitted', { query, resultCount, context, }); } }, [track, context]); /** * 追踪搜索结果点击 * @param {Object} result - 被点击的搜索结果 * @param {string} result.type - 结果类型 ('stock' | 'news' | 'concept' | 'event') * @param {string} result.id - 结果ID * @param {string} result.title - 结果标题 * @param {number} position - 在搜索结果中的位置 * @param {string} query - 搜索查询词 */ const trackSearchResultClicked = useCallback((result, position = 0, query = '') => { if (!result || !result.type) { logger.warn('useSearchEvents', 'trackSearchResultClicked: result object with type is required'); return; } track(RETENTION_EVENTS.SEARCH_RESULT_CLICKED, { result_type: result.type, result_id: result.id || result.code || '', result_title: result.title || result.name || '', position, query, context, timestamp: new Date().toISOString(), }); logger.debug('useSearchEvents', '🎯 Search Result Clicked', { type: result.type, id: result.id || result.code, position, context, }); }, [track, context]); /** * 追踪搜索筛选应用 * @param {Object} filters - 应用的筛选条件 * @param {string} filterType - 筛选类型 ('sort' | 'category' | 'date_range' | 'price_range') * @param {any} filterValue - 筛选值 */ const trackSearchFilterApplied = useCallback((filterType, filterValue, filters = {}) => { if (!filterType) { logger.warn('useSearchEvents', 'trackSearchFilterApplied: filterType is required'); return; } track(RETENTION_EVENTS.SEARCH_FILTER_APPLIED, { filter_type: filterType, filter_value: String(filterValue), all_filters: filters, context, timestamp: new Date().toISOString(), }); logger.debug('useSearchEvents', '🔍 Search Filter Applied', { filterType, filterValue, context, }); }, [track, context]); /** * 追踪搜索建议点击(自动完成) * @param {string} suggestion - 被点击的搜索建议 * @param {number} position - 在建议列表中的位置 * @param {string} source - 建议来源 ('history' | 'popular' | 'related') */ const trackSearchSuggestionClicked = useCallback((suggestion, position = 0, source = 'popular') => { if (!suggestion) { logger.warn('useSearchEvents', 'trackSearchSuggestionClicked: suggestion is required'); return; } track('Search Suggestion Clicked', { suggestion, position, source, context, timestamp: new Date().toISOString(), }); logger.debug('useSearchEvents', '💡 Search Suggestion Clicked', { suggestion, position, source, context, }); }, [track, context]); /** * 追踪搜索历史查看 * @param {number} historyCount - 历史记录数量 */ const trackSearchHistoryViewed = useCallback((historyCount = 0) => { track('Search History Viewed', { history_count: historyCount, has_history: historyCount > 0, context, timestamp: new Date().toISOString(), }); logger.debug('useSearchEvents', '📜 Search History Viewed', { historyCount, context, }); }, [track, context]); /** * 追踪搜索历史清除 */ const trackSearchHistoryCleared = useCallback(() => { track('Search History Cleared', { context, timestamp: new Date().toISOString(), }); logger.debug('useSearchEvents', '🗑️ Search History Cleared', { context, }); }, [track, context]); /** * 追踪热门搜索词点击 * @param {string} keyword - 被点击的热门关键词 * @param {number} position - 在列表中的位置 * @param {number} heatScore - 热度分数 */ const trackPopularKeywordClicked = useCallback((keyword, position = 0, heatScore = 0) => { if (!keyword) { logger.warn('useSearchEvents', 'trackPopularKeywordClicked: keyword is required'); return; } track('Popular Keyword Clicked', { keyword, position, heat_score: heatScore, context, timestamp: new Date().toISOString(), }); logger.debug('useSearchEvents', '🔥 Popular Keyword Clicked', { keyword, position, context, }); }, [track, context]); return { // 搜索流程事件 trackSearchInitiated, trackSearchQuerySubmitted, trackSearchResultClicked, // 筛选和建议 trackSearchFilterApplied, trackSearchSuggestionClicked, // 历史和热门 trackSearchHistoryViewed, trackSearchHistoryCleared, trackPopularKeywordClicked, }; }; export default useSearchEvents;