286 lines
7.6 KiB
Python
286 lines
7.6 KiB
Python
|
|
"""用户管理服务 - FastAPI 应用入口模块。
|
|||
|
|
|
|||
|
|
提供用户注册、登录、查询、更新、删除等 RESTful API 接口。
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
from typing import Optional
|
|||
|
|
|
|||
|
|
from fastapi import FastAPI, HTTPException, Query, status
|
|||
|
|
from fastapi.middleware.cors import CORSMiddleware
|
|||
|
|
|
|||
|
|
from app.models import (
|
|||
|
|
ErrorResponse,
|
|||
|
|
SuccessResponse,
|
|||
|
|
UserCreate,
|
|||
|
|
UserLogin,
|
|||
|
|
UserResponse,
|
|||
|
|
UserUpdate,
|
|||
|
|
)
|
|||
|
|
from app.services import (
|
|||
|
|
create_user,
|
|||
|
|
delete_user,
|
|||
|
|
get_all_users,
|
|||
|
|
get_user_by_id,
|
|||
|
|
get_user_count,
|
|||
|
|
login,
|
|||
|
|
update_user,
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
# 创建 FastAPI 应用实例
|
|||
|
|
app = FastAPI(
|
|||
|
|
title="User Management API",
|
|||
|
|
description="用户管理服务 - 提供用户注册、登录、CRUD 等基础功能",
|
|||
|
|
version="1.0.0",
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
# 添加 CORS 中间件,允许跨域访问
|
|||
|
|
app.add_middleware(
|
|||
|
|
CORSMiddleware,
|
|||
|
|
allow_origins=["*"],
|
|||
|
|
allow_credentials=True,
|
|||
|
|
allow_methods=["*"],
|
|||
|
|
allow_headers=["*"],
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
|
|||
|
|
@app.get("/health", tags=["系统"])
|
|||
|
|
async def health_check():
|
|||
|
|
"""健康检查接口。
|
|||
|
|
|
|||
|
|
Returns:
|
|||
|
|
服务运行状态信息
|
|||
|
|
"""
|
|||
|
|
return {
|
|||
|
|
"status": "ok",
|
|||
|
|
"service": "user-management-service",
|
|||
|
|
"version": "1.0.0",
|
|||
|
|
"total_users": get_user_count(),
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
# ──────────────────────────────────────────────
|
|||
|
|
# 用户管理 API
|
|||
|
|
# ──────────────────────────────────────────────
|
|||
|
|
|
|||
|
|
|
|||
|
|
@app.post(
|
|||
|
|
"/api/users",
|
|||
|
|
response_model=UserResponse,
|
|||
|
|
status_code=status.HTTP_201_CREATED,
|
|||
|
|
tags=["用户管理"],
|
|||
|
|
summary="注册新用户",
|
|||
|
|
description="创建一个新的用户账户,需要提供用户名、邮箱和密码。",
|
|||
|
|
responses={
|
|||
|
|
201: {"description": "用户创建成功", "model": UserResponse},
|
|||
|
|
400: {"description": "请求数据不合法", "model": ErrorResponse},
|
|||
|
|
409: {"description": "用户名或邮箱已被占用", "model": ErrorResponse},
|
|||
|
|
},
|
|||
|
|
)
|
|||
|
|
async def api_create_user(user_data: UserCreate):
|
|||
|
|
"""用户注册接口。
|
|||
|
|
|
|||
|
|
Args:
|
|||
|
|
user_data: 用户注册信息(用户名、邮箱、密码)
|
|||
|
|
|
|||
|
|
Returns:
|
|||
|
|
创建成功的用户信息
|
|||
|
|
|
|||
|
|
Raises:
|
|||
|
|
HTTPException: 当输入验证失败或用户名/邮箱已存在时抛出
|
|||
|
|
"""
|
|||
|
|
try:
|
|||
|
|
return create_user(user_data)
|
|||
|
|
except ValueError as e:
|
|||
|
|
raise HTTPException(
|
|||
|
|
status_code=status.HTTP_409_CONFLICT,
|
|||
|
|
detail=str(e),
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
|
|||
|
|
@app.get(
|
|||
|
|
"/api/users",
|
|||
|
|
response_model=list[UserResponse],
|
|||
|
|
tags=["用户管理"],
|
|||
|
|
summary="获取用户列表",
|
|||
|
|
description="分页获取所有用户信息列表。",
|
|||
|
|
)
|
|||
|
|
async def api_get_users(
|
|||
|
|
skip: int = Query(0, ge=0, description="跳过的记录数"),
|
|||
|
|
limit: int = Query(10, ge=1, le=100, description="每页数量"),
|
|||
|
|
):
|
|||
|
|
"""获取用户列表接口。
|
|||
|
|
|
|||
|
|
Args:
|
|||
|
|
skip: 跳过的记录数,默认 0
|
|||
|
|
limit: 每页数量,默认 10,最大 100
|
|||
|
|
|
|||
|
|
Returns:
|
|||
|
|
用户信息列表
|
|||
|
|
"""
|
|||
|
|
return get_all_users(skip, limit)
|
|||
|
|
|
|||
|
|
|
|||
|
|
@app.get(
|
|||
|
|
"/api/users/{user_id}",
|
|||
|
|
response_model=UserResponse,
|
|||
|
|
tags=["用户管理"],
|
|||
|
|
summary="获取单个用户",
|
|||
|
|
description="根据用户 ID 获取指定用户的详细信息。",
|
|||
|
|
responses={
|
|||
|
|
200: {"description": "成功获取用户信息", "model": UserResponse},
|
|||
|
|
404: {"description": "用户不存在", "model": ErrorResponse},
|
|||
|
|
},
|
|||
|
|
)
|
|||
|
|
async def api_get_user(user_id: str):
|
|||
|
|
"""获取单个用户接口。
|
|||
|
|
|
|||
|
|
Args:
|
|||
|
|
user_id: 用户 ID
|
|||
|
|
|
|||
|
|
Returns:
|
|||
|
|
用户详细信息
|
|||
|
|
|
|||
|
|
Raises:
|
|||
|
|
HTTPException: 当用户不存在时抛出 404
|
|||
|
|
"""
|
|||
|
|
user = get_user_by_id(user_id)
|
|||
|
|
if user is None:
|
|||
|
|
raise HTTPException(
|
|||
|
|
status_code=status.HTTP_404_NOT_FOUND,
|
|||
|
|
detail=f"用户 '{user_id}' 不存在",
|
|||
|
|
)
|
|||
|
|
return user
|
|||
|
|
|
|||
|
|
|
|||
|
|
@app.put(
|
|||
|
|
"/api/users/{user_id}",
|
|||
|
|
response_model=UserResponse,
|
|||
|
|
tags=["用户管理"],
|
|||
|
|
summary="更新用户信息",
|
|||
|
|
description="更新指定用户的用户名和/或邮箱。",
|
|||
|
|
responses={
|
|||
|
|
200: {"description": "更新成功", "model": UserResponse},
|
|||
|
|
404: {"description": "用户不存在", "model": ErrorResponse},
|
|||
|
|
409: {"description": "新用户名已被占用", "model": ErrorResponse},
|
|||
|
|
},
|
|||
|
|
)
|
|||
|
|
async def api_update_user(user_id: str, update_data: UserUpdate):
|
|||
|
|
"""更新用户信息接口。
|
|||
|
|
|
|||
|
|
Args:
|
|||
|
|
user_id: 要更新的用户 ID
|
|||
|
|
update_data: 待更新的字段
|
|||
|
|
|
|||
|
|
Returns:
|
|||
|
|
更新后的用户信息
|
|||
|
|
|
|||
|
|
Raises:
|
|||
|
|
HTTPException: 用户不存在抛出 404,用户名冲突抛出 409
|
|||
|
|
"""
|
|||
|
|
try:
|
|||
|
|
result = update_user(user_id, update_data)
|
|||
|
|
if result is None:
|
|||
|
|
raise HTTPException(
|
|||
|
|
status_code=status.HTTP_404_NOT_FOUND,
|
|||
|
|
detail=f"用户 '{user_id}' 不存在",
|
|||
|
|
)
|
|||
|
|
return result
|
|||
|
|
except ValueError as e:
|
|||
|
|
raise HTTPException(
|
|||
|
|
status_code=status.HTTP_409_CONFLICT,
|
|||
|
|
detail=str(e),
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
|
|||
|
|
@app.delete(
|
|||
|
|
"/api/users/{user_id}",
|
|||
|
|
response_model=SuccessResponse,
|
|||
|
|
tags=["用户管理"],
|
|||
|
|
summary="删除用户",
|
|||
|
|
description="删除指定的用户账户。",
|
|||
|
|
responses={
|
|||
|
|
200: {"description": "删除成功", "model": SuccessResponse},
|
|||
|
|
404: {"description": "用户不存在", "model": ErrorResponse},
|
|||
|
|
},
|
|||
|
|
)
|
|||
|
|
async def api_delete_user(user_id: str):
|
|||
|
|
"""删除用户接口。
|
|||
|
|
|
|||
|
|
Args:
|
|||
|
|
user_id: 要删除的用户 ID
|
|||
|
|
|
|||
|
|
Returns:
|
|||
|
|
删除成功消息
|
|||
|
|
|
|||
|
|
Raises:
|
|||
|
|
HTTPException: 用户不存在时抛出 404
|
|||
|
|
"""
|
|||
|
|
success = delete_user(user_id)
|
|||
|
|
if not success:
|
|||
|
|
raise HTTPException(
|
|||
|
|
status_code=status.HTTP_404_NOT_FOUND,
|
|||
|
|
detail=f"用户 '{user_id}' 不存在",
|
|||
|
|
)
|
|||
|
|
return {"message": f"用户 '{user_id}' 已成功删除"}
|
|||
|
|
|
|||
|
|
|
|||
|
|
# ──────────────────────────────────────────────
|
|||
|
|
# 用户登录 API
|
|||
|
|
# ──────────────────────────────────────────────
|
|||
|
|
|
|||
|
|
|
|||
|
|
@app.post(
|
|||
|
|
"/api/users/login",
|
|||
|
|
response_model=UserResponse,
|
|||
|
|
tags=["用户管理"],
|
|||
|
|
summary="用户登录",
|
|||
|
|
description="使用用户名和密码进行登录验证。",
|
|||
|
|
responses={
|
|||
|
|
200: {"description": "登录成功", "model": UserResponse},
|
|||
|
|
401: {"description": "用户名或密码错误", "model": ErrorResponse},
|
|||
|
|
},
|
|||
|
|
)
|
|||
|
|
async def api_login(login_data: UserLogin):
|
|||
|
|
"""用户登录接口。
|
|||
|
|
|
|||
|
|
Args:
|
|||
|
|
login_data: 登录凭证(用户名和密码)
|
|||
|
|
|
|||
|
|
Returns:
|
|||
|
|
登录成功的用户信息
|
|||
|
|
|
|||
|
|
Raises:
|
|||
|
|
HTTPException: 用户名或密码错误时抛出 401
|
|||
|
|
"""
|
|||
|
|
user = login(login_data)
|
|||
|
|
if user is None:
|
|||
|
|
raise HTTPException(
|
|||
|
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
|||
|
|
detail="用户名或密码错误",
|
|||
|
|
)
|
|||
|
|
return user
|
|||
|
|
|
|||
|
|
|
|||
|
|
# ──────────────────────────────────────────────
|
|||
|
|
# 应用入口
|
|||
|
|
# ──────────────────────────────────────────────
|
|||
|
|
|
|||
|
|
|
|||
|
|
def main():
|
|||
|
|
"""启动 FastAPI 应用的入口函数。
|
|||
|
|
|
|||
|
|
使用 uvicorn 运行服务,监听 0.0.0.0:8000。
|
|||
|
|
"""
|
|||
|
|
import uvicorn
|
|||
|
|
|
|||
|
|
uvicorn.run(
|
|||
|
|
"app.main:app",
|
|||
|
|
host="0.0.0.0",
|
|||
|
|
port=8000,
|
|||
|
|
reload=True,
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
|
|||
|
|
if __name__ == "__main__":
|
|||
|
|
main()
|