一 基本需求

模拟实现一个ATM + 购物商城程序

额度 15000或自定义

实现购物商城,买东西加入 购物车,调用信用卡接口结账

可以提现,手续费5%

支持多账户登录

支持账户间转账

记录日常消费流水

提供还款接口

ATM记录操作日志 

提供管理接口,包括添加账户、冻结账户等。。。

用户认证用装饰器

根据上面需求,我们来实现以下几个功能:

     1 注册        2 登录        3 查看余额        4 转账        5 取款        6 还款        7 查看流水        8 购物        9 查看购买商品

 

二 项目目录结构

bin目录

start.py---》程序启动页

conf目录

setting.py---》用于存放整个项目的配置信息

core目录

src.py---》用户端功能

interface目录

bank.py---》银行相关接口

shop.py---》购物相关接口

user.py---》用户相关接口

db目录

db_handler.py---》对文件的读写操作

用于存放所有用户信息,以json格式存储

lib目录

common.py---》公共方法(用户认证装饰器,获取日志对象等)

log目录

记录日志

 

三 分模块

start.py

import os,sys

path = os.path.dirname(__file__)

# print(path)

sys.path.append(path)

from core import src

# print(path)

if __name__ == '__main__':

src.run()

View Code

src.py

from interface import bank,shop,user

from lib import common

user_dic = {

'name':None

}

def register():

if user_dic['name']:

print('已经登录,不能注册')

return

print('注册')

while True:

name = input('请输入名字:').strip()

password = input('请输入密码:').strip()

conf_password = input('请确认密码:').strip()

if password == conf_password:

flag,msg = user.register_interface(name,password)

if flag:

print(msg)

break

else:

print(msg)

else:

print('两次输入的密码不一致')

def login():

if user_dic['name']:

print('已经登录')

return

print('登录')

while True:

name = input('请输入名字:').strip()

password = input('请输入密码:').strip()

flag,msg = user.login_interface(name,password)

if flag:

user_dic['name']=name

print(msg)

break

else:

print(msg)

@common.login_auth

def check_balance():

print('查看余额')

balance = bank.check_balance_interface(user_dic['name'])

print(balance)

@common.login_auth

def transfer():

print('转账')

while True:

to_user = input('请输入对方账户:').strip()

account = input('请输入转账金额:').strip()

if account.isdigit():

account = int(account)

flag,msg = bank.transfer_interface(user_dic['name'],to_user,account)

if flag:

print(msg)

break

else:

print(msg)

else:

print('请输入数字')

@common.login_auth

def repay():

print('还款')

while True:

account = input('请输入还款金额:').strip()

if account.isdigit():

account = int(account)

flag,msg = bank.repay_interface(user_dic['name'],account)

if flag:

print(msg)

break

else:

print(msg)

else:

print('请输入数字')

@common.login_auth

def withdraw():

print('取款')

while True:

account = input('请输入取款金额:').strip()

if account.isdigit():

account = int(account)

flag,msg = bank.withdraw_interface(user_dic['name'],account)

if flag:

print(msg)

break

else:

print(msg)

else:

print('请输入数字')

@common.login_auth

def check_records():

print('查看流水')

records = bank.check_records_interface(user_dic['name'])

if records:

for record in records:

print(record)

else:

print('暂无流水')

@common.login_auth

def shopping():

print('购物')

goods_list = [

['coffee',10],

['chicker',20],

['car',100000]

]

user_balance = bank.check_balance_interface(user_dic['name'])

cost = 0

shoppingcard = {

}

while True:

for i,goods in enumerate(goods_list):

print('%s : %s'%(i,goods))

buy = input('请输入要购买的数字(数字)(q退出并购买):').strip()

if buy.isdigit():

buy = int(buy)

if buy < len(goods_list):

goods_name = goods_list[buy][0]

goods_price = goods_list[buy][1]

if user_balance >= goods_price:

if goods_name not in shoppingcard:

shoppingcard[goods_name] = {'price':goods_price,'count':1}

else:

# shoppingcard[goods_name] += 1

shoppingcard[goods_name]['count'] += 1

user_balance -= goods_price

cost += goods_price

print('%s 添加购物车成功' %goods_name)

else:

print('余额不足')

else:

print('请选择存在的商品')

elif buy == 'q':

if shoppingcard:

flag,msg = shop.shopping_interface(user_dic['name'],cost,shoppingcard)

if flag:

print(msg)

break

else:

print(msg)

break

else:

print('请输入数字')

@common.login_auth

def check_shoppingcard():

print('查看购物车')

shoppingcart = shop.check_shopingcart_interface(user_dic['name'])

if shoppingcart:

print(shoppingcart)

else:

