✨ feat(vscode): 代码阅读函数、导入、常量、变量块预览改成属性表
This commit is contained in:
1 parent
0c4c9b0fba
commit
dd9b39ac5d
19 files changed
+1458
-213
No files matched your search
@@ -0,0 +1,126 @@
|
||||
"""用户管理路由。
|
||||
|
||||
提供用户自助查看 / 更新资料与上传头像接口。
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Annotated
|
||||
|
||||
from fastapi import APIRouter, Depends, File, UploadFile
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from luffy_agent.core.db import get_db
|
||||
from luffy_agent.core.exceptions import Forbidden
|
||||
from luffy_agent.core.params import Int4Path
|
||||
from luffy_agent.user.auth.deps import get_current_user
|
||||
|
||||
from .models import User, UserRole
|
||||
from .schemas import (
|
||||
UserAvatarUploadResponse,
|
||||
UserDetailResponse,
|
||||
UserUpdateRequest,
|
||||
)
|
||||
from .services import user_service
|
||||
|
||||
router = APIRouter(tags=["用户管理"], prefix="/users")
|
||||
|
||||
|
||||
@router.get("/{user_id}", response_model=UserDetailResponse)
|
||||
async def get_user(
|
||||
user_id: Int4Path,
|
||||
db: AsyncSession = Depends(get_db),
|
||||
current_user: User = Depends(get_current_user),
|
||||
) -> UserDetailResponse:
|
||||
"""获取用户详情。
|
||||
|
||||
管理员可查看任意用户,普通用户只能查看自己。
|
||||
"""
|
||||
# 非管理员只能查看自己
|
||||
if current_user.role != UserRole.ADMIN and current_user.id != user_id:
|
||||
raise Forbidden("无权查看此用户信息")
|
||||
|
||||
user = await user_service.get_user(db, user_id=user_id)
|
||||
|
||||
return UserDetailResponse(
|
||||
id=user.id,
|
||||
username=user.username,
|
||||
display_name=user.display_name,
|
||||
role=user.role.value,
|
||||
email=user.email,
|
||||
phone=user.phone,
|
||||
bio=user.bio,
|
||||
avatar_url=user.avatar_url,
|
||||
is_active=user.is_active,
|
||||
created_at=user.created_at,
|
||||
updated_at=user.updated_at,
|
||||
)
|
||||
|
||||
|
||||
@router.put("/{user_id}", response_model=UserDetailResponse)
|
||||
async def update_user(
|
||||
user_id: Int4Path,
|
||||
body: UserUpdateRequest,
|
||||
db: AsyncSession = Depends(get_db),
|
||||
current_user: User = Depends(get_current_user),
|
||||
) -> UserDetailResponse:
|
||||
"""更新用户信息。
|
||||
|
||||
管理员可更新任意用户,普通用户只能更新自己的基础资料。
|
||||
"""
|
||||
# 非管理员只能更新自己
|
||||
if current_user.role != UserRole.ADMIN and current_user.id != user_id:
|
||||
raise Forbidden("无权更新此用户信息")
|
||||
|
||||
if current_user.role != UserRole.ADMIN:
|
||||
if body.role is not None:
|
||||
raise Forbidden("无权修改角色")
|
||||
if body.is_active is not None:
|
||||
raise Forbidden("无权修改启用状态")
|
||||
if body.password is not None:
|
||||
raise Forbidden("无权修改密码")
|
||||
|
||||
user = await user_service.update_user(
|
||||
db,
|
||||
user_id=user_id,
|
||||
display_name=body.display_name,
|
||||
email=body.email,
|
||||
phone=body.phone,
|
||||
bio=body.bio,
|
||||
avatar_url=body.avatar_url,
|
||||
role=body.role,
|
||||
is_active=body.is_active,
|
||||
password=body.password,
|
||||
)
|
||||
|
||||
return UserDetailResponse(
|
||||
id=user.id,
|
||||
username=user.username,
|
||||
display_name=user.display_name,
|
||||
role=user.role.value,
|
||||
email=user.email,
|
||||
phone=user.phone,
|
||||
bio=user.bio,
|
||||
avatar_url=user.avatar_url,
|
||||
is_active=user.is_active,
|
||||
created_at=user.created_at,
|
||||
updated_at=user.updated_at,
|
||||
)
|
||||
|
||||
|
||||
@router.post("/me/avatar", response_model=UserAvatarUploadResponse)
|
||||
async def upload_current_user_avatar(
|
||||
file: Annotated[UploadFile, File(..., description="头像文件")],
|
||||
db: AsyncSession = Depends(get_db),
|
||||
current_user: User = Depends(get_current_user),
|
||||
) -> UserAvatarUploadResponse:
|
||||
"""上传当前登录用户头像。"""
|
||||
payload = await file.read()
|
||||
avatar_url = await user_service.upload_avatar(
|
||||
db,
|
||||
user_id=current_user.id,
|
||||
file_name=file.filename or "avatar.bin",
|
||||
content_type=file.content_type,
|
||||
payload=payload,
|
||||
)
|
||||
return UserAvatarUploadResponse(avatar_url=avatar_url)
|
||||
Reference in new issue
Block a user