Lan
2026-01-07 20:04:44 +08:00
parent e80be564a5
commit e87bcfcce5
3 changed files with 58 additions and 56 deletions
+7 -5
View File
@@ -17,6 +17,7 @@ from core.response import APIResponse
from apps.base.models import FileCodes, KeyValue from apps.base.models import FileCodes, KeyValue
from apps.admin.dependencies import create_token from apps.admin.dependencies import create_token
from core.settings import settings from core.settings import settings
from core.utils import get_now
admin_api = APIRouter(prefix="/admin", tags=["管理"]) admin_api = APIRouter(prefix="/admin", tags=["管理"])
@@ -37,16 +38,13 @@ async def dashboard(admin: bool = Depends(admin_required)):
all_codes = await FileCodes.all() all_codes = await FileCodes.all()
all_size = str(sum([code.size for code in all_codes])) all_size = str(sum([code.size for code in all_codes]))
sys_start = await KeyValue.filter(key="sys_start").first() sys_start = await KeyValue.filter(key="sys_start").first()
# 获取当前日期时间 now = await get_now()
now = datetime.datetime.now()
today_start = now.replace(hour=0, minute=0, second=0, microsecond=0) today_start = now.replace(hour=0, minute=0, second=0, microsecond=0)
yesterday_start = today_start - datetime.timedelta(days=1) yesterday_start = today_start - datetime.timedelta(days=1)
yesterday_end = today_start - datetime.timedelta(microseconds=1) yesterday_end = today_start - datetime.timedelta(microseconds=1)
# 统计昨天一整天的记录数(从昨天0点到23:59:59)
yesterday_codes = FileCodes.filter( yesterday_codes = FileCodes.filter(
created_at__gte=yesterday_start, created_at__lte=yesterday_end created_at__gte=yesterday_start, created_at__lte=yesterday_end
) )
# 统计今天到现在的记录数(从今天0点到现在)
today_codes = FileCodes.filter(created_at__gte=today_start) today_codes = FileCodes.filter(created_at__gte=today_start)
return APIResponse( return APIResponse(
detail={ detail={
@@ -167,7 +165,11 @@ async def update_file(
update_data["prefix"] = data.prefix update_data["prefix"] = data.prefix
if data.suffix is not None and data.suffix != file_code.suffix: if data.suffix is not None and data.suffix != file_code.suffix:
update_data["suffix"] = data.suffix update_data["suffix"] = data.suffix
if data.expired_at is not None and data.expired_at != "" and data.expired_at != file_code.expired_at: if (
data.expired_at is not None
and data.expired_at != ""
and data.expired_at != file_code.expired_at
):
update_data["expired_at"] = data.expired_at update_data["expired_at"] = data.expired_at
if data.expired_count is not None and data.expired_count != file_code.expired_count: if data.expired_count is not None and data.expired_count != file_code.expired_count:
update_data["expired_count"] = data.expired_count update_data["expired_count"] = data.expired_count
+23 -21
View File
@@ -10,30 +10,32 @@ from typing import Optional, Tuple
from apps.base.dependencies import IPRateLimit from apps.base.dependencies import IPRateLimit
from apps.base.models import FileCodes from apps.base.models import FileCodes
from core.settings import settings from core.settings import settings
from core.utils import get_random_num, get_random_string, max_save_times_desc, sanitize_filename from core.utils import (
get_random_num,
get_random_string,
max_save_times_desc,
sanitize_filename,
get_now,
)
async def get_file_path_name(file: UploadFile) -> Tuple[str, str, str, str, str]: async def get_file_path_name(file: UploadFile) -> Tuple[str, str, str, str, str]:
"""获取文件路径和文件名""" today = await get_now()
today = datetime.datetime.now() storage_path = settings.storage_path.strip("/")
storage_path = settings.storage_path.strip("/") # 移除开头和结尾的斜杠
file_uuid = uuid.uuid4().hex file_uuid = uuid.uuid4().hex
# 一些客户端对非ASCII字符会进行编码,需要解码 filename = await sanitize_filename(unquote(file.filename or ""))
filename = await sanitize_filename(unquote(file.filename))
# 使用 UUID 作为子目录名
base_path = f"share/data/{today.strftime('%Y/%m/%d')}/{file_uuid}" base_path = f"share/data/{today.strftime('%Y/%m/%d')}/{file_uuid}"
# 如果设置了存储路径,将其添加到基础路径中
path = f"{storage_path}/{base_path}" if storage_path else base_path path = f"{storage_path}/{base_path}" if storage_path else base_path
prefix, suffix = os.path.splitext(filename) prefix, suffix = os.path.splitext(filename)
# 保持原始文件名
save_path = f"{path}/{filename}" save_path = f"{path}/{filename}"
return path, suffix, prefix, filename, save_path return path, suffix, prefix, filename, save_path
async def get_chunk_file_path_name(file_name: str, upload_id: str) -> Tuple[str, str, str, str, str]: async def get_chunk_file_path_name(
"""获取切片文件的路径和文件名""" file_name: str, upload_id: str
today = datetime.datetime.now() ) -> Tuple[str, str, str, str, str]:
storage_path = settings.storage_path.strip("/") # 移除开头和结尾的斜杠 today = await get_now()
storage_path = settings.storage_path.strip("/")
base_path = f"share/data/{today.strftime('%Y/%m/%d')}/{upload_id}" base_path = f"share/data/{today.strftime('%Y/%m/%d')}/{upload_id}"
path = f"{storage_path}/{base_path}" if storage_path else base_path path = f"{storage_path}/{base_path}" if storage_path else base_path
prefix, suffix = os.path.splitext(file_name) prefix, suffix = os.path.splitext(file_name)
@@ -41,10 +43,11 @@ async def get_chunk_file_path_name(file_name: str, upload_id: str) -> Tuple[str,
return path, suffix, prefix, file_name, save_path return path, suffix, prefix, file_name, save_path
async def get_expire_info(expire_value: int, expire_style: str) -> Tuple[Optional[datetime.datetime], int, int, str]: async def get_expire_info(
"""获取过期信息""" expire_value: int, expire_style: str
) -> Tuple[Optional[datetime.datetime], int, int, str]:
expired_count, used_count = -1, 0 expired_count, used_count = -1, 0
now = datetime.datetime.now() now = await get_now()
code = None code = None
max_timedelta = ( max_timedelta = (
@@ -64,7 +67,7 @@ async def get_expire_info(expire_value: int, expire_style: str) -> Tuple[Optiona
"hour": lambda: now + datetime.timedelta(hours=expire_value), "hour": lambda: now + datetime.timedelta(hours=expire_value),
"minute": lambda: now + datetime.timedelta(minutes=expire_value), "minute": lambda: now + datetime.timedelta(minutes=expire_value),
"count": lambda: (now + datetime.timedelta(days=1), expire_value), "count": lambda: (now + datetime.timedelta(days=1), expire_value),
"forever": lambda: (None, None), # 修改这里 "forever": lambda: (None, None),
} }
if expire_style in expire_styles: if expire_style in expire_styles:
@@ -74,7 +77,7 @@ async def get_expire_info(expire_value: int, expire_style: str) -> Tuple[Optiona
if expire_style == "count": if expire_style == "count":
expired_count = extra expired_count = extra
elif expire_style == "forever": elif expire_style == "forever":
code = await get_random_code(style="string") # 移动到这里 code = await get_random_code(style="string")
else: else:
expired_at = result expired_at = result
if expired_at and expired_at - now > max_timedelta: if expired_at and expired_at - now > max_timedelta:
@@ -88,12 +91,11 @@ async def get_expire_info(expire_value: int, expire_style: str) -> Tuple[Optiona
return expired_at, expired_count, used_count, code return expired_at, expired_count, used_count, code
async def get_random_code(style="num") -> str: async def get_random_code(style: str = "num") -> str:
"""获取随机字符串"""
while True: while True:
code = await get_random_num() if style == "num" else await get_random_string() code = await get_random_num() if style == "num" else await get_random_string()
if not await FileCodes.filter(code=code).exists(): if not await FileCodes.filter(code=code).exists():
return code return str(code)
async def calculate_file_hash(file: UploadFile, chunk_size=1024 * 1024) -> str: async def calculate_file_hash(file: UploadFile, chunk_size=1024 * 1024) -> str:
+2 -4
View File
@@ -46,14 +46,12 @@ async def delete_expire_files():
async def clean_incomplete_uploads(): async def clean_incomplete_uploads():
"""清理超时未完成的分片上传"""
file_storage: FileStorageInterface = storages[settings.file_storage]() file_storage: FileStorageInterface = storages[settings.file_storage]()
expire_hours = getattr(settings, "chunk_expire_hours", 24) expire_hours = getattr(settings, "chunk_expire_hours", 24)
while True: while True:
try: try:
expire_time = datetime.datetime.now() - datetime.timedelta( now = await get_now()
hours=expire_hours expire_time = now - datetime.timedelta(hours=expire_hours)
)
expired_sessions = await UploadChunk.filter( expired_sessions = await UploadChunk.filter(
chunk_index=-1, created_at__lt=expire_time chunk_index=-1, created_at__lt=expire_time
).all() ).all()