[patch] 新增用户余额不足 交互模式代码

This commit is contained in:
2025-10-17 17:38:02 +08:00
parent a5c2a44512
commit 8eb03ddedc
4 changed files with 225 additions and 77 deletions

View File

@@ -60,7 +60,8 @@ class WebSocketManager:
def set_callbacks(self, log: Callable = None, success: Callable = None, error: Callable = None,
platform_connected: Callable = None, platform_disconnected: Callable = None,
token_error: Callable = None, disconnect: Callable = None):
token_error: Callable = None, disconnect: Callable = None,
balance_insufficient: Callable = None):
"""设置回调函数"""
if log:
self.callbacks['log'] = log
@@ -76,6 +77,8 @@ class WebSocketManager:
self.callbacks['token_error'] = token_error
if disconnect:
self.callbacks['disconnect'] = disconnect
if balance_insufficient:
self.callbacks['balance_insufficient'] = balance_insufficient
def _log(self, message: str, level: str = "INFO"):
"""内部日志方法"""
@@ -104,15 +107,16 @@ class WebSocketManager:
except Exception as e:
self._log(f"通知平台连接失败: {e}", "ERROR")
def notify_platform_kicked(self, platform_name: str, store_name: str, reason: str = "账号在其他设备登录", store_id: str = None):
def notify_platform_kicked(self, platform_name: str, store_name: str, reason: str = "账号在其他设备登录",
store_id: str = None):
"""通知GUI平台被踢下线供平台监听器调用"""
try:
self._log(f"⚠️ 平台被踢下线: {platform_name} - {store_name}, 原因: {reason}", "WARNING")
# 从连接列表中移除
if platform_name in self.connected_platforms:
self.connected_platforms.remove(platform_name)
# 🔥 发送平台断开消息给后端status=false
if store_id and self.backend_client:
try:
@@ -126,13 +130,63 @@ class WebSocketManager:
self._log(f"✅ 已通知后端 {platform_name} 平台断开: {store_id}", "INFO")
except Exception as send_error:
self._log(f"❌ 发送平台断开消息失败: {send_error}", "ERROR")
# 通知GUI显示弹窗
if self.callbacks['platform_disconnected']:
self.callbacks['platform_disconnected'](platform_name, store_name, reason)
except Exception as e:
self._log(f"通知平台断开失败: {e}", "ERROR")
def disconnect_all_async(self):
"""异步断开所有连接(余额不足时调用)- 不阻塞当前线程"""
try:
self._log("🔴 收到余额不足通知,开始断开所有连接...", "ERROR")
# 1. 断开所有平台连接
if self.platform_listeners:
platform_count = len(self.platform_listeners)
self._log(f"正在断开 {platform_count} 个平台连接...", "INFO")
# 复制键列表,避免遍历时修改字典
platform_keys = list(self.platform_listeners.keys())
for key in platform_keys:
try:
listener_info = self.platform_listeners.get(key)
if listener_info:
platform_type = listener_info.get('platform', '')
self._log(f"断开 {platform_type} 平台连接: {key}", "INFO")
# 移除连接记录
self.platform_listeners.pop(key, None)
except Exception as e:
self._log(f"断开平台连接失败: {e}", "ERROR")
self._log(f"✅ 已断开所有 {platform_count} 个平台连接", "INFO")
# 清空连接列表
self.connected_platforms.clear()
# 2. 延迟断开后端连接(在新线程中执行,避免阻塞)
import threading
def _delayed_backend_disconnect():
try:
import time
time.sleep(0.5) # 延迟0.5秒,确保上面的操作完成
if self.backend_client:
self.backend_client.should_stop = True
self.backend_client.is_connected = False
self._log("✅ 已标记后端连接为断开状态", "INFO")
except Exception as e:
self._log(f"断开后端连接失败: {e}", "ERROR")
disconnect_thread = threading.Thread(target=_delayed_backend_disconnect, daemon=True)
disconnect_thread.start()
except Exception as e:
self._log(f"断开所有连接失败: {e}", "ERROR")
def connect_backend(self, token: str) -> bool:
"""连接后端WebSocket"""
try:
@@ -188,12 +242,18 @@ class WebSocketManager:
if self.callbacks['disconnect']:
self.callbacks['disconnect'](disconnect_msg)
def _on_balance_insufficient(balance_msg: str):
"""余额不足回调"""
if self.callbacks['balance_insufficient']:
self.callbacks['balance_insufficient'](balance_msg)
def _on_log(message: str, level: str = "INFO"):
"""Backend client log callback"""
self._log(message, level)
backend.set_callbacks(success=_on_backend_success, login=_on_backend_login,
token_error=_on_token_error, disconnect=_on_disconnect,
balance_insufficient=_on_balance_insufficient,
log=_on_log)
if not backend.is_connected:
@@ -235,12 +295,18 @@ class WebSocketManager:
if self.callbacks['disconnect']:
self.callbacks['disconnect'](disconnect_msg)
def _on_balance_insufficient(balance_msg: str):
"""余额不足回调"""
if self.callbacks['balance_insufficient']:
self.callbacks['balance_insufficient'](balance_msg)
def _on_log(message: str, level: str = "INFO"):
"""Backend client log callback"""
self._log(message, level)
backend.set_callbacks(login=_on_backend_login, success=_on_backend_success,
token_error=_on_token_error, disconnect=_on_disconnect,
balance_insufficient=_on_balance_insufficient,
log=_on_log)
backend.connect()
@@ -261,15 +327,15 @@ class WebSocketManager:
# 🔥 检查并断开当前店铺的旧连接策略B先断开旧连接再建立新连接
store_key_pattern = f":{store_id}" # 匹配 "平台名:store_id" 格式
keys_to_remove = [key for key in self.platform_listeners.keys() if key.endswith(store_key_pattern)]
if keys_to_remove:
self._log(f"🔄 检测到店铺 {store_id} 重复登录,断开 {len(keys_to_remove)} 个旧连接", "INFO")
for key in keys_to_remove:
listener_info = self.platform_listeners.get(key)
if listener_info:
platform_type = listener_info.get('platform', '')
# 从各平台的 WebsocketManager 中获取连接并关闭WebSocket
try:
if platform_type == "京东":
@@ -289,7 +355,7 @@ class WebSocketManager:
pass
jd_mgr.remove_connection(key)
self._log(f"✅ 已从京东管理器移除连接: {key}", "DEBUG")
elif platform_type == "抖音":
from Utils.Dy.DyUtils import DouYinWebsocketManager as DYWSManager
dy_mgr = DYWSManager()
@@ -307,13 +373,13 @@ class WebSocketManager:
pass
dy_mgr.remove_connection(key)
self._log(f"✅ 已从抖音管理器移除连接: {key}", "DEBUG")
elif platform_type == "千牛":
from Utils.QianNiu.QianNiuUtils import QianNiuWebsocketManager as QNWSManager
qn_mgr = QNWSManager()
qn_mgr.remove_connection(key)
self._log(f"✅ 已从千牛管理器移除连接: {key}", "DEBUG")
elif platform_type == "拼多多":
from Utils.Pdd.PddUtils import WebsocketManager as PDDWSManager
pdd_mgr = PDDWSManager()
@@ -332,17 +398,17 @@ class WebSocketManager:
self._log(f"⚠️ 关闭WebSocket时出错: {ws_e}", "DEBUG")
pdd_mgr.remove_connection(key)
self._log(f"✅ 已从拼多多管理器移除连接: {key}", "DEBUG")
except Exception as e:
self._log(f"⚠️ 移除{platform_type}连接时出错: {e}", "WARNING")
# 从监听器字典中移除
self.platform_listeners.pop(key, None)
# 给WebSocket一点时间完全关闭
import time
time.sleep(0.5)
self._log(f"✅ 旧连接已全部断开,准备建立新连接", "INFO")
# 平台名称映射