From cd1d16fc7f9f6ca964141a6eb7edfc96b9298e2f Mon Sep 17 00:00:00 2001 From: hailin Date: Fri, 6 Feb 2026 00:22:04 -0800 Subject: [PATCH] =?UTF-8?q?feat(admin-web):=20=E6=89=B9=E9=87=8F=E4=B8=8B?= =?UTF-8?q?=E8=BD=BD=E6=94=AF=E6=8C=81=E6=96=AD=E7=82=B9=E7=BB=AD=E4=BC=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 下载前检查文件是否已存在 - 已存在的文件自动跳过 - 显示跳过数量和新下载数量 Co-Authored-By: Claude Opus 4.5 --- .../src/app/(dashboard)/contracts/page.tsx | 44 +++++++++++++++++-- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/frontend/admin-web/src/app/(dashboard)/contracts/page.tsx b/frontend/admin-web/src/app/(dashboard)/contracts/page.tsx index 48eb043d..80dadf96 100644 --- a/frontend/admin-web/src/app/(dashboard)/contracts/page.tsx +++ b/frontend/admin-web/src/app/(dashboard)/contracts/page.tsx @@ -224,13 +224,27 @@ export default function ContractsPage() { toast.info(`开始下载 ${total} 份合同...`); - // 第三步:逐个下载合同到用户选择的目录 + // 第三步:逐个下载合同到用户选择的目录(支持断点续传) let downloaded = 0; + let skipped = 0; for (const contract of contracts) { try { // 生成文件名 const fileName = `${contract.contractNo}_${contract.userRealName || '未实名'}_${contract.treeCount}棵.pdf`; + // 检查文件是否已存在(断点续传) + try { + await dirHandle.getFileHandle(fileName, { create: false }); + // 文件已存在,跳过 + skipped++; + downloaded++; + setDownloadedCount(downloaded); + setDownloadProgress(Math.round((downloaded / total) * 100)); + continue; + } catch { + // 文件不存在,继续下载 + } + // 下载 PDF const downloadUrl = contractService.getDownloadUrl(contract.orderNo); const response = await fetch(downloadUrl); @@ -255,7 +269,11 @@ export default function ContractsPage() { } } - toast.success(`下载完成!成功 ${downloaded}/${total} 份`); + if (skipped > 0) { + toast.success(`下载完成!新下载 ${downloaded - skipped} 份,跳过已存在 ${skipped} 份`); + } else { + toast.success(`下载完成!成功 ${downloaded}/${total} 份`); + } // 保存当前时间作为最后下载时间 const now = new Date().toISOString(); @@ -327,11 +345,25 @@ export default function ContractsPage() { toast.info(`开始下载 ${total} 份新增合同...`); - // 第三步:逐个下载合同 + // 第三步:逐个下载合同(支持断点续传) let downloaded = 0; + let skipped = 0; for (const contract of contracts) { try { const fileName = `${contract.contractNo}_${contract.userRealName || '未实名'}_${contract.treeCount}棵.pdf`; + + // 检查文件是否已存在(断点续传) + try { + await dirHandle.getFileHandle(fileName, { create: false }); + skipped++; + downloaded++; + setDownloadedCount(downloaded); + setDownloadProgress(Math.round((downloaded / total) * 100)); + continue; + } catch { + // 文件不存在,继续下载 + } + const downloadUrl = contractService.getDownloadUrl(contract.orderNo); const response = await fetch(downloadUrl); if (!response.ok) continue; @@ -350,7 +382,11 @@ export default function ContractsPage() { } } - toast.success(`下载完成!成功 ${downloaded}/${total} 份`); + if (skipped > 0) { + toast.success(`下载完成!新下载 ${downloaded - skipped} 份,跳过已存在 ${skipped} 份`); + } else { + toast.success(`下载完成!成功 ${downloaded}/${total} 份`); + } // 更新最后下载时间 const now = new Date().toISOString();