项目下载

项目目录结构

运行效果





seetings.py

  1. import logging
  2. import logging.config
  3. # 定义日志输出格式 开始
  4. import os
  5. standard_format = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' \
  6. '[%(levelname)s][%(message)s]' # 其中name为getlogger指定的名字
  7. simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'
  8. self_format = '[%(asctime)s][%(name)s][%(message)s]'
  9. # 定义日志输出格式 结束
  10. # 自定义文件路径
  11. logfile_path = os.path.join(os.path.abspath('log'), 'a.log')
  12. # log配置字典
  13. LOGGING_DIC = {
  14. 'version': 1,
  15. 'disable_existing_loggers': False,
  16. 'formatters': {
  17. 'standard': {
  18. 'format': self_format
  19. },
  20. 'simple': {
  21. 'format': self_format
  22. },
  23. },
  24. 'filters': {}, # 过滤日志
  25. 'handlers': {
  26. # 打印到终端的日志
  27. 'console': {
  28. 'level': 'DEBUG',
  29. 'class': 'logging.StreamHandler', # 打印到屏幕
  30. 'formatter': 'simple'
  31. },
  32. # 打印到文件的日志,收集info及以上的日志
  33. 'default': {
  34. 'level': 'DEBUG',
  35. 'class': 'logging.handlers.RotatingFileHandler', # 保存到文件
  36. 'formatter': 'standard',
  37. 'filename': logfile_path, # 日志文件
  38. 'maxBytes': 1024 * 1024 * 5, # 日志大小 5M
  39. 'backupCount': 5,
  40. 'encoding': 'utf-8', # 日志文件的编码,再也不用担心中文log乱码了
  41. },
  42. },
  43. 'loggers': {
  44. # logging.getLogger(__name__)拿到的logger配置
  45. '': {
  46. 'handlers': ['default', 'console'], # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
  47. 'level': 'DEBUG',
  48. 'propagate': True, # 向上(更高level的logger)传递
  49. },
  50. },
  51. }
  52. }

