在ABP中,提供了通知服务。它是一个基于实时通知的基础设施。分为订阅模式和发布模式。

本次会在项目中使用发布模式来演示一个用户注册后,收到的欢迎信息。

发布模式

首先我们在领域层建立“INotificationManager”接口和“NotificationManager”实现类,如下:

 ///     /// 通知管理领域服务    ///     public interface INotificationManager    {        Task WelcomeToCmsAsync(User user);    }
   public class NotificationManager : CmsDomainServiceBase, INotificationManager    {        private readonly INotificationPublisher _notificationPublisher;        public NotificationManager(INotificationPublisher notificationPublisher)        {            _notificationPublisher = notificationPublisher;        }        public async Task WelcomeToCmsAsync(User user)        {              await _notificationPublisher.PublishAsync(                CmsConsts.NotificationConstNames.WelcomeToCms,                new MessageNotificationData(L("WelcomeToCms")),severity:NotificationSeverity.Success,userIds:new []{user.ToUserIdentifier()}        }           }

以上就是一个简单的欢迎信息。

以上我们来分析下,调用的"INotificationManager"中的PublishAsync方法。

在源代码的定义中,我们看到了他有8个参数,我们来说说他具体去干嘛了,首先在ABP源代码中调用了这个方法之后,他会到实体NotificationInfo和UserNotification两个实体中进行处理,源代码中的结构很清晰。关联关系很明确是一个一对多的关系。

这个也就是我们在调用PublishAsync方法的时候需要我们键入一个键名,他是全局唯一的,在ABP的代码中的限制也是说明了,禁止使用空格和空字符串。

实时通知

我们刚刚说到了在PublishAsync中,涉及到了UserNotification实体,他的作用是通知用户消息,具体的代码实现中涉及到了后台作业和实时通知SignalR,而我们在客户端获取信息的时候,ABP是触发了一个全局事件。

···
abp.event.on('abp.notifications.received', function (userNotification) {
console.log(userNotification);
});
···
此处涉及的知识点为领域事件中的事件总线。
打印userNotification的Json格式如下:

{    id: "9c0aaf34-c620-4d05-89df-1f4ae11f3686",    notification: {    creationTime: "2017-05-05T01:27:25.7639034Z"    data: {    message: "This is a test notification, created at 2017/5/5 1:27:25"     type: "Abp.Notifications.MessageNotificationData" }    entityId: null    entityType: null    entityTypeName: null    id: "724d670e-2cfa-4656-a9b6-ff76ceba5ce3"    notificationName: "App.SimpleMessage"    severity: 0    tenantId: 1   }    state: 0    tenantId: 1    userId: 2}

在这个对象中:

  • userId:当前用户Id。通常你不需要知道这个,因为你知道那个是当前用户。

  • state:枚举类型 UserNotificationState 的值。 0:Unread,1:Read。

  • notification:通知详细信息:

  • notificationName: 通知的唯一名字(发布通知时使用相同的值)。

  • data:通知数据。在上面例子中,我们使用了 LocalizableMessageNotificationData (在之前的例子中我们使用它来发布的)。

  • message: 本地化信息。在UI端,我们可以使用 sourceName 和 name 来本地化信息。

  • type:通知数据类型。类型的全名称,包含名称空间。当处理这个通知数据的时候,我们可以检查这个类型。

  • properties:自定义属的基于字典类型的属性。

  • entityType,entityTypeName 和 entityId:实体信息,如果这是一个与实体相关的通知。

  • severity:枚举类型 NotificationSeverity 的值。0: Info, 1: Success, 2: Warn, 3: Error, 4: Fatal。

  • creationTime:表示通知被创建的时间。

  • id:通知的id。

  • id:用户通知id。

以上就是消息通知功能的一个介绍,我们来实现这么个功能吧。

YoYoCms中消息通知的应用

我们继续在NotificationManager中添加方法SendMessageAsync

        public async Task SendMessageAsync(UserIdentifier user, string messager, NotificationSeverity severity = NotificationSeverity.Info)        {            await _notificationPublisher.PublishAsync(                CmsConsts.NotificationConstNames.SendMessageAsync,                new MessageNotificationData(messager),severity:severity,userIds:new []{user});        }

然后在Account控制器中进行调用:

        [AbpMvcAuthorize]        public async Task
 TestNotification( string message = "" , NotificationSeverity severity = NotificationSeverity.Info)        {            if (message.IsNullOrEmpty())            {                message = "这是一条测试消息 " + Clock.Now;            }            await _notificationManager.SendMessageAsync(AbpSession.ToUserIdentifier(), message, severity: severity);                      return Content("发送提示信息: " + message);        }

然后我们可以在TenantNotifications和UserNotifications可以看到发布的信息和关联关系。
登陆到管理中心可以看到:

当前的用户信息,通知。

   vm.unReadUserNotificationCount = 0;            vm.userNotifications = [];            //格式化消息            var formattedMessage = function (item) {                var message = {                    id: item.id,                    text: abp.notifications.getFormattedMessageFromUserNotification(item),                    time: item.notification.creationTime,                    p_w_picpath: getNotificationImgBySeverity(item.notification.severity),                    state: abp.notifications.getUserNotificationStateAsString(item.state),                }                return message;            }            //获取图片路径            function getNotificationImgBySeverity(severity) {                switch (severity) {                    case abp.notifications.severity.SUCCESS:                        return '/App/assets/yoyocms/notification/1.png';                    case abp.notifications.severity.WARN:                        return '/App/assets/yoyocms/notification/2.png';                    case abp.notifications.severity.ERROR:                        return '/App/assets/yoyocms/notification/3.png';                    case abp.notifications.severity.FATAL:                        return '/App/assets/yoyocms/notification/4.png';                    case abp.notifications.severity.INFO:                    default:                          return '/App/assets/yoyocms/notification/0.png';                }            }                        //获取所有的消息信息            vm.getUserNotificationsAsync= function() {                notificationService.getPagedUserNotificationsAsync({                    maxResultCount: 5                }).then(function(result) {                    vm.unReadUserNotificationCount = result.data.unreadCount;                    vm.userNotifications = [];                    $.each(result.data.items,                        function (index, item) {                            vm.userNotifications.push(formattedMessage(item));                        });                    console.log(vm.userNotifications);                });            }        //标记所有为已读            vm.makeAllAsRead= function() {                notificationService.makeAllUserNotificationsAsRead().then(function() {                    vm.getUserNotificationsAsync();                });            }            //设置消息为已读            vm.makeNotificationAsRead = function (userNotification) {                notificationService.makeNotificationAsRead({ id: userNotification.id }).                    then(function () {                        for (var i = 0; i < vm.userNotifications.length; i++) {                            if (vm.userNotifications[i].id == userNotification.id) {                                vm.userNotifications[i].state = 'READ';                            }                        }                        vm.unReadUserNotificationCount -= 1;                });            }            //初始化方法            function init() {                vm.getUserNotificationsAsync();                          }            init();            //测试为领域事件的一个例子            abp.event.on('abp.notifications.received', function (userNotification) {                abp.notifications.showUiNotifyForUserNotification(userNotification);                vm.getUserNotificationsAsync();            });        }

其中有'abp.notifications.received'是一个领域事件的简单实现,大家有兴趣可以继续研究。