ATM2.0模块版

发布时间 2023-12-20 18:40:09作者: ssrheart

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