From 06a6392cfdefa3400317e5b49971c4b79a58cace Mon Sep 17 00:00:00 2001 From: zhinianboke <115088296+zhinianboke@users.noreply.github.com> Date: Sat, 2 Aug 2025 12:58:04 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dbug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- static/index.html | 65 +++++++++++++++++++++++++++++++++++++++++++++++ utils/qr_login.py | 13 +++++++--- 2 files changed, 75 insertions(+), 3 deletions(-) diff --git a/static/index.html b/static/index.html index ce91944..f6c5706 100644 --- a/static/index.html +++ b/static/index.html @@ -7883,6 +7883,12 @@ document.getElementById('qrCodeImage').style.display = 'none'; document.getElementById('statusText').textContent = '正在生成二维码,请耐心等待...'; document.getElementById('statusSpinner').style.display = 'none'; + + // 隐藏验证容器 + const verificationContainer = document.getElementById('verificationContainer'); + if (verificationContainer) { + verificationContainer.style.display = 'none'; + } } // 显示二维码图片 @@ -7957,6 +7963,12 @@ document.getElementById('statusSpinner').style.display = 'none'; clearQRCodeCheck(); break; + case 'verification_required': + document.getElementById('statusText').textContent = '需要手机验证'; + document.getElementById('statusSpinner').style.display = 'none'; + clearQRCodeCheck(); + showVerificationRequired(data); + break; } } } catch (error) { @@ -7964,6 +7976,59 @@ } } + // 显示需要验证的提示 + function showVerificationRequired(data) { + if (data.verification_url) { + // 隐藏二维码区域 + document.getElementById('qrCodeContainer').style.display = 'none'; + document.getElementById('qrCodeImage').style.display = 'none'; + + // 显示验证提示 + const verificationHtml = ` +
+
+ +
+
账号需要手机验证
+
+ + 检测到账号存在风控,需要进行手机验证才能完成登录 +
+
+

请点击下方按钮,在新窗口中完成手机验证:

+ + + 打开手机验证页面 + +
+
+ + + 验证步骤:
+ 1. 点击上方按钮打开验证页面
+ 2. 按照页面提示完成手机验证
+ 3. 验证完成后,重新扫码登录 +
+
+
+ `; + + // 创建验证提示容器 + let verificationContainer = document.getElementById('verificationContainer'); + if (!verificationContainer) { + verificationContainer = document.createElement('div'); + verificationContainer.id = 'verificationContainer'; + document.querySelector('#qrCodeLoginModal .modal-body').appendChild(verificationContainer); + } + + verificationContainer.innerHTML = verificationHtml; + verificationContainer.style.display = 'block'; + + // 显示Toast提示 + showToast('账号需要手机验证,请按照提示完成验证', 'warning'); + } + } + // 处理扫码成功 function handleQRCodeSuccess(data) { if (data.account_info) { diff --git a/utils/qr_login.py b/utils/qr_login.py index 8ad32f0..39d0068 100644 --- a/utils/qr_login.py +++ b/utils/qr_login.py @@ -48,7 +48,7 @@ class QRLoginSession: def __init__(self, session_id: str): self.session_id = session_id - self.status = 'waiting' # waiting, scanned, success, expired, cancelled + self.status = 'waiting' # waiting, scanned, success, expired, cancelled, verification_required self.qr_code_url = None self.qr_content = None self.cookies = {} @@ -56,6 +56,7 @@ class QRLoginSession: self.created_time = time.time() self.expire_time = 300 # 5分钟过期 self.params = {} # 存储登录参数 + self.verification_url = None # 风控验证URL def is_expired(self) -> bool: """检查是否过期""" @@ -281,13 +282,14 @@ class QRLoginManager: is True ): # 账号被风控,需要手机验证 - session.status = 'cancelled' + session.status = 'verification_required' iframe_url = ( resp.json() .get("content", {}) .get("data", {}) .get("iframeRedirectUrl") ) + session.verification_url = iframe_url logger.warning(f"账号被风控,需要手机验证: {session_id}, URL: {iframe_url}") break else: @@ -331,7 +333,7 @@ class QRLoginManager: await asyncio.sleep(2) # 超时处理 - if session.status not in ['success', 'expired', 'cancelled']: + if session.status not in ['success', 'expired', 'cancelled', 'verification_required']: session.status = 'expired' logger.info(f"二维码监控超时,标记为过期: {session_id}") @@ -354,6 +356,11 @@ class QRLoginManager: 'session_id': session_id } + # 如果需要验证,返回验证URL + if session.status == 'verification_required' and session.verification_url: + result['verification_url'] = session.verification_url + result['message'] = '账号被风控,需要手机验证' + # 如果登录成功,返回Cookie信息 if session.status == 'success' and session.cookies and session.unb: result['cookies'] = self._cookie_marshal(session.cookies)