python之信用卡ATM(第五天)

来源:http://www.cnblogs.com/wushank/archive/2016/03/06/5248916.html
-Advertisement-
Play Games

本節作業 作業需求: 模擬實現一個ATM + 購物商城程式 額度 15000或自定義 實現購物商城,買東西加入 購物車,調用信用卡介面結賬 可以提現,手續費5% 每月22號出賬單,每月10號為還款日,過期未還,按欠款總額 萬分之5 每日計息 支持多賬戶登錄 支持賬戶間轉賬 記錄每月日常消費流水 提供


本節作業

作業需求:

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

  1. 額度 15000或自定義
  2. 實現購物商城,買東西加入 購物車,調用信用卡介面結賬
  3. 可以提現,手續費5%
  4. 每月22號出賬單,每月10號為還款日,過期未還,按欠款總額 萬分之5 每日計息
  5. 支持多賬戶登錄
  6. 支持賬戶間轉賬
  7. 記錄每月日常消費流水
  8. 提供還款介面
  9. ATM記錄操作日誌
  10. 提供管理介面,包括添加賬戶、用戶額度,凍結賬戶等。。。

    因對本次作業的MVC結構沒有思路,故研究分析了王松牛人的作業,現整理如下:

 

一、作業代碼具體說明如下:

一、主程式day5_credit_card.py開始
   1、生成today今天的日期和星期數weekoftoday
   2、定義currusers:實例化modules下的users.py中的類Users
   3、初始化對賬單report.create_statement_main()
       (1)、從database目錄下的文件creditcard中讀取信用卡列表
       (2)、迴圈列表調用 create_card_statement
       (3)、create_card_statement函數說明
            3.1 獲取當前日期currday和today
            3.2 如果當天是22號出帳日:
              3.2.1 賦值startday,endday,startdate,enddate,statement_key出帳起始結束時間
              3.2.2 獲取卡號對應的消費流水列表dbapi.load_bill_report(cardno, startdate, enddate)
              3.2.3 statement_dict的信息追加到信用卡帳單信息中。
   4、迴圈菜單
       (1)、判斷用戶是否登錄,並輸出相應用戶信息
              未登錄輸出template.index_default_menu.format("", today, common.numtochr(weekoftoday))
              否則輸出template.index_logined_menu.format("歡迎您: {0}".format(curruser.name), today,common.numtochr(weekoftoday))
       (2)、輸出用戶選擇菜單
       (3)、輸入5,則退出菜單
       (4)、輸入1,首先載入當年用戶信息curruser.db_load(),然後調用doshopping(curruser)
       (5)、輸入2,首先載入當年用戶信息curruser.db_load(),然後調用user_login(curruser, today, weekoftoday)
       (6)、輸入3,調用card_center(curruser)信用卡中心
       (7)、輸入4,調用manager(curruser)後臺管理
   5、菜單1:doshopping商城函數
       (1)、實例化商城,調用shopping.Shopping()
       (2)、迴圈開始,輸出商品菜單shoppobj.welcome_menu
       (3)、輸入編號選擇並賦值shop_cassify_id,併進行輸入驗證判斷
       (4)、輸入值為4,進行購物車商品顯示shopping.Shopping.print_goods_list(shoppobj.shopping_cart)
              並顯示common.show_message("當前購物車共有 {0} 件商品,合計 {1} 元)
       (5)、輸入值為5,shoppobj.payfor_shopcart(userobj),無錯誤,輸出支付成功
       (6)、輸入值為1-3,則調用shoppobj.get_goods_list_by_typeid(),顯示商品分列表
       (7)、第二層迴圈開始,並顯示指定商品分類下的所有商品列表(Shopping類靜態方法)
              shopping.Shopping.print_goods_list(goods_list)
       (8)、選擇商品編號goods_id,加入購物車,並對輸入進行判斷
            8.1 如果輸入為q,返回上一層
            8.2 調用商品加入購物車函數shoppobj.add_shopping_card(goods_id)
            8.3 如果返回正確,則顯示購物車所有商品信息shopping.Shopping.print_goods_list(shoppobj.shopping_cart),並輸出common.show_message("已將商品加入購物車!", "INFORMATION")
               第三層迴圈開始,顯示“繼續購物(y) or 返回上一級(q)”,
            8.4 如果返回失敗,則輸出common.show_message("添加購物車失敗,請檢查輸入商品編號是否正確!", "ERROR"),並continue
   6、菜單2:user_login(curruser, today, weekoftoday)用戶登錄
       (1)、迴圈開始
       (2)、判斷用戶是否登錄成功userobj.islogin,
            2.1 如果已經登錄,則顯示個人中心菜單 template.index_user_center.format(userobj.name, today, common.numtochr(weekoftoday)) 
            2.2 輸出選擇功能菜單,選擇6,返回上級菜單
            2.3 如果選擇1-5,則通過反射來執行,從 template 模塊查找各按鍵對應的模塊
                func_dict = template.user_center_func
            2.4 根據輸出的數字,賦值相應的模塊名稱,modulepy = __import__(func_dict[_choose]["module"])
            2.5 如果選擇的是1,2,5,則賦值modulesobj 、classobj、func
   7、菜單3:card_center(curruser)信用卡中心
       (1)、判斷用戶是否登錄
            1.1 已登錄,則重新load一下數據userobj.db_load(),並獲取到綁定的信息卡信息cardno = userobj.bindcard
            1.2 獲得信用卡對象card = CreditCard(cardno)
            1.3 如果未登錄,則進行迴圈,讓用戶輸入信用卡和密碼進行認證
       (2)、顯示登錄輸出菜單index_ATM,迴圈開始:
       (3)、輸入common.input_msg("請選擇功能: ", ("1", "2", "3", "4", "5"))
       (4)、如果輸入是5,就返回上一層迴圈
       (5)、如果輸入是1,則查看信用卡信息
       (6)、如果輸入是2,則進行提現菜單
            6.1 如果card.frozenstatus狀態是1,則提示“卡已凍結,請聯繫客服”
            6.2 否則提示“信用卡提現將收取 {0}% 的手續費!”
            6.3 迴圈開始,提示"請輸入要提現的金額(q返回):"
            6.4 輸入正確的話,提示輸入信用卡密碼進行確認
            6.5 執行提現函數card.fetch_money(float(cost), cardpasswd),並根據返回結果進行輸出相應信息
       (7)、如果輸入是3,則進入轉帳菜單
            7.1 如果card.frozenstatus狀態是1,則提示“卡已凍結,請聯繫客服”
            7.2 否則提示“信用卡轉帳將收取 {0}% 的手續費!”
            7.3 迴圈開始,提示"請輸入要轉賬的卡號(q返回)"
            7.4 對卡號是數字,則生成一個trans_cardobj = CreditCard(trans_cardno)
            7.5 進行卡號判斷存在的話,提示是轉賬的金額,
            7.6 如果金額正確並輸入信用卡密碼進行確認
            7.5 執行轉帳函數card.translate_money(float(trans_cost), cardpasswd, trans_cardobj) ,並根據返回結果進行輸出相應信息  
       (8)、如果輸入是4,則進入還款菜單
            8.1 調用card.recreate_statement()函數,更新一下對賬單信息
            8.2 迴圈開始,獲取對賬單所有列表interest_list = card.load_statement_list()
            8.3 獲取還未還款的記錄並顯示message_info = report.print_statement_list(card.cardno, interest_list)
            8.4 如果有要還款的記錄,則顯示具體帳單信息
            8.5 請選擇還款的16位賬單號,然後進行判斷,
            8.6 輸出正確,則顯示指定單號的相應對賬單信息report.print_statement_detail
            8.7 輸入還款金額,並更新已還款金額 = 現在還的金額 + 已經還的金額
            8.8 需要還款數 = 消費總費用 + 利息 ,並判斷是否已還清,如果還清則設置interest_list[i][pay_serno]["isfinished"] = 1
            8.9 如果未還清,則顯示“您尚未全部還款,請在還款日前儘快還款!”
            8.10 將還款後的信息寫入資料庫更新dbapi.write_statement_list(card.cardno, interest_list)
            8.11 顯示是否繼續還款。
   8、菜單4:主菜單後臺管理模塊manager(userobj):
       (1)、用戶是否登錄,是否是角色是否是admin
       (2)、是admin,進入迴圈,顯示template.index_admin
       (3)、選擇菜單,輸入1時,進入創建新用戶調用User類中的init_user_info()函數
       (4)、選擇菜單,輸入2時,進入刪除用戶菜單調用get_users()函數
            4.1 get_users() 顯示用戶的信息,用戶新建、刪除、解鎖用戶時顯示用戶基本信息
            4.2 輸入操作的用戶名
            4.3 創建一個用戶實例_deluser = Users(),並賦值_deluser.username = username
            4.4 _deluser.load_user_info()判斷,如果用戶名存在,load用戶信息成功,顯示用戶信息,返回用戶
            4.5 用戶不存在,返回失敗
            4.6 調用_user.del_user(),並顯示刪除用戶成功
       (5)、選擇菜單,輸入3時,進行鎖定用戶菜單調用get_users()函數,方式同上
       (6)、選擇菜單,輸入4時,進入發行信用卡菜單
            6.1 調用newcard = fill_card_info()函數,填充信用卡資料信息,返回一個信用卡對象
            6.2 迴圈開始,輸入卡號,並判斷卡號是否存在,不存在退出迴圈
            6.3 在依次輸入密碼,額度等信息,並返回一個信用卡對象
       (7)、選擇菜單,輸入5時,進入凍結信用卡
            7.1 輸入要操作卡號
            7.2 card = CreditCard(cardno),實例化信用卡
            7.3 判斷信用卡是否存在card.card_is_exists
            7.4 存在則輸入卡信息,併在次確定是否凍結
            7.5 card.frozenstatus = 1設置卡的標誌位,card.update_card()更新信用卡文件
       (8)、選擇菜單,輸入0時,返回上層菜單

 
二、包conf說明:
   1、errorcode.py介紹:
       定義系統錯誤代碼表:NO_ERROR,USER_NOT_EXISTS,CARD_NOT_BINDED,BALANCE_NOT_ENOUGHT,CARD_OWNER_ERROR,CARD_PASS_ERROR
   2、settings.py介紹:定義一系列變數值
       2.1 定義程式文件主目錄BASE_DIR,並加入環境變數
       2.2 定義資料庫信息DATABASE
       2.3 定義日誌文件存放路徑LOG_PATH
       2.4 定義賬單報表文件路徑REPORT_PATH
       2.5 定義用戶登錄失敗最大次數ERROR_MAX_COUNT
       2.6 定義日息費率EXPIRE_DAY_RATE
       2.7 定義轉賬、提現手續費FETCH_MONEY_RATE
       2.8 定義信用額度CREDIT_TOTAL
       2.9 定義每月賬單日期STATEMENT_DAY
   3、template.py介紹:該模塊用來定義系統的菜單模板
       3.1 主程式中的主菜單index_default_menu
       3.2 主程式中的用戶登錄後的顯示菜單index_logined_menu
       3.3 主程式中的用戶中心菜單index_user_center
       3.4 用戶中心按鍵對應功能模塊user_center_func
       3.5 購物模塊的主菜單, menu 菜單在shopping模塊中內部構造shopping_index_menu 
       3.6 賬單報表顯示模板report_bill
       3.7 購物歷史記錄顯示模板shopping_history
       3.8 後臺管理模板index_admin
       3.9 ATM 管理模塊index_ATM
       3.10 顯示用戶基本信息模板user_info
       3.11 顯示信用卡基本信息模板card_info
       3.12 信用卡對賬單列表模板report_statement_list
       3.13 信用卡對賬單詳細模板report_statement_detail

三、包database介紹:
   1、init_db.py介紹:
       1.1 定義商品列表_shopping_list
       1.2 定義用戶列表_user_list
       1.3 定義信用卡列表_creditcard_list
       1.4 函數init_db_shoppingmark() 初始化購物商城數據表 shoppingmark.db
       1.5 函數init_db_users() 初始化用戶數據表 users.db
       1.6 函數init_db_creditcard() 初始化信用卡數據表 creditcard.db
       1.7 執行init_database(),通過反射初始化數據表分別調用以上三個函數

四、包dbhelper介紹:
   1、dbapi.py介紹:
       1.1 函數append_db_json(contant, filename),將信息以 json 格式寫入數據表文件(追加)
       1.2 函數write_db_json(contant, filename),將信息以 json 格式寫入數據表文件(覆蓋)
       1.3 函數load_data_from_db(tabename),從指定的數據表中獲取所有數據,通過 json 方式將數據返回
       1.4 函數load_bill_report(cardno, startdate, enddate),從信用卡對賬單中獲取指定卡的對賬信息數據, 獲取某一個時間段內的數據
       1.5 函數load_shop_history(user, startdate, enddate),查找報表記錄中的指定用戶的購物歷史記錄,將結果存入到列表中
       1.6 函數load_statement_list(cardno),從對賬單中獲取記錄
       1.7 函數write_statement_list(cardno, db_list),將對賬單記錄寫入對賬單文件,更新


五、包modules介紹:
1、users.py介紹之類Users:
   1、定義私有變數:__database 值為database下的user.db
   2、定義用戶的靜態變數
   3、定義動態方法db_load(self.dict_user = dbapi.load_data_from_db(self.__database)),即調用dbapi模塊中的load_data_from_db方法來展示用戶信息
   4、定義login函數,輸入用戶名和密碼
       (1)、調用user_exists,判斷用戶是否存在,不存在則使用common.show_message進行異常顏色輸出。
       (2)、如存在則調用 用戶登錄模塊_user_login ,首先對輸入的密碼參數進行md5計算_password = common.encrypt(password),調用common模塊中的encrypt函數,併進行用戶信息的判斷的賦值
       (3)、判斷是否用戶被鎖定
       (4)、判斷用戶是否登錄成功,成功則break退出,失敗則輸出異常信息
       (5)、連續三次登錄失敗,則設置用戶鎖定標識為1,並update_user更新到user.db
       (6)、重置trycount 重置次數
   5、update_user即為將dict_user用戶列表信息進行回寫文件
   6、定義用戶存在函數user_exists、創建函數create_user、刪除函數del_user、鎖定函數unlock_user
   7、創建並init_user_info初始化用戶信息,輸入各種信息後,調用 create_user來生成用戶
   8、定義靜態方法user_auth,用於用戶登錄驗證裝飾器
   9、定義bind_card函數判斷卡綁定
   10、註銷用戶函數logout,將系統屬性置空
   11、個人中心 - 修改密碼函數modify_password
   12、修改用戶信息modify_user_info
       (1)、首先輸出當前的用戶信息
       (2)、輸入新的用戶信息
       (3)、輸入新的信用卡信息,並創建一個新的卡對象,調用CreditCard模塊:cardobj = CreditCard
       (4)、判斷信用卡是否存在
       (5)、輸入其他信息,並update_user回寫文件
   13、根據用戶名獲取用戶信息load_user_info


2、shopping.py之類Shopping:
   1、定義私有變數:__welcome_title 菜單標題、__database 資料庫文件、__shop_report_file購物報表
   2、定義__init__: 特別定義方法
         (1)、獲取數據表數據self._get_shop_market()
         (2)、購物商城歡迎菜單self._construct_title_menu() 
   3、_get_shop_market方法:載入購物商品信息dbapi.load_data_from_db(shoppingmarket.db)
   4、_construct_title_menu方法:輸出購物商城菜單
       self.welcome_menu = self.__welcome_title.format(menu="".join(_menu))
   5、get_goods_list_by_typeid方法:根據用戶選擇的商品分類編號,獲取該分類下所有商品
   6、定義靜態方法print_goods_list:列表中的商品信息輸出到屏幕,商品列表或購物車商品列表
         (1)、輸出商品信息標題
         (2)、迴圈輸出商品具體信息
   7、定義方法add_shopping_card(self, goodsid):根據商品編號加入購物車
         (1)、定義變數_goods_tuple ,即具體的商品列表
         (2)、開始查找輸入的商品編號,並加入購物車列表中,並計算金額
         (3)、成功後break
         (4)、返回return 成功與否
   8、定義payfor_shopcart結算方法,並調用@Users.user_auth認證模塊作裝飾器
       購物車結算模塊,功能包括:購物車付款、購物記錄寫入文件
         (1)、判斷用戶是否綁定信用卡,如無,則返回錯誤,有,則繼續、
         (2)、實例化信用卡類cardobj = CreditCard(userobj.bindcard)
         (3)、判斷信用卡餘額是否大於購買金額,如果不夠,輸出額度不夠,否則繼續
         (4)、調用common.create_serialno(),生成一個流水號
         (5)、調用卡的支付模塊進行支付cardobj.card_pay(self.shopping_cost, 1, serno)
                    支付扣款 
                    記錄消費流水對賬單,將發生了費用還沒有還款的賬單信息寫入文件 report_bill 中
                    更新信用卡可透支餘額信息到資料庫 creditcard.db
         (6)、記錄購物流水shopping_record,並寫入報表記錄文件shopping_history
         (7)、購物結算完成後將對象的購物車清空shopping_cart.clear(), 購物車商品總價清0 ,待下次購物
         (8)、返回錯誤代碼


3、creditcard.py之類CreditCard:
   1、指定數據表__database的表creditcard
   2、定義信用卡額度,信用卡透支餘額,信用卡日息,提現手續費率,信用卡狀態等變數
   3、定義_load_card_info函數,用戶輸入的卡號獲取信用卡信息
   4、定義card_is_exists函數,判斷輸入的信用卡是否存在
   5、定義card_pay(self, cost, paytype, sereialno)函數,信用卡支付,從信用卡可透支餘額中扣費
        (1)、根據傳入的paytype的值,定義payfor的名稱,例:1:消費、2:轉賬、3:提現、4:手續費
        (2)、支付扣款self.credit_balance -= cost
        (3)、定義_tmp_bill_record,記錄消費流水對賬單
        (4)、將消費流水對賬單寫回到文件report_bill
        (5)、更新信用卡可透支餘額信息到資料庫 creditcard.db
   6、定義新發行信用卡create_card函數,根據輸入的卡號密碼等信息並更新到creditcard.db
   7、定義信用卡更新update_card函數,根據輸入的卡號密碼等信息並更新到creditcard.db
   8、定義轉賬、提現時驗證操作_pay_check函數,轉賬、提現時驗證操作,判斷卡的餘額與支付密碼是否正確。並   返回錯誤類型碼
   9、定義提現函數fetch_money(self, count, passwd)
        (1)、根據傳入的取現金額,計算取現+手續費總額
        (2)、調用_pay_check函數,根據返回值進行操作。
        (3)、如果返回值是errorcode.NO_ERROR,則調用card_pay函數將取現金額和手續費計帳,並回寫文件
        (4)、並返回errorcode.NO_ERROR
   10、定義信用卡轉賬函數translate_money(self, trans_count, passwd, trans_cardobj)
        (1)、根據傳入的轉帳金額,計算轉帳+手續費總額
        (2)、調用_pay_check函數,根據返回值進行操作。
        (3)、如果返回值是errorcode.NO_ERROR,則調用card_pay函數將轉帳金額和手續費計帳,並回寫文件
        (4)、並給對方卡充值,trans_cardobj.credit_balance += trans_count,並調用trans_cardobj.update_card()寫入資料庫文件
        (4)、並返回errorcode.NO_ERROR
   11、定義對賬單列表數據函數load_statement_list,調用dbapi.load_statement_list(self.cardno)
   12、定義recreate_statement函數,實現今天的日期將當前卡的對賬單重新生成,主要對過了還款日的賬單重新生    成利息信息
        (1)、獲取當前日期today
        (2)、獲取卡的對賬單信息card_statement = dbapi.load_statement_list(self.cardno)
        (3)、如果有記錄,進行迴圈讀取,並判斷isfinished欄位是否是1,是則加記錄加到臨時列表tmp_list
        (4)、未還款,則獲取pdate還款時期,並判斷是否過期
        (5)、如果過期則計算利息:record[k]["interest"] = v["total"] * settings.EXPIRE_DAY_RATE * day_delta
        (6)、將過期或非過期的記錄都加到臨時列表tmp_list
        (7)、將更新過的列表寫入文件,替換原有信息dbapi.write_statement_list(self.cardno, tmp_list)

4、common.py介紹:
   1、函數verification_code(),用來生成一個4位的驗證碼,並返回驗證碼
   2、函數encrypt(string),用來字元串加密
   3、函數write_log(content),用來寫錯誤日誌
   4、函數get_chinese_num(uchar),用來計算漢字的個數
   5、函數show_message(msg, msgtype)根據msgtype類型,對print函數進行封裝,根據不同類型顯示不同顏色
   6、函數create_serialno(),用來生成一個消費、轉賬、提款時的流水號,不重覆
   7、函數numtochr(num_of_weekday),將數字星期轉換為中文數字
   8、函數input_msg(message, limit_value=tuple()),判斷input輸入的信息是否為空的公共檢測函數,為空繼續輸入,不為空返回輸入的信息
   9、函數input_date(msg, default_date),對輸入的日期進行判斷是否正確 yyyy-mm-dd or yyyy-m-d

5、report.py介紹: 賬單生成模塊
   1、導入calendar,timedelta等模塊
   2、函數get_date(),用來用戶輸入一個時間段,如果顯示報表是要提供開始、結束日期,返回開始,結束時間
       2.1 調用common.input_date來生成一個開始日期startdate
       2.2 調用common.input_date來生成一個結束日期enddate
       2.3 返回一個時間的字典
   3、函數print_shopping_history(userobj),個人中心 - 購物歷史記錄列印模塊
   4、函數print_bill_history(userobj) ,個人中心-賬單明細 列印模塊
   5、函數create_card_statement(cardno),生成信用卡對賬單
   6、函數create_statement_main(),卡對賬單初始化模塊,從卡資料庫文件中載入所有卡號,對所有卡調用生成對賬單模塊
   7、函數print_statement_list(cardno, list_info),將卡號對應的未還款記錄顯示出來
   8、函數print_statement_detail(cardno, serino, details),還款模塊 - 用戶選擇還款的單號後,顯示詳細的還款對賬單及流水信息
程式說明

 

二、ATM 模擬程式說明
系統主程式為根目錄下的:day5_credit_card.py
1. 系統功能模塊
Day5_ATM 模擬程式是在python3.0 環境下開發

2. 系統目錄結構:
程式採用分層的方式編寫,包括資料庫訪問層、資料庫層(數據文件)、業務邏輯層(module 層),業務處理層(主程式)、

3.應用知識點:
a) 字典、列表、元組的操作
b) 文件的讀寫操作
c) 函數的應用
d) 類的使用
e) 裝飾器、反射

