99 </label >
1010 </div >
1111 <template #actions >
12- <object-upload-stats />
13- <object-delete-stats />
12+ <object-task-stats :tasks =" taskStore.tasks" :on-clear-tasks =" taskStore.clearTasks" >
13+ <template #task-list =" { tasks } " >
14+ <object-task-list :tasks =" tasks" />
15+ </template >
16+ </object-task-stats >
1417 <!-- <Button variant="outline" @click="() => handleNewObject(true)">
1518 <Icon name="ri:add-line" class="size-4" />
1619 <span>{{ t('New Folder') }}</span>
1922 <Icon name="ri:file-add-line " class="size-4" />
2023 <span >{{ t('Upload File') }}/{{ t('Folder') }}</span >
2124 </Button >
22- <Button
23- variant="outline"
24- class="text-destructive border-destructive"
25- :disabled =" ! checkedKeys .length "
26- v-show =" checkedKeys .length "
27- @click =" handleBatchDelete "
28- >
25+ <Button variant="outline" class="text-destructive border-destructive" :disabled =" ! checkedKeys .length " v-show =" checkedKeys .length " @click =" handleBatchDelete " >
2926 <Icon name="ri:delete-bin-5-line " class="size-4" />
3027 <span >{{ t('Delete Selected') }}</span >
3128 </Button >
4037 </template >
4138 </page-header >
4239
43- <DataTable
44- :table =" table "
45- :is-loading =" loading "
46- :empty-title =" t (' No Objects' )"
47- :empty-description =" t (' Upload files or create folders to populate this bucket.' )"
48- />
40+ <DataTable :table =" table " :is-loading =" loading " :empty-title =" t (' No Objects' )" :empty-description =" t (' Upload files or create folders to populate this bucket.' )" />
4941
5042 <div class =" flex justify-end gap-2" >
5143 <Button variant="outline" :disabled =" ! continuationToken " @click =" goToPreviousPage " >
5951 </div >
6052 </div >
6153
62- <object-upload-picker
63- :show =" uploadPickerVisible"
64- :bucketName =" bucketName"
65- :prefix =" prefix"
66- @update:show ="
67- val => {
68- uploadPickerVisible = val
69- refresh()
70- }
71- "
72- />
73- <object-new-form
74- :show =" newObjectFormVisible"
75- :bucketName =" bucketName"
76- :prefix =" prefix"
77- :asPrefix =" newObjectAsPrefix"
78- @update:show ="
79- val => {
80- newObjectFormVisible = val
81- refresh()
82- }
83- "
84- />
54+ <object-upload-picker :show =" uploadPickerVisible" :bucketName =" bucketName" :prefix =" prefix" @update:show ="
55+ val => {
56+ uploadPickerVisible = val
57+ refresh()
58+ }
59+ " />
60+ <object-new-form :show =" newObjectFormVisible" :bucketName =" bucketName" :prefix =" prefix" :asPrefix =" newObjectAsPrefix" @update:show ="
61+ val => {
62+ newObjectFormVisible = val
63+ refresh()
64+ }
65+ " />
8566 <object-info ref =" infoRef" :bucket-name =" bucketName" @refresh-parent =" handleObjectDeleted" />
8667</template >
8768
@@ -102,9 +83,8 @@ import { saveAs } from 'file-saver'
10283import JSZip from ' jszip'
10384import { joinRelativeURL } from ' ufo'
10485import type { VNode } from ' vue'
105- import { computed , h , ref , watch } from ' vue'
106- import { useDeleteTaskManagerStore } from ' ~/store/delete-tasks'
107- import { useUploadTaskManagerStore } from ' ~/store/upload-tasks'
86+ import { computed , h , onMounted , onUnmounted , ref , watch } from ' vue'
87+ import { useTaskManagerStore } from ' ~/store/tasks'
10888
10989const { $s3Client } = useNuxtApp ()
11090const { t } = useI18n ()
@@ -139,8 +119,7 @@ watch(searchTerm, () => {
139119 handleSearch ()
140120})
141121
142- const uploadTaskStore = useUploadTaskManagerStore ()
143- const deleteTaskStore = useDeleteTaskManagerStore ()
122+ const taskStore = useTaskManagerStore ()
144123
145124type ObjectRow = {
146125 Key: string
@@ -230,9 +209,8 @@ const fetchObjects = async (): Promise<ObjectRow[]> => {
230209}
231210
232211const asyncDataCacheKey = computed (() => {
233- return ` objects-${bucketName .value }-${prefix .value }-${continuationToken .value || ' start' }-${searchTerm .value || ' all' }-${
234- showDeleted .value ? ' withDeleted' : ' withoutDeleted'
235- } `
212+ return ` objects-${bucketName .value }-${prefix .value }-${continuationToken .value || ' start' }-${searchTerm .value || ' all' }-${showDeleted .value ? ' withDeleted' : ' withoutDeleted'
213+ } `
236214})
237215
238216const displayKey = (key : string ) => {
@@ -318,14 +296,14 @@ const columns = computed<ColumnDef<ObjectRow, any>[]>(() => {
318296 h (' div' , { class: ' flex items-center gap-2' }, [
319297 row .original .type === ' object'
320298 ? h (
321- Button ,
322- {
323- variant: ' outline' ,
324- size: ' sm' ,
325- onClick : () => downloadFile (row .original .Key ),
326- },
327- () => [h (Icon , { name: ' ri:download-cloud-2-line' , class: ' size-4' }), h (' span' , t (' Download' ))]
328- )
299+ Button ,
300+ {
301+ variant: ' outline' ,
302+ size: ' sm' ,
303+ onClick : () => downloadFile (row .original .Key ),
304+ },
305+ () => [h (Icon , { name: ' ri:download-cloud-2-line' , class: ' size-4' }), h (' span' , t (' Download' ))]
306+ )
329307 : null ,
330308 h (
331309 Button ,
@@ -352,17 +330,22 @@ const { table, selectedRowIds } = useDataTable<ObjectRow>({
352330// Use selectedRowIds from data-table instead of manually maintaining checkedKeys
353331const checkedKeys = computed (() => selectedRowIds .value )
354332
355- watch (
356- () => uploadTaskStore .tasks ,
357- () => setTimeout (() => refresh (), 500 ),
358- { deep: true }
359- )
333+ // 监听任务完成事件,只在所有任务完成时刷新列表
334+ // 这样可以避免在上传/删除大量文件时频繁刷新
335+ // 保存事件处理函数引用,以便在卸载时正确清理
336+ const handleAllTasksCompleted = () => {
337+ refresh ()
338+ }
360339
361- watch (
362- () => deleteTaskStore .tasks ,
363- () => setTimeout (() => refresh (), 500 ),
364- { deep: true }
365- )
340+ onMounted (() => {
341+ // 监听所有任务全部完成事件(上传/删除)
342+ taskStore .on (' drained' , handleAllTasksCompleted )
343+ })
344+
345+ onUnmounted (() => {
346+ // 清理事件监听器
347+ taskStore .off (' drained' , handleAllTasksCompleted )
348+ })
366349
367350const goToNextPage = () => {
368351 if (! nextToken .value ) return
@@ -518,7 +501,7 @@ const handleDelete = async (keys: string[]) => {
518501 if (! targets .length ) {
519502 message .success (t (' Delete Success' ))
520503 } else {
521- deleteTaskStore . addKeys (targets , bucketName .value )
504+ taskStore . addDeleteKeys (targets , bucketName .value )
522505 message .success (t (' Delete task created' ))
523506 }
524507 table .resetRowSelection ()
0 commit comments