Files
cz-app/src/utils/request.ts
2026-09-20 17:00:55 +08:00

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 })
}