Browse Source

feat(data-seeder): Optimize data seeds

pull/1416/head
colin 2 months ago
parent
commit
4fb60b078b
  1. 59
      aspnet-core/aspire/LINGYUN.Abp.MicroService.AdminService.EntityFrameworkCore/AdminServiceDataSeeder.cs
  2. 19
      aspnet-core/aspire/LINGYUN.Abp.MicroService.AdminService.EntityFrameworkCore/AdminServiceDbMigrationEventHandler.cs
  3. 12
      aspnet-core/aspire/LINGYUN.Abp.MicroService.AdminService.EntityFrameworkCore/AdminServiceDbMigrationService.cs
  4. 13
      aspnet-core/aspire/LINGYUN.Abp.MicroService.AdminService/AdminServiceModule.cs
  5. 29
      aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer.DbMigrator/appsettings.json
  6. 35
      aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer.EntityFrameworkCore/AuthServerDataSeeder.cs
  7. 109
      aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer.EntityFrameworkCore/AuthServerDbMigrationEventHandler.cs
  8. 13
      aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer.EntityFrameworkCore/AuthServerDbMigrationService.cs
  9. 89
      aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer.EntityFrameworkCore/DataSeeds/IdentityClaimTypeDataSeeder.cs
  10. 124
      aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer.EntityFrameworkCore/DataSeeds/IdentityUserRoleDataSeeder.cs
  11. 255
      aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer.EntityFrameworkCore/DataSeeds/OpenIddictDataSeeder.cs
  12. 16
      aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer/AuthServerModule.cs
  13. 9
      aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer/LINGYUN.Abp.MicroService.AuthServer.csproj
  14. 29
      aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer/appsettings.Development.json
  15. 6
      aspnet-core/aspire/LINGYUN.Abp.MicroService.IdentityService/IdentityServiceModule.cs
  16. 1
      aspnet-core/aspire/LINGYUN.Abp.MicroService.PlatformService.EntityFrameworkCore/LINGYUN.Abp.MicroService.PlatformService.EntityFrameworkCore.csproj
  17. 47
      aspnet-core/aspire/LINGYUN.Abp.MicroService.PlatformService.EntityFrameworkCore/PlatformServiceDataSeeder.cs
  18. 35
      aspnet-core/aspire/LINGYUN.Abp.MicroService.PlatformService.EntityFrameworkCore/PlatformServiceDbMigrationEventHandler.cs
  19. 12
      aspnet-core/aspire/LINGYUN.Abp.MicroService.PlatformService.EntityFrameworkCore/PlatformServiceDbMigrationService.cs
  20. 4
      aspnet-core/aspire/LINGYUN.Abp.MicroService.PlatformService.EntityFrameworkCore/PlatformServiceMigrationsEntityFrameworkCoreModule.cs
  21. 2
      aspnet-core/aspire/LINGYUN.Abp.MicroService.PlatformService/LINGYUN.Abp.MicroService.PlatformService.csproj
  22. 9
      aspnet-core/aspire/LINGYUN.Abp.MicroService.PlatformService/PlatformServiceModule.cs
  23. 139
      aspnet-core/aspire/LINGYUN.Abp.MicroService.TaskService.EntityFrameworkCore/TaskServiceDataSeeder.cs
  24. 122
      aspnet-core/aspire/LINGYUN.Abp.MicroService.TaskService.EntityFrameworkCore/TaskServiceDbMigrationEventHandler.cs
  25. 3
      aspnet-core/aspire/LINGYUN.Abp.MicroService.WebhookService.EntityFrameworkCore/WebhookServiceDbMigrationEventHandler.cs
  26. 98
      aspnet-core/modules/platform/LINGYUN.Abp.UI.Navigation.VueVbenAdmin/LINGYUN/Abp/UI/Navigation/VueVbenAdmin/VueVbenAdminNavigationSeedContributor.cs
  27. 106
      aspnet-core/modules/platform/LINGYUN.Abp.UI.Navigation.VueVbenAdmin5/LINGYUN/Abp/UI/Navigation/VueVbenAdmin5/VueVbenAdmin5NavigationSeedContributor.cs
  28. 14
      aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Datas/DataDictionaryDataSeeder.cs
  29. 4
      aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Datas/IDataDictionaryDataSeeder.cs
  30. 2
      aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Routes/IRouteDataSeeder.cs
  31. 11
      aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Routes/RouteDataSeeder.cs

59
aspnet-core/aspire/LINGYUN.Abp.MicroService.AdminService.EntityFrameworkCore/AdminServiceDataSeeder.cs

@ -0,0 +1,59 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.MultiTenancy;
using Volo.Abp.PermissionManagement;
namespace LINGYUN.Abp.MicroService.AdminService;
public class AdminServiceDataSeeder : ITransientDependency
{
protected ILogger<AdminServiceDataSeeder> Logger { get; }
protected ICurrentTenant CurrentTenant { get; }
protected IPermissionDefinitionManager PermissionDefinitionManager { get; }
protected IPermissionDataSeeder PermissionDataSeeder { get; }
public AdminServiceDataSeeder(
IPermissionDefinitionManager permissionDefinitionManager,
IPermissionDataSeeder permissionDataSeeder,
ICurrentTenant currentTenant)
{
PermissionDefinitionManager = permissionDefinitionManager;
PermissionDataSeeder = permissionDataSeeder;
CurrentTenant = currentTenant;
Logger = NullLogger<AdminServiceDataSeeder>.Instance;
}
public virtual async Task SeedAsync(DataSeedContext context)
{
using (CurrentTenant.Change(context.TenantId))
{
await SeedAdminRolePermissionsAsync(context);
}
}
private async Task SeedAdminRolePermissionsAsync(DataSeedContext context)
{
Logger.LogInformation("Seeding the default role permissions...");
var multiTenancySide = CurrentTenant.GetMultiTenancySide();
var permissionNames = (await PermissionDefinitionManager.GetPermissionsAsync())
.Where(p => p.MultiTenancySide.HasFlag(multiTenancySide))
.Where(p => !p.Providers.Any() || p.Providers.Contains(RolePermissionValueProvider.ProviderName))
.Select(p => p.Name)
.ToArray();
await PermissionDataSeeder.SeedAsync(
RolePermissionValueProvider.ProviderName,
"admin",
permissionNames,
context?.TenantId
);
Logger.LogInformation("Seed default role permissions completed.");
}
}

19
aspnet-core/aspire/LINGYUN.Abp.MicroService.AdminService.EntityFrameworkCore/AdminServiceDbMigrationEventHandler.cs

@ -1,5 +1,4 @@
using Microsoft.Extensions.Logging;
using System;
using System.Threading.Tasks;
using Volo.Abp.Data;
using Volo.Abp.DistributedLocking;
@ -11,7 +10,7 @@ using Volo.Abp.Uow;
namespace LINGYUN.Abp.MicroService.AdminService;
public class AdminServiceDbMigrationEventHandler : EfCoreDatabaseMigrationEventHandlerBase<AdminServiceMigrationsDbContext>
{
protected IDataSeeder DataSeeder { get; }
protected AdminServiceDataSeeder DataSeeder { get; }
public AdminServiceDbMigrationEventHandler(
ICurrentTenant currentTenant,
@ -20,7 +19,7 @@ public class AdminServiceDbMigrationEventHandler : EfCoreDatabaseMigrationEventH
IAbpDistributedLock abpDistributedLock,
IDistributedEventBus distributedEventBus,
ILoggerFactory loggerFactory,
IDataSeeder dataSeeder)
AdminServiceDataSeeder dataSeeder)
: base(
ConnectionStringNameAttribute.GetConnStringName<AdminServiceMigrationsDbContext>(),
currentTenant, unitOfWorkManager, tenantStore, abpDistributedLock, distributedEventBus, loggerFactory)
@ -28,8 +27,18 @@ public class AdminServiceDbMigrationEventHandler : EfCoreDatabaseMigrationEventH
DataSeeder = dataSeeder;
}
protected async override Task SeedAsync(Guid? tenantId)
protected async override Task AfterTenantCreated(TenantCreatedEto eventData, bool schemaMigrated)
{
await DataSeeder.SeedAsync(tenantId);
// 新租户数据种子
var context = new DataSeedContext(eventData.Id);
if (eventData.Properties != null)
{
foreach (var property in eventData.Properties)
{
context.WithProperty(property.Key, property.Value);
}
}
await DataSeeder.SeedAsync(context);
}
}

12
aspnet-core/aspire/LINGYUN.Abp.MicroService.AdminService.EntityFrameworkCore/AdminServiceDbMigrationService.cs

@ -1,6 +1,7 @@
using LINGYUN.Abp.Data.DbMigrator;
using Microsoft.Extensions.Logging;
using System;
using System.Threading.Tasks;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.DistributedLocking;
@ -11,16 +12,25 @@ using Volo.Abp.Uow;
namespace LINGYUN.Abp.MicroService.AdminService;
public class AdminServiceDbMigrationService : EfCoreRuntimeDbMigratorBase<AdminServiceMigrationsDbContext>, ITransientDependency
{
protected AdminServiceDataSeeder DataSeeder { get; }
public AdminServiceDbMigrationService(
ICurrentTenant currentTenant,
IUnitOfWorkManager unitOfWorkManager,
IServiceProvider serviceProvider,
IAbpDistributedLock abpDistributedLock,
IDistributedEventBus distributedEventBus,
ILoggerFactory loggerFactory)
ILoggerFactory loggerFactory,
AdminServiceDataSeeder dataSeeder)
: base(
ConnectionStringNameAttribute.GetConnStringName<AdminServiceMigrationsDbContext>(),
unitOfWorkManager, serviceProvider, currentTenant, abpDistributedLock, distributedEventBus, loggerFactory)
{
DataSeeder = dataSeeder;
}
protected async override Task SeedAsync()
{
// DbMigrator迁移数据种子
await DataSeeder.SeedAsync(new DataSeedContext());
}
}

13
aspnet-core/aspire/LINGYUN.Abp.MicroService.AdminService/AdminServiceModule.cs

