ATM与购物商城

模拟实现一个ATM + 购物商城程序

  1. 额度 15000或自定义
  2. 实现购物商城,买东西加入 购物车,调用信用卡接口结账
  3. 可以提现,手续费5%
  4. 支持多账户登录
  5. 支持账户间转账
  6. 记录每月日常消费流水
  7. 提供还款接口
  8. ATM记录操作日志
  9. 提供管理接口,包括添加账户、用户额度,冻结账户等。。。
  10. 用户认证用装饰器

readme:

程序总入口是start.py
bank下是关于ATM相关的内容
shopping_mall下购物商城相关内容
logs下是存储的日志
database下是商城和ATM的相关数据,两者中分别有“初始数据.py”将原始数据存入

start
from bank import ATM
from shopping_mall import mall

def destination():
    choice = input("请选择前往地:
"
                   "1、购物商城
"
                   "2、银行
"
                   "请选择要执行的编号:" )
    if choice == "1":
        mall.shopping()
    if choice == "2":
        ATM.opt()

destination()

 

bank_>ATM

from bank import confirm_a
from bank import main
from bank import manage

def atm(user_status):
    """
    在atm中选择要执行的内容
    :param user_status:
    :return:
    """
    atm_exit = True
    while atm_exit:
        choice =input( "33[32;1m ---------------Welcome %s---------------33[0m 
" 
                     "1. 查看账户信息
" 
                     "2. 存款
"
                     "3. 取款
" 
                     "4. 转账
" 
                     "5. 还款
" 
                     "6. 查看账单
"
                     "q. 退出
" 
                     "请选择要执行的编号:" %user_status["id"])
        menu = {
            "1": main.check_note,
            "2": main.deposit,
            "3": main.withdraw,
            "4": main.transfer,
            "5": main.repayment,
            "6": main.bill,
            "q": main.end
        }
        if choice in menu:
            # operate = menu[choice].__name__
            menu[choice](user_status)


def enter():
    """
    将用户名和密码进行验证,并且存到user_status中,方便后续调用
    :return:
    """
    user_status= {"state":False,
                  "id":None,
                  "usermsg":None}
    while user_status["state"] is False:
        acc_name = input("请输入账户名称:").strip()
        acc_msg = confirm_a.confirm(acc_name)
        if acc_msg:
            user_status["state"] = True
            user_status["id"] = acc_name
            user_status["usermsg"] = acc_msg
            atm(user_status)


def opt():
    """
    选择进入管理员入口还是atm入口
    :return:
    """
    opt_exit = True
    while opt_exit:
        choice = input("1、用户入口
"
                       "2、管理员入口
"
                       "q、退出
"
                       "请选择要执行的编号:")
        if choice == "1":
           enter()
        elif choice == "2":
            manage.admin()
        elif choice == "q":
            opt_exit = False

  bank->centre

import time
from conf import settings
from bank import logger,db_handle_a

