diff --git a/components.d.ts b/components.d.ts index c9bf78b3..aa90b1f7 100644 --- a/components.d.ts +++ b/components.d.ts @@ -14,6 +14,7 @@ declare module 'vue' { DeleteIcon: typeof import('./src/components/icon/DeleteIcon.vue')['default'] ElButton: typeof import('element-plus/es')['ElButton'] ElCheckbox: typeof import('element-plus/es')['ElCheckbox'] + ElDialog: typeof import('element-plus/es')['ElDialog'] ElForm: typeof import('element-plus/es')['ElForm'] ElFormItem: typeof import('element-plus/es')['ElFormItem'] ElInput: typeof import('element-plus/es')['ElInput'] diff --git a/src/hooks/dict.ts b/src/hooks/dict.ts index 668e54e7..cf02dfde 100644 --- a/src/hooks/dict.ts +++ b/src/hooks/dict.ts @@ -112,51 +112,83 @@ export function getCurrentStudyWord() { let data = {new: [], review: [], write: []} let dict = store.sdict; if (dict.words?.length) { - for (let i = dict.lastLearnIndex; i < dict.words.length; i++) { - if (data.new.length >= dict.perDayStudyNumber) break - let item = dict.words[i] - if (!store.known.words.map(v => v.word.toLowerCase()).includes(item.word.toLowerCase())) { + const perDay = store.sdict.perDayStudyNumber; + let start = dict.lastLearnIndex; + let end = start + dict.perDayStudyNumber + dict.words.slice(start, end).map(item => { + if (!store.knownWords.includes(item.word)) { data.new.push(item) } - } + }) - const getList = (startIndex, endIndex) => { - if (startIndex < 0) return [] + const getList = (startIndex: number, endIndex: number) => { + if (startIndex < 0) startIndex = 0 return dict.words.slice(startIndex, endIndex) } - let s = dict.lastLearnIndex - dict.perDayStudyNumber - let e = dict.lastLearnIndex + end = start + start = start - dict.perDayStudyNumber //取上一次学习的单词用于复习 - let list = getList(s, e) + let list = getList(start, end) list.map(item => { - if (!store.known.words.map(v => v.word.toLowerCase()).includes(item.word.toLowerCase())) { + if (!store.knownWords.includes(item.word)) { data.review.push(item) } }) - //取前天至再往前数3天的单词,用于默写, - Array.from({length: 4}).map((_, j) => { - e = s - s -= dict.perDayStudyNumber - list = getList(s, e) - let d = [] - for (let i = 0; i < list.length; i++) { - if (j === 3) { - if (d.length >= dict.perDayStudyNumber - data.write.length) break - } else { - if (d.length >= Math.floor(dict.perDayStudyNumber / 4)) break - } - let item = list[i] - if (!store.known.words.map(v => v.word.toLowerCase()).includes(item.word.toLowerCase())) { - d.push(item) - } - } - data.write = data.write.concat(d) - }) + // end = start + // start = start - dict.perDayStudyNumber * 3 + // //在上次学习再往前取前3次学习的单词用于默写 + // list = getList(start, end) + // list.map(item => { + // if (!store.knownWords.includes(item.word)) { + // data.write.push(item) + // } + // }) + + //write数组放的是上上次之前的单词,总的数量为perDayStudyNumber * 3,取单词的规则为:从后往前取6个perDayStudyNumber的,越靠前的取的单词越多。 + end = start + const totalNeed = perDay * 3; + const allWords = dict.words; + + // 上上次更早的单词 + const candidateWords = allWords.slice(0, end).filter(w => !store.knownWords.includes(w.word)); + + // 分6组,每组 perDay 个 + const groupCount = 6; + const groupSize = perDay; + const groups: Word[][] = []; + for (let i = 0; i < groupCount; i++) { + const start = candidateWords.length - (i + 1) * groupSize; + const end = candidateWords.length - i * groupSize; + if (start < 0 && end <= 0) break; + groups.unshift(candidateWords.slice(Math.max(0, start), Math.max(0, end))); + } + + // 分配数量,靠前组多,靠后组少 + // 例如分配比例 [1,2,3,4,5,6] + const ratio = [1, 2, 3, 4, 5, 6]; + const ratioSum = ratio.reduce((a, b) => a + b, 0); + const realRatio = ratio.map(r => Math.round(r * totalNeed / ratioSum)); + + // 按比例从每组取单词 + let writeWords: Word[] = []; + for (let i = 0; i < groups.length; i++) { + writeWords = writeWords.concat(groups[i].slice(-realRatio[i])); + } + // 如果数量不够,补足 + if (writeWords.length < totalNeed) { + const extra = candidateWords.filter(w => !writeWords.includes(w)).slice(-(totalNeed - writeWords.length)); + writeWords = writeWords.concat(extra); + } + // 最终数量截断 + writeWords = writeWords.slice(-totalNeed); + + //这里需要反转一下,越靠近今天的单词,越先练习 + data.write = writeWords.reverse(); } // console.timeEnd() - // console.log('data', data) + console.log('data', data) return data } diff --git a/src/pages/mobile/practice/index.vue b/src/pages/mobile/practice/index.vue index dee46a48..0ed8d8b2 100644 --- a/src/pages/mobile/practice/index.vue +++ b/src/pages/mobile/practice/index.vue @@ -75,7 +75,7 @@ function jumpSpecifiedChapter(val: number) { onMounted(() => { emitter.on(EventKey.write, write) - emitter.on(EventKey.repeat, repeat) + emitter.on(EventKey.repeatStudy, repeat) emitter.on(EventKey.jumpSpecifiedChapter, jumpSpecifiedChapter) emitter.on(ShortcutKey.PreviousChapter, prev) @@ -91,7 +91,7 @@ onMounted(() => { onUnmounted(() => { emitter.off(EventKey.write, write) - emitter.off(EventKey.repeat, repeat) + emitter.off(EventKey.repeatStudy, repeat) emitter.off(EventKey.jumpSpecifiedChapter, jumpSpecifiedChapter) emitter.off(ShortcutKey.PreviousChapter, prev) diff --git a/src/pages/mobile/practice/practice-word/index.vue b/src/pages/mobile/practice/practice-word/index.vue index 82110995..32a18eed 100644 --- a/src/pages/mobile/practice/practice-word/index.vue +++ b/src/pages/mobile/practice/practice-word/index.vue @@ -38,7 +38,7 @@ onMounted(() => { useEvents([ [EventKey.changeDict, getCurrentPractice], - [EventKey.next, next], + [EventKey.continueStudy, next], [ShortcutKey.NextChapter, next], ]) diff --git a/src/pages/pc/article/StudyArticle.vue b/src/pages/pc/article/StudyArticle.vue index bf611b90..e9572548 100644 --- a/src/pages/pc/article/StudyArticle.vue +++ b/src/pages/pc/article/StudyArticle.vue @@ -70,7 +70,7 @@ function jumpSpecifiedChapter(val: number) { onMounted(() => { emitter.on(EventKey.write, write) - emitter.on(EventKey.repeat, repeat) + emitter.on(EventKey.repeatStudy, repeat) emitter.on(EventKey.jumpSpecifiedChapter, jumpSpecifiedChapter) emitter.on(ShortcutKey.PreviousChapter, prev) @@ -86,7 +86,7 @@ onMounted(() => { onUnmounted(() => { emitter.off(EventKey.write, write) - emitter.off(EventKey.repeat, repeat) + emitter.off(EventKey.repeatStudy, repeat) emitter.off(EventKey.jumpSpecifiedChapter, jumpSpecifiedChapter) emitter.off(ShortcutKey.PreviousChapter, prev) diff --git a/src/pages/pc/article/practice-article/TypingArticle.vue b/src/pages/pc/article/practice-article/TypingArticle.vue index 9f4a90f0..247baded 100644 --- a/src/pages/pc/article/practice-article/TypingArticle.vue +++ b/src/pages/pc/article/practice-article/TypingArticle.vue @@ -455,7 +455,7 @@ let showQuestions = $ref(false)
diff --git a/src/pages/pc/article/practice-article/index.vue b/src/pages/pc/article/practice-article/index.vue index 9b1a241a..877d328e 100644 --- a/src/pages/pc/article/practice-article/index.vue +++ b/src/pages/pc/article/practice-article/index.vue @@ -226,7 +226,7 @@ onMounted(() => { useEvents([ [EventKey.changeDict, init], - [EventKey.next, next], + [EventKey.continueStudy, next], [ShortcutKey.NextChapter, next], [ShortcutKey.PlayWordPronunciation, play], @@ -303,7 +303,7 @@ const {playSentenceAudio} = usePlaySentenceAudio() :title="`下一章(${settingStore.shortcutKeyMap[ShortcutKey.NextChapter]})`" v-if="store.currentBook.lastLearnIndex < articleData.articles.length - 1">