47c7f17c90
— 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__
85 lines
4.3 KiB
HTML
85 lines
4.3 KiB
HTML
{% extends "admin/base.html" %}
|
|
{% block title %}Дашборд — Админ-панель{% endblock %}
|
|
{% block nav_dashboard %}active{% endblock %}
|
|
{% block page_title %}📊 Дашборд{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="a-card" style="margin-bottom:1rem;padding:0.75rem">
|
|
<div style="display:flex;justify-content:space-between;align-items:center">
|
|
<strong>🎭 Промо-фаза:</strong>
|
|
<span id="promoPhaseInfo">Загрузка...</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="a-stats">
|
|
<div class="a-stat">
|
|
<div class="as-label">Пользователей</div>
|
|
<div class="as-value">{{ total_users }}</div>
|
|
<div class="as-bar" style="width:60%;background:#f59e0b"></div>
|
|
</div>
|
|
<div class="a-stat">
|
|
<div class="as-label">Открыто кейсов</div>
|
|
<div class="as-value">{{ total_openings }}</div>
|
|
<div class="as-bar" style="width:45%;background:#60a5fa"></div>
|
|
</div>
|
|
<div class="a-stat">
|
|
<div class="as-label">Проведено контрактов</div>
|
|
<div class="as-value">{{ total_contracts }}</div>
|
|
<div class="as-bar" style="width:30%;background:#a78bfa"></div>
|
|
</div>
|
|
<div class="a-stat">
|
|
<div class="as-label">Предметов в БД</div>
|
|
<div class="as-value">{{ total_items }}</div>
|
|
<div class="as-bar" style="width:75%;background:#f472b6"></div>
|
|
</div>
|
|
<div class="a-stat">
|
|
<div class="as-label">Общий баланс</div>
|
|
<div class="as-value">{{ total_balance|money }} ₽</div>
|
|
<div class="as-bar" style="width:40%;background:#34d399"></div>
|
|
</div>
|
|
<div class="a-stat">
|
|
<div class="as-label">Средний РПУ</div>
|
|
<div class="as-value">{{ avg_rpu }}%</div>
|
|
<div class="as-bar" style="width:{{ avg_rpu }}%;background:#fbbf24"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="a-row a-mb">
|
|
<div class="a-card" style="flex:1">
|
|
<div class="a-card-header">🎲 RPU Overview</div>
|
|
{% if rpu_count > 0 %}
|
|
<div class="a-row a-gap-sm a-mb" style="text-align:center;justify-content:space-around">
|
|
<div><div class="as-value" style="font-size:1.2rem">{{ rpu_count }}</div><div class="as-label" style="font-size:0.7rem">Всего записей</div></div>
|
|
<div><div class="as-value" style="font-size:1.2rem">{{ "%.1f"|format(avg_rpu) }}%</div><div class="as-label" style="font-size:0.7rem">Средний уровень</div></div>
|
|
<div><div class="as-value" style="font-size:1.2rem" style="color:#22c55e">{{ lucky_count }}</div><div class="as-label" style="font-size:0.7rem">🍀 Везучих</div></div>
|
|
<div><div class="as-value" style="font-size:1.2rem" style="color:#f59e0b">{{ normal_count }}</div><div class="as-label" style="font-size:0.7rem">📊 Обычных</div></div>
|
|
<div><div class="as-value" style="font-size:1.2rem" style="color:#ef4444">{{ unlucky_count }}</div><div class="as-label" style="font-size:0.7rem">🌧️ Невезучих</div></div>
|
|
<div><div class="as-value" style="font-size:1.2rem">{{ total_spent|money }} ₽</div><div class="as-label" style="font-size:0.7rem">Потрачено всего</div></div>
|
|
</div>
|
|
{% else %}
|
|
<div class="a-empty"><div class="a-empty-icon">📭</div>Нет данных RPU</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block scripts %}
|
|
<script>
|
|
async function loadPromoPhase() {
|
|
try {
|
|
const r = await fetch('/admin/api/promo-phase');
|
|
const d = await r.json();
|
|
const el = document.getElementById('promoPhaseInfo');
|
|
if (d.current_phase === 'LUCKY') {
|
|
el.innerHTML = '<span style="color:#22c55e">🍀 LUCKY</span> (осталось ' + Math.floor(d.remaining_seconds / 60) + ' мин)';
|
|
} else if (d.current_phase === 'UNLUCKY') {
|
|
el.innerHTML = '<span style="color:#ef4444">💀 UNLUCKY</span> (осталось ' + Math.floor(d.remaining_seconds / 60) + ' мин)';
|
|
} else {
|
|
el.innerHTML = '<span style="color:#a3a3a3">⚪ NEUTRAL</span> (осталось ' + Math.floor(d.remaining_seconds / 60) + ' мин)';
|
|
}
|
|
} catch(e) {}
|
|
}
|
|
document.addEventListener('DOMContentLoaded', loadPromoPhase);
|
|
</script>
|
|
{% endblock %}
|