- openNotice 改为串行:先请求订阅授权,等授权弹窗关闭后再展示平台公告(此前两原生弹窗重叠会取消授权,回调全 reject) - 授权结果区分展示:成功显示已开启项数;未同意提示可在微信设置中重新允许;接口报错显示 errCode - requestSubscribeAll 单次最多取前3个模板(微信限制),并返回 resultMap 便于排查 - 回归 87 套件/639 用例全绿
93 行
3.3 KiB
JavaScript
93 行
3.3 KiB
JavaScript
// 已读取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 });
|
||
}
|
||
});
|
||
}
|