diff --git a/apps/ai-game-creator-shell/src/features/app-shell/useAccountWallet.ts b/apps/ai-game-creator-shell/src/features/app-shell/useAccountWallet.ts index 7b57f9d96..78b1c8dab 100644 --- a/apps/ai-game-creator-shell/src/features/app-shell/useAccountWallet.ts +++ b/apps/ai-game-creator-shell/src/features/app-shell/useAccountWallet.ts @@ -43,7 +43,10 @@ export function useAccountWallet(currentUserId: string) { const [nativeRechargePayment, setNativeRechargePayment] = useState(null); const rechargeLifecycleRef = useRef(0); + const walletLedgerLifecycleRef = useRef(0); const [walletUiOwnerUserId, setWalletUiOwnerUserId] = useState(currentUserId); + const currentUserIdRef = useRef(currentUserId); + currentUserIdRef.current = currentUserId; const walletOwnerMatchesCurrentUser = Boolean(currentUserId) && ownerUserId === currentUserId; const walletUiOwnerMatchesCurrentUser = @@ -79,6 +82,7 @@ export function useAccountWallet(currentUserId: string) { useEffect(() => { rechargeLifecycleRef.current += 1; + walletLedgerLifecycleRef.current += 1; setWalletUiOwnerUserId(currentUserId); setWalletLedgerOpen(false); setWalletLedger(null); @@ -93,16 +97,23 @@ export function useAccountWallet(currentUserId: string) { }, [currentUserId]); async function loadWalletLedger() { - const rechargeLifecycle = rechargeLifecycleRef.current; + const walletLedgerLifecycle = ++walletLedgerLifecycleRef.current; + const snapshotOwnerUserId = currentUserId; setWalletLedgerLoading(true); setWalletLedgerError(null); try { const ledger = await getClientProfileWalletLedger(); - if (rechargeLifecycleRef.current === rechargeLifecycle) { + if ( + walletLedgerLifecycleRef.current === walletLedgerLifecycle && + currentUserIdRef.current === snapshotOwnerUserId + ) { setWalletLedger(ledger); } } catch (error) { - if (rechargeLifecycleRef.current !== rechargeLifecycle) { + if ( + walletLedgerLifecycleRef.current !== walletLedgerLifecycle || + currentUserIdRef.current !== snapshotOwnerUserId + ) { return; } setWalletLedger(null); @@ -110,7 +121,10 @@ export function useAccountWallet(currentUserId: string) { error instanceof Error ? error.message : '读取泥点账单失败', ); } finally { - if (rechargeLifecycleRef.current === rechargeLifecycle) { + if ( + walletLedgerLifecycleRef.current === walletLedgerLifecycle && + currentUserIdRef.current === snapshotOwnerUserId + ) { setWalletLedgerLoading(false); } } diff --git a/apps/ai-game-creator-shell/tests/walletStore.test.ts b/apps/ai-game-creator-shell/tests/walletStore.test.ts index 64b162f83..2fb483e16 100644 --- a/apps/ai-game-creator-shell/tests/walletStore.test.ts +++ b/apps/ai-game-creator-shell/tests/walletStore.test.ts @@ -246,6 +246,35 @@ describe('useWalletStore', () => { }); }); + test('keeps ledger loading independent from the recharge lifecycle', async () => { + let resolveLedger!: (value: { entries: [] }) => void; + clientApi.getClientProfileRechargeCenter.mockResolvedValue({ + walletBalance: 18, + mudPointBalance: detailedBalance(18), + }); + clientApi.getClientProfileWalletLedger.mockImplementation( + () => + new Promise((resolve) => { + resolveLedger = resolve; + }), + ); + const { result } = renderHook(() => useAccountWallet('user-a')); + await act(async () => undefined); + + act(() => { + result.current.openWalletLedger(); + result.current.openRecharge(); + }); + expect(result.current.walletLedgerLoading).toBe(true); + + await act(async () => { + resolveLedger({ entries: [] }); + }); + + expect(result.current.walletLedger).toEqual({ entries: [] }); + expect(result.current.walletLedgerLoading).toBe(false); + }); + test('hides account-owned dialogs and data when the account changes', async () => { clientApi.getClientProfileRechargeCenter.mockResolvedValue({ walletBalance: 18,