def center(account,tran_type,amount,user_status):    # account,"deposit",amount,user_status
    """
    根据不同的交易类型对不同类型的银行卡进行金额的加减
    :param account: 具体银行卡,以及对应的编码
    :param tran_type: 交易类型
    :param amount: 交易金额
    :param user_status: 包含登录状态、账户名、账户信息的变量
    :return:
    """
    if tran_type in settings.TRANS_TYPE_S:
        if account[1]["classify"] == "信用卡":
            interest = amount * settings.TRANS_TYPE_CRED[tran_type]["interest"]    # 利息
            old_debt = account[1]["debt"]
            old_balance = account[1]["balance"]
            if settings.TRANS_TYPE_CRED[tran_type]["mode"]  == "plus":
                new_balance = old_balance + amount - interest
                new_debt = old_debt - amount
            elif settings.TRANS_TYPE_CRED[tran_type]["mode"] == "subtract":
                new_balance = old_balance - amount - interest
                new_debt = old_debt + amount
            if new_balance < 0:
                print("余额不足,当前余额为%s" % old_balance)
            else:
                print("交易成功")
                account[1]["balance"] = new_balance
                account[1]["debt"] = new_debt
                user_status["usermsg"]["data"][account[0] - 1] = account[1]
                account_num = str(account[0])
                account_name = account[1][account_num]
                r_key = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
                record_msg = "num:%s account:%s mode:%s amount:%s interest:%s balance:%s debt:%s"% 
                             (account[0], account_name, tran_type, amount, interest, new_balance,new_debt)
                user_status["usermsg"]["record"][account_name][r_key] = record_msg

                logger.logger_bk(user_status["id"], tran_type)
                logger.logger_month(user_status["id"], record_msg)

        elif account[1]["classify"] == "储蓄卡":
            interest = amount * settings.TRANS_TYPE_S[tran_type]["interest"]      # 利息
            old_balance = account[1]["balance"]
            if settings.TRANS_TYPE_S[tran_type]["mode"]  == "plus":
                new_balance = old_balance + amount + interest
            elif settings.TRANS_TYPE_S[tran_type]["mode"]  == "subtract":
                new_balance = old_balance - amount - interest
            if new_balance < 0:
                print("余额不足,当前余额为%s"%old_balance)
            else:
                print("交易成功")
                account[1]["balance"] = new_balance  # account = (2, {'2': '银行卡1', 'balance': 10000, 'classify': '储蓄卡', 'expiry': '2025-11-10'})
                user_status["usermsg"]["data"][account[0]-1] = account[1]
                account_num = str(account[0])
                account_name = account[1][account_num]
                r_key = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
                record_msg = "num:%s account:%s mode:%s amount:%s interest:%s balance:%s"%
                             (account[0],account_name,tran_type,amount,interest,new_balance)
                user_status["usermsg"]["record"][account_name][r_key] = record_msg

                logger.logger_bk(user_status["id"], tran_type)
                logger.logger_month(user_status["id"], record_msg)

        db_handle_a.json_stroage(user_status["id"],user_status["usermsg"])
        return
    else:
        print("该交易类型不存在")
        return

  bank->confirm_a

import hashlib
from bank import db_handle_a

def confirm(username):
    """
    验证输入的用户名和密码是否正确,正确读取文件内容
    :param username:
    :return: 读取的文件内容
    """
    usermsg = db_handle_a.json_read(username)
    count = 0
    while count < 3:
        passwd = input("请输入密码:").strip()
        m = hashlib.md5()
        m.update(passwd.encode("utf-8"))
        passwd = m.hexdigest()
        if passwd == usermsg["password"]:
            count = 3
            if usermsg["status"]:
                return usermsg
                # print("33[32;1m Welcome33[0m", name)
            else:
                print("33[35;1m 用户名已被锁定33[0m")
        else:
            count += 1
            if not count == 3:
                print("33[35;1m 密码错误,还有%s次机会!33[0m" %(3 - count))
            else:
                print("33[35;1m 密码错误,帐号被锁定33[0m")
                usermsg["status"] = 0
                db_handle_a.json_stroage(username,usermsg)

def verify(func):
    def inner(user_status,*args,**kwargs):
        if user_status["state"] == False:
            acc_name = input("请输入账户名称:").strip()
            acc_msg = confirm(acc_name)
            user_status["state"] = True
            user_status["id"] = acc_name
            user_status["usermsg"] = acc_msg
        else:
            func(user_status)
    return inner

  bank->db_handler-a

import os,json
from conf import settings

def json_read(username):
    """
    读取用户名对应文件内容
    :param username: 用户名
    :return: 文件内容
    """
    filename = os.path.join(settings.BANK_PATH,username +".json")
    if os.path.isfile(filename):
        data = json.load(open(filename, "r", encoding="utf-8"))
        return data
    else:
        print("33[37;1m用户名无效33[0m")
        exit()

def json_stroage(username,msg):
    """
    将内存中的内容存储到文件中
    :param username: 文件名
    :param msg: 将要存储的内容
    :return:
    """
    filename = os.path.join(settings.BANK_PATH, username + ".json")
    if os.path.isfile(filename):
        f = open(filename+ ".new", "w", encoding="utf-8")
        json.dump(msg,f)
        f.close()
        os.replace(filename + ".new",filename)
        return msg
    else:
        f = open(filename, "w", encoding="utf-8")
        json.dump(msg, f)
        exit()

  bank->logger

import os,logging
from logging import handlers
from conf import settings

