infly-libs
Version:
工具组件库
143 lines (128 loc) • 4.56 kB
JavaScript
/**
* 统一文件导出函数
* @param {Object} config - 配置对象
* @param {string} config.url - 请求文件的 URL
* @param {string} config.fileName - 导出文件的基础名称
* @param {Object} [config.params={}] - 请求参数
* @param {string} [config.suffix=".csv"] - 文件后缀名
* @param {Object} config.request - 请求封装实例 (如 axios 实例)
* @param {string} [config.reqMethod="get"] - 请求方法 ('get' 或 'post')
* @param {Object} [config.Message={}] - Element UI Message 组件实例
* @param {Object} [config.MessageBox={}] - Element UI MessageBox 组件实例
* @param {Object} [config.Loading={}] - Element UI Loading 组件实例
*/
async function exportFile(config) {
// 1. 参数解构与默认值,并进行基本校验
const {
url,
fileName,
params = {},
suffix = ".csv",
request,
reqMethod = "get",
Message = {},
MessageBox = {},
Loading = {}
} = config || {};
if (!url || !request) {
console.error("exportFile: 缺少必要的参数 (url, fileName, request)");
return;
}
let loadingInstance = null;
// 辅助函数:显示消息
const showMessage = (type, msg) => {
if (Message && Uts.isFunction(Message[type])) {
Message[type](msg);
}
};
// 辅助函数:显示加载
const showLoading = () => {
if (Loading && Uts.isFunction(Loading.service)) {
loadingInstance = Loading.service({
text: "文件正在下载中,请等候...",
spinner: "el-icon-loading",
background: "rgba(0, 0, 0, 0.7)"
});
}
};
// 辅助函数:隐藏加载
const hideLoading = () => {
if (loadingInstance && Uts.isFunction(loadingInstance.close)) {
loadingInstance.close();
}
};
// 辅助函数:处理文件下载
const handleDownload = (blob, fullFileName) => {
if ("download" in document.createElement("a")) {
const elink = document.createElement("a");
elink.style.display = "none";
elink.href = URL.createObjectURL(blob);
elink.download = fullFileName;
document.body.appendChild(elink);
elink.click();
URL.revokeObjectURL(elink.href);
document.body.removeChild(elink);
} else {
// IE10+下载
navigator.msSaveBlob(blob, fullFileName);
}
};
try {
// 2. 确认框
if (MessageBox && Uts.isFunction(MessageBox.confirm)) {
await MessageBox.confirm("导出筛选后的所有文件, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
});
}
showLoading(); // 显示加载
try {
// 3. 请求文件流
const requestConfig = {
responseType: "arraybuffer",
timeout: 0
};
let res;
if (reqMethod === "get") {
res = await request.get(url, { ...params, ...requestConfig });
} else if (reqMethod === "post") {
res = await request.post(url, params, requestConfig);
} else {
console.warn(`exportFile: 不支持的请求方法 '${reqMethod}'`);
showMessage("error", "导出失败:不支持的请求方法!");
return;
}
const blob = new Blob([res], { type: "application/octet-stream" });
const fullFileName = `${fileName}_${new Date().toISOString().slice(0, 10)}${suffix}`;
handleDownload(blob, fullFileName); // 处理文件下载
showMessage("success", "文件导出成功!");
} catch (err) {
console.error("导出错误:", err);
const { response } = err || {};
const { status, statusText } = response || {};
if (status === 403 || statusText === "Forbidden") {
showMessage("error", "无操作权限!");
} else if (status === 404) {
showMessage("error", "导出地址未找到!");
} else if (err.message && err.message.includes("timeout")) {
showMessage("error", "导出超时,请稍后再试!");
} else {
showMessage("error", "导出异常,请稍后再试!");
}
} finally {
hideLoading(); // 隐藏加载
}
} catch (err) {
// 捕获 MessageBox.confirm 的取消操作
if (err === "cancel") {
showMessage("info", "已取消导出");
} else {
console.error("导出流程中断:", err);
showMessage("error", "导出流程异常中断!");
}
}
}
export {
exportFile
};