Browse Source

增加Hangfire定时任务集成,扩展官方Hangfire库;增加通知事件发布接口;其他适当性修改

pull/7/head
cKey 6 years ago
parent
commit
170173f84c
  1. 13
      aspnet-core/modules/common/LINGYUN.Abp.BackgroundJobs.Hangfire/LINGYUN.Abp.BackgroundJobs.Hangfire.csproj
  2. 34
      aspnet-core/modules/common/LINGYUN.Abp.BackgroundJobs.Hangfire/LINGYUN/Abp/BackgroundJobs/Hangfire/AbpBackgroundJobsHangfireModule.cs
  3. 34
      aspnet-core/modules/common/LINGYUN.Abp.BackgroundJobs.Hangfire/LINGYUN/Abp/BackgroundJobs/Hangfire/HangfireBackgroundJobManager.cs
  4. 46
      aspnet-core/modules/common/LINGYUN.Abp.BackgroundJobs.Hangfire/LINGYUN/Abp/BackgroundJobs/Hangfire/HangfireJobExecutionAdapter.cs
  5. 35
      aspnet-core/modules/common/LINGYUN.Abp.BackgroundJobs.Hangfire/LINGYUN/Abp/BackgroundJobs/Hangfire/IBackgroundJobManagerExtensions.cs
  6. 78
      aspnet-core/modules/common/LINGYUN.Abp.BackgroundJobs.Hangfire/Volo/Abp/BackgroundJobs/CronGenerator.cs
  7. 22
      aspnet-core/modules/common/LINGYUN.Abp.Hangfire.MySqlStorage/LINGYUN.Abp.Hangfire.Storage.MySql.csproj
  8. 38
      aspnet-core/modules/common/LINGYUN.Abp.Hangfire.MySqlStorage/LINGYUN/Abp/Hangfire/Storage/MySql/AbpHangfireMySqlStorageModule.cs
  9. 20
      aspnet-core/modules/common/LINGYUN.Abp.Hangfire.Storage.SqlServer/LINGYUN.Abp.Hangfire.Storage.SqlServer.csproj
  10. 38
      aspnet-core/modules/common/LINGYUN.Abp.Hangfire.Storage.SqlServer/LINGYUN/Abp/Hangfire/Storage/SqlServer/AbpHangfireSqlServerStorageModule.cs
  11. 2
      aspnet-core/modules/common/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN.Abp.IdentityServer.WeChatValidator.csproj
  12. 2
      aspnet-core/modules/common/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/WeChatValidator/WeChatValidatorConsts.cs
  13. 3
      aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/SignalRNotificationPublishProvider.cs
  14. 2
      aspnet-core/modules/common/LINGYUN.Abp.Notifications.WeChat/LINGYUN.Abp.Notifications.WeChat.WeApp.csproj
  15. 1
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN.Abp.Notifications.csproj
  16. 2
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/AbpNotificationModule.cs
  17. 1
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/AbpNotificationOptions.cs
  18. 11
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationDispatcher.cs
  19. 2
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationStore.cs
  20. 34
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/Internal/DefaultNotificationDispatcher.cs
  21. 36
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationEventData.cs
  22. 19
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationInfo.cs
  23. 0
      aspnet-core/modules/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN.Abp.WeChat.Authorization.csproj
  24. 0
      aspnet-core/modules/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/AbpWeChatAuthorizationModule.cs
  25. 0
      aspnet-core/modules/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/AbpWeChatOptions.cs
  26. 0
      aspnet-core/modules/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/IWeChatTokenProvider.cs
  27. 0
      aspnet-core/modules/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/WeChatToken.cs
  28. 0
      aspnet-core/modules/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/WeChatTokenCacheItem.cs
  29. 0
      aspnet-core/modules/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/WeChatTokenProvider.cs
  30. 0
      aspnet-core/modules/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/WeChatTokenRequest.cs
  31. 0
      aspnet-core/modules/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/WeChatTokenResponse.cs
  32. 0
      aspnet-core/modules/common/LINGYUN.Abp.WeChat.Authorization/System/Net/Http/HttpClientWeChatTokenRequestExtensions.cs
  33. 16
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain.Shared/LINGYUN/Abp/MessageService/Notifications/CleanupNotificationJobArgs.cs
  34. 2
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain.Shared/LINGYUN/Abp/MessageService/Notifications/NotificationConsts.cs
  35. 37
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/BackgroundJobs/NotificationExpritionCleanupJob.cs
  36. 1
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Mapper/MessageServiceDomainAutoMapperProfile.cs
  37. 2
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/IUserNotificationRepository.cs
  38. 4
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/Notification.cs
  39. 22
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/NotificationStore.cs
  40. 3
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/EntityFrameworkCore/MessageServiceDbContextModelCreatingExtensions.cs
  41. 6
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Notifications/EfCoreUserNotificationRepository.cs
  42. 19
      aspnet-core/services/account/AuthServer.Host/IdentityServer/IdentityServerDataSeedContributor.cs
  43. 38
      aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/BackgroundJobs/NotificationCleanupExpritionJob.cs
  44. 23
      aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/BackgroundJobs/NotificationCleanupExpritionJobArgs.cs
  45. 136
      aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/EventBus/Distributed/NotificationEventHandler.cs
  46. 2
      aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN.Abp.MessageService.HttpApi.Host.csproj
  47. 18
      aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN/Abp/MessageService/AbpMessageServiceHttpApiHostModule.cs
  48. 508
      aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/20200617010925_Add-Notification-Column-CateGory.Designer.cs
  49. 42
      aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/20200617010925_Add-Notification-Column-CateGory.cs
  50. 7
      aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/MessageServiceHostMigrationsDbContextModelSnapshot.cs
  51. 1
      aspnet-core/services/start-all-service.bat

