99 lines
2.7 KiB
TypeScript
99 lines
2.7 KiB
TypeScript
import { API_BASE_URL, API_TIMEOUT } from '@/constants/config'
|
|
import { getAccessToken } from '@/utils/auth-storage'
|
|
|
|
export interface RequestOptions {
|
|
url: string
|
|
method?: 'GET' | 'POST' | 'PUT' | 'DELETE'
|
|
data?: object | string
|
|
header?: Record<string, string>
|
|
timeout?: number
|
|
showErrorToast?: boolean
|
|
}
|
|
|
|
export interface ApiResponse<T = unknown> {
|
|
code?: number
|
|
message?: string
|
|
msg?: string
|
|
data?: T
|
|
}
|
|
|
|
function resolveUrl(url: string) {
|
|
if (/^https?:\/\//.test(url))
|
|
return url
|
|
|
|
const path = url.startsWith('/') ? url : `/${url}`
|
|
return `${API_BASE_URL}${path}`
|
|
}
|
|
|
|
function getErrorMessage(response: ApiResponse, fallback: string) {
|
|
return response.message || response.msg || fallback
|
|
}
|
|
|
|
export function request<T = unknown>(options: RequestOptions): Promise<T> {
|
|
const {
|
|
url,
|
|
method = 'GET',
|
|
data,
|
|
header,
|
|
timeout = API_TIMEOUT,
|
|
showErrorToast = true,
|
|
} = options
|
|
|
|
return new Promise((resolve, reject) => {
|
|
const token = getAccessToken()
|
|
uni.request({
|
|
url: resolveUrl(url),
|
|
method,
|
|
data,
|
|
header: {
|
|
'Content-Type': 'application/json',
|
|
...(token ? { Authorization: `Bearer ${token}` } : {}),
|
|
...header,
|
|
},
|
|
timeout,
|
|
success: (res) => {
|
|
const statusCode = res.statusCode
|
|
const body = res.data as ApiResponse<T> | T
|
|
|
|
if (statusCode >= 200 && statusCode < 300) {
|
|
if (body && typeof body === 'object' && 'code' in body) {
|
|
const apiBody = body as ApiResponse<T>
|
|
if (apiBody.code === 0 || apiBody.code === 200) {
|
|
resolve((apiBody.data ?? apiBody) as T)
|
|
return
|
|
}
|
|
|
|
const message = getErrorMessage(apiBody, '请求失败')
|
|
if (showErrorToast)
|
|
uni.showToast({ title: message, icon: 'none' })
|
|
reject(new Error(message))
|
|
return
|
|
}
|
|
|
|
resolve(body as T)
|
|
return
|
|
}
|
|
|
|
const message = `请求失败(${statusCode})`
|
|
if (showErrorToast)
|
|
uni.showToast({ title: message, icon: 'none' })
|
|
reject(new Error(message))
|
|
},
|
|
fail: (error) => {
|
|
const message = error.errMsg || '网络异常,请稍后重试'
|
|
if (showErrorToast)
|
|
uni.showToast({ title: message, icon: 'none' })
|
|
reject(new Error(message))
|
|
},
|
|
})
|
|
})
|
|
}
|
|
|
|
export function get<T = unknown>(url: string, data?: object, options?: Omit<RequestOptions, 'url' | 'method' | 'data'>) {
|
|
return request<T>({ url, method: 'GET', data, ...options })
|
|
}
|
|
|
|
export function post<T = unknown>(url: string, data?: object, options?: Omit<RequestOptions, 'url' | 'method' | 'data'>) {
|
|
return request<T>({ url, method: 'POST', data, ...options })
|
|
}
|