| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322 |
- """
- Steam账号管理服务
- 处理Steam账号的绑定、查询等操作。敏感信息存客户端本地,数据库仅记录账号绑定关系。
- 每用户最大绑定数由表 user_steam_account_limit 管理,默认 3。
- """
- from typing import Optional, Tuple
- from sqlalchemy.orm import Session
- from app.models.steam_account import SteamAccount
- from app.models.user_steam_account_limit import UserSteamAccountLimit
- from app.core.logger import logger
- from app.utils.timezone import beijing_now_naive
- DEFAULT_MAX_STEAM_ACCOUNTS = 3
- class SteamAccountService:
- """Steam账号服务"""
- def __init__(self, db: Session):
- self.db = db
- def _get_max_steam_accounts_for_user(self, user_id: int) -> int:
- """查询该用户允许绑定的最大 Steam 账号数;无记录时默认 3。"""
- try:
- row = (
- self.db.query(UserSteamAccountLimit)
- .filter(UserSteamAccountLimit.user_id == user_id)
- .first()
- )
- if not row:
- return DEFAULT_MAX_STEAM_ACCOUNTS
- return max(1, int(row.max_steam_accounts))
- except Exception:
- return DEFAULT_MAX_STEAM_ACCOUNTS
- def get_steam_account_limit(self, user_id: int) -> Tuple[bool, str, dict]:
- """
- 获取用户 Steam 账号绑定限制信息。
- 返回:max_steam_accounts(最大可绑定数)、current_bound_count(已验证绑定数)。
- """
- try:
- max_count = self._get_max_steam_accounts_for_user(user_id)
- current_bound = (
- self.db.query(SteamAccount)
- .filter(
- SteamAccount.user_id == user_id,
- SteamAccount.is_deleted == 0,
- SteamAccount.steam_id.isnot(None),
- SteamAccount.steam_id != "",
- )
- .count()
- )
- return True, "获取成功", {
- "max_steam_accounts": max_count,
- "current_bound_count": current_bound,
- }
- except Exception as e:
- logger.exception(f"获取Steam账号限制失败: {e}")
- return False, f"获取失败: {str(e)}", {}
- def create_steam_account(
- self,
- user_id: int,
- steam_username: str,
- steam_id: Optional[str] = None,
- ) -> Tuple[bool, str, dict]:
- """
- 绑定 Steam 账号(仅记录账号标识,敏感信息存客户端本地)。
- Args:
- user_id: 用户ID
- steam_username: Steam 用户名
- steam_id: Steam ID(可选,来自客户端登录验证结果)
- Returns:
- (success, message, account_data)
- """
- try:
- # 检查是否已绑定相同 Steam 账号
- existing = (
- self.db.query(SteamAccount)
- .filter(
- SteamAccount.user_id == user_id,
- SteamAccount.steam_username == steam_username,
- SteamAccount.is_deleted == 0,
- )
- .first()
- )
- if existing:
- return False, "该Steam账号已绑定", {}
- # 仅当本次是“验证绑定”(带 steam_id)时检查上限;仅新增(steam_id 为空)不占绑定名额
- if steam_id:
- max_count = self._get_max_steam_accounts_for_user(user_id)
- current_bound = (
- self.db.query(SteamAccount)
- .filter(
- SteamAccount.user_id == user_id,
- SteamAccount.is_deleted == 0,
- SteamAccount.steam_id.isnot(None),
- SteamAccount.steam_id != "",
- )
- .count()
- )
- if current_bound >= max_count:
- return False, f"已达到最大绑定数量({max_count} 个),无法再绑定更多 Steam 账号", {}
- account = SteamAccount(
- user_id=user_id,
- steam_username=steam_username,
- steam_id=steam_id,
- is_active=True,
- )
- self.db.add(account)
- self.db.commit()
- logger.info(f"Steam账号绑定成功: user_id={user_id}, steam_username={steam_username}")
- return True, "绑定成功", {
- "id": account.id,
- "steam_username": account.steam_username,
- "steam_id": account.steam_id,
- "is_active": account.is_active,
- "created_at": account.created_at.isoformat(),
- }
- except Exception as e:
- self.db.rollback()
- logger.exception(f"Steam账号绑定失败: {e}")
- return False, f"绑定失败: {str(e)}", {}
- def bind_steam_account(
- self,
- user_id: int,
- steam_username: str,
- steam_id: str,
- ) -> Tuple[bool, str, dict]:
- """
- 对已新增的 Steam 账号进行验证绑定:将 steam_id 写入该账号记录。
- 仅当“已验证绑定数”未达上限时允许。
- """
- try:
- max_count = self._get_max_steam_accounts_for_user(user_id)
- current_bound = (
- self.db.query(SteamAccount)
- .filter(
- SteamAccount.user_id == user_id,
- SteamAccount.is_deleted == 0,
- SteamAccount.steam_id.isnot(None),
- SteamAccount.steam_id != "",
- )
- .count()
- )
- if current_bound >= max_count:
- return False, f"已达到最大绑定数量({max_count} 个),无法再绑定更多 Steam 账号", {}
- account = (
- self.db.query(SteamAccount)
- .filter(
- SteamAccount.user_id == user_id,
- SteamAccount.steam_username == steam_username,
- SteamAccount.is_deleted == 0,
- SteamAccount.steam_id.is_(None),
- )
- .first()
- )
- if not account:
- account_empty = (
- self.db.query(SteamAccount)
- .filter(
- SteamAccount.user_id == user_id,
- SteamAccount.steam_username == steam_username,
- SteamAccount.is_deleted == 0,
- )
- .first()
- )
- if account_empty and account_empty.steam_id:
- return False, "该Steam账号已绑定", {}
- return False, "请先新增该Steam账号后再进行验证绑定", {}
- account.steam_id = steam_id
- self.db.commit()
- logger.info(f"Steam账号验证绑定成功: user_id={user_id}, steam_username={steam_username}")
- return True, "绑定成功", {
- "id": account.id,
- "steam_username": account.steam_username,
- "steam_id": account.steam_id,
- "is_active": account.is_active,
- "created_at": account.created_at.isoformat(),
- }
- except Exception as e:
- self.db.rollback()
- logger.exception(f"Steam账号验证绑定失败: {e}")
- return False, f"绑定失败: {str(e)}", {}
- def get_accounts_by_user(self, user_id: int) -> Tuple[bool, str, list]:
- """
- 获取用户绑定的所有Steam账号
- Args:
- user_id: 用户ID
- Returns:
- (success, message, accounts_list)
- """
- try:
- accounts = self.db.query(SteamAccount).filter(
- SteamAccount.user_id == user_id,
- SteamAccount.is_deleted == 0
- ).all()
- result = []
- for acc in accounts:
- # 隐藏敏感信息
- result.append({
- "id": acc.id,
- "steam_username": acc.steam_username,
- "steam_id": acc.steam_id,
- "is_active": acc.is_active,
- "created_at": acc.created_at.isoformat()
- })
- return True, "获取成功", result
- except Exception as e:
- logger.exception(f"获取Steam账号列表失败: {e}")
- return False, f"获取失败: {str(e)}", []
- def get_account_by_id(self, account_id: int, user_id: int) -> Optional[SteamAccount]:
- """
- 根据ID获取账号(验证所有权)
- Args:
- account_id: 账号ID
- user_id: 用户ID
- Returns:
- SteamAccount or None
- """
- return self.db.query(SteamAccount).filter(
- SteamAccount.id == account_id,
- SteamAccount.user_id == user_id,
- SteamAccount.is_deleted == 0
- ).first()
- def update_account(
- self,
- account_id: int,
- user_id: int,
- is_active: bool = None
- ) -> Tuple[bool, str]:
- """
- 更新账号状态
- Args:
- account_id: 账号ID
- user_id: 用户ID
- is_active: 是否启用
- Returns:
- (success, message)
- """
- try:
- account = self.get_account_by_id(account_id, user_id)
- if not account:
- return False, "账号不存在"
- if is_active is not None:
- account.is_active = is_active
- self.db.commit()
- logger.info(f"Steam账号更新成功: account_id={account_id}")
- return True, "更新成功"
- except Exception as e:
- self.db.rollback()
- logger.exception(f"更新Steam账号失败: {e}")
- return False, f"更新失败: {str(e)}"
- def delete_account(self, account_id: int, user_id: int) -> Tuple[bool, str]:
- """
- 解绑Steam账号 (软删除)
- Args:
- account_id: 账号ID
- user_id: 用户ID
- Returns:
- (success, message)
- """
- try:
- account = self.get_account_by_id(account_id, user_id)
- if not account:
- return False, "账号不存在"
- # 已绑定的账号不可删除
- if account.steam_id and str(account.steam_id).strip():
- return False, "已绑定的账号不可删除,请先解绑"
- # 先写历史表,再改/删
- from app.utils.history import create_steam_account_history
- create_steam_account_history(self.db, account, "DELETE")
- # 软删除
- account.is_deleted = True
- self.db.commit()
- logger.info(f"Steam账号解绑成功: account_id={account_id}")
- return True, "解绑成功"
- except Exception as e:
- self.db.rollback()
- logger.exception(f"解绑Steam账号失败: {e}")
- return False, f"解绑失败: {str(e)}"
|