diff --git a/src/assets/css/style.scss b/src/assets/css/style.scss
index a08e09b4..995d0cce 100644
--- a/src/assets/css/style.scss
+++ b/src/assets/css/style.scss
@@ -164,6 +164,7 @@ html, body {
overflow-x: hidden;
color: var(--color-main-text);
font-family: var(--font-family);
+ background: var(--color-primary);
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
diff --git a/src/hooks/dict.ts b/src/hooks/dict.ts
index 626204ce..2a5b71dc 100644
--- a/src/hooks/dict.ts
+++ b/src/hooks/dict.ts
@@ -1,5 +1,8 @@
import {Article, Word} from "@/types/types.ts";
import {useBaseStore} from "@/stores/base.ts";
+import {useSettingStore} from "@/stores/setting.ts";
+import {getDefaultWord} from "@/types/func.ts";
+import {getRandomN, splitIntoN} from "@/utils";
export function useWordOptions() {
const store = useBaseStore()
@@ -83,105 +86,98 @@ export function useArticleOptions() {
}
export function getCurrentStudyWord() {
- // console.time()
+ console.log('getCurrentStudyWord')
const store = useBaseStore()
let data = {new: [], review: [], write: []}
let dict = store.sdict;
- if (dict.words?.length) {
- const getList = (startIndex: number, endIndex: number) => dict.words.slice(startIndex, endIndex)
-
- const perDay = store.sdict.perDayStudyNumber;
- const totalNeed = perDay * 3;
+ let isTest = false
+ let words = dict.words.slice()
+ if (isTest) {
+ words = Array.from({length: 10}).map((v, i) => {
+ return getDefaultWord({word: String(i)})
+ })
+ }
+ if (words?.length) {
+ const settingStore = useSettingStore()
+ //忽略时是否加上自定义的简单词
+ let ignoreList = [store.allIgnoreWords, store.knownWords][settingStore.ignoreSimpleWord ? 0 : 1]
+ const perDay = dict.perDayStudyNumber;
let start = dict.lastLearnIndex;
- let end = start + dict.perDayStudyNumber
-
- if (dict.complete) {
+ let complete = dict.complete;
+ if (isTest) {
+ start = 1
+ complete = true
+ }
+ let end = start
+ let list = dict.words.slice(start)
+ if (complete) {
//如果是已完成,那么把应该学的新词放到复习词组里面
- dict.words.slice(start, end).map(item => {
- if (!store.knownWords.includes(item.word)) {
- data.review.push(item)
+ for (let item of list) {
+ if (!ignoreList.includes(item.word.toLowerCase())) {
+ if (data.review.length < perDay) {
+ data.review.push(item)
+ } else break
}
- })
- //如果起点index 减去总默写不足的话,那就直接从最后面取
- //todo 这里有空了,优化成往前滚动取值
- if (start - totalNeed < 0) {
- end = dict.length
- } else {
- end = start
+ end++
}
} else {
- dict.words.slice(start, end).map(item => {
- if (!store.knownWords.includes(item.word)) {
- data.new.push(item)
+ //从start往后取perDay个单词,作为当前练习单词
+ for (let item of list) {
+ if (!ignoreList.includes(item.word.toLowerCase())) {
+ if (data.new.length < perDay) {
+ data.new.push(item)
+ } else break
}
- })
- end = start
- start = start - dict.perDayStudyNumber
- if (start < 0) start = 0
- //取上一次学习的单词用于复习
- let list = getList(start, end)
- list.map(item => {
- if (!store.knownWords.includes(item.word)) {
- data.review.push(item)
+ end++
+ }
+ //从start往前取perDay个单词,作为当前复习单词,取到0为止
+ list = dict.words.slice(0, start).toReversed()
+ for (let item of list) {
+ if (!ignoreList.includes(item.word.toLowerCase())) {
+ if (data.review.length < perDay) {
+ data.review.push(item)
+ } else break
}
- })
-
- end = start
+ start--
+ }
}
- // console.log(start,end)
- // 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的,越靠前的取的单词越多。
// 上上次更早的单词
- if (end > 0) {
- const allWords = dict.words;
- const candidateWords = allWords.slice(0, end).filter(w => !store.knownWords.includes(w.word));
+ //默认只取start之前的单词
+ let candidateWords = dict.words.slice(0, start).toReversed()
+ //但如果已完成,则滚动取值
+ if (complete) candidateWords = candidateWords.concat(dict.words.slice(end).toReversed())
+ candidateWords = candidateWords.filter(w => !ignoreList.includes(w.word.toLowerCase()));
+ // console.log(candidateWords.map(v => v.word))
+ //最终要获取的单词数量
+ const totalNeed = perDay * 3;
+ if (candidateWords.length <= totalNeed) {
+ data.write = candidateWords
+ } else {
+ //write数组放的是上上次之前的单词,总的数量为perDayStudyNumber * 3,取单词的规则为:从后往前取6个perDayStudyNumber的,越靠前的取的单词越多。
+ let days = 6
+ // 分6组,每组最多 perDay 个
+ const groups: Word[][] = splitIntoN(candidateWords.slice(0, days * perDay), 6)
+ // console.log('groups', groups)
- // 分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];
+ // 分配数量,靠前组多,靠后组少,例如分配比例 [6,5,4,3,2,1]
+ const ratio = Array.from({length: days}, (_, i) => i + 1).reverse();
const ratioSum = ratio.reduce((a, b) => a + b, 0);
- const realRatio = ratio.map(r => Math.round(r * totalNeed / ratioSum));
+ const realRatio = ratio.map(r => Math.round(r / ratioSum * totalNeed));
+ // console.log(ratio, ratioSum, realRatio, realRatio.reduce((a, b) => a + b, 0))
- // 按比例从每组取单词
+ // 按比例从每组随机取单词
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();
+ groups.map((v, i) => {
+ writeWords = writeWords.concat(getRandomN(v, realRatio[i]))
+ })
+ // console.log('writeWords', writeWords)
+ data.write = writeWords;
}
}
- // console.timeEnd()
- // console.log('data', data)
+ // console.log('data-new', data.new.map(v => v.word))
+ // console.log('data-review', data.review.map(v => v.word))
+ // console.log('data-write', data.write.map(v => v.word))
return data
}
diff --git a/src/pages/pc/article/StudyArticle.vue b/src/pages/pc/article/StudyArticle.vue
index 8fface4d..f1510933 100644
--- a/src/pages/pc/article/StudyArticle.vue
+++ b/src/pages/pc/article/StudyArticle.vue
@@ -157,7 +157,7 @@ function setArticle(val: Article) {
articleData.article.sections.map((v, i) => {
v.map((w, j) => {
w.words.map(s => {
- if (!store.knownWordsWithSimpleWords.includes(s.word.toLowerCase()) && !s.isSymbol) {
+ if (!store.allIgnoreWords.includes(s.word.toLowerCase()) && !s.isSymbol) {
statisticsStore.total++
}
})
@@ -199,13 +199,13 @@ function wrong(word: Word) {
if (!store.wrong.words.find((v: Word) => v.word.toLowerCase() === lowerName)) {
store.wrong.words.push(word)
}
- if (!store.knownWordsWithSimpleWords.includes(lowerName)) {
+ if (!store.allIgnoreWords.includes(lowerName)) {
//todo
}
}
function nextWord(word: ArticleWord) {
- if (!store.knownWordsWithSimpleWords.includes(word.word.toLowerCase()) && !word.isSymbol) {
+ if (!store.allIgnoreWords.includes(word.word.toLowerCase()) && !word.isSymbol) {
statisticsStore.inputWordNumber++
}
}
diff --git a/src/pages/pc/article/components/TypingArticle.vue b/src/pages/pc/article/components/TypingArticle.vue
index cd4535cd..8793478d 100644
--- a/src/pages/pc/article/components/TypingArticle.vue
+++ b/src/pages/pc/article/components/TypingArticle.vue
@@ -160,7 +160,7 @@ function nextSentence() {
input = wrong = ''
//todo 计得把略过的单词加上统计里面去
- // if (!store.knownWordsWithSimpleWords.includes(currentWord.word.toLowerCase()) && !currentWord.isSymbol) {
+ // if (!store.allIgnoreWords.includes(currentWord.word.toLowerCase()) && !currentWord.isSymbol) {
// statisticsStore.inputNumber++
// }
diff --git a/src/pages/pc/components/base/Switch.vue b/src/pages/pc/components/base/Switch.vue
index a0b996ce..a3396fe2 100644
--- a/src/pages/pc/components/base/Switch.vue
+++ b/src/pages/pc/components/base/Switch.vue
@@ -1,15 +1,20 @@
+
+
+
+
{{ title }}
+
{{ mainTitle }}
+
+
+
+
+ {{ desc }}
+
+
+
diff --git a/src/pages/pc/word/WordHomePage.vue b/src/pages/pc/word/WordHomePage.vue
index a6d04aba..17de57c2 100644
--- a/src/pages/pc/word/WordHomePage.vue
+++ b/src/pages/pc/word/WordHomePage.vue
@@ -31,9 +31,9 @@ let currentStudy = $ref({
write: []
})
-//todo 当选完词返回时,计算今日任务时,还是老的词典
-onMounted(init)
-watch(() => store.load, init)
+watch(() => store.load, n => {
+ if (n) init()
+}, {immediate: true})
async function init() {
if (store.word.studyIndex >= 3) {
diff --git a/src/router.ts b/src/router.ts
index 8ef2457a..d1c90c1a 100644
--- a/src/router.ts
+++ b/src/router.ts
@@ -10,7 +10,7 @@ import StudyWord from "@/pages/pc/word/StudyWord.vue";
import BookDetail from "@/pages/pc/article/BookDetail.vue";
import DictList from "@/pages/pc/word/DictList.vue";
import BookList from "@/pages/pc/article/BookList.vue";
-import Setting from "@/pages/pc/Setting.vue";
+import Setting from "@/pages/pc/setting/Setting.vue";
export const routes: RouteRecordRaw[] = [
{
diff --git a/src/stores/base.ts b/src/stores/base.ts
index 331cfb01..8b0a785c 100644
--- a/src/stores/base.ts
+++ b/src/stores/base.ts
@@ -77,8 +77,8 @@ export const useBaseStore = defineStore('base', {
knownWords(): string[] {
return this.known.words.map((v: Word) => v.word.toLowerCase())
},
- knownWordsWithSimpleWords() {
- return this.known.words.map((v: Word) => v.word.toLowerCase()).concat(this.simpleWords)
+ allIgnoreWords() {
+ return this.known.words.map((v: Word) => v.word.toLowerCase()).concat(this.simpleWords.map((v: string) => v.toLowerCase()))
},
currentStudyWordDict(): Dict {
if (this.word.studyIndex >= 0) {
diff --git a/src/stores/setting.ts b/src/stores/setting.ts
index f8a484eb..75f889e3 100644
--- a/src/stores/setting.ts
+++ b/src/stores/setting.ts
@@ -22,7 +22,6 @@ export interface SettingState {
repeatCustomCount?: number,
dictation: boolean,
translate: boolean,
- detail: boolean,
showNearWord: boolean
ignoreCase: boolean
allowWordTip: boolean
@@ -36,17 +35,14 @@ export interface SettingState {
showPanel: boolean,
sideExpand: boolean,
theme: string,
- collapse: boolean,
- chapterWordNumber: number,
shortcutKeyMap: Record,
first: boolean
firstTime: number
load: boolean
conflictNotice: boolean // 其他脚本/插件冲突提示
+ ignoreSimpleWord: boolean // 忽略简单词
}
-export const DefaultChapterWordNumber = 30
-
export const getDefaultSettingState = (): SettingState => ({
showToolbar: true,
show: false,
@@ -67,7 +63,6 @@ export const getDefaultSettingState = (): SettingState => ({
repeatCustomCount: null,
dictation: false,
translate: true,
- detail: false,
showNearWord: true,
ignoreCase: true,
@@ -80,13 +75,12 @@ export const getDefaultSettingState = (): SettingState => ({
},
waitTimeForChangeWord: 300,
theme: 'auto',
- collapse: false,
- chapterWordNumber: DefaultChapterWordNumber,
shortcutKeyMap: cloneDeep(DefaultShortcutKeyMap),
first: true,
firstTime: Date.now(),
load: false,
- conflictNotice: true
+ conflictNotice: true,
+ ignoreSimpleWord: false
})
export const useSettingStore = defineStore('setting', {
diff --git a/src/utils/const.ts b/src/utils/const.ts
index 98e4043a..9012407d 100644
--- a/src/utils/const.ts
+++ b/src/utils/const.ts
@@ -14,7 +14,7 @@ export const SAVE_DICT_KEY = {
}
export const SAVE_SETTING_KEY = {
key: 'typing-word-setting',
- version: 9
+ version: 10
}
export const EXPORT_DATA_KEY = {
key: 'typing-word-export',
diff --git a/src/utils/index.ts b/src/utils/index.ts
index 0d769404..d29c5c76 100644
--- a/src/utils/index.ts
+++ b/src/utils/index.ts
@@ -587,3 +587,30 @@ export function groupBy>(array: T[], key: string)
return result;
}, {});
}
+
+//随机取N个
+export function getRandomN(arr: any[], n: number) {
+ const copy = [...arr]
+ for (let i = copy.length - 1; i > 0; i--) {
+ const j = Math.floor(Math.random() * (i + 1));
+ [copy[i], copy[j]] = [copy[j], copy[i]] // 交换
+ }
+ return copy.slice(0, n)
+}
+
+//数组分成N份
+export function splitIntoN(arr: any[], n: number) {
+ const result = []
+ const len = arr.length
+ const base = Math.floor(len / n) // 每份至少这么多
+ let extra = len % n // 前几份多 1 个
+
+ let index = 0
+ for (let i = 0; i < n; i++) {
+ const size = base + (extra > 0 ? 1 : 0)
+ result.push(arr.slice(index, index + size))
+ index += size
+ if (extra > 0) extra--
+ }
+ return result
+}