项目1:ATM+购物商城项目
项目1:ATM+购物商城
1、项目介绍
项目需求:
# 项目需求如下:'''- 额度 15000或自定义- 实现购物商城,买东西加入购物车,调用信用卡接口结账- 可以提现,手续费5%- 支持多账户登录- 支持账户间转账- 记录每月日常消费流水- 提供还款接口- ATM记录操作日志 - 提供管理接口,包括修改用户额度,冻结账户解锁账户等...- 用户认证功能'''
需求分析:
''' - 额度15000或自定义: ----> 1、注册功能,信用卡额度15000或自定义 - 实现购物商城,买东西加入购物车,调用信用卡接口结账 ---> 2、购物车功能 , 3、支付功能- 可以提现,手续费5%: ---> 4、提现功能- 支持多个账户登录: ----> 5、登录功能- 支持账户间转账: ----> 6、转账功能- 记录日常消费流水: ----> 7、记录流水功能- 提供还款接口: ----> 8、还款功能- ATM记录操作日志: ----> 9、日志功能- 提供管理接口,包括修改用户额度,冻结账户解锁账户等 ----> 10、管理员功能- 用户认证: -----> 11、登录认证装饰器'''
架构设计:
在写程序之前不是一拿到项目需求想到哪就写到哪。假设你的程序有成千上万个功能,你都把他们写在一个文件里面。还有用户输入、逻辑处理、数据存储都写在一个函数里,会导致你的代码结构及其不清晰。而是应该对程序进行设计,设计出一种最优的程序架构! 这样做会有什么好处:
1、思路清晰
2、不会出现写到一半的时候推翻重写
3、方便自己或以后同事的维护
本项目架构设计为三层架构,这个架构为何要这样设计呢?有何好处:
1 、把每个功能都分成三个部分,逻辑清楚
2 、如果要改用户的数据展示,或者换存储机制,只需动单独一个模块就可以了,扩展性强
3 、为什么把日志模块放在接口层,因为所有的交互都会经过接口层,方便记录

