This commit is contained in:
eric
2026-03-16 20:08:21 -05:00
parent e30d4ad950
commit c93eb7b2ee
11 changed files with 314 additions and 211 deletions

View File

@@ -0,0 +1,64 @@
"use client";
import { useEffect, useRef } from "react";
import { tryCompleteOrder, applyCompleteSuccess } from "@/app/lib/complete-order";
const DEFAULT_RETRY_DELAYS = [1500, 2500, 3500, 4500, 5500];
export interface UseCompleteOrderPollingOptions {
/** 待完成订单 IDnull 则不轮询 */
orderId: string | null;
/** 成功后的额外回调(用 ref 存储避免 deps 变化) */
onSuccess?: (data: { token: string; record?: { wechatId?: string } }) => void;
/** 重试间隔(毫秒) */
retryDelays?: number[];
}
/** 清除 pending order 的 cookie 和 localStorage */
export function clearPendingOrder(): void {
try {
localStorage.removeItem("join_pay_order");
} catch {
/* ignore */
}
document.cookie = "join_pay_order=; path=/; max-age=0";
}
/** 支付完成后轮询 complete-order成功后同步 session 并清除 pending */
export function useCompleteOrderPolling({
orderId,
onSuccess,
retryDelays = DEFAULT_RETRY_DELAYS,
}: UseCompleteOrderPollingOptions): void {
const onSuccessRef = useRef(onSuccess);
onSuccessRef.current = onSuccess;
useEffect(() => {
if (!orderId || typeof window === "undefined") return;
let cancelled = false;
const run = async () => {
for (let i = 0; i <= retryDelays.length; i++) {
if (cancelled) return;
const result = await tryCompleteOrder(orderId);
if (result.ok) {
if (result.token && result.record) {
applyCompleteSuccess({ token: result.token, record: result.record });
} else if (result.record) {
applyCompleteSuccess({ token: "", record: result.record });
}
clearPendingOrder();
onSuccessRef.current?.({ token: result.token || "", record: result.record });
return;
}
if (i < retryDelays.length && !cancelled) {
await new Promise((r) => setTimeout(r, retryDelays[i]));
}
}
};
void run();
return () => {
cancelled = true;
};
}, [orderId, retryDelays]);
}