Skip to content

Commit

Permalink
管理员管理接口
Browse files Browse the repository at this point in the history
  • Loading branch information
Codespilot committed Feb 2, 2024
1 parent 456c213 commit a4882bf
Show file tree
Hide file tree
Showing 22 changed files with 665 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,10 @@ public override void AheadConfigureServices(ServiceConfigurationContext context)
{
Configure<AutomapperOptions>(options =>
{
options.AddProfile<UserMappingProfile>();
options.AddProfile<IdentityMappingProfile>();
options.AddProfile<LogsMappingProfile>();
options.AddProfile<AppsMappingProfile>();
options.AddProfile<ConfigurationMappingProfile>();
options.AddProfile<TeamMappingProfile>();
});
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using Nerosoft.Euonia.Domain;

namespace Nerosoft.Starfish.Application;

public class AdministratorAssignCommand : Command
{
public string UserId { get; set; }

public List<string> Roles { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using Nerosoft.Euonia.Domain;

namespace Nerosoft.Starfish.Application;

public class AdministratorDeleteCommand : Command
{
public AdministratorDeleteCommand(string userId)
{
UserId = userId;
}

public string UserId { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using Nerosoft.Euonia.Application;
using Nerosoft.Starfish.Transit;

namespace Nerosoft.Starfish.Application;

public interface IAdministratorApplicationService : IApplicationService
{
Task<List<AdministratorItemDto>> QueryAsync(AdministratorCriteria criteria, int skip, int count, CancellationToken cancellationToken = default);

Task<int> CountAsync(AdministratorCriteria criteria, CancellationToken cancellationToken = default);

Task AssignAsync(AdministratorAssignDto data, CancellationToken cancellationToken = default);

Task DeleteAsync(string userId, CancellationToken cancellationToken = default);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using Nerosoft.Euonia.Bus;
using Nerosoft.Euonia.Business;
using Nerosoft.Euonia.Repository;
using Nerosoft.Starfish.Domain;
using Nerosoft.Starfish.Service;

namespace Nerosoft.Starfish.Application;

public class AdministratorCommandHandler : CommandHandlerBase,
IHandler<AdministratorAssignCommand>,
IHandler<AdministratorDeleteCommand>
{
public AdministratorCommandHandler(IUnitOfWorkManager unitOfWork, IObjectFactory factory)
: base(unitOfWork, factory)
{
}

public Task HandleAsync(AdministratorAssignCommand message, MessageContext context, CancellationToken cancellationToken = default)
{
return ExecuteAsync(async () =>
{
var business = await Factory.FetchAsync<AdministratorGeneralBusiness>(message.UserId, cancellationToken);
business.UserId = message.UserId;
business.SetRoles(message.Roles);
if (business.Aggregate == null)
{
business.MarkAsInsert();
}
else
{
business.MarkAsUpdate();
}

_ = await business.SaveAsync(false, cancellationToken);
});
}

public Task HandleAsync(AdministratorDeleteCommand message, MessageContext context, CancellationToken cancellationToken = default)
{
return ExecuteAsync(async () =>
{
var business = await Factory.FetchAsync<AdministratorGeneralBusiness>(message.UserId, cancellationToken);

business.MarkAsDelete();

_ = await business.SaveAsync(false, cancellationToken);
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using Nerosoft.Euonia.Application;
using Nerosoft.Starfish.Transit;
using Nerosoft.Starfish.UseCases;

namespace Nerosoft.Starfish.Application;

internal class AdministratorApplicationService : BaseApplicationService, IAdministratorApplicationService
{
public Task<List<AdministratorItemDto>> QueryAsync(AdministratorCriteria criteria, int skip, int count, CancellationToken cancellationToken = default)
{
var input = new GenericQueryInput<AdministratorCriteria>(criteria, skip, count);
var useCase = LazyServiceProvider.GetRequiredService<IAdministratorQueryUseCase>();
return useCase.ExecuteAsync(input, cancellationToken).ContinueWith(task =>
{
task.WaitAndUnwrapException(cancellationToken);
return task.Result.Result;
}, cancellationToken);
}

public Task<int> CountAsync(AdministratorCriteria criteria, CancellationToken cancellationToken = default)
{
var input = new AdministratorCountInput(criteria);
var useCase = LazyServiceProvider.GetRequiredService<IAdministratorCountUseCase>();
return useCase.ExecuteAsync(input, cancellationToken).ContinueWith(task =>
{
task.WaitAndUnwrapException(cancellationToken);
return task.Result.Result;
}, cancellationToken);
}

public Task AssignAsync(AdministratorAssignDto data, CancellationToken cancellationToken = default)
{
var input = new AdministratorAssignInput(data);
var useCase = LazyServiceProvider.GetRequiredService<IAdministratorAssignUseCase>();
return useCase.ExecuteAsync(input, cancellationToken)
.ContinueWith(task => task.WaitAndUnwrapException(cancellationToken), cancellationToken);
}

public Task DeleteAsync(string userId, CancellationToken cancellationToken = default)
{
var input = new AdministratorDeleteInput(userId);
var useCase = LazyServiceProvider.GetRequiredService<IAdministratorDeleteUseCase>();
return useCase.ExecuteAsync(input, cancellationToken)
.ContinueWith(task => task.WaitAndUnwrapException(cancellationToken), cancellationToken);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,21 @@

namespace Nerosoft.Starfish.Application;

internal class TeamMappingProfile : Profile
/// <summary>
/// 用户映射配置
/// </summary>
internal class IdentityMappingProfile : Profile
{
public TeamMappingProfile()
/// <summary>
///
/// </summary>
public IdentityMappingProfile()
{
CreateMap<User, UserItemDto>();
CreateMap<User, UserDetailDto>();
CreateMap<UserCreateDto, UserCreateCommand>();
CreateMap<UserUpdateDto, UserUpdateCommand>();

CreateMap<Team, TeamItemDto>();
CreateMap<Team, TeamDetailDto>();

Expand All @@ -16,5 +27,8 @@ public TeamMappingProfile()
.ForMember(dest => dest.NickName, options => options.MapFrom(src => src.User.NickName))
.ForMember(dest => dest.Email, options => options.MapFrom(src => src.User.Email))
.ForMember(dest => dest.Phone, options => options.MapFrom(src => src.User.Phone));

CreateMap<Administrator, AdministratorItemDto>();
CreateMap<AdministratorAssignDto, AdministratorAssignCommand>();
}
}
22 changes: 0 additions & 22 deletions Source/Starfish.Service/Application/Mappings/UserMappingProfile.cs

This file was deleted.

2 changes: 1 addition & 1 deletion Source/Starfish.Service/Domain/Aggregates/Administrator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ public class Administrator : Aggregate<long>

public User User { get; set; }

public string Scopes { get; set; }
public string Roles { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
using Microsoft.EntityFrameworkCore;
using Nerosoft.Euonia.Business;
using Nerosoft.Starfish.Service;

// ReSharper disable MemberCanBePrivate.Global

namespace Nerosoft.Starfish.Domain;

internal sealed class AdministratorGeneralBusiness : EditableObjectBase<AdministratorGeneralBusiness>
{
[Inject]
public IUserRepository UserRepository { get; set; }

[Inject]
public IAdministratorRepository AdministratorRepository { get; set; }

public Administrator Aggregate { get; private set; }

public static readonly PropertyInfo<string> UserIdProperty = RegisterProperty<string>(p => p.UserId);

public string UserId
{
get => GetProperty(UserIdProperty);
set => SetProperty(UserIdProperty, value);
}

public static readonly PropertyInfo<HashSet<string>> RolesProperty = RegisterProperty<HashSet<string>>(p => p.Roles, []);

public HashSet<string> Roles
{
get => GetProperty(RolesProperty);
set => SetProperty(RolesProperty, value);
}

protected override void AddRules()
{
Rules.AddRule(new UserCheckRule());
}

public void SetRoles(IEnumerable<string> roles)
{
if (Roles.SetEquals(roles))
{
return;
}

Roles.Clear();
if (roles.Any())
{
foreach (var role in roles)
{
Roles.Add(role);
}
}

ChangedProperties.Add(RolesProperty);
}

[FactoryFetch]
internal async Task FetchAsync(string userId, CancellationToken cancellationToken = default)
{
var aggregate = await AdministratorRepository.GetAsync(t => t.UserId == userId, query => query.AsTracking(), cancellationToken);

if (aggregate != null)
{
using (BypassRuleChecks)
{
UserId = aggregate.UserId;
Roles = [..aggregate.Roles.Split(",")];
}

Aggregate = aggregate;
}
}

[FactoryInsert]
protected override async Task InsertAsync(CancellationToken cancellationToken = default)
{
Aggregate = new Administrator
{
UserId = UserId,
Roles = Roles.JoinAsString(",")
};

await AdministratorRepository.InsertAsync(Aggregate, true, cancellationToken);
}

[FactoryUpdate]
protected override async Task UpdateAsync(CancellationToken cancellationToken = default)
{
if (ChangedProperties.Contains(RolesProperty))
{
Aggregate.Roles = Roles.JoinAsString(",");
}

await AdministratorRepository.UpdateAsync(Aggregate, true, cancellationToken);
}

[FactoryDelete]
protected override async Task DeleteAsync(CancellationToken cancellationToken = default)
{
if (Aggregate == null)
{
throw new NotFoundException();
}

await AdministratorRepository.DeleteAsync(Aggregate, true, cancellationToken);
}

public class UserCheckRule : RuleBase
{
public override async Task ExecuteAsync(IRuleContext context, CancellationToken cancellationToken = default)
{
var target = (AdministratorGeneralBusiness)context.Target;
if (target.ChangedProperties.Contains(UserIdProperty))
{
var exists = await target.UserRepository.AnyAsync(t => t.Id == target.UserId, query => query.AsNoTracking(), cancellationToken);
if (exists)
{
context.AddErrorResult(string.Format(Resources.IDS_ERROR_USER_NOT_EXISTS, target.UserId));
}
}
}
}
}
Loading

0 comments on commit a4882bf

Please sign in to comment.