Browse Source

Merge pull request #316 from colinin/4.4

fix message service irrationality
pull/364/head
yx lin 4 years ago
committed by GitHub
parent
commit
79fbc4f9b0
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/Hubs/MessagesHub.cs
  2. 56
      aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Group/Group.cs
  3. 10
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain.Shared/LINGYUN.Abp.MessageService.Domain.Shared.csproj
  4. 50
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain.Shared/LINGYUN/Abp/MessageService/AbpMessageServiceDomainSharedModule.cs
  5. 10
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN.Abp.MessageService.Domain.csproj
  6. 93
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/AbpMessageServiceDomainModule.cs
  7. 37
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Localization/Resources/en.json
  8. 37
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Localization/Resources/zh-Hans.json
  9. 4
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Group/EfCoreUserChatGroupRepository.cs
  10. 442
      aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/EventBus/Distributed/NotificationEventHandler.cs
  11. 155
      aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/EventBus/Distributed/TenantCreateEventHandler.cs
  12. 135
      aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/EventBus/Local/UserCreateSendWelcomeEventHandler.cs
  13. 2
      aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Localization/HttpApiHost/en.json
  14. 2
      aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Localization/HttpApiHost/zh-Hans.json
  15. 8
      aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/DataSeeder/ElementAdminDataSeedContributor.cs
  16. 72
      aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/DataSeeder/VbenAdminDataSeedContributor.cs

5
aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/Hubs/MessagesHub.cs

@ -43,8 +43,9 @@ namespace LINGYUN.Abp.IM.SignalR.Hubs
var userGroups = await UserGroupStore.GetUserGroupsAsync(client.TenantId, client.UserId.Value);
foreach (var group in userGroups)
{
await Groups.AddToGroupAsync(client.ConnectionId, group.Name);
var groupClient = Clients.Group(group.Name);
// 应使用群组标识
await Groups.AddToGroupAsync(client.ConnectionId, group.Id);
var groupClient = Clients.Group(group.Id);
if (groupClient != null)
{
// 发送用户上线通知

56
aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Group/Group.cs

@ -1,26 +1,30 @@
namespace LINGYUN.Abp.IM.Group
{
public class Group
{
/// <summary>
/// 群组名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 允许匿名聊天
/// </summary>
public bool AllowAnonymous { get; set; }
/// <summary>
/// 允许发送消息
/// </summary>
public bool AllowSendMessage { get; set; }
/// <summary>
/// 最大用户数
/// </summary>
public int MaxUserLength { get; set; }
/// <summary>
/// 群组用户数
/// </summary>
public int GroupUserCount { get; set; }
}
}
namespace LINGYUN.Abp.IM.Group
{
public class Group
{
/// <summary>
/// 群组标识
/// </summary>
public string Id { get; set; }
/// <summary>
/// 群组名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 允许匿名聊天
/// </summary>
public bool AllowAnonymous { get; set; }
/// <summary>
/// 允许发送消息
/// </summary>
public bool AllowSendMessage { get; set; }
/// <summary>
/// 最大用户数
/// </summary>
public int MaxUserLength { get; set; }
/// <summary>
/// 群组用户数
/// </summary>
public int GroupUserCount { get; set; }
}
}

10
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain.Shared/LINGYUN.Abp.MessageService.Domain.Shared.csproj

@ -7,6 +7,16 @@
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<None Remove="LINGYUN\Abp\MessageService\Localization\Resources\en.json" />
<None Remove="LINGYUN\Abp\MessageService\Localization\Resources\zh-Hans.json" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="LINGYUN\Abp\MessageService\Localization\Resources\en.json" />
<EmbeddedResource Include="LINGYUN\Abp\MessageService\Localization\Resources\zh-Hans.json" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.Localization" Version="4.4.0" />
<PackageReference Include="Volo.Abp.Users.Domain.Shared" Version="4.4.0" />

50
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain.Shared/LINGYUN/Abp/MessageService/AbpMessageServiceDomainSharedModule.cs

@ -1,18 +1,32 @@
using LINGYUN.Abp.MessageService.Localization;
using Volo.Abp.Localization;
using Volo.Abp.Modularity;
namespace LINGYUN.Abp.MessageService
{
[DependsOn(typeof(AbpLocalizationModule))]
public class AbpMessageServiceDomainSharedModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpLocalizationOptions>(options =>
{
options.Resources.Add<MessageServiceResource>("en");
});
}
}
}
using LINGYUN.Abp.MessageService.Localization;
using Volo.Abp.Localization;
using Volo.Abp.Localization.ExceptionHandling;
using Volo.Abp.Modularity;
using Volo.Abp.VirtualFileSystem;
namespace LINGYUN.Abp.MessageService
{
[DependsOn(typeof(AbpLocalizationModule))]
public class AbpMessageServiceDomainSharedModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<AbpMessageServiceDomainSharedModule>();
});
Configure<AbpLocalizationOptions>(options =>
{
options.Resources
.Add<MessageServiceResource>("en")
.AddVirtualJson("/LINGYUN/Abp/MessageService/Localization/Resources");
});
Configure<AbpExceptionLocalizationOptions>(options =>
{
options.MapCodeNamespace(MessageServiceErrorCodes.Namespace, typeof(MessageServiceResource));
});
}
}
}

10
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN.Abp.MessageService.Domain.csproj

@ -7,16 +7,6 @@
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<None Remove="LINGYUN\Abp\MessageService\Localization\Resources\en.json" />
<None Remove="LINGYUN\Abp\MessageService\Localization\Resources\zh-Hans.json" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="LINGYUN\Abp\MessageService\Localization\Resources\en.json" />
<EmbeddedResource Include="LINGYUN\Abp\MessageService\Localization\Resources\zh-Hans.json" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.Caching" Version="4.4.0" />
<PackageReference Include="Volo.Abp.Ddd.Domain" Version="4.4.0" />

93
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/AbpMessageServiceDomainModule.cs

