ATM项目开发
(1)在主程序文件中创建程序入口
(2)在核心代码文件(视图层)搭建程序框架
(3)进行代码功能分配
- ATM 项目根目录
- README.md 项目说明书
- start.py 项目启动文件的创建方式二,直接暴露在最外层
- conf 配置文件
- settings.py
- lib 公共方法文件
- common.py
- core(用户视图层) 存放用户视图层代码文件
- bank_src.py 银行操作代码
- user_src.py 用户操作代码
- db(数据处理层) 存放数据与数据处理层代码
- db_hander.py 数据处理层代码
- user_data 用户数据
- bank_data 银行数据
- log 存放日志文件
- user_log 用户日志
- flow_log 流水日志
- bin(启动文件目录) 存放启动文件的方式一,单独创建目录
- main.py
【一】功能概要
【1】注册
【2】登陆
【3】取款
【4】存款
【5】转账
【6】查看流水
【7】查看日志
【8】查看银行信息(查看自己的卡号、余额)
【9】初始化银行信息
【10】退出
【二】功能需求
【1】注册
(1)身份信息构成
- 身份信息包括:用户名、密码、角色
(2)参数验证
- 验证用户名是未注册过的用户名
- 验证密码为三位数并且是数字类型
(3)信息存储
- 将个人注册信息存储到指定文件 username_log.txt 文件中 日志格式为
当前用户 username 于 xx年xx月xx日 xx时xx分xx秒 注册成功
【2】登陆
(1)参数验证
- 验证用户名是已注册过的用户名
- 验证密码为三位数并且是数字类型
(2)信息存储
- 登陆成功后存储个人信息,以备后面不定期使用
- 登陆成功后存储个人银行信息,以备后面不定期使用
(3)信息存储
- 将个人登陆信息存储到指定文件 username_log.txt 文件中
- 登陆成功 : 将个人注册信息存储到指定文件 username_log.txt 文件中 日志格式为
当前用户 username 于 xx年xx月xx日 xx时xx分xx秒 登陆成功
【3】取款
(1)参数验证
- 当前为登录用户且银行卡初始化成功
- 验证支付密码必须是数字格式,并且符合三位
- 验证银行卡号必须是数字格式,并且符合六位
- 验证取款金额小于等于当前用户余额
(2)记录流水
- 需记录当前取款流水记录,流水信息包括,流水格式为
当前用户 username 于 xx年xx月xx日 xx时xx分xx秒 取出金钱 balance 余额为 res
(3)信息存储
- 将个人银行信息存储到指定文件 username_flow.txt 文件中
【4】存款
(1)参数验证
- 当前为登录用户且银行卡初始化成功
- 验证支付密码必须是数字格式,并且符合三位
- 验证银行卡号必须是数字格式,并且符合六位
(2)记录流水
- 需记录当前存款流水记录,流水信息包括,流水格式为
当前用户 username 于 xx年xx月xx日 xx时xx分xx秒 存入 balance 余额为 res
(3)信息存储
- 将个人银行信息存储到指定文件 username_bank.txt 文件中
【5】转账
(1)参数验证
- 当前为登录用户且银行卡初始化成功
- 验证支付密码必须是数字格式,并且符合三位
- 验证银行卡号必须是数字格式,并且符合六位
- 验证取款金额必须大于0且小于等于当前用户余额
(2)记录流水
- 需记录当前取款流水记录,流水信息包括
- 流水格式为
当前用户 username 于 xx年xx月xx日 xx时xx分xx秒 向 target_username 转账 balance 余额为 res
- 流水格式为
当前用户 target_username 于 xx年xx月xx日 xx时xx分xx秒 收到 username 转账 balance 余额为 res1
- 流水格式为
(3)信息存储
- 将个人银行信息存储到指定文件 username_bank_log.txt 文件中
【6】查看流水
(1)参数验证
- 当前为登录用户且银行卡初始化成功
【7】查看日志
(1)参数验证
- 当前为登录用户且银行卡初始化成功
【8】查看银行信息(查看自己的卡号、余额)
(1)参数验证
- 当前为登录用户且银行卡初始化成功
【9】激活
(1)银行信息构成
- 银行信息包括:用户名、支付密码、余额、银行卡号
(2)参数验证
- 验证支付密码必须是数字格式,并且符合三位
- 验证银行卡号必须是数字格式,并且符合六位
- 给予初识余额 1000 元
(3)信息存储
- 记录日志到 username_flow.txt 中,日志格式为
username 于 xx年xx月xx日 xx时xx分xx秒 初始化成功 余额为 balance
- 将个人银行信息存储到指定文件 username_flow.txt 文件中
【10】退出
- 直接退出程序
【三】代码实现
【1】bin
- 存放启动文件的方式一,单独创建目录
# author : heart
# blog_url : https://www.cnblogs.com/ssrheart/
# time : 2023/12/19
from core import register,login,check_flow,check_log,check_bank_info,back,get_balance,add_balance,transfer_balance,init_bank_info
func_menu = '''
===================用户功能菜单=====================
1.注册
2.登陆
3.取款
4.存款
5.转账
6.查看流水
7.查看日志
8.查看银行信息(查看自己的卡号、余额)
9.激活银行卡
10.退出
======================欢迎使用=======================
'''
func_dict = {
'1': register,
'2': login,
'3': get_balance,
'4': add_balance,
'5': transfer_balance,
'6': check_flow,
'7': check_log,
'8': check_bank_info,
'9': init_bank_info,
'10': back
}
def main():
while True:
print(func_menu)
func_id = input('请输入功能id:>>>').strip()
if func_id not in func_dict.keys():
print('功能不存在!')
continue
func = func_dict[func_id]
flag, msg = func()
if flag:
if msg == 'back':
break
print(msg)
else:
print(msg)
continue
main()
【2】conf
- 配置文件 - settings.py
# author : heart
# blog_url : https://www.cnblogs.com/ssrheart/
# time : 2023/12/19
import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
# print(BASE_DIR) # D:\2023propygo\ATMProject\ATM3.0wjjtest
def create_path(*args):
for path in args:
if not os.path.exists(path):
os.mkdir(path)
path_list=[]
DB_DIR =os.path.join(BASE_DIR,'db')
USER_DATA=os.path.join(DB_DIR,'user_data')
BANK_DATA =os.path.join(DB_DIR,'bank_data')
LOG_DIR=os.path.join(BASE_DIR,'log')
USER_LOG=os.path.join(LOG_DIR,'user_log')
FLOW_LOG =os.path.join(LOG_DIR,'flow_log')
path_list.append(DB_DIR)
path_list.append(USER_DATA)
path_list.append(BANK_DATA)
path_list.append(LOG_DIR)
path_list.append(USER_LOG)
path_list.append(FLOW_LOG)
create_path(*path_list)
【3】core
-
核心代码
- user_src.py
# author : heart # blog_url : https://www.cnblogs.com/ssrheart/ # time : 2023/12/19 from db.db_hander import save_data,read_data import time from lib import create_data_format login_auth_dict={ 'username':'', 'is_admin':'', 'bank_id':'', 'bank_pwd':'', 'balance':'' } def login_auth(func): def inner(*args, **kwargs): if not login_auth_dict['username']: return False, f'请先登录!' if not login_auth_dict['bank_id'] and func.__name__ != 'init_bank_info': return False, f'请先激活银行卡!' return func(*args, **kwargs) return inner def get_user_pass(): username = input('请输入用户名:>>>').strip() password = input('请输入密码:>>>').strip() return username, password def register(): # (1)获取当前输入的用户名和密码 username, password = get_user_pass() # (2)校验密码格式 -- 必须是数字并且是3位 if not password.isdigit(): return False, f'非法!' if len(password) != 3: return False, f'密码必须是3位数!' # (3)给身份,是管理员还是普通用户 if username == 'heart' and password == '123': role = 'admin' else: role = 'normal' # (4)拼接数据格式 # username|password|role user_data = create_data_format(username=username,password=password,role=role) # (5)保存用户数据 # db/user_data/user_pwd.txt # username|password|role save_data(path=f'user_pwd.txt',data=user_data) # (6)构建日志信息 # log/user_log/username_log.txt # 当前用户 username 于 time.strftime{"%x %X"}注册成功! user_log = create_data_format(tag='log',username=username,msg=f'注册成功!') save_data(path=f'{username}_log.txt',data=user_log) # (7)初始化银行信息 # db/bank_data/username_bank.txt # username|bank_id|bank_pwd|balance bank_data = create_data_format(username=username,bank_id='None',bank_pwd='None',balance='None') save_data(path=f'{username}_bank.txt',data=bank_data) # (8)银行流水和日志 # 当前用户username 于 time.strftime{"%x %X"} 开卡成功,但未激活 # log/flow_log/username_flow.txt # 日志:log/user_log/username_log.txt flow_log = create_data_format(tag='flow',username=username,msg=f'开卡成功,但未激活!') save_data(path=f'{username}_flow.txt',data=flow_log) bank_user_log = create_data_format(tag='log',username=username,msg=f'开卡成功,但未激活!') save_data(path=f'{username}_log.txt',data=bank_user_log) # (9)返回注册成功的信息 # 当前用户 username 于 time.strftime{"%x %X"} 注册成功 return True,user_log # 登录 : 直接将用户信息从文件中取出,然后进行比对 用户名 - 密码 def login(): username, password = get_user_pass() user_data=read_data(tag='login',path='user_pwd.txt') if username not in user_data: return False,f'请先注册!' if not password.isdigit(): return False,f'密码必须是数字!' if len(password) !=3: return False,f'密码必须是三位数!' data = user_data.get(username) if password != data.get('password'): return False,f'密码错误!' login_auth_dict['username'] = username login_auth_dict['is_admin'] = data.get('role') userlogin_log = create_data_format(tag='log', username=username, msg=f'登录成功!') save_data(path=f'{username}_log.txt', data=userlogin_log) return True,userlogin_log # 查看流水 @login_auth def check_flow(): username = login_auth_dict['username'] data_list = read_data(tag='flow', path=f'{username}_flow.txt') count = 0 print(f"************* 流水打印开始 *************") for data in data_list: count += 1 print(f'当前第{count}条流水 :>>> {data}') print(f"************* 流水打印结束 *************") return True, f'{username}流水打印完成!' # 查看日志 @login_auth def check_log(): username = login_auth_dict['username'] data_list = read_data(tag='log', path=f'{username}_log.txt') count = 0 print(f"************* 日志打印开始 *************") for data in data_list: count += 1 print(f'当前第{count}条日志 :>>> {data}') print(f"************* 日志打印结束 *************") return True, f'{username}日志打印完成!' # 查看银行信息 @login_auth def check_bank_info(): username = login_auth_dict['username'] data_info = read_data(tag='info', path=f'{username}_bank.txt') card_id = data_info.get('bank_id') balance = data_info.get('balance') return True, f'用户{username} 卡号为{card_id} 当前余额{balance} 元!' # 退出 def back(): print('欢迎再次使用!') return True, 'back'
- bank_src
# author : heart # blog_url : https://www.cnblogs.com/ssrheart/ # time : 2023/12/19 # 取款 import time from .user_src import login_auth_dict from lib import create_data_format from db.db_hander import save_data, read_data target_user_data={'username':'', 'bank_id':'', 'bank_pwd':'', 'balance':''} def login_auth(func): def inner(*args, **kwargs): if not login_auth_dict['username']: return False, f'请先登录!' if not login_auth_dict['bank_id'] and func.__name__ != 'init_bank_info': return False, f'请先激活银行卡!' return func(*args, **kwargs) return inner def outter(tag=None): if tag == 'get': def outer(func): def inner(*args, **kwargs): balance = input('请输入取款金额:>>>').strip() if not balance.isdigit(): return False, '请输入数字!' if int(balance) > int(login_auth_dict['balance']): return False, '余额不足!' bank_id = input('请输入你的银行卡号:>>>').strip() if not bank_id.isdigit(): return False, '请输入数字!' if len(bank_id) != 6: return False, '银行卡号必须是6位数!' if bank_id != login_auth_dict['bank_id']: return False, '银行卡号不正确!' bank_pwd = input('请输入你的银行卡密码:>>>').strip() if not bank_pwd.isdigit(): return False, '请输入数字!' if len(bank_pwd) != 3: return False, '密码必须是3位数!' if bank_pwd != login_auth_dict['bank_pwd']: return False, '密码不正确!' return func(balance=balance, bank_id=bank_id, bank_pwd=bank_pwd, *args, **kwargs) return inner return outer elif tag == 'add': def outtter(func): def inner(*args, **kwargs): balance = input('请输入存款金额:>>>').strip() if not balance.isdigit(): return False, '请输入数字!' bank_id = input('请输入你的银行卡号:>>>').strip() if bank_id != login_auth_dict['bank_id']: return False, '银行卡号不正确!' if not bank_id.isdigit(): return False, '请输入数字!' if len(bank_id) != 6: return False, '银行卡号必须是6位数!' bank_pwd = input('请输入你的银行卡密码:>>>').strip() if bank_pwd != login_auth_dict['bank_pwd']: return False, '密码不正确!' if not bank_pwd.isdigit(): return False, '请输入数字!' if len(bank_pwd) != 3: return False, '密码必须是3位数!' return func(balance=balance, bank_id=bank_id, bank_pwd=bank_pwd, *args, **kwargs) return inner return outtter @login_auth @outter(tag='get') def get_balance(**kwargs): balance = kwargs.get('balance') bank_id = kwargs.get('bank_id') bank_pwd = kwargs.get('bank_pwd') username = login_auth_dict["username"] res = int(login_auth_dict['balance']) - int(balance) login_auth_dict['balance'] = str(res) bankdata = create_data_format(username=username, bank_id=bank_id, bank_pwd=bank_pwd, res=str(res)) save_data(path=f'{username}_bank.txt', data=bankdata) bank_log_data = create_data_format(tag='flow', username=username, msg=f'取款{balance}元 剩余余额{res}元!') save_data(path=f'{username}_log.txt', data=bank_log_data) save_data(path=f'{username}_flow.txt', data=bank_log_data) return True, bank_log_data # 存款 @login_auth @outter(tag='add') def add_balance(*args, **kwargs): username = login_auth_dict["username"] balance = kwargs.get('balance') bank_id = kwargs.get('bank_id') bank_pwd = kwargs.get('bank_pwd') res = int(login_auth_dict['balance']) + int(balance) login_auth_dict['balance'] = str(res) data1 = create_data_format(username=username, bank_id=bank_id, bank_pwd=bank_pwd, res=str(res)) save_data(path=f'{username}_bank.txt', data=data1) bank_log_data = create_data_format(tag='flow', username=username, msg=f'存款{balance}元 剩余余额{res}元!') save_data(path=f'{username}_log.txt', data=bank_log_data) save_data(path=f'{username}_flow.txt', data=bank_log_data) return True, bank_log_data def is_admin(func): def inner(*args,**kwargs): if login_auth_dict['is_admin'] == 'normal': return False,f'只有管理员才能转账!' return func(*args,**kwargs) return inner # 转账 @login_auth @is_admin def transfer_balance(): target_username = input('请输入对方的用户名:>>>').strip() target_user_data = read_data(path=f'{target_username}_bank.txt',tag='transfer') if target_user_data is None: return False, f'{target_username}不存在!' target_user_data['username'] = target_username target_user_data['bank_id'] = target_user_data.get('bank_id') bank_id = target_user_data['bank_id'] bank_pwd = target_user_data['bank_pwd'] username=login_auth_dict['username'] if not target_user_data['username']: return False,f'{target_username}不存在!' transfer_money=input('请输入转账金额:>>>').strip() if not transfer_money.isdigit(): return False,f'请输入数字!' transfer_money=int(transfer_money) if transfer_money <= 0: return False, '转账金额必须大于0!' if int(transfer_money) > int(login_auth_dict['balance']): return False,f'余额不足!' transfer_pwd=input('请输入你的银行密码:>>>').strip() if transfer_pwd != login_auth_dict['bank_pwd']: return False,'密码错误!' login_auth_dict['balance'] = int(login_auth_dict['balance']) - transfer_money res =login_auth_dict['balance'] bank_log_data = create_data_format(tag='flow', username=username, msg=f'向 {target_username} 用户 转账{transfer_money}元 剩余金额{res}元!') save_data(path=f'{username}_log.txt', data=bank_log_data) save_data(path=f'{username}_flow.txt', data=bank_log_data) user1_bank_data = create_data_format(username=username, bank_id=bank_id, bank_pwd=bank_pwd, res=str(res)) save_data(path=f'{username}_bank.txt', data=user1_bank_data) target_user_data['balance'] = int(target_user_data['balance']) + transfer_money res1=target_user_data['balance'] bankdata = create_data_format(username=target_username, bank_id=bank_id, bank_pwd=bank_pwd, res1=str(res1)) save_data(path=f'{target_username}_bank.txt', data=bankdata) transfer_log_data = create_data_format(tag='transfer', username=target_username, msg=f'收到转账{transfer_money}元 剩余金额{res1}元!') save_data(path=f'{target_username}_log.txt', data=transfer_log_data) save_data(path=f'{target_username}_flow.txt', data=transfer_log_data) return True,bank_log_data # 激活银行卡 @login_auth def init_bank_info(): bank_id = input('请输入你的银行卡号:>>>').strip() if not bank_id.isdigit(): return False, '请输入数字!' if len(bank_id) != 6: return False, '银行卡号必须是6位数!' bank_pwd = input('请输入你的银行卡密码:>>>').strip() if not bank_pwd.isdigit(): return False, '请输入数字!' if len(bank_pwd) != 3: return False, '密码必须是3位数!' data = login_auth_dict["username"] login_auth_dict['bank_id'] = bank_id login_auth_dict['bank_pwd'] = bank_pwd login_auth_dict['balance'] = '1000' bank_log_data = create_data_format(tag='flow', username=data, msg=f'初始化银行卡成功! 当前余额{login_auth_dict["balance"]} 元') save_data(path=f'{data}_flow.txt', data=bank_log_data) save_data(path=f'{data}_log.txt', data=bank_log_data) bank_data = create_data_format(username=data, bank_id=bank_id, bank_pwd=bank_pwd, balance=login_auth_dict['balance']) save_data(path=f'{data}_bank.txt', data=bank_data) return True, bank_log_data
【4】db
-
存放数据与数据处理层代码
- bank_data
- user_data
- db_hander.py
# author : heart # blog_url : https://www.cnblogs.com/ssrheart/ # time : 2023/12/19 import functools import os from conf import * def create_path_format(path): # 用户名和密码: user_pwd.txt --- > db/user_data/user_pwd.txt if 'pwd' in path: path = os.path.join(USER_DATA, path) # 银行信息: username_bank.txt --- > db/bank_data/username_bank.txt elif 'bank' in path: path = os.path.join(BANK_DATA, path) # 日志信息: username_log.txt --- > log/user_log/username_log.txt elif 'log' in path: path = os.path.join(USER_LOG, path) # 流水信息: username_flow.txt --- > log/flow_log/username_flow.txt elif 'flow' in path: path = os.path.join(FLOW_LOG, path) else: return False, f'当前参数错误' return path def save_data(tag=None, path=None, data=None): # (1)保存文件的路径及文件名 path = create_path_format(path) with open(path, mode='a', encoding='utf-8') as f: f.write(data + "\n") def read_data(tag=None, path=None): user_pwd_dict = {} user_bank_dict = {} user_flow_list = [] user_log_list = [] path = create_path_format(path) if not os.path.exists(path): return None with open(path, 'r', encoding='utf-8') as f: data = f.read() data_list = data.split('\n') data_list.pop() if tag == 'login': for data in data_list: username, password, role = data.split('|') user_pwd_dict[username] = {'password': password, 'role': role} if tag == 'info' or tag == 'transfer': for data in data_list: username, bank_id, bank_pwd, balance = data.split('|') user_bank_dict = {'username': username, 'bank_id': bank_id, 'bank_pwd': bank_pwd, 'balance': balance} return user_bank_dict if tag == 'flow': for data in data_list: user_flow_list.append(data) return user_flow_list if tag == 'log': for data in data_list: user_log_list.append(data) return user_log_list return user_pwd_dict
【5】lib
- 公共方法文件common
# author : heart
# blog_url : https://www.cnblogs.com/ssrheart/
# time : 2023/12/19
import time
def create_data_format(tag=None,**kwargs):
data = '|'.join(kwargs.values())
if tag == 'log' or tag =='flow':
data = f'当前用户 {kwargs.get("username")} 于 {time.strftime("%x %X")} :>>>>{kwargs.get("msg")}'
if tag =='transfer':
data = f'当前用户 {kwargs.get("username")} 于 {time.strftime("%x %X")} :>>>>{kwargs.get("msg")}'
return data
【6】log
- 日志文件
- user_log
- flow_log