Skip to content

Commit 014f728

Browse files
committed
feat(service): 添加请求数据格式转换
1 parent b33cb9e commit 014f728

File tree

6 files changed

+122
-45
lines changed

6 files changed

+122
-45
lines changed

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
"./src/**/*.{vue,js,jsx,ts,tsx,json}": "eslint --fix"
3232
},
3333
"dependencies": {
34+
"@types/qs": "^6.9.7",
3435
"@vueuse/core": "^9.10.0",
3536
"@wangeditor/editor": "^5.1.23",
3637
"@wangeditor/editor-for-vue": "^5.1.12",
@@ -39,6 +40,7 @@
3940
"md-editor-v3": "^2.7.2",
4041
"pinia": "^2.0.28",
4142
"pinia-plugin-persist": "^1.0.0",
43+
"qs": "^6.11.0",
4244
"vue": "^3.2.45",
4345
"vue-qr": "^4.0.9",
4446
"vue-router": "^4.1.6"

src/enum/common.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,9 @@ export enum EnumStorageKey {
99
/* 标签栏信息 */
1010
tabsRoutes = '__TABS_ROUTES__',
1111
}
12+
13+
export enum EnumContentType {
14+
json = 'application/json',
15+
formUrlencoded = 'application/x-www-form-urlencoded',
16+
formData = 'multipart/form-data',
17+
}

src/service/http/handle.ts

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,17 @@
11
import type { AxiosResponse, AxiosError, AxiosRequestConfig } from 'axios';
22
import {
3-
ERROR_MSG_DURATION,
43
DEFAULT_REQUEST_ERROR_CODE,
54
DEFAULT_REQUEST_ERROR_MSG,
65
NETWORK_ERROR_CODE,
76
NETWORK_ERROR_MSG,
87
REQUEST_TIMEOUT_CODE,
98
REQUEST_TIMEOUT_MSG,
109
ERROR_STATUS,
11-
ERROR_NO_TIP_STATUS,
1210
} from '@/config';
1311
import { useAuthStore } from '@/store';
14-
import { getRefreshToken } from '@/utils';
1512
import { fetchUpdateToken } from '@/service';
16-
import { setToken, setRefreshToken } from '@/utils';
13+
import { setToken, setRefreshToken, getRefreshToken } from '@/utils';
14+
import { showError } from './utils';
1715

1816
type ErrorStatus = keyof typeof ERROR_STATUS;
1917

@@ -141,12 +139,3 @@ export async function handleRefreshToken(config: AxiosRequestConfig) {
141139
resetAuthStore();
142140
return null;
143141
}
144-
145-
export function showError(error: Service.RequestError) {
146-
// 如果error不需要提示,则跳过
147-
const code = Number(error.code);
148-
if (ERROR_NO_TIP_STATUS.includes(code)) return;
149-
150-
window.console.warn(error.code, error.msg);
151-
window.$message?.error(error.msg, { duration: ERROR_MSG_DURATION });
152-
}

src/service/http/instance.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
handleServiceResult,
1010
handleRefreshToken,
1111
} from './handle';
12+
import { transformRequestData } from './utils';
1213

1314
import { DEFAULT_AXIOS_OPTIONS, DEFAULT_BACKEND_OPTIONS } from '@/config';
1415

