From 83a23701a79ce3cb9df59ea73c139136e411d406 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B6=8C=ED=98=81=EC=84=B1?= Date: Wed, 4 Mar 2026 10:35:43 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20[shipment]=20=EB=B0=B0=EC=B0=A8?= =?UTF-8?q?=EC=A0=95=EB=B3=B4=20=EB=8B=A4=EC=A4=91=20=ED=96=89=20API=20?= =?UTF-8?q?=EC=97=B0=EB=8F=99=20=E2=80=94=20actions.ts=20transform=20?= =?UTF-8?q?=ED=95=A8=EC=88=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ShipmentApiData에 vehicle_dispatches 타입 추가 - transformApiToDetail: vehicle_dispatches 배열 매핑 (레거시 단일필드 fallback 유지) - transformCreateFormToApi/transformEditFormToApi: vehicleDispatches → vehicle_dispatches 변환 추가 - transformApiToListItem: 첫 번째 배차의 arrival_datetime 반영 --- .../outbound/ShipmentManagement/actions.ts | 86 ++++++++++++++++--- 1 file changed, 72 insertions(+), 14 deletions(-) diff --git a/src/components/outbound/ShipmentManagement/actions.ts b/src/components/outbound/ShipmentManagement/actions.ts index b2ebb025..75db8eec 100644 --- a/src/components/outbound/ShipmentManagement/actions.ts +++ b/src/components/outbound/ShipmentManagement/actions.ts @@ -94,6 +94,16 @@ interface ShipmentApiData { created_at?: string; updated_at?: string; items?: ShipmentItemApiData[]; + vehicle_dispatches?: Array<{ + id: number; + seq: number; + logistics_company?: string; + arrival_datetime?: string; + tonnage?: string; + vehicle_no?: string; + driver_contact?: string; + remarks?: string; + }>; status_label?: string; priority_label?: string; delivery_method_label?: string; @@ -149,7 +159,7 @@ function transformApiToListItem(data: ShipmentApiData): ShipmentItem { canShip: data.can_ship, depositConfirmed: data.deposit_confirmed, invoiceIssued: data.invoice_issued, - deliveryTime: data.expected_arrival, + deliveryTime: data.vehicle_dispatches?.[0]?.arrival_datetime || data.expected_arrival, // 수신/작성자/출고일 매핑 receiver: data.receiver || '', receiverAddress: data.order_info?.delivery_address || data.delivery_address || '', @@ -202,18 +212,28 @@ function transformApiToDetail(data: ShipmentApiData): ShipmentDetail { zipCode: (data as unknown as Record).zip_code as string | undefined, address: (data as unknown as Record).address as string | undefined, addressDetail: (data as unknown as Record).address_detail as string | undefined, - // 배차 정보 - 기존 단일 필드에서 구성 (다중 행 API 준비 전까지) - vehicleDispatches: data.vehicle_no || data.logistics_company || data.driver_contact - ? [{ - id: `vd-${data.id}`, - logisticsCompany: data.logistics_company || '-', - arrivalDateTime: data.confirmed_arrival || data.expected_arrival || '-', - tonnage: data.vehicle_tonnage || '-', - vehicleNo: data.vehicle_no || '-', - driverContact: data.driver_contact || '-', - remarks: '', - }] - : [], + // 배차 정보 - vehicle_dispatches 테이블에서 조회, 없으면 레거시 단일 필드 fallback + vehicleDispatches: data.vehicle_dispatches && data.vehicle_dispatches.length > 0 + ? data.vehicle_dispatches.map((vd) => ({ + id: String(vd.id), + logisticsCompany: vd.logistics_company || '-', + arrivalDateTime: vd.arrival_datetime || '-', + tonnage: vd.tonnage || '-', + vehicleNo: vd.vehicle_no || '-', + driverContact: vd.driver_contact || '-', + remarks: vd.remarks || '', + })) + : (data.vehicle_no || data.logistics_company || data.driver_contact + ? [{ + id: `vd-legacy-${data.id}`, + logisticsCompany: data.logistics_company || '-', + arrivalDateTime: data.confirmed_arrival || data.expected_arrival || '-', + tonnage: data.vehicle_tonnage || '-', + vehicleNo: data.vehicle_no || '-', + driverContact: data.driver_contact || '-', + remarks: '', + }] + : []), // 제품내용 (그룹핑) - 프론트엔드에서 그룹핑 처리 productGroups: [], otherParts: [], @@ -265,7 +285,7 @@ function transformApiToStatsByStatus(data: ShipmentApiStatsByStatusResponse): Sh function transformCreateFormToApi( data: ShipmentCreateFormData ): Record { - return { + const result: Record = { lot_no: data.lotNo, scheduled_date: data.scheduledDate, priority: data.priority, @@ -276,6 +296,20 @@ function transformCreateFormToApi( loading_manager: data.loadingManager, remarks: data.remarks, }; + + if (data.vehicleDispatches && data.vehicleDispatches.length > 0) { + result.vehicle_dispatches = data.vehicleDispatches.map((vd, idx) => ({ + seq: idx + 1, + logistics_company: vd.logisticsCompany || null, + arrival_datetime: vd.arrivalDateTime || null, + tonnage: vd.tonnage || null, + vehicle_no: vd.vehicleNo || null, + driver_contact: vd.driverContact || null, + remarks: vd.remarks || null, + })); + } + + return result; } // ===== Frontend → API 변환 (수정용) ===== @@ -287,6 +321,17 @@ function transformEditFormToApi( if (data.scheduledDate !== undefined) result.scheduled_date = data.scheduledDate; if (data.priority !== undefined) result.priority = data.priority; if (data.deliveryMethod !== undefined) result.delivery_method = data.deliveryMethod; + if (data.receiver !== undefined) result.receiver = data.receiver; + if (data.receiverContact !== undefined) result.receiver_contact = data.receiverContact; + // 주소: zipCode + address + addressDetail → delivery_address로 결합 + if (data.address !== undefined || data.zipCode !== undefined || data.addressDetail !== undefined) { + const parts = [ + data.zipCode ? `[${data.zipCode}]` : '', + data.address || '', + data.addressDetail || '', + ].filter(Boolean); + result.delivery_address = parts.join(' '); + } if (data.loadingManager !== undefined) result.loading_manager = data.loadingManager; if (data.logisticsCompany !== undefined) result.logistics_company = data.logisticsCompany; if (data.vehicleTonnage !== undefined) result.vehicle_tonnage = data.vehicleTonnage; @@ -296,8 +341,21 @@ function transformEditFormToApi( if (data.driverContact !== undefined) result.driver_contact = data.driverContact; if (data.expectedArrival !== undefined) result.expected_arrival = data.expectedArrival; if (data.confirmedArrival !== undefined) result.confirmed_arrival = data.confirmedArrival; + if (data.changeReason !== undefined) result.change_reason = data.changeReason; if (data.remarks !== undefined) result.remarks = data.remarks; + if (data.vehicleDispatches) { + result.vehicle_dispatches = data.vehicleDispatches.map((vd, idx) => ({ + seq: idx + 1, + logistics_company: vd.logisticsCompany || null, + arrival_datetime: vd.arrivalDateTime || null, + tonnage: vd.tonnage || null, + vehicle_no: vd.vehicleNo || null, + driver_contact: vd.driverContact || null, + remarks: vd.remarks || null, + })); + } + return result; }