nex_basse/backend/app/api/v1/endpoints/dashboard.py

91 lines
2.6 KiB
Python

from datetime import datetime, timedelta
from pathlib import Path
import os
import shutil
from fastapi import APIRouter, Depends
from sqlalchemy.orm import Session
from sqlalchemy import func
from redis import Redis
from app.core.db import get_db
from app.core.redis import get_redis
from app.schemas.dashboard import DashboardSummary, UserStats, StorageStats, ServerStats
from app.models import User
router = APIRouter(prefix="/dashboard", tags=["dashboard"])
AUDIO_EXTENSIONS = {".mp3", ".wav", ".m4a", ".flac", ".aac", ".ogg"}
def _get_base_dir() -> Path:
return Path(__file__).resolve().parents[5]
def _scan_storage(storage_dir: Path) -> tuple[int, int]:
total_bytes = 0
file_count = 0
if not storage_dir.exists():
return 0, 0
for root, _dirs, files in os.walk(storage_dir):
for name in files:
file_path = Path(root) / name
try:
total_bytes += file_path.stat().st_size
except OSError:
continue
file_count += 1
return total_bytes, file_count
def _get_cpu_memory() -> tuple[float, float]:
try:
import psutil # type: ignore
cpu = psutil.cpu_percent(interval=0.2)
mem = psutil.virtual_memory().percent
return float(cpu), float(mem)
except Exception:
return 0.0, 0.0
def _get_disk_usage(path: Path) -> float:
try:
total, used, _free = shutil.disk_usage(path)
if total == 0:
return 0.0
return round(used / total * 100, 2)
except Exception:
return 0.0
@router.get("/summary", response_model=DashboardSummary)
def get_dashboard_summary(db: Session = Depends(get_db), redis: Redis = Depends(get_redis)):
total_users = db.query(User).filter(User.is_deleted == 0).count()
# 2. 今日新增
today_start = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
new_today = db.query(User).filter(
User.created_at >= today_start,
User.is_deleted == 0
).count()
try:
online = len(redis.keys("auth:online:*"))
except Exception:
online = 0
base_dir = _get_base_dir()
storage_dir = base_dir / "storage"
total_bytes, audio_files = _scan_storage(storage_dir)
total_gb = round(total_bytes / (1024 ** 3), 2)
cpu, mem = _get_cpu_memory()
disk = _get_disk_usage(storage_dir if storage_dir.exists() else base_dir)
return DashboardSummary(
users=UserStats(total=total_users, new_today=new_today, online=online),
storage=StorageStats(total_gb=total_gb, audio_files=audio_files),
server=ServerStats(cpu=cpu, memory=mem, disk=disk),
)