接口联调
This commit is contained in:
1 parent
43df9175df
commit
8673eb5eca
148 files changed
+2050
-37963
No files matched your search
@@ -0,0 +1,69 @@
|
||||
import { apiFetch } from "@/core/api/fetch-client";
|
||||
import { getBackendBaseURL } from "@/core/config";
|
||||
|
||||
function filenameFromContentDisposition(header: string | null): string | null {
|
||||
if (!header) return null;
|
||||
const star = /filename\*=(?:UTF-8'')?([^;]+)/i.exec(header);
|
||||
if (star) {
|
||||
const raw = star[1].replace(/["']/g, "").trim();
|
||||
try {
|
||||
return decodeURIComponent(raw);
|
||||
} catch {
|
||||
return raw;
|
||||
}
|
||||
}
|
||||
const plain = /filename="?([^";\n]+)"?/i.exec(header);
|
||||
return plain ? plain[1].trim() : null;
|
||||
}
|
||||
|
||||
function sanitizeFallbackFilename(title: string | undefined): string {
|
||||
const base = (title?.trim() || "document").replace(/[<>:"/\\|?*\x00-\x1f]+/g, "_");
|
||||
return base.toLowerCase().endsWith(".docx") ? base : `${base}.docx`;
|
||||
}
|
||||
|
||||
async function downloadBlobResponse(response: Response, fallbackFilename: string) {
|
||||
if (!response.ok) {
|
||||
const error = await response
|
||||
.json()
|
||||
.catch(() => ({ detail: "导出 Word 失败" }));
|
||||
const detail = error.detail;
|
||||
if (typeof detail === "string") throw new Error(detail);
|
||||
throw new Error("导出 Word 失败");
|
||||
}
|
||||
|
||||
const blob = await response.blob();
|
||||
const filename =
|
||||
filenameFromContentDisposition(response.headers.get("Content-Disposition")) ??
|
||||
fallbackFilename;
|
||||
const url = URL.createObjectURL(blob);
|
||||
const anchor = document.createElement("a");
|
||||
anchor.href = url;
|
||||
anchor.download = filename;
|
||||
anchor.rel = "noopener";
|
||||
document.body.appendChild(anchor);
|
||||
anchor.click();
|
||||
anchor.remove();
|
||||
window.setTimeout(() => URL.revokeObjectURL(url), 30_000);
|
||||
}
|
||||
|
||||
/** 调用后端导出 AI 写作草稿为 Word,仅传正文 markdown,不传目录/大纲。 */
|
||||
export async function downloadAIWritingDocx(options: {
|
||||
title?: string;
|
||||
draftMarkdown: string;
|
||||
}): Promise<void> {
|
||||
const draftMarkdown = options.draftMarkdown.trim();
|
||||
if (!draftMarkdown) {
|
||||
throw new Error("文档内容为空");
|
||||
}
|
||||
|
||||
const response = await apiFetch(`${getBackendBaseURL()}/api/ai-writing/export/docx`, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
title: options.title?.trim() || undefined,
|
||||
draft_markdown: draftMarkdown,
|
||||
}),
|
||||
});
|
||||
|
||||
await downloadBlobResponse(response, sanitizeFallbackFilename(options.title));
|
||||
}
|
||||
Reference in new issue
Block a user