business.py

  1. import hashlib
  2. import os
  3. import json
  4. import tkinter
  5. from core import win_login
  6. from lib import common
  7. db_path = os.path.abspath('db')
  8. def open_file_read(path):
  9. with open(path) as f1:
  10. user_dict = json.load(f1)
  11. return user_dict
  12. def open_file_write(path, user_dict):
  13. with open(path, 'w') as f1:
  14. json.dump(user_dict, f1)
  15. # 注册
  16. def register(*args, **kwargs):
  17. # 获取用户名和密码
  18. a = 0
  19. name = args[0]
  20. pwd = args[1]
  21. pwd_again = args[2]
  22. # 判断两次密码是否一致,不一致提醒用户
  23. if pwd_again != pwd:
  24. print('------两次密码不一致------')
  25. a = 1
  26. return a
  27. # 使用os.path.join方法拼出存储用户信息的文件路径
  28. user_file_path = os.path.join(db_path, f'{name}.json')
  29. # 该用户文件存在,则提醒用户
  30. if os.path.exists(user_file_path):
  31. print('------用户已经存在------')
  32. a = 2
  33. return a
  34. # 初始化用户数据
  35. md5 = hashlib.md5()
  36. md5.update(f'{name}用户的密码是{pwd}'.encode('utf8')) # 动态加盐
  37. res = md5.hexdigest()
  38. user_dict = {'name': name, 'pwd': res, 'balance': 15000, 'shop_car': {}}
  39. # 将用户数据写入文件
  40. open_file_write(user_file_path, user_dict)
  41. print(f'------用户 {name} 注册成功------')
  42. return a
  43. # 登入
  44. def login(*args, **kwargs):
  45. # 获取用户名和密码
  46. a = 0
  47. name = args[0]
  48. pwd = args[1]
  49. # 使用os.path.join方法拼出存储用户信息的文件路径
  50. user_file_path = os.path.join(db_path, f'{name}.json')
  51. # 判断数据库中是否有这个用户的数据,没有则提示用户
  52. if not os.path.exists(user_file_path):
  53. print('------用户不存在------')
  54. a = 1
  55. return a
  56. # 将数据从文件中转成原数据格式
  57. user_dict = open_file_read(user_file_path)
  58. # 判断用户输入的密码是否正确
  59. md5 = hashlib.md5()
  60. md5.update(f'{name}用户的密码是{pwd}'.encode('utf8'))
  61. res = md5.hexdigest()
  62. if res == user_dict['pwd']:
  63. print('------登入成功------')
  64. else:
  65. print('------账号或密码错误------')
  66. a = 2
  67. return a
  68. def add_shop_car(*args):
  69. good_list = [
  70. ['挂壁面', 3],
  71. ['印度飞饼', 22],
  72. ['极品木瓜', 666],
  73. ['土耳其土豆', 999],
  74. ['伊拉克拌面', 1000],
  75. ['董卓戏张飞公仔', 2000],
  76. ['仿真玩偶', 10000]
  77. ]
  78. # 创建一个临时的购物车
  79. shop_char = {}
  80. # 获取用户输入的编号
  81. chioce = args[0]
  82. # 如果用户输入的是商品编号,则准备开始添加
  83. if int(chioce) in range(len(good_list)):
  84. # 将商品名和单价分别取出来,放如两个变量
  85. good_list_list = good_list[int(chioce)]
  86. good_list_name = good_list_list[0]
  87. good_list_money = good_list_list[1]
  88. numb = int(args[1])
  89. if good_list_name in shop_char.keys():
  90. # 购物车中已经有该商品,则添加数量
  91. shop_char[good_list_name][0] += numb
  92. else:
  93. # 购物车没这个商品也就是第一次添加,则向零时购物车中新增键值对
  94. shop_char[good_list_name] = [numb, good_list_money]
  95. user_file_path = os.path.join(db_path, '%s.json' % args[2])
  96. user_dict = open_file_read(user_file_path)
  97. # 判断用户原来的购物车中是否有东西,有就增加,没有就添加新的键值对
  98. for name in shop_char.keys():
  99. if name in user_dict['shop_car'].keys():
  100. user_dict['shop_car'][name][0] += shop_char[name][0]
  101. else:
  102. user_dict['shop_car'][name] = shop_char[name]
  103. # 将用户信息重写回文件
  104. open_file_write(user_file_path, user_dict)
  105. tkinter.messagebox.showinfo(title='Hi', message='添加成功')
  106. def to_money(*args):
  107. to_name_path = os.path.join(db_path, '%s.json' % args[1])
  108. self_ptah = os.path.join(db_path, '%s.json' % args[0])
  109. user_dict = open_file_read(self_ptah)
  110. shengyu = user_dict['balance'] - int(args[2])
  111. if os.path.exists(to_name_path):
  112. if user_dict['balance'] > int(args[2]):
  113. user_dict['balance'] -= int(args[2])
  114. open_file_write(self_ptah, user_dict)
  115. user_dict1 = open_file_read(to_name_path)
  116. user_dict1['balance'] += int(args[2])
  117. open_file_write(to_name_path, user_dict1)
  118. tkinter.messagebox.showinfo(title='Hi', message=f'转账成功,转出:{args[2]}元,剩余:{shengyu}')
  119. logger1 = common.get_logger(f'{args[0]}向{args[1]}转账了{args[2]}元')
  120. logger1.debug('转账业务')
  121. else:
  122. tkinter.messagebox.showinfo(title='Hi', message='余额不足')
  123. else:
  124. tkinter.messagebox.showinfo(title='Hi', message='用户不存在')

