ATM项目实战

  1. 项目需求分析:
  2. 1.注册(密码要加密)
  3. 2.登陆
  4. 3.查看余额
  5. 4.提现(可自定手续费)
  6. 5.还款
  7. 6.转账
  8. 7.查看流水
  9. 8.添加购物车功能 (商品可配置)
  10. 9.查看购物车功能
  11. 10.结算购物车功能
  12. 11.管理员功能 (可添加账户,冻结账户)
  13. 12.项目日志,纪录用户 登录 注册 等操作时间

注册功能

  1. 1.创立项目开发目录规范
  2. 2.在用户交互层 core - src 文件中 创立 选择功能字典 run( )
  3. 3. bin - start文件中 调用开始函数 run( )
  4. if __name__ == '__main__':
  5. from core import src
  6. src.run()
  7. 4.开始编写第一个功能模块 注册 ,在用户交互层获取 用户名和密码,并在该层判断 2次输入密码是否一致,如果一致则调用注册接口 传入 用户名/密码参数
  8. name = input('请输入用户名').strip()
  9. password = input('请输入密码').strip()
  10. password1 = input('请再次输入密码').strip()
  11. if password == password1:
  12. password = common.hashl(password)
  13. flag, msg = user.register_api(name, password)
  14. print(msg)
  15. else:
  16. print('两次密码输入不一致')
  17. 5.编写加密模块放入公共组建中 common 在注册中使用 密码改为密文传入注册接口
  18. def hashl(msg):
  19. md5 = hashlib.md5()
  20. md5.update(msg.encode('utf8'))
  21. md5 = md5.hexdigest()
  22. return md5
  23. 6.在接口文件中 编写注册接口 收到传参创建用户字典,并存入db文件中用户信息json文件。
  24. name_dict = {'name': name, 'psd': password, 'balance': 1000, 'car': {}, 'state': True}
  25. if handle.select(name):
  26. return False, '用户名已存在'
  27. handle.save(name_dict)
  28. return True, f'{name} 注册成功'
  29. 6.存储用户信息属于 数据库层级操作,在handle文件中编写用户储存函数,调用配置文件路径 DB_DIR 完成数据储存
  30. 7.储存用户信息需要用到用户路径,拼接用户路径代码用到db文件夹路径,获取db路径应在配置文件中 setting 编写 DB_DIR
  31. BAST_DIR = os.path.dirname(os.path.dirname(__file__))
  32. DB_DIR = os.path.join(BAST_DIR, 'db')
  33. 8.注册接口中调用用户储存函数 传入用户字典,完成注册
  34. def save(name_dict):
  35. name_dir = os.path.join(settings.DB_DIR, f'{name_dict.get("name")}.json')
  36. with open(name_dir, 'w', encoding='utf8') as f:
  37. json.dump(name_dict, f)
  38. 9.考虑用户注册需要查看用户名是否存在,handle文件中编写用户查询函数,如果有该用户则返回用户字典,如果没有则返回空None
  39. def select(name):
  40. name_dir = os.path.join(settings.DB_DIR, f'{name}.json')
  41. if os.path.exists(name_dir):
  42. with open(name_dir, 'r', encoding='utf8') as f:
  43. name_dict = json.load(f)
  44. return name_dict
  45. 10,注册用户接口,首先判断用户是否存在,如果存在返回 用户名已存在,不存在则完成注册操作
  46. if handle.select(name):
  47. return False, '用户名已存在'

登录功能

  1. 1.在用户交互层获取 用户名和密码,并且调用加密模块函数,把加密后的密码传给登录接口
  2. name = input('请输入用户名').strip()
  3. password = input('请输入密码').strip()
  4. password = common.hashl(password)
  5. flag, msg = user.login_api(name, password)
  6. 2.登录接口 调用 查询用户函数,如果查询用户函数返回空 则代表用户名不存在,结束函数,并把结果返回给 用户交互层 输出
  7. if not handle.select(name):
  8. return False, '用户名不存在'
  9. 3.用变量接收查询函数返回值,返回的是一个用户信息字典,利用该字典中的密码和传来的密码对比,一致则 登录成功 不一致则密码错误
  10. name_dict = handle.select(name)
  11. if password == name_dict.get("psd"):
  12. return True, '登录成功'
  13. else:
  14. return False, '密码错误'

查看余额

1.查看余额归属于资金类功能,接口文件夹创建 bank.py文件

2.选择该功能后直接调用 查看余额接口 用户交互层 只做 返回结果展示

  1. msg = interface.bank.check_balance_api(is_login.get("name"))
  2. print(msg)

3.使用该功能则需要先保证账户是登录状态,并且获取到账户名,不然不知道查看谁的余额哦

