feat(WEB):작업일지 공정관리 양식 연동 및 자재 LOT 동적화
- WorkLogModal: workLogTemplateId/Name prop 추가, 공정관리 매핑 기반 콘텐츠 분기 - WorkerScreen: activeProcessSettings에 workLogTemplateId/Name 추가 - ScreenWorkLogContent: 내화실 LOT 하드코딩 → materialLots item_name별 동적 그룹핑 - SlatWorkLogContent/BendingWorkLogContent: 소규모 수정
This commit is contained in:
@@ -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}
|
||||
|
||||
Reference in New Issue
Block a user