'use client'; /** * 슬랫 중간검사 성적서 문서 콘텐츠 * * 기획서 기준: * - 헤더: "중간검사성적서 (슬랫)" + 결재란 * - 기본정보: 제품명/슬랫, 규격/EGI 1.6T, 수주처, 현장명 | 제품LOT NO, 로트크기, 검사일자, 검사자 * - ■ 중간검사 기준서: 도해 + 검사항목/검사기준/검사방법/검사주기/관련규정 * 가공상태, 결모양, 조립상태, 치수(높이/길이) * - ■ 중간검사 DATA: No, 가공상태결모양(양호/불량), 조립상태결모양(양호/불량), * ①높이(기준치/측정값입력), ②높이(기준치/측정값입력), * 길이(엔드락제외)(도면치수/측정값입력), 판정(자동) * - 부적합 내용 / 종합판정(자동) */ import { useState, useCallback, useMemo, forwardRef, useImperativeHandle, useEffect } from 'react'; import type { WorkOrder } from '../types'; import type { InspectionData } from '@/components/production/WorkerScreen/InspectionInputModal'; import type { WorkItemData } from '@/components/production/WorkerScreen/types'; import type { InspectionDataMap } from './InspectionReportModal'; import { type CheckStatus, type InspectionContentRef, convertToCheckStatus, getFullDate, getToday, getOrderInfo, calculateOverallResult, INPUT_CLASS, DEFAULT_ROW_COUNT, CheckStatusCell, JudgmentCell, InspectionLayout, InspectionFooter, } from './inspection-shared'; export type { InspectionContentRef }; export interface SlatInspectionContentProps { data: WorkOrder; readOnly?: boolean; inspectionData?: InspectionData; workItems?: WorkItemData[]; inspectionDataMap?: InspectionDataMap; schematicImage?: string; inspectionStandardImage?: string; } interface InspectionRow { id: number; itemId?: string; itemName?: string; processStatus: CheckStatus; assemblyStatus: CheckStatus; height1Standard: string; height1Measured: string; height2Standard: string; height2Measured: string; lengthDesign: string; lengthMeasured: string; } function buildRow(i: number, workItems?: WorkItemData[], inspectionDataMap?: InspectionDataMap): InspectionRow { const item = workItems?.[i]; const itemData = item && inspectionDataMap?.get(item.id); return { id: i + 1, itemId: item?.id, itemName: item?.itemName || '', processStatus: itemData ? convertToCheckStatus(itemData.processingStatus) : null, assemblyStatus: itemData ? convertToCheckStatus(itemData.assemblyStatus) : null, height1Standard: '16.5 \u00b1 1', height1Measured: itemData?.height1?.toString() || '', height2Standard: '14.5 \u00b1 1', height2Measured: itemData?.height2?.toString() || '', lengthDesign: '0', lengthMeasured: itemData?.length?.toString() || '', }; } export const SlatInspectionContent = forwardRef(function SlatInspectionContent({ data: order, readOnly = false, workItems, inspectionDataMap, schematicImage, }, ref) { const fullDate = getFullDate(); const today = getToday(); const { documentNo, primaryAssignee } = getOrderInfo(order); const rowCount = workItems?.length || DEFAULT_ROW_COUNT; const [rows, setRows] = useState(() => Array.from({ length: rowCount }, (_, i) => buildRow(i, workItems, inspectionDataMap)) ); useEffect(() => { const newRowCount = workItems?.length || DEFAULT_ROW_COUNT; setRows(Array.from({ length: newRowCount }, (_, i) => buildRow(i, workItems, inspectionDataMap))); }, [workItems, inspectionDataMap]); const [inadequateContent, setInadequateContent] = useState(''); const handleStatusChange = useCallback((rowId: number, field: 'processStatus' | 'assemblyStatus', value: CheckStatus) => { if (readOnly) return; setRows(prev => prev.map(row => row.id === rowId ? { ...row, [field]: value } : row )); }, [readOnly]); const handleInputChange = useCallback((rowId: number, field: keyof InspectionRow, value: string) => { if (readOnly) return; const filtered = value.replace(/[^\d.]/g, ''); setRows(prev => prev.map(row => row.id === rowId ? { ...row, [field]: filtered } : row )); }, [readOnly]); const getRowJudgment = useCallback((row: InspectionRow): '적' | '부' | null => { const { processStatus, assemblyStatus } = row; if (processStatus === '불량' || assemblyStatus === '불량') return '부'; if (processStatus === '양호' && assemblyStatus === '양호') return '적'; return null; }, []); const overallResult = useMemo(() => calculateOverallResult(rows.map(getRowJudgment)), [rows, getRowJudgment]); useImperativeHandle(ref, () => ({ getInspectionData: () => ({ rows: rows.map(row => ({ id: row.id, processStatus: row.processStatus, assemblyStatus: row.assemblyStatus, height1Measured: row.height1Measured, height2Measured: row.height2Measured, lengthMeasured: row.lengthMeasured, })), inadequateContent, overallResult, }), }), [rows, inadequateContent, overallResult]); return ( {/* ===== 기본 정보 ===== */}
제품명 슬랫 제품 LOT NO {order.lotNo || '-'}
규격 EGI 1.6T 로트크기 {order.items?.length || 0} 개소
수주처 {order.client || '-'} 검사일자 {today}
현장명 {order.projectName || '-'} 검사자 {primaryAssignee}
{/* ===== 중간검사 기준서 ===== */}
■ 중간검사 기준서
{schematicImage ? ( 기준서 도해 ) : (
도해 이미지 영역
)}
검사항목 검사기준 검사방법 검사주기 관련규정
결모양 가공상태 사용상 해로운 결함이 없을것 육안검사 KS F 4510 5.1항
조립상태 엔드락이 용접에 의해
견고하게 조립되어야 함
용접부위에 락카도색이
되어야 함
n = 1, c = 0 KS F 4510 9항
자체규정
치수
(mm)
높이 16.5 ± 1 체크검사 KS F 4510 7항
표9
14.5 ± 1
길이 도면치수(엔드락제외) ± 4
{/* ===== 중간검사 DATA ===== */}
■ 중간검사 DATA
{rows.map((row) => { const judgment = getRowJudgment(row); return ( handleStatusChange(row.id, 'processStatus', v)} readOnly={readOnly} /> handleStatusChange(row.id, 'assemblyStatus', v)} readOnly={readOnly} /> ); })}
No. 가공상태
결모양
조립상태
결모양
① 높이 (mm) ② 높이 (mm) 길이 (mm)
(엔드락 제외)
판정
(적/부)
기준치 측정값 기준치 측정값 도면치수 측정값
{row.id} {row.height1Standard} handleInputChange(row.id, 'height1Measured', e.target.value)} disabled={readOnly} className={INPUT_CLASS} placeholder="-" /> {row.height2Standard} handleInputChange(row.id, 'height2Measured', e.target.value)} disabled={readOnly} className={INPUT_CLASS} placeholder="-" /> {row.lengthDesign || '-'} handleInputChange(row.id, 'lengthMeasured', e.target.value)} disabled={readOnly} className={INPUT_CLASS} placeholder="-" />
{/* ===== 부적합 내용 + 종합판정 ===== */}
); });