本節作業 作業需求: 模擬實現一個ATM + 購物商城程式 額度 15000或自定義 實現購物商城,買東西加入 購物車,調用信用卡介面結賬 可以提現,手續費5% 每月22號出賬單,每月10號為還款日,過期未還,按欠款總額 萬分之5 每日計息 支持多賬戶登錄 支持賬戶間轉賬 記錄每月日常消費流水 提供
本節作業
作業需求:
模擬實現一個ATM + 購物商城程式
- 額度 15000或自定義
- 實現購物商城,買東西加入 購物車,調用信用卡介面結賬
- 可以提現,手續費5%
- 每月22號出賬單,每月10號為還款日,過期未還,按欠款總額 萬分之5 每日計息
- 支持多賬戶登錄
- 支持賬戶間轉賬
- 記錄每月日常消費流水
- 提供還款介面
- ATM記錄操作日誌
- 提供管理介面,包括添加賬戶、用戶額度,凍結賬戶等。。。
因對本次作業的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"