券兑换码增加下载功能

This commit is contained in:
2025-11-21 16:02:59 +08:00
parent 8269f619b8
commit b87ce7d43e
5 changed files with 482 additions and 194 deletions

199
utils/downloadFile.js Normal file
View File

@@ -0,0 +1,199 @@
/**
* 多端兼容文件保存基于已下载的临时路径无需重复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("当前平台暂不支持文件保存"));
}