fix(admin-web): 批量下载完成后直接触发浏览器另存为对话框
- 创建任务后自动轮询等待完成 - 完成后使用 <a download> 触发浏览器下载对话框 - 按钮显示打包进度 - 打包期间禁用按钮防止重复点击 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
15019206c8
commit
8b7872d205
|
|
@ -139,9 +139,42 @@ export default function ContractsPage() {
|
|||
window.open(downloadUrl, '_blank');
|
||||
};
|
||||
|
||||
// 批量下载(创建下载任务)
|
||||
// 批量下载状态
|
||||
const [batchDownloading, setBatchDownloading] = useState(false);
|
||||
const [batchProgress, setBatchProgress] = useState(0);
|
||||
|
||||
// 轮询任务状态直到完成
|
||||
const pollTaskUntilComplete = async (taskNo: string): Promise<string | null> => {
|
||||
const maxAttempts = 120; // 最多轮询2分钟
|
||||
for (let i = 0; i < maxAttempts; i++) {
|
||||
try {
|
||||
const status = await contractService.getBatchDownloadStatus(taskNo);
|
||||
setBatchProgress(status.progress);
|
||||
|
||||
if (status.status === 'COMPLETED' && status.resultFileUrl) {
|
||||
return status.resultFileUrl;
|
||||
} else if (status.status === 'FAILED') {
|
||||
throw new Error('任务处理失败');
|
||||
}
|
||||
|
||||
// 等待1秒后继续轮询
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
} catch (error) {
|
||||
console.error('查询任务状态失败:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
throw new Error('任务处理超时');
|
||||
};
|
||||
|
||||
// 批量下载(创建下载任务并等待完成后自动下载)
|
||||
const handleBatchDownload = async () => {
|
||||
setBatchDownloading(true);
|
||||
setBatchProgress(0);
|
||||
|
||||
try {
|
||||
toast.info('正在准备批量下载,请稍候...');
|
||||
|
||||
const result = await contractService.createBatchDownload({
|
||||
filters: {
|
||||
signedAfter: filters.signedAfter || undefined,
|
||||
|
|
@ -151,15 +184,30 @@ export default function ContractsPage() {
|
|||
},
|
||||
});
|
||||
|
||||
toast.success(`批量下载任务已创建,任务号: ${result.taskNo}`);
|
||||
// 轮询等待任务完成
|
||||
const downloadUrl = await pollTaskUntilComplete(result.taskNo);
|
||||
|
||||
// 保存当前时间作为最后下载时间
|
||||
const now = new Date().toISOString();
|
||||
localStorage.setItem('contract_last_download_time', now);
|
||||
setLastDownloadTime(now);
|
||||
if (downloadUrl) {
|
||||
// 创建隐藏的 a 标签触发浏览器下载(会弹出另存为对话框)
|
||||
const link = document.createElement('a');
|
||||
link.href = downloadUrl;
|
||||
link.download = ''; // 设置 download 属性触发下载
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
toast.success('请选择保存位置');
|
||||
|
||||
// 保存当前时间作为最后下载时间
|
||||
const now = new Date().toISOString();
|
||||
localStorage.setItem('contract_last_download_time', now);
|
||||
setLastDownloadTime(now);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('创建批量下载任务失败:', error);
|
||||
toast.error('创建批量下载任务失败');
|
||||
console.error('批量下载失败:', error);
|
||||
toast.error('批量下载失败,请重试');
|
||||
} finally {
|
||||
setBatchDownloading(false);
|
||||
setBatchProgress(0);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -170,7 +218,12 @@ export default function ContractsPage() {
|
|||
return;
|
||||
}
|
||||
|
||||
setBatchDownloading(true);
|
||||
setBatchProgress(0);
|
||||
|
||||
try {
|
||||
toast.info('正在准备增量下载,请稍候...');
|
||||
|
||||
const result = await contractService.createBatchDownload({
|
||||
filters: {
|
||||
signedAfter: lastDownloadTime,
|
||||
|
|
@ -179,15 +232,30 @@ export default function ContractsPage() {
|
|||
},
|
||||
});
|
||||
|
||||
toast.success(`增量下载任务已创建,任务号: ${result.taskNo}`);
|
||||
// 轮询等待任务完成
|
||||
const downloadUrl = await pollTaskUntilComplete(result.taskNo);
|
||||
|
||||
// 更新最后下载时间
|
||||
const now = new Date().toISOString();
|
||||
localStorage.setItem('contract_last_download_time', now);
|
||||
setLastDownloadTime(now);
|
||||
if (downloadUrl) {
|
||||
// 创建隐藏的 a 标签触发浏览器下载(会弹出另存为对话框)
|
||||
const link = document.createElement('a');
|
||||
link.href = downloadUrl;
|
||||
link.download = ''; // 设置 download 属性触发下载
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
toast.success('请选择保存位置');
|
||||
|
||||
// 更新最后下载时间
|
||||
const now = new Date().toISOString();
|
||||
localStorage.setItem('contract_last_download_time', now);
|
||||
setLastDownloadTime(now);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('创建增量下载任务失败:', error);
|
||||
toast.error('创建增量下载任务失败');
|
||||
console.error('增量下载失败:', error);
|
||||
toast.error('增量下载失败,请重试');
|
||||
} finally {
|
||||
setBatchDownloading(false);
|
||||
setBatchProgress(0);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -295,11 +363,11 @@ export default function ContractsPage() {
|
|||
</div>
|
||||
|
||||
<div className={styles.contracts__actions}>
|
||||
<Button variant="primary" onClick={handleBatchDownload}>
|
||||
批量下载 ZIP
|
||||
<Button variant="primary" onClick={handleBatchDownload} disabled={batchDownloading}>
|
||||
{batchDownloading ? `打包中 ${batchProgress}%...` : '批量下载 ZIP'}
|
||||
</Button>
|
||||
{lastDownloadTime && (
|
||||
<Button variant="outline" onClick={handleIncrementalDownload}>
|
||||
<Button variant="outline" onClick={handleIncrementalDownload} disabled={batchDownloading}>
|
||||
增量下载(上次: {new Date(lastDownloadTime).toLocaleString('zh-CN')})
|
||||
</Button>
|
||||
)}
|
||||
|
|
|
|||
Loading…
Reference in New Issue