Refactor pricing endpoints and enhance support for pricing retrieval
- Added a new endpoint `/api/support/pricing` to allow users to retrieve pricing information, making it accessible for role request dialogs. - Introduced the `GetSupportPricing` method to handle pricing queries, ensuring that pricing data is available to non-admin users. - Updated frontend components to integrate the new pricing retrieval functionality, displaying estimated costs based on user-selected configurations. - Removed the `PricingSettingsDto` as it is no longer needed, streamlining the pricing data structure. - Enhanced API documentation to reflect the new endpoint and its usage in the support context.
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
using PnvPanel.Api.Common;
|
||||
using PnvPanel.Application.Admin.Pricing;
|
||||
using PnvPanel.Application.Common.Interfaces;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using PnvPanel.Infrastructure.Identity;
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ using PnvPanel.Application.Support.AddComment;
|
||||
using PnvPanel.Application.Support.CreateBugReport;
|
||||
using PnvPanel.Application.Support.CreateRoleRequest;
|
||||
using PnvPanel.Application.Support.GetAttachment;
|
||||
using PnvPanel.Application.Support.GetSupportPricing;
|
||||
using PnvPanel.Application.Support.GetTicket;
|
||||
using PnvPanel.Application.Support.ListMyTickets;
|
||||
using PnvPanel.Application.Support.ListSelectableRoles;
|
||||
@@ -23,6 +24,7 @@ public static class SupportEndpoints
|
||||
var group = app.MapGroup("/api/support").WithTags("Support").RequireAuthorization();
|
||||
|
||||
group.MapGet("/roles", ListSelectableRoles).Produces<IReadOnlyList<RoleDto>>();
|
||||
group.MapGet("/pricing", GetSupportPricing).Produces<PricingSettingsDto>();
|
||||
group
|
||||
.MapPost("/tickets/bug-reports", CreateBugReport)
|
||||
.DisableAntiforgery()
|
||||
@@ -49,6 +51,15 @@ public static class SupportEndpoints
|
||||
return result.ToHttpResult();
|
||||
}
|
||||
|
||||
private static async Task<IResult> GetSupportPricing(
|
||||
ISender sender,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
var result = await sender.Send(new GetSupportPricingQuery(), cancellationToken);
|
||||
return result.ToHttpResult();
|
||||
}
|
||||
|
||||
private static async Task<IResult> CreateBugReport(
|
||||
[FromForm] string message,
|
||||
IFormFileCollection? files,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using PnvPanel.Application.Common.Interfaces;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
using PnvPanel.Domain.Pricing;
|
||||
|
||||
namespace PnvPanel.Application.Admin.Pricing;
|
||||
|
||||
public sealed record PricingSettingsDto(
|
||||
int? PricePerConfigPerQuarter,
|
||||
int? PricePerConfigPerHalfYear,
|
||||
int? PricePerConfigPerYear
|
||||
)
|
||||
{
|
||||
public static PricingSettingsDto FromDomain(PricingSettings settings) =>
|
||||
new(
|
||||
settings.PricePerConfigPerQuarter,
|
||||
settings.PricePerConfigPerHalfYear,
|
||||
settings.PricePerConfigPerYear
|
||||
);
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
using PnvPanel.Application.Common.Interfaces;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
using PnvPanel.Domain.Pricing;
|
||||
|
||||
namespace PnvPanel.Application.Common.Interfaces;
|
||||
|
||||
/// <summary>Все поля — цена за конфиг В МЕСЯЦ при соответствующем тарифе оплаты; итог за период =
|
||||
/// ставка × число месяцев. Используется и Admin (редактирование), и Support (справка при заявке на
|
||||
/// роль) — см. PricingSettingsDto.FromDomain.</summary>
|
||||
public sealed record PricingSettingsDto(
|
||||
int? PricePerConfigPerQuarter,
|
||||
int? PricePerConfigPerHalfYear,
|
||||
int? PricePerConfigPerYear
|
||||
)
|
||||
{
|
||||
public static PricingSettingsDto FromDomain(PricingSettings settings) =>
|
||||
new(
|
||||
settings.PricePerConfigPerQuarter,
|
||||
settings.PricePerConfigPerHalfYear,
|
||||
settings.PricePerConfigPerYear
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using PnvPanel.Application.Common.Interfaces;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
|
||||
namespace PnvPanel.Application.Support.GetSupportPricing;
|
||||
|
||||
/// <summary>Справочная цена конфига для заявки на роль (не редактирование, только чтение) — в отличие
|
||||
/// от GetPricingSettingsQuery (Admin/Pricing), доступна любому активированному пользователю.</summary>
|
||||
public sealed record GetSupportPricingQuery : IQuery<Result<PricingSettingsDto>>, IRequiresActivation;
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using PnvPanel.Application.Common.Interfaces;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
|
||||
namespace PnvPanel.Application.Support.GetSupportPricing;
|
||||
|
||||
public sealed class GetSupportPricingQueryHandler(IAppDbContext dbContext)
|
||||
: IQueryHandler<GetSupportPricingQuery, Result<PricingSettingsDto>>
|
||||
{
|
||||
public async Task<Result<PricingSettingsDto>> Handle(
|
||||
GetSupportPricingQuery query,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
var settings = await dbContext
|
||||
.PricingSettings.AsNoTracking()
|
||||
.FirstOrDefaultAsync(cancellationToken);
|
||||
|
||||
// Ещё не сидировано/не сохранено ни разу — цена не задана, а не ошибка.
|
||||
return Result.Success(
|
||||
settings is null
|
||||
? new PricingSettingsDto(null, null, null)
|
||||
: PricingSettingsDto.FromDomain(settings)
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user