fix: request download and upload not support responseReturn (#5456)
Some checks failed
CI / Test (ubuntu-latest) (push) Has been cancelled
CI / Test (windows-latest) (push) Has been cancelled
CI / Lint (ubuntu-latest) (push) Has been cancelled
CI / Lint (windows-latest) (push) Has been cancelled
CI / Check (ubuntu-latest) (push) Has been cancelled
CI / Check (windows-latest) (push) Has been cancelled
CodeQL / Analyze (${{ matrix.language }}) (none, javascript-typescript) (push) Has been cancelled
Deploy Website on push / Deploy Push Playground Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Docs Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Antd Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Element Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Naive Ftp (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
CI / CI OK (push) Has been cancelled
Deploy Website on push / Rerun on failure (push) Has been cancelled

* fix: request download and upload not support `responseReturn`

* docs: update

* fix: type of request client upload result
This commit is contained in:
Netfan 2025-01-22 00:59:10 +08:00 committed by GitHub
parent 195ceec9b4
commit e225159cce
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 93 additions and 28 deletions

View File

@ -31,6 +31,7 @@ describe('fileDownloader', () => {
expect(result).toEqual(mockBlob); expect(result).toEqual(mockBlob);
expect(mockAxiosInstance.get).toHaveBeenCalledWith(url, { expect(mockAxiosInstance.get).toHaveBeenCalledWith(url, {
responseType: 'blob', responseType: 'blob',
responseReturn: 'body',
}); });
}); });
@ -51,6 +52,7 @@ describe('fileDownloader', () => {
expect(mockAxiosInstance.get).toHaveBeenCalledWith(url, { expect(mockAxiosInstance.get).toHaveBeenCalledWith(url, {
...customConfig, ...customConfig,
responseType: 'blob', responseType: 'blob',
responseReturn: 'body',
}); });
}); });

View File

