This commit is contained in:
Zyronon
2025-10-11 00:48:32 +08:00
parent eae79387e2
commit e4f030a7a2
33 changed files with 359 additions and 489 deletions

View File

@@ -14,11 +14,11 @@ import PopConfirm from "@/components/PopConfirm.vue";
import { watch } from "vue";
import { getDefaultDict } from "@/types/func.ts";
import DeleteIcon from "@/components/icon/DeleteIcon.vue";
import recommendBookList from "@/assets/book-list.json";
import dayjs from "dayjs";
import isBetween from "dayjs/plugin/isBetween";
import { PracticeSaveArticleKey } from "@/utils/const.ts";
import isoWeek from 'dayjs/plugin/isoWeek'
import { useFetch } from "@vueuse/core";
import { DICT_LIST, PracticeSaveArticleKey } from "@/config/ENV.ts";
dayjs.extend(isoWeek)
dayjs.extend(isBetween);
@@ -152,6 +152,9 @@ const weekList = $computed(() => {
});
return list
})
const {data: recommendBookList, isFetching} = useFetch(DICT_LIST.ARTICLE.RECOMMENDED).json()
</script>
<template>
@@ -246,7 +249,8 @@ const weekList = $computed(() => {
</div>
</div>
<div class="card flex flex-col">
<div class="card flex flex-col min-h-50" v-loading="isFetching">
<div class="flex justify-between">
<div class="title">推荐</div>
<div class="flex gap-4 items-center">
@@ -258,7 +262,7 @@ const weekList = $computed(() => {
<Book :is-add="false"
quantifier=""
:item="item as any"
v-for="(item, j) in recommendBookList[0]" @click="goBookDetail(item as any)"/>
v-for="(item, j) in recommendBookList" @click="goBookDetail(item as any)"/>
</div>
</div>
</BasePage>

View File

@@ -11,15 +11,16 @@ import BaseButton from "@/components/BaseButton.vue";
import { useRoute, useRouter } from "vue-router";
import EditBook from "@/pages/article/components/EditBook.vue";
import { computed, onMounted } from "vue";
import { _dateFormat, _getDictDataByUrl, cloneDeep, msToHourMinute, total, useNav } from "@/utils";
import { _dateFormat, _getDictDataByUrl, msToHourMinute, total, useNav } from "@/utils";
import BaseIcon from "@/components/BaseIcon.vue";
import { useArticleOptions } from "@/hooks/dict.ts";
import { getDefaultArticle, getDefaultDict } from "@/types/func.ts";
import Toast from "@/components/base/toast/Toast.ts";
import ArticleAudio from "@/pages/article/components/ArticleAudio.vue";
import { MessageBox } from "@/utils/MessageBox.tsx";
import book_list from "@/assets/book-list.json";
import { useSettingStore } from "@/stores/setting.ts";
import { useFetch } from "@vueuse/core";
import { DICT_LIST } from "@/config/ENV.ts";
const runtimeStore = useRuntimeStore()
const settingStore = useSettingStore()
@@ -109,12 +110,14 @@ const {
toggleArticleCollect
} = useArticleOptions()
const {data: book_list} = useFetch(DICT_LIST.ARTICLE.ALL).json()
function reset() {
MessageBox.confirm(
'继续此操作会重置所有文章,并从官方书籍获取最新文章列表,学习记录不会被重置。确认恢复默认吗?',
'恢复默认',
async () => {
let dict = book_list.flat().find(v => v.url === runtimeStore.editDict.url) as Dict
let dict = book_list.value.find(v => v.url === runtimeStore.editDict.url) as Dict
if (dict && dict.id) {
dict = await _getDictDataByUrl(dict, DictType.article)
let rIndex = base.article.bookList.findIndex(v => v.id === runtimeStore.editDict.id)

View File

@@ -1,18 +1,19 @@
<script setup lang="ts">
import {useNav} from "@/utils";
import { useNav } from "@/utils";
import BasePage from "@/components/BasePage.vue";
import {DictResource} from "@/types/types.ts";
import {useRuntimeStore} from "@/stores/runtime.ts";
import { DictResource } from "@/types/types.ts";
import { useRuntimeStore } from "@/stores/runtime.ts";
import BaseIcon from "@/components/BaseIcon.vue";
import Empty from "@/components/Empty.vue";
import Input from "@/components/Input.vue";
import BaseButton from "@/components/BaseButton.vue";
import DictList from "@/components/list/DictList.vue";
import BackIcon from "@/components/BackIcon.vue";
import {useRouter} from "vue-router";
import book_list from "@/assets/book-list.json";
import {computed} from "vue";
import {getDefaultDict} from "@/types/func.ts";
import { useRouter } from "vue-router";
import { computed } from "vue";
import { getDefaultDict } from "@/types/func.ts";
import { useFetch } from "@vueuse/core";
import { DICT_LIST } from "@/config/ENV.ts";
const {nav} = useNav()
const runtimeStore = useRuntimeStore()
@@ -30,11 +31,12 @@ async function getDictDetail(val: DictResource) {
let showSearchInput = $ref(false)
let searchKey = $ref('')
const {data: bookList, isFetching} = useFetch(DICT_LIST.ARTICLE.ALL).json()
const searchList = computed<any[]>(() => {
if (searchKey) {
let s = searchKey.toLowerCase()
return book_list.flat().filter((item) => {
return bookList.value.filter((item) => {
return item.id.toLowerCase().includes(s)
|| item.name.toLowerCase().includes(s)
|| item.category.toLowerCase().includes(s)
@@ -49,7 +51,7 @@ const searchList = computed<any[]>(() => {
<template>
<BasePage>
<div class="card">
<div class="card min-h-50" v-loading="isFetching">
<div class="flex items-center relative gap-2">
<BackIcon class="z-2" @Click='router.back'/>
<div class="flex flex-1 gap-4" v-if="showSearchInput">
@@ -75,9 +77,9 @@ const searchList = computed<any[]>(() => {
</div>
<div class="w-full mt-2" v-else>
<DictList
v-if="book_list.flat().length "
v-if="bookList?.length "
@selectDict="selectDict"
:list="book_list.flat()"
:list="bookList"
quantifier="篇"
:select-id="'-1'"/>
</div>

View File

@@ -31,11 +31,10 @@ import EditSingleArticleModal from "@/pages/article/components/EditSingleArticle
import Tooltip from "@/components/base/Tooltip.vue";
import ConflictNotice from "@/components/ConflictNotice.vue";
import { useRoute, useRouter } from "vue-router";
import book_list from "@/assets/book-list.json";
import PracticeLayout from "@/components/PracticeLayout.vue";
import ArticleAudio from "@/pages/article/components/ArticleAudio.vue";
import { PracticeSaveArticleKey } from "@/utils/const.ts";
import VolumeSetting from "@/pages/article/components/VolumeSetting.vue";
import { DICT_LIST, PracticeSaveArticleKey } from "@/config/ENV.ts";
const store = useBaseStore()
const settingStore = useSettingStore()
@@ -51,7 +50,6 @@ let typingArticleRef = $ref<any>()
let loading = $ref<boolean>(false)
let allWrongWords = new Set()
let editArticle = $ref<Article>(getDefaultArticle())
let speedMinute = $ref(0)
let timer = $ref(0)
let isFocus = true
@@ -109,6 +107,8 @@ async function init() {
if (dictId) {
//先在自己的词典列表里面找,如果没有再在资源列表里面找
dict = store.article.bookList.find(v => v.id === dictId)
let r = await fetch(DICT_LIST.ARTICLE.ALL)
let book_list = await r.json()
if (!dict) dict = book_list.flat().find(v => v.id === dictId) as Dict
if (dict && dict.id) {
//如果是不是自定义词典,就请求数据

View File

@@ -1,9 +1,9 @@
<script setup lang="ts">
import { Article } from "@/types/types.ts";
import { watch } from "vue";
import { LOCAL_FILE_KEY } from "@/utils/const.ts";
import { get } from "idb-keyval";
import Audio from "@/components/base/Audio.vue";
import { LOCAL_FILE_KEY } from "@/config/ENV.ts";
const props = defineProps<{
article: Article

View File

@@ -18,10 +18,10 @@ import Tooltip from "@/components/base/Tooltip.vue";
import InputNumber from "@/components/base/InputNumber.vue";
import {nanoid} from "nanoid";
import {update} from "idb-keyval";
import {LOCAL_FILE_KEY} from "@/utils/const.ts";
import ArticleAudio from "@/pages/article/components/ArticleAudio.vue";
import BaseInput from "@/components/base/BaseInput.vue";
import Textarea from "@/components/base/Textarea.vue";
import { LOCAL_FILE_KEY } from "@/config/ENV.ts";
const Dialog = defineAsyncComponent(() => import('@/components/dialog/Dialog.vue'))

View File

@@ -18,8 +18,8 @@ import Space from "@/pages/article/components/Space.vue";
import { useWordOptions } from "@/hooks/dict.ts";
import nlp from "compromise/three";
import { nanoid } from "nanoid";
import { PracticeSaveArticleKey } from "@/utils/const.ts";
import { usePracticeStore } from "@/stores/practice.ts";
import { PracticeSaveArticleKey } from "@/config/ENV.ts";
interface IProps {
article: Article,

View File

@@ -38,7 +38,3 @@ useWindowClick(() => show = false)
</MiniDialog>
</div>
</template>
<style scoped lang="scss">
@import "@/assets/css/style";
</style>

View File

@@ -6,20 +6,17 @@ import { getShortcutKey, useEventListener } from "@/hooks/event.ts";
import { checkAndUpgradeSaveDict, checkAndUpgradeSaveSetting, cloneDeep, loadJsLib, shakeCommonDict } from "@/utils";
import { DefaultShortcutKeyMap, ShortcutKey } from "@/types/types.ts";
import BaseButton from "@/components/BaseButton.vue";
import {
APP_NAME,
APP_VERSION,
EXPORT_DATA_KEY,
LOCAL_FILE_KEY, PracticeSaveArticleKey,
PracticeSaveWordKey,
SAVE_DICT_KEY,
SAVE_SETTING_KEY,
SoundFileOptions
} from "@/utils/const.ts";
import VolumeIcon from "@/components/icon/VolumeIcon.vue";
import { useBaseStore } from "@/stores/base.ts";
import { saveAs } from "file-saver";
import { Origin } from "@/config/ENV.ts";
import {
APP_NAME, APP_VERSION,
EXPORT_DATA_KEY,
LOCAL_FILE_KEY,
Origin,
PracticeSaveArticleKey,
PracticeSaveWordKey, SAVE_DICT_KEY, SAVE_SETTING_KEY, SoundFileOptions
} from "@/config/ENV.ts";
import dayjs from "dayjs";
import BasePage from "@/components/BasePage.vue";
import Toast from '@/components/base/toast/Toast.ts'

View File

@@ -2,9 +2,9 @@
// import origin from './data.json'
import BaseButton from "@/components/BaseButton.vue";
import {checkAndUpgradeSaveDict} from "@/utils";
import {SAVE_DICT_KEY} from "@/utils/const.ts";
import str from './data.json'
import {get} from 'idb-keyval'
import { SAVE_DICT_KEY } from "@/config/ENV.ts";
let data = {}
let origin = {}

View File

@@ -1,8 +1,8 @@
<script setup lang="ts">
import {groupBy, useNav} from "@/utils";
import { groupBy, useNav } from "@/utils";
import BasePage from "@/components/BasePage.vue";
import {DictResource} from "@/types/types.ts";
import {useRuntimeStore} from "@/stores/runtime.ts";
import { DictResource } from "@/types/types.ts";
import { useRuntimeStore } from "@/stores/runtime.ts";
import BaseIcon from "@/components/BaseIcon.vue";
import Empty from "@/components/Empty.vue";
import Input from "@/components/Input.vue";
@@ -10,11 +10,12 @@ import BaseButton from "@/components/BaseButton.vue";
import DictList from "@/components/list/DictList.vue";
import BackIcon from "@/components/BackIcon.vue";
import DictGroup from "@/components/list/DictGroup.vue";
import {useBaseStore} from "@/stores/base.ts";
import {useRouter} from "vue-router";
import {computed} from "vue";
import {getDefaultDict} from "@/types/func.ts";
import dict_list from "@/assets/dict-list.json";
import { useBaseStore } from "@/stores/base.ts";
import { useRouter } from "vue-router";
import { computed } from "vue";
import { getDefaultDict } from "@/types/func.ts";
import { useFetch } from "@vueuse/core";
import { DICT_LIST } from "@/config/ENV.ts";
const {nav} = useNav()
const runtimeStore = useRuntimeStore()
@@ -45,9 +46,12 @@ function groupByDictTags(dictList: DictResource[]) {
}, {})
}
const {data: dict_list, isFetching} = useFetch(DICT_LIST.WORD.ALL).json()
const groupedByCategoryAndTag = $computed(() => {
const groupByCategory = groupBy(dict_list.flat(), 'category')
let data = []
if (!dict_list.value) return data
const groupByCategory = groupBy(dict_list.value.flat(), 'category')
for (const [key, value] of Object.entries(groupByCategory)) {
data.push([key, groupByDictTags(value)])
}
@@ -61,7 +65,7 @@ let searchKey = $ref('')
const searchList = computed<any[]>(() => {
if (searchKey) {
let s = searchKey.toLowerCase()
return dict_list.flat().filter((item) => {
return dict_list.value.flat().filter((item) => {
return item.id.toLowerCase().includes(s)
|| item.name.toLowerCase().includes(s)
|| item.category.toLowerCase().includes(s)
@@ -76,7 +80,7 @@ const searchList = computed<any[]>(() => {
<template>
<BasePage>
<div class="card">
<div class="card min-h-200" v-loading="isFetching">
<div class="flex items-center relative gap-2">
<BackIcon class="z-2" @click='router.back'/>
<div class="flex flex-1 gap-4" v-if="showSearchInput">
@@ -85,9 +89,11 @@ const searchList = computed<any[]>(() => {
</div>
<div class="py-1 flex flex-1 justify-end" v-else>
<span class="page-title absolute w-full center">词典列表</span>
<BaseIcon @click="showSearchInput = true"
class="z-1"
icon="fluent:search-24-regular">
<BaseIcon
title="搜索"
@click="showSearchInput = true"
class="z-1"
icon="fluent:search-24-regular">
<IconFluentSearch24Regular/>
</BaseIcon>
</div>

View File

@@ -24,9 +24,9 @@ import { usePracticeStore } from "@/stores/practice.ts";
import Toast from '@/components/base/toast/Toast.ts'
import { getDefaultDict, getDefaultWord } from "@/types/func.ts";
import ConflictNotice from "@/components/ConflictNotice.vue";
import dict_list from "@/assets/dict-list.json";
import PracticeLayout from "@/components/PracticeLayout.vue";
import { PracticeSaveWordKey } from "@/utils/const.ts";
import { DICT_LIST, PracticeSaveWordKey } from "@/config/ENV.ts";
const {
isWordCollect,
@@ -64,6 +64,8 @@ async function loadDict() {
if (dictId) {
//先在自己的词典列表里面找,如果没有再在资源列表里面找
dict = store.word.bookList.find(v => v.id === dictId)
let r = await fetch(DICT_LIST.WORD.ALL)
let dict_list = await r.json()
if (!dict) dict = dict_list.flat().find(v => v.id === dictId) as Dict
if (dict && dict.id) {
//如果是不是自定义词典,就请求数据

View File

@@ -18,9 +18,9 @@ import DeleteIcon from "@/components/icon/DeleteIcon.vue";
import PracticeSettingDialog from "@/pages/word/components/PracticeSettingDialog.vue";
import ChangeLastPracticeIndexDialog from "@/pages/word/components/ChangeLastPracticeIndexDialog.vue";
import { useSettingStore } from "@/stores/setting.ts";
import recommendDictList from "@/assets/recommend-dict-list.json";
import CollectNotice from "@/components/CollectNotice.vue";
import { PracticeSaveWordKey } from "@/utils/const.ts";
import { useFetch } from "@vueuse/core";
import { DICT_LIST, PracticeSaveWordKey } from "@/config/ENV.ts";
const store = useBaseStore()
@@ -130,7 +130,6 @@ const progressTextRight = $computed(() => {
return store.sdict?.lastLearnIndex
})
function check(cb: Function) {
if (!store.sdict.id) {
Toast.warning('请先选择一本词典')
@@ -154,6 +153,8 @@ function saveLastPracticeIndex(e) {
localStorage.removeItem(PracticeSaveWordKey.key)
currentStudy = getCurrentStudyWord()
}
const {data: recommendDictList, isFetching} = useFetch(DICT_LIST.WORD.RECOMMENDED).json()
</script>
<template>
@@ -266,7 +267,7 @@ function saveLastPracticeIndex(e) {
</div>
</div>
<div class="card flex flex-col">
<div class="card flex flex-col overflow-hidden" v-loading="isFetching">
<div class="flex justify-between">
<div class="title">推荐</div>
<div class="flex gap-4 items-center">
@@ -274,7 +275,7 @@ function saveLastPracticeIndex(e) {
</div>
</div>
<div class="flex gap-4 flex-wrap mt-4">
<div class="flex gap-4 flex-wrap mt-4 min-h-50">
<Book :is-add="false"
quantifier="个词"
:item="item as any"