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、日誌展示

在這裏插入圖片描述

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