feat(ticket): 添加票券自动重试加载功能
- 引入 ticketAutoRetryCountRef 和 ticketAutoRetryTimerRef 引用计数器 - 实现购买票券后异步重试刷新逻辑,最多重试4次 - 添加延迟重试机制,间隔时间分别为800ms、1500ms、2500ms、4000ms - 在页面显示时重置重试计数器并清除现有定时器 - 添加清理函数确保组件卸载时清除定时器 - 当检测到可用票券时不进行重试并重置计数器
This commit is contained in:
@@ -75,6 +75,8 @@ const OrderConfirm = () => {
|
|||||||
const [ticketLoading, setTicketLoading] = useState(false)
|
const [ticketLoading, setTicketLoading] = useState(false)
|
||||||
const [ticketLoaded, setTicketLoaded] = useState(false)
|
const [ticketLoaded, setTicketLoaded] = useState(false)
|
||||||
const noTicketPromptedRef = useRef(false)
|
const noTicketPromptedRef = useRef(false)
|
||||||
|
const ticketAutoRetryCountRef = useRef(0)
|
||||||
|
const ticketAutoRetryTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)
|
||||||
|
|
||||||
// Delivery range (geofence): block ordering if address/current location is outside.
|
// Delivery range (geofence): block ordering if address/current location is outside.
|
||||||
const [fences, setFences] = useState<ShopStoreFence[]>([])
|
const [fences, setFences] = useState<ShopStoreFence[]>([])
|
||||||
@@ -207,6 +209,39 @@ const OrderConfirm = () => {
|
|||||||
return !!userId && ticketLoaded && !ticketLoading && usableTickets.length === 0
|
return !!userId && ticketLoaded && !ticketLoading && usableTickets.length === 0
|
||||||
}, [ticketLoaded, ticketLoading, usableTickets.length, userId])
|
}, [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 maxQuantity = useMemo(() => {
|
||||||
const stockMax = goods?.stock ?? 999
|
const stockMax = goods?.stock ?? 999
|
||||||
if (!isEditMode) return Math.max(0, Math.min(stockMax, availableTicketTotal))
|
if (!isEditMode) return Math.max(0, Math.min(stockMax, availableTicketTotal))
|
||||||
@@ -784,6 +819,11 @@ const OrderConfirm = () => {
|
|||||||
useDidShow(() => {
|
useDidShow(() => {
|
||||||
// 返回/切换到该页面时,刷新一下当前已选门店
|
// 返回/切换到该页面时,刷新一下当前已选门店
|
||||||
setSelectedStore(getSelectedStoreFromStorage())
|
setSelectedStore(getSelectedStoreFromStorage())
|
||||||
|
ticketAutoRetryCountRef.current = 0
|
||||||
|
if (ticketAutoRetryTimerRef.current) {
|
||||||
|
clearTimeout(ticketAutoRetryTimerRef.current)
|
||||||
|
ticketAutoRetryTimerRef.current = null
|
||||||
|
}
|
||||||
loadAllData({ silent: hasInitialLoadedRef.current })
|
loadAllData({ silent: hasInitialLoadedRef.current })
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user