This commit is contained in:
Zyronon
2025-11-27 01:30:52 +08:00
parent 290534a05a
commit 69cccbf904
8 changed files with 44 additions and 29 deletions

View File

@@ -27,6 +27,7 @@
"dayjs": "^1.11.13",
"file-saver": "^2.0.5",
"idb-keyval": "^6.2.2",
"intro.js": "^8.3.2",
"md5": "^2.2.1",
"mitt": "^3.0.1",
"nanoid": "^5.1.5",

8
pnpm-lock.yaml generated
View File

@@ -35,6 +35,9 @@ importers:
idb-keyval:
specifier: ^6.2.2
version: 6.2.2
intro.js:
specifier: ^8.3.2
version: 8.3.2
md5:
specifier: ^2.2.1
version: 2.3.0
@@ -2340,6 +2343,9 @@ packages:
resolution: {integrity: sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==}
engines: {node: '>= 0.10'}
intro.js@8.3.2:
resolution: {integrity: sha512-+QsuU8P7Z/O7stAwZ8Uj6CPyKsY6xVx/7hKTVLjlIEPYHaT43XnEUUYHCln6Ehr7GlDuwczh6I8PD/HGf4EG0A==}
invert-kv@1.0.0:
resolution: {integrity: sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ==}
engines: {node: '>=0.10.0'}
@@ -6300,6 +6306,8 @@ snapshots:
interpret@1.4.0: {}
intro.js@8.3.2: {}
invert-kv@1.0.0: {}
is-absolute@1.0.0:

View File

