python第二十五课---ATM购物车所有模块代码,及框架搭建等建议与注释

ATM购物车

1. 先把主要用到的文件夹在项目根目录下创建一下!!!

2. 再先把简单的几个常用的文件创建一下

bin start.py # 直接写,固定的
core src.py
conf settings.py
db db_handler.py
interface bank_interface shop_interface user_interface admin_interface
lib common.py

3. src里面先把各个功能函数用pass自定义出来,再把功能函数名对应的字典写出来,再把输入函数编号运行对应函数的几行代码写一下,src暂时写好了。

3.2 第一层 src里面只负责,用户输入,输出,及调用对应的接口函数,不负责逻辑判断

3.3 第二层 代码的的核心逻辑在对应的接口层

3.4 第三层 负责数据相关的操作,比如查询,写入的功能

3.5 settings里面放一些配置文件,比如创建创建db文件目录,提现手续费,日志配置字典等不会改变,很多功能可能会用的功能代码,配置里面一般是一些暂时不变的东西

3.6 common里面放一些装饰器函数,加密函数,判断输入的数字是否为存数字函数,日志器生成函数

4. 开始从src里面功能函数代码编写及对应接口文件代码编写,再调其他需要的函数,在接口层开始写核心逻辑代码,写到哪,需要什么,就导什么,再写要导的函数,一步一步来

5. src代码

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

is_login = {'username': ''}


def register():
    while True:
        username = input('输入用户名(q)>>:').strip()
        if username == 'q':
            break
        password = input('请输入密码>>:').strip()
        ag_password = input('请再次输入密码>>:').strip()
        if not password == ag_password:
            print('两次密码不一致,请重新输入')
            continue
        # 调用第二层,核心的注册功能函数
        flag, msg = user_interface.register_interface(username, password)
        if not flag:
            continue
        print(msg)


def login():
    while True:
        username = input('输入用户名(q)>>:').strip()
        if username == 'q':
            break
        password = input('请输入密码>>:').strip()
        # 调用第二层核心的登录函数
        flag, msg = user_interface.login_interface(username, password)
        print(msg)
        if not flag:
            continue
        else:
            is_login['username'] = username


@common.login_auth
def check_balance():
    username = is_login.get('username')
    # 直接调用第二层核心的查看余额的函数
    flag, msg = bank_interface.check_balance_interface(username)
    print(msg)


@common.login_auth
def withdraw():
    username = is_login.get('username')
    # 1.获取用户想要提现的具体金额即可
    target_money = input('请输入要提现的金额>>:').strip()
    # 2.直接调用提现接口函数
    flag, msg = bank_interface.withdraw_interface(username, target_money)
    print(msg)


@common.login_auth
def charge_money():
    username = is_login.get('username')
    # 1. 获取想要充值的金额即可
    target_money = input('请输入要充值的金额>>:').strip()
    # 2. 直接调用充值还款的接口函数
    flag, msg = bank_interface.charge_money_interface(username, target_money)
    print(msg)


@common.login_auth
def transfer():
    # 获取想要转账的金额及转账的人
    username = is_login['username']
    target_user = input('请输入要转账的人>>:').strip()
    target_money = input('请输入要转帐的金额>>:').strip()
    # 调用转账接口函数
    flag, msg = bank_interface.transfer_interface(username, target_user, target_money)
    print(msg)


@common.login_auth
def check_flow():
    username = is_login['username']
    flag, msg = bank_interface.check_flow_interface(username)
    if flag:
        for i in msg:
            print(i)
    else:
        print(msg)


@common.login_auth
def add_shop_car():
    username = is_login.get('username')
    flag, msg = shop_interface.add_shop_car_interface(username)
    print(msg)


@common.login_auth
def check_shop_car():
    # 1.直接调用查看购物车接口
    username = is_login.get('username')
    flag, msg = shop_interface.check_shop_car_interface(username)
    if flag:  # msg 拿到的是shop_car {'商品名称':[个数,单价]}
        for i, j in msg.items():
            print(f"商品:{i} | 商品个数:{j[0]} | 商品单价:{j[1]}")
    else:
        print(msg)


