【python--- ATM+SHOPPING】

发布时间 2024-01-02 15:32:03作者: Unfool
title:  【python--- ATM+SHOPPING】
date:  2023-12-06  18:54:06 
updated: 2023-12-06 19:20:00
description:    ATM+SHOP
cover:  null

项目说明书 README.me文档

可以理解为前言,用于理解下列内容的解读

用于ATM提款+shop购物车

主要分为四个部分
1、bin
main 存放ATM架构的主体架构,可以直接在此启动,但是当前将启动目录拆出来了
2、conf
settings 当前主要目的是确认/创建目录(创建根目录,日志目录,数据目录等),日志收集格式 注:其实日志等信息可以单拎做一个py文件
3、core 可以理解为前端框架
admin_src admin/管理员用户的主要内容框架
bank_src bank/支付相关操作的模块框架
user_src 普通用户(包括管理员)的主要框架
shop_src 购物车内容
4、db
数据存放目录(shop_list/user_data)
db_handler 数据处理(主要分为数据存储,数据读取)
5、interface 可以理解为后端内容
admin_interface admin用户的主要模块的具体内容
bank_interface 银行/支付操作的主要内容
user_interface 普通用户的主要操作内容
shop_interface 购物车的主要内容
6、lib
common 公共模块,如加密,装饰器(确认除了登陆注册之外的其他操作是否经由登陆、激活银行卡操作,否则将无法操作除注册登陆以外的其他操作)、账户锁定及确认是否锁定的情况
7、log 日志存放目录

8、start 启动文件

后续以上列的顺序将以代码的形式展现出来
当前为本人第一次写的情况下应该属于比较完善的一个ATM+shop的项目,有不少地方都是比较冗余的,望见谅

main

from core.admin_src import admin
from core.bank_src import add_bank_info, get_balance, give_balance, recharge, check_flow, check_bank_info
from core.shop_src import shop
from core.user_src import login, register, exit_user

func_menu = """
# ==================ATM+购物车==================
                1、注册功能
                2、登陆功能
                3、激活银行卡
                4、提现/取款功能  
                5、转账功能
                6、充值余额
                7、查看流水功能
                8、查看银行信息(查看自己的卡号、余额、流水等信息)
                9、购物功能
                10、管理员功能
                11、退出登陆当前用户
# ====================欢迎使用==================
"""

func_dict = {
    1: register,
    2: login,
    3: add_bank_info,
    4: get_balance,
    5: give_balance,
    6: recharge,
    7: check_flow,
    8: check_bank_info,
    9: shop,
    10: admin,
    11: exit_user
}


def main():
    while True:
        print(func_menu)
        func_id = input('请输入你要选择的菜单序列号:>>>>>').strip()
        if not func_id.isdigit():
            print('你当前输入的序列格式异常,请输入数字格式进行操作')
            continue
        func_id = int(func_id)
        if func_id not in func_dict:
            print(f'请输入菜单序列号以进行相关操作')
            continue
        func_dict.get(func_id)()

settings


import os
import logging
import logging.config
import sys

#收集当前执行程序的各个目录位置
list_path = []

try:
    # 想要给日志上色就安装这个模块
    import coloredlogs
except Exception as e:
    if str(e) == "No module named 'coloredlogs'":
        pass

#(主要是第一次执行程序的时候创建目录)创建目录
def create_path(*args):
    for path in args:
        if not os.path.exists(path):
            os.mkdir(path)
            print(f'{path}目录创建完成')


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

DATA_PATH = os.path.join(BASE_PATH, 'db')
LOG_PATH = os.path.join(BASE_PATH, 'log')
USER_DATA_PATH = os.path.join(DATA_PATH, 'user_data')
USER_LOG_PATH = os.path.join(LOG_PATH, 'user_log')
USER_FLOW_PATH = os.path.join(LOG_PATH, 'flow_log')
USER_SHOP_PATH = os.path.join(DATA_PATH, 'shop_list')

list_path.append(USER_SHOP_PATH)
list_path.append(DATA_PATH)
list_path.append(LOG_PATH)
list_path.append(USER_FLOW_PATH)
list_path.append(USER_LOG_PATH)
list_path.append(USER_DATA_PATH)
create_path(*list_path)

# 日志文件路径
# os.getcwd() : 获取当前工作目录,即当前python脚本工作的目录路径
# 拼接日志文件路径 : 当前工作路径 + “logs”(日志文件路径)
LOG_PATH = LOG_PATH
# OS模块 : 创建多层文件夹
# exist_ok=True 的意思是如果该目录已经存在,则不会抛出异常。
os.makedirs(LOG_PATH, exist_ok=True)
# log日志文件路径 : 路径文件夹路径 + 日志文件
LOG_FILE_PATH = os.path.join(USER_LOG_PATH,'user_log.log')

# 自定义日志级别
CONSOLE_LOG_LEVEL = "INFO"
FILE_LOG_LEVEL = "DEBUG"

# 自定义日志格式
# 打印在文件里的格式:时间戳 + 线程名 + 线程ID + 任务ID + 发出日志调用的源文件名 + 发出日志调用的源代码行号 + 日志级别 + 日志消息正文
# [2023-06-04 15:16:05][MainThread:22896][task_id:root][调用.py:12][INFO][这是注册功能]
STANDARD_FORMAT = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d][%(levelname)s][%(message)s]'
# 打印在控制台的格式:日志级别 + 时间戳 + 发出日志调用的源文件名 + 发出日志调用的源代码行号 + 日志消息正文
# [INFO][2023-06-04 15:37:28,019][调用.py:12]这是注册功能

SIMPLE_FORMAT = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'
'''
参数详解:
-1.%(asctime)s: 时间戳,表示记录时间
-2.%(threadName)s: 线程名称
-3.%(thread)d: 线程ID
-4.task_id:%(name)s: 任务ID,即日志记录器的名称
-5.%(filename)s: 发出日志调用的源文件名
-6.%(lineno)d: 发出日志调用的源代码行号
-7.%(levelname)s: 日志级别,如DEBUG、INFO、WARNING、ERROR、CRITICAL等
-8.%(message)s: 日志消息正文
'''

