# app/services/user_service.py from sqlalchemy.orm import Session from sqlalchemy import or_ from typing import Optional, List from datetime import datetime from ..models.user import User from ..core.security import password_hasher, password_validator from ..schemas.user import UserCreate, UserUpdate, UserResponse class UserService: """用户服务""" def __init__(self, db: Session): self.db = db async def create_user(self, user_data: UserCreate) -> User: """创建用户""" # 验证密码强度 is_valid, error_msg = password_validator.validate_password_strength(user_data.password) if not is_valid: raise ValueError(error_msg) # 检查用户是否已存在 existing_user = self.db.query(User).filter( or_( User.username == user_data.username, User.email == user_data.email ) ).first() if existing_user: if existing_user.username == user_data.username: raise ValueError("用户名已存在") else: raise ValueError("邮箱已被注册") # 哈希密码 hashed_password = password_hasher.hash_password(user_data.password) # 创建用户 user = User( username=user_data.username, email=user_data.email, hashed_password=hashed_password, full_name=user_data.full_name, is_active=True, is_verified=False ) self.db.add(user) self.db.commit() self.db.refresh(user) return user async def get_user_by_id(self, user_id: int) -> Optional[User]: """通过ID获取用户""" return self.db.query(User).filter(User.id == user_id).first() async def get_user_by_username(self, username: str) -> Optional[User]: """通过用户名获取用户""" return self.db.query(User).filter(User.username == username).first() async def get_user_by_email(self, email: str) -> Optional[User]: """通过邮箱获取用户""" return self.db.query(User).filter(User.email == email).first() async def authenticate_user(self, username: str, password: str) -> Optional[User]: """验证用户""" # 通过用户名或邮箱查找用户 user = self.db.query(User).filter( or_( User.username == username, User.email == username ) ).first() if not user: return None if not password_hasher.verify_password(password, user.hashed_password): # 记录失败尝试 user.failed_login_attempts += 1 if user.failed_login_attempts >= 5: user.is_locked = True self.db.commit() return None # 重置失败尝试 user.failed_login_attempts = 0 user.last_login = datetime.now() user.is_locked = False self.db.commit() return user async def update_user(self, user_id: int, update_data: dict) -> Optional[User]: """更新用户信息""" user = await self.get_user_by_id(user_id) if not user: return None for key, value in update_data.items(): if hasattr(user, key) and value is not None: setattr(user, key, value) user.updated_at = datetime.now() self.db.commit() self.db.refresh(user) return user async def change_password(self, user_id: int, current_password: str, new_password: str) -> bool: """修改密码""" user = await self.get_user_by_id(user_id) if not user: return False # 验证当前密码 if not password_hasher.verify_password(current_password, user.hashed_password): return False # 验证新密码强度 is_valid, error_msg = password_validator.validate_password_strength(new_password) if not is_valid: raise ValueError(error_msg) # 更新密码 user.hashed_password = password_hasher.hash_password(new_password) user.last_password_change = datetime.now() self.db.commit() return True async def list_users( self, skip: int = 0, limit: int = 100, active_only: bool = True ) -> List[User]: """列出用户""" query = self.db.query(User) if active_only: query = query.filter(User.is_active == True) return query.offset(skip).limit(limit).all() async def delete_user(self, user_id: int) -> bool: """删除用户(软删除)""" user = await self.get_user_by_id(user_id) if not user: return False user.is_active = False user.updated_at = datetime.now() self.db.commit() return True async def count_users(self, active_only: bool = True) -> int: """统计用户数量""" query = self.db.query(User) if active_only: query = query.filter(User.is_active == True) return query.count()