4.编写 效验用户登录状态装饰器。由于需要多次使用,所以放在公共组建文件中

  1. def Check_login(func):
  2. def inner(*args, **kwargs):
  3. if src.is_login.get("name"):
  4. res = func(*args, **kwargs)
  5. return res
  6. else:
  7. return '请先登录账户'
  8. src.login()
  9. return inner

5.用户登录后 需要有一个全局变量 记录用户登录,放在用户交互层,所以创建一个字典,用来辨别用户是否登录

  1. is_login = {'name': None}

6.在登录功能内添加,用户登录成功后 全局字典用户登录状态改为已登录

if flag:

  1. is_login["name"] = name

7.装饰器判断全局字典用户登录状态,已登录正常执行 未登录跳转到登录页面

8.装上装饰器,然后调用 查询余额接口 传入 用户姓名数据

  1. @common.Check_login
  2. def check_balance():
  3. msg = interface.bank.check_balance_api(is_login.get("name"))
  4. print(msg)

9.接口内根据姓名 调用查询数据函数,得到用户数据,然后展示用户余额

  1. name_dict = handle.select(name)
  2. money = name_dict.get("balance")
  3. return f'您的账户余额为:{money}'

提现功能

1.用户交互层(src)中获取用户需要提现的金额,并直接判断是否是正确的数字,支持浮点数

  1. number = input('请输入您要提现的金额')
  2. try:
  3. number = float(number)
  4. except Exception:
  5. return '请输入正确的数字'

2.比符合要求的提现金额,连同用户名一起传送给提现接口 withdraw_api(name, number):

  1. else:
  2. msg = interface.bank.withdraw_api(is_login.get("name"),number)
  3. print(msg)

3.提现接口内,调用 handle.select(name) 获取用户数据 ,获取到用户余额

  1. name_dict = handle.select(name)
  2. money = name_dict.get("balance")

4.设置提现手续费,由于手续费可配置,故此放到settigs文件中

  1. WITHDRAW_SERVICE = 0.05 # 提现手续费配置比例 目前为百分之5

5.判断账户余额 是否 大于或等于 提现金额+手续费 不符合直接返回结果

  1. if money < number+withdraw_service:
  2. return f'账目余额不足,账户余额为:{money}'

6.进行将字典中余额 减去 提现金额加手续费 然后保存 提现完成

  1. money = money-number-withdraw_service
  2. name_dict["balance"] = money
  3. handle.save(name_dict)
  4. return f'提现成功,提现金额{number},手续费:{withdraw_service},账户余额:{name_dict.get("balance")}'

还款功能

1.用户交互层(src)中获取用户需要还款的金额

  1. number = input('请输入您要充值的金额')

2.调用还款功能接口 传入还款金额 账户姓名

  1. msg = interface.bank.pay_back_api(is_login.get("name"), number)

3.在接口中判断还款数字输入是否正确 不正确直接返回

  1. try:
  2. number = float(number)
  3. except Exception:
  4. return '请输入正确的数字'

4.正确则获取 用户数据 得到账户余额,账户中加上充值金额,然后再次保留到用户信息 完成充值

  1. else:
  2. name_dict = handle.select(name)
  3. name_dict["balance"] += number
  4. handle.save(name_dict)
  5. return f"充值金额:{number},充值成功

转账功能

1.用户交互层(src)中获取用户需要转账的账户,还有转账的金额,并且判断金额是否正确

  1. other_name = input('请问您需要转账给哪个账户').strip()
  2. other_money = input('请问您需要转账的金额').strip()
  3. try:
  4. other_money = float(other_money)
  5. except Exception:
  6. return '请输入正确的数字'

2.将转账的账户名,和转账金额,还有自己的用户名传给 转账接口

  1. msg = interface.bank.transfer_api(is_login.get("name"),other_name,other_money)
  2. print(msg)

3.首先判断对方用户名是否存在

  1. if not handle.select(other_name):
  2. return '转账账户不存在,请再次核实'

4.配置文件 settings中设置 转账手续费比例

  1. TRANSFER_SERVICE = 0.01 # 转账手续费配置比例 目前为百分之1
  1. 调用函数 拿到自身余额 判断自身账户余额是否够
  1. name_dict = handle.select(my_name)
  2. balance = name_dict.get("balance")
  3. transfer_service = other_money * settings.TRANSFER_SERVICE
  4. if balance < other_money + transfer_service:
  5. return '您的账户余额不足,无法转账'

6.自身账户减去转账金额 加 手续费 对方账户加入金额,并保存

  1. transfer_service = other_money * settings.TRANSFER_SERVICE #手续费
  2. balance = balance - other_money - transfer_service
  3. name_dict["balance"] = balance
  4. handle.save(name_dict)
  5. other_name_dict = handle.select(other_name)
  6. other_name_balance = other_name_dict.get("balance")
  7. other_name_dict["balance"] = other_name_balance + other_money
  8. handle.save(other_name_dict)
  9. return f'转账成功,转账账户:{other_name},转账金额:{other_money},手续费:{other_money * settings.TRANSFER_SERVICE}'

