"use client"; import React, { useState, useEffect, useCallback, useMemo } from "react"; import { Box, Paper, Typography, Table, TableBody, TableCell, TableHead, TableRow, TextField, Select, MenuItem, Button, IconButton, CircularProgress, } from "@mui/material"; import AddIcon from "@mui/icons-material/Add"; import DeleteIcon from "@mui/icons-material/Delete"; import { useTranslation } from "react-i18next"; import { getBagInfo, createJoBagConsumption, GetBagInfoResponse, CreateJoBagConsumptionRequest, } from "@/app/api/bag/action"; import { fetchProductProcessLineDetail } from "@/app/api/jo/actions"; export interface BagConsumptionRow { bagId: number; bagLotLineId: number; consumedQty: number; scrapQty: number; } interface BagConsumptionFormProps { jobOrderId: number; lineId: number; bomDescription?: string; isLastLine: boolean; onRefresh?: () => void; } const BagConsumptionForm: React.FC = ({ jobOrderId, lineId, bomDescription, isLastLine, onRefresh, }) => { const { t } = useTranslation(["common", "jo"]); const [bagList, setBagList] = useState([]); const [bagConsumptionRows, setBagConsumptionRows] = useState([ { bagId: 0, bagLotLineId: 0, consumedQty: 0, scrapQty: 0 }, ]); const [isLoadingBags, setIsLoadingBags] = useState(false); const [isSubmitting, setIsSubmitting] = useState(false); // 判断是否显示表单 const shouldShow = useMemo(() => { return bomDescription === "FG" && isLastLine; }, [bomDescription, isLastLine]); // 加载 Bag 列表 useEffect(() => { if (shouldShow) { setIsLoadingBags(true); getBagInfo() .then((bags) => { setBagList(bags); console.log("✅ Bag list loaded:", bags); }) .catch((error) => { console.error("❌ Error loading bag list:", error); }) .finally(() => { setIsLoadingBags(false); }); } }, [shouldShow]); // 添加 Bag 行 const handleAddBagRow = useCallback(() => { setBagConsumptionRows((prev) => [ ...prev, { bagId: 0, bagLotLineId: 0, consumedQty: 0, scrapQty: 0 }, ]); }, []); // 删除 Bag 行 const handleDeleteBagRow = useCallback((index: number) => { setBagConsumptionRows((prev) => prev.filter((_, i) => i !== index)); }, []); // 更新 Bag 行数据 const handleBagRowChange = useCallback( (index: number, field: keyof BagConsumptionRow, value: any) => { setBagConsumptionRows((prev) => prev.map((row, i) => (i === index ? { ...row, [field]: value } : row)) ); }, [] ); // 当选择 bag 时,自动填充 bagLotLineId const handleBagSelect = useCallback( (index: number, bagLotLineId: number) => { const selectedBag = bagList.find((b) => b.id === bagLotLineId); if (selectedBag) { handleBagRowChange(index, "bagId", selectedBag.bagId); handleBagRowChange(index, "bagLotLineId", selectedBag.id); } }, [bagList, handleBagRowChange] ); // 提交 Bag Consumption const handleSubmitBagConsumption = useCallback(async () => { if (!jobOrderId || !lineId) { alert(t("Missing job order ID or line ID")); return; } try { setIsSubmitting(true); // 过滤掉未选择 bag 的行 const validRows = bagConsumptionRows.filter( (row) => row.bagId > 0 && row.bagLotLineId > 0 ); if (validRows.length === 0) { alert(t("Please select at least one bag")); return; } // 提交每个 bag consumption const promises = validRows.map((row) => { const selectedBag = bagList.find((b) => b.id === row.bagLotLineId); const request: CreateJoBagConsumptionRequest = { bagId: row.bagId, bagLotLineId: row.bagLotLineId, jobId: jobOrderId, //startQty: selectedBag?.balanceQty || 0, consumedQty: row.consumedQty, scrapQty: row.scrapQty, }; return createJoBagConsumption(request); }); await Promise.all(promises); console.log("✅ Bag consumption submitted successfully"); // 清空表单 setBagConsumptionRows([ { bagId: 0, bagLotLineId: 0, consumedQty: 0, scrapQty: 0 }, ]); // 刷新 line detail if (onRefresh) { onRefresh(); } else { const detail = await fetchProductProcessLineDetail(lineId); console.log("✅ Line detail refreshed:", detail); } } catch (error: any) { console.error("❌ Error submitting bag consumption:", error); // ✅ 显示更详细的错误信息 const errorMessage = error?.message || error?.response?.data?.message || t("Failed to submit bag consumption. Please try again."); alert(errorMessage); } finally { setIsSubmitting(false); } }, [bagConsumptionRows, bagList, jobOrderId, lineId, onRefresh, t]); // 如果不满足显示条件,不渲染 if (!shouldShow) { return null; } return ( {t("Bag Consumption")} {isLoadingBags ? ( ) : ( <> {t("Bag")} {t("Consumed Qty")} {t("Scrap Qty")} {t("Action")} {bagConsumptionRows.map((row, index) => ( handleBagRowChange( index, "consumedQty", Number(e.target.value) || 0 ) } inputProps={{ min: 0 }} /> handleBagRowChange( index, "scrapQty", Number(e.target.value) || 0 ) } inputProps={{ min: 0 }} /> {bagConsumptionRows.length > 1 && ( handleDeleteBagRow(index)} > )} ))}
)}
); }; export default BagConsumptionForm;