sailan
项目目录
代码
# start.py
import os
import sys
# 配置启动文件的环境变量
base_path = os.path.dirname(__file__) # 获取根目录路径
sys.path.append(base_path) # 将路径加入py环境变量
# 调用视图层的run函数到这边执行
from core import src
if __name__ == '__main__':
src.run()
# src.py
from interface import user_interface, bank_interface, shop_interface # 导入的接口模块
from db import db_handler
from lib import common
user_info = {'user': None} # 记用户登入状态
# 登入功能视图层
def login():
while True:
print('=============登入============')
username = input('输入您的用户名:').strip()
password = input('请输入您的密码:').strip()
flag, msg = user_interface.login_interface(username, password) # 引用接口层功能进行逻辑运算
if flag: # 有值运行
print(msg)
user_info['user'] = username # 将全局变量user—info定义成用户名
break
else:
print(msg)
# 注册
def register():
while True:
print('=============注册=============')
username = input('请输入您的用户名:').strip()
password = input('请输入您的密码:').strip()
re_password = input('请再次输入您的密码:').strip()
if password == re_password:
flag, msg = user_interface.register_interface(username, password)
if flag:
print(msg)
break
else:
print(msg)
else:
print('两次密码不一致')
# 查询余额
@common.login_auth # 登入认证装饰器
def balance():
print('============查询余额============')
msg = bank_interface.bal_interface(user_info['user'])
print('''
''')
print('您当前账户余额为', msg)
# 提现
@common.login_auth
def withdraw():
while True:
print('=============提现=============')
print('会额外收取百分之0.5的手续费')
money = input('输入您要提现的金额:').strip()
if not money.isdigit():
print('请输入数字类型')
money = int(money)
money1 = money * 1.05
money2 = money1 - money
print(f'预计账户扣除{money1}元,手续费为{money2}元')
choice = input('输入y确认提现,n重新输入,e退出提现功能:').strip()
if choice == 'y':
flag, msg = bank_interface.withdraw_inter(user_info['user'], money1, money2)
if flag:
print(msg)
break
else:
print(msg)
elif choice == 'n':
continue
elif choice == 'e':
break
else:
print('请输入正确的编号')
# 存款
@common.login_auth
def repay():
while True:
print('=============存款============')
money = input('请输入您要存的金额:').strip()
if not money.isdigit():
print('请输入正确的类型')
continue
money = int(money)
msg = bank_interface.repay_interface(user_info['user'], money)
print(msg)
break
# 转账
@common.login_auth
def transfer():
while True:
print('=============转账=============')
username1 = input('请输入对方账户:').strip()
money = input('请输入转账金额:').strip()
if not money.isdigit():
print('请输入正确的类型')
continue
money = int(money)
flag, msg = bank_interface.transfer_interface(user_info['user'], username1, money)
if flag:
print(msg)
break
else:
print(msg)
# 查看金钱流水
@common.login_auth
def check_flow():
print('===========查看流水============')
flag, msg = bank_interface.check_flow_interface(user_info['user'])
if flag:
print(msg)
else:
print(msg)
@common.login_auth
def shopping():
shop_car = {}
res = 0
while True:
print('=============购物商场=============')
goods = [
['劳斯莱斯', 10],
['奔驰', 20],
['本田', 30],
['法拉利', 50],
['五菱荣光', 1]
]
for index,goods_l1 in enumerate(goods):
good_name, good_price = goods_l1
print(f'编号=={index}--商品名=={good_name}--单价=={good_price}')
choice = input('请输入编号:').strip()
if not choice.isdigit():
print('请输入正确的编号')
continue
choice = int(choice)
if choice not in range(len(goods)):
print('请输入商品对应的正确编号')
continue
good_n, good_p = goods[choice]
choice1 = input('请输入要购买的个数:').strip()
if not choice1.isdigit():
print('请输入正确的编号')
continue
choice1 = int(choice1)
if good_n in shop_car:
shop_car[good_n][0] += choice1
else:
shop_car[good_n] = [choice1, good_p]
res += choice1 * good_p
choice2 = input('y==付款,n==退回,r==加购物车:')
if choice2 == 'y':
flag, msg = shop_interface.shopping_interface(user_info['user'], res)
if flag:
print(msg)
break
else:
print(msg)
elif choice2 == 'n':
continue
elif choice2 == 'r':
msg1 = shop_interface.add_shop_car_interface(user_info['user'], shop_car)
print(msg1)
shop_car = {}
break
@common.login_auth
def check_shop_car():
msg = shop_interface.check_shop_car(user_info['user'])
print(msg)
# 定义功能函数字典
dic = {'1': login,
'2': register,
'3': balance,
'4': withdraw,
'5': repay,
'6': transfer,
'7': check_flow,
'8': shopping,
'9': check_shop_car
}
def run():
while True:
print(user_info['user'])
print('''
1:登入及切换用户
2:注册
3:查询余额
4:提现
5:存款
6:转账
7:查看账户消费流水
8:购物商城
9:查看购物车
0:退出
''')
choice = input('请输入功能编号:').strip()
if choice not in dic:
print('请输入正确编号')
continue
elif choice == '0':
print('已退出')
return
else:
dic[choice]() # 取到函数加括号即可运行
# user_interface
from db import db_handler # 数据层模块
from lib import common
user_logger = common.get_logger('user')
# 用户登入接口
def login_interface(username,password):
user_dic = db_handler.select(username)
if user_dic:
if user_dic['pwd'] == password:
user_logger.info(f'尊敬的{username}先生,登入成功')
return True, f'尊敬的{username}先生,登入成功'
else:
return False, '密码错误'
else:
return False, f'用户{username}不存在'
# 注册接口
def register_interface(username, password):
user_dic = db_handler.select(username)
if user_dic:
return False, f'用户{username}已存在'
else:
user_dic = {'name': username,
'pwd': password,
'balance': 1000,
'flow': [],
'shop_car': {},
'locked': False}
user_logger.info(f'用户{username}注册成功')
db_handler.save(user_dic)
return True, f'用户{username}注册成功'
# shop_car_interface
from db import db_handler
from lib import common
import time
shop_logger = common.get_logger('shop')
# 购物支付结算接口
def shopping_interface(username, res):
user_dic = db_handler.select(username)
if user_dic['balance'] >= res:
user_dic['balance'] -= res
shop_logger.info(f'本次购物消费了{res}元') # 记录操作时间日志
flow_str = f'{time.strftime("%Y-%m-%d %X")}本次购物消费了{res}元' # 记录流水
user_dic['flow'].append(flow_str)
db_handler.save(user_dic)
return True, f'本次购物消费了{res}元'
else:
return False, '账号余额不足支付'
# 加入购物车接口
def add_shop_car_interface(username, shop_car):
user_dic = db_handler.select(username)
for good_name in shop_car:
if good_name in user_dic['shop_car']:
user_dic['shop_car'][good_name][0] += shop_car[good_name][0]
else:
user_dic['shop_car'].update({good_name: shop_car[good_name]})
db_handler.save(user_dic)
return '成功加入购物车'
# 查看购物车接口
def check_shop_car(username):
user_dic = db_handler.select(username)
if user_dic['shop_car']:
return user_dic['shop_car']
else:
return '购物车暂无内容'
# bank_interface
from db import db_handler # 导入数据层模块
import time
from lib import common
bank_logger = common.get_logger('bank')
# 查询余额接口
def bal_interface(username):
user_dic = db_handler.select(username)
return user_dic['balance']
# 提现接口
def withdraw_inter(username, money1, money2):
user_dic = db_handler.select(username)
if user_dic['balance'] >= money1:
user_dic['balance'] -= money1
flow_str = f'{time.strftime("%Y-%m-%d %X")}提现成功,已扣除{money1}元,手续费为{money2}元'
user_dic['flow'].append(flow_str)
bank_logger.info(f'提现成功,已扣除{money1}元,手续费为{money2}元')
db_handler.save(user_dic)
return True, f'提现成功,已扣除{money1}元,手续费为{money2}元'
else:
return False, '账户余额不足'
# 存钱接口
def repay_interface(username, money):
user_dic = db_handler.select(username)
user_dic['balance'] += money
flow_str = f'{time.strftime("%Y-%m-%d %X")}已成功存入{money}元'
user_dic['flow'].append(flow_str)
bank_logger.info(f'已成功存入{money}元')
db_handler.save(user_dic)
return f'已成功存入{money}元'
# 转账接口
def transfer_interface(username, username1, money):
user_dic1 = db_handler.select(username1)
user_dic = db_handler.select(username)
if user_dic1:
if user_dic['balance'] >= money:
user_dic['balance'] -= money
user_dic1['balance'] += money
flow_str = f'{time.strftime("%Y-%m-%d %X")}已向{username1}转账{money}元'
user_dic['flow'].append(flow_str)
bank_logger.info(f'已向{username1}转账{money}元')
db_handler.save(user_dic)
db_handler.save(user_dic1)
return True, f'已向{username1}转账{money}元'
else:
return False, f'账户余额不足{money}'
else:
return False, f'用户{username1}不存在'
# 查看寻流水信息接口
def check_flow_interface(username):
user_dic = db_handler.select(username)
bank_logger.info(f'用户{username}查看了流水')
if user_dic['flow']:
return True, user_dic['flow']
else:
return False, '当前用户暂无流水'
# settings
import os
base_path = os.path.dirname(os.path.dirname(__file__)) # 配置文件路径
db_path = os.path.join(base_path, 'db') # 与db拼接的根目录下db文件路径
# 定义三种日志输出格式 开始
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'
# 定义日志输出格式 结束
# log文件的目录 *******
LOG_DRI_PATH = os.path.join(base_path, 'log')
# *******
LOG_FILE_NAME = 'access.log' # log文件名
# 如果不存在定义的日志目录就创建一个
if not os.path.isdir(LOG_DRI_PATH):
os.mkdir(LOG_DRI_PATH)
# log文件的全路径 *******
LOG_FILE_PATH = os.path.join(LOG_DRI_PATH, LOG_FILE_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': LOG_FILE_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)传递
},
},
}
# common
from conf import settings
def login_auth(func): # 登入认证装饰器
from core import src
def wrapper(*args, **kwargs):
if src.user_info['user']:
res = func(*args, **kwargs)
return res
else:
print('请先登入')
src.login()
return wrapper
import logging.config # 到处logging模块的配置变量
def get_logger(user_type):
# 1) 架子啊logging配置信息
logging.config.dictConfig(settings.LOGGING_DIC) # 导入上面定义的logging配置
# 2) 获取 银行相关的 logger对象
logger = logging.getLogger(user_type) # 生成一个log实例
# 3) logger.info(日志信息) info:日志的级别
# [INFO][2020-07-28 12:07:07,097][settings.py:97]tank 购买了 矮根派
# logger.info('tank 购买了 矮根派') # 记录该文件的运行状态
# 4) 返回日志对象
return logger
# db_handler
import json
import os
from conf import settings
# 数据层
def select(username): # 接受用户名字进行查找并返回信息
user_path = os.path.join(settings.db_path, '%s.json' % username)
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): # 保存传来的信息
user_path = os.path.join(settings.db_path, '%s.json' % user_dic['name'])
with open(user_path, 'w', encoding='utf-8')as f:
json.dump(user_dic, f, ensure_ascii=False)
f.flush()