feat(WEB):작업일지 공정관리 양식 연동 및 자재 LOT 동적화

- WorkLogModal: workLogTemplateId/Name prop 추가, 공정관리 매핑 기반 콘텐츠 분기
- WorkerScreen: activeProcessSettings에 workLogTemplateId/Name 추가
- ScreenWorkLogContent: 내화실 LOT 하드코딩 → materialLots item_name별 동적 그룹핑
- SlatWorkLogContent/BendingWorkLogContent: 소규모 수정
This commit is contained in:
2026-02-12 00:01:03 +09:00
parent 91100ca635
commit fcd5408052
5 changed files with 328 additions and 99 deletions

View File

@@ -5,15 +5,17 @@
*
* document-system 통합 버전 (2026-01-22)
* 공정별 작업일지 지원 (2026-01-29)
* 공정관리 양식 매핑 연동 (2026-02-11)
* - DocumentViewer 사용
* - 공정 타입에 따라 스크린/슬랫/절곡 작업일지 분기
* - processType 미지정 시 기존 WorkLogContent (범용) 사용
* - 공정관리에서 매핑된 workLogTemplateId/Name 기반으로 콘텐츠 분기
* - 양식 미매핑 시 processType 폴백
*/
import { useState, useEffect } from 'react';
import { Loader2 } from 'lucide-react';
import { DocumentViewer } from '@/components/document-system';
import { getWorkOrderById } from '../WorkOrders/actions';
import { getWorkOrderById, getMaterialInputLots } from '../WorkOrders/actions';
import type { MaterialInputLot } from '../WorkOrders/actions';
import type { WorkOrder, ProcessType } from '../WorkOrders/types';
import { WorkLogContent } from './WorkLogContent';
import {
@@ -27,10 +29,34 @@ interface WorkLogModalProps {
onOpenChange: (open: boolean) => void;
workOrderId: string | null;
processType?: ProcessType;
/** 공정관리에서 매핑된 작업일지 양식 ID */
workLogTemplateId?: number;
/** 공정관리에서 매핑된 작업일지 양식명 (예: '스크린 작업일지') */
workLogTemplateName?: string;
}
export function WorkLogModal({ open, onOpenChange, workOrderId, processType }: WorkLogModalProps) {
/**
* 양식명 → 공정 타입 매핑
* 공정관리에서 매핑된 양식명을 기반으로 콘텐츠 컴포넌트를 결정
*/
function resolveProcessTypeFromTemplate(templateName?: string): ProcessType | undefined {
if (!templateName) return undefined;
if (templateName.includes('스크린')) return 'screen';
if (templateName.includes('슬랫')) return 'slat';
if (templateName.includes('절곡')) return 'bending';
return undefined;
}
export function WorkLogModal({
open,
onOpenChange,
workOrderId,
processType,
workLogTemplateId,
workLogTemplateName,
}: WorkLogModalProps) {
const [order, setOrder] = useState<WorkOrder | null>(null);
const [materialLots, setMaterialLots] = useState<MaterialInputLot[]>([]);
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
@@ -82,12 +108,18 @@ export function WorkLogModal({ open, onOpenChange, workOrderId, processType }: W
setIsLoading(true);
setError(null);
getWorkOrderById(workOrderId)
.then((result) => {
if (result.success && result.data) {
setOrder(result.data);
Promise.all([
getWorkOrderById(workOrderId),
getMaterialInputLots(workOrderId),
])
.then(([orderResult, lotsResult]) => {
if (orderResult.success && orderResult.data) {
setOrder(orderResult.data);
} else {
setError(result.error || '데이터를 불러올 수 없습니다.');
setError(orderResult.error || '데이터를 불러올 수 없습니다.');
}
if (lotsResult.success) {
setMaterialLots(lotsResult.data);
}
})
.catch(() => {
@@ -99,6 +131,7 @@ export function WorkLogModal({ open, onOpenChange, workOrderId, processType }: W
} else if (!open) {
// 모달 닫힐 때 상태 초기화
setOrder(null);
setMaterialLots([]);
setError(null);
}
}, [open, workOrderId, processType]);
@@ -108,18 +141,38 @@ export function WorkLogModal({ open, onOpenChange, workOrderId, processType }: W
// 로딩/에러 상태는 DocumentViewer 내부에서 처리
const subtitle = order ? `${order.processName} 생산부서` : undefined;
// 공정 타입에 따라 콘텐츠 분기
// 양식 미매핑 안내
const renderNoTemplate = () => (
<div className="flex flex-col items-center justify-center h-64 gap-4 bg-white">
<p className="text-muted-foreground">
.
</p>
<p className="text-sm text-muted-foreground">
.
</p>
</div>
);
// 공정관리 양식 매핑 기반 콘텐츠 분기
const renderContent = () => {
if (!order) return null;
// processType prop 또는 order의 processType 사용
const type = processType || order.processType;
// 1순위: 공정관리에서 매핑된 양식명으로 결정
const templateType = resolveProcessTypeFromTemplate(workLogTemplateName);
// 2순위: processType 폴백 (양식 미매핑 시)
const type = templateType || processType || order.processType;
// 양식이 매핑되어 있지 않은 경우 안내
if (!workLogTemplateId && !processType) {
return renderNoTemplate();
}
switch (type) {
case 'screen':
return <ScreenWorkLogContent data={order} />;
return <ScreenWorkLogContent data={order} materialLots={materialLots} />;
case 'slat':
return <SlatWorkLogContent data={order} />;
return <SlatWorkLogContent data={order} materialLots={materialLots} />;
case 'bending':
return <BendingWorkLogContent data={order} />;
default:
@@ -127,9 +180,12 @@ export function WorkLogModal({ open, onOpenChange, workOrderId, processType }: W
}
};
// 양식명으로 문서 제목 결정
const documentTitle = workLogTemplateName || '작업일지';
return (
<DocumentViewer
title="작업일지"
title={documentTitle}
subtitle={subtitle}
preset="inspection"
open={open}