ATM项目实战
项目需求分析:
1.注册(密码要加密)
2.登陆
3.查看余额
4.提现(可自定手续费)
5.还款
6.转账
7.查看流水
8.添加购物车功能 (商品可配置)
9.查看购物车功能
10.结算购物车功能
11.管理员功能 (可添加账户,冻结账户)
12.项目日志,纪录用户 登录 注册 等操作时间
注册功能
1.创立项目开发目录规范
2.在用户交互层 core - src 文件中 创立 选择功能字典 run( )
3.在 bin - start文件中 调用开始函数 run( )
if __name__ == '__main__':
from core import src
src.run()
4.开始编写第一个功能模块 注册 ,在用户交互层获取 用户名和密码,并在该层判断 2次输入密码是否一致,如果一致则调用注册接口 传入 用户名/密码参数
name = input('请输入用户名').strip()
password = input('请输入密码').strip()
password1 = input('请再次输入密码').strip()
if password == password1:
password = common.hashl(password)
flag, msg = user.register_api(name, password)
print(msg)
else:
print('两次密码输入不一致')
5.编写加密模块放入公共组建中 common 在注册中使用 密码改为密文传入注册接口
def hashl(msg):
md5 = hashlib.md5()
md5.update(msg.encode('utf8'))
md5 = md5.hexdigest()
return md5
6.在接口文件中 编写注册接口 收到传参创建用户字典,并存入db文件中用户信息json文件。
name_dict = {'name': name, 'psd': password, 'balance': 1000, 'car': {}, 'state': True}
if handle.select(name):
return False, '用户名已存在'
handle.save(name_dict)
return True, f'{name} 注册成功'
6.存储用户信息属于 数据库层级操作,在handle文件中编写用户储存函数,调用配置文件路径 DB_DIR 完成数据储存
7.储存用户信息需要用到用户路径,拼接用户路径代码用到db文件夹路径,获取db路径应在配置文件中 setting 中 编写 DB_DIR
BAST_DIR = os.path.dirname(os.path.dirname(__file__))
DB_DIR = os.path.join(BAST_DIR, 'db')
8.注册接口中调用用户储存函数 传入用户字典,完成注册
def save(name_dict):
name_dir = os.path.join(settings.DB_DIR, f'{name_dict.get("name")}.json')
with open(name_dir, 'w', encoding='utf8') as f:
json.dump(name_dict, f)
9.考虑用户注册需要查看用户名是否存在,handle文件中编写用户查询函数,如果有该用户则返回用户字典,如果没有则返回空None
def select(name):
name_dir = os.path.join(settings.DB_DIR, f'{name}.json')
if os.path.exists(name_dir):
with open(name_dir, 'r', encoding='utf8') as f:
name_dict = json.load(f)
return name_dict
10,注册用户接口,首先判断用户是否存在,如果存在返回 用户名已存在,不存在则完成注册操作
if handle.select(name):
return False, '用户名已存在'
登录功能
1.在用户交互层获取 用户名和密码,并且调用加密模块函数,把加密后的密码传给登录接口
name = input('请输入用户名').strip()
password = input('请输入密码').strip()
password = common.hashl(password)
flag, msg = user.login_api(name, password)
2.登录接口 调用 查询用户函数,如果查询用户函数返回空 则代表用户名不存在,结束函数,并把结果返回给 用户交互层 输出
if not handle.select(name):
return False, '用户名不存在'
3.用变量接收查询函数返回值,返回的是一个用户信息字典,利用该字典中的密码和传来的密码对比,一致则 登录成功 不一致则密码错误
name_dict = handle.select(name)
if password == name_dict.get("psd"):
return True, '登录成功'
else:
return False, '密码错误'
查看余额
1.查看余额归属于资金类功能,接口文件夹创建 bank.py文件
2.选择该功能后直接调用 查看余额接口 用户交互层 只做 返回结果展示
msg = interface.bank.check_balance_api(is_login.get("name"))
print(msg)
3.使用该功能则需要先保证账户是登录状态,并且获取到账户名,不然不知道查看谁的余额哦
4.编写 效验用户登录状态装饰器。由于需要多次使用,所以放在公共组建文件中
def Check_login(func):
def inner(*args, **kwargs):
if src.is_login.get("name"):
res = func(*args, **kwargs)
return res
else:
return '请先登录账户'
src.login()
return inner
5.用户登录后 需要有一个全局变量 记录用户登录,放在用户交互层,所以创建一个字典,用来辨别用户是否登录
is_login = {'name': None}
6.在登录功能内添加,用户登录成功后 全局字典用户登录状态改为已登录
if flag:
is_login["name"] = name
7.装饰器判断全局字典用户登录状态,已登录正常执行 未登录跳转到登录页面
8.装上装饰器,然后调用 查询余额接口 传入 用户姓名数据
@common.Check_login
def check_balance():
msg = interface.bank.check_balance_api(is_login.get("name"))
print(msg)
9.接口内根据姓名 调用查询数据函数,得到用户数据,然后展示用户余额
name_dict = handle.select(name)
money = name_dict.get("balance")
return f'您的账户余额为:{money}'
提现功能
1.用户交互层(src)中获取用户需要提现的金额,并直接判断是否是正确的数字,支持浮点数
number = input('请输入您要提现的金额')
try:
number = float(number)
except Exception:
return '请输入正确的数字'
2.比符合要求的提现金额,连同用户名一起传送给提现接口 withdraw_api(name, number):
else:
msg = interface.bank.withdraw_api(is_login.get("name"),number)
print(msg)
3.提现接口内,调用 handle.select(name) 获取用户数据 ,获取到用户余额
name_dict = handle.select(name)
money = name_dict.get("balance")
4.设置提现手续费,由于手续费可配置,故此放到settigs文件中
WITHDRAW_SERVICE = 0.05 # 提现手续费配置比例 目前为百分之5
5.判断账户余额 是否 大于或等于 提现金额+手续费 不符合直接返回结果
if money < number+withdraw_service:
return f'账目余额不足,账户余额为:{money}'
6.进行将字典中余额 减去 提现金额加手续费 然后保存 提现完成
money = money-number-withdraw_service
name_dict["balance"] = money
handle.save(name_dict)
return f'提现成功,提现金额{number},手续费:{withdraw_service},账户余额:{name_dict.get("balance")}'
还款功能
1.用户交互层(src)中获取用户需要还款的金额
number = input('请输入您要充值的金额')
2.调用还款功能接口 传入还款金额 账户姓名
msg = interface.bank.pay_back_api(is_login.get("name"), number)
3.在接口中判断还款数字输入是否正确 不正确直接返回
try:
number = float(number)
except Exception:
return '请输入正确的数字'
4.正确则获取 用户数据 得到账户余额,账户中加上充值金额,然后再次保留到用户信息 完成充值
else:
name_dict = handle.select(name)
name_dict["balance"] += number
handle.save(name_dict)
return f"充值金额:{number},充值成功
转账功能
1.用户交互层(src)中获取用户需要转账的账户,还有转账的金额,并且判断金额是否正确
other_name = input('请问您需要转账给哪个账户').strip()
other_money = input('请问您需要转账的金额').strip()
try:
other_money = float(other_money)
except Exception:
return '请输入正确的数字'
2.将转账的账户名,和转账金额,还有自己的用户名传给 转账接口
msg = interface.bank.transfer_api(is_login.get("name"),other_name,other_money)
print(msg)
3.首先判断对方用户名是否存在
if not handle.select(other_name):
return '转账账户不存在,请再次核实'
4.配置文件 settings中设置 转账手续费比例
TRANSFER_SERVICE = 0.01 # 转账手续费配置比例 目前为百分之1
- 调用函数 拿到自身余额 判断自身账户余额是否够
name_dict = handle.select(my_name)
balance = name_dict.get("balance")
transfer_service = other_money * settings.TRANSFER_SERVICE
if balance < other_money + transfer_service:
return '您的账户余额不足,无法转账'
6.自身账户减去转账金额 加 手续费 对方账户加入金额,并保存
transfer_service = other_money * settings.TRANSFER_SERVICE #手续费
balance = balance - other_money - transfer_service
name_dict["balance"] = balance
handle.save(name_dict)
other_name_dict = handle.select(other_name)
other_name_balance = other_name_dict.get("balance")
other_name_dict["balance"] = other_name_balance + other_money
handle.save(other_name_dict)
return f'转账成功,转账账户:{other_name},转账金额:{other_money},手续费:{other_money * settings.TRANSFER_SERVICE}'
查看流水
1.查看流水,首先在用户注册 构建字典是添加流水记录空列表
name_dict = {'name': name, 'psd': password, 'balance': 1000, 'car': {}, 'state': True,'Check_water':[]}
2.在完成关于余额的操作时添加记录
now_time = time.strftime('%Y-%m-%d %X')
name_dict["Check_water"].append(f'时间:{now_time}----充值金额:{number},充值成功')
3.使用此功能时,调取查看流水接口,传入用户名即可
msg = interface.bank.trading_record_api(is_login.get("name"))
4.接口内获取用户资料 流水内容 返回
name_dict = handle.select(name)
water = name_dict.get("Check_water")
return water
5.判断返回内容是否为空,为空则提示,不为空这循环展示流水结果
if msg:
for i in msg:
print(i)
else:
'暂无流水记录哦'
添加购物车功能
1.选择该功能直接调取 购物车接口 把用户名传过去
interface.shop.add_shop_car(is_login.get("name"))
2.商品信息放入配置文件,在接口中循环打印出来。供用户选择
for num, goods_list in enumerate(settings.goods):
print(f'商品编号:{num + 1} | 商品名称:{goods_list[0]} | 商品单价:{goods_list[1]}')
3.将用户选择的商品信息 放入临时购物车中
number = int(number)
goods_name = settings.goods[choice-1][0]
goods_list1 = [number,settings.goods[choice-1][1]]
if goods_name in new_car:
new_car[goods_name][0] += number
print('商品添加成功')
else:
new_car[goods_name] = goods_list1
print('商品添加成功')
4.当用户退出的时候 读取用户数据,判断购物车中是否有刚刚挑选的商品,如果有就增加数量,没有则新增
choice = input('请挑选的商品>>>(q)退出商城:').strip()
if choice == 'q':
name_dict = handle.select(name)
old_car = name_dict.get("car")
if not new_car:
print('欢迎下次光临')
for goods_name,goods_list in new_car.items():
if goods_name in old_car:
old_car[goods_name][0] += goods_list[0]
print('商品已添加购物车,欢迎下次光临')
name_dict["car"] = old_car
handle.save(name_dict)
break
else:
old_car[goods_name] = goods_list
print('商品已添加购物车,欢迎下次光临')
name_dict["car"] = old_car
handle.save(name_dict)
break
查看购物车功能
1.调用查看购物车接口 还是把名字传进去
msg = interface.shop.pay_shop_car_api(is_login.get("name"))
2.在接口里面拿到 用户真实数据 并且返还出去
name_dict = handle.select(name)
old_car = name_dict.get("car")
return old_car
3.最外层拿到用户购物车数据,循环打印每个商品的名称 数量 金额
if not old_car:
print('购物车空空如也哦')
for goods_name,goods_list in old_car.items():
print(f'商品名:{goods_name},数量:{goods_list[0]},价格:{goods_list[0] * goods_list[1]}')
结算购物车
1.调用结算购物车接口,并把用户名传进去
interface.shop.pay_shop_car_api(is_login.get("name"))
2.拿到用户真实购物车数据 然后计算购物车总价
money = 0
for i,x in old_car.values():
money += i * x
3.判断账户余额
if balance < money:
return '账户余额不足'
4.开始扣除账户余额 并且把 原购物车清空 并且保存
balance = balance - money
name_dict["car"] = {}
name_dict['balance'] = balance
now_time = time.strftime('%Y-%m-%d %X')
name_dict["Check_water"].append(
f'时间:{now_time}----购物成功 | 本次消费{money}/账户余额:{name_dict.get("balance")}')
handle.save(name_dict)
return f'本次消费:{money}元,账户余额为:{name_dict.get("balance")}'
标签:return,name,项目,car,ATM,用户,dict,balance
From: https://www.cnblogs.com/moongodnnn/p/16846228.html