2026-05-01 00:14:08 +08:00

106 lines
2.5 KiB
JavaScript

import { API_BASE_URL } from "../config/env.js";
const TOKEN_KEY = "hyapp-admin.access-token";
let accessToken = window.localStorage.getItem(TOKEN_KEY) || "";
let refreshHandler = null;
let unauthorizedHandler = null;
export function getAccessToken() {
return accessToken;
}
export function setAccessToken(token) {
accessToken = token || "";
if (accessToken) {
window.localStorage.setItem(TOKEN_KEY, accessToken);
} else {
window.localStorage.removeItem(TOKEN_KEY);
}
}
export function setRefreshHandler(handler) {
refreshHandler = handler;
}
export function setUnauthorizedHandler(handler) {
unauthorizedHandler = handler;
}
export async function apiRequest(path, options = {}) {
const {
body,
headers = {},
method = body ? "POST" : "GET",
query,
retry = true,
raw = false,
skipAuth = false
} = options;
const url = buildURL(path, query);
const requestHeaders = { ...headers };
if (body !== undefined && !(body instanceof FormData)) {
requestHeaders["Content-Type"] = "application/json";
}
if (accessToken && !skipAuth) {
requestHeaders.Authorization = `Bearer ${accessToken}`;
}
const response = await fetch(url, {
method,
headers: requestHeaders,
body: body === undefined ? undefined : body instanceof FormData ? body : JSON.stringify(body),
credentials: "include"
});
if (response.status === 401 && retry && refreshHandler && !skipAuth) {
const refreshed = await refreshHandler();
if (refreshed) {
return apiRequest(path, { ...options, retry: false });
}
}
if (response.status === 401 && unauthorizedHandler && !skipAuth) {
unauthorizedHandler();
}
if (raw) {
if (!response.ok) {
throw new Error(response.statusText || "请求失败");
}
return response;
}
const payload = await readJSON(response);
if (!response.ok || payload.code !== 0) {
throw new Error(payload.message || response.statusText || "请求失败");
}
return payload.data;
}
function buildURL(path, query) {
const url = new URL(`${API_BASE_URL}${path}`, window.location.origin);
if (query) {
Object.entries(query).forEach(([key, value]) => {
if (value !== undefined && value !== null && value !== "") {
url.searchParams.set(key, value);
}
});
}
return url.toString();
}
async function readJSON(response) {
const text = await response.text();
if (!text) {
return {};
}
try {
return JSON.parse(text);
} catch {
return { code: response.ok ? 0 : response.status, message: text, data: text };
}
}