From 4bd9e645bd4664ef71ab93a75223c2419aafb0ab Mon Sep 17 00:00:00 2001 From: zyronon Date: Fri, 24 Nov 2023 01:17:07 +0800 Subject: [PATCH] Develop dictionary management function --- components.d.ts | 2 + package.json | 3 +- pnpm-lock.yaml | 17 ++- src/assets/css/style.scss | 2 +- src/pages/dict/DictManage.vue | 262 ++++++++++++++++++++-------------- src/stores/base.ts | 29 ++-- src/types.ts | 2 + src/utils/index.ts | 4 + 8 files changed, 195 insertions(+), 126 deletions(-) diff --git a/components.d.ts b/components.d.ts index 1db7a9f4..d7fd3c12 100644 --- a/components.d.ts +++ b/components.d.ts @@ -52,6 +52,8 @@ declare module 'vue' { PopConfirm: typeof import('./src/components/PopConfirm.vue')['default'] RepeatSetting: typeof import('./src/components/toolbar/RepeatSetting.vue')['default'] Ring: typeof import('./src/components/Ring.vue')['default'] + RouterLink: typeof import('vue-router')['RouterLink'] + RouterView: typeof import('vue-router')['RouterView'] SettingDialog: typeof import('./src/components/dialog/SettingDialog.vue')['default'] Slide: typeof import('./src/components/Slide.vue')['default'] Toolbar: typeof import('./src/components/toolbar/index.vue')['default'] diff --git a/package.json b/package.json index a55bd44a..19092615 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,6 @@ "dependencies": { "@opentranslate/baidu": "^1.4.2", "@opentranslate/translator": "^1.4.2", - "@types/uuid": "^9.0.4", "axios": "^1.5.0", "compromise": "^14.10.0", "copy-to-clipboard": "^3.3.3", @@ -29,6 +28,7 @@ "localforage": "^1.10.0", "lodash-es": "^4.17.21", "mitt": "^3.0.1", + "nanoid": "^5.0.3", "pinia": "^2.1.6", "sentence-splitter": "^4.2.1", "tesseract.js": "^4.1.1", @@ -43,6 +43,7 @@ "@iconify/vue": "^4.1.1", "@types/file-saver": "^2.0.5", "@types/lodash-es": "^4.17.9", + "@types/uuid": "^9.0.4", "@vitejs/plugin-vue": "^4.2.3", "@vitejs/plugin-vue-jsx": "^3.0.1", "@vue/compiler-sfc": "^3.3.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d2f7b80f..9f9610a3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -11,9 +11,6 @@ dependencies: '@opentranslate/translator': specifier: ^1.4.2 version: 1.4.2 - '@types/uuid': - specifier: ^9.0.4 - version: 9.0.4 axios: specifier: ^1.5.0 version: 1.5.1 @@ -44,6 +41,9 @@ dependencies: mitt: specifier: ^3.0.1 version: 3.0.1 + nanoid: + specifier: ^5.0.3 + version: 5.0.3 pinia: specifier: ^2.1.6 version: 2.1.6(typescript@5.2.2)(vue@3.3.4) @@ -82,6 +82,9 @@ devDependencies: '@types/lodash-es': specifier: ^4.17.9 version: 4.17.9 + '@types/uuid': + specifier: ^9.0.4 + version: 9.0.4 '@vitejs/plugin-vue': specifier: ^4.2.3 version: 4.3.4(vite@4.4.9)(vue@3.3.4) @@ -936,7 +939,7 @@ packages: /@types/uuid@9.0.4: resolution: {integrity: sha512-zAuJWQflfx6dYJM62vna+Sn5aeSWhh3OB+wfUEACNcqUSc0AGc5JKl+ycL1vrH7frGTXhJchYjE1Hak8L819dA==} - dev: false + dev: true /@types/web-bluetooth@0.0.16: resolution: {integrity: sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==} @@ -3580,6 +3583,12 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true + /nanoid@5.0.3: + resolution: {integrity: sha512-I7X2b22cxA4LIHXPSqbBCEQSL+1wv8TuoefejsX4HFWyC6jc5JG7CEaxOltiKjc1M+YCS2YkrZZcj4+dytw9GA==} + engines: {node: ^18 || >=20} + hasBin: true + dev: false + /nanomatch@1.2.13: resolution: {integrity: sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==} engines: {node: '>=0.10.0'} diff --git a/src/assets/css/style.scss b/src/assets/css/style.scss index ea0db548..a79011f8 100644 --- a/src/assets/css/style.scss +++ b/src/assets/css/style.scss @@ -380,7 +380,7 @@ footer { .common-title { height: 40rem; - font-size: 20rem; + font-size: 18rem; color: var(--color-font-1); display: flex; justify-content: center; diff --git a/src/pages/dict/DictManage.vue b/src/pages/dict/DictManage.vue index bd75bbcc..f51397c5 100644 --- a/src/pages/dict/DictManage.vue +++ b/src/pages/dict/DictManage.vue @@ -3,7 +3,7 @@ import {dictionaryResources} from '@/assets/dictionary.ts' import {useBaseStore} from "@/stores/base.ts" import {onMounted, reactive, watch} from "vue" import {DefaultDict, Dict, DictResource, DictType, languageCategoryOptions, Sort, Word} from "@/types.ts" -import {chunk, cloneDeep, groupBy, reverse, shuffle} from "lodash-es"; +import {assign, chunk, cloneDeep, groupBy, merge, reverse, shuffle} from "lodash-es"; import {$computed, $ref} from "vue/macros"; import {Icon} from '@iconify/vue'; import DictGroup from "@/components/toolbar/DictGroup.vue"; @@ -25,6 +25,8 @@ import {usePlayWordAudio} from "@/hooks/sound.ts"; import BaseButton from "@/components/BaseButton.vue"; import VirtualWordList from "@/components/list/VirtualWordList.vue"; import Dialog from "@/components/dialog/Dialog.vue"; +import {nanoid} from "nanoid"; +import {no} from "@/utils"; const store = useBaseStore() const settingStore = useSettingStore() @@ -35,7 +37,7 @@ let groupByLanguage = groupBy(dictionaryResources, 'language') let translateLanguageList = $ref([]) let wordList = $ref([]) -let step = $ref(0) +let step = $ref(1) let loading = $ref(false) let chapterList2 = $ref([]) let chapterWordNumber = $ref(settingStore.chapterWordNumber) @@ -78,10 +80,10 @@ async function selectDict(val: { if (!runtimeStore.editDict.originWords.length) { let r = await fetch(url) let v = await r.json() + v.map(s => s.id = nanoid(6)) runtimeStore.editDict.originWords = cloneDeep(v) changeSort(runtimeStore.editDict.sort) } - wordList = cloneDeep(runtimeStore.editDict.words) } if (runtimeStore.editDict.type === DictType.customWord) { @@ -266,6 +268,8 @@ async function onSubmit() { let wordFormData = $ref({ where: '', type: '', + name: '', + id: '', index: 0 }) @@ -279,7 +283,7 @@ const DefaultFormWord = { name: '', usphone: '', ukphone: '', - trans: '' + trans: '', } let wordFormMode = $ref(FormMode.None) @@ -317,47 +321,46 @@ async function onSubmitWord() { data.trans = [] } if (wordFormData.type === FormMode.Add) { - if (wordList.find(v => v.name === wordForm.name)) { - return ElMessage.warning('已有相同名称单词!') + data.id = nanoid(6) + data.checked = false + let r + if (wordFormData.where === 'chapter') { + r = currentChapterWordList.find(v => v.name === wordForm.name) + if (r) return ElMessage.warning('已有相同名称单词!') + else { + currentChapterWordList.push(data) + } } else { - runtimeStore.editDict.originWords.push(data) - runtimeStore.editDict.words.push(data) - - if (wordFormData.where === 'chapter') { - runtimeStore.editDict.chapterWords[chapterIndex].push(data) - } else { + r = residueWordList.find(v => v.name === wordForm.name) + if (r) return ElMessage.warning('已有相同名称单词!') + else { residueWordList.push(data) } - - ElMessage.success('添加成功') - wordForm = cloneDeep(DefaultFormWord) - setTimeout(wordListRef?.scrollToBottom, 100) } + + runtimeStore.editDict.originWords.push(data) + runtimeStore.editDict.words.push(data) + ElMessage.success('添加成功') + wordForm = cloneDeep(DefaultFormWord) + setTimeout(wordListRef?.scrollToBottom, 100) + console.log('runtimeStore.editDict', runtimeStore.editDict) } else { - let oldData + //直接使用引用修改 + let r if (wordFormData.where === 'chapter') { - oldData = cloneDeep(currentChapterWordList[wordFormData.index]) - }else { - oldData = cloneDeep(residueWordList[wordFormData.index]) - } - runtimeStore.editDict.words[wordFormData.index] = data - //因为虚拟列表,必须重新赋值才能检测到更新 - wordList = cloneDeep(runtimeStore.editDict.words) - //同步到原始列表,因为word可能是随机的,所以需要自己寻找index去修改原始列表 - let rIndex = runtimeStore.editDict.originWords.findIndex(v => v.name === oldData.name) - if (rIndex > -1) { - runtimeStore.editDict.originWords[rIndex] = data + r = currentChapterWordList.find(v => v.id === wordFormData.id) + if (r) assign(r, data) + } else { + r = residueWordList.find(v => v.id === wordFormData.id) + if (r) assign(r, data) } + //同步修改到列表 + r = runtimeStore.editDict.originWords.find(v => v.id === wordFormData.id) + if (r) assign(r, data) + r = runtimeStore.editDict.words.find(v => v.id === wordFormData.id) + if (r) assign(r, data) - runtimeStore.editDict.chapterWords = runtimeStore.editDict.chapterWords.map(list => { - let rIndex2 = list.findIndex(v => v.name === oldData.name) - if (rIndex2 > -1) { - list[rIndex2] = data - } - return list - }) - console.log('runtimeStore.editDict.chapterWords', runtimeStore.editDict.chapterWords) ElMessage.success('修改成功') } syncMyDictList() @@ -367,65 +370,50 @@ async function onSubmitWord() { }) } -function delWord(word: Word, index: number) { - //同步到原始列表,因为word可能是随机的,所以需要自己寻找index去修改原始列表 - let rIndex = runtimeStore.editDict.originWords.findIndex(v => v.name === word.name) +function addWord(where: string) { + // setTimeout(wordListRef?.scrollToBottom, 100) + wordFormData.type = FormMode.Add + wordFormData.where = where + wordForm = cloneDeep(DefaultFormWord) +} + +function delWord(word: Word, index: number, where: string) { + let rIndex = runtimeStore.editDict.originWords.findIndex(v => v.id === word.id) if (rIndex > -1) { runtimeStore.editDict.originWords.splice(rIndex, 1) } - - runtimeStore.editDict.chapterWords.map(list => { - let rIndex2 = list.findIndex(v => v.name === word.name) - if (rIndex2 > -1) { - list.splice(rIndex2, 1) - } - }) - - runtimeStore.editDict.chapterWords = runtimeStore.editDict.chapterWords.filter(v => v.length) - if (runtimeStore.editDict.chapterWords.length === 0) runtimeStore.editDict.chapterIndex = -1 - else { - if (runtimeStore.editDict.chapterIndex >= runtimeStore.editDict.chapterWords.length) { - runtimeStore.editDict.chapterIndex = runtimeStore.editDict.chapterWords.length - 1 - } + let rIndex2 = runtimeStore.editDict.words.findIndex(v => v.id === word.id) + if (rIndex2 > -1) { + runtimeStore.editDict.words.splice(rIndex2, 1) } - runtimeStore.editDict.words.splice(index, 1) - wordList = cloneDeep(runtimeStore.editDict.words) - syncMyDictList() + if (where === 'chapter') { + currentChapterWordList.splice(index, 1) + } else { + residueWordList.splice(index, 1) + } - closeWordForm() + if (wordFormData.type === FormMode.Edit && wordForm.name === word.name) { + closeWordForm() + } + syncMyDictList() } -function editWord(val: { - word: Word, - index: number -}) { - wordFormMode = val.index - wordForm.name = val.word.name - wordForm.ukphone = val.word.ukphone - wordForm.usphone = val.word.usphone - wordForm.trans = val.word.trans.join('\n') +function editWord(word: Word, index: number, where: string) { + wordFormData.type = FormMode.Edit + wordFormData.id = word.id + wordFormData.where = where + wordForm.name = word.name + wordForm.ukphone = word.ukphone + wordForm.usphone = word.usphone + wordForm.trans = word.trans.join('\n') } function closeWordForm() { - wordFormMode = FormMode.None + wordFormData.type = FormMode.None wordForm = cloneDeep(DefaultFormWord) } -function addWord() { - // setTimeout(wordListRef?.scrollToBottom, 100) - wordFormMode = FormMode.Add - wordForm = cloneDeep(DefaultFormWord) -} - -function add() { - if (dictIsArticle) { - - } else { - addWord() - } -} - /**/ /* 单词修改相关*/ /**/ @@ -438,7 +426,14 @@ watch(() => step, v => { } }) +watch(() => store.load, v => { + if (v) { + selectDict({dict: store.currentDict, index: 0}) + } +}) + const playWordAudio = usePlayWordAudio() +let showAllocationChapterDialog = $ref(false) onMounted(() => { dictionaryResources.map(v => { @@ -456,6 +451,8 @@ onMounted(() => { } }) + selectDict({dict: store.currentDict, index: 0}) + emitter.on(EventKey.openDictModal, (type: 'detail' | 'list' | 'my' | 'collect' | 'simple') => { if (type === "detail") { selectDict({dict: store.currentDict, index: 0}) @@ -496,8 +493,20 @@ let residueWordListCheckedTotal = $computed(() => { return residueWordList.filter(v => v.checked).length }) +function handleChangeCurrentChapter(index: number) { + currentChapterWordList.map(v => v.checked = false) + currentChapterWordListCheckAll = currentChapterWordListIsIndeterminate = false + chapterIndex = index + closeWordForm() +} + function toResidueWordList() { let list = currentChapterWordList.filter(v => v.checked) + if (wordFormData.type === FormMode.Edit && wordFormData.where === 'chapter') { + if (list.find(v => v.name === wordForm.name)) { + wordFormData.where = 'residue' + } + } runtimeStore.editDict.chapterWords[chapterIndex] = currentChapterWordList.filter(v => !v.checked) list.map(v => v.checked = false) residueWordList = residueWordList.concat(list) @@ -506,6 +515,11 @@ function toResidueWordList() { function toChapterWordList() { let list = residueWordList.filter(v => v.checked) + if (wordFormData.type === FormMode.Edit && wordFormData.where !== 'chapter') { + if (list.find(v => v.name === wordForm.name)) { + wordFormData.where = 'chapter' + } + } residueWordList = residueWordList.filter(v => !v.checked) list.map(v => v.checked = false) runtimeStore.editDict.chapterWords[chapterIndex] = runtimeStore.editDict.chapterWords[chapterIndex].concat(list) @@ -528,8 +542,6 @@ function delWordChapter(index: number) { syncMyDictList() } -let showAllocationChapterDialog = $ref(false) - function resetChapterList() { residueWordList = [] chapterIndex = -1 @@ -568,6 +580,15 @@ function handleCurrentResidueWordListCheckAll() { residueWordListIsIndeterminate = false } +function exportData() { + no() +} + +function importData() { + no() +} + +