更新 Simple_Enterprise_Warehouse_Management.py

This commit is contained in:
spdis 2025-07-27 13:40:09 +08:00
parent 36bc3c7dbd
commit 9894eef859

View File

@ -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()