@@ -4,9 +4,9 @@ import type { UploadFile, UploadFiles, UploadInstance, UploadRawFile, UploadUser
44import type { DragUploadFile , DragUploadHandler , DragUploadMode } from ' ./types'
55import FileApi from ' @/api/admin/file'
66import uploadImage from ' @/assets/mk_icon_upload.svg'
7- import { getFileIconUrl } from ' @/utils/icon'
8- import { formatFileSize } from ' @/utils/number'
97import { MsgWarning } from ' @/utils/message'
8+ import FileUploadCard from ' ./FileUploadCard.vue'
9+ import ImageUploadCard from ' ./ImageUploadCard.vue'
1010
1111defineOptions ({ name: ' MultipleFileUpload' })
1212
@@ -94,7 +94,6 @@ function validateFile(file: DragUploadFile) {
9494 file .status = ' fail'
9595 file .percentage = 0
9696 file .errMsg = ` 大小超限 `
97- file .canRetry = false
9897 return false
9998 }
10099 const acceptedTypes = props .accept
@@ -127,7 +126,6 @@ function handleUpload(file: DragUploadFile) {
127126 file .status = ' uploading'
128127 file .percentage = 0
129128 file .errMsg = ' '
130- file .canRetry = false
131129 const uid = file .uid
132130 // Promise 链同时覆盖上传接口同步抛错和异步请求失败。
133131 void Promise .resolve ()
@@ -149,7 +147,6 @@ function handleUpload(file: DragUploadFile) {
149147 if (file .status !== ' uploading' ) return
150148 file .status = ' fail'
151149 file .errMsg = ' 网络失败'
152- file .canRetry = true
153150 })
154151 .finally (() => uploadRequests .delete (uid ))
155152}
@@ -204,17 +201,17 @@ const uploadSummary = computed(() => {
204201 summary .completed = summary .success + summary .error
205202 return summary
206203})
207- const retryFiles = computed (() => fileList .value .filter ((file ) => file .status === ' fail' && file . canRetry ))
204+ const retryFiles = computed (() => fileList .value .filter ((file ) => file .status === ' fail' ))
208205const sortedFiles = computed (() => [... fileList .value ].sort ((first , second ) => getFileStatusOrder (first ) - getFileStatusOrder (second )))
209206
210207function getFileStatusOrder(file : DragUploadFile ) {
211- if (file .status === ' fail' ) return file . canRetry ? 0 : 1
208+ if (file .status === ' fail' ) return 0
212209 if (file .status === ' uploading' ) return 2
213210 return 3
214211}
215212
216213function handleRetry(file : DragUploadFile ) {
217- if (props .disabled || file .status !== ' fail' || ! file . canRetry ) return
214+ if (props .disabled || file .status !== ' fail' || ! validateFile ( file ) ) return
218215 if (upload ) handleUpload (file )
219216 else emit (' retry' , file )
220217}
@@ -302,67 +299,18 @@ defineExpose({ clearFiles, handleRemove })
302299 </div >
303300 <div v-if =" mode === 'image'" class =" mt-4 flex flex-wrap gap-3" >
304301 <template v-for =" file in fileList " :key =" file .uid ?? file .name " >
305- <MkTooltip :content =" ` ${file .name }:${file .errMsg } ` " :disabled =" file .status !== ' fail' || ! file .errMsg " placement="top">
306- <div class =" group relative shrink-0 overflow-hidden rounded-md" >
307- <el-image
308- :src =" (file.raw ? imagePreviewUrls.get(file.raw) : undefined) ?? file.url"
309- fit =" cover"
310- class =" size-26"
311- :class =" { 'border-danger!': file.status === 'fail' }"
312- ></el-image >
313-
314- <div v-if =" file.status !== 'success'" class =" pointer-events-none absolute inset-0 bg-N900/30" />
315- <div v-if =" file.status === 'ready' || file.status === 'uploading'" class =" absolute-center w-16" >
316- <el-progress :percentage =" file.status === 'uploading' ? (file.percentage ?? 0) : 0" :stroke-width =" 4" :show-text =" false" />
317- </div >
318- <!-- 重试网络失败的图片 -->
319- <div v-if =" file.status === 'fail' && file.canRetry" class =" absolute-center cursor-pointer" @click =" handleRetry(file)" >
320- <MkIcon name="icon_refresh_outlined" class="text-white!" />
321- </div >
322- <!-- 删除已选图片 -->
323- <div class =" group-hover-visible mk-remove-button" @click =" handleRemove(file)" >
324- <MkIcon name="icon_close_bold_outlined" class="text-white!" :size =" 6 " />
325- </div >
326- </div >
327- </MkTooltip >
302+ <ImageUploadCard
303+ :file =" file "
304+ :src =" (file .raw ? imagePreviewUrls .get (file .raw ) : undefined ) ?? file .url "
305+ :disabled =" disabled "
306+ @retry =" handleRetry (file )"
307+ @remove =" handleRemove (file )"
308+ />
328309 </template >
329310 </div >
330311 <div v-else class =" grid grid-cols-1 gap-3 md:grid-cols-2" >
331312 <template v-for =" file in sortedFiles " :key =" file .uid ?? file .name " >
332- <el-card class =" small relative" shadow =" never" :class =" { 'border-danger!': file.status === 'fail' }" >
333- <div class =" flex-align-center gap-3" >
334- <img :src =" getFileIconUrl(file.name)" alt =" " class =" size-8 shrink-0" />
335- <div class =" min-w-0 flex-1" >
336- <p class =" truncate" :title =" file.name" >{{ file.name }}</p >
337- <div class =" flex-align-center gap-2 text-sm" >
338- <span class =" shrink-0 text-N500" >
339- <template v-if =" file .status === ' uploading' " >{{ formatFileSize(((file.size ?? 0) * (file.percentage ?? 0)) / 100) }} /</template >
340- {{ formatFileSize(file.size) }}
341- </span >
342- <span v-if =" file.status === 'fail'" class =" text-danger" >
343- {{ file.errMsg }}
344- </span >
345- </div >
346- </div >
347- <div class =" flex shrink-0 gap-1" >
348- <!-- 重试当前失败文件 -->
349- <el-button v-if =" file.status === 'fail' && file.canRetry" :disabled =" disabled" text @click =" handleRetry(file)" >
350- <MkIcon name="icon_refresh_outlined" />
351- </el-button >
352- <!-- 删除已选文件 -->
353- <el-button :disabled =" disabled" text title =" 删除文件" @click =" handleRemove(file)" >
354- <MkIcon name="icon_delete-trash_outlined" />
355- </el-button >
356- </div >
357- </div >
358- <el-progress
359- v-if =" file.status === 'uploading'"
360- :percentage =" file.percentage ?? 0"
361- :stroke-width =" 4"
362- :show-text =" false"
363- class =" absolute inset-x-0 bottom-0"
364- />
365- </el-card >
313+ <FileUploadCard :file =" file " :disabled =" disabled " @retry =" handleRetry (file )" @remove =" handleRemove (file )" />
366314 </template >
367315 </div >
368316 </template >
0 commit comments