@ -1,55 +1,38 @@
using LINGYUN.Abp.MessageService.Chat;
using LINGYUN.Abp.MessageService.Localization;
using LINGYUN.Abp.MessageService.Mapper;
using LINGYUN.Abp.MessageService.ObjectExtending;
using Volo.Abp.AutoMapper;
using Volo.Abp.Caching;
using Volo.Abp.Localization;
using Volo.Abp.Localization.ExceptionHandling;
using Volo.Abp.Modularity;
using Volo.Abp.ObjectExtending.Modularity;
using Volo.Abp.VirtualFileSystem;
namespace LINGYUN.Abp.MessageService
{
[DependsOn(
typeof(AbpAutoMapperModule),
typeof(AbpCachingModule),
typeof(AbpMessageServiceDomainSharedModule))]
public class AbpMessageServiceDomainModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpAutoMapperOptions>(options =>
{
options.AddProfile<MessageServiceDomainAutoMapperProfile>(validate: true);
});
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<AbpMessageServiceDomainModule>();
});
Configure<AbpLocalizationOptions>(options =>
{
options.Resources
.Get<MessageServiceResource>()
.AddVirtualJson("/LINGYUN/Abp/MessageService/Localization/Resources");
});
Configure<AbpExceptionLocalizationOptions>(options =>
{
options.MapCodeNamespace(MessageServiceErrorCodes.Namespace, typeof(MessageServiceResource));
});
}
public override void PostConfigureServices(ServiceConfigurationContext context)
{
ModuleExtensionConfigurationHelper.ApplyEntityConfigurationToEntity(
MessageServiceModuleExtensionConsts.ModuleName,
MessageServiceModuleExtensionConsts.EntityNames.Message,
typeof(Message)
);
}
}
}
using LINGYUN.Abp.MessageService.Chat;
using LINGYUN.Abp.MessageService.Localization;
using LINGYUN.Abp.MessageService.Mapper;
using LINGYUN.Abp.MessageService.ObjectExtending;
using Volo.Abp.AutoMapper;
using Volo.Abp.Caching;
using Volo.Abp.Localization;
using Volo.Abp.Localization.ExceptionHandling;
using Volo.Abp.Modularity;
using Volo.Abp.ObjectExtending.Modularity;
using Volo.Abp.VirtualFileSystem;
namespace LINGYUN.Abp.MessageService
{
[DependsOn(
typeof(AbpAutoMapperModule),
typeof(AbpCachingModule),
typeof(AbpMessageServiceDomainSharedModule))]
public class AbpMessageServiceDomainModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpAutoMapperOptions>(options =>
{
options.AddProfile<MessageServiceDomainAutoMapperProfile>(validate: true);
});
}
public override void PostConfigureServices(ServiceConfigurationContext context)
{
ModuleExtensionConfigurationHelper.ApplyEntityConfigurationToEntity(
MessageServiceModuleExtensionConsts.ModuleName,
MessageServiceModuleExtensionConsts.EntityNames.Message,
typeof(Message)
);
}
}
}

37
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Localization/Resources/en.json

@ -1,37 +0,0 @@
{
"culture": "en",
"texts": {
"LINGYUN.Abp.Message:01400": "Sending the message failed: The message is incomplete!",
"LINGYUN.Abp.Message:01401": "You have not joined the group and cannot operate!",
"LINGYUN.Abp.Message:02301": "Group application has been sent, waiting for administrator's approval",
"LINGYUN.Abp.Message:02302": "You need to validate the questions to join the group chat",
"LINGYUN.Abp.Message:02400": "The administrator has turned on silence mode!",
"LINGYUN.Abp.Message:02403": "The administrator has banned you from speaking!",
"LINGYUN.Abp.Message:02401": "The administrator does not allow anonymous speaking!",
"LINGYUN.Abp.Message:02404": "Sending the message failed: the group does not exist or is disbanded!",
"LINGYUN.Abp.Message:03301": "Friend request has been sent, waiting for the other party's approval",
"LINGYUN.Abp.Message:03302": "You need to verify the problem to add friends",
"LINGYUN.Abp.Message:03400": "The user has rejected all messages!",
"LINGYUN.Abp.Message:03401": "The user rejects the message you sent!",
"LINGYUN.Abp.Message:03402": "Users do not receive anonymous comments!",
"LINGYUN.Abp.Message:03403": "Sending the message failed: the person needs to agree to add a friend!",
"LINGYUN.Abp.Message:03404": "Sending the message failed: the user does not exist or is deactivated!",
"LINGYUN.Abp.Message:03410": "Users refuse to add friends",
"LINGYUN.Abp.Message:03411": "The other party is already your friend or has sent an authentication request. The operation cannot be repeated!",
"Notifications:MultiTenancy": "Multi Tenancy",
"Notifications:Users": "Users",
"Notifications:NewTenantRegisterd": "Tenant creation notification",
"Notifications:WelcomeToApplication": "User Welcome Notice",
"Notifications:IM": "Instant Messaging",
"Notifications:FriendValidation": "Friend verification notification",
"Notifications:NewFriend": "New friend notification",
"Notifications:RequestAddNewFriend": "User {name} has requested that you be added as a friend",
"Notifications:RequestAddNewFriendDetail": "Description: {description}",
"Notifications:JoinGroup": "Join group notification",
"Notifications:ExitGroup": "Exit group notification",
"Notifications:DissolveGroup": "Dissolve group notification",
"AddNewFriendBySearchId": "Add by account search",
"WelcomeToApplicationFormUser": "User :{0} welcome to join us!",
"Messages:NewFriend": "I have added you as a friend, let's chat together!"
}
}

37
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Localization/Resources/zh-Hans.json

@ -1,37 +0,0 @@
{
"culture": "zh-Hans",
"texts": {
"LINGYUN.Abp.Message:01400": "发送消息失败: 消息不完整!",
"LINGYUN.Abp.Message:01401": "您还未加入群组,不能进行操作!",
"LINGYUN.Abp.Message:02301": "已发送群组申请,等待管理员同意",
"LINGYUN.Abp.Message:02302": "你需要验证问题才能加入群聊",
"LINGYUN.Abp.Message:02400": "管理员已开启全员禁言!",
"LINGYUN.Abp.Message:02403": "管理员已禁止您发言!",
"LINGYUN.Abp.Message:02401": "管理员不允许匿名发言!",
"LINGYUN.Abp.Message:02404": "发送消息失败: 群组不存在或已解散!",
"LINGYUN.Abp.Message:03301": "已发送好友申请,等待对方同意",
"LINGYUN.Abp.Message:03302": "你需要验证问题才能添加好友",
"LINGYUN.Abp.Message:03400": "用户已拒接所有消息!",
"LINGYUN.Abp.Message:03401": "用户拒绝您发送的消息!",
"LINGYUN.Abp.Message:03402": "用户不接收匿名发言!",
"LINGYUN.Abp.Message:03403": "需要对方同意添加好友才能发送消息!",
"LINGYUN.Abp.Message:03404": "发送消息失败: 用户不存在或已注销账号!",
"LINGYUN.Abp.Message:03410": "用户拒绝添加好友",
"LINGYUN.Abp.Message:03411": "对方已是您的好友或已发送验证请求,不能重复操作!",
"Notifications:MultiTenancy": "租户通知",
"Notifications:Users": "用户通知",
"Notifications:NewTenantRegisterd": "租户创建通知",
"Notifications:WelcomeToApplication": "用户欢迎通知",
"Notifications:IM": "即时通讯",
"Notifications:FriendValidation": "好友验证通知",
"Notifications:NewFriend": "新好友通知",
"Notifications:RequestAddNewFriend": "用户 {name} 请求添加您为好友",
"Notifications:RequestAddNewFriendDetail": "附加说明: {description}",
"Notifications:JoinGroup": "加入群组通知",
"Notifications:ExitGroup": "退出群组通知",
"Notifications:DissolveGroup": "群组解散通知",
"AddNewFriendBySearchId": "通过账号搜索添加",
"WelcomeToApplicationFormUser": "用户:{0} 欢迎您的加入!",
"Messages:NewFriend": "我已经添加您为好友,让我们一起聊天吧!"
}
}

