diff --git a/.pi/SYSTEM.md b/.pi/SYSTEM.md new file mode 100644 index 0000000..c867c29 --- /dev/null +++ b/.pi/SYSTEM.md @@ -0,0 +1,121 @@ +# LPT 前端应用(lpt-fe) + +> Vue 3 + TypeScript + Vite 单页应用 + +--- + +## 技术栈 +- **框架**: 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) +```