import { getStorage } from '@/utils/storage' export interface ApiResponse { code: number msg: string data: T } function showError(msg: string): Promise { // 不使用 Vant showToast(在非组件上下文中不可靠),直接用 DOM 插入 const el = document.createElement('div') el.textContent = msg el.style.cssText = 'position:fixed;z-index:99999;top:44%;left:50%;transform:translate(-50%,-50%);' + 'background:rgba(0,0,0,.8);color:#fff;padding:12px 24px;border-radius:8px;' + 'font-size:14px;max-width:70vw;text-align:center;white-space:pre-wrap;' + 'box-shadow:0 4px 12px rgba(0,0,0,.15);' document.body.appendChild(el) setTimeout(() => el.remove(), 2500) return new Promise((resolve) => setTimeout(resolve, 150)) } export async function request(url: string, options?: RequestInit): Promise> { const token = getStorage('token') const headers: Record = { 'Content-Type': 'application/json', ...(token ? {Authorization: `Bearer ${token}`} : {}), } const baseUrl = import.meta.env.VITE_API_BASE || '/dgapi' let res: Response try { res = await fetch(`${baseUrl}${url}`, { ...options, headers: {...headers, ...(options?.headers as Record || {})}, }) } catch { await showError('网络连接失败,请检查网络') throw new Error('网络连接失败') } // HTTP 状态码错误(500、404 等) if (!res.ok) { let errMsg = '' try { const body = await res.json() errMsg = body.msg } catch { // 响应体不是 JSON(如 HTML 错误页) } if (!errMsg) { errMsg = `服务器开小差了 (${res.status})` } await showError(errMsg) throw new Error(errMsg) } // 业务错误码 let json: ApiResponse try { json = await res.json() } catch { await showError('数据解析失败') throw new Error('数据解析失败') } if (json.code !== 200) { const errMsg = json.msg || '请求失败' await showError(errMsg) throw new Error(errMsg) } return json }