This commit is contained in:
Your Name
2026-07-27 15:20:15 +08:00
parent 4970d8f8d3
commit 8ba13a8ff9
10 changed files with 424 additions and 39 deletions
+55 -1
View File
@@ -20,7 +20,7 @@ from settings import CORS_ORIGINS, SERVE_WEB, STATIC_DIR
from help_pages import serve_credential_tool
from web_static import mount_frontend
from pydantic import BaseModel, Field
from sqlalchemy import select, update, delete, text, func
from sqlalchemy import select, update, delete, text, func, case
from sqlalchemy.ext.asyncio import AsyncSession
from models.database import engine, Base, get_db, AsyncSessionLocal
@@ -625,6 +625,15 @@ class AccountResponse(BaseModel):
from_attributes = True
class DashboardAccountStatsResponse(BaseModel):
"""Safe account totals shown to every authenticated dashboard user."""
total_accounts: int = 0
online_accounts: int = 0
my_accounts: int = 0
my_online_accounts: int = 0
class AccountUpdate(BaseModel):
phone: Optional[str] = None
username: Optional[str] = None
@@ -1010,6 +1019,51 @@ def _account_matches_keyword(account: Account, keyword: str) -> bool:
)
@app.get(
"/api/dashboard/account-stats",
response_model=DashboardAccountStatsResponse,
)
async def get_dashboard_account_stats(
db: AsyncSession = Depends(get_db),
user: User = Depends(get_current_user),
):
"""Return public platform totals without exposing other users' accounts."""
result = await db.execute(
select(
func.count(Account.id).label("total_accounts"),
func.coalesce(
func.sum(case((Account.status == "online", 1), else_=0)),
0,
).label("online_accounts"),
func.coalesce(
func.sum(case((Account.owner_id == user.id, 1), else_=0)),
0,
).label("my_accounts"),
func.coalesce(
func.sum(
case(
(
(Account.owner_id == user.id)
& (Account.status == "online"),
1,
),
else_=0,
)
),
0,
).label("my_online_accounts"),
)
)
row = result.one()
return DashboardAccountStatsResponse(
total_accounts=int(row.total_accounts or 0),
online_accounts=int(row.online_accounts or 0),
my_accounts=int(row.my_accounts or 0),
my_online_accounts=int(row.my_online_accounts or 0),
)
@app.get("/api/accounts")
async def get_accounts(
page: Optional[int] = Query(None, ge=1),