ATM+购物车

ATM+购物车

实现功能事项:
 
 
 
用户视图层:
    与用户进行交互,接收用户处理输入的数据,交给接口层进行处理,接口层最终会将一个结果
    返回给用户视图层展示给用户
 
 
逻辑接口层
    相当于用户视图层与数据处理层的桥梁
 
    专门复测接收用户视图层传过来的数据,并进行“核心的逻辑”校验,校验过程中
    ,会去访问"数据层“进行数据的增删改查,通过或不通过会返回一个结果给用户视图层进行展示
    --日志的添加、流水的添加都是在这层
 数据处理层:
    职责:接收到接口层传递过来的参数,进行数据的处理
    1.增加数据
    2.查看数据
    3.删除数据
    4.更新数据
 common通用组件
-----------------------------------
-----------------------------------
搭建项目的目录规范:
-ATM项目根目录
    -readme.md  项目说明书
    -start.py  项目启动文件
    -conf 配置文件夹
        -settings.py
    -lib  公共方法文件
        -common.py
    -core [用户视图层]存放用户视图层代码文件
        -src.py
    -interface [逻辑接口层] 存放核心业务逻辑代码
        -user_interface.py 用户相关的接口
        -bank_interface.py 银行相关的接口
        -shop_interface.py 购物相关的接口
    -db [数据处理层] 存放数据与数据处理代码
        -db_handler.py 数据处理层代码
        -user_data  用户数据
    -log  存放日志文件
​```
入口函数
1.start.py
​```python
"""
程序的入口,主程序入口
"""
import os
import sys
# python 环境下使用sys.path.append(path)添加相关的路径,
# 但在退出python环境后自己添加的路径就会自动消失了!
# 添加解析器的环境变量
sys.path.append(os.path.dirname(__file__))
from core import src
if __name__ == '__main__':
    src.run()     # 执行用户视图层的函数
​```
2.core/src.py
​```pyton
"""
核心代码区,用户视图层
"""
from interface import user_interface
from lib import common
from interface import bank_interface
# 全局变量,记录用户是否已登录
login_user=None
#1.注册功能
def register():
    while True:
        #1.让用户输入用户名和密码进行校验
        username=input("请输入用户名:").strip()
        password=input("请输入密码:").strip()
        re_password=input("请再次输入密码:").strip()
        # 很小的逻辑处理,比较两次密码是否一致
        if password==re_password:
            #2)调用接口层的注册接口
            # flag,msg--->(flag--->False,msg--->'用户名已经存在!)
            # (True,用户注册成功)(False,注册失败)
            flag,msg=user_interface.register_interface(username,password)
            #3)根据flag判断用户注册是否成功,
            if flag:
                print(msg)
                break
            else:
                print(msg)
# 2.登录功能
def login():
    # 登录视图
    while True:
        # 1)让用户输入用户名与密码
        username=input("请输入用户名:").strip()
        password=input("请输入密码:").strip()
        #2)调用接口层,将数据传给登录接口
        #True,f'用户:{username}登录成功!'
        #return False,'密码错误'
        #return 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():
    # 1.直接调用查看余额接口,获取用户余额
    balance=user_interface.check_bal_interface(login_user)
    print(f'用户{login_user}账户余额为:{balance}')
# 4.提现功能
# @common.login_auth
def withdraw():
    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():
    """
    银行卡还款,无论信用卡或者储蓄卡,是否能充任意大小的金额
    :return:
    """
    while True:
        # 1.让用户输入还款金额
        input_money=input("请输入需要还款的金额:").strip()
        # 2.判断用户输入的是否是数字
        if not input_money.isdigit():
            print("请输入正确的金额")
            continue
        input_money=int(input_money)
        # 3)判断用户输入的金额大于0
        if input_money>0:
            # 4)调用还款接口
            flag,msg=bank_interface.repay_interface(login_user,input_money)
            if flag:
                print(msg)
                break
        else:
            print("输入的金额不能小于0")
