diff --git a/controller/misc.go b/controller/misc.go index ae900870..c2764b57 100644 --- a/controller/misc.go +++ b/controller/misc.go @@ -3,12 +3,13 @@ package controller import ( "encoding/json" "fmt" + "net/http" + "strings" + "github.com/songquanpeng/one-api/common" "github.com/songquanpeng/one-api/common/config" "github.com/songquanpeng/one-api/common/message" "github.com/songquanpeng/one-api/model" - "net/http" - "strings" "github.com/gin-gonic/gin" ) @@ -120,6 +121,7 @@ func SendEmailVerification(c *gin.Context) { "
验证码 %d 分钟内有效,如果不是本人操作,请忽略。
", config.SystemName, code, common.VerificationValidMinutes) err := message.SendEmail(subject, email, content) if err != nil { + c.JSON(http.StatusOK, gin.H{ "success": false, "message": err.Error(), diff --git a/web/default/public/locales/en/translation.json b/web/default/public/locales/en/translation.json index 4e5a4e01..11394445 100644 --- a/web/default/public/locales/en/translation.json +++ b/web/default/public/locales/en/translation.json @@ -571,7 +571,9 @@ "qrcode_placeholder": "Enter an image URL", "buttons": { "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": { "title": "Turnstile Configuration", @@ -754,5 +756,72 @@ } }, "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}}" + } } } diff --git a/web/default/public/locales/zh/translation.json b/web/default/public/locales/zh/translation.json index 64c096e1..14f14776 100644 --- a/web/default/public/locales/zh/translation.json +++ b/web/default/public/locales/zh/translation.json @@ -720,10 +720,10 @@ } }, "about": { - "title": "关于系统", - "description": "可在设置页面设置关于内容,支持 HTML & Markdown", - "repository": "项目仓库地址:", - "loading_failed": "加载关于内容失败..." + "title": "关于", + "description": "One API 是一个开源的接口管理和代理平台。", + "repository": "项目地址:", + "loading_failed": "加载失败" }, "footer": { "built_by": "由", @@ -758,5 +758,66 @@ } }, "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}}" + } } } diff --git a/web/default/src/components/LoginForm.js b/web/default/src/components/LoginForm.js index 437bc8ad..569aa7e5 100644 --- a/web/default/src/components/LoginForm.js +++ b/web/default/src/components/LoginForm.js @@ -12,12 +12,14 @@ import { Card, } from 'semantic-ui-react'; import { Link, useNavigate, useSearchParams } from 'react-router-dom'; +import { useTranslation } from 'react-i18next'; import { UserContext } from '../context/User'; import { API, getLogo, showError, showSuccess, showWarning } from '../helpers'; import { onGitHubOAuthClicked, onLarkOAuthClicked } from './utils'; import larkIcon from '../images/lark.svg'; const LoginForm = () => { + const { t } = useTranslation(); const [inputs, setInputs] = useState({ username: '', password: '', @@ -33,7 +35,7 @@ const LoginForm = () => { useEffect(() => { if (searchParams.get('expired')) { - showError('未登录或登录已过期,请重新登录!'); + showError(t('messages.error.login_expired')); } let status = localStorage.getItem('status'); if (status) { @@ -57,7 +59,7 @@ const LoginForm = () => { userDispatch({ type: 'login', payload: data }); localStorage.setItem('user', JSON.stringify(data)); navigate('/'); - showSuccess('登录成功!'); + showSuccess(t('messages.success.login')); setShowWeChatLoginModal(false); } else { showError(message); @@ -82,11 +84,11 @@ const LoginForm = () => { localStorage.setItem('user', JSON.stringify(data)); if (username === 'root' && password === '123456') { navigate('/user/edit'); - showSuccess('登录成功!'); - showWarning('请立刻修改默认密码!'); + showSuccess(t('messages.success.login')); + showWarning(t('messages.error.root_password')); } else { navigate('/token'); - showSuccess('登录成功!'); + showSuccess(t('messages.success.login')); } } else { showError(message); @@ -110,7 +112,7 @@ const LoginForm = () => { style={{ marginBottom: '1.5em' }} >- 微信扫码关注公众号,输入「验证码」获取验证码(三分钟内有效) -
+{t('auth.login.wechat.scan_tip')}
- 新密码已生成,请点击密码框或上方按钮复制。请及时登录并修改密码! + {t('auth.reset.confirm.notice')}
- 系统将向您的邮箱发送一封包含重置链接的邮件,请注意查收。 + {t('auth.reset.notice')}