2025-03-12 17:52:00 +07:00
using System ;
2025-03-17 14:53:01 +07:00
using System.Collections.Generic ;
2025-03-12 17:52:00 +07:00
using System.IO ;
using System.Threading ;
using System.Threading.Tasks ;
using Microsoft.Extensions.Configuration ;
using Microsoft.Data.Sqlite ;
using Serilog ;
using Telegram.Bot ;
using Telegram.Bot.Types ;
using Telegram.Bot.Types.Enums ;
2025-03-19 13:24:38 +07:00
using Telegram.Bot.Types.ReplyMarkups ;
2025-03-12 17:52:00 +07:00
class Program
{
private static string _botToken = string . Empty ;
private static TelegramBotClient _botClient = null ! ;
2025-03-17 14:53:01 +07:00
private static Dictionary < long , bool > usersWaitingForReport = new Dictionary < long , bool > ( ) ; // Отслеживаем состояние пользователей
2025-03-17 15:33:06 +07:00
private static HashSet < long > admins = new HashSet < long > ( ) ; // Хранение списка администраторов
private static string adminPassword = "admin123" ; // Простой пароль для администратора
2025-03-12 17:52:00 +07:00
static async Task Main ( )
{
// Загружаем конфигурацию из appsettings.json
2025-03-12 22:41:14 +07:00
try
{
Log . Information ( "Загрузка конфигурации из appsettings.json..." ) ;
var config = new ConfigurationBuilder ( )
. SetBasePath ( AppContext . BaseDirectory ) // <-- Используем правильный путь
. AddJsonFile ( "appsettings.json" , optional : false , reloadOnChange : true )
. Build ( ) ;
2025-03-12 17:52:00 +07:00
2025-03-12 22:41:14 +07:00
_botToken = config [ "BotToken" ] ? ? throw new Exception ( "BotToken не найден в конфигурации!" ) ;
2025-03-19 18:26:38 +07:00
Log . Information ( "Конфигурация успешно загружена" ) ;
2025-03-12 22:41:14 +07:00
}
catch ( Exception ex )
{
Log . Error ( $"Ошибка при загрузке конфигурации: {ex.Message}" ) ;
throw ;
}
2025-03-12 17:52:00 +07:00
2025-03-19 20:19:46 +07:00
2025-03-12 17:52:00 +07:00
Log . Logger = new LoggerConfiguration ( )
. WriteTo . Console ( )
. WriteTo . File ( "logs/log.txt" , rollingInterval : RollingInterval . Day )
. CreateLogger ( ) ;
Log . Information ( "Запуск Telegram-бота..." ) ;
2025-03-12 22:41:14 +07:00
try
{
2025-03-19 20:19:46 +07:00
2025-03-12 22:41:14 +07:00
_botClient = new TelegramBotClient ( _botToken ) ;
2025-03-19 20:19:46 +07:00
var me = await _botClient . GetMe ( ) ;
2025-03-12 22:41:14 +07:00
Log . Information ( $"Бот {me.FirstName} запущен! ID: {me.Id}" ) ;
}
catch ( Exception ex )
{
Log . Error ( $"Ошибка при подключении к Telegram API: {ex.Message}" ) ;
2025-03-19 20:19:46 +07:00
2025-03-12 22:41:14 +07:00
throw ;
}
2025-03-12 17:52:00 +07:00
2025-03-17 15:07:41 +07:00
// Создание базы данных и таблицы, если они не существуют
await CreateDatabaseIfNotExists ( ) ;
2025-03-19 20:19:46 +07:00
// Загрузка списка администраторов из базы данных
await LoadAdminsFromDatabase ( ) ;
Log . Information ( $"Загружено {admins.Count} администраторов из базы данных" ) ;
2025-03-12 19:11:38 +07:00
var cts = new CancellationTokenSource ( ) ;
2025-03-12 22:41:14 +07:00
Log . Information ( "Начало получения обновлений..." ) ;
2025-03-12 22:17:34 +07:00
2025-03-12 22:41:14 +07:00
try
{
// Применение StartReceiving для работы с задачами
_botClient . StartReceiving ( HandleUpdateAsync , HandleErrorAsync , cancellationToken : cts . Token ) ;
Log . Information ( "Получение обновлений успешно началось." ) ;
}
catch ( Exception ex )
{
Log . Error ( $"Ошибка при запуске получения обновлений: {ex.Message}" ) ;
throw ;
}
2025-03-12 17:52:00 +07:00
2025-03-12 22:17:34 +07:00
// Создание TaskCompletionSource для удержания процесса бота
var tcs = new TaskCompletionSource ( ) ;
await tcs . Task ; // Это заставит бота работать до тех пор, пока не будет отменен
// Ожидаем отмены через token
cts . Token . WaitHandle . WaitOne ( ) ;
2025-03-12 17:52:00 +07:00
}
2025-03-19 19:03:49 +07:00
2025-03-19 16:30:42 +07:00
private static async Task DeletePreviousMessage ( ITelegramBotClient botClient , long chatId , int messageId )
{
try
{
await botClient . DeleteMessage ( chatId , messageId ) ;
Log . Information ( $"Сообщение {messageId} в чате {chatId} удалено." ) ;
}
catch ( Exception ex )
{
Log . Error ( $"Ошибка при удалении сообщения {messageId} в чате {chatId}: {ex.Message}" ) ;
}
}
2025-03-19 19:03:49 +07:00
2025-03-19 16:30:42 +07:00
2025-03-12 17:52:00 +07:00
private static async Task HandleUpdateAsync ( ITelegramBotClient botClient , Update update , CancellationToken cancellationToken )
{
2025-03-12 22:41:14 +07:00
try
{
2025-03-19 14:14:02 +07:00
// Обработка нажатий на кнопки
if ( update . Type = = UpdateType . CallbackQuery )
{
var callbackQuery = update . CallbackQuery ;
2025-03-19 15:54:05 +07:00
if ( callbackQuery ? . From ! = null )
{
long chatId = callbackQuery . From . Id ;
string? data = callbackQuery . Data ;
if ( callbackQuery ? . Message ? . MessageId ! = null )
{
int messageId = callbackQuery . Message . MessageId ;
2025-03-19 16:30:42 +07:00
await DeletePreviousMessage ( botClient , chatId , messageId ) ; // Удаляем предыдущее сообщение
2025-03-19 15:54:05 +07:00
}
2025-03-19 14:14:02 +07:00
2025-03-19 16:30:42 +07:00
if ( callbackQuery ? . Id ! = null )
{
await botClient . AnswerCallbackQuery ( callbackQuery . Id ) ; // Убираем "часики" у кнопки
}
2025-03-19 14:14:02 +07:00
2025-03-19 15:54:05 +07:00
if ( data = = "report" )
{
2025-03-19 19:03:49 +07:00
usersWaitingForReport [ chatId ] = true ;
2025-03-19 19:20:14 +07:00
userReportSteps [ chatId ] = 1 ;
userReports [ chatId ] = new Report ( ) ;
2025-03-19 19:36:30 +07:00
var priorityKeyboard = new InlineKeyboardMarkup ( new [ ]
{
2025-03-19 22:01:40 +07:00
new [ ]
{
InlineKeyboardButton . WithCallbackData ( "Низкий" , "priority_low" ) ,
InlineKeyboardButton . WithCallbackData ( "Средний" , "priority_medium" ) ,
InlineKeyboardButton . WithCallbackData ( "Высокий" , "priority_high" )
}
} ) ;
2025-03-19 21:59:35 +07:00
await botClient . SendMessage ( chatId , "Пожалуйста, выберите приоритет:" , replyMarkup : priorityKeyboard ) ;
Log . Information ( $"Пользователь {chatId} начал создание заявки" ) ;
2025-03-19 20:57:16 +07:00
}
2025-03-19 22:01:40 +07:00
else if ( data = = "admin_settings" )
{
if ( admins . Contains ( chatId ) )
{
await ShowAdminSettings ( botClient , chatId ) ;
}
else
{
await botClient . SendMessage ( chatId , "⛔ У вас нет прав для доступа к настройкам администраторов!" ) ;
await Task . Delay ( 2000 ) ;
await SendMainMenu ( botClient , chatId ) ;
}
}
2025-03-19 22:47:04 +07:00
else if ( data = = "view_admins" )
{
if ( admins . Contains ( chatId ) )
{
await ShowAdminsList ( botClient , chatId ) ;
}
else
{
await botClient . SendMessage ( chatId , "⛔ У вас нет прав для просмотра администраторов!" ) ;
await Task . Delay ( 2000 ) ;
await SendMainMenu ( botClient , chatId ) ;
}
}
2025-03-19 22:01:40 +07:00
else if ( data ! = null & & data . StartsWith ( "removeadmin_" ) )
{
2025-03-19 22:09:28 +07:00
long adminIdToRemove = long . Parse ( data . Substring ( 11 ) . Replace ( "_" , "" ) ) ;
2025-03-19 22:01:40 +07:00
// Проверяем, что пользователь является администратором
if ( admins . Contains ( chatId ) )
{
// Проверяем, не пытается ли пользователь удалить себя
if ( adminIdToRemove = = chatId )
{
2025-03-19 22:19:48 +07:00
var warningMessage = await botClient . SendMessage (
2025-03-19 22:01:40 +07:00
chatId : chatId ,
text : "⚠️ Вы не можете удалить себя из администраторов!"
) ;
2025-03-19 22:19:48 +07:00
await Task . Delay ( 2000 ) ;
await botClient . DeleteMessage ( chatId , warningMessage . MessageId ) ;
await ShowAdminsList ( botClient , chatId ) ;
2025-03-19 22:01:40 +07:00
}
else
{
await RemoveAdminFromDatabase ( adminIdToRemove ) ;
string username = "администратор" ;
try
{
var user = await botClient . GetChat ( adminIdToRemove ) ;
username = user . Username ? ? user . FirstName ? ? "администратор" ;
}
catch { }
await botClient . SendMessage (
chatId : chatId ,
text : $"✅ Пользователь {username} (ID: {adminIdToRemove}) удален из администраторов."
) ;
await Task . Delay ( 2000 ) ;
await ShowAdminsList ( botClient , chatId ) ;
}
}
else
{
await botClient . SendMessage ( chatId , "⛔ У вас нет прав для удаления администраторов!" ) ;
await Task . Delay ( 2000 ) ;
await SendMainMenu ( botClient , chatId ) ;
}
}
// Также добавим обработку команды /removeadmin в секцию обработки текстовых сообщений:
// В блоке для обработки текстовых сообщений (после if (message.Text.StartsWith("/admin")))
else if ( update . Type = = UpdateType . Message & & update . Message ? . Text ! = null )
{
var message = update . Message ;
Log . Information ( $"Получено сообщение от {message.Chat.Id}: {message.Text}" ) ;
if ( message . Text . StartsWith ( "/admin" ) )
{
string [ ] parts = message . Text . Split ( ' ' ) ;
if ( parts . Length = = 2 & & parts [ 1 ] = = adminPassword )
{
admins . Add ( message . Chat . Id ) ;
// Сохраняем администратора в базу данных
await SaveAdminToDatabase ( message . Chat . Id ) ;
var authMessage = await botClient . SendMessage ( message . Chat . Id , "✅ Вы авторизованы как администратор!" ) ;
Log . Information ( $"Новый администратор: {message.Chat.Id}" ) ;
await Task . Delay ( 2000 ) ;
await botClient . DeleteMessage ( message . Chat . Id , authMessage . MessageId ) ;
await SendMainMenu ( botClient , message . Chat . Id ) ;
}
else
{
var authMessage = await botClient . SendMessage ( message . Chat . Id , "❌ Неверный пароль!" ) ;
await Task . Delay ( 2000 ) ;
await botClient . DeleteMessage ( message . Chat . Id , authMessage . MessageId ) ;
await SendMainMenu ( botClient , message . Chat . Id ) ;
}
return ;
}
2025-03-19 22:48:53 +07:00
}
2025-03-19 22:01:40 +07:00
2025-03-19 22:48:53 +07:00
else if ( data = = "admin_panel" )
{
if ( admins . Contains ( chatId ) )
2025-03-19 20:57:16 +07:00
{
2025-03-19 22:48:53 +07:00
await SendAdminPanel ( botClient , chatId ) ;
2025-03-19 20:57:16 +07:00
}
2025-03-19 22:48:53 +07:00
else
2025-03-19 20:57:16 +07:00
{
2025-03-19 22:48:53 +07:00
var authMessage = await botClient . SendMessage ( chatId , "⛔ Вы не являетесь администратором!" ) ;
Log . Information ( $"Неавторизованный доступ к админ-панели от {chatId}" ) ;
await Task . Delay ( 2000 ) ;
await botClient . DeleteMessage ( chatId , authMessage . MessageId ) ;
await SendMainMenu ( botClient , chatId ) ;
2025-03-19 20:57:16 +07:00
}
2025-03-19 22:48:53 +07:00
}
else if ( data = = "view_reports" )
{
if ( admins . Contains ( chatId ) )
2025-03-19 20:57:16 +07:00
{
2025-03-19 22:44:20 +07:00
await ViewReports ( botClient , chatId ) ;
2025-03-19 20:57:16 +07:00
}
2025-03-19 22:48:53 +07:00
else
2025-03-19 22:44:20 +07:00
{
2025-03-19 22:48:53 +07:00
var authMessage = await botClient . SendMessage ( chatId , "⛔ Вы не являетесь администратором!" ) ;
Log . Information ( $"Неавторизованный доступ к заявкам от {chatId}" ) ;
await Task . Delay ( 2000 ) ;
await botClient . DeleteMessage ( chatId , authMessage . MessageId ) ;
2025-03-19 22:44:20 +07:00
await SendMainMenu ( botClient , chatId ) ;
}
2025-03-19 20:57:16 +07:00
}
2025-03-19 22:48:53 +07:00
else if ( data = = "view_archived_reports" )
2025-03-19 20:37:51 +07:00
{
2025-03-19 22:48:53 +07:00
if ( admins . Contains ( chatId ) )
2025-03-19 22:44:20 +07:00
{
2025-03-19 22:48:53 +07:00
await ViewArchivedReports ( botClient , chatId ) ;
2025-03-19 22:44:20 +07:00
}
else
{
2025-03-19 22:48:53 +07:00
var authMessage = await botClient . SendMessage ( chatId , "⛔ Вы не являетесь администратором!" ) ;
Log . Information ( $"Неавторизованный доступ к архиву заявок от {chatId}" ) ;
2025-03-19 22:44:20 +07:00
await Task . Delay ( 2000 ) ;
2025-03-19 22:48:53 +07:00
await botClient . DeleteMessage ( chatId , authMessage . MessageId ) ;
await SendMainMenu ( botClient , chatId ) ;
2025-03-19 22:44:20 +07:00
}
2025-03-19 20:37:51 +07:00
}
2025-03-19 22:48:53 +07:00
else if ( data ! = null & & data . StartsWith ( "report_" ) )
2025-03-19 20:37:51 +07:00
{
2025-03-19 22:48:53 +07:00
long reportId = long . Parse ( data . Substring ( 7 ) ) ;
if ( callbackQuery ? . Message ? . MessageId ! = null )
2025-03-19 22:44:20 +07:00
{
2025-03-19 22:48:53 +07:00
int messageId = callbackQuery . Message . MessageId ;
await ShowReportDetails ( botClient , chatId , reportId , messageId ) ;
2025-03-19 22:44:20 +07:00
}
2025-03-19 22:48:53 +07:00
}
else if ( data ! = null & & data . StartsWith ( "status_" ) )
{
string [ ] parts = data . Split ( '_' ) ;
long reportId = long . Parse ( parts [ 1 ] ) ;
string newStatus = parts [ 2 ] ;
if ( callbackQuery ? . Message ? . MessageId ! = null )
2025-03-19 22:44:20 +07:00
{
2025-03-19 22:48:53 +07:00
int messageId = callbackQuery . Message . MessageId ;
await UpdateReportStatus ( reportId , newStatus , chatId ) ;
await ShowReportDetails ( botClient , chatId , reportId , messageId ) ;
2025-03-19 22:44:20 +07:00
}
2025-03-19 20:37:51 +07:00
}
2025-03-19 22:48:53 +07:00
else if ( data ! = null & & data . StartsWith ( "delete_" ) )
{
long reportId = long . Parse ( data . Substring ( 7 ) ) ;
await DeleteReport ( botClient , chatId , reportId ) ;
}
else if ( data = = "back_to_list" )
{
await ViewReports ( botClient , chatId ) ;
}
else if ( data = = "back_to_admin_panel" )
{
await SendAdminPanel ( botClient , chatId ) ;
}
else if ( data = = "main_menu" )
{
await SendMainMenu ( botClient , chatId ) ;
}
else if ( data ! = null & & data . StartsWith ( "priority_" ) )
{
string priority = data . Substring ( 9 ) ;
userReports [ chatId ] . Priority = priority ;
userReportSteps [ chatId ] = 2 ;
await botClient . SendMessage ( chatId , "Пожалуйста, укажите кабинет." ) ;
}
}
}
2025-03-19 22:01:40 +07:00
2025-03-19 22:48:53 +07:00
// Обработка текстовых сообщений
if ( update . Type = = UpdateType . Message & & update . Message ? . Text ! = null )
{
var message = update . Message ;
Log . Information ( $"Получено сообщение от {message.Chat.Id}: {message.Text}" ) ;
if ( message . Text . StartsWith ( "/admin" ) )
{
string [ ] parts = message . Text . Split ( ' ' ) ;
if ( parts . Length = = 2 & & parts [ 1 ] = = adminPassword )
{
admins . Add ( message . Chat . Id ) ;
// Сохраняем администратора в базу данных
await SaveAdminToDatabase ( message . Chat . Id ) ;
var authMessage = await botClient . SendMessage ( message . Chat . Id , "✅ Вы авторизованы как администратор!" ) ;
Log . Information ( $"Новый администратор: {message.Chat.Id}" ) ;
await Task . Delay ( 2000 ) ;
await botClient . DeleteMessage ( message . Chat . Id , authMessage . MessageId ) ;
await SendMainMenu ( botClient , message . Chat . Id ) ;
}
else
{
var authMessage = await botClient . SendMessage ( message . Chat . Id , "❌ Неверный пароль!" ) ;
await Task . Delay ( 2000 ) ;
await botClient . DeleteMessage ( message . Chat . Id , authMessage . MessageId ) ;
await SendMainMenu ( botClient , message . Chat . Id ) ;
}
return ;
}
// В блоке для обработки текстовых сообщений
else if ( message . Text = = "/admins" )
{
if ( admins . Contains ( message . Chat . Id ) )
{
await ShowAdminsList ( botClient , message . Chat . Id ) ;
}
else
{
var authMessage = await botClient . SendMessage (
chatId : message . Chat . Id ,
text : "⛔ У вас нет прав для просмотра списка администраторов!"
) ;
await Task . Delay ( 2000 ) ;
await botClient . DeleteMessage ( message . Chat . Id , authMessage . MessageId ) ;
await SendMainMenu ( botClient , message . Chat . Id ) ;
}
}
if ( message . Text = = "/start" )
{
var keyboard = new InlineKeyboardMarkup ( new [ ]
2025-03-19 16:38:09 +07:00
{
2025-03-19 22:01:40 +07:00
new [ ]
{
InlineKeyboardButton . WithCallbackData ( "Подать заявку" , "report" ) ,
InlineKeyboardButton . WithCallbackData ( "Панель администратора" , "admin_panel" )
2025-03-19 16:38:09 +07:00
}
2025-03-19 22:01:40 +07:00
} ) ;
2025-03-19 22:48:53 +07:00
await botClient . SendMessage (
chatId : message . Chat . Id ,
text : "Привет! Я бот для с б о р а заявок на ремонт оборудования." ,
replyMarkup : keyboard
) ;
Log . Information ( $"Ответ на команду /start с кнопками отправлен." ) ;
}
else if ( usersWaitingForReport . TryGetValue ( message . Chat . Id , out bool isWaiting ) & & isWaiting )
{
if ( userReportSteps . TryGetValue ( message . Chat . Id , out int step ) )
2025-03-19 21:59:35 +07:00
{
2025-03-19 22:48:53 +07:00
switch ( step )
2025-03-19 22:44:20 +07:00
{
2025-03-19 22:48:53 +07:00
case 2 :
userReports [ message . Chat . Id ] . Room = message . Text ;
userReportSteps [ message . Chat . Id ] = 3 ;
await botClient . SendMessage ( message . Chat . Id , "Пожалуйста, опишите проблему." ) ;
break ;
case 3 :
userReports [ message . Chat . Id ] . Description = message . Text ;
userReportSteps [ message . Chat . Id ] = 4 ;
await botClient . SendMessage ( message . Chat . Id , "Пожалуйста, укажите ваше ФИО." ) ;
break ;
case 4 :
userReports [ message . Chat . Id ] . ReporterName = message . Text ;
await SaveReportToDatabase ( message . Chat . Id , userReports [ message . Chat . Id ] ) ;
var mainMenuKeyboard = new InlineKeyboardMarkup ( new [ ]
{
2025-03-19 22:01:40 +07:00
new [ ]
{
InlineKeyboardButton . WithCallbackData ( "Главное меню" , "main_menu" )
}
} ) ;
2025-03-19 22:48:53 +07:00
await botClient . SendMessage (
message . Chat . Id ,
"✅ Спасибо за заявку! Мы обработаем её в ближайшее время." ,
replyMarkup : mainMenuKeyboard
) ;
usersWaitingForReport [ message . Chat . Id ] = false ;
userReportSteps . Remove ( message . Chat . Id ) ;
userReports . Remove ( message . Chat . Id ) ;
Log . Information ( $"Заявка пользователя {message.Chat.Id} сохранена в базе данных." ) ;
break ;
2025-03-19 22:01:40 +07:00
}
2025-03-19 21:59:35 +07:00
}
2025-03-19 22:48:53 +07:00
}
else
{
await botClient . SendMessage ( message . Chat . Id , "ℹ ️ Используйте команду /start для начала работы с ботом." ) ;
2025-03-19 22:01:40 +07:00
}
2025-03-12 22:41:14 +07:00
}
2025-03-12 17:52:00 +07:00
}
2025-03-12 22:41:14 +07:00
catch ( Exception ex )
2025-03-12 17:52:00 +07:00
{
2025-03-12 22:41:14 +07:00
Log . Error ( $"Ошибка при обработке обновлений: {ex.Message}" ) ;
Log . Error ( $"StackTrace: {ex.StackTrace}" ) ;
2025-03-12 17:52:00 +07:00
}
}
2025-03-19 17:59:32 +07:00
2025-03-19 19:20:14 +07:00
2025-03-19 16:51:33 +07:00
private static async Task DeleteReport ( ITelegramBotClient botClient , long chatId , long reportId )
{
try
{
using ( var connection = new SqliteConnection ( "Data Source=bot.db" ) )
{
await connection . OpenAsync ( ) ;
var command = connection . CreateCommand ( ) ;
command . CommandText = "DELETE FROM Reports WHERE Id = @id" ;
command . Parameters . AddWithValue ( "@id" , reportId ) ;
await command . ExecuteNonQueryAsync ( ) ;
2025-03-19 16:54:20 +07:00
var deletionMessage = await botClient . SendMessage ( chatId , $"Заявка #{reportId} успешно удалена." ) ;
2025-03-19 16:51:33 +07:00
Log . Information ( $"Заявка #{reportId} удалена пользователем {chatId}." ) ;
2025-03-19 16:54:20 +07:00
// Ждем 2 секунды
await Task . Delay ( 2000 ) ;
// Удаляем сообщение о б удалении
await botClient . DeleteMessage ( chatId , deletionMessage . MessageId ) ;
// Отображаем список заявок
await ViewReports ( botClient , chatId ) ;
2025-03-19 16:51:33 +07:00
}
}
catch ( Exception ex )
{
Log . Error ( $"Ошибка при удалении заявки #{reportId}: {ex.Message}" ) ;
await botClient . SendMessage ( chatId , $"Ошибка при удалении заявки #{reportId}." ) ;
}
}
2025-03-19 19:03:49 +07:00
2025-03-19 15:27:07 +07:00
private static async Task SendMainMenu ( ITelegramBotClient botClient , long chatId )
{
var keyboard = new InlineKeyboardMarkup ( new [ ]
{
2025-03-19 17:59:32 +07:00
new [ ]
{
2025-03-19 22:57:11 +07:00
InlineKeyboardButton . WithCallbackData ( "📝 Подать заявку" , "report" ) ,
InlineKeyboardButton . WithCallbackData ( "🔐 Панель администратора" , "admin_panel" )
2025-03-19 17:59:32 +07:00
}
} ) ;
2025-03-19 15:27:07 +07:00
await botClient . SendMessage (
chatId : chatId ,
text : "Главное меню:" ,
replyMarkup : keyboard
) ;
}
2025-03-19 22:57:11 +07:00
2025-03-19 17:59:32 +07:00
private static async Task SendAdminPanel ( ITelegramBotClient botClient , long chatId )
{
var keyboard = new InlineKeyboardMarkup ( new [ ]
{
2025-03-19 22:57:11 +07:00
new [ ]
{
InlineKeyboardButton . WithCallbackData ( "📋 Менеджер заявок" , "view_reports" ) ,
InlineKeyboardButton . WithCallbackData ( "🗃️ Архив заявок" , "view_archived_reports" )
} ,
new [ ]
{
InlineKeyboardButton . WithCallbackData ( "⚙️ Управление администраторами" , "admin_settings" )
} ,
new [ ]
{
InlineKeyboardButton . WithCallbackData ( "🏠 Главное меню" , "main_menu" )
}
} ) ;
2025-03-19 17:59:32 +07:00
await botClient . SendMessage (
chatId : chatId ,
2025-03-19 20:37:51 +07:00
text : "🔐 <b>Панель администраторов:</b>" ,
parseMode : ParseMode . Html ,
2025-03-19 17:59:32 +07:00
replyMarkup : keyboard
) ;
}
2025-03-19 22:57:11 +07:00
2025-03-19 15:27:07 +07:00
private static async Task ViewReports ( ITelegramBotClient botClient , long chatId )
{
string connectionString = "Data Source=bot.db" ;
try
{
using ( var connection = new SqliteConnection ( connectionString ) )
{
await connection . OpenAsync ( ) ;
var command = connection . CreateCommand ( ) ;
2025-03-19 23:04:12 +07:00
command . CommandText = "SELECT Id, Description, Status, Priority FROM Reports WHERE Status != 'закрыта' ORDER BY CASE Priority WHEN 'высокий' THEN 1 WHEN 'средний' THEN 2 ELSE 3 END" ;
2025-03-19 15:27:07 +07:00
var buttons = new List < InlineKeyboardButton [ ] > ( ) ;
using ( var reader = await command . ExecuteReaderAsync ( ) )
{
while ( await reader . ReadAsync ( ) )
{
long id = reader . GetInt64 ( 0 ) ;
string description = reader . GetString ( 1 ) . Substring ( 0 , Math . Min ( 20 , reader . GetString ( 1 ) . Length ) ) ;
string status = reader . GetString ( 2 ) ;
2025-03-19 23:04:12 +07:00
string priority = reader . GetString ( 3 ) ;
2025-03-19 23:00:44 +07:00
string statusEmoji = GetStatusEmoji ( status ) ;
2025-03-19 23:04:12 +07:00
string priorityMarker = priority . ToLower ( ) = = "высокий" ? "⚠️" : "" ;
2025-03-19 15:27:07 +07:00
buttons . Add ( new [ ]
{
2025-03-19 19:00:55 +07:00
InlineKeyboardButton . WithCallbackData (
2025-03-19 23:04:12 +07:00
$"{priorityMarker} #{id} - {statusEmoji} {status} - {description}..." ,
2025-03-19 19:00:55 +07:00
$"report_{id}" )
} ) ;
2025-03-19 15:27:07 +07:00
}
}
// Добавляем кнопки навигации
buttons . Add ( new [ ]
{
2025-03-19 22:57:11 +07:00
InlineKeyboardButton . WithCallbackData ( "🔙 Назад" , "back_to_admin_panel" ) ,
InlineKeyboardButton . WithCallbackData ( "🏠 Главное меню" , "main_menu" )
2025-03-19 19:00:55 +07:00
} ) ;
2025-03-19 15:27:07 +07:00
await botClient . SendMessage (
chatId : chatId ,
text : "Список заявок:" ,
replyMarkup : new InlineKeyboardMarkup ( buttons )
) ;
}
}
catch ( Exception ex )
{
Log . Error ( $"Ошибка: {ex.Message}" ) ;
await botClient . SendMessage ( chatId , "Ошибка при получении заявок" ) ;
}
}
2025-03-19 22:53:45 +07:00
2025-03-19 22:57:11 +07:00
2025-03-19 23:00:44 +07:00
2025-03-19 23:04:12 +07:00
2025-03-19 17:59:32 +07:00
private static async Task ViewArchivedReports ( ITelegramBotClient botClient , long chatId )
{
string connectionString = "Data Source=bot.db" ;
try
{
using ( var connection = new SqliteConnection ( connectionString ) )
{
await connection . OpenAsync ( ) ;
var command = connection . CreateCommand ( ) ;
2025-03-19 23:04:12 +07:00
command . CommandText = "SELECT Id, Description, Status, Priority FROM Reports WHERE Status = 'закрыта' ORDER BY CASE Priority WHEN 'высокий' THEN 1 WHEN 'средний' THEN 2 ELSE 3 END" ;
2025-03-19 17:59:32 +07:00
var buttons = new List < InlineKeyboardButton [ ] > ( ) ;
using ( var reader = await command . ExecuteReaderAsync ( ) )
{
while ( await reader . ReadAsync ( ) )
{
long id = reader . GetInt64 ( 0 ) ;
string description = reader . GetString ( 1 ) . Substring ( 0 , Math . Min ( 20 , reader . GetString ( 1 ) . Length ) ) ;
string status = reader . GetString ( 2 ) ;
2025-03-19 23:04:12 +07:00
string priority = reader . GetString ( 3 ) ;
2025-03-19 23:00:44 +07:00
string statusEmoji = GetStatusEmoji ( status ) ;
2025-03-19 23:04:12 +07:00
string priorityMarker = priority . ToLower ( ) = = "высокий" ? "⚠️" : "" ;
2025-03-19 17:59:32 +07:00
buttons . Add ( new [ ]
{
InlineKeyboardButton . WithCallbackData (
2025-03-19 23:04:12 +07:00
$"{priorityMarker} #{id} - {statusEmoji} {status} - {description}..." ,
2025-03-19 17:59:32 +07:00
$"report_{id}" )
} ) ;
}
}
// Добавляем кнопки навигации
buttons . Add ( new [ ]
{
2025-03-19 22:57:11 +07:00
InlineKeyboardButton . WithCallbackData ( "🔙 Назад" , "back_to_admin_panel" ) ,
InlineKeyboardButton . WithCallbackData ( "🏠 Главное меню" , "main_menu" )
2025-03-19 17:59:32 +07:00
} ) ;
await botClient . SendMessage (
chatId : chatId ,
text : "Архив заявок:" ,
replyMarkup : new InlineKeyboardMarkup ( buttons )
) ;
}
}
catch ( Exception ex )
{
Log . Error ( $"Ошибка: {ex.Message}" ) ;
await botClient . SendMessage ( chatId , "Ошибка при получении архива заявок" ) ;
}
}
2025-03-19 22:57:11 +07:00
2025-03-19 23:00:44 +07:00
2025-03-19 23:04:12 +07:00
2025-03-19 15:27:07 +07:00
private static async Task ShowReportDetails ( ITelegramBotClient botClient , long chatId , long reportId , int messageId )
{
try
{
using ( var connection = new SqliteConnection ( "Data Source=bot.db" ) )
{
await connection . OpenAsync ( ) ;
var command = connection . CreateCommand ( ) ;
2025-03-19 19:45:56 +07:00
command . CommandText = "SELECT Priority, Room, Description, ReporterName, Status, DateCreated FROM Reports WHERE Id = @id" ;
2025-03-19 15:27:07 +07:00
command . Parameters . AddWithValue ( "@id" , reportId ) ;
using ( var reader = await command . ExecuteReaderAsync ( ) )
{
if ( await reader . ReadAsync ( ) )
{
2025-03-19 19:45:56 +07:00
string priority = reader . GetString ( 0 ) ;
string room = reader . GetString ( 1 ) ;
string description = reader . GetString ( 2 ) ;
string reporterName = reader . GetString ( 3 ) ;
string status = reader . GetString ( 4 ) ;
string dateCreated = reader . GetDateTime ( 5 ) . ToString ( "yyyy-MM-dd HH:mm:ss" ) ;
2025-03-19 15:27:07 +07:00
2025-03-19 20:19:46 +07:00
string priorityEmoji = GetPriorityEmoji ( priority ) ;
string statusEmoji = GetStatusEmoji ( status ) ;
2025-03-19 15:27:07 +07:00
var statusButtons = new InlineKeyboardMarkup ( new [ ]
{
2025-03-19 19:00:55 +07:00
new [ ]
{
InlineKeyboardButton . WithCallbackData ( "🟡 Ожидает" , $"status_{reportId}_о жида е т" ) ,
InlineKeyboardButton . WithCallbackData ( "🔵 В работе" , $"status_{reportId}_в работе" )
} ,
new [ ]
{
InlineKeyboardButton . WithCallbackData ( "🟢 Закрыта" , $"status_{reportId}_за кр ыта " )
} ,
new [ ]
{
InlineKeyboardButton . WithCallbackData ( "❌ Удалить заявку" , $"delete_{reportId}" )
} ,
new [ ]
{
InlineKeyboardButton . WithCallbackData ( "Назад" , "back_to_list" ) ,
InlineKeyboardButton . WithCallbackData ( "Главное меню" , "main_menu" )
}
} ) ;
2025-03-19 15:27:07 +07:00
2025-03-19 19:45:56 +07:00
string newText = $"Заявка #{reportId}\n\n" +
2025-03-19 20:19:46 +07:00
$"Приоритет: {priorityEmoji} {priority}\n" +
2025-03-19 19:45:56 +07:00
$"Кабинет: {room}\n" +
$"Описание: {description}\n" +
$"ФИО: {reporterName}\n" +
2025-03-19 20:19:46 +07:00
$"Статус: {statusEmoji} {status}\n" +
2025-03-19 19:45:56 +07:00
$"Дата создания: {dateCreated}" ;
2025-03-19 16:14:02 +07:00
2025-03-19 16:34:48 +07:00
await botClient . SendMessage (
chatId : chatId ,
text : newText ,
replyMarkup : statusButtons
2025-03-19 16:06:46 +07:00
) ;
2025-03-19 15:27:07 +07:00
}
}
}
}
catch ( Exception ex )
{
Log . Error ( $"Ошибка: {ex.Message}" ) ;
}
}
2025-03-19 16:06:46 +07:00
2025-03-19 20:37:51 +07:00
// Метод для удаления администратора из базы данных
private static async Task RemoveAdminFromDatabase ( long chatId )
{
try
{
using ( var connection = new SqliteConnection ( "Data Source=bot.db" ) )
{
await connection . OpenAsync ( ) ;
var command = connection . CreateCommand ( ) ;
command . CommandText = "DELETE FROM Admins WHERE ChatId = @chatId" ;
command . Parameters . AddWithValue ( "@chatId" , chatId ) ;
int rowsAffected = await command . ExecuteNonQueryAsync ( ) ;
if ( rowsAffected > 0 )
{
admins . Remove ( chatId ) ;
Log . Information ( $"Администратор {chatId} удален из базы данных" ) ;
}
else
{
Log . Information ( $"Администратор {chatId} не найден в базе данных" ) ;
}
}
}
catch ( Exception ex )
{
Log . Error ( $"Ошибка при удалении администратора из базы данных: {ex.Message}" ) ;
}
}
// Метод для отображения списка администраторов
private static async Task ShowAdminsList ( ITelegramBotClient botClient , long chatId )
{
try
{
// Проверяем, что запрашивающий пользователь - администратор
if ( ! admins . Contains ( chatId ) )
{
await botClient . SendMessage (
chatId : chatId ,
text : "⛔ У вас нет прав для просмотра списка администраторов."
) ;
return ;
}
// Получаем список всех администраторов из базы данных
var adminsList = new List < ( long chatId , string username ) > ( ) ;
using ( var connection = new SqliteConnection ( "Data Source=bot.db" ) )
{
await connection . OpenAsync ( ) ;
var command = connection . CreateCommand ( ) ;
command . CommandText = "SELECT ChatId FROM Admins" ;
using ( var reader = await command . ExecuteReaderAsync ( ) )
{
while ( await reader . ReadAsync ( ) )
{
long adminId = reader . GetInt64 ( 0 ) ;
string username = "Неизвестно" ;
// Пытаемся получить имя пользователя
try
{
var user = await botClient . GetChat ( adminId ) ;
username = user . Username ? ? user . FirstName ? ? "Неизвестно" ;
}
catch
{
// Если возникает ошибка при получении информации о пользователе,
// просто используем "Неизвестно"
}
adminsList . Add ( ( adminId , username ) ) ;
}
}
}
// Формируем сообщение
if ( adminsList . Count = = 0 )
{
await botClient . SendMessage (
chatId : chatId ,
text : "⚠️ В системе нет зарегистрированных администраторов."
) ;
return ;
}
var buttons = new List < InlineKeyboardButton [ ] > ( ) ;
var messageText = new System . Text . StringBuilder ( ) ;
messageText . AppendLine ( "📋 <b>Список администраторов:</b>\n" ) ;
for ( int i = 0 ; i < adminsList . Count ; i + + )
{
var ( adminId , username ) = adminsList [ i ] ;
messageText . AppendLine ( $"{i + 1}. {username} (ID: {adminId})" ) ;
buttons . Add ( new [ ] {
InlineKeyboardButton . WithCallbackData ( $"❌ Удалить {username}" , $"removeadmin_{adminId}" )
} ) ;
}
buttons . Add ( new [ ] {
InlineKeyboardButton . WithCallbackData ( "🔙 Назад" , "admin_settings" )
} ) ;
var keyboard = new InlineKeyboardMarkup ( buttons ) ;
await botClient . SendMessage (
chatId : chatId ,
text : messageText . ToString ( ) ,
parseMode : ParseMode . Html ,
replyMarkup : keyboard
) ;
}
catch ( Exception ex )
{
Log . Error ( $"Ошибка при отображении списка администраторов: {ex.Message}" ) ;
await botClient . SendMessage (
chatId : chatId ,
text : "❌ Произошла ошибка при отображении списка администраторов."
) ;
}
}
2025-03-19 22:57:11 +07:00
2025-03-19 20:37:51 +07:00
// Добавим метод для отображения раздела настроек администраторов
private static async Task ShowAdminSettings ( ITelegramBotClient botClient , long chatId )
{
try
{
// Проверяем, что запрашивающий пользователь - администратор
if ( ! admins . Contains ( chatId ) )
{
await botClient . SendMessage (
chatId : chatId ,
text : "⛔ У вас нет прав для доступа к настройкам администраторов."
) ;
await Task . Delay ( 2000 ) ;
await SendMainMenu ( botClient , chatId ) ;
return ;
}
2025-03-19 22:51:37 +07:00
// Получаем список всех администраторов из базы данных
var adminsList = new List < ( long chatId , string username ) > ( ) ;
using ( var connection = new SqliteConnection ( "Data Source=bot.db" ) )
2025-03-19 22:44:20 +07:00
{
2025-03-19 22:51:37 +07:00
await connection . OpenAsync ( ) ;
var command = connection . CreateCommand ( ) ;
command . CommandText = "SELECT ChatId FROM Admins" ;
using ( var reader = await command . ExecuteReaderAsync ( ) )
{
while ( await reader . ReadAsync ( ) )
{
long adminId = reader . GetInt64 ( 0 ) ;
string username = "Неизвестно" ;
// Пытаемся получить имя пользователя
try
{
var user = await botClient . GetChat ( adminId ) ;
username = user . Username ? ? user . FirstName ? ? "Неизвестно" ;
}
catch
{
// Если возникает ошибка при получении информации о пользователе,
// просто используем "Неизвестно"
}
adminsList . Add ( ( adminId , username ) ) ;
}
}
}
// Формируем сообщение
if ( adminsList . Count = = 0 )
{
await botClient . SendMessage (
chatId : chatId ,
text : "⚠️ В системе нет зарегистрированных администраторов."
) ;
return ;
}
var buttons = new List < InlineKeyboardButton [ ] > ( ) ;
var messageText = new System . Text . StringBuilder ( ) ;
messageText . AppendLine ( "📋 <b>Список администраторов:</b>\n" ) ;
for ( int i = 0 ; i < adminsList . Count ; i + + )
{
var ( adminId , username ) = adminsList [ i ] ;
messageText . AppendLine ( $"{i + 1}. {username} (ID: {adminId})" ) ;
buttons . Add ( new [ ] {
InlineKeyboardButton . WithCallbackData ( $"❌ Удалить {username}" , $"removeadmin_{adminId}" )
} ) ;
2025-03-19 22:44:20 +07:00
}
2025-03-19 22:51:37 +07:00
buttons . Add ( new [ ] {
InlineKeyboardButton . WithCallbackData ( "🔙 Назад к панели администратора" , "admin_panel" ) ,
InlineKeyboardButton . WithCallbackData ( "🏠 Главное меню" , "main_menu" )
2025-03-19 20:37:51 +07:00
} ) ;
2025-03-19 22:51:37 +07:00
var keyboard = new InlineKeyboardMarkup ( buttons ) ;
2025-03-19 20:37:51 +07:00
await botClient . SendMessage (
chatId : chatId ,
2025-03-19 22:51:37 +07:00
text : messageText . ToString ( ) ,
2025-03-19 20:37:51 +07:00
parseMode : ParseMode . Html ,
replyMarkup : keyboard
) ;
}
catch ( Exception ex )
{
Log . Error ( $"Ошибка при отображении настроек администраторов: {ex.Message}" ) ;
}
}
2025-03-19 16:14:02 +07:00
2025-03-19 16:34:48 +07:00
2025-03-19 19:45:56 +07:00
2025-03-19 22:57:11 +07:00
2025-03-19 20:19:46 +07:00
private static async Task UpdateReportStatus ( long reportId , string newStatus , long changerId )
2025-03-19 15:27:07 +07:00
{
2025-03-19 20:19:46 +07:00
try
{
string oldStatus = "" ;
// Сначала получаем текущий статус
using ( var connection = new SqliteConnection ( "Data Source=bot.db" ) )
{
await connection . OpenAsync ( ) ;
var getStatusCommand = connection . CreateCommand ( ) ;
getStatusCommand . CommandText = "SELECT Status FROM Reports WHERE Id = @id" ;
getStatusCommand . Parameters . AddWithValue ( "@id" , reportId ) ;
2025-03-19 20:37:51 +07:00
oldStatus = ( await getStatusCommand . ExecuteScalarAsync ( ) ) ? . ToString ( ) ? ? string . Empty ;
2025-03-19 20:19:46 +07:00
}
// Если статус не изменился, прерываем выполнение
if ( oldStatus = = newStatus ) return ;
// Обновляем статус
using ( var connection = new SqliteConnection ( "Data Source=bot.db" ) )
{
await connection . OpenAsync ( ) ;
var command = connection . CreateCommand ( ) ;
command . CommandText = "UPDATE Reports SET Status = @status WHERE Id = @id" ;
command . Parameters . AddWithValue ( "@status" , newStatus ) ;
command . Parameters . AddWithValue ( "@id" , reportId ) ;
await command . ExecuteNonQueryAsync ( ) ;
// Уведомляем администраторов о б изменении статуса
await NotifyAdminsAboutStatusChange ( reportId , newStatus , oldStatus , changerId ) ;
}
}
catch ( Exception ex )
2025-03-19 15:27:07 +07:00
{
2025-03-19 20:19:46 +07:00
Log . Error ( $"Ошибка при обновлении статуса заявки: {ex.Message}" ) ;
2025-03-19 15:27:07 +07:00
}
}
2025-03-19 19:20:14 +07:00
private static async Task SaveReportToDatabase ( long chatId , Report report )
2025-03-17 14:53:01 +07:00
{
string connectionString = "Data Source=bot.db" ; // Используем SQLite
try
{
using ( var connection = new SqliteConnection ( connectionString ) )
{
await connection . OpenAsync ( ) ;
var insertCommand = connection . CreateCommand ( ) ;
insertCommand . CommandText =
@ "
2025-03-19 19:20:14 +07:00
INSERT INTO Reports ( ChatId , Priority , Room , Description , ReporterName , Status )
VALUES ( @ChatId , @Priority , @Room , @Description , @ReporterName , ' о ж и д а е т ' ) ;
2025-03-19 20:19:46 +07:00
SELECT last_insert_rowid ( ) ;
";
2025-03-17 14:53:01 +07:00
insertCommand . Parameters . AddWithValue ( "@ChatId" , chatId ) ;
2025-03-19 19:20:14 +07:00
insertCommand . Parameters . AddWithValue ( "@Priority" , report . Priority ) ;
insertCommand . Parameters . AddWithValue ( "@Room" , report . Room ) ;
insertCommand . Parameters . AddWithValue ( "@Description" , report . Description ) ;
insertCommand . Parameters . AddWithValue ( "@ReporterName" , report . ReporterName ) ;
2025-03-17 14:53:01 +07:00
2025-03-19 20:19:46 +07:00
long reportId = Convert . ToInt64 ( await insertCommand . ExecuteScalarAsync ( ) ) ;
Log . Information ( $"Заявка от пользователя {chatId} успешно сохранена с ID {reportId}." ) ;
// Уведомляем администраторов о новой заявке
await NotifyAdminsAboutNewReport ( reportId , report ) ;
2025-03-17 14:53:01 +07:00
}
}
catch ( Exception ex )
{
Log . Error ( $"Ошибка при сохранении заявки в базу данных: {ex.Message}" ) ;
}
}
2025-03-19 16:51:33 +07:00
2025-03-19 19:20:14 +07:00
2025-03-19 20:19:46 +07:00
// Обновляем метод CreateDatabaseIfNotExists
2025-03-17 15:07:41 +07:00
private static async Task CreateDatabaseIfNotExists ( )
{
string connectionString = "Data Source=bot.db" ; // Путь к вашей базе данных
try
{
using ( var connection = new SqliteConnection ( connectionString ) )
{
await connection . OpenAsync ( ) ;
2025-03-19 19:29:40 +07:00
// Проверяем, существует ли таблица Reports
var checkTableCommand = connection . CreateCommand ( ) ;
checkTableCommand . CommandText = "PRAGMA table_info(Reports);" ;
var tableInfo = await checkTableCommand . ExecuteReaderAsync ( ) ;
2025-03-19 19:31:45 +07:00
var requiredColumns = new HashSet < string > { "Id" , "ChatId" , "Priority" , "Room" , "Description" , "ReporterName" , "DateCreated" , "Status" } ;
var existingColumns = new HashSet < string > ( ) ;
2025-03-19 19:29:40 +07:00
while ( await tableInfo . ReadAsync ( ) )
{
2025-03-19 19:32:58 +07:00
existingColumns . Add ( tableInfo [ "name" ] ? . ToString ( ) ? ? string . Empty ) ;
2025-03-19 19:29:40 +07:00
}
2025-03-19 19:31:45 +07:00
foreach ( var column in requiredColumns )
2025-03-19 19:29:40 +07:00
{
2025-03-19 19:31:45 +07:00
if ( ! existingColumns . Contains ( column ) )
{
var alterTableCommand = connection . CreateCommand ( ) ;
switch ( column )
{
case "Priority" :
alterTableCommand . CommandText = "ALTER TABLE Reports ADD COLUMN Priority TEXT NOT NULL DEFAULT 'низкий';" ;
break ;
case "Room" :
2025-03-19 19:32:58 +07:00
alterTableCommand . CommandText = "ALTER TABLE Reports ADD COLUMN Room TEXT NOT NULL DEFAULT '';" ;
2025-03-19 19:31:45 +07:00
break ;
case "Description" :
2025-03-19 19:32:58 +07:00
alterTableCommand . CommandText = "ALTER TABLE Reports ADD COLUMN Description TEXT NOT NULL DEFAULT '';" ;
2025-03-19 19:31:45 +07:00
break ;
case "ReporterName" :
2025-03-19 19:32:58 +07:00
alterTableCommand . CommandText = "ALTER TABLE Reports ADD COLUMN ReporterName TEXT NOT NULL DEFAULT '';" ;
2025-03-19 19:31:45 +07:00
break ;
case "DateCreated" :
alterTableCommand . CommandText = "ALTER TABLE Reports ADD COLUMN DateCreated DATETIME DEFAULT CURRENT_TIMESTAMP;" ;
break ;
case "Status" :
alterTableCommand . CommandText = "ALTER TABLE Reports ADD COLUMN Status TEXT DEFAULT 'ожидает';" ;
break ;
}
await alterTableCommand . ExecuteNonQueryAsync ( ) ;
Log . Information ( $"Столбец {column} добавлен в таблицу Reports." ) ;
}
2025-03-19 19:29:40 +07:00
}
2025-03-19 20:19:46 +07:00
// Создаем таблицу Reports, если её не существует
2025-03-17 15:07:41 +07:00
var createTableCommand = connection . CreateCommand ( ) ;
createTableCommand . CommandText =
@ "
2025-03-19 19:22:29 +07:00
CREATE TABLE IF NOT EXISTS Reports (
Id INTEGER PRIMARY KEY AUTOINCREMENT ,
ChatId INTEGER NOT NULL ,
Priority TEXT NOT NULL ,
Room TEXT NOT NULL ,
Description TEXT NOT NULL ,
ReporterName TEXT NOT NULL ,
DateCreated DATETIME DEFAULT CURRENT_TIMESTAMP ,
Status TEXT DEFAULT ' о ж и д а е т '
) ;
2025-03-19 20:19:46 +07:00
";
2025-03-17 15:07:41 +07:00
await createTableCommand . ExecuteNonQueryAsync ( ) ;
Log . Information ( "Таблица Reports успешно создана (если её не было)." ) ;
2025-03-19 20:19:46 +07:00
// Создаем таблицу администраторов
await CreateAdminsTableIfNotExists ( ) ;
2025-03-17 15:07:41 +07:00
}
}
catch ( Exception ex )
{
2025-03-19 20:19:46 +07:00
Log . Error ( $"Ошибка при создании таблиц в базе данных: {ex.Message}" ) ;
2025-03-17 15:07:41 +07:00
}
}
2025-03-19 19:22:29 +07:00
2025-03-19 19:29:40 +07:00
2025-03-19 19:31:45 +07:00
2025-03-19 19:32:58 +07:00
2025-03-19 20:19:46 +07:00
2025-03-19 19:20:14 +07:00
private static Dictionary < long , int > userReportSteps = new Dictionary < long , int > ( ) ;
private static Dictionary < long , Report > userReports = new Dictionary < long , Report > ( ) ;
private class Report
{
public string Priority { get ; set ; } = string . Empty ;
public string Room { get ; set ; } = string . Empty ;
public string Description { get ; set ; } = string . Empty ;
public string ReporterName { get ; set ; } = string . Empty ;
}
2025-03-19 20:05:10 +07:00
2025-03-12 17:52:00 +07:00
private static Task HandleErrorAsync ( ITelegramBotClient botClient , Exception exception , CancellationToken cancellationToken )
{
2025-03-12 22:41:14 +07:00
Log . Error ( $"Ошибка в процессе работы с ботом: {exception.Message}" ) ;
2025-03-12 22:35:28 +07:00
Log . Error ( $"StackTrace: {exception.StackTrace}" ) ;
2025-03-12 17:52:00 +07:00
return Task . CompletedTask ;
}
2025-03-19 20:19:46 +07:00
// Добавим метод для создания таблицы администраторов
private static async Task CreateAdminsTableIfNotExists ( )
{
try
{
using ( var connection = new SqliteConnection ( "Data Source=bot.db" ) )
{
await connection . OpenAsync ( ) ;
var command = connection . CreateCommand ( ) ;
command . CommandText = @ "
CREATE TABLE IF NOT EXISTS Admins (
Id INTEGER PRIMARY KEY AUTOINCREMENT ,
ChatId INTEGER NOT NULL UNIQUE
) ; ";
await command . ExecuteNonQueryAsync ( ) ;
Log . Information ( "Таблица Admins успешно создана (если её не было)." ) ;
}
}
catch ( Exception ex )
{
Log . Error ( $"Ошибка при создании таблицы Admins: {ex.Message}" ) ;
}
}
// Метод для сохранения администратора в базу данных
private static async Task SaveAdminToDatabase ( long chatId )
{
try
{
using ( var connection = new SqliteConnection ( "Data Source=bot.db" ) )
{
await connection . OpenAsync ( ) ;
// Проверяем, существует ли уже такой админ
var checkCommand = connection . CreateCommand ( ) ;
checkCommand . CommandText = "SELECT COUNT(*) FROM Admins WHERE ChatId = @chatId" ;
checkCommand . Parameters . AddWithValue ( "@chatId" , chatId ) ;
int count = Convert . ToInt32 ( await checkCommand . ExecuteScalarAsync ( ) ) ;
if ( count = = 0 )
{
// Добавляем нового админа
var insertCommand = connection . CreateCommand ( ) ;
insertCommand . CommandText = "INSERT INTO Admins (ChatId) VALUES (@chatId)" ;
insertCommand . Parameters . AddWithValue ( "@chatId" , chatId ) ;
await insertCommand . ExecuteNonQueryAsync ( ) ;
Log . Information ( $"Администратор {chatId} добавлен в базу данных" ) ;
}
}
}
catch ( Exception ex )
{
Log . Error ( $"Ошибка при сохранении администратора в базу данных: {ex.Message}" ) ;
}
}
// Метод для загрузки администраторов из базы данных
private static async Task LoadAdminsFromDatabase ( )
{
try
{
using ( var connection = new SqliteConnection ( "Data Source=bot.db" ) )
{
await connection . OpenAsync ( ) ;
var command = connection . CreateCommand ( ) ;
command . CommandText = "SELECT ChatId FROM Admins" ;
using ( var reader = await command . ExecuteReaderAsync ( ) )
{
while ( await reader . ReadAsync ( ) )
{
long adminId = reader . GetInt64 ( 0 ) ;
admins . Add ( adminId ) ;
Log . Information ( $"Загружен администратор с ID: {adminId}" ) ;
}
}
}
Log . Information ( $"Загружено {admins.Count} администраторов из базы данных" ) ;
}
catch ( Exception ex )
{
Log . Error ( $"Ошибка при загрузке администраторов из базы данных: {ex.Message}" ) ;
}
}
// Метод для уведомления администраторов о новой заявке
private static async Task NotifyAdminsAboutNewReport ( long reportId , Report report )
{
try
{
foreach ( var adminId in admins )
{
var statusEmoji = GetPriorityEmoji ( report . Priority ) ;
var keyboard = new InlineKeyboardMarkup ( new [ ]
{
new [ ]
{
InlineKeyboardButton . WithCallbackData ( "📝 Посмотреть детали" , $"report_{reportId}" ) ,
InlineKeyboardButton . WithCallbackData ( "📋 В с е заявки" , "view_reports" )
}
} ) ;
await _botClient . SendMessage (
chatId : adminId ,
text : $"{statusEmoji} <b>Новая заявка #{reportId}</b>\n\n" +
$"<b>Приоритет:</b> {report.Priority}\n" +
$"<b>Кабинет:</b> {report.Room}\n" +
$"<b>Описание:</b> {report.Description}\n" +
$"<b>От:</b> {report.ReporterName}" ,
parseMode : ParseMode . Html ,
replyMarkup : keyboard
) ;
Log . Information ( $"Уведомление о новой заявке #{reportId} отправлено администратору {adminId}" ) ;
}
}
catch ( Exception ex )
{
Log . Error ( $"Ошибка при отправке уведомлений администраторам о новой заявке: {ex.Message}" ) ;
}
}
// Метод для уведомления администраторов о б изменении статуса заявки
private static async Task NotifyAdminsAboutStatusChange ( long reportId , string newStatus , string oldStatus , long changerId )
{
try
{
// Получаем данные о заявке
string description = "" ;
string priority = "" ;
string room = "" ;
using ( var connection = new SqliteConnection ( "Data Source=bot.db" ) )
{
await connection . OpenAsync ( ) ;
var command = connection . CreateCommand ( ) ;
command . CommandText = "SELECT Description, Priority, Room FROM Reports WHERE Id = @id" ;
command . Parameters . AddWithValue ( "@id" , reportId ) ;
using ( var reader = await command . ExecuteReaderAsync ( ) )
{
if ( await reader . ReadAsync ( ) )
{
description = reader . GetString ( 0 ) ;
priority = reader . GetString ( 1 ) ;
room = reader . GetString ( 2 ) ;
}
}
}
foreach ( var adminId in admins )
{
// Н е уведомляем админа, который сам изменил статус
if ( adminId = = changerId ) continue ;
string statusEmoji = GetStatusEmoji ( newStatus ) ;
var keyboard = new InlineKeyboardMarkup ( new [ ]
{
new [ ]
{
InlineKeyboardButton . WithCallbackData ( "📝 Посмотреть детали" , $"report_{reportId}" )
}
} ) ;
await _botClient . SendMessage (
chatId : adminId ,
text : $"{statusEmoji} <b>Обновление статуса заявки #{reportId}</b>\n\n" +
$"<b>Приоритет:</b> {priority}\n" +
$"<b>Кабинет:</b> {room}\n" +
$"<b>Статус изменен:</b> {oldStatus} ➡️ {newStatus}\n\n" +
$"<b>Фрагмент описания:</b> {description.Substring(0, Math.Min(50, description.Length))}..." ,
parseMode : ParseMode . Html ,
replyMarkup : keyboard
) ;
Log . Information ( $"Уведомление о б изменении статуса заявки #{reportId} отправлено администратору {adminId}" ) ;
}
}
catch ( Exception ex )
{
Log . Error ( $"Ошибка при отправке уведомлений о б изменении статуса: {ex.Message}" ) ;
}
}
// Вспомогательный метод для получения emoji в зависимости от приоритета
private static string GetPriorityEmoji ( string priority )
{
return priority . ToLower ( ) switch
{
"high" or "высокий" = > "🔴" ,
"medium" or "средний" = > "🟠" ,
"low" or "низкий" = > "🟢" ,
_ = > "ℹ ️ "
} ;
}
// Вспомогательный метод для получения emoji в зависимости от статуса
private static string GetStatusEmoji ( string status )
{
return status . ToLower ( ) switch
{
"ожидает" = > "🟡" ,
"в работе" = > "🔵" ,
"закрыта" = > "🟢" ,
_ = > "ℹ ️ "
} ;
}
2025-03-19 13:56:21 +07:00
}