主頁 > 軟體設計 > 專案:ATM+購物車(超級詳解,已完結)

專案:ATM+購物車(超級詳解,已完結)

2021-01-02 11:05:52 軟體設計

python基礎要打牢,ATM+購物車拿來練手不錯,另外也可以了解開發軟體的流程,總之感覺nice(),

2020.12.31今天是2020年最后一天,意義非凡,ATM+購物車是我第一次寫的比較正規龐大的專案……原諒我沒做過課設,感覺其實用三層架構來寫也沒那么難,(不過我打算上周天和上周一寫完的…執行力不夠)且當跨年禮物吧…2021再繼續哈哈哈哈哈,

文章目錄

  • 一、 需求分析
  • 二、程式的架構分析
    • 一個專案怎么從無到有
      • 1.1需求分析
      • 1.2程式的架構設計
      • 1.3分任務開發
      • 1.4測驗
      • 1.5上線
  • 三、軟體開發目錄
  • 四、創建用戶功能字典及搭建用戶視圖層
  • 五、詳細寫各個功能
    • 1、注冊功能
    • 2、登錄功能
    • 3、查看余額
    • 4、提現功能
    • 5、還款功能
    • 6、轉賬功能
    • 7、查看流水
    • 8、購物功能
    • 9、查看購物車
    • 10、管理員功能
      • 10.1搭建管理員視圖層以及管理員功能字典
      • 10.2實作管理員各個功能
  • 六、演示視頻

一、 需求分析

模擬實作一個ATM + 購物商城程式

1. 額度 15000或自定義  ==》注冊功能
2.實作購物商城,買東西加入 購物車,呼叫信用卡介面結賬 ==》購物功能、支付功能
3.可以提現,手續費5% ==》提現功能
4.支持多賬戶登錄 ==》登陸功能
5.支持賬戶間轉賬 ==》轉賬功能
6.記錄日常消費流水 ==》記錄流水功能
7.提供還款介面 ==》還款功能
8.ATM記錄操作日志 ==》日志功能
9.提供管理介面,包括添加賬戶、用戶額度,凍結賬戶等,,,==》管理功能
10.用戶認證用裝飾器==》登陸認證裝飾器

"用戶視圖層" 展示給用戶選擇的功能
    1、注冊功能
    2、登錄功能
    3、查看余額
    4、提現功能
    5、還款功能
    6、轉賬功能
    7、查看流水
    8、購物功能
    9、查看購物車
    10、管理員功能

二、程式的架構分析

一個專案怎么從無到有

1.1需求分析

客戶提出需求,公司拿到專案
——》公司出人去(一般一個前端一個后端)和客戶討論需求、商品需求功能的可實作性、專案價格、開發周期等,得到一個需求檔案
——》公司內部開會得到一個開發檔案交給不同崗位的程式員開發,

	- Python: 后端,爬蟲
    
    - 不同的崗位:
        - UI界面設計:
            - 設計軟體的布局,會分局軟體的外觀切成一張張圖片,
        
        - 前端:
            - 拿到UI交給他的圖片,然后去搭建網頁面,
            - 設計一些頁面中,哪些位置需要接收資料,需要進行資料互動,
        
        - 后端:
            - 直接核心的業務邏輯,調度資料庫進行資料的增刪查改,
        
        - 測驗:
            - 會給代碼進行全面測驗,比如壓力測驗,界面測驗(CF卡箱子),
        
        - 運維:
            - 部署專案,

1.2程式的架構設計

	1.程式設計的好處
 	1)思路清晰
    2)不會出現寫一半代碼時推翻重寫的情況
    3)方便自己或以后的同事更好維護
	
	2.三層架構設計的好處
    1)把每個功能都分層三部分,邏輯清晰
    2)如果用戶更換不同的用戶界面或不同,
       的資料儲存機制都不會影響介面層的核心
       邏輯代碼,擴展性強,
    3)可以在介面層,準確的記錄日志與流水,
    
    3.三層架構
    
    一 用戶視圖層
  用于與用戶互動的,可以接受用戶的輸入,列印介面回傳的資料,

	二 邏輯介面層
  接受 用戶視圖層 傳遞過來的引數,根據邏輯判斷呼叫資料層加以處理,并回傳一個結果給 用戶視圖層,

 	三 資料處理層
  接受介面層傳遞過來的引數,做資料的處理
    - 保存資料  
    - 查看資料  
    - 更新資料
    - 洗掉資料

程式架構圖:
程式架構圖

