26、ATM项目的编写流程

1、搭建项目的目录规范

- ATM 项目根目录
        - readme.md  项目的说明书
    
        - start.py  项目启动文件
        
        - conf  配置文件
            - settings.py
            
        - lib   公共方法文件
            - common.py
            
        - core(用户视图层)  存放用户视图层代码文件
            - src.py
          
        - interface(逻辑接口层)   存放核心业务逻辑代码
            - user_interface.py   用户相关的接口
            - bank_interface.py   银行相关的接口
            - shop_interface.py   购物相关的接口
        
        - db(数据处理层)  存放数据与数据处理层代码
            - db_handler.py  数据处理层代码
            - user_data  用户数据
            
        - log  存放日志文件

2.1、启动项的编写

  启动文件——start文件——先将解释器添加到环境变量

sys.path.append(
    os.path.dirname(__file__)
)

2.2、启动文件——start文件——导入用户视层图

from core import src

2.3、启动文件——start文件——编写开启项目启动函数

if __name__ == '__main__':

2.4、启动文件——start文件——先执行用户视层图

   src.run()

3.1、获取项目根目录路径

BASE_PATH = os.path.dirname(
    os.path.dirname(__file__)
)

3.2、获取user_data文件夹目录路径

USER_DATA_PATH = os.path.join(
    BASE_PATH, 'db', 'user_data')

4.2.13、用户视图层core——src.py——视图层主程序的编写

def run():
    while True:
        print('''
        ===== ATM + 购物车 =====
            1、注册功能
            2、登录功能
            3、查看余额
            4、提现功能
            5、还款功能
            6、转账功能
            7、查看流水
            8、购物功能
            9、查看购物车
            10、管理员功能
        ========= end =========
        ''')

4.2.13、用户视图层core——src.py——各种功能的空函数

# 1、注册功能
def register():

# 2、登录功能
def login():

# 3、查看余额
@common.login_auth
def check_balance():

# 4、提现功能
@common.login_auth
def withdraw():

# 5、还款功能
@common.login_auth
def repay():

# 6、转账功能
@common.login_auth
def transfer():


# 7、查看流水
@common.login_auth
def check_flow():

# 8、购物功能
@common.login_auth
def shopping():

# 9、查看购物车
@common.login_auth
def check_shop_car():

# 10、管理员功能(考试额外加分项)
@common.login_auth
def admin():

4.2.12、用户视图层core——src.py——创建函数功能字典

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,
}

4.2.13.1、用户视图层core——src.py——视图层主程序的编写——让用户选择功能编号

choice = input('请输入功能编号: ').strip()

4.2.13.2、用户视图层core——src.py——视图层主程序的编写——判断功能编号是否存在

        if choice not in func_dic:
            print('请输入正确的功能编号!')
            continue

4.2.13.3、用户视图层core——src.py——视图层主程序的编写——调用选择的函数功能

func_dic.get(choice)()

4.2.2、用户视图层core——src.py——注册功能

  从interface中调用到user_interface

form interface import user_interface
def
register(): while True: username = input('请输入用户名: ').strip() password = input('请输入密码: ').strip() re_password = input('请确认密码: ').strip() if password == re_password:

4.2、用户视图层core——src.py——将数据接口的模块导入

from interface import user_interface
from interface import bank_interface
from interface import shop_interface
from lib import common

6.4.2.2、逻辑接口层interface——user_interface.py——注册接口——判断用户是否存在

  保存数据时需要做加密处理

def register_interface(username, password, balance=15000):
    # 2)查看用户是否存在
    # 2.1) 调用 数据处理层 中的 select函数,会返回 用户字典 或 None
    user_dic = db_handler.select(username)

    # {user: user, pwd: pwd...}   or  None
    # 若用户存在,则return,告诉用户重新输入
    if user_dic:
        # return (False, '用户名已存在!')
        return False, '用户名已存在!'

7.1.1、公共文件lib——common.py——md5加密

import hashlib
# md5加密
def get_pwd_md5(password):
    md5_obj = hashlib.md5()
    md5_obj.update(password.encode('utf-8'))
    salt = '一二三四五,Egon上山打老鼠!'
    md5_obj.update(salt.encode('utf-8'))
    return md5_obj.hexdigest()

