Browse Source

feat: Merge multiple functional optimizations

- **NOTES: Due to the disorderly submission order, there is no need to waste effort in sorting and consolidating the submissions.**
pull/1548/head
colin 2 weeks ago
parent
commit
a1c33d6c94
  1. 92
      apps/vben5/packages/@abp/platform/src/components/messages/email/EmailMessageModal.vue
  2. 25
      aspnet-core/aspire/LINGYUN.Abp.MicroService.AppHost/AppHost.cs
  3. 5
      aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer.DbMigrator/AuthServerDbMigratorHostedService.cs
  4. 8
      aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer.DbMigrator/AuthServerDbMigratorModule.cs
  5. 19
      aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer.DbMigrator/AuthServerInitializeDataSeeder.cs
  6. 89
      aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer.DbMigrator/DataSeeds/IdentityUserNotificationDataSeeder.cs
  7. 3
      aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer.DbMigrator/LINGYUN.Abp.MicroService.AuthServer.DbMigrator.csproj
  8. 10
      aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer.EntityFrameworkCore/DataSeeds/IdentityUserRoleDataSeeder.cs
  9. 14
      aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer/AuthServerModule.Configure.cs
  10. 19
      aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer/appsettings.Development.json
  11. 3
      aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer/appsettings.json
  12. 7
      aspnet-core/aspire/LINGYUN.Abp.MicroService.IdentityService/Handlers/IdentitySessionAccessEventHandler.cs
  13. 37
      aspnet-core/aspire/LINGYUN.Abp.MicroService.MessageService.EntityFrameworkCore/DataSeeds/NotificationDataSeeder.cs
  14. 13
      aspnet-core/framework/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/ApplicationMenu.cs
  15. 5
      aspnet-core/migrations/LY.MicroService.AuthServer.DbMigrator/AuthServerDbMigratorHostedService.cs
  16. 8
      aspnet-core/migrations/LY.MicroService.AuthServer.DbMigrator/AuthServerDbMigratorModule.cs
  17. 20
      aspnet-core/migrations/LY.MicroService.AuthServer.DbMigrator/AuthServerInitializeDataSeeder.cs
  18. 89
      aspnet-core/migrations/LY.MicroService.AuthServer.DbMigrator/DataSeeds/IdentityUserNotificationDataSeeder.cs
  19. 3
      aspnet-core/migrations/LY.MicroService.AuthServer.DbMigrator/LY.MicroService.AuthServer.DbMigrator.csproj
  20. 139
      aspnet-core/migrations/LY.MicroService.RealtimeMessage.EntityFrameworkCore/DataSeeds/NotificationDataSeeder.cs
  21. 10
      aspnet-core/migrations/LY.MicroService.RealtimeMessage.EntityFrameworkCore/RealtimeMessageDataSeedConsts.cs
  22. 33
      aspnet-core/migrations/LY.MicroService.RealtimeMessage.EntityFrameworkCore/RealtimeMessageDataSeeder.cs
  23. 11
      aspnet-core/migrations/LY.MicroService.RealtimeMessage.EntityFrameworkCore/RealtimeMessageDbMigrationService.cs
  24. 12
      aspnet-core/modules/account/LINGYUN.Abp.Account.Web/Pages/Account/SendCode.cshtml
  25. 16
      aspnet-core/modules/account/LINGYUN.Abp.Account.Web/Pages/Account/VerifyAuthenticatorCode.cshtml
  26. 19
      aspnet-core/modules/account/LINGYUN.Abp.Account.Web/Pages/Account/VerifyCode.cshtml
  27. 5
      aspnet-core/modules/platform/LINGYUN.Abp.UI.Navigation.VueVbenAdmin5/LINGYUN/Abp/UI/Navigation/VueVbenAdmin5/AbpUINavigationVueVbenAdmin5NavigationDefinitionProvider.cs
  28. 35
      aspnet-core/modules/platform/LINGYUN.Abp.UI.Navigation.VueVbenAdmin5/LINGYUN/Abp/UI/Navigation/VueVbenAdmin5/VueVbenAdmin5NavigationSeedContributor.cs
  29. 3
      aspnet-core/modules/platform/LINGYUN.Platform.Application/LINGYUN/Platform/Menus/MenuAppService.cs
  30. 2
      aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Menus/IMenuRepository.cs
  31. 2
      aspnet-core/modules/platform/LINGYUN.Platform.EntityFrameworkCore/LINGYUN/Platform/Menus/EfCoreMenuRepository.cs

92
apps/vben5/packages/@abp/platform/src/components/messages/email/EmailMessageModal.vue

@ -1,34 +1,100 @@
<script setup lang="ts">
import type { EmailMessageDto } from '../../../types/messages';
import { ref } from 'vue';
import { useVbenModal } from '@vben/common-ui';
import { useVbenForm, useVbenModal } from '@vben/common-ui';
import { $t } from '@vben/locales';
import { Tinymce } from '@abp/components/tinymce';
import { toDate } from '@abp/core';
import { useEmailMessagesApi } from '../../../api/useEmailMessagesApi';
const { getApi } = useEmailMessagesApi();
const messageContent = ref('');
const [Form, formApi] = useVbenForm({
commonConfig: {
//
componentProps: {
class: 'w-full',
},
},
layout: 'vertical',
schema: [
{
fieldName: 'subject',
component: 'Input',
disabled: true,
label: $t('AppPlatform.DisplayName:Subject'),
},
{
fieldName: 'receiver',
component: 'Input',
disabled: true,
label: $t('AppPlatform.DisplayName:Receiver'),
},
{
fieldName: 'sender',
component: 'Input',
disabled: true,
label: $t('AppPlatform.DisplayName:From'),
},
{
fieldName: 'creationTime',
component: 'DatePicker',
disabled: true,
componentProps: {
format: 'YYYY-MM-DD HH:mm:ss',
},
label: $t('AppPlatform.DisplayName:CreationTime'),
},
{
fieldName: 'content',
component: 'Input',
label: $t('AppPlatform.DisplayName:Content'),
},
],
showDefaultActions: false,
});
const [Modal, modalApi] = useVbenModal({
class: 'w-[800px]',
onOpenChange(isOpen) {
if (isOpen) {
const dto = modalApi.getData<EmailMessageDto>();
messageContent.value = dto.content;
formApi.resetForm();
onInit();
}
},
showConfirmButton: false,
});
async function onInit() {
const { id } = modalApi.getData<EmailMessageDto>();
const dto = await getApi(id);
await formApi.setValues({
subject: dto.subject,
receiver: dto.receiver,
sender: dto.sender,
creationTime: toDate(dto.creationTime),
content: dto.content,
});
}
</script>
<template>
<Modal :title="$t('AppPlatform.EmailMessages')">
<Tinymce
:value="messageContent"
:plugins="[]"
:toolbar="[]"
readonly
menubar="''"
/>
<Form>
<template #content="{ modelValue }">
<Tinymce
v-if="modelValue"
width="100%"
:value="modelValue"
:plugins="[]"
:toolbar="[]"
readonly
menubar="''"
/>
</template>
</Form>
</Modal>
</template>

