博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Day5作业,商城+ATM机+后台管理
阅读量:5758 次
发布时间:2019-06-18

本文共 63409 字,大约阅读时间需要 211 分钟。

晚来了....东西太多,需要写的blog内容太多,re讲的渣渣,不明白为什么oldboy经常换老师,吐槽下吧,真心不爱了....

github地址在这:https://github.com/ccorzorz/ATM-shoppmall

商城用原来的,先上图吧:

商城图:

ATM后台管理:

ATM终端:

README:

1.测试帐号:    商城测试帐号:cc/123   或者自己注册    ATM 终端测试帐号:cc/123 alex/123 或者自己注册    ATM 管理员测试帐号:admin/admin2.需安装的第三方模块:prettytable3.文件目录以及说明请看file_struct_info 文件4.数据库主要文件说明:    ATM 用户信息数据库:        atm_admin_db.json:        {用户名:'[用户状态,密码,信用额度,可用额度,[消费记录]'}        账单数据库:        {用户名:[本月还款金额,账单日期内的消费记录]}5.账单生成说明:    每月账单生成可在linux 系统中的 crontab 里写入,或者登录管理员后台手动生成账单,账单日为每月22日    还款日为每月10日,生成账单时需要22日后才可生成账单,否则会提示日期未到6.商城代码的说明:    时间原因,使用了第二天的商城作业修改的,但没有大幅对商城做模块拆分,只在 ATM 系统做了模块拆分7.代码运行说明:    bin目录中的文件为入口:    ATM 终端:python3 atm.py start    ATM管理后台:python3 credit_manage.py start    购物商城:python3 shop.py8.ATM 程序功能说明:    1.商城支付,充值功能接入 ATM 的支付接口    2.ATM 管理员可建卡,为方便测试,登录直接为用户名密码模式,并非6222...的卡号类型    3.支付时需要随机验证码    4.用户名的密码处理使用了MD5加密    5.账单使用了时间判断,并单独生成了每个月的账单,管理员可23日0点以后生成账单    6.逾期利息用户登录后可查询,但利息计算由于时间问题,并未对逾期分期还款等功能做处理    7.取现,支付等有5%的手续费,并会一并扣除    8.用户转账只能给此模拟银行的账户转账    9.后台管理可建卡,冻结,解冻账户,但不能删除用户    10.用户还款时,如超过需还款金额,会有提示,而且只能超额还款一次    11.提现,转账可用额度,为信用额度的一半

  目录介绍:

.|______init__.py|____bin    #执行文件目录| |____atm.py   #atm 终端开始程序,python3 atm.py start| |____credit_manage.py #atm 后台开始程序,python3 atm.py start| |____shop.py  #|____conf   #配置文件信息| |____setting.py   #通用设置模块|____core| |____atm_admin_op.py  #ATM 管理操作模块| |____atm_run.py   #ATM 终端运行主程序| |____bills_rate.py    #ATM用户查询账单模块| |____data_op.py   #数据操作类模块| |____format_num.py    #价格处理模块,处理为人民币标准显示| |____generate_bills.py    #账单生成模块| |____logger.py    #日志处理模块| |____manager_main.py  #ATM 管理员操作主程序| |____pass_handler.py  #密码 MD5加密处理模块| |____shop_mall.py #商城主程序模块| |____terminal_discover_bills.py   #ATM 查看账单模块| |____terminal_op.py   #ATM 用户常规操作模块| |____terminal_pay.py  #ATM 支付接口| |____terminal_repay.py    #ATM 还款模块| |____terminal_show_record.py  #ATM 查看消费记录模块| |____terminal_transfers.py    #ATM 转账模块| |____terminal_view_credit.py  #ATM 查看用户额度信息模块| |____terminal_withdraw.py #ATM 终端取现模块| |____time_cal.py  #时间处理模块| |____veri_code.py #随机验证码模块,用来支付时验证|____db #数据库目录| |____201605_bills.json    #atm 每月账单| |____201609_bills.json    #atm 每月账单| |____atm_admin_db.json    #atm 管理员数据库| |____atm_cart_db.json #atm 系统用户信息,包括消费记录数据等信息| |____goods.json   #商城商品信息,包括价格,分类以及库存等| |____mall_cart.json   #商城用户购物车信息,保存用户未结账退出时的购物车信息| |____mall_user.json   #商城用户文件数据库,包括购买记录| |____mall_user_lock   #商城用户锁定用户文件|____log| |____access.log   #atm 用户访问日志| |____admin.log    #atm 管理员操作日志| |____trans.log    #atm 用户终端操作日志

  bin目录下:

atm.py:

#!/usr/bin/env python# -*-coding=utf-8-*-# Auther:ccorz Mail:ccniubi@163.com Blog:http://www.cnblogs.com/ccorz/# GitHub:https://github.com/ccorzorz"""ATM 终端入口"""import syssys.path.append('..')from core import atm_runif len(sys.argv)==2 and sys.argv[1]=='start':    atm_run.main()else:    print('\"python atm.py start\" to starup programe!!')

credit_manage.py:

#!/usr/bin/env python3# -*-coding=utf-8-*-# Auther:ccorz Mail:ccniubi@163.com Blog:http://www.cnblogs.com/ccorz/# GitHub:https://github.com/ccorzorz"""ATM管理后台入口"""import syssys.path.append('..')from core import manager_mainif len(sys.argv)==2 and sys.argv[1]=='start':    manager_main.main()else:    print('\"python3 credit_manage.py start\" to starup programe')# manager_main.main()

shop.py:

#!/usr/bin/env python# -*-coding=utf-8-*-# Auther:ccorz Mail:ccniubi@163.com Blog:http://www.cnblogs.com/ccorz/# GitHub:https://github.com/ccorzorz"""购物商城入口"""import syssys.path.append('..')from core import shop_mallshop_mall.main()

  conf目录:

setting.py:

#!/usr/bin/env python# -*-coding=utf-8-*-# Auther:ccorz Mail:ccniubi@163.com Blog:http://www.cnblogs.com/ccorz/# GitHub:https://github.com/ccorzorz"""配置文件,配置交易费率字典,消费记录函数,以及日志的文件和等级等信息"""import sys,time,logging,datetimesys.path.append('..')from core import data_op,loggerdt=time.strftime('%Y-%m-%d %H:%M:%S')trans_rate={'提现':0.05,'转账':0.05,'还款':0,'支付':0,'收款':0}def record(user_name,TransType,business,amounts):    user_data=data_op.l_d()    rates=trans_rate[TransType]*amounts    user_data[user_name][4].append({dt:[TransType,business,amounts,rates]})    data_op.flush_d(user_data)    return TrueLOG_LEVEL=logging.DEBUGLOG_TYPE={'access':'access.log','trans':'trans.log','admin':'admin.log'}

  core目录:

atm_admin_op.py:

