docs: 将所有文档迁移到 docs/ 目录
- 移动42个文档文件到 docs/ 目录 - 更新 .gitignore 允许 docs/ 下的 .md 文件 - 删除根目录下的重复文档文件 📁 文档分类: - StockDetailPanel 重构文档(3个) - PostHog 集成文档(6个) - 系统架构和API文档(33个) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
322
docs/MOCK_API_DOCS.md
Normal file
322
docs/MOCK_API_DOCS.md
Normal file
@@ -0,0 +1,322 @@
|
||||
# Mock API 接口文档
|
||||
|
||||
本文档说明 Community 页面(`/community`)加载时请求的所有 Mock API 接口。
|
||||
|
||||
## 📊 接口总览
|
||||
|
||||
Community 页面加载时会并发请求以下接口:
|
||||
|
||||
| 序号 | 接口路径 | 调用时机 | 用途 | Mock 状态 |
|
||||
|------|---------|---------|------|-----------|
|
||||
| 1 | `/concept-api/search` | PopularKeywords 组件挂载 | 获取热门概念 | ✅ 已实现 |
|
||||
| 2 | `/api/events/` | Community 组件挂载 | 获取事件列表 | ✅ 已实现 |
|
||||
| 3-8 | `/api/index/{code}/kline` (6个) | MidjourneyHeroSection 组件挂载 | 获取三大指数K线数据 | ✅ 已实现 |
|
||||
|
||||
---
|
||||
|
||||
## 1. 概念搜索接口
|
||||
|
||||
### `/concept-api/search`
|
||||
|
||||
**请求方式**: `POST`
|
||||
|
||||
**调用位置**: `src/views/Community/components/PopularKeywords.js:25`
|
||||
|
||||
**调用时机**: PopularKeywords 组件挂载时(`useEffect`, 空依赖数组)
|
||||
|
||||
**请求参数**:
|
||||
```json
|
||||
{
|
||||
"query": "", // 空字符串表示获取所有概念
|
||||
"size": 20, // 获取数量
|
||||
"page": 1, // 页码
|
||||
"sort_by": "change_pct" // 排序方式:按涨跌幅排序
|
||||
}
|
||||
```
|
||||
|
||||
**响应数据**:
|
||||
```json
|
||||
{
|
||||
"results": [
|
||||
{
|
||||
"concept": "人工智能",
|
||||
"concept_id": "CONCEPT_1000",
|
||||
"stock_count": 45,
|
||||
"price_info": {
|
||||
"avg_change_pct": 5.23,
|
||||
"avg_price": "45.67",
|
||||
"total_market_cap": "567.89"
|
||||
},
|
||||
"description": "人工智能相关概念股",
|
||||
"hot_score": 89
|
||||
}
|
||||
// ... 更多概念数据
|
||||
],
|
||||
"total": 20,
|
||||
"page": 1,
|
||||
"size": 20,
|
||||
"message": "搜索成功"
|
||||
}
|
||||
```
|
||||
|
||||
**Mock Handler**: `src/mocks/handlers/concept.js`
|
||||
|
||||
---
|
||||
|
||||
## 2. 事件列表接口
|
||||
|
||||
### `/api/events/`
|
||||
|
||||
**请求方式**: `GET`
|
||||
|
||||
**调用位置**: `src/views/Community/index.js:147` → `eventService.getEvents()`
|
||||
|
||||
**调用时机**: Community 页面加载时,由 `loadEvents()` 函数调用
|
||||
|
||||
**请求参数** (Query Parameters):
|
||||
- `page`: 页码(默认: 1)
|
||||
- `per_page`: 每页数量(默认: 10)
|
||||
- `sort`: 排序方式(默认: "new")
|
||||
- `importance`: 重要性(默认: "all")
|
||||
- `search_type`: 搜索类型(默认: "topic")
|
||||
- `q`: 搜索关键词(可选)
|
||||
- `industry_code`: 行业代码(可选)
|
||||
- `industry_classification`: 行业分类(可选)
|
||||
|
||||
**示例请求**:
|
||||
```
|
||||
GET /api/events/?sort=new&importance=all&search_type=topic&page=1&per_page=10
|
||||
```
|
||||
|
||||
**响应数据**:
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"events": [
|
||||
{
|
||||
"event_id": "evt_001",
|
||||
"title": "某公司发布新产品",
|
||||
"content": "详细内容...",
|
||||
"importance": "S",
|
||||
"created_at": "2024-10-26T10:30:00Z",
|
||||
"related_stocks": ["600519", "000858"]
|
||||
}
|
||||
// ... 更多事件
|
||||
],
|
||||
"pagination": {
|
||||
"page": 1,
|
||||
"per_page": 10,
|
||||
"total": 100,
|
||||
"total_pages": 10
|
||||
}
|
||||
},
|
||||
"message": "获取成功"
|
||||
}
|
||||
```
|
||||
|
||||
**Mock Handler**: `src/mocks/handlers/event.js`
|
||||
|
||||
---
|
||||
|
||||
## 3. 指数K线数据接口
|
||||
|
||||
### `/api/index/:indexCode/kline`
|
||||
|
||||
**请求方式**: `GET`
|
||||
|
||||
**调用位置**: `src/views/Community/components/MidjourneyHeroSection.js:315-323`
|
||||
|
||||
**调用时机**: MidjourneyHeroSection 组件挂载时(`useEffect`, 空依赖数组)
|
||||
|
||||
### 3.1 分时数据 (timeline)
|
||||
|
||||
用于展示当日分钟级别的价格走势图。
|
||||
|
||||
**请求参数** (Query Parameters):
|
||||
- `type`: "timeline"
|
||||
- `event_time`: 可选,事件时间
|
||||
|
||||
**六个并发请求**:
|
||||
1. `GET /api/index/000001.SH/kline?type=timeline` - 上证指数分时
|
||||
2. `GET /api/index/399001.SZ/kline?type=timeline` - 深证成指分时
|
||||
3. `GET /api/index/399006.SZ/kline?type=timeline` - 创业板指分时
|
||||
4. `GET /api/index/000001.SH/kline?type=daily` - 上证指数日线
|
||||
5. `GET /api/index/399001.SZ/kline?type=daily` - 深证成指日线
|
||||
6. `GET /api/index/399006.SZ/kline?type=daily` - 创业板指日线
|
||||
|
||||
**timeline 响应数据**:
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": [
|
||||
{
|
||||
"time": "09:30",
|
||||
"price": 3215.67,
|
||||
"close": 3215.67,
|
||||
"volume": 235678900,
|
||||
"prev_close": 3200.00
|
||||
},
|
||||
{
|
||||
"time": "09:31",
|
||||
"price": 3216.23,
|
||||
"close": 3216.23,
|
||||
"volume": 245789000,
|
||||
"prev_close": 3200.00
|
||||
}
|
||||
// ... 每分钟一条数据,从 09:30 到 15:00
|
||||
],
|
||||
"index_code": "000001.SH",
|
||||
"type": "timeline",
|
||||
"message": "获取成功"
|
||||
}
|
||||
```
|
||||
|
||||
### 3.2 日线数据 (daily)
|
||||
|
||||
用于获取历史收盘价,计算涨跌幅百分比。
|
||||
|
||||
**daily 响应数据**:
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": [
|
||||
{
|
||||
"date": "2024-10-01",
|
||||
"time": "2024-10-01",
|
||||
"open": 3198.45,
|
||||
"close": 3205.67,
|
||||
"high": 3212.34,
|
||||
"low": 3195.12,
|
||||
"volume": 45678900000,
|
||||
"prev_close": 3195.23
|
||||
}
|
||||
// ... 最近30个交易日的数据
|
||||
],
|
||||
"index_code": "000001.SH",
|
||||
"type": "daily",
|
||||
"message": "获取成功"
|
||||
}
|
||||
```
|
||||
|
||||
**Mock Handler**: `src/mocks/handlers/stock.js`
|
||||
**数据生成函数**: `src/mocks/data/kline.js`
|
||||
|
||||
---
|
||||
|
||||
## 🔍 重复请求问题分析
|
||||
|
||||
### 问题原因
|
||||
|
||||
1. **PopularKeywords 组件重复渲染**
|
||||
- `UnifiedSearchBox` 内部包含 `<PopularKeywords />` (line 276)
|
||||
- `PopularKeywords` 组件自己会在 `useEffect` 中发起 `/concept-api/search` 请求
|
||||
- Community 页面同时还通过 Redux `fetchPopularKeywords()` 获取数据(但未使用)
|
||||
|
||||
2. **React Strict Mode**
|
||||
- 开发环境下,React 18 的 Strict Mode 会故意双倍调用 useEffect
|
||||
- 这会导致所有组件挂载时的请求被执行两次
|
||||
- 生产环境不受影响
|
||||
|
||||
3. **MidjourneyHeroSection 的 6 个K线请求**
|
||||
- 这是设计行为,一次性并发请求 6 个接口
|
||||
- 3 个分时数据 + 3 个日线数据
|
||||
- 用于展示三大指数的实时行情图表
|
||||
|
||||
### 解决方案
|
||||
|
||||
**方案 1**: 移除冗余的数据获取
|
||||
```javascript
|
||||
// Community/index.js 中移除未使用的 fetchPopularKeywords
|
||||
// 删除或注释掉 line 256
|
||||
// dispatch(fetchPopularKeywords());
|
||||
```
|
||||
|
||||
**方案 2**: 使用缓存机制
|
||||
- 在 `PopularKeywords` 组件中添加数据缓存
|
||||
- 短时间内(如 5 分钟)重复请求直接返回缓存数据
|
||||
|
||||
**方案 3**: 提升数据到父组件
|
||||
- 在 Community 页面统一管理数据获取
|
||||
- 通过 props 传递给 `PopularKeywords` 组件
|
||||
- `PopularKeywords` 不再自己发起请求
|
||||
|
||||
---
|
||||
|
||||
## 📝 其他接口
|
||||
|
||||
### `/api/conversations`
|
||||
**状态**: ❌ 未在前端代码中找到
|
||||
**可能来源**: 浏览器插件、其他应用、或外部系统
|
||||
|
||||
### `/api/parameters`
|
||||
**状态**: ❌ 未在前端代码中找到
|
||||
**可能来源**: 浏览器插件、其他应用、或外部系统
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Mock 服务启动
|
||||
|
||||
```bash
|
||||
# 启动 Mock 开发服务器
|
||||
npm run start:mock
|
||||
```
|
||||
|
||||
Mock 服务使用 [MSW (Mock Service Worker)](https://mswjs.io/) 实现,会拦截所有匹配的 API 请求并返回模拟数据。
|
||||
|
||||
### Mock 文件结构
|
||||
|
||||
```
|
||||
src/mocks/
|
||||
├── handlers/
|
||||
│ ├── index.js # 汇总所有 handlers
|
||||
│ ├── concept.js # 概念相关接口
|
||||
│ ├── event.js # 事件相关接口
|
||||
│ └── stock.js # 股票/指数K线接口
|
||||
├── data/
|
||||
│ ├── kline.js # K线数据生成函数
|
||||
│ ├── events.js # 事件数据
|
||||
│ └── industries.js # 行业数据
|
||||
└── browser.js # MSW 浏览器配置
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🐛 调试建议
|
||||
|
||||
### 1. 查看 Mock 请求日志
|
||||
|
||||
打开浏览器控制台,所有 Mock 请求都会输出日志:
|
||||
|
||||
```
|
||||
[Mock Concept] 搜索概念: {query: "", size: 20, page: 1, sort_by: "change_pct"}
|
||||
[Mock Stock] 获取指数K线数据: {indexCode: "000001.SH", type: "timeline", eventTime: null}
|
||||
[Mock] 获取事件列表: {page: 1, per_page: 10, sort: "new", ...}
|
||||
```
|
||||
|
||||
### 2. 检查网络请求
|
||||
|
||||
在浏览器 Network 面板中:
|
||||
- 筛选 XHR/Fetch 请求
|
||||
- 查看请求的 URL、参数、响应数据
|
||||
- Mock 请求的响应时间会比真实 API 更快(200-500ms)
|
||||
|
||||
### 3. 验证数据格式
|
||||
|
||||
确保 Mock 数据格式与前端期望的格式一致:
|
||||
- 检查字段名称(如 `concept` vs `name`)
|
||||
- 检查数据类型(字符串 vs 数字)
|
||||
- 检查嵌套结构(如 `price_info.avg_change_pct`)
|
||||
|
||||
---
|
||||
|
||||
## 📚 相关文档
|
||||
|
||||
- [MSW 官方文档](https://mswjs.io/)
|
||||
- [React Query 缓存策略](https://tanstack.com/query/latest)
|
||||
- [前端数据获取最佳实践](https://kentcdodds.com/blog/data-fetching)
|
||||
|
||||
---
|
||||
|
||||
**更新日期**: 2024-10-26
|
||||
**维护者**: Claude Code Assistant
|
||||
Reference in New Issue
Block a user