"use client"; import React, { useEffect, useState } from "react"; import { SmartSelect, SmartSelectOption } from "@/components/common/SmartSelect"; import { apiClient } from "@/lib/api/client"; /** * 품번/품명 자동완성 셀렉트 * * wace_plm orderMgmtList의 select2-part AJAX 패턴을 단순화한 형태. * - item_info 전체를 한 번 캐시 (id 기준 단일 소스) * - mode='partNo': 라벨로 item_number 표시 * - mode='partName': 라벨로 item_name 표시 * - 선택값(value)은 양쪽 모두 item_info.id (= part_objid) */ interface PartRow { id: string; item_number?: string; item_name?: string; } interface PartSelectProps { mode: "partNo" | "partName"; /** item_info.id (part_objid) */ value: string; /** 옵션 선택 시 part_objid + (선택사항) 마스터 정보(item_number/item_name) 전달 */ onValueChange: (partObjId: string, row?: { item_number?: string; item_name?: string }) => void; placeholder?: string; disabled?: boolean; className?: string; } let cachedRows: PartRow[] | null = null; let inflight: Promise | null = null; const fetchParts = async (): Promise => { if (cachedRows) return cachedRows; if (inflight) return inflight; inflight = (async () => { // 영업관리 4개 메뉴 공통 endpoint — wace 이식 8179건 + COMPANY_16 데이터. const res = await apiClient.get("/sales/parts"); const rows = (res.data?.data ?? []) as any[]; cachedRows = rows .filter((r) => r.id != null) .map((r) => ({ id: String(r.id), item_number: r.item_number ?? "", item_name: r.item_name ?? "", })); return cachedRows!; })(); try { return await inflight; } finally { inflight = null; } }; const toOptions = (rows: PartRow[], mode: PartSelectProps["mode"]): SmartSelectOption[] => rows .filter((r) => mode === "partNo" ? r.item_number : r.item_name) .map((r) => ({ code: r.id, label: String(mode === "partNo" ? r.item_number : r.item_name), })); export function PartSelect({ mode, value, onValueChange, placeholder = mode === "partNo" ? "품번 선택" : "품명 선택", disabled, className, }: PartSelectProps) { const [options, setOptions] = useState( cachedRows ? toOptions(cachedRows, mode) : [], ); useEffect(() => { let alive = true; fetchParts() .then((rows) => { if (alive) setOptions(toOptions(rows, mode)); }) .catch(() => {}); return () => { alive = false; }; }, [mode]); return ( { const row = cachedRows?.find((r) => r.id === v); onValueChange(v, row ? { item_number: row.item_number, item_name: row.item_name } : undefined); }} placeholder={placeholder} disabled={disabled} className={className} /> ); }