# OpenLearning **Repository Path**: l1binn/openlearning ## Basic Information - **Project Name**: OpenLearning - **Description**: 为了方便我自己的学习而打造的开放学习平台 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 2 - **Forks**: 0 - **Created**: 2022-05-11 - **Last Updated**: 2025-03-27 ## Categories & Tags **Categories**: Uncategorized **Tags**: Java, SpringBoot, thymeleaf, MySQL ## README # OpenLearning ## 介绍 为了方便我自己的学习而打造的开放学习平台 ## 软件注意事项 Mysql需设置: ```sql set global max_allowed_packet = 2*1024*1024*10; SET SQL_SAFE_UPDATES = 0; ``` ## 软件整体设计 ### 用户登录注册 用户id,用户名,密码,创建日期以及最后登录日期 ### 英语词典查询 10w+全套的英语单词,并提供查询系统 ### 英语背单词系统 #### 需求分析 1. 用户自行上传单词书(什么格式?csv吧?),或者采用别人上传好的 2. 用户可以自由选择单词书进行背诵,单词本身带有熟悉度 1. 可以选择清空某个单词书上所有单词的熟悉度 2. 设置背诵的单词背诵 3. 背诵采用艾宾浩斯记忆曲线方法 4. 单词熟悉度 1. 不认识 value=0 2. 陌生(1天) value=1 3. 熟悉1阶段(2天) value=2 4. 熟悉2阶段(4天) value=3 5. 熟悉3阶段(7天) value=4 6. 熟悉4阶段(15天) value=5 7. 熟悉5阶段(30天) value=6 8. 精通(60天) value=7 > 单词的熟悉度由日期决定 6. 背诵模式 1. Step 0: 找出当天要背的单词和可以复习的单词, 分为没熟悉度(新单词中还没背过的)和有熟悉度的(新单词中背过的和已经到了复习周期的单词) 2. Step 1 记忆生单词: 找到完全没熟悉度的单词 1. 依次背一遍,进入下一阶段 3. Step 2 第二遍背诵生单词: 单词 记得\不记得\不确定\精通(记得不需要操作,但是不记得和陌生需要操作) 1. 如果记得,熟悉度增加。 2. 如果不记得,熟悉度减少 (最低为陌生) 3. 如果不确定,熟悉度变成 (熟悉1阶段) 4. Step 3 复习熟悉的单词(包括精通的单词):记得\不记得\不确定 1. 如果记得,熟悉度增加。 2. 如果不记得,熟悉度减少 (最低为陌生) 3. 如果不确定,熟悉度变成 (熟悉1阶段) 5. Step 4 最后一轮,对生单词和熟悉单词中不记得的单词进行二次复习确定 1. 只要还有点击不认识的,反复复习,熟悉度由step2和step3确定,这里只是复习。 6. Step 5: 打卡 1. 今日的内容完成,可以考虑继续背诵,或者复习 7. 复习模式 1. 不背诵新词,只复习以前的词,找出哪些单词可以复习 2. 复习熟悉的单词(包括精通的单词):记得\不记得\不确定 1. 如果记得,熟悉度增加。 2. 如果不记得,熟悉度减少 (最低为陌生) 3. 如果不确定,熟悉度变成 (熟悉1阶段) 3. 对熟单词中不记得的单词进行二次复习确定 4. 打卡 1. 今日的内容完成,可以考虑继续背诵 7. 单词要有备注功能,每个人都能看见,并且知道是谁弄的备注 #### 概要设计 - 总单词书表(user_word_books) - 用户上传单词书,会有很多很多,此表统一管理单词书表 ``` 单词书id word_book_id int 主键自增 用户id 外键 单词书昵称 word_book_nickname varchar 非空 单词书表名称 book_uuid(会创建一个表,通过此表去查)非空 ``` - 单词书表-uuid(word_book_uuid16位) - 存储着用户上传的单词书 - 与辞典做外连接得到翻译、音标等。 ```sql CREATE TABLE `word_book_uuid16位` ( `id` INT NOT NULL AUTO_INCREMENT, `word` VARCHAR(200) NOT NULL, PRIMARY KEY (`id`), UNIQUE INDEX `id_UNIQUE` (`id` ASC)); ``` ``` 词典单词id word_id int 唯一 单词 word varchar 唯一 ``` - 单词熟悉度表(words_familiarity) ``` 单词熟悉度主键id wf_id int 主键 单词id word_id 外键 用户id user_id 外键 熟悉度 familiarity int 非空 单词熟悉度最后更新时间(复习时间) last_update_time Datetime 非空 ``` - 用户背诵设置表(word_recite_setting) ``` 表id 主键 用户id 外键 用户设置的种子 seed 用户设定的每日背诵新单词数量 recite_num int 用户当前要背诵的单词书(可以为空) use_word_book 单词书id int 外键 ``` - 用户背诵单词打卡(user_recite_history) ``` 表id 用户id 外键 用户打卡时间 user_finished_time Datetime 非空 用户当天背诵单词量 recite_words_count 用户当天复习单词量 review_words_count 用户当天熟单词遗忘数量 forgetted_words_count ``` - 用户单词笔记(user_word_note) - 用于背单词的时候能做备注 - 一个单词可以有多个备注 ``` 备注id 词典的单词id (这个单词id必须是词典的) 用户id 备注时间 remark_time Datetime 备注内容 remark_content ``` #### Java 设计 总单词书表 ``` UserWordBooks{ 单词书id wordBookId 用户id userId 单词书昵称 nickname 单词书表名称 bookUuid } ``` 单词熟悉度表 ``` wordFamiliarity{ Integer id; Integer userId; Integer wordId; Integer familiarity; DateTime lastUpdateTime } ``` 用户背诵环境设置 ``` id Integer userId; String seed Integer recite_num String useWordBook; ``` 用户背诵单词打卡 ``` id Integer userId; 用户打卡时间 Datetime user_finished_time 用户当天背诵单词量 Integer recite_word_count 用户当天复习单词量 Integer review word count 用户当天熟单词遗忘数量 Integer forgetted words count ``` #### 详细设计(没那么详细,主要内容) 1. 上传单词书功能(异步,上传是否成功放到session中) 1. 用户提交csv文件Java解析,Java依次验证是否在词典中,将在的部分保存起来。 并在session中设置有多少单词不在 2. 创建uuid,插入到总单词书表中 3. 新建单词表 2. 用户单词环境设置功能 **(强制)** 1. 每天需要背诵多少,种子数是多少 2. 要背诵的单词书是哪本(可以为空) 但是要背诵的时候必须选择 3. 用户背诵单词 1. 查询是否有选择单词书,如果没有,必须选择一本 2. 前端点击背诵单词后, 判断step的阶段,如果没有,**设置session过期时间为12小时**,进入阶段1,往session中添加{阶段1}, 执行**第3,4步**, 3. 查询生单词(20220515) 1. 查询一下单词熟悉度表中是否有单词熟悉度为0的单词,且是否当前数量 now_word_num 等于**设置的背诵数量** 2. **如果数量不够,** 通过与词典外键构建新的单词书(seed排序)得到table_word_book_1(twb1), 在twb1按顺序找还没有背诵的单词 `(select * twb1 where twb1.word not in (select t1.word_id from 单词熟悉度表 t1 where user_id = 当前用户) )` ,中选择**设置的背诵数量-now_word_num**的单词插入到单词熟悉度表中,熟悉度设置为0 3. 4. 将生单词放入session中,**并记录生单词的数量(打卡表使用)** 5. 返回记忆单词页面,等待用户下一步操作。 4. 完成记忆单词,请求下一阶段,判断step的阶段,如果step为1,这时设置step=2,将session中的单词返回给背诵页面进行刷新。 1. 背诵页面有选项,可以选择认识**不记得\不确定\完全掌握(精通)**,**认识的单词不需要点击**,分别对应3个接口 2. 将用户的 **不记得\不确定\完全掌握(精通)的单词** 分别放入session中的 **集合(不能重复,免得多次重复点击)** **no_remember_raw,no_sure_raw,expert_raw** , 等到最后提交时在上传到服务器中。 5. 完成背诵单词,请求下一阶段,判断step的阶段,如果step为2,这时设置step=3,进行step3的操作,进入**步骤第6步** 6. 查询熟单词(熟单词的数量只能是生单词的7倍,再多就顶不住了) 1. 通过与词典外键构建新的单词书(seed排序)得到table_word_book_2(twb2), 在twb2按顺序找已经背诵过的单词 `select * from (select t1.表id,t1.word_id from 单词熟悉度表 t1 where user_id = 当前用户) t2 left join (select * twb2)twb2 on t2.word_id = twb2.word_id` 我们得到了一个已经背诵过的单词表**trb1**,按顺序排序。 2. 我们要在trb1中找单词,必须符合如下条件: 1. 熟悉度为1的单词,最后更新时间是1天前的 2. 熟悉度为2的单词,最后更新时间是2天前的 3. ... 4. 熟悉度为7的单词,最后更新时间是60天前的 3. 这些单词我们通过sql语句进行查询 1. `select * from trb1 where 单词熟悉度=1 and 最后更新时间的天数-当前时间的天数>=1` 2. `select * from trb1 where 单词熟悉度=2 and 最后更新时间的天数-当前时间的天数>=2` 3. ... 4. `select * from trb1 where 单词熟悉度=7 and 最后更新时间的天数-当前时间的天数>=60` 4. 在上述条件执行后,每次要看数量有没有超过**设置的背诵数量的7倍**,有的话,后续就不查了 5. **将熟单词放入session中**,送入页面中,并记录熟单词的数量(打卡表使用) 6. 将用户的 **不记得\不确定\完全掌握(精通)的单词** 分别放入session中的 **集合(不能重复,免得多次重复点击)** **no_remember_last,no_sure_last,expert_last**, 等到最后提交时在上传到服务器中。 7. 依次遍历session中的列表,**记录熟单词的不记得\不确定数量(打卡表使用)**,依次将两节**不记得\不确定\完全掌握(精通)进行合并** 保存起来。 重新将**不确定和不记得的单词 保存一个新的内存** 发送给用户,step更新, 1. 直到所有的都弄完,不然无限循环 8. 更新单词,打卡,删除step 4. 用户单词笔记功能 1. 用户发出请求,保存到数据库中 2. 当其他人进行背诵时,默认查看,支持填写,**如果是在复习,则需要点击才能查看、填写**。 5. 复习模式 1. 重复背诵模式的step 1,5,6,7,8,9基本相同。 ## 参与贡献 1. Fork 本仓库 2. 新建 xxx 分支 3. 提交代码 4. 新建 Pull Request