Enhance documentation with new features: added dark/light/system theme support, instructions page, and application catalog. Updated API and domain model for app management and automatic migrations on startup. Improved frontend structure with new routes and features for user instructions and app management.
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
using PnvPanel.Domain.Inbounds;
|
||||
|
||||
namespace PnvPanel.Application.Admin.Inbounds;
|
||||
|
||||
public sealed record InboundDto(
|
||||
Guid Id, Guid NodeId, string RemoteInboundId, VpnProtocol Protocol, string Remark, int Port,
|
||||
bool IsPublished, string? DisplayName, int? MaxClients, IReadOnlyList<Guid> AllowedRoleIds,
|
||||
DateTimeOffset? LastSyncAt)
|
||||
{
|
||||
public static InboundDto FromDomain(Inbound inbound) => new(
|
||||
inbound.Id, inbound.NodeId, inbound.RemoteInboundId, inbound.Protocol, inbound.Remark, inbound.Port,
|
||||
inbound.IsPublished, inbound.DisplayName, inbound.MaxClients, inbound.AllowedRoleIds, inbound.LastSyncAt);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
using PnvPanel.Application.Common.Models;
|
||||
|
||||
namespace PnvPanel.Application.Admin.Inbounds;
|
||||
|
||||
public static class InboundErrors
|
||||
{
|
||||
public static readonly Error NotFound = Error.NotFound("Inbounds.NotFound", "Inbound не найден.");
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
|
||||
namespace PnvPanel.Application.Admin.Inbounds;
|
||||
|
||||
public sealed record ListInboundsQuery(Guid? NodeId) : IQuery<Result<IReadOnlyList<InboundDto>>>;
|
||||
@@ -0,0 +1,19 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using PnvPanel.Application.Common.Interfaces;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
|
||||
namespace PnvPanel.Application.Admin.Inbounds;
|
||||
|
||||
public sealed class ListInboundsQueryHandler(IAppDbContext dbContext) : IQueryHandler<ListInboundsQuery, Result<IReadOnlyList<InboundDto>>>
|
||||
{
|
||||
public async Task<Result<IReadOnlyList<InboundDto>>> Handle(ListInboundsQuery query, CancellationToken cancellationToken)
|
||||
{
|
||||
var inboundsQuery = dbContext.Inbounds.AsNoTracking();
|
||||
if (query.NodeId is { } nodeId)
|
||||
inboundsQuery = inboundsQuery.Where(i => i.NodeId == nodeId);
|
||||
|
||||
var inbounds = await inboundsQuery.OrderBy(i => i.Remark).ToListAsync(cancellationToken);
|
||||
return Result.Success<IReadOnlyList<InboundDto>>(inbounds.Select(InboundDto.FromDomain).ToList());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
|
||||
namespace PnvPanel.Application.Admin.Inbounds;
|
||||
|
||||
public sealed record PublishInboundCommand(
|
||||
Guid InboundId, bool IsPublished, string? DisplayName, IReadOnlyList<Guid> AllowedRoleIds, int? MaxClients)
|
||||
: ICommand<Result<InboundDto>>;
|
||||
@@ -0,0 +1,24 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using PnvPanel.Application.Common.Interfaces;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
|
||||
namespace PnvPanel.Application.Admin.Inbounds;
|
||||
|
||||
public sealed class PublishInboundCommandHandler(IAppDbContext dbContext)
|
||||
: ICommandHandler<PublishInboundCommand, Result<InboundDto>>
|
||||
{
|
||||
public async Task<Result<InboundDto>> Handle(PublishInboundCommand command, CancellationToken cancellationToken)
|
||||
{
|
||||
var inbound = await dbContext.Inbounds.FirstOrDefaultAsync(i => i.Id == command.InboundId, cancellationToken);
|
||||
if (inbound is null)
|
||||
return Result.Failure<InboundDto>(InboundErrors.NotFound);
|
||||
|
||||
if (command.IsPublished)
|
||||
inbound.Publish(command.DisplayName, command.AllowedRoleIds, command.MaxClients);
|
||||
else
|
||||
inbound.Unpublish();
|
||||
|
||||
return Result.Success(InboundDto.FromDomain(inbound));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using FluentValidation;
|
||||
|
||||
namespace PnvPanel.Application.Admin.Inbounds;
|
||||
|
||||
public sealed class PublishInboundCommandValidator : AbstractValidator<PublishInboundCommand>
|
||||
{
|
||||
public PublishInboundCommandValidator()
|
||||
{
|
||||
RuleFor(x => x.DisplayName).MaximumLength(100);
|
||||
RuleFor(x => x.MaxClients).GreaterThan(0).When(x => x.MaxClients.HasValue);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user