From 2809048e6e7737b3e64d28853f92b8d97a50cdd1 Mon Sep 17 00:00:00 2001 From: zdl <3489966805@qq.com> Date: Tue, 23 Dec 2025 17:59:00 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E7=B2=BE=E7=AE=80=20CLAUDE.md=20?= =?UTF-8?q?=E4=BC=98=E5=8C=96=20Claude=20Code=20=E6=80=A7=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将文件从 61KB 精简到 5.5KB(减少 91%) - 删除冗长的目录结构详解,改为表格速查 - 删除大量代码示例,保留核心概念 - 引用独立文档(TYPESCRIPT_MIGRATION.md)替代详细内容 - 保留技术栈、命令、目录结构、开发工作流等核心信息 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- CLAUDE.md | 1805 ++++------------------------------------------------- 1 file changed, 130 insertions(+), 1675 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 9b5ce716..ebbe5688 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -2,36 +2,7 @@ > **🌐 语言偏好**: 请始终使用中文与用户交流,包括所有解释、分析、文档编写和代码注释。 -本文件为 Claude Code (claude.ai/code) 提供在此代码库中工作的指导说明。 - -## 📖 文档结构导航 - -本文档分为以下主要章节,建议按需查阅: - -**基础信息**: -- [项目概览](#项目概览) - 技术栈、项目定位 -- [开发命令](#开发命令) - 常用命令速查 -- [配置](#配置) - 环境变量、MSW、路径别名、Webpack - -**架构设计**: -- [架构](#架构) - 应用入口流程、路由架构 -- [前端目录结构详解](#前端目录结构详解) - 完整的目录说明与使用指南 -- [后端架构详解](#后端架构详解) - Flask、Celery、数据库架构 - -**开发指南**: -- [开发工作流](#开发工作流) - 路由、组件、API、Redux 开发指南 -- [TypeScript 接入](#typescript-接入) - TypeScript 渐进式迁移方案与指南 -- [常见开发任务](#常见开发任务) - 5 个详细的开发任务教程 -- [技术路径与开发指南](#技术路径与开发指南) - UI 框架选型、技术栈演进、最佳实践 - -**技术决策与规范**: -- [UI 框架选型与使用指南](#ui-框架选型与使用指南) - Ant Design + Chakra UI 混合策略 -- [架构设计原则](#架构设计原则) - 组件设计、状态管理、代码分割、API 层 -- [开发规范与最佳实践](#开发规范与最佳实践) - 命名规范、Git 工作流、代码审查 - -**技术债务与维护**: -- [技术债务与已知问题](#技术债务与已知问题) - 技术债务跟踪、优化机会 -- [更新本文档](#更新本文档) - 文档维护指南 +本文件为 Claude Code 提供在此代码库中工作的指导说明。 --- @@ -42,1712 +13,196 @@ ### 技术栈 **前端** -- **核心框架**: React 18.3.1 -- **类型系统**: TypeScript 5.9.3(渐进式接入中,支持 JS/TS 混合开发) -- **UI 组件库**: - - Chakra UI 2.10.9(主要,全局使用) - - Ant Design 5.27.4(表格/表单) - - **HeroUI 3.0.0-beta**(AgentChat 专用,2025-11-22 升级) -- **状态管理**: Redux Toolkit 2.9.2 -- **路由**: React Router v6.30.1 配合 React.lazy() 实现代码分割 -- **构建系统**: CRACO 7.1.0 + 激进的 webpack 5 优化 -- **图表库**: ECharts 5.6.0、ApexCharts 3.27.3、Recharts 3.1.2、D3 7.9.0、Visx 3.12.0 -- **动画**: Framer Motion 4.1.17 -- **日历**: FullCalendar 5.9.0、React Big Calendar 0.33.2 -- **图标**: Lucide React 0.540.0(推荐)、React Icons 4.12.0、@ant-design/icons 6.0.0 -- **网络请求**: Axios 1.10.0 -- **实时通信**: Socket.IO Client 4.7.4 -- **数据分析**: PostHog 1.281.0 -- **开发工具**: MSW (Mock Service Worker) 用于 API mocking -- **虚拟化**: @tanstack/react-virtual 3.13.12(性能优化) -- **其他**: Draft.js(富文本编辑)、React Markdown、React Quill - -**注意**: HeroUI v3 文档参考 https://v3.heroui.com/llms.txt,详细升级说明见 [HEROUI_V3_UPGRADE_GUIDE.md](./HEROUI_V3_UPGRADE_GUIDE.md) +- **核心**: React 18.3.1 + TypeScript 5.9.3(渐进式迁移中) +- **UI**: Chakra UI 2.10.9(主要)+ Ant Design 5.27.4(表格/表单)+ HeroUI 3.0.0-beta(AgentChat) +- **状态**: Redux Toolkit 2.9.2 +- **路由**: React Router v6.30.1 + React.lazy() 代码分割 +- **构建**: CRACO 7.1.0 + webpack 5 优化 +- **图表**: ECharts 5.6.0、ApexCharts、Recharts、D3、Visx +- **其他**: Framer Motion、FullCalendar、Socket.IO Client、MSW、PostHog **后端** - Flask + SQLAlchemy ORM -- ClickHouse(分析型数据库)+ MySQL/PostgreSQL(事务型数据库) -- Flask-SocketIO 实现 WebSocket 实时更新 -- Celery + Redis 处理后台任务 -- 腾讯云短信 + 微信支付集成 +- ClickHouse(分析型)+ MySQL(事务型)+ Redis(缓存) +- Flask-SocketIO(WebSocket)+ Celery(后台任务) + +--- ## 开发命令 -### 前端开发 ```bash -npm start # 使用 mock 数据启动(.env.mock),代理到 localhost:5001 -npm run start:real # 使用真实后端启动(.env.local) -npm run start:dev # 使用开发配置启动(.env.development) -npm run start:test # 同时启动后端(app.py)和前端(.env.test) -npm run dev # 'npm start' 的别名 -npm run backend # 仅启动 Flask 服务器(python app.py) +# 前端开发 +npm start # Mock 模式启动(默认) +npm run start:real # 真实后端 +npm run build # 生产构建 +npm run lint:check # ESLint 检查 +npm run type-check # TypeScript 类型检查 -npm run build # 生产环境构建,包含 Gulp 许可证头 -npm run build:analyze # 使用 webpack bundle analyzer 构建 -npm test # 运行 React 测试套件(CRACO) +# 后端开发 +python app.py # Flask 服务器 +python simulation_background_processor.py # Celery 后台处理 -npm run lint:check # 检查 ESLint 规则(退出码 0) -npm run lint:fix # 自动修复 ESLint 问题 - -npm run type-check # TypeScript 类型检查(不生成输出) -npm run type-check:watch # TypeScript 类型检查监听模式 - -npm run clean # 删除 node_modules 和 package-lock.json -npm run reinstall # 清洁安装(运行 clean + install) +# 部署 +npm run deploy # 部署到生产环境 ``` -### 后端开发 -```bash -python app.py # 主 Flask 服务器 -python simulation_background_processor.py # 交易模拟的后台任务处理器 -pip install -r requirements.txt # 安装 Python 依赖 -``` - -### 部署 -```bash -npm run deploy # 从本地部署(scripts/deploy-from-local.sh) -npm run rollback # 回滚到上一个版本 -``` +--- ## 架构 ### 应用入口流程 ``` -src/index.js -└── src/App.js(根组件) - ├── AppProviders (src/providers/AppProviders.js) - │ ├── ReduxProvider(store 来自 src/store/) - │ ├── ChakraProvider(主题来自 src/theme/) - │ ├── NotificationProvider (src/contexts/NotificationContext.js) - │ └── AuthProvider (src/contexts/AuthContext.js) - ├── AppRoutes (src/routes/index.js) - │ ├── MainLayout 路由(带导航栏/页脚) - │ └── 独立路由(认证页面、全屏视图) - └── GlobalComponents(模态框覆盖层、全局 UI) +src/index.js → App.js +├── AppProviders (Redux → Chakra → Ant ConfigProvider → Notification → Auth) +├── AppRoutes (src/routes/index.js) +└── GlobalComponents ``` -### 路由架构(模块化设计) -路由采用**声明式**设计,并拆分到 `src/routes/` 中的多个文件: - -- **index.js** - 主路由器(组合配置 + 渲染路由) -- **routeConfig.js** - 路由定义(路径、组件、保护模式、布局、子路由) -- **lazy-components.js** - React.lazy() 导入,用于代码分割 -- **homeRoutes.js** - 嵌套的首页路由 -- **constants/** - 保护模式、布局映射 -- **utils/** - 路由渲染逻辑(wrapWithProtection、renderRoute) - -路由保护模式(PROTECTION_MODES): +### 路由保护模式 - `PUBLIC` - 无需认证 -- `MODAL` - 未登录时显示认证模态框 -- `REDIRECT` - 未登录时重定向到 /auth/sign-in +- `MODAL` - 未登录显示认证模态框 +- `REDIRECT` - 未登录重定向到登录页 -### 前端目录结构详解 +### 目录结构速查 -本项目采用**功能驱动的目录结构**,按职责将代码组织到不同目录中。以下是完整的目录结构及详细说明: - -#### 核心目录概览 +| 目录 | 用途 | +|------|------| +| `src/views/` | 页面组件(按功能模块组织) | +| `src/components/` | 可复用 UI 组件 | +| `src/services/` | API 服务层 | +| `src/store/slices/` | Redux 状态 | +| `src/hooks/` | 自定义 Hooks | +| `src/contexts/` | React Context | +| `src/utils/` | 工具函数 | +| `src/constants/` | 常量定义 | +| `src/types/` | TypeScript 类型 | +| `src/theme/` | Chakra UI 主题 | +| `src/routes/` | 路由配置 | +| `src/mocks/` | MSW Mock 数据 | +| `src/layouts/` | 页面布局模板 | +### 路径别名 ``` -src/ -├── index.js # 应用入口文件 -├── App.js # 根组件(组合 Providers + Routes) -│ -├── providers/ # Provider 组合层 -├── routes/ # 路由配置与管理 -│ ├── constants/ # 路由常量(保护模式等) -│ └── utils/ # 路由工具函数 -├── layouts/ # 页面布局模板 -│ ├── components/ # 布局专用组件 -│ └── config/ # 布局配置 -├── views/ # 页面级组件(详见下方) -├── components/ # 可复用 UI 组件(详见下方) -│ -├── contexts/ # React Context 状态管理 -├── store/ # Redux 全局状态管理 -│ ├── api/ # RTK Query API 定义 -│ ├── middleware/ # Redux 中间件 -│ └── slices/ # Redux Slices -├── hooks/ # 自定义 React Hooks -├── types/ # TypeScript 类型定义 -│ -├── services/ # API 服务层 -│ └── socket/ # WebSocket 服务 -├── utils/ # 工具函数库 -│ ├── performance/ # 性能监控工具 -│ └── stock/ # 股票相关工具 -├── constants/ # 全局常量定义 -│ -├── theme/ # Chakra UI 主题配置 -│ ├── additions/ # 主题扩展 -│ ├── components/ # 组件级主题 -│ └── foundations/ # 基础样式(颜色、字体等) -├── assets/ # 静态资源 -│ ├── css/ # CSS 样式 -│ ├── fonts/ # 字体文件 -│ ├── img/ # 图片资源 -│ ├── less/ # Less 样式 -│ ├── scss/ # SCSS 样式 -│ ├── sounds/ # 音频文件 -│ ├── sprites/ # 精灵图 -│ ├── svg/ # SVG 图标 -│ └── svgs/ # SVG 组件 -├── styles/ # 全局样式 -│ -├── mocks/ # 开发环境 Mock 数据 -│ ├── data/ # Mock 数据文件 -│ └── handlers/ # MSW 请求处理器 -├── lib/ # 第三方库配置 -├── data/ # 静态数据文件 -├── devtools/ # 开发调试工具 -├── bytedesk-integration/ # 客服系统集成 -│ ├── components/ # 客服组件 -│ └── config/ # 客服配置 -└── variables/ # 可配置变量 +@/ → src/ +@components/ → src/components/ +@views/ → src/views/ +@services/ → src/services/ +@store/ → src/store/ +@hooks/ → src/hooks/ +@utils/ → src/utils/ +@types/ → src/types/ +@constants/ → src/constants/ ``` --- -#### 详细目录说明 +## 开发工作流 -##### 📁 `src/providers/` - Provider 组合层 +### 添加新路由 +1. `src/routes/lazy-components.js` - 添加 lazy import +2. `src/routes/routeConfig.js` - 配置路由(path、component、protection、layout) -**用途**: 集中管理应用的所有 Context Providers,避免在 App.js 中嵌套过深。 +### 添加新 API +1. `src/services/` - 创建服务函数 +2. `src/mocks/handlers/` - 添加 MSW handler(Mock 模式) -**核心文件**: -- `AppProviders.js` - 所有 Provider 的组合容器 +### 添加新 Redux Slice +1. `src/store/slices/yourSlice.ts` - 创建 slice +2. `src/store/index.js` - 导入并添加到 store -**Provider 嵌套顺序**(从外到内): -```javascript -ReduxProvider // 1. Redux 状态管理(最外层) - └─ ChakraProvider // 2. Chakra UI 主题系统 - └─ ConfigProvider // 3. Ant Design 主题配置 - └─ NotificationProvider // 4. 通知系统 - └─ AuthProvider // 5. 认证系统(最内层) -``` - -**何时修改**: -- 添加新的全局 Provider(如 i18n、Analytics) -- 调整 Provider 顺序(注意依赖关系) - ---- - -##### 📁 `src/routes/` - 路由系统 - -**用途**: 模块化路由配置,采用声明式设计,支持懒加载和路由保护。 - -**核心文件**: -- `index.js` - 主路由器(渲染所有路由) -- `routeConfig.js` - **路由配置中心**(所有路由定义) -- `lazy-components.js` - React.lazy() 懒加载组件导入 -- `homeRoutes.js` - 首页嵌套路由 -- `constants/protectionModes.js` - 路由保护模式定义 -- `utils/wrapWithProtection.js` - 路由保护逻辑 -- `utils/renderRoute.js` - 路由渲染工具 - -**路由保护模式**: -- `PUBLIC` - 公开访问,无需登录 -- `MODAL` - 未登录时显示登录模态框(不跳转) -- `REDIRECT` - 未登录时重定向到 /auth/sign-in - -**添加新路由的步骤**: 参见"常见开发任务 → 如何添加新的页面路由" - -**命名约定**: -- 路由路径使用 kebab-case: `portfolio`, `trading-simulation` -- 组件名使用 PascalCase: `Portfolio`, `TradingSimulation` - ---- - -##### 📁 `src/layouts/` - 页面布局 - -**用途**: 定义页面的通用布局结构(导航栏、侧边栏、页脚等),复用于多个页面。 - -**核心文件**: -- `MainLayout.js` - 主布局(带顶部导航栏 + 侧边栏 + 页脚) -- `Auth.js` - 认证页面布局(无导航栏,纯净背景) - -**布局特性**: -- 每个布局包含独立的 ErrorBoundary(错误隔离) -- 通过 `` 渲染子路由内容 -- 布局内可访问认证状态(AuthContext) - -**何时创建新布局**: -- 需要完全不同的页面结构(如打印页、全屏图表) -- 特定页面需要自定义导航栏/侧边栏 - ---- - -##### 📁 `src/views/` - 页面级组件 - -**用途**: 存放路由对应的页面组件,每个文件对应一个路由页面。 - -**组织结构**: -``` -views/ -├── AgentChat/ # AI 智能会话页面 -│ ├── index.js # 页面入口 -│ ├── components/ # 页面专属组件 -│ │ ├── ChatArea/ # 聊天区域 -│ │ ├── LeftSidebar/ # 左侧边栏 -│ │ ├── RightSidebar/ # 右侧边栏 -│ │ └── MeetingRoom/ # 会议室组件 -│ ├── constants/ # 页面常量 -│ ├── hooks/ # 页面专属 Hooks -│ └── utils/ # 页面专属工具函数 -│ -├── Center/ # 投资规划中心页面 -│ ├── components/ # 日历、事件面板等 -│ ├── hooks/ # 页面 Hooks -│ └── utils/ # 工具函数 -│ -├── Community/ # 社区页面(大型功能模块) -│ ├── index.js # 页面入口 -│ ├── components/ # 页面专属组件 -│ │ ├── DynamicNews/ # 动态新闻模块 -│ │ ├── EventCard/ # 事件卡片(含 atoms 子目录) -│ │ ├── EventDetailModal/ # 事件详情弹窗 -│ │ ├── HotEvents/ # 热点事件 -│ │ └── SearchFilters/ # 搜索筛选器 -│ └── hooks/ # 页面专属 Hooks -│ -├── Company/ # 公司详情页面(复杂模块) -│ ├── components/ # 页面专属组件 -│ │ ├── CompanyHeader/ # 公司头部信息 -│ │ ├── CompanyOverview/ # 公司概览(含多个 Tab) -│ │ │ ├── BasicInfoTab/ # 基础信息 Tab -│ │ │ ├── DeepAnalysisTab/ # 深度分析 Tab -│ │ │ └── hooks/ # Tab 专属 Hooks -│ │ ├── CompanyTabs/ # Tab 导航 -│ │ ├── DynamicTracking/ # 动态跟踪 -│ │ ├── FinancialPanorama/ # 财务全景 -│ │ ├── ForecastReport/ # 预测报告 -│ │ ├── MarketDataView/ # 市场数据视图 -│ │ │ ├── components/ # 子组件 -│ │ │ │ ├── panels/ # 面板组件 -│ │ │ │ ├── shared/ # 共享组件 -│ │ │ │ └── StockSummaryCard/ -│ │ │ ├── hooks/ # 数据 Hooks -│ │ │ ├── services/ # API 服务 -│ │ │ └── utils/ # 工具函数 -│ │ └── StockQuoteCard/ # 股票报价卡片 -│ ├── constants/ # 公司页面常量 -│ ├── hooks/ # 公司页面 Hooks -│ └── theme/ # 公司页面主题 -│ -├── Concept/ # 概念板块页面 -│ ├── components/ -│ └── hooks/ -│ -├── EventDetail/ # 事件详情页面 -│ ├── components/ -│ └── hooks/ -│ -├── Home/ # 首页 -│ └── components/ -│ -├── LimitAnalyse/ # 涨停分析页面 -│ ├── components/ -│ └── hooks/ -│ -├── Profile/ # 用户中心页面 -│ └── components/ -│ ├── ForumCenter/ # 论坛中心 -│ ├── MarketDashboard/ # 市场仪表板 -│ └── WatchSidebar/ # 自选股侧边栏 -│ -├── StockOverview/ # 股票概览页面 -│ ├── components/ -│ │ ├── FlexScreen/ # 弹性屏幕 -│ │ └── HotspotOverview/ # 热点概览 -│ ├── hooks/ -│ └── theme/ -│ -├── TradingSimulation/ # 交易模拟页面 -│ ├── components/ -│ └── hooks/ -│ -├── Authentication/ # 认证相关页面 -│ ├── Lock/ -│ ├── Reset/ -│ └── Verification/ -│ -├── DataBrowser/ # 数据浏览器页面 -├── Landing/ # 落地页 -├── Pages/ # 其他页面 -├── Pricing/ # 定价页面 -├── Settings/ # 设置页面 -└── ValueForum/ # 价值论坛页面 -``` - -**命名约定**: -- 目录名使用 PascalCase: `Community`, `TradingSimulation` -- 主文件始终为 `index.js`(方便导入) - -**原则**: -- 页面组件主要负责**数据获取和布局组合**,不应包含复杂的 UI 逻辑 -- 复杂 UI 逻辑应拆分到 `components/` 子目录 -- 页面超过 500 行时考虑拆分(参见"组件组织模式") - ---- - -##### 📁 `src/components/` - 可复用 UI 组件 - -**用途**: 存放跨页面复用的通用 UI 组件(按钮、卡片、表格、模态框等)。 - -**组织结构**(按功能分类): -``` -components/ -├── Auth/ # 认证相关组件 -├── Button/ # 按钮组件 -├── Card/ # 卡片组件 -├── Calendars/ # 日历组件 -│ -├── Charts/ # 图表组件 -│ └── Stock/ # 股票图表 -│ └── hooks/ # 图表专用 Hooks -├── StockChart/ # K 线图组件(独立) -│ ├── config/ # 图表配置 -│ ├── hooks/ # 图表 Hooks -│ ├── indicators/ # 技术指标 -│ ├── types/ # 类型定义 -│ └── utils/ # 工具函数 -│ -├── ChatBot/ # 聊天机器人组件 -├── Citation/ # 引用组件 -├── ConceptStocksModal/ # 概念股票弹窗 -├── ConnectionStatusBar/ # 连接状态栏 -├── Editor/ # 富文本编辑器 -├── ErrorPage/ # 错误页面组件 -│ -├── EventCommentSection/ # 事件评论区 -├── EventDetailPanel/ # 事件详情面板 -│ └── RelatedConceptsSection/ # 相关概念区域 -├── FavoriteButton/ # 收藏按钮 -│ -├── Footer/ # 页脚组件 -├── FUI/ # 金融 UI 组件库 -├── GlassCard/ # 玻璃态卡片 -├── GlobalSidebar/ # 全局侧边栏 -│ -├── Header/ # 页头组件 -├── Heading/ # 标题组件 -├── Icons/ # 图标组件 -├── Image/ # 图片组件 -├── ImageLightbox/ # 图片灯箱 -├── ImagePreviewModal/ # 图片预览弹窗 -│ -├── InvestmentCalendar/ # 投资日历 -├── Layout/ # 布局辅助组件 -├── Loading/ # 加载状态组件 -├── Logo/ # Logo 组件 -├── Menu/ # 菜单组件 -│ -├── MiniProgramLauncher/ # 小程序启动器 -│ └── hooks/ -├── Navbars/ # 导航栏组件 -│ ├── components/ # 子组件 -│ │ ├── FeatureMenus/ # 功能菜单 -│ │ ├── MobileDrawer/ # 移动端抽屉 -│ │ ├── NavbarActions/ # 导航栏操作 -│ │ ├── Navigation/ # 导航组件 -│ │ ├── ProfileCompletenessAlert/ # 资料完善提醒 -│ │ └── UserMenu/ # 用户菜单 -│ ├── SearchBar/ # 搜索栏 -│ └── Settings/ # 设置面板 -├── NotificationContainer/ # 通知容器 -│ -├── PinInput/ # PIN 输入组件 -├── ReferencePopover/ # 引用弹出框 -├── RelationDescWithReferences/ # 带引用的关系描述 -├── RiskDisclaimer/ # 风险提示 -├── RTLProvider/ # RTL 支持 -│ -├── Scrollbar/ # 自定义滚动条 -├── ScrollToTop/ # 返回顶部 -├── Section/ # 区块组件 -├── Separator/ # 分隔线 -├── StockRelation/ # 股票关系图 -├── Subscription/ # 订阅组件 -│ -├── SubTabContainer/ # 子 Tab 容器 -├── TabContainer/ # Tab 容器 -├── Tables/ # 表格组件 -├── TabPanelContainer/ # Tab 面板容器 -├── Tagline/ # 标语组件 -├── TradeDatePicker/ # 交易日期选择器 -├── VisxPieChart/ # Visx 饼图 -│ -├── Arrows/ # 箭头组件 -├── Configurator/ # 配置器组件 -├── contexts/ # 组件专用 Context -├── FixedPlugin/ # 固定插件 -└── Generating/ # 生成中状态 -``` - -**何时添加新组件**: -- 组件在 2+ 个页面中使用 -- 组件具有明确的职责和边界 -- 组件可独立测试 - -**命名约定**: -- 组件目录使用 PascalCase: `EventCard`, `StockTable` -- 每个组件目录包含: - - `index.js` - 主导出文件 - - `ComponentName.js` - 实现代码(可选,简单组件直接在 index.js) - - `ComponentName.test.js` - 测试文件(可选) - -**避免**: -- 将页面特定组件放在这里(应放在 `views/{PageName}/components/`) -- 过度拆分(不要为了拆分而拆分) - ---- - -##### 📁 `src/contexts/` - React Context 状态管理 - -**用途**: 存放使用 React Context API 管理的跨组件状态。 - -**核心 Contexts**: -- `AuthContext.js` - 认证状态(用户信息、登录状态、登录/登出方法) -- `NotificationContext.js` - 通知系统(Socket.IO 实时通知、Toast/Alert) -- `GlobalSidebarContext.js` - 全局侧边栏状态(展开/收起、面板切换) -- `SidebarContext.js` - 页面侧边栏状态(展开/收起) - -**何时使用 Context**: -- 跨层级传递数据(避免 props drilling) -- 不频繁变化的数据(主题、语言、认证状态) -- 依赖注入场景 - -**何时不使用 Context**: -- 频繁变化的数据 → 使用 Redux -- 服务端数据 → 使用 React Query(计划中) -- 本地 UI 状态 → 使用 useState - -**Context 文件结构**: -```javascript -// AuthContext.js -export const AuthContext = createContext(); - -export const AuthProvider = ({ children }) => { - const [user, setUser] = useState(null); - // ... - return ( - - {children} - - ); -}; - -export const useAuth = () => useContext(AuthContext); // 自定义 Hook -``` - ---- - -##### 📁 `src/store/` - Redux 全局状态管理 - -**用途**: 使用 Redux Toolkit 管理全局状态(UI 状态、跨页面共享数据)。 - -**目录结构**: -``` -store/ -├── index.js # Store 配置(combineReducers) -├── hooks.ts # 类型化 Hooks(useAppSelector, useAppDispatch) -└── slices/ # Redux Slices - ├── authModalSlice.js # 认证模态框状态 - ├── communityDataSlice.js # 社区数据(事件列表、筛选) - ├── deviceSlice.js # 设备检测 - ├── industrySlice.js # 行业/概念数据 - ├── planningSlice.ts # 投资规划中心 - ├── posthogSlice.js # PostHog 分析配置 - ├── stockSlice.js # 股票数据(自选股) - └── subscriptionSlice.js # 用户订阅状态 -``` - -**何时使用 Redux**: -- 全局 UI 状态(模态框开关、侧边栏状态) -- 需要在多个不相关组件间共享的数据 -- 需要持久化的状态(与 redux-persist 结合) -- 需要中间件处理的复杂逻辑 - -**Slice 命名约定**: -- 文件名: `{feature}Slice.js` (如 `authModalSlice.js`) -- Slice 名称: `{feature}` (如 `name: 'authModal'`) -- Actions: 动词开头 (如 `openModal`, `closeModal`, `setUser`) - -**添加新 Slice**: 参见"常见开发任务 → 如何添加新的 Redux Slice" - ---- - -##### 📁 `src/hooks/` - 自定义 React Hooks - -**用途**: 存放可复用的自定义 Hooks,封装常见逻辑模式。 - -**Hook 类型示例**: -``` -hooks/ -├── useAuth.js # 认证相关(实际导出自 AuthContext) -├── useStockData.js # 数据获取 Hook -├── useDebounce.js # 防抖 Hook -├── useIntersectionObserver.js # 懒加载/无限滚动 -├── useLocalStorage.js # 本地存储持久化 -├── useMediaQuery.js # 响应式查询 -└── usePrevious.js # 获取前一个值 -``` - -**命名约定**: -- 文件名: `use{PascalCase}.js` (如 `useStockData.js`) -- 必须以 `use` 开头(React Hooks 规则) -- 一个文件导出一个 Hook - -**Hook 设计原则**: -- 职责单一(只做一件事) -- 返回对象或数组(不返回原始值) -- 包含完整的状态管理(loading, error, data) - -**何时创建新 Hook**: -- 逻辑在 2+ 个组件中重复 -- 组件逻辑可以独立测试 -- 需要封装浏览器 API(localStorage, IntersectionObserver) - ---- - -##### 📁 `src/services/` - API 服务层 - -**用途**: 封装所有后端 API 调用,提供统一的接口供组件调用。 - -**组织结构**(按业务领域划分): -``` -services/ -├── authService.js # 认证相关 API(登录、注册、登出) -├── stockService.js # 股票数据 API(模糊搜索、股票信息) -├── eventService.js # 事件/资讯 API -├── financialService.js # 财务数据 API(财报、指标) -├── marketService.js # 市场数据 API(行情、交易数据) -├── industryService.js # 行业/概念 API -├── categoryService.ts # 分类数据 API -├── elasticsearchService.js # ES 搜索服务 -├── llmService.js # LLM 大模型服务 -├── mcpService.js # MCP 协议服务 -├── socketService.js # WebSocket 服务 -├── browserNotificationService.js # 浏览器通知服务 -├── notificationHistoryService.js # 通知历史服务 -├── notificationMetricsService.js # 通知统计服务 -├── creditSystemService.js # 积分系统服务 -├── predictionMarketService.js # 预测市场服务 -├── miniprogramService.js # 小程序服务 -├── conceptStaticService.js # 概念静态数据 -├── ztStaticService.js # 涨停静态数据 -└── socket/ # WebSocket 模块 -``` - -**服务函数命名约定**: -- `fetch{Entity}` - 获取数据 (如 `fetchStockData`) -- `create{Entity}` - 创建记录 (如 `createOrder`) -- `update{Entity}` - 更新记录 (如 `updateProfile`) -- `delete{Entity}` - 删除记录 (如 `deletePost`) - -**标准 API 调用结构**: -```javascript -// stockService.js -import axios from 'axios'; -import { getApiBase } from '@utils/apiConfig'; - -const api = axios.create({ - baseURL: getApiBase(), - timeout: 10000, -}); - -export const fetchStockData = async (stockCode) => { - try { - const response = await api.get(`/api/stocks/${stockCode}`); - return response.data; - } catch (error) { - console.error('fetchStockData error:', error); - throw error; - } -}; -``` - -**原则**: -- 组件不应直接调用 axios(通过 service 层) -- 每个 service 函数应包含错误处理 -- 使用 `getApiBase()` 获取 API 基础 URL(支持 Mock 模式) - ---- - -##### 📁 `src/utils/` - 工具函数库 - -**用途**: 存放纯函数工具、格式化工具、计算逻辑等不依赖 React 的通用代码。 - -**核心工具文件**: -``` -utils/ -├── apiConfig.js # API 配置(getApiBase, isMockMode) -├── priceFormatters.js # 价格/数字格式化函数 -├── dateFormatters.js # 日期格式化函数 -├── logger.js # 统一日志工具 -├── validators.js # 表单验证函数 -├── calculations.js # 金融计算函数 -└── string.js # 字符串处理函数 -``` - -**命名约定**: -- 文件名: `camelCase.js` (如 `priceFormatters.js`) -- 函数名: `camelCase` (如 `formatPrice`, `calculateProfit`) -- 导出方式: 命名导出 (如 `export const formatPrice = ...`) - -**工具函数特点**: -- **纯函数**: 相同输入始终返回相同输出,无副作用 -- **可测试**: 易于编写单元测试 -- **可复用**: 多处使用的逻辑 - -**示例**: -```javascript -// priceFormatters.js -export const formatPrice = (price, currency = '¥') => { - return `${currency}${price.toFixed(2)}`; -}; - -export const formatPercent = (value, decimals = 2) => { - return `${(value * 100).toFixed(decimals)}%`; -}; -``` - ---- - -##### 📁 `src/constants/` - 全局常量定义 - -**用途**: 存放全局常量、枚举值、配置对象等不可变数据。 - -**常见常量文件**: -``` -constants/ -├── animations.js # 动画配置(duration、easing) -├── routes.js # 路由路径常量 -├── apiEndpoints.js # API 端点常量 -├── colors.js # 颜色常量(补充主题) -├── tradingConfig.js # 交易相关配置 -└── errorMessages.js # 错误消息常量 -``` - -**命名约定**: -- 常量名使用 SCREAMING_SNAKE_CASE: `API_BASE_URL`, `MAX_RETRY_COUNT` -- 配置对象使用 camelCase: `animationConfig`, `chartColors` - -**示例**: -```javascript -// animations.js -export const ANIMATION_DURATION = { - FAST: 150, - NORMAL: 300, - SLOW: 500, -}; - -export const EASING = { - EASE_IN_OUT: 'cubic-bezier(0.4, 0, 0.2, 1)', - EASE_OUT: 'cubic-bezier(0, 0, 0.2, 1)', -}; -``` - -**原则**: -- 避免魔法数字/字符串(在代码中硬编码) -- 方便统一修改(单一数据源) -- 提高代码可读性 - ---- - -##### 📁 `src/theme/` - UI 主题配置 - -**用途**: 定义 Chakra UI 主题配置(颜色、字体、间距、组件样式等)。 - -**核心文件**: -``` -theme/ -├── theme.js # 主题主文件(导出完整主题) -├── foundations/ # 基础样式(颜色、字体、间距) -│ ├── colors.js -│ ├── typography.js -│ └── spacing.js -└── components/ # 组件级主题覆盖 - ├── button.js - ├── card.js - └── modal.js -``` - -**主题配置示例**: -```javascript -// theme.js -import { extendTheme } from '@chakra-ui/react'; -import { colors } from './foundations/colors'; -import { ButtonStyles as Button } from './components/button'; - -const theme = extendTheme({ - colors, - fonts: { - heading: `'Open Sans', sans-serif`, - body: `'Raleway', sans-serif`, - }, - components: { - Button, - }, -}); - -export default theme; -``` - -**何时修改主题**: -- 添加自定义颜色/渐变 -- 统一修改所有 Button/Card 的默认样式 -- 配置深色模式 - ---- - -##### 📁 `src/assets/` - 静态资源 - -**用途**: 存放图片、字体、图标等静态文件。 - -**组织结构**: -``` -assets/ -├── img/ # 图片资源 -│ ├── logo.png -│ ├── backgrounds/ -│ └── illustrations/ -├── icons/ # SVG 图标 -└── fonts/ # 自定义字体文件(如需要) -``` - -**使用方式**: -```javascript -import logo from '@assets/img/logo.png'; - -Logo -``` - ---- - -##### 📁 `src/mocks/` - 开发环境 Mock 数据 - -**用途**: 使用 MSW (Mock Service Worker) 拦截 API 请求,返回 mock 数据,实现前后端分离开发。 - -**目录结构**: -``` -mocks/ -├── browser.js # MSW 初始化(浏览器环境) -├── handlers/ # API Mock Handlers(按领域划分) -│ ├── index.js # 汇总所有 handlers -│ ├── auth.js # 认证相关 API mock -│ ├── stock.js # 股票数据 API mock -│ ├── portfolio.js # 投资组合 API mock -│ └── community.js # 社区内容 API mock -└── data/ # Mock 数据文件 - ├── stocks.json - ├── users.json - └── events.json -``` - -**启用 Mock 模式**: -```bash -# 方式 1: 使用 .env.mock 配置(默认) -npm start - -# 方式 2: 手动设置环境变量 -REACT_APP_ENABLE_MOCK=true npm start -``` - -**添加新 Mock Handler**: 参见"常见开发任务 → 如何添加新的 MSW Mock Handler" - -**原则**: -- Mock 数据应尽量模拟真实数据结构 -- 使用 MSW 的 `http.get/post/put/delete` 定义 handlers -- Handler 中可模拟延迟、错误响应(测试加载/错误状态) - ---- - -##### 📁 其他目录 - -**`src/lib/`** - 第三方库配置 -- 存放第三方库的自定义配置(如 PostHog、Analytics) - -**`src/styles/`** - 全局样式 -- 存放全局 CSS/SCSS 文件(如 reset.css、global.scss) - -**`src/variables/`** - 可配置变量 -- 存放可通过环境变量覆盖的配置(如 API URLs、Feature Flags) - ---- - -#### 目录结构最佳实践 - -**1. 就近原则(Co-location)** -- 将相关文件放在一起(组件、样式、测试、工具函数) -- 示例: `EventCard/` 目录包含 `EventCard.js`、`EventCard.test.js`、`utils.js` - -**2. 单一职责** -- 每个目录只负责一个领域(不要混合业务逻辑和 UI 组件) -- 示例: `services/` 只包含 API 调用,不包含 UI 组件 - -**3. 避免深层嵌套** -- 目录层级不超过 4 层(超过则考虑重构) -- 示例: `src/views/Community/components/EventCard/` 已经是 4 层 - -**4. 命名一致性** -- 组件: PascalCase (`EventCard`) -- 文件: camelCase (`priceFormatters.js`) -- 常量: SCREAMING_SNAKE_CASE (`API_BASE_URL`) - -**5. 导出规范** -- 每个目录包含 `index.js` 作为主导出文件 -- 使用命名导出 (`export const ...`) 而非默认导出(除组件外) - ---- - -#### 查找文件指南 - -**如何快速找到想要修改的文件?** - -| 需求 | 目录 | 示例 | -|------|------|------| -| 修改页面布局 | `src/layouts/` | `MainLayout.js` | -| 修改某个页面 | `src/views/{PageName}/` | `Community/index.js` | -| 修改可复用组件 | `src/components/` | `DataTable/index.js` | -| 修改 API 调用 | `src/services/` | `stockService.js` | -| 修改工具函数 | `src/utils/` | `priceFormatters.js` | -| 修改全局状态 | `src/store/slices/` | `stockSlice.js` | -| 添加新路由 | `src/routes/routeConfig.js` | - | -| 修改主题颜色 | `src/theme/foundations/colors.js` | - | -| 添加 Mock API | `src/mocks/handlers/` | `stock.js` | - -**使用路径别名快速导入**: -```javascript -// ✅ 使用别名(推荐) -import { EventCard } from '@components/EventCard'; -import { formatPrice } from '@utils/priceFormatters'; -import { fetchStockData } from '@services/stockService'; - -// ❌ 使用相对路径(不推荐) -import { EventCard } from '../../../components/EventCard'; -import { formatPrice } from '../../utils/priceFormatters'; -``` - -### 后端架构详解 - -本项目后端采用 **Flask 微服务架构**,结合多种数据库和消息队列,实现高性能金融数据处理和实时通信。 - -#### 后端目录结构 - -``` -项目根目录/ -├── app.py # 主 Flask 应用(Web 服务器 + API 路由) -├── simulation_background_processor.py # Celery 后台处理器(交易模拟任务) -├── concept_api.py # 概念/行业分析独立 API 服务 -│ -├── wechat_pay.py # 微信支付业务逻辑 -├── wechat_pay_config.py # 微信支付配置(商户号、密钥等) -│ -├── tdays.csv # 交易日历数据(A 股交易日) -├── requirements.txt # Python 依赖包清单 -│ -├── models/ # 数据库模型定义(SQLAlchemy) -│ ├── user.py -│ ├── stock.py -│ └── transaction.py -│ -├── services/ # 业务逻辑服务层 -│ ├── stock_service.py -│ ├── trading_service.py -│ └── notification_service.py -│ -├── utils/ # 后端工具函数 -│ ├── db_utils.py # 数据库连接工具 -│ ├── clickhouse_client.py # ClickHouse 客户端封装 -│ └── date_utils.py # 日期处理工具 -│ -└── config/ # 配置文件 - ├── development.py - ├── production.py - └── test.py -``` - ---- - -#### 核心组件详解 - -##### 1️⃣ `app.py` - 主 Flask 应用 - -**职责**: Web 服务器、API 路由、认证、会话管理、WebSocket 通信 - -**核心功能**: -- **Flask 应用初始化**: 配置 CORS、Session、Logging -- **API 路由定义**: RESTful API 端点(`/api/stocks`, `/api/portfolio`, `/api/community`) -- **认证系统**: Flask-Login 集成(登录、登出、权限校验) -- **WebSocket 服务**: Flask-SocketIO 实现实时推送(股票行情、事件通知) -- **数据库连接**: SQLAlchemy ORM + ClickHouse Client -- **交易日历加载**: 启动时从 `tdays.csv` 加载 A 股交易日数据到全局变量 - -**技术栈**: -- **Flask** - 轻量级 Web 框架 -- **Flask-Login** - 用户会话管理 -- **Flask-SocketIO** - WebSocket 实时通信 -- **Flask-CORS** - 跨域资源共享配置 -- **SQLAlchemy** - ORM(对象关系映射) - -**API 路由示例**: -```python -# 获取股票数据 -@app.route('/api/stocks/', methods=['GET']) -@login_required -def get_stock_data(stock_code): - # 从 ClickHouse 查询历史数据 - data = clickhouse_client.query(f"SELECT * FROM stocks WHERE code = '{stock_code}'") - return jsonify(data) - -# 创建交易订单 -@app.route('/api/orders', methods=['POST']) -@login_required -def create_order(): - data = request.json - order = Order(user_id=current_user.id, stock_code=data['stock_code'], ...) - db.session.add(order) - db.session.commit() - return jsonify({'order_id': order.id}) -``` - -**WebSocket 事件示例**: -```python -# 客户端订阅股票行情 -@socketio.on('subscribe_stock') -def handle_subscribe(data): - stock_code = data['stock_code'] - join_room(f'stock_{stock_code}') - emit('subscribed', {'stock_code': stock_code}) - -# 服务端推送行情更新 -def push_quote_update(stock_code, quote_data): - socketio.emit('stock_quote', quote_data, room=f'stock_{stock_code}') -``` - -**交易日历加载**: -```python -# 全局变量存储交易日 -trading_days = [] - -# 启动时加载 tdays.csv -def load_trading_days(): - global trading_days - with open('tdays.csv', 'r') as f: - trading_days = [line.strip() for line in f.readlines()] - -# 判断是否为交易日 -def is_trading_day(date_str): - return date_str in trading_days -``` - ---- - -##### 2️⃣ `simulation_background_processor.py` - Celery 后台处理器 - -**职责**: 处理长时间运行的后台任务(交易模拟、报表生成、数据同步) - -**为什么需要后台处理器?** -- 交易模拟需要执行数百次历史回测计算(耗时 10-60 秒) -- 避免阻塞 Flask 主线程(影响其他 API 响应) -- 支持任务队列、重试、失败处理 - -**技术栈**: -- **Celery** - 分布式任务队列 -- **Redis** - 消息代理(Broker)和结果存储(Backend) -- **ClickHouse** - 高性能查询历史股票数据 - -**任务示例**: -```python -from celery import Celery - -# Celery 实例 -celery_app = Celery('tasks', broker='redis://localhost:6379/0') - -# 交易模拟任务 -@celery_app.task(bind=True) -def run_simulation(self, user_id, strategy_config): - """ - 执行交易模拟任务 - :param user_id: 用户 ID - :param strategy_config: 策略配置(买入条件、卖出条件、资金管理) - :return: 模拟结果(收益率、最大回撤、交易明细) - """ - try: - # 1. 从 ClickHouse 获取历史数据 - stock_data = clickhouse_client.query(...) - - # 2. 执行回测计算 - for i in range(len(stock_data)): - # 模拟交易逻辑 - if should_buy(stock_data[i]): - buy(stock_data[i]) - if should_sell(stock_data[i]): - sell(stock_data[i]) - - # 3. 计算绩效指标 - result = { - 'total_return': calculate_return(), - 'max_drawdown': calculate_drawdown(), - 'trades': get_trade_history(), - } - - # 4. 保存结果到 MySQL - save_simulation_result(user_id, result) - - return result - except Exception as e: - # 失败重试(最多 3 次) - self.retry(exc=e, countdown=60, max_retries=3) -``` - -**从 Flask 调用 Celery 任务**: -```python -# app.py -@app.route('/api/simulations', methods=['POST']) -@login_required -def start_simulation(): - strategy = request.json - - # 异步提交任务到 Celery - task = run_simulation.delay(current_user.id, strategy) - - return jsonify({ - 'task_id': task.id, - 'status': 'pending', - 'message': '模拟任务已提交,请稍后查看结果' - }) - -# 查询任务状态 -@app.route('/api/simulations/', methods=['GET']) -def get_simulation_status(task_id): - task = run_simulation.AsyncResult(task_id) - - if task.state == 'PENDING': - response = {'status': 'pending', 'progress': 0} - elif task.state == 'SUCCESS': - response = {'status': 'completed', 'result': task.result} - elif task.state == 'FAILURE': - response = {'status': 'failed', 'error': str(task.info)} - - return jsonify(response) -``` - -**启动 Celery Worker**: -```bash -# 启动 worker(监听任务队列) -celery -A simulation_background_processor worker --loglevel=info - -# 启动 Flower(Celery 监控工具) -celery -A simulation_background_processor flower -``` - ---- - -##### 3️⃣ `concept_api.py` - 概念/行业分析 API - -**职责**: 独立的概念板块分析服务(涨停分析、热点行业、资金流向) - -**为什么独立部署?** -- 概念分析计算密集(需要遍历数千只股票) -- 独立扩展性(可部署到多台服务器) -- 服务隔离(不影响主应用性能) - -**部署架构**: -``` -前端请求 → Nginx 反向代理 - ├─ /api → Flask 主应用 (端口 5001) - └─ /concept-api → Concept API (端口 6801) -``` - -**API 示例**: -```python -from flask import Flask, jsonify -import clickhouse_driver - -app = Flask(__name__) - -# 获取涨停股票列表 -@app.route('/limit_up', methods=['GET']) -def get_limit_up_stocks(): - """ - 获取当日涨停股票列表,按概念板块分组 - """ - query = """ - SELECT - stock_code, - stock_name, - concept, - close_price, - change_percent - FROM stock_daily - WHERE trade_date = today() - AND change_percent >= 9.9 - ORDER BY concept, change_percent DESC - """ - - data = clickhouse_client.query(query) - - # 按概念分组 - result = {} - for row in data: - concept = row['concept'] - if concept not in result: - result[concept] = [] - result[concept].append(row) - - return jsonify(result) - -if __name__ == '__main__': - app.run(host='0.0.0.0', port=6801) -``` - -**前端调用**(通过代理): -```javascript -// craco.config.js 配置代理 -proxy: { - '/concept-api': { - target: 'http://49.232.185.254:6801', - pathRewrite: { '^/concept-api': '' }, - } -} - -// 前端调用 -fetch('/concept-api/limit_up') - .then(res => res.json()) - .then(data => console.log(data)); -``` - ---- - -##### 4️⃣ 微信支付集成 - -**文件**: -- `wechat_pay.py` - 微信支付业务逻辑(下单、查询、退款) -- `wechat_pay_config.py` - 配置(商户号、API 密钥、证书路径) - -**核心功能**: -- **统一下单**: 创建支付订单(JSAPI、Native、H5) -- **支付回调**: 接收微信支付结果通知 -- **订单查询**: 查询订单支付状态 -- **退款处理**: 发起退款请求 - -**示例代码**: -```python -# wechat_pay.py -from wechatpy.pay import WeChatPay -from wechat_pay_config import MCHID, API_KEY, CERT_PATH - -# 初始化微信支付客户端 -wechat_pay = WeChatPay( - appid='your_appid', - api_key=API_KEY, - mch_id=MCHID, - mch_cert=CERT_PATH, -) - -# 创建订单 -def create_order(user_id, amount, description): - result = wechat_pay.order.create( - trade_type='JSAPI', - body=description, - total_fee=int(amount * 100), # 单位:分 - notify_url='https://yourdomain.com/api/wechat/callback', - user_id=user_id, - ) - return result - -# 支付回调处理 -@app.route('/api/wechat/callback', methods=['POST']) -def wechat_callback(): - xml_data = request.data - data = wechat_pay.parse_payment_result(xml_data) - - if data['return_code'] == 'SUCCESS': - # 更新订单状态 - order_id = data['out_trade_no'] - update_order_status(order_id, 'paid') - - return wechat_pay.reply('OK', True) -``` - ---- - -##### 5️⃣ 数据库架构 - -**多数据库策略**: - -| 数据库 | 用途 | 特点 | 示例表 | -|--------|------|------|--------| -| **ClickHouse** | 时序数据存储 | OLAP(列式存储、查询速度快) | `stock_daily`(日线数据)
`stock_minute`(分钟数据)
`concept_daily`(概念板块数据) | -| **MySQL/PostgreSQL** | 事务数据存储 | OLTP(ACID 保证、关系型) | `users`(用户表)
`orders`(订单表)
`portfolios`(持仓表)
`subscriptions`(订阅表) | -| **Redis** | 缓存 + 消息队列 | 内存数据库(高速读写) | 股票行情缓存
用户 Session
Celery 任务队列 | - -**ClickHouse 使用场景**: -```python -# 查询某只股票的历史数据(100 万行数据,查询耗时 < 100ms) -query = """ - SELECT - trade_date, - open, high, low, close, volume - FROM stock_daily - WHERE stock_code = '600000.SH' - AND trade_date >= '2020-01-01' - ORDER BY trade_date -""" - -data = clickhouse_client.query(query) -``` - -**MySQL 使用场景**: -```python -# 创建订单(事务保证) -@app.route('/api/orders', methods=['POST']) -def create_order(): - try: - # 开启事务 - order = Order(user_id=user_id, stock_code=stock_code, ...) - db.session.add(order) - - # 扣减账户余额 - account = Account.query.get(user_id) - account.balance -= order.total_amount - - # 提交事务 - db.session.commit() - return jsonify({'success': True}) - except Exception as e: - # 回滚事务 - db.session.rollback() - return jsonify({'error': str(e)}), 500 -``` - ---- - -#### 后端技术栈详解 - -**核心框架**: -- **Flask 2.x** - 轻量级 Web 框架,易于扩展 -- **Flask-Login** - 用户认证与会话管理 -- **Flask-SocketIO** - WebSocket 实时通信(基于 Socket.IO 协议) -- **Flask-CORS** - 跨域资源共享配置 - -**数据库与 ORM**: -- **SQLAlchemy** - Python ORM,支持 MySQL/PostgreSQL -- **ClickHouse Driver** - ClickHouse Python 客户端 -- **Redis-py** - Redis Python 客户端 - -**后台任务处理**: -- **Celery** - 分布式任务队列 -- **Redis** - Celery 消息代理(Broker) - -**第三方服务**: -- **微信支付 SDK** - `wechatpy` -- **腾讯云短信 SDK** - 发送验证码、通知 - ---- - -#### 后端开发最佳实践 - -**1. API 设计规范**: -```python -# ✅ RESTful 风格 -GET /api/stocks # 获取股票列表 -GET /api/stocks/:id # 获取单个股票 -POST /api/stocks # 创建股票 -PUT /api/stocks/:id # 更新股票 -DELETE /api/stocks/:id # 删除股票 - -# ✅ 统一响应格式 -{ - "code": 200, - "message": "success", - "data": { ... } -} - -# ❌ 避免使用动词命名 -POST /api/getStockData # 不推荐 -POST /api/createNewOrder # 不推荐 -``` - -**2. 错误处理**: -```python -# 统一错误处理 -@app.errorhandler(Exception) -def handle_error(e): - if isinstance(e, ValidationError): - return jsonify({'error': str(e)}), 400 - elif isinstance(e, Unauthorized): - return jsonify({'error': 'Unauthorized'}), 401 - else: - logger.error(f'Unhandled exception: {e}') - return jsonify({'error': 'Internal server error'}), 500 -``` - -**3. 数据库连接管理**: -```python -# 使用连接池 -engine = create_engine( - 'mysql://user:pass@localhost/db', - pool_size=10, - max_overflow=20, - pool_recycle=3600, -) - -# 请求结束后自动关闭连接 -@app.teardown_appcontext -def shutdown_session(exception=None): - db.session.remove() -``` - -**4. 性能优化**: -- **数据库索引**: 为常用查询字段添加索引 -- **查询优化**: 避免 N+1 查询,使用 `joinedload` -- **缓存策略**: 使用 Redis 缓存热点数据(股票行情、用户信息) -- **异步任务**: 耗时操作使用 Celery 异步处理 - ---- - -#### 后端部署架构 - -**生产环境部署**: -``` -Nginx (反向代理 + 负载均衡) - ├─ Gunicorn (WSGI 服务器) × 4 进程 - │ └─ Flask 应用 (app.py) - │ - ├─ Celery Worker × 2 进程 - │ └─ 后台任务处理 - │ - ├─ Redis (缓存 + 消息队列) - ├─ MySQL (事务数据) - └─ ClickHouse (时序数据) -``` - -**启动命令**: -```bash -# 启动 Flask 应用(Gunicorn) -gunicorn -w 4 -b 0.0.0.0:5001 app:app - -# 启动 Celery Worker -celery -A simulation_background_processor worker --loglevel=info - -# 启动 Concept API -python concept_api.py -``` - -**监控与日志**: -- **日志**: 使用 Python `logging` 模块记录日志 -- **监控**: Celery Flower 监控任务状态 -- **性能**: 使用 APM 工具(如 New Relic、Datadog) +### 组件组织 +- **原子设计**: Atoms → Molecules → Organisms +- **页面专属组件**: 放在 `views/{PageName}/components/` +- **可复用组件**: 放在 `src/components/` --- ## 配置 ### 环境文件 -``` -.env.mock - Mock 模式(默认):MSW 拦截所有 API 调用,无需后端 -.env.development - 开发模式:连接到开发后端 -.env.test - 测试模式:用于 'npm run start:test'(后端 + 前端一起) -.env.production - 生产环境构建配置 -``` +- `.env.mock` - Mock 模式(默认,REACT_APP_ENABLE_MOCK=true) +- `.env.development` - 开发模式 +- `.env.production` - 生产环境 -**关键环境变量:** -- `REACT_APP_ENABLE_MOCK=true` - 启用 MSW mocking -- `REACT_APP_API_URL` - 后端 URL(空字符串 = 使用相对路径或 MSW) - -### MSW (Mock Service Worker) 设置 -MSW 用于开发期间的 API mocking: - -1. **激活方式**:在 env 文件中设置 `REACT_APP_ENABLE_MOCK=true` -2. **Worker 文件**:`public/mockServiceWorker.js`(自动生成) -3. **Handlers**:`src/mocks/handlers/`(按领域组织:auth、stock、company 等) -4. **模式**:`onUnhandledRequest: 'warn'` - 未处理的请求会传递到后端 - -当 MSW 激活时,开发服务器代理被禁用(MSW 优先拦截)。 - -### 路径别名 (craco.config.js) -所有别名解析到 `src/` 子目录: -``` -@/ → src/ -@assets/ → src/assets/ -@components/ → src/components/ -@constants/ → src/constants/ -@contexts/ → src/contexts/ -@data/ → src/data/ -@hooks/ → src/hooks/ -@layouts/ → src/layouts/ -@lib/ → src/lib/ -@mocks/ → src/mocks/ -@providers/ → src/providers/ -@routes/ → src/routes/ -@services/ → src/services/ -@store/ → src/store/ -@styles/ → src/styles/ -@theme/ → src/theme/ -@utils/ → src/utils/ -@variables/ → src/variables/ -@views/ → src/views/ -``` - -### Webpack 优化 (craco.config.js) -**性能特性:** -- 文件系统缓存(重新构建速度提升 50-80%) -- 按库激进的代码分割: - - `react-vendor` - React 核心(优先级 30) - - `charts-lib` - echarts、d3、apexcharts、recharts(优先级 25) - - `chakra-ui` - Chakra UI + Emotion(优先级 23) - - `antd-lib` - Ant Design(优先级 22) - - `three-lib` - Three.js(优先级 20) - - `calendar-lib` - moment、date-fns、FullCalendar(优先级 18) -- 从构建中移除 ESLint 插件(速度提升 20-30%) -- 启用 Babel 缓存 -- moment locale 剥离(IgnorePlugin) -- Source maps:生产环境禁用,开发环境使用 `eval-cheap-module-source-map` - -**开发服务器:** -- 端口 3000(prestart 时杀死现有进程) -- 代理(当 MSW 禁用时):`/api` → `http://49.232.185.254:5001` -- Bundle 分析器:`ANALYZE=true npm run build:analyze` - -### 构建流程 -1. `npm run build` 使用 CRACO + webpack 优化编译 -2. Gulp 任务(`gulp licenses`)为 JS/HTML 添加 Creative Tim 许可证头 -3. 输出:`build/` 目录 - -**Node 兼容性:** -```bash -NODE_OPTIONS='--openssl-legacy-provider --max_old_space_size=4096' -``` - -## 开发工作流 - -### 路由开发 -添加新路由的步骤: - -1. 在 `src/routes/lazy-components.js` 中添加 lazy import -2. 在 `src/routes/routeConfig.js` 中添加路由配置: - - `path` - URL 路径 - - `component` - 来自 lazyComponents - - `protection` - MODAL/REDIRECT/PUBLIC - - `layout` - 'main'(带导航栏)或 'none'(全屏) -3. 路由自动使用 Suspense + ErrorBoundary 渲染(由 PageTransitionWrapper 处理) - -### 组件组织模式 -基于最近的重构(详见 README.md): - -**原子设计模式:** -- **Atoms(原子)** - 基础 UI 元素(按钮、徽章、输入框) -- **Molecules(分子)** - 原子的组合(卡片、表单) -- **Organisms(有机体)** - 复杂组件(列表、面板) - -**大型组件示例结构(1000+ 行):** -``` -src/views/Community/components/ -├── EventCard/ -│ ├── index.js - 智能包装器(路由紧凑 vs 详细视图) -│ ├── CompactEventCard.js - 紧凑视图 -│ ├── DetailedEventCard.js - 详细视图 -│ ├── EventTimeline.js - 原子组件 -│ ├── EventImportanceBadge.js - 原子组件 -│ └── ... -``` - -**工具提取:** -- 将可复用逻辑提取到 `src/utils/`(如 `priceFormatters.js`) -- 将共享常量提取到 `src/constants/`(如 `animations.js`) - -### API 集成 -**服务层**(`src/services/`): -- 使用 `src/utils/apiConfig.js` 中的 `getApiBase()` 获取基础 URL -- 示例:`${getApiBase()}/api/endpoint` -- 在 mock 模式下,MSW 拦截;在开发/生产环境下,请求后端 - -**添加新的 API 端点:** -1. 在 `src/services/` 中添加服务函数(或在组件中内联) -2. 如果使用 MSW:在 `src/mocks/handlers/{domain}.js` 中添加 handler -3. 在 `src/mocks/handlers/index.js` 中导入 handler - -### Redux 状态管理 -**现有 slices**(`src/store/slices/`): -- `authModalSlice` - 认证模态框状态 -- `communityDataSlice` - 社区内容(事件列表、筛选等) -- `deviceSlice` - 设备信息(移动端/桌面端检测) -- `industrySlice` - 行业/概念数据 -- `planningSlice.ts` - 投资规划中心(计划、复盘、日历事件) -- `posthogSlice` - PostHog 分析配置 -- `stockSlice` - 股票数据(自选股、全量股票列表) -- `subscriptionSlice` - 用户订阅状态 - -**添加新 slice:** -1. 创建 `src/store/slices/yourSlice.js`(推荐使用 TypeScript: `.ts`) -2. 在 `src/store/index.js` 中导入并添加 -3. 通过 `useSelector` 访问,通过 `useDispatch` 派发 -4. 使用 `useAppSelector` 和 `useAppDispatch`(类型化版本,推荐) +### MSW Mock +- 激活: `REACT_APP_ENABLE_MOCK=true` +- Handlers: `src/mocks/handlers/` +- 数据: `src/mocks/data/` --- ## TypeScript 接入 -### 概述 +**状态**: 渐进式迁移中,支持 JS/TS 混合开发 -项目已于 **2025-11-13** 完成 TypeScript 环境配置,采用**渐进式迁移策略**,支持 JavaScript 和 TypeScript 混合开发。 +**类型定义位置**: `src/types/` +- `api.ts` - ApiResponse、PaginatedResponse、ApiError +- `stock.ts` - StockInfo、StockQuote、KLineData +- `user.ts` - UserInfo、AuthInfo -**当前状态**: 环境配置完成,准备开始代码迁移 -**迁移策略**: 新代码使用 TypeScript,旧代码按优先级逐步迁移 -**类型严格度**: 推荐模式(`noImplicitAny: true`,其他严格检查待后续开启) - -### 已完成的环境配置 - -✅ **TypeScript 编译器**: v5.9.3 -✅ **tsconfig.json**: 推荐模式配置,支持 JS/TS 混合开发 -✅ **CRACO 配置**: 支持 `.ts` 和 `.tsx` 文件编译 -✅ **ESLint 配置**: 支持 TypeScript 语法检查 -✅ **路径别名**: 与现有 `@/` 别名保持一致 -✅ **全局类型定义**: 基础类型文件已创建在 `src/types/` - -### 可用类型定义 - -项目已创建以下基础类型定义文件: - -**`src/types/api.ts`** - API 相关类型 -- `ApiResponse` - 通用 API 响应结构 -- `PaginatedResponse` - 分页响应 -- `ApiError` - API 错误类型 -- `ListQueryParams` - 列表查询参数 - -**`src/types/stock.ts`** - 股票相关类型 -- `StockInfo` - 股票基础信息 -- `StockQuote` - 股票行情数据 -- `KLineData` - K 线数据 -- `StockFinancials` - 财务指标 -- `StockPosition` - 股票持仓 -- `Sector` - 概念/行业板块 - -**`src/types/user.ts`** - 用户相关类型 -- `UserInfo` - 用户基础信息 -- `AuthInfo` - 认证信息 -- `LoginParams` / `RegisterParams` - 登录/注册参数 -- `UserSubscription` - 订阅信息 -- `UserAccount` - 资金账户 -- `UserSettings` - 用户设置 - -**使用方式**: -```typescript -// 统一导入 -import type { StockQuote, UserInfo, ApiResponse } from '@/types'; - -// 或从具体文件导入 -import type { StockQuote } from '@/types/stock'; -``` - -### TypeScript 命令 +**开发规范**: +- 新代码必须使用 TypeScript +- 避免使用 `any` +- 组件 Props 使用 `interface` 定义 +**命令**: ```bash -# 类型检查(不生成输出文件) -npm run type-check - -# 类型检查 + 监听模式 -npm run type-check:watch - -# ESLint 检查(包含 TS 文件) -npm run lint:check - -# ESLint 自动修复 -npm run lint:fix +npm run type-check # 类型检查 +npm run type-check:watch # 监听模式 ``` -### 迁移路线图 +详细指南参考: [TYPESCRIPT_MIGRATION.md](./TYPESCRIPT_MIGRATION.md) -详细的迁移指南请参考 **[TYPESCRIPT_MIGRATION.md](./TYPESCRIPT_MIGRATION.md)** 文档。 +--- -**简要路线图**: +## 后端架构 -1. **优先级 1️⃣**: 工具层(`src/utils/`, `src/constants/`) - - 纯函数,迁移成本低,收益高 - - 提供类型定义给其他模块使用 +### 核心文件 +- `app.py` - Flask 主应用(API + WebSocket) +- `simulation_background_processor.py` - Celery 后台任务 +- `concept_api.py` - 概念分析独立服务 -2. **优先级 2️⃣**: 类型定义层(扩展 `src/types/`) - - 添加 `trading.ts`, `community.ts`, `chart.ts` 等 +### 数据库 +| 数据库 | 用途 | +|--------|------| +| ClickHouse | 时序数据(股票日线、分钟线) | +| MySQL | 事务数据(用户、订单、持仓) | +| Redis | 缓存 + Celery 消息队列 | -3. **优先级 3️⃣**: 服务层(`src/services/`) - - 定义 API 请求/响应类型 - - 使用 `ApiResponse` 包装响应 +### API 规范 +```python +# RESTful 风格 +GET /api/stocks # 获取列表 +GET /api/stocks/:id # 获取单个 +POST /api/stocks # 创建 +PUT /api/stocks/:id # 更新 +DELETE /api/stocks/:id # 删除 -4. **优先级 4️⃣**: Redux 状态层(`src/store/slices/`) - - 定义 `RootState` 和 `AppDispatch` 类型 - - 创建类型化的 hooks - -5. **优先级 5️⃣**: 自定义 Hooks(`src/hooks/`) - - 添加泛型支持 - - 定义完整返回值类型 - -6. **优先级 6️⃣**: 组件层(`src/components/`, `src/views/`) - - Atoms → Molecules → Organisms → Pages - - 优先迁移复用度高的组件 - -### 开发规范 - -**新代码**: -- ✅ **必须使用 TypeScript**(`.ts` 或 `.tsx`) -- ✅ 所有函数参数和返回值添加类型 -- ✅ 组件 Props 使用 `interface` 定义 -- ✅ 避免使用 `any`(特殊情况需添加注释说明) - -**旧代码迁移**: -- 按优先级迁移,不强制一次性完成 -- 迁移前先阅读 [TYPESCRIPT_MIGRATION.md](./TYPESCRIPT_MIGRATION.md) -- 迁移后运行 `npm run type-check` 验证 - -**类型定义**: -- 公共类型定义导出到 `src/types/` -- 组件内部类型可定义在组件文件中 -- 使用 `type` 还是 `interface` 参考 [迁移指南](./TYPESCRIPT_MIGRATION.md) - -### 常见问题 - -**Q: 路径别名 `@/types` 无法识别?** -A: 确保在 `tsconfig.json` 中配置了 `paths`,并重启 IDE。使用 `npm run type-check` 而非命令行 `tsc`。 - -**Q: 如何处理第三方库没有类型定义?** -A: -1. 尝试安装 `@types/library-name` -2. 创建自定义类型声明文件 `src/types/library-name.d.ts` -3. 临时使用 `as any`(需添加 TODO 注释) - -**Q: 迁移期间如何处理 any 类型?** -A: 添加 ESLint 禁用注释和 TODO 说明: -```typescript -/* eslint-disable @typescript-eslint/no-explicit-any */ -// TODO: 待完善类型定义 -const legacyFunction = (data: any): any => { ... }; +# 统一响应格式 +{ "code": 200, "message": "success", "data": {...} } ``` -**Q: React 组件的 children 类型如何定义?** -A: 使用 `React.ReactNode`: -```typescript -interface Props { - children: React.ReactNode; -} -``` +--- -### 参考资源 +## 代码规范 -- [TYPESCRIPT_MIGRATION.md](./TYPESCRIPT_MIGRATION.md) - 完整迁移指南 -- [TypeScript 官方文档](https://www.typescriptlang.org/docs/) -- [React TypeScript Cheatsheet](https://react-typescript-cheatsheet.netlify.app/) -- [Redux Toolkit TypeScript 指南](https://redux-toolkit.js.org/usage/usage-with-typescript) +### 命名约定 +- 组件/目录: PascalCase (`EventCard`) +- 文件/函数: camelCase (`formatPrice.js`) +- 常量: SCREAMING_SNAKE_CASE (`API_BASE_URL`) +- 路由路径: kebab-case (`/trading-simulation`) + +### 最佳实践 +- 组件不直接调用 axios,通过 service 层 +- 使用 `getApiBase()` 获取 API 基础 URL +- 页面超过 500 行考虑拆分 +- 复用组件需在 2+ 个页面使用 --- ## 更新本文档 -本 CLAUDE.md 文件是一个持续更新的文档。在以下情况下应更新它: -- 添加新的架构模式或指南 -- 发现新的最佳实践 -- 解决或添加技术债务项 -- 做出重要的技术决策 -- 进行重要的代码清理或重构 - -所有开发人员应在入职时审查本文档,并在做出架构决策时参考它。 +在以下情况下更新此文档: +- 添加新的架构模式 +- 做出重要技术决策 +- 进行重要代码重构