ATM项目

ATM项目讲解

项目目录图片为:

1先写启动文件

import os#导入os模块
import sys#导入环境变量模块
CHE5_DIR=os.path.dirname(os.path.dirname(__file__))#获取项目根路径
sys.path.append(CHE5_DIR)#将项目根路径添加环境变量中
if __name__ == '__main__':#设置启动方法
    from sore import src#调用sore.src文件
    src.fun_run()#调用src中的fun_run方法

2编写sore中src文件

from conf.settings import *
from lib.common import *
from interface.user_interface import *
from interface.bank_interface import *
from interface.shop_interface import *
#导入模块
#添加全局变量
is_login={
    'username':''
}
#编写装饰器
def login_key(fun_name):
    def inner(*args,**kwargs):
        if is_login['username']:
            res=fun_name(*args,**kwargs)#调用函数
            return res
        else:
            print('请先登录哦')
            login()
    return inner
#编写注册功能
def register():
    while 1:
        #1.获取用户名和密码
        username=input('请输入用户名(输入q退出)').strip()
        if username=='q':
            return
        pwd=input('请输入密码').strip()
        #2.再次获取密码进行比较
        conf_pwd=input('请重新输入密码').strip()
       
        if not pwd==conf_pwd:
            print('输入两次密码不一致')
            continue
        else:
            #5.密码加密处理 加密功能放在公共功能下common
            pwd=hash_file(pwd)
             #3.两次密码一致调用注册接口
            flag,mgs=register_alive_interface(username,pwd)
            print(mgs)#8.用户注册成功 保存返回数据
            break

def login():
        username = input('请输入用户名').strip()
        if username=='q':
            return
        pwd=input('请输入密码').strip()
        pwd = hash_file(pwd)
        flag,mgs=login_interface(username,pwd)
        if flag:
            is_login['username']=username
        print(mgs)
@login_key
def select_money():
    username=is_login.get('username')
    flag,msg=select_money_interface(username)
    print(msg)
@login_key
def withdown_deposit():
    target_money=input('请输入您想要提现的金额:').strip()
    username = is_login.get('username')
    flag,msg=withdown_deposit_interface(username,target_money)
    print(msg)
@login_key
def repayment():
    username=is_login.get('username')
    target_money=input('请输入您想要充值的金额>>>:').strip()
    flag,msg=repayment_interface(username, target_money)
    print(msg)
@login_key
def tansfer():
    target_username=input('请输入您想要转账的用户>>>:').strip()
    target_money=input('请输入您想要转账的金额>>>:').strip()
    flag,msg=tansfer_interface(is_login['username'],target_username,target_money)
    print(msg)

@login_key
def select_account():
    flag,msg=select_account_interface(is_login['username'])
    if flag:
        for data in msg:
            print(data)
    else:
        print(msg)
@login_key
def add_shop_car():
    flag, msg = add_shop_car_interface(is_login.get('username'))
    print(msg)

@login_key
def select_shop_car():
    flag,msg = select_shop_car_interface(is_login.get('username'))
    if flag:
        for name,datalist in msg.items():
            print(f"商品:{name} | 商品个数:{datalist[0]} | 商品单价:{datalist[1]}")
    else:
        print(msg)
@login_key
def checkout_shop_car():
    flag, msg = pay_shop_car_interface(is_login.get('username'))
    print(msg)
@login_key
def admin():
    pass
fun_run={
    '1':register,
    '2':login,
    '3':select_money,
    '4':withdown_deposit,
    '5':repayment,
    '6':tansfer,
    '7':select_account,
    '8':add_shop_car,
    '9':select_shop_car,
    '10':checkout_shop_car,
    '11':admin
}

while 1:
    print("""
1.注册
2.登陆
3.查看余额
4.提现
5.还款
6.转账
7.查看流水
8.添加购物车功能
9.查看购物车功能
10.结算购物车功能
11.管理员功能   
    """)
    choice=input('请输入功能编号').strip()
    if choice not in fun_run:
        print('编号不存在')
    else:
        run=fun_run[choice]
        run()

注册功能

1.获取用户名和密码
2.再次获取密码进行比较
3.两次密码一致调用注册接口
4.校验用户名已存在
5.密码加密处理 加密功能放在公共功能下common
6.构造用户字典
7.save()保存数据 日志记录
8.用户注册成功 保存返回数据