#!/usr/bin/env python# -*-coding=utf-8-*-# Auther:ccorz Mail:ccniubi@163.com Blog:http://www.cnblogs.com/ccorz/# GitHub:https://github.com/ccorzorz"""管理员操作模块,show_all 查看所有账户信息c_u 新建用户freeze_u   冻结账户un_freeze   解冻账户enhance_credit 提升额度logout 退出登录"""import syssys.path.append('..')from core import data_op,format_num,pass_handlerfrom core.logger import *def show_all():    """    显示所有用户信息    :return:  None    """    user_data=data_op.l_d()    print('现有账户额度以及状态'.center(30,'*'))    for item in user_data:        if user_data[item][0]==0:            user_data[item][0]='冻结'        else:            user_data[item][0]='正常'        print('{:10s}{:15s}{:10s}'.format(item,                                          format_num.fn(user_data[item][2]),                                          user_data[item][0]))def c_u():    """    创建用户,额度,以及密码,密码使用 md5处理,并记录 log 日志,修改相关数据库    :return: None    """    user_data=data_op.l_d()    while True:        inp=input('请输入用户帐号,输入 b 返回主菜单:')        if inp=='b':            break        elif user_data.get(inp)==None:            while True:                balance=input('请输入初始额度,必须为整数的数字:')                if balance.isdigit():                    balance=int(balance)                    break                else:                    print('输入有误,重新输入...')            pwd_inp=input('请输入用户的密码:')            pwd=pass_handler.md5_pwd(pwd_inp)            user_data[inp]=[1,pwd,balance,balance,[]]            data_op.flush_d(user_data)            print('帐号{}信息添加成功,额度为{}'.format(inp,format_num.fn(balance)))            log_admin.info('添加{}帐号信息,额度:{}'.format(inp,balance))            break        else: #如果用户存在,提示用户            print('帐号{}已存在,请重新输入.'.format(inp))def freeze_u():    """    冻结用户,修改相关数据库    :return:  None    """    user_data=data_op.l_d()    while True:        show_all()        inp=input('请输入要冻结的账户,输入 b 返回主菜单:')        if inp=='b':            break        elif user_data.get(inp)==None:  #如无账户,提示管理员            print('无{}账户信息'.format(inp))        else:            if user_data[inp][0]==0:                print('账户{}已被冻结,无需重复操作'.format(inp))                break            else:                user_data[inp][0]=0                data_op.flush_d(user_data)                print('账户{}冻结成功!'.format(inp))                log_admin.info('冻结账户{}'.format(inp))                breakdef un_freeze_u():    """    解冻账户,与冻结账户操作相反,并修改数据库    :return:    """    user_data=data_op.l_d()    freeze_user_list=[]    for item in user_data:        if user_data[item][0]==0:            freeze_user_list.append(item)    if len(freeze_user_list)==0:        print('无被冻结账户,无需继续操作.')        return False    else:        print('已被冻结用户如下'.center(20,'*'))        for item in freeze_user_list:            print(item)    while True:        inp=input('请输入要解除冻结状态的账户,输入 b 返回主菜单:')        if inp=='b':            break        elif inp not in freeze_user_list:            print('冻结状态账户中无{}账户信息'.format(inp))        else:            if user_data[inp][0]==1:                print('账户{}未冻结,无需重复操作'.format(inp))                break            else:                user_data[inp][0]=1                data_op.flush_d(user_data)                print('账户{}解冻成功!'.format(inp))                # loggerin                log_admin.info('解冻账户{}'.format(inp))                breakdef enhance_credit():    """    提升用户额度,并修改用户信用额度以及可用额度信息    :return: None    """    user_data=data_op.l_d()    ex_flag=1    while ex_flag:        show_all()        inp=input('请输入用户名,输入 b 返回主菜单:')        if inp=='b':            break        if user_data.get(inp) == None:  #判断用户是否存在            print('无{}账户信息,请重新输入.'.format(inp))        else:            # print(user_data[inp])            amount=user_data[inp][2]            f_amount=format_num.fn(amount)            print('账户{}目前最高额度为{}'.format(inp,f_amount))            while ex_flag:                want_amount=input('请输入要提升的额度,需要数字并且是整数:')                if want_amount.isdigit():                    want_amount=int(want_amount)                    if want_amount<=amount:                        print('提升目标额度小于或等于目前额度,无需提升')                    else:                        dif_amount=want_amount-user_data[inp][2]                        user_data[inp][2]=want_amount                        user_data[inp][3]+=dif_amount                        data_op.flush_d(user_data)                        print('额度提升成功,目前{}额度为{}'.format(inp,format_num.fn(want_amount)))                        log_admin.info('账户{}提升额度为{}'.format(inp,want_amount))                        ex_flag=0                else:                    print('输入有误,请重新输入.')def logout_manage():    """    退出信息,并记录日志    :return:    """    log_admin.info('admin退出登录')    exit('程序退出!')def login():    """    登录信息    :return:    """    admin_data=data_op.l_a_d()    inp=input('请输入管理员帐号:')    if admin_data.get(inp)==None:        print('管理员角色中无用户{}'.format(inp))    else:        i=0        while i<4:            if i ==3:                print('输入超过三次,关闭登录.')                return False            pwd=input('请输入{}的密码:'.format(inp))            if pwd==admin_data[inp]:                return True            else:                i+=1

atm_run.py:

#!/usr/bin/env python# -*-coding=utf-8-*-# Auther:ccorz Mail:ccniubi@163.com Blog:http://www.cnblogs.com/ccorz/# GitHub:https://github.com/ccorzorz"""ATM 终端操作"""import sys,prettytable,timesys.path.append('..')from core.terminal_op import *from core import terminal_op,terminal_repay,terminal_show_record,\    terminal_transfers,terminal_view_credit,terminal_withdraw,\    terminal_discover_bills,bills_ratedef logout():    exit('系统退出')#将函数名称对应写入列表方便用户选择menu=[terminal_view_credit.view_credit,      terminal_show_record.show_record,      terminal_repay.repay,      terminal_withdraw.withdraw,      terminal_transfers.transfers,      terminal_discover_bills.inquire_bills,      bills_rate.inquire_rates,      logout]def main():    """    先执行登录函数,返回1时进入主菜单    :return:    """    res=terminal_op.login()    if res:        row=prettytable.PrettyTable()        row.field_names=['查看可用额度','查看消费记录','还款','提现','转账',                         '查询本月账单','还款逾期情况查询','退出']        row.add_row([0,1,2,3,4,5,6,'q&quit'])        while True:            print('\033[31;1m欢迎来到宇宙最屌老男孩支行\033[0m'.center(93,'*'))            print(row)            inp=input('请输入对应的操作序列号:')            if inp.isdigit():                inp=int(inp)                if inp>7:                    print('输入有误,请重新输入!!')                else:                    #如果用户选择正确,执行对应的函数                    menu[inp](tip['user_name'])                    time.sleep(1)            elif inp.lower()=='q' or inp.lower()=='quit':                logout()            else:                print('输入有误,请重新输入!!')    else:        passif __name__ == '__main__':    main()

bills_rate.py:

#!/usr/bin/env python# -*-coding=utf-8-*-# Auther:ccorz Mail:ccniubi@163.com Blog:http://www.cnblogs.com/ccorz/# GitHub:https://github.com/ccorzorz"""账单查询模块"""import sys,json,timesys.path.append('..')from core import terminal_op,data_op,format_num,veri_code,time_cal,\    generate_bills,terminal_discover_billsfrom conf.setting import *def current_10th():    """    取当月10号的时间,并返回结构时间的数据    :return: 结构时间的数据    """    current_10th_time=time_cal.get_10th_of_current_month()    current_10th_time_stamp=time_cal.time_s_to_stamp(current_10th_time)    return current_10th_time_stampdef last_22nd():    """    取上个月22号的时间,并返回结构时间的数据    :return: 结构时间的数据    """    last_22nd_time=time_cal.get_22nd_of_last_month()    last_22nd_time_stamp=time_cal.time_s_to_stamp(last_22nd_time)    return last_22nd_time_stampdef inquire_rates(args):    """    查询账单利息函数    :param args: 用户名    :return: None    """    user_data=data_op.l_d()    user_record=user_data[args][4]    last_22nd_stamp=last_22nd()    current_10th_stamp=current_10th()    today=datetime.datetime.today()    today_stamp=time_cal.time_s_to_stamp(today)    if today_stamp <= current_10th_stamp:        # 如未到10日,提醒用户利息为0        print('未到本月10号,目前利率为0,如果已还款请飘过,如未还款,请速还款')        time.sleep(1)    else:        #计算入账的总和        income_list=[]        for item in user_record:            for key in item:    #判断目前时间是否在上月22日到本月10日之间                if last_22nd_stamp
<=current_10th_stamp: income_list.append(item.get(key)) income=[] for item in income_list: if '收款' in item or '还款' in item: income.append(item[2]) income_amount=sum(income) current_file_month=generate_bills.check_file_month() bills_db_list=terminal_discover_bills.check_exist_bills() if len(bills_db_list)==0: #判断是否存在账单文件 print('暂无账单生成,请联系客服或者银行行长,每月22日生成账单') time.sleep(1) else: dates=[] for item in bills_db_list: dates.append(item.split('_')[0]) if current_file_month in dates: bills_data=json.load(open('../db/{}_bil' 'ls.json'.format(current_file_month),'r')) should_amount=bills_data[args][0] if income_amount>=should_amount: # 判断入账的费用是否大于消费的费用总和 print('已全部还清,无逾期!') time.sleep(1) else:#否则进行逾期天数和利息计算 out_rate=0.0005 print('有逾期还款,逾期利率为每日万分之五') td=int(time.strftime('%Y%m%d')) current_10th_time=time_cal.get_10th_of_current_month() dead_line=[] dead_line.extend(str(current_10th_time).split(' ')[0].split('-')) dead_line=int(''.join(dead_line)) days=td-dead_line interest=days*out_rate*bills_data.get(args)[0] interest=format_num.fn(interest) print('您有逾期费用产生,' '逾期天数\033[31;1m{}\033[0m,逾期利率为万分之五,' '截止到今天的逾期利息' '为\033[31;1m{}\033[0m'.format(days,interest)) time.sleep(1) else: print('暂无账单生成')

data_op.py:

#!/usr/bin/env python# -*-coding=utf-8-*-# Auther:ccorz Mail:ccniubi@163.com Blog:http://www.cnblogs.com/ccorz/# GitHub:https://github.com/ccorzorz"""数据库操作函数配置"""import jsondef l_d():    """    读 atm 用户数据库    :return:    """    user_data=json.load(open('../db/atm_cart_db.json','r'))    return user_datadef flush_d(args):    """    写入 ATM用户数据    :param args:  新的用户数据    :return:  True    """    json.dump(args,open('../db/atm_cart_db.json','w'),ensure_ascii=False,indent=1)    return Truedef l_a_d():    """    加载管理员数据库    :return:    """    admin_data=json.load(open('../db/atm_admin_db.json','r'))    return admin_data