win_login.py

  1. import os
  2. import tkinter
  3. from core import business
  4. from tkinter import *
  5. from lib import common
  6. from core import business
  7. is_login = {
  8. 'username': None
  9. }
  10. def out_login(*args):
  11. is_login['username'] = None
  12. args[0].destroy()
  13. args[1].destroy()
  14. def out_shop_chr(shop):
  15. shop.destroy()
  16. def add_shop_chr(*args):
  17. business.add_shop_car(*args)
  18. def add_shop():
  19. shop = tkinter.Toplevel()
  20. sw = shop.winfo_screenwidth()
  21. sh = shop.winfo_screenheight()
  22. shop.geometry("%dx%d+%d+%d" % (500, 500, (sw - 500) / 2, (sh - 650) / 2))
  23. good_list = [
  24. ['挂壁面', 3],
  25. ['印度飞饼', 22],
  26. ['极品木瓜', 666],
  27. ['土耳其土豆', 999],
  28. ['伊拉克拌面', 1000],
  29. ['董卓戏张飞公仔', 2000],
  30. ['仿真玩偶', 10000]
  31. ]
  32. shop_list = tkinter.Listbox(shop, selectmode=MULTIPLE, width=400, height=300)
  33. for item in ['商品编号:0 | 商品名:挂壁面 | 商品单价:3',
  34. '商品编号:1 | 商品名:印度飞饼 | 商品单价:22',
  35. '商品编号:2 | 商品名:极品木瓜 | 商品单价:666',
  36. '商品编号:3 | 商品名:土耳其土豆 | 商品单价:999',
  37. '商品编号:4 | 商品名:伊拉克拌面 | 商品单价:1000',
  38. '商品编号:5 | 商品名:董卓戏张飞公仔 | 商品单价:2000',
  39. '商品编号:6 | 商品名:仿真玩偶 | 商品单价:10000']:
  40. shop_list.insert(END, item)
  41. shop_list.pack()
  42. id = tkinter.StringVar()
  43. id_label = tkinter.Label(shop, text='请输入编号:').place(x=100, y=350)
  44. id_Entry = tkinter.Entry(shop, textvariable=id).place(x=200, y=350)
  45. numb = tkinter.StringVar()
  46. numb_label = tkinter.Label(shop, text='请输入数量: ').place(x=100, y=400)
  47. numb_Entry = tkinter.Entry(shop, textvariable=numb).place(x=200, y=400)
  48. username = is_login['username']
  49. out_botton = tkinter.Button(shop, text='退出购物', command=lambda: out_shop_chr(shop)).place(x=100, y=450)
  50. add_botton = tkinter.Button(shop, text='添加商品', command=lambda: add_shop_chr(id.get(), numb.get(), username)).place(
  51. x=200, y=450)
  52. shop.mainloop()
  53. def pay():
  54. user_dict = business.open_file_read(os.path.join(os.path.abspath('db'), '%s.json' % is_login.get('username')))
  55. yue = user_dict['balance']
  56. need_money = 0
  57. # 计算需要的金额
  58. for i in user_dict['shop_car'].values():
  59. need_money += i[0] * i[1]
  60. # 如果总计大于余额提示用户额不足,否则结算成功,购物车清空
  61. if need_money > yue:
  62. tkinter.messagebox.showinfo(title='Hi', message='余额不足')
  63. else:
  64. user_dict['shop_car'] = {}
  65. user_dict['balance'] = yue - need_money
  66. business.open_file_write(os.path.join(os.path.abspath('db'), '%s.json' % is_login.get('username')), user_dict)
  67. tkinter.messagebox.showinfo(title='Hi', message=f'本次消费{need_money},余额:{yue - need_money}')
  68. name = is_login['username']
  69. logger1 = common.get_logger(f'{name}消费了{need_money}元')
  70. logger1.debug('结账业务')
  71. def select_yve():
  72. user_dict = business.open_file_read(os.path.join(os.path.abspath('db'), '%s.json' % is_login.get('username')))
  73. yue = user_dict['balance']
  74. tkinter.messagebox.showinfo(title='Hi', message=f'余额:{yue}')
  75. def to_money(*args):
  76. def pay(*args):
  77. business.to_money(*args)
  78. to_money = tkinter.Toplevel()
  79. sw = to_money.winfo_screenwidth()
  80. sh = to_money.winfo_screenheight()
  81. to_money.geometry("%dx%d+%d+%d" % (500, 350, (sw - 500) / 2, (sh - 350) / 2))
  82. to_money.title = '转账'
  83. to_name = tkinter.StringVar()
  84. to_name_label = tkinter.Label(to_money, text='转入的账号:').place(x=100, y=100)
  85. to_name_Entry = tkinter.Entry(to_money, textvariable=to_name).place(x=200, y=100)
  86. money = tkinter.StringVar()
  87. money_label = tkinter.Label(to_money, text='金额:').place(x=100, y=150)
  88. money_Entry = tkinter.Entry(to_money, textvariable=money).place(x=200, y=150)
  89. sure_button = tkinter.Button(to_money, text='确认转账',
  90. command=lambda: pay(is_login['username'], to_name.get(), money.get())).place(x=150,
  91. y=200)
  92. sure_button = tkinter.Button(to_money, text='退出', command=lambda: to_money.destroy()).place(x=250, y=200)
  93. to_money.mainloop()
  94. def select_flowing_water():
  95. log_path = os.path.join(os.path.abspath('log'), 'a.log')
  96. log_list = []
  97. with open(log_path, 'r', encoding='utf8') as f:
  98. for i in f.readlines():
  99. if is_login['username'] in i:
  100. log_list.append(i)
  101. print(log_list)
  102. water = tkinter.Toplevel()
  103. sw = water.winfo_screenwidth()
  104. sh = water.winfo_screenheight()
  105. water.geometry("%dx%d+%d+%d" % (500, 350, (sw - 500) / 2, (sh - 350) / 2))
  106. water_listbox = tkinter.Listbox(water, selectmode=MULTIPLE, width=400, height=300)
  107. for i in log_list:
  108. water_listbox.insert(END, i)
  109. water_listbox.pack()
  110. water_listbox.mainloop()
  111. # tkinter.messagebox.showinfo(title='Hi', message=f'{log_list}')
  112. def create_login(*args):
  113. is_login['username'] = args[0]
  114. print(is_login)
  115. win_login = tkinter.Tk()
  116. sw = win_login.winfo_screenwidth()
  117. sh = win_login.winfo_screenheight()
  118. win_login.geometry("%dx%d+%d+%d" % (500, 350, (sw - 500) / 2, (sh - 350) / 2))
  119. win_login.title('选择功能')
  120. lable_top = tkinter.Label(win_login,
  121. text='欢迎光临,世纪联华超市!', # 标签的文字
  122. bg='pink', # 背景颜色
  123. font=('Arial', 12), # 字体和字体大小
  124. width=60, height=2) # 标签长宽
  125. lable_top.pack(side='top')
  126. add_shop_chr = tkinter.Button(win_login, text='购物', width=20, command=add_shop).place(x=150, y=50)
  127. pay_shop_chr = tkinter.Button(win_login, text='结算', width=20, command=pay).place(x=150, y=100)
  128. move_money_to = tkinter.Button(win_login, text='转账', width=20, command=to_money).place(x=150, y=150)
  129. select_info = tkinter.Button(win_login, text='查看流水', width=20, command=select_flowing_water).place(x=150, y=200)
  130. select_balance = tkinter.Button(win_login, text='查看余额', width=20, command=select_yve).place(x=150, y=250)
  131. sign_out = tkinter.Button(win_login, text='退出登入', width=20, command=lambda: out_login(win_login, args[1])).place(
  132. x=150, y=300)
  133. win_login.mainloop()

