const BASE_URL = import.meta.env.VITE_API_BASE; const MOCK_DELAY = 300; const mock = (data, delay = MOCK_DELAY) => new Promise((resolve) => setTimeout(() => resolve(data), delay)); export const fetchApi = async (url, options = {}) => { const fullUrl = url.startsWith("http") ? url : BASE_URL + url; const token = localStorage.getItem("token"); const config = { headers: { "Content-Type": "application/json", ...(token ? { Authorization: `Bearer ${token}` } : {}), ...options.headers, }, ...options, }; try { const res = await fetch(fullUrl, config); const data = await res.json(); if (!res.ok) { throw new Error(data.message || `请求失败: ${res.status}`); } return data; } catch (error) { console.error(`[API] ${options.method || "GET"} ${fullUrl}`, error); throw error; } }; export const get = (url, params, options = {}) => { const query = params ? "?" + new URLSearchParams(params).toString() : ""; return fetchApi(url + query, { ...options, method: "GET" }); }; export const post = (url, data, options = {}) => fetchApi(url, { ...options, method: "POST", body: JSON.stringify(data), }); export const put = (url, data, options = {}) => fetchApi(url, { ...options, method: "PUT", body: JSON.stringify(data), }); export const del = (url, data, options = {}) => { const config = { ...options, method: "DELETE" }; if (data) config.body = JSON.stringify(data); return fetchApi(url, config); }; export { mock };