# 日志配置字典
LOGGING_DIC = {
    # 日志版本
    'version': 1,
    # 表示是否要禁用已经存在的日志记录器(loggers)。
    # 如果设为 False,则已经存在的日志记录器将不会被禁用,而是可以继续使用。
    # 如果设为 True,则已经存在的日志记录器将会被禁用,不能再被使用。
    'disable_existing_loggers': False,
    # 格式化程序:用于将日志记录转换为字符串以便于处理和存储。
    # 格式化程序定义了每个日志记录的输出格式,并可以包括日期、时间、日志级别和其他自定义信息。
    'formatters': {
        # 自定义格式一:年-月-日 时:分:秒
        'standard': {
            # 自定义日志格式 :时间戳 + 线程名 + 线程ID + 任务ID + 发出日志调用的源文件名 + 发出日志调用的源代码行号 + 日志级别 + 日志消息正文
            # 这里要对应全局的 STANDARD_FORMAT 配置
            'format': STANDARD_FORMAT,
            # 时间戳格式:年-月-日 时:分:秒
            'datefmt': '%Y-%m-%d %H:%M:%S'  # 时间戳格式
        },
        # 自定义格式二:
        'simple': {
            # 自定义日志格式:# 日志级别 + 时间戳 + 发出日志调用的源文件名 + 发出日志调用的源代码行号 + 日志消息正文
            # 这里要对应全局的 SIMPLE_FORMAT 配置
            'format': SIMPLE_FORMAT
        },
    },
    # 过滤器
    'filters': {},
    # 日志处理器
    'handlers': {
        # 自定义处理器名称 - 输出到控制台屏幕
        'console': {
            # 设置日志等级 为INFO
            'level': CONSOLE_LOG_LEVEL,
            # 表示该处理器将输出日志到流(stream):日志打印到控制台
            'class': 'logging.StreamHandler',
            # 日志打印格式:日志级别 + 时间戳 + 发出日志调用的源文件名 + 发出日志调用的源代码行号 + 日志消息正文
            # 这里的配置要对应 formatters 中的 simple 配置
            'formatter': 'simple'
        },
        # 自定义处理器名称 - 输出到文件
        'default': {
            # 自定义日志等级
            'level': FILE_LOG_LEVEL,
            # 标准输出到文件
            'class': 'logging.handlers.RotatingFileHandler',
            # 日志打印格式:年-月-日 时:分:秒
            # 这里的配置要对应 formatters 中的 standard 配置
            'formatter': 'standard',
            # 这里 要注意声明配置文件输出端的文件路径
            'filename': LOG_FILE_PATH,
            # 限制文件大小:1024 * 1024 * 5 = 5242880,意味着这个变量的值是 5MB(兆字节)
            'maxBytes': 1024 * 1024 * 5,
            # 表示保留最近的5个日志文件备份。
            # 当日志文件达到最大大小限制时,将会自动轮转并且保留最新的5个备份文件,以便查看先前的日志记录。
            # 当日志文件达到最大大小限制时,会自动进行轮转,后续的文件名将会以数字进行命名,
            # 例如,第一个备份文件将被重命名为原始日志文件名加上".1"的后缀,
            # 第二个备份文件将被重命名为原始日志文件名加上“.2”的后缀,
            # 以此类推,直到保留的备份数量达到设定的最大值。
            'backupCount': 5,
            # 日志存储文件格式
            'encoding': 'utf-8',
        },
    },
    # 日志记录器,用于记录应用程序的运行状态和错误信息。
    'loggers': {
        # 空字符串作为键 能够兼容所有的日志(当没有找到对应的日志记录器时默认使用此配置)
        # 默认日志配置
        '': {
            # 日志处理器 类型:打印到控制台输出 + 写入本地日志文件
            'handlers': ['default'],
            # 日志等级 : DEBUG
            'level': 'DEBUG',
            # 默认情况下,当一个日志消息被发送到一个Logger对象且没有被处理时,该消息会被传递给它的父Logger对象,以便在更高层次上进行处理。
            # 这个传递过程称为“传播(propagation)”,而propagate参数指定了是否要使日志消息向上传播。
            # 将其设置为True表示应该传播消息到上一级的Logger对象;如果设置为False则不传播。
            # 表示异常将会在程序中继续传播
            # 也就是说,如果一个异常在当前的代码块中没有被处理,它将会在上级代码块或调用函数中继续向上传递,直到被某个代码块捕获或者程序退出。
            # 这是 Python 中异常处理机制的默认行为。
            # 如果将 'propagate' 设置为 False,则异常不会被传播,即使在上级代码块中没有处理异常的语句,程序也会忽略异常并继续执行。
            'propagate': True,
        },
    },
}


def set_logging_color(name='', ):
    # 初始化日志处理器 - 使用配置字典初始化日志处理器(将自定义配置加载到日志处理器中)
    # logging.basicConfig(level=logging.WARNING)
    logging.config.dictConfig(LOGGING_DIC)
    # 实例化日志处理器对象 - 并赋予日志处理器等级
    logger = logging.getLogger(name)
    # 将logger对象传递给coloredlogs.install()函数,并执行该函数以安装彩色日志记录器,使日志信息在控制台上呈现为带有颜色的格式。
    # 具体来说,该函数会使用ANSI转义序列在终端上输出日志级别、时间戳和消息等信息,并按日志级别使用不同的颜色来区分它们。这可以让日志信息更易于阅读和理解。
    coloredlogs.install(logger=logger)
    # 禁止日志消息向更高级别的父记录器(如果存在)传递。
    # 通常情况下,当一个记录器发送一条日志消息时,该消息会被传递给其所有祖先记录器,直到传递到根记录器为止。但是,通过将logger.propagate设置为False,就可以阻止该记录器的消息向上层传递。
    # 换句话说,该记录器的消息只会被发送到该记录器的处理程序(或子记录器)中,而不会传递给祖先记录器,即使祖先记录器的日志级别比该记录器要低。
    # 这种方法通常适用于需要对特定记录器进行控制,并希望完全独立于其祖先记录器的情况。
    # 确保 coloredlogs 不会将我们的日志事件传递给根 logger,这可以防止我们重复记录每个事件
    logger.propagate = False
    # 配置 日志颜色
    # 这段代码定义了一个名为coloredFormatter的变量,并将其赋值为coloredlogs.ColoredFormatter。
    # 这是一个Python库中的类,用于创建带有彩色日志级别和消息的格式化器。
    # 该变量可以用作日志记录器或处理程序的格式化程序,以使日志输出更易于阅读和理解。
    coloredFormatter = coloredlogs.ColoredFormatter(
        # fmt表示格式字符串,它包含了一些占位符,用于在记录日志时动态地填充相关信息。
        # [%(name)s]表示打印日志时将记录器的名称放在方括号内,其中name是一个变量名,将被记录器名称所替换。
        # %(asctime)s表示打印日志时将时间戳(格式化为字符串)插入到消息中,其中asctime是时间的字符串表示形式。
        # %(funcName)s表示打印日志时将函数名插入到消息中,其中funcName是函数的名称。
        # %(lineno)-3d表示打印日志时将行号插入到消息中,并且将其格式化为3位数字,其中lineno表示行号。
        # %(message)s表示打印日志时将消息本身插入到消息中。
        # 综合起来,这个格式字符串将在记录日志时输出以下信息:记录器名称、时间戳、函数名称、行号和日志消息。
        # 记录器名称 + 时间戳 + 函数名称 + 行号 + 日志消息
        # [root] 2023-06-04 16:00:57 register 15   this is an info message
        fmt='[%(name)s] %(asctime)s %(funcName)s %(lineno)-3d  %(message)s',
        # 级别颜色字典
        level_styles=dict(
            # debug 颜色:白色
            debug=dict(color='white'),
            # info 颜色:蓝色
            info=dict(color='blue'),
            # warning 颜色:黄色 且 高亮
            warning=dict(color='yellow', bright=True),
            # error 颜色:红色 且 高亮 且 加粗
            error=dict(color='red', bold=True, bright=True),
            # critical 颜色:灰色 且 高亮 且 背景色为红色
            critical=dict(color='black', bold=True, background='red'),
        ),
        # 这段代码定义了一个名为field_styles的字典 , 其中包含四个键值对。
        # 每个键代表日志记录中的不同字段,而每个值是一个字典,它指定了与该字段相关联的样式选项。
        # 具体来说,这些字段和样式选项如下:
        # name:指定记录器的名称,将使用白色颜色。
        # asctime:指定日志记录的时间戳,将使用白色颜色。
        # funcName:指定记录消息的函数名称,将使用白色颜色。
        # lineno:指定记录消息的源代码行号,将使用白色颜色。
        field_styles=dict(
            name=dict(color='white'),
            asctime=dict(color='white'),
            funcName=dict(color='white'),
            lineno=dict(color='white'),
        )
    )

    ## 配置 StreamHandler:终端打印界面
    # 这行代码定义了一个名为ch的日志处理器。
    # 具体来说,它是logging.StreamHandler类的一个实例,用于将日志输出到标准输出流(即控制台)中。
    # 在创建StreamHandler对象时,需要指定要使用的输出流
    # 因此stream=sys.stdout参数指定了该对象将把日志写入到标准输出流中.
    ch = logging.StreamHandler(stream=sys.stdout)
    # 这段代码是 Python 中用于设置日志输出格式的语句。
    # 它使用了一个名为 coloredFormatter 的格式化器对象,并将其传递给 ch.setFormatter() 方法来指定输出日志的样式。
    # 具体来说,ch 是一个 Logger 对象,它代表了整个日志系统中的一个记录器。
    # 可以通过该对象来控制日志的级别、输出位置等行为。而 setFormatter() 方法则用于设置该 Logger 输出日志的格式化方式
    # 这里传递的是 coloredFormatter 格式化器对象。
    # 在实际应用中,coloredFormatter 可以是自定义的 Formatter 类或者已经存在的 Formatter 对象。
    # 这里 将 coloredFormatter - 彩色输出日志信息的格式化器 传入进去。
    ch.setFormatter(fmt=coloredFormatter)
    # 这段代码是在Python中添加一个日志记录器(logger)的处理器(handler)。其中,hdlr参数是指定要添加到记录器(logger)中的处理器(handler)对象,ch是一个代表控制台输出的处理器对象。
    # 这行代码的作用是将控制台输出的信息添加到日志记录器中。
    logger.addHandler(hdlr=ch)
    # 这段代码用于设置日志级别为DEBUG,也就是最低级别的日志记录。
    # 意思是在程序运行时,只有DEBUG级别及以上的日志信息才会被记录并输出,而比DEBUG级别更低的日志信息则不会被记录或输出。
    # DEBUG(调试)、INFO(信息)、WARNING(警告)、ERROR(错误)和CRITICAL(严重错误)。
    logger.setLevel(level=logging.DEBUG)
    # 返回日志生成对象
    return logger