三、代碼如下:

1、主程式credit_card.py:

#!/usr/bin/env python
# -*- encoding:utf-8 -*-

import os,sys

from datetime import date, datetime
from conf import template, errorcode
from conf import settings
from modules import shopping, common
from dbhelper import dbapi
from modules.users import Users
from modules.creditcard import CreditCard
from modules import report


def doshopping(userobj):
    """
    購物商城模塊,進行購物部分的所有處理
    :param userobj:  一個用戶對象,如果用戶未登錄,在支付模塊會通過裝飾器來登錄
    :return:
    """
    # 實例化商城
    shoppobj = shopping.Shopping()
    # 選擇商品類型
    exitflag = False
    while not exitflag:
        # 開始菜單
        print(shoppobj.welcome_menu)
        shop_cassify_id = input("請選擇商品分類編號[1-3]: ").strip().lower()
        if not shop_cassify_id: continue
        if shop_cassify_id == "0":
            exitflag = True
            continue
        if int(shop_cassify_id) not in range(1, 6):
            common.show_message("請選擇正確的商品類型編號!", "ERROR")

            continue
        elif shop_cassify_id == "4":
            # 查看購物車
            shopping.Shopping.print_goods_list(shoppobj.shopping_cart)
            common.show_message("當前購物車共有 {0} 件商品,合計 {1} 元 !".format(len(shoppobj.shopping_cart),
                                                                    shoppobj.shopping_cost), "INFORMATION")
            continue
        elif shop_cassify_id == "5":
            # 購物結算
            dealresult = shoppobj.payfor_shopcart(userobj)
            if dealresult == errorcode.NO_ERROR:
                common.show_message("支付完成!", "INFORMATION")

        else:
            # 獲取用戶選擇的商品類型編號
            shoppobj.goods_classify_id = shop_cassify_id
            # 獲得商品類型編號對應的商品列表
            goods_list = shoppobj.get_goods_list_by_typeid()

            if not goods_list:
                common.show_message("未找到商品信息!", "NOTICE")

                continue

            # 開始選擇商品,添加到購物車
            choose_goods_flag = True
            while choose_goods_flag:
                # 顯示指定商品分類下的所有商品列表(Shopping類靜態方法)
                shopping.Shopping.print_goods_list(goods_list)
                goods_id = input("選擇商品編號,加入購物車(q返回上一級): ").strip().lower()
                if not goods_id: continue
                # 返回上一級
                if goods_id == "q":
                    choose_goods_flag = False
                    continue
                else:
                    # 將選擇商品加入購物車
                    result = shoppobj.add_shopping_card(goods_id)
                    if result:
                        # 添加成功,顯示購物車所有商品信息
                        shopping.Shopping.print_goods_list(shoppobj.shopping_cart)
                        common.show_message("已將商品加入購物車!", "INFORMATION")

                        # 是否繼續添加
                        nextflag = False
                        while not nextflag:
                            donext = input("繼續購物(y) or 返回上一級(q):").strip().lower()
                            if donext == "y":
                                break
                            elif donext == "q":
                                choose_goods_flag = False
                                break
                            else:
                                continue
                    else:
                        # 添加購物車失敗
                        common.show_message("添加購物車失敗,請檢查輸入商品編號是否正確!", "ERROR")

                        continue


