feat: 完成集成后,您可以在 PostHog 中分析:
- 用户搜索行为:搜索频率、热门搜索词、搜索成功率 - 概念关注度:哪些概念最受关注、点击排名分布 - 热力图使用情况:用户点击的股票市值分布、涨跌偏好 - 日期筛选模式:用户倾向查看哪些日期的数据 - 转化漏斗:从页面浏览 → 搜索 → 点击 → 详情的转化率
This commit is contained in:
236
src/views/StockOverview/hooks/useStockOverviewEvents.js
Normal file
236
src/views/StockOverview/hooks/useStockOverviewEvents.js
Normal file
@@ -0,0 +1,236 @@
|
||||
// src/views/StockOverview/hooks/useStockOverviewEvents.js
|
||||
// 个股中心页面事件追踪 Hook
|
||||
|
||||
import { useCallback, useEffect } from 'react';
|
||||
import { usePostHogTrack } from '../../../hooks/usePostHogRedux';
|
||||
import { RETENTION_EVENTS } from '../../../lib/constants';
|
||||
import { logger } from '../../../utils/logger';
|
||||
|
||||
/**
|
||||
* 个股中心事件追踪 Hook
|
||||
* @param {Object} options - 配置选项
|
||||
* @param {Function} options.navigate - 路由导航函数
|
||||
* @returns {Object} 事件追踪处理函数集合
|
||||
*/
|
||||
export const useStockOverviewEvents = ({ navigate } = {}) => {
|
||||
const { track } = usePostHogTrack();
|
||||
|
||||
// 🎯 页面浏览事件 - 页面加载时触发
|
||||
useEffect(() => {
|
||||
track(RETENTION_EVENTS.STOCK_OVERVIEW_VIEWED, {
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
logger.debug('useStockOverviewEvents', '📊 Stock Overview Page Viewed');
|
||||
}, [track]);
|
||||
|
||||
/**
|
||||
* 追踪市场统计数据查看
|
||||
* @param {Object} stats - 市场统计数据
|
||||
*/
|
||||
const trackMarketStatsViewed = useCallback((stats) => {
|
||||
if (!stats) return;
|
||||
|
||||
track(RETENTION_EVENTS.STOCK_LIST_VIEWED, {
|
||||
total_market_cap: stats.total_market_cap,
|
||||
total_volume: stats.total_volume,
|
||||
rising_stocks: stats.rising_count,
|
||||
falling_stocks: stats.falling_count,
|
||||
data_date: stats.date,
|
||||
});
|
||||
|
||||
logger.debug('useStockOverviewEvents', '📈 Market Statistics Viewed', stats);
|
||||
}, [track]);
|
||||
|
||||
/**
|
||||
* 追踪股票搜索开始
|
||||
*/
|
||||
const trackSearchInitiated = useCallback(() => {
|
||||
track(RETENTION_EVENTS.SEARCH_INITIATED, {
|
||||
context: 'stock_overview',
|
||||
});
|
||||
|
||||
logger.debug('useStockOverviewEvents', '🔍 Search Initiated');
|
||||
}, [track]);
|
||||
|
||||
/**
|
||||
* 追踪股票搜索查询
|
||||
* @param {string} query - 搜索查询词
|
||||
* @param {number} resultCount - 搜索结果数量
|
||||
*/
|
||||
const trackStockSearched = useCallback((query, resultCount = 0) => {
|
||||
if (!query) return;
|
||||
|
||||
track(RETENTION_EVENTS.STOCK_SEARCHED, {
|
||||
query,
|
||||
result_count: resultCount,
|
||||
has_results: resultCount > 0,
|
||||
});
|
||||
|
||||
// 如果没有搜索结果,额外追踪
|
||||
if (resultCount === 0) {
|
||||
track(RETENTION_EVENTS.SEARCH_NO_RESULTS, {
|
||||
query,
|
||||
context: 'stock_overview',
|
||||
});
|
||||
}
|
||||
|
||||
logger.debug('useStockOverviewEvents', '🔍 Stock Searched', {
|
||||
query,
|
||||
resultCount,
|
||||
});
|
||||
}, [track]);
|
||||
|
||||
/**
|
||||
* 追踪搜索结果点击
|
||||
* @param {Object} stock - 被点击的股票对象
|
||||
* @param {number} position - 在搜索结果中的位置
|
||||
*/
|
||||
const trackSearchResultClicked = useCallback((stock, position = 0) => {
|
||||
track(RETENTION_EVENTS.SEARCH_RESULT_CLICKED, {
|
||||
stock_code: stock.code,
|
||||
stock_name: stock.name,
|
||||
exchange: stock.exchange,
|
||||
position,
|
||||
context: 'stock_overview',
|
||||
});
|
||||
|
||||
logger.debug('useStockOverviewEvents', '🎯 Search Result Clicked', {
|
||||
stock: stock.code,
|
||||
position,
|
||||
});
|
||||
}, [track]);
|
||||
|
||||
/**
|
||||
* 追踪概念卡片点击
|
||||
* @param {Object} concept - 概念对象
|
||||
* @param {number} rank - 在列表中的排名
|
||||
*/
|
||||
const trackConceptClicked = useCallback((concept, rank = 0) => {
|
||||
track(RETENTION_EVENTS.CONCEPT_CLICKED, {
|
||||
concept_name: concept.name,
|
||||
concept_code: concept.code,
|
||||
change_percent: concept.change_percent,
|
||||
stock_count: concept.stock_count,
|
||||
rank,
|
||||
source: 'daily_hot_concepts',
|
||||
});
|
||||
|
||||
logger.debug('useStockOverviewEvents', '🔥 Concept Clicked', {
|
||||
concept: concept.name,
|
||||
rank,
|
||||
});
|
||||
}, [track]);
|
||||
|
||||
/**
|
||||
* 追踪概念下的股票标签点击
|
||||
* @param {Object} stock - 股票对象
|
||||
* @param {string} conceptName - 所属概念名称
|
||||
*/
|
||||
const trackConceptStockClicked = useCallback((stock, conceptName) => {
|
||||
track(RETENTION_EVENTS.CONCEPT_STOCK_CLICKED, {
|
||||
stock_code: stock.code,
|
||||
stock_name: stock.name,
|
||||
concept_name: conceptName,
|
||||
source: 'daily_hot_concepts_tag',
|
||||
});
|
||||
|
||||
logger.debug('useStockOverviewEvents', '🏷️ Concept Stock Tag Clicked', {
|
||||
stock: stock.code,
|
||||
concept: conceptName,
|
||||
});
|
||||
}, [track]);
|
||||
|
||||
/**
|
||||
* 追踪热力图中股票点击
|
||||
* @param {Object} stock - 被点击的股票对象
|
||||
* @param {string} marketCapRange - 市值区间
|
||||
*/
|
||||
const trackHeatmapStockClicked = useCallback((stock, marketCapRange = '') => {
|
||||
track(RETENTION_EVENTS.STOCK_CLICKED, {
|
||||
stock_code: stock.code,
|
||||
stock_name: stock.name,
|
||||
change_percent: stock.change_percent,
|
||||
market_cap_range: marketCapRange,
|
||||
source: 'market_heatmap',
|
||||
});
|
||||
|
||||
logger.debug('useStockOverviewEvents', '📊 Heatmap Stock Clicked', {
|
||||
stock: stock.code,
|
||||
marketCapRange,
|
||||
});
|
||||
}, [track]);
|
||||
|
||||
/**
|
||||
* 追踪股票详情查看
|
||||
* @param {string} stockCode - 股票代码
|
||||
* @param {string} source - 来源(search/concept/heatmap)
|
||||
*/
|
||||
const trackStockDetailViewed = useCallback((stockCode, source = 'unknown') => {
|
||||
track(RETENTION_EVENTS.STOCK_DETAIL_VIEWED, {
|
||||
stock_code: stockCode,
|
||||
source: `stock_overview_${source}`,
|
||||
});
|
||||
|
||||
logger.debug('useStockOverviewEvents', '👁️ Stock Detail Viewed', {
|
||||
stockCode,
|
||||
source,
|
||||
});
|
||||
|
||||
// 导航到公司详情页
|
||||
if (navigate) {
|
||||
navigate(`/company/${stockCode}`);
|
||||
}
|
||||
}, [track, navigate]);
|
||||
|
||||
/**
|
||||
* 追踪概念详情查看
|
||||
* @param {string} conceptCode - 概念代码
|
||||
*/
|
||||
const trackConceptDetailViewed = useCallback((conceptCode) => {
|
||||
track(RETENTION_EVENTS.CONCEPT_DETAIL_VIEWED, {
|
||||
concept_code: conceptCode,
|
||||
source: 'stock_overview_daily_hot',
|
||||
});
|
||||
|
||||
logger.debug('useStockOverviewEvents', '🎯 Concept Detail Viewed', {
|
||||
conceptCode,
|
||||
});
|
||||
|
||||
// 导航到概念详情页
|
||||
if (navigate) {
|
||||
navigate(`/concept-detail/${conceptCode}`);
|
||||
}
|
||||
}, [track, navigate]);
|
||||
|
||||
/**
|
||||
* 追踪日期选择变化
|
||||
* @param {string} newDate - 新选择的日期
|
||||
* @param {string} previousDate - 之前的日期
|
||||
*/
|
||||
const trackDateChanged = useCallback((newDate, previousDate = null) => {
|
||||
track(RETENTION_EVENTS.SEARCH_FILTER_APPLIED, {
|
||||
filter_type: 'date',
|
||||
filter_value: newDate,
|
||||
previous_value: previousDate,
|
||||
context: 'stock_overview',
|
||||
});
|
||||
|
||||
logger.debug('useStockOverviewEvents', '📅 Date Changed', {
|
||||
newDate,
|
||||
previousDate,
|
||||
});
|
||||
}, [track]);
|
||||
|
||||
return {
|
||||
trackMarketStatsViewed,
|
||||
trackSearchInitiated,
|
||||
trackStockSearched,
|
||||
trackSearchResultClicked,
|
||||
trackConceptClicked,
|
||||
trackConceptStockClicked,
|
||||
trackHeatmapStockClicked,
|
||||
trackStockDetailViewed,
|
||||
trackConceptDetailViewed,
|
||||
trackDateChanged,
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user