Files
banban/banban-mini/src/services/api.ts
2026-04-22 17:25:03 +08:00

71 lines
1.9 KiB
TypeScript

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.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<T>(
url: string,
options: {
method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE'
data?: any
headers?: Record<string, string>
} = {}
): Promise<T> {
const token = getToken()
const headers: Record<string, string> = {
'Content-Type': 'application/json',
...options.headers,
}
if (token) {
headers.Authorization = `Bearer ${token}`
}
let response
try {
response = await Taro.request({
url: `${BASE_URL}${url}`,
method: options.method || 'GET',
data: options.data,
header: headers,
timeout: REQUEST_TIMEOUT_MS,
})
} catch (error: any) {
const message = String(error?.errMsg || error?.message || '')
const detail = message.includes('timeout')
? '请求超时,请检查后端服务是否可访问'
: '网络请求失败,请检查后端地址和网络连接'
throw new ApiError(0, detail)
}
if (response.statusCode === 401) {
handleUnauthorized({ redirect: !url.startsWith('/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 }