优化列表分页和数据加载
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
"""账号管理路由"""
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException, Query
|
||||
from sqlalchemy import func
|
||||
from sqlalchemy.orm import Session, joinedload
|
||||
from sqlalchemy import func, or_
|
||||
from sqlalchemy.orm import Session, defer, joinedload
|
||||
|
||||
from ..database import get_db
|
||||
from ..models import User, Account, AuditLog, LoginTask
|
||||
@@ -16,11 +16,15 @@ from ..services.account_service import (
|
||||
router = APIRouter(prefix="/api/accounts", tags=["账号管理"])
|
||||
|
||||
|
||||
@router.get("", response_model=list[AccountOut])
|
||||
@router.get("")
|
||||
def list_accounts(
|
||||
assigned_only: bool = Query(False),
|
||||
tag: str = Query(None),
|
||||
has_cookie: bool = Query(False),
|
||||
search: str = Query(""),
|
||||
page: int | None = Query(None, ge=1),
|
||||
page_size: int = Query(20, ge=1, le=200),
|
||||
include_sensitive: bool = Query(True),
|
||||
db: Session = Depends(get_db),
|
||||
current: User = Depends(get_current_user),
|
||||
):
|
||||
@@ -44,7 +48,31 @@ def list_accounts(
|
||||
if tag:
|
||||
query = query.filter(Account.tag == tag)
|
||||
|
||||
accounts = query.order_by(Account.id).options(joinedload(Account.assigned_user)).all()
|
||||
search_text = (search or "").strip()
|
||||
if search_text:
|
||||
pattern = f"%{search_text}%"
|
||||
query = query.filter(or_(
|
||||
Account.username.ilike(pattern),
|
||||
Account.tag.ilike(pattern),
|
||||
Account.remark.ilike(pattern),
|
||||
))
|
||||
|
||||
total = None
|
||||
if page is not None:
|
||||
total = query.order_by(None).count()
|
||||
query = query.order_by(Account.id)
|
||||
if page is not None:
|
||||
query = query.offset((page - 1) * page_size).limit(page_size)
|
||||
|
||||
can_include_sensitive = include_sensitive and user_has_permission(current, "account:view_full")
|
||||
options = [joinedload(Account.assigned_user)]
|
||||
if not can_include_sensitive:
|
||||
options.extend([
|
||||
defer(Account.password),
|
||||
defer(Account.email),
|
||||
defer(Account.email_password),
|
||||
])
|
||||
accounts = query.options(*options).all()
|
||||
result = []
|
||||
for acc in accounts:
|
||||
item = AccountOut(
|
||||
@@ -55,14 +83,45 @@ def list_accounts(
|
||||
created_at=acc.created_at,
|
||||
)
|
||||
# 只有管理员可看完整字段(密码、邮箱等)
|
||||
if user_has_permission(current, "account:view_full"):
|
||||
if can_include_sensitive:
|
||||
item.password = acc.password
|
||||
item.email = acc.email
|
||||
item.email_password = acc.email_password
|
||||
result.append(item)
|
||||
if page is not None:
|
||||
return {"items": result, "total": total or 0, "page": page, "page_size": page_size}
|
||||
return result
|
||||
|
||||
|
||||
@router.get("/summary")
|
||||
def accounts_summary(
|
||||
db: Session = Depends(get_db),
|
||||
current: User = Depends(get_current_user),
|
||||
):
|
||||
"""账号管理统计,避免前端为了卡片统计拉全量账号。"""
|
||||
query = db.query(Account)
|
||||
if not user_has_permission(current, "account:view_all"):
|
||||
if user_has_permission(current, "account:view_assigned"):
|
||||
query = query.filter(Account.assigned_to == current.id)
|
||||
else:
|
||||
raise HTTPException(status_code=403, detail="无权查看账号")
|
||||
|
||||
total = query.count()
|
||||
assigned_count = query.filter(Account.assigned_to.isnot(None)).count()
|
||||
tag_count = (
|
||||
query.filter(Account.tag != "", Account.tag.isnot(None))
|
||||
.with_entities(Account.tag)
|
||||
.distinct()
|
||||
.count()
|
||||
)
|
||||
return {
|
||||
"total": total,
|
||||
"assigned_count": assigned_count,
|
||||
"unassigned_count": max(0, total - assigned_count),
|
||||
"tag_count": tag_count,
|
||||
}
|
||||
|
||||
|
||||
@router.post("/import")
|
||||
def import_accounts(
|
||||
req: AccountImport,
|
||||
|
||||
Reference in New Issue
Block a user