diff --git a/apps/web-antd/src/api/core/upload.ts b/apps/web-antd/src/api/core/upload.ts index d7270b0e..33db90ca 100644 --- a/apps/web-antd/src/api/core/upload.ts +++ b/apps/web-antd/src/api/core/upload.ts @@ -20,18 +20,21 @@ export interface UploadResult { * 通过单文件上传接口 * @param file 上传的文件 * @param otherData 其他请求参数 后端拓展可能会用到 - * @param onUploadProgress 上传进度事件 非必传 + * @param options 一些配置项 + * @param options.onUploadProgress 上传进度事件 + * @param options.signal 上传取消信号 * @returns 上传结果 */ export function uploadApi( file: Blob | File, otherData?: Record, - onUploadProgress?: AxiosProgressEvent, + options?: { onUploadProgress?: AxiosProgressEvent; signal?: AbortSignal }, ) { + const { onUploadProgress, signal } = options ?? {}; return requestClient.upload( '/resource/oss/upload', { file, ...otherData }, - { onUploadProgress, timeout: 60_000 }, + { onUploadProgress, signal, timeout: 60_000 }, ); } diff --git a/apps/web-antd/src/components/upload/src/file-upload.vue b/apps/web-antd/src/components/upload/src/file-upload.vue index f76d6525..bd38c548 100644 --- a/apps/web-antd/src/components/upload/src/file-upload.vue +++ b/apps/web-antd/src/components/upload/src/file-upload.vue @@ -33,6 +33,7 @@ const props = withDefaults(defineProps(), { preview: defaultFilePreview, enableDragUpload: false, directory: false, + abortOnUnmounted: true, }); /** 返回不同的上传组件 */ diff --git a/apps/web-antd/src/components/upload/src/hook.ts b/apps/web-antd/src/components/upload/src/hook.ts index c3e0a41f..6c2f900c 100644 --- a/apps/web-antd/src/components/upload/src/hook.ts +++ b/apps/web-antd/src/components/upload/src/hook.ts @@ -10,7 +10,7 @@ import type { BaseUploadProps } from './props'; import type { AxiosProgressEvent, UploadResult } from '#/api'; import type { OssFile } from '#/api/system/oss/model'; -import { computed, ref, watch } from 'vue'; +import { computed, onUnmounted, ref, watch } from 'vue'; import { $t } from '@vben/locales'; @@ -206,6 +206,7 @@ export function useUpload( return file; } + const uploadAbort = new AbortController(); /** * 自定义上传实现 * @param info @@ -222,11 +223,10 @@ export function useUpload( const percent = Math.trunc((e.loaded / e.total!) * 100); info.onProgress!({ percent }); }; - const res = await api( - info.file as File, - props?.data ?? {}, - progressEvent, - ); + const res = await api(info.file as File, props?.data ?? {}, { + onUploadProgress: progressEvent, + signal: uploadAbort.signal, + }); info.onSuccess!(res); if (props.showSuccessMsg) { message.success($t('component.upload.uploadSuccess')); @@ -237,6 +237,10 @@ export function useUpload( } } + onUnmounted(() => { + props.abortOnUnmounted && uploadAbort.abort(); + }); + /** * 这里默认只监听list地址变化 即重新赋值才会触发watch * immediate用于初始化触发 diff --git a/apps/web-antd/src/components/upload/src/image-upload.vue b/apps/web-antd/src/components/upload/src/image-upload.vue index f817ad83..dbe7d9ec 100644 --- a/apps/web-antd/src/components/upload/src/image-upload.vue +++ b/apps/web-antd/src/components/upload/src/image-upload.vue @@ -42,6 +42,7 @@ const props = withDefaults(defineProps(), { listType: 'picture-card', helpMessage: true, enableDragUpload: false, + abortOnUnmounted: true, }); // 双向绑定 ossId diff --git a/apps/web-antd/src/components/upload/src/props.d.ts b/apps/web-antd/src/components/upload/src/props.d.ts index 077aded0..624b21e6 100644 --- a/apps/web-antd/src/components/upload/src/props.d.ts +++ b/apps/web-antd/src/components/upload/src/props.d.ts @@ -89,4 +89,9 @@ export interface BaseUploadProps { * @param file file */ preview?: (file: UploadFile) => Promise | void; + /** + * 是否在组件Unmounted时取消上传 + * @default true + */ + abortOnUnmounted?: boolean; } diff --git a/apps/web-antd/src/views/演示使用自行删除/upload/index.vue b/apps/web-antd/src/views/演示使用自行删除/upload/index.vue index c64d1101..c6ad6a1e 100644 --- a/apps/web-antd/src/views/演示使用自行删除/upload/index.vue +++ b/apps/web-antd/src/views/演示使用自行删除/upload/index.vue @@ -5,7 +5,7 @@ import { h, ref } from 'vue'; import { Page } from '@vben/common-ui'; -import { Alert, Card, Modal } from 'ant-design-vue'; +import { Alert, Card, Modal, Switch } from 'ant-design-vue'; import { FileUpload, ImageUpload } from '#/components/upload'; @@ -27,6 +27,8 @@ function customAccept(accept: string) { .map((str) => str.toUpperCase()) .join(','); } + +const showComponent = ref(true);