diff --git a/web/package.json b/web/package.json index 7dfd8f80..2abb1897 100644 --- a/web/package.json +++ b/web/package.json @@ -11,23 +11,25 @@ "@visactor/vchart": "~1.8.8", "@visactor/vchart-semi-theme": "~1.8.8", "axios": "^0.27.2", + "country-flag-icons": "^1.5.19", "dayjs": "^1.11.11", "history": "^5.3.0", "i18next": "^23.16.8", "i18next-browser-languagedetector": "^7.2.0", + "lucide-react": "^0.511.0", "marked": "^4.1.1", "react": "^18.2.0", "react-dom": "^18.2.0", "react-dropzone": "^14.2.3", "react-fireworks": "^1.0.4", "react-i18next": "^13.0.0", + "react-icons": "^5.5.0", "react-router-dom": "^6.3.0", "react-telegram-login": "^1.1.2", "react-toastify": "^9.0.8", "react-turnstile": "^1.0.5", "semantic-ui-offline": "^2.5.0", "semantic-ui-react": "^2.1.3", - "country-flag-icons": "^1.5.19", "sse": "https://github.com/mpetazzoni/sse.js" }, "scripts": { diff --git a/web/src/i18n/locales/en.json b/web/src/i18n/locales/en.json index eef1bb20..063a855e 100644 --- a/web/src/i18n/locales/en.json +++ b/web/src/i18n/locales/en.json @@ -1178,7 +1178,7 @@ "请输入新的密码,最短 8 位": "Please enter a new password, at least 8 characterss", "添加额度": "Add quota", "以下信息不可修改": "The following information cannot be modified", - "确定要充值吗": "Check to confirm recharge", + "充值确认": "Recharge confirmation", "充值数量": "Recharge quantity", "实付金额": "Actual payment amount", "是否确认充值?": "Confirm recharge?", @@ -1449,5 +1449,11 @@ "用户分组和额度管理": "User Group and Quota Management", "绑定信息": "Binding Information", "第三方账户绑定状态(只读)": "Third-party account binding status (read-only)", - "已绑定的 OIDC 账户": "Bound OIDC accounts" + "已绑定的 OIDC 账户": "Bound OIDC accounts", + "使用兑换码充值余额": "Recharge balance with redemption code", + "支持多种支付方式": "Support multiple payment methods", + "尊敬的": "Dear", + "请输入兑换码": "Please enter the redemption code", + "在线充值功能未开启": "Online recharge function is not enabled", + "管理员未开启在线充值功能,请联系管理员开启或使用兑换码充值。": "The administrator has not enabled the online recharge function, please contact the administrator to enable it or recharge with a redemption code." } \ No newline at end of file diff --git a/web/src/pages/TopUp/index.js b/web/src/pages/TopUp/index.js index 7f302cd5..893a31b1 100644 --- a/web/src/pages/TopUp/index.js +++ b/web/src/pages/TopUp/index.js @@ -1,34 +1,41 @@ -import React, { useEffect, useState } from 'react'; -import { API, isMobile, showError, showInfo, showSuccess } from '../../helpers'; +import React, { useEffect, useState, useContext } from 'react'; +import { API, showError, showInfo, showSuccess } from '../../helpers'; import { - renderNumber, renderQuota, renderQuotaWithAmount, + stringToColor, } from '../../helpers/render'; import { - Col, Layout, - Row, Typography, Card, Button, - Form, - Divider, - Space, Modal, Toast, + Input, + InputNumber, + Banner, + Skeleton, } from '@douyinfe/semi-ui'; -import Title from '@douyinfe/semi-ui/lib/es/typography/title'; -import Text from '@douyinfe/semi-ui/lib/es/typography/text'; -import { Link } from 'react-router-dom'; +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'; + +const { Text } = Typography; const TopUp = () => { const { t } = useTranslation(); + const [userState, userDispatch] = useContext(UserContext); + const [redemptionCode, setRedemptionCode] = useState(''); const [topUpCode, setTopUpCode] = useState(''); const [topUpCount, setTopUpCount] = useState(0); - const [minTopupCount, setMinTopUpCount] = useState(1); const [amount, setAmount] = useState(0.0); const [minTopUp, setMinTopUp] = useState(1); const [topUpLink, setTopUpLink] = useState(''); @@ -37,6 +44,30 @@ const TopUp = () => { const [isSubmitting, setIsSubmitting] = useState(false); const [open, setOpen] = useState(false); const [payWay, setPayWay] = useState(''); + const [userDataLoading, setUserDataLoading] = useState(true); + const [amountLoading, setAmountLoading] = useState(false); + + const getUsername = () => { + if (userState.user) { + return userState.user.username; + } else { + return 'null'; + } + }; + + const getUserRole = () => { + if (!userState.user) return t('普通用户'); + + switch (userState.user.role) { + case 100: + return t('超级管理员'); + case 10: + return t('管理员'); + case 0: + default: + return t('普通用户'); + } + }; const topUp = async () => { if (redemptionCode === '') { @@ -59,6 +90,13 @@ const TopUp = () => { setUserQuota((quota) => { return quota + data; }); + if (userState.user) { + const updatedUser = { + ...userState.user, + quota: userState.user.quota + data + }; + userDispatch({ type: 'login', payload: updatedUser }); + } setRedemptionCode(''); } else { showError(message); @@ -109,14 +147,12 @@ const TopUp = () => { }); if (res !== undefined) { const { message, data } = res.data; - // showInfo(message); if (message === 'success') { let params = data; let url = res.data.url; let form = document.createElement('form'); form.action = url; form.method = 'POST'; - // 判断是否为safari浏览器 let isSafari = navigator.userAgent.indexOf('Safari') > -1 && navigator.userAgent.indexOf('Chrome') < 1; @@ -135,26 +171,26 @@ const TopUp = () => { document.body.removeChild(form); } else { showError(data); - // setTopUpCount(parseInt(res.data.count)); - // setAmount(parseInt(data)); } } else { showError(res); } } catch (err) { console.log(err); - } finally { } }; const getUserQuota = async () => { + setUserDataLoading(true); let res = await API.get(`/api/user/self`); const { success, message, data } = res.data; if (success) { setUserQuota(data.quota); + userDispatch({ type: 'login', payload: data }); } else { showError(message); } + setUserDataLoading(false); }; useEffect(() => { @@ -171,11 +207,16 @@ const TopUp = () => { setEnableOnlineTopUp(status.enable_online_topup); } } - getUserQuota().then(); + + if (userState?.user?.id) { + setUserDataLoading(false); + setUserQuota(userState.user.quota); + } else { + getUserQuota().then(); + } }, []); const renderAmount = () => { - // console.log(amount); return amount + ' ' + t('元'); }; @@ -183,6 +224,7 @@ const TopUp = () => { if (value === undefined) { value = topUpCount; } + setAmountLoading(true); try { const res = await API.post('/api/user/amount', { amount: parseFloat(value), @@ -190,22 +232,19 @@ const TopUp = () => { }); if (res !== undefined) { const { message, data } = res.data; - // showInfo(message); if (message === 'success') { setAmount(parseFloat(data)); } else { setAmount(0); Toast.error({ content: '错误:' + data, id: 'getAmount' }); - // setTopUpCount(parseInt(res.data.count)); - // setAmount(parseInt(data)); } } else { showError(res); } } catch (err) { console.log(err); - } finally { } + setAmountLoading(false); }; const handleCancel = () => { @@ -213,14 +252,16 @@ const TopUp = () => { }; return ( -
- {t('充值数量')}:{topUpCount} -
-- {t('实付金额')}:{renderAmount()} -
-{t('是否确认充值?')}
+