리비전 페이지 제거 및 트랜잭션 오류 임시 수정
Some checks failed
SonarQube Analysis / SonarQube Scan (push) Has been cancelled

- frontend/src/pages/revision/ 폴더 완전 삭제
- EnhancedRevisionPage.css 제거
- support_details 저장 시 트랜잭션 오류로 인해 임시로 상세 정보 저장 비활성화
- 리비전 기능 재설계 예정
This commit is contained in:
Hyungi Ahn
2025-10-21 12:11:57 +09:00
parent 8f42a1054e
commit 1dc735f362
29 changed files with 1728 additions and 6987 deletions

View File

@@ -34,6 +34,12 @@ const BOMManagementPage = ({
const [userRequirements, setUserRequirements] = useState({});
const [purchasedMaterials, setPurchasedMaterials] = useState(new Set());
const [error, setError] = useState(null);
// 리비전 관련 상태
const [isRevisionMode, setIsRevisionMode] = useState(false);
const [revisionData, setRevisionData] = useState(null);
const [previousFileId, setPreviousFileId] = useState(null);
const [changedMaterials, setChangedMaterials] = useState({});
// 자재 업데이트 함수 (브랜드, 사용자 요구사항 등)
const updateMaterial = (materialId, updates) => {
@@ -155,12 +161,58 @@ const BOMManagementPage = ({
}
};
// 리비전 모드 감지 및 변경된 자재 로드
const checkAndLoadRevisionData = async () => {
try {
// 현재 job_no의 모든 파일 목록 확인
const filesResponse = await api.get(`/files/list?job_no=${jobNo}`);
const files = filesResponse.data.files || [];
if (files.length > 1) {
// 파일이 여러 개 있으면 리비전 모드 활성화
setIsRevisionMode(true);
// 파일들을 업로드 날짜순으로 정렬
const sortedFiles = files.sort((a, b) => new Date(a.upload_date) - new Date(b.upload_date));
// 이전 파일 ID 찾기 (현재 파일 이전 버전)
const currentIndex = sortedFiles.findIndex(file => file.id === parseInt(fileId));
if (currentIndex > 0) {
const previousFile = sortedFiles[currentIndex - 1];
setPreviousFileId(previousFile.id);
// 변경된 자재 로드
await loadChangedMaterials(fileId, previousFile.id);
}
}
} catch (error) {
console.error('리비전 데이터 로드 실패:', error);
// API 오류 시 리비전 모드 비활성화
setIsRevisionMode(false);
}
};
// 변경된 자재 로드
const loadChangedMaterials = async (currentFileId, previousFileId) => {
try {
const response = await api.get(`/simple-revision/changed-materials/${currentFileId}/${previousFileId}`);
if (response.data.success) {
setChangedMaterials(response.data.data.changes_by_category || {});
setRevisionData(response.data.data);
console.log('✅ 변경된 자재 로드 완료:', response.data.data);
}
} catch (error) {
console.error('변경된 자재 로드 실패:', error);
}
};
// 초기 로드
useEffect(() => {
if (fileId) {
loadMaterials(fileId);
loadAvailableRevisions();
loadUserRequirements(fileId);
checkAndLoadRevisionData(); // 리비전 데이터 확인
}
}, [fileId]);
@@ -180,12 +232,30 @@ const BOMManagementPage = ({
}
}, [materials, selectedCategory]);
// 카테고리별 자재 필터링
// 카테고리별 자재 필터링 (리비전 모드 지원)
const getCategoryMaterials = (category) => {
return materials.filter(material =>
material.classified_category === category ||
material.category === category
);
if (isRevisionMode && changedMaterials[category]) {
// 리비전 모드: 변경된 자재만 표시
const changedMaterialIds = changedMaterials[category].changes.map(change => change.material_id);
return materials.filter(material =>
(material.classified_category === category || material.category === category) &&
changedMaterialIds.includes(material.id)
);
} else {
// 일반 모드: 모든 자재 표시
return materials.filter(material =>
material.classified_category === category ||
material.category === category
);
}
};
// 리비전 액션 정보 가져오기
const getRevisionAction = (materialId, category) => {
if (!isRevisionMode || !changedMaterials[category]) return null;
const change = changedMaterials[category].changes.find(c => c.material_id === materialId);
return change || null;
};
// 카테고리별 컴포넌트 렌더링
@@ -210,7 +280,11 @@ const BOMManagementPage = ({
fileId,
jobNo,
user,
onNavigate
onNavigate,
// 리비전 관련 props 추가
isRevisionMode,
getRevisionAction: (materialId) => getRevisionAction(materialId, selectedCategory),
revisionData
};
switch (selectedCategory) {
@@ -282,15 +356,32 @@ const BOMManagementPage = ({
}}>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '28px' }}>
<div>
<h2 style={{
fontSize: '28px',
fontWeight: '700',
color: '#0f172a',
margin: '0 0 8px 0',
letterSpacing: '-0.025em'
}}>
BOM Materials Management
</h2>
<div style={{ display: 'flex', alignItems: 'center', gap: '12px', marginBottom: '8px' }}>
<h2 style={{
fontSize: '28px',
fontWeight: '700',
color: '#0f172a',
margin: 0,
letterSpacing: '-0.025em'
}}>
BOM Materials Management
</h2>
{isRevisionMode && (
<div style={{
background: 'linear-gradient(135deg, #f59e0b 0%, #d97706 100%)',
color: 'white',
padding: '6px 12px',
borderRadius: '8px',
fontSize: '12px',
fontWeight: '600',
textTransform: 'uppercase',
letterSpacing: '0.05em',
boxShadow: '0 4px 6px -1px rgba(245, 158, 11, 0.3)'
}}>
📊 Revision Mode
</div>
)}
</div>
<p style={{
fontSize: '16px',
color: '#64748b',
@@ -298,6 +389,15 @@ const BOMManagementPage = ({
fontWeight: '400'
}}>
{bomName} - {currentRevision} | Project: {selectedProject?.job_name || jobNo}
{isRevisionMode && revisionData && (
<span style={{
marginLeft: '16px',
color: '#f59e0b',
fontWeight: '600'
}}>
{revisionData.total_changed_materials} materials changed
</span>
)}
</p>
</div>
<button
@@ -415,6 +515,7 @@ const BOMManagementPage = ({
.map((category) => {
const isActive = selectedCategory === category.key;
const count = getCategoryMaterials(category.key).length;
const hasChanges = isRevisionMode && changedMaterials[category.key];
return (
<button
@@ -423,9 +524,11 @@ const BOMManagementPage = ({
style={{
background: isActive
? `linear-gradient(135deg, ${category.color} 0%, ${category.color}dd 100%)`
: 'white',
color: isActive ? 'white' : '#64748b',
border: isActive ? 'none' : '1px solid #e2e8f0',
: hasChanges
? 'linear-gradient(135deg, #fef3c7 0%, #fde68a 100%)'
: 'white',
color: isActive ? 'white' : hasChanges ? '#92400e' : '#64748b',
border: isActive ? 'none' : hasChanges ? '2px solid #f59e0b' : '1px solid #e2e8f0',
borderRadius: '12px',
padding: '16px 12px',
cursor: 'pointer',
@@ -433,7 +536,8 @@ const BOMManagementPage = ({
fontWeight: '600',
transition: 'all 0.2s ease',
textAlign: 'center',
boxShadow: isActive ? `0 4px 14px 0 ${category.color}39` : '0 2px 8px rgba(0,0,0,0.05)'
boxShadow: isActive ? `0 4px 14px 0 ${category.color}39` : hasChanges ? '0 4px 14px 0 rgba(245, 158, 11, 0.3)' : '0 2px 8px rgba(0,0,0,0.05)',
position: 'relative'
}}
onMouseEnter={(e) => {
if (!isActive) {
@@ -448,8 +552,16 @@ const BOMManagementPage = ({
}
}}
>
<div style={{ marginBottom: '4px' }}>
<div style={{ marginBottom: '4px', display: 'flex', alignItems: 'center', justifyContent: 'center', gap: '4px' }}>
{category.label}
{hasChanges && (
<div style={{
width: '8px',
height: '8px',
borderRadius: '50%',
background: isActive ? 'rgba(255,255,255,0.8)' : '#f59e0b'
}}></div>
)}
</div>
<div style={{
fontSize: '12px',
@@ -457,6 +569,11 @@ const BOMManagementPage = ({
fontWeight: '500'
}}>
{count} items
{hasChanges && (
<span style={{ marginLeft: '4px', fontSize: '10px' }}>
({changedMaterials[category.key].changed_count} changed)
</span>
)}
</div>
</button>
);