|
|
@ -1,10 +1,10 @@
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// Copyright (C) 2024 veypi <i@veypi.com>
|
|
|
|
// Copyright (C) 2024 veypi <i@veypi.com>
|
|
|
|
// 2024-10-28 19:22:21
|
|
|
|
// 2024-10-28 17:46:56
|
|
|
|
// Distributed under terms of the MIT license.
|
|
|
|
// Distributed under terms of the MIT license.
|
|
|
|
//
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
|
|
import axios, { AxiosError, type AxiosResponse } from 'axios';
|
|
|
|
import axios, { AxiosError, type AxiosInstance, type AxiosResponse } from 'axios';
|
|
|
|
|
|
|
|
|
|
|
|
// Be careful when using SSR for cross-request state pollution
|
|
|
|
// Be careful when using SSR for cross-request state pollution
|
|
|
|
// due to creating a Singleton instance here;
|
|
|
|
// due to creating a Singleton instance here;
|
|
|
@ -13,18 +13,10 @@ import axios, { AxiosError, type AxiosResponse } from 'axios';
|
|
|
|
// "export default () => {}" function below (which runs individually
|
|
|
|
// "export default () => {}" function below (which runs individually
|
|
|
|
// for each client)
|
|
|
|
// for each client)
|
|
|
|
|
|
|
|
|
|
|
|
axios.defaults.withCredentials = true
|
|
|
|
|
|
|
|
const proxy = axios.create({
|
|
|
|
|
|
|
|
withCredentials: true,
|
|
|
|
|
|
|
|
baseURL: "/api/",
|
|
|
|
|
|
|
|
headers: {
|
|
|
|
|
|
|
|
'content-type': 'application/json;charset=UTF-8',
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export const token = {
|
|
|
|
export const token = {
|
|
|
|
value: '',
|
|
|
|
value: '',
|
|
|
|
update: () => {
|
|
|
|
update: () => {
|
|
|
|
|
|
|
|
console.warn('token updater not set')
|
|
|
|
return new Promise<string>((resolve) => { resolve(token.value) })
|
|
|
|
return new Promise<string>((resolve) => { resolve(token.value) })
|
|
|
|
},
|
|
|
|
},
|
|
|
|
set_updator: (fn: () => Promise<string>) => {
|
|
|
|
set_updator: (fn: () => Promise<string>) => {
|
|
|
@ -34,7 +26,7 @@ export const token = {
|
|
|
|
return new Promise<void>((resolve) => {
|
|
|
|
return new Promise<void>((resolve) => {
|
|
|
|
setTimeout(() => {
|
|
|
|
setTimeout(() => {
|
|
|
|
resolve();
|
|
|
|
resolve();
|
|
|
|
}, 100)
|
|
|
|
}, 1000)
|
|
|
|
}).then(() => {
|
|
|
|
}).then(() => {
|
|
|
|
return token.update()
|
|
|
|
return token.update()
|
|
|
|
})
|
|
|
|
})
|
|
|
@ -58,32 +50,32 @@ export const token = {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// 请求拦截
|
|
|
|
// 请求拦截
|
|
|
|
const beforeRequest = (config: any) => {
|
|
|
|
const beforeRequest = (config: any) => {
|
|
|
|
config.retryTimes = 1
|
|
|
|
config.retryTimes = 3
|
|
|
|
// NOTE 添加自定义头部
|
|
|
|
// NOTE 添加自定义头部
|
|
|
|
token.value && (config.headers.Authorization = `Bearer ${token.value}`)
|
|
|
|
token.value && (config.headers.Authorization = `Bearer ${token.value}`)
|
|
|
|
// config.headers['auth_token'] = ''
|
|
|
|
|
|
|
|
return config
|
|
|
|
return config
|
|
|
|
}
|
|
|
|
}
|
|
|
|
proxy.interceptors.request.use(beforeRequest)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 响应拦截器
|
|
|
|
// 响应拦截器
|
|
|
|
const responseSuccess = (response: AxiosResponse) => {
|
|
|
|
const responseSuccess = (client: AxiosInstance) => {
|
|
|
|
|
|
|
|
return (response: AxiosResponse) => {
|
|
|
|
// eslint-disable-next-line yoda
|
|
|
|
// eslint-disable-next-line yoda
|
|
|
|
// 这里没有必要进行判断,axios 内部已经判断
|
|
|
|
// 这里没有必要进行判断,axios 内部已经判断
|
|
|
|
// const isOk = 200 <= response.status && response.status < 300
|
|
|
|
// const isOk = 200 <= response.status && response.status < 300
|
|
|
|
let data = response.data
|
|
|
|
let data = response.data
|
|
|
|
if (typeof data === 'object') {
|
|
|
|
if (typeof data === 'object') {
|
|
|
|
if (data.code !== 0) {
|
|
|
|
if (data.code !== 0) {
|
|
|
|
return responseFailed({ response } as any)
|
|
|
|
return responseFailed(client)({ response } as any)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
data = data.data
|
|
|
|
data = data.data
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return Promise.resolve(data)
|
|
|
|
return Promise.resolve(data)
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const responseFailed = (error: AxiosError) => {
|
|
|
|
const responseFailed = (client: AxiosInstance) => {
|
|
|
|
|
|
|
|
return (error: AxiosError) => {
|
|
|
|
const { response } = error
|
|
|
|
const { response } = error
|
|
|
|
const config = response?.config
|
|
|
|
|
|
|
|
const data = response?.data || {} as any
|
|
|
|
const data = response?.data || {} as any
|
|
|
|
if (!window.navigator.onLine) {
|
|
|
|
if (!window.navigator.onLine) {
|
|
|
|
alert('没有网络')
|
|
|
|
alert('没有网络')
|
|
|
@ -99,21 +91,23 @@ const responseFailed = (error: AxiosError) => {
|
|
|
|
// AuthExpired = New(40102, "auth expired")
|
|
|
|
// AuthExpired = New(40102, "auth expired")
|
|
|
|
if (data.code === 40102 || data.code === 40100) {
|
|
|
|
if (data.code === 40102 || data.code === 40100) {
|
|
|
|
token.value = ''
|
|
|
|
token.value = ''
|
|
|
|
return token.update().then(() => {
|
|
|
|
return token.update().then((e) => {
|
|
|
|
return requestRetry(100, response!)
|
|
|
|
console.log('token updated: ' + e)
|
|
|
|
|
|
|
|
return requestRetry(client)(500, response!)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (response?.status == 500) {
|
|
|
|
} else if (response?.status == 500) {
|
|
|
|
needRetry = false
|
|
|
|
needRetry = false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
console.log(data, response?.status)
|
|
|
|
|
|
|
|
if (!needRetry) {
|
|
|
|
if (!needRetry) {
|
|
|
|
return Promise.reject(data || response)
|
|
|
|
return Promise.reject(data || response)
|
|
|
|
};
|
|
|
|
};
|
|
|
|
return requestRetry(1000, response!)
|
|
|
|
return requestRetry(client)(1000, response!)
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const requestRetry = (delay = 0, response: AxiosResponse) => {
|
|
|
|
const requestRetry = (client: AxiosInstance) => {
|
|
|
|
|
|
|
|
return (delay = 0, response: AxiosResponse) => {
|
|
|
|
const config = response?.config
|
|
|
|
const config = response?.config
|
|
|
|
// @ts-ignore
|
|
|
|
// @ts-ignore
|
|
|
|
const { __retryCount = 0, retryDelay = 1000, retryTimes } = config;
|
|
|
|
const { __retryCount = 0, retryDelay = 1000, retryTimes } = config;
|
|
|
@ -125,7 +119,7 @@ const requestRetry = (delay = 0, response: AxiosResponse) => {
|
|
|
|
return Promise.reject(response?.data || response?.headers.error)
|
|
|
|
return Promise.reject(response?.data || response?.headers.error)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (delay <= 0) {
|
|
|
|
if (delay <= 0) {
|
|
|
|
return proxy.request(config as any)
|
|
|
|
return client.request(config as any)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// 延时处理
|
|
|
|
// 延时处理
|
|
|
|
return new Promise<void>((resolve) => {
|
|
|
|
return new Promise<void>((resolve) => {
|
|
|
@ -133,13 +127,17 @@ const requestRetry = (delay = 0, response: AxiosResponse) => {
|
|
|
|
resolve();
|
|
|
|
resolve();
|
|
|
|
}, delay)
|
|
|
|
}, delay)
|
|
|
|
}).then(() => {
|
|
|
|
}).then(() => {
|
|
|
|
return proxy.request(config as any)
|
|
|
|
return client.request(config as any)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
proxy.interceptors.response.use(responseSuccess, responseFailed)
|
|
|
|
const create_client = (client: AxiosInstance) => {
|
|
|
|
|
|
|
|
client.interceptors.request.use(beforeRequest)
|
|
|
|
|
|
|
|
client.interceptors.response.use(responseSuccess(client), responseFailed(client))
|
|
|
|
|
|
|
|
return client
|
|
|
|
|
|
|
|
}
|
|
|
|
interface data {
|
|
|
|
interface data {
|
|
|
|
json?: any
|
|
|
|
json?: any
|
|
|
|
query?: any
|
|
|
|
query?: any
|
|
|
@ -147,6 +145,7 @@ interface data {
|
|
|
|
header?: any
|
|
|
|
header?: any
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function transData(d: data) {
|
|
|
|
function transData(d: data) {
|
|
|
|
let opts = { params: d.query, data: {}, headers: {} as any }
|
|
|
|
let opts = { params: d.query, data: {}, headers: {} as any }
|
|
|
|
if (d.form) {
|
|
|
|
if (d.form) {
|
|
|
@ -164,24 +163,31 @@ function transData(d: data) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export const webapi = {
|
|
|
|
export const webapi = {
|
|
|
|
|
|
|
|
client: create_client(axios.create({
|
|
|
|
|
|
|
|
withCredentials: true,
|
|
|
|
|
|
|
|
baseURL: "/api/",
|
|
|
|
|
|
|
|
headers: {
|
|
|
|
|
|
|
|
'content-type': 'application/json;charset=UTF-8',
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
})),
|
|
|
|
Get<T>(url: string, req: data): Promise<T> {
|
|
|
|
Get<T>(url: string, req: data): Promise<T> {
|
|
|
|
return proxy.request<T, any>(Object.assign({ method: 'get', url: url }, transData(req)))
|
|
|
|
return webapi.client.request<T, any>(Object.assign({ method: 'get', url: url }, transData(req)))
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Head<T>(url: string, req: data): Promise<T> {
|
|
|
|
Head<T>(url: string, req: data): Promise<T> {
|
|
|
|
return proxy.request<T, any>(Object.assign({ method: 'head', url: url }, transData(req)))
|
|
|
|
return webapi.client.request<T, any>(Object.assign({ method: 'head', url: url }, transData(req)))
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Delete<T>(url: string, req: data): Promise<T> {
|
|
|
|
Delete<T>(url: string, req: data): Promise<T> {
|
|
|
|
return proxy.request<T, any>(Object.assign({ method: 'delete', url: url }, transData(req)))
|
|
|
|
return webapi.client.request<T, any>(Object.assign({ method: 'delete', url: url }, transData(req)))
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
Post<T>(url: string, req: data): Promise<T> {
|
|
|
|
Post<T>(url: string, req: data): Promise<T> {
|
|
|
|
return proxy.request<T, any>(Object.assign({ method: 'post', url: url }, transData(req)))
|
|
|
|
return webapi.client.request<T, any>(Object.assign({ method: 'post', url: url }, transData(req)))
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Put<T>(url: string, req: data): Promise<T> {
|
|
|
|
Put<T>(url: string, req: data): Promise<T> {
|
|
|
|
return proxy.request<T, any>(Object.assign({ method: 'put', url: url }, transData(req)))
|
|
|
|
return webapi.client.request<T, any>(Object.assign({ method: 'put', url: url }, transData(req)))
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Patch<T>(url: string, req: data): Promise<T> {
|
|
|
|
Patch<T>(url: string, req: data): Promise<T> {
|
|
|
|
return proxy.request<T, any>(Object.assign({ method: 'patch', url: url }, transData(req)))
|
|
|
|
return webapi.client.request<T, any>(Object.assign({ method: 'patch', url: url }, transData(req)))
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|