def get_logger(name='', ):
    '''
    :param name: 日志等级
    :return:
    '''
    # 初始化日志处理器 - 使用配置字典初始化日志处理器(将自定义配置加载到日志处理器中)
    logging.config.dictConfig(LOGGING_DIC)
    # 实例化日志处理器对象 - 并赋予日志处理器等级
    logger = logging.getLogger(name)
    # 返回日志生成对象
    return logger

admin

from conf import settings
from core import user_src
from interface import admin_interface

logger = settings.get_logger('admin')



# 修改用户信息
def set_user_info():
    while True:
        flag,msg = admin_interface.set_user_info_interface()
        if flag:
            logger.info(msg)
            if '修改' in msg:
                print('')
            else:
                print(msg)

        else:
            print(msg)
            logger.warning(msg)
            break


#整理购物清单
def organize_shopping_list():
    while True:
        flag,msg = admin_interface.organize_shopping_list_interface()
        if flag:
            logger.info(msg)
            if '查看' in msg:
                print('')
            else:
                print(msg)
            if '退出' in msg:
                break
        else:
            print(msg)
            logger.warning(msg)


def exit_admin():
    print('退出管理员系统')


admin_menu = """
===================管理员功能菜单=====================
                  1、修改用户信息
                  2、整理购物清单
                  3、退出当前系统
======================欢迎使用=======================

"""

admin_dict = {
    1: set_user_info,
    2: organize_shopping_list,
    3: exit_admin
}


def admin():
    while True:
        if user_src.login_user_data_dict['role'] != 'admin':
            print('当前权限无法操作')
            break
        print(admin_menu)
        admin_id = input('请输入你要选择的菜单序列号:>>>>>').strip()
        if admin_id == '3':
            print('退出管理员系统')
            break
        if not admin_id.isdigit():
            print('你当前输入的序列格式异常,请输入数字格式进行操作')
            continue
        admin_id = int(admin_id)
        if admin_id not in admin_dict:
            print(f'请输入菜单序列号以进行相关操作')
            continue
        admin_dict.get(admin_id)()
        if admin_id == 4:
            break
			

bank_src

from conf import settings
from interface import bank_interface
from lib import login_auth

logger = settings.get_logger('bank')


# 激活银行卡信息
@login_auth
def add_bank_info():
    while True:
        flag, msg = bank_interface.add_bank_info_register()
        if flag:
            print(msg)
            logger.info(msg)
            break
        else:
            print(msg)
            logger.warning(msg)


# 取款
@login_auth
def get_balance():
    while True:
        flag, msg = bank_interface.get_balance_interface()
        if flag:
            print(msg)
            logger.info(msg)
            break
        else:
            print(msg)
            logger.warning(msg)


# 转账
@login_auth
def give_balance():
    while True:
        flag, msg = bank_interface.give_balance_interface()
        if flag:
            print(msg)
            logger.info(msg)
            break
        else:
            print(msg)
            logger.warning(msg)
            break


# 充值
@login_auth
def recharge():
    while True:
        flag, msg = bank_interface.recharge_interface()
        if flag:
            print(msg)
            logger.info(msg)
            break
        else:
            print(msg)
            logger.warning(msg)


# 流水查看
@login_auth
def check_flow():
    flag, msg = bank_interface.check_flow_interface()
    if flag:
        logger.info(msg)
        if '查看' in msg or '用户激活银行卡信息' in msg:
            print('')
        else:
            print(msg)
    else:
        print(msg)
        logger.warning(msg)


def check_bank_info():
    flag, msg = bank_interface.check_bank_info_interface()
    if flag:
        logger.info(msg)
        if '查看' in msg:
            print('')
        else:
            print(msg)
    else:
        print(msg)
        logger.warning(msg)

shop_src

from conf import settings
from interface import shop_interface
from lib import login_auth

logger = settings.get_logger('shop')

# 购物
@login_auth
def shopping():
    while True:
        flag, msg = shop_interface.shop_interface()
        if flag:
            print(msg)
            logger.info(msg)

        else:
            print(msg)
            logger.warning(msg)
            break

# 购物车
@login_auth
def check_shop_car():
    flag, msg = shop_interface.check_shop_cat_interface()
    if flag:
        logger.info(msg)
        if '查看' in msg:
            print('')
        else:
            print(msg)
    else:
        print(msg)
        logger.warning(msg)