13
aspnet-core/modules/common/LINGYUN.Abp.BackgroundJobs.Hangfire/LINGYUN.Abp.BackgroundJobs.Hangfire.csproj

@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.HangFire" Version="2.9.0" />
<PackageReference Include="Volo.Abp.BackgroundJobs" Version="2.9.0" />
</ItemGroup>
</Project>

34
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<IOptions<AbpBackgroundJobOptions>>().Value;
if (!options.IsJobExecutionEnabled)
{
var hangfireOptions = context.ServiceProvider.GetRequiredService<IOptions<AbpHangfireOptions>>().Value;
hangfireOptions.BackgroundJobServerFactory = CreateOnlyEnqueueJobServer;
}
}
private BackgroundJobServer CreateOnlyEnqueueJobServer(IServiceProvider serviceProvider)
{
serviceProvider.GetRequiredService<JobStorage>();
return null;
}
}
}

34
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<string> EnqueueAsync<TArgs>(TArgs args, BackgroundJobPriority priority = BackgroundJobPriority.Normal,
TimeSpan? delay = null)
{
if (!delay.HasValue)
{
return Task.FromResult(
BackgroundJob.Enqueue<HangfireJobExecutionAdapter<TArgs>>(
adapter => adapter.Execute(args)
)
);
}
else
{
return Task.FromResult(
BackgroundJob.Schedule<HangfireJobExecutionAdapter<TArgs>>(
adapter => adapter.Execute(args),
delay.Value
)
);
}
}
}
}

46
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<TArgs>
{
protected AbpBackgroundJobOptions Options { get; }
protected IServiceScopeFactory ServiceScopeFactory { get; }
protected IBackgroundJobExecuter JobExecuter { get; }
public HangfireJobExecutionAdapter(
IOptions<AbpBackgroundJobOptions> 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));
}
}
}
}