6.4.2.1、逻辑接口层interface——user_interface.py——注册接口——给用户输入的密码做一次加密

    # 3)若用户不存在,则保存用户数据
    # 做密码加密
    password = common.get_pwd_md5(password)
    # 3.1) 组织用户的数据的字典信息
    user_dic = {
        'username': username,
        'password': password,
        'balance': balance,
        # 用于记录用户流水的列表
        'flow': [],
        # 用于记录用户购物车
        'shop_car': {},
        # locked:用于记录用户是否被冻结
        # False: 未冻结   True: 已被冻结
        'locked': False
    }

    # 3.2)保存数据
    db_handler.save(user_dic)
    msg = f'{username} 注册成功!'

    # 3.3)记录日志
    user_logger.info(msg)

    return True, msg

  注册接口将会传递一个username,给数据处理层,去确定是否已经被注册

5.2.1、数据处理层db——db_handler.py——查看数据

  需要从settings调用地址

  使用os内置函数

import os
from conf import settings

# 1) 接收接口层传过来的username用户名,拼接用户json文件路径
user_path = os.path.join(
settings.USER_DATA_PATH, f'{username}.json'
)

# 2)校验用户json文件是否存在
if os.path.exists(user_path):
# 3) 打开数据,并返回给接口层
with open(user_path, 'r', encoding='utf-8') as f:
user_dic = json.load(f)
return user_dic

 5.2.2、数据处理层db——db_handler.py——保存数据

  使用json函数


import json
# 保存数据(添加新数据或者更新数据)
def save(user_dic):
    # 1) 拼接用户的数据字典
    username = user_dic.get('username')

    # 根据用户的名字,拼接 用户名.json 文件路径
    user_path = os.path.join(
        settings.USER_DATA_PATH, f'{username}.json'
    )

    # 2) 保存用户数据
    with open(user_path, 'w', encoding='utf-8') as f:
        # ensure_ascii=False让文件中的中文数据,显示更美观
        json.dump(user_dic, f, ensure_ascii=False)

4.2.3.1、用户视图层——core——src.py——让用户输入用户名与密码

、登录功能
def login():
    # 登录视图
    while True:
        # 1) 让用户输入用户名与密码
        username = input('请输入用户名: ').strip()
        password = input('请输入密码: ').strip()

  需要通过接口层的登录接口验证账户是否存在

6.4.3、用户接口层——interface——user_inteerface——登录接口

# 登录接口
def login_interface(username, password):
    # 1) 先查看当前用户数据是否存在
    # {用户数据字典}  or  None
    user_dic = db_handler.select(username)

    # 2) 判断用户是否存在
    if user_dic:
        # 若有冻结用户,则需要判断是否被锁定
        if user_dic.get('locked'):
            return False, '当前用户已被锁定'

        # 给用户输入的密码做一次加密
        password = common.get_pwd_md5(password)

        # 3) 校验密码是否一致
        if password == user_dic.get('password'):
            msg = f'用户: [{username}] 登录成功!'
            user_logger.info(msg)
            return True, msg

        else:

            msg = f'用户: [{username}]密码错误!'
            user_logger.warn(msg)
            return False, msg

    msg = f'用户: [{username}]用户不存在,请重新输入!!'
    return False, msg

  通过登录功能验证后,继续编写登录功能

4.2.3.2、用户视图层——core——src.py——调用接口层,将数据传给登录接口

# 2) 调用接口层的注册接口,将用户名与密码交给接口层来进行处理

            # res ---> (False, '用户名已存在!')
            # res = user_interface.register_interface(
            # flag, msg ---> (flag---> False, msg --> '用户名已存在!')

            # (True, 用户注册成功),  (False, 注册失败)
            flag, msg = user_interface.register_interface(
                username, password
            )

            # 3) 根据flag判断用户注册是否成功,flag控制break的结束
            if flag:
                print(msg)
          global login_user
          login_user = username
break else: print(msg)

 7.1.2、公共文件lib——common.py——登录认证装饰器

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

 

posted @ 2020-04-05 08:35  疏星淡月  阅读(355)  评论(0编辑  收藏  举报