1.3分任務開發

1.4測驗

1.5上線

三、軟體開發目錄

conf:專案的配置資訊
core:核心的代碼
db:資料
interface:介面
lib:共用的一些功能
log:日志
readme:介紹專案的功能使用等
srart.py:專案的啟動檔案

在這里插入圖片描述

四、創建用戶功能字典及搭建用戶視圖層

core中src代碼如下

# 1.注冊功能
def register():
    ...
#2.登錄功能
def login():
    ...
#3.查看余額
def check_banlance():
    ...
#4.提現功能
def withdraw():
    ...
#5.還款功能
def repay():
    ...
#6.轉賬功能
def transfer():
    ...
#7.查看流水
def check_flow():
    ...
#8.購物功能
def shopping():
    ...
#9.查看購物車
def check_shop_car():
    ...
#10.管理員功能
def admin():
    ...

fuc_dic = {
    '1':register,
    '2':login,
    '3':check_banlance,
    '4':withdraw,
    '5':repay,
    '6':transfer,
    '7':check_flow,
    '8':shopping,
    '9':check_shop_car,
    '10':admin
}
def run():
    while True:
        print('''
    ====== ATM+購物車======
        1、注冊功能
	    2、登錄功能
	    3、查看余額
	    4、提現功能
	    5、還款功能
	    6、轉賬功能
	    7、查看流水
	    8、購物功能
	    9、查看購物車
	    10、管理員功能
	====== THE END======
	''')
        #接受用戶輸入
        choice = input('請輸入命令編號:').strip()
        #判斷命令編號是否合法
        if choice in fuc_dic:
            fuc_dic[choice]()
        else:
            print('請輸入合法的命令編號!')

start.py代碼如下


import os
import sys

# 添加解釋器的環境變數

sys.path.append(os.path.dirname(__file__))

from core import src
if __name__ == '__main__':
    src.run()

五、詳細寫各個功能

1、注冊功能

核心邏輯分析

用戶在視圖層輸入賬號和密碼,將賬號和密碼交給邏 輯 處理層,邏輯處理層呼叫資料處理層的功能來判斷賬號和密碼是否存在,存在與否,則回傳相應結果給邏輯處理層(介面層),若賬號密碼存在,則介面層直接回傳,若不存在需要介面層需要完成注冊功能,介面層需要做的是組織用戶的資訊,然后呼叫資料處理層的功能將用戶資訊寫入相應json檔案并回傳,最終由介面層將是否注冊成功回傳給用戶視圖層,

def register():
    while True:
        # 1.用戶輸入用戶名和密碼進行校驗
        name = input('請輸入用戶名:').strip()
        pwd = input('請輸入密碼:').strip()
        re_pwd = input('請確認密碼').strip()
        # 2.小的邏輯判斷
        if pwd == re_pwd:
            # 呼叫介面層來判斷是否注冊成功
            res,tag= user_interface.register_interface(name,pwd)
            if res:
                print(tag)
                break
            else:
                print(tag)

interface中的注冊介面

def register_interface(username,password,balance = 15000):
    # 1.呼叫資料處理層中的select函式會回傳用戶資訊字典或者None
    if db_handler.select(username):
        return False,'用戶已存在,請重新輸入!'
    else:
        password = common.get_pwd_md5(password)
        #1.組織用戶資訊,準備注冊
        user_dic = {
            'username': username,
            'password': password,
            'balance': balance,
            # 用于記錄用戶流水的串列
            'flow': [],
            # 用于記錄用戶購物車
            'shop_car': {},
            # locked:用于記錄用戶是否被凍結
            # False: 未凍結   True: 已被凍結
            'locked': False
        }
        # 2.呼叫資料處理層的保存函式將用戶資訊寫入檔案
        #密碼加密
        db_handler.save(user_dic)
        return True, f'{username} 注冊成功!'

資料處理層功能的select功能

def select(username):
    # 1.接收用戶名,拼接用戶資訊的完整json路徑
    user_path = os.path.join(
        settings.BASE_PATH,f'{username}.json'
    )

    # 2.判斷用戶json檔案是否存在
    if os.path.exists(user_path):
        with open(user_path,'r',encoding='utf-8') as f:
            user_dic = json.load(f)
            return user_dic
    # 不return默認回傳None

conf下的配置資訊

import os

BASE_PATH = os.path.dirname(
    os.path.dirname(__file__))

lib中的common.py密碼加密功能

