# 前端重构设计: Vite + React SPA 日期: 2025-11-22 状态: 已实现 (Vite + React 重构完成,Mock 验证通过) ## 1. 概述与核心理念 本文档描述了将 `Fundamental_Analysis` 前端从 Next.js 重构为 Vite + React 的方案。 新的架构将专注于简单性、类型安全和“后端驱动”的状态模型。 ### 核心理念 1. **木偶架构 (Puppet Architecture)**: 前端只包含最小的业务逻辑,它忠实反映后端的状态。 * 如果后端说“加载中”,我们就显示加载中。 * 如果后端发送了状态快照,我们就完全按照快照渲染。 * 不做任何猜测性的 UI 更新 (Optimistic UI)。 2. **单一数据源 (Single Source of Truth)**: 所有类型 (Structs, Enums) 由 Rust 定义并生成 TypeScript (Zod)。 * **前端禁止内联定义类型**。 * 使用 `zod` 对所有输入数据进行运行时校验 (Fail Early)。 3. **Rustic 风格**: * 开启 Strict Mode。 * 禁止 `any` 类型。 * 对 Enum 进行穷尽匹配 (Exhaustive matching)。 4. **Vite + React**: SPA 架构,消除 SSR 代理黑盒,使 SSE 处理更加健壮和透明。 ## 2. 技术栈 | 层级 | 技术 | 选择理由 | | :--- | :--- | :--- | | **构建工具** | **Vite** | 极速、简单、无隐藏代理黑盒。 | | **框架** | **React 19** | 保留现有的 `shadcn/ui` 组件资产。 | | **路由** | **React Router v7** | 标准的客户端路由。 | | **状态管理** | **TanStack Query** | 服务端状态缓存 (用于配置数据)。 | | **全局状态** | **Zustand** | 客户端 UI 状态 (Sidebar, Workflow) 管理。 | | **UI 库** | **shadcn/ui** | 延续现有的设计语言 (Tailwind CSS)。 | | **可视化** | **ReactFlow** | 用于渲染工作流 DAG 图。 | | **数据请求** | **Axios + Zod** | 带运行时校验的类型化 HTTP 客户端。 | | **API 生成** | **OpenAPI -> Zod** | 从后端自动生成前端类型。 | ## 3. 架构设计 ### 3.1 类型生成流水线 后端 (Rust/Axum) 需暴露 `openapi.json` (通过 `utoipa` 等库)。 前端运行生成脚本: `Rust Structs` -> `openapi.json` -> `frontend/src/api/schema.ts` (Zod schemas + TS Types)。 ### 3.2 状态管理策略 #### A. 配置数据 (Pull 模型) 低频变更的数据 (API Keys, Templates) 由 **TanStack Query** 管理。 * `useQuery(['llm-providers'])` * `useMutation(['update-provider'])` #### B. 工作流数据 (Push/Stream 模型) 实时流动的数据 (分析进度) 由自定义的 **Workflow Store (Zustand)** 管理,直接连接 SSE。 * **连接层**: 使用原生 `EventSource` 直接连接 `http://api-gateway:4000/v1/workflow/events/{id}`。 * **状态机**: ```typescript type TaskInfo = { id: string; status: 'Pending' | 'Running' | 'Completed' | 'Failed'; progress?: number; // 0-100 error?: string; logs: string[]; // 实时日志 }; type WorkflowState = | { status: 'IDLE' } | { status: 'CONNECTING', requestId: string } | { status: 'RUNNING', requestId: string, dag: Dag, tasks: Record } | { status: 'COMPLETED', result: any } | { status: 'ERROR', error: string }; ``` ## 4. 页面设计与布局 (ASCII Art) **设计原则**: 严格保留现有 Next.js 版本的 UI 布局、风格和功能流程。 ### 4.1 整体布局 (Shell) 保留现有的顶部导航栏设计 (`RootLayout`)。历史报告改为下拉菜单。 ``` +---------------------------------------------------------------+ | FA Platform | | [首页] [历史报告 v] [文档] [配置] | +-----------+---------------------------------------------------+ | | (Dropdown Menu) | | | 2025-11-22 10:00: 600519.SS (Success) | | | 2025-11-21 14:30: AAPL (Failed) | | | ... | | +---------------------------------------------------+ | | | (主内容区域) | | | +---------------------------------------------------------------+ ``` ### 4.2 仪表盘 (Dashboard / Home) 入口页面,用于发起新的分析。 ``` +---------------------------------------------------------------+ | 基本面分析报告 | | 输入股票代码和市场,生成综合分析报告。 | +---------------------------------------------------------------+ | | | [ Card: Start Analysis ] | | +---------------------------------------------------------+ | | | 股票代码: [ 600519 ] | | | | 交易市场: [ 中国 v ] | | | | | | | | [ BUTTON: 生成报告 ] | | | +---------------------------------------------------------+ | | | +---------------------------------------------------------------+ ``` ### 4.3 报告详情页 (Report View) 核心页面,负责展示实时工作流状态和分析结果。 **关键改进**: Tabs 上需有直观的状态提示 (Spinner/Check/X)。 ``` +---------------------------------------------------------------+ | [Card: Header] | | 600519.SS Market: CN [Badge: Ready/Analyzing] | | [Template Select] [Start Btn] | +---------------------------------------------------------------+ | | | [Tabs List] | | +---------------------------------------------------------+ | | | [DAG View] (Always First) | | | | [Stock Chart] | | | | [Fundamental Data] [Spinner] (Fetching...) | | | | [Analysis: Basic] [Check] | | | | [Analysis: Value] [Spinner] | | | | [Analysis: Risk ] [Pending] | | | +---------------------------------------------------------+ | | | | (Tab Content Area) | | | | ----------------------------------------------------------- | | Request ID: ... | Time: 12.5s | Tokens: 1500 | +---------------------------------------------------------------+ ``` #### 4.3.1 DAG 视图 (Workflow Graph) 使用 ReactFlow 渲染。 * **节点**: 代表任务 (Fetch Data, Analysis Modules)。 * **连线**: 代表依赖关系。 * **状态**: 节点颜色随状态变化 (灰=Pending, 蓝=Running, 绿=Completed, 红=Failed)。 * **交互**: 点击节点自动切换 Tabs 到对应的详情页。 ``` +---------------------------------------------------------------+ | [ DAG View ] | | | | [Fetch: Tushare] ---> [Fundamental Data] | | (Running) (Pending) | | | | | [Fetch: Finnhub] --------------+ | | (Done) | | | v | | [Analysis: Basic] | | (Pending) | | | +---------------------------------------------------------------+ ``` #### 4.3.2 Fundamental Data Tab 展示多个数据源的并行获取状态。 ``` +---------------------------------------------------------------+ | [ Fundamental Data ] | | | | [ Card: Tushare Provider ] | | Status: [Spinner] Running (3.2s) | | Logs: | | > Connecting to api.tushare.pro... | | > Fetching income statement... | | | | [ Card: Finnhub Provider ] | | Status: [Check] Completed | | Result: Fetched 3 years of data. | | | | [ Card: AlphaVantage Provider ] | | Status: [X] Failed | | Error: Rate limit exceeded. | | | +---------------------------------------------------------------+ ``` #### 4.3.3 Analysis Module Tab 展示 LLM 分析的流式输出。 ``` +---------------------------------------------------------------+ | [ Analysis: Basic Analysis ] | | | | Status: [Spinner] Generating Report... | | Model: gpt-4o | | | | (Markdown Content Streaming Area) | | # Basic Financial Analysis | | Based on the income statement... [Cursor] | | | +---------------------------------------------------------------+ ``` ### 4.4 配置页面 (Config) #### 4.4.1 AI Providers 配置 (Tab 1) **设计逻辑**: 1. **Provider 维度**: 允许配置多个 Provider (如 OpenAI, Anthropic, LocalLLM)。 2. **Model 维度**: 每个 Provider 下包含多个 Model。 3. **交互流程**: 添加 Provider -> 输入 Key/BaseURL -> 点击 "刷新模型列表" (Fetch List) -> 从下拉框选择或手动添加模型 -> 点击 "测试" (Test) -> 保存。 ``` +---------------------------------------------------------------+ | [ Tabs: AI Provider | 数据源配置 | 分析模板 | 系统 ] | +---------------------------------------------------------------+ | | | [ Button: + 添加 AI Provider ] | | | | [ Card: OpenAI (Official) ] [Delete] | | +---------------------------------------------------------+ | | | Base URL: [ https://api.openai.com/v1 ] | | | | API Key: [ ************************ ] [Eye Icon] | | | | | | | | [ Button: 刷新模型列表 (Refresh List) ] | | | | | | | | **模型列表 (Models)**: | | | | +-----------------------------------------------------+ | | | | | gpt-4o [Status: Active] [Test] [Remove] | | | | | | gpt-3.5-turbo [Status: Active] [Test] [Remove] | | | | | +-----------------------------------------------------+ | | | | | | | | [ Input: 添加模型 (支持搜索/补全) ] [Button: Add] | | | | (输入 "claude" 自动提示 "claude-3-sonnet", etc.) | | | +---------------------------------------------------------+ | | | | [ Card: Local LLM (Ollama) ] | | ... | | | +---------------------------------------------------------------+ ``` #### 4.4.2 数据源配置 (Data Sources) (Tab 2) **设计逻辑**: 1. **后端驱动 (Backend Driven)**: 页面不硬编码有哪些数据源。 2. **查询流程**: 前端请求 `GET /configs/data_sources/schema` (或类似接口),后端返回可用的 Provider 列表及其所需配置项 (Schema)。 3. **动态渲染**: 根据后端返回的 Schema 渲染表单 (如 API Key 输入框, URL 输入框)。 4. **测试**: 如果后端支持 `Test` 接口,显示测试按钮。 ``` +---------------------------------------------------------------+ | [ Tabs: AI Provider | 数据源配置 | 分析模板 | 系统 ] | +---------------------------------------------------------------+ | | | (Dynamically Rendered from Backend Config) | | | | [ Card: Tushare Pro ] (Enabled [x]) | | +---------------------------------------------------------+ | | | API Token: [ ******************** ] | | | | Endpoint: [ http://api.tushare.pro ] | | | | [Button: Test Connection] -> (Result: Success/Fail) | | | +---------------------------------------------------------+ | | | | [ Card: AlphaVantage ] (Enabled [ ]) | | +---------------------------------------------------------+ | | | API Key: [ ] | | | | [Button: Test Connection] | | | +---------------------------------------------------------+ | | | +---------------------------------------------------------------+ ``` #### 4.4.3 分析模板配置 (Analysis Templates) (Tab 3) **设计逻辑**: 1. **模板 (Template)**: 分析报告的骨架,包含多个模块。 2. **模块 (Module)**: 具体的分析任务 (如 "基本面概览", "风险评估")。 3. **N*M 模型选择**: 每个模块可以指定特定的 AI 模型。 * **来源**: 聚合所有 AI Providers 中已启用的模型。 * **交互**: 下拉搜索框 (Combobox),输入关键词 (如 "gpt") 筛选出 `{provider: "openai", model: "gpt-4"}`。 4. **依赖管理 (DAG)**: 指定模块依赖关系 (如 "风险评估" 依赖 "基本面概览")。 ``` +---------------------------------------------------------------+ | [ Tabs: AI Provider | 数据源配置 | 分析模板 | 系统 ] | +---------------------------------------------------------------+ | | | 当前模板: [ 快速分析模板 v ] [+ 新建模板] [删除] | | | | **分析模块 (Modules)**: | | | | [ Card: 模块 1 - 基本面概览 ] | | +---------------------------------------------------------+ | | | ID: basic_analysis | | | | 依赖 (Dependencies): [ 无 v ] | | | | | | | | **模型选择 (Model)**: | | | | [ Combobox: gpt-4o (OpenAI) v ] | | | | (数据来源: 聚合自 AI Provider Tab 的所有模型) | | | | | | | | **提示词 (Prompt)**: | | | | [ Textarea: Analyze the financial data... ] | | | +---------------------------------------------------------+ | | | | [ Card: 模块 2 - 深度风险评估 ] | | +---------------------------------------------------------+ | | | ID: risk_eval | | | | 依赖 (Dependencies): [ 基本面概览 (basic_analysis) x ] | | | | Model: [ claude-3-opus (Anthropic) v ] | | | | ... | | | +---------------------------------------------------------+ | | | | [ Button: + 添加分析模块 ] [ Button: 保存配置 ] | +---------------------------------------------------------------+ ``` #### 4.4.4 系统状态 (System) (Tab 4) **设计逻辑**: 1. **Status Check**: 简单的健康看板。 2. **Modules**: 列出所有微服务/组件的状态 (Running, Degraded, Down)。 ``` +---------------------------------------------------------------+ | [ Tabs: AI Provider | 数据源配置 | 分析模板 | 系统 ] | +---------------------------------------------------------------+ | | | **系统健康状态 (System Health)** | | | | [ API Gateway ] [ Badge: Healthy (Green) ] | | [ Workflow Orchestrator] [ Badge: Healthy (Green) ] | | [ Data Persistence ] [ Badge: Healthy (Green) ] | | [ Report Generator ] [ Badge: Degraded (Yellow) ] | | | | **服务详情**: | | - Database Connection: OK | | - NATS Connection: OK | | - Redis Cache: OK | | | +---------------------------------------------------------------+ ``` ## 5. 目录结构 (Proposed) ``` frontend/ ├── public/ ├── src/ │ ├── api/ # Axios instances, Zod schemas │ ├── assets/ │ ├── components/ # Shared UI components │ │ ├── ui/ # shadcn/ui primitives (迁移自原项目) │ │ ├── layout/ # Shell, Header │ │ ├── workflow/ # DAG Graph, Status Badges │ │ └── business/ # 业务组件 │ │ ├── StockChart.tsx │ │ ├── FinancialTable.tsx │ │ └── ModelSelector.tsx # 复用的模型选择器 │ ├── pages/ # 路由页面组件 │ │ ├── Dashboard.tsx │ │ ├── Report.tsx │ │ └── config/ # 配置相关页面拆分 │ │ ├── index.tsx # 配置页 Layout │ │ ├── AIProviderTab.tsx │ │ ├── DataSourceTab.tsx │ │ └── TemplateTab.tsx │ ├── hooks/ # Global hooks │ ├── lib/ # Utils (cn, formatters) │ ├── stores/ # Zustand stores │ ├── types/ # Global types (if not in schema) │ ├── App.tsx # Router Setup │ └── main.tsx # Entry ├── index.html ├── package.json └── vite.config.ts ``` ## 6. 迁移步骤 1. **归档**: 将现有 `frontend` 移动到 `frontend/archive/v2_nextjs`。 2. **初始化**: 在 `frontend` 创建新的 Vite 项目。 3. **安装依赖**: Tailwind, Shadcn, Axios, Zustand, React Router, Lucide, ReactFlow。 4. **移植 UI**: 从归档中复制 `components/ui` (shadcn)。 5. **移植逻辑**: * 重写 `useWorkflow` hook,使用新的 Store 模式。 * 实现 DAG 可视化组件。 * 实现配置页面的“添加+补全”交互。 6. **验证**: 测试与后端的 SSE 连接和 DAG 状态同步。 ## 7. 执行阶段 (Next Steps) 1. 归档现有代码。 2. 初始化 Vite + React 项目。 3. 配置 Tailwind + Shadcn 环境。 4. 搭建基础 Layout (Shell)。