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

发布时间 2023-06-20 16:12:11作者: 大军军军之技术落地

 一 基本需求

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

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

根据上面需求,我们来实现以下几个功能:

     1 注册
        2 登录
        3 查看余额
        4 转账
        5 取款
        6 还款
        7 查看流水
        8 购物
        9 查看购买商品

 

二 项目目录结构

bin目录

start.py---》程序启动页

conf目录

setting.py---》用于存放整个项目的配置信息

core目录

src.py---》用户端功能

interface目录

bank.py---》银行相关接口

shop.py---》购物相关接口

user.py---》用户相关接口

db目录

db_handler.py---》对文件的读写操作

用于存放所有用户信息,以json格式存储

lib目录

common.py---》公共方法(用户认证装饰器,获取日志对象等)

log目录

记录日志

 

三 分模块

start.py

import os,sys

path = os.path.dirname(__file__)
# print(path)
sys.path.append(path)
from core import src
# print(path)

if __name__ == '__main__':
    src.run()
View Code

src.py

from interface import bank,shop,user
from lib import common

user_dic = {
    'name':None
}
def register():
    if user_dic['name']:
        print('已经登录,不能注册')
        return

    print('注册')
    while True:
        name = input('请输入名字:').strip()
        password = input('请输入密码:').strip()
        conf_password = input('请确认密码:').strip()
        if password == conf_password:
            flag,msg = user.register_interface(name,password)
            if flag:
                print(msg)
                break
            else:
                print(msg)
        else:
            print('两次输入的密码不一致')
def login():
    if user_dic['name']:
        print('已经登录')
        return

    print('登录')
    while True:
        name = input('请输入名字:').strip()
        password = input('请输入密码:').strip()
        flag,msg = user.login_interface(name,password)
        if flag:
            user_dic['name']=name
            print(msg)
            break
        else:
            print(msg)

@common.login_auth
def check_balance():
    print('查看余额')
    balance = bank.check_balance_interface(user_dic['name'])
    print(balance)

@common.login_auth
def transfer():
    print('转账')
    while True:
        to_user = input('请输入对方账户:').strip()
        account = input('请输入转账金额:').strip()
        if account.isdigit():
            account = int(account)
            flag,msg = bank.transfer_interface(user_dic['name'],to_user,account)

            if flag:
                print(msg)
                break
            else:
                print(msg)
        else:
            print('请输入数字')

@common.login_auth
def repay():
    print('还款')
    while True:
        account = input('请输入还款金额:').strip()
        if account.isdigit():
            account = int(account)
            flag,msg = bank.repay_interface(user_dic['name'],account)
            if flag:
                print(msg)
                break
            else:
                print(msg)
        else:
            print('请输入数字')


@common.login_auth
def withdraw():
    print('取款')
    while True:
        account = input('请输入取款金额:').strip()
        if account.isdigit():
            account = int(account)
            flag,msg = bank.withdraw_interface(user_dic['name'],account)
            if flag:
                print(msg)
                break
            else:
                print(msg)
        else:
            print('请输入数字')
@common.login_auth
def check_records():
    print('查看流水')
    records = bank.check_records_interface(user_dic['name'])
    if records:
        for record in records:
            print(record)
    else:
        print('暂无流水')

@common.login_auth
def shopping():
    print('购物')
    goods_list = [
        ['coffee',10],
        ['chicker',20],
        ['car',100000]
    ]
    user_balance = bank.check_balance_interface(user_dic['name'])
    cost = 0
    shoppingcard = {

    }
    while True:
        for i,goods in enumerate(goods_list):
            print('%s : %s'%(i,goods))
        buy = input('请输入要购买的数字(数字)(q退出并购买):').strip()
        if buy.isdigit():
            buy = int(buy)
            if buy < len(goods_list):
                goods_name = goods_list[buy][0]
                goods_price = goods_list[buy][1]
                if user_balance >= goods_price:
                    if goods_name not in shoppingcard:
                        shoppingcard[goods_name] = {'price':goods_price,'count':1}
                    else:
                        shoppingcard[goods_name] += 1

                    user_balance -= goods_price
                    cost += goods_price

                    print('添加购物车成功')
                else:
                    print('余额不足')
            else:
                print('请选择存在的商品')

        elif buy == 'q':
            if shoppingcard:
                flag,msg = shop.shopping_interface(user_dic['name'],cost,shoppingcard)
                if flag:
                    print(msg)
                    break
                else:
                    print(msg)
                    break

        else:
            print('请输入数字')
@common.login_auth
def check_shoppingcard():
    print('查看购物车')
    shoppingcart = shop.check_shopingcart_interface(user_dic['name'])
    if shoppingcart:
        print(shoppingcart)
    else:
        print('购物车为空')

func_dic = {
    '1': register,
    '2': login,
    '3': check_balance,
    '4': transfer,
    '5': repay,
    '6': withdraw,
    '7': check_records,
    '8': shopping,
    '9': check_shoppingcard
}

