fix(WEB):검사 문서 데이터 소스 일관성 및 레거시 템플릿 폴백

- InspectionReportModal: props/API 데이터 소스를 쌍으로 선택하여 key 포맷 불일치 방지
- TemplateInspectionContent: 템플릿 버전 불일치 시 레거시 필드를 컬럼 라벨로 매칭하여 복원
This commit is contained in:
2026-02-13 03:42:02 +09:00
parent 841c284586
commit ffe0ebad35
2 changed files with 46 additions and 3 deletions

View File

@@ -135,10 +135,17 @@ export function InspectionReportModal({
const [selfTemplateData, setSelfTemplateData] = useState<InspectionTemplateData | null>(null);
// props에서 목업 제외한 실제 개소만 사용 (WorkerScreen에서 apiItems + mockItems가 합쳐져 전달됨)
// props 데이터가 없거나 비어있으면 API 로딩 데이터를 fallback으로 사용
// ★ 반드시 workItems와 inspectionDataMap을 같은 소스에서 가져와야 key 포맷이 일치함
// props: key = "${orderId}-node-${nodeKey}" (예: "18-node-1층/FSS-01")
// API: key = "report-item-${itemId}" (예: "report-item-42")
const propFiltered = propWorkItems?.filter(w => !w.id.startsWith('mock-'));
const effectiveWorkItems = (propFiltered && propFiltered.length > 0) ? propFiltered : apiWorkItems ?? undefined;
const effectiveInspectionDataMap = (propInspectionDataMap && propInspectionDataMap.size > 0) ? propInspectionDataMap : apiInspectionDataMap ?? undefined;
const propHasWorkItems = propFiltered && propFiltered.length > 0;
const propHasInspectionData = propInspectionDataMap && propInspectionDataMap.size > 0;
const usePropsSource = propHasWorkItems && propHasInspectionData;
const effectiveWorkItems = usePropsSource ? propFiltered : apiWorkItems ?? undefined;
const effectiveInspectionDataMap = usePropsSource ? propInspectionDataMap : apiInspectionDataMap ?? undefined;
// 목업 WorkOrder 생성
const createMockOrder = (id: string, pType: ProcessType): WorkOrder => ({

View File

@@ -253,6 +253,42 @@ export const TemplateInspectionContent = forwardRef<InspectionContentRef, Templa
}
}
});
// ★ 템플릿 버전 불일치 폴백: templateValues 키가 현재 템플릿과 맞지 않으면
// 레거시 필드(processingStatus, sewingStatus 등)를 컬럼 라벨로 매칭하여 복원
if (Object.keys(initial).length === 0) {
const hasAnyData = workItems.some((wi) => inspectionDataMap.get(wi.id));
if (hasAnyData) {
// 컬럼 라벨 → 레거시 필드 매핑
const labelToLegacy: Record<string, (d: Record<string, unknown>) => unknown> = {
'가공상태': (d) => d.processingStatus === 'good' ? 'ok' : d.processingStatus === 'bad' ? 'ng' : null,
'재봉상태': (d) => d.sewingStatus === 'good' ? 'ok' : d.sewingStatus === 'bad' ? 'ng' : null,
'조립상태': (d) => d.assemblyStatus === 'good' ? 'ok' : d.assemblyStatus === 'bad' ? 'ng' : null,
'절곡상태': (d) => d.bendingStatus === 'good' ? 'ok' : d.bendingStatus === 'bad' ? 'ng' : null,
'길이': (d) => d.length,
'높이': (d) => d.width,
'간격': (d) => d.gapStatus === 'ok' ? 'ok' : d.gapStatus === 'ng' ? 'ng' : null,
};
workItems.forEach((wi, rowIdx) => {
const itemData = inspectionDataMap.get(wi.id) as Record<string, unknown> | undefined;
if (!itemData) return;
for (const col of template.columns) {
const cellKey = `${rowIdx}-${col.id}`;
// 컬럼 라벨에서 번호 접두사 제거 후 매칭 (예: "① 길이" → "길이")
const labelClean = col.label.replace(/[①②③④⑤⑥⑦⑧⑨⑩\s]/g, '');
const matchEntry = Object.entries(labelToLegacy).find(([key]) => labelClean.includes(key));
if (!matchEntry) continue;
const val = matchEntry[1](itemData);
if (val == null) continue;
if (val === 'ok') initial[cellKey] = { status: 'good' };
else if (val === 'ng') initial[cellKey] = { status: 'bad' };
else if (typeof val === 'number') initial[cellKey] = { value: String(val) };
else if (typeof val === 'string') initial[cellKey] = { value: val };
}
});
}
}
if (Object.keys(initial).length > 0) setCellValues(initial);
// 부적합 내용 복원: 각 개소의 nonConformingContent를 수집