Files
geMoldInsight/frontend/src/shared/api.ts
T
2026-05-29 17:30:26 +08:00

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