"""
需求分析之项目功能
1、登录
2、注册
3、查看余额
4、转账
5、还款
6、取款
7、查看流水
8、购物
9、查看购买商品
划分项目目录
-ATM
-bin目录:
-src.py启动文件,整个项目的入口
-db目录:
-db_handler.py 查询和保存方法
-xxx.json
-yyy.json
-view目录
-main.py:视图层的逻辑
-interface目录
-bank.py
-user.py
-shopping.py
-lib目录
-common.py 公共方法,登录认证装饰器
-log目录
-日志文件放在里面
-conf目录
-配置文件
"""
src.py
import os
import sys
path = os.path.dirname(os.path.dirname(__file__))
sys.path.append(path)
from view import main
if __name__ == '__main__':
main.run()
db_handler.py
from conf import settings
import json
import os
def save(user_info):
with open('%s/%s.json' % (settings.BASE_DB, user_info['name']), 'wt', encoding='utf-8') as f:
json.dump(user_info, f, ensure_ascii=False)
f.flush()
def select(name):
path = '%s/%s.json' % (settings.BASE_DB, name)
if os.path.isfile(path):
with open('%s/%s.json' % (settings.BASE_DB, name), 'rt', encoding='utf-8') as f:
user_info = json.load(f)
return user_info
else:
return False
mian.py
from db import db_handler
from interface import bank, user
from interface import shopping as shop
from lib import common
import time
user_login = {
'is_login': False,
'user': None
}
def login():
if user_login['is_login']:
print('您已经登录了,不能注册')
return
print('登录功能')
count = 0
while True:
name = input('请输入用户名(按q退出):')
if name == 'q': break
user_info = user.get_userinfo_by_name(name)
if user_info:
if user_info['locked'] and user_info['unlocked_time'] > time.time():
print('您的用户已经被锁,请稍后再试')
break
else:
password = input('请输入密码:')
user_info = db_handler.select(name)
if password == user_info['password']:
user.unlock_name(name)
print('登录成功!')
user_login['is_login'] = True
user_login['name'] = name
break
else:
print('密码错误!')
count += 1
if count >= 3:
user.lock_name(name)
user.lock_time(name)
print('输入密码错误次数过多,用户已经被锁定')
break
else:
print('您还没注册呢!')
def register():
if user_login['is_login']:
print('您已经登录了,不能注册')
return
print('注册功能')
while True:
name = input('请输入用户名(按q退出):')
if name == 'q': break
if not user.db_handler.select(name):
password = input('请输入密码:')
re_password = input('请再次输入密码:')
if re_password == password:
res = user.register_interface(name, password)
if res:
print('注册成功')
user_login['is_login'] = True
user_login['name'] = name
break
else:
print('两次密码不一致,请重新输入。')
else:
print('您已经注册过了!')
@common.login_auth
def check_balance():
print('查询余额功能')
balance = bank.get_balance(user_login['name'])
print('您的余额为%s元' % balance)
@common.login_auth
def transfer():
print('转账功能')
while True:
to_user = input('请输入转账给的账户:')
if user.get_userinfo_by_name(to_user):
money = input('请输入转账金额:')
if bank.check_money_interface(money):
money = float(money)
_, msg = bank.transfer_interface(user_login['name'], to_user, money)
print(msg)
return
else:
print('请输入正确的金额')
else:
print('请输入正确的用户名')
@common.login_auth
def repay():
print('还款充值功能')
while True:
money = input('请输入取款金额(按q退出):')
if money == 'q': break
if bank.check_money_interface(money):
money = float(money)
_, msg = bank.repay_interface(user_login['name'], money)
print(msg)
return
else:
print('请输入正确的金额!')
@common.login_auth
def withdraw():
print('取款功能')
while True:
money = input('请输入取款金额(按q退出):')
if money == 'q': break
if bank.check_money_interface(money):
money = float(money)
_, msg = bank.withdraw_interface(user_login['name'], money)
print(msg)
break
else:
print('请输入正确的金额!')
@common.login_auth
def check_recorder():
print('查询流水功能')
recorder_list = bank.get_recorder(user_login['name'])
for item in recorder_list:
print(item)
@common.login_auth
def shopping():
print('购物功能')
'''
0 整体放到while循环中
1 打印出所有的商品,带编号(变量存商品,字典,列表)
[{name:汽车,price:100},{name:苹果,price:10},{name:香蕉,price:20}]
[[汽车,100],[苹果,10],[香蕉,20]]
2 用户输入编号,选择要购买的商品
3 校验输入的编号要在打印的数字范围内,输入的是否是数字
3.1 选中的商品加入到购物车(字典),消费多少钱,余额是多少
{汽车:{价格:10,数量:1},苹果:{价格:10,数量:1},}
[{商品名:苹果,价格:10,数量:1},{商品名:苹果,价格:10,数量:1}]
3.2 余额减商品价格,消费金额加上商品价格
3.3 如果当次选择的商品在购物车中,只需要改数量即可
3.4 如果当次选择的商品不在购物车中,向购物车中新增一条记录
4 输入q,退出,询问用户是否购买加入购物车的商品
4.1 是购买,调用购买,购买商品
4.2 不购买,直接退出
'''
goods = [
['飞机', 20000],
['汽车', 10000],
['自行车', 2000],
['滑板鞋', 200]
]
shopping_cart = {}
cost_money = 0
balance = bank.get_balance(user_login['name'])
while True:
for i, good in enumerate(goods):
print('%s 商品名:%s 价格%s' % (i, good[0], good[1]))
choice = input('请输入要购买的商品编号(一次添加一个,按q退出或购买):')
if choice.isdigit():
choice = int(choice)
if choice < 0 or choice > len(goods) - 1:
print('更多商品正在上架中')
continue
good_name = goods[choice][0]
good_price = goods[choice][1]
if balance >= good_price:
if good_name not in shopping_cart:
shopping_cart[good_name] = {'price': good_price, 'count': 1}
else:
shopping_cart[good_name]['count'] += 1
cost_money += good_price
balance -= good_price
print('%s被加入了购物车' % good_name)
print('目前购物车有', shopping_cart)
else:
print('余额不足,只剩%s元' % balance)
elif choice == 'q':
print('退出并购买')
y = input('是否购买?(y/n)')
if y == 'y':
if cost_money > 0:
print('输入密码,通过了')
msg = shop.buy_goods_interface(user_login['name'], shopping_cart, cost_money)
print('购买了%s', shopping_cart)
print(msg)
else:
print('什么都没选,你还点击购买?')
break
else:
print('没钱买吗?穷鬼')
break
else:
print('请输入正确的数字')
@common.login_auth
def check_shopping_cart():
print('查询购物车功能')
cart = shop.get_shopping_cart_interface(user_login['name'])
print(cart)
dic = {
'1': login,
'2': register,
'3': check_balance,
'4': transfer,
'5': repay,
'6': withdraw,
'7': check_recorder,
'8': shopping,
'9': check_shopping_cart,
}
def run():
while True:
print(u'''
------- WS Bank ---------
\033[32;1m1. 登录
2. 注册
3. 查看余额
4. 转账
5. 还款
6. 取款
7. 查看流水
8. 购物
9. 查看购买商品
\033[0m''')
choice = input('请输入编号(按q退出):').strip()
if choice == 'q': break
if choice in dic:
dic[choice]()
else:
print('请输入正确的数字编号。')
user.py
from db import db_handler
import time
def register_interface(name, password, balance=15000):
user_info = {'name': name, 'password': password, 'balance': 15000, 'credit': 15000, 'locked': False,
'unlocked_time': None, 'bank_flow': [], 'shopping_cart': {}}
db_handler.save(user_info)
return True
def get_userinfo_by_name(name):
user_info = db_handler.select(name)
return user_info
def lock_name(name):
user_info = db_handler.select(name)
if user_info:
user_info['locked'] = True
db_handler.save(user_info)
def lock_time(name):
user_info = db_handler.select(name)
user_info['unlocked_time'] = time.time() + 180
db_handler.save(user_info)
def unlock_name(name):
user_info = db_handler.select(name)
if user_info:
user_info['locked'] = False
db_handler.save(user_info)
bank.py
from db import db_handler
from interface import user
from lib import common
import time
logger_bank = common.load_my_logging_cfg('bank')
def check_money_interface(money):
s = str(money)
if s.count('.') == 1:
sl = s.split('.')
left = sl[0]
right = sl[1]
count_right = 0
for num in right:
count_right += 1
if 2 >= count_right >= 0:
if left.startswith('-') and left.count('-') == 1 and right.isdigit():
lleft = left.split('-')[1]
if lleft.isdigit():
return False
elif left.isdigit() and right.isdigit():
return True
else:
return False
elif s.isdigit():
s = int(s)
if s != 0:
return True
return False
def get_balance(name):
user_info = user.get_userinfo_by_name(name)
logger_bank.info('%s在%s查询余额' % (name, time.strftime('%F-%H:%M:%S')))
return user_info['balance']
def withdraw_interface(name, money):
user_info = db_handler.select(name)
if user_info['balance'] >= money * 1.05:
user_info['balance'] -= money * 1.05
user_info['balance'] = round(user_info['balance'], 2)
user_info['bank_flow'].append('%s取现%s元,扣除手续费%.2f元' % (name, money, money * 0.05))
db_handler.save(user_info)
logger_bank.info('%s在%s取现%s元,扣除手续费%s元' % (name, time.strftime('%F-%H:%M:%S'), money, money * 0.05))
return True, '取款成功'
else:
return False, '余额不足'
def repay_interface(name, money):
user_info = db_handler.select(name)
user_info['balance'] += money
user_info['bank_flow'].append('%s还款%s元' % (name, money))
user_info['balance'] = round(user_info['balance'], 2)
db_handler.save(user_info)
logger_bank.info('%s在%s还款%s元' % (name, time.strftime('%F-%H:%M:%S'), money))
return True, '还款成功'
def transfer_interface(from_user, to_user, money):
from_user_info = db_handler.select(from_user)
to_user_info = db_handler.select(to_user)
if from_user_info['balance'] >= money:
from_user_info['balance'] -= money
from_user_info['balance'] = round(from_user_info['balance'], 2)
from_user_info['bank_flow'].append('%s向%s转账%s元' % (from_user, to_user, money))
to_user_info['balance'] += money
to_user_info['balance'] = round(to_user_info['balance'], 2)
to_user_info['bank_flow'].append('%s向%s转账%s元' % (to_user, from_user, money))
db_handler.save(from_user_info)
db_handler.save(to_user_info)
logger_bank.info('%s在%s向%s转账%s元' % (from_user, time.strftime('%F-%H:%M:%S'), to_user, money))
return True, '转账成功'
else:
return False, '余额不足!'
def get_recorder(name):
user_info = db_handler.select(name)
logger_bank.info('%s在%s查看了流水' % (name, time.strftime('%F-%H:%M:%S')))
return user_info['bank_flow']
def consume_interface(name, money):
user_info = db_handler.select(name)
user_info['balance'] -= money
user_info['bank_flow'].append('%s购买商品%s元' % (name, money))
db_handler.save(user_info)
logger_bank.info('%s在%s购买商品%s元' % (name, time.strftime('%F-%H:%M:%S'), money))
return True
shopping.py
from db import db_handler
from interface import bank
def get_shopping_cart_interface(name):
user_info = db_handler.select(name)
return user_info['shopping_cart']
def buy_goods_interface(name, shopping_cart, money):
user_info = db_handler.select(name)
user_info['shopping_cart'] = shopping_cart
db_handler.save(user_info)
bank.consume_interface(name, money)
return '购买成功'
common.py
from view import main
"""
logging配置
"""
import os
import logging.config
from conf import settings
standard_format = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' \
'[%(levelname)s][%(message)s]'
simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'
id_simple_format = '[%(levelname)s][%(asctime)s] %(message)s'
logfile_dir = settings.BASE_LOG
logfile_name = 'atm.log'
if not os.path.isdir(logfile_dir):
os.mkdir(logfile_dir)
logfile_path = os.path.join(logfile_dir, logfile_name)
LOGGING_DIC = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'standard': {
'format': standard_format
},
'simple': {
'format': simple_format
},
},
'filters': {},
'handlers': {
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
'formatter': 'simple'
},
'default': {
'level': 'DEBUG',
'class': 'logging.handlers.RotatingFileHandler',
'formatter': 'standard',
'filename': logfile_path,
'maxBytes': 1024 * 1024 * 5,
'backupCount': 5,
'encoding': 'utf-8',
},
},
'loggers': {
'': {
'handlers': ['default', 'console'],
'level': 'DEBUG',
'propagate': True,
},
},
}
def load_my_logging_cfg(name):
logging.config.dictConfig(LOGGING_DIC)
logger = logging.getLogger(name)
return logger
def login_auth(func):
def inner(*args, **kwargs):
if main.user_login['is_login']:
res = func(*args, **kwargs)
return res
else:
main.login()
return inner
settings.py
import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
BASE_DB = os.path.join(BASE_DIR, 'db')
BASE_LOG = os.path.join(BASE_DIR, 'log')