登录功能

1.获取用户相关数据
2.直接调用用户登录接口 login_interface
3.先查询是否有当前用户名对应的数据值
4.如果用户名正确 比对加密密码
5.正确登录 错误返回 都返回两个值

第二层:user_interface.py

import os
from db.db_handler import *
from conf.settings import *
import lib.common
logging=lib.common.get_logger('用户模块')


def register_alive_interface(username,pwd):
    user_file = os.path.join(DB_DIR, f'{username}.jsom')
    if os.path.exists(user_file):
        return '用户名已存在'
    user_dict = {
        'username': username,
        'pwd': pwd,
        'capital': 15000.0,
        'shop_car': {},
        'is_lock': False,
        'water_flow': []
    }
    logging.info(f'用户{username}注册成功')
    cave(user_dict)
    return True,f'用户{username}注册成功'
def login_interface(username,pwd):
    user_file = os.path.join(DB_DIR, f'{username}.jsom')
    if not os.path.exists(user_file):
        return False,'用户不存在'
    user_data=select(username)
    if pwd==user_data['pwd']:
        logging.info(f'{username}登陆成功')
        return True,'登陆成功'
    else:
        logging.info(f'{username}登录失败')
        return False,'登录失败'

第三层db_handler

import os.path
from conf.settings import *
import json
def cave(user_start_value):
    user_file = os.path.join(DB_DIR, f'{user_start_value["username"]}.jsom')
    with open(user_file, 'w', encoding='utf8') as f:
        json.dump(user_start_value, f,ensure_ascii=False)
def select(username):
    user_file = os.path.join(DB_DIR, f'{username}.jsom')
    if os.path.exists(user_file):
        with open(user_file, 'r', encoding='utf8') as f:
            return json.load(f)

查看余额

1.全局用户字典是否登录
2.装饰器套用
3.直接调用查看账户余额的接口
4.查询当前登录用户的字典数据
5.从字典中获取余额信息并返回给第一层
6.日志记录

提现功能

1. 获取用户的想要提现的具体现金
2. 判断用户输入的是否是整数或者小数 
3.转数字操作
4.调用银行接口完成提现操作
5.1 获取当前登录用户的字典数据
5.2 获取用户余额并判断是否满足登录提现要求 收取手续费
5.3 添加流水信息
5.4 保存提现之后的用户数据

充值功能

1.直接获取用户想要充值的钱数
2.直接调用银行充值接口 并判断金额数字是否符合要求
3.获取用户字典数据
4.直接添加余额
5.添加流水记录
6.保存用户数据
7.日志记录

转账功能

1.获取想要转账的用户名
2.获取想要转账的金额
3.直接调用转账的接口
4.1 先校验目标用户是否存在
4.2 再校验用户数的金额是否是整数或者小数
5 获取当前登录用户的数据(也就是转账者的数据)
6.判断 转账者的余额是否充足
7. 记录加钱 扣钱的流水
8.记录转账之后的两个账户的数据
9.日志记录
10.返回数据 

查看流水

1.直接调用查看的流水接口即可
2.获取用户名对应的用户字典
for 循环打印
3.日志记录
4.返回数据

第二层bank_interface

from db.db_handler import *
from lib.common import *
from conf.settings import *
import time
logging=get_logger('银行模块')
def select_money_interface(username):
    user_dict=select(username)
    user_capital=user_dict['capital']
    logging.debug(f'用户{username},查看自己余额为{user_capital}')
    return True,f'用户{username},您的余额为{user_capital}'
def withdown_deposit_interface(username,target_money):
    flag,value=get_num(target_money)
    if not flag:
        return False,'请输入符合要求的金额数字'
    userdict=select(username)
    user_deposit=userdict['capital']
    if user_deposit<value*(1+MONEY_RATE):
        return False,f'尊敬的用户{username}您的账户连提现钱都没有,赶快去充值'
    userdict['capital']-=value*(1+MONEY_RATE)
    userdict['water_flow'].append(f'时间:{time.strftime("%Y-%m-%d %X")},账户提现了{value}元,手续费{value*(1+MONEY_RATE)}元,账户余额{userdict["capital"]}元')

    cave(userdict)
    logging.debug(f'尊敬的用户{username}提现了{value}元,手续费{value*(1+MONEY_RATE)}元,账户余额{userdict["capital"]}元')
    return True,f'尊敬的用户{username}提现了{value}元,手续费{value*(1+MONEY_RATE)}元,账户余额{userdict["capital"]}元'
