/** * 统一请求封装(基于 Nuxt 内置 ofetch) * * 与 dashboard 后端约定响应格式:{ code, msg, data } * - code = 1:成功 * - code = 0:业务错误 * - code = 2:无数据 */ import { resolveAssetUrls } from '~/utils/resolveAssetUrl'; export interface ApiResponse { code: number; msg: string; data: T | null; } export class ApiError extends Error { code: number; constructor(msg: string, code: number) { super(msg); this.code = code; } } export function useRequest() { const config = useRuntimeConfig(); const baseURL = config.public.apiBaseUrl as string; async function request(url: string, options?: Parameters[1]): Promise { const res = await $fetch>(url, { baseURL, ...options }); if (res.code === 0) { throw new ApiError(res.msg || '请求失败', res.code); } // code = 2(无数据)时 data 为 null,正常返回 // 统一解析 *_url / *_path 字段中的相对路径(如 /uploads/...)为完整资源地址 return resolveAssetUrls(res.data); } function get(url: string, params?: Record) { return request(url, { method: 'GET', params }); } function post(url: string, body?: Record) { return request(url, { method: 'POST', body }); } /** POST multipart/form-data(文件上传;ofetch 自动设置 boundary) */ function postForm(url: string, body: FormData) { return request(url, { method: 'POST', body }); } return { request, get, post, postForm }; }