@@ -1,4 +1,5 @@
@use "anim" as *;
@use 'intro.js/minified/introjs.min.css';
:root {
--color-reverse-white: white;

View File

@@ -183,7 +183,7 @@ function next() {
<div class="dict-header flex justify-between items-center relative">
<BackIcon class="dict-back z-2"/>
<div class="dict-title absolute text-2xl text-align-center w-full">{{ runtimeStore.editDict.name }}</div>
<div class="dict-actions flex gap-2">
<div class="dict-actions flex">
<BaseButton v-if="runtimeStore.editDict.custom && runtimeStore.editDict.url" type="info" @click="reset">
恢复默认
</BaseButton>

View File

@@ -1,11 +1,11 @@
<script setup lang="tsx">
import {DictId} from "@/types/types.ts";
import { DictId } from "@/types/types.ts";
import BasePage from "@/components/BasePage.vue";
import {computed, onMounted, reactive, ref, shallowReactive} from "vue";
import {useRuntimeStore} from "@/stores/runtime.ts";
import {_getDictDataByUrl, _nextTick, convertToWord, isMobile, loadJsLib, useNav} from "@/utils";
import {nanoid} from "nanoid";
import { computed, onMounted, reactive, ref, shallowReactive } from "vue";
import { useRuntimeStore } from "@/stores/runtime.ts";
import { _getDictDataByUrl, _nextTick, convertToWord, isMobile, loadJsLib, sleep, useNav } from "@/utils";
import { nanoid } from "nanoid";
import BaseIcon from "@/components/BaseIcon.vue";
import BaseTable from "@/components/BaseTable.vue";
import WordItem from "@/components/WordItem.vue";
@@ -13,21 +13,21 @@ import Toast from '@/components/base/toast/Toast.ts'
import PopConfirm from "@/components/PopConfirm.vue";
import BackIcon from "@/components/BackIcon.vue";
import BaseButton from "@/components/BaseButton.vue";
import {useRoute, useRouter} from "vue-router";
import {useBaseStore} from "@/stores/base.ts";
import { useRoute, useRouter } from "vue-router";
import { useBaseStore } from "@/stores/base.ts";
import EditBook from "@/pages/article/components/EditBook.vue";
import {getDefaultDict} from "@/types/func.ts";
import { getDefaultDict } from "@/types/func.ts";
import BaseInput from "@/components/base/BaseInput.vue";
import Textarea from "@/components/base/Textarea.vue";
import FormItem from "@/components/base/form/FormItem.vue";
import Form from "@/components/base/form/Form.vue";
import DeleteIcon from "@/components/icon/DeleteIcon.vue";
import {getCurrentStudyWord} from "@/hooks/dict.ts";
import { getCurrentStudyWord } from "@/hooks/dict.ts";
import PracticeSettingDialog from "@/pages/word/components/PracticeSettingDialog.vue";
import {useSettingStore} from "@/stores/setting.ts";
import {MessageBox} from "@/utils/MessageBox.tsx";
import {AppEnv, Origin, PracticeSaveWordKey} from "@/config/env.ts";
import {detail} from "@/apis";
import { useSettingStore } from "@/stores/setting.ts";
import { MessageBox } from "@/utils/MessageBox.tsx";
import { AppEnv, Origin, PracticeSaveWordKey } from "@/config/env.ts";
import { detail } from "@/apis";
const runtimeStore = useRuntimeStore()
const base = useBaseStore()
@@ -257,14 +257,11 @@ async function addMyStudyList() {
}
async function startTest() {
if (!runtimeStore.editDict.words.length) {
loading = true
let r = await _getDictDataByUrl(runtimeStore.editDict)
runtimeStore.editDict = r
loading = false
}
loading = true
await base.changeDict(runtimeStore.editDict)
nav('word-test/' + store.sdict.id, {})
loading = false
nav('word-test/' + store.sdict.id)
}
let exportLoading = $ref(false)
@@ -395,7 +392,7 @@ defineRender(() => {
<div class="dict-header flex justify-between items-center relative">
<BackIcon class="dict-back z-2"/>
<div class="dict-title absolute page-title text-align-center w-full">{runtimeStore.editDict.name}</div>
<div class="dict-actions flex gap-2">
<div class="dict-actions flex">
<BaseButton loading={studyLoading || loading} type="info"
onClick={() => isEdit = true}>编辑</BaseButton>
<BaseButton loading={studyLoading || loading} onClick={addMyStudyList}>学习</BaseButton>

View File

@@ -234,7 +234,7 @@ onMounted(init)
</div>
</div>
<div class="mt-6 flex gap-3">
<div class="mt-6 flex">
<BaseButton type="primary" @click="next">继续测试</BaseButton>
<BaseButton type="info" @click="end">结束</BaseButton>
</div>

View File

@@ -2,10 +2,10 @@
import { useBaseStore } from "@/stores/base.ts";
import { useRouter } from "vue-router";
import BaseIcon from "@/components/BaseIcon.vue";
import { _getAccomplishDate, _getDictDataByUrl, resourceWrap, shuffle, useNav } from "@/utils";
import { _getAccomplishDate, _getDictDataByUrl, _nextTick, resourceWrap, shuffle, useNav } from "@/utils";
import BasePage from "@/components/BasePage.vue";
import { DictResource, WordPracticeMode } from "@/types/types.ts";
import { watch } from "vue";
import { onMounted, watch } from "vue";
import { getCurrentStudyWord } from "@/hooks/dict.ts";
import { useRuntimeStore } from "@/stores/runtime.ts";
import Book from "@/components/Book.vue";
@@ -19,10 +19,11 @@ import PracticeSettingDialog from "@/pages/word/components/PracticeSettingDialog
import ChangeLastPracticeIndexDialog from "@/pages/word/components/ChangeLastPracticeIndexDialog.vue";
import { useSettingStore } from "@/stores/setting.ts";
import { useFetch } from "@vueuse/core";
import {AppEnv, DICT_LIST, Host, PracticeSaveWordKey} from "@/config/env.ts";
import { AppEnv, DICT_LIST, Host, PracticeSaveWordKey } from "@/config/env.ts";
import { myDictList } from "@/apis";
import PracticeWordListDialog from "@/pages/word/components/PracticeWordListDialog.vue";
import ShufflePracticeSettingDialog from "@/pages/word/components/ShufflePracticeSettingDialog.vue";
import introJs from "intro.js";
const store = useBaseStore()
@@ -198,12 +199,19 @@ const {
} = useFetch(resourceWrap(DICT_LIST.WORD.RECOMMENDED)).json()
let isNewHost = $ref(window.location.host === Host)
onMounted(() => {
_nextTick(() => {
introJs.tour().start();
}, 500)
})
</script>
<template>
<BasePage>
<div class="mb-4" v-if="!isNewHost">
新域名已启用后续请访问 <a href="https://typewords.cc/words?from_old_site=1">https://typewords.cc</a>。当前 2study.top 域名将在不久后停止使用
新域名已启用后续请访问 <a href="https://typewords.cc/words?from_old_site=1">https://typewords.cc</a>。当前
2study.top 域名将在不久后停止使用
</div>
<div class="card flex flex-col md:flex-row gap-8">
@@ -258,7 +266,7 @@ let isNewHost = $ref(window.location.host === Host)
<div class="flex items-center gap-4 mt-2 flex-1" v-else>
<div class="title">请选择一本词典开始学习</div>
<BaseButton type="primary" size="large" @click="router.push('/dict-list')">
<BaseButton data-intro='点击这里添加一本词典' type="primary" size="large" @click="router.push('/dict-list')">
<div class="center gap-1">
<IconFluentAdd16Regular/>
<span>选择词典</span>

View File

@@ -45,6 +45,7 @@ export default defineConfig(() => {
},
}),
UnoCSS(),
SlidePlugin(),
isAnalyseBuild ?
visualizer({
gzipSize: true,
@@ -53,7 +54,6 @@ export default defineConfig(() => {
filename: "report.html",
open: true
}) : null,
SlidePlugin(),
isCdnBuild ? [
{
name: 'inject-cdn-head',