一、核心复习规则(最终精简版,适配小程序)
1. 复习间隔(去掉10分钟,避免逾期,最适配碎片场景)
首次学习 → 1天后复习
第一次复习(正确)→ 3天后复习
第二次复习(正确)→ 7天后复习
第三次复习(正确)→ 14天后复习
第四次复习(正确)→ 30天后复习(status=6,已掌握,停止复习)
任意一次复习错误 → 重置为status=0,重新从“1天后复习”开始,错误次数+1
2. 记忆状态(status)定义
status 0:刚学习(首次学习后,nextReviewTime设为1天后)
status 1:1天后复习(首次复习阶段)
status 2:3天后复习(第二次复习阶段)
status 3:7天后复习(第三次复习阶段)
status 4:14天后复习(第四次复习阶段)
status 5:30天后复习(第五次复习阶段)
status 6:已掌握(无需再复习,nextReviewTime设为无穷大)
3. 每日新增生词量规则
默认:10个/天
可调范围:5-20个/天(用户可自定义)
动态限制:待复习单词>50个时,强制设为5个/天;待复习<30个时,解锁自定义上限
4. 逾期处理(简化逻辑,降低开发复杂度)
核心判断:当前时间戳 ≥ nextReviewTime + status<6 → 出现在复习列表(无论逾期多久)
逾期不分级:不管逾期1天、3天,复习时仅按“答对升级、答错重置”处理,不额外调整间隔
时间戳单位统一:全程使用「毫秒」作为时间单位(Date.now () 返回的就是毫秒),避免秒 / 分钟混用导致的时间计算错误;
排序优化:逾期单词按 nextReviewTime 升序排列(逾期越久排越前),优先让用户复习快忘的单词;
无额外判断:不要加「逾期天数>3 天就重置」的逻辑,完全按「答对 / 答错」处理,代码最少、最稳定;
- 状态边界:升级时用 Math.min(record.status + 1, 6) 限制 status 最大为 6,避免越界。
二、核心逻辑代码(精简可直接复用)
1. 常量定义(复习间隔)
// 复习间隔(单位:毫秒)const REVIEW_INTERVAL = [0, // status 0:刚学习(无需间隔,nextReviewTime手动设为1天后)1 * 24 * 60 * 60 * 1000, // status 1:1天3 * 24 * 60 * 60 * 1000, // status 2:3天7 * 24 * 60 * 60 * 1000, // status 3:7天14 * 24 * 60 * 60 * 1000, // status 4:14天30 * 24 * 60 * 60 * 1000, // status 5:30天Infinity // status 6:已掌握(无需复习)];
2. 核心方法(3个关键方法,覆盖全流程)
// 1. 首次学习:创建单词学习记录function createNewWordRecord(userId, wordId) {return {userId, // 关联用户ID(小程序openid)wordId, // 关联单词IDstatus: 0, // 初始状态:刚学习// 首次学习后,直接设为1天后复习nextReviewTime: Date.now() + 1 * 24 * 60 * 60 * 1000,errorCount: 0, // 错误次数初始为0createTime: Date.now(), // 首次学习时间lastReviewTime: null // 最后复习时间(初始为空)};}// 2. 复习后:更新单词复习状态(核心方法)function updateReviewStatus(record, isCorrect) {const newRecord = { ...record };if (isCorrect) {// 答对:升级status,计算下次复习时间newRecord.status = Math.min(record.status + 1, 6); // 最多到6(已掌握)newRecord.nextReviewTime = Date.now() + REVIEW_INTERVAL[newRecord.status];} else {// 答错:重置status为0,重新从1天后复习newRecord.status = 0;newRecord.nextReviewTime = Date.now() + 1 * 24 * 60 * 60 * 1000;newRecord.errorCount += 1; // 错误次数+1}newRecord.lastReviewTime = Date.now(); // 更新最后复习时间return newRecord;}// 3. 筛选:获取今日需复习的单词列表function getTodayReviewWords(allWordRecords) {const now = Date.now(); // 当前时间戳(毫秒)return allWordRecords.filter(record => {// 两个条件同时满足:未掌握(status<6)+ 复习时间已到(当前时间≥nextReviewTime)return record.status < 6 && record.nextReviewTime <= now;}).sort((a, b) => {// 排序:逾期越久,优先级越高(nextReviewTime越小,排越前)return a.nextReviewTime - b.nextReviewTime;});}
三、数据库设计(最终精简版,核心4表)
选型建议
优先使用:微信小程序云数据库(MongoDB)/ uniCloud,无需自建服务器,适配小程序生态,查询便捷。
1. 用户表(users):存储用户基础信息
| 字段名 | 类型 | 必选 | 说明 | 示例值 |
|---|---|---|---|---|
| _id | String | 是 | 用户唯一标识(小程序openid) | o6_bmjrPTlm6_2sgVt7hMZOPfL2M |
| nickName | String | 否 | 用户昵称 | 张三 |
| avatarUrl | String | 否 | 用户头像 | https://xxx.jpg |
| createTime | Number | 是 | 用户创建时间戳(毫秒) | 1710000000000 |
2. 单词表(words):存储单词基础信息(可批量导入)
| 字段名 | 类型 | 必选 | 说明 | 示例值 |
|---|---|---|---|---|
| _id | String | 是 | 单词唯一标识(自定义) | word_apple |
| word | String | 是 | 单词本身 | apple |
| phonetic | String | 否 | 音标 | /ˈæpl/ |
| meaning | String | 是 | 核心释义 | n. 苹果 |
| example | String | 否 | 例句(可选) | I like apples. |
3. 单词学习记录表(word_learning_records):核心表
存储用户每个单词的学习、复习状态,关联用户和单词,是艾宾浩斯逻辑的核心载体。
| 字段名 | 类型 | 必选 | 说明 | 示例值 |
|---|---|---|---|---|
| _id | String | 是 | 记录唯一标识(自动生成) | record_123456 |
| userId | String | 是 | 关联用户表_id(openid) | o6_bmjrPTlm6_2sgVt7hMZOPfL2M |
| wordId | String | 是 | 关联单词表_id | word_apple |
| status | Number | 是 | 记忆状态(0-6) | 2 |
| nextReviewTime | Number | 是 | 下次复习时间戳(毫秒) | 1710000000000 |
| errorCount | Number | 是 | 该单词错误次数 | 1 |
| createTime | Number | 是 | 首次学习时间戳 | 1710000000000 |
| lastReviewTime | Number | 否 | 最后一次复习时间戳 | 1710000000000 |
4. 学习设置表(learning_settings):存储用户个性化设置
| 字段名 | 类型 | 必选 | 说明 | 示例值 |
|---|---|---|---|---|
| _id | String | 是 | 设置唯一标识 | setting_123456 |
| userId | String | 是 | 关联用户表_id | o6_bmjrPTlm6_2sgVt7hMZOPfL2M |
| dailyNewWordNum | Number | 是 | 每日新增生词量(5-20) | 10 |
| remindSwitch | Boolean | 是 | 复习提醒开关 | true |
5. 索引设计(优化查询性能,必加)
| 表名 | 索引字段 | 索引类型 | 说明 |
|---|---|---|---|
| word_learning_records | userId + status | 复合索引 | 快速查询用户未掌握(status<6)的单词 |
| word_learning_records | userId + nextReviewTime | 复合索引 | 快速筛选用户今日需复习的单词 |
| word_learning_records | userId + wordId | 唯一索引 | 避免用户重复学习同一单词 |
四、关键开发注意事项
nextReviewTime 是核心:所有复习列表的筛选,仅依赖“当前时间≥nextReviewTime + status<6”,逻辑简单,避免复杂判断。
首次学习初始化:必须手动设置 nextReviewTime 为“当前时间+1天”,不能直接用 REVIEW_INTERVAL[0](0毫秒无意义)。
逾期处理:无需额外写复杂逻辑,只要复习时间已到,就出现在列表,复习后按答对/答错规则更新即可。
数据缓存:今日复习列表可缓存到小程序本地,减少数据库查询,提升页面加载速度。
用户体验:当待复习单词>40个时,弹窗提示用户“今日复习任务较多,建议减少新增量”,降低用户放弃率。
五、核心总结
核心逻辑:以“1-3-7-14-30天”为复习间隔,答对升级、答错重置,去掉10分钟间隔,适配小程序碎片场景;
核心判断:nextReviewTime 是复习列表筛选的唯一时间依据,逻辑简单、不易出错;
数据库核心:word_learning_records 表是核心,关联用户和单词,存储复习状态和时间,索引优化提升查询效率;
开发原则:简化逻辑、降低复杂度,优先保证用户能完成每日复习,减少逾期焦虑和操作成本。
(注:文档部分内容可能由 AI 生成)
