洗礼灵魂,修炼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.信用卡查询账单时,我是直接打印的日志文件里的,这样大体没问题,但不怎么好看

 

以上问题,感兴趣的可以自己优化一下,其他方面基本上没啥问题,有问题还望指出

 

细心的朋友你会发现,我的项目实战篇也是由易到难的,从零基础开始的,前面的项目很简单,不用函数都可以搞定,慢慢的开始使用到函数,下一篇项目实战也将从面向对象开始。然后前面基础篇漏掉的知识也会在实战篇中提出来,换句话就是利用项目实战,即把基础复习了,也把项目练好了,是不是想想就带劲,哈哈,唯一的不足就是,我知道我更博的时间太随意了,没办法啊,我也自学啊,还是那句,有时间就更新。不多说,大家都能把技术学好才是最终目的

 

posted @ 2018-01-24 17:21  Eeyhan  阅读(256)  评论(0编辑  收藏  举报