add admin control center ui and bot commands
This commit is contained in:
@@ -126,6 +126,15 @@ class ApiClient:
|
||||
async def pending_service_centers(self, telegram_id: int) -> list[dict[str, Any]]:
|
||||
return await self.request("GET", "/api/admin/service-centers/pending", telegram_id=telegram_id)
|
||||
|
||||
async def admin_dashboard(self, telegram_id: int) -> dict[str, Any]:
|
||||
return await self.request("GET", "/api/admin/dashboard", telegram_id=telegram_id)
|
||||
|
||||
async def admin_users(self, telegram_id: int) -> dict[str, Any]:
|
||||
return await self.request("GET", "/api/admin/users", telegram_id=telegram_id, params={"limit": 10})
|
||||
|
||||
async def admin_alerts(self, telegram_id: int) -> dict[str, Any]:
|
||||
return await self.request("GET", "/api/admin/notifications", telegram_id=telegram_id, params={"limit": 10})
|
||||
|
||||
async def moderate_service_center(
|
||||
self,
|
||||
telegram_id: int,
|
||||
|
||||
80
bot/main.py
80
bot/main.py
@@ -433,6 +433,7 @@ async def register_sto(message: Message, command: CommandObject) -> None:
|
||||
|
||||
|
||||
@dp.message(Command("admin_sto_pending"))
|
||||
@dp.message(Command("admin_pending_sto"))
|
||||
async def admin_sto_pending(message: Message) -> None:
|
||||
await upsert(message)
|
||||
try:
|
||||
@@ -459,6 +460,77 @@ async def admin_sto_pending(message: Message) -> None:
|
||||
await message.answer(text, reply_markup=admin_card_keyboard(center["id"]))
|
||||
|
||||
|
||||
@dp.message(Command("admin"))
|
||||
async def admin_home(message: Message) -> None:
|
||||
await upsert(message)
|
||||
try:
|
||||
await api.admin_dashboard(message.from_user.id)
|
||||
except httpx.HTTPStatusError as error:
|
||||
await message.answer(f"Админка недоступна: {error.response.text}")
|
||||
return
|
||||
await message.answer(
|
||||
"Admin Control Center: уведомления, пользователи, СТО, заявки, Data Explorer и Audit Log.",
|
||||
reply_markup=webapp_inline_keyboard("Открыть админку", "admin.html"),
|
||||
)
|
||||
|
||||
|
||||
@dp.message(Command("admin_stats"))
|
||||
async def admin_stats(message: Message) -> None:
|
||||
await upsert(message)
|
||||
try:
|
||||
dashboard = await api.admin_dashboard(message.from_user.id)
|
||||
except httpx.HTTPStatusError as error:
|
||||
await message.answer(f"Нет доступа к admin stats: {error.response.text}")
|
||||
return
|
||||
await message.answer(
|
||||
"\n".join(
|
||||
[
|
||||
"Admin stats",
|
||||
f"Users today: {dashboard['users_today']}",
|
||||
f"Users total: {dashboard['users_total']}",
|
||||
f"STO pending: {dashboard['pending_sto_applications']}",
|
||||
f"Appointments today: {dashboard['appointments_today']}",
|
||||
f"Work orders active: {dashboard['active_work_orders']}",
|
||||
f"Errors/security: {dashboard['system_errors']} / {dashboard['security_events']}",
|
||||
]
|
||||
),
|
||||
reply_markup=webapp_inline_keyboard("Admin dashboard", "admin.html"),
|
||||
)
|
||||
|
||||
|
||||
@dp.message(Command("admin_users"))
|
||||
async def admin_users(message: Message) -> None:
|
||||
await upsert(message)
|
||||
try:
|
||||
data = await api.admin_users(message.from_user.id)
|
||||
except httpx.HTTPStatusError as error:
|
||||
await message.answer(f"Нет доступа к admin users: {error.response.text}")
|
||||
return
|
||||
lines = ["Последние пользователи:"]
|
||||
for row in data.get("rows", [])[:10]:
|
||||
lines.append(f"#{row.get('id')} {row.get('username') or '-'} · {row.get('platform_role')} · {row.get('created_at')}")
|
||||
await message.answer("\n".join(lines), reply_markup=webapp_inline_keyboard("Users", "admin.html?section=users"))
|
||||
|
||||
|
||||
@dp.message(Command("admin_sto"))
|
||||
async def admin_sto(message: Message) -> None:
|
||||
await admin_sto_pending(message)
|
||||
|
||||
|
||||
@dp.message(Command("admin_alerts"))
|
||||
async def admin_alerts(message: Message) -> None:
|
||||
await upsert(message)
|
||||
try:
|
||||
data = await api.admin_alerts(message.from_user.id)
|
||||
except httpx.HTTPStatusError as error:
|
||||
await message.answer(f"Нет доступа к admin alerts: {error.response.text}")
|
||||
return
|
||||
lines = ["Admin alerts:"]
|
||||
for row in data.get("rows", [])[:10]:
|
||||
lines.append(f"#{row.get('id')} {row.get('severity')} · {row.get('title')} · {row.get('status')}")
|
||||
await message.answer("\n".join(lines), reply_markup=webapp_inline_keyboard("Alerts", "admin.html?section=notifications"))
|
||||
|
||||
|
||||
async def admin_action(message: Message, command: CommandObject, action: str) -> None:
|
||||
args = (command.args or "").split(maxsplit=1)
|
||||
if not args:
|
||||
@@ -577,7 +649,14 @@ async def admin_callback(callback: CallbackQuery) -> None:
|
||||
@dp.message(F.text == "Помощь")
|
||||
@dp.message(Command("help"))
|
||||
async def help_message(message: Message) -> None:
|
||||
user = await api.upsert_user(message.from_user)
|
||||
centers = await sto_workplace_centers(message.from_user.id)
|
||||
admin_help = (
|
||||
"Админ: /admin — панель, /admin_stats — метрики, /admin_users — последние пользователи, "
|
||||
"/admin_pending_sto — заявки СТО, /admin_alerts — события.\n"
|
||||
if user.get("platform_role") in {"admin", "super_admin", "moderator", "support", "analyst"}
|
||||
else ""
|
||||
)
|
||||
sto_workplace_help = (
|
||||
"• /sto_bookings или /sto_workplace — панель подтвержденного СТО;\n"
|
||||
"• /accept_sto_invite <token> — принять приглашение сотрудника;\n"
|
||||
@@ -601,6 +680,7 @@ async def help_message(message: Message) -> None:
|
||||
"• /sto — каталог проверенных СТО;\n"
|
||||
"• /appointments — мои записи в СТО;\n"
|
||||
f"{sto_workplace_help}"
|
||||
f"{admin_help}"
|
||||
"\n"
|
||||
"Владелец: добавь авто, выбери проверенное СТО, создай запись, согласуй заказ-наряд и смотри завершенные работы в истории автомобиля.\n"
|
||||
f"{sto_business_help}"
|
||||
|
||||
Reference in New Issue
Block a user