123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241 |
- import Axios from 'axios'
- import { ResCode } from './constant'
- import { setOfflineAxios } from './offline'
- import type { AxiosResponse, AxiosRequestConfig } from 'axios'
- export type ResErrorHandler = <D, T extends ResData<D>>(response: AxiosResponse<T>, data?: T) => void
- export type ReqErrorHandler = <T>(err: Error, response: AxiosRequestConfig<T>) => void
- export type ResData<T> = { code: ResCode, message: string, data: T, msg: string }
- export type Hook = {
- before?: (config: AxiosRequestConfig) => void
- after?: (config: AxiosRequestConfig) => void
- }
- export const axiosFactory = () => {
- const axiosRaw = Axios.create()
- const axiosConfig = {
- token: localStorage.getItem('token'),
- unTokenSet: [] as string[],
- unReqErrorSet: [] as string[],
- unResErrorSet: [] as string[],
- resErrorHandler: [] as ResErrorHandler[],
- reqErrorHandler: [] as ReqErrorHandler[],
- unLoadingSet: [] as string[],
- hook: [] as Hook[]
- }
- type AxiosConfig = typeof axiosConfig
- type ExponseApi<K extends keyof AxiosConfig> =
- { set: (val: AxiosConfig[K]) => void }
- & (AxiosConfig[K] extends Array<any>
- ? {
- add: (...val: AxiosConfig[K]) => void,
- del: (...val: AxiosConfig[K]) => void
- }
- : { del: () => void })
- const getExponseApi = <K extends keyof AxiosConfig>(key: K): ExponseApi<K> => {
- let axiosObj = axiosConfig[key] as any[]
- const apis: any = {
- set (val: AxiosConfig[K]) {
- console.error('set', key, val)
- axiosObj = axiosConfig[key] = val as any
- }
- }
-
- if (Array.isArray(axiosObj)) {
- apis.add = (...val: any[]) => {
- axiosObj.push(...val)
- }
- apis.del = (...val: any[]) => {
- if (val) {
- apis.set(axiosObj.filter((item: any) => !val?.includes(item)) as any)
- } else {
- axiosObj.length = 0
- }
- }
- } else {
- apis.del = () => {
- axiosConfig[key] = undefined as any
- }
- }
- return apis
- }
- const getToken = () => axiosConfig.token
- const setToken = (token: string) => {
- localStorage.setItem('token', token)
- axiosConfig.token = token
- }
- const delToken = () => {
- localStorage.removeItem('token')
- axiosConfig.token = null
- }
-
- const {
- set: setUnsetTokenURLS,
- add: addUnsetTokenURLS,
- del: delUnsetTokenURLS
- } = getExponseApi('unTokenSet')
- const {
- set: setResErrorHandler,
- add: addResErrorHandler,
- del: delResErrorHandler
- } = getExponseApi('resErrorHandler')
- const {
- set: setUnsetReqErrorURLS,
- add: addUnsetReqErrorURLS,
- del: delUnsetReqErrorURLS
- } = getExponseApi('unReqErrorSet')
- const {
- set: setReqErrorHandler,
- add: addReqErrorHandler,
- del: delReqErrorHandler
- } = getExponseApi('reqErrorHandler')
- const {
- set: setUnsetResErrorURLS,
- add: addUnsetResErrorURLS,
- del: delUnsetResErrorURLS
- } = getExponseApi('unResErrorSet')
- const {
- set: setHook,
- add: addHook,
- del: delHook
- } = getExponseApi('hook')
- const setDefaultURI = (url: string) => {
- axiosRaw.defaults.baseURL = url
- }
- const matchURL = (urls: string[], config: AxiosRequestConfig<any>) =>
- config && config.url && urls.includes(config.url)
- const callErrorHandler = (key: 'req' | 'res', ...args: any[]) => {
- Promise.resolve()
- .then(() => {
- const api = `${key}ErrorHandler`
- ;(axiosConfig as any)[api].forEach((handler: any) => handler(...args))
- })
- }
- axiosRaw.interceptors.request.use(
- config => {
- for (const hook of axiosConfig.hook) {
- hook.before && hook.before(config)
- }
- // console.log(axiosConfig.unTokenSet)
- if (!matchURL(axiosConfig.unTokenSet, config)) {
- if (!axiosConfig.token) {
- if (!offline && !matchURL(axiosConfig.unReqErrorSet, config)) {
- console.log(config)
- const error = new Error('缺少token')
- callErrorHandler('req', error, config)
- throw error
- }
- } else {
- config.headers = {
- ...config.headers,
- token: axiosConfig.token
- }
- }
- }
- return config
- }
- )
-
- offline && setOfflineAxios(axiosRaw)
- axiosRaw.interceptors.response.use(
- (response: AxiosResponse<ResData<any>>) => {
- for (const hook of axiosConfig.hook) {
- hook.after && hook.after(response.config)
- }
- if (matchURL(axiosConfig.unResErrorSet, response.config)) {
- return response
- }
- if (response.status !== 200) {
- callErrorHandler('res', response)
- throw new Error(response.statusText)
- } else if (response.data.code !== ResCode.SUCCESS) {
- callErrorHandler('res', response, response.data)
- if (response.data.code === ResCode.TOKEN_INVALID) {
- delToken()
- }
- throw new Error(response?.data?.message)
- } else {
- return response.data.data
- }
- },
- (err) => {
- for (const hook of axiosConfig.hook) {
- hook.after && hook.after(err.config)
- }
- if (!matchURL(axiosConfig.unResErrorSet, err.config)) {
- callErrorHandler('res', err.response)
- }
- throw new Error(err.response && err.response.statusText)
- }
- )
- type AxiosProcess = {
- getUri(config?: AxiosRequestConfig): string;
- request<R = any, D = any>(config: AxiosRequestConfig<D>): Promise<R>;
- get<R = any, D = any>(url: string, config?: AxiosRequestConfig<D>): Promise<R>;
- delete<R = any, D = any>(url: string, config?: AxiosRequestConfig<D>): Promise<R>;
- head<R = any, D = any>(url: string, config?: AxiosRequestConfig<D>): Promise<R>;
- options<R = any, D = any>(url: string, config?: AxiosRequestConfig<D>): Promise<R>;
- post<R = any, D = any>(url: string, data?: D, config?: AxiosRequestConfig<D>): Promise<R>;
- put<R = any, D = any>(url: string, data?: D, config?: AxiosRequestConfig<D>): Promise<R>;
- patch<R = any, D = any>(url: string, data?: D, config?: AxiosRequestConfig<D>): Promise<R>;
- postForm<R = any, D = any>(url: string, data?: D, config?: AxiosRequestConfig<D>): Promise<R>;
- putForm<R = any, D = any>(url: string, data?: D, config?: AxiosRequestConfig<D>): Promise<R>;
- patchForm<R = any, D = any>(url: string, data?: D, config?: AxiosRequestConfig<D>): Promise<R>;
- }
- interface AxiosInstanceProcess extends AxiosProcess {
- <R = any>(config: AxiosRequestConfig): Promise<R>;
- <R = any>(url: string, config?: AxiosRequestConfig): Promise<R>;
- }
- const axios: AxiosInstanceProcess = axiosRaw as any
- return {
- axios,
- getToken,
- setToken,
- delToken,
- setUnsetTokenURLS,
- addUnsetTokenURLS,
- delUnsetTokenURLS,
- setResErrorHandler,
- addResErrorHandler,
- delResErrorHandler,
- setUnsetReqErrorURLS,
- addUnsetReqErrorURLS,
- delUnsetReqErrorURLS,
- setReqErrorHandler,
- addReqErrorHandler,
- delReqErrorHandler,
- setUnsetResErrorURLS,
- addUnsetResErrorURLS,
- delUnsetResErrorURLS,
- setDefaultURI,
- setHook,
- addHook,
- delHook,
- }
- }
- export default axiosFactory
|