# 结账
@login_auth
def checkout():
    while True:
        flag, msg = shop_interface.checkout_interface()
        if flag:
            print(msg)
            logger.info(msg)

        else:
            print(msg)
            logger.warning(msg)
            break


# 退出当前系统
def exit_shop():
    print('退出购物功能菜单')
    logger.info('退出购物功能菜单')


shop_menu = """
===================购物功能菜单=====================
                  1、选购
                  2、查看购物车
                  3、结账
                  4、退出购物系统 
======================欢迎使用=======================

"""

shop_dict = {
    1: shopping,
    2: check_shop_car,
    3: checkout,
    4: exit_shop
}


def shop():
    while True:
        print(shop_menu)
        shop_id = input('请输入你要选择的菜单序列号:>>>>>').strip()
        if not shop_id.isdigit():
            print('你当前输入的序列格式异常,请输入数字格式进行操作')
            continue
        shop_id = int(shop_id)
        if shop_id not in shop_dict:
            print(f'请输入菜单序列号以进行相关操作')
            continue
        shop_dict.get(shop_id)()
        if shop_id == 4:
            break

user_src

import os
from conf import USER_DATA_PATH, settings
from interface import user_interface

#注册的字典,用于注册时更新的字典和后续相关数据更新时使用的字典
register_dict = {}

#全局登陆字典,用于确认当前登陆用户的数据
login_user_data_dict = {
    'username': None,
    'bank_id': None,
    'bank_pay_pwd': None,
    'balance': None,
    'shops:': None,
    'locked': 'false',
    'count': '0'
}

#系统json的数据文件
data_file = os.path.join(USER_DATA_PATH, 'user_data.json')

#日志采集
logger = settings.get_logger('user')


# 1、获取用户登陆信息  用户名-密码
def get_user_pwd():
    username = input('请输入用户名:').strip()
    password = input('请输入登陆密码:').strip()

    return username, password

#注册
def register():
    while True:
        username, password = get_user_pwd()
        re_password = input('请确认你的密码').strip()
        if password == re_password:
            flag, msg = user_interface.register_interface(username, password)
            if flag:
                print(msg)
                logger.info(msg)
                break
            else:
                print(msg)
                logger.warning(msg)
        else:
            print('你输入的信息有误,请确认后重试')
            logger.warning('输入的信息有误')

#登陆
def login():
    while True:
        if not login_user_data_dict or login_user_data_dict['username'] is None:
            username, password = get_user_pwd()
            flag, msg = user_interface.login_interface(username, password)
            if flag:
                print(msg)
                logger.info(msg)
                break
            else:
                print(msg)
                logger.warning(msg)
        else:
            print(f"当前已有用户登陆->:{login_user_data_dict['username']},麻烦先退出后在登陆")
            break


#退出登陆
def exit_user():
    print('退出当前登陆用户')
    login_user_data_dict.clear()
    logger.info('退出当前登陆用户')

db_handler

import json
import os
from datetime import datetime

from conf import USER_DATA_PATH, USER_FLOW_PATH, USER_SHOP_PATH


# 创建目录---根据下面的条件先创建目录,如果不包含的情况返回False及相关信息
def create_path(path):
    if 'shop' in path:
        new_path = os.path.join(USER_SHOP_PATH, path)
    elif 'data' in path:
        new_path = os.path.join(USER_DATA_PATH, path)
    elif 'flow' in path:
        new_path = os.path.join(USER_FLOW_PATH, path)
    else:
        return False, '参数异常'
    return True, new_path


# 读数据,将存入文本的数据根据相关条件进行读取
def read_data(path='None', tag='None'):
    flag, new_path = create_path(path)
    if not flag:
        return flag, new_path
    if tag == 'data' or tag == 'shop':
        with open(new_path, mode='r') as fp:
            data = json.load(fp)
    elif tag == 'flow':
        with open(new_path, mode='r') as fp:
            data = fp.read().split('\n')
            for i in data:
                print(i)
    return True, data


# 保存数据到文件中
def save_data(path='None', data='None', tag='None'):
    flag, new_path = create_path(path)
    if not flag:
        return flag, f'{new_path}非法路径'
    if tag == 'data' or tag == 'shop':
        with open(new_path, mode='w') as fp:
            json.dump(data, fp, ensure_ascii=False)
    elif tag == 'flow':
        with open(new_path, mode='a', encoding='utf8') as fp:
            data = fp.write(data + f"----> time: {datetime.now().strftime('%Y年%m月%d日 %H时%M分%S秒')}" + '\n')
    return True, data

admin_interface

import os
from conf import USER_SHOP_PATH
from core import user_src
from db import read_data, save_data
from interface import shop_interface

change_list = {
    1: '增加信息',
    2: '删除信息',
    3: '修改信息',
}


def set_user_info_interface():
    flag, data = read_data(tag='data', path='user_data.json')
    if not flag:
        return flag, data
    if user_src.login_user_data_dict['role'] != 'admin':
        return False, f"{user_src.login_user_data_dict['username']}用户无相应权限"
    res_user = input('请选择你要修改的用户信息:----->')
    # 读取文件进行判断,判断选择的用户是否已注册
    if res_user not in data:
        return False, f"{user_src.login_user_data_dict['username']}用户修改{res_user}用户信息,{res_user}用户不存在,修改失败"
    if res_user == user_src.login_user_data_dict['username']:
        username = res_user
        # 设定只有管理员可以修改权限
        role = input('请输入修改用户的权限(回车默认原来权限):----->').strip()
        if not role:
            role = data[username]['role']
            print(f'当前权限未修改 {role}')
        if role == 'admin' and username == 'quan':
            role = 'admin'
        balance = input('请输入修改用户的金额:----->').strip()
        if not balance or not balance.isdigit():
            balance = data[username]['balance']
            print(f'当前金额未调整 ---> {balance}')
        locked = input('请输入true/false,以修改用户的账户锁定情况:---->').strip()
        if not locked:
            locked = data[username]['locked']
            print(f'当前权限未修改, {locked}')
        if locked.upper() == 't' or locked.upper() == 'T':
            locked = 'true'
            print(f'账户状态已修改---{locked}')
        elif locked.upper() == 'f' or locked.upper() == 'F':
            locked = 'false'
            print(f'账户状态已修改---{locked}')
        if locked.lower() != 'true' or locked.lower() != 'false':
            return False, f'请按照需求修改用户状态 {locked}'

        user_src.register_dict[res_user] = {'username': username, 'password': data[username]['password'],
                                            'bank_id': data[username]['bank_id'],
                                            'bank_pay_pwd': data[username]['bank_pay_pwd'],
                                            'role': role, 'balance': str(balance), 'locked': locked}
        data = user_src.register_dict
        if os.path.exists(user_src.data_file):
            flag, data = read_data(tag='data', path='user_data.json')
            if not flag:
                return flag, data
            data.update(user_src.register_dict)
        flag, data = save_data(path='user_data.json', data=data, tag='data')
        if not flag:
            return flag, data
        flag, msg = save_data(path=f'{username}_log.log', tag='log', data=f'{username}用户信息修改完成')
        if not flag:
            return flag, msg
        print(f"{user_src.login_user_data_dict['username']}用户修改{username}用户信息完成")
        return True, f"{user_src.login_user_data_dict['username']}用户修改{username}用户信息"


