修复钱包旧快照吞掉终态刷新
为钱包快照绑定请求发起时的 owner 生命周期与 invalidation 版本 拒绝过期普通 GET 快照覆盖余额或中止更新刷新 同步主站与 AI Game Creator 调用方及竞态回归测试 更新账户与充值基线约束
This commit is contained in:
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user