From 6d934b4418c94ab7e93b7bb1c8fd101ec88ffae8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B6=8C=ED=98=81=EC=84=B1?= Date: Thu, 19 Feb 2026 23:46:30 +0900 Subject: [PATCH] =?UTF-8?q?feat(WEB):=20=EC=A0=88=EA=B3=A1=20=EC=9E=91?= =?UTF-8?q?=EC=97=85=EC=9D=BC=EC=A7=80=20bending=5Finfo=EB=A5=BC=20work=5F?= =?UTF-8?q?orders.options=EC=9C=BC=EB=A1=9C=20=EC=9D=B4=EB=8F=99=20+=20?= =?UTF-8?q?=ED=85=8D=EC=8A=A4=ED=8A=B8=20=ED=81=AC=EA=B8=B0=20=ED=86=B5?= =?UTF-8?q?=EC=9D=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - bending_info 저장 위치: work_order_items → work_orders.options으로 변경 - types.ts: WorkOrderApi에 options 필드 추가, 변환 함수에서 order 레벨 bendingInfo 매핑 - BendingWorkLogContent: items 탐색 대신 order.bendingInfo 직접 참조 - utils.ts: getMaterialMapping에 KSS01/KSS02 SUS 제품 지원 추가 - 4개 섹션 컴포넌트: text-[10px]/text-[8px] → text-xs로 통일 (가독성 개선) --- .../documents/BendingWorkLogContent.tsx | 24 +++++++++---------- .../documents/bending/BottomBarSection.tsx | 2 +- .../documents/bending/GuideRailSection.tsx | 4 ++-- .../documents/bending/ShutterBoxSection.tsx | 6 ++--- .../documents/bending/SmokeBarrierSection.tsx | 2 +- .../WorkOrders/documents/bending/utils.ts | 14 ++++++----- src/components/production/WorkOrders/types.ts | 9 +++---- 7 files changed, 32 insertions(+), 29 deletions(-) diff --git a/src/components/production/WorkOrders/documents/BendingWorkLogContent.tsx b/src/components/production/WorkOrders/documents/BendingWorkLogContent.tsx index c82cf060..d1a45c1a 100644 --- a/src/components/production/WorkOrders/documents/BendingWorkLogContent.tsx +++ b/src/components/production/WorkOrders/documents/BendingWorkLogContent.tsx @@ -56,20 +56,20 @@ export function BendingWorkLogContent({ data: order }: BendingWorkLogContentProp }).replace(/\. /g, '-').replace('.', '') : '-'; - // 첫 번째 아이템의 bendingInfo에서 절곡 데이터 추출 - const firstBendingInfo = items.find(item => item.bendingInfo)?.bendingInfo as BendingInfoExtended | undefined; + // 작업지시 레벨의 bendingInfo에서 절곡 데이터 추출 + const bendingInfo = order.bendingInfo as BendingInfoExtended | undefined; // bendingInfo가 없으면 빈 상태 표시 - const hasBendingData = !!firstBendingInfo?.productCode; + const hasBendingData = !!bendingInfo?.productCode; // 재질 매핑 const mapping = hasBendingData - ? getMaterialMapping(firstBendingInfo!.productCode, firstBendingInfo!.finishMaterial) + ? getMaterialMapping(bendingInfo!.productCode, bendingInfo!.finishMaterial) : null; // 생산량 합계 const summary = hasBendingData && mapping - ? calculateProductionSummary(firstBendingInfo!, mapping) + ? calculateProductionSummary(bendingInfo!, mapping) : { susTotal: 0, egiTotal: 0, grandTotal: 0 }; return ( @@ -142,16 +142,16 @@ export function BendingWorkLogContent({ data: order }: BendingWorkLogContentProp - {hasBendingData ? firstBendingInfo!.productCode : '-'} + {hasBendingData ? bendingInfo!.productCode : '-'} {mapping?.bodyMaterial || '-'} - {hasBendingData ? firstBendingInfo!.finishMaterial : '-'} + {hasBendingData ? bendingInfo!.finishMaterial : '-'} - {hasBendingData ? firstBendingInfo!.common.type : '-'} + {hasBendingData ? bendingInfo!.common.type : '-'} @@ -161,19 +161,19 @@ export function BendingWorkLogContent({ data: order }: BendingWorkLogContentProp {hasBendingData && mapping ? ( <> ) : ( diff --git a/src/components/production/WorkOrders/documents/bending/BottomBarSection.tsx b/src/components/production/WorkOrders/documents/bending/BottomBarSection.tsx index c06fbe4e..0324a415 100644 --- a/src/components/production/WorkOrders/documents/bending/BottomBarSection.tsx +++ b/src/components/production/WorkOrders/documents/bending/BottomBarSection.tsx @@ -37,7 +37,7 @@ export function BottomBarSection({ bendingInfo, mapping }: BottomBarSectionProps {/* 우측: 테이블 */}
- +
diff --git a/src/components/production/WorkOrders/documents/bending/GuideRailSection.tsx b/src/components/production/WorkOrders/documents/bending/GuideRailSection.tsx index 83fb2051..bad051fe 100644 --- a/src/components/production/WorkOrders/documents/bending/GuideRailSection.tsx +++ b/src/components/production/WorkOrders/documents/bending/GuideRailSection.tsx @@ -32,7 +32,7 @@ function PartTable({ title, rows, imageUrl, lotNo, baseSize }: { {/* 좌측: 이미지 + LOT */}
{title} -
+
입고&생산 LOT NO:
_______________
@@ -40,7 +40,7 @@ function PartTable({ title, rows, imageUrl, lotNo, baseSize }: { {/* 우측: 테이블 */}
-
세부품명
+
diff --git a/src/components/production/WorkOrders/documents/bending/ShutterBoxSection.tsx b/src/components/production/WorkOrders/documents/bending/ShutterBoxSection.tsx index 46fac236..ee302b98 100644 --- a/src/components/production/WorkOrders/documents/bending/ShutterBoxSection.tsx +++ b/src/components/production/WorkOrders/documents/bending/ShutterBoxSection.tsx @@ -41,18 +41,18 @@ function ShutterBoxSubSection({ box, index }: { box: ShutterBoxData; index: numb className="w-full border border-gray-300" /> {/* 치수 텍스트 오버레이 */} -
+
{box.size} ({box.direction})
-
+
레일폭: {box.railWidth}mm
{/* 우측: 테이블 */}
-
세부품명
+
diff --git a/src/components/production/WorkOrders/documents/bending/SmokeBarrierSection.tsx b/src/components/production/WorkOrders/documents/bending/SmokeBarrierSection.tsx index 4e6ba5e3..10b02b39 100644 --- a/src/components/production/WorkOrders/documents/bending/SmokeBarrierSection.tsx +++ b/src/components/production/WorkOrders/documents/bending/SmokeBarrierSection.tsx @@ -37,7 +37,7 @@ export function SmokeBarrierSection({ bendingInfo }: SmokeBarrierSectionProps) { {/* 우측: 테이블 */}
-
구성요소
+
diff --git a/src/components/production/WorkOrders/documents/bending/utils.ts b/src/components/production/WorkOrders/documents/bending/utils.ts index 946885a3..ee79d3ca 100644 --- a/src/components/production/WorkOrders/documents/bending/utils.ts +++ b/src/components/production/WorkOrders/documents/bending/utils.ts @@ -75,8 +75,8 @@ export function calcWeight(material: string, width: number, height: number): Wei // ============================================================ export function getMaterialMapping(productCode: string, finishMaterial: string): MaterialMapping { - // Group 1: KQTS01 - SUS 마감 - if (productCode === 'KQTS01') { + // Group 1: KQTS01, KSS01, KSS02 - SUS 전용 제품 + if (['KQTS01', 'KSS01', 'KSS02'].includes(productCode)) { return { guideRailFinish: 'SUS 1.2T', bodyMaterial: 'EGI 1.55T', @@ -96,13 +96,14 @@ export function getMaterialMapping(productCode: string, finishMaterial: string): bottomBarExtraFinish: isSUS ? 'SUS 1.2T' : '없음', }; } - // 기타 제품코드 (KSE01, KSS01, KSS02, KWE01 등) - EGI 기본 + // 기타 제품코드 (KSE01, KWE01 등) - EGI 기본, 마감유형에 따라 SUS 추가 + const isSUS = finishMaterial?.includes('SUS'); return { guideRailFinish: 'EGI 1.55T', bodyMaterial: 'EGI 1.55T', - guideRailExtraFinish: '', + guideRailExtraFinish: isSUS ? 'SUS 1.2T' : '', bottomBarFinish: 'EGI 1.55T', - bottomBarExtraFinish: '없음', + bottomBarExtraFinish: isSUS ? 'SUS 1.2T' : '없음', }; } @@ -119,7 +120,8 @@ export function getBendingImageUrl( ): string { switch (category) { case 'guiderail': { - const size = ['KQTS01', 'KTE01'].includes(productCode) + const isLargeProfile = ['KQTS01', 'KTE01'].includes(productCode); + const size = isLargeProfile ? (type === 'wall' ? '130x75' : '130x125') : (type === 'wall' ? '120x70' : '120x120'); return `${API_BASE}/images/bending/guiderail/guiderail_${productCode}_${type}_${size}.jpg`; diff --git a/src/components/production/WorkOrders/types.ts b/src/components/production/WorkOrders/types.ts index caa1bf06..35d4e496 100644 --- a/src/components/production/WorkOrders/types.ts +++ b/src/components/production/WorkOrders/types.ts @@ -206,7 +206,8 @@ export interface WorkOrder { // 공정 진행 상태 (현재 단계) currentStep: number; - // 절곡 전용 - 전개도 상세 + // 절곡 전용 + bendingInfo?: Record; // 작업지시 레벨 bending_info (work_orders.options) bendingDetails?: BendingDetail[]; // 이슈 @@ -339,6 +340,7 @@ export interface WorkOrderApi { team_id: number | null; scheduled_date: string | null; memo: string | null; + options?: { bending_info?: Record; [key: string]: unknown } | null; is_active: boolean; created_by: number | null; updated_by: number | null; @@ -482,9 +484,7 @@ export function transformApiToFrontend(api: WorkOrderApi): WorkOrder { const si = item.options.slat_info as { length?: number; slat_count?: number; joint_bar?: number; glass_qty?: number }; return { length: si.length || 0, slatCount: si.slat_count || 0, jointBar: si.joint_bar || 0, glassQty: si.glass_qty || 0 }; })() : undefined, - bendingInfo: item.options?.bending_info - ? (item.options.bending_info as Record) - : undefined, + bendingInfo: undefined, // deprecated: work order 레벨로 이동 (order.bendingInfo) materialInputLots: (() => { const inputs = item.material_inputs as Array<{ stock_lot?: { lot_no?: string } }> | undefined; if (!inputs || inputs.length === 0) return undefined; @@ -492,6 +492,7 @@ export function transformApiToFrontend(api: WorkOrderApi): WorkOrder { return lots.length > 0 ? [...new Set(lots)] : undefined; })(), })), + bendingInfo: api.options?.bending_info || undefined, bendingDetails: api.bending_detail ? transformBendingDetail(api.bending_detail) : undefined, issues: (api.issues || []).map(issue => ({ id: String(issue.id),
파트