hookehuyr

refactor(router): 移除PDF预览页面并优化课程详情页布局

移除不再使用的PDF预览页面及其路由配置,优化课程详情页文件列表的布局和交互
1 /* 1 /*
2 * @Date: 2025-03-20 20:36:36 2 * @Date: 2025-03-20 20:36:36
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2025-05-08 11:14:46 4 + * @LastEditTime: 2025-05-08 12:23:36
5 * @FilePath: /mlaj/src/main.js 5 * @FilePath: /mlaj/src/main.js
6 * @Description: 文件描述 6 * @Description: 文件描述
7 */ 7 */
...@@ -18,10 +18,10 @@ import { library } from '@fortawesome/fontawesome-svg-core' ...@@ -18,10 +18,10 @@ import { library } from '@fortawesome/fontawesome-svg-core'
18 /* import font awesome icon component */ 18 /* import font awesome icon component */
19 import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome' 19 import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
20 /* import specific icons */ 20 /* import specific icons */
21 -import { faCirclePause, faCirclePlay, faPlay, faPause, faBackwardStep, faForwardStep, faVolumeUp, faRedo, faRepeat, faList, faChevronDown, faVolumeOff, faXmark, faFileAlt, faTimes, faEye, faFilePdf, faExternalLinkAlt, faSpinner, faExclamationCircle } from '@fortawesome/free-solid-svg-icons' 21 +import { faCirclePause, faCirclePlay, faPlay, faPause, faBackwardStep, faForwardStep, faVolumeUp, faRedo, faRepeat, faList, faChevronDown, faVolumeOff, faXmark, faFileAlt, faTimes, faEye, faFilePdf, faExternalLinkAlt, faSpinner, faExclamationCircle, faDownload } from '@fortawesome/free-solid-svg-icons'
22 22
23 /* add icons to the library */ 23 /* add icons to the library */
24 -library.add(faCirclePause, faCirclePlay, faPlay, faPause, faBackwardStep, faForwardStep, faVolumeUp, faRedo, faRepeat, faList, faChevronDown, faVolumeOff, faXmark, faFileAlt, faTimes, faEye, faFilePdf, faExternalLinkAlt, faSpinner, faExclamationCircle) 24 +library.add(faCirclePause, faCirclePlay, faPlay, faPause, faBackwardStep, faForwardStep, faVolumeUp, faRedo, faRepeat, faList, faChevronDown, faVolumeOff, faXmark, faFileAlt, faTimes, faEye, faFilePdf, faExternalLinkAlt, faSpinner, faExclamationCircle, faDownload )
25 25
26 const app = createApp(App) 26 const app = createApp(App)
27 // 屏蔽警告信息 27 // 屏蔽警告信息
......
1 /* 1 /*
2 * @Date: 2025-03-20 20:36:36 2 * @Date: 2025-03-20 20:36:36
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2025-04-18 10:08:35 4 + * @LastEditTime: 2025-05-08 12:06:46
5 * @FilePath: /mlaj/src/router/routes.js 5 * @FilePath: /mlaj/src/router/routes.js
6 * @Description: 路由地址映射配置 6 * @Description: 路由地址映射配置
7 */ 7 */
...@@ -219,11 +219,5 @@ export const routes = [ ...@@ -219,11 +219,5 @@ export const routes = [
219 title: '课程集合页面', 219 title: '课程集合页面',
220 } 220 }
221 }, 221 },
222 - {
223 - path: '/pdf-preview',
224 - name: 'pdf-preview',
225 - component: () => import('../views/study/PdfPreviewPage.vue'),
226 - meta: { title: 'PDF预览' },
227 - },
228 ...checkinRoutes, 222 ...checkinRoutes,
229 ] 223 ]
......
1 -<!--
2 - * @Date: 2024-01-17
3 - * @Description: PDF预览页面
4 --->
5 -<template>
6 - <div class="pdf-preview-page bg-white min-h-screen flex flex-col">
7 - <!-- 顶部导航栏 -->
8 - <div class="flex items-center justify-between p-4 bg-white border-b sticky top-0 z-10">
9 - <div class="flex items-center space-x-2">
10 - <font-awesome-icon icon="file-pdf" class="text-red-500 text-xl" />
11 - <span class="text-gray-900 font-medium">{{ title }}</span>
12 - </div>
13 - <div class="flex items-center space-x-4">
14 - <a :href="pdfUrl" target="_blank" class="text-blue-600 hover:text-blue-800">
15 - <font-awesome-icon icon="external-link-alt" class="mr-1" />
16 - 新窗口打开
17 - </a>
18 - <button @click="goBack" class="text-gray-500 hover:text-gray-700">
19 - <font-awesome-icon icon="times" />
20 - </button>
21 - </div>
22 - </div>
23 -
24 - <!-- PDF内容区域 -->
25 - <div class="flex-1 overflow-y-auto bg-gray-100 p-4">
26 - <div v-for="pageNum in pageNums" :key="pageNum" class="mb-4" ref="pageRefs">
27 - <VuePdfEmbed
28 - v-if="pageVisibility[pageNum]"
29 - :source="{ url: pdfUrl }"
30 - :page="pageNum"
31 - :scale="1.5"
32 - :render-text="true"
33 - style="width: 100%;"
34 - />
35 - </div>
36 - </div>
37 - </div>
38 -</template>
39 -
40 -<script setup>
41 -import { ref, computed, onMounted, onBeforeUnmount, nextTick } from 'vue';
42 -import { useRoute, useRouter } from 'vue-router';
43 -import VuePdfEmbed, { useVuePdfEmbed } from 'vue-pdf-embed';
44 -
45 -const route = useRoute();
46 -const router = useRouter();
47 -
48 -// 获取路由参数
49 -const title = ref(route.query.title || 'PDF预览');
50 -const pdfUrl = ref(route.query.url || '');
51 -
52 -// PDF页面相关
53 -const pageRefs = ref([]);
54 -const pageVisibility = ref({});
55 -let pageIntersectionObserver;
56 -
57 -// 使用PDF嵌入组件
58 -const { doc } = useVuePdfEmbed({
59 - source: { url: pdfUrl.value },
60 -});
61 -
62 -// 计算总页数
63 -const pageNums = computed(() =>
64 - doc.value
65 - ? [...Array(doc.value.numPages + 1).keys()].slice(1)
66 - : []
67 -);
68 -
69 -// 重置页面交叉观察器
70 -const resetPageIntersectionObserver = () => {
71 - pageIntersectionObserver?.disconnect();
72 - pageIntersectionObserver = new IntersectionObserver((entries) => {
73 - entries.forEach((entry) => {
74 - if (entry.isIntersecting) {
75 - const index = pageRefs.value.indexOf(entry.target);
76 - const pageNum = pageNums.value[index];
77 - pageVisibility.value[pageNum] = true;
78 - }
79 - });
80 - });
81 - pageRefs.value.forEach((element) => {
82 - if (element) {
83 - pageIntersectionObserver.observe(element);
84 - }
85 - });
86 -};
87 -
88 -// 返回上一页
89 -const goBack = () => {
90 - router.back();
91 -};
92 -
93 -// 监听页数变化
94 -watch(pageNums, (newPageNums) => {
95 - if (newPageNums.length > 0) {
96 - pageVisibility.value = { [newPageNums[0]]: true };
97 - nextTick(resetPageIntersectionObserver);
98 - }
99 -});
100 -
101 -// 组件卸载前清理
102 -onBeforeUnmount(() => {
103 - pageIntersectionObserver?.disconnect();
104 -});
105 -</script>
106 -
107 -<style lang="less" scoped>
108 -.pdf-preview-page {
109 - .pdf-content {
110 - background-color: #f3f4f6;
111 - }
112 -}
113 -</style>
...@@ -50,23 +50,19 @@ ...@@ -50,23 +50,19 @@
50 <div v-if="course.course_type === 'file'" class="w-full relative bg-white rounded-lg shadow-sm"> 50 <div v-if="course.course_type === 'file'" class="w-full relative bg-white rounded-lg shadow-sm">
51 <div class="p-4 space-y-3"> 51 <div class="p-4 space-y-3">
52 <div v-for="(item, index) in courseFile?.list" :key="index" class="group hover:bg-gray-50 transition-colors rounded-lg p-3"> 52 <div v-for="(item, index) in courseFile?.list" :key="index" class="group hover:bg-gray-50 transition-colors rounded-lg p-3">
53 - <div class="flex items-center space-x-3"> 53 + <div class="flex items-center justify-between space-x-3 px-2">
54 - <div class="flex-shrink-0"> 54 + <div class="flex items-center space-x-3 flex-1 min-w-0">
55 - <font-awesome-icon icon="file-alt" class="text-gray-400 text-xl" /> 55 + <font-awesome-icon icon="file-alt" class="text-gray-400 text-lg flex-shrink-0" />
56 - </div> 56 + <h3 class="text-xs font-medium text-gray-900 truncate">{{ item.title }}</h3>
57 - <div class="flex-1 min-w-0">
58 - <h3 class="text-sm font-medium text-gray-900 truncate">{{ item.title }}</h3>
59 - <!-- PDF文件预览 -->
60 - <template v-if="item.url.toLowerCase().endsWith('.pdf')">
61 - <button @click="openPdfViewer(item)" class="mt-2 w-full text-left text-blue-600 hover:text-blue-800 hover:underline">
62 - <font-awesome-icon icon="eye" class="mr-1" />
63 - 预览PDF
64 - </button>
65 - </template>
66 - <template v-else>
67 - <a :href="item.url" target="_blank" class="text-sm text-blue-600 hover:text-blue-800 hover:underline truncate block mt-1">打开文件</a>
68 - </template>
69 </div> 57 </div>
58 + <template v-if="item.url.toLowerCase().endsWith('.pdf')">
59 + <a :href="item.url" download class="text-xs text-blue-600 hover:text-blue-800 hover:underline whitespace-nowrap">
60 + 查看文件
61 + </a>
62 + </template>
63 + <template v-else>
64 + <a :href="item.url" target="_blank" class="text-xs text-blue-600 hover:text-blue-800 hover:underline whitespace-nowrap">打开文件</a>
65 + </template>
70 </div> 66 </div>
71 </div> 67 </div>
72 </div> 68 </div>
......