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. 107
      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. 118
      aspnet-core/aspire/LINGYUN.Abp.MicroService.TaskService.EntityFrameworkCore/TaskServiceDbMigrationEventHandler.cs
  25. 3
      aspnet-core/aspire/LINGYUN.Abp.MicroService.WebhookService.EntityFrameworkCore/WebhookServiceDbMigrationEventHandler.cs
  26. 78
      aspnet-core/modules/platform/LINGYUN.Abp.UI.Navigation.VueVbenAdmin/LINGYUN/Abp/UI/Navigation/VueVbenAdmin/VueVbenAdminNavigationSeedContributor.cs
  27. 86
      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 Microsoft.Extensions.Logging;
using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp.Data; using Volo.Abp.Data;
using Volo.Abp.DistributedLocking; using Volo.Abp.DistributedLocking;
@ -11,7 +10,7 @@ using Volo.Abp.Uow;
namespace LINGYUN.Abp.MicroService.AdminService; namespace LINGYUN.Abp.MicroService.AdminService;
public class AdminServiceDbMigrationEventHandler : EfCoreDatabaseMigrationEventHandlerBase<AdminServiceMigrationsDbContext> public class AdminServiceDbMigrationEventHandler : EfCoreDatabaseMigrationEventHandlerBase<AdminServiceMigrationsDbContext>
{ {
protected IDataSeeder DataSeeder { get; } protected AdminServiceDataSeeder DataSeeder { get; }
public AdminServiceDbMigrationEventHandler( public AdminServiceDbMigrationEventHandler(
ICurrentTenant currentTenant, ICurrentTenant currentTenant,
@ -20,7 +19,7 @@ public class AdminServiceDbMigrationEventHandler : EfCoreDatabaseMigrationEventH
IAbpDistributedLock abpDistributedLock, IAbpDistributedLock abpDistributedLock,
IDistributedEventBus distributedEventBus, IDistributedEventBus distributedEventBus,
ILoggerFactory loggerFactory, ILoggerFactory loggerFactory,
IDataSeeder dataSeeder) AdminServiceDataSeeder dataSeeder)
: base( : base(
ConnectionStringNameAttribute.GetConnStringName<AdminServiceMigrationsDbContext>(), ConnectionStringNameAttribute.GetConnStringName<AdminServiceMigrationsDbContext>(),
currentTenant, unitOfWorkManager, tenantStore, abpDistributedLock, distributedEventBus, loggerFactory) currentTenant, unitOfWorkManager, tenantStore, abpDistributedLock, distributedEventBus, loggerFactory)
@ -28,8 +27,18 @@ public class AdminServiceDbMigrationEventHandler : EfCoreDatabaseMigrationEventH
DataSeeder = dataSeeder; 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 LINGYUN.Abp.Data.DbMigrator;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using System; using System;
using System.Threading.Tasks;
using Volo.Abp.Data; using Volo.Abp.Data;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Abp.DistributedLocking; using Volo.Abp.DistributedLocking;
@ -11,16 +12,25 @@ using Volo.Abp.Uow;
namespace LINGYUN.Abp.MicroService.AdminService; namespace LINGYUN.Abp.MicroService.AdminService;
public class AdminServiceDbMigrationService : EfCoreRuntimeDbMigratorBase<AdminServiceMigrationsDbContext>, ITransientDependency public class AdminServiceDbMigrationService : EfCoreRuntimeDbMigratorBase<AdminServiceMigrationsDbContext>, ITransientDependency
{ {
protected AdminServiceDataSeeder DataSeeder { get; }
public AdminServiceDbMigrationService( public AdminServiceDbMigrationService(
ICurrentTenant currentTenant, ICurrentTenant currentTenant,
IUnitOfWorkManager unitOfWorkManager, IUnitOfWorkManager unitOfWorkManager,
IServiceProvider serviceProvider, IServiceProvider serviceProvider,
IAbpDistributedLock abpDistributedLock, IAbpDistributedLock abpDistributedLock,
IDistributedEventBus distributedEventBus, IDistributedEventBus distributedEventBus,
ILoggerFactory loggerFactory) ILoggerFactory loggerFactory,
AdminServiceDataSeeder dataSeeder)
: base( : base(
ConnectionStringNameAttribute.GetConnStringName<AdminServiceMigrationsDbContext>(), ConnectionStringNameAttribute.GetConnStringName<AdminServiceMigrationsDbContext>(),
unitOfWorkManager, serviceProvider, currentTenant, abpDistributedLock, distributedEventBus, loggerFactory) 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.AspNetCore.Serilog;
using Volo.Abp.Autofac; using Volo.Abp.Autofac;
using Volo.Abp.Caching.StackExchangeRedis; using Volo.Abp.Caching.StackExchangeRedis;
using Volo.Abp.Data;
using Volo.Abp.Http.Client; using Volo.Abp.Http.Client;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
using Volo.Abp.PermissionManagement.Identity; using Volo.Abp.PermissionManagement.Identity;
using Volo.Abp.PermissionManagement.OpenIddict; using Volo.Abp.PermissionManagement.OpenIddict;
using Volo.Abp.Swashbuckle; using Volo.Abp.Swashbuckle;
using Volo.Abp.Threading;
namespace LINGYUN.Abp.MicroService.AdminService; namespace LINGYUN.Abp.MicroService.AdminService;
@ -143,15 +141,4 @@ public partial class AdminServiceModule : AbpModule
ConfigureDistributedLocking(context.Services, configuration); ConfigureDistributedLocking(context.Services, configuration);
ConfigureSecurity(context.Services, configuration, hostingEnvironment.IsDevelopment()); 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": { "ConnectionStrings": {
"Default": "Host=127.0.0.1;Database=abp;Username=postgres;Password=123456" "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);
}
}
}

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

@ -1,28 +1,17 @@
using Microsoft.AspNetCore.Identity; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Data; using Volo.Abp.Data;
using Volo.Abp.DistributedLocking; using Volo.Abp.DistributedLocking;
using Volo.Abp.EntityFrameworkCore.Migrations; using Volo.Abp.EntityFrameworkCore.Migrations;
using Volo.Abp.EventBus.Distributed; using Volo.Abp.EventBus.Distributed;
using Volo.Abp.Guids;
using Volo.Abp.Identity;
using Volo.Abp.MultiTenancy; using Volo.Abp.MultiTenancy;
using Volo.Abp.PermissionManagement;
using Volo.Abp.Uow; using Volo.Abp.Uow;
using IdentityPermissions = Volo.Abp.Identity.IdentityPermissions;
namespace LINGYUN.Abp.MicroService.AuthServer; namespace LINGYUN.Abp.MicroService.AuthServer;
public class AuthServerDbMigrationEventHandler : EfCoreDatabaseMigrationEventHandlerBase<AuthServerMigrationsDbContext> public class AuthServerDbMigrationEventHandler : EfCoreDatabaseMigrationEventHandlerBase<AuthServerMigrationsDbContext>
{ {
protected IGuidGenerator GuidGenerator { get; } protected AuthServerDataSeeder DataSeeder { get; }
protected IdentityUserManager IdentityUserManager { get; }
protected IdentityRoleManager IdentityRoleManager { get; }
protected IPermissionDataSeeder PermissionDataSeeder { get; }
public AuthServerDbMigrationEventHandler( public AuthServerDbMigrationEventHandler(
ICurrentTenant currentTenant, ICurrentTenant currentTenant,
@ -31,102 +20,26 @@ public class AuthServerDbMigrationEventHandler : EfCoreDatabaseMigrationEventHan
IAbpDistributedLock abpDistributedLock, IAbpDistributedLock abpDistributedLock,
IDistributedEventBus distributedEventBus, IDistributedEventBus distributedEventBus,
ILoggerFactory loggerFactory, ILoggerFactory loggerFactory,
IGuidGenerator guidGenerator, AuthServerDataSeeder dataSeeder)
IdentityUserManager identityUserManager,
IdentityRoleManager identityRoleManager,
IPermissionDataSeeder permissionDataSeeder)
: base( : base(
ConnectionStringNameAttribute.GetConnStringName<AuthServerMigrationsDbContext>(), ConnectionStringNameAttribute.GetConnStringName<AuthServerMigrationsDbContext>(),
currentTenant, unitOfWorkManager, tenantStore, abpDistributedLock, distributedEventBus, loggerFactory) currentTenant, unitOfWorkManager, tenantStore, abpDistributedLock, distributedEventBus, loggerFactory)
{ {
GuidGenerator = guidGenerator; DataSeeder = dataSeeder;
IdentityUserManager = identityUserManager;
IdentityRoleManager = identityRoleManager;
PermissionDataSeeder = permissionDataSeeder;
} }
protected async override Task AfterTenantCreated(TenantCreatedEto eventData, bool schemaMigrated) 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 )
}
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[]
{
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, context.WithProperty(property.Key, property.Value);
IsPublic = true
};
(await IdentityRoleManager.CreateAsync(tenantAdminRole)).CheckErrors();
} }
else
{
var tenantAdminRole = await IdentityRoleManager.FindByNameAsync(tenantAdminRoleName);
tenantAdminRoleId = tenantAdminRole.Id;
} }
var adminUserId = GuidGenerator.Create(); await DataSeeder.SeedAsync(context);
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();
}
} }
} }

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