# 密碼加密
def get_pwd_md5(pwd):
    m = hashlib.md5(pwd.encode('utf-8'))
    salt = 'wangxunzhidashuaibi'
    m.updae(salt.encode('utf-8'))
    return m.hexdegist()

2、登錄功能

核心邏輯分析
用戶在視圖層輸入賬號和密碼交給登錄介面層,介面層呼叫資料處理層的功能來判斷用戶是否登錄成功,另外加了一個用戶的登錄狀態變數login_user用于記錄用戶登錄狀態和一個用戶登錄認證裝飾器,

def login():
    while True:
        name = input('請輸入你的賬號:').strip()
        password = input('請輸入你的密碼:').strip()
        # 登錄介面:
        #登錄成功回傳True,登錄成功
        res,tag = user_interface.login_interface(name,password)
        if res:
            global login_user
            login_user = name
            print(tag)
            break
        else:
            print(tag)

interface中的登錄介面

def login_interface(name,password):
    # 呼叫資料處理層的select功能,來校驗用戶登錄是否成功

    # 回傳user_dic 或者None
    res = db_handler.select(name)
    if res:
        # 給用戶輸入的密碼加密
        password = common.get_pwd_md5(password)
        if password == res.get('password'):
            return True,'登錄成功!'
        else:
            return False,'密碼錯誤!'
    return False,'用戶不存在!請重新輸入!'

用戶登錄認證

from core import src
def login_auth(func):
    def outter(*args,**kwargs):
        if src.login_user:
            res = func(*args,**kwargs)
            return res
        else:
            print('未登錄,無法使用該功能!請登錄!')
            src.login()
    return outter

3、查看余額

核心邏輯分析
用戶登錄后(未登錄會被強制登錄),查看余額,直接呼叫查看余額介面,查看余額介面呼叫資料處理層中的功能,完成任務,

@common.login_auth
def check_banlance():
    #直接呼叫查看余額介面
    #回傳余額
    banlance = user_interface.check_balance_interface(login_user)
    print(f'====用戶{login_user}余額為{banlance}====')

interface查看余額介面


# 查看余額介面
def check_bal_interface(username):
    user_dic = db_handler.select(username)
    return user_dic['balance']

4、提現功能

核心邏輯分析
用戶在登錄后(未登錄會強制登錄),在用戶視圖層輸入提現金額,呼叫介面層中的提現介面,在提現介面中呼叫了資料處理層中的功能回傳給介面層,介面層完成邏輯處理后將結果回傳視圖層,

記錄流水和日志:要在介面層接入記錄日志的功能,
原因:介面層是處理邏輯的核心所在,用戶每次有提現/還款等功能都需要經過介面層,

注意:
轉賬要注意手續費的處理,以及用戶輸入的是否為數字等細節判斷,

#4.提現功能
@common.login_auth
def withdraw():
    while True:
        # 1.讓用戶輸入提現金額
        money = input('請輸入提現金額:').strip()

        # 2.小邏輯判斷:判斷用戶輸入的是否為數字
        if money.isdigit():
            # 呼叫提現介面層
            # 回傳(bool,str)
            flag,msg=bank_interface.withdraw_interface(login_user,money)
            if flag:
                print(msg)
                break
            else:
                print(msg)
        else:
            print('您的輸入不合法,請您輸入數字,比如1220')

interface提現介面

def withdraw_interface(name,money):
    #1.拿到用戶資訊
    user_dic = db_handler.select(name)
    #2.查看賬戶的余額
    balance = user_dic.get('balance')
    #判斷余額是否大于提現金額和手續費
    if balance >= int(money) * 1.05:
        balance -= int(money) * 1.05
        user_dic['balance'] = balance

        #記錄流水
        flow =f'用戶{name}提現{money}成功!' \
                    f'手續費為{int(money)*0.05},余額為{balance}'
        user_dic['flow'].append(flow)
        #保存或者更新用戶資料
        db_handler.save(user_dic)
        #流水既輸出在螢屏上,也保存在檔案中
        bank_logger.info(flow)

        return True,flow
    else:
        return False,'提現失敗!請重新輸入金額!'

common.py中日志功能(在介面層記錄日志)

def get_logger(log_type):  # log_type ---> user
    '''
    :param log_type: 比如是 user日志,bank日志,購物商城日志
    :return:
    '''
    # 1、加載日志配置資訊
    logging.config.dictConfig(
        settings.LOGGING_DIC
    )

    # 2、獲取日志物件
    logger = logging.getLogger(log_type)

    return logger

