import Taro from '@tarojs/taro'; import { getApiBaseUrl } from './config'; export interface RequestOptions { url: string; method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE'; data?: Record; params?: Record; header?: Record; } function buildQueryString(params?: Record): string { if (!params) return ''; const entries = Object.entries(params).filter( ([, v]) => v !== undefined && v !== null && v !== '' ); if (entries.length === 0) return ''; const qs = entries .map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`) .join('&'); return `?${qs}`; } export async function request(options: RequestOptions): Promise { const token = Taro.getStorageSync('token'); const baseUrl = getApiBaseUrl(); const queryString = buildQueryString(options.params); const fullUrl = `${baseUrl}${options.url}${queryString}`; const header: Record = { 'Content-Type': 'application/json', ...options.header, }; if (token) { header['Authorization'] = `Bearer ${token}`; } try { const res = await Taro.request({ url: fullUrl, method: options.method || 'GET', data: options.data, header, timeout: 15000, }); if (res.statusCode === 401) { console.warn('[Request] 401 未授权,清除登录状态'); Taro.removeStorageSync('token'); Taro.removeStorageSync('refreshToken'); Taro.removeStorageSync('user'); Taro.reLaunch({ url: '/pages/login/index' }); throw new Error('登录已过期,请重新登录'); } if (res.statusCode >= 400) { const errMsg = (res.data && typeof res.data === 'object' && 'message' in res.data ? String((res.data as { message: unknown }).message) : null) || `请求失败 (${res.statusCode})`; console.error(`[Request] ${options.method || 'GET'} ${options.url} 失败:`, res.statusCode, res.data); throw new Error(errMsg); } return res.data as T; } catch (error) { if (error instanceof Error && error.message === '登录已过期,请重新登录') { throw error; } console.error(`[Request] ${options.method || 'GET'} ${options.url} 异常:`, error); throw error; } } export function get(url: string, params?: Record): Promise { return request({ url, method: 'GET', params }); } export function post( url: string, data?: Record ): Promise { return request({ url, method: 'POST', data }); } export function patch( url: string, data?: Record ): Promise { return request({ url, method: 'PATCH', data }); } export function del(url: string): Promise { return request({ url, method: 'DELETE' }); }