yanghao 1 месяц назад
Родитель
Сommit
a563b4c562

+ 53 - 7
src/components/UploadFile/src/UploadFile.vue

@@ -80,6 +80,7 @@ const emit = defineEmits(['update:modelValue'])
 
 const props = defineProps({
   modelValue: propTypes.oneOfType<string | string[]>([String, Array<String>]).isRequired,
+  returnObject: propTypes.bool.def(false), // 是否返回文件元数据对象
   fileType: propTypes.array.def(['doc', 'xls', 'ppt', 'txt', 'pdf']), // 文件类型, 例如['png', 'jpg', 'jpeg']
   fileSize: propTypes.number.def(5), // 大小限制(MB)
   limit: propTypes.number.def(5), // 数量限制
@@ -137,19 +138,52 @@ const getFileUrl = (value: unknown): string => {
   return ''
 }
 
+const getFilePath = (value: unknown): string => {
+  if (value && typeof value === 'object') {
+    const file = value as { filePath?: unknown; path?: unknown; url?: unknown }
+    if (typeof file.filePath === 'string') return file.filePath
+    if (typeof file.path === 'string') return file.path
+    if (typeof file.url === 'string') return file.url
+  }
+  return getFileUrl(value)
+}
+
+const getFileMetadata = (value: unknown, rawFile?: UploadRawFile) => ({
+  fileName:
+    rawFile?.name ||
+    (value && typeof value === 'object' && typeof (value as any).fileName === 'string'
+      ? (value as any).fileName
+      : ''),
+  fileType:
+    rawFile?.type ||
+    (value && typeof value === 'object' && typeof (value as any).fileType === 'string'
+      ? (value as any).fileType
+      : ''),
+  fileSize:
+    rawFile?.size ||
+    (value && typeof value === 'object' && typeof (value as any).fileSize === 'number'
+      ? (value as any).fileSize
+      : 0),
+  filePath: getFilePath(value)
+})
+
 // 处理上传的文件发生变化
 // const handleFileChange = (uploadFile: UploadFile): void => {
 //   uploadRef.value.data.path = uploadFile.name
 // }
 // 文件上传成功
-const handleFileSuccess: UploadProps['onSuccess'] = (res: any): void => {
+const handleFileSuccess: UploadProps['onSuccess'] = (res: any, uploadFile): void => {
   message.success('上传成功')
   const url = getFileUrl(res?.data)
   if (!url) return
   // 删除自身
   const index = fileList.value.findIndex((item) => (item.response as any)?.data === res.data)
   fileList.value.splice(index, 1)
-  uploadList.value.push({ name: url.substring(url.lastIndexOf('/') + 1), url })
+  uploadList.value.push({
+    name: uploadFile.name || url.substring(url.lastIndexOf('/') + 1),
+    url,
+    attachment: getFileMetadata(res?.data, uploadFile.raw as UploadRawFile)
+  } as UploadUserFile & { attachment: ReturnType<typeof getFileMetadata> })
   if (uploadList.value.length == uploadNumber.value) {
     fileList.value.push(...uploadList.value)
     uploadList.value = []
@@ -198,10 +232,20 @@ watch(
     }
     // 情况2:数组
     fileList.value.push(
-      ...(val as any[])
-        .map((item) => getFileUrl(item))
-        .filter(Boolean)
-        .map((url) => ({ name: url.substring(url.lastIndexOf('/') + 1), url }))
+      ...((val as any[])
+        .map((item) => {
+          const url = getFileUrl(item)
+          return url
+            ? {
+                name:
+                  (typeof item === 'object' && item.fileName) ||
+                  url.substring(url.lastIndexOf('/') + 1),
+                url,
+                attachment: getFileMetadata(item)
+              }
+            : null
+        })
+        .filter(Boolean) as UploadUserFile[])
     )
   },
   { immediate: true, deep: true }
@@ -210,7 +254,9 @@ watch(
 // 发送文件链接列表更新
 const emitUpdateModelValue = () => {
   // 情况1:数组结果
-  let result: string | string[] = fileList.value.map((file) => file.url!)
+  let result: string | string[] = props.returnObject
+    ? fileList.value.map((file: any) => file.attachment || getFileMetadata(file.url))
+    : fileList.value.map((file) => file.url!)
   // 情况2:逗号分隔的字符串
   if (props.limit === 1 || isString(props.modelValue)) {
     result = result.join(',')

+ 8 - 3
src/views/technology‌/list/index2.vue

@@ -310,6 +310,7 @@
       <el-form-item label="专利附件" prop="attachments">
         <UploadFile
           :file-type="['doc', 'docx', 'pdf', 'jpg', 'png', 'jpeg']"
+          :return-object="true"
           v-model="formData.attachments"
           :limit="10"
         />
@@ -443,18 +444,22 @@ const getDeptName = (departmentId?: number) => {
   return findDept(deptList2.value) || String(departmentId)
 }
 
-const normalizeAttachments = (attachments: unknown): string[] => {
+const normalizeAttachments = (attachments: unknown): any[] => {
   if (!attachments) return []
   const values = Array.isArray(attachments) ? attachments : [attachments]
   return values
     .flatMap((attachment: any) => {
       if (typeof attachment === 'string') return attachment.split(',')
       if (attachment && typeof attachment === 'object') {
-        return attachment.url || attachment.path || attachment.fileUrl || []
+        const filePath =
+          attachment.filePath || attachment.path || attachment.url || attachment.fileUrl
+        return filePath ? [{ ...attachment, filePath }] : []
       }
       return []
     })
-    .filter((url): url is string => typeof url === 'string' && url.length > 0)
+    .filter((attachment) =>
+      typeof attachment === 'string' ? attachment.length > 0 : attachment.filePath
+    )
 }
 
 const getList = async () => {