From 69e4b0894600de4797f75e1189343d1a8ca52274 Mon Sep 17 00:00:00 2001 From: weizhong Date: Mon, 13 Oct 2025 14:40:33 +0800 Subject: [PATCH] =?UTF-8?q?=E2=80=9Crs=E6=A8=A1=E5=9D=97=E4=B8=8A=E4=BC=A0?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=E4=BF=AE=E6=94=B91013=E7=89=88=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/src/views/rs/overseas/approval.vue | 359 ++++++++++++++++++++++++- web/src/views/rs/overseas/index.vue | 274 +++++++++++++++++-- 2 files changed, 603 insertions(+), 30 deletions(-) diff --git a/web/src/views/rs/overseas/approval.vue b/web/src/views/rs/overseas/approval.vue index 051f5549..de1c03c5 100644 --- a/web/src/views/rs/overseas/approval.vue +++ b/web/src/views/rs/overseas/approval.vue @@ -289,6 +289,125 @@ {{ viewData.adminRemark }} + +
+ +
+
+ + 出国境登记表盖章文件 +
+
+
+ + + {{ viewData.stampedRegistrationFileName }} + + + 上传时间: {{ viewData.stampedFileUploadTime }} + +
+
+ + 查看 + + + 下载 + +
+
+
+ + +
+
+ + 党籍保留附件 +
+
+
+ + + {{ viewData.partyRetentionFileName }} + + + 上传时间: {{ viewData.partyRetentionUploadTime }} + +
+
+ + 查看 + + + 下载 + +
+
+
+ + +
+
+ + 其他申请附件 +
+ + + + + + + + + + + + + +
+ + + +
+

审批记录

