🍭feat: add loading states to all async operation buttons for better UX

- Add paymentLoading state for Alipay and WeChat payment buttons
- Add confirmLoading state for payment confirmation modal
- Implement proper loading management in preTopUp function with try-catch error handling
- Implement proper loading management in onlineTopUp function with comprehensive error handling
- Add loading={paymentLoading} to both payment method buttons to prevent double-clicks
- Add confirmLoading={confirmLoading} to modal confirmation button
- Enhance error handling with user-friendly error messages for failed operations
- Ensure loading states are properly cleared in finally blocks for consistent UX

This update provides immediate visual feedback when users interact with payment buttons,
prevents accidental double-clicks, and improves overall payment flow reliability
with comprehensive error handling and loading state management.
This commit is contained in:
Apple\Apple
2025-05-23 19:40:43 +08:00
parent 1660c47db5
commit eb69ada880

View File

@@ -46,6 +46,8 @@ const TopUp = () => {
const [payWay, setPayWay] = useState(''); const [payWay, setPayWay] = useState('');
const [userDataLoading, setUserDataLoading] = useState(true); const [userDataLoading, setUserDataLoading] = useState(true);
const [amountLoading, setAmountLoading] = useState(false); const [amountLoading, setAmountLoading] = useState(false);
const [paymentLoading, setPaymentLoading] = useState(false);
const [confirmLoading, setConfirmLoading] = useState(false);
const getUsername = () => { const getUsername = () => {
if (userState.user) { if (userState.user) {
@@ -121,13 +123,20 @@ const TopUp = () => {
showError(t('管理员未开启在线充值!')); showError(t('管理员未开启在线充值!'));
return; return;
} }
await getAmount(); setPaymentLoading(true);
if (topUpCount < minTopUp) { try {
showError(t('充值数量不能小于') + minTopUp); await getAmount();
return; if (topUpCount < minTopUp) {
showError(t('充值数量不能小于') + minTopUp);
return;
}
setPayWay(payment);
setOpen(true);
} catch (error) {
showError(t('获取金额失败'));
} finally {
setPaymentLoading(false);
} }
setPayWay(payment);
setOpen(true);
}; };
const onlineTopUp = async () => { const onlineTopUp = async () => {
@@ -138,6 +147,7 @@ const TopUp = () => {
showError('充值数量不能小于' + minTopUp); showError('充值数量不能小于' + minTopUp);
return; return;
} }
setConfirmLoading(true);
setOpen(false); setOpen(false);
try { try {
const res = await API.post('/api/user/pay', { const res = await API.post('/api/user/pay', {
@@ -177,6 +187,9 @@ const TopUp = () => {
} }
} catch (err) { } catch (err) {
console.log(err); console.log(err);
showError(t('支付请求失败'));
} finally {
setConfirmLoading(false);
} }
}; };
@@ -268,6 +281,7 @@ const TopUp = () => {
maskClosable={false} maskClosable={false}
size={'small'} size={'small'}
centered={true} centered={true}
confirmLoading={confirmLoading}
> >
<div className="space-y-3 py-4"> <div className="space-y-3 py-4">
<div className="flex justify-between"> <div className="flex justify-between">
@@ -514,6 +528,7 @@ const TopUp = () => {
size="large" size="large"
className="!rounded-lg !bg-blue-500 hover:!bg-blue-600 h-14" className="!rounded-lg !bg-blue-500 hover:!bg-blue-600 h-14"
disabled={!enableOnlineTopUp} disabled={!enableOnlineTopUp}
loading={paymentLoading}
icon={<SiAlipay size={20} />} icon={<SiAlipay size={20} />}
> >
<span className="ml-2">{t('支付宝')}</span> <span className="ml-2">{t('支付宝')}</span>
@@ -527,6 +542,7 @@ const TopUp = () => {
size="large" size="large"
className="!rounded-lg !bg-green-500 hover:!bg-green-600 h-14" className="!rounded-lg !bg-green-500 hover:!bg-green-600 h-14"
disabled={!enableOnlineTopUp} disabled={!enableOnlineTopUp}
loading={paymentLoading}
icon={<SiWechat size={20} />} icon={<SiWechat size={20} />}
> >
<span className="ml-2">{t('微信')}</span> <span className="ml-2">{t('微信')}</span>