format_num.py:

#!/usr/bin/env python# -*-coding=utf-8-*-# Auther:ccorz Mail:ccniubi@163.com Blog:http://www.cnblogs.com/ccorz/# GitHub:https://github.com/ccorzorzdef fn(args):    """    将金额转化为人民币模式,带逗号分隔,保留小数点两位,四舍五入    :param args:    :return:    """    num='{:,.2f}'.format(args)    return num

generate_bills.py:

#!/usr/bin/env python# -*-coding=utf-8-*-# Auther:ccorz Mail:ccniubi@163.com Blog:http://www.cnblogs.com/ccorz/# GitHub:https://github.com/ccorzorz"""账单生成模块"""import sys,json,timesys.path.append('..')from core import terminal_op,data_op,format_num,veri_code,time_calfrom conf.setting import *from core.logger import *def generate_bills(args):    """    用户账单内容生成函数    :param args: 用户名    :return: 指定用户的欠款和消费记录内容    """    user_data=data_op.l_d()    records=user_data.get(args)[4]    #上月22日,本月22日的时间戳生成    last_22=time_cal.get_22nd_of_last_month()    last_22_stamp=time_cal.time_s_to_stamp(last_22)    current_22=time_cal.get_22nd_of_current_month()    current_22_stamp=time_cal.time_s_to_stamp(current_22)    time_range_records=[]    for item in records:        for key in item:            key_stamp=time_cal.str_to_stamp(key)            if last_22_stamp < key_stamp < current_22_stamp:                time_range_records.append({key:item[key]})    # print(time_range_records)    if len(time_range_records)==0:        bills=0    else:        income_records=[]   #入账记录        expend_records=[]   #消费记录        for item in time_range_records:            for ite in item:                if '还款' in item[ite] or '收款' in item[ite]:                    income_records.append(item[ite][2])                else:                    expend_records.append(item[ite][3])                    expend_records.append(item[ite][2])        if len(income_records)==0:income=0        else:income=sum(income_records)        if len(expend_records)==0:            expend=0        else:            expend=sum(expend_records)        if income>=expend:            bills=0        else:            bills=expend-income    bills_contect=[bills,time_range_records]    #相关信息生成列表    return bills_contectdef check_file_month():    """    判断并生成本月账单文件的日期字符串    :return:    """    mon=time_cal.get_22nd_of_last_month()    file_month=str(mon).strip().split(' ')[0].strip().split('-')    file_month.pop(2)    res=''.join(file_month) #字符串萍姐    return resdef main():    """    主函数    :return:    """    dtd=time.strftime('%d')    dtd=int(dtd)    if dtd<=22: #判断时间是否过22日,如果未到22日,提醒用户        print('本月生成账单日期未到,操作退出!')        time.sleep(1)    else:        user_data=data_op.l_d()        bill={}        for item in user_data:            bills_contect=generate_bills(item)            bill[item]=bills_contect        # print(bill)        file_month=check_file_month()        #如果过22日,遍历相关日期内的数据,并将数据写入文件,生产新的文件        json.dump(bill,open('../db/{}_bills.json'.format(file_month),'w'),                  ensure_ascii=False,indent=1)        print('账单已生成,目录为:\033[31;1m../db/\033[0m,'              '文件名称为:\033[31;1m{}_bills.json\033[0m'.format(file_month))        log_admin.info('生成账单文件{}_bills.json'.format(file_month))        time.sleep(1)

logger.py:

#!/usr/bin/env python# -*-coding=utf-8-*-# Auther:ccorz Mail:ccniubi@163.com Blog:http://www.cnblogs.com/ccorz/# GitHub:https://github.com/ccorzorz"""日志模块"""import sys,loggingsys.path.append('..')from conf.setting import *def logger(log_type):    """    定义日志模块    :param log_type: 日志的用户    :return:    """    logger=logging.getLogger(log_type)    logger.setLevel(LOG_LEVEL)    ch=logging.StreamHandler()    ch.setLevel(LOG_LEVEL)    fh=logging.FileHandler('../log/{}'.format(LOG_TYPE[log_type]))    fh.setLevel(LOG_LEVEL)    formatter=logging.Formatter('%(asctime)s - %(name)s -'                                ' %(levelname)s - %(message)s')    ch.setFormatter(formatter)    fh.setFormatter(formatter)    logger.addHandler(ch)    logger.addHandler(fh)    return logger#将日志实例化,防止进入循环后多次刷新日志log_trans=logger('trans')log_access=logger('access')log_admin=logger('admin')

manager_main.py:

#!/usr/bin/env python# -*-coding=utf-8-*-# Auther:ccorz Mail:ccniubi@163.com Blog:http://www.cnblogs.com/ccorz/# GitHub:https://github.com/ccorzorz"""管理员操作主函数"""import sys,prettytablesys.path.append('..')from core import atm_admin_op,generate_billsdef show_menu():    """    定义显示菜单函数    :return:    """    row=prettytable.PrettyTable()    row.field_names=['新增账号','冻结用户','解冻用户','提升用户额度',                     '查看所有用户','生成上月账单','退出程序']    row.add_row([0,1,2,3,4,5,'q&quit'])    print(row)#函数名列表化menu_list=[atm_admin_op.c_u,           atm_admin_op.freeze_u,           atm_admin_op.un_freeze_u,           atm_admin_op.enhance_credit,           atm_admin_op.show_all,           generate_bills.main,           atm_admin_op.logout_manage]def main():    """    执行函数,登录成功后显示主菜单,用户选择对应的函数名后,执行对应的函数    :return:    """    login_res=atm_admin_op.login()    if login_res:        while True:            show_menu()            inp=input('请选择操作对应的序列号:')            if inp=='q' or inp=='quit':                menu_list[6]()            elif inp.isdigit():                inp=int(inp)                if inp<6:                    menu_list[inp]()                else:                    print('选择有误,请重新输入.')            else:                print('选择有误,请重新输入.')    else:        print('登录失败!')if __name__ == '__main__':    main()

pass_handler.py:

#!/usr/bin/env python# -*-coding=utf-8-*-# Auther:ccorz Mail:ccniubi@163.com Blog:http://www.cnblogs.com/ccorz/# GitHub:https://github.com/ccorzorzimport hashlibdef md5_pwd(pwd):    """    为了防止解密,hashlib.md5时加入自己的字段    将密码转化为 md5形式    :param pwd: 密码明文    :return: 加密后的密码    """    hash=hashlib.md5(bytes('odlboy',encoding='utf8'))    hash.update(bytes(pwd,encoding='utf8'))    res=hash.hexdigest()    return res

shop_mall.py:

