"""用户模块路由(/users/*,对应《03-接口文档》第 4 章)""" import redis.asyncio as aioredis from fastapi import APIRouter, Depends, Query, UploadFile from sqlalchemy.ext.asyncio import AsyncSession from app.core.response import ok from app.database import get_db from app.deps import Identity, get_identity, require_user from app.redis_client import get_redis from app.schemas.user import DeactivateReq, UpdateMeReq from app.services import interaction_service, storage_service, user_service, video_service router = APIRouter(prefix="/users", tags=["用户"]) # 注意:/users/me 系列须先于 /users/{user_id} 注册,避免 "me" 被路径参数匹配 @router.get("/me") async def get_me(db: AsyncSession = Depends(get_db), identity: Identity = Depends(require_user)): return ok(await user_service.get_me(db, identity.user_id)) @router.put("/me") async def update_me(req: UpdateMeReq, db: AsyncSession = Depends(get_db), redis: aioredis.Redis = Depends(get_redis), identity: Identity = Depends(require_user)): return ok(await user_service.update_me(db, redis, identity.user_id, req)) @router.post("/me/avatar") async def upload_avatar(file: UploadFile, db: AsyncSession = Depends(get_db), identity: Identity = Depends(require_user)): url = await storage_service.save_avatar(file, identity.user_id) return ok(await user_service.set_avatar(db, identity.user_id, url)) @router.get("/me/wallet") async def get_wallet(db: AsyncSession = Depends(get_db), redis: aioredis.Redis = Depends(get_redis), identity: Identity = Depends(require_user)): return ok(await user_service.get_wallet(db, redis, identity.user_id)) @router.get("/me/points/records") async def get_points_records(page: int = Query(1, ge=1), page_size: int = Query(20, ge=1, le=50), biz_type: int | None = Query(None), db: AsyncSession = Depends(get_db), identity: Identity = Depends(require_user)): return ok(await user_service.get_points_records(db, identity.user_id, page, page_size, biz_type)) @router.post("/me/deactivate") async def deactivate(req: DeactivateReq, db: AsyncSession = Depends(get_db), redis: aioredis.Redis = Depends(get_redis), identity: Identity = Depends(require_user)): return ok(await user_service.deactivate(db, redis, identity.user_id, req.password)) @router.get("/me/favorites") async def get_my_favorites(page: int = Query(1, ge=1), page_size: int = Query(20, ge=1, le=50), db: AsyncSession = Depends(get_db), identity: Identity = Depends(require_user)): return ok(await interaction_service.list_my_favorites(db, identity.user_id, page, page_size)) @router.get("/me/history") async def get_my_history(page: int = Query(1, ge=1), page_size: int = Query(20, ge=1, le=50), db: AsyncSession = Depends(get_db), identity: Identity = Depends(require_user)): return ok(await interaction_service.list_my_history(db, identity.user_id, page, page_size)) @router.get("/me/videos") async def get_my_videos(page: int = Query(1, ge=1), page_size: int = Query(20, ge=1, le=50), status: int | None = Query(None, ge=0, le=5), db: AsyncSession = Depends(get_db), identity: Identity = Depends(require_user)): return ok(await video_service.list_my_videos(db, identity.user_id, page, page_size, status)) @router.get("/{user_id}") async def get_public_profile(user_id: int, db: AsyncSession = Depends(get_db)): return ok(await user_service.get_public_profile(db, user_id)) @router.get("/{user_id}/videos") async def get_user_videos(user_id: int, page: int = Query(1, ge=1), page_size: int = Query(20, ge=1, le=50), db: AsyncSession = Depends(get_db), identity: Identity = Depends(get_identity)): return ok(await user_service.get_user_videos(db, user_id, page, page_size, identity.user_id))