@common.login_auth
def pay_shop_car():
    username = is_login.get('username')
    flag, msg = shop_interface.pay_shop_car_interface(username)
    print(msg)


@common.login_auth
def admin():
    pass


func_dict = {
    '1': register,
    '2': login,
    '3': check_balance,
    '4': withdraw,
    '5': charge_money,
    '6': transfer,
    '7': check_flow,
    '8': add_shop_car,
    '9': check_shop_car,
    '10': pay_shop_car,
    '11': admin
}


def run():
    while True:
        print("""
        1.注册
        2.登陆
        3.查看余额
        4.提现
        5.充值还款
        6.转账
        7.查看流水
        8.添加购物车功能
        9.查看购物车功能
        10.结算购物车功能
        11.管理员功能
        """)
        func_n = input('请输入要执行的函数功能编号>>:').strip()
        if func_n in func_dict:
            func_dict.get(func_n)()
        else:
            print('您输入的编号不存在,请重新输入!!')


6. user_interface 代码

from db import db_handler
from lib import common


logger = common.get_logger('注册登录模块')

def register_interface(username, password):
    # 第一步判断用户名是否存在,调用查询函数
    res = db_handler.select(username)
    if res:  # 这个地方别弄反了!!!有返回值时,说明用户名已存在了,刚刚犯错了,多加了个not了
        return False, '用户名已存在,请重新注册!!!'
    # 第二步对密码加密)
    hash_pwd = common.get_hash(password)
    # 第三步定义用户字典
    user_dict = {
        'username': username,
        'password': hash_pwd,
        'balance': 800000,
        'shop_car': {},
        'is_lock': False,  # 这样拿到用户数据先判断这个键的值,如果是True,说账户被冻结!
        'bank_flow': []
    }
    # 第四步用户字典写入用户文件
    db_handler.save(user_dict)
    logger.info(f'{username}注册成功,ni_ma_dan_de!!!')
    return True, '注册成功'


def login_interface(username, password):
    # 判断用户名是否存在,调用查询函数
    user_dict = db_handler.select(username)  # 如果用户名存在,返回值就是用户字典
    if not user_dict:  # 如果用户名不存在,返回值就是None
        return False, '用户名不存在'
    # 对输入的密码加密
    hash_pwd = common.get_hash(password)
    # 判断加密后的密码是否正确
    if user_dict.get('password') == hash_pwd:
        logger.info(f'{username}登录成功,日志器鸟用没有!!!')
        return True, '登录成功'
    else:
        return False, '密码不正确'

.
.
.

7. bank_interface.py 代码

import time

from db import db_handler
from conf import settings
from lib import common

logger = common.get_logger('银行模块')


# 查看余额接口
def check_balance_interface(username):
    # 调用查询功能函数,拿到用户的字典数据
    user_dict = db_handler.select(username)
    user_balance = user_dict.get('balance')
    # 记录日志
    logger.debug(f'用户{username}查看了自己的账户余额,sb')
    return True, f'尊敬的{username},您目前的账户余额为{user_balance}'


# 提现接口
def withdraw_interface(username, target_money):
    # 先判断输入的是不是纯数字,isdigit不能判断带小数点的数字
    flag, value = common.get_num(target_money)
    if not flag:  # 如果flag为False,说明try句式监测到用户输入的有问题
        return False, '请输入符合要求的数字'
    # 如果输入的目标提现金额是数字类型,那么value接收到了转成浮点型的提现金额
    # 1.获取当前登录用户的字典数据
    user_dict = db_handler.select(username)
    # 2.获取用户余额并判断是否满足提现要求  还应该收取手续费!!!
    # 如果目前用户的余额大于等于,要提现的金额加上手续费,那么就直接扣就行了
    user_balance = user_dict.get('balance')
    if user_balance >= value * (1 + settings.MONEY_RATE):
        user_dict['balance'] -= value * (1 + settings.MONEY_RATE)
        # 扣完,用户字典添加账户流水信息
        ctime = time.strftime('%Y-%m-%d %H:%M:%S')
        user_dict['bank_flow'].append(
            f"时间{ctime}:账户提现了{value},收取了手续费{value * settings.MONEY_RATE},该阶段账户余额{user_dict['balance']}")
        db_handler.save(user_dict)  # 余额改完后,重新写入字典
        # 记录日志
        logger.debug(f'用户{username}提现了{value},cao')
        return True, f'尊敬的客户{username},您已经提现了{value},手续费{value * settings.MONEY_RATE},账户余额{user_dict.get("balance")}'
    else:
        return False, f'尊敬的客户{username}您的账户不够提现哦,请先充值!'



