class Request { constructor() { // 全局默认配置 this.config = { baseURL: import.meta.env.VITE_API_BASE, timeout: 10000, header: { 'Content-Type': 'application/json' } } // 开发环境打印日志 if (import.meta.env.VITE_DEBUG_MODE === 'true') { this._enableDebugLog() } // 拦截器存储 this.interceptors = { request: [], response: [] } // 请求队列(用于取消请求) this.pendingRequests = new Map() } // 调试日志 _enableDebugLog() { const originalRequest = this.request this.request = async function(config) { console.log('[HTTP Request]', config) const start = Date.now() try { const res = await originalRequest.call(this, config) console.log(`[HTTP Response] ${Date.now() - start}ms`, res) return res } catch (err) { console.error(`[HTTP Error] ${Date.now() - start}ms`, err) throw err } } } // 小程序 HTTPS 强制转换 _fixUrlProtocol(url) { // #ifdef MP-WEIXIN return url.replace(/^http:/, 'https:') // #else return url // #endif } // 核心请求方法 async _request(config) { // 合并配置 const mergedConfig = { ...this.config, ...config, url: this._fixUrlProtocol(config.url) } // 生成请求标识 const requestKey = `${mergedConfig.method}-${mergedConfig.url}` const controller = new AbortController() this.pendingRequests.set(requestKey, controller) // 构建完整URL const fullUrl = `${mergedConfig.baseURL}${mergedConfig.url}` return new Promise((resolve, reject) => { uni.request({ ...mergedConfig, url: fullUrl, signal: controller.signal, success: (res) => resolve(res), fail: (err) => reject(err) }) }) } // 执行拦截器链 async _runInterceptors(type, value) { let chain = type === 'request' ? [...this.interceptors.request, this._request, undefined] : [undefined, ...this.interceptors.response] let promise = Promise.resolve(value) for (let i = 0; i < chain.length; i += 2) { const thenFn = chain[i] const catchFn = chain[i + 1] promise = promise.then(thenFn, catchFn) } return promise } // 公开请求方法 async request(config) { try { // 执行请求拦截 const processedConfig = await this._runInterceptors('request', config) // 发起请求 const response = await this._request(processedConfig) // 执行响应拦截 return this._runInterceptors('response', response) } catch (error) { // 统一错误处理 this._handleError(error) return Promise.reject(error) } } // 快捷方法 get(url, config = {}) { return this.request({ ...config, url, method: 'GET' }) } post(url, data, config = {}) { return this.request({ ...config, url, data, method: 'POST' }) } // 错误处理 _handleError(error) { let message = '请求失败' if (error.errMsg?.includes('timeout')) message = '网络超时' if (error.statusCode === 404) message = '接口不存在' uni.showToast({ title: message, icon: 'none' }) } // 取消请求 cancelRequest(url, method = 'GET') { const key = `${method}-${url}` const controller = this.pendingRequests.get(key) controller?.abort() this.pendingRequests.delete(key) } } export const http = new Request()