def logger_bk(name,message):
    """
    ATM操作日志,文档记录
    :param name: 记录执行操作的用户名
    :param message: 记录执行的操作
    :return:
    """
    logger_path = os.path.join(settings.LOGGER_PATH,"atm_logger.log")
    fomatter = logging.Formatter('%(asctime)s - %(levelname)s - %(name)s - %(message)s')
    fh = logging.FileHandler(logger_path,encoding='utf-8')
    fh.setLevel(settings.LOGGER_LEVEL)
    fh.setFormatter(fomatter)
    logger = logging.getLogger(name)
    logger.setLevel(settings.LOGGER_LEVEL)
    logger.addHandler(fh)
    logger.info(message)
    print(id(logger))
    print(logger.handlers)


def logger_month(name,message):
    """
    间隔30天记录用户在ATM机上的消费记录
    :param name: 记录执行操作的用户名
    :param message: 记录执行的操作
    :return:
    """
    logger_path = os.path.join(settings.LOGGER_PATH, name+".log")
    fh = handlers.TimedRotatingFileHandler(filename=logger_path,when ="D",interval=30,backupCount=30,encoding='utf-8')
    fomatter = logging.Formatter('%(asctime)s - %(levelname)s - %(name)s - %(message)s')
    fh.setLevel(settings.LOGGER_LEVEL)
    fh.setFormatter(fomatter)
    logger = logging.getLogger(name)
    logger.setLevel(settings.LOGGER_LEVEL)
    logger.addHandler(fh)
    logger.info(message)
    print(id(logger))
    print(logger.handlers)

  bank-main

import os,sys,time
from bank import logger,confirm_a,db_handle_a,centre
from shopping_mall import db_handle_s

@confirm_a.verify
def check_note(user_status,acc_type="check_note"):
    """
    ATM 中打印账户信息,并在日志中记录
    :param user_status: ATM.enter函数中包含登录状态、账户名、账户信息的变量
    :param acc_type: 交易类型
    :return:
    """
    user_msg = user_status["usermsg"]["data"]
    print("33[32;1m ---------------账户信息---------------33[0m" )
    for i in user_msg:
        print(i)
    logger.logger_bk(user_status["id"], acc_type)
    logger.logger_month(user_status["id"], acc_type)


def print_acc(user_msg):
    """
    ATM 中打印账户信息
    :param usermsg: 该账户的所有信息
    :return:
    """
    print("33[32;1m ---------------账户信息---------------33[0m" )
    for i in user_msg:
        print(i)


def choice_acc(msg_list,mode):
    """
    同一账户名下有多张银行卡,选择其中的银行卡,进行之后需求
    :param msg_list: 所有卡信息以列表形式传入
    :param mode: 后续需求的目的
    :return:返回所选银行卡信息及编号
    """
    while True:
        num = input("请选择%s账户:" %mode)
        if num.isdigit:
            if int(num) <= len(msg_list):
                for i in msg_list:
                    if num in i:
                        num = int(num)
                        msg = msg_list[num-1]
                        timer = time.strftime("%Y-%m-%d", time.localtime(time.time()))
                        if msg["expiry"] > timer:
                            return num,msg
                        else:
                            print("33[31;1m该银行卡已到期!无法正常使用33[0m")
        elif num == "q":
            return
        else:
            print("输入错误,请重新输入")

@confirm_a.verify
def deposit(user_status,acc_type = "deposit"):
    """
    存款
    :param user_status: ATM.enter函数中包含登录状态、账户名、账户信息的变量
    :param acc_type: 交易类型
    :return:
    """
    user_msg = user_status["usermsg"]["data"]
    print_acc(user_msg)
    mode = "存款"
    account = choice_acc(user_msg,mode)
    deposit_exit = True
    while deposit_exit:
        amount = input("请输入存款金额:")
        if len(amount) > 0 and amount.isdigit():
            amount = int(amount)
            centre.center(account, acc_type, amount, user_status)
        if amount == "q":
            deposit_exit = False

@confirm_a.verify
def withdraw(user_status,acc_type = "withdraw"):
    """
    取款
    :param user_status: ATM.enter函数中包含登录状态、账户名、账户信息的变量
    :param acc_type: 交易类型
    :return:
    """
    user_msg = user_status["usermsg"]["data"]
    print_acc(user_msg)
    mode = "取款"
    account = choice_acc(user_msg,mode)
    withdraw_exit = True
    while withdraw_exit:
        amount = input("请输入取现金额:").strip()
        if len(amount) > 0 and amount.isdigit():
            amount = int(amount)
            if amount <= account[1]["balance"]:
                centre.center(account, acc_type, amount, user_status)
            else:
                print("余额不足,可提现%s"%account[1]["balance"])
        if amount == "q":
            withdraw_exit = False

