readme.txt
ATM + 购物车 # 一个项目是如何从无到有的 1.需求分析 注册,登陆,查看余额,支付,购物车, 提现,还款,转账,查看流水,注销,管理员, 查看购物车,登陆认证装饰器, 密码加密 2.程序的架构设计 三层架构: 用户功能层: 接收用户输入的内容,展示给用户的内容. 小的逻辑判断,例如两次密码是否一致. 接口层: 处理业务逻辑. 数据处理层: 对数据进行增删查改. 3.分任务开发 4.测试 5.上线运行 注册,登陆,查看余额,提现,还款,转账,查看流水,注销,登陆认证装饰器,密码加密. 今日内容: 购物车, 查看购物车, 添加日志, 管理员 ATM + 购物车 前戏: 一个项目是如何从无到有的. 一 需求分析 对项目需求进行分析,并提取出相应的功能. - 额度15000或自定义 ---> 注册功能 - 实现购物商城,买东西加入购物车,调用信用卡接口结账 ---> 购物车, 支付功能 - 可以提现,手续费5% ---> 提现 - 支持多账户登录 ---> 登陆 - 支持账户间转账 ---> 转账 - 记录每月日常消费流水 ---> 记录流水 - 提供还款接口 ---> 还款 - ATM记录操作日志 ---> 日志功能 - 提供管理接口,包括添加账户、用户额度,冻结账户等... ---> 管理员功能 - 用户认证功能 ---> 登陆认证,使用装饰器 二 程序的架构设计 用户功能层: 负责接收用户输入的内容,并返回结果给用户. 做一些小的逻辑判断. 接口层: 处理业务逻辑. 数据处理层: 对文件进行处理. 增,删,查,改操作. 三层架构的好处: 1.代码结构清晰 2.可扩展性强. 3.易维护,管理. 三 分任务开发 - CTO - 技术总监 - 架构师 - 项目经理 - 普通开发 UI: 用户界面设计师 前端: 网页的开发 后端: 写业务逻辑,写接口 测试: 测试软件 运维: 部署项目. 四 测试 - 手动测试 传统人工去手动测试. - 自动化测试 通过脚本模拟人的行为,自动化执行测试. - 黑盒测试: 对用户界面进行测试. - 白盒测试: 对软件的性能进行测试,例如每分钟能接收多少并发量. 五 上线运行 把测试好的代码交给运维人员, 部署上线.
bin/start.py
import os import sys BASE_DIR = os.path.dirname(os.path.dirname(__file__)) sys.path.append(BASE_DIR) from core import src if __name__ == '__main__': src.run()
conf/settings.py
import os BASE_PATH = os.path.dirname(os.path.dirname(__file__)) # 拼接db目录路径 DB_PATH = os.path.join(BASE_PATH, 'db') """ logging配置 """ # 定义三种日志输出格式 开始 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' id_simple_format = '[%(levelname)s][%(asctime)s] %(message)s' # 定义日志输出格式 结束 logfile_dir = os.path.join(BASE_PATH, 'log') # log文件的目录 logfile_name = 'atm_shop_log.log' # log文件名 # 如果不存在定义的日志目录就创建一个 if not os.path.isdir(logfile_dir): os.mkdir(logfile_dir) # log文件的全路径 logfile_path = os.path.join(logfile_dir, logfile_name) # log配置字典 LOGGING_DIC = { 'version': 1, 'disable_existing_loggers': False, 'formatters': { 'standard': { 'format': standard_format }, 'simple': { 'format': simple_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)传递 }, }, }
db/db_handler.py
import os import json from conf import settings # 保存用户数据 def save(user_dic): # 拼接用户保存文件 user_path = f'{settings.DB_PATH}/{user_dic["user"]}.json' # 把用户信息写入文件中 with open(user_path,'w',encoding='utf-8') as f: json.dump(user_dic,f,ensure_ascii=False) f.flush() # 查看用户数据 def select(user): # base_path = os.path.dirname(os.path.dirname(__file__)) # db_path = os.path.join(base_path,'db') user_path = f'{settings.DB_PATH}/{user}.json' # 调用数据处理层的select函数,查看用户信息 if os.path.exists(user_path): # 若存在, 读取用户信息 with open(user_path,'r',encoding='utf-8') as f: user_dic = json.load(f) return user_dic
lib/common.py
import hashlib import logging.config from conf import settings # MD5 加密功能 def get_md5(pwd): # 加盐 val = '天山折梅手' md5 = hashlib.md5() md5.update(pwd.encode('utf-8')) md5.update(val.encode('utf-8')) res = md5.hexdigest() return res # 装饰器 def login_auth(func): from core import src def inner(*args,**kwargs): # 判断用户是否存在 if not src.user_info['user']: print('请先登录') src.register() pass res = func(*args,*kwargs) return res return inner # 日志功能 def get_logger(type_name): logging.config.dictConfig(settings.LOGGING_DIC) logger = logging.getLogger(type_name) return logger if __name__ == '__main__': res = get_md5('123') print(res) logger = get_logger('tank')
core/src.py
from interface import user_interface,bank_interface,shop_interface,admin_interface from lib import common user_info = {'user':None} # 1.注册 def register(): print('注册功能...') while True: user = input('plealse your name:>>>').strip() # 调用接口判断用户是否存在 flag = user_interface.check_user_interface(user) # 若存在,则让用户重新输入 if flag: print('user 已经 存在') continue pwd = input("please your pwd:>>>").strip() re_pwd = input('please your re_pwd:>>>') if pwd == re_pwd: # 业务逻辑 # 调用接口层注册接口保存用户信息 msg = user_interface.register_interface(user,pwd) if msg: print(msg) break else: print('注册失败') else: print('密码错误') # 2.登录 def login(): print('登录功能...') while True: user = input('plealse your name:>>>').strip() # 调用接口判断用户是否存在 flag = user_interface.check_user_interface(user) # 若不存在,则让用户重新输入 if not flag: print('请重新输入') continue pwd = input("please your pwd:>>>").strip() # 调用登录接口 flag,msg = user_interface.login_interface(user,pwd) if flag: print(msg) # 登陆成功后做一个记录 user_info['user'] = user break else: print(msg) continue # 3.查看余额 @common.login_auth def check_bal(): print('余额接口') bal = user_interface.check_bal_interface(user_info['user']) print(bal) # 4.提现 @common.login_auth def withdraw(): print('提现功能') while True: money = input('please input withdraw money:>>>').strip() if not money.isdigit(): print('请输入数字!') continue money = int(money) flag,msg = bank_interface.withdraw_interface(user_info['user'],money) if flag: print(msg) break else: print(msg) # 5.还款 @common.login_auth def repay(): print('还款功能') while True: money = input('请输入还款金额: ').strip() if not money.isdigit(): print('请输入数字') continue money = int(money) flag,msg = bank_interface.repay_interface(user_info['user'],money) if flag: print(msg) break # 6.转账 @common.login_auth def transfer(): print('转账功能') while True: to_user = input('请输入目标用户').strip() # 判断目标用户是否存在 flag = user_interface.check_user_interface(to_user) if not flag: print('目标用户不存在!') continue # 输入转账金额 money = input('请输入转账金额:').strip() if not money.isdigit(): print('请输入数字!') continue money = int(money) flag, msg = bank_interface.transfer_interface( to_user, user_info['user'], money) if flag: print(msg) break else: print(msg) # 7.查看流水 @common.login_auth def check_flow(): print('查看流水') flow_list = bank_interface.check_flow_interface(user_info['user']) for flow in flow_list: print(flow) # 8.购物车功能 @common.login_auth def shopping(): good_list = [ ['J哥牌辣椒酱', 5], ['Egon牌公仔', 10], ['nick牌T-shirt', 100], ['围城', 39], ['tank牌坦克', 50000], ] user_bal = user_interface.check_bal_interface(user_info['user']) shop_cart = {} cost = 0 while True: # 打印商品信息 for index, good_price in enumerate(good_list): print(index, good_price) # 选择商品编号或者输入q退出 choice = input('请选择商品编号或者输入q退出').strip() if choice.isdigit(): choice = int(choice) if choice >= 0 and choice < len(good_list): good_name, good_price = good_list[choice] if user_bal >= good_price: if good_name in shop_cart: shop_cart[good_name] += 1 else: shop_cart[good_name] = 1 cost += good_price else: print('*穷*, 请打工赚钱再来购买!') else: print('请输入正确商品编号.') elif choice == 'q': commit = input('是否确认结账,请输入y/n: ').strip() if commit == 'y': # 调用购车商城支付功能, 并调用银行支付接口 flag, msg = shop_interface.buy_shop_interface( user_info['user'], cost) if flag: print(msg) break else: print(msg) elif commit == 'n': # 调用添加购物车接口 shop_interface.add_shop_cart_interface(user_info['user'], shop_cart) break # 9.查看购物车 @common.login_auth def check_shop_cart(): shop_cart = shop_interface.check_shop_cart_interface(user_info['user']) if not shop_cart: print('购物车是空的,请选择购物车功能.') print(shop_cart) # 10.注销 @common.login_auth def logout(): print('注销功能') flag,msg = user_interface.logout_interface() if flag: print(msg) # 冻结用户 def lock_user(): print('冻结用户...') user = input('请输入需要冻结的用户: ').strip() flag = user_interface.check_user_interface(user) if flag: # 调用冻结接口 msg = admin_interface.lock_interface(user) print(msg) else: print('用户不存在!') def unlock_user(): print('解冻用户...') user = input('请输入需要解冻的用户: ').strip() flag = user_interface.check_user_interface(user) if flag: # 调用冻结接口 msg = admin_interface.unlock_interface(user) print(msg) else: print('用户不存在!') def change_limit(): print('修改用户额度') user = input('请输入需要修改额度的用户: ').strip() flag = user_interface.check_user_interface(user) if not flag: print('用户不存在!') return limit = input('请输入修改额度').strip() if limit.isdigit(): limit = int(limit) # 调用修改额度接口 msg = admin_interface.change_limit_interface(user, limit) print(msg) else: print('请输入数字') admin_func_dic = { '1': lock_user, '2': unlock_user, '3': change_limit, } # 11.管理员功能 def admin_sys(): while True: print(''' 1.冻结用户 2.解冻用户 3.用户额度 ''') choice = input('请选择管理员功能: ').strip() if choice not in admin_func_dic: print('请重新输入') continue admin_func_dic[choice]() func_dic = { '1': register, '2': login, '3': check_bal, '4': withdraw, '5': repay, '6': transfer, '7': check_flow, '8': shopping, '9': check_shop_cart, '10': logout, '11': admin_sys, } def run(): while True: print(""" 1.注册 2.登录 3.查看余额 4.提现 5.还款 6.转账 7.查看流水 8.购物车功能 9.查看购物车 10.注销 11.管理员功能 """) choice = input('please your choice:>>>').strip() if choice == 'q':break if choice in func_dic: func_dic[choice]() else: print('please True number') continue
interface/user_interface.py
from db import db_handler from lib import common user_logger = common.get_logger('user') # 查看用户接口 def check_user_interface(user): # 调用数据处理层的select函数,查看用户信息 user_dic = db_handler.select(user) if user_dic: return True # 注册接口 def register_interface(user,pwd,balance=15000): # 密码加密 pwd = common.get_md5(pwd) user_dic = { 'user':user, 'pwd':pwd, 'balance':15000, 'flow':[], 'shop_cart':{}, 'lock':False } # 调用保存数据功能 db_handler.save(user_dic) user_logger.info(f'{user_dic["user"]}用户注册成功') return f'{user_dic["user"]}用户注册成功' # 登录接口 def login_interface(user,pwd): user_dic = db_handler.select(user) pwd = common.get_md5(pwd) if user_dic['lock']: user_logger.info(f'{user}已经被冻结,请联系管理员') return False,'用户已被冻结,请联系管理员!' if user_dic['pwd'] == pwd: user_logger.info(f'{user}登录成功') return True,f'{user}登录成功' user_logger.info(f'{user}输入密码错误') return False,f'{user}密码错误' # 查看余额接口 def check_bal_interface(user): user_dic = db_handler.select(user) return user_dic['balance'] # 查看注销接口 def logout_interface(): from core import src user = src.user_info['user'] src.user_info['user'] = None return True,f'{user}用户注销成功.欢迎下次再来'
interface/bank_interface.py
from db import db_handler from lib import common bank_logger = common.get_logger('bank') # 提现接口 def withdraw_interface(user,money): user_dic = db_handler.select(user) if user_dic['balance'] >= money * 1.05: user_dic['balance'] -= money * 1.05 msg = f'用户{user}提现{money}元成功' user_dic['flow'].append(msg) db_handler.save(user_dic) return True,msg else: msg = f'用户{user}余额不足' return False,msg # 还款接口 def repay_interface(user,money): user_dic = db_handler.select(user) user_dic['balance'] += money msg = f'用户{user}, 还款{money}元成功!' user_dic['flow'].append(msg) db_handler.save(user_dic) return True,msg # 转账接口 def transfer_interface(to_user,from_user,money): to_user_dic = db_handler.select(to_user) from_user_dic = db_handler.select(from_user) if from_user_dic['balance'] >= money: # 加减钱操作 from_user_dic['balance'] -= money to_user_dic['balance'] += money # 拼接流水信息 to_user_flow = f'{to_user}用户接收到用户{from_user}转账{money}元' from_user_flow = f'{from_user}用户给到用户{to_user}转账{money}元' # 记录流水 from_user_dic['flow'].append(from_user_flow) to_user_dic['flow'].append(to_user_flow) # 保存用户信息 db_handler.save(from_user_dic) db_handler.save(to_user_dic) return True, from_user_flow return False, '余额不足,请充值!' # 查看流水接口 def check_flow_interface(user): user_dic = db_handler.select(user) return user_dic['flow'] # 银行支付接口 def pay_interface(user, cost): user_dic = db_handler.select(user) if user_dic['balance'] >= cost: user_dic['balance'] -= cost user_dic['flow'].append(f'{user}用户支付{cost}成功!') db_handler.save(user_dic) return True else: return False
interface/admin_interface.py
from db import db_handler from lib import common admin_logger = common.get_logger('admin') # 冻结用户接口 def lock_interface(user): user_dic = db_handler.select(user) user_dic['lock'] = True db_handler.save(user_dic) return f'{user}用户冻结成功!' def unlock_interface(user): user_dic = db_handler.select(user) user_dic['lock'] = False db_handler.save(user_dic) return f'{user}用户解冻成功!' # 修改额度接口 def change_limit_interface(user, limit): user_dic = db_handler.select(user) user_dic['balance'] = limit db_handler.save(user_dic) return f'修改用户[{user}]额度成功!'
interface/shop_interface.py
from interface import bank_interface from db import db_handler from lib import common shop_logger = common.get_logger('shop') # 商城结账接口 def buy_shop_interface(user,cost): flag = bank_interface.pay_interface(user, cost) if flag: return True,'购物成功' else: return False,'余额不足,支付失败' # 添加购物车接口 def add_shop_cart_interface(user, shop_cart): user_dic = db_handler.select(user) old_cart = user_dic['shop_cart'] # 循环当前购物车 for shop in shop_cart: if shop in old_cart: # 获取当前购物车中的商品数量 number = shop_cart[shop] # 给用户信息中的商品数量做 增值运算 old_cart[shop] += number else: # 获取当前购物车中的商品数量 number = shop_cart[shop] old_cart[shop] = number user_dic['shop_cart'].update(old_cart) db_handler.save(user_dic) return True, '添加购物车成功!' # 查看购物车接口' def check_shop_cart_interface(user): user_dic = db_handler.select(user) return user_dic['shop_cart']
log
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用