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 });
|
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 requestOrigin = getRequestOrigin(request);
|
||||||
const files = toDownloadItems((body as any)?.files, requestOrigin);
|
const files = toDownloadItems((body as any)?.files, requestOrigin);
|
||||||
const folderName = sanitizeFolderName(String((body as any)?.folderName || ""));
|
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() {
|
export function CanvasWorkspace() {
|
||||||
const containerRef = useRef<HTMLDivElement>(null);
|
const containerRef = useRef<HTMLDivElement>(null);
|
||||||
const [isPanning, setIsPanning] = useState(false);
|
const [isPanning, setIsPanning] = useState(false);
|
||||||
@ -563,51 +551,32 @@ export function CanvasWorkspace() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setIsDownloadSubmitting(true);
|
setIsDownloadSubmitting(true);
|
||||||
let timeoutId: number | null = null;
|
|
||||||
try {
|
try {
|
||||||
const controller = new AbortController();
|
const form = document.createElement("form");
|
||||||
timeoutId = window.setTimeout(() => controller.abort(), 120000);
|
form.method = "POST";
|
||||||
const response = await fetch("/api/canvas/download-zip", {
|
form.action = "/api/canvas/download-zip";
|
||||||
method: "POST",
|
form.style.display = "none";
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
const payloadInput = document.createElement("input");
|
||||||
},
|
payloadInput.type = "hidden";
|
||||||
signal: controller.signal,
|
payloadInput.name = "payload";
|
||||||
body: JSON.stringify({
|
payloadInput.value = JSON.stringify({
|
||||||
folderName,
|
folderName,
|
||||||
files,
|
files,
|
||||||
}),
|
|
||||||
});
|
});
|
||||||
|
form.appendChild(payloadInput);
|
||||||
|
|
||||||
if (!response.ok) {
|
document.body.appendChild(form);
|
||||||
const data = await response.json().catch(() => ({}));
|
form.submit();
|
||||||
toast.error(data?.error || "打包失败,请稍后重试");
|
form.remove();
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const zipBlob = await response.blob();
|
toast.success("已开始打包下载,请留意浏览器下载栏");
|
||||||
downloadBlob(zipBlob, `${folderName}.zip`);
|
} catch (_error) {
|
||||||
|
toast.error("下载失败,请稍后重试");
|
||||||
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("下载失败,请稍后重试");
|
|
||||||
}
|
|
||||||
} finally {
|
} finally {
|
||||||
if (timeoutId) {
|
window.setTimeout(() => {
|
||||||
window.clearTimeout(timeoutId);
|
setIsDownloadSubmitting(false);
|
||||||
}
|
}, 800);
|
||||||
setIsDownloadSubmitting(false);
|
|
||||||
}
|
}
|
||||||
}, [isDownloadSubmitting, selectedImageNodes]);
|
}, [isDownloadSubmitting, selectedImageNodes]);
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user