import Taro from '@tarojs/taro' import { API_BASE_URL } from '@/config/env' import { getCurrentUserId, getToken, handleUnauthorized } from './session' const BASE_URL = API_BASE_URL const REQUEST_TIMEOUT_MS = 10000 class ApiError extends Error { constructor(public status: number, message: string) { super(message) } } function getErrorDetail(data: any): string { if (!data) return 'Request failed' if (typeof data.errMsg === 'string') return data.errMsg if (typeof data.detail === 'string') return data.detail if (Array.isArray(data.detail)) { return data.detail.map((item: any) => String(item?.msg || item)).join('; ') } if (typeof data.message === 'string') return data.message return 'Request failed' } async function request( url: string, options: { method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' data?: any headers?: Record } = {} ): Promise { const token = getToken() const requestUrl = `${BASE_URL}${url}` const requestMethod = options.method || 'GET' const headers: Record = { 'Content-Type': 'application/json', ...options.headers, } if (token) { headers.Authorization = `Bearer ${token}` } let response try { response = await Taro.request({ url: requestUrl, method: requestMethod, data: options.data, header: headers, timeout: REQUEST_TIMEOUT_MS, }) } catch (error: any) { const message = String(error?.errMsg || error?.message || 'request:fail') throw new ApiError(0, message) } if (response.statusCode === 401) { handleUnauthorized({ redirect: !url.startsWith('/banban/auth/') }) } if (response.statusCode >= 400) { throw new ApiError(response.statusCode, getErrorDetail(response.data)) } return response.data as T } export { request, ApiError, BASE_URL } export { getCurrentUserId, getToken }