diff --git a/src/components/production/WorkerScreen/InspectionInputModal.tsx b/src/components/production/WorkerScreen/InspectionInputModal.tsx
index 6cb8f873..73d3d02b 100644
--- a/src/components/production/WorkerScreen/InspectionInputModal.tsx
+++ b/src/components/production/WorkerScreen/InspectionInputModal.tsx
@@ -11,7 +11,7 @@
* - bending_wip: 재고생산(재공품) 중간검사
*/
-import { useState, useEffect } from 'react';
+import { useState, useEffect, useMemo } from 'react';
import {
Dialog,
DialogContent,
@@ -149,44 +149,81 @@ function OkNgToggle({
);
}
-// 적합/부적합 버튼 컴포넌트
-function JudgmentToggle({
- value,
- onChange,
-}: {
- value: 'pass' | 'fail' | null;
- onChange: (v: 'pass' | 'fail') => void;
-}) {
+// 자동 판정 표시 컴포넌트
+function JudgmentDisplay({ value }: { value: 'pass' | 'fail' | null }) {
return (
-
);
}
+// 공정별 자동 판정 계산
+function hasMeasurement(v: number | null | undefined): boolean {
+ return v != null;
+}
+
+function computeJudgment(processType: InspectionProcessType, data: InspectionData): 'pass' | 'fail' | null {
+ switch (processType) {
+ case 'screen': {
+ const { processingStatus, sewingStatus, assemblyStatus, gapStatus, length, width } = data;
+ // 불량이 하나라도 있으면 즉시 부적합
+ if (processingStatus === 'bad' || sewingStatus === 'bad' || assemblyStatus === 'bad' || gapStatus === 'ng') return 'fail';
+ // 모든 상태 양호 + 측정값 입력 완료 시 적합
+ if (processingStatus === 'good' && sewingStatus === 'good' && assemblyStatus === 'good' && gapStatus === 'ok'
+ && hasMeasurement(length) && hasMeasurement(width)) return 'pass';
+ return null;
+ }
+ case 'slat': {
+ const { processingStatus, assemblyStatus, height1, height2, length } = data;
+ if (processingStatus === 'bad' || assemblyStatus === 'bad') return 'fail';
+ if (processingStatus === 'good' && assemblyStatus === 'good'
+ && hasMeasurement(height1) && hasMeasurement(height2) && hasMeasurement(length)) return 'pass';
+ return null;
+ }
+ case 'slat_jointbar': {
+ const { processingStatus, assemblyStatus, height1, height2, length3, gap4 } = data;
+ if (processingStatus === 'bad' || assemblyStatus === 'bad') return 'fail';
+ if (processingStatus === 'good' && assemblyStatus === 'good'
+ && hasMeasurement(height1) && hasMeasurement(height2) && hasMeasurement(length3) && hasMeasurement(gap4)) return 'pass';
+ return null;
+ }
+ case 'bending': {
+ const { bendingStatus, length } = data;
+ if (bendingStatus === 'bad') return 'fail';
+ if (bendingStatus === 'good' && hasMeasurement(length)) return 'pass';
+ return null;
+ }
+ case 'bending_wip': {
+ const { bendingStatus, length, width } = data;
+ if (bendingStatus === 'bad') return 'fail';
+ if (bendingStatus === 'good' && hasMeasurement(length) && hasMeasurement(width)) return 'pass';
+ return null;
+ }
+ default:
+ return null;
+ }
+}
+
export function InspectionInputModal({
open,
onOpenChange,
@@ -278,6 +315,17 @@ export function InspectionInputModal({
}
}, [open, productName, specification, processType, initialData]);
+ // 자동 판정 계산
+ const autoJudgment = useMemo(() => computeJudgment(processType, formData), [processType, formData]);
+
+ // 판정값 자동 동기화
+ useEffect(() => {
+ setFormData((prev) => {
+ if (prev.judgment === autoJudgment) return prev;
+ return { ...prev, judgment: autoJudgment };
+ });
+ }, [autoJudgment]);
+
const handleComplete = () => {
const data: InspectionData = {
...formData,
@@ -642,11 +690,8 @@ export function InspectionInputModal({
{/* 하단 고정: 판정 + 버튼 */}
- 판정
- setFormData((prev) => ({ ...prev, judgment: v }))}
- />
+ 판정 (자동)
+
= {};
setInspectionDataMap((prev) => {
const next = new Map(prev);
for (const apiItem of result.data!.items) {
@@ -463,10 +464,17 @@ export default function WorkerScreen() {
const match = workItems.find((w) => w.apiItemId === apiItem.item_id);
if (match) {
next.set(match.id, apiItem.inspection_data as unknown as InspectionData);
+ // 중간검사 step 완료 처리
+ const stepKey = match.id.replace('-node-', '-') + '-중간검사';
+ completionUpdates[stepKey] = true;
}
}
return next;
});
+ // stepCompletionMap 일괄 업데이트
+ if (Object.keys(completionUpdates).length > 0) {
+ setStepCompletionMap((prev) => ({ ...prev, ...completionUpdates }));
+ }
}
} catch {
// 검사 데이터 로드 실패는 무시 (새 작업일 수 있음)
@@ -906,6 +914,10 @@ export default function WorkerScreen() {
return next;
});
+ // 중간검사 step 완료 처리
+ const stepKey = selectedOrder.id.replace('-node-', '-') + '-중간검사';
+ setStepCompletionMap((prev) => ({ ...prev, [stepKey]: true }));
+
// 실제 API item인 경우 서버에 저장
const targetItem = workItems.find((w) => w.id === selectedOrder.id);
if (targetItem?.apiItemId && targetItem?.workOrderId) {