feat: 添加隐私授权检查与处理逻辑,优化用户体验

This commit is contained in:
richarjiang
2026-05-12 21:44:51 +08:00
parent 1cbc25481b
commit ef7d1ad0f7
4 changed files with 107 additions and 78 deletions

View File

@@ -40,7 +40,7 @@ Git 历史采用 Conventional Commits且摘要多为中文例如 `feat:
<claude-mem-context>
# 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

View File

@@ -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('正在连接服务器...');

View File

@@ -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<void> {
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);
}
}
/**
* 初始化按钮事件
*/

View File

@@ -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<boolean> | null = null;
/**
* 是否处于微信小游戏环境
*/
@@ -76,6 +84,91 @@ export class WxSDK {
});
}
// ==================== 隐私授权相关 ====================
/**
* 检查用户是否需要隐私授权。
* 低版本或非微信环境没有隐私拦截能力,按已授权处理。
*/
static checkPrivacySetting(): Promise<WxPrivacySettingResult> {
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<boolean> {
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<boolean> {
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<void>
*/
export async function requirePrivacyAuthorize(): Promise<void> {
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('隐私授权失败');
}
}
// ==================== 用户信息相关 ====================