def user_login(userobj, today, weekoftoday):
    """
    主菜單的2號菜單登錄系統模塊
    :param userobj: 當前用戶對象
    :param today: 菜單顯示的日期
    :param weekoftoday: 菜單顯示的星期
    :return:
    """
    quitflag = False
    while not quitflag:
        if userobj.islogin:
            # 如果用戶已經登錄,菜單功能2為個人中心,調用另一個菜單模板 index_user_center
            print(template.index_user_center.format(userobj.name, today, common.numtochr(weekoftoday)))
            _chooseflag = False
            while not _chooseflag:
                _choose = input("選擇功能:")
                if _choose not in ("1", "2", "3", "4", "5", "6"):
                    common.show_message("選擇正確的功能編號!", "ERROR")
                    continue
                else:
                    _chooseflag = True

            # 返回上級菜單
            if _choose == "6":
                quitflag = True
            else:
                # 根據用戶按鍵開始處理,從 template 模塊查找各按鍵對應的模塊,通過反射來執行
                func_dict = template.user_center_func
                modulepy = __import__(func_dict[_choose]["module"])
                # 1,2,5號鍵為users類方法,
                if _choose in ('1', '2', '5'):
                    modulesobj = getattr(modulepy, "users")
                    classobj = getattr(modulesobj, "Users")
                    func = getattr(classobj, func_dict[_choose]["func"])

                else:
                    # 3,4為 report 模塊的方法
                    modulesobj = getattr(modulepy, "report")
                    func = getattr(modulesobj, func_dict[_choose]["func"])

                func(userobj)
        else:
            # 用戶未登錄,調用 Users類的登錄模塊
            userobj.login()
            quitflag = True


