架构图:
直接盗用“贤妻”老哥画的架构图
配置信息:
# '''
# 配置信息
# '''
import os
BASE_PATH=os.path.dirname(
os.path.dirname(os.path.abspath(__file__)))
USER_DATA_PATH=os.path.join(BASE_PATH,'db','user_data')
公共方法:
'''
公共方法
'''
import hashlib
from interface import user_interface
from core import src
def md5_obj_pwd(password):
md5_obj=hashlib.md5()
salt='你搞清楚,这是在谁的bgm里!'
md5_obj.update(salt.encode('utf-8'))
md5_obj.update(password.encode('utf-8'))
return md5_obj.hexdigest()
def login_auth(func):
def wrapper(*args,**kwargs):
if not src.login_user:
print('登录后才能查看余额!')
src.login()
res=func(*args,**kwargs)
return res
else:
res = func(*args, **kwargs)
return res
return wrapper
一、注册功能
1、文字流程分析:
——>1、用户层:让用户输入用户名和密码,将用户名和密码交给接口层(用户)
——>2、接口层接收用户名和密码,将用户名传给数据层的访问数据,进行判断
——>3、数据层接收用户名,将用户名拼接成用户信息路径,查找路径是否存在文件:
3.1存在打开文件读取用户信息字典,给接口层返回字典;
3.2不存在则给接口层返回None
——>4、接口层接收数据层返回的数据,进行判断:
4.1数据为None则组织用户数据,生成字典并将字典再传给数据层,数据层调用common文件中的函数将密码转成加盐的hash值,
替换用户信息的字典中的明文密码,然后保存用户字典,之后给用户层返回:True,'注册成功';
4.2数据层返回的若不为None则说明用户已存在,给用户层返回:False,'用户已存在'
——>5、用户层接收接口层返回的布尔值和信息,进行简单判断,打印信息
2、代码实现:
用户层:
'''
第一层:用户视图层
'''
from interface import user_interface
from interface import bank_interface
from lib import common
login_user = None
def register():
username = input('请输入用户名: ').strip()
password = input('请输入密码: ').strip()
re_password = input('请确认密码: ').strip()
if re_password == password:
flag, msg = user_interface.register_interface(username, password)
if flag:
print(msg)
else:
print(msg)
else:
print('两次密码不一致,请重新输入!')
接口层:
from db import db_handler
from lib import common
def register_interface(username,password,balance=15000):
user_data=db_handler.select(username)
if not user_data:
user_dic={
'username':username,
'password':password,
'balance':balance,
'flow':[],
'shopping_car':{},
'locked':False
}
db_handler.save(user_dic)
return True,f'用户{username}注册成功!'
else:
return False,f'用户{username}已注册,请重新输入!'
数据层:
'''
第三层:数据处理层
'''
import os
import json
from lib import common
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_data = json.load(f)
return user_data
def save(user_dic):
username = user_dic.get('username')
password = user_dic.get('password')
user_dic['password'] = common.md5_obj_pwd(password)
user_path = os.path.join(settings.USER_DATA_PATH, f'{username}.json')
with open(user_path, 'w', encoding='utf-8') as f:
json.dump(user_dic, f, ensure_ascii=False)
二、登录功能
1、文字流程分析:
——>1、用户层:让用户输入用户名和密码,将用户名和密码交给接口层(用户)
——>2、接口层接收用户名和密码,将用户名传给数据层的访问数据,进行判断
——>3、数据层接收用户名,将用户名拼接成用户信息路径,查找路径是否存在文件:
3.1存在打开文件读取用户信息字典,给接口层返回字典;
3.2不存在则给接口层返回None
——>4、接口层接收数据层返回的数据,进行判断:
4.1数据为None则说明用户不存在,给用户层返回:False,'用户不存在,请重新输入'
4.2数据为字典时,调用common文件中的方法将用户输入的密码转成加盐的hash值,然后跟字典中的加盐的密文密码进行检验,
4.2.1密码正确给用户层返回:True,'登陆成功'
4.2.1密码错误给用户层返回:False,'密码错误'
——>5、户层接收接口层返回的布尔值和信息,进行简单判断:
5.1为True则将用户名赋值给记录登录用户的全局变量,打印信息
5.2为False则打印'用户不存在'或'密码错误'。
2、代码实现:
用户层:
'''
第一层:用户视图层
'''
from interface import user_interface
from interface import bank_interface
from lib import common
login_user = None
def login():
username = input('请输入用户名: ').strip()
password = input('请输入密码: ').strip()
re_password = input('请确认密码: ').strip()
global login_user
if username == login_user:
print(f'用户{username}已登录')
elif re_password == password:
flag, msg = user_interface.login_interface(username, password)
if flag:
login_user = username
print(msg)
else:
print(msg)
else:
print('两次密码不一致,请重新输入!')
接口层:
from db import db_handler
from lib import common
def login_interface(username,password):
user_dic = db_handler.select(username)
if user_dic:
password=common.md5_obj_pwd(password)
if password==user_dic.get('password'):
return True,f'用户{username}登录成功!'
else:
return False,'密码错误!
数据层:
'''
第三层:数据处理层
'''
import os
import json
from lib import common
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_data = json.load(f)
return user_data
三、查询余额功能
1、文字流程分析:
(定义查询余额功能的函数前需要先调用common下的登录认证装饰器函数作为语法糖,查询前检测用户是否登录,
如果已登录则继续查询,如果没有登录提示用户没用登录,让其登录后再进行查询)
——>1、用户层输入查询余额命令,将用户名传入接口层(用户)
——>2、接口层(用户)接收用户名,将用户名传入数据层访问余额
——>3、数据层接收用户名,将用户名拼接成用户信息路径,查找用户信息文件,将用户信息文件中的余额返回给接口层
——>4、接口层接收数据层查询的余额,继续返回给用户层
——>5、用户层接收到查询的余额,进行打印,展示。
2、代码实现:
用户层:
@common.login_auth
def check_balance():
balance = bank_interface.check_bal_inface(login_user)
print(f'用户{login_user} 账户余额为: {balance}')
接口层:
from db import db_handler
def check_bal_inface(username):
balance=db_handler.select(username).get('balance')
return balance
数据层:
'''
第三层:数据处理层
'''
import os
import json
from lib import common
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_data = json.load(f)
return user_data
四、提现功能
(定义提现功能的函数前需要先调用common下的登录认证装饰器函数作为语法糖,提现时前检测用户是否登录,
如果已登录则继续查询,如果没有登录提示用户没用登录,让其登录后再进行查询)
——>1、用户层获得用户输入的用户名和提现金额,将用户名和提现金额传入接口层(银行)
——>2、接口层(银行)接收用户名和提现金额,将其传入数据层
——>3、数据层接收用户名和提现金额,将用户名拼接成用户信息路径,查找用户信息文件,将用户信息文件中的余额返回给接口层
——>4、接口层接收数据层查询的余额,进行判断:
4.1余额大于提现金额加手续费,则用余额减去提现金额和手续费获得新的余额,用新的余额覆盖字典中之前的余额,将字典传入数据层,数据层保存新的用户字典
到达修改余额对的效果,再给用户层返回:True,'提现成功...'
4.2若余额小于提现金额加手续费,则给用户层返回:False,'余额不足'
——>5、用户层接收到 布尔值和信息,简单判断或进行打印,展示。