add lifecycle token for payment
This commit is contained in:
@@ -5378,6 +5378,7 @@ export function WorkspaceLauncher({
|
||||
useState<string | null>(null);
|
||||
const [nativeRechargePayment, setNativeRechargePayment] =
|
||||
useState<PlatformProfileRechargeNativePaymentState | null>(null);
|
||||
const rechargeLifecycleRef = useRef(0);
|
||||
const [launcherNotice, setLauncherNotice] = useState<{
|
||||
title: string;
|
||||
message: string;
|
||||
@@ -6213,20 +6214,30 @@ export function WorkspaceLauncher({
|
||||
}
|
||||
|
||||
async function loadRechargeCenter() {
|
||||
const rechargeLifecycle = rechargeLifecycleRef.current;
|
||||
setRechargeLoading(true);
|
||||
setRechargeError(null);
|
||||
try {
|
||||
applyRechargeCenter(await getClientProfileRechargeCenter());
|
||||
const center = await getClientProfileRechargeCenter();
|
||||
if (rechargeLifecycleRef.current !== rechargeLifecycle) {
|
||||
return;
|
||||
}
|
||||
applyRechargeCenter(center);
|
||||
} catch (error) {
|
||||
setRechargeError(
|
||||
error instanceof Error ? error.message : '读取泥点购买信息失败',
|
||||
);
|
||||
if (rechargeLifecycleRef.current === rechargeLifecycle) {
|
||||
setRechargeError(
|
||||
error instanceof Error ? error.message : '读取泥点购买信息失败',
|
||||
);
|
||||
}
|
||||
} finally {
|
||||
setRechargeLoading(false);
|
||||
if (rechargeLifecycleRef.current === rechargeLifecycle) {
|
||||
setRechargeLoading(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function openRecharge() {
|
||||
rechargeLifecycleRef.current += 1;
|
||||
setRechargeOpen(true);
|
||||
setRechargeError(null);
|
||||
void loadRechargeCenter();
|
||||
@@ -6236,12 +6247,16 @@ export function WorkspaceLauncher({
|
||||
if (submittingRechargeProductId) {
|
||||
return;
|
||||
}
|
||||
const rechargeLifecycle = rechargeLifecycleRef.current;
|
||||
setSubmittingRechargeProductId(product.productId);
|
||||
setRechargeError(null);
|
||||
try {
|
||||
const response = await createClientProfileRechargeOrder(
|
||||
product.productId,
|
||||
);
|
||||
if (rechargeLifecycleRef.current !== rechargeLifecycle) {
|
||||
return;
|
||||
}
|
||||
applyRechargeCenter(response.center);
|
||||
const nativePayment = response.wechatNativePayment;
|
||||
const codeUrl = nativePayment?.codeUrl?.trim();
|
||||
@@ -6258,9 +6273,13 @@ export function WorkspaceLauncher({
|
||||
isConfirming: false,
|
||||
});
|
||||
} catch (error) {
|
||||
setRechargeError(error instanceof Error ? error.message : '充值失败');
|
||||
if (rechargeLifecycleRef.current === rechargeLifecycle) {
|
||||
setRechargeError(error instanceof Error ? error.message : '充值失败');
|
||||
}
|
||||
} finally {
|
||||
setSubmittingRechargeProductId(null);
|
||||
if (rechargeLifecycleRef.current === rechargeLifecycle) {
|
||||
setSubmittingRechargeProductId(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6268,6 +6287,7 @@ export function WorkspaceLauncher({
|
||||
if (!nativeRechargePayment || nativeRechargePayment.isConfirming) {
|
||||
return;
|
||||
}
|
||||
const rechargeLifecycle = rechargeLifecycleRef.current;
|
||||
const orderId = nativeRechargePayment.orderId;
|
||||
setNativeRechargePayment((current) =>
|
||||
current?.orderId === orderId
|
||||
@@ -6276,6 +6296,9 @@ export function WorkspaceLauncher({
|
||||
);
|
||||
try {
|
||||
const response = await confirmClientWechatProfileRechargeOrder(orderId);
|
||||
if (rechargeLifecycleRef.current !== rechargeLifecycle) {
|
||||
return;
|
||||
}
|
||||
applyRechargeCenter(response.center);
|
||||
if (response.order.status === 'paid') {
|
||||
setNativeRechargePayment(null);
|
||||
@@ -6293,15 +6316,17 @@ export function WorkspaceLauncher({
|
||||
: current,
|
||||
);
|
||||
} catch {
|
||||
setNativeRechargePayment((current) =>
|
||||
current?.orderId === orderId
|
||||
? {
|
||||
...current,
|
||||
isConfirming: false,
|
||||
confirmMessage: '暂时没能确认到账状态,请稍后再试。',
|
||||
}
|
||||
: current,
|
||||
);
|
||||
if (rechargeLifecycleRef.current === rechargeLifecycle) {
|
||||
setNativeRechargePayment((current) =>
|
||||
current?.orderId === orderId
|
||||
? {
|
||||
...current,
|
||||
isConfirming: false,
|
||||
confirmMessage: '暂时没能确认到账状态,请稍后再试。',
|
||||
}
|
||||
: current,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9400,8 +9425,10 @@ export function WorkspaceLauncher({
|
||||
submittingProductId={submittingRechargeProductId}
|
||||
nativePayment={nativeRechargePayment}
|
||||
onClose={() => {
|
||||
rechargeLifecycleRef.current += 1;
|
||||
setRechargeOpen(false);
|
||||
setNativeRechargePayment(null);
|
||||
setSubmittingRechargeProductId(null);
|
||||
}}
|
||||
onRetry={() => void loadRechargeCenter()}
|
||||
onBuy={(product) => void buyRechargeProduct(product)}
|
||||
|
||||
@@ -1565,6 +1565,8 @@ describe('AI 游戏创作 App 界面边界', () => {
|
||||
latestOrder: null,
|
||||
hasPointsRecharged: true,
|
||||
};
|
||||
let rechargeOrderRequestCount = 0;
|
||||
let releaseLateRechargeOrder: (() => void) | null = null;
|
||||
const fetchSpy = vi
|
||||
.spyOn(globalThis, 'fetch')
|
||||
.mockImplementation(async (input: RequestInfo | URL) => {
|
||||
@@ -1578,6 +1580,12 @@ describe('AI 游戏创作 App 界面边界', () => {
|
||||
return new Response(JSON.stringify(rechargeCenter), { status: 200 });
|
||||
}
|
||||
if (url === '/api/profile/recharge/orders') {
|
||||
rechargeOrderRequestCount += 1;
|
||||
if (rechargeOrderRequestCount === 2) {
|
||||
await new Promise<void>((resolve) => {
|
||||
releaseLateRechargeOrder = resolve;
|
||||
});
|
||||
}
|
||||
return new Response(
|
||||
JSON.stringify({
|
||||
order: {
|
||||
@@ -1676,6 +1684,24 @@ describe('AI 游戏创作 App 界面边界', () => {
|
||||
expect(screen.queryByRole('dialog', { name: '微信扫码支付' })).toBeNull();
|
||||
});
|
||||
expect(screen.getByText('当前余额 180 泥点')).not.toBeNull();
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: /60泥点.*购买/ }));
|
||||
await waitFor(() => {
|
||||
expect(rechargeOrderRequestCount).toBe(2);
|
||||
});
|
||||
fireEvent.click(
|
||||
screen.getByRole('button', { name: '关闭购买更多泥点' }),
|
||||
);
|
||||
await act(async () => {
|
||||
releaseLateRechargeOrder?.();
|
||||
});
|
||||
fireEvent.click(screen.getByRole('button', { name: '充值' }));
|
||||
expect(
|
||||
await screen.findByRole('dialog', { name: '购买更多泥点' }),
|
||||
).not.toBeNull();
|
||||
expect(
|
||||
screen.queryByRole('dialog', { name: '微信扫码支付' }),
|
||||
).toBeNull();
|
||||
});
|
||||
|
||||
it('opens the help notice and account menu from the sidebar', () => {
|
||||
|
||||
Reference in New Issue
Block a user