settings.py新增日志配置字典

"""
logging配置
"""

# 定義三種日志輸出格式 開始
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'

# 定義日志輸出格式 結束
# ****************注意1: log檔案的目錄
# BASE_PATH = os.path.dirname(os.path.dirname(__file__))
logfile_dir = os.path.join(BASE_PATH, 'log')
# print(logfile_dir)

# ****************注意2: log檔案名
logfile_name = 'atm.log'

# 如果不存在定義的日志目錄就創建一個
if not os.path.isdir(logfile_dir):
    os.mkdir(logfile_dir)

# log檔案的全路徑
logfile_path = os.path.join(logfile_dir, logfile_name)

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': 'DEBUG',
            'propagate': True,  # 向上(更高level的logger)傳遞
        },
    },
}

interface中新增bank_log日志物件

#銀行流水日志物件
bank_logger = common.get_logger('bank')

5、還款功能

核心邏輯分析
用戶在視圖層輸入還款金額,由介面層進行與資料處理層進行互動,完成功能,

@common.login_auth
def repay():
    while True:
        money = input('請輸入你要還款的金額:').strip()
        if money.isdigit():
            if eval(money) >=0:
                # 接入還款介面
                flag,msg = bank_interface.repay_interface(login_user,money)
                if flag:
                    print(msg)
                    break
            else:
                print('金額不能小于0!請重新輸入!')
        else:
            print('必須輸入數字!請重新輸入!')

interface還款介面

def repay_interface(name,money):
    #1.得到用戶資訊字典
    user_dic = db_handler.select(name)
    #2.將還款金額加入用戶余額
    user_dic['balance'] += eval(money)
    #3.記錄流水
    flow = f'====用戶{name}還款{money}元成功,' \
           f'現有{user_dic["balance"]}元===='
    bank_logger.info(flow)
    #4.保存或者更新用戶資訊
    db_handler.save(user_dic)

    return True,flow


6、轉賬功能

核心邏輯分析
用戶輸入要轉入的賬戶和金額,傳入轉賬介面,轉賬介面利用資料處理層的select和save完成功能,

def transfer():
    while True:
        #1.接收轉賬物件及金額
        name = input('請輸入你要轉賬物件:').strip()
        money = input('請輸入你要轉賬金額:').strip()
        #2.判斷用戶輸入的金額是否為數字以及是否>0
        if money.isdigit():
            if eval(money) > 0:
                flag,msg=bank_interface.transfer_interface(name,money)
                if flag:
                    print(msg)
                    break
                else:
                    print(msg)

            else:
                print('轉賬金額必須大于0!')
        else:
            print('必須輸入數字!')

轉賬介面

def transfer_interface(name,money):
    #1.判斷被轉賬用戶是否存在
    #接入資料處理層的查找功能,回傳user_dic 或者None
    res = db_handler.select(name)
    if not res:
        return False,'目標用戶不存在!'

    #2.獲取當前用戶資料
    user_dic = db_handler.select(src.login_user)

    #3.判斷當前用戶的余額是否夠轉賬
    money = eval(money)
    if user_dic.get('balance') > money:
        user_dic['balance'] -= money
        res['balance'] += money
    else:
        return False,'用戶的錢不夠轉賬!'

    #4.記錄流水
    from_log_flow = f'用戶給用戶{name}轉賬{money}元成功!'
    user_dic['flow'].append(from_log_flow)
    to_user_flow = f'用戶接受用戶{src.login_user}轉賬{money}元成功!'
    res['flow'].append(to_user_flow)
    bank_logger.info(f'用戶{src.login_user}給用戶{name}轉賬{money}元成功!')

    #5.更新用戶資料
    db_handler.save(user_dic)
    db_handler.save(res)

    return True,from_log_flow

7、查看流水

核心邏輯分析
用戶在視圖層選擇查看流水功能,呼叫查看流水介面,流水介面呼叫資料處理層的查看功能完成功能,

#7.查看流水
@common.login_auth
def check_flow():
    #接入查看流水介面
    res = bank_interface.check_flow_interface(login_user)
    if res:
        n = 1
        for i in res:
            print(f'{n}:{i}')
            n+=1
    else:
        print('用戶{name}無流水記錄!')

查看流水介面

def check_flow_interface(login_user):
    user_dic = db_handler.select(login_user)
    return user_dic.get('flow')

8、購物功能

核心邏輯分析
用戶在視圖層選擇購物后==》
看到商品資訊==》
選擇購物/支付/加入購物車==》