def repayment_interface(username, target_money):
    flag,value=get_num(target_money)
    if not flag:
        return False,'请输入符合要求的金额数字'
    user_dict =select(username)
    user_dict['capital']+=value
    user_dict['water_flow'].append(f'时间:{time.strftime("%Y-%m-%d %X")},充值了{value}元,目前账户余额{user_dict["capital"]}元')

    cave(user_dict)
    logging.debug(f'尊敬的用户{username},您充值了{value}元,目前账户余额{user_dict["capital"]}元')
    return True,f'尊敬的用户{username},您充值了{value}元,目前账户余额{user_dict["capital"]}元'
def tansfer_interface(username,target_username,target_money):
    target_user_dict=select(target_username)
    if not target_user_dict:
        return False,f'目标用户{target_username}不存在'
    flag,value=get_num(target_money)
    if not flag:
        return False,'请重新输入金额数字'
    user_dict=select(username)
    user_capital=user_dict['capital']
    if user_capital<value:
        return False,f'您的余额不够'
    user_capital-=value
    user_dict['capital']=user_capital
    target_user_dict['capital']+=value
    target_user_dict['water_flow'].append(f'时间:{time.strftime("%Y-%m-%d %X")},收到了{username}转到了{value}元')
    user_dict['water_flow'].append(f'时间:{time.strftime("%Y-%m-%d %X")},给{target_username}账户转了{value}元,您目前账户余额为{user_dict["capital"]}元')

    cave(target_user_dict)
    cave(user_dict)
    logging.debug(f'尊敬的用户{username},您给{target_username}账户转了{value}元,您目前账户余额为{user_dict["capital"]}元')
    return True, f'尊敬的用户{username},您给{target_username}账户转了{value}元,您目前账户余额为{user_dict["capital"]}元'
def select_account_interface(username):
    user_dict=select(username)
    if user_dict['water_flow']:
        logging.debug(f'{username}查看了自己的流水记录')
        return True,user_dict['water_flow']
    return False,'该用户暂无流水记录'

添加购物车

"""
    1.先获取商品数据
    2.打印商品数据并让用户选择
    3.用户一旦退出 调用接口完成购物车数据更新
    :return:
    """
直接调用购物车接口
 # 1.获取商品信息(目前是写死的 后期可以动态获取)
 # 2.循环打印商品信息供用户选择
 # 3.获取用户输入的商品编号
 # 4.判断编号是否是纯数字
 # 5.判断数字是否超出范围
 # 6.根据商品编号获取商品信息
 # 7.获取想要购买的商品个数
 # 8.构造临时小字典存储商品信息
 # 9.写入临时小字典中
 '''10.添加结束标志 用于保存购物车数据'''
# 11.获取当前登录用户的字典数据
# 12.保存购物车数据

查看购物车

1.直接调用查看购物车接口
# 1.获取当前登录用户的字典数据
# 2.获取当前用户购物车数据
# 3.1 如果购物车有数据
# 3.2 如果没有
2.日志记录

结算购物车

1.直接调用结算购物车接口文件
2.获取当前登录用户的字典数据
3.获取当前用户车数据以及余额	
4.统计购物车商品总价
5.比较余额是否充足
6.清空购物车
7.流水记录
8.日志记录
9.保存新数据
10.返回数据值

第二层shop_interface.py

