目录
conf.setting.py
'''
配置信息
'''
import os
BASE_PAHT = os.path.dirname(os.path.dirname(__file__))
DB_PATH = os.path.join(BASE_PAHT,'db')
USER_DATA_PATH = os.path.join(DB_PATH,'user_data')
COMMODITY_PAHT = os.path.join(DB_PATH,'commodity.txt')
LOPGFILE_DIR_PATH = os.path.join(BASE_PAHT,'log','log_data')
LOGFILE_LOG_PATH = os.path.join(LOPGFILE_DIR_PATH, 'log.log')
core.src.py
'''
用户视图层
'''
from interface import user_interface
from interface import bank_interface
from interface import shop_interface
from interface import admin_interface
from lib import common
login_user = None
#注册
@common.log_write('注册')
def register():
while True:
username = input("请输入账号:").strip()
password = input("请输入密码:").strip()
re_password = input("请再次输入密码:").strip()
#小的逻辑处理,比较两次密码是否一致
if password == re_password:
# 调用接口层的注册借口,把用户名和密码传给接口层来处理
#flag = True 注册成功,flag= False 注册失败
flag,msg = user_interface.register_interface(username,password)
if flag:
print(msg)
break
else:
print(msg)
#登录
@common.log_write('登录')
def login():
while True:
username = input("请输入你的用户名:").strip()
password = input("请输入你的密码:").strip()
flag,msg = user_interface.login_interface(username,password)
if flag:
print(msg)
global login_user
login_user = username
return
else:
print(msg)
#查看余额
@common.login_auth
@common.log_write('查看余额')
def check_balance():
balance = user_interface.check_balance_interface(login_user)
print(f'{login_user}余额为:{balance}')
#提现
@common.login_auth
@common.log_write('提现')
def withdraw():
money_inp = input("请输入提现的金额:").strip()
if not money_inp.isdigit():
print("请重新输入!")
# money_inp = int(money_inp)
flag,msg = bank_interface.withdraw_interface(login_user,money_inp)
if flag:
print(msg)
else:
print(msg)
#还款
@common.login_auth
@common.log_write('还款')
def repay():
money = input("请输入你要充值的金额:")
if money.isdigit():
msg = bank_interface.repay_interface(login_user,money)
print(msg)
else:
print("请输入正确金额!")
#转账
@common.login_auth
@common.log_write('转账')
def transfer():
other_user = input("请输入收账人用户名:").strip()
money = input("请输入转账金额:").strip()
flag,msg = bank_interface.transfer_interface(login_user,other_user,money)
if flag:
print(msg)
else:
print(msg)
#查看流水
@common.login_auth
@common.log_write('查看流水')
def check_flow():
msg = bank_interface.check_flow_interface(login_user)
print(msg)
#购物
@common.login_auth
@common.log_write('购物')
def shopping():
while True:
shop_list = common.shop_msg()
for num in shop_list:
print(f'序号:{num} 名称:{shop_list[num][0]} 价格:{shop_list[num][1]}')
num_buy = input("请输入你要购买商品的序号(q退出):")
if num_buy in shop_list:
count_buy = input("请输入你要购买的商品的数量(q退出):")
flag,msg = shop_interface.shopping_interface(login_user,shop_list[num_buy],count_buy)
if flag:
print(msg)
else:
print(msg)
elif num_buy == 'q':
break
else:
print("请输入正确指令!")
#查看购物车
@common.login_auth
@common.log_write('查看购物车')
def check_shop_car():
while True:
shop_car_dic = common.shop_car_msg()
count = 0
shop_num_dic= {}
for name in shop_car_dic:
count+=1
print(f"商品序号:{count} 商品名称:{name} 单价:{shop_car_dic[name]['单价']} 数量:{shop_car_dic[name]['数量']} 总价格:{shop_car_dic[name]['总价格']}")
shop_num_dic[count] = name
if count == 0:
print(f'{login_user}的购物车是空的!')
return
num_buy = input("请输入你要支付的商品序号(q退出):").strip()
if 0<int(num_buy)<=count :
falg,msg = shop_interface.check_shop_car_interface(login_user,shop_num_dic[int(num_buy)],shop_car_dic[shop_num_dic[int(num_buy)]]['总价格'])
if falg:
print(msg)
else:
print(msg)
elif num_buy == 'q':
return
else:
print('请输入正确指令!')
#管理员功能
@common.log_write('管理员登录')
def admin():
admin_dic = {
"1":register,
"2":admin_update_bal,
"3":admin_lock
}
admin_name = input("请输入管理员用户名:")
admin_pwd = input("请输入管理员密码:")
flag,msg = admin_interface.admin_login_interface(admin_name,admin_pwd)
if flag:
print(msg)
while True:
print('''
*******管理员界面*******
1 添加用户
2 修改用户余额
3 冻结用户
''')
cmd = input("请输入你要执行的功能(q退出):")
if cmd in admin_dic:
admin_dic[cmd]()
elif cmd == 'q':
print(f'{admin_name}已退出!')
return
else:
print("请输入正确指令!")
else:
print(msg)
#登录管理员账号,只存账号密码
#userinter里添加管理员功能
#1 添加账号 == 注册
#2 冻结用户 输入用户名,修改该用户名的locked=True 或者解冻
#3 修改用户余额 输入用户名,输入新的账号金额信息,保存用户
#管理员修改用户余额
@common.log_write('修改余额')
def admin_update_bal():
username = input("请输入你要修改的用户名:")
balance = input("请输入该用户新的余额:")
msg = admin_interface.admin_update_bal_interface(username,balance)
print(msg)
#管理员冻结用户
@common.log_write('冻结用户')
def admin_lock():
username = input("请输入你要冻结或者解冻的账号:")
flag,msg = admin_interface.admin_lock_interface(username)
if flag:
print(msg)
else:
print(msg)
func_dic = {
'1':register,
'2':login,
'3':check_balance,
'4':withdraw,
'5':repay,
'6':transfer,
'7':check_flow,
'8':shopping,
'9':check_shop_car,
'10':admin,
}
def run():
while True:
print('''
===== ATM + 购物车 =====
1、注册功能
2、登录功能
3、查看余额
4、提现功能
5、还款功能
6、转账功能
7、查看流水
8、购物功能
9、查看购物车
10、管理员功能
======== end =========
''')
choice = input("请输入编号:")
if choice not in func_dic:
print("请输入正确的功能编号!")
continue
else:
func_dic[choice]()
db.db_handler.py
'''
数据处理层
-专门用来处理数据的
'''
import json
import os
from conf import settings
#查找用户是否存在
def select(username):
user_path = os.path.join(settings.USER_DATA_PATH, f"{username}.json")
#效验文件是否存在
if os.path.exists(user_path):
with open(user_path, "r", encoding="utf-8") as f:
user_dic = json.load(f)
return user_dic
#保存用户数据
def save(user_dic):
username = user_dic.get('username')
user_path = os.path.join(settings.USER_DATA_PATH, f"{username}.json")
with open(user_path,"w",encoding="utf-8")as f:
# ensure_ascii=False 让json文件中的中文数据变成中文
json.dump(user_dic,f,ensure_ascii=False)
#修改用户数据
def update(username,old_msg,new_msg):
pass
interface.admin_interface
from db import db_handler
from lib import common
#管理员登录接口
def admin_login_interface(username,password):
user_dic = db_handler.select(username)
if user_dic:
password = common.get_pwd_md5(password)
if user_dic['password'] == password:
return True,f'超级管理员{username}登录成功!'
else:
return False,f'管理员{username}密码错误!'
else:
return False,"不存在该管理员用户!"
#修改用户余额接口
def admin_update_bal_interface(username,balance):
user_dic = db_handler.select(username)
user_dic['balance'] = balance
db_handler.save(user_dic)
return f'{username}余额修改成功!'
#冻结用户接口
def admin_lock_interface(username):
user_dic = db_handler.select(username)
if user_dic['locked'] :
user_dic['locked'] = False
db_handler.save(user_dic)
return True,f'{username}账号解冻成功!'
else:
user_dic['locked'] = True
db_handler.save(user_dic)
return False,f'{username}账号冻结成功!'
interface.bank_interface
'''
银行相关业务的接口
'''
import time
from db import db_handler
#提现金额接口 手续费5%
def withdraw_interface(username,money):
user_dic = db_handler.select(username)
balance = int(user_dic['balance'])
money2=int(money)*1.05
if balance>=money2:
balance -= money2
user_dic['balance']=balance
now_time = time.strftime('%Y-%m-%d-%X')
user_dic['flow'].append(f'{now_time}:提现{money}')
db_handler.save(user_dic)
return True,f'{username}提现{money}元成功!'
else:
return False,'提现金额不足,提现失败!'
#还款接口
def repay_interface(username,money):
user_dic = db_handler.select(username)
balance = int(user_dic['balance'])
balance += int(money)
user_dic['balance'] = balance
now_time = time.strftime('%Y-%m-%d-%X')
user_dic['flow'].append(f'{now_time}:充值{money}')
db_handler.save(user_dic)
return f'{username}充值{money}成功!'
#转账接口
def transfer_interface(my_user,outher_user,money):
my_user_dic = db_handler.select(my_user)
outher_user_dic = db_handler.select(outher_user)
if outher_user_dic:
my_balance = int(my_user_dic['balance'])
money = int(money)
if my_balance>=money:
#对转账人减钱
my_balance-=money
my_user_dic['balance'] = my_balance
now_time = time.strftime('%Y-%m-%d-%X')
my_user_dic['flow'].append(f'{now_time}:转出{money}')
db_handler.save(my_user_dic)
#对收账人加钱
outher_user_balance = int(outher_user_dic['balance'])
outher_user_balance+=money
outher_user_dic['balance'] =outher_user_balance
outher_user_dic['flow'].append(f'{now_time}:收账{money}')
db_handler.save(outher_user_dic)
return True,f'转账成功,{my_user}给{outher_user}转账{money}!'
else:
return False,f'{my_user}余额不足!'
else:
return False,f'{outher_user}不存在!'
#查看流水接口
def check_flow_interface(username):
user_dic = db_handler.select(username)
return user_dic['flow']
interface.shop_interface
'''
购物商场接口
'''
import time
from lib import common
from db import db_handler
#购物功能接口
def shopping_interface(username,shop_list,count):
# 1 添加流水信息,扣除用户余额
user_dic = db_handler.select(username)
price = int(shop_list[1])
count = int(count)
user_dic['shop_car'][f"{shop_list[0]}"]={'单价':f'{shop_list[1]}','数量':f'{count}','总价格':f'{price*count}'}
db_handler.save(user_dic)
return True,f'已成功添加至{username}的购物车'
#购物车接口
def check_shop_car_interface(username,shop_name,price):
# 接收src中支付的序号,修改用户信息
user_dic = db_handler.select(username)
balance = int(user_dic['balance'])
price = int(price)
if balance>=price:
balance -= price
user_dic['balance'] = balance
now_time = time.strftime('%Y-%m-%d-%X')
user_dic['flow'].append(f'{now_time}:购物支出{price}')
user_dic['shop_car'].pop(f'{shop_name}')
db_handler.save(user_dic)
return True,f'用户{username}支付成功!'
else:
return False,f'用户{username}余额不足!'
interface.user_interface
'''
用户
逻辑接口层
'''
from lib import common
from db import db_handler
# 注册接口
def register_interface(username,password,balance=15000):
# 判断用户是否存在
user_dic = db_handler.select(username)
# 如果用户存在
if user_dic:
return False,'用户名已存在' # == >(False,'')
password = common.get_pwd_md5(password)
user_dic = {
'username': username,
'password': password,
'balance': balance,
# 记录用户的流水信息
'flow': [],
# 记录购物车信息
'shop_car': {},
# 记录用户是否被冻结 False:未冻结 True:冻结
'locked': False
}
# 如果用户不存在则注册
db_handler.save(user_dic)
return True,f'用户{username}注册成功!'
# 登录接口
def login_interface(username,password):
user_dic = db_handler.select(username)
if user_dic:
if not user_dic['locked']:
password = common.get_pwd_md5(password)
if user_dic['password'] == password:
return True,f'用户{username}登录成功!'
else:
return False,f'用户{username}密码错误!'
else:
return False,f'用户{username}被冻结,无法登录!'
else:
return False,f'登录失败'
# 查询余额接口
def check_balance_interface(username):
user_dic = db_handler.select(username)
return user_dic['balance']
lib.common.py
'''
公共函数
'''
import hashlib
from logging import config,getLogger
from log import log
from conf import settings
from db import db_handler
#密码加密
def get_pwd_md5(password):
md5_obj = hashlib.md5()
md5_obj.update(password.encode('utf-8'))
salt = 'asdjasuidfhafuigawhniordfq'
md5_obj.update(salt.encode('utf-8'))
return md5_obj.hexdigest()
#登录认证装饰器
def login_auth(func):
from core import src
def inner(*args,**kwargs):
if src.login_user:
res = func(*args,**kwargs)
return res
else:
print("未登录,请先登录!")
src.login()
return inner
#查找商品信息
def shop_msg():
with open(settings.COMMODITY_PAHT,"r",encoding="utf-8")as f :
shop_dic = {}
for line in f :
num,name,price = line.strip().split(":")
shop_dic[num] = [name,price]
return shop_dic
#查看购物车信息
def shop_car_msg():
from core import src
user_dic = db_handler.select(src.login_user)
return user_dic['shop_car']
#日志装饰器
def log_write(type):
def wrapper(func):
def inner():
from core import src
config.dictConfig(log.LOGGING_DIC)
func()
if src.login_user == None:
logger1 = getLogger('游客')
logger1.info('游客产生的info信息')
else:
logger1 = getLogger(f'{src.login_user}')
logger1.info(f'{src.login_user}执行了{type}')
return inner
return wrapper
log.log.py
import os
import logging.config
from conf import settings
# 定义三种日志输出格式 开始
standard_format = '[%(asctime)s][用户:%(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 = settings.LOPGFILE_DIR_PATH
# log文件的目录
logfile_name = 'all2.log' # log文件名
# 如果不存在定义的日志目录就创建一个
if not os.path.isdir(logfile_dir):
os.mkdir(logfile_dir)
# log文件的全路径
logfile_path = settings.LOGFILE_LOG_PATH
# 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,
# 日志大小 5M
'maxBytes': 1024 * 1024 * 5,
# 日志轮转:最大日志文件数量5
'backupCount': 5,
# 日志文件的编码,再也不用担心中文log乱码了
'encoding': 'utf-8',
},
},
# 日志制造者
'loggers': {
# logging.getLogger(__name__)拿到的logger配置
# 如果没有名字的话,名字在其他文件调用时自动传入
'': {
# 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
'handlers': ['default'],
# 第一层level,筛选后再去handlers里筛选,通常一样
'level': 'DEBUG',
# 向上(更高level的logger)传递,通常为false
'propagate': True,
},
},
}