Files
vf_react/docs/Community.md

1087 lines
31 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Community 页面 - 技术文档
> **版本**: v1.0.0
> **更新日期**: 2025-01-07
> **文档类型**: 页面架构与开发指南
---
## 📑 目录
1. [页面概述](#-页面概述)
2. [页面架构](#-页面架构)
3. [核心功能模块](#-核心功能模块)
4. [数据流与状态管理](#-数据流与状态管理)
5. [自定义 Hooks 详解](#-自定义-hooks-详解)
6. [组件结构说明](#-组件结构说明)
7. [通知与权限引导](#-通知与权限引导)
8. [开发指南](#-开发指南)
9. [代码变更历史](#-代码变更历史)
---
## 📖 页面概述
### 功能定位
Community 页面(社区页面)是应用的核心功能模块之一,提供实时金融事件、动态新闻、热点事件的展示和追踪功能。
### 核心价值
-**实时性**: 展示最新的金融事件和市场动态
-**可追踪**: 用户可以关注感兴趣的事件和股票
-**可筛选**: 支持多维度筛选(重要性、行业、时间范围等)
-**数据分析**: 集成 PostHog 埋点,追踪用户行为
-**通知引导**: 首次访问时引导用户开启通知权限
### 页面入口
- **路由路径**: `/community`
- **导航位置**: 主导航栏
- **权限要求**: MODAL未登录显示登录弹窗
---
## 🏗️ 页面架构
### 组件树结构
```
Community (index.js)
├── HotEventsSection # 热点事件区域
│ └── HotEvents # 热点事件卡片列表
└── DynamicNewsCard # 实时动态新闻区域
├── UnifiedSearchBox # 统一搜索框(关键词+筛选器)
│ ├── PopularKeywords # 热门关键词
│ ├── TradingTimeFilter # 交易时间筛选
│ └── IndustryCascader # 行业级联选择器
├── ModeToggleButtons # 横向/纵向布局切换
├── EventScrollList (横向模式) # 横向滚动事件列表
│ └── EventCard # 事件卡片
│ ├── HorizontalDynamicNewsEventCard # 横向卡片
│ └── DynamicNewsEventCard # 纵向卡片
├── VerticalModeLayout (纵向模式) # 纵向网格布局
│ └── VirtualizedFourRowGrid # 虚拟化四行网格
│ └── EventCard # 事件卡片
├── EventDetailScrollPanel # 右侧详情面板
│ └── DynamicNewsDetail # 事件详情
│ ├── EventHeaderInfo # 事件头部信息
│ ├── EventDescriptionSection # 事件描述
│ ├── RelatedStocksSection # 相关股票
│ └── RelatedConceptsSection # 相关概念
│ ├── SimpleConceptCard # 简单概念卡片
│ └── DetailedConceptCard # 详细概念卡片
└── PaginationControl # 分页控制
```
### 文件组织方式
```
src/views/Community/
├── index.js # 页面主入口
├── index.css # 页面样式
├── components/ # 页面组件
│ ├── HotEventsSection.js # 热点事件区域容器
│ ├── HotEvents.js # 热点事件卡片列表
│ ├── HotEvents.css
│ │
│ ├── DynamicNewsCard.js # 实时动态新闻主组件
│ │ ├── constants.js # 常量定义
│ │ ├── hooks/ # 专属 Hooks
│ │ │ ├── usePagination.js # 分页逻辑
│ │ │ └── useInfiniteScroll.js # 无限滚动
│ │ ├── EventScrollList.js # 横向滚动列表
│ │ ├── VerticalModeLayout.js # 纵向布局
│ │ ├── VirtualizedFourRowGrid.js # 虚拟化网格
│ │ ├── ModeToggleButtons.js # 布局切换按钮
│ │ ├── PaginationControl.js # 分页控制
│ │ ├── PageNavigationButton.js # 页码导航按钮
│ │ └── EventDetailScrollPanel.js # 详情面板容器
│ │
│ ├── EventCard/ # 事件卡片组件族
│ │ ├── index.js # 智能路由(紧凑 vs 详细)
│ │ ├── CompactEventCard.js # 紧凑卡片
│ │ ├── DetailedEventCard.js # 详细卡片
│ │ ├── HorizontalDynamicNewsEventCard.js # 横向动态卡片
│ │ ├── DynamicNewsEventCard.js # 纵向动态卡片
│ │ ├── EventHeader.js # 事件头部
│ │ ├── EventDescription.js # 事件描述
│ │ ├── EventTimeline.js # 事件时间线
│ │ ├── EventImportanceBadge.js # 重要性徽章
│ │ ├── ImportanceBadge.js # 重要性标识
│ │ ├── ImportanceStamp.js # 重要性印章
│ │ ├── EventPriceDisplay.js # 价格显示
│ │ ├── EventStats.js # 事件统计
│ │ └── EventFollowButton.js # 关注按钮
│ │
│ ├── DynamicNewsDetail/ # 事件详情面板
│ │ ├── index.js # 主入口
│ │ ├── DynamicNewsDetailPanel.js # 详情面板容器
│ │ ├── EventHeaderInfo.js # 头部信息
│ │ ├── EventDescriptionSection.js # 描述区域
│ │ ├── CollapsibleSection.js # 可折叠区域
│ │ ├── CollapsibleHeader.js # 可折叠头部
│ │ ├── RelatedStocksSection.js # 相关股票区域
│ │ ├── StockListItem.js # 股票列表项
│ │ ├── CompactStockItem.js # 紧凑股票项
│ │ ├── MiniLineChart.js # 迷你折线图
│ │ ├── MiniKLineChart.js # 迷你K线图
│ │ └── RelatedConceptsSection/ # 相关概念区域
│ │ ├── index.js
│ │ ├── SimpleConceptCard.js # 简单概念卡片
│ │ ├── DetailedConceptCard.js # 详细概念卡片
│ │ ├── ConceptStockItem.js # 概念股票项
│ │ └── TradingDateInfo.js # 交易日期信息
│ │
│ ├── UnifiedSearchBox.js # 统一搜索框
│ ├── PopularKeywords.js # 热门关键词
│ ├── SearchBox.js # 基础搜索框
│ ├── TradingTimeFilter.js # 交易时间筛选器
│ ├── IndustryCascader.js # 行业级联选择器
│ ├── ImportanceLegend.js # 重要性图例
│ │
│ ├── StockDetailPanel.js # 股票详情面板(独立模块)
│ ├── StockDetailPanel.css
│ ├── StockDetailPanel/
│ │ ├── components/
│ │ │ ├── index.js
│ │ │ ├── StockSearchBar.js # 股票搜索栏
│ │ │ ├── StockTable.js # 股票表格
│ │ │ ├── RelatedStocksTab.js # 相关股票标签页
│ │ │ ├── MiniTimelineChart.js # 迷你时间线图
│ │ │ └── LockedContent.js # 锁定内容
│ │ ├── hooks/
│ │ │ ├── useEventStocks.js # 事件股票钩子
│ │ │ ├── useWatchlist.js # 监控列表钩子
│ │ │ └── useStockMonitoring.js # 股票监控钩子
│ │ └── utils/
│ │ └── klineDataCache.js # K线数据缓存
│ │
│ ├── EventList.js # 事件列表(旧版,已备份)
│ ├── EventList.js.bak
│ ├── EventList.css
│ ├── EventListSection.js # 事件列表区域
│ ├── EventTimelineHeader.js # 事件时间线头部
│ ├── EventDetailModal.js # 事件详情弹窗
│ ├── EventDiscussionModal.js # 事件讨论弹窗
│ │
│ ├── MarketReviewCard.js # 市场回顾卡片
│ ├── InvestmentCalendar.js # 投资日历
│ ├── InvestmentCalendar.css
│ ├── MidjourneyHeroSection.js # Hero 区域
│ │
│ └── UnifiedSearchBox修复说明.md # 修复说明文档
└── hooks/ # 页面专属 Hooks
├── useEventData.js # 事件数据获取
├── useEventFilters.js # 事件筛选逻辑
└── useCommunityEvents.js # PostHog 埋点追踪
```
---
## 🎯 核心功能模块
### 1. 热点事件展示 (HotEventsSection)
**功能**:展示当前最热门的事件,吸引用户关注。
**位置**: `src/views/Community/components/HotEventsSection.js`
**特性**:
- 自动获取热点事件数据
- 卡片式展示,支持点击查看详情
- 集成 PostHog 埋点追踪点击行为
**使用示例**:
```jsx
<HotEventsSection
events={hotEvents}
onEventClick={communityEvents.trackNewsArticleClicked}
/>
```
---
### 2. 实时动态新闻 (DynamicNewsCard)
**功能**:展示实时金融事件动态,支持筛选、搜索、分页、布局切换。
**位置**: `src/views/Community/components/DynamicNewsCard.js`
**核心特性**:
#### 2.1 搜索与筛选
- ✅ 关键词搜索(支持热门关键词快速选择)
- ✅ 交易时间筛选(盘前、盘中、盘后、全部)
- ✅ 重要性筛选特级、A级、B级、C级、全部
- ✅ 行业筛选(行业级联选择器)
#### 2.2 布局模式
- **横向滚动模式**
- 适合快速浏览大量事件
- 支持左右滚动查看更多
- 卡片紧凑布局
- **纵向网格模式**
- 适合深度浏览事件详情
- 虚拟化四行网格提升性能
- 卡片详细布局
#### 2.3 详情面板
- 右侧滑出式详情面板
- 展示事件完整描述
- 展示相关股票和概念
- 支持点击股票跳转到详情页
#### 2.4 分页功能
- 支持上一页/下一页
- 支持页码快速跳转
- 显示当前页码和总页数
**使用示例**:
```jsx
<DynamicNewsCard
mt={6}
filters={filters}
popularKeywords={popularKeywords}
lastUpdateTime={lastUpdateTime}
onSearch={updateFilters}
onEventClick={handleEventClick}
onViewDetail={handleViewDetail}
trackingFunctions={{
trackNewsArticleClicked: communityEvents.trackNewsArticleClicked,
trackNewsDetailOpened: communityEvents.trackNewsDetailOpened,
trackNewsFilterApplied: communityEvents.trackNewsFilterApplied,
trackNewsSorted: communityEvents.trackNewsSorted,
trackNewsSearched: communityEvents.trackNewsSearched,
trackRelatedStockClicked: communityEvents.trackRelatedStockClicked,
}}
/>
```
---
### 3. 事件详情查看 (DynamicNewsDetail)
**功能**:展示单个事件的详细信息,包括描述、相关股票、相关概念等。
**位置**: `src/views/Community/components/DynamicNewsDetail/index.js`
**内容结构**:
```
DynamicNewsDetail
├── EventHeaderInfo # 事件头部(标题、时间、重要性)
├── EventDescriptionSection # 事件描述
├── RelatedStocksSection # 相关股票
│ ├── StockListItem # 股票列表项
│ ├── CompactStockItem # 紧凑股票项
│ ├── MiniLineChart # 迷你折线图
│ └── MiniKLineChart # 迷你K线图
└── RelatedConceptsSection # 相关概念
├── SimpleConceptCard # 简单概念卡片
├── DetailedConceptCard # 详细概念卡片
└── ConceptStockItem # 概念股票项
```
**特性**:
- ✅ 可折叠区域(节省空间)
- ✅ 相关股票实时行情展示
- ✅ 相关概念板块分析
- ✅ 支持股票点击跳转
---
### 4. 股票详情面板 (StockDetailPanel)
**功能**独立的股票详情查看模块支持搜索、监控、K线图查看。
**位置**: `src/views/Community/components/StockDetailPanel.js`
**核心功能**:
- ✅ 股票搜索
- ✅ 股票监控(加入自选)
- ✅ K线图展示
- ✅ 相关股票推荐
- ✅ 事件关联股票
**自定义 Hooks**:
- `useEventStocks` - 获取事件关联股票
- `useWatchlist` - 管理自选股列表
- `useStockMonitoring` - 股票监控逻辑
**数据缓存**:
- `klineDataCache.js` - K线数据缓存提升性能
---
## 🔄 数据流与状态管理
### Redux State (communityDataSlice)
**位置**: `src/store/slices/communityDataSlice.js`
**State 结构**:
```javascript
{
popularKeywords: [], // 热门关键词
hotEvents: [], // 热点事件
loading: false, // 加载状态
error: null // 错误信息
}
```
**Actions**:
```javascript
// 同步 Actions
dispatch(fetchPopularKeywords()); // 获取热门关键词
dispatch(fetchHotEvents()); // 获取热点事件
// Thunk Actions (异步)
dispatch(fetchPopularKeywordsAsync());
dispatch(fetchHotEventsAsync());
```
**使用示例**:
```jsx
import { useSelector, useDispatch } from 'react-redux';
import { fetchPopularKeywords, fetchHotEvents } from '@store/slices/communityDataSlice';
const Community = () => {
const dispatch = useDispatch();
const { popularKeywords, hotEvents } = useSelector(state => state.communityData);
useEffect(() => {
dispatch(fetchPopularKeywords());
dispatch(fetchHotEvents());
}, [dispatch]);
return (/* ... */);
};
```
---
### API 调用流程
**API 服务**: `src/services/communityService.js`
**主要 API 端点**:
```javascript
// 获取事件列表
GET /api/community/events
?page=1
&pageSize=20
&importance=all
&industry_code=all
&date_range=today
&trading_time=all
&search=关键词
// 获取热点事件
GET /api/community/hot-events
// 获取热门关键词
GET /api/community/popular-keywords
// 获取事件详情
GET /api/community/events/:id
// 获取相关股票
GET /api/community/events/:id/related-stocks
// 获取相关概念
GET /api/community/events/:id/related-concepts
```
**数据流向**:
```
用户交互
Component 触发 Action
自定义 Hook 处理逻辑 (useEventData, useEventFilters)
API Service 调用后端
后端返回数据
Hook 更新本地 State
Component 重新渲染
```
---
## 🪝 自定义 Hooks 详解
### 1. useEventData
**位置**: `src/views/Community/hooks/useEventData.js`
**功能**: 根据筛选条件获取事件数据。
**输入参数**:
```javascript
const filters = {
page: 1, // 页码
pageSize: 20, // 每页数量
importance: 'all', // 重要性筛选
industry_code: 'all', // 行业代码
date_range: 'today', // 日期范围
trading_time: 'all', // 交易时间
search: '' // 搜索关键词
};
```
**返回值**:
```javascript
{
events: [], // 事件列表
pagination: { // 分页信息
current: 1,
pageSize: 20,
total: 100
},
loading: false, // 加载状态
lastUpdateTime: Date // 最后更新时间
}
```
**使用示例**:
```jsx
const { events, pagination, loading, lastUpdateTime } = useEventData(filters);
```
---
### 2. useEventFilters
**位置**: `src/views/Community/hooks/useEventFilters.js`
**功能**: 管理事件筛选逻辑和导航。
**返回值**:
```javascript
{
filters: {}, // 当前筛选条件
updateFilters: (newFilters) => {}, // 更新筛选条件
handlePageChange: (page) => {}, // 分页变更
handleEventClick: (event) => {}, // 事件点击
handleViewDetail: (event) => {} // 查看详情
}
```
**使用示例**:
```jsx
const {
filters,
updateFilters,
handlePageChange,
handleEventClick,
handleViewDetail
} = useEventFilters({ navigate });
```
---
### 3. useCommunityEvents
**位置**: `src/views/Community/hooks/useCommunityEvents.js`
**功能**: 提供 PostHog 埋点追踪函数集合。
**返回的追踪函数**:
```javascript
{
trackNewsListViewed, // 新闻列表查看
trackNewsArticleClicked, // 新闻文章点击
trackNewsDetailOpened, // 新闻详情打开
trackNewsFilterApplied, // 筛选器应用
trackNewsSorted, // 排序
trackNewsSearched, // 搜索
trackRelatedStockClicked, // 相关股票点击
trackNewsShareClicked, // 分享点击
trackNewsCommentPosted, // 评论发布
trackNewsLiked // 点赞
}
```
**使用示例**:
```jsx
const communityEvents = useCommunityEvents({ navigate });
// 追踪事件点击
communityEvents.trackNewsArticleClicked({
eventId: event.id,
title: event.title,
importance: event.importance
});
```
---
## 🧩 组件结构说明
### 原子组件 (Atomic Components)
#### EventCard 系列
**设计模式**: 原子设计 + 智能路由
**组件清单**:
| 组件文件 | 功能 | 使用场景 |
|---------|------|---------|
| `index.js` | 智能路由器 | 根据 `mode` 参数路由到紧凑或详细卡片 |
| `CompactEventCard.js` | 紧凑卡片 | 列表视图、横向滚动 |
| `DetailedEventCard.js` | 详细卡片 | 详情视图、纵向网格 |
| `HorizontalDynamicNewsEventCard.js` | 横向动态卡片 | 横向滚动布局 |
| `DynamicNewsEventCard.js` | 纵向动态卡片 | 纵向网格布局 |
| `EventHeader.js` | 事件头部 | 标题、时间、重要性 |
| `EventDescription.js` | 事件描述 | 文本内容 |
| `EventTimeline.js` | 事件时间线 | 时间轴展示 |
| `EventImportanceBadge.js` | 重要性徽章 | 重要性标识 |
| `ImportanceBadge.js` | 重要性标识 | 简单版徽章 |
| `ImportanceStamp.js` | 重要性印章 | 印章样式 |
| `EventPriceDisplay.js` | 价格显示 | 股票价格和涨跌幅 |
| `EventStats.js` | 事件统计 | 浏览量、点赞数等 |
| `EventFollowButton.js` | 关注按钮 | 关注/取消关注 |
**智能路由示例**:
```jsx
import EventCard from './components/EventCard';
// 紧凑模式
<EventCard mode="compact" event={event} />
// 详细模式
<EventCard mode="detailed" event={event} />
// 横向动态模式
<EventCard mode="horizontal-dynamic" event={event} />
// 纵向动态模式
<EventCard mode="vertical-dynamic" event={event} />
```
---
### 复合组件 (Composite Components)
#### DynamicNewsCard
**设计模式**: 容器 + 展示分离
**核心子组件**:
- `UnifiedSearchBox` - 搜索和筛选
- `ModeToggleButtons` - 布局切换
- `EventScrollList` - 横向滚动列表
- `VerticalModeLayout` - 纵向网格布局
- `VirtualizedFourRowGrid` - 虚拟化网格(性能优化)
- `EventDetailScrollPanel` - 详情面板
- `PaginationControl` - 分页控制
**状态管理**:
```javascript
// 内部管理的状态
const [viewMode, setViewMode] = useState('horizontal'); // 布局模式
const [selectedEvent, setSelectedEvent] = useState(null); // 选中事件
const [currentPage, setCurrentPage] = useState(1); // 当前页码
const [detailVisible, setDetailVisible] = useState(false); // 详情面板可见性
```
**自定义 Hooks**:
- `usePagination` - 分页逻辑
- `useInfiniteScroll` - 无限滚动(可选)
---
#### HotEventsSection
**设计模式**: 简单容器
**功能**: 包装 HotEvents 组件,提供布局和样式。
**使用示例**:
```jsx
<HotEventsSection
events={hotEvents}
onEventClick={handleEventClick}
/>
```
---
### 面板组件 (Panel Components)
#### DynamicNewsDetail
**位置**: `src/views/Community/components/DynamicNewsDetail/index.js`
**设计模式**: 组合模式
**子组件结构**:
```jsx
<DynamicNewsDetailPanel>
<EventHeaderInfo />
<EventDescriptionSection />
<CollapsibleSection title="相关股票">
<RelatedStocksSection>
<StockListItem />
<CompactStockItem />
</RelatedStocksSection>
</CollapsibleSection>
<CollapsibleSection title="相关概念">
<RelatedConceptsSection>
<SimpleConceptCard />
<DetailedConceptCard />
</RelatedConceptsSection>
</CollapsibleSection>
</DynamicNewsDetailPanel>
```
**特性**:
- ✅ 可折叠区域
- ✅ 懒加载(折叠时不渲染内容)
- ✅ 滚动优化
---
#### StockDetailPanel
**位置**: `src/views/Community/components/StockDetailPanel.js`
**设计模式**: 独立模块
**内部模块**:
- `StockSearchBar` - 股票搜索
- `StockTable` - 股票表格
- `RelatedStocksTab` - 相关股票标签页
- `MiniTimelineChart` - 迷你时间线图
- `LockedContent` - 锁定内容(需要权限)
**自定义 Hooks**:
- `useEventStocks` - 事件股票获取
- `useWatchlist` - 自选股管理
- `useStockMonitoring` - 股票监控
**缓存机制**:
```javascript
// klineDataCache.js
export const klineCache = {
get: (stockCode) => { /* ... */ },
set: (stockCode, data) => { /* ... */ },
clear: () => { /* ... */ }
};
```
---
## 🔔 通知与权限引导
### 首次访问引导
**触发时机**: 用户首次访问 Community 页面
**延迟时间**: 5 秒(让用户先浏览页面内容)
**实现代码**:
```jsx
// src/views/Community/index.js
const { showCommunityGuide } = useNotification();
useEffect(() => {
if (showCommunityGuide) {
const timer = setTimeout(() => {
logger.info('Community', '显示社区权限引导');
showCommunityGuide();
}, 5000);
return () => clearTimeout(timer);
}
}, [showCommunityGuide]);
```
### 权限请求时机
**通知权限**:
- 首次收到新事件通知时
- 用户主动点击"开启通知"按钮时
**引导策略**:
- 权限状态为 `default`(未决定)→ 自动请求权限
- 权限状态为 `denied`(已拒绝)→ 显示设置指引
**相关文档**: [NOTIFICATION_SYSTEM.md](./NOTIFICATION_SYSTEM.md)
---
## 📚 开发指南
### 添加新的筛选条件
**步骤**:
1. **更新 filters 状态** (`useEventFilters.js`):
```javascript
const [filters, setFilters] = useState({
// ... 现有筛选条件
newFilter: 'default' // 新增筛选条件
});
```
2. **添加筛选器 UI** (`UnifiedSearchBox.js` 或新组件):
```jsx
<Select
value={filters.newFilter}
onChange={(value) => updateFilters({ newFilter: value })}
>
<option value="default">默认</option>
<option value="option1">选项1</option>
</Select>
```
3. **更新 API 调用** (`useEventData.js`):
```javascript
const fetchEvents = async (filters) => {
const response = await api.get('/api/community/events', {
params: {
// ... 现有参数
new_filter: filters.newFilter
}
});
return response.data;
};
```
4. **添加 PostHog 埋点** (`useCommunityEvents.js`):
```javascript
const trackNewFilterApplied = (filterValue) => {
posthog.capture('news_filter_applied', {
filter_type: 'new_filter',
filter_value: filterValue
});
};
```
---
### 添加新的事件卡片样式
**步骤**:
1. **创建新组件** (`src/views/Community/components/EventCard/NewStyleCard.js`):
```jsx
import React from 'react';
import { Box, Text } from '@chakra-ui/react';
const NewStyleCard = ({ event, onClick }) => {
return (
<Box
onClick={() => onClick(event)}
cursor="pointer"
// ... 样式
>
<Text>{event.title}</Text>
{/* 自定义内容 */}
</Box>
);
};
export default NewStyleCard;
```
2. **更新智能路由** (`src/views/Community/components/EventCard/index.js`):
```jsx
import NewStyleCard from './NewStyleCard';
const EventCard = ({ mode = 'compact', event, ...props }) => {
if (mode === 'new-style') {
return <NewStyleCard event={event} {...props} />;
}
// ... 现有逻辑
};
```
3. **使用新样式**:
```jsx
<EventCard mode="new-style" event={event} />
```
---
### 性能优化建议
#### 1. 虚拟化长列表
**已实现**: `VirtualizedFourRowGrid.js`
**适用场景**: 事件数量超过 100 条时
**库**: `react-window`
**示例**:
```jsx
import { FixedSizeGrid } from 'react-window';
<FixedSizeGrid
columnCount={4}
rowCount={Math.ceil(events.length / 4)}
columnWidth={300}
rowHeight={200}
height={800}
width={1200}
>
{({ columnIndex, rowIndex, style }) => (
<div style={style}>
<EventCard event={events[rowIndex * 4 + columnIndex]} />
</div>
)}
</FixedSizeGrid>
```
#### 2. 图片懒加载
**实现**: 使用 `loading="lazy"` 属性
```jsx
<img src={event.imageUrl} loading="lazy" alt={event.title} />
```
#### 3. 防抖搜索
**实现**: 在搜索框使用 `debounce`
```javascript
import { debounce } from 'lodash';
const debouncedSearch = debounce((keyword) => {
updateFilters({ search: keyword });
}, 300);
```
#### 4. 缓存 API 响应
**实现**: 使用 `klineDataCache.js`
```javascript
// 缓存 K线数据
const getCachedKlineData = (stockCode) => {
const cached = klineCache.get(stockCode);
if (cached && Date.now() - cached.timestamp < 60000) {
return cached.data;
}
const data = await fetchKlineData(stockCode);
klineCache.set(stockCode, data);
return data;
};
```
---
### 测试指南
#### 单元测试
**工具**: Jest + React Testing Library
**测试用例示例**:
```javascript
// useEventData.test.js
import { renderHook } from '@testing-library/react-hooks';
import { useEventData } from '../hooks/useEventData';
describe('useEventData', () => {
it('应该返回事件列表', async () => {
const { result, waitForNextUpdate } = renderHook(() =>
useEventData({ page: 1, pageSize: 20 })
);
await waitForNextUpdate();
expect(result.current.events).toHaveLength(20);
expect(result.current.loading).toBe(false);
});
});
```
#### 集成测试
**测试场景**:
- 搜索功能是否正常工作
- 筛选器是否正确应用
- 分页是否正常切换
- 事件点击是否正确跳转
**测试示例**:
```javascript
// Community.test.js
import { render, screen, fireEvent } from '@testing-library/react';
import Community from '../index';
describe('Community Page', () => {
it('应该显示搜索框', () => {
render(<Community />);
expect(screen.getByPlaceholderText('搜索事件...')).toBeInTheDocument();
});
it('应该响应搜索', async () => {
render(<Community />);
const searchInput = screen.getByPlaceholderText('搜索事件...');
fireEvent.change(searchInput, { target: { value: '特斯拉' } });
// 等待搜索结果
await screen.findByText(/特斯拉/i);
});
});
```
---
## 📜 代码变更历史
### 2025-01-07: Community 页面 PostHog 追踪完善
**变更类型**: 用户行为追踪完善
**背景**:
Community 页面已实现 `useCommunityEvents` hook提供了 9 个追踪函数,但大部分追踪函数未被实际使用。页面缺少对用户关键交互行为的追踪,无法有效分析用户使用习惯。
**变更内容**:
**新增追踪点**:
1. **热点事件交互追踪** (`HotEvents.js`)
- ✅ 热点事件卡片点击 → `trackNewsArticleClicked`
- 追踪数据:事件 ID、标题、重要性、来源
2. **动态新闻交互追踪** (`DynamicNewsCard.js`)
- ✅ 四排模式事件点击(弹窗打开)→ `trackNewsDetailOpened`
- ✅ 首次自动选中事件 → `trackNewsArticleClicked`
- 追踪数据:事件 ID、标题、重要性、显示模式、来源
3. **搜索和筛选追踪** (`UnifiedSearchBox.js`)
- ✅ 主搜索提交 → `trackNewsSearched`
- ✅ 股票选择(下拉框)→ `trackRelatedStockClicked`
- ✅ 重要性筛选 → `trackNewsFilterApplied`
- ✅ 排序更改 → `trackNewsSorted`
- ✅ 行业筛选 → `trackNewsFilterApplied`
- ✅ 热门关键词点击 → `trackNewsSearched`
- ✅ 交易时段筛选 → `trackNewsFilterApplied`
- ✅ 筛选重置 → `trackNewsFilterApplied`
- 追踪数据:搜索关键词、筛选类型、筛选值、时间戳
**实现策略**:
- 通过 props 传递追踪函数到子组件(`Community/index.js` → 子组件)
- 所有追踪函数从 `useCommunityEvents` hook 获取,无需额外创建
- 追踪调用为非阻塞操作,不影响用户体验
**优化效果**:
- ✅ 实现了 9 个 PostHog 追踪函数中的 6 个
- ✅ 覆盖了所有关键用户交互:浏览、点击、搜索、筛选
- ✅ 追踪数据结构化,便于后续分析
- ✅ 为产品优化和用户行为分析提供数据支持
**影响范围**:
- `src/views/Community/index.js` - 传递追踪函数到子组件
- `src/views/Community/components/HotEventsSection.js` - 接收并传递追踪函数
- `src/views/Community/components/HotEvents.js` - 热点事件点击追踪
- `src/views/Community/components/DynamicNewsCard.js` - 事件交互追踪
- `src/views/Community/components/UnifiedSearchBox.js` - 搜索和筛选追踪
**后续改进空间**:
- 可添加模式切换追踪(纵向 ↔ 四排)
- 可添加翻页行为追踪
- 可添加热点事件轮播翻页追踪
- 可添加相关概念点击追踪(`trackRelatedConceptClicked`
---
### 2025-01-07: Community 页面代码清理
**变更类型**: 代码清理与优化
**背景**:
Community 页面存在大量已注释但未删除的代码,影响可维护性和代码可读性。
**变更内容**:
#### 删除的组件
-`EventTimelineCard.js` - 实时事件纵向列表组件(已被 DynamicNewsCard 替代)
-`EventModals.js` - 事件弹窗组件(功能已整合到 DynamicNewsCard
#### 删除的代码
- ❌ 5 个不再使用的导入语句EventTimelineCard, EventModals, usePostHogTrack, RETENTION_EVENTS, fetchDynamicNews
- ❌ 4 个不再使用的状态和 RefselectedEvent, selectedEventForStock, eventTimelineRef, hasScrolledRef
- ❌ 1 个不再使用的函数scrollToTimeline
- ❌ 3 处已注释的代码块PostHog 追踪、EventTimelineCard 渲染、EventModals 渲染)
- ❌ 1 个重复的 useEffect动态新闻每 5 分钟刷新DynamicNewsCard 内部已管理)
#### 优化效果
- 📉 代码行数207 行 → 138 行(减少 69 行33% 代码量)
- ✅ 移除冗余代码,提高可维护性
- ✅ 减少导入依赖,加快编译速度
- ✅ 删除未使用的状态,减少内存占用
- ✅ 代码更清晰,更易理解
#### 影响范围
- `src/views/Community/index.js` - 主页面组件
- `src/views/Community/components/EventTimelineCard.js` - 已删除
- `src/views/Community/components/EventModals.js` - 已删除
#### 迁移说明
所有事件展示功能已统一由 `DynamicNewsCard` 组件实现,采用横向滚动布局,用户体验更佳。
**提交信息**:
```
feat: 删除不需要的组件
- 删除 EventTimelineCard 和 EventModals
- 清理未使用的导入和状态
- 移除已注释的代码块
- 优化页面结构,减少 33% 代码量
```
---
## 🔗 相关文档
- [项目总览 - CLAUDE.md](../CLAUDE.md)
- [通知系统 - NOTIFICATION_SYSTEM.md](./NOTIFICATION_SYSTEM.md)
- [路由系统 - src/routes/README.md](../src/routes/README.md)
- [Redux 状态管理 - src/store/README.md](../src/store/README.md)
- [PostHog 埋点追踪 - POSTHOG_TRACKING_GUIDE.md](./POSTHOG_TRACKING_GUIDE.md)
---
## 📝 文档维护
**更新时机**:
- 添加新功能模块时
- 重构组件结构时
- 修复重大 bug 时
- 性能优化时
**更新规范**:
- 保持目录结构清晰
- 添加代码示例
- 更新相关链接
- 记录变更历史
**贡献者**:
- 所有参与 Community 页面开发的工程师
---
**文档结束** 🎉