This commit is contained in:
owenchen committed 2026-10-14 21:23:40 +08:00
1 parent e740ec77ec
commit ceb3e7beec
20 files changed
+2280 -138

No files matched your search

+31 -11
View File
@@ -466,11 +466,16 @@ function timestamp(): string {
}
/**
* 下载并打开文件(默认按 Excel 处理)
* 关键防御:先探测 content-type——后端报错时返回的是 JSON 而不是文件
* 裸 arraybuffer 请求(旁路通道):文件下载/分片取回/预览字节等面向字节的场景共用。
* 关键防御与 downloadFile 同源——后端报错时回的是 JSON 而不是文件,
* 按 content-type 探测后转成错误文案抛出(业务异常不再当字节流落盘)
*/
export async function downloadFile(options: DownloadOptions): Promise<void> {
const { url, method = "POST", data, filename, extension = "xlsx" } = options;
export async function requestBuffer(options: {
url: string;
method?: "GET" | "POST";
data?: any;
}): Promise<ArrayBuffer> {
const { url, method = "POST", data } = options;
const fullUrl = url.indexOf("http") === 0 ? url : baseUrl + url;
const auth = bearerAuth();
@@ -493,7 +498,7 @@ export async function downloadFile(options: DownloadOptions): Promise<void> {
const contentType = String(
header["content-type"] || header.Content_Type || header.ContentType || "",
);
if (contentType.includes("application/json")) {
if (contentType.includes("json")) {
const text
= typeof res.data === "string"
? res.data
@@ -513,19 +518,24 @@ export async function downloadFile(options: DownloadOptions): Promise<void> {
notifyError("", message);
throw markErrorNotified(new Error(message));
}
return res.data as ArrayBuffer;
}
const fileName = `${filename}${timestamp()}.${extension}`;
/** 字节按指定文件名落盘:H5 走 blob+<a>;小程序/App 写本地目录后调起系统文档预览 */
export async function saveArrayBuffer(bytes: ArrayBuffer, fileName: string): Promise<void> {
// #ifdef H5
// H5:blob + 隐藏 <a> 触发浏览器下载
const downloadUrl = URL.createObjectURL(new Blob([res.data as ArrayBuffer]));
const downloadUrl = URL.createObjectURL(new Blob([bytes]));
const link = document.createElement("a");
link.href = downloadUrl;
link.download = fileName;
document.body.appendChild(link);
link.click();
link.remove();
URL.revokeObjectURL(downloadUrl);
// 浏览器读 blob 是异步任务:click 后立即 revoke 会让下载列表现「Failed - No file」,延迟释放
setTimeout(() => {
link.remove();
URL.revokeObjectURL(downloadUrl);
}, 3000);
// #endif
// #ifndef H5
@@ -544,7 +554,7 @@ export async function downloadFile(options: DownloadOptions): Promise<void> {
await new Promise<void>((resolve, reject) => {
fs.writeFile({
filePath,
data: res.data as ArrayBuffer,
data: bytes,
success: () => resolve(),
fail: (err: any) => reject(new Error(err.errMsg || "写入文件失败")),
});
@@ -560,5 +570,15 @@ export async function downloadFile(options: DownloadOptions): Promise<void> {
// #endif
}
/**
* 下载并打开文件(默认按 Excel 处理):请求与落盘两段均已抽为公用函数,
* 文件页的下载动作直接复用 requestBuffer + saveArrayBuffer
*/
export async function downloadFile(options: DownloadOptions): Promise<void> {
const { url, method = "POST", data, filename, extension = "xlsx" } = options;
const bytes = await requestBuffer({ url, method, data });
await saveArrayBuffer(bytes, `${filename}${timestamp()}.${extension}`);
}
// 导出(main.ts httpPlugin 注册用)
export { httpInterceptor, httpRequestConfig };