@confirm_a.verify
def bill(user_status,acc_type = "bill"):
    """
    查看账单
    :param user_status: ATM.enter函数中包含登录状态、账户名、账户信息的变量
    :param acc_type: 交易类型
    :return:
    """
    user_msg=user_status["usermsg"]["data"]
    mode = "查看账单"
    print_acc(user_msg)
    account = choice_acc(user_msg, mode)
    acc_msg = account[1]
    num = str(account[0])
    for i in user_status["usermsg"]["record"][acc_msg[num]]:
        print(i,user_status["usermsg"]["record"][acc_msg[num]][i])
        logger.logger_bk(user_status["id"], acc_type)
        logger.logger_month(user_status["id"], acc_type)

@confirm_a.verify
def trans_same(user_status,acc_type = "transfer_out"):
    """
    同行转账
    :param user_status: ATM.enter函数中包含登录状态、账户名、账户信息的变量
    :param acc_type: 交易类型
    :return:
    """
    user_msg = user_status["usermsg"]["data"]
    print_acc(user_msg)
    mode = "转出"
    account_out = choice_acc(user_msg, mode)
    mode = "转入"
    account_into = choice_acc(user_msg, mode)
    trans_same_exit = True
    while trans_same_exit:
        amount = input("请输入转出金额:").strip()
        if len(amount) > 0 and amount.isdigit():
            amount = int(amount)
            if amount <= account_out[1]["balance"]:
                centre.center(account_out, acc_type, amount, user_status)
                centre.center(account_into, "transfer_into", amount, user_status)
            else:
                print("余额不足,可提现%s" % account_out[1]["balance"])
        if amount == "q":
            trans_same_exit = False


def trans_differ(user_status,acc_type = "transfer_out",*args):   # account_outter,amount
    """
    跨行转账
    :param user_status: ATM.enter函数中包含登录状态、账户名、账户信息的变量
    :param acc_type: 交易类型
    :param args: 外部连接时,传入账户名和转账金额
    :return:
    """
    user_msg = user_status["usermsg"]["data"]
    print_acc(user_msg)
    mode = "转出"
    account_out = choice_acc(user_msg, mode)
    mode = "转入"
    if len(args) != 0:
        account_into_name = args[0]["id"]
        account_into = args[0]["data"]
        amount = str(args[1])
        ask = "2"
    elif len(args) == 0:
        ask_exit = True
        while ask_exit:
            ask = input("1、内部账号转账
"
                        "2、外部账号转账
"
                        "请选择要执行的编号:")
            if ask == "1":
                account_into = choice_acc(user_msg, mode)
            elif ask == "2":
                account_into_name = input("请输入转入账户").strip()  # "account_mall"
                account_into = db_handle_s.json_read(account_into_name, "mall_db")
                ask_exit = False
            else:
                print("输入无效,请重新输入")
        amount = input("请输入转出金额:").strip()
    trans_differ_exit = True
    while trans_differ_exit:
        if len(amount) > 0 and amount.isdigit():
            amount = int(amount)
            if amount <= account_out[1]["balance"]:
                centre.center(account_out, acc_type, amount, user_status)
                if ask == "1":
                    centre.center(account_into, "transfer_into", amount, user_status)
                elif ask == "2":
                    account_into["balance"] = account_into["balance"] + amount
                    db_handle_s.json_stroage(account_into_name, "mall_db", account_into)
                    print("交易成功")
                    return
            else:
                print("余额不足,可提现%s" % account_out[1]["balance"])
        if amount == "q":
            trans_differ_exit = False


def external(aouncc_outer,amount):
    """
    连接商城支付
    :param aouncc_outer: 商城账户
    :param amount: 消费金额
    :return:
    """
    user_status= {"state":False,
                  "id":None,
                  "usermsg":None}
    acc_name = input("请输入账户名称:").strip()
    acc_msg = confirm_a.confirm(acc_name)
    if acc_msg:
        user_status["state"] = True
        user_status["id"] = acc_name
        user_status["usermsg"] = acc_msg
    trans_differ(user_status,"transfer_out",*(aouncc_outer,amount))