35
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
{
/// <summary>
/// 后台作业进入周期性队列
/// </summary>
/// <typeparam name="TArgs">作业参数类型</typeparam>
/// <param name="backgroundJobManager">后台作业管理器</param>
/// <param name="cron">Cron表达式</param>
/// <param name="args">作业参数</param>
/// <returns></returns>
public static Task EnqueueAsync<TArgs>(
this IBackgroundJobManager backgroundJobManager,
[NotNull] string cron,
TArgs args
)
{
Check.NotNullOrWhiteSpace(cron, nameof(cron));
Check.NotNull(args, nameof(args));
var jobName = BackgroundJobNameAttribute.GetName<TArgs>();
RecurringJob.AddOrUpdate<HangfireJobExecutionAdapter<TArgs>>(jobName, adapter => adapter.Execute(args), cron);
return Task.CompletedTask;
}
}
}

78
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
{
/// <summary>
/// 周期性为分钟的任务
/// </summary>
/// <param name="interval">执行周期的间隔,默认为每分钟一次</param>
/// <returns></returns>
public static string Minute(int interval = 1)
{
return $"1 0/{interval} * * * ? ";
}
/// <summary>
/// 周期性为小时的任务
/// </summary>
/// <param name="minute">第几分钟开始,默认为第一分钟</param>
/// <param name="interval">执行周期的间隔,默认为每小时一次</param>
/// <returns></returns>
public static string Hour(int minute = 1, int interval = 1)
{
return $"1 {minute} 0/ {interval} * * ? ";
}
/// <summary>
/// 周期性为天的任务
/// </summary>
/// <param name="hour">第几小时开始,默认从1点开始</param>
/// <param name="minute">第几分钟开始,默认从第1分钟开始</param>
/// <param name="interval">执行周期的间隔,默认为每天一次</param>
/// <returns></returns>
public static string Day(int hour = 1, int minute = 1, int interval = 1)
{
return $"1 {minute} {hour} 1/ {interval} * ? ";
}
/// <summary>
/// 周期性为周的任务
/// </summary>
/// <param name="dayOfWeek">星期几开始,默认从星期一点开始</param>
/// <param name="hour">第几小时开始,默认从1点开始</param>
/// <param name="minute">第几分钟开始,默认从第1分钟开始</param>
/// <returns></returns>
public static string Week(DayOfWeek dayOfWeek = DayOfWeek.Monday, int hour = 1, int minute = 1)
{
return Cron.Weekly(dayOfWeek, hour, minute);
}
/// <summary>
/// 周期性为月的任务
/// </summary>
/// <param name="day">几号开始,默认从一号开始</param>
/// <param name="hour">第几小时开始,默认从1点开始</param>
/// <param name="minute">第几分钟开始,默认从第1分钟开始</param>
/// <returns></returns>
public static string Month(int day = 1, int hour = 1, int minute = 1)
{
return Cron.Monthly(day, hour, minute);
}
/// <summary>
/// 周期性为年的任务
/// </summary>
/// <param name="month">几月开始,默认从一月开始</param>
/// <param name="day">几号开始,默认从一号开始</param>
/// <param name="hour">第几小时开始,默认从1点开始</param>
/// <param name="minute">第几分钟开始,默认从第1分钟开始</param>
/// <returns></returns>
public static string Year(int month = 1, int day = 1, int hour = 1, int minute = 1)
{
return Cron.Yearly(month, day, hour, minute);
}
}
}

22
aspnet-core/modules/common/LINGYUN.Abp.Hangfire.MySqlStorage/LINGYUN.Abp.Hangfire.Storage.MySql.csproj

@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace />
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Version>2.9.0</Version>
<Company>LINGYUN</Company>
<Authors>LINGYUN</Authors>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<OutputPath>D:\LocalNuget</OutputPath>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Hangfire.MySql.Core" Version="2.2.5" />
<PackageReference Include="Volo.Abp.HangFire" Version="2.9.0" />
</ItemGroup>
</Project>

38
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<JobStorage, MySqlStorage>(fac =>
{
return _jobStorage;
});
context.Services.AddHangfire(config =>
{
config.UseStorage(_jobStorage);
});
}
}
}

20
aspnet-core/modules/common/LINGYUN.Abp.Hangfire.Storage.SqlServer/LINGYUN.Abp.Hangfire.Storage.SqlServer.csproj

