feat(ticket): 添加支付后自动刷新水票列表功能

- 在订单确认页面跳转到水票列表时添加时间戳参数
- 在水票列表页面添加支付后自动刷新逻辑
- 使用 ref 防止重复执行自动刷新
- 添加缓存键避免重复处理同一支付请求
- 支付后自动重试刷新水票列表三次,确保数据同步
- 实现了防抖机制防止并发刷新操作
This commit is contained in:
2026-03-11 18:51:23 +08:00
parent 0628a0f6b4
commit 4a45bc5242
2 changed files with 57 additions and 21 deletions

View File

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

View File

@@ -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<GltUserTicket[]>([]);
@@ -47,6 +48,25 @@ const UserTicketList = () => {
const [qrVisible, setQrVisible] = useState(false);
const [qrTicket, setQrTicket] = useState<GltUserTicket | null>(null);
const [qrImageUrl, setQrImageUrl] = useState('');
const payAutoRefreshRunningRef = useRef(false);
const sleep = (ms: number) => new Promise<void>((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 (