2024-11-19 13:46:35 +08:00
|
|
|
import type { AxiosInstance, AxiosRequestConfig } from "axios"
|
2024-11-14 17:33:12 +08:00
|
|
|
import { useUserStore } from "@/store/modules/user"
|
2024-11-19 13:46:35 +08:00
|
|
|
import axios from "axios"
|
2022-05-05 17:18:58 +08:00
|
|
|
import { ElMessage } from "element-plus"
|
2023-06-06 18:15:29 +08:00
|
|
|
import { get, merge } from "lodash-es"
|
2022-10-18 15:07:42 +08:00
|
|
|
import { getToken } from "./cache/cookies"
|
2022-04-21 18:20:39 +08:00
|
|
|
|
2023-07-21 15:50:23 +08:00
|
|
|
/** 退出登录并强制刷新页面(会重定向到登录页) */
|
|
|
|
function logout() {
|
2024-11-14 17:33:12 +08:00
|
|
|
useUserStore().logout()
|
2023-07-21 15:50:23 +08:00
|
|
|
location.reload()
|
|
|
|
}
|
|
|
|
|
2022-04-21 18:20:39 +08:00
|
|
|
/** 创建请求实例 */
|
|
|
|
function createService() {
|
2023-06-06 18:15:29 +08:00
|
|
|
// 创建一个 axios 实例命名为 service
|
2022-04-21 18:20:39 +08:00
|
|
|
const service = axios.create()
|
|
|
|
// 请求拦截
|
|
|
|
service.interceptors.request.use(
|
2024-11-18 19:40:44 +08:00
|
|
|
config => config,
|
2022-04-21 18:20:39 +08:00
|
|
|
// 发送失败
|
2024-11-18 19:40:44 +08:00
|
|
|
error => Promise.reject(error)
|
2022-04-21 18:20:39 +08:00
|
|
|
)
|
|
|
|
// 响应拦截(可根据具体业务作出相应的调整)
|
|
|
|
service.interceptors.response.use(
|
|
|
|
(response) => {
|
2023-06-06 18:15:29 +08:00
|
|
|
// apiData 是 api 返回的数据
|
|
|
|
const apiData = response.data
|
2023-06-08 09:45:23 +08:00
|
|
|
// 二进制数据则直接返回
|
2023-06-08 13:39:06 +08:00
|
|
|
const responseType = response.request?.responseType
|
2024-11-19 13:46:35 +08:00
|
|
|
if (responseType === "blob" || responseType === "arraybuffer") return apiData
|
2023-06-06 18:15:29 +08:00
|
|
|
// 这个 code 是和后端约定的业务 code
|
2022-04-21 18:20:39 +08:00
|
|
|
const code = apiData.code
|
2023-06-06 18:15:29 +08:00
|
|
|
// 如果没有 code, 代表这不是项目后端开发的 api
|
2022-04-21 18:20:39 +08:00
|
|
|
if (code === undefined) {
|
2022-04-22 01:16:02 +08:00
|
|
|
ElMessage.error("非本系统的接口")
|
|
|
|
return Promise.reject(new Error("非本系统的接口"))
|
2023-06-06 18:15:29 +08:00
|
|
|
}
|
|
|
|
switch (code) {
|
|
|
|
case 0:
|
|
|
|
// 本系统采用 code === 0 来表示没有业务错误
|
|
|
|
return apiData
|
2023-07-21 15:50:23 +08:00
|
|
|
case 401:
|
|
|
|
// Token 过期时
|
|
|
|
return logout()
|
2023-06-06 18:15:29 +08:00
|
|
|
default:
|
|
|
|
// 不是正确的 code
|
|
|
|
ElMessage.error(apiData.message || "Error")
|
|
|
|
return Promise.reject(new Error("Error"))
|
2022-04-21 18:20:39 +08:00
|
|
|
}
|
|
|
|
},
|
|
|
|
(error) => {
|
2023-06-06 18:15:29 +08:00
|
|
|
// status 是 HTTP 状态码
|
2022-04-22 01:16:02 +08:00
|
|
|
const status = get(error, "response.status")
|
2022-04-21 18:20:39 +08:00
|
|
|
switch (status) {
|
|
|
|
case 400:
|
2022-04-22 01:16:02 +08:00
|
|
|
error.message = "请求错误"
|
2022-04-21 18:20:39 +08:00
|
|
|
break
|
|
|
|
case 401:
|
2023-07-21 15:50:23 +08:00
|
|
|
// Token 过期时
|
|
|
|
logout()
|
2022-04-21 18:20:39 +08:00
|
|
|
break
|
2022-08-15 16:05:26 +08:00
|
|
|
case 403:
|
|
|
|
error.message = "拒绝访问"
|
|
|
|
break
|
2022-04-21 18:20:39 +08:00
|
|
|
case 404:
|
2022-04-22 01:16:02 +08:00
|
|
|
error.message = "请求地址出错"
|
2022-04-21 18:20:39 +08:00
|
|
|
break
|
|
|
|
case 408:
|
2022-04-22 01:16:02 +08:00
|
|
|
error.message = "请求超时"
|
2022-04-21 18:20:39 +08:00
|
|
|
break
|
|
|
|
case 500:
|
2022-04-22 01:16:02 +08:00
|
|
|
error.message = "服务器内部错误"
|
2022-04-21 18:20:39 +08:00
|
|
|
break
|
|
|
|
case 501:
|
2022-04-22 01:16:02 +08:00
|
|
|
error.message = "服务未实现"
|
2022-04-21 18:20:39 +08:00
|
|
|
break
|
|
|
|
case 502:
|
2022-04-22 01:16:02 +08:00
|
|
|
error.message = "网关错误"
|
2022-04-21 18:20:39 +08:00
|
|
|
break
|
|
|
|
case 503:
|
2022-04-22 01:16:02 +08:00
|
|
|
error.message = "服务不可用"
|
2022-04-21 18:20:39 +08:00
|
|
|
break
|
|
|
|
case 504:
|
2022-04-22 01:16:02 +08:00
|
|
|
error.message = "网关超时"
|
2022-04-21 18:20:39 +08:00
|
|
|
break
|
|
|
|
case 505:
|
2022-08-15 16:05:26 +08:00
|
|
|
error.message = "HTTP 版本不受支持"
|
2022-04-21 18:20:39 +08:00
|
|
|
break
|
|
|
|
default:
|
|
|
|
break
|
|
|
|
}
|
|
|
|
ElMessage.error(error.message)
|
|
|
|
return Promise.reject(error)
|
|
|
|
}
|
|
|
|
)
|
|
|
|
return service
|
|
|
|
}
|
|
|
|
|
|
|
|
/** 创建请求方法 */
|
2023-06-06 18:15:29 +08:00
|
|
|
function createRequest(service: AxiosInstance) {
|
2023-02-02 11:31:17 +08:00
|
|
|
return function <T>(config: AxiosRequestConfig): Promise<T> {
|
2023-06-06 18:15:29 +08:00
|
|
|
const token = getToken()
|
|
|
|
const defaultConfig = {
|
2022-04-21 18:20:39 +08:00
|
|
|
headers: {
|
2022-07-01 16:25:51 +08:00
|
|
|
// 携带 Token
|
2024-11-18 19:40:44 +08:00
|
|
|
"Authorization": token ? `Bearer ${token}` : undefined,
|
2023-06-06 18:15:29 +08:00
|
|
|
"Content-Type": "application/json"
|
2022-04-21 18:20:39 +08:00
|
|
|
},
|
|
|
|
timeout: 5000,
|
2024-11-21 19:50:20 +08:00
|
|
|
baseURL: import.meta.env.VITE_BASE_URL,
|
2022-04-21 18:20:39 +08:00
|
|
|
data: {}
|
|
|
|
}
|
2023-06-06 18:15:29 +08:00
|
|
|
// 将默认配置 defaultConfig 和传入的自定义配置 config 进行合并成为 mergeConfig
|
|
|
|
const mergeConfig = merge(defaultConfig, config)
|
|
|
|
return service(mergeConfig)
|
2022-04-21 18:20:39 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/** 用于网络请求的实例 */
|
2023-06-06 18:15:29 +08:00
|
|
|
const service = createService()
|
2022-04-21 18:20:39 +08:00
|
|
|
/** 用于网络请求的方法 */
|
2023-06-06 18:15:29 +08:00
|
|
|
export const request = createRequest(service)
|