Преглед изворни кода

Remove hardcoded placeholders and codes

debrand
Harry Groves пре 1 месец
родитељ
комит
2f7419207b
27 измењених фајлова са 255 додато и 6875 уклоњено
  1. +2
    -2
      src/app/(main)/laserPrint/page.tsx
  2. +2
    -2
      src/app/(main)/m18Syn/page.tsx
  3. +3
    -3
      src/app/(main)/ps/page.tsx
  4. +1
    -1
      src/app/(main)/report/AsyncItemCodeAutocomplete.tsx
  5. +1
    -1
      src/app/(main)/report/ItemQcReportFilters.tsx
  6. +2
    -2
      src/app/(main)/report/page.tsx
  7. +1
    -1
      src/app/(main)/report/reportCategories.ts
  8. +4
    -7
      src/app/(main)/testing/page.tsx
  9. +3
    -3
      src/app/api/bagPrint/actions.ts
  10. +28
    -20
      src/components/BagPrint/BagPrintSearch.tsx
  11. +2
    -2
      src/components/DeliveryOrderFloorSettings/DeliveryOrderFloorSettings.tsx
  12. +23
    -1871
      src/components/DetailScheduleDetail/ViewByFGDetails.tsx
  13. +18
    -1872
      src/components/DetailedScheduleDetail/TempRecords.tsx
  14. +21
    -15
      src/components/LaserPrint/LaserPrintSearch.tsx
  15. +2
    -2
      src/components/PoDetail/PutAwayForm.tsx
  16. +29
    -34
      src/components/PoWorkbench/detailsGrid/poWorkbenchDetailsGridMock.ts
  17. +2
    -2
      src/components/ProductionProcess/ProductionProcessDetail.tsx
  18. +11
    -2911
      src/components/RoughScheduleDetail/TempRecords.tsx
  19. +35
    -71
      src/config/reportConfig.ts
  20. +6
    -6
      src/i18n/en/deliveryOrderFloor.json
  21. +2
    -2
      src/i18n/en/m18Sync.json
  22. +23
    -17
      src/i18n/en/report.json
  23. +6
    -6
      src/i18n/zh/deliveryOrderFloor.json
  24. +1
    -1
      src/i18n/zh/laserPrint.json
  25. +2
    -2
      src/i18n/zh/m18Sync.json
  26. +2
    -2
      src/i18n/zh/navigation.json
  27. +23
    -17
      src/i18n/zh/report.json

+ 2
- 2
src/app/(main)/laserPrint/page.tsx Прегледај датотеку

@@ -4,7 +4,7 @@ import LaserPrintSearch from "@/components/LaserPrint/LaserPrintSearch";
import { Stack, Typography } from "@mui/material";

export const metadata: Metadata = {
title: "檸檬機(激光機)",
title: "激光機",
};

