作业需求:

额度 15000或自定义。

实现购物商城,买东西加入 购物车,调用信用卡接口结账。

可以提现,手续费5%。

支持多账户登录。

支持账户间转账。

记录每月日常消费流水。

提供还款接口。

ATM记录操作日志。

提供管理接口,包括添加账户、用户额度,冻结账户等。。。

用户认证用装饰器。

 

思路:

1.  将用户名,密码,额度,锁,提现额度,等信用卡用户信息写入到字典。

2.  购物车程序请参照 python作业购物车(第二周)

3.  多用户登陆和转账,可以根据用户名生成不同的字典。

4.  其他请参照README和代码。

 

程序核心代码:

README:

作者:yaobin
版本:示例版本 v0.1 mmp版本  :(
程序介绍:

    实现ATM常用功能
    模拟实现一个ATM + 购物商城程序
    额度 15000或自定义
    实现购物商城,买东西加入 购物车,调用信用卡接口结账
    可以提现,手续费5%
    支持多账户登录
    支持账户间转账
    记录每月日常消费流水
    提供还款接口
    ATM记录操作日志
    提供管理接口,包括添加账户、用户额度,冻结账户等
    用户认证用装饰器
    开始先运行atm.py时执行程序,直接到main下,输入正确用户名密码,才能进行下一步的操作,然后列出atm的功能列表(还款、取款、转账、查看等)
    shopping是一个独立的程序,调用了信用卡充值金额的功能,购物结束后把剩余的金额在写入到文件中,存入到信用卡中。
    all是集合程序调用了所有模块

程序结构:
atm/
├── README
├── atm #ATM主程目录
│   ├── __init__.py
│   ├── bin  #ATM 执行文件目录
│   │   ├── __init__.py
│   │   ├── atm.py  #ATM 执行主程序
│   │   └── atm_manage.py #ATM 管理执行主程序
│   ├── conf #配置文件
│   │   ├── __init__.py
│   │   └── settings.py
│   ├── core #主要程序逻辑都在这个目录里
│   │   ├── __init__.py
│   │   ├── accounts.py  #ATM管理接口
│   │   ├── auth.py      #用户认证模块
│   │   ├── db_handler.py   #数据库连接引擎 -----///暂时没有做
│   │   ├── logger.py       #日志记录模块
│   │   ├── main.py         #ATM主逻辑交互程序
│   │   └── creditcard.py  #记账\还钱\取钱等所有的与账户金额相关的操作
│   │   └── manage.py   #ATM管理主逻辑交互称称程序
│   ├── db  #用户数据存储的地方
│   │   ├── __init__.py
│   │   └── accounts #存各个用户的账户数据 ,一个用户一个文件
│   │       └── 111111_creditcard_dict #用户账户示例文件
│   │       └── 111111_creditcard_record #用户账户记账\还钱\取钱等所有的与账户金额相关的操作示例文件
│   │       └── super_user_passwd #ATM管理接口账号认证文件
│   └── log #日志目录
│       ├── __init__.py
│       ├── access.log #用户访问和操作的相关日志
│       ├── transactions.log    #所有的用户的信用卡提现转账的交易日志
└── shopping #电子商城程序
            ├── shopping.py  #购物商城独立程序调用信用卡接口
            └── __init__.py
View Code

bin

  atm.py

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: Colin Yao
import os
import sys
# 添加环境变量
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASE_DIR)
from core import main
'''atm程序的执行文件'''

if __name__ == '__main__':
    main.center()
View Code

  atm_manage.py

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: Colin Yao
import os
import sys
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASE_DIR)
#添加环境变量
from core import manage
if __name__ == '__main__':
   manage.center()
View Code

conf

  setting.py

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: Colin Yao
#配置文件
import logging
import os,sys

BASE_DIR  = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASE_DIR) #添加环境变量

LOGIN_LEVEL = logging.INFO#定义日志的记录级别

#print(DATABASE)
#日志类型
LOGIN_TYPE={
    "access":"access.logs",
    "transaction":"transaction.logs"
}

# DATABASE = {
#     "db_tool":"file_storage",  #文件存储,这里可拓展成数据库形式的
#     "name":"accounts",         #db下的文件名
#     "user_path":"%s/src"%BASE_DIR
# }
#shopping
View Code

core

  accounts.py

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: Colin Yao
import os,sys,json,logging
"""ATM 信用卡后台manger_account 创建、锁定、提升额度"""
BASE_DIR  = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASE_DIR) #添加环境变量
import json,sys,os,logging,time,datetime
from core import auth
"""添加信用卡,冻结信用卡,提升信用卡额度"""

"""管理接口调用"""

"""添加信用卡账户"""
def issue():
    creditcard_user = input("需要添加发行的信用卡的用户:>>>:")
    personinfo_input = input("使用人>>>:")
    _db_creditcard_record = BASE_DIR + r"\db\accounts\%s_creditcard_dict" % creditcard_user
    _db_creditcard_record_bak = BASE_DIR + r"\db\accounts\%s_creditcard_dict_bak" % creditcard_user
    _db_creditcard_record1 = BASE_DIR + r"\db\accounts\%s_creditcard_record" % creditcard_user
    usertype = {
    creditcard_user:{
    "creditcard":creditcard_user,
    "personinfo":personinfo_input,
    "password":'123',#默认密码123
    "limit": float('15000'),#默认额度
    "deflimit":float('15000'),
    "limitcash":float("7500"),
    "locked":"0"
    }}
    creditcard_value= {creditcard_user:{ "":{ "":""}}} #初始化一个流水字典
    res = os.path.exists(_db_creditcard_record)
    if res == True:
        print("用户已经存在")
    else:
       f = open(_db_creditcard_record,'w',encoding='utf-8')
       list = json.dumps(usertype)
       f.write(list)
       f.close()
       f1 = open(_db_creditcard_record1,'w',encoding='utf-8')
       list1 = json.dumps(creditcard_value)
       f1.write(list1)
       f1.close()
       print("添加用户成功")

"""冻结账户"""