@ -36,13 +36,11 @@ using Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy;
using Volo.Abp.AspNetCore.Serilog;
using Volo.Abp.Autofac;
using Volo.Abp.Caching.StackExchangeRedis;
using Volo.Abp.Data;
using Volo.Abp.Http.Client;
using Volo.Abp.Modularity;
using Volo.Abp.PermissionManagement.Identity;
using Volo.Abp.PermissionManagement.OpenIddict;
using Volo.Abp.Swashbuckle;
using Volo.Abp.Threading;
namespace LINGYUN.Abp.MicroService.AdminService;
@ -143,15 +141,4 @@ public partial class AdminServiceModule : AbpModule
ConfigureDistributedLocking(context.Services, configuration);
ConfigureSecurity(context.Services, configuration, hostingEnvironment.IsDevelopment());
}
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
AsyncHelper.RunSync(() => OnApplicationInitializationAsync(context));
}
public async override Task OnApplicationInitializationAsync(ApplicationInitializationContext context)
{
await context.ServiceProvider
.GetRequiredService<IDataSeeder>()
.SeedAsync();
}
}

29
aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer.DbMigrator/appsettings.json

@ -1,5 +1,34 @@
{
"ConnectionStrings": {
"Default": "Host=127.0.0.1;Database=abp;Username=postgres;Password=123456"
},
"OpenIddict": {
"Applications": {
"VueAdmin": {
"ClientId": "vue-admin-client",
"ClientSecret": "1q2w3e*",
"RootUrls": [ "http://localhost:5666" ]
},
"InternalService": {
"ClientId": "InternalServiceClient",
"ClientSecret": "1q2w3e*"
},
"VueOAuthClient": {
"ClientId": "vue-oauth-client",
"RootUrls": [
"http://localhost:5666",
"http://localhost:30000",
"http://localhost:30010",
"http://localhost:30015",
"http://localhost:30020",
"http://localhost:30025",
"http://localhost:30030",
"http://localhost:30040",
"http://localhost:30045",
"http://localhost:30050",
"http://localhost:30060"
]
}
}
}
}

35
aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer.EntityFrameworkCore/AuthServerDataSeeder.cs

@ -0,0 +1,35 @@
using LINGYUN.Abp.MicroService.AuthServer.DataSeeds;
using System.Threading.Tasks;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.MultiTenancy;
namespace LINGYUN.Abp.MicroService.AuthServer;
public class AuthServerDataSeeder : ITransientDependency
{
protected ICurrentTenant CurrentTenant { get; }
protected OpenIddictDataSeeder OpenIddictDataSeeder { get; }
protected IdentityClaimTypeDataSeeder IdentityClaimTypeDataSeeder { get; }
protected IdentityUserRoleDataSeeder IdentityUserRoleDataSeeder { get; }
public AuthServerDataSeeder(
ICurrentTenant currentTenant,
OpenIddictDataSeeder openIddictDataSeeder,
IdentityClaimTypeDataSeeder identityClaimTypeDataSeeder,
IdentityUserRoleDataSeeder identityUserRoleDataSeeder)
{
CurrentTenant = currentTenant;
OpenIddictDataSeeder = openIddictDataSeeder;
IdentityClaimTypeDataSeeder = identityClaimTypeDataSeeder;
IdentityUserRoleDataSeeder = identityUserRoleDataSeeder;
}
public virtual async Task SeedAsync(DataSeedContext context)
{
using (CurrentTenant.Change(context.TenantId))
{
await OpenIddictDataSeeder.SeedAsync(context);
await IdentityClaimTypeDataSeeder.SeedAsync(context);
await IdentityUserRoleDataSeeder.SeedAsync(context);
}
}
}

109
aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer.EntityFrameworkCore/AuthServerDbMigrationEventHandler.cs

@ -1,28 +1,17 @@
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using Microsoft.Extensions.Logging;
using System.Threading.Tasks;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Data;
using Volo.Abp.DistributedLocking;
using Volo.Abp.EntityFrameworkCore.Migrations;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.Guids;
using Volo.Abp.Identity;
using Volo.Abp.MultiTenancy;
using Volo.Abp.PermissionManagement;
using Volo.Abp.Uow;
using IdentityPermissions = Volo.Abp.Identity.IdentityPermissions;
namespace LINGYUN.Abp.MicroService.AuthServer;
public class AuthServerDbMigrationEventHandler : EfCoreDatabaseMigrationEventHandlerBase<AuthServerMigrationsDbContext>
{
protected IGuidGenerator GuidGenerator { get; }
protected IdentityUserManager IdentityUserManager { get; }
protected IdentityRoleManager IdentityRoleManager { get; }
protected IPermissionDataSeeder PermissionDataSeeder { get; }
protected AuthServerDataSeeder DataSeeder { get; }
public AuthServerDbMigrationEventHandler(
ICurrentTenant currentTenant,
@ -31,102 +20,26 @@ public class AuthServerDbMigrationEventHandler : EfCoreDatabaseMigrationEventHan
IAbpDistributedLock abpDistributedLock,
IDistributedEventBus distributedEventBus,
ILoggerFactory loggerFactory,
IGuidGenerator guidGenerator,
IdentityUserManager identityUserManager,
IdentityRoleManager identityRoleManager,
IPermissionDataSeeder permissionDataSeeder)
AuthServerDataSeeder dataSeeder)
: base(
ConnectionStringNameAttribute.GetConnStringName<AuthServerMigrationsDbContext>(),
currentTenant, unitOfWorkManager, tenantStore, abpDistributedLock, distributedEventBus, loggerFactory)
{
GuidGenerator = guidGenerator;
IdentityUserManager = identityUserManager;
IdentityRoleManager = identityRoleManager;
PermissionDataSeeder = permissionDataSeeder;
DataSeeder = dataSeeder;
}
protected async override Task AfterTenantCreated(TenantCreatedEto eventData, bool schemaMigrated)
{
if (!schemaMigrated)
// 新租户数据种子
var context = new DataSeedContext(eventData.Id);
if (eventData.Properties != null)
{
return;
}
using (CurrentTenant.Change(eventData.Id))
{
await SeedTenantDefaultRoleAsync(eventData);
await SeedTenantAdminAsync(eventData);
}
}
protected async virtual Task SeedTenantDefaultRoleAsync(TenantCreatedEto eventData)
{
// 默认用户
var roleId = GuidGenerator.Create();
var defaultRole = new IdentityRole(roleId, "Users", eventData.Id)
{
IsStatic = true,
IsPublic = true,
IsDefault = true,
};
(await IdentityRoleManager.CreateAsync(defaultRole)).CheckErrors();
// 所有用户都应该具有查询用户权限, 用于IM场景
await PermissionDataSeeder.SeedAsync(
RolePermissionValueProvider.ProviderName,
defaultRole.Name,
new string[]
foreach (var property in eventData.Properties )
{
IdentityPermissions.UserLookup.Default,
IdentityPermissions.Users.Default
},
tenantId: eventData.Id);
}
protected async virtual Task SeedTenantAdminAsync(TenantCreatedEto eventData)
{
const string tenantAdminUserName = "admin";
const string tenantAdminRoleName = "admin";
Guid tenantAdminRoleId;
if (!await IdentityRoleManager.RoleExistsAsync(tenantAdminRoleName))
{
tenantAdminRoleId = GuidGenerator.Create();
var tenantAdminRole = new IdentityRole(tenantAdminRoleId, tenantAdminRoleName, eventData.Id)
{
IsStatic = true,
IsPublic = true
};
(await IdentityRoleManager.CreateAsync(tenantAdminRole)).CheckErrors();
}
else
{
var tenantAdminRole = await IdentityRoleManager.FindByNameAsync(tenantAdminRoleName);
tenantAdminRoleId = tenantAdminRole.Id;
context.WithProperty(property.Key, property.Value);
}
}
var adminUserId = GuidGenerator.Create();
if (eventData.Properties.TryGetValue("AdminUserId", out var userIdString) &&
Guid.TryParse(userIdString, out var adminUserGuid))
{
adminUserId = adminUserGuid;
}
var adminEmailAddress = eventData.Properties.GetOrDefault("AdminEmail") ?? "admin@abp.io";
var adminPassword = eventData.Properties.GetOrDefault("AdminPassword") ?? "1q2w3E*";
var tenantAdminUser = await IdentityUserManager.FindByNameAsync(adminEmailAddress);
if (tenantAdminUser == null)
{
tenantAdminUser = new IdentityUser(
adminUserId,
tenantAdminUserName,
adminEmailAddress,
eventData.Id);
tenantAdminUser.AddRole(tenantAdminRoleId);
// 创建租户管理用户
(await IdentityUserManager.CreateAsync(tenantAdminUser)).CheckErrors();
(await IdentityUserManager.AddPasswordAsync(tenantAdminUser, adminPassword)).CheckErrors();
}
await DataSeeder.SeedAsync(context);
}
}

13
aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer.EntityFrameworkCore/AuthServerDbMigrationService.cs

@ -2,6 +2,7 @@
using LINGYUN.Abp.Saas.Tenants;
using Microsoft.Extensions.Logging;
using System;
using System.Threading.Tasks;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.DistributedLocking;
@ -13,8 +14,8 @@ namespace LINGYUN.Abp.MicroService.AuthServer;
public class AuthServerDbMigrationService : EfCoreRuntimeDbMigratorBase<AuthServerMigrationsDbContext>, ITransientDependency
{
protected AuthServerDataSeeder DataSeeder { get; }
public AuthServerDbMigrationService(
IDataSeeder dataSeeder,
IDbSchemaMigrator dbSchemaMigrator,
ITenantRepository tenantRepository,
ICurrentTenant currentTenant,
@ -22,10 +23,18 @@ public class AuthServerDbMigrationService : EfCoreRuntimeDbMigratorBase<AuthServ
IServiceProvider serviceProvider,
IAbpDistributedLock abpDistributedLock,
IDistributedEventBus distributedEventBus,
ILoggerFactory loggerFactory)
ILoggerFactory loggerFactory,
AuthServerDataSeeder dataSeeder)
: base(
ConnectionStringNameAttribute.GetConnStringName<AuthServerMigrationsDbContext>(),
unitOfWorkManager, serviceProvider, currentTenant, abpDistributedLock, distributedEventBus, loggerFactory)
{
DataSeeder = dataSeeder;
}
protected async override Task SeedAsync()
{
// DbMigrator迁移数据种子
await DataSeeder.SeedAsync(new DataSeedContext());
}
}

