前端架构
EduBuddy 前端是一个基于 React 18 + TypeScript + Vite 构建的单页应用(SPA),采用 Ant Design 作为 UI 组件库,ECharts 绘制可视化图表,Zustand 管理全局状态。
技术栈
| 技术 | 版本 | 用途 |
|---|---|---|
| React | 18.x | UI 框架,函数组件 + Hooks |
| TypeScript | 5.x | 类型安全 |
| Vite | 8.x | 构建工具,HMR 开发体验 |
| React Router | 6.x | 客户端路由 |
| Ant Design | 5.x | UI 组件库(表单、表格、模态框等) |
| ECharts / echarts-for-react | 5.x | 折线图、雷达图、饼图等可视化 |
| Zustand | 4.x | 轻量全局状态管理 |
| Axios | 1.x | HTTP 请求客户端 |
| react-markdown | 9.x | 渲染 AI 返回的 Markdown 内容 |
目录结构
frontend/src/
├── App.tsx # 根组件,路由配置
├── index.tsx # 应用入口,挂载 React
├── index.css # 全局样式
├── components/
│ └── layout/
│ └── MainLayout.tsx # 主布局(侧边栏 + 顶部栏 + Outlet)
├── pages/ # 页面级组件(与路由一一对应)
│ ├── DashboardPage.tsx
│ ├── QuestionsPage.tsx
│ ├── PracticePage.tsx
│ ├── LearningPathsPage.tsx
│ ├── ProgressPage.tsx
│ ├── UploadPage.tsx
│ ├── SharingPage.tsx
│ ├── ProfilePage.tsx
│ ├── LoginPage.tsx
│ └── RegisterPage.tsx
├── services/
│ └── api.ts # 所有 API 调用封装
└── store/
└── useStore.ts # Zustand 全局状态
路由设计
采用 React Router v6 嵌套路由,通过路由守卫实现权限控制:
// 路由结构
/login → LoginPage(PublicRoute,已登录跳 /dashboard)
/register → RegisterPage(PublicRoute)
/ → MainLayout(PrivateRoute,未登录跳 /login)
/dashboard → DashboardPage
/questions → QuestionsPage
/practice → PracticePage
/practice/:id → PracticePage(指定题目)
/learning-paths → LearningPathsPage
/progress → ProgressPage
/upload → UploadPage
/sharing → SharingPage
/profile → ProfilePage
路由守卫
- PrivateRoute:检查
useStore().isAuthenticated,未登录重定向到/login - PublicRoute:已登录用户访问登录/注册页时,自动重定向到
/dashboard
全局状态管理(Zustand)
useStore.ts 使用 Zustand + persist 中间件持久化用户状态:
interface AppState {
user: User | null; // 当前登录用户信息
token: string | null; // JWT Token
isAuthenticated: boolean; // 是否已登录
sidebarCollapsed: boolean; // 侧边栏折叠状态
// Actions
setUser(user, token): void // 登录后调用
logout(): void // 清除状态和 localStorage
toggleSidebar(): void
updateUser(updates): void // 更新个人资料后调用
}
持久化策略:仅持久化 user、token、isAuthenticated 三个字段到 localStorage(key: ai-student-store),UI 状态(sidebarCollapsed)不持久化。
API 服务层
services/api.ts 使用 Axios 封装所有接口调用,分为 6 个命名空间:
| 命名空间 | 说明 |
|---|---|
authAPI | 登录、注册、获取/更新用户信息、修改密码 |
questionAPI | 题目 CRUD、AI 生成、AI 解题、提交答案 |
progressAPI | 知识点掌握度、每日统计、AI 分析、评估报告 |
pathAPI | 学习路线 CRUD、AI 生成、报名、进度更新 |
uploadAPI | PDF/图片/语音/文本上传解析 |
sharingAPI | 分享、收件箱、发件箱、标记已读 |
Axios 拦截器
- 请求拦截器:从
localStorage读取 token,自动添加Authorization: Bearer <token>请求头 - 响应拦截器:
- 401 响应:清除 token,重定向到
/login - 其他错误:通过 Ant Design
message.error()全局提示错误信息
- 401 响应:清除 token,重定向到
主布局组件(MainLayout)
MainLayout.tsx 是登录后所有页面的外层容器,包含:
- 侧边栏导航:Ant Design Menu,支持折叠,高亮当前路由
- 顶部栏:用户头像/名称、未读分享计数角标、退出登录
- 内容区:
<Outlet />渲染当前路由的页面组件
可视化图表
进度页面(ProgressPage.tsx)使用 echarts-for-react 渲染三种图表:
| 图表类型 | 数据来源 | 展示内容 |
|---|---|---|
| 折线图(Line) | GET /api/progress/daily-stats | 近 30 天每日练习题数 + 学习时长 |
| 雷达图(Radar) | GET /api/progress/mastery | 各知识点掌握度(0-100%) |
| 饼图(Pie) | GET /api/progress/subject-distribution | 各学科练习占比 |
Markdown 渲染
AI 返回的解题过程、学习路线节点内容、评估报告均为 Markdown 格式,使用 react-markdown + remark-gfm 插件渲染,支持表格、代码块、数学公式(需额外插件)。
语音朗读(TTS)
答题页面通过浏览器原生 Web Speech API(window.speechSynthesis)实现文字转语音朗读,无需额外依赖或 API 费用。语言设置为 zh-CN(中文普通话)。
Web Speech API 的语音朗读功能依赖浏览器和操作系统内置的 TTS 引擎,在不同平台上音质和支持程度可能有所差异。Safari / Firefox 的行为与 Chrome 可能略有不同。