|
@@ -63,7 +63,20 @@
|
|
|
|
|
|
|
|
<!-- PDF -->
|
|
<!-- PDF -->
|
|
|
<div v-else-if="activeKind === 'pdf'" class="stage">
|
|
<div v-else-if="activeKind === 'pdf'" class="stage">
|
|
|
- <iframe class="frame" :src="pdfIframeSrc" title="PDF Preview" frameborder="0"></iframe>
|
|
|
|
|
|
|
+ <div v-if="pdfLoading" class="loading-state">
|
|
|
|
|
+ <el-icon class="is-loading" style="font-size: 24px; color: var(--el-color-primary)">
|
|
|
|
|
+ <Loading />
|
|
|
|
|
+ </el-icon>
|
|
|
|
|
+ <p style="margin-top: 10px; color: var(--el-text-color-secondary)">正在加载 PDF...</p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <el-empty v-else-if="pdfError" :description="pdfError" />
|
|
|
|
|
+ <iframe
|
|
|
|
|
+ v-else
|
|
|
|
|
+ class="frame"
|
|
|
|
|
+ :src="pdfBlobUrl || pdfIframeSrc"
|
|
|
|
|
+ title="PDF Preview"
|
|
|
|
|
+ frameborder="0"
|
|
|
|
|
+ ></iframe>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
<!-- Word -->
|
|
<!-- Word -->
|
|
@@ -179,6 +192,55 @@ const pdfIframeSrc = computed(() => {
|
|
|
return `${activeUrl.value}#toolbar=0&navpanes=0&scrollbar=0`
|
|
return `${activeUrl.value}#toolbar=0&navpanes=0&scrollbar=0`
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
|
|
+const pdfBlobUrl = ref<string>('')
|
|
|
|
|
+const pdfLoading = ref(false)
|
|
|
|
|
+const pdfError = ref<string>('')
|
|
|
|
|
+
|
|
|
|
|
+watch(
|
|
|
|
|
+ () => activeUrl.value,
|
|
|
|
|
+ async (url) => {
|
|
|
|
|
+ if (!url || activeKind.value !== 'pdf') {
|
|
|
|
|
+ pdfBlobUrl.value = ''
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ pdfLoading.value = true
|
|
|
|
|
+ pdfError.value = ''
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ const response = await fetch(url, {
|
|
|
|
|
+ method: 'GET',
|
|
|
|
|
+ mode: 'cors'
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ if (!response.ok) {
|
|
|
|
|
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const contentType = response.headers.get('content-type') || ''
|
|
|
|
|
+ if (!contentType.includes('application/pdf')) {
|
|
|
|
|
+ throw new Error('非 PDF 文件类型')
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const blob = await response.blob()
|
|
|
|
|
+ const blobUrl = URL.createObjectURL(blob)
|
|
|
|
|
+
|
|
|
|
|
+ if (pdfBlobUrl.value) {
|
|
|
|
|
+ URL.revokeObjectURL(pdfBlobUrl.value)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ pdfBlobUrl.value = blobUrl
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error('PDF 加载失败:', error)
|
|
|
|
|
+ pdfError.value = error instanceof Error ? error.message : 'PDF 加载失败'
|
|
|
|
|
+ pdfBlobUrl.value = url
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ pdfLoading.value = false
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ { immediate: true }
|
|
|
|
|
+)
|
|
|
|
|
+
|
|
|
const previewHint = computed(() => {
|
|
const previewHint = computed(() => {
|
|
|
if (!activeUrl.value) return ''
|
|
if (!activeUrl.value) return ''
|
|
|
if (activeKind.value === 'word' && !officeIframeSrc.value) {
|
|
if (activeKind.value === 'word' && !officeIframeSrc.value) {
|
|
@@ -187,11 +249,6 @@ const previewHint = computed(() => {
|
|
|
return ''
|
|
return ''
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
-const openNewTab = () => {
|
|
|
|
|
- if (!activeUrl.value) return
|
|
|
|
|
- window.open(activeUrl.value, '_blank', 'noopener,noreferrer')
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
const download = () => {
|
|
const download = () => {
|
|
|
if (!activeUrl.value) return
|
|
if (!activeUrl.value) return
|
|
|
const a = document.createElement('a')
|
|
const a = document.createElement('a')
|