一,作者介绍
吴海东
二,程序说明
1.ATM取款机提现、还款、转账功能
2.冻结账户、创建新账户功能
3.商品购物功能
4.退出
三,程序前准备
● account.txt:创建该文件用于存放信用卡账户信息
● savings.txt:创建该文件用于存放储蓄卡信息
● frozen.txt:创建该文件存放冻结账户信息,此文件初始化可为空
● goods:创建该文件存放购物的商品
● shopping_cart:创建该文件存放已购买的商品,此文件初始化可为空
● trade_log:创建该文件用于存放日志信息,此文件初始化可为空
四,程序脚本
main.py:脚本主程序入口
#-*-UTF-8-*-
import os
from core import bank
from core import login
from shopping_mail import shopping
import logging
from logging.handlers import RotatingFileHandler
# 获取日志文件的绝对路径
BASE_DIR = (os.path.dirname(os.path.abspath(__file__)))
# 设置日志格式
def log_format():
"""
设置日志格式
:return:
"""
file_name = (BASE_DIR + "\\trade_log")
login.file_exist_check(file_name)
logging.basicConfig(
filename=file_name,
level=logging.INFO,
format='[%(asctime)s] [%(filename)s:%(lineno)d] %(levelname)s %(message)s',
datefmt='%Y-%m-%d %H:%M:%S %p')
def main():
log_format() # 调用日志
# 显示登录首页服务平台选项
while True:
print('1.信用卡\n2.商城\n3.退出')
fm_server = input("请选择你的服务编号:")
if fm_server.isdigit():
fm_server = int(fm_server)
# 判断选项编号是否符合条件
if fm_server <= 3 and fm_server >= 0:
if fm_server == 1:
bank.credit_platform() # 进入信用卡服务平台
elif fm_server == 2:
username = bank.verify_password() # 用户登录账户密码验证
username = username[0]
shopping.shopping_service(username) # 进入购物商城
else:
print("\033[1;31m请输入规范的服务编号!\033[0m")
continue
else:
print("\033[1;31m错误的服务编号!\033[0m")
continue
if __name__ == '__main__':
main()
login.py:用户登录账户密码验证
#-*-UTF-8-*-
import os
import sys
import logging
# 获取账户文件绝对路径
BASE_DIR = (os.path.dirname(os.path.abspath(__file__)))
def configure_file(file_name, action):
"""
定义一个方法读取文件
:param file_name: 账户文件
:param action: 读操作
:return:返回读取账户文件结果
"""
with open(file_name, action, encoding='utf-8')as f:
file_line = f.readlines()
return file_line
def file_exist_check(file_name):
"""
检查文件是否存在
:param file_name:账户文件
"""
if not os.path.exists(file_name):
print("Error: file %s is not exist!!!" % file_name)
exit(2)
# 创建新用户
def create_account():
"""
创建一个新的账户
:return: 返回创建账户的结果
"""
file_name = (BASE_DIR + "\\account.txt") # 获取账户文件
file_exist_check(file_name) # 调用文件检查是否存在
while True:
loginSucces = False # 定义loginSucces为False
# 调用读取文件方法
file_line = configure_file(file_name, 'r')
new_user = input("请创建账户名:") # 获取用户输入的账户名
if new_user.isalpha():
for line in file_line:
line = eval(line)
user = line["account"][0]
# 判断输入的账户名是否在账户文件中
if new_user in user:
print("此用户名已存在!")
break
# 如果不存在就跳过
elif new_user not in user:
pass
else:
new_passwd = input("请创建账户密码:") # 获取用户输入的账户密码
# 把新创建的账户写入账户文件,并指定信用卡金额数
with open(file_name, 'a+', encoding="utf-8")as f:
f.write(
"{'account':[\'%s\',\'%s\'],'credit_money':\'%s\'}\n" %
(str(new_user), str(new_passwd), 500000))
loginSucces = True # 把loginSucces改为True
if loginSucces:
print("\033[1;32m账户创建成功\n请重新登录账号\033[0m")
return loginSucces
break
# 判断账户密码
def auth_name(func):
"""
定义一个装饰器
:param func: 装饰verify_password函数
:return: 返回账户密码验证的结果
"""
def wrapper_name():
"""
验证登录的账户密码
:return:
"""
while True:
loginSucces = False # 定义loginSucces为False
file_name = (BASE_DIR + "\\account.txt") # 获取账户文件
file_exist_check(file_name) # 检查账户文件
file_line = configure_file(file_name, 'r') # 读取账户文件
username = input('请输入账户名:').strip() # 获取输入的账户名
if username.isalpha(): # 判断输入的账户名是否是字符串
for line_username in file_line:
line_username = eval(line_username) # 转换成字典
# 判断输入的账户名是否在字典里
if username in line_username['account'][0]:
file_name = (BASE_DIR + "\\frozen.txt") # 获取冻结账户文件
file_exist_check(file_name) # 检查文件是否存在
file_line = configure_file(file_name, 'r') # 读取文件
if len(file_line) != 0: # 判断文件是否为空
# 如果不为空,检查输入的文件名是否在冻结文件里
for line_locking in file_line:
line_locking = eval(line_locking)
if username in line_locking['frozen_username']:
print("\033[1;31m该用户已被冻结!\033[0m")
logging.info(
"username:%s Frozen account" % username)
# 如果不在冻结文件里就提示输入密码
elif username not in line_locking['frozen_username']:
password = input('请输入账户密码:').strip()
# 如果密码跟账户文件里的不一致,提示密码错误信息,并要求重新输入账户密码
if password != line_username['account'][1]:
print(
"\033[1;31mPassword error!\033[0m")
logging.info(
'username:%s Password error!' % username)
continue
# 如果密码一致,输出欢迎信息
elif password == line_username['account'][1]:
print(
"\033[1;32mhonorific:%s Welcome to use credit card service\033[0m" %
username)
logging.info(
'username:%s login Success!' % username)
loginSucces = True
if loginSucces:
return username, loginSucces
# 如果文件是空的,提示输入密码
elif len(file_line) == 0:
password = input('请输入账户密码:').strip()
# 如果密码跟账户文件里的不一致,提示密码错误信息,并要求重新输入账户密码
if password != line_username['account'][1]:
print("\033[1;31mPassword error!\033[0m")
logging.info(
'username:%s Password error!' % username)
continue
# 如果密码一致,输出欢迎信息
elif password == line_username['account'][1]:
print(
"\033[1;32mhonorific:%s Welcome to use credit card service\033[0m" %
username)
logging.info(
'username:%s login Success!' % username)
loginSucces = True
if loginSucces:
return username, loginSucces
else:
continue # 递归检查
else:
print("\033[1;31m请输入正确的用户名和密码!\033[0m")
continue
else:
print("\033[1;31m请输入规范的用户名和密码!\033[0m")
continue
return wrapper_name
bank.py:信用卡服务主入口
#-*-UTF-8-*-
import os
import sys
import re
import logging
BASE_DIR = (os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASE_DIR) # 添加core目录的绝对路径
# 获取ATM目录的绝对路径
BASE_DIRR_REMOTE = (
os.path.dirname(
os.path.dirname(
os.path.abspath(__file__))))
from login import auth_name
from core import login
@auth_name
def verify_password(): # 定义装饰账户密码验证的函数
return 'ok'
def credit_platform():
"""
信用卡登录界面选项
"""
while True:
print('1.登录\n2.注册\n3.退出')
bk_server = input("请选择你的服务编号:")
if bk_server.isdigit():
bk_server = int(bk_server)
if bk_server <= 3 and bk_server >= 0:
if bk_server == 1:
# 调用装饰账户密码验证的函数
username, loginSucces = verify_password()
# 判断如果loginSucces的返回结果为Ture,进入信用卡服务平台
if str(loginSucces) == 'True':
user_menu(username)
elif bk_server == 2:
# 调用创建新账户功能,并判断是否创建成功
loginSucces = login.create_account()
# 判断如果loginSucces的返回结果为Ture,返回信用卡登录界面
if str(loginSucces) == 'True':
continue
# 退出信用卡登录界面
elif bk_server == 3:
break
else:
print("请输入规范的服务编号!")
continue
else:
print("错误的服务编号!")
continue
def user_menu(username):
"""
信用卡用户服务选项
:param username:登录的信用卡账户名
"""
while True:
print('1.提现\n2.还款\n3.转账\n4.查看额度\n5.冻结账户\n6.退出账户')
bk_server = input("请选择你的服务编号:")
if bk_server.isdigit():
bk_server = int(bk_server)
if bk_server <= 6 and bk_server >= 0:
if bk_server == 1:
creditcard(username) # 调用提取现金
elif bk_server == 2:
repayment_Savingsdeposit(username) # 调用信用卡还款
elif bk_server == 3:
# 调用信用卡转账
account_name_a, transfer_money = judge_account(username)
transfer_accounts(account_name_a, transfer_money)
elif bk_server == 4:
query_money(username) # 调用查询金额
elif bk_server == 5:
loginSucces = Frozen_account(username) # 调用冻结账户
if str(loginSucces) == 'True':
credit_platform()
elif loginSucces == 'False':
pass
elif bk_server == 6:
break # 退出信用卡服务平台
def credit_card_field(username, file_name, money_key, line):
"""
定义一个方法处理信用卡的金额变动
:param username: 信用卡账户名
:param file_name: 账户文件
:param money_key: 金额字段
:param line: 读取账户文件
:return: 返回两个金额数
"""
total_old = line[money_key]
total_new = line[money_key]
total_new = re.match("^\d\d*", total_new)
total_new = total_new.group()
total_new = int(total_new)
return total_old, total_new, line
def creditcard(username):
"""
服务类型:提取现金
扣取信用卡金额
:param username: 信用卡账户名
"""
# 获取账户文件
file_name = (BASE_DIRR_REMOTE + r"\core\account.txt")
# 检查账户文件是否存在
login.file_exist_check(file_name)
# 调用读取账户文件
file_line = login.configure_file(file_name, 'r')
while True:
with open(file_name, 'w', encoding="utf-8")as f:
for line in file_line:
line = eval(line) # 将每条账户信息转成字典
user = line["account"][0] # 获取账户名
# 如果账户名在这条字典里,就提示输入金额数
if username in user:
# 调用信用卡字段处理方法获取两个金额数
total_old, total_new, line = credit_card_field(
username, file_name, "credit_money", line)
draw_money = input("请输入提取的金额数:").strip()
if draw_money.isdigit():
draw_money = int(draw_money)
# 如果输入的金额数小于等于总金额数,就扣取金额
if draw_money <= total_new:
total_new -= draw_money # 减去金额
total_new *= 0.5 # 减去%5手续费金额
# 把新的金额数跟之前的金额数做替换并写入账户文件
line_update = str(line).replace(
str(total_old), str(total_new))
f.write("%s\n" % line_update)
# 调用日志文件记录扣取的金额数
logging.info(
"username:%s,business:Withdrawals,credit card---Amount of deducted amount:%s" %
(str(username), str(draw_money)))
# 调用现金储蓄文件,把扣取的金额数加入到文件中
savingsdeposit_card(username, draw_money)
continue # 递归查询账户文件
else:
print("取款数额超出信用卡金额范围!")
break
# 如果这个账户名不在这条字典里,直接写入原文件
else:
line = str(line)
f.write("%s\n" % line)
else:
break
def savingsdeposit_card(username, draw_money):
"""
服务类型:提取现金
存入金额到现金储蓄文件
:param username: 账户名
:param draw_money: 信用卡扣取的金额数
"""
# 获取储蓄文件
file_name = (BASE_DIRR_REMOTE + r"\core\savings.txt")
# 检查文件是否存在
login.file_exist_check(file_name)
# 读取储蓄文件
file_line = login.configure_file(file_name, 'r')
with open(file_name, 'w', encoding='utf-8')as f:
for line in file_line:
line = eval(line) # 将每条账户信息转成字典
user = line["cash_money"][0] # 获取账户名
# 如果账户名在这条字典里,就加上金额数并替换之前的金额数写入储蓄文件
if username in user:
line_old = line["cash_money"][1]
line_new = line["cash_money"][1]
line_new = int(line_new)
line_new += draw_money
line_update = str(line).replace(str(line_old), str(line_new))
f.write("%s\n" % line_update)
print("\033[1;32m----提现成功----\033[0m")
# 调用日志文件记录存入的金额数
logging.info(
"username:%s,business:Withdrawals,Memory card---Amount of deposit:%s" %
(str(username), str(draw_money)))
# 如果账户名不在这条字典里,直接写入原文件
else:
line = str(line)
f.write("%s\n" % line)
def repayment_Savingsdeposit(username):
"""
服务类型:信用卡还款
扣取储蓄文件金额
:param username: 账户名
"""
# 获取储蓄文件
file_name = (BASE_DIRR_REMOTE + r"\core\savings.txt")
# 检查文件是否存在
login.file_exist_check(file_name)
# 读取储蓄文件
file_line = login.configure_file(file_name, 'r')
while True:
with open(file_name, 'w', encoding='utf-8')as f:
for line in file_line:
line = eval(line) # 将每条账户信息转成字典
user = line["cash_money"][0] # 获取账户名
# 如果账户名在这条字典里,提示输入金额数
if username in user:
line_old = line["cash_money"][1]
line_new = line["cash_money"][1]
repay_money = input("请输入还款的金额数:").strip()
if repay_money.isdigit():
repay_money = int(repay_money)
line_new = int(line_new)
# 如果输入的金额数小于等于总金额数,就扣取金额并替换原来的金额数并写入储蓄文件
if repay_money <= line_new:
line_new -= repay_money
line_update = str(line).replace(
str(line_old), str(line_new))
f.write("%s\n" % line_update)
# 调用日志文件记录扣取的金额数
logging.info(
"username:%s,business:repayment,Memory card---Amount of deducted amount:%s" %
(str(username), str(repay_money)))
# 调用信用卡账户文件,把扣取的金额数加入到文件中
repayment_creditcard(username, repay_money)
else:
print("取款数额超出信用卡金额范围!")
break
else:
print("请输入规范的金额数!")
break
# 如果账户名不在这条字典里,直接写入原文件
else:
line = str(line)
f.write("%s\n" % line)
continue # 递归查询储蓄文件
else:
break
def repayment_creditcard(username, repay_money):
"""
服务类型:信用卡还款
存入金额到信用卡账户文件
:param username: 账户名
:param repay_money: 储蓄文件扣取的金额数
"""
# 获取账户文件
file_name = (BASE_DIRR_REMOTE + r"\core\account.txt")
# 检查文件是否存在
login.file_exist_check(file_name)
# 读取账户文件
file_line = login.configure_file(file_name, 'r')
with open(file_name, 'w', encoding='utf-8')as f:
for line in file_line:
line = eval(line) # 将每条账户信息转成字典
user = line["account"][0] # 获取账户名
# 如果账户名在这条字典里,就调用信用卡字段处理方法获取两个金额数
if username in user:
total_old, total_new, line = credit_card_field(
username, file_name, "credit_money", line)
total_new += repay_money # 加上金额数到信用卡账户文件
# 把新的金额数跟之前的金额数做替换,并写入信用卡账户文件
line_update = str(line).replace(str(total_old), str(total_new))
f.write("%s\n" % line_update)
print("\033[1;32m----还款成功----\033[0m")
# 调用日志文件记录存入的金额数
logging.info(
"username:%s,business:repayment,credit card---Amount of deposit:%s" %
(str(username), str(repay_money)))
else:
# 如果账户名不在这条字典里,直接写入原文件
line = str(line)
f.write("%s\n" % line)
def judge_account(username):
"""
服务类型:信用卡转账
信用卡账户转账服务
:param username: 账户名
:return 返回输入的账户名和扣取的金额数
"""
# 获取信用卡账户文件
file_name = (BASE_DIRR_REMOTE + r"\core\account.txt")
# 检查文件是否存在
login.file_exist_check(file_name)
# 读取信用卡账户文件
file_line = login.configure_file(file_name, 'r')
while True:
# 获取输入的两次账户名
account_name_a = input("请输入转账的用户名:").strip()
account_name_b = input("请再次输入转账的用户名:").strip()
# 判断账户名是否是字符串类型
if account_name_a.isalpha() and account_name_b.isalpha():
# 如果两次输入的账户名不一致打印错误信息,并要求重新输入
if account_name_a != account_name_b:
print("两次用户名不一致!")
continue
# 如果两次输入的账户名都等于当前登录的账户名,就提示错误信息,并要求重新输入
elif account_name_a == username and account_name_b == username:
print("不可以给自己转账!")
continue
else:
with open(file_name, 'r+', encoding='utf-8')as f:
# 将每条账户信息转成字典
for line_transfer_money in file_line:
line_transfer_money = eval(line_transfer_money)
# 获取每条字典的账户名
user = line_transfer_money["account"][0]
# 如果账户名在这条字典里就截取这条账户信息的金额数
if username in user:
total_old = line_transfer_money["credit_money"]
total_new = line_transfer_money["credit_money"]
# 获取输入的转账金额数
transfer_money = input("请输入转账的金额:").strip()
# 判断是否是整数类型
if transfer_money.isdigit():
transfer_money = int(transfer_money)
total_new = int(total_new)
# 如果输入的金额数小于等于总金额数,就扣取金额并替换原来的金额数并写入账户文件
if transfer_money <= total_new:
total_new -= transfer_money
line_update = str(line_transfer_money).replace(
str(total_old), str(total_new))
f.write("%s\n" % line_update)
# 调用日志文件记录扣取的金额数
logging.info(
"username:%s,business:Transfer accounts,credit card---Number of transfers:%s" %
(str(username), str(transfer_money)))
# 调用转账功能需要被转账的账户
# transfer_accounts(account_name_a,transfer_money)
else:
print("取款数额超出信用卡金额范围!")
break
else:
print("请输入规范的金额数!")
break
else:
# 如果账户名不在这条字典里,直接写入原文件
line_transfer_money = str(line_transfer_money)
f.write("%s\n" % line_transfer_money)
# transfer_accounts(account_name_a, transfer_money)
continue
else:
return account_name_a, transfer_money
def transfer_accounts(account_name_a, transfer_money):
"""
服务类型:信用卡转账
:param account_name_a: 被转账的账户名
:param transfer_money:信用卡账户扣取的金额数
"""
# 获取账户文件
file_name = (BASE_DIRR_REMOTE + r"\core\account.txt")
# 检查文件是否存在
login.file_exist_check(file_name)
# 读取账户文件
file_line = login.configure_file(file_name, 'r')
while True:
with open(file_name, 'r+', encoding='utf-8')as f:
for line_transfer_money in file_line:
line_transfer_money = eval(line_transfer_money) # 将每条账户信息转成字典
user = line_transfer_money["account"][0] # 获取每条字典的账户名
# 如果账户名在这条字典里就将金额数加到总金额数,并替换字典原来的金额数后写入账户文件
if account_name_a in user:
line_old = line_transfer_money["credit_money"]
line_new = line_transfer_money["credit_money"]
line_new = int(line_new)
line_new += transfer_money
line_update = str(line_transfer_money).replace(
str(line_old), str(line_new))
f.write("%s\n" % line_update)
print("\033[1;32m----转账成功----\033[0m")
# 调用日志文件记录存入的金额数
logging.info(
"username:%s,business:Transfer accounts,Memory card---Amount of deposit:%s" %
(str(account_name_a), str(transfer_money)))
else:
# 如果账户名不在这条字典里,直接写入原文件
line_transfer_money = str(line_transfer_money)
f.write("%s\n" % line_transfer_money)
else:
break
def query_money(username):
"""
查询信用卡账户余额
:param username: 账户名
"""
# 获取账户文件
file_name = (BASE_DIRR_REMOTE + r"\core\account.txt")
# 检查文件是否存在
login.file_exist_check(file_name)
# 读取账户文件
file_line = login.configure_file(file_name, 'r')
for line in file_line:
line = eval(line) # # 将每条账户信息转成字典
user = line["account"][0] # 获取每条字典的账户名
# 如果账户名在这条字典里,就打印这个账户的余额信息
if username in user:
print('%s\n用户名:%s 信用卡剩余余额:%s\n%s\n' %
('=' * 50, username, line['credit_money'], '=' * 50))
def Frozen_account(username):
"""
冻结账户
:param username: 账户名
:return 返回冻结账户是否成功状态
"""
# 获取冻结文件
file_name = (BASE_DIRR_REMOTE + r"\core\frozen.txt")
# 检查文件是否存在
login.file_exist_check(file_name)
# 读取冻结文件
file_line = login.configure_file(file_name, 'r')
while True:
loginSucces = False
# 如果文件的行数不等于0,就把每条信息转成字典
if len(file_line) != 0:
for line_locking in file_line:
line_locking = eval(line_locking)
# 如果账户名在冻结文件里就输出打印信息
if username in line_locking['frozen_username']:
print("该账户已处于冻结状态!")
# 如果账户名不在冻结文件里,就输出是否冻结该用户提示
elif username not in line_locking['frozen_username']:
locking = input("是否确定冻结该账户?y/n:")
if locking.isalpha():
# 如果等于y,就把该账户名追加写入冻结文件,并返回loginSucces状态
if locking == "y":
with open(file_name, 'a+', encoding='utf-8')as f:
f.write(
"\n{'frozen_username':'%s'}" %
username)
print("\033[1;32m该账户冻结成功!\033[0m")
loginSucces = True
return loginSucces
# 如果等于n,直接返回loginSucces状态
elif locking == "n":
return loginSucces
else:
print("错误的选项请重新输入!")
continue
else:
print("输入的数据类型不符合规范,请重新输入!")
continue
# 如果行数等于0,就输出是否冻结该账户提示
if len(file_line) == 0:
locking = input("是否确定冻结该账户?y/n:")
if locking.isalpha():
# 如果等于y,就把该账户名追加写入冻结文件,并返回loginSucces状态
if locking == "y":
with open(file_name, 'w', encoding='utf-8')as f:
f.write("{'frozen_username':'%s'}\n" % username)
print("\033[1;32m该账户冻结成功!\033[0m")
loginSucces = True
return loginSucces
# 如果等于n,直接返回loginSucces状态
elif locking == "n":
return loginSucces
else:
print("\033[1;31m错误的选项请重新输入!\033[0m")
continue
else:
print("\033[1;31m输入的数据类型不符合规范,请重新输入!\033[0m")
continue
shopping.py:购物商城主入口
#-*-UTF-8-*-
import os
import sys
import time
import re
import logging
# 获取shopping_mail目录的绝对路径
BASE_DIR_LOCAL = (os.path.dirname(os.path.abspath(__file__)))
# 获取ATM目录的绝对路径
BASE_DIR = (os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from core import login
from core import bank
# 定义一个空列表
#shopping_list = []
def shopping_bar_view(username):
"""
查看购物栏内已购买的物品信息
:param username: 用户名
"""
# 获取购物栏文件
file_name = (BASE_DIR_LOCAL + r"\shopping_cart")
# 检查文件是否存在
login.file_exist_check(file_name)
# 读取购物栏文件
file_line = login.configure_file(file_name, 'r')
if len(file_line) != 0:
for line in file_line:
line = eval(line)
# 如果查到用户名就打印此用户的所有已购物品信息
if username in line.keys():
print(
"已购买的物品:\n%s\n%s\n" %
(line[username]["goods"], '=' * 50))
def configure_file(username, file_name, shopping_list):
"""
新用户已购物品写入购物栏文件
:param username: 用户名
:param file_name: 购物栏文件名
:param shopping_list: 购物列表
"""
with open(file_name, 'w', encoding='utf-8')as f:
f.write("{\"%s\":{\"goods\":%s}}\n" % (username, shopping_list))
logging.info("username:%s,Already purchased:%s" %
(str(username), str(shopping_list)))
def already_exists_configure_file(username, file_name, shopping_list):
"""
已存在购物栏的用户再次写入已购物品到购物栏文件
:param username: 用户名
:param file_name: 购物栏文件名
:param shopping_list: 购物列表
"""
with open(file_name, 'r+', encoding='utf-8')as f:
login.file_exist_check(file_name)
file_line = login.configure_file(file_name, 'r')
for line in file_line:
line = eval(line)
# 如果查到用户名在这条字典里,就获取这个用户的购物列表项
if username in line.keys():
line_user = line[username]["goods"]
line_old = line_user
line_new = line_user
# 将购物列表添加到购物栏的购物列表里
line_new.extend(shopping_list)
# 替换旧的购物栏购物列表并写入购物栏文件里
line_updat = str(line).replace(str(line_old), str(line_new))
f.write("%s\n" % line_updat)
# 调用日志文件记录新的购物列表信息
logging.info(
"username:%s,Buy again:%s" %
(str(username), str(shopping_list)))
else:
# 如果查不到用户名在这条字典里,就直接写入原文件
line = str(line)
f.write("%s\n" % line)
def shopping_bag(file_line):
"""
打印出购物商品列表
:param file_line: 购物商品文件名
:return: 返回用户输入的商品编号跟商品名
"""
line = [line.strip() for line in file_line]
for index, line in enumerate(line):
print(index, line)
purchase = input("请选择你要的商品:")
return purchase, file_line
def commodity_payment(username, sum, BASE_DIR):
"""
商品结账付款
:param username: 用户名
:param sum: 付款金额
:param BASE_DIR: 账户文件名
"""
# 获取账户文件
file_name = (BASE_DIR + r"\core\account.txt")
# 检查文件是否存在
login.file_exist_check(file_name)
# 读取账户文件
file_line = login.configure_file(file_name, 'r')
with open(file_name, 'r+', encoding="utf-8")as f:
for line_creditcard in file_line:
line_creditcard = eval(line_creditcard)
user = line_creditcard["account"][0] # 获取账户名
# 如果账户名在这条字典里,就获取这个用户的信用卡金额
if username in user:
total_old = line_creditcard["credit_money"]
total_new = line_creditcard["credit_money"]
total_new = re.match("^\d\d*", total_new)
total_new = total_new.group()
total_new = int(total_new)
sum = int(sum)
# 如果付款金额数小于等于信用卡金额数,就扣取付款金额并替换旧的信用卡金额数写入原文件
if sum <= total_new:
total_new -= sum
line = str(line_creditcard).replace(
str(total_old), str(total_new))
f.write("%s\n" % line)
# 调用日志文件记录扣取的金额数并打印输出信息
logging.info(
"username:%s,Total deductions:%s" %
(str(username), str(sum)))
print("\033[1;32m付款成功!\033[0m")
# 如果账户名不在这条字典里,就直接写入原文件,继续循环下一条字典
else:
line = str(line_creditcard)
f.write("%s\n" % line)
def shopping_once(username):
"""
用户第一次购买商品入口
:param username: 用户名
"""
shopping_list = [] # 定义一个空的购物列表
while True:
# 获取商品文件
file_name = (BASE_DIR_LOCAL + r"\goods")
# 检查文件是否存在
login.file_exist_check(file_name)
# 读取商品文件
file_line = login.configure_file(file_name, 'r')
# 调用打印购物商品列表函数
purchase, goods_file = shopping_bag(file_line)
if purchase.isdigit():
purchase = int(purchase)
# 如果返回的商品编号小于商品文件的总行数并且大于0
if purchase < len(goods_file) and purchase >= 0:
# 获取这个编号的商品并以逗号分割成列表
commodity = goods_file[purchase]
commodity = commodity.strip().split(',')
# 把商品添加到空的购物列表里,并输出打印shopping_list
shopping_list.append(commodity)
print("Have buy goods:%s" % shopping_list)
# 获取用户输入的选项
Whether_payment = input("是否确定付款y或n:")
if Whether_payment.isalpha():
Whether_payment = str(Whether_payment)
if Whether_payment == 'y':
print("正在付款中。。。。")
sum = 0 # 定义一个初始值便于累加金额数
# 循环获取购物列表的每个商品的金额数
for total_line in shopping_list:
goods_money = total_line[1]
goods_money = int(goods_money)
sum += goods_money # 把所有商品的金额数进行累加
# 调用商品结账付款入口
commodity_payment(username, sum, BASE_DIR)
# 获取购物栏文件
file_name = (BASE_DIR_LOCAL + "\\shopping_cart")
# 检查文件是否存在
login.file_exist_check(file_name)
# 调用把物品写入购物栏入口
configure_file(username, file_name, shopping_list)
print("商品交易完成")
while True:
# 交易完成后,打印输出信息
print("继续购买:y\n查看已购买的物品:l\n退出商城:q\n")
# 获取用户输入的选项
user_option = input("请选择服务选项:")
if user_option.isalpha():
if str(user_option) == 'y':
# 调用再次购物商品入口
shopping_secondary(username)
elif str(user_option) == 'l':
# 调用打印购物栏列表
shopping_bar_view(username)
continue
elif str(user_option) == 'q':
exit("\033[1;32m欢迎下次光临!\033[0m") # 退出购物商城
else:
print("\033[1;31m请输入规范的选项!\033[0m")
continue
# 如果是n,回到购物商品选项列表
elif Whether_payment == 'n':
continue
else:
print("\033[1;31m请输入规范的选项!\033[0m")
continue
def shopping_secondary(username):
"""
用户再次商品购物入口
:param username:用户名
"""
shopping_list = [] # 定义一个空的购物列表
while True:
# 获取商品文件
file_name = (BASE_DIR_LOCAL + r"\goods")
# 检查文件是否存在
login.file_exist_check(file_name)
# 读取商品文件
file_line = login.configure_file(file_name, 'r')
# 调用打印购物商品列表函数
purchase, goods_file = shopping_bag(file_line)
if purchase.isdigit():
purchase = int(purchase)
# 如果返回的商品编号小于商品文件的总行数并且大于0
if purchase < len(goods_file) and purchase >= 0:
# 获取这个编号的商品并以逗号分割成列表
commodity = goods_file[purchase]
commodity = commodity.strip().split(',')
# 把商品添加到空的购物列表里,并输出打印shopping_list
shopping_list.append(commodity)
print("Have buy goods:%s" % shopping_list)
# 获取用户输入的选项
Whether_payment = input("是否确定付款y或n:")
if Whether_payment.isalpha():
Whether_payment = str(Whether_payment)
if Whether_payment == 'y':
print("正在付款中。。。。")
sum = 0 # 定义一个初始值便于累加金额数
# 循环获取购物列表的每个商品的金额数
for total_line in shopping_list:
goods_name = total_line[0]
goods_money = total_line[1]
goods_money = int(goods_money)
sum += goods_money # 把所有商品的金额数进行累加
# 调用商品结账付款入口
commodity_payment(username, sum, BASE_DIR)
# 获取购物栏文件
file_name = (BASE_DIR_LOCAL + "\\shopping_cart")
# 检查文件是否存在
login.file_exist_check(file_name)
# 调用把物品写入购物栏入口
already_exists_configure_file(
username, file_name, shopping_list)
print("商品交易完成")
while True:
# 交易完成后,打印输出信息
print("继续购买:y\n查看已购买的物品:l\n退出商城:q\n")
user_option = input("请选择服务选项:")
if user_option.isalpha():
if str(user_option) == 'y':
continue # 返回继续购物
elif str(user_option) == 'l':
# 调用打印购物栏列表
shopping_bar_view(username)
continue
elif str(user_option) == 'q':
exit("\033[1;32m欢迎下次光临!\033[0m") # 退出购物商城
else:
print("\033[1;32m请输入规范的选项!\033[0m")
continue
# 如果是n,回到购物商品选项列表
elif Whether_payment == 'n':
continue
else:
print("\033[1;31m请输入规范的选项!\033[0m")
continue
def shopping_service(username):
"""
用户进入商品购物系统平台主入口
:param username: 用户名
"""
# 获取购物栏文件
file_name = (BASE_DIR_LOCAL + r"\shopping_cart")
# 检查文件是否存在
login.file_exist_check(file_name)
# 读取购物栏文件
file_line = login.configure_file(file_name, 'r')
# 如果文件的总行数不等于0,就把每行都转成字典
if len(file_line) != 0:
for line in file_line:
line = eval(line)
# 如果用户名在其中一条字典里,就打印输出该用户的购物历史
if username in line.keys():
print("购物历史:\n%s\n%s\n" % (line[username]["goods"], '=' * 50))
# 调用用户再次商品购物入口进行购物
shopping_secondary(username)
# 如果用户名不在这条字典里,就继续检查下一条字典
elif username not in line.keys():
continue
# 如果用户名都不在字典里,就调用用户第一次商品购物入口
else:
shopping_once(username)
# 如果文件的总行数不等于0,就调用用户第一次商品购物入口
else:
shopping_once(username)