|
@@ -1,6 +1,9 @@
|
|
|
import axios from 'axios'
|
|
import axios from 'axios'
|
|
|
-// import qs from 'qs'
|
|
|
|
|
import { toast } from 'vue-sonner'
|
|
import { toast } from 'vue-sonner'
|
|
|
|
|
+import type { AxiosRequestConfig } from 'axios'
|
|
|
|
|
+import type {
|
|
|
|
|
+ BaseResponse,
|
|
|
|
|
+} from '@/types'
|
|
|
|
|
|
|
|
// 请求重试配置
|
|
// 请求重试配置
|
|
|
const MAX_RETRY_COUNT = 3 // 最大重试次数
|
|
const MAX_RETRY_COUNT = 3 // 最大重试次数
|
|
@@ -18,6 +21,11 @@ const api = axios.create({
|
|
|
baseURL: (import.meta.env.DEV && import.meta.env.VITE_OPEN_PROXY) ? '/proxy/' : import.meta.env.VITE_APP_API_BASEURL,
|
|
baseURL: (import.meta.env.DEV && import.meta.env.VITE_OPEN_PROXY) ? '/proxy/' : import.meta.env.VITE_APP_API_BASEURL,
|
|
|
timeout: 1000 * 60,
|
|
timeout: 1000 * 60,
|
|
|
responseType: 'json',
|
|
responseType: 'json',
|
|
|
|
|
+ headers: {
|
|
|
|
|
+ Accept: 'application/json',
|
|
|
|
|
+ 'Content-Type': 'application/json',
|
|
|
|
|
+ 'accessToken': 'rcOBHJ0Hb8h5xgM/CWtNd8RBhA6WS4OPyJcxrxk4xPZtzeh5PtRXVDA7Um0NZA6NQmnbnZgWB0nNPb8iCrneQj4badFveWLrFq4LrySto3pIo/Zg1dJubbwmu3Vr1LCbSYyVIFrrgt9PXiA85kb9g38FSG3KTSi3AEY/UgjLNLBtH2+91YXKEy2KRZV3v75f',
|
|
|
|
|
+ },
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
api.interceptors.request.use(
|
|
api.interceptors.request.use(
|
|
@@ -28,6 +36,7 @@ api.interceptors.request.use(
|
|
|
if (request.headers) {
|
|
if (request.headers) {
|
|
|
if (userStore.isLogin) {
|
|
if (userStore.isLogin) {
|
|
|
request.headers.Token = userStore.token
|
|
request.headers.Token = userStore.token
|
|
|
|
|
+ // request.headers.adminToken = userStore.token
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
// 是否将 POST 请求参数进行字符串化处理
|
|
// 是否将 POST 请求参数进行字符串化处理
|
|
@@ -44,22 +53,21 @@ api.interceptors.request.use(
|
|
|
function handleError(error: any) {
|
|
function handleError(error: any) {
|
|
|
if (error.status === 401) {
|
|
if (error.status === 401) {
|
|
|
useUserStore().requestLogout()
|
|
useUserStore().requestLogout()
|
|
|
|
|
+ throw error
|
|
|
}
|
|
}
|
|
|
- else {
|
|
|
|
|
- let message = error.message
|
|
|
|
|
- if (message === 'Network Error') {
|
|
|
|
|
- message = '后端网络故障'
|
|
|
|
|
- }
|
|
|
|
|
- else if (message.includes('timeout')) {
|
|
|
|
|
- message = '接口请求超时'
|
|
|
|
|
- }
|
|
|
|
|
- else if (message.includes('Request failed with status code')) {
|
|
|
|
|
- message = `接口${message.substr(message.length - 3)}异常`
|
|
|
|
|
- }
|
|
|
|
|
- toast.error('Error', {
|
|
|
|
|
- description: message,
|
|
|
|
|
- })
|
|
|
|
|
|
|
+ let message = error.message
|
|
|
|
|
+ if (message === 'Network Error') {
|
|
|
|
|
+ message = '后端网络故障'
|
|
|
|
|
+ }
|
|
|
|
|
+ else if (message.includes('timeout')) {
|
|
|
|
|
+ message = '接口请求超时'
|
|
|
}
|
|
}
|
|
|
|
|
+ else if (message.includes('Request failed with status code')) {
|
|
|
|
|
+ message = `接口${message.substr(message.length - 3)}异常`
|
|
|
|
|
+ }
|
|
|
|
|
+ toast.error('Error', {
|
|
|
|
|
+ description: message,
|
|
|
|
|
+ })
|
|
|
return Promise.reject(error)
|
|
return Promise.reject(error)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -67,10 +75,12 @@ api.interceptors.response.use(
|
|
|
(response) => {
|
|
(response) => {
|
|
|
/**
|
|
/**
|
|
|
* 全局拦截请求发送后返回的数据,如果数据有报错则在这做全局的错误提示
|
|
* 全局拦截请求发送后返回的数据,如果数据有报错则在这做全局的错误提示
|
|
|
- * 假设返回数据格式为:{ status: 1, error: '', data: {} }
|
|
|
|
|
- * 规则是当 status 为 1 时表示请求成功,为 0 时表示接口需要登录或者登录状态失效,需要重新登录
|
|
|
|
|
|
|
+ * 假设返回数据格式为:{code: 0, data: 'DiGJfn3jDc6EQ1KoH/ckj8ZN'}
|
|
|
|
|
+ * 规则是当 status 为 0 时表示请求成功,为 -40 时表示接口需要登录或者登录状态失效,需要重新登录
|
|
|
* 请求出错时 error 会返回错误信息
|
|
* 请求出错时 error 会返回错误信息
|
|
|
*/
|
|
*/
|
|
|
|
|
+ const { code, msg } = response.data
|
|
|
|
|
+ console.log(code, msg)
|
|
|
if (typeof response.data === 'object') {
|
|
if (typeof response.data === 'object') {
|
|
|
if (response.data.status === 1) {
|
|
if (response.data.status === 1) {
|
|
|
if (response.data.error !== '') {
|
|
if (response.data.error !== '') {
|
|
@@ -85,30 +95,74 @@ api.interceptors.response.use(
|
|
|
}
|
|
}
|
|
|
return Promise.resolve(response.data)
|
|
return Promise.resolve(response.data)
|
|
|
}
|
|
}
|
|
|
- else {
|
|
|
|
|
- return Promise.reject(response.data)
|
|
|
|
|
|
|
+
|
|
|
|
|
+ // 成功状态
|
|
|
|
|
+ if (code === 0) {
|
|
|
|
|
+ return Promise.resolve(response.data)
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ handleErrorCode(code, msg)
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ return Promise.reject(response.data)
|
|
|
},
|
|
},
|
|
|
async (error) => {
|
|
async (error) => {
|
|
|
// 获取请求配置
|
|
// 获取请求配置
|
|
|
const config = error.config
|
|
const config = error.config
|
|
|
|
|
+
|
|
|
// 如果配置不存在或未启用重试,则直接处理错误
|
|
// 如果配置不存在或未启用重试,则直接处理错误
|
|
|
if (!config || !config.retry) {
|
|
if (!config || !config.retry) {
|
|
|
return handleError(error)
|
|
return handleError(error)
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
// 设置重试次数
|
|
// 设置重试次数
|
|
|
config.retryCount = config.retryCount || 0
|
|
config.retryCount = config.retryCount || 0
|
|
|
|
|
+
|
|
|
// 判断是否超过重试次数
|
|
// 判断是否超过重试次数
|
|
|
if (config.retryCount >= MAX_RETRY_COUNT) {
|
|
if (config.retryCount >= MAX_RETRY_COUNT) {
|
|
|
return handleError(error)
|
|
return handleError(error)
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
// 重试次数自增
|
|
// 重试次数自增
|
|
|
config.retryCount += 1
|
|
config.retryCount += 1
|
|
|
|
|
+
|
|
|
// 延迟重试
|
|
// 延迟重试
|
|
|
await new Promise(resolve => setTimeout(resolve, RETRY_DELAY))
|
|
await new Promise(resolve => setTimeout(resolve, RETRY_DELAY))
|
|
|
|
|
+
|
|
|
// 重新发起请求
|
|
// 重新发起请求
|
|
|
return api(config)
|
|
return api(config)
|
|
|
},
|
|
},
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
|
|
+// 处理错误 code
|
|
|
|
|
+async function handleErrorCode(code: number, msg: string) {
|
|
|
|
|
+ console.log('EE', code, msg)
|
|
|
|
|
+
|
|
|
|
|
+ if (code === -94) {
|
|
|
|
|
+ // 登录失效,退出登录
|
|
|
|
|
+ useUserStore().requestLogout()
|
|
|
|
|
+ toast.error('Error', {
|
|
|
|
|
+ description: msg,
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+ else if (code === -40) {
|
|
|
|
|
+ // 特殊错误,只显示提示
|
|
|
|
|
+ toast.error('Error', {
|
|
|
|
|
+ description: msg,
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+ else {
|
|
|
|
|
+ // 所有其他业务错误(如 code: -90),只显示错误提示,不退出登录
|
|
|
|
|
+ toast.error('Error', {
|
|
|
|
|
+ description: msg || '请求失败',
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
export default api
|
|
export default api
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+// 封装一个 request 请求,直接返回 BaseResponse
|
|
|
|
|
+export const request = async <T>(url: string, data?:Record<string,any>, config?: AxiosRequestConfig<any> | undefined)=> {
|
|
|
|
|
+ return await api.post(url, data, config) as BaseResponse<T>
|
|
|
|
|
+}
|