Refactor messaging system to utilize LiteCqrs library
- Replaced instances of the previous messaging system with LiteCqrs across various application components, enhancing the CQRS implementation. - Updated dependency injection to register LiteCqrs services and behaviors, streamlining command and query handling. - Adjusted multiple command and query handlers to align with the new messaging framework, ensuring consistent functionality and improved maintainability. - Added LiteCqrs package reference in the project file for better dependency management.
This commit is contained in:
@@ -7,7 +7,10 @@
|
||||
**PnvPanel** — self-service портал для VPN-конфигураций (VLESS/VMess/Trojan/Shadowsocks): пользователи
|
||||
сами создают конфиги, админ управляет серверами и пользователями. Есть **Telegram-бот** (ссылка на
|
||||
сайт, просмотр конфигов, passwordless-вход). Бэкенд оркестрирует панели **3x-ui** через
|
||||
[`ThreeXui.Net`](https://github.com/mrleo1nid/ThreeXui.Net) и хранит проекцию домена в PostgreSQL.
|
||||
[`ThreeXui.Net`](https://github.com/mrleo1nid/ThreeXui.Net), CQRS — через собственную библиотеку
|
||||
[`LiteCqrs.Net`](https://github.com/mrleo1nid/LiteCqrs.Net) (на время разработки подключена как
|
||||
`ProjectReference` из соседнего репозитория `D:\Github\LiteCqrs.Net`, ещё не опубликована в
|
||||
NuGet/GitHub), и хранит проекцию домена в PostgreSQL.
|
||||
Живые обновления — SignalR. Поставка — **единый Docker-образ** (фронт+бек+бот) + PostgreSQL в compose.
|
||||
|
||||
> Собрано и покрыто тестами, единый образ и compose-стек проверены живьём. Есть опциональный биллинг
|
||||
@@ -25,8 +28,10 @@
|
||||
|
||||
## Стек
|
||||
|
||||
- **Backend**: C# / .NET 10, ASP.NET Core Web API, Clean Architecture, CQRS (**собственный тонкий
|
||||
диспетчер**, без MediatR), EF Core 10 + Npgsql, ASP.NET Core Identity + JWT, SignalR, FluentValidation,
|
||||
- **Backend**: C# / .NET 10, ASP.NET Core Web API, Clean Architecture, CQRS (через
|
||||
[`LiteCqrs.Net`](https://github.com/mrleo1nid/LiteCqrs.Net) — собственная лёгкая
|
||||
CQRS-библиотека, альтернатива MediatR с явным разделением Command/Query), EF Core 10 + Npgsql,
|
||||
ASP.NET Core Identity + JWT, SignalR, FluentValidation,
|
||||
Serilog. Маппинг DTO вручную (`FromDomain(...)`, без Mapster). OpenAPI — нативный
|
||||
`Microsoft.AspNetCore.OpenApi` + Scalar UI (без Swashbuckle).
|
||||
- **Frontend**: React 19 + Vite + TS, TanStack Query/Router, shadcn-стиль поверх Radix + Tailwind v4,
|
||||
@@ -174,8 +179,8 @@ docker compose up -d # api + postgres (+ web)
|
||||
|
||||
## Ключевые решения
|
||||
|
||||
См. [tech-stack.md](docs/tech-stack.md#ключевые-решения-по-домену-и-поведению): CQRS — собственный
|
||||
диспетчер (не MediatR); одна роль на пользователя; секреты нод — ASP.NET Data Protection; биллинг
|
||||
См. [tech-stack.md](docs/tech-stack.md#ключевые-решения-по-домену-и-поведению): CQRS — через
|
||||
LiteCqrs.Net (собственная библиотека, не MediatR); одна роль на пользователя; секреты нод — ASP.NET Data Protection; биллинг
|
||||
опционален per-роль (недоступен для `admin`); i18n — RU+EN (react-i18next); Telegram — long polling,
|
||||
только привязка (не signup); история трафика — простая таблица + TTL; логирование — Serilog.
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
<PackageVersion Include="System.IdentityModel.Tokens.Jwt" Version="8.21.0" />
|
||||
<PackageVersion Include="Telegram.Bot" Version="22.10.2" />
|
||||
<PackageVersion Include="ThreeXui.Net" Version="1.0.4" />
|
||||
<PackageVersion Include="LiteCqrs.Net" Version="1.0.1" />
|
||||
<!-- Тестирование (M8) -->
|
||||
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="18.8.1" />
|
||||
<PackageVersion Include="xunit" Version="2.9.3" />
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using PnvPanel.Api.Common;
|
||||
using PnvPanel.Application.Activation;
|
||||
using PnvPanel.Application.Admin.Activation;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
using PnvPanel.Domain.Activation;
|
||||
using PnvPanel.Infrastructure.Identity;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using PnvPanel.Api.Common;
|
||||
using PnvPanel.Application.Admin.Apps;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Domain.Apps;
|
||||
using PnvPanel.Infrastructure.Identity;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using PnvPanel.Api.Common;
|
||||
using PnvPanel.Application.Admin.Billing;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
using PnvPanel.Domain.Billing;
|
||||
using PnvPanel.Infrastructure.Identity;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using PnvPanel.Api.Common;
|
||||
using PnvPanel.Application.Admin.Instructions;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Instructions;
|
||||
using PnvPanel.Infrastructure.Identity;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using PnvPanel.Api.Common;
|
||||
using PnvPanel.Application.Admin.Maintenance;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
using PnvPanel.Infrastructure.Identity;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using PnvPanel.Api.Common;
|
||||
using PnvPanel.Application.Admin.News;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
using PnvPanel.Application.News;
|
||||
using PnvPanel.Infrastructure.Identity;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using PnvPanel.Api.Common;
|
||||
using PnvPanel.Application.Admin.Plans;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Infrastructure.Identity;
|
||||
|
||||
namespace PnvPanel.Api.Endpoints;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using PnvPanel.Api.Common;
|
||||
using PnvPanel.Application.Admin.Pricing;
|
||||
using PnvPanel.Application.Common.Interfaces;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Infrastructure.Identity;
|
||||
|
||||
namespace PnvPanel.Api.Endpoints;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using PnvPanel.Api.Common;
|
||||
using PnvPanel.Application.Admin.Audit;
|
||||
using PnvPanel.Application.Admin.Stats;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
using PnvPanel.Domain.Audit;
|
||||
using PnvPanel.Infrastructure.Identity;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using PnvPanel.Api.Common;
|
||||
using PnvPanel.Application.Admin.Support;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
using PnvPanel.Application.Support;
|
||||
using PnvPanel.Application.Support.AddComment;
|
||||
|
||||
@@ -2,7 +2,7 @@ using PnvPanel.Api.Common;
|
||||
using PnvPanel.Application.Admin.Configs;
|
||||
using PnvPanel.Application.Admin.Users;
|
||||
using PnvPanel.Application.Common.Interfaces;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
using PnvPanel.Application.Configs;
|
||||
using PnvPanel.Domain.Configs;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using PnvPanel.Api.Common;
|
||||
using PnvPanel.Application.Apps;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Domain.Apps;
|
||||
|
||||
namespace PnvPanel.Api.Endpoints;
|
||||
|
||||
@@ -8,7 +8,7 @@ using PnvPanel.Application.Auth.Logout;
|
||||
using PnvPanel.Application.Auth.Me;
|
||||
using PnvPanel.Application.Auth.Refresh;
|
||||
using PnvPanel.Application.Auth.Register;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
|
||||
namespace PnvPanel.Api.Endpoints;
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ using PnvPanel.Application.Billing.CreatePaymentRequest;
|
||||
using PnvPanel.Application.Billing.GetMyBillingStatus;
|
||||
using PnvPanel.Application.Billing.MarkPaymentSent;
|
||||
using PnvPanel.Application.Billing.SendRequisitesToTelegram;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Domain.Billing;
|
||||
|
||||
namespace PnvPanel.Api.Endpoints;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using PnvPanel.Api.Common;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Configs;
|
||||
using PnvPanel.Application.Configs.Create;
|
||||
using PnvPanel.Application.Configs.Edit;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using PnvPanel.Api.Common;
|
||||
using PnvPanel.Application.Admin.Inbounds;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Infrastructure.Identity;
|
||||
|
||||
namespace PnvPanel.Api.Endpoints;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using PnvPanel.Api.Common;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Instructions;
|
||||
|
||||
namespace PnvPanel.Api.Endpoints;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using PnvPanel.Api.Common;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
using PnvPanel.Application.News;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using PnvPanel.Api.Common;
|
||||
using PnvPanel.Application.Admin.Nodes;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Infrastructure.Identity;
|
||||
|
||||
namespace PnvPanel.Api.Endpoints;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using PnvPanel.Api.Common;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Plans;
|
||||
|
||||
namespace PnvPanel.Api.Endpoints;
|
||||
|
||||
@@ -2,7 +2,7 @@ using PnvPanel.Api.Common;
|
||||
using PnvPanel.Application.Admin.Roles;
|
||||
using PnvPanel.Application.Admin.Users;
|
||||
using PnvPanel.Application.Common.Interfaces;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Infrastructure.Identity;
|
||||
|
||||
namespace PnvPanel.Api.Endpoints;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using System.Text;
|
||||
using PnvPanel.Api.Common;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Subscriptions;
|
||||
|
||||
namespace PnvPanel.Api.Endpoints;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using PnvPanel.Api.Common;
|
||||
using PnvPanel.Application.Common.Interfaces;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
using PnvPanel.Application.Support;
|
||||
using PnvPanel.Application.Support.AddComment;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using PnvPanel.Api.Common;
|
||||
using PnvPanel.Application.Auth;
|
||||
using PnvPanel.Application.Common.Interfaces;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Telegram;
|
||||
using PnvPanel.Domain.Telegram;
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ using PnvPanel.Application.Admin.Support;
|
||||
using PnvPanel.Application.Billing;
|
||||
using PnvPanel.Application.Billing.GetMyBillingStatus;
|
||||
using PnvPanel.Application.Common.Interfaces;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Configs.GetConfigLink;
|
||||
using PnvPanel.Application.Configs.GetMyConfigs;
|
||||
using PnvPanel.Application.Telegram;
|
||||
@@ -354,246 +354,246 @@ public sealed class PnvBotUpdateHandler(
|
||||
switch (parts[0])
|
||||
{
|
||||
case "login":
|
||||
{
|
||||
var result =
|
||||
parts[1] == "approve"
|
||||
? await sender.Send(
|
||||
new ApproveTelegramLoginCommand(requestId, fromId),
|
||||
cancellationToken
|
||||
)
|
||||
: await sender.Send(
|
||||
new RejectTelegramLoginCommand(requestId, fromId),
|
||||
cancellationToken
|
||||
);
|
||||
|
||||
await botClient.AnswerCallbackQuery(
|
||||
callback.Id,
|
||||
result.IsSuccess ? "Готово" : result.Error.Message,
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
if (callback.Message is not null)
|
||||
{
|
||||
var statusText = result.IsSuccess
|
||||
? (parts[1] == "approve" ? "✅ Вход подтверждён." : "❌ Вход отклонён.")
|
||||
: $"⚠️ {result.Error.Message}";
|
||||
var text = $"{Escape(callback.Message.Text ?? "")}\n\n{statusText}";
|
||||
await botClient.EditMessageText(
|
||||
chatId.Value,
|
||||
callback.Message.Id,
|
||||
text,
|
||||
parseMode: ParseMode.Html,
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
}
|
||||
var result =
|
||||
parts[1] == "approve"
|
||||
? await sender.Send(
|
||||
new ApproveTelegramLoginCommand(requestId, fromId),
|
||||
cancellationToken
|
||||
)
|
||||
: await sender.Send(
|
||||
new RejectTelegramLoginCommand(requestId, fromId),
|
||||
cancellationToken
|
||||
);
|
||||
|
||||
break;
|
||||
}
|
||||
case "act":
|
||||
{
|
||||
if (!await TrySetAdminCurrentUserAsync(services, fromId, cancellationToken))
|
||||
{
|
||||
await botClient.AnswerCallbackQuery(
|
||||
callback.Id,
|
||||
"Недостаточно прав.",
|
||||
result.IsSuccess ? "Готово" : result.Error.Message,
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
var result =
|
||||
parts[1] == "approve"
|
||||
? await sender.Send(
|
||||
new ApproveActivationCommand(requestId),
|
||||
cancellationToken
|
||||
)
|
||||
: await sender.Send(
|
||||
new RejectActivationCommand(requestId, Reason: null),
|
||||
cancellationToken
|
||||
if (callback.Message is not null)
|
||||
{
|
||||
var statusText = result.IsSuccess
|
||||
? (parts[1] == "approve" ? "✅ Вход подтверждён." : "❌ Вход отклонён.")
|
||||
: $"⚠️ {result.Error.Message}";
|
||||
var text = $"{Escape(callback.Message.Text ?? "")}\n\n{statusText}";
|
||||
await botClient.EditMessageText(
|
||||
chatId.Value,
|
||||
callback.Message.Id,
|
||||
text,
|
||||
parseMode: ParseMode.Html,
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
}
|
||||
|
||||
await botClient.AnswerCallbackQuery(
|
||||
callback.Id,
|
||||
result.IsSuccess ? "Готово" : result.Error.Message,
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
if (callback.Message is not null)
|
||||
{
|
||||
// Редактируем исходное сообщение с запросом вместо отдельного — иначе кнопки
|
||||
// «Активировать/Отклонить» остаются висеть под уже обработанным запросом (в т.ч.
|
||||
// если его обработали в другом месте — на сайте или из другого чата).
|
||||
var statusText = result.IsSuccess
|
||||
? (
|
||||
parts[1] == "approve"
|
||||
? "✅ Пользователь активирован."
|
||||
: "❌ Запрос отклонён."
|
||||
)
|
||||
: $"⚠️ {result.Error.Message}";
|
||||
var text = $"{Escape(callback.Message.Text ?? "")}\n\n{statusText}";
|
||||
await botClient.EditMessageText(
|
||||
chatId.Value,
|
||||
callback.Message.Id,
|
||||
text,
|
||||
parseMode: ParseMode.Html,
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case "erq":
|
||||
{
|
||||
if (!await TrySetAdminCurrentUserAsync(services, fromId, cancellationToken))
|
||||
{
|
||||
await botClient.AnswerCallbackQuery(
|
||||
callback.Id,
|
||||
"Недостаточно прав.",
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
var result =
|
||||
parts[1] == "approve"
|
||||
? await sender.Send(
|
||||
new ApproveExtensionRequestCommand(requestId),
|
||||
cancellationToken
|
||||
)
|
||||
: await sender.Send(
|
||||
new RejectExtensionRequestCommand(requestId, Reason: null),
|
||||
cancellationToken
|
||||
);
|
||||
|
||||
await botClient.AnswerCallbackQuery(
|
||||
callback.Id,
|
||||
result.IsSuccess ? "Готово" : result.Error.Message,
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
if (callback.Message is not null)
|
||||
{
|
||||
var statusText = result.IsSuccess
|
||||
? (
|
||||
parts[1] == "approve"
|
||||
? "✅ Заявка на продление одобрена."
|
||||
: "❌ Заявка отклонена."
|
||||
)
|
||||
: $"⚠️ {result.Error.Message}";
|
||||
var text = $"{Escape(callback.Message.Text ?? "")}\n\n{statusText}";
|
||||
await botClient.EditMessageText(
|
||||
chatId.Value,
|
||||
callback.Message.Id,
|
||||
text,
|
||||
parseMode: ParseMode.Html,
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case "pay":
|
||||
{
|
||||
if (!await TrySetAdminCurrentUserAsync(services, fromId, cancellationToken))
|
||||
{
|
||||
await botClient.AnswerCallbackQuery(
|
||||
callback.Id,
|
||||
"Недостаточно прав.",
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
var result =
|
||||
parts[1] == "approve"
|
||||
? await sender.Send(
|
||||
new ConfirmPaymentRequestCommand(requestId),
|
||||
cancellationToken
|
||||
)
|
||||
: await sender.Send(
|
||||
new RejectPaymentRequestCommand(requestId, Reason: null),
|
||||
cancellationToken
|
||||
);
|
||||
|
||||
await botClient.AnswerCallbackQuery(
|
||||
callback.Id,
|
||||
result.IsSuccess ? "Готово" : result.Error.Message,
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
if (callback.Message is not null)
|
||||
{
|
||||
var statusText = result.IsSuccess
|
||||
? (
|
||||
parts[1] == "approve"
|
||||
? "✅ Оплата подтверждена."
|
||||
: "❌ Оплата отклонена."
|
||||
)
|
||||
: $"⚠️ {result.Error.Message}";
|
||||
var text = $"{Escape(callback.Message.Text ?? "")}\n\n{statusText}";
|
||||
await botClient.EditMessageText(
|
||||
chatId.Value,
|
||||
callback.Message.Id,
|
||||
text,
|
||||
parseMode: ParseMode.Html,
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case "cfg":
|
||||
{
|
||||
if (!await TrySetCurrentUserAsync(services, fromId, cancellationToken))
|
||||
{
|
||||
await botClient.AnswerCallbackQuery(
|
||||
callback.Id,
|
||||
"Telegram не привязан.",
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
var linkResult = await sender.Send(
|
||||
new GetConfigLinkQuery(requestId),
|
||||
cancellationToken
|
||||
);
|
||||
await botClient.AnswerCallbackQuery(
|
||||
callback.Id,
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
|
||||
if (!linkResult.IsSuccess)
|
||||
{
|
||||
await botClient.SendMessage(
|
||||
chatId.Value,
|
||||
$"Не удалось получить ссылку: {linkResult.Error.Message}",
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (callback.Message is null)
|
||||
break;
|
||||
}
|
||||
case "act":
|
||||
{
|
||||
if (!await TrySetAdminCurrentUserAsync(services, fromId, cancellationToken))
|
||||
{
|
||||
await botClient.AnswerCallbackQuery(
|
||||
callback.Id,
|
||||
"Недостаточно прав.",
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Редактируем то же сообщение (не плодим отдельное с сырым URL) — ссылка моноширинным
|
||||
// блоком, по нему в Telegram можно тапнуть и скопировать целиком одним движением.
|
||||
// Убираем именно эту кнопку из клавиатуры — остальные конфиги и «В меню» остаются на месте.
|
||||
var text =
|
||||
$"{Escape(callback.Message.Text ?? "")}\n\n<code>{Escape(linkResult.Value.ConnectionString)}</code>";
|
||||
var remainingRows = (callback.Message.ReplyMarkup?.InlineKeyboard ?? [])
|
||||
.Where(row => row.All(b => b.CallbackData != data))
|
||||
.ToArray();
|
||||
var result =
|
||||
parts[1] == "approve"
|
||||
? await sender.Send(
|
||||
new ApproveActivationCommand(requestId),
|
||||
cancellationToken
|
||||
)
|
||||
: await sender.Send(
|
||||
new RejectActivationCommand(requestId, Reason: null),
|
||||
cancellationToken
|
||||
);
|
||||
|
||||
await botClient.EditMessageText(
|
||||
chatId.Value,
|
||||
callback.Message.Id,
|
||||
text,
|
||||
parseMode: ParseMode.Html,
|
||||
replyMarkup: remainingRows.Length > 0
|
||||
? new InlineKeyboardMarkup(remainingRows)
|
||||
: null,
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
await botClient.AnswerCallbackQuery(
|
||||
callback.Id,
|
||||
result.IsSuccess ? "Готово" : result.Error.Message,
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
if (callback.Message is not null)
|
||||
{
|
||||
// Редактируем исходное сообщение с запросом вместо отдельного — иначе кнопки
|
||||
// «Активировать/Отклонить» остаются висеть под уже обработанным запросом (в т.ч.
|
||||
// если его обработали в другом месте — на сайте или из другого чата).
|
||||
var statusText = result.IsSuccess
|
||||
? (
|
||||
parts[1] == "approve"
|
||||
? "✅ Пользователь активирован."
|
||||
: "❌ Запрос отклонён."
|
||||
)
|
||||
: $"⚠️ {result.Error.Message}";
|
||||
var text = $"{Escape(callback.Message.Text ?? "")}\n\n{statusText}";
|
||||
await botClient.EditMessageText(
|
||||
chatId.Value,
|
||||
callback.Message.Id,
|
||||
text,
|
||||
parseMode: ParseMode.Html,
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "erq":
|
||||
{
|
||||
if (!await TrySetAdminCurrentUserAsync(services, fromId, cancellationToken))
|
||||
{
|
||||
await botClient.AnswerCallbackQuery(
|
||||
callback.Id,
|
||||
"Недостаточно прав.",
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
var result =
|
||||
parts[1] == "approve"
|
||||
? await sender.Send(
|
||||
new ApproveExtensionRequestCommand(requestId),
|
||||
cancellationToken
|
||||
)
|
||||
: await sender.Send(
|
||||
new RejectExtensionRequestCommand(requestId, Reason: null),
|
||||
cancellationToken
|
||||
);
|
||||
|
||||
await botClient.AnswerCallbackQuery(
|
||||
callback.Id,
|
||||
result.IsSuccess ? "Готово" : result.Error.Message,
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
if (callback.Message is not null)
|
||||
{
|
||||
var statusText = result.IsSuccess
|
||||
? (
|
||||
parts[1] == "approve"
|
||||
? "✅ Заявка на продление одобрена."
|
||||
: "❌ Заявка отклонена."
|
||||
)
|
||||
: $"⚠️ {result.Error.Message}";
|
||||
var text = $"{Escape(callback.Message.Text ?? "")}\n\n{statusText}";
|
||||
await botClient.EditMessageText(
|
||||
chatId.Value,
|
||||
callback.Message.Id,
|
||||
text,
|
||||
parseMode: ParseMode.Html,
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case "pay":
|
||||
{
|
||||
if (!await TrySetAdminCurrentUserAsync(services, fromId, cancellationToken))
|
||||
{
|
||||
await botClient.AnswerCallbackQuery(
|
||||
callback.Id,
|
||||
"Недостаточно прав.",
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
var result =
|
||||
parts[1] == "approve"
|
||||
? await sender.Send(
|
||||
new ConfirmPaymentRequestCommand(requestId),
|
||||
cancellationToken
|
||||
)
|
||||
: await sender.Send(
|
||||
new RejectPaymentRequestCommand(requestId, Reason: null),
|
||||
cancellationToken
|
||||
);
|
||||
|
||||
await botClient.AnswerCallbackQuery(
|
||||
callback.Id,
|
||||
result.IsSuccess ? "Готово" : result.Error.Message,
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
if (callback.Message is not null)
|
||||
{
|
||||
var statusText = result.IsSuccess
|
||||
? (
|
||||
parts[1] == "approve"
|
||||
? "✅ Оплата подтверждена."
|
||||
: "❌ Оплата отклонена."
|
||||
)
|
||||
: $"⚠️ {result.Error.Message}";
|
||||
var text = $"{Escape(callback.Message.Text ?? "")}\n\n{statusText}";
|
||||
await botClient.EditMessageText(
|
||||
chatId.Value,
|
||||
callback.Message.Id,
|
||||
text,
|
||||
parseMode: ParseMode.Html,
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case "cfg":
|
||||
{
|
||||
if (!await TrySetCurrentUserAsync(services, fromId, cancellationToken))
|
||||
{
|
||||
await botClient.AnswerCallbackQuery(
|
||||
callback.Id,
|
||||
"Telegram не привязан.",
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
var linkResult = await sender.Send(
|
||||
new GetConfigLinkQuery(requestId),
|
||||
cancellationToken
|
||||
);
|
||||
await botClient.AnswerCallbackQuery(
|
||||
callback.Id,
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
|
||||
if (!linkResult.IsSuccess)
|
||||
{
|
||||
await botClient.SendMessage(
|
||||
chatId.Value,
|
||||
$"Не удалось получить ссылку: {linkResult.Error.Message}",
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (callback.Message is null)
|
||||
break;
|
||||
|
||||
// Редактируем то же сообщение (не плодим отдельное с сырым URL) — ссылка моноширинным
|
||||
// блоком, по нему в Telegram можно тапнуть и скопировать целиком одним движением.
|
||||
// Убираем именно эту кнопку из клавиатуры — остальные конфиги и «В меню» остаются на месте.
|
||||
var text =
|
||||
$"{Escape(callback.Message.Text ?? "")}\n\n<code>{Escape(linkResult.Value.ConnectionString)}</code>";
|
||||
var remainingRows = (callback.Message.ReplyMarkup?.InlineKeyboard ?? [])
|
||||
.Where(row => row.All(b => b.CallbackData != data))
|
||||
.ToArray();
|
||||
|
||||
await botClient.EditMessageText(
|
||||
chatId.Value,
|
||||
callback.Message.Id,
|
||||
text,
|
||||
parseMode: ParseMode.Html,
|
||||
replyMarkup: remainingRows.Length > 0
|
||||
? new InlineKeyboardMarkup(remainingRows)
|
||||
: null,
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
|
||||
namespace PnvPanel.Application.Activation;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using PnvPanel.Application.Auth;
|
||||
using PnvPanel.Application.Common.Interfaces;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
using PnvPanel.Domain.Activation;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
|
||||
namespace PnvPanel.Application.Activation;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using PnvPanel.Application.Auth;
|
||||
using PnvPanel.Application.Common.Interfaces;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
using PnvPanel.Domain.Activation;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
|
||||
namespace PnvPanel.Application.Admin.Activation;
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@ using Microsoft.EntityFrameworkCore;
|
||||
using PnvPanel.Application.Activation;
|
||||
using PnvPanel.Application.Auth;
|
||||
using PnvPanel.Application.Common.Interfaces;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
using PnvPanel.Domain.Activation;
|
||||
using PnvPanel.Domain.Audit;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
using PnvPanel.Domain.Activation;
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using PnvPanel.Application.Common.Interfaces;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
|
||||
namespace PnvPanel.Application.Admin.Activation;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
|
||||
namespace PnvPanel.Application.Admin.Activation;
|
||||
|
||||
@@ -2,7 +2,7 @@ using Microsoft.EntityFrameworkCore;
|
||||
using PnvPanel.Application.Activation;
|
||||
using PnvPanel.Application.Auth;
|
||||
using PnvPanel.Application.Common.Interfaces;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
using PnvPanel.Domain.Activation;
|
||||
using PnvPanel.Domain.Audit;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
using PnvPanel.Domain.Apps;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using PnvPanel.Application.Common.Interfaces;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
using PnvPanel.Domain.Apps;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
|
||||
namespace PnvPanel.Application.Admin.Apps;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using PnvPanel.Application.Common.Interfaces;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
|
||||
namespace PnvPanel.Application.Admin.Apps;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
|
||||
namespace PnvPanel.Application.Admin.Apps;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using PnvPanel.Application.Common.Interfaces;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
|
||||
namespace PnvPanel.Application.Admin.Apps;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
using PnvPanel.Domain.Apps;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using PnvPanel.Application.Common.Interfaces;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
|
||||
namespace PnvPanel.Application.Admin.Apps;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
using PnvPanel.Domain.Audit;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using PnvPanel.Application.Common.Interfaces;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
|
||||
namespace PnvPanel.Application.Admin.Audit;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
|
||||
namespace PnvPanel.Application.Admin.Billing;
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ using PnvPanel.Application.Auth;
|
||||
using PnvPanel.Application.Billing;
|
||||
using PnvPanel.Application.Common.Concurrency;
|
||||
using PnvPanel.Application.Common.Interfaces;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
using PnvPanel.Domain.Audit;
|
||||
using PnvPanel.Domain.Billing;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
|
||||
namespace PnvPanel.Application.Admin.Billing;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using PnvPanel.Application.Common.Interfaces;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
using PnvPanel.Domain.Billing;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
|
||||
namespace PnvPanel.Application.Admin.Billing;
|
||||
|
||||
@@ -3,7 +3,7 @@ using PnvPanel.Application.Admin.Users;
|
||||
using PnvPanel.Application.Auth;
|
||||
using PnvPanel.Application.Billing;
|
||||
using PnvPanel.Application.Common.Interfaces;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
using PnvPanel.Domain.Audit;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
using PnvPanel.Domain.Billing;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using PnvPanel.Application.Common.Interfaces;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
|
||||
namespace PnvPanel.Application.Admin.Billing;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
|
||||
namespace PnvPanel.Application.Admin.Billing;
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ using PnvPanel.Application.Auth;
|
||||
using PnvPanel.Application.Billing;
|
||||
using PnvPanel.Application.Common.Concurrency;
|
||||
using PnvPanel.Application.Common.Interfaces;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
using PnvPanel.Domain.Audit;
|
||||
using PnvPanel.Domain.Billing;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
|
||||
namespace PnvPanel.Application.Admin.Billing;
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using PnvPanel.Application.Common.Interfaces;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
using PnvPanel.Domain.Billing;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using PnvPanel.Application.Common.Interfaces;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
using PnvPanel.Domain.Configs;
|
||||
using PnvPanel.Domain.Inbounds;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using PnvPanel.Application.Common.Interfaces;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
|
||||
namespace PnvPanel.Application.Admin.Configs;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
|
||||
namespace PnvPanel.Application.Admin.Inbounds;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using PnvPanel.Application.Common.Interfaces;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
using PnvPanel.Domain.Audit;
|
||||
using PnvPanel.Domain.Configs;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
|
||||
namespace PnvPanel.Application.Admin.Inbounds;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using PnvPanel.Application.Common.Interfaces;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
|
||||
namespace PnvPanel.Application.Admin.Inbounds;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
|
||||
namespace PnvPanel.Application.Admin.Inbounds;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using PnvPanel.Application.Common.Interfaces;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
using PnvPanel.Domain.Audit;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
using PnvPanel.Application.Instructions;
|
||||
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
using PnvPanel.Application.Common.Interfaces;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
using PnvPanel.Application.Instructions;
|
||||
using PnvPanel.Domain.Instructions;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
|
||||
namespace PnvPanel.Application.Admin.Instructions;
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using PnvPanel.Application.Common.Interfaces;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
|
||||
namespace PnvPanel.Application.Admin.Instructions;
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
using PnvPanel.Application.Instructions;
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using PnvPanel.Application.Common.Interfaces;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
using PnvPanel.Application.Instructions;
|
||||
using PnvPanel.Domain.Instructions;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
using PnvPanel.Application.Instructions;
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using PnvPanel.Application.Common.Interfaces;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
using PnvPanel.Application.Instructions;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
|
||||
namespace PnvPanel.Application.Admin.Maintenance;
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using PnvPanel.Application.Auth;
|
||||
using PnvPanel.Application.Common.Interfaces;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
using PnvPanel.Domain.Audit;
|
||||
using PnvPanel.Domain.Support;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
|
||||
namespace PnvPanel.Application.Admin.Maintenance;
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using PnvPanel.Application.Auth;
|
||||
using PnvPanel.Application.Common.Interfaces;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
using PnvPanel.Domain.Audit;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
|
||||
namespace PnvPanel.Application.Admin.Maintenance;
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using PnvPanel.Application.Auth;
|
||||
using PnvPanel.Application.Common.Interfaces;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
using PnvPanel.Domain.Audit;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
|
||||
namespace PnvPanel.Application.Admin.Maintenance;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using PnvPanel.Application.Auth;
|
||||
using PnvPanel.Application.Common.Interfaces;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
using PnvPanel.Domain.Audit;
|
||||
using PnvPanel.Domain.Configs;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
using PnvPanel.Application.News;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using PnvPanel.Application.Common.Interfaces;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
using PnvPanel.Application.News;
|
||||
using PnvPanel.Domain.News;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
|
||||
namespace PnvPanel.Application.Admin.News;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using PnvPanel.Application.Common.Interfaces;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
|
||||
namespace PnvPanel.Application.Admin.News;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
using PnvPanel.Application.News;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using PnvPanel.Application.Common.Interfaces;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
using PnvPanel.Application.News;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
using PnvPanel.Application.News;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using PnvPanel.Application.Common.Interfaces;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
using PnvPanel.Application.News;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
|
||||
namespace PnvPanel.Application.Admin.Nodes;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using PnvPanel.Application.Common.Interfaces;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
using PnvPanel.Domain.Audit;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
|
||||
namespace PnvPanel.Application.Admin.Nodes;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using PnvPanel.Application.Common.Interfaces;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
|
||||
namespace PnvPanel.Application.Admin.Nodes;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
using PnvPanel.Domain.Nodes;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using PnvPanel.Application.Common.Interfaces;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
using PnvPanel.Domain.Nodes;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
|
||||
namespace PnvPanel.Application.Admin.Nodes;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using PnvPanel.Application.Common.Interfaces;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
using PnvPanel.Domain.Audit;
|
||||
using PnvPanel.Domain.Nodes;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using LiteCqrs;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
using PnvPanel.Domain.Nodes;
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user