File tree 7 files changed +93
-28
lines changed
packages/effects/request/src/request-client
views/demos/features/file-download
7 files changed +93
-28
lines changed Original file line number Diff line number Diff line change @@ -31,6 +31,7 @@ describe('fileDownloader', () => {
31
31
expect ( result ) . toEqual ( mockBlob ) ;
32
32
expect ( mockAxiosInstance . get ) . toHaveBeenCalledWith ( url , {
33
33
responseType : 'blob' ,
34
+ responseReturn : 'body' ,
34
35
} ) ;
35
36
} ) ;
36
37
@@ -51,6 +52,7 @@ describe('fileDownloader', () => {
51
52
expect ( mockAxiosInstance . get ) . toHaveBeenCalledWith ( url , {
52
53
...customConfig ,
53
54
responseType : 'blob' ,
55
+ responseReturn : 'body' ,
54
56
} ) ;
55
57
} ) ;
56
58
Original file line number Diff line number Diff line change 1
- import type { AxiosRequestConfig } from 'axios' ;
2
-
3
1
import type { RequestClient } from '../request-client' ;
4
- import type { RequestResponse } from '../types' ;
2
+ import type { RequestClientConfig } from '../types' ;
3
+
4
+ type DownloadRequestConfig = {
5
+ /**
6
+ * 定义期望获得的数据类型。
7
+ * raw: 原始的AxiosResponse,包括headers、status等。
8
+ * body: 只返回响应数据的BODY部分(Blob)
9
+ */
10
+ responseReturn ?: 'body' | 'raw' ;
11
+ } & Omit < RequestClientConfig , 'responseReturn' > ;
5
12
6
13
class FileDownloader {
7
14
private client : RequestClient ;
8
15
9
16
constructor ( client : RequestClient ) {
10
17
this . client = client ;
11
18
}
12
-
13
- public async download (
19
+ /**
20
+ * 下载文件
21
+ * @param url 文件的完整链接
22
+ * @param config 配置信息,可选。
23
+ * @returns 如果config.responseReturn为'body',则返回Blob(默认),否则返回RequestResponse<Blob>
24
+ */
25
+ public async download < T = Blob > (
14
26
url : string ,
15
- config ?: AxiosRequestConfig ,
16
- ) : Promise < RequestResponse < Blob > > {
17
- const finalConfig : AxiosRequestConfig = {
27
+ config ?: DownloadRequestConfig ,
28
+ ) : Promise < T > {
29
+ const finalConfig : DownloadRequestConfig = {
30
+ responseReturn : 'body' ,
18
31
...config ,
19
32
responseType : 'blob' ,
20
33
} ;
21
34
22
- const response = await this . client . get < RequestResponse < Blob > > (
23
- url ,
24
- finalConfig ,
25
- ) ;
35
+ const response = await this . client . get < T > ( url , finalConfig ) ;
26
36
27
37
return response ;
28
38
}
Original file line number Diff line number Diff line change 1
- import type { AxiosRequestConfig , AxiosResponse } from 'axios' ;
2
-
3
1
import type { RequestClient } from '../request-client' ;
2
+ import type { RequestClientConfig } from '../types' ;
4
3
5
4
class FileUploader {
6
5
private client : RequestClient ;
@@ -9,18 +8,18 @@ class FileUploader {
9
8
this . client = client ;
10
9
}
11
10
12
- public async upload (
11
+ public async upload < T = any > (
13
12
url : string ,
14
13
data : Record < string , any > & { file : Blob | File } ,
15
- config ?: AxiosRequestConfig ,
16
- ) : Promise < AxiosResponse > {
14
+ config ?: RequestClientConfig ,
15
+ ) : Promise < T > {
17
16
const formData = new FormData ( ) ;
18
17
19
18
Object . entries ( data ) . forEach ( ( [ key , value ] ) => {
20
19
formData . append ( key , value ) ;
21
20
} ) ;
22
21
23
- const finalConfig : AxiosRequestConfig = {
22
+ const finalConfig : RequestClientConfig = {
24
23
...config ,
25
24
headers : {
26
25
'Content-Type' : 'multipart/form-data' ,
Original file line number Diff line number Diff line change @@ -25,15 +25,15 @@ export const defaultResponseInterceptor = ({
25
25
if ( config . responseReturn === 'raw' ) {
26
26
return response ;
27
27
}
28
- const code = responseData [ codeField ] ;
29
- if (
30
- status >= 200 && status < 400 && isFunction ( successCode )
31
- ? successCode ( code )
32
- : code === successCode
33
- ) {
28
+
29
+ if ( status >= 200 && status < 400 ) {
34
30
if ( config . responseReturn === 'body' ) {
35
31
return responseData ;
36
- } else {
32
+ } else if (
33
+ isFunction ( successCode )
34
+ ? successCode ( responseData [ codeField ] )
35
+ : responseData [ codeField ] === successCode
36
+ ) {
37
37
return isFunction ( dataField )
38
38
? dataField ( responseData )
39
39
: responseData [ dataField ] ;
Original file line number Diff line number Diff line change @@ -7,9 +7,9 @@ import type {
7
7
8
8
type ExtendOptions = {
9
9
/** 响应数据的返回方式。
10
- * raw: 原始的AxiosResponse,包括headers、status等。
11
- * body: 返回响应数据的BODY部分。
12
- * data: 解构响应的BODY数据,只返回其中的data节点数据。
10
+ * raw: 原始的AxiosResponse,包括headers、status等,不做是否成功请求的检查 。
11
+ * body: 返回响应数据的BODY部分(只会根据status检查请求是否成功,忽略对code的判断,这种情况下应由调用方检查请求是否成功) 。
12
+ * data: 解构响应的BODY数据,只返回其中的data节点数据(会检查status和code是否为成功状态) 。
13
13
*/
14
14
responseReturn ?: 'body' | 'data' | 'raw' ;
15
15
} ;
Original file line number Diff line number Diff line change
1
+ import type { RequestResponse } from '@vben/request' ;
2
+
3
+ import { requestClient } from '../request' ;
4
+
5
+ /**
6
+ * 下载文件,获取Blob
7
+ * @returns Blob
8
+ */
9
+ async function downloadFile1 ( ) {
10
+ return requestClient . download < Blob > (
11
+ 'https://unpkg.com/@vbenjs/static-source@0.1.7/source/logo-v1.webp' ,
12
+ ) ;
13
+ }
14
+
15
+ /**
16
+ * 下载文件,获取完整的Response
17
+ * @returns RequestResponse<Blob>
18
+ */
19
+ async function downloadFile2 ( ) {
20
+ return requestClient . download < RequestResponse < Blob > > (
21
+ 'https://unpkg.com/@vbenjs/static-source@0.1.7/source/logo-v1.webp' ,
22
+ {
23
+ responseReturn : 'raw' ,
24
+ } ,
25
+ ) ;
26
+ }
27
+
28
+ export { downloadFile1 , downloadFile2 } ;
Original file line number Diff line number Diff line change 1
1
<script setup lang="ts">
2
+ import { ref } from ' vue' ;
3
+
2
4
import { Page } from ' @vben/common-ui' ;
3
5
import {
4
6
downloadFileFromBase64 ,
@@ -9,7 +11,23 @@ import {
9
11
10
12
import { Button , Card } from ' ant-design-vue' ;
11
13
14
+ import { downloadFile1 , downloadFile2 } from ' #/api/examples/download' ;
15
+
12
16
import imageBase64 from ' ./base64' ;
17
+
18
+ const downloadResult = ref (' ' );
19
+
20
+ function getBlob() {
21
+ downloadFile1 ().then ((res ) => {
22
+ downloadResult .value = ` 获取Blob成功,长度:${res .size } ` ;
23
+ });
24
+ }
25
+
26
+ function getResponse() {
27
+ downloadFile2 ().then ((res ) => {
28
+ downloadResult .value = ` 获取Response成功,headers:${JSON .stringify (res .headers )},长度:${res .data .size } ` ;
29
+ });
30
+ }
13
31
</script >
14
32
15
33
<template >
@@ -70,5 +88,13 @@ import imageBase64 from './base64';
70
88
Download TxT
71
89
</Button >
72
90
</Card >
91
+
92
+ <Card class =" my-5" title =" Request download" >
93
+ <Button type =" primary" @click =" getBlob" > 获取Blob </Button >
94
+ <Button type =" primary" class =" ml-4" @click =" getResponse" >
95
+ 获取Response
96
+ </Button >
97
+ <div class =" mt-4" >{{ downloadResult }}</div >
98
+ </Card >
73
99
</Page >
74
100
</template >
You can’t perform that action at this time.
0 commit comments