This commit is contained in:
zyronon
2024-05-31 02:31:38 +08:00
parent b9a35f5c6d
commit ce07e9e20e
10 changed files with 4307 additions and 5061 deletions

9141
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
import {Article, Dict, DictType, Word} from "@/types.ts";
import {useBaseStore} from "@/stores/base.ts";
import {useRuntimeStore} from "@/stores/runtime.ts";
import {chunk, cloneDeep} from "lodash-es";
import {chunk, cloneDeep, shuffle} from "lodash-es";
import {isArticle} from "@/hooks/article.ts";
import {nanoid} from "nanoid";
@@ -109,24 +109,60 @@ export function syncMyDictList(dict: Dict, isCustom = true) {
}
export function getCurrentStudyWord() {
console.time()
const store = useBaseStore()
let data = {new: [], review: []}
let data = {new: [], review: [], write: []}
let c = store.currentStudy.word
let dict = store.currentStudyWordDict;
if (dict.words?.length) {
for (let i = c.lastLearnIndex; i < dict.words.length; i++) {
if (data.new.length >= c.perDayStudyNumber) break
let item = dict.words[i]
if (!store.skipWordNames.includes(item.word.toLowerCase())) {
if (!store.simple2.map(v => v.word.toLowerCase()).includes(item.word.toLowerCase())) {
data.new.push(item)
}
}
if (dict.statistics.length) {
let stat = dict.statistics.reverse()
stat.slice(0, 1).map(({startIndex, endIndex}) => {
let list = dict.words.splice(startIndex, endIndex)
})
const getList = (startIndex, endIndex) => {
if (startIndex < 0) return []
return dict.words.slice(startIndex, endIndex)
}
let s = c.lastLearnIndex - c.perDayStudyNumber
let e = c.lastLearnIndex
//取上一次学习的单词用于复习
let list = getList(s, e)
list.map(item => {
if (!store.master.map(v => v.word.toLowerCase()).includes(item.word.toLowerCase())) {
data.review.push(item)
}
})
data.review = shuffle(data.review)
//取前天至再往前数3天的单词用于默写
Array.from({length: 4}).map((_, j) => {
e = s
s -= c.perDayStudyNumber
list = getList(s, e)
let d = []
for (let i = 0; i < list.length; i++) {
if (j === 3) {
if (d.length >= c.perDayStudyNumber - data.write.length) break
} else {
if (d.length >= Math.floor(c.perDayStudyNumber / 4)) break
}
let item = list[i]
if (!store.master.map(v => v.word.toLowerCase()).includes(item.word.toLowerCase())) {
d.push(item)
}
}
data.write = data.write.concat(d)
})
data.write = shuffle(data.write)
}
console.timeEnd()
console.log('data', data)
return data
}

View File

@@ -63,7 +63,7 @@ export function useStartKeyboardEventListener() {
for (let i = 0; i < list.length; i++) {
let [k, v] = list[i]
if (v === shortcutKey) {
console.log('快捷键', k)
// console.log('快捷键', k)
shortcutEvent = k
break
}

View File

@@ -121,7 +121,7 @@ let show = $ref(false)
}
.aside {
background: white;
background: var(--color-second-bg);
position: fixed;
z-index: 999;
top: 0;

View File

@@ -21,14 +21,20 @@ let open = $ref(false)
onMounted(() => {
emitter.on(EventKey.openStatModal, () => {
let data = {
startIndex: store.sword.lastLearnIndex,
endIndex: store.sword.lastLearnIndex + store.sword.perDayStudyNumber,
speed: statStore.speed,
startDate: statStore.startDate,
}
store.sword.lastLearnIndex = data.endIndex
store.currentStudyWordDict.statistics.push(data as any)
store.currentStudyWordDict.statistics.sort((a, b) => a.startDate - b.startDate)
console.log('staa', JSON.parse(JSON.stringify(store.currentStudyWordDict.statistics)))
open = true
})
let data = cloneDeep(statStore)
delete data.step
delete data.correctRate
store.currentStudyWordDict.statistics.push(data as any)
const close = () => {
open = false
}

View File

@@ -24,6 +24,7 @@ interface IProps {
data: {
new: any[],
review: any[],
write: any[],
}
}
@@ -31,6 +32,7 @@ const props = withDefaults(defineProps<IProps>(), {
data: {
new: [],
review: [],
write: [],
}
})
@@ -43,7 +45,7 @@ const emit = defineEmits<{
const typingRef: any = $ref()
const store = useBaseStore()
const runtimeStore = useRuntimeStore()
const statisticsStore = usePracticeStore()
const statStore = usePracticeStore()
const settingStore = useSettingStore()
const {
@@ -69,14 +71,14 @@ watch(() => props.data, () => {
current.wrongWords = []
allWrongWords = []
statisticsStore.step = 0
statisticsStore.startDate = Date.now()
statisticsStore.correctRate = -1
statisticsStore.inputWordNumber = 0
statisticsStore.wrongWordNumber = 0
statisticsStore.total = props.data.review.concat(props.data.new).length
statisticsStore.newWordNumber = props.data.new.length
statisticsStore.index = 0
statStore.step = 0
statStore.startDate = Date.now()
statStore.correctRate = -1
statStore.inputWordNumber = 0
statStore.wrongWordNumber = 0
statStore.total = props.data.review.concat(props.data.new).length
statStore.newWordNumber = props.data.new.length
statStore.index = 0
}, {immediate: true, deep: true})
const word = $computed(() => {
@@ -99,23 +101,37 @@ function next(isTyping: boolean = true) {
current.index = 0
current.wrongWords = []
} else {
console.log('学完了,没错词', statisticsStore.total)
isTyping && statisticsStore.inputWordNumber++
statisticsStore.speed = Date.now() - statisticsStore.startDate
if (statisticsStore.step) {
console.log('学完了,没错词', statStore.total, statStore.step,current.index,current.words)
isTyping && statStore.inputWordNumber++
statStore.speed = Date.now() - statStore.startDate
if (statStore.step === 2) {
emitter.emit(EventKey.openStatModal, {})
// emit('complete', {})
} else {
}
if (statStore.step === 1) {
settingStore.dictation = true
statisticsStore.step++
current.words = shuffle(props.data.review.concat(props.data.new))
current.words = props.data.write.concat(props.data.new).concat(props.data.review)
statStore.step++
current.index = 0
}
if (statStore.step === 0) {
statStore.step++
if (props.data.review.length) {
current.words = props.data.review
settingStore.dictation = false
current.index = 0
} else {
next()
}
}
}
} else {
current.index++
isTyping && statisticsStore.inputWordNumber++
console.log('这个词完了')
isTyping && statStore.inputWordNumber++
// console.log('这个词完了')
}
}
@@ -128,7 +144,7 @@ function wordWrong() {
}
if (!allWrongWords.find((v: Word) => v.word.toLowerCase() === word.word.toLowerCase())) {
allWrongWords.push(word)
statisticsStore.wrongWordNumber++
statStore.wrongWordNumber++
}
}
@@ -264,8 +280,10 @@ onUnmounted(() => {
>
<div class="list-header">
<div>
{{ statisticsStore.step ? '复习' : '学习'}}
{{ current.words.length }}个单词</div>
{{ statStore.step }}
{{ statStore.step ? '复习' : '学习' }}
{{ current.words.length }}个单词
</div>
<div style="position:relative;"
@click.stop="null">
<BaseIcon

View File

@@ -18,24 +18,23 @@ import TypingWord from "@/pages/pc/practice/practice-word/TypingWord.vue";
import {getCurrentStudyWord, syncMyDictList} from "@/hooks/dict.ts";
import {cloneDeep, shuffle} from "lodash-es";
const statisticsStore = usePracticeStore()
const statStore = usePracticeStore()
const store = useBaseStore()
const settingStore = useSettingStore()
const runtimeStore = useRuntimeStore()
const {toggleTheme} = useTheme()
watch(statisticsStore, () => {
if (statisticsStore.inputWordNumber < 1) {
return statisticsStore.correctRate = -1
watch(statStore, () => {
if (statStore.inputWordNumber < 1) {
return statStore.correctRate = -1
}
if (statisticsStore.wrongWordNumber > statisticsStore.inputWordNumber) {
return statisticsStore.correctRate = 0
if (statStore.wrongWordNumber > statStore.inputWordNumber) {
return statStore.correctRate = 0
}
statisticsStore.correctRate = 100 - Math.trunc(((statisticsStore.wrongWordNumber) / (statisticsStore.inputWordNumber)) * 100)
statStore.correctRate = 100 - Math.trunc(((statStore.wrongWordNumber) / (statStore.inputWordNumber)) * 100)
})
function next() {
store.currentStudy.word.lastLearnIndex = store.currentStudy.word.lastLearnIndex + store.currentStudy.word.perDayStudyNumber
emitter.emit(EventKey.resetWord)
getCurrentPractice()
}
@@ -104,7 +103,9 @@ onUnmounted(() => {
onMounted(() => {
settingStore.dictation = false
data = runtimeStore.routeData
if (runtimeStore.routeData) {
data = runtimeStore.routeData
}
emitter.on(EventKey.changeDict, getCurrentPractice)
})

View File

@@ -10,8 +10,11 @@ import BasePage from "@/pages/pc/components/BasePage.vue";
import {getDefaultDict} from "@/types.ts";
import {onMounted} from "vue";
import {getCurrentStudyWord} from "@/hooks/dict.ts";
import {c} from "vite/dist/node/types.d-aGj9QkWt";
import {usePracticeStore} from "@/stores/practice.ts";
const store = useBaseStore()
const statStore = usePracticeStore()
const router = useRouter()
const {nav} = useNav()
@@ -28,13 +31,18 @@ const otherWordDictList = $computed(() => {
let currentStudy = $ref({
new: [],
review: []
review: [],
write: []
})
onMounted(() => {
currentStudy = getCurrentStudyWord()
})
function study(){
nav('study-word',{},currentStudy)
}
</script>
<template>
@@ -92,11 +100,17 @@ onMounted(() => {
<div class="text-4xl font-bold">{{ currentStudy.review.length }}</div>
<div class="text">复习数</div>
</div>
<div class="flex-1 flex flex-col items-center">
<div class="text-4xl font-bold">{{
currentStudy.new.length + currentStudy.review.length + currentStudy.write.length
}}</div>
<div class="text">默写数</div>
</div>
</div>
</div>
<div class="">
<div class="rounded-xl bg-slate-800 flex items-center gap-2 py-3 px-5 text-white cursor-pointer"
@click="nav('study-word',{},currentStudy)">
@click="study">
<span>开始学习</span>
<Icon icon="icons8:right-round" class="text-2xl"/>
</div>
@@ -178,7 +192,8 @@ onMounted(() => {
<style scoped lang="scss">
.card {
@apply rounded-xl bg-white p-4 mt-5;
@apply rounded-xl p-4 mt-5;
background: var(--color-second-bg);
}
.center {

View File

@@ -130,13 +130,14 @@ export const DefaultBaseState = (): BaseState => ({
length: 2607,
translateLanguage: 'common',
language: 'en',
type: DictType.word
type: DictType.word,
statistics: []
},
],
currentStudy: {
word: {
dictIndex: 0,
perDayStudyNumber: 5,
perDayStudyNumber: 20,
lastLearnIndex: 0,
},
article: {
@@ -265,6 +266,9 @@ export const useBaseStore = defineStore('base', {
currentStudyWordDict(): Dict {
return this.wordDictList[this.currentStudy.word.dictIndex] ?? getDefaultDict()
},
sword() {
return this.currentStudy.word
},
currentStudyWordProgress(): number {
if (!this.currentStudyWordDict.words?.length) return 0
return Number(((this.currentStudy.word.lastLearnIndex / this.currentStudyWordDict.words?.length) * 100).toFixed())
@@ -313,54 +317,25 @@ export const useBaseStore = defineStore('base', {
} catch (e) {
console.error('读取本地dict数据失败', e)
}
const runtimeStore = useRuntimeStore()
//自定义的词典文章只删除了sections单词并未做删除所以这里不需要处理
if (this.currentDict.isCustom) {
if (this.current.index < 3) {
//前三本词典的isCustom为true。数据全都保存了不需要处理了
} else {
//自定义的词典文章只删除了sections单词并未做删除所以这里不需要处理
if (this.currentDict.isCustom) {
} else {
//处理非自定义的情况。
let dictResourceUrl = `./dicts/${this.currentDict.language}/${this.currentDict.type}/${this.currentDict.translateLanguage}/${this.currentDict.url}`;
if ([DictType.word].includes(this.currentDict.type)) {
if (!this.currentDict.originWords.length) {
let v = await getDictFile(dictResourceUrl)
// v = v.slice(0, 50)
v.map(s => {
s.id = nanoid(6)
})
this.currentDict.originWords = cloneDeep(v)
this.currentDict.words = cloneDeep(v)
this.currentDict.chapterWords = chunk(this.currentDict.words, this.currentDict.chapterWordNumber)
}
}
if ([DictType.article].includes(this.currentDict.type)) {
if (!this.currentDict.articles.length) {
let s = await getDictFile(dictResourceUrl)
this.currentDict.articles = cloneDeep(s.map(v => {
v.id = nanoid(6)
return v
}))
}
}
}
}
let currentDict = this.wordDictList[this.currentStudy.word.dictIndex]
let dictResourceUrl = `./dicts/${currentDict.language}/${currentDict.type}/${currentDict.translateLanguage}/${currentDict.url}`;
if (!currentDict.originWords.length) {
if (!currentDict.words.length) {
let v = await getDictFile(dictResourceUrl)
// v = v.slice(0, 50)
v.map(s => {
s.id = nanoid(6)
})
currentDict.originWords = cloneDeep(v)
currentDict.words = cloneDeep(v)
currentDict.chapterWords = chunk(currentDict.words, currentDict.chapterWordNumber)
// currentDict.originWords = cloneDeep(v)
// currentDict.words = cloneDeep(v)
currentDict.words = Object.freeze(v)
}
currentDict = this.articleDictList[this.currentStudy.article.dictIndex]
@@ -373,7 +348,7 @@ export const useBaseStore = defineStore('base', {
}))
}
console.log('this.wordDictList', this.articleDictList)
console.log('this.wordDictList', this.wordDictList[0].words[0])
emitter.emit(EventKey.changeDict)
resolve(true)
})

View File

@@ -10,6 +10,8 @@ export interface PracticeState {
inputWordNumber: number,//当前总输入了多少个单词(不包含跳过)
wrongWordNumber: number,
correctRate: number,
startIndex:number,
endIndex:number,
}
export const usePracticeStore = defineStore('practice', {
@@ -21,6 +23,8 @@ export const usePracticeStore = defineStore('practice', {
correctRate: -1,
total: 0,
index: 0,
startIndex: 0,
endIndex: 0,
newWordNumber: 0,
inputWordNumber: 0,
wrongWordNumber: 0,