CaiYouHui后端fastapi实现

user_service.py 5.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. # app/services/user_service.py
  2. from sqlalchemy.orm import Session
  3. from sqlalchemy import or_
  4. from typing import Optional, List
  5. from datetime import datetime
  6. from ..models.user import User
  7. from ..core.security import password_hasher, password_validator
  8. from ..schemas.user import UserCreate, UserUpdate, UserResponse
  9. class UserService:
  10. """用户服务"""
  11. def __init__(self, db: Session):
  12. self.db = db
  13. async def create_user(self, user_data: UserCreate) -> User:
  14. """创建用户"""
  15. # 验证密码强度
  16. is_valid, error_msg = password_validator.validate_password_strength(user_data.password)
  17. if not is_valid:
  18. raise ValueError(error_msg)
  19. # 检查用户是否已存在
  20. existing_user = self.db.query(User).filter(
  21. or_(
  22. User.username == user_data.username,
  23. User.email == user_data.email
  24. )
  25. ).first()
  26. if existing_user:
  27. if existing_user.username == user_data.username:
  28. raise ValueError("用户名已存在")
  29. else:
  30. raise ValueError("邮箱已被注册")
  31. # 哈希密码
  32. hashed_password = password_hasher.hash_password(user_data.password)
  33. # 创建用户
  34. user = User(
  35. username=user_data.username,
  36. email=user_data.email,
  37. hashed_password=hashed_password,
  38. full_name=user_data.full_name,
  39. is_active=True,
  40. is_verified=False
  41. )
  42. self.db.add(user)
  43. self.db.commit()
  44. self.db.refresh(user)
  45. return user
  46. async def get_user_by_id(self, user_id: int) -> Optional[User]:
  47. """通过ID获取用户"""
  48. return self.db.query(User).filter(User.id == user_id).first()
  49. async def get_user_by_username(self, username: str) -> Optional[User]:
  50. """通过用户名获取用户"""
  51. return self.db.query(User).filter(User.username == username).first()
  52. async def get_user_by_email(self, email: str) -> Optional[User]:
  53. """通过邮箱获取用户"""
  54. return self.db.query(User).filter(User.email == email).first()
  55. async def authenticate_user(self, username: str, password: str) -> Optional[User]:
  56. """验证用户"""
  57. # 通过用户名或邮箱查找用户
  58. user = self.db.query(User).filter(
  59. or_(
  60. User.username == username,
  61. User.email == username
  62. )
  63. ).first()
  64. if not user:
  65. return None
  66. if not password_hasher.verify_password(password, user.hashed_password):
  67. # 记录失败尝试
  68. user.failed_login_attempts += 1
  69. if user.failed_login_attempts >= 5:
  70. user.is_locked = True
  71. self.db.commit()
  72. return None
  73. # 重置失败尝试
  74. user.failed_login_attempts = 0
  75. user.last_login = datetime.now()
  76. user.is_locked = False
  77. self.db.commit()
  78. return user
  79. async def update_user(self, user_id: int, update_data: dict) -> Optional[User]:
  80. """更新用户信息"""
  81. user = await self.get_user_by_id(user_id)
  82. if not user:
  83. return None
  84. for key, value in update_data.items():
  85. if hasattr(user, key) and value is not None:
  86. setattr(user, key, value)
  87. user.updated_at = datetime.now()
  88. self.db.commit()
  89. self.db.refresh(user)
  90. return user
  91. async def change_password(self, user_id: int, current_password: str, new_password: str) -> bool:
  92. """修改密码"""
  93. user = await self.get_user_by_id(user_id)
  94. if not user:
  95. return False
  96. # 验证当前密码
  97. if not password_hasher.verify_password(current_password, user.hashed_password):
  98. return False
  99. # 验证新密码强度
  100. is_valid, error_msg = password_validator.validate_password_strength(new_password)
  101. if not is_valid:
  102. raise ValueError(error_msg)
  103. # 更新密码
  104. user.hashed_password = password_hasher.hash_password(new_password)
  105. user.last_password_change = datetime.now()
  106. self.db.commit()
  107. return True
  108. async def list_users(
  109. self,
  110. skip: int = 0,
  111. limit: int = 100,
  112. active_only: bool = True
  113. ) -> List[User]:
  114. """列出用户"""
  115. query = self.db.query(User)
  116. if active_only:
  117. query = query.filter(User.is_active == True)
  118. return query.offset(skip).limit(limit).all()
  119. async def delete_user(self, user_id: int) -> bool:
  120. """删除用户(软删除)"""
  121. user = await self.get_user_by_id(user_id)
  122. if not user:
  123. return False
  124. user.is_active = False
  125. user.updated_at = datetime.now()
  126. self.db.commit()
  127. return True
  128. async def count_users(self, active_only: bool = True) -> int:
  129. """统计用户数量"""
  130. query = self.db.query(User)
  131. if active_only:
  132. query = query.filter(User.is_active == True)
  133. return query.count()