# 充值还款接口
def charge_money_interface(username, target_money):
    # 还是先判断输入的是不是纯数字,调用判断函数
    flag, value = common.get_num(target_money)
    if not flag:
        return False, '请输入符合要求的金额数字'
    # 获取用户字典数据,目标金额是数字的条件下,value接收到的就是转成浮点型的目标金额
    user_dict = db_handler.select(username)
    # 添加余额
    user_dict['balance'] += value
    # 添加流水记录
    ctime = time.strftime('%Y-%m-%d %H-%M-%S')
    user_dict['bank_flow'].append(f"时间{ctime}:账户充值了{value},该阶段账户余额{user_dict['balance']}")
    # 保存用户数据
    db_handler.save(user_dict)
    # 记录日志
    logger.debug(f"用户{username}充值了{value},该阶段账户余额{user_dict['balance']},sd")
    return True, f"尊敬的用户{username},您充值了{value},目前账户余额为{user_dict['balance']}"



# 转账接口
def transfer_interface(username,target_user,target_money):
    # 校验目标用户是否存在
    target_user_dict = db_handler.select(target_user)
    if not target_user_dict:
        return False, f'目标用户{target_user}不存在'
    # 再次校验用户输入的金额是否为纯数字,调用common里面的判断是否为数字的函数
    flag, value = common.get_num(target_money)
    if not flag:
        return False, '请输入符合要求的金额数字'
    # 符合金额为纯数字后,获取当前登录用户的数据
    current_user_dict = db_handler.select(username)
    # 判断当前用户余额是否充足
    if current_user_dict.get('balance') >= value:
        current_user_dict['balance'] -= value   # 用户自己账户扣钱
        # 记录账户扣钱的流水
        ctime = time.strftime('%Y-%m-%d %H:%M:%S')
        current_user_dict['bank_flow'].append(f"时间{ctime}:给{target_user}账户转了{value},现阶段余额{current_user_dict['balance']}")
        # 被转账用户账户加钱
        target_user_dict['balance'] += value
        # 记录加钱账户的流水
        target_user_dict['bank_flow'].append(f"时间{ctime}:收到{username}账户转过来的钱{value},现阶段余额{target_user_dict}")
        # 将被修改后的用户字典与目标用户字典重新写入对应的用户文件
        db_handler.save(current_user_dict)
        db_handler.save(target_user_dict)
        # 记录日志
        logger.debug(f'用户{username}您给{target_user}账户转了{value},终于会用日志了!干')
        # 最后返回信息给src
        return True, f"尊敬的用户{username},您给{target_user}账户转了{value},当前账户余额为{current_user_dict['balance']}"
    else:
        return False, '您当前的余额不够转账'



# 查看流水接口
def check_flow_interface(username):
    # 获取当前登录用户的数据
    user_dict = db_handler.select(username)
    if user_dict.get('bank_flow'):
        # 记录日志
        logger.debug(f'{username}查看了自己的流水记录,nimadan')
        return True, user_dict.get('bank_flow')
    else:
        return False, '该用户暂无流水记录'

.
.
.

8.shop_interface.py 代码

from db import db_handler
from lib import common
import time

logger = common.get_logger('购物车模块')


