From b00e12c9bb19343549e96b7ce0e6ecb1cf204ff3 Mon Sep 17 00:00:00 2001 From: "weicw1996@qq.com" Date: Tue, 6 Oct 2026 13:04:53 +0800 Subject: [PATCH] =?UTF-8?q?:sparkles:=20=E5=BC=82=E5=B8=B8=E4=B8=8A?= =?UTF-8?q?=E6=8A=A5=E5=BC=B9=E7=AA=97=E9=99=84=E4=BB=B6=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E5=9C=A8=E7=BA=BF=E9=A2=84=E8=A7=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/waybill-manage-page.vue | 6 +- src/views/transit/exception-disposal.vue | 117 +++++++++++++++++- 2 files changed, 119 insertions(+), 4 deletions(-) diff --git a/src/views/business/components/waybill-manage-page.vue b/src/views/business/components/waybill-manage-page.vue index 2f59e6c..c77d702 100644 --- a/src/views/business/components/waybill-manage-page.vue +++ b/src/views/business/components/waybill-manage-page.vue @@ -2726,8 +2726,7 @@ :key="index" type="primary" class="waybill-manage-page__exception-attachment-link" - :href="file.url" - target="_blank" + @click="previewWaybillExceptionAttachment(file, row)" > {{ file.name || '附件' + (index + 1) }} @@ -5578,6 +5577,9 @@ export default { return []; } }, + previewWaybillExceptionAttachment(file, row) { + this.previewAttachment(file, this.parseWaybillExceptionAttachments(row.attachmentsJson)); + }, async submitWaybillExceptionEdit() { await this.$refs.waybillExceptionEditFormRef.validate(); this.waybillExceptionDialog.submitting = true; diff --git a/src/views/transit/exception-disposal.vue b/src/views/transit/exception-disposal.vue index 8bc1154..d9ef5b2 100644 --- a/src/views/transit/exception-disposal.vue +++ b/src/views/transit/exception-disposal.vue @@ -399,8 +399,7 @@ :key="index" type="primary" class="exception-disposal-page__attachment-link" - :href="file.url" - target="_blank" + @click="previewAttachment(file, parseAttachments(row.attachmentsJson))" > {{ file.name || '附件' + (index + 1) }} @@ -440,6 +439,47 @@ 取消 + + + + + + + @@ -460,8 +500,36 @@ import { } from '@/option/transit/exception-disposal'; import { getUploadHeaders } from '@/utils/upload'; import * as api from '@/api/transit/exception-disposal'; +import PdfPreview from '@/components/pdf-preview/main.vue'; +import { ElImageViewer } from 'element-plus'; +import { OpenFileViewer } from '@open-file-viewer/vue'; +import { fallbackPlugin, imagePlugin, officePlugin, textPlugin } from '@open-file-viewer/core'; +import '@open-file-viewer/core/style.css'; +import pdfWorkerSrc from 'pdfjs-dist/build/pdf.worker.mjs?url'; + +const attachmentName = row => row?.originalName || row?.name || row?.fileName || '附件'; +const attachmentUrl = row => + row?.url || row?.link || row?.fileUrl || row?.downloadUrl || row?.domain || ''; +const attachmentExtension = row => { + const source = String(attachmentName(row) || attachmentUrl(row)).split('?')[0]; + const index = source.lastIndexOf('.'); + return index > -1 ? source.slice(index + 1).toLowerCase() : ''; +}; +const isAttachmentImage = row => + ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'].includes(attachmentExtension(row)); +const isAttachmentPdf = row => { + const mimeType = String(row.mimeType || row.contentType || '').toLowerCase(); + return mimeType.includes('application/pdf') || attachmentExtension(row) === 'pdf'; +}; +const attachmentViewerPlugins = [ + imagePlugin(), + officePlugin({ pdf: { workerSrc: pdfWorkerSrc, useFetchData: true } }), + textPlugin(), + fallbackPlugin(), +]; export default { + components: { ElImageViewer, OpenFileViewer, PdfPreview }, data() { return { Rank, @@ -501,6 +569,19 @@ export default { { max: 500, message: '上报说明不能超过500个字符', trigger: 'blur' }, ], }, + attachmentImagePreviewVisible: false, + attachmentImagePreviewUrls: [], + attachmentImagePreviewIndex: 0, + attachmentDocumentPreviewVisible: false, + attachmentPreviewFile: {}, + attachmentViewerPlugins, + attachmentViewerToolbar: { + download: true, + fullscreen: true, + print: true, + rotate: true, + zoom: true, + }, }; }, computed: { @@ -675,6 +756,38 @@ export default { return []; } }, + previewAttachment(row, rows = []) { + const url = attachmentUrl(row); + if (!url) { + this.$message.warning('附件地址为空,无法预览'); + return; + } + if (isAttachmentImage(row)) { + this.attachmentImagePreviewUrls = (rows || []) + .filter(item => isAttachmentImage(item) && attachmentUrl(item)) + .map(item => attachmentUrl(item)); + this.attachmentImagePreviewIndex = Math.max( + this.attachmentImagePreviewUrls.indexOf(url), + 0 + ); + this.attachmentImagePreviewVisible = true; + return; + } + const isPdf = isAttachmentPdf(row); + this.attachmentPreviewFile = { + name: attachmentName(row), + url, + mimeType: isPdf ? 'application/pdf' : row.mimeType || row.contentType || '', + isPdf, + }; + this.attachmentDocumentPreviewVisible = true; + }, + handleAttachmentPreviewUnsupported() { + this.$message.warning('当前文件暂不支持在线预览'); + }, + handleAttachmentPreviewError() { + this.$message.error('附件预览失败'); + }, async completeRow(row) { await this.$confirm('确认完成该异常处置?', '提示', { type: 'warning' }); await api.complete({ id: row.id });