@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace />
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Version>2.9.0</Version>
<Authors>LINGYUN</Authors>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<OutputPath>D:\LocalNuget</OutputPath>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="HangFire.SqlServer" Version="1.7.11" />
<PackageReference Include="Volo.Abp.HangFire" Version="2.9.0" />
</ItemGroup>
</Project>

38
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<JobStorage, SqlServerStorage>(fac =>
{
return _jobStorage;
});
context.Services.AddHangfire(config =>
{
config.UseStorage(_jobStorage);
});
}
}
}

2
aspnet-core/modules/common/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN.Abp.IdentityServer.WeChatValidator.csproj

@ -20,7 +20,7 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\moudles\common\LINGYUN.Abp.WeChat.Authorization\LINGYUN.Abp.WeChat.Authorization.csproj" />
<ProjectReference Include="..\..\..\modules\common\LINGYUN.Abp.WeChat.Authorization\LINGYUN.Abp.WeChat.Authorization.csproj" />
</ItemGroup>
</Project>

2
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

3
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;

2
aspnet-core/modules/common/LINGYUN.Abp.Notifications.WeChat/LINGYUN.Abp.Notifications.WeChat.WeApp.csproj

@ -14,7 +14,7 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\moudles\common\LINGYUN.Abp.WeChat.Authorization\LINGYUN.Abp.WeChat.Authorization.csproj" />
<ProjectReference Include="..\LINGYUN.Abp.WeChat.Authorization\LINGYUN.Abp.WeChat.Authorization.csproj" />
<ProjectReference Include="..\LINGYUN.Abp.Notifications\LINGYUN.Abp.Notifications.csproj" />
</ItemGroup>

1
aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN.Abp.Notifications.csproj

@ -13,6 +13,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.EventBus" Version="2.9.0" />
<PackageReference Include="Volo.Abp.Json" Version="2.9.0" />
<PackageReference Include="Volo.Abp.BackgroundJobs" Version="2.9.0" />
</ItemGroup>

2
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<AbpNotificationOptions>(options =>
{
services.ExecutePreConfiguredActions(options);
options.DefinitionProviders.AddIfNotContains(definitionProviders);
});
}

1
aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/AbpNotificationOptions.cs

@ -7,7 +7,6 @@ namespace LINGYUN.Abp.Notifications
public ITypeList<INotificationDefinitionProvider> DefinitionProviders { get; }
public ITypeList<INotificationPublishProvider> PublishProviders { get; }
public AbpNotificationOptions()
{
PublishProviders = new TypeList<INotificationPublishProvider>();

11
aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationDispatcher.cs

@ -26,5 +26,16 @@ namespace LINGYUN.Abp.Notifications
/// <returns></returns>
Task DispatchAsync(NotificationName notificationName, NotificationData data, Guid? tenantId = null,
NotificationSeverity notificationSeverity = NotificationSeverity.Info);
/// <summary>
/// 发送通知事件
/// </summary>
/// <param name="notificationName">通知名称</param>
/// <param name="data">数据</param>
/// <param name="tenantId">租户</param>
/// <param name="notificationSeverity">级别</param>
/// <returns></returns>
Task DispatchEventAsync(NotificationName notificationName, NotificationData data, Guid? tenantId = null,
NotificationSeverity notificationSeverity = NotificationSeverity.Info);
}
}

2
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<Guid> userIds);

34
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
/// </summary>
public ILogger<DefaultNotificationDispatcher> Logger { get; set; }
/// <summary>
/// Reference to <see cref="IDistributedEventBus"/>.
/// </summary>
public IDistributedEventBus DistributedEventBus { get; set; }
/// <summary>
/// Reference to <see cref="IBackgroundJobManager"/>.
/// </summary>
private readonly IBackgroundJobManager _backgroundJobManager;
@ -49,6 +54,7 @@ namespace LINGYUN.Abp.Notifications.Internal
_notificationDefinitionManager = notificationDefinitionManager;
_notificationPublishProviderManager = notificationPublishProviderManager;
DistributedEventBus = NullDistributedEventBus.Instance;
Logger = NullLogger<DefaultNotificationDispatcher>.Instance;
}
/// <summary>
@ -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);
}
/// <summary>
/// 发送通知事件
/// </summary>
/// <param name="notificationName"></param>
/// <param name="data"></param>
/// <param name="tenantId"></param>
/// <param name="notificationSeverity"></param>
/// <returns></returns>
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);
}
/// <summary>
/// 发送通知
/// </summary>
/// <param name="notification">通知信息</param>