def card_center(userobj):
    if userobj.islogin:
        # 重新load一下數據
        userobj.db_load()
        cardno = userobj.bindcard
        # 獲得信用卡對象
        card = CreditCard(cardno)
    else:
        # 未登錄信用卡
        input_flag = False
        while not input_flag:
            cardno = input("請輸入信用卡卡號: ").strip().lower()
            if cardno.isnumeric():
                card = CreditCard(cardno)
                if card.card_is_exists:
                    pwd = input("請輸入密碼:")
                    if common.encrypt(pwd) == card.password:
                        common.show_message("登錄成功", "NOTICE")
                        input_flag = True
                        continue
                else:
                    common.show_message("卡號不存在,請重新輸入!", "ERROR")
                    continue
            else:
                common.show_message("卡號無效!", "ERROR")
                continue

    show_template = template.index_ATM
    quitflag = False
    while not quitflag:
        print(show_template.format(cardno=card.cardno))
        _choose = common.input_msg("請選擇功能: ", ("1", "2", "3", "4", "5"))
        # 返回
        if _choose == "5":
            quitflag = True
            continue

        # 查看信用卡信息
        if _choose == "1":
            common.show_message(template.card_info.format(cardno=card.cardno,
                                                          owner=card.owner,
                                                          total=card.credit_total,
                                                          balance=card.credit_balance,
                                                          status="正常" if card.frozenstatus == 0 else "凍結"
                                                          ), "NOTICE")
        # 提現
        if _choose == "2":
            if card.frozenstatus == 1:
                common.show_message("卡已凍結,請聯繫客服!", "ERROR")
            else:
                common.show_message("信用卡提現將收取 {0}% 的手續費!".format(settings.FETCH_MONEY_RATE * 100), "NOTICE")
                quitflag = False
                while not quitflag:
                    cost = common.input_msg("請輸入要提現的金額(q返回):")
                    if cost.isnumeric():
                        cardpasswd = common.input_msg("請輸入信用卡密碼:")
                        # 執行提現操作
                        exe_result = card.fetch_money(float(cost), cardpasswd)
                        if exe_result == errorcode.NO_ERROR:
                            common.show_message("已完成提現!", "NOTICE")
                        if exe_result == errorcode.BALANCE_NOT_ENOUGHT:
                            common.show_message("信用卡可透支餘額不足!", "ERROR")
                        if exe_result == errorcode.CARD_PASS_ERROR:
                            common.show_message("信用卡密碼錯誤!", "ERROR")
                    elif cost == "q":
                        quitflag = True
                        continue
                    else:
                        common.show_message("輸入錯誤!", "ERROR")
        # 轉賬
        if _choose == "3"	   

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • .NET環境下基於RBAC的訪問控制 Access Control of Application Based on RBAC model in .NET Environment 摘 要:本文從目前信息系統的變化趨勢及其多資源的訪問問題出發,提出一種基於RBAC模型的訪問控制方案。該方案以.NET環境
  • 標準輻射場裝置控制系統軟體設計。
  • 做過後臺的,應該都知道,經常要用到iframe來處理導航,如果按一般的思路來做這個功能,還是挺簡單的 可是當我用smarty的時候,就發現了問題,比如,一個iframeset分成了:頭部top,左邊menu,右邊main, 正常情況,用smarty來處理的話,一般是這樣: 如果3個頁面僅僅只是靜態頁
  • 題目描述:一個正整數有可能可以被表示為 n(>=2) 個連續正整數之和,如: 15=1+2+3+4+5 15=4+5+6 15=7+8 請編寫程式,根據輸入的任何一個正整數,找出符合這種要求的所有連續正整數序列。 輸入數據:一個正整數,以命令行參數的形式提供給程式。 輸出數據:在標準輸出上列印出符合
  • 封裝類Attribute: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 public class Attribute { private int id; private String name; priva
  • mutiplexer 數據選擇器 1 one-bit wide 2-1 mux wire dout = sel? din1 : din0; // conditional continuous and wire assignment 2 4-1 mux module mux4_1(sel, din0,
  • 1 register = storage keyword reg; default x; variable that can hold value 2 net = connection keyword wire; default z; be driven continuously 例 1) D fl
  • AbortPath 拋棄選入指定設備場景中的所有路徑。也取消目前正在進行的任何路徑的創建工作AngleArc 用一個連接弧畫一條線Arc 畫一個圓弧BeginPath 啟動一個路徑分支CancelDC 取消另一個線程里的長時間繪圖操作Chord 畫一個弦CloseEnhMetaFile 關閉指定的增
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...