diff --git a/.dockerignore b/.dockerignore
index 53d0019..cf14beb 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -7,4 +7,12 @@ Makefile
docs
.eslintcache
.gocache
-/web/node_modules
\ No newline at end of file
+/web/node_modules
+.claude
+.plans
+current-page*
+models-page*
+pricing-page.png
+login-page
+scripts
+relay/helper/price_test.go
\ No newline at end of file
diff --git a/web/src/components/auth/LoginForm.jsx b/web/src/components/auth/LoginForm.jsx
index 82dba4e..0feb33c 100644
--- a/web/src/components/auth/LoginForm.jsx
+++ b/web/src/components/auth/LoginForm.jsx
@@ -17,8 +17,8 @@ along with this program. If not, see .
For commercial licensing, please contact support@quantumnous.com
*/
-import React, { useContext, useEffect, useMemo, useRef, useState } from 'react';
-import { Link, useNavigate, useSearchParams } from 'react-router-dom';
+import React, { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
+import { Link, useLocation, useNavigate, useSearchParams } from 'react-router-dom';
import { UserContext } from '../../context/User';
import { StatusContext } from '../../context/Status';
import {
@@ -69,6 +69,7 @@ import { SiDiscord } from 'react-icons/si';
const LoginForm = () => {
let navigate = useNavigate();
+ const location = useLocation();
const { t } = useTranslation();
const githubButtonTextKeyByState = {
idle: '使用 GitHub 继续',
@@ -113,6 +114,15 @@ const LoginForm = () => {
const githubButtonText = t(githubButtonTextKeyByState[githubButtonState]);
const [customOAuthLoading, setCustomOAuthLoading] = useState({});
+ const navigateAfterLogin = useCallback(() => {
+ const from = location.state?.from;
+ if (from && from.pathname) {
+ navigate(from.pathname + (from.search || ''));
+ } else {
+ navigate('/console');
+ }
+ }, [location.state, navigate]);
+
const logo = getLogo();
const systemName = getSystemName();
@@ -198,7 +208,7 @@ const LoginForm = () => {
localStorage.setItem('user', JSON.stringify(data));
setUserData(data);
updateAPI();
- navigate('/');
+ navigateAfterLogin();
showSuccess(t('登录成功!'));
setShowWeChatLoginModal(false);
} else {
@@ -255,7 +265,7 @@ const LoginForm = () => {
centered: true,
});
}
- navigate('/console');
+ navigateAfterLogin();
} else {
showError(message);
}
@@ -300,7 +310,7 @@ const LoginForm = () => {
showSuccess(t('登录成功!'));
setUserData(data);
updateAPI();
- navigate('/');
+ navigateAfterLogin();
} else {
showError(message);
}
@@ -456,7 +466,7 @@ const LoginForm = () => {
setUserData(finish.data);
updateAPI();
showSuccess(t('登录成功!'));
- navigate('/console');
+ navigateAfterLogin();
} else {
showError(finish.message || t('Passkey 登录失败,请重试'));
}
@@ -491,7 +501,7 @@ const LoginForm = () => {
setUserData(data);
updateAPI();
showSuccess(t('登录成功!'));
- navigate('/console');
+ navigateAfterLogin();
};
// 返回登录页面
diff --git a/web/src/components/topup/RechargeCard.jsx b/web/src/components/topup/RechargeCard.jsx
index 7be1b97..b3e3f18 100644
--- a/web/src/components/topup/RechargeCard.jsx
+++ b/web/src/components/topup/RechargeCard.jsx
@@ -102,6 +102,7 @@ const RechargeCard = ({
const initialTabSetRef = useRef(false);
const showAmountSkeleton = useMinimumLoadingTime(amountLoading);
const [activeTab, setActiveTab] = useState('topup');
+ const [amountWarning, setAmountWarning] = useState('');
const shouldShowSubscription =
!subscriptionLoading && subscriptionPlans.length > 0;
@@ -255,18 +256,26 @@ const RechargeCard = ({
onChange={async (displayValue) => {
const rawValue = needsConvert ? Math.round(displayValue / curRate) : displayValue;
if (rawValue && rawValue >= 1) {
+ if (rawValue < minTopUp) {
+ setAmountWarning(t('金额过小,最低需充值') + displayMin + ' ' + curSymbol);
+ } else {
+ setAmountWarning('');
+ }
setTopUpCount(rawValue);
setSelectedPreset(null);
await getAmount(rawValue);
+ } else {
+ setAmountWarning(t('金额过小,最低需充值') + displayMin + ' ' + curSymbol);
}
}}
onBlur={(e) => {
const displayVal = parseInt(e.target.value);
const rawVal = needsConvert ? Math.round(displayVal / curRate) : displayVal;
if (!rawVal || rawVal < 1) {
- setTopUpCount(1);
- getAmount(1);
+ setTopUpCount(minTopUp);
+ getAmount(minTopUp);
}
+ setAmountWarning('');
}}
formatter={(value) => (value ? `${value}` : '')}
parser={(value) =>
@@ -275,26 +284,33 @@ const RechargeCard = ({
suffix={curSymbol}
style={{ width: '100%' }}
extraText={
-
- }
- >
-
- {t('实付金额:')}
-
- {renderAmount()}
-
-
-
+ <>
+ {amountWarning && (
+
+ {amountWarning}
+
+ )}
+
+ }
+ >
+
+ {t('实付金额:')}
+
+ {renderAmount()}
+
+
+
+ >
}
/>
);
@@ -436,6 +452,7 @@ const RechargeCard = ({
bodyStyle={{ padding: '12px' }}
onClick={() => {
selectPresetAmount(preset);
+ setAmountWarning('');
onlineFormApiRef.current?.setValue(
'topUpCount',
needsConvert ? Math.round(preset.value * pRate) : preset.value,