4
aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Group/EfCoreUserChatGroupRepository.cs

@ -140,7 +140,8 @@ namespace LINGYUN.Abp.MessageService.Group
gp.AllowAnonymous,
gp.AllowSendMessage,
gp.MaxUserCount,
gp.Name
gp.Name,
gp.GroupId,
}
into cg
select new IM.Group.Group
@ -149,6 +150,7 @@ namespace LINGYUN.Abp.MessageService.Group
AllowSendMessage = cg.Key.AllowSendMessage,
MaxUserLength = cg.Key.MaxUserCount,
Name = cg.Key.Name,
Id = cg.Key.GroupId.ToString(),
GroupUserCount = cg.Count()
};

442
aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/EventBus/Distributed/NotificationEventHandler.cs

@ -1,221 +1,221 @@
using LINGYUN.Abp.MessageService.Utils;
using LINGYUN.Abp.Notifications;
using LINGYUN.Abp.RealTime;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.BackgroundJobs;
using Volo.Abp.DependencyInjection;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.Json;
using Volo.Abp.Uow;
namespace LINGYUN.Abp.MessageService.EventBus.Distributed
{
/// <summary>
/// 订阅通知发布事件,统一发布消息
/// </summary>
/// <remarks>
/// 作用在于SignalR客户端只会与一台服务器建立连接,
/// 只有启用了SignlR服务端的才能真正将消息发布到客户端
/// </remarks>
public class NotificationEventHandler : IDistributedEventHandler<NotificationEto<NotificationData>>, ITransientDependency
{
/// <summary>
/// Reference to <see cref="ILogger<DefaultNotificationDispatcher>"/>.
/// </summary>
public ILogger<NotificationEventHandler> Logger { get; set; }
/// <summary>
/// Reference to <see cref="AbpNotificationOptions"/>.
/// </summary>
protected AbpNotificationOptions Options { get; }
/// <summary>
/// Reference to <see cref="IJsonSerializer"/>.
/// </summary>
protected IJsonSerializer JsonSerializer { get; }
/// <summary>
/// Reference to <see cref="IBackgroundJobManager"/>.
/// </summary>
protected IBackgroundJobManager BackgroundJobManager { get; }
/// <summary>
/// Reference to <see cref="INotificationStore"/>.
/// </summary>
protected INotificationStore NotificationStore { get; }
/// <summary>
/// Reference to <see cref="INotificationDefinitionManager"/>.
/// </summary>
protected INotificationDefinitionManager NotificationDefinitionManager { get; }
/// <summary>
/// Reference to <see cref="INotificationSubscriptionManager"/>.
/// </summary>
protected INotificationSubscriptionManager NotificationSubscriptionManager { get; }
/// <summary>
/// Reference to <see cref="INotificationPublishProviderManager"/>.
/// </summary>
protected INotificationPublishProviderManager NotificationPublishProviderManager { get; }
/// <summary>
/// Initializes a new instance of the <see cref="NotificationEventHandler"/> class.
/// </summary>
public NotificationEventHandler(
IJsonSerializer jsonSerializer,
IBackgroundJobManager backgroundJobManager,
IOptions<AbpNotificationOptions> options,
INotificationStore notificationStore,
INotificationDefinitionManager notificationDefinitionManager,
INotificationSubscriptionManager notificationSubscriptionManager,
INotificationPublishProviderManager notificationPublishProviderManager)
{
Options = options.Value;
JsonSerializer = jsonSerializer;
BackgroundJobManager = backgroundJobManager;
NotificationStore = notificationStore;
NotificationDefinitionManager = notificationDefinitionManager;
NotificationSubscriptionManager = notificationSubscriptionManager;
NotificationPublishProviderManager = notificationPublishProviderManager;
Logger = NullLogger<NotificationEventHandler>.Instance;
}
[UnitOfWork]
public virtual async Task HandleEventAsync(NotificationEto<NotificationData> eventData)
{
// 如果上面过滤了应用程序,这里可以使用Get方法,否则,最好使用GetOrNull加以判断
var notification = NotificationDefinitionManager.GetOrNull(eventData.Name);
if (notification == null)
{
return;
}
var notificationInfo = new NotificationInfo
{
Name = notification.Name,
CreationTime = eventData.CreationTime,
Data = eventData.Data,
Severity = eventData.Severity,
Lifetime = notification.NotificationLifetime,
TenantId = eventData.TenantId,
Type = notification.NotificationType
};
notificationInfo.SetId(eventData.Id);
// TODO: 可以做成一个接口来序列化消息
notificationInfo.Data = NotificationDataConverter.Convert(notificationInfo.Data);
Logger.LogDebug($"Persistent notification {notificationInfo.Name}");
// 持久化通知
await NotificationStore.InsertNotificationAsync(notificationInfo);
var providers = Enumerable
.Reverse(NotificationPublishProviderManager.Providers);
await PublishFromProvidersAsync(providers, eventData.Users, notificationInfo);
}
/// <summary>
/// 指定提供者发布通知
/// </summary>
/// <param name="providers">提供者列表</param>
/// <param name="notificationInfo">通知信息</param>
/// <returns></returns>
protected async Task PublishFromProvidersAsync(
IEnumerable<INotificationPublishProvider> providers,
IEnumerable<UserIdentifier> users,
NotificationInfo notificationInfo)
{
// 检查是够已订阅消息
Logger.LogDebug($"Gets a list of user subscriptions {notificationInfo.Name}");
List<NotificationSubscriptionInfo> userSubscriptions;
if (users == null)
{
// 获取用户订阅列表
userSubscriptions = await NotificationSubscriptionManager
.GetUserSubscriptionsAsync(notificationInfo.TenantId, notificationInfo.Name);
}
else
{
// 过滤未订阅的用户
userSubscriptions = await NotificationSubscriptionManager
.GetUsersSubscriptionsAsync(notificationInfo.TenantId, notificationInfo.Name, users);
}
users = userSubscriptions.Select(us => new UserIdentifier(us.UserId, us.UserName));
if (users.Count() > 0)
{
// 持久化用户通知
Logger.LogDebug($"Persistent user notifications {notificationInfo.Name}");
await NotificationStore
.InsertUserNotificationsAsync(
notificationInfo,
users.Select(u => u.UserId));
// 2020-11-02 fix bug, 多个发送提供者处于同一个工作单元之下,不能把删除用户订阅写入到单个通知提供者完成事件中
// 而且为了确保一致性,删除订阅移动到发布通知之前
if (notificationInfo.Lifetime == NotificationLifetime.OnlyOne)
{
// 一次性通知在发送完成后就取消用户订阅
await NotificationStore
.DeleteUserSubscriptionAsync(
notificationInfo.TenantId,
users,
notificationInfo.Name);
}
// 发布通知
foreach (var provider in providers)
{
await PublishAsync(provider, notificationInfo, users);
}
}
}
/// <summary>
/// 发布通知
/// </summary>
/// <param name="provider">通知发布者</param>
/// <param name="notificationInfo">通知信息</param>
/// <param name="subscriptionUserIdentifiers">订阅用户列表</param>
/// <returns></returns>
protected async Task PublishAsync(
INotificationPublishProvider provider,
NotificationInfo notificationInfo,
IEnumerable<UserIdentifier> subscriptionUserIdentifiers)
{
try
{
Logger.LogDebug($"Sending notification with provider {provider.Name}");
var notifacationDataMapping = Options.NotificationDataMappings
.GetMapItemOrDefault(notificationInfo.Name, provider.Name);
if (notifacationDataMapping != null)
{
notificationInfo.Data = notifacationDataMapping.MappingFunc(notificationInfo.Data);
}
// 发布
await provider.PublishAsync(notificationInfo, subscriptionUserIdentifiers);
Logger.LogDebug($"Send notification {notificationInfo.Name} with provider {provider.Name} was successful");
}
catch (Exception ex)
{
Logger.LogWarning($"Send notification error with provider {provider.Name}");
Logger.LogWarning($"Error message:{ex.Message}");
Logger.LogTrace(ex, $"Send notification error with provider { provider.Name}");
Logger.LogDebug($"Send notification error, notification {notificationInfo.Name} entry queue");
// 发送失败的消息进入后台队列
await BackgroundJobManager.EnqueueAsync(
new NotificationPublishJobArgs(
notificationInfo.GetId(),
provider.GetType().AssemblyQualifiedName,
subscriptionUserIdentifiers.ToList(),
notificationInfo.TenantId));
}
}
}
}
using LINGYUN.Abp.MessageService.Utils;
using LINGYUN.Abp.Notifications;
using LINGYUN.Abp.RealTime;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.BackgroundJobs;
using Volo.Abp.DependencyInjection;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.Json;
using Volo.Abp.Uow;
namespace LINGYUN.Abp.MessageService.EventBus.Distributed
{
/// <summary>
/// 订阅通知发布事件,统一发布消息
/// </summary>
/// <remarks>
/// 作用在于SignalR客户端只会与一台服务器建立连接,
/// 只有启用了SignlR服务端的才能真正将消息发布到客户端
/// </remarks>
public class NotificationEventHandler : IDistributedEventHandler<NotificationEto<NotificationData>>, ITransientDependency
{
/// <summary>
/// Reference to <see cref="ILogger<DefaultNotificationDispatcher>"/>.
/// </summary>
public ILogger<NotificationEventHandler> Logger { get; set; }
/// <summary>
/// Reference to <see cref="AbpNotificationOptions"/>.
/// </summary>
protected AbpNotificationOptions Options { get; }
/// <summary>
/// Reference to <see cref="IJsonSerializer"/>.
/// </summary>
protected IJsonSerializer JsonSerializer { get; }
/// <summary>
/// Reference to <see cref="IBackgroundJobManager"/>.
/// </summary>
protected IBackgroundJobManager BackgroundJobManager { get; }
/// <summary>
/// Reference to <see cref="INotificationStore"/>.
/// </summary>
protected INotificationStore NotificationStore { get; }
/// <summary>
/// Reference to <see cref="INotificationDefinitionManager"/>.
/// </summary>
protected INotificationDefinitionManager NotificationDefinitionManager { get; }
/// <summary>
/// Reference to <see cref="INotificationSubscriptionManager"/>.
/// </summary>
protected INotificationSubscriptionManager NotificationSubscriptionManager { get; }
/// <summary>
/// Reference to <see cref="INotificationPublishProviderManager"/>.
/// </summary>
protected INotificationPublishProviderManager NotificationPublishProviderManager { get; }
/// <summary>
/// Initializes a new instance of the <see cref="NotificationEventHandler"/> class.
/// </summary>
public NotificationEventHandler(
IJsonSerializer jsonSerializer,
IBackgroundJobManager backgroundJobManager,
IOptions<AbpNotificationOptions> options,
INotificationStore notificationStore,
INotificationDefinitionManager notificationDefinitionManager,
INotificationSubscriptionManager notificationSubscriptionManager,
INotificationPublishProviderManager notificationPublishProviderManager)
{
Options = options.Value;
JsonSerializer = jsonSerializer;
BackgroundJobManager = backgroundJobManager;
NotificationStore = notificationStore;
NotificationDefinitionManager = notificationDefinitionManager;
NotificationSubscriptionManager = notificationSubscriptionManager;
NotificationPublishProviderManager = notificationPublishProviderManager;
Logger = NullLogger<NotificationEventHandler>.Instance;
}
[UnitOfWork]
public virtual async Task HandleEventAsync(NotificationEto<NotificationData> eventData)
{
// 如果上面过滤了应用程序,这里可以使用Get方法,否则,最好使用GetOrNull加以判断
var notification = NotificationDefinitionManager.GetOrNull(eventData.Name);
if (notification == null)
{
return;
}
var notificationInfo = new NotificationInfo
{
Name = notification.Name,
CreationTime = eventData.CreationTime,
Data = eventData.Data,
Severity = eventData.Severity,
Lifetime = notification.NotificationLifetime,
TenantId = eventData.TenantId,
Type = notification.NotificationType
};
notificationInfo.SetId(eventData.Id);
// TODO: 可以做成一个接口来序列化消息
notificationInfo.Data = NotificationDataConverter.Convert(notificationInfo.Data);
Logger.LogDebug($"Persistent notification {notificationInfo.Name}");
// 持久化通知
await NotificationStore.InsertNotificationAsync(notificationInfo);
var providers = Enumerable
.Reverse(NotificationPublishProviderManager.Providers);
await PublishFromProvidersAsync(providers, eventData.Users, notificationInfo);
}
/// <summary>
/// 指定提供者发布通知
/// </summary>
/// <param name="providers">提供者列表</param>
/// <param name="notificationInfo">通知信息</param>
/// <returns></returns>
protected async Task PublishFromProvidersAsync(
IEnumerable<INotificationPublishProvider> providers,
IEnumerable<UserIdentifier> users,
NotificationInfo notificationInfo)
{
// 检查是够已订阅消息
Logger.LogDebug($"Gets a list of user subscriptions {notificationInfo.Name}");
List<NotificationSubscriptionInfo> userSubscriptions;
if (users == null)
{
// 获取用户订阅列表
userSubscriptions = await NotificationSubscriptionManager
.GetUserSubscriptionsAsync(notificationInfo.TenantId, notificationInfo.Name);
}
else
{
// 过滤未订阅的用户
userSubscriptions = await NotificationSubscriptionManager
.GetUsersSubscriptionsAsync(notificationInfo.TenantId, notificationInfo.Name, users);
}
users = userSubscriptions.Select(us => new UserIdentifier(us.UserId, us.UserName));
if (users.Any())
{
// 持久化用户通知
Logger.LogDebug($"Persistent user notifications {notificationInfo.Name}");
await NotificationStore
.InsertUserNotificationsAsync(
notificationInfo,
users.Select(u => u.UserId));
// 2020-11-02 fix bug, 多个发送提供者处于同一个工作单元之下,不能把删除用户订阅写入到单个通知提供者完成事件中
// 而且为了确保一致性,删除订阅移动到发布通知之前
if (notificationInfo.Lifetime == NotificationLifetime.OnlyOne)
{
// 一次性通知在发送完成后就取消用户订阅
await NotificationStore
.DeleteUserSubscriptionAsync(
notificationInfo.TenantId,
users,
notificationInfo.Name);
}
// 发布通知
foreach (var provider in providers)
{
await PublishAsync(provider, notificationInfo, users);
}
}
}
/// <summary>
/// 发布通知
/// </summary>
/// <param name="provider">通知发布者</param>
/// <param name="notificationInfo">通知信息</param>
/// <param name="subscriptionUserIdentifiers">订阅用户列表</param>
/// <returns></returns>
protected async Task PublishAsync(
INotificationPublishProvider provider,
NotificationInfo notificationInfo,
IEnumerable<UserIdentifier> subscriptionUserIdentifiers)
{
try
{
Logger.LogDebug($"Sending notification with provider {provider.Name}");
var notifacationDataMapping = Options.NotificationDataMappings
.GetMapItemOrDefault(notificationInfo.Name, provider.Name);
if (notifacationDataMapping != null)
{
notificationInfo.Data = notifacationDataMapping.MappingFunc(notificationInfo.Data);
}
// 发布
await provider.PublishAsync(notificationInfo, subscriptionUserIdentifiers);
Logger.LogDebug($"Send notification {notificationInfo.Name} with provider {provider.Name} was successful");
}
catch (Exception ex)
{
Logger.LogWarning($"Send notification error with provider {provider.Name}");
Logger.LogWarning($"Error message:{ex.Message}");
Logger.LogTrace(ex, $"Send notification error with provider { provider.Name}");
Logger.LogDebug($"Send notification error, notification {notificationInfo.Name} entry queue");
// 发送失败的消息进入后台队列
await BackgroundJobManager.EnqueueAsync(
new NotificationPublishJobArgs(
notificationInfo.GetId(),
provider.GetType().AssemblyQualifiedName,
subscriptionUserIdentifiers.ToList(),
notificationInfo.TenantId));
}
}
}
}