1.購物:需要對用戶輸入的指令進行判定
2.支付:計算當前購物車總花費,接入支付介面,完成支付
3.加入購物車:讀取之前的購物車,若存在加入重復的商品	名,則數量增加,否則新增購物,最后更新購物車
#8.購物功能
@common.login_auth
def shopping():
    # 1.列印商品資訊
    shop_list = []
    print('============歡迎來到有趣用品商城============')
    with open(r'F:\ATM+購物車\db\shoppings.txt',encoding='utf-8') as f:
        n = 1 # 記錄商品編號
        for line in f:
            shop_name,shop_price  = line.strip().split(':')
            shop_price = eval(shop_price)
            shop_list.append((shop_name,shop_price))
            print(f'商品編號:{n},'
                  f'商品名稱:{shop_name},'
                  f'商品單價:{shop_price}')
            n+=1
    print('================24小時服務================')
    # 2.初始化購物車
    shopping_car = {}

    #3.模擬用戶購物
    while True:
        choice = input('請輸入商品編號(若結賬輸入y 添加購物車輸入n):').strip()

        #3.1選擇結賬
        if choice == 'y':
            # 判斷購物車是否為空 ==》
            #空==》不能支付
            #否則==》呼叫支付介面
            if not shopping_car:
                print('購物車為空,無法支付!')
            else:
                #呼叫商品結算介面
                flag,msg=shop_interface.shopping_interface(shopping_car,login_user)
                if flag:
                    print(msg)
                    break
                else:
                    print(msg)


        elif choice == 'n':
            #判斷購物車內是否為空
            # 空==》提示用戶選擇商品
            # 非空 ==》代表用戶選擇了商品加入了購物車
            if not shopping_car:
                print('當前購物車為空,請在該購物車內添加商品!')
            else:
                #接入添加購物車介面
                res = shop_interface.add_shop_car(login_user,shopping_car)
                if res:
                    print('添加購物車成功!')
                    break
                else:
                    print('添加購物車失敗!')
        else:
            #模擬用戶選擇商品
            #判斷用戶輸入的編號是否合法
            if not choice.isdigit():
                print('請輸入數字編號!')
            elif not type(eval(choice)) is  int:
                print('請輸入整數編號!')
            elif eval(choice) > n or eval(choice) < 1:
                print('請輸入1-{n}內的編號!')
            else:
                #獲取用戶所選商品的名字和單價
                shop_name,shop_price = shop_list[eval(choice)-1]
                #采用{'name':[price,number]}形式組織購物車
                if shop_name in shopping_car:
                    shopping_car[shop_name][1]+=1
                else:
                    shopping_car[shop_name] = [shop_price,1]
                print(f'當前購物車{shopping_car}')

商品結算介面和添加購物車介面

#商品結算介面
def shopping_interface(shopping_car,name):
    #1.計算用戶商品總花銷
    cost= 0
    # 采用{'name':[price,number]}形式組織購物車
    for i in shopping_car.values():
        price,number = i
        cost+=price*number

    #2.支付
    #呼叫銀行支付介面
    flag,msg=bank_interface.pay_interface(name,cost)
    return flag,msg

#添加購物車介面
def add_shop_car(name,shopping_car):
    # 獲取用戶購物車
    use_dic = db_handler.select(name)
    user_car = use_dic['shop_car']

    #添加購物車
    for shop_name,shop_price_num in shopping_car.items():
        shop_price,shop_num  = shop_price_num
        #判斷商品在不在購物車里面,若在則數量增加
        #否則將商品添加到購物車里
        #購物車組織{商品名:[單價,數量]}
        if shop_name in user_car:
            use_dic['shop_car'][shop_name][1] += shop_num
        else:
            use_dic['shop_car'][shop_name] = [shop_price,shop_num]
            #等同于use_dic['shop_car'].update({shop_name:[shop_price,shop_num]})
        #更新購物車資料
        db_handler.save(use_dic)
        return True

支付介面

# 支付介面
def pay_interface(login_user, cost):
    user_dic = db_handler.select(login_user)

    # 判斷用戶金額是否足夠
    if user_dic.get('balance') >= cost:
        # 減錢
        user_dic['balance'] -= cost

        # 記錄消費流水
        flow = f'用戶消費金額: [{cost}$]'
        user_dic['flow'].append(flow)

        # 保存資料
        db_handler.save(user_dic)

        # return True 或 return False 交給購物介面來做處理
        return True

    return False

9、查看購物車

