简易 ATM+购物商城程序(详细版)

作业需求:
模拟实现一个ATM+购物商城程序
1.额度15000或自定义(注册功能)
2.实现购物商城,买东西加入购物车,调用信用卡接口结账(购物支付功能)
3.可以提现,手续费5%(提现功能)
4.每月22号出账单,每月10号为还款日,过期未还,按欠款总额 万分之5每日计息
5.支持多账户登录(登录功能)
6.支持账户间转账(转账功能)
7.记录每月日常消费流水(记录流水功能)
8.提供还款接口(还款功能)
9.ATM记录操作日志(记录日志功能)
10.提供管理接口,包括添加账户、用户额度,冻结账户等(管理员功能)
11.用户认证用装饰器(登录认证装饰器)

start.py文件

# 启动文件:在这个文件中右键运行代码
# import sys
#
# print(sys.path)
from core import src
if __name__ == '__main__':
    src.run()

conf目录下settings.p

import os

BASE_DIR = os.path.dirname(os.path.dirname(__file__))

core目录下src.py

import os
import json

user_data = {
    'username': None,
    'is_login': False
}

# 注册功能
def register():
    print("注册功能:")
    if user_data['is_login']:
        print("已经登录")
        return
    while True:
        username = input('请输入用户名:>>').strip()
        """
            db/egon.json
                {'username':'egon', 'password':123, 'account':10000, 'locked':False}
            db/ly.json
            db/qq.json
            db/tom.json
        """
        # path = os.path.dirname(os.path.dirname(__file__))
        path = settings.BASE_DIR
        # day19/db/egon.json
        path_file = os.path.join(path, 'db', '%s.json' % username)

        # 判断是否存在, 其实就是判断文件是否存在
        if os.path.exists(path_file):  # 即可以判断文件也可以判断文件夹是否存在
            # if os.path.isfile(path_file):  # 可以判断文件
            # if os.path.isdir(path_file):  # 可以判断文件夹   dir  => directory => 文件夹
            print("用户名已经存在")
            continue

        pwd = input('请输入密码:>>').strip()
        """
            那些数据可以写文件?
                1. 字符串
                2. 二进制
            基于网络传输的数据也是
        """
        # 注册
        user_dic = {'username': username, 'password': pwd, 'account': 10000, 'locked': False, 'flow': []}
        # 写文件
        with open(path_file, 'w', encoding='utf-8') as f:
            json.dump(user_dic, f)

        # 写日志
        from lib import common
        common.write_log("%s注册成功" % username)
        print("恭喜哦~注册成功")
        break

"""
user_data = {
    'username': egon,
    'is_login': True
}
"""
from conf import settings

# 登录
def login():
    print("登录功能:")
    count = 0
    if user_data['is_login']:
        print("已经登录")
        return
    while True:
        username = input('请输入用户名:>>').strip()
        # path = os.path.dirname(os.path.dirname(__file__))
        path = settings.BASE_DIR
        # day19/db/egon.json
        path_file = os.path.join(path, 'db', '%s.json' % username)

        # 判断用户名是否存在
        if not os.path.isfile(path_file):
            print("用户名不存在")
            continue
            # 查询用户信息
        with open(path_file, 'r', encoding='utf-8') as f:
            data = json.load(f)  # dict

        # 判断用户状态
        if data.get('locked'):
            print("用户已经锁定,请联系我哦~")
            break

        # 输入密码
        pwd = input('请输入密码:>>').strip()

        # 判断密码是否正确
        if pwd == data.get('password'):
            print("登录成功")
            user_data['username'] = username
            user_data['is_login'] = True

            # 写日志
            from lib import common
            common.write_log('%s登录了' % username)
            break
        else:
            print("密码错误")
            count += 1
            if count == 3:
                # 锁定
                """
                data = {"username": "ly", "password": "123", "account": 10000, "locked": false}
                """
                data['locked'] = True

                """
                data = {"username": "ly", "password": "123", "account": 10000, "locked": true}
                """
                with open(path_file, 'w', encoding='utf-8') as f:
                    json.dump(data, f)

"""
user_data = {
    'username':None,
    'is_login':False
}
"""

from lib import common
from conf import settings
import time