def frozen():
    creditcard_user = input("需要冻结发行的信用卡的用户:>>>:")
    _db_creditcard_record = BASE_DIR + r"\db\accounts\%s_creditcard_dict" % creditcard_user
    _db_creditcard_record_bak = BASE_DIR + r"\db\accounts\%s_creditcard_dict_bak" % creditcard_user
    res = os.path.exists(_db_creditcard_record)
    if res != True:
        print("用户不存在请重新输入存在")
    else:
        f = open(_db_creditcard_record, 'r', encoding='utf-8')
        list = json.loads(f.read())
        a = list[creditcard_user]["locked"]
        f.close()
        if a != '0':
            print("用户已经被冻结")
        else:
            f1 = open(_db_creditcard_record_bak, 'w', encoding='utf-8')
            list[creditcard_user]["locked"] = '1'
            dict = json.dumps(list)
            f1.write(dict)
            f1.close()
            os.remove(_db_creditcard_record)
            os.rename(_db_creditcard_record_bak, _db_creditcard_record)
            print("冻结成功信用为:%s" %creditcard_user)

"""提升信用卡额度"""

def promotion_quota():
    creditcard_user = input("需要提额的信用卡的用户:>>>:")
    _db_creditcard_record = BASE_DIR + r"\db\accounts\%s_creditcard_dict" %creditcard_user
    _db_creditcard_record_bak = BASE_DIR + r"\db\accounts\%s_creditcard_dict_bak" %creditcard_user
    res = os.path.exists(_db_creditcard_record)
    if res != True:
        print("用户不存在请重新输入存在")
    else:
        f = open(_db_creditcard_record, 'r', encoding='utf-8')

        list = json.loads(f.read())
        deflimit = list[creditcard_user]["deflimit"]
        print("现有额度为%s"%deflimit)
        def_creditcard_user_cash = input("请输入要提升的额度>>>:") #这里提升的额度为deflimit
        creditcard_limit = (int(def_creditcard_user_cash) -  int(deflimit) + int(list[creditcard_user]["limit"] ))          #固定额度减去提升的额度、加上现有额度、提升后的信用卡额度
        creditcard_limitcash = (int(list[creditcard_user]["limitcash"]) + ((int(def_creditcard_user_cash) -  int(deflimit))* 0.5))  #提升后的额度 - 原有的固定额度*0.5 + 现在的取现额度才是提升后的取现额度 :(  MMP!!!!!!!!!!!!!!!
        list[creditcard_user]["deflimit"] = def_creditcard_user_cash  #提升后的固定额度写入字典
        list[creditcard_user]["limit"] = creditcard_limit #提升固定额度后的信用卡额度写入字典
        list[creditcard_user]["limitcash"] = creditcard_limitcash #提升固定额度后的取现额度写入字典
        a = list[creditcard_user]["locked"]
        f.close()
        if a != '0':
            print("用户已经被冻结.不能提额")
        else:
            f1 = open(_db_creditcard_record_bak, 'w', encoding='utf-8')
            dict = json.dumps(list)
            f1.write(dict)
            f1.close()
            os.remove(_db_creditcard_record)
            os.rename(_db_creditcard_record_bak, _db_creditcard_record)
            print("成功提升信用额度为:%s 提额后的现有额度:%s 提升后的取现额度 %s " % (
            def_creditcard_user_cash, creditcard_limit, creditcard_limitcash))
View Code

  auth.py 

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: Colin Yao
import os,sys,json
BASE_DIR  = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASE_DIR) #添加环境变量
super_user_passwd = BASE_DIR + r"\db\accounts\super_user_passwd"
from core import logger
def auth(auth_type):
    """超级用户后台管理认证接口"""
    def outer_wrapper(func):
        if auth_type =="admincenter_auth":
            def wrapper():
                res = func()
                super_user = input("请输入后台管理员账号>>>>:")
                super_passwd = input("请输入后台管理员密码>>>>:")
                with  open(super_user_passwd, 'r', encoding='utf-8') as f:
                    (id, user, passwd) = f.readline().strip().split(',')
                if user == super_user and passwd == super_passwd:
                    print("welcome %s" %super_user)
                    return res,super_user
                else:
                    log_obj = logger.log('access')
                    log_obj.error("不正确的密码 %s" % super_user)
                    print("用户名或密码输入有误程序退出")
                    sys.exit()
            return wrapper

        """商城用户登录认证"""
        if auth_type == "user_auth":
            def wrapper():
                res = func()
                shopping_user = input("请输入用户名>>>>:")
                shopping_passwd = input("请输入密码>>>>:")
                print("功能后面在加入")
                # with  open(super_user_passwd, 'r', encoding='utf-8') as f:
                #     f.readlines()

            return wrapper
        if auth_type == "creditcard_auth":
            def wrapper():
                log_obj = logger.log('access')
                res = func()
                creditcard_user = input("请输入信用卡账号>>>>:")  # 信用卡账号
                creditcard_passwd = input("请输入信用卡密码>>>>:")  # 信用卡密码
                _creditcard_passwd = BASE_DIR + r"\db\accounts\%s_creditcard_dict" % creditcard_user
                res = os.path.exists(_creditcard_passwd)
                if res == True:
                    if len(creditcard_user.strip()) > 0:
                        with open(_creditcard_passwd, 'r', encoding='utf-8') as f:
                            list = json.loads(f.read())
                            if creditcard_user in list.keys():  # 用户在key中、用户唯一
                                if creditcard_passwd == list[creditcard_user]["password"]:  # 读取字典中用户和key的值
                                    if list[creditcard_user]["locked"] == '0':  # 如果用户的lock 为0 证明是没有锁定的账户为1 是锁定状态
                                        print("信用卡认证成功 welcome %s" % creditcard_user)
                                        return res,creditcard_user
                                    else:
                                        print("信用卡被冻结用户%s请您联系用户中心 WEB:扯淡.com  TEL: 100000" % creditcard_user)
                                        log_obj.error("%s is locked" % creditcard_user)
                                        sys.exit()
                                else:
                                    print("信用卡用户:%s 密码输入有误认证失败" % creditcard_user)
                                    log_obj.error("%s wrong shopping_db " % creditcard_user)
                                    sys.exit()
                            else:
                                sys.exit()
                    else:
                        sys.exit()
                else:
                    print("不存在此信用卡用户%s" % creditcard_user)
                    log_obj.error("%s wrong username" % creditcard_user)
                    sys.exit()
            return wrapper
    return outer_wrapper

