更新 Simple_Enterprise_Warehouse_Management.py
This commit is contained in:
		@@ -9,7 +9,7 @@ class InventoryUI:
 | 
				
			|||||||
        self.root = tk.Tk()
 | 
					        self.root = tk.Tk()
 | 
				
			||||||
        self.root.title("出入库管理系统")
 | 
					        self.root.title("出入库管理系统")
 | 
				
			||||||
        self.root.geometry("800x600")
 | 
					        self.root.geometry("800x600")
 | 
				
			||||||
        self.root.resizable(False, False)
 | 
					        self.root.resizable(True, True)
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        # 初始化库存管理器
 | 
					        # 初始化库存管理器
 | 
				
			||||||
        self.manager = InventoryManager("inventory_data.json")
 | 
					        self.manager = InventoryManager("inventory_data.json")
 | 
				
			||||||
@@ -51,6 +51,15 @@ class InventoryUI:
 | 
				
			|||||||
        # 绑定双击事件
 | 
					        # 绑定双击事件
 | 
				
			||||||
        self.product_tree.bind("<Double-1>", self.on_product_select)
 | 
					        self.product_tree.bind("<Double-1>", self.on_product_select)
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
 | 
					        # 绑定拖拽事件(使用右键拖拽避免与双击冲突)
 | 
				
			||||||
 | 
					        self.product_tree.bind("<Button-3>", self.on_drag_start)
 | 
				
			||||||
 | 
					        self.product_tree.bind("<B3-Motion>", self.on_drag_motion)
 | 
				
			||||||
 | 
					        self.product_tree.bind("<ButtonRelease-3>", self.on_drag_end)
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # 拖拽相关变量
 | 
				
			||||||
 | 
					        self.drag_item = None
 | 
				
			||||||
 | 
					        self.drag_start_y = 0
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
        # 底部统计信息
 | 
					        # 底部统计信息
 | 
				
			||||||
        stats_frame = tk.Frame(self.root)
 | 
					        stats_frame = tk.Frame(self.root)
 | 
				
			||||||
        stats_frame.pack(fill=tk.X, padx=10, pady=5)
 | 
					        stats_frame.pack(fill=tk.X, padx=10, pady=5)
 | 
				
			||||||
@@ -276,39 +285,7 @@ class InventoryUI:
 | 
				
			|||||||
        for widget in self.root.winfo_children():
 | 
					        for widget in self.root.winfo_children():
 | 
				
			||||||
            widget.destroy()
 | 
					            widget.destroy()
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    def load_products(self):
 | 
					 | 
				
			||||||
        """加载产品列表"""
 | 
					 | 
				
			||||||
        try:
 | 
					 | 
				
			||||||
            with open("inventory_data.json", "r", encoding="utf-8") as f:
 | 
					 | 
				
			||||||
                data = json.load(f)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # 清空现有数据
 | 
					 | 
				
			||||||
            for item in self.product_tree.get_children():
 | 
					 | 
				
			||||||
                self.product_tree.delete(item)
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            total_value = 0
 | 
					 | 
				
			||||||
            total_weight = 0
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            for product_name, product_data in data["products"].items():
 | 
					 | 
				
			||||||
                weight = float(product_data["total_weight"])
 | 
					 | 
				
			||||||
                price = float(product_data["avg_price"])
 | 
					 | 
				
			||||||
                value = weight * price
 | 
					 | 
				
			||||||
                
 | 
					 | 
				
			||||||
                total_weight += weight
 | 
					 | 
				
			||||||
                total_value += value
 | 
					 | 
				
			||||||
                
 | 
					 | 
				
			||||||
                self.product_tree.insert("", tk.END, values=(
 | 
					 | 
				
			||||||
                    product_name,
 | 
					 | 
				
			||||||
                    f"{weight:.2f}",
 | 
					 | 
				
			||||||
                    f"{price:.2f}",
 | 
					 | 
				
			||||||
                    "详情"
 | 
					 | 
				
			||||||
                ))
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            # 更新统计信息
 | 
					 | 
				
			||||||
            self.stats_label.config(text=f"库存总价值: {total_value:.2f} 元    库存总重: {total_weight:.2f} kg")
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
        except Exception as e:
 | 
					 | 
				
			||||||
            messagebox.showerror("错误", f"加载产品数据失败: {str(e)}")
 | 
					 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    def load_transactions(self, product_name):
 | 
					    def load_transactions(self, product_name):
 | 
				
			||||||
        """加载指定产品的交易记录"""
 | 
					        """加载指定产品的交易记录"""
 | 
				
			||||||
