64 lines
2.0 KiB
TypeScript
64 lines
2.0 KiB
TypeScript
/**
|
|
* 带鉴权下载二进制文件(Excel 等)。
|
|
* 为何:window.open 带 token 遇 JSON 错误页难提示;统一走 fetch + blob。
|
|
*/
|
|
import { useGlobSetting } from '/@/hooks/setting';
|
|
import { getToken } from '/@/utils/auth';
|
|
|
|
export type AuthDownloadParams = Record<string, string | number | undefined | null>;
|
|
|
|
/**
|
|
* GET 下载附件并触发浏览器保存。
|
|
* @param path 相对 API 路径,如 /inquiry/workOrder/view/export
|
|
* @param params query 参数(空值跳过)
|
|
* @param fallbackName 无 Content-Disposition 时的文件名
|
|
*/
|
|
export async function downloadAuthGet(
|
|
path: string,
|
|
params: AuthDownloadParams = {},
|
|
fallbackName = 'download.bin',
|
|
): Promise<void> {
|
|
const glob = useGlobSetting();
|
|
const base = (glob.apiUrl || '').replace(/\/$/, '');
|
|
const qs = new URLSearchParams();
|
|
Object.keys(params).forEach((k) => {
|
|
const v = params[k];
|
|
if (v === undefined || v === null || String(v).trim() === '') return;
|
|
qs.set(k, String(v));
|
|
});
|
|
const url = `${base}${path}${qs.toString() ? `?${qs.toString()}` : ''}`;
|
|
const token = getToken() || '';
|
|
const res = await fetch(url, {
|
|
method: 'GET',
|
|
headers: {
|
|
'X-Access-Token': String(token),
|
|
},
|
|
});
|
|
const ctype = (res.headers.get('content-type') || '').toLowerCase();
|
|
if (!res.ok || ctype.includes('application/json')) {
|
|
let msg = `下载失败 HTTP ${res.status}`;
|
|
try {
|
|
const j = await res.json();
|
|
if (j?.message) msg = String(j.message);
|
|
} catch {
|
|
/* ignore */
|
|
}
|
|
throw new Error(msg);
|
|
}
|
|
const blob = await res.blob();
|
|
let name = fallbackName;
|
|
const cd = res.headers.get('content-disposition') || '';
|
|
const m = /filename\*=UTF-8''([^;]+)|filename=\"?([^\";]+)\"?/i.exec(cd);
|
|
if (m) {
|
|
name = decodeURIComponent((m[1] || m[2] || name).trim());
|
|
}
|
|
const href = URL.createObjectURL(blob);
|
|
const a = document.createElement('a');
|
|
a.href = href;
|
|
a.download = name;
|
|
document.body.appendChild(a);
|
|
a.click();
|
|
a.remove();
|
|
URL.revokeObjectURL(href);
|
|
}
|