Files
LoveACE-EndF/router/user/__init__.py
2025-08-03 16:50:56 +08:00

242 lines
10 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import base64
from fastapi import Depends
from fastapi.routing import APIRouter
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select
from database.creator import get_db_session
from database.user import UserProfile, User
from provider.loveac.authme import fetch_user_by_token, AuthmeRequest
from utils.file_manager import file_manager
from .model import (
UserProfileResponse,
GetUserProfileRequest,
UpdateUserProfileRequest,
UserProfileData,
UserSettings,
)
user_router = APIRouter(prefix="/api/v1/user")
@user_router.post("/profile/get", summary="获取用户资料")
async def get_user_profile(
data: GetUserProfileRequest,
asyncsession: AsyncSession = Depends(get_db_session),
):
"""
获取用户资料
:param data: GetUserProfileRequest
:return: UserProfileResponse
"""
try:
# 使用token验证获取用户
authme_request = AuthmeRequest(token=data.token)
user = await fetch_user_by_token(authme_request, asyncsession)
async with asyncsession as session:
result = await session.execute(
select(UserProfile).where(UserProfile.userid == user.userid)
)
profile = result.scalars().first()
if not profile:
# 如果用户资料不存在,创建默认资料
profile = UserProfile(
userid=user.userid,
avatar_filename=None,
background_filename=None,
nickname=None,
settings_filename=None
)
session.add(profile)
await session.commit()
# 获取头像数据
avatar_data = None
if profile.avatar_filename:
avatar_bytes = await file_manager.get_avatar(profile.avatar_filename)
if avatar_bytes:
# 转换为base64
avatar_data = base64.b64encode(avatar_bytes).decode('utf-8')
# 根据文件扩展名添加data URI前缀
if profile.avatar_filename.endswith('.png'):
avatar_data = f"data:image/png;base64,{avatar_data}"
elif profile.avatar_filename.endswith(('.jpg', '.jpeg')):
avatar_data = f"data:image/jpeg;base64,{avatar_data}"
elif profile.avatar_filename.endswith('.gif'):
avatar_data = f"data:image/gif;base64,{avatar_data}"
# 获取背景数据
background_data = None
if profile.background_filename:
background_bytes = await file_manager.get_background(profile.background_filename)
if background_bytes:
# 转换为base64
background_data = base64.b64encode(background_bytes).decode('utf-8')
# 根据文件扩展名添加data URI前缀
if profile.background_filename.endswith('.png'):
background_data = f"data:image/png;base64,{background_data}"
elif profile.background_filename.endswith(('.jpg', '.jpeg')):
background_data = f"data:image/jpeg;base64,{background_data}"
elif profile.background_filename.endswith('.gif'):
background_data = f"data:image/gif;base64,{background_data}"
elif profile.background_filename.endswith('.webp'):
background_data = f"data:image/webp;base64,{background_data}"
# 获取设置数据
settings_data = None
if profile.settings_filename:
settings_dict = await file_manager.get_settings(profile.settings_filename)
if settings_dict:
settings_data = UserSettings(**settings_dict)
profile_data = UserProfileData(
userid=profile.userid,
avatar=avatar_data,
background=background_data,
nickname=profile.nickname,
settings=settings_data,
)
return UserProfileResponse(
code=200,
message="获取用户资料成功",
data=profile_data
)
except Exception as e:
return UserProfileResponse(
code=500,
message=f"获取用户资料失败: {str(e)}",
data=None
)
@user_router.post("/profile/update", summary="更新用户资料")
async def update_user_profile(
data: UpdateUserProfileRequest,
asyncsession: AsyncSession = Depends(get_db_session),
):
"""
更新用户资料
:param data: UpdateUserProfileRequest
:return: UserProfileResponse
"""
try:
# 使用token验证获取用户
authme_request = AuthmeRequest(token=data.token)
user = await fetch_user_by_token(authme_request, asyncsession)
async with asyncsession as session:
result = await session.execute(
select(UserProfile).where(UserProfile.userid == user.userid)
)
profile = result.scalars().first()
if not profile:
# 如果用户资料不存在,创建新的
profile = UserProfile(
userid=user.userid,
avatar_filename=None,
background_filename=None,
nickname=data.nickname,
settings_filename=None
)
session.add(profile)
else:
# 更新昵称
if data.nickname is not None:
profile.nickname = data.nickname
# 处理头像更新
if data.avatar is not None:
if data.avatar: # 如果头像不为空
new_avatar_filename = await file_manager.save_avatar(user.userid, data.avatar)
profile.avatar_filename = new_avatar_filename
else: # 如果头像为空,表示删除头像
if profile.avatar_filename:
await file_manager.delete_avatar(profile.avatar_filename)
profile.avatar_filename = None
# 处理背景更新
if data.background is not None:
if data.background: # 如果背景不为空
new_background_filename = await file_manager.save_background(user.userid, data.background)
profile.background_filename = new_background_filename
else: # 如果背景为空,表示删除背景
if profile.background_filename:
await file_manager.delete_background(profile.background_filename)
profile.background_filename = None
# 处理设置更新
if data.settings is not None:
if data.settings: # 如果设置不为空
# data.settings在model验证时已经被转换为UserSettings对象
if isinstance(data.settings, UserSettings):
settings_dict = data.settings.model_dump()
new_settings_filename = await file_manager.save_settings(user.userid, settings_dict)
profile.settings_filename = new_settings_filename
else:
# 如果不是UserSettings对象说明验证有问题
raise ValueError(f"Settings对象类型错误: {type(data.settings)}")
else: # 如果设置为空,表示删除设置
if profile.settings_filename:
await file_manager.delete_settings(profile.settings_filename)
profile.settings_filename = None
await session.commit()
await session.refresh(profile)
# 获取更新后的数据
avatar_data = None
if profile.avatar_filename:
avatar_bytes = await file_manager.get_avatar(profile.avatar_filename)
if avatar_bytes:
avatar_data = base64.b64encode(avatar_bytes).decode('utf-8')
if profile.avatar_filename.endswith('.png'):
avatar_data = f"data:image/png;base64,{avatar_data}"
elif profile.avatar_filename.endswith(('.jpg', '.jpeg')):
avatar_data = f"data:image/jpeg;base64,{avatar_data}"
elif profile.avatar_filename.endswith('.gif'):
avatar_data = f"data:image/gif;base64,{avatar_data}"
background_data = None
if profile.background_filename:
background_bytes = await file_manager.get_background(profile.background_filename)
if background_bytes:
background_data = base64.b64encode(background_bytes).decode('utf-8')
if profile.background_filename.endswith('.png'):
background_data = f"data:image/png;base64,{background_data}"
elif profile.background_filename.endswith(('.jpg', '.jpeg')):
background_data = f"data:image/jpeg;base64,{background_data}"
elif profile.background_filename.endswith('.gif'):
background_data = f"data:image/gif;base64,{background_data}"
elif profile.background_filename.endswith('.webp'):
background_data = f"data:image/webp;base64,{background_data}"
settings_data = None
if profile.settings_filename:
settings_dict = await file_manager.get_settings(profile.settings_filename)
if settings_dict:
settings_data = UserSettings(**settings_dict)
profile_data = UserProfileData(
userid=profile.userid,
avatar=avatar_data,
background=background_data,
nickname=profile.nickname,
settings=settings_data,
)
return UserProfileResponse(
code=200,
message="更新用户资料成功",
data=profile_data
)
except Exception as e:
return UserProfileResponse(
code=500,
message=f"更新用户资料失败: {str(e)}",
data=None
)