Files
zsglpt/admin-frontend/src/api/client.js

63 lines
1.9 KiB
JavaScript

import axios from 'axios'
import { ElMessage } from 'element-plus'
let lastToastKey = ''
let lastToastAt = 0
function toastErrorOnce(key, message, minIntervalMs = 1500) {
const now = Date.now()
if (key === lastToastKey && now - lastToastAt < minIntervalMs) return
lastToastKey = key
lastToastAt = now
ElMessage.error(message)
}
function getCookie(name) {
const escaped = String(name || '').replace(/([.*+?^${}()|[\]\\])/g, '\\$1')
const match = document.cookie.match(new RegExp(`(?:^|; )${escaped}=([^;]*)`))
return match ? decodeURIComponent(match[1]) : ''
}
export const api = axios.create({
baseURL: '/yuyx/api',
timeout: 30_000,
withCredentials: true,
})
api.interceptors.request.use((config) => {
const method = String(config?.method || 'GET').toUpperCase()
if (!['GET', 'HEAD', 'OPTIONS'].includes(method)) {
const token = getCookie('csrf_token')
if (token) {
config.headers = config.headers || {}
config.headers['X-CSRF-Token'] = token
}
}
return config
})
api.interceptors.response.use(
(response) => response,
(error) => {
const status = error?.response?.status
const payload = error?.response?.data
const message = payload?.error || payload?.message || error?.message || '请求失败'
if (status === 401) {
toastErrorOnce('401', message || '登录已过期,请重新登录', 3000)
const pathname = window.location?.pathname || ''
if (!pathname.startsWith('/yuyx')) window.location.href = '/yuyx'
} else if (status === 403) {
toastErrorOnce('403', message || '需要管理员权限', 5000)
} else if (status) {
toastErrorOnce(`http:${status}:${message}`, message)
} else if (error?.code === 'ECONNABORTED') {
toastErrorOnce('timeout', '请求超时', 3000)
} else {
toastErrorOnce(`net:${message}`, message, 3000)
}
return Promise.reject(error)
},
)