|
|
import { getToken, setToken } from '@/store/system.ts' import { IApiResult } from '@/global' import { Record } from '@icon-park/react' import { message } from 'antd' import axios, { AxiosRequestConfig, AxiosInstance, AxiosResponse, } from 'axios'
export type { AxiosRequestConfig } type FetchMethod = <T = any, D = any>(url: string, data?: D, config?: AxiosRequestConfig<D>) => Promise<IApiResult<T>>
interface RequestMethods extends Pick<AxiosInstance, 'get' | 'post' | 'put' | 'delete' | 'request' | 'postForm' | 'patch' | 'patchForm' | 'putForm' | 'options'> { download: (url: string, data?: any) => Promise<BlobPart> }
const axiosInstance = axios.create({ baseURL: '/api/v1', // timeout: 1000,
headers: { 'Content-Type': 'application/json', }, validateStatus: status => { return status >= 200 && status < 300 } })
//拦截request,添加token
axiosInstance.interceptors.request.use((config) => {
const token = getToken() if (token) { config.headers.Authorization = `Bearer ${token}` }
return config }, (error) => { console.log('error', error) return Promise.reject(error) })
//拦截response,返回data
axiosInstance.interceptors.response.use( (response) => { // console.log('response', response.data)
message.destroy()
const result = response.data as IApiResult switch (result.code) { case 0: case 200: //login
if (response.config.url?.includes('/sys/login')) { setToken(result.data.token) const search = new URLSearchParams(window.location.search) // eslint-disable-next-line no-case-declarations
const redirect = search.get('redirect') if (redirect) { window.location.href = redirect } } return response case 401: setToken('') if (window.location.pathname === '/login') { return Promise.reject(new Error('to login')) }
// 401: 未登录
message.error('登录失败,跳转重新登录') // eslint-disable-next-line no-case-declarations
const search = new URLSearchParams(window.location.search) // eslint-disable-next-line no-case-declarations
let redirect = window.location.pathname if (search.toString() !== '') { redirect = window.location.pathname + '?=' + search.toString() } window.location.href = `/login?redirect=${encodeURIComponent(redirect)}` return Promise.reject(new Error('to login')) default: message.error(result.message ?? '请求失败') return Promise.reject(response) }
}, (error) => { // console.log('error', error)
message.destroy() const { response } = error if (response) { switch (response.status) { case 401: if (window.location.pathname === '/login') { return }
setToken('') // 401: 未登录
message.error('登录失败,跳转重新登录') // eslint-disable-next-line no-case-declarations
const search = new URLSearchParams(window.location.search) // eslint-disable-next-line no-case-declarations
let redirect = window.location.pathname if (search.toString() !== '') { redirect = window.location.pathname + '?=' + search.toString() } window.location.href = `/login?redirect=${encodeURIComponent(redirect)}` return case 403: message.error('没有权限') break case 404: message.error('请求的资源不存在') break default: message.error(response.data.message ?? response.data ?? error.message ?? '请求失败') return Promise.reject(response) } }
return Promise.reject(error) })
//扩展download方法
// @ts-ignore fix download
axiosInstance.download = (url: string, data?: any) => { const formData = new FormData() for (const key in data) { formData.append(key, data[key]) } const config = { method: 'post', url, data: formData, responseType: 'blob', timeout: 40 * 1000, } as AxiosRequestConfig return axiosInstance.request(config) }
//创建返回IApiResult类型的request
export const createFetchMethods = () => { const methods = {}
for (const method of Object.keys(axiosInstance)) { methods[method] = async <T = any, D = any>(url: string, data?: D, config?: AxiosRequestConfig<D>) => { config = config ?? {} config.url = url config.method = method const isGet = method === 'get' if (isGet) { config.params = data } else { config.data = data } return axiosInstance(config) .then((response: AxiosResponse<IApiResult<T>>) => { if (response.data.code !== 200 && response.data.code !== 0) { throw new Error(response.data.message) } return response.data as IApiResult<T> }) .catch((err) => { throw err }) } }
return methods as Record<keyof RequestMethods, FetchMethod> }
export const request = createFetchMethods() export default request
|