import sys from PyQt5.QtCore import Qt from PyQt5.QtGui import QFont, QPalette, QColor from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QLabel, QPushButton, QLineEdit, QTextEdit, QFrame, QDialog, QDialogButtonBox, QComboBox) import config from WebSocket.backend_singleton import get_websocket_manager # 新增: 用户名密码输入对话框类 class LoginWindow(QMainWindow): def __init__(self): super().__init__() self.jd_worker = None self.progress_dialog = None self.douyin_worker = None self.qian_niu_worker = None self.pdd_worker = None # 重复执行防护 self.platform_combo_connected = False self.last_login_time = 0 self.login_cooldown = 2 # 登录冷却时间(秒) # 日志管理相关变量已删除 self.initUI() # 设置当前平台为ComboBox的当前值 self.current_platform = self.platform_combo.currentText() def initUI(self): # 设置窗口基本属性 self.setWindowTitle('AI回复连接入口-V1.0') self.setGeometry(300, 300, 800, 600) # 增大窗口尺寸 self.setMinimumSize(700, 500) # 设置最小尺寸保证显示完整 # 创建中央widget central_widget = QWidget() self.setCentralWidget(central_widget) # 创建主布局 main_layout = QVBoxLayout() main_layout.setSpacing(25) # 增加间距 main_layout.setContentsMargins(40, 40, 40, 40) # 增加边距 central_widget.setLayout(main_layout) # 添加标题 title_label = QLabel('AI回复连接入口') title_label.setAlignment(Qt.AlignCenter) title_label.setFont(QFont('Microsoft YaHei', 24, QFont.Bold)) # 使用系统自带字体 title_label.setStyleSheet("color: #2c3e50;") main_layout.addWidget(title_label) # 添加分隔线 line = QFrame() line.setFrameShape(QFrame.HLine) line.setFrameShadow(QFrame.Sunken) line.setStyleSheet("color: #bdc3c7;") main_layout.addWidget(line) # 在token_input之前添加平台选择区域 platform_layout = QHBoxLayout() platform_label = QLabel("选择平台:") self.platform_combo = QComboBox() self.platform_combo.addItems(["JD", "抖音", "千牛(淘宝)", "拼多多"]) # 防止重复连接信号 - 更强的保护 if not hasattr(self, 'platform_combo_connected') or not self.platform_combo_connected: try: self.platform_combo.currentIndexChanged.disconnect() except TypeError: pass # 如果没有连接则忽略 self.platform_combo.currentIndexChanged.connect(self.on_platform_changed) self.platform_combo_connected = True platform_layout.addWidget(platform_label) platform_layout.addWidget(self.platform_combo) # 将platform_layout添加到主布局中,在token_layout之前 main_layout.addLayout(platform_layout) # 创建令牌输入区域 token_layout = QHBoxLayout() token_layout.setSpacing(15) token_label = QLabel('令牌:') token_label.setFont(QFont('Microsoft YaHei', 12)) token_label.setFixedWidth(80) self.token_input = QLineEdit() self.token_input.setPlaceholderText('请输入您的访问令牌') self.token_input.setEchoMode(QLineEdit.Password) self.token_input.setFont(QFont('Microsoft YaHei', 11)) # noinspection PyUnresolvedReferences self.token_input.returnPressed.connect(self.login) # 表示回车提交 self.token_input.setMinimumHeight(40) # 增加输入框高度 # 预填已保存的令牌(如果存在) try: from config import get_saved_token saved = get_saved_token() if saved: self.token_input.setText(saved) except Exception: pass token_layout.addWidget(token_label) token_layout.addWidget(self.token_input) main_layout.addLayout(token_layout) # 创建连接按钮 self.login_btn = QPushButton('是否连接') self.login_btn.setFont(QFont('Microsoft YaHei', 12, QFont.Bold)) self.login_btn.setMinimumHeight(45) # 增大按钮高度 self.login_btn.clicked.connect(self.login) # 表示点击提交 main_layout.addWidget(self.login_btn) # 添加分隔线 line = QFrame() line.setFrameShape(QFrame.HLine) line.setFrameShadow(QFrame.Sunken) line.setStyleSheet("color: #bdc3c7;") main_layout.addWidget(line) # 日志框已永久删除,只使用终端输出 self.log_display = None # 应用现代化样式 self.apply_modern_styles() # 系统初始化日志输出到终端 print("[INFO] 系统初始化完成") # # 在平台选择改变时添加调试日志 # self.platform_combo.currentIndexChanged.connect(self.on_platform_changed) # 设置默认平台 self.platform_combo.setCurrentText("JD") print(f"🔥 设置默认平台为: {self.platform_combo.currentText()}") def apply_modern_styles(self): """应用现代化样式,兼容各Windows版本""" self.setStyleSheet(""" QMainWindow { background-color: #f9f9f9; } QLabel { color: #34495e; } QLineEdit { padding: 10px; border: 2px solid #dfe6e9; border-radius: 6px; font-size: 14px; background-color: white; selection-background-color: #3498db; selection-color: white; } QLineEdit:focus { border-color: #3498db; } QPushButton { background-color: #3498db; border: none; color: white; padding: 12px 24px; border-radius: 6px; font-size: 14px; min-width: 120px; } QPushButton:hover { background-color: #2980b9; } QPushButton:pressed { background-color: #1a6a9c; } QPushButton:disabled { background-color: #bdc3c7; color: #7f8c8d; } QTextEdit { border: 2px solid #dfe6e9; border-radius: 6px; background-color: white; padding: 8px; font-family: 'Consolas', 'Microsoft YaHei', monospace; } QFrame[frameShape="4"] { color: #dfe6e9; } QGroupBox { font-weight: bold; border: 2px solid #dfe6e9; border-radius: 6px; margin-top: 10px; padding-top: 10px; } QComboBox { padding: 8px; border: 2px solid #dfe6e9; border-radius: 6px; font-size: 14px; background-color: white; min-width: 100px; } QComboBox::drop-down { border: none; width: 20px; } QComboBox QAbstractItemView { border: 2px solid #dfe6e9; selection-background-color: #3498db; selection-color: white; } """) # 设置全局字体,确保各Windows版本显示一致 font = QFont('Microsoft YaHei', 10) # Windows系统自带字体 QApplication.setFont(font) # 设置调色板确保颜色一致性 palette = QPalette() palette.setColor(QPalette.Window, QColor(249, 249, 249)) palette.setColor(QPalette.WindowText, QColor(52, 73, 94)) palette.setColor(QPalette.Base, QColor(255, 255, 255)) palette.setColor(QPalette.AlternateBase, QColor(233, 235, 239)) palette.setColor(QPalette.ToolTipBase, QColor(255, 255, 255)) palette.setColor(QPalette.ToolTipText, QColor(52, 73, 94)) palette.setColor(QPalette.Text, QColor(52, 73, 94)) palette.setColor(QPalette.Button, QColor(52, 152, 219)) palette.setColor(QPalette.ButtonText, QColor(255, 255, 255)) palette.setColor(QPalette.BrightText, QColor(255, 255, 255)) palette.setColor(QPalette.Highlight, QColor(52, 152, 219)) palette.setColor(QPalette.HighlightedText, QColor(255, 255, 255)) QApplication.setPalette(palette) def on_platform_changed(self, index): """平台选择改变时的处理 - 新增方法""" platform = self.platform_combo.currentText() self.current_platform = platform self.add_log(f"已选择平台: {platform}", "INFO") print(f"🔥 平台已更改为: {platform}") def add_log(self, message, log_type="INFO"): """添加日志信息 - 只输出到终端""" from datetime import datetime timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") # 根据日志类型设置颜色(ANSI颜色码) colors = { "ERROR": "\033[91m", # 红色 "SUCCESS": "\033[92m", # 绿色 "WARNING": "\033[93m", # 黄色 "INFO": "\033[94m", # 蓝色 "DEBUG": "\033[95m" # 紫色 } reset = "\033[0m" # 重置颜色 color = colors.get(log_type, colors["INFO"]) log_entry = f"{color}[{timestamp}] [{log_type}] {message}{reset}" print(log_entry) def login(self): """处理连接逻辑""" # 防止重复快速点击 import time current_time = time.time() if current_time - self.last_login_time < self.login_cooldown: self.add_log(f"请等待 {self.login_cooldown} 秒后再试", "WARNING") return self.last_login_time = current_time token = self.token_input.text().strip() if not token: self.add_log("请输入有效的连接令牌", "ERROR") return # 禁用连接按钮,防止重复点击 self.login_btn.setEnabled(False) self.login_btn.setText("连接中...") try: # 使用 WebSocket 管理器处理连接 ws_manager = get_websocket_manager() # 设置回调函数 ws_manager.set_callbacks( log=self.add_log, success=lambda: self.add_log("WebSocket连接管理器连接成功", "SUCCESS"), error=lambda error: self.add_log(f"WebSocket连接管理器错误: {error}", "ERROR") ) # 连接后端 success = ws_manager.connect_backend(token) if success: self.add_log("已启动WebSocket连接管理器", "SUCCESS") else: self.add_log("WebSocket连接管理器启动失败", "ERROR") except Exception as e: self.add_log(f"连接失败: {e}", "ERROR") finally: self.login_btn.setEnabled(True) self.login_btn.setText("开始连接") def verify_token(self, token): """简化的令牌校验:非空即通过(实际校验由后端承担)""" return bool(token) def closeEvent(self, event): """窗口关闭事件处理""" try: # 使用 WebSocket 管理器断开所有连接 from WebSocket.backend_singleton import get_websocket_manager ws_manager = get_websocket_manager() ws_manager.disconnect_all() # 停止所有工作线程(向后兼容) workers = [] if hasattr(self, 'jd_worker') and self.jd_worker: workers.append(self.jd_worker) if hasattr(self, 'douyin_worker') and self.douyin_worker: workers.append(self.douyin_worker) if hasattr(self, 'qian_niu_worker') and self.qian_niu_worker: workers.append(self.qian_niu_worker) if hasattr(self, 'pdd_worker') and self.pdd_worker: workers.append(self.pdd_worker) # 停止所有线程 for worker in workers: if worker.isRunning(): worker.stop() worker.quit() worker.wait(1000) # 强制关闭事件循环 for worker in workers: if hasattr(worker, 'loop') and worker.loop and not worker.loop.is_closed(): worker.loop.close() except Exception as e: print(f"关闭窗口时发生错误: {str(e)}") finally: event.accept() def main(): """主函数,用于测试界面""" app = QApplication(sys.argv) # 设置应用程序属性 app.setApplicationName(config.WINDOW_TITLE) app.setApplicationVersion(config.VERSION) # 创建主窗口 window = LoginWindow() window.show() # 程序启动断点 # 运行应用程序 sys.exit(app.exec_()) if __name__ == '__main__': main() # sd_aAoHIO9fDRIkePZEhW6oaFgK6IzAPxuB 测试令牌(token) # username = "KLD测试" # password = "kld168168" # taobao nickname = "tb420723827:redboat"