89
aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer.EntityFrameworkCore/DataSeeds/IdentityClaimTypeDataSeeder.cs

@ -0,0 +1,89 @@
using JetBrains.Annotations;
using Microsoft.Extensions.Logging;
using OpenIddict.Abstractions;
using System.Threading.Tasks;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Guids;
using Volo.Abp.Identity;
namespace LINGYUN.Abp.MicroService.AuthServer.DataSeeds;
public class IdentityClaimTypeDataSeeder : ITransientDependency
{
public ILogger<IdentityClaimTypeDataSeeder> Logger { protected get; set; }
protected IGuidGenerator GuidGenerator { get; }
protected IdentityClaimTypeManager IdentityClaimTypeManager { get; }
protected IIdentityClaimTypeRepository IdentityClaimTypeRepository { get; }
public IdentityClaimTypeDataSeeder(
IGuidGenerator guidGenerator,
IdentityClaimTypeManager identityClaimTypeManager,
IIdentityClaimTypeRepository identityClaimTypeRepository)
{
GuidGenerator = guidGenerator;
IdentityClaimTypeManager = identityClaimTypeManager;
IdentityClaimTypeRepository = identityClaimTypeRepository;
}
public async virtual Task SeedAsync(DataSeedContext context)
{
if (context.TenantId.HasValue)
{
return;
}
Logger.LogInformation("Seeding the default identity claim types...");
await CreateIdentityClaimTypeAsync(OpenIddictConstants.Claims.Address);
await CreateIdentityClaimTypeAsync(OpenIddictConstants.Claims.Birthdate, valueType: IdentityClaimValueType.DateTime);
await CreateIdentityClaimTypeAsync(OpenIddictConstants.Claims.Country);
await CreateIdentityClaimTypeAsync(OpenIddictConstants.Claims.Email);
await CreateIdentityClaimTypeAsync(OpenIddictConstants.Claims.EmailVerified, valueType: IdentityClaimValueType.Boolean);
await CreateIdentityClaimTypeAsync(OpenIddictConstants.Claims.FamilyName);
await CreateIdentityClaimTypeAsync(OpenIddictConstants.Claims.Gender);
await CreateIdentityClaimTypeAsync(OpenIddictConstants.Claims.GivenName);
await CreateIdentityClaimTypeAsync(OpenIddictConstants.Claims.Locale);
await CreateIdentityClaimTypeAsync(OpenIddictConstants.Claims.Locality);
await CreateIdentityClaimTypeAsync(OpenIddictConstants.Claims.MiddleName);
await CreateIdentityClaimTypeAsync(OpenIddictConstants.Claims.Name);
await CreateIdentityClaimTypeAsync(OpenIddictConstants.Claims.Nickname);
await CreateIdentityClaimTypeAsync(OpenIddictConstants.Claims.PhoneNumber);
await CreateIdentityClaimTypeAsync(OpenIddictConstants.Claims.PhoneNumberVerified, valueType: IdentityClaimValueType.Boolean);
await CreateIdentityClaimTypeAsync(OpenIddictConstants.Claims.Picture);
await CreateIdentityClaimTypeAsync(OpenIddictConstants.Claims.PostalCode);
await CreateIdentityClaimTypeAsync(OpenIddictConstants.Claims.PreferredUsername);
await CreateIdentityClaimTypeAsync(OpenIddictConstants.Claims.Profile);
await CreateIdentityClaimTypeAsync(OpenIddictConstants.Claims.Region);
await CreateIdentityClaimTypeAsync(OpenIddictConstants.Claims.Role);
await CreateIdentityClaimTypeAsync(OpenIddictConstants.Claims.StreetAddress);
await CreateIdentityClaimTypeAsync(OpenIddictConstants.Claims.Username);
await CreateIdentityClaimTypeAsync(OpenIddictConstants.Claims.Website);
await CreateIdentityClaimTypeAsync(OpenIddictConstants.Claims.Zoneinfo);
Logger.LogInformation("Seeding default identity claim types completed.");
}
private async Task CreateIdentityClaimTypeAsync(
[NotNull] string name,
bool required = false,
bool isStatic = false,
[CanBeNull] string regex = null,
[CanBeNull] string regexDescription = null,
[CanBeNull] string description = null,
IdentityClaimValueType valueType = IdentityClaimValueType.String)
{
if (!await IdentityClaimTypeRepository.AnyAsync(name))
{
await IdentityClaimTypeManager.CreateAsync(
new IdentityClaimType(
GuidGenerator.Create(),
name,
required,
isStatic,
regex,
regexDescription,
description,
valueType));
}
}
}

124
aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer.EntityFrameworkCore/DataSeeds/IdentityUserRoleDataSeeder.cs

@ -0,0 +1,124 @@
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Options;
using System;
using System.Threading.Tasks;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Guids;
using Volo.Abp.Identity;
namespace LINGYUN.Abp.MicroService.AuthServer.DataSeeds;
public class IdentityUserRoleDataSeeder : ITransientDependency
{
public const string AdminUserIdPropertyName = "AdminUserId";
public const string AdminEmailPropertyName = "AdminEmail";
public const string AdminEmailDefaultValue = "admin@abp.io";
public const string AdminUserNamePropertyName = "AdminUserName";
public const string AdminUserNameDefaultValue = "admin";
public const string AdminPasswordPropertyName = "AdminPassword";
public const string AdminPasswordDefaultValue = "1q2w3E*";
protected IGuidGenerator GuidGenerator { get; }
protected IIdentityRoleRepository RoleRepository { get; }
protected IIdentityUserRepository UserRepository { get; }
protected ILookupNormalizer LookupNormalizer { get; }
protected IdentityUserManager UserManager { get; }
protected IdentityRoleManager RoleManager { get; }
protected IOptions<IdentityOptions> IdentityOptions { get; }
public IdentityUserRoleDataSeeder(
IGuidGenerator guidGenerator,
IIdentityRoleRepository roleRepository,
IIdentityUserRepository userRepository,
ILookupNormalizer lookupNormalizer,
IdentityUserManager userManager,
IdentityRoleManager roleManager,
IOptions<IdentityOptions> identityOptions)
{
GuidGenerator = guidGenerator;
RoleRepository = roleRepository;
UserRepository = userRepository;
LookupNormalizer = lookupNormalizer;
UserManager = userManager;
RoleManager = roleManager;
IdentityOptions = identityOptions;
}
public virtual async Task SeedAsync(DataSeedContext context)
{
await SeedAdminUserAsync(context);
await SeedDefaultRoleAsync(context);
}
private async Task SeedAdminUserAsync(DataSeedContext context)
{
await IdentityOptions.SetAsync();
const string adminRoleName = "admin";
var adminUserName = context?[AdminUserNamePropertyName] as string ?? AdminUserNameDefaultValue;
Guid adminRoleId;
if (!await RoleManager.RoleExistsAsync(adminRoleName))
{
adminRoleId = GuidGenerator.Create();
var adminRole = new IdentityRole(
adminRoleId,
adminRoleName,
context.TenantId)
{
IsStatic = true,
IsPublic = true
};
(await RoleManager.CreateAsync(adminRole)).CheckErrors();
}
else
{
var adminRole = await RoleManager.FindByNameAsync(adminRoleName);
adminRoleId = adminRole.Id;
}
var adminUserId = GuidGenerator.Create();
if (context.Properties.TryGetValue(AdminUserIdPropertyName, out var userIdString) &&
Guid.TryParse(userIdString?.ToString(), out var adminUserGuid))
{
adminUserId = adminUserGuid;
}
var adminEmailAddress = context?[AdminEmailPropertyName] as string ?? AdminEmailDefaultValue;
var adminPassword = context?[AdminPasswordPropertyName] as string ?? AdminPasswordDefaultValue;
var adminUser = await UserManager.FindByNameAsync(adminUserName);
if (adminUser == null)
{
adminUser = new IdentityUser(
adminUserId,
adminUserName,
adminEmailAddress,
context.TenantId);
adminUser.AddRole(adminRoleId);
// 创建租户管理用户
(await UserManager.CreateAsync(adminUser)).CheckErrors();
(await UserManager.AddPasswordAsync(adminUser, adminPassword)).CheckErrors();
}
}
private async Task SeedDefaultRoleAsync(DataSeedContext context)
{
const string defaultRoleName = "Users";
if (await RoleManager.FindByNameAsync(defaultRoleName) != null)
{
var roleId = GuidGenerator.Create();
var defaultRole = new IdentityRole(
roleId,
defaultRoleName,
context.TenantId)
{
IsStatic = true,
IsPublic = true,
IsDefault = true,
};
(await RoleManager.CreateAsync(defaultRole)).CheckErrors();
}
}
}

255
aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer/DataSeeder/OpenIddictDataSeederContributor.cs → aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer.EntityFrameworkCore/DataSeeds/OpenIddictDataSeeder.cs

