""" 用户资料 API """ from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select from app.database import get_db from app.models.user import User, UserRole from app.models.organization import Brand, Agency, Creator from app.api.deps import get_current_user from app.services.auth import verify_password, hash_password from app.schemas.profile import ( ProfileResponse, ProfileUpdateRequest, ChangePasswordRequest, BrandProfile, AgencyProfile, CreatorProfile, ) router = APIRouter(prefix="/profile", tags=["用户资料"]) def _build_profile_response(user: User, brand=None, agency=None, creator=None) -> ProfileResponse: """构建资料响应""" resp = ProfileResponse( id=user.id, email=user.email, phone=user.phone, name=user.name, avatar=user.avatar, role=user.role.value, is_verified=user.is_verified, created_at=user.created_at, ) if brand: resp.brand = BrandProfile( id=brand.id, name=brand.name, logo=brand.logo, description=brand.description, contact_name=brand.contact_name, contact_phone=brand.contact_phone, contact_email=brand.contact_email, ) if agency: resp.agency = AgencyProfile( id=agency.id, name=agency.name, logo=agency.logo, description=agency.description, contact_name=agency.contact_name, contact_phone=agency.contact_phone, contact_email=agency.contact_email, ) if creator: resp.creator = CreatorProfile( id=creator.id, name=creator.name, avatar=creator.avatar, bio=creator.bio, douyin_account=creator.douyin_account, xiaohongshu_account=creator.xiaohongshu_account, bilibili_account=creator.bilibili_account, ) return resp async def _get_role_entity(db: AsyncSession, user: User): """根据角色获取对应实体""" if user.role == UserRole.BRAND: result = await db.execute(select(Brand).where(Brand.user_id == user.id)) return result.scalar_one_or_none(), None, None elif user.role == UserRole.AGENCY: result = await db.execute(select(Agency).where(Agency.user_id == user.id)) return None, result.scalar_one_or_none(), None elif user.role == UserRole.CREATOR: result = await db.execute(select(Creator).where(Creator.user_id == user.id)) return None, None, result.scalar_one_or_none() return None, None, None @router.get("", response_model=ProfileResponse) async def get_profile( current_user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db), ): """获取当前用户资料""" brand, agency, creator = await _get_role_entity(db, current_user) return _build_profile_response(current_user, brand, agency, creator) @router.put("", response_model=ProfileResponse) async def update_profile( request: ProfileUpdateRequest, current_user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db), ): """更新当前用户资料""" # 更新 User 表通用字段 if request.name is not None: current_user.name = request.name if request.avatar is not None: current_user.avatar = request.avatar if request.phone is not None: current_user.phone = request.phone # 更新角色表字段 brand, agency, creator = await _get_role_entity(db, current_user) if current_user.role == UserRole.BRAND and brand: if request.name is not None: brand.name = request.name if request.description is not None: brand.description = request.description if request.contact_name is not None: brand.contact_name = request.contact_name if request.contact_phone is not None: brand.contact_phone = request.contact_phone if request.contact_email is not None: brand.contact_email = request.contact_email elif current_user.role == UserRole.AGENCY and agency: if request.name is not None: agency.name = request.name if request.description is not None: agency.description = request.description if request.contact_name is not None: agency.contact_name = request.contact_name if request.contact_phone is not None: agency.contact_phone = request.contact_phone if request.contact_email is not None: agency.contact_email = request.contact_email elif current_user.role == UserRole.CREATOR and creator: if request.name is not None: creator.name = request.name if request.avatar is not None: creator.avatar = request.avatar if request.bio is not None: creator.bio = request.bio if request.douyin_account is not None: creator.douyin_account = request.douyin_account if request.xiaohongshu_account is not None: creator.xiaohongshu_account = request.xiaohongshu_account if request.bilibili_account is not None: creator.bilibili_account = request.bilibili_account await db.commit() # 重新查询返回最新数据 brand, agency, creator = await _get_role_entity(db, current_user) return _build_profile_response(current_user, brand, agency, creator) @router.put("/password") async def change_password( request: ChangePasswordRequest, current_user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db), ): """修改密码""" if not verify_password(request.old_password, current_user.password_hash): raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="原密码不正确", ) current_user.password_hash = hash_password(request.new_password) await db.commit() return {"message": "密码修改成功"}