index.ts
/**
* @Author: boyyang
* @Date: 2022-04-16 11:45:46
* @LastEditTime: 2022-04-17 15:58:22
* @LastEditors: boyyang
* @Description:
* @FilePath: \drawingBed\src\utils\http\index.ts
* @[如果痛恨所處的黑暗,請你成為你想要的光。 --塞爾維亞的天空]
*/
import { Axios } from './http'
import { transForm } from './transform'
import { env } from '@/utils/env'
const createHttp = () => {
return new Axios({
baseURL: env.VITE_APP_API_URL,
timeout: 10 * 1000,
transForm: transForm,
// 配置項,下面的選項都可以在獨立的接口請求中覆蓋
requestOptions: {
// 是否返回原生響應頭 比如:需要獲取響應頭時使用該屬性
isReturnNativeResponse: false,
// 需要對返回數據進行處理
isTransformResponse: true,
// get請求添加時間戳
joinTime: true,
// 是否攜帶token
withToken: true,
// 顯示請求后message
isShowMessage: true,
// 顯示請求成功message
isShowSuccessMessage: true,
// 顯示請求失敗message
isShowErrorMessage: true,
// 序列化請求參數 post formData
serializeParams: true
},
})
}
const http = createHttp()
export {
http
}
http.ts
/**
* @Author: boyyang
* @Date: 2022-04-16 11:29:46
* @LastEditTime: 2022-04-17 17:50:55
* @LastEditors: boyyang
* @Description:
* @FilePath: \drawingBed\src\utils\http\http.ts
* @[如果痛恨所處的黑暗,請你成為你想要的光。 --塞爾維亞的天空]
*/
import type { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios'
import axios from 'axios'
import { AxiosOptions, RequestOptions, Result } from './types'
class Axios {
private axiosInstance: AxiosInstance
private options: AxiosOptions
constructor(options: AxiosOptions) {
this.options = options
this.axiosInstance = axios.create(options)
this.setupInterceptors()
}
// 初始化攔截器
private setupInterceptors() {
const { requestInterceptorsCatch } = this.getTransForm() || {}
// 請求之前的攔截器
this.axiosInstance.interceptors.request.use((config: AxiosRequestConfig) => {
const { requestInterceptors } = this.getTransForm() || {}
if (requestInterceptors) {
config = requestInterceptors(config, this.options)
}
return config
},
(error: any) => {
return Promise.reject(error)
}
)
// 請求之后的攔截器
this.axiosInstance.interceptors.response.use((response: AxiosResponse<any>) => {
console.log(response)
const { responseInterceptors } = this.getTransForm() || {}
if (responseInterceptors) {
response = responseInterceptors(response)
}
return response
},
(error: any) => {
return Promise.reject(error)
}
)
}
// 請求
public request<T = any>(config: AxiosRequestConfig, options?: RequestOptions): Promise<Result | T> {
const transForm = this.getTransForm()
const { beforeRequestHook } = transForm || {}
const { requestOptions } = this.options || {}
const opt: RequestOptions = Object.assign({}, requestOptions, options)
if (beforeRequestHook) {
config = beforeRequestHook(config, opt)
}
return new Promise((resolve, reject) => {
this.axiosInstance
.request<any, AxiosResponse<Result>>(config)
.then((response: AxiosResponse<Result>) => {
const { transformRequestData } = this.getTransForm() || {}
if (transformRequestData) {
try {
const res = transformRequestData(response, opt)
resolve(res)
} catch (err) {
reject(err || new Error('request error!'))
}
return
}
resolve(response as unknown as Promise<T>)
})
.catch((error: any) => {
const { requestCatch } = this.getTransForm() || {}
if (requestCatch) {
requestCatch(error)
}
reject(error)
})
})
}
// 獲取轉換器
private getTransForm() {
const { transForm } = this.options
return transForm
}
}
export {
Axios
}
/**
* @Author: boyyang
* @Date: 2022-04-17 11:51:40
* @LastEditTime: 2022-04-17 17:59:50
* @LastEditors: boyyang
* @Description:
* @FilePath: \drawingBed\src\utils\http\transform.ts
* @[如果痛恨所處的黑暗,請你成為你想要的光。 --塞爾維亞的天空]
*/
import { TransForm, RequestOptions, Result, AxiosOptions } from './types'
import { AxiosResponse, AxiosRequestConfig } from 'axios'
import qs from 'qs'
import { useUserStoreWithOut } from '@/store/modules/user'
const userStore = useUserStoreWithOut()
const transForm: TransForm = {
// 請求前hook
beforeRequestHook: (config: AxiosRequestConfig, options: RequestOptions) => {
const { serializeParams, joinTime, withToken } = options
if (serializeParams) { // 序列化參數
if (config.method?.toUpperCase() === 'GET') {
if (joinTime) { // 是否拼接時間戳
config.params = {
...config.params,
_t: Date.now()
}
}
} else {
config.data = qs.stringify(config.data)
}
}
if (withToken) { // 如果需要帶上token
config.headers = {
...config.headers,
token: userStore.getToken
}
}
return config
},
// 轉換請求數據
transformRequestData: (res: AxiosResponse<Result>, options: RequestOptions) => {
const {
isShowMessage,
isShowSuccessMessage,
isShowErrorMessage,
isReturnNativeResponse,
isTransformResponse
} = options
const { data, config } = res
const { code, msg } = data
// 是否顯示請求成功信息
if (isShowMessage) {
if (isShowSuccessMessage) {
if (code === 1 && msg && config.method?.toUpperCase() === 'POST') {
// 成功
window.$message.success(msg)
}
}
if (isShowErrorMessage) {
if (code === 0 && msg) {
// 失敗
window.$message.error(msg)
}
}
}
// 是否返回原生響應頭
if (isReturnNativeResponse) {
return res
}
// 是否進行任何處理,直接返回
if (isTransformResponse) {
return data
}
},
// 請求攔截器
requestInterceptors: (config: AxiosRequestConfig, options: AxiosOptions): AxiosRequestConfig => {
return config
},
// 響應攔截器
responseInterceptors: (res: AxiosResponse<any>): AxiosResponse<any> => {
return res
},
responseInterceptorsCatch: (error: Error) => {
console.log(error)
},
requestCatch: (error: any) => {
console.log(error.response)
const { msg } = error.response.data
window.$message.error(msg)
return error
}
}
export {
transForm
}
types.ts
/**
* @Author: boyyang
* @Date: 2022-04-17 11:32:55
* @LastEditTime: 2022-04-17 17:52:38
* @LastEditors: boyyang
* @Description:
* @FilePath: \drawingBed\src\utils\http\types.ts
* @[如果痛恨所處的黑暗,請你成為你想要的光。 --塞爾維亞的天空]
*/
import type { AxiosRequestConfig, AxiosResponse } from 'axios'
export interface AxiosOptions extends AxiosRequestConfig {
requestOptions?: RequestOptions,
transForm?: TransForm
}
export interface RequestOptions {
// 序列化請求參數
serializeParams?: boolean
// 是否顯示提示信息
isShowMessage?: boolean
// 是否解析成JSON
isParseToJson?: boolean
// 成功的文本信息
successMessageText?: string
// 是否顯示成功信息
isShowSuccessMessage?: boolean
// 是否顯示失敗信息
isShowErrorMessage?: boolean
// 是否添加時間戳
joinTime?: boolean
// 不進行任何處理,直接返回
isTransformResponse?: boolean
// 是否返回原生響應頭
isReturnNativeResponse?: boolean
// 是否攜帶token
withToken?: boolean
}
export interface Result<T = any> {
code: number
msg: string
data: T
}
export abstract class TransForm {
/**
* @description: 請求之前處理配置
* @description: Process configuration before request
*/
beforeRequestHook?: (config: AxiosRequestConfig, options: RequestOptions) => AxiosRequestConfig
/**
* @description: 請求成功處理
*/
transformRequestData?: (res: AxiosResponse<Result>, options: RequestOptions) => any
/**
* @description: 請求失敗處理
*/
requestCatch?: (e: any) => Promise<any>
/**
* @description: 請求之前的攔截器
*/
requestInterceptors?: (config: AxiosRequestConfig, options: AxiosOptions) => AxiosRequestConfig
/**
* @description: 請求之后的攔截器
*/
responseInterceptors?: (res: AxiosResponse<any>) => AxiosResponse<any>
/**
* @description: 請求之前的攔截器錯誤處理
*/
requestInterceptorsCatch?: (error: Error) => void
/**
* @description: 請求之后的攔截器錯誤處理
*/
responseInterceptorsCatch?: (error: Error) => void
}