feat:Optimize the book detail page

This commit is contained in:
Zyronon
2026-01-06 23:12:02 +08:00
parent c5720973ee
commit e1555d7b46
9 changed files with 34 additions and 39 deletions

2
components.d.ts vendored
View File

@@ -46,6 +46,7 @@ declare module 'vue' {
IconFluentAdd16Regular: typeof import('~icons/fluent/add16-regular')['default']
IconFluentAdd20Regular: typeof import('~icons/fluent/add20-regular')['default']
IconFluentAddSquare20Regular: typeof import('~icons/fluent/add-square20-regular')['default']
IconFluentAlignSpaceFitVertical20Regular: typeof import('~icons/fluent/align-space-fit-vertical20-regular')['default']
IconFluentArrowBounce20Regular: typeof import('~icons/fluent/arrow-bounce20-regular')['default']
IconFluentArrowCircleRight16Regular: typeof import('~icons/fluent/arrow-circle-right16-regular')['default']
IconFluentArrowClockwise20Regular: typeof import('~icons/fluent/arrow-clockwise20-regular')['default']
@@ -116,6 +117,7 @@ declare module 'vue' {
IconFluentTextEditStyle20Regular: typeof import('~icons/fluent/text-edit-style20-regular')['default']
IconFluentTextListAbcUppercaseLtr20Regular: typeof import('~icons/fluent/text-list-abc-uppercase-ltr20-regular')['default']
IconFluentTextParagraph16Regular: typeof import('~icons/fluent/text-paragraph16-regular')['default']
IconFluentTextPositionThrough20Regular: typeof import('~icons/fluent/text-position-through20-regular')['default']
IconFluentTextUnderlineDouble20Regular: typeof import('~icons/fluent/text-underline-double20-regular')['default']
IconFluentTranslate16Regular: typeof import('~icons/fluent/translate16-regular')['default']
IconFluentTranslateOff16Regular: typeof import('~icons/fluent/translate-off16-regular')['default']

View File

@@ -83,7 +83,6 @@ async function close() {
watch(
() => props.modelValue,
n => {
// console.log('n', n)
if (n) {
id = Date.now()
runtimeStore.modalList.push({ id, close })

View File

@@ -2,8 +2,8 @@ import { Article, Dict, DictId, DictType, TaskWords, Word } from '@/types/types.
import { useBaseStore } from '@/stores/base.ts'
import { useSettingStore } from '@/stores/setting.ts'
import { getDefaultDict, getDefaultWord } from '@/types/func.ts'
import { _getDictDataByUrl, cloneDeep, getRandomN, resourceWrap, shuffle, splitIntoN } from '@/utils'
import { onMounted, watch } from 'vue'
import { _getDictDataByUrl, cloneDeep, getRandomN, resourceWrap, shuffle, sleep, splitIntoN } from '@/utils'
import { onMounted, ref, watch } from 'vue'
import { AppEnv, DICT_LIST } from '@/config/env.ts'
import { detail } from '@/apis'
import { useRuntimeStore } from '@/stores/runtime.ts'
@@ -220,32 +220,31 @@ export function getCurrentStudyWord(): TaskWords {
export function useGetDict() {
const store = useBaseStore()
const runtimeStore = useRuntimeStore()
let loading = $ref(false)
let loading = ref(false)
const route = useRoute()
const router = useRouter()
watch(
[() => store.load, () => loading],
([a, b]) => {
if (a && b) loadDict()
if (a && b.value) loadDict()
},
{ immediate: true }
)
onMounted(() => {
if (!runtimeStore.editDict?.id) {
let dictId = route.params?.id
let dictId = route.query?.id
if (!dictId) {
return router.push('/articles')
}
loading = true
loading.value = true
} else {
loadDict(runtimeStore.editDict)
}
})
async function loadDict(dict?: Dict) {
// console.log('load好了开始加载')
if (!dict) {
dict = getDefaultDict()
let dictId = route.query.id
@@ -262,7 +261,7 @@ export function useGetDict() {
![DictId.articleCollect].includes(dict.en_name || dict.id) &&
!dict?.is_default
) {
loading = true
loading.value = true
let r = await _getDictDataByUrl(dict, DictType.article)
runtimeStore.editDict = r
}
@@ -277,14 +276,13 @@ export function useGetDict() {
}
}
}
loading = false
loading.value = false
} else {
// router.push('/articles')
router.push('/articles')
}
}
return {
dict: runtimeStore.editDict,
loading,
}
}

View File

@@ -75,7 +75,6 @@ async function init() {
watch(
() => store?.sbook?.id,
n => {
console.log('n', n)
if (!n) {
_nextTick(async () => {
const Shepherd = await loadJsLib('Shepherd', LIB_JS_URL.SHEPHERD)

View File

@@ -3,30 +3,20 @@ import BackIcon from '@/components/BackIcon.vue'
import Empty from '@/components/Empty.vue'
import ArticleList from '@/components/list/ArticleList.vue'
import { useBaseStore } from '@/stores/base.ts'
import { Article, Dict, DictId, DictType } from '@/types/types.ts'
import { Article, Dict, DictType } from '@/types/types.ts'
import { useRuntimeStore } from '@/stores/runtime.ts'
import BaseButton from '@/components/BaseButton.vue'
import { useRoute, useRouter } from 'vue-router'
import EditBook from '@/pages/article/components/EditBook.vue'
import { computed, onMounted, onUnmounted, watch } from 'vue'
import {
_dateFormat,
_getDictDataByUrl,
_nextTick,
cloneDeep,
msToHourMinute,
resourceWrap,
total,
useNav,
} from '@/utils'
import { _dateFormat, _getDictDataByUrl, _nextTick, msToHourMinute, resourceWrap, total, useNav } from '@/utils'
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 { useSettingStore } from '@/stores/setting.ts'
import { useFetch } from '@vueuse/core'
import { AppEnv, DICT_LIST } from '@/config/env.ts'
import { detail } from '@/apis'
import { DICT_LIST } from '@/config/env.ts'
import BaseIcon from '@/components/BaseIcon.vue'
import Switch from '@/components/base/Switch.vue'
import { useGetDict } from '@/hooks/dict.ts'
@@ -70,7 +60,7 @@ const showBookDetail = computed(() => {
return !(isAdd || isEdit)
})
const { dict, loading } = useGetDict()
const { loading } = useGetDict()
onMounted(() => {
if (route.query?.isAdd) {
@@ -157,6 +147,7 @@ const list = $computed(() => {
}),
].concat(runtimeStore.editDict.articles)
})
console.log('list',list)
let showTranslate = $ref(true)
let startPlay = $ref(false)
@@ -185,6 +176,7 @@ const shouldShowInlineTranslation = $computed(() => {
// 定位翻译到原文下方
function positionTranslations() {
if (loading.value || selectArticle.id === -1) return
_nextTick(() => {
const articleRect = articleWrapperRef.getBoundingClientRect()
selectArticle.textTranslate.split('\n\n').forEach((paragraph, paraIndex) => {
@@ -219,8 +211,10 @@ watch([() => displayMode, () => selectArticle.id, () => showTranslate], () => {
<template>
<div class="center h-screen">
<div class="bg-second w-full 3xl:w-7/10 2xl:w-8/10 xl:w-full 2xl:card 2xl:h-[97vh] h-full overflow-hidden mb-0">
<div class="flex p-space box-border flex-col h-full" v-if="showBookDetail">
<div
class="bg-second w-full 3xl:w-7/10 2xl:w-8/10 xl:w-full 2xl:card 2xl:h-[97vh] h-full p-3 box-border overflow-hidden mb-0"
>
<div class="flex box-border flex-col h-full" v-if="showBookDetail" v-loading="loading">
<div class="dict-header flex justify-between items-center relative">
<div class="flex gap-space">
<BackIcon class="dict-back z-2" />
@@ -239,7 +233,7 @@ watch([() => displayMode, () => selectArticle.id, () => showTranslate], () => {
<div class="3xl:w-80 2xl:w-60 xl:w-55 lg:w-50 overflow-auto">
<ArticleList
:show-desc="true"
v-if="runtimeStore.editDict.length"
v-if="list.length"
@click="handleCheckedChange"
:list="list"
:active-id="selectArticle.id"
@@ -257,16 +251,16 @@ watch([() => displayMode, () => selectArticle.id, () => showTranslate], () => {
v-if="runtimeStore.editDict?.cover"
alt=""
/>
<div class="text-lg">介绍{{ runtimeStore.editDict.description }}</div>
<div class="text-lg">{{ runtimeStore.editDict.description }}</div>
</div>
<div class="text-base" v-if="totalSpend">总学习时长{{ totalSpend }}</div>
<div class="text-base mt-10" v-if="totalSpend">总学习时长{{ totalSpend }}</div>
</template>
<template v-else>
<div class="flex-1 overflow-auto pb-30">
<div>
<div class="flex justify-between items-center relative">
<span>
<span class="text-4xl">{{ selectArticle.title }}</span>
<span class="text-3xl">{{ selectArticle.title }}</span>
<span class="ml-6 text-2xl" v-if="showTranslate">{{ selectArticle.titleTranslate }}</span>
</span>
<div class="flex items-center gap-2 mr-4">
@@ -397,7 +391,10 @@ watch([() => displayMode, () => selectArticle.id, () => showTranslate], () => {
</div>
</template>
</div>
<div class="border-t-1 border-t-gray-300 border-solid border-0 center gap-2 pt-4">
<div
v-if="selectArticle.audioSrc || selectArticle.audioFileId"
class="border-t-1 border-t-gray-300 border-solid border-0 center gap-2 pt-4"
>
<ArticleAudio
:article="selectArticle"
@update-speed="handleSpeedUpdate"
@@ -416,7 +413,7 @@ watch([() => displayMode, () => selectArticle.id, () => showTranslate], () => {
</div>
</div>
</div>
<div class="card mb-0 dict-detail-card" v-else>
<div class="" v-else>
<div class="dict-header flex justify-between items-center relative">
<BackIcon class="dict-back z-2" @click="isAdd ? $router.back() : (isEdit = false)" />
<div class="dict-title absolute text-2xl text-align-center w-full">

View File

@@ -675,7 +675,7 @@ const currentPractice = inject('currentPractice', [])
<header class="pt-10 pb-6">
<div class="text-center">
<span class="text-3xl">{{ store.sbook.lastLearnIndex + 1 }}. </span>
<span class="text-4xl">{{ props.article?.title??'' }}</span>
<span class="text-3xl">{{ props.article?.title??'' }}</span>
<span class="ml-6 text-2xl" v-if="settingStore.translate">{{ props.article?.titleTranslate }}</span>
</div>

View File

@@ -29,7 +29,7 @@ async function check() {
console.parse(str)
// console.log(str)
let data = checkAndUpgradeSaveDict(str)
console.log('data', data)
// console.log('data', data)
// this.setState(data)
}

View File

@@ -58,7 +58,7 @@ const groupedByCategoryAndTag = $computed(() => {
data.push([key, groupByDictTags(value)])
}
[data[2], data[3]] = [data[3], data[2]];
console.log('data', data)
// console.log('data', data)
return data
})

View File

@@ -185,7 +185,7 @@ export const useBaseStore = defineStore('base', {
Object.assign(data, res.data)
}
}
console.log('data', data)
// console.log('data', data)
this.setState(data)
} catch (e) {
console.error('读取本地dict数据失败', e)