From 9934cdc5bdb5448c3433195ef1c40a10e5b5b270 Mon Sep 17 00:00:00 2001 From: t0ng7u Date: Sat, 16 Aug 2025 19:22:14 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=8C=90=20feat(i18n):=20add=20internationa?= =?UTF-8?q?lization=20support=20for=20TwoFASetting=20component?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add comprehensive i18n support to TwoFASetting.js component - Add all required English translations to en.json for 2FA settings - Update component to accept t function as prop and use translation keys - Fix prop passing in PersonalSetting.js to provide t function - Maintain all existing UI improvements and functionality - Support both Chinese and English interfaces for: * Main 2FA settings card with status indicators * Setup modal with guided steps (QR scan, backup codes, verification) * Disable 2FA modal with impact warnings and confirmation * Regenerate backup codes modal with success states * All buttons, placeholders, messages, and notifications - Follow project i18n conventions using t('key') pattern - Ensure seamless language switching for enhanced user experience This enables the 2FA settings to be fully localized while preserving the modern UI design and improved user workflow from previous updates. --- .../components/settings/PersonalSetting.js | 2 +- web/src/components/settings/TwoFASetting.js | 122 +++++++++--------- web/src/i18n/locales/en.json | 59 ++++++++- 3 files changed, 119 insertions(+), 64 deletions(-) diff --git a/web/src/components/settings/PersonalSetting.js b/web/src/components/settings/PersonalSetting.js index 0a350084..010b5051 100644 --- a/web/src/components/settings/PersonalSetting.js +++ b/web/src/components/settings/PersonalSetting.js @@ -1043,7 +1043,7 @@ const PersonalSetting = () => { {/* 两步验证设置 */} - + {/* 危险区域 */} { +const TwoFASetting = ({ t }) => { const [loading, setLoading] = useState(false); const [status, setStatus] = useState({ enabled: false, @@ -59,7 +59,7 @@ const TwoFASetting = () => { setStatus(res.data.data); } } catch (error) { - showError('获取2FA状态失败'); + showError(t('获取2FA状态失败')); } }; @@ -80,7 +80,7 @@ const TwoFASetting = () => { showError(res.data.message); } } catch (error) { - showError('设置2FA失败'); + showError(t('设置2FA失败')); } finally { setLoading(false); } @@ -89,7 +89,7 @@ const TwoFASetting = () => { // 启用2FA const handleEnable2FA = async () => { if (!verificationCode) { - showWarning('请输入验证码'); + showWarning(t('请输入验证码')); return; } @@ -99,7 +99,7 @@ const TwoFASetting = () => { code: verificationCode }); if (res.data.success) { - showSuccess('两步验证启用成功!'); + showSuccess(t('两步验证启用成功!')); setEnableModalVisible(false); setSetupModalVisible(false); setVerificationCode(''); @@ -109,7 +109,7 @@ const TwoFASetting = () => { showError(res.data.message); } } catch (error) { - showError('启用2FA失败'); + showError(t('启用2FA失败')); } finally { setLoading(false); } @@ -118,12 +118,12 @@ const TwoFASetting = () => { // 禁用2FA const handleDisable2FA = async () => { if (!verificationCode) { - showWarning('请输入验证码或备用码'); + showWarning(t('请输入验证码或备用码')); return; } if (!confirmDisable) { - showWarning('请确认您已了解禁用两步验证的后果'); + showWarning(t('请确认您已了解禁用两步验证的后果')); return; } @@ -133,7 +133,7 @@ const TwoFASetting = () => { code: verificationCode }); if (res.data.success) { - showSuccess('两步验证已禁用'); + showSuccess(t('两步验证已禁用')); setDisableModalVisible(false); setVerificationCode(''); setConfirmDisable(false); @@ -142,7 +142,7 @@ const TwoFASetting = () => { showError(res.data.message); } } catch (error) { - showError('禁用2FA失败'); + showError(t('禁用2FA失败')); } finally { setLoading(false); } @@ -151,7 +151,7 @@ const TwoFASetting = () => { // 重新生成备用码 const handleRegenerateBackupCodes = async () => { if (!verificationCode) { - showWarning('请输入验证码'); + showWarning(t('请输入验证码')); return; } @@ -162,31 +162,31 @@ const TwoFASetting = () => { }); if (res.data.success) { setBackupCodes(res.data.data.backup_codes); - showSuccess('备用码重新生成成功'); + showSuccess(t('备用码重新生成成功')); setVerificationCode(''); fetchStatus(); } else { showError(res.data.message); } } catch (error) { - showError('重新生成备用码失败'); + showError(t('重新生成备用码失败')); } finally { setLoading(false); } }; // 通用复制函数 - const copyTextToClipboard = (text, successMessage = '已复制到剪贴板') => { + const copyTextToClipboard = (text, successMessage = t('已复制到剪贴板')) => { navigator.clipboard.writeText(text).then(() => { showSuccess(successMessage); }).catch(() => { - showError('复制失败,请手动复制'); + showError(t('复制失败,请手动复制')); }); }; const copyBackupCodes = () => { const codesText = backupCodes.join('\n'); - copyTextToClipboard(codesText, '备用码已复制到剪贴板'); + copyTextToClipboard(codesText, t('备用码已复制到剪贴板')); }; // 备用码展示组件 @@ -229,7 +229,7 @@ const TwoFASetting = () => { onClick={onCopy} className="!rounded-lg !bg-slate-600 hover:!bg-slate-700 w-full" > - 复制所有代码 + {t('复制所有代码')} @@ -245,7 +245,7 @@ const TwoFASetting = () => { onClick={() => setCurrentStep(currentStep - 1)} className="!rounded-lg" > - 上一步 + {t('上一步')} )} {currentStep < 2 ? ( @@ -255,7 +255,7 @@ const TwoFASetting = () => { onClick={() => setCurrentStep(currentStep + 1)} className="!rounded-lg !bg-slate-600 hover:!bg-slate-700" > - 下一步 + {t('下一步')} ) : ( )} @@ -290,7 +290,7 @@ const TwoFASetting = () => { }} className="!rounded-lg" > - 取消 + {t('取消')} ); @@ -320,7 +320,7 @@ const TwoFASetting = () => { }} className="!rounded-lg !bg-slate-600 hover:!bg-slate-700" > - 完成 + {t('完成')} ); } @@ -335,7 +335,7 @@ const TwoFASetting = () => { }} className="!rounded-lg" > - 取消 + {t('取消')} ); @@ -366,23 +366,23 @@ const TwoFASetting = () => {
- 两步验证设置 + {t('两步验证设置')} {status.enabled ? ( - 已启用 + {t('已启用')} ) : ( - 未启用 + {t('未启用')} )} {status.locked && ( - 账户已锁定 + {t('账户已锁定')} )}
- 两步验证(2FA)为您的账户提供额外的安全保护。启用后,登录时需要输入密码和验证器应用生成的验证码。 + {t('两步验证(2FA)为您的账户提供额外的安全保护。启用后,登录时需要输入密码和验证器应用生成的验证码。')} {status.enabled && (
- 剩余备用码:{status.backup_codes_remaining || 0} 个 + {t('剩余备用码:')}{status.backup_codes_remaining || 0}{t('个')}
)}
@@ -398,7 +398,7 @@ const TwoFASetting = () => { className="!rounded-lg !bg-slate-600 hover:!bg-slate-700" icon={} > - 启用验证 + {t('启用验证')} ) : (
@@ -410,7 +410,7 @@ const TwoFASetting = () => { className="!rounded-lg !bg-slate-500 hover:!bg-slate-600" icon={} > - 禁用两步验证 + {t('禁用两步验证')}
)} @@ -433,7 +433,7 @@ const TwoFASetting = () => { title={
- 设置两步验证 + {t('设置两步验证')}
} visible={setupModalVisible} @@ -451,9 +451,9 @@ const TwoFASetting = () => {
{/* 步骤进度 */} - - - + + + {/* 步骤内容 */} @@ -461,7 +461,7 @@ const TwoFASetting = () => { {currentStep === 0 && (
- 使用认证器应用(如 Google Authenticator、Microsoft Authenticator)扫描下方二维码: + {t('使用认证器应用(如 Google Authenticator、Microsoft Authenticator)扫描下方二维码:')}
@@ -470,7 +470,7 @@ const TwoFASetting = () => {
- 或手动输入密钥:{setupData.secret} + {t('或手动输入密钥:')}{setupData.secret}
@@ -481,10 +481,10 @@ const TwoFASetting = () => { {/* 备用码展示 */} { const codesText = setupData.backup_codes.join('\n'); - copyTextToClipboard(codesText, '备用码已复制到剪贴板'); + copyTextToClipboard(codesText, t('备用码已复制到剪贴板')); }} />
@@ -492,7 +492,7 @@ const TwoFASetting = () => { {currentStep === 2 && ( { title={
- 禁用两步验证 + {t('禁用两步验证')}
} visible={disableModalVisible} @@ -528,7 +528,7 @@ const TwoFASetting = () => {
@@ -537,24 +537,24 @@ const TwoFASetting = () => {
- 禁用后的影响: + {t('禁用后的影响:')}
  • - 降低您账户的安全性 + {t('降低您账户的安全性')}
  • - 需要重新完整设置才能再次启用 + {t('需要重新完整设置才能再次启用')}
  • - 永久删除您的两步验证设置 + {t('永久删除您的两步验证设置')}
  • - 永久删除所有备用码(包括未使用的) + {t('永久删除所有备用码(包括未使用的)')}
@@ -564,10 +564,10 @@ const TwoFASetting = () => {
- 验证身份 + {t('验证身份')} { onChange={(e) => setConfirmDisable(e.target.checked)} className="text-sm" > - 我已了解禁用两步验证将永久删除所有相关设置和备用码,此操作不可撤销 + {t('我已了解禁用两步验证将永久删除所有相关设置和备用码,此操作不可撤销')}
@@ -594,7 +594,7 @@ const TwoFASetting = () => { title={
- 重新生成备用码 + {t('重新生成备用码')}
} visible={backupModalVisible} @@ -614,7 +614,7 @@ const TwoFASetting = () => {
@@ -623,10 +623,10 @@ const TwoFASetting = () => {
- 验证身份 + {t('验证身份')} {
- 新的备用码已生成 + {t('新的备用码已生成')}
- 旧的备用码已失效,请保存新的备用码 + {t('旧的备用码已失效,请保存新的备用码')} {/* 备用码展示 */} diff --git a/web/src/i18n/locales/en.json b/web/src/i18n/locales/en.json index 3b4700f6..14870045 100644 --- a/web/src/i18n/locales/en.json +++ b/web/src/i18n/locales/en.json @@ -697,7 +697,7 @@ "令牌分组": "Token grouping", "隐": "hidden", "本站当前已启用模型": "The model is currently enabled on this site", - "个": "indivual", + "个": " indivual", "倍率是本站的计算方式,不同模型有着不同的倍率,并非官方价格的多少倍,请务必知晓。": "The magnification is the calculation method of this website. Different models have different magnifications, which are not multiples of the official price. Please be sure to know.", "所有各厂聊天模型请统一使用OpenAI方式请求,支持OpenAI官方库
Claude()Claude官方格式请求": "Please use the OpenAI method to request all chat models from each factory, and support the OpenAI official library
Claude()Claude official format request", "分组说明": "Group description", @@ -1918,5 +1918,60 @@ "后缀名称匹配": "Suffix name matching", "包含名称匹配": "Contains name matching", "展开更多": "Expand more", - "已切换至最优倍率视图,每个模型使用其最低倍率分组": "Switched to the optimal ratio view, each model uses its lowest ratio group" + "已切换至最优倍率视图,每个模型使用其最低倍率分组": "Switched to the optimal ratio view, each model uses its lowest ratio group", + "两步验证设置": "Two-factor authentication settings", + "两步验证(2FA)为您的账户提供额外的安全保护。启用后,登录时需要输入密码和验证器应用生成的验证码。": "Two-factor authentication (2FA) provides additional security protection for your account. After enabling, you need to enter your password and the verification code generated by the authenticator application when logging in.", + "启用两步验证": "Enable two-factor authentication", + "禁用两步验证": "Disable two-factor authentication", + "启用两步验证后,登录时需要输入密码和验证器应用生成的验证码": "After enabling two-factor authentication, you need to enter your password and the verification code generated by the authenticator application when logging in", + "禁用两步验证后,登录时只需要输入密码": "After disabling two-factor authentication, you only need to enter your password when logging in", + "验证身份": "Verify identity", + "为了保护您的账户安全,请输入认证器验证码来确认身份": "To protect your account security, please enter the authenticator verification code to confirm your identity", + "输入认证器应用显示的6位数字验证码": "Enter the 6-digit verification code displayed on the authenticator application", + "新的备用恢复代码": "New backup recovery code", + "新的备用码已生成": "New backup code has been generated", + "我已了解禁用两步验证将永久删除所有相关设置和备用码,此操作不可撤销": "I have understood that disabling two-factor authentication will permanently delete all related settings and backup codes, this operation cannot be undone", + "账户已锁定": "Account locked", + "剩余备用码:": "Remaining backup codes: ", + "启用验证": "Enable Authentication", + "重新生成备用码": "Regenerate backup codes", + "设置两步验证": "Set up two-factor authentication", + "扫描二维码": "Scan QR code", + "使用认证器应用扫描二维码": "Scan QR code with authenticator app", + "保存备用码": "Save backup codes", + "保存备用码以备不时之需": "Save backup codes for emergencies", + "验证设置": "Verify setup", + "输入验证码完成设置": "Enter verification code to complete setup", + "使用认证器应用(如 Google Authenticator、Microsoft Authenticator)扫描下方二维码:": "Use an authenticator app (such as Google Authenticator, Microsoft Authenticator) to scan the QR code below:", + "或手动输入密钥:": "Or manually enter the secret:", + "备用恢复代码": "Backup recovery codes", + "复制所有代码": "Copy all codes", + "上一步": "Previous", + "下一步": "Next", + "完成设置并启用两步验证": "Complete setup and enable two-factor authentication", + "确认禁用": "Confirm disable", + "完成": "Complete", + "生成新的备用码": "Generate new backup codes", + "警告:禁用两步验证将永久删除您的验证设置和所有备用码,此操作不可撤销!": "Warning: Disabling two-factor authentication will permanently delete your verification settings and all backup codes. This action is irreversible!", + "禁用后的影响:": "Impact after disabling:", + "降低您账户的安全性": "Reduce your account security", + "需要重新完整设置才能再次启用": "Need to set up again to re-enable", + "永久删除您的两步验证设置": "Permanently delete your two-factor authentication settings", + "永久删除所有备用码(包括未使用的)": "Permanently delete all backup codes (including unused ones)", + "请输入认证器验证码或备用码": "Please enter authenticator verification code or backup code", + "重新生成备用码将使现有的备用码失效,请确保您已保存了当前的备用码。": "Regenerating backup codes will invalidate existing backup codes. Please ensure you have saved the current backup codes.", + "请输入认证器验证码": "Please enter authenticator verification code", + "旧的备用码已失效,请保存新的备用码": "Old backup codes have been invalidated, please save the new backup codes", + "获取2FA状态失败": "Failed to get 2FA status", + "设置2FA失败": "Failed to set up 2FA", + "请输入验证码": "Please enter verification code", + "两步验证启用成功!": "Two-factor authentication enabled successfully!", + "启用2FA失败": "Failed to enable 2FA", + "请输入验证码或备用码": "Please enter verification code or backup code", + "请确认您已了解禁用两步验证的后果": "Please confirm that you understand the consequences of disabling two-factor authentication", + "两步验证已禁用": "Two-factor authentication has been disabled", + "禁用2FA失败": "Failed to disable 2FA", + "备用码重新生成成功": "Backup codes regenerated successfully", + "重新生成备用码失败": "Failed to regenerate backup codes", + "备用码已复制到剪贴板": "Backup codes copied to clipboard" } \ No newline at end of file