Python构建简单的ATM+购物功能项目


南宫乘风:我在学Python哦

Python:你不写Python项目,是不会有进步的,年轻人,耗子尾汁吧

南宫乘风:我要进步,要学习,开始项目

Python:来骗,来偷袭。很快啊!年轻人,不讲码德


学了一点时间Python,为了巩固基础,拿一个简单的项目练手。

ATM+购物车功能(ps:很简单,大佬不要嘲笑哈)

项目需求:

1.额度15000或自定义     -->  注册功能
2.实现购物商城,买东西加入购物车,调用信用卡接口结账  --> 购物功能、支付功能
3.可以提现,手续费5%   --> 提现功能
4.支持多账户登录  --> 登录功能
5.支持账户间转账  --> 转账功能
6.记录日常消费 -->  记录流水功能
7.提供还款接口 -->  还款功能
8.ATM记录操作日志 --> 记录日志功能
9.提供管理接口,包括添加账户、用户额度,冻结账户等。。。 ---> 管理员功能
10.用户认证用装饰器  --> 登录认证装饰器

"用户视图层" 展示给用户选择的功能

user

1、注册功能
2、登录功能
3、查看余额
4、提现功能
5、还款功能
6、转账功能
7、查看流水
8、购物功能
9、查看购物车
10、管理员功能

admin

1、添加账号
2、修改额度
3、冻结账号
4、解冻账号
5、返回上一层

架构流程图

采取MVC的架构方式

各层分开,编写接口

三层架构:

1、把每个功能都分层三部分,逻辑清晰
2、如果用户更换不同的用户界面或不同的数据库存储机制,不会影响接口层的核心逻辑代码,扩展性强。
3)可以在接口层,准确的记录日志与流水。

三层架构构建   项目代码https://wwx.lanzoux.com/i1vhGixijzi

启动界面

start.py(程序的入口)

'''
程序入口
'''
import os
import sys
from core import src

# 添加解释器的环境变量
sys.path.append(
    os.path.dirname(__file__)
)
# 开始执行项目main
if __name__ == "__main__":
    src.run()

conf

setting.py(log日志的配置文件,项目的环境配置)

'''
配置文件设置

'''
import os
BASE=os.path.dirname(os.path.dirname(__file__))
# print(BASE)
#获取user_date文件夹路径
USER_DATE=os.path.join(BASE,'db','user_date')
# print(USER_DATE)

"""
日志配置字典LOGGING_DIC
"""
# 1、定义三种日志输出格式,日志中可能用到的格式化串如下
# %(name)s Logger的名字
# %(levelno)s 数字形式的日志级别
# %(levelname)s 文本形式的日志级别
# %(pathname)s 调用日志输出函数的模块的完整路径名,可能没有
# %(filename)s 调用日志输出函数的模块的文件名
# %(module)s 调用日志输出函数的模块名
# %(funcName)s 调用日志输出函数的函数名
# %(lineno)d 调用日志输出函数的语句所在的代码行
# %(created)f 当前时间,用UNIX标准的表示时间的浮 点数表示
# %(relativeCreated)d 输出日志信息时的,自Logger创建以 来的毫秒数
# %(asctime)s 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒
# %(thread)d 线程ID。可能没有
# %(threadName)s 线程名。可能没有
# %(process)d 进程ID。可能没有
# %(message)s用户输出的消息
import os
BASE_PATH=os.path.dirname(os.path.dirname(__file__))
a1_path=os.path.join(BASE_PATH,'log','a1.log')
a2_path=os.path.join(BASE_PATH,'log','a2.log')
# print(a1_path+'
'+a2_path)

# 2、强调:其中的%(name)s为getlogger时指定的名字
standard_format = '%(asctime)s - %(threadName)s:%(thread)d - 日志名字:%(name)s - %(filename)s:%(lineno)d -' 
                  '%(levelname)s - %(message)s'

simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'

test_format = '%(asctime)s] %(message)s'

