CLAUDE.md 10.3 KB

CLAUDE.md

此文件为 Claude Code (claude.ai/code) 在此代码库中工作时提供指导。

项目概述

美乐爱觉 (mlaj) - 基于 Vue 3 的教育平台,深度集成微信生态,服务于教师和学生。

  • 框架: Vue 3 (Composition API + <script setup>)
  • 构建工具: Vite 6.2.0
  • 包管理器: pnpm (项目使用 .nvm 管理 Node.js 18.19.1)
  • UI 框架: Vant 4.9.22 (移动端优先)
  • 样式: TailwindCSS + Less (分层)
  • 状态管理: Context API (/src/contexts/) + localStorage
  • 路由: Vue Router 4.5.0,支持懒加载和路由守卫
  • HTTP: Axios 1.8.4,集中式拦截器

常用开发命令

核心开发

pnpm dev          # 启动开发服务器 (使用 Node.js 18.19.1)
pnpm build        # 生产环境构建
pnpm preview      # 本地预览生产构建
pnpm test         # 使用 Vitest 运行测试

部署

pnpm dev_upload    # 部署到开发服务器
pnpm behalo_upload # 部署到 behalo 环境
pnpm oa_upload     # 部署到 OA 服务器

开发流程

  • 每个部署命令都会:构建、归档(tar.gz)、通过 scp 上传、在服务器上解压、清理归档文件。

目录结构

src/
├── api/              # API 接口层 - 按领域模块化
│   ├── auth.js       # 认证相关接口
│   ├── course.js     # 课程相关接口
│   ├── teacher.js    # 教师端接口
│   └── ...
├── assets/           # 静态资源 (图片、CSS、模拟数据)
├── components/       # 可复用的 Vue 组件
│   ├── ui/           # 通用 UI 组件 (VideoPlayer, AudioPlayer, CheckInDialog 等)
│   ├── checkin/      # 打卡相关组件
│   ├── courses/      # 课程相关组件
│   └── studyDetail/  # 学习详情页组件
├── composables/      # Vue 组合式函数,用于逻辑复用 (useStudyComments, useStudyRecordTracker 等)
├── contexts/         # 全局状态提供者 (auth, cart)
├── common/           # 共享常量和工具
├── router/           # Vue Router 配置
│   ├── index.js      # 路由实例与守卫
│   ├── routes.js     # 路由定义(懒加载)
│   └── guards.js     # 认证守卫辅助函数
├── utils/            # 工具函数
│   ├── axios.js      # Axios 实例与拦截器 (认证头、401 处理)
│   ├── tools.js      # 通用工具 (wxInfo, 文件处理等)
│   └── auth_user_info.js  # 用户信息存储辅助函数
└── views/            # 页面组件,按功能组织
    ├── auth/         # 登录/认证页面
    ├── courses/      # 课程浏览、详情、购买
    ├── profile/      # 用户资料、设置、课程历史
    ├── recall/       # 提醒/回忆系统
    ├── study/        # 学习资料和内容
    └── teacher/      # 教师端仪表板、任务、班级管理

路径别名

vite.config.jsjsconfig.json 中配置:

  • @/src/
  • @components/src/components/
  • @composables/src/composables/
  • @utils/src/utils/
  • @api/src/api/
  • @images/src/assets/images/
  • @css/src/assets/css/
  • @mock/src/assets/mock/
  • common/src/common/
  • @root/ → 项目根目录

核心架构模式

API 接口层架构

位置: /src/api/

所有接口遵循统一的响应结构:

{
  code: 1,  // 1 = 成功,其他 = 失败
  data: any,  // 响应数据
  msg: string // 消息(成功时为空,失败时为错误信息)
}

重要: 检查成功时使用 if (res.code === 1) 而不是 if (res.code),避免将 401/403 误判为成功。

认证头 通过 axios 拦截器自动添加 (/src/utils/axios.js):

  • 每次请求读取 localStorage.user_info
  • 设置 User-IdUser-Token 请求头
  • 401 响应处理:仅当当前路由需要认证时才重定向到登录页 (见 guards.js 中的 checkAuth)

组件分层

视图页面 (/src/views/): 页面级组件,负责编排:

  • 通过 API 获取数据
  • 通过 refs/composables 管理状态
  • 路由和导航
  • 集成更小的组件

UI 组件 (/src/components/ui/): 可复用、无状态或自包含:

  • VideoPlayer, AudioPlayer, CheckInDialog, SharePoster, SearchBar 等
  • 应尽可能避免直接调用 API
  • 通过 emit 事件向父组件传递操作

组合式函数 (/src/composables/): 可复用逻辑:

  • useStudyComments: 评论获取、提交、分页
  • useStudyRecordTracker: 学习时长追踪和分析
  • useCheckin: 打卡流程和提交
  • 返回响应式 refs 和函数,内部处理副作用

路由与认证

路由 使用懒加载进行代码分割:

{
  path: '/courses/:id',
  component: () => import('@/views/courses/CourseDetailPage.vue')
}

认证守卫 (/src/router/guards.js):

  • checkAuth(route) - 返回 true 或重定向对象
  • 不再自动触发微信认证;仅通过登录页手动触发
  • 路由可标记 meta: { requireAuth: false } 以公开访问

样式策略

