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 // HTTP 状态码映射 const HTTP_STATUS_MAP = { 400: '请求参数错误', 401: '未授权或登录过期', 403: '访问被禁止', 404: '请求的资源不存在', 500: '服务器内部错误', 502: '网关错误', 503: '服务暂时不可用', 504: '网关超时' } export function setupHttp() { if (http) return http const {token}= codeAuthStore() const config = useRuntimeConfig() const baseURL = config.public.NUXT_PUBLIC_API_COLLECT_CODE const router = useRouter() 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, Authorization: token.value } // GET 请求添加时间戳防止缓存 if (request.toLowerCase().includes('get')) { options.params = { ...options.params, _t: Date.now() } } }, // 响应拦截 async onResponse({ response }) { const data = response._data // 处理业务错误 if (data.status === 1) { message.error(data.msg || '操作失败') } // 处理登录失效 if (data.status === 401) { message.error('登录已过期,请重新登录') token.value = '' // 清除 token router.replace('/collectCode/login') } return response }, // 响应错误处理 async onResponseError({ response, request }) { // 网络错误 if (!response) { message.error('网络连接失败,请检查网络设置') return Promise.reject(new Error('网络错误')) } const status = response.status const data = response._data // 处理 HTTP 状态错误 const errorMessage = data.msg || HTTP_STATUS_MAP[status] || '请求失败' 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) { throw new Error('HTTP client not initialized. Call setupHttp first.') } return http } // 导出请求工具函数 export async function request({url,...options}) { const http = getHttp() try { return await http(url, {...options,body:options.data}) } catch (error) { throw error } }