项目下载

项目目录结构

运行效果





seetings.py

import logging
import logging.config
# 定义日志输出格式 开始
import os standard_format = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' \
'[%(levelname)s][%(message)s]' # 其中name为getlogger指定的名字
simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s' self_format = '[%(asctime)s][%(name)s][%(message)s]'
# 定义日志输出格式 结束 # 自定义文件路径
logfile_path = os.path.join(os.path.abspath('log'), 'a.log') # log配置字典
LOGGING_DIC = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'standard': {
'format': self_format
},
'simple': {
'format': self_format
},
},
'filters': {}, # 过滤日志
'handlers': {
# 打印到终端的日志
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler', # 打印到屏幕
'formatter': 'simple'
},
# 打印到文件的日志,收集info及以上的日志
'default': {
'level': 'DEBUG',
'class': 'logging.handlers.RotatingFileHandler', # 保存到文件
'formatter': 'standard',
'filename': logfile_path, # 日志文件
'maxBytes': 1024 * 1024 * 5, # 日志大小 5M
'backupCount': 5,
'encoding': 'utf-8', # 日志文件的编码,再也不用担心中文log乱码了
},
},
'loggers': {
# logging.getLogger(__name__)拿到的logger配置
'': {
'handlers': ['default', 'console'], # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
'level': 'DEBUG',
'propagate': True, # 向上(更高level的logger)传递
}, },
}
}

business.py

import hashlib
import os
import json
import tkinter
from core import win_login
from lib import common db_path = os.path.abspath('db') def open_file_read(path):
with open(path) as f1:
user_dict = json.load(f1)
return user_dict def open_file_write(path, user_dict):
with open(path, 'w') as f1:
json.dump(user_dict, f1) # 注册
def register(*args, **kwargs):
# 获取用户名和密码
a = 0
name = args[0]
pwd = args[1]
pwd_again = args[2]
# 判断两次密码是否一致,不一致提醒用户
if pwd_again != pwd:
print('------两次密码不一致------')
a = 1
return a
# 使用os.path.join方法拼出存储用户信息的文件路径
user_file_path = os.path.join(db_path, f'{name}.json')
# 该用户文件存在,则提醒用户
if os.path.exists(user_file_path):
print('------用户已经存在------')
a = 2
return a
# 初始化用户数据
md5 = hashlib.md5()
md5.update(f'{name}用户的密码是{pwd}'.encode('utf8')) # 动态加盐
res = md5.hexdigest()
user_dict = {'name': name, 'pwd': res, 'balance': 15000, 'shop_car': {}}
# 将用户数据写入文件
open_file_write(user_file_path, user_dict)
print(f'------用户 {name} 注册成功------')
return a # 登入
def login(*args, **kwargs):
# 获取用户名和密码
a = 0
name = args[0]
pwd = args[1]
# 使用os.path.join方法拼出存储用户信息的文件路径
user_file_path = os.path.join(db_path, f'{name}.json')
# 判断数据库中是否有这个用户的数据,没有则提示用户
if not os.path.exists(user_file_path):
print('------用户不存在------')
a = 1
return a
# 将数据从文件中转成原数据格式
user_dict = open_file_read(user_file_path)
# 判断用户输入的密码是否正确
md5 = hashlib.md5()
md5.update(f'{name}用户的密码是{pwd}'.encode('utf8'))
res = md5.hexdigest()
if res == user_dict['pwd']:
print('------登入成功------')
else:
print('------账号或密码错误------')
a = 2
return a def add_shop_car(*args):
good_list = [
['挂壁面', 3],
['印度飞饼', 22],
['极品木瓜', 666],
['土耳其土豆', 999],
['伊拉克拌面', 1000],
['董卓戏张飞公仔', 2000],
['仿真玩偶', 10000]
]
# 创建一个临时的购物车
shop_char = {}
# 获取用户输入的编号
chioce = args[0]
# 如果用户输入的是商品编号,则准备开始添加
if int(chioce) in range(len(good_list)):
# 将商品名和单价分别取出来,放如两个变量
good_list_list = good_list[int(chioce)]
good_list_name = good_list_list[0]
good_list_money = good_list_list[1]
numb = int(args[1])
if good_list_name in shop_char.keys():
# 购物车中已经有该商品,则添加数量
shop_char[good_list_name][0] += numb
else:
# 购物车没这个商品也就是第一次添加,则向零时购物车中新增键值对
shop_char[good_list_name] = [numb, good_list_money]
user_file_path = os.path.join(db_path, '%s.json' % args[2])
user_dict = open_file_read(user_file_path)
# 判断用户原来的购物车中是否有东西,有就增加,没有就添加新的键值对
for name in shop_char.keys():
if name in user_dict['shop_car'].keys():
user_dict['shop_car'][name][0] += shop_char[name][0]
else:
user_dict['shop_car'][name] = shop_char[name]
# 将用户信息重写回文件
open_file_write(user_file_path, user_dict)
tkinter.messagebox.showinfo(title='Hi', message='添加成功') def to_money(*args):
to_name_path = os.path.join(db_path, '%s.json' % args[1])
self_ptah = os.path.join(db_path, '%s.json' % args[0])
user_dict = open_file_read(self_ptah)
shengyu = user_dict['balance'] - int(args[2])
if os.path.exists(to_name_path):
if user_dict['balance'] > int(args[2]):
user_dict['balance'] -= int(args[2])
open_file_write(self_ptah, user_dict)
user_dict1 = open_file_read(to_name_path)
user_dict1['balance'] += int(args[2])
open_file_write(to_name_path, user_dict1)
tkinter.messagebox.showinfo(title='Hi', message=f'转账成功,转出:{args[2]}元,剩余:{shengyu}')
logger1 = common.get_logger(f'{args[0]}向{args[1]}转账了{args[2]}元')
logger1.debug('转账业务')
else:
tkinter.messagebox.showinfo(title='Hi', message='余额不足')
else:
tkinter.messagebox.showinfo(title='Hi', message='用户不存在')

