From 0628a0f6b415a2b198e1a44ae998c3dc5c2190cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B5=E5=BF=A0=E6=9E=97?= <170083662@qq.com> Date: Wed, 11 Mar 2026 17:33:33 +0800 Subject: [PATCH] =?UTF-8?q?feat(ticket):=20=E6=B7=BB=E5=8A=A0=E7=A5=A8?= =?UTF-8?q?=E5=88=B8=E8=87=AA=E5=8A=A8=E9=87=8D=E8=AF=95=E5=8A=A0=E8=BD=BD?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 引入 ticketAutoRetryCountRef 和 ticketAutoRetryTimerRef 引用计数器 - 实现购买票券后异步重试刷新逻辑,最多重试4次 - 添加延迟重试机制,间隔时间分别为800ms、1500ms、2500ms、4000ms - 在页面显示时重置重试计数器并清除现有定时器 - 添加清理函数确保组件卸载时清除定时器 - 当检测到可用票券时不进行重试并重置计数器 --- src/user/ticket/use.tsx | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/user/ticket/use.tsx b/src/user/ticket/use.tsx index 9708278..4a755af 100644 --- a/src/user/ticket/use.tsx +++ b/src/user/ticket/use.tsx @@ -75,6 +75,8 @@ const OrderConfirm = () => { const [ticketLoading, setTicketLoading] = useState(false) const [ticketLoaded, setTicketLoaded] = useState(false) const noTicketPromptedRef = useRef(false) + const ticketAutoRetryCountRef = useRef(0) + const ticketAutoRetryTimerRef = useRef | null>(null) // Delivery range (geofence): block ordering if address/current location is outside. const [fences, setFences] = useState([]) @@ -207,6 +209,39 @@ const OrderConfirm = () => { return !!userId && ticketLoaded && !ticketLoading && usableTickets.length === 0 }, [ticketLoaded, ticketLoading, usableTickets.length, userId]) + // After buying tickets and redirecting here, some backends may issue tickets asynchronously. + // If opened with a `goodsId`, retry a few times to refresh tickets. + useEffect(() => { + if (isEditMode) return + if (!numericGoodsId) return + if (!ticketLoaded || ticketLoading) return + + if (usableTickets.length > 0) { + ticketAutoRetryCountRef.current = 0 + return + } + + if (ticketAutoRetryCountRef.current >= 4) return + if (ticketAutoRetryTimerRef.current) return + + const delays = [800, 1500, 2500, 4000] + const delay = delays[ticketAutoRetryCountRef.current] ?? 2500 + ticketAutoRetryCountRef.current += 1 + ticketAutoRetryTimerRef.current = setTimeout(async () => { + ticketAutoRetryTimerRef.current = null + await loadUserTickets() + }, delay) + }, [isEditMode, numericGoodsId, ticketLoaded, ticketLoading, usableTickets.length]) + + useEffect(() => { + return () => { + if (ticketAutoRetryTimerRef.current) { + clearTimeout(ticketAutoRetryTimerRef.current) + ticketAutoRetryTimerRef.current = null + } + } + }, []) + const maxQuantity = useMemo(() => { const stockMax = goods?.stock ?? 999 if (!isEditMode) return Math.max(0, Math.min(stockMax, availableTicketTotal)) @@ -784,6 +819,11 @@ const OrderConfirm = () => { useDidShow(() => { // 返回/切换到该页面时,刷新一下当前已选门店 setSelectedStore(getSelectedStoreFromStorage()) + ticketAutoRetryCountRef.current = 0 + if (ticketAutoRetryTimerRef.current) { + clearTimeout(ticketAutoRetryTimerRef.current) + ticketAutoRetryTimerRef.current = null + } loadAllData({ silent: hasInitialLoadedRef.current }) })