Files
lckt-admin/src/utils/request.js
2025-09-02 22:56:30 +08:00

203 lines
4.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import axios from 'axios' // 引入axios
import { useUserStore } from '@/pinia/modules/user'
import { ElLoading, ElMessage } from 'element-plus'
import { emitter } from '@/utils/bus'
import router from '@/router/index'
const service = axios.create({
baseURL: import.meta.env.VITE_BASE_API,
timeout: 99999
})
let activeAxios = 0
let timer
let loadingInstance
let isLoadingVisible = false
let forceCloseTimer
const showLoading = (
option = {
target: null
}
) => {
const loadDom = document.getElementById('gva-base-load-dom')
activeAxios++
// 清除之前的定时器
if (timer) {
clearTimeout(timer)
}
// 清除强制关闭定时器
if (forceCloseTimer) {
clearTimeout(forceCloseTimer)
}
timer = setTimeout(() => {
// 再次检查activeAxios状态防止竞态条件
if (activeAxios > 0 && !isLoadingVisible) {
if (!option.target) option.target = loadDom
loadingInstance = ElLoading.service(option)
isLoadingVisible = true
// 设置强制关闭定时器防止loading永远不关闭30秒超时
forceCloseTimer = setTimeout(() => {
if (isLoadingVisible && loadingInstance) {
console.warn('Loading强制关闭超时30秒')
loadingInstance.close()
isLoadingVisible = false
activeAxios = 0 // 重置计数器
}
}, 30000)
}
}, 400)
}
const closeLoading = () => {
activeAxios--
if (activeAxios <= 0) {
activeAxios = 0 // 确保不会变成负数
clearTimeout(timer)
if (forceCloseTimer) {
clearTimeout(forceCloseTimer)
forceCloseTimer = null
}
if (isLoadingVisible && loadingInstance) {
loadingInstance.close()
isLoadingVisible = false
}
loadingInstance = null
}
}
// 全局重置loading状态的函数用于异常情况
const resetLoading = () => {
activeAxios = 0
isLoadingVisible = false
if (timer) {
clearTimeout(timer)
timer = null
}
if (forceCloseTimer) {
clearTimeout(forceCloseTimer)
forceCloseTimer = null
}
if (loadingInstance) {
try {
loadingInstance.close()
} catch (e) {
console.warn('关闭loading时出错:', e)
}
loadingInstance = null
}
}
// http request 拦截器
service.interceptors.request.use(
(config) => {
if (!config.donNotShowLoading) {
showLoading(config.loadingOption)
}
const userStore = useUserStore()
config.headers = {
'Content-Type': 'application/json',
'x-token': userStore.token,
'x-user-id': userStore.userInfo.ID,
...config.headers
}
return config
},
(error) => {
if (!error.config.donNotShowLoading) {
closeLoading()
}
emitter.emit('show-error', {
code: 'request',
message: error.message || '请求发送失败'
})
return error
}
)
function getErrorMessage(error) {
return error.response?.data?.msg || '请求失败'
}
// http response 拦截器
service.interceptors.response.use(
(response) => {
const userStore = useUserStore()
if (!response.config.donNotShowLoading) {
closeLoading()
}
if (response.headers['new-token']) {
userStore.setToken(response.headers['new-token'])
}
if (typeof response.data.code === 'undefined') {
return response
}
if (response.data.code === 0 || response.headers.success === 'true') {
if (response.headers.msg) {
response.data.msg = decodeURI(response.headers.msg)
}
return response.data
} else {
ElMessage({
showClose: true,
message: response.data.msg || decodeURI(response.headers.msg),
type: 'error'
})
return response.data.msg ? response.data : response
}
},
(error) => {
if (!error.config.donNotShowLoading) {
closeLoading()
}
if (!error.response) {
// 网络错误
resetLoading()
emitter.emit('show-error', {
code: 'network',
message: getErrorMessage(error)
})
return Promise.reject(error)
}
// HTTP 状态码错误
if (error.response.status === 401) {
emitter.emit('show-error', {
code: '401',
message: getErrorMessage(error),
fn: () => {
const userStore = useUserStore()
userStore.ClearStorage()
router.push({ name: 'Login', replace: true })
}
})
return Promise.reject(error)
}
emitter.emit('show-error', {
code: error.response.status,
message: getErrorMessage(error)
})
return Promise.reject(error)
}
)
// 监听页面卸载事件确保loading被正确清理
if (typeof window !== 'undefined') {
window.addEventListener('beforeunload', resetLoading)
window.addEventListener('unload', resetLoading)
}
// 导出service和resetLoading函数
export { resetLoading }
export default service