Add user login system with role-based access control: - Admin users see all data and can filter by any manager - Regular users only see records where ManagerName matches their username New components: - BIPUsersDAO: user authentication and management - SessionManager: singleton session state management - LoginDialog: modal login UI for app startup - init_users.sql: initial user setup script Permission enforcement: - Material validation tab: hide manager filter for non-admin, force filter by current user - Material type management: hide filter UI for non-admin, filter at database level - Window title and status bar display current user info Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
144 lines
5.0 KiB
Python
144 lines
5.0 KiB
Python
#!/usr/bin/env python
|
||
# -*- coding: utf-8 -*-
|
||
"""
|
||
主窗口
|
||
|
||
ERP 自动化工具的主窗口,包含多个功能标签页。
|
||
"""
|
||
|
||
import tkinter as tk
|
||
from tkinter import ttk
|
||
from gui.config_manager import ConfigManager
|
||
from gui.data_extraction_tab import DataExtractionTab
|
||
from gui.material_validation_tab import MaterialValidationTab
|
||
from gui.data_query_tab import DataQueryTab
|
||
from gui.settings_tab import SettingsTab
|
||
|
||
|
||
class MainWindow:
|
||
"""主窗口类"""
|
||
|
||
def __init__(self, root: tk.Tk, session_manager):
|
||
"""
|
||
初始化主窗口
|
||
|
||
Args:
|
||
root: Tk 根窗口
|
||
session_manager: SessionManager 实例,用于用户认证和权限管理
|
||
"""
|
||
self.root = root
|
||
self.config = ConfigManager()
|
||
self.session_manager = session_manager
|
||
|
||
# 设置窗口属性(包含用户信息)
|
||
user_type_display = "管理员" if session_manager.is_admin() else "用户"
|
||
self.root.title(f"ERP 自动化工具 v1.0 - {session_manager.get_username()} ({user_type_display})")
|
||
self.root.geometry("1000x700")
|
||
|
||
# 设置最小窗口大小
|
||
self.root.minsize(800, 600)
|
||
|
||
# 创建菜单栏
|
||
self.create_menu()
|
||
|
||
# 创建主界面
|
||
self.create_widgets()
|
||
|
||
# 创建状态栏
|
||
self.create_status_bar()
|
||
|
||
# 居中窗口
|
||
self._center_window()
|
||
|
||
def create_menu(self):
|
||
"""创建菜单栏"""
|
||
menubar = tk.Menu(self.root)
|
||
self.root.config(menu=menubar)
|
||
|
||
# 文件菜单
|
||
file_menu = tk.Menu(menubar, tearoff=0)
|
||
menubar.add_cascade(label="文件", menu=file_menu)
|
||
file_menu.add_command(label="退出", command=self.root.quit)
|
||
|
||
# 帮助菜单
|
||
help_menu = tk.Menu(menubar, tearoff=0)
|
||
menubar.add_cascade(label="帮助", menu=help_menu)
|
||
help_menu.add_command(label="关于", command=self.show_about)
|
||
|
||
def create_widgets(self):
|
||
"""创建主界面组件"""
|
||
# 创建 Notebook(标签页容器)
|
||
self.notebook = ttk.Notebook(self.root)
|
||
self.notebook.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)
|
||
|
||
# 数据提取标签页
|
||
self.extraction_tab = DataExtractionTab(self.notebook, self.config)
|
||
self.notebook.add(self.extraction_tab, text="数据提取")
|
||
|
||
# 物料校验标签页(传入 session_manager)
|
||
self.validation_tab = MaterialValidationTab(self.notebook, self.config, self.session_manager)
|
||
self.notebook.add(self.validation_tab, text="物料校验")
|
||
|
||
# 数据查询标签页
|
||
self.query_tab = DataQueryTab(self.notebook, self.config)
|
||
self.notebook.add(self.query_tab, text="数据查询")
|
||
|
||
# 设置标签页
|
||
self.settings_tab = SettingsTab(self.notebook, self.config)
|
||
self.notebook.add(self.settings_tab, text="设置")
|
||
|
||
def create_status_bar(self):
|
||
"""创建状态栏"""
|
||
self.status_bar = ttk.Frame(self.root, relief=tk.SUNKEN)
|
||
self.status_bar.pack(side=tk.BOTTOM, fill=tk.X)
|
||
|
||
# 状态文本
|
||
self.status_text = tk.StringVar()
|
||
self.status_text.set("就绪")
|
||
status_label = ttk.Label(
|
||
self.status_bar, textvariable=self.status_text, anchor=tk.W
|
||
)
|
||
status_label.pack(side=tk.LEFT, padx=5)
|
||
|
||
# 用户信息显示
|
||
user_type_display = "管理员" if self.session_manager.is_admin() else "用户"
|
||
self.user_info_var = tk.StringVar()
|
||
self.user_info_var.set(f"当前用户: {self.session_manager.get_username()} ({user_type_display})")
|
||
user_label = ttk.Label(
|
||
self.status_bar, textvariable=self.user_info_var, anchor=tk.E
|
||
)
|
||
user_label.pack(side=tk.RIGHT, padx=5)
|
||
|
||
# 配置状态指示
|
||
self.config_status = tk.StringVar()
|
||
self.config_status.set("配置已加载")
|
||
config_label = ttk.Label(
|
||
self.status_bar, textvariable=self.config_status, anchor=tk.E
|
||
)
|
||
config_label.pack(side=tk.RIGHT, padx=5)
|
||
|
||
def _center_window(self):
|
||
"""将窗口居中显示"""
|
||
self.root.update_idletasks()
|
||
width = self.root.winfo_width()
|
||
height = self.root.winfo_height()
|
||
x = (self.root.winfo_screenwidth() // 2) - (width // 2)
|
||
y = (self.root.winfo_screenheight() // 2) - (height // 2)
|
||
self.root.geometry(f"{width}x{height}+{x}+{y}")
|
||
|
||
def show_about(self):
|
||
"""显示关于对话框"""
|
||
from tkinter import messagebox
|
||
|
||
messagebox.showinfo(
|
||
"关于 ERP 自动化工具",
|
||
"ERP 自动化工具 v1.0\n\n"
|
||
"功能:\n"
|
||
"• 数据提取 - 从 ERP 系统提取备料计划数据\n"
|
||
"• 物料校验 - 校验物料状态并匹配待删除物料\n"
|
||
"• 数据查询 - 查询生产订单号等信息\n"
|
||
"• 设置管理 - 管理系统配置\n"
|
||
"• 数据库持久化 - 将提取的数据自动保存到 SQL Server\n\n"
|
||
"基于 Playwright 和 Python 开发",
|
||
)
|