export default async function LaserPrintPage() {
@@ -12,7 +12,7 @@ export default async function LaserPrintPage() {
<I18nProvider namespaces={["laserPrint", "navigation", "common"]}>
<Stack direction="row" justifyContent="space-between" flexWrap="wrap" rowGap={2}>
<Typography variant="h4" marginInlineEnd={2}>
檸檬機(激光機)
激光機
</Typography>
</Stack>
<LaserPrintSearch />


+ 2
- 2
src/app/(main)/m18Syn/page.tsx Прегледај датотеку

@@ -318,7 +318,7 @@ export default function M18SynPage() {
label="PO Code"
value={m18PoCode}
onChange={(e) => setM18PoCode(e.target.value)}
placeholder="e.g. PFP002PO26030341"
placeholder="e.g. DEMO-PO-001"
sx={{ minWidth: 320 }}
/>
<Button variant="contained" color="primary" onClick={handleSyncM18PoByCode} disabled={isSyncingM18Po}>
@@ -418,7 +418,7 @@ export default function M18SynPage() {
label="Item / product code"
value={m18ProductCode}
onChange={(e) => setM18ProductCode(e.target.value)}
placeholder="e.g. PP1175 (M18 item code)"
placeholder="e.g. DEMO-FG-01"
sx={{ minWidth: 320 }}
/>
<Button


+ 3
- 3
src/app/(main)/ps/page.tsx Прегледај датотеку

@@ -1179,9 +1179,9 @@ export default function ProductionSchedulePage() {
<th className="px-4 py-2 text-left font-bold text-slate-700 dark:text-slate-200">設定排期庫存</th>
<th className="px-4 py-2 text-right font-bold text-slate-700 dark:text-slate-200">過去平均出貨量</th>
<th className="px-4 py-2 text-left font-bold text-slate-700 dark:text-slate-200">設定排期每天出貨量</th>
<th className="px-4 py-2 text-center font-bold text-slate-700 dark:text-slate-200">咖啡</th>
<th className="px-4 py-2 text-center font-bold text-slate-700 dark:text-slate-200">茶</th>
<th className="px-4 py-2 text-center font-bold text-slate-700 dark:text-slate-200">檸檬</th>
<th className="px-4 py-2 text-center font-bold text-slate-700 dark:text-slate-200">類別 A</th>
<th className="px-4 py-2 text-center font-bold text-slate-700 dark:text-slate-200">類別 B</th>
<th className="px-4 py-2 text-center font-bold text-slate-700 dark:text-slate-200">類別 C</th>
</tr>
</thead>
<tbody>


+ 1
- 1
src/app/(main)/report/AsyncItemCodeAutocomplete.tsx Прегледај датотеку

@@ -239,7 +239,7 @@ const AsyncItemCodeAutocomplete: React.FC<Props> = ({
{...params}
fullWidth
label={label}
placeholder={hasSelection ? "" : (placeholder || "e.g. FA0591")}
placeholder={hasSelection ? "" : (placeholder || "e.g. DEMO-FG-01")}
helperText={t("typeToSearchItemCode", { min: minChars })}
InputLabelProps={params.InputLabelProps}
InputProps={{


+ 1
- 1
src/app/(main)/report/ItemQcReportFilters.tsx Прегледај датотеку

@@ -75,7 +75,7 @@ export default function ItemQcReportFilters({
label={field("itemCode", "貨品編號 Item Code")}
value={criteria.itemCode || ""}
onChange={(e) => onFieldChange("itemCode", e.target.value)}
placeholder="e.g. MJ0364"
placeholder="e.g. DEMO-FG-01"
/>
</Grid>
<Grid item {...gridSize}>


+ 2
- 2
src/app/(main)/report/page.tsx Прегледај датотеку

@@ -159,7 +159,7 @@ export default function ReportPage() {
if (reportId === 'rep-010') {
updateCriteria({ qcType: 'all', qcItemScope: 'all' });
} else if (reportId === 'rep-004') {
updateCriteria({ storeId: 'All', poPrefix: 'All' });
updateCriteria({ storeId: 'All' });
} else if (reportId === 'rep-021') {
updateCriteria({ storeId: 'All', stockTakeSectionDescription: 'All', lotOrigin: 'All' });
} else {
@@ -727,7 +727,7 @@ export default function ReportPage() {
<Grid item {...gridSize} key={fieldKey}>
<AsyncItemCodeAutocomplete
label={translatedLabel}
placeholder={field.placeholder || "e.g. FA0591"}
placeholder={field.placeholder || "e.g. DEMO-FG-01"}
value={selectedCodes}
onInputValueChange={(text) => {
pendingItemCodeInputRef.current[field.name] = text;


+ 1
- 1
src/app/(main)/report/reportCategories.ts Прегледај датотеку

@@ -33,6 +33,6 @@ export const REPORT_CATEGORIES: ReportCategoryConfig[] = [
headerBg: "#f5d4a8",
bodyBg: "#fdf6ec",
accent: "#e65100",
reportIds: ["rep-006", "rep-005", "rep-015"],
reportIds: ["rep-006", "rep-005"],
},
];

+ 4
- 7
src/app/(main)/testing/page.tsx Прегледај датотеку

@@ -560,7 +560,7 @@ export default function TestingPage() {
<Alert severity="info" sx={{ mb: 2 }}>
Uses <strong>GET /py/job-orders?planStart=</strong> for the day,
then the same <code>jobOrders</code> payload as{" "}
<strong>Bag Print → 下載 OnPack2023檸檬機</strong>. The ZIP contains
<strong>Bag Print → 下載 OnPack 文字</strong>. The ZIP contains
loose <code>.job</code> / <code>.image</code> / BMPs — extract
before sending to NGE; the ZIP itself is only a transport bundle.
</Alert>
@@ -973,12 +973,9 @@ export default function TestingPage() {
<TabPanel value={tabValue} index={5}>
<Section title="6. M18 sync alert email">
<Alert severity="info" sx={{ mb: 2 }}>
Production sync errors email{" "}
<strong>[email protected]</strong> and{" "}
<strong>[email protected]</strong> (see{" "}
<code>scheduler.sync-alert.email.to-addresses</code>). WhatsApp/Twilio
is disabled. SMTP from DB <code>MAIL.smtp.*</code> (e.g. Gmail{" "}
<code>[email protected]</code> + app password).
Production sync errors email the addresses in{" "}
<code>scheduler.sync-alert.email.to-addresses</code>. WhatsApp/Twilio
is disabled. SMTP comes from DB <code>MAIL.smtp.*</code>.
</Alert>
<Stack spacing={2} sx={{ mb: 2, maxWidth: 720 }}>
<TextField


+ 3
- 3
src/app/api/bagPrint/actions.ts Прегледај датотеку

@@ -180,7 +180,7 @@ function skippedWithoutExpiryFromResponse(res: Response): string[] {
.filter(Boolean);
}

/** 汁水機 OnPack — same as QR ZIP, plus LOGO_EXP BMP from item_default_shelf_life. */
/** OnPack QR — same as QR ZIP, plus LOGO_EXP BMP from item_default_shelf_life. */
export async function downloadOnPackQrZipWithExpiry(
request: OnPackQrDownloadRequest,
): Promise<OnPackZipDownload> {
@@ -201,7 +201,7 @@ export async function downloadOnPackQrZipWithExpiry(
};
}

/** OnPack2023 檸檬機 — text QR template (`onpack2030_2`), no separate .bmp */
/** OnPack text QR template (`onpack2030_2`), no separate .bmp */
export async function downloadOnPackTextQrZip(
request: OnPackQrDownloadRequest,
): Promise<Blob> {
@@ -219,7 +219,7 @@ export async function downloadOnPackTextQrZip(
return res.blob();
}

/** OnPack2023 檸檬機 — same as text ZIP, plus TEXT_EXP from item_default_shelf_life. */
/** OnPack text QR — same as text ZIP, plus TEXT_EXP from item_default_shelf_life. */
export async function downloadOnPackTextQrZipWithExpiry(
request: OnPackQrDownloadRequest,
): Promise<OnPackZipDownload> {


+ 28
- 20
src/components/BagPrint/BagPrintSearch.tsx Прегледај датотеку

@@ -82,15 +82,23 @@ const SETTINGS_KEY = "bagPrint_settings";
const DEFAULT_SETTINGS = {
dabag_ip: "",
dabag_port: "3008",
laser_ip: "192.168.17.10",
laser_ip: "",
laser_port: "45678",
};

const LIVE_PRINTER_HOSTS = new Set(["192.168.17.10", "192.168.18.77"]);

function loadSettings(): typeof DEFAULT_SETTINGS {
if (typeof window === "undefined") return DEFAULT_SETTINGS;
try {
const s = localStorage.getItem(SETTINGS_KEY);
if (s) return { ...DEFAULT_SETTINGS, ...JSON.parse(s) };
if (s) {
const merged = { ...DEFAULT_SETTINGS, ...JSON.parse(s) };
if (LIVE_PRINTER_HOSTS.has(String(merged.laser_ip ?? "").trim())) {
merged.laser_ip = "";
}
return merged;
}
} catch {}
return DEFAULT_SETTINGS;
}
@@ -467,11 +475,11 @@ const BagPrintSearch: React.FC = () => {
link.remove();
window.URL.revokeObjectURL(url);

setSnackbar(skippedExpirySnackbar("OnPack 汁水機(含到期日)ZIP 已下載", skippedWithoutExpiry));
setSnackbar(skippedExpirySnackbar("OnPack QR(含到期日)ZIP 已下載", skippedWithoutExpiry));
} catch (e) {
setSnackbar({
open: true,
message: e instanceof Error ? e.message : "下載 OnPack 汁水機(含到期日)失敗",
message: e instanceof Error ? e.message : "下載 OnPack QR(含到期日)失敗",
severity: "error",
});
} finally {
@@ -505,11 +513,11 @@ const BagPrintSearch: React.FC = () => {
link.remove();
window.URL.revokeObjectURL(url);

setSnackbar({ open: true, message: "OnPack2023檸檬機 ZIP 已下載", severity: "success" });
setSnackbar({ open: true, message: "OnPack 文字 ZIP 已下載", severity: "success" });
} catch (e) {
setSnackbar({
open: true,
message: e instanceof Error ? e.message : "下載 OnPack2023檸檬機 失敗",
message: e instanceof Error ? e.message : "下載 OnPack 文字 失敗",
severity: "error",
});
} finally {
@@ -544,11 +552,11 @@ const BagPrintSearch: React.FC = () => {
link.remove();
window.URL.revokeObjectURL(url);

setSnackbar(skippedExpirySnackbar("OnPack2023檸檬機(含到期日)ZIP 已下載", skippedWithoutExpiry));
setSnackbar(skippedExpirySnackbar("OnPack 文字(含到期日)ZIP 已下載", skippedWithoutExpiry));
} catch (e) {
setSnackbar({
open: true,
message: e instanceof Error ? e.message : "下載 OnPack2023檸檬機(含到期日)失敗",
message: e instanceof Error ? e.message : "下載 OnPack 文字(含到期日)失敗",
severity: "error",
});
} finally {
@@ -597,7 +605,7 @@ const BagPrintSearch: React.FC = () => {
),
);
} catch {
/* 檸檬機標籤可沒有;不擋畫面 */
/* 激光機標籤可沒有;不擋畫面 */
}
})();
}, []);
@@ -793,7 +801,7 @@ const BagPrintSearch: React.FC = () => {
jobOrders.length === 0
}
>
{downloadingOnPack ? "下載中..." : "下載 OnPack 汁水機 QR code"}
{downloadingOnPack ? "下載中..." : "下載 OnPack QR code"}
</Button>
<Button
variant="contained"
@@ -808,7 +816,7 @@ const BagPrintSearch: React.FC = () => {
jobOrders.length === 0
}
>
{downloadingOnPackExp ? "下載中..." : "下載 OnPack 汁水機(含到期日)"}
{downloadingOnPackExp ? "下載中..." : "下載 OnPack QR(含到期日)"}
</Button>
<Button
variant="contained"
@@ -824,7 +832,7 @@ const BagPrintSearch: React.FC = () => {
jobOrders.length === 0
}
>
{downloadingOnPackText ? "下載中..." : "下載 OnPack2023檸檬機"}
{downloadingOnPackText ? "下載中..." : "下載 OnPack 文字"}
</Button>
{canSeeOnPackAdmin && (
<Button
@@ -841,7 +849,7 @@ const BagPrintSearch: React.FC = () => {
jobOrders.length === 0
}
>
{downloadingOnPackTextExp ? "下載中..." : "下載 OnPack2023檸檬機(含到期日)"}
{downloadingOnPackTextExp ? "下載中..." : "下載 OnPack 文字(含到期日)"}
</Button>
)}
</Stack>
@@ -903,8 +911,8 @@ const BagPrintSearch: React.FC = () => {
{jo.itemCode || "—"}
</Typography>
<Stack direction="row" spacing={0.5} flexWrap="wrap" useFlexGap sx={{ mt: 0.5 }}>
{juiceExpiryOk ? <Chip size="small" label="汁水機" color="primary" /> : null}
{lemonOk ? <Chip size="small" label="檸檬機" color="secondary" /> : null}
{juiceExpiryOk ? <Chip size="small" label="OnPack QR" color="primary" /> : null}
{lemonOk ? <Chip size="small" label="激光機" color="secondary" /> : null}
</Stack>
</Box>
<Box sx={{ flex: 1, minWidth: 0 }}>
@@ -1086,17 +1094,17 @@ const BagPrintSearch: React.FC = () => {
>
<Stack spacing={1.5} sx={{ flexShrink: 0, mb: 1 }}>
<Typography variant="subtitle2" color="primary">
汁水機({expiryCodes.length})
OnPack QR({expiryCodes.length})
</Typography>
<Typography variant="body2" color="text.secondary">
「下載 OnPack 汁水機(含到期日)」只用此清單。名稱印在 Product 行,過長可改短後按儲存。
「下載 OnPack QR(含到期日)」只用此清單。名稱印在 Product 行,過長可改短後按儲存。
點欄位標題可排序;冷藏/-18/列印第一次點擊會把「未設」排到最前。
</Typography>
<Stack direction="row" spacing={1} alignItems="center">
<TextField
label="新增品號"
size="small"
placeholder="例如 PP2211"
placeholder="例如 DEMO-FG-01"
value={expiryCodeInput}
onChange={(e) => setExpiryCodeInput(e.target.value)}
onKeyDown={(e) => {
@@ -1216,7 +1224,7 @@ const BagPrintSearch: React.FC = () => {
onChange={(e) =>
setNameDrafts((prev) => ({ ...prev, [row.itemCode]: e.target.value }))
}
placeholder={row.defaultPrintName || "例如 豬肉水(1包X2千克)"}
placeholder={row.defaultPrintName || "例如 鄉村麵包"}
inputProps={{ maxLength: 255 }}
fullWidth
/>
@@ -1292,7 +1300,7 @@ const BagPrintSearch: React.FC = () => {
</TableContainer>
)}
<Typography variant="body2" color="text.secondary" sx={{ flexShrink: 0, mt: 1 }}>
檸檬機到期日 ZIP 品號稍後加入。
激光機到期日 ZIP 品號稍後加入。
</Typography>
</DialogContent>
<DialogActions>


+ 2
- 2
src/components/DeliveryOrderFloorSettings/DeliveryOrderFloorSettings.tsx Прегледај датотеку

@@ -358,8 +358,8 @@ const DeliveryOrderFloorSettings: React.FC = () => {
onChange={onFloorSelectChange}
disabled={dialogSaving || comboLoading}
>
<MenuItem value="2F">2F</MenuItem>
<MenuItem value="4F">4F</MenuItem>
<MenuItem value="2F">2/F</MenuItem>
<MenuItem value="4F">4/F</MenuItem>
</Select>
</FormControl>
<Button


+ 23
- 1871
src/components/DetailScheduleDetail/ViewByFGDetails.tsx
Разлика између датотеке није приказан због своје велике величине
Прегледај датотеку


+ 18
- 1872
src/components/DetailedScheduleDetail/TempRecords.tsx
Разлика између датотеке није приказан због своје велике величине
Прегледај датотеку


+ 21
- 15
src/components/LaserPrint/LaserPrintSearch.tsx Прегледај датотеку

@@ -83,21 +83,27 @@ const LaserPrintSearch: React.FC = () => {
message: "",
});
const [successSignal, setSuccessSignal] = useState<string | null>(null);
const [laserHost, setLaserHost] = useState("192.168.18.77");
const [laserHost, setLaserHost] = useState("");
const [laserPort, setLaserPort] = useState("45678");
const [laserItemCodes, setLaserItemCodes] = useState("PP1175");
const [laserItemCodes, setLaserItemCodes] = useState("");
const [lastLaserReceive, setLastLaserReceive] = useState<LaserLastReceiveSuccess | null>(null);
const [settingsLoaded, setSettingsLoaded] = useState(false);
const [printerConnected, setPrinterConnected] = useState(false);
const [printerMessage, setPrinterMessage] = useState("檸檬機(激光機)未連接");
const [printerMessage, setPrinterMessage] = useState("激光機未連接");
const sendInFlightRef = useRef(false);

const loadSystemSettings = useCallback(async () => {
try {
const s = await fetchLaserBag2Settings();
setLaserHost(s.host);
const host = (s.host ?? "").trim();
setLaserHost(host === "192.168.18.77" || host === "192.168.17.10" ? "" : host);
setLaserPort(String(s.port));
setLaserItemCodes(s.itemCodes ?? "PP1175");
const itemCodes = (s.itemCodes ?? "")
.split(",")
.map((code) => code.trim())
.filter((code) => code && code !== "PP1175" && code !== "PP2211")
.join(",");
setLaserItemCodes(itemCodes);
setLastLaserReceive(s.lastReceiveSuccess ?? null);
setSettingsLoaded(true);
} catch (e) {
@@ -158,7 +164,7 @@ const LaserPrintSearch: React.FC = () => {
setPrinterMessage(result.message);
} catch (e) {
setPrinterConnected(false);
setPrinterMessage(e instanceof Error ? e.message : "檸檬機(激光機)狀態檢查失敗");
setPrinterMessage(e instanceof Error ? e.message : "激光機狀態檢查失敗");
}
}, []);

@@ -201,7 +207,7 @@ const LaserPrintSearch: React.FC = () => {
if (sendInFlightRef.current || sendingJobId !== null) return;

if (!laserHost.trim()) {
setErrorSnackbar({ open: true, message: "請在系統設定中填寫檸檬機(激光機) IP。" });
setErrorSnackbar({ open: true, message: "請在系統設定中填寫激光機 IP。" });
return;
}

@@ -239,8 +245,8 @@ const LaserPrintSearch: React.FC = () => {
: "";
setSuccessSignal(
laterFail
? `已送出 ${sentOk} 次至檸檬機(激光機)${ackHint}(後續重送失敗:${laterFail})`
: `已送出 ${sentOk} 次至檸檬機(激光機)${ackHint}`,
? `已送出 ${sentOk} 次至激光機${ackHint}(後續重送失敗:${laterFail})`
: `已送出 ${sentOk} 次至激光機${ackHint}`,
);
await loadSystemSettings();
} catch (e) {
@@ -287,7 +293,7 @@ const LaserPrintSearch: React.FC = () => {
{lastLaserReceive.source ? ` (${lastLaserReceive.source === "AUTO" ? "自動送出" : "手動點選"})` : ""}
</Typography>
<Typography variant="body2" sx={{ mt: 0.5 }}>
此時間只會在檸檬機回覆 receive 時更新。之後送出失敗不會改這裡。
此時間只會在激光機回覆 receive 時更新。之後送出失敗不會改這裡。
</Typography>
</Alert>
)}
@@ -332,7 +338,7 @@ const LaserPrintSearch: React.FC = () => {
}}
title={printerMessage}
>
檸檬機(激光機):
激光機:
</Box>
</Stack>
</Stack>
@@ -420,11 +426,11 @@ const LaserPrintSearch: React.FC = () => {
</Paper>

<Dialog open={settingsOpen} onClose={() => setSettingsOpen(false)} maxWidth="sm" fullWidth>
<DialogTitle>檸檬機(激光機)(系統設定)</DialogTitle>
<DialogTitle>激光機(系統設定)</DialogTitle>
<DialogContent>
<Stack spacing={2} sx={{ mt: 1 }}>
<Typography variant="body2" color="text.secondary">
儲存後寫入資料庫,後端送出走此 IP/埠(預設 192.168.18.77:45678)。
儲存後寫入資料庫,後端送出走此 IP/埠。未填 IP 則不會送出。
</Typography>
<TextField
label="IP"
@@ -446,8 +452,8 @@ const LaserPrintSearch: React.FC = () => {
value={laserItemCodes}
onChange={(e) => setLaserItemCodes(e.target.value)}
fullWidth
placeholder="PP1175"
helperText="預設 PP1175;可輸入多個品號,例如 PP1175,AB999。留空則列表顯示當日全部包裝工單。"
placeholder="例如 DEMO-FG-01"
helperText="可輸入多個品號,例如 DEMO-FG-01,DEMO-FG-02。留空則列表顯示當日全部包裝工單。"
/>
</Stack>
</DialogContent>


+ 2
- 2
src/components/PoDetail/PutAwayForm.tsx Прегледај датотеку

@@ -116,7 +116,7 @@ const PutAwayForm: React.FC<Props> = ({ itemDetail, warehouse=[], disabled, sugg
group: "default",
};
const options = useMemo(() => {
const defaultLabel = suggestedLocationCode || t("W201 - 2F-A,B室");
const defaultLabel = suggestedLocationCode || t("Select warehouse");
return [
{ value: 1, label: defaultLabel, group: "default" },
...filteredWarehouse.map((w) => ({
@@ -260,7 +260,7 @@ const PutAwayForm: React.FC<Props> = ({ itemDetail, warehouse=[], disabled, sugg
editable: false,
renderCell(params) {
const value = (params.value as string) ?? "";
// 目前格式像 "2F-W201-#L-08 - 2F-W201",只要左邊 LocationCode
// Location label is "code - description"; keep the code on the left.
const locationCode = value.split(" - ")[0] || value;
return (


+ 29
- 34
src/components/PoWorkbench/detailsGrid/poWorkbenchDetailsGridMock.ts Прегледај датотеку

@@ -5,72 +5,67 @@ export const PO_WORKBENCH_DETAILS_GRID_MOCK_ROWS: readonly PoWorkbenchDetailsGri
[
{
id: "mock-line-1",
itemName:
"澳洲和牛腱(冷凍)· A5級去筋切片裝 2.5kg×4包/箱(供應商批次:AU-WG-2026-Q1)",
itemCode: "AB1234",
itemName: "普通麵粉",
itemCode: "DEMO-RM-01",
category: "material",
storageLocation: "YF-W201-#A-12",
storageLocation: "DEMO-A-#A-01",
receiveStatus: "pending",
expectedQty: 100,
purchaseUnitLabel: "1箱X100包X150克",
purchaseUnitLabel: "1袋X25公斤",
receivedQtyPurchase: 0,
receivedQtyInventory: 0,
inventoryUnitLabel: "克",
inventoryUnitLabel: "公斤",
},
{
id: "mock-line-2",
itemName:
"耐高温真空膠袋(食品級)· 300×450mm 厚度80μm 每卷500個(雙層密封條)",
itemCode: "BC5678",
itemName: "鮮奶",
itemCode: "DEMO-RM-02",
category: "consumable",
storageLocation: "YF-C305-#B-04",
storageLocation: "DEMO-B-#B-02",
receiveStatus: "receiving",
expectedQty: 24,
purchaseUnitLabel: "1箱X24卷X500個",
receivedQtyPurchase: 26,
receivedQtyInventory: 312000,
inventoryUnitLabel: "個",
purchaseUnitLabel: "1箱X12瓶X1升",
receivedQtyPurchase: 12,
receivedQtyInventory: 12,
inventoryUnitLabel: "升",
},
{
id: "mock-line-3",
itemName:
"照燒汁(商用濃縮裝)· 日式醬油基底 5L/桶(開封後需冷藏,效期見標籤)",
itemCode: "FG9012",
itemName: "鄉村麵包",
itemCode: "DEMO-FG-01",
category: "finishedGoods",
storageLocation: "YF-D102-#C-08",
storageLocation: "DEMO-A-#C-03",
receiveStatus: "completed",
expectedQty: 48,
purchaseUnitLabel: "1板X4桶X5升",
purchaseUnitLabel: "1箱X8個",
receivedQtyPurchase: 48,
receivedQtyInventory: 960,
inventoryUnitLabel: "升",
receivedQtyInventory: 48,
inventoryUnitLabel: "個",
},
{
id: "mock-line-4",
itemName:
"高筋麵粉預拌漿(半成品)· 中央廚房標準配方 20kg/袋(含酵母改良劑)",
itemCode: "DE3456",
itemName: "麵團",
itemCode: "DEMO-SF-01",
category: "semiFinished",
storageLocation: "YF-W118-#D-22",
storageLocation: "DEMO-A-#D-04",
receiveStatus: "receiving",
expectedQty: 60,
purchaseUnitLabel: "1板X3袋X20公斤",
receivedQtyPurchase: 55,
receivedQtyInventory: 3300,
purchaseUnitLabel: "1袋X10公斤",
receivedQtyPurchase: 40,
receivedQtyInventory: 40,
inventoryUnitLabel: "公斤",
},
{
id: "mock-line-5",
itemName:
"廚房多功能清潔劑(濃縮原液)· 無磷配方 1L×12瓶/箱(勿與漂白水混用)",
itemCode: "EF7890",
itemName: "奶包",
itemCode: "DEMO-FG-02",
category: "miscNonConsumable",
storageLocation: "YF-M402-#E-01",
storageLocation: "DEMO-B-#E-05",
receiveStatus: "pending",
expectedQty: 120,
purchaseUnitLabel: "1扎X3箱X12包X350克",
purchaseUnitLabel: "1箱X20個",
receivedQtyPurchase: 0,
receivedQtyInventory: 0,
inventoryUnitLabel: "瓶",
inventoryUnitLabel: "個",
},
] as const;

+ 2
- 2
src/components/ProductionProcess/ProductionProcessDetail.tsx Прегледај датотеку

@@ -315,7 +315,7 @@ const fetchProcessDetailRef = useRef<() => Promise<void>>();
const processQrCode = useCallback((qrValue: string, lineId: number) => {
// 设备快捷格式:{2fitesteXXX} - XXX 直接作为设备代码
// 格式:{2fitesteXXX} = equipmentCode: "XXX"
// 例如:{2fiteste包裝機類-真空八爪魚機-1號} = equipmentCode: "包裝機類-真空八爪魚機-1號"
// 例如:{2fitesteDEMO-EQ-01} = equipmentCode: "DEMO-EQ-01"
if (qrValue.match(/\{2fiteste(.+)\}/)) {
const match = qrValue.match(/\{2fiteste(.+)\}/);
const equipmentCode = match![1];
@@ -371,7 +371,7 @@ const processQrCode = useCallback((qrValue: string, lineId: number) => {
// 可能是员工编号
setScannedStaffNo(trimmedValue);
} else if (trimmedValue.includes("-")) {
// 可能包含 "-" 的是设备代码(如 "包裝機類-真空八爪魚機-1號")
// 可能包含 "-" 的是设备代码(如 "DEMO-EQ-01")
setScannedEquipmentCode(trimmedValue);
}
}


+ 11
- 2911
src/components/RoughScheduleDetail/TempRecords.tsx
Разлика између датотеке није приказан због своје велике величине
Прегледај датотеку


+ 35
- 71
src/config/reportConfig.ts Прегледај датотеку

@@ -54,9 +54,20 @@ const asyncItemCodeField = (
multiple: true,
allowInput: true,
asyncSearch: true,
placeholder: "e.g. FA0591",
placeholder: "e.g. DEMO-FG-01",
});

const floorOptionsAll: ReportField["options"] = [
{ label: "全部", value: "All" },
{ label: "2/F", value: "2/F" },
{ label: "4/F", value: "4/F" },
];

const floorOptions: ReportField["options"] = [
{ label: "2/F", value: "2/F" },
{ label: "4/F", value: "4/F" },
];

const pasteItemCodeField = (): ReportField => ({
label: "貼上貨品編號 Paste Item Codes",
name: "itemCodePaste",
@@ -124,29 +135,12 @@ export const REPORTS: ReportDefinition[] = [
name: "storeId",
type: "select",
required: false,
options: [
{ label: "全部", value: "All" },
{ label: "1F", value: "1F" },
{ label: "2F", value: "2F" },
{ label: "3F", value: "3F" },
{ label: "4F", value: "4F" },
],
options: floorOptionsAll,
},
{ label: "倉庫 Warehouse", name: "warehouse", type: "text", required: false, placeholder: "e.g. W201" },
{ label: "倉庫 Warehouse", name: "warehouse", type: "text", required: false, placeholder: "e.g. DEMO-A" },
{ label: "區域 Area", name: "area", type: "text", required: false, placeholder: "e.g. #A" },
{ label: "儲位 Slot", name: "slot", type: "text", required: false, placeholder: "e.g. 01" },
{ label: "批號 Lot No", name: "lotNo", type: "text", required: false, placeholder: "e.g. LT-202608" },
{
label: "PP/PF 分類",
name: "poPrefix",
type: "select",
required: false,
options: [
{ label: "全部", value: "All" },
{ label: "PP", value: "PP" },
{ label: "PF", value: "PF" },
],
},
]
},
{
@@ -193,13 +187,7 @@ export const REPORTS: ReportDefinition[] = [
name: "store_id",
type: "select",
required: false,
options: [
{ label: "全部", value: "All" },
{ label: "1F", value: "1F" },
{ label: "2F", value: "2F" },
{ label: "3F", value: "3F" },
{ label: "4F", value: "4F" }
],
options: floorOptionsAll,
},
{
label: "狀態",
@@ -220,14 +208,11 @@ export const REPORTS: ReportDefinition[] = [
multiple: true,
options: [
{ label: "全部", value: "All" },
{ label: "PP", value: "PP" },
{ label: "PF", value: "PF" },
{ label: "TOA", value: "TOA" },
{ label: "工廠生產", value: "工廠生產" },
{ label: "倉存調整", value: "倉存調整" },
{ label: "期初存貨", value: "期初存貨" },
{ label: "採購入倉", value: "採購入倉" },
{ label: "其他入倉", value: "其他入倉" },
{ label: "採購", value: "purchase" },
{ label: "生產", value: "production" },
{ label: "倉存調整", value: "adjustment" },
{ label: "期初存貨", value: "opening" },
{ label: "其他", value: "other" },
],
},
]
@@ -241,19 +226,13 @@ export const REPORTS: ReportDefinition[] = [
fields: [
{ label: "庫存日期 Stock Date(僅今天)", name: "stockDate", type: "date", required: true, disabled: true },
{ label: "貨品編號 Item Code", name: "itemCode", type: "text", required: false },
{ label: "倉位 Warehouse Code", name: "warehouseCode", type: "text", required: false, placeholder: "e.g. W200 or 2F-W200-#A-00" },
{ label: "倉位 Warehouse Code", name: "warehouseCode", type: "text", required: false, placeholder: "e.g. DEMO-A" },
{
label: "樓層 Store ID",
name: "storeId",
type: "select",
required: false,
options: [
{ label: "全部", value: "All" },
{ label: "1F", value: "1F" },
{ label: "2F", value: "2F" },
{ label: "3F", value: "3F" },
{ label: "4F", value: "4F" },
],
options: floorOptionsAll,
},
{ label: "批號 Lot No", name: "lotNo", type: "text", required: false, placeholder: "e.g. LT-202608" },
],
@@ -271,15 +250,9 @@ export const REPORTS: ReportDefinition[] = [
name: "storeId",
type: "select",
required: false,
options: [
{ label: "全部", value: "All" },
{ label: "1F", value: "1F" },
{ label: "2F", value: "2F" },
{ label: "3F", value: "3F" },
{ label: "4F", value: "4F" },
],
options: floorOptionsAll,
},
{ label: "倉庫 Warehouse", name: "warehouse", type: "text", required: false, placeholder: "e.g. W201" },
{ label: "倉庫 Warehouse", name: "warehouse", type: "text", required: false, placeholder: "e.g. DEMO-A" },
{ label: "區域 Area", name: "area", type: "text", required: false, placeholder: "e.g. #A" },
{ label: "儲位 Slot", name: "slot", type: "text", required: false, placeholder: "e.g. 02" },
{
@@ -299,8 +272,8 @@ export const REPORTS: ReportDefinition[] = [
required: false,
options: [
{ label: "全部", value: "All" },
{ label: "PP", value: "PP" },
{ label: "PF", value: "PF" },
{ label: "採購", value: "purchase" },
{ label: "生產", value: "production" },
{ label: "其他", value: "other" },
],
},
@@ -442,12 +415,10 @@ export const REPORTS: ReportDefinition[] = [
{ label: "類別 Category", name: "stockCategory", type: "select", required: false,
multiple: true,
options: [
{ label: "All", value: "All" },
{ label: "MAT", value: "MAT" },
{ label: "WIP", value: "WIP" },
{ label: "NM", value: "NM" },
{ label: "FG", value: "FG" },
{ label: "CMB", value: "CMB" }
{ label: "全部", value: "All" },
{ label: "原料", value: "mat" },
{ label: "半成品", value: "sfg" },
{ label: "成品", value: "fg" },
] },
{ label: "貨品編號 Item Code", name: "itemCode", type: "select", required: false,
multiple: true,
@@ -472,9 +443,9 @@ export const REPORTS: ReportDefinition[] = [
{ label: "類別 Category", name: "stockCategory", type: "select", required: false,
multiple: true,
options: [
{ label: "All", value: "All" },
{ label: "WIP", value: "WIP" },
{ label: "FG", value: "FG" },
{ label: "全部", value: "All" },
{ label: "半成品", value: "sfg" },
{ label: "成品", value: "fg" },
] },
{ label: "貨品編號 Item Code", name: "itemCode", type: "select", required: false,
multiple: true,
@@ -533,10 +504,7 @@ export const REPORTS: ReportDefinition[] = [
name: "storeId",
type: "select",
required: false,
options: [
{ label: "2F", value: "2F" },
{ label: "4F", value: "4F" },
],
options: floorOptions,
},
],
},
@@ -574,11 +542,7 @@ export const REPORTS: ReportDefinition[] = [
name: "storeId",
type: "select",
required: false,
options: [
{ label: "全部", value: "All" },
{ label: "2F", value: "2F" },
{ label: "4F", value: "4F" },
],
options: floorOptionsAll,
},
],
},

+ 6
- 6
src/i18n/en/deliveryOrderFloor.json Прегледај датотеку

@@ -1,12 +1,12 @@
{
"title": "Delivery order / workbench floor (supplier codes)",
"Intro": "Manage supplier codes assigned to each floor. Use the edit button to add or remove suppliers from a floor.",
"2F supplier": "2F supplier",
"4F supplier": "4F supplier",
"Edit 2F": "Edit 2F",
"Edit 4F": "Edit 4F",
"Edit 2F title": "Edit 2F supplier codes",
"Edit 4F title": "Edit 4F supplier codes",
"2F supplier": "2/F supplier",
"4F supplier": "4/F supplier",
"Edit 2F": "Edit 2/F",
"Edit 4F": "Edit 4/F",
"Edit 2F title": "Edit 2/F supplier codes",
"Edit 4F title": "Edit 4/F supplier codes",
"Edit dialog title": "Edit floor–supplier mapping",
"Floor label": "Floor",
"Add mapping": "Add mapping",


+ 2
- 2
src/i18n/en/m18Sync.json Прегледај датотеку

@@ -20,10 +20,10 @@
"btnSyncDoExtra": "Sync DO (Extra) from M18",
"btnSyncProduct": "Sync product from M18",
"syncing": "Syncing...",
"placeholderPoCode": "e.g. PFP002PO26030341",
"placeholderPoCode": "e.g. DEMO-PO-001",
"placeholderDoCode": "e.g. same document code as M18 shop PO",
"placeholderDoExtraCode": "Enter multiple codes separated by comma or newline",
"placeholderProductCode": "e.g. PP1175 (M18 item code)",
"placeholderProductCode": "e.g. DEMO-FG-01",
"waiting": "Waiting for implementation...",
"noResponse": "No response received",
"alreadyExists": "{{docName}} already exists in system",


+ 23
- 17
src/i18n/en/report.json Прегледај датотеку

@@ -57,17 +57,11 @@
"warehouse": "Warehouse",
"area": "Area",
"slot": "Slot",
"lotNo": "Lot No",
"poPrefix": "PP/PF"
"lotNo": "Lot No"
},
"options": {
"storeId": {
"All": "All"
},
"poPrefix": {
"All": "All",
"PP": "PP",
"PF": "PF"
}
},
"fieldHints": {
@@ -107,14 +101,11 @@
},
"type": {
"All": "All",
"PP": "PP",
"PF": "PF",
"TOA": "TOA",
"工廠生產": "Factory production",
"倉存調整": "Inventory adjustment",
"期初存貨": "Opening inventory",
"採購入倉": "Purchase inbound",
"其他入倉": "Other inbound"
"purchase": "Purchase",
"production": "Production",
"adjustment": "Inventory adjustment",
"opening": "Opening inventory",
"other": "Other"
}
}
},
@@ -208,6 +199,14 @@
},
"fieldHints": {
"itemCodePaste": "Paste item codes from Excel. Separate with spaces, commas, or new lines"
},
"options": {
"stockCategory": {
"All": "All",
"mat": "Material",
"sfg": "Semi-finished",
"fg": "Finished goods"
}
}
},
"rep-005": {
@@ -222,6 +221,13 @@
},
"fieldHints": {
"itemCodePaste": "Paste item codes from Excel. Separate with spaces, commas, or new lines"
},
"options": {
"stockCategory": {
"All": "All",
"sfg": "Semi-finished",
"fg": "Finished goods"
}
}
},
"rep-015": {
@@ -295,8 +301,8 @@
},
"lotOrigin": {
"All": "All",
"PP": "PP",
"PF": "PF",
"purchase": "Purchase",
"production": "Production",
"other": "Other"
}
}


+ 6
- 6
src/i18n/zh/deliveryOrderFloor.json Прегледај датотеку

@@ -1,12 +1,12 @@
{
"title": "送貨單樓層設定(供應商代碼)",
"Intro": "管理各樓層的供應商代碼。點擊編輯按鈕可新增或移除供應商。",
"2F supplier": "2F 供應商",
"4F supplier": "4F 供應商",
"Edit 2F": "編輯 2F",
"Edit 4F": "編輯 4F",
"Edit 2F title": "編輯 2F 供應商代碼",
"Edit 4F title": "編輯 4F 供應商代碼",
"2F supplier": "2/F 供應商",
"4F supplier": "4/F 供應商",
"Edit 2F": "編輯 2/F",
"Edit 4F": "編輯 4/F",
"Edit 2F title": "編輯 2/F 供應商代碼",
"Edit 4F title": "編輯 4/F 供應商代碼",
"Edit dialog title": "編輯樓層供應商映射",
"Floor label": "樓層",
"Add mapping": "新增映射",


+ 1
- 1
src/i18n/zh/laserPrint.json Прегледај датотеку

@@ -1,3 +1,3 @@
{
"title": "檸檬機(激光機)"
"title": "激光機"
}

+ 2
- 2
src/i18n/zh/m18Sync.json Прегледај датотеку

@@ -20,10 +20,10 @@
"btnSyncDoExtra": "從 M18 同步送貨訂單(加單)",
"btnSyncProduct": "從 M18 同步貨品",
"syncing": "同步中…",
"placeholderPoCode": "例:PFP002PO26030341",
"placeholderPoCode": "例:DEMO-PO-001",
"placeholderDoCode": "例:與 M18 店鋪訂單相同的文件編號",
"placeholderDoExtraCode": "可輸入多個 code,用逗號或換行分隔",
"placeholderProductCode": "例:PP1175(M18 貨品編號)",
"placeholderProductCode": "例:DEMO-FG-01",
"waiting": "等待實作…",
"noResponse": "未收到回應",
"alreadyExists": "{{docName}}已存在系統",


+ 2
- 2
src/i18n/zh/navigation.json Прегледај датотеку

@@ -25,7 +25,7 @@
"nav.breadcrumb.joEdit": "工單詳情",
"nav.breadcrumb.joTesting": "工單測試",
"nav.breadcrumb.joWorkbench": "工單工作台",
"nav.breadcrumb.laserPrint": "檸檬機(激光機)",
"nav.breadcrumb.laserPrint": "激光機",
"nav.breadcrumb.m18Sync": "M18 同步",
"nav.breadcrumb.poEdit": "編輯",
"nav.breadcrumb.poWorkbench": "採購單工作台",
@@ -64,7 +64,7 @@
"nav.jobOrder.productionProcess": "工單生產流程",
"nav.jobOrder.searchCreate": "搜索工單/ 建立工單",
"nav.jobOrderManagement": "管理工單",
"nav.laserPrint": "檸檬機(激光機)",
"nav.laserPrint": "激光機",
"nav.m18Sync": "M18 同步",
"nav.productionServer": "正式伺服器",
"nav.report": "報告管理",


+ 23
- 17
src/i18n/zh/report.json Прегледај датотеку

@@ -57,17 +57,11 @@
"warehouse": "倉庫",
"area": "區域",
"slot": "儲位",
"lotNo": "批號",
"poPrefix": "PP/PF 分類"
"lotNo": "批號"
},
"options": {
"storeId": {
"All": "全部"
},
"poPrefix": {
"All": "全部",
"PP": "PP",
"PF": "PF"
}
},
"fieldHints": {
@@ -107,14 +101,11 @@
},
"type": {
"All": "全部",
"PP": "PP",
"PF": "PF",
"TOA": "TOA",
"工廠生產": "工廠生產",
"倉存調整": "倉存調整",
"期初存貨": "期初存貨",
"採購入倉": "採購入倉",
"其他入倉": "其他入倉"
"purchase": "採購",
"production": "生產",
"adjustment": "倉存調整",
"opening": "期初存貨",
"other": "其他"
}
}
},
@@ -208,6 +199,14 @@
},
"fieldHints": {
"itemCodePaste": "可從 Excel 貼上多個貨品編號,以空格、逗號或換行分隔"
},
"options": {
"stockCategory": {
"All": "全部",
"mat": "原料",
"sfg": "半成品",
"fg": "成品"
}
}
},
"rep-005": {
@@ -222,6 +221,13 @@
},
"fieldHints": {
"itemCodePaste": "可從 Excel 貼上多個貨品編號,以空格、逗號或換行分隔"
},
"options": {
"stockCategory": {
"All": "全部",
"sfg": "半成品",
"fg": "成品"
}
}
},
"rep-015": {
@@ -295,8 +301,8 @@
},
"lotOrigin": {
"All": "全部",
"PP": "PP",
"PF": "PF",
"purchase": "採購",
"production": "生產",
"other": "其他"
}
}


Loading…
Откажи
Сачувај