## Architecture ### 目录结构(React + TypeScript + Ant Design) ``` frontend/src/ ├── pages/ # 页面级组件(路由对应) ├── components/ # 可复用 UI 组件 ├── services/ # API 客户端(Axios 封装) ├── hooks/ # 自定义 React Hooks ├── contexts/ # Context Providers(auth, timer 等) ├── utils/ # 工具函数(auth, validation, date 等) ├── types/ # TypeScript 类型定义 └── config/ # Feature flags, 性能配置 ``` ### 状态管理 | 状态类型 | 方案 | |---------|------| | 服务器状态 | React Query (TanStack Query) | | 全局状态 | Context API | | 本地状态 | useState / useReducer | | 表单状态 | Ant Design Form | **禁止**:Redux / MobX(本项目不使用) ### 路由 - React Router v6 - 路由定义集中在 `src/routes/` - 懒加载:`const Page = lazy(() => import(...))` ### API 调用 - 使用 `services/` 下的封装函数,不要在组件里直接 `axios.get` - 响应类型必须有 TypeScript interface - 错误统一由 axios 拦截器处理 ### 样式 - Ant Design 组件 + CSS Module - 禁止内联 `style={{ ... }}` 用于复杂样式 - 全局变量走 CSS Variables ### Modal 安全规则(重要) `Modal.success/info/warning/error` 是非阻塞调用,后续 UI 操作必须放在 `onOk` 回调中: ```tsx // WRONG Modal.success({ title: '成功' }); setNextModalOpen(true); // 立即执行,两个 modal 冲突 // CORRECT Modal.success({ title: '成功', onOk: () => setNextModalOpen(true), }); ``` ### 命名规范 | 类型 | 约定 | 示例 | |------|------|------| | 组件文件 | PascalCase | `UserProfile.tsx` | | Hook 文件 | camelCase | `useAuth.ts` | | 工具文件 | kebab-case | `date-utils.ts` | | 组件名 | PascalCase | `UserProfile` | | Hook 名 | `use` 前缀 | `useAuth` | ### 测试 - 单测:Jest + React Testing Library - E2E:Playwright - 测试文件:`xxx.test.tsx` 与源文件同目录