# 编辑商品信息
def organize_shopping_list_interface():
    flag, data = read_data(path='shop.json', tag='shop')
    if not flag:
        return flag, data
    print("货架存在的商品信息如下:")
    for i, info in enumerate(data.values(), start=1):
        name, price, num = info.values()
        print(f"商品编号:{i}  商品名:{name}  商品价格:{price}  商品数量:{num}")
    for i, info in enumerate(change_list.values(), start=1):
        print(i, info)
    print('请根据数字进行相应操作')
    change_id = input('请确认你要执行的商品操作菜单序号----->').strip()
    if change_id == 'q':
        return True, '用户退出修改商品信息'
    if not change_id.isdigit():
        return False, '请根据数字格式进行对应的操作'
    change_id = int(change_id)
    if change_id not in change_list:
        return False, '请按照对应的菜单序列进行选择操作(数字)'
    # 增加
    if int(change_id) == 1:
        shop_name = input('请输入你要添加的商品名:------>').strip()
        shop_price = input('请输入添加的商品价格:------->').strip()
        shop_count = input('请输入你要上架的商品数量:------>').strip()
        if not shop_price.isdigit() and not shop_count.isdigit():
            return False, '请按照格式进行修改(数字格式)'
        shop_interface.shops_list[shop_name] = {'name': shop_name, 'price': shop_price, 'count': shop_count}
        data = shop_interface.shops_list
        shop_file = os.path.join(USER_SHOP_PATH, 'shop.json')
        if os.path.exists(shop_file):
            flag, data = read_data(tag='shop', path='shop.json')
            if not flag:
                return flag, data
            data.update(shop_interface.shops_list)
        save_data(path=f"shop.json", tag='shop', data=data)
        return True, f'{shop_name}商品已添加'
    # 删除
    if int(change_id) == 2:
        del_name = input('请输入你要删除的商品信息:----->').strip()
        if del_name not in data:
            return False, '商品信息不存在,无法删除'
        print(f'删除的商品:{del_name}')
        is_sure_del = input('请确认是否删除当前商品y/YES(其他输入项默认为否)------>').strip()
        if is_sure_del.upper() != 'Y' and is_sure_del.upper() != 'YES':
            return False, '商品不删除'
        del data[del_name]
        save_data(path='shop.json', tag='shop', data=data)
        return True, f'商品{del_name}已删除'
    # 改操作
    if int(change_id) == 3:
        select_shop = input('请选择你要修改的商品:----->').strip()
        if select_shop not in data:
            return False, '请确认当前商品进行修改,当前商品不存在'
        select_price = input('请选择你要修改的价格').strip()
        if not select_price.isdigit():
            return False, '请确认输入的修改格式'
        select_count = input('请选择你要修改的数量').strip()
        if not select_count.isdigit():
            return False, '请确认输入格式是否正常'
        shop_interface.shops_list[select_shop] = {'name': select_shop, 'price': select_price, 'count': select_count}
        data = shop_interface
        shop_file = os.path.join(USER_SHOP_PATH, 'shop.json')
        if os.path.exists(shop_file):
            flag, data = read_data(tag='shop', path='shop.json')
            if not flag:
                return flag, data
            data.update(shop_interface.shops_list)
        save_data(path=f"shop.json", tag='shop', data=data)
        return True, f"{select_shop}商品已修改"

bank_interface

import os
import random

from conf import USER_FLOW_PATH
from core import user_src
from core.user_src import login_user_data_dict, register_dict, data_file
from db import save_data, read_data
from lib.common import get_pwd_md5, init_bank_info, set_is_locked


# 用于将数据写入到json数据文本和日志中去
def load_log(is_true):
    data = register_dict
    if os.path.exists(data_file):
        flag, data = read_data(tag='data', path='user_data.json')
        if not flag:
            return flag, data
        data.update(register_dict)
    flag, data = save_data(path=f"user_data.json", tag='data', data=data)
    if not flag:
        return False, data
    if is_true == 'add_bank_info':
        flag, new_msg = save_data(path=f"{login_user_data_dict['username']}_flow.log",
                                  data=f"{login_user_data_dict['username']}用户激活银行卡信息成功", tag='flow')
        if not flag:
            return flag, new_msg
        save_data(path=f"user_flow.log",
                  data=f"{login_user_data_dict['username']}用户激活银行卡信息成功", tag='flow')
    if is_true == 'get_balance':  # 取款
        save_data(path=f"user_flow.log", tag='flow',
                  data=f"{login_user_data_dict['username']}用户取款成功,取款金额:{register_dict[login_user_data_dict['username']]['balance']}")
        save_data(path=f"{login_user_data_dict['username']}_flow.log", tag='flow',
                  data=f"{login_user_data_dict['username']}用户取款成功,取款金额:{register_dict[login_user_data_dict['username']]['balance']}")
    if is_true == 'recharge':  # 充值
        save_data(path=f"{login_user_data_dict['username']}_flow.log", tag='flow',
                  data=f"{login_user_data_dict['username']}用户充值成功,充值金额:{register_dict[login_user_data_dict['username']]['balance']}")
        save_data(path=f"user_flow.log", tag='flow',
                  data=f"{login_user_data_dict['username']}用户充值成功,充值金额:{register_dict[login_user_data_dict['username']]['balance']}")


def add_bank_info_register():
    if login_user_data_dict['bank_id'] != 'None':
        return False, '账户已初始化,无需重复执行'
    if login_user_data_dict['locked'] != 'false':
        return False, '当前用户已被锁定,请联系管理员解锁'
    bank_id = input('请输入你的银行卡号(跳过的话直接回车键随机生成六位数银行卡号):----->').strip()
    if not bank_id:
        bank_id = random.randrange(100000, 999999)
        save_data(path=f"{login_user_data_dict['username']}_flow.log", tag='flow',
                  data=f"{login_user_data_dict['username']}用户初始化银行卡信息,选择随机生成六位数银行卡")
        print(f'已为你重新生成六位数银行卡号{bank_id},请牢记')
    elif not bank_id.isdigit():
        return False, f"{login_user_data_dict['username']}用户初始化银行卡信息,输入银行卡号格式异常"
    elif len(bank_id) != 6:
        return False, f"{login_user_data_dict['username']}用户初始化银行卡信息,输入银行卡号格式异常"
    else:
        print(f'六位数银行卡号{bank_id},请牢记')
    bank_pay_pwd = input('请输入你的银行卡支付密码(4位):---->').strip()
    if not bank_pay_pwd.isdigit():
        return False, f"{login_user_data_dict['username']}用户初始化银行卡信息,输入银行卡号格式异常"
    if len(bank_pay_pwd) != 4:
        return False, f"{login_user_data_dict['username']}用户初始化银行卡信息,输入银行卡号长度不符要求"
    bank_pay_pwd = get_pwd_md5(bank_pay_pwd)
    register_dict[login_user_data_dict['username']] = {'username': login_user_data_dict['username'],
                                                       'password': login_user_data_dict['password'],
                                                       'bank_id': str(bank_id),
                                                       'bank_pay_pwd': str(bank_pay_pwd),
                                                       'role': login_user_data_dict['role'],
                                                       'balance': '0', 'locked': 'false'}
    load_log(is_true='add_bank_info')
    msg = f"""
        麻烦留意一下当前银行卡信息:
        用户名:                {login_user_data_dict['username']}
        银行卡号                {register_dict[login_user_data_dict['username']]['bank_id']}
        银行支付密码             {register_dict[login_user_data_dict['username']]['bank_pay_pwd']}
        一般情况下,支付密码和登陆密码是不会显示出来,只有根据登陆后对其进行修改
        """
    init_bank_info(login_user_data_dict['username'])
    print(f"{login_user_data_dict['username']}用户激活银行卡信息见:" + msg)
    return True, f"{login_user_data_dict['username']}用户激活银行卡信息"


