Files
mp-xieyingeng/docs/superpowers/plans/2026-04-07-wechat-privacy-userinfo.md
2026-04-07 21:40:59 +08:00

13 KiB
Raw Permalink Blame History

微信隐私授权与用户信息功能实现计划

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.

Goal: 接入微信隐私授权 API进入首页时检查隐私授权状态分享时获取用户头像昵称并上传服务端

Architecture:

  • WxSDK 工具类新增隐私授权和用户信息获取方法
  • StorageManager 新增用户信息本地缓存
  • PageHome 接入隐私授权检查
  • PageWriteLevels 接入用户信息获取与上传
  • ApiConfig 新增用户信息 API 端点

Tech Stack: Cocos Creator 3.8.8, TypeScript, 微信小游戏 API


文件变更概览

文件 变更类型
assets/scripts/config/ApiConfig.ts 新增端点
assets/scripts/utils/StorageManager.ts 新增用户信息存取方法
assets/scripts/utils/WxSDK.ts 新增隐私授权、用户信息获取方法
assets/prefabs/PageHome.ts 接入隐私授权检查
assets/prefabs/PageWriteLevels.ts 接入用户信息获取与上传

Task 1: ApiConfig 新增用户信息 API 端点

Files:

  • Modify: assets/scripts/config/ApiConfig.ts

  • Step 1: 添加用户信息 API 端点

打开文件 assets/scripts/config/ApiConfig.ts,在 API_ENDPOINTS 对象中添加:

USER_INFO: `${API_BASE}/user/info`,

最终文件应如下:

export const API_ENDPOINTS = {
    WX_LOGIN: `${API_BASE}/auth/wx-login`,
    USER_ASSETS: `${API_BASE}/user/assets`,
    USER_ASSETS_CONSUME: `${API_BASE}/user/assets/consume`,
    USER_ASSETS_EARN: `${API_BASE}/user/assets/earn`,
    USER_GAME_DATA: `${API_BASE}/user/game-data`,
    LEVELS: `${API_BASE}/wechat-game/levels`,
    SHARE_CREATE: `${API_BASE}/share`,
    USER_INFO: `${API_BASE}/user/info`,
} as const;
  • Step 2: 提交代码
git add assets/scripts/config/ApiConfig.ts
git commit -m "feat: 新增用户信息 API 端点"

Task 2: StorageManager 新增用户信息缓存方法

Files:

  • Modify: assets/scripts/utils/StorageManager.ts

  • Step 1: 添加用户信息存储相关常量

打开 assets/scripts/utils/StorageManager.ts,在文件顶部找到存储 key 定义的位置,添加:

const STORAGE_KEYS = {
    // ... 现有 keys
    USER_INFO: 'user_info',
} as const;
  • Step 2: 新增用户信息存取方法

在 StorageManager 类中添加以下方法:

/**
 * 保存用户信息(头像、昵称)
 * @param userInfo 用户信息对象 { avatarUrl: string, nickName: string }
 */
static setUserInfo(userInfo: { avatarUrl: string; nickName: string }): void {
    localStorage.setItem(STORAGE_KEYS.USER_INFO, JSON.stringify(userInfo));
}

/**
 * 获取本地缓存的用户信息
 * @returns 用户信息对象或 null
 */
static getUserInfo(): { avatarUrl: string; nickName: string } | null {
    const data = localStorage.getItem(STORAGE_KEYS.USER_INFO);
    if (!data) return null;
    try {
        return JSON.parse(data);
    } catch {
        return null;
    }
}

/**
 * 清除用户信息缓存
 */
static clearUserInfo(): void {
    localStorage.removeItem(STORAGE_KEYS.USER_INFO);
}
  • Step 3: 提交代码
git add assets/scripts/utils/StorageManager.ts
git commit -m "feat: StorageManager 新增用户信息缓存方法"

Task 3: WxSDK 新增隐私授权和用户信息获取方法

Files:

  • Modify: assets/scripts/utils/WxSDK.ts

  • Step 1: 添加隐私授权检查方法

