| 1 | /* |
| 2 | * @Author: nevin |
| 3 | * @Date: 2025-01-17 20:21:04 |
| 4 | * @LastEditTime: 2025-02-27 16:57:37 |
| 5 | * @LastEditors: nevin |
| 6 | * @Description: 请求 |
| 7 | */ |
| 8 | import axios, { AxiosRequestConfig, AxiosResponse } from 'axios'; |
| 9 | import { message } from 'antd'; |
| 10 | import { useUserStore } from '@/store/user'; |
| 11 | |
| 12 | interface ProjectAxiosRequestConfig extends AxiosRequestConfig { |
| 13 | // 是否需要token,默认为true,为false表示不需要token,需要token的接口如果不存在token会被拦截 |
| 14 | isToken?: boolean; |
| 15 | } |
| 16 | |
| 17 | export const getAxiosRequest = (baseURL: string) => { |
| 18 | const MessageKey = 'reqKey'; |
| 19 | |
| 20 | // 创建 axios 实例 |
| 21 | const request = axios.create({ |
| 22 | baseURL, // 从环境变量获取基础URL |
| 23 | timeout: 15000, // 请求超时时间 |
| 24 | headers: { |
| 25 | 'Content-Type': 'application/json', |
| 26 | }, |
| 27 | }); |
| 28 | |
| 29 | // 请求拦截器 |
| 30 | request.interceptors.request.use( |
| 31 | (config) => { |
| 32 | // 获取 token |
| 33 | const token = useUserStore.getState().token; |
| 34 | |
| 35 | // @ts-ignore 如果没有token或者不在白名单内将接口拦截 |
| 36 | if (token === '' && config.isToken !== false) { |
| 37 | console.log('接口拦截:', config.url); |
| 38 | return Promise.reject(); |
| 39 | } |
| 40 | |
| 41 | // @ts-ignore |
| 42 | if (config!.isToken !== false) { |
| 43 | useUserStore.getState().refreshTokenDet(); |
| 44 | } |
| 45 | |
| 46 | config.headers.Authorization = `Bearer ${token}`; |
| 47 | return config; |
| 48 | }, |
| 49 | (error) => { |
| 50 | return Promise.reject(error); |
| 51 | }, |
| 52 | ); |
| 53 | |
| 54 | // 响应拦截器 |
| 55 | request.interceptors.response.use( |
| 56 | (response: AxiosResponse) => { |
| 57 | const { data } = response; |
| 58 | |
| 59 | // 这里可以根据后端的响应结构进行调整 |
| 60 | if (data.code !== 0) { |
| 61 | message.error({ |
| 62 | content: data.message || data.msg || '请求失败', |
| 63 | key: MessageKey, |
| 64 | }); |
| 65 | return Promise.reject(new Error(data.message|| data.msg || '请求失败')); |
| 66 | } |
| 67 | |
| 68 | return data.data; |
| 69 | }, |
| 70 | (error) => { |
| 71 | if (!error) return; |
| 72 | // 处理 HTTP 错误状态 |
| 73 | if (error.response) { |
| 74 | switch (error.response.status) { |
| 75 | case 401: |
| 76 | message.error({ |
| 77 | content: '未授权,请重新登录', |
| 78 | key: MessageKey, |
| 79 | }); |
| 80 | // 可以在这里处理登出逻辑 |
| 81 | setTimeout(() => useUserStore.getState().logout(), 500); |
| 82 | break; |
| 83 | case 403: |
| 84 | message.error({ |
| 85 | key: MessageKey, |
| 86 | content: '拒绝访问', |
| 87 | }); |
| 88 | setTimeout(() => useUserStore.getState().logout(), 500); |
| 89 | break; |
| 90 | case 404: |
| 91 | message.error({ |
| 92 | key: MessageKey, |
| 93 | content: '请求错误,未找到该资源', |
| 94 | }); |
| 95 | break; |
| 96 | case 500: |
| 97 | message.error({ |
| 98 | key: MessageKey, |
| 99 | content: '服务器错误', |
| 100 | }); |
| 101 | break; |
| 102 | default: |
| 103 | message.error({ |
| 104 | key: MessageKey, |
| 105 | content: `连接错误 ${error.response.status}`, |
| 106 | }); |
| 107 | } |
| 108 | } else { |
| 109 | message.error({ |
| 110 | content: '网络异常,请检查网络连接', |
| 111 | key: MessageKey, |
| 112 | }); |
| 113 | } |
| 114 | return Promise.reject(error); |
| 115 | }, |
| 116 | ); |
| 117 | |
| 118 | // 封装通用请求方法 |
| 119 | const http = { |
| 120 | get<T = any>(url: string, config?: ProjectAxiosRequestConfig): Promise<T> { |
| 121 | return request.get(url, config); |
| 122 | }, |
| 123 | |
| 124 | post<T = any>( |
| 125 | url: string, |
| 126 | data?: any, |
| 127 | config?: ProjectAxiosRequestConfig, |
| 128 | ): Promise<T> { |
| 129 | return request.post(url, data, config); |
| 130 | }, |
| 131 | |
| 132 | put<T = any>( |
| 133 | url: string, |
| 134 | data?: any, |
| 135 | config?: ProjectAxiosRequestConfig, |
| 136 | ): Promise<T> { |
| 137 | return request.put(url, data, config); |
| 138 | }, |
| 139 | |
| 140 | delete<T = any>( |
| 141 | url: string, |
| 142 | config?: ProjectAxiosRequestConfig, |
| 143 | ): Promise<T> { |
| 144 | return request.delete(url, config); |
| 145 | }, |
| 146 | }; |
| 147 | |
| 148 | return http; |
| 149 | }; |
| 150 | |
| 151 | export const http = getAxiosRequest(import.meta.env.VITE_APP_URL); |
| 152 | export const hotHttp = getAxiosRequest(import.meta.env.VITE_APP_HOT_URL); |
| 153 | |
| 154 | export default http; |
| 155 |