def get_balance_interface():
    set_is_locked()
    count = int(user_src.login_user_data_dict['count'])
    print('取款附有取款利息,当前利息为5%')
    balance = input('请输入你要取得金额:---->').strip()
    if not balance.isdigit():
        return False, f"{login_user_data_dict['username']}用户取款,输入金额格式不符要求"
    if login_user_data_dict['balance'] == 'None':
        return False, f"{login_user_data_dict['username']}用户尚未激活银行卡信息,无法取款"
    if float(balance) > float(login_user_data_dict['balance']):
        return False, f"{login_user_data_dict['username']}用户取款,账户金额不足,取款失败"

    bank_pwd = input('请输入支付密码:------>').strip()
    if not bank_pwd.isdigit():
        count += 1
        count = str(count)
        login_user_data_dict['count'] = count
        return False, f"{login_user_data_dict['username']}用户取款,输入支付密码格式不符要求"

    bank_pwd = get_pwd_md5(bank_pwd)
    if bank_pwd != login_user_data_dict['bank_pay_pwd']:
        count += 1
        count = str(count)
        login_user_data_dict['count'] = count

        return False, f"{login_user_data_dict['username']}用户取款,输入支付密码错误"

    # 定义取款后金额
    balance_interest = float(balance) * 0.05
    new_balance = float(login_user_data_dict['balance']) - float(balance) - balance_interest

    login_user_data_dict['balance'] = str(new_balance)
    register_dict[login_user_data_dict['username']] = {'username': login_user_data_dict['username'],
                                                       'password': login_user_data_dict['password'],
                                                       'bank_id': login_user_data_dict['bank_id'],
                                                       'bank_pay_pwd': str(bank_pwd),
                                                       'role': login_user_data_dict['role'],
                                                       'balance': new_balance, 'locked': 'false'}
    count = '0'
    login_user_data_dict['count'] = count
    load_log(is_true='get_balance')
    init_bank_info(login_user_data_dict['username'])
    return True, f"{login_user_data_dict['username']}用户取款成功,取款金额:{str(balance)},取款利息为{balance_interest}"


def give_balance_interface():
    set_is_locked()
    flag, date = read_data(path='user_data.json', tag='data')
    if not flag:
        return flag, date
    username = input('请输入你要转账的用户名:---->').strip()
    if username not in date:
        return False, f'转账用户{username}不存在'
    if date[username]['balance'] == 'None':
        return False, '当前转账用户银行信息未激活'
    balance_new = input('请输入你要转账的金额:---->').strip()
    if not balance_new.isdigit():
        return False, "{login_user_data_dict['username']}用户转账,输入金额格式不符要求,数字格式"
    balance_new = float(balance_new)
    if login_user_data_dict['balance'] == 'None':
        return False, f"{login_user_data_dict['username']}用户尚未激活银行卡信息,无法转账"
    if balance_new <= 0 or balance_new > float(login_user_data_dict['balance']) or float(
            login_user_data_dict['balance']) <= 0:
        return False, "{login_user_data_dict['username']}用户转账,输入金额额度不符要求"
    bank_pwd = input('请输入你的支付密码:---->').strip()
    count = int(user_src.login_user_data_dict['count'])
    if not bank_pwd.isdigit():
        count += 1
        count = str(count)
        login_user_data_dict['count'] = count
        return False, "{login_user_data_dict['username']}用户转账,输入支付密码格式不符要求"

    bank_pwd = get_pwd_md5(bank_pwd)
    if bank_pwd != login_user_data_dict['bank_pay_pwd']:
        count += 1
        count = str(count)
        login_user_data_dict['count'] = count
        return False, "{login_user_data_dict['username']}用户转账,输入支付密码错误"

    balance = float(login_user_data_dict['balance']) - float(balance_new)  # 针对当前用户  额外定义一个空余额用于赋值转账后的余额, = 原本的余额 - 转账余额
    register_dict[login_user_data_dict['username']] = {'username': login_user_data_dict['username'],
                                                       'password': login_user_data_dict['password'],
                                                       'bank_id': login_user_data_dict['bank_id'],
                                                       'bank_pay_pwd': bank_pwd,
                                                       'role': login_user_data_dict['role'],
                                                       'balance': balance, 'locked': 'false'}
    data = register_dict
    count = '0'
    login_user_data_dict['count'] = count
    if os.path.exists(data_file):
        flag, data = read_data(tag='data', path='user_data.json')
        if not flag:
            return flag, data
        data.update(register_dict)
    # 保存当前用户的数据
    flag, msg = save_data(path=f"user_data.json", tag='data', data=data)
    if not flag:
        return flag, msg
    flag, data = read_data(path=f"user_data.json", tag='data')
    if not flag:
        return flag, data
    balance = float(data[username]['balance']) + balance_new
    register_dict[username] = {'username': username,
                               'password': data.get(username)['password'],
                               'bank_id': data.get(username)['bank_id'],
                               'bank_pay_pwd': data.get(username)['bank_pay_pwd'],
                               'role': data.get(username)['role'],
                               'balance': balance, 'locked': 'false'
                               }
    data = register_dict
    if os.path.exists(data_file):
        flag, data = read_data(tag='data', path='user_data.json')
        if not flag:
            return flag, data
        data.update(register_dict)
    # 保存转账用户的数据
    flag, msg = save_data(path=f"user_data.json", tag='data', data=data)
    if not flag:
        return flag, msg
    save_data(path=f"{login_user_data_dict['username']}_flow.log", tag='flow',
              data=f"{login_user_data_dict['username']}用户转账成功,转账用户{username},转账金额{balance_new}")
    save_data(path=f"user_flow.log", tag='flow',
              data=f"用户{username}收到{login_user_data_dict['username']}用户转账 ,金额{balance_new}")
    save_data(path=f"{login_user_data_dict['username']}_flow.log", tag='flow',
              data=f"{login_user_data_dict['username']}用户转账给{username}用户,转账金额{balance_new}")
    return True, f"{login_user_data_dict['username']}用户转账成功,转账用户{username},转账金额{balance_new}"


