/** * HTTP请求工具类 * 封装uni.request,统一处理请求和响应 */ import { API_CONFIG } from './config'; import { getToken, handleUnauthorized } from './auth'; /** * 请求配置接口 */ interface RequestConfig { url: string; method?: 'GET' | 'POST' | 'PUT' | 'DELETE'; data?: any; header?: any; timeout?: number; /** 是否跳过添加token,用于免登录接口 */ skipAuth?: boolean; } /** * 响应数据接口 */ interface ResponseData { code: number; message: string; data?: T; } /** * 发起HTTP请求 * @param config 请求配置 * @returns Promise<响应数据> */ export const request = (config: RequestConfig): Promise => { return new Promise((resolve, reject) => { const { url, method = 'GET', data, header = {}, timeout = API_CONFIG.timeout, skipAuth = false } = config; // 构建完整URL let fullUrl = url.startsWith('http') ? url : `${API_CONFIG.baseUrl}${url}`; // 添加token到请求头(skipAuth为true时跳过) if (!skipAuth) { const token = getToken(); if (token) { header['accessToken'] = token; if (API_CONFIG.enableLog) { console.log('[请求拦截] 添加token到请求头:', token.substring(0, 8) + '...'); } } else { if (API_CONFIG.enableLog) { console.warn('[请求拦截] 未找到token,请求将不携带token'); } } } // 添加Content-Type if (!header['Content-Type']) { header['Content-Type'] = 'application/json'; } // 打印请求日志 if (API_CONFIG.enableLog) { console.log(`[请求] ${method} ${fullUrl}`, data); } // 发起请求 uni.request({ url: fullUrl, method, data, header, timeout, success: (res: any) => { // 打印响应日志 if (API_CONFIG.enableLog) { console.log(`[响应] ${method} ${fullUrl}`, res.data); } const responseData = res.data as ResponseData; // 处理HTTP状态码 if (res.statusCode !== 200) { const errorMsg = `请求失败: HTTP ${res.statusCode}`; uni.showToast({ title: errorMsg, icon: 'none' }); reject(new Error(errorMsg)); return; } // 处理业务状态码 if (responseData.code === 200 || responseData.code === 0) { // 成功 if (API_CONFIG.enableLog) { console.log('[响应处理] 业务成功,返回data:', responseData.data); } resolve(responseData.data as T); } else if (responseData.code === 401) { // 未登录或token过期 -> 全局未授权处理(清除登录信息并跳转登录页) handleUnauthorized(); reject(new Error(responseData.message || '未登录')); } else { // 业务错误 const errorMsg = responseData.message || '操作失败'; uni.showToast({ title: errorMsg, icon: 'none' }); reject(new Error(errorMsg)); } }, fail: (err: any) => { // 网络错误 console.error(`[请求失败] ${method} ${fullUrl}`, err); let errorMsg = '网络请求失败'; if (err.errMsg) { if (err.errMsg.includes('timeout')) { errorMsg = '请求超时,请检查网络'; } else if (err.errMsg.includes('fail')) { errorMsg = '网络连接失败,请检查网络'; } } uni.showToast({ title: errorMsg, icon: 'none' }); reject(new Error(errorMsg)); } }); }); }; /** * GET请求 */ export const get = (url: string, data?: any, options?: { skipAuth?: boolean }): Promise => { return request({ url, method: 'GET', data, ...options }); }; /** * POST请求 */ export const post = (url: string, data?: any): Promise => { return request({ url, method: 'POST', data }); }; /** * PUT请求 */ export const put = (url: string, data?: any): Promise => { return request({ url, method: 'PUT', data }); }; /** * DELETE请求 */ export const del = (url: string, data?: any): Promise => { return request({ url, method: 'DELETE', data }); };