项目需求: 模拟实现一个ATM + 购物商城程序 额度 15000或自定义 实现购物商城,买东西加入 购物车,调用信用卡接口结账 可以提现,手续费5% 支持多账户登录 支持账户间转账 记录日常消费流水 提供还款接口 ATM记录操作日志 提供管理接口,包括添加账户、冻结账户等。。。 用户认证用装饰器 项目功能: 1、登录 2、注册 3、查看余额 4、转账 5、还款 6、取款 7、查看流水 8、购物 9、查看购买商品
bin/start
import os, 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/setting
import os BASE_DIR = os.path.dirname(os.path.dirname(__file__)) BASE_DB_LOCAL = os.path.join(BASE_DIR, 'db') BASE_LOG_LOCAL=os.path.join(BASE_DIR, 'log') logfile_name = 'log.log' # log文件名 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' # 定义日志输出格式 结束 # 如果不存在定义的日志目录就创建一个 if not os.path.isdir(BASE_LOG_LOCAL): os.mkdir(BASE_LOG_LOCAL) # log文件的全路径 logfile_path = os.path.join(BASE_LOG_LOCAL, 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)传递 }, }, }
core/src
from interface import bank from interface import user from interface import shop from lib import common user_data = { 'name': None, 'is_auth': False, } def login(): ''' 登录函数,密码输错三次锁定,用户名输错可以一直输入 :return: ''' print('请登录:') count = 0 while True: name = input('please input username>>:').strip() if 'q' == name: break user_dic = user.get_userinfo_by_name(name) if count >= 3: # 锁定用户 user.lock_user(name) print('try too many,user locked') break if user_dic: passwrod = input('please input password>>:').strip() if user_dic['password'] == passwrod and not user_dic['locked']: user_data['name'] = name user_data['is_auth'] = True print('login success') break else: print('password error or user locked') count += 1 continue else: print('user do not exist') continue def register(): ''' 注册函数,登录了不能继续注册,已存在的用户不能再次注册 :return: ''' if user_data['is_auth']: print('you is login') return print('注册:') while True: name = input('please input username>>').strip() if 'q' == name: break user_dic = user.get_userinfo_by_name(name) if user_dic: print('user is exist') continue else: password = input('please input password>>').strip() password2 = input('please config password>>').strip() if password == password2: user.register_user(name, password) break else: print('password not equles') continue @common.login_auth def check_balance(): balance = bank.get_balance_interface(user_data['name']) print('查看余额') print('您的余额为:%s' % balance) @common.login_auth def transfer(): print('转账') while True: trans_name = input('please input transfer user(q to exit)>>').strip() if trans_name == user_data['name']: print('connot transfer to yourself') continue if 'q' == trans_name: break trans_dic = user.get_userinfo_by_name(trans_name) if trans_dic: trans_money = input('please input transfer money>>:').strip() if trans_money.isdigit(): trans_money = int(trans_money) user_balance = bank.get_balance_interface(user_data['name']) if user_balance >= trans_money: bank.transfer_interface(user_data['name'], trans_name, trans_money) break else: print('money not enough') continue else: print('please input numbers') continue else: print('user do not exist') continue @common.login_auth def repay(): print('还款') while True: repay_money = input('please input repay money(q to exit)>>:').strip() if 'q' == repay_money: break if repay_money.isdigit(): repay_money = int(repay_money) bank.repay_interface(user_data['name'], repay_money) print('repay success') break else: print('please input number') continue @common.login_auth def withdraw(): print('取款') while True: withdraw_money = input('please input withdraw money(q to exit)>>:').strip() if 'q' == withdraw_money: break if withdraw_money.isdigit(): withdraw_money = int(withdraw_money) if bank.withdraw_interface(user_data['name'], withdraw_money): print('withdraw %s yuan success' % withdraw_money) break else: print('money not enough') continue else: print('please input numbers') continue @common.login_auth def check_record(): print('您的银行流水为:') for record in bank.check_record(user_data['name']): print(record) @common.login_auth def shopping(): print('购物') goods_list = [ ['coffe', 30], ['chicken', 20], ['iPhone', 8000], ['macBook', 12000], ['car', 100000] ] shopping_cart = {} user_money = bank.get_balance_interface(user_data['name']) cost_money = 0 while True: for i, item in enumerate(goods_list): print(i, item) choice = input('please choice goods or exit(q)>>:').strip() if choice.isdigit(): choice = int(choice) if choice < 0 or choice >= len(goods_list): continue goods_name = goods_list[choice][0] goods_price = goods_list[choice][1] if user_money >= goods_price: if goods_name in shopping_cart: # 原来已经购买过 shopping_cart[goods_name]['count'] += 1 else: shopping_cart[goods_name] = {'price': goods_price, 'count': 1} user_money -= goods_price cost_money += goods_price print('%s add to shopping cart' % goods_name) else: print('money not enough') continue elif choice == 'q': print(shopping_cart) buy = input('buy or not (y/n)>>:').strip() if buy == 'y': #正常需要加密码验证 if cost_money==0:break if shop.shopping_interface(user_data['name'], shopping_cart, cost_money): print('buy success ') break else: print('buy error') break else: print('you buy nothing') break else: print('illegal input') continue @common.login_auth def look_shoppingcart(): print('查看购物车') print(shop.look_shoppingcart(user_data['name'])) # 此处可以详细拼接购物车 func_dic = { '1': login, '2': register, '3': check_balance, '4': transfer, '5': repay, '6': withdraw, '7': check_record, '8': shopping, '9': look_shoppingcart, } def run(): while True: print(''' 1、登录 2、注册 3、查看余额 4、转账 5、还款 6、取款 7、查看流水 8、购物 9、查看购买商品 ''') choose = input('choice>>:').strip() if choose not in func_dic: continue func_dic[choose]()
db/db_handle
import json import os from conf import setting def update(update_dic): path = r'%s/%s.json' % (setting.BASE_DB_LOCAL, update_dic['name']) with open(path, 'w', encoding='utf-8') as f: j = json.dump(update_dic, f) f.flush() def select(name): path = r'%s/%s.json' % (setting.BASE_DB_LOCAL, name) if os.path.isfile(path): with open(path, 'r', encoding='utf-8') as f: return json.load(f) else: return False
interface/bank
from db import db_handle from lib import common from interface import user logger_bank = common.get_logger('Bnak') def transfer_interface(from_name, to_name, account): ''' 转账接口 :param from_name: :param to_name: :param account: :return: ''' from_user_dic = user.get_userinfo_by_name(from_name) to_user_dic = user.get_userinfo_by_name(to_name) if from_user_dic['account']>=account: from_user_dic['account'] -= account to_user_dic['account'] += account # 记录流水 from_user_dic['bankflow'].extend(['%s transfer %s yuan to %s' % (from_name, account, to_name)]) to_user_dic['bankflow'].extend(['%s accept %s yuan from %s' % (to_name, account, from_name)]) db_handle.update(from_user_dic) db_handle.update(to_user_dic) logger_bank.info('%s 向 %s 转账 %s' % (from_name, to_name, account)) return True else: return False def repay_interface(name, account): ''' 还款接口 :param name: :param account: :return: ''' user_dic = user.get_userinfo_by_name(name) user_dic['account'] += account # 记录流水 user_dic['bankflow'].extend(['%s repay %s yuan' % (name, account)]) db_handle.update(user_dic) logger_bank.info('%s 还款 %s 元' % (name, account)) def get_balance_interface(name): ''' 查看余额接口 :param name: :return: ''' # user_dic=user.get_userinfo_by_name(name) # return user_dic['account'] # logger_bank.info('%s 查看了余额' % (name)) return user.get_userinfo_by_name(name)['account'] def consum_interface(name, account): ''' 消费接口 :param name: :param account: :return: ''' user_dic = user.get_userinfo_by_name(name) if user_dic['account']>=account: user_dic['account'] -= account # 记录流水 user_dic['bankflow'].extend(['%s consum %s yuan' % (name, account)]) db_handle.update(user_dic) logger_bank.info('%s 消费 %s 元' % (name, account)) return True else: return False def withdraw_interface(name, account): ''' 取款接口(扣手续费) :param name: :param account: :return: ''' user_dic = user.get_userinfo_by_name(name) if user_dic['account']>=account * 1.05: user_dic['account'] -= account * 1.05 # 记录流水 user_dic['bankflow'].extend(['%s withdraw %s yuan' % (name, account)]) db_handle.update(user_dic) logger_bank.info('%s 取款 %s 元' % (name, account)) return True else: return False def check_record(name): ''' 查看流水接口 :param name: :return: ''' current_user = user.get_userinfo_by_name(name) logger_bank.info('%s 查看了银行流水' % name) return current_user['bankflow']
interface/shop
from lib import common from db import db_handle from interface import user from interface import bank logger_shopping = common.get_logger('Shopoing') def shopping_interface(name, shopping_cart, cost_money): ''' 购物接口 :param name: :param shopping_cart: :param cost_money: :return: ''' # 调用信用卡扣款接口付款 if bank.consum_interface(name, cost_money): # 保存购物车 user_dic = user.get_userinfo_by_name(name) user_dic['shopping_cart'] = shopping_cart db_handle.update(user_dic) logger_shopping.info('%s 花费 %s 购买了 %s' % (name, cost_money, shopping_cart)) return True else: return False def look_shoppingcart(name): ''' 查看购物车接口 :param name: :return: ''' user_dic = user.get_userinfo_by_name(name) logger_shopping.info('%s 查看了购物车' % name) return user_dic['shopping_cart']
interface/user
from db import db_handle from lib import common logger_user = common.get_logger('user') def get_userinfo_by_name(name): ''' 通过用户名获取用户信息接口 :param name: :return: ''' return db_handle.select(name) def lock_user(name): ''' 锁定用户接口 :param name: :return: ''' user_dic = db_handle.select(name) user_dic['locked'] = True db_handle.update(user_dic) logger_user.info('%s 被锁定了' % name) def unlock_user(name): ''' 解锁用户接口 :param name: :return: ''' user_dic = get_userinfo_by_name(name) user_dic['locked'] = False db_handle.update(user_dic) logger_user.info('%s 被解锁了' % name) def register_user(name, password, balance=15000): ''' 注册用户接口 :param name: :param password: :param banlance: :return: ''' user_dic = {'name': name, 'password': password, 'locked': False, 'account': balance, 'credit': balance, 'shopping_cart': {}, 'bankflow': []} db_handle.update(user_dic) logger_user.info('%s 注册了' % name)
lib/common
import logging.config from core import src from conf import setting # def login_auth(func): ''' 登录认证装饰器 :param func: :return: ''' def wrapper(*args, **kwargs): if not src.user_data['is_auth']: print('没有登录') src.login() else: return func(*args, **kwargs) return wrapper def get_logger(name): '''log日志 ''' logging.config.dictConfig(setting.LOGGING_DIC) # 导入上面定义的logging配置 logger = logging.getLogger(name) # 生成一个log实例 return logger
log接收日志
Readme