@ -14,13 +14,12 @@ using Volo.Abp.OpenIddict.Applications;
using Volo.Abp.OpenIddict.Scopes;
using Volo.Abp.PermissionManagement;
namespace LINGYUN.Abp.MicroService.AuthServer.DataSeeder;
public class OpenIddictDataSeederContributor : OpenIddictDataSeedContributorBase, IDataSeedContributor, ITransientDependency
namespace LINGYUN.Abp.MicroService.AuthServer.DataSeeds;
public class OpenIddictDataSeeder : OpenIddictDataSeedContributorBase, ITransientDependency
{
public ILogger<OpenIddictDataSeederContributor> Logger { protected get; set; }
public ILogger<OpenIddictDataSeeder> Logger { protected get; set; }
protected IPermissionDataSeeder PermissionDataSeeder { get; }
public OpenIddictDataSeederContributor(
public OpenIddictDataSeeder(
IConfiguration configuration,
IOpenIddictApplicationRepository openIddictApplicationRepository,
IAbpApplicationManager applicationManager,
@ -31,7 +30,7 @@ public class OpenIddictDataSeederContributor : OpenIddictDataSeedContributorBase
{
PermissionDataSeeder = permissionDataSeeder;
Logger = NullLogger<OpenIddictDataSeederContributor>.Instance;
Logger = NullLogger<OpenIddictDataSeeder>.Instance;
}
public async virtual Task SeedAsync(DataSeedContext context)
@ -54,17 +53,17 @@ public class OpenIddictDataSeederContributor : OpenIddictDataSeedContributorBase
private async Task CreateDefaultScopeAsync()
{
// OpenID Connect核心scope - 用于标识这是一个OIDC请求
// OpenId Connect
await CreateScopesAsync(new OpenIddictScopeDescriptor
{
Name = OpenIddictConstants.Scopes.OpenId,
DisplayName = "OpenID Connect", // 友好的显示名称
DisplayName = "OpenId Connect",
DisplayNames =
{
[CultureInfo.GetCultureInfo("zh-Hans")] = "身份认证",
[CultureInfo.GetCultureInfo("en")] = "OpenID Connect"
[CultureInfo.GetCultureInfo("en")] = "OpenId Connect"
},
Description = "使用OpenID Connect协议进行身份验证",
Description = "OpenId Connect协议进行身份验证",
Descriptions =
{
[CultureInfo.GetCultureInfo("zh-Hans")] = "允许应用程序使用您的身份信息进行登录",
@ -72,7 +71,7 @@ public class OpenIddictDataSeederContributor : OpenIddictDataSeedContributorBase
}
});
// Profile scope - 用户基本信息
// Profile
await CreateScopesAsync(new OpenIddictScopeDescriptor
{
Name = OpenIddictConstants.Scopes.Profile,
@ -90,7 +89,7 @@ public class OpenIddictDataSeederContributor : OpenIddictDataSeedContributorBase
}
});
// Email scope
// Email
await CreateScopesAsync(new OpenIddictScopeDescriptor
{
Name = OpenIddictConstants.Scopes.Email,
@ -108,7 +107,7 @@ public class OpenIddictDataSeederContributor : OpenIddictDataSeedContributorBase
}
});
// Phone scope
// Phone
await CreateScopesAsync(new OpenIddictScopeDescriptor
{
Name = OpenIddictConstants.Scopes.Phone,
@ -126,7 +125,7 @@ public class OpenIddictDataSeederContributor : OpenIddictDataSeedContributorBase
}
});
// Address scope
// Address
await CreateScopesAsync(new OpenIddictScopeDescriptor
{
Name = OpenIddictConstants.Scopes.Address,
@ -144,7 +143,7 @@ public class OpenIddictDataSeederContributor : OpenIddictDataSeedContributorBase
}
});
// Roles scope
// Roles
await CreateScopesAsync(new OpenIddictScopeDescriptor
{
Name = OpenIddictConstants.Scopes.Roles,
@ -162,7 +161,7 @@ public class OpenIddictDataSeederContributor : OpenIddictDataSeedContributorBase
}
});
// Offline Access scope - 用于获取刷新令牌
// OfflineAccess
await CreateScopesAsync(new OpenIddictScopeDescriptor
{
Name = OpenIddictConstants.Scopes.OfflineAccess,
@ -183,6 +182,7 @@ public class OpenIddictDataSeederContributor : OpenIddictDataSeedContributorBase
private async Task CreateApiScopeAsync(string scope)
{
// 前端汇总授权范围
await CreateScopesAsync(new OpenIddictScopeDescriptor
{
Name = scope,
@ -213,6 +213,216 @@ public class OpenIddictDataSeederContributor : OpenIddictDataSeedContributorBase
"workflow-service",
}
});
// ApiGateway Swagger
await CreateScopesAsync(new OpenIddictScopeDescriptor
{
Name = "api-gateway",
DisplayName = "Api Gateway",
DisplayNames =
{
[CultureInfo.GetCultureInfo("zh-Hans")] = "应用程序接口网关",
[CultureInfo.GetCultureInfo("en")] = "Api Gateway"
},
Description = "适用于应用程序接口网关Swagger授权",
Descriptions =
{
[CultureInfo.GetCultureInfo("zh-Hans")] = "适用于应用程序接口网关Swagger授权",
[CultureInfo.GetCultureInfo("en")] = "Applicable to application Programming interface gateway Swagger authorization"
},
Resources =
{
"api-gateway",
}
});
// Admin Service
await CreateScopesAsync(new OpenIddictScopeDescriptor
{
Name = "admin-service",
DisplayName = "Admin Service",
DisplayNames =
{
[CultureInfo.GetCultureInfo("zh-Hans")] = "后台管理服务",
[CultureInfo.GetCultureInfo("en")] = "Admin Service"
},
Description = "适用于后台管理服务Swagger授权",
Descriptions =
{
[CultureInfo.GetCultureInfo("zh-Hans")] = "适用于后台管理服务Swagger授权",
[CultureInfo.GetCultureInfo("en")] = "Applicable to the back-end management service Swagger authorization"
},
Resources =
{
"admin-service",
}
});
// Identity Service
await CreateScopesAsync(new OpenIddictScopeDescriptor
{
Name = "identity-service",
DisplayName = "Identity Service",
DisplayNames =
{
[CultureInfo.GetCultureInfo("zh-Hans")] = "身份认证服务",
[CultureInfo.GetCultureInfo("en")] = "Identity Service"
},
Description = "适用于身份认证服务Swagger授权",
Descriptions =
{
[CultureInfo.GetCultureInfo("zh-Hans")] = "适用于身份认证服务Swagger授权",
[CultureInfo.GetCultureInfo("en")] = "Applicable to the identity service Swagger authorization"
},
Resources =
{
"identity-service",
}
});
// Localization Service
await CreateScopesAsync(new OpenIddictScopeDescriptor
{
Name = "localization-service",
DisplayName = "Localization Service",
DisplayNames =
{
[CultureInfo.GetCultureInfo("zh-Hans")] = "本地化管理服务",
[CultureInfo.GetCultureInfo("en")] = "Localization Service"
},
Description = "适用于本地化管理服务Swagger授权",
Descriptions =
{
[CultureInfo.GetCultureInfo("zh-Hans")] = "适用于本地化管理服务Swagger授权",
[CultureInfo.GetCultureInfo("en")] = "Applicable to the Localization service Swagger authorization"
},
Resources =
{
"localization-service",
}
});
// Message Service
await CreateScopesAsync(new OpenIddictScopeDescriptor
{
Name = "message-service",
DisplayName = "Message Service",
DisplayNames =
{
[CultureInfo.GetCultureInfo("zh-Hans")] = "消息管理服务",
[CultureInfo.GetCultureInfo("en")] = "Message Service"
},
Description = "适用于消息管理服务Swagger授权",
Descriptions =
{
[CultureInfo.GetCultureInfo("zh-Hans")] = "适用于消息管理服务Swagger授权",
[CultureInfo.GetCultureInfo("en")] = "Applicable to the Message service Swagger authorization"
},
Resources =
{
"message-service",
}
});
// Platform Service
await CreateScopesAsync(new OpenIddictScopeDescriptor
{
Name = "platform-service",
DisplayName = "Platform Service",
DisplayNames =
{
[CultureInfo.GetCultureInfo("zh-Hans")] = "平台管理服务",
[CultureInfo.GetCultureInfo("en")] = "Platform Service"
},
Description = "适用于平台管理服务Swagger授权",
Descriptions =
{
[CultureInfo.GetCultureInfo("zh-Hans")] = "适用于平台管理服务Swagger授权",
[CultureInfo.GetCultureInfo("en")] = "Applicable to the Platform service Swagger authorization"
},
Resources =
{
"platform-service",
}
});
// Task Service
await CreateScopesAsync(new OpenIddictScopeDescriptor
{
Name = "task-service",
DisplayName = "Task Service",
DisplayNames =
{
[CultureInfo.GetCultureInfo("zh-Hans")] = "任务管理服务",
[CultureInfo.GetCultureInfo("en")] = "Task Service"
},
Description = "适用于任务管理服务Swagger授权",
Descriptions =
{
[CultureInfo.GetCultureInfo("zh-Hans")] = "适用于任务管理服务Swagger授权",
[CultureInfo.GetCultureInfo("en")] = "Applicable to the Task service Swagger authorization"
},
Resources =
{
"task-service",
}
});
// Webhook Service
await CreateScopesAsync(new OpenIddictScopeDescriptor
{
Name = "webhook-service",
DisplayName = "Webhook Service",
DisplayNames =
{
[CultureInfo.GetCultureInfo("zh-Hans")] = "Webhook管理服务",
[CultureInfo.GetCultureInfo("en")] = "Webhook Service"
},
Description = "适用于Webhook管理服务Swagger授权",
Descriptions =
{
[CultureInfo.GetCultureInfo("zh-Hans")] = "适用于Webhook管理服务Swagger授权",
[CultureInfo.GetCultureInfo("en")] = "Applicable to the Webhook service Swagger authorization"
},
Resources =
{
"webhook-service",
}
});
// Wechat Service
await CreateScopesAsync(new OpenIddictScopeDescriptor
{
Name = "wechat-service",
DisplayName = "Wechat Service",
DisplayNames =
{
[CultureInfo.GetCultureInfo("zh-Hans")] = "微信管理服务",
[CultureInfo.GetCultureInfo("en")] = "Wechat Service"
},
Description = "适用于微信管理服务Swagger授权",
Descriptions =
{
[CultureInfo.GetCultureInfo("zh-Hans")] = "适用于微信管理服务Swagger授权",
[CultureInfo.GetCultureInfo("en")] = "Applicable to the Wechat service Swagger authorization"
},
Resources =
{
"wechat-service",
}
});
// Workflow Service
await CreateScopesAsync(new OpenIddictScopeDescriptor
{
Name = "workflow-service",
DisplayName = "Workflow Service",
DisplayNames =
{
[CultureInfo.GetCultureInfo("zh-Hans")] = "工作流管理服务",
[CultureInfo.GetCultureInfo("en")] = "Workflow Service"
},
Description = "适用于工作流管理服务Swagger授权",
Descriptions =
{
[CultureInfo.GetCultureInfo("zh-Hans")] = "适用于工作流管理服务Swagger授权",
[CultureInfo.GetCultureInfo("en")] = "Applicable to the Workflow service Swagger authorization"
},
Resources =
{
"workflow-service",
}
});
}
private async Task CreateApplicationAsync(string scope)
@ -316,7 +526,18 @@ public class OpenIddictDataSeederContributor : OpenIddictDataSeedContributorBase
OpenIddictConstants.Scopes.Phone,
OpenIddictConstants.Scopes.Profile,
OpenIddictConstants.Scopes.OfflineAccess,
scope],
scope,
"api-gateway",
"auth-server",
"admin-service",
"identity-service",
"localization-service",
"message-service",
"platform-service",
"task-service",
"webhook-service",
"wechat-service",
"workflow-service"],
oauthClientRedirectUrls,
oauthClientPostLogoutRedirectUrls);

