Procházet zdrojové kódy

demo bom excel

bomUpdateTest
CANCERYS\kw093 před 2 týdny
rodič
revize
a0515e4fbb
5 změnil soubory, kde provedl 77 přidání a 3 odebrání
  1. +14
    -0
      src/app/api/bom/client.ts
  2. +26
    -2
      src/components/ImportBom/BomVersionControlBar.tsx
  3. +33
    -1
      src/components/ImportBom/ImportBomDetailTab.tsx
  4. +2
    -0
      src/i18n/en/importBom.json
  5. +2
    -0
      src/i18n/zh/importBom.json

+ 14
- 0
src/app/api/bom/client.ts Zobrazit soubor

@@ -182,6 +182,20 @@ export async function fetchBomComboClient(options?: {
return response.data;
}

export async function downloadBomDetailExcelClient(
id: number,
fileName: string,
): Promise<{ blob: Blob; fileName: string }> {
const response = await axiosInstance.get(
`${NEXT_PUBLIC_API_URL}/bom/${id}/export-excel`,
{ responseType: "blob" },
);
return {
blob: response.data as Blob,
fileName,
};
}

export async function editBomClient(
id: number,
request: EditBomRequest,


+ 26
- 2
src/components/ImportBom/BomVersionControlBar.tsx Zobrazit soubor

@@ -14,6 +14,7 @@ import {
Typography,
} from "@mui/material";
import SaveIcon from "@mui/icons-material/Save";
import FileDownloadIcon from "@mui/icons-material/FileDownload";
import type { BomVersionSummary } from "@/app/api/bom";
import { fetchBomVersionsClient } from "@/app/api/bom/client";
import { useTranslation } from "react-i18next";
@@ -26,12 +27,15 @@ type Props = {
compareMode: boolean;
compareToId: number | "";
saving: boolean;
exporting?: boolean;
versionsRefreshKey?: number;
saveDisabled: boolean;
exportDisabled?: boolean;
saveError?: string | null;
onVersionChange: (id: number) => void;
onToggleCompare: () => void;
onCompareToChange: (id: number) => void;
onExport?: () => void;
onSave: () => void;
};

@@ -63,12 +67,15 @@ export const BomVersionControlBar: React.FC<Props> = ({
compareMode,
compareToId,
saving,
exporting = false,
versionsRefreshKey = 0,
saveDisabled,
exportDisabled = false,
saveError,
onVersionChange,
onToggleCompare,
onCompareToChange,
onExport,
onSave,
}) => {
const { t } = useTranslation("importBom");
@@ -94,7 +101,7 @@ export const BomVersionControlBar: React.FC<Props> = ({
}, [bomCode, bomKind, versionsRefreshKey]);

const showCompareButton = versions.length >= 2;
const controlsDisabled = loadingVersions || saving;
const controlsDisabled = loadingVersions || saving || exporting;
const comparingTwo =
compareMode &&
versionId !== "" &&
@@ -189,6 +196,23 @@ export const BomVersionControlBar: React.FC<Props> = ({
</Stack>

<Stack direction="row" spacing={1} alignItems="center" flexWrap="wrap">
{onExport && (
<Button
size="small"
variant="outlined"
startIcon={
exporting ? (
<CircularProgress size={16} color="inherit" />
) : (
<FileDownloadIcon />
)
}
disabled={saving || exporting || exportDisabled}
onClick={onExport}
>
{exporting ? t("Downloading...") : t("Export Excel")}
</Button>
)}
<Button
size="small"
variant="contained"
@@ -199,7 +223,7 @@ export const BomVersionControlBar: React.FC<Props> = ({
<SaveIcon />
)
}
disabled={saving || saveDisabled}
disabled={saving || exporting || saveDisabled}
onClick={onSave}
>
{saving ? t("Saving...") : t("Save")}


+ 33
- 1
src/components/ImportBom/ImportBomDetailTab.tsx Zobrazit soubor

@@ -32,6 +32,7 @@ import {
fetchBomDetailClient,
fetchAllEquipmentsMasterClient,
fetchAllProcessesMasterClient,
downloadBomDetailExcelClient,
type EquipmentMasterRow,
type ProcessMasterRow,
} from "@/app/api/bom/client";
@@ -100,6 +101,7 @@ const ImportBomDetailTab: React.FC = () => {
const [currentBom, setCurrentBom] = useState<BomCombo | null>(null);
const loadDetailInFlightRef = useRef(false);
const saveInFlightRef = useRef(false);
const exportInFlightRef = useRef(false);
const skipAutoSearchRef = useRef(false);
const detailIdRef = useRef<number | null>(null);
const lastSearchInputsRef = useRef<BomSearchInputs>(EMPTY_BOM_SEARCH_INPUTS);
@@ -164,6 +166,7 @@ const ImportBomDetailTab: React.FC = () => {
>([]);
const [editMasterLoading, setEditMasterLoading] = useState(false);
const [saving, setSaving] = useState(false);
const [exporting, setExporting] = useState(false);
const [saveError, setSaveError] = useState<string | null>(null);
const [versionId, setVersionId] = useState<number | "">("");
const [compareMode, setCompareMode] = useState(false);
@@ -549,6 +552,32 @@ const ImportBomDetailTab: React.FC = () => {
unresolvedMaterialIssueCount,
]);

const handleExportExcel = useCallback(async () => {
if (typeof versionId !== "number" || exportInFlightRef.current) return;
exportInFlightRef.current = true;
setExporting(true);
setSaveError(null);
try {
const code = (detail?.itemCode ?? currentBom?.code ?? "BOM").trim() || "BOM";
const rev = detail?.revisionNo ?? 1;
const { blob, fileName } = await downloadBomDetailExcelClient(
versionId,
`${code}_V${rev}.xlsx`,
);
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = fileName;
a.click();
URL.revokeObjectURL(url);
} catch (e: unknown) {
setSaveError(e instanceof Error ? e.message : t("Export excel failed"));
} finally {
setExporting(false);
exportInFlightRef.current = false;
}
}, [currentBom?.code, detail?.itemCode, detail?.revisionNo, t, versionId]);

const handleToggleCompare = useCallback(async () => {
if (compareMode) {
setCompareMode(false);
@@ -866,7 +895,7 @@ const ImportBomDetailTab: React.FC = () => {
</Paper>
)}
{detail && (
<Stack spacing={2} sx={{ pointerEvents: saving ? "none" : "auto" }}>
<Stack spacing={2} sx={{ pointerEvents: saving || exporting ? "none" : "auto" }}>
<Typography variant="subtitle1">
{detail.itemCode} {detail.itemName}
</Typography>
@@ -879,8 +908,10 @@ const ImportBomDetailTab: React.FC = () => {
compareMode={compareMode}
compareToId={compareToId}
saving={saving}
exporting={exporting}
versionsRefreshKey={versionsRefreshKey}
saveDisabled={effectiveSaveDisabled}
exportDisabled={typeof versionId !== "number"}
saveError={
blockedByUnresolvedMaterialIssue
? unresolvedMaterialIssueMessage
@@ -892,6 +923,7 @@ const ImportBomDetailTab: React.FC = () => {
}}
onToggleCompare={() => void handleToggleCompare()}
onCompareToChange={setCompareToId}
onExport={() => void handleExportExcel()}
onSave={() => void handleSave()}
/>
)}


+ 2
- 0
src/i18n/en/importBom.json Zobrazit soubor

@@ -42,6 +42,8 @@
"Download corrected excel": "Download corrected Excel",
"Downloading...": "Downloading…",
"Download corrected excel failed": "Failed to download corrected Excel",
"Export Excel": "Export Excel",
"Export excel failed": "Failed to export Excel",
"Confirm import": "Confirm import",
"Download issue log": "Download issue log Excel",
"Import completed": "Import completed",


+ 2
- 0
src/i18n/zh/importBom.json Zobrazit soubor

@@ -42,6 +42,8 @@
"Download corrected excel": "下載修正版 Excel",
"Downloading...": "下載中…",
"Download corrected excel failed": "下載修正版 Excel 失敗",
"Export Excel": "匯出 Excel",
"Export excel failed": "匯出 Excel 失敗",
"Confirm import": "確認匯入",
"Download issue log": "下載檢查結果 Excel",
"Import completed": "匯入完成",


Načítá se…
Zrušit
Uložit