Skip to content

Commit ee0cb34

Browse files
committed
feat:force delete object
1 parent 7e7c0a3 commit ee0cb34

4 files changed

Lines changed: 118 additions & 3 deletions

File tree

components/object/info.vue

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@
176176
:visible="showVersions"
177177
@close="showVersions = false"
178178
@preview="handlePreviewVersion"
179+
@refresh-parent="handleRefreshParent"
179180
/>
180181
</template>
181182

@@ -199,10 +200,21 @@ const openDrawer = (bucket: string, objName: string) => {
199200
getObject();
200201
getObjectLockConfig();
201202
};
203+
204+
// 处理版本组件请求刷新父组件
205+
const handleRefreshParent = () => {
206+
// 通知父组件(文件列表)刷新
207+
emit('refresh-parent');
208+
};
209+
210+
// 暴露方法给父组件
202211
defineExpose({
203212
openDrawer,
204213
});
205214
215+
// 定义emit事件
216+
const emit = defineEmits(['refresh-parent']);
217+
206218
const message = useMessage();
207219
208220
// 当前路径的前缀, example: '/folder1/folder2/'

components/object/list.vue

Lines changed: 78 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@
8484
<Icon name="ri:arrow-right-s-line" class="ml-2" />
8585
</n-button>
8686
</n-button-group>
87-
<object-info ref="infoRef" />
87+
<object-info ref="infoRef" @refresh-parent="handleObjectDeleted" />
8888
</template>
8989

9090
<script setup lang="ts">
@@ -233,7 +233,7 @@ const columns: DataTableColumns<RowData> = [
233233
title: t('Actions'),
234234
key: 'actions',
235235
align: 'center',
236-
width: 100,
236+
width: 150,
237237
render: (row: RowData) => {
238238
return h(
239239
NSpace,
@@ -258,6 +258,37 @@ const columns: DataTableColumns<RowData> = [
258258
),
259259
}
260260
),
261+
// 删除按钮 - 文件和文件夹都显示
262+
h(
263+
NPopconfirm,
264+
{ onPositiveClick: () => handleDeleteAllVersions(row) },
265+
{
266+
default: () =>
267+
h('div', [
268+
h(
269+
'div',
270+
{ style: 'margin-bottom: 8px;' },
271+
row.type === 'object' ? t('Delete All Versions Warning') : t('Warning')
272+
),
273+
h(
274+
'div',
275+
{ style: 'color: #666; font-size: 12px;' },
276+
row.type === 'object'
277+
? t('Delete All Versions Description')
278+
: t('Are you sure you want to delete this folder and all its contents?')
279+
),
280+
]),
281+
trigger: () =>
282+
h(
283+
NButton,
284+
{ size: 'small', type: 'error', secondary: true },
285+
{
286+
default: () => '',
287+
icon: () => h(Icon, { name: 'ri:delete-bin-5-line' }),
288+
}
289+
),
290+
}
291+
),
261292
],
262293
}
263294
);
@@ -349,6 +380,51 @@ const filteredObjects = computed(() => {
349380
});
350381
});
351382
383+
/** ************************************处理对象删除********************************* */
384+
// 处理对象被删除(从版本组件触发)
385+
const handleObjectDeleted = () => {
386+
// 刷新文件列表
387+
salt.value = randomString();
388+
refresh();
389+
};
390+
391+
/** ************************************删除所有版本********************************* */
392+
// 删除文件的所有版本或文件夹及其内容
393+
const handleDeleteAllVersions = async (row: RowData) => {
394+
try {
395+
if (row.type === 'object') {
396+
// 删除文件的所有版本
397+
const { deleteAllVersions } = useObject({ bucket: bucketName.value });
398+
await deleteAllVersions(row.Key);
399+
message.success(t('Delete All Versions Success'));
400+
} else if (row.type === 'prefix') {
401+
// 删除文件夹及其所有内容
402+
const { mapAllFiles } = useObject({ bucket: bucketName.value });
403+
const files: string[] = [];
404+
405+
// 递归收集文件夹下的所有文件
406+
await mapAllFiles(bucketName.value, row.Key, (fileKey: string) => {
407+
files.push(fileKey);
408+
});
409+
410+
if (files.length > 0) {
411+
// 使用删除任务管理器删除所有文件
412+
deleteTaskStore.addKeys(files, bucketName.value);
413+
message.success(t('Delete task created'));
414+
} else {
415+
message.success(t('Delete Success'));
416+
}
417+
}
418+
419+
// 刷新数据
420+
salt.value = randomString();
421+
refresh();
422+
} catch (error: any) {
423+
console.error('Delete failed:', error);
424+
message.error(t('Delete Failed'));
425+
}
426+
};
427+
352428
/** ************************************批量删除********************************* */
353429
function rowKey(row: any): string {
354430
return row.Key || '';

components/object/versions.vue

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import dayjs from 'dayjs';
2121
import { NButton } from 'naive-ui';
2222
2323
const props = defineProps<{ bucketName: string; objectKey: string; visible: boolean }>();
24-
const emit = defineEmits(['close', 'preview']);
24+
const emit = defineEmits(['close', 'preview', 'refresh-parent']);
2525
const { t } = useI18n();
2626
const message = useMessage();
2727
@@ -153,7 +153,10 @@ async function deleteVersion(row: any) {
153153
try {
154154
await deleteObject(props.objectKey, row.VersionId);
155155
message.success(t('Delete Success'));
156+
157+
// 重新获取版本列表
156158
await fetchVersions();
159+
emit('refresh-parent');
157160
} catch (e: any) {
158161
message.error(t('Delete Failed'));
159162
}

composables/useObject.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ export function useObject({ bucket, region }: { bucket: string; region?: string
5656
Key: key,
5757
};
5858

59+
// 如果版本ID存在且不是null版本ID,则传递版本ID
5960
if (versionId) {
6061
params.VersionId = versionId;
6162
}
@@ -191,6 +192,28 @@ export function useObject({ bucket, region }: { bucket: string; region?: string
191192
return await $client.send(new ListObjectVersionsCommand(params));
192193
}
193194

195+
async function deleteAllVersions(key: string) {
196+
try {
197+
// 获取对象的所有版本
198+
const versions = await getObjectVersions(key);
199+
const versionsToDelete = versions.Versions || [];
200+
const deleteMarkers = versions.DeleteMarkers || [];
201+
202+
// 删除所有版本
203+
const deletePromises = versionsToDelete.map(version => deleteObject(key, version.VersionId));
204+
205+
// 删除所有删除标记
206+
const deleteMarkerPromises = deleteMarkers.map(marker => deleteObject(key, marker.VersionId));
207+
208+
await Promise.all([...deletePromises, ...deleteMarkerPromises]);
209+
210+
return { success: true };
211+
} catch (error) {
212+
console.error('Error deleting all versions:', error);
213+
throw error;
214+
}
215+
}
216+
194217
return {
195218
headObject,
196219
putObject,
@@ -206,5 +229,6 @@ export function useObject({ bucket, region }: { bucket: string; region?: string
206229
getObjectLegalHold,
207230
putObjectLegalHold,
208231
getObjectVersions,
232+
deleteAllVersions,
209233
};
210234
}

0 commit comments

Comments
 (0)