16
aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer/AuthServerModule.cs

@ -25,19 +25,15 @@ using LINGYUN.Abp.OpenIddict.WeChat.Work;
using LINGYUN.Abp.Serilog.Enrichers.Application;
using LINGYUN.Abp.Serilog.Enrichers.UniqueId;
using LINGYUN.Abp.Sms.Platform;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonXLite;
using Volo.Abp.AspNetCore.Serilog;
using Volo.Abp.Autofac;
using Volo.Abp.Caching.StackExchangeRedis;
using Volo.Abp.Data;
using Volo.Abp.Modularity;
using Volo.Abp.PermissionManagement.Identity;
using Volo.Abp.Threading;
namespace LINGYUN.Abp.MicroService.AuthServer;
@ -119,16 +115,4 @@ public partial class AuthServerModule : AbpModule
ConfigureDistributedLocking(context.Services, configuration);
ConfigureSecurity(context.Services, configuration, hostingEnvironment.IsDevelopment());
}
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
AsyncHelper.RunSync(() => OnApplicationInitializationAsync(context));
}
public async override Task OnApplicationInitializationAsync(ApplicationInitializationContext context)
{
await context.ServiceProvider
.GetRequiredService<IDataSeeder>()
.SeedAsync();
}
}

9
aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer/LINGYUN.Abp.MicroService.AuthServer.csproj

@ -78,10 +78,6 @@
<ProjectReference Include="..\LINGYUN.Abp.MicroService.ServiceDefaults\LINGYUN.Abp.MicroService.ServiceDefaults.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="wwwroot\" />
</ItemGroup>
<Target Name="RestoreNpmPackages" BeforeTargets="BeforeBuild">
<Message Text="正在执行 abp install-libs ..." Importance="high" />
@ -89,10 +85,7 @@
<PackageJsonPath>$(MSBuildProjectDirectory)\package.json</PackageJsonPath>
</PropertyGroup>
<Exec Command="abp install-libs"
Condition="Exists('$(PackageJsonPath)')"
WorkingDirectory="$(MSBuildProjectDirectory)"
IgnoreExitCode="false" />
<Exec Command="abp install-libs" Condition="Exists('$(PackageJsonPath)')" WorkingDirectory="$(MSBuildProjectDirectory)" IgnoreExitCode="false" />
</Target>
</Project>

29
aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer/appsettings.Development.json

@ -93,35 +93,6 @@
"MapInboundClaims": false,
"RequireHttpsMetadata": false
},
"OpenIddict": {
"Applications": {
"VueAdmin": {
"ClientId": "vue-admin-client",
"ClientSecret": "1q2w3e*",
"RootUrls": ["http://localhost:5666"]
},
"InternalService": {
"ClientId": "InternalServiceClient",
"ClientSecret": "1q2w3e*"
},
"VueOAuthClient": {
"ClientId": "vue-oauth-client",
"RootUrls": [
"http://localhost:5666",
"http://localhost:30000",
"http://localhost:30010",
"http://localhost:30015",
"http://localhost:30020",
"http://localhost:30025",
"http://localhost:30030",
"http://localhost:30040",
"http://localhost:30045",
"http://localhost:30050",
"http://localhost:30060"
]
}
}
},
"Identity": {
"Password": {
"RequiredLength": 6,

6
aspnet-core/aspire/LINGYUN.Abp.MicroService.IdentityService/IdentityServiceModule.cs

@ -128,10 +128,4 @@ public partial class IdentityServiceModule : AbpModule
ConfigureDistributedLocking(context.Services, configuration);
ConfigureSecurity(context.Services, configuration, hostingEnvironment.IsDevelopment());
}
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
var app = context.GetApplicationBuilder();
}
}

1
aspnet-core/aspire/LINGYUN.Abp.MicroService.PlatformService.EntityFrameworkCore/LINGYUN.Abp.MicroService.PlatformService.EntityFrameworkCore.csproj

@ -25,6 +25,7 @@
<ProjectReference Include="..\..\framework\navigation\LINGYUN.Abp.UI.Navigation\LINGYUN.Abp.UI.Navigation.csproj" />
<ProjectReference Include="..\..\modules\platform\LINGYUN.Platform.EntityFrameworkCore\LINGYUN.Platform.EntityFrameworkCore.csproj" />
<ProjectReference Include="..\..\modules\saas\LINGYUN.Abp.Saas.EntityFrameworkCore\LINGYUN.Abp.Saas.EntityFrameworkCore.csproj" />
<ProjectReference Include="..\..\modules\platform\LINGYUN.Abp.UI.Navigation.VueVbenAdmin5\LINGYUN.Abp.UI.Navigation.VueVbenAdmin5.csproj" />
</ItemGroup>
</Project>

47
aspnet-core/aspire/LINGYUN.Abp.MicroService.PlatformService.EntityFrameworkCore/PlatformServiceDataSeeder.cs

@ -0,0 +1,47 @@
using LINGYUN.Abp.UI.Navigation;
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.MultiTenancy;
namespace LINGYUN.Abp.MicroService.PlatformService;
public class PlatformServiceDataSeeder : ITransientDependency
{
protected IEnumerable<INavigationSeedContributor> NavigationSeedContributors { get; }
protected INavigationProvider NavigationProvider { get; }
protected ICurrentTenant CurrentTenant { get; }
public PlatformServiceDataSeeder(
IEnumerable<INavigationSeedContributor> navigationSeedContributors,
INavigationProvider navigationProvider,
ICurrentTenant currentTenant)
{
NavigationSeedContributors = navigationSeedContributors;
NavigationProvider = navigationProvider;
CurrentTenant = currentTenant;
}
public async virtual Task SeedAsync(DataSeedContext context)
{
using (CurrentTenant.Change(context.TenantId))
{
await SeedNavigationAsync();
}
}
private async Task SeedNavigationAsync()
{
var menus = await NavigationProvider.GetAllAsync();
var multiTenancySides = CurrentTenant.IsAvailable
? MultiTenancySides.Tenant
: MultiTenancySides.Host;
var seedContext = new NavigationSeedContext(menus, multiTenancySides);
foreach (var contributor in NavigationSeedContributors)
{
await contributor.SeedAsync(seedContext);
}
}
}

35
aspnet-core/aspire/LINGYUN.Abp.MicroService.PlatformService.EntityFrameworkCore/PlatformServiceDbMigrationEventHandler.cs

@ -1,10 +1,8 @@
using LINGYUN.Abp.Saas.Tenants;
using LINGYUN.Abp.UI.Navigation;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Linq;
using System.Threading.Tasks;
@ -12,7 +10,6 @@ using Volo.Abp.Data;
using Volo.Abp.DistributedLocking;
using Volo.Abp.EntityFrameworkCore.Migrations;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.Features;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Uow;
@ -21,9 +18,7 @@ public class PlatformServiceDbMigrationEventHandler :
EfCoreDatabaseMigrationEventHandlerBase<PlatformServiceMigrationsDbContext>,
IDistributedEventHandler<TenantDeletedEto>
{
protected IEnumerable<INavigationSeedContributor> NavigationSeedContributors { get; }
protected INavigationProvider NavigationProvider { get; }
protected IFeatureChecker FeatureChecker { get; }
protected PlatformServiceDataSeeder DataSeeder { get; }
protected IConfiguration Configuration { get; }
public PlatformServiceDbMigrationEventHandler(
ICurrentTenant currentTenant,
@ -32,37 +27,29 @@ public class PlatformServiceDbMigrationEventHandler :
IAbpDistributedLock abpDistributedLock,
IDistributedEventBus distributedEventBus,
ILoggerFactory loggerFactory,
IFeatureChecker featureChecker,
IConfiguration configuration,
INavigationProvider navigationProvider,
IEnumerable<INavigationSeedContributor> navigationSeedContributors)
PlatformServiceDataSeeder dataSeeder)
: base(
ConnectionStringNameAttribute.GetConnStringName<PlatformServiceMigrationsDbContext>(),
currentTenant, unitOfWorkManager, tenantStore, abpDistributedLock, distributedEventBus, loggerFactory)
{
FeatureChecker = featureChecker;
Configuration = configuration;
NavigationProvider = navigationProvider;
NavigationSeedContributors = navigationSeedContributors;
DataSeeder = dataSeeder;
}
protected async override Task SeedAsync(Guid? tenantId)
protected async override Task AfterTenantCreated(TenantCreatedEto eventData, bool schemaMigrated)
{
using (CurrentTenant.Change(tenantId))
// 新租户数据种子
var context = new DataSeedContext(eventData.Id);
if (eventData.Properties != null)
{
var menus = await NavigationProvider.GetAllAsync();
var multiTenancySides = CurrentTenant.IsAvailable
? MultiTenancySides.Tenant
: MultiTenancySides.Host;
var seedContext = new NavigationSeedContext(menus, multiTenancySides);
foreach (var contributor in NavigationSeedContributors)
foreach (var property in eventData.Properties)
{
await contributor.SeedAsync(seedContext);
context.WithProperty(property.Key, property.Value);
}
}
await DataSeeder.SeedAsync(context);
}
public async virtual Task HandleEventAsync(TenantDeletedEto eventData)

12
aspnet-core/aspire/LINGYUN.Abp.MicroService.PlatformService.EntityFrameworkCore/PlatformServiceDbMigrationService.cs