# 6.转账功能
# @common.login_auth
def transfer():
    """
    1.接收用户输入的转账目标用户
    2.接收永不输入的转账金额
    :return:
    """
    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():
    # 直接调用查看流水接口
    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():
    pass
# 9.查看购物车
# @common.login_auth
def check_shop_car():
    pass
# 10.管理员功能
def admin():
    pass
func_dict={
    '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("""
        1.注册功能
        2.登录功能
        3.查看余额
        4.提现功能
        5.还款功能
        6.转账功能
        7.查看流水
        8.购物功能
        9.查看购物车
        10.管理员功能
 
        """)
        choice=input("请输入功能编号:").strip()
        if choice not in func_dict:
            print("请输入正确的功能编号!")
            continue
        func_dict.get(choice)()    #相当于func_dic.get("1")()--->register
if __name__ == '__main__':
    run()
    
​```
2.1core/admin.py
​```python
from core import src
from interface import admin_interface
#添加用户
def add_user():
    src.register()    #调用添加账户信息
#修改用户额度
def change_balance():
    while True:
        #1)输入需要修改的账户名
        chang_user=input("请输入需要修改额度的用户:").strip()
        #2)修改的用户用户额度
        money=input("请输入需要修改的用户额度:").strip()
        if not money.isdigit():
            continue
        #3)调用修改额度接口
        flag,msg=admin_interface.change_balance_interface(chang_user,money)
        if flag:
            print(msg)
            break
        else:
            print(msg)
#冻结用户
def lock_user():
    while True:
        #1)输入要冻结的用户名
        change_user=input("请输入需要冻结的账户:").strip()
        flag,msg=admin_interface.lock_user_interface(change_user)
        if flag:
            print(msg)
            break
        else:
            print(msg)
#
#管理员功能字典
admin_func={
    '1':add_user,
    '2':change_balance,
    '3':lock_user,
}
def admin_run():
    while True:
        print("""
        1.添加账户
        2.修改额度
        3.冻结账户
        
        """)
        choice=input("请输入管理员功能编号:").strip()
        if choice not in admin_func:
            print("请输入正确编号!")
            continue
        admin_func.get(choice)()
​```
3.interface接口
3.1bank_intrface.py
​```python
"""
银行相关业务的接口
"""
from db import db_handler
#提现接口(手续费5%,就是每次提现都是花费5%)
def withdraw_interface(username,money):
    #1)先获取用户字典
    user_dic=db_handler.select(username)
    #账户中的金额
    balance=int(user_dic.get('balance'))
    #提现本金+手续费
    money2=int(money)*1.05
    #判断用户金额是否足够
    if balance>=money2:
        #2)修改用户字典中的金额
        balance-=money2
        user_dic['balance']=balance
        #3) 记录流水
        flow=f'用户[{username}]体现金额[{money}$]成功,手续费用为[{money2-float(money)}]'
        user_dic['flow'].append(flow)
        # 3.1)在保存数据,或者更新数据
        db_handler.save(user_dic)
        return True,f'用户[{username}]提取金额[{money}]成功,手续费为:{money2-float(money)}$'
    return False,f'提现金额不足,请重新输入!'
# 还款接口
def repay_interface(username,money):
    """
    1.获取用户的金额
    2.给用户的金额做加钱的操作
    :return:
    """
    # 1.获取用户字典
    user_dic=db_handler.select(username)
    #2.直接做加钱操作
    # user_dic["balance"]----->int
    user_dic['balance']+=money
    #3.记录流水
    flow=f'用户:[{username}] 还款[{money}]成功!'
    user_dic['flow'].append(flow)
    #3.调用数据处理层,将修改后的数据更新
    db_handler.save(user_dic)
    return True,f'用户:[{username}] 还款:[{money}]成功,当前额度为:{user_dic["balance"]}'
# 转账接口
def transfer_interface(login_user,to_user,money):
    """
    1.获取“当前用户”数据
    2.获取“目标用户”数据
    3.获取转账金额
    :param login_user:
    :param to_user:
    :param money:
    :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:
        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'用户[{login_user}]给用户:[{to_user}]转账:[{money}]成功'
        login_user_dic['flow'].append(login_user_flow)
        # 给目标用户流水
        to_user_flow = f'用户[{to_user}]接收用户:[{login_user}]转账:[{money}]成功'
        to_user_dic['flow'].append(to_user_flow)
        #6.保存用户数据
        #6.1)调用数据处理层的save功能,保存当前用户数据
        db_handler.save(login_user_dic)
        #6.2)给调用数据处理层的save功能,保存目标用户数据
        db_handler.save(to_user_dic)
        return True,f'用户:[{login_user}]给用户[{to_user}]转账:[{money}]元,成功!'
    return False,"当前用户转账金额不足!"
#查看流水接口
def check_flow_interface(login_user):
    user_dic=db_handler.select(login_user)
    return user_dic.get('flow')   #返回一个list列表
#支付接口
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,或者false 交给购物接口来处理
        return True
    return False
​```
3.2shop_intrface.py
​```python
"""
购物商城接口
"""
from db import db_handler
#商品准备结算接口
def shopping_interface(login_user,shopping_car):
    #1)计算消费总额
    #{‘商品名称’:["价格","数量"]}
    cost=0
    for price_number in shopping_car.values():
        price,number=price_number
        cost+=(price*number)
    #导入银行接口
    from interface import bank_interface
    #逻辑校验成功后,再调用银行的支付接口
    flag=bank_interface.pay_interface(login_user,cost)
    if flag:
        return True,"支付成功,准备发货!"
    return False,"支付失败,金额不足!"
#购物车添加接口
def add_shop_car_interface(login_user,shopping_car):
    #1)获取当前用户的购物车
    user_dic=db_handler.select(login_user)
    #获取用户文件中的商品的数据
    shop_car=user_dic.get("shop_car")
    #2)添加购物车
    #2.1)判断当前用户选择的商品是否已经存在
    # shopping_car--->{'商品名':["商品价格,商品数量"]}
    for shop_name,price_number in shopping_car.items():
        #每个商品的数量
        number=price_number[1]
        #2.2)若有商品重复,则累加商品数量
        if shop_name in shop_car:
            user_dic['shop_car'][shop_name][1]+=number
        else:
            #2.3)若不是重复的,更新到商品字典中
            user_dic['shop_car'].update({shop_name:price_number})
    #保存用户数量
    db_handler.save(user_dic)
    return True,"添加购物车成功!"
#查看购物车接口
def check_shop_car_interface(login_user):
    pass
​```
3.3user_intrface.py
​```python
"""
逻辑接口层
    用户接口
"""
from db import db_handler
from lib import common
# 注册接口
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)
    #3.1 组织用户的数据的字典信息
    user_dict={
        'username':username,
        'password':password,
        'balance':balance,
        # 用于记录用户流水的列表
        'flow':[],
        # 用于记录用户购物车
        'shop_car':{},
        #locked 用于记录用户是否被冻结
        #False:未冻结  True:已经被冻结
        #
        'locked':False
    }
    #3.2 保存数据
    db_handler.save(user_dict)
    return True,f'{username}注册成功!'
