• ATM+购物车代码实现


    conf:

    settings.

    # 存放配置信息
    
    import os
    
    # 获取项目的 根目录路径
    BASE_PATH = os.path.dirname(
        os.path.dirname(__file__)
    )
    
    
    # goods_list文件目录路径
    GOODS_PATH = os.path.join(BASE_PATH, 'db', 'goods_list.json')
    
    # 获取 user_data 文件夹的 目录路径
    USER_DATA_PATH = os.path.join(
        BASE_PATH, 'db', 'user_data'
    )
    
    
    """
    logging配置
    """
    
    # 定义三种日志输出格式 开始
    standard_format = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' 
                      '[%(levelname)s][%(message)s]'  # 其中name为getlogger指定的名字
    simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'
    
    id_simple_format = '[%(levelname)s][%(asctime)s] %(message)s'
    
    # 定义日志输出格式 结束
    # ****************注意1: log文件的目录
    BASE_PATH = os.path.dirname(os.path.dirname(__file__))
    logfile_dir = os.path.join(BASE_PATH, 'log')
    # print(logfile_dir)
    
    # ****************注意2: log文件名
    logfile_name = 'log.log'
    
    # 如果不存在定义的日志目录就创建一个
    if not os.path.isdir(logfile_dir):
        os.mkdir(logfile_dir)
    
    # log文件的全路径
    logfile_path = os.path.join(logfile_dir, logfile_name)
    
    LOGGING_DIC = {
        'version': 1,
        'disable_existing_loggers': False,
        'formatters': {
            'standard': {
                'format': standard_format
            },
            'simple': {
                'format': simple_format
            },
        },
        'filters': {},
        'handlers': {
            # 打印到终端的日志
            'console': {
                'level': 'DEBUG',
                'class': 'logging.StreamHandler',  # 打印到屏幕
                'formatter': 'simple'
            },
            # 打印到文件的日志,收集info及以上的日志
            'default': {
                'level': 'DEBUG',
                'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件
                'formatter': 'standard',
                'filename': logfile_path,  # 日志文件
                'maxBytes': 1024 * 1024 * 5,  # 日志大小 5M
                'backupCount': 5,
                'encoding': 'utf-8',  # 日志文件的编码,再也不用担心中文log乱码了
            },
        },
        'loggers': {
            # logging.getLogger(__name__)拿到的logger配置
            '': {
                'handlers': ['default', 'console'],  # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
                'level': 'DEBUG',
                'propagate': True,  # 向上(更高level的logger)传递
            },
        },
    }

    core:

    admin.py

    from core import src
    from interface import admin_interface
    
    
    # 添加用户
    def add_user():
        src.register()
    
    
    # 修改用户额度
    def change_balance():
        while True:
            # 1.输入修改的用户名
            change_user = input('请输入需要修改额度的用户:').strip()
    
            # 2.输入修改用户额度
            money = input('请输入需要修改的用户额度:').strip()
            if not money.isdigit():
                continue
    
            # 3.调用修改额度接口
            flag, msg = admin_interface.change_balance_interface(
                change_user, money
            )
    
            if flag:
                print(msg)
                break
            else:
                print(msg)
    
    
    # 冻结用户
    def lock_user():
        while True:
            # 1.输入懂的用户名
            to_lock_user = input('请输入需要冻结的用户:').strip()
    
            # 2.调用冻结用户接口
            flag, msg = admin_interface.lock_user_interface(
                to_lock_user
            )
    
            if flag:
                print(msg)
                break
            else:
                print(msg)
    
    
    # 解冻用户
    def unlock_user():
        while True:
            # 1.输入懂的用户名
            to_unlock_user = input('请输入需要解冻的用户:').strip()
    
            # 2.调用冻结用户接口
            flag, msg = admin_interface.unlock_user_interface(
                to_unlock_user
            )
    
            if flag:
                print(msg)
                break
            else:
                print(msg)
    
    
    # 管理员功能字典
    admin_dic = {
        '1': add_user,
        '2': change_balance,
        '3': lock_user,
        '4': unlock_user
    }
    
    
    def admin_run():
        while True:
            print('''
            ======== 管理员功能 ========
            |       1.添加账户         |
            |       2.修改额度         |
            |       3.冻结账户         |
            |       4.解冻账户         |
            ========= THE END =========
                ''')
            choice = input('请输入管理员功能编号(按q退出):').strip()
    
            if choice.lower() == 'q':
                break
    
            # 判断功能编号是否存在
            if choice not in admin_dic:
                print('请输入正确的功能编号!')
                continue
    
            # 调用用于选择的功能函数
            admin_dic.get(choice)()  # admin_dic.get('1')() ---> add_user()

    src.py

    '''
    用户视图层
    '''
    from interface import user_interface
    from interface import bank_interface
    from interface import shop_interface
    from lib import common
    
    # 全局变量,记录用户是否已登录
    login_user = None
    
    
    # 1.注册功能
    def register():
        print('注册功能执行中...')
        while True:
            # 1.让用户输入用户名与密码进行校验
            username = input('请输入用户名: ').strip()
            password = input('请输入密码: ').strip()
            re_password = input('请确认密码: ').strip()
            # 可以输入自定义的金额
    
            # 小的逻辑处理: 比如两次密码是否一致
            if password == re_password:
                # 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)
                    break
    
                else:
                    print(msg)
    
    
    # 2.登录功能
    def login():
        print('登录功能执行中...')
        # 登录视图
        while True:
            # 1.让用户输入用户名与密码
            username = input('请输入用户名: ').strip()
            password = input('请输入密码: ').strip()
    
            # 2.调用接口层,将数据传给登录接口
            # (True, f'用户: [{username}] 登录成功!'),
            # (return False, '密码错误'), (False, '用户不存在,请重新输入!')
            flag, msg = user_interface.login_interface(
                username, password
            )
            if flag:
                print(msg)
                # 记录用户信息,已登录
                global login_user
                login_user = username
                break
    
            else:
                print(msg)
    
    
    # 3.查看余额
    @common.login_auth
    def check_balance():
        print('查看余额功能执行中...')
        # 1.直接调用查看余额接口,获取用户余额
        balance = user_interface.check_bal_interface(
            login_user
        )
    
        print(f'用户[{login_user}] 账户余额为: [{balance}元]!')
    
    
    # 4.提现功能
    @common.login_auth
    def withdraw():
        print('提现功能执行中...')
        while True:
            # 1.让用户输入提现金额
            input_money = input('请输入提现金额: ').strip()
    
            # 2.判断用户输入的金额是否是数字
            if not input_money.isdigit():
                print('请重新输入')
                continue
    
            # 3.用户提现金额,将提现的金额交付给接口层来处理
            flag, msg = bank_interface.withdraw_interface(
                login_user, input_money
            )
    
            if flag:
                print(msg)
                break
            else:
                print(msg)
    
    
    # 5.还款功能
    @common.login_auth
    def repay():
        print('还款功能执行中...')
        while True:
            # 1.让用户输入还款金额
            input_money = input('请输入还款金额: ').strip()
    
            # 2.判断用户输入的金额是否是数字
            if not input_money.isdigit():
                print('请重新输入')
                continue
    
            input_money = int(input_money)
            if input_money > 0:
                # 3.用户还款金额,将还款的金额交付给接口层来处理
                flag, msg = bank_interface.repay_interface(
                    login_user, input_money
                )
    
                if flag:
                    print(msg)
                    break
                else:
                    print(msg)
    
            else:
                print('输入的金额不能小于等于0!')
    
    
    # 6.转账功能
    @common.login_auth
    def transfer():
        print('转账功能执行中...')
        '''
        1.接收用户输入的 转账目标用户
        2.接收用户输入的 转账金额
        '''
        while True:
    
            # 1.让用户输入转账用户和金额
            to_user = input('请输入转账目标用户:').strip()
            money = input('请输入转账金额:').strip()
    
            # 2.判断用户输入金额是否是数字或者>0
            if not money.isdigit():
                print('请输入正确的金额!')
                continue
    
            money = int(money)
    
            if money > 0:
                # 3.调用转账接口
                flag, msg = bank_interface.transfer_interface(
                    # 当前用户,目标用户,转账金额
                    login_user, to_user, money
                )
                if flag:
                    print(msg)
                    break
                else:
                    print(msg)
    
            else:
                print('请输入正确的金额!')
    
    
    # 7.查看流水
    @common.login_auth
    def check_flow():
        print('查看流水功能执行中...')
        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():
        print('购物功能执行中...')
        while True:
            # 获取全部商品信息并打印
            goods_dic = shop_interface.get_goods_interface()
            print('=================== Welcome To Hardware World ===================
    ')
            for number, goods_info in goods_dic.items():
                print(f'| 编号:[{number}] 商品名:[{goods_info.get("goods_name")}] 价格:[{goods_info.get("price")}]元')
            print('')
            print("============================ THE END ============================")
            goods_id = input("请输入要购买的商品编号(按q返回上一层):").strip()
            if goods_id.lower() == 'q':
                break
            count = input("请输入购买的数量:").strip()
            if not count.isdigit() or count == '0':
                print("输入错误")
                continue
            if goods_id not in goods_dic:
                print('该商品不存在')
                continue
            # 将对应编号的商品加入购物车
            shop_interface.add_shop_car_interface(goods_dic[goods_id], int(count))
            print(f"{goods_dic[goods_id]['goods_name']}已加入购物车,请到购物车结算")
    
    
    # 作业:清空购物车功能
    # 清空购物车
    def clean_shop_car():
        inp_clear = input("是否清空购物车?(Y/N):").strip()
        if inp_clear.lower() != 'y':
            print("清空购物车失败,用户取消操作")
            return False
        msg = shop_interface.clean_shop_car_interface(login_user)
        print(msg)
        return True
    
    
    # 9.查看购物车
    @common.login_auth
    def check_shop_car():
        print('查看购物车功能执行中...')
        shop_car_dic = shop_interface.check_shop_car_interface(login_user)
        while True:
            shop_id = 0
            print("========================  购物车内容  =========================")
            print('')
            for goods_name, goods_info in shop_car_dic.items():
                print(f'| ID:[{shop_id}] 商品名 {goods_name} 数量 {goods_info.get("count")}个 总价 {goods_info.get("total")}元')
                shop_id += 1
            print('')
            print("========================== THE END  ==========================")
            pay_id = input("请选择需要付款的商品ID(按q离开购物车,按c清空购物车):").strip()
            if pay_id.lower() == 'c':
                flog = clean_shop_car()
                if flog:
                    return
                continue
            if pay_id.lower() == 'q':
                break
            if int(pay_id) not in range(len(shop_car_dic)):
                print("商品不存在")
                continue
            # 获取选择付款商品的商品信息并打印
            buy_goods_name = list(shop_car_dic.keys())[int(pay_id)]
            buy_goods_count = shop_car_dic[buy_goods_name].get('count')
            buy_goods_total = shop_car_dic[buy_goods_name].get('total')
            print(f"您将付款的商品为:{buy_goods_name},数量为:{buy_goods_count}个, 总价为:{buy_goods_total}元")
            # 付款
            inp_buy = input("确认付款(Y/n):").strip()
            if inp_buy.lower() == 'y':
                flog, msg = shop_interface.payment_interface(login_user, buy_goods_name, buy_goods_total)
                if flog:
                    print(msg)
                    break
                else:
                    print('msg')
            print("付款失败,用户取消支付")
    
    
    @common.login_auth
    # 10.管理员功能
    def admin():
        print('管理员功能执行中...')
        from core import admin
        if login_user == 'admin':
            admin.admin_run()
        else:
            print('你没有资格!')
    
    
    # 创建函数功能字典
    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,
    }
    
    
    # 视图层主程序
    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)()  # func_dic.get('1')() ---> register()

    db:

    userdata

    用于存放用户信息

    db_handler.py

    '''
    数据处理层
        专门用于处理数据的
    '''
    
    import os
    import json
    from conf import settings
    
    
    # 查看数据
    def select(username):
        # 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, mode='rt', encoding='UTF-8') as f:
                user_dic = json.load(f)
                return user_dic
    
    
    # 保存数据(添加新数据或者更新数据)
    def save(user_dic):
        # 1.拼接用户的数据字典
        username = user_dic.get('username')
    
        user_path = os.path.join(
            settings.USER_DATA_PATH, f'{username}.json'
        )
        # 2.保存用户数据
        with open(user_path, mode='wt', encoding='UTF-8') as f:
            # ensure_ascii=False让文件中的中文数据,显示更美观
            json.dump(user_dic, f, ensure_ascii=False)
    
    
    # 获取商品数据
    def select_goods():
        with open(settings.GOODS_PATH, mode='rt', encoding='UTF-8') as f:
            goods_dic = json.load(f)
            return goods_dic

    goods_list.json

    {
      "0": {"goods_name": "logitech-G703", "price": 549},
      "1": {"goods_name": "Antec-HCG750W", "price": 799},
      "2": {"goods_name": "ROG-M11E-Z390", "price": 6999},
      "3": {"goods_name": "G.SKILL-16G-RGB", "price": 769},
      "4": {"goods_name": "Intel-i9-9900KF", "price": 3599},
      "5": {"goods_name": "SAMSUNG-970Pro-1T", "price": 2699},
      "6": {"goods_name": "Segotep-K1(ATX3.0)", "price": 499},
      "7": {"goods_name": "ROG-RTX-2080Ti-11G", "price": 11999},
      "8": {"goods_name": "CHERRY-MX6.0-BLUE RGB", "price": 1399},
      "9": {"goods_name": "ASUS-ROG-360mm-RGB Aura", "price": 2299},
      "10": {"goods_name": "SAMSUNG-27inch-Space-2K/144Hz", "price": 3499}
    }

    interface:

    admin_interface.py

    from db import db_handler
    from lib import common
    
    # 根据不同的接口类型传入不同的日志对象
    admin_logger = common.get_logger(log_type='admin')
    
    
    # 修改额度接口
    def change_balance_interface(username, money):
        user_dic = db_handler.select(username)
    
        if user_dic:
            # 修改额度
            user_dic['balance'] = int(money)
    
            # 保存修改后用户的数据
            db_handler.save(user_dic)
            msg = f'管理员修改用户: [{username}]额度修改成功!'
            admin_logger.info(msg)
    
            return True, '额度修改成功!'
    
        return False, '该用户不存在!'
    
    
    # 冻结接口
    def lock_user_interface(username):
        user_dic = db_handler.select(username)
    
        if user_dic:
            if not user_dic['locked']:
                # 将locked的默认值改为True
                user_dic['locked'] = True
                db_handler.save(user_dic)
    
                msg = f'用户:[{username}]冻结成功!'
                admin_logger.info(msg)
                return True, msg
            else:
                return False, '该用户已被冻结,无需再次冻结!'
    
        return False, '冻结用户不存在!'
    
    
    # 解冻接口
    def unlock_user_interface(username):
        user_dic = db_handler.select(username)
    
        if user_dic:
            if user_dic['locked']:
                # 将locked的默认值改为False
                user_dic['locked'] = False
                db_handler.save(user_dic)
    
                msg = f'用户:[{username}]解冻成功!'
                admin_logger.info(msg)
                return True, msg
            else:
                return False, '该用户未被冻结,无需解冻!'
    
        return False, '解冻用户不存在!'

    bank_interface.py

    # 银行相关业务的接口
    import time
    from db import db_handler
    from lib import common
    
    # 根据不同的接口类型传入不同的日志对象
    bank_logger = common.get_logger(log_type='bank')
    
    # 记录当前操作的时间
    start_time = time.strftime('%Y-%m-%d %H:%M:%S')
    
    
    # 提现接口(手续费5%)
    def withdraw_interface(username, money):
        # 1.先获取用户字典
        user_dic = db_handler.select(username)
    
        # 账户中的金额
        balance = int(user_dic.get('balance'))
    
        # 提现本金 + 手续费
        money2 = int(money) * 1.05  # ---> float
    
        # 判断用户金额是否足够
        if balance >= money2:
            # 2.修改用户字典中的金额
            balance -= money2
    
            user_dic['balance'] = balance
    
            # 3.记录流水
            flow = f'{start_time} 用户:[{username}] 提现金额:[{money}元]成功,手续费为: [{money2 - float(money)}元]'
            user_dic['flow'].append(flow)
    
            # 4.再保存数据,或更新数据
            db_handler.save(user_dic)
            bank_logger.info(flow)
            return True, flow
    
        return False, '提现金额不足,请重新输入!'
    
    
    # 还款接口(无需手续费)
    def repay_interface(username, money):
        # 1.先获取用户字典
        user_dic = db_handler.select(username)
    
        # 2.直接做加钱操作
        # user_dic['balance'] ==> int
        user_dic['balance'] += money
        new_money = user_dic['balance']
    
        # 3.记录流水
        flow = f'{start_time} 用户:[{username}]  还款:[{money}]成功!'
        user_dic['flow'].append(flow)
    
        # 4.调用数据处理层,将修改后的数据更新
        db_handler.save(user_dic)
        bank_logger.info(f'{start_time} 用户:{username} 还款成功,还款金额:[{money}]元')
        return True, flow
    
    
    # 转账接口
    def transfer_interface(login_user, to_user, money):
        '''
        1.获取“当前用户”数据
        2.获取“目标用户”数据
        3.获取“转账金额”数据
        :return:
        '''
    
        # 1.获取“当前用户”字典
        login_user_dic = db_handler.select(login_user)
    
        # 2.获取“目标用户”字典
        to_user_dic = db_handler.select(to_user)
    
        # 3.判断目标用户是否存在
        if not to_user_dic:
            bank_logger.warning(f'{start_time} 用户:[{login_user}] 转账失败,用户:[{to_user}]不存在')
            return False, '目标用户不存在!'
    
        # 4.若用户存在,则判断“当前用户转账金额”是否足够
        if login_user_dic['balance'] >= money:
            # 5.若足够,则开始给目标用户转账
            # 5.1.给当前用户的数据,做减钱操作
            login_user_dic['balance'] -= money
    
            # 5.2.给目标用户的数据,做加钱操作
            to_user_dic['balance'] += money
    
            # 5.3.记录当前用户 与 目标用户 的流水
            # 当前用户流水
            login_user_flow = f'{start_time} 用户:[{login_user}] 给 用户:[{to_user}] 转账:[{money}元]'
            login_user_dic['flow'].append(login_user_flow)
    
            # 目标用户流水
            to_user_flow = f'{start_time} 用户:[{to_user}] 接收 用户:[{login_user}] 转账:[{money}元]'
            to_user_dic['flow'].append(to_user_flow)
    
            # 6.调用数据处理层的save功能,保存用户数据
            # 6.1.保存当前用户数据
            db_handler.save(login_user_dic)
    
            # 6.2.保存目标用户数据
            db_handler.save(to_user_dic)
            bank_logger.info(f'{login_user} 转账成功,对方用户:[{to_user}],转账金额[{money}]元')
            return True, login_user_flow
    
        else:
            bank_logger.warning(f'{start_time} 用户:[{login_user}] 转账失败,余额不足')
            return False, '余额不足,转账失败!'
    
    
    # 查看流水接口
    def check_flow_interface(login_user):
        user_flow_dic = db_handler.select(login_user)
        return user_flow_dic['flow']
    
    
    # 支付接口
    def pay_interface(login_user, cost):
        user_dic = db_handler.select(login_user)
    
        # 判断用户金额是否足够
        if user_dic.get('balance') >= cost:
            # 扣费
            user_dic['balance'] -= cost
    
            # 记录消费流水
            flow = f'用户消费金额:[{cost}元]'
            user_dic['flow'].append(flow)
    
            # 保存数据
            db_handler.save(user_dic)
    
            # return True 或者 return False 交给购物接口来操作
            return True
    
        return False

    shop_interface.py

    # 商品购买接口
    import time
    from db import db_handler
    from lib import common
    
    # 根据不同的接口类型传入不同的日志对象log_type=
    shop_logger = common.get_logger(log_type='shop')
    
    start_time = time.strftime('%Y-%m-%d %H:%M:%S')
    
    
    # 获取商品信息接口
    def get_goods_interface():
        goods_dic = db_handler.select_goods()
        return goods_dic
    
    
    # 商品准备结算接口
    def payment_interface(login_user, buy_goods_name, buy_goods_total):
        user_dic = db_handler.select(login_user)
        # 获取用户购物车字典
        shop_car_dic = user_dic['shop_car']
        # 获取用户余额
        balance = user_dic['balance']
        if buy_goods_total > balance:
            shop_logger.warning(f'用户:[{login_user}] 支付失败,余额不足')
            return False, '支付失败,余额不足'
        balance -= buy_goods_total
        shop_car_dic.pop(buy_goods_name)
        # 修改用户余额
        user_dic['balance'] = balance
        # 删除已付款商品
        user_dic['shop_car'] = shop_car_dic
        # 增加流水
        user_dic['flow'].append(f'{start_time} 用户:[{login_user}] 购买商品:[{buy_goods_name}] 消费:[{buy_goods_total}]元')
        # 更新用户数据
        db_handler.save(user_dic)
        shop_logger.info(f'{start_time} 用户:{login_user} 付款成功! 商品:[{buy_goods_name}] 等待发货')
        return True, '支付成功'
    
    
    # 购物车添加接口
    def add_shop_car_interface(goods_dic, count):
        from core import src
        total = goods_dic["price"] * count
        goods_name = goods_dic['goods_name']
        shop_dic = {
            f"{goods_name}": {"count": count, "total": total}
        }
        user_dic = db_handler.select(src.login_user)
        # 用户购物车内商品信息
        shop_car_dic = user_dic['shop_car']
        # 如果购物车为空则直接加入
        if user_dic.get('shop_car') == {}:
            user_dic['shop_car'] = shop_dic
        else:
            # 如果商品不在购物车中则直接加入
            if goods_name not in shop_car_dic:
                shop_car_dic.update(shop_dic)
                user_dic['shop_car'] = shop_car_dic
            else:
                # 商品在购物车中,修改商品数量以及总价
                user_dic['shop_car'].get(goods_name)['count'] += count
                user_dic['shop_car'].get(goods_name)['total'] += total
        db_handler.save(user_dic)
        shop_logger.info(f'{start_time} 用户:{src.login_user} 添加商品:[{goods_name}]至购物车成功')
    
        return True, '添加购物车成功!'
    
    
    # 获取购物车信息接口
    def check_shop_car_interface(login_user):
        user_dic = db_handler.select(login_user)
        shop_car_dic = user_dic["shop_car"]
        shop_logger.info(f'{start_time} 用户:[{login_user}] 查看购物车')
        return shop_car_dic
    
    
    # 清空购物车
    def clean_shop_car_interface(login_user):
        user_dic = db_handler.select(login_user)
        user_dic['shop_car'] = {}
        db_handler.save(user_dic)
        shop_logger.info(f'{start_time} 用户:[{login_user}] 清空了购物车')
        return '清空购物车成功'

    userface_interface.py

    # 逻辑接口层
    #     用户接口
    
    from db import db_handler
    from lib import common
    
    # 根据不同的接口类型传入不同的日志对象
    user_logger = common.get_logger(log_type='user')
    
    
    # 注册接口
    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, '用户名已存在!'
    
        # 3.若用户不存在,则保存用户数据
        # 做密码加密
        password = common.get_pwd_md5(password)
    
        if username == 'admin':
            user_dic = {
                'username': username,
                'password': password,
                'balance': balance,
                # 用于记录用户流水的列表
                'flow': [],
                # 用于记录用户购物车
                'shop_car': {},
                # locked:用于记录用户是否被冻结
                # False: 未冻结   True: 已被冻结
                'is_admin': True
                }
    
        # 3.1.组织用户的数据的字典信息
        user_dic = {
            'username': username,
            'password': password,
            'balance': balance,
            # 用于记录用户流水的列表
            'flow': [],
            # 用于记录用户购物车
            'shop_car': {},
            # locked:用于记录用户是否被冻结
            # False: 未冻结   True: 已被冻结
            'locked': False,
            'is_admin': False
    
        }
    
        # 3.2.保存数据
        db_handler.save(user_dic)
        msg = f'{username} 新用户注册成功, 初始额度为:{balance}元'
    
        # 3.3.记录日志
        user_logger.info(msg)
    
        return True, msg
    
    
    # 登录接口
    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
    
    
    # 查看余额接口
    def check_bal_interface(username):
        user_dic = db_handler.select(username)
        return user_dic['balance']

    lib:

    common.py

    # 存放公共方法
    
    import hashlib
    from conf import settings
    import logging.config
    
    
    # md5加密
    def get_pwd_md5(password):
        md5_obj = hashlib.md5()
        md5_obj.update(password.encode('UTF-8'))
        salt = '急急如律令!'
        md5_obj.update(salt.encode('UTF-8'))
        return md5_obj.hexdigest()
    
    
    # 登录认证装饰器
    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
    
    
    # 添加日志功能: (日志功能在接口层 使用)
    def get_logger(log_type):  # log_type ---> user
        '''
        :param log_type: 比如是 user日志,bank日志,购物商城日志
        :return:
        '''
        # 1.加载日志配置信息
        logging.config.dictConfig(
            settings.LOGGING_DIC
        )
    
        # 2.获取日志对象
        logger = logging.getLogger(log_type)
    
        return logger

    log:

    log.log

    存放日志信息 readme:

    readme:

    项目说明书
    项目:ATM + 购物车
    
    项目需求:
    1.额度 15000或自定义
    2.实现购物商城,买东西加入 购物车,调用信用卡接口结账
    3.可以提现,手续费5%
    4.支持多账户登录
    5.支持账户间转账
    6.记录每月日常消费流水
    7.提供还款接口
    8.ATM记录操作日志
    9.提供管理接口,包括添加账户、用户额度,冻结账户等。。。
    10.用户认证用装饰器
    -开发软件的公司:帮甲方开发软件的
    
    -客户:指的是某些服务行业的客户,需要找人开发某些软件(甲方)
    
    -用户:甲方的软件已经开始上线,提供给我们(用户)使用
    
    一个项目是如何从无到有
    1.需求分析
    
    需求文档:
    
    额度 15000或自定义  ------------->1.注册功能 (15000默认的额度)
    实现购物商城,买东西加入 购物车,调用信用卡接口结账 ------> 2.购物车功能 3.支付功能
    可以提现,手续费5% ---->4.提现功能
    支持多账户登录  ---->5.登录功能
    支持账户间转账 ----->6.转账功能
    记录每月日常消费流水 ----->7.记录消费流水(设置金额)
    提供还款接口----->8.还款功能
    ATM记录操作日志----->9.记录软件使用日志功能
    提供管理接口,包括添加账户、用户额度,冻结账户等。。。----->10.管理员功能
    用户认证用装饰器----->11.登录认证装饰器
    提取出来的功能:
    
    1.注册功能
    2.购物车功能
    3.支付功能
    4.提现功能
    5.登录功能
    6.转账功能
    7.'记录'消费流水
    8.还款功能
    9.记录日志功能
    10.管理员功能
    11.登录认证装饰器
    提供给用户选择与操作的功能:
    
    1.注册功能
    2.登录功能
    3.查看余额
    4.提现功能
    5.还款功能
    6.转账功能
    7.查看流水
    8.购物功能
    9.查看购物车
    10.管理员功能
    2.软件的架构设计
    
    1、程序设计的好处
        1) 思路清晰
        2) 不会出现写一半代码时推翻重写
        3) 方便自己或以后的同事更好维护
    2、三层架构设计的好处
        1) 把每个功能都分层三部分,逻辑清晰
        2) 如果用户更换不同的用户界面或不同,
        的数据储存机制都不会影响接口层的核心
        逻辑代码,扩展性强。
        3) 可以在接口层,准确的记录日志与流水。
    三层架构:
    
    用户视图层(第一层):提供给用户选择的功能界面
    
    职责:用于与用户进行交互,接受用户输入的数据,交给接口层进行处理,接口层最终会将一个结果给用户视图层,展示给用户看的
    逻辑接口层(第二层):所有核心逻辑都放在接口中,提供给用户视图层来使用(调用)的
    
    登录接口:
         接收用户视图层传递过来的参数,根据逻辑判断调用数据层加以处理,并返回一个结果给用户视图层。
        1.查看用户名,是否存在,若存在,则继续校验密码,若不存在,则返回结果给用户视图层,让用户重新输入
        2.若用户存在,做密码的校验,若密码正确返回登录给用户视图层
    职责:相当于用户视图层与数据处理层的桥梁。专门负责接收用户视图层传过来的数据,并进行'核心的逻辑'校验过程中,回去访问'数据层'进行数据的增删改查,通过或不通过后会返回一个结果给用户视图层进行展示
    数据处理层:(第三层):接受接口层传过来的参数,返回相应的数据给接口层,或者保存数据,做数据的处理
    
    - 保存数据  save()
    - 查看数据  select()
    - 更新数据  update()
    - 删除数据  delete()
    根据用户名查询数据,若有则返回用户数据给接口层,若没有则默认返回None
    3.分任务开发
    
    多个人同步去开发项目,高效开发项目
    - 不同的岗位:
        - UI界面设计:
            - 设计软件的布局,会分局软件的外观切成一张张图片。
        
        - 前端:
            - 拿到UI交给他的图片,然后去搭建网页面。
            - 设计一些页面中,哪些位置需要接收数据,需要进行数据交互。
        
        - 后端:
            - 直接核心的业务逻辑,调度数据库进行数据的增删查改。
        
        - 测试:
            - 会给代码进行全面测试,比如压力测试,界面测试(CF卡箱子)。
        
        - 运维:
            - 部署项目。
    4.测试
    
        4.1手动测试
        4.2自动化测试
    5.上线运行
    
    统计代码
    
    file  ==>  settings  ==>  Plugins  ==>  Statistic  ==>  Installer

    三层架构图

    start.py:

    '''
    程序的入口
    '''
    import sys
    import os
    
    #添加解释器的环境变量
    sys.path.append(
        os.path.dirname(__file__)
    )
    
    from core import src
    #开始执行项目函数
    if __name__ == '__main__':
    
    # 1.先执行用户视图层
        src.run()
  • 相关阅读:
    raspbian设置locale
    docker redis
    consul开发部署集群
    自动更新ssh登录的key到远程主机
    docker官方脚本阿里云镜像
    nodejs中国镜像
    github修改hosts加速
    docker容器更新总是自动重启
    webstrom不显示右边的竖线,代码结构线
    _mssql.c:266:22: fatal error: sqlfront.h: No such file or directory
  • 原文地址:https://www.cnblogs.com/2722127842qq-123/p/13392680.html
Copyright © 2020-2023  润新知