diff --git a/auth/session_manager.py b/auth/session_manager.py index c7275de..e4ad86c 100644 --- a/auth/session_manager.py +++ b/auth/session_manager.py @@ -63,6 +63,28 @@ class SessionManager: return True return False + def login_by_computer_name(self) -> bool: + """ + Attempt silent login using computer name + + Returns: + True if login successful, False otherwise + """ + import socket + from db.bip_users_dao import BIPUsersDAO + + computer_name = socket.gethostname() + dao = BIPUsersDAO() + user_info = dao.authenticate_by_computer_name(computer_name) + + if user_info: + self._current_user = { + 'username': user_info['username'], + 'user_type': user_info['user_type'] + } + return True + return False + def logout(self): """Logout the current user and clear session""" self._current_user = None diff --git a/db/bip_users_dao.py b/db/bip_users_dao.py index 02965d7..4cb489c 100644 --- a/db/bip_users_dao.py +++ b/db/bip_users_dao.py @@ -49,6 +49,44 @@ class BIPUsersDAO(BaseDAO): } return None + def authenticate_by_computer_name(self, computer_name: str) -> Optional[Dict[str, Any]]: + """ + Authenticate a user using computer name (silent login) + + Args: + computer_name: The computer name to authenticate + + Returns: + Dict with user info if authentication successful, None otherwise + Returns: {id, username, user_type} + """ + table_name = self._convert_sql('[dbo].[BIPUsers]') + placeholder = self._get_placeholder() + + # Note: Column name is 'ComputerNmae' (typo in database schema) + if self._db_type == DatabaseType.MYSQL: + sql = f""" + SELECT ID, UserName, UserType + FROM {table_name} + WHERE ComputerNmae = {placeholder} + """ + else: + sql = f""" + SELECT [ID], [UserName], [UserType] + FROM {table_name} + WHERE [ComputerNmae] = {placeholder} + """ + + with get_connection() as db: + results = db.execute_query(sql, (computer_name,)) + if results: + return { + 'id': results[0]['ID'], + 'username': results[0]['UserName'], + 'user_type': results[0]['UserType'] + } + return None + def get_all_users(self) -> List[Dict[str, Any]]: """ Get all users from the database @@ -84,14 +122,15 @@ class BIPUsersDAO(BaseDAO): for row in results ] - def create_user(self, username: str, password: str, user_type: str) -> bool: + def create_user(self, username: str, password: str, user_type: str, computer_name: str = '') -> bool: """ - Create a new user + Create a new user with optional computer name for silent login Args: username: The username (must be unique) password: The password (plain text for internal tool) user_type: User type ('Admin', 'User', or 'Guest') + computer_name: Optional computer name for silent login (default: '') Returns: True if successful, False otherwise @@ -101,19 +140,35 @@ class BIPUsersDAO(BaseDAO): # 根据数据库类型选择列名格式 if self._db_type == DatabaseType.MYSQL: - sql = f""" - INSERT INTO {table_name} (UserName, Password, UserType) - VALUES ({placeholder}, {placeholder}, {placeholder}) - """ + if computer_name: + sql = f""" + INSERT INTO {table_name} (UserName, Password, UserType, ComputerNmae) + VALUES ({placeholder}, {placeholder}, {placeholder}, {placeholder}) + """ + params = (username, password, user_type, computer_name) + else: + sql = f""" + INSERT INTO {table_name} (UserName, Password, UserType) + VALUES ({placeholder}, {placeholder}, {placeholder}) + """ + params = (username, password, user_type) else: - sql = f""" - INSERT INTO {table_name} ([UserName], [Password], [UserType]) - VALUES ({placeholder}, {placeholder}, {placeholder}) - """ + if computer_name: + sql = f""" + INSERT INTO {table_name} ([UserName], [Password], [UserType], [ComputerNmae]) + VALUES ({placeholder}, {placeholder}, {placeholder}, {placeholder}) + """ + params = (username, password, user_type, computer_name) + else: + sql = f""" + INSERT INTO {table_name} ([UserName], [Password], [UserType]) + VALUES ({placeholder}, {placeholder}, {placeholder}) + """ + params = (username, password, user_type) try: with get_connection() as db: - db.execute_update(sql, (username, password, user_type)) + db.execute_update(sql, params) return True except Exception as e: print(f"Error creating user: {e}") diff --git a/gui/login_dialog.py b/gui/login_dialog.py index a90ad8e..ffefa76 100644 --- a/gui/login_dialog.py +++ b/gui/login_dialog.py @@ -1,6 +1,7 @@ """ Login Dialog - Modal dialog for user authentication """ +import socket import tkinter as tk from tkinter import ttk, messagebox from typing import Optional, Tuple @@ -37,7 +38,7 @@ class LoginDialog: """Create the login dialog UI""" self.dialog = tk.Toplevel(self.parent) self.dialog.title("ERP 自动化工具 - 登录") - self.dialog.geometry("400x250") + self.dialog.geometry("400x280") self.dialog.resizable(False, False) # Center the dialog on parent @@ -52,7 +53,7 @@ class LoginDialog: parent_height = self.parent.winfo_height() dialog_width = 400 - dialog_height = 250 + dialog_height = 280 x = parent_x + (parent_width - dialog_width) // 2 y = parent_y + (parent_height - dialog_height) // 2 self.dialog.geometry(f"{dialog_width}x{dialog_height}+{x}+{y}") @@ -78,7 +79,16 @@ class LoginDialog: text="请登录", font=('', 16, 'bold') ) - title_label.pack(pady=(0, 20)) + title_label.pack(pady=(0, 10)) + + # Computer name display + computer_name_label = ttk.Label( + main_frame, + text=f"当前计算机: {socket.gethostname()}", + font=('', 9), + foreground='gray' + ) + computer_name_label.pack(pady=(0, 15)) # Username field username_frame = ttk.Frame(main_frame)