@ -1,6 +1,7 @@
using LINGYUN.Abp.Data.DbMigrator;
using Microsoft.Extensions.Logging;
using System;
using System.Threading.Tasks;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.DistributedLocking;
@ -11,16 +12,25 @@ using Volo.Abp.Uow;
namespace LINGYUN.Abp.MicroService.PlatformService;
public class PlatformServiceDbMigrationService : EfCoreRuntimeDbMigratorBase<PlatformServiceMigrationsDbContext>, ITransientDependency
{
protected PlatformServiceDataSeeder DataSeeder { get; }
public PlatformServiceDbMigrationService(
ICurrentTenant currentTenant,
IUnitOfWorkManager unitOfWorkManager,
IServiceProvider serviceProvider,
IAbpDistributedLock abpDistributedLock,
IDistributedEventBus distributedEventBus,
ILoggerFactory loggerFactory)
ILoggerFactory loggerFactory,
PlatformServiceDataSeeder dataSeeder)
: base(
ConnectionStringNameAttribute.GetConnStringName<PlatformServiceMigrationsDbContext>(),
unitOfWorkManager, serviceProvider, currentTenant, abpDistributedLock, distributedEventBus, loggerFactory)
{
DataSeeder = dataSeeder;
}
protected async override Task SeedAsync()
{
// DbMigrator迁移数据种子
await DataSeeder.SeedAsync(new DataSeedContext());
}
}

4
aspnet-core/aspire/LINGYUN.Abp.MicroService.PlatformService.EntityFrameworkCore/PlatformServiceMigrationsEntityFrameworkCoreModule.cs

