From 2a7acb7b6c2d78a51a9ac18ce2f683e1e8a63fa2 Mon Sep 17 00:00:00 2001 From: cKey <35512826+colinin@users.noreply.github.com> Date: Tue, 2 Jun 2020 11:59:42 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84=E9=80=9A=E7=9F=A5=E7=BB=84?= =?UTF-8?q?=E4=BB=B6;=E5=AE=8C=E5=96=84=E7=94=A8=E6=88=B7=E6=B3=A8?= =?UTF-8?q?=E5=86=8C=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/NotificationController.cs | 25 ++-- ...YUN.Abp.MessageService.HttpApi.Host.csproj | 1 + .../AbpMessageServiceHttpApiHostModule.cs | 24 ---- .../Utils/SnowflakeIdGenerator.cs | 16 +++ .../LINGYUN/Abp/Account/AccountAppService.cs | 12 +- .../SignalR/Hubs/NotificationsHub.cs | 14 +- .../LINGYUN.Abp.Notifications.csproj | 2 +- .../Abp/Notifications/INotificationStore.cs | 2 + .../Internal/DefaultNotificationDispatcher.cs | 4 +- .../Abp/Notifications/NotificationInfo.cs | 4 +- .../Newtonsoft/Json/HexLongConverter.cs | 30 +++++ .../AbpMessageServiceDomainModule.cs | 13 +- .../IUserNotificationRepository.cs | 2 + .../Notifications/NotificationStore.cs | 17 ++- .../EfCoreUserNotificationRepository.cs | 5 + vueJs/src/api/abpconfiguration.ts | 9 ++ vueJs/src/components/Notification/index.vue | 124 +++++++++++++----- vueJs/src/lang/zh.ts | 3 + vueJs/src/store/modules/user.ts | 2 +- vueJs/src/views/admin/tenants/index.vue | 3 +- vueJs/src/views/admin/users/index.vue | 3 - vueJs/src/views/login/index.vue | 13 +- vueJs/src/views/register/index.vue | 80 +++++------ 23 files changed, 270 insertions(+), 138 deletions(-) create mode 100644 aspnet-core/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN/Abp/MessageService/Utils/SnowflakeIdGenerator.cs create mode 100644 aspnet-core/modules/common/LINGYUN.Abp.Notifications/Newtonsoft/Json/HexLongConverter.cs diff --git a/aspnet-core/LINGYUN.Abp.MessageService.HttpApi.Host/Controllers/NotificationController.cs b/aspnet-core/LINGYUN.Abp.MessageService.HttpApi.Host/Controllers/NotificationController.cs index d20c686f3..fc87e40a4 100644 --- a/aspnet-core/LINGYUN.Abp.MessageService.HttpApi.Host/Controllers/NotificationController.cs +++ b/aspnet-core/LINGYUN.Abp.MessageService.HttpApi.Host/Controllers/NotificationController.cs @@ -10,11 +10,11 @@ namespace LINGYUN.Abp.MessageService.Controllers [Route("api/app/notifications")] public class NotificationController : AbpController { - private readonly INotificationPublisher _notificationPublisher; + private readonly INotificationDispatcher _notificationDispatcher; public NotificationController( - INotificationPublisher notificationPublisher) + INotificationDispatcher notificationDispatcher) { - _notificationPublisher = notificationPublisher; + _notificationDispatcher = notificationDispatcher; } [HttpPost] @@ -24,17 +24,19 @@ namespace LINGYUN.Abp.MessageService.Controllers var notificationInfo = new NotificationInfo { TenantId = null, - NotificationSeverity = NotificationSeverity.Success, + NotificationSeverity = notification.Severity, NotificationType = NotificationType.Application, - Id = 164589598456654164, - Name = "TestApplicationNotofication" + Id = new Random().Next(int.MinValue, int.MaxValue), + Name = "TestApplicationNotofication", + CreationTime = Clock.Now }; - notificationInfo.Data.Properties["Title"] = notification.Title; - notificationInfo.Data.Properties["Message"] = notification.Message; - notificationInfo.Data.Properties["DateTime"] = notification.DateTime; - notificationInfo.Data.Properties["Severity"] = notification.Severity; + notificationInfo.Data.Properties["id"] = notificationInfo.Id.ToString(); + notificationInfo.Data.Properties["title"] = notification.Title; + notificationInfo.Data.Properties["message"] = notification.Message; + notificationInfo.Data.Properties["datetime"] = Clock.Now; + notificationInfo.Data.Properties["severity"] = notification.Severity; - await _notificationPublisher.PublishAsync(notificationInfo, new List() { notification.UserId }); + await _notificationDispatcher.DispatcheAsync(notificationInfo); } } @@ -42,7 +44,6 @@ namespace LINGYUN.Abp.MessageService.Controllers { public Guid UserId { get; set; } public string Title { get; set; } - public DateTime DateTime { get; set; } = DateTime.Now; public string Message { get; set; } public NotificationSeverity Severity { get; set; } = NotificationSeverity.Success; } diff --git a/aspnet-core/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN.Abp.MessageService.HttpApi.Host.csproj b/aspnet-core/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN.Abp.MessageService.HttpApi.Host.csproj index 6068bef78..bba35b34b 100644 --- a/aspnet-core/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN.Abp.MessageService.HttpApi.Host.csproj +++ b/aspnet-core/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN.Abp.MessageService.HttpApi.Host.csproj @@ -30,6 +30,7 @@ + diff --git a/aspnet-core/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN/Abp/MessageService/AbpMessageServiceHttpApiHostModule.cs b/aspnet-core/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN/Abp/MessageService/AbpMessageServiceHttpApiHostModule.cs index 471488ada..917a61050 100644 --- a/aspnet-core/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN/Abp/MessageService/AbpMessageServiceHttpApiHostModule.cs +++ b/aspnet-core/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN/Abp/MessageService/AbpMessageServiceHttpApiHostModule.cs @@ -87,30 +87,6 @@ namespace LINGYUN.Abp.MessageService options.Languages.Add(new LanguageInfo("zh-Hans", "zh-Hans", "简体中文")); }); - Configure(options => - { - // 处理signalr某些请求由querystring发送请求令牌 - // https://docs.microsoft.com/zh-cn/aspnet/core/signalr/authn-and-authz?view=aspnetcore-3.1 - options.Authority = configuration["AuthServer:Authority"]; - options.Events = new JwtBearerEvents - { - OnMessageReceived = context => - { - var accessToken = context.Request.Query["access_token"]; - - // If the request is for our hub... - var path = context.HttpContext.Request.Path; - if (!string.IsNullOrEmpty(accessToken) && - (path.StartsWithSegments("/signalr-hubs/notifications"))) - { - // Read the token out of the query string - context.Token = accessToken; - } - return Task.CompletedTask; - } - }; - }); - context.Services.AddAuthentication("Bearer") .AddIdentityServerAuthentication(options => { diff --git a/aspnet-core/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN/Abp/MessageService/Utils/SnowflakeIdGenerator.cs b/aspnet-core/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN/Abp/MessageService/Utils/SnowflakeIdGenerator.cs new file mode 100644 index 000000000..0b5d5b0c8 --- /dev/null +++ b/aspnet-core/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN/Abp/MessageService/Utils/SnowflakeIdGenerator.cs @@ -0,0 +1,16 @@ +using DotNetCore.CAP.Internal; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.DependencyInjection; + +namespace LINGYUN.Abp.MessageService.Utils +{ + [Dependency(ServiceLifetime.Singleton, TryRegister = true)] + [ExposeServices(typeof(ISnowflakeIdGenerator))] + public class SnowflakeIdGenerator : ISnowflakeIdGenerator + { + public long Create() + { + return SnowflakeId.Default().NextId(); + } + } +} diff --git a/aspnet-core/modules/account/LINGYUN.Abp.Account.Application/LINGYUN/Abp/Account/AccountAppService.cs b/aspnet-core/modules/account/LINGYUN.Abp.Account.Application/LINGYUN/Abp/Account/AccountAppService.cs index c2e5e7982..0ec05b642 100644 --- a/aspnet-core/modules/account/LINGYUN.Abp.Account.Application/LINGYUN/Abp/Account/AccountAppService.cs +++ b/aspnet-core/modules/account/LINGYUN.Abp.Account.Application/LINGYUN/Abp/Account/AccountAppService.cs @@ -59,13 +59,15 @@ namespace LINGYUN.Abp.Account var userEmail = input.EmailAddress ?? input.PhoneNumber + "@abp.io"; var userName = input.UserName ?? input.PhoneNumber; - var user = new IdentityUser(GuidGenerator.Create(), userName, userEmail, CurrentTenant.Id); - user.Name = input.Name ?? input.PhoneNumber; + var user = new IdentityUser(GuidGenerator.Create(), userName, userEmail, CurrentTenant.Id) + { + Name = input.Name ?? input.PhoneNumber + }; (await UserManager.CreateAsync(user, input.Password)).CheckErrors(); - await UserManager.ChangePhoneNumberAsync(user, input.PhoneNumber, input.VerifyCode); - await UserManager.SetEmailAsync(user, userEmail); - await UserManager.AddDefaultRolesAsync(user); + (await UserManager.SetPhoneNumberAsync(user, input.PhoneNumber)).CheckErrors(); + (await UserManager.SetEmailAsync(user, userEmail)).CheckErrors(); + (await UserManager.AddDefaultRolesAsync(user)).CheckErrors(); await Cache.RemoveAsync(phoneVerifyCacheKey); diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/Hubs/NotificationsHub.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/Hubs/NotificationsHub.cs index 9cfd63d85..5cd3ab3f1 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/Hubs/NotificationsHub.cs +++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/Hubs/NotificationsHub.cs @@ -2,7 +2,6 @@ using Microsoft.AspNetCore.SignalR; using System.Threading.Tasks; using Volo.Abp.Application.Dtos; -using Volo.Abp.AspNetCore.SignalR; using Volo.Abp.Users; namespace LINGYUN.Abp.Notifications.SignalR.Hubs @@ -14,11 +13,20 @@ namespace LINGYUN.Abp.Notifications.SignalR.Hubs protected INotificationStore NotificationStore => LazyGetRequiredService(ref _notificationStore); [HubMethodName("GetNotification")] - public virtual async Task> GetNotificationAsync(NotificationReadState readState = NotificationReadState.UnRead) + public virtual async Task> GetNotificationAsync( + NotificationReadState readState = NotificationReadState.UnRead, int maxResultCount = 10) { - var userNotifications = await NotificationStore.GetUserNotificationsAsync(CurrentTenant.Id, CurrentUser.GetId(), readState); + var userNotifications = await NotificationStore.GetUserNotificationsAsync(CurrentTenant.Id, CurrentUser.GetId(), readState, maxResultCount); return new ListResultDto(userNotifications); } + + [HubMethodName("ChangeState")] + public virtual async Task ChangeStateAsync(long id, NotificationReadState readState = NotificationReadState.Read) + { + await NotificationStore.ChangeUserNotificationReadStateAsync(CurrentTenant.Id, CurrentUser.GetId(), id, readState); + } + + } } 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 268dae169..60d5efeb9 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 @@ -6,7 +6,7 @@ - + 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 1ca149a17..e7d0074e5 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 @@ -24,6 +24,8 @@ namespace LINGYUN.Abp.Notifications Task InsertUserNotificationAsync(NotificationInfo notification, Guid userId); + Task InsertUserNotificationsAsync(NotificationInfo notification, IEnumerable userIds); + Task DeleteUserNotificationAsync(Guid? tenantId, Guid userId, long notificationId); Task GetNotificationOrNullAsync(Guid? tenantId, long notificationId); 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 ff03a6478..1e470ee39 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 @@ -23,9 +23,9 @@ namespace LINGYUN.Abp.Notifications.Internal // 获取用户订阅列表 var userSubscriptions = await _notificationStore.GetSubscriptionsAsync(notification.TenantId, notification.Name); - // 持久化用户订阅通知 + // 持久化用户通知 var subscriptionUserIds = userSubscriptions.Select(us => us.UserId); - await _notificationStore.InsertUserSubscriptionAsync(notification.TenantId, subscriptionUserIds, notification.Name); + await _notificationStore.InsertUserNotificationsAsync(notification, subscriptionUserIds); // 发布用户通知 await _notificationPublisher.PublishAsync(notification, subscriptionUserIds); 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 e1bdf131b..62c39d11b 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,4 +1,5 @@ -using System; +using Newtonsoft.Json; +using System; namespace LINGYUN.Abp.Notifications { @@ -6,6 +7,7 @@ namespace LINGYUN.Abp.Notifications { public Guid? TenantId { get; set; } public string Name { get; set; } + [JsonConverter(typeof(HexLongConverter))] public long Id { get; set; } public NotificationData Data { get; set; } public DateTime CreationTime { get; set; } diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/Newtonsoft/Json/HexLongConverter.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/Newtonsoft/Json/HexLongConverter.cs new file mode 100644 index 000000000..e28c43cda --- /dev/null +++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/Newtonsoft/Json/HexLongConverter.cs @@ -0,0 +1,30 @@ +using System; + +namespace Newtonsoft.Json +{ + public class HexLongConverter : JsonConverter + { + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + long v = value is ulong ? (long)(ulong)value : (long)value; + writer.WriteValue(v.ToString()); + } + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + string value = reader.Value as string; + long lValue = long.Parse(value); + return typeof(ulong) == objectType ? (object)(ulong)lValue : lValue; + } + public override bool CanConvert(Type objectType) + { + switch (objectType.FullName) + { + case "System.Int64": + case "System.UInt64": + return true; + default: + return false; + } + } + } +} diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/AbpMessageServiceDomainModule.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/AbpMessageServiceDomainModule.cs index 78da839db..b48c045fd 100644 --- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/AbpMessageServiceDomainModule.cs +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/AbpMessageServiceDomainModule.cs @@ -1,9 +1,18 @@ -using Volo.Abp.Modularity; +using LINGYUN.Abp.MessageService.Mapper; +using Volo.Abp.AutoMapper; +using Volo.Abp.Modularity; namespace LINGYUN.Abp.MessageService { + [DependsOn(typeof(AbpAutoMapperModule))] public class AbpMessageServiceDomainModule : AbpModule { - + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.AddProfile(validate: true); + }); + } } } 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 fe5995696..73f7bf28a 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 InsertUserNotificationsAsync(IEnumerable userNotifications); + Task GetByIdAsync(Guid userId, long notificationId); Task> GetNotificationsAsync(Guid userId, NotificationReadState readState = NotificationReadState.UnRead, int maxResultCount = 10); 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 d36d75ff0..d0130281e 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 @@ -155,7 +155,11 @@ namespace LINGYUN.Abp.MessageService.Notifications { using (CurrentTenant.Change(notification.TenantId)) { - var notify = new Notification(SnowflakeIdGenerator.Create(), notification.Name, + var notifyId = SnowflakeIdGenerator.Create(); + // 保存主键,防止前端js long类型溢出 + notification.Data["id"] = notifyId.ToString(); + + var notify = new Notification(notifyId, notification.Name, notification.Data.GetType().AssemblyQualifiedName, JsonSerializer.Serialize(notification.Data), notification.NotificationSeverity) { @@ -235,5 +239,16 @@ namespace LINGYUN.Abp.MessageService.Notifications using (CurrentTenant.Change(tenantId)) return await UserSubscribeRepository.UserSubscribeExistsAysnc(notificationName, userId); } + + public async Task InsertUserNotificationsAsync(NotificationInfo notification, IEnumerable userIds) + { + var userNofitications = new List(); + foreach(var userId in userIds) + { + var userNofitication = new UserNotification(notification.Id, userId); + userNofitications.Add(userNofitication); + } + await UserNotificationRepository.InsertUserNotificationsAsync(userNofitications); + } } } 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 6b3e24fd7..96d4f55e7 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,11 @@ namespace LINGYUN.Abp.MessageService.Notifications { } + public async Task InsertUserNotificationsAsync(IEnumerable userNotifications) + { + await DbSet.AddRangeAsync(userNotifications); + } + public async Task ChangeUserNotificationReadStateAsync(Guid userId, long notificationId, NotificationReadState readState) { var userNofitication = await GetByIdAsync(userId, notificationId); diff --git a/vueJs/src/api/abpconfiguration.ts b/vueJs/src/api/abpconfiguration.ts index 41ecea8ac..1ab7735dd 100644 --- a/vueJs/src/api/abpconfiguration.ts +++ b/vueJs/src/api/abpconfiguration.ts @@ -90,6 +90,8 @@ export interface IAbpConfiguration { multiTenancy: MultiTenancy objectExtensions: any setting: Setting + + getSetting(key: string): string | undefined } export class AbpConfiguration implements IAbpConfiguration { @@ -111,4 +113,11 @@ export class AbpConfiguration implements IAbpConfiguration { this.multiTenancy = new MultiTenancy() this.currentTenant = new CurrentTenant() } + + public getSetting(key: string) { + if (this.setting.values && this.setting.values[key]) { + return this.setting.values[key] + } + return undefined + } } diff --git a/vueJs/src/components/Notification/index.vue b/vueJs/src/components/Notification/index.vue index ba39f0d57..7c7d78f14 100644 --- a/vueJs/src/components/Notification/index.vue +++ b/vueJs/src/components/Notification/index.vue @@ -1,11 +1,15 @@