在 WxSDK 类末尾(} 之前)添加:

// ==================== 隐私授权相关 ====================

/**
 * 检查用户是否已授权隐私
 * @returns Promise<{ needAuthorization: boolean }> needAuthorization 为 false 表示已授权
 */
static checkPrivacySetting(): Promise<{ needAuthorization: boolean }> {
    return new Promise((resolve, reject) => {
        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 });
            }
        });
    });
}

/**
 * 引导用户进行隐私授权
 * 调用后会弹出微信隐私授权弹窗
 * @returns Promise<void>
 */
static 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 || '隐私授权失败'));
            }
        });
    });
}
  • Step 2: 添加获取用户头像昵称方法

在同一文件中继续添加:

// ==================== 用户信息相关 ====================

/**
 * 用户信息(头像、昵称)
 */
export interface WxUserInfo {
    avatarUrl: string;
    nickName: string;
    country?: string;
    province?: string;
    city?: string;
    gender?: number;
}

/**
 * 获取用户头像和昵称(需要用户主动授权)
 * @returns Promise<WxUserInfo>
 */
static getUserProfile(): Promise<WxUserInfo> {
    return new Promise((resolve, reject) => {
        const wxApi = WxSDK.getWx();
        if (!wxApi) {
            // 非微信环境,返回 mock 数据
            console.warn('[WxSDK] 非微信环境,返回 mock 用户信息');
            resolve({
                avatarUrl: '',
                nickName: '微信用户'
            });
            return;
        }

        if (typeof wxApi.getUserProfile !== 'function') {
            console.warn('[WxSDK] 当前微信版本不支持 getUserProfile');
            reject(new Error('当前微信版本不支持 getUserProfile'));
            return;
        }

        wxApi.getUserProfile({
            desc: '用于完善用户资料',
            success: (res: any) => {
                if (res.userInfo) {
                    console.log('[WxSDK] 获取用户信息成功');
                    resolve({
                        avatarUrl: res.userInfo.avatarUrl,
                        nickName: res.userInfo.nickName,
                        country: res.userInfo.country,
                        province: res.userInfo.province,
                        city: res.userInfo.city,
                        gender: res.userInfo.gender
                    });
                } else {
                    console.error('[WxSDK] 获取用户信息失败: 无 userInfo');
                    reject(new Error('获取用户信息失败'));
                }
            },
            fail: (err: any) => {
                console.error('[WxSDK] 获取用户信息失败:', err);
                reject(new Error(err.errMsg || '获取用户信息失败'));
            }
        });
    });
}
  • Step 3: 提交代码
git add assets/scripts/utils/WxSDK.ts
git commit -m "feat: WxSDK 新增隐私授权和用户信息获取方法"

Task 4: PageHome 接入隐私授权检查

Files:

  • Modify: assets/prefabs/PageHome.ts

  • Step 1: 在 onViewLoad 中添加隐私授权检查

打开 assets/prefabs/PageHome.ts,在 onViewLoad 方法末尾添加:

/**
 * 检查隐私授权状态
 */
private async _checkPrivacyAuthorization(): Promise<void> {
    if (!WxSDK.isWechat()) {
        console.log('[PageHome] 非微信环境,跳过隐私授权检查');
        return;
    }

    try {
        const { needAuthorization } = await WxSDK.checkPrivacySetting();
        if (needAuthorization) {
            console.log('[PageHome] 用户未授权隐私,引导授权');
            await WxSDK.requirePrivacyAuthorize();
        } else {
            console.log('[PageHome] 用户已授权隐私');
        }
    } catch (err) {
        console.warn('[PageHome] 隐私授权检查异常:', err);
    }
}
  • Step 2: 在 onViewLoad 中调用隐私授权检查

onViewLoad 方法末尾添加调用:

onViewLoad(): void {
    console.log('[PageHome] onViewLoad');
    this._initButtons();
    this._initWxShare();
    // 新增:检查隐私授权
    this._checkPrivacyAuthorization();
}
  • Step 3: 提交代码