155
aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/EventBus/Distributed/TenantCreateEventHandler.cs

@ -1,83 +1,72 @@
using LINGYUN.Abp.MessageService.Localization;
using LINGYUN.Abp.MultiTenancy;
using LINGYUN.Abp.Notifications;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging;
using System;
using System.Globalization;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.Localization;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Settings;
namespace LINGYUN.Abp.MessageService.EventBus.Distributed
{
public class TenantCreateEventHandler : IDistributedEventHandler<CreateEventData>, ITransientDependency
{
protected ILogger<TenantCreateEventHandler> Logger { get; }
protected ICurrentTenant CurrentTenant { get; }
protected ISettingProvider SettingProvider { get; }
protected IStringLocalizer StringLocalizer { get; }
protected INotificationSender NotificationSender { get; }
protected INotificationSubscriptionManager NotificationSubscriptionManager { get; }
public TenantCreateEventHandler(
ICurrentTenant currentTenant,
ISettingProvider settingProvider,
INotificationSender notificationSender,
INotificationSubscriptionManager notificationSubscriptionManager,
IStringLocalizer<MessageServiceResource> stringLocalizer,
ILogger<TenantCreateEventHandler> logger)
{
Logger = logger;
CurrentTenant = currentTenant;
SettingProvider = settingProvider;
StringLocalizer = stringLocalizer;
NotificationSender = notificationSender;
NotificationSubscriptionManager = notificationSubscriptionManager;
}
public async Task HandleEventAsync(CreateEventData eventData)
{
var tenantAdminUserIdentifier = new UserIdentifier(eventData.AdminUserId, eventData.AdminEmailAddress);
// 租户管理员订阅事件
await NotificationSubscriptionManager
.SubscribeAsync(
eventData.Id,
tenantAdminUserIdentifier,
TenantNotificationNames.NewTenantRegistered);
var userDefaultCultureName = await SettingProvider.GetOrNullAsync(LocalizationSettingNames.DefaultLanguage);
if (userDefaultCultureName.IsNullOrWhiteSpace())
{
userDefaultCultureName = CultureInfo.CurrentUICulture.Name;
}
// 使用系统区域语言发布通知
using (CultureHelper.Use(userDefaultCultureName, userDefaultCultureName))
{
var notificationData = new NotificationData();
notificationData.WriteStandardData(
L("NewTenantRegisteredNotificationTitle"),
L("NewTenantRegisteredNotificationMessage", eventData.Name),
DateTime.Now, eventData.AdminEmailAddress);
// 发布租户创建通知
await NotificationSender
.SendNofiterAsync(
TenantNotificationNames.NewTenantRegistered,
notificationData,
tenantAdminUserIdentifier,
eventData.Id,
NotificationSeverity.Success);
}
}
protected string L(string name, params object[] args)
{
return StringLocalizer[name, args]?.Value;
}
}
}
using LINGYUN.Abp.MessageService.Localization;
using LINGYUN.Abp.MultiTenancy;
using LINGYUN.Abp.Notifications;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.Localization;
using Volo.Abp.MultiTenancy;
namespace LINGYUN.Abp.MessageService.EventBus.Distributed
{
public class TenantCreateEventHandler : IDistributedEventHandler<CreateEventData>, ITransientDependency
{
protected ILogger<TenantCreateEventHandler> Logger { get; }
protected INotificationSender NotificationSender { get; }
protected INotificationSubscriptionManager NotificationSubscriptionManager { get; }
public TenantCreateEventHandler(
INotificationSender notificationSender,
INotificationSubscriptionManager notificationSubscriptionManager,
ILogger<TenantCreateEventHandler> logger)
{
Logger = logger;
NotificationSender = notificationSender;
NotificationSubscriptionManager = notificationSubscriptionManager;
}
public async Task HandleEventAsync(CreateEventData eventData)
{
var tenantAdminUserIdentifier = new UserIdentifier(eventData.AdminUserId, eventData.AdminEmailAddress);
Logger.LogInformation("tenant administrator subscribes to new tenant events..");
// 租户管理员订阅事件
await NotificationSubscriptionManager
.SubscribeAsync(
eventData.Id,
tenantAdminUserIdentifier,
TenantNotificationNames.NewTenantRegistered);
var notificationData = new NotificationData();
notificationData.WriteLocalizedData(
new LocalizableStringInfo(
LocalizationResourceNameAttribute.GetName(typeof(MessageServiceResource)),
"NewTenantRegisteredNotificationTitle",
new Dictionary<object, object>
{
{ "User", eventData.Name }
}),
new LocalizableStringInfo(
LocalizationResourceNameAttribute.GetName(typeof(MessageServiceResource)),
"NewTenantRegisteredNotificationMessage",
new Dictionary<object, object>
{
{ "User", eventData.Name}
}),
DateTime.Now, eventData.AdminEmailAddress);
Logger.LogInformation("publish new tenant notification..");
// 发布租户创建通知
await NotificationSender
.SendNofiterAsync(
TenantNotificationNames.NewTenantRegistered,
notificationData,
tenantAdminUserIdentifier,
eventData.Id,
NotificationSeverity.Success);
}
}
}

