feat: встроить шаблоны в SD_MAIN_MENU_TEXT при нажатии 3
This commit is contained in:
@@ -112,7 +112,63 @@ async def main_menu(msg: Message):
|
|||||||
USER_MENU_SHOWN[user_id] = True
|
USER_MENU_SHOWN[user_id] = True
|
||||||
set_state(user_id, "SD_MODE")
|
set_state(user_id, "SD_MODE")
|
||||||
log_menu_stats(user_id, "Service Desk", "Вход")
|
log_menu_stats(user_id, "Service Desk", "Вход")
|
||||||
# sd_module_handler покажет шаблоны или меню
|
# Загружаем шаблоны и встраиваем их в текст
|
||||||
|
try:
|
||||||
|
import json, asyncio, httpx, urllib3
|
||||||
|
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
||||||
|
# Импортируем SD_URL и SD_TOKEN из config
|
||||||
|
import importlib.util
|
||||||
|
spec = importlib.util.spec_from_file_location("custom_config", "/opt/trueconf_bot/config/config.py")
|
||||||
|
custom_config = importlib.util.module_from_spec(spec)
|
||||||
|
spec.loader.exec_module(custom_config)
|
||||||
|
SD_URL = custom_config.SD_URL
|
||||||
|
SD_TOKEN = custom_config.SD_TOKEN
|
||||||
|
headers = {"authtoken": SD_TOKEN, "Accept": "application/vnd.manageengine.sdp.v3+json"}
|
||||||
|
input_data = {"list_info": {"row_count": 100, "start_index": 1}}
|
||||||
|
params = {"input_data": json.dumps(input_data)}
|
||||||
|
url = f"{SD_URL}/api/v3/request_templates"
|
||||||
|
async with httpx.AsyncClient(verify=False) as client:
|
||||||
|
resp = await client.get(url, headers=headers, params=params, timeout=30.0)
|
||||||
|
if resp.status_code == 200:
|
||||||
|
data = resp.json()
|
||||||
|
all_templates = data.get("request_templates", [])
|
||||||
|
pre_filtered = [
|
||||||
|
t for t in all_templates
|
||||||
|
if t.get("status") == "ACTIVE"
|
||||||
|
and not t.get("inactive", False)
|
||||||
|
and str(t.get("id")) != "2"
|
||||||
|
]
|
||||||
|
async def check_template(t, cl):
|
||||||
|
try:
|
||||||
|
t_resp = await client.get(url + "/" + str(t["id"]), headers=headers, timeout=15.0)
|
||||||
|
if t_resp.status_code == 200:
|
||||||
|
detailed = t_resp.json().get("request_template", {})
|
||||||
|
return t if detailed.get("show_to_requester") is True else None
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
return None
|
||||||
|
tasks = [check_template(t, client) for t in pre_filtered]
|
||||||
|
results = await asyncio.gather(*tasks)
|
||||||
|
templates = [t for t in results if t is not None]
|
||||||
|
# Пагинация по 10
|
||||||
|
per_page = 10
|
||||||
|
total_pages = (len(templates) + per_page - 1) // per_page if templates else 1
|
||||||
|
start = 0
|
||||||
|
end = min(per_page, len(templates))
|
||||||
|
page_items = templates[start:end]
|
||||||
|
template_lines = ""
|
||||||
|
for idx, t in enumerate(page_items):
|
||||||
|
num = idx + 1
|
||||||
|
digit = f"{num}⃣"
|
||||||
|
template_lines += f"{digit} - {t['name']}\n"
|
||||||
|
page_info = f"\n📄 <b>Страница 1 из {total_pages}</b>"
|
||||||
|
template_text = f"\n\n📋 <b>Выберите шаблон:</b>\n{template_lines}{page_info}"
|
||||||
|
full_text = SD_MAIN_MENU_TEXT + template_text
|
||||||
|
await msg.answer(full_text, parse_mode="html")
|
||||||
|
else:
|
||||||
|
await msg.answer(SD_MAIN_MENU_TEXT, parse_mode="html")
|
||||||
|
except Exception as e:
|
||||||
|
await msg.answer(SD_MAIN_MENU_TEXT, parse_mode="html")
|
||||||
return
|
return
|
||||||
elif action == "PHOTO":
|
elif action == "PHOTO":
|
||||||
USER_MENU_SHOWN[user_id] = True
|
USER_MENU_SHOWN[user_id] = True
|
||||||
|
|||||||
@@ -45,12 +45,6 @@ from utils.texts import (
|
|||||||
sd_file_attached,
|
sd_file_attached,
|
||||||
sd_file_upload_error,
|
sd_file_upload_error,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Цифры для пагинации (1-0, 0 = 10)
|
|
||||||
DIGIT_MAP = {
|
|
||||||
"1": "1⃣", "2": "2⃣", "3": "3⃣", "4": "4⃣", "5": "5⃣",
|
|
||||||
"6": "6⃣", "7": "7⃣", "8": "8⃣", "9": "9⃣", "0": "0⃣"
|
|
||||||
}
|
|
||||||
from utils.texts import UNKNOWN_MAIN_CMD_TEXT
|
from utils.texts import UNKNOWN_MAIN_CMD_TEXT
|
||||||
# 🔌 Импортируем централизованную функцию сбора статистики из main
|
# 🔌 Импортируем централизованную функцию сбора статистики из main
|
||||||
from utils.stats_logger import log_menu_stats
|
from utils.stats_logger import log_menu_stats
|
||||||
@@ -342,37 +336,6 @@ async def sd_module_handler(msg: Message):
|
|||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
# Инициализация шаблонов: загружаем если их ещё нет
|
|
||||||
if not sd_sessions.get(user_id, {}).get("templates"):
|
|
||||||
if user_id not in sd_sessions:
|
|
||||||
sd_sessions[user_id] = {"step": "need_text", "files_queue": [], "post_create_queue": [], "templates": [], "template_names": {}, "template_menu_text": "", "template_page": 0}
|
|
||||||
templates = await get_sd_templates()
|
|
||||||
if templates:
|
|
||||||
sd_sessions[user_id]["templates"] = templates
|
|
||||||
sd_sessions[user_id]["template_names"] = {str(i+1): str(t["id"]) for i, t in enumerate(templates)}
|
|
||||||
per_page = 10
|
|
||||||
page = 0
|
|
||||||
total_pages = (len(templates) + per_page - 1) // per_page if templates else 1
|
|
||||||
start = page * per_page
|
|
||||||
end = start + per_page
|
|
||||||
page_items = templates[start:end]
|
|
||||||
template_menu_text = ""
|
|
||||||
for idx, t in enumerate(page_items):
|
|
||||||
num = idx + 1
|
|
||||||
digit = DIGIT_MAP[str(num)] if num <= 9 else "0⃣" if num == 10 else str(num)
|
|
||||||
template_menu_text += f"{digit} - {t['name']}\n"
|
|
||||||
sd_sessions[user_id]["template_menu_text"] = template_menu_text.strip()
|
|
||||||
sd_sessions[user_id]["template_page"] = page
|
|
||||||
sd_sessions[user_id]["template_per_page"] = per_page
|
|
||||||
sd_sessions[user_id]["template_total_pages"] = total_pages
|
|
||||||
sd_workflow_logger.info(f"[Template] Loaded {len(templates)} templates, page {page+1}/{total_pages}")
|
|
||||||
page_info = f"\n📄 <b>Страница {page + 1} из {total_pages}</b>"
|
|
||||||
await msg.answer(
|
|
||||||
f"Выберите нужный шаблон:\n\n"
|
|
||||||
f"{template_menu_text}{page_info}",
|
|
||||||
parse_mode="html"
|
|
||||||
)
|
|
||||||
return
|
|
||||||
msg_text = _extract_text_from_content(msg.content)
|
msg_text = _extract_text_from_content(msg.content)
|
||||||
is_attachment = hasattr(msg.type, "name") and msg.type.name == "ATTACHMENT"
|
is_attachment = hasattr(msg.type, "name") and msg.type.name == "ATTACHMENT"
|
||||||
inline_attachments = _extract_attachments_from_content(msg.content, is_attachment)
|
inline_attachments = _extract_attachments_from_content(msg.content, is_attachment)
|
||||||
@@ -401,82 +364,6 @@ async def sd_module_handler(msg: Message):
|
|||||||
sd_sessions[user_id] = {"step": "need_text", "files_queue": [], "post_create_queue": [], "templates": [], "template_names": {}}
|
sd_sessions[user_id] = {"step": "need_text", "files_queue": [], "post_create_queue": [], "templates": [], "template_names": {}}
|
||||||
session = sd_sessions[user_id]
|
session = sd_sessions[user_id]
|
||||||
|
|
||||||
# --- ШАГ 0: ВЫБОР ШАБЛОНА ---
|
|
||||||
if session["step"] == "choose_template":
|
|
||||||
if cmd in ["skip", "пропустить", "без шаблона"]:
|
|
||||||
sd_workflow_logger.info("[Template] User skipped template selection")
|
|
||||||
session["step"] = "need_text"
|
|
||||||
await msg.answer(SD_MAIN_MENU_TEXT, parse_mode="html")
|
|
||||||
return
|
|
||||||
# Пагинация: 7 = пред, 8 = след, 9 = назад, 0 = в меню
|
|
||||||
if cmd in ["7", "пред", "prev"]:
|
|
||||||
page = session.get("template_page", 0)
|
|
||||||
if page > 0:
|
|
||||||
page -= 1
|
|
||||||
per_page = session.get("template_per_page", 10)
|
|
||||||
total_pages = session.get("template_total_pages", 1)
|
|
||||||
templates = session.get("templates", [])
|
|
||||||
start = page * per_page
|
|
||||||
end = start + per_page
|
|
||||||
page_items = templates[start:end]
|
|
||||||
template_menu_text = ""
|
|
||||||
for idx, t in enumerate(page_items):
|
|
||||||
num = idx + 1
|
|
||||||
digit = DIGIT_MAP[str(num)] if num <= 9 else "0⃣" if num == 10 else str(num)
|
|
||||||
template_menu_text += f"{digit} - {t['name']}\n"
|
|
||||||
session["template_menu_text"] = template_menu_text.strip()
|
|
||||||
session["template_page"] = page
|
|
||||||
sd_workflow_logger.info(f"[Template] Page {page+1}/{total_pages}")
|
|
||||||
await msg.answer(
|
|
||||||
f"Выберите шаблон:\n\n"
|
|
||||||
f"{template_menu_text}\n📄 <b>Страница {page + 1} из {total_pages}</b>",
|
|
||||||
parse_mode="html"
|
|
||||||
)
|
|
||||||
return
|
|
||||||
if cmd in ["8", "след", "next"]:
|
|
||||||
page = session.get("template_page", 0)
|
|
||||||
total_pages = session.get("template_total_pages", 1)
|
|
||||||
if page < total_pages - 1:
|
|
||||||
page += 1
|
|
||||||
per_page = session.get("template_per_page", 10)
|
|
||||||
templates = session.get("templates", [])
|
|
||||||
start = page * per_page
|
|
||||||
end = start + per_page
|
|
||||||
page_items = templates[start:end]
|
|
||||||
template_menu_text = ""
|
|
||||||
for idx, t in enumerate(page_items):
|
|
||||||
num = idx + 1
|
|
||||||
digit = DIGIT_MAP[str(num)] if num <= 9 else "0⃣" if num == 10 else str(num)
|
|
||||||
template_menu_text += f"{digit} - {t['name']}\n"
|
|
||||||
session["template_menu_text"] = template_menu_text.strip()
|
|
||||||
session["template_page"] = page
|
|
||||||
sd_workflow_logger.info(f"[Template] Page {page+1}/{total_pages}")
|
|
||||||
await msg.answer(
|
|
||||||
f"Выберите шаблон:\n\n"
|
|
||||||
f"{template_menu_text}\n📄 <b>Страница {page + 1} из {total_pages}</b>",
|
|
||||||
parse_mode="html"
|
|
||||||
)
|
|
||||||
return
|
|
||||||
if cmd in ["9", "0"]:
|
|
||||||
session["step"] = "need_text"
|
|
||||||
await msg.answer(SD_MAIN_MENU_TEXT, parse_mode="html")
|
|
||||||
return
|
|
||||||
if cmd in session.get("template_names", {}):
|
|
||||||
template_id = session["template_names"][cmd]
|
|
||||||
template_name = next((t["name"] for t in session.get("templates", []) if str(t["id"]) == str(template_id)), "Неизвестно")
|
|
||||||
sd_workflow_logger.info(f"[Template] User selected: {template_id} ({template_name})")
|
|
||||||
session["template_id"] = template_id
|
|
||||||
session["step"] = "need_text"
|
|
||||||
await msg.answer(SD_MAIN_MENU_TEXT, parse_mode="html")
|
|
||||||
return
|
|
||||||
else:
|
|
||||||
await msg.answer(
|
|
||||||
f"Неверный номер. Выберите из списка:\n\n"
|
|
||||||
f"{session.get('template_menu_text', '')}\n\n"
|
|
||||||
f"7⃣ — Пред. страница\n8⃣ — След. страница\n9⃣ — Назад\n0⃣ — В меню",
|
|
||||||
parse_mode="html"
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
# --- ШАГ 1: ОЖИДАНИЕ ТЕКСТА ---
|
# --- ШАГ 1: ОЖИДАНИЕ ТЕКСТА ---
|
||||||
if session["step"] == "need_text":
|
if session["step"] == "need_text":
|
||||||
|
|||||||
Reference in New Issue
Block a user