Windows.py

  1. import tkinter
  2. from tkinter import *
  3. from tkinter import messagebox
  4. from core import business
  5. from core import win_login
  6. import hashlib
  7. import os
  8. from start import db_path
  9. import json
  10. def run():
  11. pass
  12. def click_login_botton():
  13. a = business.login(name.get(), pwd.get())
  14. if a == 0:
  15. print(tkinter.messagebox.showinfo(title='Hi', message='登入成功'))
  16. win_login.create_login(name.get(), win)
  17. elif a == 1:
  18. print(tkinter.messagebox.showinfo(title='Hi', message='用户不存在'))
  19. return
  20. elif a == 2:
  21. print(tkinter.messagebox.showinfo(title='Hi', message='账号或密码错误'))
  22. return
  23. def click_register_button():
  24. def register():
  25. print(new_name.get(), new_pwd.get(), new_pwd_two.get())
  26. a = business.register(new_name.get(), new_pwd.get(), new_pwd_two.get())
  27. if a == 0:
  28. tkinter.messagebox.showinfo(title='Hi', message='注册成功')
  29. win_register.destroy()
  30. elif a == 1:
  31. print(tkinter.messagebox.showinfo(title='Hi', message='密码不一致'))
  32. win_register.destroy()
  33. else:
  34. print(tkinter.messagebox.showinfo(title='Hi', message='账号已存在'))
  35. win_register.destroy()
  36. win_register = tkinter.Toplevel(win)
  37. sw = win_register.winfo_screenwidth()
  38. sh = win_register.winfo_screenheight()
  39. win_register.geometry("%dx%d+%d+%d" % (300, 170, (sw - 300) / 2, (sh - 170) / 2))
  40. win_register.title('注册')
  41. # win_register.geometry('300x170')
  42. name_Label = tkinter.Label(win_register, text='用户名 ').place(x=20, y=20)
  43. pwd_Label = tkinter.Label(win_register, text='密码 ').place(x=20, y=60)
  44. pwd_two_Label = tkinter.Label(win_register, text='再次确认密码 ').place(x=20, y=100)
  45. new_name = tkinter.StringVar()
  46. new_pwd = tkinter.StringVar()
  47. new_pwd_two = tkinter.StringVar()
  48. name_Entry = tkinter.Entry(win_register, textvariable=new_name).place(x=100, y=20)
  49. pwd_Entry = tkinter.Entry(win_register, show='*', textvariable=new_pwd).place(x=100, y=60)
  50. pwd_two_Entry = tkinter.Entry(win_register, show='*', textvariable=new_pwd_two).place(x=100, y=100)
  51. register_button = tkinter.Button(win_register, text='注册', command=register).place(x=150, y=130)
  52. win_register.mainloop()
  53. win = tkinter.Tk()
  54. win.title('购物车+ATM')
  55. # win.geometry('450x200')
  56. sw = win.winfo_screenwidth()
  57. # 得到屏幕宽度
  58. sh = win.winfo_screenheight()
  59. # 得到屏幕高度
  60. ww = 450
  61. wh = 200
  62. # 窗口宽高为100
  63. x = (sw - ww) / 6
  64. y = (sh - wh) / 2
  65. win.geometry("%dx%d+%d+%d" % (ww, wh, x, y))
  66. lable_top = tkinter.Label(win,
  67. text='欢迎光临,世纪联华超市!', # 标签的文字
  68. bg='pink', # 背景颜色
  69. font=('Arial', 12), # 字体和字体大小
  70. width=60, height=2) # 标签长宽
  71. lable_top.pack(side='top')
  72. username_lable = tkinter.Label(win, text='用户名 ').place(x=120, y=90)
  73. password_lable = tkinter.Label(win, text='密码 ').place(x=120, y=120)
  74. name = tkinter.StringVar()
  75. pwd = tkinter.StringVar()
  76. username_entry = tkinter.Entry(win, textvariable=name).place(x=180, y=90)
  77. password_entry = tkinter.Entry(win, show='*', textvariable=pwd).place(x=180, y=120)
  78. login_button = tkinter.Button(win, text='登入', command=click_login_botton).place(x=180, y=160)
  79. register_button = tkinter.Button(win, text='注册', command=click_register_button).place(x=270, y=160)
  80. win.mainloop()

