first commit
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
import math
|
||||
import uuid
|
||||
|
||||
from fastapi import APIRouter, HTTPException, Query, status
|
||||
from sqlalchemy import func, select
|
||||
from sqlalchemy.exc import IntegrityError
|
||||
from sqlalchemy.orm import joinedload
|
||||
|
||||
from app.deps import CurrentUser, DbSession, OptionalUser
|
||||
from app.models import Cloud, Profile, User
|
||||
from app.schemas import CloudOut, PageOut, ProfileOut, ProfileUpdateIn, PublicProfileOut
|
||||
from app.serializers import cloud_out, profile_out, public_profile_out
|
||||
|
||||
|
||||
router = APIRouter(prefix="/profiles", tags=["用户资料"])
|
||||
|
||||
|
||||
@router.get("/{user_id}", response_model=PublicProfileOut)
|
||||
async def get_profile(user_id: uuid.UUID, db: DbSession) -> PublicProfileOut:
|
||||
profile = await db.get(Profile, user_id)
|
||||
if not profile:
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="用户不存在")
|
||||
return public_profile_out(profile)
|
||||
|
||||
|
||||
@router.patch("/me", response_model=ProfileOut)
|
||||
async def update_my_profile(
|
||||
payload: ProfileUpdateIn,
|
||||
user: CurrentUser,
|
||||
db: DbSession,
|
||||
) -> ProfileOut:
|
||||
user.profile.username = payload.username
|
||||
try:
|
||||
await db.commit()
|
||||
except IntegrityError as exc:
|
||||
await db.rollback()
|
||||
raise HTTPException(status_code=status.HTTP_409_CONFLICT, detail="这个昵称已经被使用") from exc
|
||||
return profile_out(user.profile)
|
||||
|
||||
|
||||
@router.get("/{user_id}/clouds", response_model=PageOut[CloudOut])
|
||||
async def get_profile_clouds(
|
||||
user_id: uuid.UUID,
|
||||
db: DbSession,
|
||||
viewer: OptionalUser,
|
||||
page: int = Query(1, ge=1),
|
||||
page_size: int = Query(50, ge=1, le=100),
|
||||
) -> PageOut[CloudOut]:
|
||||
if not await db.get(Profile, user_id):
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="用户不存在")
|
||||
|
||||
can_manage = bool(viewer and (viewer.id == user_id or viewer.profile.role == "admin"))
|
||||
filters = [Cloud.user_id == user_id]
|
||||
if not can_manage:
|
||||
filters.extend([Cloud.status == "approved", Cloud.is_hidden.is_(False)])
|
||||
|
||||
total = await db.scalar(select(func.count()).select_from(Cloud).where(*filters)) or 0
|
||||
result = await db.execute(
|
||||
select(Cloud)
|
||||
.options(joinedload(Cloud.user).joinedload(User.profile), joinedload(Cloud.cloud_type))
|
||||
.where(*filters)
|
||||
.order_by(Cloud.captured_at.desc().nulls_last(), Cloud.created_at.desc(), Cloud.id.desc())
|
||||
.offset((page - 1) * page_size)
|
||||
.limit(page_size)
|
||||
)
|
||||
items = [cloud_out(item, include_private=can_manage) for item in result.scalars().unique().all()]
|
||||
return PageOut(
|
||||
items=items,
|
||||
page=page,
|
||||
page_size=page_size,
|
||||
total=total,
|
||||
total_pages=max(1, math.ceil(total / page_size)),
|
||||
)
|
||||
Reference in New Issue
Block a user