@confirm_a.verify
def transfer(user_status,acc_type = "transfer"):
    """
    转账总入口
    :param user_status: ATM.enter函数中包含登录状态、账户名、账户信息的变量
    :param acc_type: 交易类型
    :return:
    """
    mode = "转账"
    way = input("请选择转账方式:
"
                "1.同行转账
"
                "2.跨行转账
"
                "请选择要执行的编号:")
    menu = {"1": trans_same,
            "2": trans_differ}
    if way in menu:
       menu[way](user_status,acc_type = "transfer_out")


@confirm_a.verify
def repayment(user_status,acc_type = "repayment"):
    """
    还款总入口
    :param user_status:
    :param acc_type:
    :return:
    """
    mode = "还款"
    way = input("请选择还款方式:
"
                "1、转账
"
                "2、存款
"
                "请选择要执行的编号:")
    menu = {"1":transfer,
            "2":deposit}
    if way in menu:
        menu[way](user_status,acc_type = "repayment")


def end(user_status,acc_type = "end"):
    exit()

  bank->manager

import os,sys,time,json,hashlib,datetime

from bank import db_handle_a,logger

def common(usermsg,name):
    """
    增加银行卡中的具体内容
    :param usermsg: 账户所有信息
    :param name: 账户名
    :return:
    """
    user_msg = usermsg["data"]
    num = len(user_msg)
    num = str(num+1)
    new_data = {num: "", "balance": "", "classify": ""}
    card = True
    while card:
        ask = input("信用卡(c)还是储蓄卡(d)?")
        if ask == "c":
            new_data["classify"] = "信用卡"
            new_data["balance"] = int(input("请输入用户额度"))
            card = False
        elif ask == "d":
            new_data["classify"] = "储蓄卡"
            new_data["balance"] = int(input("请输入存入金额:"))
            card = False
        elif ask == "q":
            card = False
        else:
            print("无效输入,请重新输入")
    card_name = input("请输入银行卡名:")
    new_data[num] = card_name
    new_data["expiry"] = (datetime.datetime.now()+datetime.timedelta(days=3650)).strftime("%Y-%m-%d")
    r_key = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
    new_msg = "创建新卡"
    usermsg["record"][card_name] = {}
    usermsg["record"][card_name][r_key] = new_msg
    user_msg.append(new_data)
    return usermsg

def add_new_card():
    """
    为已存在的账户添加银行卡
    :return:
    """
    name = input("请输入账户名:").strip()
    usermsg = db_handle_a.json_read(name)
    usermsg = common(usermsg,name)
    record_msg = "添加新银行卡" + name
    logger.logger_bk(name, record_msg)
    logger.logger_month(name, record_msg)
    db_handle_a.json_stroage(name,usermsg)
    manage_exit = False


def add_new_acc():
    """
    创建新的账户
    :return:
    """
    name = input("请输入账户名:").strip()
    password = input("请输入密码:")
    m = hashlib.md5
    m.update(password.encode("utf-8"))
    password = m.hexdigest()
    usermsg = {"password": password,
            "status": 1,
            "data": [],
            "record": {}
            }
    usermsg = common(usermsg,name)
    timmer = time.strftime('%Y-%m-%d', time.localtime(time.time()))
    record_msg = "建立账户" + name + timmer
    logger.logger_bk(name, record_msg)
    logger.logger_month(name, record_msg)
    db_handle_a.json_stroage(name,usermsg)
    manage_exit = False


def frozen():
    """
    冻结或解锁账户
    :return:
    """
    name = input("请输入账户名:").strip()
    usermsg = db_handle_a.json_read(name)
    frozen_exit = True
    while frozen_exit:
        if usermsg["status"] == 1:
            ask = input("是否冻结账户?")
            if ask == "y":
                usermsg["status"] = 0
                logger.logger_bk(name, "冻结账户")
                logger.logger_month(name, "冻结账户")
                frozen_exit = False
            elif ask == "n" or ask == "q":
                frozen_exit = False
            else:
                print("输入错误!")
        elif usermsg["status"] == 0:
            ask = input("是否解锁账户?")
            if ask == "y":
                usermsg["status"] = 1
                logger.logger_bk(name, "解锁账户")
                logger.logger_month(name, "解锁账户")
                frozen_exit = False
            elif ask == "n" or ask == "q":
                frozen_exit = False
            else:
                print("输入错误!")
    db_handle_a.json_stroage(name,usermsg)