36
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
};
}
}
}

19
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
};
}
}
}

0
aspnet-core/moudles/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN.Abp.WeChat.Authorization.csproj → aspnet-core/modules/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN.Abp.WeChat.Authorization.csproj

0
aspnet-core/moudles/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/AbpWeChatAuthorizationModule.cs → aspnet-core/modules/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/AbpWeChatAuthorizationModule.cs

0
aspnet-core/moudles/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/AbpWeChatOptions.cs → aspnet-core/modules/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/AbpWeChatOptions.cs

0
aspnet-core/moudles/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/IWeChatTokenProvider.cs → aspnet-core/modules/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/IWeChatTokenProvider.cs

0
aspnet-core/moudles/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/WeChatToken.cs → aspnet-core/modules/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/WeChatToken.cs

0
aspnet-core/moudles/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/WeChatTokenCacheItem.cs → aspnet-core/modules/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/WeChatTokenCacheItem.cs

0
aspnet-core/moudles/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/WeChatTokenProvider.cs → aspnet-core/modules/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/WeChatTokenProvider.cs

0
aspnet-core/moudles/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/WeChatTokenRequest.cs → aspnet-core/modules/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/WeChatTokenRequest.cs

0
aspnet-core/moudles/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/WeChatTokenResponse.cs → aspnet-core/modules/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/WeChatTokenResponse.cs

0
aspnet-core/moudles/common/LINGYUN.Abp.WeChat.Authorization/System/Net/Http/HttpClientWeChatTokenRequestExtensions.cs → aspnet-core/modules/common/LINGYUN.Abp.WeChat.Authorization/System/Net/Http/HttpClientWeChatTokenRequestExtensions.cs

16
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain.Shared/LINGYUN/Abp/MessageService/Notifications/CleanupNotificationJobArgs.cs

@ -1,16 +0,0 @@
using System;
namespace LINGYUN.Abp.MessageService.Notifications
{
public class CleanupNotificationJobArgs
{
/// <summary>
/// 清理大小
/// </summary>
public int Count { get; set; }
/// <summary>
/// 清理租户
/// </summary>
public Guid? TenantId { get; set; }
}
}

2
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;

37
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/BackgroundJobs/NotificationExpritionCleanupJob.cs

@ -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<CleanupNotificationJobArgs>
{
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();
}
}
}
}
}

1
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Mapper/MessageServiceDomainAutoMapperProfile.cs

@ -16,6 +16,7 @@ namespace LINGYUN.Abp.MessageService.Mapper
CreateMap<Notification, NotificationInfo>()
.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) =>

2
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<UserNotification, long>
{
Task<bool> AnyAsync(Guid userId, long notificationId);
Task InsertUserNotificationsAsync(IEnumerable<UserNotification> userNotifications);
Task<UserNotification> GetByIdAsync(Guid userId, long notificationId);

4
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;

22
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<UserNotification>();
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);

3
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<UserNotification>(b =>

6
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<bool> AnyAsync(Guid userId, long notificationId)
{
return await DbSet
.AnyAsync(x => x.NotificationId.Equals(notificationId) && x.UserId.Equals(userId));
}
public async Task InsertUserNotificationsAsync(IEnumerable<UserNotification> userNotifications)
{
await DbSet.AddRangeAsync(userNotifications);

19
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()

38
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<NotificationCleanupExpritionJobArgs>, 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);
}
}
}
}

23
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
{
/// <summary>
/// 清理大小
/// </summary>
public int Count { get; set; }
public NotificationCleanupExpritionJobArgs()
{
}
public NotificationCleanupExpritionJobArgs(int count = 200)
{
Count = count;
}
}
}

