• Python构建简单的ATM+购物功能项目



    南宫乘风:我在学Python哦

    Python:你不写Python项目,是不会有进步的,年轻人,耗子尾汁吧

    南宫乘风:我要进步,要学习,开始项目

    Python:来骗,来偷袭。很快啊!年轻人,不讲码德


    学了一点时间Python,为了巩固基础,拿一个简单的项目练手。

    ATM+购物车功能(ps:很简单,大佬不要嘲笑哈)

    项目需求:

    1.额度15000或自定义     -->  注册功能
    2.实现购物商城,买东西加入购物车,调用信用卡接口结账  --> 购物功能、支付功能
    3.可以提现,手续费5%   --> 提现功能
    4.支持多账户登录  --> 登录功能
    5.支持账户间转账  --> 转账功能
    6.记录日常消费 -->  记录流水功能
    7.提供还款接口 -->  还款功能
    8.ATM记录操作日志 --> 记录日志功能
    9.提供管理接口,包括添加账户、用户额度,冻结账户等。。。 ---> 管理员功能
    10.用户认证用装饰器  --> 登录认证装饰器

    "用户视图层" 展示给用户选择的功能

    user
    
    1、注册功能
    2、登录功能
    3、查看余额
    4、提现功能
    5、还款功能
    6、转账功能
    7、查看流水
    8、购物功能
    9、查看购物车
    10、管理员功能

    admin

    1、添加账号
    2、修改额度
    3、冻结账号
    4、解冻账号
    5、返回上一层

    架构流程图

    采取MVC的架构方式

    各层分开,编写接口

    三层架构:

    1、把每个功能都分层三部分,逻辑清晰
    2、如果用户更换不同的用户界面或不同的数据库存储机制,不会影响接口层的核心逻辑代码,扩展性强。
    3)可以在接口层,准确的记录日志与流水。

    三层架构构建   项目代码https://wwx.lanzoux.com/i1vhGixijzi

    启动界面

    start.py(程序的入口)

    '''
    程序入口
    '''
    import os
    import sys
    from core import src
    
    # 添加解释器的环境变量
    sys.path.append(
        os.path.dirname(__file__)
    )
    # 开始执行项目main
    if __name__ == "__main__":
        src.run()
    

    conf

    setting.py(log日志的配置文件,项目的环境配置)

    '''
    配置文件设置
    
    '''
    import os
    BASE=os.path.dirname(os.path.dirname(__file__))
    # print(BASE)
    #获取user_date文件夹路径
    USER_DATE=os.path.join(BASE,'db','user_date')
    # print(USER_DATE)
    
    """
    日志配置字典LOGGING_DIC
    """
    # 1、定义三种日志输出格式,日志中可能用到的格式化串如下
    # %(name)s Logger的名字
    # %(levelno)s 数字形式的日志级别
    # %(levelname)s 文本形式的日志级别
    # %(pathname)s 调用日志输出函数的模块的完整路径名,可能没有
    # %(filename)s 调用日志输出函数的模块的文件名
    # %(module)s 调用日志输出函数的模块名
    # %(funcName)s 调用日志输出函数的函数名
    # %(lineno)d 调用日志输出函数的语句所在的代码行
    # %(created)f 当前时间,用UNIX标准的表示时间的浮 点数表示
    # %(relativeCreated)d 输出日志信息时的,自Logger创建以 来的毫秒数
    # %(asctime)s 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒
    # %(thread)d 线程ID。可能没有
    # %(threadName)s 线程名。可能没有
    # %(process)d 进程ID。可能没有
    # %(message)s用户输出的消息
    import os
    BASE_PATH=os.path.dirname(os.path.dirname(__file__))
    a1_path=os.path.join(BASE_PATH,'log','a1.log')
    a2_path=os.path.join(BASE_PATH,'log','a2.log')
    # print(a1_path+'
    '+a2_path)
    
    # 2、强调:其中的%(name)s为getlogger时指定的名字
    standard_format = '%(asctime)s - %(threadName)s:%(thread)d - 日志名字:%(name)s - %(filename)s:%(lineno)d -' 
                      '%(levelname)s - %(message)s'
    
    simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'
    
    test_format = '%(asctime)s] %(message)s'
    
    # 3、日志配置字典
    LOGGING_DIC = {
        'version': 1,
        'disable_existing_loggers': False,
        'formatters': {
            'standard': {
                'format': standard_format
            },
            'simple': {
                'format': simple_format
            },
            'test': {
                'format': test_format
            },
        },
    
        'filters': {},
        # handlers是日志的接收者,不同的handler会将日志输出到不同的位置
        'handlers': {
            #打印到终端的日志
            'console': {
                'level': 'DEBUG',
                'class': 'logging.StreamHandler',  # 打印到屏幕
                'formatter': 'simple'
            },
            'default': {
                'level': 'DEBUG',
                'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件
                # 'maxBytes': 1024*1024*5,  # 日志大小 5M
                'maxBytes': 1024*1024*5,
                'backupCount': 5,
                'filename': a1_path,  # os.path.join(os.path.dirname(os.path.dirname(__file__)),'log','a2.log')
                'encoding': 'utf-8',
                'formatter': 'standard',
    
            },
            #打印到文件的日志,收集info及以上的日志
            'other': {
                'level': 'DEBUG',
                'class': 'logging.FileHandler',  # 保存到文件
                'filename': a1_path, # os.path.join(os.path.dirname(os.path.dirname(__file__)),'log','a2.log')
                'encoding': 'utf-8',
                'formatter': 'standard',
    
    
            },
        },
        # loggers是日志的产生者,产生的日志会传递给handler然后控制输出
        'loggers': {
            #logging.getLogger(__name__)拿到的logger配置
            'kkk': {
                'handlers': ['console','other'],  # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
                'level': 'DEBUG', # loggers(第一层日志级别关限制)--->handlers(第二层日志级别关卡限制)
                'propagate': False,  # 默认为True,向上(更高level的logger)传递,通常设置为False即可,否则会一份日志向上层层传递
            },
            '终端提示': {
                'handlers': ['console',],  # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
                'level': 'DEBUG',  # loggers(第一层日志级别关限制)--->handlers(第二层日志级别关卡限制)
                'propagate': False,  # 默认为True,向上(更高level的logger)传递,通常设置为False即可,否则会一份日志向上层层传递
            },
            '': {
                'handlers': ['default', ],  # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
                'level': 'DEBUG',  # loggers(第一层日志级别关限制)--->handlers(第二层日志级别关卡限制)
                'propagate': False,  # 默认为True,向上(更高level的logger)传递,通常设置为False即可,否则会一份日志向上层层传递
            },
        },
    }
    
    

    core

    admin.py(admin用户视图)

    from core import src
    from interface import admin_interface
    
    
    def add_user():
        src.register()
    
    
    def change_balance():
        while True:
            # 输入修改修改用户名
            change_user = input('请输入需要修改额度的用户:').strip()
            change_money = input('请输入需要修改的用户额度:').strip()
            if not change_money.isdigit():
                continue
            if int(change_money) >= 0:
                flag, msg = admin_interface.change_balance_interafce(change_user, change_money)
                if flag:
                    print(msg)
                else:
                    print(msg)
            else:
                print('输入的额度不正确')
    
    
    def disable_user():
        # 输入要冻结的用户
        while True:
            dis_user = input('请输入要冻结的用户:').strip()
            flag, msg = admin_interface.disable_user_interface(dis_user)
            if flag:
                print(msg)
                break
            else:
                print(msg)
    
    
    def enable_user():
        # 输入要解冻冻结的用户
        while True:
            dis_user = input('请输入要解冻冻结的用户:').strip()
            flag, msg = admin_interface.enable_user_interface(dis_user)
            if flag:
                print(msg)
                break
            else:
                print(msg)
    
    
    def lsat_men():
        from core import src
        src.run()
    
    
    func_dic = {
        '1': add_user,
        '2': change_balance,
        '3': disable_user,
        '4': enable_user,
        '5': lsat_men,
    
    }
    
    
    def admin_run():
        while True:
            print('''
                1、添加账号
                2、修改额度
                3、冻结账号
                4、解冻账号
                5、返回上一层
            ''')
            choice = input('请输入管理员功能编号:').strip()
            if choice not in func_dic:
                print("请输入正确的功能编号")
                continue
            func_dic.get(choice)()
    
    # if __name__ == '__main__':
    #     admin()
    

    src.py(用户的视图)

    '''
    用户视图层
    '''
    
    from interface import user_interface, bank_interface, shop_interface
    from lib import common
    from core import admin
    
    # 1、注册功能
    '''def register():
        while True:
            # 1 让用户输入用户名称和密码进行校验
            username = input('请输入用户:').strip()
            if username.strip()=='':
                print("请输入正确的用户名")
                continue
    
            user_path = os.path.join(setting.USER_DATE, f"{username}.json")
            if os.path.exists(user_path):
                print(f"您输入的用户名:{username}已经存在")
                continue
            password = input("请输入密码:").strip()
            re_password = input("请确认密码:").strip()
            # 判断密码是否一致
            if password == re_password:
    
                # 2 查看用户是否存在
                # 3 如用户存在,则让用户重新输入
                # 4 如用户不存在,则保存用户数据
                # 4.1 组织用户的数据的字典信息
                user_dic = {
                    'username': username,
                    'password': password,
                    'balance': 15000,
                    # 用于记录用户的流水类表
    
                    'flow': [],
                    # 用于记录用户购物车
                    'shop_car': [],
                    # locaked :用于记录用户是否冻结
                    # false:未冻结  True:已经被冻结
                    'locaked': False
                }
                # 用户数据tank.json
                user_path = os.path.join(setting.USER_DATE, f"{username}.json")
                with open(user_path, 'w', encoding='utf-8') as f:
                    json.dump(user_dic, f)
            else:
                print('您的两次密码不一致,请重新输入')'''
    
    login_user = None
    
    
    # 分层版
    def register():
        while True:
            # 1 让用户输入用户名称和密码进行校验
            username = input('请输入用户:').strip()
            if username.strip() == '':
                print("请输入正确的用户名")
                continue
            password = input("请输入密码:").strip()
            re_password = input("请确认密码:").strip()
            # 判断密码是否一致
            if password == re_password:
                # 2 调用接口层的注册结果。将用户名和密码传到接口层
                # (True, 用户注册成功),  (False, 注册失败)
                flag, msg = user_interface.register_interface(
                    username, password
                )
    
                # 3) 根据flag判断用户注册是否成功,flag控制break的结束
                if flag:
                    print(msg)
                    break
                else:
                    print(msg)
            else:
                print('您的两次密码不一致,请重新输入')
    
    
    # 2、登录功能
    def login():
        # 登录视图层
        while True:
            username = input('请输入用户名:').strip()
            password = input('请输入用户名密码:').strip()
    
            flag, msg = user_interface.longin_interface(username, password)
            if flag:
                global login_user
                login_user = username
                print(msg)
                break
            else:
                print(msg)
    
    
    # 3、查看余额
    @common.login_auth
    def check_balance():
        # 直接调用查看用户接口,获取用余额
        balance = user_interface.check_balance_interface(login_user)
        print(f'用户:{login_user}账号余额为:{balance}')
    
    
    # 4、提现功能
    @common.login_auth
    def withdraw():
        while True:
            # 让用户输入体现金额
            input_money = input('请输入提现金额:').strip()
            # 判断用户输入的金额是否是数字
            if not input_money.isdigit():
                print('请重新输入:')
                continue
            # 用户提现,将金额提交接口处理
            flag, msg = bank_interface.withdraw_interface(login_user, int(input_money))
            if flag:
                print(msg)
                break
            else:
                print(msg)
    
    
    # 5、还款功能
    @common.login_auth
    def repay():
        while True:
            # 让用户输入体现金额
            repay_money = input('请输入还款金额:').strip()
            # 判断用户输入的金额是否是数字
            if not repay_money.isdigit():
                print('请重新输入')
                continue
            # 用户提现,将金额提交接口处理
            if int(repay_money) > 0:
                flag, msg = bank_interface.repay_interface(login_user, int(repay_money))
                if flag:
                    print(msg)
                    break
            else:
                print('不能输入小于0的数字')
    
    
    # 6、转账功能
    @common.login_auth
    def transfer():
        '''
        接收用户的转账金额
        接收用户输入的转账目标
        :return:
        '''
        while True:
            user_money = input('请输入转账目标用户:').strip()
            money = input('请输入转账金额:').strip()
            if not money.isdigit():
                print('请输入正确的金额!')
                continue
            money = int(money)
            if money > 0:
                # 转账接口
                flag, msg = bank_interface.transfer_interface(login_user, user_money, money)
                if flag:
                    print(msg)
                    break
                else:
                    print(msg)
            else:
                print('请输入正确的金额!')
    
    
    # 7、查看流水
    @common.login_auth
    def check_flow():
        # 直接调用查看流水的列表
        flow_list = bank_interface.check_flow_interface(login_user)
        if flow_list:
            for flow in flow_list:
                print(flow)
        else:
            print('当前用户没有流水记录')
    
    
    # 8、购物功能
    @common.login_auth
    def shopping():
        '''
        {
            '0':{'name':'包子','price':30},
            '0': {'name': '包子', 'price': 30},
            '0': {'name': '包子', 'price': 30},
        }
        :return:
        '''
        shop_list = [
            ['包子', 30],
            ['衣服', 150],
            ['安全套', 25],
            ['情趣内衣', 520],
            ['cosplay', 250],
        ]
        shopping_car = {}
        while True:
            # 先打印商品的信息,让用户选择
            print('===================欢迎来到情趣商城================')
            for index, shop in enumerate(shop_list):
                shop_name, shop_price = shop
                print(f'商品编号:{index}, 商品名称:{shop_name},商品单价:{shop_price}')
            print('========================end======================')
    
            shop_choice = input("请输入你要选购的商品编号(是否结账y or n):").strip()
            if shop_choice.upper() == 'Y':
                if not shopping_car:
                    print('购物车是空的,不能支付,请重新输入')
                    continue
                # 调用支付接口进行支付
                flag,msg=shop_interface.shopping_interface(login_user,shopping_car)
                if flag:
                    print(msg)
                    break
                else:
                    print(msg)
            elif shop_choice.upper() == 'N':
                # 判断当前用户是否添加过购物车
                if not shopping_car:
                    print('购物车是空的,不能添加,请重新输入')
                    continue
    
                flag,msg=shop_interface.add_shop_car_interface(login_user,shopping_car)
                if flag:
                    print(msg)
                    break
    
            if not shop_choice.isdigit():
                print('请输入正确的编号!')
                continue
            shop_choice = int(shop_choice)
            if shop_choice not in range(len(shop_list)):
                print('请输入正确的编号!')
                continue
            shop_name, shop_price = shop_list[shop_choice]
    
            if shop_name in shopping_car:
                shopping_car[shop_name][1] += 1
            else:
                shopping_car[shop_name] = [shop_price, 1]
    
            print("当前购物车:",shopping_car)
    
    # 9、查看购物车
    @common.login_auth
    def check_shop_car():
        shop_list = shop_interface.check_shop_car_interface(login_user)
        if shop_list:
            for shop_name,print_number in shop_list.items():
                print(f'商品:[{shop_name}],数量:[{print_number[1]}]')
        else:
            print('当前用户没有流水记录')
    
    
    @common.login_auth
    def admin_spuer():
        admin.admin_run()
    
    
    # 创建函数功能字典
    
    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_spuer,
    }
    
    
    def run():
        while True:
            print('''
            ==========ATM+购物车==========
                    1、注册功能
                    2、登录功能
                    3、查看余额
                    4、提现功能
                    5、还款功能
                    6、转账功能
                    7、查看流水
                    8、购物功能
                    9、查看购物车
                    10、管理员功能
            ==========  end  ==========
            ''')
            choice = input("请输入功能编号:").strip()
            if choice not in func_dic:
                print("请输入正确的功能编号")
                continue
            func_dic.get(choice)()
    

    db

    user_date (用户存放json的目录)

    q.json (用户数据的存放文件,字典形式)
     

    {"username": "q", "password": "099b3b060154898840f0ebdfb46ec78f", "balance": 14375.0, "flow": ["用户[q] 提现金额 [500],手续费为:[25.0]", "用户:[q]给用户[w] 转账:[100] 元 成功"], "shop_car": {}, "locked": false}

    json格式

    {
    	"username": "q",
    	"password": "099b3b060154898840f0ebdfb46ec78f",
    	"balance": 14375.0,
    	"flow": ["用户[q] 提现金额 [500],手续费为:[25.0]", "用户:[q]给用户[w] 转账:[100] 元 成功"],
    	"shop_car": {},
    	"locked": false
    }

    db_hander.py(对数据处理,相当于mysql接口处理)

    '''
    数据处理层
        专门用户处理数据的
    '''
    import json
    import os
    from conf import setting
    
    
    # 判断用户是否已经注册
    def user_select(username):
        # 1) 接收接口层传过来的username用户名,拼接用户json文件路径
        user_path = os.path.join(
            setting.USER_DATE, 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
    
        # 3) 不return,默认return None
    
    # 保存数据处理
    def user_save(user_dic):
        user_path = os.path.join(setting.USER_DATE, f"{user_dic['username']}.json")
        with open(user_path, 'w', encoding='utf-8') as f:
            json.dump(user_dic, f, ensure_ascii=False)
    

    interface

    admin_interface.py(admin的业务接口处理)

    from db import db_hander
    from lib import common
    user_logger=common.get_log('admin')
    
    # 修改额度接口
    def change_balance_interafce(change_user, change_money):
        user_dic = db_hander.user_select(change_user)
    
        if user_dic:
            user_dic['balance'] = int(change_money)
            db_hander.user_save(user_dic)
            msg=f'[{change_user}]的额度修改{change_money}成功'
            user_logger.info(msg)
            return True, msg
        return False, '修改额度用户不存在'
    
    
    def disable_user_interface(dis_user):
        user_dic = db_hander.user_select(dis_user)
        if user_dic:
            user_dic['locked'] = True
            db_hander.user_save(user_dic)
            msg = f'[{dis_user}]的冻结成功'
            user_logger.info(msg)
            return True, msg
        else:
            return False, '冻结用户不存在'
    
    # 解冻用户的接口
    def enable_user_interface(dis_user):
        user_dic = db_hander.user_select(dis_user)
        if user_dic:
            if user_dic['locked']:
                user_dic['locked'] = False
                db_hander.user_save(user_dic)
                msg = f'[{dis_user}]的冻结成功'
                user_logger.info(msg)
                return True, msg
            return False,f'用户:{dis_user}处于正常状态'
        else:
            return False, '冻结用户不存在'

    bank_interface.py(银行业务处理接口)

    '''
    银行相关的业务
    '''
    from db import db_hander
    from lib import common
    user_logger=common.get_log('bank')
    
    # 用户的提现金额接口
    def withdraw_interface(login_user, input_money):
        # 先获取用户字典
        user_dic = db_hander.user_select(login_user)
        # 获取银行的金额
        balance = int(user_dic.get('balance'))
        # 本金+ 手续费
        money = int(input_money) * 1.05
        repair = round(money - input_money, 2)
        # 判断用户金额是否足够
        if balance >= money:
            # 修改用户字典的金额
            balance -= money
            user_dic['balance'] = balance
            flow = f'用户[{login_user}] 提现金额 [{input_money}],手续费为:[{repair}]'
            user_dic['flow'].append(flow)
            # 在保存数据
            db_hander.user_save(user_dic)
            msg=f'用户[{login_user}] 提现金额 [{input_money}],手续费为:[{repair}]'
            user_logger.info(msg)
            return True, msg
        return False, '提现金额不足,请重新输入'
    
    
    # 还款接口
    def repay_interface(login_user, repay_money):
        # 先获取用户字典
        user_dic = db_hander.user_select(login_user)
        # 获取银行的金额
        balance = int(user_dic.get('balance'))
        # 本金+ 手续费
        money = int(repay_money)
        # repair = round(money - repay_money, 2)
        # 修改用户字典的金额
        balance += money
        user_dic['balance'] = balance
        # 在保存数据
        flow = f'用户:[{login_user}] 还款金额 :[{repay_money}]成功]'
        user_dic['flow'].append(flow)
        db_hander.user_save(user_dic)
        msg = f'用户:[{login_user}] 还款金额 :[{repay_money}]成功]'
        user_logger.info(msg)
        return True, msg
    
    
    # 转账接口
    def transfer_interface(login_user, user_money, money):
        # 先获取用户字典
        login_user_dic = db_hander.user_select(login_user)
        user_money_dic = db_hander.user_select(user_money)
        # 判断目标用户是否存在
        if not user_money_dic:
            return False, '目标用户不存在'
        if login_user == user_money:
            return False, '不能给自己转账'
        if login_user_dic['balance'] >= money:
            login_user_dic['balance'] -= money
            user_money_dic['balance'] += money
            flow1 = f'用户:[{login_user}]给用户[{user_money}] 转账:[{money}] 元 成功'
            login_user_dic['flow'].append(flow1)
            flow2 = f'用户:[{user_money}]接受用户[{login_user}] 转账:[{money}] 元 成功'
            user_money_dic['flow'].append(flow2)
            db_hander.user_save(login_user_dic)
            db_hander.user_save(user_money_dic)
            msg = f'用户:[{login_user}]给用户[{user_money}] 转账:[{money}] 元 成功'
            user_logger.info(msg)
            return True, msg
        msg = f'用户:[{login_user}]银行余额不足'
        user_logger.info(msg)
        return False, msg
    
    
    # 流水接口列表查询
    def check_flow_interface(login_user):
        # 先获取用户字典
        login_user_dic = db_hander.user_select(login_user)
        flow_list = login_user_dic['flow']
        return flow_list
    
    
    # 支付接口
    def pay_interface(login_user, cost):
        user_dic = db_hander.user_select(login_user)
        if user_dic.get('balance') >= cost:
            user_dic['balance'] -= cost
    
            flow = f'用户:{login_user}消费金额:{cost}'
            user_dic['flow'].append(flow)
            db_hander.user_save(user_dic)
            user_logger.info(flow)
            return True
        return False
    
    
    

    shop_interface.py(购物业务接口处理)

    '''
    购物商城接口
    '''
    from interface import bank_interface
    from db import db_hander
    from lib import common
    shop_logger = common.get_log(log_type='shop')
    
    # 商品准备结算接口
    def shopping_interface(login_user, shopping_car):
        # 计算商品总价
        cost = 0
        for shop_price in shopping_car.values():
            price, number = shop_price
            cost += (price * number)
    
        # 逻辑校验成功,调用银行的支付接口
        flag = bank_interface.pay_interface(login_user, cost)
        if flag:
            msg = f'用户:[{login_user}]支付 [{cost}$] 成功, 准备发货!'
            shop_logger.info(msg)
            return True, msg
    
        return False, '支付失败,金额不足'
    
    
    # 商品添加购物车功能
    def add_shop_car_interface(login_user, shopping_car):
        # 获取当前用户的购物车
        user_dic = db_hander.user_select(login_user)
        #原来用户的字典的商城列表
        shop_car = user_dic.get('shop_car')
    
        for shop_name, price_number in shopping_car.items():
            number = price_number[1]
            if shop_name in shop_car:
                user_dic['shop_car'][shop_name][1] += number
            else:
                user_dic['shop_car'].update(
                    {shop_name: price_number}
                )
            db_hander.user_save(user_dic)
        return True, '添加购物车成功'
    
    # 查看购物车接口
    def check_shop_car_interface(login_user):
        # 获取当前用户的购物车
        user_dic = db_hander.user_select(login_user)
        shop_list = user_dic['shop_car']
        return shop_list
    

    user_interface.py(用户业务接口处理)

    '''
    用户相关的接口
    
    '''
    import os
    import json
    
    from db import db_hander
    from lib import common
    user_logger=common.get_log('user')
    
    # 用户注册
    def register_interface(username, password, balance=15000):
        # 2)查看用户是否存在
        # 2.1) 调用 数据处理层 中的 select函数,会返回 用户字典 或 None
        user_dic = db_hander.user_select(username)
    
        # {user: user, pwd: pwd...}   or  None
        # 若用户存在,则return,告诉用户重新输入
        if user_dic:
            # return (False, '用户名已存在!')
            return False, '用户名已存在!'
    
        # 3)若用户不存在,则保存用户数据
        # 做密码加密
        password = common.salt(username, password)
    
        # 3.1) 组织用户的数据的字典信息
        user_dic = {
            'username': username,
            'password': password,
            'balance': balance,
            # 用于记录用户流水的列表
            'flow': [],
            # 用于记录用户购物车
            'shop_car': {},
            # locked:用于记录用户是否被冻结
            # False: 未冻结   True: 已被冻结
            'locked': False
        }
    
        # 3.2)保存数据
        db_hander.user_save(user_dic)
        msg=f'{username} 注册成功!'
        user_logger.info(msg)
        return True, msg
    
    
    # 登录接口
    def longin_interface(username, password):
        # 先查看用户是否存在
        user_dic = db_hander.user_select(username)
        password_md5 = common.salt(username, password)
    
        if user_dic:
            print(user_dic.get('locked'))
            if user_dic.get('locked'):
                return False, f'用户:[{username}]已经被冻结'
            if password_md5 == user_dic['password']:
                msg=f'用户:[{username}] 登录成功  '
                user_logger.info(msg)
                return True,msg
    
            else:
                msg = f'用户:[{username}]密码错误'
                user_logger.warning(msg)
                return False, msg
        msg = f'用户[{username}]不存在,请重新输入'
        user_logger.info(msg)
        return False, msg
    
    
    # 查看用户余额接口
    def check_balance_interface(login_user):
        user_dic = db_hander.user_select(login_user)
        return user_dic.get('balance')
    

    lib

    common.py(公用类,盐MD5加密,登录装饰器)

    import hashlib
    from core import src
    from conf import setting
    import logging.config
    
    
    # 盐加密,通名字加密 密码
    
    def salt(username, password):
        password_ms5= hashlib.md5()
        password_ms5.update((username+password).encode('utf-8'))
        res = password_ms5.hexdigest()
        return res
    
    
    # 登录认证装饰器
    def login_auth(func):
        def inner(*args, **kwargs):
            if src.login_user:
                res = func(*args, **kwargs)
                return res
            else:
                print('未出示证明,无法享受服务')
                src.login()
    
        return inner
    
    
    # 添加日志功能(日志功能在接口层使用)
    def get_log(log_type):
        '''
        :param log_type:  user日志   bank日志   购物商城日志
        :return:
        '''
        # 1、加载日志配置信息
        logging.config.dictConfig(
            setting.LOGGING_DIC
        )
        # 获取日志对象
        logger = logging.getLogger(log_type)
        return logger
    

    log(日志文件记录)

    a1.log

    2020-11-29 23:03:52,782 - MainThread:13396 - 日志名字:user - user_interface.py:58 -INFO - 用户:[q]登录成功!
    2020-11-29 23:04:11,089 - MainThread:13396 - 日志名字:user - user_interface.py:58 -INFO - 用户:[w]登录成功!
    2020-11-29 23:04:15,584 - MainThread:13396 - 日志名字:user - user_interface.py:69 -INFO - 用户不存在,请重新输入

    整体项目架构不错,可以很清楚了解到三层架构的构建

    用户点击:用户视图层————————》业务接口处理————————》数据库数据处理

    数据返回用户:数据处理完数据————————》业务接口处理————————》用户视图层

  • 相关阅读:
    Redis分布式锁的实现原理
    Redis锁的简单应用
    Redis所需内存 超过可用内存怎么办
    redis学习笔记之虚拟内存
    组织安全性SQL
    应收发票相关脚本
    用户与职责与请求关系语句
    应收事物处理删除 SQL 语句
    总账库存科目明细追溯
    月结各模块关闭情况查询
  • 原文地址:https://www.cnblogs.com/heian99/p/14124796.html
Copyright © 2020-2023  润新知