Fix subscription renewal and partner notification delivery
This commit is contained in:
+20
-54
@@ -2,7 +2,7 @@
|
||||
* 微信订阅消息工具
|
||||
* 统一管理订阅消息的请求和状态
|
||||
*
|
||||
* 订阅状态以服务端接口为准
|
||||
* 服务端记录的是授权登记,不代表微信侧仍有剩余次数。
|
||||
*/
|
||||
const { api } = require('./request');
|
||||
|
||||
@@ -11,8 +11,8 @@ const SUBSCRIBE_TEMPLATES = {
|
||||
notify: 'tOaqM_Z6pNSih2pVpaUmP86MgwnDT5ZlwOqd0lgmXP8',
|
||||
};
|
||||
|
||||
// 防重复标记:同一会话中已请求过订阅,不再重复弹窗
|
||||
let _requestedInSession = false;
|
||||
// 只合并正在进行的授权请求,后续用户点击仍可补充一次性授权。
|
||||
let _pendingSubscribe = null;
|
||||
|
||||
/**
|
||||
* 请求用户订阅指定模板
|
||||
@@ -20,7 +20,8 @@ let _requestedInSession = false;
|
||||
* @returns {Promise<object>} 订阅结果 { templateType: true/false }
|
||||
*/
|
||||
function requestSubscribe(templateTypes) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (_pendingSubscribe) return _pendingSubscribe;
|
||||
const pending = new Promise((resolve, reject) => {
|
||||
if (!Array.isArray(templateTypes)) {
|
||||
templateTypes = [templateTypes];
|
||||
}
|
||||
@@ -48,9 +49,7 @@ function requestSubscribe(templateTypes) {
|
||||
});
|
||||
|
||||
// 将授权结果同步到后端
|
||||
syncSubscribeResults(results);
|
||||
|
||||
resolve(results);
|
||||
syncSubscribeResults(results).then(() => resolve(results), reject);
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error('[subscribe] 请求订阅失败:', err);
|
||||
@@ -58,62 +57,29 @@ function requestSubscribe(templateTypes) {
|
||||
}
|
||||
});
|
||||
});
|
||||
_pendingSubscribe = pending.finally(() => { _pendingSubscribe = null; });
|
||||
return _pendingSubscribe;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将订阅结果同步到后端
|
||||
*/
|
||||
function syncSubscribeResults(results) {
|
||||
Object.keys(results).forEach((type) => {
|
||||
const accepted = results[type];
|
||||
const tmplId = SUBSCRIBE_TEMPLATES[type];
|
||||
if (!tmplId || tmplId === 'TEMPLATE_ID_') return;
|
||||
|
||||
if (accepted) {
|
||||
// 用户授权了,记录到后端,并同步本地标记
|
||||
api.subscribeTemplate({
|
||||
template_type: type,
|
||||
template_id: tmplId
|
||||
}).then(() => {
|
||||
wx.setStorageSync('subscribed_notify', true);
|
||||
}).catch((e) => {
|
||||
console.warn('[subscribe] 同步订阅状态到后端失败:', e);
|
||||
});
|
||||
}
|
||||
// 用户拒绝时不做任何操作
|
||||
});
|
||||
return Promise.all(Object.keys(results).filter(type => results[type]).map(type => {
|
||||
return api.subscribeTemplate({template_type:type, template_id:SUBSCRIBE_TEMPLATES[type]}).then(result => {
|
||||
if (!result || !result.success) throw new Error('订阅授权保存失败');
|
||||
wx.setStorageSync('subscribed_notify', true);
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* 操作后静默请求订阅(无应用层弹窗)
|
||||
*
|
||||
* 优化策略:
|
||||
* 1. 同一会话中只弹窗一次(_requestedInSession 标记)
|
||||
* 2. 用户明确关闭通知(subscribed_notify=false)时才跳过
|
||||
* 3. 如果用户没有伴侣,不弹窗
|
||||
*
|
||||
* @param {string} scene - 触发场景(diary/photo/checkin/login)
|
||||
*/
|
||||
// 必须由用户点击直接调用;补充的是当前用户接收TA提醒的次数。
|
||||
function requestSubscribeAfterAction(scene) {
|
||||
// 同一会话中已请求过,跳过
|
||||
if (_requestedInSession) return;
|
||||
|
||||
// 用户明确关闭了通知,不打扰
|
||||
if (wx.getStorageSync('subscribed_notify') === false) return;
|
||||
|
||||
// 检查是否有伴侣,没有伴侣不需要订阅
|
||||
const coupleId = wx.getStorageSync('coupleId');
|
||||
if (!coupleId) return;
|
||||
|
||||
// 标记已请求,防止重复弹窗
|
||||
_requestedInSession = true;
|
||||
|
||||
// 延迟一点请求,避免干扰用户当前操作。
|
||||
// 注意:微信订阅消息是一次性授权,每次操作后都应申请续订,
|
||||
// 用户勾选「总是保持以上选择」后这里会静默通过,不会反复弹窗。
|
||||
setTimeout(() => {
|
||||
requestSubscribe('notify').catch(() => {});
|
||||
}, 1500);
|
||||
if (wx.getStorageSync('subscribed_notify') === false || !wx.getStorageSync('coupleId')) return Promise.resolve({});
|
||||
return requestSubscribe('notify').catch(error => {
|
||||
console.warn('[subscribe] 授权或保存失败,下次点击可重试:', error);
|
||||
return {};
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user