def add_shop_car_interface(username):
    temp_shop_car = {}  # {'商品名':[数量,价格]}
    while True:
        good_list = [
            ['挂壁面', 3],
            ['印度飞饼', 22],
            ['极品木瓜', 666],
            ['土耳其土豆', 999],
            ['伊拉克拌面', 1000],
            ['董卓戏张飞公仔', 2000],
            ['仿真玩偶', 10000]
        ]
        for i, j in enumerate(good_list):
            print(f'商品编号:{i}     |    商品名称:{j[0]}    |    商品价格:{j[1]}')
        good_id = input('请输入商品编号(q)>>:').strip()
        # 第三部分
        if good_id == 'q':
            # 打开用户文件,拿到老的shop_car
            user_dict = db_handler.select(username)
            old_shop_car = user_dict.get('shop_car')
            for i_name, j_list in temp_shop_car.items():
                if i_name in old_shop_car:
                    old_shop_car.get(i_name)[0] += j_list[0]
                else:
                    old_shop_car[i_name] = j_list
            user_dict['shop_car'] = old_shop_car
            # 写入用户文件
            db_handler.save(user_dict)
            # 记录日志
            logger.info(f'{username}用户添加购物车成功,fuck')
            return True, '添加购物车成功!!!'

        # 第二部分
        if not good_id.isdigit():
            print('请输入纯数字!!')
            continue
        good_id = int(good_id)
        if good_id not in range(len(good_list)):
            print('没有您要购买的商品编号,请重新选择编号')
            continue
        good_name = good_list[good_id][0]
        good_price = good_list[good_id][1]
        good_num = input('请输入该商品的购买数量').strip()
        if not good_num.isdigit():
            print('商品数量必须是纯数字')
            continue
        good_num = int(good_num)
        if good_name in temp_shop_car:  # 商品名在里面,就数量增加
            temp_shop_car.get(good_name)[0] += good_num
        else:  # 不在里面就将选购的{商品名称:[数量,价格]}加到临时字典里面去
            temp_shop_car[good_name] = [good_num, good_price]


def check_shop_car_interface(username):
    # 调用查询功能函数,获取当前登录用户的字典数据,获取当前用户购物车数据
    user_dict = db_handler.select(username)
    user_shop_car = user_dict.get('shop_car')
    if user_shop_car:   # 判断购物车是否为空,
        # 并加个日志记录
        logger.info(f'用户{username}查看了购物车数据,shit')
        return True, user_shop_car
    else:
        return False, '暂无购物车数据,感觉去选购吧'


def pay_shop_car_interface(username):
    # 调用查询功能函数,获取当前用户购物车数据及账户余额
    user_dict = db_handler.select(username)
    user_shop_car = user_dict.get('shop_car')
    current_balance = user_dict.get('balance')
    if not user_shop_car:
        return False, '购物车为空,赶紧选购吧'
    # 统计购物车商品总价
    total_money = 0
    for i in user_shop_car.values():
        total_money = total_money + i[0]*i[1]
    # 比较余额是否充足
    if total_money > current_balance:
        return False, '余额不足,请充值'
    else:
        user_dict['balance'] = current_balance

    # 添加账户流水信息到用户字典里的'bank_flow'值里面去
    ctime = time.strftime('%Y-%m-%d %X')
    user_dict['bank_flow'].append(f'时间{ctime}:购物消费了{total_money}')
    # 清空购物车
    user_dict['shop_car'] = {}
    # 记录日志
    logger.info(f'{username}疯狂消费了{total_money},bitch')
    # 再写入功能函数
    db_handler.save(user_dict)
    return True, f"本次消费{total_money},卡上余额{user_dict['balance']}欢迎下次再来!!"

.
.

9.db_handler.py 代码

import os
import json
from conf.settings import DB_DIR


# 用户查询
def select(username):
    user_file_path = os.path.join(DB_DIR, f'{username}.json')
    if os.path.isfile(user_file_path):
        with open(user_file_path, 'r', encoding='utf8')as f:
            return json.load(f)  # 有返回值说明用户名已经存在了
    # 用户名不存在,不会走if的代码,所以返回值为None!!!


# 用户写入
def save(user_dict):
    username = user_dict.get('username')
    user_file_path = os.path.join(DB_DIR, f'{username}.json')
    with open(user_file_path, 'w', encoding='utf8')as f:
        json.dump(user_dict, f, ensure_ascii=False)   # 涉及到汉字写入字典时要再加一个参数

.
.

10. common.py 代码

import hashlib
import logging
import logging.config
from conf import settings


# 加密功能
def get_hash(msg):
    md555 = hashlib.md5()
    md555.update(msg.encode('utf8'))
    hash_msg = md555.hexdigest()
    return hash_msg


