Files
vf_react/docs/MOCK_API_DOCS.md
zdl 09db05c448 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>
2025-10-30 14:51:22 +08:00

8.2 KiB
Raw Blame History

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, 空依赖数组)

请求参数:

{
  "query": "",              // 空字符串表示获取所有概念
  "size": 20,               // 获取数量
  "page": 1,                // 页码
  "sort_by": "change_pct"   // 排序方式:按涨跌幅排序
}

响应数据:

{
  "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:147eventService.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

响应数据:

{
  "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 响应数据:

{
  "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 响应数据:

{
  "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: 移除冗余的数据获取

// Community/index.js 中移除未使用的 fetchPopularKeywords
// 删除或注释掉 line 256
// dispatch(fetchPopularKeywords());

方案 2: 使用缓存机制

  • PopularKeywords 组件中添加数据缓存
  • 短时间内(如 5 分钟)重复请求直接返回缓存数据

方案 3: 提升数据到父组件

  • 在 Community 页面统一管理数据获取
  • 通过 props 传递给 PopularKeywords 组件
  • PopularKeywords 不再自己发起请求

📝 其他接口

/api/conversations

状态: 未在前端代码中找到 可能来源: 浏览器插件、其他应用、或外部系统

/api/parameters

状态: 未在前端代码中找到 可能来源: 浏览器插件、其他应用、或外部系统


🚀 Mock 服务启动

# 启动 Mock 开发服务器
npm run start:mock

Mock 服务使用 MSW (Mock Service Worker) 实现,会拦截所有匹配的 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

📚 相关文档


更新日期: 2024-10-26 维护者: Claude Code Assistant