微信小程式訂閱
摘要
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); } } }); }