@@ -1164,6 +1141,155 @@ class InventoryUI:
 | 
				
			|||||||
        except Exception as e:
 | 
					        except Exception as e:
 | 
				
			||||||
            messagebox.showerror("错误", f"生成HTML报表失败: {str(e)}")
 | 
					            messagebox.showerror("错误", f"生成HTML报表失败: {str(e)}")
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
 | 
					    def on_drag_start(self, event):
 | 
				
			||||||
 | 
					        """开始拖拽(右键)"""
 | 
				
			||||||
 | 
					        # 获取点击的项目
 | 
				
			||||||
 | 
					        item = self.product_tree.identify_row(event.y)
 | 
				
			||||||
 | 
					        if item:
 | 
				
			||||||
 | 
					            self.drag_item = item
 | 
				
			||||||
 | 
					            self.drag_start_y = event.y
 | 
				
			||||||
 | 
					            # 高亮显示被拖拽的项目
 | 
				
			||||||
 | 
					            self.product_tree.selection_set(item)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    def on_drag_motion(self, event):
 | 
				
			||||||
 | 
					        """拖拽移动"""
 | 
				
			||||||
 | 
					        if self.drag_item:
 | 
				
			||||||
 | 
					            # 获取当前鼠标位置的项目
 | 
				
			||||||
 | 
					            target_item = self.product_tree.identify_row(event.y)
 | 
				
			||||||
 | 
					            if target_item and target_item != self.drag_item:
 | 
				
			||||||
 | 
					                # 高亮显示目标位置
 | 
				
			||||||
 | 
					                self.product_tree.selection_set(target_item)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    def on_drag_end(self, event):
 | 
				
			||||||
 | 
					        """结束拖拽"""
 | 
				
			||||||
 | 
					        if self.drag_item:
 | 
				
			||||||
 | 
					            # 获取目标位置
 | 
				
			||||||
 | 
					            target_item = self.product_tree.identify_row(event.y)
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            if target_item and target_item != self.drag_item:
 | 
				
			||||||
 | 
					                # 获取产品名称用于确认
 | 
				
			||||||
 | 
					                source_values = self.product_tree.item(self.drag_item)["values"]
 | 
				
			||||||
 | 
					                target_values = self.product_tree.item(target_item)["values"]
 | 
				
			||||||
 | 
					                source_name = source_values[0]
 | 
				
			||||||
 | 
					                target_name = target_values[0]
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                # 确认移动操作
 | 
				
			||||||
 | 
					                if messagebox.askyesno("确认移动", f"是否将 '{source_name}' 移动到 '{target_name}' 的位置?"):
 | 
				
			||||||
 | 
					                    # 执行移动操作
 | 
				
			||||||
 | 
					                    self.move_product_item(self.drag_item, target_item)
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            # 重置拖拽状态
 | 
				
			||||||
 | 
					            self.drag_item = None
 | 
				
			||||||
 | 
					            self.drag_start_y = 0
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    def move_product_item(self, source_item, target_item):
 | 
				
			||||||
 | 
					        """移动产品项目"""
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            # 获取源项目和目标项目的信息
 | 
				
			||||||
 | 
					            source_values = self.product_tree.item(source_item)["values"]
 | 
				
			||||||
 | 
					            target_values = self.product_tree.item(target_item)["values"]
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            source_product = source_values[0]
 | 
				
			||||||
 | 
					            target_product = target_values[0]
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            # 获取所有项目的顺序
 | 
				
			||||||
 | 
					            all_items = []
 | 
				
			||||||
 | 
					            for item in self.product_tree.get_children():
 | 
				
			||||||
 | 
					                values = self.product_tree.item(item)["values"]
 | 
				
			||||||
 | 
					                all_items.append(values[0])  # 产品名
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            # 计算新的顺序
 | 
				
			||||||
 | 
					            source_index = all_items.index(source_product)
 | 
				
			||||||
 | 
					            target_index = all_items.index(target_product)
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            # 修复移动逻辑:先移除源项目,然后根据调整后的索引插入
 | 
				
			||||||
 | 
					            all_items.pop(source_index)
 | 
				
			||||||
 | 
					            # 如果目标位置在源位置之后,需要调整目标索引
 | 
				
			||||||
 | 
					            if target_index > source_index:
 | 
				
			||||||
 | 
					                target_index -= 1
 | 
				
			||||||
 | 
					            all_items.insert(target_index, source_product)
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            # 更新JSON文件中的产品顺序
 | 
				
			||||||
 | 
					            self.save_product_order(all_items)
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            # 重新加载产品列表并刷新界面
 | 
				
			||||||
 | 
					            self.load_products()
 | 
				
			||||||
 | 
					            self.product_tree.update()
 | 
				
			||||||
 | 
					            self.root.update_idletasks()
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            messagebox.showinfo("成功", f"已将 '{source_product}' 移动到 '{target_product}' 的位置")
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					        except Exception as e:
 | 
				
			||||||
 | 
					            messagebox.showerror("错误", f"移动产品失败: {str(e)}")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    def save_product_order(self, product_order):
 | 
				
			||||||
 | 
					        """保存产品顺序到JSON文件"""
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            with open("inventory_data.json", "r", encoding="utf-8") as f:
 | 
				
			||||||
 | 
					                data = json.load(f)
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            # 创建新的有序产品字典
 | 
				
			||||||
 | 
					            old_products = data["products"]
 | 
				
			||||||
 | 
					            new_products = {}
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            # 统一将产品顺序转换为字符串类型
 | 
				
			||||||
 | 
					            product_order = [str(item) for item in product_order]
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            # 第一步:按顺序添加存在的老产品
 | 
				
			||||||
 | 
					            for product_name in product_order:
 | 
				
			||||||
 | 
					                if product_name in old_products:
 | 
				
			||||||
 | 
					                    new_products[product_name] = old_products[product_name]
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            # 第二步:添加顺序列表中没有但存在于老产品中的项目
 | 
				
			||||||
 | 
					            for product_name in old_products:
 | 
				
			||||||
 | 
					                if product_name not in new_products:
 | 
				
			||||||
 | 
					                    new_products[product_name] = old_products[product_name]
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            # 更新数据
 | 
				
			||||||
 | 
					            data["products"] = new_products
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            # 保存文件,确保字典顺序被保持
 | 
				
			||||||
 | 
					            with open("inventory_data.json", "w", encoding="utf-8") as f:
 | 
				
			||||||
 | 
					                json.dump(data, f, indent=2, ensure_ascii=False)
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					        except Exception as e:
 | 
				
			||||||
 | 
					            raise Exception(f"保存产品顺序失败: {str(e)}")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    def load_products(self):
 | 
				
			||||||
 | 
					        """加载产品列表(保持JSON中的顺序)"""
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            with open("inventory_data.json", "r", encoding="utf-8") as f:
 | 
				
			||||||
 | 
					                data = json.load(f)
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            # 清空现有数据
 | 
				
			||||||
 | 
					            for item in self.product_tree.get_children():
 | 
				
			||||||
 | 
					                self.product_tree.delete(item)
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            total_value = 0
 | 
				
			||||||
 | 
					            total_weight = 0
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            # 按照JSON中的顺序加载产品
 | 
				
			||||||
 | 
					            for product_name, product_data in data["products"].items():
 | 
				
			||||||
 | 
					                weight = float(product_data["total_weight"])
 | 
				
			||||||
 | 
					                price = float(product_data["avg_price"])
 | 
				
			||||||
 | 
					                value = weight * price
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                total_weight += weight
 | 
				
			||||||
 | 
					                total_value += value
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                self.product_tree.insert("", tk.END, values=(
 | 
				
			||||||
 | 
					                    product_name,
 | 
				
			||||||
 | 
					                    f"{weight:.2f}",
 | 
				
			||||||
 | 
					                    f"{price:.2f}",
 | 
				
			||||||
 | 
					                    "详情"
 | 
				
			||||||
 | 
					                ))
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            # 更新统计信息
 | 
				
			||||||
 | 
					            self.stats_label.config(text=f"库存总价值: {total_value:.2f} 元    库存总重: {total_weight:.2f} kg")
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					        except Exception as e:
 | 
				
			||||||
 | 
					            messagebox.showerror("错误", f"加载产品数据失败: {str(e)}")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    def run(self):
 | 
					    def run(self):
 | 
				
			||||||
        """运行应用"""
 | 
					        """运行应用"""
 | 
				
			||||||
        self.root.mainloop()
 | 
					        self.root.mainloop()
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user