#!/usr/bin/env python# -*-coding=utf-8-*-# Auther:ccorz Mail:ccniubi@163.com Blog:http://www.cnblogs.com/ccorz/# GitHub:https://github.com/ccorzorz#加载模块import syssys.path.append('..')import json,prettytable,time,collectionsfrom core import terminal_pay#将json中的数据赋值为变量user_info=json.load(open('../db/mall_user.json','r'))goods=json.load(open('../db/goods.json','r'))save_cart=json.load(open('../db/mall_cart.json','r'))#设置时间戳的变量time_now=time.strftime('%Y-%m-%d %H:%M:%S')cart=Noneuser_name=Nonebalance=None#打开用户锁定文件,并将其转化为列表user_lock=open('../db/mall_user_lock','r+')locker=user_lock.readlines()#定义刷新商品信息的函数def refresh_goods():    json.dump(goods,open('../db/goods.json','w'),ensure_ascii=False,indent=1)def refresh_user():    json.dump(user_info,open('../db/mall_user.json','w'),ensure_ascii=False,indent=1)#定义如果未结算退出时记录购物车信息的函数def cache_cart(user_name):    save_cart[user_name]=cart      #将购物车列表赋值于要保存的数据变量    # json文件写入    json.dump(save_cart,open('../db/mall_cart.json','w'),ensure_ascii=False,indent=1)#定义用户注册函数def regis():    #设置退出标识符    exit_flag=0    while exit_flag==0:        user_name=input('请输入您的用户名:')        if user_name in user_info.keys():            print('此用户已被注册,请重新输入.')        else:            user_pwd=input('请输入您的密码:')            for i in range(3):                user_pwd_again=input('请再次确认您的密码:')                if user_pwd_again==user_pwd:                    #赋值密码变量                    user_info[user_name]=[user_pwd_again,0,[]]                    #将变量写入user_info文件                    refresh_user()                    print('用户名%s已注册成功,请登录购买商品...'%user_name)                    exit_flag=1                    break                elif i==2:                    print('您输入的密码次数超过三次,注册关闭!')                    exit_flag=1                else:                    print('您输入的密码和上次输入的密码不匹配,请重新输入,还有%s次机会.'%(2-i))#定义用户充值函数def refill(user_name):    for i in range(3):        amount=input('请输入您要充值的金额,请输入数字:')        if amount.isdigit():            result=terminal_pay.pay_api(int(amount),'大牛逼商城',)            if result:                user_info[user_name][1]+=int(amount)                #写入用户的json文件中                refresh_user()                print('\033[32;1m土豪,请保养程序员!!!\033[0m充值成功,您的余'                      '额为\033[31;1m%s\033[0m'%user_info[user_name][1])                #打印余额                balance=user_info[user_name][1]                print(balance)                break            else:                print('充值失败,请联系最屌银行行长')                break        elif i==2:            exit('你在坑我么?告诉你要输入数字的,程序关闭...')        else:            print('您输入的不是数字,请重新输入..')#定义显示购物车函数def show_vcart(cart):    # print(cart)    if len(cart)>0:        #将内存中的购物车列表计算重复数量        v_cart = collections.Counter(cart)        #转化为字典,方便取值        dv_cart=dict(v_cart)        #使用prettytable 显示购物车信息        row=prettytable.PrettyTable()        row.field_names=['序列号','商品名称','商品数量','商品总价']        for i in enumerate(dv_cart):            index=i[0]            item=i[1][0]            totle_price = i[1][1] * dv_cart[i[1]]            item_amount = dv_cart[i[1]]            row.add_row([index,item,item_amount,totle_price])        print(row)    else:        print('\033[31;1m购物车为空\033[0m'.center(50,'*'))    time.sleep(1)#定义付款结算函数def check_cart():    while True:        inp = input('''1.余额支付2.信用卡支付选择支付类型:''')        if inp == '1':            if len(cart)>0:                v_cart=collections.Counter(cart)                dv_cart=dict(v_cart)                #定义空列表                ddv_cart=[]                #遍历字典,将字典中的元素添加入空列表                for i in enumerate(dv_cart):                    index=i[0]                    item=i[1][0]                    totle_price = i[1][1] * dv_cart[i[1]]                    item_amount = dv_cart[i[1]]                    ddv_cart.append([item,item_amount,totle_price])                #改变json数据中的变量值,记录购物历史                user_info[user_name][2].append([time_now,ddv_cart])                #更改余额                user_info[user_name][1]=balance                #更爱用户余额,写入购物历史数据,更改商品库存                refresh_user()                refresh_goods()                #清空购物车中的商品                cart.clear()                #将清空的购物车信息写入二次登陆的用户信息                cache_cart(user_name)                print('\033[31;1m结账成功,波多野结衣即将为您送货,请准备收货...\033[0m')                time.sleep(1)                break            else:                print('\033[31;1m购物车是空的...\033[0m')                #如果为空,重置二次登陆用户的购物车信息                cache_cart(user_name)                time.sleep(1)                break            # break            # return True        elif inp == '2':            if len(cart)>0:                # print(cart)                pri_list=[]                for item in cart:                    pri_list.append(item[1])                sum_amount=sum(pri_list)                result=terminal_pay.pay_api(sum_amount,'大牛逼商城',)                if result:                    v_cart=collections.Counter(cart)                    dv_cart=dict(v_cart)                    #定义空列表                    ddv_cart=[]                    #遍历字典,将字典中的元素添加入空列表                    for i in enumerate(dv_cart):                        index=i[0]                        item=i[1][0]                        totle_price = i[1][1] * dv_cart[i[1]]                        item_amount = dv_cart[i[1]]                        ddv_cart.append([item,item_amount,totle_price])                    #改变json数据中的变量值,记录购物历史                    user_info[user_name][2].append([time_now,ddv_cart])                    #更爱用户余额,写入购物历史数据,更改商品库存                    refresh_user()                    refresh_goods()                    #清空购物车中的商品                    cart.clear()                    #将清空的购物车信息写入二次登陆的用户信息                    cache_cart(user_name)                    print('\033[31;1m结账成功,波多野结衣即将为您送货,请准备收货...\033[0m')                    time.sleep(1)                    break                else:                    print('信用卡支付失败!!!')                    time.sleep(1)                    break            else:                print('\033[31;1m购物车是空的...\033[0m')                time.sleep(1)                break#定义查看购物历史函数def show_his(user_name):    user_info=json.load(open('../db/mall_user.json','r'))    #购物历史数据变量赋值    his_list=user_info[user_name][2]    #入购物历史为空的处理    if len(his_list)==0:        print('无购物历史...')    else:        for his in his_list:            #取值时间戳            dt=his[0]            print('\033[31;1m购物时间:%s\033[0m'.center(50,'*')%dt)            #打印购买详情            row=prettytable.PrettyTable()            row.field_names=['商品名称','数量','总额']            for item in his[1]:                #变量取值                p_name=item[0]                p_amount=item[1]                p_totle=item[2]                row.add_row([p_name,p_amount,p_totle])            print(row)#定义编辑购物车函数,后期追加的功能,所以代码比较多,跟之前写的耦合性较弱def edit_cart(user_name):    #定义变量,用set的方式去重,并转化为列表,作为商品信息    e_cart=list(set(cart))    e_vcart=collections.Counter(cart)    e_vcart=dict(e_vcart)    #将列表排序,方便取值    e_cart.sort()    #打印购物车信息    row=prettytable.PrettyTable()    row.field_names=['商品序列号','商品名称','商品数量','总价']    for i in enumerate(e_cart):        index=i[0]        p_name=i[1][0]        p_price=i[1][1]        p_amount=e_vcart[i[1]]        p_totle=i[1][1]*e_vcart[i[1]]        p_belong=i[1][2]        row.add_row([index,p_name,p_amount,p_totle])    print(row)    while True:        #用户选择商品序列        choice_num=input('请输入要编辑的商品序列号,输入\033[31;1mq或quit\033[0m为退出编辑购物车:')        #设置条件,输入为数字,并且小于商品列表的数量        if choice_num.isdigit() and  int(choice_num)
p_amount: #计算差价 d_price=int(choice_num_d-p_amount)*int(e_vcart[e_cart[choice_num]]) if balance>=d_price: for i in range(choice_num_d-p_amount): cart.append(e_cart[choice_num]) #使用差价计算余额 balance-=d_price #修改库存信息 goods_stock+=p_amount goods_stock-=choice_num_d else: print('余额不足,修改失败,请充值!') break else: d_price=int(abs(choice_num_d-p_amount))*(e_vcart[e_cart[choice_num]]) for i in range(abs(choice_num_d-p_amount)): cart.remove(e_cart[choice_num]) #计算差价,修改库存,余额 balance+=d_price goods_stock+=p_amount goods_stock-=choice_num_d print('修改成功.') break else: print('输入数量有误,请合适商品的库存...') break else: print('输入类型有误请重新输入...') break elif choice_num == 'q' or choice_num == 'quit': print('退出编辑购物车...') break else: print('输入有误,请重新输入...')def main(): #设置退出循环标识符初始值 break_flag=0 #程序开始,输入用户名 name=input('请输入\033[31;1m壕\033[0m的用户名:') global user_name user_name=name if user_name in locker: #退出并回显 exit('用户已被锁定') #判断是否在为已注册用户并且未被锁定 elif user_name in user_info.keys() and user_info not in locker: for i in range(3): #退出标识符是否被改变 if break_flag==1: #如改为1退出循环 break else: #确认密码 pwd=input('请输入%s的密码:'%user_name) if pwd==user_info[user_name][0]: #判断是否有未结算退出的购物清单 global cart if save_cart.get(user_name)==None: #如果空,将购物车设置为空 cart=[] else: #反之,将读取未结算商品列表 cart=save_cart[user_name] for i in range(len(cart)): cart[i]=tuple(cart[i]) print('登陆成功...') print('欢迎来到大牛逼商城,走过路过,不要错过...'.center(50,'*')) while break_flag==0: #判断购物车是否为空,设置余额初始值 global balance if save_cart.get(user_name)==None or len(save_cart[user_name])<=0: balance = user_info[user_name][1] print('壕,您的账户余额为:\033[31;1m%s\033[0m,\033[32;1m(钱不够?账户' '充值请输入r,回车继续购物)\033[0m:'%balance) else: #如果购物车不为空,计算扣除商品总价后的余额初始 cart_price_list=[] for i in cart: cart_price_list.append(i[1]) # balance=user_info[user_name][1]-sum(cart_price_list) print('\033[31;1m您的购物车中还有未结算的商品,如减去购物车' '中的商品总价,您的余额为\033[0m\033[31;1m%s\033[0m'%balance) time.sleep(1) #显示购物主菜单 mrow=prettytable.PrettyTable() mrow.field_names=['功能','购物','查看购物车','查看购物历史', '余额充值','退出购物商城','确认购买','编辑购物车'] mrow.add_row(['快捷键','回车','S或showcart','H或history', 'R或refill','Q或quit','C或check','E或者edit']) print(mrow) menu=input('''\033[32;1m选择菜单:\033[0m''') #判断用户选择 if menu.lower()=='r': refill(user_name) #执行充值函数 elif menu.lower()=='h' or menu.lower()=='history': time.sleep(1) show_his(user_name) #执行查看购物历史记录函数 time.sleep(1) elif menu.lower()=='s' or menu.lower()=='showcart' : time.sleep(1) show_vcart(cart) #执行查看购物车函数 elif menu.lower()=='c' or menu.lower()=='check': check_cart() elif menu.lower()=='q' or menu.lower()=='quit': cache_cart(user_name) #执行未结算退出保存购物清单函数 exit('已退出商城') elif menu.lower()=='e' or menu.lower()=='edit': edit_cart(user_name) #执行编辑购物车函数 elif len(menu)==0: #判断输入为回车 while break_flag==0: print('壕,您的扣除购物车中的钱款预计账户余额为:\033[31;1m%s\033[0m:'%balance) print('请选择商品的类型编号'.center(50,'=')) cla_list=list(goods.keys()) #将分类转化为列表 #打印商品分类 for i in cla_list: print(cla_list.index(i),i) #让用户选择分类序列号 choice_cla_num=input('\033[32;1m请选择您要购买物品类型所对' '应的序列号(返回主菜单输入b或back,查看购物车输入s,确认付款输入c,退出输入q或quit):\033[0m') #判断用户输入的类型,如果为数字并且数字小于列表元素数量 if choice_cla_num.isdigit() and int(choice_cla_num)
= p_count*p_price: p_stock-=p_count goods[cla][p_name]['stock']=p_stock #加入购物车 for i in range(p_count): cart.append((p_name,p_price,p_belong)) print('商品\033[32;1m%s\033[0m已加入购物车'%p_name) v_cart=collections.Counter(cart) print('\033[31;1m未付款商品\033[0m'.center(50,'*')) #显示购物车 show_vcart(v_cart) #余额减去商品总价 balance-=p_count*p_price break elif choice_p_num.lower()=='b' or choice_p_num.lower=='back': break elif choice_p_num.lower()=='s': show_vcart(cart) #查看购物车 elif choice_p_num.lower()=='c' or choice_p_num.lower()=='check': check_cart() #确认支付 elif choice_p_num.lower()=='q' or choice_p_num.lower()=='quit': cache_cart(user_name) exit('已退出商城') else: print('输入类型错误,请重新输入') time.sleep(1) elif choice_cla_num.lower()=='s'or choice_cla_num.lower()=='showcart': show_vcart(cart) #查看购物车 elif choice_cla_num.lower()=='c' or choice_cla_num.lower()=='check': check_cart() elif choice_cla_num.lower()=='b'or choice_cla_num.lower()=='back': break elif choice_cla_num.lower()=='q' or choice_cla_num.lower()=='quit': break_flag=1 cache_cart(user_name) elif choice_cla_num.lower()=='e' or choice_cla_num.lower()=='edit': edit_cart(user_name) #编辑购物车 else: print('输入有误,请重新输入') #输入密码超过三次,用户锁定,并写入被锁用户名单文件 elif i==2: user_lock.write('\n%s'%user_name) user_lock.close() exit('三次密码错误,账户已被锁定') else: print('密码错误,请重新输入...') else: #用户注册选项 y_or_n=input('没有此用户名,需要注册才能进入商城!!!' '是否要注册?\033[31;1m输入y或者回车为注册,n或者q退出\033[0m:') if len(y_or_n)==0 or y_or_n=='y': regis() #执行用户注册函数 elif y_or_n=='n' or y_or_n=='q': exit('程序退出...') else: exit('输入错误,程序退出...')if __name__ == '__main__': main()

