docs: 更新README文档以反映最新系统架构和功能变更
- 添加业务系统架构详细说明,包括用户认证、课程系统、打卡作业系统等模块 - 记录近期功能更新,包括教师端功能、登录逻辑优化、课程详情页改进等 - 完善目录结构说明和技术栈实现细节
Showing
1 changed file
with
173 additions
and
16 deletions
| ... | @@ -3,68 +3,202 @@ | ... | @@ -3,68 +3,202 @@ |
| 3 | 测试环境网站 | 3 | 测试环境网站 |
| 4 | https://oa-dev.onwall.cn/f/mlaj | 4 | https://oa-dev.onwall.cn/f/mlaj |
| 5 | 5 | ||
| 6 | - 功能更新记录 | 6 | +## 业务系统架构 |
| 7 | - - 教师端新增作业管理页面:路径 `/teacher/tasks`,标题“作业管理”。 | 7 | + |
| 8 | +### 1. 用户与认证 (User & Auth) | ||
| 9 | + | ||
| 10 | +- **核心流程**:支持手机号+验证码/密码登录,注册流程。 | ||
| 11 | +- **微信集成**: | ||
| 12 | + - 环境检测:`wxInfo().isWeiXin` 检测微信浏览器。 | ||
| 13 | + - 授权登录:基于 OAuth 2.0,通过 `getAuthInfoAPI` 获取 OpenID/UserInfo,支持静默/显式授权。 | ||
| 14 | + - 分享配置:通过 JS-SDK 配置自定义分享标题、描述和图片。 | ||
| 15 | +- **个人中心**:管理个人资料(头像/昵称/手机/密码)、消息通知、帮助中心。 | ||
| 16 | +- **状态管理**:`contexts/auth.js` 维护全局 `currentUser`,使用 localStorage 持久化,Axios 拦截器自动注入 Token。 | ||
| 17 | + | ||
| 18 | +### 2. 课程系统 (Courses) | ||
| 19 | + | ||
| 20 | +- **展示与浏览**:首页推荐、课程列表(热门/精选/搜索)、课程详情页(介绍/目录/评价)。 | ||
| 21 | +- **购买流程**: | ||
| 22 | + - 购物车:`contexts/cart.js` 支持单品/多品模式,本地持久化。 | ||
| 23 | + - 结算:收银台页面 (`/checkout`),集成微信支付 (`api/wx/pay.js`)。 | ||
| 24 | + - 环境校验:付费课程强制在微信环境内购买。 | ||
| 25 | +- **学习体验**: | ||
| 26 | + - 学习页:展示课程目录与学习进度。 | ||
| 27 | + - 内容预览:集成 Video.js 播放视频,PDF.js 预览文档,Office Web Viewer 预览 Word/Excel/PPT。 | ||
| 28 | + - 记录追踪:`useStudyRecordTracker` 自动追踪学习时长与进度。 | ||
| 29 | + | ||
| 30 | +### 3. 打卡与作业系统 (Check-in & Tasks) | ||
| 31 | + | ||
| 32 | +- **学生端**: | ||
| 33 | + - **作业日历**:`IndexCheckInPage` 展示每日打卡状态,支持按月切换。 | ||
| 34 | + - **统一打卡页** (`/checkin/detail`): | ||
| 35 | + - 支持类型:文本、图片、视频、音频、计数打卡(如感恩日记)。 | ||
| 36 | + - 核心逻辑:`useCheckin` 封装上传(七牛云+Hash秒传)、校验、提交逻辑。 | ||
| 37 | + - 交互:支持补卡、编辑已提交内容、选择打卡对象(计数模式)。 | ||
| 38 | + - **互动社区**:打卡动态流,支持点赞、评论、查看他人作品。 | ||
| 39 | +- **教师端** (`/teacher`): | ||
| 40 | + - **作业管理**:发布新作业,查看作业列表与详情(完成率/出勤率统计)。 | ||
| 41 | + - **班级管理**:查看班级学员列表,进入学员详情页。 | ||
| 42 | + - **审批流程**:审核学生提交的打卡内容,支持通过/驳回。 | ||
| 43 | + | ||
| 44 | +### 4. 活动系统 (Activities) | ||
| 45 | + | ||
| 46 | +- **功能**:活动列表展示、活动详情、在线报名表单 (`/activities/:id/signup`)。 | ||
| 47 | +- **记录**:用户可查看“我的活动”历史记录。 | ||
| 48 | + | ||
| 49 | +### 5. 召回系统 (Recall) | ||
| 50 | + | ||
| 51 | +- **目标**:面向老用户的营销与促活流程。 | ||
| 52 | +- **流程**: | ||
| 53 | + 1. 登录/身份验证(支持身份证查询历史)。 | ||
| 54 | + 2. 引导页与信息补全。 | ||
| 55 | + 3. **时光机旅程 (Timeline)**:展示用户在平台的历史里程碑。 | ||
| 56 | + 4. 活动历史回顾与积分汇总。 | ||
| 57 | + 5. **专属海报**:生成个性化分享海报。 | ||
| 58 | + 6. 导流:引导至 AI 星球或最新课程。 | ||
| 59 | + | ||
| 60 | +### 6. 积分与订单 | ||
| 61 | + | ||
| 62 | +- **订单**:查看订单状态(待支付/已支付/退款),支持取消订单。 | ||
| 63 | +- **积分**:查看积分余额与变动明细,积分可用于抵扣或兑换(视具体业务规则)。 | ||
| 64 | + | ||
| 65 | +## 核心技术栈与实现 | ||
| 66 | + | ||
| 67 | +### 状态管理 | ||
| 68 | + | ||
| 69 | +- **Context API**:项目主要使用 Vue 3 `provide/inject` 模式进行全局状态管理。 | ||
| 70 | + - `auth.js`:用户认证、登录态、Token 管理。 | ||
| 71 | + - `cart.js`:购物车逻辑、商品增删改、结算流程。 | ||
| 72 | +- **持久化**:关键状态同步至 `localStorage`,页面刷新不丢失。 | ||
| 73 | + | ||
| 74 | +### 文件处理 | ||
| 75 | + | ||
| 76 | +- **七牛云上传**: | ||
| 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 | + | ||
| 125 | +## 功能更新记录 (Recent Changes) | ||
| 126 | + | ||
| 127 | +- **打卡详情页重构 (`/checkin/detail`)**: | ||
| 128 | + - 统一了文本、媒体上传和计数打卡的入口。 | ||
| 129 | + - 实现了基于 `useCheckin` 的通用提交流程。 | ||
| 130 | + - 优化了附件预览和编辑回填逻辑。 | ||
| 131 | + | ||
| 132 | +- **教师端功能完善**: | ||
| 133 | + - 新增作业管理、作业主页(统计与日历视图)、学员作业记录页面。 | ||
| 134 | +- **基础体验优化**: | ||
| 135 | + - 登录逻辑调整:仅在点击微信图标时触发授权。 | ||
| 136 | + - 搜索栏优化:支持 iOS 软键盘搜索键。 | ||
| 137 | + - 课程详情页:增加动态 Open Graph 标签,优化分享体验。 | ||
| 138 | + | ||
| 139 | +功能更新记录 | ||
| 140 | + | ||
| 141 | +- 教师端新增作业管理页面:路径 `/teacher/tasks`,标题“作业管理”。 | ||
| 8 | - 列表展示:作业名称、开始时间、截止时间。 | 142 | - 列表展示:作业名称、开始时间、截止时间。 |
| 9 | - 当前数据来源为Mock,后续可替换为真实接口数据。 | 143 | - 当前数据来源为Mock,后续可替换为真实接口数据。 |
| 10 | - - 教师端新增作业主页:路径 `/teacher/tasks/:id`,标题“作业主页”。 | 144 | +- 教师端新增作业主页:路径 `/teacher/tasks/:id`,标题“作业主页”。 |
| 11 | - 头部:作业名称、介绍文案、细项信息(周期、频次、时间段、附件类型)。 | 145 | - 头部:作业名称、介绍文案、细项信息(周期、频次、时间段、附件类型)。 |
| 12 | - 统计:出勤率与任务完成率(参考 `myClassPage.vue` 统计样式,数据Mock)。 | 146 | - 统计:出勤率与任务完成率(参考 `myClassPage.vue` 统计样式,数据Mock)。 |
| 13 | - 日历:使用 `van-calendar` 单选模式,选择日期后展示当日学生完成情况。 | 147 | - 日历:使用 `van-calendar` 单选模式,选择日期后展示当日学生完成情况。 |
| 14 | - 学生完成情况:参考图片2样式,勾选代表已完成,未勾选代表未完成(数据Mock)。 | 148 | - 学生完成情况:参考图片2样式,勾选代表已完成,未勾选代表未完成(数据Mock)。 |
| 15 | - - 教师端新增学员作业记录页面:路径 `/teacher/student-record`,标题“学员作业记录”。 | 149 | +- 教师端新增学员作业记录页面:路径 `/teacher/student-record`,标题“学员作业记录”。 |
| 16 | - 在作业主页的学生列表点击卡片可跳转至该页面(当前版本为固定示例页面)。 | 150 | - 在作业主页的学生列表点击卡片可跳转至该页面(当前版本为固定示例页面)。 |
| 17 | - 列表展示:作业帖子、图片/视频/音频、点赞与点评弹窗(与 `studentPage.vue` 的作业记录样式一致)。 | 151 | - 列表展示:作业帖子、图片/视频/音频、点赞与点评弹窗(与 `studentPage.vue` 的作业记录样式一致)。 |
| 18 | - 接口参数固定:`user_id=817017`,`group_id=816653`(后续可替换为动态参数)。 | 152 | - 接口参数固定:`user_id=817017`,`group_id=816653`(后续可替换为动态参数)。 |
| 19 | - - 学习详情页标签指示条修复:`/src/views/profile/StudyCoursePage.vue` | 153 | +- 学习详情页标签指示条修复:`/src/views/profile/StudyCoursePage.vue` |
| 20 | - 现象:首次进入且存在“打卡互动”时,底部绿色指示条定位错误。 | 154 | - 现象:首次进入且存在“打卡互动”时,底部绿色指示条定位错误。 |
| 21 | - 修复:新增标签容器 `ref` 与 `ResizeObserver`,按栏目数量对容器进行等分,指示条宽度与位移按分段和索引计算,异步加载第三个栏目时不再错位。 | 155 | - 修复:新增标签容器 `ref` 与 `ResizeObserver`,按栏目数量对容器进行等分,指示条宽度与位移按分段和索引计算,异步加载第三个栏目时不再错位。 |
| 22 | - - 登录逻辑调整:仅在登录页微信图标点击时触发授权 | 156 | +- 登录逻辑调整:仅在登录页微信图标点击时触发授权 |
| 23 | - 变更文件:`/src/views/auth/LoginPage.vue`、`/src/router/guards.js`、`/src/router/index.js` | 157 | - 变更文件:`/src/views/auth/LoginPage.vue`、`/src/router/guards.js`、`/src/router/index.js` |
| 24 | - 路由守卫:移除自动微信授权检查,新增 `startWxAuth` 供手动触发。 | 158 | - 路由守卫:移除自动微信授权检查,新增 `startWxAuth` 供手动触发。 |
| 25 | - 登录页:微信图标绑定点击事件,非微信环境提示“请在微信内打开”。 | 159 | - 登录页:微信图标绑定点击事件,非微信环境提示“请在微信内打开”。 |
| 26 | - 使用方式:进入登录页,点击微信图标进行授权登录。 | 160 | - 使用方式:进入登录页,点击微信图标进行授权登录。 |
| 27 | 161 | ||
| 28 | - - 课程详情页动态 Open Graph 元标签 | 162 | +- 课程详情页动态 Open Graph 元标签 |
| 29 | - 行为:进入课程详情页时,在 `<head>` 中插入 4 个 `meta` 标签:`og:title`(课程 `title`)、`og:description`(课程 `subtitle`)、`og:image`(课程 `cover`)、`og:url`(当前页面 URL);这些 `meta` 必须插在 `<title>` 标签的前面;离开页面时移除。 | 163 | - 行为:进入课程详情页时,在 `<head>` 中插入 4 个 `meta` 标签:`og:title`(课程 `title`)、`og:description`(课程 `subtitle`)、`og:image`(课程 `cover`)、`og:url`(当前页面 URL);这些 `meta` 必须插在 `<title>` 标签的前面;离开页面时移除。 |
| 30 | - CDN 规则:若图片域名为 `cdn.ipadbiz.cn`,自动追加 `?imageMogr2/thumbnail/200x/strip/quality/70`。 | 164 | - CDN 规则:若图片域名为 `cdn.ipadbiz.cn`,自动追加 `?imageMogr2/thumbnail/200x/strip/quality/70`。 |
| 31 | - 位置:`/src/views/courses/CourseDetailPage.vue`,在 `onMounted` 插入,`onUnmounted` 清理。 | 165 | - 位置:`/src/views/courses/CourseDetailPage.vue`,在 `onMounted` 插入,`onUnmounted` 清理。 |
| 32 | - 函数:`build_og_image_url(src)`、`set_og_meta(payload)`、`remove_og_meta()`。 | 166 | - 函数:`build_og_image_url(src)`、`set_og_meta(payload)`、`remove_og_meta()`。 |
| 33 | 167 | ||
| 34 | - - 课程详情页咨询弹窗(Mock) | 168 | +- 课程详情页咨询弹窗(Mock) |
| 35 | - 入口:详情页顶部快捷操作中的“咨询”按钮。 | 169 | - 入口:详情页顶部快捷操作中的“咨询”按钮。 |
| 36 | - 展示:底部弹出层,仅底部关闭按钮;展示联系人列表,可点击名称或号码直接拨打(`tel:`)。 | 170 | - 展示:底部弹出层,仅底部关闭按钮;展示联系人列表,可点击名称或号码直接拨打(`tel:`)。 |
| 37 | - 联系人:支持多个联系人,展示姓名与号码;电话号码使用绿色高亮;联系人与号码字体大小一致。 | 171 | - 联系人:支持多个联系人,展示姓名与号码;电话号码使用绿色高亮;联系人与号码字体大小一致。 |
| 38 | - 位置:`/src/views/courses/CourseDetailPage.vue`,“咨询弹窗”模板与交互逻辑(`open_consult_dialog`、`close_consult_dialog`、`consult_contacts`、`call_phone(phone)`)。 | 172 | - 位置:`/src/views/courses/CourseDetailPage.vue`,“咨询弹窗”模板与交互逻辑(`open_consult_dialog`、`close_consult_dialog`、`consult_contacts`、`call_phone(phone)`)。 |
| 39 | 173 | ||
| 40 | - - 购买流程环境校验 | 174 | +- 购买流程环境校验 |
| 41 | - 行为:仅对非免费课程在详情页点击“购买”时进行校验;生产环境下必须为微信内置浏览器(`wxInfo().isWeiXin`)。 | 175 | - 行为:仅对非免费课程在详情页点击“购买”时进行校验;生产环境下必须为微信内置浏览器(`wxInfo().isWeiXin`)。 |
| 42 | - 免费课程:跳过微信环境校验,允许直接进入结算流程。 | 176 | - 免费课程:跳过微信环境校验,允许直接进入结算流程。 |
| 43 | - 非微信环境(付费课):提示“请在微信内打开进行购买”,不进入结算。 | 177 | - 非微信环境(付费课):提示“请在微信内打开进行购买”,不进入结算。 |
| 44 | - 位置:`/src/views/courses/CourseDetailPage.vue` 的 `handlePurchase` 中,使用 `wxInfo` 进行环境判断。 | 178 | - 位置:`/src/views/courses/CourseDetailPage.vue` 的 `handlePurchase` 中,使用 `wxInfo` 进行环境判断。 |
| 45 | 179 | ||
| 46 | - - 微信授权自动触发(微信环境内) | 180 | +- 微信授权自动触发(微信环境内) |
| 47 | - 行为:在微信内置浏览器环境下点击“购买”时,若检测到未完成微信授权(`openid_has=false`),系统将自动发起一次微信授权流程并中止本次购买;授权完成后再次点击可进入结算。 | 181 | - 行为:在微信内置浏览器环境下点击“购买”时,若检测到未完成微信授权(`openid_has=false`),系统将自动发起一次微信授权流程并中止本次购买;授权完成后再次点击可进入结算。 |
| 48 | - 开发环境:不触发微信授权流程(保留现有调试行为)。 | 182 | - 开发环境:不触发微信授权流程(保留现有调试行为)。 |
| 49 | - 位置:`/src/views/courses/CourseDetailPage.vue` 的 `handlePurchase` 中,调用 `getAuthInfoAPI()` 探测并使用 `startWxAuth()` 触发授权。 | 183 | - 位置:`/src/views/courses/CourseDetailPage.vue` 的 `handlePurchase` 中,调用 `getAuthInfoAPI()` 探测并使用 `startWxAuth()` 触发授权。 |
| 50 | 184 | ||
| 51 | - - 401拦截策略优化(公开页面不再跳登录) | 185 | +- 401拦截策略优化(公开页面不再跳登录) |
| 52 | - 行为:接口返回 `code=401` 时,不再对公开页面(如课程详情 `/courses/:id`)进行登录重定向;仅当当前路由确实需要登录权限时才跳转至登录页。 | 186 | - 行为:接口返回 `code=401` 时,不再对公开页面(如课程详情 `/courses/:id`)进行登录重定向;仅当当前路由确实需要登录权限时才跳转至登录页。 |
| 53 | - 原理:响应拦截器调用路由守卫 `checkAuth` 判断当前路由是否为受限页面,受限则清理登录信息并附带 `redirect` 重定向至登录页;公开页面保持当前页,由业务自行处理401。 | 187 | - 原理:响应拦截器调用路由守卫 `checkAuth` 判断当前路由是否为受限页面,受限则清理登录信息并附带 `redirect` 重定向至登录页;公开页面保持当前页,由业务自行处理401。 |
| 54 | - 位置:`/src/utils/axios.js`,在响应拦截器中按需处理重定向。 | 188 | - 位置:`/src/utils/axios.js`,在响应拦截器中按需处理重定向。 |
| 55 | - - 搜索栏回车搜索兼容性提升 | 189 | +- 搜索栏回车搜索兼容性提升 |
| 56 | - 行为:将输入框类型改为 `search`,并可选开启 `form @submit.prevent` 机制以提升 iOS 设备软键盘“搜索”键触发稳定性;同时保留 `@keyup.enter` 回车触发搜索。 | 190 | - 行为:将输入框类型改为 `search`,并可选开启 `form @submit.prevent` 机制以提升 iOS 设备软键盘“搜索”键触发稳定性;同时保留 `@keyup.enter` 回车触发搜索。 |
| 57 | - 路由行为: | 191 | - 路由行为: |
| 58 | - 课程页(`isCoursePage=true`):回车或搜索键触发后跳转至 `/courses-list` 并携带 `keyword` 参数。 | 192 | - 课程页(`isCoursePage=true`):回车或搜索键触发后跳转至 `/courses-list` 并携带 `keyword` 参数。 |
| 59 | - 列表页:仅更新当前路由的查询参数 `keyword`。 | 193 | - 列表页:仅更新当前路由的查询参数 `keyword`。 |
| 60 | - 位置:`/src/components/ui/SearchBar.vue`,新增 `useFormSubmit` 可选参数(默认开启)。 | 194 | - 位置:`/src/components/ui/SearchBar.vue`,新增 `useFormSubmit` 可选参数(默认开启)。 |
| 61 | - - 课程列表页搜索触发修复 | 195 | +- 课程列表页搜索触发修复 |
| 62 | - 现象:进入列表页后,输入关键字并更新为 `/courses-list?keyword=xxx` 时未触发搜索。 | 196 | - 现象:进入列表页后,输入关键字并更新为 `/courses-list?keyword=xxx` 时未触发搜索。 |
| 63 | - 原因:父组件 `handleSearch` 对“相同关键字”进行了拦截,导致路由参数变化不执行请求。 | 197 | - 原因:父组件 `handleSearch` 对“相同关键字”进行了拦截,导致路由参数变化不执行请求。 |
| 64 | - 修复:移除拦截逻辑;无论关键字是否变化均触发搜索(防抖控制频率)。 | 198 | - 修复:移除拦截逻辑;无论关键字是否变化均触发搜索(防抖控制频率)。 |
| 65 | - 位置:`/src/views/courses/CourseListPage.vue` 的 `handleSearch`。 | 199 | - 位置:`/src/views/courses/CourseListPage.vue` 的 `handleSearch`。 |
| 66 | 200 | ||
| 67 | - - 分享海报弹窗(通用组件) | 201 | +- 分享海报弹窗(通用组件) |
| 68 | - 入口:课程详情页底部操作栏“分享”按钮。 | 202 | - 入口:课程详情页底部操作栏“分享”按钮。 |
| 69 | - 组件:`/src/components/ui/SharePoster.vue`(支持复用),`v-model:show` 控制显隐,`course` 传入课程信息,`qr_url` 可指定二维码内容地址(默认取当前页面 URL)。 | 203 | - 组件:`/src/components/ui/SharePoster.vue`(支持复用),`v-model:show` 控制显隐,`course` 传入课程信息,`qr_url` 可指定二维码内容地址(默认取当前页面 URL)。 |
| 70 | - 布局:上部封面图;下部信息区左侧二维码,右侧课程标题、副标题、精简介绍与日期范围。 | 204 | - 布局:上部封面图;下部信息区左侧二维码,右侧课程标题、副标题、精简介绍与日期范围。 |
| ... | @@ -76,7 +210,7 @@ https://oa-dev.onwall.cn/f/mlaj | ... | @@ -76,7 +210,7 @@ https://oa-dev.onwall.cn/f/mlaj |
| 76 | - 跨域:通过 `crossorigin="anonymous"` 加载封面,并追加时间戳防缓存;若封面跨域不允许,则显示降级卡片,仍可长按截图保存。 | 210 | - 跨域:通过 `crossorigin="anonymous"` 加载封面,并追加时间戳防缓存;若封面跨域不允许,则显示降级卡片,仍可长按截图保存。 |
| 77 | - 文案:使用中文字体并自动换行限制行数,末行超出追加省略号。 | 211 | - 文案:使用中文字体并自动换行限制行数,末行超出追加省略号。 |
| 78 | 212 | ||
| 79 | - - 打卡弹窗统一为通用组件 CheckInDialog | 213 | +- 打卡弹窗统一为通用组件 CheckInDialog |
| 80 | - 目的:统一 CourseDetailPage、StudyCoursePage、StudyDetailPage 三处页面的打卡弹窗与交互,避免重复逻辑。 | 214 | - 目的:统一 CourseDetailPage、StudyCoursePage、StudyDetailPage 三处页面的打卡弹窗与交互,避免重复逻辑。 |
| 81 | - 组件:`/src/components/ui/CheckInDialog.vue`,`v-model:show` 控制显隐;支持外部传入任务列表。 | 215 | - 组件:`/src/components/ui/CheckInDialog.vue`,`v-model:show` 控制显隐;支持外部传入任务列表。 |
| 82 | - Props: | 216 | - Props: |
| ... | @@ -89,7 +223,7 @@ https://oa-dev.onwall.cn/f/mlaj | ... | @@ -89,7 +223,7 @@ https://oa-dev.onwall.cn/f/mlaj |
| 89 | - `/src/views/study/StudyDetailPage.vue` | 223 | - `/src/views/study/StudyDetailPage.vue` |
| 90 | - 清理:上述页面已移除旧弹窗的冗余状态与方法(如 `default_list`、`showTaskList`、`showTimeoutTaskList`、`selectedCheckIn` 等),统一由组件内部处理。 | 224 | - 清理:上述页面已移除旧弹窗的冗余状态与方法(如 `default_list`、`showTaskList`、`showTimeoutTaskList`、`selectedCheckIn` 等),统一由组件内部处理。 |
| 91 | 225 | ||
| 92 | - - 打卡列表组件 CheckInList(复用) | 226 | +- 打卡列表组件 CheckInList(复用) |
| 93 | - 目的:抽取首页与弹窗内重复的“打卡类型列表 + 提交按钮”UI与交互逻辑,提升复用性与维护性。 | 227 | - 目的:抽取首页与弹窗内重复的“打卡类型列表 + 提交按钮”UI与交互逻辑,提升复用性与维护性。 |
| 94 | - 位置:`/src/components/ui/CheckInList.vue`,样式补充:`/src/components/ui/CheckInList.less`(使用 Less 层级嵌套)。 | 228 | - 位置:`/src/components/ui/CheckInList.vue`,样式补充:`/src/components/ui/CheckInList.less`(使用 Less 层级嵌套)。 |
| 95 | - Props: | 229 | - Props: |
| ... | @@ -105,3 +239,26 @@ https://oa-dev.onwall.cn/f/mlaj | ... | @@ -105,3 +239,26 @@ https://oa-dev.onwall.cn/f/mlaj |
| 105 | - 使用位置: | 239 | - 使用位置: |
| 106 | - 首页:`/src/views/HomePage.vue`(替换原重复 UI,监听 `submit-success` 显示“打卡成功”)。 | 240 | - 首页:`/src/views/HomePage.vue`(替换原重复 UI,监听 `submit-success` 显示“打卡成功”)。 |
| 107 | - 弹窗:`/src/components/ui/CheckInDialog.vue`(以 `active_list` 作为数据源,监听 `submit-success` 转发为 `check-in-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`。 | ... | ... |
-
Please register or login to post a comment