# 设计文档 - 基本面选股系统 MVP ## 1. 引言 ### 1.1. 文档目的 本文档旨在根据《需求文档 - MVP版本》的要求,提供一个全面的系统设计方案。它将详细阐述系统架构、模块划分、技术选型、数据库设计和API接口,作为开发团队进行系统实现的核心技术指导文件。 ### 1.2. 项目概述 基本面选股系统是一个Web应用,旨在为投资者提供自动化、多维度的股票基本面分析报告。用户通过输入股票代码和市场,可以获取或生成一份包含财务数据、AI业务分析、市场情绪、风险评估等多个模块的综合报告,以辅助投资决策。 ### 1.3. 范围 本设计涵盖了从用户界面到后端服务、再到数据库的全栈技术方案。主要包括: - **前端**:用户交互界面,包括报告查询、展示、进度追踪和系统配置。 - **后端**:核心业务逻辑,包括报告生成、数据获取、AI分析、任务管理和配置服务。 - **数据库**:报告数据、分析模块内容、进度信息和系统配置的持久化存储。 ## 2. 系统架构 ### 2.1. 架构概述 系统采用前后端分离的现代化Web架构: - **前端 (Frontend)**:基于React (Next.js) 的单页面应用 (SPA),负责用户界面和交互逻辑。它通过RESTful API与后端通信。 - **后端 (Backend)**:基于Python FastAPI框架的异步API服务,负责处理所有业务逻辑、数据操作和与外部服务的集成。 - **数据库 (Database)**:采用PostgreSQL作为关系型数据库,存储所有持久化数据。 - **异步任务队列**: 利用FastAPI的`BackgroundTasks`处理耗时的报告生成任务,避免阻塞API请求,并允许实时进度追踪。 ![System Architecture Diagram](https://i.imgur.com/example.png) ### 2.2. 技术选型 | 层次 | 技术 | 理由 | | :--- | :--- | :--- | | **前端** | React (Next.js), TypeScript, Shadcn/UI | 提供优秀的开发体验、类型安全、高性能的服务端渲染(SSR)和丰富的UI组件库。 | | **后端** | Python, FastAPI, SQLAlchemy (Async) | 异步框架带来高并发性能,Python拥有强大的数据处理和AI生态,SQLAlchemy提供强大的ORM能力。 | | **数据库** | PostgreSQL | 功能强大、稳定可靠的开源关系型数据库,支持JSONB等高级数据类型,适合存储结构化报告数据。 | | **数据源** | Tushare API, Yahoo Finance | Tushare提供全面的中国市场数据,Yahoo Finance作为其他市场的补充,易于集成。 | | **AI模型** | Google Gemini | 强大的大语言模型,能够根据指令生成高质量的业务分析内容。 | ## 3. 后端设计 (Backend Design) ### 3.1. 核心服务设计 后端逻辑将围绕以下几个核心服务展开: - **ReportGenerator (报告生成器)**: 核心服务,负责编排整个报告生成流程。它接收报告请求,并按顺序调用各个分析模块。 - **AnalysisModule (分析模块)**: 定义一个基础接口或抽象类,每个具体的分析(如基本面、看涨/看跌分析等)都将实现此接口。这使得系统易于扩展新的分析维度。 - **DataSourceManager (数据源管理器)**: 封装对Tushare、Yahoo等外部数据API的调用,提供统一的数据获取接口,并处理认证、重试和缓存逻辑。 - **AIService (AI服务)**: 封装对Gemini API的调用,负责发送Prompt、处理响应和管理Token消耗的记录。 - **ConfigManager (配置管理器)**: 负责从`config.json`或数据库中加载、更新和验证系统配置(如API密钥、数据库URL)。 - **ProgressTracker (进度追踪器)**: 负责在报告生成的每个阶段更新状态、耗时和Token使用情况,并提供给前端查询。 ### 3.2. 异步任务处理 报告生成是一个耗时操作,将通过FastAPI的`BackgroundTasks`在后台执行。当用户请求生成新报告时,API会立即返回一个报告ID和“生成中”的状态,并将生成任务添加到后台队列。前端可以通过该ID轮询或使用WebSocket/SSE来获取实时进度。 ### 3.3. API 端点设计 后端将提供以下RESTful API端点: | Method | Endpoint | 描述 | 请求体/参数 | 响应体 | | :--- | :--- | :--- | :--- | :--- | | `POST` | `/api/reports` | 创建或获取报告。如果报告已存在,返回现有报告;否则,启动后台任务生成新报告。 | `symbol`, `market` | `ReportResponse` | | `POST` | `/api/reports/regenerate` | 强制重新生成报告。 | `symbol`, `market` | `ReportResponse` | | `GET` | `/api/reports/{report_id}` | 获取特定报告的详细内容,包括所有分析模块。 | `report_id` (UUID) | `ReportResponse` | | `GET` | `/api/reports` | 获取报告列表,支持分页和筛选。 | `skip`, `limit`, `status` | `List[ReportResponse]` | | `GET` | `/api/progress/stream/{report_id}` | (SSE) 实时流式传输报告生成进度。 | `report_id` (UUID) | `ProgressResponse` (Stream) | | `GET` | `/api/config` | 获取当前系统所有配置。 | - | `ConfigResponse` | | `PUT` | `/api/config` | 更新系统配置。 | `ConfigUpdateRequest` | `ConfigResponse` | | `POST`| `/api/config/test` | 测试特定配置的有效性(如数据库连接)。 | `ConfigTestRequest` | `ConfigTestResponse` | ## 4. 数据库设计 ### 4.1. 数据模型 (Schema) **1. `reports` (报告表)** 存储报告的元数据。 | 字段名 | 类型 | 描述 | 示例 | | :--- | :--- | :--- | :--- | | `id` | UUID (Primary Key) | 报告的唯一标识符 | `uuid.uuid4()` | | `symbol` | VARCHAR | 股票代码 | "600519" | | `market` | VARCHAR | 交易市场 | "china" | | `status` | VARCHAR | 生成状态 (generating, completed, failed) | "completed" | | `created_at` | TIMESTAMPTZ | 创建时间 | `datetime.utcnow()` | | `updated_at` | TIMESTAMPTZ | 最后更新时间 | `datetime.utcnow()` | **2. `analysis_modules` (分析模块表)** 存储每个报告的具体分析模块内容。 | 字段名 | 类型 | 描述 | 示例 | | :--- | :--- | :--- | :--- | | `id` | UUID (Primary Key) | 模块的唯一标识符 | `uuid.uuid4()` | | `report_id` | UUID (Foreign Key) | 关联的报告ID | `reports.id` | | `module_type` | VARCHAR | 模块类型 (e.g., "business_info", "bull_case") | "bull_case" | | `content` | JSONB | 模块的分析结果,结构化数据 | `{"title": "看涨分析", "data": [...]}` | | `status` | VARCHAR | 模块生成状态 (pending, running, completed, failed) | "completed" | | `error_message`| TEXT | 失败时的错误信息 | "API call failed" | **3. `progress_tracking` (进度追踪表)** 记录报告生成过程中每个步骤的状态和性能指标。 | 字段名 | 类型 | 描述 | 示例 | | :--- | :--- | :--- | :--- | | `id` | UUID (Primary Key) | 进度记录的唯一标识符 | `uuid.uuid4()` | | `report_id` | UUID (Foreign Key) | 关联的报告ID | `reports.id` | | `step_name` | VARCHAR | 步骤名称 | "获取财务数据" | | `status` | VARCHAR | 步骤状态 (pending, running, completed, failed) | "completed" | | `started_at` | TIMESTAMPTZ | 步骤开始时间 | `datetime.utcnow()` | | `completed_at` | TIMESTAMPTZ | 步骤完成时间 | `datetime.utcnow()` | | `duration_ms` | INTEGER | 步骤耗时(毫秒) | 1500 | | `token_usage` | INTEGER | AI步骤的Token消耗量 | 2500 | | `error_message`| TEXT | 失败时的错误信息 | "Data source timeout" | **4. `system_config` (系统配置表)** 以键值对形式存储可动态修改的系统配置。 | 字段名 | 类型 | 描述 | 示例 | | :--- | :--- | :--- | :--- | | `config_key` | VARCHAR (Primary Key) | 配置项的键 | "gemini_api_key" | | `config_value`| JSONB | 配置项的值 | `{"api_key": "..."}` | ### 4.2. 关系 - `reports` 与 `analysis_modules` 是一对多关系。 - `reports` 与 `progress_tracking` 是一对多关系。 ## 5. 前端设计 (Frontend Design) ### 5.1. 组件设计 - **`StockInputForm`**: 首页的核心组件,包含证券代码输入框和交易市场选择器。 - **`ReportPage`**: 报告的主页面,根据报告状态显示历史报告、进度追踪器或完整的分析模块。 - **`ProgressTracker`**: 实时进度组件,通过订阅SSE或定时轮询来展示报告生成的步骤、状态和耗时。 - **`ModuleNavigator`**: 报告页面的侧边栏或顶部导航,允许用户在不同的分析模块间切换。 - **`ModuleViewer`**: 用于展示单个分析模块内容的组件,能渲染从`content` (JSONB)字段解析出的文本、图表和表格。 - **`ConfigPage`**: 系统配置页面,提供表单来修改和测试数据库、API密钥等配置。 ### 5.2. 页面与路由 - `/`: 首页,展示`StockInputForm`。 - `/report/{symbol}`: 报告页面,动态路由,根据查询参数(如`market`)加载`ReportPage`。 - `/report/{symbol}/{moduleId}`: 模块详情页,展示特定分析模块的内容。 - `/config`: 系统配置页面,展示`ConfigPage`。 ### 5.3. 状态管理 - 使用Zustand或React Context进行全局状态管理,主要管理用户信息、系统配置和当前的报告状态。 - 组件内部状态将使用React的`useState`和`useReducer`。 - 使用React Query或SWR来管理API数据获取、缓存和同步,简化数据获取逻辑并提升用户体验。