프론트엔드 작성중
This commit is contained in:
122
frontend/src/api.js
Normal file
122
frontend/src/api.js
Normal file
@@ -0,0 +1,122 @@
|
||||
import axios from 'axios';
|
||||
|
||||
// 환경변수에서 API URL을 읽음 (Vite 기준)
|
||||
const API_BASE_URL = import.meta.env.VITE_API_URL ||
|
||||
(import.meta.env.DEV ? 'http://localhost:8000' : 'http://localhost:8000');
|
||||
|
||||
console.log('API Base URL:', API_BASE_URL);
|
||||
console.log('Environment:', import.meta.env.MODE);
|
||||
|
||||
// axios 인스턴스 생성
|
||||
export const api = axios.create({
|
||||
baseURL: API_BASE_URL,
|
||||
timeout: 30000, // 30초로 증가
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
|
||||
// 재시도 로직을 위한 설정
|
||||
const MAX_RETRIES = 3;
|
||||
const RETRY_DELAY = 1000; // 1초
|
||||
|
||||
// 재시도 함수
|
||||
const retryRequest = async (config, retries = MAX_RETRIES) => {
|
||||
try {
|
||||
return await api(config);
|
||||
} catch (error) {
|
||||
if (retries > 0 && (error.code === 'ECONNABORTED' || error.response?.status >= 500)) {
|
||||
console.log(`API 재시도 중... (${MAX_RETRIES - retries + 1}/${MAX_RETRIES})`);
|
||||
await new Promise(resolve => setTimeout(resolve, RETRY_DELAY));
|
||||
return retryRequest(config, retries - 1);
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
// 공통 에러 핸들링 (예시)
|
||||
api.interceptors.response.use(
|
||||
response => response,
|
||||
error => {
|
||||
console.error('API Error:', {
|
||||
url: error.config?.url,
|
||||
method: error.config?.method,
|
||||
status: error.response?.status,
|
||||
data: error.response?.data,
|
||||
message: error.message
|
||||
});
|
||||
|
||||
// 필요시 에러 로깅/알림 등 추가
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
// 예시: 파일 업로드 (multipart/form-data)
|
||||
export function uploadFile(formData, options = {}) {
|
||||
const config = {
|
||||
method: 'post',
|
||||
url: '/upload',
|
||||
data: formData,
|
||||
headers: { 'Content-Type': 'multipart/form-data' },
|
||||
...options,
|
||||
};
|
||||
|
||||
return retryRequest(config);
|
||||
}
|
||||
|
||||
// 예시: 자재 목록 조회
|
||||
export function fetchMaterials(params) {
|
||||
return api.get('/files/materials', { params });
|
||||
}
|
||||
|
||||
// 예시: 자재 요약 통계
|
||||
export function fetchMaterialsSummary(params) {
|
||||
return api.get('/files/materials/summary', { params });
|
||||
}
|
||||
|
||||
// 파일 목록 조회
|
||||
export function fetchFiles(params) {
|
||||
return api.get('/files', { params });
|
||||
}
|
||||
|
||||
// 파일 삭제
|
||||
export function deleteFile(fileId) {
|
||||
return api.delete(`/files/${fileId}`);
|
||||
}
|
||||
|
||||
// 예시: Job 목록 조회
|
||||
export function fetchJobs(params) {
|
||||
return api.get('/jobs', { params });
|
||||
}
|
||||
|
||||
// 예시: Job 생성
|
||||
export function createJob(data) {
|
||||
return api.post('/jobs', data);
|
||||
}
|
||||
|
||||
// 프로젝트 수정
|
||||
export function updateProject(projectId, data) {
|
||||
return api.put(`/projects/${projectId}`, data);
|
||||
}
|
||||
|
||||
// 프로젝트 삭제
|
||||
export function deleteProject(projectId) {
|
||||
return api.delete(`/projects/${projectId}`);
|
||||
}
|
||||
|
||||
// 스풀 관련 API
|
||||
export function fetchProjectSpools(projectId) {
|
||||
return api.get(`/spools/project/${projectId}/spools`);
|
||||
}
|
||||
|
||||
export function validateSpoolIdentifier(identifier) {
|
||||
return api.post('/spools/validate-identifier', { spool_identifier: identifier });
|
||||
}
|
||||
|
||||
export function generateSpoolIdentifier(dwgName, areaNumber, spoolNumber) {
|
||||
return api.post('/spools/generate-identifier', {
|
||||
dwg_name: dwgName,
|
||||
area_number: areaNumber,
|
||||
spool_number: spoolNumber
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user