feat(project): 初始化项目结构和配置

- 添加.gitignore和.flaskenv环境配置文件
- 创建Flask应用基础架构,包括models、services、utils模块
- 配置数据库模型User和Setting,集成SQLAlchemy和Alembic迁移
- 添加前端Vue项目结构,包含Element Plus组件库
- 配置前后端API路由和蓝prints模块
- 实现书籍下载服务BookService功能模块
- 添加代码规范配置.editorconfig、.oxfmtrc.json、.oxlintrc.json
- 配置VSCode推荐插件和前端构建工具链
- 实现文件服务FileService和相关业务逻辑
This commit is contained in:
2026-04-19 15:43:45 +08:00
parent b9fad6344f
commit ade1b6c9b0
63 changed files with 9610 additions and 1 deletions
+106
View File
@@ -0,0 +1,106 @@
import json
import time
import ctypes
from collections import defaultdict
from typing import List
from datetime import datetime
from functools import cmp_to_key
def windows_sort_unicode(items: List[str]) -> List[str]:
"""
使用Windows API实现字符串列表的排序。
该函数通过调用Windows的Shlwapi.dll库中的StrCmpLogicalW函数进行字符串的比较,以实现自然排序。
自然排序是指在排序数字和字母组合的字符串时,数字按照数值来比较,而不是按照字符的ASCII值来比较。
:param items: List[str] - 需要排序的字符串列表。
:return: List[str] - 排序后的字符串列表。
"""
shlwapi = ctypes.windll.LoadLibrary('Shlwapi.dll')
StrCmpLogicalW = shlwapi.StrCmpLogicalW
StrCmpLogicalW.argtypes = [ctypes.c_wchar_p, ctypes.c_wchar_p]
StrCmpLogicalW.restype = ctypes.c_int
def compare(a: str, b: str) -> int:
"""
比较两个字符串的函数,用于在排序时调用。
:param a: str - 第一个字符串。
:param b: str - 第二个字符串。
:return: int - StrCmpLogicalW函数的返回值,表示两个字符串的比较结果。
"""
return StrCmpLogicalW(str(a), str(b))
return sorted(items, key=cmp_to_key(compare))
def read_json_file(json_path): # 读取json文件
with open(json_path, 'r', encoding='utf-8') as file:
data = json.load(file)
return data
def write_json_file(json_path, data): # 写入json文件
with open(json_path, 'w') as file:
json.dump(data, file, sort_keys=False, indent=4)
def datetime_to_timestamp(date) -> int:
"""
日期转时间戳
:param date: 需要转换的日期
:return:
"""
return int(datetime.strptime(date, "%Y-%m-%d").timestamp())
def timestamp_to_datetime(timestamp):
"""
时间戳转日期
:param timestamp: 需要转换的时间戳
:return:
"""
return datetime.fromtimestamp(timestamp).strftime("%Y-%m-%d")
def get_today_timestamp():
"""
获取今日时间戳
:return:
"""
return datetime_to_timestamp(datetime.now().strftime("%Y-%m-%d"))
def show_delay_progress(delay_time: float) -> None:
"""在控制台显示延迟进度条"""
total_blocks = 30 # 进度条总长度
start_time = time.time()
end_time = start_time + delay_time
print(f"\n等待 {delay_time:.1f} 秒... [{' ' * total_blocks}]", end='', flush=True)
while time.time() < end_time:
elapsed = time.time() - start_time
progress = min(1.0, elapsed / delay_time)
filled = int(progress * total_blocks)
remaining = end_time - time.time()
print(f"\r等待 {delay_time:.1f} 秒... [{'=' * filled}>{' ' * (total_blocks - filled - 1)}]"
f" 剩余: {remaining:.1f}s", end='', flush=True)
time.sleep(0.1)
print("\r" + " " * 80 + "\r", end='', flush=True) # 清空进度行
def to_json_serializable(obj):
"""递归将 defaultdict 和 set 转换为 JSON 可序列化的类型"""
if isinstance(obj, defaultdict):
# 转为普通字典,并递归处理每个值
obj = dict(obj)
if isinstance(obj, dict):
return {k: to_json_serializable(v) for k, v in obj.items()}
if isinstance(obj, set):
return list(obj) # 集合转列表
# 其他基本类型(str, int, float, list, tuple, None)直接返回
return obj