From ef7d1ad0f75f29a6c1b9a6c1e1532c6e07f209bb Mon Sep 17 00:00:00 2001 From: richarjiang Date: Tue, 12 May 2026 21:44:51 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E9=9A=90=E7=A7=81?= =?UTF-8?q?=E6=8E=88=E6=9D=83=E6=A3=80=E6=9F=A5=E4=B8=8E=E5=A4=84=E7=90=86?= =?UTF-8?q?=E9=80=BB=E8=BE=91=EF=BC=8C=E4=BC=98=E5=8C=96=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E4=BD=93=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AGENTS.md | 2 +- assets/PageLoading.ts | 7 ++ assets/prefabs/PageHome.ts | 26 +----- assets/scripts/utils/WxSDK.ts | 150 ++++++++++++++++++++++------------ 4 files changed, 107 insertions(+), 78 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index c407745..358e604 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -40,7 +40,7 @@ Git 历史采用 Conventional Commits,且摘要多为中文,例如 `feat: # Memory Context -# $CMEM mp-xieyingeng 2026-05-12 9:28pm GMT+8 +# $CMEM mp-xieyingeng 2026-05-12 9:37pm GMT+8 Legend: 🎯session 🔴bugfix 🟣feature 🔄refactor ✅change 🔵discovery ⚖️decision Format: ID TIME TYPE TITLE diff --git a/assets/PageLoading.ts b/assets/PageLoading.ts index f462812..8509c51 100644 --- a/assets/PageLoading.ts +++ b/assets/PageLoading.ts @@ -33,6 +33,13 @@ export class PageLoading extends Component { this._updateStatusLabel('正在加载...'); + // 阶段0: 主动触发微信隐私授权。分享挑战直达关卡时也会先经过这里。 + this._updateStatusLabel('正在确认隐私授权...'); + const privacyAuthorized = await WxSDK.ensurePrivacyAuthorized(); + if (!privacyAuthorized) { + console.warn('[PageLoading] 用户未同意隐私授权,继续加载基础流程'); + } + // 阶段1: 登录 + 获取 game-data(含 nextLevel) this._updateProgress(0); this._updateStatusLabel('正在连接服务器...'); diff --git a/assets/prefabs/PageHome.ts b/assets/prefabs/PageHome.ts index c106044..1828f69 100644 --- a/assets/prefabs/PageHome.ts +++ b/assets/prefabs/PageHome.ts @@ -1,7 +1,7 @@ import { _decorator, Node, Button, Label, tween, Vec3, UIOpacity, UITransform, Color, instantiate, ProgressBar } from 'cc'; import { BaseView } from 'db://assets/scripts/core/BaseView'; import { ViewManager } from 'db://assets/scripts/core/ViewManager'; -import { WxSDK, checkPrivacySetting, requirePrivacyAuthorize } from 'db://assets/scripts/utils/WxSDK'; +import { WxSDK } from 'db://assets/scripts/utils/WxSDK'; import { StaminaManager } from 'db://assets/scripts/utils/StaminaManager'; import { ToastManager } from 'db://assets/scripts/utils/ToastManager'; import { StaminaInfo } from 'db://assets/scripts/types/ApiTypes'; @@ -71,8 +71,6 @@ export class PageHome extends BaseView { this.updateAchievementTitleInfo(); this._initButtons(); this._initWxShare(); - // 检查隐私授权 - this._checkPrivacyAuthorization(); } /** @@ -86,28 +84,6 @@ export class PageHome extends BaseView { }); } - /** - * 检查隐私授权状态 - */ - private async _checkPrivacyAuthorization(): Promise { - if (!WxSDK.isWechat()) { - console.log('[PageHome] 非微信环境,跳过隐私授权检查'); - return; - } - - try { - const { needAuthorization } = await checkPrivacySetting(); - if (needAuthorization) { - console.log('[PageHome] 用户未授权隐私,引导授权'); - await requirePrivacyAuthorize(); - } else { - console.log('[PageHome] 用户已授权隐私'); - } - } catch (err) { - console.warn('[PageHome] 隐私授权检查异常:', err); - } - } - /** * 初始化按钮事件 */ diff --git a/assets/scripts/utils/WxSDK.ts b/assets/scripts/utils/WxSDK.ts index 845c3c0..5f1eb52 100644 --- a/assets/scripts/utils/WxSDK.ts +++ b/assets/scripts/utils/WxSDK.ts @@ -24,11 +24,19 @@ export interface WxShareTimelineConfig { query?: string; } +export interface WxPrivacySettingResult { + /** true 表示需要用户确认隐私授权 */ + needAuthorization: boolean; +} + /** * 微信小游戏 SDK 工具类 * 封装微信平台相关 API,非微信环境下静默降级 */ export class WxSDK { + /** 隐私授权请求进行中时复用同一个 Promise,避免启动链路重复弹窗 */ + private static _privacyAuthorizePromise: Promise | null = null; + /** * 是否处于微信小游戏环境 */ @@ -76,6 +84,91 @@ export class WxSDK { }); } + // ==================== 隐私授权相关 ==================== + + /** + * 检查用户是否需要隐私授权。 + * 低版本或非微信环境没有隐私拦截能力,按已授权处理。 + */ + static checkPrivacySetting(): Promise { + return new Promise((resolve) => { + const wxApi = WxSDK.getWx(); + if (!wxApi) { + resolve({ needAuthorization: false }); + return; + } + + if (typeof wxApi.getPrivacySetting !== 'function') { + console.warn('[WxSDK] 当前微信版本不支持 getPrivacySetting'); + resolve({ needAuthorization: false }); + return; + } + + wxApi.getPrivacySetting({ + success: (res: any) => { + const needAuthorization = !!res?.needAuthorization; + console.log('[WxSDK] 隐私授权检查结果:', res); + resolve({ needAuthorization }); + }, + fail: (err: any) => { + console.warn('[WxSDK] 隐私授权检查失败:', err); + resolve({ needAuthorization: true }); + } + }); + }); + } + + /** + * 主动触发微信小游戏隐私授权流程。 + * 已授权用户会直接 success;低版本或非微信环境直接视为通过。 + */ + static requirePrivacyAuthorize(): Promise { + const wxApi = WxSDK.getWx(); + if (!wxApi) { + console.warn('[WxSDK] 非微信环境,跳过隐私授权'); + return Promise.resolve(true); + } + + if (typeof wxApi.requirePrivacyAuthorize !== 'function') { + console.warn('[WxSDK] 当前微信版本不支持 requirePrivacyAuthorize'); + return Promise.resolve(true); + } + + if (WxSDK._privacyAuthorizePromise) { + return WxSDK._privacyAuthorizePromise; + } + + WxSDK._privacyAuthorizePromise = new Promise((resolve) => { + wxApi.requirePrivacyAuthorize({ + success: () => { + console.log('[WxSDK] 用户已授权隐私'); + resolve(true); + }, + fail: (err: any) => { + console.warn('[WxSDK] 用户拒绝或授权失败:', err); + resolve(false); + }, + complete: () => { + WxSDK._privacyAuthorizePromise = null; + } + }); + }); + + return WxSDK._privacyAuthorizePromise; + } + + /** + * 启动阶段使用的隐私授权入口:主动调用 requirePrivacyAuthorize, + * 让微信在合适时机触发官方隐私弹窗逻辑。 + */ + static ensurePrivacyAuthorized(): Promise { + if (!WxSDK.isWechat()) { + return Promise.resolve(true); + } + + return WxSDK.requirePrivacyAuthorize(); + } + // ==================== 分享相关 ==================== /** @@ -323,33 +416,7 @@ export class WxSDK { * @returns Promise<{ needAuthorization: boolean }> needAuthorization 为 false 表示已授权 */ export async function checkPrivacySetting(): Promise<{ needAuthorization: boolean }> { - return new Promise((resolve) => { - const wxApi = WxSDK.getWx(); - if (!wxApi) { - // 非微信环境,认为已授权 - resolve({ needAuthorization: false }); - return; - } - - if (typeof wxApi.getPrivacySetting !== 'function') { - // 低版本微信,认为已授权 - console.warn('[WxSDK] 当前微信版本不支持 getPrivacySetting'); - resolve({ needAuthorization: false }); - return; - } - - wxApi.getPrivacySetting({ - success: (res: any) => { - console.log('[WxSDK] 隐私授权检查结果:', res); - resolve({ needAuthorization: res.needAuthorization }); - }, - fail: (err: any) => { - console.warn('[WxSDK] 隐私授权检查失败:', err); - // 检查失败时认为需要授权 - resolve({ needAuthorization: true }); - } - }); - }); + return WxSDK.checkPrivacySetting(); } /** @@ -358,31 +425,10 @@ export async function checkPrivacySetting(): Promise<{ needAuthorization: boolea * @returns Promise */ export async function requirePrivacyAuthorize(): Promise { - return new Promise((resolve, reject) => { - const wxApi = WxSDK.getWx(); - if (!wxApi) { - console.warn('[WxSDK] 非微信环境,跳过隐私授权'); - resolve(); - return; - } - - if (typeof wxApi.requirePrivacyAuthorize !== 'function') { - console.warn('[WxSDK] 当前微信版本不支持 requirePrivacyAuthorize'); - resolve(); - return; - } - - wxApi.requirePrivacyAuthorize({ - success: () => { - console.log('[WxSDK] 用户已授权隐私'); - resolve(); - }, - fail: (err: any) => { - console.warn('[WxSDK] 用户拒绝或授权失败:', err); - reject(new Error(err.errMsg || '隐私授权失败')); - } - }); - }); + const authorized = await WxSDK.requirePrivacyAuthorize(); + if (!authorized) { + throw new Error('隐私授权失败'); + } } // ==================== 用户信息相关 ====================