From b87ce7d43e5b06f66a3a7eeaeff90ea8007e0e11 Mon Sep 17 00:00:00 2001
From: YeMingfei666 <1619116647@qq.com>
Date: Fri, 21 Nov 2025 16:02:59 +0800
Subject: [PATCH] =?UTF-8?q?=E5=88=B8=E5=85=91=E6=8D=A2=E7=A0=81=E5=A2=9E?=
=?UTF-8?q?=E5=8A=A0=E4=B8=8B=E8=BD=BD=E5=8A=9F=E8=83=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
http/api/market/couponRedemption.js | 2 +-
http/http.js | 407 +++++++++++++----------
pageMarket/couponExchangeCode/detail.vue | 66 +++-
pages.json | 2 +-
utils/downloadFile.js | 199 +++++++++++
5 files changed, 482 insertions(+), 194 deletions(-)
create mode 100644 utils/downloadFile.js
diff --git a/http/api/market/couponRedemption.js b/http/api/market/couponRedemption.js
index 74b5956..25b8580 100644
--- a/http/api/market/couponRedemption.js
+++ b/http/api/market/couponRedemption.js
@@ -67,7 +67,7 @@ export function codeList(params) {
});
}
export function codeExport(params) {
- return request({
+ return http.download({
url: urlType + `/admin/couponRedemption/code/export`,
method: "GET",
params: {
diff --git a/http/http.js b/http/http.js
index 2837d66..3059424 100644
--- a/http/http.js
+++ b/http/http.js
@@ -1,26 +1,26 @@
/**
* HTTP的封装, 基于uni.request
* 包括: 通用响应结果的处理 和 业务的增删改查函数
- *
+ *
* @author terrfly
* @site https://www.jeequan.com
* @date 2021/12/16 18:35
*/
// 设置env配置文件
-import envConfig from '@/env/config.js'
+import envConfig from "@/env/config.js";
// 导入全局属性
-import appConfig from '@/config/appConfig.js'
-import storageManage from '@/commons/utils/storageManage.js'
-import infoBox from "@/commons/utils/infoBox.js"
-import go from '@/commons/utils/go.js';
-import { reject } from 'lodash';
+import appConfig from "@/config/appConfig.js";
+import storageManage from "@/commons/utils/storageManage.js";
+import infoBox from "@/commons/utils/infoBox.js";
+import go from "@/commons/utils/go.js";
+import { reject } from "lodash";
// 设置node环境
// envConfig.changeEnv(storageManage.env('production'))
-envConfig.changeEnv(storageManage.env('development'))
+envConfig.changeEnv(storageManage.env("development"));
// 测试服
// #ifdef H5
-let baseUrl = '/api/'
+let baseUrl = "/api/";
// #endif
// #ifndef H5
// let baseUrl = 'https://tapi.cashier.sxczgkj.cn/'
@@ -29,207 +29,248 @@ let baseUrl = '/api/'
//正式
// let baseUrl = 'https://cashier.sxczgkj.com/'
-let baseUrl = appConfig.env.JEEPAY_BASE_URL
+let baseUrl = appConfig.env.JEEPAY_BASE_URL;
// #endif
-const loadingShowTime = 200
+const loadingShowTime = 200;
-function getHeader(){
- const headerObject={}
- headerObject["token"] = storageManage.token()
- headerObject["shopId"] = uni.getStorageSync("shopInfo").id
- headerObject["platformType"] = 'APP'
-
- return headerObject
+function getHeader() {
+ const headerObject = {};
+ headerObject["token"] = storageManage.token();
+ headerObject["shopId"] = uni.getStorageSync("shopInfo").id;
+ headerObject["platformType"] = "APP";
+
+ return headerObject;
}
-// 通用处理逻辑
+// 通用处理逻辑
function commonsProcess(showLoading, httpReqCallback) {
+ // 判断是否请求完成(用作 是否loading )
+ // 包括: 'ing', 'ingLoading', 'finish'
+ let reqState = "ing";
- // 判断是否请求完成(用作 是否loading )
- // 包括: 'ing', 'ingLoading', 'finish'
- let reqState = 'ing'
+ // 是否已经提示的错误信息
+ let isShowErrorToast = false;
- // 是否已经提示的错误信息
- let isShowErrorToast = false
+ // 请求完成, 需要处理的动作
+ let reqFinishFunc = () => {
+ if (reqState == "ingLoading") {
+ // 关闭loading弹层
+ infoBox.hideLoading();
+ }
+ reqState = "finish"; // 请求完毕
+ };
+ // 明确显示loading
+ if (showLoading) {
+ // xx ms内响应完成,不提示loading
+ setTimeout(() => {
+ if (reqState == "ing") {
+ reqState = "ingLoading";
+ infoBox.showLoading();
+ }
+ }, loadingShowTime);
+ }
- // 请求完成, 需要处理的动作
- let reqFinishFunc = () => {
+ return httpReqCallback()
+ .then((httpData) => {
+ reqFinishFunc(); // 请求完毕的动作
+ // 从http响应数据中解构响应数据 [ 响应码、 bodyData ]
+ let { statusCode, data } = httpData;
+ // 避免混淆重新命名
+ let bodyData = data;
+ if (statusCode == 500) {
+ isShowErrorToast = true;
+ return Promise.reject(bodyData); // 跳转到catch函数
+ }
+ if (statusCode == 501) {
+ // storageManage.token(null, true)
+ // 提示信息
+ isShowErrorToast = true;
+ // infoBox.showErrorToast('请登录').then(() => {
+ // go.to("PAGES_LOGIN", {}, go.GO_TYPE_RELAUNCH)
+ // })
+ return Promise.reject(bodyData); // 跳转到catch函数
+ }
+ // http响应码不正确
+ if (statusCode != 200 && statusCode != 204 && statusCode != 201) {
+ isShowErrorToast = true;
+ bodyData.msg =
+ bodyData.msg == "Bad credentials" ? "用户名或密码错误" : bodyData.msg;
+ infoBox.showToast(bodyData.msg || "服务器异常");
+ return Promise.reject(bodyData); // 跳转到catch函数
+ }
- if (reqState == 'ingLoading') { // 关闭loading弹层
- infoBox.hideLoading()
- }
- reqState = 'finish' // 请求完毕
- }
+ // // 业务响应异常
+ if (bodyData.hasOwnProperty("code") && bodyData.code != 200) {
+ isShowErrorToast = true;
+ infoBox.showToast(bodyData.msg);
+ // if (bodyData.code == 5005) { // 密码已过期, 直接跳转到更改密码页面
+ // uni.reLaunch({
+ // url: '/pageUser/setting/updatePwd'
+ // })
+ // }
+ // if(bodyData.code == 500){ // 密码已过期, 直接跳转到更改密码页面
+ // uni.redirectTo({url: '/pages/login/index'})
+ // }
+ return Promise.reject(bodyData); // 跳转到catch函数
+ }
- // 明确显示loading
- if (showLoading) {
- // xx ms内响应完成,不提示loading
- setTimeout(() => {
- if (reqState == 'ing') {
- reqState = 'ingLoading'
- infoBox.showLoading()
- }
- }, loadingShowTime)
- }
+ // 构造请求成功的响应数据
+ return Promise.resolve(bodyData.data);
+ })
+ .catch((res) => {
+ console.log(res);
+ if (res.code == 501) {
+ storageManage.token(null, true);
+ infoBox.showToast("登录过期,请重新登录").then(() => {
+ uni.redirectTo({ url: "/pages/login/index" });
+ reject();
+ });
+ }
+ // if(res.status==400){
+ // storageManage.token(null, true)
+ // infoBox.showErrorToast('').then(() => {
+ // go.to("PAGES_LOGIN", {}, go.GO_TYPE_RELAUNCH)
+ // })
+ // }
+ if (res.code == 500) {
+ infoBox.showToast(res.msg || "服务器异常").then(() => {});
+ }
+ // if(res&&res.msg){
+ // infoBox.showErrorToast(res.msg)
+ // }
+ reqFinishFunc(); // 请求完毕的动作
- return httpReqCallback().then((httpData) => {
- reqFinishFunc(); // 请求完毕的动作
- // 从http响应数据中解构响应数据 [ 响应码、 bodyData ]
- let {
- statusCode,
- data
- } = httpData
- // 避免混淆重新命名
- let bodyData = data
- if (statusCode == 500) {
- isShowErrorToast = true
- return Promise.reject(bodyData) // 跳转到catch函数
- }
- if (statusCode == 501) {
- // storageManage.token(null, true)
- // 提示信息
- isShowErrorToast = true
- // infoBox.showErrorToast('请登录').then(() => {
- // go.to("PAGES_LOGIN", {}, go.GO_TYPE_RELAUNCH)
- // })
- return Promise.reject(bodyData) // 跳转到catch函数
- }
- // http响应码不正确
- if (statusCode != 200 && statusCode != 204 && statusCode != 201) {
- isShowErrorToast = true
- bodyData.msg=bodyData.msg=='Bad credentials'?'用户名或密码错误':bodyData.msg
- infoBox.showToast(bodyData.msg || '服务器异常')
- return Promise.reject(bodyData) // 跳转到catch函数
- }
-
- // // 业务响应异常
- if (bodyData.hasOwnProperty('code') && bodyData.code != 200) {
- isShowErrorToast = true
- infoBox.showToast(bodyData.msg)
- // if (bodyData.code == 5005) { // 密码已过期, 直接跳转到更改密码页面
- // uni.reLaunch({
- // url: '/pageUser/setting/updatePwd'
- // })
- // }
- // if(bodyData.code == 500){ // 密码已过期, 直接跳转到更改密码页面
- // uni.redirectTo({url: '/pages/login/index'})
- // }
- return Promise.reject(bodyData) // 跳转到catch函数
- }
-
- // 构造请求成功的响应数据
- return Promise.resolve(bodyData.data)
-
- }).catch(res => {
- console.log(res)
- if(res.code==501){
- storageManage.token(null, true)
- infoBox.showToast('登录过期,请重新登录').then(() => {
- uni.redirectTo({url: '/pages/login/index'})
- reject()
- })
- }
- // if(res.status==400){
- // storageManage.token(null, true)
- // infoBox.showErrorToast('').then(() => {
- // go.to("PAGES_LOGIN", {}, go.GO_TYPE_RELAUNCH)
- // })
- // }
- if(res.code==500){
- infoBox.showToast(res.msg||'服务器异常').then(() => {})
- }
- // if(res&&res.msg){
- // infoBox.showErrorToast(res.msg)
- // }
- reqFinishFunc(); // 请求完毕的动作
-
- // 如果没有提示错误, 那么此处提示 异常。
- if (!isShowErrorToast) {
- infoBox.showToast(`请求网络异常`)
- }
-
- return Promise.reject(res)
-
- }).finally(() => { // finally 是 then结束后再执行, 此处不适用。 需要在请求完成后立马调用: reqFinishFunc()
-
- });
+ // 如果没有提示错误, 那么此处提示 异常。
+ if (!isShowErrorToast) {
+ infoBox.showToast(`请求网络异常`);
+ }
+ return Promise.reject(res);
+ })
+ .finally(() => {
+ // finally 是 then结束后再执行, 此处不适用。 需要在请求完成后立马调用: reqFinishFunc()
+ });
}
-
// 默认 显示loading(控制 xxs 内 不提示loading )
function req(uri, data, method = "GET", showLoading = true, extParams = {}) {
- // headerObject[appConfig.tokenKey] = storageManage.token()
- return commonsProcess(showLoading, () => {
- return uni.request(
- Object.assign({
- url: baseUrl + uri,
- data: data,
- method: method,
- header: getHeader()
- }, extParams)
- )
- })
+ // headerObject[appConfig.tokenKey] = storageManage.token()
+ return commonsProcess(showLoading, () => {
+ return uni.request(
+ Object.assign(
+ {
+ url: baseUrl + uri,
+ data: data,
+ method: method,
+ header: getHeader(),
+ },
+ extParams
+ )
+ );
+ });
}
-
// 默认 显示loading(控制 xxs 内 不提示loading )
function request(args) {
- const {
- url,
- data,
- params,
- method = "GET",
- showLoading = true,
- extParams = {}
- } = args
- let headerObject = {}
- // headerObject[appConfig.tokenKey] = storageManage.token()
- return commonsProcess(showLoading, () => {
- return uni.request(
- Object.assign({
- url: baseUrl + url,
- data: params||data,
- method: method,
- header: getHeader()
- }, extParams)
-
- )
- })
+ const {
+ url,
+ data,
+ params,
+ method = "GET",
+ showLoading = true,
+ extParams = {},
+ } = args;
+ let headerObject = {};
+ // headerObject[appConfig.tokenKey] = storageManage.token()
+ return commonsProcess(showLoading, () => {
+ return uni.request(
+ Object.assign(
+ {
+ url: baseUrl + url,
+ data: params || data,
+ method: method,
+ header: getHeader(),
+ },
+ extParams
+ )
+ );
+ });
}
-
-
// 上传
function upload(uri, data, file, showLoading = true, extParams = {}) {
- // 放置token
- let headerObject = {}
- // headerObject[appConfig.tokenKey] = storageManage.token()
+ // 放置token
+ let headerObject = {};
+ // headerObject[appConfig.tokenKey] = storageManage.token()
- return commonsProcess(showLoading, () => {
- return uni.uploadFile(
- Object.assign({
- url: baseUrl + uri,
- formData: data,
- name: "file",
- filePath: file.path||file.url,
- header: getHeader()
- }, extParams)
- ).then((httpData) => {
- // uni.upload 返回bodyData 的是 string类型。 需要解析。
- httpData.data = JSON.parse(httpData.data)
- return Promise.resolve(httpData)
- }).catch(err=>{
- uni.hideLoading()
- infoBox.showErrorToast(`上传失败`)
- })
- })
+ return commonsProcess(showLoading, () => {
+ return uni
+ .uploadFile(
+ Object.assign(
+ {
+ url: baseUrl + uri,
+ formData: data,
+ name: "file",
+ filePath: file.path || file.url,
+ header: getHeader(),
+ },
+ extParams
+ )
+ )
+ .then((httpData) => {
+ // uni.upload 返回bodyData 的是 string类型。 需要解析。
+ httpData.data = JSON.parse(httpData.data);
+ return Promise.resolve(httpData);
+ })
+ .catch((err) => {
+ uni.hideLoading();
+ infoBox.showErrorToast(`上传失败`);
+ });
+ });
+}
+
+function returnParams(params) {
+ let returnStr = "";
+ if (params) {
+ returnStr = "?";
+ for (let key in params) {
+ returnStr += `${key}=${params[key]}&`;
+ }
+ returnStr = returnStr.substring(0, returnStr.length - 1);
+ }
+ return returnStr;
+}
+// 下载文件
+function download(args) {
+ const {
+ url,
+ data,
+ params,
+ method = "GET",
+ showLoading = true,
+ extParams = {},
+ } = args;
+ let headerObject = {};
+ return uni
+ .downloadFile({
+ url: baseUrl + url + returnParams(params),
+
+ header: getHeader(),
+ })
+ .then((httpData) => {
+ return Promise.resolve(httpData);
+ })
+ .catch((err) => {
+ uni.hideLoading();
+ infoBox.showErrorToast(`下载失败`);
+ });
}
export default {
- req: req,
- request,
- upload: upload
-}
\ No newline at end of file
+ req: req,
+ request,
+ upload: upload,
+ download,
+};
diff --git a/pageMarket/couponExchangeCode/detail.vue b/pageMarket/couponExchangeCode/detail.vue
index df65294..2c0a752 100644
--- a/pageMarket/couponExchangeCode/detail.vue
+++ b/pageMarket/couponExchangeCode/detail.vue
@@ -31,9 +31,9 @@
- 优惠券
-
- {{ returnCoupon }}
+ 优惠券
+
+ {{ returnCoupon }}
修改
@@ -58,10 +58,11 @@
placeholder="输入兑换码"
class="u-font-28 u-m-l-20"
placeholder-class="color-999 u-font-28"
- v-model="query.name"
+ @input="codeChange"
+ v-model="query.code"
/>
- 导出
+ 导出
@@ -130,7 +131,7 @@ import CouponList from "@/pageMarket/components/coupon-list.vue";
import Modal from "@/pageMarket/components/modal.vue";
import * as couponRedemptionApi from "@/http/api/market/couponRedemption.js";
-
+import { saveFileFromTemp } from "@/utils/downloadFile.js";
import {
reactive,
toRefs,
@@ -188,6 +189,8 @@ const form = reactive({
onLoad((opt) => {
const item = uni.getStorageSync("couponRedemptionItem");
Object.assign(form, item);
+ console.log(form);
+ getList();
});
const query = reactive({
status: "",
@@ -233,10 +236,55 @@ function refresh() {
query.page = 1;
getList();
}
-watch(() => query, refresh);
-onMounted(() => {
- getList();
+watch(() => query.status, refresh);
+
+//节流
+const throttle = (fn, delay = 500) => {
+ let timer = null;
+ return function () {
+ if (timer) {
+ return;
+ }
+ timer = setTimeout(() => {
+ fn.apply(this, arguments);
+ timer = null;
+ }, delay);
+ };
+};
+
+const codeChange = throttle(() => {
+ console.log(query.code);
+ refresh();
});
+
+function exportCode() {
+ couponRedemptionApi
+ .codeExport({
+ status: query.status,
+ redemptionId: form.id,
+ code: query.code,
+ })
+ .then((res) => {
+ console.log(res);
+ if (res.statusCode == 200) {
+ saveFileFromTemp({
+ tempFilePath: res.tempFilePath,
+ fileName: '优惠券兑换码.xlsx',
+ isNowOpen:true
+ });
+ // uni.getFileSystemManager().saveFile({
+ // tempFilePath: res.tempFilePath,
+ // success: function (res) {
+ // console.log(res);
+ // },
+ // fail: function (err) {
+ // console.log(err);
+ // }
+ // });
+ }
+ });
+}
+
onReachBottom(() => {
console.log("触底");
if (isEnd.value) {
diff --git a/pages.json b/pages.json
index e363174..fa709e3 100644
--- a/pages.json
+++ b/pages.json
@@ -740,7 +740,7 @@
"style": {
"navigationBarTitleText": "券兑换码详情"
}
- },
+ }
]
diff --git a/utils/downloadFile.js b/utils/downloadFile.js
new file mode 100644
index 0000000..4e01b5a
--- /dev/null
+++ b/utils/downloadFile.js
@@ -0,0 +1,199 @@
+/**
+ * 多端兼容文件保存(基于已下载的临时路径,无需重复download)
+ * 核心:传入的url是uni.downloadFile返回的tempFilePath,直接用fs.saveFile保存
+ * @param {string} tempFilePath - 已下载的文件临时路径(必填,来自downloadFile返回值)
+ * @param {string} [fileName] - 自定义保存文件名(可选,默认从临时路径提取)
+ * @returns {Promise} - 保存结果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("当前平台暂不支持文件保存"));
+}
+