save
This commit is contained in:
1
components.d.ts
vendored
1
components.d.ts
vendored
@@ -9,7 +9,6 @@ declare module 'vue' {
|
||||
export interface GlobalComponents {
|
||||
Add: typeof import('./src/components/Toolbar/Add.vue')['default']
|
||||
AddDict: typeof import('./src/components/Add/AddDict.vue')['default']
|
||||
AddWordDialog: typeof import('./src/components/Modal/AddWordDialog.vue')['default']
|
||||
ArticleList: typeof import('./src/components/Article/ArticleList.vue')['default']
|
||||
Backgorund: typeof import('./src/components/Backgorund.vue')['default']
|
||||
BaseButton: typeof import('./src/components/BaseButton.vue')['default']
|
||||
|
||||
@@ -2327,7 +2327,7 @@ const enArticle: DictResource[] = [
|
||||
description: '新概念英语2-课文',
|
||||
category: '英语学习',
|
||||
tags: ['新概念英语'],
|
||||
url: '/articles/NCE_2.json',
|
||||
url: 'NCE_2.json',
|
||||
length: 5892,
|
||||
translateLanguage: 'common',
|
||||
language: 'en',
|
||||
|
||||
@@ -1,567 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
|
||||
import {$computed, $ref} from "vue/macros";
|
||||
import Slide from "@/components/Slide.vue";
|
||||
import DictList from "@/components/list/DictList.vue";
|
||||
import {Icon} from "@iconify/vue";
|
||||
import {useBaseStore} from "@/stores/base.ts";
|
||||
import {useSettingStore} from "@/stores/setting.ts";
|
||||
import {useRuntimeStore} from "@/stores/runtime.ts";
|
||||
import {useDisableEventListener} from "@/hooks/event.ts";
|
||||
import {DefaultDict, Dict, DictType, Word} from "@/types.ts";
|
||||
import {onMounted, reactive, watch} from "vue";
|
||||
import {FormInstance, FormRules} from "element-plus";
|
||||
import {dictionaryResources} from "@/assets/dictionary.ts";
|
||||
import {cloneDeep} from "lodash-es";
|
||||
import Empty from "@/components/Empty.vue";
|
||||
import BaseIcon from "@/components/BaseIcon.vue";
|
||||
import VirtualWordList from "@/components/list/VirtualWordList.vue";
|
||||
import Modal from "@/components/Modal/Modal.vue";
|
||||
import {emitter, EventKey} from "@/utils/eventBus.ts";
|
||||
|
||||
|
||||
const store = useBaseStore()
|
||||
|
||||
const emit = defineEmits([
|
||||
'close',
|
||||
])
|
||||
|
||||
let step = $ref(1)
|
||||
let isAddDict = $ref(false)
|
||||
let wordList = $ref([])
|
||||
|
||||
let dictList: Dict[] = $computed(() => {
|
||||
return [
|
||||
store.collect,
|
||||
store.simple,
|
||||
store.wrong
|
||||
].concat(store.myDicts.filter(v => [DictType.customWord, DictType.customArticle].includes(v.type)))
|
||||
.concat([{name: '',} as any])
|
||||
})
|
||||
|
||||
let categoryList = {}
|
||||
let tagList = {}
|
||||
|
||||
const DefaultDictForm = {
|
||||
id: '',
|
||||
name: '',
|
||||
description: '',
|
||||
category: '',
|
||||
tags: [],
|
||||
translateLanguage: 'zh-CN',
|
||||
language: 'en',
|
||||
type: DictType.customWord
|
||||
}
|
||||
let dictForm: any = $ref(cloneDeep(DefaultDictForm))
|
||||
const dictFormRef = $ref<FormInstance>()
|
||||
const dictRules = reactive<FormRules>({
|
||||
name: [
|
||||
{required: true, message: '请输入名称', trigger: 'blur'},
|
||||
{max: 20, message: '名称不能超过20个字符', trigger: 'blur'},
|
||||
],
|
||||
category: [{required: true, message: '请选择', trigger: 'change'}],
|
||||
tags: [{required: true, message: '请选择', trigger: 'change'}],
|
||||
})
|
||||
|
||||
watch(() => dictForm.language, () => isAddDict && (dictForm.category = ''))
|
||||
watch(() => dictForm.category, () => isAddDict && (dictForm.tags = []))
|
||||
|
||||
onMounted(() => {
|
||||
dictionaryResources.map(v => {
|
||||
if (categoryList[v.language]) {
|
||||
if (!categoryList[v.language].find(w => w === v.category)) {
|
||||
categoryList[v.language].push(v.category)
|
||||
}
|
||||
} else {
|
||||
categoryList[v.language] = [v.category]
|
||||
}
|
||||
if (tagList[v.category]) {
|
||||
tagList[v.category] = Array.from(new Set(tagList[v.category].concat(v.tags)))
|
||||
} else {
|
||||
tagList[v.category] = v.tags
|
||||
}
|
||||
})
|
||||
|
||||
// console.log('categoryList', categoryList)
|
||||
// console.log('tagList', tagList)
|
||||
})
|
||||
|
||||
function selectDict(val: { index: number }) {
|
||||
store.current.editIndex = val.index
|
||||
wordList = cloneDeep(store.editDict.originWords)
|
||||
isAddDict = false
|
||||
step = 1
|
||||
}
|
||||
|
||||
function editDict() {
|
||||
// dictForm.id = store.editDict.id
|
||||
// dictForm.name = store.editDict.name
|
||||
// dictForm.description = store.editDict.description
|
||||
console.log('store.editDict', store.editDict)
|
||||
dictForm = cloneDeep(store.editDict)
|
||||
//直接复制,上面会watch到category,然后把tags 设置为空
|
||||
setTimeout(() => isAddDict = true, 0)
|
||||
}
|
||||
|
||||
function closeDictForm() {
|
||||
if (dictForm.id) {
|
||||
isAddDict = false
|
||||
dictForm = cloneDeep(DefaultDictForm)
|
||||
} else {
|
||||
step = 0
|
||||
}
|
||||
}
|
||||
|
||||
async function onSubmit() {
|
||||
await dictFormRef.validate((valid, fields) => {
|
||||
if (valid) {
|
||||
let data: Dict = {
|
||||
...DefaultDict,
|
||||
...dictForm,
|
||||
}
|
||||
if (data.id) {
|
||||
let rIndex = store.myDicts.findIndex(v => v.id === data.id)
|
||||
store.myDicts[rIndex] = cloneDeep(data)
|
||||
isAddDict = false
|
||||
ElMessage.success('修改成功')
|
||||
} else {
|
||||
data.id = 'custom-dict-' + Date.now()
|
||||
if (store.myDicts.find(v => v.name === dictForm.name)) {
|
||||
return ElMessage.warning('已有相同名称词典!')
|
||||
} else {
|
||||
store.myDicts.push(cloneDeep(data))
|
||||
store.current.editIndex = 3 + store.myDicts.filter(v => [DictType.customWord, DictType.customArticle].includes(v.type)).length - 1
|
||||
isAddDict = false
|
||||
ElMessage.success('添加成功')
|
||||
}
|
||||
}
|
||||
console.log('submit!', data)
|
||||
|
||||
} else {
|
||||
ElMessage.warning('请填写完整')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**/
|
||||
/**/
|
||||
/**/
|
||||
enum FormMode {
|
||||
None = -1,
|
||||
Add = -2,
|
||||
}
|
||||
|
||||
const DefaultFormWord = {
|
||||
name: '',
|
||||
usphone: '',
|
||||
ukphone: '',
|
||||
trans: ''
|
||||
}
|
||||
|
||||
let wordFormMode = $ref(FormMode.None)
|
||||
let wordForm = $ref(cloneDeep(DefaultFormWord))
|
||||
const wordFormRef = $ref<FormInstance>()
|
||||
const wordRules = reactive<FormRules>({
|
||||
name: [
|
||||
{required: true, message: '请输入单词', trigger: 'blur'},
|
||||
{max: 30, message: '名称不能超过30个字符', trigger: 'blur'},
|
||||
],
|
||||
})
|
||||
let wordListRef: any = $ref()
|
||||
|
||||
async function onSubmitWord() {
|
||||
await wordFormRef.validate((valid, fields) => {
|
||||
if (valid) {
|
||||
let data: any = cloneDeep(wordForm)
|
||||
if (data.trans) {
|
||||
data.trans = data.trans.split('\n');
|
||||
} else {
|
||||
data.trans = []
|
||||
}
|
||||
if (wordFormMode === FormMode.Add) {
|
||||
if (wordList.find(v => v.name === wordForm.name)) {
|
||||
return ElMessage.warning('已有相同名称单词!')
|
||||
} else {
|
||||
store.editDict.originWords.push(data)
|
||||
//因为虚拟列表,必须重新赋值才能检测到更新
|
||||
wordList = cloneDeep(store.editDict.originWords)
|
||||
ElMessage.success('添加成功')
|
||||
wordForm = cloneDeep(DefaultFormWord)
|
||||
setTimeout(wordListRef?.scrollToBottom, 100)
|
||||
}
|
||||
console.log('store.editDict', store.editDict)
|
||||
} else {
|
||||
store.editDict.originWords[wordFormMode] = data
|
||||
//因为虚拟列表,必须重新赋值才能检测到更新
|
||||
wordList = cloneDeep(store.editDict.originWords)
|
||||
ElMessage.success('修改成功')
|
||||
}
|
||||
} else {
|
||||
ElMessage.warning('请填写完整')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function delWord(index: number) {
|
||||
store.editDict.originWords.splice(index, 1)
|
||||
wordList = cloneDeep(store.editDict.originWords)
|
||||
}
|
||||
|
||||
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 closeWordForm() {
|
||||
wordFormMode = FormMode.None
|
||||
wordForm = cloneDeep(DefaultFormWord)
|
||||
}
|
||||
|
||||
function addWord() {
|
||||
wordFormMode = FormMode.Add
|
||||
wordForm = cloneDeep(DefaultFormWord)
|
||||
}
|
||||
|
||||
watch(() => step, v => {
|
||||
if (v === 0) {
|
||||
closeWordForm()
|
||||
closeDictForm()
|
||||
}
|
||||
})
|
||||
|
||||
let show = $ref(false)
|
||||
|
||||
useDisableEventListener(() => show)
|
||||
|
||||
function close() {
|
||||
show = false
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
emitter.on(EventKey.editDict, (dict: Dict) => {
|
||||
let rIndex = dictList.findIndex(v => v.id === dict.id)
|
||||
if (rIndex > -1) {
|
||||
selectDict({index: rIndex})
|
||||
addWord()
|
||||
show = true
|
||||
}
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Modal
|
||||
:header="false"
|
||||
v-model="show"
|
||||
:show-close="false">
|
||||
<div id="AddWordDialog" :class="wordFormMode !== FormMode.None && 'add-word-mode'">
|
||||
<Slide :slide-count="2" :step="step">
|
||||
<div class="page dict-list-page">
|
||||
<header>
|
||||
<div class="title">
|
||||
我的词典
|
||||
</div>
|
||||
<Icon @click="close"
|
||||
class="hvr-grow pointer"
|
||||
width="20" color="#929596"
|
||||
icon="ion:close-outline"/>
|
||||
</header>
|
||||
<div class="list">
|
||||
<DictList
|
||||
@add="step = 1;isAddDict = true"
|
||||
@selectDict="selectDict"
|
||||
:list="dictList"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="page add-page">
|
||||
<header>
|
||||
<div class="left" @click.stop="step = 0">
|
||||
<Icon icon="octicon:arrow-left-24" class="go" width="20"/>
|
||||
<div class="title">
|
||||
词典详情
|
||||
</div>
|
||||
</div>
|
||||
<Icon @click="close"
|
||||
class="hvr-grow pointer"
|
||||
width="20" color="#929596"
|
||||
icon="ion:close-outline"/>
|
||||
</header>
|
||||
<div class="detail" v-if="!isAddDict">
|
||||
<div class="dict">
|
||||
<div class="info">
|
||||
<div class="name">{{ store.editDict.name }}</div>
|
||||
<div class="desc">{{ store.editDict.description }}</div>
|
||||
<div class="more-info">
|
||||
<div class="item">词汇量:{{ store.editDict.originWords.length }}词</div>
|
||||
<div class="item">创建日期:-</div>
|
||||
<div class="item">花费时间:-</div>
|
||||
<div class="item">累积错误:-</div>
|
||||
</div>
|
||||
<BaseIcon
|
||||
v-if="![DictType.collect,DictType.wrong,DictType.simple].includes(store.editDict.type)"
|
||||
class-name="edit-icon"
|
||||
icon="tabler:edit"
|
||||
@click='editDict'
|
||||
/>
|
||||
</div>
|
||||
<div class="add" v-if="wordFormMode !== FormMode.None">
|
||||
<div class="common-title">{{ wordFormMode === FormMode.Add ? '添加' : '修改' }}单词</div>
|
||||
<el-form
|
||||
class="form"
|
||||
ref="wordFormRef"
|
||||
:rules="wordRules"
|
||||
:model="wordForm"
|
||||
label-width="140rem">
|
||||
<el-form-item label="单词" prop="name">
|
||||
<el-input v-model="wordForm.name"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="翻译">
|
||||
<el-input v-model="wordForm.trans"
|
||||
placeholder="多个翻译请换行"
|
||||
:autosize="{ minRows: 2, maxRows: 6 }"
|
||||
type="textarea"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="音标/发音/注音①">
|
||||
<el-input v-model="wordForm.usphone"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="音标/发音/注音②">
|
||||
<el-input v-model="wordForm.ukphone"/>
|
||||
</el-form-item>
|
||||
<div class="flex-center">
|
||||
<el-button @click="closeWordForm">关闭</el-button>
|
||||
<el-button type="primary" @click="onSubmitWord">{{
|
||||
wordFormMode === FormMode.Add ? '添加' : '保存'
|
||||
}}
|
||||
</el-button>
|
||||
</div>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="list-wrapper">
|
||||
<div class="list-header">
|
||||
<div class="name">单词列表</div>
|
||||
<div class="flex-center gap10">
|
||||
<div class="name">{{ wordList.length }}个单词</div>
|
||||
<BaseIcon icon="mi:add"
|
||||
@click='addWord'
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<VirtualWordList
|
||||
ref="wordListRef"
|
||||
v-if="wordList.length"
|
||||
class="word-list"
|
||||
:is-active="true"
|
||||
@change="editWord"
|
||||
:list="wordList"
|
||||
:activeIndex="wordFormMode">
|
||||
<template v-slot="{word,index}">
|
||||
<BaseIcon
|
||||
class-name="del"
|
||||
@click="delWord(index)"
|
||||
title="移除"
|
||||
icon="solar:trash-bin-minimalistic-linear"/>
|
||||
</template>
|
||||
</VirtualWordList>
|
||||
<Empty v-else/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="edit" v-else>
|
||||
<div class="common-title">{{ dictForm.id ? '修改' : '添加' }}词典</div>
|
||||
<el-form
|
||||
ref="dictFormRef"
|
||||
:rules="dictRules"
|
||||
:model="dictForm"
|
||||
label-width="120rem">
|
||||
<el-form-item label="名称" prop="name">
|
||||
<el-input v-model="dictForm.name"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="描述">
|
||||
<el-input v-model="dictForm.description" type="textarea"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="语言">
|
||||
<el-select v-model="dictForm.language" placeholder="请选择选项">
|
||||
<el-option label="英语" value="en"/>
|
||||
<el-option label="德语" value="de"/>
|
||||
<el-option label="日语" value="ja"/>
|
||||
<el-option label="代码" value="code"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="翻译语言">
|
||||
<el-select v-model="dictForm.translateLanguage" placeholder="请选择选项">
|
||||
<!-- <el-option label="通用" value="common"/>-->
|
||||
<el-option label="中文" value="zh-CN"/>
|
||||
<el-option label="英语" value="en"/>
|
||||
<el-option label="德语" value="de"/>
|
||||
<el-option label="日语" value="ja"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="分类" prop="category">
|
||||
<el-select v-model="dictForm.category" placeholder="请选择选项">
|
||||
<el-option :label="i" :value="i" v-for="i in categoryList[dictForm.language]"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="标签" prop="tags">
|
||||
<el-select
|
||||
multiple
|
||||
v-model="dictForm.tags" placeholder="请选择选项">
|
||||
<el-option :label="i" :value="i" v-for="i in tagList[dictForm.category]"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="类型">
|
||||
<el-select v-model="dictForm.type" placeholder="请选择选项">
|
||||
<el-option label="单词" :value="DictType.customWord"/>
|
||||
<el-option label="文章" :value="DictType.customArticle"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<div class="flex-center">
|
||||
<el-button @click="closeDictForm">关闭</el-button>
|
||||
<el-button type="primary" @click="onSubmit">确定</el-button>
|
||||
</div>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
</Slide>
|
||||
</div>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "@/assets/css/variable";
|
||||
|
||||
#AddWordDialog {
|
||||
width: 650rem;
|
||||
height: 70vh;
|
||||
transition: all .3s;
|
||||
|
||||
&.add-word-mode {
|
||||
width: 800rem;
|
||||
|
||||
.more-info {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
display: none;
|
||||
}
|
||||
|
||||
.dict{
|
||||
padding-right: var(--space);
|
||||
}
|
||||
}
|
||||
|
||||
$header-height: 60rem;
|
||||
|
||||
header {
|
||||
color: var(--color-font-3);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
height: $header-height;
|
||||
|
||||
.left {
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
gap: 10rem;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
.dict-list-page {
|
||||
padding: 0 var(--space);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.add-page {
|
||||
color: var(--color-font-1);
|
||||
//display: flex;
|
||||
//flex-direction: column;
|
||||
|
||||
header {
|
||||
padding: 0 var(--space);
|
||||
}
|
||||
|
||||
.detail {
|
||||
flex: 1;
|
||||
height: calc(100% - $header-height);
|
||||
display: flex;
|
||||
position: relative;
|
||||
|
||||
.dict {
|
||||
flex: 1;
|
||||
border-radius: 10rem;
|
||||
background: var(--color-second-bg);
|
||||
color: var(--color-font-1);
|
||||
padding-left: var(--space);
|
||||
padding-bottom: var(--space);
|
||||
box-sizing: border-box;
|
||||
overflow: auto;
|
||||
|
||||
.info {
|
||||
border-radius: 8rem;
|
||||
background: var(--color-item-bg);
|
||||
padding: 20rem;
|
||||
position: relative;
|
||||
|
||||
:deep(.edit-icon) {
|
||||
position: absolute;
|
||||
top: 10rem;
|
||||
right: 10rem;
|
||||
}
|
||||
|
||||
.name {
|
||||
font-size: 24rem;
|
||||
margin-bottom: 10rem;
|
||||
}
|
||||
|
||||
.desc {
|
||||
font-size: 18rem;
|
||||
margin-bottom: 30rem;
|
||||
}
|
||||
|
||||
.item {
|
||||
margin-top: 10rem;
|
||||
}
|
||||
}
|
||||
|
||||
.add {
|
||||
margin-top: 20rem;
|
||||
}
|
||||
}
|
||||
|
||||
.list-wrapper {
|
||||
width: 400rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
font-size: 14rem;
|
||||
padding-bottom: 20rem;
|
||||
|
||||
.list-header {
|
||||
min-height: 50rem;
|
||||
padding: 10rem 24rem;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
font-size: 16rem;
|
||||
color: var(--color-font-3);
|
||||
|
||||
.name {
|
||||
font-size: 18rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.edit {
|
||||
height: calc(100% - $header-height);
|
||||
padding: var(--space);
|
||||
padding-top: 0;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import {dictionaryResources} from '@/assets/dictionary.ts'
|
||||
import {useBaseStore} from "@/stores/base.ts"
|
||||
import {watch, reactive, onMounted} from "vue"
|
||||
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 {$computed, $ref} from "vue/macros";
|
||||
@@ -40,14 +40,6 @@ watch(() => runtimeStore.showDictModal, (n: boolean) => {
|
||||
runtimeStore.editDict = cloneDeep(store.currentDict)
|
||||
})
|
||||
|
||||
let myAllDict = $computed(() => {
|
||||
return [
|
||||
store.collect,
|
||||
store.simple,
|
||||
store.wrong
|
||||
].concat(store.myDicts);
|
||||
})
|
||||
|
||||
async function selectDict(val: { dict: DictResource, index: number }) {
|
||||
let item = val.dict
|
||||
console.log('item', item)
|
||||
@@ -59,44 +51,40 @@ async function selectDict(val: { dict: DictResource, index: number }) {
|
||||
let find: Dict = store.myDicts.find((v: Dict) => v.name === item.name)
|
||||
if (find) {
|
||||
runtimeStore.editDict = cloneDeep(find)
|
||||
if (find.type === DictType.article) {
|
||||
if (!find.articles.length) {
|
||||
let r = await fetch(`./dicts/${find.language}/${find.type}/${find.translateLanguage}/${find.url}`)
|
||||
let v = await r.json()
|
||||
runtimeStore.editDict.articles = v.map(s => {
|
||||
s.id = uuidv4()
|
||||
return s
|
||||
})
|
||||
}
|
||||
} else {
|
||||
wordList = cloneDeep(runtimeStore.editDict.originWords)
|
||||
}
|
||||
loading = false
|
||||
} else {
|
||||
let data: Dict = {
|
||||
runtimeStore.editDict = cloneDeep({
|
||||
...cloneDeep(DefaultDict),
|
||||
...item,
|
||||
})
|
||||
}
|
||||
|
||||
if ([DictType.collect, DictType.simple, DictType.simple].includes(runtimeStore.editDict.type)) {
|
||||
wordList = cloneDeep(runtimeStore.editDict.originWords)
|
||||
} else {
|
||||
let url = `./dicts/${runtimeStore.editDict.language}/${runtimeStore.editDict.type}/${runtimeStore.editDict.translateLanguage}/${runtimeStore.editDict.url}`;
|
||||
if (runtimeStore.editDict.type === DictType.word) {
|
||||
if (!runtimeStore.editDict.originWords.length) {
|
||||
let r = await fetch(url)
|
||||
let v = await r.json()
|
||||
runtimeStore.editDict.originWords = cloneDeep(v)
|
||||
runtimeStore.editDict.words = cloneDeep(v)
|
||||
runtimeStore.editDict.chapterWords = chunk(runtimeStore.editDict.words, runtimeStore.editDict.chapterWordNumber)
|
||||
}
|
||||
wordList = cloneDeep(runtimeStore.editDict.originWords)
|
||||
}
|
||||
runtimeStore.editDict = cloneDeep(data)
|
||||
let r = await fetch(`./dicts/${data.language}/${data.type}/${data.translateLanguage}/${item.url}`)
|
||||
r.json().then(v => {
|
||||
console.log('v', v)
|
||||
if (data.type === DictType.article) {
|
||||
|
||||
if (runtimeStore.editDict.type === DictType.article) {
|
||||
if (!runtimeStore.editDict.articles.length) {
|
||||
let r = await fetch(url)
|
||||
let v = await r.json()
|
||||
runtimeStore.editDict.articles = cloneDeep(v.map(s => {
|
||||
s.id = uuidv4()
|
||||
return s
|
||||
}))
|
||||
} else {
|
||||
runtimeStore.editDict.originWords = v
|
||||
runtimeStore.editDict.words = v
|
||||
runtimeStore.editDict.chapterWords = chunk(v, runtimeStore.editDict.chapterWordNumber)
|
||||
console.log(' runtimeStore.editDict', runtimeStore.editDict)
|
||||
wordList = cloneDeep(runtimeStore.editDict.originWords)
|
||||
}
|
||||
loading = false
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
loading = false
|
||||
}
|
||||
|
||||
function changeDict() {
|
||||
@@ -128,12 +116,12 @@ const groupByTranslateLanguage = $computed(() => {
|
||||
data = groupBy(articleList, 'translateLanguage')
|
||||
} else if (currentLanguage === 'my') {
|
||||
data = {
|
||||
common: myAllDict.concat([{name: '',} as any])
|
||||
common: store.myDicts.concat([{name: '',} as any])
|
||||
}
|
||||
} else {
|
||||
data = groupBy(groupByLanguage[currentLanguage], 'translateLanguage')
|
||||
}
|
||||
console.log('groupByTranslateLanguage', data)
|
||||
// console.log('groupByTranslateLanguage', data)
|
||||
translateLanguageList = Object.keys(data)
|
||||
currentTranslateLanguage = translateLanguageList[0]
|
||||
return data
|
||||
@@ -147,7 +135,7 @@ const groupedByCategoryAndTag = $computed(() => {
|
||||
for (const [key, value] of Object.entries(groupByCategory)) {
|
||||
data.push([key, groupByDictTags(value)])
|
||||
}
|
||||
console.log('groupedByCategoryAndTag', data)
|
||||
// console.log('groupedByCategoryAndTag', data)
|
||||
return data
|
||||
})
|
||||
|
||||
@@ -270,6 +258,7 @@ async function onSubmit() {
|
||||
if (data.id) {
|
||||
let rIndex = store.myDicts.findIndex(v => v.id === data.id)
|
||||
store.myDicts[rIndex] = cloneDeep(data)
|
||||
runtimeStore.editDict = cloneDeep(data)
|
||||
isAddDict = false
|
||||
ElMessage.success('修改成功')
|
||||
} else {
|
||||
@@ -278,13 +267,12 @@ async function onSubmit() {
|
||||
return ElMessage.warning('已有相同名称词典!')
|
||||
} else {
|
||||
store.myDicts.push(cloneDeep(data))
|
||||
store.current.editIndex = 3 + store.myDicts.filter(v => [DictType.customWord, DictType.customArticle].includes(v.type)).length - 1
|
||||
runtimeStore.editDict = cloneDeep(data)
|
||||
isAddDict = false
|
||||
ElMessage.success('添加成功')
|
||||
}
|
||||
}
|
||||
console.log('submit!', data)
|
||||
|
||||
} else {
|
||||
ElMessage.warning('请填写完整')
|
||||
}
|
||||
@@ -408,7 +396,8 @@ watch(() => step, v => {
|
||||
<div class="dict-list-wrapper">
|
||||
<template v-if="currentLanguage === 'my'">
|
||||
<DictList
|
||||
@add="step = 1"
|
||||
@add="step = 1;isAddDict = true"
|
||||
@selectDict="selectDict"
|
||||
:list="groupByTranslateLanguage['common']"/>
|
||||
</template>
|
||||
<template v-else>
|
||||
@@ -824,7 +813,6 @@ $header-height: 60rem;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
position: relative;
|
||||
gap: var(--space);
|
||||
|
||||
.left-column {
|
||||
overflow: auto;
|
||||
@@ -834,11 +822,10 @@ $header-height: 60rem;
|
||||
gap: 10rem;
|
||||
min-height: 100rem;
|
||||
position: relative;
|
||||
border-radius: 10rem;
|
||||
background: var(--color-second-bg);
|
||||
color: var(--color-font-1);
|
||||
font-size: 14rem;
|
||||
position: relative;
|
||||
padding-right: var(--space);
|
||||
|
||||
.name {
|
||||
font-size: 28rem;
|
||||
@@ -861,8 +848,8 @@ $header-height: 60rem;
|
||||
|
||||
:deep(.edit-icon) {
|
||||
position: absolute;
|
||||
top: 10rem;
|
||||
right: 10rem;
|
||||
top: 8rem;
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -957,7 +944,11 @@ $header-height: 60rem;
|
||||
justify-content: center;
|
||||
|
||||
.wrapper {
|
||||
width: 70%;
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.el-select {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ const {
|
||||
{{ store.collect.articles.length }}篇文章
|
||||
</div>
|
||||
</div>
|
||||
<template v-if="store.current.dictType !== DictType.collect &&
|
||||
<template v-if="store.currentDict.type !== DictType.collect &&
|
||||
(
|
||||
( practiceType === DictType.word && store.collect.words.length) ||
|
||||
( practiceType === DictType.article && store.collect.articles.length)
|
||||
@@ -133,7 +133,7 @@ const {
|
||||
<div class="panel-page-item" v-if="store.simple.words.length">
|
||||
<div class="list-header">
|
||||
<div class="dict-name">总词数:{{ store.simple.words.length }}</div>
|
||||
<template v-if="store.current.dictType !== DictType.simple && store.simple.words.length">
|
||||
<template v-if="store.currentDict.type !== DictType.simple && store.simple.words.length">
|
||||
<PopConfirm
|
||||
:title="`确认切换?`"
|
||||
@confirm="changeIndex(0,store.simple)"
|
||||
@@ -161,7 +161,7 @@ const {
|
||||
<div class="list-header">
|
||||
<div class="dict-name">总词数:{{ store.wrong.words.length }}</div>
|
||||
<template
|
||||
v-if="store.current.dictType !== DictType.wrong && store.wrong.words.length">
|
||||
v-if="store.currentDict.type !== DictType.wrong && store.wrong.words.length">
|
||||
<PopConfirm
|
||||
:title="`确认切换?`"
|
||||
@confirm="changeIndex(0,store.wrong)"
|
||||
|
||||
@@ -17,7 +17,6 @@ import {ShortcutKey} from "@/types.ts";
|
||||
import useTheme from "@/hooks/useTheme.ts";
|
||||
import SettingModal from "@/components/Modal/SettingModal.vue";
|
||||
import DictModal from "@/components/Modal/DictDialog/index.vue";
|
||||
import AddWordDialog from "@/components/Modal/AddWordDialog.vue";
|
||||
|
||||
const practiceStore = usePracticeStore()
|
||||
const store = useBaseStore()
|
||||
@@ -165,7 +164,7 @@ onUnmounted(() => {
|
||||
<PracticeWord ref="practiceRef" v-else/>
|
||||
<Footer/>
|
||||
</div>
|
||||
<AddWordDialog></AddWordDialog>
|
||||
<!-- <AddWordDialog></AddWordDialog>-->
|
||||
<DictModal/>
|
||||
<SettingModal v-if="runtimeStore.showSettingModal" @close="runtimeStore.showSettingModal = false"/>
|
||||
<Statistics/>
|
||||
|
||||
@@ -40,7 +40,7 @@ let editArticle = $ref<Article>(cloneDeep(DefaultArticle))
|
||||
watch([
|
||||
() => store.current.index,
|
||||
() => store.load,
|
||||
() => store.current.dictType,
|
||||
() => store.currentDict.type,
|
||||
() => store.currentDict.chapterIndex,
|
||||
], n => {
|
||||
console.log('n', n)
|
||||
|
||||
@@ -140,7 +140,7 @@ function next(isTyping: boolean = true) {
|
||||
data.index++
|
||||
isTyping && practiceStore.inputWordNumber++
|
||||
console.log('这个词完了')
|
||||
if ([DictType.customWord, DictType.word].includes(store.current.dictType)
|
||||
if ([DictType.customWord, DictType.word].includes(store.currentDict.type)
|
||||
&& store.skipWordNames.includes(word.name.toLowerCase())) {
|
||||
next()
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ defineProps<{
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
selectDict: [val: { dict: Dict, index: number }]
|
||||
selectDict: [val: { dict: any, index: number }]
|
||||
detail: [],
|
||||
add: []
|
||||
}>()
|
||||
|
||||
@@ -6,9 +6,6 @@ import {v4 as uuidv4} from 'uuid';
|
||||
import {useRuntimeStore} from "@/stores/runtime.ts";
|
||||
|
||||
export interface State {
|
||||
collect: Dict,
|
||||
simple: Dict,
|
||||
wrong: Dict,
|
||||
myDicts: Dict[],
|
||||
current: {
|
||||
dictType: DictType,
|
||||
@@ -68,62 +65,56 @@ export interface State {
|
||||
export const useBaseStore = defineStore('base', {
|
||||
state: (): State => {
|
||||
return {
|
||||
collect: {
|
||||
...cloneDeep(DefaultDict),
|
||||
id: 'collect',
|
||||
name: '收藏',
|
||||
type: DictType.collect,
|
||||
category: '自带字典',
|
||||
tags: ['自带'],
|
||||
},
|
||||
simple: {
|
||||
...cloneDeep(DefaultDict),
|
||||
id: 'skip',
|
||||
name: '简单词',
|
||||
type: DictType.simple,
|
||||
category: '自带字典'
|
||||
},
|
||||
wrong: {
|
||||
...cloneDeep(DefaultDict),
|
||||
id: 'wrong',
|
||||
name: '错词本',
|
||||
type: DictType.wrong,
|
||||
category: '自带字典'
|
||||
},
|
||||
myDicts: [
|
||||
{
|
||||
...cloneDeep(DefaultDict),
|
||||
id: '新概念英语2-课文',
|
||||
name: '新概念英语2-课文',
|
||||
type: DictType.article,
|
||||
id: 'collect',
|
||||
name: '收藏',
|
||||
type: DictType.collect,
|
||||
category: '自带字典',
|
||||
tags: ['自带'],
|
||||
},
|
||||
{
|
||||
...cloneDeep(DefaultDict),
|
||||
id: 'skip',
|
||||
name: '简单词',
|
||||
type: DictType.simple,
|
||||
category: '自带字典'
|
||||
},
|
||||
{
|
||||
...cloneDeep(DefaultDict),
|
||||
id: 'wrong',
|
||||
name: '错词本',
|
||||
type: DictType.wrong,
|
||||
category: '自带字典'
|
||||
},
|
||||
{
|
||||
...cloneDeep(DefaultDict),
|
||||
id: 'article_nce2',
|
||||
name: "新概念英语2-课文",
|
||||
description: '新概念英语2-课文',
|
||||
category: '英语学习',
|
||||
tags: ['新概念英语'],
|
||||
url: 'NCE_2.json',
|
||||
translateLanguage: 'common',
|
||||
language: 'en',
|
||||
type: DictType.article
|
||||
},
|
||||
{
|
||||
...cloneDeep(DefaultDict),
|
||||
id: '新概念英语2',
|
||||
name: '新概念英语2',
|
||||
type: DictType.word,
|
||||
name: '新概念英语(新版)-2',
|
||||
description: '新概念英语新版第二册',
|
||||
category: '青少年英语',
|
||||
tags: ['新概念英语'],
|
||||
url: 'nce-new-2.json',
|
||||
resourceId: 'nce-new-2',
|
||||
translateLanguage: 'common',
|
||||
language: 'en',
|
||||
type: DictType.word
|
||||
},
|
||||
{
|
||||
...cloneDeep(DefaultDict),
|
||||
id: '新概11',
|
||||
name: '新22',
|
||||
type: DictType.customWord,
|
||||
url: 'nce-new-2.json',
|
||||
resourceId: 'nce-new-2',
|
||||
translateLanguage: 'common',
|
||||
language: 'en',
|
||||
}
|
||||
],
|
||||
current: {
|
||||
dictType: DictType.word,
|
||||
index: 1,
|
||||
index: 4,
|
||||
editIndex: 0,
|
||||
// dictType: DictType.article,
|
||||
// index: 0,
|
||||
@@ -141,51 +132,39 @@ export const useBaseStore = defineStore('base', {
|
||||
}
|
||||
},
|
||||
getters: {
|
||||
skipWordNames: (state: State) => {
|
||||
return state.simple.originWords.map(v => v.name.toLowerCase())
|
||||
collect() {
|
||||
return this.myDicts[0]
|
||||
},
|
||||
skipWordNamesWithSimpleWords: (state: State) => {
|
||||
return state.simple.originWords.map(v => v.name.toLowerCase()).concat(state.simpleWords)
|
||||
simple(): Dict {
|
||||
return this.myDicts[1]
|
||||
},
|
||||
wrong() {
|
||||
return this.myDicts[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: State): boolean {
|
||||
//如果是收藏时,特殊判断
|
||||
if (state.current.dictType === DictType.collect) {
|
||||
if (this.currentDict.type === DictType.collect) {
|
||||
return state.current.practiceType === DictType.article
|
||||
}
|
||||
return [
|
||||
DictType.article,
|
||||
DictType.customArticle
|
||||
].includes(state.current.dictType)
|
||||
].includes(this.currentDict.type)
|
||||
},
|
||||
editDict(state: State) {
|
||||
if (state.current.editIndex === -1) {
|
||||
return cloneDeep(DefaultDict)
|
||||
}
|
||||
switch (state.current.editIndex) {
|
||||
case 0:
|
||||
return state.collect
|
||||
case 1:
|
||||
return state.simple
|
||||
case 2:
|
||||
return state.wrong
|
||||
default:
|
||||
return state.myDicts.filter(v => [DictType.customWord, DictType.customArticle].includes(v.type))[state.current.editIndex - 3]
|
||||
}
|
||||
return state.myDicts.filter(v => [DictType.customWord, DictType.customArticle].includes(v.type))[state.current.editIndex - 3]
|
||||
},
|
||||
currentDict(state: State): Dict {
|
||||
switch (state.current.dictType) {
|
||||
case DictType.collect:
|
||||
return state.collect
|
||||
case DictType.simple:
|
||||
return state.simple
|
||||
case DictType.wrong:
|
||||
return state.wrong
|
||||
case DictType.word:
|
||||
case DictType.article:
|
||||
case DictType.customWord:
|
||||
case DictType.customArticle:
|
||||
return this.myDicts[this.current.index]
|
||||
}
|
||||
currentDict(): Dict {
|
||||
return this.myDicts[this.current.index]
|
||||
},
|
||||
currentEditDict(): Dict {
|
||||
return this.myDicts[this.current.editIndex]
|
||||
@@ -202,7 +181,7 @@ export const useBaseStore = defineStore('base', {
|
||||
},
|
||||
chapterName(state: State) {
|
||||
let title = ''
|
||||
switch (state.current.dictType) {
|
||||
switch (this.currentDict.type) {
|
||||
case DictType.collect:
|
||||
if (state.current.practiceType === DictType.word) {
|
||||
return `第${this.currentDict.chapterIndex + 1}章`
|
||||
@@ -215,20 +194,6 @@ export const useBaseStore = defineStore('base', {
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
setEditDict(val: Dict) {
|
||||
if (this.current.editIndex !== -1) {
|
||||
switch (this.current.editIndex) {
|
||||
case 0:
|
||||
return this.collect = val
|
||||
case 1:
|
||||
return this.simple = val
|
||||
case 2:
|
||||
return this.wrong = val
|
||||
default:
|
||||
return this.myDicts[this.current.editIndex] = val
|
||||
}
|
||||
}
|
||||
},
|
||||
setState(obj: any) {
|
||||
for (const [key, value] of Object.entries(obj)) {
|
||||
this[key] = value
|
||||
@@ -244,17 +209,13 @@ export const useBaseStore = defineStore('base', {
|
||||
// this.setState(obj)
|
||||
}
|
||||
|
||||
if ([
|
||||
DictType.collect,
|
||||
DictType.wrong,
|
||||
DictType.simple,
|
||||
].includes(this.current.dictType)) {
|
||||
if (this.current.index < 3) {
|
||||
|
||||
} else {
|
||||
if ([
|
||||
DictType.word,
|
||||
DictType.customWord,
|
||||
].includes(this.current.dictType)) {
|
||||
].includes(this.currentDict.type)) {
|
||||
if (!this.currentDict.originWords.length) {
|
||||
let r = await fetch(`./dicts/${this.currentDict.language}/${this.currentDict.type}/${this.currentDict.translateLanguage}/${this.currentDict.url}`)
|
||||
// let r = await fetch(`.${this.currentDict.url}`)
|
||||
@@ -292,8 +253,7 @@ export const useBaseStore = defineStore('base', {
|
||||
if ([
|
||||
DictType.article,
|
||||
DictType.customArticle,
|
||||
].includes(this.current.dictType)) {
|
||||
console.log(1, this.currentDict)
|
||||
].includes(this.currentDict.type)) {
|
||||
if (!this.currentDict.articles.length) {
|
||||
console.log(2)
|
||||
let r = await fetch(`./dicts/${this.currentDict.language}/${this.currentDict.type}/${this.currentDict.translateLanguage}/${this.currentDict.url}`)
|
||||
@@ -322,7 +282,7 @@ export const useBaseStore = defineStore('base', {
|
||||
//TODO 保存统计
|
||||
// this.saveStatistics()
|
||||
console.log('changeDict', cloneDeep(dict), chapterIndex, chapterWordIndex)
|
||||
this.current.dictType = dict.type
|
||||
this.currentDict.type = dict.type
|
||||
this.current.practiceType = practiceType
|
||||
if ([DictType.collect,
|
||||
DictType.simple,
|
||||
|
||||
Reference in New Issue
Block a user