# 装饰器
def login_auth(func):
    def inner(*args, **kwargs):
        from core import src
        if src.is_login:
            res = func(*args, **kwargs)
            return res
        else:
            print('您还未登录,请先登录')
            src.login()

    return inner


# 判断输入的钱是否为纯数字
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(settings.LOGGING_DIC)  # 自动加载字典中的配置
    logger1 = logging.getLogger(msg)
    return logger1

.

11. admin 代码编写注意事项

用户字典里面首先要加个判断是不是管理员的键值对
'is_admin': False

冻结操作:
用了冻结功能,原来函数有几个地方要改一下:
---------------------------------------------------------------------
第一个注册接口函数里面,用户字典里面,要有一个标记用户是否被冻结的键值对'is_lock': False
---------------------------------------------------------------------
第二个登录接口函数里面,再用户密码比对正确后,还要再加一个判断,判断用户是否被冻结
并且返回值那边要多返回一个用户是不是管理员的信息!!!这是关键!!!
        if user_dict['is_lock']: # 多一个判断is_lock的值是什么!!!
            return False, '该账号已被锁定 请联系管理员Jason'  # 如果判断出被锁定了,就直接结束!!!
        else:
            logger.debug(f'用户{username},登录成功')
            return True, ('登录成功!!!', user_dict.get('is_admin'))
--------------------------------------------------------------------------
第三个原来src里面的登录成功后,原来全局变量只有一个用户名,现在也要再加一个
        if flag:
            is_login['username'] = username
            is_login['is_admin'] = msg[1]
            print(msg[0])
 # 这个因为msg接收到的是('登录成功!!!', user_dict.get('is_admin'))
        else:
            print(msg)
            continue
------------------------------------------------------------------------
整体大致思路:

src里面的admin函数先打印出可以操作的功能,根据编号,调用对应的接口函数
比如选择冻结功能,先要调一个获取db文件目录下所有用户名列表的函数:
该函数就一个作用,调用第三层的函数拿到用户名的列表,并返回出去!!!
def get_username_list():
    file_name_list = db_handler.get_file_names()
    return True, file_name_list
---------------------------------------------------------------
因为涉及到文件的操作,所以获取db文件目录下所有用户名列表的函数,在db_handler里面
# 对文件的操作尽量都放在db_handler文件里面,所以这定义了一个获得文件目录下所有文件名称的功能函数
# 获得文件目录下所有文件名称功能
def get_file_names():
    data_list = os.listdir(DB_DIR)  # 先拿到db目录下的所有文件名称
    file_list = [data.split('.')[0] for data in data_list if data.endswith('.json')]  # 再筛选出具有.json结尾的文件名
    return file_list
# 当然这个自定函数还可以将 目录名称DB_DIR 与 文件后缀名.json 不要写死,这样就可以对任意的文件目录里面所有想要的的一类文件名的功能了!!!
# 目录名称与文件后缀名 用两个形参代替,这样在函数调用阶段,往里面传什么文件目录,及什么文件名后缀,就能拿到该文件目录里面对应后缀名的文件名了!!!
-----------------------------------------------------------------------------
这样admin函数里面:
	   elif func_n == '1':
            flag, user_name_list = admin_interface.get_username_list()
            user_name_list = [i for i in user_name_list if i != username]  # 筛掉管理员自己,不等于自己的保留下来
            for i, j in enumerate(user_name_list):     # 再枚举打印一下,供管理员选择想冻结谁
                print(f"编号:{i}    |   用户名:{j}")
            username_id = input('请输入对应的用户编号').strip()
            # 一系列小判断.isdigit() 及判断输入编号超没超范围等
            username_id = int(username_id)  # 字符串转一下整型
            target_lock_username = user_name_list[username_id]  # 索引获取用户名
            # 调用管理员接口冻结账户
            flag, msg = admin_interface.lock_user_interface(username, target_lock_username)
            print(msg)
-----------------------------------------------------------------------------
def lock_user_interface(username, target_lock_username):
    user_dict = db_handler.select(target_lock_username)  # 调用被冻结用户的用户字典
    user_dict['is_lock'] = True  # 改下键值对
    db_handler.save(user_dict)  # 再存进去
    logger.error(f'管理员{username}冻结了{target_lock_username}账户')  # 再记个日志
    return True, f'{target_lock_username}账户已被冻结'  # 最后return一下信息

