feat(service): 添加请求数据格式转换

This commit is contained in:
Coffee-crocodile 2023-01-12 18:06:23 +08:00
parent b33cb9e353
commit 014f728faf
6 changed files with 122 additions and 45 deletions

View File

@ -31,6 +31,7 @@
"./src/**/*.{vue,js,jsx,ts,tsx,json}": "eslint --fix"
},
"dependencies": {
"@types/qs": "^6.9.7",
"@vueuse/core": "^9.10.0",
"@wangeditor/editor": "^5.1.23",
"@wangeditor/editor-for-vue": "^5.1.12",
@ -39,6 +40,7 @@
"md-editor-v3": "^2.7.2",
"pinia": "^2.0.28",
"pinia-plugin-persist": "^1.0.0",
"qs": "^6.11.0",
"vue": "^3.2.45",
"vue-qr": "^4.0.9",
"vue-router": "^4.1.6"

View File

@ -9,3 +9,9 @@ export enum EnumStorageKey {
/* 标签栏信息 */
tabsRoutes = '__TABS_ROUTES__',
}
export enum EnumContentType {
json = 'application/json',
formUrlencoded = 'application/x-www-form-urlencoded',
formData = 'multipart/form-data',
}

View File

@ -1,6 +1,5 @@
import type { AxiosResponse, AxiosError, AxiosRequestConfig } from 'axios';
import {
ERROR_MSG_DURATION,
DEFAULT_REQUEST_ERROR_CODE,
DEFAULT_REQUEST_ERROR_MSG,
NETWORK_ERROR_CODE,
@ -8,12 +7,11 @@ import {
REQUEST_TIMEOUT_CODE,
REQUEST_TIMEOUT_MSG,
ERROR_STATUS,
ERROR_NO_TIP_STATUS,
} from '@/config';
import { useAuthStore } from '@/store';
import { getRefreshToken } from '@/utils';
import { fetchUpdateToken } from '@/service';
import { setToken, setRefreshToken } from '@/utils';
import { setToken, setRefreshToken, getRefreshToken } from '@/utils';
import { showError } from './utils';
type ErrorStatus = keyof typeof ERROR_STATUS;
@ -141,12 +139,3 @@ export async function handleRefreshToken(config: AxiosRequestConfig) {
resetAuthStore();
return null;
}
export function showError(error: Service.RequestError) {
// 如果error不需要提示,则跳过
const code = Number(error.code);
if (ERROR_NO_TIP_STATUS.includes(code)) return;
window.console.warn(error.code, error.msg);
window.$message?.error(error.msg, { duration: ERROR_MSG_DURATION });
}

View File

@ -9,6 +9,7 @@ import {
handleServiceResult,
handleRefreshToken,
} from './handle';
import { transformRequestData } from './utils';
import { DEFAULT_AXIOS_OPTIONS, DEFAULT_BACKEND_OPTIONS } from '@/config';
@ -32,9 +33,15 @@ export default class createAxiosInstance {
// 设置类拦截器的函数
setInterceptor() {
this.instance.interceptors.request.use(
(config) => {
async (config) => {
const handleConfig = { ...config };
if (handleConfig.headers) {
// 数据格式转换
// handleConfig.headers.setContentType('application/json');
// const contentType = handleConfig.headers.get('Content-Type');
const contentType = 'application/json';
handleConfig.data = await transformRequestData(handleConfig.data, contentType);
// 设置token
typeof handleConfig.headers.set === 'function' &&
handleConfig.headers.set('Authorization', `Bearer ${getToken() || ''}`);

69
src/service/http/utils.ts Normal file
View File

@ -0,0 +1,69 @@
import { ERROR_MSG_DURATION, ERROR_NO_TIP_STATUS } from '@/config';
import { isArray, isFile } from '@/utils';
import { EnumContentType } from '@/enum';
import qs from 'qs';
export function showError(error: Service.RequestError) {
// 如果error不需要提示,则跳过
const code = Number(error.code);
if (ERROR_NO_TIP_STATUS.includes(code)) return;
window.console.warn(error.code, error.msg);
window.$message?.error(error.msg, { duration: ERROR_MSG_DURATION });
}
/**
*
* @param requestData -
* @param contentType - Content-Type
*/
export async function transformRequestData(requestData: any, contentType?: string) {
// application/json类型不处理
let data = requestData;
// form类型转换
if (contentType === EnumContentType.formUrlencoded) {
data = qs.stringify(requestData);
}
// form-data类型转换
if (contentType === EnumContentType.formData) {
data = await handleFormData(requestData);
}
return data;
}
async function handleFormData(data: Record<string, any>) {
const formData = new FormData();
const entries = Object.entries(data);
entries.forEach(async ([key, value]) => {
const isFileType = isFile(value) || (isArray(value) && value.length && isFile(value[0]));
if (isFileType) {
await transformFile(formData, key, value);
} else {
formData.append(key, value);
}
});
return formData;
}
/**
*
* @param key -
* @param file -
*/
async function transformFile(formData: FormData, key: string, file: File[] | File) {
if (isArray(file)) {
// 多文件
await Promise.all(
(file as File[]).map((item) => {
formData.append(key, item);
return true;
})
);
} else {
// 单文件
formData.append(key, file);
}
}

View File

@ -65,6 +65,10 @@ export function isFunction(val: unknown): val is Function {
return typeof val === 'function';
}
export function isFile<T extends File>(val: T | unknown): val is T {
return is(val, 'File');
}
export function isBoolean(val: unknown): val is boolean {
return is(val, 'Boolean');
}