"""装饰器添加print语句并带有色彩"""

'''后台管理认证'''
@auth(auth_type="user_auth")
def user_auth():
    print("\33[32;0m用户登录认证\33[0m".center(40,"-"))
    return "True"

'''信用卡认证'''
@auth(auth_type="creditcard_auth")
def creditcard_auth():
    print("\33[32;0m信用卡登录认证\33[0m".center(40,"-"))
    return "True"

'''后台管理认证'''
@auth(auth_type="admincenter_auth")
def admincenter_auth():
    print("\33[32;0m后台管理登录认证\33[0m".center(40,"-"))
    return "True"
View Code

  logger.py

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: Colin Yao
import  os,sys,json,datetime,time,logging

BASE_DIR  = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASE_DIR) #添加环境变量

from conf import settings
from core import db_handler

def log(logging_type):
    """
      main模块调用access_logger = logs.logs("access")
     :param logging_type: "access"
     return: 返回logger日志对象
    """
    logger=logging.getLogger(logging_type)  #传日志用例,生成日志对象
    logger.setLevel(settings.LOGIN_LEVEL)   #设置日志级别

    ch = logging.StreamHandler()     #日志打印到屏幕,获取对象
    ch.setLevel(settings.LOGIN_LEVEL)

    # 获取文件日志对象及日志文件
    log_file="%s/logs/%s"%(settings.BASE_DIR,settings.LOGIN_TYPE[logging_type])
    #log_file = "%s\logs\%s" % (BASE_DIR, settings.LOGIN_TYPE[logging_type])
    fh = logging.FileHandler(log_file)
    fh.setLevel(settings.LOGIN_LEVEL)

    # 日志格式
    formatter=logging.Formatter("%(asctime)s-%(name)s-%(levelname)s-%(message)s")

    # 输出格式
    ch.setFormatter(formatter)
    fh.setFormatter(formatter)

    #把日志打印到指定的handler
    logger.addHandler(ch)
    logger.addHandler(fh)

    return logger    #log方法返回logger对象
View Code

  main.py 

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: Colin Yao
import os,sys,logging,json
BASE_DIR  = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASE_DIR) #添加环境变量
from core import logger
from core import auth
from core import creditcard

def center():
    msg = '''
        \33[34;0m
        [1]我的信用卡
        [2]信用卡流水记录
        [3]提现
        [4]转账
        [5]还款
        [6]退出按q 即可
        \33[0m
        '''
    print("欢迎进入信用卡ATM中心请输入账号名密码进行认证")
    res = auth.creditcard_auth()
    creditcard_user = res[1]
    while True:
        print(msg)
        choice_id = input("请选择您需要的服务>>>:")
        if choice_id == "1":
            creditcard.my_creditcard(creditcard_user)
        elif choice_id == "2":
            creditcard.see(creditcard_user)
        elif choice_id == "3":
            creditcard.withdrawals(creditcard_user)
        elif choice_id == "4":
            creditcard.transfer_accounts(creditcard_user)
        elif choice_id == "5":
            creditcard.repayment(creditcard_user)
        elif choice_id == "6" or choice_id == "q":
            print("Bye %s" % creditcard_user)
            sys.exit()
        else:
            print("输入有误请重新输入")
center()
View Code

  creditcard.py

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: Colin Yao
import json,sys,os,logging,time,datetime
BASE_DIR  = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASE_DIR) #添加环境变量
from core import auth
from core import logger
log_obj = logger.log('transaction')

"""用户接口调用"""

"""我的信用卡信息"""

def my_creditcard(creditcard_user):
    while True:
        _db_creditcard_record = BASE_DIR + r"\db\accounts\%s_creditcard_dict" % creditcard_user
        print("\33[32;0m我的信用卡信息\33[0m".center(40, "-"))
        with open(_db_creditcard_record, 'r', encoding='utf-8') as f:
            list = json.loads(f.read())
            #print(list)
            #print(list[creditcard_user]["limit"])
            print("卡号:\t[%s]\n额度:\t[¥%s]\n取现额度:\t[¥%s]\n持卡人:\t[%s]\n" %(creditcard_user,list[creditcard_user]["limit"],list[creditcard_user]["limitcash"],list[creditcard_user]["personinfo"]))
        if_back = input("\33[34;0m是否退出 返回[b]\33[0m:")
        if if_back == "b":
            break
"""信用卡流水记录"""

def flow(creditcard_user,value):
    _db_creditcard_record = BASE_DIR + r"\db\accounts\%s_creditcard_record" %creditcard_user
    with open(_db_creditcard_record, "r+",encoding='utf-8') as f:
        list = json.loads(f.read())
        month = time.strftime('%Y-%m-%d', time.localtime())
        times = time.strftime("%H:%M:%S")
        if str(creditcard_user) not in list.keys():
            list[creditcard_user] = {month: {times: value}}
            print(list[creditcard_user])
        else:
            if month not in list[creditcard_user].keys():
                list[creditcard_user][month] = {times: value}
            else:
                list[creditcard_user][month][times] = value
        """value类似还款转账"""
        dict = json.dumps(list)
        f.seek(0)
        f.truncate(0)
        f.write(dict)

"""查看信用卡流水"""

def see(creditcard_user):
  while True:
      _db_creditcard_record = BASE_DIR + r"\db\accounts\%s_creditcard_record" % creditcard_user
      with open(_db_creditcard_record, "r+", encoding='utf-8') as f:
          list = json.loads(f.read())
          if creditcard_user in list.keys():
              for key in list[creditcard_user]:
                  print("消费日期为>>>:", key)
              date = input("\n\33[34;0m流水查询 返回[b] / 输入消费的日期既可以查询[2000-01-01]\33[0m:")
              if date == 'b':
                  break
                  pass
              if date in list[creditcard_user].keys():
                  keys = sorted(list[creditcard_user][date])
                  print("\33[31;1m当前信用卡[%s] 交易记录>>>\33[0m" % (creditcard_user))
                  for key in keys:
                      print("\33[31;1m时间>>>:%s  %s\33[0m" % (key, list[creditcard_user][date][key]))
                  print("")
              else:
                  print("\33[31;0m输入的日期有误\33[0m\n")
          else:
              print("\33[31;0m信用卡 %s 还没有进行过消费\33[0m\n" % (creditcard_user))
              break

