From 3bcc0c19ceca507760605f38c46827202ae0e0ca Mon Sep 17 00:00:00 2001 From: Dream Hunter Date: Wed, 19 Aug 2026 13:31:55 +0800 Subject: [PATCH] fix: clarify account and address terminology (#1113) * fix: clarify account and address terminology * fix: narrow account and address terminology changes * fix: simplify mailbox settings label * fix: align mailbox translations and send docs --- CHANGELOG.md | 4 ++ CHANGELOG_EN.md | 4 ++ frontend/src/i18n/locales/source/de.ts | 19 ++++----- frontend/src/i18n/locales/source/es.ts | 19 ++++----- frontend/src/i18n/locales/source/ja.ts | 19 ++++----- frontend/src/i18n/locales/source/ptBR.ts | 19 ++++----- frontend/src/i18n/message-registry.ts | 40 ++++++++++--------- frontend/src/views/index/SendMail.vue | 4 +- .../docs/en/guide/config-send-mail.md | 22 +++++++++- .../docs/zh/guide/config-send-mail.md | 22 +++++++++- 10 files changed, 112 insertions(+), 60 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5bdb1f6..d64cbac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,8 +14,12 @@ ### Bug Fixes +- fix: |Frontend| 将邮箱主页的账户设置、删除账户等表述更正为邮箱地址操作,并明确发信权限与额度按当前邮箱地址独立管理 + ### Improvements +- docs: |发送邮件| 补充用户账号、邮箱地址和发信权限的概念区别及按当前地址申请权限的操作说明 + - fix: |Worker| 地址活跃时间保活增加 1 天写入窗口,用户设置和邮箱访问不再重复更新近期活跃地址,降低 D1 写入量(issue #1103) - feat: |用户系统| 用户绑定地址列表改用服务端分页,并仅在第一页查询总数;用户邮件列表改用 JOIN、删除改用 `EXISTS` 在数据库侧校验地址归属,避免为大用户加载全部绑定地址(issue #1103) diff --git a/CHANGELOG_EN.md b/CHANGELOG_EN.md index 36c82fe..7a82aef 100644 --- a/CHANGELOG_EN.md +++ b/CHANGELOG_EN.md @@ -14,8 +14,12 @@ ### Bug Fixes +- fix: |Frontend| Relabel mailbox settings and deletion actions as email-address operations, and clarify that send permission and balance are managed independently for the current email address + ### Improvements +- docs: |Send Mail| Document the differences between user accounts, email addresses, and send permission, including how to request permission for the currently selected address + - fix: |Worker| Throttle address-activity touches to one write per day so user settings and mailbox access do not repeatedly update recently active addresses, reducing D1 writes (issue #1103) - feat: |User| Add server-side pagination for bound addresses, with totals queried only on the first page; validate user-mail list ownership with a JOIN and delete ownership with `EXISTS` instead of loading every bound address for large users (issue #1103) diff --git a/frontend/src/i18n/locales/source/de.ts b/frontend/src/i18n/locales/source/de.ts index 4243db3..e0d7398 100644 --- a/frontend/src/i18n/locales/source/de.ts +++ b/frontend/src/i18n/locales/source/de.ts @@ -6,9 +6,9 @@ export const deMessages = { "views.Admin.about": "Über", "views.Header.accessHeader": "Zugangspasswort", "views.Admin.account": "Konto", - "views.Index.accountSettings": "Kontoeinstellungen", + "views.Index.accountSettings": "E-Mail-Einstellungen", "views.Admin.account_settings": "Kontoeinstellungen", - "views.index.SimpleIndex.accountSettings": "Kontoeinstellungen", + "views.index.SimpleIndex.accountSettings": "E-Mail-Einstellungen", "views.index.Attachment.action": "Aktion", "views.admin.SenderAccess.action": "Aktion", "views.user.UserSettings.actions": "Aktionen", @@ -60,8 +60,8 @@ export const deMessages = { "views.index.Attachment.deleteConfirm": "Möchtest du wirklich diesen Anhang löschen?", "views.admin.Account.deleteTip": "Möchtest du wirklich diese E-Mail löschen?", "views.admin.SenderAccess.deleteTip": "Möchtest du dies wirklich löschen?", - "views.index.AccountSettings.deleteAccountConfirm": "Möchtest du wirklich dein Konto und alle zugehörigen E-Mails löschen?", - "views.index.AccountSettings.logoutConfirm": "Möchtest du dich wirklich abmelden?", + "views.index.AccountSettings.deleteAccountConfirm": "Möchtest du diese E-Mail-Adresse und alle zugehörigen E-Mails wirklich löschen? Dein Benutzerkonto wird dabei nicht gelöscht.", + "views.index.AccountSettings.logoutConfirm": "Möchtest du dich wirklich von der aktuellen E-Mail-Adresse abmelden?", "components.MailBox.deleteMailTip": "Möchtest du die E-Mail wirklich löschen?", "components.MailContentRenderer.deleteMailTip": "Möchtest du die E-Mail wirklich löschen?", "components.SendBox.deleteMailTip": "Möchtest du die E-Mail wirklich löschen?", @@ -98,7 +98,7 @@ export const deMessages = { "views.user.AddressManagement.changeMailAddress": "Adresse wechseln", "views.index.TelegramAddress.changeMailAddress": "Mailadresse ändern", "views.index.LocalAddress.changeMailAddress": "Mailadresse ändern", - "views.index.AccountSettings.changePassword": "Passwort ändern", + "views.index.AccountSettings.changePassword": "Adresspasswort ändern", "views.admin.UserManagement.changeRole": "Ändern Rolle", "components.SendBox.showCode": "Ansicht des Originalcodes umschalten", "views.admin.Telegram.status": "Status prüfen", @@ -170,7 +170,7 @@ export const deMessages = { "views.admin.UserManagement.delete": "Löschen", "views.admin.AccountSettings.delete_rule": "Löschen", "views.admin.Maintenance.deleteCustomSql": "Löschen", - "views.index.AccountSettings.deleteAccount": "Konto löschen", + "views.index.AccountSettings.deleteAccount": "E-Mail-Adresse löschen", "views.admin.Account.deleteAccount": "Konto löschen", "views.user.UserSettings.deletePasskey": "Passkey löschen", "views.admin.AccountSettings.delete_success": "Erfolgreich gelöscht", @@ -282,7 +282,7 @@ export const deMessages = { "views.user.UserSettings.logout": "Abmelden", "views.user.BindAddress.logout": "Abmelden", "views.Admin.logout": "Abmelden", - "views.index.AccountSettings.logout": "Abmelden", + "views.index.AccountSettings.logout": "Von aktueller E-Mail-Adresse abmelden", "views.Admin.logoutSuccess": "Erfolgreich abgemeldet", "views.admin.UserOauth2Settings.mailAllowList": "E-Mail-Adressfreigabeliste", "views.admin.UserSettings.mailAllowList": "E-Mail-Adressfreigabeliste", @@ -334,7 +334,8 @@ export const deMessages = { "views.admin.AccountSettings.noLimitSendAddressList": "Adressliste ohne Guthabenlimit", "views.index.SimpleIndex.noMails": "Keine E-Mails gefunden", "views.admin.RoleAddressConfig.noRolesAvailable": "In der Systemkonfiguration sind keine Rollen verfügbar", - "views.index.SendMail.requestAccessTip": "Noch kein Sendeguthaben vorhanden. Wenn der Administrator ein Standardguthaben aktiviert hat, wird es automatisch zugewiesen; andernfalls Zugriff anfordern oder den Administrator kontaktieren.", + "views.index.SendMail.requestAccessTip": "Sendeberechtigung und Guthaben werden für jede E-Mail-Adresse separat verwaltet. Die aktuelle Adresse {address} hat kein verfügbares Guthaben. Fordere die Berechtigung für diese Adresse an oder kontaktiere den Administrator.", + "views.index.SendMail.requestSuccess": "Sendeberechtigung für die aktuelle Adresse angefordert", "components.SendBox.emptySent": "Keine gesendeten E-Mails", "views.admin.RoleAddressConfig.notConfigured": "Nicht konfiguriert (globale Einstellungen verwenden)", "views.Admin.userOauth2Settings": "OAuth2-Einstellungen", @@ -465,7 +466,7 @@ export const deMessages = { "views.admin.UserAddressManagement.send_count": "Sendeanzahl", "views.Index.sendmail": "E-Mail senden", "views.Admin.sendMail": "E-Mail senden", - "views.index.SendMail.send_balance": "Verbleibendes Sendeguthaben", + "views.index.SendMail.send_balance": "Sendeguthaben der aktuellen Adresse", "views.admin.Statistics.sendMailCount": "Anzahl gesendeter E-Mails", "views.admin.AccountSettings.send_mail_limit": "Sende-Limit", "views.user.UserLogin.sendVerificationCode": "Bestätigungscode senden", diff --git a/frontend/src/i18n/locales/source/es.ts b/frontend/src/i18n/locales/source/es.ts index 22b452a..2fa3d5e 100644 --- a/frontend/src/i18n/locales/source/es.ts +++ b/frontend/src/i18n/locales/source/es.ts @@ -6,9 +6,9 @@ export const esMessages = { "views.Admin.about": "Acerca de", "views.Header.accessHeader": "Contraseña de acceso", "views.Admin.account": "Cuenta", - "views.Index.accountSettings": "Configuración de la cuenta", + "views.Index.accountSettings": "Configuración del correo", "views.Admin.account_settings": "Configuración de la cuenta", - "views.index.SimpleIndex.accountSettings": "Configuración de la cuenta", + "views.index.SimpleIndex.accountSettings": "Configuración del correo", "views.index.Attachment.action": "Acción", "views.admin.SenderAccess.action": "Acción", "views.user.UserSettings.actions": "Acciones", @@ -60,8 +60,8 @@ export const esMessages = { "views.index.Attachment.deleteConfirm": "¿Seguro que quieres eliminar este adjunto?", "views.admin.Account.deleteTip": "¿Seguro que quieres eliminar este correo?", "views.admin.SenderAccess.deleteTip": "¿Seguro que quieres eliminar esto?", - "views.index.AccountSettings.deleteAccountConfirm": "¿Seguro que quieres eliminar tu cuenta y todos sus correos?", - "views.index.AccountSettings.logoutConfirm": "¿Seguro que quieres cerrar sesión?", + "views.index.AccountSettings.deleteAccountConfirm": "¿Seguro que quieres eliminar esta dirección de correo y todos sus correos? Esto no elimina tu cuenta de usuario.", + "views.index.AccountSettings.logoutConfirm": "¿Seguro que quieres cerrar la sesión de la dirección de correo actual?", "components.MailBox.deleteMailTip": "¿Seguro que quieres eliminar el correo?", "components.MailContentRenderer.deleteMailTip": "¿Seguro que quieres eliminar el correo?", "components.SendBox.deleteMailTip": "¿Seguro que quieres eliminar el correo?", @@ -98,7 +98,7 @@ export const esMessages = { "views.user.AddressManagement.changeMailAddress": "Cambiar dirección", "views.index.TelegramAddress.changeMailAddress": "Cambiar dirección de correo", "views.index.LocalAddress.changeMailAddress": "Cambiar dirección de correo", - "views.index.AccountSettings.changePassword": "Cambiar contraseña", + "views.index.AccountSettings.changePassword": "Cambiar contraseña de la dirección", "views.admin.UserManagement.changeRole": "Cambiar Rol", "components.SendBox.showCode": "Cambiar vista del código original", "views.admin.Telegram.status": "Ver estado", @@ -170,7 +170,7 @@ export const esMessages = { "views.admin.UserManagement.delete": "Eliminar", "views.admin.AccountSettings.delete_rule": "Eliminar", "views.admin.Maintenance.deleteCustomSql": "Eliminar", - "views.index.AccountSettings.deleteAccount": "Eliminar cuenta", + "views.index.AccountSettings.deleteAccount": "Eliminar dirección de correo", "views.admin.Account.deleteAccount": "Eliminar cuenta", "views.user.UserSettings.deletePasskey": "Eliminar passkey", "views.admin.AccountSettings.delete_success": "Eliminado correctamente", @@ -282,7 +282,7 @@ export const esMessages = { "views.user.UserSettings.logout": "Cerrar sesión", "views.user.BindAddress.logout": "Cerrar sesión", "views.Admin.logout": "Cerrar sesión", - "views.index.AccountSettings.logout": "Cerrar sesión", + "views.index.AccountSettings.logout": "Cerrar sesión de la dirección de correo actual", "views.Admin.logoutSuccess": "Sesión cerrada correctamente", "views.admin.UserOauth2Settings.mailAllowList": "Lista blanca de direcciones de correo", "views.admin.UserSettings.mailAllowList": "Lista blanca de direcciones de correo", @@ -334,7 +334,8 @@ export const esMessages = { "views.admin.AccountSettings.noLimitSendAddressList": "Lista de direcciones sin límite de saldo", "views.index.SimpleIndex.noMails": "No se encontraron correos", "views.admin.RoleAddressConfig.noRolesAvailable": "No hay roles disponibles en la configuración del sistema", - "views.index.SendMail.requestAccessTip": "Todavía no hay saldo de envío. Si el administrador activó un saldo por defecto, se asignará automáticamente; si no, solicita acceso o contacta con el administrador.", + "views.index.SendMail.requestAccessTip": "El permiso y el saldo de envío se gestionan por separado para cada dirección. La dirección actual, {address}, no tiene saldo disponible. Solicita permiso para esta dirección o contacta con el administrador.", + "views.index.SendMail.requestSuccess": "Permiso de envío solicitado para la dirección actual", "components.SendBox.emptySent": "No hay correos enviados", "views.admin.RoleAddressConfig.notConfigured": "No configurado (usar configuración global)", "views.Admin.userOauth2Settings": "Configuración de OAuth2", @@ -465,7 +466,7 @@ export const esMessages = { "views.admin.UserAddressManagement.send_count": "Cantidad enviada", "views.Index.sendmail": "Enviar correo", "views.Admin.sendMail": "Enviar correo", - "views.index.SendMail.send_balance": "Saldo restante de envío", + "views.index.SendMail.send_balance": "Saldo de envío de la dirección actual", "views.admin.Statistics.sendMailCount": "Cantidad de correos enviados", "views.admin.AccountSettings.send_mail_limit": "Límite de envío", "views.user.UserLogin.sendVerificationCode": "Enviar código de verificación", diff --git a/frontend/src/i18n/locales/source/ja.ts b/frontend/src/i18n/locales/source/ja.ts index ce2efed..978ed18 100644 --- a/frontend/src/i18n/locales/source/ja.ts +++ b/frontend/src/i18n/locales/source/ja.ts @@ -6,9 +6,9 @@ export const jaMessages = { "views.Admin.about": "概要", "views.Header.accessHeader": "アクセス用パスワード", "views.Admin.account": "アカウント", - "views.Index.accountSettings": "アカウント設定", + "views.Index.accountSettings": "メール設定", "views.Admin.account_settings": "アカウント設定", - "views.index.SimpleIndex.accountSettings": "アカウント設定", + "views.index.SimpleIndex.accountSettings": "メール設定", "views.index.Attachment.action": "操作", "views.admin.SenderAccess.action": "操作", "views.user.UserSettings.actions": "操作", @@ -60,8 +60,8 @@ export const jaMessages = { "views.index.Attachment.deleteConfirm": "この添付ファイルを削除してもよろしいですか?", "views.admin.Account.deleteTip": "このメールを削除してもよろしいですか?", "views.admin.SenderAccess.deleteTip": "これを削除してもよろしいですか?", - "views.index.AccountSettings.deleteAccountConfirm": "このアカウントと関連メールをすべて削除してもよろしいですか?", - "views.index.AccountSettings.logoutConfirm": "ログアウトしてもよろしいですか?", + "views.index.AccountSettings.deleteAccountConfirm": "このメールアドレスと関連するすべてのメールを削除しますか?ユーザーアカウントは削除されません。", + "views.index.AccountSettings.logoutConfirm": "現在のメールアドレスからログアウトしますか?", "components.MailBox.deleteMailTip": "メールを削除してもよろしいですか?", "components.MailContentRenderer.deleteMailTip": "メールを削除してもよろしいですか?", "components.SendBox.deleteMailTip": "メールを削除してもよろしいですか?", @@ -98,7 +98,7 @@ export const jaMessages = { "views.user.AddressManagement.changeMailAddress": "アドレスを変更", "views.index.TelegramAddress.changeMailAddress": "メールアドレスを変更", "views.index.LocalAddress.changeMailAddress": "メールアドレスを変更", - "views.index.AccountSettings.changePassword": "パスワードを変更", + "views.index.AccountSettings.changePassword": "アドレスパスワードを変更", "views.admin.UserManagement.changeRole": "ロールを変更", "components.SendBox.showCode": "元のコード表示を切り替え", "views.admin.Telegram.status": "ステータスを確認", @@ -170,7 +170,7 @@ export const jaMessages = { "views.admin.UserManagement.delete": "削除", "views.admin.AccountSettings.delete_rule": "削除", "views.admin.Maintenance.deleteCustomSql": "削除", - "views.index.AccountSettings.deleteAccount": "アカウントを削除", + "views.index.AccountSettings.deleteAccount": "メールアドレスを削除", "views.admin.Account.deleteAccount": "アカウントを削除", "views.user.UserSettings.deletePasskey": "Passkeyを削除", "views.admin.AccountSettings.delete_success": "削除しました", @@ -282,7 +282,7 @@ export const jaMessages = { "views.user.UserSettings.logout": "ログアウト", "views.user.BindAddress.logout": "ログアウト", "views.Admin.logout": "ログアウト", - "views.index.AccountSettings.logout": "ログアウト", + "views.index.AccountSettings.logout": "現在のメールアドレスからログアウト", "views.Admin.logoutSuccess": "ログアウトしました", "views.admin.UserOauth2Settings.mailAllowList": "メールアドレス許可リスト", "views.admin.UserSettings.mailAllowList": "メールアドレス許可リスト", @@ -334,7 +334,8 @@ export const jaMessages = { "views.admin.AccountSettings.noLimitSendAddressList": "残高無制限の送信アドレス一覧", "views.index.SimpleIndex.noMails": "メールが見つかりません", "views.admin.RoleAddressConfig.noRolesAvailable": "システム設定に利用可能なロールがありません", - "views.index.SendMail.requestAccessTip": "まだ送信残高がありません。管理者がデフォルト残高を有効にしていれば自動付与されます。そうでない場合は権限申請または管理者へ連絡してください。", + "views.index.SendMail.requestAccessTip": "送信権限と残高はメールアドレスごとに管理されます。現在のアドレス {address} には利用可能な残高がありません。このアドレスの権限を申請するか、管理者に連絡してください。", + "views.index.SendMail.requestSuccess": "現在のアドレスの送信権限を申請しました", "components.SendBox.emptySent": "送信済みメールはありません", "views.admin.RoleAddressConfig.notConfigured": "未設定 (全体設定を使用)", "views.Admin.userOauth2Settings": "OAuth2設定", @@ -465,7 +466,7 @@ export const jaMessages = { "views.admin.UserAddressManagement.send_count": "送信数", "views.Index.sendmail": "メール送信", "views.Admin.sendMail": "メール送信", - "views.index.SendMail.send_balance": "残り送信枠", + "views.index.SendMail.send_balance": "現在のアドレスの送信残高", "views.admin.Statistics.sendMailCount": "送信メール数", "views.admin.AccountSettings.send_mail_limit": "送信上限", "views.user.UserLogin.sendVerificationCode": "認証コードを送信", diff --git a/frontend/src/i18n/locales/source/ptBR.ts b/frontend/src/i18n/locales/source/ptBR.ts index 8dad4c5..6268727 100644 --- a/frontend/src/i18n/locales/source/ptBR.ts +++ b/frontend/src/i18n/locales/source/ptBR.ts @@ -6,9 +6,9 @@ export const ptBRMessages = { "views.Admin.about": "Sobre", "views.Header.accessHeader": "Senha de acesso", "views.Admin.account": "Conta", - "views.Index.accountSettings": "Configurações da conta", + "views.Index.accountSettings": "Configurações de e-mail", "views.Admin.account_settings": "Configurações da conta", - "views.index.SimpleIndex.accountSettings": "Configurações da conta", + "views.index.SimpleIndex.accountSettings": "Configurações de e-mail", "views.index.Attachment.action": "Ação", "views.admin.SenderAccess.action": "Ação", "views.user.UserSettings.actions": "Ações", @@ -60,8 +60,8 @@ export const ptBRMessages = { "views.index.Attachment.deleteConfirm": "Tem certeza de que deseja excluir este anexo?", "views.admin.Account.deleteTip": "Tem certeza de que deseja excluir este e-mail?", "views.admin.SenderAccess.deleteTip": "Tem certeza de que deseja excluir isto?", - "views.index.AccountSettings.deleteAccountConfirm": "Tem certeza de que deseja excluir sua conta e todos os e-mails dela?", - "views.index.AccountSettings.logoutConfirm": "Tem certeza de que deseja sair?", + "views.index.AccountSettings.deleteAccountConfirm": "Tem certeza de que deseja excluir este endereço de e-mail e todas as mensagens dele? Isso não exclui sua conta de usuário.", + "views.index.AccountSettings.logoutConfirm": "Tem certeza de que deseja sair do endereço de e-mail atual?", "components.MailBox.deleteMailTip": "Tem certeza de que deseja excluir o e-mail?", "components.MailContentRenderer.deleteMailTip": "Tem certeza de que deseja excluir o e-mail?", "components.SendBox.deleteMailTip": "Tem certeza de que deseja excluir o e-mail?", @@ -98,7 +98,7 @@ export const ptBRMessages = { "views.user.AddressManagement.changeMailAddress": "Alterar endereço", "views.index.TelegramAddress.changeMailAddress": "Alterar endereço de e-mail", "views.index.LocalAddress.changeMailAddress": "Alterar endereço de e-mail", - "views.index.AccountSettings.changePassword": "Alterar senha", + "views.index.AccountSettings.changePassword": "Alterar senha do endereço", "views.admin.UserManagement.changeRole": "Alterar Função", "components.SendBox.showCode": "Alternar visualização do código original", "views.admin.Telegram.status": "Ver status", @@ -170,7 +170,7 @@ export const ptBRMessages = { "views.admin.UserManagement.delete": "Excluir", "views.admin.AccountSettings.delete_rule": "Excluir", "views.admin.Maintenance.deleteCustomSql": "Excluir", - "views.index.AccountSettings.deleteAccount": "Excluir conta", + "views.index.AccountSettings.deleteAccount": "Excluir endereço de e-mail", "views.admin.Account.deleteAccount": "Excluir conta", "views.user.UserSettings.deletePasskey": "Excluir passkey", "views.admin.AccountSettings.delete_success": "Excluído com sucesso", @@ -282,7 +282,7 @@ export const ptBRMessages = { "views.user.UserSettings.logout": "Sair", "views.user.BindAddress.logout": "Sair", "views.Admin.logout": "Sair", - "views.index.AccountSettings.logout": "Sair", + "views.index.AccountSettings.logout": "Sair do endereço de e-mail atual", "views.Admin.logoutSuccess": "Logout realizado com sucesso", "views.admin.UserOauth2Settings.mailAllowList": "Lista branca de endereços de e-mail", "views.admin.UserSettings.mailAllowList": "Lista branca de endereços de e-mail", @@ -334,7 +334,8 @@ export const ptBRMessages = { "views.admin.AccountSettings.noLimitSendAddressList": "Lista de endereços sem limite de saldo", "views.index.SimpleIndex.noMails": "Nenhum e-mail encontrado", "views.admin.RoleAddressConfig.noRolesAvailable": "Nenhuma função disponível na configuração do sistema", - "views.index.SendMail.requestAccessTip": "Ainda não há saldo de envio. Se o administrador ativou um saldo padrão, ele será atribuído automaticamente; caso contrário, solicite acesso ou fale com o administrador.", + "views.index.SendMail.requestAccessTip": "A permissão e o saldo de envio são gerenciados separadamente para cada endereço. O endereço atual, {address}, não tem saldo disponível. Solicite permissão para este endereço ou fale com o administrador.", + "views.index.SendMail.requestSuccess": "Permissão de envio solicitada para o endereço atual", "components.SendBox.emptySent": "Nenhum e-mail enviado", "views.admin.RoleAddressConfig.notConfigured": "Não configurado (usar configurações globais)", "views.Admin.userOauth2Settings": "Configurações de OAuth2", @@ -465,7 +466,7 @@ export const ptBRMessages = { "views.admin.UserAddressManagement.send_count": "Quantidade enviada", "views.Index.sendmail": "Enviar e-mail", "views.Admin.sendMail": "Enviar e-mail", - "views.index.SendMail.send_balance": "Saldo restante de envio", + "views.index.SendMail.send_balance": "Saldo de envio do endereço atual", "views.admin.Statistics.sendMailCount": "Quantidade de e-mails enviados", "views.admin.AccountSettings.send_mail_limit": "Limite de envio", "views.user.UserLogin.sendVerificationCode": "Enviar código de verificação", diff --git a/frontend/src/i18n/message-registry.ts b/frontend/src/i18n/message-registry.ts index 018beed..f3d76b2 100644 --- a/frontend/src/i18n/message-registry.ts +++ b/frontend/src/i18n/message-registry.ts @@ -419,8 +419,8 @@ export const MESSAGE_REGISTRY = { "zh": "关于" }, "accountSettings": { - "en": "Account Settings", - "zh": "账户" + "en": "Email Settings", + "zh": "邮箱设置" }, "appearance": { "en": "Appearance", @@ -891,8 +891,8 @@ export const MESSAGE_REGISTRY = { }, "views.index.AccountSettings": { "changePassword": { - "en": "Change Password", - "zh": "修改密码" + "en": "Change Address Password", + "zh": "修改地址密码" }, "clearInbox": { "en": "Clear Inbox", @@ -915,20 +915,20 @@ export const MESSAGE_REGISTRY = { "zh": "确认密码" }, "deleteAccount": { - "en": "Delete Account", - "zh": "删除账户" + "en": "Delete Email Address", + "zh": "删除邮箱地址" }, "deleteAccountConfirm": { - "en": "Are you sure to delete your account and all emails for this account?", - "zh": "确定要删除你的账户和其中的所有邮件吗?" + "en": "Are you sure you want to delete this email address and all of its emails? This does not delete your user account.", + "zh": "确定要删除当前邮箱地址及其中的所有邮件吗?此操作不会删除你的用户账号。" }, "logout": { - "en": "Logout", - "zh": "退出登录" + "en": "Log Out of Address", + "zh": "退出地址登录" }, "logoutConfirm": { - "en": "Are you sure to logout?", - "zh": "确定要退出登录吗?" + "en": "Are you sure you want to log out of the current email address?", + "zh": "确定要退出当前邮箱地址的登录吗?" }, "newPassword": { "en": "New Password", @@ -1059,8 +1059,12 @@ export const MESSAGE_REGISTRY = { "zh": "申请权限" }, "requestAccessTip": { - "en": "No send balance yet. If your admin enabled a default balance it should be assigned automatically; otherwise request access or contact the admin.", - "zh": "当前还没有可用的发信额度。如果管理员启用了默认额度,会自动发放;否则请申请权限或联系管理员处理。" + "en": "Send permission and balance are managed separately for each email address. The current address, {address}, has no available balance. Request permission for this address or contact the admin.", + "zh": "发信权限和额度按邮箱地址独立管理。当前地址 {address} 暂无可用额度,请为此地址申请发信权限或联系管理员。" + }, + "requestSuccess": { + "en": "Send permission requested for the current address", + "zh": "已为当前地址提交发信权限申请" }, "rich text": { "en": "Rich Text", @@ -1071,8 +1075,8 @@ export const MESSAGE_REGISTRY = { "zh": "发送" }, "send_balance": { - "en": "Send Mail Balance Left", - "zh": "剩余发送邮件额度" + "en": "Current Address Send Balance", + "zh": "当前地址剩余发信额度" }, "subject": { "en": "Subject", @@ -1105,8 +1109,8 @@ export const MESSAGE_REGISTRY = { }, "views.index.SimpleIndex": { "accountSettings": { - "en": "Account Settings", - "zh": "账户设置" + "en": "Email Settings", + "zh": "邮箱设置" }, "addressCopied": { "en": "Address copied successfully", diff --git a/frontend/src/views/index/SendMail.vue b/frontend/src/views/index/SendMail.vue index c9635dc..2bd7913 100644 --- a/frontend/src/views/index/SendMail.vue +++ b/frontend/src/views/index/SendMail.vue @@ -116,7 +116,7 @@ const requestAccess = async () => { body: JSON.stringify({}) } ) - message.success(t("success")) + message.success(t("requestSuccess")) await api.getSettings(); } catch (error) { message.error(error.message || "error"); @@ -161,7 +161,7 @@ onMounted(async () => {
- {{ t('requestAccessTip') }} + {{ t('requestAccessTip', { address: settings.address }) }} {{ t('requestAccess') }} diff --git a/vitepress-docs/docs/en/guide/config-send-mail.md b/vitepress-docs/docs/en/guide/config-send-mail.md index d173116..2c0eccb 100644 --- a/vitepress-docs/docs/en/guide/config-send-mail.md +++ b/vitepress-docs/docs/en/guide/config-send-mail.md @@ -150,12 +150,30 @@ cd worker wrangler secret put SMTP_CONFIG ``` +## User Accounts, Email Addresses, and Send Permission + +These concepts are related, but they identify different objects: + +| Concept | Description | +|---------|-------------| +| User account | Signs in to the user center and can bind and manage multiple email addresses. The user account's login email is not automatically a sending or receiving address | +| Email address | The identity that actually receives and sends mail, such as `name@example.com`. The address currently selected on the frontend home page is authenticated by its Address JWT | +| Send permission and balance | Permission and balance records in `address_sender` are managed independently **per email address**; user roles configured by `NO_LIMIT_SEND_ROLE` can bypass address balance checks | + +Multiple email addresses bound to the same user account therefore do not share send permission or balance. To request permission for an address: + +1. Switch to the email address that needs to send mail +2. Open the **Send Mail** page +3. Click **Request Access** + +The request affects only the address selected at that time. After switching to another address, check that address's own balance and request permission separately if needed. An email address can also hold send permission without being bound to a user account. + ## Send Balance Mechanism -Users need a send balance to send emails. The balance mechanism works as follows: +An email address needs its own send balance to send emails. The balance mechanism works as follows: 1. **Auto-initialize Default Quota**: When `DEFAULT_SEND_BALANCE > 0`, the system automatically initializes the default quota when the user opens the send page or calls the send-mail API for the first time -2. **Manual Request**: If `DEFAULT_SEND_BALANCE = 0`, users can still click "Request Send Permission" in the frontend to create a pending send-access record for admins to review +2. **Manual Request**: If `DEFAULT_SEND_BALANCE = 0`, switch to the target email address in the frontend and click **Request Access** to create a pending send-access record for the current address 3. **Unlimited Sending**: The following methods can bypass balance checks: - Add the address to the "No Limit Send Address List" in the admin console - Configure the `NO_LIMIT_SEND_ROLE` environment variable to specify roles that can send without limits diff --git a/vitepress-docs/docs/zh/guide/config-send-mail.md b/vitepress-docs/docs/zh/guide/config-send-mail.md index 7fe40ac..ce3ec4b 100644 --- a/vitepress-docs/docs/zh/guide/config-send-mail.md +++ b/vitepress-docs/docs/zh/guide/config-send-mail.md @@ -150,12 +150,30 @@ cd worker wrangler secret put SMTP_CONFIG ``` +## 用户账号、邮箱地址与发信权限 + +这三个概念相互关联,但不是同一个对象: + +| 概念 | 说明 | +|------|------| +| 用户账号 | 用于登录用户中心,可绑定和管理多个邮箱地址;用户账号的登录邮箱本身不等于用于收发信的邮箱地址 | +| 邮箱地址 | 实际收信和发信的身份,例如 `name@example.com`;前端首页当前选中的地址由该地址的凭证(Address JWT)认证 | +| 发信权限与额度 | `address_sender` 中的权限和额度以**邮箱地址**为单位独立管理;`NO_LIMIT_SEND_ROLE` 配置的用户角色可以绕过地址额度检查 | + +因此,同一用户账号绑定的多个邮箱地址不会共享发信权限或余额。为某个地址申请发信权限时: + +1. 先在前端切换到需要发信的邮箱地址 +2. 打开「发送邮件」页 +3. 点击「申请权限」 + +申请只作用于当时选中的邮箱地址。切换到另一个地址后,需要查看该地址自己的额度,并在需要时单独申请。邮箱地址不必绑定用户账号也可以独立持有发信权限。 + ## 发信余额机制 -用户发送邮件需要有发信余额。余额机制如下: +邮箱地址发送邮件需要有该地址的发信余额。余额机制如下: 1. **自动初始化默认额度**:当 `DEFAULT_SEND_BALANCE > 0` 时,用户打开前端发信页或第一次调用发信接口时,系统会自动为该地址初始化默认额度 -2. **手动申请**:如果 `DEFAULT_SEND_BALANCE = 0`,用户仍可以在前端界面点击「申请发信权限」按钮,创建待管理员处理的发信权限记录 +2. **手动申请**:如果 `DEFAULT_SEND_BALANCE = 0`,使用者可以在前端切换到目标邮箱地址并点击「申请权限」,为当前地址创建待管理员处理的发信权限记录 3. **无限制发送**:以下方式可以跳过余额检查: - 在 admin 后台将地址加入「无限制发送地址列表」 - 配置 `NO_LIMIT_SEND_ROLE` 环境变量,指定可以无限发送的用户角色