@ -1,6 +1,6 @@
using LINGYUN.Abp.Data.DbMigrator;
using LINGYUN.Abp.Saas.EntityFrameworkCore;
using LINGYUN.Abp.UI.Navigation;
using LINGYUN.Abp.UI.Navigation.VueVbenAdmin5;
using LINGYUN.Platform.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using System;
@ -14,7 +14,7 @@ using Volo.Abp.SettingManagement.EntityFrameworkCore;
namespace LINGYUN.Abp.MicroService.PlatformService;
[DependsOn(
typeof(AbpUINavigationModule),
typeof(AbpUINavigationVueVbenAdmin5Module),
typeof(AbpSaasEntityFrameworkCoreModule),
typeof(PlatformEntityFrameworkCoreModule),
typeof(AbpSettingManagementEntityFrameworkCoreModule),

2
aspnet-core/aspire/LINGYUN.Abp.MicroService.PlatformService/LINGYUN.Abp.MicroService.PlatformService.csproj

@ -72,11 +72,9 @@
<ProjectReference Include="..\..\modules\oss-management\LINGYUN.Abp.OssManagement.Tencent\LINGYUN.Abp.OssManagement.Tencent.csproj" />
<ProjectReference Include="..\..\modules\platform\LINGYUN.Abp.Emailing.Platform\LINGYUN.Abp.Emailing.Platform.csproj" />
<ProjectReference Include="..\..\modules\platform\LINGYUN.Abp.Sms.Platform\LINGYUN.Abp.Sms.Platform.csproj" />
<ProjectReference Include="..\..\modules\platform\LINGYUN.Abp.UI.Navigation.VueVbenAdmin5\LINGYUN.Abp.UI.Navigation.VueVbenAdmin5.csproj" />
<ProjectReference Include="..\..\modules\platform\LINGYUN.Platform.Application\LINGYUN.Platform.Application.csproj" />
<ProjectReference Include="..\..\modules\platform\LINGYUN.Platform.EntityFrameworkCore\LINGYUN.Platform.EntityFrameworkCore.csproj" />
<ProjectReference Include="..\..\modules\platform\LINGYUN.Platform.HttpApi\LINGYUN.Platform.HttpApi.csproj" />
<ProjectReference Include="..\..\modules\platform\LINGYUN.Platform.Theme.VueVbenAdmin\LINGYUN.Platform.Theme.VueVbenAdmin.csproj" />
<ProjectReference Include="..\..\modules\realtime-notifications\LINGYUN.Abp.Notifications\LINGYUN.Abp.Notifications.csproj" />
<ProjectReference Include="..\..\modules\saas\LINGYUN.Abp.Saas.EntityFrameworkCore\LINGYUN.Abp.Saas.EntityFrameworkCore.csproj" />
</ItemGroup>

9
aspnet-core/aspire/LINGYUN.Abp.MicroService.PlatformService/PlatformServiceModule.cs

@ -25,11 +25,9 @@ using LINGYUN.Abp.Saas.EntityFrameworkCore;
using LINGYUN.Abp.Serilog.Enrichers.Application;
using LINGYUN.Abp.Serilog.Enrichers.UniqueId;
using LINGYUN.Abp.Sms.Aliyun;
using LINGYUN.Abp.UI.Navigation.VueVbenAdmin5;
using LINGYUN.Platform;
using LINGYUN.Platform.EntityFrameworkCore;
using LINGYUN.Platform.HttpApi;
using LINGYUN.Platform.Theme.VueVbenAdmin;
using Microsoft.Extensions.Options;
using Volo.Abp;
using Volo.Abp.AspNetCore.Authentication.JwtBearer;
@ -38,7 +36,6 @@ using Volo.Abp.AspNetCore.Serilog;
using Volo.Abp.Autofac;
using Volo.Abp.BackgroundWorkers;
using Volo.Abp.Caching.StackExchangeRedis;
using Volo.Abp.Data;
using Volo.Abp.FeatureManagement.EntityFrameworkCore;
using Volo.Abp.Http.Client;
using Volo.Abp.Http.Client.IdentityModel.Web;
@ -60,8 +57,6 @@ namespace LINGYUN.Abp.MicroService.PlatformService;
typeof(AbpAuditLoggingElasticsearchModule),
typeof(AbpAspNetCoreMultiTenancyModule),
typeof(AbpAspNetCoreMvcLocalizationModule),
typeof(AbpUINavigationVueVbenAdmin5Module),
typeof(PlatformThemeVueVbenAdminModule),
typeof(AbpOssManagementAliyunModule), // 阿里云存储提供者模块
typeof(AbpOssManagementTencentModule), // 腾讯云存储提供者模块
typeof(AbpOssManagementNexusModule), // Nexus存储提供者模块
@ -151,10 +146,6 @@ public partial class PlatformServiceModule : AbpModule
public async override Task OnApplicationInitializationAsync(ApplicationInitializationContext context)
{
await context.ServiceProvider
.GetRequiredService<IDataSeeder>()
.SeedAsync();
var options = context.ServiceProvider.GetRequiredService<IOptions<AbpOssManagementOptions>>().Value;
if (options.IsCleanupEnabled)
{

139
aspnet-core/aspire/LINGYUN.Abp.MicroService.TaskService.EntityFrameworkCore/TaskServiceDataSeeder.cs

@ -0,0 +1,139 @@
using LINGYUN.Abp.BackgroundTasks;
using LINGYUN.Abp.BackgroundTasks.Internal;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.MultiTenancy;
namespace LINGYUN.Abp.MicroService.TaskService;
public class TaskServiceDataSeeder : ITransientDependency
{
protected AbpBackgroundTasksOptions Options { get; }
protected IJobStore JobStore { get; }
protected IJobScheduler JobScheduler { get; }
protected ICurrentTenant CurrentTenant { get; }
public TaskServiceDataSeeder(
IOptions<AbpBackgroundTasksOptions> options,
IJobStore jobStore,
IJobScheduler jobScheduler,
ICurrentTenant currentTenant)
{
Options = options.Value;
JobStore = jobStore;
JobScheduler = jobScheduler;
CurrentTenant = currentTenant;
}
public async virtual Task SeedAsync(DataSeedContext context)
{
if (context.TenantId.HasValue)
{
using (CurrentTenant.Change(context.TenantId))
{
await QueueBackgroundJobAsync(context.TenantId.Value);
}
}
}
public async virtual Task RemoveSeedAsync(Guid tenantId)
{
using (CurrentTenant.Change(tenantId))
{
var pollingJob = BuildPollingJobInfo(tenantId);
await JobScheduler.RemoveAsync(pollingJob);
await JobStore.RemoveAsync(pollingJob.Id);
var cleaningJob = BuildCleaningJobInfo(tenantId);
await JobScheduler.RemoveAsync(cleaningJob);
await JobStore.RemoveAsync(cleaningJob.Id);
var checkingJob = BuildCheckingJobInfo(tenantId);
await JobScheduler.RemoveAsync(checkingJob);
await JobStore.RemoveAsync(checkingJob.Id);
}
}
protected async virtual Task QueueBackgroundJobAsync(Guid tenantId)
{
var pollingJob = BuildPollingJobInfo(tenantId);
await JobStore.StoreAsync(pollingJob);
await JobScheduler.QueueAsync(pollingJob);
var cleaningJob = BuildCleaningJobInfo(tenantId);
await JobStore.StoreAsync(cleaningJob);
await JobScheduler.QueueAsync(cleaningJob);
var checkingJob = BuildCheckingJobInfo(tenantId);
await JobStore.StoreAsync(checkingJob);
await JobScheduler.QueueAsync(checkingJob);
}
protected virtual JobInfo BuildPollingJobInfo(Guid tenantId)
{
return new JobInfo
{
Id = tenantId.ToString() + "_Polling",
Name = nameof(BackgroundPollingJob),
Group = "Polling",
Description = "Polling tasks to be executed",
Args = new Dictionary<string, object>() { { nameof(JobInfo.TenantId), tenantId } },
Status = JobStatus.Running,
BeginTime = DateTime.Now,
CreationTime = DateTime.Now,
Cron = Options.JobFetchCronExpression,
JobType = JobType.Period,
Priority = JobPriority.High,
Source = JobSource.System,
LockTimeOut = Options.JobFetchLockTimeOut,
TenantId = tenantId,
Type = typeof(BackgroundPollingJob).AssemblyQualifiedName,
};
}
protected virtual JobInfo BuildCleaningJobInfo(Guid tenantId)
{
return new JobInfo
{
Id = tenantId.ToString() + "_Cleaning",
Name = nameof(BackgroundCleaningJob),
Group = "Cleaning",
Description = "Cleaning tasks to be executed",
Args = new Dictionary<string, object>() { { nameof(JobInfo.TenantId), tenantId } },
Status = JobStatus.Running,
BeginTime = DateTime.Now,
CreationTime = DateTime.Now,
Cron = Options.JobCleanCronExpression,
JobType = JobType.Period,
Priority = JobPriority.High,
Source = JobSource.System,
TenantId = tenantId,
Type = typeof(BackgroundCleaningJob).AssemblyQualifiedName,
};
}
protected virtual JobInfo BuildCheckingJobInfo(Guid tenantId)
{
return new JobInfo
{
Id = tenantId.ToString() + "_Checking",
Name = nameof(BackgroundCheckingJob),
Group = "Checking",
Description = "Checking tasks to be executed",
Args = new Dictionary<string, object>() { { nameof(JobInfo.TenantId), tenantId } },
Status = JobStatus.Running,
BeginTime = DateTime.Now,
CreationTime = DateTime.Now,
Cron = Options.JobCheckCronExpression,
LockTimeOut = Options.JobCheckLockTimeOut,
JobType = JobType.Period,
Priority = JobPriority.High,
Source = JobSource.System,
TenantId = tenantId,
Type = typeof(BackgroundCheckingJob).AssemblyQualifiedName,
};
}
}

122
aspnet-core/aspire/LINGYUN.Abp.MicroService.TaskService.EntityFrameworkCore/TaskServiceDbMigrationEventHandler.cs

@ -1,10 +1,5 @@
using LINGYUN.Abp.BackgroundTasks;
using LINGYUN.Abp.BackgroundTasks.Internal;
using LINGYUN.Abp.Saas.Tenants;
using LINGYUN.Abp.Saas.Tenants;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp.Data;
using Volo.Abp.DistributedLocking;
@ -19,9 +14,7 @@ public class TaskServiceDbMigrationEventHandler :
EfCoreDatabaseMigrationEventHandlerBase<TaskServiceMigrationsDbContext>,
IDistributedEventHandler<EntityDeletedEto<TenantEto>>
{
protected AbpBackgroundTasksOptions Options { get; }
protected IJobStore JobStore { get; }
protected IJobScheduler JobScheduler { get; }
protected TaskServiceDataSeeder DataSeeder { get; }
public TaskServiceDbMigrationEventHandler(
ICurrentTenant currentTenant,
@ -30,122 +23,33 @@ public class TaskServiceDbMigrationEventHandler :
IAbpDistributedLock abpDistributedLock,
IDistributedEventBus distributedEventBus,
ILoggerFactory loggerFactory,
IJobStore jobStore,
IJobScheduler jobScheduler,
IOptions<AbpBackgroundTasksOptions> options)
TaskServiceDataSeeder dataSeeder)
: base(
ConnectionStringNameAttribute.GetConnStringName<TaskServiceMigrationsDbContext>(),
currentTenant, unitOfWorkManager, tenantStore, abpDistributedLock, distributedEventBus, loggerFactory)
{
JobStore = jobStore;
JobScheduler = jobScheduler;
Options = options.Value;
DataSeeder = dataSeeder;
}
public async Task HandleEventAsync(EntityDeletedEto<TenantEto> eventData)
{
// 租户删除时移除轮询作业
var pollingJob = BuildPollingJobInfo(eventData.Entity.Id, eventData.Entity.Name);
await JobScheduler.RemoveAsync(pollingJob);
await JobStore.RemoveAsync(pollingJob.Id);
var cleaningJob = BuildCleaningJobInfo(eventData.Entity.Id, eventData.Entity.Name);
await JobScheduler.RemoveAsync(cleaningJob);
await JobStore.RemoveAsync(cleaningJob.Id);
var checkingJob = BuildCheckingJobInfo(eventData.Entity.Id, eventData.Entity.Name);
await JobScheduler.RemoveAsync(checkingJob);
await JobStore.RemoveAsync(checkingJob.Id);
await DataSeeder.RemoveSeedAsync(eventData.Entity.Id);
}
protected async override Task AfterTenantCreated(TenantCreatedEto eventData, bool schemaMigrated)
{
if (!schemaMigrated)
// 新租户数据种子
var context = new DataSeedContext(eventData.Id);
if (eventData.Properties != null)
{
return;
foreach (var property in eventData.Properties)
{
context.WithProperty(property.Key, property.Value);
}
}
await QueueBackgroundJobAsync(eventData);
}
protected async virtual Task QueueBackgroundJobAsync(TenantCreatedEto eventData)
{
var pollingJob = BuildPollingJobInfo(eventData.Id, eventData.Name);
await JobStore.StoreAsync(pollingJob);
await JobScheduler.QueueAsync(pollingJob);
var cleaningJob = BuildCleaningJobInfo(eventData.Id, eventData.Name);
await JobStore.StoreAsync(cleaningJob);
await JobScheduler.QueueAsync(cleaningJob);
var checkingJob = BuildCheckingJobInfo(eventData.Id, eventData.Name);
await JobStore.StoreAsync(checkingJob);
await JobScheduler.QueueAsync(checkingJob);
}
protected virtual JobInfo BuildPollingJobInfo(Guid tenantId, string tenantName)
{
return new JobInfo
{
Id = tenantId.ToString() + "_Polling",
Name = nameof(BackgroundPollingJob),
Group = "Polling",
Description = "Polling tasks to be executed",
Args = new Dictionary<string, object>() { { nameof(JobInfo.TenantId), tenantId } },
Status = JobStatus.Running,
BeginTime = DateTime.Now,
CreationTime = DateTime.Now,
Cron = Options.JobFetchCronExpression,
JobType = JobType.Period,
Priority = JobPriority.High,
Source = JobSource.System,
LockTimeOut = Options.JobFetchLockTimeOut,
TenantId = tenantId,
Type = typeof(BackgroundPollingJob).AssemblyQualifiedName,
};
}
protected virtual JobInfo BuildCleaningJobInfo(Guid tenantId, string tenantName)
{
return new JobInfo
{
Id = tenantId.ToString() + "_Cleaning",
Name = nameof(BackgroundCleaningJob),
Group = "Cleaning",
Description = "Cleaning tasks to be executed",
Args = new Dictionary<string, object>() { { nameof(JobInfo.TenantId), tenantId } },
Status = JobStatus.Running,
BeginTime = DateTime.Now,
CreationTime = DateTime.Now,
Cron = Options.JobCleanCronExpression,
JobType = JobType.Period,
Priority = JobPriority.High,
Source = JobSource.System,
TenantId = tenantId,
Type = typeof(BackgroundCleaningJob).AssemblyQualifiedName,
};
}
protected virtual JobInfo BuildCheckingJobInfo(Guid tenantId, string tenantName)
{
return new JobInfo
{
Id = tenantId.ToString() + "_Checking",
Name = nameof(BackgroundCheckingJob),
Group = "Checking",
Description = "Checking tasks to be executed",
Args = new Dictionary<string, object>() { { nameof(JobInfo.TenantId), tenantId } },
Status = JobStatus.Running,
BeginTime = DateTime.Now,
CreationTime = DateTime.Now,
Cron = Options.JobCheckCronExpression,
LockTimeOut = Options.JobCheckLockTimeOut,
JobType = JobType.Period,
Priority = JobPriority.High,
Source = JobSource.System,
TenantId = tenantId,
Type = typeof(BackgroundCheckingJob).AssemblyQualifiedName,
};
await DataSeeder.SeedAsync(context);
}
}

3
aspnet-core/aspire/LINGYUN.Abp.MicroService.WebhookService.EntityFrameworkCore/WebhookServiceDbMigrationEventHandler.cs

@ -15,8 +15,7 @@ public class WebhookServiceDbMigrationEventHandler : EfCoreDatabaseMigrationEven
ITenantStore tenantStore,
IAbpDistributedLock abpDistributedLock,
IDistributedEventBus distributedEventBus,
ILoggerFactory loggerFactory,
IDataSeeder dataSeeder)
ILoggerFactory loggerFactory)
: base(
ConnectionStringNameAttribute.GetConnStringName<WebhookServiceMigrationsDbContext>(),
currentTenant, unitOfWorkManager, tenantStore, abpDistributedLock, distributedEventBus, loggerFactory)

98
aspnet-core/modules/platform/LINGYUN.Abp.UI.Navigation.VueVbenAdmin/LINGYUN/Abp/UI/Navigation/VueVbenAdmin/VueVbenAdminNavigationSeedContributor.cs

@ -76,7 +76,7 @@ public class VueVbenAdminNavigationSeedContributor : NavigationSeedContributor
continue;
}
var menuMeta = new Dictionary<string, object>()
var menuMeta = new Dictionary<string, object>(menu.ExtraProperties)
{
{ "title", menu.DisplayName },
{ "icon", menu.Icon ?? "" },
@ -84,17 +84,6 @@ public class VueVbenAdminNavigationSeedContributor : NavigationSeedContributor
{ "hideTab", false },
{ "ignoreAuth", false },
};
foreach (var prop in menu.ExtraProperties)
{
if (menuMeta.ContainsKey(prop.Key))
{
menuMeta[prop.Key] = prop.Value;
}
else
{
menuMeta.Add(prop.Key, prop.Value);
}
}
var seedMenu = await SeedMenuAsync(
layout: layout,
@ -129,8 +118,7 @@ public class VueVbenAdminNavigationSeedContributor : NavigationSeedContributor
{
continue;
}
var menuMeta = new Dictionary<string, object>()
var menuMeta = new Dictionary<string, object>(item.ExtraProperties)
{
{ "title", item.DisplayName },
{ "icon", item.Icon ?? "" },
@ -138,17 +126,6 @@ public class VueVbenAdminNavigationSeedContributor : NavigationSeedContributor
{ "hideTab", false },
{ "ignoreAuth", false },
};
foreach (var prop in item.ExtraProperties)
{
if (menuMeta.ContainsKey(prop.Key))
{
menuMeta[prop.Key] = prop.Value;
}
else
{
menuMeta.Add(prop.Key, prop.Value);
}
}
var seedMenu = await SeedMenuAsync(
layout: layout,
@ -189,6 +166,18 @@ public class VueVbenAdminNavigationSeedContributor : NavigationSeedContributor
bool isPublic = false
)
{
var menuMeta = new Dictionary<string, object>();
foreach (var item in data.Items)
{
menuMeta[item.Name] = item.DefaultValue;
}
if (meta != null)
{
foreach (var item in meta)
{
menuMeta[item.Key] = item.Value;
}
}
var menu = await RouteDataSeeder.SeedMenuAsync(
layout,
name,
@ -200,19 +189,8 @@ public class VueVbenAdminNavigationSeedContributor : NavigationSeedContributor
description,
parentId,
tenantId,
isPublic
);
foreach (var item in data.Items)
{
menu.SetProperty(item.Name, item.DefaultValue);
}
if (meta != null)
{
foreach (var item in meta)
{
menu.SetProperty(item.Key, item.Value);
}
}
isPublic,
menuMeta);
if (roles != null)
{
@ -235,15 +213,17 @@ public class VueVbenAdminNavigationSeedContributor : NavigationSeedContributor
private async Task<DataItem> SeedUIFrameworkDataAsync(Guid? tenantId)
{
var data = await DataDictionaryDataSeeder
.SeedAsync(
"UI Framework",
CodeNumberGenerator.CreateCode(10),
"UI框架",
"UI Framework",
null,
tenantId,
true);
var data = new Data(
GuidGenerator.Create(),
"UI Framework",
CodeNumberGenerator.CreateCode(10),
"UI框架",
"UI Framework",
null,
tenantId)
{
IsStatic = true,
};
data.AddItem(
GuidGenerator,
@ -254,6 +234,8 @@ public class VueVbenAdminNavigationSeedContributor : NavigationSeedContributor
Options.UI,
isStatic: true);
await DataDictionaryDataSeeder.SeedAsync(data);
return data.FindItem(Options.UI);
}
@ -275,15 +257,17 @@ public class VueVbenAdminNavigationSeedContributor : NavigationSeedContributor
private async Task<Data> SeedLayoutDataAsync(Guid? tenantId)
{
var data = await DataDictionaryDataSeeder
.SeedAsync(
Options.LayoutName,
CodeNumberGenerator.CreateCode(10),
"Vben Admin 布局约束",
"Vben Admin Layout Meta Dictionary",
null,
tenantId,
true);
var data = new Data(
GuidGenerator.Create(),
Options.LayoutName,
CodeNumberGenerator.CreateCode(10),
"Vben Admin 布局约束",
"Vben Admin Layout Meta Dictionary",
null,
tenantId)
{
IsStatic = true,
};
data.AddItem(
GuidGenerator,
@ -446,6 +430,8 @@ public class VueVbenAdminNavigationSeedContributor : NavigationSeedContributor
ValueType.Boolean,
"扩展的格式化frame,{token}: 在打开的iframe页面传递token请求头");
await DataDictionaryDataSeeder.SeedAsync(data);
return data;
}

106
aspnet-core/modules/platform/LINGYUN.Abp.UI.Navigation.VueVbenAdmin5/LINGYUN/Abp/UI/Navigation/VueVbenAdmin5/VueVbenAdmin5NavigationSeedContributor.cs

@ -76,22 +76,11 @@ public class VueVbenAdmin5NavigationSeedContributor : NavigationSeedContributor
continue;
}
var menuMeta = new Dictionary<string, object>()
var menuMeta = new Dictionary<string, object>(menu.ExtraProperties)
{
{ "icon", menu.Icon ?? "" },
{ "order", menu.Order },
["icon"] = menu.Icon ?? "",
["order"] = menu.Order
};
foreach (var prop in menu.ExtraProperties)
{
if (menuMeta.ContainsKey(prop.Key))
{
menuMeta[prop.Key] = prop.Value;
}
else
{
menuMeta.Add(prop.Key, prop.Value);
}
}
var seedMenu = await SeedMenuAsync(
layout: layout,
@ -127,22 +116,11 @@ public class VueVbenAdmin5NavigationSeedContributor : NavigationSeedContributor
continue;
}
var menuMeta = new Dictionary<string, object>()
var menuMeta = new Dictionary<string, object>(item.ExtraProperties)
{
{ "icon", item.Icon ?? "" },
{ "order", item.Order },
["icon"] = item.Icon ?? "",
["order"] = item.Order
};
foreach (var prop in item.ExtraProperties)
{
if (menuMeta.ContainsKey(prop.Key))
{
menuMeta[prop.Key] = prop.Value;
}
else
{
menuMeta.Add(prop.Key, prop.Value);
}
}
var seedMenu = await SeedMenuAsync(
layout: layout,
@ -183,6 +161,18 @@ public class VueVbenAdmin5NavigationSeedContributor : NavigationSeedContributor
bool isPublic = false
)
{
var menuMeta = new Dictionary<string, object>();
foreach (var item in data.Items)
{
menuMeta[item.Name] = item.DefaultValue;
}
if (meta != null)
{
foreach (var item in meta)
{
menuMeta[item.Key] = item.Value;
}
}
var menu = await RouteDataSeeder.SeedMenuAsync(
layout,
name,
@ -194,19 +184,8 @@ public class VueVbenAdmin5NavigationSeedContributor : NavigationSeedContributor
description,
parentId,
tenantId,
isPublic
);
foreach (var item in data.Items)
{
menu.SetProperty(item.Name, item.DefaultValue);
}
if (meta != null)
{
foreach (var item in meta)
{
menu.SetProperty(item.Key, item.Value);
}
}
isPublic,
menuMeta);
if (roles != null)
{
@ -229,15 +208,17 @@ public class VueVbenAdmin5NavigationSeedContributor : NavigationSeedContributor
private async Task<DataItem> SeedUIFrameworkDataAsync(Guid? tenantId)
{
var data = await DataDictionaryDataSeeder
.SeedAsync(
"UI Framework",
CodeNumberGenerator.CreateCode(30),
"UI框架",
"UI Framework",
null,
tenantId,
true);
var data = new Data(
GuidGenerator.Create(),
"UI Framework",
CodeNumberGenerator.CreateCode(30),
"UI框架",
"UI Framework",
null,
tenantId)
{
IsStatic = true,
};
data.AddItem(
GuidGenerator,
@ -248,6 +229,8 @@ public class VueVbenAdmin5NavigationSeedContributor : NavigationSeedContributor
Options.UI,
isStatic: true);
await DataDictionaryDataSeeder.SeedAsync(data);
return data.FindItem(Options.UI);
}
@ -269,16 +252,17 @@ public class VueVbenAdmin5NavigationSeedContributor : NavigationSeedContributor
private async Task<Data> SeedLayoutDataAsync(Guid? tenantId)
{
var data = await DataDictionaryDataSeeder
.SeedAsync(
Options.LayoutName,
CodeNumberGenerator.CreateCode(40),
"Vben5 Admin 布局约束",
"Vben5 Admin模板布局约束",
null,
tenantId,
true);
var data = new Data(
GuidGenerator.Create(),
Options.LayoutName,
CodeNumberGenerator.CreateCode(40),
"Vben5 Admin 布局约束",
"Vben5 Admin模板布局约束",
null,
tenantId)
{
IsStatic = true,
};
data.AddItem(
GuidGenerator,
"title",
@ -460,6 +444,8 @@ public class VueVbenAdmin5NavigationSeedContributor : NavigationSeedContributor
ValueType.Boolean,
"用于配置当前路由不使用基础布局,仅在顶级时生效。默认情况下,所有的路由都会被包裹在基础布局中(包含顶部以及侧边等导航部件),如果你的页面不需要这些部件,可以设置 noBasicLayout 为 true。");
await DataDictionaryDataSeeder.SeedAsync(data);
return data;
}

14
aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Datas/DataDictionaryDataSeeder.cs

@ -1,6 +1,7 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Xml.Linq;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Guids;
using Volo.Abp.MultiTenancy;
@ -57,4 +58,17 @@ public class DataDictionaryDataSeeder : IDataDictionaryDataSeeder, ITransientDep
return data;
}
}
public async virtual Task<Data> SeedAsync(
Data data,
CancellationToken cancellationToken = default)
{
using (CurrentTenant.Change(data.TenantId))
{
var existsData = await DataRepository.FindByNameAsync(data.Name, cancellationToken: cancellationToken);
existsData ??= await DataRepository.InsertAsync(data, true, cancellationToken);
return existsData;
}
}
}

