feat: 支持登录、个人信息存储

This commit is contained in:
richarjiang
2026-04-05 13:37:58 +08:00
parent e438f6fce4
commit b732e4d8f8
23 changed files with 3572 additions and 144 deletions

View File

@@ -0,0 +1,146 @@
import { HttpUtil } from './HttpUtil';
import { StorageManager } from './StorageManager';
import { WxSDK } from './WxSDK';
import { API_ENDPOINTS, API_TIMEOUT } from '../config/ApiConfig';
import { ApiEnvelope, WxLoginData, GameData } from '../types/ApiTypes';
/**
* 认证管理器
* 单例模式,负责微信登录和 JWT token 管理
*/
export class AuthManager {
private static _instance: AuthManager | null = null;
private _userId: string = '';
private _isLoggedIn: boolean = false;
/** 服务端返回的已完成关卡 ID登录后暂存等 LevelDataManager 就绪后同步) */
private _completedLevelIds: string[] = [];
/** 服务端返回的已完成关卡 ID登录后暂存等 LevelDataManager 就绪后同步) */
private _completedLevelIds: string[] = [];
static get instance(): AuthManager {
if (!this._instance) {
this._instance = new AuthManager();
}
return this._instance;
}
private constructor() {}
get isLoggedIn(): boolean {
return this._isLoggedIn;
}
get userId(): string {
return this._userId;
}
get completedLevelIds(): string[] {
return this._completedLevelIds;
}
/**
* 初始化认证:尝试恢复 token 或执行微信登录
*/
async initialize(): Promise<boolean> {
const savedToken = StorageManager.getToken();
if (savedToken) {
HttpUtil.setAuthToken(savedToken);
try {
const valid = await this.validateToken();
if (valid) {
console.log('[AuthManager] Token 恢复成功');
return true;
}
} catch {
console.warn('[AuthManager] 本地 token 无效,重新登录');
}
}
return this.wxLogin();
}
private async wxLogin(): Promise<boolean> {
try {
let code: string;
if (WxSDK.isWechat()) {
code = await WxSDK.login();
} else {
console.warn('[AuthManager] 非微信环境,使用开发模式 mock code');
code = 'dev_mock_code';
}
const response = await HttpUtil.post<ApiEnvelope<WxLoginData>>(
API_ENDPOINTS.WX_LOGIN,
{ code },
API_TIMEOUT.DEFAULT
);
if (!response.success || !response.data) {
console.error('[AuthManager] 登录失败:', response.message);
return false;
}
const { token, user } = response.data;
HttpUtil.setAuthToken(token);
StorageManager.setToken(token);
this._userId = user.id;
this._isLoggedIn = true;
StorageManager.setPoints(user.points);
// 获取通关进度
await this.fetchCompletedLevels();
console.log(`[AuthManager] 登录成功,用户: ${user.id},积分: ${user.points}`);
return true;
} catch (err) {
console.error('[AuthManager] 登录异常:', err);
return false;
}
}
private async validateToken(): Promise<boolean> {
try {
const response = await HttpUtil.get<ApiEnvelope<GameData>>(
API_ENDPOINTS.USER_GAME_DATA,
API_TIMEOUT.SHORT
);
if (!response.success || !response.data) {
return false;
}
this._userId = response.data.user.id;
this._isLoggedIn = true;
StorageManager.setPoints(response.data.user.points);
this._completedLevelIds = response.data.completedLevelIds;
console.log(`[AuthManager] Token 验证成功,积分: ${response.data.user.points},已完成: ${this._completedLevelIds.length}`);
return true;
} catch {
return false;
}
}
/**
* 登录成功后获取通关进度
*/
private async fetchCompletedLevels(): Promise<void> {
try {
const response = await HttpUtil.get<ApiEnvelope<GameData>>(
API_ENDPOINTS.USER_GAME_DATA,
API_TIMEOUT.SHORT
);
if (response.success && response.data) {
this._completedLevelIds = response.data.completedLevelIds;
// 同步最新积分
StorageManager.setPoints(response.data.user.points);
}
} catch {
console.warn('[AuthManager] 获取通关进度失败');
}
}
}