Files
mp-xieyingeng/assets/scripts/utils/StaminaManager.ts
richarjiang 69c0986996 feat: 进入关卡时 toast 提示体力消耗,修复 StorageManager 接口位置和 WxSDK 访问级别
- 进入关卡成功后显示 toast 提示消耗体力及剩余体力
- 将 StorageManager 中 UserInfo 接口移至模块顶层,修复嵌套接口语法问题
- WxSDK.getWx() 改为 static 公开方法,便于外部调用
2026-04-10 10:10:19 +08:00

111 lines
3.6 KiB
TypeScript

import { HttpUtil } from './HttpUtil';
import { StorageManager } from './StorageManager';
import { AuthManager } from './AuthManager';
import { API_TIMEOUT, getLevelEnterUrl, getLevelCompleteUrl } from '../config/ApiConfig';
import { ApiEnvelope, StaminaInfo, EnterLevelData, CompleteLevelData } from '../types/ApiTypes';
/**
* 体力值管理器
* 单例模式,负责体力值的服务端同步、进入关卡和通关上报
* 以服务端为准,本地 StorageManager 作为缓存
*/
export class StaminaManager {
private static _instance: StaminaManager | null = null;
static get instance(): StaminaManager {
if (!this._instance) {
this._instance = new StaminaManager();
}
return this._instance;
}
private constructor() {}
/**
* 获取当前体力信息(从本地缓存)
*/
getStamina(): StaminaInfo {
return StorageManager.getStamina();
}
/**
* 更新本地缓存的体力信息
* @param stamina 服务端返回的体力信息
*/
updateStamina(stamina: StaminaInfo): void {
StorageManager.setStamina(stamina);
}
/**
* 检查当前是否有足够的体力
*/
hasStamina(): boolean {
return StorageManager.hasStamina();
}
/**
* 进入关卡
* 消耗 1 点体力(未通关关卡),获取完整关卡详情(含答案和线索)
* @param levelId 关卡 ID
* @returns 关卡详情,失败时返回 null
*/
async enterLevel(levelId: string): Promise<EnterLevelData | null> {
if (!AuthManager.instance.isLoggedIn) {
console.warn('[StaminaManager] 未登录,无法进入关卡');
return null;
}
try {
const response = await HttpUtil.post<ApiEnvelope<EnterLevelData>>(
getLevelEnterUrl(levelId),
{},
API_TIMEOUT.DEFAULT
);
if (response.success && response.data) {
StorageManager.setStamina(response.data.stamina);
console.log(`[StaminaManager] 进入关卡 ${levelId},体力: ${response.data.stamina.current}/${response.data.stamina.max}`);
return response.data;
}
console.warn('[StaminaManager] 进入关卡失败:', response.message);
return null;
} catch (err) {
console.error('[StaminaManager] 进入关卡请求失败:', err);
return null;
}
}
/**
* 通关上报
* @param levelId 关卡 ID
* @param timeSpent 通关耗时(秒)
* @returns 通关响应,失败时返回 null
*/
async completeLevel(levelId: string, timeSpent: number): Promise<CompleteLevelData | null> {
if (!AuthManager.instance.isLoggedIn) {
console.warn('[StaminaManager] 未登录,无法上报通关');
return null;
}
try {
const response = await HttpUtil.post<ApiEnvelope<CompleteLevelData>>(
getLevelCompleteUrl(levelId),
{ timeSpent },
API_TIMEOUT.DEFAULT
);
if (response.success && response.data) {
console.log(`[StaminaManager] 通关上报成功: ${levelId}, 首次: ${response.data.firstClear}, 耗时: ${response.data.timeSpent}s`);
return response.data;
}
console.warn('[StaminaManager] 通关上报失败:', response.message);
return null;
} catch (err) {
console.error('[StaminaManager] 通关上报请求失败:', err);
return null;
}
}
}