feat:修改默写单词计算逻辑,修改统计组件
This commit is contained in:
1
components.d.ts
vendored
1
components.d.ts
vendored
@@ -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']
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -38,7 +38,7 @@ onMounted(() => {
|
||||
|
||||
useEvents([
|
||||
[EventKey.changeDict, getCurrentPractice],
|
||||
[EventKey.next, next],
|
||||
[EventKey.continueStudy, next],
|
||||
[ShortcutKey.NextChapter, next],
|
||||
])
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -455,7 +455,7 @@ let showQuestions = $ref(false)
|
||||
<div class="options flex justify-center" v-if="isEnd">
|
||||
<BaseButton
|
||||
v-if="store.currentBook.lastLearnIndex < store.currentBook.articles.length - 1"
|
||||
@click="emitter.emit(EventKey.next)">下一章
|
||||
@click="emitter.emit(EventKey.continueStudy)">下一章
|
||||
</BaseButton>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -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">
|
||||
<IconWrapper>
|
||||
<Icon @click="emitter.emit(EventKey.next)" icon="octicon:arrow-right-24"/>
|
||||
<Icon @click="emitter.emit(EventKey.continueStudy)" icon="octicon:arrow-right-24"/>
|
||||
</IconWrapper>
|
||||
</Tooltip>
|
||||
</div>
|
||||
|
||||
@@ -19,6 +19,7 @@ export interface ModalProps {
|
||||
confirmButtonText?: string
|
||||
cancelButtonText?: string,
|
||||
keyboard?: boolean,
|
||||
closeOnClickBg?: boolean,
|
||||
confirm?: any
|
||||
beforeClose?: any
|
||||
}
|
||||
@@ -26,6 +27,7 @@ export interface ModalProps {
|
||||
const props = withDefaults(defineProps<ModalProps>(), {
|
||||
modelValue: undefined,
|
||||
showClose: true,
|
||||
closeOnClickBg: true,
|
||||
fullScreen: false,
|
||||
footer: false,
|
||||
header: true,
|
||||
@@ -148,7 +150,7 @@ async function cancel() {
|
||||
<div class="modal-mask"
|
||||
ref="maskRef"
|
||||
v-if="!fullScreen"
|
||||
@click.stop="close"></div>
|
||||
@click.stop="closeOnClickBg && close()"></div>
|
||||
<div class="modal"
|
||||
ref="modalRef"
|
||||
:class="[
|
||||
|
||||
@@ -3,35 +3,68 @@ import Dialog from "@/pages/pc/components/dialog/Dialog.vue";
|
||||
import {useBaseStore} from "@/stores/base.ts";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import {ShortcutKey} from "@/types.ts";
|
||||
import {emitter, EventKey, useEvent, useEvents} from "@/utils/eventBus.ts";
|
||||
import {emitter, EventKey, useEvents} from "@/utils/eventBus.ts";
|
||||
import {Icon} from '@iconify/vue';
|
||||
import {useSettingStore} from "@/stores/setting.ts";
|
||||
import {usePracticeStore} from "@/stores/practice.ts";
|
||||
import {dayjs} from "element-plus";
|
||||
import dayjs from "dayjs";
|
||||
import isBetween from "dayjs/plugin/isBetween";
|
||||
import {watch} from "vue";
|
||||
|
||||
dayjs.extend(isBetween);
|
||||
|
||||
const store = useBaseStore()
|
||||
const settingStore = useSettingStore()
|
||||
const statStore = usePracticeStore()
|
||||
let open = $ref(false)
|
||||
const model = defineModel({default: false})
|
||||
let list = $ref([])
|
||||
|
||||
useEvent(EventKey.openStatModal, () => {
|
||||
let data = {
|
||||
speed: statStore.speed,
|
||||
startDate: statStore.startDate,
|
||||
total: statStore.total,
|
||||
wrong: statStore.wrong,
|
||||
|
||||
function calcWeekList() {
|
||||
// 获取本周的起止时间
|
||||
const startOfWeek = dayjs().startOf('week').add(1, 'day'); // 周一
|
||||
const endOfWeek = dayjs().endOf('week').add(1, 'day'); // 周日
|
||||
// 初始化 7 天的数组,默认 false
|
||||
const weekList = Array(7).fill(false);
|
||||
|
||||
store.sdict.statistics.forEach(item => {
|
||||
const date = dayjs(item.startDate);
|
||||
if (date.isBetween(startOfWeek, endOfWeek, null, '[]')) {
|
||||
let idx = date.day();
|
||||
// dayjs().day() 0=周日, 1=周一, ..., 6=周六
|
||||
// 需要转换为 0=周一, ..., 6=周日
|
||||
if (idx === 0) {
|
||||
idx = 6; // 周日放到最后
|
||||
} else {
|
||||
idx = idx - 1; // 其余前移一位
|
||||
}
|
||||
weekList[idx] = true;
|
||||
}
|
||||
});
|
||||
list = weekList;
|
||||
console.log(list)
|
||||
}
|
||||
|
||||
// 监听 model 弹窗打开时重新计算
|
||||
watch(model, (newVal) => {
|
||||
if (newVal) {
|
||||
let data = {
|
||||
speed: statStore.speed,
|
||||
startDate: statStore.startDate,
|
||||
total: statStore.total,
|
||||
wrong: statStore.wrong,
|
||||
}
|
||||
//这里不知为啥会卡,打开有延迟
|
||||
requestIdleCallback(() => {
|
||||
store.sdict.lastLearnIndex = store.sdict.lastLearnIndex + statStore.newWordNumber
|
||||
store.sdict.statistics.push(data as any)
|
||||
store.sdict.statistics.sort((a, b) => a.startDate - b.startDate)
|
||||
calcWeekList(); // 新增:计算本周学习记录
|
||||
})
|
||||
}
|
||||
store.sdict.lastLearnIndex = store.sdict.lastLearnIndex + statStore.newWordNumber
|
||||
store.sdict.statistics.push(data as any)
|
||||
store.sdict.statistics.sort((a, b) => a.startDate - b.startDate)
|
||||
|
||||
console.log('staa', JSON.parse(JSON.stringify(store.sdict.statistics)))
|
||||
open = true
|
||||
})
|
||||
|
||||
const close = () => {
|
||||
open = false
|
||||
}
|
||||
const close = () => model.value = false
|
||||
|
||||
useEvents([
|
||||
[ShortcutKey.NextChapter, close],
|
||||
@@ -39,8 +72,8 @@ useEvents([
|
||||
[ShortcutKey.DictationChapter, close],
|
||||
])
|
||||
|
||||
function options(emitType: 'write' | 'repeat' | 'next') {
|
||||
open = false
|
||||
function options(emitType: string) {
|
||||
model.value = false
|
||||
emitter.emit(EventKey[emitType])
|
||||
}
|
||||
|
||||
@@ -53,26 +86,29 @@ const isEnd = $computed(() => {
|
||||
|
||||
<template>
|
||||
<Dialog
|
||||
:close-on-click-bg="false"
|
||||
:header="false"
|
||||
v-model="open">
|
||||
<div class="statistics relative flex flex-col gap-6">
|
||||
:keyboard="false"
|
||||
:show-close="false"
|
||||
v-model="model">
|
||||
<div class="w-120 bg-white color-black p-6 relative flex flex-col gap-6">
|
||||
<div class="w-full flex flex-col justify-evenly">
|
||||
<div class="center text-xl mb-2">已完成今日任务</div>
|
||||
<div class="center text-2xl mb-2">已完成今日任务</div>
|
||||
<div class="flex">
|
||||
<div class="flex-1 flex flex-col items-center">
|
||||
<div class="text-sm color-gray">新词数</div>
|
||||
<div class="text-4xl font-bold">{{ statStore.newWordNumber }}</div>
|
||||
<div class="text">新词数</div>
|
||||
</div>
|
||||
<div class="flex-1 flex flex-col items-center">
|
||||
<div class="text-sm color-gray">复习数</div>
|
||||
<div class="text-4xl font-bold">{{ statStore.newWordNumber }}</div>
|
||||
<div class="text">复习数</div>
|
||||
</div>
|
||||
<div class="flex-1 flex flex-col items-center">
|
||||
<div class="text-sm color-gray">默写数</div>
|
||||
<div class="text-4xl font-bold">{{
|
||||
statStore.newWordNumber
|
||||
}}
|
||||
</div>
|
||||
<div class="text">默写数</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -102,31 +138,38 @@ const isEnd = $computed(() => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="center flex-col">
|
||||
<div class="title text-align-center mb-2">本周学习记录</div>
|
||||
<div class="flex gap-4 color-gray">
|
||||
<div
|
||||
class="w-8 h-8 rounded-full center"
|
||||
:class="item ? 'bg-green color-white' : 'bg-gray-200'"
|
||||
v-for="(item, i) in list"
|
||||
:key="i"
|
||||
>{{ i + 1 }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-center gap-4 ">
|
||||
<BaseButton
|
||||
:keyboard="settingStore.shortcutKeyMap[ShortcutKey.RepeatChapter]"
|
||||
@click="options('repeat')">
|
||||
@click="options(EventKey.repeatStudy)">
|
||||
重学
|
||||
</BaseButton>
|
||||
<BaseButton
|
||||
:keyboard="settingStore.shortcutKeyMap[ShortcutKey.NextChapter]"
|
||||
@click="options('next')">
|
||||
@click="options(EventKey.continueStudy)">
|
||||
{{ isEnd ? '重新练习' : '再来一组' }}
|
||||
</BaseButton>
|
||||
|
||||
<BaseButton>
|
||||
分享
|
||||
</BaseButton>
|
||||
</div>
|
||||
</div>
|
||||
</Dialog>
|
||||
</template>
|
||||
<style scoped lang="scss">
|
||||
$card-radius: .5rem;
|
||||
$dark-second-bg: rgb(60, 63, 65);
|
||||
$item-hover: rgb(75, 75, 75);
|
||||
|
||||
.statistics {
|
||||
padding: var(--space);
|
||||
width: 30rem;
|
||||
background: $dark-second-bg;
|
||||
border-radius: $card-radius;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
@@ -43,7 +43,7 @@ const store = useBaseStore()
|
||||
const statStore = usePracticeStore()
|
||||
const typingRef: any = $ref()
|
||||
let allWrongWords = new Set()
|
||||
|
||||
let showStatDialog = $ref(false)
|
||||
let studyData = $ref<IProps>({
|
||||
new: [],
|
||||
review: [],
|
||||
@@ -94,29 +94,32 @@ const nextWord: Word = $computed(() => {
|
||||
})
|
||||
|
||||
function next(isTyping: boolean = true) {
|
||||
showStatDialog = true
|
||||
return
|
||||
if (data.index === data.words.length - 1) {
|
||||
if (data.wrongWords.length) {
|
||||
console.log('学完了,但还有错词')
|
||||
console.log('当前学完了,但还有错词')
|
||||
data.words = shuffle(cloneDeep(data.wrongWords))
|
||||
data.index = 0
|
||||
data.wrongWords = []
|
||||
} else {
|
||||
console.log('学完了,没错词', statStore.total, statStore.step, data.index)
|
||||
console.log('当前学完了,没错词', statStore.total, statStore.step, data.index)
|
||||
isTyping && statStore.inputWordNumber++
|
||||
statStore.speed = Date.now() - statStore.startDate
|
||||
|
||||
//学完了
|
||||
if (statStore.step === 2) {
|
||||
console.log('emit')
|
||||
statStore.speed = Date.now() - statStore.startDate
|
||||
console.log('全完学完了')
|
||||
emitter.emit(EventKey.openStatModal, {})
|
||||
// emit('complete', {})
|
||||
}
|
||||
|
||||
//开始默认
|
||||
//开始默认所有单词
|
||||
if (statStore.step === 1) {
|
||||
console.log('开始默认所有单词')
|
||||
statStore.step++
|
||||
settingStore.dictation = true
|
||||
data.words = shuffle(studyData.write.concat(studyData.new).concat(studyData.review))
|
||||
statStore.step++
|
||||
data.index = 0
|
||||
}
|
||||
|
||||
@@ -124,6 +127,7 @@ function next(isTyping: boolean = true) {
|
||||
if (statStore.step === 0) {
|
||||
statStore.step++
|
||||
if (studyData.review.length) {
|
||||
console.log('开始复习')
|
||||
data.words = shuffle(studyData.review)
|
||||
settingStore.dictation = false
|
||||
data.index = 0
|
||||
@@ -145,18 +149,16 @@ function onTypeWrong() {
|
||||
allWrongWords.add(word.word.toLowerCase())
|
||||
statStore.wrong++
|
||||
}
|
||||
//todo 后续要测试有非常的多的错词时,这会还卡不卡
|
||||
setTimeout(() => {
|
||||
requestAnimationFrame(() => {
|
||||
if (!store.wrong.words.find((v: Word) => v.word.toLowerCase() === temp)) {
|
||||
store.wrong.words.push(word)
|
||||
store.wrong.length = store.wrong.words.length
|
||||
}
|
||||
if (!data.wrongWords.find((v: Word) => v.word.toLowerCase() === temp)) {
|
||||
data.wrongWords.push(word)
|
||||
}
|
||||
})
|
||||
}, 500)
|
||||
//测试时这里会卡一下,加上requestIdleCallback就好了
|
||||
requestIdleCallback(() => {
|
||||
if (!store.wrong.words.find((v: Word) => v.word.toLowerCase() === temp)) {
|
||||
store.wrong.words.push(word)
|
||||
store.wrong.length = store.wrong.words.length
|
||||
}
|
||||
if (!data.wrongWords.find((v: Word) => v.word.toLowerCase() === temp)) {
|
||||
data.wrongWords.push(word)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function onKeyUp(e: KeyboardEvent) {
|
||||
@@ -177,12 +179,16 @@ useStartKeyboardEventListener()
|
||||
|
||||
useOnKeyboardEventListener(onKeyDown, onKeyUp)
|
||||
|
||||
//TODO 需要判断是否已忽略
|
||||
function repeat() {
|
||||
// console.log('repeat')
|
||||
console.log('repeat')
|
||||
settingStore.dictation = false
|
||||
emitter.emit(EventKey.resetWord)
|
||||
studyData = cloneDeep(studyData)
|
||||
let temp = cloneDeep(studyData)
|
||||
//排除已掌握单词
|
||||
temp.new = temp.new.filter(v => !store.knownWords.includes(v.word))
|
||||
temp.review = temp.review.filter(v => !store.knownWords.includes(v.word))
|
||||
temp.write = temp.write.filter(v => !store.knownWords.includes(v.word))
|
||||
studyData = temp
|
||||
}
|
||||
|
||||
//TODO 略过忽略的单词上
|
||||
@@ -243,8 +249,8 @@ function togglePanel() {
|
||||
}
|
||||
|
||||
useEvents([
|
||||
[EventKey.repeat, repeat],
|
||||
[EventKey.next, next],
|
||||
[EventKey.repeatStudy, repeat],
|
||||
[EventKey.continueStudy, next],
|
||||
[EventKey.changeDict, () => {
|
||||
studyData = getCurrentStudyWord()
|
||||
}],
|
||||
@@ -354,7 +360,9 @@ useEvents([
|
||||
</Panel>
|
||||
</div>
|
||||
</div>
|
||||
<Statistics/>
|
||||
<Statistics v-model="showStatDialog"
|
||||
|
||||
/>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
@@ -155,18 +155,16 @@ function toggleSelect(item) {
|
||||
<div class="flex">
|
||||
<div class="flex-1 flex flex-col items-center">
|
||||
<div class="text-4xl font-bold">{{ currentStudy.new.length }}</div>
|
||||
<div class="text">新词数</div>
|
||||
<div class="text">新词</div>
|
||||
</div>
|
||||
<div class="flex-1 flex flex-col items-center">
|
||||
<div class="text-4xl font-bold">{{ currentStudy.review.length }}</div>
|
||||
<div class="text">复习数</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 class="text-4xl font-bold">{{ currentStudy.write.length }}
|
||||
</div>
|
||||
<div class="text">默写数</div>
|
||||
<div class="text">默写</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -105,6 +105,9 @@ export const useBaseStore = defineStore('base', {
|
||||
known(): Dict {
|
||||
return this.word.bookList[2]
|
||||
},
|
||||
knownWords(): string[] {
|
||||
return this.known.words.map(v => v.word)
|
||||
},
|
||||
skipWordNames() {
|
||||
return this.simple.words.map(v => v.word.toLowerCase())
|
||||
},
|
||||
|
||||
@@ -14,8 +14,8 @@ export const EventKey = {
|
||||
keydown: 'keydown',
|
||||
keyup: 'keyup',
|
||||
onTyping: 'onTyping',
|
||||
repeat: 'repeat',
|
||||
next: 'next',
|
||||
repeatStudy: 'repeatStudy',
|
||||
continueStudy: 'continueStudy',
|
||||
write: 'write',
|
||||
editDict: 'editDict',
|
||||
openMyDictDialog: 'openMyDictDialog',
|
||||
|
||||
Reference in New Issue
Block a user