win_login.py

import os
import tkinter
from core import business
from tkinter import *
from lib import common
from core import business is_login = {
'username': None
} def out_login(*args):
is_login['username'] = None
args[0].destroy()
args[1].destroy() def out_shop_chr(shop):
shop.destroy() def add_shop_chr(*args):
business.add_shop_car(*args) def add_shop():
shop = tkinter.Toplevel()
sw = shop.winfo_screenwidth()
sh = shop.winfo_screenheight()
shop.geometry("%dx%d+%d+%d" % (500, 500, (sw - 500) / 2, (sh - 650) / 2))
good_list = [
['挂壁面', 3],
['印度飞饼', 22],
['极品木瓜', 666],
['土耳其土豆', 999],
['伊拉克拌面', 1000],
['董卓戏张飞公仔', 2000],
['仿真玩偶', 10000]
]
shop_list = tkinter.Listbox(shop, selectmode=MULTIPLE, width=400, height=300)
for item in ['商品编号:0 | 商品名:挂壁面 | 商品单价:3',
'商品编号:1 | 商品名:印度飞饼 | 商品单价:22',
'商品编号:2 | 商品名:极品木瓜 | 商品单价:666',
'商品编号:3 | 商品名:土耳其土豆 | 商品单价:999',
'商品编号:4 | 商品名:伊拉克拌面 | 商品单价:1000',
'商品编号:5 | 商品名:董卓戏张飞公仔 | 商品单价:2000',
'商品编号:6 | 商品名:仿真玩偶 | 商品单价:10000']:
shop_list.insert(END, item)
shop_list.pack()
id = tkinter.StringVar()
id_label = tkinter.Label(shop, text='请输入编号:').place(x=100, y=350)
id_Entry = tkinter.Entry(shop, textvariable=id).place(x=200, y=350) numb = tkinter.StringVar()
numb_label = tkinter.Label(shop, text='请输入数量: ').place(x=100, y=400)
numb_Entry = tkinter.Entry(shop, textvariable=numb).place(x=200, y=400)
username = is_login['username']
out_botton = tkinter.Button(shop, text='退出购物', command=lambda: out_shop_chr(shop)).place(x=100, y=450)
add_botton = tkinter.Button(shop, text='添加商品', command=lambda: add_shop_chr(id.get(), numb.get(), username)).place(
x=200, y=450) shop.mainloop() def pay():
user_dict = business.open_file_read(os.path.join(os.path.abspath('db'), '%s.json' % is_login.get('username')))
yue = user_dict['balance']
need_money = 0
# 计算需要的金额
for i in user_dict['shop_car'].values():
need_money += i[0] * i[1]
# 如果总计大于余额提示用户额不足,否则结算成功,购物车清空
if need_money > yue:
tkinter.messagebox.showinfo(title='Hi', message='余额不足')
else:
user_dict['shop_car'] = {}
user_dict['balance'] = yue - need_money
business.open_file_write(os.path.join(os.path.abspath('db'), '%s.json' % is_login.get('username')), user_dict)
tkinter.messagebox.showinfo(title='Hi', message=f'本次消费{need_money},余额:{yue - need_money}')
name = is_login['username']
logger1 = common.get_logger(f'{name}消费了{need_money}元')
logger1.debug('结账业务') def select_yve():
user_dict = business.open_file_read(os.path.join(os.path.abspath('db'), '%s.json' % is_login.get('username')))
yue = user_dict['balance']
tkinter.messagebox.showinfo(title='Hi', message=f'余额:{yue}') def to_money(*args):
def pay(*args):
business.to_money(*args) to_money = tkinter.Toplevel()
sw = to_money.winfo_screenwidth()
sh = to_money.winfo_screenheight()
to_money.geometry("%dx%d+%d+%d" % (500, 350, (sw - 500) / 2, (sh - 350) / 2))
to_money.title = '转账'
to_name = tkinter.StringVar()
to_name_label = tkinter.Label(to_money, text='转入的账号:').place(x=100, y=100)
to_name_Entry = tkinter.Entry(to_money, textvariable=to_name).place(x=200, y=100)
money = tkinter.StringVar()
money_label = tkinter.Label(to_money, text='金额:').place(x=100, y=150)
money_Entry = tkinter.Entry(to_money, textvariable=money).place(x=200, y=150)
sure_button = tkinter.Button(to_money, text='确认转账',
command=lambda: pay(is_login['username'], to_name.get(), money.get())).place(x=150,
y=200)
sure_button = tkinter.Button(to_money, text='退出', command=lambda: to_money.destroy()).place(x=250, y=200)
to_money.mainloop() def select_flowing_water():
log_path = os.path.join(os.path.abspath('log'), 'a.log')
log_list = []
with open(log_path, 'r', encoding='utf8') as f:
for i in f.readlines():
if is_login['username'] in i:
log_list.append(i)
print(log_list)
water = tkinter.Toplevel()
sw = water.winfo_screenwidth()
sh = water.winfo_screenheight()
water.geometry("%dx%d+%d+%d" % (500, 350, (sw - 500) / 2, (sh - 350) / 2))
water_listbox = tkinter.Listbox(water, selectmode=MULTIPLE, width=400, height=300)
for i in log_list:
water_listbox.insert(END, i) water_listbox.pack()
water_listbox.mainloop()
# tkinter.messagebox.showinfo(title='Hi', message=f'{log_list}') def create_login(*args):
is_login['username'] = args[0]
print(is_login)
win_login = tkinter.Tk()
sw = win_login.winfo_screenwidth()
sh = win_login.winfo_screenheight()
win_login.geometry("%dx%d+%d+%d" % (500, 350, (sw - 500) / 2, (sh - 350) / 2))
win_login.title('选择功能')
lable_top = tkinter.Label(win_login,
text='欢迎光临,世纪联华超市!', # 标签的文字
bg='pink', # 背景颜色
font=('Arial', 12), # 字体和字体大小
width=60, height=2) # 标签长宽
lable_top.pack(side='top')
add_shop_chr = tkinter.Button(win_login, text='购物', width=20, command=add_shop).place(x=150, y=50)
pay_shop_chr = tkinter.Button(win_login, text='结算', width=20, command=pay).place(x=150, y=100)
move_money_to = tkinter.Button(win_login, text='转账', width=20, command=to_money).place(x=150, y=150)
select_info = tkinter.Button(win_login, text='查看流水', width=20, command=select_flowing_water).place(x=150, y=200)
select_balance = tkinter.Button(win_login, text='查看余额', width=20, command=select_yve).place(x=150, y=250)
sign_out = tkinter.Button(win_login, text='退出登入', width=20, command=lambda: out_login(win_login, args[1])).place(
x=150, y=300)
win_login.mainloop()