目录设计:
'''- ATM - conf 配置文件文件夹 - setting.py - lib 公共方法文件夹 - common.py 公共方法文件 - interface 接口层文件夹 - user.py 用户接口文件 - shop.py 购物接口文件 - bank.py 银行接口文件 - core 用户功能文件夹 - src.py 视图文件 - db 数据处理层文件夹 - db_handler.py 数据处理功能文件 - log 日志存放目录 - start.py 程序的入口文件,启动文件 - readme 程序的说明文件'''
2、项目详解
1、程序入口
从入口文件开始写在start.py,这里是我们程序的入口,我们要运行程序,从这里开始,通过这里到到达用户功能层。
import os, sys
# 找到当前项目所在位置
path = os.path.dirname(__file__)
# 项目目录加入到环境变量中
sys.path.append(path)
# 导入用户功能层中的src.py文件
from core import src
if __name__=="__main__":
# 执行src中的run方法启动程序
src.run()
start.py
2、注册功能
1、从start.py进入到在core的src.py(用户功能层)中,我们再run方法中列出我们所有的功能,编号与func_dic字典中键对应,值是函数地址,用户输入以后调用register方法。
2、在register方法中接收用户输入的用户名,密码,重复密码,如果两次密码不一致,则从新输入,如果一致则调用interface文件中user——interface.py文件中register_interface(, password, balance = 15000)方法(接口层),等待接口层返回,如果返回True这注册成功,如果返回False则展示错误信息,重新注册。
3、 在 register_interface(name, password, balance = 15000)注册接口中调用db文件夹中的db_handler.select(name)(数据处理层),接收数据,如果有该用户的信息怎么返回False,'用户已存在'给用户功能层的register方法。如果不存在则db文件夹中的db_handler.save(dic)(数据处理层)方法,保存用户信息。并返回True,'注册成功'。
4、 db文件夹中的db_handler.save(dic)(数据处理层),将以用户的用户名为文件名,将用户信息转化为json数据存储。db文件夹中的db_handler.select(name)(数据处理层)返回用户信息已字典的形式。
3、登录功能
1、在src.py(用户功能层)的run方法中添加“ 登入” 在func_dic添加login,然后实现login,就可以了,我们把上面的run方法写好以后,要添加新的功能是不是特别简单。
2、我们在src.py(用户功能层)中实现login方法,在login函数中接收用户输入的用户名和密码后,后调用interface中的user.login_interface(name,password)(接口层),等待接口层返回,如果返回True这将用户名存到user_dic={'name':None}中,作为保存登入状态,如果返回False则登入失败,显示失败原因。
3、在interface文件夹中的user.login_interface(name,password)(接口层)方法中,调用db文件夹中的db_handler.select(name)(数据处理层)方法,如果数据不存在则返回False,"用户不存在",如果有数据则判断取出的数据是否和用户输入的密码是否一致且用户没有被锁定。如果一致且没有没有被锁定,则返回True,"登入成功",反之返回False,"密码错误或用户被锁定"。
4、用户认证
后续的功能我们要保证用户只有在登入的状态下才能使用,如果用户没有登入就让用户登入。那我们如何保证只有登入才能使用,不然跳转到登入,我们用装饰器实现
5、查看余额
1、在src.py(用户功能层)的run方法中添加“ 查看流水” 在func_dic添加check_balance,然后实现check_balance就可以了。
2、在check_balance方法上加登入认证装饰器,保证用户是登入状态。
3、在src.py(用户功能层)check_balance方法中调用interface文件夹下的bank.check_balance_interface(user_dic['name'])方法,(接口层,因为这里和钱相关我们把这个接口写在了bank文件中),获取用户的余额,并打印。
4、在interface文件夹下的bank文件中check_balance_interface方法调用db文件夹下的db_handle文件中的selec方法,获取用户的信息,并返回用户的余额。
6、转账功能
1、在src.py(用户功能层)的run方法中添加“ 转账” 在func_dic添加transfer,然后实现transfer就可以了。
2、在transfer方法上加登入认证装饰器,保证用户是登入状态。
3、接收用户输入的要转账的用户名以及金额,并保证用户输入的金额为数字。
4、在src.py(用户功能层)transfer方法中调用interface文件夹下的
bank.transfer_interface(user_dic['name'],to_user,account)方法,(接口层,因为这里和钱相关我们把这个接口写在了bank文件中),等待接口返回数据,如果返回False则失败并打印错误原因。如果返回True则转账成功。
5、在interface文件夹下的bank文件中transfer_interface(from_name,to_name,account)方法调用db文件夹下的db_handle文件中的selec方法,获取to_name用户的信息,如果没有则返回False,"要转账的用户不存在",如果存在,则调用db文件夹下的db_handle文件中的selec方法,获取from_name用户的信息,判断要转账的金额是不是大于当前会员的余额,如果大于则返回False,"余额不足",如果余额充足,将扣减当前用户的余额,增加to_name用户的余额,并将流水记入到两个用户的信息中,然后做用户信息的保存,并返回True,"转账成功"。
7、还款功能
1、在src.py(用户功能层)的run方法中添加“转账”在func_dic添加repay,然后实现repay就可以了。
2、在repay方法上加登入认证装饰器,保证用户是登入状态
3、接收用户输入的要还款的金额,并保证用户输入的金额为数字,
4、在src.py(用户功能层)transfer方法中调用interface文件夹下的bank.bank.repay_interface(user_dic['name'],account)方法,(接口层,因为这里和钱相关我们把这个接口写在了bank文件中),等待接口返回数据,如果返回False则失败并打印错误原因。如果返回True则还款成功。
5、在interface文件夹下的bank文件中repay_interface(user_dic['name'],account)方法调用db文件夹下的db_handle文件中的selec方法,获取user_dic['name']用户的信息,增加user_dic['name']用户的余额,并将流水记入到该用户的信息中,然后做用户信息的保存,并返回True,"还款成功"。
8、提现功能
1、在src.py(用户功能层)的run方法中添加“ 取款” 在func_dic添加withdraw,然后实现withdraw就可以了。
2、在withdraw方法上加登入认证装饰器,保证用户是登入状态。
3、接收用户输入的要取款的金额,并保证用户输入的金额为数字。
4、在src.py(用户功能层)transfer方法中调用interface文件夹下的bank.withdraw_interface(user_dic['name'],account)方法,(接口层,因为这里和钱相关我们把这个接口写在了bank文件中),等待接口返回数据,如果返回False则失败并打印错误原因。如果返回True则取款成功。
5、在interface文件夹下的bank文件中withdraw_interface(user_dic['name'],account)方法调用db文件夹下的db_handle文件中的selec方法,获取user_dic['name']用户的信息,查看user_dic['name']用户的余额,如果取款金额乘1.05后,大于用户余额,则返回False,'余额不足',若不大于余额,这扣减用户的余额,并将流水记入到该用户的信息中,然后做用户信息的保存,并返回True,"取款成功"。
9、查看流水功能
1、在src.py(用户功能层)的run方法中添加“ 取款” 在func_dic添加check_records,然后实现check_records就可以了
2、在check_records方法上加登入认证装饰器,保证用户是登入状态。
3、在src.py(用户功能层)transfer方法中调用interface文件夹下的bank.check_records_interface(user_dic['name'])方法,(接口层,因为这里和钱相关我们把这个接口写在了bank文件中),等待接口返回数据,如果返回False则失败并打印错误原因。如果返回True则取款成功。
4、在interface文件夹下的bank文件中check_records_interface(user_dic['name'],account)方法调用db文件夹下的db_handle文件中的selec方法,获取user_dic['name']用户的流水信息并返回
10、购物车功能
1、在src.py(用户功能层)的run方法中添加“ 取款” 在func_dic添加shopping,然后实现shopping就可以了。
2、在shopping方法上加登入认证装饰器,保证用户是登入状态。
3、在src.py(用户功能层)transfer方法中调用interface文件夹下的bank.check_balance_interface(user_dic['name'])方法,(接口层,因为这里和钱相关我们把这个接口写在了bank文件中),等待接口返回的用户余额,打印商品列表,等待用户输入要购买的商品编号,将商品名称,价钱,数量加入到shoppingcart字典中,计算购车中所有商品所需的金额,如果大于用户余额,则添加失败,如果小与则添加成功,当用户输入q的时候结束购买,调用调用interface文件夹下的shop.shoping_interface(user_dic['name'],cost,shoppingcart)方法,(接口层,因为这里和购物相关我们把这个接口写在了shop文件中)等待返回结果并展示。
4、在interface文件夹下的shop文件中shoping_interface(name,cost,shoppingcart)调用在interface文件夹下的bank文件中的consume_interface(name,cost)(因为和钱相关我们写到bank文件中)方法,该方法中调用db文件夹下的db_handle文件中的selec方法,获取user_dic['name']用户的流水信息对金额判断,如果余额充足,则扣减金额,记录日志,如果成功则返回True。在shoping_interface方法中将购物车的信息保存在用户的信息中,返回购买成功,如果consume_interface中发现金额不足则返回False,在shoping_interface方法将返回购买成功。
11、查看购物车
1、在src.py(用户功能层)的run方法中添加“ 查看购物车” 在func_dic添加check_shoppingcard,然后实现check_shoppingcard,就可以了。
2、在check_shoppingcard方法上加登入认证装饰器,保证用户是登入状态。
3、在src.py(用户功能层)transfer方法中调用interface文件夹下的shop.check_shopingcart_interface(user_dic['name'])方法,(接口层,因为这里和购物相关我们把这个接口写在了shop文件中),等待接口返回数据,展示数据。
4、在interface文件夹下的shop文件中check_shopingcart_interface(user_dic['name'])方法调用db文件夹下的db_handle文件中的selec方法,获取user_dic['name']用户的购物车信息并返回。
12、日志功能
1、conf文件夹中的setting文件中配置日志。
2、在lib文件夹的common文件中生成日志对象。
3、在需要调用的地方,直接获取日志对象,生成日志。
4、后续要用直接传入名字,生成不同的名字即可。
13、注销功能
直接将user字典中的名字变为None就可以了
14、管理员功能
1、在src.py中写出三个功能,冻结用户、解锁用户、修改额度,并生成管理员字典将这三个功能存入,在管理员功能里调用对应的功能即可
2、在admin_interface接口层写出对应的功能接口,冻结和解锁用户将用户字典里lock改为True或False即可,修改额度将用户字典里的balance修改即可
3、项目代码
from interface import user_interface
from lib import common
from interface import bank_interface
from interface import shop_interface
from interface import admin_interface
user_info = {'user': None}
# 注册功能
def register():
while True:
name = input('请输入用户名').strip()
msg = user_interface.check_user_interface(name)
if msg:
print('用户名已存在')
continue
pwd = input('请输入密码').strip()
pwd2 = input('请确认密码').strip()
if pwd == pwd2:
flag, msg = user_interface.register_interface(name, pwd)
if flag:
print(msg)
break
else:
print('两次密码不一样')
# 登录功能
def login():
while True:
username = input('请输入用户名:').strip()
msg = user_interface.check_user_interface(username)
if not msg:
print('输入用户名不存在')
continue
pwd = input('请输入密码:').strip()
flag, msg = user_interface.login_interface(username, pwd)
if flag:
user_info['user'] = username
print(msg)
break
else:
print(msg)
# 查看余额功能
@common.login_auth
def check_balance():
msg = bank_interface.check_balance_interface(user_info.get('user'))
print(f'余额为{msg}')
# 提现功能
@common.login_auth
def withdraw():
while True:
money = input('请输入提现金额:')
if not money.isdigit():
print('请输入数字金额')
continue
money = eval(money)
flag, msg = bank_interface.withdraw_interface(user_info.get('user'), money)
if flag:
print(msg)
break
else:
print(msg)
# 转账功能
@common.login_auth
def transfer():
while True:
to_transfer = input('请输入转向的用户:').strip()
flag = user_interface.check_user_interface(to_transfer)
if not flag:
print('输入用户不存在')
continue
if user_info['user'] == to_transfer:
print('不能向自己转账')
continue
money = input('请输入转账金额:').strip()
if money.isdigit():
money = eval(money)
flag, msg = bank_interface.transfer_interface(user_info['user'], to_transfer, money)
if flag:
print(msg)
break
else:
print(msg)
continue
else:
print('请输入整数金额!')
# 还款功能
@common.login_auth
def repay():
money = input('请输入还款金额').strip()
if money.isdigit():
money = eval(money)
msg = bank_interface.repay_interface(user_info['user'], money)
print(msg)
else:
print('请输入整数金额!')
# 查看流水功能
@common.login_auth
def check_flow():
msg = bank_interface.check_flow_interface(user_info['user'])
for i in msg:
print(i)
# 购物功能
@common.login_auth
def shopping():
good_list = [
['奔驰', 150],
['宝马', 200],
['路虎', 100],
['保时捷', 1000],
['飞机', 20000],
]
shop_car = {}
cost = 0
while True:
for index, good_info in enumerate(good_list):
good_name, good_price = good_info
print(f'商品编号:{index} 商品名称:{good_name} 商品价格:{good_price}')
choice = input('请输入商品编号或输入q进行结账:').strip()
if choice.isdigit():
choice = int(choice)
if choice in range(len(good_list)):
good_name, good_price = good_list[choice]
if good_name in shop_car:
shop_car[good_name] += 1
else:
shop_car[good_name] = 1
cost += good_price
else:
print('请输入正确编号')
else:
if choice == 'q':
res = input('请输入y结账或输任意键退出').strip()
if res == 'y':
flag, msg = shop_interface.shop_pay_interface(user_info['user'], cost)
if flag:
print(msg)
break
else:
print(msg)
continue
else:
msg = shop_interface.add_shop_car(user_info['user'], shop_car)
print(msg)
break
# 查看购物车功能
@common.login_auth
def check_shop_car():
msg = shop_interface.check_shop_car_interface(user_info['user'])
if msg:
print(msg)
else:
print('你的购物车是空的')
# 注销登录功能
@common.login_auth
def logout():
user_info['user'] = None
print('用户已注销登录')
# 冻结账户功能
def lock_user():
while True:
lock_name = input('请输入锁定的用户名').strip()
msg = user_interface.check_user_interface(lock_name)
if not msg:
print('用户不存在')
continue
else:
res = admin_interface.lock_user_interface(lock_name)
print(res)
break
# 解锁账户功能
def unlock_user():
while True:
unlock_name = input('请输入解锁的用户名').strip()
msg = user_interface.check_user_interface(unlock_name)
if not msg:
print('用户不存在')
continue
else:
res = admin_interface.unlock_user_interface(unlock_name)
print(res)
break
# 修改额度功能
def change_limit():
while True:
change_limit_name = input('请输入额度的用户名').strip()
msg = user_interface.check_user_interface(change_limit_name)
if not msg:
print('用户不存在')
continue
else:
limit = input('请输入修改的额度是:').strip()
if limit.isdigit():
limit = eval(limit)
res = admin_interface.change_limit_interface(change_limit_name, limit)
print(res)
break
else:
print('请输入整数金额')
admin_dic = {
': lock_user,
': unlock_user,
': change_limit
}
# 管理员功能
@common.login_auth
def admin():
while True:
print('''
1.冻结账户
2.解锁账户
3.修改用户额度
''')
choice = input('请输入功能编号')
if choice in admin_dic:
admin_dic[choice]()
break
else:
print('请输入正确的编号')
user_func_dic = {
': register,
': login,
': check_balance,
': withdraw,
': transfer,
': repay,
': check_flow,
': shopping,
': check_shop_car,
': logout,
': admin,
}
def run():
while True:
print('''
1.注册
2.登录
3.查看余额
4.提现
5.转账
6.还款
7.查看流水
8.购物
9.查看购物车
10.注销登录
11.管理员
12.退出程序
''')
choice = input('请输入功能编号:').strip()
':
break
if choice in user_func_dic:
user_func_dic[choice]()
else:
print('请输入正确的功能编号')
src.py
from db import db_handler
from lib import common
logger = common.get_logger('user')
# 查看用户接口
def check_user_interface(name):
user_dic = db_handler.select(name)
return user_dic
# 注册接口
def register_interface(name,pwd,balance=30000):
pwd = common.md5_pwd(pwd)
user_dic = {'username': name,
'pwd': pwd,
'flow': [],
'balance': balance,
'shop_car': {},
'lock': False
}
db_handler.save(user_dic)
logger.info(f'{name}用户注册成功')
return True, f'{name}用户注册成功'
# 登录接口
def login_interface(username, pwd):
pwd = common.md5_pwd(pwd)
user_dic = db_handler.select(username)
if user_dic['lock'] == True:
return False, '账户已锁定请联系管理员'
elif pwd == user_dic['pwd']:
logger.info('登录成功')
return True, '登录成功'
else:
logger.info('密码错误')
return False, '密码错误'
user_interface.py
import os
from conf import setting
import json
def select(username):
user_path = f'{setting.DB_PATH}/{username}.json'
if os.path.exists(user_path):
with open(user_path, 'r', encoding='utf-8') as f:
user_dic = json.load(f)
return user_dic
else:
return None
def save(user_dic):
user_path = f'{setting.DB_PATH}/{user_dic["username"]}.json'
with open(user_path, 'w', encoding='utf-8') as f:
res = json.dump(user_dic, f, ensure_ascii=False)
f.flush()
return res
db_handler.py
import os
PATH = os.path.dirname(os.path.dirname(__file__))
DB_PATH = os.path.join(PATH,'db')
"""
logging配置
"""
# 定义三种日志输出格式 开始
standard_format = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' \
'[%(levelname)s][%(message)s]' # 其中name为getlogger指定的名字
simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'
id_simple_format = '[%(levelname)s][%(asctime)s] %(message)s'
# 定义日志输出格式 结束
# ****************注意1: log文件的目录
BASE_PATH = os.path.dirname(os.path.dirname(__file__))
logfile_dir = os.path.join(BASE_PATH, 'log')
# print(logfile_dir)
# ****************注意2: log文件名
logfile_name = 'user.log'
# 如果不存在定义的日志目录就创建一个
if not os.path.isdir(logfile_dir):
os.mkdir(logfile_dir)
# log文件的全路径
logfile_path = os.path.join(logfile_dir, logfile_name)
# ****************注意3: log配置字典
LOGGING_DIC = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'standard': {
'format': standard_format
},
'simple': {
'format': simple_format
},
},
'filters': {},
'handlers': {
# 打印到终端的日志
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler', # 打印到屏幕
'formatter': 'simple'
},
# 打印到文件的日志,收集info及以上的日志
'default': {
'level': 'DEBUG',
'class': 'logging.handlers.RotatingFileHandler', # 保存到文件
'formatter': 'standard',
'filename': logfile_path, # 日志文件
'maxBytes': 1024 * 1024 * 5, # 日志大小 5M
'backupCount': 5,
'encoding': 'utf-8', # 日志文件的编码,再也不用担心中文log乱码了
},
},
'loggers': {
# logging.getLogger(__name__)拿到的logger配置
'': {
'handlers': ['default', 'console'], # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
'level': 'DEBUG',
'propagate': True, # 向上(更高level的logger)传递
},
},
}
setting.py
from db import db_handler
from lib import common
logger = common.get_logger('bank')
# 查看余额接口
def check_balance_interface(username):
user_dic = db_handler.select(username)
logger.info(f'用户查看余额{user_dic["balance"]}')
return user_dic['balance']
# 提现接口
def withdraw_interface(username, money):
user_dic = db_handler.select(username)
if user_dic['balance'] >= money * 1.05:
user_dic['balance'] -= money * 1.05
flow = f'用户{username}提现{money}元,手续费{money*0.05}元'
user_dic['flow'].append(flow)
db_handler.save(user_dic)
logger.info(flow)
return True, flow
else:
logger.info('余额不足')
return False, '余额不足'
# 转账接口
def transfer_interface(from_user,to_user, money):
from_user_dic = db_handler.select(from_user)
to_user_dic = db_handler.select(to_user)
if from_user_dic['balance'] >= money:
from_user_dic['balance'] -= money
to_user_dic['balance'] += money
from_flow = f'用户{from_user}转向用户{to_user}金额{money}元'
to_flow = f'用户{to_user}收到用户{from_user}金额{money}元'
from_user_dic['flow'].append(from_flow)
to_user_dic['flow'].append(to_flow)
db_handler.save(from_user_dic)
db_handler.save(to_user_dic)
logger.info(from_flow)
return True, from_flow
else:
logger.info('余额不足')
return False, '余额不足'
# 还款接口
def repay_interface(username, money):
user_dic = db_handler.select(username)
user_dic['balance'] += money
flow = f'用户还款{money}元'
user_dic['flow'].append(flow)
db_handler.save(user_dic)
logger.info(flow)
return flow
# 查看流水
def check_flow_interface(username):
user_dic = db_handler.select(username)
logger.info(f"用户查看流水{user_dic['flow']}")
return user_dic['flow']
#银行支付功能
def pay_interface(username,cost):
user_dic = db_handler.select(username)
if user_dic['balance'] > cost:
user_dic['balance'] -= cost
flow = f'购物支付{cost}元'
user_dic['flow'].append(flow)
db_handler.save(user_dic)
return True, flow
else:
return False,'余额不足'
bank_interface.py
from db import db_handler
from interface import bank_interface
from lib import common
logger = common.get_logger('shop')
# 购物支付接口
def shop_pay_interface(username,cost):
flag,msg = bank_interface.pay_interface(username,cost)
if flag:
logger.info(msg)
return True, msg
else:
logger.info(msg)
return False, msg
# 加入购物车功能接口
def add_shop_car(username,shop_car):
user_dic = db_handler.select(username)
old_car = user_dic['shop_car']
for shop in shop_car:
if shop in old_car:
num = shop_car[shop]
old_car[shop] += num
else:
num = shop_car[shop]
old_car[shop] = num
user_dic['shop_car'].update(old_car)
db_handler.save(user_dic)
logger.info('添加购物车成功')
return '添加购物车成功'
# 查看购物车接口
def check_shop_car_interface(username):
user_dic = db_handler.select(username)
logger.info(user_dic['shop_car'])
return user_dic['shop_car']
shop_interface.py
from db import db_handler
from lib import common
logger = common.get_logger('admin')
# 冻结用户
def lock_user_interface(username):
user_dic = db_handler.select(username)
user_dic['lock'] = True
db_handler.save(user_dic)
logger.info(f'用户{username}已冻结')
return f'用户{username}已冻结'
#解锁用户
def unlock_user_interface(username):
user_dic = db_handler.select(username)
user_dic['lock'] = False
db_handler.save(user_dic)
logger.info(f'用户{username}已解锁')
return f'用户{username}已解锁'
# 修改额度
def change_limit_interface(username,limit):
user_dic = db_handler.select(username)
user_dic['balance'] = limit
db_handler.save(user_dic)
logger.info(f'用户{username}额度修改为{limit}')
return f'用户{username}额度修改为{limit}'
admin_interface.py
import hashlib
import logging.config
from conf import setting
# 加密
def md5_pwd(pwd):
md5_d = hashlib.md5()
md5_d.update(pwd.encode('utf8'))
sal = '小鸡炖蘑菇'
md5_d.update(sal.encode('utf8'))
res = md5_d.hexdigest()
return res
# 登录认证
def login_auth(func):
from core import src
def inner(*args, **kwargs):
if not src.user_info['user']:
print('未登录,请先登录')
src.login()
else:
res = func(*args, **kwargs)
return res
return inner
#日志功能
def get_logger(user):
logging.config.dictConfig(setting.LOGGING_DIC)
logger = logging.getLogger(user)
return logger
common.py
项目1:ATM+购物商城项目的更多相关文章
- python_项目_ATM和购物商城的程序
1 需求 模拟实现一个ATM + 购物商城程序 额度15000或自定义 实现购物商城,买东西加入购物车,调用信用卡接口结账 可以提现,手续费5% 支持多账户登录 支持账户间转账 记录每月日常消费流水 ...
- ATM+购物商城
知识内容: 1.luffy买tesla 2.ATM+购物商城 一.luffy买tesla 需求: 1.目录结构说明 account luffy.json --> 存储用户账户信息 {" ...
- 2.2 - ATM+购物商城程序
要求:模拟实现一个ATM + 购物商城程序1.额度 15000或自定义2.实现购物商城,买东西加入 购物车,调用信用卡接口结账3.可以提现,手续费5%4.支持多账户登录5.支持账户间转账6.记录每月日 ...
- Python开发程序:ATM+购物商城
一.程序要求 模拟实现一个ATM + 购物商城程序 额度 15000或自定义 实现购物商城,买东西加入 购物车,调用信用卡接口结账 可以提现,手续费5% 每月22号出账单,每月10号为还款日,过期未还 ...
- 模拟实现ATM+购物商城程序
流程图: 需求: ATM:模拟实现一个ATM + 购物商城程序额度 15000或自定义实现购物商城,买东西加入 购物车,调用信用卡接口结账可以提现,手续费5%支持多账户登录支持账户间转账记录每月日常消 ...
- day4作业模拟实现一个ATM + 购物商城程序
作业需求: 模拟实现一个ATM + 购物商城程序 1.额度 15000或自定义: 2.实现购物商城,买东西加入 购物车,调用信用卡接口结账: 3.可以提现,手续费5%: 4.每月22号出账单,每月10 ...
- ATM:模拟实现一个ATM + 购物商城程序
额度 15000或自定义 实现购物商城,买东西加入 购物车,调用信用卡接口结账 可以提现,手续费5% 支持多账户登录 支持账户间转账 记录每月日常消费流水 提供还款接口 ATM记录操作日志 提供管理接 ...
- First Project -用函数写的ATM+购物商城程序
作业需求:模拟实现一个ATM + 购物商城程序 额度15000或自定义 实现购物商城,买东西加入 购物车,调用信用卡接口结账 可以提现,手续费5% 每月22号出账单,每月10号为还款日,过期未还,按欠 ...
- Python实现ATM+购物商城
需求: 模拟实现一个ATM + 购物商城程序 额度 15000或自定义 实现购物商城,买东西加入 购物车,调用信用卡接口结账 可以提现,手续费5% 每月22号出账单,每月10号为还款日,过期未还,按欠 ...
随机推荐
- 动图+源码,演示 Java 中常用数据结构执行过程及原理
阅读本文大概需要 3.7 分钟. 作者:大道方圆 cnblogs.com/xdecode/p/9321848.html 最近在整理数据结构方面的知识, 系统化看了下Java中常用数据结构, 突发奇想 ...
- SpringBoot第四篇:整合JDBCTemplate
作者:追梦1819 原文:https://www.cnblogs.com/yanfei1819/p/10868954.html 版权声明:本文为博主原创文章,转载请附上博文链接! 引言 前面几篇文 ...
- Vue双向绑定原理(我尽量写的。简洁)
先问自己两个问题: 1.app.message修改数据的时候,Vue内部是如何监听message数据发生改变的 使用Object.defineProperty ->监听对象属性的改变 2.当数据 ...
- Java8 新特性 Steam() 中间有状态操作
中间有状态操作 Java8 新特性 Stream 练习实例 中间操作,就是把数据处理成自己想要的类型,并且有状态操作,是在所有的数据基础上进行操作的.比如dictinct(去重),sorted(排 ...
- Aladdin and the Flying Carpet LightOJ 1341 唯一分解定理
题意:给出a,b,问有多少种长方形满足面积为a,最短边>=b? 首先简单讲一下唯一分解定理. 唯一分解定理:任何一个自然数N,都可以满足:,pi是质数. 且N的正因子个数为(1+a1)*(1+a ...
- 转: 彻底理解 Spring 容器和应用上下文
本文由 简悦 SimpRead 转码, 原文地址 https://mp.weixin.qq.com/s/o11jVTJRsBi998WlgpfrOw 有了 Spring 之后,通过依赖注入的方式,我们 ...
- JSON.parse() 与 JSON.stringify()
JSON.parse() 方法用来解析JSON字符串,构造由字符串描述的JavaScript值或对象.提供可选的reviver函数用以在返回之前对所得到的对象执行变换(操作). 语法 JSON.par ...
- 基础知识---IEnumerable、ICollection、IList、IQueryable
一.定义 IEnumerable public interface IEnumerable<out T> : IEnumerable ICollection public interfac ...
- python 练习题:定义一个函数quadratic(a, b, c),接收3个参数,返回一元二次方程ax^2+bx+c=0的两个解
请定义一个函数quadratic(a, b, c),接收3个参数,返回一元二次方程 ax^2+bx+c=0的两个解. 提示: 一元二次方程的求根公式为: x1 = (-b + math.sqrt((b ...
- NET 在一个数组中查找另一个数组所在起始位置(下标从0开始,未找到返回-1)
问题: 如果 search 在 dist 中顺序出现而不要求连续出现,那代码应该如何修改?如何计算这种匹配的可能性? 数组 search=[5,4,6],在数据 dist=[1,5,5,4,3,4,5 ...