/** * 订阅消息授权助手 * * 用法:在需要提醒用户的入口调用一次即可 * import { requestSubscribeNotice } from '@/utils/subscribe.js' * await requestSubscribeNotice() * * 说明: * - 微信一次性订阅:用户每同意一次,服务器才有一次推送机会,所以要挑「用户确实 * 可能需要收到提醒」的时机调用(比如进入工作台、提交完审批后)。 * - 微信限制一次最多弹 3 个模板,这里自动分批。 */ import { getSubscribeTemplates, authorizeSubscribe } from '@/api/subscribe.js' /** 单次弹窗最多 3 个模板 ID */ const MAX_TMPL_PER_CALL = 3 /** * 拉起微信订阅授权弹窗,并把授权结果上报给服务器 * @param {{silent?: boolean, tip?: string}} options * @returns {Promise<{ok: boolean, reason?: string, accepted?: string[]}>} */ export async function requestSubscribeNotice(options = {}) { const silent = !!options.silent // #ifdef MP-WEIXIN let templates = [] try { const data = await getSubscribeTemplates() templates = (data && data.list) || [] } catch (e) { if (!silent) uni.showToast({ title: '获取订阅模板失败', icon: 'none' }) return { ok: false, reason: 'template_fetch_failed' } } const tmplIds = templates.map((t) => t.template_id).filter(Boolean) if (!tmplIds.length) { if (!silent) uni.showToast({ title: '暂未配置订阅消息模板', icon: 'none' }) return { ok: false, reason: 'no_template' } } const accepted = [] for (let i = 0; i < tmplIds.length; i += MAX_TMPL_PER_CALL) { const batch = tmplIds.slice(i, i + MAX_TMPL_PER_CALL) let result = {} try { result = await new Promise((resolve, reject) => { uni.requestSubscribeMessage({ tmplIds: batch, success: resolve, fail: reject }) }) } catch (e) { if (!silent) uni.showToast({ title: '订阅授权失败', icon: 'none' }) return { ok: false, reason: 'request_failed' } } batch.forEach((id) => { if (result[id] === 'accept') accepted.push(id) }) } if (!accepted.length) { if (!silent) uni.showToast({ title: '你取消了订阅授权', icon: 'none' }) return { ok: false, reason: 'refuse' } } try { await authorizeSubscribe(accepted) } catch (e) { if (!silent) uni.showToast({ title: '授权结果上报失败', icon: 'none' }) return { ok: false, reason: 'report_failed' } } if (!silent) { uni.showToast({ title: options.tip || '已开启消息提醒', icon: 'success' }) } return { ok: true, accepted } // #endif // #ifndef MP-WEIXIN if (!silent) uni.showToast({ title: '请在微信小程序中开启消息提醒', icon: 'none' }) return { ok: false, reason: 'not_mp' } // #endif }