| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169 |
- # 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()
|