feat: implement user type-based UI access control

Restrict settings interface and material validation features based on user type:

- SettingsTab: User type only sees "Test ERP Connection" and "Test Database Connection" buttons; Admin sees full configuration interface
- MaterialValidationTab: Hide manager filter and data source options from non-admin users; default to database_filtered mode
- test_db_connection(): Read from config directly to support User type without UI variables
- Add backward compatibility: no session_manager defaults to full interface

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Misaka_Company
2026-02-10 17:30:26 +08:00
parent db461e39f9
commit d18bedcd77
4 changed files with 219 additions and 79 deletions

View File

@@ -171,13 +171,18 @@ class MaterialValidationTab(ttk.Frame):
control_frame = ttk.Frame(main_container)
control_frame.pack(fill=tk.X, pady=(0, 10))
# 负责人筛选区域
manager_filter_frame = ttk.LabelFrame(
main_container,
text="筛选(按负责人)",
padding=10
)
manager_filter_frame.pack(fill=tk.X, pady=(0, 10))
# 负责人筛选区域 - 仅管理员可见
# PERMISSION CHECK: 非管理员用户不显示筛选区域
if self.session_manager.is_admin():
manager_filter_frame = ttk.LabelFrame(
main_container,
text="筛选(按负责人)",
padding=10
)
manager_filter_frame.pack(fill=tk.X, pady=(0, 10))
else:
# 普通用户:创建一个空容器,避免后续代码出错
manager_filter_frame = ttk.Frame(main_container)
# 中部:结果表格
result_frame = ttk.LabelFrame(main_container, text="校验结果", padding=5)
@@ -197,28 +202,33 @@ class MaterialValidationTab(ttk.Frame):
def _create_control_panel(self, parent):
"""创建控制面板"""
# 数据来源选择
source_group = ttk.LabelFrame(parent, text="数据来源", padding=10)
source_group.pack(fill=tk.X, pady=5)
# 数据来源选择 - 仅管理员可见
# PERMISSION CHECK: 非管理员用户不显示数据来源选项
if self.session_manager.is_admin():
source_group = ttk.LabelFrame(parent, text="数据来源", padding=10)
source_group.pack(fill=tk.X, pady=5)
self.source_mode = tk.StringVar(value="database_full")
self.source_mode = tk.StringVar(value="database_full")
# 数据库模式
ttk.Radiobutton(
source_group,
text="数据库 - 全表校验",
variable=self.source_mode,
value="database_full",
command=self._on_source_mode_change,
).grid(row=0, column=0, sticky="w", padx=5)
# 数据库模式
ttk.Radiobutton(
source_group,
text="数据库 - 全表校验",
variable=self.source_mode,
value="database_full",
command=self._on_source_mode_change,
).grid(row=0, column=0, sticky="w", padx=5)
ttk.Radiobutton(
source_group,
text="数据库 - ProductionID 过滤",
variable=self.source_mode,
value="database_filtered",
command=self._on_source_mode_change,
).grid(row=0, column=1, sticky="w", padx=5)
ttk.Radiobutton(
source_group,
text="数据库 - ProductionID 过滤",
variable=self.source_mode,
value="database_filtered",
command=self._on_source_mode_change,
).grid(row=0, column=1, sticky="w", padx=5)
else:
# 普通用户:默认使用 database_filtered 模式
self.source_mode = tk.StringVar(value="database_filtered")
# 文件选择
file_group = ttk.LabelFrame(parent, text="文件选择", padding=10)
@@ -243,18 +253,15 @@ class MaterialValidationTab(ttk.Frame):
)
self.db_filtered_production_id_selector.pack(fill=tk.X)
# 输出文件
output_frame = ttk.Frame(file_group)
output_frame.grid(row=1, column=0, columnspan=2, sticky="ew", pady=(10, 0))
# 输出文件(对于所有用户都可见)
self.output_file_selector = FileSelector(
output_frame,
file_group,
label_text="输出文件:",
file_type="file",
file_types=[("Excel 文件", "*.xlsx"), ("所有文件", "*.*")],
initial_dir=self.config.get("paths.data_dir", "data/"),
)
self.output_file_selector.pack(fill=tk.X)
self.output_file_selector.pack(fill=tk.X, pady=(10, 0))
# 设置默认输出
default_output = os.path.join(
@@ -370,20 +377,31 @@ class MaterialValidationTab(ttk.Frame):
def _on_source_mode_change(self):
"""数据源模式切换"""
# PERMISSION CHECK: 普通用户固定为 database_filtered 模式
if not self.session_manager.is_admin():
# 对于普通用户pack 数据库过滤模式框架
self.db_full_frame.pack_forget()
self.db_filtered_frame.pack(fill=tk.X, pady=(0, 5))
return
mode = self.source_mode.get()
# 隐藏所有文件选择框架
self.db_full_frame.grid_remove()
self.db_filtered_frame.grid_remove()
self.db_full_frame.pack_forget()
self.db_filtered_frame.pack_forget()
# 根据模式显示对应的文件选择器
if mode == "database_full":
self.db_full_frame.grid(row=0, column=0, columnspan=2, sticky="ew")
self.db_full_frame.pack(fill=tk.X, pady=(0, 5))
elif mode == "database_filtered":
self.db_filtered_frame.grid(row=0, column=0, columnspan=2, sticky="ew")
self.db_filtered_frame.pack(fill=tk.X, pady=(0, 5))
def _create_manager_filter_area(self, parent):
"""创建负责人筛选区域"""
# PERMISSION CHECK: 非管理员用户不显示筛选区域
if not self.session_manager.is_admin():
return
# 创建复选框容器
canvas_container = ttk.Frame(parent)
canvas_container.pack(fill=tk.BOTH, expand=True)