terminal_discover_bills.py:

#!/usr/bin/env python# -*-coding=utf-8-*-# Auther:ccorz Mail:ccniubi@163.com Blog:http://www.cnblogs.com/ccorz/# GitHub:https://github.com/ccorzorz"""账单查询模块"""import sys,json,time,os,prettytablesys.path.append('..')from core import terminal_op,data_op,format_num,veri_code,time_cal,generate_billsfrom conf.setting import *def check_exist_bills():    """    判断账单文件是否存在    :return: 账单文件列表    """    file_dir=os.listdir('../db') #将../db 目录下的内容生成列表形式    bills_db_list=[]    for item in file_dir:   #将以 bills.json 结尾的字符串添加进列表        if item.endswith('bills.json'):            bills_db_list.append(item)    return bills_db_listdef inquire_bills(args):    """    账单查询函数    :param args: 用户名    :return:  None    """    #确认本月的账单文件名的日期字符串    current_file_month=generate_bills.check_file_month()    bills_db_list=check_exist_bills()    if len(bills_db_list)==0:   #如果为空,提示用户无账单        print('未到账单日,账单未生成!')    else:        dates=[]        for item in bills_db_list:            dates.append(item.split('_')[0])        # print(dates)        if current_file_month in dates:            print('本月账单已生成:{}'.format(current_file_month))            time.sleep(1)            #加载账单数据,并显示用户欠款额度和消费记录            bills_data=json.load(open('../db/{}_bil'                                      'ls.json'.format(current_file_month),'r'))            print('{}于{}月的账单'.center(52,'*').format(args,current_file_month))            print('需还款金额:\033[31;1m{}(人民'                  '币)\033[0m'.format(format_num.fn(bills_data[args][0])))            print('消费记录'.center(52,'-'))            row=prettytable.PrettyTable()            row.field_names=['时间','交易方式','商家','金额','利息']            record=bills_data.get(args)[1]            # print(record)            for item in record:                for key in item:                    row.add_row([key,item[key][0],item[key][1],                                 item[key][2],item[key][3],])            print(row)            print('\033[31;1m请务必在下月10日(包括10日)之'                  '前还款,否则会有每日0.05%利息产生!\033[0m')        else:            print('未到账单日,账单未生成!')

terminal_op.py:

#!/usr/bin/env python# -*-coding=utf-8-*-# Auther:ccorz Mail:ccniubi@163.com Blog:http://www.cnblogs.com/ccorz/# GitHub:https://github.com/ccorzorz"""ATM 终端操作模块"""import syssys.path.append('..')from core import data_op,format_num,pass_handlerfrom core.logger import *#定义全局变量tip={'user_name':None,'login_state':False}def check_login(func):    """    定义一个装饰器,但后来发现逻辑中没什么乱用...搁置了,判断用户是否登录    :param func:    :return:    """    def inner(*args,**kwargs):        if tip['login_state']:            res=func(*args,**kwargs)            return res        else:            print('\033[31;1m此操作需要登录!!!\033[0m')    return innerdef freeze_count(args):    """    修改用户帐号状态的标志符函数    :param args: 用户名    :return: None    """    user_data=data_op.l_d()    user_data[args][0]=0    data_op.flush_d(user_data)def login():    user_data=data_op.l_d()    inp=input('请输入账户名:')    if user_data.get(inp)==None:        print('{}账户错误,请重新输入..'.format(inp))    else:        if user_data[inp][0]==0:    #判断用户状态            print('您的账户{}已被冻结,请联系管理员'.format(inp))            log_access.warning('冻结用户{}尝试登录'.format(inp))            return False        else:            i=0            while i<4:                if i==3:                    freeze_count(inp)   #输入超过三次,冻结用户,修改状态标志符                    print('您的账户{}已被冻结,请联系管理员'.format(inp))                    log_access.warning('用户{}被冻结'.format(inp))                    return False                pwd_inp=input('请输入{}的密码:'.format(inp))                pwd=pass_handler.md5_pwd(pwd_inp)   #密码加密匹配                if pwd==user_data[inp][1]:                    tip['user_name']=inp                    tip['login_state']=True #修改全局变量字典                    # print(tip)                    print('登录成功!')                    log_access.info('用户{}登录成功'.format(inp))                    return True                else:                    print('密码输入有误,请重新输入.')                    i+=1if __name__ == '__main__':    login()

terminal_pay.py:

