From 4a45bc52428b741cedd0cbbf8cd318e7e816c178 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 18:51:23 +0800 Subject: [PATCH] =?UTF-8?q?feat(ticket):=20=E6=B7=BB=E5=8A=A0=E6=94=AF?= =?UTF-8?q?=E4=BB=98=E5=90=8E=E8=87=AA=E5=8A=A8=E5=88=B7=E6=96=B0=E6=B0=B4?= =?UTF-8?q?=E7=A5=A8=E5=88=97=E8=A1=A8=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在订单确认页面跳转到水票列表时添加时间戳参数 - 在水票列表页面添加支付后自动刷新逻辑 - 使用 ref 防止重复执行自动刷新 - 添加缓存键避免重复处理同一支付请求 - 支付后自动重试刷新水票列表三次,确保数据同步 - 实现了防抖机制防止并发刷新操作 --- src/shop/orderConfirm/index.tsx | 14 ++++---- src/user/ticket/index.tsx | 64 +++++++++++++++++++++++++-------- 2 files changed, 57 insertions(+), 21 deletions(-) diff --git a/src/shop/orderConfirm/index.tsx b/src/shop/orderConfirm/index.tsx index 003e473..ca9f7fa 100644 --- a/src/shop/orderConfirm/index.tsx +++ b/src/shop/orderConfirm/index.tsx @@ -507,6 +507,7 @@ const OrderConfirm = () => { await PaymentHandler.pay(updatedOrderData, currentPaymentType, hasTicketTemplate ? { onSuccess: async () => { const id = goods.goodsId + const ticketIndexUrl = `/user/ticket/index?fromPayAt=${Date.now()}` try { const res = await Taro.showModal({ title: '提示', @@ -518,13 +519,13 @@ const OrderConfirm = () => { if (id) { await Taro.redirectTo({ url: `/user/ticket/use?goodsId=${id}` }) } else { - await Taro.redirectTo({ url: '/user/ticket/index' }) + await Taro.redirectTo({ url: ticketIndexUrl }) } } else { - await Taro.redirectTo({ url: '/user/ticket/index' }) + await Taro.redirectTo({ url: ticketIndexUrl }) } } catch (_e) { - await Taro.redirectTo({ url: '/user/ticket/index' }) + await Taro.redirectTo({ url: ticketIndexUrl }) } return false } @@ -583,6 +584,7 @@ const OrderConfirm = () => { await PaymentHandler.pay(orderData, paymentType, hasTicketTemplate ? { onSuccess: async () => { const id = goods.goodsId + const ticketIndexUrl = `/user/ticket/index?fromPayAt=${Date.now()}` try { const res = await Taro.showModal({ title: '提示', @@ -594,13 +596,13 @@ const OrderConfirm = () => { if (id) { await Taro.redirectTo({ url: `/user/ticket/use?goodsId=${id}` }) } else { - await Taro.redirectTo({ url: '/user/ticket/index' }) + await Taro.redirectTo({ url: ticketIndexUrl }) } } else { - await Taro.redirectTo({ url: '/user/ticket/index' }) + await Taro.redirectTo({ url: ticketIndexUrl }) } } catch (_e) { - await Taro.redirectTo({ url: '/user/ticket/index' }) + await Taro.redirectTo({ url: ticketIndexUrl }) } return false } diff --git a/src/user/ticket/index.tsx b/src/user/ticket/index.tsx index bc94a3e..d2e9b92 100644 --- a/src/user/ticket/index.tsx +++ b/src/user/ticket/index.tsx @@ -1,4 +1,4 @@ -import { useState } from 'react'; +import { useRef, useState } from 'react'; import Taro, { useDidShow } from '@tarojs/taro'; import { Button, @@ -23,6 +23,7 @@ import dayjs from "dayjs"; import { ensureLoggedIn } from '@/utils/auth'; const PAGE_SIZE = 10; +const PAY_REFRESH_HANDLED_KEY = 'user_ticket_from_pay_at_handled'; const UserTicketList = () => { const [ticketList, setTicketList] = useState([]); @@ -47,6 +48,25 @@ const UserTicketList = () => { const [qrVisible, setQrVisible] = useState(false); const [qrTicket, setQrTicket] = useState(null); const [qrImageUrl, setQrImageUrl] = useState(''); + const payAutoRefreshRunningRef = useRef(false); + + const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)); + + const parsePositiveNumberParam = (v: unknown) => { + const n = Number(v); + return Number.isFinite(n) && n > 0 ? n : undefined; + }; + + const getFromPayAtParam = () => { + const params = Taro.getCurrentInstance().router?.params; + return parsePositiveNumberParam((params as any)?.fromPayAt); + }; + + const shouldAutoRefreshAfterPay = (fromPayAt?: number) => { + if (!fromPayAt) return false; + const handled = parsePositiveNumberParam(Taro.getStorageSync(PAY_REFRESH_HANDLED_KEY)) || 0; + return handled !== fromPayAt; + }; const getUserId = () => { const raw = Taro.getStorageSync('UserId'); @@ -530,22 +550,36 @@ const UserTicketList = () => { } useDidShow(() => { - const tabParam = Taro.getCurrentInstance().router?.params?.tab - const nextTab = - tabParam === 'ticket' || tabParam === 'order' - ? tabParam - : undefined + void (async () => { + const tabParam = Taro.getCurrentInstance().router?.params?.tab; + const nextTab = tabParam === 'ticket' || tabParam === 'order' ? tabParam : undefined; - if (nextTab && nextTab !== activeTab) { - setActiveTab(nextTab) - } + if (nextTab && nextTab !== activeTab) { + setActiveTab(nextTab); + } - const tabToLoad = nextTab || activeTab - if (tabToLoad === 'ticket') { - reloadTickets(true).then() - } else { - reloadOrders(true).then() - } + const tabToLoad = nextTab || activeTab; + if (tabToLoad === 'ticket') { + await reloadTickets(true); + + const fromPayAt = getFromPayAtParam(); + if (shouldAutoRefreshAfterPay(fromPayAt) && !payAutoRefreshRunningRef.current) { + payAutoRefreshRunningRef.current = true; + try { + Taro.setStorageSync(PAY_REFRESH_HANDLED_KEY, fromPayAt); + // 支付后水票可能异步入账:自动再刷新几次,避免用户手动下拉刷新。 + for (const delayMs of [800, 1500, 2500]) { + await sleep(delayMs); + await reloadTickets(true); + } + } finally { + payAutoRefreshRunningRef.current = false; + } + } + } else { + await reloadOrders(true); + } + })(); }) return (