微信小程序订阅
泽能 人气:0微信小程序订阅
摘要
1.基于promise封装微信小程序订阅
2.解决由于微信基础库版本低下的兼容
3.解决“总是保持以上选择,不再询问”的取消状态
主要运用API:
requestSubscribeMessage
getSetting
openSetting
主要功能:
用户强制订阅,无论怎么取消都能订阅,总代码在下方,具体流程思路有耐心可以往下看...,可以拷贝直接用。引入即可,当然我比较菜,大家可以再改改。
总代码
/** * @desc 小程序订阅功能 * @param {Array} tmplIds 订阅列表 * @returns {Promise} 返回promise */ // 永久关闭订阅则代表点击了我不在接受此消息,再次订阅是无法弹起授权窗口的。普通关闭时可以再次弹起授权窗口。 export const Subscribe = (tmplIds = []) => { return new Promise((resolve, reject) => { // 判断是否为微信小程序,不是的不做订阅进行跳过 let isWx = false; // #ifdef MP-WEIXIN isWx = true; // #endif if (!isWx) resolve(1); console.log('进来了哟') // 判断基本库是否在2.8.3,低于的暂时不做订阅进行跳过 const versionCan = compareVersion("2.8.3"); if (versionCan === -1) resolve(1); // 主流程 requestSubscribe(tmplIds, resolve, reject) }) } // 申请订阅功能 function requestSubscribe(tmplIds, resolve, reject) { uni.requestSubscribeMessage({ tmplIds, success: async res => { // 检查订阅数量 let checkSubscribeBool = await checkSubscribeAll(tmplIds, res); if (checkSubscribeBool) { // 用户完成订阅 console.log("[用户完成订阅]") resolve(1); } else { // 跳去检查永久关闭订阅还是普通关闭订阅 guidSubscribeMessageAuthAfter(tmplIds, resolve, reject); } }, fail: res => { console.log(res, "订阅,失败"); if (res.errCode == 20004) { // console.log(res, 'fail:用户关闭了主开关,无法进行订阅,引导开启---'); guideOpenSubscribeMessage(tmplIds, resolve, reject); } return } }) } // 计算用户订阅消息的数量 function checkSubscribeAll(tmplIds, res) { // 将accept的生成一个数组,判断申请的订阅消息是不是已经订阅消息的子集 let arr = []; for (const key of Object.keys(res)) { if (res[key] === 'accept') { arr.push(key); } } if (arr.length == tmplIds.length) { console.log('订阅完毕') return true } else { console.log('没订阅或者少订阅') return false } } // 检查用户是否授权完毕(检查时永久关闭还是普通关闭) function guidSubscribeMessageAuthAfter(tmplIds, resolve, reject) { uni.getSetting({ withSubscriptions: true, success: async res => { let { authSetting = {}, subscriptionsSetting: { mainSwitch = false, itemSettings = {} } = {} } = res; if (Object.keys(itemSettings).length == 0) { // 这种情况是普通关闭 uni.showModal({ title: "温馨提示", content: "同意订阅才能及时获知完成进度领取优惠", confirmText: "重新订阅", cancelText: "我再看看", success: res => { if (res.confirm) { // 重新调起授权订阅 requestSubscribe(tmplIds, resolve, reject); } else if (res.cancel) { //没成功订阅,返回reject reject(2); } } }); } else { // 这种是订阅成功或永久关闭 let checkSubscribeBool = await checkSubscribeAll(tmplIds, itemSettings); if ( authSetting["scope.subscribeMessage"] || (mainSwitch && checkSubscribeBool) ) { //成功 console.log("用户手动开启同意了,订阅消息"); resolve(1); } else { //失败,永久关闭 guideOpenSubscribeMessage(tmplIds, resolve, reject); } } } }); } //引导用户重新授权(永久关闭的方法) function guideOpenSubscribeMessage(tmplIds, resolve, reject) { // console.log(resolve, reject, 'rescovavasr1') uni.showModal({ title: "温馨提示", content: "检测到您没有开启全部订阅消息的权限,是否去设置?", success: res => { if (res.confirm) { uni.openSetting({ success: res => { // 在检查是否全部订阅完毕 guidSubscribeMessageAuthAfter(tmplIds, resolve, reject); } }); } else if (res.cancel) { // console.log(resolve, reject, 'rescovavasr2') uni.showModal({ title: "温馨提示", content: "同意订阅才能及时获知完成进度领取优惠", showCancel: false, confirmText: "我知道了" }); reject(2); } } }); } // 比较版本号 function compareVersion(v2) { let { SDKVersion: v1 } = uni.getSystemInfoSync(); v1 = v1.split("."); v2 = v2.split("."); const len = Math.max(v1.length, v2.length); while (v1.length < len) { v1.push("0"); } while (v2.length < len) { v2.push("0"); } for (let i = 0; i < len; i++) { const num1 = parseInt(v1[i]); const num2 = parseInt(v2[i]); if (num1 > num2) { return 1; } else if (num1 < num2) { return -1; } } return 0; }
思路流程解析
这是第一步,封装promise,返回订阅成功和订阅失败的回调。以及判断版本号是否低于2.8.3,低于2.8.3是只能使用一个模板id的,可以考虑做兼容。这边内部原因就跳过不做订阅。然后走入主流程requestSubscribe(tmplIds, resolve, reject),带入模板id和俩个回调
return new Promise((resolve, reject) => { // 判断是否为微信小程序,不是的不做订阅进行跳过 let isWx = false; // #ifdef MP-WEIXIN isWx = true; // #endif if (!isWx) resolve(1); console.log('进来了哟') // 判断基本库是否在2.8.3,低于的暂时不做订阅进行跳过 const versionCan = compareVersion("2.8.3"); if (versionCan === -1) resolve(1); // 主流程 requestSubscribe(tmplIds, resolve, reject) })
这是第二步,订阅api。api走通就success,报错走fail。 主要看success,返回一个res,大家可以打印看看,里面就一个对象,键是id,订阅成功的值是accept,执行一波判断数量函数,符合长度说明用户全部订阅,就放行。
当然点击了“总是保持以上选择,不再询问”也是走到这里面,然后值都是订阅失败的。这里走去检查看看是否点击了“总是保持以上选择,不再询问”。
// 申请订阅功能 function requestSubscribe(tmplIds, resolve, reject) { uni.requestSubscribeMessage({ tmplIds, success: async res => { // 检查订阅数量 let checkSubscribeBool = await checkSubscribeAll(tmplIds, res); if (checkSubscribeBool) { // 用户完成订阅 console.log("[用户完成订阅]") resolve(1); } else { // 跳去检查永久关闭订阅还是普通关闭订阅 guidSubscribeMessageAuthAfter(tmplIds, resolve, reject); } }, fail: res => { console.log(res, "订阅,失败"); if (res.errCode == 20004) { // console.log(res, 'fail:用户关闭了主开关,无法进行订阅,引导开启---'); guideOpenSubscribeMessage(tmplIds, resolve, reject); } return } }) }
第三步 getsettingApi,检查用户是否点击了“总是保持以上选择,不再询问”,判断的条件就是返回的res有没有itemSettings,当然大家可以找俩种情况比对一下就知道了,永久关闭的是有的那个对象的,普通关闭是没有的。
判断这个目的,是可以直接在调起订阅界面。可以引导用户重新点击。当然如果调不起就走guideOpenSubscribeMessage函数。
// 检查用户是否授权完毕(检查时永久关闭还是普通关闭) function guidSubscribeMessageAuthAfter(tmplIds, resolve, reject) { uni.getSetting({ withSubscriptions: true, success: async res => { let { authSetting = {}, subscriptionsSetting: { mainSwitch = false, itemSettings = {} } = {} } = res; if (Object.keys(itemSettings).length == 0) { // 这种情况是普通关闭 uni.showModal({ title: "温馨提示", content: "同意订阅才能及时获知完成进度领取优惠", confirmText: "重新订阅", cancelText: "我再看看", success: res => { if (res.confirm) { // 重新调起授权订阅 requestSubscribe(tmplIds, resolve, reject); } else if (res.cancel) { //没成功订阅,返回reject reject(2); } } }); } else { // 这种是订阅成功或永久关闭 let checkSubscribeBool = await checkSubscribeAll(tmplIds, itemSettings); if ( authSetting["scope.subscribeMessage"] || (mainSwitch && checkSubscribeBool) ) { //成功 console.log("用户手动开启同意了,订阅消息"); resolve(1); } else { //失败,永久关闭 guideOpenSubscribeMessage(tmplIds, resolve, reject); } } } }); }
第四步,用户永久关闭了订阅,我们可以用openSetting打开。这时候订阅消息是会出来没订阅的模板的。重新引导...这样就结束了这个封装啦!
//引导用户重新授权(永久关闭的方法) function guideOpenSubscribeMessage(tmplIds, resolve, reject) { // console.log(resolve, reject, 'rescovavasr1') uni.showModal({ title: "温馨提示", content: "检测到您没有开启全部订阅消息的权限,是否去设置?", success: res => { if (res.confirm) { uni.openSetting({ success: res => { // 在检查是否全部订阅完毕 guidSubscribeMessageAuthAfter(tmplIds, resolve, reject); } }); } else if (res.cancel) { // console.log(resolve, reject, 'rescovavasr2') uni.showModal({ title: "温馨提示", content: "同意订阅才能及时获知完成进度领取优惠", showCancel: false, confirmText: "我知道了" }); reject(2); } } }); }
大家觉得有什么奇怪的,欢迎和我讨论
加载全部内容