###################################start.py
import sys,os
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASE_DIR)
from core import src
if __name__ == '__main__':
src.run()
###################################setting.py
import logging,os,sys
import logging.config
BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASE_DIR)
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'
test_format = '%(asctime)s] %(message)s'
# logfile_path = 'a3.log'
logfile_path =os.path.join(BASE_DIR,'log','log.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乱码了
},
# 'other': {
# 'level': 'DEBUG',
# 'class': 'logging.FileHandler', # 保存到文件
# 'formatter': 'test',
# 'filename': 'a2.log',
# 'encoding': 'utf-8',
# },
},
'loggers': {
#logging.getLogger(__name__)拿到的logger配置 空字符串作为键 能够兼容所有的日志
'': {
'handlers': ['default', 'console'], # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
'level': 'DEBUG',
'propagate': True, # 向上(更高level的logger)传递
}, # 当键不存在的情况下 (key设为空字符串)默认都会使用该k:v配置
# 'other': {
# 'handlers': ['other',],
# 'level': 'DEBUG',
# 'propagate': False,
# },
},
}
###################################spc.py
import os, json, hashlib,re,random,sys,logging,time
BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASE_DIR)
from lib import common
# from conf import setting
is_login={'is_login':False}
id_user_dict={}
@common.logger_out
def register():
"""
author:mry
email:。。。。。。。。
date:2023-03-14
:return:
"""
# 身份证
while True:
input_id = input("请输入身份证号:")
# print(re.findall('^(\d{18,18}|\d{15,15}|\d{17,17}x', id))
if re.findall('^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$', input_id) != None:
break
else:
print('错误,重来')
# 姓名
input_name = input("请输入姓名:")
# 手机号
while True:
input_phone = input("请输入手机号:")
if re.findall('^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$', input_phone) != None:
break
else:
print('错误,重来')
# 交易密码
while True:
input_pwd = input("请输入交易密码:")
if re.findall('^\d{6}$', input_pwd) != None:
cryptograph_pwd, res = common.add_code(input_pwd)
break
else:
print('错误,重来')
# 生成卡号
print('正在生成你的卡号.....')
while True:
cardnum = random.randint(0000000000000, 9999999999999)
new_card_id = '621723' + str(cardnum)
# print("test=:", new_card_id)
if common.is_exist(new_card_id)==0:
print("你的卡号:", new_card_id)
break
# 生成用户字典
id_user_dict={"卡号":new_card_id,"交易密码":cryptograph_pwd,"校验码":res,"身份证号码":input_id,"姓名":input_name,"手机号":input_phone,"余额":1500.00,"locked":False, "flow": [], "shopping_car": {}}
write_file('add',new_card_id, id_user_dict)
print('恭喜哦,称为我们的会员了!!!')
# 记录日志
return('%s身份证号码为%s,注册了一张卡号为%s的卡,余额为%s'%(id_user_dict.get('姓名'),id_user_dict.get('身份证号码'),id_user_dict.get('卡号'),id_user_dict.get('余额')))
@common.logger_out
def login():
if is_login['is_login']:
print('已经登录')
return
# 输入并校验卡号
while True:
input_card_id=input("请输入银行卡号:")
if common.is_exist(input_card_id):
break
else:
print('错误,重来')
id_user_dict = read_file(input_card_id)
if id_user_dict["locked"]:
print('账户已经锁定,请联系管理员')
return
# 输入并校验密码
lock_cont=1
while True:
input_pwd=input("请输入密码:")
res=id_user_dict.get('校验码')
pwd = input_pwd + res
md5 = hashlib.md5()
md5.update(pwd.encode('utf-8'))
cryptograph_pwd = md5.hexdigest()
if id_user_dict.get('交易密码')==cryptograph_pwd:
print('成功登录')
break
else:
lock_cont +=1
if lock_cont>3:
id_user_dict["locked"]=True
write_file('modify',input_card_id,id_user_dict)
print('输错超过3次,账户已经锁定,请联系管理员')
return("卡号为%s密码输错超过3次,账号锁定" % input_card_id)
else:
common.logger.info("卡号为%s尝试登录,密码错误" % input_card_id)
print('错误,重来')
# 修改登录状态
# global is_login
is_login['is_login']=True
# 检测并获得相应权限
# super_purview['super_purview']=id_employee_dict.get('权限')
return id_user_dict.get('姓名')+"银行卡号为"+id_user_dict.get('卡号')+'登录了系统'
#提现
@common.logger_out
@common.login_auth
def withdraw():
money=float(id_user_dict.get('余额'))
print('你的余额为:',money)
while True:
withdraw_money=input('请输入提现金额:').strip()
if not common.if_money(withdraw_money):
print('错误,重来')
continue
withdraw_money=float(withdraw_money)
service_charge=int(withdraw_money)*0.05
if (service_charge+withdraw_money)<=money:
money=money-(service_charge+withdraw_money)
print('提现成功,剩余%s元'%money)
id_user_dict['余额'] = money
write_file('modify', id_user_dict.get('卡号'), id_user_dict)
id_user_dict['flow'].append("%s,提现%s元,手续费%s,余额%s元" % (
time.strftime('%y-%m-%d %X'), withdraw_money, service_charge, id_user_dict.get('余额')))
# print(id_user_dict['flow'])
write_file('modify', id_user_dict.get('卡号'), id_user_dict)
return "%s提现%s元,手续费%s,余额%s元" % ( id_user_dict.get('卡号'),withdraw_money, service_charge, id_user_dict.get('余额'))
break
else:print("提现金额+手续费大于余额,重新输入")
@common.logger_out
@common.login_auth
def transfer():
money = float(id_user_dict.get('余额'))
print('你的余额为:', money)
# 输入并校验卡号
while True:
input_transfer_id=input("请输入需要转入的银行卡号:")
if common.is_exist(input_transfer_id) and input_transfer_id!=id_user_dict.get('卡号'):
break
else:
print('错误,重来')
# 输入转入金额
while True:
transfer_money=input('请输入转入金额:').strip()
# 检验是否数值
if not common.if_money(transfer_money):
print('错误,重来')
continue
transfer_money=float(transfer_money)
# service_charge=int(withdraw_money)*0.05
if transfer_money<=money:
money=money-transfer_money
print('转账成功,剩余%s元'%money)
id_user_dict['余额'] = money
#
write_file('modify', id_user_dict.get('卡号'), id_user_dict)
# 记录当前用户流水
id_user_dict['flow'].append("%s,向卡号%s转账%s元,余额%s元"%(time.strftime('%y-%m-%d %X'), input_transfer_id,transfer_money, id_user_dict.get('余额')))
write_file('modify', id_user_dict.get('卡号'), id_user_dict)
#
# id_transfer_dict=read_file(input_transfer_id)#当前代码逻辑与其他冲突
with open(BASE_DIR+'\\db\\'+input_transfer_id+'.json', 'r', encoding='utf-8') as f:
id_transfer_dict = json.load(f)
transfer_old_money=float(id_transfer_dict.get('余额'))
transfer_new_money=transfer_old_money+transfer_money
id_transfer_dict['余额'] = transfer_new_money
#
write_file('modify', id_transfer_dict.get('卡号'), id_transfer_dict)
# 记录被转入流水
print('2测试当前用户id_user_dict',id_user_dict.get('卡号'))#出现错误,变成了被转的id
id_transfer_dict['flow'].append("%s,卡号%s转入%s元,余额%s元"%(time.strftime('%y-%m-%d %X'),id_user_dict.get('卡号'), transfer_money, id_transfer_dict.get('余额')))
write_file('modify', id_transfer_dict.get('卡号'), id_transfer_dict)
return ("%s,向卡号%s转账%s元,余额%s元"%( id_user_dict.get('卡号'), input_transfer_id,transfer_money, id_user_dict.get('余额')))
break
else:print("转账金额大于余额,重新输入")
@common.logger_out
@common.login_auth
def pay():
money = float(id_user_dict.get("余额"))
print('你的余额为:', money)
# 检验是否数值
while True:
pay_money = input('请输入充值金额:').strip()
# 检验是否数字
if not common.if_money(pay_money):
print('错误,重来')
continue
pay_money= float(pay_money)
# print('测试pay_money数据类型',type(pay_money))
break
money+=pay_money
id_user_dict['余额'] = money
write_file('modify', id_user_dict.get('卡号'), id_user_dict)
id_user_dict['flow'].append("%s,充值%s元,余额%s元"% (time.strftime('%y-%m-%d %X'), pay_money , id_user_dict.get('余额')))
write_file('modify', id_user_dict.get('卡号'), id_user_dict)
print('余额为:',id_user_dict.get('余额'))
return ("%s,充值%s元,余额%s元" % (id_user_dict.get('卡号'), pay_money, id_user_dict.get('余额')))
@common.logger_out
@common.login_auth
def check_money():
money = float(id_user_dict.get('余额'))
print('你的余额为:', money)
return ("卡号为%s,执行了余额查询" % (id_user_dict.get('卡号')))
@common.logger_out
@common.login_auth
def check_flow():
print(id_user_dict.get('卡号'))
print(id_user_dict.get('flow'))
return ("卡号为%s,执行了流水查询" % (id_user_dict.get('卡号')))
# @common.logger_out
@common.login_auth
def add_shopping():
# 打印商品列表
print('编号:商品名 价格')
for d in shopping_dict:
print(d,shopping_dict[d])
while True:
choose=input('请输入商品编号(q返回上一级):').strip()
# 获取该编号的商品名
input_shopping_name=shopping_dict.get(choose)[0]
print('您选择的是',input_shopping_name)
if choose=="q":return
elif choose in shopping_dict:
shopping_car_dict=id_user_dict.get("shopping_car")
# print("购物车商品、数量、单价:",shopping_car_dict)
input_num=input('请输入加购%s商品数量'%input_shopping_name).strip()
#判断商品是否存在购物车
# 如果在
if input_shopping_name in shopping_car_dict:
# 取出数量
oldnum=shopping_car_dict.get(input_shopping_name)[0]
shopping_car_dict.get(input_shopping_name)[0]=oldnum+int(input_num)
print(id_user_dict.get("shopping_car"))
write_file('modify',id_user_dict.get('卡号'),id_user_dict)
print(input_num)
# common.logger.info(f"func:{'卡号为%s,执行了添加%s商品%s件到购物车' % (id_user_dict.get('卡号'),input_shopping_name,input_num)}")
### common.logger.info('卡号为%s,执行了添加%s商品%s件到购物车' % (id_user_dict.get('卡号'),input_shopping_name,input_num))
# 如果不在
else:
shopping_car_dict.update({input_shopping_name:[int(input_num),float(shopping_dict.get(choose)[1])]})
write_file('modify', id_user_dict.get('卡号'), id_user_dict)
else:
print('重输')
continue
common.logger.info('卡号为%s,执行了添加%s商品%s件到购物车' % (id_user_dict.get('卡号'), input_shopping_name, input_num))
# return
@common.logger_out
@common.login_auth
def check_shopping():
print('这是我的购物车')
shopping_car_dict=id_user_dict.get("shopping_car")
# print(shopping_car_dict)
print('商品名\t数量\t单价 \t总价')
sum=0
for each_shop,j in shopping_car_dict.items():
each_sum=int(j[0])*float(j[1])
print(" %s\t%s\t%s \t%s"%(each_shop,j[0],j[1],each_sum))
sum+=each_sum
print('全部金额总价:',sum)
return ("卡号为%s,执行了查询购物车" % (id_user_dict.get('卡号')))
def read_file(card_id):
# path1=os.path.abspath(os.path.join(os.path.abspath('core'), "..\\.."))
file_path=BASE_DIR+'\\db\\'+card_id+'.json'
# print(file_path)
with open(file_path,'r',encoding='utf-8') as f:
global id_user_dict
id_user_dict=json.load(f)
return id_user_dict
def write_file(doing,card_id,*args):
if doing=='add':
# arg接收了用户字典
with open(os.path.join(BASE_DIR, "db", card_id + '.json'), 'w', encoding='utf-8') as f:
json.dump(args[0],f,ensure_ascii=False)# ensure_ascii=False,不然,默认是True,会转为万国码
print('存储成功')
elif doing=='delete':
os.remove(os.path.join(BASE_DIR, "db", card_id + '.json'))
# with open(os.path.join(path1, "db", employee_id + '.txt'), 'w', encoding='utf-8') as f:
elif doing=='modify':
with open(os.path.join(BASE_DIR, "db", card_id + '.json'), 'w', encoding='utf-8') as f:
json.dump(args[0], f, ensure_ascii=False) # ensure_ascii=False,不然,默认是True,会转为万国码
print('存储成功')
func_dict = {
'1': register,
'2': login,
'3': withdraw,
'4': transfer,
'5': pay,
'6': check_money,
'7': check_flow,
'8': add_shopping,
'9': check_shopping,
}
shopping_dict = {
'1': ['苹果',8],
'2': ['香蕉',4],
'3': ['菠萝',5],
'4': ['樱桃',50],
'5': ['草莓',12],
'6': ['猕猴桃',5],
'7': ['芒果',6],
'8': ['葡萄',7],
'9': ['橘子',3],
}
def menu():
print("""------------------欢迎使用ATM自助系统---------------------------
\t 1. 注册功能\t\t 6. 查看余额
\t 2. 登录功能\t\t 7. 查看流水
\t 3. 提现功能(5%的手续费)\t 8. 添加购物车
\t 4. 转账功能\t\t 9. 查看购物车
\t 5. 充值功能\t\t 0. 退出
-------------------------------------------------------------
""")
def run():
while True:
menu()
cmd = input('输入选项').strip()
if not cmd: continue
if cmd in func_dict:
func_dict.get(cmd)()
elif cmd == '0':
break
else:
print('重来')
###################################common.py
import os,re,sys,random,logging,hashlib,datetime
BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
print(BASE_DIR)
sys.path.append(BASE_DIR)
from conf import setting
from core import src
# 读取卡号字典
def card_id_list():
file_list=os.listdir(BASE_DIR+'\\db')
card_id=[]
for file_name in file_list:
id=re.findall(('(.+).json'),file_name)
if id!=[]:
card_id.append(id[0])
return card_id
# 判断卡号是否存在,存在1,不存在0
def is_exist(new_card_id):
print("测试卡号是否存在new_card_id=",new_card_id)
# for card_id in card_id_list():
# if new_card_id==card_id:return 1
# else:return 0
if os.path.exists(BASE_DIR+'\\db\\'+new_card_id+'.json'):
print('卡号存在')
return 1
else:return 0
# 动态加盐
def add_code(input_employee_pwd):
res=get_code(5)
pwd=input_employee_pwd +res
md5 = hashlib.md5()
md5.update(pwd.encode('utf-8'))
cryptograph_pwd=md5.hexdigest()
# print("测试,密文=",cryptograph_pwd)
return cryptograph_pwd,res
# 产生随机数
def get_code(n):
code = '' # 存储生成的随机验证码
# 6位的验证码
for i in range(n):
random_int = str(random.randint(0, 9))# 1. 产生0-9之间的任意一个数据
random_upper = chr(random.randint(65, 90)) # A-Z# 2. 产生大写字母
random_lower = chr(random.randint(97, 122)) # a-z# 3. 产生小写字母
temp = random.choice([random_int, random_lower, random_upper])# 4. 要从以上三种情况中随机选出一个字符来
code += temp
return code
''''''
logger= logging.getLogger(__name__)
# formatter = logging.Formatter('%(asctime)s - [%(levelname)s]-%(message)s')
chlr = logging.StreamHandler()
# chlr.setFormatter(formatter)
logger.addHandler(chlr)
def logger_out(func):
def get_logger(*args,**kwargs):
#日志加载和记录
# timestamp = datetime.datetime.now().strftime('%Y-%m-%d %X')
logging.config.dictConfig(setting.LOGGING_DIC) # 自动加载字典中的配置
res = func(*args,**kwargs)
# logger.info(f"func:{func.__name__}{args}->{res}")
logger.info({res})
# return res
return get_logger
#判断输入的是不是数值(含小数)
def if_money(money):
if money=='0':return 0
elif re.findall("(^[\-0-9][0-9]*(.[0-9]+)?)$",money)!=[]:
# print("测试,经过校验,是数字")
return 1
# elif money.isdigit():return 1
else:
# print("测试,经过校验,不是数字")
return 0
# re.findall("\d+.?\d+?",money)
# 装饰器登录状态检测
def login_auth(func):
def auth(*args,**kwargs):
if src.is_login.get('is_login'):
res = func(*args,**kwargs)
return res
else:
print('未登录,请先登录')
while 1:
cmd=input('1.登录 2.注册')
if cmd=='1':
src.login()
break
elif cmd=='2':
src.register()
print('注册成功,请登录')
src.login()
break
else:
print('好好输入')
return auth