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 }) })