------------------------------------------------------------------------


思考:
首先admin功能要考虑的点是,只有及少部分的人是管理员,admin里面的功能很强大,不可能让其他人运行该函数体代码的,所以如何记录谁是admin,谁是普通用户?
最简单的方法是在创建用户时,在用户字典里面再加一个键值对'is_admin':False,用来记录用户是不是管理员,默认是False。当想要让该用户成为管理员的时候就将False改为True就行了。
这样每个注册的人身上就多了一个标志了,标志了是否是管理员了!!!
user_dict = {
        'username': username,
        'password': hash_pwd,
        'balance': 800000,
        'shop_car': {},
        'is_lock': False,  # 拿到用户数据先判断这个键的值,如果是True,说明账户被冻结!
        'bank_flow': []
        'is_admin':False  # 默认所有人都不是管理员
    }


-----------------------------------------------------------------------------

再考虑src里面admin函数的运行,必须首先要是登录的账户,其次还要是管理员才行。
所以,首先将原来的无参装饰器升级为有参装饰器:原来装饰器的作用是判断用户的登录状态,如果用户没登陆,就没执行相关函数的功能
现在想要在用户执行admin函数时,不仅要判断用户有没有登录,还要判断用户是不是管理员
在原来无参装饰器的基础上,改为有参装饰器,原装饰器内部又多了一层判断,先判断传进来的可运行该被装饰函数的用户类型,如果是普通用户类型,只要登录了就可以运行被装饰的函数,但是如果传进来的可运行函数的用户类型是管理员用户,那么不仅要是登录状态,还要判断全局变量里面'is_admin'的对应的值是不是True,如果不是True则无权执行被装饰的函数
当然了,还有一种简单的办法,就是原来装饰器的代码不改,直接在src里面的admin函数体里面,直接先进行一个判断,全局变量里面'is_admin'的对应的值是不是True,如果不是True,直接return结束告诉用户无权运行该函数,这里只是为了练习一下有参装饰器,故意采用这种复杂的方式的!!!
def outer(type):   # 传一个被装饰函数需要的用户类型
    def login_auth(func_name):
        def inner(*args, **kwargs):
            if src.is_login.get('username'):
                if type == 'normal':    # 判断用户类型
                    res = func_name(*args, **kwargs)
                    return res
                elif type == 'admin':    # 再判断用户类型
                    if src.is_login.get('is_admin'):  # 判断全局变量里面的'is_admin'的值,是True才能运行被装饰函数。
                        res = func_name(*args, **kwargs)
                        return res
                    else:
                        print('您不是管理员 没有执行权限')
            else:
                print('您暂未登录 请先去登录')
                src.login()

        return inner
    return login_auth

