python项目实战(一):ATM+购物车(购物商城)

一、项目开发架构图

在这里插入图片描述

1、用户视图层

用户视图层是展示给用户看的,用户视图层展示相关功能给用户看的,接收用户输入的内容比如用户通过注册功能,输入用户名和密码,用户视图层也可以校验简单的逻辑,比如用户注册时两次输入的密码是否一致;

2、逻辑接口层

逻辑处理层主要是用来接收视图层传数据处理层的内容并进行逻辑判断,组织数据,同时记录相关流水与日志。

3、数据处理层

1.数据处理层主要是进行数据的增删改查,与数据打交道的,和数据库打交道,但本项目采用json文件存储数据,所以相当于对json文件进行操作

2.用户注册时,用户视图层接收用户输入的内容并传给逻辑接口层,接口层接收到数据传递给数据处理层,如果用户已存在,则返回该用户对应的信息,否则返回 None,逻辑接口层拿到数据处理返回的数据,进行 判断,如果接收到的是用户信息已存在,则告诉视图层,该用户已存在,否则继续注册。

3.用户登录时,用户视图层接收用户输入的内容并传给逻辑接口层,接口层接收到数据传递给数据处理层,如果用户已存在,则返回该用户对应的信息,否则返回None,逻辑接口层拿到数据处理返回的数据,进行判断,如果接收到的是用户信息,则进行比对用户密码是否一致,然后将结果返回用户视图层

二、项目目录展示

在这里插入图片描述

三、项目源码展示

1、readme.md

# 项目说明书
## ATM + 购物车
## 项目需求
    1.账户初始金额15000 ---> 注册功能
    2.实现购物商城,买东西加入购物车,调用信用卡接口结账 ---> 购物功能
    3.可以提现,手续费5%    ---> 提现功能
    4.支持多账户登录、实现密码加密   ---> 登录功能
    5.支持账户间转账   ---> 转账功能
    6.记录每月日常消费流水    ---> 记录流水功能
    7.提供充值接口    ---> 充值功能
    8.提供管理接口,包括添加商品种类及商品、管理员账户为admin、查看商品列表、冻结账户、查看日志(这个不是记录流水的)等  ---> 管理员功能
    9.登录发送邮箱验证码采用装饰器
## 用户视图层需要展示的功能
    1.注册功能
    2.登录功能
    3.查看余额
    4.提现功能
    5.充值功能
    6.转账功能
    7.查看流水
    8.购物功能
    9.查看购物车
    10.管理员功能

2、settings.py

'''
配置
'''
import os

# 指定用户数据目录
USERDATA_PATH = os.path.join(
        os.path.abspath('.'),'db','user_data'
    )

# 指定管理员账号数据目录
ADMINDATA_PATH = os.path.join(
    os.path.abspath('.'),'db','admin_data','admin.json'
)

# 指定商品数据目录
GOODSDATA_PATH = os.path.join(
        os.path.abspath('.'),'db','goods_data'
    )

# 指定登录密码的盐
SALT = 'fuck'

# 指定加密传输的算法
ENCRIPT_ALGO = 'md5'

# 指定日志文件路径
LOG_PATH = os.path.join(
    os.path.abspath('.'),'log','operation.log'
)
# 配置日志字典
standard_format = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]''[%(levelname)s][%(message)s]'

simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'

test_format = '%(asctime)s] %(message)s'

LOGGING_DIC = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'standard': {
            'format': standard_format
        },
        'simple': {
            'format': simple_format
        },
        'test': {
            'format': test_format
        },
    },
    'filters': {},
    'handlers': {
        #打印到文件的日志,收集info及以上的日志
        'file': {
            'level': 'DEBUG',
            'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件,日志轮转
            'formatter': 'standard',
            'filename': LOG_PATH,  # 日志文件
            'maxBytes': 1024*1024*5,  # 日志大小 5M
            'backupCount': 5,
            'encoding': 'utf-8',  # 日志文件的编码,再也不用担心中文log乱码了
        },
    },
    'loggers': {
        #logging.getLogger(__name__)拿到的logger配置
        'operation': {
            'handlers': ['file'],
            'level': 'DEBUG',
            'propagate': False,
        },
    },
}

3、src.py

'''
用户视图层
'''
import time
from interface import user_interface
from interface import bank_interface
from interface import shop_interface
from interface import admin_interface
from lib import common

login_user = None

