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