// 已读取AGENTS.md // 微信订阅消息授权工具:预加载模板ID,在关键动作点击时同步请求授权。 // 说明:订阅消息为一次性订阅,需在用户点击(或确认弹窗)动作中调用 requestSubscribeFor。 import { getSubscribeTemplates } from './api.js'; const SCENE_KEYS = { order: ['orderStatusTemplateId', 'verifyCodeTemplateId'], withdraw: ['withdrawSuccessTemplateId'], activity: ['activityJoinTemplateId'] }; let templates = null; /** 页面加载时预加载模板配置(避免在点击时 await 丢失手势上下文) */ export async function preloadSubscribeTemplates() { try { templates = await getSubscribeTemplates(); } catch (_) { templates = null; } return templates; } /** 过滤掉占位/空模板ID,只保留真实模板 */ function resolveTmplIds(scene) { if (!templates || templates.enablePush === false) return []; const keys = SCENE_KEYS[scene] || []; return keys .map((k) => templates[k]) .filter((x) => x && !String(x).startsWith('tmpl_')); } /** * 在关键动作前请求订阅授权(同步调用,不阻塞业务)。 * scene: 'order' | 'withdraw' | 'activity' */ export function requestSubscribeFor(scene) { try { // #ifdef MP-WEIXIN if (typeof uni.requestSubscribeMessage !== 'function') return; const tmplIds = resolveTmplIds(scene); if (tmplIds.length === 0) return; uni.requestSubscribeMessage({ tmplIds, complete: () => {} }); // #endif } catch (_) { // 授权失败不影响主流程 } } /** 全部已配置的真实模板ID(过滤空值与 tmpl_ 占位符) */ function allTmplIds() { if (!templates || templates.enablePush === false) return []; return ['orderStatusTemplateId', 'activityJoinTemplateId', 'withdrawSuccessTemplateId', 'verifyCodeTemplateId'] .map((k) => templates[k]) .filter((x) => x && !String(x).startsWith('tmpl_')); } /** * 主动请求全部订阅授权(用于「平台消息与通知」入口)。 * 注意:wx.requestSubscribeMessage 必须在用户点击手势中同步调用;本函数不 await 任何网络请求。 * 返回每项授权结果,便于界面给出真实提示(订阅消息为一次性订阅,每条授权仅可下发 1 条)。 */ export function requestSubscribeAll() { return new Promise((resolve) => { try { if (typeof uni.requestSubscribeMessage !== 'function') { return resolve({ supported: false, tmplIds: [], accepted: [], rejected: [] }); } const tmplIds = allTmplIds(); if (tmplIds.length === 0) { return resolve({ supported: true, tmplIds: [], accepted: [], rejected: [], noTemplates: true }); } // 微信单次最多 3 个模板 const batch = tmplIds.slice(0, 3); uni.requestSubscribeMessage({ tmplIds: batch, success: (res) => { const accepted = batch.filter((id) => res && res[id] === 'accept'); const rejected = batch.filter((id) => !res || res[id] !== 'accept'); resolve({ supported: true, tmplIds: batch, accepted, rejected, resultMap: res }); }, fail: (err) => resolve({ supported: true, tmplIds: batch, accepted: [], rejected: batch, error: err }), complete: () => {} }); } catch (e) { resolve({ supported: true, tmplIds: [], accepted: [], rejected: [], error: e }); } }); }