"""提现"""
def withdrawals(creditcard_user):
    _db_creditcard_record = BASE_DIR + r"\db\accounts\%s_creditcard_dict" % creditcard_user
    _db_creditcard_record_bak = BASE_DIR + r"\db\accounts\%s_creditcard_dict_bak" % creditcard_user
    limit_input = input("请输入提现金额>>>:")
    f = open(_db_creditcard_record, "r", encoding='utf-8')
    list=json.loads(f.read())
    cash_limit = list[creditcard_user]["limitcash"]  #能提现的额度
    limit = list[creditcard_user]["limit"] #当前额度
    interest = (int(limit_input) * 0.05)
    new_limit = (limit - int(limit_input)-interest)  #当前额度-提现金额-利息等于现在的额度
    print("现在取款的金额", limit_input)
    print("当前额度", limit)
    print("利息", interest)
    print("取现后的额度", new_limit)
    if cash_limit >= int(limit_input):  # 当取现额度大于等于取现金额的时候
        if cash_limit >= int(limit_input):  # 当取现额度大于等于取现金额的时候
            list[creditcard_user]["limit"] = new_limit
            f.close()
            f1 = open(_db_creditcard_record_bak, "w", encoding='utf-8')
            f1.seek(0)
            f1.truncate(0)
            dict = json.dumps(list)
            f1.write(dict)
            f1.close()
            os.remove(_db_creditcard_record)
            os.rename(_db_creditcard_record_bak, _db_creditcard_record)
            value = "\33[31;1m信用卡用户:%s取现金额:¥%s 成功\33[0m" % (creditcard_user, limit_input)
            value1 = "\33[31;1m信用卡利息:¥%s 现在额度为:¥%s \33[0m" % (interest, new_limit)
            print(value, value1, "\n")
            log_obj.info(
                "account:%s cash:%s limit:%s interest:%s OK" % (creditcard_user, limit_input, new_limit, interest))
            flow(creditcard_user, value)
        else:
            print("输入有误重新输入")
    else:
        print("提款金额大于默认提款额度了,You Can 联系后台中心提升提款额度")
    return limit_input

"""转账"""
def transfer_accounts(creditcard_user):
    _db_creditcard_record = BASE_DIR + r"\db\accounts\%s_creditcard_dict" % creditcard_user
    _db_creditcard_record_bak = BASE_DIR + r"\db\accounts\%s_creditcard_dict_bak" % creditcard_user
    while True:
        print("\33[32;0m转账\33[0m".center(40, "-"))
        if_trans = input("\n\33[34;0m是否进行转账 确定[y]/返回[b]\33[0m:")
        if if_trans == "y":
            transfer_input = input("请输入需要转账的账户>>>:")
            #transfer_input = '222222'
            _db_creditcard_record_transfer = BASE_DIR + r"\db\accounts\%s_creditcard_dict" %transfer_input
            _db_creditcard_record_bak_transfer = BASE_DIR + r"\db\accounts\%s_creditcard_dict_bak" %transfer_input
            transfer_cash_input = input("请输入需要转账的金额>>>:")#输入转出的金额
            #transfer_cash_input = '1000'
            f = open(_db_creditcard_record, "r", encoding='utf-8') #首先先确认这个金额是否超过额度,如果超过额度那么不能转账
            list = json.loads(f.read())  #
            limit = list[creditcard_user]["limit"]
            print("现在的额度%s 可转账金额%s" %(limit,limit))
            print("转账金额%s" %transfer_cash_input)
            if int(transfer_cash_input) <= limit:
                #用当前信用卡额度转账金额  limit - transfer_cache_input
                new_limit = (limit - int(transfer_cash_input))
                print("信用卡转账后的额度%s"%new_limit) #处理自己的额度然后处理转账账户的额度
                list[creditcard_user]["limit"] = new_limit
                f.close()
                f1 = open(_db_creditcard_record_bak, "w", encoding='utf-8')
                f1.seek(0)
                f1.truncate(0)
                dict = json.dumps(list)
                f1.write(dict)
                f1.close()
                os.remove(_db_creditcard_record)
                os.rename(_db_creditcard_record_bak,_db_creditcard_record)
                value = "\33[31;1m信用卡 %s 转账金额 ¥%s 转账成功\33[0m" % (creditcard_user,transfer_cash_input)
                print(value, "\n")
                log_obj.info("account:%s transfer_account:%s  cash:%s limit:%s OK" %(creditcard_user,transfer_input,transfer_cash_input,new_limit,))
            else:
                print("还款额大于默认额度了,可以联系后台中心提升默认额度")
            flow(creditcard_user, value)
            #处理对方账户的金额
            if transfer_input in _db_creditcard_record_transfer:
                f2 = open(_db_creditcard_record_transfer, "r", encoding='utf-8')  # 打开转账用户的文件
                list1 = json.loads(f2.read())  #
                limit2 = list1[transfer_input]["limit"]  #对方的信用卡额度
                new_limit1 = (limit2 + int(transfer_cash_input)) #准备增加对方信用卡额度
                list1[transfer_input]["limit"] = new_limit1
                f2.close()
                f3 = open(_db_creditcard_record_bak_transfer, "w", encoding='utf-8')
                f3.seek(0)
                f3.truncate(0)
                dict1 = json.dumps(list1)
                print()
                f3.write(dict1)
                f3.close()
                os.remove(_db_creditcard_record_transfer)
                os.rename(_db_creditcard_record_bak_transfer, _db_creditcard_record_transfer)
        if if_trans == "b":
            break

