from typing import Annotated from app.auth import validate_username from app.config import settings from app.database import User from app.database.events import Event, EventType from app.dependencies.database import Database from app.dependencies.user import ClientUser from app.models.user import Page from app.models.userpage import ( UpdateUserpageRequest, UpdateUserpageResponse, UserpageError, ValidateBBCodeRequest, ValidateBBCodeResponse, ) from app.service.bbcode_service import bbcode_service from app.utils import utcnow from .router import router from fastapi import Body, HTTPException from sqlmodel import exists, select @router.post("/rename", name="修改用户名", tags=["用户", "g0v0 API"]) async def user_rename( session: Database, new_name: Annotated[str, Body(..., description="新的用户名")], current_user: ClientUser, ): """修改用户名 为指定用户修改用户名,并将原用户名添加到历史用户名列表中 错误情况: - 404: 找不到指定用户 - 409: 新用户名已被占用 返回: - 成功: None """ samename_user = (await session.exec(select(exists()).where(User.username == new_name))).first() if samename_user: raise HTTPException(409, "Username Exisits") errors = validate_username(new_name) if errors: raise HTTPException(403, "\n".join(errors)) previous_username = [] previous_username.extend(current_user.previous_usernames) previous_username.append(current_user.username) current_user.username = new_name current_user.previous_usernames = previous_username rename_event = Event( created_at=utcnow(), type=EventType.USERNAME_CHANGE, user_id=current_user.id, user=current_user, ) rename_event.event_payload["user"] = { "username": new_name, "url": settings.web_url + "users/" + str(current_user.id), "previous_username": current_user.previous_usernames[-1], } session.add(rename_event) await session.commit() return None @router.put( "/user/page", response_model=UpdateUserpageResponse, name="更新用户页面", description="更新指定用户的个人页面内容(支持BBCode)。匹配官方osu-web API格式。", tags=["用户", "g0v0 API"], ) async def update_userpage( request: UpdateUserpageRequest, session: Database, current_user: ClientUser, ): """更新用户页面内容""" try: # 处理BBCode内容 processed_page = bbcode_service.process_userpage_content(request.body) # 更新数据库 - 直接更新用户对象 current_user.page = Page(html=processed_page["html"], raw=processed_page["raw"]) session.add(current_user) await session.commit() await session.refresh(current_user) # 返回官方格式的响应:只包含html return UpdateUserpageResponse(html=processed_page["html"]) except UserpageError as e: # 使用官方格式的错误响应:{'error': message} raise HTTPException(status_code=422, detail={"error": e.message}) except Exception: raise HTTPException(status_code=500, detail={"error": "Failed to update user page"}) @router.post( "/user/validate-bbcode", response_model=ValidateBBCodeResponse, name="验证BBCode", description="验证BBCode语法并返回预览。", tags=["用户", "g0v0 API"], ) async def validate_bbcode( request: ValidateBBCodeRequest, ): """验证BBCode语法""" try: # 验证BBCode语法 errors = bbcode_service.validate_bbcode(request.content) # 生成预览(如果没有严重错误) if len(errors) == 0: preview = bbcode_service.process_userpage_content(request.content) else: preview = {"raw": request.content, "html": ""} return ValidateBBCodeResponse(valid=len(errors) == 0, errors=errors, preview=preview) except UserpageError as e: return ValidateBBCodeResponse(valid=False, errors=[e.message], preview={"raw": request.content, "html": ""}) except Exception: raise HTTPException(status_code=500, detail={"error": "Failed to validate BBCode"})