需求说明:
额度 15000或自定义 实现购物商城,买东西加入 购物车,调用信用卡接口结账 可以提现,手续费5% 支持多账户登录 支持账户间转账 记录每月日常消费流水 提供还款接口 ATM记录操作日志 提供管理接口,包括添加账户、用户额度,冻结账户等。。。 用户认证用装饰器
程序说明:
主菜单,进入主菜单显示如下:
【1】购物商城 【2】用户中心 【3】信用卡中心 【4】后台管理 【5】登录系统 【6】退出
购物商城:
显示各种商品和价格,选择对应的序号进行购买
用户中心:
【1】修改密码 【2】额度查询 【3】消费记录 【4】返回
信用卡中心:
【1】额度查询 【2】提现 【3】转账 【4】还款 【5】返回
后台管理,主要是admin用户进行管理:
【1】创建用户 【2】冻结信用卡 【3】解冻用户
【4】额度调整 【5】退出后台管理
登录系统:
未登录的用户需要进行登录
代码结构
程序代码,主程序:
1 #!/usr/bin/env python 2 #-*- coding:utf-8 -*- 3 # @Time : 2017/10/19 22:18 4 # @Author : lichuan 5 # @File : creditcard.py 6 7 from config import template 8 import time 9 from datetime import datetime 10 from module import common 11 import pickle 12 from log import my_log_settings 13 import logging 14 from module.users import Users 15 import os,sys 16 17 18 #加在日志配置模块 19 my_log_settings.load_my_logging_cfg() 20 #访问日志logger,path=log/access.log 21 acess_logger=logging.getLogger(__name__) 22 #消费日志logger,path=log/shop.log 23 shop_logger=logging.getLogger('shop') 24 25 #用户认证函数 26 # @wraps 27 def auth(func): 28 ''' 29 用户是否已经登录的认证装饰器 30 :param func: 31 :return: 32 ''' 33 def warpper(*args,**kwargs): 34 import pickle 35 # userinfo=pickle.loads(open('.json','rb').read())\ 36 userinfos = load_user() 37 if len(userinfos)!=0: 38 func(*args,**kwargs) 39 else: 40 login() 41 userinfos = load_user() 42 if len(userinfos)!=0: 43 func(*args,**kwargs) 44 return warpper 45 46 @auth 47 def shop_center(): 48 ''' 49 购物商城界面选择 50 :return: 51 ''' 52 shop={'apple手机':7000,'魅族手机':2000,'小米手机':2500,'华为手机':4000,'小米笔记本':4000} 53 shop_list=['apple手机','魅族手机','小米手机','华为手机','小米笔记本'] 54 salary=15000 55 userinfo=load_user() 56 # print(userinfo) 57 buy_list={} 58 salary=int(userinfo['salary']) 59 shop_flag=True 60 while shop_flag: 61 print(template.shopping_index_menu) 62 choice=input('请选择:').strip() 63 if not choice.isdigit() or int(choice) not in range(1,7): 64 print('输入错误,请重试!') 65 continue 66 if int(choice) == 6: 67 Users[userinfo['name']]=userinfo 68 dump_user(userinfo) 69 print('退出购物商城,再见!') 70 break 71 else: 72 key=shop_list[int(choice)-1] 73 money=shop[key] 74 if money > salary: 75 print('剩余额度不够,请选择别的商品!') 76 continue 77 else: 78 salary=salary-money 79 username=userinfo['name'] 80 shop_logger.info('[%s]购买%s,花费%d元!' % (username,key,money)) 81 print('%s,价值%d元,已购买!' % (key,money)) 82 print('剩余额度:%d元' % salary) 83 #更新信息到Users配置文件 84 userinfo['salary']=salary 85 if key in buy_list: 86 buy_list[key]+=1 87 else: 88 buy_list[key] = 1 89 userinfo['buy_list']=buy_list 90 Users[userinfo['name']] = userinfo 91 common.update_users(Users) 92 93 #从文件加载登录用户的信息 94 def load_user(): 95 ''' 96 从文件加载登录用户的信息 97 :return: userinfo信息 98 ''' 99 try: 100 with open('.pkl', 'rb') as read_f: 101 userinfo = {} 102 userinfo = pickle.loads(read_f.read()) 103 # print(userinfo) 104 except (FileNotFoundError,EOFError): 105 pass 106 return userinfo 107 108 #将登录用户信息重新写入.pkl 109 def dump_user(users): 110 ''' 111 将users信息重新写入.pkl文件进行保存。 112 :param users:users信息是个字典 113 :return: 114 ''' 115 with open('.pkl', 'w'): 116 pass 117 with open('.pkl', 'wb') as read_f: 118 p = pickle.dumps(users) 119 read_f.write(p) 120 121 #用户登录函数 122 def login(): 123 ''' 124 用户登录函数,对用户名密码进行校验,用户密码采用加密模块hashlib进行加盐加密 125 :return: 126 ''' 127 err_count=0 128 login_flag=True 129 while login_flag: 130 username=input('please input your username: ').strip() 131 password=input('please input your password: ').strip() 132 if username in Users: 133 if Users[username]['password'] == common.encrypt(password) and Users[username]['islocked'] == 0: 134 userinfo=Users[username] 135 err_count = 0 136 with open('.pkl','wb') as write_f: 137 p=pickle.dumps(userinfo) 138 write_f.write(p) 139 acess_logger.info(str(username)+' login success!') 140 print(str(username)+' login success!') 141 login_flag=False 142 elif Users[username]['islocked'] != 0: 143 print('user is locked ! cannot login!') 144 err_count = 0 145 login_flag=False 146 break 147 else: 148 print('name or password is wrong!!!') 149 acess_logger.info(str(username)+' login Falied ,password is wrong') 150 err_count+=1 151 #错误登录3次以上,锁定用户 152 if err_count >= 3: 153 Users[username]['islocked']=1 154 acess_logger.info(str(username)+' user locked!') 155 print(str(username)+' user locked!') 156 common.update_users(Users) 157 break 158 else: 159 print('name or password is wrong!') 160 # err_count+=1 161 162 @auth 163 def user_center(today,weekday): 164 ''' 165 用户登录后进入的用户个人中心界面 166 :param name:用户名称 167 :param today: 168 :param weekday:星期几 169 :return: 170 ''' 171 center_flag=True 172 userinfo=load_user() 173 name=userinfo['name'] 174 while center_flag: 175 print(template.index_user_center.format(name,today,weekday)) 176 choice=input('please input your choice:').strip() 177 if not choice.isdigit() or int(choice) not in range(1,5): 178 print('input wrong,please try again!') 179 continue 180 if int(choice) == 4: 181 print('用户中心和您再见!') 182 center_flag=False 183 break 184 elif int(choice) == 1: 185 common.modify_passwd(userinfo) 186 elif int(choice) == 2: 187 query_salary() 188 elif int(choice) == 3: 189 buylist=common.buy_list(userinfo['name']) 190 for b in buylist: 191 print(b,end='') 192 193 #额度查询函数,显示信用卡基本信息 194 def query_salary(): 195 status_all=['正常','被锁定'] 196 userinfo=load_user() 197 salary=userinfo['salary'] 198 total_salary=userinfo['total_salary'] 199 cardno=userinfo['bindcard'] 200 name=userinfo['name'] 201 status=status_all[0] if userinfo['islocked'] ==0 else status_all[1] 202 print(template.card_info.format(cardno,name,total_salary,salary,status)) 203 # print(template.card_info.format(str(cardno),name,str(total_salary),str(salary),status)) 204 205 #转账函数 206 def forward_cash(): 207 userinfo = load_user() 208 salary = userinfo['salary'] 209 u_card_no = userinfo['bindcard'] 210 card_list=[] 211 print('您现在剩余的可用额度为:%d' %salary) 212 card_no=input('请输入对方的卡号:').strip() 213 money=input('请输入转账的金额:').strip() 214 if not money.isdigit(): 215 print('金额输入有误!') 216 return 217 for k in Users: 218 if Users[k]['bindcard'] != u_card_no: 219 card_list.append(Users[k]['bindcard']) 220 if card_no not in card_list: 221 print('卡号有误') 222 return 223 if int(money) > salary: 224 print('转账金额超出你的信用额度!') 225 return 226 #减去自己的额度 227 salary=salary-int(money) 228 userinfo['salary']=salary 229 dump_user(userinfo) 230 Users[userinfo['name']]['salary']=salary 231 #增加别人的额度 232 for k in Users: 233 if card_no == Users[k]['bindcard']: 234 Users[k]['salary']+=int(money) 235 common.update_users(Users) 236 print('[%s]转账%d元给%s,手续费%d元' % (userinfo['name'],int(money),card_no)) 237 shop_logger.info('[%s]转账%d元给%s' % (userinfo['name'],int(money),card_no)) 238 239 #提现函数 240 def draw_cash(): 241 cash=input('请输入提现金额:').strip() 242 if not cash.isdigit() or int(cash) < 0: 243 print('金额输入错误!') 244 return 245 userinfo=load_user() 246 salary=userinfo['salary'] 247 if int(cash) > salary: 248 print('你的额度是%s,额度不够!' % salary) 249 return 250 else: 251 salary = salary - int(cash)*1.05 252 userinfo['salary']=salary 253 dump_user(userinfo) 254 Users[userinfo['name']]['salary'] = salary 255 common.update_users(Users) 256 query_salary() 257 shop_logger.info('[%s]取现%d元,手续费%d元!' % (userinfo['name'],int(cash),int(cash)*0.05)) 258 print('[%s]取现%d元,手续费%d元!' % (userinfo['name'],int(cash),int(cash)*0.05)) 259 260 #信用卡还款 261 def repay_salary(): 262 repay_money=input('请输入还款金额:').strip() 263 if not repay_money.isdigit(): 264 print('金额有误!') 265 return 266 else: 267 repay_money=int(repay_money) 268 userinfo = load_user() 269 userinfo['salary'] = userinfo['salary']+repay_money 270 dump_user(userinfo) 271 Users[userinfo['name']]=userinfo 272 common.update_users(Users) 273 query_salary() 274 shop_logger.info('[%s]还款%d元' % (userinfo['name'], repay_money)) 275 print('[%s]还款%d元' % (userinfo['name'], repay_money)) 276 277 #信用卡中心程序 278 @auth 279 def card_center(): 280 ''' 281 信用卡中心程序 282 :return: 283 ''' 284 func={ 285 '1': query_salary, 286 '2': draw_cash, 287 '3': forward_cash, 288 '4': repay_salary, 289 } 290 card_flag=True 291 while card_flag: 292 #初始化打印信息 293 userinfo=load_user() 294 user_name=userinfo['name'] 295 card_no=userinfo['bindcard'] 296 print(template.index_card_center.format(user_name,card_no)) 297 choice=input('请选择:').strip() 298 if not choice.isdigit() or int(choice) not in range(1,6): 299 print('输入错误,请重试!') 300 continue 301 if int(choice) == 5: 302 print('信用卡中心和您再见!') 303 break 304 else: 305 func[choice]() 306 307 308 #后台管理程序 309 @auth 310 def manager(): 311 func={ 312 '1':common.create_card, 313 '2':common.lock_card, 314 '3':common.unlock_card, 315 '4':common.modify_salary, 316 } 317 userinfo=load_user() 318 if userinfo['name'] != 'admin': 319 print('只有admin用户可以进入后台管理!') 320 return 321 manager_flag=True 322 while manager_flag: 323 print(template.index_admin.format(userinfo['name'])) 324 choice=input('请选择:').strip() 325 if not choice.isdigit() or int(choice) not in range(1,6): 326 print('输入错误!') 327 continue 328 if int(choice) == 5: 329 print('后台管理和您再见!') 330 manager_flag=False 331 break 332 else: 333 func[choice]() 334 335 if __name__ == '__main__': 336 Flag=True 337 # Flag=False 338 while Flag: 339 userinfo = load_user() 340 # print(userinfo) 341 # print(userinfo['name']) 342 username = '' 343 # username = userinfo['name'] if len(userinfo) != 0 else '' 344 today=time.strftime('%Y-%m-%d',time.localtime()) 345 weekday=common.numTo_characters(datetime.now().weekday()) 346 print(template.index_default_menu.format(username,today,weekday)) 347 choice = input("请选择:").strip() 348 if not choice.isdigit(): 349 print("输入错误,请重新输入") 350 continue 351 if int(choice) not in range(1,7): 352 print("输入错误,,请重新输入") 353 continue 354 if int(choice) == 1: 355 shop_center() 356 elif int(choice) == 2: 357 user_center(today,weekday) 358 elif int(choice) == 3: 359 card_center() 360 elif int(choice) == 4: 361 manager() 362 elif int(choice) == 5: 363 login() 364 elif int(choice) == 6: 365 with open('.pkl','w',encoding='utf-8'): 366 pass 367 print("再见!") 368 Flag=False