1. 完整的用户旅程
- 从进入网站 → 浏览内容 → 使用功能 → 遇到付费墙 → 付费转化
2. 核心业务指标
- DAU/MAU(活跃用户)
- 功能使用率(哪些功能最受欢迎)
- 搜索热度(用户需求洞察)
- Revenue转化漏斗(付费转化分析)
- 用户参与度(Profile更新、设置变更)
3. 产品优化方向
- 哪些功能需要优化?
- 用户在哪个环节流失?
- 哪些内容最受欢迎?
- 如何提高付费转化率?
245 lines
6.8 KiB
JavaScript
245 lines
6.8 KiB
JavaScript
// 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;
|