zoukankan      html  css  js  c++  java
  • ATM+购物车三层结构+分析

    一个项目如何从无到有

    需求分析

    1. 拿到项目会先在客户那里一起讨论需求,商量项目的功能能否实现,周期与价格,得到一个需求文档

    2. 公司内部开一个会,最终得到一个开发文档,交给不同岗位的程序员开发不同的岗位:

    • UI:设计软件的布局,会将软件的外观切成一张张图片
    • 前端:根据拿到的图片去搭建网页界面,设计一些页面中,哪些位置需要接收数据,需要进行数据交互
    • 后端:直接核心的业务逻辑,调度数据库进行数据的增删改查
    • 测试:给代码进行全面测试,比如压力测试,界面测试
    • 运维:搭建项目

    程序的架构设计

    程序设计的好处

    1. 思路清晰
    2. 不会出现写一半代码时推翻重写
    3. 方便自己或以后的同事维护

    分层处理:

    一 用户视图层

    用户视图层是展示给用户看的,用户视图层展示相关功能给用户看的,接收用户输入的内容
    比如用户通过注册功能,输入用户名和密码,用户视图层也可以校验简单的逻辑,比如用户注册时两次输入的密码是否一致;

      

    二逻辑处理层

    逻辑处理层主要是用来接收视图层传数据处理层的内容并进行逻辑判断,组织数据,同时记录相关流水与日志。
    

      

    三 数据处理层

    数据处理层主要是进行数据的增删改查

    用户注册时,用户视图层接收用户输入的内容并传给逻辑接口层,接口层接收到数据传递给数据处理层,如果用户已存在,则返回该用户对应的信息,否则返回 None
    逻辑接口层拿到数据处理返回的数据,进行 判断,如果接收到的是用户信息已存在,则告诉视图层,该用户已存在,否则继续注册。

    用户登录时,用户视图层接收用户输入的内容并传给逻辑接口层,接口层接收到数据传递给数据处理层,如果用户已存在,则返回该用户对应的信息,否则返回 None
    逻辑接口层拿到数据处理返回的数据,进行判断,如果接收到的是用户信息,则进行比对用户密码是否一致,然后将结果返回用户视图层

      

    项目需求

    额度 15000或自定义
    实现购物商城,买东西加入 购物车,调用信用卡接口结账
    可以提现,手续费5%
    支持多账户登录
    支持账户间转账
    记录每月日常消费流水
    提供还款接口
    ATM记录操作日志
    提供管理接口,包括添加账户、用户额度,冻结账户等。。。
    用户认证用装饰器xxxxxxxxxx 
    

      

    from db import db_handler
    from lib import common
    
    # 初始化的用户登录状态,登录用户名(全局变量)
    login = False
    user_in = None
    
    # 1、注册功能
    def register():
        user = input('请输入账号:').strip()
        pwd = input('请输入密码:').strip()
        pwd1 = input('请确认密码:').strip()
        if user:
            if pwd:
                if pwd == pwd1:
                    users = user_interface.register_interface(user,pwd)
                    print(users)
                    return user
                else:
                    print('密码不一致')
            else:
                print('密码不能为空哦')
        else:
            print('账号不能为空哦')
    
    
    # 2、登录功能
    def user_login():
        global login
        global user_in
        while True:
            user = input('请输入账号:').strip()
            pwd = input('请输入密码:').strip()
            login, user_in = user_interface.login_interface(user,pwd)
            if login:
                print('登录成功')
                break
            else:
                print(user_in)
    
    
    # 3、查看余额
    @common.check_login
    def look_money():
        money = bank_interface.look_money_interface(user_in)
        print('用户 {} 余额为:{}'.format(user_in,money))
    
    
    # 4、提现功能
    @common.check_login
    def top_up():
        while True:
            money = input('请输入提现金额:').strip()
            if money.isdigit():
                done, result = bank_interface.top_up_interface(money,user_in)
                print(result)
                break
            else:
                print('请输入整数数字')
    
    
    # 5、还款功能
    @common.check_login
    def repay():
        while True:
            money = input('请输入充值金额:').strip()
            if money.isdigit():
                result = bank_interface.repay_money_interface(user_in,money)
                print(result)
                break
            else:
                print('请输入整数金额')
    
    
    # 6、转账功能
    @common.check_login
    def transfer():
        while True:
            user2 = input('你想转给谁:').strip()
            money = input('你想转多少:')
            if money.isdigit():
                done, result = bank_interface.transfer_interface(user_in,user2,money)
                print(result)
                if done:
                    break
            else:
                print('请输入整数金额')
    
    
    # 7、查看流水
    @common.check_login
    def look_flow():
        flow = bank_interface.look_flow_interface(user_in)
        if flow:
            print('流水为:{}'.format(flow))
        else:
            print('no flow')
    
    
    # 8、购物功能
    @common.check_login
    def shopping():
        while True:
            print('商品列表如下哦:')
            shop_dic = db_handler.get_shop_data()
            for i in range(len(shop_dic)):
                print('{} {} {} 元'.format(i,shop_dic[str(i)][0],shop_dic[str(i)][1]))
            choice = input('请输入编号,q 退出:').strip()
            if choice.lower() == 'q':
                break
            if choice in shop_dic:
                result = shop_interface.in_shop_interface(user_in,shop_dic[choice])
                print(result)
            else:
                print('没有这个编号的商品')
    
    
    # 9、查看购物车
    @common.check_login
    def look_shop_car():
        result_shop = shop_interface.look_shop_interface(user_in)
        goods = result_shop[1]
        if result_shop[0] != 0:
            print('购物车商品如下:')
            for good in goods:
                print('商品名称:{} 商品数量:{} 商品单价:{} 元 '.format(good,goods[good][0],goods[good][1]))
            print('商品总价格:{}'.format(result_shop[0]))
            choice = input('是否付款:y/n:').strip()
            if choice.lower() == 'y':
                result = bank_interface.pay_money_interface(user_in)
                print(result[1])
        else:
            print('还没有商品')
    
    
    # 10、管理员视图层
    @common.check_login
    def rooter():
        from core import root  # 涉及到循环导入,从这里调用管理员视图层,管理员视图层也需要该用户视图层的信息,比如,已登录的账号名,登录状态(全局变量)
        root.root_run()  # 新的管理员的视图层
    
    
    
    def run():
        func_dic = {
            '0': ['用户注册', register],
            '1': ['用户登录', user_login],
            '2': ['查看余额', look_money],
            '3': ['提现', top_up],
            '4': ['还款', repay],
            '5': ['转账', transfer],
            '6': ['查看流水', look_flow],
            '7': ['购物', shopping],
            '8': ['查看购物车', look_shop_car],
            '9': ['管理员', rooter],
        }
        # settings.logging.info('egon充值5元')  #Windows 存储 gbk  mac Linux 存储 utf-8
        while True:
            print('功能列表如下:')
            for i in range(len(func_dic)):
                print('{} {}'.format(i,func_dic[str(i)][0]))
            choice = input('请输入编号(q退出):').strip()
            if choice.lower() == 'q':
                break
            if choice in func_dic:
                func_dic[choice][1]()
            else:
                print('没有这个功能编号,傻叉')
    

      用户视图层:输入用户名和密码,确认密码,进行小逻辑判断,接收逻辑接口层的返回值,打印输出结果。
    逻辑处理层:接收用户视图层的输入,即用户名,密码。调用查看用户接口(数据处理层),进行注册功能的核心逻辑处理,判断用户是否存在,不存在就添加用户,将处理结果返回给用户视图层。逻辑处理过程中,涉及到数据处理,要将一些值交给数据处理层,处理后的结果继续使用,或者返回用户视图层。
    数据处理层:接收其它层的数据,进行数据的增删改查,是数据相关的一些操作。注册:查:查询用户接口,返回用户信息,如果返回信息不为空,就是存在该用户,返回None,就是不存在该用户,查询用户接口是与数据处理相关,所以是数据处理层;增改:更新用户数据接口,增加该用户,也可以看做是修改用户的存储信息。

    # 注册接口
    def register_interface(user, pwd):
        user_data = db_handler.check_user(user)
        if user_data:
            return '用户已存在'
        pwd = common.get_mb5_pwd(pwd)
        user_dic = {
            'username': user,
            'pwd': pwd,
            'flow': [],
            'shop': {},
            'balance': 0,
            'block': False
        }
        settings.logging.info('{} 注册了'.format(user))
        db_handler.add_user(user_dic)
        return '注册成功'
    

      登录功能:
    用户视图层:输入用户名和密码,进行小逻辑判断,接收逻辑接口层的返回值,打印输出结果。
    逻辑处理层:接收用户视图层的输入,即用户名,密码。进行核心逻辑处理,判断用户是否存在,存在就校验密码是否正确,如果正确,就登录成功,将处理结果返回给用户视图层。逻辑处理过程中,涉及到数据处理,要将一些值交给数据处理层,处理后的结果继续使用,或者返回用户视图层。可以从数据处理层返回的信息中,得到用户名和密码,进行校验。
    数据处理层:接收其它层的数据,进行数据的增删改查,是数据相关的一些操作。登录:查:返回用户信息;

    # 登录接口
    def login_interface(user, pwd):
        user_dic = db_handler.check_user(user)
        if user_dic:
            if user_dic['block']:
                return False, '用户已被锁定了'
            pwd = common.get_mb5_pwd(pwd)
            if pwd == user_dic.get('pwd'):
                user_in = user
                settings.logging.info('{} 登录了'.format(user))
                return True, user_in
            else:
                return False, '密码不正确'
        else:
            return False, '用户不存在'
    

      

    注意:密码要进行加密操作,用户信息字典,要存储成json格式。

    以下功能要注意验证登录状态,即添加登录装饰器,登录后才能操作,设置全局变量登录状态:login,登录用户user_in

    查看余额:
    用户视图层:将登录用户名传给查看用户接口,即传到逻辑接口层,接收逻辑接口层的返回值,打印输出结果。
    逻辑处理层:接收用户视图层的输入,即已登录用户名。进行核心逻辑处理,因为是已登录用户,所以,不用判断用户是否存在;调用数据处理的查询用户接口,直接将用户名传到数据处理层,将处理结果,即用户信息字典,得到字典后,可以 得到 该用户的余额,将其返回给用户视图层打印。
    数据处理层:接收其它层的数据,进行数据的增删改查,是数据相关的一些操作。查询余额:查:返回用户信息;

    # 查询余额接口
    def look_money_interface(user):
        user_dic = db_handler.check_user(user)  # 查看用户接口
        money = user_dic.get('balance')
        return money
    

      提现:
    用户视图层:将登录用户名传给查看用户接口,即传到逻辑接口层,接收逻辑接口层的返回值,打印输出结果。
    逻辑处理层:接收用户视图层的输入,即已登录用户名。进行核心逻辑处理,调用数据处理的查询用户接口,直接将用户名传到数据处理层,将处理结果,即用户信息字典,得到字典后,可以 修改 用户的余额,再将修改后的用户信息,调用 数据层 的 数据更新接口 ,将用户信息进行重新写入,将其结果,比如说,'提现成功',返回给用户视图层打印。
    数据处理层:接收其它层的数据,进行数据的增删改查,是数据相关的一些操作。提现:查:查询用户接口,返回用户信息;改:更新用户接口,将用户新的信息重新写入文件,注意:在'w'模式下,没有文件,就创建文件。所以,更新数据,和注册账号,都可以用这个接口。并且,重新写入,也是利用了'w'模式的打开文件,先将文件清空,再写入的方式。

    # 提现功能接口
    def top_up_interface(money, user):
        user_dic = db_handler.check_user(user)
        money = float(money)
        if money * 1.05 > user_dic.get('balance'):
            settings.logging.info('{} 提现失败'.format(user))
            return False, '提现失败,余额不足'
        user_dic['balance'] = float(user_dic.get('balance')) - money * 1.05
        user_dic['flow'].append('{} {} 提现了 {} 元'.format(time.strftime('%Y-%m-%d %X'), user, money))
        db_handler.update_user(user_dic)
        settings.logging.info('{} 提现成功,金额为:{} 元'.format(user,money))
        return True, '提现成功,金额为:{} 元,余额为:{} , 手续费:{} 元'.format(money, user_dic['balance'], money * 0.05)
    

      还款:
    用户视图层:将登录用户名传给查看用户接口,即传到逻辑接口层,接收逻辑接口层的返回值,打印输出结果。
    逻辑处理层:接收用户视图层的输入,即已登录用户名。进行核心逻辑处理,调用数据处理的查询用户接口,直接将用户名传到数据处理层,将处理结果,即用户信息字典,得到字典后,还款,即将金额进行充值,增加金额,将新的用户信息,通过数据处理层的更新用户信息的接口,重新写入用户信息,将其结果,比如说 True,'还款成功,金额为:...'。返回给用户视图层打印。
    数据处理层:接收其它层的数据,进行数据的增删改查,是数据相关的一些操作。查询余额:查:返回用户信息,查询用户接口;改:更新用户数据信息,更新用户信息接口

    # 还款功能接口
    def repay_money_interface(user, money):
        money = float(money)
        user_dic = db_handler.check_user(user)
        user_dic['balance'] = float(user_dic['balance'] + money)
        user_dic['flow'].append('{} {} 还款 {} 元'.format(time.strftime('%Y-%m-%d %X'), user, money))
        db_handler.update_user(user_dic)
        settings.logging.info('{} 还款,金额为:{} 元'.format(user,money))
        return '还款成功,金额为:{}'.format(money)
    

      转账:
    用户视图层:将登录用户名,目标用户,转账金额,传给查看用户接口,即传到逻辑接口层,接收逻辑接口层的返回值,打印输出结果。
    逻辑处理层:接收用户视图层的输入,即已登录用户名,目标账户,转账金额。调用查看数据处理层的查看用户接口,得到用户信息,判断已登录账户钱够不够,够的话,就减少转账用户的金额,将信息更新,调用更新用户信息接口;把目标用户也取出来,进行数据更新。将处理结果返回给用户视图层。
    数据处理层:转账:查:查看用户信息接口,返回用户信息,即转账用户,目标用户的用户信息,都要进行处理;改:更新用户数据信息,更新用户信息接口,更新两个用户的信息

      

    # 转账功能接口
    def transfer_interface(user, user2, money):
        user_dic2 = db_handler.check_user(user2)
        if not user_dic2:
            return False, '没有这个用户哦'
        user_dic = db_handler.check_user(user)
        if float(user_dic.get('balance')) > float(money):
            user_dic['balance'] = float(user_dic['balance']) - float(money)
            user_dic['flow'].append('{} {} 转账给 {} {} 元'.format(time.strftime('%Y-%m-%d %X'), user, user2, money))
            db_handler.update_user(user_dic)
            user_dic2['balance'] = float(user_dic2['balance']) + float(money)
            user_dic2['flow'].append('{} {} 收到 {} 转账 {} 元'.format(time.strftime('%Y-%m-%d %X'), user2, user, money))
            db_handler.update_user(user_dic2)
            settings.logging.info('{} 转账给 {} ,金额:{} 元'.format(user,user2,money))
            return True, '转账成功,金额为:{}'.format(money)
        else:
            user_dic['flow'].append('{} {} 转账给 {} {} 元,失败!'.format(time.strftime('%Y-%m-%d %X'), user,user2,money))
            settings.logging.info('{} 转账给 {} ,失败!'.format(user,user2))
            return False, '转账失败,金额不足'
    

      查看流水:
    用户视图层:将登录用户名,传给查看用户接口,即传到逻辑接口层,接收逻辑接口层的返回值,打印输出结果。
    逻辑处理层:接收用户视图层的输入,即已登录用户名。调用查看用户接口,得到用户信息,返回流水,用户视图层
    数据处理层:查看流水:查:返回用户信息,查询用户接口;

    # 查看流水接口
    def look_flow_interface(user):
        user_dict = db_handler.check_user(user)
        return user_dict['flow']
    

      

    购物:
    用户视图层:将用户选择的编号传给,逻辑接口层。
    逻辑处理层:接收用户视图层的输入的编号。将商品加入购物车,即调用查看用户接口(数据处理层),得到用户信息字典,将商品信息加入到用户字典的购物车信息里,比如,商品名称,单价,数量。
    数据处理层:更新用户信息字典。

    # 加入购物车接口
    def in_shop_interface(user,list_shop):
        user_dic = db_handler.check_user(user)
        if list_shop[0] not in user_dic['shop']:
            user_dic['shop'][list_shop[0]] = [1,list_shop[1]]
        else:
            user_dic['shop'][list_shop[0]][0] = int(user_dic['shop'][list_shop[0]][0]) + 1
        db_handler.update_user(user_dic)
        settings.logging.info('{} 购买了 {}'.format(user,list_shop[0]))
        return '已加入购物车,商品为:{} , 价格:{} 元'.format(list_shop[0],list_shop[1])
    

      查看购物车:
    用户视图层:将已登录用户名传给逻辑接口层。得到购物车信息,打印。然后询问是否结算,如果结算,调用支付接口(逻辑接口层),
    逻辑处理层:调用查看用户接口(数据处理层),得到用户信息字典,将购物车信息返回给用户视图层;支付接口:判断金额够不够,够的话就,减少金额,清空购物车,即把用户信息字典的购物车赋值为空,比如空字典。更新用户信息接口(数据处理层),更新用户数据。
    数据处理层:查看用户接口,更新用户数字接口

    # 查看购物车接口
    def look_shop_interface(user):
        user_dic = db_handler.check_user(user)
        goods = user_dic['shop']
        money_sum = 0
        for i in goods:
            money_sum += float(goods[i][0]) * int(goods[i][1])
        return money_sum, goods
    
    
    # 结算支付接口
    def pay_money_interface(user):
        user_dic = db_handler.check_user(user)
        goods = user_dic['shop']
        money_sum = 0
        for i in goods:
            money_sum += float(goods[i][0]) * int(goods[i][1])
        if float(user_dic['balance']) > money_sum:
            user_dic['balance'] = float(user_dic['balance']) - money_sum
            user_dic['flow'].append('{} {} 付款成功,金额为: {} 元'.format(time.strftime('%Y-%m-%d %X'), user, money_sum))
            user_dic['shop'] = {}
            db_handler.update_user(user_dic)
            settings.logging.info('{} 付款:{} 元'.format(user,money_sum))
            return True,  '付款成功,金额为:{}'.format(money_sum)
        else:
            settings.logging.info('{} 付款失败'.format(user))
            return False, '付款失败,请充值'
    

      管理员功能:
    可以新建一个视图层,为管理员的视图层,按照三层架构去写每个功能。

    # 检测是否是管理员,是的话就运行管理员视图层
    def root_check_interface(user):
        user_dic = db_handler.check_user(user)
        if user_dic.get('root'):
            return True
    

      

    数据处理层
    from conf import settings
    import os
    import json
    
    def check_user(username):  # 查看用户接口
        file_path = os.path.join(settings.USER_DATA_PATH, '{}.json'.format(username))
        if os.path.exists(file_path):
            with open(file_path, 'r', encoding='utf-8') as f:
                dic = json.load(f)
            return dic
    
    def update_user(dic):  # 数据更新接口
        dic_path = os.path.join(settings.USER_DATA_PATH,'{}.json'.format(dic['username']))
        with open(dic_path,'w',encoding='utf-8') as f:
            json.dump(dic,f)
    
    add_user = update_user  #写了两个一样的数据更新程序,所以去掉一个,赋值给add_user
    
    def get_shop_data():  # 获得商品信息接口,从文件中获得
        with open(settings.SHOP_DATA_PATH,'r',encoding='utf-8') as f:
            return json.load(f)
    

      

  • 相关阅读:
    Java学习01-使用maven插件tomcat搭建web maven项目
    Anaconda3安装及使用
    python标准日志模块logging及日志系统设计
    python traceback捕获并打印异常
    python time
    PIL 中的 Image 模块
    python zipfile使用
    PHP 判断用户是否手机访问
    php数组相加 两个数组键名相同 后者不能覆盖前者
    解决Ubuntu Server 12.04换了网卡MAC地址后 网络不可用的问题.
  • 原文地址:https://www.cnblogs.com/Tornadoes-Destroy-Parking-Lots/p/12622931.html
Copyright © 2011-2022 走看看