一个项目从无到有:
1、需求分析
注册/登录用户接口 ---> 注册功能
实现购物商城,买东西加入 购物车,调用 购物车 结账 ----> 购物功能、支付功能
可以提现,手续费5% ---> 提现功能
支持多账户登录 ---> 登录功能
支持账户间转账 ---> 转账功能
记录消费流水 ---> 记录流水功能
提供充值接口 --->充值功能
记录程序操作日志 ---> 记录日志功能
用户认证用装饰器 ---> 登录认证装饰器‘
2、程序的架构设计(需要关注)
- 三层架构(*******)
- 视图层: 专门用于与用户交互;
- 展示功能给用户看、接收用户输入的数据、将功能返回的结果展示给用户看的;
- 接口层: 专门做业务逻辑的处理;
- 接收到用户输入的数据,进行逻辑判断,然后返回判断后的结果给视图层;
- 数据层: 专门做数据的处理
- 增加数据
- 删除数据
- 更新数据
- 查看数据
3、分任务开发 (本项目没有)
- 项目经理:(项目的负责人)
- UI(1-2人): 界面设计(app端的界面/web界面)。
- 前端(1-2人): 拿到UI的设计图纸,开发页面。
- 后端(2-3人): 开发业务逻辑
- 运维(1人): 拿到开发好的代码,部署再 “服务器” 中,上线运行
程序文件存放说明
bin\start.py
from core import src
src.run()
conf\setting.py 找到当前文件根目录,添加到环境变量
import os
import sys
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
sys.path.append(BASE_DIR)
core\src.py 在用户界面显示的程序,可以选择操作,输入输出数据。
import time
import json
from db.dbhandle import *
from lib.common import *
from conf.setting import *
from interface.user_interface import *
from interface.bank_interface import *
from interface.shop_interface import *
cur_user = None
@logger
def register():
while True:
# 输入账户,密码
username = input('请输入注册账户名:')
psw = input('设置账户密码:')
psw2 = input('请再输入一次密码:')
if psw != psw2:
print('两次密码不同,重新输入!')
continue
tag = register_inter(username, psw)
if tag:
print(f'用户{username}注册成功!')
time_now = time.strftime("%Y-%m-%d %H:%M:%S")
log_info = f"{time_now},用户{username}注册成功,密码为:{psw}"
return log_info
else:
print('用户已经存在,请重新注册!')
@logger
def login():
count = 0
while True:
username = input('输入用户名:')
psw = input('输入密码:')
tag = login_inter(username, psw)
if tag:
global cur_user
cur_user = username
time_now = time.strftime("%Y-%m-%d %H:%M:%S")
log_info = f"{time_now},用户{cur_user}登录"
return log_info
else:
if count == 2:
print('错误次数过多,系统关闭')
break
count += 1
continue
# 3 查看余额
@logger
@check_user
def check_bal():
check_bal_inter(cur_user)
time_now = time.strftime("%Y-%m-%d %H:%M:%S")
log_info = f"{time_now},用户{cur_user}查询了余额"
return log_info
# 4 转账
@logger
@check_user
def transfer():
while True:
target_user = input('输入目标账户:')
trans_amount = float(input('输入转账金额:'))
tag = transfer_inter(cur_user, target_user, trans_amount)
if tag:
time_now = time.strftime("%Y-%m-%d %H:%M:%S")
log_info = f"{time_now},用户{cur_user}给{target_user}转帐{trans_amount}元"
return log_info
else:
continue
# 5 充值
@logger
@check_user
def recharge():
charge_amount = float(input('输入充值金额:'))
recharge_inter(cur_user, charge_amount)
time_now = time.strftime("%Y-%m-%d %H:%M:%S")
log_info = f"{time_now},用户{cur_user}充值了{charge_amount}元"
return log_info
# 6 提现
@logger
@check_user
def withdraw():
withdraw_amount = float(input('输入提现金额(提现有5%手续费):'))
time_now = time.strftime("%Y-%m-%d %H:%M:%S")
tag = withdraw_inter(cur_user, withdraw_amount)
if tag:
log_info = f"{time_now},用户{cur_user}提现了{withdraw_amount}元"
return log_info
else:
return
# 7 查看流水
@logger
@check_user
def check_flow():
check_flow_inter(cur_user)
time_now = time.strftime("%Y-%m-%d %H:%M:%S")
log_info = f"{time_now},用户{cur_user}查看了账单流水"
return log_info
# 8 购物
@logger
@check_user
def shopping():
user_pro_dic = {}
product_dic = {
'macbook': 9989.88,
'surfacebook': 11999.00,
'matebook': 7899.99,
'yoga': 4388.89,
'xps': 8679.97,
}
print('现有五款笔记本在售:')
for i in product_dic:
print(f"{i.title()}------{product_dic[i]}元")
while True:
choice = input('继续购物请按任意键,退出请按0:')
if choice != '0':
buy_name = input('输入想要的商品名:').strip(' ').lower()
buy_number = eval(input('输入产品数量:'))
if buy_name not in product_dic:
print('商品名称有误,重新输入!')
continue
if type(buy_number) is not int:
print('数量有误,请输入整数!')
continue
shopping_inter(cur_user, product_dic, buy_name, buy_number)
time_now = time.strftime("%Y-%m-%d %H:%M:%S")
log_info = f"{time_now},用户{cur_user},添加了{buy_number}台{buy_name}到购物车"
return log_info
else:
print('欢迎下次光临!')
return
# 9 查看购物车
@logger
@check_user
def check_cart():
total_price = check_cart_inter(cur_user)
time_now = time.strftime("%Y-%m-%d %H:%M:%S")
log_info = f'{time_now},用户{cur_user},支付了{total_price}'
return log_info
# 10 退出用户
@logger
def logout():
global cur_user
if cur_user is None:
print('当前无用户登录。')
return
time_now = time.strftime("%Y-%m-%d %H:%M:%S")
log_info = f'{time_now},用户{cur_user}退出登录'
print(f'用户{cur_user}退出成功!')
cur_user = None
return log_info
func_dic = {
'1': [register, '注册'],
'2': [login, '登录'],
'3': [check_bal, '查询'],
'4': [transfer, '转账'],
'5': [recharge, '充值'],
'6': [withdraw, '提现'],
'7': [check_flow, '账单流水'],
'8': [shopping, '购物'],
'9': [check_cart, '查看购物车'],
'10': [logout, '切换用户']
}
def run():
while True:
print("==" * 16)
print('欢迎来到挖土笔记本商城,选择你的操作:')
print('0------退出')
for k in func_dic:
print(f'{k}------{func_dic[k][1]}')
print(' ')
cmd = input('请输入操作编号:')
print('=' * 16)
if cmd == '0':
print('系统关闭')
break
if cmd in func_dic:
func_dic[cmd][0]()
else:
print('操作编号有误, 请重新输入!')
db\db_handle.py 处理数据的程序,可以存/取数据。
from conf.setting import *
import json
def show_info(username):
user_file_path = os.path.join(BASE_DIR, 'db', '%s.json' % username)
if os.path.exists(user_file_path):
with open(user_file_path, 'r', encoding='utf-8') as file:
user_info = json.load(file)
return user_info
def save(user_info):
user_file_path = os.path.join(BASE_DIR, 'db', '%s.json' % user_info['name'])
with open(user_file_path, 'w', encoding='utf-8') as file:
json.dump(user_info, file, ensure_ascii=False)
file.flush()
db\jack.json 示例一个用户数据文件,json格式,可存放用户名,密码,余额,购物车,银行流水,锁定状态
{
"name": "jack",
"psw": "123",
"balance": 572138.63,
"cart": [
{
"pro_name": "macbook",
"price": 9989.88,
"number": 3
},
{
"pro_name": "yoga",
"price": 4388.89,
"number": 2
},
{
"pro_name": "matebook",
"price": 7899.99,
"number": 1
}
],
"bank_flow": [
"2020-07-26 09:31:32,向pinkman转账1300.0元",
"2020-07-26 09:32:07, 提现了1000.0元",
"2020-07-26 09:34:49,向pinkman转账3320.0元",
"2020-07-26 09:34:59, 提现了889.0元",
"2020-07-26 09:35:12, 提现了1000.0元",
"2020-07-26 09:35:21, 提现了123.0元",
"2020-07-26 09:55:06,向pinkman转账1333.0元",
"2020-07-26 10:05:21,向pinkman转账220.0元",
"2020-07-26 10:06:00, 充值了1000.0元",
"2020-07-26 11:20:03,向pinkman转账13.0元",
"2020-07-26 14:45:39, 充值了10000.0元",
"2020-07-26 15:01:14,向morty转账40000.0元",
"2020-07-27 11:55:51,向pinkman转账7277.0元",
"2020-07-27 11:58:59, 充值了10000.0元",
"2020-07-27 15:22:06,向pinkman转账123.0元",
"2020-07-27 15:59:38,向pinkman转账10000.0元",
"2020-07-27 16:11:26, 充值了11000.0元",
"2020-07-28 11:47:37, 支付了102616.08元,余额为598178.54元"
],
"locked": false
}
interface\bank_interface.py 银行的接口 用来处理转账、充值、提现
from db.dbhandle import *
import time
def transfer_inter(cur_user, target_user, trans_amount):
tar_user_info = show_info(target_user)
if tar_user_info:
tar_user_info['balance'] += trans_amount
time_now = time.strftime("%Y-%m-%d %H:%M:%S")
user_info = show_info(cur_user)
if user_info['balance'] >= trans_amount:
flow_info = '%s,收到%s转账%s元' % (time_now, cur_user, trans_amount)
tar_user_info['bank_flow'].append(flow_info)
save(tar_user_info)
flow_info = '%s,向%s转账%s元' % (time_now, target_user, trans_amount)
user_info['bank_flow'].append(flow_info)
user_info['balance'] -= trans_amount
save(user_info)
print(f"转账成功,当前余额为{user_info['balance']}")
return True
else:
print(f"余额不足,当前余额为{user_info['balance']},请充值")
return True
else:
print('目标账户不存在,请重试!')
return False
def recharge_inter(cur_user, charge_amount):
user_info = show_info(cur_user)
time_now = time.strftime("%Y-%m-%d %H:%M:%S")
flow_info = f'{time_now}, 充值了{charge_amount}元'
user_info['bank_flow'].append(flow_info)
user_info['balance'] += charge_amount
save(user_info)
print(f"充值成功!当前余额为{user_info['balance']}")
def withdraw_inter(cur_user, withdraw_amount):
user_info = show_info(cur_user)
if user_info['balance'] >= 1.05 * withdraw_amount:
time_now = time.strftime("%Y-%m-%d %H:%M:%S")
flow_info = f'{time_now}, 提现了{withdraw_amount}元'
user_info['bank_flow'].append(flow_info)
user_info['balance'] -= 1.05 * withdraw_amount
save(user_info)
print(f"提现成功!当前余额为{user_info['balance']}")
return True
else:
print('余额不足,无法提现。')
return False
interface\shopping_interface.py 购物接口,有添加商品到购物车和结算功能。
from db.dbhandle import *
import time
def shopping_inter(cur_user, product_dic, buy_name, buy_number):
user_pro_dic = {}
user_info = show_info(cur_user)
for i in user_info['cart']:
if buy_name == i['pro_name']:
i['number'] += buy_number
print('添加购物车成功!')
save(user_info)
return True
else:
user_pro_dic['pro_name'] = buy_name
user_pro_dic['price'] = product_dic[buy_name]
user_pro_dic['number'] = buy_number
user_info['cart'].append(user_pro_dic)
print('添加购物车成功!')
save(user_info)
def check_cart_inter(cur_user):
total_price = 0
user_info = show_info(cur_user)
user_bal = user_info['balance']
print('您的购物车中有:')
for i in user_info['cart']:
print(f"商品:{i['pro_name']},单价:{i['price']},数量:{i['number']}")
total_price += i['number'] * i['price']
cmd = input('是否支付,支付请按任意键,退出请按0:')
if cmd == '0':
return
if user_bal < total_price:
print('余额不足,请充值!')
return
user_info['balance'] -= total_price
user_info['cart'].clear()
time_now = time.strftime("%Y-%m-%d %H:%M:%S")
shop_info = f"{time_now}, 支付了{total_price}元,余额为{user_info['balance']}元"
user_info['bank_flow'].append(shop_info)
print(f"支付成功,当前余额为{user_info['balance']},欢迎下次光临!")
save(user_info)
return total_price
interface\user_interface.py 用户接口,用于注册登录,查询余额、流水
from db.dbhandle import *
import time
def register_inter(username, psw):
user_info = show_info(username)
if user_info:
return False
# 如果不存在,组织用户数据
else:
user_info = {
'name': username,
'psw': psw,
'balance': 0,
'cart': [],
'bank_flow': [],
'locked': False
}
save(user_info)
return True
def login_inter(username, psw):
user_info = show_info(username)
if not user_info:
print(f'用户{username}不存在呀,重新输入!')
return False
else:
if psw != user_info['psw']:
print('密码不正确请重试!')
# print(user_count)
return False
else:
print(f'用户{username}登入成功!')
return True
def check_bal_inter(username):
user_info = show_info(username)
balance = user_info['balance']
print(f'用户{username}的余额是{balance}元')
def check_flow_inter(cur_user):
user_info = show_info(cur_user)
for i in user_info['bank_flow']:
print(i)
lib\common.py 通用的方法,一般为装饰器,这里放了认证装饰器和日志装饰器
from conf.setting import *
def check_user(func):
def wrapper(*args, **kwargs):
from core.src import cur_user
if cur_user == None:
print('请登录!')
return
else:
print(f'当前用户{cur_user}')
res = func(*args, **kwargs)
return res
return wrapper
def logger(func):
def wrapper(*args, **kwargs):
log_path = os.path.join(BASE_DIR, 'log', 'access.log')
# log_path = r'/Users/moyan/PycharmProjects/Shopping/log/access.log'
res = func(*args, **kwargs)
if res is not None:
with open(log_path, 'at', encoding='utf-8') as file:
file.write(res + '\n')
return res
return wrapper
log\access.log
2020-07-26 10:22:11,用户jack登录
2020-07-26 10:22:16,用户jack查询了余额
2020-07-26 10:22:16,用户jack查询了余额
2020-07-26 10:22:17,用户jack查询了余额
2020-07-26 10:25:25,用户jack登录
2020-07-26 10:25:28,用户jack退出登录
2020-07-26 10:26:59,用户jack登录
2020-07-26 10:34:41,用户rick注册成功,密码为:123
2020-07-26 10:34:52,用户rick登录
2020-07-26 10:34:54,用户rick查询了余额
2020-07-26 10:35:17,用户rick充值了1000000.0元
2020-07-26 10:35:20,用户rick查询了余额
2020-07-26 10:35:24,用户rick退出登录
2020-07-26 10:36:25,用户jack登录
2020-07-26 10:36:27,用户jack查询了余额
2020-07-26 10:36:32,用户jack查看了账单流水
2020-07-26 11:08:12,用户iris注册成功,密码为:123
2020-07-26 11:19:53,用户jack登录
2020-07-26 11:19:56,用户jack查询了余额
2020-07-26 11:20:03,用户jack给pinkman转帐13.0元
2020-07-26 14:45:24,用户jack登录
2020-07-26 14:45:31,用户jack查询了余额
2020-07-26 14:45:32,用户jack查询了余额
2020-07-26 14:45:39,用户jack充值了10000.0元
2020-07-26 14:55:43,用户jack登录