feat(admin-web): 批量下载支持选择保存路径
使用 File System Access API 让管理员可以选择文件保存位置, 而不是自动下载到默认目录。 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
8b7872d205
commit
f97eacdc70
|
|
@ -167,6 +167,38 @@ export default function ContractsPage() {
|
||||||
throw new Error('任务处理超时');
|
throw new Error('任务处理超时');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 使用 File System Access API 让用户选择保存位置(Chrome/Edge 支持)
|
||||||
|
const saveFileWithPicker = async (url: string, suggestedName: string): Promise<boolean> => {
|
||||||
|
try {
|
||||||
|
// 检查浏览器是否支持 File System Access API
|
||||||
|
if ('showSaveFilePicker' in window) {
|
||||||
|
// 先下载文件内容
|
||||||
|
const response = await fetch(url);
|
||||||
|
const blob = await response.blob();
|
||||||
|
|
||||||
|
// 弹出保存对话框让用户选择位置
|
||||||
|
const fileHandle = await (window as unknown as { showSaveFilePicker: (options: unknown) => Promise<FileSystemFileHandle> }).showSaveFilePicker({
|
||||||
|
suggestedName,
|
||||||
|
types: [{
|
||||||
|
description: 'ZIP 压缩文件',
|
||||||
|
accept: { 'application/zip': ['.zip'] },
|
||||||
|
}],
|
||||||
|
});
|
||||||
|
|
||||||
|
// 写入文件
|
||||||
|
const writable = await fileHandle.createWritable();
|
||||||
|
await writable.write(blob);
|
||||||
|
await writable.close();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
// 用户取消或浏览器不支持,回退到普通下载
|
||||||
|
console.log('File System Access API 不可用或用户取消,使用普通下载');
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
// 批量下载(创建下载任务并等待完成后自动下载)
|
// 批量下载(创建下载任务并等待完成后自动下载)
|
||||||
const handleBatchDownload = async () => {
|
const handleBatchDownload = async () => {
|
||||||
setBatchDownloading(true);
|
setBatchDownloading(true);
|
||||||
|
|
@ -188,14 +220,26 @@ export default function ContractsPage() {
|
||||||
const downloadUrl = await pollTaskUntilComplete(result.taskNo);
|
const downloadUrl = await pollTaskUntilComplete(result.taskNo);
|
||||||
|
|
||||||
if (downloadUrl) {
|
if (downloadUrl) {
|
||||||
// 创建隐藏的 a 标签触发浏览器下载(会弹出另存为对话框)
|
// 生成文件名
|
||||||
const link = document.createElement('a');
|
const today = new Date().toISOString().split('T')[0].replace(/-/g, '');
|
||||||
link.href = downloadUrl;
|
const suggestedName = `contracts_${today}.zip`;
|
||||||
link.download = ''; // 设置 download 属性触发下载
|
|
||||||
document.body.appendChild(link);
|
// 优先使用 File System Access API 让用户选择保存位置
|
||||||
link.click();
|
toast.info('请选择保存位置...');
|
||||||
document.body.removeChild(link);
|
const saved = await saveFileWithPicker(downloadUrl, suggestedName);
|
||||||
toast.success('请选择保存位置');
|
|
||||||
|
if (saved) {
|
||||||
|
toast.success('文件保存成功!');
|
||||||
|
} else {
|
||||||
|
// 浏览器不支持或用户取消,使用备用方法
|
||||||
|
const link = document.createElement('a');
|
||||||
|
link.href = downloadUrl;
|
||||||
|
link.download = suggestedName;
|
||||||
|
document.body.appendChild(link);
|
||||||
|
link.click();
|
||||||
|
document.body.removeChild(link);
|
||||||
|
toast.success('下载已开始');
|
||||||
|
}
|
||||||
|
|
||||||
// 保存当前时间作为最后下载时间
|
// 保存当前时间作为最后下载时间
|
||||||
const now = new Date().toISOString();
|
const now = new Date().toISOString();
|
||||||
|
|
@ -236,14 +280,26 @@ export default function ContractsPage() {
|
||||||
const downloadUrl = await pollTaskUntilComplete(result.taskNo);
|
const downloadUrl = await pollTaskUntilComplete(result.taskNo);
|
||||||
|
|
||||||
if (downloadUrl) {
|
if (downloadUrl) {
|
||||||
// 创建隐藏的 a 标签触发浏览器下载(会弹出另存为对话框)
|
// 生成文件名
|
||||||
const link = document.createElement('a');
|
const today = new Date().toISOString().split('T')[0].replace(/-/g, '');
|
||||||
link.href = downloadUrl;
|
const suggestedName = `contracts_incremental_${today}.zip`;
|
||||||
link.download = ''; // 设置 download 属性触发下载
|
|
||||||
document.body.appendChild(link);
|
// 优先使用 File System Access API 让用户选择保存位置
|
||||||
link.click();
|
toast.info('请选择保存位置...');
|
||||||
document.body.removeChild(link);
|
const saved = await saveFileWithPicker(downloadUrl, suggestedName);
|
||||||
toast.success('请选择保存位置');
|
|
||||||
|
if (saved) {
|
||||||
|
toast.success('文件保存成功!');
|
||||||
|
} else {
|
||||||
|
// 浏览器不支持或用户取消,使用备用方法
|
||||||
|
const link = document.createElement('a');
|
||||||
|
link.href = downloadUrl;
|
||||||
|
link.download = suggestedName;
|
||||||
|
document.body.appendChild(link);
|
||||||
|
link.click();
|
||||||
|
document.body.removeChild(link);
|
||||||
|
toast.success('下载已开始');
|
||||||
|
}
|
||||||
|
|
||||||
// 更新最后下载时间
|
// 更新最后下载时间
|
||||||
const now = new Date().toISOString();
|
const now = new Date().toISOString();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue