hyf-backend/th_agenter/api/endpoints/users.py

248 lines
9.0 KiB
Python

"""User management endpoints."""
from typing import List, Optional
from fastapi import APIRouter, Depends, HTTPException, status, Query
from sqlalchemy.orm import Session
from ...db.database import get_session
from ...core.simple_permissions import require_super_admin
from ...services.auth import AuthService
from ...services.user import UserService
from ...schemas.user import UserResponse, UserUpdate, UserCreate, ChangePasswordRequest, ResetPasswordRequest
from utils.util_exceptions import HxfResponse
router = APIRouter()
@router.get("/profile", response_model=UserResponse, summary="获取当前用户的个人信息")
async def get_user_profile(
current_user = Depends(AuthService.get_current_user)
):
"""获取当前用户的个人信息."""
response = UserResponse.model_validate(current_user)
return HxfResponse(response)
@router.put("/profile", response_model=UserResponse, summary="更新当前用户的个人信息")
async def update_user_profile(
user_update: UserUpdate,
current_user = Depends(AuthService.get_current_user),
session: Session = Depends(get_session)
):
"""更新当前用户的个人信息."""
user_service = UserService(session)
# Check if email is being changed and is already taken
if user_update.email and user_update.email != current_user.email:
existing_user = await user_service.get_user_by_email(user_update.email)
if existing_user:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Email already registered"
)
# Update user
updated_user = await user_service.update_user(current_user.id, user_update)
response = UserResponse.model_validate(updated_user)
return HxfResponse(response)
@router.delete("/profile", summary="删除当前用户的账户")
async def delete_user_account(
current_user = Depends(AuthService.get_current_user),
session: Session = Depends(get_session)
):
"""删除当前用户的账户."""
username = current_user.username
user_service = UserService(session)
await user_service.delete_user(current_user.id)
session.desc = f"删除用户 [{username}] 成功"
response = {"message": f"删除用户 {username} 成功"}
return HxfResponse(response)
# Admin endpoints
@router.post("/", response_model=UserResponse, summary="创建新用户 (需要有管理员权限)")
async def create_user(
user_create: UserCreate,
current_user = Depends(require_super_admin),
session: Session = Depends(get_session)
):
"""创建一个新用户 (需要有管理员权限)."""
user_service = UserService(session)
# Check if username already exists
existing_user = await user_service.get_user_by_username(user_create.username)
if existing_user:
session.desc = f"创建用户 [{user_create.username}] 失败 - 用户名已存在"
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Username already registered"
)
# Check if email already exists
existing_user = await user_service.get_user_by_email(user_create.email)
if existing_user:
session.desc = f"创建用户 [{user_create.username}] 失败 - 邮箱已存在"
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Email already registered"
)
# Create user
new_user = await user_service.create_user(user_create)
response = UserResponse.model_validate(new_user)
return HxfResponse(response)
@router.get("/", summary="列出所有用户,支持分页和筛选 (仅管理员权限)")
async def list_users(
page: int = Query(1, ge=1),
size: int = Query(20, ge=1, le=100),
search: Optional[str] = Query(None),
role_id: Optional[int] = Query(None),
is_active: Optional[bool] = Query(None),
session: Session = Depends(get_session)
):
"""列出所有用户,支持分页和筛选 (仅管理员权限)."""
session.desc = f"START: 列出所有用户,分页={page}, 每页大小={size}, 搜索={search}, 角色ID={role_id}, 激活状态={is_active}"
user_service = UserService(session)
skip = (page - 1) * size
users, total = await user_service.get_users_with_filters(
skip=skip,
limit=size,
search=search,
role_id=role_id,
is_active=is_active
)
result = {
"users": [UserResponse.model_validate(user) for user in users],
"total": total,
"page": page,
"page_size": size
}
return HxfResponse(result)
@router.get("/{user_id}", response_model=UserResponse, summary="通过ID获取用户信息 (仅管理员权限)")
async def get_user(
user_id: int,
current_user = Depends(AuthService.get_current_active_user),
session: Session = Depends(get_session)
):
"""通过ID获取用户信息 (仅管理员权限)."""
user_service = UserService(session)
user = await user_service.get_user_by_id(user_id)
if not user:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="User not found"
)
response = UserResponse.model_validate(user)
return HxfResponse(response)
@router.put("/change-password", summary="修改当前用户的密码")
async def change_password(
request: ChangePasswordRequest,
current_user = Depends(AuthService.get_current_active_user),
session: Session = Depends(get_session)
):
"""修改当前用户的密码."""
user_service = UserService(session)
try:
await user_service.change_password(
user_id=current_user.id,
current_password=request.current_password,
new_password=request.new_password
)
response = {"message": "Password changed successfully"}
return HxfResponse(response)
except Exception as e:
if "Current password is incorrect" in str(e):
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Current password is incorrect"
)
elif "must be at least 6 characters" in str(e):
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="New password must be at least 6 characters long"
)
else:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="Failed to change password"
)
@router.put("/{user_id}/reset-password", summary="重置用户密码 (仅管理员权限)")
async def reset_user_password(
user_id: int,
request: ResetPasswordRequest,
current_user = Depends(require_super_admin),
session: Session = Depends(get_session)
):
"""重置用户密码 (仅管理员权限)."""
user_service = UserService(session)
try:
await user_service.reset_password(
user_id=user_id,
new_password=request.new_password
)
response = {"message": "Password reset successfully"}
return HxfResponse(response)
except Exception as e:
if "User not found" in str(e):
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="User not found"
)
elif "must be at least 6 characters" in str(e):
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="New password must be at least 6 characters long"
)
else:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="Failed to reset password"
)
@router.put("/{user_id}", response_model=UserResponse, summary="更新用户信息 (仅管理员权限)")
async def update_user(
user_id: int,
user_update: UserUpdate,
current_user = Depends(AuthService.get_current_active_user),
session: Session = Depends(get_session)
):
"""更新用户信息 (仅管理员权限)."""
user_service = UserService(session)
user = await user_service.get_user_by_id(user_id)
if not user:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="User not found"
)
updated_user = await user_service.update_user(user_id, user_update)
response = UserResponse.model_validate(updated_user)
return HxfResponse(response)
@router.delete("/{user_id}", summary="删除用户 (仅管理员权限)")
async def delete_user(
user_id: int,
current_user = Depends(AuthService.get_current_active_user),
session: Session = Depends(get_session)
):
"""删除用户 (仅管理员权限)."""
user_service = UserService(session)
user = await user_service.get_user_by_id(user_id)
if not user:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="User not found"
)
await user_service.delete_user(user_id)
response = {"message": "User deleted successfully"}
return HxfResponse(response)