From 8f3af4ed0710a93e0bbb42eb53012550dd09ee26 Mon Sep 17 00:00:00 2001 From: zdl <3489966805@qq.com> Date: Tue, 28 Oct 2025 21:06:53 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20Community=20=E9=A1=B5=E9=9D=A2=20PostHo?= =?UTF-8?q?g=20=E4=BA=8B=E4=BB=B6=E8=BF=BD=E8=B8=AA=E5=AE=8C=E6=88=90=20Cu?= =?UTF-8?q?stom=20Hook=20=E9=9B=86=E6=88=90=EF=BC=88useEventFilters.js?= =?UTF-8?q?=EF=BC=89=20=E9=A1=B5=E9=9D=A2=E7=BB=84=E4=BB=B6=E8=BF=BD?= =?UTF-8?q?=E8=B8=AA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/Community/hooks/useEventFilters.js | 83 +++++++++++++++++++- src/views/Community/index.js | 12 +++ 2 files changed, 91 insertions(+), 4 deletions(-) diff --git a/src/views/Community/hooks/useEventFilters.js b/src/views/Community/hooks/useEventFilters.js index 20ca3c8b..e65401fd 100644 --- a/src/views/Community/hooks/useEventFilters.js +++ b/src/views/Community/hooks/useEventFilters.js @@ -4,6 +4,8 @@ import { useState, useCallback } from 'react'; import { useSearchParams } from 'react-router-dom'; import { logger } from '../../../utils/logger'; +import { usePostHogTrack } from '../../../hooks/usePostHogRedux'; +import { RETENTION_EVENTS } from '../../../lib/constants'; /** * 事件筛选逻辑 Hook @@ -15,6 +17,7 @@ import { logger } from '../../../utils/logger'; */ export const useEventFilters = ({ navigate, onEventClick, eventTimelineRef } = {}) => { const [searchParams] = useSearchParams(); + const { track } = usePostHogTrack(); // PostHog 追踪 // 筛选参数状态 - 初始化时从URL读取,之后只用本地状态 const [filters, setFilters] = useState(() => { @@ -35,12 +38,68 @@ export const useEventFilters = ({ navigate, onEventClick, eventTimelineRef } = { oldFilters: filters, 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); logger.debug('useEventFilters', '✅ setFilters 已调用 (React异步更新中...)'); - }, [filters]); + }, [filters, track]); // 处理分页变化 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 }); @@ -53,21 +112,37 @@ export const useEventFilters = ({ navigate, onEventClick, eventTimelineRef } = { }); }, 100); // 延迟100ms,确保DOM更新 } - }, [filters, updateFilters, eventTimelineRef]); + }, [filters, updateFilters, eventTimelineRef, track]); // 处理事件点击 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) { onEventClick(event); } - }, [onEventClick]); + }, [onEventClick, track]); // 处理查看详情 const handleViewDetail = useCallback((eventId) => { + // 🎯 PostHog 追踪:查看详情 + track(RETENTION_EVENTS.NEWS_DETAIL_OPENED, { + event_id: eventId, + source: 'community_page', + }); + if (navigate) { navigate(`/event-detail/${eventId}`); } - }, [navigate]); + }, [navigate, track]); return { filters, diff --git a/src/views/Community/index.js b/src/views/Community/index.js index 4c759ce5..16436fe1 100644 --- a/src/views/Community/index.js +++ b/src/views/Community/index.js @@ -20,12 +20,15 @@ import { useEventFilters } from './hooks/useEventFilters'; import { logger } from '../../utils/logger'; import { useNotification } from '../../contexts/NotificationContext'; +import { usePostHogTrack } from '../../hooks/usePostHogRedux'; +import { RETENTION_EVENTS } from '../../lib/constants'; // 导航栏已由 MainLayout 提供,无需在此导入 const Community = () => { const navigate = useNavigate(); const dispatch = useDispatch(); + const { track } = usePostHogTrack(); // PostHog 追踪 // Redux状态 const { popularKeywords, hotEvents } = useSelector(state => state.communityData); @@ -59,6 +62,15 @@ const Community = () => { dispatch(fetchHotEvents()); }, [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(() => { if (showCommunityGuide) {