print('购物车为空')

func_dic = {

'1': register,

'2': login,

'3': check_balance,

'4': transfer,

'5': repay,

'6': withdraw,

'7': check_records,

'8': shopping,

'9': check_shoppingcard

}

def run():

while True:

print('''

1 注册

2 登录

3 查看余额

4 转账

5 还款

6 取款

7 查看流水

8 购物

9 查看购买商品

''')

choice = input('请选择:')

if choice not in func_dic:continue

func_dic[choice]()

View Code

user.py

from db import db_handler

def register_interface(name,password,balance=1500):

user_dic = db_handler.select(name)

if user_dic:

return False,'用户已存在'

else:

user_dic = {

'name': name,

'password': password,

'lockd': False,

'balance': balance,

'credit': balance,

'bankflow': [],

'shoppingcard': {}

}

db_handler.save(user_dic)

return True,'注册成功'

def login_interface(name,password):

user_dic = db_handler.select(name)

if user_dic:

if password == user_dic['password']:

return True,'登录成功'

else:

return False,'密码错误或者已经锁定'

else:

return False,'用户不存在'

View Code

shop.py

from db import db_handler

from interface import bank

def check_shopingcart_interface(name):

user_dic = db_handler.select(name)

return user_dic['shoppingcard']

def shopping_interface(name,cost,shoppingcard):

flag = bank.consume_interface(name,cost)

if flag:

user_dic = db_handler.select(name)

user_dic['shoppingcard'] = shoppingcard

db_handler.save(user_dic)

return True,'购买成功'

else:

return False,'购买失败'

View Code

bank.py

import db.db_handler

from db import db_handler

from lib import common

bank_logger = common.get_logger('bank')

def check_balance_interface(name):

user_dic = db_handler.select(name)

return user_dic['balance']

def transfer_interface(from_name,to_name,account):

to_user_dic = db_handler.select(to_name)

if to_user_dic:

from_user_dic = db.db_handler.select(from_name)

if from_user_dic['balance'] >= account:

from_user_dic['balance'] -= account

to_user_dic['balance'] += account

from_user_dic['bankflow'].append('%s 向 %s 转账 %s'%(from_name,to_name,account))

to_user_dic['bankflow'].append('%s 收到 %s 转账 %s'%(to_name,from_name,account))

db_handler.save(from_user_dic)

db_handler.save(to_user_dic)

return True,'转账成功'

else:

return False,'您的额度不够'

else:

return False,'对方账户不存在'

def repay_interface(name,account):

user_dic = db_handler.select(name)

user_dic['balance'] += account

user_dic['bankflow'].append('还款 %s' %(account))

db_handler.save(user_dic)

bank_logger.info('还款成功')

return True,'还款成功'

def withdraw_interface(name,account):

user_dic = db_handler.select(name)

account = account*1.05

if user_dic['balance'] >= account:

user_dic['balance'] -= account

user_dic['bankflow'].append('取款 %s' % (account))

db_handler.save(user_dic)

return True,'取款成功'

else:

return False,'余额不足'

def check_records_interface(name):

user_dic = db_handler.select(name)

return user_dic['bankflow']

def consume_interface(name,account):

user_dic = db_handler.select(name)

if user_dic['balance'] >= account:

user_dic['balance'] -= account

user_dic['bankflow'].append('消费 %s' % (account))

db_handler.save(user_dic)

return True

else:

return False

View Code

db_handler.py

import os

from conf import setting

import json

def select(name):

path = os.path.join(setting.base_db, '%s,json' %name)

if os.path.exists(path):

with open(path,'r',encoding='utf-8') as f:

return json.load(f)

else:

return None

def save(user_dic):

path = os.path.join(setting.base_db,'%s,json'%user_dic['name'])

with open(path,'w',encoding='utf-8') as f:

json.dump(user_dic,f)

f.flush()

View Code

common.py

import logging.config

from conf import setting

def login_auth(func):

from core import src

def wrapper(*args,**kwargs):

if not src.user_dic['name']:

src.login()

else:

return func(*args,**kwargs)

return wrapper

def get_logger(name):

logging.config.dictConfig(setting.LOGGING_DIC)

my_logger = logging.getLogger(name)

return my_logger

View Code

setting.py

import os

base_dir = os.path.dirname(os.path.dirname(__file__))

base_db = os.path.join(base_dir,'db')

base_log = os.path.join(base_dir,'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):

os.mkdir(base_log)

# log文件的全路径

logfile_path = os.path.join(base_log, 'log.log')

logfile_another = os.path.join(base_log, 'another.log')

# 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': 'INFO',

'propagate': True, # 向上(更高level的logger)传递

},

},

}

View Code

 

查看原文