Day5作业,商城+ATM机+后台管理

Posted ccorz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Day5作业,商城+ATM机+后台管理相关的知识,希望对你有一定的参考价值。

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

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

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

商城图:

ATM后台管理:

ATM终端:

README:

1.测试帐号:
    商城测试帐号:cc/123   或者自己注册
    ATM 终端测试帐号:cc/123 alex/123 或者自己注册
    ATM 管理员测试帐号:admin/admin

2.需安装的第三方模块:prettytable

3.文件目录以及说明请看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.py

8.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 sys
sys.path.append(\'..\')
from core import atm_run

if 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 sys
sys.path.append(\'..\')
from core import manager_main
if 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 sys
sys.path.append(\'..\')
from core import shop_mall

shop_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,datetime
sys.path.append(\'..\')
from core import data_op,logger

dt=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 True

LOG_LEVEL=logging.DEBUG
LOG_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 sys
sys.path.append(\'..\')
from core import data_op,format_num,pass_handler
from 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))
                break


def 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))
                break


def 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,time
sys.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_rate



def 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:
        pass


if __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,time
sys.path.append(\'..\')
from core import terminal_op,data_op,format_num,veri_code,time_cal,\\
    generate_bills,terminal_discover_bills
from 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_stamp

def 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_stamp

def 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<time_cal.str_to_stamp(key)<=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 json
def l_d():
    """
    读 atm 用户数据库
    :return:
    """
    user_data=json.load(open(\'../db/atm_cart_db.json\',\'r\'))
    return user_data

def flush_d(args):
    """
    写入 ATM用户数据
    :param args:  新的用户数据
    :return:  True
    """
    json.dump(args,open(\'../db/atm_cart_db.json\',\'w\'),ensure_ascii=False,indent=1)
    return True

def 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/ccorzorz

def 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,time
sys.path.append(\'..\')
from core import terminal_op,data_op,format_num,veri_code,time_cal
from 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_contect


def 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 res




def 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,logging
sys.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,prettytable
sys.path.append(\'..\')
from core import atm_admin_op,generate_bills

def 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/ccorzorz

import hashlib

def 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 sys
sys.path.append(\'..\')
import json,prettytable,time,collections
from 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=None
user_name=None
balance=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)<len(e_cart):
            #变量赋值
            choice_num=int(choice_num)
            goods_stock=goods[e_cart[choice_num][2]][e_cart[choice_num][0]][\'stock\']
            p_amount=e_vcart[e_cart[choice_num]]
            balance=user_info[user_name][1]
            print(\'目前商品库存量为\\033[32;1m%s\\033[0m\'%goods_stock)
            while True:
                choice_num_d=input(\'输入要购买的商品数量:\')
                if choice_num_d.isdigit():
                    choice_num_d=int(choice_num_d)
                    if choice_num_d<=goods_stock:
                        if choice_num_d==p_amount:
                            print(\'修改商品数量成功\')
                            break
                        elif choice_num_d>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)<len(cla_list):
                                    #设置变量
                                    choice_cla_num=int(choice_cla_num)
                                    cla=cla_list[choice_cla_num]
                                    goods_list=list(goods[cla])     #取出对应的商品列表
                                    while break_flag==0:
                                        print(\'壕,您的预计账户余额为:\\033[31;1m%s\\033[0m\'%balance)
                                        row=prettytable.PrettyTable()
                                        row.field_names=[\'序列号\',\'商品名称\',\'商品价格\',\'商品库存\']
                                        for p in goods_list:
                                            p_num=goods_list.index(p)
                                            p_name=p
                                            p_price=goods[cla][p][\'price\']
                                            p_stock=goods[cla][p][\'stock\']
                                            row.add_row([p_num,p_name,p_price,p_stock])
                                        print(row)
                                        #用户选择物品编号
                                        choice_p_num=input(\'\\033[32;1m输入您要购买的商品序列号,返回商品分类请输入\'
                                                           \'b或back,查看购物车输入s,确认付款输入c,退出系统输入q或quit:\\033[0m\')
                                        if choice_p_num.isdigit() and int(choice_p_num)<len(goods_list):
                                            #定义变量
                                            p_name=goods_list[int(choice_p_num)]
                                            p_price=goods[cla][p_name][\'price\']
                                            p_stock=goods[cla][p_name][\'stock\']
                                            p_belong=goods[cla][p_name][\'belong\']
                                            while break_flag==0:
                                                p_count=input(\'\\033[32;1m输入您要购买的商品数量,直接回车系统默认数量默1:\\033[0m\')
                                                #判断库存
                                                if len(p_count)==0:
                                                    p_count=1
                                                elif p_count.isdigit():
                                                    if int(p_count) <= p_stock:
                                                        p_count = int(p_count)
                                                    else:
                                                        print(\'库存数量有限,最大购买数量为%s\' % p_stock)
                                                        break
                                                #余额大于商品总价
                                                # if balance >= 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,prettytable
sys.path.append(\'..\')
from core import terminal_op,data_op,format_num,veri_code,time_cal,generate_bills
from 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_list



def 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 sys
sys.path.append(\'..\')
from core import data_op,format_num,pass_handler
from 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 inner

def 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+=1

if __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,time
sys.path.append(\'..\')
from core import terminal_op,data_op,format_num,veri_code
from 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 False

if __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 sys
sys.path.append(\'..\')
from core import data_op,format_num
from 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,prettytable
sys.path.append(\'..\')
from core import data_op,format_num

def 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 sys
sys.path.append(\'..\')
from core import data_op,format_num,veri_code
from 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_nam

以上是关于Day5作业,商城+ATM机+后台管理的主要内容,如果未能解决你的问题,请参考以下文章

day5作业购物商城+ATM

Day5_作业

python基础作业------模拟实现一个ATM + 购物商城程序

atm

python- ATM与购物商城

python实现购物车+ATM机 部分功能