hookehuyr

docs: 完善项目文档结构并更新内容指南

- 添加详细目录结构,便于快速导航
- 新增快速开始章节,包含环境准备和新手指南
- 扩展常用开发命令和目录结构说明
- 完善核心架构模式解释,补充组合式函数详情
- 新增常见问题与解决方案章节,涵盖Video.js、API调用、Vant组件等常见问题
- 更新功能更新记录,按时间分类整理
- 优化组件目录结构说明,增加文档索引
Showing 1 changed file with 218 additions and 62 deletions
...@@ -2,18 +2,74 @@ ...@@ -2,18 +2,74 @@
2 2
3 此文件为 Claude Code (claude.ai/code) 在此代码库中工作时提供指导。 3 此文件为 Claude Code (claude.ai/code) 在此代码库中工作时提供指导。
4 4
5 +## 目录
6 +
7 +- [项目概述](#项目概述) - 技术栈与基本信息
8 +- [快速开始](#快速开始) - 环境准备与新手指南
9 +- [常用开发命令](#常用开发命令) - 开发、测试、部署命令
10 +- [目录结构](#目录结构) - 项目文件组织
11 +- [路径别名](#路径别名) - 导入路径快捷方式
12 +- [核心架构模式](#核心架构模式) - API、组件、路由、样式、状态管理
13 +- [重要注意事项](#重要注意事项) - 常见陷阱与最佳实践
14 +- [业务系统架构](#业务系统架构) - 6大业务模块说明
15 +- [常见问题与解决方案](#常见问题与解决方案) - Q&A
16 +- [功能更新记录](#功能更新记录) - 最近变更历史
17 +- [文档索引](#文档索引) - 相关文档链接
18 +
5 ## 项目概述 19 ## 项目概述
6 20
7 **美乐爱觉 (mlaj)** - 基于 Vue 3 的教育平台,深度集成微信生态,服务于教师和学生。 21 **美乐爱觉 (mlaj)** - 基于 Vue 3 的教育平台,深度集成微信生态,服务于教师和学生。
8 22
9 -- **框架**: Vue 3 (Composition API + `<script setup>`) 23 +- **框架**: Vue 3.5.13 (Composition API + `<script setup>`)
10 - **构建工具**: Vite 6.2.0 24 - **构建工具**: Vite 6.2.0
11 - **包管理器**: pnpm (项目使用 `.nvm` 管理 Node.js 18.19.1) 25 - **包管理器**: pnpm (项目使用 `.nvm` 管理 Node.js 18.19.1)
12 -- **UI 框架**: Vant 4.9.22 (移动端优先) 26 +- **UI 框架**: Vant 4.9.22 (移动端优先,组件自动导入)
13 -- **样式**: TailwindCSS + Less (分层) 27 +- **样式**: TailwindCSS 3.4.1 + Less 4.2.2 (分层架构)
14 - **状态管理**: Context API (`/src/contexts/`) + localStorage 28 - **状态管理**: Context API (`/src/contexts/`) + localStorage
15 - **路由**: Vue Router 4.5.0,支持懒加载和路由守卫 29 - **路由**: Vue Router 4.5.0,支持懒加载和路由守卫
16 - **HTTP**: Axios 1.8.4,集中式拦截器 30 - **HTTP**: Axios 1.8.4,集中式拦截器
31 +- **视频播放**: Video.js 7.21.7 (通过 `@videojs-player/vue` 封装)
32 +
33 +## 快速开始
34 +
35 +### 环境准备
36 +
37 +1. **Node.js 版本**: 使用 `.nvm` 管理 Node.js 18.19.1
38 + ```bash
39 + nvm use 18.19.1
40 + ```
41 +
42 +2. **安装依赖**:
43 + ```bash
44 + pnpm install
45 + ```
46 +
47 +3. **启动开发服务器**:
48 + ```bash
49 + pnpm dev
50 + ```
51 +
52 +### 新手指南
53 +
54 +**添加新页面**:
55 +1. 在 `/src/views/` 相应模块下创建页面组件
56 +2. 在 `/src/router/` 对应路由文件中注册路由
57 +3. 如需认证,在路由 `meta` 中添加 `requiresAuth: true`
58 +
59 +**调用 API**:
60 +1. 在 `/src/api/` 对应模块中定义 API 函数
61 +2. 遵循统一返回结构:`{ code: 1, data: any, msg: string }`
62 +3. 使用 `if (res.code === 1)` 检查成功(而非 `if (res.code)`
63 +
64 +**创建可复用组件**:
65 +1. 放置在 `/src/components/ui/`(通用)或相应业务目录
66 +2. 使用 `defineProps``defineEmits` 定义接口
67 +3. 通过 emit 事件向父组件传递操作,避免直接调用 API
68 +
69 +**提取逻辑到 Composable**:
70 +1. 在 `/src/composables/` 创建 `useXxx.js`
71 +2. 返回响应式 refs 和函数
72 +3. 内部处理副作用(API 调用、事件监听等)
17 73
18 ## 常用开发命令 74 ## 常用开发命令
19 75
...@@ -39,10 +95,12 @@ pnpm oa_upload # 部署到 OA 服务器 ...@@ -39,10 +95,12 @@ pnpm oa_upload # 部署到 OA 服务器
39 95
40 ``` 96 ```
41 src/ 97 src/
42 -├── api/ # API 接口层 - 按领域模块化 98 +├── api/ # API 接口层 - 15个模块,按领域组织
43 │ ├── auth.js # 认证相关接口 99 │ ├── auth.js # 认证相关接口
100 +│ ├── checkin.js # 打卡/作业接口
44 │ ├── course.js # 课程相关接口 101 │ ├── course.js # 课程相关接口
45 │ ├── teacher.js # 教师端接口 102 │ ├── teacher.js # 教师端接口
103 +│ ├── recall_users.js # 召回系统接口
46 │ └── ... 104 │ └── ...
47 ├── assets/ # 静态资源 (图片、CSS、模拟数据) 105 ├── assets/ # 静态资源 (图片、CSS、模拟数据)
48 ├── components/ # 可复用的 Vue 组件 106 ├── components/ # 可复用的 Vue 组件
...@@ -50,7 +108,13 @@ src/ ...@@ -50,7 +108,13 @@ src/
50 │ ├── checkin/ # 打卡相关组件 108 │ ├── checkin/ # 打卡相关组件
51 │ ├── courses/ # 课程相关组件 109 │ ├── courses/ # 课程相关组件
52 │ └── studyDetail/ # 学习详情页组件 110 │ └── studyDetail/ # 学习详情页组件
53 -├── composables/ # Vue 组合式函数,用于逻辑复用 (useStudyComments, useStudyRecordTracker 等) 111 +├── composables/ # 13个组合式函数,用于逻辑复用
112 +│ ├── useAuth.js # 认证相关逻辑
113 +│ ├── useCheckin.js # 打卡流程与提交
114 +│ ├── useCheckinDraft.js # 打卡草稿缓存
115 +│ ├── useStudyComments.js # 评论获取、提交、分页
116 +│ ├── useStudyRecordTracker.js # 学习时长追踪和分析
117 +│ └── ...
54 ├── contexts/ # 全局状态提供者 (auth, cart) 118 ├── contexts/ # 全局状态提供者 (auth, cart)
55 ├── common/ # 共享常量和工具 119 ├── common/ # 共享常量和工具
56 ├── router/ # Vue Router 配置 120 ├── router/ # Vue Router 配置
...@@ -120,9 +184,11 @@ src/ ...@@ -120,9 +184,11 @@ src/
120 - 通过 emit 事件向父组件传递操作 184 - 通过 emit 事件向父组件传递操作
121 185
122 **组合式函数** (`/src/composables/`): 可复用逻辑: 186 **组合式函数** (`/src/composables/`): 可复用逻辑:
187 +- `useAuth`: 认证状态管理与登录流程
188 +- `useCheckin`: 打卡流程和提交(七牛上传、校验、提交)
189 +- `useCheckinDraft`: 打卡草稿自动缓存(防止数据丢失)
123 - `useStudyComments`: 评论获取、提交、分页 190 - `useStudyComments`: 评论获取、提交、分页
124 - `useStudyRecordTracker`: 学习时长追踪和分析 191 - `useStudyRecordTracker`: 学习时长追踪和分析
125 -- `useCheckin`: 打卡流程和提交
126 - 返回响应式 refs 和函数,内部处理副作用 192 - 返回响应式 refs 和函数,内部处理副作用
127 193
128 ### 路由与认证 194 ### 路由与认证
...@@ -240,6 +306,17 @@ Vant 组件通过 `unplugin-vue-components` 自动导入: ...@@ -240,6 +306,17 @@ Vant 组件通过 `unplugin-vue-components` 自动导入:
240 306
241 ### 打卡系统 307 ### 打卡系统
242 308
309 +**核心 composable**: `useCheckin.js` 封装打卡流程:
310 +- 文件上传:七牛云 + Hash 秒传(避免重复上传)
311 +- 支持类型:文本、图片、视频、音频、计数打卡
312 +- 数据校验:文件大小、数量、类型验证
313 +- 提交流程:新增/编辑统一处理
314 +
315 +**草稿缓存**: `useCheckinDraft.js` 防止数据丢失:
316 +- 自动保存:输入内容实时缓存到 localStorage
317 +- 智能恢复:页面加载时自动填充上次未提交的内容
318 +- 清理机制:提交成功或手动清除时移除草稿
319 +
243 **统一组件**: `CheckInDialog.vue` 处理所有打卡流程: 320 **统一组件**: `CheckInDialog.vue` 处理所有打卡流程:
244 - 接收 `items_today` 和 `items_history` props 321 - 接收 `items_today` 和 `items_history` props
245 - 每项包含 `id`, `name`, `task_type` ('checkin'/'upload'), `is_gray` 322 - 每项包含 `id`, `name`, `task_type` ('checkin'/'upload'), `is_gray`
...@@ -259,6 +336,12 @@ Vant 组件通过 `unplugin-vue-components` 自动导入: ...@@ -259,6 +336,12 @@ Vant 组件通过 `unplugin-vue-components` 自动导入:
259 - `VITE_PROXY_TARGET` - 后端 API 目标 336 - `VITE_PROXY_TARGET` - 后端 API 目标
260 - `VITE_OUTDIR` - 构建输出目录 337 - `VITE_OUTDIR` - 构建输出目录
261 338
339 +**环境与部署**:
340 +- **开发环境**: `http://oa-dev.onwall.cn/`
341 +- **生产环境**: `http://oa.onwall.cn`
342 +- **部署流程**: 构建 → 归档(tar.gz) → SCP 上传 → 服务器解压 → 清理归档
343 +- **代码分割**: 手动配置 chunks,Office 工具和图片工具单独打包
344 +
262 ### Speckit 框架命令 345 ### Speckit 框架命令
263 346
264 位于 `.cursor/commands/`: 347 位于 `.cursor/commands/`:
...@@ -285,6 +368,14 @@ Vant 组件通过 `unplugin-vue-components` 自动导入: ...@@ -285,6 +368,14 @@ Vant 组件通过 `unplugin-vue-components` 自动导入:
285 - 混合使用 2 空格/4 空格缩进 368 - 混合使用 2 空格/4 空格缩进
286 - 混合使用 function/箭头函数 369 - 混合使用 function/箭头函数
287 - 混合使用中文/英文注释 370 - 混合使用中文/英文注释
371 +- API 返回值语义不一致(部分返回 `false` 而非标准结构)
372 +- 部分页面组件过大,应考虑拆分
373 +
374 +**改进建议**:
375 +- 统一使用 ESLint + Prettier 进行代码格式化
376 +- 制定统一的 API 返回值规范
377 +- 大型页面组件应拆分为多个子组件
378 +- 增加单元测试覆盖(当前测试文件较少)
288 379
289 ## 特殊功能 380 ## 特殊功能
290 381
...@@ -395,54 +486,102 @@ Vant 组件通过 `unplugin-vue-components` 自动导入: ...@@ -395,54 +486,102 @@ Vant 组件通过 `unplugin-vue-components` 自动导入:
395 - `checkAuth`:基于白名单或 `meta.requiresAuth` 拦截未登录访问。 486 - `checkAuth`:基于白名单或 `meta.requiresAuth` 拦截未登录访问。
396 - `startWxAuth`:按需触发微信授权流程(非自动触发,避免死循环)。 487 - `startWxAuth`:按需触发微信授权流程(非自动触发,避免死循环)。
397 488
398 -## 目录结构说明 489 +## 常见问题与解决方案
490 +
491 +### Q: 为什么 Video.js 在切换显示/隐藏时无法正常工作?
492 +
493 +**A**: Video.js 在 `v-show` (display: none) 状态下初始化会失败。
494 +- **解决**: 使用 `v-if` 而非 `v-show`
495 +- **正确模式**: 设置 `isPlaying = true`,然后 `setTimeout` 再调用 `play()`
496 +- **参考**: `StudyDetailPage.vue` 中的实现
497 +
498 +### Q: 为什么我的 401 响应导致页面跳转到登录页?
499 +
500 +**A**: 这是预期的行为,但仅对需要认证的页面生效。
501 +- 公开页面(如课程详情)不会跳转
502 +- 受限页面会清理登录信息并重定向
503 +- 如需自定义处理,在组件内监听 API 错误
504 +
505 +### Q: 如何正确检查 API 响应是否成功?
399 506
507 +**A**: 始终使用 `if (res.code === 1)` 而非 `if (res.code)`。
508 +```javascript
509 +// ✓ 正确
510 +const { code, data } = await getCourseDetailAPI({ i: courseId })
511 +if (code === 1) { /* 成功 */ }
512 +
513 +// ✗ 错误 - 会将 401/403 当作成功
514 +if (code) { /* ... */ }
400 ``` 515 ```
401 -src/ 516 +
402 -├── api/ # API 接口层 517 +### Q: 为什么 Vant 组件导入后报错或无法使用?
403 -│ ├── auth.js # 认证 518 +
404 -│ ├── checkin.js # 打卡/作业 519 +**A**: Vant 组件已配置自动导入,无需手动导入。
405 -│ ├── course.js # 课程 520 +```javascript
406 -│ ├── teacher.js # 教师端 521 +// ✗ 错误
407 -│ ├── recall_users.js # 召回系统 522 +import { Button } from 'vant'
408 -│ └── ... 523 +
409 -├── components/ # UI 组件 524 +// ✓ 正确
410 -│ ├── ui/ # 通用组件 (VideoPlayer, CheckInDialog, SearchBar) 525 +// 直接使用 <van-button>,无需导入
411 -│ ├── checkin/ # 打卡业务组件 526 +```
412 -│ ├── teacher/ # 教师端组件 527 +
413 -│ └── ... 528 +### Q: 如何在微信环境下正确处理支付和授权?
414 -├── composables/ # 逻辑复用 (useCheckin, useAuth, useStudyRecordTracker) 529 +
415 -├── contexts/ # 全局状态 (auth, cart) 530 +**A**: 使用 `wxInfo()` 工具函数检测环境:
416 -├── router/ # 路由配置 531 +```javascript
417 -│ ├── checkin.js # 打卡路由 532 +import { wxInfo } from '@/utils/tools'
418 -│ ├── teacher.js # 教师路由 533 +
419 -│ └── ... 534 +// 检测微信环境
420 -├── views/ # 页面视图 535 +if (wxInfo().isWeiXin) {
421 -│ ├── auth/ # 登录/注册 536 + // 微信浏览器
422 -│ ├── checkin/ # 打卡相关页面 (Index, Detail, Upload) 537 +} else {
423 -│ ├── courses/ # 课程相关页面 538 + // 其他浏览器
424 -│ ├── teacher/ # 教师端页面 (Task, Student, Class) 539 +}
425 -│ ├── recall/ # 召回系统页面 540 +```
426 -│ ├── profile/ # 个人中心 541 +
427 -│ └── ... 542 +### Q: 打卡时如何避免数据丢失?
428 -└── ... 543 +
544 +**A**: 使用 `useCheckinDraft` 自动缓存草稿:
545 +```javascript
546 +import { useCheckinDraft } from '@/composables/useCheckinDraft'
547 +
548 +const { saveDraft, loadDraft, clearDraft } = useCheckinDraft()
549 +
550 +// 输入时自动保存
551 +onMounted(() => loadDraft())
552 +watch(inputValue, () => saveDraft(inputValue.value))
553 +
554 +// 提交成功后清除
555 +onSubmitSuccess(() => clearDraft())
429 ``` 556 ```
430 557
431 ## 功能更新记录 (Recent Changes) 558 ## 功能更新记录 (Recent Changes)
432 559
433 -- **打卡详情页重构 (`/checkin/detail`)** 560 +### 最近重要更新
434 - - 统一了文本、媒体上传和计数打卡的入口。 561 +
435 - - 实现了基于 `useCheckin` 的通用提交流程。 562 +**打卡系统增强** (2025):
436 - - 优化了附件预览和编辑回填逻辑。 563 +- 打卡详情页重构 (`/checkin/detail`):统一文本、媒体上传和计数打卡入口
564 +- 新增草稿缓存功能 (`useCheckinDraft`):防止数据丢失,自动保存和恢复
565 +- 优化附件预览和编辑回填逻辑
566 +- 实现基于 `useCheckin` 的通用提交流程
567 +
568 +**教师端完善** (2025):
569 +- 作业管理页面 (`/teacher/tasks`)
570 +- 作业主页 (`/teacher/tasks/:id`):统计与日历视图
571 +- 学员作业记录页面 (`/teacher/student-record`)
437 572
438 -- **教师端功能完善** 573 +**召回系统** (2025):
439 - - 新增作业管理、作业主页(统计与日历视图)、学员作业记录页面。 574 +- 身份证查询历史功能
440 -- **基础体验优化** 575 +- 时光机旅程 (Timeline) 展示用户里程碑
441 - - 登录逻辑调整:仅在点击微信图标时触发授权。 576 +- 专属海报生成与分享
442 - - 搜索栏优化:支持 iOS 软键盘搜索键。
443 - - 课程详情页:增加动态 Open Graph 标签,优化分享体验。
444 577
445 -功能更新记录 578 +**基础体验优化** (2025):
579 +- 登录逻辑调整:仅在点击微信图标时触发授权
580 +- 搜索栏优化:支持 iOS 软键盘搜索键
581 +- 课程详情页:动态 Open Graph 标签,优化分享体验
582 +- 401 拦截策略优化:公开页面不再跳转登录页
583 +
584 +### 历史功能更新 (详细记录)
446 585
447 - 教师端新增作业管理页面:路径 `/teacher/tasks`,标题“作业管理”。 586 - 教师端新增作业管理页面:路径 `/teacher/tasks`,标题“作业管理”。
448 - 列表展示:作业名称、开始时间、截止时间。 587 - 列表展示:作业名称、开始时间、截止时间。
...@@ -569,21 +708,38 @@ src/ ...@@ -569,21 +708,38 @@ src/
569 - 预览能力: 708 - 预览能力:
570 - 上传组件点击预览时,根据扩展名识别:音频使用 `AudioPlayer` 底部弹窗;视频使用 `VideoPlayer` 居中弹窗(封面 → 点击播放 → 关闭时重置进度);图片使用 `van-image-preview` 709 - 上传组件点击预览时,根据扩展名识别:音频使用 `AudioPlayer` 底部弹窗;视频使用 `VideoPlayer` 居中弹窗(封面 → 点击播放 → 关闭时重置进度);图片使用 `van-image-preview`
571 710
572 -## /src/components 目录下组件 711 +## /src/components 目录结构
573 - 712 +
574 -| 目标目录(src/components/) | 包含组件 | 说明 | 713 +项目包含 **12个主要组件目录**,涵盖了从基础 UI 到业务功能的完整组件体系:
575 -| --------------------------- | ------------------------------------------------------------ | ---------------- | 714 +
576 -| `checkin/` | `CheckInDialog.vue`, `CheckInList.vue`, `CheckInResult.vue` | 打卡相关组件 | 715 +| 目录 | 组件示例 | 说明 |
577 -| `media/` | `AudioPlayer.vue`, `VideoPlayer.vue`, `MusicPlayer.vue` | 音视频播放组件 | 716 +|------|---------|------|
578 -| `activity/` | `ActivityApplyHistoryPopup.vue`, `ActivityCard.vue`, `ActivityStatusBadge.vue`, `ActivityTicket.vue` | 活动相关组件 | 717 +| `ui/` | `VideoPlayer`, `AudioPlayer`, `CheckInDialog`, `SharePoster`, `SearchBar` | 通用 UI 组件库 |
579 -| `common/` | `ConfirmDialog.vue`, `GradientHeader.vue`, `MenuItem.vue`, `SearchBar.vue`, `TermsPopup.vue`, `UserAgreement.vue` | 通用基础组件 | 718 +| `checkin/` | `CheckInDialog`, `CheckInList`, `CheckInResult` | 打卡业务组件 |
580 -| `effects/` | `FrostedGlass.vue`, `LoadingSpinner.vue` | 视觉特效组件 | 719 +| `media/` | `AudioPlayer`, `VideoPlayer`, `MusicPlayer` | 音视频播放组件 |
581 -| `courses/` | `CourseCard.vue`, `LiveStreamCard.vue` | 课程展示组件 | 720 +| `activity/` | `ActivityCard`, `ActivityTicket`, `ActivityStatusBadge` | 活动相关组件 |
582 -| `payment/` | `WechatPayment.vue` | 支付组件 | 721 +| `common/` | `ConfirmDialog`, `GradientHeader`, `MenuItem` | 通用基础组件 |
583 -| `studyDetail/` | `StudyMaterialsPopup.vue` | 学习资料弹窗 | 722 +| `effects/` | `FrostedGlass`, `LoadingSpinner` | 视觉特效组件 |
584 -| `layout/` | `AppLayout.vue`, `BottomNav.vue` | 布局与导航 | 723 +| `courses/` | `CourseCard`, `LiveStreamCard` | 课程展示组件 |
585 -| `share/` | `SharePoster.vue` | 分享海报 | 724 +| `payment/` | `WechatPayment` | 支付组件 |
586 -| `files/` | `FilePreview.vue` | 文件预览 | 725 +| `studyDetail/` | `StudyMaterialsPopup` | 学习资料弹窗 |
587 -| `feedback/` | `FeedbackForm.vue` | 反馈表单 | 726 +| `layout/` | `AppLayout`, `BottomNav` | 布局与导航 |
727 +| `share/` | `SharePoster` | 分享海报 |
728 +| `files/` | `FilePreview` | 文件预览 |
729 +| `feedback/` | `FeedbackForm` | 反馈表单 |
730 +| `teacher/` | 教师端专用组件 | 教师业务组件 |
731 +
732 +---
733 +
734 +## 文档索引
735 +
736 +项目包含以下文档,帮助理解不同方面:
737 +
738 +- **CLAUDE.md** (本文档) - 项目总体架构与开发指南
739 +- **VUE_CODE_STYLE_GUIDE.md** - Vue 代码风格规范与最佳实践
740 +- **CHANGELOG.md** - 变更日志记录
741 +- **package.json** - 依赖与脚本配置
742 +- **vite.config.js** - 构建工具配置
743 +- **tailwind.config.js** - 样式系统配置
588 744
589 --- 745 ---
......