From 09909f0dcf3df16d9f443bd5483f69e8f1422b74 Mon Sep 17 00:00:00 2001 From: jing <1683105490@qq.com> Date: Sat, 10 Oct 2026 16:02:20 +0800 Subject: [PATCH] =?UTF-8?q?chore=EF=BC=9A=E7=9C=9F=E6=9C=BA=E4=B8=8A?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=E5=B9=BF=E5=91=8A=E6=AD=A3=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- common/js/diy.js | 50 +++++++++++++++++++++++++++++++++++++------ pages/index/index.vue | 2 +- 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/common/js/diy.js b/common/js/diy.js index d7710f9..0f5f93e 100644 --- a/common/js/diy.js +++ b/common/js/diy.js @@ -298,14 +298,20 @@ export default { data: {}, async: false }); - this.adv = res.value + // 接口把启动广告配置放在 data 字段(少数环境也可能放在 value), 两者兼容, + // 避免取到 undefined 后模板 v-if 抛错导致 uni-popup 不渲染、真机广告弹不出来 + let advData = (res && (res.data != null ? res.data : res.value)) || {}; + this.adv = advData; // 后台配置: advshow=1 开启启动广告; advtype 决定弹出策略 // advtype == 1: 首次弹出 —— 仅第一次进入小程序弹出(持久化标记, 清缓存后可再弹) // advtype == 0: 每次弹出 —— 每次"重新进入小程序"都弹出(不含 Tab 切换回首页) if (this.adv.advshow == 1) { - setTimeout(() => { + setTimeout(async () => { + // 隐私协议未同意时, 先等用户点击隐私协议(同意/拒绝)关闭弹窗, + // 否则广告弹窗会被隐私弹窗(z-index:5000)盖住, 真机上表现为"点了隐私协议后广告不弹" + await this._waitPrivacyResolved(); if (!this.$refs.uniPopupWindow) return; - if (res.value.advtype == 1) { + if (this.adv.advtype == 1) { // 首次弹出: 从未展示过才弹 var popwindow_count = uni.getStorageSync(this.id + this.name + '_popwindow_count'); if (popwindow_count == '' || popwindow_count == 0) { @@ -320,9 +326,41 @@ export default { } } }, 500); - } - - }, + } + }, + /** + * 等待隐私协议流程结束后再弹启动广告 + * - 鸿蒙元服务: 隐私由系统托管, 应用层不弹自建弹窗, 直接放行 + * - 已同意过(storage privacyAgreed): 无需等待, 直接放行 + * - 未同意: 监听 PrivacyManager 广播的 privacy:agreed / privacy:disagreed, + * 用户点击隐私协议(同意/拒绝)关闭弹窗后放行 + * - 兜底超时: 隐私协议因规则未弹等情况永不 emit 时也要弹广告, 避免卡死 + * @param {number} [maxWait=15000] + * @returns {Promise} + */ + _waitPrivacyResolved(maxWait = 15000) { + // 鸿蒙元服务: 隐私协议由系统托管, 应用层不弹自建隐私弹窗, 无需等待 + // #ifdef MP-HARMONY + return Promise.resolve(); + // #endif + // 已经同意过 → 隐私弹窗不会再出现, 直接放行 + if (uni.getStorageSync('privacyAgreed')) return Promise.resolve(); + return new Promise((resolve) => { + let done = false; + const finish = () => { + if (done) return; + done = true; + uni.$off('privacy:agreed', finish); + uni.$off('privacy:disagreed', finish); + clearTimeout(timer); + resolve(); + }; + uni.$on('privacy:agreed', finish); + uni.$on('privacy:disagreed', finish); + // 兜底: 隐私协议因规则未弹 / 一直未处理时, 超时后也要弹广告 + const timer = setTimeout(finish, maxWait); + }); + }, // 无法从网络获取 diy 数据时:在页面内渲染错误横幅(各端可靠、一定可见) // 同时通过 uni.$emit 通知 splash-state 关闭启动屏 (否则 strict 模式永远不关) // @param {Object|string} [err] 网络异常对象 {errMsg, statusCode} / 服务端消息字符串 diff --git a/pages/index/index.vue b/pages/index/index.vue index cd606b4..f50de06 100644 --- a/pages/index/index.vue +++ b/pages/index/index.vue @@ -53,7 +53,7 @@ -