[patch] 因pdd内部回复消息接口与登录接口不同步导致监听过程中发送消息接口返回会话过期处理优化逻辑 并设计开发提示用户 并提供用户是否重新发送会话过期消息体按钮

This commit is contained in:
2025-10-24 17:47:28 +08:00
parent 9effc859ac
commit 7a1ad47439
3 changed files with 393 additions and 50 deletions

View File

@@ -48,6 +48,9 @@ class WebSocketManager:
# 平台连接信号(线程安全)
self.platform_signals = PlatformConnectionSignals()
self.platform_signals.platform_connected.connect(self._on_platform_signal_received)
# 🔥 会话超时信号(用于拼多多会话过期重试)
self.session_timeout_signal = None
self.callbacks = {
'log': None,
@@ -384,6 +387,16 @@ class WebSocketManager:
from Utils.Pdd.PddUtils import WebsocketManager as PDDWSManager
pdd_mgr = PDDWSManager()
conn_info = pdd_mgr.get_connection(key)
# 清理旧listener的定时器避免遗留定时器触发
old_listener = listener_info.get('listener')
if old_listener and hasattr(old_listener, 'pdd_bot') and old_listener.pdd_bot:
try:
old_listener.pdd_bot._cancel_session_timeout_check()
self._log(f"✅ [PDD] 旧监听器的定时器已清理", "DEBUG")
except Exception:
pass
if conn_info and conn_info.get('platform'):
# 关闭WebSocket连接
ws = conn_info['platform'].get('ws')
@@ -685,39 +698,38 @@ class WebSocketManager:
def _start_pdd_listener(self, store_id: str, data: str, store_name: str = ""):
"""启动拼多多平台监听"""
try:
# 在创建新实例前,清理旧实例的定时器(避免遗留定时器触发)
shop_key = f"拼多多:{store_id}"
old_listener_info = self.platform_listeners.get(shop_key)
if old_listener_info:
try:
old_listener = old_listener_info.get('listener')
if old_listener and hasattr(old_listener, 'pdd_bot') and old_listener.pdd_bot:
old_listener.pdd_bot._cancel_session_timeout_check()
self._log(f"✅ 已清理旧监听器定时器", "DEBUG")
except Exception:
pass
def _runner():
try:
self._log("🚀 开始创建拼多多监听器实例", "DEBUG")
listener = PDDListenerForGUI_WS(log_callback=self._log)
self._log("✅ 拼多多监听器实例创建成功", "DEBUG")
# 传递session_timeout_signal用于会话过期重试
listener = PDDListenerForGUI_WS(
log_callback=self._log,
session_timeout_signal=self.session_timeout_signal
)
# 立即保存listener引用到platform_listeners用于后续清理定时器
shop_key = f"拼多多:{store_id}"
if shop_key in self.platform_listeners:
self.platform_listeners[shop_key]['listener'] = listener
# 判断是登录参数还是Cookie
if self._is_pdd_login_params(data):
# 使用登录参数启动
self._log("📋 使用登录参数启动拼多多监听器", "INFO")
self._log("🔄 开始执行 start_with_login_params", "DEBUG")
result = asyncio.run(listener.start_with_login_params(store_id=store_id, login_params=data))
self._log(f"📊 start_with_login_params 执行结果: {result}", "DEBUG")
# 详细的结果分析仅日志记录GUI 已在主线程中通知)
if result == "need_verification_code":
self._log("✅ [PDD] 登录流程正常,已发送验证码需求通知给后端", "SUCCESS")
elif result == "verification_code_error":
self._log("⚠️ [PDD] 验证码错误,已发送错误通知给后端", "WARNING")
elif result:
self._log("✅ [PDD] 登录成功,平台连接已建立", "SUCCESS")
else:
self._log("❌ [PDD] 登录失败", "ERROR")
else:
# 使用Cookie启动兼容旧方式
self._log("🍪 使用Cookie启动拼多多监听器", "INFO")
self._log("🔄 开始执行 start_with_cookies", "DEBUG")
result = asyncio.run(listener.start_with_cookies(store_id=store_id, cookies=data))
self._log(f"📊 start_with_cookies 执行结果: {result}", "DEBUG")
# Cookie启动成功时记录日志GUI 已在主线程中通知)
if result:
self._log("✅ [PDD] Cookie启动成功平台连接已建立", "SUCCESS")
# 根据实际登录结果上报状态给后端
if self.backend_client and result not in ["need_verification_code", "verification_code_error",
@@ -802,29 +814,19 @@ class WebSocketManager:
def _is_pdd_login_params(self, data: str) -> bool:
"""判断是否为拼多多登录参数"""
try:
self._log(f"🔍 [DEBUG] 检查是否为登录参数,数据长度: {len(data)}", "DEBUG")
self._log(f"🔍 [DEBUG] 数据前100字符: {data[:100]}", "DEBUG")
import json
parsed_data = json.loads(data)
self._log(f"🔍 [DEBUG] JSON解析成功键: {list(parsed_data.keys())}", "DEBUG")
login_params = parsed_data.get("data", {}).get("login_params", {})
self._log(f"🔍 [DEBUG] login_params存在: {bool(login_params)}", "DEBUG")
if not login_params:
self._log("🔍 [DEBUG] login_params为空返回False", "DEBUG")
return False
# 检查必需的登录参数字段
required_fields = ["username", "password", "anti_content", "risk_sign", "timestamp"]
has_all_fields = all(field in login_params for field in required_fields)
self._log(f"🔍 [DEBUG] 包含所有必需字段: {has_all_fields}", "DEBUG")
self._log(f"🔍 [DEBUG] 现有字段: {list(login_params.keys())}", "DEBUG")
return has_all_fields
except Exception as e:
self._log(f"🔍 [DEBUG] 解析失败: {e}", "DEBUG")
except Exception:
return False
def send_message(self, message: dict):