# LPT 前端应用(lpt-fe) > Vue 3 + TypeScript + Vite 单页应用 ## Git 提交规范 - 提交信息使用**中文**,简洁描述变更内容 - 格式:`类型: 简述`,如 `feat: 新增学习会话页面`、`fix: 修复路由守卫401跳转`、`docs: 补充组件说明` --- ## 技术栈 - **框架**: Vue 3 + TypeScript + Vite 5 - **UI 库**: Element Plus 2.8 - **HTTP**: Axios(`withCredentials: true`,自动携带 Cookie `satoken`) - **思维导图**: mind-elixir 5.13 - **Markdown**: marked 18.0 - **测试**: Vitest + Playwright --- ## 项目结构 ``` lpt-fe/src/ ├── api/ → API 接口层(6个模块) │ ├── login.ts │ ├── reportFragments.ts │ ├── review.ts │ ├── standardMindMap.ts │ ├── studySessions.ts │ └── tasks.ts ├── components/ → 页面组件 │ ├── Login.vue → 登录页 │ ├── Welcome.vue → 首页(滚动 feed + 回忆卡片) │ ├── Study.vue → 学习任务列表 + 权重配置 │ ├── StartTask.vue → 学习会话(预期 + AI 草稿) │ ├── Review.vue → 复习总览 │ ├── ReviewDetail.vue → 复习详情(报告/残片 + 溯源) │ ├── ReviewRecall.vue → 回忆复习主页面 │ ├── TaskForm.vue → 任务编辑(Markdown 学习材料) │ ├── MindMapViewer.vue → 思维导图渲染/编辑/选择 │ ├── MarkdownRenderer.vue → Markdown 渲染 │ ├── MyHead.vue → 顶部导航 │ └── MyFooter.vue → 底部 ├── composables/ → 组合式函数 │ ├── fragment.ts → 残片管理 │ └── useTimer.ts → 计时器 ├── router/ → 路由配置 ├── utils/ → 工具函数 │ ├── request.ts → Axios 封装 │ └── fetchTitle.ts → 链接标题抓取 └── __tests__/ → 单元测试 ``` --- ## 路由表 | 路径 | 组件 | 说明 | |------|------|------| | `/login` | Login.vue | 登录页(无需认证) | | `/welcome` | Welcome.vue | 首页 | | `/study` | Study.vue | 学习任务列表 | | `/start-task/:taskNum` | StartTask.vue | 学习会话 | | `/add-task` | TaskForm.vue | 创建任务 | | `/update-task/:taskId` | TaskForm.vue | 更新任务 | | `/review` | Review.vue | 复习总览 | | `/review/detail/:type/:id` | ReviewDetail.vue | 复习详情 | | `/review/recall/:taskNum` | ReviewRecall.vue | 回忆复习 | --- ## 认证与请求 - axios `withCredentials: true`,Cookie `satoken` 自动携带 - 401 处理(HTTP 层 + 业务层双重检测):清 `localStorage.isLoggedIn` → `router.push("/login")` - `validateResponse`:`code !== 200` → reject - Vite 代理: `/api` → `http://localhost:5157`,自动重写去掉 `/api` 前缀 --- ## Markdown 学习材料 - 编辑:textarea 输入,支持 `[文字](url)` 和裸 URL - 预览:`renderMarkdown(raw)` 同步函数,使用占位符防止嵌套 HTML - 保存:`convertMaterialUrls()` 异步拉取标题,替换裸 URL 为 `[标题](url)` - `getUrlTitle(url)`:调 `/utils/fetch-title`,内存缓存 + 请求去重 --- ## 开发配置 - **开发端口**: 5158 - **代理**: `/api` → `http://localhost:5157` - **环境变量**: `.env.development` / `.env.production` / `.env.uat` --- ## 启动命令 ```bash npm install # 安装依赖 npm run dev # 启动开发服务器(端口 5158) npm run build # 生产构建 npm run test # 单元测试 npm run test:e2e # E2E 测试 npx vue-tsc --noEmit # 类型检查 ``` --- ## Docker - 多阶段构建:`node:20-alpine` 编译 → `nginx:alpine` 运行 - 暴露端口:80 - 构建参数:`BUILD_MODE`(默认 production) --- ## 关联项目 | 项目 | 路径 | 端口 | 说明 | |------|------|------|------| | lpt-be | `../lpt-be/` | 5157 | Spring Boot 后端,前端通过 `/api` 代理调用 | | lpt-ai | `../lpt-ai/` | 5199 | AI 服务,前端不直接调用 | ## 调用关系 ``` 浏览器 → lpt-fe (5158) ──/api──→ lpt-be (5157) ──HTTP──→ lpt-ai (5199) │ └── MySQL (8109) ```