From 75a462f8ee30491f05d29ccac1b65d31e835957b Mon Sep 17 00:00:00 2001 From: spring <2396852758@qq.com> Date: 星期三, 20 八月 2025 15:57:14 +0800 Subject: [PATCH] 档案管理调整 --- src/views/fileManagement/document/attachmentManager.vue | 426 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 426 insertions(+), 0 deletions(-) diff --git a/src/views/fileManagement/document/attachmentManager.vue b/src/views/fileManagement/document/attachmentManager.vue new file mode 100644 index 0000000..a4e1d43 --- /dev/null +++ b/src/views/fileManagement/document/attachmentManager.vue @@ -0,0 +1,426 @@ +<template> + <el-dialog v-model="dialogVisible" title="闄勪欢绠$悊" width="60%" :before-close="handleClose"> + <div class="attachment-manager"> + <!-- 涓婁紶鍖哄煙 --> + <div class="upload-section"> + <el-upload + ref="uploadRef" + :action="uploadUrl" + :headers="uploadHeaders" + :before-upload="handleBeforeUpload" + :on-success="handleUploadSuccess" + :on-error="handleUploadError" + :on-remove="handleRemove" + :file-list="fileList" + multiple + :limit="10" + :show-file-list="false" + :data="{documentId: currentDocumentId}" + accept=".doc,.docx,.xls,.xlsx,.ppt,.pptx,.pdf,.txt,.xml,.jpg,.jpeg,.png,.gif,.bmp,.rar,.zip,.7z" + > + <el-button type="primary" :icon="Plus">涓婁紶闄勪欢</el-button> + <template #tip> + <div class="el-upload__tip"> + 鏀寔鏍煎紡锛歞oc锛宒ocx锛寈ls锛寈lsx锛宲pt锛宲ptx锛宲df锛宼xt锛寈ml锛宩pg锛宩peg锛宲ng锛実if锛宐mp锛宺ar锛寊ip锛�7z + <br>鍗曚釜鏂囦欢澶у皬涓嶈秴杩�50MB + </div> + </template> + </el-upload> + </div> + + <!-- 闄勪欢鍒楄〃 --> + <div class="attachment-list"> + <el-table :data="fileList" border height="400px" v-loading="loading"> + <el-table-column label="搴忓彿" type="index" width="60" align="center" /> + <el-table-column label="闄勪欢鍚嶇О" prop="name" min-width="200" show-overflow-tooltip /> + <el-table-column label="鏂囦欢澶у皬" prop="size" width="100" align="center"> + <template #default="scope"> + {{ formatFileSize(scope.row.size) }} + </template> + </el-table-column> + <el-table-column label="涓婁紶鏃堕棿" prop="uploadTime" width="160" align="center"> + <template #default="scope"> + {{ formatDate(scope.row.uploadTime) }} + </template> + </el-table-column> + <el-table-column label="鐘舵��" prop="status" width="80" align="center"> + <template #default="scope"> + <el-tag :type="scope.row.status === 'success' ? 'success' : 'danger'" size="small"> + {{ scope.row.status === 'success' ? '鎴愬姛' : '澶辫触' }} + </el-tag> + </template> + </el-table-column> + <el-table-column fixed="right" label="鎿嶄綔" width="200" align="center"> + <template #default="scope"> + <el-button link type="primary" size="small" @click="previewFile(scope.row)"> + 棰勮 + </el-button> + <el-button link type="primary" size="small" @click="downloadFile(scope.row)"> + 涓嬭浇 + </el-button> + <el-button link type="danger" size="small" @click="removeFile(scope.row)"> + 鍒犻櫎 + </el-button> + </template> + </el-table-column> + </el-table> + </div> + </div> + + <!-- 鏂囦欢棰勮缁勪欢 --> + <filePreview ref="filePreviewRef" /> + </el-dialog> +</template> + +<script setup> +import { ref, reactive, computed } from 'vue' +import { ElMessage, ElMessageBox } from 'element-plus' +import { Plus } from '@element-plus/icons-vue' +import { getToken } from "@/utils/auth" +import { addDocumentationFile, getDocumentationFileList, deleteDocumentationFile } from '@/api/fileManagement/document' +import filePreview from '@/components/filePreview/index.vue' + +const props = defineProps({ + // documentId 閫氳繃 open 浜嬩欢浼犲叆锛屼笉闇�瑕佷綔涓� props +}) + +const emit = defineEmits(['update:attachments']) + +const dialogVisible = ref(false) +const loading = ref(false) +const fileList = ref([]) +const uploadRef = ref() +const filePreviewRef = ref() +const currentDocumentId = ref('') // 鍐呴儴绠$悊褰撳墠鏂囨。ID + +// 涓婁紶閰嶇疆 +const uploadUrl = import.meta.env.VITE_APP_BASE_API + "/file/upload" +const uploadHeaders = computed(() => ({ + Authorization: "Bearer " + getToken() +})) + +// 鎵撳紑寮规 +const open = (attachments = [], documentId = '') => { + dialogVisible.value = true + currentDocumentId.value = documentId // 璁剧疆褰撳墠鏂囨。ID + // 濡傛灉鏈夋枃妗D锛屽垯鍔犺浇闄勪欢鍒楄〃 + if (documentId) { + loadAttachmentList(documentId) + } else { + fileList.value = attachments || [] + // total.value = fileList.value.length // Removed total.value + } + // currentPage.value = 1 // Removed currentPage.value +} + +// 鍔犺浇闄勪欢鍒楄〃 +const loadAttachmentList = async (documentId) => { + try { + loading.value = true + const params = { + page: 1, // Always load from page 1 + size: 1000, // Load all for now + documentationId: documentId + } + + const res = await getDocumentationFileList(params) + if (res.code === 200) { + const records = res.data + + // 杞崲鏁版嵁鏍煎紡 + fileList.value = records.map(item => ({ + id: item.id, + name: item.name, + size: item.fileSize, + url: item.url, + uploadTime: item.createTime || item.uploadTime, + status: 'success', + uid: item.id + })) + + // total.value = totalCount // Removed total.value + } else { + ElMessage.error(res.msg || '鑾峰彇闄勪欢鍒楄〃澶辫触') + fileList.value = [] + // total.value = 0 // Removed total.value + } + } catch (error) { + console.error('鑾峰彇闄勪欢鍒楄〃澶辫触:', error) + ElMessage.error('鑾峰彇闄勪欢鍒楄〃澶辫触') + fileList.value = [] + // total.value = 0 // Removed total.value + } finally { + loading.value = false + } +} + +// 鍏抽棴寮规 +const handleClose = () => { + dialogVisible.value = false + emit('update:attachments', fileList.value) +} + +// 鏂囦欢涓婁紶鍓嶆牎楠� +const handleBeforeUpload = (file) => { + // 妫�鏌ユ枃浠跺ぇ灏忥紙50MB锛� + const isLt50M = file.size / 1024 / 1024 < 50 + if (!isLt50M) { + ElMessage.error('鏂囦欢澶у皬涓嶈兘瓒呰繃50MB!') + return false + } + + // 妫�鏌ユ枃浠剁被鍨� + const allowedTypes = [ + 'application/msword', + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'application/vnd.ms-excel', + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + 'application/vnd.ms-powerpoint', + 'application/vnd.openxmlformats-officedocument.presentationml.presentation', + 'application/pdf', + 'text/plain', + 'text/xml', + 'image/jpeg', + 'image/png', + 'image/gif', + 'image/bmp', + 'application/x-rar-compressed', + 'application/zip', + 'application/x-7z-compressed' + ] + + if (!allowedTypes.includes(file.type)) { + ElMessage.error('涓嶆敮鎸佺殑鏂囦欢绫诲瀷!') + return false + } + + return true +} + +// 鏂囦欢涓婁紶鎴愬姛 +const handleUploadSuccess = (response, file, fileList) => { + console.log('鏂囦欢涓婁紶鎴愬姛鍝嶅簲:', response); + console.log('鏂囦欢淇℃伅:', file); + + if (response.code === 200) { + // 鏋勫缓闄勪欢鏁版嵁 - 纭繚姝g‘鑾峰彇URL + const attachmentData = { + name: file.name, + url: response.data.url || response.data.path || response.data.tempPath || file.url, + fileSize: file.size, + documentationId: currentDocumentId.value + }; + + console.log('鏋勫缓鐨勯檮浠舵暟鎹�:', attachmentData); + + // 璋冪敤淇濆瓨闄勪欢鎺ュ彛 + saveAttachment(attachmentData, file, fileList); + } else { + ElMessage.error(response.msg || '鏂囦欢涓婁紶澶辫触') + } +} + +// 淇濆瓨闄勪欢淇℃伅 +const saveAttachment = async (attachmentData, file, fileList) => { + try { + console.log('寮�濮嬩繚瀛橀檮浠讹紝鏁版嵁:', attachmentData); + + // 纭繚URL瀛楁瀛樺湪涓旀湁鏁� + if (!attachmentData.url) { + console.error('闄勪欢URL涓虹┖锛屾棤娉曚繚瀛�'); + ElMessage.error('鏂囦欢URL鑾峰彇澶辫触锛屾棤娉曚繚瀛橀檮浠�'); + return; + } + + const res = await addDocumentationFile(attachmentData); + console.log('淇濆瓨闄勪欢鎺ュ彛鍝嶅簲:', res); + + if (res.code === 200) { + const newFile = { + id: res.data.id || Date.now(), + name: attachmentData.name, + size: attachmentData.fileSize, + url: attachmentData.url, + uploadTime: new Date().toISOString(), + status: 'success', + uid: file.uid + } + + console.log('鍒涘缓鐨勬柊鏂囦欢瀵硅薄:', newFile); + fileList.push(newFile) + ElMessage.success('鏂囦欢涓婁紶骞朵繚瀛樻垚鍔�') + + // 淇濆瓨鎴愬姛鍚庡埛鏂伴檮浠跺垪琛� + if (currentDocumentId.value) { + await loadAttachmentList(currentDocumentId.value); + } + } else { + ElMessage.error(res.msg || '淇濆瓨闄勪欢淇℃伅澶辫触') + // 淇濆瓨澶辫触鏃剁Щ闄ゆ枃浠� + const index = fileList.findIndex(item => item.uid === file.uid) + if (index > -1) { + fileList.splice(index, 1) + } + } + } catch (error) { + console.error('淇濆瓨闄勪欢澶辫触:', error) + ElMessage.error('淇濆瓨闄勪欢淇℃伅澶辫触') + // 淇濆瓨澶辫触鏃剁Щ闄ゆ枃浠� + const index = fileList.findIndex(item => item.uid === file.uid) + if (index > -1) { + fileList.splice(index, 1) + } + } +} + +// 鏂囦欢涓婁紶澶辫触 +const handleUploadError = (error, file, fileList) => { + console.error('鏂囦欢涓婁紶澶辫触:', error); + console.error('澶辫触鐨勬枃浠�:', file); + console.error('褰撳墠鏂囦欢鍒楄〃:', fileList); + + ElMessage.error('鏂囦欢涓婁紶澶辫触锛岃妫�鏌ョ綉缁滆繛鎺ユ垨鏂囦欢鏍煎紡') +} + +// 绉婚櫎鏂囦欢 +const handleRemove = (file, fileList) => { + const index = fileList.findIndex(item => item.uid === file.uid) + if (index > -1) { + fileList.splice(index, 1) + // total.value = fileList.length // Removed total.value + } +} + +// 鍒犻櫎鏂囦欢 +const removeFile = (file) => { + ElMessageBox.confirm(`纭畾瑕佸垹闄ゆ枃浠� "${file.name}" 鍚楋紵`, '鍒犻櫎纭', { + confirmButtonText: '纭畾', + cancelButtonText: '鍙栨秷', + type: 'warning' + }).then(async () => { + try { + // 璋冪敤鍒犻櫎鎺ュ彛 + const res = await deleteDocumentationFile([file.id]); + if (res.code === 200) { + // 浠庢湰鍦板垪琛ㄤ腑绉婚櫎 + const index = fileList.value.findIndex(item => item.id === file.id); + if (index > -1) { + fileList.value.splice(index, 1); + } + ElMessage.success('鍒犻櫎鎴愬姛'); + + // 濡傛灉鏈夋枃妗D锛屽埛鏂伴檮浠跺垪琛� + if (currentDocumentId.value) { + await loadAttachmentList(currentDocumentId.value); + } + } else { + ElMessage.error(res.msg || '鍒犻櫎澶辫触'); + } + } catch (error) { + console.error('鍒犻櫎闄勪欢澶辫触:', error); + ElMessage.error('鍒犻櫎闄勪欢澶辫触'); + } + }).catch(() => { + // 鍙栨秷鍒犻櫎 + }) +} + +// 棰勮鏂囦欢 +const previewFile = (file) => { + if (file.url) { + filePreviewRef.value.open(file.url) + } else { + ElMessage.warning('鏂囦欢鍦板潃鏃犳晥锛屾棤娉曢瑙�') + } +} + +// 涓嬭浇鏂囦欢 +const downloadFile = (file) => { + if (file.url) { + // 鍒涘缓涓嬭浇閾炬帴 + const link = document.createElement('a') + link.href = file.url + link.download = file.name + document.body.appendChild(link) + link.click() + document.body.removeChild(link) + ElMessage.success('寮�濮嬩笅杞芥枃浠�') + } else { + ElMessage.warning('鏂囦欢鍦板潃鏃犳晥锛屾棤娉曚笅杞�') + } +} + +// 鏍煎紡鍖栨枃浠跺ぇ灏� +const formatFileSize = (bytes) => { + if (bytes === 0) return '0 B' + const k = 1024 + const sizes = ['B', 'KB', 'MB', 'GB'] + const i = Math.floor(Math.log(bytes) / Math.log(k)) + return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i] +} + +// 鏍煎紡鍖栨棩鏈� +const formatDate = (dateString) => { + if (!dateString) return '' + const date = new Date(dateString) + return date.toLocaleString('zh-CN', { + year: 'numeric', + month: '2-digit', + day: '2-digit', + hour: '2-digit', + minute: '2-digit' + }) +} + +// 娴嬭瘯鏂囦欢涓婁紶 +const testUpload = () => { + console.log('褰撳墠鏂囨。ID:', currentDocumentId.value); + console.log('涓婁紶URL:', uploadUrl); + console.log('涓婁紶Headers:', uploadHeaders.value); +} + +// 鏆撮湶鏂规硶 +defineExpose({ + open, + loadAttachmentList, + testUpload +}) +</script> + +<style scoped> +.attachment-manager { + padding: 20px; +} + +.upload-section { + margin-bottom: 20px; + padding: 20px; + background-color: #f8f9fa; + border-radius: 8px; + border: 2px dashed #d9d9d9; +} + +.upload-section:hover { + border-color: #409eff; +} + +.attachment-list { + margin-bottom: 20px; +} + +.el-upload__tip { + margin-top: 10px; + color: #666; + font-size: 12px; + line-height: 1.5; +} + +:deep(.el-upload) { + width: 100%; +} + +:deep(.el-upload-dragger) { + width: 100%; + height: 120px; +} +</style> -- Gitblit v1.9.3