flpolprojects commited on
Commit
dbbc0da
·
verified ·
1 Parent(s): 5104923

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +218 -0
app.py ADDED
@@ -0,0 +1,218 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import telebot
2
+ from telebot import types
3
+ from flask import Flask, request, jsonify, render_template
4
+ import threading
5
+ import json
6
+ from datetime import datetime
7
+ import os
8
+
9
+ # Инициализация бота и Flask
10
+ BOT_TOKEN = '7734802681:AAGKHGG8O9uNk64JWTHH5yqXzvSxCcoLUdA' # Замени на токен твоего бота от @BotFather
11
+ bot = telebot.TeleBot(BOT_TOKEN)
12
+ app = Flask(__name__)
13
+
14
+ # Путь для хранения данных (товары и заказы)
15
+ DATA_FILE = 'data.json'
16
+
17
+ # Загрузка или создание данных
18
+ def load_data():
19
+ if os.path.exists(DATA_FILE):
20
+ with open(DATA_FILE, 'r', encoding='utf-8') as f:
21
+ return json.load(f)
22
+ return {'products': [], 'orders': []}
23
+
24
+ def save_data(data):
25
+ with open(DATA_FILE, 'w', encoding='utf-8') as f:
26
+ json.dump(data, f, ensure_ascii=False, indent=4)
27
+
28
+ data = load_data()
29
+
30
+ # Обработчики для бота (пользовательская часть)
31
+ @bot.message_handler(commands=['start'])
32
+ def send_welcome(message):
33
+ markup = types.ReplyKeyboardMarkup(resize_keyboard=True)
34
+ btn1 = types.KeyboardButton("📋 Меню")
35
+ btn2 = types.KeyboardButton("🛒 Корзина")
36
+ btn3 = types.KeyboardButton("📦 Заказы")
37
+ markup.add(btn1, btn2, btn3)
38
+ bot.reply_to(message, "Привет! Я твой бот-магазин. Выбери действие:", reply_markup=markup)
39
+
40
+ @bot.message_handler(content_types=['text'])
41
+ def func(message):
42
+ if message.text == "📋 Меню":
43
+ show_products(message)
44
+ elif message.text == "🛒 Корзина":
45
+ show_cart(message)
46
+ elif message.text == "📦 Заказы":
47
+ show_orders(message)
48
+
49
+ def show_products(message):
50
+ if not data['products']:
51
+ bot.reply_to(message, "Нет доступных товаров.")
52
+ return
53
+ for product in data['products']:
54
+ bot.reply_to(message, f"🏷 {product['name']} - {product['price']} руб.\nОписание: {product['description']}\n/id: {product['id']}",
55
+ reply_markup=get_product_keyboard(product['id']))
56
+
57
+ def get_product_keyboard(product_id):
58
+ markup = types.InlineKeyboardMarkup()
59
+ btn_add = types.InlineKeyboardButton("Добавить в корзину", callback_data=f"add_{product_id}")
60
+ markup.add(btn_add)
61
+ return markup
62
+
63
+ @bot.callback_query_handler(func=lambda call: call.data.startswith('add_'))
64
+ def callback_handler(call):
65
+ product_id = int(call.data.split('_')[1])
66
+ product = next((p for p in data['products'] if p['id'] == product_id), None)
67
+ if product:
68
+ user_id = call.from_user.id
69
+ cart = next((o for o in data['orders'] if o['user_id'] == user_id and not o['completed']), None)
70
+ if not cart:
71
+ cart = {'user_id': user_id, 'items': [], 'completed': False, 'date': datetime.now().isoformat()}
72
+ data['orders'].append(cart)
73
+ cart['items'].append({'product_id': product_id, 'quantity': 1})
74
+ save_data(data)
75
+ bot.answer_callback_query(call.id, "Товар добавлен в корзину!")
76
+ else:
77
+ bot.answer_callback_query(call.id, "Товар не найден.")
78
+
79
+ def show_cart(message):
80
+ user_id = message.from_user.id
81
+ cart = next((o for o in data['orders'] if o['user_id'] == user_id and not o['completed']), None)
82
+ if not cart or not cart['items']:
83
+ bot.reply_to(message, "Ваша корзина пуста.")
84
+ return
85
+ total = 0
86
+ response = "Ваша корзина:\n"
87
+ for item in cart['items']:
88
+ product = next(p for p in data['products'] if p['id'] == item['product_id'])
89
+ response += f"🏷 {product['name']} - {product['price']} руб. x {item['quantity']}\n"
90
+ total += product['price'] * item['quantity']
91
+ response += f"\nИтого: {total} руб."
92
+ markup = types.InlineKeyboardMarkup()
93
+ btn_complete = types.InlineKeyboardButton("Оформить заказ", callback_data=f"complete_{user_id}")
94
+ markup.add(btn_complete)
95
+ bot.reply_to(message, response, reply_markup=markup)
96
+
97
+ @bot.callback_query_handler(func=lambda call: call.data.startswith('complete_'))
98
+ def complete_order(call):
99
+ user_id = int(call.data.split('_')[1])
100
+ cart = next((o for o in data['orders'] if o['user_id'] == user_id and not o['completed']), None)
101
+ if cart:
102
+ cart['completed'] = True
103
+ save_data(data)
104
+ bot.answer_callback_query(call.id, "Заказ успешно оформлен!")
105
+ bot.send_message(user_id, "Спасибо за заказ! Мы скоро свяжемся с вами.")
106
+ else:
107
+ bot.answer_callback_query(call.id, "Корзина пуста или заказ уже оформлен.")
108
+
109
+ def show_orders(message):
110
+ user_id = message.from_user.id
111
+ user_orders = [o for o in data['orders'] if o['user_id'] == user_id and o['completed']]
112
+ if not user_orders:
113
+ bot.reply_to(message, "У вас нет оформленных заказов.")
114
+ return
115
+ for order in user_orders:
116
+ response = "Ваш заказ:\n"
117
+ total = 0
118
+ for item in order['items']:
119
+ product = next(p for p in data['products'] if p['id'] == item['product_id'])
120
+ response += f"🏷 {product['name']} - {product['price']} руб. x {item['quantity']}\n"
121
+ total += product['price'] * item['quantity']
122
+ response += f"\nИтого: {total} руб.\nДата: {order['date']}"
123
+ bot.reply_to(message, response)
124
+
125
+ # Админ-панель (Flask)
126
+ @app.route('/')
127
+ def admin_panel():
128
+ return render_template('admin.html', products=data['products'], orders=data['orders'])
129
+
130
+ @app.route('/add_product', methods=['POST'])
131
+ def add_product():
132
+ if request.method == 'POST':
133
+ name = request.form['name']
134
+ price = float(request.form['price'])
135
+ description = request.form['description']
136
+ product_id = max((p['id'] for p in data['products']), default=0) + 1
137
+ data['products'].append({'id': product_id, 'name': name, 'price': price, 'description': description})
138
+ save_data(data)
139
+ return jsonify({'status': 'success'})
140
+
141
+ @app.route('/delete_product/<int:product_id>', methods=['POST'])
142
+ def delete_product(product_id):
143
+ data['products'] = [p for p in data['products'] if p['id'] != product_id]
144
+ save_data(data)
145
+ return jsonify({'status': 'success'})
146
+
147
+ # HTML для админ-панели (встроенный в код для простоты)
148
+ admin_html = """
149
+ <!DOCTYPE html>
150
+ <html>
151
+ <head>
152
+ <title>Админ-панель</title>
153
+ <style>
154
+ body { font-family: Arial, sans-serif; margin: 20px; }
155
+ .product { border: 1px solid #ccc; padding: 10px; margin: 10px 0; }
156
+ button { margin: 5px; }
157
+ </style>
158
+ </head>
159
+ <body>
160
+ <h1>Управление товарами</h1>
161
+ <form id="addProductForm">
162
+ <input type="text" name="name" placeholder="Название" required><br>
163
+ <input type="number" name="price" placeholder="Цена" step="0.01" required><br>
164
+ <textarea name="description" placeholder="Описание" required></textarea><br>
165
+ <button type="submit">Добавить товар</button>
166
+ </form>
167
+ <h2>Существующие товары</h2>
168
+ {% for product in products %}
169
+ <div class="product">
170
+ {{ product.name }} - {{ product.price }} руб.<br>
171
+ {{ product.description }}<br>
172
+ <button onclick="deleteProduct({{ product.id }})">Удалить</button>
173
+ </div>
174
+ {% endfor %}
175
+ <h2>Заказы</h2>
176
+ {% for order in orders %}
177
+ <div class="product">
178
+ Пользователь: {{ order.user_id }}<br>
179
+ Дата: {{ order.date }}<br>
180
+ Товары: {% for item in order.items %}
181
+ {{ item.quantity }} x {{ [p.name for p in products if p.id == item.product_id][0] }}<br>
182
+ {% endfor %}
183
+ </div>
184
+ {% endfor %}
185
+ <script>
186
+ document.getElementById('addProductForm').onsubmit = async (e) => {
187
+ e.preventDefault();
188
+ const formData = new FormData(e.target);
189
+ const response = await fetch('/add_product', { method: 'POST', body: formData });
190
+ if (response.ok) window.location.reload();
191
+ };
192
+ async function deleteProduct(productId) {
193
+ const response = await fetch(`/delete_product/${productId}`, { method: 'POST' });
194
+ if (response.ok) window.location.reload();
195
+ }
196
+ </script>
197
+ </body>
198
+ </html>
199
+ """
200
+
201
+ # Сохранение HTML в файл (если нужно, можно убрать и использовать как строку)
202
+ with open('templates/admin.html', 'w', encoding='utf-8') as f:
203
+ f.write(admin_html)
204
+
205
+ # Запуск бота и Flask в разных потоках
206
+ def run_bot():
207
+ bot.polling(none_stop=True)
208
+
209
+ def run_flask():
210
+ app.run(host='0.0.0.0', port=7860)
211
+
212
+ if __name__ == '__main__':
213
+ bot_thread = threading.Thread(target=run_bot)
214
+ flask_thread = threading.Thread(target=run_flask)
215
+ bot_thread.start()
216
+ flask_thread.start()
217
+ bot_thread.join()
218
+ flask_thread.join()