mirror of
				https://github.com/songquanpeng/one-api.git
				synced 2025-11-04 15:53:42 +08:00 
			
		
		
		
	chore: update default theme style
This commit is contained in:
		@@ -3,12 +3,13 @@ package controller
 | 
				
			|||||||
import (
 | 
					import (
 | 
				
			||||||
	"encoding/json"
 | 
						"encoding/json"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
 | 
						"net/http"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/songquanpeng/one-api/common"
 | 
						"github.com/songquanpeng/one-api/common"
 | 
				
			||||||
	"github.com/songquanpeng/one-api/common/config"
 | 
						"github.com/songquanpeng/one-api/common/config"
 | 
				
			||||||
	"github.com/songquanpeng/one-api/common/message"
 | 
						"github.com/songquanpeng/one-api/common/message"
 | 
				
			||||||
	"github.com/songquanpeng/one-api/model"
 | 
						"github.com/songquanpeng/one-api/model"
 | 
				
			||||||
	"net/http"
 | 
					 | 
				
			||||||
	"strings"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/gin-gonic/gin"
 | 
						"github.com/gin-gonic/gin"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@@ -120,6 +121,7 @@ func SendEmailVerification(c *gin.Context) {
 | 
				
			|||||||
		"<p>验证码 %d 分钟内有效,如果不是本人操作,请忽略。</p>", config.SystemName, code, common.VerificationValidMinutes)
 | 
							"<p>验证码 %d 分钟内有效,如果不是本人操作,请忽略。</p>", config.SystemName, code, common.VerificationValidMinutes)
 | 
				
			||||||
	err := message.SendEmail(subject, email, content)
 | 
						err := message.SendEmail(subject, email, content)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		c.JSON(http.StatusOK, gin.H{
 | 
							c.JSON(http.StatusOK, gin.H{
 | 
				
			||||||
			"success": false,
 | 
								"success": false,
 | 
				
			||||||
			"message": err.Error(),
 | 
								"message": err.Error(),
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -571,7 +571,9 @@
 | 
				
			|||||||
        "qrcode_placeholder": "Enter an image URL",
 | 
					        "qrcode_placeholder": "Enter an image URL",
 | 
				
			||||||
        "buttons": {
 | 
					        "buttons": {
 | 
				
			||||||
          "save": "Save WeChat Server Settings"
 | 
					          "save": "Save WeChat Server Settings"
 | 
				
			||||||
        }
 | 
					        },
 | 
				
			||||||
 | 
					        "scan_tip": "Scan QR code to follow WeChat Official Account, enter 'code' to get verification code (valid for 3 minutes)",
 | 
				
			||||||
 | 
					        "code_placeholder": "Verification code"
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      "turnstile": {
 | 
					      "turnstile": {
 | 
				
			||||||
        "title": "Turnstile Configuration",
 | 
					        "title": "Turnstile Configuration",
 | 
				
			||||||
@@ -754,5 +756,72 @@
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "loading_failed": "Failed to load homepage content..."
 | 
					    "loading_failed": "Failed to load homepage content..."
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "auth": {
 | 
				
			||||||
 | 
					    "login": {
 | 
				
			||||||
 | 
					      "title": "User Login",
 | 
				
			||||||
 | 
					      "username": "Username / Email",
 | 
				
			||||||
 | 
					      "password": "Password",
 | 
				
			||||||
 | 
					      "button": "Login",
 | 
				
			||||||
 | 
					      "forgot_password": "Forgot password?",
 | 
				
			||||||
 | 
					      "reset_password": "Reset",
 | 
				
			||||||
 | 
					      "no_account": "No account?",
 | 
				
			||||||
 | 
					      "register": "Register",
 | 
				
			||||||
 | 
					      "other_methods": "Other login methods",
 | 
				
			||||||
 | 
					      "wechat": {
 | 
				
			||||||
 | 
					        "scan_tip": "Scan QR code to follow WeChat Official Account, enter 'code' to get verification code (valid for 3 minutes)",
 | 
				
			||||||
 | 
					        "code_placeholder": "Verification code"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "register": {
 | 
				
			||||||
 | 
					      "title": "New User Registration",
 | 
				
			||||||
 | 
					      "username": "Username (max 12 characters)",
 | 
				
			||||||
 | 
					      "password": "Password (8-20 characters)",
 | 
				
			||||||
 | 
					      "confirm_password": "Confirm password",
 | 
				
			||||||
 | 
					      "email": "Email address",
 | 
				
			||||||
 | 
					      "verification_code": "Verification code",
 | 
				
			||||||
 | 
					      "get_code": "Get code",
 | 
				
			||||||
 | 
					      "get_code_retry": "Retry ({{countdown}})",
 | 
				
			||||||
 | 
					      "button": "Register",
 | 
				
			||||||
 | 
					      "has_account": "Have an account?",
 | 
				
			||||||
 | 
					      "login": "Login"
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "reset": {
 | 
				
			||||||
 | 
					      "title": "Password Reset",
 | 
				
			||||||
 | 
					      "email": "Email address",
 | 
				
			||||||
 | 
					      "button": "Submit",
 | 
				
			||||||
 | 
					      "notice": "The system will send an email containing a reset link to your mailbox. Please check your email.",
 | 
				
			||||||
 | 
					      "confirm": {
 | 
				
			||||||
 | 
					        "title": "Password Reset Confirmation",
 | 
				
			||||||
 | 
					        "new_password": "New password",
 | 
				
			||||||
 | 
					        "button": "Submit",
 | 
				
			||||||
 | 
					        "button_disabled": "Password reset completed",
 | 
				
			||||||
 | 
					        "notice": "New password has been generated, please click the password field or button above to copy. Please login and change your password as soon as possible!"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "about": {
 | 
				
			||||||
 | 
					    "title": "About",
 | 
				
			||||||
 | 
					    "description": "One API is an open-source API management and proxy platform.",
 | 
				
			||||||
 | 
					    "repository": "Repository: ",
 | 
				
			||||||
 | 
					    "loading_failed": "Loading failed"
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "messages": {
 | 
				
			||||||
 | 
					    "success": {
 | 
				
			||||||
 | 
					      "login": "Login successful!",
 | 
				
			||||||
 | 
					      "register": "Registration successful!",
 | 
				
			||||||
 | 
					      "verification_code": "Verification code sent, please check your email!",
 | 
				
			||||||
 | 
					      "password_reset": "Reset email sent, please check your inbox!"
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "error": {
 | 
				
			||||||
 | 
					      "login_expired": "Not logged in or session expired, please login again!",
 | 
				
			||||||
 | 
					      "password_length": "Password must be at least 8 characters!",
 | 
				
			||||||
 | 
					      "password_mismatch": "Passwords do not match",
 | 
				
			||||||
 | 
					      "turnstile_wait": "Please wait a few seconds, Turnstile is checking the environment!",
 | 
				
			||||||
 | 
					      "root_password": "Please change the default password immediately!"
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "notice": {
 | 
				
			||||||
 | 
					      "password_copied": "New password copied to clipboard: {{password}}"
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -720,10 +720,10 @@
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "about": {
 | 
					  "about": {
 | 
				
			||||||
    "title": "关于系统",
 | 
					    "title": "关于",
 | 
				
			||||||
    "description": "可在设置页面设置关于内容,支持 HTML & Markdown",
 | 
					    "description": "One API 是一个开源的接口管理和代理平台。",
 | 
				
			||||||
    "repository": "项目仓库地址:",
 | 
					    "repository": "项目地址:",
 | 
				
			||||||
    "loading_failed": "加载关于内容失败..."
 | 
					    "loading_failed": "加载失败"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "footer": {
 | 
					  "footer": {
 | 
				
			||||||
    "built_by": "由",
 | 
					    "built_by": "由",
 | 
				
			||||||
@@ -758,5 +758,66 @@
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "loading_failed": "加载首页内容失败..."
 | 
					    "loading_failed": "加载首页内容失败..."
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "auth": {
 | 
				
			||||||
 | 
					    "login": {
 | 
				
			||||||
 | 
					      "title": "用户登录",
 | 
				
			||||||
 | 
					      "username": "用户名 / 邮箱地址",
 | 
				
			||||||
 | 
					      "password": "密码",
 | 
				
			||||||
 | 
					      "button": "登录",
 | 
				
			||||||
 | 
					      "forgot_password": "忘记密码?",
 | 
				
			||||||
 | 
					      "reset_password": "点击重置",
 | 
				
			||||||
 | 
					      "no_account": "没有账户?",
 | 
				
			||||||
 | 
					      "register": "点击注册",
 | 
				
			||||||
 | 
					      "other_methods": "使用其他方式登录",
 | 
				
			||||||
 | 
					      "wechat": {
 | 
				
			||||||
 | 
					        "scan_tip": "微信扫码关注公众号,输入「验证码」获取验证码(三分钟内有效)",
 | 
				
			||||||
 | 
					        "code_placeholder": "验证码"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "register": {
 | 
				
			||||||
 | 
					      "title": "新用户注册",
 | 
				
			||||||
 | 
					      "username": "输入用户名,最长 12 位",
 | 
				
			||||||
 | 
					      "password": "输入密码,最短 8 位,最长 20 位",
 | 
				
			||||||
 | 
					      "confirm_password": "再次输入密码",
 | 
				
			||||||
 | 
					      "email": "输入邮箱地址",
 | 
				
			||||||
 | 
					      "verification_code": "输入验证码",
 | 
				
			||||||
 | 
					      "get_code": "获取验证码",
 | 
				
			||||||
 | 
					      "get_code_retry": "重试 ({{countdown}})",
 | 
				
			||||||
 | 
					      "button": "注册",
 | 
				
			||||||
 | 
					      "has_account": "已有账户?",
 | 
				
			||||||
 | 
					      "login": "点击登录"
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "reset": {
 | 
				
			||||||
 | 
					      "title": "密码重置",
 | 
				
			||||||
 | 
					      "email": "邮箱地址",
 | 
				
			||||||
 | 
					      "button": "提交",
 | 
				
			||||||
 | 
					      "notice": "系统将向您的邮箱发送一封包含重置链接的邮件,请注意查收。",
 | 
				
			||||||
 | 
					      "confirm": {
 | 
				
			||||||
 | 
					        "title": "密码重置确认",
 | 
				
			||||||
 | 
					        "new_password": "新密码",
 | 
				
			||||||
 | 
					        "button": "提交",
 | 
				
			||||||
 | 
					        "button_disabled": "密码重置完成",
 | 
				
			||||||
 | 
					        "notice": "新密码已生成,请点击密码框或上方按钮复制。请及时登录并修改密码!"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "messages": {
 | 
				
			||||||
 | 
					    "success": {
 | 
				
			||||||
 | 
					      "login": "登录成功!",
 | 
				
			||||||
 | 
					      "register": "注册成功!",
 | 
				
			||||||
 | 
					      "verification_code": "验证码发送成功,请检查你的邮箱!",
 | 
				
			||||||
 | 
					      "password_reset": "重置邮件发送成功,请检查邮箱!"
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "error": {
 | 
				
			||||||
 | 
					      "login_expired": "未登录或登录已过期,请重新登录!",
 | 
				
			||||||
 | 
					      "password_length": "密码长度不得小于 8 位!",
 | 
				
			||||||
 | 
					      "password_mismatch": "两次输入的密码不一致",
 | 
				
			||||||
 | 
					      "turnstile_wait": "请稍后几秒重试,Turnstile 正在检查用户环境!",
 | 
				
			||||||
 | 
					      "root_password": "请立刻修改默认密码!"
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "notice": {
 | 
				
			||||||
 | 
					      "password_copied": "新密码已复制到剪贴板:{{password}}"
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,12 +12,14 @@ import {
 | 
				
			|||||||
  Card,
 | 
					  Card,
 | 
				
			||||||
} from 'semantic-ui-react';
 | 
					} from 'semantic-ui-react';
 | 
				
			||||||
import { Link, useNavigate, useSearchParams } from 'react-router-dom';
 | 
					import { Link, useNavigate, useSearchParams } from 'react-router-dom';
 | 
				
			||||||
 | 
					import { useTranslation } from 'react-i18next';
 | 
				
			||||||
import { UserContext } from '../context/User';
 | 
					import { UserContext } from '../context/User';
 | 
				
			||||||
import { API, getLogo, showError, showSuccess, showWarning } from '../helpers';
 | 
					import { API, getLogo, showError, showSuccess, showWarning } from '../helpers';
 | 
				
			||||||
import { onGitHubOAuthClicked, onLarkOAuthClicked } from './utils';
 | 
					import { onGitHubOAuthClicked, onLarkOAuthClicked } from './utils';
 | 
				
			||||||
import larkIcon from '../images/lark.svg';
 | 
					import larkIcon from '../images/lark.svg';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const LoginForm = () => {
 | 
					const LoginForm = () => {
 | 
				
			||||||
 | 
					  const { t } = useTranslation();
 | 
				
			||||||
  const [inputs, setInputs] = useState({
 | 
					  const [inputs, setInputs] = useState({
 | 
				
			||||||
    username: '',
 | 
					    username: '',
 | 
				
			||||||
    password: '',
 | 
					    password: '',
 | 
				
			||||||
@@ -33,7 +35,7 @@ const LoginForm = () => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  useEffect(() => {
 | 
					  useEffect(() => {
 | 
				
			||||||
    if (searchParams.get('expired')) {
 | 
					    if (searchParams.get('expired')) {
 | 
				
			||||||
      showError('未登录或登录已过期,请重新登录!');
 | 
					      showError(t('messages.error.login_expired'));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    let status = localStorage.getItem('status');
 | 
					    let status = localStorage.getItem('status');
 | 
				
			||||||
    if (status) {
 | 
					    if (status) {
 | 
				
			||||||
@@ -57,7 +59,7 @@ const LoginForm = () => {
 | 
				
			|||||||
      userDispatch({ type: 'login', payload: data });
 | 
					      userDispatch({ type: 'login', payload: data });
 | 
				
			||||||
      localStorage.setItem('user', JSON.stringify(data));
 | 
					      localStorage.setItem('user', JSON.stringify(data));
 | 
				
			||||||
      navigate('/');
 | 
					      navigate('/');
 | 
				
			||||||
      showSuccess('登录成功!');
 | 
					      showSuccess(t('messages.success.login'));
 | 
				
			||||||
      setShowWeChatLoginModal(false);
 | 
					      setShowWeChatLoginModal(false);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      showError(message);
 | 
					      showError(message);
 | 
				
			||||||
@@ -82,11 +84,11 @@ const LoginForm = () => {
 | 
				
			|||||||
        localStorage.setItem('user', JSON.stringify(data));
 | 
					        localStorage.setItem('user', JSON.stringify(data));
 | 
				
			||||||
        if (username === 'root' && password === '123456') {
 | 
					        if (username === 'root' && password === '123456') {
 | 
				
			||||||
          navigate('/user/edit');
 | 
					          navigate('/user/edit');
 | 
				
			||||||
          showSuccess('登录成功!');
 | 
					          showSuccess(t('messages.success.login'));
 | 
				
			||||||
          showWarning('请立刻修改默认密码!');
 | 
					          showWarning(t('messages.error.root_password'));
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
          navigate('/token');
 | 
					          navigate('/token');
 | 
				
			||||||
          showSuccess('登录成功!');
 | 
					          showSuccess(t('messages.success.login'));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
        showError(message);
 | 
					        showError(message);
 | 
				
			||||||
@@ -110,7 +112,7 @@ const LoginForm = () => {
 | 
				
			|||||||
                style={{ marginBottom: '1.5em' }}
 | 
					                style={{ marginBottom: '1.5em' }}
 | 
				
			||||||
              >
 | 
					              >
 | 
				
			||||||
                <Image src={logo} style={{ marginBottom: '10px' }} />
 | 
					                <Image src={logo} style={{ marginBottom: '10px' }} />
 | 
				
			||||||
                <Header.Content>用户登录</Header.Content>
 | 
					                <Header.Content>{t('auth.login.title')}</Header.Content>
 | 
				
			||||||
              </Header>
 | 
					              </Header>
 | 
				
			||||||
            </Card.Header>
 | 
					            </Card.Header>
 | 
				
			||||||
            <Form size='large'>
 | 
					            <Form size='large'>
 | 
				
			||||||
@@ -118,7 +120,7 @@ const LoginForm = () => {
 | 
				
			|||||||
                fluid
 | 
					                fluid
 | 
				
			||||||
                icon='user'
 | 
					                icon='user'
 | 
				
			||||||
                iconPosition='left'
 | 
					                iconPosition='left'
 | 
				
			||||||
                placeholder='用户名 / 邮箱地址'
 | 
					                placeholder={t('auth.login.username')}
 | 
				
			||||||
                name='username'
 | 
					                name='username'
 | 
				
			||||||
                value={username}
 | 
					                value={username}
 | 
				
			||||||
                onChange={handleChange}
 | 
					                onChange={handleChange}
 | 
				
			||||||
@@ -128,7 +130,7 @@ const LoginForm = () => {
 | 
				
			|||||||
                fluid
 | 
					                fluid
 | 
				
			||||||
                icon='lock'
 | 
					                icon='lock'
 | 
				
			||||||
                iconPosition='left'
 | 
					                iconPosition='left'
 | 
				
			||||||
                placeholder='密码'
 | 
					                placeholder={t('auth.login.password')}
 | 
				
			||||||
                name='password'
 | 
					                name='password'
 | 
				
			||||||
                type='password'
 | 
					                type='password'
 | 
				
			||||||
                value={password}
 | 
					                value={password}
 | 
				
			||||||
@@ -145,7 +147,7 @@ const LoginForm = () => {
 | 
				
			|||||||
                }}
 | 
					                }}
 | 
				
			||||||
                onClick={handleSubmit}
 | 
					                onClick={handleSubmit}
 | 
				
			||||||
              >
 | 
					              >
 | 
				
			||||||
                登录
 | 
					                {t('auth.login.button')}
 | 
				
			||||||
              </Button>
 | 
					              </Button>
 | 
				
			||||||
            </Form>
 | 
					            </Form>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -160,15 +162,15 @@ const LoginForm = () => {
 | 
				
			|||||||
                }}
 | 
					                }}
 | 
				
			||||||
              >
 | 
					              >
 | 
				
			||||||
                <div>
 | 
					                <div>
 | 
				
			||||||
                  忘记密码?
 | 
					                  {t('auth.login.forgot_password')}
 | 
				
			||||||
                  <Link to='/reset' style={{ color: '#2185d0' }}>
 | 
					                  <Link to='/reset' style={{ color: '#2185d0' }}>
 | 
				
			||||||
                    点击重置
 | 
					                    {t('auth.login.reset_password')}
 | 
				
			||||||
                  </Link>
 | 
					                  </Link>
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
                <div>
 | 
					                <div>
 | 
				
			||||||
                  没有账户?
 | 
					                  {t('auth.login.no_account')}
 | 
				
			||||||
                  <Link to='/register' style={{ color: '#2185d0' }}>
 | 
					                  <Link to='/register' style={{ color: '#2185d0' }}>
 | 
				
			||||||
                    点击注册
 | 
					                    {t('auth.login.register')}
 | 
				
			||||||
                  </Link>
 | 
					                  </Link>
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
              </div>
 | 
					              </div>
 | 
				
			||||||
@@ -182,7 +184,7 @@ const LoginForm = () => {
 | 
				
			|||||||
                  horizontal
 | 
					                  horizontal
 | 
				
			||||||
                  style={{ color: '#666', fontSize: '0.9em' }}
 | 
					                  style={{ color: '#666', fontSize: '0.9em' }}
 | 
				
			||||||
                >
 | 
					                >
 | 
				
			||||||
                  使用其他方式登录
 | 
					                  {t('auth.login.other_methods')}
 | 
				
			||||||
                </Divider>
 | 
					                </Divider>
 | 
				
			||||||
                <div
 | 
					                <div
 | 
				
			||||||
                  style={{
 | 
					                  style={{
 | 
				
			||||||
@@ -250,14 +252,12 @@ const LoginForm = () => {
 | 
				
			|||||||
            <Modal.Description>
 | 
					            <Modal.Description>
 | 
				
			||||||
              <Image src={status.wechat_qrcode} fluid />
 | 
					              <Image src={status.wechat_qrcode} fluid />
 | 
				
			||||||
              <div style={{ textAlign: 'center' }}>
 | 
					              <div style={{ textAlign: 'center' }}>
 | 
				
			||||||
                <p>
 | 
					                <p>{t('auth.login.wechat.scan_tip')}</p>
 | 
				
			||||||
                  微信扫码关注公众号,输入「验证码」获取验证码(三分钟内有效)
 | 
					 | 
				
			||||||
                </p>
 | 
					 | 
				
			||||||
              </div>
 | 
					              </div>
 | 
				
			||||||
              <Form size='large'>
 | 
					              <Form size='large'>
 | 
				
			||||||
                <Form.Input
 | 
					                <Form.Input
 | 
				
			||||||
                  fluid
 | 
					                  fluid
 | 
				
			||||||
                  placeholder='验证码'
 | 
					                  placeholder={t('auth.login.wechat.code_placeholder')}
 | 
				
			||||||
                  name='wechat_verification_code'
 | 
					                  name='wechat_verification_code'
 | 
				
			||||||
                  value={inputs.wechat_verification_code}
 | 
					                  value={inputs.wechat_verification_code}
 | 
				
			||||||
                  onChange={handleChange}
 | 
					                  onChange={handleChange}
 | 
				
			||||||
@@ -266,13 +266,13 @@ const LoginForm = () => {
 | 
				
			|||||||
                  fluid
 | 
					                  fluid
 | 
				
			||||||
                  size='large'
 | 
					                  size='large'
 | 
				
			||||||
                  style={{
 | 
					                  style={{
 | 
				
			||||||
                    background: '#2F73FF', // 使用更现代的蓝色
 | 
					                    background: '#2F73FF',
 | 
				
			||||||
                    color: 'white',
 | 
					                    color: 'white',
 | 
				
			||||||
                    marginBottom: '1.5em',
 | 
					                    marginBottom: '1.5em',
 | 
				
			||||||
                  }}
 | 
					                  }}
 | 
				
			||||||
                  onClick={onSubmitWeChatVerificationCode}
 | 
					                  onClick={onSubmitWeChatVerificationCode}
 | 
				
			||||||
                >
 | 
					                >
 | 
				
			||||||
                  登录
 | 
					                  {t('auth.login.button')}
 | 
				
			||||||
                </Button>
 | 
					                </Button>
 | 
				
			||||||
              </Form>
 | 
					              </Form>
 | 
				
			||||||
            </Modal.Description>
 | 
					            </Modal.Description>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,29 +8,23 @@ import {
 | 
				
			|||||||
  Card,
 | 
					  Card,
 | 
				
			||||||
  Message,
 | 
					  Message,
 | 
				
			||||||
} from 'semantic-ui-react';
 | 
					} from 'semantic-ui-react';
 | 
				
			||||||
import {
 | 
					import { useTranslation } from 'react-i18next';
 | 
				
			||||||
  API,
 | 
					import { API, copy, getLogo, showError, showNotice } from '../helpers';
 | 
				
			||||||
  copy,
 | 
					 | 
				
			||||||
  showError,
 | 
					 | 
				
			||||||
  showInfo,
 | 
					 | 
				
			||||||
  showNotice,
 | 
					 | 
				
			||||||
  showSuccess,
 | 
					 | 
				
			||||||
} from '../helpers';
 | 
					 | 
				
			||||||
import { useSearchParams } from 'react-router-dom';
 | 
					import { useSearchParams } from 'react-router-dom';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const PasswordResetConfirm = () => {
 | 
					const PasswordResetConfirm = () => {
 | 
				
			||||||
 | 
					  const { t } = useTranslation();
 | 
				
			||||||
  const [inputs, setInputs] = useState({
 | 
					  const [inputs, setInputs] = useState({
 | 
				
			||||||
    email: '',
 | 
					    email: '',
 | 
				
			||||||
    token: '',
 | 
					    token: '',
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
  const { email, token } = inputs;
 | 
					  const { email, token } = inputs;
 | 
				
			||||||
 | 
					 | 
				
			||||||
  const [loading, setLoading] = useState(false);
 | 
					  const [loading, setLoading] = useState(false);
 | 
				
			||||||
 | 
					 | 
				
			||||||
  const [disableButton, setDisableButton] = useState(false);
 | 
					  const [disableButton, setDisableButton] = useState(false);
 | 
				
			||||||
  const [countdown, setCountdown] = useState(30);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const [newPassword, setNewPassword] = useState('');
 | 
					  const [newPassword, setNewPassword] = useState('');
 | 
				
			||||||
 | 
					  const logo = getLogo();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const [countdown, setCountdown] = useState(30);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const [searchParams, setSearchParams] = useSearchParams();
 | 
					  const [searchParams, setSearchParams] = useSearchParams();
 | 
				
			||||||
  useEffect(() => {
 | 
					  useEffect(() => {
 | 
				
			||||||
@@ -68,7 +62,7 @@ const PasswordResetConfirm = () => {
 | 
				
			|||||||
      let password = res.data.data;
 | 
					      let password = res.data.data;
 | 
				
			||||||
      setNewPassword(password);
 | 
					      setNewPassword(password);
 | 
				
			||||||
      await copy(password);
 | 
					      await copy(password);
 | 
				
			||||||
      showNotice(`新密码已复制到剪贴板:${password}`);
 | 
					      showNotice(t('messages.notice.password_copied', { password }));
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      showError(message);
 | 
					      showError(message);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -90,8 +84,8 @@ const PasswordResetConfirm = () => {
 | 
				
			|||||||
                textAlign='center'
 | 
					                textAlign='center'
 | 
				
			||||||
                style={{ marginBottom: '1.5em' }}
 | 
					                style={{ marginBottom: '1.5em' }}
 | 
				
			||||||
              >
 | 
					              >
 | 
				
			||||||
                <Image src='/logo.png' style={{ marginBottom: '10px' }} />
 | 
					                <Image src={logo} style={{ marginBottom: '10px' }} />
 | 
				
			||||||
                <Header.Content>密码重置确认</Header.Content>
 | 
					                <Header.Content>{t('auth.reset.confirm.title')}</Header.Content>
 | 
				
			||||||
              </Header>
 | 
					              </Header>
 | 
				
			||||||
            </Card.Header>
 | 
					            </Card.Header>
 | 
				
			||||||
            <Form size='large'>
 | 
					            <Form size='large'>
 | 
				
			||||||
@@ -99,7 +93,7 @@ const PasswordResetConfirm = () => {
 | 
				
			|||||||
                fluid
 | 
					                fluid
 | 
				
			||||||
                icon='mail'
 | 
					                icon='mail'
 | 
				
			||||||
                iconPosition='left'
 | 
					                iconPosition='left'
 | 
				
			||||||
                placeholder='邮箱地址'
 | 
					                placeholder={t('auth.reset.email')}
 | 
				
			||||||
                name='email'
 | 
					                name='email'
 | 
				
			||||||
                value={email}
 | 
					                value={email}
 | 
				
			||||||
                readOnly
 | 
					                readOnly
 | 
				
			||||||
@@ -110,7 +104,7 @@ const PasswordResetConfirm = () => {
 | 
				
			|||||||
                  fluid
 | 
					                  fluid
 | 
				
			||||||
                  icon='lock'
 | 
					                  icon='lock'
 | 
				
			||||||
                  iconPosition='left'
 | 
					                  iconPosition='left'
 | 
				
			||||||
                  placeholder='新密码'
 | 
					                  placeholder={t('auth.reset.confirm.new_password')}
 | 
				
			||||||
                  name='newPassword'
 | 
					                  name='newPassword'
 | 
				
			||||||
                  value={newPassword}
 | 
					                  value={newPassword}
 | 
				
			||||||
                  readOnly
 | 
					                  readOnly
 | 
				
			||||||
@@ -122,30 +116,29 @@ const PasswordResetConfirm = () => {
 | 
				
			|||||||
                  onClick={(e) => {
 | 
					                  onClick={(e) => {
 | 
				
			||||||
                    e.target.select();
 | 
					                    e.target.select();
 | 
				
			||||||
                    navigator.clipboard.writeText(newPassword);
 | 
					                    navigator.clipboard.writeText(newPassword);
 | 
				
			||||||
                    showNotice(`密码已复制到剪贴板:${newPassword}`);
 | 
					                    showNotice(t('auth.reset.confirm.notice'));
 | 
				
			||||||
                  }}
 | 
					                  }}
 | 
				
			||||||
                />
 | 
					                />
 | 
				
			||||||
              )}
 | 
					              )}
 | 
				
			||||||
              <Button
 | 
					              <Button
 | 
				
			||||||
                color='blue'
 | 
					 | 
				
			||||||
                fluid
 | 
					                fluid
 | 
				
			||||||
                size='large'
 | 
					                size='large'
 | 
				
			||||||
                onClick={handleSubmit}
 | 
					                onClick={handleSubmit}
 | 
				
			||||||
                loading={loading}
 | 
					                loading={loading}
 | 
				
			||||||
                disabled={disableButton}
 | 
					                disabled={disableButton}
 | 
				
			||||||
                style={{
 | 
					                style={{
 | 
				
			||||||
                  background: '#2F73FF', // 使用更现代的蓝色
 | 
					                  background: '#2F73FF',
 | 
				
			||||||
                  color: 'white',
 | 
					                  color: 'white',
 | 
				
			||||||
                  marginBottom: '1.5em',
 | 
					                  marginBottom: '1.5em',
 | 
				
			||||||
                }}
 | 
					                }}
 | 
				
			||||||
              >
 | 
					              >
 | 
				
			||||||
                {disableButton ? '密码重置完成' : '提交'}
 | 
					                {disableButton ? t('auth.reset.confirm.button_disabled') : t('auth.reset.confirm.button')}
 | 
				
			||||||
              </Button>
 | 
					              </Button>
 | 
				
			||||||
            </Form>
 | 
					            </Form>
 | 
				
			||||||
            {newPassword && (
 | 
					            {newPassword && (
 | 
				
			||||||
              <Message style={{ background: 'transparent', boxShadow: 'none' }}>
 | 
					              <Message style={{ background: 'transparent', boxShadow: 'none' }}>
 | 
				
			||||||
                <p style={{ fontSize: '0.9em', color: '#666' }}>
 | 
					                <p style={{ fontSize: '0.9em', color: '#666' }}>
 | 
				
			||||||
                  新密码已生成,请点击密码框或上方按钮复制。请及时登录并修改密码!
 | 
					                  {t('auth.reset.confirm.notice')}
 | 
				
			||||||
                </p>
 | 
					                </p>
 | 
				
			||||||
              </Message>
 | 
					              </Message>
 | 
				
			||||||
            )}
 | 
					            )}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,21 +8,23 @@ import {
 | 
				
			|||||||
  Card,
 | 
					  Card,
 | 
				
			||||||
  Message,
 | 
					  Message,
 | 
				
			||||||
} from 'semantic-ui-react';
 | 
					} from 'semantic-ui-react';
 | 
				
			||||||
import { API, showError, showInfo, showSuccess } from '../helpers';
 | 
					import { useTranslation } from 'react-i18next';
 | 
				
			||||||
 | 
					import { API, getLogo, showError, showInfo, showSuccess } from '../helpers';
 | 
				
			||||||
import Turnstile from 'react-turnstile';
 | 
					import Turnstile from 'react-turnstile';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const PasswordResetForm = () => {
 | 
					const PasswordResetForm = () => {
 | 
				
			||||||
 | 
					  const { t } = useTranslation();
 | 
				
			||||||
  const [inputs, setInputs] = useState({
 | 
					  const [inputs, setInputs] = useState({
 | 
				
			||||||
    email: '',
 | 
					    email: '',
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
  const { email } = inputs;
 | 
					  const { email } = inputs;
 | 
				
			||||||
 | 
					 | 
				
			||||||
  const [loading, setLoading] = useState(false);
 | 
					  const [loading, setLoading] = useState(false);
 | 
				
			||||||
  const [turnstileEnabled, setTurnstileEnabled] = useState(false);
 | 
					  const [turnstileEnabled, setTurnstileEnabled] = useState(false);
 | 
				
			||||||
  const [turnstileSiteKey, setTurnstileSiteKey] = useState('');
 | 
					  const [turnstileSiteKey, setTurnstileSiteKey] = useState('');
 | 
				
			||||||
  const [turnstileToken, setTurnstileToken] = useState('');
 | 
					  const [turnstileToken, setTurnstileToken] = useState('');
 | 
				
			||||||
  const [disableButton, setDisableButton] = useState(false);
 | 
					  const [disableButton, setDisableButton] = useState(false);
 | 
				
			||||||
  const [countdown, setCountdown] = useState(30);
 | 
					  const [countdown, setCountdown] = useState(30);
 | 
				
			||||||
 | 
					  const logo = getLogo();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  useEffect(() => {
 | 
					  useEffect(() => {
 | 
				
			||||||
    let status = localStorage.getItem('status');
 | 
					    let status = localStorage.getItem('status');
 | 
				
			||||||
@@ -66,10 +68,12 @@ const PasswordResetForm = () => {
 | 
				
			|||||||
    );
 | 
					    );
 | 
				
			||||||
    const { success, message } = res.data;
 | 
					    const { success, message } = res.data;
 | 
				
			||||||
    if (success) {
 | 
					    if (success) {
 | 
				
			||||||
      showSuccess('重置邮件发送成功,请检查邮箱!');
 | 
					      showSuccess(t('auth.reset.notice'));
 | 
				
			||||||
      setInputs({ ...inputs, email: '' });
 | 
					      setInputs({ ...inputs, email: '' });
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      showError(message);
 | 
					      showError(message);
 | 
				
			||||||
 | 
					      setDisableButton(false);
 | 
				
			||||||
 | 
					      setCountdown(30);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    setLoading(false);
 | 
					    setLoading(false);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@@ -89,8 +93,8 @@ const PasswordResetForm = () => {
 | 
				
			|||||||
                textAlign='center'
 | 
					                textAlign='center'
 | 
				
			||||||
                style={{ marginBottom: '1.5em' }}
 | 
					                style={{ marginBottom: '1.5em' }}
 | 
				
			||||||
              >
 | 
					              >
 | 
				
			||||||
                <Image src='/logo.png' style={{ marginBottom: '10px' }} />
 | 
					                <Image src={logo} style={{ marginBottom: '10px' }} />
 | 
				
			||||||
                <Header.Content>密码重置</Header.Content>
 | 
					                <Header.Content>{t('auth.reset.title')}</Header.Content>
 | 
				
			||||||
              </Header>
 | 
					              </Header>
 | 
				
			||||||
            </Card.Header>
 | 
					            </Card.Header>
 | 
				
			||||||
            <Form size='large'>
 | 
					            <Form size='large'>
 | 
				
			||||||
@@ -98,7 +102,7 @@ const PasswordResetForm = () => {
 | 
				
			|||||||
                fluid
 | 
					                fluid
 | 
				
			||||||
                icon='mail'
 | 
					                icon='mail'
 | 
				
			||||||
                iconPosition='left'
 | 
					                iconPosition='left'
 | 
				
			||||||
                placeholder='邮箱地址'
 | 
					                placeholder={t('auth.reset.email')}
 | 
				
			||||||
                name='email'
 | 
					                name='email'
 | 
				
			||||||
                value={email}
 | 
					                value={email}
 | 
				
			||||||
                onChange={handleChange}
 | 
					                onChange={handleChange}
 | 
				
			||||||
@@ -133,12 +137,12 @@ const PasswordResetForm = () => {
 | 
				
			|||||||
                  marginBottom: '1.5em',
 | 
					                  marginBottom: '1.5em',
 | 
				
			||||||
                }}
 | 
					                }}
 | 
				
			||||||
              >
 | 
					              >
 | 
				
			||||||
                {disableButton ? `重试 (${countdown})` : '提交'}
 | 
					                {disableButton ? t('auth.register.get_code_retry', { countdown }) : t('auth.reset.button')}
 | 
				
			||||||
              </Button>
 | 
					              </Button>
 | 
				
			||||||
            </Form>
 | 
					            </Form>
 | 
				
			||||||
            <Message style={{ background: 'transparent', boxShadow: 'none' }}>
 | 
					            <Message style={{ background: 'transparent', boxShadow: 'none' }}>
 | 
				
			||||||
              <p style={{ fontSize: '0.9em', color: '#666' }}>
 | 
					              <p style={{ fontSize: '0.9em', color: '#666' }}>
 | 
				
			||||||
                系统将向您的邮箱发送一封包含重置链接的邮件,请注意查收。
 | 
					                {t('auth.reset.notice')}
 | 
				
			||||||
              </p>
 | 
					              </p>
 | 
				
			||||||
            </Message>
 | 
					            </Message>
 | 
				
			||||||
          </Card.Content>
 | 
					          </Card.Content>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,15 +6,16 @@ import {
 | 
				
			|||||||
  Header,
 | 
					  Header,
 | 
				
			||||||
  Image,
 | 
					  Image,
 | 
				
			||||||
  Message,
 | 
					  Message,
 | 
				
			||||||
  Segment,
 | 
					 | 
				
			||||||
  Card,
 | 
					  Card,
 | 
				
			||||||
  Divider,
 | 
					  Divider,
 | 
				
			||||||
} from 'semantic-ui-react';
 | 
					} from 'semantic-ui-react';
 | 
				
			||||||
import { Link, useNavigate } from 'react-router-dom';
 | 
					import { Link, useNavigate } from 'react-router-dom';
 | 
				
			||||||
 | 
					import { useTranslation } from 'react-i18next';
 | 
				
			||||||
import { API, getLogo, showError, showInfo, showSuccess } from '../helpers';
 | 
					import { API, getLogo, showError, showInfo, showSuccess } from '../helpers';
 | 
				
			||||||
import Turnstile from 'react-turnstile';
 | 
					import Turnstile from 'react-turnstile';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const RegisterForm = () => {
 | 
					const RegisterForm = () => {
 | 
				
			||||||
 | 
					  const { t } = useTranslation();
 | 
				
			||||||
  const [inputs, setInputs] = useState({
 | 
					  const [inputs, setInputs] = useState({
 | 
				
			||||||
    username: '',
 | 
					    username: '',
 | 
				
			||||||
    password: '',
 | 
					    password: '',
 | 
				
			||||||
@@ -28,6 +29,8 @@ const RegisterForm = () => {
 | 
				
			|||||||
  const [turnstileSiteKey, setTurnstileSiteKey] = useState('');
 | 
					  const [turnstileSiteKey, setTurnstileSiteKey] = useState('');
 | 
				
			||||||
  const [turnstileToken, setTurnstileToken] = useState('');
 | 
					  const [turnstileToken, setTurnstileToken] = useState('');
 | 
				
			||||||
  const [loading, setLoading] = useState(false);
 | 
					  const [loading, setLoading] = useState(false);
 | 
				
			||||||
 | 
					  const [disableButton, setDisableButton] = useState(false);
 | 
				
			||||||
 | 
					  const [countdown, setCountdown] = useState(30);
 | 
				
			||||||
  const logo = getLogo();
 | 
					  const logo = getLogo();
 | 
				
			||||||
  let affCode = new URLSearchParams(window.location.search).get('aff');
 | 
					  let affCode = new URLSearchParams(window.location.search).get('aff');
 | 
				
			||||||
  if (affCode) {
 | 
					  if (affCode) {
 | 
				
			||||||
@@ -46,6 +49,19 @@ const RegisterForm = () => {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  useEffect(() => {
 | 
				
			||||||
 | 
					    let countdownInterval = null;
 | 
				
			||||||
 | 
					    if (disableButton && countdown > 0) {
 | 
				
			||||||
 | 
					      countdownInterval = setInterval(() => {
 | 
				
			||||||
 | 
					        setCountdown(countdown - 1);
 | 
				
			||||||
 | 
					      }, 1000);
 | 
				
			||||||
 | 
					    } else if (countdown === 0) {
 | 
				
			||||||
 | 
					      setDisableButton(false);
 | 
				
			||||||
 | 
					      setCountdown(30);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return () => clearInterval(countdownInterval);
 | 
				
			||||||
 | 
					  }, [disableButton, countdown]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  let navigate = useNavigate();
 | 
					  let navigate = useNavigate();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function handleChange(e) {
 | 
					  function handleChange(e) {
 | 
				
			||||||
@@ -56,16 +72,16 @@ const RegisterForm = () => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  async function handleSubmit(e) {
 | 
					  async function handleSubmit(e) {
 | 
				
			||||||
    if (password.length < 8) {
 | 
					    if (password.length < 8) {
 | 
				
			||||||
      showInfo('密码长度不得小于 8 位!');
 | 
					      showInfo(t('messages.error.password_length'));
 | 
				
			||||||
      return;
 | 
					      return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (password !== password2) {
 | 
					    if (password !== password2) {
 | 
				
			||||||
      showInfo('两次输入的密码不一致');
 | 
					      showInfo(t('messages.error.password_mismatch'));
 | 
				
			||||||
      return;
 | 
					      return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (username && password) {
 | 
					    if (username && password) {
 | 
				
			||||||
      if (turnstileEnabled && turnstileToken === '') {
 | 
					      if (turnstileEnabled && turnstileToken === '') {
 | 
				
			||||||
        showInfo('请稍后几秒重试,Turnstile 正在检查用户环境!');
 | 
					        showInfo(t('messages.error.turnstile_wait'));
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      setLoading(true);
 | 
					      setLoading(true);
 | 
				
			||||||
@@ -80,7 +96,7 @@ const RegisterForm = () => {
 | 
				
			|||||||
      const { success, message } = res.data;
 | 
					      const { success, message } = res.data;
 | 
				
			||||||
      if (success) {
 | 
					      if (success) {
 | 
				
			||||||
        navigate('/login');
 | 
					        navigate('/login');
 | 
				
			||||||
        showSuccess('注册成功!');
 | 
					        showSuccess(t('messages.success.register'));
 | 
				
			||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
        showError(message);
 | 
					        showError(message);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
@@ -91,18 +107,21 @@ const RegisterForm = () => {
 | 
				
			|||||||
  const sendVerificationCode = async () => {
 | 
					  const sendVerificationCode = async () => {
 | 
				
			||||||
    if (inputs.email === '') return;
 | 
					    if (inputs.email === '') return;
 | 
				
			||||||
    if (turnstileEnabled && turnstileToken === '') {
 | 
					    if (turnstileEnabled && turnstileToken === '') {
 | 
				
			||||||
      showInfo('请稍后几秒重试,Turnstile 正在检查用户环境!');
 | 
					      showInfo(t('messages.error.turnstile_wait'));
 | 
				
			||||||
      return;
 | 
					      return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    setDisableButton(true);
 | 
				
			||||||
    setLoading(true);
 | 
					    setLoading(true);
 | 
				
			||||||
    const res = await API.get(
 | 
					    const res = await API.get(
 | 
				
			||||||
      `/api/verification?email=${inputs.email}&turnstile=${turnstileToken}`
 | 
					      `/api/verification?email=${inputs.email}&turnstile=${turnstileToken}`
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
    const { success, message } = res.data;
 | 
					    const { success, message } = res.data;
 | 
				
			||||||
    if (success) {
 | 
					    if (success) {
 | 
				
			||||||
      showSuccess('验证码发送成功,请检查你的邮箱!');
 | 
					      showSuccess(t('messages.success.verification_code'));
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      showError(message);
 | 
					      showError(message);
 | 
				
			||||||
 | 
					      setDisableButton(false);
 | 
				
			||||||
 | 
					      setCountdown(30);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    setLoading(false);
 | 
					    setLoading(false);
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
@@ -123,7 +142,7 @@ const RegisterForm = () => {
 | 
				
			|||||||
                style={{ marginBottom: '1.5em' }}
 | 
					                style={{ marginBottom: '1.5em' }}
 | 
				
			||||||
              >
 | 
					              >
 | 
				
			||||||
                <Image src={logo} style={{ marginBottom: '10px' }} />
 | 
					                <Image src={logo} style={{ marginBottom: '10px' }} />
 | 
				
			||||||
                <Header.Content>新用户注册</Header.Content>
 | 
					                <Header.Content>{t('auth.register.title')}</Header.Content>
 | 
				
			||||||
              </Header>
 | 
					              </Header>
 | 
				
			||||||
            </Card.Header>
 | 
					            </Card.Header>
 | 
				
			||||||
            <Form size='large'>
 | 
					            <Form size='large'>
 | 
				
			||||||
@@ -131,7 +150,7 @@ const RegisterForm = () => {
 | 
				
			|||||||
                fluid
 | 
					                fluid
 | 
				
			||||||
                icon='user'
 | 
					                icon='user'
 | 
				
			||||||
                iconPosition='left'
 | 
					                iconPosition='left'
 | 
				
			||||||
                placeholder='输入用户名,最长 12 位'
 | 
					                placeholder={t('auth.register.username')}
 | 
				
			||||||
                onChange={handleChange}
 | 
					                onChange={handleChange}
 | 
				
			||||||
                name='username'
 | 
					                name='username'
 | 
				
			||||||
                style={{ marginBottom: '1em' }}
 | 
					                style={{ marginBottom: '1em' }}
 | 
				
			||||||
@@ -140,7 +159,7 @@ const RegisterForm = () => {
 | 
				
			|||||||
                fluid
 | 
					                fluid
 | 
				
			||||||
                icon='lock'
 | 
					                icon='lock'
 | 
				
			||||||
                iconPosition='left'
 | 
					                iconPosition='left'
 | 
				
			||||||
                placeholder='输入密码,最短 8 位,最长 20 位'
 | 
					                placeholder={t('auth.register.password')}
 | 
				
			||||||
                onChange={handleChange}
 | 
					                onChange={handleChange}
 | 
				
			||||||
                name='password'
 | 
					                name='password'
 | 
				
			||||||
                type='password'
 | 
					                type='password'
 | 
				
			||||||
@@ -150,7 +169,7 @@ const RegisterForm = () => {
 | 
				
			|||||||
                fluid
 | 
					                fluid
 | 
				
			||||||
                icon='lock'
 | 
					                icon='lock'
 | 
				
			||||||
                iconPosition='left'
 | 
					                iconPosition='left'
 | 
				
			||||||
                placeholder='再次输入密码'
 | 
					                placeholder={t('auth.register.confirm_password')}
 | 
				
			||||||
                onChange={handleChange}
 | 
					                onChange={handleChange}
 | 
				
			||||||
                name='password2'
 | 
					                name='password2'
 | 
				
			||||||
                type='password'
 | 
					                type='password'
 | 
				
			||||||
@@ -163,7 +182,7 @@ const RegisterForm = () => {
 | 
				
			|||||||
                    fluid
 | 
					                    fluid
 | 
				
			||||||
                    icon='mail'
 | 
					                    icon='mail'
 | 
				
			||||||
                    iconPosition='left'
 | 
					                    iconPosition='left'
 | 
				
			||||||
                    placeholder='输入邮箱地址'
 | 
					                    placeholder={t('auth.register.email')}
 | 
				
			||||||
                    onChange={handleChange}
 | 
					                    onChange={handleChange}
 | 
				
			||||||
                    name='email'
 | 
					                    name='email'
 | 
				
			||||||
                    type='email'
 | 
					                    type='email'
 | 
				
			||||||
@@ -171,9 +190,10 @@ const RegisterForm = () => {
 | 
				
			|||||||
                      <Button
 | 
					                      <Button
 | 
				
			||||||
                        onClick={sendVerificationCode}
 | 
					                        onClick={sendVerificationCode}
 | 
				
			||||||
                        disabled={loading}
 | 
					                        disabled={loading}
 | 
				
			||||||
                        // style={{ backgroundColor: '#2F73FF', color: 'white' }}
 | 
					 | 
				
			||||||
                      >
 | 
					                      >
 | 
				
			||||||
                        获取验证码
 | 
					                        {disableButton 
 | 
				
			||||||
 | 
					                          ? t('auth.register.get_code_retry', { countdown })
 | 
				
			||||||
 | 
					                          : t('auth.register.get_code')}
 | 
				
			||||||
                      </Button>
 | 
					                      </Button>
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    style={{ marginBottom: '1em' }}
 | 
					                    style={{ marginBottom: '1em' }}
 | 
				
			||||||
@@ -182,7 +202,7 @@ const RegisterForm = () => {
 | 
				
			|||||||
                    fluid
 | 
					                    fluid
 | 
				
			||||||
                    icon='lock'
 | 
					                    icon='lock'
 | 
				
			||||||
                    iconPosition='left'
 | 
					                    iconPosition='left'
 | 
				
			||||||
                    placeholder='输入验证码'
 | 
					                    placeholder={t('auth.register.verification_code')}
 | 
				
			||||||
                    onChange={handleChange}
 | 
					                    onChange={handleChange}
 | 
				
			||||||
                    name='verification_code'
 | 
					                    name='verification_code'
 | 
				
			||||||
                    style={{ marginBottom: '1em' }}
 | 
					                    style={{ marginBottom: '1em' }}
 | 
				
			||||||
@@ -218,7 +238,7 @@ const RegisterForm = () => {
 | 
				
			|||||||
                }}
 | 
					                }}
 | 
				
			||||||
                loading={loading}
 | 
					                loading={loading}
 | 
				
			||||||
              >
 | 
					              >
 | 
				
			||||||
                注册
 | 
					                {t('auth.register.button')}
 | 
				
			||||||
              </Button>
 | 
					              </Button>
 | 
				
			||||||
            </Form>
 | 
					            </Form>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -231,9 +251,9 @@ const RegisterForm = () => {
 | 
				
			|||||||
                  color: '#666',
 | 
					                  color: '#666',
 | 
				
			||||||
                }}
 | 
					                }}
 | 
				
			||||||
              >
 | 
					              >
 | 
				
			||||||
                已有账户?
 | 
					                {t('auth.register.has_account')}
 | 
				
			||||||
                <Link to='/login' style={{ color: '#2185d0' }}>
 | 
					                <Link to='/login' style={{ color: '#2185d0' }}>
 | 
				
			||||||
                  点击登录
 | 
					                  {t('auth.register.login')}
 | 
				
			||||||
                </Link>
 | 
					                </Link>
 | 
				
			||||||
              </div>
 | 
					              </div>
 | 
				
			||||||
            </Message>
 | 
					            </Message>
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user