"""还款"""
def repayment(creditcard_user):
    _db_creditcard_record = BASE_DIR + r"\db\accounts\%s_creditcard_dict" % creditcard_user
    _db_creditcard_record_bak = BASE_DIR + r"\db\accounts\%s_creditcard_dict_bak" % creditcard_user
    limit_input = input("请输入还款金额>>>:")
    f = open(_db_creditcard_record, "r", encoding='utf-8')
    list=json.loads(f.read())
    limit = list[creditcard_user]["limit"]
    deflimit = list[creditcard_user]["deflimit"]
    new_limit = (limit + int(limit_input))
    if int(new_limit) <= int(deflimit):
        list[creditcard_user]["limit"] = new_limit
        f.close()
        f1 = open(_db_creditcard_record_bak, "w", encoding='utf-8')
        f1.seek(0)
        f1.truncate(0)
        dict = json.dumps(list)
        f1.write(dict)
        f1.close()
        os.remove(_db_creditcard_record)
        os.rename(_db_creditcard_record_bak,_db_creditcard_record)
        value = "\33[31;1m信用卡 %s 还款金额 ¥%s 还款成功\33[0m" % (creditcard_user, limit_input)
        log_obj.info("account:%s repayment:%s limit:%s OK" % (creditcard_user, limit_input, new_limit))
        print(value, "\n")
        flow(creditcard_user, value)
    else:
        print("还款额大于默认额度了,可以联系后台中心提升默认额度")
        pass
View Code

  manage.py 

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: Colin Yao
"""#ATM管理接口"""
import os,sys
BASE_DIR  = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASE_DIR) #添加环境变量
from core import auth
from core import accounts
from core import creditcard
from conf import settings


"""输入账号密码创建超级用户"""

msg =  '''
\33[34;0m
欢迎进入ATM后台管理接口

[1] 添加信用卡
[2] 冻结信用卡
[3] 提升信用卡额度
[4] 退出
\33[0m
'''

"""输入用户选择调用account模块"""

def user_choice():
    while True:
        print(msg)
        user_choice = input("请输入模式进行操作>>>:")
        if user_choice == '1':
            # 调用account模块的issue函数添加用户
            accounts.issue()
        elif user_choice == '2':
            # 调用account模块的fozen函数锁定用户
            accounts.frozen()
        elif user_choice == '3':
            # 调用account模块的un_lock函数解锁用户
            accounts.promotion_quota()
        elif user_choice == '4' or user_choice == 'q':
            sys.exit()
        else:
            print("输入有误,程序退出")
            sys.exit()
"""程序入口"""
def manage():
    auth.admincenter_auth() # 调用用户认证auth模块中manger函数1 默认账户密码admin shopping_db
    user_choice()
manage()
View Code

db

  111111_creditcard_dict

{"111111": {"personinfo": "\u5929\u68da\u5143\u5e05", "password": "123", "limit": 19214.300000000007, "locked": "0", "limitcash": 30000.0, "deflimit": "60000", "creditcard": "111111"}}
View Code

  111111_creditcard_record

