Kaynağa Gözat

fix(production-process): allow clearable qty and fix step-page back UX

Empty output qty fields no longer stick at 0; empty submits as 0. Hide leave-JO back on step page so users return to the process steps list instead.

Co-authored-by: Cursor <[email protected]>
stockTakeUpdate^2
CANCERYS\kw093 6 gün önce
ebeveyn
işleme
a71dd3dfbb
11 değiştirilmiş dosya ile 173 ekleme ve 90 silme
  1. +1
    -1
      src/app/api/jo/actions.ts
  2. +36
    -19
      src/components/ProductionProcess/ProductionOutputForm.tsx
  3. +35
    -24
      src/components/ProductionProcess/ProductionOutputFormPage.tsx
  4. +10
    -1
      src/components/ProductionProcess/ProductionProcessDetail.tsx
  5. +14
    -7
      src/components/ProductionProcess/ProductionProcessJobOrderDetail.tsx
  6. +1
    -1
      src/components/ProductionProcess/ProductionProcessList.tsx
  7. +68
    -37
      src/components/ProductionProcess/ProductionProcessStepExecution.tsx
  8. +2
    -0
      src/i18n/en/jo.json
  9. +2
    -0
      src/i18n/en/productionProcess.json
  10. +2
    -0
      src/i18n/zh/jo.json
  11. +2
    -0
      src/i18n/zh/productionProcess.json

+ 1
- 1
src/app/api/jo/actions.ts Dosyayı Görüntüle

@@ -906,7 +906,7 @@ export const fetchAllJoborderProductProcessInfo = cache(async (type?: string | n
);
});