@@ -32,9 +33,15 @@ export default class createAxiosInstance {
3233
// 设置类拦截器的函数
3334
setInterceptor() {
3435
this.instance.interceptors.request.use(
35-
(config) => {
36+
async (config) => {
3637
const handleConfig = { ...config };
3738
if (handleConfig.headers) {
39+
// 数据格式转换
40+
// handleConfig.headers.setContentType('application/json');
41+
// const contentType = handleConfig.headers.get('Content-Type');
42+
const contentType = 'application/json';
43+
handleConfig.data = await transformRequestData(handleConfig.data, contentType);
44+
3845
// 设置token
3946
typeof handleConfig.headers.set === 'function' &&
4047
handleConfig.headers.set('Authorization', `Bearer ${getToken() || ''}`);

src/service/http/utils.ts

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import { ERROR_MSG_DURATION, ERROR_NO_TIP_STATUS } from '@/config';
2+
import { isArray, isFile } from '@/utils';
3+
import { EnumContentType } from '@/enum';
4+
import qs from 'qs';
5+
6+
export function showError(error: Service.RequestError) {
7+
// 如果error不需要提示,则跳过
8+
const code = Number(error.code);
9+
if (ERROR_NO_TIP_STATUS.includes(code)) return;
10+
11+
window.console.warn(error.code, error.msg);
12+
window.$message?.error(error.msg, { duration: ERROR_MSG_DURATION });
13+
}
14+
/**
15+
* 请求数据的转换
16+
* @param requestData - 请求数据
17+
* @param contentType - 请求头的Content-Type
18+
*/
19+
export async function transformRequestData(requestData: any, contentType?: string) {
20+
// application/json类型不处理
21+
let data = requestData;
22+
// form类型转换
23+
if (contentType === EnumContentType.formUrlencoded) {
24+
data = qs.stringify(requestData);
25+
}
26+
// form-data类型转换
27+
if (contentType === EnumContentType.formData) {
28+
data = await handleFormData(requestData);
29+
}
30+
31+
return data;
32+
}
33+
34+
async function handleFormData(data: Record<string, any>) {
35+
const formData = new FormData();
36+
const entries = Object.entries(data);
37+
38+
entries.forEach(async ([key, value]) => {
39+
const isFileType = isFile(value) || (isArray(value) && value.length && isFile(value[0]));
40+
41+
if (isFileType) {
42+
await transformFile(formData, key, value);
43+
} else {
44+
formData.append(key, value);
45+
}
46+
});
47+
48+
return formData;
49+
}
50+
51+
/**
52+
* 接口为上传文件的类型时数据转换
53+
* @param key - 文件的属性名
54+
* @param file - 单文件或多文件
55+
*/
56+
async function transformFile(formData: FormData, key: string, file: File[] | File) {
57+
if (isArray(file)) {
58+
// 多文件
59+
await Promise.all(
60+
(file as File[]).map((item) => {
61+
formData.append(key, item);
62+
return true;
63+
})
64+
);
65+
} else {
66+
// 单文件
67+
formData.append(key, file);
68+
}
69+
}

src/utils/is.ts

Lines changed: 35 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2,96 +2,100 @@
22
const toString = Object.prototype.toString;
33

44
export function is(val: unknown, type: string) {
5-
return toString.call(val) === `[object ${type}]`;
5+
return toString.call(val) === `[object ${type}]`;
66
}
77

88
export function isDef<T = unknown>(val?: T): val is T {
9-
return typeof val !== 'undefined';
9+
return typeof val !== 'undefined';
1010
}
1111

1212
export function isUnDef<T = unknown>(val?: T): val is T {
13-
return !isDef(val);
13+
return !isDef(val);
1414
}
1515

1616
export function isObject(val: any): val is Record<any, any> {
17-
return val !== null && is(val, 'Object');
17+
return val !== null && is(val, 'Object');
1818
}
1919

2020
export function isEmpty<T = unknown>(val: T): val is T {
21-
if (isArray(val) || isString(val)) {
22-
return val.length === 0;
23-
}
21+
if (isArray(val) || isString(val)) {
22+
return val.length === 0;
23+
}
2424

25-
if (val instanceof Map || val instanceof Set) {
26-
return val.size === 0;
27-
}
25+
if (val instanceof Map || val instanceof Set) {
26+
return val.size === 0;
27+
}
2828

29-
if (isObject(val)) {
30-
return Object.keys(val).length === 0;
31-
}
29+
if (isObject(val)) {
30+
return Object.keys(val).length === 0;
31+
}
3232

33-
return false;
33+
return false;
3434
}
3535

3636
export function isDate(val: unknown): val is Date {
37-
return is(val, 'Date');
37+
return is(val, 'Date');
3838
}
3939

4040
export function isNull(val: unknown): val is null {
41-
return val === null;
41+
return val === null;
4242
}
4343

4444
export function isNullAndUnDef(val: unknown): val is null | undefined {
45-
return isUnDef(val) && isNull(val);
45+
return isUnDef(val) && isNull(val);
4646
}
4747

4848
export function isNullOrUnDef(val: unknown): val is null | undefined {
49-
return isUnDef(val) || isNull(val);
49+
return isUnDef(val) || isNull(val);
5050
}
5151

5252
export function isNumber(val: unknown): val is number {
53-
return is(val, 'Number');
53+
return is(val, 'Number');
5454
}
5555

5656
export function isPromise<T = any>(val: unknown): val is Promise<T> {
57-
return is(val, 'Promise') && isObject(val) && isFunction(val.then) && isFunction(val.catch);
57+
return is(val, 'Promise') && isObject(val) && isFunction(val.then) && isFunction(val.catch);
5858
}
5959

6060
export function isString(val: unknown): val is string {
61-
return is(val, 'String');
61+
return is(val, 'String');
6262
}
6363

6464
export function isFunction(val: unknown): val is Function {
65-
return typeof val === 'function';
65+
return typeof val === 'function';
66+
}
67+
68+
export function isFile<T extends File>(val: T | unknown): val is T {
69+
return is(val, 'File');
6670
}
6771

6872
export function isBoolean(val: unknown): val is boolean {
69-
return is(val, 'Boolean');
73+
return is(val, 'Boolean');
7074
}
7175

7276
export function isRegExp(val: unknown): val is RegExp {
73-
return is(val, 'RegExp');
77+
return is(val, 'RegExp');
7478
}
7579

7680
export function isArray(val: any): val is Array<any> {
77-
return val && Array.isArray(val);
81+
return val && Array.isArray(val);
7882
}
7983

8084
export function isWindow(val: any): val is Window {
81-
return typeof window !== 'undefined' && is(val, 'Window');
85+
return typeof window !== 'undefined' && is(val, 'Window');
8286
}
8387

8488
export function isElement(val: unknown): val is Element {
85-
return isObject(val) && !!val.tagName;
89+
return isObject(val) && !!val.tagName;
8690
}
8791

8892
export const isServer = typeof window === 'undefined';
8993

9094
export const isClient = !isServer;
9195

9296
export function isUrl<T>(path: T): boolean {
93-
const reg =
94-
/(((^https?:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+(?::\d+)?|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)$/;
95-
// @ts-expect-error
96-
return reg.test(path);
97+
const reg =
98+
/(((^https?:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+(?::\d+)?|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)$/;
99+
// @ts-expect-error
100+
return reg.test(path);
97101
}

0 commit comments

Comments
 (0)