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-20 09:50:04 +07:00
private static Dictionary < long , string > adminFullNames = new Dictionary < long , string > ( ) ;
2025-03-21 09:56:56 +07:00
private static HashSet < long > superAdmins = new HashSet < long > ( ) ; // Хранение списка суперпользователей
private static string superAdminPassword = "superadmin123" ; // Пароль для суперпользователя
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
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
{
_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}" ) ;
throw ;
}
2025-03-12 17:52:00 +07:00
2025-03-17 15:07:41 +07:00
// Создание базы данных и таблицы, если они не существуют
await CreateDatabaseIfNotExists ( ) ;
2025-03-20 11:02:41 +07:00
await CreateUserSettingsTableIfNotExists ( ) ;
2025-03-17 15:07:41 +07:00
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-20 11:44:58 +07:00
private static async Task MonitorReportStatus ( long reportId , CancellationToken token )
{
2025-03-20 12:11:21 +07:00
// Ждем 1 час перед первой проверкой
2025-03-20 22:55:36 +07:00
await Task . Delay ( TimeSpan . FromHours ( 1 ) , token ) ;
2025-03-20 11:52:14 +07:00
2025-03-20 11:44:58 +07:00
while ( ! token . IsCancellationRequested )
{
try
{
using ( var connection = new SqliteConnection ( "Data Source=bot.db" ) )
{
await connection . OpenAsync ( ) ;
var command = connection . CreateCommand ( ) ;
command . CommandText = @ "
2025-03-20 22:47:33 +07:00
SELECT Status
FROM Reports
WHERE Id = @id ";
2025-03-20 11:44:58 +07:00
command . Parameters . AddWithValue ( "@id" , reportId ) ;
var status = ( string? ) await command . ExecuteScalarAsync ( ) ;
2025-03-20 22:47:33 +07:00
// Проверяем, существует ли заявка
if ( status = = null )
{
// Если заявка была удалена, прекращаем мониторинг
Log . Information ( $"Заявка #{reportId} была удалена, прекращаем мониторинг." ) ;
return ;
}
2025-03-20 11:44:58 +07:00
if ( status = = "в работе" | | status = = "закрыта" )
{
// Если статус изменился на "в работе" или "закрыта", прекращаем мониторинг
return ;
}
2025-03-20 12:11:21 +07:00
var getAdminsCommand = connection . CreateCommand ( ) ;
getAdminsCommand . CommandText = "SELECT ChatId, NotifyOnPendingReports FROM Admins" ;
using ( var reader = await getAdminsCommand . ExecuteReaderAsync ( ) )
2025-03-20 11:44:58 +07:00
{
2025-03-20 12:11:21 +07:00
while ( await reader . ReadAsync ( ) )
{
long adminId = reader . GetInt64 ( 0 ) ;
bool notifyOnPendingReports = reader . GetInt32 ( 1 ) = = 1 ;
if ( notifyOnPendingReports )
{
await _botClient . SendMessage (
chatId : adminId ,
text : $"⚠️ Заявка #{reportId} остается в статусе 'Ожидает'."
) ;
}
}
2025-03-20 11:44:58 +07:00
}
}
}
catch ( Exception ex )
{
Log . Error ( $"Ошибка при мониторинге статуса заявки #{reportId}: {ex.Message}" ) ;
}
2025-03-20 12:11:21 +07:00
// Ждем 1 час перед следующей проверкой
2025-03-20 22:55:36 +07:00
await Task . Delay ( TimeSpan . FromHours ( 1 ) , token ) ;
2025-03-20 11:44:58 +07:00
}
}
2025-03-20 11:52:14 +07:00
2025-03-20 12:11:21 +07:00
2025-03-20 22:47:33 +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 ) ;
}
catch ( Exception ex )
{
Log . Error ( $"Ошибка при удалении сообщения {messageId} в чате {chatId}: {ex.Message}" ) ;
}
}
2025-03-19 19:03:49 +07:00
2025-03-20 11:02:41 +07:00
private static async Task CreateUserSettingsTableIfNotExists ( )
{
try
{
using ( var connection = new SqliteConnection ( "Data Source=bot.db" ) )
{
await connection . OpenAsync ( ) ;
var command = connection . CreateCommand ( ) ;
command . CommandText = @ "
CREATE TABLE IF NOT EXISTS UserSettings (
UserId INTEGER PRIMARY KEY ,
NotificationsEnabled INTEGER NOT NULL DEFAULT 1
) ; ";
await command . ExecuteNonQueryAsync ( ) ;
Log . Information ( "Таблица UserSettings успешно создана (если её не было)." ) ;
}
}
catch ( Exception ex )
{
Log . Error ( $"Ошибка при создании таблицы UserSettings: {ex.Message}" ) ;
}
}
2025-03-21 09:33:08 +07:00
private static async Task ViewUserReports ( ITelegramBotClient botClient , long chatId )
{
string connectionString = "Data Source=bot.db" ;
try
{
using ( var connection = new SqliteConnection ( connectionString ) )
{
await connection . OpenAsync ( ) ;
var command = connection . CreateCommand ( ) ;
command . CommandText = "SELECT Id, Description, Status, Priority FROM Reports WHERE ChatId = @chatId" ;
command . Parameters . AddWithValue ( "@chatId" , chatId ) ;
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 ) ;
string priority = reader . GetString ( 3 ) ;
string statusEmoji = GetStatusEmoji ( status ) ;
string priorityMarker = priority . ToLower ( ) = = "высокий" ? "⚠️ " : "" ;
buttons . Add ( new [ ]
{
InlineKeyboardButton . WithCallbackData (
$"{priorityMarker}#{id} - {statusEmoji} {status} - {description}..." ,
$"user_report_{id}" )
} ) ;
}
}
// Добавляем кнопки навигации
buttons . Add ( new [ ]
{
InlineKeyboardButton . WithCallbackData ( "🏠 Главное меню" , "main_menu" )
} ) ;
await botClient . SendMessage (
chatId : chatId ,
text : "Ваши заявки:" ,
replyMarkup : new InlineKeyboardMarkup ( buttons )
) ;
}
}
catch ( Exception ex )
{
Log . Error ( $"Ошибка: {ex.Message}" ) ;
await botClient . SendMessage ( chatId , "Ошибка при получении ваших заявок" ) ;
}
}
2025-03-20 11:02:41 +07:00
private static async Task ShowUserSettings ( ITelegramBotClient botClient , long chatId )
{
try
{
// Получаем текущие настройки пользователя
bool notificationsEnabled = true ; // По умолчанию уведомления включены
2025-03-19 16:30:42 +07:00
2025-03-20 11:02:41 +07:00
using ( var connection = new SqliteConnection ( "Data Source=bot.db" ) )
{
await connection . OpenAsync ( ) ;
var command = connection . CreateCommand ( ) ;
command . CommandText = "SELECT NotificationsEnabled FROM UserSettings WHERE UserId = @userId" ;
command . Parameters . AddWithValue ( "@userId" , chatId ) ;
var result = await command . ExecuteScalarAsync ( ) ;
2025-03-20 11:12:10 +07:00
// Отладочная информация
Log . Information ( $"[Отладка] Для пользователя {chatId} проверяем настройки уведомлений. Результат из БД: {result}" ) ;
2025-03-20 11:02:41 +07:00
if ( result ! = null & & result ! = DBNull . Value )
{
2025-03-20 11:12:10 +07:00
int dbValue = Convert . ToInt32 ( result ) ;
notificationsEnabled = dbValue = = 1 ;
Log . Information ( $"[Отладка] Для пользователя {chatId} настройка уведомлений из БД: {dbValue} => notificationsEnabled={notificationsEnabled}" ) ;
2025-03-20 11:02:41 +07:00
}
else
{
// Если запись для пользователя отсутствует, создаем е е
var insertCommand = connection . CreateCommand ( ) ;
insertCommand . CommandText = "INSERT INTO UserSettings (UserId, NotificationsEnabled) VALUES (@userId, 1)" ;
insertCommand . Parameters . AddWithValue ( "@userId" , chatId ) ;
await insertCommand . ExecuteNonQueryAsync ( ) ;
2025-03-20 11:12:10 +07:00
Log . Information ( $"[Отладка] Создали запись для пользователя {chatId} с notificationsEnabled=true" ) ;
2025-03-20 11:02:41 +07:00
}
}
// Создаем клавиатуру с настройками
string notificationStatus = notificationsEnabled ? "✅ Включены" : "❌ Отключены" ;
string toggleAction = notificationsEnabled ? "toggle_off" : "toggle_on" ;
2025-03-20 11:12:10 +07:00
Log . Information ( $"[Отладка] Для пользователя {chatId} показываем статус: {notificationStatus}, toggleAction: {toggleAction}" ) ;
2025-03-20 11:02:41 +07:00
var keyboard = new InlineKeyboardMarkup ( new [ ]
{
new [ ]
{
InlineKeyboardButton . WithCallbackData ( $"Уведомления: {notificationStatus}" , $"notifications_{toggleAction}" )
} ,
new [ ]
{
InlineKeyboardButton . WithCallbackData ( "🔙 Назад в меню" , "main_menu" )
}
} ) ;
await botClient . SendMessage (
chatId : chatId ,
text : "⚙️ <b>Настройки пользователя</b>\n\n" +
2025-03-21 10:17:39 +07:00
"Здесь вы можете настроить параметры бота:\n\n" +
"Уведомления включают:\n" +
2025-03-21 10:18:55 +07:00
"- Уведомления о смене статуса ваших заявок\n" ,
2025-03-20 11:02:41 +07:00
parseMode : ParseMode . Html ,
replyMarkup : keyboard
) ;
}
catch ( Exception ex )
{
Log . Error ( $"Ошибка при отображении настроек пользователя: {ex.Message}" ) ;
2025-03-20 11:12:10 +07:00
Log . Error ( $"StackTrace: {ex.StackTrace}" ) ;
2025-03-20 11:02:41 +07:00
await botClient . SendMessage ( chatId , "Произошла ошибка при загрузке настроек." ) ;
}
}
2025-03-20 11:12:10 +07:00
2025-03-21 10:17:39 +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 ) ;
}
}
2025-03-20 12:06:45 +07:00
else if ( data ! = null & & data . StartsWith ( "enable_notifications_" ) )
{
long adminId = long . Parse ( data . Substring ( "enable_notifications_" . Length ) ) ;
await ToggleAdminNotifications ( adminId , true ) ;
await ShowAdminSettings ( botClient , chatId ) ;
}
else if ( data ! = null & & data . StartsWith ( "disable_notifications_" ) )
{
long adminId = long . Parse ( data . Substring ( "disable_notifications_" . Length ) ) ;
await ToggleAdminNotifications ( adminId , false ) ;
await ShowAdminSettings ( botClient , chatId ) ;
}
2025-03-21 09:33:08 +07:00
else if ( data = = "user_reports" )
{
await ViewUserReports ( botClient , chatId ) ;
}
else if ( data ! = null & & data . StartsWith ( "user_report_" ) )
{
long reportId = long . Parse ( data . Substring ( "user_report_" . Length ) ) ;
2025-03-21 09:56:56 +07:00
if ( callbackQuery ? . Message ? . MessageId ! = null )
{
int messageId = callbackQuery . Message . MessageId ;
await ShowReportDetails ( botClient , chatId , reportId , messageId ) ;
}
2025-03-21 09:33:08 +07:00
}
else if ( data ! = null & & data . StartsWith ( "delete_" ) )
{
long reportId = long . Parse ( data . Substring ( 7 ) ) ;
await DeleteReport ( botClient , chatId , reportId ) ;
}
2025-03-21 09:56:56 +07:00
else if ( data = = "leave_admin" )
{
2025-03-21 10:06:33 +07:00
bool isSuperUser = superAdmins . Contains ( chatId ) ;
2025-03-21 09:56:56 +07:00
await RemoveSelfFromAdmins ( chatId ) ;
var message = await botClient . SendMessage (
chatId : chatId ,
2025-03-21 10:06:33 +07:00
text : isSuperUser
? "✅ Вы вышли из режима суперпользователя."
: "✅ Вы вышли из режима администратора."
2025-03-21 09:56:56 +07:00
) ;
await Task . Delay ( 2000 ) ;
await botClient . DeleteMessage ( chatId , message . MessageId ) ;
await SendMainMenu ( botClient , chatId ) ;
}
else if ( data ! = null & & data . StartsWith ( "removeadmin_" ) )
{
long adminIdToRemove = long . Parse ( data . Substring ( 11 ) . Replace ( "_" , "" ) ) ;
// Проверяем, что пользователь является суперпользователем
if ( superAdmins . Contains ( chatId ) )
{
// Проверяем, не пытается ли пользователь удалить себя
if ( adminIdToRemove = = chatId )
{
var warningMessage = await botClient . SendMessage (
chatId : chatId ,
text : "⚠️ Вы не можете удалить себя из администраторов через эту функцию. Используйте 'Выйти из режима администратора'!"
) ;
await Task . Delay ( 2000 ) ;
await botClient . DeleteMessage ( chatId , warningMessage . MessageId ) ;
await ShowAdminsList ( botClient , chatId ) ;
}
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 ) ;
}
}
2025-03-19 22:01:40 +07:00
// Также добавим обработку команды /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 ) ;
// Сохраняем администратора в базу данных
2025-03-20 09:50:04 +07:00
await SaveAdminToDatabase ( message . Chat . Id , "" ) ; // Добавляем пустую строку для fullName
2025-03-19 22:01:40 +07:00
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 ) ;
}
2025-03-20 09:50:04 +07:00
2025-03-19 22:01:40 +07:00
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 23:28:19 +07:00
else if ( data = = "delete_all_reports" )
{
2025-03-21 10:14:10 +07:00
if ( superAdmins . Contains ( chatId ) )
2025-03-19 23:28:19 +07:00
{
var confirmKeyboard = new InlineKeyboardMarkup ( new [ ]
{
new [ ]
{
InlineKeyboardButton . WithCallbackData ( "✅ Подтвердить" , "confirm_delete_all_reports" ) ,
InlineKeyboardButton . WithCallbackData ( "❌ Отмена" , "admin_panel" )
}
2025-03-21 10:14:10 +07:00
} ) ;
2025-03-19 23:28:19 +07:00
await botClient . SendMessage (
chatId : chatId ,
text : "Вы уверены, что хотите удалить все заявки? Это действие необратимо." ,
replyMarkup : confirmKeyboard
) ;
}
else
{
await botClient . SendMessage ( chatId , "⛔ У вас нет прав для удаления всех заявок!" ) ;
await Task . Delay ( 2000 ) ;
await SendMainMenu ( botClient , chatId ) ;
}
}
2025-03-21 10:14:10 +07:00
2025-03-19 23:28:19 +07:00
else if ( data = = "confirm_delete_all_reports" )
{
if ( admins . Contains ( chatId ) )
{
await DeleteAllReports ( botClient , chatId ) ;
}
else
{
await botClient . SendMessage ( chatId , "⛔ У вас нет прав для удаления всех заявок!" ) ;
await Task . Delay ( 2000 ) ;
await SendMainMenu ( botClient , chatId ) ;
}
}
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 ) ;
}
2025-03-20 11:02:41 +07:00
else if ( data = = "user_settings" )
{
await ShowUserSettings ( botClient , chatId ) ;
}
else if ( data ! = null & & data . StartsWith ( "notifications_toggle_" ) )
{
2025-03-20 11:17:47 +07:00
string action = data . Substring ( "notifications_toggle_" . Length ) ; // "on" или "off"
2025-03-20 11:02:41 +07:00
await ToggleNotifications ( botClient , chatId , action ) ;
}
2025-03-20 11:17:47 +07:00
2025-03-19 22:48:53 +07:00
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-21 10:27:06 +07:00
else if ( data = = "confirm_report" )
{
await ConfirmReport ( botClient , chatId ) ;
}
else if ( data = = "cancel_report" )
{
await CancelReport ( botClient , chatId ) ;
}
2025-03-19 22:48:53 +07:00
}
}
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 ;
2025-03-20 10:18:01 +07:00
// Обработка текстовых сообщений
if ( update . Type = = UpdateType . Message & & update . Message ? . Text ! = null )
2025-03-19 22:48:53 +07:00
{
2025-03-20 10:21:33 +07:00
var receivedMessage = update . Message ;
Log . Information ( $"Получено сообщение от {receivedMessage.Chat.Id}: {receivedMessage.Text}" ) ;
2025-03-20 10:18:01 +07:00
2025-03-21 09:56:56 +07:00
if ( receivedMessage . Text . StartsWith ( "/superadm" ) )
{
string [ ] parts = receivedMessage . Text . Split ( new [ ] { ' ' } , 3 ) ; // Разделяем на 3 части: команду, пароль и остаток как ФИО
if ( parts . Length > = 3 & & parts [ 1 ] = = superAdminPassword )
{
string fullName = parts [ 2 ] ; // Вся оставшаяся строка - это ФИО
admins . Add ( receivedMessage . Chat . Id ) ;
superAdmins . Add ( receivedMessage . Chat . Id ) ;
adminFullNames [ receivedMessage . Chat . Id ] = fullName ;
// Сохраняем суперпользователя в базу данных
await SaveSuperAdminToDatabase ( receivedMessage . Chat . Id , fullName ) ;
var authMessage = await botClient . SendMessage ( receivedMessage . Chat . Id , $"✅ Вы авторизованы как суперпользователь, {fullName}!" ) ;
Log . Information ( $"Новый суперпользователь: {receivedMessage.Chat.Id}, ФИО: {fullName}" ) ;
await Task . Delay ( 2000 ) ;
await botClient . DeleteMessage ( receivedMessage . Chat . Id , authMessage . MessageId ) ;
await SendMainMenu ( botClient , receivedMessage . Chat . Id ) ;
}
else
{
var authMessage = await botClient . SendMessage ( receivedMessage . Chat . Id , "❌ Неверный формат команды или пароль! Используйте: /superadm пароль Фамилия Имя Отчество" ) ;
await Task . Delay ( 2000 ) ;
await botClient . DeleteMessage ( receivedMessage . Chat . Id , authMessage . MessageId ) ;
await SendMainMenu ( botClient , receivedMessage . Chat . Id ) ;
}
return ;
}
// Обработка обычной команды администратора
else if ( receivedMessage . Text . StartsWith ( "/admin" ) )
2025-03-19 22:48:53 +07:00
{
2025-03-20 10:21:33 +07:00
string [ ] parts = receivedMessage . Text . Split ( new [ ] { ' ' } , 3 ) ; // Разделяем на 3 части: команду, пароль и остаток как ФИО
2025-03-20 10:18:01 +07:00
if ( parts . Length > = 3 & & parts [ 1 ] = = adminPassword )
{
string fullName = parts [ 2 ] ; // Вся оставшаяся строка - это ФИО
2025-03-20 10:21:33 +07:00
admins . Add ( receivedMessage . Chat . Id ) ;
adminFullNames [ receivedMessage . Chat . Id ] = fullName ;
2025-03-21 09:56:56 +07:00
// Сохраняем администратора в базу данных, убедившись что он не суперпользователь
2025-03-20 10:21:33 +07:00
await SaveAdminToDatabase ( receivedMessage . Chat . Id , fullName ) ;
2025-03-20 10:18:01 +07:00
2025-03-20 10:21:33 +07:00
var authMessage = await botClient . SendMessage ( receivedMessage . Chat . Id , $"✅ Вы авторизованы как администратор, {fullName}!" ) ;
Log . Information ( $"Новый администратор: {receivedMessage.Chat.Id}, ФИО: {fullName}" ) ;
2025-03-20 10:18:01 +07:00
await Task . Delay ( 2000 ) ;
2025-03-20 10:21:33 +07:00
await botClient . DeleteMessage ( receivedMessage . Chat . Id , authMessage . MessageId ) ;
await SendMainMenu ( botClient , receivedMessage . Chat . Id ) ;
2025-03-20 10:18:01 +07:00
}
else
{
2025-03-20 10:21:33 +07:00
var authMessage = await botClient . SendMessage ( receivedMessage . Chat . Id , "❌ Неверный формат команды или пароль! Используйте: /admin пароль Фамилия Имя Отчество" ) ;
2025-03-20 10:18:01 +07:00
await Task . Delay ( 2000 ) ;
2025-03-20 10:21:33 +07:00
await botClient . DeleteMessage ( receivedMessage . Chat . Id , authMessage . MessageId ) ;
await SendMainMenu ( botClient , receivedMessage . Chat . Id ) ;
2025-03-20 10:18:01 +07:00
}
return ;
2025-03-19 22:48:53 +07:00
}
2025-03-20 09:50:04 +07:00
2025-03-20 10:18:01 +07:00
// В блоке для обработки текстовых сообщений
else if ( message . Text = = "/admins" )
2025-03-19 22:48:53 +07:00
{
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 ) ;
}
}
2025-03-20 11:29:21 +07:00
if ( message . Text = = "/start" )
2025-03-19 22:01:40 +07:00
{
2025-03-20 11:29:21 +07:00
await SendMainMenu ( botClient , message . Chat . Id ) ;
Log . Information ( $"Ответ на команду /start с кнопками отправлен." ) ;
2025-03-19 16:38:09 +07:00
}
2025-03-19 23:24:19 +07:00
2025-03-20 11:29:21 +07:00
else if ( usersWaitingForReport . TryGetValue ( message . Chat . Id , out bool isWaiting ) & & isWaiting )
2025-03-21 10:27:06 +07:00
{
2025-03-20 10:21:33 +07:00
if ( userReportSteps . TryGetValue ( message . Chat . Id , out int step ) )
2025-03-19 22:44:20 +07:00
{
2025-03-20 10:21:33 +07:00
switch ( step )
{
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 ;
2025-03-21 10:27:06 +07:00
userReportSteps [ message . Chat . Id ] = 5 ;
var confirmKeyboard = new InlineKeyboardMarkup ( new [ ]
2025-03-20 10:21:33 +07:00
{
2025-03-21 10:27:06 +07:00
new [ ]
{
InlineKeyboardButton . WithCallbackData ( "✅ Подтвердить" , "confirm_report" ) ,
InlineKeyboardButton . WithCallbackData ( "❌ Отменить" , "cancel_report" )
}
} ) ;
2025-03-20 10:21:33 +07:00
await botClient . SendMessage (
message . Chat . Id ,
2025-03-21 10:27:06 +07:00
"Пожалуйста, подтвердите отправку заявки:" ,
replyMarkup : confirmKeyboard
2025-03-20 10:21:33 +07:00
) ;
break ;
2025-03-21 10:27:06 +07:00
}
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-21 10:27:06 +07:00
private static async Task ConfirmReport ( ITelegramBotClient botClient , long chatId )
{
if ( userReports . TryGetValue ( chatId , out var report ) )
{
await SaveReportToDatabase ( chatId , report ) ;
var mainMenuKeyboard = new InlineKeyboardMarkup ( new [ ]
{
new [ ]
{
InlineKeyboardButton . WithCallbackData ( "Главное меню" , "main_menu" )
}
} ) ;
await botClient . SendMessage (
chatId : chatId ,
text : "✅ Спасибо за заявку! Мы обработаем её в ближайшее время." ,
replyMarkup : mainMenuKeyboard
) ;
usersWaitingForReport [ chatId ] = false ;
userReportSteps . Remove ( chatId ) ;
userReports . Remove ( chatId ) ;
Log . Information ( $"Заявка пользователя {chatId} сохранена в базе данных." ) ;
}
}
private static async Task CancelReport ( ITelegramBotClient botClient , long chatId )
{
usersWaitingForReport [ chatId ] = false ;
userReportSteps . Remove ( chatId ) ;
userReports . Remove ( chatId ) ;
await botClient . SendMessage (
chatId : chatId ,
text : "❌ Заявка отменена." ,
replyMarkup : new InlineKeyboardMarkup ( new [ ]
{
new [ ]
{
InlineKeyboardButton . WithCallbackData ( "Главное меню" , "main_menu" )
}
} )
) ;
Log . Information ( $"Заявка пользователя {chatId} отменена." ) ;
}
2025-03-19 23:28:19 +07:00
private static async Task DeleteAllReports ( ITelegramBotClient botClient , long chatId )
{
try
{
using ( var connection = new SqliteConnection ( "Data Source=bot.db" ) )
{
await connection . OpenAsync ( ) ;
var command = connection . CreateCommand ( ) ;
command . CommandText = "DELETE FROM Reports" ;
await command . ExecuteNonQueryAsync ( ) ;
var deletionMessage = await botClient . SendMessage ( chatId , "В с е заявки успешно удалены." ) ;
Log . Information ( $"В с е заявки удалены пользователем {chatId}." ) ;
// Ждем 2 секунды
await Task . Delay ( 2000 ) ;
// Удаляем сообщение о б удалении
await botClient . DeleteMessage ( chatId , deletionMessage . MessageId ) ;
// Возвращаемся к панели администратора
await SendAdminPanel ( botClient , chatId ) ;
}
}
catch ( Exception ex )
{
Log . Error ( $"Ошибка при удалении всех заявок: {ex.Message}" ) ;
await botClient . SendMessage ( chatId , "Ошибка при удалении всех заявок." ) ;
}
}
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 ( ) ;
2025-03-21 09:33:08 +07:00
command . CommandText = "SELECT ChatId FROM Reports WHERE Id = @id" ;
2025-03-19 16:51:33 +07:00
command . Parameters . AddWithValue ( "@id" , reportId ) ;
2025-03-21 09:33:08 +07:00
var ownerChatId = ( long? ) await command . ExecuteScalarAsync ( ) ;
if ( ownerChatId = = null )
{
await botClient . SendMessage ( chatId , $"Заявка #{reportId} не найдена." ) ;
return ;
}
if ( ownerChatId ! = chatId & & ! admins . Contains ( chatId ) )
{
await botClient . SendMessage ( chatId , "⛔ Вы не можете удалить эту заявку, так как она не принадлежит вам." ) ;
return ;
}
command . CommandText = "DELETE FROM Reports WHERE Id = @id" ;
2025-03-19 16:51:33 +07:00
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 ) ;
2025-03-21 09:33:08 +07:00
// Отображаем список заявок пользователя
await ViewUserReports ( 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-21 09:33:08 +07:00
2025-03-19 23:37:05 +07:00
private static async Task NotifyUserAboutStatusChange ( long chatId , long reportId , string newStatus )
{
try
{
2025-03-20 11:02:41 +07:00
// Проверяем настройки пользователя
bool notificationsEnabled = true ; // По умолчанию уведомления включены
using ( var connection = new SqliteConnection ( "Data Source=bot.db" ) )
{
await connection . OpenAsync ( ) ;
var command = connection . CreateCommand ( ) ;
command . CommandText = "SELECT NotificationsEnabled FROM UserSettings WHERE UserId = @userId" ;
command . Parameters . AddWithValue ( "@userId" , chatId ) ;
var result = await command . ExecuteScalarAsync ( ) ;
if ( result ! = null & & result ! = DBNull . Value )
{
notificationsEnabled = Convert . ToInt32 ( result ) = = 1 ;
}
}
// Если уведомления отключены, не отправляем сообщение
if ( ! notificationsEnabled )
{
Log . Information ( $"Уведомление о смене статуса заявки #{reportId} не отправлено пользователю {chatId} (уведомления отключены)" ) ;
return ;
}
2025-03-19 23:37:05 +07:00
string statusEmoji = GetStatusEmoji ( newStatus ) ;
await _botClient . SendMessage (
chatId : chatId ,
text : $"{statusEmoji} <b>Статус вашей заявки #{reportId} был изменен на: {newStatus}</b>" ,
parseMode : ParseMode . Html
) ;
Log . Information ( $"Уведомление о смене статуса заявки #{reportId} отправлено пользователю {chatId}" ) ;
}
catch ( Exception ex )
{
Log . Error ( $"Ошибка при отправке уведомления пользователю о смене статуса: {ex.Message}" ) ;
}
}
2025-03-19 19:03:49 +07:00
2025-03-20 11:02:41 +07:00
private static async Task ToggleNotifications ( ITelegramBotClient botClient , long chatId , string action )
{
try
{
2025-03-20 11:12:10 +07:00
// Проверка текущего состояния перед изменением
bool currentState = true ;
using ( var connection = new SqliteConnection ( "Data Source=bot.db" ) )
{
await connection . OpenAsync ( ) ;
var checkCommand = connection . CreateCommand ( ) ;
checkCommand . CommandText = "SELECT NotificationsEnabled FROM UserSettings WHERE UserId = @userId" ;
checkCommand . Parameters . AddWithValue ( "@userId" , chatId ) ;
var result = await checkCommand . ExecuteScalarAsync ( ) ;
if ( result ! = null & & result ! = DBNull . Value )
{
currentState = Convert . ToInt32 ( result ) = = 1 ;
}
}
Log . Information ( $"[Отладка] Переключение уведомлений для пользователя {chatId}: текущее состояние={currentState}, action={action}" ) ;
2025-03-20 11:09:25 +07:00
// Если action = "toggle_on", то нужно ВКЛЮЧИТЬ уведомления (установить в БД 1)
// Если action = "toggle_off", то нужно ВЫКЛЮЧИТЬ уведомления (установить в БД 0)
2025-03-20 11:20:49 +07:00
bool newValue = action = = "on" ;
2025-03-20 11:02:41 +07:00
int dbValue = newValue ? 1 : 0 ;
2025-03-19 19:03:49 +07:00
2025-03-20 11:12:10 +07:00
Log . Information ( $"[Отладка] Переключение уведомлений для пользователя {chatId}: action={action}, новое значение={newValue}, значение в БД={dbValue}" ) ;
2025-03-20 11:06:02 +07:00
2025-03-20 11:02:41 +07:00
using ( var connection = new SqliteConnection ( "Data Source=bot.db" ) )
{
await connection . OpenAsync ( ) ;
var command = connection . CreateCommand ( ) ;
command . CommandText = @ "
2025-03-20 11:15:05 +07:00
INSERT INTO UserSettings ( UserId , NotificationsEnabled )
VALUES ( @userId , @value )
ON CONFLICT ( UserId )
DO UPDATE SET NotificationsEnabled = @value ";
2025-03-20 11:02:41 +07:00
command . Parameters . AddWithValue ( "@userId" , chatId ) ;
command . Parameters . AddWithValue ( "@value" , dbValue ) ;
2025-03-20 11:12:10 +07:00
int rowsAffected = await command . ExecuteNonQueryAsync ( ) ;
Log . Information ( $"[Отладка] Запрос выполнен, затронуто {rowsAffected} строк" ) ;
}
// Проверка после изменения
using ( var connection = new SqliteConnection ( "Data Source=bot.db" ) )
{
await connection . OpenAsync ( ) ;
var checkCommand = connection . CreateCommand ( ) ;
checkCommand . CommandText = "SELECT NotificationsEnabled FROM UserSettings WHERE UserId = @userId" ;
checkCommand . Parameters . AddWithValue ( "@userId" , chatId ) ;
var result = await checkCommand . ExecuteScalarAsync ( ) ;
bool updatedState = false ;
if ( result ! = null & & result ! = DBNull . Value )
{
updatedState = Convert . ToInt32 ( result ) = = 1 ;
}
Log . Information ( $"[Отладка] После обновления: значение в БД для пользователя {chatId} = {result}, обновленное состояние={updatedState}" ) ;
2025-03-20 11:02:41 +07:00
}
// Показываем обновленные настройки
await ShowUserSettings ( botClient , chatId ) ;
string statusText = newValue ? "включены" : "отключены" ;
2025-03-20 11:09:25 +07:00
Log . Information ( $"Пользователь {chatId}: уведомления {statusText}" ) ;
2025-03-20 11:02:41 +07:00
}
catch ( Exception ex )
{
Log . Error ( $"Ошибка при изменении настроек уведомлений: {ex.Message}" ) ;
2025-03-20 11:12:10 +07:00
Log . Error ( $"StackTrace: {ex.StackTrace}" ) ;
2025-03-20 11:02:41 +07:00
await botClient . SendMessage ( chatId , "Произошла ошибка при обновлении настроек." ) ;
}
}
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 )
{
2025-03-21 11:04:26 +07:00
var menuButtons = new List < InlineKeyboardButton [ ] >
{
2025-03-19 17:59:32 +07:00
new [ ]
{
2025-03-19 22:57:11 +07:00
InlineKeyboardButton . WithCallbackData ( "📝 Подать заявку" , "report" ) ,
2025-03-20 11:25:24 +07:00
InlineKeyboardButton . WithCallbackData ( "⚙️ Настройки" , "user_settings" )
2025-03-20 11:02:41 +07:00
} ,
new [ ]
2025-03-21 09:33:08 +07:00
{
InlineKeyboardButton . WithCallbackData ( "📋 Мои заявки" , "user_reports" )
2025-03-21 11:04:26 +07:00
}
} ;
// Добавляем кнопку панели администратора только если пользователь является админом или суперпользователем
if ( admins . Contains ( chatId ) )
2025-03-20 11:02:41 +07:00
{
2025-03-21 11:04:26 +07:00
menuButtons . Add ( new [ ]
{
2025-03-19 22:57:11 +07:00
InlineKeyboardButton . WithCallbackData ( "🔐 Панель администратора" , "admin_panel" )
2025-03-21 11:04:26 +07:00
} ) ;
2025-03-19 17:59:32 +07:00
}
2025-03-21 11:04:26 +07:00
var keyboard = new InlineKeyboardMarkup ( menuButtons ) ;
2025-03-19 15:27:07 +07:00
await botClient . SendMessage (
chatId : chatId ,
text : "Главное меню:" ,
replyMarkup : keyboard
) ;
}
2025-03-21 09:33:08 +07:00
2025-03-21 11:04:26 +07:00
2025-03-19 17:59:32 +07:00
private static async Task SendAdminPanel ( ITelegramBotClient botClient , long chatId )
{
2025-03-21 10:14:10 +07:00
var buttonsRows = new List < InlineKeyboardButton [ ] >
{
2025-03-19 22:57:11 +07:00
new [ ]
{
InlineKeyboardButton . WithCallbackData ( "📋 Менеджер заявок" , "view_reports" ) ,
InlineKeyboardButton . WithCallbackData ( "🗃️ Архив заявок" , "view_archived_reports" )
} ,
new [ ]
{
2025-03-21 10:14:10 +07:00
InlineKeyboardButton . WithCallbackData ( "⚙️ Личный кабинет" , "admin_settings" )
}
} ;
// Добавлять кнопку "Удалить все заявки" только для суперадминов
if ( superAdmins . Contains ( chatId ) )
2025-03-19 23:28:19 +07:00
{
2025-03-21 10:14:10 +07:00
buttonsRows . Add ( new [ ]
{
2025-03-19 23:28:19 +07:00
InlineKeyboardButton . WithCallbackData ( "❌ Удалить все заявки" , "delete_all_reports" )
2025-03-21 10:14:10 +07:00
} ) ;
2025-03-19 22:57:11 +07:00
}
2025-03-21 10:14:10 +07:00
// Кнопка возврата в главное меню
buttonsRows . Add ( new [ ]
{
InlineKeyboardButton . WithCallbackData ( "🏠 Главное меню" , "main_menu" )
} ) ;
var keyboard = new InlineKeyboardMarkup ( buttonsRows ) ;
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 23:28:19 +07:00
2025-03-21 10:14:10 +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:06:45 +07:00
command . CommandText = "SELECT Id, Description, Status, Priority FROM Reports WHERE Status != 'закрыта'" ;
2025-03-19 15:27:07 +07:00
2025-03-19 23:15:18 +07:00
var buttons = new List < InlineKeyboardButton [ ] > ( ) ;
2025-03-19 15:27:07 +07:00
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:15:18 +07:00
string statusEmoji = GetStatusEmoji ( status ) ;
2025-03-19 23:21:03 +07:00
string priorityMarker = priority . ToLower ( ) = = "высокий" ? "⚠️ " : "" ;
2025-03-19 15:27:07 +07:00
2025-03-19 23:15:18 +07:00
buttons . Add ( new [ ]
{
InlineKeyboardButton . WithCallbackData (
2025-03-19 23:21:03 +07:00
$"{priorityMarker}#{id} - {statusEmoji} {status} - {description}..." ,
2025-03-19 23:15:18 +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 (
2025-03-19 23:21:03 +07:00
chatId : chatId ,
text : "Список заявок:" ,
replyMarkup : new InlineKeyboardMarkup ( buttons )
) ;
2025-03-19 15:27:07 +07:00
}
}
catch ( Exception ex )
{
Log . Error ( $"Ошибка: {ex.Message}" ) ;
await botClient . SendMessage ( chatId , "Ошибка при получении заявок" ) ;
}
}
2025-03-19 23:21:03 +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:06:45 +07:00
command . CommandText = "SELECT Id, Description, Status, Priority FROM Reports WHERE Status = 'закрыта'" ;
2025-03-19 17:59:32 +07:00
2025-03-19 23:15:18 +07:00
var buttons = new List < InlineKeyboardButton [ ] > ( ) ;
2025-03-19 17:59:32 +07:00
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:15:18 +07:00
string statusEmoji = GetStatusEmoji ( status ) ;
2025-03-19 23:21:03 +07:00
string priorityMarker = priority . ToLower ( ) = = "высокий" ? "⚠️ " : "" ;
2025-03-19 17:59:32 +07:00
2025-03-19 23:15:18 +07:00
buttons . Add ( new [ ]
{
InlineKeyboardButton . WithCallbackData (
2025-03-19 23:21:03 +07:00
$"{priorityMarker}#{id} - {statusEmoji} {status} - {description}..." ,
2025-03-19 23:15:18 +07:00
$"report_{id}" )
} ) ;
2025-03-19 17:59:32 +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 17:59:32 +07:00
} ) ;
await botClient . SendMessage (
2025-03-19 23:21:03 +07:00
chatId : chatId ,
text : "Архив заявок:" ,
replyMarkup : new InlineKeyboardMarkup ( buttons )
) ;
2025-03-19 17:59:32 +07:00
}
}
catch ( Exception ex )
{
Log . Error ( $"Ошибка: {ex.Message}" ) ;
await botClient . SendMessage ( chatId , "Ошибка при получении архива заявок" ) ;
2025-03-19 23:21:03 +07:00
2025-03-19 17:59:32 +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 23:06:45 +07:00
2025-03-19 23:09:50 +07:00
2025-03-19 23:11:40 +07:00
2025-03-19 23:21:03 +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-21 09:39:31 +07:00
command . CommandText = "SELECT Priority, Room, Description, ReporterName, Status, DateCreated, AdminId, ChatId 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-21 09:39:31 +07:00
long ownerChatId = reader . GetInt64 ( 7 ) ;
2025-03-19 15:27:07 +07:00
2025-03-20 10:05:28 +07:00
// Проверяем существование столбца AdminId
long adminId = 0 ;
try
2025-03-19 19:00:55 +07:00
{
2025-03-20 10:05:28 +07:00
if ( ! reader . IsDBNull ( 6 ) )
adminId = reader . GetInt64 ( 6 ) ;
}
catch
2025-03-19 19:00:55 +07:00
{
2025-03-20 10:05:28 +07:00
Log . Warning ( $"Столбец AdminId для заявки {reportId} не найден или содержит NULL" ) ;
2025-03-19 19:00:55 +07:00
}
2025-03-19 15:27:07 +07:00
2025-03-20 10:05:28 +07:00
string adminFullName = adminId > 0 & & adminFullNames . ContainsKey ( adminId )
2025-03-20 10:09:22 +07:00
? adminFullNames [ adminId ]
: "Н е назначен" ;
2025-03-20 10:05:28 +07:00
string priorityEmoji = GetPriorityEmoji ( priority ) ;
string statusEmoji = GetStatusEmoji ( status ) ;
2025-03-21 09:39:31 +07:00
InlineKeyboardMarkup keyboard ;
// Разные клавиатуры для админов и обычных пользователей
if ( admins . Contains ( chatId ) )
2025-03-20 10:09:22 +07:00
{
2025-03-21 09:39:31 +07:00
// Клавиатура для администраторов с возможностью изменения статуса
keyboard = new InlineKeyboardMarkup ( new [ ]
{
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" )
}
} ) ;
}
else
2025-03-20 10:09:22 +07:00
{
2025-03-21 09:39:31 +07:00
// Клавиатура для обычных пользователей - только удаление своих заявок
keyboard = new InlineKeyboardMarkup ( new [ ]
{
new [ ]
{
InlineKeyboardButton . WithCallbackData ( "❌ Удалить заявку" , $"delete_{reportId}" )
} ,
new [ ]
{
InlineKeyboardButton . WithCallbackData ( "🔙 Назад к списку" , "user_reports" ) ,
InlineKeyboardButton . WithCallbackData ( "🏠 Главное меню" , "main_menu" )
}
} ) ;
2025-03-20 10:09:22 +07:00
}
string newText = $"Заявка #{reportId}\n\n" +
$"Приоритет: {priorityEmoji} {priority}\n" +
$"Кабинет: {room}\n" +
$"Описание: {description}\n" +
$"ФИО: {reporterName}\n" +
$"Статус: {statusEmoji} {status}\n" +
$"Дата создания: {dateCreated}\n" +
$"Администратор: {adminFullName}" ;
await botClient . SendMessage (
chatId : chatId ,
text : newText ,
2025-03-21 09:39:31 +07:00
replyMarkup : keyboard
2025-03-20 10:09:22 +07:00
) ;
}
else
{
// Если заявка не найдена
await botClient . SendMessage (
chatId : chatId ,
text : $"⚠️ Заявка #{reportId} не найдена!"
) ;
Log . Warning ( $"Заявка #{reportId} не найдена при попытке просмотра деталей." ) ;
await Task . Delay ( 2000 ) ;
2025-03-21 09:39:31 +07:00
// Возвращаем к нужному списку в зависимости от роли пользователя
if ( admins . Contains ( chatId ) )
{
await ViewReports ( botClient , chatId ) ;
}
else
{
await ViewUserReports ( botClient , chatId ) ;
}
2025-03-19 15:27:07 +07:00
}
}
}
}
catch ( Exception ex )
{
2025-03-20 10:09:22 +07:00
Log . Error ( $"Ошибка при отображении деталей заявки #{reportId}: {ex.Message}" ) ;
await botClient . SendMessage (
chatId : chatId ,
text : $"Произошла ошибка при загрузке заявки #{reportId}."
) ;
2025-03-19 15:27:07 +07:00
}
}
2025-03-19 16:06:46 +07:00
2025-03-20 10:05:28 +07:00
2025-03-20 10:09:22 +07:00
2025-03-21 09:39:31 +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}" ) ;
}
}
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-21 09:56:56 +07:00
bool isSuperAdmin = superAdmins . Contains ( chatId ) ;
var buttons = new List < InlineKeyboardButton [ ] > ( ) ;
2025-03-19 22:51:37 +07:00
2025-03-21 09:56:56 +07:00
// Разные опции в зависимости от типа пользователя
if ( isSuperAdmin )
{
buttons . Add ( new [ ] {
InlineKeyboardButton . WithCallbackData ( "👥 Управление администраторами" , "view_admins" )
} ) ;
}
// Настройки уведомлений для всех типов администраторов
bool notifyOnPendingReports = true ;
2025-03-19 22:51:37 +07:00
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 ( ) ;
2025-03-21 09:56:56 +07:00
command . CommandText = "SELECT NotifyOnPendingReports FROM Admins WHERE ChatId = @chatId" ;
command . Parameters . AddWithValue ( "@chatId" , chatId ) ;
2025-03-19 22:51:37 +07:00
2025-03-21 09:56:56 +07:00
var result = await command . ExecuteScalarAsync ( ) ;
if ( result ! = null & & result ! = DBNull . Value )
2025-03-19 22:51:37 +07:00
{
2025-03-21 09:56:56 +07:00
notifyOnPendingReports = Convert . ToInt32 ( result ) = = 1 ;
2025-03-19 22:51:37 +07:00
}
}
2025-03-21 09:56:56 +07:00
string notificationStatus = notifyOnPendingReports ? "✅ Включены" : "❌ Отключены" ;
string toggleAction = notifyOnPendingReports ? "disable_notifications" : "enable_notifications" ;
2025-03-19 22:51:37 +07:00
2025-03-21 09:56:56 +07:00
buttons . Add ( new [ ] {
InlineKeyboardButton . WithCallbackData ( $"Уведомления о просрочке: {notificationStatus}" , $"{toggleAction}_{chatId}" )
} ) ;
2025-03-19 22:51:37 +07:00
2025-03-21 10:06:33 +07:00
// Кнопка выхода из режима администратора или суперпользователя (текст зависит от роли)
2025-03-21 09:56:56 +07:00
buttons . Add ( new [ ] {
2025-03-21 10:06:33 +07:00
InlineKeyboardButton . WithCallbackData (
isSuperAdmin ? "🚪 Выйти из режима суперпользователя" : "🚪 Выйти из режима администратора" ,
"leave_admin" )
2025-03-21 09:56:56 +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-21 09:56:56 +07:00
string roleName = isSuperAdmin ? "суперпользователя" : "администратора" ;
2025-03-19 20:37:51 +07:00
await botClient . SendMessage (
chatId : chatId ,
2025-03-21 09:56:56 +07:00
text : $"⚙️ <b>Настройки {roleName}</b>\n\n" +
$"Ваша роль: {(isSuperAdmin ? " 👑 С у п е р п о л ь з о в а т е л ь " : " 👤 А д м и н и с т р а т о р ")}\n" +
$"Уведомления о просрочках: {notificationStatus}\n\n" +
$"Выберите действие:" ,
2025-03-19 20:37:51 +07:00
parseMode : ParseMode . Html ,
replyMarkup : keyboard
) ;
}
catch ( Exception ex )
{
2025-03-21 09:56:56 +07:00
Log . Error ( $"Ошибка при отображении настроек администратора: {ex.Message}" ) ;
2025-03-19 20:37:51 +07:00
}
}
2025-03-19 16:14:02 +07:00
2025-03-19 16:34:48 +07:00
2025-03-21 09:56:56 +07:00
2025-03-20 12:06:45 +07:00
private static async Task ToggleAdminNotifications ( long adminId , bool enable )
{
try
{
using ( var connection = new SqliteConnection ( "Data Source=bot.db" ) )
{
await connection . OpenAsync ( ) ;
var command = connection . CreateCommand ( ) ;
command . CommandText = "UPDATE Admins SET NotifyOnPendingReports = @notify WHERE ChatId = @chatId" ;
command . Parameters . AddWithValue ( "@notify" , enable ? 1 : 0 ) ;
command . Parameters . AddWithValue ( "@chatId" , adminId ) ;
await command . ExecuteNonQueryAsync ( ) ;
Log . Information ( $"Уведомления для администратора {adminId} {(enable ? " в к л ю ч е н ы " : " о т к л ю ч е н ы ")}" ) ;
}
}
catch ( Exception ex )
{
Log . Error ( $"Ошибка при переключении уведомлений для администратора {adminId}: {ex.Message}" ) ;
}
}
2025-03-20 12:11:21 +07:00
2025-03-19 23:43:30 +07:00
private static async Task NotifyAdminsAboutWorkAssignment ( long reportId , long changerId )
{
try
{
// Получаем данные о заявке
string description = "" ;
string priority = "" ;
string room = "" ;
2025-03-20 09:50:04 +07:00
string changerFullName = adminFullNames [ changerId ] ;
2025-03-19 23:43:30 +07:00
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 priorityEmoji = GetPriorityEmoji ( priority ) ;
var keyboard = new InlineKeyboardMarkup ( new [ ]
{
new [ ]
{
InlineKeyboardButton . WithCallbackData ( "📝 Посмотреть детали" , $"report_{reportId}" )
}
} ) ;
await _botClient . SendMessage (
chatId : adminId ,
2025-03-20 09:50:04 +07:00
text : $"{priorityEmoji} <b>Заявка #{reportId} взята в работу администратором {changerFullName}</b>\n\n" +
2025-03-19 23:43:30 +07:00
$"<b>Приоритет:</b> {priority}\n" +
$"<b>Кабинет:</b> {room}\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}" ) ;
}
}
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
{
2025-03-21 09:39:31 +07:00
if ( ! admins . Contains ( changerId ) )
{
Log . Warning ( $"Попытка изменения статуса пользователем без прав администратора: {changerId}" ) ;
return ; // Прерываем выполнение, если пользователь не администратор
}
2025-03-19 20:19:46 +07:00
string oldStatus = "" ;
2025-03-19 23:37:05 +07:00
long userChatId = 0 ;
2025-03-19 20:19:46 +07:00
2025-03-19 23:37:05 +07:00
// Сначала получаем текущий статус и chatId пользователя
2025-03-19 20:19:46 +07:00
using ( var connection = new SqliteConnection ( "Data Source=bot.db" ) )
{
await connection . OpenAsync ( ) ;
var getStatusCommand = connection . CreateCommand ( ) ;
2025-03-19 23:37:05 +07:00
getStatusCommand . CommandText = "SELECT Status, ChatId FROM Reports WHERE Id = @id" ;
2025-03-19 20:19:46 +07:00
getStatusCommand . Parameters . AddWithValue ( "@id" , reportId ) ;
2025-03-19 23:37:05 +07:00
using ( var reader = await getStatusCommand . ExecuteReaderAsync ( ) )
{
if ( await reader . ReadAsync ( ) )
{
oldStatus = reader . GetString ( 0 ) ;
userChatId = reader . GetInt64 ( 1 ) ;
}
}
2025-03-19 20:19:46 +07:00
}
// Если статус не изменился, прерываем выполнение
if ( oldStatus = = newStatus ) return ;
2025-03-20 09:50:04 +07:00
// Обновляем статус и сохраняем ID администратора
2025-03-19 20:19:46 +07:00
using ( var connection = new SqliteConnection ( "Data Source=bot.db" ) )
{
await connection . OpenAsync ( ) ;
var command = connection . CreateCommand ( ) ;
2025-03-20 09:50:04 +07:00
command . CommandText = "UPDATE Reports SET Status = @status, AdminId = @adminId WHERE Id = @id" ;
2025-03-19 20:19:46 +07:00
command . Parameters . AddWithValue ( "@status" , newStatus ) ;
2025-03-20 09:50:04 +07:00
command . Parameters . AddWithValue ( "@adminId" , changerId ) ;
2025-03-19 20:19:46 +07:00
command . Parameters . AddWithValue ( "@id" , reportId ) ;
await command . ExecuteNonQueryAsync ( ) ;
// Уведомляем администраторов о б изменении статуса
await NotifyAdminsAboutStatusChange ( reportId , newStatus , oldStatus , changerId ) ;
2025-03-19 23:37:05 +07:00
// Уведомляем пользователя о б изменении статуса
await NotifyUserAboutStatusChange ( userChatId , reportId , newStatus ) ;
2025-03-19 23:43:30 +07:00
// Уведомляем администраторов, если заявка взята в работу
if ( newStatus = = "в работе" )
{
await NotifyAdminsAboutWorkAssignment ( reportId , changerId ) ;
}
2025-03-20 11:52:14 +07:00
// Перезапускаем мониторинг, если статус изменился обратно на "ожидает"
if ( newStatus = = "ожидает" )
{
var cts = new CancellationTokenSource ( ) ;
_ = Task . Run ( ( ) = > MonitorReportStatus ( reportId , cts . Token ) ) ;
}
2025-03-19 20:19:46 +07:00
}
}
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 23:37:05 +07:00
2025-03-19 23:43:30 +07:00
2025-03-20 09:50:04 +07:00
2025-03-20 11:52:14 +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-20 11:44:58 +07:00
// Запускаем мониторинг статуса заявки
var cts = new CancellationTokenSource ( ) ;
_ = Task . Run ( ( ) = > MonitorReportStatus ( reportId , cts . Token ) ) ;
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-20 11:44:58 +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-20 10:05:28 +07:00
var requiredColumns = new HashSet < string > { "Id" , "ChatId" , "Priority" , "Room" , "Description" , "ReporterName" , "DateCreated" , "Status" , "AdminId" } ;
2025-03-19 19:31:45 +07:00
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 ;
2025-03-20 10:05:28 +07:00
case "AdminId" :
alterTableCommand . CommandText = "ALTER TABLE Reports ADD COLUMN AdminId INTEGER DEFAULT 0;" ;
break ;
2025-03-19 19:31:45 +07:00
}
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-20 10:05:28 +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 ' о ж и д а е т ' ,
AdminId INTEGER DEFAULT 0
) ;
";
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: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 = @ "
2025-03-21 09:56:56 +07:00
CREATE TABLE IF NOT EXISTS Admins (
Id INTEGER PRIMARY KEY AUTOINCREMENT ,
ChatId INTEGER NOT NULL UNIQUE ,
FullName TEXT NOT NULL ,
NotifyOnPendingReports INTEGER NOT NULL DEFAULT 1 ,
IsSuperAdmin INTEGER NOT NULL DEFAULT 0
) ; ";
2025-03-19 20:19:46 +07:00
await command . ExecuteNonQueryAsync ( ) ;
Log . Information ( "Таблица Admins успешно создана (если её не было)." ) ;
2025-03-20 09:56:06 +07:00
2025-03-20 12:06:45 +07:00
// Проверяем наличие столбца NotifyOnPendingReports
2025-03-20 09:56:06 +07:00
command . CommandText = "PRAGMA table_info(Admins);" ;
var tableInfo = await command . ExecuteReaderAsync ( ) ;
2025-03-20 12:06:45 +07:00
bool notifyColumnExists = false ;
2025-03-21 09:56:56 +07:00
bool superAdminColumnExists = false ;
2025-03-20 09:56:06 +07:00
while ( await tableInfo . ReadAsync ( ) )
{
2025-03-20 12:06:45 +07:00
if ( tableInfo [ "name" ] . ToString ( ) = = "NotifyOnPendingReports" )
2025-03-20 09:56:06 +07:00
{
2025-03-20 12:06:45 +07:00
notifyColumnExists = true ;
2025-03-21 09:56:56 +07:00
}
if ( tableInfo [ "name" ] . ToString ( ) = = "IsSuperAdmin" )
{
superAdminColumnExists = true ;
2025-03-20 09:56:06 +07:00
}
}
2025-03-20 09:58:07 +07:00
await tableInfo . CloseAsync ( ) ; // Закрываем DataReader перед изменением CommandText
2025-03-20 12:06:45 +07:00
if ( ! notifyColumnExists )
2025-03-20 09:56:06 +07:00
{
2025-03-20 12:06:45 +07:00
command . CommandText = "ALTER TABLE Admins ADD COLUMN NotifyOnPendingReports INTEGER NOT NULL DEFAULT 1;" ;
2025-03-20 09:56:06 +07:00
await command . ExecuteNonQueryAsync ( ) ;
2025-03-20 12:06:45 +07:00
Log . Information ( "Столбец NotifyOnPendingReports добавлен в таблицу Admins." ) ;
2025-03-20 09:56:06 +07:00
}
2025-03-21 09:56:56 +07:00
// Добавляем столбец IsSuperAdmin, если е г о нет
if ( ! superAdminColumnExists )
{
command . CommandText = "ALTER TABLE Admins ADD COLUMN IsSuperAdmin INTEGER NOT NULL DEFAULT 0;" ;
await command . ExecuteNonQueryAsync ( ) ;
Log . Information ( "Столбец IsSuperAdmin добавлен в таблицу Admins." ) ;
}
2025-03-19 20:19:46 +07:00
}
}
catch ( Exception ex )
{
Log . Error ( $"Ошибка при создании таблицы Admins: {ex.Message}" ) ;
}
}
2025-03-20 09:50:04 +07:00
2025-03-20 09:56:06 +07:00
2025-03-20 09:58:07 +07:00
2025-03-20 12:06:45 +07:00
2025-03-21 09:56:56 +07:00
2025-03-19 20:19:46 +07:00
// Метод для сохранения администратора в базу данных
2025-03-20 09:50:04 +07:00
private static async Task SaveAdminToDatabase ( long chatId , string fullName )
2025-03-19 20:19:46 +07:00
{
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 )
{
2025-03-21 09:56:56 +07:00
// Добавляем нового админа (явно указываем IsSuperAdmin = 0)
2025-03-19 20:19:46 +07:00
var insertCommand = connection . CreateCommand ( ) ;
2025-03-21 09:56:56 +07:00
insertCommand . CommandText = "INSERT INTO Admins (ChatId, FullName, IsSuperAdmin) VALUES (@chatId, @fullName, 0)" ;
2025-03-19 20:19:46 +07:00
insertCommand . Parameters . AddWithValue ( "@chatId" , chatId ) ;
2025-03-20 09:50:04 +07:00
insertCommand . Parameters . AddWithValue ( "@fullName" , fullName ) ;
2025-03-19 20:19:46 +07:00
await insertCommand . ExecuteNonQueryAsync ( ) ;
Log . Information ( $"Администратор {chatId} добавлен в базу данных" ) ;
}
2025-03-21 09:56:56 +07:00
else
{
// Обновляем данные, если пользователь уже существует
var updateCommand = connection . CreateCommand ( ) ;
updateCommand . CommandText = "UPDATE Admins SET FullName = @fullName WHERE ChatId = @chatId" ;
updateCommand . Parameters . AddWithValue ( "@chatId" , chatId ) ;
updateCommand . Parameters . AddWithValue ( "@fullName" , fullName ) ;
await updateCommand . ExecuteNonQueryAsync ( ) ;
Log . Information ( $"Данные администратора {chatId} обновлены" ) ;
}
2025-03-19 20:19:46 +07:00
}
}
catch ( Exception ex )
{
Log . Error ( $"Ошибка при сохранении администратора в базу данных: {ex.Message}" ) ;
}
}
2025-03-21 09:56:56 +07:00
2025-03-19 20:19:46 +07:00
// Метод для загрузки администраторов из базы данных
private static async Task LoadAdminsFromDatabase ( )
{
try
{
using ( var connection = new SqliteConnection ( "Data Source=bot.db" ) )
{
await connection . OpenAsync ( ) ;
var command = connection . CreateCommand ( ) ;
2025-03-21 09:56:56 +07:00
command . CommandText = "SELECT ChatId, FullName, IsSuperAdmin FROM Admins" ;
2025-03-19 20:19:46 +07:00
using ( var reader = await command . ExecuteReaderAsync ( ) )
{
while ( await reader . ReadAsync ( ) )
{
long adminId = reader . GetInt64 ( 0 ) ;
2025-03-20 09:50:04 +07:00
string fullName = reader . GetString ( 1 ) ;
2025-03-21 09:56:56 +07:00
bool isSuperAdmin = reader . GetInt32 ( 2 ) = = 1 ;
2025-03-19 20:19:46 +07:00
admins . Add ( adminId ) ;
2025-03-20 09:50:04 +07:00
adminFullNames [ adminId ] = fullName ;
2025-03-21 09:56:56 +07:00
// Добавляем в список суперпользователей, если это суперадмин
if ( isSuperAdmin )
{
superAdmins . Add ( adminId ) ;
}
Log . Information ( $"Загружен {(isSuperAdmin ? " с у п е р п о л ь з о в а т е л ь " : " а д м и н и с т р а т о р ")} с ID: {adminId}, ФИО: {fullName}" ) ;
2025-03-19 20:19:46 +07:00
}
}
}
2025-03-21 09:56:56 +07:00
Log . Information ( $"Загружено {admins.Count} администраторов из базы данных, из них {superAdmins.Count} суперпользователей" ) ;
2025-03-19 20:19:46 +07:00
}
catch ( Exception ex )
{
Log . Error ( $"Ошибка при загрузке администраторов из базы данных: {ex.Message}" ) ;
}
}
2025-03-21 09:56:56 +07:00
private static async Task SaveSuperAdminToDatabase ( long chatId , string fullName )
{
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, FullName, IsSuperAdmin) VALUES (@chatId, @fullName, 1)" ;
insertCommand . Parameters . AddWithValue ( "@chatId" , chatId ) ;
insertCommand . Parameters . AddWithValue ( "@fullName" , fullName ) ;
await insertCommand . ExecuteNonQueryAsync ( ) ;
Log . Information ( $"Суперпользователь {chatId} добавлен в базу данных" ) ;
}
else
{
// Обновляем существующего пользователя до суперадмина
var updateCommand = connection . CreateCommand ( ) ;
updateCommand . CommandText = "UPDATE Admins SET IsSuperAdmin = 1, FullName = @fullName WHERE ChatId = @chatId" ;
updateCommand . Parameters . AddWithValue ( "@chatId" , chatId ) ;
updateCommand . Parameters . AddWithValue ( "@fullName" , fullName ) ;
await updateCommand . ExecuteNonQueryAsync ( ) ;
Log . Information ( $"Пользователь {chatId} повышен до суперпользователя" ) ;
}
}
}
catch ( Exception ex )
{
Log . Error ( $"Ошибка при сохранении суперпользователя в базу данных: {ex.Message}" ) ;
}
}
private static async Task RemoveSelfFromAdmins ( 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 ) ;
superAdmins . Remove ( chatId ) ;
if ( adminFullNames . ContainsKey ( chatId ) )
{
adminFullNames . 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 , bool isSuperAdmin ) > ( ) ;
using ( var connection = new SqliteConnection ( "Data Source=bot.db" ) )
{
await connection . OpenAsync ( ) ;
var command = connection . CreateCommand ( ) ;
command . CommandText = "SELECT ChatId, FullName, IsSuperAdmin FROM Admins" ;
using ( var reader = await command . ExecuteReaderAsync ( ) )
{
while ( await reader . ReadAsync ( ) )
{
long adminId = reader . GetInt64 ( 0 ) ;
string fullName = reader . GetString ( 1 ) ;
bool isSuperAdmin = reader . GetInt32 ( 2 ) = = 1 ;
adminsList . Add ( ( adminId , fullName , isSuperAdmin ) ) ;
}
}
}
// Формируем сообщение
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" ) ;
bool isSuperUser = superAdmins . Contains ( chatId ) ;
for ( int i = 0 ; i < adminsList . Count ; i + + )
{
var ( adminId , username , adminIsSuperAdmin ) = adminsList [ i ] ;
string role = adminIsSuperAdmin ? "👑 Суперпользователь" : "👤 Администратор" ;
messageText . AppendLine ( $"{i + 1}. {username} (ID: {adminId}) - {role}" ) ;
// Кнопка удаления доступна только суперпользователям и только для других администраторов
if ( isSuperUser & & adminId ! = chatId )
{
buttons . Add ( new [ ] {
InlineKeyboardButton . WithCallbackData ( $"❌ Удалить {username}" , $"removeadmin_{adminId}" )
} ) ;
}
}
2025-03-21 10:06:33 +07:00
// Кнопка "Назад" всегда доступна
2025-03-21 09:56:56 +07:00
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 20:19:46 +07:00
// Метод для уведомления администраторов о новой заявке
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
}