@@ -408,19 +527,27 @@ import { approveOverseasApplication, exportOverseasApplication, exportOverseasApproval, + listOverseasAttachments, type OverseasApplicationQuery, type OverseasApplicationVO, type OverseasApprovalQuery, type OverseasApprovalVO, type ApprovalRequest, + type OverseasAttachmentVO, fixOverseasApprovalData } from '@/api/rs/overseas'; import { ElMessage, ElMessageBox } from 'element-plus'; +import { Document, Warning, Paperclip, View, Download } from '@element-plus/icons-vue'; import animate from '@/animate'; +import request from '@/utils/request'; +import { getToken } from '@/utils/auth'; // 响应式数据 const { proxy } = getCurrentInstance() as any; +// 附件列表数据 +const viewAttachmentList = ref([]); + const state = reactive({ // 选项卡相关 activeTab: 'pending', @@ -667,17 +794,25 @@ const resetRecordQuery = () => { // 查看申请详情 const handleViewApplication = async (row: OverseasApplicationVO) => { + console.log('📄 [查看详情] 开始查看申请详情,申请ID:', row.applicationId); try { const response = await getOverseasApplication(row.applicationId); state.viewData = response.data; + console.log('✅ [查看详情] 申请详情获取成功:', response.data); // 获取审批记录 const approvalResponse = await getOverseasApprovalByApplication(row.applicationId); state.applicationApprovalList = approvalResponse.data; + // 加载附件列表 + console.log('🔄 [查看详情] 开始加载附件列表...'); + await loadViewAttachmentList(row.applicationId); + console.log('✅ [查看详情] 附件列表加载完成'); + state.viewDialog.visible = true; } catch (error) { - console.error('获取申请详情失败:', error); + console.error('❌ [查看详情] 获取申请详情失败:', error); + ElMessage.error('获取申请详情失败'); } }; @@ -747,19 +882,26 @@ const handleExportRecord = async () => { // 查看审批记录详情 const handleViewRecord = async (row: OverseasApprovalVO) => { + console.log('📄 [查看记录详情] 开始查看审批记录详情,申请ID:', row.applicationId); try { // 通过申请ID获取申请详情 const response = await getOverseasApplication(row.applicationId); state.viewData = response.data; + console.log('✅ [查看记录详情] 申请详情获取成功'); // 获取完整的审批记录历史 const approvalResponse = await getOverseasApprovalByApplication(row.applicationId); state.applicationApprovalList = approvalResponse.data; + // 加载附件列表 + console.log('🔄 [查看记录详情] 开始加载附件列表...'); + await loadViewAttachmentList(row.applicationId); + console.log('✅ [查看记录详情] 附件列表加载完成'); + // 显示查看对话框 state.viewDialog.visible = true; } catch (error: any) { - console.error('获取审批记录详情失败:', error); + console.error('❌ [查看记录详情] 获取审批记录详情失败:', error); proxy.$modal.msgError('获取详情失败: ' + (error?.message || String(error))); } }; @@ -851,6 +993,219 @@ const getApprovalStatusTagType = (status: string): 'success' | 'warning' | 'dang }; return typeMap[status] || 'info'; }; + +// ============== 附件相关方法 ============== + +// 加载附件列表 +const loadViewAttachmentList = async (applicationId: number | string) => { + console.log('🔍 [附件加载] 开始加载附件列表,applicationId:', applicationId); + try { + const response = await listOverseasAttachments(applicationId); + console.log('✅ [附件加载] API响应成功:', response); + + viewAttachmentList.value = response.data || []; + + if (!response.data || response.data.length === 0) { + console.warn('⚠️ [附件加载] 该申请暂无附件数据'); + } else { + console.log('✨ [附件加载] 附件列表:', viewAttachmentList.value); + } + } catch (error: any) { + console.error('❌ [附件加载] 加载附件列表失败:', error); + viewAttachmentList.value = []; + } +}; + +// 下载附件(从详情页) +const handleDownloadAttachment = (row: OverseasAttachmentVO) => { + console.log('📥 下载附件:', row.fileOriginalName); + // 直接通过链接下载 + const link = document.createElement('a'); + link.href = row.filePath; + link.download = row.fileOriginalName; + link.target = '_blank'; + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); +}; + +// 下载出国境登记表盖章文件 +const handleDownloadStampedFile = async (data: OverseasApplicationVO) => { + console.log('📥 下载出国境登记表盖章文件:', data.stampedRegistrationFileName); + + if (!data.stampedFileOssId) { + ElMessage.warning('文件OSS ID不存在,无法下载'); + return; + } + + try { + // 使用request下载文件 + const response = await request({ + url: `/resource/oss/download/${data.stampedFileOssId}`, + method: 'get', + responseType: 'blob' + }); + + // 创建带MIME类型的Blob并触发下载 + const blob = response instanceof Blob + ? new Blob([response], { type: 'application/pdf' }) + : new Blob([response.data], { type: 'application/pdf' }); + const url = window.URL.createObjectURL(blob); + + const link = document.createElement('a'); + link.href = url; + link.download = data.stampedRegistrationFileName || '出国境登记表盖章文件.pdf'; + + document.body.appendChild(link); + link.click(); + + // 清理资源 + document.body.removeChild(link); + window.URL.revokeObjectURL(url); + + ElMessage.success('文件下载成功'); + } catch (error) { + console.error('下载出国境登记表盖章文件失败:', error); + ElMessage.error('下载文件失败,请检查文件权限或稍后重试'); + } +}; + +// 下载党籍保留附件 +const handleDownloadPartyRetentionFile = async (data: OverseasApplicationVO) => { + console.log('📥 下载党籍保留附件:', data.partyRetentionFileName); + + if (!data.partyRetentionFileOssId) { + ElMessage.warning('文件OSS ID不存在,无法下载'); + return; + } + + try { + // 使用request下载文件 + const response = await request({ + url: `/resource/oss/download/${data.partyRetentionFileOssId}`, + method: 'get', + responseType: 'blob' + }); + + // 创建带MIME类型的Blob并触发下载 + const blob = response instanceof Blob + ? new Blob([response], { type: 'application/pdf' }) + : new Blob([response.data], { type: 'application/pdf' }); + const url = window.URL.createObjectURL(blob); + + const link = document.createElement('a'); + link.href = url; + link.download = data.partyRetentionFileName || '党籍保留附件.pdf'; + + document.body.appendChild(link); + link.click(); + + // 清理资源 + document.body.removeChild(link); + window.URL.revokeObjectURL(url); + + ElMessage.success('文件下载成功'); + } catch (error) { + console.error('下载党籍保留附件失败:', error); + ElMessage.error('下载文件失败,请检查文件权限或稍后重试'); + } +}; + +// 预览党籍保留附件 +const handlePreviewPartyRetentionFile = async (data: OverseasApplicationVO) => { + console.log('👁️ 预览党籍保留附件:', data.partyRetentionFileName); + + if (!data.partyRetentionFileOssId) { + ElMessage.warning('文件OSS ID不存在,无法预览'); + return; + } + + try { + // 获取文件扩展名 + const fileName = data.partyRetentionFileName || ''; + const fileExt = fileName.substring(fileName.lastIndexOf('.') + 1).toLowerCase(); + + // 使用request获取文件blob + const response = await request({ + url: `/resource/oss/download/${data.partyRetentionFileOssId}`, + method: 'get', + responseType: 'blob' + }); + + // 创建带MIME类型的Blob(关键:指定type为application/pdf才能正常预览) + const blob = response instanceof Blob + ? new Blob([response], { type: 'application/pdf' }) + : new Blob([response.data], { type: 'application/pdf' }); + const fileUrl = window.URL.createObjectURL(blob); + + // 根据文件类型进行预览 + if (fileExt === 'pdf') { + // PDF直接在新标签页打开 + window.open(fileUrl, '_blank'); + + // 60秒后清理URL + setTimeout(() => { + window.URL.revokeObjectURL(fileUrl); + }, 60000); + } + // 其他文件类型提示下载 + else { + ElMessage.info('该文件类型不支持在线预览,请下载后查看'); + await handleDownloadPartyRetentionFile(data); + } + } catch (error) { + console.error('预览党籍保留附件失败:', error); + ElMessage.error('预览文件失败,请检查文件权限或稍后重试'); + } +}; + +// 预览出国境登记表盖章文件 +const handlePreviewStampedFile = async (data: OverseasApplicationVO) => { + console.log('👁️ 预览出国境登记表盖章文件:', data.stampedRegistrationFileName); + + if (!data.stampedFileOssId) { + ElMessage.warning('文件OSS ID不存在,无法预览'); + return; + } + + try { + // 获取文件扩展名 + const fileName = data.stampedRegistrationFileName || ''; + const fileExt = fileName.substring(fileName.lastIndexOf('.') + 1).toLowerCase(); + + // 使用request获取文件blob + const response = await request({ + url: `/resource/oss/download/${data.stampedFileOssId}`, + method: 'get', + responseType: 'blob' + }); + + // 创建带MIME类型的Blob(关键:指定type为application/pdf才能正常预览) + const blob = response instanceof Blob + ? new Blob([response], { type: 'application/pdf' }) + : new Blob([response.data], { type: 'application/pdf' }); + const fileUrl = window.URL.createObjectURL(blob); + + // 根据文件类型进行预览 + if (fileExt === 'pdf') { + // PDF直接在新标签页打开 + window.open(fileUrl, '_blank'); + + // 60秒后清理URL + setTimeout(() => { + window.URL.revokeObjectURL(fileUrl); + }, 60000); + } + // 其他文件类型提示下载 + else { + ElMessage.info('该文件类型不支持在线预览,请下载后查看'); + await handleDownloadStampedFile(data); + } + } catch (error) { + console.error('预览出国境登记表盖章文件失败:', error); + ElMessage.error('预览文件失败,请检查文件权限或稍后重试'); + } +}; + + + ${fileName} + + + `); + previewWindow.document.close(); + } + } + // PDF类型在新窗口预览 + else if (fileExt === 'pdf') { + // 获取PDF文件 + const response = await request({ + url: `/resource/oss/download/${data.partyRetentionFileOssId}`, + method: 'get', + responseType: 'blob' + }); + + // 正确处理Blob创建,确保包含正确的MIME类型 + const blob = response instanceof Blob + ? new Blob([response], { type: 'application/pdf' }) + : new Blob([response.data], { type: 'application/pdf' }); + + console.log('📄 [PDF预览] 党籍附件Blob创建成功:', { + size: blob.size, + type: blob.type, + fileName: fileName + }); + + const blobUrl = window.URL.createObjectURL(blob); + + // 在新窗口打开PDF + window.open(blobUrl, '_blank'); + + // 延迟清理,确保新窗口已加载 + setTimeout(() => { + window.URL.revokeObjectURL(blobUrl); + }, 60000); // 60秒后清理 + } + // 其他文件类型提示下载 + else { + ElMessage.info('该文件类型不支持在线预览,请下载后查看'); + await handleDownloadPartyRetentionFile(data); + } + } catch (error) { + console.error('预览党籍保留附件失败:', error); + ElMessage.error('预览文件失败,请检查文件权限或稍后重试'); + } +}; + +// 预览出国境登记表盖章文件 +const handlePreviewStampedFile = async (data: OverseasApplicationVO) => { + console.log('👁️ 预览出国境登记表盖章文件:', data.stampedRegistrationFileName); + + if (!data.stampedFileOssId) { + ElMessage.warning('文件OSS ID不存在,无法预览'); + return; + } + + try { + // 判断文件类型 + const fileName = data.stampedRegistrationFileName || ''; + const fileExt = fileName.split('.').pop()?.toLowerCase(); + + // 图片类型直接在新窗口预览 + if (['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'].includes(fileExt || '')) { + // 使用OSS下载接口获取图片 + const imageUrl = `/resource/oss/download/${data.stampedFileOssId}`; + + // 获取blob URL用于预览 + const response = await request({ + url: imageUrl, + method: 'get', + responseType: 'blob' + }); + + const blob = response instanceof Blob + ? new Blob([response], { type: response.type || 'image/jpeg' }) + : new Blob([response.data], { type: response.data.type || 'image/jpeg' }); + const blobUrl = window.URL.createObjectURL(blob); + + // 在新窗口打开图片 + const previewWindow = window.open('', '_blank'); + if (previewWindow) { + previewWindow.document.write(` + + + + ${fileName} + + + + ${fileName} + + + `); + previewWindow.document.close(); + } + } + // PDF类型在新窗口预览 + else if (fileExt === 'pdf') { + // 获取PDF文件 + const response = await request({ + url: `/resource/oss/download/${data.stampedFileOssId}`, + method: 'get', + responseType: 'blob' + }); + + // 正确处理Blob创建,确保包含正确的MIME类型 + const blob = response instanceof Blob + ? new Blob([response], { type: 'application/pdf' }) + : new Blob([response.data], { type: 'application/pdf' }); + + console.log('📄 [PDF预览] 盖章文件Blob创建成功:', { + size: blob.size, + type: blob.type, + fileName: fileName + }); + + const blobUrl = window.URL.createObjectURL(blob); + + // 在新窗口打开PDF + window.open(blobUrl, '_blank'); + + // 延迟清理,确保新窗口已加载 + setTimeout(() => { + window.URL.revokeObjectURL(blobUrl); + }, 60000); // 60秒后清理 + } + // 其他文件类型提示下载 + else { + ElMessage.info('该文件类型不支持在线预览,请下载后查看'); + await handleDownloadStampedFile(data); + } + } catch (error) { + console.error('预览出国境登记表盖章文件失败:', error); + ElMessage.error('预览文件失败,请检查文件权限或稍后重试'); + } +};