更新 Simple_Enterprise_Warehouse_Management.py
This commit is contained in:
parent
36bc3c7dbd
commit
9894eef859
@ -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()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user