查看流水

1.查看流水,首先在用户注册 构建字典是添加流水记录空列表

  1. name_dict = {'name': name, 'psd': password, 'balance': 1000, 'car': {}, 'state': True,'Check_water':[]}

2.在完成关于余额的操作时添加记录

  1. now_time = time.strftime('%Y-%m-%d %X')
  2. name_dict["Check_water"].append(f'时间:{now_time}----充值金额:{number},充值成功')

3.使用此功能时,调取查看流水接口,传入用户名即可

  1. msg = interface.bank.trading_record_api(is_login.get("name"))

4.接口内获取用户资料 流水内容 返回

  1. name_dict = handle.select(name)
  2. water = name_dict.get("Check_water")
  3. return water

5.判断返回内容是否为空,为空则提示,不为空这循环展示流水结果

  1. if msg:
  2. for i in msg:
  3. print(i)
  4. else:
  5. '暂无流水记录哦'

添加购物车功能

1.选择该功能直接调取 购物车接口 把用户名传过去

  1. interface.shop.add_shop_car(is_login.get("name"))

2.商品信息放入配置文件,在接口中循环打印出来。供用户选择

  1. for num, goods_list in enumerate(settings.goods):
  2. print(f'商品编号:{num + 1} | 商品名称:{goods_list[0]} | 商品单价:{goods_list[1]}')

3.将用户选择的商品信息 放入临时购物车中

  1. number = int(number)
  2. goods_name = settings.goods[choice-1][0]
  3. goods_list1 = [number,settings.goods[choice-1][1]]
  4. if goods_name in new_car:
  5. new_car[goods_name][0] += number
  6. print('商品添加成功')
  7. else:
  8. new_car[goods_name] = goods_list1
  9. print('商品添加成功')

4.当用户退出的时候 读取用户数据,判断购物车中是否有刚刚挑选的商品,如果有就增加数量,没有则新增

  1. choice = input('请挑选的商品>>>(q)退出商城:').strip()
  2. if choice == 'q':
  3. name_dict = handle.select(name)
  4. old_car = name_dict.get("car")
  5. if not new_car:
  6. print('欢迎下次光临')
  7. for goods_name,goods_list in new_car.items():
  8. if goods_name in old_car:
  9. old_car[goods_name][0] += goods_list[0]
  10. print('商品已添加购物车,欢迎下次光临')
  11. name_dict["car"] = old_car
  12. handle.save(name_dict)
  13. break
  14. else:
  15. old_car[goods_name] = goods_list
  16. print('商品已添加购物车,欢迎下次光临')
  17. name_dict["car"] = old_car
  18. handle.save(name_dict)
  19. break

查看购物车功能

1.调用查看购物车接口 还是把名字传进去

  1. msg = interface.shop.pay_shop_car_api(is_login.get("name"))

2.在接口里面拿到 用户真实数据 并且返还出去

  1. name_dict = handle.select(name)
  2. old_car = name_dict.get("car")
  3. return old_car

3.最外层拿到用户购物车数据,循环打印每个商品的名称 数量 金额

  1. if not old_car:
  2. print('购物车空空如也哦')
  3. for goods_name,goods_list in old_car.items():
  4. print(f'商品名:{goods_name},数量:{goods_list[0]},价格:{goods_list[0] * goods_list[1]}')

结算购物车

1.调用结算购物车接口,并把用户名传进去

  1. interface.shop.pay_shop_car_api(is_login.get("name"))

2.拿到用户真实购物车数据 然后计算购物车总价

  1. money = 0
  2. for i,x in old_car.values():
  3. money += i * x

3.判断账户余额

  1. if balance < money:
  2. return '账户余额不足'

4.开始扣除账户余额 并且把 原购物车清空 并且保存

  1. balance = balance - money
  2. name_dict["car"] = {}
  3. name_dict['balance'] = balance
  4. now_time = time.strftime('%Y-%m-%d %X')
  5. name_dict["Check_water"].append(
  6. f'时间:{now_time}----购物成功 | 本次消费{money}/账户余额:{name_dict.get("balance")}')
  7. handle.save(name_dict)
  8. return f'本次消费:{money}元,账户余额为:{name_dict.get("balance")}'

