62 lines
2.0 KiB
TypeScript
62 lines
2.0 KiB
TypeScript
import { useAppStore } from '@/stores/app'
|
|
|
|
async function parseErrorMessage(response: Response): Promise<string> {
|
|
try {
|
|
const contentType = response.headers.get('content-type') || ''
|
|
if (contentType.includes('application/json')) {
|
|
const body = await response.json().catch(() => null)
|
|
if (body?.detail) {
|
|
if (Array.isArray(body.detail)) {
|
|
const lines = body.detail
|
|
.map((e: { loc?: string[]; msg?: string }) => {
|
|
const loc = Array.isArray(e?.loc) ? e.loc.join('.') : ''
|
|
const msg = e?.msg ? String(e.msg) : '校验失败'
|
|
return loc ? `${loc}: ${msg}` : msg
|
|
})
|
|
.filter(Boolean)
|
|
return lines.length ? lines.join('\n') : '请求校验失败'
|
|
}
|
|
if (typeof body.detail === 'object') return JSON.stringify(body.detail)
|
|
return String(body.detail)
|
|
}
|
|
if (body?.message) return String(body.message)
|
|
return '请求失败'
|
|
}
|
|
const text = await response.text().catch(() => '')
|
|
const normalized = (text || '').trim()
|
|
if (!normalized) return '请求失败'
|
|
return normalized.length > 200 ? normalized.slice(0, 200) + '...' : normalized
|
|
} catch {
|
|
return '请求失败'
|
|
}
|
|
}
|
|
|
|
export async function apiRequest<T = any>(url: string, options: RequestInit = {}): Promise<T> {
|
|
const store = useAppStore()
|
|
const headers: Record<string, string> = {
|
|
'Content-Type': 'application/json',
|
|
...(options.headers as Record<string, string> || {}),
|
|
}
|
|
|
|
if (store.token) {
|
|
headers['Authorization'] = `Bearer ${store.token}`
|
|
}
|
|
|
|
const response = await fetch(url, { ...options, headers })
|
|
|
|
if (response.status === 401) {
|
|
store.user = null
|
|
store.token = null
|
|
localStorage.removeItem('token')
|
|
localStorage.removeItem('user')
|
|
throw new Error('登录已过期,请重新登录')
|
|
}
|
|
|
|
if (!response.ok) {
|
|
const message = await parseErrorMessage(response)
|
|
throw new Error(message)
|
|
}
|
|
|
|
return response.json()
|
|
}
|