# 注册功能
def register():
    print('---------欢迎进入注册界面---------')
    while True:
        username = input('请输入账户名:').strip()
        password = input('请输入密码:').strip()
        re_password = input('请再次确认密码:').strip()
        while password != re_password:
            re_password = input('确认密码错误,请再次确认密码:').strip()
        gender = input('请输入您的性别:').strip()
        sex = ['男', '女']
        while gender not in sex:
            gender = input('您的输入非法,请重新输入您的性别:').strip()
        email_addr = input('请输入您的邮箱地址:').strip()
        register_res = user_interface.register_interface(username,password,gender,email_addr)
        flag = register_res[0]
        msg = register_res[1]
        if flag:
            print(msg)
            break
        else:
            print(msg)
            continue
# 登录功能
@common.login_inner
def login():
    count = 0
    while True:
        print('---------欢迎进入用户登录界面---------')
        username = input('请输入账户名:').strip()
        password = input('请输入密码:').strip()
        password = common.get_pwd_hash(password)
        login_res = user_interface.login_interface(username,password)
        flag = login_res[0]
        msg = login_res[1]
        if flag:
            print(msg)
            return username
        elif flag == '0':
            print(msg)
            break
        else:
            print(msg)
            count += 1
            if count == 3:
                break
            continue
# 查看余额
def check_balance():
    user_dic = common.get_userdic(login_user)
    print('尊敬的{}{}您好!'.format(login_user,common.get_status(user_dic)))
    print('您当前的账户余额:',user_dic['balance'],'¥')
# 提现功能
def withdraw():
    while True:
        money = input('请输入您要提现的金额:').strip()
        if not money.isdigit():
            print('输入错误,只支持整数转账!')
            continue
        time.sleep(2)
        withdraw_res = bank_interface.withdraw_interface(int(money),login_user)
        flag = withdraw_res[0]
        msg = withdraw_res[1]
        if flag:
            print(msg)
            break
        else:
            check_balance()
            print(msg)
            continue
# 充值功能
def recharge():
    while True:
        money = input('请输入您的充值金额:').strip()
        if not money.isdigit():
            print('输入错误,只支持整数充值!')
            continue
        else:
            print('充值中...')
            time.sleep(2.5)
            recharge_res = bank_interface.recharge_interface(int(money),login_user)
            print(recharge_res)
            break

# 转账功能
def transfer():
    while True:
        username = input('请输入转账的用户:').strip()
        money = input('请输入转账的金额:').strip()
        if not money.isdigit():
            print('输入错误,只支持整数转账!')
            continue
        transfer_res = bank_interface.transfer_interface(username,int(money),login_user)
        flag = transfer_res[0]
        msg = transfer_res[1]
        if flag:
            print(msg)
            break
        else:
            print(msg)
            continue
# 查看流水
def check_flow():
    while True:
        num = input('请输入您要查看的最近流水条目数:').strip()
        if not num.isdigit():
            print('输入非法!')
            continue
        bank_interface.checkflow_interface(login_user,int(num))
        break
# 购物功能
def shopping():
    goods_kind_dic = common.get_goods_kind_dic()
    def printing():
        print('----------下面是三种类型的商品-----------')
        for i in goods_kind_dic.keys():
            print(i)
        print('----------------end-----------------')

    def printer():
        print('----------{}类型的所有商品如下-----------'.format(choice))
        for i in goods_kind_dic[choice].keys():
            if i == '0':
                print(i, goods_kind_dic[choice][i][0])
                continue
            print(i, goods_kind_dic[choice][i][0], '{} ¥'.format(goods_kind_dic[choice][i][1]))
        print('-----------------end------------------')
    printing()
    while True:
        choice = input('商品种类选择 >>>').strip()
        if choice == '':
            continue
        elif choice == 'ls':
            printing()
        elif choice not in goods_kind_dic:
            print('暂无此商品种类,请重新选择商品种类!')
            continue
        elif choice == 'exit':
            break
        else:
            printer()
            while True:
                num = input('购买商品选择 >>>').strip()
                if num == '':
                    continue
                elif num == 'ls':
                    printer()
                elif not num.isdigit():
                    print('错误输入!')
                    continue
                elif num == '0':
                    break
                else:
                    flag = input('是否加入购物车(yes or no ?)').strip()
                    shop_res = shop_interface.shopping_interface(num,choice,login_user,flag)
                    print(shop_res)
                    continue
