220 lines
7.7 KiB
Python
220 lines
7.7 KiB
Python
import asyncio
|
||
import logging
|
||
import mysql.connector
|
||
from slixmpp.componentxmpp import ComponentXMPP
|
||
|
||
JID = "repair.xmpp-life.ru"
|
||
SECRET = "PASSWORD"
|
||
|
||
# 🔐 Разрешённые пользователи
|
||
ALLOWED_JIDS = [
|
||
"user1@xmpp-life.ru",
|
||
"user2@xmpp-life.ru"
|
||
]
|
||
|
||
DB_CONFIG = {
|
||
"host": "192.168.0.130",
|
||
"user": "repair_user",
|
||
"password": "PASSWORD",
|
||
"database": "repair_db"
|
||
}
|
||
|
||
|
||
class RepairComponent(ComponentXMPP):
|
||
|
||
def __init__(self, jid, secret, server, port):
|
||
super().__init__(jid, secret, server, port)
|
||
self.add_event_handler("message", self.message)
|
||
self.add_event_handler("session_start", self.start)
|
||
|
||
async def start(self, event):
|
||
print("✅ Компонент подключен к Openfire")
|
||
|
||
async def message(self, msg):
|
||
if msg['type'] not in ('chat', 'normal'):
|
||
return
|
||
|
||
# 🔐 Проверка отправителя
|
||
sender = str(msg['from']).split('/')[0]
|
||
|
||
if sender not in ALLOWED_JIDS:
|
||
msg.reply("⛔ Доступ запрещён").send()
|
||
return
|
||
|
||
text = msg['body'].strip()
|
||
|
||
conn = None
|
||
cursor = None
|
||
|
||
try:
|
||
conn = mysql.connector.connect(**DB_CONFIG)
|
||
cursor = conn.cursor(dictionary=True)
|
||
|
||
# =====================================
|
||
# INFO
|
||
# =====================================
|
||
if text.lower() == "/info":
|
||
response = (
|
||
"📌 Формат добавления заказа:\n\n"
|
||
"Номер / Модель / Статус / Описание неисправности / "
|
||
"ФИО клиента / Телефон / Стоимость\n\n"
|
||
"Пример:\n"
|
||
"279 / Телевизор Haier 24 / Диагностика / "
|
||
"Не включается / Иванов Иван / 89131234567 / 4500\n\n"
|
||
"Команды:\n"
|
||
"/get Номер — показать заказ\n"
|
||
"/del Номер — удалить заказ\n"
|
||
"/list — последние 10 заказов"
|
||
)
|
||
msg.reply(response).send()
|
||
return
|
||
|
||
# =====================================
|
||
# УДАЛЕНИЕ
|
||
# =====================================
|
||
if text.startswith("/del"):
|
||
parts = text.split()
|
||
if len(parts) != 2:
|
||
msg.reply("❌ Используй: /del Номер").send()
|
||
return
|
||
|
||
order_number = parts[1]
|
||
|
||
cursor.execute("DELETE FROM repair_orders WHERE order_number=%s", (order_number,))
|
||
conn.commit()
|
||
|
||
if cursor.rowcount > 0:
|
||
msg.reply("🗑 Заказ удалён").send()
|
||
else:
|
||
msg.reply("❌ Заказ не найден").send()
|
||
return
|
||
|
||
# =====================================
|
||
# ПОЛУЧИТЬ ЗАКАЗ
|
||
# =====================================
|
||
if text.startswith("/get"):
|
||
parts = text.split()
|
||
if len(parts) != 2:
|
||
msg.reply("❌ Используй: /get Номер").send()
|
||
return
|
||
|
||
order_number = parts[1]
|
||
|
||
cursor.execute("SELECT * FROM repair_orders WHERE order_number=%s", (order_number,))
|
||
result = cursor.fetchone()
|
||
|
||
if result:
|
||
response = (
|
||
f"📦 Заказ: {result['order_number']}\n"
|
||
f"🔧 Модель: {result['model']}\n"
|
||
f"📌 Статус: {result['status']}\n"
|
||
f"📃 Описание неисправности: {result.get('fault_description', '')}\n"
|
||
f"👤 Клиент: {result.get('client_name', '')}\n"
|
||
f"📞 Телефон: {result.get('client_phone', '')}\n"
|
||
f"💰 Стоимость: {result.get('repair_price', '')}"
|
||
)
|
||
else:
|
||
response = "❌ Заказ не найден"
|
||
|
||
msg.reply(response).send()
|
||
return
|
||
|
||
# =====================================
|
||
# СПИСОК
|
||
# =====================================
|
||
if text == "/list":
|
||
cursor.execute(
|
||
"SELECT order_number, status FROM repair_orders "
|
||
"ORDER BY order_number DESC LIMIT 10"
|
||
)
|
||
results = cursor.fetchall()
|
||
|
||
if not results:
|
||
msg.reply("База пустая").send()
|
||
return
|
||
|
||
response = "📋 Последние заказы:\n\n"
|
||
for row in results:
|
||
response += f"{row['order_number']} — {row['status']}\n"
|
||
|
||
msg.reply(response).send()
|
||
return
|
||
|
||
# =====================================
|
||
# ДОБАВЛЕНИЕ / ОБНОВЛЕНИЕ
|
||
# =====================================
|
||
|
||
parts = [p.strip() for p in text.split("/")]
|
||
|
||
if len(parts) != 7:
|
||
msg.reply(
|
||
"❌ Формат:\n"
|
||
"Номер / Модель / Статус / Описание неисправности / "
|
||
"ФИО / Телефон / Стоимость\n\n"
|
||
"Напиши /info для инструкции"
|
||
).send()
|
||
return
|
||
|
||
order_number, model, status, fault_description, client_name, client_phone, repair_price = parts
|
||
|
||
cursor.execute("""
|
||
INSERT INTO repair_orders
|
||
(order_number, model, status, fault_description, client_name, client_phone, repair_price)
|
||
VALUES (%s, %s, %s, %s, %s, %s, %s)
|
||
ON DUPLICATE KEY UPDATE
|
||
model = VALUES(model),
|
||
status = VALUES(status),
|
||
fault_description = VALUES(fault_description),
|
||
client_name = VALUES(client_name),
|
||
client_phone = VALUES(client_phone),
|
||
repair_price = VALUES(repair_price)
|
||
""", (
|
||
order_number,
|
||
model,
|
||
status,
|
||
fault_description,
|
||
client_name,
|
||
client_phone,
|
||
repair_price
|
||
))
|
||
|
||
conn.commit()
|
||
|
||
msg.reply(
|
||
f"✅ Заказ {order_number} сохранён / обновлён\n\n"
|
||
f"📦 Заказ: {order_number}\n"
|
||
f"🔧 Модель: {model}\n"
|
||
f"📌 Статус: {status}\n"
|
||
f"📃 Описание неисправности: {fault_description}\n"
|
||
f"👤 Клиент: {client_name}\n"
|
||
f"📞 Телефон: {client_phone}\n"
|
||
f"💰 Стоимость: {repair_price}"
|
||
).send()
|
||
|
||
except Exception as e:
|
||
msg.reply(f"❌ Ошибка: {str(e)}").send()
|
||
|
||
finally:
|
||
if cursor:
|
||
cursor.close()
|
||
if conn:
|
||
conn.close()
|
||
|
||
|
||
async def main():
|
||
logging.basicConfig(level=logging.INFO)
|
||
|
||
xmpp = RepairComponent(
|
||
JID,
|
||
SECRET,
|
||
"127.0.0.1",
|
||
5275
|
||
)
|
||
|
||
print("🔄 Подключение к Openfire...")
|
||
await xmpp.connect()
|
||
await xmpp.disconnected
|
||
|
||
|
||
if __name__ == '__main__':
|
||
asyncio.run(main())
|