IntelliClass_FE/pages/preview/[resource_url].vue
Timothy Yin 6221602d5e
refactor: restructure sidebar components and update navigation
- Updated Container.vue to import SubNavItem from Secondary.vue and renamed component usage.
- Removed NavMain.vue and NavUser.vue components, consolidating sidebar functionality.
- Deleted Sidebar.vue and created a new sidebar structure in index.vue.
- Implemented new Main.vue and User.vue components under sidebar/nav for better organization.
- Added DPlayer for video playback in preview page and adjusted layout accordingly.
- Introduced new course Card.vue component for displaying course information.
- Created Secondary.vue for secondary navigation with improved styling and functionality.
- Updated package.json to include dplayer and its types for video handling.
2025-04-19 12:16:39 +08:00

139 lines
3.3 KiB
Vue

<script lang="ts" setup>
import VueOfficePptx from '@vue-office/pptx'
import VueOfficeDocx from '@vue-office/docx'
import VueOfficeExcel from '@vue-office/excel'
import VueOfficePdf from '@vue-office/pdf'
import '@vue-office/docx/lib/index.css'
import '@vue-office/excel/lib/index.css'
import DPlayer from 'dplayer'
definePageMeta({
hideSidebar: true,
})
const {
params: { resource_url },
} = useRoute()
const { setBreadcrumbs } = useBreadcrumbs()
const url = computed(() => {
return atob(resource_url as string)
})
const fileExtension = computed(() => {
const lastDotIndex = url.value.lastIndexOf('.')
if (lastDotIndex === -1) return ''
return url.value.substring(lastDotIndex + 1).toLowerCase()
})
const fileType = computed(() => {
const ext = fileExtension.value
if (ext === 'pdf') return 'pdf'
if (ext === 'doc' || ext === 'docx') return 'word'
if (ext === 'ppt' || ext === 'pptx') return 'ppt'
if (ext === 'xls' || ext === 'xlsx') return 'excel'
if (ext === 'txt') return 'txt'
if (ext === 'jpg' || ext === 'jpeg' || ext === 'png' || ext === 'gif')
return 'image'
if (ext === 'mp4' || ext === 'avi' || ext === 'mov') return 'video'
if (ext === 'mp3' || ext === 'wav') return 'audio'
return ''
})
const containerClass = computed(() => {
return fileType.value === 'video'
? 'max-w-6xl mx-auto'
: 'w-full h-full border rounded-lg overflow-hidden'
})
onMounted(() => {
useHead({
title: `${fileType.value.toUpperCase()} 资源预览`,
})
setBreadcrumbs([
{
label: `${fileType.value.toUpperCase()} 资源预览`,
},
])
// initialize video player
if (fileType.value === 'video') {
const dp = new DPlayer({
container: document.getElementById('dplayer'),
screenshot: true,
video: {
url: url.value,
},
})
dp.play()
}
})
const vueOfficeOptions = {
autoSize: true,
autoHeight: true,
autoWidth: true,
autoScale: true,
autoRotate: true,
autoFit: true,
}
</script>
<template>
<AppContainer>
<div v-if="!url">
<div class="flex items-center justify-center h-full">
<p class="text-muted-foreground">资源链接无效</p>
</div>
</div>
<div
v-else
:class="containerClass"
>
<!-- Video -->
<div
v-if="fileType === 'video'"
id="dplayer"
/>
<!-- Vue Office -->
<VueOfficeDocx
v-else-if="fileType === 'word'"
class="w-full h-full"
:src="url"
:options="vueOfficeOptions"
/>
<VueOfficePptx
v-else-if="fileType === 'ppt'"
class="w-full h-full"
:src="url"
:options="vueOfficeOptions"
/>
<VueOfficeExcel
v-else-if="fileType === 'excel'"
class="w-full h-full"
:src="url"
:options="vueOfficeOptions"
/>
<VueOfficePdf
v-else-if="fileType === 'pdf'"
class="w-full h-full"
:src="url"
:options="vueOfficeOptions"
/>
<div
v-else
class="flex flex-col items-center justify-center h-full gap-4 text-muted-foreground"
>
<Icon
name="fluent-color:notebook-question-mark-24"
class="text-6xl"
/>
<p>暂不支持该资源类型</p>
</div>
</div>
</AppContainer>
</template>
<style scoped></style>