TailwindCSS 是主要样式方案:

  • 用于布局、间距、排版、颜色
  • 自定义颜色定义在 tailwind.config.js 中 (primary: #4caf50)

Less 用于组件特定样式:

  • 组件边界内的嵌套选择器
  • 使用 <style lang="less" scoped> 限制作用域到组件
  • 使用 :deep() 修改 Vant/VideoJS 内部样式

自动导入:

  • Vant 组件自动导入(无需手动导入)
  • Vue 组合式函数自动导入 (ref, computed, onMounted 等)

状态管理模式

用户认证状态:

  • 运行时: contexts/auth.jscurrentUser ref
  • 持久化: localStorage.currentUserlocalStorage.user_info
  • Axios 请求头: 从 localStorage 派生(在拦截器中)
  • 辅助函数: getUserInfoFromStorage(), removeUserInfoFromStorage()

购物车/订单状态:

  • 运行时: contexts/cart.js
  • 通过 provide/inject 在页面间保持

微信集成

微信 JS SDK 初始化在 App.vue 中:

  • 仅在浏览器环境中
  • 通过 wxInfo() 工具检测环境
  • wxInfo().isWeiXin - 在微信浏览器中运行
  • wxInfo().isPc - 在 PC 上运行

微信认证流程:

  1. 用户在登录页点击微信图标
  2. 重定向到微信 OAuth
  3. 回调 → getUserIsLoginAPI() → 写入用户信息到存储
  4. 重定向到原页面或首页

微信支付:

  • 集成在结账流程中
  • 生产环境: 需要微信浏览器环境 (wxInfo().isWeiXin)
  • 免费课程: 跳过环境验证

文件预览系统

PDF 预览:

  • 组件: @sunsetglow/vue-pdf-viewer
  • 专用路由: /pdfPreview 用于浏览器内预览

Office 文档 (Word, Excel, PPT):

  • @vue-office/docx, @vue-office/excel, @vue-office/pptx
  • 弹窗预览组件,带错误处理

图片:

  • 使用 Vant 的 van-image-preview

视频播放器:

  • 基于 @videojs-player/vue (Video.js 7.21.7 的封装)
  • 自定义 VideoPlayer.vue 组件添加错误处理、自动重试和播放速率控制

重要注意事项

视频播放器问题

VideoPlayer 使用 v-show vs v-if:

  • Video.js 在 v-show (display: none) 下无法正常工作
  • 使用 v-if 确保视频元素在初始化前完全挂载
  • 参考 StudyDetailPage.vue 中的正确模式:设置 isPlaying = true,然后 setTimeout 再调用 play()

401 响应处理

src/utils/axios.js 中的 axios 响应拦截器:

  • 仅当 checkAuth(to) 返回重定向时才跳转到登录页
  • 公开页面(如课程详情)即使在 401 时也保持当前页
  • 页面组件应为自己的用户操作处理 401

API 响应安全性

始终检查 res.code === 1(而不仅仅是 res.code):

// 正确
const { code, data } = await getCourseDetailAPI({ i: courseId })
if (code === 1) { ... }

// 错误 - 将 401/403 当作成功
if (code) { ... }

组件自动导入

Vant 组件通过 unplugin-vue-components 自动导入:

  • 不要导入 import { Button } from 'vant'
  • 直接使用 <van-button>
  • 参见 src/components.d.ts 查看所有可用组件

打卡系统

统一组件: CheckInDialog.vue 处理所有打卡流程:

  • 接收 items_todayitems_history props
  • 每项包含 id, name, task_type ('checkin'/'upload'), is_gray
  • 完成时触发 check-in-success 事件

可复用列表组件: CheckInList.vue

  • 用于首页和 CheckInDialog
  • 对话框使用紧凑模式,页面使用正常模式
  • submit-success 事件向上冒泡

环境配置

使用 .env.development, .env.production 等:

  • VITE_PORT - 开发服务器端口
  • VITE_BASE - 基础路径
  • VITE_PROXY_PREFIX - API 代理前缀
  • VITE_PROXY_TARGET - 后端 API 目标
  • VITE_OUTDIR - 构建输出目录

Speckit 框架命令

位于 .cursor/commands/:

  • /speckit.specify - 从需求生成规范
  • /speckit.plan - 创建实现计划
  • /speckit.tasks - 生成任务分解
  • /speckit.analyze - 跨文件一致性分析
  • /speckit.implement - 执行实现计划
  • /speckit.checklist - 验证检查清单
  • /speckit.clarify - 需求澄清
  • /speckit.constitution - 项目原则和约束

代码风格说明 (来自 VUE_CODE_STYLE_GUIDE.md)

当前实践:

  • 新组件使用 <script setup> 和 Composition API
  • API 函数应始终返回 { code, data, msg } - 永不返回 false
  • 尽可能将逻辑提取到 composables (/src/composables/useXxx.js)
  • 本地状态使用 refs,派生状态使用 computed
  • 除非必要避免 JSX;大多数页面使用 Vue 模板

已知不一致性 (需注意):

  • 文件中混合使用分号/无分号
  • 混合使用 2 空格/4 空格缩进
  • 混合使用 function/箭头函数
  • 混合使用中文/英文注释

特殊功能

分享海报生成

  • 基于 Canvas 的海报生成,带二维码 (qrcode 包)
  • 自动优化 cdn.ipadbiz.cn URL 的图片
  • 使用 crossorigin="anonymous" 处理跨域 Canvas 污染
  • 组件: SharePoster.vue (可复用)

动态 Open Graph 元标签

  • 课程详情页动态添加 og:title, og:description, og:image, og:url
  • 页面卸载时移除标签以避免冲突

标签指示器动画

  • 基于 ResizeObserver 的指示器定位
  • 处理异步加载第三列而不错位
  • 参考 StudyCoursePage.vue 的实现

测试

  • 测试运行器: Vitest
  • 命令: pnpm test
  • 测试文件位于 /test/ (当前可能测试覆盖较少)