44 changed files with 659 additions and 191 deletions
@ -0,0 +1,3 @@ |
|||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
|||
<ConfigureAwait ContinueOnCapturedContext="false" /> |
|||
</Weavers> |
|||
@ -0,0 +1,19 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\..\configureawait.props" /> |
|||
<Import Project="..\..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>netstandard2.0</TargetFramework> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Volo.Abp.TextTemplating.Core" Version="$(VoloAbpPackageVersion)" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\LINGYUN.Abp.Notifications\LINGYUN.Abp.Notifications.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,12 @@ |
|||
using Volo.Abp.Modularity; |
|||
using Volo.Abp.TextTemplating; |
|||
|
|||
namespace LINGYUN.Abp.Notifications.TextTemplating; |
|||
|
|||
[DependsOn( |
|||
typeof(AbpNotificationModule), |
|||
typeof(AbpTextTemplatingCoreModule))] |
|||
public class AbpNotificationsTextTemplatingModule : AbpModule |
|||
{ |
|||
|
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.TextTemplating; |
|||
|
|||
namespace LINGYUN.Abp.Notifications.TextTemplating; |
|||
|
|||
public class NotificationTemplateContentContributor : ITemplateContentContributor, ITransientDependency |
|||
{ |
|||
public async virtual Task<string> GetOrNullAsync(TemplateContentContributorContext context) |
|||
{ |
|||
var store = context.ServiceProvider.GetRequiredService<INotificationTemplateStore>(); |
|||
|
|||
return await store.GetOrNullAsync(context.TemplateDefinition.Name, context.Culture); |
|||
} |
|||
} |
|||
@ -0,0 +1,66 @@ |
|||
using JetBrains.Annotations; |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp; |
|||
|
|||
namespace LINGYUN.Abp.Notifications; |
|||
public static class INotificationSenderExtensions |
|||
{ |
|||
/// <summary>
|
|||
/// 发送通知
|
|||
/// </summary>
|
|||
/// <param name="sender">发送接口</param>
|
|||
/// <param name="name">名称</param>
|
|||
/// <param name="data">数据</param>
|
|||
/// <param name="user">用户,为空标识发给所有订阅用户</param>
|
|||
/// <param name="tenantId">租户</param>
|
|||
/// <param name="severity">严重级别</param>
|
|||
/// <returns>通知标识</returns>
|
|||
public async static Task<string> SendNofiterAsync( |
|||
[NotNull] this INotificationSender sender, |
|||
[NotNull] string name, |
|||
[NotNull] NotificationData data, |
|||
UserIdentifier user = null, |
|||
Guid? tenantId = null, |
|||
NotificationSeverity severity = NotificationSeverity.Info) |
|||
{ |
|||
Check.NotNull(sender, nameof(sender)); |
|||
Check.NotNullOrWhiteSpace(name, nameof(name)); |
|||
Check.NotNull(data, nameof(data)); |
|||
|
|||
if (user == null) |
|||
{ |
|||
return await sender.SendNofiterAsync(name, data, tenantId: tenantId, severity: severity); |
|||
} |
|||
return await sender.SendNofiterAsync(name, data, new[] { user },tenantId: tenantId, severity: severity); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 发送模板通知
|
|||
/// </summary>
|
|||
/// <param name="sender">发送接口</param>
|
|||
/// <param name="name">名称</param>
|
|||
/// <param name="template">模板对象</param>
|
|||
/// <param name="user">用户,为空发给所有订阅用户</param>
|
|||
/// <param name="tenantId">租户</param>
|
|||
/// <param name="severity">严重级别</param>
|
|||
/// <returns>通知标识</returns>
|
|||
public async static Task<string> SendNofiterAsync( |
|||
[NotNull] this INotificationSender sender, |
|||
[NotNull] string name, |
|||
[NotNull] NotificationTemplate template, |
|||
UserIdentifier user = null, |
|||
Guid? tenantId = null, |
|||
NotificationSeverity severity = NotificationSeverity.Info) |
|||
{ |
|||
Check.NotNull(sender, nameof(sender)); |
|||
Check.NotNullOrWhiteSpace(name, nameof(name)); |
|||
Check.NotNull(template, nameof(template)); |
|||
|
|||
if (user == null) |
|||
{ |
|||
return await sender.SendNofiterAsync(name, template, tenantId: tenantId, severity: severity); |
|||
} |
|||
return await sender.SendNofiterAsync(name, template, new[] { user }, tenantId: tenantId, severity: severity); |
|||
} |
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace LINGYUN.Abp.Notifications; |
|||
|
|||
public interface INotificationTemplateStore |
|||
{ |
|||
Task<string> GetOrNullAsync(string templateName, string culture = null, CancellationToken cancellationToken = default); |
|||
} |
|||
@ -0,0 +1,53 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using Volo.Abp; |
|||
using Volo.Abp.Data; |
|||
using Volo.Abp.EventBus; |
|||
|
|||
namespace LINGYUN.Abp.Notifications; |
|||
|
|||
/// <summary>
|
|||
/// 通知模板消息
|
|||
/// </summary>
|
|||
[Serializable] |
|||
[EventName("notifications.template")] |
|||
public class NotificationTemplate : IHasExtraProperties |
|||
{ |
|||
public string Name { get; set; } |
|||
public string Title { get; set; } |
|||
public string Culture { get; set; } |
|||
public string FormUser { get; set; } |
|||
public object this[string key] |
|||
{ |
|||
get { |
|||
return this.GetProperty(key); |
|||
} |
|||
set { |
|||
this.SetProperty(key, value); |
|||
} |
|||
} |
|||
public ExtraPropertyDictionary ExtraProperties { get; set; } |
|||
public NotificationTemplate( |
|||
string name, |
|||
string title, |
|||
string culture = null, |
|||
string formUser = null, |
|||
IDictionary<string, object> data = null) |
|||
{ |
|||
Name = Check.NotNullOrWhiteSpace(name, nameof(name)); |
|||
|
|||
Title = title; |
|||
Culture = culture; |
|||
FormUser = formUser; |
|||
|
|||
if (data != null) |
|||
{ |
|||
ExtraProperties = new ExtraPropertyDictionary(data); |
|||
} |
|||
else |
|||
{ |
|||
ExtraProperties = new ExtraPropertyDictionary(); |
|||
this.SetDefaultsForExtraProperties(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace LINGYUN.Abp.Notifications; |
|||
|
|||
[Dependency(TryRegister = true)] |
|||
public class NullNotificationTemplateStore : INotificationTemplateStore, ISingletonDependency |
|||
{ |
|||
public readonly static INotificationTemplateStore Instance = new NullNotificationTemplateStore(); |
|||
|
|||
public Task<string> GetOrNullAsync(string templateName, string culture = null, CancellationToken cancellationToken = default) |
|||
{ |
|||
return Task.FromResult<string>(null); |
|||
} |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
using LINGYUN.Abp.Notifications; |
|||
using System.ComponentModel.DataAnnotations; |
|||
|
|||
namespace LINGYUN.Abp.MessageService.Notifications; |
|||
|
|||
public class NotificationMarkReadStateInput |
|||
{ |
|||
[Required] |
|||
public long[] IdList { get; set; } |
|||
|
|||
public NotificationReadState State { get; set; } |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
using LINGYUN.Abp.Notifications; |
|||
using System; |
|||
|
|||
namespace LINGYUN.Abp.MessageService.Notifications; |
|||
|
|||
public class UserNotificationDto |
|||
{ |
|||
public string Name { get; set; } |
|||
public string Id { get; set; } |
|||
public NotificationData Data { get; set; } |
|||
public DateTime CreationTime { get; set; } |
|||
public NotificationLifetime Lifetime { get; set; } |
|||
public NotificationType Type { get; set; } |
|||
public NotificationSeverity Severity { get; set; } |
|||
public NotificationReadState State { get; set; } |
|||
} |
|||
@ -0,0 +1,28 @@ |
|||
using AutoMapper; |
|||
using LINGYUN.Abp.MessageService.Notifications; |
|||
using LINGYUN.Abp.Notifications; |
|||
using System; |
|||
|
|||
namespace LINGYUN.Abp.MessageService |
|||
{ |
|||
public class AbpMessageServiceApplicationAutoMapperProfile : Profile |
|||
{ |
|||
public AbpMessageServiceApplicationAutoMapperProfile() |
|||
{ |
|||
CreateMap<UserNotificationInfo, UserNotificationDto>() |
|||
.ForMember(dto => dto.Id, map => map.MapFrom(src => src.Id.ToString())) |
|||
.ForMember(dto => dto.Lifetime, map => map.Ignore()) |
|||
.ForMember(dto => dto.Data, map => map.MapFrom((src, nfi) => |
|||
{ |
|||
var dataType = Type.GetType(src.NotificationTypeName); |
|||
var data = Activator.CreateInstance(dataType); |
|||
if (data is NotificationData notificationData) |
|||
{ |
|||
notificationData.ExtraProperties = src.ExtraProperties; |
|||
return notificationData; |
|||
} |
|||
return new NotificationData(); |
|||
})); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Text; |
|||
using Volo.Abp.Domain.Entities.Auditing; |
|||
|
|||
namespace LINGYUN.Abp.MessageService.Notifications; |
|||
|
|||
public class NotificationTemplate : AuditedAggregateRoot<Guid> |
|||
{ |
|||
|
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
using LINGYUN.Abp.Notifications; |
|||
using System; |
|||
using Volo.Abp.Data; |
|||
|
|||
namespace LINGYUN.Abp.MessageService.Notifications; |
|||
|
|||
public class UserNotificationInfo |
|||
{ |
|||
public Guid? TenantId { get; set; } |
|||
public string Name { get; set; } |
|||
public long Id { get; set; } |
|||
public ExtraPropertyDictionary ExtraProperties { get; set; } |
|||
public string NotificationTypeName { get; set; } |
|||
public DateTime CreationTime { get; set; } |
|||
public NotificationType Type { get; set; } |
|||
public NotificationSeverity Severity { get; set; } |
|||
public NotificationReadState State { get; set; } |
|||
} |
|||
Loading…
Reference in new issue