# gui/login_window.py """ Окно авторизации менеджера Соответствует требованиям ТЗ по аутентификации """ import sys from PyQt6.QtWidgets import (QApplication, QDialog, QVBoxLayout, QHBoxLayout, QLabel, QLineEdit, QPushButton, QMessageBox, QFrame, QCheckBox) from PyQt6.QtCore import Qt, pyqtSignal from PyQt6.QtGui import QFont, QPixmap, QIcon import requests from requests.auth import HTTPBasicAuth class LoginWindow(QDialog): """Окно авторизации системы MasterPol""" login_success = pyqtSignal(dict) # Сигнал об успешной авторизации def __init__(self): super().__init__() self.setup_ui() self.load_settings() def setup_ui(self): """Настройка интерфейса окна авторизации""" self.setWindowTitle("MasterPol - Авторизация") self.setFixedSize(400, 500) self.setModal(True) # Установка иконки приложения try: self.setWindowIcon(QIcon("resources/icon.png")) except: pass layout = QVBoxLayout() layout.setContentsMargins(30, 30, 30, 30) layout.setSpacing(0) # Заголовок title_label = QLabel("MasterPol") title_label.setFont(QFont("Arial", 24, QFont.Weight.Bold)) title_label.setAlignment(Qt.AlignmentFlag.AlignCenter) title_label.setStyleSheet("color: #007acc; margin-bottom: 20px;") subtitle_label = QLabel("Система управления партнерами") subtitle_label.setFont(QFont("Arial", 12)) subtitle_label.setAlignment(Qt.AlignmentFlag.AlignCenter) subtitle_label.setStyleSheet("color: #666; margin-bottom: 30px;") layout.addWidget(title_label) layout.addWidget(subtitle_label) # Форма авторизаци form_frame = QFrame() form_frame.setStyleSheet(""" QFrame { background-color: white; border: 0px solid #ddd; border-radius: 4px; padding: 20px; } """) form_layout = QVBoxLayout() form_layout.setSpacing(15) # Поле логина username_layout = QVBoxLayout() username_label = QLabel("Имя пользователя:") username_label.setStyleSheet("font-weight: bold; color: #333;") self.username_input = QLineEdit() self.username_input.setPlaceholderText("Введите имя пользователя") self.username_input.setStyleSheet(""" QLineEdit { padding: 8px 12px; border: 2px solid #ccc; border-radius: 6px; font-size: 14px; } QLineEdit:focus { border-color: #007acc; } """) username_layout.addWidget(username_label) username_layout.addWidget(self.username_input) # Поле пароля password_layout = QVBoxLayout() password_label = QLabel("Пароль:") password_label.setStyleSheet("font-weight: bold; color: #333;") self.password_input = QLineEdit() self.password_input.setPlaceholderText("Введите пароль") self.password_input.setEchoMode(QLineEdit.EchoMode.Password) self.password_input.setStyleSheet(""" QLineEdit { padding: 10px; border: 1px solid #ccc; border-radius: 4px; font-size: 14px; } QLineEdit:focus { border-color: #007acc; } """) password_layout.addWidget(password_label) password_layout.addWidget(self.password_input) # Запомнить меня self.remember_checkbox = QCheckBox("Запомнить меня") self.remember_checkbox.setStyleSheet("color: #333;") # Кнопка входа self.login_button = QPushButton("Войти в систему") self.login_button.clicked.connect(self.authenticate) self.login_button.setStyleSheet(""" QPushButton { background-color: #007acc; color: white; border: none; padding: 12px; border-radius: 4px; font-weight: bold; font-size: 14px; } QPushButton:hover { background-color: #005a9e; } QPushButton:disabled { background-color: #ccc; color: #666; } """) # Подсказка hint_label = QLabel("Используйте логин: manager, пароль: pass123") hint_label.setStyleSheet("color: #666; font-size: 12px; margin-top: 10px;") hint_label.setAlignment(Qt.AlignmentFlag.AlignCenter) form_layout.addLayout(username_layout) form_layout.addLayout(password_layout) form_layout.addWidget(self.remember_checkbox) form_layout.addWidget(self.login_button) form_layout.addWidget(hint_label) form_frame.setLayout(form_layout) layout.addWidget(form_frame) # Информация о системе info_label = QLabel("MasterPol v1.0.0\nСистема управления партнерами и продажами") info_label.setAlignment(Qt.AlignmentFlag.AlignCenter) info_label.setStyleSheet("color: #999; font-size: 11px; margin-top: 20px;") layout.addWidget(info_label) self.setLayout(layout) # Подключаем обработчики событий self.username_input.returnPressed.connect(self.authenticate) self.password_input.returnPressed.connect(self.authenticate) def load_settings(self): """Загрузка сохраненных настроек авторизации""" try: # Здесь можно добавить загрузку из файла настроек # Пока просто устанавливаем значения по умолчанию self.username_input.setText("manager") except: pass def save_settings(self): """Сохранение настроек авторизации""" if self.remember_checkbox.isChecked(): # Здесь можно добавить сохранение в файл настроек pass def authenticate(self): """Аутентификация пользователя""" username = self.username_input.text().strip() password = self.password_input.text().strip() if not username or not password: QMessageBox.warning(self, "Ошибка", "Заполните все поля") return # Блокируем кнопку во время аутентификации self.login_button.setEnabled(False) self.login_button.setText("Проверка...") try: # Выполняем аутентификацию через API response = requests.post( "http://localhost:8000/api/v1/auth/login", auth=HTTPBasicAuth(username, password), timeout=10 ) if response.status_code == 200: user_data = response.json() # Сохраняем настройки self.save_settings() # Сохраняем учетные данные для будущих запросов user_data['auth'] = HTTPBasicAuth(username, password) # Отправляем сигнал об успешной авторизации self.login_success.emit(user_data) else: QMessageBox.warning( self, "Ошибка авторизации", "Неверное имя пользователя или пароль" ) except requests.exceptions.ConnectionError: QMessageBox.critical( self, "Ошибка подключения", "Не удалось подключиться к серверу.\n" "Убедитесь, что сервер запущен на localhost:8000" ) except requests.exceptions.Timeout: QMessageBox.critical( self, "Ошибка подключения", "Превышено время ожидания ответа от сервера" ) except Exception as e: QMessageBox.critical( self, "Ошибка", f"Произошла непредвиденная ошибка:\n{str(e)}" ) finally: # Разблокируем кнопку self.login_button.setEnabled(True) self.login_button.setText("Войти в систему") def main(): """Точка входа для тестирования окна авторизации""" app = QApplication(sys.argv) window = LoginWindow() window.show() sys.exit(app.exec()) if __name__ == "__main__": main()