架构图:
直接盗用“贤妻”老哥画的架构图
配置信息:
# \'\'\'
# 配置信息
# \'\'\'
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、用户层接收到 布尔值和信息,简单判断或进行打印,展示。