135
aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/EventBus/Local/UserCreateSendWelcomeEventHandler.cs

@ -1,63 +1,72 @@
using LINGYUN.Abp.MessageService.Localization;
using LINGYUN.Abp.Notifications;
using System;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Entities.Events;
using Volo.Abp.EventBus;
using Volo.Abp.Localization;
using Volo.Abp.Users;
namespace LINGYUN.Abp.MessageService.EventBus
{
public class UserCreateSendWelcomeEventHandler : ILocalEventHandler<EntityCreatedEventData<UserEto>>, ITransientDependency
{
private readonly INotificationSender _notificationSender;
private readonly INotificationSubscriptionManager _notificationSubscriptionManager;
public UserCreateSendWelcomeEventHandler(
INotificationSender notificationSender,
INotificationSubscriptionManager notificationSubscriptionManager
)
{
_notificationSender = notificationSender;
_notificationSubscriptionManager = notificationSubscriptionManager;
}
public async Task HandleEventAsync(EntityCreatedEventData<UserEto> eventData)
{
var userIdentifer = new UserIdentifier(eventData.Entity.Id, eventData.Entity.UserName);
// 订阅用户欢迎消息
await _notificationSubscriptionManager
.SubscribeAsync(
eventData.Entity.TenantId,
userIdentifer,
UserNotificationNames.WelcomeToApplication);
var userWelcomeNotifictionData = new NotificationData();
//userWelcomeNotifictionData.WriteStandardData(
// L("WelcomeToApplicationFormUser", eventData.Entity.Name ?? eventData.Entity.UserName),
// L("WelcomeToApplicationFormUser", eventData.Entity.Name ?? eventData.Entity.UserName),
// DateTime.Now, eventData.Entity.UserName);
userWelcomeNotifictionData
.WriteLocalizedData(
new LocalizableStringInfo(
LocalizationResourceNameAttribute.GetName(typeof(MessageServiceResource)),
"WelcomeToApplicationFormUser"),
new LocalizableStringInfo(
LocalizationResourceNameAttribute.GetName(typeof(MessageServiceResource)),
"WelcomeToApplicationFormUser"),
DateTime.Now, eventData.Entity.UserName);
await _notificationSender
.SendNofiterAsync(
UserNotificationNames.WelcomeToApplication,
userWelcomeNotifictionData,
userIdentifer,
eventData.Entity.TenantId,
NotificationSeverity.Info
);
}
}
}
using LINGYUN.Abp.MessageService.Localization;
using LINGYUN.Abp.Notifications;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Entities.Events;
using Volo.Abp.EventBus;
using Volo.Abp.Localization;
using Volo.Abp.Users;
namespace LINGYUN.Abp.MessageService.EventBus
{
public class UserCreateSendWelcomeEventHandler : ILocalEventHandler<EntityCreatedEventData<UserEto>>, ITransientDependency
{
private readonly INotificationSender _notificationSender;
private readonly INotificationSubscriptionManager _notificationSubscriptionManager;
public UserCreateSendWelcomeEventHandler(
INotificationSender notificationSender,
INotificationSubscriptionManager notificationSubscriptionManager
)
{
_notificationSender = notificationSender;
_notificationSubscriptionManager = notificationSubscriptionManager;
}
public async Task HandleEventAsync(EntityCreatedEventData<UserEto> eventData)
{
var userIdentifer = new UserIdentifier(eventData.Entity.Id, eventData.Entity.UserName);
// 订阅用户欢迎消息
await _notificationSubscriptionManager
.SubscribeAsync(
eventData.Entity.TenantId,
userIdentifer,
UserNotificationNames.WelcomeToApplication);
var userWelcomeNotifictionData = new NotificationData();
//userWelcomeNotifictionData.WriteStandardData(
// L("WelcomeToApplicationFormUser", eventData.Entity.Name ?? eventData.Entity.UserName),
// L("WelcomeToApplicationFormUser", eventData.Entity.Name ?? eventData.Entity.UserName),
// DateTime.Now, eventData.Entity.UserName);
userWelcomeNotifictionData
.WriteLocalizedData(
new LocalizableStringInfo(
LocalizationResourceNameAttribute.GetName(typeof(MessageServiceResource)),
"WelcomeToApplicationFormUser",
new Dictionary<object, object>
{
{ "User", eventData.Entity.UserName }
}),
new LocalizableStringInfo(
LocalizationResourceNameAttribute.GetName(typeof(MessageServiceResource)),
"WelcomeToApplicationFormUser",
new Dictionary<object, object>
{
{ "User", eventData.Entity.UserName }
}),
DateTime.Now, eventData.Entity.UserName);
await _notificationSender
.SendNofiterAsync(
UserNotificationNames.WelcomeToApplication,
userWelcomeNotifictionData,
userIdentifer,
eventData.Entity.TenantId,
NotificationSeverity.Info
);
}
}
}