import logging
import time
from db.db_handler import *
def add_shop_car_interface(username):
    temp_shop_car={}#  目标购物车
    while 1:
        goods_list = [
            ['挂壁面', 3],
            ['印度飞饼', 22],
            ['极品木瓜', 666],
            ['土耳其土豆', 999],
            ['伊拉克拌面', 1000],
            ['董卓戏张飞公仔', 2000],
            ['仿真玩偶', 10000]
        ]
        for num,goods in enumerate(goods_list,start=1 ):
            print(f'商品编号{num}         |商品名称{goods[0]}             |商品单价{goods[1]}')
        choice=input('请输入您想要购买的商品编号,输入(q)退出').strip()
        if choice=='q':
            user_data_dict=select(username) #
            old_shop_car=user_data_dict['shop_car']
            for g_name,g_list in temp_shop_car.items():
                if g_name not in old_shop_car:
                    old_shop_car[g_name]=g_list
                else:
                    old_shop_car[g_name][0]+=temp_shop_car[g_name][0]
            user_data_dict['shop_car']=old_shop_car
            cave(user_data_dict)
            return True,'添加购物车成功'
        if not choice.isdigit(): #判断数字
            return False,'请输入数字'
        choice=int(choice)-1 #购物商品的索引
        if choice not in range(len(goods_list)):
            return False,'标号不存在'
        target_goods_data=goods_list[choice]#目标商品数据  ['挂壁面', 3],
        goods_num=input(f'请输入您想要购买的{target_goods_data[0]}的商品数量>>>:').strip()#   购买的数量
        if not goods_num.isdigit():
            return False,'请输入数字'
        goods_num=int(goods_num)
        arget_goods_name=target_goods_data[0]#目标商品名称
        if arget_goods_name not in temp_shop_car:#如果目标商品名字不在临时购物车中
            temp_shop_car[arget_goods_name]=[goods_num,target_goods_data[1]] #临时购物车商品k:v列表         购物车商品:【购物车数量,购物车单价】
        else:
            temp_shop_car[arget_goods_name][0]+=goods_num   #如果存在 购物车数量+=购物车数量
def select_shop_car_interface(username):
    user_data=select(username)
    user_shop_car=user_data['shop_car']
    if user_shop_car:
        return True,user_shop_car
    return False,'暂无购物车数据'
def pay_shop_car_interface(username):
    user_data=select(username)
    user_shop_car=user_data['shop_car']#"shop_car": {"挂壁面": [2, 3]},
    if not user_shop_car:
        return False,'购物车空空如也'
    user_capital=user_data['capital']
    total_money=0
    for g_list in user_shop_car.values():#{"挂壁面": [2, 3]}
        total_money+=g_list[1]*g_list[0]
    if total_money>user_capital:
        return False,f'用户{username}您的余额为{user_capital}不足{total_money}'
    user_capital-=total_money
    user_data['shop_car']={}
    user_data['water_flow'].append(f'时间:{time.strftime("%Y-%m-%d %X")},尊敬的{username} 您本次消费{total_money} 卡上余额剩余{user_capital} 欢迎下次再来挥霍!!!')

    logging.info(f'{username}消费了{total_money}')
    cave(user_data)
    return True,f'尊敬的{username} 您本次消费{total_money} 卡上余额剩余{user_capital} 欢迎下次再来挥霍!!!'


配置文件settings.py

import os
CHE5_DIR = os.path.dirname(os.path.dirname(__file__))
DB_DIR=os.path.join(CHE5_DIR,'db')
if not os.path.exists(DB_DIR):
    os.mkdir(DB_DIR)
MONEY_RATE = 0.05
# 我偷懒 不改大写了
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'

# 自定义文件路径
LOG_DIR = os.path.join(CHE5_DIR, 'log')
if not os.path.isdir(LOG_DIR):
    os.mkdir(LOG_DIR)
LOGFILE_PATH = os.path.join(LOG_DIR, 'ATM.log')

# log配置字典
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)传递
        },  # 当键不存在的情况下 (key设为空字符串)默认都会使用该k:v配置
        # '购物车记录': {
        #     'handlers': ['default','console'],  # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
        #     'level': 'WARNING',
        #     'propagate': True,  # 向上(更高level的logger)传递
        # },  # 当键不存在的情况下 (key设为空字符串)默认都会使用该k:v配置
    },
}


公共文件common.py

import hashlib
import logging
import logging.config
from conf.settings import *
def hash_file(mgs):
    md5=hashlib.md5()
    md5.update(mgs.encode('utf8'))
    res=md5.hexdigest()
    return res
def get_num(target_money):
    try:
        target_money=float(target_money)
    except ValueError:
        return False,'请输入整数或小数'
    else:
        return True,target_money

def get_logger(msg):
    logging.config.dictConfig(LOGGING_DIC)
    logger1=logging.getLogger(msg)
    return logger1
posted @ 2022-10-31 22:29  冰柠檬檬  阅读(55)  评论(0)    收藏  举报