import asyncio import logging from typing import Tuple from danding_bot.plugins.danding_points import points_api from .config import Config logger = logging.getLogger("horse_racing.points") MAX_RETRIES = 3 RETRY_DELAY = 0.5 class PointsService: def __init__(self, config: Config): self.config = config async def _call_with_retry(self, func, *args, retries=MAX_RETRIES): """Call API function with retry logic.""" last_exc = None for attempt in range(retries): try: return await func(*args) except Exception as e: last_exc = e logger.warning( f"Points API call failed (attempt {attempt + 1}/{retries}): {e}" ) if attempt < retries - 1: await asyncio.sleep(RETRY_DELAY) logger.error(f"Points API call failed after {retries} attempts: {last_exc}") raise last_exc async def spend_bet_points( self, user_id: str, amount: int, reason: str = "赛马下注" ) -> Tuple[bool, int]: """Deduct points for betting with retry.""" try: return await self._call_with_retry( points_api.spend_points, user_id, amount, "horse_race", reason ) except Exception as e: logger.error(f"spend_bet_points failed for user {user_id}: {e}") return False, 0 async def refund_bet_points( self, user_id: str, amount: int, reason: str = "取消报名退还" ) -> Tuple[bool, int]: """Refund bet points.""" return await points_api.add_points(user_id, amount, "horse_race", reason) async def payout_winnings( self, user_id: str, amount: int, odds: float ) -> Tuple[bool, int]: """Payout bet winnings.""" payout = int(amount * odds) reason = f"下注获胜 ×{odds:.2f}" return await points_api.add_points(user_id, payout, "horse_race", reason) async def reward_participant(self, user_id: str) -> Tuple[bool, int]: """Reward race participant.""" return await points_api.add_points( user_id, self.config.PARTICIPANT_REWARD, "horse_race", "参赛奖励", ) async def reward_champion(self, user_id: str) -> Tuple[bool, int]: """Reward race champion.""" return await points_api.add_points( user_id, self.config.CHAMPION_REWARD, "horse_race", "冠军奖励", ) async def set_points( self, user_id: str, amount: int, reason: str = "测试设置积分" ) -> Tuple[bool, int]: """Set user points (for testing).""" return await points_api.set_points(user_id, amount, "horse_race", reason) async def get_balance(self, user_id: str) -> int: """Get user balance.""" return await points_api.get_balance(user_id)