#!/usr/bin/env python# -*-coding=utf-8-*-# Auther:ccorz Mail:ccniubi@163.com Blog:http://www.cnblogs.com/ccorz/# GitHub:https://github.com/ccorzorz"""支付接口"""import sys,timesys.path.append('..')from core import terminal_op,data_op,format_num,veri_codefrom conf.setting import *from core.logger import *def pay_api(args,business):    """    支付接口主函数    :param args: 支付金额    :param business: 支付商家    :return: True:支付成功  False:支付失败    """    print('\033[31;1m欢迎使用宇宙最屌银行支付接口,支付需要登录\033[0m')    res=terminal_op.login() #支付前先登录    if res:        user_data=data_op.l_d()        tip=terminal_op.tip        user_name=tip['user_name']        balance=user_data[tip['user_name']][3]        #提示用户可用额度        print('您的可用额度为{}'.format(format_num.fn(balance)))        if balance < args:  #额度不足,提醒            print('\033[31;1m可用额度不足,请使用其他方式支付\033[0m')            log_trans.info('{}调用支付接口,额度不足,支付失败'.format(user_name))            time.sleep(1)            return False        else:            #如果额度够,验证码验证,并修改相关用户数据信息            user_data[tip['user_name']][3]-=args            res=veri_code.check_veri()            if res:                data_op.flush_d(user_data)                record(user_name,'支付',business,args)                print('支付完成')                log_trans.info('{}支付调用,用'                                     '户{}支付{}'.format(business,user_name,args))                return True            else:                print('验证码失败,支付失败,loser!!')                time.sleep(1)                return False    else:        #登录失败        print('支付失败,请用其他方式支付,或者联系银行行长!')        log_trans.info('支付接口支付失败,登录验证不通过')        time.sleep(1)        return Falseif __name__ == '__main__':    pay_api(100,'test')

terminal_repay.py:

#!/usr/bin/env python# -*-coding=utf-8-*-# Auther:ccorz Mail:ccniubi@163.com Blog:http://www.cnblogs.com/ccorz/# GitHub:https://github.com/ccorzorz"""还款模块"""import syssys.path.append('..')from core import data_op,format_numfrom conf.setting import *from core.logger import *def repay(args):    """    还款函数    :param args:    :return:    """    user_data=data_op.l_d()    #如果可用额度大于等于信用额度,提示用户无需还款    if user_data[args][3] >= user_data[args][2]:        print('无欠款,无需还款!!!')    else:        #计算需还款额度        need_repay=user_data[args][2]-user_data[args][3]        print('您所需还款金额为:\033[31;1m{}\033[0m'.format(format_num.fn(need_repay)))        while True:            amount=input('请输入还款金额:')            if amount.isdigit():                amount=int(amount)                if amount>need_repay:   #判断如果大于需还款金额,用户选择                    inp=input('还款金额多余所需还款金额,是否继续?'                          '\033[32;1m回车或y 继续,back 或者 b 为返回\033[0m:')                    if len(inp)==0 or inp.lower() == 'y':                        #修改用户账户信息                        user_data[args][3]+=amount                        data_op.flush_d(user_data)                        print('还多了...还款完成!,目前可用信用金额'                              '为\033[31;1m{}\033[0m'.format                              (format_num.fn(user_data[args][3])))                        record(args,'还款','终端机',amount)                        log_trans.info('{}成功还款{}'.format(args,amount))                        break                    elif inp.lower() == 'b' or inp.lower()=='back':                        break                else:                    #修改用户账户信息                    user_data[args][3]+=amount                    data_op.flush_d(user_data)                    print('还款完成!目前可用信用金额'                              '为\033[31;1m{}\033[0m'.format                          (format_num.fn(user_data[args][3])))                    record(args,'还款','终端机',amount)                    log_trans.info('{}成功还款{}'.format(args,amount))                    break            else:                print('输入有误,请重新输入.')

terminal_show_record.py:

#!/usr/bin/env python# -*-coding=utf-8-*-# Auther:ccorz Mail:ccniubi@163.com Blog:http://www.cnblogs.com/ccorz/# GitHub:https://github.com/ccorzorz"""消费记录模块"""import sys,prettytablesys.path.append('..')from core import data_op,format_numdef show_record(args):    """    查看交易记录函数    :param args: 用户名    :return: None    """    user_data=data_op.l_d()    records=user_data.get(args)[4]    if len(records)==0:        print('无消费记录!')    else:        row=prettytable.PrettyTable()        row.field_names=['时间','交易','商家','交易金额','利息']        for item in records:            for record in item:                row.add_row([record,item[record][0],item[record][1],                             item[record][2],item[record][3]])        print(row)

terminal_transfers.py:

#!/usr/bin/env python# -*-coding=utf-8-*-# Auther:ccorz Mail:ccniubi@163.com Blog:http://www.cnblogs.com/ccorz/# GitHub:https://github.com/ccorzorz"""转账模块"""import syssys.path.append('..')from core import data_op,format_num,veri_codefrom conf.setting import *from core.logger import *def transfers(args):    #载入用户数据    user_data=data_op.l_d()    able_amount=user_data[args][3]    max_amount_2=user_data[args][2]/2    #可用额度如果大于信用额度的二分之一,则可转账额度为可用额度    if able_amount>=max_amount_2:        able_wd_amount=max_amount_2    else:#否则,可转账额度为可用额度        able_wd_amount=able_amount    print('您的可用转账额度为:{}'.format(format_num.fn(able_wd_amount)))    t_user_name=input('请输入您要转入的账户名称:')    #判断用户转账目标是否存在于本系统数据库中    if user_data.get(t_user_name)==None:        print('本银行无此账户信息,请核实信息后再进行转账...')    else:        #转账操作        for i in range(4):            if i ==3:                print('输入格式错误超过3次,退出提现操作.')                break            amount=input('请输入转账金额:')            if amount.isdigit():                amount=int(amount)                #判断金额是否超支                if amount>able_wd_amount:                    print('最高转账额度为{},已超支,'                          '退出操作!'.format(format_num.fn(able_wd_amount)))                    break                else:                    #如不超支,转账,先验证码验证                    res=veri_code.check_veri()                    if res:                        #修改数据库信息                        user_data[args][3]-=amount+amount*trans_rate['转账']                        user_data[t_user_name][3]+=amount                        data_op.flush_d(user_data)                        print('转账成功,现可消费额度为:'                              '{}'.format(format_num.fn(user_data[args][3])))                        record(args,'转账','终端机',amount)                        record(t_user_name,'收款',args,amount)                        log_trans.info('{}向{}成功转账{}'.format(args,t_user_name,amount))                        break                    else:                        print('验证失败!转账操作失败!!')                        log_trans.info('{}向{}转账失败'.format(args,t_user_name))                        break            else:                i+=1                print('输入格式错误,还有{}次机会'.format(3-i))

terminal_view_credit.py:

#!/usr/bin/env python# -*-coding=utf-8-*-# Auther:ccorz Mail:ccniubi@163.com Blog:http://www.cnblogs.com/ccorz/# GitHub:https://github.com/ccorzorz"""查看用户信息模块"""import syssys.path.append('..')from core import data_op,format_numdef view_credit(args):    """    查看用户信息,加载数据,并将相关数据显示至屏幕    :param args:用户名    :return:    """    user_data=data_op.l_d()    if user_data.get(args)==None:        print('无此用户.')    else:        balance=user_data[args][3]        balance=format_num.fn(balance)        credit=format_num.fn(user_data[args][2])        print('您的信用额度:\033[31;1m{}\033[0m,目前可用信用额'              '度为\033[31;1m{}\033[0m'.format(credit,balance))

terminal_withdraw.py:

#!/usr/bin/env python# -*-coding=utf-8-*-# Auther:ccorz Mail:ccniubi@163.com Blog:http://www.cnblogs.com/ccorz/# GitHub:https://github.com/ccorzorz"""提现模块"""import syssys.path.append('..')from core import data_op,format_numfrom conf.setting import *from core.logger import *def withdraw(args):    """    提现函数,与转账模块基本一样,但无需验证目标用户    :param args: 用户名    :return:    """    user_data=data_op.l_d()    able_amount=user_data[args][3]    max_amount_2=user_data[args][2]/2    if able_amount>=max_amount_2:        able_wd_amount=max_amount_2    else:        able_wd_amount=able_amount    print('您的可用提现额度为:{}'.format(format_num.fn(able_wd_amount)))    for i in range(4):        if i ==3:            print('输入格式错误超过3次,退出提现操作.')            break        amount=input('请输入提现金额:')        if amount.isdigit():            amount=int(amount)            if amount>able_wd_amount:                print('最高取现额度为{},已超支,'                      '退出操作!'.format(format_num.fn(able_wd_amount)))                log_trans.info('{}提现操作失败'.format(args))                break            else:                user_data[args][3]-=amount+amount*trans_rate['提现']                data_op.flush_d(user_data)                print('现可消费额度为:'                      '{}'.format(format_num.fn(user_data[args][3])))                record(args,'提现','终端机',amount)                log_trans.info('{}成功提现{}'.format(args,amount))                break        else:            i+=1            print('输入格式错误,还有{}次机会'.format(3-i))

time_op.py:

