1、作业需求:
模拟实现一个ATM + 购物商城程序
额度 15000或自定义
实现购物商城,买东西加入 购物车,调用信用卡接口结账
可以提现,手续费5%
支持多账户登录
支持账户间转账
记录每月日常消费流水
提供还款接口
ATM记录操作日志
提供管理接口,包括添加账户、用户额度,冻结账户等。。。
用户认证用装饰器
2、流程图

3、目录结构
|——员工信息查询系统 |——bin目录 | |—— _init.py | |__ Stary.py(开始程序) | |——core目录 | |—— __init__.py | |—— main.py(主模块程序) | |—— auth.py(登录认证程序) | |——db目录 | |—— shop_car(购物车文件目录) | |——XXX.txt(购物车文件) | |__ user_info(用户数据) | |——XXX.json(用户信息数据) |——log目录 | |—— card_log(信用卡日志目录) | |——XXX.log(信用卡日志文件) | |__ shop_log(购物日志目录) | |——XXX.log(购物日志文件) |——modules目录 | |—— __init__.py | |—— admincenter.py(管理中心程序) | |—— creditcard.py(信用卡程序) | |—— shopping.py(购物商城程序) |__ __init.py__
4、core目录
auth.py(登录认证模块)
#-*- Coding:utf-8 -*-
# Author: D.Gray
import os,sys
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASE_DIR)
def accse_login(user_data):
'''
定义一个用户登录装饰器
:param user_data:
:return:
'''
def out_wrapper(func): #func接收 admin_info,shop_info,admin_info函数的返回值
def wrapper(*args,**kwargs):
count = 0
if not user_data['is_authenticated'] and count < 3:
print("33[32;0m用户登录认证33[0m".center(40, "-"))
while count < 3:
user = input(' 33[32;1m请输入用户名>>>: 33[0m')
db_path = BASE_DIR + r'dbuser_info'
db_path_user = db_path + '\%s.json' % user
if os.path.isfile(db_path_user): #判断用户文件是否存在
with open(db_path_user, 'r', encoding='utf-8') as fh:
user_datas = eval(fh.read()) #将用户文件中内容转换为字典形式
pwd = input(' 33[32;1m请输入用户密码>>>: 33[0m')
if pwd == user_datas['password']:
user_data['account_id'] = user_datas["cardid"]
user_data['is_authenticated'] = True
user_data['account_data'] = user_datas
break
else:
print(' 33[31;1m密码错误请重新输入 33[0m')
else:
count += 1
print(' 33[31;1m该用户不存在,请重新输入还剩 %s 次机会 33[0m'% (3-count))
func(*args,**kwargs)
return func
return wrapper
return out_wrapper
mian.py(主模块程序)
#-*- Coding:utf-8 -*-
# Author: D.Gray
import sys,os
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASE_DIR)
from core import auth
from modules import creditcard
from modules import shopping
from modules import admincenter
#用户数据信息
user_data = {
'account_id':None, #帐号ID
'is_authenticated':False, #是否认证
'account_data':None #帐号数据
}
def run():
'''
定义一个主界面函数
:return:
'''
while True:
print(''' 33[35;1m ************欢迎来到ATM电子商务淫行************
1.信用卡中心
2.购物中心
3.管理中心
4.退出 33[0m''')
inputs = input(' 33[35;1m请选择操作方式>>>: 33[0m').strip()
dict = {
'1':card_info,
'2':shop_info,
'3':admin_info
}
if inputs in dict.keys():
dict[inputs]()
elif inputs == '4':
exit('程序退出 欢迎下次使用')
else:
print(' 33[31;1m请输入有效操作方式 33[0m')
def admin_info():
'''
定义一个管理员权限用户主函数
:return:
'''
auth_user() #调用用户认证接口
if user_data['account_data']['type'] == 1:
while True:
print(''' 33[35;1m ---------------欢迎 %s 来到信用卡管理中心---------------
1. 发行信用卡
2. 冻结信用卡
3. 解冻信用卡
4. 提升信用卡额度
5. 返回主菜单
6. 退出 33[0m'''%user_data['account_data']["username"])
inputs = input(' 33[35;1m请选择操作方式1>>>: 33[0m').strip()
menu_dic = {
"1": admincenter.banks,
"2": admincenter.freezing,
"3": admincenter.defrosting,
"4": admincenter.limit,
}
if inputs in menu_dic.keys():
menu_dic[inputs](user_data['account_data'])
elif inputs == '5':
break
elif inputs == '6':
exit('程序退出 欢迎下次使用')
else:
print(' 33[31;1m请输入有效操作方式 33[0m')
else:
exit('对不起您的账号权限不足无法登录该模块')
def shop_info():
'''
定义一个用户购物的主函数
:return:
'''
auth_user() #调用用户认证接口
while True:
print(''' 33[35;1m ---------------欢迎来到购物中心---------------
1.购物商城
2.查看购物车
3.查看购物记录
4.返回主菜单
5.退出 33[0m''')
menu_dic = {
'1':shopping.shopping,
'2':shopping.shop_car,
'3':shopping.center
}
inputs = input(' 33[35;1m请选择操作方式>>>: 33[0m').strip()
if inputs in menu_dic.keys():
menu_dic[inputs](user_data['account_data'])
elif inputs == '4':
break
elif inputs == '5':
exit('程序退出 欢迎下次使用')
else:
print(' 33[31;1m请输入有效操作方式 33[0m')
def card_info():
'''
定义一个信用卡管理中心的主函数
:return:
'''
auth_user() #调用用户认证接口
while True:
print(''' 33[35;1m ---------------欢迎 %s 来到信用卡中心---------------
1. 账户信息
2. 存款
3. 提现
4. 转账
5. 账单
6. 返回主菜单
7. 退出
33[0m'''%user_data['account_data']["username"])
user_account = user_data['account_data']
inputs = input(' 33[35;1m请选择操作方式1>>>: 33[0m').strip()
menu_dic = {
"1": creditcard.account_info,
"2": creditcard.repay,
"3": creditcard.withdraw,
"4": creditcard.transfer,
"5": creditcard.paycheck,
}
if inputs in menu_dic.keys():
menu_dic[inputs](user_account)
elif inputs == '6':
break
elif inputs == '7':
exit('程序退出 欢迎下次使用')
else:
print(' 33[31;1m请输入有效操作方式 33[0m')
@auth.accse_login(user_data) #装饰器认证
def auth_user():
'''
调用 auth模块中的accse_login装饰器对用户进行登录认证
:return:
'''
print(' 33[32;1m用户 %s 登录认证成功 33[0m' % user_data['account_data']["username"])
5、db(数据库)
{
"status":1,
"expire_date": "2021-01-01",
"credit":5500,
"pay_day":22,
"balance":9028,
"enroll_date": "2016-01-02",
"cardid":1112,
"password": "123456",
"username": "admin",
"type":1,
"cardname":"招商银行-星耀"
}
IPhone 1299 IWatch 2999 MacBo 1999 IPad 2199 Bicyc 999 X-box 1199 Letv 819 Book 599
6、log(日志目录)
#-*- Coding:utf-8 -*-
# Author: D.Gray
import logging,sys,os
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASE_DIR)
def card_log(username,log):
'''
定义一个信用卡日志函数
:return:
'''
log_path = BASE_DIR+r'logcard_log\%s_card.log'%username
logger = logging.getLogger('Test_LOG')
logger.setLevel(logging.INFO)
fh = logging.FileHandler(log_path,encoding='utf-8') #将日志打印到log目录下的日志文件中
fh.setLevel(logging.INFO)
fh_format = logging.Formatter('%(asctime)s %(message)s',datefmt='%m/%d/%Y %H:%M:%S')
fh.setFormatter(fh_format)
logger.addHandler(fh)
logger.info(log)
logger.removeHandler(fh) #避免打印重复日志
def shop_log(username,log):
'''
定义一个购物日志函数
:param username:
:param log:
:return:
'''
log_path = BASE_DIR + r'logshop_log\%s_shop.log' % username
logger = logging.getLogger('Test_LOG')
logger.setLevel(logging.INFO)
fh = logging.FileHandler(log_path,encoding='utf-8')
fh.setLevel(logging.INFO)
fh_format = logging.Formatter('%(asctime)s %(message)s', datefmt='%m/%d/%Y %H:%M:%S')
fh.setFormatter(fh_format)
logger.addHandler(fh)
logger.info(log)
logger.removeHandler(fh)
7、modules(模块程序)
admincenter.py
#-*- Coding:utf-8 -*-
# Author: D.Gray
import os,sys,logging
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASE_DIR)
db_path = BASE_DIR + r'dbuser_info'
def banks(account):
'''
定义一个查询发行信用卡函数
:param account:
:return:
'''
print(' 33[33;1m尊敬的用户您的发行信用卡是 【%s】'
'
卡号为:%s 开户日期为:%s 信用卡有效期至:%s'
'
我们将会真挚的为您服务!!!'
%(account['cardname'],account["cardid"],account["enroll_date"],account["expire_date"]))
def freezing(account):
'''
定义一个冻结信用卡函数
:return:
'''
db_path_user = db_path+'\%s.json'%account['username']
with open(db_path_user,'r',encoding='utf-8') as fh:
fr = fh.read()
fd = eval(fr)
if fd['status'] == 0:
print(' 33[31;1m当前信用卡 【已冻结】 33[0m')
if fd['status'] == 1:
free = input(' 33[33;1m当前信用卡 【未冻结】 按任意键选择冻结 按b返回>>>