| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 |
- """export_records.py — 导出记录管理路由及管理端存储查询。"""
- import math
- from fastapi import APIRouter
- from fastapi.responses import FileResponse
- from app.core.database import AsyncSessionLocal
- from app.core.exceptions import RecordNotFoundError
- from app.services.export_record_service import ExportRecordService
- from app.services.storage_monitor import get_storage_info
- router = APIRouter(tags=["Export Records"])
- def _ok(data: dict) -> dict:
- return {"code": 0, "data": data}
- # ------------------------------------------------------------------ #
- # GET /export/records — 分页查询导出记录
- # ------------------------------------------------------------------ #
- @router.get("/export/records", summary="获取导出记录列表")
- async def list_export_records(
- userId: str,
- page: int = 1,
- pageSize: int = 20,
- sortOrder: str = "desc",
- ) -> dict:
- page = max(1, page)
- page_size = min(max(1, pageSize), 100)
- async with AsyncSessionLocal() as db:
- svc = ExportRecordService(db)
- records, total = await svc.list_records(
- user_id=userId,
- page=page,
- page_size=page_size,
- sort_order=sortOrder,
- )
- total_pages = math.ceil(total / page_size) if total > 0 else 1
- return _ok(
- {
- "records": [
- {
- "recordId": r.id,
- "userId": r.user_id,
- "fileName": r.file_name,
- "fileSize": r.file_size,
- "downloadUrl": r.download_url,
- "documentId": r.document_id,
- "styleId": r.style_id,
- "createdAt": int(r.created_at.timestamp() * 1000),
- }
- for r in records
- ],
- "pagination": {
- "page": page,
- "pageSize": page_size,
- "total": total,
- "totalPages": total_pages,
- },
- }
- )
- # ------------------------------------------------------------------ #
- # GET /export/records/{recordId}/download — 重新下载文件
- # ------------------------------------------------------------------ #
- @router.get("/export/records/{recordId}/download", summary="重新下载导出文件")
- async def download_export_record(recordId: str, userId: str) -> FileResponse:
- from pathlib import Path
- async with AsyncSessionLocal() as db:
- svc = ExportRecordService(db)
- record = await svc.get_record(recordId, userId)
- file_path = Path(record.file_path)
- if not file_path.exists():
- raise RecordNotFoundError(recordId)
- return FileResponse(
- path=str(file_path),
- filename=record.file_name,
- media_type="application/msword",
- )
- # ------------------------------------------------------------------ #
- # DELETE /export/records/{recordId} — 删除记录(同步删文件)
- # ------------------------------------------------------------------ #
- @router.delete("/export/records/{recordId}", summary="删除导出记录")
- async def delete_export_record(recordId: str, userId: str) -> dict:
- async with AsyncSessionLocal() as db:
- svc = ExportRecordService(db)
- await svc.delete_record(recordId, userId)
- return {"code": 0, "message": "Record deleted successfully"}
- # ------------------------------------------------------------------ #
- # GET /admin/storage — 管理端存储查询
- # ------------------------------------------------------------------ #
- @router.get("/admin/storage", summary="管理端:存储使用情况")
- async def admin_storage() -> dict:
- info = get_storage_info()
- return _ok(
- {
- "diskTotalBytes": info["disk_total_bytes"],
- "diskUsedBytes": info["disk_used_bytes"],
- "tmpTotalBytes": info["tmp_total_bytes"],
- "quotaBytes": info["quota_bytes"],
- "quotaExceeded": info["quota_exceeded"],
- "activeUsers": info["active_users"],
- "perUserQuotaBytes": info["per_user_quota_bytes"],
- "users": [
- {
- "userId": u["user_id"],
- "usedBytes": u["used_bytes"],
- "quotaExceeded": u["quota_exceeded"],
- }
- for u in info["users"]
- ],
- }
- )
|