# 3、日志配置字典
LOGGING_DIC = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'standard': {
            'format': standard_format
        },
        'simple': {
            'format': simple_format
        },
        'test': {
            'format': test_format
        },
    },

    'filters': {},
    # handlers是日志的接收者,不同的handler会将日志输出到不同的位置
    'handlers': {
        #打印到终端的日志
        'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',  # 打印到屏幕
            'formatter': 'simple'
        },
        'default': {
            'level': 'DEBUG',
            'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件
            # 'maxBytes': 1024*1024*5,  # 日志大小 5M
            'maxBytes': 1024*1024*5,
            'backupCount': 5,
            'filename': a1_path,  # os.path.join(os.path.dirname(os.path.dirname(__file__)),'log','a2.log')
            'encoding': 'utf-8',
            'formatter': 'standard',

        },
        #打印到文件的日志,收集info及以上的日志
        'other': {
            'level': 'DEBUG',
            'class': 'logging.FileHandler',  # 保存到文件
            'filename': a1_path, # os.path.join(os.path.dirname(os.path.dirname(__file__)),'log','a2.log')
            'encoding': 'utf-8',
            'formatter': 'standard',


        },
    },
    # loggers是日志的产生者,产生的日志会传递给handler然后控制输出
    'loggers': {
        #logging.getLogger(__name__)拿到的logger配置
        'kkk': {
            'handlers': ['console','other'],  # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
            'level': 'DEBUG', # loggers(第一层日志级别关限制)--->handlers(第二层日志级别关卡限制)
            'propagate': False,  # 默认为True,向上(更高level的logger)传递,通常设置为False即可,否则会一份日志向上层层传递
        },
        '终端提示': {
            'handlers': ['console',],  # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
            'level': 'DEBUG',  # loggers(第一层日志级别关限制)--->handlers(第二层日志级别关卡限制)
            'propagate': False,  # 默认为True,向上(更高level的logger)传递,通常设置为False即可,否则会一份日志向上层层传递
        },
        '': {
            'handlers': ['default', ],  # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
            'level': 'DEBUG',  # loggers(第一层日志级别关限制)--->handlers(第二层日志级别关卡限制)
            'propagate': False,  # 默认为True,向上(更高level的logger)传递,通常设置为False即可,否则会一份日志向上层层传递
        },
    },
}

core

admin.py(admin用户视图)

from core import src
from interface import admin_interface


def add_user():
    src.register()


def change_balance():
    while True:
        # 输入修改修改用户名
        change_user = input('请输入需要修改额度的用户:').strip()
        change_money = input('请输入需要修改的用户额度:').strip()
        if not change_money.isdigit():
            continue
        if int(change_money) >= 0:
            flag, msg = admin_interface.change_balance_interafce(change_user, change_money)
            if flag:
                print(msg)
            else:
                print(msg)
        else:
            print('输入的额度不正确')


def disable_user():
    # 输入要冻结的用户
    while True:
        dis_user = input('请输入要冻结的用户:').strip()
        flag, msg = admin_interface.disable_user_interface(dis_user)
        if flag:
            print(msg)
            break
        else:
            print(msg)


def enable_user():
    # 输入要解冻冻结的用户
    while True:
        dis_user = input('请输入要解冻冻结的用户:').strip()
        flag, msg = admin_interface.enable_user_interface(dis_user)
        if flag:
            print(msg)
            break
        else:
            print(msg)


def lsat_men():
    from core import src
    src.run()


func_dic = {
    '1': add_user,
    '2': change_balance,
    '3': disable_user,
    '4': enable_user,
    '5': lsat_men,

}


def admin_run():
    while True:
        print('''
            1、添加账号
            2、修改额度
            3、冻结账号
            4、解冻账号
            5、返回上一层
        ''')
        choice = input('请输入管理员功能编号:').strip()
        if choice not in func_dic:
            print("请输入正确的功能编号")
            continue
        func_dic.get(choice)()

# if __name__ == '__main__':
#     admin()

src.py(用户的视图)

'''
用户视图层
'''

from interface import user_interface, bank_interface, shop_interface
from lib import common
from core import admin

# 1、注册功能
'''def register():
    while True:
        # 1 让用户输入用户名称和密码进行校验
        username = input('请输入用户:').strip()
        if username.strip()=='':
            print("请输入正确的用户名")
            continue

        user_path = os.path.join(setting.USER_DATE, f"{username}.json")
        if os.path.exists(user_path):
            print(f"您输入的用户名:{username}已经存在")
            continue
        password = input("请输入密码:").strip()
        re_password = input("请确认密码:").strip()
        # 判断密码是否一致
        if password == re_password:

            # 2 查看用户是否存在
            # 3 如用户存在,则让用户重新输入
            # 4 如用户不存在,则保存用户数据
            # 4.1 组织用户的数据的字典信息
            user_dic = {
                'username': username,
                'password': password,
                'balance': 15000,
                # 用于记录用户的流水类表

                'flow': [],
                # 用于记录用户购物车
                'shop_car': [],
                # locaked :用于记录用户是否冻结
                # false:未冻结  True:已经被冻结
                'locaked': False
            }
            # 用户数据tank.json
            user_path = os.path.join(setting.USER_DATE, f"{username}.json")
            with open(user_path, 'w', encoding='utf-8') as f:
                json.dump(user_dic, f)
        else:
            print('您的两次密码不一致,请重新输入')'''

