Files

63 lines
2.7 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* =====================================================================
* 网络层(api.js
* 统一调用 /api/* 接口;localStorage 只保存 token 与 username(绝不保存密码)。
* ===================================================================== */
export class ApiError extends Error {
constructor(message, status) {
super(message);
this.status = status;
}
}
export async function api(path, { method = "GET", body } = {}) {
const headers = { "Content-Type": "application/json" };
const token = localStorage.getItem("token");
if (token) headers["Authorization"] = `Bearer ${token}`;
let res;
try {
res = await fetch(path, { method, headers, body: body === undefined ? undefined : JSON.stringify(body) });
} catch (err) {
throw new ApiError("网络请求失败,请稍后再试", 0);
}
let json = null;
try { json = await res.json(); } catch (err) { /* 忽略非 JSON 响应 */ }
if (!json || typeof json.success === "undefined") {
throw new ApiError(`服务器响应异常(${res.status}`, res.status);
}
if (!json.success) throw new ApiError(json.message || "请求失败", res.status);
return json.data;
}
// multipart 表单提交(普通字段 + 单个文件),用于项目管理等
export async function uploadForm(path, fields = {}, file = null, method = "POST") {
const form = new FormData();
for (const [key, value] of Object.entries(fields)) {
if (value !== undefined && value !== null && value !== "") form.append(key, String(value));
}
if (file) form.append("file", file);
const headers = {};
const token = localStorage.getItem("token");
if (token) headers["Authorization"] = `Bearer ${token}`;
const res = await fetch(path, { method, headers, body: form });
let json = null;
try { json = await res.json(); } catch (err) { /* 忽略非 JSON 响应 */ }
if (!json || !json.success) throw new ApiError((json && json.message) || "操作失败", res.status);
return json.data;
}
// multipart 上传(头像/图片/项目文件),返回 {url, filename, size}
export async function uploadFile(path, file, extra = {}) {
const form = new FormData();
form.append("file", file);
// extra:附加字段(如上传文档时携带文章分区 category,供后端校验)
for (const [key, value] of Object.entries(extra)) form.append(key, value);
const headers = {};
const token = localStorage.getItem("token");
if (token) headers["Authorization"] = `Bearer ${token}`;
const res = await fetch(path, { method: "POST", headers, body: form });
let json = null;
try { json = await res.json(); } catch (err) { /* 忽略非 JSON 响应 */ }
if (!json || !json.success) throw new ApiError((json && json.message) || "上传失败", res.status);
return json.data;
}