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 18:26:38 +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 18:26:38 +07:00
|
|
|
|
|
2025-03-12 22:41:14 +07:00
|
|
|
|
_botClient = new TelegramBotClient(_botToken);
|
2025-03-19 18:26:38 +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 18:26:38 +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-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();
|
|
|
|
|
await botClient.SendMessage(chatId, "Пожалуйста, укажите приоритет (низкий, средний, высокий).");
|
2025-03-19 19:03:49 +07:00
|
|
|
|
Log.Information($"Пользователь {chatId} начал создание заявки");
|
2025-03-19 15:54:05 +07:00
|
|
|
|
}
|
2025-03-19 19:03:49 +07:00
|
|
|
|
else if (data == "admin_panel")
|
2025-03-19 17:59:32 +07:00
|
|
|
|
{
|
2025-03-19 19:03:49 +07:00
|
|
|
|
if (admins.Contains(chatId))
|
2025-03-19 17:59:32 +07:00
|
|
|
|
{
|
2025-03-19 19:03:49 +07:00
|
|
|
|
await SendAdminPanel(botClient, chatId);
|
2025-03-19 17:59:32 +07:00
|
|
|
|
}
|
2025-03-19 19:03:49 +07:00
|
|
|
|
else
|
2025-03-19 17:59:32 +07:00
|
|
|
|
{
|
2025-03-19 19:03:49 +07:00
|
|
|
|
var keyboard = new InlineKeyboardMarkup(new[]
|
2025-03-19 17:59:32 +07:00
|
|
|
|
{
|
|
|
|
|
new[]
|
|
|
|
|
{
|
|
|
|
|
InlineKeyboardButton.WithCallbackData("Главное меню", "main_menu")
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
2025-03-19 19:03:49 +07:00
|
|
|
|
await botClient.SendMessage(chatId, "⛔ Вы не являетесь администратором!", replyMarkup: keyboard);
|
|
|
|
|
Log.Information($"Неавторизованный доступ к админ-панели от {chatId}");
|
2025-03-19 15:54:05 +07:00
|
|
|
|
}
|
2025-03-19 19:03:49 +07:00
|
|
|
|
}
|
|
|
|
|
else if (data == "view_reports")
|
|
|
|
|
{
|
|
|
|
|
if (admins.Contains(chatId))
|
2025-03-19 15:54:05 +07:00
|
|
|
|
{
|
2025-03-19 19:03:49 +07:00
|
|
|
|
await ViewReports(botClient, chatId);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
var keyboard = new InlineKeyboardMarkup(new[]
|
2025-03-19 19:00:55 +07:00
|
|
|
|
{
|
2025-03-19 16:42:16 +07:00
|
|
|
|
new[]
|
|
|
|
|
{
|
|
|
|
|
InlineKeyboardButton.WithCallbackData("Главное меню", "main_menu")
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
2025-03-19 19:03:49 +07:00
|
|
|
|
await botClient.SendMessage(chatId, "⛔ Вы не являетесь администратором!", replyMarkup: keyboard);
|
|
|
|
|
Log.Information($"Неавторизованный доступ к заявкам от {chatId}");
|
2025-03-19 17:59:32 +07:00
|
|
|
|
}
|
2025-03-19 19:03:49 +07:00
|
|
|
|
}
|
|
|
|
|
else if (data == "view_archived_reports")
|
|
|
|
|
{
|
|
|
|
|
if (admins.Contains(chatId))
|
2025-03-19 17:59:32 +07:00
|
|
|
|
{
|
2025-03-19 19:03:49 +07:00
|
|
|
|
await ViewArchivedReports(botClient, chatId);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
var keyboard = new InlineKeyboardMarkup(new[]
|
2025-03-19 19:00:55 +07:00
|
|
|
|
{
|
2025-03-19 17:59:32 +07:00
|
|
|
|
new[]
|
|
|
|
|
{
|
|
|
|
|
InlineKeyboardButton.WithCallbackData("Главное меню", "main_menu")
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
2025-03-19 19:03:49 +07:00
|
|
|
|
await botClient.SendMessage(chatId, "⛔ Вы не являетесь администратором!", replyMarkup: keyboard);
|
|
|
|
|
Log.Information($"Неавторизованный доступ к архиву заявок от {chatId}");
|
2025-03-19 19:00:55 +07:00
|
|
|
|
}
|
2025-03-19 19:03:49 +07:00
|
|
|
|
}
|
|
|
|
|
else if (data != null && data.StartsWith("report_"))
|
|
|
|
|
{
|
|
|
|
|
long reportId = long.Parse(data.Substring(7));
|
|
|
|
|
if (callbackQuery?.Message?.MessageId != null)
|
2025-03-19 19:00:55 +07:00
|
|
|
|
{
|
2025-03-19 19:03:49 +07:00
|
|
|
|
int messageId = callbackQuery.Message.MessageId;
|
|
|
|
|
await ShowReportDetails(botClient, chatId, reportId, messageId);
|
2025-03-19 19:00:55 +07:00
|
|
|
|
}
|
2025-03-19 19:03:49 +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 19:00:55 +07:00
|
|
|
|
{
|
2025-03-19 19:03:49 +07:00
|
|
|
|
int messageId = callbackQuery.Message.MessageId;
|
|
|
|
|
await UpdateReportStatus(reportId, newStatus);
|
|
|
|
|
await ShowReportDetails(botClient, chatId, reportId, messageId);
|
2025-03-19 16:30:42 +07:00
|
|
|
|
}
|
2025-03-19 14:14:02 +07:00
|
|
|
|
}
|
2025-03-19 19:03:49 +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 == "main_menu")
|
|
|
|
|
{
|
|
|
|
|
await SendMainMenu(botClient, chatId);
|
|
|
|
|
}
|
2025-03-19 14:14:02 +07:00
|
|
|
|
}
|
2025-03-19 19:03:49 +07:00
|
|
|
|
}
|
2025-03-19 14:14:02 +07:00
|
|
|
|
|
2025-03-19 19:03:49 +07:00
|
|
|
|
// Обработка текстовых сообщений
|
|
|
|
|
if (update.Type == UpdateType.Message && update.Message?.Text != null)
|
|
|
|
|
{
|
|
|
|
|
var message = update.Message;
|
|
|
|
|
Log.Information($"Получено сообщение от {message.Chat.Id}: {message.Text}");
|
2025-03-19 19:00:55 +07:00
|
|
|
|
|
2025-03-19 19:03:49 +07:00
|
|
|
|
// Обработка команды /admin для авторизации
|
|
|
|
|
if (message.Text.StartsWith("/admin"))
|
|
|
|
|
{
|
|
|
|
|
string[] parts = message.Text.Split(' ');
|
|
|
|
|
if (parts.Length == 2 && parts[1] == adminPassword)
|
2025-03-19 16:38:09 +07:00
|
|
|
|
{
|
2025-03-19 19:03:49 +07:00
|
|
|
|
admins.Add(message.Chat.Id);
|
|
|
|
|
var keyboard = new InlineKeyboardMarkup(new[]
|
2025-03-19 16:42:16 +07:00
|
|
|
|
{
|
|
|
|
|
new[]
|
|
|
|
|
{
|
|
|
|
|
InlineKeyboardButton.WithCallbackData("Главное меню", "main_menu")
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
2025-03-19 19:03:49 +07:00
|
|
|
|
await botClient.SendMessage(message.Chat.Id, "✅ Вы авторизованы как администратор!", replyMarkup: keyboard);
|
|
|
|
|
Log.Information($"Новый администратор: {message.Chat.Id}");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
var keyboard = new InlineKeyboardMarkup(new[]
|
2025-03-19 16:42:16 +07:00
|
|
|
|
{
|
|
|
|
|
new[]
|
|
|
|
|
{
|
|
|
|
|
InlineKeyboardButton.WithCallbackData("Главное меню", "main_menu")
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
2025-03-19 19:03:49 +07:00
|
|
|
|
await botClient.SendMessage(message.Chat.Id, "❌ Неверный пароль!", replyMarkup: keyboard);
|
2025-03-19 16:38:09 +07:00
|
|
|
|
}
|
2025-03-19 19:03:49 +07:00
|
|
|
|
return;
|
|
|
|
|
}
|
2025-03-19 14:14:02 +07:00
|
|
|
|
|
2025-03-19 19:03:49 +07:00
|
|
|
|
if (message.Text == "/start")
|
|
|
|
|
{
|
|
|
|
|
var keyboard = new InlineKeyboardMarkup(new[]
|
2025-03-19 16:38:09 +07:00
|
|
|
|
{
|
|
|
|
|
new[]
|
|
|
|
|
{
|
|
|
|
|
InlineKeyboardButton.WithCallbackData("Подать заявку", "report"),
|
2025-03-19 17:59:32 +07:00
|
|
|
|
InlineKeyboardButton.WithCallbackData("Панель администратора", "admin_panel")
|
2025-03-19 16:38:09 +07:00
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
2025-03-19 19:03:49 +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)
|
|
|
|
|
{
|
2025-03-19 19:20:14 +07:00
|
|
|
|
if (userReportSteps.TryGetValue(message.Chat.Id, out int step))
|
2025-03-19 16:38:09 +07:00
|
|
|
|
{
|
2025-03-19 19:20:14 +07:00
|
|
|
|
switch (step)
|
|
|
|
|
{
|
|
|
|
|
case 1:
|
|
|
|
|
userReports[message.Chat.Id].Priority = message.Text;
|
|
|
|
|
userReportSteps[message.Chat.Id] = 2;
|
|
|
|
|
await botClient.SendMessage(message.Chat.Id, "Пожалуйста, укажите кабинет.");
|
|
|
|
|
break;
|
|
|
|
|
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]);
|
|
|
|
|
await botClient.SendMessage(
|
|
|
|
|
message.Chat.Id,
|
|
|
|
|
"✅ Спасибо за заявку! Мы обработаем её в ближайшее время."
|
|
|
|
|
);
|
|
|
|
|
usersWaitingForReport[message.Chat.Id] = false;
|
|
|
|
|
userReportSteps.Remove(message.Chat.Id);
|
|
|
|
|
userReports.Remove(message.Chat.Id);
|
|
|
|
|
Log.Information($"Заявка пользователя {message.Chat.Id} сохранена в базе данных.");
|
|
|
|
|
break;
|
|
|
|
|
}
|
2025-03-19 16:38:09 +07:00
|
|
|
|
}
|
2025-03-19 19:03:49 +07:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2025-03-19 19:20:14 +07:00
|
|
|
|
await botClient.SendMessage(message.Chat.Id, "ℹ️ Используйте команду /start для начала работы с ботом.");
|
2025-03-19 16:30:42 +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[]
|
|
|
|
|
{
|
|
|
|
|
InlineKeyboardButton.WithCallbackData("Подать заявку", "report"),
|
|
|
|
|
InlineKeyboardButton.WithCallbackData("Панель администратора", "admin_panel")
|
|
|
|
|
}
|
|
|
|
|
});
|
2025-03-19 15:27:07 +07:00
|
|
|
|
|
|
|
|
|
await botClient.SendMessage(
|
|
|
|
|
chatId: chatId,
|
|
|
|
|
text: "Главное меню:",
|
|
|
|
|
replyMarkup: keyboard
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-19 17:59:32 +07:00
|
|
|
|
private static async Task SendAdminPanel(ITelegramBotClient botClient, long chatId)
|
|
|
|
|
{
|
|
|
|
|
var keyboard = new InlineKeyboardMarkup(new[]
|
|
|
|
|
{
|
|
|
|
|
new[]
|
|
|
|
|
{
|
|
|
|
|
InlineKeyboardButton.WithCallbackData("Менеджер заявок", "view_reports"),
|
|
|
|
|
InlineKeyboardButton.WithCallbackData("Архив заявок", "view_archived_reports")
|
|
|
|
|
},
|
|
|
|
|
new[]
|
|
|
|
|
{
|
|
|
|
|
InlineKeyboardButton.WithCallbackData("Главное меню", "main_menu")
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
await botClient.SendMessage(
|
|
|
|
|
chatId: chatId,
|
2025-03-19 18:26:38 +07:00
|
|
|
|
text: "Панель администраторов:",
|
2025-03-19 17:59:32 +07:00
|
|
|
|
replyMarkup: keyboard
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
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 18:26:38 +07:00
|
|
|
|
command.CommandText = "SELECT Id, Description, Status FROM Reports WHERE Status != 'закрыта'";
|
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);
|
|
|
|
|
|
|
|
|
|
buttons.Add(new[]
|
|
|
|
|
{
|
2025-03-19 19:00:55 +07:00
|
|
|
|
InlineKeyboardButton.WithCallbackData(
|
|
|
|
|
$"#{id} - {status} - {description}...",
|
|
|
|
|
$"report_{id}")
|
|
|
|
|
});
|
2025-03-19 15:27:07 +07:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Добавляем кнопки навигации
|
|
|
|
|
buttons.Add(new[]
|
|
|
|
|
{
|
2025-03-19 19:00:55 +07:00
|
|
|
|
InlineKeyboardButton.WithCallbackData("Главное меню", "main_menu")
|
|
|
|
|
});
|
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 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 18:26:38 +07:00
|
|
|
|
command.CommandText = "SELECT Id, Description, Status FROM Reports WHERE Status = 'закрыта'";
|
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);
|
|
|
|
|
|
|
|
|
|
buttons.Add(new[]
|
|
|
|
|
{
|
|
|
|
|
InlineKeyboardButton.WithCallbackData(
|
|
|
|
|
$"#{id} - {status} - {description}...",
|
|
|
|
|
$"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-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();
|
|
|
|
|
command.CommandText = "SELECT Description, Status FROM Reports WHERE Id = @id";
|
|
|
|
|
command.Parameters.AddWithValue("@id", reportId);
|
|
|
|
|
|
|
|
|
|
using (var reader = await command.ExecuteReaderAsync())
|
|
|
|
|
{
|
|
|
|
|
if (await reader.ReadAsync())
|
|
|
|
|
{
|
|
|
|
|
string description = reader.GetString(0);
|
|
|
|
|
string status = reader.GetString(1);
|
|
|
|
|
|
|
|
|
|
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 16:14:02 +07:00
|
|
|
|
string newText = $"Заявка #{reportId}\n\nОписание: {description}\nСтатус: {status}";
|
|
|
|
|
|
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 16:14:02 +07:00
|
|
|
|
|
|
|
|
|
|
2025-03-19 16:34:48 +07:00
|
|
|
|
|
2025-03-19 15:27:07 +07:00
|
|
|
|
private static async Task UpdateReportStatus(long reportId, string newStatus)
|
2025-03-19 17:59:32 +07:00
|
|
|
|
{
|
|
|
|
|
try
|
2025-03-19 15:27:07 +07:00
|
|
|
|
{
|
2025-03-19 17:59:32 +07:00
|
|
|
|
using (var connection = new SqliteConnection("Data Source=bot.db"))
|
2025-03-19 15:27:07 +07:00
|
|
|
|
{
|
2025-03-19 17:59:32 +07:00
|
|
|
|
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();
|
2025-03-19 15:27:07 +07:00
|
|
|
|
}
|
|
|
|
|
}
|
2025-03-19 17:59:32 +07:00
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
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-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
|
|
|
|
|
|
|
|
|
await insertCommand.ExecuteNonQueryAsync();
|
|
|
|
|
Log.Information($"Заявка от пользователя {chatId} успешно сохранена.");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
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-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();
|
|
|
|
|
|
|
|
|
|
bool priorityColumnExists = false;
|
|
|
|
|
|
|
|
|
|
while (await tableInfo.ReadAsync())
|
|
|
|
|
{
|
|
|
|
|
if (tableInfo["name"].ToString() == "Priority")
|
|
|
|
|
{
|
|
|
|
|
priorityColumnExists = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!priorityColumnExists)
|
|
|
|
|
{
|
|
|
|
|
// Добавляем столбец Priority, если его нет
|
|
|
|
|
var alterTableCommand = connection.CreateCommand();
|
|
|
|
|
alterTableCommand.CommandText = "ALTER TABLE Reports ADD COLUMN Priority TEXT NOT NULL DEFAULT 'низкий';";
|
|
|
|
|
await alterTableCommand.ExecuteNonQueryAsync();
|
|
|
|
|
Log.Information("Столбец Priority добавлен в таблицу 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-17 15:07:41 +07:00
|
|
|
|
await createTableCommand.ExecuteNonQueryAsync();
|
|
|
|
|
|
|
|
|
|
Log.Information("Таблица Reports успешно создана (если её не было).");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
Log.Error($"Ошибка при создании таблицы в базе данных: {ex.Message}");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-19 19:22:29 +07:00
|
|
|
|
|
2025-03-19 19:29:40 +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-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 13:56:21 +07:00
|
|
|
|
}
|