修复钱包旧快照吞掉终态刷新

为钱包快照绑定请求发起时的 owner 生命周期与 invalidation 版本
拒绝过期普通 GET 快照覆盖余额或中止更新刷新
同步主站与 AI Game Creator 调用方及竞态回归测试
更新账户与充值基线约束
This commit is contained in:
2026-08-06 10:35:25 +08:00
parent 6300ba55f7
commit 2bb52ef915
7 changed files with 176 additions and 60 deletions
@@ -596,15 +596,20 @@ describe('ImageCanvasEditorView', () => {
it('shows the live mud point balance in the canvas topbar when logged in', async () => {
usePlatformWalletStore.getState().setWalletOwner('user-1');
usePlatformWalletStore.getState().applyWalletBalanceSnapshot('user-1', {
totalPoints: 1234,
permanentPoints: 1000,
limitedPoints: 214,
limitedExpiresAt: '2026-07-31T16:00:00Z',
dailyFreePoints: 20,
dailyFreeResetPoints: 20,
dailyFreeResetsAt: '2026-07-12T16:00:00Z',
});
const walletSnapshot = usePlatformWalletStore
.getState()
.captureWalletBalanceSnapshot('user-1');
usePlatformWalletStore
.getState()
.applyWalletBalanceSnapshot(walletSnapshot!, {
totalPoints: 1234,
permanentPoints: 1000,
limitedPoints: 214,
limitedExpiresAt: '2026-07-31T16:00:00Z',
dailyFreePoints: 20,
dailyFreeResetPoints: 20,
dailyFreeResetsAt: '2026-07-12T16:00:00Z',
});
render(
<AuthUiContext.Provider
value={createAuthValue({
@@ -668,15 +673,20 @@ describe('ImageCanvasEditorView', () => {
it('opens the shared wallet breakdown and ledger from the canvas topbar', async () => {
const user = userEvent.setup();
usePlatformWalletStore.getState().setWalletOwner('user-1');
usePlatformWalletStore.getState().applyWalletBalanceSnapshot('user-1', {
totalPoints: 1234,
permanentPoints: 1000,
limitedPoints: 0,
limitedExpiresAt: null,
dailyFreePoints: 234,
dailyFreeResetPoints: 20,
dailyFreeResetsAt: '2026-07-12T16:00:00Z',
});
const walletSnapshot = usePlatformWalletStore
.getState()
.captureWalletBalanceSnapshot('user-1');
usePlatformWalletStore
.getState()
.applyWalletBalanceSnapshot(walletSnapshot!, {
totalPoints: 1234,
permanentPoints: 1000,
limitedPoints: 0,
limitedExpiresAt: null,
dailyFreePoints: 234,
dailyFreeResetPoints: 20,
dailyFreeResetsAt: '2026-07-12T16:00:00Z',
});
render(
<AuthUiContext.Provider
value={createAuthValue({
@@ -61,11 +61,7 @@ type WechatPayResult = {
};
type RechargePaymentResultKind =
| 'success'
| 'pending'
| 'cancel'
| 'failed'
| 'expired';
'success' | 'pending' | 'cancel' | 'failed' | 'expired';
export type RechargePaymentResult = {
kind: RechargePaymentResultKind;
@@ -369,6 +365,9 @@ export function usePlatformProfileCenterController({
const applyWalletBalanceSnapshot = usePlatformWalletStore(
(state) => state.applyWalletBalanceSnapshot,
);
const captureWalletBalanceSnapshot = usePlatformWalletStore(
(state) => state.captureWalletBalanceSnapshot,
);
const onWalletBalanceMayHaveChanged = usePlatformWalletStore(
(state) => state.onWalletBalanceMayHaveChanged,
);
@@ -402,8 +401,9 @@ export function usePlatformProfileCenterController({
setRewardCodeSuccess(null);
setIsSubmittingReferralRedeem(false);
}, [currentUserId]);
const rechargeCenterReadAbortControllerRef =
useRef<AbortController | null>(null);
const rechargeCenterReadAbortControllerRef = useRef<AbortController | null>(
null,
);
useEffect(() => {
return () => {
@@ -480,7 +480,11 @@ export function usePlatformProfileCenterController({
}, [loadWalletLedger]);
const applyRechargeCenter = useCallback(
(center: ProfileRechargeCenterResponse, refreshWallet = false) => {
(
center: ProfileRechargeCenterResponse,
refreshWallet = false,
walletSnapshot = captureWalletBalanceSnapshot(currentUserId),
) => {
if (
!currentUserId ||
usePlatformWalletStore.getState().ownerUserId !== currentUserId
@@ -493,8 +497,8 @@ export function usePlatformProfileCenterController({
setIsLoadingRechargeCenter(false);
setRechargeError(null);
setRechargeCenter(center);
if (center.mudPointBalance) {
applyWalletBalanceSnapshot(currentUserId, center.mudPointBalance);
if (center.mudPointBalance && walletSnapshot) {
applyWalletBalanceSnapshot(walletSnapshot, center.mudPointBalance);
}
if (refreshWallet || !center.mudPointBalance) {
void onWalletBalanceMayHaveChanged();
@@ -503,12 +507,14 @@ export function usePlatformProfileCenterController({
},
[
applyWalletBalanceSnapshot,
captureWalletBalanceSnapshot,
currentUserId,
onWalletBalanceMayHaveChanged,
],
);
const loadRechargeCenter = useCallback(() => {
const walletSnapshot = captureWalletBalanceSnapshot(currentUserId);
const revision = ++rechargeCenterReadRevisionRef.current;
rechargeCenterReadAbortControllerRef.current?.abort();
const abortController = new AbortController();
@@ -521,7 +527,7 @@ export function usePlatformProfileCenterController({
!abortController.signal.aborted &&
revision === rechargeCenterReadRevisionRef.current
) {
applyRechargeCenter(center);
applyRechargeCenter(center, false, walletSnapshot);
}
})
.catch((error: unknown) => {
@@ -544,7 +550,7 @@ export function usePlatformProfileCenterController({
setIsLoadingRechargeCenter(false);
}
});
}, [applyRechargeCenter]);
}, [applyRechargeCenter, captureWalletBalanceSnapshot, currentUserId]);
const refreshRechargeState = useCallback(() => {
loadRechargeCenter();