- 모든 자재 카테고리별 상세 테이블 생성 (fitting, valve, flange, bolt, gasket, instrument) - PIPE, FITTING, VALVE 분류 결과를 각 상세 테이블에 저장하는 로직 구현 - 프론트엔드 라우팅 정리 및 BOM 현황 페이지 기능 개선 - 자재확인 페이지 에러 처리 개선 TODO: FLANGE, BOLT, GASKET, INSTRUMENT 저장 로직 추가 필요
134 lines
3.4 KiB
JavaScript
134 lines
3.4 KiB
JavaScript
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 compareRevisions(jobNo, filename, oldRevision, newRevision) {
|
|
return api.get('/files/materials/compare-revisions', {
|
|
params: {
|
|
job_no: jobNo,
|
|
filename: filename,
|
|
old_revision: oldRevision,
|
|
new_revision: newRevision
|
|
}
|
|
});
|
|
}
|
|
|
|
// 프로젝트 수정
|
|
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
|
|
});
|
|
}
|