def modify():
    """
    修改账户用户额度
    :return:
    """
    name = input("请输入账户名:").strip()
    usermsg = db_handle_a.json_read(name)
    user_msg = usermsg["data"]
    mode = "修改用户额度"
    print("33[32;1m ---------------账户信息---------------33[0m")
    for i in user_msg:
        print(i)
    modify_exit = True
    while modify_exit:
        num = input("请选择%s账户:" %mode)
        if num.isdigit:
            if int(num) <= len(user_msg):
                for i in user_msg:
                    if num in i:
                        num = int(num)
                        msg = user_msg[num-1]
                        modify_exit = False
        elif num == "q":
            modify_exit = False
        else:
            print("输入错误,请重新输入")
    new_balance = int(input("请输入修改额度:"))
    msg["balance"] = new_balance
    usermsg["data"][num-1]["balance"] =  new_balance
    record_msg = "修改额度:%s"%new_balance
    db_handle_a.json_stroage(name,usermsg)
    logger.logger_bk(name, mode)
    logger.logger_month(name, record_msg)

def end():
    """
    退出程序
    :return:
    """
    exit()


def admin():
    """
    管理员总入口,选择具体执行模块
    :return:
    """
    manage_exit = True
    while manage_exit:
        print("请选择所需服务:".center(50,"-"))
        msg = "1、添加账户
" 
              "2、添加银行卡
" 
              "ATM与购物商城、冻结解锁账户
" 
              "4、修改用户额度
" 
              "q、退出
" 
              ">>:"
        menu = {
            "1": add_new_acc,
            "2": add_new_card,
            "ATM与购物商城": frozen,
            "4": modify,
            "q": end
            }
        choice = input(msg)
        if choice in menu:
            menu[choice]()

  conf->settings

import os,logging

BASE_DIR =os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

DB_PATH = os.path.join(BASE_DIR,"database")

BANK_PATH = os.path.join(DB_PATH,"database_bank")

MALL_PATH = os.path.join(DB_PATH,"database_mall")
MALL_PATH_C = os.path.join(MALL_PATH,"customer")
MALL_PATH_M = os.path.join(MALL_PATH,"mall_db")

LOGGER_PATH = os.path.join(BASE_DIR,"logs")
LOGGER_LEVEL = logging.INFO

TRANS_TYPE_CRED = {"deposit":{"mode":"plus","interest":0},
                   "withdraw":{"mode":"subtract","interest":0.05},
                   "transfer_out":{"mode":"subtract","interest":0.05},
                   "transfer_into":{"mode":"plus","interest":0},
                   "repayment": {"mode": "plus", "interest": 0}}
TRANS_TYPE_S = {"deposit":{"mode":"plus","interest":0},
                "withdraw":{"mode":"subtract","interest":0},
                "transfer_out":{"mode":"subtract","interest":0},
                "transfer_into":{"mode":"plus","interest":0},
                "repayment": {"mode": "plus", "interest":0}}

MALL_PATH_M = os.path.join(MALL_PATH,"mall_db")
GOODS = [{"1": "电脑", "price": 1999},
         {"2": "鼠标", "price": 10},
         {"ATM与购物商城": "游艇", "price": 20},
         {"4": "美女", "price": 998},
         {"5": "iphone", "price": 7000}]

  database->database_bank->初始化数据.py

import json,hashlib

data = {"password":"abc123",
        "status":1,
        "data" : [{"1":"信用卡","balance":15000,"debt":0,"classify":"信用卡","expiry":"2022-12-21"},
                  {"2":"银行卡1","balance":10000,"classify":"储蓄卡","expiry":"2025-11-10"}],
        "record":{"信用卡":{},"银行卡1":{}}
        }
m = hashlib.md5()
m.update(data["password"].encode("utf-8"))
data["password"] = m.hexdigest()
json.dump(data,open("alex.json","w",encoding="utf_8"))