25
aspnet-core/aspire/LINGYUN.Abp.MicroService.AppHost/AppHost.cs

@ -64,7 +64,7 @@ IResourceBuilder<ProjectResource> AddDotNetProject<TDbMigrator, TProject>(
string portName,
string serviceSuffix = "Service",
string migratorSuffix = "Migrator",
IResourceBuilder<ProjectResource>? waitProject = null)
params IResourceBuilder<ProjectResource>[]? waitProjects)
where TDbMigrator : IProjectMetadata, new()
where TProject : IProjectMetadata, new()
{
@ -109,9 +109,12 @@ IResourceBuilder<ProjectResource> AddDotNetProject<TDbMigrator, TProject>(
.WaitFor(abpDb);
}
if (waitProject != null)
if (waitProjects != null)
{
service.WaitFor(waitProject);
foreach (var waitProject in waitProjects)
{
service = service.WaitFor(waitProject);
}
}
return service;
@ -139,7 +142,7 @@ var authServer = AddDotNetProject<
migratorSuffix: "Migrator",
port: 44385,
portName: "auth",
waitProject: localizationService);
waitProjects: localizationService);
// AdminService
var adminService = AddDotNetProject<
@ -151,7 +154,7 @@ var adminService = AddDotNetProject<
migratorSuffix: "Migrator",
port: 30010,
portName: "admin",
waitProject: authServer);
waitProjects: authServer);
// IdentityService
AddDotNetProject<
@ -163,7 +166,7 @@ AddDotNetProject<
migratorSuffix: "Migrator",
port: 30015,
portName: "identity",
waitProject: authServer);
waitProjects: authServer);
// TaskService
var taskService = AddDotNetProject<
@ -175,7 +178,7 @@ var taskService = AddDotNetProject<
migratorSuffix: "Migrator",
port: 30040,
portName: "task",
waitProject: adminService)
waitProjects: adminService)
.WithHttpHealthCheck("/health/service");
// MessageService
@ -188,7 +191,7 @@ AddDotNetProject<
migratorSuffix: "Migrator",
port: 30020,
portName: "message",
waitProject: taskService);
waitProjects: taskService);
// WebhookService
AddDotNetProject<
@ -200,7 +203,7 @@ AddDotNetProject<
migratorSuffix: "Migrator",
port: 30045,
portName: "webhook",
waitProject: taskService);
waitProjects: taskService);
// PlatformService
AddDotNetProject<
@ -212,7 +215,7 @@ AddDotNetProject<
migratorSuffix: "Migrator",
port: 30025,
portName: "platform",
waitProject: adminService);
waitProjects: adminService);
// WeChatService
builder.AddProject<Projects.LINGYUN_Abp_MicroService_WeChatService>("WeChatService")
@ -252,7 +255,7 @@ AddDotNetProject<
migratorSuffix: "Migrator",
port: 30070,
portName: "ai",
waitProject: localizationService);
waitProjects: localizationService);
// ApiGateway
var apigateway = builder.AddProject<Projects.LINGYUN_Abp_MicroService_ApiGateway>("ApiGateway")

5
aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer.DbMigrator/AuthServerDbMigratorHostedService.cs

@ -36,6 +36,11 @@ public class AuthServerDbMigratorHostedService : IHostedService
.GetRequiredService<AuthServerDbMigrationService>()
.CheckAndApplyDatabaseMigrationsAsync();
await application
.ServiceProvider
.GetRequiredService<AuthServerInitializeDataSeeder>()
.SeedAsync(new DataSeedContext());
await application.ShutdownAsync();
_hostApplicationLifetime.StopApplication();

8
aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer.DbMigrator/AuthServerDbMigratorModule.cs