# lib => library
# 提现
@common.login_auth
def withdraw():
    """
        分析提现功能:
            1. 输入提现金额
            2. 扣除手续费, 5%
            3. 判断金额是否足够,
            4. 把金额减掉
            5. 添加流水
            6. 添加日志
    :return:
    """
    print("提现功能:")
    while True:
        # 1. 输入提现金额
        money = input('请输入提现金额:>>').strip()
        if not money: continue

        if not money.isdigit():
            print("输入金额不合法")
            continue
        money = int(money)
        # 2. 读取用户信息

        # 读取当前用户的信息
        path = settings.BASE_DIR
        path_file = os.path.join(path, 'db', '%s.json' % user_data['username'])

        with open(path_file, 'r', encoding='utf-8') as f:
            user_dic = json.load(f)

        # 判断金额是否足够
        if user_dic['account'] >= money * 1.05:
            # 修改金额
            user_dic['account'] -= money * 1.05
            # 再次写入文件
            with open(path_file, 'w', encoding='utf-8') as f:
                json.dump(user_dic, f)
            print("提现成功,欢迎老板~")
            break
        else:
            print("穷逼一个")
            continue

# 转账
@common.login_auth
def transfer():
    """
        分析转账功能:
            1. 输入转账的账户,转账的账户必须存在
            2. 输入转账金额
            3. 检测自己的账户金额是否足够
            4. 增加对方账户的金额,自己账户的金额要减掉
            5. 写流水
            6. 写日志
    :return:
    """

    print("转账功能:")
    while True:
        # 1. 输入转账的账户
        to_user = input('请输入转账的账户用户名:>>').strip()

        # 2. 验证账户是否存在
        path = settings.BASE_DIR
        to_path_file = os.path.join(path, 'db', '%s.json' % to_user)

        # 判断转账的用户是否存在
        if not os.path.exists(to_path_file):
            print("用户不存在")
            continue

        # 3. 输入转账金额
        transfer_money = int(input('请输入转账金额:>>').strip())

        # 4. 读取自己的账户金额是否足够
        from_path_file = os.path.join(path, 'db', '%s.json' % user_data['username'])
        with open(from_path_file, 'r', encoding='utf-8') as f:
            from_user_dic = json.load(f)

        # 比较金额
        if from_user_dic['account'] >= transfer_money:
            # 对方账户增加金额
            with open(to_path_file, 'r', encoding='utf-8') as f1:
                to_user_dic = json.load(f1)

            to_user_dic['account'] += transfer_money
            to_user_dic['flow'].append('收到了%s的一笔转账%s元' % (from_user_dic['username'], transfer_money))

            with open(to_path_file, 'w', encoding='utf-8') as f2:
                json.dump(to_user_dic, f2, ensure_ascii=False)

            # 自己的账户减掉金额
            from_user_dic['account'] -= transfer_money
            from_user_dic['flow'].append('向%s转了一笔钱%s元' % (to_user_dic['username'], transfer_money))

            with open(from_path_file, 'w', encoding='utf-8') as f3:
                json.dump(from_user_dic, f3, ensure_ascii=False)
            print("转账成功")
            break

        else:
            print("没钱啊,别装了。。。")

"""
充值必须要登录,就要有一个验证登录的装饰器
"""

# 充值
@common.login_auth
def pay():
    """
        分析充值的需求:
            1. 要输入充值的金额
            2. 要充值的账号必须存在
            3. 把账户的余额修改掉
    """
    print("充值金额:")
    while True:
        # 1. 输入充值金额
        money = input('请输入充值金额:>>').strip()

        # 验证输入的金额是否为数字
        if not money.isdigit():
            print("输入金额不是数字")
            continue

        money = int(money)

        """
            1. 拿到你现在的余额
                
            2. 用你现在的余额加上money
        """
        # 读取当前用户的信息
        path = settings.BASE_DIR
        path_file = os.path.join(path, 'db', '%s.json' % user_data['username'])

        # 判断当前用户是否存在
        if not os.path.exists(path_file):
            print("用户不存在")
            continue

        # 读取用户信息
        with open(path_file, 'r', encoding='utf-8') as f:
            user_dic = json.load(f)

        # 获取当前时间
        # ctime = time.time() # 2021-
        now = time.strftime('%Y-%m-%d %X')
        # 增加账号金额
        user_dic['account'] += money
        user_dic['flow'].append('%s在%s充值了%s元' % (user_data['username'], now, money))
        # user_dic['flow'].append('%s在%s充值了%s元')

        # {"username": "ly", "password": "123", "account": 10000, "locked": true}
        #
        with open(path_file, 'w', encoding='utf-8') as f:
            json.dump(user_dic, f, ensure_ascii=False)

        # 写入流水

        print("充值成功, 赶紧潇洒哦")
        break