common.py

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

start.py

  1. import os
  2. import sys
  3. from core import Windows
  4. sys.path.append(os.path.dirname(__file__))
  5. db_path = os.path.join(os.path.dirname(__file__), 'db')
  6. if not os.path.exists(db_path):
  7. os.makedirs(db_path)
  8. if __name__ == '__main__':
  9. 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. _CrtCheckMemory

    参考: _CrtCheckMemory MSDN 堆异常检查-MS vs stdio 编写程序经常会涉及到堆的申请,但是如果你向所申请堆里写数据,超过了你最开始申请的空间是,运行中就会发生中断. _C ...

  2. formSelects

    formSelects-v4.js 链接:https://pan.baidu.com/s/1Qp-ez7CuA1cVdWhP37EA7Q  提取码:17iq只需要下文中的css文件和js文件引入到页面 ...

  3. pydev+eclipse写python代码

    首先,下载pydev:PyDev for Eclipse - Browse /pydev at SourceForge.net (建议下载到本地,之前看其他文章时,进行了如下安装: 启动 Eclips ...

  4. hbase增删查

    代码: package cn.idcast.hbase; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.h ...

  5. 【weex开发】weex官方源码

    公司目前使用版本:weex_sdk:0.10.0 介绍地址:https://bintray.com/alibabaweex/maven/weex_sdk/0.18.0 weex最新版本:weex_sd ...

  6. Jquery中each的3种遍历方式

    学习目标: 参考博文: https://blog.csdn.net/honey_th/article/details/7404273 一.Jquery中each的几种遍历方法 1. 选择器+遍历 &l ...

  7. 初始化properties

    package com.letech.common; import java.io.IOException; import java.util.Properties; public class Con ...

  8. JdGrid排序问题

    JdGrid排序问题 js代码 function gridList() { var $gridList = $("#gridList"); $gridList.dataGrid({ ...

  9. Shiro-登陆流程认证-图解

  10. shell、bash和sh区别

    shell是你(用户)和Linux(或者更准确的说,是你和Linux内核)之间的接口程序.你在提示符下输入的每个命令都由shell先解释然后传给Linux内核. shell 是一个命令语言解释器(co ...