Files
tk-factory-services/tkeg/web/src/hooks/useRevisionManagement.js
2026-03-16 15:41:58 +09:00

319 lines
11 KiB
JavaScript

/**
* 리비전 관리 훅
* - 리비전 세션 생성, 관리, 완료
* - 자재 비교 및 변경사항 처리
* - 리비전 히스토리 조회
*/
import { useState, useCallback } from 'react';
import api from '../api';
export const useRevisionManagement = () => {
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const [currentSession, setCurrentSession] = useState(null);
const [sessionStatus, setSessionStatus] = useState(null);
const [revisionHistory, setRevisionHistory] = useState([]);
// 에러 처리 헬퍼
const handleError = useCallback((error, defaultMessage) => {
console.error(defaultMessage, error);
const errorMessage = error.response?.data?.detail || error.message || defaultMessage;
setError(errorMessage);
return { success: false, error: errorMessage };
}, []);
// 리비전 세션 생성
const createRevisionSession = useCallback(async (jobNo, currentFileId, previousFileId) => {
setLoading(true);
setError(null);
try {
const response = await api.post('/revision-management/sessions', {
job_no: jobNo,
current_file_id: currentFileId,
previous_file_id: previousFileId
});
if (response.data.success) {
setCurrentSession(response.data.data);
console.log('✅ 리비전 세션 생성 완료:', response.data.data);
return { success: true, data: response.data.data };
} else {
return handleError(new Error(response.data.message), '리비전 세션 생성 실패');
}
} catch (error) {
return handleError(error, '리비전 세션 생성 중 오류 발생');
} finally {
setLoading(false);
}
}, [handleError]);
// 세션 상태 조회
const getSessionStatus = useCallback(async (sessionId) => {
setLoading(true);
setError(null);
try {
const response = await api.get(`/revision-management/sessions/${sessionId}`);
if (response.data.success) {
setSessionStatus(response.data.data);
console.log('✅ 세션 상태 조회 완료:', response.data.data);
return { success: true, data: response.data.data };
} else {
return handleError(new Error(response.data.message), '세션 상태 조회 실패');
}
} catch (error) {
return handleError(error, '세션 상태 조회 중 오류 발생');
} finally {
setLoading(false);
}
}, [handleError]);
// 카테고리별 자재 비교
const compareCategory = useCallback(async (sessionId, category) => {
setLoading(true);
setError(null);
try {
const response = await api.post(`/revision-management/sessions/${sessionId}/compare/${category}`);
if (response.data.success) {
console.log(`✅ 카테고리 ${category} 비교 완료:`, response.data.data);
return { success: true, data: response.data.data };
} else {
return handleError(new Error(response.data.message), `카테고리 ${category} 비교 실패`);
}
} catch (error) {
return handleError(error, `카테고리 ${category} 비교 중 오류 발생`);
} finally {
setLoading(false);
}
}, [handleError]);
// 세션 변경사항 조회
const getSessionChanges = useCallback(async (sessionId, category = null) => {
setLoading(true);
setError(null);
try {
const params = category ? { category } : {};
const response = await api.get(`/revision-management/sessions/${sessionId}/changes`, { params });
if (response.data.success) {
console.log('✅ 세션 변경사항 조회 완료:', response.data.data);
return { success: true, data: response.data.data };
} else {
return handleError(new Error(response.data.message), '세션 변경사항 조회 실패');
}
} catch (error) {
return handleError(error, '세션 변경사항 조회 중 오류 발생');
} finally {
setLoading(false);
}
}, [handleError]);
// 리비전 액션 처리
const processRevisionAction = useCallback(async (changeId, action, notes = null) => {
setLoading(true);
setError(null);
try {
const response = await api.post(`/revision-management/changes/${changeId}/process`, {
action,
notes
});
if (response.data.success) {
console.log('✅ 리비전 액션 처리 완료:', response.data.data);
return { success: true, data: response.data.data };
} else {
return handleError(new Error(response.data.message), '리비전 액션 처리 실패');
}
} catch (error) {
return handleError(error, '리비전 액션 처리 중 오류 발생');
} finally {
setLoading(false);
}
}, [handleError]);
// 세션 완료
const completeSession = useCallback(async (sessionId) => {
setLoading(true);
setError(null);
try {
const response = await api.post(`/revision-management/sessions/${sessionId}/complete`);
if (response.data.success) {
setCurrentSession(null);
setSessionStatus(null);
console.log('✅ 리비전 세션 완료:', response.data.data);
return { success: true, data: response.data.data };
} else {
return handleError(new Error(response.data.message), '리비전 세션 완료 실패');
}
} catch (error) {
return handleError(error, '리비전 세션 완료 중 오류 발생');
} finally {
setLoading(false);
}
}, [handleError]);
// 세션 취소
const cancelSession = useCallback(async (sessionId, reason = null) => {
setLoading(true);
setError(null);
try {
const params = reason ? { reason } : {};
const response = await api.post(`/revision-management/sessions/${sessionId}/cancel`, null, { params });
if (response.data.success) {
setCurrentSession(null);
setSessionStatus(null);
console.log('✅ 리비전 세션 취소:', response.data.data);
return { success: true, data: response.data.data };
} else {
return handleError(new Error(response.data.message), '리비전 세션 취소 실패');
}
} catch (error) {
return handleError(error, '리비전 세션 취소 중 오류 발생');
} finally {
setLoading(false);
}
}, [handleError]);
// 리비전 히스토리 조회
const getRevisionHistory = useCallback(async (jobNo) => {
setLoading(true);
setError(null);
try {
const response = await api.get(`/revision-management/history/${jobNo}`);
if (response.data.success) {
setRevisionHistory(response.data.data.history);
console.log('✅ 리비전 히스토리 조회 완료:', response.data.data);
return { success: true, data: response.data.data };
} else {
return handleError(new Error(response.data.message), '리비전 히스토리 조회 실패');
}
} catch (error) {
return handleError(error, '리비전 히스토리 조회 중 오류 발생');
} finally {
setLoading(false);
}
}, [handleError]);
// 리비전 요약 조회
const getRevisionSummary = useCallback(async (sessionId) => {
setLoading(true);
setError(null);
try {
const response = await api.get(`/revision-management/sessions/${sessionId}/summary`);
if (response.data.success) {
console.log('✅ 리비전 요약 조회 완료:', response.data.data);
return { success: true, data: response.data.data };
} else {
return handleError(new Error(response.data.message), '리비전 요약 조회 실패');
}
} catch (error) {
return handleError(error, '리비전 요약 조회 중 오류 발생');
} finally {
setLoading(false);
}
}, [handleError]);
// 지원 카테고리 조회
const getSupportedCategories = useCallback(async () => {
try {
const response = await api.get('/revision-management/categories');
if (response.data.success) {
return { success: true, data: response.data.data.categories };
}
} catch (error) {
console.warn('지원 카테고리 조회 실패:', error);
}
// 기본 카테고리 반환
return {
success: true,
data: [
{ key: "PIPE", name: "배관", description: "파이프 및 배관 자재" },
{ key: "FITTING", name: "피팅", description: "배관 연결 부품" },
{ key: "FLANGE", name: "플랜지", description: "플랜지 및 연결 부품" },
{ key: "VALVE", name: "밸브", description: "각종 밸브류" },
{ key: "GASKET", name: "가스켓", description: "씰링 부품" },
{ key: "BOLT", name: "볼트", description: "체결 부품" },
{ key: "SUPPORT", name: "서포트", description: "지지대 및 구조물" },
{ key: "SPECIAL", name: "특수자재", description: "특수 목적 자재" },
{ key: "UNCLASSIFIED", name: "미분류", description: "분류되지 않은 자재" }
]
};
}, []);
// 리비전 액션 목록 조회
const getRevisionActions = useCallback(async () => {
try {
const response = await api.get('/revision-management/actions');
if (response.data.success) {
return { success: true, data: response.data.data.actions };
}
} catch (error) {
console.warn('리비전 액션 조회 실패:', error);
}
// 기본 액션 반환
return {
success: true,
data: [
{ key: "new_material", name: "신규 자재", description: "새로 추가된 자재" },
{ key: "additional_purchase", name: "추가 구매", description: "구매된 자재의 수량 증가" },
{ key: "inventory_transfer", name: "재고 이관", description: "구매된 자재의 수량 감소 또는 제거" },
{ key: "purchase_cancel", name: "구매 취소", description: "미구매 자재의 제거" },
{ key: "quantity_update", name: "수량 업데이트", description: "미구매 자재의 수량 변경" },
{ key: "maintain", name: "유지", description: "변경사항 없음" }
]
};
}, []);
// 상태 초기화
const resetState = useCallback(() => {
setCurrentSession(null);
setSessionStatus(null);
setRevisionHistory([]);
setError(null);
setLoading(false);
}, []);
return {
// 상태
loading,
error,
currentSession,
sessionStatus,
revisionHistory,
// 액션
createRevisionSession,
getSessionStatus,
compareCategory,
getSessionChanges,
processRevisionAction,
completeSession,
cancelSession,
getRevisionHistory,
getRevisionSummary,
getSupportedCategories,
getRevisionActions,
resetState,
// 유틸리티
clearError: () => setError(null)
};
};