# 微信隐私授权与用户信息功能实现计划 > **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` 对象中添加: ```typescript USER_INFO: `${API_BASE}/user/info`, ``` 最终文件应如下: ```typescript 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: 提交代码** ```bash 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 定义的位置,添加: ```typescript const STORAGE_KEYS = { // ... 现有 keys USER_INFO: 'user_info', } as const; ``` - [ ] **Step 2: 新增用户信息存取方法** 在 StorageManager 类中添加以下方法: ```typescript /** * 保存用户信息(头像、昵称) * @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: 提交代码** ```bash 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 类末尾(`}` 之前)添加: ```typescript // ==================== 隐私授权相关 ==================== /** * 检查用户是否已授权隐私 * @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 */ static 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 || '隐私授权失败')); } }); }); } ``` - [ ] **Step 2: 添加获取用户头像昵称方法** 在同一文件中继续添加: ```typescript // ==================== 用户信息相关 ==================== /** * 用户信息(头像、昵称) */ export interface WxUserInfo { avatarUrl: string; nickName: string; country?: string; province?: string; city?: string; gender?: number; } /** * 获取用户头像和昵称(需要用户主动授权) * @returns Promise */ static getUserProfile(): Promise { 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: 提交代码** ```bash 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` 方法末尾添加: ```typescript /** * 检查隐私授权状态 */ private async _checkPrivacyAuthorization(): Promise { 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` 方法末尾添加调用: ```typescript onViewLoad(): void { console.log('[PageHome] onViewLoad'); this._initButtons(); this._initWxShare(); // 新增:检查隐私授权 this._checkPrivacyAuthorization(); } ``` - [ ] **Step 3: 提交代码** ```bash 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,添加: ```typescript import { HttpUtil } from 'db://assets/scripts/utils/HttpUtil'; ``` - [ ] **Step 2: 在 _onCompleteClick 中添加用户信息获取逻辑** 修改 `_onCompleteClick` 方法,在分享成功后的逻辑中添加用户信息获取: ```typescript private async _onCompleteClick(): Promise { 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 类中添加新方法: ```typescript /** * 获取用户头像昵称并上传到服务端 */ private async _uploadUserInfo(): Promise { // 先检查本地缓存 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,添加: ```typescript import { StorageManager } from 'db://assets/scripts/utils/StorageManager'; import { API_ENDPOINTS, API_TIMEOUT } from 'db://assets/scripts/config/ApiConfig'; ``` - [ ] **Step 5: 提交代码** ```bash git add assets/prefabs/PageWriteLevels.ts git commit -m "feat: PageWriteLevels 接入用户信息获取与上传" ``` --- ## 实现完成 所有任务已完成,实现功能: 1. ✅ PageHome 进入时检查隐私授权状态,未授权则引导用户授权 2. ✅ PageWriteLevels 分享时获取用户头像昵称,本地缓存并上传服务端 3. ✅ 新增用户信息 API 端点 4. ✅ StorageManager 支持用户信息缓存