需求分析
- 实现用户的登录注册功能,并且用户分为普通用户和管理员用户
- 用户注册时会自动添加 20000 元的余额,与 10000 元的信用余额
- 用户拥有–充值,提现,转账,还款,查询银行流水的基本功能
- 用户可以进入购物界面,能够添加物品进入购物车中
- 用户可以查询当前购物车中的物品,可以结算购物车中的所有商品
- 可以修改购物车中的商品
- 可以查询所有的购物历史
- 对于管理员的用户,可以锁定账户,充值账户密码,删除账户,修改账户的锁定状态
- 对于管理员用户,以及操作账户金额的所有功能需要记录日志
架构设计
三层架构
三层架构是一个成熟的软件应用程序 架构,它将应用程序组织到三个逻辑和物理计算层中: 表示层或用户界面;用于处理数据的应用程序层;以及用于存储和管理应用程序关联数据的数据层。
三层架构的主要优势在于,由于每层都在自己的基础架构上运行,因此每层都可以由独立开发团队同时开发,并且可根据需要进行更新或扩展,而不会影响其他层
视图层
视图层是应用程序的用户界面和通信层,供最终用户与应用程序进行交互。 其主要目的是向用户显示信息并从用户收集信息。 此顶级层可以在(例如)Web 浏览器上运行、作为桌面应用程序运行或作为图形用户界面 (GUI) 运行。 Web 表示层通常使用 HTML、CSS 和 JavaScript 开发。 可根据平台以各种不同语言编写桌面应用程序。
接口层
接口层,也称为逻辑层或中间层,是应用程序的核心。 在该层中,将采用业务逻辑(一组特定的业务规则)处理从表示层收集到的信息, 有时也会处理数据层中的其他信息 。 接口层还可以添加、删除或修改数据层中的数据。
接口层通常使用 Python、Java、Perl、PHP 或 Ruby 开发,并使用 API 调用与数据层通信。
数据处理层
数据处理层层(有时称为数据库层、数据访问层或后端)可供存储和管理应用程序所处理的信息。 这可以是关系 数据库管理系统,例如 PostgreSQL、MySQL、MariaDB、Oracle、DB2、Informix 或 Microsoft SQL Server,也可以是 NoSQL 数据库服务器,如 Cassandra、CouchDB 或 MongoDB。
在三层应用程序中,所有通信均通过接口层进行。 视图层和数据层无法直接彼此通信。
项目框架
项目代码
start.py
–启动文件
import os
import sys
from core.user_view import run
# 处理项目的环境变量,将项目的根目录加入环境变量中去
sys.path.append(os.path.dirname(__file__))
if __name__ == '__main__':
run()
conf
文件夹
settings.py
–配置文件
import os
# 项目根目录的路径
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
# 项目的数据存放文件夹的路径
BASE_DB = os.path.join(BASE_DIR, 'database')
# 存储到文件的日志格式
file_format = '[%(levelname)s][%(asctime)s]%(message)s'
# log 文件夹路径
LOG_PATH = os.path.join(BASE_DIR, 'log')
# 日志文件路径
BANK_FILE_PATH = os.path.join(LOG_PATH, 'bank.log')
SHOP_FILE_PATH = os.path.join(LOG_PATH, 'shop.log')
USER_FILE_PATH = os.path.join(LOG_PATH, 'user.log')
# 日志配置字典
LOGGING_DIC = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'to_file': {
'format': file_format
},
},
'filters': {},
'handlers': {
# 打印到文件的日志,收集info及以上的日志
'bank': {
'level': 'DEBUG',
'class': 'logging.handlers.RotatingFileHandler', # 保存到文件,日志轮转
'formatter': 'to_file',
'filename': BANK_FILE_PATH, # 日志文件
'maxBytes': 1024 * 1024 * 5, # 日志大小 5M
'backupCount': 5,
'encoding': 'utf-8', # 日志文件的编码,再也不用担心中文log乱码了
},
'shop': {
'level': 'DEBUG',
'class': 'logging.handlers.RotatingFileHandler', # 保存到文件,日志轮转
'formatter': 'to_file',
'filename': SHOP_FILE_PATH, # 日志文件
'maxBytes': 1024 * 1024 * 5, # 日志大小 5M
'backupCount': 5,
'encoding': 'utf-8', # 日志文件的编码,再也不用担心中文log乱码了
},
'user': {
'level': 'DEBUG',
'class': 'logging.handlers.RotatingFileHandler', # 保存到文件,日志轮转
'formatter': 'to_file',
'filename': USER_FILE_PATH, # 日志文件
'maxBytes': 1024 * 1024 * 5, # 日志大小 5M
'backupCount': 5,
'encoding': 'utf-8', # 日志文件的编码,再也不用担心中文log乱码了
},
# 打印到终端的日志
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler', # 打印到屏幕
'formatter': 'to_file'
},
},
'loggers': {
# logging.getLogger(__name__)拿到的logger配置
'': {
'handlers': ['bank', 'console'], # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
'level': 'DEBUG', # loggers(第一层日志级别关限制)--->handlers(第二层日志级别关卡限制)
'propagate': False, # 默认为True,向上(更高level的logger)传递,通常设置为False即可,否则会一份日志向上层层传递
},
'shopping': {
'handlers': ['shop', ], # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
'level': 'INFO', # loggers(第一层日志级别关限制)--->handlers(第二层日志级别关卡限制)
'propagate': False, # 默认为True,向上(更高level的logger)传递,通常设置为False即可,否则会一份日志向上层层传递
},
'user': {
'handlers': ['user', ], # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
'level': 'INFO', # loggers(第一层日志级别关限制)--->handlers(第二层日志级别关卡限制)
'propagate': False, # 默认为True,向上(更高level的logger)传递,通常设置为False即可,否则会一份日志向上层层传递
},
},
}
lib
文件夹
common.py
–公共方法
import logging.config
from conf import settings
from core import user_view
# 登录认证装饰器
def auth(func):
def wrapper(*args, **kwargs):
# 根据用户登录认证的字典来判断是否已经有用户登录
if user_view.auth_dict.get('name'):
res = func(*args, **kwargs)
return res
else:
print("此功能需要登录用户")
print("=====================")
user_view.login()
return wrapper
# 获得日志对象
def get_logging(name):
# 加载配置
logging.config.dictConfig(settings.LOGGING_DIC)
return logging.getLogger(name)
database
文件夹–数据库
database_handler
–数据处理
import pickle
import os
from conf import settings
# 判断用户是否存在
def user_exist(name):
file_path = os.path.join(settings.BASE_DB, f'{name}.pickle')
if not os.path.exists(file_path):
return False, '用户不存在'
else:
with open(file_path, 'rb') as f:
user_info = pickle.load(f)
return True,user_info
# 保存用户信息
def save_userinfo(user_info):
name = user_info.get('name')
file_path = os.path.join(settings.BASE_DB, f'{name}.pickle')
with open(file_path, 'wb') as f:
pickle.dump(user_info, f)
return True
# 判断用户的购物车是否存在
def user_court_exist(name):
file_path = os.path.join(settings.BASE_DB, f'{name}_court.pickle')
if not os.path.exists(file_path):
return False
else:
with open(file_path, 'rb') as f:
user_court = pickle.load(f)
return user_court
# 保存用户的购物车信息
def user_court_save(user_court,name):
file_path = os.path.join(settings.BASE_DB, f'{name}_court.pickle')
with open(file_path, 'wb') as f:
pickle.dump(user_court, f)
return True
core
文件夹–视图层
user_view
–用户视图(主视图)
from lib import common
from database import db_handler
from core.shop_view import shopping_run
from core.admin_view import admin_run
from interface import bank_interface
from interface import user_interface
auth_dict = {"name": None}
def logout():
if not auth_dict['name']:
print("当前没有用户登录")
return
auth_dict['name'] = None
print("退出账户成功!")
def login():
if auth_dict['name']:
print("不能重复登录!")
return
while True:
name_in = input("请输入用户名(q to quit):").strip()
if name_in == "q": break
pwd_in = input("请输入密码:").strip()
flag, msg = user_interface.login_interface(name_in, pwd_in)
if not flag:
print(msg)
print()
continue
print(msg)
print()
auth_dict['name'] = name_in
break
def register():
if auth_dict['name']:
print("已有账户登录,不可注册!")
return
while True:
name_in = input("请输入用户名(q to quit):").strip()
if name_in == "q": break
pwd_in = input("请输入密码:").strip()
print('是否注册为管理员账户,输入 y 确定,输入其他则注册为普通用户')
admin_in = input('您的选择').strip()
if admin_in == 'y':
bool_in = True
else:
bool_in = False
flag = user_interface.register_interface(name_in, pwd_in, bool_in)
if not flag:
continue
print('注册成功!~')
print()
break
@common.auth
def check_balance():
balance = bank_interface.check_balance_interface(auth_dict["name"])
print(f'用户{auth_dict["name"]}的账户余额:¥{balance}')
@common.auth
def check_credit():
credit = bank_interface.check_credit_interface(auth_dict["name"])
print(f'用户{auth_dict["name"]}的信用余额:¥{credit}')
@common.auth
def recharge():
while True:
money = input("请输入您想充值的金额(q to quit):").strip()
if money == 'q': break
if not money.isdigit():
print("请输入整数!")
continue
money = int(money)
bank_interface.recharge_interface(money, auth_dict["name"])
print("充值成功")
print()
break
@common.auth
def withdraw():
while True:
money = input("请输入您想充值的金额(q to quit):").strip()
if money == 'q': break
if not money.isdigit():
print("请输入整数!")
continue
money = int(money)
flag = bank_interface.withdraw_interface(money, auth_dict["name"])
if not flag:
print("余额不足,提现失败!")
print()
continue
print("提现成功!~")
print()
break
@common.auth
def transfer():
while True:
to_name = input("请输入用户名(q to quit):").strip()
if to_name == "q": break
if to_name == auth_dict["name"]:
print('不能给自己转账,请重试!')
continue
flag, user_info = db_handler.user_exist(to_name)
if not flag:
print(user_info)
continue
while True:
money = input("请输入您想转账的金额(q to quit):").strip()
if money == 'q': break
if not money.isdigit():
print("请输入整数!")
continue
money = int(money)
flag = bank_interface.transfer_interface(
auth_dict["name"], to_name, money
)
if not flag:
print("您的余额不足,请重试!")
continue
print("转账成功")
break
break
@common.auth
def repay():
while True:
money = input("请输入您想还款的金额(q to quit):").strip()
if money == 'q': break
if not money.isdigit():
print("请输入整数!")
continue
money = int(money)
flag = bank_interface.repay_interface(money, auth_dict["name"])
if not flag:
print("余额不足,还款失败!~")
print()
continue
print("还款成功!~")
break
@common.auth
def check_bank_flow():
bank_flow = bank_interface.check_flow_interface(auth_dict["name"])
if not bank_flow:
print("你当前的银行流水为空")
return
print("您的银行流水记录为:")
for msg in bank_flow:
print(msg)
print()
func_dict = {
'1': ["登录", login],
'2': ["注册", register],
'3': ["查询账户余额", check_balance],
'4': ["查询信用余额", check_credit],
'5': ["充值", recharge],
'6': ["提现", withdraw],
'7': ["转账", transfer],
'8': ["还款", repay],
'9': ["查询银行流水", check_bank_flow],
'10': ["购物界面", shopping_run],
'11': ['管理员界面', admin_run],
'0': ["注销", logout],
}
def run():
while True:
print("=======用户系统========")
for key in func_dict:
print(key, func_dict[key][0])
print("q 退出")
print("=====================")
choice = input("请输入功能编号:").strip()
if choice == 'q':
break
if choice in func_dict:
func_dict[choice][1]()
else:
print("输入的编号非法,请重试!")
print("=====================")
admin_view.py
–管理员视图
from lib import common
from interface import admin_interface
from database import db_handler
def lock(admin_name):
while True:
name_in = input('请输入锁定的用户名(q to quit):').strip()
if name_in == 'q': break
if name_in == admin_name:
print('不能锁定自己的账户')
continue
flag, user_dict = db_handler.user_exist(name_in)
if not flag:
print(user_dict)
continue
flag, msg = admin_interface.lock_interface(admin_name, name_in)
print(msg)
break
def reset_pwd(admin_name):
while True:
name_in = input('请输入重置密码的用户名(q to quit):').strip()
if name_in == 'q': break
flag, user_dict = db_handler.user_exist(name_in)
if not flag:
print(user_dict)
continue
pwd_new = input('请输入新的密码:').strip()
flag, msg = admin_interface.reset_interface(admin_name, name_in, pwd_new)
print(msg)
break
def del_user(admin_name):
while True:
name_in = input('请输入删除的用户名(q to quit):').strip()
if name_in == 'q': break
flag, user_dict = db_handler.user_exist(name_in)
if not flag:
print(user_dict)
continue
res = input('是否删除该账户?(y/others)').strip()
if res == 'y':
_, msg = admin_interface.del_user_interface(admin_name, name_in)
print(msg)
break
def unlock(admin_name):
while True:
name_in = input('请输入解锁的用户名(q to quit):').strip()
if name_in == 'q': break
flag, user_dict = db_handler.user_exist(name_in)
if not flag:
print(user_dict)
continue
flag, msg = admin_interface.unlock_interface(admin_name, name_in)
print(msg)
break
func_dict = {
'1': ["锁定用户账户", lock],
'2': ["重置用户密码", reset_pwd],
'3': ["删除用户", del_user],
'4': ["解锁用户", unlock],
}
@common.auth
def admin_run():
# 获取用户名
from core.user_view import auth_dict
auth_name = auth_dict["name"]
if not admin_interface.is_admin(auth_name):
print('您没有管理员权限!!!')
return False
while True:
print("=======管理员系统========")
for key in func_dict:
print(key, func_dict[key][0])
print("q 退出")
print("=====================")
choice = input("请输入功能编号:").strip()
if choice == 'q':
break
if choice in func_dict:
func_dict[choice][1](auth_name)
else:
print("输入的编号非法,请重试!")
print("=====================")
shop_view.py
–购物视图
from lib import common
from database import db_handler
from interface import shop_interface
from interface.shop_interface import goods_list
def shopping(auth_name):
# 循环打印商品信息
while True:
print("=======商品信息=======")
for num in goods_list:
print(f'编号:{num} 商品名称:{goods_list[num][0]} 单价:¥{goods_list[num][1]}')
print("q 退出")
print("=====================")
# 根据编号获取商品
choice = input("请输入商品的编号:").strip()
if choice == 'q': break
if choice not in goods_list:
print("输入编号有误,请重试!")
continue
# 获取想要购买的数量
while True:
goods_num = input("请输入您想购买的数量(q to quit):").strip()
if goods_num == 'q': break
if not goods_num.isdigit():
print("请输入整数")
continue
goods_num = int(goods_num)
# 获得了商品的编号,购买数量后,调用加入购物车功能
shop_interface.add_shopping_court(auth_name, choice, goods_num)
print("商品加入购物车成功")
break
def check_shop_court(auth_name):
shop_interface.check_shopping_court_interface(auth_name)
def change_shop_court(auth_name):
flag = shop_interface.change_shopping_court_interface(auth_name)
if flag:
print('修改成功!')
else:
print('修改失败!')
def pay(auth_name):
# 获取购物车信息
shop_court = db_handler.user_court_exist(auth_name)
# 购物车不存在
if not shop_court:
print('您当前的购物车为空')
return
else:
total_money = 0
print("您当前的购物车清单====>")
for goods_num in shop_court:
print(f'编号:{goods_num} '
f'名称:{shop_court[goods_num][0]} '
f'单价:¥{shop_court[goods_num][1]}'
f'数量:{shop_court[goods_num][2]}')
print('-------')
money = shop_court[goods_num][1] * shop_court[goods_num][2]
total_money += money
flag, msg = shop_interface.pay_interface(shop_court, total_money, auth_name)
print(msg)
def check_shop_history(auth_name):
history_list = shop_interface.check_shop_history_interface(auth_name)
if not history_list:
print('购物历史信息为空!')
return
for index, history in enumerate(history_list):
for key in history:
goods_name = history[key][0]
goods_num = history[key][2]
print(f'第{index + 1}次消费:编号:{key},名称:{goods_name},数量:{goods_num}')
return
func_dict = {
'1': ["购物", shopping],
'2': ["查看购物车", check_shop_court],
'3': ["修改购物车", change_shop_court],
'4': ["结算", pay],
'5': ["查询购物历史订单", check_shop_history],
}
@common.auth
def shopping_run():
# 获取用户名
from core.user_view import auth_dict
auth_name = auth_dict["name"]
# 购物视图
while True:
print("=======购物系统========")
for key in func_dict:
print(key, func_dict[key][0])
print("q 退出")
print("=====================")
choice = input("请输入功能编号:").strip()
if choice == 'q':
break
if choice in func_dict:
func_dict[choice][1](auth_name)
else:
print("输入的编号非法,请重试!")
print("=====================")
interface
文件夹–接口层
user_interface.py
–用户接口
import hashlib
from database import db_handler
from lib import common
user_logger = common.get_logging('user')
def register_interface(name, pwd, bool_in):
flag, _ = db_handler.user_exist(name)
if flag:
print('用户已存在,请重新输入')
print()
return False
md5_hash = hashlib.md5()
md5_hash.update("password-salt".encode('utf-8'))
md5_hash.update(pwd.encode('utf-8'))
pwd_salt = md5_hash.hexdigest()
user_info = {
"name": name,
"pwd": pwd_salt,
'is_lock': False, # 记录账号是否被锁定
'is_admin': bool_in, # 记录是否是管理员
"balance": 20000,
"credit": 10000,
"bank_flow": [],
"shopping_history": []
}
db_handler.save_userinfo(user_info)
user_logger.info(f'注册了一个新的用户{name},管理员权限为{bool_in}')
return True
def login_interface(name, pwd):
flag, user_info = db_handler.user_exist(name)
if not flag:
return False, "用户不存在!"
if user_info['is_lock']:
return False,'用户已被锁定,请联系管理员'
pwd_real = user_info.get('pwd')
md5_hash = hashlib.md5()
md5_hash.update("password-salt".encode('utf-8'))
md5_hash.update(pwd.encode('utf-8'))
pwd_salt = md5_hash.hexdigest()
if not flag:
return False, "用户不存在,请重试!~"
if pwd_real == pwd_salt:
return True, '登录成功'
else:
return False, '密码错误'
bank_interface
–用户操作金钱的接口
import time
from lib import common
from database import db_handler
bank_logger = common.get_logging('bank')
def check_balance_interface(username):
_, user_dict = db_handler.user_exist(username)
balance = user_dict.get('balance')
bank_logger.info(f'用户{username}查询了账户余额')
time.sleep(0.3)
return balance
def check_credit_interface(username):
_, user_dict = db_handler.user_exist(username)
credit = user_dict.get('credit')
bank_logger.info(f'用户{username}查询了信用余额')
time.sleep(0.3)
return credit
def recharge_interface(money, name):
_, user_dict = db_handler.user_exist(name)
user_dict["balance"] += money
ctime = time.strftime('%Y-%m-%d %x')
user_dict['bank_flow'].append(f'用户{name}在{ctime}充值了¥{money}')
db_handler.save_userinfo(user_dict)
bank_logger.info(f'用户{name}充值了¥{money}')
time.sleep(0.3)
return True
def withdraw_interface(money, name):
_, user_dict = db_handler.user_exist(name)
balance = user_dict["balance"]
if balance < money * 1.05:
return False
else:
balance -= money * 1.05
user_dict["balance"] = balance
ctime = time.strftime('%Y-%m-%d %x')
user_dict['bank_flow'].append(f'用户{name}在{ctime}提现了¥{money}扣除手续费¥{money * 0.05}')
db_handler.save_userinfo(user_dict)
bank_logger.info(f'用户{name}提现了¥{money}扣除手续费¥{money * 0.05}')
time.sleep(0.3)
return True
def transfer_interface(from_name, to_name, money):
_, from_dict = db_handler.user_exist(from_name)
_, to_dict = db_handler.user_exist(to_name)
balance = from_dict.get("balance")
if balance >= money:
from_dict["balance"] -= money
to_dict["balance"] += money
ctime = time.strftime('%Y-%m-%d %x')
from_dict['bank_flow'].append(f'{ctime} 给用户{to_name}转账了¥{money}')
from_dict['bank_flow'].append(f'{ctime} 接受到用户{from_name}的转账¥{money}')
db_handler.save_userinfo(from_dict)
db_handler.save_userinfo(to_dict)
bank_logger.info(f'用户{from_name}给用户{to_name}转账了¥{money}')
time.sleep(0.3)
return True
else:
return False
def repay_interface(money, name):
_, user_dict = db_handler.user_exist(name)
balance = user_dict["balance"]
if balance < money:
return False
else:
user_dict["balance"] -= money
user_dict["credit"] += money
ctime = time.strftime('%Y-%m-%d %x')
user_dict['bank_flow'].append(f'用户{name}在{ctime}还款了¥{money}')
db_handler.save_userinfo(user_dict)
bank_logger.info(f'用户{name}还款了¥{money}')
time.sleep(0.3)
return True
def check_flow_interface(name):
_, user_dict = db_handler.user_exist(name)
if not user_dict["bank_flow"]:
return False
bank_logger.info(f'用户{name}查询了银行流水信息')
time.sleep(0.3)
return user_dict["bank_flow"]
def consume(total_money, name):
_, user_dict = db_handler.user_exist(name)
balance = user_dict.get('balance')
credit = user_dict.get('credit')
# 进行支付
if total_money > (balance + credit):
return False, '你的余额不足,购买失败'
else:
# 当用户余额足以支付,则只使用余额支付
if balance >= total_money:
balance -= total_money
else:
last = total_money - balance
balance = 0
credit -= last
# 再保存用户的数据
ctime = time.strftime('%Y-%m-%d %x')
user_dict["balance"] = balance
user_dict["credit"] = credit
user_dict['bank_flow'].append(f'用户{name}在{ctime}消费了¥{total_money}')
db_handler.save_userinfo(user_dict)
# 记录日志
bank_logger.info(f'用户{name}消费了¥{total_money}')
time.sleep(0.3)
return True, "消费成功!"
admin_interface
–管理员接口
import os
from conf import settings
from database import db_handler
from lib import common
import hashlib
user_logger = common.get_logging('user')
def is_admin(name):
flag, user_dict = db_handler.user_exist(name)
if user_dict['is_admin']:
return True
def lock_interface(ad_name,name_change):
flag, user_dict = db_handler.user_exist(name_change)
user_dict['is_lock'] = True
db_handler.save_userinfo(user_dict)
user_logger.info(f'管理员{ad_name}将用户{name_change}锁定')
return True,'成功锁定账户!'
def reset_interface(ad_name,name_change,pwd_new):
flag, user_dict = db_handler.user_exist(name_change)
md5_hash = hashlib.md5()
md5_hash.update("password-salt".encode('utf-8'))
md5_hash.update(pwd_new.encode('utf-8'))
pwd_save = md5_hash.hexdigest()
user_dict['pwd'] = pwd_save
db_handler.save_userinfo(user_dict)
user_logger.info(f'管理员{ad_name}将用户{name_change}的密码重置')
return True,'密码重置成功!'
def del_user_interface(ad_name,name_change):
file_path = os.path.join(settings.BASE_DB, f'{name_change}.pickle')
os.remove(file_path)
user_logger.info(f'管理员{ad_name}将用户{name_change}删除')
return True,'删除账户成功'
def unlock_interface(ad_name,name_change):
flag, user_dict = db_handler.user_exist(name_change)
if user_dict['is_lock']:
user_dict['is_lock'] = False
db_handler.save_userinfo(user_dict)
user_logger.info(f'管理员{ad_name}将用户{name_change}解锁')
return True,'成功解锁账户!'
else:
return False,'用户没有被锁定!'
shop_interface
–购物接口
from lib import common
from interface import bank_interface
from database import db_handler
shop_logger = common.get_logging('shopping')
goods_list = {
"1": ["小母牛", 1000],
"2": ["小公牛", 500],
"3": ["小汽车", 1500],
"5": ["大汽车", 2000],
"6": ["小玩具", 200],
"7": ["文具一套", 10]
}
def add_shopping_court(name, goods_name_num, goods_count_num):
user_court = db_handler.user_court_exist(name)
# 该用户的购物车不存在时,新建一个文件存储
if not user_court:
user_court = {
# "编号":['名称',‘单价’,‘数量’]
goods_name_num: [
goods_list[goods_name_num][0],
goods_list[goods_name_num][1],
goods_count_num
],
}
else:
# 判断物品是否已经加入购物车中
if goods_name_num in user_court:
# 商品在购物车中,直接修改数量即可
user_court[goods_name_num][2] += goods_count_num
else:
# 商品不在购物车中,添加数据
user_court[goods_name_num] = [
goods_list[goods_name_num][0],
goods_list[goods_name_num][1],
goods_count_num
]
# 保存购物车
db_handler.user_court_save(user_court, name)
shop_logger.info(f'{name}的购物车修改了商品{goods_list[goods_name_num][0]}')
return True
def check_shopping_court_interface(name):
shop_court = db_handler.user_court_exist(name)
if not shop_court:
print('购物车信息为空!')
else:
print("您当前的购物车清单====>")
for goods_num in shop_court:
print(f'编号:{goods_num} '
f'名称:{shop_court[goods_num][0]} '
f'单价:¥{shop_court[goods_num][1]}'
f'数量:{shop_court[goods_num][2]}')
print('-------')
def change_shopping_court_interface(name):
shop_court = db_handler.user_court_exist(name)
if shop_court:
while True:
# 打印购物车
print("您当前的购物车清单====>")
for goods_num in shop_court:
print(f'编号:{goods_num} '
f'名称:{shop_court[goods_num][0]} '
f'单价:¥{shop_court[goods_num][1]}'
f'数量:{shop_court[goods_num][2]}')
print('-------')
choice = input("请输入商品的编号(q to quit):").strip()
if choice == 'q':
return False
if choice not in shop_court:
print("输入编号有误,请重试!")
continue
else:
if shop_court[choice][2] > 1:
shop_court[choice][2] -= 1
else:
del [shop_court[choice]]
print(f'商品{shop_court[choice][0]}数量-1')
db_handler.user_court_save(shop_court, name)
shop_logger.info(f'{name}的购物车修改了商品{shop_court[choice][0]}')
return True
else:
print('购物车信息为空!')
return False
def pay_interface(shop_court, total_money, name):
# 调用消费接口
flag, msg = bank_interface.consume(total_money, name)
# 消费成功
if flag:
# 修改购物历史信息
_, user_dict = db_handler.user_exist(name)
# 将购物车订单信息加入消费历史中
user_dict["shopping_history"].append(shop_court)
db_handler.save_userinfo(user_dict)
# 清空用户的购物车
shop_court = {}
db_handler.user_court_save(shop_court, name)
# 记录日志
shop_logger.info(f'{name}结算并清空了购物车')
return True, "支付成功,购物车清空!"
# 消费失败
else:
return False, msg
def check_shop_history_interface(name):
_, user_dict = db_handler.user_exist(name)
return user_dict["shopping_history"]