login_user = None


# 分层版
def register():
    while True:
        # 1 让用户输入用户名称和密码进行校验
        username = input('请输入用户:').strip()
        if username.strip() == '':
            print("请输入正确的用户名")
            continue
        password = input("请输入密码:").strip()
        re_password = input("请确认密码:").strip()
        # 判断密码是否一致
        if password == re_password:
            # 2 调用接口层的注册结果。将用户名和密码传到接口层
            # (True, 用户注册成功),  (False, 注册失败)
            flag, msg = user_interface.register_interface(
                username, password
            )

            # 3) 根据flag判断用户注册是否成功,flag控制break的结束
            if flag:
                print(msg)
                break
            else:
                print(msg)
        else:
            print('您的两次密码不一致,请重新输入')


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

        flag, msg = user_interface.longin_interface(username, password)
        if flag:
            global login_user
            login_user = username
            print(msg)
            break
        else:
            print(msg)


# 3、查看余额
@common.login_auth
def check_balance():
    # 直接调用查看用户接口,获取用余额
    balance = user_interface.check_balance_interface(login_user)
    print(f'用户:{login_user}账号余额为:{balance}')


# 4、提现功能
@common.login_auth
def withdraw():
    while True:
        # 让用户输入体现金额
        input_money = input('请输入提现金额:').strip()
        # 判断用户输入的金额是否是数字
        if not input_money.isdigit():
            print('请重新输入:')
            continue
        # 用户提现,将金额提交接口处理
        flag, msg = bank_interface.withdraw_interface(login_user, int(input_money))
        if flag:
            print(msg)
            break
        else:
            print(msg)


# 5、还款功能
@common.login_auth
def repay():
    while True:
        # 让用户输入体现金额
        repay_money = input('请输入还款金额:').strip()
        # 判断用户输入的金额是否是数字
        if not repay_money.isdigit():
            print('请重新输入')
            continue
        # 用户提现,将金额提交接口处理
        if int(repay_money) > 0:
            flag, msg = bank_interface.repay_interface(login_user, int(repay_money))
            if flag:
                print(msg)
                break
        else:
            print('不能输入小于0的数字')


