# -*- coding = utf-8 -*- # @Time : 2025/2/13 下午4:53 # @File : routes.py # @Software : PyCharm # @Author : xingc # @Desc : from typing import List, Literal from fastapi import APIRouter, Query, Depends, HTTPException, status from sqlalchemy import select, func from sqlalchemy.ext.asyncio import AsyncSession from core.base import schema as base_schema from core.db.crud import CRUD from core.db.engine import get_async_session from core.db.models import User, UserFollows from core.routers.auth.schema import LoginUser from core.routers.auth.services import get_current_user from . import schema user_router = APIRouter(prefix='/user', tags=['用户模块']) @user_router.get('/me/info', summary='用户信息(我的)', response_model=base_schema.BaseResponse[schema.User]) async def get_me_info( login_user: LoginUser = Depends(get_current_user), db_session: AsyncSession = Depends(get_async_session) ): db_crud = CRUD(db_session, User) user = await db_crud.get(filters={'user_id': login_user.user_id}) if user is None: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail='用户不存在') return {'data': user} @user_router.get( '/visit/{user_id}/info', summary='用户信息(访问者)', response_model=base_schema.BaseResponse[schema.LiteUser] ) async def get_visit_user_info( user_id: int, login_user: LoginUser = Depends(get_current_user), db_session: AsyncSession = Depends(get_async_session) ): if user_id == login_user.user_id: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail='无法操作') db_crud = CRUD(db_session, User) user = await db_crud.get(filters={'user_id': user_id}) if user is None: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail='访问用户不存在') return {'data': user} @user_router.get( '/followers/all', summary='获取所有关注列表', response_model=base_schema.BaseResponse[ base_schema.Paginated[ List[schema.LiteUser] ] ] ) async def get_all_followers( login_user: LoginUser = Depends(get_current_user), page: int = Query(default=1, gt=0), page_size: int = Query(default=15, gt=0, le=200), db_session: AsyncSession = Depends(get_async_session) ): # 组装查询条件 conditions = [ UserFollows.follower_id == login_user.user_id ] # 记录总数查询 total_stmt = ( select(func.count()).select_from(UserFollows).filter(*conditions) ) total = await db_session.execute(total_stmt) # 分页记录查询 stmt = ( select(User, UserFollows) .join(User, UserFollows.followed_id == User.user_id) .where(*conditions) .order_by(UserFollows.created_at.desc()).limit(page_size).offset((page - 1) * page_size) ) records = await db_session.execute(stmt) return { 'data': { 'list': records.scalars().all(), 'total': total.scalar(), 'page': page, 'page_size': page_size, }, } @user_router.post('/follow/{user_id}/', summary='新增/取消关注用户', response_model=base_schema.BaseResponse) async def follow_user( user_id: int, action: Literal['follower', 'unfollower'], login_user: LoginUser = Depends(get_current_user), db_session: AsyncSession = Depends(get_async_session) ): if user_id == login_user.user_id: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail='无法操作') db_crud = CRUD(db_session, User) follower_user: User | None = await db_crud.get(filters={'user_id': user_id}) if follower_user is None: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail='被关注者不存在') user: User | None = await db_crud.get(filters={'user_id': login_user.user_id}) db_crud = CRUD(db_session, UserFollows) record = { 'follower_id': login_user.user_id, 'followed_id': user.user_id, } if action == 'follower': await db_crud.create(data=record, filters=record) if action == 'unfollower': await db_crud.delete(filters=record) return {'message': 'ok'} @user_router.post( '/search/', summary='搜索用户', response_model=base_schema.BaseResponse[ base_schema.Paginated[ List[schema.LiteUser] ] ] ) async def search_user( nickname: str = Query(...), page_size: int = Query(default=30, gt=0, le=30), login_user: LoginUser = Depends(get_current_user), db_session: AsyncSession = Depends(get_async_session) ): db_crud = CRUD(db_session, User) users, total = await db_crud.get_paginated( page_size=page_size, filters={ 'nickname__like': nickname, 'user_id__ne': login_user.user_id } ) return {'data': { 'list': users, 'total': total, 'page_size': page_size }}