diff --git a/pwuniapp/common/subscribe.js b/pwuniapp/common/subscribe.js index e09003e..50e48d9 100644 --- a/pwuniapp/common/subscribe.js +++ b/pwuniapp/common/subscribe.js @@ -73,14 +73,16 @@ export function requestSubscribeAll() { if (tmplIds.length === 0) { return resolve({ supported: true, tmplIds: [], accepted: [], rejected: [], noTemplates: true }); } + // 微信单次最多 3 个模板 + const batch = tmplIds.slice(0, 3); uni.requestSubscribeMessage({ - tmplIds, + tmplIds: batch, success: (res) => { - const accepted = tmplIds.filter((id) => res && res[id] === 'accept'); - const rejected = tmplIds.filter((id) => !res || res[id] !== 'accept'); - resolve({ supported: true, tmplIds, accepted, rejected, raw: 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, accepted: [], rejected: tmplIds, error: err }), + fail: (err) => resolve({ supported: true, tmplIds: batch, accepted: [], rejected: batch, error: err }), complete: () => {} }); } catch (e) { diff --git a/pwuniapp/pages/user/index.vue b/pwuniapp/pages/user/index.vue index 610257a..44197ff 100644 --- a/pwuniapp/pages/user/index.vue +++ b/pwuniapp/pages/user/index.vue @@ -1165,10 +1165,7 @@ const contactService = () => { }); }; -const openNotice = () => { - // 同步触发微信订阅授权(必须保留点击手势,不能先 await 网络);再展示平台须知。 - const subResult = typeof uni.requestSubscribeMessage === 'function' ? requestSubscribeAll() : null; - +const showPlatformNotice = () => { const notice = platformConfigs.value.safety_notice || {}; const title = notice.title || '平台官方公告与指引'; let content = '【安全履约须知】\n1. 为保障搭子与陪伴师人身与财产安全,线下约局须在合规公开商业街区进行。\n2. 现场碰面后请出示 4 位数字核销码进行签到确认。\n3. 平台提供 7x24 小时争议仲裁与资金托管保障服务。'; @@ -1183,20 +1180,38 @@ const openNotice = () => { confirmText: '我知道了', confirmColor: '#6366F1' }); +}; - if (subResult) { - subResult.then((r) => { - if (!r || !r.supported) return; - if (r.noTemplates || !r.tmplIds || r.tmplIds.length === 0) { - uni.showToast({ title: '后台未配置订阅消息模板', icon: 'none' }); - return; - } - const accepted = (r.accepted || []).length > 0; - noticeSubscribe.value = accepted; - uni.setStorageSync('notice_subscribe', accepted ? '1' : '0'); - uni.showToast({ title: accepted ? '已开启消息提醒' : '未获得提醒授权', icon: 'none' }); - }); +const openNotice = () => { + // 订阅授权必须在点击手势内同步触发;且要等授权弹窗关闭后再展示平台公告, + // 否则两个原生弹窗重叠会把授权弹窗顶掉,表现为"未获得提醒授权"。 + if (typeof uni.requestSubscribeMessage !== 'function') { + showPlatformNotice(); + return; } + + requestSubscribeAll().then((r) => { + if (r && r.supported && !r.noTemplates && Array.isArray(r.tmplIds) && r.tmplIds.length > 0) { + if (r.error) { + const code = (r.error && (r.error.errCode || r.error.errcode)) || ''; + console.log('[subscribe] 授权失败', r.error); + uni.showToast({ title: `开启失败${code ? '(' + code + ')' : ''}`, icon: 'none', duration: 2500 }); + } else { + const accepted = (r.accepted || []).length; + noticeSubscribe.value = accepted > 0; + uni.setStorageSync('notice_subscribe', accepted > 0 ? '1' : '0'); + if (accepted > 0) { + uni.showToast({ title: `已开启消息提醒(${accepted} 项)`, icon: 'none', duration: 2000 }); + } else { + console.log('[subscribe] 用户未同意', r.resultMap || {}); + uni.showToast({ title: '未同意订阅,可在微信设置中重新允许', icon: 'none', duration: 2600 }); + } + } + } else if (r && r.supported && r.noTemplates) { + uni.showToast({ title: '后台未配置订阅消息模板', icon: 'none' }); + } + showPlatformNotice(); + }); }; const openFaq = () => { diff --git a/server/tests/subscription-message-diagnose.spec.ts b/server/tests/subscription-message-diagnose.spec.ts index 956023e..80d7556 100644 --- a/server/tests/subscription-message-diagnose.spec.ts +++ b/server/tests/subscription-message-diagnose.spec.ts @@ -67,5 +67,8 @@ describe('第七十批订阅消息原因可见与真实授权', () => { expect(subscribeCode).toContain("startsWith('tmpl_')"); expect(userCode).toContain('requestSubscribeAll'); expect(userCode).toContain('uni.requestSubscribeMessage'); + // 授权弹窗结束后再弹公告,避免两弹窗重叠 + expect(userCode).toContain('showPlatformNotice'); + expect(subscribeCode).toContain('resultMap'); }); });