chore: update default theme style

This commit is contained in:
JustSong 2025-02-02 16:02:38 +08:00
parent 9b83d63896
commit c64b7c891f
7 changed files with 224 additions and 75 deletions

View File

@ -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(),

View File

@ -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}}"
}
} }
} }

View File

@ -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}}"
}
} }
} }

View File

@ -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>

View File

@ -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>
)} )}

View File

@ -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>

View File

@ -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>