# 登录接口
def login_interface(username,password):
    #1)先查看当前用户数据是否存在
    #{用户数据字典} or None
    user_dict=db_handler.select(username)
    #用户判断用户是否存在
    #若有冻结用户 则需要判断是否被锁定
    if user_dict.get("locked"):
        return False,"当前用户已被锁定"
    #2)判断用户是否存在
    if user_dict:
        #给用户输入的密码做一次加密
        password=common.get_pwd_md5(password)
        #3)校验密码是否一致
        if password==user_dict.get('password'):
            return True,f'用户:{username}登录成功!'
        else:
            return False,'密码错误'
    return False,'用户不存在,请重新输入'
#查看余额接口
def check_bal_interface(username):
    user_dic=db_handler.select(username)
    return user_dic['balance']
​```
3.4interface/admin.py接口
​```python
from db import db_handler
# 修改额度接口
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)
        return True,"额度修改成功!"
    return False,"修改额度用户不存在!"
#冻结账户接口
def lock_user_interface(username):
    user_dic=db_handler.select(username)
    if user_dic:
        #将locked的默认值修改为True
        user_dic['lcoker']=True
        db_handler.save(user_dic)
        return True,f"用户{username}冻结成功!"
    return False,"冻结用户不存在"
​```
4.lib
lib/common.py
​```python
"""
存放公共方法
"""
import hashlib
#md5加密
def get_pwd_md5(password):
    md5_obj=hashlib.md5()
    md5_obj.update(password.encode('utf-8'))
    #加盐操作
    salt='我是加盐操作123456!'
    md5_obj.update(salt.encode('utf-8'))
    return md5_obj.hexdigest()
