From ee13e92b61971ab8cd7de998448f54cb32045d40 Mon Sep 17 00:00:00 2001 From: hyungi Date: Thu, 16 Oct 2025 07:08:19 +0900 Subject: [PATCH] =?UTF-8?q?=F0=9F=93=8A=20=EC=97=91=EC=85=80=20=EB=82=B4?= =?UTF-8?q?=EB=B3=B4=EB=82=B4=EA=B8=B0=20=EA=B0=9C=EC=84=A0=20=EC=99=84?= =?UTF-8?q?=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ✅ 개선 사항: - 품목명에 상세 타입 정보 포함 (빠짐없이) - 타입 컬럼 제거 (중복 방지) - 납기일을 항상 P열에 고정 - 남는 공간을 관리항목1부터 채우기 🔧 상세 개선: - ELBOW: 각도(90°/45°), 반경(LR/SR), 연결방식(SW/BW) 표시 - FLANGE: 풀네임 + 끝단처리 정보 포함 - 모든 카테고리에서 타입 컬럼 제거하고 품목명에 통합 - P열 납기일 고정, 관리항목으로 빈 공간 채우기 --- frontend/src/utils/excelExport.js | 144 +++++++++++++++++++----------- 1 file changed, 93 insertions(+), 51 deletions(-) diff --git a/frontend/src/utils/excelExport.js b/frontend/src/utils/excelExport.js index 7412caf..f0a0e41 100644 --- a/frontend/src/utils/excelExport.js +++ b/frontend/src/utils/excelExport.js @@ -217,9 +217,33 @@ const formatMaterialForExcel = (material, includeComparison = false) => { itemName = 'OLET'; } } else if (fittingType === 'ELBOW') { - // 엘보 각도 표시 - const angle = fittingSubtype === '90DEG' ? '90도' : fittingSubtype === '45DEG' ? '45도' : ''; - itemName = `엘보 ${angle}`.trim(); + // 엘보 상세 정보 표시 (각도, 반경, 연결방식) + let elbowDetails = []; + + // 각도 정보 + if (fittingSubtype.includes('90DEG') || cleanDescription.includes('90')) { + elbowDetails.push('90도'); + } else if (fittingSubtype.includes('45DEG') || cleanDescription.includes('45')) { + elbowDetails.push('45도'); + } else { + elbowDetails.push('90도'); // 기본값 + } + + // 반경 정보 + if (fittingSubtype.includes('LONG_RADIUS') || cleanDescription.toUpperCase().includes('LR')) { + elbowDetails.push('LR'); + } else if (fittingSubtype.includes('SHORT_RADIUS') || cleanDescription.toUpperCase().includes('SR')) { + elbowDetails.push('SR'); + } + + // 연결 방식 + if (cleanDescription.includes('SW')) { + elbowDetails.push('SW'); + } else if (cleanDescription.includes('BW')) { + elbowDetails.push('BW'); + } + + itemName = `엘보 ${elbowDetails.join(' ')}`.trim(); } else if (fittingType === 'TEE') { // 티 타입 표시 const teeType = fittingSubtype === 'EQUAL' ? '등경' : fittingSubtype === 'REDUCING' ? '축소' : ''; @@ -237,29 +261,47 @@ const formatMaterialForExcel = (material, includeComparison = false) => { const flangeType = flangeDetails.flange_type || ''; const facingType = flangeDetails.facing_type || ''; - if (flangeType === 'WELD_NECK') { - itemName = '웰드넥 플랜지'; - } else if (flangeType === 'SLIP_ON') { - itemName = '슬립온 플랜지'; - } else if (flangeType === 'SOCKET_WELD') { - itemName = '소켓웰드 플랜지'; - } else if (flangeType === 'BLIND') { - itemName = '블라인드 플랜지'; - } else if (flangeType === 'REDUCING') { - itemName = '축소 플랜지'; + // 플랜지 타입 풀네임 매핑 (한국어) + const flangeTypeKoreanMap = { + 'WELD_NECK': 'WELD NECK FLANGE', + 'SLIP_ON': 'SLIP ON FLANGE', + 'SOCKET_WELD': 'SOCKET WELD FLANGE', + 'BLIND': 'BLIND FLANGE', + 'REDUCING': 'REDUCING FLANGE', + 'ORIFICE': 'ORIFICE FLANGE', + 'SPECTACLE': 'SPECTACLE BLIND', + 'PADDLE': 'PADDLE BLIND', + 'SPACER': 'SPACER' + }; + + // 끝단처리 정보 추가 + const facingInfo = facingType ? ` ${facingType}` : ''; + + if (flangeType && flangeTypeKoreanMap[flangeType]) { + itemName = `${flangeTypeKoreanMap[flangeType]}${facingInfo}`; } else { - // 특수 플랜지는 구분 + // description에서 추출 const desc = cleanDescription.toUpperCase(); if (desc.includes('ORIFICE')) { - itemName = '오리피스 플랜지'; + itemName = `ORIFICE FLANGE${facingInfo}`; } else if (desc.includes('SPECTACLE')) { - itemName = '스펙터클 블라인드'; + itemName = `SPECTACLE BLIND${facingInfo}`; } else if (desc.includes('PADDLE')) { - itemName = '패들 블라인드'; + itemName = `PADDLE BLIND${facingInfo}`; } else if (desc.includes('SPACER')) { - itemName = '스페이서'; + itemName = `SPACER${facingInfo}`; + } else if (desc.includes('REDUCING') || desc.includes('RED')) { + itemName = `REDUCING FLANGE${facingInfo}`; + } else if (desc.includes('BLIND')) { + itemName = `BLIND FLANGE${facingInfo}`; + } else if (desc.includes('WN')) { + itemName = `WELD NECK FLANGE${facingInfo}`; + } else if (desc.includes('SO')) { + itemName = `SLIP ON FLANGE${facingInfo}`; + } else if (desc.includes('SW')) { + itemName = `SOCKET WELD FLANGE${facingInfo}`; } else { - itemName = '플랜지'; + itemName = `FLANGE${facingInfo}`; } } @@ -624,7 +666,7 @@ const formatMaterialForExcel = (material, includeComparison = false) => { // F~O열: 카테고리별 전용 컬럼 구성 (10개 컬럼) if (category === 'PIPE') { - // 파이프 전용 컬럼 (F~O) + // 파이프 전용 컬럼 (F~O) - 타입 제거, 품목명에 포함됨 base['크기'] = material.size_spec || '-'; // F열 base['압력등급'] = pressure; // G열 base['스케줄'] = schedule; // H열 @@ -636,17 +678,17 @@ const formatMaterialForExcel = (material, includeComparison = false) => { base['관리항목2'] = ''; // N열 base['관리항목3'] = ''; // O열 } else if (category === 'FITTING') { - // 피팅 전용 컬럼 (F~O) + // 피팅 전용 컬럼 (F~O) - 타입 제거, 품목명에 포함됨 base['크기'] = material.size_spec || '-'; // F열 base['압력등급'] = pressure; // G열 - base['타입'] = material.fitting_details?.fitting_type || '-'; // H열 - base['재질'] = grade; // I열 - base['상세내역'] = detailInfo || '-'; // J열 - base['사용자요구'] = material.user_requirement || ''; // K열 - base['관리항목1'] = ''; // L열 - base['관리항목2'] = ''; // M열 - base['관리항목3'] = ''; // N열 - base['관리항목4'] = ''; // O열 + base['재질'] = grade; // H열 + base['상세내역'] = detailInfo || '-'; // I열 + base['사용자요구'] = material.user_requirement || ''; // J열 + base['관리항목1'] = ''; // K열 + base['관리항목2'] = ''; // L열 + base['관리항목3'] = ''; // M열 + base['관리항목4'] = ''; // N열 + base['관리항목5'] = ''; // O열 } else if (category === 'FLANGE') { // 플랜지 타입 풀네임 매핑 (영어) const flangeTypeMap = { @@ -681,34 +723,34 @@ const formatMaterialForExcel = (material, includeComparison = false) => { const rawFlangeType = material.flange_details?.flange_type || ''; const rawFacingType = material.flange_details?.facing_type || ''; - // 플랜지 전용 컬럼 (F~O) + // 플랜지 전용 컬럼 (F~O) - 타입 제거, 품목명에 포함됨 base['크기'] = material.size_spec || '-'; // F열 base['압력등급'] = pressure; // G열 - base['타입'] = flangeTypeMap[rawFlangeType] || rawFlangeType || 'FLANGE'; // H열 - base['재질'] = grade; // I열 - base['페이싱'] = facingTypeMap[rawFacingType] || rawFacingType || '-'; // J열 - base['사용자요구'] = material.user_requirement || ''; // K열 - base['관리항목1'] = ''; // L열 - base['관리항목2'] = ''; // M열 - base['관리항목3'] = ''; // N열 - base['관리항목4'] = ''; // O열 + base['재질'] = grade; // H열 + base['페이싱'] = facingTypeMap[rawFacingType] || rawFacingType || '-'; // I열 + base['사용자요구'] = material.user_requirement || ''; // J열 + base['관리항목1'] = ''; // K열 + base['관리항목2'] = ''; // L열 + base['관리항목3'] = ''; // M열 + base['관리항목4'] = ''; // N열 + base['관리항목5'] = ''; // O열 } else if (category === 'VALVE') { - // 밸브 전용 컬럼 (F~O) + // 밸브 전용 컬럼 (F~O) - 타입 제거, 품목명에 포함됨 base['크기'] = material.size_spec || '-'; // F열 base['압력등급'] = pressure; // G열 - base['타입'] = material.valve_details?.valve_type || '-'; // H열 - base['재질'] = grade; // I열 - base['상세내역'] = detailInfo || '-'; // J열 - base['사용자요구'] = material.user_requirement || ''; // K열 - base['관리항목1'] = ''; // L열 - base['관리항목2'] = ''; // M열 - base['관리항목3'] = ''; // N열 - base['관리항목4'] = ''; // O열 + base['재질'] = grade; // H열 + base['상세내역'] = detailInfo || '-'; // I열 + base['사용자요구'] = material.user_requirement || ''; // J열 + base['관리항목1'] = ''; // K열 + base['관리항목2'] = ''; // L열 + base['관리항목3'] = ''; // M열 + base['관리항목4'] = ''; // N열 + base['관리항목5'] = ''; // O열 } else if (category === 'GASKET') { - // 가스켓 전용 컬럼 (F~O) + // 가스켓 전용 컬럼 (F~O) - 타입 제거, 품목명에 포함됨 base['크기'] = material.size_spec || '-'; // F열 base['압력등급'] = pressure; // G열 - base['타입/구조'] = grade; // H열: H/F/I/O, SWG 등 + base['구조'] = grade; // H열: H/F/I/O, SWG 등 (타입 정보 제거) base['재질'] = gasketMaterial || '-'; // I열: SS304/GRAPHITE/SS304/SS304 base['두께'] = gasketThickness || '-'; // J열: 4.5mm base['사용자요구'] = material.user_requirement || ''; // K열 @@ -717,7 +759,7 @@ const formatMaterialForExcel = (material, includeComparison = false) => { base['관리항목3'] = ''; // N열 base['관리항목4'] = ''; // O열 } else if (category === 'BOLT') { - // 볼트 전용 컬럼 (F~O) + // 볼트 전용 컬럼 (F~O) - 타입 제거, 품목명에 포함됨 base['크기'] = material.size_spec || '-'; // F열 base['압력등급'] = pressure; // G열 base['길이'] = schedule; // H열: 볼트는 길이 정보 @@ -729,7 +771,7 @@ const formatMaterialForExcel = (material, includeComparison = false) => { base['관리항목3'] = ''; // N열 base['관리항목4'] = ''; // O열 } else { - // 기타 카테고리 기본 컬럼 (F~O) + // 기타 카테고리 기본 컬럼 (F~O) - 타입 제거, 품목명에 포함됨 base['크기'] = material.size_spec || '-'; // F열 base['압력등급'] = pressure; // G열 base['스케줄'] = schedule; // H열