------------------------------------------------------------------------
这样一改原来的装饰器语法糖全部改成有参装饰器语法糖@outer('normal'),普通函数都装这个,admin函数装@outer('admin'),这样装饰器就ok了
--------------------------------------------------------------------------
再考虑是不是应该在用户登录成功后,
在src里面改全局变量is_login = {'username':'''is_admin':''}  中的'username'的值的同时,也要改一下'is_admin'对应的状态。它们改is_login里面的状态都是基于用户字典里面原来存的数据来改的!!!
--------------------------------------------------------------------------
在登录的接口函数里面原来登录成功后代码是这样的:
return True'登录成功'
这样在src里面msg只能接收到的返回值是'登录成功'看不到是不是管理员的信息,所以可以把代码改成这样return True, ('登录成功',user_dict.get('is_damin'))
这样msg就同时拿到了登录成功的信息,及是否是管理员的信息了!!!
这样原来的src里面的login里面的打印代码:
 print(msg)
        if not flag:
            continue
        else:
            is_login['username'] = username
---------------------------------------------------------------------------
就要改成了:因为在flag为false时,msg只接收到一个信息,flag为true时,msg接收到了一个元组,索引想打印信息就要打印msg[0]了!!!!
		if not flag:
			print(msg)
			continue
        else:
			print(msg[0])
			is_login['username'] = username
			is_login['is_admin'] = msg[1]
-----------------------------------------------------------------------------
src里面编写admin函数代码
def admin():
	while True:
		print("""
		1.冻结功能
		2.删除账户
		3.修改密码
		4.充值账户
		""")
		func_n = input('请输入要执行的功能编号>>:').strip()
		if func_n == 'q':
			break
		if func_n == '1':
------------------------------------------
			# 可以将项目中所有的用户名展示给管理员选择
			# 就要将db文件夹下所有是.json的文件夹给弄出来,可以在admin_interface里面再弄一个能得出.json文件名的函数比如:
def get_username_list():
    data_list = os.listdir(settings.DB_DIR)  # 先拿到db目录下的所有文件名称
    file_name_list =
				[i.split('.')[0] for i in data_list if i.endswith('.json')]
	# 再筛选出具有.json结尾的文件名,再用split切割小点子,根据索引拿到用户名了
	return True, file_name_list
--------------------------------------------
			flag,user_name_list = admin_interface.get_username_list()
			# 这样在src admin里面就可拿到所有的用户名了
			'''管理员不可以操作自己 可以借助于全局变量is_login做筛选判断,筛掉管理员自己的用户名'''
			user_name_list = [name for name in user_name_list if name != is_login.get('username')]
			for i, name in enumerate(user_name_list):   # 枚举打印
				print(f'用户编号:{i}    |   用户名:{name}')
				user_num= input('请选择想要冻结的账户编号>>>:').strip()
				# 一系列小判断
				# 获取用户名
				user_num = int(user_num)
				target_lock_username = user_name_list[user_num]
				# 调用管理员接口冻结账户
				flag, msg =
admin_interface.lock_user_interface(is_login.get('username'),target_lock_username)  # 传了一个管理员的名字与一个要冻结的用户的名字
				print(msg)
		elif func_n == '2':
			pass
		elif func_n == '3':
			pass
		elif func_n == '4':
			pass
		else:
			print('暂无该功能,敬请期待!!')

---------------------------------------------------------------------------
再写一个冻结用户的账号的接口函数
def lock_user_interface(admin_name,lock_name):
	user_dict = db_handler.select(lock_username)  # 调用被冻结用户的用户字典
    user_dict['is_lock'] = True                   # 改下键值对
    db_handler.save(user_dict)                    # 再存进去
    logger.error(f'管理员{admin_name}冻结了{lock_username}账户')   # 再记个日志
    return True, f'{lock_username}账户已被冻结'   # 最后return一下信息

---------------------------------------------------------------------------
最后还有一个地方要改一下:就是登录的接口里面还要再加一个判断,判断用户有没有被冻结。
原函数为:
def login_interface(username, password):
    # 判断用户名是否存在,调用查询函数
    user_dict = db_handler.select(username)  # 如果用户名存在,返回值就是用户字典
    if not user_dict:  # 如果用户名不存在,返回值就是None
        return False, '用户名不存在'
    # 对输入的密码加密
    hash_pwd = common.get_hash(password)
    # 判断加密后的密码是否正确
	if user_dict.get('password') == hash_pwd:
			if user_dict.get(is_lock)    # 再加一行判断
				return False'该账户已被冻结,请练习管理员'
			logger.info(f'{username}登录成功,日志器鸟用没有!!!')
			return True, ('登录成功',user_dict.get(is_admin)
	else:
		return False'密码不正确'
---------------------------------------------------------------------------




.

12.代码编写注意事项:

银行的功能里面: 提现,转账,充值,这3个功能操作成功要记一个银行流水信息,添加到用户的字典里面的对应的银行流水里面。

.

提现接口函数代码 编写流程:

提现接口函数代码编写流程:先调用判断输入目标金额判断是不是纯数字的函数,该函数的利用的异常捕获,try句式。
try:
	target-money = float(target-money) 
except Expection:
	return False'输入的不是纯数字'
elsereturn True,target-money
拿到该函数的返回值flag与value
拿到用户字典,拿到用户余额user_balance = user_dict.get('balance')
判断用户余额是否大于等于(要提现的金额加上提现的费率),如果大于,直接扣
if user_balance >= value*(1+settings.MONEY_RATE):
	user_dict['balance'] -= value*(1+settings.MONEY_RATE)
	db_handler.save(user_dict)  # 余额改完后,重新写入字典
	扣完记流水添加到用户字典里面的bank_flow
	ctime = time.strftime('%Y-%m-%d %H:%M:%S')
	 user_dict['bank_flow'].append(
            f"时间{ctime}:账户提现了{value},收取了手续费{value * settings.MONEY_RATE},该阶段账户余额{user_dict['balance']}")
	再记录日志logger.info('123456789dsdsssf')
	return Truef"{username}提现了{value},手续费{value*settings.MONEY_RATE},账户余额{user_dict['balance']}"
elsereturn False'您的账户余额不足,无法体现您想要的金额,请充值'

再到src接收该接口函数的返回值,
flag,msg = bank_interface.withdraw_interface(username,target-money)
print(msg)

提现所有的操作都结束了

.

充值还款接口函数代码 编写流程:

还是先调用判断输入目标金额是不是纯数字的函数,该函数的利用的异常捕获,try句式。
try:
	target-money = float(target-money)   # 作用是将输入字符串转成浮点型
except Expection:
	return False'输入的不是纯数字'
elsereturn True,target-money
用flag与value接收返回值
 flag, value = common.get_num(target_money)
    if not flag:
        return False, '请输入符合要求的金额数字'
# 充值功能还是先获取用户字典,及账户余额,
	 user_dict = db_handler.select(username)
	 user_dict['balance'] += value   # 直接在原有的余额基础上加
	 db_handler.save(user_dict)      # 再写入字典
	# 添加流水
	ctime = time.strftime(%Y-%m-%d %H:%M:%S)
	user_dict.get('bank_flow').append(f"时间{ctime}:用户{usernaem},充值了{value},当前账户余额{user_dict['balance']}")
	# 添加日志记录
	logger.debug(f"用户{usernaem},充值了{value},当前账户余额{user_dict['balance']})
	return True,f"尊敬的用户{username},您充值了{value},目前账户余额为{user_dict['balance']}"


这样 充值功能的代码就写好了

.

转账还款接口函数代码 编写流程:

转账记住要传3个参,转账人的用户名,目标用户的用户名,及要转账金额,所以第一层src里面调用句式如下:
flag, msg = bank_interface.transfer_interface(username,target_user,target_money)

接口里面:
还是先调用判断输入目标金额是不是纯数字的函数,该函数的利用的异常捕获,try句式。
try:
	target-money = float(target-money)   # 作用是将输入字符串转成浮点型
except Expection:
	return False'输入的不是纯数字'
elsereturn True,target-money
用flag与value接收返回值
 flag, value = common.get_num(target_money)
    if not flag:
        return False, '请输入符合要求的金额数字'
	# 先判断被转账的用户的用户名是否存在,
	target_user_dict = db_handler.select(target_user)
	if not user_dict:
		return False'您要转账的用户名步存在'
	# 再判断当前账户的余额够不够转账的金额
	# 还是先拿用户字典及余额
	user_dict = db_handler.select(username)
	if user_dict['balance'] >= value:
		user_dict['balance'] -= value    # 余额大于转账的钱,就直接扣用户余额
		# 记录用户流水
		ctime = time.strftime(%Y-%m-%d %H:%M:%S)
		user_dict['bank_flow'].append(f"时间{ctime}:用户{username},转了{value},当前账户余额为{user_dict['balance']}")
		target_user_dict['balance'] += value  # 被转的的人账户加钱
		记录被转用户流水
		target_user_dict['bank_flow'].append(f"时间{ctime}:用户{username},给你转了{value},您当前账户余额为{target_user_dict['balance']}")
		# 把用户与被转用户账户余额更改后的字典再重新写入用户文件
		db_handler.save(user_dict)
		db_handler.save(target_user_dict)
		# 记录一个日志
		logger.debug(f"用户{username},给{target_user},转了{value}")
		return Truef"尊敬的用户{username},您转了{value},当前账户余额为{user_dict['balance']}
	else:
		return False,'您当前的余额不够转账'

这样转账功能就写好了
posted @   tengyifan  阅读(44)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
点击右上角即可分享
微信分享提示