X-Admin&ABP框架開發-消息通知

  業務型網站使用過程當中,消息通知是一個不可或缺的功能,採用站內通知、短信通知、郵件通知、微信通知等等各類方式都有,ABP框架對這部分工做已經封裝的很好了,站在巨人的肩膀上,一覽全貌,帶來的就是心情舒暢。java

   ABP官網地址:https://aspnetboilerplate.com/git

 

1、明確概念及設計

  一次完整的消息發送/接收過程當中,會存在幾個必要的點,也正如同現實生活中的場景,有人發送,有人接收,發送的消息自己也有類型。後端

  

一、消息類型定義瀏覽器

   在ABP中已經提供了消息類型定義的相關類,可是須要咱們去實現,在領域層新建一個Notifications文件夾並添加一個定義經常使用消息類型名稱的靜態類如AppNotificationNames(名稱可隨意),在其中開始定義消息類型名稱。微信

/// <summary>
/// 設置應用程序中經常使用通知惟一的名稱常量
/// </summary>
public static class AppNotificationNames
{
    #region 新的任務
    public const string NewTask = "App.NewTask";
    #endregion

    #region 簡單消息
    public const string SimpleMessage = "App.SimpleMessage";
    #endregion
}

   其次,開始消息類型定義,新建一個NotificationProvider的類,完成消息類型定義,管理消息類型時,能夠針對消息設置權限,這樣方便不一樣的角色擁有不一樣的消息通知。app

/// <summary>
/// 消息類型定義
/// </summary>
public class AppNotificationProvider : NotificationProvider
{
    /// <summary>
    /// 設置消息類型
    /// </summary>
    /// <param name="context"></param>
    public override void SetNotifications(INotificationDefinitionContext context)
    {
        #region 任務提醒
        context.Manager.Add(
            new NotificationDefinition(
                AppNotificationNames.NewTask,
                displayName: L("NewTask"),
                permissionDependency: new SimplePermissionDependency(PermissionNames.Pages_TaskManage)
            )
        );
        #endregion
    }

    private static ILocalizableString L(string name)
    {
        return new LocalizableString(name, SurroundConsts.LocalizationSourceName);
    }
}

   最後在領域層的Module.PreInitialize()中完成加入。框架

//通知定義
Configuration.Notifications.Providers.Add<AppNotificationProvider>();

 

二、消息訂閱方式async

  對於消息訂閱環節,是存在兩種情形的,第一種,發送方發出的消息,能夠指定全部訂閱了的人員接收,好比,只有擁有任務管理權限的人才會接收到新的任務下發的通知;第二種就是指定到具體人員接收,好比文件上傳完畢的消息通知是通知到負責文件上傳的人。ide

   

   消息訂閱的管理,在ABP框架中已經封裝好了,咱們能夠經過構造函數注入直接使用,經過獲取系統內的提早定義的全部消息類型,咱們能夠在界面上完成訂閱工做,爲當前用戶訂閱在他角色權限內的消息通知及無權限限制的消息通知等。函數

private readonly INotificationDefinitionManager _notificationDefinitionManager;
private readonly INotificationSubscriptionManager _notificationSubscriptionManager;

public NotificationAppService(
    INotificationDefinitionManager notificationDefinitionManager,
    INotificationSubscriptionManager notificationSubscriptionManager)
{
    _notificationDefinitionManager = notificationDefinitionManager;
    _notificationSubscriptionManager = notificationSubscriptionManager;
}

 

三、消息發佈方式

  

  消息發佈時,能夠是嵌入在其它操做中,好比制定完成一個新的任務後,發送消息給相關人員,或是在文件上傳完畢後,發送給文件上傳人員,也能夠是定時任務中,指定時間點發送消息,對於這部分來說,在領域層創建一個消息通知的類,來負責處理消息通知,而具體實現消息通知的過程ABP框架中已經實現了,如同消息訂閱同樣,只須要在構造函數中注入便可,其次定義具體的消息發送方法,使得具體操做結束後調用具體的消息發送來發送消息。

/// <summary>
/// 消息通知發佈實例
/// </summary>
public class AppNotifier : DomainService, IAppNotifier
{
    #region 初始化
    private readonly INotificationPublisher _notificationPublisher;

    public AppNotifier(INotificationPublisher notificationPublisher)
    {
        _notificationPublisher = notificationPublisher;
    }
    #endregion

    #region 消息發送
    public async Task SendMessageAsync(UserIdentifier user, string message, NotificationSeverity severity = NotificationSeverity.Info)
    {
        await _notificationPublisher.PublishAsync(
            AppNotificationNames.SimpleMessage,
            new MessageNotificationData(message),
            severity: severity,
            userIds: new[] { user }
        );
    }
    #endregion

    #region 任務提醒
    public async Task NewTaskAsync(string message, NotificationSeverity severity = NotificationSeverity.Info)
    {
        await PublishMessage(AppNotificationNames.NewTask, message);
    }
    #endregion

    #region 輔助方法
    private async Task PublishMessage(string appNotificationName, string message)
    {
        await _notificationPublisher.PublishAsync(appNotificationName, new MessageNotificationData(message));
    }
    #endregion
}

 

2、完成用戶訂閱消息

   在MVC層,在用戶控制器中完成對消息通知設置,消息自己是獨立的,只應有了用戶才活躍起來,所以把消息的設定掛鉤在用戶身上,應該算是合理的,並同時完成頁面的設計。

/// <summary>
/// 通知設置
/// </summary>
/// <returns></returns>
public async Task<ActionResult> NotificationSetting()
{
    var notificationSettings = await _notificationAppService.GetNotificationSettings();
    return View(notificationSettings);
}

/// <summary>
/// 更新通知訂閱
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task<JsonResult> UpdateNotificationSetting([FromBody]UpdateNotificationSettingsInput input)
{
    await _notificationAppService.UpdateNotificationSettings(input);
    return Json(new ResponseParamViewModel("通知設置已更新"));
}

   頁面設計只須要對提早在領域層中定義好的消息類型展現出來便可,用戶自主勾選哪些想要接收的消息提示。

  

 

3、發佈消息通知用戶

  在指定操做完畢,能夠調用消息服務來推送消息到目標接收人員,此處,更改了原先數據字典建立處的代碼,當建立數據字典成功後,給與一個消息提示來模擬發佈消息通知用戶的過程。

var existedDataDictionary = await _dataDictionaryRepository.GetAll().Where(d => d.TypeName == input.DataDictionary.TypeName).FirstOrDefaultAsync();

if (existedDataDictionary != null)
{
    throw new UserFriendlyException(L("該字典類型已存在,沒法添加"));
}

var dataDictionary = ObjectMapper.Map<DataDictionary>(input.DataDictionary);
await _dataDictionaryRepository.InsertAsync(dataDictionary);

//模擬測試消息通知
await _appNotifier.NewTaskAsync("字典類型已完成添加,能夠開始使用了");

   該消息觸發的前提是,須要訂閱該消息,否則有人發,無人收,老是很難爲情。所以提早在通知設置中開啓類型爲「新的任務」的開關。

  

  對於消息發送到了瀏覽器中呈現,這個過程採用了SignalR,ABP框架也完成了先後端的消息通知,所以能夠直接使用便可。

 

  至此,站內消息通知的設計完畢,對於業務需求中可能面對的更爲豐富的功能就得花更多時間來完成了。 

  代碼地址:https://gitee.com/530521314/Partner.Surround.git

 

2019-07-27,望技術有成後能回來看見本身的腳步
相關文章
相關標籤/搜索