"""抽卡签到积分编排。""" from __future__ import annotations from typing import Any, Protocol class GachaSignInRecorder(Protocol): async def record_sign_in(self, user_id: str, points_awarded: int) -> bool: """记录抽卡签到,首次签到返回 True。""" class PointsAwarder(Protocol): async def add_points(self, user_id: str, amount: int, source: str, reason: str) -> tuple[bool, int]: """发放积分,返回是否成功与新余额。""" async def award_daily_sign_in_points( *, data_manager: GachaSignInRecorder, points_api: PointsAwarder, user_id: str, points: int, source: str, reason: str, ) -> tuple[bool, int, str]: """先记录签到再发放积分,避免重复签到时重复发积分。 `/bot/gacha/sign-in` 负责判断当天是否已经签到;只有它确认首次签到后, nonebot 才调用 `/bot/points/add` 发积分。 """ signed = await data_manager.record_sign_in(user_id, points) if not signed: return False, 0, "signed_already_or_failed" success, new_balance = await points_api.add_points(user_id, points, source, reason) if not success: return False, new_balance, "points_failed" return True, new_balance, "awarded"