# 6、转账功能
@common.login_auth
def transfer():
    '''
    接收用户的转账金额
    接收用户输入的转账目标
    :return:
    '''
    while True:
        user_money = input('请输入转账目标用户:').strip()
        money = input('请输入转账金额:').strip()
        if not money.isdigit():
            print('请输入正确的金额!')
            continue
        money = int(money)
        if money > 0:
            # 转账接口
            flag, msg = bank_interface.transfer_interface(login_user, user_money, 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():
    '''
    {
        '0':{'name':'包子','price':30},
        '0': {'name': '包子', 'price': 30},
        '0': {'name': '包子', 'price': 30},
    }
    :return:
    '''
    shop_list = [
        ['包子', 30],
        ['衣服', 150],
        ['安全套', 25],
        ['情趣内衣', 520],
        ['cosplay', 250],
    ]
    shopping_car = {}
    while True:
        # 先打印商品的信息,让用户选择
        print('===================欢迎来到情趣商城================')
        for index, shop in enumerate(shop_list):
            shop_name, shop_price = shop
            print(f'商品编号:{index}, 商品名称:{shop_name},商品单价:{shop_price}')
        print('========================end======================')

        shop_choice = input("请输入你要选购的商品编号(是否结账y or n):").strip()
        if shop_choice.upper() == 'Y':
            if not shopping_car:
                print('购物车是空的,不能支付,请重新输入')
                continue
            # 调用支付接口进行支付
            flag,msg=shop_interface.shopping_interface(login_user,shopping_car)
            if flag:
                print(msg)
                break
            else:
                print(msg)
        elif shop_choice.upper() == 'N':
            # 判断当前用户是否添加过购物车
            if not shopping_car:
                print('购物车是空的,不能添加,请重新输入')
                continue

            flag,msg=shop_interface.add_shop_car_interface(login_user,shopping_car)
            if flag:
                print(msg)
                break

        if not shop_choice.isdigit():
            print('请输入正确的编号!')
            continue
        shop_choice = int(shop_choice)
        if shop_choice not in range(len(shop_list)):
            print('请输入正确的编号!')
            continue
        shop_name, shop_price = shop_list[shop_choice]

        if shop_name in shopping_car:
            shopping_car[shop_name][1] += 1
        else:
            shopping_car[shop_name] = [shop_price, 1]

        print("当前购物车:",shopping_car)

# 9、查看购物车
@common.login_auth
def check_shop_car():
    shop_list = shop_interface.check_shop_car_interface(login_user)
    if shop_list:
        for shop_name,print_number in shop_list.items():
            print(f'商品:[{shop_name}],数量:[{print_number[1]}]')
    else:
        print('当前用户没有流水记录')


@common.login_auth
def admin_spuer():
    admin.admin_run()


# 创建函数功能字典

func_dic = {
    '1': register,
    '2': login,
    '3': check_balance,
    '4': withdraw,
    '5': repay,
    '6': transfer,
    '7': check_flow,
    '8': shopping,
    '9': check_shop_car,
    '10': admin_spuer,
}


def run():
    while True:
        print('''
        ==========ATM+购物车==========
                1、注册功能
                2、登录功能
                3、查看余额
                4、提现功能
                5、还款功能
                6、转账功能
                7、查看流水
                8、购物功能
                9、查看购物车
                10、管理员功能
        ==========  end  ==========
        ''')
        choice = input("请输入功能编号:").strip()
        if choice not in func_dic:
            print("请输入正确的功能编号")
            continue
        func_dic.get(choice)()

db

user_date (用户存放json的目录)

q.json (用户数据的存放文件,字典形式)
 

{"username": "q", "password": "099b3b060154898840f0ebdfb46ec78f", "balance": 14375.0, "flow": ["用户[q] 提现金额 [500],手续费为:[25.0]", "用户:[q]给用户[w] 转账:[100] 元 成功"], "shop_car": {}, "locked": false}

json格式

{
	"username": "q",
	"password": "099b3b060154898840f0ebdfb46ec78f",
	"balance": 14375.0,
	"flow": ["用户[q] 提现金额 [500],手续费为:[25.0]", "用户:[q]给用户[w] 转账:[100] 元 成功"],
	"shop_car": {},
	"locked": false
}

db_hander.py(对数据处理,相当于mysql接口处理)

'''
数据处理层
    专门用户处理数据的
'''
import json
import os
from conf import setting


# 判断用户是否已经注册
def user_select(username):
    # 1) 接收接口层传过来的username用户名,拼接用户json文件路径
    user_path = os.path.join(
        setting.USER_DATE, f'{username}.json'
    )

    # 2)校验用户json文件是否存在
    if os.path.exists(user_path):
        # 3) 打开数据,并返回给接口层
        with open(user_path, 'r', encoding='utf-8') as f:
            user_dic = json.load(f)
            return user_dic

    # 3) 不return,默认return None

# 保存数据处理
def user_save(user_dic):
    user_path = os.path.join(setting.USER_DATE, f"{user_dic['username']}.json")
    with open(user_path, 'w', encoding='utf-8') as f:
        json.dump(user_dic, f, ensure_ascii=False)

interface

admin_interface.py(admin的业务接口处理)

from db import db_hander
from lib import common
user_logger=common.get_log('admin')

# 修改额度接口
def change_balance_interafce(change_user, change_money):
    user_dic = db_hander.user_select(change_user)

    if user_dic:
        user_dic['balance'] = int(change_money)
        db_hander.user_save(user_dic)
        msg=f'[{change_user}]的额度修改{change_money}成功'
        user_logger.info(msg)
        return True, msg
    return False, '修改额度用户不存在'


def disable_user_interface(dis_user):
    user_dic = db_hander.user_select(dis_user)
    if user_dic:
        user_dic['locked'] = True
        db_hander.user_save(user_dic)
        msg = f'[{dis_user}]的冻结成功'
        user_logger.info(msg)
        return True, msg
    else:
        return False, '冻结用户不存在'

# 解冻用户的接口
def enable_user_interface(dis_user):
    user_dic = db_hander.user_select(dis_user)
    if user_dic:
        if user_dic['locked']:
            user_dic['locked'] = False
            db_hander.user_save(user_dic)
            msg = f'[{dis_user}]的冻结成功'
            user_logger.info(msg)
            return True, msg
        return False,f'用户:{dis_user}处于正常状态'
    else:
        return False, '冻结用户不存在'

bank_interface.py(银行业务处理接口)

'''
银行相关的业务
'''
from db import db_hander
from lib import common
user_logger=common.get_log('bank')

# 用户的提现金额接口
def withdraw_interface(login_user, input_money):
    # 先获取用户字典
    user_dic = db_hander.user_select(login_user)
    # 获取银行的金额
    balance = int(user_dic.get('balance'))
    # 本金+ 手续费
    money = int(input_money) * 1.05
    repair = round(money - input_money, 2)
    # 判断用户金额是否足够
    if balance >= money:
        # 修改用户字典的金额
        balance -= money
        user_dic['balance'] = balance
        flow = f'用户[{login_user}] 提现金额 [{input_money}],手续费为:[{repair}]'
        user_dic['flow'].append(flow)
        # 在保存数据
        db_hander.user_save(user_dic)
        msg=f'用户[{login_user}] 提现金额 [{input_money}],手续费为:[{repair}]'
        user_logger.info(msg)
        return True, msg
    return False, '提现金额不足,请重新输入'


# 还款接口
def repay_interface(login_user, repay_money):
    # 先获取用户字典
    user_dic = db_hander.user_select(login_user)
    # 获取银行的金额
    balance = int(user_dic.get('balance'))
    # 本金+ 手续费
    money = int(repay_money)
    # repair = round(money - repay_money, 2)
    # 修改用户字典的金额
    balance += money
    user_dic['balance'] = balance
    # 在保存数据
    flow = f'用户:[{login_user}] 还款金额 :[{repay_money}]成功]'
    user_dic['flow'].append(flow)
    db_hander.user_save(user_dic)
    msg = f'用户:[{login_user}] 还款金额 :[{repay_money}]成功]'
    user_logger.info(msg)
    return True, msg


# 转账接口
def transfer_interface(login_user, user_money, money):
    # 先获取用户字典
    login_user_dic = db_hander.user_select(login_user)
    user_money_dic = db_hander.user_select(user_money)
    # 判断目标用户是否存在
    if not user_money_dic:
        return False, '目标用户不存在'
    if login_user == user_money:
        return False, '不能给自己转账'
    if login_user_dic['balance'] >= money:
        login_user_dic['balance'] -= money
        user_money_dic['balance'] += money
        flow1 = f'用户:[{login_user}]给用户[{user_money}] 转账:[{money}] 元 成功'
        login_user_dic['flow'].append(flow1)
        flow2 = f'用户:[{user_money}]接受用户[{login_user}] 转账:[{money}] 元 成功'
        user_money_dic['flow'].append(flow2)
        db_hander.user_save(login_user_dic)
        db_hander.user_save(user_money_dic)
        msg = f'用户:[{login_user}]给用户[{user_money}] 转账:[{money}] 元 成功'
        user_logger.info(msg)
        return True, msg
    msg = f'用户:[{login_user}]银行余额不足'
    user_logger.info(msg)
    return False, msg


# 流水接口列表查询
def check_flow_interface(login_user):
    # 先获取用户字典
    login_user_dic = db_hander.user_select(login_user)
    flow_list = login_user_dic['flow']
    return flow_list


# 支付接口
def pay_interface(login_user, cost):
    user_dic = db_hander.user_select(login_user)
    if user_dic.get('balance') >= cost:
        user_dic['balance'] -= cost

        flow = f'用户:{login_user}消费金额:{cost}'
        user_dic['flow'].append(flow)
        db_hander.user_save(user_dic)
        user_logger.info(flow)
        return True
    return False


shop_interface.py(购物业务接口处理)

'''
购物商城接口
'''
from interface import bank_interface
from db import db_hander
from lib import common
shop_logger = common.get_log(log_type='shop')

# 商品准备结算接口
def shopping_interface(login_user, shopping_car):
    # 计算商品总价
    cost = 0
    for shop_price in shopping_car.values():
        price, number = shop_price
        cost += (price * number)

    # 逻辑校验成功,调用银行的支付接口
    flag = bank_interface.pay_interface(login_user, cost)
    if flag:
        msg = f'用户:[{login_user}]支付 [{cost}$] 成功, 准备发货!'
        shop_logger.info(msg)
        return True, msg

    return False, '支付失败,金额不足'


# 商品添加购物车功能
def add_shop_car_interface(login_user, shopping_car):
    # 获取当前用户的购物车
    user_dic = db_hander.user_select(login_user)
    #原来用户的字典的商城列表
    shop_car = user_dic.get('shop_car')

    for shop_name, price_number in shopping_car.items():
        number = price_number[1]
        if shop_name in shop_car:
            user_dic['shop_car'][shop_name][1] += number
        else:
            user_dic['shop_car'].update(
                {shop_name: price_number}
            )
        db_hander.user_save(user_dic)
    return True, '添加购物车成功'

# 查看购物车接口
def check_shop_car_interface(login_user):
    # 获取当前用户的购物车
    user_dic = db_hander.user_select(login_user)
    shop_list = user_dic['shop_car']
    return shop_list

user_interface.py(用户业务接口处理)

'''
用户相关的接口

'''
import os
import json

from db import db_hander
from lib import common
user_logger=common.get_log('user')

# 用户注册
def register_interface(username, password, balance=15000):
    # 2)查看用户是否存在
    # 2.1) 调用 数据处理层 中的 select函数,会返回 用户字典 或 None
    user_dic = db_hander.user_select(username)

    # {user: user, pwd: pwd...}   or  None
    # 若用户存在,则return,告诉用户重新输入
    if user_dic:
        # return (False, '用户名已存在!')
        return False, '用户名已存在!'

    # 3)若用户不存在,则保存用户数据
    # 做密码加密
    password = common.salt(username, password)

    # 3.1) 组织用户的数据的字典信息
    user_dic = {
        'username': username,
        'password': password,
        'balance': balance,
        # 用于记录用户流水的列表
        'flow': [],
        # 用于记录用户购物车
        'shop_car': {},
        # locked:用于记录用户是否被冻结
        # False: 未冻结   True: 已被冻结
        'locked': False
    }

    # 3.2)保存数据
    db_hander.user_save(user_dic)
    msg=f'{username} 注册成功!'
    user_logger.info(msg)
    return True, msg


# 登录接口
def longin_interface(username, password):
    # 先查看用户是否存在
    user_dic = db_hander.user_select(username)
    password_md5 = common.salt(username, password)

    if user_dic:
        print(user_dic.get('locked'))
        if user_dic.get('locked'):
            return False, f'用户:[{username}]已经被冻结'
        if password_md5 == user_dic['password']:
            msg=f'用户:[{username}] 登录成功  '
            user_logger.info(msg)
            return True,msg

        else:
            msg = f'用户:[{username}]密码错误'
            user_logger.warning(msg)
            return False, msg
    msg = f'用户[{username}]不存在,请重新输入'
    user_logger.info(msg)
    return False, msg


# 查看用户余额接口
def check_balance_interface(login_user):
    user_dic = db_hander.user_select(login_user)
    return user_dic.get('balance')

lib

common.py(公用类,盐MD5加密,登录装饰器)

import hashlib
from core import src
from conf import setting
import logging.config


# 盐加密,通名字加密 密码

def salt(username, password):
    password_ms5= hashlib.md5()
    password_ms5.update((username+password).encode('utf-8'))
    res = password_ms5.hexdigest()
    return res


# 登录认证装饰器
def login_auth(func):
    def inner(*args, **kwargs):
        if src.login_user:
            res = func(*args, **kwargs)
            return res
        else:
            print('未出示证明,无法享受服务')
            src.login()

    return inner


# 添加日志功能(日志功能在接口层使用)
def get_log(log_type):
    '''
    :param log_type:  user日志   bank日志   购物商城日志
    :return:
    '''
    # 1、加载日志配置信息
    logging.config.dictConfig(
        setting.LOGGING_DIC
    )
    # 获取日志对象
    logger = logging.getLogger(log_type)
    return logger

log(日志文件记录)

a1.log

2020-11-29 23:03:52,782 - MainThread:13396 - 日志名字:user - user_interface.py:58 -INFO - 用户:[q]登录成功!
2020-11-29 23:04:11,089 - MainThread:13396 - 日志名字:user - user_interface.py:58 -INFO - 用户:[w]登录成功!
2020-11-29 23:04:15,584 - MainThread:13396 - 日志名字:user - user_interface.py:69 -INFO - 用户不存在,请重新输入

整体项目架构不错,可以很清楚了解到三层架构的构建

用户点击:用户视图层————————》业务接口处理————————》数据库数据处理

数据返回用户:数据处理完数据————————》业务接口处理————————》用户视图层

原文地址:https://www.cnblogs.com/heian99/p/14124796.html