@ -1,7 +1,14 @@
import type { AxiosRequestConfig } from 'axios';
import type { RequestClient } from '../request-client'; import type { RequestClient } from '../request-client';
import type { RequestResponse } from '../types'; import type { RequestClientConfig } from '../types';
type DownloadRequestConfig = {
/**
*
* raw: 原始的AxiosResponseheadersstatus等
* body: 只返回响应数据的BODY部分(Blob)
*/
responseReturn?: 'body' | 'raw';
} & Omit<RequestClientConfig, 'responseReturn'>;
class FileDownloader { class FileDownloader {
private client: RequestClient; private client: RequestClient;
@ -9,20 +16,23 @@ class FileDownloader {
constructor(client: RequestClient) { constructor(client: RequestClient) {
this.client = client; this.client = client;
} }
/**
public async download( *
* @param url
* @param config
* @returns config.responseReturn为'body'Blob()RequestResponse<Blob>
*/
public async download<T = Blob>(
url: string, url: string,
config?: AxiosRequestConfig, config?: DownloadRequestConfig,
): Promise<RequestResponse<Blob>> { ): Promise<T> {
const finalConfig: AxiosRequestConfig = { const finalConfig: DownloadRequestConfig = {
responseReturn: 'body',
...config, ...config,
responseType: 'blob', responseType: 'blob',
}; };
const response = await this.client.get<RequestResponse<Blob>>( const response = await this.client.get<T>(url, finalConfig);
url,
finalConfig,
);
return response; return response;
} }

View File

@ -1,6 +1,5 @@
import type { AxiosRequestConfig, AxiosResponse } from 'axios';
import type { RequestClient } from '../request-client'; import type { RequestClient } from '../request-client';
import type { RequestClientConfig } from '../types';
class FileUploader { class FileUploader {
private client: RequestClient; private client: RequestClient;
@ -9,18 +8,18 @@ class FileUploader {
this.client = client; this.client = client;
} }
public async upload( public async upload<T = any>(
url: string, url: string,
data: Record<string, any> & { file: Blob | File }, data: Record<string, any> & { file: Blob | File },
config?: AxiosRequestConfig, config?: RequestClientConfig,
): Promise<AxiosResponse> { ): Promise<T> {
const formData = new FormData(); const formData = new FormData();
Object.entries(data).forEach(([key, value]) => { Object.entries(data).forEach(([key, value]) => {
formData.append(key, value); formData.append(key, value);
}); });
const finalConfig: AxiosRequestConfig = { const finalConfig: RequestClientConfig = {
...config, ...config,
headers: { headers: {
'Content-Type': 'multipart/form-data', 'Content-Type': 'multipart/form-data',

View File

@ -25,15 +25,15 @@ export const defaultResponseInterceptor = ({
if (config.responseReturn === 'raw') { if (config.responseReturn === 'raw') {
return response; return response;
} }
const code = responseData[codeField];
if ( if (status >= 200 && status < 400) {
status >= 200 && status < 400 && isFunction(successCode)
? successCode(code)
: code === successCode
) {
if (config.responseReturn === 'body') { if (config.responseReturn === 'body') {
return responseData; return responseData;
} else { } else if (
isFunction(successCode)
? successCode(responseData[codeField])
: responseData[codeField] === successCode
) {
return isFunction(dataField) return isFunction(dataField)
? dataField(responseData) ? dataField(responseData)
: responseData[dataField]; : responseData[dataField];

View File

@ -7,9 +7,9 @@ import type {
type ExtendOptions = { type ExtendOptions = {
/** /**
* raw: 原始的AxiosResponseheadersstatus等 * raw: 原始的AxiosResponseheadersstatus等
* body: 返回响应数据的BODY部分 * body: 返回响应数据的BODY部分status检查请求是否成功code的判断
* data: 解构响应的BODY数据data节点数据 * data: 解构响应的BODY数据data节点数据status和code是否为成功状态
*/ */
responseReturn?: 'body' | 'data' | 'raw'; responseReturn?: 'body' | 'data' | 'raw';
}; };

View File

@ -0,0 +1,28 @@
import type { RequestResponse } from '@vben/request';
import { requestClient } from '../request';
/**
* Blob
* @returns Blob
*/
async function downloadFile1() {
return requestClient.download<Blob>(
'https://unpkg.com/@vbenjs/static-source@0.1.7/source/logo-v1.webp',
);
}
/**
* Response
* @returns RequestResponse<Blob>
*/
async function downloadFile2() {
return requestClient.download<RequestResponse<Blob>>(
'https://unpkg.com/@vbenjs/static-source@0.1.7/source/logo-v1.webp',
{
responseReturn: 'raw',
},
);
}
export { downloadFile1, downloadFile2 };

View File

@ -1,4 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref } from 'vue';
import { Page } from '@vben/common-ui'; import { Page } from '@vben/common-ui';
import { import {
downloadFileFromBase64, downloadFileFromBase64,
@ -9,7 +11,23 @@ import {
import { Button, Card } from 'ant-design-vue'; import { Button, Card } from 'ant-design-vue';
import { downloadFile1, downloadFile2 } from '#/api/examples/download';
import imageBase64 from './base64'; import imageBase64 from './base64';
const downloadResult = ref('');
function getBlob() {
downloadFile1().then((res) => {
downloadResult.value = `获取Blob成功长度${res.size}`;
});
}
function getResponse() {
downloadFile2().then((res) => {
downloadResult.value = `获取Response成功headers${JSON.stringify(res.headers)},长度:${res.data.size}`;
});
}
</script> </script>
<template> <template>
@ -70,5 +88,13 @@ import imageBase64 from './base64';
Download TxT Download TxT
</Button> </Button>
</Card> </Card>
<Card class="my-5" title="Request download">
<Button type="primary" @click="getBlob"> 获取Blob </Button>
<Button type="primary" class="ml-4" @click="getResponse">
获取Response
</Button>
<div class="mt-4">{{ downloadResult }}</div>
</Card>
</Page> </Page>
</template> </template>