Files
lucky_shop/common/js/uniapp.utils.js
2026-09-12 11:03:34 +08:00

171 lines
5.1 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.
/**
* 将常用的Uniapp提供的函数,存放到这里,按需引用
*/
import lang from './lang.js';
/**
* 判断是否为「微信剪贴板隐私声明缺失」导致的复制失败
*
* 微信自 2023-09-15 起把剪贴板接口纳入《小程序用户隐私保护指引》,
* 若小程序后台未声明「剪贴板」(或声明未审核通过),调用会返回:
* { errno: 112, errMsg: 'setClipboardData:fail api scope is not declared in the privacy agreement' }
* 这是平台侧配置问题,不改代码也能复现,因此不能把原始英文 errMsg 直接展示给用户。
*
* @param {*} err uni.setClipboardData 的 fail 回调参数
* @returns {Boolean} true=剪贴板隐私声明缺失
*/
export const isClipboardPrivacyError = (err) => {
if (!err) return false;
if (Number(err.errno) === 112) return true;
const msg = `${err.errMsg || err.message || ''}`;
return /privacy agreement/i.test(msg) || /api scope is not declared/i.test(msg);
};
/**
* 显示错误信息
* @param {Exception} err
* @param {Boolean} useModal
*/
const showError = (err, useModal = false) => {
const content = err?.message || err?.errMsg || err?.toString();
if (!useModal) {
uni.showToast({
title: content,
icon: 'none',
duration: 3000
});
} else {
uni.showModal({
title: lang.lang('uniappUtils.errorTip'),
content,
showCancel: false,
})
}
}
/**
* 打电话
* @param {string} mobile 电话号码
*/
export const makePhoneCall = (mobile) => {
try {
uni.makePhoneCall({
phoneNumber: `${mobile}`,
success(e) {
}
});
} catch (err) {
showError(err);
}
}
/**
* 拷贝文本(返回 Promise)
* @param {*} text
* @param {*} options
* @returns {Promise} 返回 Promise,成功时 resolve,失败时 reject
*/
export const copyTextAsync = (text, { copySuccess = '', copyFailed = '' } = {}) => {
return new Promise((resolve, reject) => {
// 输入验证
if (!text && text !== '') {
const error = new Error(lang.lang('uniappUtils.copyTextEmpty'));
showError(error);
reject(error);
return;
}
// 超时监测
const timeoutId = setTimeout(() => {
let error = new Error(lang.lang('uniappUtils.copyTimeout'));
// #ifdef MP-WEIXIN
error = new Error([
lang.lang('uniappUtils.copyTimeoutTitle'),
lang.lang('uniappUtils.copyTimeoutReason'),
lang.lang('uniappUtils.wechatClipboardReason1'),
lang.lang('uniappUtils.wechatClipboardReason2')
].join('\r\n'));
// #endif
showError(error, true);
reject(error);
}, 5000);
try {
uni.setClipboardData({
data: `${text}`,
success: (res) => {
clearTimeout(timeoutId);
try {
if (copySuccess) {
uni.showToast({
title: copySuccess,
icon: 'success',
duration: 2000
});
}
} catch (e) {
showError(e);
}
resolve(res);
},
fail: (err) => {
clearTimeout(timeoutId);
try {
// 剪贴板隐私声明缺失(errno 112)属平台配置问题, 用可读文案替代微信原始英文错误
const tip = isClipboardPrivacyError(err)
? lang.lang('uniappUtils.clipboardPrivacyNotDeclared')
: (err.message || err.errMsg || copyFailed || lang.lang('uniappUtils.copyFailed'));
uni.showToast({
title: tip,
icon: 'none',
duration: 2000
});
} catch (e) {
showError(e);
}
reject(err);
}
});
} catch (err) {
clearTimeout(timeoutId);
showError(err);
reject(err);
}
});
}
/**
* 拷贝文本(回调形式,兼容旧代码)
* @param {*} text
* @param {*} options
* @param {Function} callback 回调函数,接收 (success, error) 参数
*/
export const copyText = (text, options = {}, callback) => {
copyTextAsync(text, options)
.then(res => {
if (callback) callback(true, null);
})
.catch(err => {
if (callback) callback(false, err);
});
}
/**
* 打开定位
* @param {Object} options
*/
export const openLocation = ({ latitude, longitude, name } = {}) => {
try {
uni.openLocation({
latitude,
longitude,
name,
});
} catch (err) {
showError(err);
}
}