2025-02-05 09:00:22 +00:00
|
|
|
import {useRuntimeConfig} from '#app'
|
|
|
|
import {ofetch} from 'ofetch'
|
|
|
|
import {message} from '@/components/x-message/useMessage.js'
|
|
|
|
import {codeAuthStore} from "@/stores-collect-code/auth/index.js"
|
|
|
|
|
|
|
|
let httpStatusErrorHandler
|
|
|
|
let http
|
|
|
|
|
2025-02-26 06:08:04 +00:00
|
|
|
// HTTP 状态码映射 - 使用i18n国际化
|
2025-02-05 09:00:22 +00:00
|
|
|
export function setupHttp() {
|
|
|
|
if (http) return http
|
2025-03-02 06:35:00 +00:00
|
|
|
const {codeToken}= codeAuthStore()
|
2025-02-05 09:00:22 +00:00
|
|
|
const config = useRuntimeConfig()
|
|
|
|
const baseURL = config.public.NUXT_PUBLIC_API_COLLECT_CODE
|
|
|
|
const router = useRouter()
|
2025-02-26 06:08:04 +00:00
|
|
|
const i18n = useNuxtApp().$i18n
|
|
|
|
|
|
|
|
// 国际化的HTTP状态码映射
|
|
|
|
const HTTP_STATUS_MAP = {
|
|
|
|
400: i18n.t('http.error.badRequest'),
|
|
|
|
401: i18n.t('http.error.unauthorized'),
|
|
|
|
403: i18n.t('http.error.forbidden'),
|
|
|
|
404: i18n.t('http.error.notFound'),
|
|
|
|
500: i18n.t('http.error.serverError'),
|
|
|
|
502: i18n.t('http.error.badGateway'),
|
|
|
|
503: i18n.t('http.error.serviceUnavailable'),
|
|
|
|
504: i18n.t('http.error.gatewayTimeout')
|
|
|
|
}
|
2025-02-05 09:00:22 +00:00
|
|
|
|
|
|
|
const defaultOptions = {
|
|
|
|
baseURL,
|
|
|
|
headers: { 'Content-Type': 'application/json' },
|
|
|
|
timeout: 15000, // 15秒超时
|
|
|
|
retry: 3,
|
|
|
|
retryDelay: 1000,
|
|
|
|
}
|
|
|
|
|
|
|
|
http = ofetch.create({
|
|
|
|
...defaultOptions,
|
|
|
|
|
|
|
|
// 请求拦截
|
|
|
|
async onRequest({ options, request }) {
|
|
|
|
// 添加 token
|
|
|
|
options.headers = {
|
|
|
|
...options.headers,
|
2025-03-02 06:35:00 +00:00
|
|
|
Authorization: codeToken.value,
|
2025-02-26 06:08:04 +00:00
|
|
|
'accept-language': i18n.locale.value
|
2025-02-05 09:00:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// GET 请求添加时间戳防止缓存
|
|
|
|
if (request.toLowerCase().includes('get')) {
|
|
|
|
options.params = {
|
|
|
|
...options.params,
|
|
|
|
_t: Date.now()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
// 响应拦截
|
|
|
|
async onResponse({ response }) {
|
|
|
|
const data = response._data
|
|
|
|
|
|
|
|
// 处理业务错误
|
|
|
|
if (data.status === 1) {
|
2025-02-26 06:08:04 +00:00
|
|
|
message.error(data.msg || i18n.t('http.error.operationFailed'))
|
2025-02-05 09:00:22 +00:00
|
|
|
}
|
2025-03-02 09:21:17 +00:00
|
|
|
console.log('拦截响应',data)
|
2025-02-05 09:00:22 +00:00
|
|
|
// 处理登录失效
|
|
|
|
if (data.status === 401) {
|
2025-02-26 06:08:04 +00:00
|
|
|
message.error(i18n.t('http.error.loginExpired'))
|
2025-03-02 09:21:17 +00:00
|
|
|
codeToken.value = '' // 清除 token
|
2025-02-05 09:00:22 +00:00
|
|
|
router.replace('/collectCode/login')
|
|
|
|
}
|
|
|
|
|
|
|
|
return response
|
|
|
|
},
|
|
|
|
|
|
|
|
// 响应错误处理
|
|
|
|
async onResponseError({ response, request }) {
|
|
|
|
// 网络错误
|
|
|
|
if (!response) {
|
2025-02-26 06:08:04 +00:00
|
|
|
message.error(i18n.t('http.error.networkError'))
|
|
|
|
return Promise.reject(new Error(i18n.t('http.error.networkError')))
|
2025-02-05 09:00:22 +00:00
|
|
|
}
|
|
|
|
const status = response.status
|
|
|
|
const data = response._data
|
|
|
|
|
|
|
|
// 处理 HTTP 状态错误
|
2025-02-26 06:08:04 +00:00
|
|
|
const errorMessage = data.msg || HTTP_STATUS_MAP[status] || i18n.t('http.error.requestFailed')
|
2025-02-05 09:00:22 +00:00
|
|
|
|
|
|
|
if (Array.isArray(data.msg)) {
|
|
|
|
data.msg.forEach(item => {
|
|
|
|
httpStatusErrorHandler?.(item, status)
|
|
|
|
})
|
|
|
|
} else {
|
|
|
|
httpStatusErrorHandler?.(errorMessage, status)
|
|
|
|
}
|
|
|
|
|
|
|
|
message.error(errorMessage)
|
|
|
|
return Promise.reject(data)
|
|
|
|
},
|
|
|
|
})
|
|
|
|
|
|
|
|
return http
|
|
|
|
}
|
|
|
|
|
|
|
|
export function createAbortController() {
|
|
|
|
return new AbortController()
|
|
|
|
}
|
|
|
|
|
|
|
|
export function injectHttpStatusErrorHandler(handler) {
|
|
|
|
httpStatusErrorHandler = handler
|
|
|
|
}
|
|
|
|
|
|
|
|
export function getHttp() {
|
|
|
|
if (!http) {
|
2025-02-26 06:08:04 +00:00
|
|
|
throw new Error(useNuxtApp().$i18n.t('http.error.httpNotInitialized'))
|
2025-02-05 09:00:22 +00:00
|
|
|
}
|
|
|
|
return http
|
|
|
|
}
|
|
|
|
|
|
|
|
// 导出请求工具函数
|
|
|
|
export async function request({url,...options}) {
|
|
|
|
const http = getHttp()
|
|
|
|
try {
|
|
|
|
return await http(url, {...options,body:options.data})
|
|
|
|
} catch (error) {
|
|
|
|
throw error
|
|
|
|
}
|
|
|
|
}
|