Browse Source

🐛 fix(theme): sync theme state between global context and local components

- Replace local isDarkMode state with global useTheme hook in TopUp component
- Replace local isDarkMode state with global useTheme hook in PersonalSetting component
- Remove redundant theme detection useEffect hooks that caused state inconsistency
- Update theme condition checks from isDarkMode to theme === 'dark'
- Fix issue where components showed dark gradients in light mode due to theme state mismatch
- Clean up trailing commas in import statements

This ensures all components stay synchronized with the global theme system managed by HeaderBar's theme toggle button.
Apple\Apple 9 months ago
parent
commit
5d3a6caae5

+ 15 - 40
web/src/components/settings/PersonalSetting.js

@@ -19,6 +19,7 @@ import {
 } from '../../helpers';
 import Turnstile from 'react-turnstile';
 import { UserContext } from '../../context/User';
+import { useTheme } from '../../context/Theme';
 import {
   Avatar,
   Banner,
@@ -39,7 +40,7 @@ import {
   AutoComplete,
   Checkbox,
   Tabs,
-  TabPane,
+  TabPane
 } from '@douyinfe/semi-ui';
 import { IllustrationNoContent, IllustrationNoContentDark } from '@douyinfe/semi-illustrations';
 import {
@@ -53,7 +54,7 @@ import {
   IconKey,
   IconDelete,
   IconChevronDown,
-  IconChevronUp,
+  IconChevronUp
 } from '@douyinfe/semi-icons';
 import { SiTelegram, SiWechat, SiLinux } from 'react-icons/si';
 import { Bell, Shield, Webhook, Globe, Settings, UserPlus, ShieldCheck } from 'lucide-react';
@@ -64,6 +65,7 @@ const PersonalSetting = () => {
   const [userState, userDispatch] = useContext(UserContext);
   let navigate = useNavigate();
   const { t } = useTranslation();
+  const theme = useTheme();
 
   const [inputs, setInputs] = useState({
     wechat_verification_code: '',
@@ -104,33 +106,6 @@ const PersonalSetting = () => {
   });
   const [modelsLoading, setModelsLoading] = useState(true);
   const [showWebhookDocs, setShowWebhookDocs] = useState(true);
-  const [isDarkMode, setIsDarkMode] = useState(false);
-
-  // 检测暗色模式
-  useEffect(() => {
-    const checkDarkMode = () => {
-      const isDark = document.documentElement.classList.contains('dark') || 
-                    window.matchMedia('(prefers-color-scheme: dark)').matches;
-      setIsDarkMode(isDark);
-    };
-
-    checkDarkMode();
-    
-    // 监听主题变化
-    const observer = new MutationObserver(checkDarkMode);
-    observer.observe(document.documentElement, {
-      attributes: true,
-      attributeFilter: ['class']
-    });
-
-    const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
-    mediaQuery.addListener(checkDarkMode);
-
-    return () => {
-      observer.disconnect();
-      mediaQuery.removeListener(checkDarkMode);
-    };
-  }, []);
 
   useEffect(() => {
     let status = localStorage.getItem('status');
@@ -413,7 +388,7 @@ const PersonalSetting = () => {
                 <Card
                   className="!rounded-2xl !border-0 !shadow-lg overflow-hidden"
                   style={{
-                    background: isDarkMode 
+                    background: theme === 'dark'
                       ? 'linear-gradient(135deg, #1e293b 0%, #334155 50%, #475569 100%)'
                       : 'linear-gradient(135deg, #f8fafc 0%, #e2e8f0 50%, #cbd5e1 100%)',
                     position: 'relative'
@@ -444,7 +419,7 @@ const PersonalSetting = () => {
                             {isRoot() ? (
                               <Tag
                                 size='small'
-                                className="!rounded-full bg-gray-100 dark:bg-gray-700 text-gray-600 dark:text-gray-300 border border-gray-200 dark:border-gray-600"
+                                className="!rounded-full bg-gray-100 dark:bg-gray-700 text-gray-600 dark:text-gray-300"
                                 style={{ fontWeight: '500' }}
                               >
                                 {t('超级管理员')}
@@ -452,7 +427,7 @@ const PersonalSetting = () => {
                             ) : isAdmin() ? (
                               <Tag
                                 size='small'
-                                className="!rounded-full bg-gray-50 dark:bg-gray-700 text-gray-600 dark:text-gray-300 border border-gray-200 dark:border-gray-600"
+                                className="!rounded-full bg-gray-50 dark:bg-gray-700 text-gray-600 dark:text-gray-300"
                                 style={{ fontWeight: '500' }}
                               >
                                 {t('管理员')}
@@ -460,7 +435,7 @@ const PersonalSetting = () => {
                             ) : (
                               <Tag
                                 size='small'
-                                className="!rounded-full bg-slate-50 dark:bg-slate-700 text-slate-600 dark:text-slate-300 border border-slate-200 dark:border-slate-600"
+                                className="!rounded-full bg-slate-50 dark:bg-slate-700 text-slate-600 dark:text-slate-300"
                                 style={{ fontWeight: '500' }}
                               >
                                 {t('普通用户')}
@@ -468,7 +443,7 @@ const PersonalSetting = () => {
                             )}
                             <Tag
                               size='small'
-                              className="!rounded-full bg-slate-100 dark:bg-slate-700 text-slate-600 dark:text-slate-300 border border-slate-200 dark:border-slate-600"
+                              className="!rounded-full bg-slate-100 dark:bg-slate-700 text-slate-600 dark:text-slate-300"
                               style={{ fontWeight: '500' }}
                             >
                               ID: {userState?.user?.id}
@@ -737,7 +712,7 @@ const PersonalSetting = () => {
                             shadows='hover'
                           >
                             <div className="flex items-center justify-between">
-                                                              <div className="flex items-center flex-1">
+                              <div className="flex items-center flex-1">
                                 <div className="w-10 h-10 rounded-full bg-slate-100 dark:bg-slate-700 flex items-center justify-center mr-3">
                                   <IconMail size="default" className="text-slate-600 dark:text-slate-300" />
                                 </div>
@@ -1255,11 +1230,11 @@ const PersonalSetting = () => {
                             itemKey='price'
                           >
                             <div className="py-4">
-                                                              <div className="bg-white rounded-xl">
-                                  <div className="flex items-start">
-                                    <div className="w-10 h-10 rounded-full bg-slate-100 flex items-center justify-center mt-1">
-                                      <Shield size={20} className="text-slate-600" />
-                                    </div>
+                              <div className="bg-white rounded-xl">
+                                <div className="flex items-start">
+                                  <div className="w-10 h-10 rounded-full bg-slate-100 flex items-center justify-center mt-1">
+                                    <Shield size={20} className="text-slate-600" />
+                                  </div>
                                   <div className="flex-1">
                                     <div className="flex items-center justify-between">
                                       <div>

+ 0 - 13
web/src/components/table/LogsTable.js

@@ -1,18 +1,5 @@
 import React, { useEffect, useState } from 'react';
 import { useTranslation } from 'react-i18next';
-import {
-  CreditCard,
-  ShoppingCart,
-  Settings,
-  Server,
-  AlertTriangle,
-  HelpCircle,
-  Zap,
-  Play,
-  Clock,
-  Hash,
-  Key
-} from 'lucide-react';
 import {
   API,
   copy,

+ 13 - 2
web/src/i18n/locales/en.json

@@ -837,7 +837,18 @@
   "支付宝": "Alipay",
   "待使用收益": "Proceeds to be used",
   "邀请人数": "Number of people invited",
-  "兑换余额": "Exchange balance",
+  "兑换码充值": "Redemption code recharge",
+  "使用兑换码快速充值": "Use redemption code to quickly recharge",
+  "支付方式": "Payment method",
+  "邀请奖励": "Invite reward",
+  "或输入自定义金额": "Or enter a custom amount",
+  "选择充值额度": "Select recharge amount",
+  "实付": "Actual payment",
+  "快速方便的充值方式": "Quick and convenient recharge method",
+  "邀请好友获得额外奖励": "Invite friends to get additional rewards",
+  "邀请好友注册,好友充值后您可获得相应奖励": "Invite friends to register, and you can get the corresponding reward after the friend recharges",
+  "通过划转功能将奖励额度转入到您的账户余额中": "Transfer the reward amount to your account balance through the transfer function",
+  "邀请的好友越多,获得的奖励越多": "The more friends you invite, the more rewards you will get",
   "在线充值": "Online recharge",
   "充值数量,最低 ": "Recharge quantity, minimum",
   "请选择充值金额": "Please select the recharge amount",
@@ -954,7 +965,7 @@
   "任务ID": "Task ID",
   "周": "week",
   "总计:": "Total:",
-  "划转": "transfer",
+  "划转到余额": "Transfer to balance",
   "可用额度": "Available credit",
   "邀请码:": "Invitation code:",
   "最低": "lowest",

+ 450 - 437
web/src/pages/TopUp/index.js

@@ -6,12 +6,11 @@ import {
   showSuccess,
   renderQuota,
   renderQuotaWithAmount,
-  stringToColor,
   copy,
   getQuotaPerUnit
 } from '../../helpers';
 import {
-  Layout,
+  Avatar,
   Typography,
   Card,
   Button,
@@ -21,24 +20,30 @@ import {
   InputNumber,
   Banner,
   Skeleton,
+  Divider,
 } from '@douyinfe/semi-ui';
-import {
-  IconCreditCard,
-  IconGift,
-  IconPlus,
-  IconLink,
-} from '@douyinfe/semi-icons';
 import { SiAlipay, SiWechat } from 'react-icons/si';
 import { useTranslation } from 'react-i18next';
 import { UserContext } from '../../context/User';
 import { StatusContext } from '../../context/Status/index.js';
+import { useTheme } from '../../context/Theme';
+import {
+  CreditCard,
+  Gift,
+  Link as LinkIcon,
+  Copy,
+  Users,
+  User,
+  Coins
+} from 'lucide-react';
 
-const { Text } = Typography;
+const { Text, Title } = Typography;
 
 const TopUp = () => {
   const { t } = useTranslation();
   const [userState, userDispatch] = useContext(UserContext);
   const [statusState] = useContext(StatusContext);
+  const theme = useTheme();
 
   const [redemptionCode, setRedemptionCode] = useState('');
   const [topUpCode, setTopUpCode] = useState('');
@@ -47,6 +52,7 @@ const TopUp = () => {
   const [topUpCount, setTopUpCount] = useState(statusState?.status?.min_topup || 1);
   const [topUpLink, setTopUpLink] = useState(statusState?.status?.top_up_link || '');
   const [enableOnlineTopUp, setEnableOnlineTopUp] = useState(statusState?.status?.enable_online_topup || false);
+  const [priceRatio, setPriceRatio] = useState(statusState?.status?.price || 1);
   const [userQuota, setUserQuota] = useState(0);
   const [isSubmitting, setIsSubmitting] = useState(false);
   const [open, setOpen] = useState(false);
@@ -55,13 +61,25 @@ const TopUp = () => {
   const [amountLoading, setAmountLoading] = useState(false);
   const [paymentLoading, setPaymentLoading] = useState(false);
   const [confirmLoading, setConfirmLoading] = useState(false);
-  const [isDarkMode, setIsDarkMode] = useState(false);
 
   // 邀请相关状态
   const [affLink, setAffLink] = useState('');
   const [openTransfer, setOpenTransfer] = useState(false);
   const [transferAmount, setTransferAmount] = useState(0);
 
+  // 预设充值额度选项
+  const [presetAmounts, setPresetAmounts] = useState([
+    { value: 5 },
+    { value: 10 },
+    { value: 30 },
+    { value: 50 },
+    { value: 100 },
+    { value: 300 },
+    { value: 500 },
+    { value: 1000 }
+  ]);
+  const [selectedPreset, setSelectedPreset] = useState(null);
+
   const getUsername = () => {
     if (userState.user) {
       return userState.user.username;
@@ -251,38 +269,11 @@ const TopUp = () => {
   };
 
   // 复制邀请链接
-  const handleAffLinkClick = async (e) => {
-    e.target.select();
-    await copy(e.target.value);
+  const handleAffLinkClick = async () => {
+    await copy(affLink);
     showSuccess(t('邀请链接已复制到剪切板'));
   };
 
-  // 检测暗色模式
-  useEffect(() => {
-    const checkDarkMode = () => {
-      const isDark = document.documentElement.classList.contains('dark') || 
-                    window.matchMedia('(prefers-color-scheme: dark)').matches;
-      setIsDarkMode(isDark);
-    };
-
-    checkDarkMode();
-    
-    // 监听主题变化
-    const observer = new MutationObserver(checkDarkMode);
-    observer.observe(document.documentElement, {
-      attributes: true,
-      attributeFilter: ['class']
-    });
-
-    const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
-    mediaQuery.addListener(checkDarkMode);
-
-    return () => {
-      observer.disconnect();
-      mediaQuery.removeListener(checkDarkMode);
-    };
-  }, []);
-
   useEffect(() => {
     if (userState?.user?.id) {
       setUserDataLoading(false);
@@ -300,6 +291,7 @@ const TopUp = () => {
       setTopUpCount(statusState.status.min_topup || 1);
       setTopUpLink(statusState.status.top_up_link || '');
       setEnableOnlineTopUp(statusState.status.enable_online_topup || false);
+      setPriceRatio(statusState.status.price || 1);
     }
   }, [statusState?.status]);
 
@@ -342,432 +334,453 @@ const TopUp = () => {
     setOpenTransfer(false);
   };
 
+  // 选择预设充值额度
+  const selectPresetAmount = (preset) => {
+    setTopUpCount(preset.value);
+    setSelectedPreset(preset.value);
+    setAmount(preset.value * priceRatio);
+  };
+
+  // 格式化大数字显示
+  const formatLargeNumber = (num) => {
+    return num.toString();
+  };
+
   return (
-    <div className="bg-gray-50">
-      <Layout>
-        <Layout.Content>
-          {/* 划转模态框 */}
-          <Modal
-            title={
-              <div className="flex items-center">
-                <IconCreditCard className="mr-2" />
-                {t('请输入要划转的数量')}
-              </div>
-            }
-            visible={openTransfer}
-            onOk={transfer}
-            onCancel={handleTransferCancel}
-            maskClosable={false}
-            size={'small'}
-            centered={true}
-          >
-            <div className="space-y-4 py-4">
-              <div>
-                <Typography.Text strong className="block mb-2">
-                  {t('可用额度')} {renderQuota(userState?.user?.aff_quota)}
-                </Typography.Text>
-                <Input
-                  value={userState?.user?.aff_quota}
-                  disabled={true}
-                  size="large"
-                  className="!rounded-lg"
-                />
-              </div>
-              <div>
-                <Typography.Text strong className="block mb-2">
-                  {t('划转额度')} {renderQuota(transferAmount)}{' '}
-                  {t('最低') + renderQuota(getQuotaPerUnit())}
-                </Typography.Text>
-                <InputNumber
-                  min={0}
-                  value={transferAmount}
-                  onChange={(value) => setTransferAmount(value)}
-                  disabled={false}
-                  size="large"
-                  className="!rounded-lg w-full"
-                />
-              </div>
-            </div>
-          </Modal>
+    <div className="mx-auto">
+      {/* 划转模态框 */}
+      <Modal
+        title={
+          <div className="flex items-center">
+            <CreditCard className="mr-2" size={18} />
+            {t('划转邀请额度')}
+          </div>
+        }
+        visible={openTransfer}
+        onOk={transfer}
+        onCancel={handleTransferCancel}
+        maskClosable={false}
+        size="small"
+        centered
+      >
+        <div className="space-y-4">
+          <div>
+            <Typography.Text strong className="block mb-2">
+              {t('可用邀请额度')}
+            </Typography.Text>
+            <Input
+              value={renderQuota(userState?.user?.aff_quota)}
+              disabled
+              size="large"
+            />
+          </div>
+          <div>
+            <Typography.Text strong className="block mb-2">
+              {t('划转额度')} ({t('最低') + renderQuota(getQuotaPerUnit())})
+            </Typography.Text>
+            <InputNumber
+              min={getQuotaPerUnit()}
+              max={userState?.user?.aff_quota || 0}
+              value={transferAmount}
+              onChange={(value) => setTransferAmount(value)}
+              size="large"
+              className="w-full"
+            />
+          </div>
+        </div>
+      </Modal>
+
+      {/* 充值确认模态框 */}
+      <Modal
+        title={
+          <div className="flex items-center">
+            <CreditCard className="mr-2" size={18} />
+            {t('充值确认')}
+          </div>
+        }
+        visible={open}
+        onOk={onlineTopUp}
+        onCancel={handleCancel}
+        maskClosable={false}
+        size="small"
+        centered
+        confirmLoading={confirmLoading}
+      >
+        <div className="space-y-4">
+          <div className="flex justify-between items-center py-2">
+            <Text strong>{t('充值数量')}:</Text>
+            <Text>{renderQuotaWithAmount(topUpCount)}</Text>
+          </div>
+          <div className="flex justify-between items-center py-2">
+            <Text strong>{t('实付金额')}:</Text>
+            {amountLoading ? (
+              <Skeleton.Title style={{ width: '60px', height: '16px' }} />
+            ) : (
+              <Text type="danger" strong>{renderAmount()}</Text>
+            )}
+          </div>
+          <div className="flex justify-between items-center py-2">
+            <Text strong>{t('支付方式')}:</Text>
+            <Text>
+              {payWay === 'zfb' ? (
+                <div className="flex items-center">
+                  <SiAlipay className="mr-1" size={16} />
+                  {t('支付宝')}
+                </div>
+              ) : (
+                <div className="flex items-center">
+                  <SiWechat className="mr-1" size={16} />
+                  {t('微信')}
+                </div>
+              )}
+            </Text>
+          </div>
+        </div>
+      </Modal>
+
+      <div className="grid grid-cols-1 lg:grid-cols-12 gap-6">
+        {/* 左侧充值区域 */}
+        <div className="lg:col-span-7 space-y-6 w-full">
+          {/* 在线充值卡片 */}
+          <Card
+            className="!rounded-2xl"
+            shadows='always'
+            bordered={false}
+            header={
+              <div className="px-5 py-4 pb-0">
+                <div className="flex items-center justify-between">
+                  <div className="flex items-center">
+                    <Avatar
+                      className="mr-3 shadow-md flex-shrink-0"
+                      color="blue"
+                    >
+                      <CreditCard size={24} />
+                    </Avatar>
+                    <div>
+                      <Title heading={5} style={{ margin: 0 }}>
+                        {t('在线充值')}
+                      </Title>
+                      <Text type="tertiary" className="text-sm">
+                        {t('快速方便的充值方式')}
+                      </Text>
+                    </div>
+                  </div>
 
-          <Modal
-            title={
-              <div className="flex items-center">
-                <IconGift className="mr-2" />
-                {t('充值确认')}
+                  <div className="flex items-center">
+                    {userDataLoading ? (
+                      <Skeleton.Paragraph style={{ width: '120px' }} rows={1} />
+                    ) : (
+                      <Text type="tertiary" className="hidden sm:block">
+                        <div className="flex items-center">
+                          <User size={14} className="mr-1" />
+                          <span className="hidden md:inline">{getUsername()} ({getUserRole()})</span>
+                          <span className="md:hidden">{getUsername()}</span>
+                        </div>
+                      </Text>
+                    )}
+                  </div>
+                </div>
               </div>
             }
-            visible={open}
-            onOk={onlineTopUp}
-            onCancel={handleCancel}
-            maskClosable={false}
-            size={'small'}
-            centered={true}
-            confirmLoading={confirmLoading}
           >
-            <div className="space-y-3 py-4">
-              <div className="flex justify-between">
-                <Text strong>{t('充值数量')}:</Text>
-                <Text>{topUpCount}</Text>
-              </div>
-              <div className="flex justify-between">
-                <Text strong>{t('实付金额')}:</Text>
-                {amountLoading ? (
-                  <Skeleton.Title style={{ width: '60px', height: '16px' }} />
-                ) : (
-                  <Text type="danger">{renderAmount()}</Text>
-                )}
+            <div className="space-y-4">
+              {/* 账户余额信息 */}
+              <div className="grid grid-cols-2 gap-4 mb-2">
+                <Card className="!rounded-2xl">
+                  <Text type="tertiary" className="mb-1">
+                    {t('当前余额')}
+                  </Text>
+                  {userDataLoading ? (
+                    <Skeleton.Title style={{ width: '100px', height: '30px' }} />
+                  ) : (
+                    <div className="text-xl font-semibold mt-2">
+                      {renderQuota(userState?.user?.quota || userQuota)}
+                    </div>
+                  )}
+                </Card>
+                <Card className="!rounded-2xl">
+                  <Text type="tertiary" className="mb-1">
+                    {t('历史消耗')}
+                  </Text>
+                  {userDataLoading ? (
+                    <Skeleton.Title style={{ width: '100px', height: '30px' }} />
+                  ) : (
+                    <div className="text-xl font-semibold mt-2">
+                      {renderQuota(userState?.user?.used_quota || 0)}
+                    </div>
+                  )}
+                </Card>
               </div>
-            </div>
-          </Modal>
-
-          <div className="flex justify-center">
-            <div className="w-full">
-              <Card className="!rounded-2xl shadow-lg border-0">
-                <Card
-                  className="!rounded-2xl !border-0 !shadow-lg overflow-hidden"
-                  style={{
-                    background: isDarkMode 
-                      ? 'linear-gradient(135deg, #1e293b 0%, #334155 50%, #475569 100%)'
-                      : 'linear-gradient(135deg, #f8fafc 0%, #e2e8f0 50%, #cbd5e1 100%)',
-                    position: 'relative'
-                  }}
-                  bodyStyle={{ padding: 0 }}
-                >
-                  <div className="absolute inset-0 overflow-hidden">
-                    <div className="absolute -top-10 -right-10 w-40 h-40 bg-slate-400 opacity-5 rounded-full"></div>
-                    <div className="absolute -bottom-16 -left-16 w-48 h-48 bg-slate-300 opacity-8 rounded-full"></div>
-                    <div className="absolute top-1/2 right-1/4 w-24 h-24 bg-slate-400 opacity-6 rounded-full"></div>
-                  </div>
 
-                  <div className="relative p-4 sm:p-6 md:p-8 text-gray-600 dark:text-gray-300">
-                    <div className="flex justify-between items-start mb-4 sm:mb-6">
-                      <div className="flex-1 min-w-0">
-                        {userDataLoading ? (
-                          <Skeleton.Title style={{ width: '200px', height: '20px' }} />
-                        ) : (
-                          <div className="text-base sm:text-lg font-semibold truncate text-gray-800 dark:text-gray-100">
-                            {t('尊敬的')} {getUsername()}
+              {enableOnlineTopUp && (
+                <>
+                  {/* 预设充值额度卡片网格 */}
+                  <div>
+                    <Text strong className="block mb-3">{t('选择充值额度')}</Text>
+                    <div className="grid grid-cols-2 sm:grid-cols-4 gap-3">
+                      {presetAmounts.map((preset, index) => (
+                        <Card
+                          key={index}
+                          onClick={() => selectPresetAmount(preset)}
+                          className={`cursor-pointer !rounded-2xl transition-all hover:shadow-md ${selectedPreset === preset.value
+                            ? 'border-blue-500'
+                            : 'border-gray-200 hover:border-gray-300'
+                            }`}
+                          bodyStyle={{ textAlign: 'center' }}
+                        >
+                          <div className="font-medium text-lg flex items-center justify-center mb-1">
+                            <Coins size={16} className="mr-0.5" />
+                            {formatLargeNumber(preset.value)}
                           </div>
-                        )}
-                      </div>
-                      <div className="w-10 h-10 sm:w-12 sm:h-12 rounded-lg flex items-center justify-center shadow-md flex-shrink-0 ml-2 bg-slate-400 dark:bg-slate-500">
-                        <IconCreditCard size="default" className="text-white" />
-                      </div>
+                          <div className="text-xs text-gray-500">
+                            {t('实付')} ¥{(preset.value * priceRatio).toFixed(2)}
+                          </div>
+                        </Card>
+                      ))}
                     </div>
+                  </div>
 
-                    <div className="mb-4 sm:mb-6">
-                      <div className="text-xs sm:text-sm mb-1 sm:mb-2 text-gray-500 dark:text-gray-400">
-                        {t('当前余额')}
-                      </div>
-                      {userDataLoading ? (
-                        <Skeleton.Title style={{ width: '180px', height: '32px' }} />
+                  <Divider style={{ margin: '24px 0' }}>
+                    <Text className="text-sm font-medium">{t('或输入自定义金额')}</Text>
+                  </Divider>
+
+                  <div>
+                    <div className="flex justify-between mb-2">
+                      <Text strong>{t('充值数量')}</Text>
+                      {amountLoading ? (
+                        <Skeleton.Title style={{ width: '80px', height: '16px' }} />
                       ) : (
-                        <div className="text-2xl sm:text-3xl md:text-4xl font-bold tracking-wide text-gray-900 dark:text-gray-100">
-                          {renderQuota(userState?.user?.quota || userQuota)}
-                        </div>
+                        <Text type="tertiary">{t('实付金额:') + renderAmount()}</Text>
                       )}
                     </div>
+                    <InputNumber
+                      disabled={!enableOnlineTopUp}
+                      placeholder={t('充值数量,最低 ') + renderQuotaWithAmount(minTopUp)}
+                      value={topUpCount}
+                      min={minTopUp}
+                      max={999999999}
+                      step={1}
+                      precision={0}
+                      onChange={async (value) => {
+                        if (value && value >= 1) {
+                          setTopUpCount(value);
+                          setSelectedPreset(null);
+                          await getAmount(value);
+                        }
+                      }}
+                      onBlur={(e) => {
+                        const value = parseInt(e.target.value);
+                        if (!value || value < 1) {
+                          setTopUpCount(1);
+                          getAmount(1);
+                        }
+                      }}
+                      size="large"
+                      className="w-full"
+                      formatter={(value) => value ? `${value}` : ''}
+                      parser={(value) => value ? parseInt(value.replace(/[^\d]/g, '')) : 0}
+                    />
+                  </div>
 
-                    <div className="flex flex-col sm:flex-row sm:justify-between sm:items-end">
-                      <div className="grid grid-cols-3 gap-2 sm:flex sm:space-x-6 lg:space-x-8 mb-3 sm:mb-0">
-                        <div className="text-center sm:text-left">
-                          <div className="text-xs text-gray-400 dark:text-gray-500">
-                            {t('历史消耗')}
-                          </div>
-                          {userDataLoading ? (
-                            <Skeleton.Title style={{ width: '60px', height: '14px' }} />
-                          ) : (
-                            <div className="text-xs sm:text-sm font-medium truncate text-gray-600 dark:text-gray-300">
-                              {renderQuota(userState?.user?.used_quota || 0)}
-                            </div>
-                          )}
-                        </div>
-                        <div className="text-center sm:text-left">
-                          <div className="text-xs text-gray-400 dark:text-gray-500">
-                            {t('用户分组')}
-                          </div>
-                          {userDataLoading ? (
-                            <Skeleton.Title style={{ width: '50px', height: '14px' }} />
-                          ) : (
-                            <div className="text-xs sm:text-sm font-medium truncate text-gray-600 dark:text-gray-300">
-                              {userState?.user?.group || t('默认')}
-                            </div>
-                          )}
-                        </div>
-                        <div className="text-center sm:text-left">
-                          <div className="text-xs text-gray-400 dark:text-gray-500">
-                            {t('用户角色')}
-                          </div>
-                          {userDataLoading ? (
-                            <Skeleton.Title style={{ width: '60px', height: '14px' }} />
-                          ) : (
-                            <div className="text-xs sm:text-sm font-medium truncate text-gray-600 dark:text-gray-300">
-                              {getUserRole()}
-                            </div>
-                          )}
-                        </div>
-                      </div>
-
-                      <div className="self-end sm:self-auto">
-                        {userDataLoading ? (
-                          <Skeleton.Title style={{ width: '50px', height: '24px' }} />
-                        ) : (
-                          <div className="px-2 py-1 sm:px-3 rounded-md text-xs sm:text-sm font-medium inline-block bg-slate-100 dark:bg-slate-700 text-slate-600 dark:text-slate-300 border border-slate-200 dark:border-slate-600">
-                            ID: {userState?.user?.id || '---'}
-                          </div>
-                        )}
-                      </div>
-                    </div>
-
-                    <div className="absolute top-0 left-0 w-full h-2 bg-gradient-to-r from-slate-300 via-slate-400 to-slate-500 dark:from-slate-600 dark:via-slate-500 dark:to-slate-400 opacity-40"></div>
+                  <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
+                    <Button
+                      type="primary"
+                      onClick={() => preTopUp('zfb')}
+                      size="large"
+                      disabled={!enableOnlineTopUp}
+                      loading={paymentLoading && payWay === 'zfb'}
+                      icon={<SiAlipay size={18} />}
+                      style={{ height: '44px' }}
+                    >
+                      <span className="ml-2">{t('支付宝')}</span>
+                    </Button>
+                    <Button
+                      type="primary"
+                      onClick={() => preTopUp('wx')}
+                      size="large"
+                      disabled={!enableOnlineTopUp}
+                      loading={paymentLoading && payWay === 'wx'}
+                      icon={<SiWechat size={18} />}
+                      style={{ height: '44px' }}
+                    >
+                      <span className="ml-2">{t('微信')}</span>
+                    </Button>
                   </div>
-                </Card>
+                </>
+              )}
+
+              {!enableOnlineTopUp && (
+                <Banner
+                  type="warning"
+                  description={t('管理员未开启在线充值功能,请联系管理员或使用兑换码充值。')}
+                  closeIcon={null}
+                  className="!rounded-2xl"
+                />
+              )}
 
-                <div className="p-6">
-                  <div className="grid grid-cols-1 lg:grid-cols-3 gap-8">
-                    {/* 左侧:在线充值和兑换余额 */}
-                    <div className="lg:col-span-2 space-y-8">
-                      {/* 在线充值部分 */}
-                      <div>
-                        <div className="flex items-center mb-6">
-                          <div className="w-12 h-12 rounded-full bg-slate-100 dark:bg-slate-700 flex items-center justify-center mr-4">
-                            <IconPlus size="large" className="text-slate-600 dark:text-slate-300" />
-                          </div>
-                          <div>
-                            <Text className="text-xl font-semibold">{t('在线充值')}</Text>
-                            <div className="text-gray-500 text-sm">{t('支持多种支付方式')}</div>
-                          </div>
-                        </div>
+              <Divider style={{ margin: '24px 0' }}>
+                <Text className="text-sm font-medium">{t('兑换码充值')}</Text>
+              </Divider>
 
-                        <div className="space-y-4">
-                          <div>
-                            <div className="flex justify-between mb-2">
-                              <Text strong>{t('充值数量')}</Text>
-                              {amountLoading ? (
-                                <Skeleton.Title style={{ width: '80px', height: '14px' }} />
-                              ) : (
-                                <Text type="tertiary">{t('实付金额:') + ' ' + renderAmount()}</Text>
-                              )}
-                            </div>
-                            <InputNumber
-                              disabled={!enableOnlineTopUp}
-                              placeholder={
-                                t('充值数量,最低 ') + renderQuotaWithAmount(minTopUp)
-                              }
-                              value={topUpCount}
-                              min={minTopUp}
-                              max={999999999}
-                              step={1}
-                              precision={0}
-                              onChange={async (value) => {
-                                if (value && value >= 1) {
-                                  setTopUpCount(value);
-                                  await getAmount(value);
-                                }
-                              }}
-                              onBlur={(e) => {
-                                const value = parseInt(e.target.value);
-                                if (!value || value < 1) {
-                                  setTopUpCount(1);
-                                  getAmount(1);
-                                }
-                              }}
-                              size="large"
-                              className="!rounded-lg w-full"
-                              prefix={<IconCreditCard />}
-                              formatter={(value) => value ? `${value}` : ''}
-                              parser={(value) => value ? parseInt(value.replace(/[^\d]/g, '')) : 0}
-                            />
-                          </div>
+              <Card className="!rounded-2xl">
+                <div className="flex items-start mb-4">
+                  <Gift size={16} className="mr-2 mt-0.5" />
+                  <Text strong>{t('使用兑换码快速充值')}</Text>
+                </div>
 
-                          <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
-                            <Button
-                              type="primary"
-                              theme="solid"
-                              onClick={async () => {
-                                preTopUp('zfb');
-                              }}
-                              size="large"
-                              className="!rounded-lg !bg-slate-600 hover:!bg-slate-700 h-14"
-                              disabled={!enableOnlineTopUp}
-                              loading={paymentLoading}
-                              icon={<SiAlipay size={20} />}
-                            >
-                              <span className="ml-2">{t('支付宝')}</span>
-                            </Button>
-                            <Button
-                              type="primary"
-                              theme="solid"
-                              onClick={async () => {
-                                preTopUp('wx');
-                              }}
-                              size="large"
-                              className="!rounded-lg !bg-slate-600 hover:!bg-slate-700 h-14"
-                              disabled={!enableOnlineTopUp}
-                              loading={paymentLoading}
-                              icon={<SiWechat size={20} />}
-                            >
-                              <span className="ml-2">{t('微信')}</span>
-                            </Button>
-                          </div>
+                <div className="mb-4">
+                  <Input
+                    placeholder={t('请输入兑换码')}
+                    value={redemptionCode}
+                    onChange={(value) => setRedemptionCode(value)}
+                    size="large"
+                  />
+                </div>
 
-                          {!enableOnlineTopUp && (
-                            <Banner
-                              fullMode={false}
-                              type="warning"
-                              icon={null}
-                              closeIcon={null}
-                              className="!rounded-lg"
-                              title={
-                                <div style={{ fontWeight: 600, fontSize: '14px', lineHeight: '20px' }}>
-                                  {t('在线充值功能未开启')}
-                                </div>
-                              }
-                              description={
-                                <div>
-                                  {t('管理员未开启在线充值功能,请联系管理员开启或使用兑换码充值。')}
-                                </div>
-                              }
-                            />
-                          )}
-                        </div>
-                      </div>
+                <div className="flex flex-col sm:flex-row gap-3">
+                  {topUpLink && (
+                    <Button
+                      type="secondary"
+                      onClick={openTopUpLink}
+                      size="large"
+                      className="flex-1"
+                      icon={<LinkIcon size={16} />}
+                      style={{ height: '40px' }}
+                    >
+                      {t('获取兑换码')}
+                    </Button>
+                  )}
+                  <Button
+                    type="primary"
+                    onClick={topUp}
+                    disabled={isSubmitting || !redemptionCode}
+                    loading={isSubmitting}
+                    size="large"
+                    className="flex-1"
+                    style={{ height: '40px' }}
+                  >
+                    {isSubmitting ? t('兑换中...') : t('兑换')}
+                  </Button>
+                </div>
+              </Card>
+            </div>
+          </Card>
+        </div>
+
+        {/* 右侧邀请信息卡片 */}
+        <div className="lg:col-span-5">
+          <Card
+            className="!rounded-2xl"
+            shadows='always'
+            bordered={false}
+            header={
+              <div className="px-5 py-4 pb-0">
+                <div className="flex items-center justify-between">
+                  <div className="flex items-center">
+                    <Avatar
+                      className="mr-3 shadow-md flex-shrink-0"
+                      color="green"
+                    >
+                      <Users size={24} />
+                    </Avatar>
+                    <div>
+                      <Title heading={5} style={{ margin: 0 }}>
+                        {t('邀请奖励')}
+                      </Title>
+                      <Text type="tertiary" className="text-sm">
+                        {t('邀请好友获得额外奖励')}
+                      </Text>
+                    </div>
+                  </div>
+                </div>
+              </div>
+            }
+          >
+            <div className="space-y-6">
+              <div className="grid grid-cols-1 gap-4">
+                <Card className="!rounded-2xl">
+                  <div className="flex justify-between items-center">
+                    <Text type="tertiary">{t('待使用收益')}</Text>
+                    <Button
+                      type="primary"
+                      theme="solid"
+                      size="small"
+                      disabled={!userState?.user?.aff_quota || userState?.user?.aff_quota <= 0}
+                      onClick={() => setOpenTransfer(true)}
+                    >
+                      {t('划转到余额')}
+                    </Button>
+                  </div>
+                  <div className="text-2xl font-semibold mt-2">
+                    {renderQuota(userState?.user?.aff_quota || 0)}
+                  </div>
+                </Card>
 
-                      {/* 兑换余额部分 */}
-                      <div>
-                        <div className="flex items-center mb-6">
-                          <div className="w-12 h-12 rounded-full bg-slate-100 dark:bg-slate-700 flex items-center justify-center mr-4">
-                            <IconGift size="large" className="text-slate-600 dark:text-slate-300" />
-                          </div>
-                          <div>
-                            <Text className="text-xl font-semibold">{t('兑换余额')}</Text>
-                            <div className="text-gray-500 text-sm">{t('使用兑换码充值余额')}</div>
-                          </div>
-                        </div>
+                <div className="grid grid-cols-2 gap-4">
+                  <Card className="!rounded-2xl">
+                    <Text type="tertiary">{t('总收益')}</Text>
+                    <div className="text-xl font-semibold mt-2">
+                      {renderQuota(userState?.user?.aff_history_quota || 0)}
+                    </div>
+                  </Card>
+                  <Card className="!rounded-2xl">
+                    <Text type="tertiary">{t('邀请人数')}</Text>
+                    <div className="text-xl font-semibold mt-2 flex items-center">
+                      <Users size={16} className="mr-1" />
+                      {userState?.user?.aff_count || 0}
+                    </div>
+                  </Card>
+                </div>
+              </div>
 
-                        <div className="space-y-4">
-                          <div>
-                            <Text strong className="block mb-2">{t('兑换码')}</Text>
-                            <Input
-                              placeholder={t('请输入兑换码')}
-                              value={redemptionCode}
-                              onChange={(value) => setRedemptionCode(value)}
-                              size="large"
-                              className="!rounded-lg"
-                              prefix={<IconGift />}
-                            />
-                          </div>
+              <div className="space-y-4">
+                <Title heading={6}>{t('邀请链接')}</Title>
+                <div className="relative">
+                  <Input
+                    value={affLink}
+                    readOnly
+                    size="large"
+                  />
+                  <Button
+                    type="primary"
+                    theme="light"
+                    onClick={handleAffLinkClick}
+                    className="absolute right-1 top-1 bottom-1"
+                    icon={<Copy size={14} />}
+                  >
+                    {t('复制')}
+                  </Button>
+                </div>
 
-                          <div className="flex flex-col sm:flex-row gap-3">
-                            {topUpLink && (
-                              <Button
-                                type="primary"
-                                theme="solid"
-                                onClick={openTopUpLink}
-                                size="large"
-                                className="!rounded-lg flex-1"
-                                icon={<IconLink />}
-                              >
-                                {t('获取兑换码')}
-                              </Button>
-                            )}
-                            <Button
-                              type="warning"
-                              theme="solid"
-                              onClick={topUp}
-                              disabled={isSubmitting}
-                              loading={isSubmitting}
-                              size="large"
-                              className="!rounded-lg flex-1"
-                            >
-                              {isSubmitting ? t('兑换中...') : t('兑换')}
-                            </Button>
-                          </div>
-                        </div>
+                <div className="mt-4">
+                  <Card className="!rounded-2xl">
+                    <div className="space-y-4">
+                      <div className="flex items-start">
+                        <div className="w-1.5 h-1.5 rounded-full bg-blue-500 mt-2 mr-3 flex-shrink-0"></div>
+                        <Text type="tertiary" className="text-sm leading-6">
+                          {t('邀请好友注册,好友充值后您可获得相应奖励')}
+                        </Text>
                       </div>
-                    </div>
-
-                    {/* 右侧:邀请信息部分 */}
-                    <div className="lg:col-span-1">
-                      <div className="flex items-center justify-between mb-6">
-                        <div className="flex items-center">
-                          <div className="w-12 h-12 rounded-full bg-slate-100 dark:bg-slate-700 flex items-center justify-center mr-4">
-                            <IconLink size="large" className="text-slate-600 dark:text-slate-300" />
-                          </div>
-                          <div>
-                            <div className="flex items-center gap-3">
-                              <Text className="text-xl font-semibold">{t('邀请信息')}</Text>
-                              <Button
-                                type="primary"
-                                theme="solid"
-                                onClick={() => setOpenTransfer(true)}
-                                size="small"
-                                className="!rounded-lg !bg-slate-600 hover:!bg-slate-700"
-                                icon={<IconCreditCard />}
-                              >
-                                {t('划转')}
-                              </Button>
-                            </div>
-                            <div className="text-gray-500 text-sm">{t('管理您的邀请链接和收益')}</div>
-                          </div>
-                        </div>
+                      <div className="flex items-start">
+                        <div className="w-1.5 h-1.5 rounded-full bg-green-500 mt-2 mr-3 flex-shrink-0"></div>
+                        <Text type="tertiary" className="text-sm leading-6">
+                          {t('通过划转功能将奖励额度转入到您的账户余额中')}
+                        </Text>
                       </div>
-
-                      <div className="space-y-4">
-                        <div className="grid grid-cols-1 gap-3">
-                          <Card
-                            className="!rounded-2xl text-center"
-                            bodyStyle={{ padding: '16px' }}
-                            shadows='hover'
-                          >
-                            <div className="text-gray-600 text-xs font-medium">{t('待使用收益')}</div>
-                            <div className="text-gray-900 text-lg font-bold mt-1">
-                              {renderQuota(userState?.user?.aff_quota)}
-                            </div>
-                          </Card>
-                          <Card
-                            className="!rounded-2xl text-center"
-                            bodyStyle={{ padding: '16px' }}
-                            shadows='hover'
-                          >
-                            <div className="text-gray-600 text-xs font-medium">{t('总收益')}</div>
-                            <div className="text-gray-900 text-lg font-bold mt-1">
-                              {renderQuota(userState?.user?.aff_history_quota)}
-                            </div>
-                          </Card>
-                          <Card
-                            className="!rounded-2xl text-center"
-                            bodyStyle={{ padding: '16px' }}
-                            shadows='hover'
-                          >
-                            <div className="text-gray-600 text-xs font-medium">{t('邀请人数')}</div>
-                            <div className="text-gray-900 text-lg font-bold mt-1">
-                              {userState?.user?.aff_count || 0}
-                            </div>
-                          </Card>
-                        </div>
-
-                        <div className="bg-white rounded-lg p-3">
-                          <Typography.Text strong className="block mb-2 text-sm">{t('邀请链接')}</Typography.Text>
-                          <Input
-                            value={affLink}
-                            onClick={handleAffLinkClick}
-                            readOnly
-                            size="large"
-                            className="!rounded-lg"
-                            prefix={<IconLink />}
-                          />
-                        </div>
+                      <div className="flex items-start">
+                        <div className="w-1.5 h-1.5 rounded-full bg-purple-500 mt-2 mr-3 flex-shrink-0"></div>
+                        <Text type="tertiary" className="text-sm leading-6">
+                          {t('邀请的好友越多,获得的奖励越多')}
+                        </Text>
                       </div>
                     </div>
-                  </div>
+                  </Card>
                 </div>
-              </Card>
+              </div>
             </div>
-          </div>
-        </Layout.Content>
-      </Layout>
+          </Card>
+        </div>
+      </div>
     </div>
   );
 };