Files
playwrite/gui/utils/decorators.py
Misaka Server f715cb97e3 refactor: implement UI code optimization and refactoring
This commit implements the comprehensive UI code refactoring plan to improve
code quality, reduce duplication, and enhance maintainability.

Phase 1: High Priority Improvements
- Create BaseDialog class to eliminate window centering code duplication
  across ProgressDialog, DeleteProgressWindow, LoginDialog, and
  UserSelectionDialog (~30 lines of duplicate code removed)
- Unify log color configuration with LogTheme class in gui/log_config.py
- Create permission check decorators (@require_admin, @require_permission,
  @require_user_type, @handle_errors)
- Update all dialog classes to use unified patterns

Phase 2: Architecture Improvements
- Create input validation framework (ValidationResult, Validator,
  ValidatedWidget classes)
- Implement StateManager with observer pattern for component state sharing
- Create unified ErrorHandler for consistent error handling
- Extract CheckboxTreeview into reusable component

New Modules:
- gui/widgets/base_dialog.py - Base dialog class with modal setup and centering
- gui/utils/decorators.py - Permission and error handling decorators
- gui/utils/error_handler.py - Unified error handling with user-friendly messages
- gui/utils/state_manager.py - State management with observer pattern
- gui/utils/validators.py - Input validation framework
- gui/material_validation/checkbox_treeview.py - Reusable checkbox table

Modified Files:
- gui/log_config.py - Added LogTheme class for centralized styling
- gui/widgets/log_text.py - Use LogTheme.COLORS
- gui/widgets/progress_dialog.py - Inherit from BaseDialog
- gui/widgets/delete_progress_window.py - Inherit from BaseDialog, use LogTheme
- gui/widgets/__init__.py - Add new exports, optional imports
- gui/login_dialog.py - Use unified centering pattern
- gui/user_selection_dialog.py - Use unified centering pattern
- gui/material_validation_tab.py - Import CheckboxTreeview from new module

Benefits:
- Reduced code duplication by ~200 lines
- Improved maintainability through centralized configuration
- Better abstraction with 5 new reusable base classes
- Enhanced type safety with type hints
- Future-proof theming support via LogTheme

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-26 18:40:26 +08:00

160 lines
4.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Decorators - GUI 装饰器集合
提供常用的 GUI 相关装饰器,用于权限检查、异常处理等
"""
from functools import wraps
from typing import Callable, Optional
try:
from auth.session_manager import SessionManager
except ImportError:
SessionManager = None
from tkinter import messagebox
def require_admin(func: Callable) -> Callable:
"""
装饰器:要求管理员权限
如果当前用户不是管理员,显示警告消息并阻止函数执行
Usage:
@require_admin
def _open_admin_panel(self):
# 只有管理员可以执行
pass
Args:
func: 被装饰的函数
Returns:
包装后的函数
"""
@wraps(func)
def wrapper(self, *args, **kwargs):
if SessionManager is None:
# 如果没有 SessionManager直接执行向后兼容
return func(self, *args, **kwargs)
session = SessionManager.get_instance()
if not session.is_admin():
messagebox.showwarning("权限不足", "此功能需要管理员权限")
return
return func(self, *args, **kwargs)
return wrapper
def require_permission(permission: str):
"""
装饰器:要求特定权限
如果当前用户缺少指定权限,显示警告消息并阻止函数执行
Usage:
@require_permission("delete_materials")
def _delete_materials(self):
# 只有具有 delete_materials 权限的用户可以执行
pass
Args:
permission: 所需的权限名称
Returns:
装饰器函数
"""
def decorator(func: Callable) -> Callable:
@wraps(func)
def wrapper(self, *args, **kwargs):
if SessionManager is None:
# 如果没有 SessionManager直接执行向后兼容
return func(self, *args, **kwargs)
session = SessionManager.get_instance()
if not session.has_permission(permission):
messagebox.showwarning("权限不足", f"缺少权限: {permission}")
return
return func(self, *args, **kwargs)
return wrapper
return decorator
def require_user_type(user_type: str):
"""
装饰器:要求特定用户类型
如果当前用户不是指定类型,显示警告消息并阻止函数执行
Usage:
@require_user_type("Admin")
def _admin_function(self):
# 只有 Admin 类型用户可以执行
pass
Args:
user_type: 所需的用户类型
Returns:
装饰器函数
"""
def decorator(func: Callable) -> Callable:
@wraps(func)
def wrapper(self, *args, **kwargs):
if SessionManager is None:
# 如果没有 SessionManager直接执行向后兼容
return func(self, *args, **kwargs)
session = SessionManager.get_instance()
current_user_type = session.get_current_user_type()
if current_user_type != user_type:
messagebox.showwarning(
"权限不足",
f"此功能仅限 {user_type} 用户使用"
)
return
return func(self, *args, **kwargs)
return wrapper
return decorator
def handle_errors(
show_user: bool = True,
default_return=None,
log_context: str = ""
):
"""
装饰器:统一错误处理
捕获函数中的异常并使用 ErrorHandler 进行处理
Usage:
@handle_errors(show_user=True, log_context="Deleting materials")
def _delete_materials(self):
# 可能抛出异常的操作
pass
Args:
show_user: 是否向用户显示错误消息
default_return: 发生异常时的默认返回值
log_context: 日志上下文信息
Returns:
装饰器函数
"""
def decorator(func: Callable) -> Callable:
@wraps(func)
def wrapper(self, *args, **kwargs):
try:
return func(self, *args, **kwargs)
except Exception as e:
from gui.utils.error_handler import ErrorHandler
context = log_context or f"{func.__name__}"
ErrorHandler.handle(e, context, show_user)
return default_return
return wrapper
return decorator