def recharge_interface():
    set_is_locked()
    balance = input('请输入你要充值的金额:---->').strip()
    if not balance.isdigit():
        return False, f"{login_user_data_dict['username']}用户充值金额,输入金额格式不符要求"
    balance = float(login_user_data_dict['balance']) + float(balance)  # 充值后的金额
    register_dict[login_user_data_dict['username']] = {
        'username': login_user_data_dict['username'],
        'password': login_user_data_dict['password'],
        'bank_id': login_user_data_dict['bank_id'],
        'bank_pay_pwd': login_user_data_dict['bank_pay_pwd'],
        'role': login_user_data_dict['role'],
        'balance': str(balance),
        'locked': 'false'
    }
    load_log(is_true='recharge')
    init_bank_info(login_user_data_dict['username'])
    return True, f"{login_user_data_dict['username']}用户充值成功,充值金额:{balance}"


def check_flow_interface():
    set_is_locked()
    flow_file = os.path.join(USER_FLOW_PATH, f"{login_user_data_dict['username']}_flow.log")
    if not os.path.exists(flow_file):
        return False, f"{login_user_data_dict['username']}用户无法查看流水信息,请检查当前用户是否有进行过相关金额操作后在查看"
    flag, msg = read_data(path=f"{login_user_data_dict['username']}_flow.log", tag='flow')
    if not flag:
        return flag, msg
    print('以上为流水信息')
    return True, f"{login_user_data_dict['username']}用户查看流水具体信息"


def check_bank_info_interface():
    set_is_locked()
    flag, data = read_data(path=f"user_data.json", tag='data')
    if not flag:
        return flag, data
    msg = f"""
        当前用户{login_user_data_dict['username']}银行信息见下:
        用户名:            {login_user_data_dict['username']}
        密码:              {data[login_user_data_dict['username']]['password']}
        银行卡号:           {data[login_user_data_dict['username']]['bank_id']}
        支付密码:           {data[login_user_data_dict['username']]['bank_pay_pwd']}
        权限:              {data[login_user_data_dict['username']]['role']}
        余额:              {data[login_user_data_dict['username']]['balance']}
        注:密码和支付密码信息属于加密信息,一般不会显示出来,只会用于更改信息
        如果上述信息显示为None,说明当前尚未激活银行信息,麻烦先移步激活银行信息步骤
        """
    print(msg)
    return True, f"{login_user_data_dict['username']}用户查看银行具体信息"

shop_interface

import os

from conf import USER_SHOP_PATH
from core import user_src
from core.user_src import data_file
from db import save_data, read_data
from lib.common import set_is_locked, get_pwd_md5, init_bank_info

shop_file = os.path.join(USER_SHOP_PATH, 'shop.json')

# 商店物品价目/数目清单
shops_list = {
    # '商品名':{价格,数量}
    'mac': {'name': 'mac', 'price': '20000', 'count': '3'},
    'iphone': {'name': 'iphone', 'price': '1000', 'count': '3'},
    'lenove': {'name': 'lenove', 'price': '3000', 'count': '10'},
    'tesla': {'name': 'tesla', 'price': '1000000', 'count': '10'},
    'chicken': {'name': 'chicken', 'price': '200', 'count': '1'}
}
# 用户购物清单
user_shop_list = {}
# 用户总账单
checkout_shops_list = []


def shop_interface():
    if not os.path.exists(shop_file):
        flag, msg = save_data(path='shop.json', tag='shop', data=shops_list)
        if not flag:
            return flag, msg
    set_is_locked()
    flag, data = read_data(path='shop.json', tag='shop')
    if not flag:
        return flag, data
    print("货架存在的商品信息如下:")
    for i, info in enumerate(data.values(), start=1):
        name, price, num = info.values()
        print(f"商品编号:{i}  商品名:{name}  商品价格:{price}  商品数量:{num}")
    select_shop = input('请输入你要购买的商品名:---->').strip()
    if select_shop == 'q':
        return False, f"{user_src.login_user_data_dict['username']}用户退出选购商品页面"
    if select_shop not in data:
        return False, f'无法获取你选择的商品:{select_shop},请查看商品列表进行购买'
    select_count = input('请确认你要购买当前商品的数量:---->').strip()
    if int(select_count) > int(data[select_shop]['count']):
        return False, f'选购数量超过当前商品总数'
    if int(data[select_shop]['count']) < 0:
        return False, f'抱歉,商品已售磬'
    # 更新用户的购物车列表:
    user_shop_list[select_shop] = {'name': data[select_shop]['name'], 'price': data[select_shop]['price'],
                                   'count': str(select_count)}
    data = user_shop_list
    user_shop_file = os.path.join(USER_SHOP_PATH, f"{user_src.login_user_data_dict['username']}_shop.json")
    if os.path.exists(user_shop_file):
        flag, data = read_data(tag='shop', path=f"{user_src.login_user_data_dict['username']}_shop.json")
        if not flag:
            return flag, data
    data.update(user_shop_list)
    flag, msg = save_data(path=f"{user_src.login_user_data_dict['username']}_shop.json", tag='shop', data=data)
    if not flag:
        return flag, msg

    return True, f"{user_src.login_user_data_dict['username']}用户已更新商品至购物车"


def check_shop_cat_interface():
    set_is_locked()
    user_shop_file = os.path.join(USER_SHOP_PATH, f"{user_src.login_user_data_dict['username']}_shop.json")
    if not os.path.exists(user_shop_file):
        return False, '当前未检索到购物车有商品,请前去购物之后在来查看或者进行后续结账吧'
    flag, data = read_data(path=f"{user_src.login_user_data_dict['username']}_shop.json", tag='shop')
    if not flag:
        return flag, data
    print("当前购物车商品信息如下:")
    for i, info in enumerate(data.values(), start=1):
        name, price, num = info.values()
        print(f"商品编号:{i}  商品名:{name}  商品价格:{price}  商品数量:{num}")
    save_data(path=f"{user_src.login_user_data_dict['username']}_log.log", tag='log',
              data=f"{user_src.login_user_data_dict['username']}用户查看购物车清单")
    print('以上为购物车清单')
    return True, f"{user_src.login_user_data_dict['username']}用户查看购物车清单"


