Files
ghatreh_user/src/utils/useAxios.ts
T

235 lines
7.0 KiB
TypeScript
Raw Normal View History

2026-06-29 15:27:35 +03:30
import { getConfigApp } from '@/utils/config'
import { baseURL as fallbackBaseURL } from '@/themeConfig'
2025-10-05 09:44:14 +03:30
import type {AxiosRequestConfig, AxiosResponse} from 'axios'
import axios from 'axios'
import {getToken, removeToken} from "@/utils";
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({
2026-06-29 15:27:35 +03:30
baseURL: fallbackBaseURL,
headers,
2025-10-05 09:44:14 +03:30
})
_axios.interceptors.request.use(
(config) => {
2026-06-29 15:27:35 +03:30
const runtimeBaseURL = getConfigApp('node_server')
if (runtimeBaseURL) {
config.baseURL = runtimeBaseURL
}
2025-10-05 09:44:14 +03:30
//console.log('request config', config)
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) {
2026-06-29 22:43:28 +03:30
const response = error.response
const config = error.config as MyAxiosRequestConfig | undefined
2026-04-09 13:58:37 +03:30
2026-06-29 22:43:28 +03:30
if (response?.status === 401) {
2025-10-05 09:44:14 +03:30
removeToken()
2025-12-21 17:22:27 +03:30
if (router.currentRoute.value.name !== 'buyProduct') {
2026-06-29 22:43:28 +03:30
await router.push({name: 'login'})
2025-12-21 17:22:27 +03:30
}
2026-06-29 22:43:28 +03:30
return Promise.reject(error)
2025-10-05 09:44:14 +03:30
}
2026-06-29 22:43:28 +03:30
if (!shouldShowApiError(config)) {
return Promise.reject(error)
}
const apiMessage = extractApiErrorMessage(response?.data)
const status = Number(response?.status ?? 0)
2026-06-29 22:43:28 +03:30
if (response?.status === 403) {
showApiError(
withHttpStatus(apiMessage || 'شما دسترسی لازم برای انجام این عملیات را ندارید', 403),
config,
)
2026-06-29 22:43:28 +03:30
return Promise.reject(error)
}
if (response?.status === 422) {
if (apiMessage) {
showApiError(withHttpStatus(apiMessage, 422), config)
} else {
showApiError(withHttpStatus('خطا در اعتبارسنجی', 422), config)
2026-06-29 22:43:28 +03:30
}
return Promise.reject(error)
}
if (response) {
if (status >= 500) {
showApiError(withHttpStatus(SERVER_ERROR, status), config)
} else {
showApiError(withHttpStatus(apiMessage || DEFAULT_LOAD_ERROR, status), config)
}
2026-06-29 22:43:28 +03:30
return Promise.reject(error)
}
// بدون status (نه 4xx نه 5xx): قطع شبکه، timeout، DNS، …
showApiError(NETWORK_ERROR, config)
2025-10-05 09:44:14 +03:30
return Promise.reject(error)
})
2026-06-29 22:43:28 +03:30
const DEFAULT_LOAD_ERROR = 'خطا در بارگذاری اطلاعات'
const SERVER_ERROR = 'خطا در برقراری ارتباط با سرور'
const NETWORK_ERROR = 'لطفا اینترنت خود را بررسی کنید و مجددا تلاش کنید'
function withHttpStatus(message: string, status: number): string {
return `${message} (${status})`
}
2026-06-29 22:43:28 +03:30
function extractApiErrorMessage(data: unknown): string {
if (!data || typeof data !== 'object') {
return ''
2025-10-05 09:44:14 +03:30
}
2026-06-29 22:43:28 +03:30
const record = data as Record<string, unknown>
const rawMessage = record.message
if (typeof rawMessage === 'string' && rawMessage.trim()) {
return rawMessage.trim()
}
if (typeof rawMessage === 'number') {
return String(rawMessage)
}
const rawError = record.error
if (typeof rawError === 'string' && rawError.trim()) {
return rawError.trim()
}
const errors = record.errors
if (errors && typeof errors === 'object') {
for (const value of Object.values(errors as Record<string, unknown>)) {
if (Array.isArray(value) && typeof value[0] === 'string' && value[0].trim()) {
return value[0].trim()
}
if (typeof value === 'string' && value.trim()) {
return value.trim()
}
}
}
return ''
2025-10-05 09:44:14 +03:30
}
2026-06-29 22:43:28 +03:30
function shouldShowApiError(config: MyAxiosRequestConfig | undefined): boolean {
return get(config, 'meta.errorMessage', 'message') !== 'none'
}
function showApiError(msg: string, config: MyAxiosRequestConfig | undefined) {
if (!shouldShowApiError(config)) {
return
}
message.error(msg)
}
2025-10-05 09:44:14 +03:30
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}