# 购物车操作
def shop_car():
    def printing():
        print('''
        -------------购物车界面-------------
        exit 退出购物车
        0    查看购物车
        1    购物车付款
        2    清空购物车
        ----------------end---------------
        ''')
    printing()
    while True:
        num = input('请输入您的选择 >>>').strip()
        if num == '':
            continue
        elif num == 'ls':
            printing()
            continue
        elif num == 'exit':
            break
        elif num.isdigit():
            msg = shop_interface.shopcar_interface(num,login_user)
            print(msg)
            continue
        else:
            print('输入错误!')
            continue
# 管理员功能
@common.login_inner
def admin():
    print('--------- 欢迎进入管理员登录界面 ---------')
    password = input('请输入管理员账号的密码:').strip()
    password = common.get_pwd_hash(password)
    print('----------------- end ----------------')
    login_res = admin_interface.login_interface(password)
    flag = login_res[0]
    msg = login_res[1]
    if flag:
        print(msg)
        return 'admin'
    else:
        print(msg)

def admin_func():
    def printing():
        print('''
        -------------- 管理员后台管理界面 --------------
                        exit    退出
                        0       修改登录密码
                        1       查看商品列表
                        2       添加商品
                        3       冻结账户
                        4       账号解冻
        -------------------- end --------------------
        ''')
    printing()
    while True:
        num = input('请输入您要执行的操作 >>>').strip()
        if num == 'exit':
            break
        elif num == 'ls':
            printing()
            continue
        elif num == '':
            continue
        elif num == '0':
            password = input('请输入修改后的密码:').strip()
            password = common.get_pwd_hash(password)
            msg = admin_interface.pwd_modify_interface(password)
            print(msg)
            continue
        elif num == '1':
            print('''
------------- 吴晋丞购物商城商品列表 -------------
            ''')
            admin_interface.check_goods_dic()
            print('''
-------------------- end ---------------------
            ''')
        elif num == '2':
            goods_type = input('请输入商品的种类:').strip()
            goods_num = input('请输入商品的编号:').strip()
            goods_name = input('请输入商品的名称:').strip()
            goods_price = input('请输入商品的价格:').strip()
            mes = admin_interface.add_goods_interface(goods_type,goods_num,goods_name,int(goods_price))
            print(mes)
            continue
        elif num == '3' or num == '4':
            if num == '3':
                status = True
                username = input('请输入您要冻结的账户的用户名:').strip()
            else:
                status = False
                username = input('请输入您要解冻的账户的用户名:').strip()
            locked_res = admin_interface.locking_interface(username,status)
            print(locked_res)
        else:
            print('输入错误!')
            continue

basic_func = {
    '0':['退出程序'],
    '1':['注册功能',register],
    '2':['登录功能',login],
    '3':['管理员登录',admin]
}
user_func = {
    '0':['用户登出'],
    '1':['查看余额',check_balance],
    '2':['提现功能',withdraw],
    '3':['充值功能',recharge],
    '4':['转账功能',transfer],
    '5':['查看流水',check_flow],
    '6':['购物功能',shopping],
    '7':['购物车功能',shop_car],
}

# 视图层主程序
def run():
    def printer():
        print('--------- ATM+购物车系统 ---------')
        for key in basic_func:
            print(key, basic_func[key][0])
        print('-------------- end --------------')
    def printing():
        print('--------- ATM+购物车系统 ---------')
        for key in user_func:
            print(key, user_func[key][0])
        print('-------------- end --------------')
    count = True
    while True:
        global login_user
        if login_user == None or login_user == 'admin':
            if count:
                printer()
                count = False
            else:
                num = input('请输入功能编号:')
                if num == '0':
                    break
                elif num == '':
                    continue
                elif num in basic_func:
                    basic_func[num][1]()
                if login_user == 'admin':
                    printer()
        else:
            if not count:
                printing()
                count = True
            else:
                num = input('{} >>>'.format(login_user))
                if num == '0':
                    login_user = None
                    continue
                elif num == 'ls':
                    printing()
                elif num in user_func:
                    user_func[num][1]()
                else:
                    continue

4、admin.json

{"username": "admin", "password": "6e40f96fc8400f9b72d46f7bf0f85faf", "email": "[email protected]"}

5、base.json

