fix: 修复一系列 bug

This commit is contained in:
richarjiang
2026-05-19 22:56:31 +08:00
parent 43afe6085d
commit 2a599b0356
15 changed files with 1321 additions and 39 deletions

View File

@@ -292,6 +292,14 @@ export class PageLevel extends BaseView {
/** 是否处于分享挑战模式 */
private _isShareMode: boolean = false;
/**
* 当前 PageLevel 实例所处分享挑战的 shareCode 缓存。
* PageLevel 注册时 cache: true复用同一个实例。
* 当用户在后台切换好友分享卡片时ShareManager.shareCode 会发生变化,
* onViewShow 通过对比这个值与最新的 ShareManager.shareCode 来判断是否需要 _reinitLevelSession。
*/
private _activeShareCode: string | null = null;
/** 体力恢复倒计时定时器 */
private _staminaTimerId: ReturnType<typeof setInterval> | null = null;
@@ -335,8 +343,10 @@ export class PageLevel extends BaseView {
this._shareSubmissions.clear();
this._isSubmittingShareResult = false;
this._hasRequestedShareUserInfo = false;
this._activeShareCode = ShareManager.instance.shareCode;
console.log('[PageLevel] 进入分享挑战模式');
} else {
this._activeShareCode = null;
// 从 AuthManager 获取首关数据(由 PageLoading → game-data 提供)
const nextLevel = AuthManager.instance.nextLevel;
if (nextLevel) {
@@ -373,12 +383,41 @@ export class PageLevel extends BaseView {
const params = this.getParams();
const desiredShareMode = params?.shareMode === true;
if (desiredShareMode !== this._isShareMode) {
console.log(`[PageLevel] 检测到模式切换 ${this._isShareMode}${desiredShareMode},重新初始化关卡会话`);
// 当前 ShareManager 中的 shareCode(可能因为后台切到新的分享卡片而变化)
const latestShareCode = ShareManager.instance.shareCode;
const modeChanged = desiredShareMode !== this._isShareMode;
// 同样是分享模式,但 ShareManager 中的 shareCode 已经换了一份题单 —— 也必须重建会话
const shareCodeChanged = desiredShareMode && latestShareCode !== this._activeShareCode;
if (modeChanged || shareCodeChanged) {
console.log(
`[PageLevel] 检测到模式/分享码切换 mode:${this._isShareMode}->${desiredShareMode} ` +
`code:${this._activeShareCode}->${latestShareCode},重新初始化关卡会话`,
);
this._reinitLevelSession(desiredShareMode);
return;
}
// 上一次离场时如果停留在「答对后通关流程」_isTransitioning=true 由 showSuccess 置位、
// 而 _applyLevelConfig 才会重置),缓存的 PageLevel 实例会保留完成态:
// - 输入格已填入正确答案
// - 提交按钮被 _isTransitioning 锁住,无法重新提交
// - 倒计时已停、谐音梗已揭示
// 此时玩家从首页再次进入会看到一个无法操作的"死局"。必须把会话推进到下一关。
// 注意:这只可能在主线模式发生 —— 分享模式下点 iconSetting / PassModal 的 home
// 都会调用 ShareManager.clearShareMode + ViewManager.replace再次进入会被
// 上面的 modeChanged / shareCodeChanged 分支拦截走 _reinitLevelSession。
if (this._isTransitioning) {
console.log('[PageLevel] 上次离场时停留在通关后状态,自动推进到下一关');
this._closePassModal();
this._closeWrongModal();
this._closeTimeoutModal();
this._closeCommonModal();
void this.goToNextLevel();
return;
}
this._refreshModeUI();
this.updateStaminaLabel();
if (!this._isShareMode) {
@@ -408,8 +447,10 @@ export class PageLevel extends BaseView {
this._hasRequestedShareUserInfo = false;
if (this._isShareMode) {
console.log('[PageLevel] 切换到分享挑战模式');
this._activeShareCode = ShareManager.instance.shareCode;
console.log(`[PageLevel] 切换到分享挑战模式 (shareCode=${this._activeShareCode})`);
} else {
this._activeShareCode = null;
// 主线模式:从 AuthManager 拉取最新的 nextLevel
this._nextLevelData = null;
const nextLevel = AuthManager.instance.nextLevel;
@@ -866,6 +907,16 @@ export class PageLevel extends BaseView {
console.log('[PageLevel] IconSetting 点击,返回主页');
AudioManager.instance.playButtonClick();
// 离开 PageLevel 时把所有挂在 Canvas 上的关卡级弹窗一起清掉。
// PassModal / WrongModal / TimeoutModal / CommonModal 都是 addChild 到 this.node.parent
// 也就是 PageLevel 的兄弟节点PageLevel 被 ViewManager 隐藏后它们并不会自动消失,
// 否则会孤儿地盖在 PageHome 上。同时清掉 PassModal 也避免再次进入时缓存实例
// 残留 _passModalNode 引用让 _swapToNextLevelImagesIfReady 误判弹窗仍在打开。
this._closePassModal();
this._closeWrongModal();
this._closeTimeoutModal();
this._closeCommonModal();
// 分享模式下栈中没有 PageHome需要清除分享状态并直接打开首页
if (this._isShareMode) {
ShareManager.instance.clearShareMode();