{"111111": {"": {"": ""}, "2017-10-15": {"20:31:14": "\u001b[31;1m\u4fe1\u7528\u5361\u7528\u6237:111111\u53d6\u73b0\u91d1\u989d:\u00a51000 \u6210\u529f\u001b[0m"}, "2017-10-16": {"00:45:55": "\u001b[31;1m\u4fe1\u7528\u5361 111111 \u8f6c\u8d26\u91d1\u989d \u00a520 \u8f6c\u8d26\u6210\u529f\u001b[0m", "00:47:35": "\u001b[31;1m\u4fe1\u7528\u5361 111111 \u8f6c\u8d26\u91d1\u989d \u00a520 \u8f6c\u8d26\u6210\u529f\u001b[0m", "00:51:31": "\u001b[31;1m\u4fe1\u7528\u5361 111111 \u8fd8\u6b3e\u91d1\u989d \u00a5200 \u8fd8\u6b3e\u6210\u529f\u001b[0m", "03:20:03": "\u001b[31;1m\u4fe1\u7528\u5361\u7528\u6237:111111\u53d6\u73b0\u91d1\u989d:\u00a510 \u6210\u529f\u001b[0m", "03:20:59": "\u001b[31;1m\u4fe1\u7528\u5361\u7528\u6237:111111\u53d6\u73b0\u91d1\u989d:\u00a530 \u6210\u529f\u001b[0m", "03:26:22": "\u001b[31;1m\u4fe1\u7528\u5361 111111 \u8f6c\u8d26\u91d1\u989d \u00a5200 \u8f6c\u8d26\u6210\u529f\u001b[0m", "03:28:03": "\u001b[31;1m\u4fe1\u7528\u5361 111111 \u8fd8\u6b3e\u91d1\u989d \u00a5200 \u8fd8\u6b3e\u6210\u529f\u001b[0m", "12:49:57": "\u001b[31;1m\u4fe1\u7528\u5361\u7528\u6237:111111\u53d6\u73b0\u91d1\u989d:\u00a5200 \u6210\u529f\u001b[0m", "15:22:13": "\u001b[31;1m\u4fe1\u7528\u5361\u7528\u6237:111111\u53d6\u73b0\u91d1\u989d:\u00a55299 \u6210\u529f\u001b[0m", "15:26:02": "\u001b[31;1m\u4fe1\u7528\u5361\u7528\u6237:111111\u53d6\u73b0\u91d1\u989d:\u00a55299 \u6210\u529f\u001b[0m", "15:26:03": "\u001b[31;1m\u4fe1\u7528\u5361\u7528\u6237:111111\u53d6\u73b0\u91d1\u989d:\u00a55299 \u6210\u529f\u001b[0m", "15:26:04": "\u001b[31;1m\u4fe1\u7528\u5361\u7528\u6237:111111\u53d6\u73b0\u91d1\u989d:\u00a55299 \u6210\u529f\u001b[0m", "15:26:05": "\u001b[31;1m\u4fe1\u7528\u5361\u7528\u6237:111111\u53d6\u73b0\u91d1\u989d:\u00a55299 \u6210\u529f\u001b[0m", "15:26:06": "\u001b[31;1m\u4fe1\u7528\u5361\u7528\u6237:111111\u53d6\u73b0\u91d1\u989d:\u00a55299 \u6210\u529f\u001b[0m", "15:26:07": "\u001b[31;1m\u4fe1\u7528\u5361\u7528\u6237:111111\u53d6\u73b0\u91d1\u989d:\u00a55299 \u6210\u529f\u001b[0m", "15:26:08": "\u001b[31;1m\u4fe1\u7528\u5361\u7528\u6237:111111\u53d6\u73b0\u91d1\u989d:\u00a55299 \u6210\u529f\u001b[0m", "15:26:09": "\u001b[31;1m\u4fe1\u7528\u5361\u7528\u6237:111111\u53d6\u73b0\u91d1\u989d:\u00a55299 \u6210\u529f\u001b[0m", "15:26:10": "\u001b[31;1m\u4fe1\u7528\u5361\u7528\u6237:111111\u53d6\u73b0\u91d1\u989d:\u00a55299 \u6210\u529f\u001b[0m", "15:26:11": "\u001b[31;1m\u4fe1\u7528\u5361\u7528\u6237:111111\u53d6\u73b0\u91d1\u989d:\u00a55299 \u6210\u529f\u001b[0m", "15:26:12": "\u001b[31;1m\u4fe1\u7528\u5361\u7528\u6237:111111\u53d6\u73b0\u91d1\u989d:\u00a55299 \u6210\u529f\u001b[0m", "15:26:13": "\u001b[31;1m\u4fe1\u7528\u5361\u7528\u6237:111111\u53d6\u73b0\u91d1\u989d:\u00a55299 \u6210\u529f\u001b[0m", "15:26:14": "\u001b[31;1m\u4fe1\u7528\u5361\u7528\u6237:111111\u53d6\u73b0\u91d1\u989d:\u00a55299 \u6210\u529f\u001b[0m", "15:26:15": "\u001b[31;1m\u4fe1\u7528\u5361\u7528\u6237:111111\u53d6\u73b0\u91d1\u989d:\u00a55299 \u6210\u529f\u001b[0m", "15:26:16": "\u001b[31;1m\u4fe1\u7528\u5361\u7528\u6237:111111\u53d6\u73b0\u91d1\u989d:\u00a55299 \u6210\u529f\u001b[0m", "15:26:17": "\u001b[31;1m\u4fe1\u7528\u5361\u7528\u6237:111111\u53d6\u73b0\u91d1\u989d:\u00a55299 \u6210\u529f\u001b[0m", "15:26:18": "\u001b[31;1m\u4fe1\u7528\u5361\u7528\u6237:111111\u53d6\u73b0\u91d1\u989d:\u00a55299 \u6210\u529f\u001b[0m", "15:26:19": "\u001b[31;1m\u4fe1\u7528\u5361\u7528\u6237:111111\u53d6\u73b0\u91d1\u989d:\u00a55299 \u6210\u529f\u001b[0m", "15:26:20": "\u001b[31;1m\u4fe1\u7528\u5361\u7528\u6237:111111\u53d6\u73b0\u91d1\u989d:\u00a55299 \u6210\u529f\u001b[0m", "15:26:21": "\u001b[31;1m\u4fe1\u7528\u5361\u7528\u6237:111111\u53d6\u73b0\u91d1\u989d:\u00a55299 \u6210\u529f\u001b[0m", "15:26:22": "\u001b[31;1m\u4fe1\u7528\u5361\u7528\u6237:111111\u53d6\u73b0\u91d1\u989d:\u00a55299 \u6210\u529f\u001b[0m", "15:26:23": "\u001b[31;1m\u4fe1\u7528\u5361\u7528\u6237:111111\u53d6\u73b0\u91d1\u989d:\u00a55299 \u6210\u529f\u001b[0m", "15:26:24": "\u001b[31;1m\u4fe1\u7528\u5361\u7528\u6237:111111\u53d6\u73b0\u91d1\u989d:\u00a55299 \u6210\u529f\u001b[0m", "15:26:25": "\u001b[31;1m\u4fe1\u7528\u5361\u7528\u6237:111111\u53d6\u73b0\u91d1\u989d:\u00a55299 \u6210\u529f\u001b[0m", "15:26:26": "\u001b[31;1m\u4fe1\u7528\u5361\u7528\u6237:111111\u53d6\u73b0\u91d1\u989d:\u00a55299 \u6210\u529f\u001b[0m", "15:26:27": "\u001b[31;1m\u4fe1\u7528\u5361\u7528\u6237:111111\u53d6\u73b0\u91d1\u989d:\u00a55299 \u6210\u529f\u001b[0m", "15:26:28": "\u001b[31;1m\u4fe1\u7528\u5361\u7528\u6237:111111\u53d6\u73b0\u91d1\u989d:\u00a55299 \u6210\u529f\u001b[0m", "15:26:29": "\u001b[31;1m\u4fe1\u7528\u5361\u7528\u6237:111111\u53d6\u73b0\u91d1\u989d:\u00a55299 \u6210\u529f\u001b[0m", "15:26:30": "\u001b[31;1m\u4fe1\u7528\u5361\u7528\u6237:111111\u53d6\u73b0\u91d1\u989d:\u00a55299 \u6210\u529f\u001b[0m", "15:26:31": "\u001b[31;1m\u4fe1\u7528\u5361\u7528\u6237:111111\u53d6\u73b0\u91d1\u989d:\u00a55299 \u6210\u529f\u001b[0m", "15:26:32": "\u001b[31;1m\u4fe1\u7528\u5361\u7528\u6237:111111\u53d6\u73b0\u91d1\u989d:\u00a55299 \u6210\u529f\u001b[0m", "15:26:33": "\u001b[31;1m\u4fe1\u7528\u5361\u7528\u6237:111111\u53d6\u73b0\u91d1\u989d:\u00a55299 \u6210\u529f\u001b[0m", "15:26:34": "\u001b[31;1m\u4fe1\u7528\u5361\u7528\u6237:111111\u53d6\u73b0\u91d1\u989d:\u00a55299 \u6210\u529f\u001b[0m", "15:26:35": "\u001b[31;1m\u4fe1\u7528\u5361\u7528\u6237:111111\u53d6\u73b0\u91d1\u989d:\u00a55299 \u6210\u529f\u001b[0m", "15:26:36": "\u001b[31;1m\u4fe1\u7528\u5361\u7528\u6237:111111\u53d6\u73b0\u91d1\u989d:\u00a55299 \u6210\u529f\u001b[0m", "15:26:37": "\u001b[31;1m\u4fe1\u7528\u5361\u7528\u6237:111111\u53d6\u73b0\u91d1\u989d:\u00a55299 \u6210\u529f\u001b[0m", "15:26:38": "\u001b[31;1m\u4fe1\u7528\u5361\u7528\u6237:111111\u53d6\u73b0\u91d1\u989d:\u00a55299 \u6210\u529f\u001b[0m", "15:26:39": "\u001b[31;1m\u4fe1\u7528\u5361\u7528\u6237:111111\u53d6\u73b0\u91d1\u989d:\u00a55299 \u6210\u529f\u001b[0m", "15:26:40": "\u001b[31;1m\u4fe1\u7528\u5361\u7528\u6237:111111\u53d6\u73b0\u91d1\u989d:\u00a55299 \u6210\u529f\u001b[0m", "15:27:24": "\u001b[31;1m\u4fe1\u7528\u5361\u7528\u6237:111111\u53d6\u73b0\u91d1\u989d:\u00a55299 \u6210\u529f\u001b[0m", "15:28:41": "\u001b[31;1m\u4fe1\u7528\u5361\u7528\u6237:111111\u53d6\u73b0\u91d1\u989d:\u00a55299 \u6210\u529f\u001b[0m", "15:29:36": "\u001b[31;1m\u4fe1\u7528\u5361\u7528\u6237:111111\u53d6\u73b0\u91d1\u989d:\u00a55299 \u6210\u529f\u001b[0m", "15:30:49": "\u001b[31;1m\u4fe1\u7528\u5361\u7528\u6237:111111\u53d6\u73b0\u91d1\u989d:\u00a55299 \u6210\u529f\u001b[0m", "15:38:30": "\u001b[31;1m\u4fe1\u7528\u5361\u7528\u6237:111111\u53d6\u73b0\u91d1\u989d:\u00a5200 \u6210\u529f\u001b[0m", "15:38:41": "\u001b[31;1m\u4fe1\u7528\u5361 111111 \u8f6c\u8d26\u91d1\u989d \u00a5100 \u8f6c\u8d26\u6210\u529f\u001b[0m", "15:38:54": "\u001b[31;1m\u4fe1\u7528\u5361 111111 \u8fd8\u6b3e\u91d1\u989d \u00a53000 \u8fd8\u6b3e\u6210\u529f\u001b[0m"}}}
View Code

  super_user_passwd