/** FP-MTMS Version Checklist | Functions Ref. No. 40 | v1.0.7 | 2026-08-06 */
/** FP-MTMS Version Checklist | Functions Ref. No. 40 | v1.0.11 | 2026-10-29 */
export const fetchJoborderProductProcessesPage = cache(async (params: {
/** Job order / process date(YYYY-MM-DD) */
date?: string | null;


+ 36
- 19
src/components/ProductionProcess/ProductionOutputForm.tsx Dosyayı Görüntüle

@@ -17,25 +17,42 @@ import CheckCircleIcon from "@mui/icons-material/CheckCircle";
import { useTranslation } from "react-i18next";
import { UpdateProductProcessLineQtyRequest } from "@/app/api/jo/actions";

type QtyInput = number | "";

export type ProductionOutputFormData = Omit<
UpdateProductProcessLineQtyRequest,
| "outputFromProcessQty"
| "byproductQty"
| "defectQty"
| "defect2Qty"
| "defect3Qty"
| "scrapQty"
> & {
outputFromProcessQty: QtyInput;
byproductQty: QtyInput;
defectQty: QtyInput;
defect2Qty: QtyInput;
defect3Qty: QtyInput;
scrapQty: QtyInput;
};

const parseQtyInput = (raw: string): QtyInput => {
if (raw === "") return "";
const n = parseInt(raw, 10);
return Number.isNaN(n) ? "" : n;
};

export const toSubmitQty = (v: QtyInput | null | undefined): number =>
v === "" || v == null || Number.isNaN(Number(v)) ? 0 : Number(v);

interface ProductionOutputFormProps {
outputData: (UpdateProductProcessLineQtyRequest & {
byproductName: string;
byproductQty: number;
byproductUom: string;
});
setOutputData: React.Dispatch<
React.SetStateAction<
UpdateProductProcessLineQtyRequest & {
byproductName: string;
byproductQty: number;
byproductUom: string;
}
>
>;
outputData: ProductionOutputFormData;
setOutputData: React.Dispatch<React.SetStateAction<ProductionOutputFormData>>;
onSubmit: () => Promise<void> | void;
onCancel: () => void;
}

/** FP-MTMS Version Checklist | Functions Ref. No. 59 | v1.0.1 | 2026-10-29 */
const ProductionOutputForm: React.FC<ProductionOutputFormProps> = ({
outputData,
setOutputData,
@@ -68,7 +85,7 @@ const ProductionOutputForm: React.FC<ProductionOutputFormProps> = ({
onChange={(e) =>
setOutputData({
...outputData,
outputFromProcessQty: parseInt(e.target.value) || 0,
outputFromProcessQty: parseQtyInput(e.target.value),
})
}
/>
@@ -103,7 +120,7 @@ const ProductionOutputForm: React.FC<ProductionOutputFormProps> = ({
onChange={(e) =>
setOutputData({
...outputData,
byproductQty: parseInt(e.target.value) || 0,
byproductQty: parseQtyInput(e.target.value),
})
}
/>
@@ -138,7 +155,7 @@ const ProductionOutputForm: React.FC<ProductionOutputFormProps> = ({
onChange={(e) =>
setOutputData({
...outputData,
defectQty: parseInt(e.target.value) || 0,
defectQty: parseQtyInput(e.target.value),
})
}
/>
@@ -173,7 +190,7 @@ const ProductionOutputForm: React.FC<ProductionOutputFormProps> = ({
onChange={(e) =>
setOutputData({
...outputData,
scrapQty: parseInt(e.target.value) || 0,
scrapQty: parseQtyInput(e.target.value),
})
}
/>
@@ -207,4 +224,4 @@ const ProductionOutputForm: React.FC<ProductionOutputFormProps> = ({
);
};

export default ProductionOutputForm;
export default ProductionOutputForm;

+ 35
- 24
src/components/ProductionProcess/ProductionOutputFormPage.tsx Dosyayı Görüntüle

@@ -5,47 +5,47 @@ import {
Button,
Typography,
} from "@mui/material";
import ArrowBackIcon from "@mui/icons-material/ArrowBack";
import { useTranslation } from "react-i18next";
import {
fetchProductProcessLineDetail,
updateProductProcessLineQty,
UpdateProductProcessLineQtyRequest,
JobOrderProcessLineDetailResponse,
} from "@/app/api/jo/actions";
import ProductionOutputForm from "./ProductionOutputForm";
import ProductionOutputForm, {
ProductionOutputFormData,
toSubmitQty,
} from "./ProductionOutputForm";

interface ProductionOutputFormPageProps {
lineId: number | null;
onBack: () => void;
}

/** FP-MTMS Version Checklist | Functions Ref. No. 59 | v1.0.1 | 2026-10-29 */
const ProductionOutputFormPage: React.FC<ProductionOutputFormPageProps> = ({
lineId,
onBack,
}) => {
const { t } = useTranslation();
const { t } = useTranslation(["common", "jo", "productionProcess"]);
const [lineDetail, setLineDetail] = useState<JobOrderProcessLineDetailResponse | null>(null);
const [outputData, setOutputData] = useState<UpdateProductProcessLineQtyRequest & {
byproductName: string;
byproductQty: number;
byproductUom: string;
}>({
const [outputData, setOutputData] = useState<ProductionOutputFormData>({
productProcessLineId: lineId ?? 0,
outputFromProcessQty: 0,
outputFromProcessQty: "",
outputFromProcessUom: "",
defectQty: 0,
defectQty: "",
defectUom: "",
defect2Qty: 0,
defect2Qty: "",
defect2Uom: "",
defect3Qty: 0,
defect3Qty: "",
defect3Uom: "",
defectDescription: "",
defectDescription2: "",
defectDescription3: "",
scrapQty: 0,
scrapQty: "",
scrapUom: "",
byproductName: "",
byproductQty: 0,
byproductQty: "",
byproductUom: "",
});

@@ -60,14 +60,14 @@ const ProductionOutputFormPage: React.FC<ProductionOutputFormPageProps> = ({
setOutputData((prev) => ({
...prev,
productProcessLineId: detail.id,
outputFromProcessQty: (detail as any).outputFromProcessQty || 0,
outputFromProcessQty: (detail as any).outputFromProcessQty || "",
outputFromProcessUom: (detail as any).outputFromProcessUom || "",
defectQty: detail.defectQty || 0,
defectQty: detail.defectQty || "",
defectUom: detail.defectUom || "",
scrapQty: detail.scrapQty || 0,
scrapQty: detail.scrapQty || "",
scrapUom: detail.scrapUom || "",
byproductName: detail.byproductName || "",
byproductQty: detail.byproductQty || 0,
byproductQty: detail.byproductQty || "",
byproductUom: detail.byproductUom || "",
}));
})
@@ -84,6 +84,12 @@ const ProductionOutputFormPage: React.FC<ProductionOutputFormPageProps> = ({
await updateProductProcessLineQty({
...outputData,
productProcessLineId: lineDetail.id || 0,
outputFromProcessQty: toSubmitQty(outputData.outputFromProcessQty),
byproductQty: toSubmitQty(outputData.byproductQty),
defectQty: toSubmitQty(outputData.defectQty),
defect2Qty: toSubmitQty(outputData.defect2Qty),
defect3Qty: toSubmitQty(outputData.defect3Qty),
scrapQty: toSubmitQty(outputData.scrapQty),
});

console.log("Output data submitted successfully");
@@ -94,14 +100,14 @@ const ProductionOutputFormPage: React.FC<ProductionOutputFormPageProps> = ({
setOutputData((prev) => ({
...prev,
productProcessLineId: detail.id,
outputFromProcessQty: (detail as any).outputFromProcessQty || 0,
outputFromProcessQty: (detail as any).outputFromProcessQty || "",
outputFromProcessUom: (detail as any).outputFromProcessUom || "",
defectQty: detail.defectQty || 0,
defectQty: detail.defectQty || "",
defectUom: detail.defectUom || "",
scrapQty: detail.scrapQty || 0,
scrapQty: detail.scrapQty || "",
scrapUom: detail.scrapUom || "",
byproductName: detail.byproductName || "",
byproductQty: detail.byproductQty || 0,
byproductQty: detail.byproductQty || "",
byproductUom: detail.byproductUom || "",
}));

@@ -116,8 +122,13 @@ const ProductionOutputFormPage: React.FC<ProductionOutputFormPageProps> = ({
return (
<Box>
<Box sx={{ mb: 2 }}>
<Button variant="outlined" onClick={onBack}>
{t("Back to List")}
<Button
variant="outlined"
size="small"
onClick={onBack}
startIcon={<ArrowBackIcon />}
>
{t("Back to Process Steps")}
</Button>
</Box>



+ 10
- 1
src/components/ProductionProcess/ProductionProcessDetail.tsx Dosyayı Görüntüle

@@ -64,13 +64,16 @@ interface ProductProcessDetailProps {
jobOrderId: number;
onBack: () => void;
fromJosave?: boolean;
/** 進入步驟執行頁時通知父層(用來隱藏「返回列表」) */
onStepViewChange?: (inStepView: boolean) => void;
}

/** FP-MTMS Version Checklist | Functions Ref. No. 50 | v1.0.1 | 2026-08-10 */
/** FP-MTMS Version Checklist | Functions Ref. No. 50 | v1.0.2 | 2026-10-29 */
const ProductionProcessDetail: React.FC<ProductProcessDetailProps> = ({
jobOrderId,
onBack,
fromJosave,
onStepViewChange,
}) => {
// console.log(" ProductionProcessDetail RENDER", { jobOrderId, fromJosave });
@@ -143,6 +146,12 @@ const fetchProcessDetailRef = useRef<() => Promise<void>>();
useEffect(() => {
onBackRef.current = onBack;
}, [onBack]);

useEffect(() => {
const inStepView = isExecutingLine && selectedLineId != null;
onStepViewChange?.(inStepView);
return () => onStepViewChange?.(false);
}, [isExecutingLine, selectedLineId, onStepViewChange]);
// 获取 process 和 lines 数据
const fetchProcessDetail = useCallback(async () => {
// console.log(" fetchProcessDetail CALLED", { jobOrderId, timestamp: new Date().toISOString() });


+ 14
- 7
src/components/ProductionProcess/ProductionProcessJobOrderDetail.tsx Dosyayı Görüntüle

@@ -54,7 +54,7 @@ interface ProductProcessJobOrderDetailProps {
initialTabIndex?: number;
}

/** FP-MTMS Version Checklist | Functions Ref. No. 40 | v1.0.7 | 2026-08-06 */
/** FP-MTMS Version Checklist | Functions Ref. No. 40 | v1.0.11 | 2026-10-29 */
const ProductionProcessJobOrderDetail: React.FC<ProductProcessJobOrderDetailProps> = ({
jobOrderId,
onBack,
@@ -68,6 +68,7 @@ const ProductionProcessJobOrderDetail: React.FC<ProductProcessJobOrderDetailProp
const [inventoryData, setInventoryData] = useState<InventoryResult[]>([]);
const [tabIndex, setTabIndex] = useState(initialTabIndex);
const [selectedProcessId, setSelectedProcessId] = useState<number | null>(null);
const [inStepView, setInStepView] = useState(false);
const [operationPriority, setOperationPriority] = useState<number>(50);
const [openOperationPriorityDialog, setOpenOperationPriorityDialog] = useState(false);
const [openPlanStartDialog, setOpenPlanStartDialog] = useState(false);
@@ -320,6 +321,9 @@ const handleRelease = useCallback(async (jobOrderId: number) => {
const handleTabChange = useCallback<NonNullable<TabsProps["onChange"]>>(
(_e, newValue) => {
setTabIndex(newValue);
if (newValue !== 2) {
setInStepView(false);
}
},
[],
);
@@ -796,12 +800,14 @@ const handleRelease = useCallback(async (jobOrderId: number) => {

return (
<Box>
{/* 返回按钮 */}
<Box sx={{ mb: 2 }}>
<Button variant="outlined" onClick={onBack} startIcon={<ArrowBackIcon />}>
{t("Back to List")}
</Button>
</Box>
{/* 步驟執行頁不顯示「返回列表」,避免誤離開工單 */}
{!inStepView && (
<Box sx={{ mb: 2 }}>
<Button variant="outlined" onClick={onBack} startIcon={<ArrowBackIcon />}>
{t("Back to List")}
</Button>
</Box>
)}
{/* 标签页 */}
<Box sx={{ borderBottom: '1px solid #e0e0e0' }}>
@@ -833,6 +839,7 @@ const handleRelease = useCallback(async (jobOrderId: number) => {

}}
fromJosave={Boolean(fromJosave && !isPutAwayed)}
onStepViewChange={setInStepView}
/>
)}
{tabIndex === 3 && <ProductionProcessesLineRemarkTableContent />}


+ 1
- 1
src/components/ProductionProcess/ProductionProcessList.tsx Dosyayı Görüntüle

@@ -179,7 +179,7 @@ function isWaitingQcPutAway(
return s !== "completed" && s !== "rejected";
}

/** FP-MTMS Version Checklist | Functions Ref. No. 40 | v1.0.10 | 2026-10-15 */
/** FP-MTMS Version Checklist | Functions Ref. No. 40 | v1.0.11 | 2026-10-29 */
const ProductProcessList: React.FC<ProductProcessListProps> = ({
onSelectProcess,
printerCombo,


+ 68
- 37
src/components/ProductionProcess/ProductionProcessStepExecution.tsx Dosyayı Görüntüle

@@ -28,6 +28,7 @@ import CheckCircleIcon from "@mui/icons-material/CheckCircle";
import StopIcon from "@mui/icons-material/Stop";
import PauseIcon from "@mui/icons-material/Pause";
import PlayArrowIcon from "@mui/icons-material/PlayArrow";
import ArrowBackIcon from "@mui/icons-material/ArrowBack";
import { useTranslation } from "react-i18next";
import {
JobOrderProcessLineDetailResponse,
@@ -47,6 +48,35 @@ import { fetchNameList, NameList } from "@/app/api/user/actions";
import BagConsumptionForm from "./BagConsumptionForm"; // ✅ 添加导入
import OverallTimeRemainingCard from "./OverallTimeRemainingCard"; // ✅ 添加导入
import dayjs from "dayjs";

type QtyInput = number | "";

type OutputFormState = Omit<
UpdateProductProcessLineQtyRequest,
| "outputFromProcessQty"
| "byproductQty"
| "defectQty"
| "defect2Qty"
| "defect3Qty"
| "scrapQty"
> & {
outputFromProcessQty: QtyInput;
byproductQty: QtyInput;
defectQty: QtyInput;
defect2Qty: QtyInput;
defect3Qty: QtyInput;
scrapQty: QtyInput;
};

const parseQtyInput = (raw: string): QtyInput => {
if (raw === "") return "";
const n = parseInt(raw, 10);
return Number.isNaN(n) ? "" : n;
};

const toSubmitQty = (v: QtyInput | null | undefined): number =>
v === "" || v == null || Number.isNaN(Number(v)) ? 0 : Number(v);

interface ProductionProcessStepExecutionProps {
lineId: number | null;
onBack: () => void;
@@ -55,7 +85,7 @@ interface ProductionProcessStepExecutionProps {
jobOrderId?: number; // ✅ 添加
}

/** FP-MTMS Version Checklist | Functions Ref. No. 59 | v1.0.0 | 2026-08-10 */
/** FP-MTMS Version Checklist | Functions Ref. No. 59 | v1.0.1 | 2026-10-29 */
const ProductionProcessStepExecution: React.FC<ProductionProcessStepExecutionProps> = ({
lineId,
onBack,
@@ -75,24 +105,20 @@ const ProductionProcessStepExecution: React.FC<ProductionProcessStepExecutionPro
lineStatusNorm === "autopass";
const isPassStatus = lineStatusNorm === "pass";
const isAutoPassStatus = lineStatusNorm === "autopass";
const [outputData, setOutputData] = useState<UpdateProductProcessLineQtyRequest & {
byproductName: string;
byproductQty: number;
byproductUom: string;
}>({
const [outputData, setOutputData] = useState<OutputFormState>({
productProcessLineId: lineId ?? 0,
outputFromProcessQty: 0,
outputFromProcessQty: "",
outputFromProcessUom: "",
defectQty: 0,
defectQty: "",
defectUom: "",
scrapQty: 0,
scrapQty: "",
scrapUom: "",
byproductName: "",
byproductQty: 0,
byproductQty: "",
byproductUom: "",
defect2Qty: 0,
defect2Qty: "",
defect2Uom: "",
defect3Qty: 0,
defect3Qty: "",
defect3Uom: "",
defectDescription: "",
defectDescription2: "",
@@ -153,14 +179,14 @@ const ProductionProcessStepExecution: React.FC<ProductionProcessStepExecutionPro
setOutputData(prev => ({
...prev,
productProcessLineId: detail.id,
outputFromProcessQty: (detail as any).outputFromProcessQty || 0,
outputFromProcessQty: (detail as any).outputFromProcessQty || "",
outputFromProcessUom: (detail as any).outputFromProcessUom || "",
defectQty: detail.defectQty || 0,
defectQty: detail.defectQty || "",
defectUom: detail.defectUom || "",
scrapQty: detail.scrapQty || 0,
scrapQty: detail.scrapQty || "",
scrapUom: detail.scrapUom || "",
byproductName: detail.byproductName || "",
byproductQty: detail.byproductQty || 0,
byproductQty: detail.byproductQty || "",
byproductUom: detail.byproductUom || ""
}));
})
@@ -351,20 +377,20 @@ const ProductionProcessStepExecution: React.FC<ProductionProcessStepExecutionPro
await updateProductProcessLineQty({
productProcessLineId: lineDetail?.id || 0 as number,
byproductName: outputData.byproductName,
byproductQty: outputData.byproductQty,
byproductQty: toSubmitQty(outputData.byproductQty),
byproductUom: outputData.byproductUom,
outputFromProcessQty: outputData.outputFromProcessQty,
outputFromProcessQty: toSubmitQty(outputData.outputFromProcessQty),
outputFromProcessUom: outputData.outputFromProcessUom,
defectQty: outputData.defectQty,
defectQty: toSubmitQty(outputData.defectQty),
defectUom: outputData.defectUom,
defect2Qty: outputData.defect2Qty,
defect2Qty: toSubmitQty(outputData.defect2Qty),
defect2Uom: outputData.defect2Uom,
defect3Qty: outputData.defect3Qty,
defect3Qty: toSubmitQty(outputData.defect3Qty),
defect3Uom: outputData.defect3Uom,
defectDescription: outputData.defectDescription,
defectDescription2: outputData.defectDescription2,
defectDescription3: outputData.defectDescription3,
scrapQty: outputData.scrapQty,
scrapQty: toSubmitQty(outputData.scrapQty),
scrapUom: outputData.scrapUom,
});

@@ -383,21 +409,21 @@ const ProductionProcessStepExecution: React.FC<ProductionProcessStepExecutionPro
setOutputData(prev => ({
...prev,
productProcessLineId: detail.id,
outputFromProcessQty: (detail as any).outputFromProcessQty || 0,
outputFromProcessQty: (detail as any).outputFromProcessQty || "",
outputFromProcessUom: (detail as any).outputFromProcessUom || "",
defectQty: detail.defectQty || 0,
defectQty: detail.defectQty || "",
defectUom: detail.defectUom || "",
defectDescription: detail.defectDescription || "",
defectDescription2: detail.defectDescription2 || "",
defectDescription3: detail.defectDescription3 || "",
defectQty2: detail.defectQty2 || 0,
defectUom2: detail.defectUom2 || "",
defectQty3: detail.defectQty3 || 0,
defectUom3: detail.defectUom3 || "",
scrapQty: detail.scrapQty || 0,
defect2Qty: (detail as any).defect2Qty || "",
defect2Uom: (detail as any).defect2Uom || "",
defect3Qty: (detail as any).defect3Qty || "",
defect3Uom: (detail as any).defect3Uom || "",
scrapQty: detail.scrapQty || "",
scrapUom: detail.scrapUom || "",
byproductName: detail.byproductName || "",
byproductQty: detail.byproductQty || 0,
byproductQty: detail.byproductQty || "",
byproductUom: detail.byproductUom || ""
}));
})
@@ -561,8 +587,13 @@ const ProductionProcessStepExecution: React.FC<ProductionProcessStepExecutionPro
return (
<Box>
<Box sx={{ mb: 2 }}>
<Button variant="outlined" onClick={onBack}>
{t("Back to List")}
<Button
variant="outlined"
size="small"
onClick={onBack}
startIcon={<ArrowBackIcon />}
>
{t("Back to Process Steps")}
</Button>
</Box>
{processData && (
@@ -812,7 +843,7 @@ const ProductionProcessStepExecution: React.FC<ProductionProcessStepExecutionPro
value={outputData.outputFromProcessQty}
onChange={(e) => setOutputData({
...outputData,
outputFromProcessQty: parseInt(e.target.value) || 0
outputFromProcessQty: parseQtyInput(e.target.value)
})}
/>
</TableCell>
@@ -854,7 +885,7 @@ const ProductionProcessStepExecution: React.FC<ProductionProcessStepExecutionPro
value={outputData.defectQty}
onChange={(e) => setOutputData({
...outputData,
defectQty: parseInt(e.target.value) || 0
defectQty: parseQtyInput(e.target.value)
})}
/>
</TableCell>
@@ -902,7 +933,7 @@ const ProductionProcessStepExecution: React.FC<ProductionProcessStepExecutionPro
value={outputData.defect2Qty}
onChange={(e) => setOutputData({
...outputData,
defect2Qty: parseInt(e.target.value) || 0
defect2Qty: parseQtyInput(e.target.value)
})}
/>
</TableCell>
@@ -950,7 +981,7 @@ const ProductionProcessStepExecution: React.FC<ProductionProcessStepExecutionPro
value={outputData.defect3Qty}
onChange={(e) => setOutputData({
...outputData,
defect3Qty: parseInt(e.target.value) || 0
defect3Qty: parseQtyInput(e.target.value)
})}
/>
</TableCell>
@@ -998,7 +1029,7 @@ const ProductionProcessStepExecution: React.FC<ProductionProcessStepExecutionPro
value={outputData.scrapQty}
onChange={(e) => setOutputData({
...outputData,
scrapQty: parseInt(e.target.value) || 0
scrapQty: parseQtyInput(e.target.value)
})}
/>
</TableCell>


+ 2
- 0
src/i18n/en/jo.json Dosyayı Görüntüle

@@ -32,6 +32,8 @@
"BOM Type": "BOM Type",
"Back": "Back",
"Back to List": "Back to List",
"Back to Process": "Back to Process Steps",
"Back to Process Steps": "Back to Process Steps",
"Bad Item Qty": "Bad Item Qty",
"Bad Package Qty": "Bad Package Qty",
"Bag": "Bag",


+ 2
- 0
src/i18n/en/productionProcess.json Dosyayı Görüntüle

@@ -10,6 +10,8 @@
"Auto-refresh every 10 minutes": "Auto-refresh every 10 minutes",
"Back": "Back",
"Back to List": "Back to List",
"Back to Process": "Back to Process Steps",
"Back to Process Steps": "Back to Process Steps",
"Bag": "Bag",
"Bag Consumption": "Bag Consumption",
"Balance": "Balance",


+ 2
- 0
src/i18n/zh/jo.json Dosyayı Görüntüle

@@ -34,6 +34,8 @@
"BOM Type": "BOM 類型",
"Back": "返回",
"Back to List": "返回列表",
"Back to Process": "返回列表",
"Back to Process Steps": "返回列表",
"Bad Item Qty": "不良物品數量",
"Bad Package Qty": "不良包裝數量",
"Bag": "包裝袋",


+ 2
- 0
src/i18n/zh/productionProcess.json Dosyayı Görüntüle

@@ -10,6 +10,8 @@
"Auto-refresh every 10 minutes": "每10分鐘自動刷新",
"Back": "返回",
"Back to List": "返回列表",
"Back to Process": "返回列表",
"Back to Process Steps": "返回列表",
"Bag": "包裝袋",
"Bag Consumption": "包裝袋消耗",
"Balance": "可用數量",


Yükleniyor…
İptal
Kaydet