# 结账
def checkout_interface():
    set_is_locked()
    user_shop_file = os.path.join(USER_SHOP_PATH, f"{user_src.login_user_data_dict['username']}_shop.json")
    if not os.path.exists(user_shop_file):
        return False, '当前未检索到购物车有商品,请前去购物之后在来查看或结账吧'
    flag, data = read_data(path=f"{user_src.login_user_data_dict['username']}_shop.json", tag='shop')
    if not flag:
        return flag, data

    print("当前购物车商品信息如下:")
    for i, info in enumerate(data.values(), start=1):
        name, price, num = info.values()
        print(f"商品编号:{i}  商品名:{name}  商品价格:{price}  商品数量:{num}")
    # for i in data:
    #     print(f"""
    #         =========当前购物车商品==========
    #         商品名:  {data[i]['name']}
    #         商品价格: {data[i]['price']}
    #         商品数量: {data[i]['count']}
    #         ===============================
    #         """)
    for i in data:
        checkout_shops_list.append(float(data[i]['price']) * float(data[i]['count']))
    checkout_data = sum(checkout_shops_list)
    print(f'当前所有商品的价格为:{checkout_data}')
    is_sure_checkout = input('请输入yes/no确认是否结账:----->').strip()
    if is_sure_checkout.upper() == 'Y' or is_sure_checkout.upper() == 'YES':
        bank_pwd = input('请输入支付密码:------>').strip()
        count = int(user_src.login_user_data_dict['count'])
        if not bank_pwd.isdigit():
            count += 1
            count = str(count)
            user_src.login_user_data_dict['count'] = count
            save_data(path=f"{user_src.login_user_data_dict['username']}_log.log", tag='log',
                      data=f"{user_src.login_user_data_dict['username']}用户取款,输入支付密码格式不符要求")
            checkout_shops_list.clear()
            return False, f'输入密码格式错误'
    else:
        checkout_shops_list.clear()
        return False, '请重新确认你的购物车需要结账的清单'

    bank_pwd = get_pwd_md5(bank_pwd)
    if bank_pwd != user_src.login_user_data_dict['bank_pay_pwd']:
        count += 1
        count = str(count)
        user_src.login_user_data_dict['count'] = count
        return False, f"{user_src.login_user_data_dict['username']}用户结账商品,输入支付密码错误"
    if float(user_src.login_user_data_dict['balance']) < float(checkout_data):
        return False, f"{user_src.login_user_data_dict['username']}用户余额不足,结账失败"
    #同步主商品列表信息
    flag, all_data = read_data(path='user_shop.json', tag='shop')
    if not flag:
        return flag, all_data
    # 将数据更新保存到文件中
    for i in data:
        # # 更新系统的物品清单:
        count = int(all_data[i]['count']) - int(data[i]['count'])
        user_shop_list[i] = {'name': i, 'price': data[i]['price'],
                             'count': count}
        data = user_shop_list
        if os.path.exists(shop_file):
            flag, data = read_data(tag='shop', path=f"user_shop.json")
            if not flag:
                return flag, data
        data.update(user_shop_list[i])
        flag, msg = save_data(path=f"user_shop.json", tag='shop', data=data)
        if not flag:
            return flag, msg

    # 保存数据到文本和全局用户字典
    balance = float(user_src.login_user_data_dict['balance']) - float(checkout_data)
    user_src.register_dict[user_src.login_user_data_dict['username']] = {
        'username': user_src.login_user_data_dict['username'],
        'password': user_src.login_user_data_dict['password'],
        'bank_id': user_src.login_user_data_dict['bank_id'],
        'bank_pay_pwd': bank_pwd,
        'role': user_src.login_user_data_dict['role'],
        'balance': str(balance), 'locked': 'false'}
    count = '0'
    user_src.login_user_data_dict['count'] = count
    data = user_src.register_dict
    if os.path.exists(data_file):
        flag, data = read_data(tag='data', path='user_data.json')
        if not flag:
            return flag, data
        data.update(user_src.register_dict)
    # 保存转账用户的数据
    flag, msg = save_data(path=f"user_data.json", tag='data', data=data)
    if not flag:
        return flag, msg
    init_bank_info(user_src.login_user_data_dict['username'])

user_interface

import os
from core import user_src
from db import save_data, read_data
from lib.common import get_pwd_md5, init_bank_info


def register_interface(username, password):
    if os.path.exists(user_src.data_file):
        flag, data = read_data(path='user_data.json', tag='data')
        if not flag:
            return flag, data
        if username in data:
            return False, '当前用户重复注册操作,注册失败'
    if not password.isdigit():
        return False, '用户输入的密码格式不正确,注册失败'
    if len(password) != 4:
        return False, '注册用户密码长度格式输入错误,注册失败(长度需求:4位)'
    if username == 'quan':
        role = 'admin'
    else:
        role = 'normal'
    user_src.login_user_data_dict['role'] = role
    user_src.register_dict[username] = {'username': username, 'password': get_pwd_md5(password),
                                        'bank_id': 'None',
                                        'bank_pay_pwd': 'None',
                                        'role': role, 'balance': 'None', 'locked': 'false'}
    data = user_src.register_dict
    if os.path.exists(user_src.data_file):
        flag, data = read_data(tag='data', path='user_data.json')
        if not flag:
            return flag, data
        data.update(user_src.register_dict)
    flag, data = save_data(path='user_data.json', data=data, tag='data')
    if not flag:
        return flag, data
    return True, f'{username}用户注册成功'


def login_interface(username, password):
    flag, data = read_data(path='user_data.json', tag='data')
    if not flag:
        return flag, data
    if not password.isdigit():
        return False, '用户密码格式输入错误,登陆失败'
    if len(password) != 4:
        return False, '用户输入的密码长度不满足需求(长度需求:4位)'
    if username not in data:  # or password != data.get(username)['password']:
        return False, f'用户不存在,登陆失败'
    password = get_pwd_md5(password)
    if username != data.get(username)['username'] or password != data.get(username)['password']:
        return False, f'你输入的用户名或者密码错误'
    # 冻结用户,判断是否被锁定
    if data[username]['locked'] != 'false':
        return False, '当前用户已锁定,需要联系管理员解锁'
    user_src.login_user_data_dict['username'] = username
    init_bank_info(username)
    return True, f'{username}用户登陆成功'

common

import hashlib
from core import user_src
from db import read_data


# 加密
#将密码加密,为了加密的程度,将加密的密码加了一个所谓的盐
def get_pwd_md5(password):
    salt = password
    md5_obj = hashlib.md5()
    res = salt + password
    md5_obj.update(res.encode('utf-8'))
    return md5_obj.hexdigest()


#根据全局字典进行初始化数据
def init_bank_info(username):
    flag, data = read_data(path='user_data.json', tag='data')
    if not flag:
        return flag, data
    # register_dict = data.get(username)
    user_src.login_user_data_dict['username'] = data.get(username)['username']
    user_src.login_user_data_dict['password'] = data[username]['password']
    user_src.login_user_data_dict['bank_id'] = data[username]['bank_id']
    user_src.login_user_data_dict['bank_pay_pwd'] = data[username]['bank_pay_pwd']
    user_src.login_user_data_dict['balance'] = data[username]['balance']
    user_src.login_user_data_dict['role'] = data[username]['role']
    user_src.login_user_data_dict['locked'] = data[username]['locked']


#主要由全局字典中的'locked'确认当前账户是否锁定,且添加了锁定账户的条件(三次)
def set_is_locked():
    if user_src.login_user_data_dict['locked'] == 'true':
        return False, '当前账户已锁定,请联系管理员解锁'

    if user_src.login_user_data_dict['count'] == '3':
        user_src.login_user_data_dict['locked'] = 'true'
        return False, '当前用户支付密码错误输入三次,账户已锁定,请联系管理员解锁'

#装饰器,确认除了登陆注册之外的其他操作是否经由登陆、激活银行卡操作,否则将无法操作除注册登陆以外的其他操作
def login_auth(func):
    def inner(*args, **kwargs):
        if not user_src.login_user_data_dict or user_src.login_user_data_dict['username'] == 'None':
            print('麻烦先登陆在执行当前操作')
            return False, ''
        if user_src.login_user_data_dict['bank_id'] == 'None' and func.__name__ != 'add_bank_info':
            print('麻烦先激活银行卡')
            return False, ''
        res = func(*args, **kwargs)
        return res

    return inner

start

from bin.main import *
if __name__ == '__main__':
    main()