1,admin,passwd
View Code

  shoppingdb

�}q (X   test1q}q(X   usernameqhX
   userpasswdqX   123456qX   salaryqX    qX   shop_carqhX
   shop_car_listq    huX   testq
}q(hh
hX   abcdqhhhhh    huX   colinq
}q(X   usernameqh
X
   userpasswdqX   123456qX   salaryqM��X   shop_carq]q(X   IPoneqM��qX   Mac ProqM�.�qX   LG显示器23.6qMQ�qX   MI盒子qKdžqX       Iphone 6sqM��qeX
   shop_car_listq]q (KKKKKeuX   123q!}q"(X   usernameq#h!X
   userpasswdq$X   123q%X   salaryq&J�� X   shop_carq']q(X       Iphone 6sq)M��q*aX
   shop_car_listq+]q,KauX   colinyaoq-}q.(X   usernameq/h-X
   userpasswdq0X   123456q1X   salaryq2MpX   shop_carq3hX
   shop_car_listq4huX   aaaaaaaaaaaaq5}q6(X   usernameq7h5X
   userpasswdq8X   123q9X   salaryq:hX   shop_carq;hX
   shop_car_listq<huX   yyyq=}q>(X   usernameq?h=X
   userpasswdq@X   yyyqAX   salaryqBhX   shop_carqChX
   shop_car_listqDhuu.
View Code

logs

  access.log

2017-10-16 03:10:31,037-access-ERROR-wrong passwd 111111
2017-10-16 03:11:19,717-access-ERROR-����ȷ������ 111111
2017-10-16 03:40:22,661-access-ERROR-111111 wrong passwd retry
2017-10-16 03:42:55,245-access-ERROR-111123123 wrong user retry
2017-10-16 03:43:34,413-access-ERROR-asdjasdlkashdkjasd wrong username
2017-10-16 03:43:59,117-access-ERROR-111111 wrong passwd 
2017-10-16 03:44:20,045-access-ERROR-222222 is locked
2017-10-16 03:44:34,733-access-ERROR- wrong username
2017-10-16 03:46:00,341-access-ERROR-111123123 wrong username
2017-10-16 03:46:06,468-access-ERROR-123456 wrong username
2017-10-16 03:48:28,781-access-ERROR-2 wrong username
2017-10-16 03:48:28,781-access-ERROR-2 wrong username
2017-10-16 03:55:18,773-access-ERROR-111111 wrong passwd 
2017-10-16 04:02:14,653-access-ERROR-����ȷ������ admin
2017-10-16 12:49:15,293-access-ERROR-222222 is locked
2017-10-16 15:21:19,283-access-ERROR-222222 is locked
2017-10-16 15:25:36,922-access-ERROR-222222 is locked
2017-10-18 17:46:30,207-access-ERROR-222222 is locked
2017-10-19 13:46:24,582-access-ERROR-222222 is locked
View Code

  transactions.log  

2017-10-16 03:20:59,584-transaction-INFO-account:111111 cash:30 limit:50118.0 interest:1.5
2017-10-16 03:26:22,568-transaction-INFO-account:111111 transfer_account:222222  cash:200 limit:49918.0 
2017-10-16 03:28:03,265-transaction-INFO-account:111111 repayment:200 limit:50118.0 OK
2017-10-16 12:49:57,063-transaction-INFO-account:111111 cash:200 limit:49908.0 interest:10.0 OK
2017-10-16 15:22:13,998-transaction-INFO-account:111111 cash:5299 limit:44344.05 interest:264.95 OK
2017-10-16 15:26:02,381-transaction-INFO-account:111111 cash:5299 limit:38780.100000000006 interest:264.95 OK
2017-10-16 15:26:02,386-transaction-INFO-account:111111 cash:5299 limit:38780.100000000006 interest:264.95 OK
2017-10-16 15:26:02,390-transaction-INFO-account:111111 cash:5299 limit:38780.100000000006 interest:264.95 OK
2017-10-16 15:26:02,394-transaction-INFO-account:111111 cash:5299 limit:38780.100000000006 interest:264.95 OK
2017-10-16 15:26:02,398-transaction-INFO-account:111111 cash:5299 limit:38780.100000000006 interest:264.95 OK
View Code

shopping

  shopping.py

# -*- coding: utf-8 -*-
import pickle,os,sys,json
BASE_DIR  = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASE_DIR) #添加环境变量
_db_shopping_record = BASE_DIR + r"\db\accounts\shopping_db"
_db_shopping_cache = BASE_DIR + r"\db\accounts\shopping_cache"
from core import auth,creditcard
from conf import settings

