源代码下载地址:
https://download.csdn.net/download/wtt234/64021267
bin/start.py
"""
项目启动入口
"""
import os
import sys
#将项目的根目录,添加到sys.path中2
sys.path.append(os.path.dirname(os.path.dirname(__file__)))
from core import src
if __name__ == '__main__':
src.run()
?2.conf/settings.py
"""
此处存储固定的配置信息
"""
import os
#获取项目根目录xiaoshuoyueduqi根目录
BASE_PATH=os.path.dirname(os.path.dirname(__file__))
#获取db目录路径 xiaoshuoyueduqi/db
DB_PATH=os.path.join(BASE_PATH,'db')
# 获取db.txt的根目录
DB_TXT_PATH= os.path.join(DB_PATH,'db.txt')
#”story_class.txt“文件目录路径
STORY_PATH=os.path.join(DB_PATH,'story_class.txt')
#小说存放目录
FICTION_DIR=os.path.join(DB_PATH,"fictions")
#日志文件的路径
LOG_PATH=os.path.join(BASE_PATH,"log","log.txt")
3. core/src.py
"""
此处存放核心业务逻辑代码
"""
from conf import settings
from db import db_handler
import time
login_user=None #用于标记登录的用户
from lib import common
# 注册功能
def register():
print("注册功能执行中....")
while True:
username=input("请输入用户名:").strip()
#1)先校验用户是否存在
#1)涉及数据的操作:调用查看数据功能----select
#1)给select函数传输当前输入的用户名,用于判断该用户是否存在
#user_data--->[user,pwd,bal] or None
user_data=db_handler.select(username)
#若存在,让用户重新输入
if user_data:
print("当前输入的用户已经存在,请重新输入!")
continue
password=input("请输入密码:").strip()
re_password=input("请确认密码:").strip()
#两次密码是否一致校验
if password==re_password:
# 保存数据
db_handler.save(username,password)
print(f"用户{username}注册成功!")
break
else:
print("两次密码不一致,请重新输入!")
# 登录功能
def login():
print("登录功能执行中...")
while True:
username=input("请输入用户名(输入q退出:)").strip()
#1)查看当前用户是否存在[user,pwd,balance] or None
user_data=db_handler.select(username)
#2)若不存在,让用户重新输入
if not user_data:
print("当前输入的用户不存在,请重新输入!")
continue
password=input("请输入密码:").strip()
#3)校验用户输入的密码是否与db.txt中密码一致
if password==user_data[1]: #[user,pwd,balance],数据格式
#4)用户登录后记录登录状态
global login_user
login_user=username
print(f'用户[{username}]登录成功!')
return
else:
print("输入密码不正确,请重新输入!")
# return
# 充值功能
@common.login_auth
def recharge():
print("充值功能执行中...")
while True:
#1)让用户输入充值金额
balance=input("请输入充值金额:").strip()
#2)判断用户输入的金额是否是数字
if not balance.isdigit():
print("请输入数字!")
continue
balance=int(balance)
#3)修改当前用户的金额
#3.1)获取当前用户的数据
user,pwd,bal=db_handler.select(login_user)
#3.2)先获取用户“修改前”数据
old_data=f"{user}:{pwd}:{bal}"
#3.3)修改当前用户金额,做加钱操作
bal=int(bal)
bal+=balance
#'tom:123456:100"---->tom:123456:100100"
#3.4)拼接“修改”后数的当前用户数据
#此时的bal的值已经被修改
new_data=f"{user}:{pwd}:{bal}"
#3.5)调用修改数据功能
db_handler.update(old_data,new_data)
print(f"当前用户:[{login_user}]充值金额[[{balance}元,成功!]")
#3.6)做记录日志功能
now_time=time.strftime("%Y-%m-%d %X")
log_data=f"时间:{now_time} 用户名:{login_user}充值金额:{balance}"
print(log_data) # 打印下日志
common.append_log(log_data)
break
# 小说阅读功能
@common.login_auth
def reader():
#2.先将”story_class.txt“文件中数据,获取出来,解析成字典类型
story_dic=db_handler.get_all_story()
#判断”story_class.txt“文件是否有小说数据
if not story_dic:
print("没有小说,请联系管理员上传相应文件~~")
return
while True:
#1)打印小说种类选择信息
print("""
========欢迎来到小说阅读功能主页============
0.玄幻小说
1.都市小说
2.IT技术书籍
===============END========================
""")
#2)让用户输入小说类型编号
choice1=input("请输入小说类型编号:").strip()
#3)判断当前用户选择的编号是否存在
#若输入有误,重新输入
if choice1 not in story_dic:
print("输入有误,请重新输入!!!")
continue
#4)获取当前小说类型中的所有小说数据
#4)获取当前小说类型中的所有小说数据 choice1=="1"
# "1": {
# "0:": ["城南故事.txt", 6],
# "1:": ["小城古过去.txt", 10]
#
# },
fiction_dic=story_dic.get(choice1)
#5)打印当前所有类型的所有小说,让用户选择
for number,fiction_list in fiction_dic.items():
name,price=fiction_list
print(f"小说编号:[{number}],小说名字[{name}],小说价格:[{price}]")
#6)让用户选择需要购买的小说
while True:
choice2=input("请输入购买的小说编号:").strip()
if choice2 not in fiction_dic:
print("输入有误,请重新输入!!!")
continue
#["城南故事.txt", 6]
name,price=fiction_dic.get(choice2)
#7)让用户输入y选择是否购买商品
choice3=input(f"当前选择的小说名为:[{name}],商品单价为:[{price}],请输入'y'购买,或者:")
#8)判断用户输入的是否是y
if choice3=="y":
#9)校验当前用户的金额是否>=小说单价
#9.1获取当前用户金额
user,pwd,bal=db_handler.select(login_user)
#9.2判断金额
bal=int(bal)
#小说单价
price=int(price)
if bal<price:
print("金额不足,请先充值!!!")
break
#10)开始扣费
#10)拼接用户修改前的数据
old_data=f"{user}:{pwd}:{bal}"
#10.2开始对用户金额做减
#)拼接用户修改后的数据
new_data=f"{user}:{pwd}:{bal}"
db_handler.update(old_data,new_data)
print("当前小说购买成功,自动打开小说阅读~~")
#11.调用获取小说详细数据信息
fiction_data=db_handler.show_fiction_data(name)
print(f"""
=======当前小说内容如下=========
{fiction_data}
============END================
""")
#12)记录购买成功日志
# 做记录日志功能
now_time = time.strftime("%Y-%m-%d %X")
log_data = f"时间:{now_time} 用户名:{login_user}购买金额:{price}"
print(log_data) #打印下日志
common.append_log(log_data)
break
break
# 函数字典
func_dic = {
'0': register,
'1': login,
'2': recharge,
'3': reader,
}
def run():
"""
0 账户注册
1 账户登录
2 充值功能
3 阅读小说
"""
while True:
print("""
========小说阅读器欢迎========
0 账户注册
1 账户登录
2 充值功能
3 阅读小说
=============END=============
""")
# choice--->'1'
choice = input("请输入功能编号(提示:[输入q退出]):").strip()
if choice=='q':
break
# 判断用户输入的编号是否在函数字典中
if choice not in func_dic:
print("当前账号有误,请重新输入!")
continue
# func_dic.get("1")()--->register函数对象-------->regiister()
func_dic.get(choice)()
4.db/fictions [小说文件]
4.1db.txt
4.2db.hanler.py
"""
用于存储操作数据代码
"""
import os
from conf import settings
#查看数据
def select(username):
with open(settings.DB_TXT_PATH,'r',encoding='utf-8')as f:
#获取db.txt文件中的每一行数据
for line in f:
#在每一行汇总,判断接收过来的用户名是否存在db.txt中
#数据存储格式:tom:123456:99999999
#数据存储格式:姓名:密码:金额
if username in line:
#若用户存在,则在当前行中提取该用户的所有数据
#user_data--->[user,pwd,balace]
user_data=line.strip().split(":")
return user_data #返回一个列表 [user,pwd,balace]
#保存数据
# 保存数据格式"tom:123456:99999“
# 保存数据格式"用户名:密码:初始金额“
def save(username,password,balance=0):
with open(settings.DB_TXT_PATH,'a',encoding='utf-8')as f:
f.write(f"{username}:{password}:{balance}\n")
#更新数据
def update(old_data,new_data):
"""
将旧数据old——data,替换为新数据new_data
"""
#1)拼接新的文件路径
new_path=os.path.join(settings.DB_PATH,'new.txt')
#2)读取源文件db.txt中数据进行修改,写入到新文件new.txt文件中,再更名为db.txt
with open(settings.DB_TXT_PATH,"r",encoding="utf-8")as r_f,open(new_path,"w",encoding="utf-8")as w_f:
#2.1新旧数据替换
all_user_data=r_f.read()
all_user_data=all_user_data.replace(old_data,new_data)
#2.2)将新数据写入新文件中
w_f.write(all_user_data)
#2.3文件名的修改"new.txt--->db.txt"
os.remove(settings.DB_TXT_PATH)
os.rename(new_path,settings.DB_TXT_PATH) #把‘new.txt--->db.txt"修改为
# os.remove(new_path) #删除’new.txt“文件
#获取小说字典数据
#”story_class.txt“中的字典数据
def get_all_story():
with open(settings.STORY_PATH,"r",encoding="utf-8")as f:
story_dic=eval(f.read())
return story_dic
# 查看单本小说
def show_fiction_data(fiction_name):
#获取小说路径
fiction_path=os.path.join(settings.FICTION_DIR,fiction_name)
#打开文件,获取文件数据,并返回给用户展示
with open(fiction_path,"r",encoding="utf-8")as f:
fiction_data=f.read()
return fiction_data
4.3 story_class.txt
{
"0":{
"0":["倚天屠龙记.txt",3],
"1":["射雕英雄传.txt",10]
},
"1":{
"0":["城南故事.txt",6],
"1":["小城古过去.txt",10]
},
"2":{
"0":["java.txt",3],
"1":["python.txt",10]
},
}
5.lib/common.py
"""
存储存放公共功能
"""
from conf import settings
# 登录认证装饰器
def login_auth(func):
#在这里导入,解决循环导入的问题
from core import src
def inner(*args,**kwargs):
if src.login_user:
res=func(*args,**kwargs)
return res
else:
print("未登录,不允许使用特殊功能,请先登录~")
src.login()
return inner
#记录日志,应该存放在公共功能中。
def append_log(log_data):
with open(settings.LOG_PATH,"a",encoding="utf-8")as f:
f.write(log_data+"\n")
6.log/log.txt
时间:2021-12-15 17:28:58 用户名:tom充值金额:10000000
时间:2021-12-15 17:29:17 用户名:tom购买金额:3
7.readme.txt
-软件的使用规范
-bin
-start---->启动软件入口
-conf
-setting.py 配置文件
-core
-src 核心业务逻辑代码
-db ---->用于存储数据文件与操作数据的代码文件
-db_file ---->db.txt
-db_handler---操作数据的代码
-lib
-common:存放公共的功能
-log
-log.txt 存放日志的文件
--------------------------------
程序实现功能:
0 账户注册
1 账户登录
2 充值功能
3 阅读小说
-----------------------------------
---------书籍的目录结构-------------
”story_class.txt“
存放类别与小说文件路径,读取出来可用eval反解除字典来
-------------------
用户登录成功后显示如下内容:
“
0.玄幻小说
1.都市小说
2.IT技术书籍
”
------------------
步骤:
用户输入具体的小说编号,提示是否付费,用户输入‘y’后,扣费并显示书籍内容,如果余额不足提示“余额不足”
------------------
{
"0":{
"0:":["倚天屠龙记.txt",3],
"1:":["射雕英雄传.txt",10]
},
"1":{
"0:":["城南故事.txt",6],
"1:":["小城古过去.txt",10]
},
"2":{
"0:":["java.txt",3],
"1:":["python.txt",10]
},
}
----------------------
----------------------
8.目录结构图片
|