cashier_app/utils/downloadFile.js

200 lines
6.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 多端兼容文件保存基于已下载的临时路径无需重复download
* 核心传入的url是uni.downloadFile返回的tempFilePath直接用fs.saveFile保存
* @param {string} tempFilePath - 已下载的文件临时路径必填来自downloadFile返回值
* @param {string} [fileName] - 自定义保存文件名(可选,默认从临时路径提取)
* @returns {Promise<void>} - 保存结果Promise
*/
export function saveFileFromTemp(args) {
const {tempFilePath, fileName,isNowOpen=false}=args
// 前置校验:临时路径必填
if (!tempFilePath) {
uni.showToast({ title: "文件临时路径不能为空", icon: "none" });
return Promise.reject(new Error("临时路径不能为空"));
}
// 共用逻辑:从临时路径/URL提取默认文件名适配各端临时路径格式
const getDefaultFileName = () => {
let name = `文件_${Date.now()}`;
try {
// 处理微信小程序临时路径wxfile://tmp/xxx.pdf
if (
tempFilePath.includes("wxfile://") ||
tempFilePath.includes("/tmp/")
) {
const lastSlashIndex = tempFilePath.lastIndexOf("/");
if (lastSlashIndex !== -1) {
name = tempFilePath.slice(lastSlashIndex + 1);
}
}
// 处理App临时路径_doc/tmp/xxx.png或普通URL
else {
const urlObj = new URL(tempFilePath, window.location.origin); // 兼容相对路径
const pathname = urlObj.pathname;
const lastSlashIndex = pathname.lastIndexOf("/");
if (lastSlashIndex !== -1) {
name = pathname.slice(lastSlashIndex + 1).split("?")[0];
}
}
// 补充文件后缀(如果没有)
if (!name.includes(".")) {
name += ".bin"; // 兜底后缀,可根据实际业务调整(如:.pdf/.png
}
} catch (e) {
name = `文件_${Date.now()}.bin`;
}
return fileName || name;
};
const targetFileName = getDefaultFileName();
// -------------------------- H5端处理临时路径直接触发下载 --------------------------
// #ifdef H5
return new Promise((resolve, reject) => {
// H5的临时路径可能是blob:xxx格式直接用a标签下载
const link = document.createElement("a");
link.href = tempFilePath;
link.download = targetFileName;
link.target = "_blank";
link.style.display = "none";
link.addEventListener("error", () => {
uni.showToast({
title: "保存失败H5临时路径无效或跨域",
icon: "none",
duration: 3000,
});
reject(new Error("H5临时路径保存失败"));
});
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
uni.showToast({ title: "保存成功,请查看浏览器下载列表", icon: "none" });
resolve();
});
// #endif
// -------------------------- 微信小程序端处理fs.saveFile 保存临时路径) --------------------------
// #ifdef MP-WEIXIN
return new Promise((resolve, reject) => {
const fs = uni.getFileSystemManager();
// 微信小程序保存路径(沙箱目录)
const saveFilePath = `${wx.env.USER_DATA_PATH}/${targetFileName}`;
// 直接保存临时路径(无需下载)
fs.saveFile({
tempFilePath: tempFilePath, // 传入已下载的临时路径
filePath: saveFilePath,
success: (saveRes) => {
if(isNowOpen){
uni.openDocument({
filePath: saveRes.savedFilePath,
showMenu:true,
success: (openRes) => {
uni.showToast({
title: "文件已打开",
icon: "none",
duration: 1500,
});
},
fail: (openErr) => {
uni.showToast({
title: `打开文件失败:${openErr.errMsg}`,
icon: "none",
duration: 1500,
});
},
});
}else{
uni.showModal({
title: "保存成功",
content: `文件已保存至:微信 → 我 → 文件 → 下载管理`,
showCancel: false,
});
}
resolve(saveRes);
},
fail: (saveErr) => {
uni.showToast({ title: `保存失败:${saveErr.errMsg}`, icon: "none" });
reject(saveErr);
},
});
});
// #endif
// -------------------------- App端处理fs.saveFile 保存临时路径) --------------------------
// #ifdef APP
return new Promise(async (resolve, reject) => {
const fs = uni.getFileSystemManager();
// App保存路径沙箱目录
const saveFilePath = `${uni.env.USER_DATA_PATH}/${targetFileName}`;
// Android 6.0+ 申请存储权限
if (uni.getSystemInfoSync().platform === "android") {
try {
const permRes = await uni.requestPermissions({
scope: "scope.writeExternalStorage",
});
if (!permRes[0].authSetting["scope.writeExternalStorage"]) {
uni.showModal({
title: "权限不足",
content: "请授予存储权限后重试(设置 → 应用 → 权限管理)",
showCancel: false,
});
return reject(new Error("存储权限未授予"));
}
} catch (permErr) {
uni.showToast({
title: `权限申请失败:${permErr.errMsg}`,
icon: "none",
});
return reject(permErr);
}
}
// 直接保存临时路径(无需下载)
fs.saveFile({
tempFilePath: tempFilePath, // 传入已下载的临时路径
filePath: saveFilePath,
success: (saveRes) => {
const platform = uni.getSystemInfoSync().platform;
uni.showModal({
title: "保存成功",
content:
platform === "ios"
? "文件已保存至应用沙箱,点击「查看」打开"
: `文件路径:内部存储/Android/data/应用包名/files/${targetFileName}`,
confirmText: "查看",
cancelText: "取消",
success: (modalRes) => {
if (modalRes.confirm) {
uni.openDocument({
filePath: saveRes.savedFilePath,
showMenu: true,
fail: (openErr) => {
uni.showToast({
title: `无法打开:${openErr.errMsg}`,
icon: "none",
});
},
});
}
},
});
resolve(saveRes);
},
fail: (saveErr) => {
uni.showToast({ title: `保存失败:${saveErr.errMsg}`, icon: "none" });
reject(saveErr);
},
});
});
// #endif
// 其他未适配平台
return Promise.reject(new Error("当前平台暂不支持文件保存"));
}