data = {"password":"def456",
        "status":1,
        "data" : [{"1":"信用卡","balance":15000,"debt":0,"classify":"信用卡","expiry":"2023-11-1"},
                  {"2":"银行卡1","balance":2000,"classify":"储蓄卡","expiry":"2020-12-15"},
                  {"ATM与购物商城":"银行卡2","balance":5000,"classify":"储蓄卡","expiry":"2022-10-1"}],
        "record": {"信用卡": {}, "银行卡1": {},"银行卡2": {}}
        }
m = hashlib.md5()
m.update(data["password"].encode("utf-8"))
data["password"] = m.hexdigest()
json.dump(data,open("rain.json","w",encoding="utf_8"))

data = {"password":"hij789",
        "status":1,
        "data" : [{"1":"信用卡","balance":15000,"debt":0,"classify":"信用卡","expiry":"2022-ATM与购物商城-17"},
                  {"2":"银行卡","balance":4000,"classify":"储蓄卡","expiry":"2025-11-18"},
                  {"ATM与购物商城":"银行卡","balance":6000,"classify":"储蓄卡","expiry":"2021-10-17"}],
        "record": {"信用卡": {}, "银行卡1": {}}
        }
m = hashlib.md5()
m.update(data["password"].encode("utf-8"))
data["password"] = m.hexdigest()
json.dump(data,open("jack.json","w",encoding="utf_8"))

  database->database_mall->customer->初始化数据.py

import json
data = {"password":"123",
        "shopping_chart":[],
        "record":[]}
json.dump(data,open("alex.json","w",encoding="utf_8"))

data = {"password":"456",
        "shopping_chart":[],
        "record":[]}
json.dump(data,open("rain.json","w",encoding="utf_8"))

data = {"password":"789",
        "shopping_chart":[],
        "record": []}
json.dump(data,open("jack.json","w",encoding="utf_8"))

  database->database_mall->mall_db->初始化数据

import json

goods = [
{"1": "电脑", "price": 1999},
{"2": "鼠标", "price": 10},
{"ATM与购物商城": "游艇", "price": 20},
{"4": "美女", "price": 998},
{"5": "iphone", "price": 7000}
]
json.dump(goods,open("shopping_goods.json","w",encoding="utf-8"))

account_mall = {"balance":0}
json.dump(account_mall,open("account_mall.json","w",encoding="utf-8"))

  shopping_mall->confirm_s

from shopping_mall import db_handle_s
def confirm(username):
    """
    商城验证用户名密码是否正确
    :param username: 用户名
    :return: 用户名
    """
    usermsg = db_handle_s.json_read(username,"customer")
    comfirm_exit = True
    while comfirm_exit:
        passwd = input("请输入密码:")
        if passwd == usermsg["password"]:
            return usermsg
        else:
            print("33[35;1m 密码错误,请重新输入!33[0m")

  shopping_mall->db_handle_s

import os,json
from conf import settings

def json_read(username,parent):
    """
    读取购物商城文件内容
    :param username: 文件名
    :param parent: 文件父级目录名
    :return: 文件内容
    """
    if parent == "customer":
        filename = os.path.join(settings.MALL_PATH_C, username + ".json")
    elif parent == "mall_db":
        filename = os.path.join(settings.MALL_PATH_M, username + ".json")
    if os.path.isfile(filename):
        data = json.load(open(filename, "r", encoding="utf-8"))
        return data
    else:
        print("33[37;1m用户名无效33[0m")
        exit()

def json_stroage(username,parent,msg):
    """
    存储商城文件内容
    :param username:文件名
    :param parent: 文件父级目录
    :param msg: 存储内容
    :return:
    """
    if parent == "customer":
        filename = os.path.join(settings.MALL_PATH_C, username + ".json")
    elif parent == "mall_db":
        filename = os.path.join(settings.MALL_PATH_M, username + ".json")
    if os.path.isfile(filename):
        f = open(filename + ".new", "w", encoding="utf-8")
        json.dump(msg,f)
        f.close()
        os.replace(filename+".new",filename)
        return msg
    else:
        print("33[37;1m用户名无效33[0m")
        exit()

  shopping_mall->mall

import os,sys,json,time

from conf import settings
from shopping_mall import confirm_s,db_handle_s
from bank import main

def flush_goods():
    """
    在conf.settings中的商品列表刷新
    :return:
    """
    json.dump(settings.GOODS, open(os.path.join(settings.MALL_PATH_M,"shopping_goods.json"), "w", encoding="utf-8"))