ATM项目的更多相关文章

  1. ATM项目详解

    内容概要: ATM项目 代码实操流程 ATM项目 # 需求: """ - 额度15000或自定义 - 支持多账户登录 - 可以查看账户余额 - 可以提现(可自定义手续费比 ...

  2. day25 ATM项目(第一天)

    项目的说明书 项目:ATM + 购物车 项目需求: 1.额度15000或自定义 --> 注册功能 2.实现购物商城,买东西加入购物车,调用信用卡接口结账 --> 购物功能.支付功能 3.可 ...

  3. 购物车+ATM项目(图形化)

    项目下载 项目目录结构 运行效果 seetings.py import logging import logging.config # 定义日志输出格式 开始 import os standard_f ...

  4. ATM项目开发

    目录 一.项目开发流程 1.项目需求分析: 2.项目架构设计: 3.项目分组开发: 4.项目提交测试: 5.项目交付上线: 二.项目需求分析 1.主题 2.项目核心 3.项目需求: 4.从需求中提炼出 ...

  5. 10月28日内容总结——ATM项目开发流程

    目录 一.项目开发流程 1.项目需求分析: 2.项目架构设计: 3.项目分组开发: 4.项目提交测试: 5.项目交付上线: 二.项目需求分析 1.主题 2.项目核心 3.项目需求: 4.从需求中提炼出 ...

  6. python ATM项目

    1.需求: 指定最大透支额度 可取款 定期还款(每月指定日期还款,如15号) 可存款 定期出账单 支持多用户登陆,用户间转帐 支持多用户 管理员可添加账户.指定用户额度.冻结用户等 购物车: 商品信息 ...

  7. Python基础阶段总结:ATM项目实战

    目录 ATM逻辑描述 三层框架简介 1.第一层(src.py) 2.第二层(interface文件夹下内容) 3.第三层(db_hanlder) 启动函数 用户注册功能 用户登录 common中的小功 ...

  8. ATM购物车项目总结

    目录 项目实现思路 ATM项目 优先实现功能 拆分函数 项目路径展示 项目启动文件 start.py 配置文件 setting.py 日志配置字典 日志函数 展示层 src.py 用户注册 获取用户输 ...

  9. ATM购物车项目 三层架构

    目录 项目开发流程 项目需求 三层架构 (重点) 实际案例 展示层 核心逻辑层 数据处理层 ATM项目 项目开发流程 # 1.项目需求分析 产品经理(客户) 架构师 开发经理 1.架构师 开发经理提前 ...

随机推荐

  1. PostgreSQL 模式(SCHEMA)

    PostgreSQL 模式(SCHEMA)可以看着是一个表的集合. 一个模式可以包含视图.索引.据类型.函数和操作符等. 相同的对象名称可以被用于不同的模式中而不会出现冲突,例如 schema1 和 ...

  2. .NET 反向代理 YARP 跨域请求 CORS

    使用过 nginx 的小伙伴应该都知道,这个中间件是可以设置跨域的,作为今天的主角,同样的 反向代理中间件的 YARP 毫无意外也支持了跨域请求设置. 有些小伙伴可能会问了,怎样才算是跨域呢? 在 H ...

  3. vue3中pinia的使用总结

    pinia的简介和优势: Pinia是Vue生态里Vuex的代替者,一个全新Vue的状态管理库.在Vue3成为正式版以后,尤雨溪强势推荐的项目就是Pinia.那先来看看Pinia比Vuex好的地方,也 ...

  4. 洛谷P4638 SHOI2011 银行 ( 最大流)

    类似题目(一模一样):http://poj.org/problem?id=1149 我这里以poj1149的PIGS为例, 新建源点s和汇点t,n个顾客作为中间的点,,对于每个顾客,他可以解锁一定的猪 ...

  5. ASP.NET Core :中间件系列(三):中间件限流

    中间件 微软官网定义: 中间件 中间件意思就是处理请求和响应的软件: 1.选择是否将请求传递到管道中的下一个组件. 2.可在管道中的下一个组件前后执行工作. 对中间件类 必须 包括以下 具有类型为 R ...

  6. DDD-领域驱动(二)-贫血模型与充血模型

    贫血模型 一般来说 贫血模型:**一个类中只有属性或者成员变量,没有方法 **!例如 DbFirst 从数据库同步实体过来, -- 对于一个系统刚开始的时候会觉得这时候是最舒服的,但是如果后期系统需要 ...

  7. python信息检索实验之向量空间模型与布尔检索

    import numpy as np import pandas as pd import math def bool_retrieval(string): if string.count('and' ...

  8. 27.路由器Routers

    像一些reils这样的web框架提供自动生成urls的功能,但是Django没有 rest framework为django添加了这一功能,以一种简单.快速.一致的方式 routers必须配合view ...

  9. .NET周报【10月第3期 2022-10-25】

    国内文章 聊一聊被 .NET程序员 遗忘的 COM 组件 https://www.cnblogs.com/huangxincheng/p/16799234.html 将Windows编程中经典的COM ...

  10. FileNotFoundError: Could not find module libmxnet.dll

    解决方法:把CUDA的bin目录下的dll文件全部复制到libmxnet.dll所在的目录 问题原因:libmxnet.dll引用了一些CUDA的dll,但是找不到路径.