RPU v2, promo/bank система, админка, оптимизации
— RPU v2: бюджет удачи, потолок (ceiling), комбек после проигрышей, hot/cold анализ, интеграция с promo-фазами — Bank API: mock-банк для карты (депозит/вывод с балансом 1000₽) — Promo-сервис: автогенерация промокодов каждый час, типы (card_to_site, luck_boost, ceiling_boost, free_case, reset_streak) — Promo-фазы: LUCKY/NEUTRAL/UNLUCKY, переключение каждые 1-6ч — Admin: история транзакций (user_history), управление промокодами, управление promo-фазами, API фильтров/коллекций, RPU info — Database: WAL mode, новые поля RPU v2, TransactionLog, карточный баланс, статистики (streaks, ceiling, budget) — Frontend: /deposit, /promo/activate, /withdraw, /card-balance, /online-count, /rpu-info, lifespan вместо startup event — UI: user_history.html, улучшения профиля, кейсов, навигации — Cases: обновление cases.json (1892 строки новых данных) — Achievements: кэш коллекций, оптимизация is_custom проверок — Sounds: дополнительные звуковые эффекты — Upgrade: интеграция с RPU (множители, streaks) — .gitignore: исключены .db, .bak, __pycache__
This commit is contained in:
+107
@@ -0,0 +1,107 @@
|
||||
"""
|
||||
BankAPI — внешний сервис для управления "картой" пользователя.
|
||||
Сейчас заглушка (mock), архитектура под настоящий REST.
|
||||
"""
|
||||
|
||||
import random
|
||||
from datetime import datetime, timedelta
|
||||
from typing import Optional
|
||||
|
||||
|
||||
class BankAPIClient:
|
||||
"""
|
||||
Клиент для взаимодействия с Bank API.
|
||||
В будущем — HTTP-клиент к внешнему сервису.
|
||||
Сейчас — in-memory заглушка.
|
||||
"""
|
||||
|
||||
def __init__(self, base_url: str = "http://bank-api:8000"):
|
||||
self.base_url = base_url
|
||||
# mock: user_id -> {balance, transactions}
|
||||
self._mock_balances: dict[int, float] = {}
|
||||
self._mock_txns: dict[int, list] = {}
|
||||
self._initial_balance = 1000.0
|
||||
|
||||
def _ensure_user(self, user_id: int):
|
||||
if user_id not in self._mock_balances:
|
||||
self._mock_balances[user_id] = self._initial_balance
|
||||
self._mock_txns[user_id] = []
|
||||
|
||||
async def get_balance(self, user_id: int) -> float:
|
||||
"""Сколько денег на карте пользователя"""
|
||||
self._ensure_user(user_id)
|
||||
return self._mock_balances[user_id]
|
||||
|
||||
async def transfer_to_site(self, user_id: int, amount: float,
|
||||
promo_code: Optional[str] = None) -> dict:
|
||||
"""
|
||||
Перевод с карты на баланс сайта.
|
||||
Возвращает: {success, amount, new_card_balance, promo_effect}
|
||||
"""
|
||||
self._ensure_user(user_id)
|
||||
if self._mock_balances[user_id] < amount:
|
||||
return {"success": False, "error": "Недостаточно средств на карте"}
|
||||
|
||||
self._mock_balances[user_id] -= amount
|
||||
self._mock_txns[user_id].append({
|
||||
"type": "card_to_site",
|
||||
"amount": amount,
|
||||
"promo": promo_code,
|
||||
"timestamp": datetime.utcnow().isoformat()
|
||||
})
|
||||
|
||||
return {
|
||||
"success": True,
|
||||
"amount": amount,
|
||||
"new_card_balance": self._mock_balances[user_id],
|
||||
"promo_effect": None
|
||||
}
|
||||
|
||||
async def withdraw_to_card(self, user_id: int, amount: float) -> dict:
|
||||
"""
|
||||
Вывод с баланса сайта на карту.
|
||||
Возвращает: {success, amount, new_card_balance, fee}
|
||||
"""
|
||||
self._ensure_user(user_id)
|
||||
fee = round(amount * 0.10, 2) # 10% комиссия
|
||||
net = round(amount - fee, 2)
|
||||
|
||||
self._mock_balances[user_id] += net
|
||||
self._mock_txns[user_id].append({
|
||||
"type": "site_to_card",
|
||||
"gross": amount,
|
||||
"fee": fee,
|
||||
"net": net,
|
||||
"timestamp": datetime.utcnow().isoformat()
|
||||
})
|
||||
|
||||
return {
|
||||
"success": True,
|
||||
"amount": amount,
|
||||
"fee": fee,
|
||||
"net": net,
|
||||
"new_card_balance": self._mock_balances[user_id]
|
||||
}
|
||||
|
||||
async def validate_promo(self, user_id: int, promo_code: str) -> dict:
|
||||
"""
|
||||
Проверяет промокод. Возвращает его эффект для перевода card->site.
|
||||
"""
|
||||
# Заглушка — реальная логика будет в PromoCode сервисе
|
||||
return {
|
||||
"valid": True,
|
||||
"promo_type": "card_to_site",
|
||||
"amount": 0,
|
||||
"luck_boost": 0,
|
||||
"ceiling_boost": 0
|
||||
}
|
||||
|
||||
async def get_transaction_history(self, user_id: int,
|
||||
limit: int = 50) -> list:
|
||||
"""История транзакций по карте"""
|
||||
self._ensure_user(user_id)
|
||||
return self._mock_txns[user_id][-limit:]
|
||||
|
||||
|
||||
# Singleton
|
||||
bank_client = BankAPIClient()
|
||||
Reference in New Issue
Block a user