def pay(name,usermsg):
    """
    完成购物车结算,与银行相连接
    :param name: 消费者用户名
    :param usermsg: 该消费者对应文件中的信息
    :return:
    """
    count = check(name,usermsg)    # 结算前打印购物车中信息,并得到总结
    if count:
        question = input("是否提交订单(y/n):")
        if question == "y":
            account_mall = db_handle_s.json_read("account_mall", "mall_db")
            account_mall = {"id":"account_mall","data":account_mall}
            main.external(account_mall,count)    # 与银行相连接
            timer = time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(time.time()))    # 写入购物记录
            usermsg["shopping_chart"].insert(0,timer)
            usermsg["shopping_chart"].append("count:%s"%count)
            usermsg["record"] = []
            usermsg["record"].append(usermsg["shopping_chart"])
            usermsg["shopping_chart"] = []
            db_handle_s.json_stroage(name,"customer",usermsg)
        elif question == "n" or question == "q":
            return
        else:
            print("输入错误!")
    else:
        return


def check(name,usermsg):
    """
    查看购物车以及购物车中商品的总价
    :param name: 消费者用户名
    :param usermsg: 该消费者对应文件中信息
    :return: 返回总价
    """
    shopping_cart = usermsg["shopping_chart"]
    print('33[36;1m %s 33[0m' %"购物车".center(50, "-"))
    if len(shopping_cart) == 0:
        print("33[36;1m 购物车为空 33[0m")
    else:
        for i in shopping_cart:
            print(i)
        count = 0
        for i in shopping_cart:
            count = count + i["price"]
        print("合计价格:",count)
        return count


def trade(name,usermsg):
    """商城购物
    :param name: 消费者用户名
    :param usermsg: 该消费者文件中的信息
    :return:
    """

    trade_exit = True
    while trade_exit:
        shopping_cart = usermsg["shopping_chart"]
        goods = db_handle_s.json_read("shopping_goods", "mall_db")  # 从文件中读取商品列表
        print("33[32;1m %s 33[0m" %"商品列表".center(50, "-"))
        for i in goods:
            print(i)
        print("33[32;1m %s 33[0m" % "end".center(50, "-"))
        num = input("输入商品编码,加入购物车:").strip()
        add_exit = True
        while add_exit:
            if num.isdigit():
                if int(num) <= len(goods):
                    for i in goods:
                        if num in i:
                            num = int(num)
                            shopping_cart.append(goods[num - 1])
                            db_handle_s.json_stroage(name,"customer",usermsg)
                            add_exit = False
                else:
                    print("输入商品编码有误,请重新输入!")
            elif num == "q":
                return usermsg
        check(name,usermsg)
    return usermsg


def end(usermsg,name):
    exit()


def search(name,usermsg):
    """
    查看购物历史记录
    :param name: 消费者用户名
    :param usermsg: 该消费者对应文件中的所有信息
    :return:
    """
    print("33[33;1m %s 33[0m" % "历史记录".center(50, "-"))
    record = usermsg["record"]
    if len(record) == 0:
        print("33[33;1m 历史记录为空 33[0m")
    else:
        for i in record:
            print(i)
    print("33[33;1m %s 33[0m" % "end".center(50, "-"))


def shopping():
    """
    购物商城的总入口
    :return:
    """
    flush_goods()
    name = input("请输入商场用户名:").strip()
    usermsg = confirm_s.confirm(name)   # 读取消费者文件内容{"password": "123", "shopping_chart": [], "record": []}
    shopping_exit = True
    if usermsg:
        while shopping_exit:
            choice =input( "33[32;1m %s 33[0m 
" 
                         "1. 购物
" 
                         "2. 查看购物车
" 
                         "3. 结算
"
                         "4. 记录查询
"
                         "q. 退出
"
                           "33[32;1m %s 33[0m 
"
                         "请选择要执行的操作:
" %("welcome %s".center(50,"-")%name,"end".center(50,"-")))
            menu = {
                "1":trade,
                "2":check,
                "3":pay,
                "4":search,
                "q":end
            }
            if choice in menu:
                menu[choice](name,usermsg)

  

原文地址:https://www.cnblogs.com/fantsaymwq/p/9846910.html