91 lines
2.1 KiB
TypeScript
91 lines
2.1 KiB
TypeScript
import axios, {
|
|
type AxiosInstance,
|
|
type AxiosRequestConfig,
|
|
type AxiosResponse,
|
|
type InternalAxiosRequestConfig
|
|
} from 'axios'
|
|
import { ElMessage } from 'element-plus'
|
|
import NProgress from 'nprogress'
|
|
import { useUserStore } from '@/stores/modules/user'
|
|
|
|
NProgress.configure({ showSpinner: false })
|
|
|
|
/**
|
|
* 后端统一响应结构
|
|
*/
|
|
export interface ApiResponse<T = unknown> {
|
|
code: number
|
|
message: string
|
|
data: T
|
|
}
|
|
|
|
const service: AxiosInstance = axios.create({
|
|
baseURL: import.meta.env.VITE_API_BASE_URL,
|
|
timeout: 15000,
|
|
withCredentials: false
|
|
})
|
|
|
|
// 请求拦截器
|
|
service.interceptors.request.use(
|
|
(config: InternalAxiosRequestConfig) => {
|
|
NProgress.start()
|
|
const userStore = useUserStore()
|
|
if (userStore.token) {
|
|
config.headers.Authorization = `Bearer ${userStore.token}`
|
|
}
|
|
return config
|
|
},
|
|
(error) => {
|
|
NProgress.done()
|
|
return Promise.reject(error)
|
|
}
|
|
)
|
|
|
|
// 响应拦截器
|
|
service.interceptors.response.use(
|
|
(response: AxiosResponse<ApiResponse>) => {
|
|
NProgress.done()
|
|
const { code, message, data } = response.data
|
|
|
|
if (code === 200) {
|
|
return data as any
|
|
}
|
|
|
|
ElMessage.error(message || '请求失败')
|
|
return Promise.reject(new Error(message || 'Error'))
|
|
},
|
|
(error) => {
|
|
NProgress.done()
|
|
const status = error.response?.status
|
|
let message = error.message
|
|
|
|
if (status === 401) {
|
|
message = '登录已过期,请重新登录'
|
|
const userStore = useUserStore()
|
|
userStore.clearAuth()
|
|
// 避免循环依赖,使用 import() 动态加载
|
|
import('@/router').then(({ default: router }) => {
|
|
router.push('/login')
|
|
})
|
|
} else if (status === 403) {
|
|
message = '无权限访问'
|
|
} else if (status === 404) {
|
|
message = '资源不存在'
|
|
} else if (status === 500) {
|
|
message = '服务器内部错误'
|
|
}
|
|
|
|
ElMessage.error(message)
|
|
return Promise.reject(error)
|
|
}
|
|
)
|
|
|
|
/**
|
|
* 统一请求方法封装
|
|
*/
|
|
export function request<T = unknown>(config: AxiosRequestConfig): Promise<T> {
|
|
return service.request<unknown, T>(config)
|
|
}
|
|
|
|
export default service
|