import json import os from PySide6.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QLabel, QLineEdit, QComboBox, QPushButton, QGroupBox, QMessageBox, QFormLayout) from PySide6.QtCore import Qt import paramiko from loguru import logger class ServerConnectionTab(QWidget): def __init__(self): super().__init__() logger.info("初始化服务器连接标签页") self.ssh_client = None self.config_data = {} self.init_ui() self.load_config() def init_ui(self): # 主布局 main_layout = QVBoxLayout() # 服务器配置组 config_group = QGroupBox("服务器配置") config_layout = QFormLayout() # 别名选择 alias_layout = QHBoxLayout() self.alias_combo = QComboBox() self.alias_combo.currentTextChanged.connect(self.on_alias_changed) alias_layout.addWidget(self.alias_combo, 3) self.new_alias_input = QLineEdit() self.new_alias_input.setPlaceholderText("输入新别名") alias_layout.addWidget(self.new_alias_input, 2) self.add_alias_button = QPushButton("添加") self.add_alias_button.clicked.connect(self.add_new_alias) alias_layout.addWidget(self.add_alias_button, 1) config_layout.addRow("别名:", alias_layout) # 服务器信息输入 self.ip_input = QLineEdit() config_layout.addRow("IP地址:", self.ip_input) self.username_input = QLineEdit() config_layout.addRow("用户名:", self.username_input) self.password_input = QLineEdit() self.password_input.setEchoMode(QLineEdit.Password) config_layout.addRow("密码:", self.password_input) self.port_input = QLineEdit("22") config_layout.addRow("端口:", self.port_input) self.project_input = QLineEdit() config_layout.addRow("项目名称:", self.project_input) config_group.setLayout(config_layout) main_layout.addWidget(config_group) # 按钮区域 button_layout = QHBoxLayout() self.save_button = QPushButton("保存配置") self.save_button.clicked.connect(self.save_config) button_layout.addWidget(self.save_button) self.connect_button = QPushButton("连接服务器") self.connect_button.clicked.connect(self.connect_to_server) button_layout.addWidget(self.connect_button) main_layout.addLayout(button_layout) # 连接状态 self.status_label = QLabel("未连接") self.status_label.setAlignment(Qt.AlignCenter) main_layout.addWidget(self.status_label) # 添加伸缩空间 main_layout.addStretch() self.setLayout(main_layout) logger.info("服务器连接标签页UI初始化完成") def load_config(self): logger.info("加载配置文件") config_path = os.path.join(os.path.dirname(__file__), "config.json") try: if os.path.exists(config_path): with open(config_path, "r", encoding="utf-8") as f: self.config_data = json.load(f) logger.info(f"成功加载配置文件: {config_path}") else: logger.info(f"配置文件不存在,将创建新文件: {config_path}") self.config_data = {} # 更新别名下拉框 self.alias_combo.clear() for alias in self.config_data.keys(): self.alias_combo.addItem(alias) # 如果有配置,选择第一个别名 if self.config_data: self.alias_combo.setCurrentIndex(0) except Exception as e: logger.error(f"加载配置文件失败: {str(e)}") QMessageBox.warning(self, "错误", f"加载配置文件失败: {str(e)}") def on_alias_changed(self, alias): logger.info(f"选择别名: {alias}") if alias and alias in self.config_data: server_info = self.config_data[alias] self.ip_input.setText(server_info.get("ip", "")) self.username_input.setText(server_info.get("username", "")) self.password_input.setText(server_info.get("password", "")) self.port_input.setText(str(server_info.get("port", "22"))) self.project_input.setText(server_info.get("project", "")) def add_new_alias(self): logger.info("添加新别名") new_alias = self.new_alias_input.text().strip() if not new_alias: QMessageBox.warning(self, "警告", "请输入新别名") return if new_alias in self.config_data: QMessageBox.warning(self, "警告", "该别名已存在") return # 添加新别名到下拉框 self.alias_combo.addItem(new_alias) self.alias_combo.setCurrentText(new_alias) # 清空输入框 self.new_alias_input.clear() logger.info(f"已添加新别名: {new_alias}") def save_config(self): logger.info("保存配置") alias = self.alias_combo.currentText() if not alias: QMessageBox.warning(self, "警告", "请选择或添加别名") return # 获取当前输入的值 server_info = { "ip": self.ip_input.text(), "username": self.username_input.text(), "password": self.password_input.text(), "port": int(self.port_input.text()), "project": self.project_input.text() } # 更新配置数据 self.config_data[alias] = server_info # 保存到文件 config_path = os.path.join(os.path.dirname(__file__), "config.json") try: with open(config_path, "w", encoding="utf-8") as f: json.dump(self.config_data, f, ensure_ascii=False, indent=4) logger.info(f"配置已保存到: {config_path}") QMessageBox.information(self, "成功", "配置已保存") except Exception as e: logger.error(f"保存配置失败: {str(e)}") QMessageBox.warning(self, "错误", f"保存配置失败: {str(e)}") def connect_to_server(self): logger.info("尝试连接服务器") # 获取连接信息 ip = self.ip_input.text() username = self.username_input.text() password = self.password_input.text() port = int(self.port_input.text()) if not all([ip, username, password]): QMessageBox.warning(self, "警告", "请填写完整的连接信息") return try: # 创建SSH客户端 self.ssh_client = paramiko.SSHClient() self.ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 连接服务器 self.ssh_client.connect(ip, port=port, username=username, password=password) logger.info(f"成功连接到服务器: {ip}") self.status_label.setText(f"已连接到 {ip}") self.status_label.setStyleSheet("color: green;") QMessageBox.information(self, "成功", f"成功连接到服务器: {ip}") except Exception as e: logger.error(f"连接服务器失败: {str(e)}") self.status_label.setText("连接失败") self.status_label.setStyleSheet("color: red;") QMessageBox.warning(self, "错误", f"连接服务器失败: {str(e)}") if self.ssh_client: self.ssh_client.close() self.ssh_client = None def get_ssh_client(self): return self.ssh_client