tkinter的应用--mini级《仓库管理系统》
一、tkinter UI界面;二、mysql、python;
三、python
四、功能:
(1)采购管理:订货、收货、退货;
(2)零售管理:零售结算;
(3)仓库管理:库存查询;
(4)结算管理:零售流水、购货账单查询;
(5)管理员:操作员、管理员账号管理;
五、数据库:
table:
用户: user: {user_name,id, password, reg_time}
采购--进货: purchase: {id,name, price,num, statu(定、收、退), shop,phone ,user_id}
库存: stock: {id, sum,price, name, }
流水账--卖出: runuing: {id, stock_id, num, acount, time,user_id}
六、运行截图:
https://attach.52pojie.cn//forum/202002/12/232301fv3339sokz1dusvz.png?l
https://attach.52pojie.cn//forum/202002/12/232304n9ifxn4ret344o4b.png?l
https://attach.52pojie.cn//forum/202002/12/232306eqr6kgaddkpwxdwq.png?l
https://attach.52pojie.cn//forum/202002/12/232309xlsl8zisly95l0l0.png?l
七、源码:
(1)gui.py
"""
程序入口 :界面调用其他模块
(1)option.config : 配置文件
·init: False(默认), 未初始化数据库;true,数据库已经建立。程序自己完成。
·host:主机;
·user:数据库用户
·password:数据库密码
·database: 用户数据库( warehouse )
(2)settings.py: 基础设置。
(3)mysql_connnect.py: 实现对数据库的各种操作
(4)gui.py:程序UI设计, 程序入口
"""
import tkinteras tk
import tkinter.messagebox
from tkinter import Menu
from tkinter import ttk
importtime
importsettings
import mysql_connectassql
importre
# 登录类
class sign_frame( tk.Frame ):
def __init__(self, **kwargs ):
super().__init__( **kwargs)
tk.Label( self, text="登录", width=10,height=2, font=("黑体",15),bg="cyan" ).place(x=250,y=10)
self.place(x=160, y=40)
tk.Label( self, text="账号: ", width= 14, height=2,font=("楷体", 12),bg="palegreen",anchor="w")\
.place(x =150, y=100 )
self.user_id = tk.Entry(self, width=20)
self.user_id.place(x= 300, y=110)
tk.Label( self, text="密码: ", width= 14, height=2,font=("楷体", 12),bg="palegreen",anchor="w" )\
.place(x =150, y=150 )
self.user_pw = tk.Entry(self, width=20)
self.user_pw.place(x= 300, y=160)
tk.Label( self, text="重新输入密码: ", width= 14, height=2,font=("楷体", 12),bg="palegreen",anchor="w" )\
.place(x =150, y=200 )
self.user_pw2 = tk.Entry(self, width=20)
self.user_pw2.place(x= 300, y=210)
tk.Button( self, text="登录", width=10,height=1, command=self.check).place(x=150, y=270 )
tk.Button( self, text="退出", width=10,height=1, command=self.quit_user).place(x=365, y=270 )
def check(self):
user_id = self.user_id.get()
user_pw = self.user_pw.get()
user_pw2 = self.user_pw2.get()
# Todo 测试结束后删除
#user_id ="root"
#user_pw = user_pw2 = "root"
if(user_pw != user_pw2):
tk.messagebox.showwarning(title='提示', message='密码不一致!')
else:
#done 登录验证
ans = sql.check_sign(user_id,user_pw)
if ans :
tk.messagebox.showinfo( title="提示",message="登陆成功!")
settings.user["name"] = ans
settings.user["id"] = user_id
else:
tk.messagebox.showwarning(title='提示', message='密码错误!')
tk.Label( master=root ,text="昵称:{}\t\t账号:{}".format( settings.user["name"], settings.user["id"] ))\
.place(x=50, y=10)
def quit_user(self):
settings.user["name"] = ""
settings.user["id"] = ""
tk.Label( master=root ,text="昵称:{}\t\t账号:{}".format( settings.user["name"], settings.user["id"] ),
width=200,anchor="w")\
.place(x=50, y=10)
# 购货管理
classpurchase_frame(tk.Frame ):
def __init__(self, **kwargs):
super().__init__( **kwargs)
tk.Label( self, text="购货管理", width=10,height=2, font=("黑体",15),bg="cyan" ).place(x=250,y=10)
self.place(x=160, y=40)
# 实现订货
tk.Label( self, text="订货", width=10,height=2, font=("黑体",13),bg="palegreen" ).place(x=100,y=70)
tk.Label( self, text="商品名:", width=10,height=2, font=("楷体",12),bg="palegreen",anchor="w" ).place(x=10,y=90)
self.name = tk.Entry(self, width=18 )
self.name.place(x=100,y=100 )
tk.Label( self, text="数量 :", width=10,height=2, font=("楷体",12),bg="palegreen",anchor="w" ).place(x=10,y=120)
self.num = tk.Entry( self, width=18)
self.num.place(x=100, y=130)
tk.Label( self, text="单价:", width=10,height=2, font=("楷体",12),bg="palegreen",anchor="w" ).place(x=10,y=150)
self.price = tk.Entry( self, width=18)
self.price.place(x=100, y=160)
tk.Label( self, text="供货商:", width=10,height=2, font=("楷体",12),bg="palegreen",anchor="w" ).place(x=10,y=180)
self.shop = tk.Entry( self, width=18)
self.shop.place(x=100, y=190)
tk.Label( self, text="联系方式:", width=10,height=2, font=("楷体",12),bg="palegreen",anchor="w" ).place(x=10,y=210)
self.phone = tk.Entry( self, width=18)
self.phone.place(x=100, y=220)
tk.Button(self, text="确认订货", width=10,height=1, command=self.order_goods).place(x=10, y=270 )
tk.Button(self, text="重置", width=10,height=1, command=self.set_entry).place(x=150, y=270 )
# 实现收货和退货
tk.Label( self, text="订货清单", width=10,height=2, font=("黑体",13),bg="palegreen" ).place(x=300,y=70)
self.info_list = tk.Listbox(self, width=40, height=13, font=("宋体",12))
self.info_list.place(x=250,y=100)
self.add_inof_list()
menu = Menu(root, tearoff=0)
menu.add_command(label="收货", command=self.get_goods)
menu.add_command(label="查看信息", command= self.show_info_selected)
#menu.add_separator()
menu.add_command(label="退货", command= self.return_goods)
self.menu = menu
# 鼠标右键弹出菜单
self.info_list.bind("<Button-3>", self.popupmenu)
# 收货
def get_goods(self):
loc =self.info_list.curselection()
data=str( self.info_list.get(loc) ).split(" ")
title = ['订单编号:','商品名:','供货商:','联系方式:']
format_data = ""
for index in range( len( title) ):
format_data += str( title)+ str( data)+"\n"
iftk.messagebox.askyesno( title="确认收货", message=format_data):
self.info_list.delete(loc)
# done 数据库修改
sql.change_goods_state_receving(data, data)
# 退货处理
def return_goods(self):
loc =self.info_list.curselection()
data=str( self.info_list.get(loc) ).split(" ")
title = ['订单编号:','商品名:','供货商:','联系方式:']
format_data = ""
for index in range( len( title) ):
format_data += str( title)+ str( data)+"\n"
iftk.messagebox.askyesno( title="确认退货", message=format_data):
self.info_list.delete(loc)
# done 数据库修改
sql.change_goods_state_back(data)
# 订货清单打开菜单
def popupmenu(self,event):
iflen ( self.info_list.curselection()) :
self.menu.post(event.x_root, event.y_root)
# 添加订货清单信息
def add_inof_list(self):
# done 获取数据库信息
data = sql.get_goods_info_order()
for item in data:
self.info_list.insert('end', item )
# 订货
def order_goods(self):
id = self.get_id()
name = self.name.get()
num= self.num.get()
price ="%5.2f" % float( self.price.get())
state = "订货"
shop = self.shop.get()
phone = self.phone.get()
user_id = settings.user["id"]
show_data = "{} {} {} {}".format(id,name,shop, phone)
self.info_list.insert('end', show_data)
# done 写入数据库
sql.order_goods(id=id, name=name, num=num, price=price,shop=shop,phone=phone, user_id=user_id)
# 计算订单编号
def get_id(self):
id_time = time.strftime('%Y-%m-%d',time.localtime(time.time()))
# DOne 读取数据库今日订单数量
id_num = int(sql.get_purchase_day_sum( id_time ))
returnstr(id_time)+( "_{:0>4d}".format(id_num) )
# 清空订货信息(订货)
def set_entry(self):
self.name.delete(0,'end')
self.num.delete(0,'end')
self.price.delete(0,'end')
self.shop.delete(0,'end')
self.phone.delete(0,'end')
# 显示订单详情( 状态 = ‘订货’)
def show_info_selected(self):
data = self.info_list.get(self.info_list.curselection())
id= data.split(" ")
#done 查询订单的详细信息
data = sql.get_goods_detailed_info( id )
format_data = ""
for item in data:
format_data += str(item)+"\n"
tk.messagebox.showinfo( title="提示",message=format_data)
# 零售管理
classrunning_frame(tk.Frame ):
def __init__(self, **kwargs):
super().__init__( **kwargs)
tk.Label( self, text="零售管理", width=10,height=2, font=("黑体",15),bg="cyan" ).place(x=250,y=10)
self.place(x=160, y=40)
# 添加商品
tk.Label( self, text="商品名-编号", width=20,height=2, font=("楷体",12),bg="palegreen",anchor="w").place(x=20,y=70)
tk.Label( self, text="单价", width=10,height=2, font=("楷体",12),bg="palegreen",anchor="w" ).place(x=250,y=70)
tk.Label( self, text="数量", width=10,height=2, font=("楷体",12),bg="palegreen",anchor="w" ).place(x=350,y=70)
tk.Label( self, text="合计", width=10,height=2, font=("楷体",12),bg="palegreen",anchor="w" ).place(x=450,y=70)
self.name_id = ttk.Combobox(self,width=28)
self.name_id.bind("<<ComboboxSelected>>",self.update_goods_info)
self.name_id.place(x=20, y=100)
self.set_value()
self.price = tk.Spinbox(self,width=7, from_=0,to=100000,increment=1,command=self.change_num)
self.price.place( x=250, y=100)
self.num = tk.Spinbox(self,width=7, from_=0,to=100000,increment=1)
self.num.place( x=350, y=100)
self.account= tk.Label(self, text="-----", width=10,height=1, font=("楷体",12),bg="palegreen",anchor="w" )
self.account.place(x=450,y=100)
tk.Button(self, text="单品合计", width=10,height=1, command=self.add_goods).place(x=510,y=90)
# 商品展示
self.goods_info = tk.Listbox(self, width=71,height=9, font=("宋体", 12))
self.goods_info.place(x=20,y=140)
# 商品清除
menu = Menu(root, tearoff=0)
menu.add_command(label="删除", command=self.del_goods)
self.menu = menu
# 鼠标右键弹出菜单
self.goods_info.bind("<Button-3>", self.popupmenu)
#总额计算
tk.Button( self,text="计算总和", width=10,height=1, command= self.all_account ).place(x=20, y=310)
tk.Button( self,text="清空商品", width=10,height=1, command= self.del_goods_info ).place(x=510, y=310)
self.money= tk.Label(self, text="-----", width=10,height=1, font=("楷体",12),bg="palegreen",anchor="w" )
self.money.place( x=200, y=310)
# 设置商品信息
def set_value(self):
#done 获取库存商品name id
data = sql.get_stock_goods_name_id()
self.name_id['value'] = data
#选择商品后修改对应数据
def update_goods_info(self,event):
name_id=str ( self.name_id.get() ).split("")
id = name_id
# done 读取商品的库存价格
price = sql.get_stock_goods_price(id)
self.price.delete(0,'end')
self.price.insert(0, price)
# 修改价格整数为小数
defchange_num(self):
data =self.price.get()
self.price.insert('end',".00")
# 计算商品价格 加入购物车
def add_goods(self):
name_id = self.name_id.get()
price = self.price.get()
num =self.num.get()
account = eval(price) * eval(num)
self.account['text'] = format(account, '>5.2f')
data = "{}{}/元{}/个{}元".format(name_id, str(price),str(num),format(account, '>5.2f'))
self.goods_info.insert(0, data)
# 商品清单打开菜单
def popupmenu(self,event):
iflen ( self.goods_info.curselection()) :
self.menu.post(event.x_root, event.y_root)
# 删除商品--商品栏中清除
def del_goods(self):
loc =self.goods_info.curselection()
data=str( self.goods_info.get(loc) ).replace("","\n")
iftk.messagebox.askyesno( title="确认删除", message=data):
self.goods_info.delete(loc)
# 计算商品总和
def all_account(self):
data = self.goods_info.get(0,'end')
money = float(0)
for item indata:
money += float ( str(item).split(" ")[-1][:-1] )
self.money['text'] = format( money, '<8.2f' )
# DOne 流水账 输入数据库
sql.write_running(settings.user["id"] , data )
# 清空商品
def del_goods_info(self):
iftk.messagebox.askyesno( title="确认删除", message="清空商品栏?"):
self.goods_info.delete(0,'end')
self.money['text'] = "-----"
# 仓库管理
classwarehouse_frame(tk.Frame ):
def __init__(self, **kwargs):
super().__init__( **kwargs)
tk.Label( self, text="仓库管理", width=10,height=2, font=("黑体",15),bg="cyan" ).place(x=250,y=10)
self.place(x=160, y=40)
# 查看存货
tk.Label( self, text="商品名", width=20,height=2, font=("楷体",12),bg="palegreen",anchor="w").place(x=20,y=70)
self.name = ttk.Combobox( self, width=20 )
self.name.place( x=20,y=100 )
self.set_name()
tk.Label( self, text="数量", width=10,height=2, font=("楷体",12),bg="palegreen",anchor="w" ).place(x=250,y=70)
self.num_type = ttk.Combobox( self, width=1 )
self.num_type['value'] = ['>','=',"<"]
self.num_type.current(0)
self.num_type.place( x=250,y=100 )
self.num_value = tk.Spinbox(self,width=4, from_=0,to=9999999,increment=1)
self.num_value.place( x=280,y=100 )
tk.Label( self, text="价格", width=10,height=2, font=("楷体",12),bg="palegreen",anchor="w" ).place(x=350,y=70)
self.price_type = ttk.Combobox( self, width=1 )
self.price_type['value'] = ['>','=',"<"]
self.price_type.current(0)
self.price_type.place( x=350,y=100 )
self.price_value = tk.Spinbox(self,width=4, from_=0,to=9999999,increment=1,command= self.set_price_value)
self.price_value.place( x=380,y=100 )
tk.Button(self, text="条件查询", font=("楷体",12), command= self.find_stock).place(x=430,y=95)
tk.Button(self, text="查询全部", bg="gold",font=("楷体",12), command=self.find_all_stock).place(x=510,y=95)
# 库存显示
self.stock_info =tk.Listbox(self,width=80, height=10)
self.stock_info.place( x=20, y=150)
# 读取库存商品名
def set_name(self):
#done 读取数据库库存商品名
data = sql.get_stock_goods_name_id()
self.name['value'] = data
# 按条件查询库存
deffind_stock(self):
name = str ( self.name.get()).split(" ")
num =self.num_type.get() + self.num_value.get()
price =self.price_type.get() + self.price_value.get()
# done 按条件查询库存
data = sql.get_stock_goods_price_and_num( name, num, price )
self.stock_info.delete(0,'end')
foritem in data:
self.stock_info.insert('end',item )
# 查询所有库存
def find_all_stock(self):
# done查询全部库存
data = sql.get_all_stock_info()
self.stock_info.delete(0,'end')
foritem in data:
self.stock_info.insert('end',item )
# 格式化价格设置
defset_price_value(self):
self.price_value.insert('end','.00')
# 结算管理
classacount_frame(tk.Frame ):
def __init__(self, **kwargs):
super().__init__( **kwargs)
tk.Label( self, text="结算管理", width=10,height=2, font=("黑体",15),bg="cyan" ).place(x=250,y=10)
self.place(x=160, y=40)
# 查询条件
tk.Label( self, text="查询类型:", width=20,height=2, font=("楷体",12),bg="palegreen",anchor="w").place(x=10,y=70)
self.type = ttk.Combobox(self, width=15 ,height=2)
self.type['value'] = ['购货账目','零售账目']
self.type.place(x=90, y=75)
self.type.current(0)
tk.Label( self, text="开始时间:", width=20,height=2, font=("楷体",12),bg="palegreen",anchor="w").place(x=10,y=100)
self.y1 = tk.Spinbox(self,width=6, from_=0,to=2050,increment=1, command= self.set_y1 )
self.y1.place(x=90,y=107)
self.y1.delete(0,'end')
self.y1.insert(0,'2020年')
self.m1 = tk.Spinbox(self,width=3, from_=1,to=12,increment=1, command= self.set_m1)
self.m1.place(x=145,y=107)
self.m1.delete(0,'end')
self.m1.insert(0,'1月')
self.d1 = tk.Spinbox(self,width=3, from_=1,to=31,increment=1, command= self.set_d1)
self.d1.place(x=180,y=107)
self.d1.delete(0,'end')
self.d1.insert(0,'1日')
tmp_time = time.strftime('%Y-%m-%d',time.localtime(time.time())).split("-")
tk.Label( self, text="结束时间:", width=20,height=2, font=("楷体",12),bg="palegreen",anchor="w").place(x=10,y=130)
self.y2 = tk.Spinbox(self,width=6, from_=0,to=2050,increment=1, command= self.set_y2 )
self.y2.place(x=90,y=137)
self.y2.delete(0,'end')
self.y2.insert(0,'{}年'.format(tmp_time))
self.m2 = tk.Spinbox(self,width=3, from_=1,to=12,increment=1, command= self.set_m2)
self.m2.place(x=145,y=137)
self.m2.delete(0,'end')
self.m2.insert(0,'{}月'.format(tmp_time))
self.d2 = tk.Spinbox(self,width=3, from_=1,to=31,increment=1, command= self.set_d2)
self.d2.place(x=180,y=137)
self.d2.delete(0,'end')
self.d2.insert(0,'{}日'.format(tmp_time))
tk.Label( self, text="操作员:", width=20,height=2, font=("楷体",12),bg="palegreen",anchor="w").place(x=10,y=160)
self.user = ttk.Combobox(self, width=15 ,height=2)
self.user.place(x=90, y=165)
self.set_user_val()
tk.Button(self, text="查询", width=28,height=1, command=self.find_info).place(x=10, y=240 )
# 查询结果显示
self.ans_info = tk.Listbox(self, width=45,height=15,font=('宋体',12))
self.ans_info.place( x=220, y=70)
self.ans_info.bind("<Double-Button-1>", self.show_detailed_ans_info)
# 显示详细信息
def show_detailed_ans_info(self,event):
type = self.ans_info.curselection()
if type and type>0:
id = self.ans_info.get( type )
# todo 获取详细信息
data = sql.get_detailed_info( str( self.ans_info.get(0)).strip(), str(id).split(" ") )
tk.messagebox.showinfo(title= str( self.ans_info.get(0) ).strip(), message=data )
# 设置查询条件--操作员
def set_user_val(self):
# DOne 获取操作员id_name
data = sql.get_user_name_id()
self.user['value'] = data
# 查询信息
def find_info(self):
type = self.type.get()
start_time = re.sub( r"[年月日]","","%s-%03s-%03s" % ( str(self.y1.get()),str( self.m1.get()),str(self.d1.get() )) )
end_time = re.sub( r"[年月日]","","%s-%03s-%03s" % ( str(self.y2.get()), str(self.m2.get()),str(self.d2.get()) ) )
start_time.replace(" ",'0')
end_time.replace(" ",'0')
try:
user_id =str( self.user.get() ).split("__")
except Exception as e:
user_id = ""
# done读取数据库
data= sql.find_running_or_purchase( type, start_time, end_time, user_id)
self.ans_info.delete(0,'end')
foritem in data:
self.ans_info.insert('end', item )
# 设置伪日历
def set_y1(self):
self.y1.insert('end','年')
def set_m1(self):
self.m1.insert('end','月')
def set_d1(self):
self.d1.insert('end','日')
def set_y2(self):
self.y2.insert('end','年')
def set_m2(self):
self.m2.insert('end','月')
def set_d2(self):
self.d2.insert('end','日')
# 管理员
classmanger_frame(tk.Frame ):
def __init__(self, **kwargs):
super().__init__( **kwargs)
tk.Label( self, text="管理员", width=10,height=2, font=("黑体",15),bg="cyan" ).place(x=250,y=10)
self.place(x=160, y=40)
# 实现 添加账号
tk.Label( self, text="添加账号", width=10,height=2, font=("黑体",13),bg="palegreen" ).place(x=90,y=60)
tk.Label( self, text="昵称:", width=10,height=2, font=("楷体",12),bg="palegreen",anchor="w" ).place(x=10,y=90)
self.name = tk.Entry(self, width=18 )
self.name.place(x=120,y=100 )
tk.Label( self, text="账号 :", width=10,height=2, font=("楷体",12),bg="palegreen",anchor="w" ).place(x=10,y=120)
self.id = tk.Entry( self, width=18)
self.id.place(x=120, y=130)
tk.Label( self, text="密码:", width=10,height=2, font=("楷体",12),bg="palegreen",anchor="w" ).place(x=10,y=150)
self.pw = tk.Entry( self, width=18)
self.pw.place(x=120, y=160)
tk.Label( self, text="再次输入密码:", width=13,height=2, font=("楷体",12),bg="palegreen",anchor="w" ).place(x=10,y=180)
self.pw2 = tk.Entry( self, width=18)
self.pw2.place(x=120, y=190)
tk.Label( self, text="等级:", width=10,height=2, font=("楷体",12),bg="palegreen",anchor="w" ).place(x=10,y=210)
self.grade = ttk.Combobox( self, width=16)
self.grade.place(x=120, y=220)
self.grade['value'] = ['管理员','普通操作员']
self.grade.current(1)
tk.Button(self, text="添加账号", width=10,height=1, command=self.add_account).place(x=10, y=270 )
tk.Button(self, text="重置", width=10,height=1, command=self.reset_entry).place(x=170, y=270 )
# 实现删除和修改信息
tk.Label( self, text="账号", width=10,height=2, font=("黑体",13),bg="palegreen" ).place(x=300,y=60)
self.account_list = tk.Listbox(self, width=35, height=13, font=("宋体",12))
self.account_list.place(x=280,y=100)
self.add_account_list()
menu = Menu(root, tearoff=0)
menu.add_command(label="修改信息", command=self.change_pw)
menu.add_command(label="删除账号", command= self.del_account)
self.menu = menu
# 鼠标右键弹出菜单
self.account_list.bind("<Button-3>", self.popupmenu)
# 商品清单打开菜单
def popupmenu(self,event):
iflen ( self.account_list.curselection()) :
self.menu.post(event.x_root, event.y_root)
# 添加账号
def add_account(self):
name = self.name.get()
id = self.id.get()
pw = self.pw.get()
pw2 = self.pw2.get()
grade = self.grade.get()
# done 添加账号,写入数据库
if name=="" orid=="" or grade=="":
tk.messagebox.showwarning( title="添加账号", message="请填入正确的数据!")
else:
ifnot pw==pw2:
tk.messagebox.showwarning( title="密码", message="密码不一致!")
else:
if sql.add_user(name,id, pw, grade):
tk.messagebox.showinfo(title="添加账号" ,message="添加成功!")
info = "{}{}{}{}".format(name, id, pw,grade)
self.account_list.insert('end', info )
else:
tk.messagebox.showerror(title="添加账号", message="账号已存在,请修改账号!")
# 修改信息界面
def change_pw(self):
# 获取数据
data =str ( self.account_list.get( self.account_list.curselection()) )
data = data.split("")
print( data )
# 界面
child = tk.Toplevel()
child.geometry("280x210+100+100")
child.config( bg="palegreen")
child.title("修改账号信息")
tk.Label( child, text="昵称:", width=10,height=2, font=("楷体",12),bg="palegreen",anchor="w" ).place(x=10,y=20)
name = tk.Entry(child, width=18 )
name.place(x=120,y=30 )
name.insert(0,data )
tk.Label( child, text="账号 :", width=10,height=2, font=("楷体",12),bg="palegreen",anchor="w" ).place(x=10,y=50)
id = tk.Label( child, width=18, text=str(data), anchor="w" )
id.place(x=120, y=60)
tk.Label( child, text="密码:", width=10,height=2, font=("楷体",12),bg="palegreen",anchor="w" ).place(x=10,y=80)
pw = tk.Entry( child, width=18)
pw.insert( 0,data )
pw.place(x=120, y=90)
tk.Label( child, text="等级:", width=10,height=2, font=("楷体",12),bg="palegreen",anchor="w" ).place(x=10,y=110)
grade = ttk.Combobox( child, width=16)
grade.place(x=120, y=120)
grade['value'] = ['管理员','普通操作员']
grade.current(1)
if data == "管理员":
grade.current(0)
tk.Button(child, text="修改信息", width=10,height=1, command=lambda :self.change_account(str(data), name, pw,grade)).place(x=10, y=170 )
tk.Button(child, text="退出", width=10,height=1, command=child.destroy ).place(x=170, y=170 )
child.mainloop()
# 修改信息
def change_account(self, id, name,pw, grade):
name = name.get()
pw = pw.get()
grade = grade.get()
if name==""orpw==""orgrade=="":
tk.messagebox.showwarning(title="修改用户信息", message="请正确填写相关数据!")
else:
#done 修改用户信息
sql.update_user_info(id, name, pw, grade)
self.account_list.delete(0,'end')
self.add_account_list()
# 删除账号
def del_account(self):
loc =self.account_list.curselection()
data=str( self.account_list.get(loc) ).split("")
title = ['昵称:','账号:','密码:','登记:']
format_data = ""
for indexin range( len(data) ):
format_data += title[ index]+data+"\n"
iftk.messagebox.askyesno( title="确认删除", message=data):
self.account_list.delete(loc)
# done 数据库修改
sql.del_user( data )
# 获取已存在账号信息
def add_account_list(self):
# done 获取管理员信息
data = sql.get_user_info()
self.account_list.delete(0,'end')
foritem indata:
self.account_list.insert('end', item)
# 重置输入框
def reset_entry(self):
self.name.delete(0,'end')
self.id.delete(0,'end')
self.pw.delete(0,'end')
self.pw2.delete(0,'end')
self.grade.current(0)
# 管理员登录 - settings.manger_signing( False/ True)
defmanger_sign( frame, tmp_frame):
child = tk.Toplevel( )
child.geometry("300x230+100+100")
child.config( bg="palegreen")
child.title("管理员登录")
#管理员登录信息
tk.Label(child, width=10, height=2, text="账号: ",anchor="w",bg="palegreen",font=("黑体", 12) ).place(x=20, y=20)
user_id = tk.Entry( child, width=20 )
user_id.place(x=130, y=25 )
tk.Label(child, width=10, height=2, text="密码: ",anchor="w",bg="palegreen",font=("黑体", 12) ).place(x=20, y=60)
user_pw = tk.Entry( child, width=20 )
user_pw.place(x=130, y=65 )
tk.Label(child, width=13, height=2, text="再次输入密码: ",anchor="w",bg="palegreen",font=("黑体", 12) ).place(x=20, y=100)
user_pw2 = tk.Entry( child, width=20 )
user_pw2.place(x=130, y=105 )
# 操作
tk.Button(child,width=10, height=1, text="登录", command=lambda : manger_sign_check( frame, tmp_frame, child, user_id.get(), user_pw.get(), user_pw2.get())).place(x=20, y=165)
tk.Button(child,width=10, height=1, text="重置", command=lambda : reset_manger_sign_info( user_id, user_pw, user_pw2)).place(x=190, y=165)
child.mainloop()
#管理员登录
def manger_sign_check(frame, tmp_frame, child, user_id, user_pw, user_pw2 ):
if not user_pw==user_pw2:
print( user_pw, user_pw2)
tk.messagebox.showwarning( title="管理员登录", message="密码不一致!")
else:
# done 管理员登录
data,name = sql.manger_sign( user_id,user_pw)
if data :
tk.messagebox.showinfo(title="提示", message="管理员:{}\n \t\t登录成功!".format(name))
child.destroy()
settings.manger_signing = True
frame.destroy()
frame = exec(tmp_frame+"(master=root,width=600, height=350,bg='palegreen' )")
else:
tk.messagebox.showwarning(title="警告", message="管理员 登录失败!")
#重置管理员登录信息
def reset_manger_sign_info( user_id, user_pw, user_pw2 ):
user_id.delete(0,'end')
user_pw.delete(0,'end')
user_pw2.delete(0,'end')
#实现页面切换
defchange_frame(frame, tmp_frame ):
if settings.user["name"] == '':
tk.messagebox.showerror(title="提示",message="请您登录")
else:
if tmp_frame == "manger_frame":# 管理员登录
manger_sign( frame, tmp_frame)
else:
if isinstance(frame, manger_frame):
settings.manger_signing = False
frame.destroy()
frame = exec(tmp_frame+"(master=root,width=600, height=350,bg='palegreen' )")
if __name__ == '__main__':
root =tk.Tk()
root.title("售货管理系统")
root.geometry("800x400")
tk.Label( master=root ,text="昵称:{}\t账号:{}".format( settings.user["name"], settings.user["id"] ))\
.place(x=50, y=10)
frame = sign_frame( master=root,width=600, height=350,bg="palegreen")
purchase_button = tk.Button(master=root, text="登录", width=10,height=2,
command= lambda : change_frame(frame, "sign_frame"))
purchase_button.place(x=50,y=40)
purchase_button = tk.Button(master=root, text="购货管理", width=10,height=2,
command= lambda : change_frame(frame, "purchase_frame"))
purchase_button.place(x=50,y=100)
running_button = tk.Button(master=root, text="零售管理", width=10,height=2,
command= lambda : change_frame(frame, "running_frame") )
running_button.place(x=50,y=160)
warehouse_button = tk.Button(master=root, text="仓库管理", width=10,height=2,
command= lambda : change_frame(frame, "warehouse_frame" ) )
warehouse_button.place(x=50,y=220)
acount_button = tk.Button(master=root, text="结算管理", width=10,height=2,
command= lambda : change_frame(frame,"acount_frame" ) )
acount_button.place(x=50,y=280)
manger_button = tk.Button(master=root, text="管理员", width=10,height=2,
command= lambda :change_frame( frame, "manger_frame" ))
manger_button.place(x=50,y=340)
root.mainloop()
(2)mysql_conn.py:数据库操作
# -*- coding: UTF-8 -*-
importsettings
importre
importtime
sql = settings.mysql_conn
cur=sql.cursor()
"""
登录界面
"""
# 验证登录: 成功,返回True,用户姓名;失败, 返回False,""
defcheck_sign(id,pw):
code="selectname from users where id='{}'and pw='{}' ".format(id, pw)
ifcur.execute( code ):
returnTrue,cur.fetchall()
else:
returnFalse,""
"""
购货管理
"""
# 获取订单信息( 状态 =“订货”), id name shop phone
def get_goods_info_order():
code = "select id, name, shop,phone from purchase where state='订货'"
data = []
ifcur.execute( code ):
cur_data = cur.fetchall()
for item incur_data:
tmp = ""
for i initem :
tmp += str(i)+" "
data.append( tmp )
return data
# 获取某订单的详细信息( 状态 =“订货”)
defget_goods_detailed_info(id): # 订单id
code= "SELECTpurchase.*, users.name FROM purchase,usersWHERE purchase.id='{}' AND purchase.user_id=users.id ".format( id )
data = []
title = ['订单号:','名字:','价格:','数量:','状态:','店铺名称:','联系方式:','操作员id:','操作员:']
if cur.execute(code ):
cur_data = cur.fetchall( )
for index inrange (len(cur_data) ):
#print( cur_data, index, len( cur_data))
data.append(str( title[ index ]) + str( cur_data) )
return data
# 订单收货- (1)状态修改为收货; (2)库存修改
def change_goods_state_receving(id, name):
#(1)修改状态
code = "update purchase setstate='收货' where id='{}'".format(id)
cur.execute( code )
#(2)库存修改
code = "select id from stock where name='{}'".format( name )
if cur.execute( code ):
code = "update stockset sum= sum+( select num from purchase where id='{}') whereid='{}' ".format(id, cur.fetchall())
else:
cur.execute("select count(*) fromstock")
s_id = "%06d" % cur.fetchall()
name = name
cur.execute("select num,pricefrompurchase where id='{}'".format(id))
num, price=cur.fetchall()
code = "insert into stock(id,name,sum,price) values('{}','{}','{}','{}')".format( s_id, name, num, price)
print(code )
cur.execute( code )
# 订单退货- (1)状态修改为 退货 ;
def change_goods_state_back(id):
code = "update purchase setstate='退货' where id='{}'".format(id)
cur.execute( code )
# 订货
def order_goods(id, name, num, price,shop,phone, user_id):
code = "insert into purchase(id,name,num,price,shop,phone,user_id,state) values('{}','{}','{}',{},'{}','{}','{}','订货')".format(id, name, num, price,shop,phone, user_id)
cur.execute( code )
print( code )
#获取当天订单数量
def get_purchase_day_sum( id_time ):
code = "select count(*) from purchase where id like '{}%'".format( id_time )
cur.execute(code)
returncur.fetchall() + 1
"""
零售管理
"""
# 获取库存商品的name id
def get_stock_goods_name_id():
code = "select name, idfromstock"
cur.execute( code )
data= []
tmp_data= cur.fetchall()
for item intmp_data:
data_str= ""
for i in item :
data_str += str(i)+""
data.append( data_str )
return data
#获取库存商品价格---利润值相加
def get_stock_goods_price(id):
code = "selectpricefrom stock where id='{}'".format( id )
cur.execute( code )
return "%.2f" % (float (cur.fetchall()) * (1+settings.profit))
#流水账写入数据库
def write_running(user_id , data ):
id_time = time.strftime('%Y-%m-%d',time.localtime(time.time()))
foritem in data:
cur.execute("select count(*) from running where id like '{}%'".format(id_time))
id_num = cur.fetchall()
id = str( id_time) +"_"+ "{:0>4d}".format( int( id_num) )
item = re.sub(r" +"," ",str(item) ).split(" ")
name = item
stock_id = item
price = item[:-2]
num = item[:-2]
# 添加流水账
code = "insert into running(id, stock_id, num, account, user_id)values('{}','{}','{}','{}','{}')".format( id,stock_id,num, price,user_id)
cur.execute( code )
# 修改库存
code = "update stock set sum=sum-{}where id='{}'".format(num, stock_id )
cur.execute( code )
"""
仓库管理
"""
#获取符合条件的库存信息
def get_stock_goods_price_and_num( name, num, price ):
code = "select name, id, price,sum from stock wherename like '%{}%' andsum{} andprice{} order by id asc".format(name, num, price)
cur.execute( code )
data = []
title= ['商品名','编号','价格/元','数量/个']
data.append( "%-25s%-25s%-25s%-25s" % (title,title, title,title ))
ans =cur.fetchall()
for item in ans:
tmp_item = ""
for i in item:
tmp_item +=str(i)+ " "*(25-len( str(i)))
data.append(tmp_item )
returndata
# 获取所有库存信息
def get_all_stock_info():
code = "select name, id, price,sum fromstock order by id asc "
cur.execute( code )
data = []
title= ['商品名','编号','价格/元','数量/个']
data.append( "%-25s%-25s%-25s%-25s" % (title,title, title, title ))
ans =cur.fetchall()
for item in ans:
tmp_item = ""
for i in item:
tmp_item += str(i)+ " "*(25-len( str(i)))
data.append(tmp_item )
returndata
"""
结算管理
"""
# 获取管理员name_id
def get_user_name_id():
code = "select name, idfrom users"
cur.execute( code )
data = []
cur_data = cur.fetchall()
for item incur_data:
data.append( str( item ) + "__" + str( item ) )
return data
# 获取流水账单或者购货账单
def find_running_or_purchase( type, start_time, end_time, user_id):
data = []
if type=="购货账目":
data.append( " "*10 + "购货账目")
code = "select id, name, shop ,state from purchase where id>='{}_0000' andid<='{}_9999' and user_id like '%{}%' ".format( start_time,end_time, user_id)
else:
data.append( " "*10 + "零售账目")
code = "select running.id, stock.name, running.num, running.time from running, stock whererunning.stock_id=stock.id and running.id>='{}_0000' andrunning.id<='{}_9999' and running.user_id like '%{}%'".format(start_time,end_time, user_id)
# print(code)
ifcur.execute( code ):
cur_data = cur.fetchall()
for item incur_data:
tmp = ""
for i initem :
tmp += str(i)+ ""
data.append( tmp )
return data
# 查看查询数据的详细信息
defget_detailed_info( type, id ):
print( type, id )
data = ""
if type=="购货账目":
title = ['购物编号:','商品名:','订单数量:','单价:','状态:','供货商:','联系方式:','操作员:']
code = "select p.id, p.name,p.num, p.price,p.state, p.shop,p.phone,u.namefrom purchase p,users u where p.id='{}' andp.user_id=u.id ".format( id )
else:
title = ['流水编号:','商品名:','销售数量:','价格:','结单时间:','操作员:']
code = "select r.id, s.name, r.num,r.account, r.time, u.name from running r, stock s, users u where r.id='{}' and s.id=r.stock_id and u.id=r.user_id".format(id)
cur.execute( code )
cur_data = cur.fetchall()
for indexin range( len(title) ):
data += str( title) + str( cur_data ) + "\n"
return data
"""
管理员
"""
# 添加账号
defadd_user(name,id, pw, grade):
code = " insert into users(name, id, pw, grade) values('{}','{}','{}','{}')".format( name,id, pw,grade)
try:
cur.execute( code )
returnTrue
except Exception:
return False
# 删除账号
def del_user( id ):
code = "delete fromusers where id='{}'".format( id )
cur.execute( code )
# 获取管理员信息
defget_user_info():
code = "select name,id,pw,grade from users "
cur.execute( code )
data = []
cur_data = cur.fetchall()
for item incur_data:
tmp_code = "{}{}p:{}{}".format(str(item), str(item), str(item),str(item) )
data.append( tmp_code )
return data
# 修改用户信息
def update_user_info(id, name, pw, grade):
code = "update users set name='{}',pw='{}',grade='{}'where id='{}' ".format(name,pw,grade,id )
cur.execute( code )
# 管理员登录
def manger_sign( user_id,user_pw):
code = "select name from users where id='{}' and pw='{}'".format( user_id, user_pw)
if cur.execute( code ):
return True, cur.fetchall()
return False,""
(3)option.config: 配置文件,
{'init': 'true', 'host': 'localhost', 'user': 'root', 'password': 'root', 'database': 'warehouse'}
(4)settings.py
'''
设置
1、数据库信息set{}
2、用户信息( 当前登录 ) user{}
3、设置数据库:
(1)未设置, 设置;
(2)已设置, 跳过。
4、连接数据库mysql_conn
5、利润设置 profit
'''
importpymysql
# -*- coding: UTF-8 -*-
# 利润设置
profit = 0.1
# 数据库设置
set =dict()
set = { "init":"",
"host":"",
"user":"",
"password":"",
"database":""
}
# 当前登录用户
user = {
"name":"",
"id":""
}
# 管理员是否登录
manger_signing = False
def read_con():
with open("option.config", "r")as f:
ret = eval(f.read() )
for item in ret:
set = ret
def init_database():
conn = pymysql.connect(set["host"], set["user"],set["password"])
cursor = conn.cursor()
# 创建数据库
try:
cursor.execute("createdatabase warehouse")
set["database"] = "warehouse"
except Exception as e :
print("数据库:", e )
cursor.close()
conn.close()
# 重新连接数据库
conn = pymysql.connect(set["host"], set["user"],set["password"] , "warehouse" )
cursor = conn.cursor()
# 创建用户表
# # 用户: user: {user_name,id, password, reg_time}
try:
cursor.execute("""
create table users (
name varchar(20),
id varchar(20) primary key,
pw varchar(20),
grade varchar(20) check( grade in ('管理员','普通操作员')),
seg timestamp )
""")
except Exceptionas e:
print("用户表:", e )
# 添加管理员账号
# # 账号: root , 密码: toor
try:
code = "insert intousers(name,id,pw,grade) values('终极Boss','root','toor','管理员')"
cursor.execute( code )
except Exceptionas e:
print("操作员: " , e)
#创建购货表
## 采购--进货: purchase: {id,name, price,num, statu(定、收、退), shop,phone ,user_id}
try:
cursor.execute("""
create table purchase(
id varchar(20) primary key,
name varchar(20),
price double,
num int,
state varchar(15) check( state in('定货','收货','退货') ),
shop varchar(20),
phone varchar(20),
user_id varchar(20) )
""" )
exceptExceptionas e:
print("购货表: ",e)
#库存:
## stock: {id, sum,price, name, }
try:
cursor.execute("""
createtable stock(
id varchar(20)primary key,
sum int,
price double,
name varchar(20)
)
""")
exceptException as e:
print("库存表: ", e)
#账目表
## 流水账--卖出: runuing: {id, stock_id, num, account, time,user}
try:
cursor.execute("""
createtable running(
idvarchar(20)primary key,
stock_id varchar(20),
numint,
accountdouble,
time timestamp,
user_id varchar(20)
)
""")
except Exceptionas e:
print("账目表: ", e)
cursor.close()
conn.close()
def main():
read_con()
if set["init"] == "False":
init_database()
set["init"] = "true"
withopen("option.config","w")asf:
f.write( str( set ))
returnpymysql.connect(set["host"], set["user"],set["password"], set["database"] )
# 数据库连接
mysql_conn = main()
'''
if __name__ == "__main__":
conn = main().cursor()
conn.close()
'''
随遇而安8 发表于 2020-7-8 15:10
有两处不是很明白,来请教一下@山野村夫-陈墨 ,如下图
701这个意思是,现在的frame对象是不是 manager_frame类的实例化对象,如果是那么就证明管理员已经登陆了。 不需要再次登录。
704这个你可以试试, 我觉得是不行的。 这是我第一次下 tk的多个界面,有些东西我也吃不透 。
不过我觉得修改为exec( "frame="+tmp_frame+"( ............)").
随遇而安8 发表于 2020-7-8 15:10
有两处不是很明白,来请教一下@山野村夫-陈墨 ,如下图
不好意思。
mysql_conn.py这个文件的 253行修改成下面这样就好了 。
code = "select name from users where id='{}' and pw='{}'and grade=';管理员'".format( user_id, user_pw) 。
这是你私信我的问题 。 过来学习学习 谢谢分享!简单实用! 这个真的要好好学习下 {:1_921:}谢谢大佬分享。 可以导出报表吗? 很厉害。 这个仓库管理系统很棒 真的很不错,这个看起来很厉害。我是一是谢谢啦! 学习啦!感谢楼主~