#!/usr/bin/env python# -*-coding=utf-8-*-# Auther:ccorz Mail:ccniubi@163.com Blog:http://www.cnblogs.com/ccorz/# GitHub:https://github.com/ccorzorz"""时间处理模块"""import datetime,timedef get_22nd_of_last_month():    """    获取上个月第一天的日期,然后加21天就是22号的日期    :return: 返回日期    """    today=datetime.datetime.today()    year=today.year    month=today.month    if month==1:        month=12        year-=1    else:        month-=1    res=datetime.datetime(year,month,1)+datetime.timedelta(days=21)    return resdef get_22nd_of_next_month():    """    获取下个月的22号的日期    :return: 返回日期    """    today=datetime.datetime.today()    year=today.year    month=today.month    if month==12:        month=1        year+=1    else:        month+=1    res=datetime.datetime(year,month,1)+datetime.timedelta(days=21)    return resdef get_10th_of_current_month():    """    获取本月的10号的日期    :return: 返回日期    """    today=datetime.datetime.today()    year=today.year    month=today.month    res=datetime.datetime(year,month,11)    return resdef get_22nd_of_current_month():    """    获取本月22号的日期    :return: 返回日期    """    today=datetime.datetime.today()    year=today.year    month=today.month    res=datetime.datetime(year,month,22)    return resdef time_s_to_stamp(args):    """    将datetime日期格式,先timetuple()转化为struct_time格式    然后time.mktime转化为时间戳    :param args:    datetime时间格式数据    :return:    时间戳格式数据    """    res=time.mktime(args.timetuple())    return resdef str_to_stamp(args):    """    将时间字符串格式转化为时间戳格式    :param args: 时间字符串格式    :return: 时间戳数据    """    r=time.strptime(args,'%Y-%m-%d %H:%M:%S')    res=time.mktime(r)    return res

veri_code.py:

#!/usr/bin/env python# -*-coding=utf-8-*-# Auther:ccorz Mail:ccniubi@163.com Blog:http://www.cnblogs.com/ccorz/# GitHub:https://github.com/ccorzorzimport randomdef veri_code():    """    #定义随机验证码函数    :return: 返回生成的随机码    """    li = []    for i in range(6):  #循环6次,生成6个字符        r = random.randrange(0, 5)  #随机生成0-4之间的数字        if r == 1 or r == 4:    #如果随机数字是1或者4时,生成0-9的数字            num = random.randrange(0, 9)            li.append(str(num))        else:   #如果不是1或者4时,生成65-90之间的数字            temp = random.randrange(65, 91)            char = chr(temp)    #将数字转化为ascii列表中对应的字母            li.append(char)    r_code = ''.join(li)    #6个字符拼接为字符串    print('\033[31;1m%s\033[0m' % r_code)    return r_code   #返回字符串def check_veri():    res=veri_code()    for i in range(3):        code=input('请输入验证码:')        if code.lower() == res.lower():            return True        else:            print('验证码错误,剩余尝试次数:{}'.format(2-i))

  db目录:

201605_bills.json:

{ "ccc": [  0,  [] ], "alex2": [  0,  [] ], "alex1": [  0,  [] ], "chengc": [  0,  [] ], "cc": [  11694.949999999997,  [   {    "2016-06-09 18:02:26": [     "提现",     "终端机",     8000,     400.0    ]   },   {    "2016-06-09 18:10:34": [     "支付",     "大牛逼商城",     300,     0    ]   },   {    "2016-06-09 18:20:56": [     "支付",     "大牛逼商城",     1800,     0    ]   },   {    "2016-06-09 18:26:33": [     "还款",     "终端机",     1,     0    ]   },   {    "2016-06-09 19:26:48": [     "提现",     "终端机",     1000,     50.0    ]   },   {    "2016-06-09 19:27:37": [     "提现",     "终端机",     2,     0.1    ]   },   {    "2016-06-09 21:35:38": [     "转账",     "终端机",     1,     0.05    ]   },   {    "2016-06-09 21:36:45": [     "转账",     "终端机",     1,     0.05    ]   },   {    "2016-06-09 23:00:46": [     "还款",     "终端机",     20,     0    ]   },   {    "2016-06-09 23:02:20": [     "提现",     "终端机",     1,     0.05    ]   },   {    "2016-06-09 23:02:20": [     "提现",     "终端机",     3,     0.15000000000000002    ]   },   {    "2016-06-09 23:03:47": [     "转账",     "终端机",     50,     2.5    ]   },   {    "2016-06-09 23:34:05": [     "转账",     "终端机",     1,     0.05    ]   },   {    "2016-06-09 23:34:05": [     "收款",     "cc",     1,     0    ]   },   {    "2016-06-10 00:28:04": [     "转账",     "终端机",     100,     5.0    ]   }  ] ], "alex": [  0,  [   {    "2016-06-09 21:36:45": [     "收款",     "cc",     1,     0    ]   },   {    "2016-06-09 23:03:47": [     "收款",     "cc",     50,     0    ]   },   {    "2016-06-10 00:28:04": [     "收款",     "cc",     100,     0    ]   }  ] ], "cccc": [  0,  [] ]}

atm_admin_db.json:

{"admin":"admin"}

atm_cart_db.json:

{ "cccc": [  1,  "b864ac015392b00d908bb7f760036248",  13000,  3000,  [] ], "ccc": [  1,  "3580a3546bd6afa4a37d0a02c46a4b5a",  10000,  5000,  [] ], "alex2": [  1,  "b864ac015392b00d908bb7f760036248",  15000,  15000,  [] ], "wyw": [  1,  "b864ac015392b00d908bb7f760036248",  100000,  105201,  [   {    "2016-06-12 10:41:11": [     "收款",     "cc",     1,     0    ]   },   {    "2016-06-12 16:30:15": [     "收款",     "cc",     5200,     0    ]   }  ] ], "ab": [  1,  "b864ac015392b00d908bb7f760036248",  1223,  1223,  [] ], "alex1": [  1,  "b864ac015392b00d908bb7f760036248",  5100,  5000,  [] ], "chengc": [  1,  "b864ac015392b00d908bb7f760036248",  150000,  150000,  [] ], "alex": [  1,  "b864ac015392b00d908bb7f760036248",  16000,  15152,  [   {    "2016-06-09 21:36:45": [     "收款",     "cc",     1,     0    ]   },   {    "2016-06-09 23:03:47": [     "收款",     "cc",     50,     0    ]   },   {    "2016-06-10 00:28:04": [     "收款",     "cc",     100,     0    ]   }  ] ], "yangk": [  1,  "b864ac015392b00d908bb7f760036248",  19999,  19999,  [] ], "cc": [  1,  "b864ac015392b00d908bb7f760036248",  51004,  50755.999999999985,  [   {    "2016-06-09 18:02:26": [     "提现",     "终端机",     8000,     400.0    ]   },   {    "2016-06-09 18:10:34": [     "支付",     "大牛逼商城",     300,     0    ]   },   {    "2016-06-09 18:20:56": [     "支付",     "大牛逼商城",     1800,     0    ]   },   {    "2016-06-09 18:26:33": [     "还款",     "终端机",     1,     0    ]   },   {    "2016-06-09 19:26:48": [     "提现",     "终端机",     1000,     50.0    ]   },   {    "2016-06-09 19:27:37": [     "提现",     "终端机",     2,     0.1    ]   },   {    "2016-06-09 21:35:38": [     "转账",     "终端机",     1,     0.05    ]   },   {    "2016-06-09 21:36:45": [     "转账",     "终端机",     1,     0.05    ]   },   {    "2016-06-09 23:00:46": [     "还款",     "终端机",     20,     0    ]   },   {    "2016-06-09 23:02:20": [     "提现",     "终端机",     1,     0.05    ]   },   {    "2016-06-09 23:02:20": [     "提现",     "终端机",     3,     0.15000000000000002    ]   },   {    "2016-06-09 23:03:47": [     "转账",     "终端机",     50,     2.5    ]   },   {    "2016-06-09 23:34:05": [     "转账",     "终端机",     1,     0.05    ]   },   {    "2016-06-09 23:34:05": [     "收款",     "cc",     1,     0    ]   },   {    "2016-06-10 00:28:04": [     "转账",     "终端机",     100,     5.0    ]   },   {    "2016-06-15 20:51:11": [     "还款",     "终端机",     1,     0    ]   },   {    "2016-06-15 20:51:11": [     "还款",     "终端机",     1,     0    ]   },   {    "2016-06-12 10:15:59": [     "支付",     "test",     100,     0    ]   },   {    "2016-06-12 10:41:11": [     "转账",     "终端机",     1,     0.05    ]   },   {    "2016-06-12 10:41:11": [     "提现",     "终端机",     200,     10.0    ]   },   {    "2016-06-12 10:41:11": [     "还款",     "终端机",     2000,     0    ]   },   {    "2016-06-12 13:03:54": [     "支付",     "大牛逼商城",     100,     0    ]   },   {    "2016-06-12 16:28:03": [     "支付",     "大牛逼商城",     900,     0    ]   },   {    "2016-06-12 16:30:15": [     "还款",     "终端机",     22,     0    ]   },   {    "2016-06-12 16:30:15": [     "提现",     "终端机",     300,     15.0    ]   },   {    "2016-06-12 16:30:15": [     "转账",     "终端机",     5200,     260.0    ]   },   {    "2016-06-15 13:07:51": [     "支付",     "大牛逼商城",     5888,     0    ]   },   {    "2016-06-15 13:09:16": [     "还款",     "终端机",     12000,     0    ]   }  ] ], "1234": [  1,  "15da27ca7d6c671cbdf85396b9096d80",  10000,  1220,  [] ]}

