docs: 新增项目文档并重构README结构
将原README中的详细内容拆分为多个文档,提升可维护性 - 新增docs/COMPONENTS.md:组件目录索引 - 新增docs/CHANGELOG.md:功能更新记录 - 新增docs/ARCHITECTURE.md:架构实现与工程配置 - 重构README.md为项目概览与快速索引
Showing
4 changed files
with
234 additions
and
213 deletions
| 1 | -美乐爱觉项目 | 1 | +# 美乐爱觉项目(mlaj) |
| 2 | 2 | ||
| 3 | -测试环境网站 | 3 | +测试环境网站:<https://oa-dev.onwall.cn/f/mlaj> |
| 4 | -https://oa-dev.onwall.cn/f/mlaj | 4 | + |
| 5 | +## 项目概览 | ||
| 6 | + | ||
| 7 | +本项目是面向移动端(以微信内置浏览器为主)的教育业务 H5,覆盖「用户登录/微信授权 → 课程浏览/购买 → 学习与内容预览 → 打卡作业(学生端/教师端)→ 活动报名 → 召回促活 → 积分/订单」等完整链路。 | ||
| 8 | + | ||
| 9 | +## 技术栈 | ||
| 10 | + | ||
| 11 | +- Vue 3 + Vite 6(Hash 路由) | ||
| 12 | +- UI:Vant 4 + TailwindCSS 3 + Less(Tailwind 负责布局,Less 做补充) | ||
| 13 | +- 路由:Vue Router 4(带全局守卫与白名单/Meta 双策略鉴权) | ||
| 14 | +- 请求:Axios(统一注入认证头、统一 401 策略) | ||
| 15 | +- 测试:Vitest(已有 composables/utils 单测) | ||
| 16 | +- 微信生态:weixin-js-sdk、OAuth/OpenID 登录态探测与手动触发授权、微信支付 | ||
| 17 | +- 媒体与文档:Video.js、PDF/Office 预览组件 | ||
| 18 | + | ||
| 19 | +## 项目结构(快速索引) | ||
| 20 | + | ||
| 21 | +``` | ||
| 22 | +src/ | ||
| 23 | +├── api/ # 按业务域拆分的接口封装(auth/course/checkin/teacher/...) | ||
| 24 | +├── components/ # 组件(按业务域归类) | ||
| 25 | +├── composables/ # 组合式函数(逻辑复用,含单测) | ||
| 26 | +├── contexts/ # 全局状态(provide/inject:auth/cart) | ||
| 27 | +├── router/ # 路由定义与守卫 | ||
| 28 | +├── utils/ # 工具层(axios、上传、鉴权存储、版本更新等) | ||
| 29 | +└── views/ # 页面(按业务域归类) | ||
| 30 | +``` | ||
| 31 | + | ||
| 32 | +## 可复用能力清单 | ||
| 33 | + | ||
| 34 | +- 认证与登录态:[/src/contexts/auth.js](file:///Users/huyirui/program/itomix/git/mlaj/src/contexts/auth.js) | ||
| 35 | +- 购物车:[/src/contexts/cart.js](file:///Users/huyirui/program/itomix/git/mlaj/src/contexts/cart.js) | ||
| 36 | +- Axios 统一策略:[/src/utils/axios.js](file:///Users/huyirui/program/itomix/git/mlaj/src/utils/axios.js) | ||
| 37 | +- 微信能力封装:[/src/router/guards.js](file:///Users/huyirui/program/itomix/git/mlaj/src/router/guards.js)、[/src/api/wx](file:///Users/huyirui/program/itomix/git/mlaj/src/api/wx) | ||
| 38 | +- 上传与文件处理:[/src/utils/upload.js](file:///Users/huyirui/program/itomix/git/mlaj/src/utils/upload.js)、[/src/utils/qiniuFileHash.js](file:///Users/huyirui/program/itomix/git/mlaj/src/utils/qiniuFileHash.js) | ||
| 39 | +- 内容预览组件:[/src/components/media](file:///Users/huyirui/program/itomix/git/mlaj/src/components/media) | ||
| 40 | +- 滚动/播放/图片容错等组合式函数:[/src/composables](file:///Users/huyirui/program/itomix/git/mlaj/src/composables) | ||
| 41 | +- 版本更新提示:[/src/utils/versionUpdater.js](file:///Users/huyirui/program/itomix/git/mlaj/src/utils/versionUpdater.js) | ||
| 42 | + | ||
| 43 | +## 项目优缺点(基于现状扫描) | ||
| 44 | + | ||
| 45 | +### 优点 | ||
| 46 | + | ||
| 47 | +- 业务域拆分清晰:api / views / components / composables 的分层直观 | ||
| 48 | +- 复用意识强:打卡、媒体预览、海报、鉴权与请求拦截均做了抽象 | ||
| 49 | +- 微信场景适配完整:授权、JSSDK、支付链路齐全,并避免路由守卫自动授权死循环 | ||
| 50 | +- 具备基础测试资产:composables/utils 已引入 Vitest 并有用例 | ||
| 51 | + | ||
| 52 | +### 缺点与风险 | ||
| 53 | + | ||
| 54 | +- 文档与代码存在不一致:README/CLAUDE 中的组件目录、路径描述与实际目录不一致 | ||
| 55 | +- 依赖与工程规范不够统一:同时存在 pnpm/yarn/npm 的 lock 文件,容易引起依赖漂移 | ||
| 56 | +- 构建产物体积偏大:存在 500kB 以上的 chunk(需要按路由/组件进一步拆分) | ||
| 57 | +- 状态来源较多:localStorage + contexts + axios 默认头并存,一致性风险偏高 | ||
| 58 | +- 全局屏蔽 warnHandler:[/src/main.js](file:///Users/huyirui/program/itomix/git/mlaj/src/main.js) 会吞掉 Vue 警告,可能掩盖潜在问题 | ||
| 59 | +- 目录存在历史遗留:[/src/layouts](file:///Users/huyirui/program/itomix/git/mlaj/src/layouts) 与 [/src/components/layout](file:///Users/huyirui/program/itomix/git/mlaj/src/components/layout) 并存,建议后续清理归一 | ||
| 60 | + | ||
| 61 | +## 文档索引 | ||
| 62 | + | ||
| 63 | +- 近期功能更新记录:[/docs/CHANGELOG.md](file:///Users/huyirui/program/itomix/git/mlaj/docs/CHANGELOG.md) | ||
| 64 | +- 架构实现与工程配置:[/docs/ARCHITECTURE.md](file:///Users/huyirui/program/itomix/git/mlaj/docs/ARCHITECTURE.md) | ||
| 65 | +- /src/components 组件目录索引:[/docs/COMPONENTS.md](file:///Users/huyirui/program/itomix/git/mlaj/docs/COMPONENTS.md) | ||
| 66 | +- 代码风格与最佳实践:[/VUE_CODE_STYLE_GUIDE.md](file:///Users/huyirui/program/itomix/git/mlaj/VUE_CODE_STYLE_GUIDE.md) | ||
| 67 | +- 已知问题与改进建议:[/ISSUES_TO_FIX.md](file:///Users/huyirui/program/itomix/git/mlaj/ISSUES_TO_FIX.md) | ||
| 68 | +- 协作说明(较长):[/CLAUDE.md](file:///Users/huyirui/program/itomix/git/mlaj/CLAUDE.md) | ||
| 5 | 69 | ||
| 6 | ## 业务系统架构 | 70 | ## 业务系统架构 |
| 7 | 71 | ||
| ... | @@ -62,222 +126,16 @@ https://oa-dev.onwall.cn/f/mlaj | ... | @@ -62,222 +126,16 @@ https://oa-dev.onwall.cn/f/mlaj |
| 62 | - **订单**:查看订单状态(待支付/已支付/退款),支持取消订单。 | 126 | - **订单**:查看订单状态(待支付/已支付/退款),支持取消订单。 |
| 63 | - **积分**:查看积分余额与变动明细,积分可用于抵扣或兑换(视具体业务规则)。 | 127 | - **积分**:查看积分余额与变动明细,积分可用于抵扣或兑换(视具体业务规则)。 |
| 64 | 128 | ||
| 65 | -## 核心技术栈与实现 | 129 | +## 架构实现与工程配置 |
| 66 | - | ||
| 67 | -### 状态管理 | ||
| 68 | - | ||
| 69 | -- **Context API**:项目主要使用 Vue 3 `provide/inject` 模式进行全局状态管理。 | ||
| 70 | - - `auth.js`:用户认证、登录态、Token 管理。 | ||
| 71 | - - `cart.js`:购物车逻辑、商品增删改、结算流程。 | ||
| 72 | -- **持久化**:关键状态同步至 `localStorage`,页面刷新不丢失。 | ||
| 73 | - | ||
| 74 | -### 文件处理 | ||
| 75 | 130 | ||
| 76 | -- **七牛云上传**: | 131 | +实现细节(登录态注入、401 策略、微信授权、上传/预览、Vite 代理与环境变量等)已迁移到:[/docs/ARCHITECTURE.md](file:///Users/huyirui/program/itomix/git/mlaj/docs/ARCHITECTURE.md) |
| 77 | - - 前端计算文件 Hash (`browser-md5-file` / `qiniuFileHash`)。 | ||
| 78 | - - 申请上传 Token(支持 Hash 秒传检测)。 | ||
| 79 | - - 直传七牛云对象存储。 | ||
| 80 | - - 回填业务服务器保存元数据。 | ||
| 81 | -- **文档预览**: | ||
| 82 | - - PDF: `@sunsetglow/vue-pdf-viewer` | ||
| 83 | - - Office: `@vue-office/docx`, `@vue-office/excel`, `@vue-office/pptx` | ||
| 84 | - - Video: `@videojs-player/vue` (Video.js 7.x) | ||
| 85 | - | ||
| 86 | -### 路由与权限 | ||
| 87 | - | ||
| 88 | -- **路由守卫** (`guards.js`): | ||
| 89 | - - `checkAuth`:基于白名单或 `meta.requiresAuth` 拦截未登录访问。 | ||
| 90 | - - `startWxAuth`:按需触发微信授权流程(非自动触发,避免死循环)。 | ||
| 91 | - | ||
| 92 | -## 目录结构说明 | ||
| 93 | - | ||
| 94 | -``` | ||
| 95 | -src/ | ||
| 96 | -├── api/ # API 接口层 | ||
| 97 | -│ ├── auth.js # 认证 | ||
| 98 | -│ ├── checkin.js # 打卡/作业 | ||
| 99 | -│ ├── course.js # 课程 | ||
| 100 | -│ ├── teacher.js # 教师端 | ||
| 101 | -│ ├── recall_users.js # 召回系统 | ||
| 102 | -│ └── ... | ||
| 103 | -├── components/ # UI 组件 | ||
| 104 | -│ ├── ui/ # 通用组件 (VideoPlayer, CheckInDialog, SearchBar) | ||
| 105 | -│ ├── checkin/ # 打卡业务组件 | ||
| 106 | -│ ├── teacher/ # 教师端组件 | ||
| 107 | -│ └── ... | ||
| 108 | -├── composables/ # 逻辑复用 (useCheckin, useAuth, useStudyRecordTracker) | ||
| 109 | -├── contexts/ # 全局状态 (auth, cart) | ||
| 110 | -├── router/ # 路由配置 | ||
| 111 | -│ ├── checkin.js # 打卡路由 | ||
| 112 | -│ ├── teacher.js # 教师路由 | ||
| 113 | -│ └── ... | ||
| 114 | -├── views/ # 页面视图 | ||
| 115 | -│ ├── auth/ # 登录/注册 | ||
| 116 | -│ ├── checkin/ # 打卡相关页面 (Index, Detail, Upload) | ||
| 117 | -│ ├── courses/ # 课程相关页面 | ||
| 118 | -│ ├── teacher/ # 教师端页面 (Task, Student, Class) | ||
| 119 | -│ ├── recall/ # 召回系统页面 | ||
| 120 | -│ ├── profile/ # 个人中心 | ||
| 121 | -│ └── ... | ||
| 122 | -└── ... | ||
| 123 | -``` | ||
| 124 | 132 | ||
| 125 | ## 功能更新记录 (Recent Changes) | 133 | ## 功能更新记录 (Recent Changes) |
| 126 | 134 | ||
| 127 | -- **打卡详情页重构 (`/checkin/detail`)**: | 135 | +详细记录已迁移到:[/docs/CHANGELOG.md](file:///Users/huyirui/program/itomix/git/mlaj/docs/CHANGELOG.md) |
| 128 | - - 统一了文本、媒体上传和计数打卡的入口。 | ||
| 129 | - - 实现了基于 `useCheckin` 的通用提交流程。 | ||
| 130 | - - 优化了附件预览和编辑回填逻辑。 | ||
| 131 | - | ||
| 132 | -- **教师端功能完善**: | ||
| 133 | - - 新增作业管理、作业主页(统计与日历视图)、学员作业记录页面。 | ||
| 134 | -- **基础体验优化**: | ||
| 135 | - - 登录逻辑调整:仅在点击微信图标时触发授权。 | ||
| 136 | - - 搜索栏优化:支持 iOS 软键盘搜索键。 | ||
| 137 | - - 课程详情页:增加动态 Open Graph 标签,优化分享体验。 | ||
| 138 | - | ||
| 139 | -功能更新记录 | ||
| 140 | - | ||
| 141 | -- 教师端新增作业管理页面:路径 `/teacher/tasks`,标题“作业管理”。 | ||
| 142 | - - 列表展示:作业名称、开始时间、截止时间。 | ||
| 143 | - - 当前数据来源为Mock,后续可替换为真实接口数据。 | ||
| 144 | -- 教师端新增作业主页:路径 `/teacher/tasks/:id`,标题“作业主页”。 | ||
| 145 | - - 头部:作业名称、介绍文案、细项信息(周期、频次、时间段、附件类型)。 | ||
| 146 | - - 统计:出勤率与任务完成率(参考 `myClassPage.vue` 统计样式,数据Mock)。 | ||
| 147 | - - 日历:使用 `van-calendar` 单选模式,选择日期后展示当日学生完成情况。 | ||
| 148 | - - 学生完成情况:参考图片2样式,勾选代表已完成,未勾选代表未完成(数据Mock)。 | ||
| 149 | -- 教师端新增学员作业记录页面:路径 `/teacher/student-record`,标题“学员作业记录”。 | ||
| 150 | - - 在作业主页的学生列表点击卡片可跳转至该页面(当前版本为固定示例页面)。 | ||
| 151 | - - 列表展示:作业帖子、图片/视频/音频、点赞与点评弹窗(与 `studentPage.vue` 的作业记录样式一致)。 | ||
| 152 | - - 接口参数固定:`user_id=817017`,`group_id=816653`(后续可替换为动态参数)。 | ||
| 153 | -- 学习详情页标签指示条修复:`/src/views/profile/StudyCoursePage.vue` | ||
| 154 | - - 现象:首次进入且存在“打卡互动”时,底部绿色指示条定位错误。 | ||
| 155 | - - 修复:新增标签容器 `ref` 与 `ResizeObserver`,按栏目数量对容器进行等分,指示条宽度与位移按分段和索引计算,异步加载第三个栏目时不再错位。 | ||
| 156 | -- 登录逻辑调整:仅在登录页微信图标点击时触发授权 | ||
| 157 | - - 变更文件:`/src/views/auth/LoginPage.vue`、`/src/router/guards.js`、`/src/router/index.js` | ||
| 158 | - - 路由守卫:移除自动微信授权检查,新增 `startWxAuth` 供手动触发。 | ||
| 159 | - - 登录页:微信图标绑定点击事件,非微信环境提示“请在微信内打开”。 | ||
| 160 | - - 使用方式:进入登录页,点击微信图标进行授权登录。 | ||
| 161 | - | ||
| 162 | -- 课程详情页动态 Open Graph 元标签 | ||
| 163 | - - 行为:进入课程详情页时,在 `<head>` 中插入 4 个 `meta` 标签:`og:title`(课程 `title`)、`og:description`(课程 `subtitle`)、`og:image`(课程 `cover`)、`og:url`(当前页面 URL);这些 `meta` 必须插在 `<title>` 标签的前面;离开页面时移除。 | ||
| 164 | - - CDN 规则:若图片域名为 `cdn.ipadbiz.cn`,自动追加 `?imageMogr2/thumbnail/200x/strip/quality/70`。 | ||
| 165 | - - 位置:`/src/views/courses/CourseDetailPage.vue`,在 `onMounted` 插入,`onUnmounted` 清理。 | ||
| 166 | - - 函数:`build_og_image_url(src)`、`set_og_meta(payload)`、`remove_og_meta()`。 | ||
| 167 | - | ||
| 168 | -- 课程详情页咨询弹窗(Mock) | ||
| 169 | - - 入口:详情页顶部快捷操作中的“咨询”按钮。 | ||
| 170 | - - 展示:底部弹出层,仅底部关闭按钮;展示联系人列表,可点击名称或号码直接拨打(`tel:`)。 | ||
| 171 | - - 联系人:支持多个联系人,展示姓名与号码;电话号码使用绿色高亮;联系人与号码字体大小一致。 | ||
| 172 | - - 位置:`/src/views/courses/CourseDetailPage.vue`,“咨询弹窗”模板与交互逻辑(`open_consult_dialog`、`close_consult_dialog`、`consult_contacts`、`call_phone(phone)`)。 | ||
| 173 | - | ||
| 174 | -- 购买流程环境校验 | ||
| 175 | - - 行为:仅对非免费课程在详情页点击“购买”时进行校验;生产环境下必须为微信内置浏览器(`wxInfo().isWeiXin`)。 | ||
| 176 | - - 免费课程:跳过微信环境校验,允许直接进入结算流程。 | ||
| 177 | - - 非微信环境(付费课):提示“请在微信内打开进行购买”,不进入结算。 | ||
| 178 | - - 位置:`/src/views/courses/CourseDetailPage.vue` 的 `handlePurchase` 中,使用 `wxInfo` 进行环境判断。 | ||
| 179 | - | ||
| 180 | -- 微信授权自动触发(微信环境内) | ||
| 181 | - - 行为:在微信内置浏览器环境下点击“购买”时,若检测到未完成微信授权(`openid_has=false`),系统将自动发起一次微信授权流程并中止本次购买;授权完成后再次点击可进入结算。 | ||
| 182 | - - 开发环境:不触发微信授权流程(保留现有调试行为)。 | ||
| 183 | - - 位置:`/src/views/courses/CourseDetailPage.vue` 的 `handlePurchase` 中,调用 `getAuthInfoAPI()` 探测并使用 `startWxAuth()` 触发授权。 | ||
| 184 | - | ||
| 185 | -- 401拦截策略优化(公开页面不再跳登录) | ||
| 186 | - - 行为:接口返回 `code=401` 时,不再对公开页面(如课程详情 `/courses/:id`)进行登录重定向;仅当当前路由确实需要登录权限时才跳转至登录页。 | ||
| 187 | - - 原理:响应拦截器调用路由守卫 `checkAuth` 判断当前路由是否为受限页面,受限则清理登录信息并附带 `redirect` 重定向至登录页;公开页面保持当前页,由业务自行处理401。 | ||
| 188 | - - 位置:`/src/utils/axios.js`,在响应拦截器中按需处理重定向。 | ||
| 189 | -- 搜索栏回车搜索兼容性提升 | ||
| 190 | - - 行为:将输入框类型改为 `search`,并可选开启 `form @submit.prevent` 机制以提升 iOS 设备软键盘“搜索”键触发稳定性;同时保留 `@keyup.enter` 回车触发搜索。 | ||
| 191 | - - 路由行为: | ||
| 192 | - - 课程页(`isCoursePage=true`):回车或搜索键触发后跳转至 `/courses-list` 并携带 `keyword` 参数。 | ||
| 193 | - - 列表页:仅更新当前路由的查询参数 `keyword`。 | ||
| 194 | - - 位置:`/src/components/ui/SearchBar.vue`,新增 `useFormSubmit` 可选参数(默认开启)。 | ||
| 195 | -- 课程列表页搜索触发修复 | ||
| 196 | - - 现象:进入列表页后,输入关键字并更新为 `/courses-list?keyword=xxx` 时未触发搜索。 | ||
| 197 | - - 原因:父组件 `handleSearch` 对“相同关键字”进行了拦截,导致路由参数变化不执行请求。 | ||
| 198 | - - 修复:移除拦截逻辑;无论关键字是否变化均触发搜索(防抖控制频率)。 | ||
| 199 | - - 位置:`/src/views/courses/CourseListPage.vue` 的 `handleSearch`。 | ||
| 200 | - | ||
| 201 | -- 分享海报弹窗(通用组件) | ||
| 202 | - - 入口:课程详情页底部操作栏“分享”按钮。 | ||
| 203 | - - 组件:`/src/components/ui/SharePoster.vue`(支持复用),`v-model:show` 控制显隐,`course` 传入课程信息,`qr_url` 可指定二维码内容地址(默认取当前页面 URL)。 | ||
| 204 | - - 布局:上部封面图;下部信息区左侧二维码,右侧课程标题、副标题、精简介绍与日期范围。 | ||
| 205 | - - 样式:优先使用 TailwindCSS 布局;组件内部使用 Less 做层级嵌套的样式补充。 | ||
| 206 | - - 图片规则:当封面图域名为 `cdn.ipadbiz.cn` 时,自动追加 `?imageMogr2/thumbnail/200x/strip/quality/70` 压缩参数。 | ||
| 207 | - - 接入位置:`/src/views/courses/CourseDetailPage.vue`,导入并渲染 `<SharePoster v-model:show="show_share_poster" :course="course" />`。 | ||
| 208 | - - Canvas 合成:弹窗打开时使用 Canvas 直接合成海报(封面图、二维码、文案),生成 `dataURL` 并以 `<img>` 展示,用户可直接长按图片保存到手机(无需额外按钮)。 | ||
| 209 | - - 依赖:`pnpm add qrcode`(在 Canvas 内本地生成二维码,避免跨域图片导致画布污染)。 | ||
| 210 | - - 跨域:通过 `crossorigin="anonymous"` 加载封面,并追加时间戳防缓存;若封面跨域不允许,则显示降级卡片,仍可长按截图保存。 | ||
| 211 | - - 文案:使用中文字体并自动换行限制行数,末行超出追加省略号。 | ||
| 212 | - | ||
| 213 | -- 打卡弹窗统一为通用组件 CheckInDialog | ||
| 214 | - - 目的:统一 CourseDetailPage、StudyCoursePage、StudyDetailPage 三处页面的打卡弹窗与交互,避免重复逻辑。 | ||
| 215 | - - 组件:`/src/components/ui/CheckInDialog.vue`,`v-model:show` 控制显隐;支持外部传入任务列表。 | ||
| 216 | - - Props: | ||
| 217 | - - `items_today`:今日打卡任务数组(外部传入)。 | ||
| 218 | - - `items_history`:历史打卡任务数组(外部传入)。 | ||
| 219 | - - 数据结构:每项需包含 `id`、`title(name)`、`task_type`(`checkin`/`upload`)、`is_gray`。 | ||
| 220 | - - 使用位置: | ||
| 221 | - - `/src/views/courses/CourseDetailPage.vue` | ||
| 222 | - - `/src/views/profile/StudyCoursePage.vue` | ||
| 223 | - - `/src/views/study/StudyDetailPage.vue` | ||
| 224 | - - 清理:上述页面已移除旧弹窗的冗余状态与方法(如 `default_list`、`showTaskList`、`showTimeoutTaskList`、`selectedCheckIn` 等),统一由组件内部处理。 | ||
| 225 | - | ||
| 226 | -- 打卡列表组件 CheckInList(复用) | ||
| 227 | - - 目的:抽取首页与弹窗内重复的“打卡类型列表 + 提交按钮”UI与交互逻辑,提升复用性与维护性。 | ||
| 228 | - - 位置:`/src/components/ui/CheckInList.vue`,样式补充:`/src/components/ui/CheckInList.less`(使用 Less 层级嵌套)。 | ||
| 229 | - - Props: | ||
| 230 | - - `items`:打卡任务数组,元素包含 `id`、`name`、`task_type`(`checkin`/`upload`)、`is_gray`。 | ||
| 231 | - - `dense`:是否使用更紧凑的栅格与间距。 | ||
| 232 | - - `scroll`:是否启用滚动容器(最大高度 13rem)。 | ||
| 233 | - - Emits: | ||
| 234 | - - `submit-success`:提交成功后触发,由父组件决定后续行为(轻提示、关闭弹窗等)。 | ||
| 235 | - - 行为: | ||
| 236 | - - 点击置灰的 `checkin` 项时提示“您已经完成了今天的打卡”。 | ||
| 237 | - - 点击 `upload` 类型时跳转到 `/checkin/index?id=xxx` 上传页面。 | ||
| 238 | - - 选择 `checkin` 类型后显示提交按钮,点击后调用接口提交;成功后抛出 `submit-success` 并重置选中项。 | ||
| 239 | - - 使用位置: | ||
| 240 | - - 首页:`/src/views/HomePage.vue`(替换原重复 UI,监听 `submit-success` 显示“打卡成功”)。 | ||
| 241 | - - 弹窗:`/src/components/ui/CheckInDialog.vue`(以 `active_list` 作为数据源,监听 `submit-success` 转发为 `check-in-success` 并延时关闭)。 | ||
| 242 | - | ||
| 243 | -- 打卡详情页(统一提交/编辑页)CheckinDetailPage | ||
| 244 | - - 路径:`/checkin/detail`,页面文件:`/src/views/checkin/CheckinDetailPage.vue` | ||
| 245 | - - 目标:统一“提交作业/打卡”的入口,覆盖文本/图片/视频/音频上传,以及计数打卡;同时承接“编辑已提交动态”的入口。 | ||
| 246 | - - 路由参数约定(query): | ||
| 247 | - - 新增提交:`task_id`(大作业ID)、`subtask_id`(可选,默认选中小作业)、`date`(YYYY-MM-DD,用于补卡与月份计算)、`is_patch`(是否补卡:'1'/'0')、`task_type`(当前作业类型,常见为 `upload`/`count`)。 | ||
| 248 | - - 编辑提交:额外携带 `status=edit`、`post_id`(打卡动态ID)、`type`(原 `file_type`,实际以详情接口回填为准)。 | ||
| 249 | - - 初始化数据: | ||
| 250 | - - 大作业详情:调用 `getTaskDetailAPI({ i: task_id, month })` 获取作业描述、默认附件类型、完成状态等。 | ||
| 251 | - - 小作业列表:调用 `getSubtaskListAPI({ task_id, date })` 获取小作业列表并生成 Picker 选项(包含 `note/field_list/person_type/attachment_type/is_makeup` 等)。 | ||
| 252 | - - 编辑回填:通过 `useCheckin().initEditData` 调 `getUploadTaskInfoAPI({ i: post_id })` 回填 `note/file_type/files/subtask_id/gratitude_count` 等。 | ||
| 253 | - - 附件类型与上传限制: | ||
| 254 | - - `normalizeAttachmentTypeConfig` 解析后端 `attachment_type` 配置,生成 `attachmentTypeOptions`,并通过 `setMaxFileSizeMbMap` 写入不同类型的最大上传大小。 | ||
| 255 | - - 计数打卡(`task_type=count`)下过滤掉 `text` 类型;非计数模式下当 `activeType` 不在选项中时自动重置为第一个可用类型。 | ||
| 256 | - - 提交流程(核心封装在 `useCheckin`): | ||
| 257 | - - 上传:`beforeRead/afterRead` 先校验数量/大小/类型,再走七牛上传(hash 去重 → token → upload → saveFile),成功回填 `meta_id/url/status`。 | ||
| 258 | - - 提交:`onSubmit` 新增走 `addUploadTaskAPI`,编辑走 `editUploadTaskInfoAPI`;成功后写 `sessionStorage.checkin_refresh_flag/checkin_refresh_id` 供列表页局部刷新,并 `router.back()` 返回。 | ||
| 259 | - - 页面层校验:文本打卡至少 10 字;计数打卡必须选择对象且次数 > 0;非文本类型必须有文件。 | ||
| 260 | - - 计数打卡交互: | ||
| 261 | - - 通过 `reuseGratitudeFormAPI({ subtask_id })` 获取可选对象列表 `targetList` 与最近使用 `last_used_list`,进入页面会自动勾选最近使用项。 | ||
| 262 | - - 选中对象首次会弹窗确认(标记 `has_confirmed`),支持新增/编辑;删除对象调用 `gratitudeDeleteAPI`(当前页面内未引入该 API,需补齐后才可生效)。 | ||
| 263 | - - 预览能力: | ||
| 264 | - - 上传组件点击预览时,根据扩展名识别:音频使用 `AudioPlayer` 底部弹窗;视频使用 `VideoPlayer` 居中弹窗(封面 → 点击播放 → 关闭时重置进度);图片使用 `van-image-preview`。 | ||
| 265 | 136 | ||
| 266 | ## /src/components 目录下组件 | 137 | ## /src/components 目录下组件 |
| 267 | 138 | ||
| 268 | -| 目标目录(src/components/) | 包含组件 | 说明 | | 139 | +组件目录索引已迁移到:[/docs/COMPONENTS.md](file:///Users/huyirui/program/itomix/git/mlaj/docs/COMPONENTS.md) |
| 269 | -| --------------------------- | ------------------------------------------------------------ | ---------------- | | ||
| 270 | -| `checkin/` | `CheckInDialog.vue`, `CheckInList.vue`, `CheckInResult.vue` | 打卡相关组件 | | ||
| 271 | -| `media/` | `AudioPlayer.vue`, `VideoPlayer.vue`, `MusicPlayer.vue` | 音视频播放组件 | | ||
| 272 | -| `activity/` | `ActivityApplyHistoryPopup.vue`, `ActivityCard.vue`, `ActivityStatusBadge.vue`, `ActivityTicket.vue` | 活动相关组件 | | ||
| 273 | -| `common/` | `ConfirmDialog.vue`, `GradientHeader.vue`, `MenuItem.vue`, `SearchBar.vue`, `TermsPopup.vue`, `UserAgreement.vue` | 通用基础组件 | | ||
| 274 | -| `effects/` | `FrostedGlass.vue`, `LoadingSpinner.vue` | 视觉特效组件 | | ||
| 275 | -| `courses/` | `CourseCard.vue`, `LiveStreamCard.vue` | 课程展示组件 | | ||
| 276 | -| `payment/` | `WechatPayment.vue` | 支付组件 | | ||
| 277 | -| `studyDetail/` | `StudyMaterialsPopup.vue` | 学习资料弹窗 | | ||
| 278 | -| `layout/` | `AppLayout.vue`, `BottomNav.vue` | 布局与导航 | | ||
| 279 | -| `share/` | `SharePoster.vue` | 分享海报 | | ||
| 280 | -| `files/` | `FilePreview.vue` | 文件预览 | | ||
| 281 | -| `feedback/` | `FeedbackForm.vue` | 反馈表单 | | ||
| 282 | 140 | ||
| 283 | --- | 141 | --- | ... | ... |
docs/ARCHITECTURE.md
0 → 100644
| 1 | +# 架构实现与工程配置 | ||
| 2 | + | ||
| 3 | +## 入口与初始化 | ||
| 4 | + | ||
| 5 | +- 应用入口:[/src/main.js](file:///Users/huyirui/program/itomix/git/mlaj/src/main.js) | ||
| 6 | + - 创建 App、注册全局 Icon 组件、挂载路由 | ||
| 7 | + - 全局注入 axios 到 app.config.globalProperties.$http | ||
| 8 | +- 根组件:[/src/App.vue](file:///Users/huyirui/program/itomix/git/mlaj/src/App.vue) | ||
| 9 | + - 初始化全局认证与购物车:provideAuth / provideCart | ||
| 10 | + - 生产环境 + 微信环境:初始化微信 JSSDK(配置签名 URL) | ||
| 11 | + - 生产环境:版本更新探测(弹窗提示刷新) | ||
| 12 | + | ||
| 13 | +## 路由与权限 | ||
| 14 | + | ||
| 15 | +- 路由入口:[/src/router/index.js](file:///Users/huyirui/program/itomix/git/mlaj/src/router/index.js) | ||
| 16 | + - Hash 路由:createWebHashHistory(import.meta.env.VITE_BASE || '/') | ||
| 17 | + - beforeEach:统一登录页回跳处理,并在必要时探测“是否已登录” | ||
| 18 | +- 鉴权策略:[/src/router/guards.js](file:///Users/huyirui/program/itomix/git/mlaj/src/router/guards.js) | ||
| 19 | + - 白名单 + meta.requiresAuth 双策略判断 | ||
| 20 | + - 未登录时重定向 /login 并带 redirect | ||
| 21 | +- 微信授权策略:[/src/router/guards.js](file:///Users/huyirui/program/itomix/git/mlaj/src/router/guards.js) | ||
| 22 | + - 不在路由守卫自动触发授权,避免循环 | ||
| 23 | + - 仅在用户触发(如点击微信图标/购买流程探测)时调用 startWxAuth | ||
| 24 | + | ||
| 25 | +## 请求与登录态注入 | ||
| 26 | + | ||
| 27 | +- Axios 封装:[/src/utils/axios.js](file:///Users/huyirui/program/itomix/git/mlaj/src/utils/axios.js) | ||
| 28 | + - 请求拦截:动态读取本地 user_info 并注入 User-Id / User-Token | ||
| 29 | + - 响应拦截:code=401 时,仅当当前路由确实需要登录才跳转登录(公开页面不强制跳转) | ||
| 30 | +- 登录态管理:[/src/contexts/auth.js](file:///Users/huyirui/program/itomix/git/mlaj/src/contexts/auth.js) | ||
| 31 | + - provide/inject 维护 currentUser/loading/login/logout | ||
| 32 | + - localStorage 持久化 currentUser | ||
| 33 | + - 初始化流程中会探测授权/登录态并拉取用户信息 | ||
| 34 | + | ||
| 35 | +## 购物车与结算 | ||
| 36 | + | ||
| 37 | +- 购物车上下文:[/src/contexts/cart.js](file:///Users/huyirui/program/itomix/git/mlaj/src/contexts/cart.js) | ||
| 38 | + - 单品/多品两种模式(App.vue 默认使用单品模式) | ||
| 39 | + - localStorage 带时间戳的过期策略(默认一天过期) | ||
| 40 | + - handleCheckout 负责构建订单数据并提交订单 | ||
| 41 | + | ||
| 42 | +## 上传与预览 | ||
| 43 | + | ||
| 44 | +- 上传工具:[/src/utils/upload.js](file:///Users/huyirui/program/itomix/git/mlaj/src/utils/upload.js)、[/src/utils/qiniuFileHash.js](file:///Users/huyirui/program/itomix/git/mlaj/src/utils/qiniuFileHash.js) | ||
| 45 | + - 前端计算文件 Hash,支持“秒传检测 + 直传对象存储” | ||
| 46 | +- 关键业务复用:[/src/composables/useCheckin.js](file:///Users/huyirui/program/itomix/git/mlaj/src/composables/useCheckin.js) | ||
| 47 | + - 打卡/作业提交流程:校验、上传、提交、编辑回填等 | ||
| 48 | +- 预览组件:[/src/components/media](file:///Users/huyirui/program/itomix/git/mlaj/src/components/media) | ||
| 49 | + - 视频/音频播放器、PDF/Office 预览等 | ||
| 50 | + | ||
| 51 | +## Vite 配置与环境变量 | ||
| 52 | + | ||
| 53 | +- Vite 配置:[/vite.config.js](file:///Users/huyirui/program/itomix/git/mlaj/vite.config.js) | ||
| 54 | + - 自动按需引入 Vant 组件(unplugin-auto-import / unplugin-vue-components) | ||
| 55 | + - 别名:@ / @components / @utils / @api 等 | ||
| 56 | + - 本地代理:createProxy(viteEnv.VITE_PROXY_PREFIX, viteEnv.VITE_PROXY_TARGET) | ||
| 57 | +- 环境变量示例:[.env](file:///Users/huyirui/program/itomix/git/mlaj/.env) | ||
| 58 | + - VITE_PORT:开发端口 | ||
| 59 | + - VITE_PROXY_TARGET / VITE_PROXY_PREFIX:接口代理目标与前缀 | ||
| 60 | + - VITE_OUTDIR:构建输出目录 | ||
| 61 | + - VITE_CONSOLE:调试开关 | ||
| 62 | + | ||
| 63 | +## 目录结构(详细) | ||
| 64 | + | ||
| 65 | +``` | ||
| 66 | +mlaj/ | ||
| 67 | +├── build/ # Vite 代理封装 | ||
| 68 | +├── docs/ # 项目文档(本目录) | ||
| 69 | +├── public/ # 静态资源 | ||
| 70 | +├── src/ | ||
| 71 | +│ ├── api/ # 按业务域拆分的接口封装(auth/course/checkin/teacher/...) | ||
| 72 | +│ ├── assets/ # 图片等资源 | ||
| 73 | +│ ├── common/ # 常量 | ||
| 74 | +│ ├── components/ # 组件(按业务域归类) | ||
| 75 | +│ ├── composables/ # 组合式函数(逻辑复用,含单测) | ||
| 76 | +│ ├── contexts/ # 全局状态(provide/inject:auth/cart) | ||
| 77 | +│ ├── router/ # 路由定义与守卫 | ||
| 78 | +│ ├── utils/ # 工具层(axios、上传、鉴权存储、版本更新等) | ||
| 79 | +│ └── views/ # 页面(按业务域归类) | ||
| 80 | +├── tailwind.config.js # Tailwind 配置 | ||
| 81 | +└── vite.config.js # Vite 配置 | ||
| 82 | +``` |
docs/CHANGELOG.md
0 → 100644
| 1 | +# 功能更新记录(Recent Changes) | ||
| 2 | + | ||
| 3 | +说明:该章节从 README 迁移到本文件,避免 README 过长。后续新增变更建议追加在文件顶部。 | ||
| 4 | + | ||
| 5 | +## 打卡详情页重构(/checkin/detail) | ||
| 6 | + | ||
| 7 | +- 统一了文本、媒体上传和计数打卡的入口 | ||
| 8 | +- 实现了基于 composables 的通用提交流程:[/src/composables/useCheckin.js](file:///Users/huyirui/program/itomix/git/mlaj/src/composables/useCheckin.js) | ||
| 9 | +- 页面入口:[/src/views/checkin/CheckinDetailPage.vue](file:///Users/huyirui/program/itomix/git/mlaj/src/views/checkin/CheckinDetailPage.vue) | ||
| 10 | +- 优化了附件预览与编辑回填逻辑(音频/视频/图片预览能力) | ||
| 11 | + | ||
| 12 | +## 教师端功能完善(/teacher) | ||
| 13 | + | ||
| 14 | +- 新增作业管理页面:/teacher/tasks(列表展示:名称、开始/截止时间) | ||
| 15 | +- 新增作业主页:/teacher/tasks/:id(统计 + 日历视图) | ||
| 16 | +- 新增学员作业记录页:/teacher/student-record(作业帖子 + 点赞/点评) | ||
| 17 | + | ||
| 18 | +## 基础体验优化 | ||
| 19 | + | ||
| 20 | +- 登录逻辑调整:仅在登录页点击微信图标时触发授权(避免路由守卫自动授权导致的循环) | ||
| 21 | + - 关键文件:[/src/router/guards.js](file:///Users/huyirui/program/itomix/git/mlaj/src/router/guards.js)、[/src/router/index.js](file:///Users/huyirui/program/itomix/git/mlaj/src/router/index.js)、[/src/views/auth/LoginPage.vue](file:///Users/huyirui/program/itomix/git/mlaj/src/views/auth/LoginPage.vue) | ||
| 22 | +- 搜索栏优化:提升 iOS 软键盘“搜索”键触发稳定性 | ||
| 23 | +- 课程详情页:增加动态 Open Graph 标签,优化分享体验 | ||
| 24 | + | ||
| 25 | +## 课程详情页动态 Open Graph 元标签 | ||
| 26 | + | ||
| 27 | +- 行为:进入课程详情页时,在 head 中插入 og:title / og:description / og:image / og:url;离开页面时移除 | ||
| 28 | +- CDN 规则:图片域名为 cdn.ipadbiz.cn 时,追加 ?imageMogr2/thumbnail/200x/strip/quality/70 | ||
| 29 | +- 位置:[/src/views/courses/CourseDetailPage.vue](file:///Users/huyirui/program/itomix/git/mlaj/src/views/courses/CourseDetailPage.vue) | ||
| 30 | + | ||
| 31 | +## 购买流程环境校验与微信授权探测 | ||
| 32 | + | ||
| 33 | +- 行为:仅对非免费课程在详情页点击“购买”时进行校验;生产环境必须为微信内置浏览器 | ||
| 34 | +- 微信环境内:若未完成微信授权(openid_has=false),会自动发起一次微信授权并中止本次购买,授权后再次点击进入结算 | ||
| 35 | +- 位置:[/src/views/courses/CourseDetailPage.vue](file:///Users/huyirui/program/itomix/git/mlaj/src/views/courses/CourseDetailPage.vue) | ||
| 36 | + | ||
| 37 | +## 401 拦截策略优化(公开页面不再跳登录) | ||
| 38 | + | ||
| 39 | +- 行为:接口返回 code=401 时,仅当当前路由确实需要登录时才重定向登录 | ||
| 40 | +- 位置:[/src/utils/axios.js](file:///Users/huyirui/program/itomix/git/mlaj/src/utils/axios.js) | ||
| 41 | + | ||
| 42 | +## 搜索栏回车搜索兼容性提升 | ||
| 43 | + | ||
| 44 | +- 行为:输入框类型改为 search,并可选开启 form submit 机制,同时保留 keyup.enter | ||
| 45 | +- 位置:[/src/components/common/SearchBar.vue](file:///Users/huyirui/program/itomix/git/mlaj/src/components/common/SearchBar.vue) | ||
| 46 | + | ||
| 47 | +## 分享海报弹窗(可复用) | ||
| 48 | + | ||
| 49 | +- 入口:课程详情页底部操作栏“分享”按钮 | ||
| 50 | +- 组件:[/src/components/poster/SharePoster.vue](file:///Users/huyirui/program/itomix/git/mlaj/src/components/poster/SharePoster.vue) | ||
| 51 | +- 能力:弹窗打开时通过 Canvas 合成海报(封面、二维码、文案),生成 dataURL 展示,用户长按保存 | ||
| 52 | + | ||
| 53 | +## 打卡弹窗与列表组件(可复用) | ||
| 54 | + | ||
| 55 | +- 打卡弹窗:[/src/components/checkin/CheckInDialog.vue](file:///Users/huyirui/program/itomix/git/mlaj/src/components/checkin/CheckInDialog.vue) | ||
| 56 | +- 打卡列表:[/src/components/checkin/CheckInList.vue](file:///Users/huyirui/program/itomix/git/mlaj/src/components/checkin/CheckInList.vue) |
docs/COMPONENTS.md
0 → 100644
| 1 | +# /src/components 组件目录索引 | ||
| 2 | + | ||
| 3 | +## 目录划分 | ||
| 4 | + | ||
| 5 | +| 目录 | 代表组件 | 说明 | | ||
| 6 | +| --- | --- | --- | | ||
| 7 | +| activity/ | ActivityCard.vue、ActivityApplyHistoryPopup.vue | 活动卡片、报名/历史相关弹窗 | | ||
| 8 | +| calendar/ | CollapsibleCalendar.vue、TaskCalendar.vue | 日历与任务日历组件 | | ||
| 9 | +| checkin/ | CheckInDialog.vue、CheckInList.vue、CheckinCard.vue、UploadVideoPopup.vue | 打卡/作业相关组件(弹窗、列表、卡片、上传) | | ||
| 10 | +| common/ | ConfirmDialog.vue、GradientHeader.vue、SearchBar.vue、UserAgreement.vue | 通用基础组件(确认、头部、搜索、协议) | | ||
| 11 | +| count/ | AddTargetDialog.vue、CheckinTargetList.vue、postCountModel.vue | 计数型打卡相关组件 | | ||
| 12 | +| courses/ | CourseCard.vue、CourseList.vue、LiveStreamCard.vue、ReviewPopup.vue | 课程展示与列表、直播卡片、评价弹窗等 | | ||
| 13 | +| effects/ | FrostedGlass.vue、StarryBackground.vue | 视觉效果组件 | | ||
| 14 | +| homePage/ | FeaturedCoursesSection.vue、LatestActivitiesSection.vue | 首页区块组件(精选/活动/推荐等) | | ||
| 15 | +| infoEntry/ | formPage.vue | 信息录入相关组件 | | ||
| 16 | +| layout/ | AppLayout.vue、BottomNav.vue | 页面布局与底部导航 | | ||
| 17 | +| media/ | AudioPlayer.vue、VideoPlayer.vue、PdfPreview.vue、OfficeViewer.vue | 音视频播放器与文档预览 | | ||
| 18 | +| payment/ | WechatPayment.vue | 微信支付相关组件 | | ||
| 19 | +| poster/ | RecallPoster.vue、SharePoster.vue | 海报生成与分享相关组件 | | ||
| 20 | +| studyDetail/ | StudyCatalogPopup.vue、StudyCommentsSection.vue、StudyMaterialsPopup.vue | 学习详情页的弹窗与评论区 | | ||
| 21 | +| teacher/ | TaskFilter.vue、TaskCascaderFilter.vue | 教师端筛选与任务相关组件 | | ||
| 22 | + | ||
| 23 | +## 备注 | ||
| 24 | + | ||
| 25 | +- 历史遗留目录:[/src/layouts](file:///Users/huyirui/program/itomix/git/mlaj/src/layouts) 与 [/src/components/layout](file:///Users/huyirui/program/itomix/git/mlaj/src/components/layout) 并存,建议后续合并归一 |
-
Please register or login to post a comment