{"exit": {"退出购物!": null}, "food": {"0": ["返回上级菜单"], "1": ["阆中牛肉面", 7], "2": ["成都羊肉汤锅", 300], "3": ["成都麻辣兔头", 8], "4": ["狼牙土豆", 5], "5": ["孜然烤面筋", 3], "6": ["单人冒菜套餐", 20]}

6、food.json

{"1": ["阆中牛肉面", 7], "2": ["成都羊肉汤锅", 300], "3": ["成都麻辣兔头", 8], "4": ["狼牙土豆", 5], "5": ["孜然烤面镜", 3], "6": ["单人冒菜套餐", 20], "7": ["成都酸辣粉", 10], "8": ["单人份烧烤", 10], "9": ["伤心凉粉", 7]}

注意:其他几个json文件都是存储不同的商品的,就不再展示了!

7、user_data

运行程序后,你注册的用户信息就会存到这个目录里去

8、db_handler.py

'''
数据处理层
'''
import os
import json
from conf.settings import USERDATA_PATH as userdata_path
from lib.common import get_userdic
from conf.settings import ADMINDATA_PATH as admin_path
from conf.settings import GOODSDATA_PATH

# 用户是否存在
def user_is_exist(username):
    user_path = os.path.join(
        userdata_path,'{}.json'.format(username)
    )
    return os.path.exists(user_path)

# 存储用户数据
def save_userdata(user_dic):
    username = user_dic['username']
    user_path = os.path.join(
        userdata_path,'{}.json'.format(username)
    )
    with open(user_path,mode='w',encoding='utf-8') as write_f:
        json.dump(user_dic,write_f,ensure_ascii=False)

# 查看用户密码信息是否正确
def check_user_msg(username,password):
        user_dic = get_userdic(username)
        if user_dic['password'] == password:
            return True
        else:
            return False

# 获取管理员账户(admin)数据字典
def get_admindic():
    with open(admin_path,mode='r',encoding='utf-8') as read_f:
        admin_dic = json.load(read_f)
        return admin_dic

# 保存管理员账户数据
def save_admindata(admin_dic):
    with open(admin_path,mode='w',encoding='utf-8') as write_f:
        json.dump(admin_dic,write_f,ensure_ascii=False)

# 获取商品的数据存储路径
def get_goods_path(goods_type):
    goods_path = os.path.join(
        GOODSDATA_PATH, '{}.json'.format(goods_type)
    )
    return goods_path

# 商品类型是否存在
def goods_type_isexist(goods_type):
    goods_path = get_goods_path(goods_type)
    return os.path.isfile(goods_path)

# 获取商品数据字典
def get_goods_dic(goods_type):
    goods_path = get_goods_path(goods_type)
    with open(goods_path,mode='r',encoding='utf-8') as read_f:
        goods_dic = json.load(read_f)
        return goods_dic

# 保存商品数据字典
def save_goods_dic(goods_type,goods_dic):
    goods_path = get_goods_path(goods_type)
    with open(goods_path,mode='w',encoding='utf-8') as write_f:
        json.dump(goods_dic,write_f,ensure_ascii=False)

# 创建新的商品类型及商品
def create_type_and_goods(goods_type,goods_num,goods_name,goods_price):
    goods_path = get_goods_path(goods_type)
    with open(goods_path,mode='w',encoding='utf-8') as f:
        goods_dic = {}
        goods_dic[goods_num]=[goods_name,goods_price]
        json.dump(goods_dic,f,ensure_ascii=False)

9、admin_interface.py

'''
管理员操作接口
'''
from db import db_handler
from lib import common
from conf import settings
import logging.config
logging.config.dictConfig(settings.LOGGING_DIC)
logger1=logging.getLogger('operation')
# 管理员登录
def login_interface(password):
    admin_dic = db_handler.get_admindic()
    if admin_dic['password'] == password:
        return True,'密码验证成功!正在向管理员账号发送验证码...'
    else:
        return False,'密码验证失败!'

# 修改管理员账号的密码接口
def pwd_modify_interface(password):
    admin_dic = db_handler.get_admindic()
    admin_dic['password'] = password
    db_handler.save_admindata(admin_dic)
    logger1.warning('管理员账号密码被修改!')
    return '管理员账号密码修改成功!'

# 查看商品列表接口
def check_goods_dic():
    goods_kind_dic = common.get_goods_kind_dic()
    for k in goods_kind_dic.keys():
        if k == 'exit':
            continue
        print('{}类型:'.format(k))
        for key in goods_kind_dic[k].keys():
            if key == '0':
                continue
            print(' '*10,key,goods_kind_dic[k][key][0])

# 添加商品接口
def add_goods_interface(goods_type,goods_num,goods_name,goods_price):
    flag = db_handler.goods_type_isexist(goods_type)
    goods_kind_dic = common.get_goods_kind_dic()
    if flag:
        goods_dic = db_handler.get_goods_dic(goods_type)
        for k in goods_dic.keys():
            if goods_dic[k][0] == goods_name:
                return '商品已存在!'
        goods_dic[goods_num]=[goods_name,goods_price]
        db_handler.save_goods_dic(goods_type,goods_dic)
        goods_kind_dic[goods_type][goods_num]=[goods_name,goods_price]
        common.save_goods_kind_dic(goods_kind_dic)
        mes = '成功在{}类型商品中添加商品{}!'.format(goods_type, goods_name)
        logger1.info(mes)
        return mes
    db_handler.create_type_and_goods(goods_type,goods_num,goods_name,goods_price)
    goods_kind_dic[goods_type] = {'0': ['返回上级菜单'],goods_num: [goods_name, goods_price]}
    common.save_goods_kind_dic(goods_kind_dic)
    mess = '成功添加{}类型商品,并在其添加{}商品'.format(goods_type, goods_name)
    logger1.info(mess)
    return mess

# 冻结/解冻账户接口
def locking_interface(username,status):
    userdic = db_handler.get_userdic(username)
    if status:
        userdic['locked'] = True
        db_handler.save_userdata(userdic)
        return '账户{}冻结成功!'.format(username)
    userdic['locked'] = False
    db_handler.save_userdata(userdic)
    mes = '账户{}解冻成功!'.format(username)
    logger1.info(mes)
    return mes

10、bank_interface.py

'''
银行操作接口
'''
from db import db_handler
from lib import common
import time
# 提现接口
def withdraw_interface(money,login_user):
    userdic = common.get_userdic(login_user)
    balance = float(userdic['balance'])
    total_fee = money * 1.05
    if  total_fee <= balance:
        service_fee = money * 0.05
        service_fee = round(service_fee,3)
        balance -= service_fee + float(money)
        balance = round(balance, 3)
        userdic['balance'] = balance
        flow = '{},提现成功,提现金额:{} ¥,手续费:{} ¥'.format(time.strftime('%Y-%m-%d %X %p'),money,service_fee)
        userdic['flow'].insert(0,flow)
        db_handler.save_userdata(userdic)
        return True,'提现成功,提现金额:{} ¥,手续费:{} ¥,当前账户余额:{} ¥'.format(money,service_fee,balance)
    return False,'账户余额不足,提现失败!'

# 充值接口
def recharge_interface(money,login_user):
    userdic = common.get_userdic(login_user)
    userdic['balance'] += money
    flow = '{},充值成功,充值金额:{} ¥'.format(time.strftime('%Y-%m-%d %X %p'),money)
    userdic['flow'].insert(0,flow)
    db_handler.save_userdata(userdic)
    return '充值成功!'

# 转账接口
def transfer_interface(username,money,login_user):
    if not db_handler.user_is_exist(username):
        return False,'转账失败,转账用户不存在!'
    userdic = common.get_userdic(login_user)
    if userdic['balance'] >= money:
        # 先减钱,再加钱,注意自己给自己转账这种特殊情况,先更新完userdic信息,我再进行加钱操作
        userdic['balance'] -= money
        flow = '{},转账成功,TO:{},转账金额:{} ¥'.format(time.strftime('%Y-%m-%d %X %p'),username,money)
        userdic['flow'].insert(0,flow)
        db_handler.save_userdata(userdic)
        
        tr_userdic = common.get_userdic(username)
        tr_userdic['balance'] += money
        flow = '{},收到一笔转账,FROM:{},金额:{} ¥'.format(time.strftime('%Y-%m-%d %X %p'),login_user,money)
        tr_userdic['flow'].insert(0,flow)
        db_handler.save_userdata(tr_userdic)
        return True,'转账成功!'
    return False,'转账失败,账户余额不足!'

# 记录流水接口
def checkflow_interface(login_user,num=10):
    userdic = common.get_userdic(login_user)
    count = 0
    for i in userdic['flow']:
        if count > num - 1:
            break
        print(i)
        count += 1

11、shop_interface.py

'''
购物操作接口
'''
from conf.settings import GOODSDATA_PATH
import os
import json
from lib import common
from db import db_handler
import time

# 购物接口
def shopping_interface(num,choice,login_user,flag):
    goods_path = os.path.join(
        GOODSDATA_PATH,'{}.json'.format(choice)
    )
    with open(goods_path,mode='r',encoding='utf-8') as read_f:
        goods_dic = json.load(read_f)
        if num not in goods_dic:
            return '暂无此商品!'
        pay_fee = goods_dic[num][1]
        goodname = goods_dic[num][0]
        userdic = common.get_userdic(login_user)
        if flag == 'yes':
            userdic['shop_car'][goodname] = pay_fee
            db_handler.save_userdata(userdic)
            return '加入购物车成功'
        else:
            userdic['balance'] -= pay_fee
            flow = '{},购买{}成功,付款{} ¥'.format(time.strftime('%Y-%m-%d %X %p'),goodname,pay_fee)
            userdic['flow'].insert(0,flow)
            db_handler.save_userdata(userdic)
            print('支付中...')
            time.sleep(2)
            return '购买{}成功'.format(goodname)

# 购物车接口
def shopcar_interface(num,login_user):
    def clear_shopcar(userdic,flag='yes'):
        if flag == 'yes':
            userdic['shop_car'] = {}
            db_handler.save_userdata(userdic)
            return '成功清空购物车!'
    userdic = common.get_userdic(login_user)
    if num == '0':
        if userdic['shop_car'] == {}:
            return '购物车暂无商品,快去选购商品吧!'
        else:
            print('''
----------您的购物车商品如下----------''')
            for k in userdic['shop_car'].keys():
                print(' '*10,k,'{} ¥'.format(userdic['shop_car'][k]))
            return '----------------end----------------'
    elif num == '1':
        total_val = 0
        if userdic['shop_car'] == {}:
            return '购物车暂无商品!'
        for k in userdic['shop_car'].keys():
            total_val += userdic['shop_car'][k]
        if (total_val > userdic['balance']):
            return '账户余额不足,付款失败!'
        userdic['balance'] -= total_val
        for key in userdic['shop_car']:
            flow = '{},购买{}成功,付款:{} ¥'.format(time.strftime('%Y-%m-%d %X %p'),key,userdic['shop_car'][key])
            userdic['flow'].insert(0,flow)
        clear_shopcar(userdic)
        print('支付中...')
        time.sleep(2)
        return '付款成功!'
    else:
        flag = input('请确定是否清空购物车(yes or no ?)')
        clear_res = clear_shopcar(userdic,flag)
        return clear_res

12、user_interface.py

'''
用户操作接口
'''
from db import db_handler
from lib import common
from conf import settings
import logging.config
logging.config.dictConfig(settings.LOGGING_DIC)
logger1=logging.getLogger('operation')
# 注册接口
def register_interface(username,password,gender,email_addr):
    flag = db_handler.user_is_exist(username)
    user_dic = {
        'username':username,
        'gender':gender,
        'password':common.get_pwd_hash(password),
        'email':email_addr,
        'balance':15000,
        'flow':[],
        'shop_car':{},
        'locked':False
    }
    if flag:
        return False,'用户已存在!'
    else:
        db_handler.save_userdata(user_dic)
        logger1.info('用户名:{},注册成功!'.format(username))
        return True,'注册成功!'

# 登录接口
def login_interface(username,password):
    flag = db_handler.user_is_exist(username)
    if not flag:
        return False,'登录的账号不存在,请重新输入!'
    else:
        userdic = db_handler.get_userdic(username)
        if userdic['locked'] == True:
            return 0,'账号已被冻结!'
        status = db_handler.check_user_msg(username,password)
        if status:
            return True,'账号密码验证成功,正在向{}的邮箱账号发送验证码...'.format(username)
        else:
            return False,'密码错误,请重新输入!'

13、common.py

'''
公共方法区
'''
import smtplib
import random
from email.mime.text import MIMEText
from email.header import Header
from email.utils import formataddr
import hashlib
from conf.settings import USERDATA_PATH
import os
import json
import sys
import time
import core.src
from db import db_handler
from conf import settings
import logging.config

logging.config.dictConfig(settings.LOGGING_DIC)
logger1=logging.getLogger('operation')
# 获取登录密码的hash值
def get_pwd_hash(password):
    from conf.settings import SALT as salt
    from conf.settings import ENCRIPT_ALGO
    try:
        m = getattr(hashlib,ENCRIPT_ALGO)()
    except AttributeError:
        print('指定的加密算法不存在,程序正在退出...')
        time.sleep(2)
        sys.exit()
    m.update(salt.encode('utf-8'))
    m.update(password.encode('utf-8'))
    return m.hexdigest()

# 生成随机验证码
def make_code(n=6):
    res = ''
    for i in range(n):
        num = str(random.randint(1, 9))  # 生成随机1-9,并强转成字符串格式
        num2 = str(random.randint(1, 9))
        big_char = chr(random.randint(65, 90))  # 生成随机A-Z字母
        small_char = chr(random.randint(97,122)) # 随机生成a-z字母
        get_str = random.choice([num,num2,big_char,small_char])  # 从生成的数字和字母选择一个进行字符串拼接
        res += get_str
    return res

# 传入接收邮件账号和随机验证码,发送邮件
def send_mail(username_recv,code):
    sender = 'zab***[email protected]'
    receivers = '{}'.format(username_recv)
    # 三个参数:第一个为邮件正文文本内容,第二个 plain 设置文本格式,第三个 utf-8 设置编码
    message = MIMEText('【 吴晋丞购物商城 】你正在登录吴晋丞购物商城,验证码{}。转发可能导致账号被盗。'.format(code), 'plain', 'utf-8')
    message['From'] = formataddr(["admin", sender])  # 发送者
    message['To'] = formataddr(["吴晋丞购物商城", receivers])  # 接收者

    subject = '来自吴晋丞购物商城的消息'
    message['Subject'] = Header(subject, 'utf-8')  # 邮件的主题

    smtpObj = smtplib.SMTP('smtp.163.com', port=25)
    smtpObj.login(user=sender, password='HYDSGRIJQXNMUGWB')  # password并不是邮箱的密码,而是开启邮箱的授权码
    smtpObj.sendmail(sender, receivers, message.as_string())  # 发送邮件

# 登录发送邮箱验证码的装饰器
def login_inner(func):
    def send_email(*args,**kwargs):
        username = func(*args,**kwargs)
        if username == None:
            return None
        if username == 'admin':
            admin_dic = db_handler.get_admindic()
            email_addr = admin_dic['email']
        else:
            userdic = get_userdic(username)
            email_addr = userdic['email']
        code = make_code()
        send_mail(email_addr,code)
        verti_code = input('请输入您的验证码:').strip()
        if verti_code == code and username != 'admin':
            mes = '登录成功,欢迎{}{}进入购物商城!'.format(username, get_status(userdic))
            logger1.info(mes)
            print(mes)
        elif verti_code == code:
            mess = '登录成功,欢迎管理员进入购物商城后台管理系统!'
            logger1.info(mess)
            print(mess)
        core.src.login_user = username
        if username == 'admin':
            core.src.admin_func()
        return username
    return send_email

# 根据用户名获取用户数据字典
def get_userdic(username):
    user_path = os.path.join(
        USERDATA_PATH,'{}.json'.format(username)
    )
    with open(user_path,mode='r',encoding='utf-8') as read_f:
        user_dic = json.load(read_f)
        return user_dic

# 获取用户的身份
def get_status(user_dic):
    if user_dic['gender'] == '男':
        return '先生'
    else:
        return '女士'

goods_path = os.path.join(
        os.path.abspath('.'), 'db', 'goods_data','base.json'
    )
def get_goods_kind_dic():
    with open(goods_path,mode='r',encoding='utf-8') as f:
        goods_kind_dic = json.load(f)
        return goods_kind_dic
def save_goods_kind_dic(goods_kind_dic):
    with open(goods_path,mode='w',encoding='utf-8') as f:
        json.dump(goods_kind_dic,f,ensure_ascii=False)

14、operation.log

# 存放商城购物系统的操作日志,查看日志就在这里面查看就行了

15、start.py

运行这个程序文件,就行了!

'''
程序的入口
'''
import core.src as src
src.run()

四、运行效果展示

1、用户使用效果展示

--------- ATM+购物车系统 ---------
0 退出程序
1 注册功能
2 登录功能
3 管理员登录
-------------- end --------------
请输入功能编号:1
---------欢迎进入注册界面---------
请输入账户名:fuck
请输入密码:123
请再次确认密码:123
请输入您的性别:男
请输入您的邮箱地址:*********@qq.com
注册成功!
请输入功能编号:2
---------欢迎进入用户登录界面---------
请输入账户名:fuck
请输入密码:123
账号密码验证成功,正在向fuck的邮箱账号发送验证码...
请输入您的验证码:i58xy5
登录成功,欢迎fuck先生进入购物商城!
--------- ATM+购物车系统 ---------
0 用户登出
1 查看余额
2 提现功能
3 充值功能
4 转账功能
5 查看流水
6 购物功能
7 购物车功能
-------------- end --------------
fuck >>>1
尊敬的fuck先生您好!
您当前的账户余额: 15000 ¥
fuck >>>6
----------下面是三种类型的商品-----------
exit
food
sex_toy
special_service
snack
----------------end-----------------
商品种类选择 >>>food
----------food类型的所有商品如下-----------
0 返回上级菜单
1 阆中牛肉面 7 ¥
2 成都羊肉汤锅 300 ¥
3 成都麻辣兔头 8 ¥
4 狼牙土豆 5 ¥
5 孜然烤面筋 3 ¥
6 单人冒菜套餐 20 ¥
7 成都酸辣粉 10 ¥
8 单人份烧烤 10 ¥
9 伤心凉粉 7 ¥
10 北京烤鸭 100 ¥
-----------------end------------------
购买商品选择 >>>2
是否加入购物车(yes or no ?)yes
加入购物车成功
购买商品选择 >>>5
是否加入购物车(yes or no ?)no
支付中...
购买孜然烤面筋成功
购买商品选择 >>>10
是否加入购物车(yes or no ?)yes
加入购物车成功
购买商品选择 >>>
购买商品选择 >>>0
商品种类选择 >>>ls
----------下面是三种类型的商品-----------
exit
food
sex_toy
special_service
snack
----------------end-----------------
商品种类选择 >>>exit
fuck >>>ls
--------- ATM+购物车系统 ---------
0 用户登出
1 查看余额
2 提现功能
3 充值功能
4 转账功能
5 查看流水
6 购物功能
7 购物车功能
-------------- end --------------
fuck >>>7

        -------------购物车界面-------------
        exit 退出购物车
        0    查看购物车
        1    购物车付款
        2    清空购物车
        ----------------end---------------
        
请输入您的选择 >>>0

----------您的购物车商品如下----------
           成都羊肉汤锅 300 ¥
           北京烤鸭 100 ¥
----------------end----------------
请输入您的选择 >>>1
支付中...
付款成功!
请输入您的选择 >>>exit
fuck >>>ls
--------- ATM+购物车系统 ---------
0 用户登出
1 查看余额
2 提现功能
3 充值功能
4 转账功能
5 查看流水
6 购物功能
7 购物车功能
-------------- end --------------
fuck >>>5
请输入您要查看的最近流水条目数:10
2020-05-21 15:09:10 PM,购买北京烤鸭成功,付款:100 ¥
2020-05-21 15:09:10 PM,购买成都羊肉汤锅成功,付款:300 ¥
2020-05-21 15:08:42 PM,购买孜然烤面镜成功,付款3 ¥

2、管理员界面效果展示

--------- ATM+购物车系统 ---------
0 退出程序
1 注册功能
2 登录功能
3 管理员登录
-------------- end --------------
请输入功能编号:3
--------- 欢迎进入管理员登录界面 ---------
请输入管理员账号的密码:wjc5188891.
----------------- end ----------------
密码验证成功!正在向管理员账号发送验证码...
请输入您的验证码:62IGX7
登录成功,欢迎管理员进入购物商城后台管理系统!

        -------------- 管理员后台管理界面 --------------
                        exit    退出
                        0       修改登录密码
                        1       查看商品列表
                        2       添加商品
                        3       冻结账户
                        4       账号解冻
        -------------------- end --------------------
        
请输入您要执行的操作 >>>1

------------- 吴晋丞购物商城商品列表 -------------
            
food类型:
           1 阆中牛肉面
           2 成都羊肉汤锅
           3 成都麻辣兔头
           4 狼牙土豆
           5 孜然烤面筋
           6 单人冒菜套餐
           7 成都酸辣粉
           8 单人份烧烤
           9 伤心凉粉
           10 北京烤鸭
snack类型:
           1 泡椒臭干子

-------------------- end ---------------------
            
请输入您要执行的操作 >>>2
请输入商品的种类:snack
请输入商品的编号:2
请输入商品的名称:猪宝贝
请输入商品的价格:1
成功在snack类型商品中添加商品猪宝贝!
请输入您要执行的操作 >>>1

------------- 吴晋丞购物商城商品列表 -------------
            
food类型:
           1 阆中牛肉面
           2 成都羊肉汤锅
           3 成都麻辣兔头
           4 狼牙土豆
           5 孜然烤面筋
           6 单人冒菜套餐
           7 成都酸辣粉
           8 单人份烧烤
           9 伤心凉粉
           10 北京烤鸭
snack类型:
           1 泡椒臭干子
           2 猪宝贝

-------------------- end ---------------------
            
请输入您要执行的操作 >>>ls

        -------------- 管理员后台管理界面 --------------
                        exit    退出
                        0       修改登录密码
                        1       查看商品列表
                        2       添加商品
                        3       冻结账户
                        4       账号解冻
        -------------------- end --------------------

3、日志展示

在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章