js
复制代码
/**
* @description Promise调用安全包装
* @param {Promise} p
* @returns {Promise}
*/
const $sync = (p) => p.then((d) => [null, d]).catch((e) => [e]);
/**
* @name requestSubscribeMessage
* @description 处理消息订阅,兼容一次性订阅和长期订阅
* @param {String} templateId 消息模板id
* @returns {Boolean} 是否订阅成功
*/
export async function requestSubscribeMessage(templateId) {
// 检查之前是否授权
const [, settingRes] = await $sync(checkSubscribeMessageAuth(templateId));
// 之前已授权,返回true,执行业务逻辑
if (settingRes) return true;
// 之前未授权,请求授权
const [, authRes] = await $sync(doRequestSubscribeMessage(templateId));
// 用户同意授权,返回true,执行业务逻辑
if (authRes) return true;
// 用户拒绝授权,显示引导授权弹窗
const [, guideRes] = await $sync(showAuthGuideModal());
// 用户确认去修改配置,打开配置页面
if (guideRes) {
const [, openSettingRes] = await $sync(openSettingPage(templateId));
// 用户在设置页面已授权,返回true,执行业务逻辑
if (openSettingRes) return true;
}
// 默认返回false,代表用户未授权或授权失败
return false;
}
// 检查订阅消息授权状态的函数
function checkSubscribeMessageAuth(templateId) {
return new Promise((resolve, reject) => {
wx.getSetting({
withSubscriptions: true, // 注意:需要此参数来获取订阅消息状态
success: (res) => {
// 检查订阅消息设置是否存在
if (!res.subscriptionsSetting) {
reject(new Error("无法获取订阅消息设置"));
return;
}
const { mainSwitch, itemSettings = {} } = res.subscriptionsSetting;
// 首先检查订阅消息总开关是否开启
if (!mainSwitch) {
reject(new Error("订阅消息总开关未打开"));
return;
}
// 如果提供了具体模板ID,检查其授权状态
if (templateId) {
const templateAuth = itemSettings[templateId];
if (templateAuth !== "accept") {
reject(new Error(`模板消息 ${templateId} 未授权`));
return;
}
} else {
reject(new Error("未提供模板id"));
}
// 授权检查通过
resolve(itemSettings);
},
fail: (err) => {
reject(err);
},
});
});
}
// 请求订阅消息授权
function doRequestSubscribeMessage(templateId) {
return new Promise((resolve, reject) => {
wx.requestSubscribeMessage({
tmplIds: [templateId], // 需要订阅的消息模板ID的数组
success: (res) => {
if (res[templateId] === "accept") {
// 用户同意订阅
resolve(true);
} else {
// 用户拒绝订阅、被后台封禁、因标题同名被后台过滤等
reject(new Error("用户拒绝订阅"));
}
},
fail: (err) => {
reject(new Error("调起授权弹窗失败"));
},
});
});
}
// 显示引导授权弹窗
function showAuthGuideModal() {
return new Promise((resolve, reject) => {
wx.showModal({
title: "温馨提示",
content: "为了您能及时收到重要通知,请开启消息订阅权限。",
confirmText: "前往开启",
success: (res) => {
res.confirm ? resolve(true) : reject(new Error("用户取消"));
},
fail: () => {
reject(new Error("打开引导弹窗失败"));
},
});
});
}
// 打开设置页面
function openSettingPage(templateId) {
return new Promise((resolve, reject) => {
wx.openSetting({
withSubscriptions: true,
success: (res) => {
// 用户从设置页面返回,再次检查授权状态
const mainSwitch = res?.subscriptionsSetting?.mainSwitch || false;
const itemSettings = res?.subscriptionsSetting?.itemSettings || {};
if (mainSwitch && itemSettings[templateId] === "accept") {
resolve(true);
} else {
reject(new Error("用户在设置页面未授权"));
}
},
fail: (err) => {
reject(new Error("打开设置页面失败"));
},
});
});
}