From 31e225f6d3691c91a0cafffba3fc13126ccd3b76 Mon Sep 17 00:00:00 2001 From: SeongHyun Kim Date: Tue, 7 Apr 2026 16:59:25 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20POP=20=ED=99=94=EB=A9=B4=EC=84=A4?= =?UTF-8?q?=EC=A0=95=20=EC=B1=84=EB=B2=88=EA=B7=9C=EC=B9=99=20=EC=85=80?= =?UTF-8?q?=EB=A0=89=ED=8A=B8=20=EB=B0=95=EC=8A=A4=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 새 type "numbering-rule" 추가 - NumberingRuleSelect 컴포넌트: 회사별 채번규칙 목록 자동 로드 - 입고/출고 설정에서 inbound/outbound 키워드로 필터링 - 등록된 채번규칙이 없으면 안내 메시지 표시 --- .scannerwork/.sonar_lock | 0 .scannerwork/report-task.txt | 6 ++ .../admin/screenMng/popSettingsMng/page.tsx | 85 ++++++++++++++++++- sonar-project.properties | 6 +- 4 files changed, 91 insertions(+), 6 deletions(-) create mode 100644 .scannerwork/.sonar_lock create mode 100644 .scannerwork/report-task.txt diff --git a/.scannerwork/.sonar_lock b/.scannerwork/.sonar_lock new file mode 100644 index 00000000..e69de29b diff --git a/.scannerwork/report-task.txt b/.scannerwork/report-task.txt new file mode 100644 index 00000000..363424f2 --- /dev/null +++ b/.scannerwork/report-task.txt @@ -0,0 +1,6 @@ +projectKey=vexplor +serverUrl=http://localhost:9000 +serverVersion=26.3.0.120487 +dashboardUrl=http://localhost:9000/dashboard?id=vexplor +ceTaskId=f2c72369-4d50-4483-bf76-b03788385757 +ceTaskUrl=http://localhost:9000/api/ce/task?id=f2c72369-4d50-4483-bf76-b03788385757 diff --git a/frontend/app/(main)/admin/screenMng/popSettingsMng/page.tsx b/frontend/app/(main)/admin/screenMng/popSettingsMng/page.tsx index 80d8b7dd..1b5ee89d 100644 --- a/frontend/app/(main)/admin/screenMng/popSettingsMng/page.tsx +++ b/frontend/app/(main)/admin/screenMng/popSettingsMng/page.tsx @@ -165,15 +165,16 @@ interface SettingField { key: string; label: string; description: string; - type: "toggle" | "text" | "number" | "select" | "color" | "tags" | "array-object"; + type: "toggle" | "text" | "number" | "select" | "color" | "tags" | "array-object" | "numbering-rule"; defaultValue?: unknown; options?: { value: string; label: string }[]; fields?: { key: string; label: string; type: string }[]; + tableFilter?: string; // numbering-rule용: inbound/outbound 등 } const SETTINGS_SCHEMA: Record = { inbound: [ - { key: "numberingRuleId", label: "📋 입고번호 채번규칙", description: "입고 확정 시 사용할 채번규칙을 선택합니다", type: "text" }, + { key: "numberingRuleId", label: "📋 입고번호 채번규칙", description: "입고 확정 시 사용할 채번규칙을 선택합니다", type: "numbering-rule", tableFilter: "inbound" }, { key: "barcodeEnabled", label: "바코드 스캔 (미구현)", description: "바코드/QR 스캔 기능을 사용합니다", type: "toggle" }, { key: "inspectionRequired", label: "검사 필수 (미구현)", description: "입고 시 검사 항목을 필수로 표시합니다", type: "toggle" }, { key: "photoUpload", label: "사진 첨부 (미구현)", description: "입고 확정 시 사진 첨부를 허용합니다", type: "toggle" }, @@ -181,7 +182,7 @@ const SETTINGS_SCHEMA: Record = { { key: "defectSeparation", label: "불량 분리 (미구현)", description: "양품/불량 수량을 분리 입력합니다", type: "toggle" }, ], outbound: [ - { key: "numberingRuleId", label: "📋 출고번호 채번규칙", description: "출고 확정 시 사용할 채번규칙을 선택합니다", type: "text" }, + { key: "numberingRuleId", label: "📋 출고번호 채번규칙", description: "출고 확정 시 사용할 채번규칙을 선택합니다", type: "numbering-rule", tableFilter: "outbound" }, { key: "barcodeEnabled", label: "바코드 스캔 (미구현)", description: "바코드/QR 스캔 기능을 사용합니다", type: "toggle" }, { key: "photoUpload", label: "사진 첨부 (미구현)", description: "출고 시 사진 첨부를 허용합니다", type: "toggle" }, ], @@ -256,6 +257,82 @@ const SETTINGS_SCHEMA: Record = { ], }; +// ============================================================ +// 채번규칙 셀렉트 컴포넌트 +// ============================================================ + +function NumberingRuleSelect({ + field, + value, + onChange, +}: { + field: SettingField; + value: unknown; + onChange: (value: unknown) => void; +}) { + const { user } = useAuth(); + const [rules, setRules] = useState<{ value: string; label: string }[]>([]); + const [loading, setLoading] = useState(false); + + useEffect(() => { + const loadRules = async () => { + setLoading(true); + try { + const companyCode = user?.companyCode || "COMPANY_7"; + const res = await apiClient.get(`/numbering-rules?company_code=${companyCode}`); + const data = res.data?.data || res.data || []; + const allRules = Array.isArray(data) ? data : (data.rules || []); + // tableFilter로 필터링 (inbound/outbound 등) + const filtered = field.tableFilter + ? allRules.filter((r: any) => + (r.table_name || "").toLowerCase().includes(field.tableFilter!) || + (r.rule_name || r.column_name || "").toLowerCase().includes(field.tableFilter!) + ) + : allRules; + setRules( + filtered.length > 0 + ? filtered.map((r: any) => ({ + value: r.id || r.rule_id, + label: `${r.rule_name || r.table_name + "." + r.column_name} (${r.prefix || ""}${r.separator || ""}...)`, + })) + : allRules.map((r: any) => ({ + value: r.id || r.rule_id, + label: `${r.rule_name || r.table_name + "." + r.column_name}`, + })) + ); + } catch { + setRules([]); + } + setLoading(false); + }; + loadRules(); + }, [user?.companyCode, field.tableFilter]); + + return ( +
+ +

{field.description}

+ {loading ? ( +

채번규칙 로드 중...

+ ) : rules.length === 0 ? ( +

등록된 채번규칙이 없습니다. PC에서 먼저 채번규칙을 등록해주세요.

+ ) : ( + + )} +
+ ); +} + // ============================================================ // Sub-components: TagEditor, ArrayObjectEditor // ============================================================ @@ -484,6 +561,8 @@ function SettingRow({ ); + case "numbering-rule": + return ; case "color": return (
diff --git a/sonar-project.properties b/sonar-project.properties index 4a233136..b08e2bd3 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -1,7 +1,7 @@ sonar.projectKey=vexplor sonar.projectName=vexplor -sonar.sources=backend-node/src,frontend/src -sonar.exclusions=**/node_modules/**,**/dist/**,**/*.test.*,**/test-scenarios/** -sonar.javascript.lcov.reportPaths=coverage/lcov.info +sonar.sources=backend-node/src +sonar.exclusions=**/node_modules/**,**/dist/**,**/*.test.*,**/test-scenarios/**,**/build/**,**/.next/** sonar.host.url=http://localhost:9000 sonar.sourceEncoding=UTF-8 +sonar.scm.disabled=true