Windows.py

import tkinter
from tkinter import *
from tkinter import messagebox
from core import business
from core import win_login
import hashlib
import os
from start import db_path
import json
def run():
pass def click_login_botton():
a = business.login(name.get(), pwd.get())
if a == 0:
print(tkinter.messagebox.showinfo(title='Hi', message='登入成功'))
win_login.create_login(name.get(), win)
elif a == 1:
print(tkinter.messagebox.showinfo(title='Hi', message='用户不存在'))
return
elif a == 2:
print(tkinter.messagebox.showinfo(title='Hi', message='账号或密码错误'))
return def click_register_button():
def register():
print(new_name.get(), new_pwd.get(), new_pwd_two.get())
a = business.register(new_name.get(), new_pwd.get(), new_pwd_two.get())
if a == 0:
tkinter.messagebox.showinfo(title='Hi', message='注册成功')
win_register.destroy()
elif a == 1:
print(tkinter.messagebox.showinfo(title='Hi', message='密码不一致'))
win_register.destroy()
else:
print(tkinter.messagebox.showinfo(title='Hi', message='账号已存在'))
win_register.destroy() win_register = tkinter.Toplevel(win)
sw = win_register.winfo_screenwidth()
sh = win_register.winfo_screenheight()
win_register.geometry("%dx%d+%d+%d" % (300, 170, (sw - 300) / 2, (sh - 170) / 2))
win_register.title('注册')
# win_register.geometry('300x170')
name_Label = tkinter.Label(win_register, text='用户名 ').place(x=20, y=20)
pwd_Label = tkinter.Label(win_register, text='密码 ').place(x=20, y=60)
pwd_two_Label = tkinter.Label(win_register, text='再次确认密码 ').place(x=20, y=100)
new_name = tkinter.StringVar()
new_pwd = tkinter.StringVar()
new_pwd_two = tkinter.StringVar()
name_Entry = tkinter.Entry(win_register, textvariable=new_name).place(x=100, y=20)
pwd_Entry = tkinter.Entry(win_register, show='*', textvariable=new_pwd).place(x=100, y=60)
pwd_two_Entry = tkinter.Entry(win_register, show='*', textvariable=new_pwd_two).place(x=100, y=100)
register_button = tkinter.Button(win_register, text='注册', command=register).place(x=150, y=130)
win_register.mainloop() win = tkinter.Tk()
win.title('购物车+ATM')
# win.geometry('450x200')
sw = win.winfo_screenwidth()
# 得到屏幕宽度
sh = win.winfo_screenheight()
# 得到屏幕高度
ww = 450
wh = 200
# 窗口宽高为100
x = (sw - ww) / 6
y = (sh - wh) / 2
win.geometry("%dx%d+%d+%d" % (ww, wh, x, y)) lable_top = tkinter.Label(win,
text='欢迎光临,世纪联华超市!', # 标签的文字
bg='pink', # 背景颜色
font=('Arial', 12), # 字体和字体大小
width=60, height=2) # 标签长宽
lable_top.pack(side='top')
username_lable = tkinter.Label(win, text='用户名 ').place(x=120, y=90)
password_lable = tkinter.Label(win, text='密码 ').place(x=120, y=120)
name = tkinter.StringVar()
pwd = tkinter.StringVar()
username_entry = tkinter.Entry(win, textvariable=name).place(x=180, y=90)
password_entry = tkinter.Entry(win, show='*', textvariable=pwd).place(x=180, y=120)
login_button = tkinter.Button(win, text='登入', command=click_login_botton).place(x=180, y=160)
register_button = tkinter.Button(win, text='注册', command=click_register_button).place(x=270, y=160)
win.mainloop()

