feat: 서포트 카테고리 전면 개선
Some checks failed
SonarQube Analysis / SonarQube Scan (push) Has been cancelled

- 서포트 카테고리 UI 개선: 좌우 스크롤, 헤더/본문 동기화, 가운데 정렬
- 동일 항목 합산 기능 구현 (Type + Size + Grade 기준)
- 헤더 구조 변경: 압력/스케줄 제거, 구매수량 단일화, User Requirements 추가
- 우레탄 블럭슈 두께 정보(40t, 27t) Material Grade에 포함
- 서포트 수량 계산 수정: 취합된 숫자 그대로 표시 (4의 배수 계산 제거)
- 서포트 분류 로직 개선: CLAMP, U-BOLT, URETHANE BLOCK SHOE 등 정확한 분류
- 백엔드 서포트 분류기에 User Requirements 추출 기능 추가
- 엑셀 내보내기에 서포트 카테고리 처리 로직 추가
This commit is contained in:
hyungi
2025-10-17 07:59:35 +09:00
parent a27213e0e5
commit 6b6360ecd5
19 changed files with 2452 additions and 278 deletions

110
update_excel_exports.py Normal file
View File

@@ -0,0 +1,110 @@
import os
import re
# 수정할 파일들과 카테고리
files_categories = [
('frontend/src/components/bom/materials/ValveMaterialsView.jsx', 'VALVE'),
('frontend/src/components/bom/materials/GasketMaterialsView.jsx', 'GASKET'),
('frontend/src/components/bom/materials/BoltMaterialsView.jsx', 'BOLT'),
('frontend/src/components/bom/materials/SupportMaterialsView.jsx', 'SUPPORT')
]
for file_path, category in files_categories:
if os.path.exists(file_path):
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
# 기존 try 블록을 새로운 방식으로 교체
old_pattern = r'try\s*\{\s*//\s*1\.\s*구매신청\s*생성.*?alert\(\'엑셀\s*파일은\s*다운로드되었지만\s*구매신청\s*생성에\s*실패했습니다\.\'\);\s*\}'
new_code = f'''try {{
console.log('🔄 {category.lower()} 엑셀 내보내기 시작 - 새로운 방식');
// 1. 먼저 클라이언트에서 엑셀 파일 생성
console.log('📊 엑셀 Blob 생성 중...', dataWithRequirements.length, '개 자료');
const excelBlob = await createExcelBlob(dataWithRequirements, excelFileName, {{
category: '{category}',
filename: excelFileName,
uploadDate: new Date().toLocaleDateString()
}});
console.log('✅ 엑셀 Blob 생성 완료:', excelBlob.size, 'bytes');
// 2. 구매신청 생성
const allMaterialIds = selectedMaterialsData.map(m => m.id);
const response = await api.post('/purchase-request/create', {{
file_id: fileId,
job_no: jobNo,
category: '{category}',
material_ids: allMaterialIds,
materials_data: dataWithRequirements.map(m => ({{
material_id: m.id,
description: m.original_description,
category: m.classified_category,
size: m.size_inch || m.size_spec,
schedule: m.schedule,
material_grade: m.material_grade || m.full_material_grade,
quantity: m.quantity,
unit: m.unit,
user_requirement: userRequirements[m.id] || ''
}}))
}});
if (response.data.success) {{
console.log(`✅ 구매신청 완료: ${{response.data.request_no}}, request_id: ${{response.data.request_id}}`);
// 3. 생성된 엑셀 파일을 서버에 업로드
console.log('📤 서버에 엑셀 파일 업로드 중...');
const formData = new FormData();
formData.append('excel_file', excelBlob, excelFileName);
formData.append('request_id', response.data.request_id);
formData.append('category', '{category}');
const uploadResponse = await api.post('/purchase-request/upload-excel', formData, {{
headers: {{
'Content-Type': 'multipart/form-data',
}},
}});
console.log('✅ 엑셀 업로드 완료:', uploadResponse.data);
if (onPurchasedMaterialsUpdate) {{
onPurchasedMaterialsUpdate(allMaterialIds);
}}
}}
// 4. 클라이언트 다운로드
const url = window.URL.createObjectURL(excelBlob);
const link = document.createElement('a');
link.href = url;
link.download = excelFileName;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
window.URL.revokeObjectURL(url);
alert(`구매신청 ${{response.data?.request_no || ''}}이 생성되고 엑셀 파일이 저장되었습니다.`);
}} catch (error) {{
console.error('엑셀 저장 또는 구매신청 실패:', error);
// 실패 시에도 클라이언트 다운로드는 진행
exportMaterialsToExcel(dataWithRequirements, excelFileName, {{
category: '{category}',
filename: excelFileName,
uploadDate: new Date().toLocaleDateString()
}});
alert('엑셀 파일은 다운로드되었지만 구매신청 생성에 실패했습니다.');
}}'''
# 간단한 패턴으로 기존 try 블록 찾기
try_pattern = r'try\s*\{[^}]*?구매신청\s*생성[^}]*?\}\s*catch[^}]*?\}'
if re.search(try_pattern, content, re.DOTALL):
content = re.sub(try_pattern, new_code, content, flags=re.DOTALL)
with open(file_path, 'w', encoding='utf-8') as f:
f.write(content)
print(f"✅ Updated {file_path}")
else:
print(f"❌ Pattern not found in {file_path}")
else:
print(f"❌ File not found: {file_path}")
print("✅ All files updated!")