Files
Ticket/web/src/api/http.ts
T
2026-05-19 15:12:58 +08:00

88 lines
2.7 KiB
TypeScript
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, { AxiosError } from 'axios'
import { appEnv } from '@/config/env'
import type { ApiResult } from '@/types/http'
import { BizError } from '@/types/http'
import { redirectToLogin } from '@/utils/auth-session'
import { appMessage } from '@/utils/message'
import { useAuthStore } from '@/stores/auth'
const AUTH_ERROR_CODES = new Set([
'AUTH.UNAUTHORIZED',
'AUTH.TOKEN_VERSION_INVALID',
'AUTH.USER_DISABLED',
'AUTH.USERNAME_OR_PASSWORD_INVALID'
])
const http = axios.create({
baseURL: appEnv.apiBaseUrl,
timeout: 15000
})
http.interceptors.request.use((config) => {
const authStore = useAuthStore()
const token = authStore.token
if (token) {
config.headers.Authorization = `Bearer ${token}`
}
return config
})
http.interceptors.response.use(
async (response) => {
const payload = response.data as ApiResult<unknown>
const traceId = response.headers['x-trace-id'] as string | undefined
if (!payload || typeof payload.code !== 'string') {
return response.data
}
if (payload.code === '0') {
return payload.data
}
const errorMessage = payload.message || '请求失败'
const resolvedTraceId = payload.traceId ?? traceId
if (AUTH_ERROR_CODES.has(payload.code)) {
await redirectToLogin('expired')
appMessage.warning(errorMessage)
throw new BizError(payload.code, errorMessage, resolvedTraceId)
}
appMessage.error(
resolvedTraceId ? `${errorMessage}(追踪ID${resolvedTraceId}` : errorMessage
)
throw new BizError(payload.code, errorMessage, resolvedTraceId)
},
async (error: AxiosError<ApiResult<unknown>>) => {
const status = error.response?.status
const traceId =
(error.response?.headers?.['x-trace-id'] as string | undefined) ??
error.response?.data?.traceId
const backendMessage = error.response?.data?.message
if (status === 401) {
const errorMessage = backendMessage ?? '未登录或登录已失效,请重新登录'
await redirectToLogin('expired')
appMessage.warning(errorMessage)
return Promise.reject(new BizError('401', errorMessage, traceId))
}
if (status === 403) {
const errorMessage = backendMessage ?? '无权限访问该资源'
console.warn('[HTTP] 收到 403 响应', {
url: error.config?.url,
message: backendMessage
})
appMessage.error(errorMessage)
return Promise.reject(new BizError('403', errorMessage, traceId))
}
const errorMessage = backendMessage ?? error.message ?? '网络异常,请稍后重试'
appMessage.error(traceId ? `${errorMessage}(追踪ID${traceId}` : errorMessage)
return Promise.reject(new BizError(String(status ?? 'HTTP_ERROR'), errorMessage, traceId))
}
)
export default http