From bf13756e6d04743bf1122021cb9fe0e10792e9de Mon Sep 17 00:00:00 2001 From: cnlimiter Date: Sun, 15 Mar 2026 02:17:38 +0800 Subject: [PATCH] =?UTF-8?q?feat(core):=20=E5=A2=9E=E5=BC=BA=E6=B3=A8?= =?UTF-8?q?=E5=86=8C=E6=B5=81=E7=A8=8B=E7=9A=84=E9=82=AE=E7=AE=B1=E9=87=8D?= =?UTF-8?q?=E5=A4=8D=E6=A3=80=E6=B5=8B=E4=B8=8E=E9=94=99=E8=AF=AF=E5=A4=84?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在注册引擎中增加邮箱重复检测机制,当检测到邮箱已在OpenAI注册时自动标记为失败状态 - 优化密码注册失败的错误信息解析,提供更详细的错误反馈 - 改进Outlook账户选择逻辑,自动跳过已注册的邮箱账户 - 在CRUD操作中为账户添加状态字段,支持更细粒度的账户状态管理 --- src/core/register.py | 39 +++++++++++++++++++++++++++++++++- src/database/crud.py | 4 +++- src/web/routes/registration.py | 35 +++++++++++++++++++++++------- 3 files changed, 68 insertions(+), 10 deletions(-) diff --git a/src/core/register.py b/src/core/register.py index 4fa3215..6fdafaa 100644 --- a/src/core/register.py +++ b/src/core/register.py @@ -297,7 +297,23 @@ class RegistrationEngine: self._log(f"提交密码状态: {response.status_code}") if response.status_code != 200: - self._log(f"密码注册失败: {response.text[:200]}", "warning") + error_text = response.text[:500] + self._log(f"密码注册失败: {error_text}", "warning") + + # 解析错误信息,判断是否是邮箱已注册 + try: + error_json = response.json() + error_msg = error_json.get("error", {}).get("message", "") + error_code = error_json.get("error", {}).get("code", "") + + # 检测邮箱已注册的情况 + if "already" in error_msg.lower() or "exists" in error_msg.lower() or error_code == "user_exists": + self._log(f"邮箱 {self.email} 可能已在 OpenAI 注册过", "error") + # 标记此邮箱为已注册状态 + self._mark_email_as_registered() + except Exception: + pass + return False, None return True, password @@ -306,6 +322,27 @@ class RegistrationEngine: self._log(f"密码注册失败: {e}", "error") return False, None + def _mark_email_as_registered(self): + """标记邮箱为已注册状态(用于防止重复尝试)""" + try: + with get_db() as db: + # 检查是否已存在该邮箱的记录 + existing = crud.get_account_by_email(db, self.email) + if not existing: + # 创建一个失败记录,标记该邮箱已注册过 + crud.create_account( + db, + email=self.email, + password="", # 空密码表示未成功注册 + email_service=self.email_service.service_type.value, + email_service_id=self.email_info.get("service_id") if self.email_info else None, + status="failed", + extra_data={"register_failed_reason": "email_already_registered_on_openai"} + ) + self._log(f"已在数据库中标记邮箱 {self.email} 为已注册状态") + except Exception as e: + logger.warning(f"标记邮箱状态失败: {e}") + def _send_verification_code(self) -> bool: """发送验证码""" try: diff --git a/src/database/crud.py b/src/database/crud.py index 1af726b..79fef2a 100644 --- a/src/database/crud.py +++ b/src/database/crud.py @@ -29,7 +29,8 @@ def create_account( id_token: Optional[str] = None, proxy_used: Optional[str] = None, expires_at: Optional['datetime'] = None, - extra_data: Optional[Dict[str, Any]] = None + extra_data: Optional[Dict[str, Any]] = None, + status: Optional[str] = None ) -> Account: """创建新账户""" db_account = Account( @@ -47,6 +48,7 @@ def create_account( proxy_used=proxy_used, expires_at=expires_at, extra_data=extra_data or {}, + status=status or 'active', registered_at=datetime.utcnow() ) db.add(db_account) diff --git a/src/web/routes/registration.py b/src/web/routes/registration.py index a8f6db3..ff6ced7 100644 --- a/src/web/routes/registration.py +++ b/src/web/routes/registration.py @@ -248,18 +248,37 @@ async def run_registration_task(task_uuid: str, email_service_type: str, proxy: raise ValueError("没有可用的自定义域名邮箱服务,请先在设置中配置") elif service_type == EmailServiceType.OUTLOOK: # 检查数据库中是否有可用的 Outlook 账户 - from ...database.models import EmailService as EmailServiceModel - db_service = db.query(EmailServiceModel).filter( + from ...database.models import EmailService as EmailServiceModel, Account + # 获取所有启用的 Outlook 服务 + outlook_services = db.query(EmailServiceModel).filter( EmailServiceModel.service_type == "outlook", EmailServiceModel.enabled == True - ).order_by(EmailServiceModel.priority.asc()).first() + ).order_by(EmailServiceModel.priority.asc()).all() - if db_service and db_service.config: - config = db_service.config.copy() - crud.update_registration_task(db, task_uuid, email_service_id=db_service.id) - logger.info(f"使用数据库 Outlook 账户: {db_service.name}") - else: + if not outlook_services: raise ValueError("没有可用的 Outlook 账户,请先在设置中导入账户") + + # 找到一个未注册的 Outlook 账户 + selected_service = None + for svc in outlook_services: + email = svc.config.get("email") if svc.config else None + if not email: + continue + # 检查是否已在 accounts 表中注册 + existing = db.query(Account).filter(Account.email == email).first() + if not existing: + selected_service = svc + logger.info(f"选择未注册的 Outlook 账户: {email}") + break + else: + logger.info(f"跳过已注册的 Outlook 账户: {email}") + + if selected_service and selected_service.config: + config = selected_service.config.copy() + crud.update_registration_task(db, task_uuid, email_service_id=selected_service.id) + logger.info(f"使用数据库 Outlook 账户: {selected_service.name}") + else: + raise ValueError("所有 Outlook 账户都已注册过 OpenAI 账号,请添加新的 Outlook 账户") else: config = email_service_config or {}