feat: Community 页面 PostHog 事件追踪完成

Custom Hook 集成(useEventFilters.js) 页面组件追踪
This commit is contained in:
zdl
2025-10-28 21:06:53 +08:00
parent fb76e442f7
commit 8f3af4ed07
2 changed files with 91 additions and 4 deletions

View File

@@ -4,6 +4,8 @@
import { useState, useCallback } from 'react'; import { useState, useCallback } from 'react';
import { useSearchParams } from 'react-router-dom'; import { useSearchParams } from 'react-router-dom';
import { logger } from '../../../utils/logger'; import { logger } from '../../../utils/logger';
import { usePostHogTrack } from '../../../hooks/usePostHogRedux';
import { RETENTION_EVENTS } from '../../../lib/constants';
/** /**
* 事件筛选逻辑 Hook * 事件筛选逻辑 Hook
@@ -15,6 +17,7 @@ import { logger } from '../../../utils/logger';
*/ */
export const useEventFilters = ({ navigate, onEventClick, eventTimelineRef } = {}) => { export const useEventFilters = ({ navigate, onEventClick, eventTimelineRef } = {}) => {
const [searchParams] = useSearchParams(); const [searchParams] = useSearchParams();
const { track } = usePostHogTrack(); // PostHog 追踪
// 筛选参数状态 - 初始化时从URL读取之后只用本地状态 // 筛选参数状态 - 初始化时从URL读取之后只用本地状态
const [filters, setFilters] = useState(() => { const [filters, setFilters] = useState(() => {
@@ -35,12 +38,68 @@ export const useEventFilters = ({ navigate, onEventClick, eventTimelineRef } = {
oldFilters: filters, oldFilters: filters,
timestamp: new Date().toISOString() timestamp: new Date().toISOString()
}); });
// 🎯 PostHog 追踪:搜索查询
if (newFilters.q !== filters.q && newFilters.q) {
track(RETENTION_EVENTS.SEARCH_QUERY_SUBMITTED, {
query: newFilters.q,
category: 'news',
previous_query: filters.q || null,
});
}
// 🎯 PostHog 追踪:排序变化
if (newFilters.sort !== filters.sort) {
track(RETENTION_EVENTS.SEARCH_FILTER_APPLIED, {
filter_type: 'sort',
filter_value: newFilters.sort,
previous_value: filters.sort,
});
}
// 🎯 PostHog 追踪:重要性筛选
if (newFilters.importance !== filters.importance) {
track(RETENTION_EVENTS.SEARCH_FILTER_APPLIED, {
filter_type: 'importance',
filter_value: newFilters.importance,
previous_value: filters.importance,
});
}
// 🎯 PostHog 追踪:时间范围筛选
if (newFilters.date_range !== filters.date_range && newFilters.date_range) {
track(RETENTION_EVENTS.SEARCH_FILTER_APPLIED, {
filter_type: 'date_range',
filter_value: newFilters.date_range,
previous_value: filters.date_range || null,
});
}
// 🎯 PostHog 追踪:行业筛选
if (newFilters.industry_code !== filters.industry_code && newFilters.industry_code) {
track(RETENTION_EVENTS.SEARCH_FILTER_APPLIED, {
filter_type: 'industry',
filter_value: newFilters.industry_code,
previous_value: filters.industry_code || null,
});
}
setFilters(newFilters); setFilters(newFilters);
logger.debug('useEventFilters', '✅ setFilters 已调用 (React异步更新中...)'); logger.debug('useEventFilters', '✅ setFilters 已调用 (React异步更新中...)');
}, [filters]); }, [filters, track]);
// 处理分页变化 // 处理分页变化
const handlePageChange = useCallback((page) => { const handlePageChange = useCallback((page) => {
// 🎯 PostHog 追踪:翻页
track(RETENTION_EVENTS.NEWS_LIST_VIEWED, {
page,
filters: {
sort: filters.sort,
importance: filters.importance,
has_query: !!filters.q,
},
});
// 保持现有筛选条件,只更新页码 // 保持现有筛选条件,只更新页码
updateFilters({ ...filters, page }); updateFilters({ ...filters, page });
@@ -53,21 +112,37 @@ export const useEventFilters = ({ navigate, onEventClick, eventTimelineRef } = {
}); });
}, 100); // 延迟100ms确保DOM更新 }, 100); // 延迟100ms确保DOM更新
} }
}, [filters, updateFilters, eventTimelineRef]); }, [filters, updateFilters, eventTimelineRef, track]);
// 处理事件点击 // 处理事件点击
const handleEventClick = useCallback((event) => { const handleEventClick = useCallback((event) => {
// 🎯 PostHog 追踪:新闻事件点击
track(RETENTION_EVENTS.NEWS_ARTICLE_CLICKED, {
event_id: event.id || event.event_id,
event_title: event.title,
importance: event.importance,
source: 'community_page',
has_stocks: !!(event.related_stocks && event.related_stocks.length > 0),
has_concepts: !!(event.related_concepts && event.related_concepts.length > 0),
});
if (onEventClick) { if (onEventClick) {
onEventClick(event); onEventClick(event);
} }
}, [onEventClick]); }, [onEventClick, track]);
// 处理查看详情 // 处理查看详情
const handleViewDetail = useCallback((eventId) => { const handleViewDetail = useCallback((eventId) => {
// 🎯 PostHog 追踪:查看详情
track(RETENTION_EVENTS.NEWS_DETAIL_OPENED, {
event_id: eventId,
source: 'community_page',
});
if (navigate) { if (navigate) {
navigate(`/event-detail/${eventId}`); navigate(`/event-detail/${eventId}`);
} }
}, [navigate]); }, [navigate, track]);
return { return {
filters, filters,

View File

@@ -20,12 +20,15 @@ import { useEventFilters } from './hooks/useEventFilters';
import { logger } from '../../utils/logger'; import { logger } from '../../utils/logger';
import { useNotification } from '../../contexts/NotificationContext'; import { useNotification } from '../../contexts/NotificationContext';
import { usePostHogTrack } from '../../hooks/usePostHogRedux';
import { RETENTION_EVENTS } from '../../lib/constants';
// 导航栏已由 MainLayout 提供,无需在此导入 // 导航栏已由 MainLayout 提供,无需在此导入
const Community = () => { const Community = () => {
const navigate = useNavigate(); const navigate = useNavigate();
const dispatch = useDispatch(); const dispatch = useDispatch();
const { track } = usePostHogTrack(); // PostHog 追踪
// Redux状态 // Redux状态
const { popularKeywords, hotEvents } = useSelector(state => state.communityData); const { popularKeywords, hotEvents } = useSelector(state => state.communityData);
@@ -59,6 +62,15 @@ const Community = () => {
dispatch(fetchHotEvents()); dispatch(fetchHotEvents());
}, [dispatch]); }, [dispatch]);
// 🎯 PostHog 追踪:页面浏览
useEffect(() => {
track(RETENTION_EVENTS.COMMUNITY_PAGE_VIEWED, {
timestamp: new Date().toISOString(),
has_hot_events: hotEvents && hotEvents.length > 0,
has_keywords: popularKeywords && popularKeywords.length > 0,
});
}, [track]); // 只在组件挂载时执行一次
// ⚡ 首次访问社区时,延迟显示权限引导 // ⚡ 首次访问社区时,延迟显示权限引导
useEffect(() => { useEffect(() => {
if (showCommunityGuide) { if (showCommunityGuide) {