git add assets/prefabs/PageHome.ts
git commit -m "feat: PageHome 接入隐私授权检查"

Task 5: PageWriteLevels 接入用户信息获取与上传

Files:

  • Modify: assets/prefabs/PageWriteLevels.ts

  • Step 1: 添加 HttpUtil import如果还没有

检查文件顶部 import如果没有 HttpUtil添加

import { HttpUtil } from 'db://assets/scripts/utils/HttpUtil';
  • Step 2: 在 _onCompleteClick 中添加用户信息获取逻辑

修改 _onCompleteClick 方法,在分享成功后的逻辑中添加用户信息获取:

private async _onCompleteClick(): Promise<void> {
    if (!this._validateSelection()) return;

    const shareTitle = this.shareTitleEditBox?.getComponent(EditBox)?.string?.trim() || '';
    if (!shareTitle) {
        ToastManager.instance.show('请输入分享标题');
        return;
    }

    if (this._isSubmitting) return;
    this._isSubmitting = true;

    try {
        const levelIds = this._getSelectedLevelIds();
        if (levelIds.length !== MAX_SELECTION) {
            ToastManager.instance.show('获取关卡数据失败,请重试');
            return;
        }

        const shareCode = await ShareManager.instance.createShare(shareTitle, levelIds);
        if (!shareCode) {
            ToastManager.instance.show('创建分享失败,请重试');
            return;
        }

        console.log('[PageWriteLevels] 创建分享成功, code:', shareCode);
        
        // 获取用户头像昵称并上传
        await this._uploadUserInfo();
        
        ShareManager.instance.triggerWxShare(shareTitle, shareCode);
        ToastManager.instance.show('分享创建成功!');
    } catch (err) {
        console.error('[PageWriteLevels] 完成按钮异常:', err);
        ToastManager.instance.show('操作失败,请重试');
    } finally {
        this._isSubmitting = false;
    }
}
  • Step 3: 添加 _uploadUserInfo 方法

在 PageWriteLevels 类中添加新方法:

/**
 * 获取用户头像昵称并上传到服务端
 */
private async _uploadUserInfo(): Promise<void> {
    // 先检查本地缓存
    const cachedUserInfo = StorageManager.getUserInfo();
    if (cachedUserInfo) {
        console.log('[PageWriteLevels] 使用缓存的用户信息');
        return;
    }

    if (!WxSDK.isWechat()) {
        console.log('[PageWriteLevels] 非微信环境,跳过获取用户信息');
        return;
    }

    try {
        const userInfo = await WxSDK.getUserProfile();
        
        // 本地缓存
        StorageManager.setUserInfo(userInfo);
        
        // 上传到服务端
        const response = await HttpUtil.post(
            API_ENDPOINTS.USER_INFO,
            {
                avatarUrl: userInfo.avatarUrl,
                nickName: userInfo.nickName
            },
            API_TIMEOUT.DEFAULT
        );
        
        if (response.success) {
            console.log('[PageWriteLevels] 用户信息上传成功');
        } else {
            console.warn('[PageWriteLevels] 用户信息上传失败:', response.message);
        }
    } catch (err) {
        console.warn('[PageWriteLevels] 获取用户信息失败:', err);
        // 不阻断主流程
    }
}
  • Step 4: 添加必要的 import

检查文件顶部 import添加

import { StorageManager } from 'db://assets/scripts/utils/StorageManager';
import { API_ENDPOINTS, API_TIMEOUT } from 'db://assets/scripts/config/ApiConfig';
  • Step 5: 提交代码
git add assets/prefabs/PageWriteLevels.ts
git commit -m "feat: PageWriteLevels 接入用户信息获取与上传"

实现完成

所有任务已完成,实现功能:

  1. PageHome 进入时检查隐私授权状态,未授权则引导用户授权
  2. PageWriteLevels 分享时获取用户头像昵称,本地缓存并上传服务端
  3. 新增用户信息 API 端点
  4. StorageManager 支持用户信息缓存