import telebot from telebot import types from flask import Flask, request, jsonify, render_template_string import threading import json from datetime import datetime import os import logging # Настройка логирования logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) # Инициализация бота и Flask BOT_TOKEN = '7734802681:AAGKHGG8O9uNk64JWTHH5yqXzvSxCcoLUdA' bot = telebot.TeleBot(BOT_TOKEN) app = Flask(__name__) # Путь для хранения данных (товары и заказы) DATA_FILE = 'data.json' # Загрузка или создание данных def load_data(): try: if os.path.exists(DATA_FILE): with open(DATA_FILE, 'r', encoding='utf-8') as f: return json.load(f) return {'products': [], 'orders': []} except Exception as e: logger.error(f"Ошибка при загрузке данных: {e}") return {'products': [], 'orders': []} def save_data(data): try: with open(DATA_FILE, 'w', encoding='utf-8') as f: json.dump(data, f, ensure_ascii=False, indent=4) except Exception as e: logger.error(f"Ошибка при сохранении данных: {e}") data = load_data() # Обработчики для бота (пользовательская часть) @bot.message_handler(commands=['start']) def send_welcome(message): markup = types.ReplyKeyboardMarkup(resize_keyboard=True) btn1 = types.KeyboardButton("📋 Меню") btn2 = types.KeyboardButton("🛒 Корзина") btn3 = types.KeyboardButton("📦 Заказы") markup.add(btn1, btn2, btn3) bot.reply_to(message, "Привет! Я твой бот-магазин. Выбери действие:", reply_markup=markup) @bot.message_handler(content_types=['text']) def func(message): if message.text == "📋 Меню": show_products(message) elif message.text == "🛒 Корзина": show_cart(message) elif message.text == "📦 Заказы": show_orders(message) def show_products(message): if not data['products']: bot.reply_to(message, "Нет доступных товаров.") return for product in data['products']: bot.reply_to(message, f"🏷 {product['name']} - {product['price']} руб.\nОписание: {product['description']}\n/id: {product['id']}", reply_markup=get_product_keyboard(product['id'])) def get_product_keyboard(product_id): markup = types.InlineKeyboardMarkup() btn_add = types.InlineKeyboardButton("Добавить в корзину", callback_data=f"add_{product_id}") markup.add(btn_add) return markup @bot.callback_query_handler(func=lambda call: call.data.startswith('add_')) def callback_handler(call): product_id = int(call.data.split('_')[1]) product = next((p for p in data['products'] if p['id'] == product_id), None) if product: user_id = call.from_user.id cart = next((o for o in data['orders'] if o['user_id'] == user_id and not o['completed']), None) if not cart: cart = {'user_id': user_id, 'items': [], 'completed': False, 'date': datetime.now().isoformat()} data['orders'].append(cart) cart['items'].append({'product_id': product_id, 'quantity': 1}) save_data(data) bot.answer_callback_query(call.id, "Товар добавлен в корзину!") else: bot.answer_callback_query(call.id, "Товар не найден.") def show_cart(message): user_id = message.from_user.id cart = next((o for o in data['orders'] if o['user_id'] == user_id and not o['completed']), None) if not cart or not cart['items']: bot.reply_to(message, "Ваша корзина пуста.") return total = 0 response = "Ваша корзина:\n" for item in cart['items']: product = next(p for p in data['products'] if p['id'] == item['product_id']) response += f"🏷 {product['name']} - {product['price']} руб. x {item['quantity']}\n" total += product['price'] * item['quantity'] response += f"\nИтого: {total} руб." markup = types.InlineKeyboardMarkup() btn_complete = types.InlineKeyboardButton("Оформить заказ", callback_data=f"complete_{user_id}") markup.add(btn_complete) bot.reply_to(message, response, reply_markup=markup) @bot.callback_query_handler(func=lambda call: call.data.startswith('complete_')) def complete_order(call): user_id = int(call.data.split('_')[1]) cart = next((o for o in data['orders'] if o['user_id'] == user_id and not o['completed']), None) if cart: cart['completed'] = True save_data(data) bot.answer_callback_query(call.id, "Заказ успешно оформлен!") bot.send_message(user_id, "Спасибо за заказ! Мы скоро свяжемся с вами.") else: bot.answer_callback_query(call.id, "Корзина пуста или заказ уже оформлен.") def show_orders(message): user_id = message.from_user.id user_orders = [o for o in data['orders'] if o['user_id'] == user_id and o['completed']] if not user_orders: bot.reply_to(message, "У вас нет оформленных заказов.") return for order in user_orders: response = "Ваш заказ:\n" total = 0 for item in order['items']: product = next(p for p in data['products'] if p['id'] == item['product_id']) response += f"🏷 {product['name']} - {product['price']} руб. x {item['quantity']}\n" total += product['price'] * item['quantity'] response += f"\nИтого: {total} руб.\nДата: {order['date']}" bot.reply_to(message, response) # Админ-панель (Flask) с HTML, CSS и JavaScript в строке admin_html = """ Админ-панель

Управление товарами




Существующие товары

{% if products %} {% for product in products %}
{{ product.name }} - {{ product.price }} руб.
{{ product.description }}
{% endfor %} {% else %}

Нет товаров.

{% endif %}

Заказы

{% if orders %} {% for order in orders %}
Пользователь: {{ order.user_id }}
Дата: {{ order.date }}
Товары: {% for item in order.items %} {{ item.quantity }} x {{ [p.name for p in products if p.id == item.product_id][0] }}
{% endfor %}
{% endfor %} {% else %}

Нет заказов.

{% endif %}
""" @app.route('/') def admin_panel(): try: return render_template_string(admin_html, products=data['products'], orders=data['orders']) except Exception as e: logger.error(f"Ошибка в шаблоне: {e}") return "Ошибка сервера. Проверь логи.", 500 @app.route('/add_product', methods=['POST']) def add_product(): try: if request.method == 'POST': name = request.form['name'] price = float(request.form['price']) description = request.form['description'] product_id = max((p['id'] for p in data['products']), default=0) + 1 data['products'].append({'id': product_id, 'name': name, 'price': price, 'description': description}) save_data(data) return jsonify({'status': 'success'}) except Exception as e: logger.error(f"Ошибка при добавлении товара: {e}") return jsonify({'status': 'error', 'message': str(e)}), 500 @app.route('/delete_product/', methods=['POST']) def delete_product(product_id): try: data['products'] = [p for p in data['products'] if p['id'] != product_id] save_data(data) return jsonify({'status': 'success'}) except Exception as e: logger.error(f"Ошибка при удалении товара: {e}") return jsonify({'status': 'error', 'message': str(e)}), 500 # Запуск бота и Flask в разных потоках def run_bot(): try: bot.polling(none_stop=True) except Exception as e: logger.error(f"Ошибка в боте: {e}") def run_flask(): try: app.run(host='0.0.0.0', port=7860) except Exception as e: logger.error(f"Ошибка в Flask: {e}") if __name__ == '__main__': bot_thread = threading.Thread(target=run_bot) flask_thread = threading.Thread(target=run_flask) bot_thread.start() flask_thread.start() bot_thread.join() flask_thread.join()