common.py

import logging
from conf import settings
from logging import config def get_logger(msg):
# 记录日志
logging.config.dictConfig(settings.LOGGING_DIC) # 自动加载字典中的配置
logger1 = logging.getLogger(msg)
return logger1 # 返回一个logger1对象

start.py

import os
import sys
from core import Windows sys.path.append(os.path.dirname(__file__))
db_path = os.path.join(os.path.dirname(__file__), 'db')
if not os.path.exists(db_path):
os.makedirs(db_path) if __name__ == '__main__':
Windows.run()

购物车+ATM项目(图形化)的更多相关文章

  1. IT项目量化管理:细化、量化与图形化 与 中国IT项目实施困惑

    IT项目开发和实施的组织先后在组织中引入项目管理模型的管理制度.流程和方法,但收入甚微.大量的IT项目依然面临着无休止的需求蔓延与频繁加班.项目工期失控.质量低下等典型的项目失控现象.对项目引入量化意 ...

  2. 2018-05-17-OAA-一种mermaid脚本驱动的软件项目模块图形化表述思路

    layout: post title: 2018-05-17-OAA-一种mermaid脚本驱动的软件项目模块图形化表述思路 key: 20180517 tags: OAA flow chart se ...

  3. Git各大平台(win/Linux/Mac)图形化界面客户端大汇总

    摘要: 介绍各平台下的图形化界面git客户端(本人并没有全部使用过),欢迎大家补充新的软件或者使用感受~  一.TortoiseGit - The coolest Interface to Git V ...

  4. [.net 面向对象程序设计进阶] (26) 团队开发利器(五)分布式版本控制系统Git——图形化Git客户端工具TortoiseGit

    [.net 面向对象程序设计进阶] (26) 团队开发利器(五)分布式版本控制系统Git——图形化Git客户端工具TortoiseGit 读前必备: 接上篇: 分布式版本控制系统Git——使用GitS ...

  5. js正则表达式图形化工具-rline

    github地址:https://github.com/finance-sh/rline 在线demo: http://lihuazhai.com/demo/test.html 这是一个js正则表达式 ...

  6. 图形化查看maven的dependency依赖

    开发项目的时候,我们想知道一个maven的依赖库是来自那个工程,eclipse有插件可以直接看Dependency Hierarchy,推荐一个第三方的工具yED 在工程的pom.xml文件中添加如下 ...

  7. 【转】Git图形化界面客户端大汇总

    原文网址:http://my.oschina.net/amstrong/blog/159114 目录[-] 一.TortoiseGit - The coolest Interface to Git V ...

  8. NI Labview 将图形化系统设计用于肿瘤治疗

    NI Labview 将图形化系统设计用于肿瘤治疗 - Jeff Stevens, Sanarus 挑战:在严格的规则条例范围内保持设计过程的情况下,为通过FDA认证的等级II医疗设备进行设计.原型并 ...

  9. 几款开源的图形化Redis客户端管理软件

    转载于:http://www.itxuexiwang.com/a/shujukujishu/redis/2016/0216/98.html?1455870209 Redis是一个超精简的基于内存的键值 ...

