| | |
| | | |
| | | // GraphQL请求工具函数 |
| | | export const graphqlRequest = async (query: string, variables: any = {}) => { |
| | | // 获取JWT token |
| | | const { getToken } = await import('@/utils/auth'); |
| | | // 获取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 response = await fetch(API_CONFIG.GRAPHQL_ENDPOINT, { |
| | | method: 'POST', |
| | | headers: headers, |
| | | body: JSON.stringify({ |
| | | query, |
| | | variables, |
| | | }), |
| | | }) |
| | | // 构建请求体 |
| | | const requestBody = JSON.stringify({ |
| | | query, |
| | | variables, |
| | | }); |
| | | |
| | | if (!response.ok) { |
| | | throw new Error(`HTTP error! status: ${response.status}`) |
| | | 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; |
| | | } |
| | | |
| | | const result = await response.json() |
| | | |
| | | if (result.errors) { |
| | | throw new Error(result.errors[0].message) |
| | | } |
| | | |
| | | return result.data |
| | | } |
| | | |
| | | // 通用API请求工具函数 |