feat: 자재 리비전 비교 및 구매 목록 시스템 구현

- 자재 리비전간 비교 기능 추가 (MaterialComparisonPage) - 버그 해결 필요
- 리비전간 추가 구매 필요 자재 분석 페이지 추가 (RevisionPurchasePage)
- 자재 비교 결과 컴포넌트 구현 (MaterialComparisonResult)
- 자재 비교 API 라우터 추가 (material_comparison.py) - 로직 개선 필요
- 자재 비교 시스템 데이터베이스 스키마 추가
- FileManager, FileUpload 컴포넌트 개선
- BOMManagerPage 제거 및 새로운 구조로 리팩토링
- 자재 분류기 및 스키마 개선

TODO: 자재 비교 알고리즘 정확도 향상 및 예외 처리 강화 필요
This commit is contained in:
Hyungi Ahn
2025-07-22 15:56:40 +09:00
parent 6ca1cd17e2
commit 534015cc7c
16 changed files with 2577 additions and 267 deletions

View File

@@ -131,13 +131,16 @@ def check_astm_standard(description: str, standard: str, standard_data: Dict) ->
for pattern in standard_data["patterns"]:
match = re.search(pattern, description)
if match:
grade_code = match.group(1) if match.groups() else ""
full_grade = f"ASTM {standard}" + (f" {grade_code}" if grade_code else "")
return {
"standard": f"ASTM {standard}",
"grade": f"ASTM {standard}",
"material_type": determine_material_type(standard, ""),
"grade": full_grade,
"material_type": determine_material_type(standard, grade_code),
"manufacturing": standard_data.get("manufacturing", "UNKNOWN"),
"confidence": 0.9,
"evidence": [f"ASTM_{standard}: Direct Match"]
"evidence": [f"ASTM_{standard}: {grade_code if grade_code else 'Direct Match'}"]
}
# 하위 분류가 있는 경우 (A182, A234 등)
@@ -149,9 +152,27 @@ def check_astm_standard(description: str, standard: str, standard_data: Dict) ->
grade_code = match.group(1) if match.groups() else ""
grade_info = subtype_data["grades"].get(grade_code, {})
# A312의 경우 TP304 형태로 전체 grade 표시
if standard == "A312" and grade_code and not grade_code.startswith("TP"):
full_grade = f"ASTM {standard} TP{grade_code}"
elif grade_code.startswith("TP"):
full_grade = f"ASTM {standard} {grade_code}"
# A403의 경우 WP304 형태로 전체 grade 표시
elif standard == "A403" and grade_code and not grade_code.startswith("WP"):
full_grade = f"ASTM {standard} WP{grade_code}"
elif grade_code.startswith("WP"):
full_grade = f"ASTM {standard} {grade_code}"
# A420의 경우 WPL3 형태로 전체 grade 표시
elif standard == "A420" and grade_code and not grade_code.startswith("WPL"):
full_grade = f"ASTM {standard} WPL{grade_code}"
elif grade_code.startswith("WPL"):
full_grade = f"ASTM {standard} {grade_code}"
else:
full_grade = f"ASTM {standard} {grade_code}" if grade_code else f"ASTM {standard}"
return {
"standard": f"ASTM {standard}",
"grade": f"ASTM {standard} {grade_code}",
"grade": full_grade,
"material_type": determine_material_type(standard, grade_code),
"manufacturing": subtype_data.get("manufacturing", "UNKNOWN"),
"composition": grade_info.get("composition", ""),
@@ -275,7 +296,7 @@ def get_manufacturing_method_from_material(material_result: Dict) -> str:
# 직접 매핑
if 'A182' in material_standard or 'A105' in material_standard:
return 'FORGED'
elif 'A234' in material_standard or 'A403' in material_standard:
elif 'A234' in material_standard or 'A403' in material_standard or 'A420' in material_standard:
return 'WELDED_FABRICATED'
elif 'A216' in material_standard or 'A351' in material_standard:
return 'CAST'