zoukankan      html  css  js  c++  java
  • day07作业---ATM+购物车

    ATM三层架构思路:

    启动文件

    首先,创建一个start.py作为整个项目启动的启动文件。
    然后导入os和sys模块,从core中导入src,也就是用户视图层。
    然后添加解释器的环境变量,再开始执行项目函数。
    在src.py 用户视图层中,先写好各个功能函数名,然后创建一个函数功能字典。
    然后就是视图层的主程序,打印选择列表让用户选择,根据选择的编号来调用不同的功能函数。

    配置信息

    在conf的setting.py中,编写配置文件。
    写好项目的根目录路径BASE_PATH。
    写好商品信息路径GOODS_PATH。
    写好用户信息路径USER_DATA_PATH
    然后写上日志配置(日志格式可以复制粘贴过来)

    公共方法

    在lib的common.py中存放公共方法。
    导入conf的settings配置。
    写上用户的登录认证装饰器。
    导入hashlib模块,写上密码的md5加密,以json格式存储密码。
    导入logging.config,添加日志功能,在接口层使用。

    商品信息

    在db的goods_list.json中编写商品数据,以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}
    }

    数据处理层

    在db的db_handler.py 数据处理层中,导入json和os模块,从conf中导入settings配置。
    编写查看数据函数,接收接口层传过来的username用户名,拼接用户json文件路径。
    校验用户json文件,打开数据,并返回给接口层。
    编写保存数据函数,用于添加新数据或者更新数据。
    拼接用户的数据字典,保存用户数据。
    编写获取商品数据函数,用于获取商品数据。
    商品数据也是以json格式读取的。

    注册功能

    编写interface的user_interface.py的注册接口。
    查看用户是否存在,若存在,返回“用户名已存在!”
    若不存在,就编写一个用户字典保存为“用户名.json”。
    其中,如果用户名是“admin”,就是管理员,字典信息中的“is_admin”为“True”。
    然后调用数据处理层的db_handler的save功能进行保存。
    在core的src.py 用户视图层中,编写注册函数。
    先定义一个全局遍历login_user = None,用来记录用户是否已登录。
    让用户输入用户名和密码进行注册,2次密码必须相同。
    调用接口层的注册接口,将用户名与密码交给接口层来进行处理。
    输入的用户名如果是admin,就是管理员,其余是普通用户。
    根据flag判断用户注册是否成功,flag控制break的结束。

    登录功能

    编写interface的user_interface.py的登录接口。
    先调用数据处理层的db_handler的select功能查看当前用户数据是否存在。
    如果存在,就继续执行,如果不存在,就输出“用户不存在,请重新输入!”
    再根据get用户字典的‘locker’的True或False判断用户是否被冻结。
    然后给用户的密码做一次加密,和取过来的加密的用户密码比对,查看是否一致。
    如果一致,就登录成功;如果不一致,登录失败。
    在core的src.py 用户视图层中,编写登录函数。
    让用户输入用户名和密码。
    调用接口层的登录接口,将用户名与密码交给接口层来进行处理。
    输入的用户名如果是admin,就是管理员,其余是普通用户。
    根据flag判断用户注册是否成功,flag控制break的结束。

    查看余额功能

    编写interface的user_interface.py的查看余额接口。
    编写user_dic调用数据处理层的db_handler的select功能查看当前用户的余额。
    返回给用户视图层。
    在core的src.py 用户视图层中,编写查看余额函数。
    只有登录的用户才能查看。
    调用接口层的查看余额接口,传入当前登录的用户名。
    打印用户名和用户金额。

    提现功能

    编写interface的user_interface.py的查看提现接口。
    编写user_dic调用数据处理层的db_handler的select功能查看当前用户的余额。
    把当前余额变成整型,然后计算手续费。
    判断用户金额是否足够,如果足够,就修改用户字典中的金额,如果不足够,就退出并提示“余额不足!”
    记录流水,调用数据处理层的db_handler的save和update功能保存并更新数据。
    将结果返回给用户视图层。
    在core的src.py 用户视图层中,编写提现函数。
    只有登录的用户才能提现。
    让用户输入提现金额,判断用户输入的金额是否是数字,如果不是,就重新输入。
    用户提现金额,将提现的金额交付给接口层来处理,传入当前登录的用户名。
    调用接口层的查看余额接口,传入当前登录的用户名。
    打印用户名和提现信息和余额信息。

    还款功能

    编写interface的user_interface.py的查看还款接口。
    编写user_dic调用数据处理层的db_handler的select功能查看当前用户的余额。
    把当前余额变成整型,然后计算还款额。
    记录流水,调用数据处理层的db_handler的save和update功能保存并更新数据。
    将结果返回给用户视图层。
    在core的src.py 用户视图层中,编写还款函数。
    只有登录的用户才能提现。
    让用户输入提现金额,判断用户输入的金额是否是数字,如果不是,就重新输入。
    用户还款金额,将还款的金额交付给接口层来处理,传入当前登录的用户名。
    调用接口层的查看余额接口,传入当前登录的用户名。
    打印用户名和还款信息和余额信息。

    转账功能

    编写interface的bank_interface.py的转账接口。
    编写login_dic和to_user_dic调用数据处理层的db_handler的select功能。
    获取“当前用户”和“目标用户”字典,判断目标用户是否存在,若用户存在,则判断“当前用户转账金额”是否足够。
    若足够,给当前用户的数据,做减钱操作;给目标用户的数据,做加钱操作,然后记录双方流水。
    调用数据处理层的db_handler的save功能保存数据。
    将结果返回给用户视图层。
    在core的src.py 用户视图层中,编写转账函数。
    只有登录的用户才能提现。
    判断用户输入金额是否是数字或者>0,如果不是,就重新输入。
    让用户输入转账的用户和金额。将输入的信息交付给接口层来处理,传入当前登录的用户名、对方用户名、金额。
    调用接口层的,打印用户名和还款信息和余额信息。

    流水功能

    编写interface的bank_interface.py的查看流水接口。
    编写user_flow_dic字典,调用调用数据处理层的db_handler的select功能,传入当前用户。
    将结果返回给用户视图层。
    在core的src.py 用户视图层中,编写查看流水函数。
    调用interface的bank_interface.py接口,传入当前用户。
    调用流水接口,输出流水信息。

    购物功能

    编写interface的shop_interface.py的购物接口。
    编写goods_dic字典,调用数据处理层的db_handler的select_goods功能查看商品信息。
    将结果返回给用户视图层。
    编写interface的shop_interface.py的add_shop_car_interface购物车添加接口。
    将用户视图层传来的视频信息存入字典。
    如果商品不在购物车中则直接加入,商品在购物车中,修改商品数量以及总价。
    将结果返回给用户视图层。
    在core的src.py 用户视图层中,编写购物函数。
    调用interface的bank_interface.py接口,获取全部商品信息并打印。
    将对应编号的商品加入购物车,调用add_shop_car_interface购物车添加接口。
    调用购物车添加接口,已经入购物车的信息。

    购物车结算功能

    编写interface的shop_interface.py的查看购物车接口。
    编写user_dic字典,调用调用数据处理层的db_handler的select功能,传入当前用户。
    编写shop_car_dic字典,取出user_dic字典中的"shop_car",然后记录流水信息。
    将结果返回给用户视图层。
    在core的src.py 用户视图层中,编写查看购物车函数。
    调用interface的shop_interface.py接口,获取用户字典里的"shop_car"。
    打印购物车内的信息,让用户选择要购买的购物车内的商品ID,输入c清空购物车,输入q退出该界面。
    如果ID不存在,就跳过本次循环,输出信息“商品不存在”。
    获取选择付款商品的商品信息并打印。

    管理员功能

    编写interface的admin_interface.py的查看管理员接口。
    编写4种功能:添加用户直接调用注册函数;修改额度调用用户字典直接修改,冻结和解冻用户修改用户字典的“locker”的bool值。
    将结果返回给用户视图层。
    在core下单独编写一个admin.py。
    编写4个功能函数,调用各个接口。
    编写管理员功能字典:
    admin_dic = {
        '1': add_user,
        '2': change_balance,
        '3': lock_user,
        '4': unlock_user
    }
    编写管理员视图和功能选项,打印选择列表让用户选择,根据选择的编号来调用不同的功能函数。
    在core的src.py 用户视图层中,编写管理员函数。
    直接调用core下的admin.py的admin.run()函数执行功能。
    如果用户名是admin的话,就是管理员,如果不是,就是普通用户,没有资格使用该功能。

    conf:

    settings.py

    存放配置信息
    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:

    项目的说明书
    项目:ATM + 购物车
    项目需求:
    1.额度15000或自定义  ==>  注册功能
    2.实现购物商城,买东西加入购物车,调用信用卡接口结账  ==>  购物功能、支付功能
    3.可以提现,手续费5%  ==>  提现功能
    4.支持多账户登录  ==>  登录功能
    5.支持账户间转账  ==>  转账功能
    6.记录日常消费  ==>  记录流水功能
    7.提供还款接口  ==>  还款功能
    8.ATM记录操作日志  ==>  记录日志功能
    9.提供管理接口,包括添加账户、用户额度,冻结账户等...  ==>  管理员功能
    10.用户认证用装饰器  ==>  登录认证装饰器
    "用户视图层" 展示给用户选择的功能
    1.注册功能
    2.登录功能
    3.查看余额
    4.提现功能
    5.还款功能
    6.转账功能
    7.查看流水
    8.购物功能
    9.查看购物车
    10.管理员功能
    一个项目是如何从无到有
    一 需求分析
    1.拿到项目,会先在客户那里一起讨论需求,
    商量项目的功能是否能实现,周期与价格,得到一个需求文档。
    
    2.最后在公司内部需要开一次会议,最终得到一个开发文档,
    交给不同岗位的程序员进行开发。
        - Python: 后端,爬虫
        
        - 不同的岗位:
            - UI界面设计:
                - 设计软件的布局,会分局软件的外观切成一张张图片。
            
            - 前端:
                - 拿到UI交给他的图片,然后去搭建网页面。
                - 设计一些页面中,哪些位置需要接收数据,需要进行数据交互。
            
            - 后端:
                - 直接核心的业务逻辑,调度数据库进行数据的增删查改。
            
            - 测试:
                - 会给代码进行全面测试,比如压力测试,界面测试(CF的卡箱子BUG)。
            
            - 运维:
                - 部署项目。
    二 程序的架构设计
    1、程序设计的好处
    1) 思路清晰
    2) 不会出现写一半代码时推翻重写
    3) 方便自己或以后的同事更好维护
    2、三层架构设计的好处
    1) 把每个功能都分层三部分,逻辑清晰
    2) 如果用户更换不同的用户界面或不同,
    的数据储存机制都不会影响接口层的核心
    逻辑代码,扩展性强。
    3) 可以在接口层,准确的记录日志与流水。
    3、三层架构
    一 用户视图层
    用于与用户交互的,可以接受用户的输入,打印接口返回的数据。
    二 逻辑接口层
    接受 用户视图层 传递过来的参数,根据逻辑判断调用数据层加以处理,
    并返回一个结果给 用户视图层。
    三 数据处理层
    接受接口层传递过来的参数,做数据的 
        - 保存数据  save()
        - 查看数据  select()
        - 更新数据  update()
        - 删除数据  delete()
    三 分任务开发
    四 测试
    五 上线
    统计代码
    file  ==>  settings  ==>  Plugins  ==>  Statistic  ==>  Installer
    单击左下角:Statistic  ==>  单击:py
        Total Lines:总代码行数
        Sources Code Lines:纯代码行数
        Sources Code Lines[%]:纯代码行数百分比
        Comment Lines:注释行数
        Comment Lines[%]:注释行数百分比
        Blank Lines:空白行数
        Blank Lines[%]:空白行数百分比

    start.py:

    '''
    程序的入口
    '''
    import sys
    import os
    
    #添加解释器的环境变量
    sys.path.append(
        os.path.dirname(__file__)
    )
    
    from core import src
    #开始执行项目函数
    if __name__ == '__main__':
    
    # 1.先执行用户视图层
        src.run()
  • 相关阅读:
    事务传播机制,搞懂。
    洛谷 P1553 数字反转(升级版) 题解
    洛谷 P1200 [USACO1.1]你的飞碟在这儿Your Ride Is Here 题解
    洛谷 P1055 ISBN号码 题解
    洛谷 P2141 珠心算测验 题解
    洛谷 P1047 校门外的树 题解
    洛谷 P1980 计数问题 题解
    洛谷 P1008 三连击 题解
    HDU 1013 题解
    HDU 1012 题解
  • 原文地址:https://www.cnblogs.com/2722127842qq-123/p/13518654.html
Copyright © 2011-2022 走看看