diff --git a/aspnet-core/modules/common/LINGYUN.Abp.BackgroundJobs.Hangfire/LINGYUN.Abp.BackgroundJobs.Hangfire.csproj b/aspnet-core/modules/common/LINGYUN.Abp.BackgroundJobs.Hangfire/LINGYUN.Abp.BackgroundJobs.Hangfire.csproj new file mode 100644 index 000000000..b87cec0b6 --- /dev/null +++ b/aspnet-core/modules/common/LINGYUN.Abp.BackgroundJobs.Hangfire/LINGYUN.Abp.BackgroundJobs.Hangfire.csproj @@ -0,0 +1,13 @@ + + + + netstandard2.0 + + + + + + + + + diff --git a/aspnet-core/modules/common/LINGYUN.Abp.BackgroundJobs.Hangfire/LINGYUN/Abp/BackgroundJobs/Hangfire/AbpBackgroundJobsHangfireModule.cs b/aspnet-core/modules/common/LINGYUN.Abp.BackgroundJobs.Hangfire/LINGYUN/Abp/BackgroundJobs/Hangfire/AbpBackgroundJobsHangfireModule.cs new file mode 100644 index 000000000..0fc08ae96 --- /dev/null +++ b/aspnet-core/modules/common/LINGYUN.Abp.BackgroundJobs.Hangfire/LINGYUN/Abp/BackgroundJobs/Hangfire/AbpBackgroundJobsHangfireModule.cs @@ -0,0 +1,34 @@ +using Hangfire; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using System; +using Volo.Abp; +using Volo.Abp.BackgroundJobs; +using Volo.Abp.Hangfire; +using Volo.Abp.Modularity; + +namespace LINGYUN.Abp.BackgroundJobs.Hangfire +{ + [DependsOn( + typeof(AbpBackgroundJobsAbstractionsModule), + typeof(AbpHangfireModule) + )] + public class AbpBackgroundJobsHangfireModule : AbpModule + { + public override void OnPreApplicationInitialization(ApplicationInitializationContext context) + { + var options = context.ServiceProvider.GetRequiredService>().Value; + if (!options.IsJobExecutionEnabled) + { + var hangfireOptions = context.ServiceProvider.GetRequiredService>().Value; + hangfireOptions.BackgroundJobServerFactory = CreateOnlyEnqueueJobServer; + } + } + + private BackgroundJobServer CreateOnlyEnqueueJobServer(IServiceProvider serviceProvider) + { + serviceProvider.GetRequiredService(); + return null; + } + } +} \ No newline at end of file diff --git a/aspnet-core/modules/common/LINGYUN.Abp.BackgroundJobs.Hangfire/LINGYUN/Abp/BackgroundJobs/Hangfire/HangfireBackgroundJobManager.cs b/aspnet-core/modules/common/LINGYUN.Abp.BackgroundJobs.Hangfire/LINGYUN/Abp/BackgroundJobs/Hangfire/HangfireBackgroundJobManager.cs new file mode 100644 index 000000000..435f0192f --- /dev/null +++ b/aspnet-core/modules/common/LINGYUN.Abp.BackgroundJobs.Hangfire/LINGYUN/Abp/BackgroundJobs/Hangfire/HangfireBackgroundJobManager.cs @@ -0,0 +1,34 @@ +using Hangfire; +using System; +using System.Threading.Tasks; +using Volo.Abp.BackgroundJobs; +using Volo.Abp.DependencyInjection; + +namespace LINGYUN.Abp.BackgroundJobs.Hangfire +{ + [Dependency(ReplaceServices = true)] + public class HangfireBackgroundJobManager : IBackgroundJobManager, ITransientDependency + { + public virtual Task EnqueueAsync(TArgs args, BackgroundJobPriority priority = BackgroundJobPriority.Normal, + TimeSpan? delay = null) + { + if (!delay.HasValue) + { + return Task.FromResult( + BackgroundJob.Enqueue>( + adapter => adapter.Execute(args) + ) + ); + } + else + { + return Task.FromResult( + BackgroundJob.Schedule>( + adapter => adapter.Execute(args), + delay.Value + ) + ); + } + } + } +} \ No newline at end of file diff --git a/aspnet-core/modules/common/LINGYUN.Abp.BackgroundJobs.Hangfire/LINGYUN/Abp/BackgroundJobs/Hangfire/HangfireJobExecutionAdapter.cs b/aspnet-core/modules/common/LINGYUN.Abp.BackgroundJobs.Hangfire/LINGYUN/Abp/BackgroundJobs/Hangfire/HangfireJobExecutionAdapter.cs new file mode 100644 index 000000000..97cb8dc4a --- /dev/null +++ b/aspnet-core/modules/common/LINGYUN.Abp.BackgroundJobs.Hangfire/LINGYUN/Abp/BackgroundJobs/Hangfire/HangfireJobExecutionAdapter.cs @@ -0,0 +1,46 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using Volo.Abp; +using Volo.Abp.BackgroundJobs; +using Volo.Abp.Threading; + +namespace LINGYUN.Abp.BackgroundJobs.Hangfire +{ + public class HangfireJobExecutionAdapter + { + protected AbpBackgroundJobOptions Options { get; } + protected IServiceScopeFactory ServiceScopeFactory { get; } + protected IBackgroundJobExecuter JobExecuter { get; } + + public HangfireJobExecutionAdapter( + IOptions options, + IBackgroundJobExecuter jobExecuter, + IServiceScopeFactory serviceScopeFactory) + { + JobExecuter = jobExecuter; + ServiceScopeFactory = serviceScopeFactory; + Options = options.Value; + } + + public void Execute(TArgs args) + { + if (!Options.IsJobExecutionEnabled) + { + throw new AbpException( + "Background job execution is disabled. " + + "This method should not be called! " + + "If you want to enable the background job execution, " + + $"set {nameof(AbpBackgroundJobOptions)}.{nameof(AbpBackgroundJobOptions.IsJobExecutionEnabled)} to true! " + + "If you've intentionally disabled job execution and this seems a bug, please report it." + ); + } + + using (var scope = ServiceScopeFactory.CreateScope()) + { + var jobType = Options.GetJob(typeof(TArgs)).JobType; + var context = new JobExecutionContext(scope.ServiceProvider, jobType, args); + AsyncHelper.RunSync(() => JobExecuter.ExecuteAsync(context)); + } + } + } +} \ No newline at end of file diff --git a/aspnet-core/modules/common/LINGYUN.Abp.BackgroundJobs.Hangfire/LINGYUN/Abp/BackgroundJobs/Hangfire/IBackgroundJobManagerExtensions.cs b/aspnet-core/modules/common/LINGYUN.Abp.BackgroundJobs.Hangfire/LINGYUN/Abp/BackgroundJobs/Hangfire/IBackgroundJobManagerExtensions.cs new file mode 100644 index 000000000..aca3a52ea --- /dev/null +++ b/aspnet-core/modules/common/LINGYUN.Abp.BackgroundJobs.Hangfire/LINGYUN/Abp/BackgroundJobs/Hangfire/IBackgroundJobManagerExtensions.cs @@ -0,0 +1,35 @@ +using Hangfire; +using JetBrains.Annotations; +using System.Threading.Tasks; +using Volo.Abp; +using Volo.Abp.BackgroundJobs; + +namespace LINGYUN.Abp.BackgroundJobs.Hangfire +{ + public static class IBackgroundJobManagerExtensions + { + /// + /// 后台作业进入周期性队列 + /// + /// 作业参数类型 + /// 后台作业管理器 + /// Cron表达式 + /// 作业参数 + /// + public static Task EnqueueAsync( + this IBackgroundJobManager backgroundJobManager, + [NotNull] string cron, + TArgs args + ) + { + Check.NotNullOrWhiteSpace(cron, nameof(cron)); + Check.NotNull(args, nameof(args)); + + var jobName = BackgroundJobNameAttribute.GetName(); + + RecurringJob.AddOrUpdate>(jobName, adapter => adapter.Execute(args), cron); + + return Task.CompletedTask; + } + } +} diff --git a/aspnet-core/modules/common/LINGYUN.Abp.BackgroundJobs.Hangfire/Volo/Abp/BackgroundJobs/CronGenerator.cs b/aspnet-core/modules/common/LINGYUN.Abp.BackgroundJobs.Hangfire/Volo/Abp/BackgroundJobs/CronGenerator.cs new file mode 100644 index 000000000..fae4a57b1 --- /dev/null +++ b/aspnet-core/modules/common/LINGYUN.Abp.BackgroundJobs.Hangfire/Volo/Abp/BackgroundJobs/CronGenerator.cs @@ -0,0 +1,78 @@ +using Hangfire; +using System; + +namespace Volo.Abp.BackgroundJobs +{ + public class CronGenerator + { + /// + /// 周期性为分钟的任务 + /// + /// 执行周期的间隔,默认为每分钟一次 + /// + public static string Minute(int interval = 1) + { + return $"1 0/{interval} * * * ? "; + } + + /// + /// 周期性为小时的任务 + /// + /// 第几分钟开始,默认为第一分钟 + /// 执行周期的间隔,默认为每小时一次 + /// + public static string Hour(int minute = 1, int interval = 1) + { + return $"1 {minute} 0/ {interval} * * ? "; + } + + /// + /// 周期性为天的任务 + /// + /// 第几小时开始,默认从1点开始 + /// 第几分钟开始,默认从第1分钟开始 + /// 执行周期的间隔,默认为每天一次 + /// + public static string Day(int hour = 1, int minute = 1, int interval = 1) + { + return $"1 {minute} {hour} 1/ {interval} * ? "; + } + + /// + /// 周期性为周的任务 + /// + /// 星期几开始,默认从星期一点开始 + /// 第几小时开始,默认从1点开始 + /// 第几分钟开始,默认从第1分钟开始 + /// + public static string Week(DayOfWeek dayOfWeek = DayOfWeek.Monday, int hour = 1, int minute = 1) + { + return Cron.Weekly(dayOfWeek, hour, minute); + } + + /// + /// 周期性为月的任务 + /// + /// 几号开始,默认从一号开始 + /// 第几小时开始,默认从1点开始 + /// 第几分钟开始,默认从第1分钟开始 + /// + public static string Month(int day = 1, int hour = 1, int minute = 1) + { + return Cron.Monthly(day, hour, minute); + } + + /// + /// 周期性为年的任务 + /// + /// 几月开始,默认从一月开始 + /// 几号开始,默认从一号开始 + /// 第几小时开始,默认从1点开始 + /// 第几分钟开始,默认从第1分钟开始 + /// + public static string Year(int month = 1, int day = 1, int hour = 1, int minute = 1) + { + return Cron.Yearly(month, day, hour, minute); + } + } +} diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Hangfire.MySqlStorage/LINGYUN.Abp.Hangfire.Storage.MySql.csproj b/aspnet-core/modules/common/LINGYUN.Abp.Hangfire.MySqlStorage/LINGYUN.Abp.Hangfire.Storage.MySql.csproj new file mode 100644 index 000000000..2dce503aa --- /dev/null +++ b/aspnet-core/modules/common/LINGYUN.Abp.Hangfire.MySqlStorage/LINGYUN.Abp.Hangfire.Storage.MySql.csproj @@ -0,0 +1,22 @@ + + + + netstandard2.0 + + false + true + 2.9.0 + LINGYUN + LINGYUN + + + + D:\LocalNuget + + + + + + + + diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Hangfire.MySqlStorage/LINGYUN/Abp/Hangfire/Storage/MySql/AbpHangfireMySqlStorageModule.cs b/aspnet-core/modules/common/LINGYUN.Abp.Hangfire.MySqlStorage/LINGYUN/Abp/Hangfire/Storage/MySql/AbpHangfireMySqlStorageModule.cs new file mode 100644 index 000000000..f7a056012 --- /dev/null +++ b/aspnet-core/modules/common/LINGYUN.Abp.Hangfire.MySqlStorage/LINGYUN/Abp/Hangfire/Storage/MySql/AbpHangfireMySqlStorageModule.cs @@ -0,0 +1,38 @@ +using Hangfire; +using Hangfire.MySql.Core; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Hangfire; +using Volo.Abp.Modularity; + +namespace LINGYUN.Abp.Hangfire.Storage.MySql +{ + [DependsOn(typeof(AbpHangfireModule))] + public class AbpHangfireMySqlStorageModule : AbpModule + { + private MySqlStorage _jobStorage; + + public override void ConfigureServices(ServiceConfigurationContext context) + { + var configuration = context.Services.GetConfiguration(); + + var mysqlStorageOptions = new MySqlStorageOptions(); + configuration.GetSection("Hangfire:MySql").Bind(mysqlStorageOptions); + + var hangfireMySqlConfiguration = configuration.GetSection("Hangfire:MySql:Connection"); + var hangfireMySqlCon = hangfireMySqlConfiguration.Exists() + ? hangfireMySqlConfiguration.Value : configuration.GetConnectionString("Default"); + + _jobStorage = new MySqlStorage(hangfireMySqlCon, mysqlStorageOptions); + context.Services.AddSingleton(fac => + { + return _jobStorage; + }); + + context.Services.AddHangfire(config => + { + config.UseStorage(_jobStorage); + }); + } + } +} diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Hangfire.Storage.SqlServer/LINGYUN.Abp.Hangfire.Storage.SqlServer.csproj b/aspnet-core/modules/common/LINGYUN.Abp.Hangfire.Storage.SqlServer/LINGYUN.Abp.Hangfire.Storage.SqlServer.csproj new file mode 100644 index 000000000..9258b98dd --- /dev/null +++ b/aspnet-core/modules/common/LINGYUN.Abp.Hangfire.Storage.SqlServer/LINGYUN.Abp.Hangfire.Storage.SqlServer.csproj @@ -0,0 +1,20 @@ + + + + netstandard2.0 + + true + 2.9.0 + LINGYUN + + + + D:\LocalNuget + + + + + + + + diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Hangfire.Storage.SqlServer/LINGYUN/Abp/Hangfire/Storage/SqlServer/AbpHangfireSqlServerStorageModule.cs b/aspnet-core/modules/common/LINGYUN.Abp.Hangfire.Storage.SqlServer/LINGYUN/Abp/Hangfire/Storage/SqlServer/AbpHangfireSqlServerStorageModule.cs new file mode 100644 index 000000000..42e4ff8db --- /dev/null +++ b/aspnet-core/modules/common/LINGYUN.Abp.Hangfire.Storage.SqlServer/LINGYUN/Abp/Hangfire/Storage/SqlServer/AbpHangfireSqlServerStorageModule.cs @@ -0,0 +1,38 @@ +using Hangfire; +using Hangfire.SqlServer; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Hangfire; +using Volo.Abp.Modularity; + +namespace LINGYUN.Abp.Hangfire.Storage.SqlServer +{ + [DependsOn(typeof(AbpHangfireModule))] + public class AbpHangfireSqlServerStorageModule : AbpModule + { + private SqlServerStorage _jobStorage; + + public override void ConfigureServices(ServiceConfigurationContext context) + { + var configuration = context.Services.GetConfiguration(); + + var sqlserverStorageOptions = new SqlServerStorageOptions(); + configuration.GetSection("Hangfire:SqlServer").Bind(sqlserverStorageOptions); + + var hangfireSqlServerConfiguration = configuration.GetSection("Hangfire:SqlServer:Connection"); + var hangfireSqlServerCon = hangfireSqlServerConfiguration.Exists() + ? hangfireSqlServerConfiguration.Value : configuration.GetConnectionString("Default"); + + _jobStorage = new SqlServerStorage(hangfireSqlServerCon, sqlserverStorageOptions); + context.Services.AddSingleton(fac => + { + return _jobStorage; + }); + + context.Services.AddHangfire(config => + { + config.UseStorage(_jobStorage); + }); + } + } +} diff --git a/aspnet-core/modules/common/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN.Abp.IdentityServer.WeChatValidator.csproj b/aspnet-core/modules/common/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN.Abp.IdentityServer.WeChatValidator.csproj index fbae27373..d87bbe6fc 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN.Abp.IdentityServer.WeChatValidator.csproj +++ b/aspnet-core/modules/common/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN.Abp.IdentityServer.WeChatValidator.csproj @@ -20,7 +20,7 @@ - + diff --git a/aspnet-core/modules/common/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/WeChatValidator/WeChatValidatorConsts.cs b/aspnet-core/modules/common/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/WeChatValidator/WeChatValidatorConsts.cs index bc86ed61e..91ab26b6b 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/WeChatValidator/WeChatValidatorConsts.cs +++ b/aspnet-core/modules/common/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/WeChatValidator/WeChatValidatorConsts.cs @@ -10,7 +10,7 @@ public class ClaimTypes { - public const string OpenId = "wechat-id"; + public const string OpenId = "wx-openid"; } public class AuthenticationMethods diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/SignalRNotificationPublishProvider.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/SignalRNotificationPublishProvider.cs index 414eb0c64..02c9a216c 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/SignalRNotificationPublishProvider.cs +++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/SignalRNotificationPublishProvider.cs @@ -10,7 +10,8 @@ namespace LINGYUN.Abp.Notifications.SignalR { public class SignalRNotificationPublishProvider : NotificationPublishProvider { - public override string Name => "SignalR"; + public const string ProviderName = "SignalR"; + public override string Name => ProviderName; private readonly IOnlineClientManager _onlineClientManager; diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications.WeChat/LINGYUN.Abp.Notifications.WeChat.WeApp.csproj b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.WeChat/LINGYUN.Abp.Notifications.WeChat.WeApp.csproj index e84d5cac5..790973e9a 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.Notifications.WeChat/LINGYUN.Abp.Notifications.WeChat.WeApp.csproj +++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.WeChat/LINGYUN.Abp.Notifications.WeChat.WeApp.csproj @@ -14,7 +14,7 @@ - + diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN.Abp.Notifications.csproj b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN.Abp.Notifications.csproj index 8611e478a..9af56cb36 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN.Abp.Notifications.csproj +++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN.Abp.Notifications.csproj @@ -13,6 +13,7 @@ + diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/AbpNotificationModule.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/AbpNotificationModule.cs index 92b5fce3b..30bf9376b 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/AbpNotificationModule.cs +++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/AbpNotificationModule.cs @@ -2,6 +2,7 @@ using Microsoft.Extensions.DependencyInjection; using System; using System.Collections.Generic; +using Volo.Abp; using Volo.Abp.BackgroundJobs; using Volo.Abp.Json; using Volo.Abp.Modularity; @@ -38,6 +39,7 @@ namespace LINGYUN.Abp.Notifications services.Configure(options => { + services.ExecutePreConfiguredActions(options); options.DefinitionProviders.AddIfNotContains(definitionProviders); }); } diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/AbpNotificationOptions.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/AbpNotificationOptions.cs index dffacc0bf..45289f231 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/AbpNotificationOptions.cs +++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/AbpNotificationOptions.cs @@ -7,7 +7,6 @@ namespace LINGYUN.Abp.Notifications public ITypeList DefinitionProviders { get; } public ITypeList PublishProviders { get; } - public AbpNotificationOptions() { PublishProviders = new TypeList(); diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationDispatcher.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationDispatcher.cs index 99e189f7d..708d24f58 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationDispatcher.cs +++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationDispatcher.cs @@ -26,5 +26,16 @@ namespace LINGYUN.Abp.Notifications /// Task DispatchAsync(NotificationName notificationName, NotificationData data, Guid? tenantId = null, NotificationSeverity notificationSeverity = NotificationSeverity.Info); + + /// + /// 发送通知事件 + /// + /// 通知名称 + /// 数据 + /// 租户 + /// 级别 + /// + Task DispatchEventAsync(NotificationName notificationName, NotificationData data, Guid? tenantId = null, + NotificationSeverity notificationSeverity = NotificationSeverity.Info); } } diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationStore.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationStore.cs index 951537cb8..e90af6509 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationStore.cs +++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationStore.cs @@ -28,6 +28,8 @@ namespace LINGYUN.Abp.Notifications Task DeleteNotificationAsync(NotificationInfo notification); + Task DeleteNotificationAsync(int batchCount); + Task InsertUserNotificationAsync(NotificationInfo notification, Guid userId); Task InsertUserNotificationsAsync(NotificationInfo notification, IEnumerable userIds); diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/Internal/DefaultNotificationDispatcher.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/Internal/DefaultNotificationDispatcher.cs index a28d9dbfe..f081278cf 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/Internal/DefaultNotificationDispatcher.cs +++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/Internal/DefaultNotificationDispatcher.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Volo.Abp.BackgroundJobs; +using Volo.Abp.EventBus.Distributed; namespace LINGYUN.Abp.Notifications.Internal { @@ -18,6 +19,10 @@ namespace LINGYUN.Abp.Notifications.Internal /// public ILogger Logger { get; set; } /// + /// Reference to . + /// + public IDistributedEventBus DistributedEventBus { get; set; } + /// /// Reference to . /// private readonly IBackgroundJobManager _backgroundJobManager; @@ -49,6 +54,7 @@ namespace LINGYUN.Abp.Notifications.Internal _notificationDefinitionManager = notificationDefinitionManager; _notificationPublishProviderManager = notificationPublishProviderManager; + DistributedEventBus = NullDistributedEventBus.Instance; Logger = NullLogger.Instance; } /// @@ -74,6 +80,7 @@ namespace LINGYUN.Abp.Notifications.Internal var notificationInfo = new NotificationInfo { + CateGory = notificationName.CateGory, Name = notificationName.Name, CreationTime = DateTime.Now, NotificationSeverity = notificationSeverity, @@ -93,6 +100,33 @@ namespace LINGYUN.Abp.Notifications.Internal await PublishFromProvidersAsync(providers, notificationInfo); } /// + /// 发送通知事件 + /// + /// + /// + /// + /// + /// + public virtual async Task DispatchEventAsync(NotificationName notificationName, NotificationData data, Guid? tenantId = null, + NotificationSeverity notificationSeverity = NotificationSeverity.Info) + { + // 获取自定义的通知 + var defineNotification = _notificationDefinitionManager.Get(notificationName.CateGory); + + var notificationEventData = new NotificationEventData + { + CateGory = notificationName.CateGory, + Name = notificationName.Name, + CreationTime = DateTime.Now, + NotificationSeverity = notificationSeverity, + NotificationType = defineNotification.NotificationType, + TenantId = tenantId, + Data = data + }; + // 发布分布式通知事件,让消息中心统一处理 + await DistributedEventBus.PublishAsync(notificationEventData); + } + /// /// 发送通知 /// /// 通知信息 diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationEventData.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationEventData.cs new file mode 100644 index 000000000..1859937aa --- /dev/null +++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationEventData.cs @@ -0,0 +1,36 @@ +using System; + +namespace LINGYUN.Abp.Notifications +{ + public class NotificationEventData + { + public Guid? TenantId { get; set; } + public string CateGory { get; set; } + public string Name { get; set; } + public string Id { get; set; } + public NotificationData Data { get; set; } + public DateTime CreationTime { get; set; } + public NotificationType NotificationType { get; set; } + public NotificationSeverity NotificationSeverity { get; set; } + + public NotificationEventData() + { + + } + + public NotificationInfo ToNotificationInfo() + { + return new NotificationInfo + { + NotificationSeverity = NotificationSeverity, + CreationTime = CreationTime, + Data = Data, + Id = Id, + Name = Name, + CateGory = CateGory, + NotificationType = NotificationType, + TenantId = TenantId + }; + } + } +} diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationInfo.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationInfo.cs index cd6911dde..ebb3c325a 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationInfo.cs +++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationInfo.cs @@ -1,5 +1,4 @@ -using Newtonsoft.Json; -using System; +using System; namespace LINGYUN.Abp.Notifications { @@ -7,6 +6,7 @@ namespace LINGYUN.Abp.Notifications { public Guid? TenantId { get; set; } public string Name { get; set; } + public string CateGory { get; set; } public string Id { get; set; } public NotificationData Data { get; set; } public DateTime CreationTime { get; set; } @@ -36,5 +36,20 @@ namespace LINGYUN.Abp.Notifications { return long.Parse(Id); } + + public NotificationEventData ToNotificationEventData() + { + return new NotificationEventData + { + NotificationSeverity = NotificationSeverity, + CreationTime = CreationTime, + Data = Data, + Id = Id, + Name = Name, + CateGory = CateGory, + NotificationType = NotificationType, + TenantId = TenantId + }; + } } } diff --git a/aspnet-core/moudles/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN.Abp.WeChat.Authorization.csproj b/aspnet-core/modules/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN.Abp.WeChat.Authorization.csproj similarity index 100% rename from aspnet-core/moudles/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN.Abp.WeChat.Authorization.csproj rename to aspnet-core/modules/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN.Abp.WeChat.Authorization.csproj diff --git a/aspnet-core/moudles/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/AbpWeChatAuthorizationModule.cs b/aspnet-core/modules/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/AbpWeChatAuthorizationModule.cs similarity index 100% rename from aspnet-core/moudles/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/AbpWeChatAuthorizationModule.cs rename to aspnet-core/modules/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/AbpWeChatAuthorizationModule.cs diff --git a/aspnet-core/moudles/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/AbpWeChatOptions.cs b/aspnet-core/modules/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/AbpWeChatOptions.cs similarity index 100% rename from aspnet-core/moudles/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/AbpWeChatOptions.cs rename to aspnet-core/modules/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/AbpWeChatOptions.cs diff --git a/aspnet-core/moudles/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/IWeChatTokenProvider.cs b/aspnet-core/modules/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/IWeChatTokenProvider.cs similarity index 100% rename from aspnet-core/moudles/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/IWeChatTokenProvider.cs rename to aspnet-core/modules/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/IWeChatTokenProvider.cs diff --git a/aspnet-core/moudles/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/WeChatToken.cs b/aspnet-core/modules/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/WeChatToken.cs similarity index 100% rename from aspnet-core/moudles/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/WeChatToken.cs rename to aspnet-core/modules/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/WeChatToken.cs diff --git a/aspnet-core/moudles/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/WeChatTokenCacheItem.cs b/aspnet-core/modules/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/WeChatTokenCacheItem.cs similarity index 100% rename from aspnet-core/moudles/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/WeChatTokenCacheItem.cs rename to aspnet-core/modules/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/WeChatTokenCacheItem.cs diff --git a/aspnet-core/moudles/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/WeChatTokenProvider.cs b/aspnet-core/modules/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/WeChatTokenProvider.cs similarity index 100% rename from aspnet-core/moudles/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/WeChatTokenProvider.cs rename to aspnet-core/modules/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/WeChatTokenProvider.cs diff --git a/aspnet-core/moudles/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/WeChatTokenRequest.cs b/aspnet-core/modules/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/WeChatTokenRequest.cs similarity index 100% rename from aspnet-core/moudles/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/WeChatTokenRequest.cs rename to aspnet-core/modules/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/WeChatTokenRequest.cs diff --git a/aspnet-core/moudles/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/WeChatTokenResponse.cs b/aspnet-core/modules/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/WeChatTokenResponse.cs similarity index 100% rename from aspnet-core/moudles/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/WeChatTokenResponse.cs rename to aspnet-core/modules/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/WeChatTokenResponse.cs diff --git a/aspnet-core/moudles/common/LINGYUN.Abp.WeChat.Authorization/System/Net/Http/HttpClientWeChatTokenRequestExtensions.cs b/aspnet-core/modules/common/LINGYUN.Abp.WeChat.Authorization/System/Net/Http/HttpClientWeChatTokenRequestExtensions.cs similarity index 100% rename from aspnet-core/moudles/common/LINGYUN.Abp.WeChat.Authorization/System/Net/Http/HttpClientWeChatTokenRequestExtensions.cs rename to aspnet-core/modules/common/LINGYUN.Abp.WeChat.Authorization/System/Net/Http/HttpClientWeChatTokenRequestExtensions.cs diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain.Shared/LINGYUN/Abp/MessageService/Notifications/CleanupNotificationJobArgs.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain.Shared/LINGYUN/Abp/MessageService/Notifications/CleanupNotificationJobArgs.cs deleted file mode 100644 index 03536e0da..000000000 --- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain.Shared/LINGYUN/Abp/MessageService/Notifications/CleanupNotificationJobArgs.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; - -namespace LINGYUN.Abp.MessageService.Notifications -{ - public class CleanupNotificationJobArgs - { - /// - /// 清理大小 - /// - public int Count { get; set; } - /// - /// 清理租户 - /// - public Guid? TenantId { get; set; } - } -} diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain.Shared/LINGYUN/Abp/MessageService/Notifications/NotificationConsts.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain.Shared/LINGYUN/Abp/MessageService/Notifications/NotificationConsts.cs index 83de31bff..4e4d39cd6 100644 --- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain.Shared/LINGYUN/Abp/MessageService/Notifications/NotificationConsts.cs +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain.Shared/LINGYUN/Abp/MessageService/Notifications/NotificationConsts.cs @@ -2,6 +2,8 @@ { public class NotificationConsts { + public const int MaxCateGoryLength = 50; + public const int MaxNameLength = 100; public const int MaxDataLength = 1024 * 1024; diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/BackgroundJobs/NotificationExpritionCleanupJob.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/BackgroundJobs/NotificationExpritionCleanupJob.cs deleted file mode 100644 index 7a342922e..000000000 --- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/BackgroundJobs/NotificationExpritionCleanupJob.cs +++ /dev/null @@ -1,37 +0,0 @@ -using LINGYUN.Abp.MessageService.Notifications; -using System.Threading.Tasks; -using Volo.Abp.BackgroundJobs; -using Volo.Abp.MultiTenancy; -using Volo.Abp.Uow; - -namespace LINGYUN.Abp.MessageService.BackgroundJobs -{ - public class NotificationExpritionCleanupJob : AsyncBackgroundJob - { - private readonly ICurrentTenant _currentTenant; - private readonly IUnitOfWorkManager _unitOfWorkManager; - private readonly INotificationRepository _notificationRepository; - public NotificationExpritionCleanupJob( - ICurrentTenant currentTenant, - IUnitOfWorkManager unitOfWorkManager, - INotificationRepository notificationRepository) - { - _currentTenant = currentTenant; - _unitOfWorkManager = unitOfWorkManager; - _notificationRepository = notificationRepository; - } - - public override async Task ExecuteAsync(CleanupNotificationJobArgs args) - { - using (var unitOfWork = _unitOfWorkManager.Begin()) - { - using (_currentTenant.Change(args.TenantId)) - { - await _notificationRepository.DeleteExpritionAsync(args.Count); - - await unitOfWork.SaveChangesAsync(); - } - } - } - } -} diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Mapper/MessageServiceDomainAutoMapperProfile.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Mapper/MessageServiceDomainAutoMapperProfile.cs index 631b50e39..dc161472f 100644 --- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Mapper/MessageServiceDomainAutoMapperProfile.cs +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Mapper/MessageServiceDomainAutoMapperProfile.cs @@ -16,6 +16,7 @@ namespace LINGYUN.Abp.MessageService.Mapper CreateMap() .ForMember(dto => dto.Id, map => map.MapFrom(src => src.NotificationId)) .ForMember(dto => dto.Name, map => map.MapFrom(src => src.NotificationName)) + .ForMember(dto => dto.CateGory, map => map.MapFrom(src => src.NotificationCateGory)) .ForMember(dto => dto.NotificationType, map => map.MapFrom(src => src.Type)) .ForMember(dto => dto.NotificationSeverity, map => map.MapFrom(src => src.Severity)) .ForMember(dto => dto.Data, map => map.MapFrom((src, nfi) => diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/IUserNotificationRepository.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/IUserNotificationRepository.cs index 73f7bf28a..f0a98e351 100644 --- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/IUserNotificationRepository.cs +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/IUserNotificationRepository.cs @@ -8,6 +8,8 @@ namespace LINGYUN.Abp.MessageService.Notifications { public interface IUserNotificationRepository : IBasicRepository { + Task AnyAsync(Guid userId, long notificationId); + Task InsertUserNotificationsAsync(IEnumerable userNotifications); Task GetByIdAsync(Guid userId, long notificationId); diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/Notification.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/Notification.cs index 329ae9140..75d49b423 100644 --- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/Notification.cs +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/Notification.cs @@ -12,16 +12,18 @@ namespace LINGYUN.Abp.MessageService.Notifications public virtual NotificationSeverity Severity { get; protected set; } public virtual NotificationType Type { get; set; } public virtual long NotificationId { get; protected set; } + public virtual string NotificationCateGory { get; protected set; } public virtual string NotificationName { get; protected set; } public virtual string NotificationData { get; protected set; } public virtual string NotificationTypeName { get; protected set; } public virtual DateTime? ExpirationTime { get; set; } public virtual DateTime CreationTime { get; set; } protected Notification(){} - public Notification(long id, string name, string dataType, string data, NotificationSeverity severity = NotificationSeverity.Info) + public Notification(long id, string category, string name, string dataType, string data, NotificationSeverity severity = NotificationSeverity.Info) { NotificationId = id; Severity = severity; + NotificationCateGory = category; NotificationName = name; NotificationData = data; NotificationTypeName = dataType; diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/NotificationStore.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/NotificationStore.cs index 2530351ec..a7b5a5bef 100644 --- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/NotificationStore.cs +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/NotificationStore.cs @@ -65,6 +65,17 @@ namespace LINGYUN.Abp.MessageService.Notifications } } + [UnitOfWork] + public async Task DeleteNotificationAsync(int batchCount) + { + using (var unitOfWork = _unitOfWorkManager.Begin()) + { + await NotificationRepository.DeleteExpritionAsync(batchCount); + + await unitOfWork.SaveChangesAsync(); + } + } + [UnitOfWork] public async Task DeleteUserNotificationAsync(Guid? tenantId, Guid userId, long notificationId) { @@ -202,7 +213,7 @@ namespace LINGYUN.Abp.MessageService.Notifications // 保存主键,防止前端js long类型溢出 // notification.Data["id"] = notifyId.ToString(); - var notify = new Notification(notifyId, notification.Name, + var notify = new Notification(notifyId, notification.CateGory, notification.Name, notification.Data.GetType().AssemblyQualifiedName, JsonSerializer.Serialize(notification.Data), notification.NotificationSeverity) { @@ -286,8 +297,13 @@ namespace LINGYUN.Abp.MessageService.Notifications var userNofitications = new List(); foreach (var userId in userIds) { - var userNofitication = new UserNotification(notification.GetId(), userId, notification.TenantId); - userNofitications.Add(userNofitication); + // 重复检查 + // TODO:如果存在很多个订阅用户,这是个隐患 + if (!await UserNotificationRepository.AnyAsync(userId, notification.GetId())) + { + var userNofitication = new UserNotification(notification.GetId(), userId, notification.TenantId); + userNofitications.Add(userNofitication); + } } await UserNotificationRepository.InsertUserNotificationsAsync(userNofitications); diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/EntityFrameworkCore/MessageServiceDbContextModelCreatingExtensions.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/EntityFrameworkCore/MessageServiceDbContextModelCreatingExtensions.cs index d93b8a5fd..c18867104 100644 --- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/EntityFrameworkCore/MessageServiceDbContextModelCreatingExtensions.cs +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/EntityFrameworkCore/MessageServiceDbContextModelCreatingExtensions.cs @@ -25,13 +25,14 @@ namespace LINGYUN.Abp.MessageService.EntityFrameworkCore b.ToTable(options.TablePrefix + "Notifications", options.Schema); b.Property(p => p.NotificationName).HasMaxLength(NotificationConsts.MaxNameLength).IsRequired(); + b.Property(p => p.NotificationCateGory).HasMaxLength(NotificationConsts.MaxCateGoryLength).IsRequired(); b.Property(p => p.NotificationTypeName).HasMaxLength(NotificationConsts.MaxTypeNameLength).IsRequired(); b.Property(p => p.NotificationData).HasMaxLength(NotificationConsts.MaxDataLength).IsRequired(); b.ConfigureMultiTenant(); b.ConfigureCreationTime(); - b.HasIndex(p => p.NotificationName); + b.HasIndex(p => new { p.TenantId, p.NotificationName }); }); builder.Entity(b => diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Notifications/EfCoreUserNotificationRepository.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Notifications/EfCoreUserNotificationRepository.cs index c743dee86..86636675d 100644 --- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Notifications/EfCoreUserNotificationRepository.cs +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Notifications/EfCoreUserNotificationRepository.cs @@ -20,6 +20,12 @@ namespace LINGYUN.Abp.MessageService.Notifications { } + public async Task AnyAsync(Guid userId, long notificationId) + { + return await DbSet + .AnyAsync(x => x.NotificationId.Equals(notificationId) && x.UserId.Equals(userId)); + } + public async Task InsertUserNotificationsAsync(IEnumerable userNotifications) { await DbSet.AddRangeAsync(userNotifications); diff --git a/aspnet-core/services/account/AuthServer.Host/IdentityServer/IdentityServerDataSeedContributor.cs b/aspnet-core/services/account/AuthServer.Host/IdentityServer/IdentityServerDataSeedContributor.cs index f05e4d42a..5356e5842 100644 --- a/aspnet-core/services/account/AuthServer.Host/IdentityServer/IdentityServerDataSeedContributor.cs +++ b/aspnet-core/services/account/AuthServer.Host/IdentityServer/IdentityServerDataSeedContributor.cs @@ -1,4 +1,5 @@ -using Microsoft.Extensions.Configuration; +using LINGYUN.Abp.IdentityServer.WeChatValidator; +using Microsoft.Extensions.Configuration; using System; using System.Collections.Generic; using System.IO; @@ -8,6 +9,7 @@ using Volo.Abp.Authorization.Permissions; using Volo.Abp.Data; using Volo.Abp.DependencyInjection; using Volo.Abp.Guids; +using Volo.Abp.Identity; using Volo.Abp.IdentityServer.ApiResources; using Volo.Abp.IdentityServer.Clients; using Volo.Abp.IdentityServer.IdentityResources; @@ -21,6 +23,7 @@ namespace Multicolin.Aftermarket.IdentityServer private readonly IApiResourceRepository _apiResourceRepository; private readonly IClientRepository _clientRepository; private readonly IIdentityResourceDataSeeder _identityResourceDataSeeder; + private readonly IIdentityClaimTypeRepository _identityClaimTypeRepository; private readonly IPermissionDataSeeder _permissionDataSeeder; private readonly IGuidGenerator _guidGenerator; private readonly IConfiguration _configuration; @@ -30,11 +33,13 @@ namespace Multicolin.Aftermarket.IdentityServer IPermissionDataSeeder permissionDataSeeder, IApiResourceRepository apiResourceRepository, IIdentityResourceDataSeeder identityResourceDataSeeder, + IIdentityClaimTypeRepository identityClaimTypeRepository, IGuidGenerator guidGenerator) { _clientRepository = clientRepository; _permissionDataSeeder = permissionDataSeeder; _apiResourceRepository = apiResourceRepository; + _identityClaimTypeRepository = identityClaimTypeRepository; _identityResourceDataSeeder = identityResourceDataSeeder; _guidGenerator = guidGenerator; var env = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"; @@ -52,6 +57,18 @@ namespace Multicolin.Aftermarket.IdentityServer await _identityResourceDataSeeder.CreateStandardResourcesAsync(); await CreateApiResourcesAsync(); await CreateClientsAsync(); + await CreateWeChatClaimTypeAsync(); + } + + private async Task CreateWeChatClaimTypeAsync() + { + if (!await _identityClaimTypeRepository.AnyAsync(WeChatValidatorConsts.ClaimTypes.OpenId)) + { + var wechatClaimType = new IdentityClaimType(_guidGenerator.Create(), WeChatValidatorConsts.ClaimTypes.OpenId, + isStatic: true, description: "适用于微信认证的用户标识"); + + await _identityClaimTypeRepository.InsertAsync(wechatClaimType); + } } private async Task CreateApiResourcesAsync() diff --git a/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/BackgroundJobs/NotificationCleanupExpritionJob.cs b/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/BackgroundJobs/NotificationCleanupExpritionJob.cs new file mode 100644 index 000000000..591ced1b8 --- /dev/null +++ b/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/BackgroundJobs/NotificationCleanupExpritionJob.cs @@ -0,0 +1,38 @@ +using LINGYUN.Abp.Notifications; +using Microsoft.Extensions.Logging; +using System; +using System.Threading.Tasks; +using Volo.Abp.BackgroundJobs; +using Volo.Abp.DependencyInjection; + +namespace LINGYUN.Abp.MessageService.BackgroundJobs +{ + internal class NotificationCleanupExpritionJob : AsyncBackgroundJob, ITransientDependency + { + protected INotificationStore Store { get; } + protected IServiceProvider ServiceProvider { get; } + + public NotificationCleanupExpritionJob( + INotificationStore store, + IServiceProvider serviceProvider) + { + Store = store; + ServiceProvider = serviceProvider; + } + + public override async Task ExecuteAsync(NotificationCleanupExpritionJobArgs args) + { + try + { + Logger.LogDebug("Before cleanup exprition jobs..."); + await Store.DeleteNotificationAsync(args.Count); + Logger.LogDebug("Exprition jobs cleanup job was successful..."); + } + catch (Exception ex) + { + Logger.LogWarning("Exprition jobs cleanup job was failed..."); + Logger.LogWarning("Error:{0}", ex.Message); + } + } + } +} diff --git a/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/BackgroundJobs/NotificationCleanupExpritionJobArgs.cs b/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/BackgroundJobs/NotificationCleanupExpritionJobArgs.cs new file mode 100644 index 000000000..73b57110a --- /dev/null +++ b/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/BackgroundJobs/NotificationCleanupExpritionJobArgs.cs @@ -0,0 +1,23 @@ +using Volo.Abp.BackgroundJobs; + +namespace LINGYUN.Abp.MessageService.BackgroundJobs +{ + [BackgroundJobName("定时清理过期通知消息任务")] + internal class NotificationCleanupExpritionJobArgs + { + /// + /// 清理大小 + /// + public int Count { get; set; } + + public NotificationCleanupExpritionJobArgs() + { + + } + + public NotificationCleanupExpritionJobArgs(int count = 200) + { + Count = count; + } + } +} diff --git a/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/EventBus/Distributed/NotificationEventHandler.cs b/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/EventBus/Distributed/NotificationEventHandler.cs new file mode 100644 index 000000000..b099fd697 --- /dev/null +++ b/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/EventBus/Distributed/NotificationEventHandler.cs @@ -0,0 +1,136 @@ +using LINGYUN.Abp.Notifications; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; +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.Uow; + +namespace LINGYUN.Abp.MessageService.EventBus.Distributed +{ + /// + /// 订阅通知发布事件,统一发布消息 + /// + /// + /// 作用在于SignalR客户端只会与一台服务器建立连接, + /// 只有启用了SignlR服务端的才能真正将消息发布到客户端 + /// + public class NotificationEventHandler : IDistributedEventHandler, ITransientDependency + { + /// + /// Reference to . + /// + public ILogger Logger { get; set; } + /// + /// Reference to . + /// + protected IBackgroundJobManager BackgroundJobManager; + /// + /// Reference to . + /// + protected INotificationStore NotificationStore { get; } + /// + /// Reference to . + /// + protected INotificationPublishProviderManager NotificationPublishProviderManager { get; } + + /// + /// Initializes a new instance of the class. + /// + public NotificationEventHandler( + IBackgroundJobManager backgroundJobManager, + + INotificationStore notificationStore, + INotificationPublishProviderManager notificationPublishProviderManager) + { + BackgroundJobManager = backgroundJobManager; + + NotificationStore = notificationStore; + NotificationPublishProviderManager = notificationPublishProviderManager; + + Logger = NullLogger.Instance; + } + + [UnitOfWork] + public virtual async Task HandleEventAsync(NotificationEventData eventData) + { + var notificationInfo = eventData.ToNotificationInfo(); + + var providers = Enumerable + .Reverse(NotificationPublishProviderManager.Providers); + + await PublishFromProvidersAsync(providers, notificationInfo); + } + + /// + /// 指定提供者发布通知 + /// + /// 提供者列表 + /// 通知信息 + /// + protected async Task PublishFromProvidersAsync(IEnumerable providers, + NotificationInfo notificationInfo) + { + Logger.LogDebug($"Persistent notification {notificationInfo.Name}"); + + // 持久化通知 + await NotificationStore.InsertNotificationAsync(notificationInfo); + + Logger.LogDebug($"Gets a list of user subscriptions {notificationInfo.Name}"); + // 获取用户订阅列表 + var userSubscriptions = await NotificationStore.GetSubscriptionsAsync(notificationInfo.TenantId, notificationInfo.Name); + + Logger.LogDebug($"Persistent user notifications {notificationInfo.Name}"); + // 持久化用户通知 + var subscriptionUserIdentifiers = userSubscriptions.Select(us => new UserIdentifier(us.UserId, us.UserName)); + + await NotificationStore.InsertUserNotificationsAsync(notificationInfo, + subscriptionUserIdentifiers.Select(u => u.UserId)); + + // 发布通知 + foreach (var provider in providers) + { + await PublishAsync(provider, notificationInfo, subscriptionUserIdentifiers); + } + } + /// + /// 发布通知 + /// + /// 通知发布者 + /// 通知信息 + /// 订阅用户列表 + /// + protected async Task PublishAsync(INotificationPublishProvider provider, NotificationInfo notificationInfo, + IEnumerable subscriptionUserIdentifiers) + { + try + { + Logger.LogDebug($"Sending notification with provider {provider.Name}"); + + // 发布 + 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)); + } + } + } +} diff --git a/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN.Abp.MessageService.HttpApi.Host.csproj b/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN.Abp.MessageService.HttpApi.Host.csproj index f557962e3..08d38c8de 100644 --- a/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN.Abp.MessageService.HttpApi.Host.csproj +++ b/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN.Abp.MessageService.HttpApi.Host.csproj @@ -43,6 +43,8 @@ + + diff --git a/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN/Abp/MessageService/AbpMessageServiceHttpApiHostModule.cs b/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN/Abp/MessageService/AbpMessageServiceHttpApiHostModule.cs index f23bf4fc2..a1390d1ce 100644 --- a/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN/Abp/MessageService/AbpMessageServiceHttpApiHostModule.cs +++ b/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN/Abp/MessageService/AbpMessageServiceHttpApiHostModule.cs @@ -1,7 +1,11 @@ using DotNetCore.CAP; +using Hangfire; using IdentityModel; +using LINGYUN.Abp.BackgroundJobs.Hangfire; using LINGYUN.Abp.EventBus.CAP; +using LINGYUN.Abp.Hangfire.Storage.MySql; using LINGYUN.Abp.IM.SignalR; +using LINGYUN.Abp.MessageService.BackgroundJobs; using LINGYUN.Abp.MessageService.EntityFrameworkCore; using LINGYUN.Abp.MessageService.Localization; using LINGYUN.Abp.MessageService.MultiTenancy; @@ -20,6 +24,7 @@ using Volo.Abp; using Volo.Abp.AspNetCore.Authentication.JwtBearer; using Volo.Abp.AspNetCore.MultiTenancy; using Volo.Abp.Autofac; +using Volo.Abp.BackgroundJobs; using Volo.Abp.Caching; using Volo.Abp.EntityFrameworkCore; using Volo.Abp.Localization; @@ -29,6 +34,7 @@ using Volo.Abp.PermissionManagement.EntityFrameworkCore; using Volo.Abp.Security.Claims; using Volo.Abp.SettingManagement.EntityFrameworkCore; using Volo.Abp.TenantManagement.EntityFrameworkCore; +using Volo.Abp.Threading; using Volo.Abp.VirtualFileSystem; namespace LINGYUN.Abp.MessageService @@ -45,6 +51,8 @@ namespace LINGYUN.Abp.MessageService typeof(AbpNotificationsSignalRModule), typeof(AbpNotificationsWeChatWeAppModule), typeof(AbpCAPEventBusModule), + typeof(AbpBackgroundJobsHangfireModule), + typeof(AbpHangfireMySqlStorageModule), typeof(AbpAutofacModule) )] public class AbpMessageServiceHttpApiHostModule : AbpModule @@ -147,6 +155,14 @@ namespace LINGYUN.Abp.MessageService } } + public override void OnPostApplicationInitialization(ApplicationInitializationContext context) + { + var backgroundJobManager = context.ServiceProvider.GetRequiredService(); + // 五分钟执行一次的定时任务 + AsyncHelper.RunSync(async () => await + backgroundJobManager.EnqueueAsync(CronGenerator.Minute(5), new NotificationCleanupExpritionJobArgs(200))); + } + public override void OnApplicationInitialization(ApplicationInitializationContext context) { var app = context.GetApplicationBuilder(); @@ -177,6 +193,8 @@ namespace LINGYUN.Abp.MessageService }); // 审计日志 app.UseAuditing(); + app.UseHangfireServer(); + app.UseHangfireDashboard(); // 路由 app.UseConfiguredEndpoints(); } diff --git a/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/20200617010925_Add-Notification-Column-CateGory.Designer.cs b/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/20200617010925_Add-Notification-Column-CateGory.Designer.cs new file mode 100644 index 000000000..352a9f8ae --- /dev/null +++ b/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/20200617010925_Add-Notification-Column-CateGory.Designer.cs @@ -0,0 +1,508 @@ +// +using System; +using LINGYUN.Abp.MessageService.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Volo.Abp.EntityFrameworkCore; + +namespace LINGYUN.Abp.MessageService.Migrations +{ + [DbContext(typeof(MessageServiceHostMigrationsDbContext))] + [Migration("20200617010925_Add-Notification-Column-CateGory")] + partial class AddNotificationColumnCateGory + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.MySql) + .HasAnnotation("ProductVersion", "3.1.4") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + modelBuilder.Entity("LINGYUN.Abp.MessageService.Messages.ChatGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("Address") + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("AllowAnonymous") + .HasColumnType("tinyint(1)"); + + b.Property("AllowSendMessage") + .HasColumnType("tinyint(1)"); + + b.Property("CreationTime") + .HasColumnName("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("CreatorId") + .HasColumnName("CreatorId") + .HasColumnType("char(36)"); + + b.Property("Description") + .HasColumnType("varchar(128) CHARACTER SET utf8mb4") + .HasMaxLength(128); + + b.Property("GroupId") + .HasColumnType("bigint"); + + b.Property("LastModificationTime") + .HasColumnName("LastModificationTime") + .HasColumnType("datetime(6)"); + + b.Property("LastModifierId") + .HasColumnName("LastModifierId") + .HasColumnType("char(36)"); + + b.Property("MaxUserCount") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasColumnType("varchar(20) CHARACTER SET utf8mb4") + .HasMaxLength(20); + + b.Property("Notice") + .HasColumnType("varchar(64) CHARACTER SET utf8mb4") + .HasMaxLength(64); + + b.Property("Tag") + .HasColumnType("varchar(512) CHARACTER SET utf8mb4") + .HasMaxLength(512); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "Name"); + + b.ToTable("AppChatGroups"); + }); + + modelBuilder.Entity("LINGYUN.Abp.MessageService.Messages.ChatGroupAdmin", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("AllowAddPeople") + .HasColumnType("tinyint(1)"); + + b.Property("AllowDissolveGroup") + .HasColumnType("tinyint(1)"); + + b.Property("AllowKickPeople") + .HasColumnType("tinyint(1)"); + + b.Property("AllowSendNotice") + .HasColumnType("tinyint(1)"); + + b.Property("AllowSilence") + .HasColumnType("tinyint(1)"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("CreatorId") + .HasColumnType("char(36)"); + + b.Property("GroupId") + .HasColumnType("bigint"); + + b.Property("IsSuperAdmin") + .HasColumnType("tinyint(1)"); + + b.Property("LastModificationTime") + .HasColumnType("datetime(6)"); + + b.Property("LastModifierId") + .HasColumnType("char(36)"); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("char(36)"); + + b.Property("UserId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "GroupId"); + + b.ToTable("AppChatGroupAdmins"); + }); + + modelBuilder.Entity("LINGYUN.Abp.MessageService.Messages.GroupChatBlack", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("CreatorId") + .HasColumnType("char(36)"); + + b.Property("GroupId") + .HasColumnType("bigint"); + + b.Property("ShieldUserId") + .HasColumnType("char(36)"); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "GroupId"); + + b.ToTable("AppGroupChatBlacks"); + }); + + modelBuilder.Entity("LINGYUN.Abp.MessageService.Messages.GroupMessage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("Content") + .IsRequired() + .HasColumnType("longtext CHARACTER SET utf8mb4") + .HasMaxLength(1048576); + + b.Property("CreationTime") + .HasColumnName("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("CreatorId") + .HasColumnType("char(36)"); + + b.Property("GroupId") + .HasColumnType("bigint"); + + b.Property("MessageId") + .HasColumnType("bigint"); + + b.Property("SendState") + .HasColumnType("tinyint"); + + b.Property("SendUserName") + .IsRequired() + .HasColumnType("varchar(64) CHARACTER SET utf8mb4") + .HasMaxLength(64); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("char(36)"); + + b.Property("Type") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "GroupId"); + + b.ToTable("AppGroupMessages"); + }); + + modelBuilder.Entity("LINGYUN.Abp.MessageService.Messages.UserChatBlack", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("CreatorId") + .HasColumnType("char(36)"); + + b.Property("ShieldUserId") + .HasColumnType("char(36)"); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("char(36)"); + + b.Property("UserId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "UserId"); + + b.ToTable("AppUserChatBlacks"); + }); + + modelBuilder.Entity("LINGYUN.Abp.MessageService.Messages.UserChatGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("CreationTime") + .HasColumnName("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("CreatorId") + .HasColumnName("CreatorId") + .HasColumnType("char(36)"); + + b.Property("GroupId") + .HasColumnType("bigint"); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("char(36)"); + + b.Property("UserId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "GroupId", "UserId"); + + b.ToTable("AppUserChatGroups"); + }); + + modelBuilder.Entity("LINGYUN.Abp.MessageService.Messages.UserChatSetting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("AllowAddFriend") + .HasColumnType("tinyint(1)"); + + b.Property("AllowAnonymous") + .HasColumnType("tinyint(1)"); + + b.Property("AllowReceiveMessage") + .HasColumnType("tinyint(1)"); + + b.Property("AllowSendMessage") + .HasColumnType("tinyint(1)"); + + b.Property("RequireAddFriendValition") + .HasColumnType("tinyint(1)"); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("char(36)"); + + b.Property("UserId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "UserId"); + + b.ToTable("AppUserChatSettings"); + }); + + modelBuilder.Entity("LINGYUN.Abp.MessageService.Messages.UserMessage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("Content") + .IsRequired() + .HasColumnType("longtext CHARACTER SET utf8mb4") + .HasMaxLength(1048576); + + b.Property("CreationTime") + .HasColumnName("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("CreatorId") + .HasColumnType("char(36)"); + + b.Property("MessageId") + .HasColumnType("bigint"); + + b.Property("ReceiveUserId") + .HasColumnType("char(36)"); + + b.Property("SendState") + .HasColumnType("tinyint"); + + b.Property("SendUserName") + .IsRequired() + .HasColumnType("varchar(64) CHARACTER SET utf8mb4") + .HasMaxLength(64); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("char(36)"); + + b.Property("Type") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "ReceiveUserId"); + + b.ToTable("AppUserMessages"); + }); + + modelBuilder.Entity("LINGYUN.Abp.MessageService.Messages.UserSpecialFocus", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("CreatorId") + .HasColumnType("char(36)"); + + b.Property("FocusUserId") + .HasColumnType("char(36)"); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("char(36)"); + + b.Property("UserId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "UserId"); + + b.ToTable("AppUserSpecialFocuss"); + }); + + modelBuilder.Entity("LINGYUN.Abp.MessageService.Notifications.Notification", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("CreationTime") + .HasColumnName("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("ExpirationTime") + .HasColumnType("datetime(6)"); + + b.Property("NotificationCateGory") + .IsRequired() + .HasColumnType("varchar(50) CHARACTER SET utf8mb4") + .HasMaxLength(50); + + b.Property("NotificationData") + .IsRequired() + .HasColumnType("longtext CHARACTER SET utf8mb4") + .HasMaxLength(1048576); + + b.Property("NotificationId") + .HasColumnType("bigint"); + + b.Property("NotificationName") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b.Property("NotificationTypeName") + .IsRequired() + .HasColumnType("varchar(512) CHARACTER SET utf8mb4") + .HasMaxLength(512); + + b.Property("Severity") + .HasColumnType("tinyint"); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("char(36)"); + + b.Property("Type") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "NotificationName"); + + b.ToTable("AppNotifications"); + }); + + modelBuilder.Entity("LINGYUN.Abp.MessageService.Notifications.UserNotification", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("NotificationId") + .HasColumnType("bigint"); + + b.Property("ReadStatus") + .HasColumnType("int"); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("char(36)"); + + b.Property("UserId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "UserId", "NotificationId") + .HasName("IX_Tenant_User_Notification_Id"); + + b.ToTable("AppUserNotifications"); + }); + + modelBuilder.Entity("LINGYUN.Abp.MessageService.Subscriptions.UserSubscribe", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("CreationTime") + .HasColumnName("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("NotificationName") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("char(36)"); + + b.Property("UserId") + .HasColumnType("char(36)"); + + b.Property("UserName") + .IsRequired() + .ValueGeneratedOnAdd() + .HasColumnType("varchar(128) CHARACTER SET utf8mb4") + .HasMaxLength(128) + .HasDefaultValue("/"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "UserId", "NotificationName") + .IsUnique() + .HasName("IX_Tenant_User_Notification_Name"); + + b.ToTable("AppUserSubscribes"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/20200617010925_Add-Notification-Column-CateGory.cs b/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/20200617010925_Add-Notification-Column-CateGory.cs new file mode 100644 index 000000000..928173a6d --- /dev/null +++ b/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/20200617010925_Add-Notification-Column-CateGory.cs @@ -0,0 +1,42 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace LINGYUN.Abp.MessageService.Migrations +{ + public partial class AddNotificationColumnCateGory : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropIndex( + name: "IX_AppNotifications_NotificationName", + table: "AppNotifications"); + + migrationBuilder.AddColumn( + name: "NotificationCateGory", + table: "AppNotifications", + maxLength: 50, + nullable: false, + defaultValue: ""); + + migrationBuilder.CreateIndex( + name: "IX_AppNotifications_TenantId_NotificationName", + table: "AppNotifications", + columns: new[] { "TenantId", "NotificationName" }); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropIndex( + name: "IX_AppNotifications_TenantId_NotificationName", + table: "AppNotifications"); + + migrationBuilder.DropColumn( + name: "NotificationCateGory", + table: "AppNotifications"); + + migrationBuilder.CreateIndex( + name: "IX_AppNotifications_NotificationName", + table: "AppNotifications", + column: "NotificationName"); + } + } +} diff --git a/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/MessageServiceHostMigrationsDbContextModelSnapshot.cs b/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/MessageServiceHostMigrationsDbContextModelSnapshot.cs index cccaa5a84..824c5c9e7 100644 --- a/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/MessageServiceHostMigrationsDbContextModelSnapshot.cs +++ b/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/MessageServiceHostMigrationsDbContextModelSnapshot.cs @@ -396,6 +396,11 @@ namespace LINGYUN.Abp.MessageService.Migrations b.Property("ExpirationTime") .HasColumnType("datetime(6)"); + b.Property("NotificationCateGory") + .IsRequired() + .HasColumnType("varchar(50) CHARACTER SET utf8mb4") + .HasMaxLength(50); + b.Property("NotificationData") .IsRequired() .HasColumnType("longtext CHARACTER SET utf8mb4") @@ -426,7 +431,7 @@ namespace LINGYUN.Abp.MessageService.Migrations b.HasKey("Id"); - b.HasIndex("NotificationName"); + b.HasIndex("TenantId", "NotificationName"); b.ToTable("AppNotifications"); }); diff --git a/aspnet-core/services/start-all-service.bat b/aspnet-core/services/start-all-service.bat index c7641f6ff..a311b5962 100644 --- a/aspnet-core/services/start-all-service.bat +++ b/aspnet-core/services/start-all-service.bat @@ -4,5 +4,6 @@ cls start .\start-identity-server.bat --run start .\start-apigateway-admin.bat --run start .\start-platform.bat --run +start .\start-messages.bat --run ping -n 10 127.1 >nul start .\start-apigateway-host.bat --run \ No newline at end of file