洗礼灵魂,修炼python(82)--全栈项目实战篇(10)—— 信用卡+商城项目(模拟京东淘宝)
本次项目相当于对python基础做总结,常用语法,数组类型,函数,文本操作等等
本项目在博客园里其他开发者也做过,我是稍作修改来的,大体没变的
项目需求:
信用卡+商城:
A、信用卡(类似白条/花呗)
1.额度15000以上或者自定义
2.可以提现,手续费5%
3.账户信息,信用卡和购物车共用
4.支持账户间转账
5.支持购物结账功能
6.有还款功能
7.记录每月日常消费流水
8.每个重要步骤都要记录到日志文件里(用logging模块)
9.有管理员功能,添加账户,冻结账户,调整用户额度
(可选)10.每月19号出帐,27号为最后还款日,逾期未还,按利息为欠款总额的万分之5每日计算
B、在线购物商场
1.与信用卡信息对接,支持信用卡结账
2.登录验证用装饰器
3.支持多账户登录
4.有多个页面,个人主页,电脑,手机,日用品主页,具体多少个主页随意(结合前面学到的)
5.每进入一个页面,分别打印页面下的产品
6.个人页面,电脑,手机等页面可以退回到主页 (类似前面的多级菜单同样的功能)
分析:
本次项目由于项目比前面的难度有提升,并且涉及到贴合以后真正的开发,很多设置都是可修改,并不是前面的项目那样,单个文件就搞定的。要求不用多说,就和常识里使用到的类似京东的白条,支付宝的蚂蚁花呗,然后加上一个购物商场,功能也不用多说。但是文件很多,由此,画一个流程图解释:
这个流程图我使用的百度脑图画的,分享链接:http://naotu.baidu.com/file/8ecc09fd00d5016349e4e7f72583ec48
画得比较简单,每个文件都有备注是干嘛的。
其实这个没什么难度,流程还是那些,登录验证,交易,更新数据,结束
流程图:
剩下的就是每个文件的编写,以及如何让这些文件联系起来了
这里说个知识点:
# 将当前py文件的上级文件夹目录的路径添加到模块索引列表内 import sys,os path = os.path.dirname(__file__) sys.path.append(path)
以上的代码则可以把你的文件作为py文件导入并且不怕因为文件路径被修改而导致导入失败了
代码:
项目包下载链接:传送门
需要的文件:
card.py:
#!usr/bin/env python #-*- coding:utf-8 -*- # author:yangva # datetime:2018/1/19 0019 21:41 import os,sys base_dir = os.path.dirname(os.path.dirname(__file__)) sys.path.append(base_dir) from libs import main if __name__ == '__main__': main.run()
main.py:
#!usr/bin/env python #-*- coding:utf-8 -*- # author:yangva # datetime:2018/1/19 0019 21:43 import os,sys base_dir = os.path.dirname(os.path.dirname(__file__)) sys.path.append(base_dir) from libs import auth from libs import logger from libs import transaction from libs import accounts from conf import settings # 用户数据,作为标志位以及缓存用户信用卡信息 account_data = { 'account_id':None, 'is_auth':False, 'data':None } # 用户日志 account_log = logger.logger('account') # 交易日志 transaction_log = logger.logger('transaction') # 账户信息 def userinfo(data): ''' print user of data :param data: user data :return: ''' for k,v in data.items(): print(k,':',v) # 查询账单 def select(data): ''' check transaction data :param data: user data :return: ''' check_path = '%s/log/transaction.log'%settings.BASE_DIR with open(check_path) as f: for i in f.readlines(): if str(data['id']) in i: print(i) # 退出 def logout(data): ''' quit the programs func :param data: user data :return: ''' print('account [%s] quit...'%data['id']) exit() # 还款 def repay(data): ''' user repay bill :param data: user data :return: ''' corrent_accdata = accounts.corrent_accdata(data['id']) print('''---------- user %s bill ---------- creadit: %s balance: %s '''%(corrent_accdata['id'],corrent_accdata['credit'],corrent_accdata['balance'])) back_flag = False while not back_flag: repay_amount = input("\033[36;1mplease enter amount or 'b' to back:\033[0m").strip() if repay_amount == 'b': back_flag = True print() #此处的打印空是为了换行美观,否则日志输出会和repay_amount在同一行 if len(repay_amount) > 0 and repay_amount.isdigit(): new_data = transaction.change(corrent_accdata,repay_amount,transaction_log,'repay') if new_data: print('\033[46;1mnew balance:[%s]\033[0m'%new_data['balance']) else: print('\033[31;1m[%s] not integer,only support integer\033[0m'%repay_amount) if repay_amount == 'b': back_flag = True # 取款 def draw(data): ''' user repay bill :param data: user data :return: ''' corrent_accdata = accounts.corrent_accdata(data['id']) print('''---------- user %s bill ---------- creadit: %s balance: %s '''%(corrent_accdata['id'],corrent_accdata['credit'],corrent_accdata['balance'])) back_flag = False while not back_flag: draw_amount = input("\033[36;1mplease enter amount or 'b' to back:\033[0m").strip() if draw_amount == 'b': back_flag = True if len(draw_amount) > 0 and draw_amount.isdigit(): new_data = transaction.change(corrent_accdata,draw_amount,transaction_log,'draw') if new_data: print('\033[46;1mnew balance:[%s]\033[0m'%new_data['balance']) else: print('\033[31;1m[%s] not integer,only support integer\033[0m'%draw_amount) # 转账 def transfer(data): ''' user1 transfer money to user2 :param data: user data :return: ''' corrent_accdata = accounts.corrent_accdata(data['id']) print('''---------- user %s bill ---------- creadit: %s balance: %s '''%(corrent_accdata['id'],corrent_accdata['credit'],corrent_accdata['balance'])) back_flag = False while not back_flag: transfer_amount = input("\033[36;1mplease enter amount or 'b' to back:\033[0m").strip() if transfer_amount == 'b': back_flag = True if len(transfer_amount) > 0 and transfer_amount.isdigit(): transfer_user_id = input("\033[36;1mplease enter user id :\033[0m").strip() try: transfer_userdata = accounts.corrent_accdata(transfer_user_id) new_data = transaction.change(corrent_accdata,transfer_amount,transaction_log,'transfer') if new_data: transfer_userdata['balance'] += float(transfer_amount) accounts.dump_accdata(transfer_userdata) print('\033[46;1mtrade successfully!\033[0m') print('\033[46;1mnew balance:[%s]\033[0m'%new_data['balance']) except Exception as reason: print('\033[31;1mtransaction failure!\033[0m') print(reason) else: print('\033[31;1m[%s] not integer,only support integer\033[0m'%transfer_amount) # 信用卡操作对象 def optionlist(data): ''' :param data: user's data :return: ''' menu = u'''\033[32;1m 1.账户信息 2.还款 3.取款 4.转账 5.查询账单 6.退出\033[0m''' option_dict = { '1':userinfo, '2':repay, '3':draw, '4':transfer, '5':select, '6':logout } exit_flag = False while not exit_flag: print(menu) user_option = input('\033[36;1mplease enter the option number:\033[32;1m') if user_option in option_dict: option_dict[user_option](data) else: print("\033[31;1m sorry,haven't option [%s]\033[0m"%user_option) # 运行 def run(): ''' 运行函数,将整个项目运行起来 :return: ''' userdata = auth.login(account_data,account_log) if account_data['is_auth'] == True: account_data['data'] = userdata optionlist(userdata)
logger.py:
#!usr/bin/env python #-*- coding:utf-8 -*- # author:yangva # datetime:2018/1/19 0019 21:54 import logging from conf import settings def logger(log_type): # 创建一个文件型日志对象 log_file = '%s/log/%s'%(settings.BASE_DIR,settings.LOG_TYPE[log_type]) fh = logging.FileHandler(log_file) fh.setLevel(settings.LOG_LEVEL) # 创建一个输出到屏幕型日志对象 sh = logging.StreamHandler() sh.setLevel(settings.LOG_LEVEL) # 设置日志格式 formater = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') # 添加格式到文件型和输出型日志对象中 fh.setFormatter(formater) sh.setFormatter(formater) # 创建log对象,命名 logger = logging.getLogger(log_type) logger.setLevel(settings.LOG_LEVEL) # 把文件型日志和输出型日志对象添加进logger logger.addHandler(fh) logger.addHandler(sh) return logger
auth.py:
#!usr/bin/env python #-*- coding:utf-8 -*- # author:yangva # datetime:2018/1/19 0019 21:53 import json,os,time from conf import settings from libs import db def auth(userid,password): ''' account libs func :param userid: user card id :param password: user pasword :return: ''' userdbpath = db.db(settings.DATABASEINFO) account_file = '%s/%s.json'%(userdbpath,userid) # print(account_file) if os.path.isfile(account_file): with open(account_file) as f: account_data = json.load(f) if account_data['password'] == password: indate = time.mktime(time.strptime(account_data['expire_date'],'%Y-%m-%d')) if indate < time.time(): print("\033[31;1m your card was out of date\033[0m") else: return account_data else: print('\033[31;1m your id or password incorrect\033[0m') else: print('\033[31;1maccount [%s] does not exist\033[0m'%userid) def login(data,logobj): ''' account login func :param data: user's data :param logobj: account logger object :return: ''' count = 0 while data['is_auth'] is not True and count < 3: userid = input("\033[36;1mplease enter your card's id:\033[0m").strip() password = input('\033[36;1menter your password:\033[0m').strip() userauth = auth(userid,password) if userauth: data['is_auth'] = True data['account_id'] = userid return userauth count +=1 else: logobj.error('\033[31;1maccount [%s] too many login attempts\033[0m' % userid) exit()
accounts.py:
#!usr/bin/env python #-*- coding:utf-8 -*- # author:yangva # datetime:2018/1/20 0020 22:38 from conf import settings from libs import db import json def corrent_accdata(userid): ''' :param userid: user card's id :return: ''' accdata_path = db.db(settings.DATABASEINFO) acc_file = '%s/%s.json'%(accdata_path,userid) with open(acc_file) as f: corrent_accdata = json.load(f) return corrent_accdata def dump_accdata(data): ''' :param data: user data :return: ''' accdata_path = db.db(settings.DATABASEINFO) acc_file = '%s/%s.json'%(accdata_path,data['id']) with open(acc_file,'w') as f: json.dump(data,f) return True
transaction.py:
#!usr/bin/env python #-*- coding:utf-8 -*- # author:yangva # datetime:2018/1/20 0020 17:50 from conf import settings from libs import accounts def change(account_data,amount,logobj,trantype): ''' :param account_data: user data :param amount: user entered amount :param logobj: transaction logging object :param trantype: transaction type :return: ''' amount = float(amount) if trantype in settings.TRAN_TYPE: interest = amount * settings.TRAN_TYPE[trantype]['interest'] #利息 old_balance = account_data['balance'] if settings.TRAN_TYPE[trantype]['action'] == 'plus': new_balance = old_balance + amount +interest elif settings.TRAN_TYPE[trantype]['action'] == 'minus': new_balance = old_balance - amount - interest if new_balance < 0: print("\033[31;1maccount [%s] balance is not sufficient to pay [%s]!\033[0m" %(account_data['id'],amount +interest)) return account_data['balance'] = new_balance accounts.dump_accdata(account_data) logobj.info('account:%s - transaction:%s - amount:%s - interest:%s' %(account_data['id'],trantype,amount,interest)) return account_data else: print('\033[31;1mTransaction type [%s] is not exist!\033[0m'%trantype)
settings.py:
#!usr/bin/env python #-*- coding:utf-8 -*- # author:yangva # datetime:2018/1/19 0019 21:56 import os,sys,logging # 项目根目录 BASE_DIR = os.path.dirname(os.path.dirname(__file__)) # 设置日志等级 LOG_LEVEL = logging.INFO # 存储日志类型 LOG_TYPE = { 'transaction':'transaction.log', 'account':'account.log' } # 数据库信息 DATABASEINFO = { 'engine':'file',# 数据库类型,可以为文件,可以为数据库 'dirname':'accounts',# 数据文件目录名 'path':'%s/db'%BASE_DIR } # 交易类型 TRAN_TYPE = { 'repay':{'action':'plus','interest':0}, 'draw':{'action':'minus','interest':0.05}, 'transfer':{'action':'minus','interest':0.05} }
db.py:
#!usr/bin/env python #-*- coding:utf-8 -*- # author:yangva # datetime:2018/1/19 0019 22:51 def fl_db(parms): ''' :param parms: malldb type :return: malldb path ''' # print('file malldb:,parms') db_path = '%s/%s'%(parms['path'],parms['dirname']) # print(db_path) return db_path def ml_db(parms): pass def mo_db(parms): pass def oe_db(parms): pass def db(parms): ''' :param parms: malldb information :return: ''' db_dict = { 'file':fl_db, 'mysql':ml_db, 'mongodb':mo_db, 'orlcle':oe_db, } if parms['engine'] in db_dict: return db_dict[parms['engine']](parms)
example.py:
#!usr/bin/env python #-*- coding:utf-8 -*- # author:yangva # datetime:2018/1/20 0020 15:43 import json,sys,os,datetime base_dir = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) sys.path.append(base_dir) from conf import settings from libs import db path = db.db(settings.DATABASEINFO) acc_dic = { 'id': 123, #卡号 'password': 'abc', #密码 'credit': 15000, #额度 'balance': 15000, #余额 'enroll_date': '2016-01-02', #注册日期 'expire_date': '2021-01-01', #失效日期 'pay_day': 22, #还款日 'status': 0 # 0 = normal, 1 = locked, 2 = disabled } id = int(input('\033[36;1menter your user id:\033[0m')) corrent_path = '%s/%s.json'%(path,id) acc_dic['id'] = id enroll_date = datetime.date.today() expire_date = enroll_date + datetime.timedelta(days=365*5) acc_dic['enroll_date'] = str(enroll_date) acc_dic['expire_date'] = str(expire_date) with open(corrent_path,'w') as f: json.dump(acc_dic,f)
shopping.py:
#!usr/bin/env python #-*- coding:utf-8 -*- # author:yangva # datetime:2018/1/21 0024 17:44 import sys,json,os from collections import Counter base_dir = os.path.dirname(os.path.dirname(__file__)) sys.path.append(base_dir) from card.conf import settings from card.libs import db # # 载入商城账号信息,商城和信用卡并不是等同的 # user_path = '%s/mall/yang.json'%base_dir # with open(user_path) as f: # userdata = json.load(f) # # 读取信用卡 # path = db.db(settings.DATABASEINFO) # account_path = '%s/%s.json'%(path,userdata['id']) # with open(account_path) as f: # accountdata = json.load(f) # # 账户可用余额 # salary = accountdata['balance'] # #缓存总额,用于后面总共消费多少作计算 # temp = salary #购物车 cart = [] #商品总清单 product ={ '手机':{ '1':{'IphoneX':8388.00}, '2':{'Iphone8':5088.00}, '3':{'一加5T':3270.00}, '4':{'魅族pro7':1999.00}, '5':{'小米MIX2':3299.00}, '6':{'华为p10':3488.00} }, '电脑':{ '7':{'联想R720-15I':7399.00}, '8':{'惠普战66ProG1':6499.00}, '9':{'戴尔XPS13':6299.00}, '10':{'MacBookAir':6988.00} }, '日用品':{ '11':{'高露洁牙刷':12.90}, '12':{'三利纯棉浴巾':32.50}, '13':{'半球电水壶':49.00} } } login_status = False #登录状态标志位 #登录验证 def login(func): def inner(): global login_status,accountdata,salary,temp,account_path while not login_status: print('\033[32;1m请登录\033[0m') username = input('\033[32;1musername:\033[0m') password = input('\033[32;1mpassword:\033[0m') user_path = '%s/mall/%s.json'%(base_dir,username) if os.path.isfile(user_path): with open(user_path) as f: userdata = json.load(f) while password != userdata[username]: # 购物商场可以无限次登录 print('\033[31;1m用户名或密码错误,请重新登录\033[0m') password = input('\033[32;1mpassword:\033[0m') else: print('\033[34;1m登录成功!\n') login_status = True path = db.db(settings.DATABASEINFO) # 载入信用卡信息 account_path = '%s/%s.json'%(path,userdata['id']) with open(account_path) as f: accountdata = json.load(f) # 账户可用余额 salary = accountdata['balance'] #缓存总额,用于后面总共消费多少作计算 temp = salary return func() else: print('\033[31;1m不存在的用户名或者用户文件\033[0m') else: #已登录状态 return func() return inner #手机页面 @login def phone(string='手机'): shopping_cart(string) #电脑页面 @login def pc(string='电脑'): shopping_cart(string) #日用品页面 @login def life(string='日用品'): shopping_cart(string) #主页 @login def home(): print('\033[36;1m首页,js动态切换图片;精品促销;XX品牌日\033[0m') #消费流水 @login def consume(): consume = temp-salary #消费金额 if consume > 0: print('\033[36;1m您当前的消费流水详细账单:\033[0m') for i,j in dict(Counter(cart)).items(): print('\033[36;1m%s 数量:%s\033[0m'%(i,j)) print('\033[46;1m您总共消费了 %.2f 元,可用余额为 %.2f 元\033[0m\n'%(temp-salary,salary)) else: print('\033[31;1m您还未购买任何物品\033[0m\n') # 更新用户数据 def dump(): accountdata['balance'] = salary with open(account_path,'w') as f: json.dump(accountdata,f) return accountdata # 退出 def logout(): acc = dump() if acc: print('\033[36;1m欢迎下次光临!您已退出!\033[0m') exit() #购物车 def shopping_cart(string): global salary for page,goods_msg in product.items(): if page == string: while True: print('\033[36;1m页面:%s\033[0m\n'%page) for ID,goods in goods_msg.items(): for name,price in goods.items(): print('\033[32;1m商品id:%s\t\t\t商品名:%s\t\t\t价格:%s\033[0m'%(ID,name,price)) shopping = input('\033[32;1m请输入商品id(需要返回上一级菜单请输入“b”)>>>:\033[0m') if shopping in goods_msg.keys(): gname = list(goods_msg[shopping].keys())[0] gprice =list(goods_msg[shopping].values())[0] if salary < gprice: print('\033[31;1m您的余额不足\033[0m') else: salary -= gprice print('\033[46;1m您已购买商品 %s -- 单价 %.2f,剩余余额:%.2f\033[0m\n'%(gname,gprice,salary)) cart.append('商品:%s 单价:%.2f'%(gname,gprice)) if not salary: #购买后再次检测信用卡剩余额度 print('\033[31;1m您的余额为0,不能再购买任何东西,程序已退出,欢迎下次光临\033[0m') break elif shopping == 'b': #购买结束,到收银台结账 print('\033[32;1m已返回上一级\033[0m\n') break else: print('\033[31;1m您的输入有误,请查看是否有id为【%s】的商品\033[0m'%shopping) #主函数 def man(): mapper = {'1':home,'2':pc,'3':phone,'4':life,'5':consume,'6':logout} #映射函数 print('\033[32;1m-------欢迎光临XXX商城-------\033[0m') while True: print('\033[32;1m1.主页\n2.电脑\n3.手机\n4.日用品\n5.打印流水凭条\n6.退出\033[0m') page = input('\033[32;1m请选择访问页面(输入前面的序号即可):\033[0m') if page in mapper: mapper[page]() else: print('\033[31;1m输入有误!!\033[0m') if __name__ == '__main__': man()
62285580.json:
{"status": 0, "password": "123", "expire_date": "2020-07-26", "balance": 1500.75, "pay_day": 22, "id": 62285580, "enroll_date": "2015-07-25", "credit": 15000}
62285589.json:
{"status": 0, "password": "abc", "expire_date": "2021-01-01", "balance": 16022.05, "pay_day": 22, "id": 62285589, "enroll_date": "2016-01-02", "credit": 15000}
以下两个文件是购物商场的账户数据文件,你也可以统一的放在一个json里
yang.json:
{"yang": "abc", "id": 62285589}
ling.json:
{"ling": "123", "id": 62285580}
运行效果:
运行card.py:
(部分截图)
详细结果:
please enter your card's id:62285589 enter your password:abc 1.账户信息 2.还款 3.取款 4.转账 5.查询账单 6.退出 please enter the option number:2 ---------- user 62285589 bill ---------- creadit: 15000 balance: 16022.05 please enter amount or 'b' to back:500 new balance:[16522.05] please enter amount or 'b' to back:2018-01-24 17:03:06,773 - transaction - INFO - account:62285589 - transaction:repay - amount:500.0 - interest:0.0 b [b] not integer,only support integer 1.账户信息 2.还款 3.取款 4.转账 5.查询账单 6.退出 please enter the option number:1 status : 0 password : abc expire_date : 2021-01-01 balance : 16022.05 pay_day : 22 id : 62285589 enroll_date : 2016-01-02 credit : 15000 1.账户信息 2.还款 3.取款 4.转账 5.查询账单 6.退出 please enter the option number:3 ---------- user 62285589 bill ---------- creadit: 15000 balance: 16522.05 please enter amount or 'b' to back:100 2018-01-24 17:04:52,005 - transaction - INFO - account:62285589 - transaction:draw - amount:100.0 - interest:5.0 new balance:[16417.05] please enter amount or 'b' to back:b [b] not integer,only support integer 1.账户信息 2.还款 3.取款 4.转账 5.查询账单 6.退出 please enter the option number:4 ---------- user 62285589 bill ---------- creadit: 15000 balance: 16417.05 please enter amount or 'b' to back:200 please enter user id :62285580 2018-01-24 17:05:11,616 - transaction - INFO - account:62285589 - transaction:transfer - amount:200.0 - interest:10.0 trade successfully! new balance:[16207.05] please enter amount or 'b' to back:b [b] not integer,only support integer 1.账户信息 2.还款 3.取款 4.转账 5.查询账单 6.退出 please enter the option number:5 2018-01-21 20:21:53,140 - transaction - INFO - account:62285589--transaction:repay--amount:400.0--interest:0.0 2018-01-21 20:25:43,037 - transaction - INFO - account:62285589--transaction:draw--amount:400.0--interest:20.0 2018-01-21 20:27:08,946 - transaction - INFO - account:62285589--transaction:draw--amount:400.0--interest:20.0 2018-01-21 20:31:55,979 - transaction - INFO - account:62285589 - transaction:transfer - amount:100.0 - interest:5.0 2018-01-24 17:03:06,773 - transaction - INFO - account:62285589 - transaction:repay - amount:500.0 - interest:0.0 2018-01-24 17:04:52,005 - transaction - INFO - account:62285589 - transaction:draw - amount:100.0 - interest:5.0 2018-01-24 17:05:11,616 - transaction - INFO - account:62285589 - transaction:transfer - amount:200.0 - interest:10.0 1.账户信息 2.还款 3.取款 4.转账 5.查询账单 6.退出 please enter the option number:6 account [62285589] quit...
运行shopping.py:
详细结果:
-------欢迎光临XXX商城------- 1.主页 2.电脑 3.手机 4.日用品 5.打印流水凭条 6.退出 请选择访问页面(输入前面的序号即可):2 请登录 username:yang password:abc 登录成功! 页面:电脑 商品id:7 商品名:联想R720-15I 价格:7399.0 商品id:8 商品名:惠普战66ProG1 价格:6499.0 商品id:9 商品名:戴尔XPS13 价格:6299.0 商品id:10 商品名:MacBookAir 价格:6988.0 请输入商品id(需要返回上一级菜单请输入“b”)>>>:b 已返回上一级 1.主页 2.电脑 3.手机 4.日用品 5.打印流水凭条 6.退出 请选择访问页面(输入前面的序号即可):1 首页,js动态切换图片;精品促销;XX品牌日 1.主页 2.电脑 3.手机 4.日用品 5.打印流水凭条 6.退出 请选择访问页面(输入前面的序号即可):3 页面:手机 商品id:1 商品名:IphoneX 价格:8388.0 商品id:2 商品名:Iphone8 价格:5088.0 商品id:3 商品名:一加5T 价格:3270.0 商品id:4 商品名:魅族pro7 价格:1999.0 商品id:5 商品名:小米MIX2 价格:3299.0 商品id:6 商品名:华为p10 价格:3488.0 请输入商品id(需要返回上一级菜单请输入“b”)>>>:4 您已购买商品 魅族pro7 -- 单价 1999.00,剩余余额:14208.05 页面:手机 商品id:1 商品名:IphoneX 价格:8388.0 商品id:2 商品名:Iphone8 价格:5088.0 商品id:3 商品名:一加5T 价格:3270.0 商品id:4 商品名:魅族pro7 价格:1999.0 商品id:5 商品名:小米MIX2 价格:3299.0 商品id:6 商品名:华为p10 价格:3488.0 请输入商品id(需要返回上一级菜单请输入“b”)>>>:b 已返回上一级 1.主页 2.电脑 3.手机 4.日用品 5.打印流水凭条 6.退出 请选择访问页面(输入前面的序号即可):4 页面:日用品 商品id:11 商品名:高露洁牙刷 价格:12.9 商品id:12 商品名:三利纯棉浴巾 价格:32.5 商品id:13 商品名:半球电水壶 价格:49.0 请输入商品id(需要返回上一级菜单请输入“b”)>>>:11 您已购买商品 高露洁牙刷 -- 单价 12.90,剩余余额:14195.15 页面:日用品 商品id:11 商品名:高露洁牙刷 价格:12.9 商品id:12 商品名:三利纯棉浴巾 价格:32.5 商品id:13 商品名:半球电水壶 价格:49.0 请输入商品id(需要返回上一级菜单请输入“b”)>>>:b 已返回上一级 1.主页 2.电脑 3.手机 4.日用品 5.打印流水凭条 6.退出 请选择访问页面(输入前面的序号即可):5 您当前的消费流水详细账单: 商品:魅族pro7 单价:1999.00 数量:1 商品:高露洁牙刷 单价:12.90 数量:1 您总共消费了 2011.90 元,可用余额为 14195.15 元 1.主页 2.电脑 3.手机 4.日用品 5.打印流水凭条 6.退出 请选择访问页面(输入前面的序号即可):6 欢迎下次光临!您已退出!
打开json文件验证:
表示同步成功
总结:
其实还有两个问题:
1.购物商场当多用户登录时,如果都是登录的同一个账号的话,会有意想不到的问题,由于还没学到socket编程以及IO阻塞,所以暂时不优化
2.信用卡查询账单时,我是直接打印的日志文件里的,这样大体没问题,但不怎么好看
以上问题,感兴趣的可以自己优化一下,其他方面基本上没啥问题,有问题还望指出
细心的朋友你会发现,我的项目实战篇也是由易到难的,从零基础开始的,前面的项目很简单,不用函数都可以搞定,慢慢的开始使用到函数,下一篇项目实战也将从面向对象开始。然后前面基础篇漏掉的知识也会在实战篇中提出来,换句话就是利用项目实战,即把基础复习了,也把项目练好了,是不是想想就带劲,哈哈,唯一的不足就是,我知道我更博的时间太随意了,没办法啊,我也自学啊,还是那句,有时间就更新。不多说,大家都能把技术学好才是最终目的