ATM+购物车项目架构

架构图:

直接盗用“贤妻”老哥画的架构图

配置信息:

# '''
# 配置信息
# '''
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、用户层接收到 布尔值和信息,简单判断或进行打印,展示。

posted @ 2020-04-03 01:09  风起千寻  阅读(159)  评论(0编辑  收藏  举报