product_list = [
        ('Iphone 6s', 5299),
        ('Iphone 6s Plus', 5999),
        ('Sumsung s7', 3888),
        ('Sumsung s7 Edge', 5688),
        ('360 F4 ', 799),
        ('红米Note3 ', 899),
        ('魅族 MX6', 1999),
        ('华为 Mate', 2799),
    ]


f = open(_db_shopping_record, 'rb')
user_list = pickle.load(f)
f.close()

def wirte_logout():
    f = open(_db_shopping_record, 'wb')
    pickle.dump(user_list, f)
    f.close()
    return

def index_page():
    page = '''

[0]登录 [1]注册 [2]浏览

'''
    print('\n', '手机商城测试页面'.center(60, '-'),page)
    return


def login():
    print('\n')
    global user
    count = 1
    for i in range(5):
        if count <= 3:
            user = input('用户登录: ')
            password = input('密 码: ')
            if user in user_list.keys():
                if user == user_list[user]['username'] and password == user_list[user]['userpasswd']:
                    print("欢迎%s光临"%user)
                    return user
                    print(msg)
                    break
                else:
                    print('用户名或密码不正确,请重新登录!')
            else:
                user_choice = input('用户不存在,是否需要注册(y/n)')
                if user_choice == 'y':
                    add_user()
                    break
                elif user_choice == 'n':
                    pass
            count += 1
        elif count > 3:
            exit('超出登录次数!登录失败')
    return


def add_user():
    global user
    exit_flag = False
    print('\n')
    while not exit_flag:
        username = input('请输入你的用户名:')
        if username in user_list.keys():
            print('\n用户名已存在,请输入其他名称\n')
        else:
            exit_flag = True
    userpasswd = input('请输入你的密码')
    user_list[username] = {}
    user_list[username]['username'] = username
    user_list[username]['userpasswd'] = userpasswd
    user_list[username]['salary'] = ''
    user_list[username]['shop_car'] = ''
    user_list[username]['shop_car_list'] = ''
    print('\n注册成功,你的用户名是:%s' % username, '\n')
    user = user_list[username]['username']
    wirte_logout()
    return


def print_product_list():
    print('\n产品列表:\n')
    for item in enumerate(product_list):
        index = item[0]
        p_name = item[1][0]
        p_price = item[1][1]
        print(index, ':', p_name, p_price)
    return


def printending():
    print('购物车中的商品'.center(50, '-'))
    for item in user_list[user]['shop_car']:
        a = user_list[user]['shop_car'].index(item)
        print('商品:%s  价格:%s  数量:%s' % (
        user_list[user]['shop_car'][a][0], user_list[user]['shop_car'][a][1], user_list[user]['shop_car_list'][a]))
    print('End'.center(50, '-'))
    return


"""调用信用卡auth 登陆 信用卡接口进行结账主要用提现功能"""
def pay_money(cash):
    user_choice1 = input('您购买的商品总价格为 %s 请确认是否结账[y]返回请按[b]' %cash)  # %count
    if user_choice1 == 'y':
        # 调用信用卡模块进行结账
        res = auth.creditcard_auth()
        creditcard_user = res[1]
        res1 = creditcard.withdrawals(creditcard_user)
        # 判断提现的钱数是否商品价格
        if res1 != None:
            if int(res1) < cash:
                print("您提取的余额不够支付账单、请再次提取")
                creditcard.withdrawals(creditcard_user)
            else:
                print("结账成功,购物车商品加入到数据库")
            pass
    elif user_choice1 == 'b':
        pass
    else:
        print("输入有误,请重新输入")
    return


exit_flag = False

while not exit_flag:
    index_page()

    index_user_choice = input('请输入您要进行的操作:')

    if index_user_choice == '0':
        login()
        exit_flag = True
    elif index_user_choice == '1':
        add_user()
        exit_flag = True
    elif index_user_choice == '2':
        print_product_list()
    else:
        print('输入操作无效!')

print('Begin The Shopping'.center(80, '-'), '\n')

#def shopping():
while True:
    if not user_list[user]['shop_car']:
        shop_car = []
        shop_car_list = []
    else:
        shop_car = user_list[user]['shop_car']
        shop_car_list = user_list[user]['shop_car_list']
    print_product_list()
    print("[查看购物车:c=check,退出商城:q=quit]", '\n')
    user_choice = input('请输入您想要购买的商品编号>>>: ')
    if user_choice.isdigit():
        user_choice = int(user_choice)
        if user_choice < len(product_list):
            p_item = product_list[user_choice]
            product = p_item[0]
            cash = p_item[1]
            if p_item not in shop_car:
                shop_car.append(p_item)
                shop_car_list.append(1)
                user_list[user]['shop_car'] = shop_car
                user_list[user]['shop_car_list'] = shop_car_list
                print('\033[32;1m 添加了:%s,价格是:%s\033[0m' % (product, cash), '\n')
                pay_money(cash)
            else:
                item_num = shop_car_list[shop_car.index(p_item)] + 1
                shop_car_list[shop_car.index(p_item)] = item_num
                user_list[user]['shop_car_list'] = shop_car_list
                print('\033[32;1m 在购物车上添加了:%s\033[0m' % (product, cash), '\n')
                pay_money(cash)
        else:
            print('你选择的商品不存在!', '\n')
    else:
        if user_choice == 'q' or user_choice == 'quit':
            printending()
            print('Bye %s' % user)
            wirte_logout()
            sys.exit()
        elif user_choice == 'c' or user_choice == 'check':
            printending()
        else:
            print('请输入合法字符!', '\n')
View Code

 

程序测试样图:

 

posted on 2017-12-03 23:36  Sean_Yao  阅读(1892)  评论(3编辑  收藏  举报