= async ({ searchParams }) => {
+ const { t } = await getServerI18n("qcItem");
+
+ const id = searchParams["id"];
+
+ if (!id || isArray(id)) {
+ notFound();
+ }
+
+ try {
+ console.log("first");
+ await fetchQcItemDetails(id);
+ console.log("firsts");
+ } catch (e) {
+ if (
+ e instanceof ServerFetchError &&
+ (e.response?.status === 404 || e.response?.status === 400)
+ ) {
+ console.log(e);
+ notFound();
+ }
+ }
+
+ return (
+ <>
+
+ {t("Edit Qc Item")}
+
+
+
+
+ >
+ );
+};
+
+export default qcItem;
diff --git a/src/app/(main)/settings/qcItem copy/page.tsx b/src/app/(main)/settings/qcItem copy/page.tsx
new file mode 100644
index 0000000..f1b4e71
--- /dev/null
+++ b/src/app/(main)/settings/qcItem copy/page.tsx
@@ -0,0 +1,48 @@
+import { Metadata } from "next";
+import { getServerI18n, I18nProvider } from "@/i18n";
+import Typography from "@mui/material/Typography";
+import { Button, Link, Stack } from "@mui/material";
+import { Add } from "@mui/icons-material";
+import { Suspense } from "react";
+import { preloadQcItem } from "@/app/api/settings/qcItem";
+import QcItemSearch from "@/components/QcItemSearch";
+
+export const metadata: Metadata = {
+ title: "Qc Item",
+};
+
+const qcItem: React.FC = async () => {
+ const { t } = await getServerI18n("qcItem");
+
+ preloadQcItem();
+
+ return (
+ <>
+
+
+ {t("Qc Item")}
+
+ }
+ LinkComponent={Link}
+ href="qcItem/create"
+ >
+ {t("Create Qc Item")}
+
+
+ }>
+
+
+
+
+ >
+ );
+};
+
+export default qcItem;
diff --git a/src/app/(main)/settings/qcItemAll/page.tsx b/src/app/(main)/settings/qcItemAll/page.tsx
new file mode 100644
index 0000000..ff0d328
--- /dev/null
+++ b/src/app/(main)/settings/qcItemAll/page.tsx
@@ -0,0 +1,47 @@
+import { Metadata } from "next";
+import { getServerI18n, I18nProvider } from "@/i18n";
+import Typography from "@mui/material/Typography";
+import { Stack } from "@mui/material";
+import { Suspense } from "react";
+import QcItemAllTabs from "@/components/QcItemAll/QcItemAllTabs";
+import Tab0ItemQcCategoryMapping from "@/components/QcItemAll/Tab0ItemQcCategoryMapping";
+import Tab1QcCategoryQcItemMapping from "@/components/QcItemAll/Tab1QcCategoryQcItemMapping";
+import Tab2QcCategoryManagement from "@/components/QcItemAll/Tab2QcCategoryManagement";
+import Tab3QcItemManagement from "@/components/QcItemAll/Tab3QcItemManagement";
+
+export const metadata: Metadata = {
+ title: "Qc Item All",
+};
+
+const qcItemAll: React.FC = async () => {
+ const { t } = await getServerI18n("qcItemAll");
+
+ return (
+ <>
+
+
+ {t("Qc Item All")}
+
+
+ Loading...}>
+
+ }
+ tab1Content={}
+ tab2Content={}
+ tab3Content={}
+ />
+
+
+ >
+ );
+};
+
+export default qcItemAll;
+
diff --git a/src/app/(main)/testing/page.tsx b/src/app/(main)/testing/page.tsx
index 4c64f92..3efaf70 100644
--- a/src/app/(main)/testing/page.tsx
+++ b/src/app/(main)/testing/page.tsx
@@ -4,13 +4,47 @@ import React, { useState } from "react";
import {
Box, Grid, Paper, Typography, Button, Dialog, DialogTitle,
DialogContent, DialogActions, TextField, Stack, Table,
- TableBody, TableCell, TableContainer, TableHead, TableRow
+ TableBody, TableCell, TableContainer, TableHead, TableRow,
+ Tabs, Tab // ← Added for tabs
} from "@mui/material";
import { FileDownload, Print, SettingsEthernet, Lan, Router } from "@mui/icons-material";
import dayjs from "dayjs";
import { NEXT_PUBLIC_API_URL } from "@/config/api";
+// Simple TabPanel component for conditional rendering
+interface TabPanelProps {
+ children?: React.ReactNode;
+ index: number;
+ value: number;
+}
+
+function TabPanel(props: TabPanelProps) {
+ const { children, value, index, ...other } = props;
+ return (
+
+ {value === index && (
+
+ {children}
+
+ )}
+
+ );
+}
+
export default function TestingPage() {
+ // Tab state
+ const [tabValue, setTabValue] = useState(0);
+
+ const handleTabChange = (event: React.SyntheticEvent, newValue: number) => {
+ setTabValue(newValue);
+ };
+
// --- 1. TSC Section States ---
const [tscConfig, setTscConfig] = useState({ ip: '192.168.1.100', port: '9100' });
const [tscItems, setTscItems] = useState([
@@ -35,10 +69,22 @@ export default function TestingPage() {
});
// --- 4. Laser Section States ---
-const [laserConfig, setLaserConfig] = useState({ ip: '192.168.1.102', port: '8080' });
-const [laserItems, setLaserItems] = useState([
- { id: 1, templateId: 'JOB_001', lotNo: 'L-LASER-01', expiryDate: '2025-12-31', power: '50' },
-]);
+ const [laserConfig, setLaserConfig] = useState({ ip: '192.168.1.102', port: '8080' });
+ const [laserItems, setLaserItems] = useState([
+ { id: 1, templateId: 'JOB_001', lotNo: 'L-LASER-01', expiryDate: '2025-12-31', power: '50' },
+ ]);
+
+ // --- 5. HANS600S-M Section States ---
+ const [hansConfig, setHansConfig] = useState({ ip: '192.168.76.10', port: '45678' });
+ const [hansItems, setHansItems] = useState([
+ {
+ id: 1,
+ textChannel3: 'SN-HANS-001-20260117', // channel 3 (e.g. serial / text1)
+ textChannel4: 'BATCH-HK-TEST-OK', // channel 4 (e.g. batch / text2)
+ text3ObjectName: 'Text3', // EZCAD object name for channel 3
+ text4ObjectName: 'Text4' // EZCAD object name for channel 4
+ },
+ ]);
// Generic handler for inline table edits
const handleItemChange = (setter: any, id: number, field: string, value: string) => {
@@ -105,6 +151,7 @@ const [laserItems, setLaserItems] = useState([
} catch (e) { console.error("OnPack Error:", e); }
};
+ // Laser Print (Section 4 - original)
const handleLaserPrint = async (row: any) => {
const token = localStorage.getItem("accessToken");
const payload = { ...row, printerIp: laserConfig.ip, printerPort: laserConfig.port };
@@ -122,7 +169,6 @@ const [laserItems, setLaserItems] = useState([
const token = localStorage.getItem("accessToken");
const payload = { ...row, printerIp: laserConfig.ip, printerPort: parseInt(laserConfig.port) };
try {
- // We'll create this endpoint in the backend next
const response = await fetch(`${NEXT_PUBLIC_API_URL}/plastic/preview-laser`, {
method: 'POST',
headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' },
@@ -132,24 +178,58 @@ const [laserItems, setLaserItems] = useState([
} catch (e) { console.error("Preview Error:", e); }
};
+ // HANS600S-M TCP Print (Section 5)
+ const handleHansPrint = async (row: any) => {
+ const token = localStorage.getItem("accessToken");
+ const payload = {
+ printerIp: hansConfig.ip,
+ printerPort: hansConfig.port,
+ textChannel3: row.textChannel3,
+ textChannel4: row.textChannel4,
+ text3ObjectName: row.text3ObjectName,
+ text4ObjectName: row.text4ObjectName
+ };
+ try {
+ const response = await fetch(`${NEXT_PUBLIC_API_URL}/plastic/print-laser-tcp`, {
+ method: 'POST',
+ headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' },
+ body: JSON.stringify(payload)
+ });
+ const result = await response.text();
+ if (response.ok) {
+ alert(`HANS600S-M Mark Success: ${result}`);
+ } else {
+ alert(`HANS600S-M Failed: ${result}`);
+ }
+ } catch (e) {
+ console.error("HANS600S-M Error:", e);
+ alert("HANS600S-M Connection Error");
+ }
+ };
+
// Layout Helper
const Section = ({ title, children }: { title: string, children?: React.ReactNode }) => (
-
-
-
- {title}
-
- {children || Waiting for implementation...}
-
-
+
+
+ {title}
+
+ {children || Waiting for implementation...}
+
);
return (
- Printer Testing Dashboard
+ Printer Testing
-
- {/* 1. TSC Section */}
+
+
+
+
+
+
+
+
+
setTscConfig({...tscConfig, ip: e.target.value})} />
@@ -181,8 +261,9 @@ const [laserItems, setLaserItems] = useState([
+
- {/* 2. DataFlex Section */}
+
setDfConfig({...dfConfig, ip: e.target.value})} />
@@ -214,8 +295,9 @@ const [laserItems, setLaserItems] = useState([
+
- {/* 3. OnPack Section */}
+
@@ -226,8 +308,9 @@ const [laserItems, setLaserItems] = useState([
+
- {/* 4. Laser Section (HANS600S-M) */}
+
setLaserConfig({...laserConfig, ip: e.target.value})} />
@@ -283,7 +366,94 @@ const [laserItems, setLaserItems] = useState([
Note: HANS Laser requires pre-saved templates on the controller.
-
+
+
+
+
+
+ setHansConfig({...hansConfig, ip: e.target.value})}
+ />
+ setHansConfig({...hansConfig, port: e.target.value})}
+ />
+
+
+
+
+
+
+
+ Ch3 Text (SN)
+ Ch4 Text (Batch)
+ Obj3 Name
+ Obj4 Name
+ Action
+
+
+
+ {hansItems.map(row => (
+
+
+ handleItemChange(setHansItems, row.id, 'textChannel3', e.target.value)}
+ sx={{ minWidth: 180 }}
+ />
+
+
+ handleItemChange(setHansItems, row.id, 'textChannel4', e.target.value)}
+ sx={{ minWidth: 140 }}
+ />
+
+
+ handleItemChange(setHansItems, row.id, 'text3ObjectName', e.target.value)}
+ size="small"
+ />
+
+
+ handleItemChange(setHansItems, row.id, 'text4ObjectName', e.target.value)}
+ size="small"
+ />
+
+
+ }
+ onClick={() => handleHansPrint(row)}
+ sx={{ minWidth: 80 }}
+ >
+ TCP Mark
+
+
+
+ ))}
+
+
+
+
+ TCP Push to EZCAD3 (Ch3/Ch4 via E3_SetTextObject) | IP:192.168.76.10:45678 | Backend: /print-laser-tcp
+
+
+
{/* Dialog for OnPack */}
-
+ {error && (
+
+ {error}
+
+ )}
+
+ {loading ? (
+
+
+
+ ) : (
@@ -356,6 +341,7 @@ const TruckLane: React.FC = () => {
rowsPerPageOptions={[5, 10, 25, 50]}
/>
+ )}
diff --git a/src/components/StockIssue/SearchPage.tsx b/src/components/StockIssue/SearchPage.tsx
index 608dc31..dad5252 100644
--- a/src/components/StockIssue/SearchPage.tsx
+++ b/src/components/StockIssue/SearchPage.tsx
@@ -150,7 +150,7 @@ const SearchPage: React.FC = ({ dataList }) => {
{ name: "itemDescription", label: t("Item") },
{ name: "lotNo", label: t("Lot No.") },
{ name: "storeLocation", label: t("Location") },
- { name: "missQty", label: t("Miss Qty") },
+ { name: "issueQty", label: t("Miss Qty") },
{
name: "id",
label: t("Action"),
@@ -176,7 +176,7 @@ const SearchPage: React.FC = ({ dataList }) => {
{ name: "itemDescription", label: t("Item") },
{ name: "lotNo", label: t("Lot No.") },
{ name: "storeLocation", label: t("Location") },
- { name: "badItemQty", label: t("Defective Qty") },
+ { name: "issueQty", label: t("Defective Qty") },
{
name: "id",
label: t("Action"),
diff --git a/src/components/StockRecord/SearchPage.tsx b/src/components/StockRecord/SearchPage.tsx
index 8d1c02a..025dd84 100644
--- a/src/components/StockRecord/SearchPage.tsx
+++ b/src/components/StockRecord/SearchPage.tsx
@@ -77,16 +77,10 @@ const SearchPage: React.FC = ({ dataList: initialDataList }) => {
sorted.forEach((item) => {
const currentBalance = balanceMap.get(item.itemId) || 0;
- let newBalance = currentBalance;
+
- // 根据类型计算余额
- if (item.transactionType === "IN") {
- newBalance = currentBalance + item.qty;
- } else if (item.transactionType === "OUT") {
- newBalance = currentBalance - item.qty;
- }
-
- balanceMap.set(item.itemId, newBalance);
+
+
// 格式化日期 - 优先使用 date 字段
let formattedDate = "";
@@ -128,7 +122,7 @@ const SearchPage: React.FC = ({ dataList: initialDataList }) => {
formattedDate,
inQty: item.transactionType === "IN" ? item.qty : 0,
outQty: item.transactionType === "OUT" ? item.qty : 0,
- balanceQty: item.balanceQty ? item.balanceQty : newBalance,
+ balanceQty: item.balanceQty ?? 0,
});
});
diff --git a/src/components/StockTakeManagement/ApproverStockTake.tsx b/src/components/StockTakeManagement/ApproverStockTake.tsx
index 512898a..0a263b5 100644
--- a/src/components/StockTakeManagement/ApproverStockTake.tsx
+++ b/src/components/StockTakeManagement/ApproverStockTake.tsx
@@ -404,6 +404,17 @@ const ApproverStockTake: React.FC = ({
) : (
<>
+
diff --git a/src/components/StockTakeManagement/PickerReStockTake.tsx b/src/components/StockTakeManagement/PickerReStockTake.tsx
index e186194..9233ca8 100644
--- a/src/components/StockTakeManagement/PickerReStockTake.tsx
+++ b/src/components/StockTakeManagement/PickerReStockTake.tsx
@@ -354,6 +354,17 @@ const PickerReStockTake: React.FC = ({
) : (
<>
+
diff --git a/src/components/StockTakeManagement/PickerStockTake.tsx b/src/components/StockTakeManagement/PickerStockTake.tsx
index 9c49f44..cda39cf 100644
--- a/src/components/StockTakeManagement/PickerStockTake.tsx
+++ b/src/components/StockTakeManagement/PickerStockTake.tsx
@@ -443,6 +443,17 @@ const PickerStockTake: React.FC = ({
) : (
<>
+
diff --git a/src/i18n/en/dashboard.json b/src/i18n/en/dashboard.json
index 7d5f025..5a1c9aa 100644
--- a/src/i18n/en/dashboard.json
+++ b/src/i18n/en/dashboard.json
@@ -73,6 +73,11 @@
"Last Ticket End": "Last Ticket End",
"Pick Time (min)": "Pick Time (min)",
"No truck schedules available for today": "No truck schedules available for today",
+ "No truck schedules available": "No truck schedules available",
+ "Select Date": "Select Date",
+ "Today": "Today",
+ "Tomorrow": "Tomorrow",
+ "Day After Tomorrow": "Day After Tomorrow",
"Goods Receipt Status": "Goods Receipt Status",
"Filter": "Filter",
"All": "All",
diff --git a/src/i18n/en/items.json b/src/i18n/en/items.json
index 40d8912..cf58fad 100644
--- a/src/i18n/en/items.json
+++ b/src/i18n/en/items.json
@@ -9,5 +9,12 @@
"Back": "Back",
"Status": "Status",
"Complete": "Complete",
- "Missing Data": "Missing Data"
+ "Missing Data": "Missing Data",
+ "Loading QC items...": "Loading QC items...",
+ "Select a QC template to view items": "Select a QC template to view items",
+ "No QC items in this template": "No QC items in this template",
+ "QC Checklist": "QC Checklist",
+ "QC Type": "QC Type",
+ "IPQC": "IPQC",
+ "EPQC": "EPQC"
}
\ No newline at end of file
diff --git a/src/i18n/en/qcItemAll.json b/src/i18n/en/qcItemAll.json
new file mode 100644
index 0000000..f587f48
--- /dev/null
+++ b/src/i18n/en/qcItemAll.json
@@ -0,0 +1,58 @@
+{
+ "Qc Item All": "QC Management",
+ "Item and Qc Category Mapping": "Item and Qc Category Mapping",
+ "Qc Category and Qc Item Mapping": "Qc Category and Qc Item Mapping",
+ "Qc Category Management": "Qc Category Management",
+ "Qc Item Management": "Qc Item Management",
+ "Qc Category": "Qc Category",
+ "Qc Item": "Qc Item",
+ "Item": "Item",
+ "Code": "Code",
+ "Name": "Name",
+ "Description": "Description",
+ "Type": "Type",
+ "Order": "Order",
+ "Item Count": "Item Count",
+ "Qc Item Count": "Qc Item Count",
+ "Qc Category Count": "Qc Category Count",
+ "Actions": "Actions",
+ "View": "View",
+ "Edit": "Edit",
+ "Delete": "Delete",
+ "Add": "Add",
+ "Add Mapping": "Add Mapping",
+ "Add Association": "Add Association",
+ "Save": "Save",
+ "Cancel": "Cancel",
+ "Submit": "Submit",
+ "Details": "Details",
+ "Create Qc Category": "Create Qc Category",
+ "Edit Qc Category": "Edit Qc Category",
+ "Create Qc Item": "Create Qc Item",
+ "Edit Qc Item": "Edit Qc Item",
+ "Delete Success": "Delete Success",
+ "Delete Error": "Delete Error",
+ "Submit Success": "Submit Success",
+ "Submit Error": "Submit Error",
+ "Cannot Delete": "Cannot Delete",
+ "Cannot delete QcCategory. It has {itemCount} item(s) and {qcItemCount} qc item(s) linked to it.": "Cannot delete QcCategory. It has {itemCount} item(s) and {qcItemCount} qc item(s) linked to it.",
+ "Cannot delete QcItem. It is linked to one or more QcCategories.": "Cannot delete QcItem. It is linked to one or more QcCategories.",
+ "Select Item": "Select Item",
+ "Select Qc Category": "Select Qc Category",
+ "Select Qc Item": "Select Qc Item",
+ "Select Type": "Select Type",
+ "Item Code": "Item Code",
+ "Item Name": "Item Name",
+ "Qc Category Code": "Qc Category Code",
+ "Qc Category Name": "Qc Category Name",
+ "Qc Item Code": "Qc Item Code",
+ "Qc Item Name": "Qc Item Name",
+ "Mapping Details": "Mapping Details",
+ "Association Details": "Association Details",
+ "No mappings found": "No mappings found",
+ "No associations found": "No associations found",
+ "No data available": "No data available",
+ "Confirm Delete": "Confirm Delete",
+ "Are you sure you want to delete this item?": "Are you sure you want to delete this item?"
+}
+
diff --git a/src/i18n/zh/dashboard.json b/src/i18n/zh/dashboard.json
index 6fdfaec..c2cf9d7 100644
--- a/src/i18n/zh/dashboard.json
+++ b/src/i18n/zh/dashboard.json
@@ -65,7 +65,7 @@
"Last updated": "最後更新",
"Truck Schedule": "車輛班次",
"Time Remaining": "剩餘時間",
- "No. of Shops": "門店數量",
+ "No. of Shops": "門店數量[提票數量]",
"Total Items": "總貨品數",
"Tickets Released": "已發放成品出倉單",
"First Ticket Start": "首單開始時間",
@@ -73,6 +73,11 @@
"Last Ticket End": "末單結束時間",
"Pick Time (min)": "揀貨時間(分鐘)",
"No truck schedules available for today": "今日無車輛調度計劃",
+ "No truck schedules available": "無車輛調度計劃",
+ "Select Date": "請選擇日期",
+ "Today": "是日",
+ "Tomorrow": "翌日",
+ "Day After Tomorrow": "後日",
"Goods Receipt Status": "貨物接收狀態",
"Filter": "篩選",
"All": "全部",
diff --git a/src/i18n/zh/inventory.json b/src/i18n/zh/inventory.json
index 831d0e0..d2e9663 100644
--- a/src/i18n/zh/inventory.json
+++ b/src/i18n/zh/inventory.json
@@ -33,6 +33,11 @@
"Start Time": "開始時間",
"Difference": "差異",
"stockTaking": "盤點中",
+ "rejected": "已拒絕",
+ "miss": "缺貨",
+ "bad": "不良",
+ "expiry": "過期",
+ "Bom Req. Qty": "需求數(BOM單位)",
"selected stock take qty": "已選擇盤點數量",
"book qty": "帳面庫存",
"start time": "開始時間",
diff --git a/src/i18n/zh/items.json b/src/i18n/zh/items.json
index c2f200a..288c7b8 100644
--- a/src/i18n/zh/items.json
+++ b/src/i18n/zh/items.json
@@ -36,12 +36,19 @@
"LocationCode": "預設位置",
"DefaultLocationCode": "預設位置",
"Special Type": "特殊類型",
-"None": "無",
+"None": "正常",
"isEgg": "雞蛋",
"isFee": "費用",
"isBag": "袋子",
"Back": "返回",
"Status": "狀態",
"Complete": "完成",
-"Missing Data": "缺少資料"
+"Missing Data": "缺少資料",
+"Loading QC items...": "正在加載質檢項目...",
+"Select a QC template to view items": "選擇質檢模板以查看項目",
+"No QC items in this template": "此模板無質檢項目",
+"QC Checklist": "質檢項目",
+"QC Type": "質檢種類",
+"IPQC": "IPQC",
+"EPQC": "EPQC"
}
\ No newline at end of file
diff --git a/src/i18n/zh/jo.json b/src/i18n/zh/jo.json
index a66718c..21d94b0 100644
--- a/src/i18n/zh/jo.json
+++ b/src/i18n/zh/jo.json
@@ -203,6 +203,7 @@
"No Group": "沒有組",
"No created items": "沒有創建物料",
"Order Quantity": "需求數",
+ "Bom Req. Qty": "需求數(BOM單位)",
"Selected": "已選擇",
"Are you sure you want to delete this procoess?": "您確定要刪除此工序嗎?",
"Please select item": "請選擇物料",
diff --git a/src/i18n/zh/qcItemAll.json b/src/i18n/zh/qcItemAll.json
new file mode 100644
index 0000000..370113b
--- /dev/null
+++ b/src/i18n/zh/qcItemAll.json
@@ -0,0 +1,58 @@
+{
+ "Qc Item All": "QC 綜合管理",
+ "Item and Qc Category Mapping": "物料與品檢模板映射",
+ "Qc Category and Qc Item Mapping": "品檢模板與品檢項目映射",
+ "Qc Category Management": "品檢模板管理",
+ "Qc Item Management": "品檢項目管理",
+ "Qc Category": "品檢模板",
+ "Qc Item": "品檢項目",
+ "Item": "物料",
+ "Code": "編號",
+ "Name": "名稱",
+ "Description": "描述",
+ "Type": "類型",
+ "Order": "順序",
+ "Item Count": "關聯物料數量",
+ "Qc Item Count": "關聯品檢項目數量",
+ "Qc Category Count": "關聯品檢模板數量",
+ "Actions": "操作",
+ "View": "查看",
+ "Edit": "編輯",
+ "Delete": "刪除",
+ "Add": "新增",
+ "Add Mapping": "新增映射",
+ "Add Association": "新增關聯",
+ "Save": "儲存",
+ "Cancel": "取消",
+ "Submit": "提交",
+ "Details": "詳情",
+ "Create Qc Category": "新增品檢模板",
+ "Edit Qc Category": "編輯品檢模板",
+ "Create Qc Item": "新增品檢項目",
+ "Edit Qc Item": "編輯品檢項目",
+ "Delete Success": "刪除成功",
+ "Delete Error": "刪除失敗",
+ "Submit Success": "提交成功",
+ "Submit Error": "提交失敗",
+ "Cannot Delete": "無法刪除",
+ "Cannot delete QcCategory. It has {itemCount} item(s) and {qcItemCount} qc item(s) linked to it.": "無法刪除品檢模板。它有 {itemCount} 個物料和 {qcItemCount} 個品檢項目與其關聯。",
+ "Cannot delete QcItem. It is linked to one or more QcCategories.": "無法刪除品檢項目。它與一個或多個品檢模板關聯。",
+ "Select Item": "選擇物料",
+ "Select Qc Category": "選擇品檢模板",
+ "Select Qc Item": "選擇品檢項目",
+ "Select Type": "選擇類型",
+ "Item Code": "物料編號",
+ "Item Name": "物料名稱",
+ "Qc Category Code": "品檢模板編號",
+ "Qc Category Name": "品檢模板名稱",
+ "Qc Item Code": "品檢項目編號",
+ "Qc Item Name": "品檢項目名稱",
+ "Mapping Details": "映射詳情",
+ "Association Details": "關聯詳情",
+ "No mappings found": "未找到映射",
+ "No associations found": "未找到關聯",
+ "No data available": "暫無數據",
+ "Confirm Delete": "確認刪除",
+ "Are you sure you want to delete this item?": "您確定要刪除此項目嗎?"
+}
+