볼트 분류 개선 및 업로드 성능 최적화

- 볼트 길이 추출 로직 개선: '70.0000 LG' 형태 인식 추가
- 재질 중복 표시 수정: 'ASTM A193 ASTM A193 B7' → 'B7'
- A193/A194 등급 추출 로직 개선: 'GR B7/2H' 형태 지원
- bolt_details 테이블에 pressure_rating 컬럼 추가
- 볼트 분류기 오분류 방지: 플랜지/피팅이 볼트로 분류되지 않도록 수정
- 업로드 성능 개선: 키워드 기반 빠른 분류기 선택 로직 추가
- 분류 키워드 대폭 확장: 피팅/파이프/플랜지 키워드 추가
This commit is contained in:
Hyungi Ahn
2025-07-18 12:48:24 +09:00
parent 25ce3590ee
commit 3dd301cb57
13 changed files with 1184 additions and 106 deletions

View File

@@ -205,7 +205,8 @@ def classify_gasket(dat_file: str, description: str, main_nom: str, length: floa
"material": gasket_material_result.get('material', 'UNKNOWN'),
"characteristics": gasket_material_result.get('characteristics', ''),
"temperature_range": gasket_material_result.get('temperature_range', ''),
"confidence": gasket_material_result.get('confidence', 0.0)
"confidence": gasket_material_result.get('confidence', 0.0),
"swg_details": gasket_material_result.get('swg_details', {})
},
# 가스켓 분류 정보
@@ -294,16 +295,72 @@ def classify_gasket_type(dat_file: str, description: str) -> Dict:
"applications": ""
}
def parse_swg_details(description: str) -> Dict:
"""SWG (Spiral Wound Gasket) 상세 정보 파싱"""
desc_upper = description.upper()
result = {
"face_type": "UNKNOWN",
"outer_ring": "UNKNOWN",
"filler": "UNKNOWN",
"inner_ring": "UNKNOWN",
"thickness": None,
"detailed_construction": "",
"confidence": 0.0
}
# H/F/I/O 패턴 파싱 (Head/Face/Inner/Outer)
hfio_pattern = r'H/F/I/O|HFIO'
if re.search(hfio_pattern, desc_upper):
result["face_type"] = "H/F/I/O"
result["confidence"] += 0.3
# 재질 구성 파싱 (SS304/GRAPHITE/CS/CS)
# H/F/I/O 다음에 나오는 재질 구성을 찾음
material_pattern = r'H/F/I/O\s+([A-Z0-9]+)/([A-Z]+)/([A-Z0-9]+)/([A-Z0-9]+)'
material_match = re.search(material_pattern, desc_upper)
if material_match:
result["outer_ring"] = material_match.group(1) # SS304
result["filler"] = material_match.group(2) # GRAPHITE
result["inner_ring"] = material_match.group(3) # CS
# 네 번째는 보통 outer ring 반복
result["detailed_construction"] = f"{material_match.group(1)}/{material_match.group(2)}/{material_match.group(3)}/{material_match.group(4)}"
result["confidence"] += 0.4
else:
# H/F/I/O 없이 재질만 있는 경우
material_pattern_simple = r'([A-Z0-9]+)/([A-Z]+)/([A-Z0-9]+)/([A-Z0-9]+)'
material_match = re.search(material_pattern_simple, desc_upper)
if material_match:
result["outer_ring"] = material_match.group(1)
result["filler"] = material_match.group(2)
result["inner_ring"] = material_match.group(3)
result["detailed_construction"] = f"{material_match.group(1)}/{material_match.group(2)}/{material_match.group(3)}/{material_match.group(4)}"
result["confidence"] += 0.3
# 두께 파싱 (4.5mm)
thickness_pattern = r'(\d+(?:\.\d+)?)\s*MM'
thickness_match = re.search(thickness_pattern, desc_upper)
if thickness_match:
result["thickness"] = float(thickness_match.group(1))
result["confidence"] += 0.3
return result
def classify_gasket_material(description: str) -> Dict:
"""가스켓 전용 재질 분류"""
"""가스켓 전용 재질 분류 (SWG 상세 정보 포함)"""
desc_upper = description.upper()
# 가스켓 전용 재질 확인
# SWG 상세 정보 파싱
swg_details = None
if "SWG" in desc_upper or "SPIRAL WOUND" in desc_upper:
swg_details = parse_swg_details(description)
# 기본 가스켓 재질 확인
for material_type, material_data in GASKET_MATERIALS.items():
for keyword in material_data["keywords"]:
if keyword in desc_upper:
return {
result = {
"material": material_type,
"characteristics": material_data["characteristics"],
"temperature_range": material_data["temperature_range"],
@@ -311,6 +368,13 @@ def classify_gasket_material(description: str) -> Dict:
"matched_keyword": keyword,
"applications": material_data["applications"]
}
# SWG 상세 정보 추가
if swg_details and swg_details["confidence"] > 0:
result["swg_details"] = swg_details
result["confidence"] = min(0.95, result["confidence"] + swg_details["confidence"] * 0.1)
return result
# 일반 재질 키워드 확인
if any(keyword in desc_upper for keyword in ["RUBBER", "고무"]):