[ABP實戰開源項目]---ABP實時服務-通知系統.發布模式


簡介

在ABP中,提供了通知服務。它是一個基於實時通知的基礎設施。分為訂閱模式和發布模式。
本次會在項目中使用發布模式來演示一個用戶注冊后,收到的歡迎信息。

發布模式

首先我們在領域層建立“INotificationManager”接口和“NotificationManager”實現類,如下:

 /// <summary>
    /// 通知管理領域服務
    /// </summary>
    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方法。

Paste_Image.png

在源代碼的定義中,我們看到了他有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<ActionResult> TestNotification( string message = "" , NotificationSeverity severity = NotificationSeverity.Info)
        {
            if (message.IsNullOrEmpty())
            {
                message = "這是一條測試消息 " + Clock.Now;
            }
            await _notificationManager.SendMessageAsync(AbpSession.ToUserIdentifier(), message, severity: severity);
          

            return Content("發送提示信息: " + message);
        }

Paste_Image.png
然后我們可以在TenantNotifications和UserNotifications可以看到發布的信息和關聯關系。
登陸到管理中心可以看到:

Paste_Image.png

當前的用戶信息,通知。

   vm.unReadUserNotificationCount = 0;
            vm.userNotifications = [];
            //格式化消息
            var formattedMessage = function (item) {

                var message = {
                    id: item.id,
                    text: abp.notifications.getFormattedMessageFromUserNotification(item),
                    time: item.notification.creationTime,
                    image: 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'是一個領域事件的簡單實現,大家有興趣可以繼續研究。以上整個功能已經發布到GitHub上,歡迎大家下載使用。

THE END

本開源項目的地址為:https://github.com/ltm0203/YoYoCms
預覽網址為:http://www.yoyocms.com/
涉及的技術選型:https://github.com/ltm0203/YoYoCms/tree/dev/doc


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM