AdminLTE3
This commit is contained in:
360
.history/views/admin/telegram_20251026214810.ejs
Normal file
360
.history/views/admin/telegram_20251026214810.ejs
Normal file
@@ -0,0 +1,360 @@
|
||||
<!-- Content Header (Page header) -->
|
||||
<section class="content-header">
|
||||
<div class="container-fluid">
|
||||
<div class="row mb-2">
|
||||
<div class="col-sm-6">
|
||||
<h1><i class="fab fa-telegram mr-2 text-info"></i>Telegram Bot</h1>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<ol class="breadcrumb float-sm-right">
|
||||
<li class="breadcrumb-item"><a href="/admin">Админ</a></li>
|
||||
<li class="breadcrumb-item active">Telegram Bot</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Main content -->
|
||||
<section class="content">
|
||||
<div class="container-fluid">
|
||||
<!-- Bot Status Card -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">Статус бота</h3>
|
||||
<div class="card-tools">
|
||||
<button id="refresh-status" class="btn btn-sm btn-default">
|
||||
<i class="fas fa-sync-alt"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="info-box">
|
||||
<span class="info-box-icon" id="status-icon">
|
||||
<i class="fas fa-question"></i>
|
||||
</span>
|
||||
<div class="info-box-content">
|
||||
<span class="info-box-text">Статус подключения</span>
|
||||
<span class="info-box-number" id="status-text">Проверка...</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="info-box">
|
||||
<span class="info-box-icon bg-info">
|
||||
<i class="fab fa-telegram"></i>
|
||||
</span>
|
||||
<div class="info-box-content">
|
||||
<span class="info-box-text">Имя бота</span>
|
||||
<span class="info-box-number" id="bot-name">Загрузка...</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Configuration Card -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">Конфигурация</h3>
|
||||
</div>
|
||||
<form id="config-form">
|
||||
<div class="card-body">
|
||||
<div class="form-group">
|
||||
<label for="bot-token">Токен бота</label>
|
||||
<div class="input-group">
|
||||
<input type="password" class="form-control" id="bot-token" name="botToken" placeholder="Введите токен бота">
|
||||
<div class="input-group-append">
|
||||
<button type="button" class="btn btn-outline-secondary" onclick="toggleTokenVisibility()">
|
||||
<i class="fas fa-eye" id="token-eye"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<small class="form-text text-muted">
|
||||
Получите токен у <a href="https://t.me/BotFather" target="_blank">@BotFather</a>
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="admin-chat-id">ID чата администратора</label>
|
||||
<input type="text" class="form-control" id="admin-chat-id" name="adminChatId" placeholder="Введите ID чата">
|
||||
<small class="form-text text-muted">
|
||||
Узнайте ваш ID чата у <a href="https://t.me/userinfobot" target="_blank">@userinfobot</a>
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="custom-control custom-switch">
|
||||
<input type="checkbox" class="custom-control-input" id="notifications-enabled" name="notificationsEnabled">
|
||||
<label class="custom-control-label" for="notifications-enabled">Включить уведомления</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Типы уведомлений</label>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="custom-control custom-checkbox">
|
||||
<input type="checkbox" class="custom-control-input" id="notify-contacts" name="notifyContacts">
|
||||
<label class="custom-control-label" for="notify-contacts">Новые контакты</label>
|
||||
</div>
|
||||
<div class="custom-control custom-checkbox">
|
||||
<input type="checkbox" class="custom-control-input" id="notify-orders" name="notifyOrders">
|
||||
<label class="custom-control-label" for="notify-orders">Новые заказы</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="custom-control custom-checkbox">
|
||||
<input type="checkbox" class="custom-control-input" id="notify-errors" name="notifyErrors">
|
||||
<label class="custom-control-label" for="notify-errors">Системные ошибки</label>
|
||||
</div>
|
||||
<div class="custom-control custom-checkbox">
|
||||
<input type="checkbox" class="custom-control-input" id="notify-updates" name="notifyUpdates">
|
||||
<label class="custom-control-label" for="notify-updates">Обновления системы</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<button type="submit" class="btn btn-primary">
|
||||
<i class="fas fa-save mr-1"></i>Сохранить
|
||||
</button>
|
||||
<button type="button" class="btn btn-secondary ml-2" onclick="testConnection()">
|
||||
<i class="fas fa-bolt mr-1"></i>Проверить подключение
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- Test Message Card -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">Тестовое сообщение</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="form-group">
|
||||
<label for="test-message">Сообщение</label>
|
||||
<textarea class="form-control" id="test-message" rows="3" placeholder="Введите тестовое сообщение...">Тестовое сообщение от SmartSolTech Admin Panel</textarea>
|
||||
</div>
|
||||
<button type="button" class="btn btn-info" onclick="sendTestMessage()">
|
||||
<i class="fas fa-paper-plane mr-1"></i>Отправить тест
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Activity Log Card -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">Журнал активности</h3>
|
||||
<div class="card-tools">
|
||||
<button class="btn btn-sm btn-default" onclick="clearLog()">
|
||||
<i class="fas fa-trash"></i> Очистить
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div id="activity-log" style="max-height: 300px; overflow-y: auto;">
|
||||
<!-- Log entries will be added here -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<script>
|
||||
let activityLog = [];
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
loadConfig();
|
||||
checkBotStatus();
|
||||
initializeLog();
|
||||
|
||||
document.getElementById('config-form').addEventListener('submit', saveConfig);
|
||||
});
|
||||
|
||||
function addLog(message, type = 'info') {
|
||||
const timestamp = new Date().toLocaleString('ru-RU');
|
||||
const logEntry = { timestamp, message, type };
|
||||
|
||||
activityLog.unshift(logEntry);
|
||||
if (activityLog.length > 100) {
|
||||
activityLog = activityLog.slice(0, 100);
|
||||
}
|
||||
|
||||
updateLogDisplay();
|
||||
}
|
||||
|
||||
function updateLogDisplay() {
|
||||
const logContainer = document.getElementById('activity-log');
|
||||
const typeColors = {
|
||||
info: 'text-info',
|
||||
success: 'text-success',
|
||||
error: 'text-danger',
|
||||
warning: 'text-warning'
|
||||
};
|
||||
|
||||
logContainer.innerHTML = activityLog.map(entry => `
|
||||
<div class="mb-2">
|
||||
<small class="text-muted">[${entry.timestamp}]</small>
|
||||
<span class="${typeColors[entry.type] || 'text-info'}">${entry.message}</span>
|
||||
</div>
|
||||
`).join('');
|
||||
}
|
||||
|
||||
function initializeLog() {
|
||||
addLog('Telegram Bot панель загружена');
|
||||
}
|
||||
|
||||
function clearLog() {
|
||||
if (confirm('Очистить журнал активности?')) {
|
||||
activityLog = [];
|
||||
updateLogDisplay();
|
||||
addLog('Журнал активности очищен');
|
||||
}
|
||||
}
|
||||
|
||||
async function loadConfig() {
|
||||
try {
|
||||
const response = await fetch('/api/admin/telegram/config');
|
||||
const data = await response.json();
|
||||
|
||||
if (data.success) {
|
||||
const config = data.config;
|
||||
document.getElementById('bot-token').value = config.botToken || '';
|
||||
document.getElementById('admin-chat-id').value = config.adminChatId || '';
|
||||
document.getElementById('notifications-enabled').checked = config.notificationsEnabled || false;
|
||||
document.getElementById('notify-contacts').checked = config.notifyContacts || false;
|
||||
document.getElementById('notify-orders').checked = config.notifyOrders || false;
|
||||
document.getElementById('notify-errors').checked = config.notifyErrors || false;
|
||||
document.getElementById('notify-updates').checked = config.notifyUpdates || false;
|
||||
|
||||
addLog('Конфигурация загружена');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error loading config:', error);
|
||||
addLog('Ошибка загрузки конфигурации: ' + error.message, 'error');
|
||||
}
|
||||
}
|
||||
|
||||
async function saveConfig(event) {
|
||||
event.preventDefault();
|
||||
|
||||
const formData = new FormData(event.target);
|
||||
const config = {
|
||||
botToken: formData.get('botToken'),
|
||||
adminChatId: formData.get('adminChatId'),
|
||||
notificationsEnabled: formData.has('notificationsEnabled'),
|
||||
notifyContacts: formData.has('notifyContacts'),
|
||||
notifyOrders: formData.has('notifyOrders'),
|
||||
notifyErrors: formData.has('notifyErrors'),
|
||||
notifyUpdates: formData.has('notifyUpdates')
|
||||
};
|
||||
|
||||
try {
|
||||
const response = await fetch('/api/admin/telegram/config', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(config)
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (data.success) {
|
||||
addLog('Конфигурация сохранена', 'success');
|
||||
setTimeout(checkBotStatus, 1000);
|
||||
} else {
|
||||
throw new Error(data.message);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error saving config:', error);
|
||||
addLog('Ошибка сохранения конфигурации: ' + error.message, 'error');
|
||||
}
|
||||
}
|
||||
|
||||
async function checkBotStatus() {
|
||||
try {
|
||||
const response = await fetch('/api/admin/telegram/status');
|
||||
const data = await response.json();
|
||||
|
||||
const statusIcon = document.getElementById('status-icon');
|
||||
const statusText = document.getElementById('status-text');
|
||||
const botName = document.getElementById('bot-name');
|
||||
|
||||
if (data.success && data.status.connected) {
|
||||
statusIcon.className = 'info-box-icon bg-success';
|
||||
statusIcon.innerHTML = '<i class="fas fa-check"></i>';
|
||||
statusText.textContent = 'Подключен';
|
||||
botName.textContent = data.status.botInfo.first_name;
|
||||
addLog('Бот подключен: ' + data.status.botInfo.first_name, 'success');
|
||||
} else {
|
||||
statusIcon.className = 'info-box-icon bg-danger';
|
||||
statusIcon.innerHTML = '<i class="fas fa-times"></i>';
|
||||
statusText.textContent = 'Не подключен';
|
||||
botName.textContent = 'Не подключен';
|
||||
addLog('Бот не подключен: ' + (data.message || 'Неизвестная ошибка'), 'error');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error checking bot status:', error);
|
||||
const statusIcon = document.getElementById('status-icon');
|
||||
const statusText = document.getElementById('status-text');
|
||||
const botName = document.getElementById('bot-name');
|
||||
|
||||
statusIcon.className = 'info-box-icon bg-warning';
|
||||
statusIcon.innerHTML = '<i class="fas fa-exclamation"></i>';
|
||||
statusText.textContent = 'Ошибка проверки';
|
||||
botName.textContent = 'Ошибка';
|
||||
addLog('Ошибка проверки статуса: ' + error.message, 'error');
|
||||
}
|
||||
}
|
||||
|
||||
async function testConnection() {
|
||||
addLog('Проверка подключения...');
|
||||
await checkBotStatus();
|
||||
}
|
||||
|
||||
async function sendTestMessage() {
|
||||
const message = document.getElementById('test-message').value;
|
||||
if (!message.trim()) {
|
||||
alert('Введите сообщение для отправки');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
addLog('Отправка тестового сообщения...');
|
||||
|
||||
const response = await fetch('/api/admin/telegram/test', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ message })
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (data.success) {
|
||||
addLog('Тестовое сообщение отправлено', 'success');
|
||||
} else {
|
||||
throw new Error(data.message);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error sending test message:', error);
|
||||
addLog('Ошибка отправки сообщения: ' + error.message, 'error');
|
||||
}
|
||||
}
|
||||
|
||||
function toggleTokenVisibility() {
|
||||
const tokenInput = document.getElementById('bot-token');
|
||||
const tokenEye = document.getElementById('token-eye');
|
||||
|
||||
if (tokenInput.type === 'password') {
|
||||
tokenInput.type = 'text';
|
||||
tokenEye.className = 'fas fa-eye-slash';
|
||||
} else {
|
||||
tokenInput.type = 'password';
|
||||
tokenEye.className = 'fas fa-eye';
|
||||
}
|
||||
}
|
||||
</script>
|
||||
Reference in New Issue
Block a user