136
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
{
/// <summary>
/// 订阅通知发布事件,统一发布消息
/// </summary>
/// <remarks>
/// 作用在于SignalR客户端只会与一台服务器建立连接,
/// 只有启用了SignlR服务端的才能真正将消息发布到客户端
/// </remarks>
public class NotificationEventHandler : IDistributedEventHandler<NotificationEventData>, ITransientDependency
{
/// <summary>
/// Reference to <see cref="ILogger<DefaultNotificationDispatcher>"/>.
/// </summary>
public ILogger<NotificationEventHandler> Logger { get; set; }
/// <summary>
/// Reference to <see cref="IBackgroundJobManager"/>.
/// </summary>
protected IBackgroundJobManager BackgroundJobManager;
/// <summary>
/// Reference to <see cref="INotificationStore"/>.
/// </summary>
protected INotificationStore NotificationStore { 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(
IBackgroundJobManager backgroundJobManager,
INotificationStore notificationStore,
INotificationPublishProviderManager notificationPublishProviderManager)
{
BackgroundJobManager = backgroundJobManager;
NotificationStore = notificationStore;
NotificationPublishProviderManager = notificationPublishProviderManager;
Logger = NullLogger<NotificationEventHandler>.Instance;
}
[UnitOfWork]
public virtual async Task HandleEventAsync(NotificationEventData eventData)
{
var notificationInfo = eventData.ToNotificationInfo();
var providers = Enumerable
.Reverse(NotificationPublishProviderManager.Providers);
await PublishFromProvidersAsync(providers, notificationInfo);
}
/// <summary>
/// 指定提供者发布通知
/// </summary>
/// <param name="providers">提供者列表</param>
/// <param name="notificationInfo">通知信息</param>
/// <returns></returns>
protected async Task PublishFromProvidersAsync(IEnumerable<INotificationPublishProvider> 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);
}
}
/// <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}");
// 发布
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));
}
}
}
}

2
aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN.Abp.MessageService.HttpApi.Host.csproj

@ -43,6 +43,8 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\modules\common\LINGYUN.Abp.Hangfire.MySqlStorage\LINGYUN.Abp.Hangfire.Storage.MySql.csproj" />
<ProjectReference Include="..\..\..\modules\common\LINGYUN.Abp.BackgroundJobs.Hangfire\LINGYUN.Abp.BackgroundJobs.Hangfire.csproj" />
<ProjectReference Include="..\..\..\modules\common\LINGYUN.Abp.EventBus.CAP\LINGYUN.Abp.EventBus.CAP.csproj" />
<ProjectReference Include="..\..\..\modules\common\LINGYUN.Abp.IM.SignalR\LINGYUN.Abp.IM.SignalR.csproj" />
<ProjectReference Include="..\..\..\modules\common\LINGYUN.Abp.Notifications.SignalR\LINGYUN.Abp.Notifications.SignalR.csproj" />

18
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<IBackgroundJobManager>();
// 五分钟执行一次的定时任务
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();
}

508
aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/20200617010925_Add-Notification-Column-CateGory.Designer.cs

