Browse Source

Merge branch 'master' into test-dev

duy 1 month ago
parent
commit
2e5fe1b966

+ 20 - 21
src/layout/index.vue

@@ -1,6 +1,6 @@
 <template>
     <el-container
-        v-loading="isAppLoadings" class="hc-layout-box" 
+        v-loading="isAppLoadings" class="hc-layout-box"
 
         :class="{ 'yn-theme': !isYunNanProject, 'is-no-layout': !isNullES(isLayout) && isLayout === 'no' }"
     >
@@ -105,7 +105,7 @@ onMounted(async () => {
     isLayout.value = layout ?? layout2
     annRefs.value = []
     initButtons()
-      
+
     // 确保初始化时加载样式
     currentStyle = await loadStyles()
 })
@@ -131,7 +131,7 @@ watch(() => isAppLoading.value, (res) => {
         }
     }
 
-    
+
 }, { immediate:true })
 
 //路由信息
@@ -175,8 +175,8 @@ watch(() => store.getMenus, (val) => {
                     newArr.push(element2)
                 }
                 }
-               
-             
+
+
             } else if (element.code === 'patrol-menu') {
                 newArr.push(element)
             } else if (element.code === 'system-service') {
@@ -187,11 +187,11 @@ watch(() => store.getMenus, (val) => {
             }
 
             // 最后添加 tasks
-           
 
-            
+
+
         }
-      
+
        let obj1 = newArr[newArr.length - 1]
        let obj2 = newArr[newArr.length - 2]
        newArr[newArr.length - 1] = obj2
@@ -249,8 +249,7 @@ const cascaderSend = async ({ projectId, contractId }) => {
     socket = new HcSocket({ projectId, contractId, userId: userId.value }, (res) => {
         socketData(res?.data)
     })
-    console.log(socket, 'socket')
-    
+ 
 }
 
 //长链接消息
@@ -375,10 +374,10 @@ const loadStyles = async () => {
     styleElement.setAttribute('data-theme', isYunNanProject.value ? 'yunnan' : 'default')
 
     // 3. 加载对应的样式模块
-    const module = isYunNanProject.value 
+    const module = isYunNanProject.value
       ? await import('./test-yn/index-yn.scss?inline')
       : await import('./index.scss?inline')
-    
+
     styleElement.textContent = module.default
     document.head.appendChild(styleElement)
     currentStyle = styleElement
@@ -415,7 +414,7 @@ watch(() =>store.getProjectId, (newProjectId) => {
     //重新加载菜单
     let val = store.getMenus
     if (!isYunNanProject.value) {
-       
+
         return
     }
      let newVal = getArrValue(val)
@@ -430,8 +429,8 @@ watch(() =>store.getProjectId, (newProjectId) => {
                     newArr.push(element2)
                 }
                 }
-               
-             
+
+
             } else if (element.code === 'patrol-menu') {
                 newArr.push(element)
             } else if (element.code === 'system-service') {
@@ -442,11 +441,11 @@ watch(() =>store.getProjectId, (newProjectId) => {
             }
 
             // 最后添加 tasks
-           
 
-            
+
+
         }
-      
+
        let obj1 = newArr[newArr.length - 1]
        let obj2 = newArr[newArr.length - 2]
        newArr[newArr.length - 1] = obj2
@@ -454,7 +453,7 @@ watch(() =>store.getProjectId, (newProjectId) => {
         menuBarData.value = newArr
         console.log(menuBarData.value, 'menuBarData.value')
          isAsideMenu.value = true
-       
+
 
 })
 </script>
@@ -462,13 +461,13 @@ watch(() =>store.getProjectId, (newProjectId) => {
 <style lang="scss" scoped>
 .logo-transition {
     transition: all 0.3s ease;
-    
+
     img {
         max-height: 28px;
         transition: all 0.3s ease;
         will-change: transform;
     }
-    
+
     &.hc-layout-header-logo {
         display: flex;
         align-items: center;

+ 1 - 1
src/router/modules/base.js

@@ -505,7 +505,7 @@ export default [
 
         ],
     },
-        {
+              {
         path: '/system/service',
         name: 'system-service',
         redirect: '/system/service/plane',

+ 3 - 10
src/views/data-fill/collapse-form/index.vue

@@ -2387,16 +2387,9 @@ const deviationSaveClick = async ()=>{
 
 //选择附件类型
 const fileTypeDialog = ref(false)
-const fileTypeModalRef = ref(null)
-const fileTypeSaveClick = async ()=>{
-    const validate = await formValidate(fileTypeModalRef.value, fileTypeRules)
-    if ( !validate) {
-        return false
-    }
-    fileTypeDialog.value = false
-
-     fileModal.value = true
-    getIsUseTestTreeCy()
+const fileTypeSaveClick = ()=>{
+         fileModal.value = true
+           getIsUseTestTreeCy()
 
 }
 const fileTypeModal = ref({

+ 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>
 
@@ -3430,6 +3431,12 @@ const uploadChange = async ({ type }) => {
         getBussFileList(primaryKeyId.value)
     }
 }
+const uploadUpdate = (list)=>{
+
+    
+    fileListData.value = list
+
+}
 
 //树节点被选中
 const treeSelectNode = ref([])