def run():
    while True:
        print('''
            1 注册
            2 登录
            3 查看余额
            4 转账
            5 还款
            6 取款
            7 查看流水
            8 购物
            9 查看购买商品
        ''')
        choice = input('请选择')
        if choice not in func_dic:continue
        func_dic[choice]()
View Code

user.py

from db import db_handler

def register_interface(name,password,balance=1500):
    user_dic = db_handler.select(name)
    if user_dic:
        return False,'用户已存在'
    else:
        user_dic = {
            'name': name,
            'password': password,
            'lockd': False,
            'balance': balance,
            'credit': balance,
            'bankflow': [],
            'shoppingcard': {}
        }

        db_handler.save(user_dic)
        return True,'注册成功'

def login_interface(name,password):
    user_dic = db_handler.select(name)
    if user_dic:
        if password == user_dic['password']:
            return True,'登录成功'
        else:
            return False,'密码错误或者已经锁定'
    else:
        return False,'用户不存在'
View Code

shop.py

from db import db_handler
from interface import bank

def check_shopingcart_interface(name):
    user_dic = db_handler.select(name)

    return user_dic['shoppingcard']


def shopping_interface(name,cost,shoppingcard):
    flag = bank.consume_interface(name,cost)
    if flag:
        user_dic = db_handler.select(name)
        user_dic['shoppingcard'] = shoppingcard
        db_handler.save(user_dic)
        return True,'购买成功'
    else:
        return False,'购买失败'
View Code

bank.py

import db.db_handler
from db import db_handler

from lib import common

bank_logger = common.get_logger('bank')
def check_balance_interface(name):
    user_dic = db_handler.select(name)
    return user_dic['balance']



def transfer_interface(from_name,to_name,account):
    to_user_dic = db_handler.select(to_name)
    if to_user_dic:
        from_user_dic = db.db_handler.select(from_name)
        if from_user_dic['balance'] >= account:
            from_user_dic['balance'] -= account
            to_user_dic['balance'] += account
            from_user_dic['bankflow'].append('%s 向 %s 转账 %s'%(from_name,to_name,account))
            to_user_dic['bankflow'].append('%s 收到 %s 转账 %s'%(to_name,from_name,account))


            db_handler.save(from_user_dic)
            db_handler.save(to_user_dic)
            return True,'转账成功'
        else:
            return False,'您的额度不够'
    else:
        return False,'对方账户不存在'


def repay_interface(name,account):
    user_dic = db_handler.select(name)
    user_dic['balance'] += account
    user_dic['bankflow'].append('还款 %s' %(account))
    db_handler.save(user_dic)
    bank_logger.info('还款成功')
    return True,'还款成功'

def withdraw_interface(name,account):
    user_dic = db_handler.select(name)
    account = account*1.05
    if user_dic['balance'] >= account:
        user_dic['balance'] -= account
        user_dic['bankflow'].append('取款 %s' % (account))
        db_handler.save(user_dic)
        return True,'取款成功'
    else:
        return False,'余额不足'

def check_records_interface(name):
    user_dic = db_handler.select(name)
    return user_dic['bankflow']

def consume_interface(name,account):
    user_dic = db_handler.select(name)
    if user_dic['balance'] >= account:
        user_dic['balance'] -= account
        user_dic['bankflow'].append('消费 %s' % (account))
        db_handler.save(user_dic)
        return True
    else:
        return False
View Code

db_handler.py

import os
from conf import setting
import json

def select(name):
    path = os.path.join(setting.base_db, '%s,json' %name)

    if os.path.exists(path):
        with open(path,'r',encoding='utf-8') as f:
            return json.load(f)

    else:
        return None

def save(user_dic):
    path = os.path.join(setting.base_db,'%s,json'%user_dic['name'])

    with open(path,'w',encoding='utf-8') as f:
        json.dump(user_dic,f)
        f.flush()
View Code

common.py

import logging.config
from conf import setting

def login_auth(func):
    from core import src
    def wrapper(*args,**kwargs):
        if not src.user_dic['name']:
            src.login()

        else:
            return func(*args,**kwargs)
    return wrapper

def get_logger(name):
    logging.config.dictConfig(setting.LOGGING_DIC)
    my_logger = logging.getLogger(name)
    return my_logger
View Code

setting.py

import os
base_dir = os.path.dirname(os.path.dirname(__file__))
base_db = os.path.join(base_dir,'db')
base_log = os.path.join(base_db,'log')

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'

id_simple_format = '[%(levelname)s][%(asctime)s] %(message)s'

# 定义日志输出格式 结束




# 如果不存在定义的日志目录就创建一个
if not os.path.isdir(base_log):
    os.mkdir(base_log)

# log文件的全路径
logfile_path = os.path.join(base_log, 'log.log')
logfile_another = os.path.join(base_log, 'another.log')

# 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': 'INFO',
            'propagate': True,  # 向上(更高level的logger)传递
        },
    },
}
View Code