一、目录规范

 ATM购物车(一) Python

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。

 

 二、readme

# ATM + 购物车项目
# 一个项目是如何从无到有的

# 1、需求分析(需要关注)
    额度 15000 或 自定义    --->  注册功能
    实现购物商城,买东西加入 购物车,调用 信用卡接口 结账 ----> 购物功能、支付功能
    可以提现,手续费5%  ---> 提现功能
    支持多账户登录 ---> 登录功能
    支持账户间转账 ---> 转账功能
    记录消费流水 ---> 记录流水功能
    提供还款接口 ---> 还款功能
    ATM记录操作日志 ---> 记录日志功能
    提供管理接口,包括添加账户、修改用户额度,冻结账户等。。。  ---> 管理员功能(添加账户、修改用户额度,冻结账户)
    用户认证用装饰器 ---> 登录认证装饰器‘

    # 用户界面允许用户能选择的功能
        1.注册功能
        2.登录功能
        3.查看余额
        4.提现功能
        5.还款功能
        6.转账功能
        7.查看流水
        8.购物功能
        9.查看购物车功能
        10.管理员功能
            - 添加账户、修改用户额度,冻结账户

# 2、程序的架构设计(需要关注)
    - 三层架构(*******- 视图层: 专门用于与用户交互;
            - 展示功能给用户看、接收用户输入的数据、将功能返回的结果展示给用户看的;

        - 接口层: 专门做业务逻辑的处理;
            - 接收到用户输入的数据,进行逻辑判断,然后返回判断后的结果给视图层;

        - 数据层: 专门做数据的处理
            - 增加数据
            - 删除数据
            - 更新数据
            - 查看数据

# 3、分任务开发
    - 项目经理:(项目的负责人)
        - UI(1-2人): 界面设计(app端的界面/web界面)。
        - 前端(1-2人): 拿到UI的设计图纸,开发页面。
        - 后端(2-3人): 开发业务逻辑
        - 运维(1人): 拿到开发好的代码,部署再 “服务器” 中,上线运行

# 4、测试软件
# 5、上线运营

三、start.py

# 启动程序入口
# 1.将当前ATM项目工程,添加解释器的环境变量
import os  # 与操作系统进行交互
import sys  # 与解释器进行交互

# 1) 获取ATM的目录路径
base_path = os.path.dirname(__file__)

# 2) 将项目路径添加到解释器的环境变量中
sys.path.append(base_path)

# 3) 将视图层中的执行函数,引用到当前位置执行
from core import src

if __name__ == '__main__':
    # 执行src模块中的run函数
    src.run()

四、conf---->settings

# 配置文件(常量)
import os

# ATM根目录路径
# D:\python全栈15期\day18\ATM
BASE_PATH = os.path.dirname(os.path.dirname(__file__))

# DB目录路径
# D:\python全栈15期\day18\ATM\db
DB_PATH = os.path.join(BASE_PATH, 'db')

五、core--->src

# 视图层
from interface import user_interface
from interface import bank_interface
from lib import common

# 专门用于记录用户是否登录,登录状态
user_info = {
    'user': None
}

# 拆分三层架构版本
def register():
    while True:
        # 1) 让用户输入用户名与密码
        username = input('请输入用户名: ').strip()
        password = input('请输入密码: ').strip()
        re_password = input('请输入密码: ').strip()

        # 2)小的逻辑判断
        if password == re_password:
            # 3) 再视图层中调用注册接口,将用户与密码传递给注册接口做 核心逻辑的处理
            # flag, msg = (False, '用户已存在,请重新输入')
            flag, msg = user_interface.register_interface(username, password)

            #  True, f'用户[{username}]注册成功'
            if flag:
                print(msg)
                break

            # False, '用户已存在,请重新输入'
            else:
                print(msg)

        else:
            print('两次密码不一致,请重新输入!')


# 2.登录功能
def login():
    while True:
        # 1) 让用户输入用户名与密码
        username = input('请输入用户名: ').strip()
        password = input('请输入密码: ').strip()

        # 3) 再视图层中调用 登录接口 ,将用户与密码传递给登录接口做 核心逻辑的处理
        flag, msg = user_interface.login_interface(username, password)

        #  True, f'用户[{username}]登录成功'
        if flag:
            print(msg)
            user_info['user'] = username
            break

        # False, '用户已存在,请重新输入'
        else:
            print(msg)


# 3.查看余额
@common.login_auth
def check_bal():
    # 直接调用查看余额接口层,获取数据
    bal = user_interface.check_bal_interface(user_info.get('user'))
    print(f'当前用户的余额为:[{bal}]')


# 4.提现功能
@common.login_auth
def withdraw():
    while True:
        # 1) 输入需要提现的金额
        balance = input('请输入需要提现的金额:').strip()
        # 小的逻辑判断,判断是否是数字,若是数字则转为int类型
        if not balance.isdigit():
            print('请输入数字类型!')
            continue

        # str ---> int
        balance = int(balance)

        # 2) 调用提现接口
        # flag, msg = (True, f'提现[{money}]成功! 手续费为:[{money2 - money}]')
        flag, msg = bank_interface.withdraw_interface(user_info.get('user'), balance)

        # 3)打印接口返回的结果
        if flag:
            print(msg)
            break
        else:
            print(msg)


# 5.还款功能
@common.login_auth
def repay():
    while True:
        # 1) 让用户输入还款金额
        money = input('请输入需要还款的金额: ').strip()

        # 2) 小的逻辑判断,判断是否是数字,若是数字则转为int类型
        if not money.isdigit():
            print('请输入数字类型!')
            continue
        money = int(money)

        # 3) 调用还款接口
        msg = bank_interface.repay_interface(user_info.get('user'), money)
        print(msg)
        break


# 6.转账功能
@common.login_auth
def transfer():
    pass


# 7.查看流水
@common.login_auth
def check_flow():
    pass


# 8.购物功能
@common.login_auth
def shopping():
    pass


# 9.查看购物车功能
@common.login_auth
def check_shop_car():
    pass


# 10.管理员功能
@common.login_auth
def admin():
    pass


# 函数功能字典
func_dic = {
    '1': register,
    '2': login,
    '3': check_bal,
    '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_dic:
            print('编号有误,请重新输入!')
            continue

        # func_dic.get('1')   --->  register()
        func_dic.get(choice)()

 

# 1.注册功能
# 不分层版本
# def register():
#     while True:
#         username = input('请输入用户名: ').strip()
#         password = input('请输入密码: ').strip()
#         re_password = input('请输入密码: ').strip()
#
#         if password == re_password:
#
#             # 组织用户的数据,转成json数据 --> json_str 保存到文件中
#             # 逻辑处理
#             user_dic = {
#                 'name': username,
#                 'pwd': password,
#                 'balance': 15000,
#                 'flow': [],
#                 # 'shop_car': {'商品名称': ['商品数量', '单价']}
#                 'shop_car': {},
#                 'locked': False
#             }
#             # D:\python全栈15期\day18\ATM\db\tank.json
#             # 以每个注册 “用户的名字” 作为json文件名
#             user_path = os.path.join(settings.DB_PATH, '%s.json' % username)
#
#             # 判断当前注册用户是否存在,os.path.exists(需要判断的文件路径)
#             if os.path.exists(user_path):
#                 print('用户已存在,请重新输入!')
#                 continue
#
#             with open(user_path, 'w', encoding='utf-8') as f:
#                 # dict ---> json_str ---> f.write(json_str)   ----> json文件中
#                 json.dump(user_dic, f)
#                 # 文件刷新
#                 f.flush()
#
#             print(f'用户[{username}]注册成功')
#             break
#         else:
#             print('两次密码不一致,请重新输入!')

六、db---->handler

# 数据层
import json
from conf import settings
import os


# 1、查看数据
def select(username):
    # 用户json文件的路径
    user_path = os.path.join(settings.DB_PATH, '%s.json' % username)

    # 判断当前注册用户是否存在,os.path.exists(需要判断的文件路径)
    if os.path.exists(user_path):
        # 读取文件中的数据
        with open(user_path, 'r', encoding='utf-8') as f:
            # f.read() ---> json_str ---> python
            user_dic = json.load(f)
            return user_dic


# 2、保存数据
def save(user_dic):
    # 用户json文件的路径
    user_path = os.path.join(settings.DB_PATH, '%s.json' % user_dic['name'])

    # 将数据写入文件中
    with open(user_path, 'w', encoding='utf-8') as f:
        # dict ---> json_str ---> f.write(json_str)   ----> json文件中
        json.dump(user_dic, f)
        # 文件刷新
        f.flush()

七、interface

  bank_interface.py

# 银行功能接口
from db import db_handler


# 提现接口
def withdraw_interface(username, money):
    user_dic = db_handler.select(username)
    # 可以提现,手续费5%
    # 1) 判断用户账户的金额是否,大于等于 提现金额 + 5%手续费
    # 提现金额 + 5%手续费    money + money * 0.05
    money2 = money * 1.05
    if user_dic.get('balance') >= money2:
        # 给当前用户字典金额减钱
        user_dic['balance'] -= money2
        db_handler.save(user_dic)
        return True, f'提现[{money}]成功! 手续费为:[{money2 - money}]'

    else:
        return False, '余额不足,快去充钱!'


# 还款接口
def repay_interface(username, money):

    # 1) 先将当前用户字典取出来
    user_dic = db_handler.select(username)

    # 2)直接加钱
    user_dic['balance'] += money

    # 3)再更新数据
    db_handler.save(user_dic)

    return f'还款[{money}]成功!'

user_interface.py

# 用户功能接口
from db import db_handler


# 注册接口
def register_interface(username, password):
    # 逻辑处理   --->  接口层
    # 1) 去数据处理层获取用户数据
    # user_dic --->  用户字典 / None
    user_dic = db_handler.select(username)

    # 2) 若user_dic有数据,则代表用户存在,返回用户已存在,请重新输入给
    if user_dic:
        return False, '用户已存在,请重新输入'  # ---》 return (False, '用户已存在,请重新输入')

    # 3) 若用户不存在,则可以注册
    # 组织用户的数据,转成json数据 --> json_str 保存到文件中
    user_dic = {
        'name': username,
        'pwd': password,
        'balance': 15000,
        'flow': [],
        # 'shop_car': {'商品名称': ['商品数量', '单价']}
        'shop_car': {},
        'locked': False
    }

    # 4) 调用数据层中的保存数据功能save,将字典传递过去进行数据的保存
    db_handler.save(user_dic)

    # 5) 返回注册结果给用户视图层
    return True, f'用户[{username}]注册成功'


# 登录接口
def login_interface(username, password):

    # 1) 先去数据层,获取用户字典数据
    user_dic = db_handler.select(username)

    # 2) 判断用户是否存在,若存在则校验密码
    if user_dic:
        if password == user_dic.get('pwd'):
            return True, f'用户[{username}]登录成功!'

        else:
            return False, '密码错误,请重新输入'

    # 3) 若不存在,则返回 错误信息给视图层
    else:
        return False, '用户不存在,请重新输入'


# 查看余额接口
def check_bal_interface(username):

    user_dic = db_handler.select(username)

    return user_dic.get('balance')

八、lib---->common.py

# 此处写公共方法


# 登录认证装饰器模板
def login_auth(func):
    # 解决循环导入问题
    from core import src
    def inner(*args, **kwargs):

        # 判断用户的登录状态,若有值代表已登录,通过校验
        if src.user_info.get('user'):
            res = func(*args, **kwargs)
            return res

        else:
            src.login()

    return inner

九、log

  日志

 

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