frontend layout and infrastructure
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
import { ApiError } from '@/types/api'
|
||||
|
||||
interface RequestOptions extends RequestInit {
|
||||
params?: Record<string, unknown>
|
||||
}
|
||||
|
||||
async function request<T = unknown>(url: string, options: RequestOptions = {}): Promise<T> {
|
||||
const token = localStorage.getItem('access_token')
|
||||
|
||||
const headers: Record<string, string> = {
|
||||
'Content-Type': 'application/json',
|
||||
...(options.headers as Record<string, string>),
|
||||
}
|
||||
|
||||
if (token) {
|
||||
headers['Authorization'] = `Bearer ${token}`
|
||||
}
|
||||
|
||||
// 拼接查询参数
|
||||
if (options.params) {
|
||||
const query = new URLSearchParams(
|
||||
Object.entries(options.params)
|
||||
.filter(([, v]) => v !== undefined && v !== null && v !== '')
|
||||
.map(([k, v]) => [k, String(v)])
|
||||
)
|
||||
const separator = url.includes('?') ? '&' : '?'
|
||||
url = `${url}${separator}${query}`
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const { params: _params, ...fetchOptions } = options
|
||||
|
||||
const response = await fetch(url, { ...fetchOptions, headers })
|
||||
|
||||
// 401 未授权
|
||||
if (response.status === 401) {
|
||||
localStorage.removeItem('access_token')
|
||||
localStorage.removeItem('refresh_token')
|
||||
localStorage.removeItem('user')
|
||||
window.location.href = '/login'
|
||||
throw new ApiError('登录已过期,请重新登录', 401)
|
||||
}
|
||||
|
||||
const result = await response.json()
|
||||
|
||||
// 业务错误
|
||||
if (result.code !== 0) {
|
||||
throw new ApiError(result.message || '请求失败', result.code)
|
||||
}
|
||||
|
||||
return result.data
|
||||
}
|
||||
|
||||
export const api = {
|
||||
get: <T = unknown>(url: string, params?: Record<string, unknown>) =>
|
||||
request<T>(url, { method: 'GET', params }),
|
||||
|
||||
post: <T = unknown>(url: string, data?: unknown) =>
|
||||
request<T>(url, { method: 'POST', body: JSON.stringify(data) }),
|
||||
|
||||
put: <T = unknown>(url: string, data?: unknown) =>
|
||||
request<T>(url, { method: 'PUT', body: JSON.stringify(data) }),
|
||||
|
||||
patch: <T = unknown>(url: string, data?: unknown) =>
|
||||
request<T>(url, { method: 'PATCH', body: JSON.stringify(data) }),
|
||||
|
||||
delete: <T = unknown>(url: string) =>
|
||||
request<T>(url, { method: 'DELETE' }),
|
||||
}
|
||||
Reference in New Issue
Block a user