晚来了....东西太多,需要写的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:[email protected] 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:[email protected] 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:[email protected] 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:[email protected] 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:[email protected] 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:[email protected] 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:[email protected] 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:[email protected] 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:[email protected] 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:[email protected] 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:[email protected] 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:[email protected] 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:[email protected] 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:[email protected] 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:[email protected] 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:[email protected] 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:[email protected] 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:[email protected] 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:[email protected] 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:[email protected] 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_name,amount)) break else: print(‘验证失败!转账操作失败!!‘) log_trans.info(‘{}向{}转账失败‘.format(args,t_user_name)) break else: i+=1 print(‘输入格式错误,还有{}次机会‘.format(3-i))
terminal_view_credit.py:
#!/usr/bin/env python # -*-coding=utf-8-*- # Auther:ccorz Mail:[email protected] Blog:http://www.cnblogs.com/ccorz/ # GitHub:https://github.com/ccorzorz """ 查看用户信息模块 """ import sys sys.path.append(‘..‘) from core import data_op,format_num def view_credit(args): """ 查看用户信息,加载数据,并将相关数据显示至屏幕 :param args:用户名 :return: """ user_data=data_op.l_d() if user_data.get(args)==None: print(‘无此用户.‘) else: balance=user_data[args][3] balance=format_num.fn(balance) credit=format_num.fn(user_data[args][2]) print(‘您的信用额度:\033[31;1m{}\033[0m,目前可用信用额‘ ‘度为\033[31;1m{}\033[0m‘.format(credit,balance))
terminal_withdraw.py:
#!/usr/bin/env python # -*-coding=utf-8-*- # Auther:ccorz Mail:[email protected] 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 withdraw(args): """ 提现函数,与转账模块基本一样,但无需验证目标用户 :param args: 用户名 :return: """ user_data=data_op.l_d() able_amount=user_data[args][3] max_amount_2=user_data[args][2]/2 if able_amount>=max_amount_2: able_wd_amount=max_amount_2 else: able_wd_amount=able_amount print(‘您的可用提现额度为:{}‘.format(format_num.fn(able_wd_amount))) for i in range(4): if i ==3: print(‘输入格式错误超过3次,退出提现操作.‘) break amount=input(‘请输入提现金额:‘) if amount.isdigit(): amount=int(amount) if amount>able_wd_amount: print(‘最高取现额度为{},已超支,‘ ‘退出操作!‘.format(format_num.fn(able_wd_amount))) log_trans.info(‘{}提现操作失败‘.format(args)) break else: user_data[args][3]-=amount+amount*trans_rate[‘提现‘] data_op.flush_d(user_data) print(‘现可消费额度为:‘ ‘{}‘.format(format_num.fn(user_data[args][3]))) record(args,‘提现‘,‘终端机‘,amount) log_trans.info(‘{}成功提现{}‘.format(args,amount)) break else: i+=1 print(‘输入格式错误,还有{}次机会‘.format(3-i))
time_op.py:
#!/usr/bin/env python # -*-coding=utf-8-*- # Auther:ccorz Mail:[email protected] Blog:http://www.cnblogs.com/ccorz/ # GitHub:https://github.com/ccorzorz """ 时间处理模块 """ import datetime,time def get_22nd_of_last_month(): """ 获取上个月第一天的日期,然后加21天就是22号的日期 :return: 返回日期 """ today=datetime.datetime.today() year=today.year month=today.month if month==1: month=12 year-=1 else: month-=1 res=datetime.datetime(year,month,1)+datetime.timedelta(days=21) return res def get_22nd_of_next_month(): """ 获取下个月的22号的日期 :return: 返回日期 """ today=datetime.datetime.today() year=today.year month=today.month if month==12: month=1 year+=1 else: month+=1 res=datetime.datetime(year,month,1)+datetime.timedelta(days=21) return res def get_10th_of_current_month(): """ 获取本月的10号的日期 :return: 返回日期 """ today=datetime.datetime.today() year=today.year month=today.month res=datetime.datetime(year,month,11) return res def get_22nd_of_current_month(): """ 获取本月22号的日期 :return: 返回日期 """ today=datetime.datetime.today() year=today.year month=today.month res=datetime.datetime(year,month,22) return res def time_s_to_stamp(args): """ 将datetime日期格式,先timetuple()转化为struct_time格式 然后time.mktime转化为时间戳 :param args: datetime时间格式数据 :return: 时间戳格式数据 """ res=time.mktime(args.timetuple()) return res def str_to_stamp(args): """ 将时间字符串格式转化为时间戳格式 :param args: 时间字符串格式 :return: 时间戳数据 """ r=time.strptime(args,‘%Y-%m-%d %H:%M:%S‘) res=time.mktime(r) return res
veri_code.py:
#!/usr/bin/env python # -*-coding=utf-8-*- # Auther:ccorz Mail:[email protected] Blog:http://www.cnblogs.com/ccorz/ # GitHub:https://github.com/ccorzorz import random def veri_code(): """ #定义随机验证码函数 :return: 返回生成的随机码 """ li = [] for i in range(6): #循环6次,生成6个字符 r = random.randrange(0, 5) #随机生成0-4之间的数字 if r == 1 or r == 4: #如果随机数字是1或者4时,生成0-9的数字 num = random.randrange(0, 9) li.append(str(num)) else: #如果不是1或者4时,生成65-90之间的数字 temp = random.randrange(65, 91) char = chr(temp) #将数字转化为ascii列表中对应的字母 li.append(char) r_code = ‘‘.join(li) #6个字符拼接为字符串 print(‘\033[31;1m%s\033[0m‘ % r_code) return r_code #返回字符串 def check_veri(): res=veri_code() for i in range(3): code=input(‘请输入验证码:‘) if code.lower() == res.lower(): return True else: print(‘验证码错误,剩余尝试次数:{}‘.format(2-i))
db目录:
201605_bills.json:
{ "ccc": [ 0, [] ], "alex2": [ 0, [] ], "alex1": [ 0, [] ], "chengc": [ 0, [] ], "cc": [ 11694.949999999997, [ { "2016-06-09 18:02:26": [ "提现", "终端机", 8000, 400.0 ] }, { "2016-06-09 18:10:34": [ "支付", "大牛逼商城", 300, 0 ] }, { "2016-06-09 18:20:56": [ "支付", "大牛逼商城", 1800, 0 ] }, { "2016-06-09 18:26:33": [ "还款", "终端机", 1, 0 ] }, { "2016-06-09 19:26:48": [ "提现", "终端机", 1000, 50.0 ] }, { "2016-06-09 19:27:37": [ "提现", "终端机", 2, 0.1 ] }, { "2016-06-09 21:35:38": [ "转账", "终端机", 1, 0.05 ] }, { "2016-06-09 21:36:45": [ "转账", "终端机", 1, 0.05 ] }, { "2016-06-09 23:00:46": [ "还款", "终端机", 20, 0 ] }, { "2016-06-09 23:02:20": [ "提现", "终端机", 1, 0.05 ] }, { "2016-06-09 23:02:20": [ "提现", "终端机", 3, 0.15000000000000002 ] }, { "2016-06-09 23:03:47": [ "转账", "终端机", 50, 2.5 ] }, { "2016-06-09 23:34:05": [ "转账", "终端机", 1, 0.05 ] }, { "2016-06-09 23:34:05": [ "收款", "cc", 1, 0 ] }, { "2016-06-10 00:28:04": [ "转账", "终端机", 100, 5.0 ] } ] ], "alex": [ 0, [ { "2016-06-09 21:36:45": [ "收款", "cc", 1, 0 ] }, { "2016-06-09 23:03:47": [ "收款", "cc", 50, 0 ] }, { "2016-06-10 00:28:04": [ "收款", "cc", 100, 0 ] } ] ], "cccc": [ 0, [] ] }
atm_admin_db.json:
{"admin":"admin"}
atm_cart_db.json:
{ "cccc": [ 1, "b864ac015392b00d908bb7f760036248", 13000, 3000, [] ], "ccc": [ 1, "3580a3546bd6afa4a37d0a02c46a4b5a", 10000, 5000, [] ], "alex2": [ 1, "b864ac015392b00d908bb7f760036248", 15000, 15000, [] ], "wyw": [ 1, "b864ac015392b00d908bb7f760036248", 100000, 105201, [ { "2016-06-12 10:41:11": [ "收款", "cc", 1, 0 ] }, { "2016-06-12 16:30:15": [ "收款", "cc", 5200, 0 ] } ] ], "ab": [ 1, "b864ac015392b00d908bb7f760036248", 1223, 1223, [] ], "alex1": [ 1, "b864ac015392b00d908bb7f760036248", 5100, 5000, [] ], "chengc": [ 1, "b864ac015392b00d908bb7f760036248", 150000, 150000, [] ], "alex": [ 1, "b864ac015392b00d908bb7f760036248", 16000, 15152, [ { "2016-06-09 21:36:45": [ "收款", "cc", 1, 0 ] }, { "2016-06-09 23:03:47": [ "收款", "cc", 50, 0 ] }, { "2016-06-10 00:28:04": [ "收款", "cc", 100, 0 ] } ] ], "yangk": [ 1, "b864ac015392b00d908bb7f760036248", 19999, 19999, [] ], "cc": [ 1, "b864ac015392b00d908bb7f760036248", 51004, 50755.999999999985, [ { "2016-06-09 18:02:26": [ "提现", "终端机", 8000, 400.0 ] }, { "2016-06-09 18:10:34": [ "支付", "大牛逼商城", 300, 0 ] }, { "2016-06-09 18:20:56": [ "支付", "大牛逼商城", 1800, 0 ] }, { "2016-06-09 18:26:33": [ "还款", "终端机", 1, 0 ] }, { "2016-06-09 19:26:48": [ "提现", "终端机", 1000, 50.0 ] }, { "2016-06-09 19:27:37": [ "提现", "终端机", 2, 0.1 ] }, { "2016-06-09 21:35:38": [ "转账", "终端机", 1, 0.05 ] }, { "2016-06-09 21:36:45": [ "转账", "终端机", 1, 0.05 ] }, { "2016-06-09 23:00:46": [ "还款", "终端机", 20, 0 ] }, { "2016-06-09 23:02:20": [ "提现", "终端机", 1, 0.05 ] }, { "2016-06-09 23:02:20": [ "提现", "终端机", 3, 0.15000000000000002 ] }, { "2016-06-09 23:03:47": [ "转账", "终端机", 50, 2.5 ] }, { "2016-06-09 23:34:05": [ "转账", "终端机", 1, 0.05 ] }, { "2016-06-09 23:34:05": [ "收款", "cc", 1, 0 ] }, { "2016-06-10 00:28:04": [ "转账", "终端机", 100, 5.0 ] }, { "2016-06-15 20:51:11": [ "还款", "终端机", 1, 0 ] }, { "2016-06-15 20:51:11": [ "还款", "终端机", 1, 0 ] }, { "2016-06-12 10:15:59": [ "支付", "test", 100, 0 ] }, { "2016-06-12 10:41:11": [ "转账", "终端机", 1, 0.05 ] }, { "2016-06-12 10:41:11": [ "提现", "终端机", 200, 10.0 ] }, { "2016-06-12 10:41:11": [ "还款", "终端机", 2000, 0 ] }, { "2016-06-12 13:03:54": [ "支付", "大牛逼商城", 100, 0 ] }, { "2016-06-12 16:28:03": [ "支付", "大牛逼商城", 900, 0 ] }, { "2016-06-12 16:30:15": [ "还款", "终端机", 22, 0 ] }, { "2016-06-12 16:30:15": [ "提现", "终端机", 300, 15.0 ] }, { "2016-06-12 16:30:15": [ "转账", "终端机", 5200, 260.0 ] }, { "2016-06-15 13:07:51": [ "支付", "大牛逼商城", 5888, 0 ] }, { "2016-06-15 13:09:16": [ "还款", "终端机", 12000, 0 ] } ] ], "1234": [ 1, "15da27ca7d6c671cbdf85396b9096d80", 10000, 1220, [] ] }
goods.json:
{ "服装": { "T恤": { "stock": 887, "belong": "服装", "price": 300 }, "小白鞋": { "stock": 5954, "belong": "服装", "price": 900 }, "Nudie牛仔裤": { "stock": 3973, "belong": "服装", "price": 699 }, "驴牌腰带": { "stock": 2999, "belong": "服装", "price": 9999 } }, "手机": { "华为Mate": { "stock": 5995, "belong": "手机", "price": 2999 }, "Iphone": { "stock": 2996, "belong": "手机", "price": 5888 }, "锤子2(这特么真是手机)": { "stock": 2994, "belong": "手机", "price": 998 }, "XiaoMi 4": { "stock": 5395, "belong": "手机", "price": 1999 } }, "电脑": { "Mac pro": { "stock": 3994, "belong": "电脑", "price": 9999 }, "Mac Air": { "stock": 6001, "belong": "电脑", "price": 6999 }, "IBM X240": { "stock": 3003, "belong": "电脑", "price": 6999 }, "Surface Book": { "stock": 3020, "belong": "电脑", "price": 8999 } }, "汽车": { "Porsche 911": { "stock": 594, "belong": "汽车", "price": 2999999 }, "Tesla Model S": { "stock": 3000, "belong": "汽车", "price": 799999 }, "BMW X3": { "stock": 399, "belong": "汽车", "price": 499999 }, "PASST": { "stock": 297, "belong": "汽车", "price": 299999 } }, "家电": { "微波炉": { "stock": 2994, "belong": "家电", "price": 800 }, "彩电": { "stock": 397, "belong": "家电", "price": 5000 }, "洗衣机": { "stock": 597, "belong": "家电", "price": 999 }, "冰箱": { "stock": 300, "belong": "家电", "price": 3000 }, "热水器": { "stock": 900, "belong": "家电", "price": 600 } } }
mall_cart.json:
{ "cc": [], "shane": [] }
mall_user.json:
{ "zc": [ "123", 0, [] ], "shane": [ "123", 96105, [ [ "2016-06-06 13:54:13", [ [ "微波炉", 2, 1600 ], [ "洗衣机", 1, 999 ] ] ], [ "2016-06-06 13:54:13", [ [ "T恤", 2, 600 ], [ "Nudie牛仔裤", 1, 699 ] ] ] ] ], "zhangxiaodong": [ "zhangxiaodong", 0, [] ], "123": [ "123", 0, [] ], "cc": [ "123", 73045, [ [ "2016-05-19 14:23:37", [ [ "小白鞋", 1, 900 ], [ "T恤", 1, 300 ] ] ], [ "2016-05-19 17:07:06", [ [ "微波炉", 1, 800 ] ] ], [ "2016-05-19 17:56:19", [ [ "Nudie牛仔裤", 1, 699 ], [ "洗衣机", 1, 999 ] ] ], [ "2016-05-20 10:07:34", [ [ "IBM X240", 1, 6999 ] ] ], [ "2016-05-20 13:34:32", [ [ "锤子2(这特么真是手机)", 1, 998 ] ] ], [ "2016-05-20 15:59:02", [ [ "洗衣机", 1, 999 ] ] ], [ "2016-06-06 13:51:04", [ [ "小白鞋", 2, 1800 ] ] ], [ "2016-06-06 15:25:05", [ [ "T恤", 1, 300 ] ] ], [ "2016-06-06 15:25:05", [ [ "Mac Air", 1, 6999 ] ] ], [ "2016-06-06 17:29:16", [ [ "微波炉", 1, 800 ] ] ], [ "2016-06-07 11:37:57", [ [ "Nudie牛仔裤", 1, 699 ] ] ], [ "2016-06-07 14:12:59", [ [ "彩电", 1, 5000 ] ] ], [ "2016-06-08 09:26:10", [ [ "微波炉", 2, 1600 ] ] ], [ "2016-06-08 17:19:09", [ [ "彩电", 1, 5000 ], [ "T恤", 3, 900 ] ] ], [ "2016-06-08 17:20:05", [ [ "小白鞋", 1, 900 ] ] ], [ "2016-06-08 17:20:05", [ [ "Iphone", 1, 5888 ] ] ], [ "2016-06-08 17:20:05", [ [ "XiaoMi 4", 1, 1999 ] ] ], [ "2016-06-08 17:29:18", [ [ "小白鞋", 2, 1800 ] ] ], [ "2016-06-08 17:29:18", [ [ "小白鞋", 1, 900 ] ] ], [ "2016-06-08 17:31:51", [ [ "Nudie牛仔裤", 2, 1398 ] ] ], [ "2016-06-08 17:35:40", [ [ "T恤", 1, 300 ] ] ], [ "2016-06-08 17:36:25", [ [ "Mac pro", 1, 9999 ] ] ], [ "2016-06-08 17:50:44", [ [ "T恤", 1, 300 ] ] ], [ "2016-06-08 17:54:24", [ [ "华为Mate", 1, 2999 ] ] ], [ "2016-06-09 18:10:34", [ [ "T恤", 1, 300 ] ] ], [ "2016-06-09 18:20:56", [ [ "小白鞋", 2, 1800 ] ] ], [ "2016-06-12 16:28:03", [ [ "小白鞋", 1, 900 ] ] ], [ "2016-06-15 13:07:51", [ [ "Iphone", 1, 5888 ] ] ] ] ], "chengc": [ "123456", 999999999, [] ] }
mall_user_lock:
shane
log日志会自动创建..
trans.log:
2016-06-15 20:51:21,143 - trans - INFO - cc成功还款1 2016-06-15 20:51:27,495 - trans - INFO - cc成功还款1 2016-06-15 20:51:27,495 - trans - INFO - cc成功还款1 2016-06-12 10:16:09,824 - trans - INFO - test支付调用,用户cc支付100 2016-06-12 10:43:13,253 - trans - INFO - cc向wyw成功转账1 2016-06-12 10:43:24,376 - trans - INFO - cc成功提现200 2016-06-12 10:43:48,317 - trans - INFO - cc成功还款2000 2016-06-12 13:04:25,868 - trans - INFO - 大牛逼商城支付调用,用户cc支付100 2016-06-12 13:04:47,828 - trans - INFO - cc调用支付接口,额度不足,支付失败 2016-06-12 13:05:33,324 - trans - INFO - cc调用支付接口,额度不足,支付失败 2016-06-12 16:28:34,212 - trans - INFO - 大牛逼商城支付调用,用户cc支付900 2016-06-12 16:30:37,353 - trans - INFO - cc成功还款22 2016-06-12 16:30:52,169 - trans - INFO - cc成功提现300 2016-06-12 16:31:19,328 - trans - INFO - cc向wyw成功转账5200 2016-06-15 13:08:31,554 - trans - INFO - 大牛逼商城支付调用,用户cc支付5888 2016-06-15 13:09:36,623 - trans - INFO - cc成功还款12000
时间: 2024-10-10 12:07:58