/** * 跳转到指定页面 * @param {String} url * @param {Boolean} isNeedLogin * @param {Object} options * @returns */ export const navigateTo = async (url, options = {}) => { // console.log('navigateTo = ' , url) if (!url) { return; } try { await uni.navigateTo({ url, ...options, }); // console.log('res = ' , res) // if (!res) { // uni.reLaunch({ // url, // }) // } } catch (error) { console.log("error = ", error); uni.reLaunch({ url, }); //TODO handle the exception } }; /** * 关闭当前页面跳转到指定页面 * @param {String} url * @param {Boolean} isNeedLogin * @returns */ export const redirectTo = async (url) => { if (!url) { return; } const res = await uni .redirectTo({ url, }) .catch(console.log); if (!res) { uni.reLaunch({ url, }); } }; /** * 弹窗展示成功信息 * @param {String} title 超过 7 个汉字会截断 * @param {Number} millisecond */ export const successToast = (title, millisecond = 1500) => { uni.showToast({ title, }); return new Promise((resolve) => { setTimeout(() => { resolve(); }, millisecond); }); }; /** * 弹窗展示错误信息 * @param {String} title * @param {Number} millisecond */ export const errorToast = (title, millisecond = 1500) => { uni.showToast({ title, icon: "none", }); return new Promise((resolve) => { setTimeout(() => { resolve(); }, millisecond); }); }; /** * 弹窗确认操作 * @param {String} content * @param {String} title * @param {Object} options */ export const confirmModal = (content, title = "提示", options) => new Promise((resolve, reject) => { uni.showModal({ ...options, title, content, success: (modal) => { resolve(modal.confirm); }, fail: (err) => { reject(err); }, }); }); // 日期格式化 export const parseTime = (time, pattern) => { if (!time) { return null; } const format = pattern || "{y}-{m}-{d} {h}:{i}:{s}"; let date; if (typeof time === "object") { date = time; } else { if (typeof time === "string" && /^[0-9]+$/.test(time)) { time = parseInt(time); } else if (typeof time === "string") { time = time .replace(new RegExp(/-/gm), "/") .replace("T", " ") .replace(new RegExp(/\.[\d]{3}/gm), ""); } if (typeof time === "number" && time.toString().length === 10) { time = time * 1000; } date = new Date(time); } const formatObj = { y: date.getFullYear(), m: date.getMonth() + 1, d: date.getDate(), h: date.getHours(), i: date.getMinutes(), s: date.getSeconds(), a: date.getDay(), }; return format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => { let value = formatObj[key]; // Note: getDay() returns 0 on Sunday if (key === "a") { return ["日", "一", "二", "三", "四", "五", "六"][value]; } if (result.length > 0 && value < 10) { value = "0" + value; } return value || 0; }); }; // 处理 微信小程序 图片 视频 表格自适应 // 处理后的内容(优化图片显示) export const processedContent = (value) => { if (!value) return ""; // 处理富文本内容,优化图片自适应 let content = value; // 为图片添加样式,确保自适应 content = content.replace(/]*)>/gi, function (match, attrs) { // 移除原有的 width 和 height 属性 attrs = attrs.replace(/\s*(width|height)\s*=\s*["'][^"']*["']/gi, ""); // 添加自适应样式 return ``; }); // 为视频添加自适应样式 content = content.replace(/]*)>/gi, function (match, attrs) { attrs = attrs.replace(/\s*(width|height)\s*=\s*["'][^"']*["']/gi, ""); return ``; }); // 处理表格自适应 content = content.replace( /]*)>/gi, '' ); return content; }; /** * 取富文本内容的第一段文本 * */ export const getFirstParagraph = (htmlString) => { if (!htmlString || typeof htmlString !== 'string') return ''; // 匹配第一个

标签(兼容

等) const pRegex = /]*>(.*?)<\/p>/is; const match = htmlString.match(pRegex); if (!match || !match[1]) return ''; // 提取到的内容,去除所有标签,保留纯文本 const innerHTML = match[1]; const text = innerHTML.replace(/<[^>]+>/g, '').trim(); // 去除所有标签 return text; } // 获取标题 export const getLabel = (val, list) => { for (let item of list) { if (item.value === val) { return item.label || item.text; } } } /*** * 文件下载功能,自动判断环境,h5环境直接打开文件,小程序环境下载到本地 * @param {String} url * @returns {Promise} * @description 下载文件到本地,并打开文件 * */ export const downloadFile = (url) => { if (!url) { uni.showToast({ title: "文件地址为空", icon: "none" }); return Promise.reject(new Error("url is required")); } const cleanUrl = String(url).split("#")[0].split("?")[0]; const fileNameFromUrl = cleanUrl.split("/").pop() || ""; const ext = (fileNameFromUrl.split(".").pop() || "").toLowerCase(); const isDoc = ["pdf", "docx", "doc", "ppt", "pptx", "xls", "xlsx"].includes(ext); const isImage = ["png", "jpeg", "jpg"].includes(ext); const fallbackName = ext ? `download.${ext}` : "download"; const downloadName = fileNameFromUrl || fallbackName; uni.showLoading({ title: "文件处理中...", mask: true }); // #ifdef H5 return (async () => { try { if (isImage) { window.open(url, "_blank"); return; } const response = await fetch(url); if (!response.ok) throw new Error(`download failed: ${response.status}`); const blob = await response.blob(); const blobUrl = window.URL.createObjectURL(blob); const a = document.createElement("a"); a.href = blobUrl; a.download = downloadName; a.style.display = "none"; document.body.appendChild(a); a.click(); document.body.removeChild(a); window.URL.revokeObjectURL(blobUrl); uni.showToast({ title: "开始下载", icon: "none" }); } catch (e) { try { window.open(url, "_blank"); } catch (_) {} uni.showToast({ title: "已在新窗口打开", icon: "none" }); } finally { uni.hideLoading(); } })(); // #endif // #ifndef H5 return new Promise((resolve, reject) => { uni.downloadFile({ url, success: (res) => { if (res.statusCode !== 200 || !res.tempFilePath) { uni.hideLoading(); uni.showToast({ title: "下载失败", icon: "none" }); reject(res); return; } const tempFilePath = res.tempFilePath; if (isImage) { uni.previewImage({ urls: [tempFilePath] }); if (!uni.saveImageToPhotosAlbum) { uni.hideLoading(); resolve({ tempFilePath }); return; } uni.saveImageToPhotosAlbum({ filePath: tempFilePath, success: () => { uni.showToast({ title: "已保存到相册", icon: "none" }); resolve({ tempFilePath }); }, fail: (err) => { const errMsg = (err && err.errMsg) || ""; if (/auth|permission|authorize|denied/i.test(errMsg)) { uni.showToast({ title: "请授权保存到相册", icon: "none" }); } else { uni.showToast({ title: "保存相册失败", icon: "none" }); } resolve({ tempFilePath, err }); }, complete: () => { uni.hideLoading(); }, }); return; } if (isDoc && uni.openDocument) { uni.saveFile({ tempFilePath, success: (saveRes) => { uni.openDocument({ filePath: saveRes.savedFilePath, showMenu: true, success: () => { resolve({ savedFilePath: saveRes.savedFilePath }); }, fail: (err) => { uni.hideLoading(); uni.showToast({ title: "文件打开失败", icon: "none" }); reject(err); }, complete: () => { uni.hideLoading(); }, }); }, fail: (err) => { uni.hideLoading(); uni.showToast({ title: "文件保存失败", icon: "none" }); reject(err); }, }); return; } if (uni.saveFile) { uni.saveFile({ tempFilePath, success: (saveRes) => { uni.hideLoading(); uni.showToast({ title: "下载完成", icon: "none" }); resolve({ savedFilePath: saveRes.savedFilePath }); }, fail: () => { uni.hideLoading(); uni.showToast({ title: "下载完成", icon: "none" }); resolve({ tempFilePath }); }, }); return; } uni.hideLoading(); uni.showToast({ title: "下载完成", icon: "none" }); resolve({ tempFilePath }); }, fail: (err) => { uni.hideLoading(); uni.showToast({ title: "下载失败", icon: "none" }); reject(err); }, }); }); // #endif }; /** * 保留指定位数小数 * @param {string|number} value - 要处理的值 * @param {number} n - 保留的小数位数,默认为2位 * @returns {string} 处理后的值 */ export const retainDecimals = (value, n = 2) => { // 确保 n 是正整数 const decimalPlaces = Math.max(0, Math.floor(n)); // 转换为字符串处理 const stringValue = String(value); // 移除非数字和小数点的字符 let cleanValue = stringValue.replace(/[^\d.]/g, ""); // 处理多个小数点的情况,保留第一个小数点 const firstDotIndex = cleanValue.indexOf('.'); if (firstDotIndex !== -1) { // 保留第一个小数点前的部分和第一个小数点 const beforeDot = cleanValue.substring(0, firstDotIndex + 1); // 移除第一个小数点后所有的小数点,只保留数字 const afterDot = cleanValue.substring(firstDotIndex + 1).replace(/\./g, ''); // 根据参数 n 限制小数点后的位数 const limitedAfterDot = afterDot.substring(0, decimalPlaces); // 如果小数点后没有数字,去除小数点 if (limitedAfterDot === '') { cleanValue = beforeDot.substring(0, firstDotIndex); } else { cleanValue = beforeDot + limitedAfterDot; } } return cleanValue; }; /** * 移除监听 * * */ export const onOffLine = (eventName = 'popupChange', callback) => { uni.$off(eventName, callback) };