diff --git a/gui/material_validation_tab.py b/gui/material_validation_tab.py index b24edbb..70033e8 100644 --- a/gui/material_validation_tab.py +++ b/gui/material_validation_tab.py @@ -273,6 +273,7 @@ class MaterialValidationTab(ttk.Frame): self.validation_results = None self.material_records_cache = None # 缓存完整的物料记录 self.shared_production_ids = [] # 共享的 Production ID 列表 + self.hidden_items = set() # Track hidden item IDs for User mode # 负责人筛选相关 self.managers: List[str] = [] # 可用负责人列表 @@ -474,52 +475,161 @@ class MaterialValidationTab(ttk.Frame): def _create_result_table(self, parent): """创建结果表格""" - # 新列定义:选择、材料名称、材料代码、规格、型号、负责人 - columns = ("选择", "材料名称", "材料代码", "规格", "型号", "负责人") - self.tree = CheckboxTreeview( - parent, - columns=columns, - show="headings", - height=10, - on_checkbox_change=self._sync_checkbox_by_material_code - ) + # 检查是否为非管理员用户 + is_user_only = not self.session_manager.is_admin() - # 设置列标题和宽度 - self.tree.heading("选择", text="选择") - self.tree.heading("材料名称", text="材料名称") - self.tree.heading("材料代码", text="材料代码") - self.tree.heading("规格", text="规格") - self.tree.heading("型号", text="型号") - self.tree.heading("负责人", text="负责人(双击编辑)") + if is_user_only: + # User 模式:创建两列布局(表格 + 按钮) + # 主容器 + main_result_container = ttk.Frame(parent) + main_result_container.grid(row=0, column=0, sticky="nsew") + parent.rowconfigure(0, weight=1) + parent.columnconfigure(0, weight=1) - self.tree.column("选择", width=50, anchor="center") - self.tree.column("材料名称", width=250) - self.tree.column("材料代码", width=150) - self.tree.column("规格", width=150) - self.tree.column("型号", width=150) - self.tree.column("负责人", width=150) + # 表格容器 + table_container = ttk.Frame(main_result_container) + table_container.grid(row=0, column=0, sticky="nsew") + main_result_container.rowconfigure(0, weight=1) + main_result_container.columnconfigure(0, weight=1) - # 添加滚动条 - scrollbar_y = ttk.Scrollbar(parent, orient=tk.VERTICAL, command=self.tree.yview) - scrollbar_x = ttk.Scrollbar( - parent, orient=tk.HORIZONTAL, command=self.tree.xview - ) + # 创建表格 + columns = ("选择", "材料名称", "材料代码", "规格", "型号", "负责人") + self.tree = CheckboxTreeview( + table_container, + columns=columns, + show="headings", + height=10, + on_checkbox_change=self._sync_checkbox_by_material_code + ) - self.tree.configure( - yscrollcommand=scrollbar_y.set, xscrollcommand=scrollbar_x.set - ) + # 设置列标题和宽度 + self.tree.heading("选择", text="选择") + self.tree.heading("材料名称", text="材料名称") + self.tree.heading("材料代码", text="材料代码") + self.tree.heading("规格", text="规格") + self.tree.heading("型号", text="型号") + self.tree.heading("负责人", text="负责人(双击编辑)") - # 布局 - self.tree.grid(row=0, column=0, sticky="nsew") - scrollbar_y.grid(row=0, column=1, sticky="ns") - scrollbar_x.grid(row=1, column=0, sticky="ew") + self.tree.column("选择", width=50, anchor="center") + self.tree.column("材料名称", width=250) + self.tree.column("材料代码", width=150) + self.tree.column("规格", width=150) + self.tree.column("型号", width=150) + self.tree.column("负责人", width=150) - parent.rowconfigure(0, weight=1) - parent.columnconfigure(0, weight=1) + # 添加滚动条 + scrollbar_y = ttk.Scrollbar(table_container, orient=tk.VERTICAL, command=self.tree.yview) + scrollbar_x = ttk.Scrollbar(table_container, orient=tk.HORIZONTAL, command=self.tree.xview) + + self.tree.configure( + yscrollcommand=scrollbar_y.set, xscrollcommand=scrollbar_x.set + ) + + # 布局 + self.tree.grid(row=0, column=0, sticky="nsew") + scrollbar_y.grid(row=0, column=1, sticky="ns") + scrollbar_x.grid(row=1, column=0, sticky="ew") + + table_container.rowconfigure(0, weight=1) + table_container.columnconfigure(0, weight=1) + + # 创建筛选按钮(右侧) + self._create_user_filter_buttons(main_result_container) + else: + # Admin 模式:原布局 + columns = ("选择", "材料名称", "材料代码", "规格", "型号", "负责人") + self.tree = CheckboxTreeview( + parent, + columns=columns, + show="headings", + height=10, + on_checkbox_change=self._sync_checkbox_by_material_code + ) + + # 设置列标题和宽度 + self.tree.heading("选择", text="选择") + self.tree.heading("材料名称", text="材料名称") + self.tree.heading("材料代码", text="材料代码") + self.tree.heading("规格", text="规格") + self.tree.heading("型号", text="型号") + self.tree.heading("负责人", text="负责人(双击编辑)") + + self.tree.column("选择", width=50, anchor="center") + self.tree.column("材料名称", width=250) + self.tree.column("材料代码", width=150) + self.tree.column("规格", width=150) + self.tree.column("型号", width=150) + self.tree.column("负责人", width=150) + + # 添加滚动条 + scrollbar_y = ttk.Scrollbar(parent, orient=tk.VERTICAL, command=self.tree.yview) + scrollbar_x = ttk.Scrollbar( + parent, orient=tk.HORIZONTAL, command=self.tree.xview + ) + + self.tree.configure( + yscrollcommand=scrollbar_y.set, xscrollcommand=scrollbar_x.set + ) + + # 布局 + self.tree.grid(row=0, column=0, sticky="nsew") + scrollbar_y.grid(row=0, column=1, sticky="ns") + scrollbar_x.grid(row=1, column=0, sticky="ew") + + parent.rowconfigure(0, weight=1) + parent.columnconfigure(0, weight=1) # 绑定双击事件用于编辑负责人 self.tree.bind("", self._on_cell_double_click) + def _create_user_filter_buttons(self, parent): + """创建 User 用户的筛选按钮""" + button_frame = ttk.Frame(parent) + button_frame.grid(row=0, column=1, sticky="ns", padx=(10, 0)) + + self.btn_hide_checked = ttk.Button( + button_frame, + text="隐藏勾选", + command=self._hide_checked_items, + state=tk.DISABLED + ) + self.btn_hide_checked.pack(fill=tk.X, pady=2) + + self.btn_show_all = ttk.Button( + button_frame, + text="显示全部", + command=self._show_all_items, + state=tk.DISABLED + ) + self.btn_show_all.pack(fill=tk.X, pady=2) + + def _hide_checked_items(self): + """隐藏所有已勾选的物料""" + checked_items = self.tree.get_checked_items() + if not checked_items: + self.log_text.info("没有已勾选的物料") + return + + for item in checked_items: + self.tree.detach(item) # Remove from view but keep data + self.hidden_items.add(item) + + self.log_text.info(f"已隐藏 {len(checked_items)} 条勾选的物料") + self.btn_show_all.config(state=tk.NORMAL) + + def _show_all_items(self): + """显示所有物料(包括已隐藏的)""" + if not self.hidden_items: + self.log_text.info("没有隐藏的物料") + return + + for item in self.hidden_items: + self.tree.move(item, '', 'end') # Restore to end of tree + + count = len(self.hidden_items) + self.hidden_items.clear() + self.log_text.info(f"已显示 {count} 条隐藏的物料") + def _create_log_panel(self, parent): """创建日志面板""" self.log_text = LogText(parent, height=8, readonly=True) @@ -967,6 +1077,16 @@ class MaterialValidationTab(ttk.Frame): self.deselect_all_button.config(state=tk.DISABLED) self.log_text.clear() + # 清空隐藏的项目 + self.hidden_items.clear() + + # 禁用筛选按钮(User 模式) + if not self.session_manager.is_admin(): + if hasattr(self, 'btn_hide_checked'): + self.btn_hide_checked.config(state=tk.DISABLED) + if hasattr(self, 'btn_show_all'): + self.btn_show_all.config(state=tk.DISABLED) + # 保存当前筛选状态 self.previously_selected_managers = self._get_selected_managers() @@ -1080,6 +1200,13 @@ class MaterialValidationTab(ttk.Frame): ): self.execute_delete_button.config(state=tk.NORMAL) + # 启用筛选按钮(User 模式) + if not self.session_manager.is_admin(): + if hasattr(self, 'btn_hide_checked'): + self.btn_hide_checked.config(state=tk.NORMAL) + if hasattr(self, 'btn_show_all'): + self.btn_show_all.config(state=tk.NORMAL) + # 恢复筛选状态 if hasattr(self, 'previously_selected_managers') and self.previously_selected_managers: self._restore_manager_filter_state(self.previously_selected_managers)