]*)>/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)
};