# 登录认证装饰器模板
# def login_authmobao(func):
#     def inner(*args,**kwargs):
#         res=func(*args,**kwargs)
#         return res
#
#     return inner()
 # 登录认证装饰器
 # 装饰器的使用,为其他函数进行装饰。
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()
​```
5.db数据存储
下面两个,一个是文件夹“”user_data",存放用户*.json数据,还有一个db_handler.py--->这个主要是进行数据的存储处理
 
db_handler.py
 
​```python
"""
数据处理层
    -专门用户处理数据的
"""
 
import json
import os
from conf import settings
 
 
#查看数据
 
def select(username):
    #     1)接收层传过来的username用户名,拼接用户json文件路径,如果穿过来的用户是
    # 是’张三‘那么本地就是存储为"张三.json"文件
    user_path=os.path.join(
        settings.USER_DATA_PATH,f'{username}.json'
    )
 
#     2)校验用户json文件是否存在
    if os.path.exists(user_path):
        #3)打开数据,并返回给接口层
        with open(user_path,'r',encoding='utf-8')as f:
            use_dict=json.load(f)
            return use_dict
 
    # 3)不return,默认return None
 
 
# 保存数据
def save(user_dict):
    # 1)拼接用户的数据字典
    username=user_dict.get('username')
 
    user_path=os.path.join(settings.USER_DATA_PATH,f'{username}.json')
 
    # 2)保存用户数据
 
    with open(user_path,'w',encoding='utf-8')as f:
        #ensure_ascii=False),让保存到jsoon文件的中文,显示为中文而不是16进制
        json.dump(user_dict,f,ensure_ascii=False)
 
 
​```
 
6.配置文件conf文件夹
 
conf/settings.py---->数据文件的配置事项
 
​```python
 
"""
保存配置信息
"""
 
import os
 
#获取项目根目录路径
 
BASE_PATH=os.path.dirname(os.path.dirname(__file__))
 
 
# 获取user_data文件夹的目录路径
USER_DATA_PATH=os.path.join(
    BASE_PATH,'db','user_data'
)
# print(USER_DATA_PATH)
​```
 
7.sstart.py--->启动文件
 
​```python
"""
程序的入口,主程序入口
"""
 
 
import os
import sys
 
# python 环境下使用sys.path.append(path)添加相关的路径,
# 但在退出python环境后自己添加的路径就会自动消失了!
# 添加解析器的环境变量
sys.path.append(os.path.dirname(__file__))
 
from core import src
 
 
if __name__ == '__main__':
    src.run()     # 执行用户视图层的函数
​```

posted @ 2022-10-31 23:30  逐风若梦  阅读(32)  评论(0编辑  收藏  举报