Modify the name field of word
This commit is contained in:
@@ -22,7 +22,7 @@ en2zh_CN.map(v => {
|
||||
if (rIndex === -1) {
|
||||
// let data = {
|
||||
// id: allNew.length,
|
||||
// word: v.name,
|
||||
// word: v.word,
|
||||
// phonetic0: v.usphone,
|
||||
// phonetic1: v.ukphone,
|
||||
// trans: []
|
||||
@@ -46,7 +46,7 @@ en2zh_CN.map(v => {
|
||||
// }
|
||||
|
||||
// allNew.push()
|
||||
// minNew.push(v.name)
|
||||
// minNew.push(v.word)
|
||||
|
||||
if (!v.name.includes(' ')){
|
||||
notContain.push(v.name)
|
||||
|
||||
@@ -28,7 +28,7 @@ onMounted(() => {
|
||||
if (!w.trans.length) {
|
||||
requestIdleCallback(() => {
|
||||
if (list.length) {
|
||||
let res = runtimeStore.translateWordList.find(a => a.name === w.name)
|
||||
let res = runtimeStore.translateWordList.find(a => a.word === w.word)
|
||||
if (res) w = Object.assign(w, res)
|
||||
count++
|
||||
if (count === list.length) {
|
||||
|
||||
@@ -48,7 +48,7 @@ defineExpose({scrollToBottom, scrollToItem})
|
||||
</template>
|
||||
<template v-slot="{ item, index }">
|
||||
<div class="item-title">
|
||||
<span class="word" :class="!showWord && 'text-shadow'">{{ item.name }}</span>
|
||||
<span class="word" :class="!showWord && 'text-shadow'">{{ item.word }}</span>
|
||||
<span class="phonetic">{{ item.usphone }}</span>
|
||||
<VolumeIcon class="volume" @click="playWordAudio(item.name)"></VolumeIcon>
|
||||
</div>
|
||||
|
||||
@@ -74,7 +74,7 @@ export function splitEnArticle(text: string): { sections: Sentence[][], newText:
|
||||
|
||||
let word3: ArticleWord = {
|
||||
...DefaultArticleWord,
|
||||
name: pre,
|
||||
word: pre,
|
||||
nextSpace: false,
|
||||
isSymbol: true,
|
||||
symbolPosition: ''
|
||||
@@ -194,7 +194,7 @@ export function splitEnArticle(text: string): { sections: Sentence[][], newText:
|
||||
})
|
||||
|
||||
//去除空格占位符
|
||||
sentence.words = sentence.words.filter(v => v.name !== 'placeholder')
|
||||
sentence.words = sentence.words.filter(v => v.word !== 'placeholder')
|
||||
})
|
||||
})
|
||||
|
||||
@@ -202,7 +202,7 @@ export function splitEnArticle(text: string): { sections: Sentence[][], newText:
|
||||
sections.map((sectionItem, a) => {
|
||||
sectionItem.map((sentenceItem, b) => {
|
||||
sentenceItem.text = sentenceItem.words.reduce((previousValue: string, currentValue) => {
|
||||
previousValue += currentValue.name + (currentValue.nextSpace ? ' ' : '')
|
||||
previousValue += currentValue.word + (currentValue.nextSpace ? ' ' : '')
|
||||
return previousValue
|
||||
}, '')
|
||||
})
|
||||
|
||||
@@ -11,15 +11,15 @@ export function useWordOptions() {
|
||||
const store = useBaseStore()
|
||||
|
||||
function isWordCollect(val: Word) {
|
||||
return !!store.collect.originWords.find(v => v.name.toLowerCase() === val.name.toLowerCase())
|
||||
return !!store.collect.originWords.find(v => v.word.toLowerCase() === val.word.toLowerCase())
|
||||
}
|
||||
|
||||
function toggleWordCollect(val: Word) {
|
||||
let rIndex = store.collect.originWords.findIndex(v => v.name.toLowerCase() === val.name.toLowerCase())
|
||||
let rIndex = store.collect.originWords.findIndex(v => v.word.toLowerCase() === val.word.toLowerCase())
|
||||
if (rIndex > -1) {
|
||||
store.collect.originWords.splice(rIndex, 1)
|
||||
} else {
|
||||
let rIndex = store.simple.originWords.findIndex(v => v.name.toLowerCase() === val.name.toLowerCase())
|
||||
let rIndex = store.simple.originWords.findIndex(v => v.word.toLowerCase() === val.word.toLowerCase())
|
||||
if (rIndex > -1) {
|
||||
store.simple.originWords.splice(rIndex, 1)
|
||||
}
|
||||
@@ -30,15 +30,15 @@ export function useWordOptions() {
|
||||
}
|
||||
|
||||
function isWordSimple(val: Word) {
|
||||
return !!store.simple.originWords.find(v => v.name.toLowerCase() === val.name.toLowerCase())
|
||||
return !!store.simple.originWords.find(v => v.word.toLowerCase() === val.word.toLowerCase())
|
||||
}
|
||||
|
||||
function toggleWordSimple(val: Word) {
|
||||
let rIndex = store.simple.originWords.findIndex(v => v.name.toLowerCase() === val.name.toLowerCase())
|
||||
let rIndex = store.simple.originWords.findIndex(v => v.word.toLowerCase() === val.word.toLowerCase())
|
||||
if (rIndex > -1) {
|
||||
store.simple.originWords.splice(rIndex, 1)
|
||||
} else {
|
||||
let rIndex = store.collect.originWords.findIndex(v => v.name.toLowerCase() === val.name.toLowerCase())
|
||||
let rIndex = store.collect.originWords.findIndex(v => v.word.toLowerCase() === val.word.toLowerCase())
|
||||
if (rIndex > -1) {
|
||||
store.collect.originWords.splice(rIndex, 1)
|
||||
}
|
||||
@@ -49,7 +49,7 @@ export function useWordOptions() {
|
||||
}
|
||||
|
||||
function delWrongWord(val: Word) {
|
||||
let rIndex = store.wrong.originWords.findIndex(v => v.name.toLowerCase() === val.name.toLowerCase())
|
||||
let rIndex = store.wrong.originWords.findIndex(v => v.word.toLowerCase() === val.word.toLowerCase())
|
||||
if (rIndex > -1) {
|
||||
store.wrong.originWords.splice(rIndex, 1)
|
||||
}
|
||||
@@ -57,7 +57,7 @@ export function useWordOptions() {
|
||||
}
|
||||
|
||||
function delSimpleWord(val: Word) {
|
||||
let rIndex = store.simple.originWords.findIndex(v => v.name.toLowerCase() === val.name.toLowerCase())
|
||||
let rIndex = store.simple.originWords.findIndex(v => v.word.toLowerCase() === val.word.toLowerCase())
|
||||
if (rIndex > -1) {
|
||||
store.simple.originWords.splice(rIndex, 1)
|
||||
}
|
||||
@@ -117,7 +117,7 @@ export async function checkDictHasTranslate(dict: Dict) {
|
||||
dict.words = cloneDeep(v)
|
||||
dict.chapterWords = chunk(dict.words, dict.chapterWordNumber)
|
||||
dict.chapterWords[dict.chapterIndex].map((w: Word) => {
|
||||
let res = list.find(a => a.name === w.name)
|
||||
let res = list.find(a => a.word === w.word)
|
||||
if (res) w = Object.assign(w, res)
|
||||
})
|
||||
} else {
|
||||
|
||||
@@ -34,7 +34,7 @@ let data = $ref({
|
||||
const word: Word = $computed(() => {
|
||||
return data.words[data.index] ?? {
|
||||
trans: [],
|
||||
name: '',
|
||||
word: '',
|
||||
usphone: '',
|
||||
ukphone: '',
|
||||
}
|
||||
@@ -47,7 +47,7 @@ function getCurrentPractice() {
|
||||
|
||||
store.chapter.map((w: Word) => {
|
||||
if (!w.trans.length) {
|
||||
let res = runtimeStore.translateWordList.find(a => a.name === w.name)
|
||||
let res = runtimeStore.translateWordList.find(a => a.word === w.word)
|
||||
if (res) w = Object.assign(w, res)
|
||||
}
|
||||
})
|
||||
@@ -118,7 +118,7 @@ function next(isTyping: boolean = true) {
|
||||
isTyping && practiceStore.inputWordNumber++
|
||||
console.log('这个词完了')
|
||||
if ([DictType.word].includes(store.currentDict.type)
|
||||
&& store.skipWordNames.includes(word.name.toLowerCase())) {
|
||||
&& store.skipWordNames.includes(word.word.toLowerCase())) {
|
||||
next()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,17 +141,17 @@ function next(isTyping: boolean = true) {
|
||||
isTyping && practiceStore.inputWordNumber++
|
||||
console.log('这个词完了')
|
||||
if ([DictType.word].includes(store.currentDict.type)
|
||||
&& store.skipWordNames.includes(word.name.toLowerCase())) {
|
||||
&& store.skipWordNames.includes(word.word.toLowerCase())) {
|
||||
next()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function wordWrong() {
|
||||
if (!store.wrong.originWords.find((v: Word) => v.name.toLowerCase() === word.name.toLowerCase())) {
|
||||
if (!store.wrong.originWords.find((v: Word) => v.word.toLowerCase() === word.word.toLowerCase())) {
|
||||
store.wrong.originWords.push(word)
|
||||
}
|
||||
if (!data.wrongWords.find((v: Word) => v.name.toLowerCase() === word.name.toLowerCase())) {
|
||||
if (!data.wrongWords.find((v: Word) => v.word.toLowerCase() === word.word.toLowerCase())) {
|
||||
data.wrongWords.push(word)
|
||||
practiceStore.wrongWordNumber++
|
||||
}
|
||||
|
||||
@@ -1,467 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import {onMounted, onUnmounted, watch} from "vue"
|
||||
import {$computed, $ref} from "vue/macros"
|
||||
import {useBaseStore} from "@/stores/base.ts"
|
||||
import {DefaultDisplayStatistics, DictType, ShortcutKey, Sort, Word} from "@/types.ts";
|
||||
import {emitter, EventKey} from "@/utils/eventBus.ts"
|
||||
import {cloneDeep, reverse, shuffle} from "lodash-es"
|
||||
import {usePracticeStore} from "@/stores/practice.ts"
|
||||
import {useSettingStore} from "@/stores/setting.ts";
|
||||
import {useOnKeyboardEventListener, useWindowClick} from "@/hooks/event.ts";
|
||||
import Typing from "@/pages/mobile/practice/practice-word/Typing.vue";
|
||||
import {useRuntimeStore} from "@/stores/runtime.ts";
|
||||
import {useWordOptions} from "@/hooks/dict.ts";
|
||||
import BaseIcon from "@/components/BaseIcon.vue";
|
||||
import WordList from "@/components/list/WordList.vue";
|
||||
import Empty from "@/components/Empty.vue";
|
||||
import MiniDialog from "@/components/dialog/MiniDialog.vue";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import SlideHorizontal from "@/components/slide/SlideHorizontal.vue";
|
||||
import SlideItem from "@/components/slide/SlideItem.vue";
|
||||
import MobilePanel from "@/pages/mobile/components/MobilePanel.vue";
|
||||
import router from "@/router.ts";
|
||||
import {Icon} from "@iconify/vue";
|
||||
|
||||
interface IProps {
|
||||
words: Word[],
|
||||
index: number,
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<IProps>(), {
|
||||
words: [],
|
||||
index: -1
|
||||
})
|
||||
|
||||
const emit = defineEmits<{
|
||||
'update:words': [val: Word[]],
|
||||
sort: [val: Word[]]
|
||||
}>()
|
||||
|
||||
const typingRef: any = $ref()
|
||||
const store = useBaseStore()
|
||||
const runtimeStore = useRuntimeStore()
|
||||
const practiceStore = usePracticeStore()
|
||||
const settingStore = useSettingStore()
|
||||
|
||||
const {
|
||||
isWordCollect,
|
||||
toggleWordCollect,
|
||||
isWordSimple,
|
||||
toggleWordSimple
|
||||
} = useWordOptions()
|
||||
|
||||
let data = $ref({
|
||||
index: props.index,
|
||||
words: props.words,
|
||||
wrongWords: [],
|
||||
})
|
||||
|
||||
let stat = cloneDeep(DefaultDisplayStatistics)
|
||||
let showSortOption = $ref(false)
|
||||
useWindowClick(() => showSortOption = false)
|
||||
|
||||
watch(() => props.words, () => {
|
||||
data.words = props.words
|
||||
data.index = props.index
|
||||
data.wrongWords = []
|
||||
|
||||
practiceStore.wrongWords = []
|
||||
practiceStore.repeatNumber = 0
|
||||
practiceStore.startDate = Date.now()
|
||||
practiceStore.correctRate = -1
|
||||
practiceStore.inputWordNumber = 0
|
||||
practiceStore.wrongWordNumber = 0
|
||||
stat = cloneDeep(DefaultDisplayStatistics)
|
||||
|
||||
}, {immediate: true})
|
||||
|
||||
watch(data, () => {
|
||||
practiceStore.total = data.words.length
|
||||
practiceStore.index = data.index
|
||||
})
|
||||
|
||||
const word = $computed(() => {
|
||||
return data.words[data.index] ?? {
|
||||
trans: [],
|
||||
name: '',
|
||||
usphone: '',
|
||||
ukphone: '',
|
||||
}
|
||||
})
|
||||
|
||||
const prevWord: Word = $computed(() => {
|
||||
return data.words?.[data.index - 1] ?? undefined
|
||||
})
|
||||
|
||||
const nextWord: Word = $computed(() => {
|
||||
return data.words?.[data.index + 1] ?? undefined
|
||||
})
|
||||
|
||||
function next(isTyping: boolean = true) {
|
||||
if (data.index === data.words.length - 1) {
|
||||
|
||||
//复制当前错词,因为第一遍错词是最多的,后续的练习都是从错词中练习
|
||||
if (stat.total === -1) {
|
||||
let now = Date.now()
|
||||
stat = {
|
||||
startDate: practiceStore.startDate,
|
||||
endDate: now,
|
||||
spend: now - practiceStore.startDate,
|
||||
total: props.words.length,
|
||||
correctRate: -1,
|
||||
inputWordNumber: practiceStore.inputWordNumber,
|
||||
wrongWordNumber: data.wrongWords.length,
|
||||
wrongWords: data.wrongWords,
|
||||
}
|
||||
stat.correctRate = 100 - Math.trunc(((stat.wrongWordNumber) / (stat.total)) * 100)
|
||||
}
|
||||
|
||||
if (data.wrongWords.length) {
|
||||
console.log('当前背完了,但还有错词')
|
||||
data.words = cloneDeep(data.wrongWords)
|
||||
|
||||
practiceStore.total = data.words.length
|
||||
practiceStore.index = data.index = 0
|
||||
practiceStore.inputWordNumber = 0
|
||||
practiceStore.wrongWordNumber = 0
|
||||
practiceStore.repeatNumber++
|
||||
data.wrongWords = []
|
||||
} else {
|
||||
console.log('这章节完了')
|
||||
isTyping && practiceStore.inputWordNumber++
|
||||
|
||||
let now = Date.now()
|
||||
stat.endDate = now
|
||||
stat.spend = now - stat.startDate
|
||||
|
||||
emitter.emit(EventKey.openStatModal, stat)
|
||||
}
|
||||
} else {
|
||||
data.index++
|
||||
isTyping && practiceStore.inputWordNumber++
|
||||
console.log('这个词完了')
|
||||
if ([DictType.word].includes(store.currentDict.type)
|
||||
&& store.skipWordNames.includes(word.name.toLowerCase())) {
|
||||
next()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function wordWrong() {
|
||||
if (!store.wrong.originWords.find((v: Word) => v.name.toLowerCase() === word.name.toLowerCase())) {
|
||||
store.wrong.originWords.push(word)
|
||||
}
|
||||
if (!data.wrongWords.find((v: Word) => v.name.toLowerCase() === word.name.toLowerCase())) {
|
||||
data.wrongWords.push(word)
|
||||
practiceStore.wrongWordNumber++
|
||||
}
|
||||
}
|
||||
|
||||
function onKeyUp(e: KeyboardEvent) {
|
||||
typingRef.hideWord()
|
||||
}
|
||||
|
||||
async function onKeyDown(e: KeyboardEvent) {
|
||||
// console.log('e', e)
|
||||
switch (e.key) {
|
||||
case 'Backspace':
|
||||
typingRef.del()
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
useOnKeyboardEventListener(onKeyDown, onKeyUp)
|
||||
|
||||
//TODO 略过忽略的单词上
|
||||
function prev() {
|
||||
if (data.index === 0) {
|
||||
ElMessage.warning('已经是第一个了~')
|
||||
} else {
|
||||
data.index--
|
||||
}
|
||||
}
|
||||
|
||||
function skip(e: KeyboardEvent) {
|
||||
next(false)
|
||||
// e.preventDefault()
|
||||
}
|
||||
|
||||
function show(e: KeyboardEvent) {
|
||||
typingRef.showWord()
|
||||
}
|
||||
|
||||
function collect(e: KeyboardEvent) {
|
||||
toggleWordCollect(word)
|
||||
}
|
||||
|
||||
function toggleWordSimpleWrapper() {
|
||||
if (!isWordSimple(word)) {
|
||||
toggleWordSimple(word)
|
||||
//延迟一下,不知道为什么不延迟会导致当前条目不自动定位到列表中间
|
||||
setTimeout(() => next(false))
|
||||
} else {
|
||||
toggleWordSimple(word)
|
||||
}
|
||||
}
|
||||
|
||||
function play() {
|
||||
typingRef.play()
|
||||
}
|
||||
|
||||
function sort(type: Sort) {
|
||||
if (type === Sort.reverse) {
|
||||
ElMessage.success('已翻转排序')
|
||||
emit('sort', reverse(cloneDeep(data.words)))
|
||||
}
|
||||
if (type === Sort.random) {
|
||||
ElMessage.success('已随机排序')
|
||||
emit('sort', shuffle(data.words))
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
emitter.on(ShortcutKey.ShowWord, show)
|
||||
emitter.on(ShortcutKey.Previous, prev)
|
||||
emitter.on(ShortcutKey.Next, skip)
|
||||
emitter.on(ShortcutKey.ToggleCollect, collect)
|
||||
emitter.on(ShortcutKey.ToggleSimple, toggleWordSimpleWrapper)
|
||||
emitter.on(ShortcutKey.PlayWordPronunciation, play)
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
emitter.off(ShortcutKey.ShowWord, show)
|
||||
emitter.off(ShortcutKey.Previous, prev)
|
||||
emitter.off(ShortcutKey.Next, skip)
|
||||
emitter.off(ShortcutKey.ToggleCollect, collect)
|
||||
emitter.off(ShortcutKey.ToggleSimple, toggleWordSimpleWrapper)
|
||||
emitter.off(ShortcutKey.PlayWordPronunciation, play)
|
||||
})
|
||||
|
||||
let index = $ref(0)
|
||||
watch(() => index, n => {
|
||||
settingStore.showPanel = index === 1
|
||||
})
|
||||
|
||||
let inputRef = $ref<HTMLInputElement>()
|
||||
|
||||
|
||||
function change(e) {
|
||||
console.log('e', e)
|
||||
e.key = e.data
|
||||
emitter.emit(EventKey.onTyping, e)
|
||||
inputRef.value = ''
|
||||
}
|
||||
|
||||
function know() {
|
||||
settingStore.translate = false
|
||||
setTimeout(() => {
|
||||
data.index++
|
||||
}, 300)
|
||||
}
|
||||
|
||||
function unknow() {
|
||||
settingStore.translate = true
|
||||
inputRef.focus()
|
||||
}
|
||||
|
||||
let bodyHeight = $ref('100vh')
|
||||
onMounted(() => {
|
||||
bodyHeight = document.body.clientHeight + 'px'
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="practice-word" :style="{height:bodyHeight}">
|
||||
<SlideHorizontal v-model:index="index">
|
||||
<SlideItem>
|
||||
<div class="practice-body" @click.stop="index = 0">
|
||||
<div class="tool-bar">
|
||||
<div class="left">
|
||||
<Icon icon="octicon:arrow-left-24" width="22"
|
||||
@click="router.back()"
|
||||
/>
|
||||
</div>
|
||||
<div class="right">
|
||||
<BaseIcon
|
||||
v-if="!isWordCollect(word)"
|
||||
class="collect"
|
||||
@click="toggleWordCollect(word)"
|
||||
icon="ph:star"/>
|
||||
<BaseIcon
|
||||
v-else
|
||||
class="fill"
|
||||
@click="toggleWordCollect(word)"
|
||||
icon="ph:star-fill"/>
|
||||
<BaseIcon
|
||||
@click="index = 1"
|
||||
icon="tdesign:menu-unfold"/>
|
||||
</div>
|
||||
</div>
|
||||
<input ref="inputRef"
|
||||
style="position:fixed;top:-200vh;"
|
||||
@input="change"
|
||||
type="text">
|
||||
<Typing
|
||||
style="width: 90%;"
|
||||
v-loading="!store.load"
|
||||
ref="typingRef"
|
||||
:word="word"
|
||||
@next="next"
|
||||
/>
|
||||
<div class="options">
|
||||
<div class="wrapper">
|
||||
<BaseButton @click="unknow">不认识</BaseButton>
|
||||
<BaseButton @click="know">认识</BaseButton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</SlideItem>
|
||||
<SlideItem style="width: 80vw;">
|
||||
<MobilePanel>
|
||||
<template v-slot="{active}">
|
||||
<div class="panel-page-item"
|
||||
v-loading="!store.load"
|
||||
>
|
||||
<div class="list-header">
|
||||
<div class="left">
|
||||
<div class="title">
|
||||
{{ store.chapterName }}
|
||||
</div>
|
||||
<BaseIcon title="切换词典"
|
||||
@click="emitter.emit(EventKey.openDictModal,'list')"
|
||||
icon="carbon:change-catalog"/>
|
||||
<div style="position:relative;"
|
||||
@click.stop="null">
|
||||
<BaseIcon
|
||||
title="改变顺序"
|
||||
icon="icon-park-outline:sort-two"
|
||||
@click="showSortOption = !showSortOption"
|
||||
/>
|
||||
<MiniDialog
|
||||
v-model="showSortOption"
|
||||
style="width: 130rem;"
|
||||
>
|
||||
<div class="mini-row-title">
|
||||
列表循环设置
|
||||
</div>
|
||||
<div class="mini-row">
|
||||
<BaseButton size="small" @click="sort(Sort.reverse)">翻转</BaseButton>
|
||||
<BaseButton size="small" @click="sort(Sort.random)">随机</BaseButton>
|
||||
</div>
|
||||
</MiniDialog>
|
||||
</div>
|
||||
<BaseIcon icon="bi:arrow-right"
|
||||
@click="next"
|
||||
v-if="store.currentDict.chapterIndex < store.currentDict.chapterWords.length - 1"/>
|
||||
</div>
|
||||
<div class="right">
|
||||
{{ data.words.length }}个单词
|
||||
</div>
|
||||
</div>
|
||||
<WordList
|
||||
v-if="data.words.length"
|
||||
:is-active="active"
|
||||
:static="false"
|
||||
:show-word="!settingStore.dictation"
|
||||
:show-translate="settingStore.translate"
|
||||
:list="data.words"
|
||||
:activeIndex="data.index"
|
||||
@click="(val:any) => data.index = val.index"
|
||||
>
|
||||
<template v-slot:suffix="{item,index}">
|
||||
<BaseIcon
|
||||
v-if="!isWordCollect(item)"
|
||||
class="collect"
|
||||
@click="toggleWordCollect(item)"
|
||||
title="收藏" icon="ph:star"/>
|
||||
<BaseIcon
|
||||
v-else
|
||||
class="fill"
|
||||
@click="toggleWordCollect(item)"
|
||||
title="取消收藏" icon="ph:star-fill"/>
|
||||
<BaseIcon
|
||||
v-if="!isWordSimple(item)"
|
||||
class="easy"
|
||||
@click="toggleWordSimple(item)"
|
||||
title="标记为简单词"
|
||||
icon="material-symbols:check-circle-outline-rounded"/>
|
||||
<BaseIcon
|
||||
v-else
|
||||
class="fill"
|
||||
@click="toggleWordSimple(item)"
|
||||
title="取消标记简单词"
|
||||
icon="material-symbols:check-circle-rounded"/>
|
||||
</template>
|
||||
</WordList>
|
||||
<Empty v-else/>
|
||||
</div>
|
||||
</template>
|
||||
</MobilePanel>
|
||||
</SlideItem>
|
||||
</SlideHorizontal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "@/assets/css/variable";
|
||||
|
||||
.practice-word {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100vh;
|
||||
min-height: 100vh;
|
||||
width: 100vw;
|
||||
font-size: 14rem;
|
||||
|
||||
.practice-body {
|
||||
width: 100%;
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 10rem;
|
||||
padding: 10rem;
|
||||
box-sizing: border-box;
|
||||
|
||||
.tool-bar {
|
||||
width: 100%;
|
||||
height: 50rem;
|
||||
display: flex;
|
||||
padding: 0 10rem;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 10rem;
|
||||
}
|
||||
|
||||
:deep(.word) {
|
||||
letter-spacing: 0;
|
||||
font-size: 40rem !important;
|
||||
}
|
||||
|
||||
.options {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding-bottom: 20rem;
|
||||
|
||||
.wrapper {
|
||||
width: 80%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10rem;
|
||||
}
|
||||
|
||||
.base-button {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
@@ -27,7 +27,7 @@ function getCurrentPractice() {
|
||||
|
||||
store.chapter.map((w: Word) => {
|
||||
if (!w.trans.length) {
|
||||
let res = runtimeStore.translateWordList.find(a => a.name === w.name)
|
||||
let res = runtimeStore.translateWordList.find(a => a.word === w.word)
|
||||
if (res) w = Object.assign(w, res)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -159,7 +159,7 @@ function handleChangeCurrentChapter(val: {
|
||||
v.checked = false
|
||||
//TODO 可能会存在卡的问题
|
||||
if (!v.trans.length && runtimeStore.translateWordList.length) {
|
||||
let res = runtimeStore.translateWordList.find(a => a.name === v.name)
|
||||
let res = runtimeStore.translateWordList.find(a => a.word === v.word)
|
||||
if (res) v = Object.assign(v, res)
|
||||
}
|
||||
})
|
||||
@@ -178,7 +178,7 @@ function checkRepeatWord(
|
||||
let repeatWords = []
|
||||
let noRepeatWords = []
|
||||
words.map((v: any) => {
|
||||
let rIndex = targetList.findIndex(s => s.name === v.name)
|
||||
let rIndex = targetList.findIndex(s => s.word === v.word)
|
||||
if (rIndex > -1) {
|
||||
v.index = rIndex
|
||||
repeatWords.push(v)
|
||||
@@ -189,7 +189,7 @@ function checkRepeatWord(
|
||||
concatNoRepeat(noRepeatWords)
|
||||
if (repeatWords.length) {
|
||||
MessageBox.confirm(
|
||||
'单词"' + repeatWords.map(v => v.name).join(', ') + '" 已存在,继续将会覆盖原有单词,是否继续?',
|
||||
'单词"' + repeatWords.map(v => v.word).join(', ') + '" 已存在,继续将会覆盖原有单词,是否继续?',
|
||||
'检测到重复单词',
|
||||
() => concatRepeat(repeatWords),
|
||||
null,
|
||||
@@ -206,7 +206,7 @@ function toResidueWordList() {
|
||||
checkRepeatWord(list, residueWordList,
|
||||
noRepeatWords => {
|
||||
if (wordFormData.type === FormMode.Edit && wordFormData.where === 'chapter') {
|
||||
if (noRepeatWords.find(v => v.name === wordForm.name)) {
|
||||
if (noRepeatWords.find(v => v.word === wordForm.word)) {
|
||||
wordFormData.where = 'residue'
|
||||
}
|
||||
}
|
||||
@@ -220,7 +220,7 @@ function toResidueWordList() {
|
||||
},
|
||||
repeatWords => {
|
||||
if (wordFormData.type === FormMode.Edit && wordFormData.where === 'chapter') {
|
||||
if (repeatWords.find(v => v.name === wordForm.name)) {
|
||||
if (repeatWords.find(v => v.word === wordForm.word)) {
|
||||
wordFormData.where = 'residue'
|
||||
}
|
||||
}
|
||||
@@ -244,7 +244,7 @@ function toChapterWordList() {
|
||||
checkRepeatWord(list, chapterWordList,
|
||||
noRepeatWords => {
|
||||
if (wordFormData.type === FormMode.Edit && wordFormData.where !== 'chapter') {
|
||||
if (noRepeatWords.find(v => v.name === wordForm.name)) {
|
||||
if (noRepeatWords.find(v => v.word === wordForm.word)) {
|
||||
wordFormData.where = 'chapter'
|
||||
}
|
||||
}
|
||||
@@ -258,7 +258,7 @@ function toChapterWordList() {
|
||||
},
|
||||
repeatWords => {
|
||||
if (wordFormData.type === FormMode.Edit && wordFormData.where !== 'chapter') {
|
||||
if (repeatWords.find(v => v.name === wordForm.name)) {
|
||||
if (repeatWords.find(v => v.word === wordForm.word)) {
|
||||
wordFormData.where = 'chapter'
|
||||
}
|
||||
}
|
||||
@@ -330,7 +330,7 @@ async function onSubmitWord() {
|
||||
if (wordFormData.type === FormMode.Add) {
|
||||
data.id = nanoid(6)
|
||||
data.checked = false
|
||||
let r = list.find(v => v.name === wordForm.name)
|
||||
let r = list.find(v => v.word === wordForm.word)
|
||||
if (r) return ElMessage.warning('已有相同名称单词!')
|
||||
else list.push(data)
|
||||
runtimeStore.editDict.originWords.push(data)
|
||||
@@ -367,7 +367,7 @@ function delWord(val: {
|
||||
runtimeStore.editDict.words.splice(rIndex2, 1)
|
||||
}
|
||||
|
||||
if (wordFormData.type === FormMode.Edit && wordForm.name === val.item.name) {
|
||||
if (wordFormData.type === FormMode.Edit && wordForm.word === val.item.word) {
|
||||
closeWordForm()
|
||||
}
|
||||
syncEditDict2MyDictList()
|
||||
@@ -377,7 +377,7 @@ function editWord(word: Word, index: number, where: string) {
|
||||
wordFormData.type = FormMode.Edit
|
||||
wordFormData.id = word.id
|
||||
wordFormData.where = where
|
||||
wordForm.name = word.name
|
||||
wordForm.word = word.word
|
||||
wordForm.ukphone = word.ukphone
|
||||
wordForm.usphone = word.usphone
|
||||
wordForm.trans = word.trans.join('\n')
|
||||
@@ -472,7 +472,7 @@ function exportData(type: string) {
|
||||
let wb = XLSX.utils.book_new()
|
||||
let sheetData = list.map(v => {
|
||||
return {
|
||||
单词: v.name,
|
||||
单词: v.word,
|
||||
'音标①': v.usphone,
|
||||
'音标②': v.ukphone,
|
||||
'释义(一行一个释义)': v.trans.join('\n')
|
||||
@@ -501,7 +501,7 @@ function importData(e: any) {
|
||||
let word: Word = {
|
||||
id: nanoid(6),
|
||||
checked: false,
|
||||
name: String(v['单词']),
|
||||
word: String(v['单词']),
|
||||
usphone: String(v['音标①'] ?? ''),
|
||||
ukphone: String(v['音标②'] ?? ''),
|
||||
trans: String(v['释义(一行一个释义)'] ?? '').split('\n')
|
||||
@@ -563,7 +563,7 @@ defineExpose({getDictDetail, add: addWord, editDict})
|
||||
<div class="left">
|
||||
<div class="top">
|
||||
<div class="title">
|
||||
{{ runtimeStore.editDict.name }}
|
||||
{{ runtimeStore.editDict.word }}
|
||||
</div>
|
||||
<template v-if="!isPinDict">
|
||||
<BaseIcon icon="tabler:edit" @click='editDict'/>
|
||||
@@ -695,8 +695,8 @@ defineExpose({getDictDetail, add: addWord, editDict})
|
||||
:rules="wordRules"
|
||||
:model="wordForm"
|
||||
label-width="100rem">
|
||||
<el-form-item label="单词" prop="name">
|
||||
<el-input v-model="wordForm.name"/>
|
||||
<el-form-item label="单词" prop="word">
|
||||
<el-input v-model="wordForm.word"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="翻译">
|
||||
<el-input v-model="wordForm.trans"
|
||||
|
||||
@@ -11,7 +11,6 @@ import {onMounted, reactive} from "vue";
|
||||
import {cloneDeep} from "lodash-es";
|
||||
import {Icon} from '@iconify/vue';
|
||||
import {$computed, $ref} from "vue/macros";
|
||||
import BaseIcon from "@/components/BaseIcon.vue";
|
||||
import {useSettingStore} from "@/stores/setting.ts";
|
||||
|
||||
const store = useBaseStore()
|
||||
@@ -85,7 +84,7 @@ const isEnd = $computed(() => {
|
||||
<div class="result">
|
||||
<div class="wrong-words-wrapper">
|
||||
<div class="wrong-words">
|
||||
<div class="word" v-for="i in currentStat.wrongWords">{{ i.name }}</div>
|
||||
<div class="word" v-for="i in currentStat.wrongWords">{{ i.word }}</div>
|
||||
<!-- <div class="word" v-for="i in 100">{{ i }}</div>-->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -84,8 +84,8 @@ watch(() => settingStore.dictation, () => {
|
||||
|
||||
function nextSentence() {
|
||||
// wordData.words = [
|
||||
// {"name": "pharmacy", "trans": ["药房;配药学,药剂学;制药业;一批备用药品"], "usphone": "'fɑrməsi", "ukphone": "'fɑːməsɪ"},
|
||||
// // {"name": "foregone", "trans": ["过去的;先前的;预知的;预先决定的", "发生在…之前(forego的过去分词)"], "usphone": "'fɔrɡɔn", "ukphone": "fɔː'gɒn"}, {"name": "president", "trans": ["总统;董事长;校长;主席"], "usphone": "'prɛzɪdənt", "ukphone": "'prezɪd(ə)nt"}, {"name": "plastic", "trans": ["塑料的;(外科)造型的;可塑的", "塑料制品;整形;可塑体"], "usphone": "'plæstɪk", "ukphone": "'plæstɪk"}, {"name": "provisionally", "trans": ["临时地,暂时地"], "usphone": "", "ukphone": ""}, {"name": "incentive", "trans": ["动机;刺激", "激励的;刺激的"], "usphone": "ɪn'sɛntɪv", "ukphone": "ɪn'sentɪv"}, {"name": "calculate", "trans": ["计算;以为;作打算"], "usphone": "'kælkjulet", "ukphone": "'kælkjʊleɪt"}
|
||||
// {"word": "pharmacy", "trans": ["药房;配药学,药剂学;制药业;一批备用药品"], "usphone": "'fɑrməsi", "ukphone": "'fɑːməsɪ"},
|
||||
// // {"word": "foregone", "trans": ["过去的;先前的;预知的;预先决定的", "发生在…之前(forego的过去分词)"], "usphone": "'fɔrɡɔn", "ukphone": "fɔː'gɒn"}, {"word": "president", "trans": ["总统;董事长;校长;主席"], "usphone": "'prɛzɪdənt", "ukphone": "'prezɪd(ə)nt"}, {"word": "plastic", "trans": ["塑料的;(外科)造型的;可塑的", "塑料制品;整形;可塑体"], "usphone": "'plæstɪk", "ukphone": "'plæstɪk"}, {"word": "provisionally", "trans": ["临时地,暂时地"], "usphone": "", "ukphone": ""}, {"word": "incentive", "trans": ["动机;刺激", "激励的;刺激的"], "usphone": "ɪn'sɛntɪv", "ukphone": "ɪn'sentɪv"}, {"word": "calculate", "trans": ["计算;以为;作打算"], "usphone": "'kælkjulet", "ukphone": "'kælkjʊleɪt"}
|
||||
// ]
|
||||
// return
|
||||
|
||||
@@ -97,7 +97,7 @@ function nextSentence() {
|
||||
input = wrong = ''
|
||||
|
||||
//todo 计得把略过的单词加上统计里面去
|
||||
// if (!store.skipWordNamesWithSimpleWords.includes(currentWord.name.toLowerCase()) && !currentWord.isSymbol) {
|
||||
// if (!store.skipWordNamesWithSimpleWords.includes(currentWord.word.toLowerCase()) && !currentWord.isSymbol) {
|
||||
// practiceStore.inputNumber++
|
||||
// }
|
||||
|
||||
@@ -168,7 +168,7 @@ function onTyping(e: KeyboardEvent) {
|
||||
} else {
|
||||
let letter = e.key
|
||||
|
||||
let key = currentWord.name[stringIndex]
|
||||
let key = currentWord.word[stringIndex]
|
||||
// console.log('key', key,)
|
||||
|
||||
let isRight = false
|
||||
@@ -183,7 +183,7 @@ function onTyping(e: KeyboardEvent) {
|
||||
// console.log('匹配上了')
|
||||
stringIndex++
|
||||
//如果当前词没有index,说明这个词完了,下一个是空格
|
||||
if (!currentWord.name[stringIndex]) {
|
||||
if (!currentWord.word[stringIndex]) {
|
||||
input = wrong = ''
|
||||
if (!currentWord.isSymbol) {
|
||||
playCorrect()
|
||||
@@ -260,11 +260,11 @@ function del() {
|
||||
}
|
||||
|
||||
function playWord(word: ArticleWord) {
|
||||
playWordAudio(word.name)
|
||||
playWordAudio(word.word)
|
||||
}
|
||||
|
||||
function currentWordInput(word: ArticleWord, i: number, i2: number,) {
|
||||
let str = word.name.slice(input.length + wrong.length, input.length + wrong.length + 1)
|
||||
let str = word.word.slice(input.length + wrong.length, input.length + wrong.length + 1)
|
||||
if (word.isSymbol) {
|
||||
return str
|
||||
}
|
||||
@@ -279,7 +279,7 @@ function currentWordInput(word: ArticleWord, i: number, i2: number,) {
|
||||
}
|
||||
|
||||
function currentWordEnd(word: ArticleWord, i: number, i2: number,) {
|
||||
let str = word.name.slice(input.length + wrong.length + (wrong ? 0 : 1))
|
||||
let str = word.word.slice(input.length + wrong.length + (wrong ? 0 : 1))
|
||||
if (hoverIndex.sectionIndex === i && hoverIndex.sentenceIndex === i2) {
|
||||
return str
|
||||
}
|
||||
@@ -291,7 +291,7 @@ function currentWordEnd(word: ArticleWord, i: number, i2: number,) {
|
||||
}
|
||||
|
||||
function otherWord(word: ArticleWord, i: number, i2: number, i3: number) {
|
||||
let str = word.name
|
||||
let str = word.word
|
||||
if (word.isSymbol) {
|
||||
return str
|
||||
}
|
||||
@@ -393,7 +393,7 @@ defineExpose({showSentence, play, del,hideSentence,nextSentence})
|
||||
?'wrote' :
|
||||
(sectionIndex>=indexI &&sentenceIndex>=indexJ && wordIndex>indexW)
|
||||
?'wrote':
|
||||
(sectionIndex>=indexI &&sentenceIndex>=indexJ && wordIndex>=indexW && stringIndex>=word.name.length)
|
||||
(sectionIndex>=indexI &&sentenceIndex>=indexJ && wordIndex>=indexW && stringIndex>=word.word.length)
|
||||
?'wrote':
|
||||
''),
|
||||
(`${indexI}${indexJ}${indexW}` === currentIndex && !isSpace && wrong )?'word-wrong':'',
|
||||
|
||||
@@ -177,7 +177,7 @@ function edit(val: Article = articleData.article) {
|
||||
// wordData.words = [
|
||||
// {
|
||||
// ...cloneDeep(DefaultWord),
|
||||
// name: 'test'
|
||||
// word: 'test'
|
||||
// }
|
||||
// ]
|
||||
// wordData.index = 0
|
||||
@@ -187,12 +187,12 @@ function edit(val: Article = articleData.article) {
|
||||
}
|
||||
|
||||
function wrong(word: Word) {
|
||||
let lowerName = word.name.toLowerCase();
|
||||
if (!store.wrong.originWords.find((v: Word) => v.name.toLowerCase() === lowerName)) {
|
||||
let lowerName = word.word.toLowerCase();
|
||||
if (!store.wrong.originWords.find((v: Word) => v.word.toLowerCase() === lowerName)) {
|
||||
store.wrong.originWords.push(word)
|
||||
}
|
||||
if (!store.skipWordNamesWithSimpleWords.includes(lowerName)) {
|
||||
if (!practiceStore.wrongWords.find((v) => v.name.toLowerCase() === lowerName)) {
|
||||
if (!practiceStore.wrongWords.find((v) => v.word.toLowerCase() === lowerName)) {
|
||||
practiceStore.wrongWords.push(word)
|
||||
practiceStore.wrongWordNumber++
|
||||
}
|
||||
@@ -223,7 +223,7 @@ function over() {
|
||||
}
|
||||
|
||||
function nextWord(word: ArticleWord) {
|
||||
if (!store.skipWordNamesWithSimpleWords.includes(word.name.toLowerCase()) && !word.isSymbol) {
|
||||
if (!store.skipWordNamesWithSimpleWords.includes(word.word.toLowerCase()) && !word.isSymbol) {
|
||||
practiceStore.inputWordNumber++
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ const volumeIconRef: any = $ref()
|
||||
const volumeTranslateIconRef: any = $ref()
|
||||
|
||||
let displayWord = $computed(() => {
|
||||
return props.word.name.slice(input.length + wrong.length)
|
||||
return props.word.word.slice(input.length + wrong.length)
|
||||
})
|
||||
|
||||
watch(() => props.word, () => {
|
||||
@@ -85,11 +85,11 @@ async function onTyping(e: KeyboardEvent) {
|
||||
let isTypingRight = false
|
||||
let isWordRight = false
|
||||
if (settingStore.ignoreCase) {
|
||||
isTypingRight = letter.toLowerCase() === props.word.name[input.length].toLowerCase()
|
||||
isWordRight = (input + letter).toLowerCase() === props.word.name.toLowerCase()
|
||||
isTypingRight = letter.toLowerCase() === props.word.word[input.length].toLowerCase()
|
||||
isWordRight = (input + letter).toLowerCase() === props.word.word.toLowerCase()
|
||||
} else {
|
||||
isTypingRight = letter === props.word.name[input.length]
|
||||
isWordRight = (input + letter) === props.word.name
|
||||
isTypingRight = letter === props.word.word[input.length]
|
||||
isWordRight = (input + letter) === props.word.word
|
||||
}
|
||||
if (isTypingRight) {
|
||||
input += letter
|
||||
@@ -195,7 +195,7 @@ defineExpose({del, showWord, hideWord, play})
|
||||
<Tooltip
|
||||
:title="`发音(快捷键:${settingStore.shortcutKeyMap[ShortcutKey.PlayWordPronunciation]})`"
|
||||
>
|
||||
<VolumeIcon ref="volumeIconRef" :simple="true" :cb="() => playWordAudio(word.name)"/>
|
||||
<VolumeIcon ref="volumeIconRef" :simple="true" :cb="() => playWordAudio(word.word)"/>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<div class="phonetic" v-if="settingStore.wordSoundType === 'us' && word.usphone">[{{ word.usphone}}]</div>
|
||||
|
||||
@@ -83,7 +83,7 @@ watch(data, () => {
|
||||
const word = $computed(() => {
|
||||
return data.words[data.index] ?? {
|
||||
trans: [],
|
||||
name: '',
|
||||
word: '',
|
||||
usphone: '',
|
||||
ukphone: '',
|
||||
}
|
||||
@@ -141,17 +141,17 @@ function next(isTyping: boolean = true) {
|
||||
isTyping && practiceStore.inputWordNumber++
|
||||
console.log('这个词完了')
|
||||
if ([DictType.word].includes(store.currentDict.type)
|
||||
&& store.skipWordNames.includes(word.name.toLowerCase())) {
|
||||
&& store.skipWordNames.includes(word.word.toLowerCase())) {
|
||||
next()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function wordWrong() {
|
||||
if (!store.wrong.originWords.find((v: Word) => v.name.toLowerCase() === word.name.toLowerCase())) {
|
||||
if (!store.wrong.originWords.find((v: Word) => v.word.toLowerCase() === word.word.toLowerCase())) {
|
||||
store.wrong.originWords.push(word)
|
||||
}
|
||||
if (!data.wrongWords.find((v: Word) => v.name.toLowerCase() === word.name.toLowerCase())) {
|
||||
if (!data.wrongWords.find((v: Word) => v.word.toLowerCase() === word.word.toLowerCase())) {
|
||||
data.wrongWords.push(word)
|
||||
practiceStore.wrongWordNumber++
|
||||
}
|
||||
@@ -249,7 +249,7 @@ onUnmounted(() => {
|
||||
<Tooltip
|
||||
:title="`上一个(快捷键:${settingStore.shortcutKeyMap[ShortcutKey.Previous]})`"
|
||||
>
|
||||
<div class="word">{{ prevWord.name }}</div>
|
||||
<div class="word">{{ prevWord.word }}</div>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<div class="next"
|
||||
@@ -258,7 +258,7 @@ onUnmounted(() => {
|
||||
<Tooltip
|
||||
:title="`下一个(快捷键:${settingStore.shortcutKeyMap[ShortcutKey.Next]})`"
|
||||
>
|
||||
<div class="word" :class="settingStore.dictation && 'text-shadow'">{{ nextWord.name }}</div>
|
||||
<div class="word" :class="settingStore.dictation && 'text-shadow'">{{ nextWord.word }}</div>
|
||||
</Tooltip>
|
||||
<Icon class="arrow" icon="bi:arrow-right" width="22"/>
|
||||
</div>
|
||||
|
||||
@@ -27,7 +27,7 @@ function getCurrentPractice() {
|
||||
|
||||
store.chapter.map((w: Word) => {
|
||||
if (!w.trans.length) {
|
||||
let res = runtimeStore.translateWordList.find(a => a.name === w.name)
|
||||
let res = runtimeStore.translateWordList.find(a => a.word === w.word)
|
||||
if (res) w = Object.assign(w, res)
|
||||
}
|
||||
})
|
||||
|
||||
115327
src/pages/test/data.json
115327
src/pages/test/data.json
File diff suppressed because one or more lines are too long
@@ -1,8 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
|
||||
import {splitEnArticle} from "@/hooks/article.ts";
|
||||
import origin from './data.json'
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import {useSettingStore} from "@/stores/setting.ts";
|
||||
import {checkAndUpgradeSaveDict, shakeCommonDict} from "@/utils";
|
||||
import localforage from "localforage";
|
||||
import {SAVE_DICT_KEY} from "@/utils/const.ts";
|
||||
|
||||
@@ -28,17 +27,37 @@ let data = {
|
||||
// "newWords": [],
|
||||
// "id": "TdAAqD"
|
||||
// }
|
||||
splitEnArticle(data.text)
|
||||
const settingStore = useSettingStore()
|
||||
async function test(){
|
||||
|
||||
async function look() {
|
||||
let configStr: string = await localforage.getItem(SAVE_DICT_KEY.key)
|
||||
console.log(configStr)
|
||||
let obj = JSON.parse(configStr)
|
||||
console.log('local', obj)
|
||||
|
||||
}
|
||||
|
||||
function set() {
|
||||
localforage.setItem(SAVE_DICT_KEY.key, JSON.stringify({val: shakeCommonDict(origin.val as any), version: 3}))
|
||||
}
|
||||
|
||||
async function check() {
|
||||
// let configStr: string = await localforage.getItem(SAVE_DICT_KEY.key)
|
||||
// console.log('local', configStr)
|
||||
// console.log('or',origin)
|
||||
let configStr: string = await localforage.getItem(SAVE_DICT_KEY.key)
|
||||
let data = checkAndUpgradeSaveDict(configStr)
|
||||
console.log('data',data)
|
||||
// this.setState(data)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="page">
|
||||
<BaseButton @click="test">test</BaseButton>
|
||||
<div class="data">
|
||||
<p>数据升级检测</p>
|
||||
<BaseButton @click="look">获取保存到localforage的数据</BaseButton>
|
||||
<BaseButton @click="set">设置data.json的数据到localforage</BaseButton>
|
||||
<BaseButton @click="check">检测升级逻辑</BaseButton>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -48,5 +67,12 @@ async function test(){
|
||||
z-index: 1;
|
||||
font-size: 14rem;
|
||||
color: black;
|
||||
|
||||
.data{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10rem;
|
||||
width: 300rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -9,348 +9,303 @@ import {SAVE_DICT_KEY, SAVE_SETTING_KEY} from "@/utils/const.ts";
|
||||
import {checkAndUpgradeSaveDict} from "@/utils";
|
||||
|
||||
export interface BaseState {
|
||||
myDictList: Dict[],
|
||||
collectDictIds: string[],
|
||||
current: {
|
||||
index: number,
|
||||
practiceType: DictType,//练习类型,目前仅词典为collect时判断是练单词还是文章使用
|
||||
},
|
||||
simpleWords: string[],
|
||||
load: boolean
|
||||
myDictList: Dict[],
|
||||
collectDictIds: string[],
|
||||
current: {
|
||||
index: number,
|
||||
practiceType: DictType,//练习类型,目前仅词典为collect时判断是练单词还是文章使用
|
||||
},
|
||||
simpleWords: string[],
|
||||
load: boolean
|
||||
}
|
||||
|
||||
export const DefaultBaseState = (): BaseState => ({
|
||||
myDictList: [
|
||||
{
|
||||
...cloneDeep(DefaultDict),
|
||||
id: 'collect',
|
||||
name: '收藏',
|
||||
type: DictType.collect,
|
||||
category: '自带字典',
|
||||
tags: ['自带'],
|
||||
isCustom: true,
|
||||
},
|
||||
{
|
||||
...cloneDeep(DefaultDict),
|
||||
id: 'skip',
|
||||
name: '简单词',
|
||||
type: DictType.simple,
|
||||
category: '自带字典',
|
||||
isCustom: true,
|
||||
},
|
||||
{
|
||||
...cloneDeep(DefaultDict),
|
||||
id: 'wrong',
|
||||
name: '错词本',
|
||||
type: DictType.wrong,
|
||||
category: '自带字典',
|
||||
isCustom: true,
|
||||
},
|
||||
{
|
||||
...cloneDeep(DefaultDict),
|
||||
id: 'cet4',
|
||||
name: 'CET-4',
|
||||
description: '大学英语四级词库',
|
||||
category: '中国考试',
|
||||
tags: ['大学英语'],
|
||||
url: 'CET4_T.json',
|
||||
length: 2607,
|
||||
translateLanguage: 'common',
|
||||
language: 'en',
|
||||
type: DictType.word
|
||||
},
|
||||
// {
|
||||
// ...cloneDeep(DefaultDict),
|
||||
// id: 'article_nce2',
|
||||
// name: "新概念英语2-课文",
|
||||
// description: '新概念英语2-课文',
|
||||
// category: '英语学习',
|
||||
// tags: ['新概念英语'],
|
||||
// url: 'NCE_2.json',
|
||||
// translateLanguage: 'common',
|
||||
// language: 'en',
|
||||
// type: DictType.article,
|
||||
// resourceId: 'article_nce2',
|
||||
// length: 96
|
||||
// },
|
||||
// {
|
||||
// ...cloneDeep(DefaultDict),
|
||||
// id: 'nce-new-2',
|
||||
// name: '新概念英语(新版)-2',
|
||||
// description: '新概念英语新版第二册',
|
||||
// category: '青少年英语',
|
||||
// tags: ['新概念英语'],
|
||||
// url: 'nce-new-2.json',
|
||||
// translateLanguage: 'common',
|
||||
// language: 'en',
|
||||
// type: DictType.word,
|
||||
// resourceId: 'nce-new-2',
|
||||
// length: 862
|
||||
// },
|
||||
],
|
||||
collectDictIds: [],
|
||||
current: {
|
||||
index: 3,
|
||||
// dictType: DictType.article,
|
||||
// index: 0,
|
||||
practiceType: DictType.word,
|
||||
myDictList: [
|
||||
{
|
||||
...cloneDeep(DefaultDict),
|
||||
id: 'collect',
|
||||
name: '收藏',
|
||||
type: DictType.collect,
|
||||
category: '自带字典',
|
||||
tags: ['自带'],
|
||||
isCustom: true,
|
||||
},
|
||||
simpleWords: [
|
||||
'a', 'an',
|
||||
'i', 'my', 'you', 'your', 'me', 'it',
|
||||
'what', 'who', 'where', 'how', 'when', 'which',
|
||||
'be', 'am', 'is', 'do', 'are', 'did', 'were', 'was', 'can', 'could', 'will', 'would',
|
||||
'the', 'that', 'this', 'to', 'of', 'for', 'and', 'at', 'not', 'no', 'yes',
|
||||
],
|
||||
load: false
|
||||
{
|
||||
...cloneDeep(DefaultDict),
|
||||
id: 'skip',
|
||||
name: '简单词',
|
||||
type: DictType.simple,
|
||||
category: '自带字典',
|
||||
isCustom: true,
|
||||
},
|
||||
{
|
||||
...cloneDeep(DefaultDict),
|
||||
id: 'wrong',
|
||||
name: '错词本',
|
||||
type: DictType.wrong,
|
||||
category: '自带字典',
|
||||
isCustom: true,
|
||||
},
|
||||
{
|
||||
...cloneDeep(DefaultDict),
|
||||
id: 'cet4',
|
||||
name: 'CET-4',
|
||||
description: '大学英语四级词库',
|
||||
category: '中国考试',
|
||||
tags: ['大学英语'],
|
||||
url: 'CET4_T.json',
|
||||
length: 2607,
|
||||
translateLanguage: 'common',
|
||||
language: 'en',
|
||||
type: DictType.word
|
||||
},
|
||||
// {
|
||||
// ...cloneDeep(DefaultDict),
|
||||
// id: 'article_nce2',
|
||||
// name: "新概念英语2-课文",
|
||||
// description: '新概念英语2-课文',
|
||||
// category: '英语学习',
|
||||
// tags: ['新概念英语'],
|
||||
// url: 'NCE_2.json',
|
||||
// translateLanguage: 'common',
|
||||
// language: 'en',
|
||||
// type: DictType.article,
|
||||
// resourceId: 'article_nce2',
|
||||
// length: 96
|
||||
// },
|
||||
// {
|
||||
// ...cloneDeep(DefaultDict),
|
||||
// id: 'nce-new-2',
|
||||
// name: '新概念英语(新版)-2',
|
||||
// description: '新概念英语新版第二册',
|
||||
// category: '青少年英语',
|
||||
// tags: ['新概念英语'],
|
||||
// url: 'nce-new-2.json',
|
||||
// translateLanguage: 'common',
|
||||
// language: 'en',
|
||||
// type: DictType.word,
|
||||
// resourceId: 'nce-new-2',
|
||||
// length: 862
|
||||
// },
|
||||
],
|
||||
collectDictIds: [],
|
||||
current: {
|
||||
index: 3,
|
||||
// dictType: DictType.article,
|
||||
// index: 0,
|
||||
practiceType: DictType.word,
|
||||
},
|
||||
simpleWords: [
|
||||
'a', 'an',
|
||||
'i', 'my', 'you', 'your', 'me', 'it',
|
||||
'what', 'who', 'where', 'how', 'when', 'which',
|
||||
'be', 'am', 'is', 'do', 'are', 'did', 'were', 'was', 'can', 'could', 'will', 'would',
|
||||
'the', 'that', 'this', 'to', 'of', 'for', 'and', 'at', 'not', 'no', 'yes',
|
||||
],
|
||||
load: false
|
||||
})
|
||||
|
||||
// words: [
|
||||
// {
|
||||
// "name": "cancelcancelcancelcancelcancelcancelcancelcancel",
|
||||
// "trans": ['取消取消取消取消取消取消取消取消取消取消取消取消取消取消取消取消'],
|
||||
// "usphone": "",
|
||||
// "ukphone": ""
|
||||
// },
|
||||
// {
|
||||
// "name": "prepare",
|
||||
// "trans": [],
|
||||
// "usphone": "",
|
||||
// "ukphone": ""
|
||||
// },
|
||||
// {
|
||||
// "name": "half",
|
||||
// "trans": [],
|
||||
// "usphone": "",
|
||||
// "ukphone": ""
|
||||
// },
|
||||
// {
|
||||
// "name": "spacious",
|
||||
// "trans": [],
|
||||
// "usphone": "",
|
||||
// "ukphone": ""
|
||||
// },
|
||||
// {
|
||||
// "name": "analyse",
|
||||
// "trans": [],
|
||||
// "usphone": "",
|
||||
// "ukphone": ""
|
||||
// },
|
||||
// {
|
||||
// "name": "costing",
|
||||
// "trans": [],
|
||||
// "usphone": "",
|
||||
// "ukphone": ""
|
||||
// },
|
||||
// {
|
||||
// "name": "nowadays",
|
||||
// "trans": [],
|
||||
// "usphone": "",
|
||||
// "ukphone": ""
|
||||
// },
|
||||
// ],
|
||||
|
||||
export const useBaseStore = defineStore('base', {
|
||||
state: (): BaseState => {
|
||||
return DefaultBaseState()
|
||||
state: (): BaseState => {
|
||||
return DefaultBaseState()
|
||||
},
|
||||
getters: {
|
||||
collect(): Dict {
|
||||
return this.myDictList[0]
|
||||
},
|
||||
getters: {
|
||||
collect(): Dict {
|
||||
return this.myDictList[0]
|
||||
},
|
||||
simple(): Dict {
|
||||
return this.myDictList[1]
|
||||
},
|
||||
wrong(): Dict {
|
||||
return this.myDictList[2]
|
||||
},
|
||||
skipWordNames() {
|
||||
return this.simple.originWords.map(v => v.name.toLowerCase())
|
||||
},
|
||||
skipWordNamesWithSimpleWords() {
|
||||
return this.simple.originWords.map(v => v.name.toLowerCase()).concat(this.simpleWords)
|
||||
},
|
||||
isArticle(state: BaseState): boolean {
|
||||
//如果是收藏时,特殊判断
|
||||
if (this.currentDict.type === DictType.collect) {
|
||||
return state.current.practiceType === DictType.article
|
||||
}
|
||||
return [
|
||||
DictType.article,
|
||||
].includes(this.currentDict.type)
|
||||
},
|
||||
currentDict(): Dict {
|
||||
return this.myDictList[this.current.index]
|
||||
},
|
||||
chapter(state: BaseState): Word[] {
|
||||
return this.currentDict.chapterWords[this.currentDict.chapterIndex] ?? []
|
||||
},
|
||||
chapterName(state: BaseState) {
|
||||
let title = ''
|
||||
switch (this.currentDict.type) {
|
||||
case DictType.collect:
|
||||
if (state.current.practiceType === DictType.article) {
|
||||
return `第${this.currentDict.chapterIndex + 1}章`
|
||||
}
|
||||
case DictType.wrong:
|
||||
case DictType.simple:
|
||||
return this.currentDict.name
|
||||
case DictType.word:
|
||||
return `第${this.currentDict.chapterIndex + 1}章`
|
||||
}
|
||||
return title
|
||||
simple(): Dict {
|
||||
return this.myDictList[1]
|
||||
},
|
||||
wrong(): Dict {
|
||||
return this.myDictList[2]
|
||||
},
|
||||
skipWordNames() {
|
||||
return this.simple.originWords.map(v => v.name.toLowerCase())
|
||||
},
|
||||
skipWordNamesWithSimpleWords() {
|
||||
return this.simple.originWords.map(v => v.name.toLowerCase()).concat(this.simpleWords)
|
||||
},
|
||||
isArticle(state: BaseState): boolean {
|
||||
//如果是收藏时,特殊判断
|
||||
if (this.currentDict.type === DictType.collect) {
|
||||
return state.current.practiceType === DictType.article
|
||||
}
|
||||
return [
|
||||
DictType.article,
|
||||
].includes(this.currentDict.type)
|
||||
},
|
||||
currentDict(): Dict {
|
||||
return this.myDictList[this.current.index]
|
||||
},
|
||||
chapter(state: BaseState): Word[] {
|
||||
return this.currentDict.chapterWords[this.currentDict.chapterIndex] ?? []
|
||||
},
|
||||
chapterName(state: BaseState) {
|
||||
let title = ''
|
||||
switch (this.currentDict.type) {
|
||||
case DictType.collect:
|
||||
if (state.current.practiceType === DictType.article) {
|
||||
return `第${this.currentDict.chapterIndex + 1}章`
|
||||
}
|
||||
case DictType.wrong:
|
||||
case DictType.simple:
|
||||
return this.currentDict.name
|
||||
case DictType.word:
|
||||
return `第${this.currentDict.chapterIndex + 1}章`
|
||||
}
|
||||
return title
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
setState(obj: any) {
|
||||
//这样不会丢失watch的值的引用
|
||||
merge(this, obj)
|
||||
},
|
||||
async init(outData?: any) {
|
||||
return new Promise(async resolve => {
|
||||
try {
|
||||
if (outData) {
|
||||
this.setState(outData)
|
||||
} else {
|
||||
let configStr: string = await localforage.getItem(SAVE_DICT_KEY.key)
|
||||
let data = checkAndUpgradeSaveDict(configStr)
|
||||
this.setState(data)
|
||||
}
|
||||
localforage.setItem(SAVE_DICT_KEY.key, JSON.stringify({val: this.$state, version: SAVE_DICT_KEY.version}))
|
||||
} catch (e) {
|
||||
console.error('读取本地dict数据失败', e)
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
setState(obj: any) {
|
||||
//这样不会丢失watch的值的引用
|
||||
merge(this, obj)
|
||||
},
|
||||
async init(outData?: any) {
|
||||
return new Promise(async resolve => {
|
||||
try {
|
||||
if (outData) {
|
||||
this.setState(outData)
|
||||
} else {
|
||||
let configStr: string = await localforage.getItem(SAVE_DICT_KEY.key)
|
||||
let data = checkAndUpgradeSaveDict(configStr)
|
||||
this.setState(data)
|
||||
}
|
||||
localforage.setItem(SAVE_DICT_KEY.key, JSON.stringify({val: this.$state, version: SAVE_DICT_KEY.version}))
|
||||
} catch (e) {
|
||||
console.error('读取本地dict数据失败', e)
|
||||
}
|
||||
const runtimeStore = useRuntimeStore()
|
||||
const runtimeStore = useRuntimeStore()
|
||||
|
||||
if (location.href.includes('?mode=article')) {
|
||||
console.log('文章')
|
||||
let dict = {
|
||||
...cloneDeep(DefaultDict),
|
||||
id: 'article_nce2',
|
||||
name: "新概念英语2-课文",
|
||||
description: '新概念英语2-课文',
|
||||
category: '英语学习',
|
||||
tags: ['新概念英语'],
|
||||
url: 'NCE_2.json',
|
||||
translateLanguage: 'common',
|
||||
language: 'en',
|
||||
type: DictType.article,
|
||||
resourceId: 'article_nce2',
|
||||
length: 96
|
||||
}
|
||||
let rIndex = this.myDictList.findIndex((v: Dict) => v.id === dict.id)
|
||||
if (rIndex > -1) {
|
||||
this.myDictList[rIndex] = dict
|
||||
this.current.index = rIndex
|
||||
} else {
|
||||
this.myDictList.push(cloneDeep(dict))
|
||||
this.current.index = this.myDictList.length - 1
|
||||
}
|
||||
}
|
||||
|
||||
if (this.current.index < 3) {
|
||||
store.currentDict.words = cloneDeep(n)
|
||||
store.currentDict.chapterWords = [store.currentDict.words]
|
||||
} 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 r = await fetch(dictResourceUrl)
|
||||
let v = await r.json()
|
||||
v.map(s => {
|
||||
s.id = nanoid(6)
|
||||
})
|
||||
if (this.currentDict.translateLanguage === 'common') {
|
||||
let r2 = await fetch('./translate/en2zh_CN-min.json')
|
||||
// fetch('http://sc.ttentau.top/en2zh_CN-min.json').then(r2 => {
|
||||
let list: Word[] = await r2.json()
|
||||
if (list && list.length) {
|
||||
runtimeStore.translateWordList = list
|
||||
}
|
||||
}
|
||||
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 r = await fetch(dictResourceUrl)
|
||||
let s: any[] = await r.json()
|
||||
this.currentDict.articles = cloneDeep(s.map(v => {
|
||||
v.id = nanoid(6)
|
||||
return v
|
||||
}))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//TODO 先这样,默认加载
|
||||
if (!runtimeStore.translateWordList.length) {
|
||||
setTimeout(async () => {
|
||||
let r2 = await fetch('./translate/en2zh_CN-min.json')
|
||||
// fetch('http://sc.ttentau.top/en2zh_CN-min.json').then(r2 => {
|
||||
let list: Word[] = await r2.json()
|
||||
if (list && list.length) {
|
||||
runtimeStore.translateWordList = list
|
||||
}
|
||||
})
|
||||
}
|
||||
emitter.emit(EventKey.changeDict)
|
||||
resolve(true)
|
||||
})
|
||||
},
|
||||
saveStatistics(statistics: DisplayStatistics) {
|
||||
if (statistics.spend > 1000 * 10) {
|
||||
delete statistics.wrongWords
|
||||
this.currentDict.statistics.push(statistics)
|
||||
}
|
||||
},
|
||||
async changeDict(dict: Dict, practiceType?: DictType, chapterIndex?: number, wordIndex?: number) {
|
||||
//TODO 保存统计
|
||||
// this.saveStatistics()
|
||||
console.log('changeDict', cloneDeep(dict), chapterIndex, wordIndex)
|
||||
if (chapterIndex === undefined) chapterIndex = dict.chapterIndex
|
||||
if (wordIndex === undefined) wordIndex = dict.wordIndex
|
||||
if (practiceType === undefined) this.current.practiceType = practiceType
|
||||
if ([DictType.collect,
|
||||
DictType.simple,
|
||||
DictType.wrong].includes(dict.type)) {
|
||||
dict.chapterIndex = 0
|
||||
dict.wordIndex = wordIndex
|
||||
dict.chapterWordNumber = dict.words.length
|
||||
dict.chapterWords = [dict.words]
|
||||
} else {
|
||||
if (dict.type === DictType.article) {
|
||||
if (chapterIndex > dict.articles.length) {
|
||||
dict.chapterIndex = 0
|
||||
dict.wordIndex = 0
|
||||
}
|
||||
} else {
|
||||
if (chapterIndex > dict.chapterWords.length) {
|
||||
dict.chapterIndex = 0
|
||||
dict.wordIndex = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
// await checkDictHasTranslate(dict)
|
||||
let rIndex = this.myDictList.findIndex((v: Dict) => v.id === dict.id)
|
||||
if (rIndex > -1) {
|
||||
this.myDictList[rIndex] = dict
|
||||
this.current.index = rIndex
|
||||
} else {
|
||||
this.myDictList.push(cloneDeep(dict))
|
||||
this.current.index = this.myDictList.length - 1
|
||||
}
|
||||
|
||||
emitter.emit(EventKey.changeDict)
|
||||
if (location.href.includes('?mode=article')) {
|
||||
console.log('文章')
|
||||
//TODO
|
||||
let dict = {
|
||||
...cloneDeep(DefaultDict),
|
||||
id: 'article_nce2',
|
||||
name: "新概念英语2-课文",
|
||||
description: '新概念英语2-课文',
|
||||
category: '英语学习',
|
||||
tags: ['新概念英语'],
|
||||
url: 'NCE_2.json',
|
||||
translateLanguage: 'common',
|
||||
language: 'en',
|
||||
type: DictType.article,
|
||||
resourceId: 'article_nce2',
|
||||
length: 96
|
||||
}
|
||||
let rIndex = this.myDictList.findIndex((v: Dict) => v.id === dict.id)
|
||||
if (rIndex > -1) {
|
||||
this.myDictList[rIndex] = dict
|
||||
this.current.index = rIndex
|
||||
} else {
|
||||
this.myDictList.push(cloneDeep(dict))
|
||||
this.current.index = this.myDictList.length - 1
|
||||
}
|
||||
}
|
||||
|
||||
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 r = await fetch(dictResourceUrl)
|
||||
let v = await r.json()
|
||||
v.map(s => {
|
||||
s.id = nanoid(6)
|
||||
})
|
||||
if (this.currentDict.translateLanguage === 'common') {
|
||||
let r2 = await fetch('./translate/en2zh_CN-min.json')
|
||||
// fetch('http://sc.ttentau.top/en2zh_CN-min.json').then(r2 => {
|
||||
let list: Word[] = await r2.json()
|
||||
if (list && list.length) {
|
||||
runtimeStore.translateWordList = list
|
||||
}
|
||||
}
|
||||
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 r = await fetch(dictResourceUrl)
|
||||
let s: any[] = await r.json()
|
||||
this.currentDict.articles = cloneDeep(s.map(v => {
|
||||
v.id = nanoid(6)
|
||||
return v
|
||||
}))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//TODO 先这样,默认加载
|
||||
if (!runtimeStore.translateWordList.length) {
|
||||
setTimeout(async () => {
|
||||
let r2 = await fetch('./translate/en2zh_CN-min.json')
|
||||
// fetch('http://sc.ttentau.top/en2zh_CN-min.json').then(r2 => {
|
||||
let list: Word[] = await r2.json()
|
||||
if (list && list.length) {
|
||||
runtimeStore.translateWordList = list
|
||||
}
|
||||
})
|
||||
}
|
||||
emitter.emit(EventKey.changeDict)
|
||||
resolve(true)
|
||||
})
|
||||
},
|
||||
saveStatistics(statistics: DisplayStatistics) {
|
||||
if (statistics.spend > 1000 * 10) {
|
||||
delete statistics.wrongWords
|
||||
this.currentDict.statistics.push(statistics)
|
||||
}
|
||||
},
|
||||
async changeDict(dict: Dict, practiceType?: DictType, chapterIndex?: number, wordIndex?: number) {
|
||||
//TODO 保存统计
|
||||
// this.saveStatistics()
|
||||
console.log('changeDict', cloneDeep(dict), chapterIndex, wordIndex)
|
||||
if (chapterIndex === undefined) chapterIndex = dict.chapterIndex
|
||||
if (wordIndex === undefined) wordIndex = dict.wordIndex
|
||||
if (practiceType === undefined) this.current.practiceType = practiceType
|
||||
if ([DictType.collect,
|
||||
DictType.simple,
|
||||
DictType.wrong].includes(dict.type)) {
|
||||
dict.chapterIndex = 0
|
||||
dict.wordIndex = wordIndex
|
||||
dict.chapterWordNumber = dict.words.length
|
||||
dict.chapterWords = [dict.words]
|
||||
} else {
|
||||
if (dict.type === DictType.article) {
|
||||
if (chapterIndex > dict.articles.length) {
|
||||
dict.chapterIndex = 0
|
||||
dict.wordIndex = 0
|
||||
}
|
||||
} else {
|
||||
if (chapterIndex > dict.chapterWords.length) {
|
||||
dict.chapterIndex = 0
|
||||
dict.wordIndex = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
// await checkDictHasTranslate(dict)
|
||||
let rIndex = this.myDictList.findIndex((v: Dict) => v.id === dict.id)
|
||||
if (rIndex > -1) {
|
||||
this.myDictList[rIndex] = dict
|
||||
this.current.index = rIndex
|
||||
} else {
|
||||
this.myDictList.push(cloneDeep(dict))
|
||||
this.current.index = this.myDictList.length - 1
|
||||
}
|
||||
|
||||
emitter.emit(EventKey.changeDict)
|
||||
}
|
||||
},
|
||||
})
|
||||
10
src/types.ts
10
src/types.ts
@@ -5,7 +5,7 @@ import myFlag from "@/assets/img/flags/my.png";
|
||||
import {DefaultChapterWordNumber} from "@/stores/setting.ts";
|
||||
|
||||
export type Word = {
|
||||
"name": string,
|
||||
"word": string,
|
||||
"usphone": string,
|
||||
"ukphone": string,
|
||||
"trans": string[]
|
||||
@@ -14,7 +14,7 @@ export type Word = {
|
||||
}
|
||||
|
||||
export const DefaultWord: Word = {
|
||||
name: '',
|
||||
word: '',
|
||||
usphone: '',
|
||||
ukphone: '',
|
||||
trans: []
|
||||
@@ -48,7 +48,7 @@ export enum DictType {
|
||||
}
|
||||
|
||||
export const DefaultArticleWord: ArticleWord = {
|
||||
name: '',
|
||||
word: '',
|
||||
usphone: '',
|
||||
ukphone: '',
|
||||
trans: [],
|
||||
@@ -194,8 +194,8 @@ export enum TranslateEngine {
|
||||
export const languageCategoryOptions = [
|
||||
{id: 'article', name: '文章', flag: bookFlag},
|
||||
{id: 'en', name: '英语', flag: enFlag},
|
||||
// {id: 'ja', name: '日语', flag: jpFlag},
|
||||
// {id: 'de', name: '德语', flag: deFlag},
|
||||
// {id: 'ja', word: '日语', flag: jpFlag},
|
||||
// {id: 'de', word: '德语', flag: deFlag},
|
||||
{id: 'code', name: 'Code', flag: codeFlag},
|
||||
{id: 'my', name: '我的', flag: myFlag},
|
||||
]
|
||||
|
||||
@@ -10,7 +10,7 @@ export const APP_NAME = 'Typing Word'
|
||||
|
||||
export const SAVE_DICT_KEY = {
|
||||
key: 'typing-word-dict',
|
||||
version: 3
|
||||
version: 4
|
||||
}
|
||||
export const SAVE_SETTING_KEY = {
|
||||
key: 'typing-word-setting',
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import localforage from "localforage";
|
||||
import {SAVE_DICT_KEY, SAVE_SETTING_KEY} from "@/utils/const.ts";
|
||||
import {BaseState, DefaultBaseState} from "@/stores/base.ts";
|
||||
import {DefaultSettingState, SettingState} from "@/stores/setting.ts";
|
||||
@@ -13,7 +12,7 @@ export function no() {
|
||||
ElMessage.warning('未现实')
|
||||
}
|
||||
|
||||
export function checkAndUpgradeSaveDict(val: string) {
|
||||
export function checkAndUpgradeSaveDict(val: any) {
|
||||
// console.log(configStr)
|
||||
// console.log('s', new Blob([val]).size)
|
||||
// val = ''
|
||||
@@ -43,6 +42,42 @@ export function checkAndUpgradeSaveDict(val: string) {
|
||||
}
|
||||
return defaultBaseState
|
||||
} else {
|
||||
if (version <= 3) {
|
||||
// if (false) {
|
||||
let temp = (list: any[]): any[] => {
|
||||
return list.map(a => {
|
||||
return {
|
||||
word: a.name,
|
||||
trans: a.trans.map(b => {
|
||||
return {
|
||||
cn: b,
|
||||
}
|
||||
}),
|
||||
phonetic0: a.usphone,
|
||||
phonetic1: a.ukphone,
|
||||
}
|
||||
})
|
||||
}
|
||||
state.myDictList.map(v => {
|
||||
if ([DictType.collect, DictType.simple, DictType.wrong].includes(v.type)) {
|
||||
v.originWords = temp(v.originWords)
|
||||
if (v.words) v.words = temp(v.words)
|
||||
v.chapterWords.map((s, i) => {
|
||||
v.chapterWords[i] = temp(s)
|
||||
})
|
||||
} else {
|
||||
if (v.isCustom) {
|
||||
if (v.type === DictType.word) {
|
||||
v.originWords = temp(v.originWords)
|
||||
if (v.words) v.words = temp(v.words)
|
||||
v.chapterWords.map((s, i) => {
|
||||
v.chapterWords[i] = temp(s)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
//防止人为删除数据,导致数据不完整报错
|
||||
for (const [key, value] of Object.entries(defaultBaseState)) {
|
||||
if (state[key] !== undefined) defaultBaseState[key] = state[key]
|
||||
@@ -56,7 +91,7 @@ export function checkAndUpgradeSaveDict(val: string) {
|
||||
return {}
|
||||
}
|
||||
|
||||
export function checkAndUpgradeSaveSetting(val: string) {
|
||||
export function checkAndUpgradeSaveSetting(val: any) {
|
||||
// console.log(configStr)
|
||||
// console.log('s', new Blob([val]).size)
|
||||
// val = ''
|
||||
@@ -124,6 +159,6 @@ export function shakeCommonDict(n: BaseState): BaseState {
|
||||
return data
|
||||
}
|
||||
|
||||
export function isMobile():boolean {
|
||||
export function isMobile(): boolean {
|
||||
return /Mobi|Android|iPhone/i.test(navigator.userAgent)
|
||||
}
|
||||
Reference in New Issue
Block a user