From e098cfd8fa98c26288e7f9e38972a3b97b0649df Mon Sep 17 00:00:00 2001 From: chabai <14799297+dhasjklhdfjkasfbhfasfj@user.noreply.gitee.com> Date: Fri, 8 Aug 2025 10:26:36 +0800 Subject: [PATCH] =?UTF-8?q?=E5=BC=80=E5=8F=91=E5=95=86=E5=8A=A1=E6=A8=A1?= =?UTF-8?q?=E5=9D=97=E6=96=87=E4=BB=B6=E9=A2=84=E8=A7=88=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/bussiness/index.ts | 4 +- src/views/bussiness-data/bussiness.vue | 166 ++++++++++++++++++++++--- 2 files changed, 152 insertions(+), 18 deletions(-) diff --git a/src/apis/bussiness/index.ts b/src/apis/bussiness/index.ts index 71803d4..a28311e 100644 --- a/src/apis/bussiness/index.ts +++ b/src/apis/bussiness/index.ts @@ -156,10 +156,10 @@ export function deleteFileApi(fileId: string) { }) } -// 预览文件(后端没有提供预览接口,使用下载接口) +// 预览文件 export function previewFileApi(fileId: string) { return request({ - url: '/businessData/file/download', + url: '/businessData/file/preview', method: 'get', params: { fileId: fileId diff --git a/src/views/bussiness-data/bussiness.vue b/src/views/bussiness-data/bussiness.vue index e0e0fac..ec48882 100644 --- a/src/views/bussiness-data/bussiness.vue +++ b/src/views/bussiness-data/bussiness.vue @@ -1333,31 +1333,157 @@ const resetUpload = () => { // 预览文件 const handlePreview = async (file) => { try { + console.log('开始预览文件:', file); + Message.loading('正在加载预览...', 0); // 显示加载提示 + const blob = await previewFileApi(file.fileId); + Message.clear(); // 清除加载提示 + + if (!blob) { + Message.error('无法获取文件数据'); + return; + } + const url = URL.createObjectURL(blob); + const fileName = file.fileName || file.name; + const ext = getFileExtension(fileName).toLowerCase(); + + console.log('文件扩展名:', ext); // 根据文件类型决定预览方式 - const ext = getFileExtension(file.fileName || file.name).toLowerCase(); - if (['jpg', 'jpeg', 'png', 'gif', 'bmp'].includes(ext)) { - // 图片预览 - const img = new Image(); - img.src = url; - Modal.info({ - title: '图片预览', - content: img, - width: '80%' - }); + if (['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'].includes(ext)) { + // 图片预览 - 使用更好的图片预览组件 + showImagePreview(url, fileName); } else if (ext === 'pdf') { // PDF预览(在新窗口打开) window.open(url, '_blank'); + Message.success('PDF文件已在新窗口打开'); + } else if (['txt', 'md', 'json', 'xml', 'csv'].includes(ext)) { + // 文本文件预览 + showTextPreview(blob, fileName); + } else if (['doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx'].includes(ext)) { + // Office文档预览提示 + Modal.confirm({ + title: '文件预览', + content: `${fileName} 是Office文档格式,您可以选择:`, + okText: '下载查看', + cancelText: '取消', + onOk: () => { + handleDownload(file); + } + }); } else { - // 其他类型提示下载 - Message.info(`该文件类型不支持预览,将为您下载文件: ${file.fileName || file.name}`); - handleDownload(file); + // 其他类型询问是否下载 + Modal.confirm({ + title: '文件预览', + content: `文件类型 ${ext.toUpperCase()} 暂不支持在线预览,是否下载查看?`, + okText: '下载', + cancelText: '取消', + onOk: () => { + handleDownload(file); + } + }); } + + // 延迟释放URL,确保预览组件有足够时间加载 + setTimeout(() => { + URL.revokeObjectURL(url); + }, 10000); + } catch (error) { + Message.clear(); // 清除加载提示 console.error('预览失败:', error); - Message.error('预览文件失败'); + + // 更详细的错误处理 + if (error.response?.status === 404) { + Message.error('文件不存在或已被删除'); + } else if (error.response?.status === 403) { + Message.error('没有权限访问该文件'); + } else if (error.response?.status === 500) { + Message.error('服务器内部错误,请稍后重试'); + } else { + Message.error('预览文件失败,请检查网络连接'); + } + } +}; + +// 显示图片预览 +const showImagePreview = (url, fileName) => { + const container = document.createElement('div'); + container.style.cssText = ` + width: 100%; + height: 100%; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding: 20px; + box-sizing: border-box; + `; + + const img = document.createElement('img'); + img.src = url; + img.style.cssText = ` + max-width: 100%; + max-height: 70vh; + object-fit: contain; + border-radius: 8px; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); + `; + + const title = document.createElement('div'); + title.textContent = fileName; + title.style.cssText = ` + margin-top: 16px; + font-size: 14px; + color: #666; + text-align: center; + word-break: break-all; + `; + + container.appendChild(img); + container.appendChild(title); + + Modal.info({ + title: '图片预览', + content: container, + width: '80%', + maskClosable: true, + footer: null + }); +}; + +// 显示文本预览 +const showTextPreview = async (blob, fileName) => { + try { + const text = await blob.text(); + const container = document.createElement('div'); + container.style.cssText = ` + width: 100%; + height: 400px; + border: 1px solid #e5e5e5; + border-radius: 6px; + padding: 16px; + background-color: #fafafa; + font-family: 'Courier New', monospace; + font-size: 13px; + line-height: 1.6; + overflow: auto; + white-space: pre-wrap; + word-break: break-word; + `; + container.textContent = text; + + Modal.info({ + title: `文本预览 - ${fileName}`, + content: container, + width: '70%', + maskClosable: true, + footer: null + }); + } catch (error) { + console.error('文本预览失败:', error); + Message.error('无法读取文本内容'); } }; @@ -1771,6 +1897,8 @@ onMounted(() => { min-height: 300px; display: flex; flex-direction: column; + position: relative; + height: 100%; } /* 表格容器 */ @@ -1780,9 +1908,10 @@ onMounted(() => { margin-top: 16px; border-radius: 8px; border: 1px solid var(--color-border); - overflow: auto; + overflow-y: auto; background-color: var(--color-bg-1); box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05); + padding-bottom: 80px; /* 为分页留出空间 */ } /* 表头行样式 */ @@ -2553,7 +2682,12 @@ onMounted(() => { /* 文件分页样式 */ .file-pagination { - margin-top: 24px; + position: absolute; + bottom: 0; + left: 0; + right: 0; + z-index: 10; + margin-top: 0; padding: 16px 0; display: flex; justify-content: center;