fix: switch canvas zip download to native form submission
This commit is contained in:
parent
e344a6db73
commit
056514f167
@ -103,7 +103,21 @@ export async function POST(request: NextRequest) {
|
||||
return NextResponse.json({ success: false, error: "未登录" }, { status: 401 });
|
||||
}
|
||||
|
||||
const body = await request.json().catch(() => ({}));
|
||||
let body: Record<string, unknown> = {};
|
||||
const contentType = request.headers.get("content-type") || "";
|
||||
if (contentType.includes("application/json")) {
|
||||
body = (await request.json().catch(() => ({}))) as Record<string, unknown>;
|
||||
} else {
|
||||
const formData = await request.formData().catch(() => null);
|
||||
const payload = formData?.get("payload");
|
||||
if (typeof payload === "string" && payload.trim()) {
|
||||
try {
|
||||
body = (JSON.parse(payload) as Record<string, unknown>) || {};
|
||||
} catch (_error) {
|
||||
body = {};
|
||||
}
|
||||
}
|
||||
}
|
||||
const requestOrigin = getRequestOrigin(request);
|
||||
const files = toDownloadItems((body as any)?.files, requestOrigin);
|
||||
const folderName = sanitizeFolderName(String((body as any)?.folderName || ""));
|
||||
|
||||
@ -36,18 +36,6 @@ function isNodeInViewport(
|
||||
);
|
||||
}
|
||||
|
||||
function downloadBlob(blob: Blob, filename: string): void {
|
||||
const link = document.createElement("a");
|
||||
const objectUrl = URL.createObjectURL(blob);
|
||||
link.href = objectUrl;
|
||||
link.download = filename;
|
||||
link.rel = "noopener noreferrer";
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
link.remove();
|
||||
window.setTimeout(() => URL.revokeObjectURL(objectUrl), 1500);
|
||||
}
|
||||
|
||||
export function CanvasWorkspace() {
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
const [isPanning, setIsPanning] = useState(false);
|
||||
@ -563,51 +551,32 @@ export function CanvasWorkspace() {
|
||||
}
|
||||
|
||||
setIsDownloadSubmitting(true);
|
||||
let timeoutId: number | null = null;
|
||||
try {
|
||||
const controller = new AbortController();
|
||||
timeoutId = window.setTimeout(() => controller.abort(), 120000);
|
||||
const response = await fetch("/api/canvas/download-zip", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
signal: controller.signal,
|
||||
body: JSON.stringify({
|
||||
folderName,
|
||||
files,
|
||||
}),
|
||||
const form = document.createElement("form");
|
||||
form.method = "POST";
|
||||
form.action = "/api/canvas/download-zip";
|
||||
form.style.display = "none";
|
||||
|
||||
const payloadInput = document.createElement("input");
|
||||
payloadInput.type = "hidden";
|
||||
payloadInput.name = "payload";
|
||||
payloadInput.value = JSON.stringify({
|
||||
folderName,
|
||||
files,
|
||||
});
|
||||
form.appendChild(payloadInput);
|
||||
|
||||
if (!response.ok) {
|
||||
const data = await response.json().catch(() => ({}));
|
||||
toast.error(data?.error || "打包失败,请稍后重试");
|
||||
return;
|
||||
}
|
||||
document.body.appendChild(form);
|
||||
form.submit();
|
||||
form.remove();
|
||||
|
||||
const zipBlob = await response.blob();
|
||||
downloadBlob(zipBlob, `${folderName}.zip`);
|
||||
|
||||
const successCount = Number(response.headers.get("X-Download-Success-Count") || "0");
|
||||
const failedCount = Number(response.headers.get("X-Download-Failed-Count") || "0");
|
||||
const totalCount = files.length;
|
||||
|
||||
if (failedCount > 0) {
|
||||
toast.warning(`已打包 ${successCount} 张,失败 ${failedCount} 张`);
|
||||
} else {
|
||||
toast.success(`已下载压缩包,包含 ${successCount || totalCount} 张图片`);
|
||||
}
|
||||
} catch (error) {
|
||||
if (error instanceof DOMException && error.name === "AbortError") {
|
||||
toast.error("打包超时,请减少图片数量后重试");
|
||||
} else {
|
||||
toast.error("下载失败,请稍后重试");
|
||||
}
|
||||
toast.success("已开始打包下载,请留意浏览器下载栏");
|
||||
} catch (_error) {
|
||||
toast.error("下载失败,请稍后重试");
|
||||
} finally {
|
||||
if (timeoutId) {
|
||||
window.clearTimeout(timeoutId);
|
||||
}
|
||||
setIsDownloadSubmitting(false);
|
||||
window.setTimeout(() => {
|
||||
setIsDownloadSubmitting(false);
|
||||
}, 800);
|
||||
}
|
||||
}, [isDownloadSubmitting, selectedImageNodes]);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user