Files
boursecu_user/src/utils/useAxios.ts
T
2026-06-27 13:49:00 +03:30

236 lines
6.9 KiB
TypeScript

import { getConfigApp } from '@/utils/config'
import { baseURL as fallbackBaseURL } from '@/themeConfig'
import type {AxiosRequestConfig, AxiosResponse} from 'axios'
import axios from 'axios'
import {getToken, removeToken} from "@/utils";
import { findStoredAuthToken } from '@/utils/authToken';
import router from "@/router";
import {get} from 'lodash'
import {message} from "ant-design-vue";
interface Meta {
errorMessage?: 'message' | 'notification' | 'toast' | 'none'
}
interface MyAxiosRequestConfig<D = any> extends AxiosRequestConfig<D> {
meta?: Meta
}
const headers = {
'Content-Type': 'application/json',
Accept: 'application/json',
}
const _axios = axios.create({
baseURL: fallbackBaseURL,
headers,
})
let sessionVerifyTimer: ReturnType<typeof setTimeout> | null = null
let sessionVerifyInFlight = false
function requestPath(config: { url?: string; baseURL?: string } | undefined): string {
const raw = String(config?.url ?? '')
if (raw.startsWith('http')) {
try {
return new URL(raw).pathname
} catch {
return raw
}
}
return raw
}
async function logoutToLogin() {
removeToken()
if (router.currentRoute.value.name !== 'login') {
await router.push({ name: 'login' })
}
}
function scheduleSessionVerify() {
if (sessionVerifyTimer) {
return
}
sessionVerifyTimer = setTimeout(async () => {
sessionVerifyTimer = null
if (sessionVerifyInFlight) {
return
}
const token = findStoredAuthToken()
if (!token) {
return
}
sessionVerifyInFlight = true
try {
await _axios.get('/customer/me', {
headers: { Authorization: `Bearer ${token}` },
meta: { errorMessage: 'none' },
})
} catch {
await logoutToLogin()
} finally {
sessionVerifyInFlight = false
}
}, 2000)
}
_axios.interceptors.request.use(
(config) => {
const runtimeBaseURL = getConfigApp('node_server')
if (runtimeBaseURL) {
config.baseURL = runtimeBaseURL
}
if (config.headers) {
const token = getToken()
if (token) {
//@ts-ignore
config.headers['Authorization'] = 'Bearer ' + token
}
}
return config
},
(error) => {
//console.log('this is error on interceptors.request', error)
Promise.reject(error)
},
)
_axios.interceptors.response.use(
(response) => {
//console.log('this is response')
// Any status code that lie within the range of 2xx cause this function to trigger
// Do something with response data
//console.log('this is fulfilled on interceptors.response', response.data)
return response.data
},
async function (error) {
const response = error.response
const config = error.config
if (response?.data?.message && response.status !== 401) {
checkStatus(response.data.message, response.status, config)
}
if (response?.status === 401) {
const hadAuth = Boolean(config?.headers?.Authorization)
if (hadAuth) {
const path = requestPath(config)
if (path.includes('/customer/me')) {
await logoutToLogin()
} else {
scheduleSessionVerify()
}
}
} else if (response?.status === 403) {
message.error('شما دسترسی لازم برای انجام این عملیات را ندارید')
} else if (error.response && error.response.status == 422) {
// message.error(error.response.data?.message)
} else if (error.response) {
message.error('خطا در بارگذاری اطلاعات')
}
// Any status codes that falls outside the range of 2xx cause this function to trigger
// Do something with response error
//const { response, code, message, config } = error || {}
//const errorMessageMode = config?.requestOptions?.errorMessageMode || 'none'
//const msg: string = response?.data?.error?.message ?? ''
//checkStatus(error?.response?.status, msg)
return Promise.reject(error)
})
function checkStatus(msg: string, code: number, config: any) {
//const { code, data, message } = data
const errorMessage = get(config, 'meta.errorMessage', 'message')
/*if (config.meta) {
if (config.meta.message) {
errorMessage = config.meta.message
}
}*/
console.log('this is config', config)
if (errorMessage == 'none') return
switch (errorMessage) {
case 'message':
message.error(msg)
break
default:
message.error(msg)
}
}
const myAxios = {
//AxiosResponse<T>
post<T = any, R = T, D = any>(
url: string,
data?: D,
config?: MyAxiosRequestConfig<D>,
): Promise<R> {
return _axios.post(url, data, config)
},
request<T = any, R = AxiosResponse<T>, D = any>(config: MyAxiosRequestConfig<D>): Promise<R> {
return _axios.request(config)
},
//AxiosResponse<T>
get<T = any, R = T, D = any>(url: string, config?: MyAxiosRequestConfig<D>): Promise<R> {
return _axios.get(url, config)
},
//AxiosResponse<T>
delete<T = any, R = T, D = any>(url: string, config?: MyAxiosRequestConfig<D>): Promise<R> {
return _axios.delete(url, config)
},
//AxiosResponse<T>
head<T = any, R = T, D = any>(url: string, config?: MyAxiosRequestConfig<D>): Promise<R> {
return _axios.head(url, config)
},
//AxiosResponse<T>
options<T = any, R = T, D = any>(url: string, config?: MyAxiosRequestConfig<D>): Promise<R> {
return _axios.options(url, config)
},
//AxiosResponse<T>
put<T = any, R = T, D = any>(
url: string,
data?: D,
config?: MyAxiosRequestConfig<D>,
): Promise<R> {
return _axios.put(url, data, config)
},
//AxiosResponse<T>
patch<T = any, R = T, D = any>(
url: string,
data?: D,
config?: MyAxiosRequestConfig<D>,
): Promise<R> {
return _axios.patch(url, data, config)
},
//AxiosResponse<T>
postForm<T = any, R = T, D = any>(
url: string,
data?: D,
config?: MyAxiosRequestConfig<D>,
): Promise<R> {
return _axios.postForm(url, data, config)
},
//AxiosResponse<T>
putForm<T = any, R = T, D = any>(
url: string,
data?: D,
config?: MyAxiosRequestConfig<D>,
): Promise<R> {
return _axios.putForm(url, data, config)
},
//AxiosResponse<T>
patchForm<T = any, R = T, D = any>(
url: string,
data?: D,
config?: MyAxiosRequestConfig<D>,
): Promise<R> {
return _axios.patchForm(url, data, config)
},
}
export default myAxios
export {_axios}