ATM购物车项目流程
项目开发流程
1.项目需求分析
产品经理(客户) 架构师 开发经理
1.架构师 开发经理提前构思大致方案
2.引导客户提出合理要求(避免不合理的请求)
3.记录会议内容
2.项目架构设计
架构师
1.项目编程语言
2.项目整体框架
框架、数据库服务
3.项目报价
3.项目分组开发
架构师 开发经理 程序员
1.任务拆分开发
4.项目提交测试
1.程序员自己要提前测试一下
2.测试部门专门测试(扣绩效)
5.项目交付上线
1.运维人员负责即可
"""
小公司:成长速度特别快 但是压力非常大
大公司:履历好看 福利待遇好 较为安逸
"""
项目需求分析
该项目的核心不仅在于引领初学者快速入门python项目开发,更是站在项目架构的角度教你如何在程序开发之初合理且优雅地设计程序的架构,从而极大地提升程序的开发效率与可扩展性
"""
- 额度15000或自定义
- 支持多账户登录
- 可以查看账户余额
- 可以提现(可自定义手续费比例)
- 提供还款接口
- 支持账户间转账
- 记录每月日常消费流水
- 实现购物商城,买东西加入购物车,调用信用卡接口结账
- 提供管理接口,包括添加账户、用户额度,冻结账户等
- ATM记录操作日志
- 用户认证功能
"""
1.注册功能
2.登录功能
3.查看余额
4.提现功能
5.充值功能
6.转账功能
7.查看流水
8.添加购物车
9.结算购物车
10.管理员功能
10.1.冻结账户
10.2.删除账户
项目架构设计(重点)
以实际项目为例讲解三层架构设计
百度
以百度登录功能为例 分析执行步骤
1.在浏览器页面上获取用户名和密码
2.基于网络发送给百度服务端
3.服务端连接数据库服务
淘宝
以淘宝买商品为例 分析执行步骤
1.浏览器页面展示商品总价
2.基于网络发送给淘宝服务端再次计算总价
3.调用数据库服务完成金额操作
"""
第一层:只做数据展示和简单的数据获取
cmd终端、浏览器页面、手机app页面
第二层:真正的核心业务逻辑处理(代码)
编写代码的py文件、目录、框架
第三层:数据操作
文件读写操作、py文件、数据库软件
"""
ATM架构设计
三层架构
core目录下的src.py(浏览器)
interface目录下的多个py文件(框架)
db目录下db_handler.py(数据库服务)
项目目录搭建
软件开发目录规范
项目功能搭建
1.注册功能
第一层:展示层
1.接收用户名和密码输入,并把密码做hash值加密(通过调用公共模块common里面定义的hash_pwd接口)。
2.判断密码是否一致,如果一致,调用第二层逻辑判断,传参用户名和密码两个参数,也用两个参数flag和msg来接收。
3.如果密码不一致,直接在第一层返回密码不一致错误。
第二层:逻辑处理层
1.接收第一层传过来的用户名和密码,然后通过传参用户名调用用户数据字典并使用user_data来接收。
2.对user_data判断,如果有值说明用户存在,直接返回,反之则手动添加个用户模板,并把用户模板传给用户数据字典,最后直接给第一层返回注册成功。
第三层:数据存储层
对注册的用户名保存到db目录,并以用户名.json后缀结尾文件保存
2.登陆功能
第一层:展示层
1.接收用户名和密码输入,并把密码做hash值加密(通过调用公共模板common里面定义的hash_pwd接口)。
2.调用第二层接口,把用户名和密码作为参数传进去,并用flag和msg接收这个功能接口,并对flag值做判断,如果flag值为true,说明用户登录成功,此时添加用户登录状态,否则就是登录失败。
第二层:逻辑处理层
1.接收第一层传过来的用户名和密码,通过给用户数据字典传参用户名判断,如果用户名有值,说明用户存在,如果没有值,说明用户不存在,立刻返回False并提示用户不存在。
2.判断用户密码是否一致,如果一致直接返回True并提示登录成功,否则返回False并提示用户密码错误
第三层:数据存储层
查询用户数据字典,判断用户是否存在
3.查看余额
第一层:展示层
通过传参用户名调用第二层功能接口层,并用flag和msg接收调用的接口层,并打印msg信息
第二层:逻辑处理层
1调用用户数据字典,返回一个数据字典,读取字典里面余额
2增加用户流水并记录日志,最后返回字典的余额
第三层:数据存储层
查询用户的数据字典,有数据直接返回,否则就是一个None
4.提现功能
第一层:展示层
1.接收提现的金额输入,并对金额的数字做判断,是否符合整数或小数,如果输入的是其它字符则提示并返回。
2.通过传参用户名和提现金额调用第二层接口层,并用flag和msg接收调用的接口层,并打印msg信息
第二层:逻辑处理层
1.先去用户数据字典获取到用户数据,并对用户余额做判断,如果余额小于提现金额+手续费,直接返回余额不足。
2.余额减去提现金额+手续费,增加用户流水和记录日志,调用第三层保存用户数据,最后返回提现成功并把提现金额和手续费及余额打印
第三层:数据存储层
用户数据查询及提现余额减少并保存
5.还款功能
第一层:展示层
1.接收还款金额的输入,并对金额的数字做判断,是否符合整数或小数,如果输入的是其它字符则提示并返回。
2.通过传参用户名和还款金额调用第二层接口层,并用flag和msg接收调用的接口层,并打印msg信息
第二层:逻辑处理层
1.先去用户数据字典获取到用户数据,并提取出余额。
2.直接对余额加上还款金额,并打印用户流水和记录日志,调用第三层保存用户数据,最后返回还款成功并把还款金额和余额打印。
第三层:数据存储层
用户数据查询及余额增加还款并保存
6.转账功能
第一层:展示层
1.接收待转账的用户名和转账金额两个变量输入,对转账金额进行数字判断,如果数字不符合小数或整数直接返回报错
2.通过传参要转账的用户,待转账的用户及待转账的金额调用第二层接口层,并用flag和msg接收调用接口层,并打印msg信息
第二层:逻辑处理层
1.分别通过传参待转账用户和要转账用户给用户数据字典,得到两个用户数据。
2.对待转账用户判断,如果没有值,说明待转账用户不存在,直接传False并打印用户不存在。
3.对要转账用户的余额进行判断,看是否大于待转账金额,如果小于待转账金额,直接传False并打印要转账用户余额不足,无法完成转账
4.完成待转账和要转账用户的金额转账,分别增减转账金额,同时对这两个用户完成流水增加并打印日志,调用第三层保存用户数据。最后返回True及打印转账完成
第三层:数据存储层
用户数据查询及用户余额增减并保存
7.查看流水
第一层:展示层
1.通过传参要查看的流水账户调用第二层接口层,并用flag和msg接收调用接口层,打印msg信息
第二层:逻辑处理层
1.传参用户名给第三层用户数据字典,得到用户的数据字典。
2.读取用户流水,并记录用户流水和打印日志,调用第三层保存用户数据,最后返回True及用户流水
第三层:数据存储层
用户数据查询及用户数据保存
8.添加购物车功能
第一层:展示层
1.while循环打印商品信息
2.接收用户输入的商品编号并对编号做判断,如果编号是数字则用int做转换,如果是非数字直接打印错误并返回。
3.对商品编号是否存在已存在编号里判断,如果不是在已存在编号里,则打印错误并返回
4.设置商品列表和商品名称两个变量名,用于后续临时购物车判断
5.在循环打印购物车前添加一个临时字典,通过商品名称对字典进行判断,如果字典有数据值,则追加商品数量,如果没有这直接通过字典的方式赋值
6.当商品编号为q时,调用第二层接口层,并传用户名和临时购物车两个参数,并用flag和msg接收传调用的接口层,并打印msg信息
第二层:逻辑处理层
1.传参用户名给第三层用户数据字典,得到用户的数据字典。
2.设置一个购物车字典变量,读取用户的购物车信息
3.循环遍历读取临时字典的键和值,并对购物车字典进行判断,如果临时字典的键(商品名称)在购物车字典里,则追加购物车字典的商品数量,如果没有则直接Key:Value的方式赋值
4.保存购物车字典,并打印日志,调用第三层接口保存用户数据,最后返回True并打印购物车添加成功
第三层:数据存储层
读取用户数据及保存用户数据
9.查看购物车功能
第一层:展示层
1.通过传参用户名调用第二层功能接口层,并用flag和msg接收调用的接口层,并打印msg信息
第二层:逻辑处理层
1.传参用户名给第三层用户数据字典,得到用户的数据字典。
2.获取用户车购物数据,如果购物车为空,打印False并返回购物车空空如也
3.如果购物车有数据,获取购物车信息并打印日志,最后返回True并返回购物车信息
第三层:数据存储层
查询用户数据
10.结算购物车功能
第一层:展示层
1.通过传参用户名调用第二层功能接口层,并用flag和msg接收调用的接口层,并打印msg信息
第二层:逻辑处理层
1.传参用户名给第三层用户数据字典,得到用户的数据字典。
2.设置购物车和当前余额两个变量接收用户数据字典的值.
3.如果购物车没有信息,打印False并返回购物车空空如也
4.计算购物车总额并对余额进行判断,如果购物车总额大于余额,打印False并返回用户余额不足,无法结算购物车
5.结算购物车并清空购物车,保存用户信息,打印日志,最后返回True并返回用户消费金额及余额。
第三层:数据存储层
查询用户数据和保存用户数据
11.管理员功能
第一层:展示层
1.使用用户名和密码两个变量接收用户的输入。
2.通过传参用户名和密码(做hash调用common)给第二层功能接口层,并用flag和msg接收并打印msg。
第二层:逻辑处理层
1.传参用户名给第三层用户数据字典,得到用户的数据字典。
2.判断用户名是否存在,不存在直接打印False并返回用户不存在
3.判断密码是否一致,不一致打印False并返回密码错误
4.判断用户是否是管理员,不是则打印False并返回不是管理员
5.调用管理员接口层,返回一个循环打印,里面有用户锁定和用户查询两个功能函数。
6.进入用户锁定功能函数后,提示用户输入用户名,调用第三层获取用户数据字典,并对用户名进行判断,如果用户名不存在打印并返回。
7.如果用户存在获取用户的is_lock状态值,设置为True并保存用户数据字典,打印并返回用户锁定完成,最后按退出结束整个程序
第三层:数据存储层
读取用户数据和保存用户数据
ATM项目购物车代码汇总
项目启动脚本start.py:
import os
import sys
base_dir = os.path.dirname(os.path.dirname(__file__))
sys.path.append(base_dir)
if __name__ == '__main__':
from core import src
src.run()
项目启动配置文件settings.py
import os
import time
ctime = time.strftime('%Y-%m-%d %X')
BASE_DRI=os.path.dirname(os.path.dirname(__file__))
DB_DIR = os.path.join(BASE_DRI,'db')
if not os.path.exists(DB_DIR):
os.mkdir(DB_DIR)
# 商品列表
GOOD_LIST = [
['挂壁面',3],
['印度飞饼',22],
['极品木瓜',666],
['极品飞车',999],
['凳子',2000],
['桌子',5000],
['床',10000],
]
# 日志目录
LOG_DIR=os.path.join(BASE_DRI,'log')
if not os.path.exists(LOG_DIR):
os.mkdir(LOG_DIR)
#提现手续费
WITHDRAW_RATE = 0.01
# 定义日志输出格式 开始
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'
# 自定义文件路径
logfile_path = f'{LOG_DIR}/ATM.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)传递
}, # 当键不存在的情况下 (key设为空字符串)默认都会使用该k:v配置
# '购物车记录': {
# 'handlers': ['default','console'], # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
# 'level': 'WARNING',
# 'propagate': True, # 向上(更高level的logger)传递
# }, # 当键不存在的情况下 (key设为空字符串)默认都会使用该k:v配置
},
}
项目公共模块 comon.py
import hashlib
import logging
import logging.config
from conf import settings
import os
from core import src
from db import db_handler
#判断用户输入的数据是否合法
def get_num(num):
try:
float(num)
except Exception as e:
return False,'请输入整数或小数'
else:
return True,float(num)
# 给密码hash加密
def hash_pwd(password):
md5 = hashlib.md5()
md5.update(password.encode('utf8'))
return md5.hexdigest()
# 设置日志模板调用
def get_log(title):
logging.config.dictConfig(settings.LOGGING_DIC)
return logging.getLogger(title)
# 用户登录判断装饰器
def login_auth(type):
def outer(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':
# 获取用户名数据并判断is_admin的键是不是为真
if src.is_login.get('is_admin'):
res = func_name(*args, **kwargs)
return res
else:
print('您不是管理员,没有权限进行操作')
else:
print('用户没有登录,请登录')
src.login()
return inner
return outer
项目核心模块 src.py(第一层展示层)
from lib import common
from interface import user_interface,shop_car_interface,bank_interface,admin_interface
from conf import settings
is_login = {'username':None,
'is_admin':None,}
def register():
username = input('请输入注册用户名>>>>:').strip()
password = input('请输入注册密码>>>>:').strip()
confirm_pwd = input('请输入确认注册密码>>>>:').strip()
if len(username) == 0:
print('用户创建不规范')
return
if password == confirm_pwd:
hash_pwd = common.hash_pwd(password)
flag,msg = user_interface.register_interface(username,hash_pwd)
print(msg)
else:
print('注册密码不一致,请确认')
def login():
username = input('请输入登录用户名>>>>:').strip()
password = input('请输入登录密码>>>>:').strip()
hash_pwd = common.hash_pwd(password)
flag,msg = user_interface.login_interface(username,hash_pwd)
if flag:
# 登录成功增加用户登录状态和锁定状态
is_login['username'] = username
is_login['is_admin'] = msg[1] # msg返回的是元组,第一个是状态,第二个是管理员的状态
print(msg[0])
else:
print(msg)
@common.login_auth('normal')
def check_balance():
_,msg = bank_interface.check_balance_interface(is_login.get('username'))
print(msg)
@common.login_auth('normal')
def withdraw():
target_num = input('请输入提现金额>>>>:').strip()
flag1,target_money=common.get_num(target_num)
if flag1:
flag,msg = bank_interface.withdraw_interface(is_login.get('username'),target_money)
print(msg)
else:
# 填写的是非整数或小数打印下面
print(target_money)
@common.login_auth('normal')
def repay_amount():
target_num = input('请输入转账金额>>>:').strip()
flag1,target_money = common.get_num(target_num)
if flag1:
flag,msg = bank_interface.repay_amount_interface(is_login.get('username'),target_money)
print(msg)
else:
print(target_money)
@common.login_auth('normal')
def transfer():
target_user = input('请输入待转账用户>>>>:').strip()
target_num = input('请输入待转账金额>>>>:').strip()
flag1,target_money = common.get_num(target_num)
if flag1:
flag,msg = bank_interface.transfer_interface(is_login.get('username'),target_user,target_money)
print(msg)
else:
print(target_money)
@common.login_auth('normal')
def check_flow():
_,msg = bank_interface.check_flow_interface(is_login.get('username'))
print(msg)
@common.login_auth('normal')
def add_shop_car():
temp_shop_car = {}
while True:
# 1.循环打印商品信息
for num,good_data in enumerate(settings.GOOD_LIST): #['印度飞饼','22']
print(f'商品编号:{num}|商品名称:{good_data[0]}|商品价格:{good_data[1]}')
# 2.接收用户商品编号输入并判断是否数字,是则int,否则打印并返回
choice_num = input('请输入商品编号(按q退出)>>>:').strip()
# 7.商品编号为q时,调用数据保存接口
if choice_num.lower() =='q':
_,msg=shop_car_interface.add_shop_car_interface(is_login.get('username'),temp_shop_car)
print(msg)
return
#判断是否数字,是则int,否则打印并返回
if not choice_num.isdigit():
print('商品编号必须是纯数字')
continue
choice_num = int(choice_num)
# 3.判断商品编号是否在已存在编号里,不是打印并返回
if choice_num not in range(len(settings.GOOD_LIST)):
print('商品编号必须在已存在编号里')
continue
# 4.接收商品数量输入,判断商品数量是否整型,不是打印并返回
good_num = input('请输入商品数量>>>>:').strip()
if not good_num.isdigit():
print('商品编号必须是纯数字')
continue
good_num = int(good_num)
# 5.设置商品列表和商品名称两个变量,用户后面临时字典判断
target_good_list = settings.GOOD_LIST[choice_num] #['印度飞饼','22']
good_name = target_good_list[0]
# 6.设置临时字典,用商品名称判断临时字典是否有数据,有数据追加临时字典,没有则直接赋值临时字典
if good_name in temp_shop_car: #{'印度飞饼',[2,22]}
temp_shop_car[good_name][0] += good_num
else:
temp_shop_car[good_name] = [good_num,target_good_list[1]]
@common.login_auth('normal')
def check_shop_car():
_,msg = shop_car_interface.check_shop_car_interface(is_login.get('username'))
print(msg)
@common.login_auth('normal')
def pay_shop_car():
_,msg = shop_car_interface.pay_shop_car_interface(is_login.get('username'))
print(msg)
@common.login_auth('admin')
def admin():
while True:
print("""
1.锁定用户
2.解锁用户
3.删除用户
4.退出
""")
choice_num = input('请输入功能编号>>>:').strip()
if choice_num == '1':
# 获取所有用户列表
user_list = admin_interface.select_user_list(is_login.get('username')) # ['user1','user2']
# 打印所有用户列表供管理员选择(排除自己被选择)
all_user_list = [ user for user in user_list if user != is_login.get('username')]
for num,username in enumerate(all_user_list):
print(f'用户编号:{num}|用户名称:{username}')
choice = input('请输入指定的名称>>>>:').strip()
if not choice.isdigit():
print('请输入正确的编号')
continue
choice = int(choice)
# 选择指定的用户
target_lock_user = all_user_list[choice]
# 执行锁定用户操作并返回锁定成功 (_)一般不需要怎么用可以用_代替
_,msg =admin_interface.lock_user(is_login.get('username'),target_lock_user)
print(msg)
elif choice_num == '2':
# 获取所有用户列表
user_list = admin_interface.select_user_list(is_login.get('username'))
# 打印所有用户列表供管理员选择(排除自己被选择)
all_user_list = [user for user in user_list if user != is_login.get('username')]
for num, username in enumerate(all_user_list):
print(f'用户编号:{num}|用户名称:{username}')
choice = input('请输入指定的名称>>>>:').strip()
if not choice.isdigit():
print('请输入正确的编号')
continue
choice = int(choice)
# 选择指定的用户
target_unlock_user = all_user_list[choice]
# 执行解锁用户操作并返回解锁成功 (_)一般不需要怎么用可以用_代替
_, msg = admin_interface.unlock_user(is_login.get('username'), target_unlock_user)
print(msg)
elif choice_num == '3':
# 获取所有用户列表
user_list = admin_interface.select_user_list(is_login.get('username')) # ['user1','user2']
# 打印所有用户列表供管理员选择(排除自己被选择)
all_user_list = [user for user in user_list if user != is_login.get('username')]
for num, username in enumerate(all_user_list):
print(f'用户编号:{num}|用户名称:{username}')
choice = input('请输入指定的名称>>>>:').strip()
if not choice.isdigit():
print('请输入正确的编号')
continue
choice = int(choice)
# 选择指定的用户
target_delete_user = all_user_list[choice]
# 执行删除用户操作并返回删除成功 (_)一般不需要怎么用可以用_代替
_, msg = admin_interface.delete_user(is_login.get('username'), target_delete_user)
print(msg)
elif choice_num == '4':
run()
else:
print('请输入正确功能编号')
func_dict = {
'1':register,
'2':login,
'3':check_balance,
'4':withdraw,
'5':repay_amount,
'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.管理员功能
""")
choice_num = input('请输入功能编号>>>>:').strip()
if choice_num in func_dict:
func_dict.get(choice_num)()
else:
print('请输入正确功能编号')
第二层逻辑判断层之用户模块user_interface.py
from db import db_handler
from lib import common
logger = common.get_log('用户模块')
def register_interface(username,password):
user_data = db_handler.select(username)
#判断用户是否有数据
if user_data:
logger.info(f'{username}用户已存在')
return False,f'{username}用户已存在'
# 创建用户数据字典
user_data_dict = {
'username':username,
'password':password,
'is_lock':False,
'is_admin':False,
'flow_water':[],
'balance':15000,
'shop_car':{},
}
# 保存用户数据并返回注册成功
db_handler.save(user_data_dict)
logger.info(f'{username}用户注册成功')
return True,f'{username}用户注册成功'
def login_interface(username,password):
user_data = db_handler.select(username)
# 确认用户是否存在
if not user_data:
return False,f'{username}用户不存在,请确认'
# 确认密码
if user_data.get('password') == password:
# 确认是否被锁定
if user_data.get('is_lock'):
return False,f'{username}用户被锁定,无法登录,请联系管理员winter'
else:
return True,(f'{username}登录成功',user_data.get('is_admin'))
else:
return False,f'{username}密码错误'
第二层逻辑判断层之银行模块bank_interface.py
from lib import common
from db import db_handler
from conf import settings
logger = common.get_log('银行模块')
def check_balance_interface(username):
'''查看指定用户余额'''
user_data = db_handler.select(username)
# 增加用户流水
user_data['flow_water'].append(f'时间:{settings.ctime} {username}查看了流水')
db_handler.save(user_data)
logger.debug(f'{username}余额为{user_data.get("balance")}')
return True, f'{username}余额为{user_data.get("balance")}'
def withdraw_interface(username, target_money):
# 1.获取用户数据
user_data = db_handler.select(username)
# 2.判断用户余额是否大于提现+手续费金额
if user_data.get('balance') < target_money * (1+ settings.WITHDRAW_RATE):
return False,f'{username}用户余额不够,无法提现'
user_data['balance'] -= target_money * (1+settings.WITHDRAW_RATE)
# 添加用户流水
user_data['flow_water'].append(f'时间:{settings.ctime} {username}提现了{target_money}')
# 保存用户数据
db_handler.save(user_data)
logger.debug(f'{username}用户提现了{target_money},手续费{target_money*settings.WITHDRAW_RATE}')
return True,f'{username}用户提现了{target_money},手续费{target_money*settings.WITHDRAW_RATE}'
def repay_amount_interface(username,target_money):
user_data = db_handler.select(username)
# 转账
user_data['balance'] += target_money
# 增加用户流水
user_data['flow_water'].append(f'时间:{settings.ctime} {username}完成了{target_money}转账')
# 保存用户数据
db_handler.save(user_data)
logger.debug(f'{username}完成了{target_money}转账,余额为{user_data.get("balance")}')
return True, f'{username}完成了{target_money}转账'
def transfer_interface(username,target_user,target_money):
# 获取用户信息
user_dict = db_handler.select(username)
target_user_dict = db_handler.select(target_user)
# 判断目标用户是否存在
if not target_user_dict:
logger.debug(f'{target_user}用户不存在')
return False,f'{target_user}用户不存在'
# 判断转账用户余额是否大于转账金额
if user_dict.get('balance') < target_money:
return False,f'{username}用户余额不足,无法完成转账'
# 完成用户转账
user_dict['balance'] -= target_money
target_user_dict['balance'] += target_money
# 增加用户流水
user_dict['flow_water'].append(f'时间:{settings.ctime} 给{target_user}完成了{target_money}转账')
target_user_dict['flow_water'].append(f'时间:{settings.ctime} 接收到{username}用户{target_money}转账')
# 保存数据
db_handler.save(user_dict)
db_handler.save(target_user_dict)
logger.debug(f'{username}给{target_user}完成了{target_money}转账')
return True,f'{username}给{target_user}完成了{target_money}转账'
def check_flow_interface(username):
user_data = db_handler.select(username)
user_data['flow_water'].append(f'{username}查看了流水')
db_handler.save(user_data)
logger.debug(f'时间:{settings.ctime} {username}查看了流水')
return True,f'{username}查看了流水{user_data.get("flow_water")}'
第二层逻辑判断层之购物车模块shop_car_interface.py
from db import db_handler
from lib import common
logger = common.get_log('购物车模块')
def add_shop_car_interface(username,temp_shop_car):
# 8.接收用户数据,打开文件字典
user_data = db_handler.select(username)
old_shop_car = user_data.get('shop_car')
#并循环遍历临时字典k:v,用k判断文件字典是否有数据,有则追加文件字典商品数量,没有则直接赋值
for g_name,g_list in temp_shop_car.items(): #{'印度飞饼',[2,22]}
if g_name in old_shop_car:
old_shop_car[g_name][0] += temp_shop_car[g_name][0]
else:
old_shop_car[g_name] = g_list
# 保存用户数据,打印商品成功并返回
user_data['shop_car'] = old_shop_car
db_handler.save(user_data)
logger.info(f'{username}用户添加购物车成功,{old_shop_car}')
return True,f'{username}用户添加购物车成功'
#查看购物车
def check_shop_car_interface(username):
user_data =db_handler.select(username)
logger.info(f'{username}查看了购物车')
return True, user_data.get('shop_car')
def pay_shop_car_interface(username):
user_data = db_handler.select(username)
# 获取购物车和余额
shop_car = user_data.get('shop_car')
current_balance = user_data.get('balance')
# 判断购物车是否为空
if not shop_car:
logger.info(f'{username}用户购物车空空如也,请求添加购物车吧')
return False, f'{username}用户购物车空空如也,请求添加购物车吧'
# 计算购物车总额,并和余额对比
total_money = 0
for g_list in shop_car.values(): #[2,22],[3,666]
total_money += g_list[0] * g_list[1]
if total_money > current_balance:
logger.info(f'{username}用户余额不足,无法结算购物车')
return False,f'{username}用户余额不足,无法结算购物车'
# 结算并清空购物车
user_data['balance'] -= total_money
user_data['shop_car'] = {}
# 保存用户数据并返回
db_handler.save(user_data)
logger.info(f'{username} 花费了{total_money} 余额还剩余{user_data.get("balance")}')
return True,f'{username} 花费了{total_money} 余额还剩余{user_data.get("balance")}'
第二层逻辑判断层之管理员模块admin_interface.py
from db import db_handler
from lib import common
logger = common.get_log('管理员模块')
#查询所有用户接口
def select_user_list(username):
user_list =db_handler.user_list()
return user_list
# 锁定用户接口
def lock_user(username,target_lock_user):
user_data = db_handler.select(target_lock_user)
user_data['is_lock'] = True
db_handler.save(user_data)
logger.info(f'{username}用户给{target_lock_user}用户进行了锁定')
return True,f'{target_lock_user}用户已完成锁定'
# 解锁用户接口
def unlock_user(username, target_unlock_user):
user_data = db_handler.select(target_unlock_user)
user_data['is_lock'] = False
db_handler.save(user_data)
logger.info(f'{username}用户给{target_unlock_user}用户进行了解锁')
return True,f'{target_unlock_user}用户已完成解锁'
# 删除用户接口
def delete_user(username, target_delete_user):
user_data = db_handler.delete(target_delete_user)
logger.info(f'{target_delete_user}用户被{username}删除成功')
return True,f'{target_delete_user}用户被{username}删除成功'
第三层DB存储层db_handler.py
import json
from conf import settings
import os
# 用户数据查询
def select(username):
user_file_path = os.path.join(settings.DB_DIR,f'{username}.json')
if os.path.exists(user_file_path):
with open(user_file_path,'r',encoding='utf8') as f:
user_data = json.load(f)
return user_data
# 用户数据保存
def save(user_data_dict):
username = user_data_dict.get('username')
user_file_path = os.path.join(settings.DB_DIR,f'{username}.json')
with open(user_file_path,'w',encoding='utf8') as f:
json.dump(user_data_dict,f,ensure_ascii=False)
# 查询所有用户列表
def user_list():
list_dir = os.listdir(settings.DB_DIR)
user_list = [ user.split('.')[0] for user in list_dir if user.endswith('.json')]
return user_list
# 删除指定的用户
def delete(username):
user_file_path = os.path.join(settings.DB_DIR,f'{username}.json')
os.remove(user_file_path)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