feat: 接入微信隐私授权API和用户信息获取

- WxSDK 新增隐私授权检查和用户信息获取方法
- StorageManager 新增用户信息本地缓存方法
- PageHome 进入时检查隐私授权状态
- PageWriteLevels 分享时获取用户头像昵称并上传服务端
- ApiConfig 新增用户信息 API 端点

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
richarjiang
2026-04-07 21:40:48 +08:00
parent 0ecb572ba8
commit 0da6fc12bb
5 changed files with 254 additions and 1 deletions

View File

@@ -15,6 +15,7 @@ export const API_ENDPOINTS = {
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;
/** 构建加入分享的 URL */

View File

@@ -24,6 +24,9 @@ export class StorageManager {
/** 认证 token 存储键 */
private static readonly KEY_TOKEN = 'auth_token';
/** 用户信息存储键 */
private static readonly KEY_USER_INFO = 'user_info';
/** 默认积分 */
private static readonly DEFAULT_POINTS = 10;
@@ -264,6 +267,48 @@ export class StorageManager {
StorageManager.resetPoints();
StorageManager.resetProgress();
StorageManager.clearToken();
StorageManager.clearUserInfo();
console.log('[StorageManager] 所有数据已重置');
}
// ==================== 用户信息管理 ====================
/**
* 用户信息结构
*/
interface UserInfo {
avatarUrl: string;
nickName: string;
}
/**
* 保存用户信息(头像、昵称)
* @param userInfo 用户信息对象
*/
static setUserInfo(userInfo: UserInfo): void {
sys.localStorage.setItem(StorageManager.KEY_USER_INFO, JSON.stringify(userInfo));
console.log('[StorageManager] 用户信息已保存');
}
/**
* 获取本地缓存的用户信息
* @returns 用户信息对象或 null
*/
static getUserInfo(): UserInfo | null {
const data = sys.localStorage.getItem(StorageManager.KEY_USER_INFO);
if (!data) return null;
try {
return JSON.parse(data) as UserInfo;
} catch {
return null;
}
}
/**
* 清除用户信息缓存
*/
static clearUserInfo(): void {
sys.localStorage.removeItem(StorageManager.KEY_USER_INFO);
console.log('[StorageManager] 用户信息已清除');
}
}

View File

@@ -237,3 +237,135 @@ export class WxSDK {
return null;
}
}
// ==================== 隐私授权相关 ====================
/**
* 检查用户是否已授权隐私
* @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 });
}
});
});
}
/**
* 引导用户进行隐私授权
* 调用后会弹出微信隐私授权弹窗
* @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 || '隐私授权失败'));
}
});
});
}
// ==================== 用户信息相关 ====================
/**
* 用户信息(头像、昵称)
*/
export interface WxUserInfo {
avatarUrl: string;
nickName: string;
country?: string;
province?: string;
city?: string;
gender?: number;
}
/**
* 获取用户头像和昵称(需要用户主动授权)
* @returns Promise<WxUserInfo>
*/
export async function 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 || '获取用户信息失败'));
}
});
});
}