mirror of
https://github.com/vbenjs/vue-vben-admin.git
synced 2025-01-23 01:30:26 +08:00
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
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:
parent
195ceec9b4
commit
e225159cce
@ -31,6 +31,7 @@ describe('fileDownloader', () => {
|
||||
expect(result).toEqual(mockBlob);
|
||||
expect(mockAxiosInstance.get).toHaveBeenCalledWith(url, {
|
||||
responseType: 'blob',
|
||||
responseReturn: 'body',
|
||||
});
|
||||
});
|
||||
|
||||
@ -51,6 +52,7 @@ describe('fileDownloader', () => {
|
||||
expect(mockAxiosInstance.get).toHaveBeenCalledWith(url, {
|
||||
...customConfig,
|
||||
responseType: 'blob',
|
||||
responseReturn: 'body',
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -1,7 +1,14 @@
|
||||
import type { AxiosRequestConfig } from 'axios';
|
||||
|
||||
import type { RequestClient } from '../request-client';
|
||||
import type { RequestResponse } from '../types';
|
||||
import type { RequestClientConfig } from '../types';
|
||||
|
||||
type DownloadRequestConfig = {
|
||||
/**
|
||||
* 定义期望获得的数据类型。
|
||||
* raw: 原始的AxiosResponse,包括headers、status等。
|
||||
* body: 只返回响应数据的BODY部分(Blob)
|
||||
*/
|
||||
responseReturn?: 'body' | 'raw';
|
||||
} & Omit<RequestClientConfig, 'responseReturn'>;
|
||||
|
||||
class FileDownloader {
|
||||
private client: RequestClient;
|
||||
@ -9,20 +16,23 @@ class FileDownloader {
|
||||
constructor(client: RequestClient) {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
public async download(
|
||||
/**
|
||||
* 下载文件
|
||||
* @param url 文件的完整链接
|
||||
* @param config 配置信息,可选。
|
||||
* @returns 如果config.responseReturn为'body',则返回Blob(默认),否则返回RequestResponse<Blob>
|
||||
*/
|
||||
public async download<T = Blob>(
|
||||
url: string,
|
||||
config?: AxiosRequestConfig,
|
||||
): Promise<RequestResponse<Blob>> {
|
||||
const finalConfig: AxiosRequestConfig = {
|
||||
config?: DownloadRequestConfig,
|
||||
): Promise<T> {
|
||||
const finalConfig: DownloadRequestConfig = {
|
||||
responseReturn: 'body',
|
||||
...config,
|
||||
responseType: 'blob',
|
||||
};
|
||||
|
||||
const response = await this.client.get<RequestResponse<Blob>>(
|
||||
url,
|
||||
finalConfig,
|
||||
);
|
||||
const response = await this.client.get<T>(url, finalConfig);
|
||||
|
||||
return response;
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
import type { AxiosRequestConfig, AxiosResponse } from 'axios';
|
||||
|
||||
import type { RequestClient } from '../request-client';
|
||||
import type { RequestClientConfig } from '../types';
|
||||
|
||||
class FileUploader {
|
||||
private client: RequestClient;
|
||||
@ -9,18 +8,18 @@ class FileUploader {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
public async upload(
|
||||
public async upload<T = any>(
|
||||
url: string,
|
||||
data: Record<string, any> & { file: Blob | File },
|
||||
config?: AxiosRequestConfig,
|
||||
): Promise<AxiosResponse> {
|
||||
config?: RequestClientConfig,
|
||||
): Promise<T> {
|
||||
const formData = new FormData();
|
||||
|
||||
Object.entries(data).forEach(([key, value]) => {
|
||||
formData.append(key, value);
|
||||
});
|
||||
|
||||
const finalConfig: AxiosRequestConfig = {
|
||||
const finalConfig: RequestClientConfig = {
|
||||
...config,
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data',
|
||||
|
@ -25,15 +25,15 @@ export const defaultResponseInterceptor = ({
|
||||
if (config.responseReturn === 'raw') {
|
||||
return response;
|
||||
}
|
||||
const code = responseData[codeField];
|
||||
if (
|
||||
status >= 200 && status < 400 && isFunction(successCode)
|
||||
? successCode(code)
|
||||
: code === successCode
|
||||
) {
|
||||
|
||||
if (status >= 200 && status < 400) {
|
||||
if (config.responseReturn === 'body') {
|
||||
return responseData;
|
||||
} else {
|
||||
} else if (
|
||||
isFunction(successCode)
|
||||
? successCode(responseData[codeField])
|
||||
: responseData[codeField] === successCode
|
||||
) {
|
||||
return isFunction(dataField)
|
||||
? dataField(responseData)
|
||||
: responseData[dataField];
|
||||
|
@ -7,9 +7,9 @@ import type {
|
||||
|
||||
type ExtendOptions = {
|
||||
/** 响应数据的返回方式。
|
||||
* raw: 原始的AxiosResponse,包括headers、status等。
|
||||
* body: 返回响应数据的BODY部分。
|
||||
* data: 解构响应的BODY数据,只返回其中的data节点数据。
|
||||
* raw: 原始的AxiosResponse,包括headers、status等,不做是否成功请求的检查。
|
||||
* body: 返回响应数据的BODY部分(只会根据status检查请求是否成功,忽略对code的判断,这种情况下应由调用方检查请求是否成功)。
|
||||
* data: 解构响应的BODY数据,只返回其中的data节点数据(会检查status和code是否为成功状态)。
|
||||
*/
|
||||
responseReturn?: 'body' | 'data' | 'raw';
|
||||
};
|
||||
|
28
playground/src/api/examples/download.ts
Normal file
28
playground/src/api/examples/download.ts
Normal 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 };
|
@ -1,4 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
|
||||
import { Page } from '@vben/common-ui';
|
||||
import {
|
||||
downloadFileFromBase64,
|
||||
@ -9,7 +11,23 @@ import {
|
||||
|
||||
import { Button, Card } from 'ant-design-vue';
|
||||
|
||||
import { downloadFile1, downloadFile2 } from '#/api/examples/download';
|
||||
|
||||
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>
|
||||
|
||||
<template>
|
||||
@ -70,5 +88,13 @@ import imageBase64 from './base64';
|
||||
Download TxT
|
||||
</Button>
|
||||
</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>
|
||||
</template>
|
||||
|
Loading…
Reference in New Issue
Block a user