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 extends AxiosRequestConfig { meta?: Meta } const headers = { 'Content-Type': 'application/json', Accept: 'application/json', } const _axios = axios.create({ baseURL: fallbackBaseURL, headers, }) let sessionVerifyTimer: ReturnType | 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 post( url: string, data?: D, config?: MyAxiosRequestConfig, ): Promise { return _axios.post(url, data, config) }, request, D = any>(config: MyAxiosRequestConfig): Promise { return _axios.request(config) }, //AxiosResponse get(url: string, config?: MyAxiosRequestConfig): Promise { return _axios.get(url, config) }, //AxiosResponse delete(url: string, config?: MyAxiosRequestConfig): Promise { return _axios.delete(url, config) }, //AxiosResponse head(url: string, config?: MyAxiosRequestConfig): Promise { return _axios.head(url, config) }, //AxiosResponse options(url: string, config?: MyAxiosRequestConfig): Promise { return _axios.options(url, config) }, //AxiosResponse put( url: string, data?: D, config?: MyAxiosRequestConfig, ): Promise { return _axios.put(url, data, config) }, //AxiosResponse patch( url: string, data?: D, config?: MyAxiosRequestConfig, ): Promise { return _axios.patch(url, data, config) }, //AxiosResponse postForm( url: string, data?: D, config?: MyAxiosRequestConfig, ): Promise { return _axios.postForm(url, data, config) }, //AxiosResponse putForm( url: string, data?: D, config?: MyAxiosRequestConfig, ): Promise { return _axios.putForm(url, data, config) }, //AxiosResponse patchForm( url: string, data?: D, config?: MyAxiosRequestConfig, ): Promise { return _axios.patchForm(url, data, config) }, } export default myAxios export {_axios}