// API配置文件 - 统一管理所有API相关配置
|
export const API_CONFIG = {
|
// 基础URL配置
|
BASE_URL: '/api',
|
|
// GraphQL端点
|
GRAPHQL_ENDPOINT: '/api/graphql',
|
|
// 其他API端点
|
ENDPOINTS: {
|
MEDIA_UPLOAD: '/api/media/upload',
|
MEDIA_DOWNLOAD: '/api/media/download',
|
WECHAT_LOGIN: '/api/wechat/login',
|
WECHAT_PHONE: '/api/wechat/phone'
|
}
|
}
|
|
// GraphQL请求工具函数
|
export const graphqlRequest = async (query: string, variables: any = {}) => {
|
// 获取JWT token与工具
|
const { getToken, isTokenExpired, clearAuth } = await import('@/utils/auth');
|
const token = getToken();
|
|
// 若token过期,直接清理并跳登录
|
if (!token || isTokenExpired(token)) {
|
clearAuth();
|
// 避免在登录页重复跳转造成白屏/循环
|
const atLogin = typeof window !== 'undefined' && window.location && window.location.hash?.startsWith('#/login');
|
if (!atLogin) {
|
window.location.href = '/#/login';
|
}
|
throw new Error('Token expired or missing')
|
}
|
|
// 构建请求头
|
const headers: Record<string, string> = {
|
'Content-Type': 'application/json',
|
};
|
|
if (token) {
|
headers['Authorization'] = `Bearer ${token}`;
|
}
|
|
// 构建请求体
|
const requestBody = JSON.stringify({
|
query,
|
variables,
|
});
|
|
try {
|
// 发送请求
|
const response = await fetch(API_CONFIG.GRAPHQL_ENDPOINT, {
|
method: 'POST',
|
headers,
|
body: requestBody,
|
});
|
|
if (!response.ok) {
|
// 处理401未授权
|
if (response.status === 401) {
|
const { clearAuth } = await import('@/utils/auth');
|
clearAuth();
|
const atLogin = typeof window !== 'undefined' && window.location && window.location.hash?.startsWith('#/login');
|
if (!atLogin) {
|
window.location.href = '/#/login';
|
}
|
}
|
throw new Error(`HTTP error! status: ${response.status}`);
|
}
|
|
const result = await response.json();
|
|
if (result.errors) {
|
const msg = JSON.stringify(result.errors) || ''
|
// 识别认证类错误关键字
|
const isAuthError =
|
msg.includes('Unauthorized') ||
|
msg.includes('认证') ||
|
msg.includes('unauthorized') ||
|
msg.includes('invalid token') ||
|
msg.includes('expired')
|
|
if (isAuthError) {
|
const { clearAuth } = await import('@/utils/auth');
|
clearAuth();
|
const atLogin = typeof window !== 'undefined' && window.location && window.location.hash?.startsWith('#/login');
|
if (!atLogin) {
|
window.location.href = '/#/login';
|
}
|
}
|
throw new Error(`GraphQL errors: ${msg}`);
|
}
|
|
return result;
|
} catch (error) {
|
console.error('=== GraphQL请求失败 ===');
|
console.error('错误详情:', error);
|
throw error;
|
}
|
}
|
|
// 通用API请求工具函数
|
export const apiRequest = async (endpoint: string, options: RequestInit = {}) => {
|
const url = endpoint.startsWith('http') ? endpoint : `${API_CONFIG.BASE_URL}${endpoint}`
|
|
const response = await fetch(url, {
|
headers: {
|
'Content-Type': 'application/json',
|
...options.headers,
|
},
|
...options,
|
})
|
|
if (!response.ok) {
|
throw new Error(`HTTP error! status: ${response.status}`)
|
}
|
|
return response.json()
|
}
|