This commit is contained in:
zyronon
2024-05-31 15:26:56 +08:00
parent 55858ae3cf
commit e307af64af
24 changed files with 6458 additions and 332 deletions

View File

@@ -43,6 +43,7 @@
"@iconify/vue": "^4.1.1",
"@types/file-saver": "^2.0.5",
"@types/lodash-es": "^4.17.9",
"@unocss/postcss": "^0.60.2",
"@vitejs/plugin-vue": "^4.2.3",
"@vitejs/plugin-vue-jsx": "^3.0.1",
"@vue-macros/reactivity-transform": "^0.4.5",
@@ -56,11 +57,11 @@
"sass": "^1.64.2",
"tslib": "^2.6.2",
"typescript": "^5.2.0",
"@unocss/postcss": "^0.60.2",
"unocss": "^0.60.2",
"unplugin-auto-import": "^0.16.6",
"unplugin-vue-components": "^0.25.2",
"unplugin-vue-define-options": "^1.4.1",
"unplugin-vue-macros": "^2.9.3",
"vite": "^5.2.11",
"vue-tsc": "^2.0.19",
"xlsx": "^0.18.5"

6428
pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -126,7 +126,7 @@ function selectDict(val: { dict: DictResource | Dict, index: number }) {
<div class="translate">
<span>翻译</span>
<el-radio-group v-model="articleData.currentTranslateLanguage">
<el-radio-button border v-for="i in articleData.translateLanguageList" :label="i">{{
<el-radio-button border v-for="i in articleData.translateLanguageList" :value="i">{{
$t(i)
}}
</el-radio-button>
@@ -144,7 +144,7 @@ function selectDict(val: { dict: DictResource | Dict, index: number }) {
<div class="translate">
<span>翻译</span>
<el-radio-group v-model="wordData.currentTranslateLanguage">
<el-radio-button border v-for="i in wordData.translateLanguageList" :label="i">{{
<el-radio-button border v-for="i in wordData.translateLanguageList" :value="i">{{
$t(i)
}}
</el-radio-button>

View File

@@ -16,7 +16,7 @@ import WordList from "@/pages/pc/components/list/WordList.vue";
import Empty from "@/components/Empty.vue";
import {Icon} from "@iconify/vue";
import router from "@/router.ts";
import Typing from "@/pages/pc/practice/practice-word/Typing.vue";
import Typing from "@/pages/pc/components/practice-word/Typing.vue";
import {usePracticeStore} from "@/stores/practice.ts";
const store = useBaseStore()

View File

@@ -3,7 +3,7 @@
import Toolbar from "@/pages/pc/components/toolbar/index.vue"
import {onMounted, onUnmounted, watch} from "vue";
import {usePracticeStore} from "@/stores/practice.ts";
import Footer from "@/pages/pc/practice/Footer.vue";
import Footer from "@/pages/pc/word/Footer.vue";
import {useBaseStore} from "@/stores/base.ts";
import Statistics from "@/pages/pc/word/Statistics.vue";

View File

@@ -3,7 +3,7 @@
import Toolbar from "@/pages/pc/components/toolbar/index.vue"
import {onMounted, onUnmounted, watch} from "vue";
import {usePracticeStore} from "@/stores/practice.ts";
import Footer from "@/pages/pc/practice/Footer.vue";
import Footer from "@/pages/pc/word/Footer.vue";
import {useBaseStore} from "@/stores/base.ts";
import Statistics from "@/pages/pc/word/Statistics.vue";

View File

@@ -99,7 +99,7 @@ function del(e) {
<div class="translate ">
<span>释义</span>
<el-radio-group v-model="currentTranslateLanguage">
<el-radio-button border v-for="i in translateLanguageList" :label="i">{{ $t(i) }}</el-radio-button>
<el-radio-button border v-for="i in translateLanguageList" :value="i">{{ $t(i) }}</el-radio-button>
</el-radio-group>
</div>
<DictGroup

View File

@@ -109,8 +109,8 @@ const showCollectToggleButton = $computed(() => {
<div class="list-header">
<div class="left">
<el-radio-group v-model="practiceType">
<el-radio-button border :label="DictType.word">单词</el-radio-button>
<el-radio-button border :label="DictType.article">文章</el-radio-button>
<el-radio-button border :value="DictType.word">单词</el-radio-button>
<el-radio-button border :value="DictType.article">文章</el-radio-button>
</el-radio-group>
<div class="dict-name" v-if="practiceType === DictType.word && store.collect.words.length">
{{ store.collect.words.length }}个单词

View File

@@ -268,9 +268,9 @@ defineExpose({save, getEditArticle: () => cloneDeep(editArticle)})
v-model="editArticle.useTranslateType"
@change="renewSections"
>
<el-radio-button :label="TranslateType.custom">本地翻译</el-radio-button>
<el-radio-button :label="TranslateType.network">网络翻译</el-radio-button>
<el-radio-button :label="TranslateType.none">不需要翻译</el-radio-button>
<el-radio-button :value="TranslateType.custom">本地翻译</el-radio-button>
<el-radio-button :value="TranslateType.network">网络翻译</el-radio-button>
<el-radio-button :value="TranslateType.none">不需要翻译</el-radio-button>
</el-radio-group>
</div>
<textarea

View File

@@ -9,9 +9,9 @@ import {useSettingStore} from "@/stores/setting.ts";
import {useOnKeyboardEventListener, useWindowClick} from "@/hooks/event.ts";
import {Icon} from "@iconify/vue";
import Tooltip from "@/pages/pc/components/Tooltip.vue";
import Options from "@/pages/pc/practice/Options.vue";
import Typing from "@/pages/pc/practice/practice-word/Typing.vue";
import Panel from "@/pages/pc/practice/Panel.vue";
import Options from "@/pages/pc/word/Options.vue";
import Typing from "@/pages/pc/components/practice-word/Typing.vue";
import Panel from "@/pages/pc/components/Panel.vue";
import {useRuntimeStore} from "@/stores/runtime.ts";
import {useWordOptions} from "@/hooks/dict.ts";
import BaseIcon from "@/components/BaseIcon.vue";

View File

@@ -52,11 +52,11 @@ onMounted(() => {
单词循环设置
</div>
<el-radio-group v-model="settingStore.repeatCount">
<el-radio :label="1" size="default">1</el-radio>
<el-radio :label="2" size="default">2</el-radio>
<el-radio :label="3" size="default">3</el-radio>
<el-radio :label="5" size="default">5</el-radio>
<el-radio :label="100" size="default">自定义</el-radio>
<el-radio :value="1" size="default">1</el-radio>
<el-radio :value="2" size="default">2</el-radio>
<el-radio :value="3" size="default">3</el-radio>
<el-radio :value="5" size="default">5</el-radio>
<el-radio :value="100" size="default">自定义</el-radio>
</el-radio-group>
<div class="mini-row" v-if="settingStore.repeatCount === 100">
<label class="item-title">自定义循环次数</label>

View File

@@ -54,7 +54,7 @@ function save() {
</IconWrapper>
</Tooltip>
<MiniDialog v-model="show"
style="width: 230rem;"
style="width: 230rem;"
>
<div class="mini-row">
<label class="item-title">显示翻译</label>
@@ -69,8 +69,8 @@ function save() {
<div class="mini-row">
<label class="item-title">翻译类型</label>
<el-radio-group v-model="translateType" size="small">
<el-radio-button :label="1">本地翻译</el-radio-button>
<el-radio-button :label="0">网络翻译</el-radio-button>
<el-radio-button :value="1">本地翻译</el-radio-button>
<el-radio-button :value="0">网络翻译</el-radio-button>
</el-radio-group>
</div>
<div class="mini-row" v-if="translateType">

View File

@@ -1,163 +0,0 @@
<script setup lang="ts">
import {useBaseStore} from "@/stores/base.ts"
import {nextTick, onMounted, watch} from "vue"
import {Dict, DictResource, DictType} from "@/types.ts"
import "vue-activity-calendar/style.css";
import {useRuntimeStore} from "@/stores/runtime.ts";
import {useSettingStore} from "@/stores/setting.ts";
import {emitter, EventKey} from "@/utils/eventBus.ts";
import Slide from "@/pages/pc/components/Slide.vue";
import ArticleDictDetail from "@/pages/pc/dict/components/ArticleDictDetail.vue";
import WordDictDetail from "@/pages/pc/dict/components/WordDictDetail.vue";
import DictListPanel from "@/pages/pc/components/DictListPanel.vue";
import EditDict from "@/pages/pc/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(0)
let isAddDict = $ref(false)
async function selectDict(val: { dict: DictResource | Dict }, cb?: any) {
step = 1
isAddDict = false
dictIsArticle = val.dict.type === DictType.article
nextTick(() => {
detailRef?.getDictDetail(val)
cb?.()
})
}
function changeDict() {
store.changeDict(runtimeStore.editDict)
}
watch(() => store.load, v => {
if (v) {
// 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})
// 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 'detail':
setTimeout(() => {
selectDict({dict: runtimeStore.editDict})
}, 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})
}
if (type === "list") {
// currentLanguage = 'en'
step = 0
}
if (type === "my") {
// currentLanguage = 'my'
step = 0
}
if (type === "collect") {
selectDict({dict: store.collect})
}
if (type === "simple") {
selectDict({dict: store.simple})
}
})
// console.log('categoryList', categoryList)
// console.log('tagList', tagList)
})
</script>
<template>
<div id="DictDialog">
<Slide :slide-count="2" :step="step">
<DictListPanel
@add="addDict"
@select-dict="selectDict"
/>
<div class="dict-detail-page">
<EditDict
v-if="isAddDict"
:isAdd="true"
@cancel="cancelAddDict"
@submit="selectDict({dict:runtimeStore.editDict})"/>
<template v-else>
<ArticleDictDetail
ref="detailRef"
@back="back"
v-if="dictIsArticle"/>
<WordDictDetail
ref="detailRef"
@back="back"
v-else/>
</template>
</div>
</Slide>
</div>
</template>
<style scoped lang="scss">
@import "@/assets/css/variable";
#DictDialog {
font-size: .9rem;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
z-index: 1;
width: 80vw;
height: 75vh;
}
.dict-detail-page {
width: 50%;
height: 100%;
}
</style>

View File

@@ -1,73 +0,0 @@
<script setup lang="ts">
import DictManage from "@/pages/pc/dict/DictManage.vue";
import {onMounted} from "vue";
import {useRoute} from "vue-router";
import {useRuntimeStore} from "@/stores/runtime.ts";
import Logo from "@/pages/pc/components/Logo.vue";
const router = useRoute()
const runtimeStore = useRuntimeStore()
onMounted(() => {
})
</script>
<template>
<div class="anim page">
<header class="anim">
<div class="nav-list">
<nav>
<router-link to="/pc/practice">练习</router-link>
</nav>
<nav class="active">
<router-link to="/pc/dict">词典</router-link>
</nav>
<nav @click.stop="runtimeStore.showSettingModal = true"><a href="javascript:void(0)">设置</a></nav>
</div>
</header>
<div class="content">
<DictManage/>
</div>
</div>
</template>
<style scoped lang="scss">
.page {
header {
background: var(--color-second-bg);
height: 4rem;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
border-bottom: 1px solid var(--color-item-border);
.nav-list {
display: flex;
gap: .6rem;
nav {
padding: .4rem 1.2rem;
cursor: pointer;
font-size: 1rem;
transition: all .3s;
&:hover {
}
&.active {
border-bottom: 2px solid var(--color-main-active);
}
a {
color: var(--color-font-1);
}
}
}
}
}
</style>

View File

@@ -102,7 +102,7 @@ function change(e) {
<div class="translate ">
<span>释义</span>
<el-radio-group v-model="currentTranslateLanguage">
<el-radio-button border v-for="i in translateLanguageList" :label="i">{{ $t(i) }}</el-radio-button>
<el-radio-button border v-for="i in translateLanguageList" :value="i">{{ $t(i) }}</el-radio-button>
</el-radio-group>
</div>
<DictGroup

View File

@@ -11,8 +11,8 @@ import {
Word
} from "@/types.ts";
import {cloneDeep} from "lodash-es";
import TypingWord from "@/pages/pc/practice/practice-word/TypingWord.vue";
import Panel from "../Panel.vue";
import TypingWord from "@/pages/pc/components/practice-word/TypingWord.vue";
import Panel from "../../components/Panel.vue";
import {onMounted, onUnmounted, watch} from "vue";
import {renewSectionTexts, renewSectionTranslates} from "@/hooks/translate.ts";
import {MessageBox} from "@/utils/MessageBox.tsx";

View File

@@ -1,64 +0,0 @@
<script setup lang="ts">
import TypingWord from "@/pages/pc/practice/practice-word/TypingWord.vue";
import {cloneDeep} from "lodash-es";
import {useBaseStore} from "@/stores/base.ts";
import {onMounted, onUnmounted} from "vue";
import {useRuntimeStore} from "@/stores/runtime.ts";
import {ShortcutKey, Word} from "@/types.ts";
import {emitter, EventKey} from "@/utils/eventBus.ts";
import {useSettingStore} from "@/stores/setting.ts";
import {syncMyDictList} from "@/hooks/dict.ts";
const store = useBaseStore()
let wordData = $ref({
words: [],
index: -1
})
function getCurrentPractice() {
if (store.currentStudyWordDict.words?.length) {
wordData.index = 0
wordData.words = cloneDeep(store.currentStudyWordDict.words.slice(store.currentStudy.word.lastLearnIndex, store.currentStudy.word.lastLearnIndex + store.currentStudy.word.perDayStudyNumber))
emitter.emit(EventKey.resetWord)
}
}
//TODO wait
function sort(list: Word[]) {
store.currentDict.chapterWords[store.currentDict.chapterIndex] = wordData.words = list
wordData.index = 0
syncMyDictList(store.currentDict)
}
onMounted(() => {
getCurrentPractice()
emitter.on(EventKey.changeDict, getCurrentPractice)
})
onUnmounted(() => {
emitter.off(EventKey.changeDict, getCurrentPractice)
})
defineExpose({getCurrentPractice})
</script>
<template>
<div class="practice">
<TypingWord
@sort="sort"
v-model:words="wordData.words"
:index="wordData.index"/>
</div>
</template>
<style scoped lang="scss">
.practice {
//height: 100%;
flex: 1;
display: flex;
}
</style>

View File

@@ -3,7 +3,7 @@
import Toolbar from "@/pages/pc/components/toolbar/index.vue"
import {onMounted, onUnmounted, watch} from "vue";
import {usePracticeStore} from "@/stores/practice.ts";
import Footer from "@/pages/pc/practice/Footer.vue";
import Footer from "@/pages/pc/word/Footer.vue";
import {useBaseStore} from "@/stores/base.ts";
import Statistics from "@/pages/pc/word/Statistics.vue";
@@ -14,7 +14,7 @@ import {ShortcutKey, Word} from "@/types.ts";
import DictModal from "@/pages/pc/components/dialog/DictDiglog.vue";
import {useStartKeyboardEventListener} from "@/hooks/event.ts";
import useTheme from "@/hooks/theme.ts";
import TypingWord from "@/pages/pc/practice/practice-word/TypingWord.vue";
import TypingWord from "@/pages/pc/components/practice-word/TypingWord.vue";
import {getCurrentStudyWord, syncMyDictList} from "@/hooks/dict.ts";
import {cloneDeep, shuffle} from "lodash-es";

View File

@@ -10,7 +10,6 @@ import BasePage from "@/pages/pc/components/BasePage.vue";
import {getDefaultDict} from "@/types.ts";
import {onMounted, watch} from "vue";
import {getCurrentStudyWord} from "@/hooks/dict.ts";
import {c} from "vite/dist/node/types.d-aGj9QkWt";
import {usePracticeStore} from "@/stores/practice.ts";
const store = useBaseStore()

View File

@@ -1,6 +1,5 @@
import * as VueRouter from 'vue-router'
import {RouteRecordRaw} from 'vue-router'
import Dict from '@/pages/pc/dict/index.vue'
import Mobile from '@/pages/mobile/index.vue'
import MobilePractice from '@/pages/mobile/practice/index.vue'
import Test from "@/pages/test/test.vue";
@@ -39,7 +38,6 @@ export const routes: RouteRecordRaw[] = [
{path: 'learn-article', component: LearnArticle},
]
},
{path: '/pc/dict', component: Dict},
{path: '/mobile', component: Mobile,},
{path: '/mobile/practice', component: MobilePractice},

View File

@@ -29,7 +29,7 @@
"types": [
"vite/client",
"element-plus/global",
"unplugin-vue-macros/macros-global"
"unplugin-vue-macros/macros-global",
],
"baseUrl": "src",
//This is because TypeScript does not resolve webpack aliases automatically.