Develop dictionary management function
This commit is contained in:
@@ -1,8 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import {useBaseStore} from "@/stores/base.ts"
|
||||
import {nextTick, onMounted, watch} from "vue"
|
||||
import {Dict, DictResource, DictType, Sort} from "@/types.ts"
|
||||
import {cloneDeep, reverse, shuffle} from "lodash-es";
|
||||
import {Dict, DictResource, DictType} from "@/types.ts"
|
||||
import {$ref} from "vue/macros";
|
||||
import "vue-activity-calendar/style.css";
|
||||
import {useRuntimeStore} from "@/stores/runtime.ts";
|
||||
@@ -11,27 +10,26 @@ import {emitter, EventKey} from "@/utils/eventBus.ts";
|
||||
import Slide from "@/components/Slide.vue";
|
||||
import ArticleDictDetail from "@/pages/dict/components/ArticleDictDetail.vue";
|
||||
import WordDictDetail from "@/pages/dict/components/WordDictDetail.vue";
|
||||
import DictListPanel from "@/pages/dict/components/DictListPanel.vue";
|
||||
import DictListPanel from "@/components/DictListPanel.vue";
|
||||
import EditDict from "@/pages/dict/components/EditDict.vue";
|
||||
import {useRoute} from "vue-router";
|
||||
|
||||
|
||||
const route = useRoute()
|
||||
const store = useBaseStore()
|
||||
const settingStore = useSettingStore()
|
||||
const runtimeStore = useRuntimeStore()
|
||||
let detailRef = $ref()
|
||||
let dictIsArticle = $ref(false)
|
||||
let step = $ref(1)
|
||||
let step = $ref(0)
|
||||
let isAddDict = $ref(false)
|
||||
|
||||
async function selectDict(val: {
|
||||
dict: DictResource | Dict,
|
||||
index: number
|
||||
}) {
|
||||
async function selectDict(val: { dict: DictResource | Dict }, cb?: any) {
|
||||
step = 1
|
||||
isAddDict = false
|
||||
dictIsArticle = val.dict.type === DictType.article
|
||||
nextTick(() => {
|
||||
detailRef?.getDictDetail(val)
|
||||
cb?.()
|
||||
})
|
||||
}
|
||||
|
||||
@@ -39,58 +37,63 @@ function changeDict() {
|
||||
store.changeDict(runtimeStore.editDict)
|
||||
}
|
||||
|
||||
function changeSort(v: Sort) {
|
||||
if (v === Sort.normal) {
|
||||
runtimeStore.editDict.words = cloneDeep(runtimeStore.editDict.originWords)
|
||||
} else if (v === Sort.random) {
|
||||
runtimeStore.editDict.words = shuffle(runtimeStore.editDict.originWords)
|
||||
} else {
|
||||
runtimeStore.editDict.words = reverse(runtimeStore.editDict.originWords)
|
||||
}
|
||||
// resetChapterList()
|
||||
}
|
||||
|
||||
/**/
|
||||
/*词典相关*/
|
||||
/**/
|
||||
|
||||
|
||||
let categoryList = {}
|
||||
let tagList = {}
|
||||
|
||||
|
||||
/**/
|
||||
/*词典相关*/
|
||||
/**/
|
||||
|
||||
watch(() => step, v => {
|
||||
if (v === 0) {
|
||||
// closeWordForm()
|
||||
// closeDictForm()
|
||||
// chapterWordNumber = settingStore.chapterWordNumber
|
||||
}
|
||||
})
|
||||
|
||||
watch(() => store.load, v => {
|
||||
if (v) {
|
||||
selectDict({dict: store.currentDict, index: 0})
|
||||
// selectDict({dict: store.currentDict, index: 0})
|
||||
}
|
||||
})
|
||||
|
||||
function addDict() {
|
||||
step = 1
|
||||
isAddDict = true
|
||||
}
|
||||
|
||||
function back() {
|
||||
step = 0
|
||||
}
|
||||
|
||||
function cancelAddDict() {
|
||||
step = 0
|
||||
setTimeout(() => {
|
||||
isAddDict = false
|
||||
}, 500)
|
||||
}
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
|
||||
selectDict({dict: store.currentDict, index: 0})
|
||||
|
||||
// selectDict({dict: store.currentDict, index: 0})
|
||||
console.log('router.params', route)
|
||||
switch (route.query.type) {
|
||||
case 'addDict':
|
||||
setTimeout(() => {
|
||||
addDict()
|
||||
}, 300)
|
||||
break
|
||||
case 'addWordOrArticle':
|
||||
setTimeout(() => {
|
||||
selectDict({dict: runtimeStore.editDict}, () => {
|
||||
detailRef?.add()
|
||||
})
|
||||
}, 300)
|
||||
break
|
||||
case 'editDict':
|
||||
setTimeout(() => {
|
||||
selectDict({dict: runtimeStore.editDict}, () => {
|
||||
detailRef?.editDict()
|
||||
})
|
||||
}, 300)
|
||||
break
|
||||
}
|
||||
emitter.on(EventKey.openDictModal, (type: 'detail' | 'list' | 'my' | 'collect' | 'simple') => {
|
||||
if (type === "detail") {
|
||||
selectDict({dict: store.currentDict, index: 0})
|
||||
selectDict({dict: store.currentDict})
|
||||
}
|
||||
if (type === "list") {
|
||||
currentLanguage = 'en'
|
||||
// currentLanguage = 'en'
|
||||
step = 0
|
||||
}
|
||||
if (type === "my") {
|
||||
currentLanguage = 'my'
|
||||
// currentLanguage = 'my'
|
||||
step = 0
|
||||
}
|
||||
if (type === "collect") {
|
||||
@@ -105,19 +108,6 @@ onMounted(() => {
|
||||
// console.log('categoryList', categoryList)
|
||||
// console.log('tagList', tagList)
|
||||
})
|
||||
|
||||
|
||||
function addDict() {
|
||||
step = 1
|
||||
isAddDict = true
|
||||
}
|
||||
|
||||
function back() {
|
||||
step = 0
|
||||
// isAddDict = false
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -131,7 +121,7 @@ function back() {
|
||||
<EditDict
|
||||
v-if="isAddDict"
|
||||
:isAdd="true"
|
||||
@cancel="isAddDict = false;step = 0"
|
||||
@cancel="cancelAddDict"
|
||||
@submit="selectDict({dict:runtimeStore.editDict})"/>
|
||||
<template v-else>
|
||||
<ArticleDictDetail
|
||||
@@ -151,11 +141,6 @@ function back() {
|
||||
<style scoped lang="scss">
|
||||
@import "@/assets/css/variable";
|
||||
|
||||
$modal-mask-bg: rgba(#000, .15);
|
||||
$radius: 16rem;
|
||||
$time: 0.3s;
|
||||
$header-height: 60rem;
|
||||
|
||||
#DictDialog {
|
||||
font-size: 14rem;
|
||||
position: fixed;
|
||||
|
||||
@@ -219,9 +219,15 @@ function exportData(val: { type: string, data?: Article }) {
|
||||
}
|
||||
|
||||
function editDict() {
|
||||
isEditDict = true
|
||||
}
|
||||
|
||||
defineExpose({getDictDetail})
|
||||
function add() {
|
||||
emitter.emit(EventKey.openArticleListModal)
|
||||
}
|
||||
|
||||
defineExpose({getDictDetail, add, editDict})
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
@@ -237,7 +243,7 @@ defineExpose({getDictDetail})
|
||||
{{ runtimeStore.editDict.name }}
|
||||
</div>
|
||||
<template v-if="!isPinDict">
|
||||
<BaseIcon icon="tabler:edit" @click='isEditDict = true'/>
|
||||
<BaseIcon icon="tabler:edit" @click='editDict'/>
|
||||
<BaseIcon icon="ph:star" @click='no'/>
|
||||
<BaseButton size="small" v-if="runtimeStore.editDict.isCustom" @click="resetDict">恢复默认</BaseButton>
|
||||
</template>
|
||||
@@ -283,7 +289,7 @@ defineExpose({getDictDetail})
|
||||
<span>文章管理</span>
|
||||
<div class="options">
|
||||
<BaseIcon
|
||||
@click="emitter.emit(EventKey.openArticleListModal)"
|
||||
@click="add"
|
||||
icon="fluent:add-20-filled"
|
||||
title="新增章节"/>
|
||||
<span>{{ runtimeStore.editDict.articles.length }}篇</span>
|
||||
|
||||
@@ -16,6 +16,7 @@ const props = defineProps<{
|
||||
emptyTitle?: string,
|
||||
showAdd?: boolean,
|
||||
list: Word[]
|
||||
canOperation: boolean
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
@@ -95,7 +96,7 @@ useWindowClick(() => show = false)
|
||||
<div class="header">
|
||||
<div class="common-title">
|
||||
<span>{{ title }}</span>
|
||||
<div class="options">
|
||||
<div class="options" v-if="canOperation">
|
||||
<div class="setting"
|
||||
v-if="list.length"
|
||||
@click.stop="null">
|
||||
@@ -125,7 +126,7 @@ useWindowClick(() => show = false)
|
||||
</div>
|
||||
</div>
|
||||
<div class="select"
|
||||
v-if="list.length"
|
||||
v-if="list.length && canOperation"
|
||||
>
|
||||
<div class="left">
|
||||
<el-checkbox
|
||||
@@ -145,12 +146,12 @@ useWindowClick(() => show = false)
|
||||
v-if="list.length"
|
||||
@click="handleCheckedChange"
|
||||
>
|
||||
<template v-slot:prefix="{word}">
|
||||
<template v-slot:prefix="{word}" v-if="canOperation">
|
||||
<el-checkbox v-model="word.checked"
|
||||
@change="handleCheckedChange({word})"
|
||||
size="large"/>
|
||||
</template>
|
||||
<template v-slot="{word,index}">
|
||||
<template v-slot="{word,index}" v-if="canOperation">
|
||||
<BaseIcon
|
||||
class-name="del"
|
||||
@click="emit('edit',{word,index})"
|
||||
|
||||
@@ -1,179 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
|
||||
import {DictResource, languageCategoryOptions} from "@/types.ts";
|
||||
import {$computed, $ref} from "vue/macros";
|
||||
import {dictionaryResources} from "@/assets/dictionary.ts";
|
||||
import {groupBy} from "lodash-es";
|
||||
import {useBaseStore} from "@/stores/base.ts";
|
||||
import {useSettingStore} from "@/stores/setting.ts";
|
||||
import {useRuntimeStore} from "@/stores/runtime.ts";
|
||||
import DictList from "@/components/list/DictList.vue";
|
||||
import DictGroup from "@/components/toolbar/DictGroup.vue";
|
||||
|
||||
const emit = defineEmits<{
|
||||
add: [],
|
||||
selectDict: [val: { dict: any, index: number }]
|
||||
}>()
|
||||
const store = useBaseStore()
|
||||
const settingStore = useSettingStore()
|
||||
const runtimeStore = useRuntimeStore()
|
||||
|
||||
let currentLanguage = $ref('my')
|
||||
let currentTranslateLanguage = $ref('common')
|
||||
let groupByLanguage = groupBy(dictionaryResources, 'language')
|
||||
let translateLanguageList = $ref([])
|
||||
|
||||
function groupByDictTags(dictList: DictResource[]) {
|
||||
return dictList.reduce<Record<string, DictResource[]>>((result, dict) => {
|
||||
dict.tags.forEach((tag) => {
|
||||
if (Object.prototype.hasOwnProperty.call(result, tag)) {
|
||||
result[tag].push(dict)
|
||||
} else {
|
||||
result[tag] = [dict]
|
||||
}
|
||||
})
|
||||
return result
|
||||
}, {})
|
||||
}
|
||||
|
||||
const groupByTranslateLanguage = $computed(() => {
|
||||
let data: any
|
||||
if (currentLanguage === 'article') {
|
||||
let articleList = dictionaryResources.filter(v => v.type === 'article')
|
||||
data = groupBy(articleList, 'translateLanguage')
|
||||
} else if (currentLanguage === 'my') {
|
||||
data = {
|
||||
common: store.myDictList.concat([{name: '',} as any])
|
||||
}
|
||||
} else {
|
||||
data = groupBy(groupByLanguage[currentLanguage], 'translateLanguage')
|
||||
}
|
||||
// console.log('groupByTranslateLanguage', data)
|
||||
translateLanguageList = Object.keys(data)
|
||||
currentTranslateLanguage = translateLanguageList[0]
|
||||
return data
|
||||
})
|
||||
|
||||
const groupedByCategoryAndTag = $computed(() => {
|
||||
const currentTranslateLanguageDictList = groupByTranslateLanguage[currentTranslateLanguage]
|
||||
const groupByCategory = groupBy(currentTranslateLanguageDictList, 'category')
|
||||
|
||||
let data = []
|
||||
for (const [key, value] of Object.entries(groupByCategory)) {
|
||||
data.push([key, groupByDictTags(value)])
|
||||
}
|
||||
// console.log('groupedByCategoryAndTag', data)
|
||||
return data
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="dict-list-panel">
|
||||
<header>
|
||||
<div class="tabs">
|
||||
<div class="tab"
|
||||
:class="currentLanguage === item.id && 'active'"
|
||||
@click="currentLanguage = item.id"
|
||||
v-for="item in languageCategoryOptions">
|
||||
<img :src='item.flag' alt=""/>
|
||||
<span>{{ item.name }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<div class="page-content">
|
||||
<div class="dict-list-wrapper">
|
||||
<template v-if="currentLanguage === 'my'">
|
||||
<DictList
|
||||
@add="emit('add')"
|
||||
@selectDict="e => emit('selectDict',e)"
|
||||
:list="groupByTranslateLanguage['common']"/>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class="translate">
|
||||
<span>翻译:</span>
|
||||
<el-radio-group v-model="currentTranslateLanguage">
|
||||
<el-radio-button border v-for="i in translateLanguageList" :label="i">{{ i }}</el-radio-button>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
<DictGroup
|
||||
v-for="item in groupedByCategoryAndTag"
|
||||
:select-dict-name="runtimeStore.editDict.resourceId"
|
||||
@selectDict="e => emit('selectDict',e)"
|
||||
:groupByTag="item[1]"
|
||||
:category="item[0]"
|
||||
/>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "@/assets/css/variable";
|
||||
|
||||
.dict-list-panel {
|
||||
width: 50%;
|
||||
height: 100%;
|
||||
$header-height: 60rem;
|
||||
padding: var(--space);
|
||||
padding-top: 0;
|
||||
box-sizing: border-box;
|
||||
|
||||
header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
height: $header-height;
|
||||
|
||||
.tabs {
|
||||
display: flex;
|
||||
gap: 20rem;
|
||||
|
||||
.tab {
|
||||
color: var(--color-font-1);
|
||||
cursor: pointer;
|
||||
padding: 10rem;
|
||||
padding-bottom: 5rem;
|
||||
transition: all .5s;
|
||||
border-bottom: 2px solid transparent;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6rem;
|
||||
|
||||
&.active {
|
||||
border-bottom: 2px solid $main;
|
||||
}
|
||||
|
||||
img {
|
||||
height: 30rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.page-content {
|
||||
display: flex;
|
||||
height: calc(100% - $header-height);
|
||||
|
||||
.dict-list-wrapper {
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
height: 100%;
|
||||
padding-right: var(--space);
|
||||
|
||||
.translate {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: var(--color-font-1);
|
||||
margin-bottom: 30rem;
|
||||
|
||||
& > span {
|
||||
font-size: 22rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -9,7 +9,7 @@ import {assign, chunk, cloneDeep, reverse, shuffle} from "lodash-es";
|
||||
import {DefaultDict, Dict, DictResource, DictType, Sort, Word} from "@/types.ts";
|
||||
import {nanoid} from "nanoid";
|
||||
import {FormInstance, FormRules} from "element-plus";
|
||||
import {reactive, watch} from "vue";
|
||||
import {reactive} from "vue";
|
||||
import {useRuntimeStore} from "@/stores/runtime.ts";
|
||||
import {useBaseStore} from "@/stores/base.ts";
|
||||
import {useSettingStore} from "@/stores/setting.ts";
|
||||
@@ -48,6 +48,9 @@ useWindowClick(() => showExport = false)
|
||||
const isPinDict = $computed(() => {
|
||||
return [DictType.collect, DictType.wrong, DictType.simple].includes(runtimeStore.editDict.type)
|
||||
})
|
||||
const isCanOperation = $computed(() => {
|
||||
return runtimeStore.editDict.type !== DictType.wrong
|
||||
})
|
||||
|
||||
let chapterWordList: Word[] = $computed({
|
||||
get() {
|
||||
@@ -106,7 +109,7 @@ function addNewChapter() {
|
||||
runtimeStore.editDict.chapterWords.push([])
|
||||
chapterList2 = Array.from({length: runtimeStore.editDict.chapterWords.length}).map((v, i) => ({id: i}))
|
||||
ElMessage.success('新增章节成功')
|
||||
setTimeout(() => chapterListRef?.scrollToItem(chapterList2.length -1), 100)
|
||||
setTimeout(() => chapterListRef?.scrollToItem(chapterList2.length - 1), 100)
|
||||
}
|
||||
|
||||
function delWordChapter(index: number) {
|
||||
@@ -490,7 +493,11 @@ function importData(e: any) {
|
||||
reader.readAsBinaryString(file);
|
||||
}
|
||||
|
||||
defineExpose({getDictDetail})
|
||||
function editDict() {
|
||||
isEditDict = true
|
||||
}
|
||||
|
||||
defineExpose({getDictDetail, add: addWord, editDict})
|
||||
|
||||
</script>
|
||||
|
||||
@@ -506,7 +513,7 @@ defineExpose({getDictDetail})
|
||||
{{ runtimeStore.editDict.name }}
|
||||
</div>
|
||||
<template v-if="!isPinDict">
|
||||
<BaseIcon icon="tabler:edit" @click='isEditDict = true'/>
|
||||
<BaseIcon icon="tabler:edit" @click='editDict'/>
|
||||
<BaseIcon icon="ph:star" @click='no'/>
|
||||
<BaseButton size="small" v-if="runtimeStore.editDict.isCustom" @click="resetDict">恢复默认</BaseButton>
|
||||
</template>
|
||||
@@ -552,13 +559,14 @@ defineExpose({getDictDetail})
|
||||
<span>章节管理</span>
|
||||
<div class="options">
|
||||
<BaseIcon
|
||||
v-if="isCanOperation"
|
||||
@click="addNewChapter"
|
||||
icon="fluent:add-20-filled"
|
||||
title="新增章节"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="select">
|
||||
<BaseButton size="small" @click="showAllocationChapterDialog = true">智能分配</BaseButton>
|
||||
<BaseButton v-if="isCanOperation" size="small" @click="showAllocationChapterDialog = true">智能分配</BaseButton>
|
||||
<span>{{ runtimeStore.editDict.chapterWords.length }}章</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -583,7 +591,9 @@ defineExpose({getDictDetail})
|
||||
<span>{{ runtimeStore.editDict.chapterWords[item.id]?.length }}词</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="right">
|
||||
<div class="right"
|
||||
v-if="isCanOperation"
|
||||
>
|
||||
<BaseIcon
|
||||
class-name="del"
|
||||
@click="delWordChapter(item.id)"
|
||||
@@ -598,6 +608,7 @@ defineExpose({getDictDetail})
|
||||
</div>
|
||||
<ChapterWordList
|
||||
ref="chapterWordListRef"
|
||||
:can-operation="isCanOperation"
|
||||
:title="`${chapterIndex > -1 ? `第${chapterIndex + 1}章` : ''} 单词列表`"
|
||||
:show-add="chapterIndex > -1"
|
||||
@add="addWord('chapter')"
|
||||
@@ -605,7 +616,7 @@ defineExpose({getDictDetail})
|
||||
:empty-title="chapterIndex === -1?'请选择章节':null"
|
||||
@edit="val => editWord(val.word,val.index,'chapter')"
|
||||
v-model:list="chapterWordList"/>
|
||||
<div class="options-column">
|
||||
<div class="options-column" v-if="isCanOperation">
|
||||
<BaseButton @click="toChapterWordList"
|
||||
:disabled="residueWordListCheckedTotal === 0">
|
||||
<
|
||||
@@ -616,6 +627,8 @@ defineExpose({getDictDetail})
|
||||
</BaseButton>
|
||||
</div>
|
||||
<ChapterWordList
|
||||
v-if="isCanOperation"
|
||||
:can-operation="isCanOperation"
|
||||
ref="residueWordListRef"
|
||||
title="未分配单词列表"
|
||||
:empty-title="null"
|
||||
|
||||
@@ -1,13 +1,20 @@
|
||||
<script setup lang="ts">
|
||||
|
||||
import DictManage from "@/pages/dict/DictManage.vue";
|
||||
import {onMounted} from "vue";
|
||||
import {useRoute} from "vue-router";
|
||||
|
||||
const router = useRoute()
|
||||
|
||||
onMounted(()=>{
|
||||
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div id="page">
|
||||
<DictManage/>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
@@ -9,7 +9,6 @@ import BaseButton from "@/components/BaseButton.vue";
|
||||
import {useSettingStore} from "@/stores/setting.ts";
|
||||
import Close from "@/components/icon/Close.vue";
|
||||
import Empty from "@/components/Empty.vue";
|
||||
import ArticleList from "@/components/article/ArticleList-FQ.vue";
|
||||
import {useArticleOptions, useWordOptions} from "@/hooks/dict.ts";
|
||||
import {Icon} from "@iconify/vue";
|
||||
import Tooltip from "@/components/Tooltip.vue";
|
||||
@@ -18,8 +17,13 @@ import CommonWordList from "@/components/list/CommonWordList.vue";
|
||||
import BaseIcon from "@/components/BaseIcon.vue";
|
||||
import {emitter, EventKey} from "@/utils/eventBus.ts";
|
||||
import ArticleList2 from "@/components/list/ArticleList2.vue";
|
||||
import {useRouter} from "vue-router";
|
||||
import {useRuntimeStore} from "@/stores/runtime.ts";
|
||||
import {cloneDeep} from "lodash-es";
|
||||
|
||||
const router = useRouter()
|
||||
const store = useBaseStore()
|
||||
const runtimeStore = useRuntimeStore()
|
||||
const settingStore = useSettingStore()
|
||||
let tabIndex = $ref(0)
|
||||
provide('tabIndex', computed(() => tabIndex))
|
||||
@@ -53,6 +57,16 @@ const {
|
||||
toggleArticleCollect
|
||||
} = useArticleOptions()
|
||||
|
||||
function addCollect() {
|
||||
runtimeStore.editDict = cloneDeep(store.collect)
|
||||
router.push({path: '/dict', query: {type: 'addWordOrArticle'}})
|
||||
}
|
||||
|
||||
function addSimple() {
|
||||
runtimeStore.editDict = cloneDeep(store.simple)
|
||||
router.push({path: '/dict', query: {type: 'addWordOrArticle'}})
|
||||
}
|
||||
|
||||
</script>
|
||||
<template>
|
||||
<Transition name="fade">
|
||||
@@ -94,7 +108,7 @@ const {
|
||||
</div>
|
||||
<Tooltip title="添加">
|
||||
<IconWrapper>
|
||||
<Icon icon="fluent:add-12-regular" @click="emitter.emit(EventKey.openDictModal,'collect')"/>
|
||||
<Icon icon="fluent:add-12-regular" @click="addCollect"/>
|
||||
</IconWrapper>
|
||||
</Tooltip>
|
||||
</div>
|
||||
@@ -151,7 +165,7 @@ const {
|
||||
<div class="dict-name">总词数:{{ store.simple.words.length }}</div>
|
||||
<Tooltip title="添加">
|
||||
<IconWrapper>
|
||||
<Icon icon="fluent:add-12-regular" @click="emitter.emit(EventKey.openDictModal,'simple')"/>
|
||||
<Icon icon="fluent:add-12-regular" @click="addSimple"/>
|
||||
</IconWrapper>
|
||||
</Tooltip>
|
||||
</div>
|
||||
|
||||
@@ -1,16 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import {$ref} from "vue/macros";
|
||||
import TypingArticle from "./TypingArticle.vue";
|
||||
import {
|
||||
Article,
|
||||
ArticleWord,
|
||||
DefaultArticle,
|
||||
DefaultWord,
|
||||
DisplayStatistics,
|
||||
ShortcutKey,
|
||||
TranslateType,
|
||||
Word
|
||||
} from "@/types.ts";
|
||||
import {Article, ArticleWord, DefaultArticle, DisplayStatistics, ShortcutKey, TranslateType, Word} from "@/types.ts";
|
||||
import {cloneDeep} from "lodash-es";
|
||||
import TypingWord from "@/pages/practice/practice-word/TypingWord.vue";
|
||||
import Panel from "../Panel.vue";
|
||||
@@ -21,7 +12,6 @@ import {useBaseStore} from "@/stores/base.ts";
|
||||
import EditSingleArticleModal from "@/components/article/EditSingleArticleModal.vue";
|
||||
import {usePracticeStore} from "@/stores/practice.ts";
|
||||
import {emitter, EventKey} from "@/utils/eventBus.ts";
|
||||
import ArticleList from "@/components/article/ArticleList-FQ.vue";
|
||||
import IconWrapper from "@/components/IconWrapper.vue";
|
||||
import {Icon} from "@iconify/vue";
|
||||
import Tooltip from "@/components/Tooltip.vue";
|
||||
|
||||
Reference in New Issue
Block a user