2
aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Localization/HttpApiHost/en.json

@ -2,6 +2,6 @@
"culture": "en",
"texts": {
"NewTenantRegisteredNotificationTitle": "Tenants create notification",
"NewTenantRegisteredNotificationMessage": "New tenants to create success, the tenant name: {0}!"
"NewTenantRegisteredNotificationMessage": "New tenants to create success, the tenant name: {Name}!"
}
}

2
aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Localization/HttpApiHost/zh-Hans.json

@ -2,6 +2,6 @@
"culture": "zh-Hans",
"texts": {
"NewTenantRegisteredNotificationTitle": "租户创建通知",
"NewTenantRegisteredNotificationMessage": "新租户创建成功,租户名称:{0}!"
"NewTenantRegisteredNotificationMessage": "新租户创建成功,租户名称:{Name}!"
}
}

8
aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/DataSeeder/ElementAdminDataSeedContributor.cs

@ -241,9 +241,9 @@ namespace LINGYUN.Platform.DataSeeder
private async Task SeedAdminMenuAsync(Layout layout, Data data)
{
var adminMenu = await SeedMenuAsync(
layout,
layout,
data,
"admin",
"admin",
"/admin",
CodeNumberGenerator.CreateCode(2),
layout.Path,
@ -938,7 +938,7 @@ namespace LINGYUN.Platform.DataSeeder
menu.SetProperty(item.Key, item.Value);
}
}
if (roles != null)
{
foreach (var role in roles)
@ -958,4 +958,4 @@ namespace LINGYUN.Platform.DataSeeder
return menu;
}
}
}
}