4
aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Datas/IDataDictionaryDataSeeder.cs

@ -15,4 +15,8 @@ public interface IDataDictionaryDataSeeder
Guid? tenantId = null,
bool isStatic = false,
CancellationToken cancellationToken = default);
Task<Data> SeedAsync(
Data data,
CancellationToken cancellationToken = default);
}

2
aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Routes/IRouteDataSeeder.cs

@ -1,6 +1,7 @@
using LINGYUN.Platform.Layouts;
using LINGYUN.Platform.Menus;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
@ -31,6 +32,7 @@ public interface IRouteDataSeeder
Guid? parentId = null,
Guid? tenantId = null,
bool isPublic = false,
IDictionary<string, object> meta = null,
CancellationToken cancellationToken = default);
Task SeedUserMenuAsync(

11
aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Routes/RouteDataSeeder.cs

@ -1,9 +1,11 @@
using LINGYUN.Platform.Layouts;
using LINGYUN.Platform.Menus;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Guids;
@ -72,6 +74,7 @@ public class RouteDataSeeder : IRouteDataSeeder, ITransientDependency
Guid? parentId = null,
Guid? tenantId = null,
bool isPublic = false,
IDictionary<string, object> meta = null,
CancellationToken cancellationToken = default)
{
if (parentId.HasValue)
@ -103,6 +106,14 @@ public class RouteDataSeeder : IRouteDataSeeder, ITransientDependency
IsPublic = isPublic
};
if (meta != null)
{
foreach (var item in meta)
{
menu.SetProperty(item.Key, item.Value);
}
}
menu = await MenuRepository.InsertAsync(menu, cancellationToken: cancellationToken);
}

Loading…
Cancel
Save