Procházet zdrojové kódy

StockItemConsumptionTrendReport Excel Version

MergeProblem1
B.E.N.S.O.N před 1 dnem
rodič
revize
05eab73a5b
1 změnil soubory, kde provedl 74 přidání a 5 odebrání
  1. +74
    -5
      src/app/(main)/report/page.tsx

+ 74
- 5
src/app/(main)/report/page.tsx Zobrazit soubor

@@ -131,19 +131,26 @@ export default function ReportPage() {
setDynamicOptions({}); setDynamicOptions({});
}, [selectedReportId]); }, [selectedReportId]);


const handlePrint = async () => {
if (!currentReport) return;
const validateRequiredFields = () => {
if (!currentReport) return true;


// 1. Mandatory Field Validation
// Mandatory Field Validation
const missingFields = currentReport.fields const missingFields = currentReport.fields
.filter(field => field.required && !criteria[field.name]) .filter(field => field.required && !criteria[field.name])
.map(field => field.label); .map(field => field.label);


if (missingFields.length > 0) { if (missingFields.length > 0) {
alert(`缺少必填條件:\n- ${missingFields.join('\n- ')}`); alert(`缺少必填條件:\n- ${missingFields.join('\n- ')}`);
return;
return false;
} }


return true;
};

const handlePrint = async () => {
if (!currentReport) return;
if (!validateRequiredFields()) return;

// For rep-005, the print logic is handled by SemiFGProductionAnalysisReport component // For rep-005, the print logic is handled by SemiFGProductionAnalysisReport component
if (currentReport.id === 'rep-005') return; if (currentReport.id === 'rep-005') return;


@@ -156,12 +163,51 @@ export default function ReportPage() {
await executePrint(); await executePrint();
}; };


const handleExcelPrint = async () => {
if (!currentReport) return;
if (!validateRequiredFields()) return;
await executeExcelReport();
};

const executeExcelReport = async () => { const executeExcelReport = async () => {
if (!currentReport) return; if (!currentReport) return;
setLoading(true); setLoading(true);
try { try {
if (currentReport.id === 'rep-014') { if (currentReport.id === 'rep-014') {
await generateGrnReportExcel(criteria, currentReport.title); await generateGrnReportExcel(criteria, currentReport.title);
} else {
// Backend returns actual .xlsx bytes for this Excel endpoint.
const queryParams = new URLSearchParams(criteria).toString();
const excelUrl = `${currentReport.apiEndpoint}-excel?${queryParams}`;

const response = await clientAuthFetch(excelUrl, {
method: 'GET',
headers: { Accept: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' },
});

if (response.status === 401 || response.status === 403) return;
if (!response.ok) {
const errorText = await response.text();
console.error("Response error:", errorText);
throw new Error(`HTTP error! status: ${response.status}, message: ${errorText}`);
}

const blob = await response.blob();
const downloadUrl = window.URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = downloadUrl;

const contentDisposition = response.headers.get('Content-Disposition');
let fileName = `${currentReport.title}.xlsx`;
if (contentDisposition?.includes('filename=')) {
fileName = contentDisposition.split('filename=')[1].split(';')[0].replace(/"/g, '');
}

link.setAttribute('download', fileName);
document.body.appendChild(link);
link.click();
link.remove();
window.URL.revokeObjectURL(downloadUrl);
} }
setShowConfirmDialog(false); setShowConfirmDialog(false);
} catch (error) { } catch (error) {
@@ -438,7 +484,7 @@ export default function ReportPage() {
})} })}
</Grid> </Grid>


<Box sx={{ mt: 4, display: 'flex', justifyContent: 'flex-end' }}>
<Box sx={{ mt: 4, display: 'flex', gap: 2, justifyContent: 'flex-end' }}>
{currentReport.id === 'rep-005' ? ( {currentReport.id === 'rep-005' ? (
<SemiFGProductionAnalysisReport <SemiFGProductionAnalysisReport
criteria={criteria} criteria={criteria}
@@ -447,6 +493,29 @@ export default function ReportPage() {
setLoading={setLoading} setLoading={setLoading}
reportTitle={currentReport.title} reportTitle={currentReport.title}
/> />
) : currentReport.id === 'rep-006' ? (
<>
<Button
variant="contained"
size="large"
startIcon={<DownloadIcon />}
onClick={handlePrint}
disabled={loading}
sx={{ px: 4 }}
>
{loading ? "生成 PDF..." : "下載報告 (PDF)"}
</Button>
<Button
variant="outlined"
size="large"
startIcon={<DownloadIcon />}
onClick={handleExcelPrint}
disabled={loading}
sx={{ px: 4 }}
>
{loading ? "生成 Excel..." : "下載報告 (Excel)"}
</Button>
</>
) : currentReport.responseType === 'excel' ? ( ) : currentReport.responseType === 'excel' ? (
<Button <Button
variant="contained" variant="contained"


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