核心邏輯分析
和查看余額一樣,直接呼叫介面層,利用資料處理層查看功能完成任務,

#9.查看購物車
@common.login_auth
def check_shop_car():
    #呼叫查看購物車介面
    res = shop_interface.check_spc(login_user)
    if res:
        for i in res:
            print(i)
    else:
        print('用戶購物車內沒東西!')

查看購物車介面

def check_spc(name):
    user_dic = db_handler.select(name)
    shop_car = user_dic['shop_car']
    return shop_car

10、管理員功能

核心邏輯分析
有點像寫一個小的ATM+購物車,只不過功能不一樣,

管理員需要有的功能分析如下:
1.添加用戶
2.修改用戶額度
3.凍結用戶

與寫整個專案不同,管理員功能相對來說比較獨立,我們在寫這個功能的時候,同樣采取三層架構,
即管理員視圖層=》管理員介面層=》管理員資料處理層,但這里處理的是用戶的資料,其實也是用戶資料處理層,
#添加用戶
def add_user():
    ...

#修改用戶額度
def change_balance():
    ...

#凍結用戶
def lock_user():
    ...

#管理員功能字典
admin_dic={}

#管理員視圖層
def admin_run():
    print('=====歡迎進入管理員功能區=====')
    

10.1搭建管理員視圖層以及管理員功能字典

#管理員功能字典
admin_dic={
    '0':['退出',None],
    '1':['添加用戶',add_user],
    '2':['修改用戶額度',change_balance],
    '3':['凍結用戶',lock_user]
}

#管理員視圖層
def admin_run():
    print('=====歡迎進入管理員功能區=====')
    #展示管理員功能
    while True:
        for k,v in admin_dic:
            print(f'{k}:{v[0]}')
    
        #管理員選擇功能
        choice = input('請輸入您想要使用的管理員功能').strip()
        
        #判斷用戶輸入的合法性
        if choice not in admin_dic:
            print('請您輸入合法的數字!')
        else:
            admin_dic[choice][1]()

10.2實作管理員各個功能

1、添加用戶功能

#添加用戶
def add_user():
    #相當于注冊一個用戶
    src.register()

2、修改用戶額度功能

#修改用戶額度
def change_balance():
    #獲取要修改物件的賬號和所要修改的額度
    while True:
        name = input('請輸入要修改的賬號:').strip()
        balance = input('請輸入要修改的額度:').strip()

        #判斷輸入額度的合法性
        if not balance.isdigit():
            print('輸入不合法!')
        else:
            #修改用戶的額度,呼叫修改用戶額度介面
            #修改成功回傳 True和日志
            flag,msg = admin_interface.change_balance(name,balance)
            if flag:
                print(msg)
                break
            print(msg)

修改用戶額度介面

#修改用戶額度
def change_balance(name,money):
    #獲取用戶的資訊字典
    #接入資料處理層查看資料:回傳用戶資訊字典或者None
    user_dic = db_handler.select(name)

    if user_dic:
        #修改額度
        user_dic['balance'] = eval(money)
        #記錄流水
        flow = f'管理員{src.login_user}修改{name}用戶額度為{money}成功!'
        admin_logger.info(flow)
        #保存資料
        db_handler.save(user_dic)
        return True,flow
    return False,'用戶不存在!'

3、凍結用戶功能

#凍結用戶
def lock_user():
    while True:
        name = input('請您輸入要凍結的賬號名').strip()

        #呼叫凍結用戶介面
        flag,msg = admin_interface.lock_user_interface(name)
        if flag:
            print(msg)
            break
        print(msg)

凍結用戶介面

#凍結用戶
def lock_user_interface(name):
    #拿到用戶資訊字典
    user_dic = db_handler.select(name)
    if user_dic:
        #locked:用于記錄用戶是否被凍結
        # False: 未凍結   True: 已被凍結
        user_dic['locked'] = 'True'
        #記錄日志
        msg =f'用戶{name}被凍結!'
        admin_logger.info(msg)
        #保存資料
        db_handler.save(user_dic)
        return True,msg
    return False,'用戶不存在!'

六、演示視頻

ps:ATM+購物車專案壓縮包私我

<iframe id="uVnhApXu-1609507476996" src="https://player.bilibili.com/player.html?aid=928468051" allowfullscreen="true" data-mediaembed="bilibili"></iframe>

ATM+購物車

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/243559.html

標籤:其他

上一篇:作業五年經驗總結

下一篇:DVWA+Xampp靶機搭建

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more