随机推荐

  1. 在虚拟机里面运行java程序

    首先输入vi在里面写一个java程序 然后再查找jdk 复制jdk名字 然后安装jdk 安装完之后输入Javac加你创建的文件名 然后再输入Java 和文件名(这个不要加后缀)然后就打印出来了

  2. yum下载安装git服务

    yum install git 安装成功后,配置 用户 邮箱信息 注: youxiu326 github账号名称 youxiu326@163.com    github账号对应邮箱 git confi ...

  3. AD18布线技巧

    3. 快乐打孔模式(颜色配置)PCB 设计完成后,补回流孔,需要打开多层,软件设置如下: 设置方法: 转载原文链接未知

  4. vue打包后空白页问题全记录 (background路径,css js404,jsonp等);

    总结一下vue打包后问题全记录:大部分开发者webpack基本上都是拿来就用的(并没有系统化的研究). 一 >>> 打包之后的静态文件不能直接访问:(例如dist)打包后搭个服务器才 ...

  5. hive从入门到放弃(四)——分区与分桶

    今天讲讲分区表和分桶表,前面的文章还没看的可以点击链接: hive从入门到放弃(一)--初识hive hive从入门到放弃(二)--DDL数据定义 hive从入门到放弃(三)--DML数据操作 分区 ...

  6. Python网络爬虫 - 爬取中证网银行相关信息

    最终版:07_中证网(Plus -Pro).py # coding=utf-8 import requests from bs4 import BeautifulSoup import io impo ...

  7. Python的组合数据类型

    """ Python的组合类型: 序列类型:元素之间存在先后关系,可以通过索引来访问 列表: 元组: 字符串: 映射类型:用键值来表示数据 字典: 集合类型:元素是无序的 ...

  8. 面试官:Zookeeper怎么解决读写、双写并发不一致问题,以及共享锁的实现原理?

    哈喽!大家好,我是小奇,一位不靠谱的程序员 小奇打算以轻松幽默的对话方式来分享一些技术,如果你觉得通过小奇的文章学到了东西,那就给小奇一个赞吧 文章持续更新 一.前言 今天清明假期,赶上北京玉渊潭公园 ...

  9. 微信小程序实战,用vue3实现每日浪漫情话推荐~

    之前做了个恋爱话术微信小程序,实现高情商的恋爱聊天. 但最近突然发现,每天早上给女朋友发一段优美情话可以让她开心一整天,但无奈自己的语言水平确实有限,不能随手拈来,着实让人有点不爽. 不过办法总比困难 ...

  10. RENIX软件V6板卡速率设置——网络测试仪实操

    本文主要介绍RENIX软件V6板卡速率设置相关操作.全文分为V6板卡介绍.如何配置端口两大部分.其中从添加和连接机箱.预约端口.配置端口为强制10M.配置端口为自协商100M.配置说明五个方面详细介绍 ...