160 lines
4.2 KiB
TypeScript
160 lines
4.2 KiB
TypeScript
/**
|
|
* API utilities for fetching celestial data
|
|
*/
|
|
import axios from 'axios';
|
|
import type { CelestialDataResponse, BodyInfo } from '../types';
|
|
import { auth } from './auth';
|
|
|
|
// Dynamically determine the API base URL
|
|
const getApiBaseUrl = () => {
|
|
if (import.meta.env.VITE_API_BASE_URL) {
|
|
return import.meta.env.VITE_API_BASE_URL;
|
|
}
|
|
|
|
// In production, use relative path /api (proxied by Nginx)
|
|
// This works for both internal IP and external domain access
|
|
if (import.meta.env.PROD) {
|
|
return '/api';
|
|
}
|
|
|
|
// In development, proxy is configured in vite.config.ts
|
|
return '/api';
|
|
};
|
|
|
|
const API_BASE_URL = getApiBaseUrl();
|
|
|
|
export const api = axios.create({
|
|
baseURL: API_BASE_URL,
|
|
timeout: 120000, // Increase timeout to 120 seconds for historical data queries
|
|
});
|
|
|
|
// Add request interceptor for auth
|
|
api.interceptors.request.use(
|
|
(config) => {
|
|
// Add token if available
|
|
const token = auth.getToken();
|
|
if (token) {
|
|
config.headers.Authorization = `Bearer ${token}`;
|
|
}
|
|
|
|
return config;
|
|
},
|
|
(error) => {
|
|
return Promise.reject(error);
|
|
}
|
|
);
|
|
|
|
// Add response interceptor for error handling
|
|
api.interceptors.response.use(
|
|
(response) => {
|
|
return response;
|
|
},
|
|
(error) => {
|
|
// Only log errors in development
|
|
if (import.meta.env.DEV) {
|
|
console.error('[API Error]', error.config?.url, error.message);
|
|
if (error.response) {
|
|
console.error('[API Error Response]', error.response.status, error.response.data);
|
|
} else if (error.request) {
|
|
console.error('[API Error Request]', error.request);
|
|
}
|
|
}
|
|
return Promise.reject(error);
|
|
}
|
|
);
|
|
|
|
/**
|
|
* Fetch celestial positions
|
|
*/
|
|
export async function fetchCelestialPositions(
|
|
startTime?: string,
|
|
endTime?: string,
|
|
step: string = '1d'
|
|
): Promise<CelestialDataResponse> {
|
|
const params: Record<string, string> = { step };
|
|
if (startTime) params.start_time = startTime;
|
|
if (endTime) params.end_time = endTime;
|
|
|
|
const response = await api.get<CelestialDataResponse>('/celestial/positions', {
|
|
params,
|
|
});
|
|
return response.data;
|
|
}
|
|
|
|
/**
|
|
* Fetch body information
|
|
*/
|
|
export async function fetchBodyInfo(bodyId: string): Promise<BodyInfo> {
|
|
const response = await api.get<BodyInfo>(`/celestial/info/${bodyId}`);
|
|
return response.data;
|
|
}
|
|
|
|
/**
|
|
* List all bodies
|
|
*/
|
|
export async function fetchAllBodies(): Promise<{ bodies: BodyInfo[] }> {
|
|
const response = await api.get('/celestial/list');
|
|
return response.data;
|
|
}
|
|
|
|
/**
|
|
* Fetch static data by category (constellation, galaxy, nebula, star, cluster)
|
|
*/
|
|
export async function fetchStaticData(category: string): Promise<{
|
|
category: string;
|
|
items: Array<{
|
|
id: number;
|
|
name: string;
|
|
name_zh: string;
|
|
data: any;
|
|
}>;
|
|
}> {
|
|
const response = await api.get(`/celestial/static/${category}`);
|
|
return response.data;
|
|
}
|
|
|
|
/**
|
|
* Get resource URL from backend
|
|
*/
|
|
export function getResourceUrl(type: 'texture' | 'model' | 'icon' | 'thumbnail' | 'data', filename: string): string {
|
|
const protocol = window.location.protocol;
|
|
const hostname = window.location.hostname;
|
|
const port = import.meta.env.VITE_API_BASE_URL ? '' : ':8000';
|
|
return `${protocol}//${hostname}${port}/upload/${type}/${filename}`;
|
|
}
|
|
|
|
/**
|
|
* Fetch resources for a celestial body
|
|
*/
|
|
export async function fetchBodyResources(bodyId: string, resourceType?: string): Promise<{
|
|
body_id: string;
|
|
resources: Array<{
|
|
id: number;
|
|
resource_type: string;
|
|
file_path: string;
|
|
file_size: number;
|
|
mime_type: string;
|
|
created_at: string;
|
|
extra_data?: Record<string, any>;
|
|
}>;
|
|
}> {
|
|
const params: Record<string, string> = {};
|
|
if (resourceType) params.resource_type = resourceType;
|
|
|
|
const response = await api.get(`/celestial/resources/${bodyId}`, { params });
|
|
return response.data;
|
|
}
|
|
|
|
/**
|
|
* Auth API methods
|
|
*/
|
|
export async function login(username: string, password: string): Promise<any> {
|
|
const response = await api.post('/auth/login', { username, password });
|
|
return response.data;
|
|
}
|
|
|
|
export async function register(username: string, password: string, email?: string, full_name?: string): Promise<any> {
|
|
const response = await api.post('/auth/register', { username, password, email, full_name });
|
|
return response.data;
|
|
}
|