2025-04-10 11:54:21 +08:00
|
|
|
|
import { getConfig } from './config';
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2025-04-10 17:49:42 +08:00
|
|
|
|
* API响应接口
|
2025-04-10 11:54:21 +08:00
|
|
|
|
*/
|
|
|
|
|
|
export interface ApiResponse<T = any> {
|
|
|
|
|
|
code: number;
|
|
|
|
|
|
msg: string;
|
|
|
|
|
|
data: T | null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2025-04-10 17:49:42 +08:00
|
|
|
|
* API请求函数
|
2025-04-10 11:54:21 +08:00
|
|
|
|
* @param endpoint API端点
|
|
|
|
|
|
* @param method HTTP方法
|
|
|
|
|
|
* @param data 请求数据
|
|
|
|
|
|
* @returns API响应
|
|
|
|
|
|
*/
|
|
|
|
|
|
export async function apiRequest<T = any>(
|
|
|
|
|
|
endpoint: string,
|
|
|
|
|
|
method: 'GET' | 'POST' | 'PUT' | 'DELETE' = 'GET',
|
|
|
|
|
|
data?: any
|
|
|
|
|
|
): Promise<ApiResponse<T>> {
|
2025-04-10 17:49:42 +08:00
|
|
|
|
// 获取API基础URL
|
2025-04-10 11:54:21 +08:00
|
|
|
|
const { apiBaseUrl } = getConfig();
|
|
|
|
|
|
const url = `${apiBaseUrl}${endpoint}`;
|
|
|
|
|
|
|
2025-04-10 17:49:42 +08:00
|
|
|
|
// 构建请求头
|
2025-04-10 11:54:21 +08:00
|
|
|
|
const headers: HeadersInit = {
|
|
|
|
|
|
'Content-Type': 'application/json',
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2025-04-10 17:49:42 +08:00
|
|
|
|
// 添加认证信息(如果有)
|
|
|
|
|
|
if (typeof window !== 'undefined') {
|
|
|
|
|
|
const token = localStorage.getItem('admin_token');
|
|
|
|
|
|
if (token) {
|
|
|
|
|
|
// 设置Cookie中的认证信息
|
|
|
|
|
|
document.cookie = `admin_token=${token}; path=/`;
|
|
|
|
|
|
}
|
2025-04-10 11:54:21 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-04-10 17:49:42 +08:00
|
|
|
|
// 构建请求选项
|
|
|
|
|
|
const options: RequestInit = {
|
2025-04-10 11:54:21 +08:00
|
|
|
|
method,
|
|
|
|
|
|
headers,
|
|
|
|
|
|
credentials: 'include', // 包含跨域请求的Cookie
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2025-04-10 17:49:42 +08:00
|
|
|
|
// 添加请求体(针对POST、PUT请求)
|
|
|
|
|
|
if (method !== 'GET' && data) {
|
|
|
|
|
|
options.body = JSON.stringify(data);
|
2025-04-10 11:54:21 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
2025-04-10 17:49:42 +08:00
|
|
|
|
// 发送请求
|
|
|
|
|
|
const response = await fetch(url, options);
|
2025-04-10 11:54:21 +08:00
|
|
|
|
|
2025-04-10 17:49:42 +08:00
|
|
|
|
// 解析响应
|
|
|
|
|
|
const result = await response.json();
|
2025-04-10 11:54:21 +08:00
|
|
|
|
|
2025-04-10 17:49:42 +08:00
|
|
|
|
// 如果响应状态码不是2xx,或者接口返回的code不是200,抛出错误
|
|
|
|
|
|
if (!response.ok || (result && result.code !== 200)) {
|
|
|
|
|
|
// 如果是认证错误,清除登录信息
|
|
|
|
|
|
if (result.code === 401) {
|
|
|
|
|
|
if (typeof window !== 'undefined') {
|
|
|
|
|
|
localStorage.removeItem('admin_id');
|
|
|
|
|
|
localStorage.removeItem('admin_name');
|
|
|
|
|
|
localStorage.removeItem('admin_account');
|
|
|
|
|
|
localStorage.removeItem('admin_token');
|
|
|
|
|
|
}
|
2025-04-10 11:54:21 +08:00
|
|
|
|
}
|
2025-04-10 17:49:42 +08:00
|
|
|
|
|
|
|
|
|
|
throw result; // 抛出响应结果作为错误
|
2025-04-10 11:54:21 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
|
} catch (error) {
|
2025-04-10 17:49:42 +08:00
|
|
|
|
// 直接抛出错误,由调用方处理
|
|
|
|
|
|
throw error;
|
2025-04-10 11:54:21 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|