@ -2,6 +2,7 @@
using LINGYUN.Abp.Saas.Tenants; using LINGYUN.Abp.Saas.Tenants;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using System; using System;
using System.Threading.Tasks;
using Volo.Abp.Data; using Volo.Abp.Data;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Abp.DistributedLocking; using Volo.Abp.DistributedLocking;
@ -13,8 +14,8 @@ namespace LINGYUN.Abp.MicroService.AuthServer;
public class AuthServerDbMigrationService : EfCoreRuntimeDbMigratorBase<AuthServerMigrationsDbContext>, ITransientDependency public class AuthServerDbMigrationService : EfCoreRuntimeDbMigratorBase<AuthServerMigrationsDbContext>, ITransientDependency
{ {
protected AuthServerDataSeeder DataSeeder { get; }
public AuthServerDbMigrationService( public AuthServerDbMigrationService(
IDataSeeder dataSeeder,
IDbSchemaMigrator dbSchemaMigrator, IDbSchemaMigrator dbSchemaMigrator,
ITenantRepository tenantRepository, ITenantRepository tenantRepository,
ICurrentTenant currentTenant, ICurrentTenant currentTenant,
@ -22,10 +23,18 @@ public class AuthServerDbMigrationService : EfCoreRuntimeDbMigratorBase<AuthServ
IServiceProvider serviceProvider, IServiceProvider serviceProvider,
IAbpDistributedLock abpDistributedLock, IAbpDistributedLock abpDistributedLock,
IDistributedEventBus distributedEventBus, IDistributedEventBus distributedEventBus,
ILoggerFactory loggerFactory) ILoggerFactory loggerFactory,
AuthServerDataSeeder dataSeeder)
: base( : base(
ConnectionStringNameAttribute.GetConnStringName<AuthServerMigrationsDbContext>(), ConnectionStringNameAttribute.GetConnStringName<AuthServerMigrationsDbContext>(),
unitOfWorkManager, serviceProvider, currentTenant, abpDistributedLock, distributedEventBus, loggerFactory) 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.OpenIddict.Scopes;
using Volo.Abp.PermissionManagement; using Volo.Abp.PermissionManagement;
namespace LINGYUN.Abp.MicroService.AuthServer.DataSeeder; namespace LINGYUN.Abp.MicroService.AuthServer.DataSeeds;
public class OpenIddictDataSeeder : OpenIddictDataSeedContributorBase, ITransientDependency
public class OpenIddictDataSeederContributor : OpenIddictDataSeedContributorBase, IDataSeedContributor, ITransientDependency
{ {
public ILogger<OpenIddictDataSeederContributor> Logger { protected get; set; } public ILogger<OpenIddictDataSeeder> Logger { protected get; set; }
protected IPermissionDataSeeder PermissionDataSeeder { get; } protected IPermissionDataSeeder PermissionDataSeeder { get; }
public OpenIddictDataSeederContributor( public OpenIddictDataSeeder(
IConfiguration configuration, IConfiguration configuration,
IOpenIddictApplicationRepository openIddictApplicationRepository, IOpenIddictApplicationRepository openIddictApplicationRepository,
IAbpApplicationManager applicationManager, IAbpApplicationManager applicationManager,
@ -31,7 +30,7 @@ public class OpenIddictDataSeederContributor : OpenIddictDataSeedContributorBase
{ {
PermissionDataSeeder = permissionDataSeeder; PermissionDataSeeder = permissionDataSeeder;
Logger = NullLogger<OpenIddictDataSeederContributor>.Instance; Logger = NullLogger<OpenIddictDataSeeder>.Instance;
} }
public async virtual Task SeedAsync(DataSeedContext context) public async virtual Task SeedAsync(DataSeedContext context)
@ -54,17 +53,17 @@ public class OpenIddictDataSeederContributor : OpenIddictDataSeedContributorBase
private async Task CreateDefaultScopeAsync() private async Task CreateDefaultScopeAsync()
{ {
// OpenID Connect核心scope - 用于标识这是一个OIDC请求 // OpenId Connect
await CreateScopesAsync(new OpenIddictScopeDescriptor await CreateScopesAsync(new OpenIddictScopeDescriptor
{ {
Name = OpenIddictConstants.Scopes.OpenId, Name = OpenIddictConstants.Scopes.OpenId,
DisplayName = "OpenID Connect", // 友好的显示名称 DisplayName = "OpenId Connect",
DisplayNames = DisplayNames =
{ {
[CultureInfo.GetCultureInfo("zh-Hans")] = "身份认证", [CultureInfo.GetCultureInfo("zh-Hans")] = "身份认证",
[CultureInfo.GetCultureInfo("en")] = "OpenID Connect" [CultureInfo.GetCultureInfo("en")] = "OpenId Connect"
}, },
Description = "使用OpenID Connect协议进行身份验证", Description = "OpenId Connect协议进行身份验证",
Descriptions = Descriptions =
{ {
[CultureInfo.GetCultureInfo("zh-Hans")] = "允许应用程序使用您的身份信息进行登录", [CultureInfo.GetCultureInfo("zh-Hans")] = "允许应用程序使用您的身份信息进行登录",
@ -72,7 +71,7 @@ public class OpenIddictDataSeederContributor : OpenIddictDataSeedContributorBase
} }
}); });
// Profile scope - 用户基本信息 // Profile
await CreateScopesAsync(new OpenIddictScopeDescriptor await CreateScopesAsync(new OpenIddictScopeDescriptor
{ {
Name = OpenIddictConstants.Scopes.Profile, Name = OpenIddictConstants.Scopes.Profile,
@ -90,7 +89,7 @@ public class OpenIddictDataSeederContributor : OpenIddictDataSeedContributorBase
} }
}); });
// Email scope // Email
await CreateScopesAsync(new OpenIddictScopeDescriptor await CreateScopesAsync(new OpenIddictScopeDescriptor
{ {
Name = OpenIddictConstants.Scopes.Email, Name = OpenIddictConstants.Scopes.Email,
@ -108,7 +107,7 @@ public class OpenIddictDataSeederContributor : OpenIddictDataSeedContributorBase
} }
}); });
// Phone scope // Phone
await CreateScopesAsync(new OpenIddictScopeDescriptor await CreateScopesAsync(new OpenIddictScopeDescriptor
{ {
Name = OpenIddictConstants.Scopes.Phone, Name = OpenIddictConstants.Scopes.Phone,
@ -126,7 +125,7 @@ public class OpenIddictDataSeederContributor : OpenIddictDataSeedContributorBase
} }
}); });
// Address scope // Address
await CreateScopesAsync(new OpenIddictScopeDescriptor await CreateScopesAsync(new OpenIddictScopeDescriptor
{ {
Name = OpenIddictConstants.Scopes.Address, Name = OpenIddictConstants.Scopes.Address,
@ -144,7 +143,7 @@ public class OpenIddictDataSeederContributor : OpenIddictDataSeedContributorBase
} }
}); });
// Roles scope // Roles
await CreateScopesAsync(new OpenIddictScopeDescriptor await CreateScopesAsync(new OpenIddictScopeDescriptor
{ {
Name = OpenIddictConstants.Scopes.Roles, Name = OpenIddictConstants.Scopes.Roles,
@ -162,7 +161,7 @@ public class OpenIddictDataSeederContributor : OpenIddictDataSeedContributorBase
} }
}); });
// Offline Access scope - 用于获取刷新令牌 // OfflineAccess
await CreateScopesAsync(new OpenIddictScopeDescriptor await CreateScopesAsync(new OpenIddictScopeDescriptor
{ {
Name = OpenIddictConstants.Scopes.OfflineAccess, Name = OpenIddictConstants.Scopes.OfflineAccess,
@ -183,6 +182,7 @@ public class OpenIddictDataSeederContributor : OpenIddictDataSeedContributorBase
private async Task CreateApiScopeAsync(string scope) private async Task CreateApiScopeAsync(string scope)
{ {
// 前端汇总授权范围
await CreateScopesAsync(new OpenIddictScopeDescriptor await CreateScopesAsync(new OpenIddictScopeDescriptor
{ {
Name = scope, Name = scope,
@ -213,6 +213,216 @@ public class OpenIddictDataSeederContributor : OpenIddictDataSeedContributorBase
"workflow-service", "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) private async Task CreateApplicationAsync(string scope)
@ -316,7 +526,18 @@ public class OpenIddictDataSeederContributor : OpenIddictDataSeedContributorBase
OpenIddictConstants.Scopes.Phone, OpenIddictConstants.Scopes.Phone,
OpenIddictConstants.Scopes.Profile, OpenIddictConstants.Scopes.Profile,
OpenIddictConstants.Scopes.OfflineAccess, 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, oauthClientRedirectUrls,
oauthClientPostLogoutRedirectUrls); 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.Application;
using LINGYUN.Abp.Serilog.Enrichers.UniqueId; using LINGYUN.Abp.Serilog.Enrichers.UniqueId;
using LINGYUN.Abp.Sms.Platform; using LINGYUN.Abp.Sms.Platform;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
using System.Threading.Tasks;
using Volo.Abp; using Volo.Abp;
using Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonXLite; using Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonXLite;
using Volo.Abp.AspNetCore.Serilog; using Volo.Abp.AspNetCore.Serilog;
using Volo.Abp.Autofac; using Volo.Abp.Autofac;
using Volo.Abp.Caching.StackExchangeRedis; using Volo.Abp.Caching.StackExchangeRedis;
using Volo.Abp.Data;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
using Volo.Abp.PermissionManagement.Identity; using Volo.Abp.PermissionManagement.Identity;
using Volo.Abp.Threading;
namespace LINGYUN.Abp.MicroService.AuthServer; namespace LINGYUN.Abp.MicroService.AuthServer;
@ -119,16 +115,4 @@ public partial class AuthServerModule : AbpModule
ConfigureDistributedLocking(context.Services, configuration); ConfigureDistributedLocking(context.Services, configuration);
ConfigureSecurity(context.Services, configuration, hostingEnvironment.IsDevelopment()); 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" /> <ProjectReference Include="..\LINGYUN.Abp.MicroService.ServiceDefaults\LINGYUN.Abp.MicroService.ServiceDefaults.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Folder Include="wwwroot\" />
</ItemGroup>
<Target Name="RestoreNpmPackages" BeforeTargets="BeforeBuild"> <Target Name="RestoreNpmPackages" BeforeTargets="BeforeBuild">
<Message Text="正在执行 abp install-libs ..." Importance="high" /> <Message Text="正在执行 abp install-libs ..." Importance="high" />
@ -89,10 +85,7 @@
<PackageJsonPath>$(MSBuildProjectDirectory)\package.json</PackageJsonPath> <PackageJsonPath>$(MSBuildProjectDirectory)\package.json</PackageJsonPath>
</PropertyGroup> </PropertyGroup>
<Exec Command="abp install-libs" <Exec Command="abp install-libs" Condition="Exists('$(PackageJsonPath)')" WorkingDirectory="$(MSBuildProjectDirectory)" IgnoreExitCode="false" />
Condition="Exists('$(PackageJsonPath)')"
WorkingDirectory="$(MSBuildProjectDirectory)"
IgnoreExitCode="false" />
</Target> </Target>
</Project> </Project>

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

@ -93,35 +93,6 @@
"MapInboundClaims": false, "MapInboundClaims": false,
"RequireHttpsMetadata": 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": { "Identity": {
"Password": { "Password": {
"RequiredLength": 6, "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); ConfigureDistributedLocking(context.Services, configuration);
ConfigureSecurity(context.Services, configuration, hostingEnvironment.IsDevelopment()); 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="..\..\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\platform\LINGYUN.Platform.EntityFrameworkCore\LINGYUN.Platform.EntityFrameworkCore.csproj" />
<ProjectReference Include="..\..\modules\saas\LINGYUN.Abp.Saas.EntityFrameworkCore\LINGYUN.Abp.Saas.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> </ItemGroup>
</Project> </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.Saas.Tenants;
using LINGYUN.Abp.UI.Navigation;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using System; using System;
using System.Collections.Generic;
using System.Data.Common; using System.Data.Common;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -12,7 +10,6 @@ using Volo.Abp.Data;
using Volo.Abp.DistributedLocking; using Volo.Abp.DistributedLocking;
using Volo.Abp.EntityFrameworkCore.Migrations; using Volo.Abp.EntityFrameworkCore.Migrations;
using Volo.Abp.EventBus.Distributed; using Volo.Abp.EventBus.Distributed;
using Volo.Abp.Features;
using Volo.Abp.MultiTenancy; using Volo.Abp.MultiTenancy;
using Volo.Abp.Uow; using Volo.Abp.Uow;
@ -21,9 +18,7 @@ public class PlatformServiceDbMigrationEventHandler :
EfCoreDatabaseMigrationEventHandlerBase<PlatformServiceMigrationsDbContext>, EfCoreDatabaseMigrationEventHandlerBase<PlatformServiceMigrationsDbContext>,
IDistributedEventHandler<TenantDeletedEto> IDistributedEventHandler<TenantDeletedEto>
{ {
protected IEnumerable<INavigationSeedContributor> NavigationSeedContributors { get; } protected PlatformServiceDataSeeder DataSeeder { get; }
protected INavigationProvider NavigationProvider { get; }
protected IFeatureChecker FeatureChecker { get; }
protected IConfiguration Configuration { get; } protected IConfiguration Configuration { get; }
public PlatformServiceDbMigrationEventHandler( public PlatformServiceDbMigrationEventHandler(
ICurrentTenant currentTenant, ICurrentTenant currentTenant,
@ -32,37 +27,29 @@ public class PlatformServiceDbMigrationEventHandler :
IAbpDistributedLock abpDistributedLock, IAbpDistributedLock abpDistributedLock,
IDistributedEventBus distributedEventBus, IDistributedEventBus distributedEventBus,
ILoggerFactory loggerFactory, ILoggerFactory loggerFactory,
IFeatureChecker featureChecker,
IConfiguration configuration, IConfiguration configuration,
INavigationProvider navigationProvider, PlatformServiceDataSeeder dataSeeder)
IEnumerable<INavigationSeedContributor> navigationSeedContributors)
: base( : base(
ConnectionStringNameAttribute.GetConnStringName<PlatformServiceMigrationsDbContext>(), ConnectionStringNameAttribute.GetConnStringName<PlatformServiceMigrationsDbContext>(),
currentTenant, unitOfWorkManager, tenantStore, abpDistributedLock, distributedEventBus, loggerFactory) currentTenant, unitOfWorkManager, tenantStore, abpDistributedLock, distributedEventBus, loggerFactory)
{ {
FeatureChecker = featureChecker;
Configuration = configuration; Configuration = configuration;
NavigationProvider = navigationProvider; DataSeeder = dataSeeder;
NavigationSeedContributors = navigationSeedContributors;
} }
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(); foreach (var property in eventData.Properties)
var multiTenancySides = CurrentTenant.IsAvailable
? MultiTenancySides.Tenant
: MultiTenancySides.Host;
var seedContext = new NavigationSeedContext(menus, multiTenancySides);
foreach (var contributor in NavigationSeedContributors)
{ {
await contributor.SeedAsync(seedContext); context.WithProperty(property.Key, property.Value);
} }
} }
await DataSeeder.SeedAsync(context);
} }
public async virtual Task HandleEventAsync(TenantDeletedEto eventData) 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 LINGYUN.Abp.Data.DbMigrator;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using System; using System;
using System.Threading.Tasks;
using Volo.Abp.Data; using Volo.Abp.Data;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Abp.DistributedLocking; using Volo.Abp.DistributedLocking;
@ -11,16 +12,25 @@ using Volo.Abp.Uow;
namespace LINGYUN.Abp.MicroService.PlatformService; namespace LINGYUN.Abp.MicroService.PlatformService;
public class PlatformServiceDbMigrationService : EfCoreRuntimeDbMigratorBase<PlatformServiceMigrationsDbContext>, ITransientDependency public class PlatformServiceDbMigrationService : EfCoreRuntimeDbMigratorBase<PlatformServiceMigrationsDbContext>, ITransientDependency
{ {
protected PlatformServiceDataSeeder DataSeeder { get; }
public PlatformServiceDbMigrationService( public PlatformServiceDbMigrationService(
ICurrentTenant currentTenant, ICurrentTenant currentTenant,
IUnitOfWorkManager unitOfWorkManager, IUnitOfWorkManager unitOfWorkManager,
IServiceProvider serviceProvider, IServiceProvider serviceProvider,
IAbpDistributedLock abpDistributedLock, IAbpDistributedLock abpDistributedLock,
IDistributedEventBus distributedEventBus, IDistributedEventBus distributedEventBus,
ILoggerFactory loggerFactory) ILoggerFactory loggerFactory,
PlatformServiceDataSeeder dataSeeder)
: base( : base(
ConnectionStringNameAttribute.GetConnStringName<PlatformServiceMigrationsDbContext>(), ConnectionStringNameAttribute.GetConnStringName<PlatformServiceMigrationsDbContext>(),
unitOfWorkManager, serviceProvider, currentTenant, abpDistributedLock, distributedEventBus, loggerFactory) 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.Data.DbMigrator;
using LINGYUN.Abp.Saas.EntityFrameworkCore; using LINGYUN.Abp.Saas.EntityFrameworkCore;
using LINGYUN.Abp.UI.Navigation; using LINGYUN.Abp.UI.Navigation.VueVbenAdmin5;
using LINGYUN.Platform.EntityFrameworkCore; using LINGYUN.Platform.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using System; using System;
@ -14,7 +14,7 @@ using Volo.Abp.SettingManagement.EntityFrameworkCore;
namespace LINGYUN.Abp.MicroService.PlatformService; namespace LINGYUN.Abp.MicroService.PlatformService;
[DependsOn( [DependsOn(
typeof(AbpUINavigationModule), typeof(AbpUINavigationVueVbenAdmin5Module),
typeof(AbpSaasEntityFrameworkCoreModule), typeof(AbpSaasEntityFrameworkCoreModule),
typeof(PlatformEntityFrameworkCoreModule), typeof(PlatformEntityFrameworkCoreModule),
typeof(AbpSettingManagementEntityFrameworkCoreModule), 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\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.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.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.Application\LINGYUN.Platform.Application.csproj" />
<ProjectReference Include="..\..\modules\platform\LINGYUN.Platform.EntityFrameworkCore\LINGYUN.Platform.EntityFrameworkCore.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.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\realtime-notifications\LINGYUN.Abp.Notifications\LINGYUN.Abp.Notifications.csproj" />
<ProjectReference Include="..\..\modules\saas\LINGYUN.Abp.Saas.EntityFrameworkCore\LINGYUN.Abp.Saas.EntityFrameworkCore.csproj" /> <ProjectReference Include="..\..\modules\saas\LINGYUN.Abp.Saas.EntityFrameworkCore\LINGYUN.Abp.Saas.EntityFrameworkCore.csproj" />
</ItemGroup> </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.Application;
using LINGYUN.Abp.Serilog.Enrichers.UniqueId; using LINGYUN.Abp.Serilog.Enrichers.UniqueId;
using LINGYUN.Abp.Sms.Aliyun; using LINGYUN.Abp.Sms.Aliyun;
using LINGYUN.Abp.UI.Navigation.VueVbenAdmin5;
using LINGYUN.Platform; using LINGYUN.Platform;
using LINGYUN.Platform.EntityFrameworkCore; using LINGYUN.Platform.EntityFrameworkCore;
using LINGYUN.Platform.HttpApi; using LINGYUN.Platform.HttpApi;
using LINGYUN.Platform.Theme.VueVbenAdmin;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Volo.Abp; using Volo.Abp;
using Volo.Abp.AspNetCore.Authentication.JwtBearer; using Volo.Abp.AspNetCore.Authentication.JwtBearer;
@ -38,7 +36,6 @@ using Volo.Abp.AspNetCore.Serilog;
using Volo.Abp.Autofac; using Volo.Abp.Autofac;
using Volo.Abp.BackgroundWorkers; using Volo.Abp.BackgroundWorkers;
using Volo.Abp.Caching.StackExchangeRedis; using Volo.Abp.Caching.StackExchangeRedis;
using Volo.Abp.Data;
using Volo.Abp.FeatureManagement.EntityFrameworkCore; using Volo.Abp.FeatureManagement.EntityFrameworkCore;
using Volo.Abp.Http.Client; using Volo.Abp.Http.Client;
using Volo.Abp.Http.Client.IdentityModel.Web; using Volo.Abp.Http.Client.IdentityModel.Web;
@ -60,8 +57,6 @@ namespace LINGYUN.Abp.MicroService.PlatformService;
typeof(AbpAuditLoggingElasticsearchModule), typeof(AbpAuditLoggingElasticsearchModule),
typeof(AbpAspNetCoreMultiTenancyModule), typeof(AbpAspNetCoreMultiTenancyModule),
typeof(AbpAspNetCoreMvcLocalizationModule), typeof(AbpAspNetCoreMvcLocalizationModule),
typeof(AbpUINavigationVueVbenAdmin5Module),
typeof(PlatformThemeVueVbenAdminModule),
typeof(AbpOssManagementAliyunModule), // 阿里云存储提供者模块 typeof(AbpOssManagementAliyunModule), // 阿里云存储提供者模块
typeof(AbpOssManagementTencentModule), // 腾讯云存储提供者模块 typeof(AbpOssManagementTencentModule), // 腾讯云存储提供者模块
typeof(AbpOssManagementNexusModule), // Nexus存储提供者模块 typeof(AbpOssManagementNexusModule), // Nexus存储提供者模块
@ -151,10 +146,6 @@ public partial class PlatformServiceModule : AbpModule
public async override Task OnApplicationInitializationAsync(ApplicationInitializationContext context) public async override Task OnApplicationInitializationAsync(ApplicationInitializationContext context)
{ {
await context.ServiceProvider
.GetRequiredService<IDataSeeder>()
.SeedAsync();
var options = context.ServiceProvider.GetRequiredService<IOptions<AbpOssManagementOptions>>().Value; var options = context.ServiceProvider.GetRequiredService<IOptions<AbpOssManagementOptions>>().Value;
if (options.IsCleanupEnabled) 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,
};
}
}

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

@ -1,10 +1,5 @@
using LINGYUN.Abp.BackgroundTasks; using LINGYUN.Abp.Saas.Tenants;
using LINGYUN.Abp.BackgroundTasks.Internal;
using LINGYUN.Abp.Saas.Tenants;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp.Data; using Volo.Abp.Data;
using Volo.Abp.DistributedLocking; using Volo.Abp.DistributedLocking;
@ -19,9 +14,7 @@ public class TaskServiceDbMigrationEventHandler :
EfCoreDatabaseMigrationEventHandlerBase<TaskServiceMigrationsDbContext>, EfCoreDatabaseMigrationEventHandlerBase<TaskServiceMigrationsDbContext>,
IDistributedEventHandler<EntityDeletedEto<TenantEto>> IDistributedEventHandler<EntityDeletedEto<TenantEto>>
{ {
protected AbpBackgroundTasksOptions Options { get; } protected TaskServiceDataSeeder DataSeeder { get; }
protected IJobStore JobStore { get; }
protected IJobScheduler JobScheduler { get; }
public TaskServiceDbMigrationEventHandler( public TaskServiceDbMigrationEventHandler(
ICurrentTenant currentTenant, ICurrentTenant currentTenant,
@ -30,122 +23,33 @@ public class TaskServiceDbMigrationEventHandler :
IAbpDistributedLock abpDistributedLock, IAbpDistributedLock abpDistributedLock,
IDistributedEventBus distributedEventBus, IDistributedEventBus distributedEventBus,
ILoggerFactory loggerFactory, ILoggerFactory loggerFactory,
IJobStore jobStore, TaskServiceDataSeeder dataSeeder)
IJobScheduler jobScheduler,
IOptions<AbpBackgroundTasksOptions> options)
: base( : base(
ConnectionStringNameAttribute.GetConnStringName<TaskServiceMigrationsDbContext>(), ConnectionStringNameAttribute.GetConnStringName<TaskServiceMigrationsDbContext>(),
currentTenant, unitOfWorkManager, tenantStore, abpDistributedLock, distributedEventBus, loggerFactory) currentTenant, unitOfWorkManager, tenantStore, abpDistributedLock, distributedEventBus, loggerFactory)
{ {
JobStore = jobStore; DataSeeder = dataSeeder;
JobScheduler = jobScheduler;
Options = options.Value;
} }
public async Task HandleEventAsync(EntityDeletedEto<TenantEto> eventData) public async Task HandleEventAsync(EntityDeletedEto<TenantEto> eventData)
{ {
// 租户删除时移除轮询作业 // 租户删除时移除轮询作业
var pollingJob = BuildPollingJobInfo(eventData.Entity.Id, eventData.Entity.Name); await DataSeeder.RemoveSeedAsync(eventData.Entity.Id);
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);
} }
protected async override Task AfterTenantCreated(TenantCreatedEto eventData, bool schemaMigrated) 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)
}
await QueueBackgroundJobAsync(eventData);
}
protected async virtual Task QueueBackgroundJobAsync(TenantCreatedEto eventData)
{ {
var pollingJob = BuildPollingJobInfo(eventData.Id, eventData.Name); context.WithProperty(property.Key, property.Value);
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) await DataSeeder.SeedAsync(context);
{
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,
};
} }
} }

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

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

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

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

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

@ -1,6 +1,7 @@
using System; using System;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Xml.Linq;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Abp.Guids; using Volo.Abp.Guids;
using Volo.Abp.MultiTenancy; using Volo.Abp.MultiTenancy;
@ -57,4 +58,17 @@ public class DataDictionaryDataSeeder : IDataDictionaryDataSeeder, ITransientDep
return data; 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, Guid? tenantId = null,
bool isStatic = false, bool isStatic = false,
CancellationToken cancellationToken = default); 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.Layouts;
using LINGYUN.Platform.Menus; using LINGYUN.Platform.Menus;
using System; using System;
using System.Collections.Generic;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -31,6 +32,7 @@ public interface IRouteDataSeeder
Guid? parentId = null, Guid? parentId = null,
Guid? tenantId = null, Guid? tenantId = null,
bool isPublic = false, bool isPublic = false,
IDictionary<string, object> meta = null,
CancellationToken cancellationToken = default); CancellationToken cancellationToken = default);
Task SeedUserMenuAsync( 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.Layouts;
using LINGYUN.Platform.Menus; using LINGYUN.Platform.Menus;
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Abp.Guids; using Volo.Abp.Guids;
@ -72,6 +74,7 @@ public class RouteDataSeeder : IRouteDataSeeder, ITransientDependency
Guid? parentId = null, Guid? parentId = null,
Guid? tenantId = null, Guid? tenantId = null,
bool isPublic = false, bool isPublic = false,
IDictionary<string, object> meta = null,
CancellationToken cancellationToken = default) CancellationToken cancellationToken = default)
{ {
if (parentId.HasValue) if (parentId.HasValue)
@ -103,6 +106,14 @@ public class RouteDataSeeder : IRouteDataSeeder, ITransientDependency
IsPublic = isPublic IsPublic = isPublic
}; };
if (meta != null)
{
foreach (var item in meta)
{
menu.SetProperty(item.Key, item.Value);
}
}
menu = await MenuRepository.InsertAsync(menu, cancellationToken: cancellationToken); menu = await MenuRepository.InsertAsync(menu, cancellationToken: cancellationToken);
} }

Loading…
Cancel
Save