2024-11-17 17:17:40 +08:00
|
|
|
interface ApiConfig {
|
2024-11-19 00:20:31 +08:00
|
|
|
baseURL: string;
|
|
|
|
timeout?: number;
|
2024-11-17 17:17:40 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
export class ApiService {
|
2024-11-19 00:20:31 +08:00
|
|
|
private static instance: ApiService;
|
|
|
|
private baseURL: string;
|
|
|
|
private timeout: number;
|
2024-11-17 17:17:40 +08:00
|
|
|
|
|
|
|
private constructor(config: ApiConfig) {
|
|
|
|
this.baseURL = config.baseURL;
|
2024-11-19 00:20:31 +08:00
|
|
|
this.timeout = config.timeout || 10000;
|
2024-11-17 17:17:40 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
public static getInstance(config?: ApiConfig): ApiService {
|
|
|
|
if (!this.instance && config) {
|
|
|
|
this.instance = new ApiService(config);
|
|
|
|
}
|
|
|
|
return this.instance;
|
|
|
|
}
|
|
|
|
|
|
|
|
private async getSystemToken(): Promise<string> {
|
2024-11-18 01:09:28 +08:00
|
|
|
const username = import.meta.env.VITE_SYSTEM_USERNAME;
|
|
|
|
const password = import.meta.env.VITE_SYSTEM_PASSWORD;
|
|
|
|
if (!username || !password ) {
|
|
|
|
throw new Error('Failed to obtain the username or password of the front-end system');
|
2024-11-17 17:17:40 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
2024-11-18 01:09:28 +08:00
|
|
|
const response = await fetch(`${this.baseURL}/auth/token/system`, {
|
2024-11-17 17:17:40 +08:00
|
|
|
method: 'POST',
|
|
|
|
headers: {
|
|
|
|
'Content-Type': 'application/json',
|
|
|
|
},
|
2024-11-18 01:09:28 +08:00
|
|
|
body: JSON.stringify({
|
|
|
|
username,
|
|
|
|
password,
|
|
|
|
}),
|
2024-11-17 17:17:40 +08:00
|
|
|
});
|
|
|
|
|
|
|
|
if (!response.ok) {
|
|
|
|
throw new Error('Failed to get system token');
|
|
|
|
}
|
|
|
|
|
2024-11-18 01:09:28 +08:00
|
|
|
const data = await response.text();
|
2024-11-19 00:20:31 +08:00
|
|
|
return data;
|
2024-11-17 17:17:40 +08:00
|
|
|
} catch (error) {
|
|
|
|
console.error('Error getting system token:', error);
|
|
|
|
throw error;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public async request<T>(
|
|
|
|
endpoint: string,
|
|
|
|
options: RequestInit = {},
|
2024-11-19 00:20:31 +08:00
|
|
|
toekn ?: string
|
2024-11-17 17:17:40 +08:00
|
|
|
): Promise<T> {
|
|
|
|
const controller = new AbortController();
|
|
|
|
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
|
|
|
|
|
|
try {
|
|
|
|
const headers = new Headers(options.headers);
|
|
|
|
|
2024-11-19 00:20:31 +08:00
|
|
|
if (toekn) {
|
|
|
|
headers.set('Authorization', `Bearer ${toekn}`);
|
2024-11-17 17:17:40 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
const response = await fetch(`${this.baseURL}${endpoint}`, {
|
|
|
|
...options,
|
|
|
|
headers,
|
|
|
|
signal: controller.signal,
|
|
|
|
});
|
|
|
|
|
|
|
|
if (!response.ok) {
|
|
|
|
throw new Error(`API Error: ${response.statusText}`);
|
|
|
|
}
|
|
|
|
|
|
|
|
const data = await response.json();
|
|
|
|
return data as T;
|
|
|
|
} catch (error: any) {
|
|
|
|
if (error.name === 'AbortError') {
|
|
|
|
throw new Error('Request timeout');
|
|
|
|
}
|
|
|
|
throw error;
|
|
|
|
} finally {
|
|
|
|
clearTimeout(timeoutId);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export default ApiService.getInstance({
|
|
|
|
baseURL: import.meta.env.VITE_API_BASE_URL,
|
2024-11-19 00:20:31 +08:00
|
|
|
});
|