@ -1,10 +1,16 @@
using Volo.Abp.Autofac;
using LINGYUN.Abp.Identity.Notifications;
using LINGYUN.Abp.Notifications.Common;
using LINGYUN.Abp.Notifications.EntityFrameworkCore;
using Volo.Abp.Autofac;
using Volo.Abp.Modularity;
namespace LINGYUN.Abp.MicroService.AuthServer;
[DependsOn(
typeof(AbpAutofacModule),
typeof(AbpNotificationsCommonModule),
typeof(AbpIdentityNotificationsModule),
typeof(AbpNotificationsEntityFrameworkCoreModule),
typeof(AuthServerMigrationsEntityFrameworkCoreModule))]
public class AuthServerDbMigratorModule : AbpModule
{

19
aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer.DbMigrator/AuthServerInitializeDataSeeder.cs

@ -0,0 +1,19 @@
using LINGYUN.Abp.MicroService.AuthServer.DataSeeds;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
namespace LINGYUN.Abp.MicroService.AuthServer;
public class AuthServerInitializeDataSeeder : ITransientDependency
{
protected IdentityUserNotificationDataSeeder UserNotificationDataSeeder { get; }
public AuthServerInitializeDataSeeder(IdentityUserNotificationDataSeeder userNotificationDataSeeder)
{
UserNotificationDataSeeder = userNotificationDataSeeder;
}
public virtual async Task SeedAsync(DataSeedContext context)
{
await UserNotificationDataSeeder.SeedAsync(context);
}
}

89
aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer.DbMigrator/DataSeeds/IdentityUserNotificationDataSeeder.cs

@ -0,0 +1,89 @@
using LINGYUN.Abp.Identity.Notifications;
using LINGYUN.Abp.Notifications;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Identity;
using Volo.Abp.Users;
namespace LINGYUN.Abp.MicroService.AuthServer.DataSeeds;
public class IdentityUserNotificationDataSeeder : ITransientDependency
{
public ILogger<IdentityUserNotificationDataSeeder> Logger { protected get; set; }
protected IdentityUserManager IdentityUserManager { get; }
protected INotificationSender NotificationSender { get; }
protected INotificationSubscriptionManager NotificationSubscriptionManager { get; }
public IdentityUserNotificationDataSeeder(
IdentityUserManager identityUserManager,
INotificationSender notificationSender,
INotificationSubscriptionManager notificationSubscriptionManager)
{
IdentityUserManager = identityUserManager;
NotificationSender = notificationSender;
NotificationSubscriptionManager = notificationSubscriptionManager;
Logger = NullLogger<IdentityUserNotificationDataSeeder>.Instance;
}
public virtual async Task SeedAsync(DataSeedContext context)
{
await SubscribeDefaultNotifierAsync(context);
}
protected async virtual Task SubscribeDefaultNotifierAsync(DataSeedContext context)
{
var user = await IdentityUserManager.FindByNameAsync("admin");
if (user == null)
{
Logger.LogInformation("No user information named {UserName} was found, so default messages cannot be subscribed to.", "admin");
return;
}
Logger.LogInformation("User {UserId} has subscribed to default notifications.", user.Id);
var userIdentifer = new UserIdentifier(user.Id, user.UserName);
// 订阅内置通知
await NotificationSubscriptionManager
.SubscribeAsync(
context.TenantId,
userIdentifer,
DefaultNotifications.SystemNotice);
await NotificationSubscriptionManager
.SubscribeAsync(
context.TenantId,
userIdentifer,
DefaultNotifications.OnsideNotice);
await NotificationSubscriptionManager
.SubscribeAsync(
context.TenantId,
userIdentifer,
DefaultNotifications.ActivityNotice);
// 新用户订阅会话过期通知
await NotificationSubscriptionManager
.SubscribeAsync(
context.TenantId,
userIdentifer,
IdentityNotificationNames.Session.ExpirationSession);
// 新用户订阅不活跃用户相关通知
await NotificationSubscriptionManager
.SubscribeAsync(
context.TenantId,
userIdentifer,
IdentityNotificationNames.IdentityUser.InactiveUserReminderNotifier);
await NotificationSubscriptionManager
.SubscribeAsync(
context.TenantId,
userIdentifer,
IdentityNotificationNames.IdentityUser.InactiveUserDeactivationNotifier);
// 订阅用户欢迎消息
await NotificationSubscriptionManager
.SubscribeAsync(
context.TenantId,
userIdentifer,
UserNotificationNames.WelcomeToApplication);
Logger.LogInformation("User {UserId} is subscribed to notifications by default.", user.Id);
}
}

3
aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer.DbMigrator/LINGYUN.Abp.MicroService.AuthServer.DbMigrator.csproj

@ -28,6 +28,9 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\modules\identity\LINGYUN.Abp.Identity.Notifications\LINGYUN.Abp.Identity.Notifications.csproj" />
<ProjectReference Include="..\..\modules\realtime-notifications\LINGYUN.Abp.Notifications.Common\LINGYUN.Abp.Notifications.Common.csproj" />
<ProjectReference Include="..\..\modules\realtime-notifications\LINGYUN.Abp.Notifications.EntityFrameworkCore\LINGYUN.Abp.Notifications.EntityFrameworkCore.csproj" />
<ProjectReference Include="..\..\modules\saas\LINGYUN.Abp.Saas.EntityFrameworkCore\LINGYUN.Abp.Saas.EntityFrameworkCore.csproj" />
<ProjectReference Include="..\LINGYUN.Abp.MicroService.AuthServer.EntityFrameworkCore\LINGYUN.Abp.MicroService.AuthServer.EntityFrameworkCore.csproj" />
</ItemGroup>

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

@ -6,6 +6,7 @@ using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Guids;
using Volo.Abp.Identity;
using Volo.Abp.Roles;
namespace LINGYUN.Abp.MicroService.AuthServer.DataSeeds;
public class IdentityUserRoleDataSeeder : ITransientDependency
@ -54,7 +55,7 @@ public class IdentityUserRoleDataSeeder : ITransientDependency
{
await IdentityOptions.SetAsync();
const string adminRoleName = "admin";
const string adminRoleName = AbpRoleConsts.AdminRoleName;
var adminUserName = context[AdminUserNamePropertyName] as string ?? AdminUserNameDefaultValue;
Guid adminRoleId;
@ -86,10 +87,9 @@ public class IdentityUserRoleDataSeeder : ITransientDependency
var adminEmailAddress = context[AdminEmailPropertyName] as string ?? AdminEmailDefaultValue;
var adminPassword = context[AdminPasswordPropertyName] as string ?? AdminPasswordDefaultValue;
var adminUser = await UserManager.FindByNameAsync(adminUserName);
if (adminUser == null)
if (await UserManager.FindByNameAsync(adminUserName) == null)
{
adminUser = new IdentityUser(
var adminUser = new IdentityUser(
adminUserId,
adminUserName,
adminEmailAddress,
@ -106,7 +106,7 @@ public class IdentityUserRoleDataSeeder : ITransientDependency
private async Task SeedDefaultRoleAsync(DataSeedContext context)
{
const string defaultRoleName = "Users";
if (await RoleManager.FindByNameAsync(defaultRoleName) != null)
if (await RoleManager.FindByNameAsync(defaultRoleName) == null)
{
var roleId = GuidGenerator.Create();
var defaultRole = new IdentityRole(

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

@ -116,13 +116,10 @@ public partial class AuthServerModule
{
builder.AddValidation(options =>
{
var validAudiences = configuration.GetSection("AuthServer:ValidAudiences").Get<List<string>>();
if (validAudiences?.Count > 0)
var validAudiences = configuration.GetSection("AuthServer:ValidAudiences").Get<string[]>();
if (validAudiences?.Length > 0)
{
foreach (var audience in validAudiences)
{
options.AddAudiences(audience);
}
options.AddAudiences(validAudiences);
}
options.UseLocalServer();
@ -427,6 +424,11 @@ public partial class AuthServerModule
options.TokenValidationParameters.ValidIssuers = validIssuers;
options.TokenValidationParameters.IssuerValidator = TokenWildcardIssuerValidator.IssuerValidator;
}
var validAudiences = configuration.GetSection("AuthServer:ValidAudiences").Get<List<string>>();
if (validAudiences?.Count > 0)
{
options.TokenValidationParameters.ValidAudiences = validAudiences;
}
});
services

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

@ -101,7 +101,21 @@
"AuthServer": {
"Authority": "http://localhost:44385/",
"Audience": "auth-server",
"ValidAudiences": [ "lingyun-abp-application" ],
"ValidAudiences": [
"api-gateway",
"auth-server",
"admin-service",
"ai-service",
"identity-service",
"localization-service",
"message-service",
"platform-service",
"task-service",
"webhook-service",
"wechat-service",
"workflow-service",
"lingyun-abp-application"
],
"MapInboundClaims": false,
"RequireHttpsMetadata": false
},
@ -138,7 +152,8 @@
"Override": {
"System": "Warning",
"Microsoft": "Warning",
"DotNetCore": "Debug"
"DotNetCore": "Warning",
"OpenIddict": "Warning"
}
},
"WriteTo": [

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

@ -34,7 +34,8 @@
"Override": {
"System": "Warning",
"Microsoft": "Warning",
"DotNetCore": "Information"
"DotNetCore": "Warning",
"OpenIddict": "Warning"
}
},
"Enrich": [ "FromLogContext", "WithProcessId", "WithThreadId", "WithEnvironmentName", "WithMachineName", "WithApplicationName", "WithUniqueId" ],

7
aspnet-core/aspire/LINGYUN.Abp.MicroService.IdentityService/Handlers/IdentitySessionAccessEventHandler.cs

@ -86,8 +86,7 @@ public class IdentitySessionAccessEventHandler :
[UnitOfWork]
public async virtual Task HandleEventAsync(IdentityUserSessionPasswordChangedEto eventData)
{
if (!eventData.SessionId.IsNullOrWhiteSpace() &&
Guid.TryParse(eventData.SessionId, out var exceptSessionId))
if (!eventData.SessionId.IsNullOrWhiteSpace())
{
// 用户密码更新使会话过期
var lockKey = $"{nameof(IdentitySessionAccessEventHandler)}_{nameof(IdentityUserSessionPasswordChangedEto)}";
@ -103,7 +102,9 @@ public class IdentitySessionAccessEventHandler :
Logger.LogDebug("Due to the password update of user {Id}, all sessions have been revoked.", eventData.Id);
await IdentitySessionStore.RevokeAllAsync(eventData.Id, exceptSessionId);
var session = await IdentitySessionStore.FindAsync(eventData.SessionId);
await IdentitySessionStore.RevokeAllAsync(eventData.Id, session?.Id);
}
}

37
aspnet-core/aspire/LINGYUN.Abp.MicroService.MessageService.EntityFrameworkCore/DataSeeds/NotificationDataSeeder.cs

@ -7,7 +7,6 @@ using System.Threading.Tasks;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Users;
namespace LINGYUN.Abp.MicroService.MessageService.DataSeeds;
@ -28,45 +27,9 @@ public class NotificationDataSeeder : ITransientDependency
public virtual async Task SeedAsync(DataSeedContext context)
{
await SubscribeDefaultNotifierAsync(context);
await SeedWelcomeNotifierAsync(context);
}
public async virtual Task SubscribeDefaultNotifierAsync(DataSeedContext context)
{
if (!context.Properties.TryGetValue(MessageServiceDataSeedConsts.AdminUserIdPropertyName, out var userIdString) ||
!Guid.TryParse(userIdString?.ToString(), out var adminUserId))
{
return;
}
var adminUserName = context.Properties.GetOrDefault(MessageServiceDataSeedConsts.AdminUserNamePropertyName)?.ToString()
?? MessageServiceDataSeedConsts.AdminUserNameDefaultValue;
var userIdentifer = new UserIdentifier(adminUserId, adminUserName);
// 订阅内置通知
await NotificationSubscriptionManager
.SubscribeAsync(
context.TenantId,
userIdentifer,
DefaultNotifications.SystemNotice);
await NotificationSubscriptionManager
.SubscribeAsync(
context.TenantId,
userIdentifer,
DefaultNotifications.OnsideNotice);
await NotificationSubscriptionManager
.SubscribeAsync(
context.TenantId,
userIdentifer,
DefaultNotifications.ActivityNotice);
// 订阅用户欢迎消息
await NotificationSubscriptionManager
.SubscribeAsync(
context.TenantId,
userIdentifer,
UserNotificationNames.WelcomeToApplication);
}
public async virtual Task SeedWelcomeNotifierAsync(DataSeedContext context)
{
try

13
aspnet-core/framework/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/ApplicationMenu.cs

@ -105,6 +105,19 @@ public class ApplicationMenu : IHasMenuItems, IHasExtraProperties
return menuItem;
}
public ApplicationMenu WithRoles(string[] roles)
{
this.SetProperty("roles", roles.JoinAsString(";"));
return this;
}
public string[] GetRoles()
{
var roles = this.GetProperty<string>("roles") ?? "";
return roles.Split(";");
}
public override string ToString()
{
return $"[ApplicationMenu] Name = {Name}";

5
aspnet-core/migrations/LY.MicroService.AuthServer.DbMigrator/AuthServerDbMigratorHostedService.cs

@ -42,6 +42,11 @@ public class AuthServerDbMigratorHostedService : IHostedService
.GetRequiredService<AuthServerDbMigrationService>()
.CheckAndApplyDatabaseMigrationsAsync();
await application
.ServiceProvider
.GetRequiredService<AuthServerInitializeDataSeeder>()
.SeedAsync(new DataSeedContext());
await application.ShutdownAsync();
_hostApplicationLifetime.StopApplication();

8
aspnet-core/migrations/LY.MicroService.AuthServer.DbMigrator/AuthServerDbMigratorModule.cs

@ -1,4 +1,7 @@
using LY.MicroService.AuthServer.EntityFrameworkCore;
using LINGYUN.Abp.Identity.Notifications;
using LINGYUN.Abp.Notifications.Common;
using LINGYUN.Abp.Notifications.EntityFrameworkCore;
using LY.MicroService.AuthServer.EntityFrameworkCore;
using Volo.Abp.Autofac;
using Volo.Abp.Modularity;
@ -6,6 +9,9 @@ namespace LY.MicroService.AuthServer.DbMigrator;
[DependsOn(
typeof(AuthServerMigrationsEntityFrameworkCoreModule),
typeof(AbpNotificationsEntityFrameworkCoreModule),
typeof(AbpNotificationsCommonModule),
typeof(AbpIdentityNotificationsModule),
typeof(AbpAutofacModule)
)]
public partial class AuthServerDbMigratorModule : AbpModule

20
aspnet-core/migrations/LY.MicroService.AuthServer.DbMigrator/AuthServerInitializeDataSeeder.cs

@ -0,0 +1,20 @@
using LY.MicroService.AuthServer.DbMigrator.DataSeeds;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
namespace LY.MicroService.AuthServer.DbMigrator;
public class AuthServerInitializeDataSeeder : ITransientDependency
{
protected IdentityUserNotificationDataSeeder UserNotificationDataSeeder { get; }
public AuthServerInitializeDataSeeder(IdentityUserNotificationDataSeeder userNotificationDataSeeder)
{
UserNotificationDataSeeder = userNotificationDataSeeder;
}
public virtual async Task SeedAsync(DataSeedContext context)
{
await UserNotificationDataSeeder.SeedAsync(context);
}
}

89
aspnet-core/migrations/LY.MicroService.AuthServer.DbMigrator/DataSeeds/IdentityUserNotificationDataSeeder.cs

@ -0,0 +1,89 @@
using LINGYUN.Abp.Identity.Notifications;
using LINGYUN.Abp.Notifications;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Identity;
using Volo.Abp.Users;
namespace LY.MicroService.AuthServer.DbMigrator.DataSeeds;
public class IdentityUserNotificationDataSeeder : ITransientDependency
{
public ILogger<IdentityUserNotificationDataSeeder> Logger { protected get; set; }
protected IdentityUserManager IdentityUserManager { get; }
protected INotificationSender NotificationSender { get; }
protected INotificationSubscriptionManager NotificationSubscriptionManager { get; }
public IdentityUserNotificationDataSeeder(
IdentityUserManager identityUserManager,
INotificationSender notificationSender,
INotificationSubscriptionManager notificationSubscriptionManager)
{
IdentityUserManager = identityUserManager;
NotificationSender = notificationSender;
NotificationSubscriptionManager = notificationSubscriptionManager;
Logger = NullLogger<IdentityUserNotificationDataSeeder>.Instance;
}
public virtual async Task SeedAsync(DataSeedContext context)
{
await SubscribeDefaultNotifierAsync(context);
}
protected async virtual Task SubscribeDefaultNotifierAsync(DataSeedContext context)
{
var user = await IdentityUserManager.FindByNameAsync("admin");
if (user == null)
{
Logger.LogInformation("No user information named {UserName} was found, so default messages cannot be subscribed to.", "admin");
return;
}
Logger.LogInformation("User {UserId} has subscribed to default notifications.", user.Id);
var userIdentifer = new UserIdentifier(user.Id, user.UserName);
// 订阅内置通知
await NotificationSubscriptionManager
.SubscribeAsync(
context.TenantId,
userIdentifer,
DefaultNotifications.SystemNotice);
await NotificationSubscriptionManager
.SubscribeAsync(
context.TenantId,
userIdentifer,
DefaultNotifications.OnsideNotice);
await NotificationSubscriptionManager
.SubscribeAsync(
context.TenantId,
userIdentifer,
DefaultNotifications.ActivityNotice);
// 新用户订阅会话过期通知
await NotificationSubscriptionManager
.SubscribeAsync(
context.TenantId,
userIdentifer,
IdentityNotificationNames.Session.ExpirationSession);
// 新用户订阅不活跃用户相关通知
await NotificationSubscriptionManager
.SubscribeAsync(
context.TenantId,
userIdentifer,
IdentityNotificationNames.IdentityUser.InactiveUserReminderNotifier);
await NotificationSubscriptionManager
.SubscribeAsync(
context.TenantId,
userIdentifer,
IdentityNotificationNames.IdentityUser.InactiveUserDeactivationNotifier);
// 订阅用户欢迎消息
await NotificationSubscriptionManager
.SubscribeAsync(
context.TenantId,
userIdentifer,
UserNotificationNames.WelcomeToApplication);
Logger.LogInformation("User {UserId} is subscribed to notifications by default.", user.Id);
}
}

3
aspnet-core/migrations/LY.MicroService.AuthServer.DbMigrator/LY.MicroService.AuthServer.DbMigrator.csproj

@ -32,6 +32,9 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\modules\identity\LINGYUN.Abp.Identity.Notifications\LINGYUN.Abp.Identity.Notifications.csproj" />
<ProjectReference Include="..\..\modules\realtime-notifications\LINGYUN.Abp.Notifications.Common\LINGYUN.Abp.Notifications.Common.csproj" />
<ProjectReference Include="..\..\modules\realtime-notifications\LINGYUN.Abp.Notifications.EntityFrameworkCore\LINGYUN.Abp.Notifications.EntityFrameworkCore.csproj" />
<ProjectReference Include="..\..\modules\saas\LINGYUN.Abp.Saas.EntityFrameworkCore\LINGYUN.Abp.Saas.EntityFrameworkCore.csproj" />
<ProjectReference Include="..\LY.MicroService.AuthServer.EntityFrameworkCore\LY.MicroService.AuthServer.EntityFrameworkCore.csproj" />
</ItemGroup>

139
aspnet-core/migrations/LY.MicroService.RealtimeMessage.EntityFrameworkCore/DataSeeds/NotificationDataSeeder.cs

@ -0,0 +1,139 @@
using LINGYUN.Abp.Notifications;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Users;
namespace LY.MicroService.RealtimeMessage.EntityFrameworkCore.DataSeeds;
public class NotificationDataSeeder : ITransientDependency
{
public ILogger<NotificationDataSeeder> Logger { protected get; set; }
protected INotificationSender NotificationSender { get; }
protected INotificationSubscriptionManager NotificationSubscriptionManager { get; }
public NotificationDataSeeder(
INotificationSender notificationSender,
INotificationSubscriptionManager notificationSubscriptionManager)
{
NotificationSender = notificationSender;
NotificationSubscriptionManager = notificationSubscriptionManager;
Logger = NullLogger<NotificationDataSeeder>.Instance;
}
public virtual async Task SeedAsync(DataSeedContext context)
{
await SubscribeDefaultNotifierAsync(context);
await SeedWelcomeNotifierAsync(context);
}
public async virtual Task SubscribeDefaultNotifierAsync(DataSeedContext context)
{
if (!context.Properties.TryGetValue(RealtimeMessageDataSeedConsts.AdminUserIdPropertyName, out var userIdString) ||
!Guid.TryParse(userIdString?.ToString(), out var adminUserId))
{
return;
}
var adminUserName = context.Properties.GetOrDefault(RealtimeMessageDataSeedConsts.AdminUserNamePropertyName)?.ToString()
?? RealtimeMessageDataSeedConsts.AdminUserNameDefaultValue;
var userIdentifer = new UserIdentifier(adminUserId, adminUserName);
// 订阅内置通知
await NotificationSubscriptionManager
.SubscribeAsync(
context.TenantId,
userIdentifer,
DefaultNotifications.SystemNotice);
await NotificationSubscriptionManager
.SubscribeAsync(
context.TenantId,
userIdentifer,
DefaultNotifications.OnsideNotice);
await NotificationSubscriptionManager
.SubscribeAsync(
context.TenantId,
userIdentifer,
DefaultNotifications.ActivityNotice);
// 新用户订阅会话过期通知
await NotificationSubscriptionManager
.SubscribeAsync(
context.TenantId,
userIdentifer,
"AbpIdentity.Session.Expiration");
// 新用户订阅不活跃用户相关通知
await NotificationSubscriptionManager
.SubscribeAsync(
context.TenantId,
userIdentifer,
"AbpIdentity.IdentityUser.InactiveUserReminderNotifier");
await NotificationSubscriptionManager
.SubscribeAsync(
context.TenantId,
userIdentifer,
"AbpIdentity.IdentityUser.InactiveUserDeactivationNotifier");
// 订阅用户欢迎消息
await NotificationSubscriptionManager
.SubscribeAsync(
context.TenantId,
userIdentifer,
UserNotificationNames.WelcomeToApplication);
}
public async virtual Task SeedWelcomeNotifierAsync(DataSeedContext context)
{
try
{
if (!context.TenantId.HasValue)
{
return;
}
if (!context.Properties.TryGetValue(RealtimeMessageDataSeedConsts.AdminUserIdPropertyName, out var userIdString) ||
!Guid.TryParse(userIdString?.ToString(), out var adminUserId))
{
return;
}
var adminEmailAddress = context.Properties.GetOrDefault(RealtimeMessageDataSeedConsts.AdminEmailPropertyName)?.ToString()
?? RealtimeMessageDataSeedConsts.AdminEmailDefaultValue;
var adminUserName = context.Properties.GetOrDefault(RealtimeMessageDataSeedConsts.AdminUserNamePropertyName)?.ToString()
?? RealtimeMessageDataSeedConsts.AdminUserNameDefaultValue;
var tenantAdminUserIdentifier = new UserIdentifier(adminUserId, adminEmailAddress);
// 租户管理员订阅事件
await NotificationSubscriptionManager
.SubscribeAsync(
context.TenantId,
tenantAdminUserIdentifier,
TenantNotificationNames.NewTenantRegistered);
Logger.LogInformation("publish new tenant notification..");
await NotificationSender.SendNofiterAsync(
TenantNotificationNames.NewTenantRegistered,
new NotificationTemplate(
TenantNotificationNames.NewTenantRegistered,
formUser: adminEmailAddress,
data: new Dictionary<string, object?>
{
{ "name", adminUserName },
{ "email", adminEmailAddress },
{ "id", context.TenantId },
}),
tenantAdminUserIdentifier,
context.TenantId,
NotificationSeverity.Success);
Logger.LogInformation("tenant administrator subscribes to new tenant events..");
}
catch (Exception ex)
{
Logger.LogWarning(ex, "Failed to send the tenant initialization notification.");
}
}
}

10
aspnet-core/migrations/LY.MicroService.RealtimeMessage.EntityFrameworkCore/RealtimeMessageDataSeedConsts.cs

@ -0,0 +1,10 @@
namespace LY.MicroService.RealtimeMessage.EntityFrameworkCore;
public class RealtimeMessageDataSeedConsts
{
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";
}

33
aspnet-core/migrations/LY.MicroService.RealtimeMessage.EntityFrameworkCore/RealtimeMessageDataSeeder.cs

@ -0,0 +1,33 @@
using LY.MicroService.RealtimeMessage.EntityFrameworkCore.DataSeeds;
using System.Threading.Tasks;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.MultiTenancy;
namespace LY.MicroService.RealtimeMessage.EntityFrameworkCore;
public class RealtimeMessageDataSeeder : ITransientDependency
{
protected NotificationDataSeeder NotificationDataSeeder { get; }
protected ICurrentTenant CurrentTenant { get; }
public RealtimeMessageDataSeeder(
ICurrentTenant currentTenant,
NotificationDataSeeder notificationDataSeeder)
{
CurrentTenant = currentTenant;
NotificationDataSeeder = notificationDataSeeder;
}
public async virtual Task SeedAsync(DataSeedContext context)
{
using (CurrentTenant.Change(context.TenantId))
{
await SeedNotificationAsync(context);
}
}
private async Task SeedNotificationAsync(DataSeedContext context)
{
await NotificationDataSeeder.SeedAsync(context);
}
}

11
aspnet-core/migrations/LY.MicroService.RealtimeMessage.EntityFrameworkCore/RealtimeMessageDbMigrationService.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;
@ -12,7 +13,10 @@ namespace LY.MicroService.RealtimeMessage.EntityFrameworkCore;
public class RealtimeMessageDbMigrationService : EfCoreRuntimeDbMigratorBase<RealtimeMessageMigrationsDbContext>, ITransientDependency
{
protected RealtimeMessageDataSeeder DataSeeder { get; }
public RealtimeMessageDbMigrationService(
RealtimeMessageDataSeeder dataSeeder,
ICurrentTenant currentTenant,
IUnitOfWorkManager unitOfWorkManager,
IServiceProvider serviceProvider,
@ -23,5 +27,12 @@ public class RealtimeMessageDbMigrationService : EfCoreRuntimeDbMigratorBase<Rea
ConnectionStringNameAttribute.GetConnStringName<RealtimeMessageMigrationsDbContext>(),
unitOfWorkManager, serviceProvider, currentTenant, abpDistributedLock, distributedEventBus, loggerFactory)
{
DataSeeder = dataSeeder;
}
protected async override Task SeedAsync()
{
// DbMigrator迁移数据种子
await DataSeeder.SeedAsync(new DataSeedContext());
}
}

12
aspnet-core/modules/account/LINGYUN.Abp.Account.Web/Pages/Account/SendCode.cshtml

@ -15,11 +15,15 @@
<abp-select asp-for="Input.SelectedProvider" label="@L["SelectedProvider"].Value" asp-items="@Model.Providers"></abp-select>
</div>
<div class="d-grid gap-2">
<abp-button type="submit" button-type="Primary" class="mt-2 mb-3">@L["SendVerifyCode"]</abp-button>
<abp-button type="submit" button-type="Primary" class="btn-block btn-lg">@L["SendVerifyCode"]</abp-button>
<abp-button type="button" button-type="Outline_Primary" class="btn-block btn-lg">
<a asp-page="./Login" asp-all-route-data="@(new Dictionary<string, string?> { { "returnUrl", Model.ReturnUrl }, { "returnUrlHash", Model.ReturnUrlHash } })">
<i class="fa fa-long-arrow-left"></i>
</a>
@L["Login"]
</abp-button>
</div>
<a asp-page="./Login" asp-all-route-data="@(new Dictionary<string, string?> {{"returnUrl", Model.ReturnUrl}, {"returnUrlHash", Model.ReturnUrlHash}})">
<i class="fa fa-long-arrow-left"></i> @L["Login"]
</a>
</form>
</div>
</div>

16
aspnet-core/modules/account/LINGYUN.Abp.Account.Web/Pages/Account/VerifyAuthenticatorCode.cshtml

@ -13,14 +13,18 @@
<input asp-for="Input.VerifyCode" class="form-control" />
<span asp-validation-for="Input.VerifyCode" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="RememberBrowser"></label>
<div class="mt-2">
<abp-input asp-for="RememberBrowser" />
</div>
<abp-button type="submit" button-type="Primary" class="btn-block btn-lg mt-3">@L["VerifyAuthenticatorCode"]</abp-button>
<a asp-page="./Login" asp-all-route-data="@(new Dictionary<string, string?> {{"returnUrl", Model.ReturnUrl}, {"returnUrlHash", Model.ReturnUrlHash}})">
<i class="fa fa-long-arrow-left"></i> @L["Login"]
</a>
<div class="d-grid gap-2">
<abp-button type="submit" button-type="Primary" class="btn-block btn-lg">@L["VerifyAuthenticatorCode"]</abp-button>
<abp-button type="button" button-type="Outline_Primary" class="btn-block btn-lg">
<a asp-page="./Login" asp-all-route-data="@(new Dictionary<string, string?> { { "returnUrl", Model.ReturnUrl }, { "returnUrlHash", Model.ReturnUrlHash } })">
<i class="fa fa-long-arrow-left"></i>
</a>
@L["Login"]
</abp-button>
</div>
</form>
</div>
</div>

19
aspnet-core/modules/account/LINGYUN.Abp.Account.Web/Pages/Account/VerifyCode.cshtml

@ -13,17 +13,18 @@
<div class="form-group">
<abp-input asp-for="Input.VerifyCode" label="@L["VerifyCode"].Value" class="form-control" />
</div>
<abp-row>
<abp-column>
<abp-input asp-for="Input.RememberBrowser" />
</abp-column>
</abp-row>
<div class="mt-2">
<abp-input asp-for="Input.RememberBrowser" />
</div>
<div class="d-grid gap-2">
<abp-button type="submit" button-type="Primary" class="mt-2 mb-3">@L["VerifyAuthenticatorCode"]</abp-button>
<abp-button type="submit" button-type="Primary" class="btn-block btn-lg">@L["VerifyAuthenticatorCode"]</abp-button>
<abp-button type="button" button-type="Outline_Primary" class="btn-block btn-lg">
<a asp-page="./SendCode" asp-all-route-data="@(new Dictionary<string, string?> { { "returnUrl", Model.ReturnUrl }, { "returnUrlHash", Model.ReturnUrlHash } })">
<i class="fa fa-long-arrow-left"></i>
</a>
@L["ReSendVerifyCode"]
</abp-button>
</div>
<a asp-page="./SendCode" asp-all-route-data="@(new Dictionary<string, string?> {{"returnUrl", Model.ReturnUrl}, {"returnUrlHash", Model.ReturnUrlHash}})">
<i class="fa fa-long-arrow-left"></i> @L["ReSendVerifyCode"]
</a>
</form>
</div>
</div>

5
aspnet-core/modules/platform/LINGYUN.Abp.UI.Navigation.VueVbenAdmin5/LINGYUN/Abp/UI/Navigation/VueVbenAdmin5/AbpUINavigationVueVbenAdmin5NavigationDefinitionProvider.cs

@ -106,6 +106,7 @@ public class AbpUINavigationVueVbenAdmin5NavigationDefinitionProvider : Navigati
component: "",
description: "账户管理",
icon: "mdi:account-outline")
.WithRoles(["Users"])
.SetProperty("hideInMenu", "true")
.SetProperty("title", "abp.account.title");
@ -117,6 +118,8 @@ public class AbpUINavigationVueVbenAdmin5NavigationDefinitionProvider : Navigati
component: "/account/my-settings/index",
icon: "tdesign:user-setting",
description: "个人设置")
.WithRoles(["Users"])
.SetProperty("hideInMenu", "true")
.SetProperty("title", "abp.account.settings.title")
);
@ -133,6 +136,7 @@ public class AbpUINavigationVueVbenAdmin5NavigationDefinitionProvider : Navigati
description: "仪表盘",
icon: "lucide:layout-dashboard",
order: -1)
.WithRoles(["Users"])
.SetProperty("title", "page.dashboard.title");
dashboard.AddItem(
@ -155,6 +159,7 @@ public class AbpUINavigationVueVbenAdmin5NavigationDefinitionProvider : Navigati
component: "/dashboard/workspace/index",
icon: "carbon:workspace",
description: "工作台")
.WithRoles(["Users"])
.SetProperty("title", "page.dashboard.workspace")
);

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

@ -6,6 +6,7 @@ using LINGYUN.Platform.Utils;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Data;
@ -81,6 +82,7 @@ public class VueVbenAdmin5NavigationSeedContributor : NavigationSeedContributor
["icon"] = menu.Icon ?? "",
["order"] = menu.Order
};
var roles = menu.GetRoles();
var seedMenu = await SeedMenuAsync(
layout: layout,
@ -95,7 +97,7 @@ public class VueVbenAdmin5NavigationSeedContributor : NavigationSeedContributor
parentId: null,
tenantId: layout.TenantId,
meta: menuMeta,
roles: new string[] { "admin" });
roles: roles.Union(["admin"]).ToArray());
await SeedDefinitionMenuItemsAsync(layout, data, seedMenu, menu.Items, multiTenancySides);
}
@ -121,21 +123,22 @@ public class VueVbenAdmin5NavigationSeedContributor : NavigationSeedContributor
["icon"] = item.Icon ?? "",
["order"] = item.Order
};
var roles = item.GetRoles();
var seedMenu = await SeedMenuAsync(
layout: layout,
data: data,
name: item.Name,
path: item.Url,
code: CodeNumberGenerator.AppendCode(menu.Code, CodeNumberGenerator.CreateCode(index)),
component: item.Component.IsNullOrWhiteSpace() ? layout.Path! : item.Component,
displayName: item.DisplayName,
redirect: item.Redirect,
description: item.Description,
parentId: menu.Id,
tenantId: menu.TenantId,
meta: menuMeta,
roles: new string[] { "admin" });
layout: layout,
data: data,
name: item.Name,
path: item.Url,
code: CodeNumberGenerator.AppendCode(menu.Code, CodeNumberGenerator.CreateCode(index)),
component: item.Component.IsNullOrWhiteSpace() ? layout.Path! : item.Component,
displayName: item.DisplayName,
redirect: item.Redirect,
description: item.Description,
parentId: menu.Id,
tenantId: menu.TenantId,
meta: menuMeta,
roles: roles.Union(["admin"]).ToArray());
await SeedDefinitionMenuItemsAsync(layout, data, seedMenu, item.Items, multiTenancySides);
@ -189,7 +192,7 @@ public class VueVbenAdmin5NavigationSeedContributor : NavigationSeedContributor
if (roles != null)
{
foreach (var role in roles)
foreach (var role in roles.Distinct())
{
await RouteDataSeeder.SeedRoleMenuAsync(role, menu, tenantId);
}
@ -197,7 +200,7 @@ public class VueVbenAdmin5NavigationSeedContributor : NavigationSeedContributor
if (users != null)
{
foreach (var user in users)
foreach (var user in users.Distinct())
{
await RouteDataSeeder.SeedUserMenuAsync(user, menu, tenantId);
}

3
aspnet-core/modules/platform/LINGYUN.Platform.Application/LINGYUN/Platform/Menus/MenuAppService.cs

@ -86,8 +86,7 @@ public class MenuAppService : PlatformApplicationServiceBase, IMenuAppService
public async virtual Task<ListResultDto<MenuDto>> GetAllAsync(MenuGetAllInput input)
{
var menus = await MenuRepository.GetAllAsync(
input.Filter, input.Sorting,
input.Framework, input.ParentId, input.LayoutId);
input.Filter, input.Framework, input.ParentId, input.LayoutId, input.Sorting);
return new ListResultDto<MenuDto>(
ObjectMapper.Map<List<Menu>, List<MenuDto>>(menus));

2
aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Menus/IMenuRepository.cs

@ -105,9 +105,9 @@ public interface IMenuRepository : IBasicRepository<Menu, Guid>
Task<List<Menu>> GetAllAsync(
string? filter = null,
string? framework = null,
string? sorting = nameof(Menu.Code),
Guid? parentId = null,
Guid? layoutId = null,
string? sorting = nameof(Menu.Code),
CancellationToken cancellationToken = default);
Task RemoveAllRolesAsync(

2
aspnet-core/modules/platform/LINGYUN.Platform.EntityFrameworkCore/LINGYUN/Platform/Menus/EfCoreMenuRepository.cs

@ -165,9 +165,9 @@ public class EfCoreMenuRepository : EfCoreRepository<IPlatformDbContext, Menu, G
public async virtual Task<List<Menu>> GetAllAsync(
string? filter = null,
string? framework = null,
string? sorting = nameof(Menu.Code),
Guid? parentId = null,
Guid? layoutId = null,
string? sorting = nameof(Menu.Code),
CancellationToken cancellationToken = default)
{
if (sorting.IsNullOrWhiteSpace())

Loading…
Cancel
Save