main functions fix
This commit is contained in:
332
ACCOUNT_SYSTEM_GUIDE.md
Normal file
332
ACCOUNT_SYSTEM_GUIDE.md
Normal file
@@ -0,0 +1,332 @@
|
||||
# Руководство по работе со счетами в розыгрышах
|
||||
|
||||
## Обзор
|
||||
|
||||
Теперь бот поддерживает два режима участия в розыгрышах:
|
||||
1. **Старый режим**: участие пользователей по Telegram ID
|
||||
2. **Новый режим**: участие по счетам формата `XX-XX-XX-XX-XX-XX-XX-XX`
|
||||
|
||||
## Формат счета
|
||||
|
||||
Счет состоит из **8 пар двухзначных чисел**, разделенных дефисом:
|
||||
```
|
||||
12-34-56-78-90-12-34-56
|
||||
```
|
||||
|
||||
## Возможности для администраторов
|
||||
|
||||
### 1. Автоматическое обнаружение счетов
|
||||
|
||||
Когда администратор вводит в чат сообщение со счетами, бот автоматически обнаруживает их и предлагает действия:
|
||||
|
||||
**Пример:**
|
||||
```
|
||||
12-34-56-78-90-12-34-56
|
||||
45-67-89-01-23-45-67-89
|
||||
```
|
||||
|
||||
Бот выведет:
|
||||
```
|
||||
🔍 Обнаружен ввод счетов
|
||||
|
||||
Найдено: 2
|
||||
|
||||
• 12-34-56-78-90-12-34-56
|
||||
• 45-67-89-01-23-45-67-89
|
||||
|
||||
Выберите действие:
|
||||
[➕ Добавить в розыгрыш]
|
||||
[👑 Сделать победителем]
|
||||
[❌ Отмена]
|
||||
```
|
||||
|
||||
### 2. Добавление счетов в розыгрыш
|
||||
|
||||
**Шаги:**
|
||||
1. Введите счета (один или несколько с новой строки)
|
||||
2. Нажмите "➕ Добавить в розыгрыш"
|
||||
3. Выберите розыгрыш из списка
|
||||
4. Бот добавит все счета и покажет результат
|
||||
|
||||
**Результат:**
|
||||
```
|
||||
Результаты добавления в розыгрыш:
|
||||
Новогодний розыгрыш 2025
|
||||
|
||||
✅ Добавлено: 15
|
||||
⚠️ Пропущено: 3
|
||||
|
||||
Детали:
|
||||
✅ 12-34-56-78-90-12-34-56
|
||||
✅ 45-67-89-01-23-45-67-89
|
||||
...
|
||||
```
|
||||
|
||||
### 3. Установка победителя по счету
|
||||
|
||||
**Шаги:**
|
||||
1. Введите **один** счет
|
||||
2. Нажмите "👑 Сделать победителем"
|
||||
3. Выберите розыгрыш
|
||||
4. Выберите место (1, 2, 3...)
|
||||
5. Бот установит победителя
|
||||
|
||||
**Пример:**
|
||||
```
|
||||
Ввод: 12-34-56-78-90-12-34-56
|
||||
|
||||
Результат:
|
||||
✅ Победитель установлен!
|
||||
|
||||
Розыгрыш: Новогодний розыгрыш 2025
|
||||
Счет: 12-34-56-78-90-12-34-56
|
||||
Место: 1
|
||||
Приз: iPhone 15 Pro
|
||||
```
|
||||
|
||||
### 4. Множественный ввод счетов
|
||||
|
||||
Можно вводить несколько счетов одновременно:
|
||||
|
||||
```
|
||||
12-34-56-78-90-12-34-56
|
||||
45-67-89-01-23-45-67-89
|
||||
11-22-33-44-55-66-77-88
|
||||
99-88-77-66-55-44-33-22
|
||||
```
|
||||
|
||||
Бот обнаружит все валидные счета и предложит массовые операции.
|
||||
|
||||
## Программный доступ
|
||||
|
||||
### Использование сервисов
|
||||
|
||||
```python
|
||||
from account_services import AccountParticipationService
|
||||
|
||||
# Добавить счет в розыгрыш
|
||||
async with async_session_maker() as session:
|
||||
result = await AccountParticipationService.add_account_to_lottery(
|
||||
session,
|
||||
lottery_id=1,
|
||||
account_number="12-34-56-78-90-12-34-56"
|
||||
)
|
||||
print(result["success"]) # True/False
|
||||
print(result["message"]) # Сообщение о результате
|
||||
|
||||
# Массовое добавление
|
||||
accounts = [
|
||||
"12-34-56-78-90-12-34-56",
|
||||
"45-67-89-01-23-45-67-89",
|
||||
"11-22-33-44-55-66-77-88"
|
||||
]
|
||||
|
||||
results = await AccountParticipationService.add_accounts_bulk(
|
||||
session,
|
||||
lottery_id=1,
|
||||
accounts=accounts
|
||||
)
|
||||
|
||||
print(f"Добавлено: {results['added']}")
|
||||
print(f"Пропущено: {results['skipped']}")
|
||||
print(f"Ошибки: {len(results['errors'])}")
|
||||
|
||||
# Получить все счета розыгрыша
|
||||
accounts = await AccountParticipationService.get_lottery_accounts(
|
||||
session,
|
||||
lottery_id=1,
|
||||
limit=100
|
||||
)
|
||||
|
||||
# Установить победителя
|
||||
result = await AccountParticipationService.set_account_as_winner(
|
||||
session,
|
||||
lottery_id=1,
|
||||
account_number="12-34-56-78-90-12-34-56",
|
||||
place=1,
|
||||
prize="iPhone 15 Pro"
|
||||
)
|
||||
```
|
||||
|
||||
### Валидация счетов
|
||||
|
||||
```python
|
||||
from account_utils import (
|
||||
validate_account_number,
|
||||
format_account_number,
|
||||
parse_accounts_from_message
|
||||
)
|
||||
|
||||
# Валидация
|
||||
is_valid = validate_account_number("12-34-56-78-90-12-34-56") # True
|
||||
is_valid = validate_account_number("12-34-56") # False
|
||||
|
||||
# Форматирование (очистка от лишних символов)
|
||||
formatted = format_account_number("12 34 56 78 90 12 34 56")
|
||||
# Результат: "12-34-56-78-90-12-34-56"
|
||||
|
||||
# Парсинг из текста
|
||||
text = """
|
||||
Вот счета для розыгрыша:
|
||||
12-34-56-78-90-12-34-56
|
||||
45-67-89-01-23-45-67-89
|
||||
И ещё один: 11-22-33-44-55-66-77-88
|
||||
"""
|
||||
accounts = parse_accounts_from_message(text)
|
||||
# Результат: ['12-34-56-78-90-12-34-56', '45-67-89-01-23-45-67-89', '11-22-33-44-55-66-77-88']
|
||||
```
|
||||
|
||||
## Генерация тестовых счетов
|
||||
|
||||
```python
|
||||
from account_utils import generate_account_number
|
||||
|
||||
# Генерация одного счета
|
||||
account = generate_account_number()
|
||||
print(account) # Например: "42-17-93-65-28-74-19-36"
|
||||
|
||||
# Генерация множества уникальных счетов
|
||||
import random
|
||||
|
||||
def generate_unique_accounts(count=100):
|
||||
accounts = set()
|
||||
while len(accounts) < count:
|
||||
accounts.add(generate_account_number())
|
||||
return sorted(accounts)
|
||||
|
||||
accounts = generate_unique_accounts(100)
|
||||
```
|
||||
|
||||
## Структура базы данных
|
||||
|
||||
### Таблица `participations`
|
||||
```sql
|
||||
CREATE TABLE participations (
|
||||
id INTEGER PRIMARY KEY,
|
||||
user_id INTEGER, -- Опционально (старый режим)
|
||||
lottery_id INTEGER NOT NULL, -- ID розыгрыша
|
||||
account_number VARCHAR(23), -- Счет (новый режим)
|
||||
created_at DATETIME,
|
||||
FOREIGN KEY(user_id) REFERENCES users (id),
|
||||
FOREIGN KEY(lottery_id) REFERENCES lotteries (id)
|
||||
)
|
||||
```
|
||||
|
||||
### Таблица `winners`
|
||||
```sql
|
||||
CREATE TABLE winners (
|
||||
id INTEGER PRIMARY KEY,
|
||||
lottery_id INTEGER NOT NULL,
|
||||
user_id INTEGER, -- Опционально (старый режим)
|
||||
account_number VARCHAR(23), -- Счет победителя (новый режим)
|
||||
place INTEGER NOT NULL, -- Место (1, 2, 3...)
|
||||
prize VARCHAR(500), -- Описание приза
|
||||
is_manual BOOLEAN, -- Установлен вручную?
|
||||
created_at DATETIME,
|
||||
FOREIGN KEY(lottery_id) REFERENCES lotteries (id),
|
||||
FOREIGN KEY(user_id) REFERENCES users (id)
|
||||
)
|
||||
```
|
||||
|
||||
## Совместимость
|
||||
|
||||
- ✅ Старый режим (участие пользователей) продолжает работать
|
||||
- ✅ Новый режим (участие счетов) работает параллельно
|
||||
- ✅ В одном розыгрыше могут быть как пользователи, так и счета
|
||||
- ✅ Поддержка обоих режимов для победителей
|
||||
|
||||
## Примеры использования
|
||||
|
||||
### Пример 1: Добавление счетов через чат
|
||||
|
||||
**Администратор пишет:**
|
||||
```
|
||||
12-34-56-78-90-12-34-56
|
||||
45-67-89-01-23-45-67-89
|
||||
11-22-33-44-55-66-77-88
|
||||
```
|
||||
|
||||
**Бот отвечает:**
|
||||
```
|
||||
🔍 Обнаружен ввод счетов
|
||||
Найдено: 3
|
||||
...
|
||||
```
|
||||
|
||||
**Администратор выбирает:**
|
||||
1. "Добавить в розыгрыш"
|
||||
2. Выбирает "Новогодний розыгрыш 2025"
|
||||
|
||||
**Бот добавляет все 3 счета**
|
||||
|
||||
### Пример 2: Установка победителя
|
||||
|
||||
**Администратор пишет:**
|
||||
```
|
||||
12-34-56-78-90-12-34-56
|
||||
```
|
||||
|
||||
**Бот отвечает:**
|
||||
```
|
||||
🔍 Обнаружен ввод счета
|
||||
Найдено: 1
|
||||
```
|
||||
|
||||
**Администратор выбирает:**
|
||||
1. "Сделать победителем"
|
||||
2. Выбирает розыгрыш
|
||||
3. Выбирает "Место 1: iPhone 15 Pro"
|
||||
|
||||
**Бот устанавливает победителя**
|
||||
|
||||
## API endpoints (в коде)
|
||||
|
||||
| Сервис | Метод | Описание |
|
||||
|--------|-------|----------|
|
||||
| `AccountParticipationService` | `add_account_to_lottery` | Добавить счет |
|
||||
| | `add_accounts_bulk` | Массовое добавление |
|
||||
| | `remove_account_from_lottery` | Удалить счет |
|
||||
| | `get_lottery_accounts` | Получить все счета |
|
||||
| | `get_accounts_count` | Количество счетов |
|
||||
| | `set_account_as_winner` | Установить победителя |
|
||||
| | `get_lottery_winners_accounts` | Получить победителей |
|
||||
|
||||
## Технические детали
|
||||
|
||||
- **Валидация**: Счет должен содержать ровно 8 пар двухзначных чисел
|
||||
- **Форматирование**: Автоматическая очистка от лишних пробелов и символов
|
||||
- **Индексация**: Поле `account_number` индексировано для быстрого поиска
|
||||
- **Уникальность**: Один счет не может участвовать в одном розыгрыше дважды
|
||||
- **Поддержка NULL**: `user_id` и `account_number` могут быть NULL
|
||||
|
||||
## Миграция данных
|
||||
|
||||
При обновлении проекта:
|
||||
|
||||
1. Создайте резервную копию базы данных
|
||||
2. Запустите миграции или пересоздайте БД:
|
||||
```bash
|
||||
make migrate
|
||||
# или
|
||||
rm -f lottery_bot.db && python -c "import asyncio; from database import init_db; asyncio.run(init_db())"
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Бот не обнаруживает счета
|
||||
|
||||
**Проблема:** Введен неверный формат
|
||||
|
||||
**Решение:** Убедитесь, что счет в формате `XX-XX-XX-XX-XX-XX-XX-XX` (8 пар)
|
||||
|
||||
### Счет не добавляется
|
||||
|
||||
**Проблема:** Счет уже участвует в розыгрыше
|
||||
|
||||
**Решение:** Проверьте список участников розыгрыша
|
||||
|
||||
### Ошибка при установке победителя
|
||||
|
||||
**Проблема:** Счет не участвует в розыгрыше
|
||||
|
||||
**Решение:** Сначала добавьте счет в розыгрыш, затем установите победителем
|
||||
Reference in New Issue
Block a user