UNPKG

@twotwoba/vv-cli

Version:

Easily create Vite + React19/Vue3 web/h5/mini-program/chrome-extension projects.

155 lines (141 loc) 5.44 kB
import { AUTH_KEY } from '@/constant/keys' import type { RequestConfig, ApiResponse, RequestInterceptors } from '@/types/request' /** * 请求封装 */ class Request { // 基础配置 private baseURL: string private timeout: number // 拦截器 private interceptors?: RequestInterceptors constructor(baseUrl: string, interceptors?: RequestInterceptors, timeout = 100000) { this.baseURL = baseUrl this.timeout = timeout this.interceptors = interceptors } // 核心请求方法 private request<T>(options: RequestConfig) { // 合并基础配置 const finalConfig: RequestConfig = { url: this.baseURL + options.url, method: options.method || 'GET', data: options.data || {}, header: options.header || {}, timeout: options.timeout || this.timeout } // 执行请求拦截器 if (this.interceptors?.request) { const interceptorRes = this.interceptors.request(finalConfig) // 支持拦截器返回Promise if (interceptorRes instanceof Promise) { return interceptorRes.then((resolvedConfig) => { return this.sendRequest<T>({ ...finalConfig, ...resolvedConfig }) }) } Object.assign(finalConfig, interceptorRes) } return this.sendRequest<T>(finalConfig) } private sendRequest<T = any>(config: RequestConfig): Promise<ApiResponse<T>> { return new Promise((resolve, reject) => { uni.request({ ...config, success: (res: UniApp.RequestSuccessCallbackResult) => { // HTTP状态码校验 if (res.statusCode !== 200) { uni.showToast({ title: `请求失败:${res.statusCode}`, icon: 'none', duration: 2000 }) reject({ code: res.statusCode, msg: `HTTP错误:${res.statusCode}`, data: null }) return } const responseData = res.data as ApiResponse<T> // 执行响应成功拦截器 if (this.interceptors?.responseSuccess) { const interceptorRes = this.interceptors.responseSuccess(responseData) if (interceptorRes instanceof Promise) { interceptorRes .then((resolvedData) => resolve(resolvedData)) .catch(reject) return } resolve(interceptorRes) return } // 业务状态码校验(根据业务定制) if (responseData.code !== 200) { uni.showToast({ title: responseData.message || '操作失败', icon: 'none', duration: 2000 }) reject(responseData) return } resolve(responseData) }, fail: (err: UniApp.GeneralCallbackResult) => { // 执行响应失败拦截器 if (this.interceptors?.responseFail) { const interceptorErr = this.interceptors.responseFail(err) reject(interceptorErr || err) } else { uni.showToast({ title: err.errMsg || '网络异常', icon: 'none', duration: 2000 }) reject(err) } }, complete: () => { uni.hideLoading() } }) }) } get<T>(url: string, data = {}, options = {}) { return this.request<T>({ url, method: 'GET', data, ...options }) } post<T>(url: string, data = {}, options = {}) { return this.request<T>({ url, method: 'POST', data, ...options }) } put<T>(url: string, data = {}, options = {}) { return this.request<T>({ url, method: 'PUT', data, ...options }) } } const baseURL = import.meta.env.VITE_FETCH_BASE_URL const interceptors: RequestInterceptors = { request: (config) => { const token = uni.getStorageSync(AUTH_KEY) if (token) { config.header = { ...config.header, platform: 'MINI_PROGRAM', Authorization: `Bearer ${token}` } } return config }, // 响应成功拦截器:可统一处理数据 responseSuccess: (data) => { return data }, // 响应失败拦截器:统一处理错误 responseFail: (error) => { console.error('请求失败:', error) return error } } const request = new Request(baseURL, interceptors) export default request