259 lines
11 KiB
Python
259 lines
11 KiB
Python
import sys
|
|
from PySide6.QtWidgets import QApplication, QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QLabel, QTabWidget, QLineEdit, QMessageBox, QSizePolicy
|
|
from PySide6.QtCore import Qt, QSize
|
|
from PySide6.QtGui import QFont, QIcon, QPixmap, QShortcut
|
|
from codes.common import clibs, db_operation
|
|
from codes.common.secure_encrypt import PassCipher
|
|
from codes.ui import main_ui
|
|
from codes.common.exception_handler import handle_exception
|
|
|
|
|
|
class LoginWindow(QWidget):
|
|
def __init__(self):
|
|
super().__init__()
|
|
self.pre_do()
|
|
self.init_ui()
|
|
self.post_do()
|
|
|
|
def pre_do(self):
|
|
db_operation.db_init()
|
|
db_operation.db_conn()
|
|
|
|
def init_ui(self):
|
|
self.setObjectName("LoginWindow")
|
|
self.setMinimumSize(420, 200)
|
|
self.setMaximumSize(500, 240)
|
|
self.resize(480, 200)
|
|
self.setWindowTitle("登录")
|
|
self.setWindowIcon(QIcon(clibs.icon))
|
|
self.setFont(QFont("Consolas", 14))
|
|
|
|
self.layout_outer = QHBoxLayout()
|
|
self.lb_logo = QLabel()
|
|
self.lb_logo.setObjectName("lb_logo")
|
|
self.lb_logo.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
|
self.lb_logo.setSizePolicy(QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Preferred)
|
|
self.lb_logo.setPixmap(QPixmap(clibs.logo))
|
|
self.lb_logo.setFixedSize(QSize(120, 120))
|
|
self.lb_logo.setScaledContents(True)
|
|
self.layout_outer.addWidget(self.lb_logo)
|
|
|
|
self.tabW_login = QTabWidget()
|
|
self.tabW_login.setObjectName("tabW_login")
|
|
self.tab_login = QWidget()
|
|
self.tab_login.setObjectName("tab_login")
|
|
self.tabW_login.addTab(self.tab_login, "登录")
|
|
self.tab_register = QWidget()
|
|
self.tab_register.setObjectName("tab_register")
|
|
self.tabW_login.addTab(self.tab_register, "注册")
|
|
self.layout_outer.addWidget(self.tabW_login)
|
|
|
|
# 登陆页面
|
|
self.layout_H_username = QHBoxLayout()
|
|
self.lb_username = QLabel("账号")
|
|
self.lb_username.setObjectName("lb_username")
|
|
self.lb_username.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
|
self.layout_H_username.addWidget(self.lb_username)
|
|
self.le_username = QLineEdit()
|
|
self.le_username.setObjectName("le_username")
|
|
self.le_username.setFocus()
|
|
self.layout_H_username.addWidget(self.le_username)
|
|
|
|
self.layout_H_password = QHBoxLayout()
|
|
self.lb_password = QLabel("密码")
|
|
self.lb_password.setObjectName("lb_password")
|
|
self.lb_password.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
|
self.layout_H_password.addWidget(self.lb_password)
|
|
self.le_password = QLineEdit()
|
|
self.le_password.setObjectName("le_password")
|
|
self.le_password.setEchoMode(QLineEdit.EchoMode.Password)
|
|
self.layout_H_password.addWidget(self.le_password)
|
|
|
|
self.layout_H_button = QHBoxLayout()
|
|
self.btn_login = QPushButton("登录")
|
|
self.btn_login.setObjectName("btn_login")
|
|
self.btn_login.setAutoDefault(True)
|
|
self.btn_cancel = QPushButton("取消")
|
|
self.btn_cancel.setObjectName("btn_cancel")
|
|
self.btn_cancel.setAutoDefault(True)
|
|
self.layout_H_button.addWidget(self.btn_login)
|
|
self.layout_H_button.addWidget(self.btn_cancel)
|
|
|
|
self.layout_V_user_pass = QVBoxLayout()
|
|
self.layout_V_user_pass.addLayout(self.layout_H_username)
|
|
self.layout_V_user_pass.addLayout(self.layout_H_password)
|
|
self.layout_V_user_pass.addLayout(self.layout_H_button)
|
|
self.tab_login.setLayout(self.layout_V_user_pass)
|
|
|
|
# 注册页面
|
|
self.layout_H_username_reg = QHBoxLayout()
|
|
self.lb_username_reg = QLabel("账号设定")
|
|
self.lb_username_reg.setObjectName("lb_username_reg")
|
|
self.lb_username_reg.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
|
self.layout_H_username_reg.addWidget(self.lb_username_reg)
|
|
self.le_username_reg = QLineEdit()
|
|
self.le_username_reg.setObjectName("le_username_reg")
|
|
self.le_username_reg.setFocus()
|
|
self.layout_H_username_reg.addWidget(self.le_username_reg)
|
|
|
|
self.layout_H_password_reg = QHBoxLayout()
|
|
self.lb_password_reg = QLabel("密码设定")
|
|
self.lb_password_reg.setObjectName("lb_password_reg")
|
|
self.lb_password_reg.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
|
self.layout_H_password_reg.addWidget(self.lb_password_reg)
|
|
self.le_password_reg = QLineEdit()
|
|
self.le_password_reg.setObjectName("le_password_reg")
|
|
self.le_password_reg.setEchoMode(QLineEdit.EchoMode.Password)
|
|
self.layout_H_password_reg.addWidget(self.le_password_reg)
|
|
|
|
self.layout_H_password_reg_confirm = QHBoxLayout()
|
|
self.lb_password_reg_confirm = QLabel("密码确认")
|
|
self.lb_password_reg_confirm.setObjectName("lb_password_reg_confirm")
|
|
self.lb_password_reg_confirm.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
|
self.layout_H_password_reg_confirm.addWidget(self.lb_password_reg_confirm)
|
|
self.le_password_reg_confirm = QLineEdit()
|
|
self.le_password_reg.setObjectName("le_password_reg")
|
|
self.le_password_reg_confirm.setEchoMode(QLineEdit.EchoMode.Password)
|
|
self.layout_H_password_reg_confirm.addWidget(self.le_password_reg_confirm)
|
|
|
|
self.layout_H_button_reg = QHBoxLayout()
|
|
self.btn_login_reg = QPushButton("确认")
|
|
self.btn_login_reg.setObjectName("btn_login_reg")
|
|
self.btn_login_reg.setAutoDefault(True)
|
|
self.btn_cancel_reg = QPushButton("取消")
|
|
self.btn_cancel_reg.setObjectName("btn_cancel_reg")
|
|
self.btn_cancel_reg.setAutoDefault(True)
|
|
self.layout_H_button_reg.addWidget(self.btn_login_reg)
|
|
self.layout_H_button_reg.addWidget(self.btn_cancel_reg)
|
|
|
|
self.layout_V_user_pass_reg = QVBoxLayout()
|
|
self.layout_V_user_pass_reg.addLayout(self.layout_H_username_reg)
|
|
self.layout_V_user_pass_reg.addLayout(self.layout_H_password_reg)
|
|
self.layout_V_user_pass_reg.addLayout(self.layout_H_password_reg_confirm)
|
|
self.layout_V_user_pass_reg.addLayout(self.layout_H_button_reg)
|
|
self.tab_register.setLayout(self.layout_V_user_pass_reg)
|
|
|
|
self.setLayout(self.layout_outer)
|
|
self.le_username.setFocus()
|
|
|
|
def post_do(self):
|
|
self.setup_slot()
|
|
|
|
def setup_slot(self):
|
|
self.tabW_login.currentChanged.connect(self.onChange_tabW)
|
|
self.btn_login.clicked.connect(self.login_check)
|
|
self.btn_cancel.clicked.connect(self.close)
|
|
self.btn_login_reg.clicked.connect(self.register_check)
|
|
self.btn_cancel_reg.clicked.connect(self.close)
|
|
self.le_password.returnPressed.connect(self.login_check)
|
|
self.le_password_reg_confirm.returnPressed.connect(self.register_check)
|
|
QShortcut("Esc", self).activated.connect(self.close)
|
|
QShortcut("Alt+1", self).activated.connect(lambda: self.tabW_login.setCurrentIndex(0))
|
|
QShortcut("Alt+2", self).activated.connect(lambda: self.tabW_login.setCurrentIndex(1))
|
|
|
|
def onChange_tabW(self):
|
|
text = self.tabW_login.tabText(self.tabW_login.currentIndex())
|
|
if text == "登录":
|
|
self.le_username.clear()
|
|
self.le_password.clear()
|
|
self.le_username.setFocus()
|
|
elif text == "注册":
|
|
self.le_username_reg.clear()
|
|
self.le_password_reg.clear()
|
|
self.le_password_reg_confirm.clear()
|
|
self.le_username_reg.setFocus()
|
|
|
|
@handle_exception()
|
|
def login_check(self):
|
|
def login_failed(flag: int = 0):
|
|
reason = {-1: "用户名或密码为空", 0: "用户名未注册", 1: "解密成功,密码错误", 2: "解密失败,密码错误", 3: "数据库中有重复的用户名"}
|
|
self.le_username.clear()
|
|
self.le_password.clear()
|
|
self.le_username.setFocus()
|
|
QMessageBox.critical(self, "错误", "账号或密码错误,请重新输入!")
|
|
raise Exception(f"username:{username} login failed, reason: {reason[flag]}")
|
|
|
|
def validate_login():
|
|
nonlocal username, password
|
|
record = db_operation.db_query_users(username)
|
|
if username == "" or password == "":
|
|
login_failed(flag=-1)
|
|
|
|
if len(record) == 0:
|
|
login_failed(flag=0)
|
|
elif len(record) == 1:
|
|
keys = ["id", "timestamp", "username", "password", "salt"]
|
|
login_info = dict(zip(keys, record[0]))
|
|
salt = PassCipher.gen_salt("@".join([username, password]))
|
|
cipher = PassCipher(salt)
|
|
try:
|
|
decrypt_password = cipher.decrypt(login_info["password"])
|
|
if password != decrypt_password:
|
|
login_failed(flag=1)
|
|
else:
|
|
self.mainWindow = main_ui.MainWindow()
|
|
self.mainWindow.show()
|
|
clibs.username = username
|
|
clibs.password = password
|
|
db_operation.db_write_logs(f"username:{username} 登录成功!")
|
|
self.deleteLater()
|
|
except ValueError:
|
|
login_failed(flag=2)
|
|
else:
|
|
login_failed(flag=3)
|
|
|
|
username = self.le_username.text()
|
|
password = self.le_password.text()
|
|
validate_login()
|
|
|
|
@handle_exception()
|
|
def register_check(self):
|
|
def register_failed(flag: int = 0):
|
|
reason = {-1: "用户名或密码为空", 0: "两次密码不一致", 1: "密码长度不合规", 2: "用户名已存在", 3: "数据库中有重复的用户名"}
|
|
self.le_username_reg.clear()
|
|
self.le_password_reg.clear()
|
|
self.le_password_reg_confirm.clear()
|
|
self.le_username_reg.setFocus()
|
|
QMessageBox.critical(self, "错误", "账号错误,密码长度(>8)不合规,或两次输入密码不一致,请确认后重新输入!")
|
|
raise Exception(f"register failed, reason: {reason[flag]}")
|
|
|
|
def validate_register():
|
|
nonlocal username, password, password_confirm
|
|
record = db_operation.db_query_users(username)
|
|
if username == "" or password == "" or password_confirm == "":
|
|
register_failed(flag=-1)
|
|
|
|
if password != password_confirm:
|
|
register_failed(flag=0)
|
|
|
|
if len(password) < clibs.config["minimum_password_length"]:
|
|
register_failed(flag=1)
|
|
|
|
if len(record) == 0:
|
|
salt = PassCipher.gen_salt("@".join([username, password]))
|
|
cipher = PassCipher(salt)
|
|
password_encrypted = cipher.encrypt(password)
|
|
db_operation.db_write_users(username, password_encrypted, salt)
|
|
QMessageBox.information(self, "成功", "注册成功,切换至登录窗口进行登录!")
|
|
self.tabW_login.setCurrentIndex(self.tabW_login.indexOf(self.tab_login))
|
|
elif len(record) == 1:
|
|
register_failed(flag=2)
|
|
else:
|
|
register_failed(flag=3)
|
|
|
|
username = self.le_username_reg.text()
|
|
password = self.le_password_reg.text()
|
|
password_confirm = self.le_password_reg_confirm.text()
|
|
validate_register()
|
|
|
|
def closeEvent(self, event):
|
|
event.accept()
|
|
|
|
|
|
if __name__ == '__main__':
|
|
app = QApplication(sys.argv)
|
|
window = LoginWindow()
|
|
window.show()
|
|
sys.exit(app.exec())
|
|
|