feat: add admin file policy actions

This commit is contained in:
Lan
2026-06-03 05:45:02 +08:00
parent 764fc78cd1
commit 0fe539dda5
3 changed files with 104 additions and 1 deletions
+7
View File
@@ -41,3 +41,10 @@ class BatchUpdateFileData(BaseModel):
expired_count: Optional[int] = None expired_count: Optional[int] = None
clearExpiredAt: Optional[bool] = None clearExpiredAt: Optional[bool] = None
clear_expired_at: Optional[bool] = None clear_expired_at: Optional[bool] = None
class FilePolicyActionData(BaseModel):
id: int
action: str
downloadLimit: Optional[int] = None
download_limit: Optional[int] = None
+64 -1
View File
@@ -1,6 +1,6 @@
import os import os
import time import time
from datetime import datetime from datetime import datetime, timedelta
from typing import Any, Optional from typing import Any, Optional
from core.response import APIResponse from core.response import APIResponse
@@ -107,6 +107,28 @@ class FileService:
"failed": failed, "failed": failed,
} }
async def apply_file_policy_action(
self,
file_id: int,
action: str,
download_limit: Optional[int] = None,
) -> dict[str, Any]:
file_code = await FileCodes.filter(id=file_id).first()
if not file_code:
raise HTTPException(status_code=404, detail="文件不存在")
action = action.strip().lower()
now = await get_now()
update_data = self._build_policy_action_update(
file_code=file_code,
action=action,
now=now,
download_limit=download_limit,
)
await file_code.update_from_dict(update_data).save()
return await self.get_file_detail(file_id)
async def list_files( async def list_files(
self, self,
page: int, page: int,
@@ -449,6 +471,47 @@ class FileService:
start = start.replace(tzinfo=None) start = start.replace(tzinfo=None)
return int((end - start).total_seconds()) return int((end - start).total_seconds())
def _build_policy_action_update(
self,
file_code: FileCodes,
action: str,
now: datetime,
download_limit: Optional[int],
) -> dict[str, Any]:
if action == "extend_24h":
return {"expired_at": self._extended_expiration(file_code.expired_at, now, hours=24)}
if action == "extend_7d":
return {"expired_at": self._extended_expiration(file_code.expired_at, now, days=7)}
if action == "make_permanent":
return {"expired_at": None, "expired_count": -1}
if action == "reset_download_limit":
next_limit = download_limit if download_limit is not None else 5
if next_limit < 1:
raise HTTPException(status_code=400, detail="取件次数必须大于 0")
return {"expired_count": next_limit}
raise HTTPException(status_code=400, detail="不支持的策略动作")
def _extended_expiration(
self,
expired_at: Optional[datetime],
now: datetime,
**duration: int,
) -> datetime:
base_time = now
if expired_at is not None:
comparable_expired_at = self._align_datetime(expired_at, now)
if comparable_expired_at > now:
base_time = comparable_expired_at
return base_time + timedelta(**duration)
def _align_datetime(self, value: datetime, reference: datetime) -> datetime:
if value.tzinfo is None and reference.tzinfo is not None:
return value.replace(tzinfo=reference.tzinfo)
if value.tzinfo is not None and reference.tzinfo is None:
return value.replace(tzinfo=None)
return value
def _match_admin_file( def _match_admin_file(
self, self,
item: dict[str, Any], item: dict[str, Any],
+33
View File
@@ -18,6 +18,7 @@ from apps.admin.schemas import (
IDData, IDData,
IDsData, IDsData,
BatchUpdateFileData, BatchUpdateFileData,
FilePolicyActionData,
ShareItem, ShareItem,
DeleteItem, DeleteItem,
LoginData, LoginData,
@@ -218,6 +219,38 @@ async def file_batch_update_post(
return await batch_update_files(data, file_service) return await batch_update_files(data, file_service)
async def apply_file_policy_action(
data: FilePolicyActionData,
file_service: FileService,
):
download_limit = data.downloadLimit
if download_limit is None:
download_limit = data.download_limit
detail = await file_service.apply_file_policy_action(
file_id=data.id,
action=data.action,
download_limit=download_limit,
)
return APIResponse(detail=detail)
@admin_api.patch("/file/policy-action")
async def file_policy_action(
data: FilePolicyActionData,
file_service: FileService = Depends(get_file_service),
):
return await apply_file_policy_action(data, file_service)
@admin_api.post("/file/policy-action")
async def file_policy_action_post(
data: FilePolicyActionData,
file_service: FileService = Depends(get_file_service),
):
return await apply_file_policy_action(data, file_service)
@admin_api.get("/file/list") @admin_api.get("/file/list")
async def file_list( async def file_list(
page: int = 1, page: int = 1,