@ -0,0 +1,508 @@
// <auto-generated />
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<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<string>("Address")
.HasColumnType("varchar(256) CHARACTER SET utf8mb4")
.HasMaxLength(256);
b.Property<bool>("AllowAnonymous")
.HasColumnType("tinyint(1)");
b.Property<bool>("AllowSendMessage")
.HasColumnType("tinyint(1)");
b.Property<DateTime>("CreationTime")
.HasColumnName("CreationTime")
.HasColumnType("datetime(6)");
b.Property<Guid?>("CreatorId")
.HasColumnName("CreatorId")
.HasColumnType("char(36)");
b.Property<string>("Description")
.HasColumnType("varchar(128) CHARACTER SET utf8mb4")
.HasMaxLength(128);
b.Property<long>("GroupId")
.HasColumnType("bigint");
b.Property<DateTime?>("LastModificationTime")
.HasColumnName("LastModificationTime")
.HasColumnType("datetime(6)");
b.Property<Guid?>("LastModifierId")
.HasColumnName("LastModifierId")
.HasColumnType("char(36)");
b.Property<int>("MaxUserCount")
.HasColumnType("int");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("varchar(20) CHARACTER SET utf8mb4")
.HasMaxLength(20);
b.Property<string>("Notice")
.HasColumnType("varchar(64) CHARACTER SET utf8mb4")
.HasMaxLength(64);
b.Property<string>("Tag")
.HasColumnType("varchar(512) CHARACTER SET utf8mb4")
.HasMaxLength(512);
b.Property<Guid?>("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<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<bool>("AllowAddPeople")
.HasColumnType("tinyint(1)");
b.Property<bool>("AllowDissolveGroup")
.HasColumnType("tinyint(1)");
b.Property<bool>("AllowKickPeople")
.HasColumnType("tinyint(1)");
b.Property<bool>("AllowSendNotice")
.HasColumnType("tinyint(1)");
b.Property<bool>("AllowSilence")
.HasColumnType("tinyint(1)");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)");
b.Property<long>("GroupId")
.HasColumnType("bigint");
b.Property<bool>("IsSuperAdmin")
.HasColumnType("tinyint(1)");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime(6)");
b.Property<Guid?>("LastModifierId")
.HasColumnType("char(36)");
b.Property<Guid?>("TenantId")
.HasColumnName("TenantId")
.HasColumnType("char(36)");
b.Property<Guid>("UserId")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("TenantId", "GroupId");
b.ToTable("AppChatGroupAdmins");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Messages.GroupChatBlack", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)");
b.Property<long>("GroupId")
.HasColumnType("bigint");
b.Property<Guid>("ShieldUserId")
.HasColumnType("char(36)");
b.Property<Guid?>("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<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<string>("Content")
.IsRequired()
.HasColumnType("longtext CHARACTER SET utf8mb4")
.HasMaxLength(1048576);
b.Property<DateTime>("CreationTime")
.HasColumnName("CreationTime")
.HasColumnType("datetime(6)");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)");
b.Property<long>("GroupId")
.HasColumnType("bigint");
b.Property<long>("MessageId")
.HasColumnType("bigint");
b.Property<sbyte>("SendState")
.HasColumnType("tinyint");
b.Property<string>("SendUserName")
.IsRequired()
.HasColumnType("varchar(64) CHARACTER SET utf8mb4")
.HasMaxLength(64);
b.Property<Guid?>("TenantId")
.HasColumnName("TenantId")
.HasColumnType("char(36)");
b.Property<int>("Type")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("TenantId", "GroupId");
b.ToTable("AppGroupMessages");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Messages.UserChatBlack", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)");
b.Property<Guid>("ShieldUserId")
.HasColumnType("char(36)");
b.Property<Guid?>("TenantId")
.HasColumnName("TenantId")
.HasColumnType("char(36)");
b.Property<Guid>("UserId")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("TenantId", "UserId");
b.ToTable("AppUserChatBlacks");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Messages.UserChatGroup", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<DateTime>("CreationTime")
.HasColumnName("CreationTime")
.HasColumnType("datetime(6)");
b.Property<Guid?>("CreatorId")
.HasColumnName("CreatorId")
.HasColumnType("char(36)");
b.Property<long>("GroupId")
.HasColumnType("bigint");
b.Property<Guid?>("TenantId")
.HasColumnName("TenantId")
.HasColumnType("char(36)");
b.Property<Guid>("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<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<bool>("AllowAddFriend")
.HasColumnType("tinyint(1)");
b.Property<bool>("AllowAnonymous")
.HasColumnType("tinyint(1)");
b.Property<bool>("AllowReceiveMessage")
.HasColumnType("tinyint(1)");
b.Property<bool>("AllowSendMessage")
.HasColumnType("tinyint(1)");
b.Property<bool>("RequireAddFriendValition")
.HasColumnType("tinyint(1)");
b.Property<Guid?>("TenantId")
.HasColumnName("TenantId")
.HasColumnType("char(36)");
b.Property<Guid>("UserId")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("TenantId", "UserId");
b.ToTable("AppUserChatSettings");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Messages.UserMessage", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<string>("Content")
.IsRequired()
.HasColumnType("longtext CHARACTER SET utf8mb4")
.HasMaxLength(1048576);
b.Property<DateTime>("CreationTime")
.HasColumnName("CreationTime")
.HasColumnType("datetime(6)");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)");
b.Property<long>("MessageId")
.HasColumnType("bigint");
b.Property<Guid>("ReceiveUserId")
.HasColumnType("char(36)");
b.Property<sbyte>("SendState")
.HasColumnType("tinyint");
b.Property<string>("SendUserName")
.IsRequired()
.HasColumnType("varchar(64) CHARACTER SET utf8mb4")
.HasMaxLength(64);
b.Property<Guid?>("TenantId")
.HasColumnName("TenantId")
.HasColumnType("char(36)");
b.Property<int>("Type")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("TenantId", "ReceiveUserId");
b.ToTable("AppUserMessages");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Messages.UserSpecialFocus", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)");
b.Property<Guid>("FocusUserId")
.HasColumnType("char(36)");
b.Property<Guid?>("TenantId")
.HasColumnName("TenantId")
.HasColumnType("char(36)");
b.Property<Guid>("UserId")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("TenantId", "UserId");
b.ToTable("AppUserSpecialFocuss");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Notifications.Notification", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<DateTime>("CreationTime")
.HasColumnName("CreationTime")
.HasColumnType("datetime(6)");
b.Property<DateTime?>("ExpirationTime")
.HasColumnType("datetime(6)");
b.Property<string>("NotificationCateGory")
.IsRequired()
.HasColumnType("varchar(50) CHARACTER SET utf8mb4")
.HasMaxLength(50);
b.Property<string>("NotificationData")
.IsRequired()
.HasColumnType("longtext CHARACTER SET utf8mb4")
.HasMaxLength(1048576);
b.Property<long>("NotificationId")
.HasColumnType("bigint");
b.Property<string>("NotificationName")
.IsRequired()
.HasColumnType("varchar(100) CHARACTER SET utf8mb4")
.HasMaxLength(100);
b.Property<string>("NotificationTypeName")
.IsRequired()
.HasColumnType("varchar(512) CHARACTER SET utf8mb4")
.HasMaxLength(512);
b.Property<sbyte>("Severity")
.HasColumnType("tinyint");
b.Property<Guid?>("TenantId")
.HasColumnName("TenantId")
.HasColumnType("char(36)");
b.Property<int>("Type")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("TenantId", "NotificationName");
b.ToTable("AppNotifications");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Notifications.UserNotification", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<long>("NotificationId")
.HasColumnType("bigint");
b.Property<int>("ReadStatus")
.HasColumnType("int");
b.Property<Guid?>("TenantId")
.HasColumnName("TenantId")
.HasColumnType("char(36)");
b.Property<Guid>("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<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<DateTime>("CreationTime")
.HasColumnName("CreationTime")
.HasColumnType("datetime(6)");
b.Property<string>("NotificationName")
.IsRequired()
.HasColumnType("varchar(100) CHARACTER SET utf8mb4")
.HasMaxLength(100);
b.Property<Guid?>("TenantId")
.HasColumnName("TenantId")
.HasColumnType("char(36)");
b.Property<Guid>("UserId")
.HasColumnType("char(36)");
b.Property<string>("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
}
}
}

42
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<string>(
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");
}
}
}

7
aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/MessageServiceHostMigrationsDbContextModelSnapshot.cs

@ -396,6 +396,11 @@ namespace LINGYUN.Abp.MessageService.Migrations
b.Property<DateTime?>("ExpirationTime")
.HasColumnType("datetime(6)");
b.Property<string>("NotificationCateGory")
.IsRequired()
.HasColumnType("varchar(50) CHARACTER SET utf8mb4")
.HasMaxLength(50);
b.Property<string>("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");
});

1
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
Loading…
Cancel
Save