72
aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/DataSeeder/VbenAdminDataSeedContributor.cs

@ -288,7 +288,7 @@ namespace LINGYUN.Platform.DataSeeder
{ "hideTab", false },
{ "ignoreAuth", true },
},
new string[] { "vben-admin" });
new string[] { "admin" });
var analysis = await SeedMenuAsync(
layout, //layout
@ -308,7 +308,7 @@ namespace LINGYUN.Platform.DataSeeder
{ "icon", "" },
{ "hideTab", false },
},
new string[] { "vben-admin" });
new string[] { "admin" });
var workbench = await SeedMenuAsync(
layout, //layout
@ -328,7 +328,7 @@ namespace LINGYUN.Platform.DataSeeder
{ "icon", "" },
{ "hideTab", false },
},
new string[] { "vben-admin" });
new string[] { "admin" });
}
private async Task SeedManageMenuAsync(Layout layout, Data data)
@ -352,7 +352,7 @@ namespace LINGYUN.Platform.DataSeeder
{ "hideTab", false },
{ "ignoreAuth", false },
},
new string[] { "vben-admin" });
new string[] { "admin" });
var identity = await SeedMenuAsync(
layout, //layout
@ -372,7 +372,7 @@ namespace LINGYUN.Platform.DataSeeder
{ "icon", "" },
{ "hideTab", false },
},
new string[] { "vben-admin" });
new string[] { "admin" });
var user = await SeedMenuAsync(
layout, //layout
data, //data
@ -391,7 +391,7 @@ namespace LINGYUN.Platform.DataSeeder
{ "icon", "" },
{ "hideTab", false },
},
new string[] { "vben-admin" });
new string[] { "admin" });
var role = await SeedMenuAsync(
layout, //layout
data, //data
@ -410,7 +410,7 @@ namespace LINGYUN.Platform.DataSeeder
{ "icon", "" },
{ "hideTab", false },
},
new string[] { "vben-admin" });
new string[] { "admin" });
var claimTypes = await SeedMenuAsync(
layout, //layout
data, //data
@ -429,7 +429,7 @@ namespace LINGYUN.Platform.DataSeeder
{ "icon", "" },
{ "hideTab", false },
},
new string[] { "vben-admin" });
new string[] { "admin" });
var organizationUnits = await SeedMenuAsync(
layout, //layout
data, //data
@ -448,7 +448,7 @@ namespace LINGYUN.Platform.DataSeeder
{ "icon", "" },
{ "hideTab", false },
},
new string[] { "vben-admin" });
new string[] { "admin" });
var securityLog = await SeedMenuAsync(
layout, //layout
data, //data
@ -468,7 +468,7 @@ namespace LINGYUN.Platform.DataSeeder
{ "hideTab", false },
{ "requiredFeatures", "AbpAuditing.Logging.SecurityLog" } // 此路由需要依赖安全日志特性
},
new string[] { "vben-admin" });
new string[] { "admin" });
var auditLogs = await SeedMenuAsync(
layout, //layout
@ -489,7 +489,7 @@ namespace LINGYUN.Platform.DataSeeder
{ "hideTab", false },
{ "requiredFeatures", "AbpAuditing.Logging.AuditLog" } // 此路由需要依赖审计日志特性
},
new string[] { "vben-admin" });
new string[] { "admin" });
var settings = await SeedMenuAsync(
layout, //layout
@ -510,7 +510,7 @@ namespace LINGYUN.Platform.DataSeeder
{ "hideTab", false },
{ "requiredFeatures", "SettingManagement.Enable" } // 此路由需要依赖设置管理特性
},
new string[] { "vben-admin" });
new string[] { "admin" });
var identityServer = await SeedMenuAsync(
layout, //layout
@ -530,7 +530,7 @@ namespace LINGYUN.Platform.DataSeeder
{ "icon", "" },
{ "hideTab", false },
},
new string[] { "vben-admin" });
new string[] { "admin" });
var clients = await SeedMenuAsync(
layout, //layout
data, //data
@ -549,7 +549,7 @@ namespace LINGYUN.Platform.DataSeeder
{ "icon", "" },
{ "hideTab", false },
},
new string[] { "vben-admin" });
new string[] { "admin" });
var apiResource = await SeedMenuAsync(
layout, //layout
data, //data
@ -568,7 +568,7 @@ namespace LINGYUN.Platform.DataSeeder
{ "icon", "" },
{ "hideTab", false },
},
new string[] { "vben-admin" });
new string[] { "admin" });
var identityResources = await SeedMenuAsync(
layout, //layout
data, //data
@ -587,7 +587,7 @@ namespace LINGYUN.Platform.DataSeeder
{ "icon", "" },
{ "hideTab", false },
},
new string[] { "vben-admin" });
new string[] { "admin" });
var apiScopes = await SeedMenuAsync(
layout, //layout
data, //data
@ -606,7 +606,7 @@ namespace LINGYUN.Platform.DataSeeder
{ "icon", "" },
{ "hideTab", false },
},
new string[] { "vben-admin" });
new string[] { "admin" });
var persistedGrants = await SeedMenuAsync(
layout, //layout
data, //data
@ -625,7 +625,7 @@ namespace LINGYUN.Platform.DataSeeder
{ "icon", "" },
{ "hideTab", false },
},
new string[] { "vben-admin" });
new string[] { "admin" });
}
@ -650,7 +650,7 @@ namespace LINGYUN.Platform.DataSeeder
{ "hideTab", false },
{ "ignoreAuth", false },
},
new string[] { "vben-admin" });
new string[] { "admin" });
var tenants = await SeedMenuAsync(
layout, //layout
data, //data
@ -669,7 +669,7 @@ namespace LINGYUN.Platform.DataSeeder
{ "icon", "" },
{ "hideTab", false },
},
new string[] { "vben-admin" });
new string[] { "admin" });
}
private async Task SeedPlatformMenuAsync(Layout layout, Data data)
@ -693,7 +693,7 @@ namespace LINGYUN.Platform.DataSeeder
{ "hideTab", false },
{ "ignoreAuth", false },
},
new string[] { "vben-admin" });
new string[] { "admin" });
var dataDictionary = await SeedMenuAsync(
layout, //layout
data, //data
@ -712,7 +712,7 @@ namespace LINGYUN.Platform.DataSeeder
{ "icon", "" },
{ "hideTab", false },
},
new string[] { "vben-admin" });
new string[] { "admin" });
var layouts = await SeedMenuAsync(
layout, //layout
data, //data
@ -731,7 +731,7 @@ namespace LINGYUN.Platform.DataSeeder
{ "icon", "" },
{ "hideTab", false },
},
new string[] { "vben-admin" });
new string[] { "admin" });
var menus = await SeedMenuAsync(
layout, //layout
data, //data
@ -750,7 +750,7 @@ namespace LINGYUN.Platform.DataSeeder
{ "icon", "" },
{ "hideTab", false },
},
new string[] { "vben-admin" });
new string[] { "admin" });
}
private async Task SeedApiGatewayMenuAsync(Layout layout, Data data)
@ -774,7 +774,7 @@ namespace LINGYUN.Platform.DataSeeder
{ "hideTab", false },
{ "ignoreAuth", false },
},
new string[] { "vben-admin" });
new string[] { "admin" });
var routeGroup = await SeedMenuAsync(
layout, //layout
data, //data
@ -793,7 +793,7 @@ namespace LINGYUN.Platform.DataSeeder
{ "icon", "" },
{ "hideTab", false },
},
new string[] { "vben-admin" });
new string[] { "admin" });
var global = await SeedMenuAsync(
layout, //layout
data, //data
@ -812,7 +812,7 @@ namespace LINGYUN.Platform.DataSeeder
{ "icon", "" },
{ "hideTab", false },
},
new string[] { "vben-admin" });
new string[] { "admin" });
var route = await SeedMenuAsync(
layout, //layout
data, //data
@ -831,7 +831,7 @@ namespace LINGYUN.Platform.DataSeeder
{ "icon", "" },
{ "hideTab", false },
},
new string[] { "vben-admin" });
new string[] { "admin" });
var aggregate = await SeedMenuAsync(
layout, //layout
data, //data
@ -850,7 +850,7 @@ namespace LINGYUN.Platform.DataSeeder
{ "icon", "" },
{ "hideTab", false },
},
new string[] { "vben-admin" });
new string[] { "admin" });
}
private async Task SeedLocalizationMenuAsync(Layout layout, Data data)
@ -874,7 +874,7 @@ namespace LINGYUN.Platform.DataSeeder
{ "hideTab", false },
{ "ignoreAuth", false },
},
new string[] { "vben-admin" });
new string[] { "admin" });
var languages = await SeedMenuAsync(
layout, //layout
data, //data
@ -893,7 +893,7 @@ namespace LINGYUN.Platform.DataSeeder
{ "icon", "" },
{ "hideTab", false },
},
new string[] { "vben-admin" });
new string[] { "admin" });
var resources = await SeedMenuAsync(
layout, //layout
data, //data
@ -912,7 +912,7 @@ namespace LINGYUN.Platform.DataSeeder
{ "icon", "" },
{ "hideTab", false },
},
new string[] { "vben-admin" });
new string[] { "admin" });
var texts = await SeedMenuAsync(
layout, //layout
data, //data
@ -931,7 +931,7 @@ namespace LINGYUN.Platform.DataSeeder
{ "icon", "" },
{ "hideTab", false },
},
new string[] { "vben-admin" });
new string[] { "admin" });
}
private async Task SeedOssManagementMenuAsync(Layout layout, Data data)
@ -955,7 +955,7 @@ namespace LINGYUN.Platform.DataSeeder
{ "hideTab", false },
{ "ignoreAuth", false },
},
new string[] { "vben-admin" });
new string[] { "admin" });
var containers = await SeedMenuAsync(
layout, //layout
data, //data
@ -974,7 +974,7 @@ namespace LINGYUN.Platform.DataSeeder
{ "icon", "" },
{ "hideTab", false },
},
new string[] { "vben-admin" });
new string[] { "admin" });
var objects = await SeedMenuAsync(
layout, //layout
data, //data
@ -993,7 +993,7 @@ namespace LINGYUN.Platform.DataSeeder
{ "icon", "" },
{ "hideTab", false },
},
new string[] { "vben-admin" });
new string[] { "admin" });
}
private async Task<Menu> SeedMenuAsync(

Loading…
Cancel
Save