import asyncio from typing import Optional, Dict import time from sqlalchemy import select, update, insert from sqlalchemy.ext.asyncio import AsyncSession from utils.logger import session_logger from pydantic import BaseModel from database.models import Card as DBCard from services.database_service_base import DatabaseServiceBase class Card(BaseModel): card_id: Optional[int] = None card_uuid: str device_id: Optional[str] = None card_name: Optional[str] = None status: int = 0 total_swaps: int = 0 created_at: Optional[float] = None updated_at: Optional[float] = None @classmethod def from_db_model(cls, db_model: DBCard): """从数据库模型创建卡片对象""" return cls( card_id=db_model.card_id, card_uuid=db_model.card_uuid, device_id=db_model.device_id, card_name=db_model.card_name, status=db_model.status, total_swaps=db_model.total_swaps, created_at=db_model.created_at.timestamp() if db_model.created_at else None, updated_at=db_model.updated_at.timestamp() if db_model.updated_at else None ) class CardService(DatabaseServiceBase): def __init__(self): super().__init__(service_name="card") self.cards: Dict[str, Card] = {} self.lock = asyncio.Lock() async def _load_card_from_db(self, card_uuid: str, async_session: AsyncSession) -> Optional[Card]: """从数据库加载卡片信息""" try: query = select(DBCard).where(DBCard.card_uuid == card_uuid) result = await async_session.execute(query) db_card = result.scalar_one_or_none() if db_card: card = Card.from_db_model(db_card) async with self.lock: self.cards[card_uuid] = card return card return None except Exception as e: session_logger.error("card", "service", f"从数据库加载卡片失败: {str(e)}") return None async def _save_card_to_db(self, card: Card, async_session: AsyncSession): """保存卡片信息到数据库""" try: query = select(DBCard).where(DBCard.card_uuid == card.card_uuid) result = await async_session.execute(query) existing_card = result.scalar_one_or_none() if existing_card: stmt = update(DBCard).where( DBCard.card_uuid == card.card_uuid ).values( device_id=card.device_id, card_name=card.card_name, status=card.status, total_swaps=card.total_swaps ) else: stmt = insert(DBCard).values( card_uuid=card.card_uuid, device_id=card.device_id, card_name=card.card_name, status=card.status, total_swaps=card.total_swaps ) await async_session.execute(stmt) await async_session.commit() session_logger.info("card", "service", f"卡片已保存到数据库: {card.card_uuid}") except Exception as e: await async_session.rollback() session_logger.error("card", "service", f"保存卡片到数据库失败: {str(e)}") raise async def get_card_by_uuid(self, card_uuid: str, force_refresh: bool = False) -> Optional[Card]: """根据UUID获取卡片信息""" await self._init_database() card = None if not force_refresh: async with self.lock: card = self.cards.get(card_uuid) if not card: db_session = await self.db_manager.get_session() try: card = await self._load_card_from_db(card_uuid, db_session) finally: await db_session.close() return card async def get_card_by_device_id(self, device_id: str) -> list[Card]: """根据设备ID获取卡片列表""" await self._init_database() db_session = await self.db_manager.get_session() try: query = select(DBCard).where(DBCard.device_id == device_id) result = await db_session.execute(query) db_cards = result.scalars().all() cards = [] for db_card in db_cards: card = Card.from_db_model(db_card) async with self.lock: self.cards[card.card_uuid] = card cards.append(card) return cards except Exception as e: session_logger.error(device_id, "card", f"根据设备ID获取卡片失败: {str(e)}") return [] finally: await db_session.close() async def activate_card(self, card_uuid: str, device_id: str, card_name: Optional[str] = None) -> Card: """激活卡片并绑定到设备""" await self._init_database() db_session = await self.db_manager.get_session() try: # 检查卡片是否已存在 existing_card = await self.get_card_by_uuid(card_uuid) if existing_card: # 更新现有卡片 existing_card.device_id = device_id existing_card.card_name = card_name existing_card.status = 1 # 激活状态 await self._save_card_to_db(existing_card, db_session) session_logger.info(device_id, "card", f"卡片已激活并绑定到设备: {card_uuid}") return existing_card else: # 创建新卡片 new_card = Card( card_uuid=card_uuid, device_id=device_id, card_name=card_name, status=1, # 激活状态 total_swaps=0 ) await self._save_card_to_db(new_card, db_session) session_logger.info(device_id, "card", f"新卡片已创建并激活: {card_uuid}") return new_card finally: await db_session.close() async def increment_swap_count(self, card_uuid: str) -> Optional[Card]: """增加卡片交换次数""" await self._init_database() card = await self.get_card_by_uuid(card_uuid) if card: card.total_swaps += 1 db_session = await self.db_manager.get_session() try: await self._save_card_to_db(card, db_session) session_logger.info("card", "service", f"卡片交换次数已增加: {card_uuid}, 总次数: {card.total_swaps}") return card finally: await db_session.close() return None async def check_card_ownership(self, card_uuid: str, device_id: str) -> bool: """检查卡片是否属于指定设备""" card = await self.get_card_by_uuid(card_uuid) if card and card.device_id == device_id: return True return False card_service = CardService()