goods.json:

{ "服装": {  "T恤": {   "stock": 887,   "belong": "服装",   "price": 300  },  "小白鞋": {   "stock": 5954,   "belong": "服装",   "price": 900  },  "Nudie牛仔裤": {   "stock": 3973,   "belong": "服装",   "price": 699  },  "驴牌腰带": {   "stock": 2999,   "belong": "服装",   "price": 9999  } }, "手机": {  "华为Mate": {   "stock": 5995,   "belong": "手机",   "price": 2999  },  "Iphone": {   "stock": 2996,   "belong": "手机",   "price": 5888  },  "锤子2(这特么真是手机)": {   "stock": 2994,   "belong": "手机",   "price": 998  },  "XiaoMi 4": {   "stock": 5395,   "belong": "手机",   "price": 1999  } }, "电脑": {  "Mac pro": {   "stock": 3994,   "belong": "电脑",   "price": 9999  },  "Mac Air": {   "stock": 6001,   "belong": "电脑",   "price": 6999  },  "IBM X240": {   "stock": 3003,   "belong": "电脑",   "price": 6999  },  "Surface Book": {   "stock": 3020,   "belong": "电脑",   "price": 8999  } }, "汽车": {  "Porsche 911": {   "stock": 594,   "belong": "汽车",   "price": 2999999  },  "Tesla Model S": {   "stock": 3000,   "belong": "汽车",   "price": 799999  },  "BMW X3": {   "stock": 399,   "belong": "汽车",   "price": 499999  },  "PASST": {   "stock": 297,   "belong": "汽车",   "price": 299999  } }, "家电": {  "微波炉": {   "stock": 2994,   "belong": "家电",   "price": 800  },  "彩电": {   "stock": 397,   "belong": "家电",   "price": 5000  },  "洗衣机": {   "stock": 597,   "belong": "家电",   "price": 999  },  "冰箱": {   "stock": 300,   "belong": "家电",   "price": 3000  },  "热水器": {   "stock": 900,   "belong": "家电",   "price": 600  } }}

mall_cart.json:

{ "cc": [], "shane": []}

mall_user.json:

{ "zc": [  "123",  0,  [] ], "shane": [  "123",  96105,  [   [    "2016-06-06 13:54:13",    [     [      "微波炉",      2,      1600     ],     [      "洗衣机",      1,      999     ]    ]   ],   [    "2016-06-06 13:54:13",    [     [      "T恤",      2,      600     ],     [      "Nudie牛仔裤",      1,      699     ]    ]   ]  ] ], "zhangxiaodong": [  "zhangxiaodong",  0,  [] ], "123": [  "123",  0,  [] ], "cc": [  "123",  73045,  [   [    "2016-05-19 14:23:37",    [     [      "小白鞋",      1,      900     ],     [      "T恤",      1,      300     ]    ]   ],   [    "2016-05-19 17:07:06",    [     [      "微波炉",      1,      800     ]    ]   ],   [    "2016-05-19 17:56:19",    [     [      "Nudie牛仔裤",      1,      699     ],     [      "洗衣机",      1,      999     ]    ]   ],   [    "2016-05-20 10:07:34",    [     [      "IBM X240",      1,      6999     ]    ]   ],   [    "2016-05-20 13:34:32",    [     [      "锤子2(这特么真是手机)",      1,      998     ]    ]   ],   [    "2016-05-20 15:59:02",    [     [      "洗衣机",      1,      999     ]    ]   ],   [    "2016-06-06 13:51:04",    [     [      "小白鞋",      2,      1800     ]    ]   ],   [    "2016-06-06 15:25:05",    [     [      "T恤",      1,      300     ]    ]   ],   [    "2016-06-06 15:25:05",    [     [      "Mac Air",      1,      6999     ]    ]   ],   [    "2016-06-06 17:29:16",    [     [      "微波炉",      1,      800     ]    ]   ],   [    "2016-06-07 11:37:57",    [     [      "Nudie牛仔裤",      1,      699     ]    ]   ],   [    "2016-06-07 14:12:59",    [     [      "彩电",      1,      5000     ]    ]   ],   [    "2016-06-08 09:26:10",    [     [      "微波炉",      2,      1600     ]    ]   ],   [    "2016-06-08 17:19:09",    [     [      "彩电",      1,      5000     ],     [      "T恤",      3,      900     ]    ]   ],   [    "2016-06-08 17:20:05",    [     [      "小白鞋",      1,      900     ]    ]   ],   [    "2016-06-08 17:20:05",    [     [      "Iphone",      1,      5888     ]    ]   ],   [    "2016-06-08 17:20:05",    [     [      "XiaoMi 4",      1,      1999     ]    ]   ],   [    "2016-06-08 17:29:18",    [     [      "小白鞋",      2,      1800     ]    ]   ],   [    "2016-06-08 17:29:18",    [     [      "小白鞋",      1,      900     ]    ]   ],   [    "2016-06-08 17:31:51",    [     [      "Nudie牛仔裤",      2,      1398     ]    ]   ],   [    "2016-06-08 17:35:40",    [     [      "T恤",      1,      300     ]    ]   ],   [    "2016-06-08 17:36:25",    [     [      "Mac pro",      1,      9999     ]    ]   ],   [    "2016-06-08 17:50:44",    [     [      "T恤",      1,      300     ]    ]   ],   [    "2016-06-08 17:54:24",    [     [      "华为Mate",      1,      2999     ]    ]   ],   [    "2016-06-09 18:10:34",    [     [      "T恤",      1,      300     ]    ]   ],   [    "2016-06-09 18:20:56",    [     [      "小白鞋",      2,      1800     ]    ]   ],   [    "2016-06-12 16:28:03",    [     [      "小白鞋",      1,      900     ]    ]   ],   [    "2016-06-15 13:07:51",    [     [      "Iphone",      1,      5888     ]    ]   ]  ] ], "chengc": [  "123456",  999999999,  [] ]}

mall_user_lock:

shane

  log日志会自动创建..

trans.log:

2016-06-15 20:51:21,143 - trans - INFO - cc成功还款12016-06-15 20:51:27,495 - trans - INFO - cc成功还款12016-06-15 20:51:27,495 - trans - INFO - cc成功还款12016-06-12 10:16:09,824 - trans - INFO - test支付调用,用户cc支付1002016-06-12 10:43:13,253 - trans - INFO - cc向wyw成功转账12016-06-12 10:43:24,376 - trans - INFO - cc成功提现2002016-06-12 10:43:48,317 - trans - INFO - cc成功还款20002016-06-12 13:04:25,868 - trans - INFO - 大牛逼商城支付调用,用户cc支付1002016-06-12 13:04:47,828 - trans - INFO - cc调用支付接口,额度不足,支付失败2016-06-12 13:05:33,324 - trans - INFO - cc调用支付接口,额度不足,支付失败2016-06-12 16:28:34,212 - trans - INFO - 大牛逼商城支付调用,用户cc支付9002016-06-12 16:30:37,353 - trans - INFO - cc成功还款222016-06-12 16:30:52,169 - trans - INFO - cc成功提现3002016-06-12 16:31:19,328 - trans - INFO - cc向wyw成功转账52002016-06-15 13:08:31,554 - trans - INFO - 大牛逼商城支付调用,用户cc支付58882016-06-15 13:09:36,623 - trans - INFO - cc成功还款12000

  

你可能感兴趣的文章
一个简单的接口,被调用并同步给出响应的方法
查看>>
Hadoop序列化与压缩
查看>>
我的友情链接
查看>>
显式锁(第十三章)
查看>>
SCCM的证书配置PKI
查看>>
看linux书籍做的一些重要笔记(2011.07.03更新)
查看>>
CString、Char* ,char [20]、wchar_t、unsigned short转化
查看>>
从案例学RxAndroid开发(上)
查看>>
Redis学习手册(内存优化)
查看>>
浅尝TensorFlow on Kubernetes
查看>>
springboot系列十 Spring-Data-Redis
查看>>
Confluence 6 注册外部小工具
查看>>
excel进行矩阵计算
查看>>
基于Android平台的动态生成控件和动态改变控件位置的方法
查看>>
linux 死机分析
查看>>
BOM
查看>>
LeetCode:Nim Game - 尼姆博弈
查看>>
iOS: Block的循环引用
查看>>
mysql实战02 | 日志系统:一条SQL更新语句是如何执行的?
查看>>
ECC椭圆曲线详解(有具体实例)
查看>>