瀏覽代碼

feat(data-fill): 优化附件上传组件功能
- 添加未上传文件缓存,支持类型切换时恢复未上传文件

duy 1 月之前
父節點
當前提交
5cd0f7cf5d
共有 2 個文件被更改,包括 229 次插入227 次删除
  1. 222 227
      src/views/data-fill/components/HcUpload.vue
  2. 7 0
      src/views/data-fill/wbs.vue

+ 222 - 227
src/views/data-fill/components/HcUpload.vue

@@ -59,12 +59,13 @@
 </template>
 
 <script setup>
-import { nextTick, onMounted, ref, watch } from 'vue'
+import { nextTick, onBeforeUpdate, onMounted, ref, watch } from 'vue'
 import { getHeader } from 'hc-vue3-ui'
 import wbsApi from '~api/data-fill/wbs'
 import { isFileSize } from 'js-fast-way'
 import { toPdfPage } from '~uti/btn-auth'
 import draggable from 'vuedraggable'
+
 const props = defineProps({
     fileList: {
         type: Array,
@@ -102,11 +103,10 @@ const props = defineProps({
         type:Boolean,
         default:false,
     }, //是否列表文件
-
 })
 
 //事件
-const emit = defineEmits(['change', 'close'])
+const emit = defineEmits(['change', 'close', 'update'])
 //变量
 const uploadData = ref(props.datas)
 const fileListData = ref(props.fileList)
@@ -119,8 +119,10 @@ const autoUpload = ref(props.autoUpload)
 const typevalue = ref(props.typevalue)
 const isListFile = ref(props.isListFile)
 
+// 按类型存储未上传的文件
+const unUploadedFiles = ref({})
 
-//监听
+//监听props变化
 watch(() => [
     props.fileList,
     props.datas,
@@ -131,7 +133,6 @@ watch(() => [
     props.autoUpload,
     props.typevalue,
     props.isListFile,
-
 ], ([fileList, datas, isCanupload, Action, Accept, Tip, auto, type, list]) => {
     uploadData.value = datas
     fileListData.value = fileList
@@ -143,33 +144,26 @@ watch(() => [
     typevalue.value = type
     isListFile.value = list
 })
-watch(() => [
-    props.typevalue,
-    props.autoUpload,
-], ([ type, auto]) => {
-    typevalue.value = type
-    autoUpload.value = auto
-},
-{ immediate: true },
-)
-watch(() => [
-    props.typevalue,
-  
-], ([ type]) => {
-    typevalue.value = type
+
+// 类型变化监听
+watch(() => props.typevalue, async (newType, oldType) => {
+    await nextTick()
   
-      if (typevalue.value) {
-          emit('change', { type: 'success' })
-      }
-
-},
-{ immediate: true },
-)
-// 在watch中添加对fileList的深度监听
+    // 保留所有已上传文件(已删除的会被父组件同步移除)
+    const uploadedFiles = fileListData.value.filter(file => 
+        file.id || file.status === 'success',
+    )
+    
+    // 恢复新类型对应的未上传文件
+    const newTypeUnUploaded = unUploadedFiles.value[newType] || []
+    fileListData.value = [...uploadedFiles, ...newTypeUnUploaded]
+}, { immediate: true })
+
+// 深度监听fileList变化
 watch(() => props.fileList, (newVal) => {
-  fileListData.value = [...newVal] // 使用新数组保证响应性
+  fileListData.value = [...newVal]
 }, { deep: true, immediate: true })
-//渲染完成
+
 onMounted(() => {
     beforeFileNum.value = 0
     finishFileNum.value = 0
@@ -179,93 +173,89 @@ onMounted(() => {
 //上传前
 const beforeFileNum = ref(0)
 const beforeUpload = async (file) => {
-  console.log(file, 'file上传前')
-  
-    
     if (isFileSize(file?.size, 60)) {
         beforeFileNum.value++
-        // 获取当前文件的索引
         const fileIndex = fileListData.value.findIndex(f => f.raw === file.raw)
-        
-        // 设置uploadData中的sort参数
         uploadData.value.sort = fileIndex + 1
         return true
     } else {
-        window?.$message?.warning('文件大小, 不能过60M!')
-      
-        console.log(fileListData.value, 'fileListData.value')
-        
+        window?.$message?.warning('文件大小不能超过60M!')
         return false
     }
 }
 
-
 //超出限制时
 const uploadExceed = () => {
     window?.$message?.warning('请上传 jpg/png/pdf/excel/word 的文件,文件大小 不超过60M')
 }
-const q = 1 // 假设q是固定偏移量,可以根据需要调整
-// 新增的处理方法
+const q = 1 
+
 // 文件变化处理
 const handleFileChange = async (file, fileList) => {
     if (!isFileSize(file?.size, 60)) {
-        window?.$message?.warning('文件大小, 不能过60M!')
+        window?.$message?.warning('文件大小不能过60M!')
         return
     }
-      fileListData.value = fileList.map((item, index) => ({
+    
+    const processedList = fileList.map((item, index) => ({
         ...item,
-        sort: index + q, // 为每个文件添加sort字段
-        url:'',
-      }))
-
-    fileListData.value = fileList.filter(file => {
-      // 检查 size 属性是否存在且等于 60M,或者 size 属性不存在
-      return (file.size !== undefined && isFileSize(file?.size, 60)) || file.size === undefined
-    })
-  
-
-      
+        sort: index + q,
+        url: '',
+    })).filter(file => 
+        (file.size !== undefined && isFileSize(file.size, 60)) || file.size === undefined,
+    )
+    
+    fileListData.value = [...processedList]
+    
+    if (typevalue.value) {
+        const currentUnUploaded = fileListData.value.filter(file => 
+            !file.id && !['success', 'uploading'].includes(file.status),
+        )
+        unUploadedFiles.value[typevalue.value] = [...currentUnUploaded]
+    } else {
+        window?.$message?.warning('请先选择附件类型再添加文件')
+    }
 }
+
 //上传文件前预览pdf
 const pdfLoading = ref(false)
 const getPdfUrl = async (arr) => {
-      // 创建 FormData 对象
-      const formData = new FormData()
-    //   // 1. 添加多个文件(后端接收的是 files[] 数组)
-      arr.forEach((file) => {
-      if (file.raw !== undefined) {
-          formData.append('file', file.raw) // 确保 file.raw 是 File 对象
+    const formData = new FormData()
+    arr.forEach((file) => {
+        if (file.raw !== undefined) {
+            formData.append('file', file.raw)
         }
-      })
-      pdfLoading.value = true
-
-      const { error, code, msg, data } = await wbsApi.previewBussfile(formData) // 修改这里
-           pdfLoading.value = false
-              if (!error && code === 200) {
-                console.log(data, 'data')
-                return data
-
-                
-               } else {
-                window?.$message?.error(msg || '操作失败')
-
-              }
+    })
+    pdfLoading.value = true
 
+    const { error, code, msg, data } = await wbsApi.previewBussfile(formData)
+    pdfLoading.value = false
+    if (!error && code === 200) {
+        return data
+    } else {
+        window?.$message?.error(msg || '操作失败')
+    }
 }
+
 // 拖拽结束事件
 const onDragEnd = () => {
-  // 更新排序号
-  fileListData.value = fileListData.value.map((file, index) => ({
-    ...file,
-    sort: index + q,
-  }))
+    fileListData.value = fileListData.value.map((file, index) => ({
+        ...file,
+        sort: index + q,
+    }))
 }
+
 // 手动删除文件
 const handleRemove = (file) => {
-  console.log('手动删除文件', file)
-  
-      delUploadData(file)
+    if (typevalue.value && unUploadedFiles.value[typevalue.value]) {
+        const index = unUploadedFiles.value[typevalue.value].findIndex(f => f.uid === file.uid)
+        if (index !== -1) {
+            unUploadedFiles.value[typevalue.value].splice(index, 1)
+        }
+    }
+    delUploadData(file)
 }
+
 //上传中
 const loadingText = ref('上传中...')
 const uploadprogress = () => {
@@ -275,19 +265,38 @@ const uploadprogress = () => {
 
 //上传完成
 const finishFileNum = ref(0)
-const uploadSuccess = () => {
+const uploadSuccess = (response, file) => {
     finishFileNum.value++
+    
+    if (typevalue.value && unUploadedFiles.value[typevalue.value]) {
+        const index = unUploadedFiles.value[typevalue.value].findIndex(f => f.uid === file.uid)
+        if (index !== -1) {
+            unUploadedFiles.value[typevalue.value].splice(index, 1)
+        }
+    }
+    
     if (beforeFileNum.value === finishFileNum.value) {
         uploadDisabled.value = false
         emit('change', { type: 'success' })
+        emit('update', [...fileListData.value]) // 同步更新父组件文件列表
     }
 }
 
 //上传失败
 const errorFileNum = ref(0)
-const uploadError = () => {
+const uploadError = (error, file) => {
     errorFileNum.value++
     window?.$message?.error('上传失败')
+    
+    if (typevalue.value) {
+        if (!unUploadedFiles.value[typevalue.value]) {
+            unUploadedFiles.value[typevalue.value] = []
+        }
+        if (!unUploadedFiles.value[typevalue.value].some(f => f.uid === file.uid)) {
+            unUploadedFiles.value[typevalue.value].push(file)
+        }
+    }
+    
     const num = finishFileNum.value + errorFileNum.value
     if (beforeFileNum.value === num) {
         uploadDisabled.value = false
@@ -299,62 +308,64 @@ const uploadError = () => {
 const uploadPreview = ({ url }) => {
     emit('close')
     toPdfPage(url)
-    /*if (url) {
-        window.open(url, '_blank')
-    }*/
 }
+
 const previewUrl = async (item)=>{
     const pdfUrLArray = await getPdfUrl([item])
-
     item.url = pdfUrLArray[0]?.url || ''
     if (item.url) {
         toPdfPage(item.url)
     }
 }
+
 const uploadRef = ref(null)
 
-// 删除文件
+// 删除文件 - 核心修改:删除后同步更新父组件fileList
 const delUploadData = async (file) => {
     const { id, status } = file
-    console.log(file, 'file')
     
     if (!id || status === 'uploading') {
-        // 如果id不存在或文件正在上传,直接删除文件
+        // 处理未上传文件删除
         const index = fileListData.value.findIndex(f => f.uid === file.uid)
         if (index !== -1) {
             fileListData.value.splice(index, 1)
         }
+        
+        if (typevalue.value && unUploadedFiles.value[typevalue.value]) {
+            const unUploadedIndex = unUploadedFiles.value[typevalue.value].findIndex(f => f.uid === file.uid)
+            if (unUploadedIndex !== -1) {
+                unUploadedFiles.value[typevalue.value].splice(unUploadedIndex, 1)
+            }
+        }
+        
         uploadRef.value.abort()
         uploadDisabled.value = false
-      
+        // 通知父组件更新文件列表
+        emit('update', [...fileListData.value])
     } else {
-        // 如果id存在且文件不在上传状态,调用接口删除文件
+        // 处理已上传文件删除
         loadingText.value = '删除中...'
         uploadDisabled.value = true
-        // const { error, code, msg } = await (accept.value === 'application/pdf'
-         const { error, code, msg } = await (!isListFile.value 
+        const { error, code, msg } = await (!isListFile.value 
             ? wbsApi.delTabById({ ids: id })
             : wbsApi.removeBussFile({ ids: id }))
         uploadDisabled.value = false
         if (!error && code === 200) {
             window?.$message?.success('删除成功')
-            // 从fileListData中移除已删除的文件
+            // 从列表中移除
             const index = fileListData.value.findIndex(f => f.uid === file.uid)
             if (index !== -1) {
                 fileListData.value.splice(index, 1)
             }
-         
+            // 关键:通知父组件更新fileList,确保切换类型时能获取最新列表
+                   emit('update', [...fileListData.value])
         } else {
             window?.$message?.error(msg || '操作失败')
-           
         }
     }
-       
 }
 
 const uploadRemove = () => {
-
-
     if (fileListData.value.length <= 0) {
         emit('change', { type: 'del' })
     }
@@ -370,143 +381,127 @@ const beforesubmitUpload = () => {
             uploadInput.click()
         }
     }
-
-
-
 }
+
 const subLoading = ref(false)
 const submitUpload = async () => {
-     
-          if (fileListData.value.length === 0) {
-            window.$message.warning('请先上传文件')
-            return
-          }
-
-          // 确保所有文件都有 sort 参数
-          fileListData.value = fileListData.value.map((file, index) => ({
-            ...file,
-            sort: index + q,
-          }))
-
-          // 创建 FormData 对象
-          const formData = new FormData()
-        //   // 1. 添加多个文件(后端接收的是 files[] 数组)
-          fileListData.value.forEach((file) => {
-
-            
-          if (file.raw !== undefined) {
-              formData.append('file', file.raw) // 确保 file.raw 是 File 对象
-            }
-          })
-          function hasFileFields(formData) {
-            for (let [key, value] of formData.entries()) {
-                if (value instanceof File || value instanceof Blob) {
-                    return true
-                }
+    if (fileListData.value.length === 0) {
+        window.$message.warning('请先上传文件')
+        return
+    }
+
+    fileListData.value = fileListData.value.map((file, index) => ({
+        ...file,
+        sort: index + q,
+    }))
+
+    const formData = new FormData()
+    fileListData.value.forEach((file) => {
+        if (file.raw !== undefined && !file.id) {
+            formData.append('file', file.raw)
+        }
+    })
+    
+    function hasFileFields(formData) {
+        for (let [key, value] of formData.entries()) {
+            if (value instanceof File || value instanceof Blob) {
+                return true
             }
-            return false
         }
-        if (hasFileFields(formData)) {
-            console.log('formData 包含文件字段')
-              subLoading.value = true
-              if (isListFile.value) {
-                        // 2. 添加其他参数
-                  formData.append('classify', uploadData.value.classify)
-                  formData.append('pkeyId', uploadData.value.pkeyId)
-                  formData.append('nodeId', uploadData.value.nodeId)
-                  formData.append('type', 2)
-                  formData.append('contractId', uploadData.value.contractId)
-                  formData.append('projectId', uploadData.value.projectId)
-                  const { error, code, msg } = await wbsApi.addBussFile(formData) // 修改这里
-                  uploadDisabled.value = false
-                  subLoading.value = false
-                  if (!error && code === 200) {
-                    window?.$message?.success('上传成功') 
-                  await sortFile()
-                    emit('change', { type: 'success' })
-
-                  } else if (code === 413) {
-                      window?.$message?.error('上传文件过大,请上传小于60M的文件')
-                  
-                    } else {
-                    window?.$message?.error(msg || '操作失败')
-
-                  }
-                } else {
-                    // 2. 添加其他参数
-                  formData.append('classify', uploadData.value.classify)
-                  formData.append('nodeId', uploadData.value.nodeId)
-                  formData.append('type', uploadData.value.type)
-                  formData.append('contractId', uploadData.value.contractId)
-                  const { error, code, msg } = await wbsApi.addBussFileNode(formData) // 修改这里
-                        uploadDisabled.value = false
-                        subLoading.value = false
-                  if (!error && code === 200) {
-                  window?.$message?.success('上传成功') 
-                  await sortFile()
-                      emit('change', { type: 'success' })
-
-                    } else if (code === 413) {
-                      window?.$message?.error('上传文件过大,请上传小于60M的文件')
-                  
-                    } else {
-                      window?.$message?.error(msg || '操作失败')
-
-                    }
+        return false
+    }
+    
+    if (hasFileFields(formData)) {
+        subLoading.value = true
+        if (isListFile.value) {
+            formData.append('classify', uploadData.value.classify)
+            formData.append('pkeyId', uploadData.value.pkeyId)
+            formData.append('nodeId', uploadData.value.nodeId)
+            formData.append('type', 2)
+            formData.append('contractId', uploadData.value.contractId)
+            formData.append('projectId', uploadData.value.projectId)
+            const { error, code, msg } = await wbsApi.addBussFile(formData)
+            uploadDisabled.value = false
+            subLoading.value = false
+            if (!error && code === 200) {
+                window?.$message?.success('上传成功') 
+                await sortFile()
+                if (typevalue.value) {
+                    unUploadedFiles.value[typevalue.value] = []
                 }
-
+                emit('change', { type: 'success' })
+                     emit('update', [...fileListData.value])
+            } else if (code === 413) {
+                window?.$message?.error('上传文件过大,请上传小于60M的文件')
+            } else {
+                window?.$message?.error(msg || '操作失败')
+            }
         } else {
-            console.log('formData 不包含文件字段')
-            // 处理没有文件字段的情况
-            await sortFile()
-              emit('change', { type: 'success' })
+            formData.append('classify', uploadData.value.classify)
+            formData.append('nodeId', uploadData.value.nodeId)
+            formData.append('type', uploadData.value.type)
+            formData.append('contractId', uploadData.value.contractId)
+            const { error, code, msg } = await wbsApi.addBussFileNode(formData)
+            uploadDisabled.value = false
+            subLoading.value = false
+            if (!error && code === 200) {
+                window?.$message?.success('上传成功') 
+                await sortFile()
+                if (typevalue.value) {
+                    unUploadedFiles.value[typevalue.value] = []
+                }
+                emit('change', { type: 'success' })
+                    emit('update', [...fileListData.value])
+            } else if (code === 413) {
+                window?.$message?.error('上传文件过大,请上传小于60M的文件')
+            } else {
+                window?.$message?.error(msg || '操作失败')
+            }
         }
+    } else {
+        await sortFile()
+        emit('change', { type: 'success' })
+    }
     subLoading.value = false
 }
+
 //上传文件后排序
 const sortFile = async ()=>{
-  if (fileListData.value.length <= 0) {
-    window.$message.warning('请先上传文件')
-    return
-  }
-  let list = []
-  fileListData.value.forEach((file) => {
-    list.push(
-      file.name,
-  
-    )
-  })
-  let obj1 = {
-    list:list,
-    id:uploadData.value.nodeId,
-    contractId:uploadData.value.contractId,
-    classify:uploadData.value.classify,
-    type:uploadData.value.type,
-   
- 
-
-  }
+    if (fileListData.value.length <= 0) {
+        window.$message.warning('请先上传文件')
+        return
+    }
+    let list = []
+    fileListData.value.forEach((file) => {
+        list.push(file.name)
+    })
+    
+    let obj1 = {
+        list:list,
+        id:uploadData.value.nodeId,
+        contractId:uploadData.value.contractId,
+        classify:uploadData.value.classify,
+        type:uploadData.value.type,
+    }
+    
     let obj2 = {
-    list:list,
-  
-    id:uploadData.value.pkeyId,
-    contractId:uploadData.value.contractId,
-    classify:uploadData.value.classify,
-    projectId:uploadData.value.projectId,
-    type:2,
-
-  }
-      const { error, code, msg } = await (isListFile.value
-            ? wbsApi.addFileSort(obj2)
-            : wbsApi.addFileSort(obj1))
-        uploadDisabled.value = false
-        if (!error && code === 200) {
-            // window?.$message?.success('排序成功')
-           
-        } else {
-            window?.$message?.error(msg || '操作失败')
-            
-        }
+        list:list,
+        id:uploadData.value.pkeyId,
+        contractId:uploadData.value.contractId,
+        classify:uploadData.value.classify,
+        projectId:uploadData.value.projectId,
+        type:2,
+    }
+    
+    const { error, code, msg } = await (isListFile.value
+        ? wbsApi.addFileSort(obj2)
+        : wbsApi.addFileSort(obj1))
+    uploadDisabled.value = false
+    if (!error && code === 200) {
+        // 排序成功
+    } else {
+        window?.$message?.error(msg || '操作失败')
+    }
 }
 </script>
 
@@ -595,4 +590,4 @@ const sortFile = async ()=>{
 .hc-upload-border1 .el-upload-dragger .el-upload__text{
   padding: 40px;
 }
-</style>
+</style>

+ 7 - 0
src/views/data-fill/wbs.vue

@@ -1319,6 +1319,7 @@
                 :typevalue="typevalue"
                 @change="uploadChange"
                 @close="uploadModalClose"
+                @update="uploadUpdate"
             />
         </hc-new-dialog>
 
@@ -3406,6 +3407,12 @@ const uploadChange = async ({ type }) => {
         getBussFileList(primaryKeyId.value)
     }
 }
+const uploadUpdate = (list)=>{
+
+    
+    fileListData.value = list
+
+}
 
 //树节点被选中
 const treeSelectNode = ref([])