# 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` 内部包含 `` (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