# 查看余额
def check_money():
    pass

# 查看流水
def check_flow():
    pass

# 遍历

# 加入购物车
@common.login_auth
def add_cart():
    """
        1. 得先有商品
            goods = [
                ['商品名称', 100],
                ['商品名称', 100],
                ['商品名称', 100],
            ]
        2. 让用户输入商品序号
        3. 定义一个全局变量, 判断字典里是不是已经有了,没有的话,'商品名称':{'price':100,'count': 3}
        4. 在用户信息中,增加一个key: shopping_cart:{}
        5. 日志

    数据存储格式:
        {'商品名称':{'price':100,'count': 2},'商品名称1':{'price':200,'count': 1}}
    :return:
    """
    print("加入购物车:")
    shopping_cart = {}
    while True:
        goods = [
            ['hulatang', 100],
            ['tea', 200],
            ['coffee', 300],
            ['water', 400],
        ]

        """
            0. hulatang  100
            1. tea       200
            2. coffee    300
            3. water     400
        """
        for k, v in enumerate(goods):
            print("%s  %s  %s" % (k, v[0], v[1]))

        num = input('请输入商品序号(q to quit):>>').strip()  # 0, 1, 2 ,3
        if num.isdigit():
            num = int(num)
            # 商品名称
            goods_name = goods[num][0]
            goods_price = goods[num][1]

            # 去shopping_cart中判断是否存在
            if goods_name not in shopping_cart:
                # {'tea':{'price': 100, 'count':1}}
                shopping_cart[goods_name] = {'price': goods_price, 'count': 1}
            else:
                # {'tea':{'price': 100, 'count':2}}
                shopping_cart[goods_name]['count'] += 1
            print("请继续购物~")
        elif num == 'q':
            # 把用户选择的商品写入文件中
            if shopping_cart:
                # 读取用户信息
                # 读取当前用户的信息
                path = settings.BASE_DIR
                path_file = os.path.join(path, 'db', '%s.json' % user_data['username'])
                with open(path_file, 'r', encoding='utf-8') as f:
                    user_dic = json.load(f)
                user_dic['shopping_cart'] = shopping_cart

                with open(path_file, 'w', encoding='utf-8') as f:
                    json.dump(user_dic, f)
                print("欢迎下次再来")
                break

        else:
            print("输入序号不合法")

# 查看购物车
def check_shop():
    pass

func_dic = {
    '1': register,
    '2': login,
    '3': withdraw,
    '4': transfer,
    '5': pay,
    '6': check_money,
    '7': check_flow,
    '8': add_cart,
    '9': check_shop,
}

def run():
    while True:
        print(""""
        ############################################
            1. 注册
            2. 登录
            3. 提现
            4. 转账
            5. 充值
            6. 查看余额
            7. 查看流水
            8. 加入购物车
            9. 查看购物车
        ############################################
        """)

        choice = input('请输入你的选择:>>').strip()
        # if choice == 1:
        #     register()
        # elif choice == 2:
        #     login()
        if choice not in func_dic: continue
        func_dic[choice]()

lib目录下common.py

# 验证登录的装饰器

from core import src

def login_auth(func):
    # func => pay
    def inner(*args, **kwargs):
        # 验证是否登录
        if src.user_data['is_login']:
            return func(*args, **kwargs)
        else:
            # 没有登录
            src.login()

    return inner

import logging
import os
from conf import settings

# 一:日志配置
logging.basicConfig(
    # 1、日志输出位置:1、终端 2、文件
    # filename='access.log', # 不指定,默认打印到终端
    filename=os.path.join(settings.BASE_DIR, 'log', 'log.log'),  # 不指定,默认打印到终端

    # 2、日志格式
    format='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',

    # 3、时间格式
    datefmt='%Y-%m-%d %H:%M:%S %p',

    # 4、日志级别
    # critical => 50
    # error => 40
    # warning => 30
    # info => 20
    # debug => 10
    level=10,
)

# 二:输出日志
# logging.debug('调试debug')
# logging.info('消息info')
# logging.warning('警告warn')
# logging.error('错误error')
# logging.critical('严重critical')

def write_log(info):
    logging.debug(info)

'''
# 注意下面的root是默认的日志名字
WARNING:root:警告warn
ERROR:root:错误error
CRITICAL:root:严重critical
'''
posted @ 2021-08-23 18:48  停在夏季  阅读(56)  评论(0编辑  收藏  举报
-->