hookehuyr

feat(StudyDetailPage): 添加文件下载功能

为StudyDetailPage页面添加文件下载功能,用户点击非PDF文件时触发下载操作。通过axios获取文件数据,并使用Blob对象处理下载流程,提升用户体验。
......@@ -54,8 +54,12 @@
<font-awesome-icon icon="file-alt" class="text-gray-400 text-lg flex-shrink-0" />
<h3 class="text-x font-medium text-gray-900 truncate">{{ item.title }}</h3>
</div>
<div v-if="item.url.toLowerCase().endsWith('.pdf')" class="text-x text-blue-600 hover:text-blue-800 hover:underline whitespace-nowrap" @click="showPdf(item)">查看文件</div>
<a v-else :href="item.url" target="_blank" class="text-x text-blue-600 hover:text-blue-800 hover:underline whitespace-nowrap">查看文件</a>
<div v-if="item.url.toLowerCase().endsWith('.pdf')"
class="text-x text-blue-600 hover:text-blue-800 hover:underline whitespace-nowrap"
@click="showPdf(item)">查看文件</div>
<div v-else @click="downloadFile(item)"
class="text-x text-blue-600 hover:text-blue-800 hover:underline whitespace-nowrap">
下载文件</div>
</div>
</div>
</div>
......@@ -238,6 +242,7 @@ import VideoPlayer from '@/components/ui/VideoPlayer.vue';
import AudioPlayer from '@/components/ui/AudioPlayer.vue';
import dayjs from 'dayjs';
import { formatDate } from '@/utils/tools'
import axios from 'axios';
import PdfPreview from '@/components/ui/PdfPreview.vue';
......@@ -360,7 +365,7 @@ const pdfShow = ref(false);
const pdfTitle = ref('');
const pdfUrl = ref('');
const showPdf = ({title, url}) => {
const showPdf = ({ title, url }) => {
pdfTitle.value = title;
pdfUrl.value = url;
pdfShow.value = true;
......@@ -584,6 +589,59 @@ watch(showCommentPopup, async (newVal) => {
onPopupLoad();
}
});
// 下载文件
const downloadFile = ({ title, url }) => {
// 获取文件URL和文件名
const fileUrl = url;
const fileName = title;
// 根据文件URL后缀获取MIME类型
const getMimeType = (url) => {
const extension = url.split('.').pop().toLowerCase();
const mimeTypes = {
'pdf': 'application/pdf',
'doc': 'application/msword',
'docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'xls': 'application/vnd.ms-excel',
'xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'ppt': 'application/vnd.ms-powerpoint',
'pptx': 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
'txt': 'text/plain',
'zip': 'application/zip',
'rar': 'application/x-rar-compressed',
'7z': 'application/x-7z-compressed',
'mp3': 'audio/mpeg',
'mp4': 'video/mp4',
'jpg': 'image/jpeg',
'jpeg': 'image/jpeg',
'png': 'image/png',
'gif': 'image/gif'
};
return mimeTypes[extension] || 'application/octet-stream';
};
axios({
method: 'get',
url: fileUrl,
responseType: 'blob' // 表示返回的数据类型是Blob
}).then((response) => {
const blob = new Blob([response.data], { type: getMimeType(fileUrl) });
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = fileName;
a.style.display = 'none';
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
}).catch((error) => {
console.error('下载文件出错:', error);
});
}
</script>
<style lang="less" scoped>
......