修改订单查询接口逻辑、前台页面增加刷新页面订单消失问题,调整后台支付账单页面数据问题

This commit is contained in:
2026-06-11 13:51:46 +08:00
parent cace26018a
commit 1b7b794164
4 changed files with 134 additions and 15 deletions
@@ -27,7 +27,7 @@ import {
} from '@ant-design/icons';
import { Outlet, useNavigate, useLocation } from 'react-router-dom';
import { useAuthStore } from '../../store/useAuthStore';
import { getMenuConfigs, getRechargePackages, getPaymentMethods, createRechargeOrder, getPaymentOrders, cancelPaymentOrder, getNotifications, markNotificationRead, getSiteInfo } from '../../api';
import { getMenuConfigs, getRechargePackages, getPaymentMethods, createRechargeOrder, getPaymentOrder, cancelPaymentOrder, getNotifications, markNotificationRead, getSiteInfo } from '../../api';
import NotificationPopup from '../NotificationPopup';
interface MenuConfig {
@@ -97,6 +97,9 @@ const AppLayout: React.FC = () => {
const countdownTimerRef = useRef<ReturnType<typeof setInterval> | null>(null);
const currentOrderNoRef = useRef<string | null>(null);
const [enabledMethods, setEnabledMethods] = useState<{ alipay: boolean; wechat: boolean }>({ alipay: false, wechat: false });
// LocalStorage keys
const PENDING_ORDER_KEY = 'pending_payment_order';
// 监听预览弹窗状态,关闭浮动按钮
useEffect(() => {
@@ -122,6 +125,57 @@ const AppLayout: React.FC = () => {
}).catch(() => {});
};
// 检查并恢复待处理的支付订单
useEffect(() => {
const checkPendingOrder = async () => {
const savedOrderStr = localStorage.getItem(PENDING_ORDER_KEY);
if (savedOrderStr) {
try {
const savedOrder = JSON.parse(savedOrderStr);
// 查询订单状态
const order = await getPaymentOrder(savedOrder.orderNo);
if (order.status === 'pending') {
// 订单仍然待支付,恢复弹窗
setCurrentPaymentInfo({
price: savedOrder.price,
credits: savedOrder.credits,
qrCode: savedOrder.qrCode,
method: savedOrder.method,
});
currentOrderNoRef.current = savedOrder.orderNo;
// 计算剩余时间
const now = Date.now();
const createdAt = new Date(savedOrder.createdAt).getTime();
const timeoutSeconds = savedOrder.timeoutSeconds || 180;
const elapsedSeconds = Math.floor((now - createdAt) / 1000);
const remainingSeconds = Math.max(0, timeoutSeconds - elapsedSeconds);
if (remainingSeconds > 0) {
setQrCodeModalOpen(true);
startPolling(savedOrder.orderNo, remainingSeconds);
} else {
// 已超时,清除
localStorage.removeItem(PENDING_ORDER_KEY);
}
} else if (order.status === 'paid') {
// 已支付
message.success('支付成功!积分已到账');
useAuthStore.getState().refreshUser();
localStorage.removeItem(PENDING_ORDER_KEY);
} else {
// 订单已取消或其他状态,清除
localStorage.removeItem(PENDING_ORDER_KEY);
}
} catch {
// 查询失败,清除
localStorage.removeItem(PENDING_ORDER_KEY);
}
}
};
checkPendingOrder();
}, []);
useEffect(() => {
getMenuConfigs().then(data => {
let items = data.filter((m: any) => m.is_active !== false && m.isActive !== false);
@@ -202,22 +256,23 @@ const AppLayout: React.FC = () => {
stopPolling();
setCountdown(timeoutSeconds);
// 订单状态轮询(每2秒查询一次,减少请求频率
// 订单状态轮询(每2秒查询一次,只查询当前订单
const pollingTimer = setInterval(async () => {
try {
const orders = await getPaymentOrders();
const order = orders.find((o: any) => o.orderNo === orderNo);
if (order && order.status === 'paid') {
const order = await getPaymentOrder(orderNo);
if (order.status === 'paid') {
stopPolling();
currentOrderNoRef.current = null;
localStorage.removeItem(PENDING_ORDER_KEY);
message.success('支付成功!积分已到账');
useAuthStore.getState().refreshUser();
setQrCodeModalOpen(false);
setCurrentPaymentInfo(null);
setSelectedPlan(null);
} else if (order && order.status === 'cancelled') {
} else if (order.status === 'cancelled') {
stopPolling();
currentOrderNoRef.current = null;
localStorage.removeItem(PENDING_ORDER_KEY);
}
} catch {
// ignore polling errors
@@ -235,6 +290,7 @@ const AppLayout: React.FC = () => {
cancelPaymentOrder(currentOrderNoRef.current).catch(() => {});
currentOrderNoRef.current = null;
}
localStorage.removeItem(PENDING_ORDER_KEY);
message.warning('订单已超时,请重新充值');
setQrCodeModalOpen(false);
setCurrentPaymentInfo(null);
@@ -639,15 +695,28 @@ const AppLayout: React.FC = () => {
const order = await createRechargeOrder(plan.id, paymentMethod);
if (order.paymentMethod === 'alipay' && order.qrUrl) {
// Alipay: show the real QR code URL from the backend
setCurrentPaymentInfo({
const paymentInfo = {
price: plan.price,
credits: totalCredits,
qrCode: order.qrUrl,
method: 'alipay',
});
};
setCurrentPaymentInfo(paymentInfo);
setRechargeModalOpen(false);
setQrCodeModalOpen(true);
currentOrderNoRef.current = order.orderNo;
// 保存到 localStorage
localStorage.setItem(PENDING_ORDER_KEY, JSON.stringify({
orderNo: order.orderNo,
price: plan.price,
credits: totalCredits,
qrCode: order.qrUrl,
method: 'alipay',
createdAt: order.createdAt || new Date().toISOString(),
timeoutSeconds: 180,
}));
// Start polling for payment status
startPolling(order.orderNo);
} else {
@@ -684,6 +753,7 @@ const AppLayout: React.FC = () => {
try { await cancelPaymentOrder(currentOrderNoRef.current); } catch {}
currentOrderNoRef.current = null;
}
localStorage.removeItem(PENDING_ORDER_KEY);
setQrCodeModalOpen(false);
setCurrentPaymentInfo(null);
}}
@@ -809,6 +879,7 @@ const AppLayout: React.FC = () => {
try { await cancelPaymentOrder(currentOrderNoRef.current); } catch {}
currentOrderNoRef.current = null;
}
localStorage.removeItem(PENDING_ORDER_KEY);
setQrCodeModalOpen(false);
setCurrentPaymentInfo(null);
setSelectedPlan(null);