Browse Source

feat: 重构消息模块

pull/127/head 8.0.4.9
WangJunZzz 2 years ago
parent
commit
bd51b698de
  1. 5
      aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.Application.Contracts/Users/IUserAppService.cs
  2. 17
      aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.Application/Users/UserAppService.cs
  3. 8
      aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.HttpApi/Systems/UserController.cs
  4. 2
      aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Application.Contracts/Hubs/INotificationHubAppService.cs
  5. 56
      aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Application.Contracts/Notifications/Dtos/PagingNotificationInput.cs
  6. 8
      aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Application.Contracts/Notifications/Dtos/PagingNotificationListInput.cs
  7. 46
      aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Application.Contracts/Notifications/Dtos/PagingNotificationListOutput.cs
  8. 70
      aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Application.Contracts/Notifications/Dtos/PagingNotificationOutput.cs
  9. 34
      aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Application.Contracts/Notifications/Dtos/PagingNotificationSubscriptionInput.cs
  10. 70
      aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Application.Contracts/Notifications/Dtos/PagingNotificationSubscriptionOutput.cs
  11. 16
      aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Application.Contracts/Notifications/Dtos/SendCommonMessageInput.cs
  12. 24
      aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Application.Contracts/Notifications/INotificationAppService.cs
  13. 4
      aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Application.Contracts/Permissions/NotificationManagementPermissionDefinitionProvider.cs
  14. 19
      aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Application.Contracts/Permissions/NotificationManagementPermissions.cs
  15. 12
      aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Application/Hubs/NotificationHubAppService.cs
  16. 10
      aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Application/NotificationManagementApplicationAutoMapperProfile.cs
  17. 2
      aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Application/Notifications/LocalEventHandlers/NotificationCreatedLocalEventHandler.cs
  18. 94
      aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Application/Notifications/NotificationAppService.cs
  19. 4
      aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Domain.Shared/Localization/NotificationManagement/en.json
  20. 4
      aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Domain.Shared/Localization/NotificationManagement/zh-Hans.json
  21. 69
      aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Domain.Shared/Notifications/Dtos/NotificationDto.cs
  22. 36
      aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Domain.Shared/Notifications/Dtos/NotificationSubscriptionDto.cs
  23. 11
      aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Domain.Shared/Notifications/Enums/MessageLevel.cs
  24. 9
      aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Domain.Shared/Notifications/Enums/MessageType.cs
  25. 41
      aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Domain.Shared/Notifications/Etos/NotificationEto.cs
  26. 11
      aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Domain.Shared/Notifications/MaxLengths/NotificationMaxLengths.cs
  27. 5
      aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Domain/NotificationDomainAutoMapperProfile.cs
  28. 129
      aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Domain/Notifications/Aggregates/Notification.cs
  29. 50
      aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Domain/Notifications/Aggregates/NotificationSubscription.cs
  30. 74
      aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Domain/Notifications/INotificationManager.cs
  31. 35
      aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Domain/Notifications/INotificationRepository.cs
  32. 35
      aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Domain/Notifications/INotificationSubscriptionManager.cs
  33. 34
      aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Domain/Notifications/INotificationSubscriptionRepository.cs
  34. 187
      aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Domain/Notifications/NotificationManager.cs
  35. 36
      aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Domain/Notifications/NotificationSubscriptionManager.cs
  36. 2
      aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.EntityFrameworkCore/EntityFrameworkCore/INotificationManagementDbContext.cs
  37. 3
      aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.EntityFrameworkCore/EntityFrameworkCore/NotificationManagementDbContext.cs
  38. 10
      aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.EntityFrameworkCore/EntityFrameworkCore/NotificationManagementDbContextModelCreatingExtensions.cs
  39. 10
      aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.EntityFrameworkCore/EntityFrameworkCore/Notifications/EfCoreNotificationQueryableExtensions.cs
  40. 72
      aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.EntityFrameworkCore/EntityFrameworkCore/Notifications/EfCoreNotificationRepository.cs
  41. 39
      aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.EntityFrameworkCore/EntityFrameworkCore/Notifications/EfCoreNotificationSubscriptionRepository.cs
  42. 27
      aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.HttpApi/Notifications/NotificationController.cs
  43. 6
      aspnet-core/services/host/Lion.AbpPro.HttpApi.Host/appsettings.json
  44. 1
      aspnet-core/services/src/Lion.AbpPro.EntityFrameworkCore/EntityFrameworkCore/AbpProDbContext.cs
  45. 1991
      aspnet-core/services/src/Lion.AbpPro.EntityFrameworkCore/Migrations/20231220041852_Init.Designer.cs
  46. 2003
      aspnet-core/services/src/Lion.AbpPro.EntityFrameworkCore/Migrations/20240404001711_AddTenantId.Designer.cs
  47. 104
      aspnet-core/services/src/Lion.AbpPro.EntityFrameworkCore/Migrations/20240404001711_AddTenantId.cs
  48. 37
      aspnet-core/services/src/Lion.AbpPro.EntityFrameworkCore/Migrations/20240404004344_RemoveLanguageIndex.cs
  49. 64
      aspnet-core/services/src/Lion.AbpPro.EntityFrameworkCore/Migrations/20240418052548_1.0.0.Designer.cs
  50. 92
      aspnet-core/services/src/Lion.AbpPro.EntityFrameworkCore/Migrations/20240418052548_1.0.0.cs
  51. 60
      aspnet-core/services/src/Lion.AbpPro.EntityFrameworkCore/Migrations/AbpProDbContextModelSnapshot.cs
  52. 18
      vben28/src/hooks/web/useSignalR.ts
  53. 182
      vben28/src/layouts/default/header/components/notify/NoticeList.vue
  54. 29
      vben28/src/layouts/default/header/components/notify/data.ts
  55. 6
      vben28/src/layouts/default/header/components/notify/index.vue
  56. 10
      vben28/src/layouts/default/header/index.vue
  57. 13
      vben28/src/locales/lang/en/routes/admin.ts
  58. 13
      vben28/src/locales/lang/zh-CN/routes/admin.ts
  59. 20
      vben28/src/router/routes/modules/admin.ts
  60. 566
      vben28/src/services/ServiceProxies.ts
  61. 65
      vben28/src/views/admin/notification/CreateNotification.vue
  62. 65
      vben28/src/views/admin/notification/CreateSubscription.vue
  63. 396
      vben28/src/views/admin/notification/Index.ts
  64. 107
      vben28/src/views/admin/notification/Index.vue
  65. 76
      vben28/src/views/admin/notification/Subscription.vue

5
aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.Application.Contracts/Users/IUserAppService.cs

@ -12,6 +12,11 @@ namespace Lion.AbpPro.BasicManagement.Users
/// </summary>
Task<PagedResultDto<IdentityUserDto>> ListAsync(PagingUserListInput input);
/// <summary>
/// 分页查询用户
/// </summary>
Task<List<IdentityUserDto>> ListAllAsync(PagingUserListInput input);
/// <summary>
/// 用户导出列表
/// </summary>

17
aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.Application/Users/UserAppService.cs

@ -54,6 +54,23 @@ namespace Lion.AbpPro.BasicManagement.Users
base.ObjectMapper.Map<List<Volo.Abp.Identity.IdentityUser>, List<IdentityUserDto>>(source));
}
public async Task<List<IdentityUserDto>> ListAllAsync(PagingUserListInput input)
{
var request = new GetIdentityUsersInput
{
Filter = input.Filter?.Trim(),
MaxResultCount = input.PageSize,
SkipCount = input.SkipCount,
Sorting = nameof(IHasModificationTime.LastModificationTime)
};
var source = await _identityUserRepository
.GetListAsync(request.Sorting, request.MaxResultCount, request.SkipCount, request.Filter);
return ObjectMapper.Map<List<Volo.Abp.Identity.IdentityUser>, List<IdentityUserDto>>(source);
}
/// <summary>
/// 用户导出列表
/// </summary>

8
aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.HttpApi/Systems/UserController.cs

@ -19,6 +19,14 @@ namespace Lion.AbpPro.BasicManagement.Systems
{
return _userAppService.ListAsync(input);
}
[HttpPost("list")]
[SwaggerOperation(summary: "分页获取用户信息", Tags = new[] { "Users" })]
public Task<List<IdentityUserDto>> ListAllAsync(PagingUserListInput input)
{
return _userAppService.ListAllAsync(input);
}
[HttpPost("export")]
[SwaggerOperation(summary: "导出用户列表", Tags = new[] { "Users" })]
[ProducesResponseType(typeof(FileContentResult), (int)HttpStatusCode.OK)]

2
aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Application.Contracts/Hubs/INotificationHubAppService.cs

@ -2,5 +2,5 @@
public interface INotificationHubAppService : IApplicationService
{
Task SendMessageAsync(Guid id, string title, string content, MessageType messageType,MessageLevel messageLevel, List<string> users);
Task SendMessageAsync(Guid id, string title, string content, MessageType messageType,MessageLevel messageLevel, string receiverUserId);
}

56
aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Application.Contracts/Notifications/Dtos/PagingNotificationInput.cs

@ -0,0 +1,56 @@
namespace Lion.AbpPro.NotificationManagement.Notifications.Dtos
{
public class PagingNotificationInput : PagingBase
{
/// <summary>
/// 标题
/// </summary>
public string Title { get; set; }
/// <summary>
/// 内容
/// </summary>
public string Content { get; set; }
/// <summary>
/// 发送者Id
/// </summary>
public Guid? SenderUserId { get; set; }
/// <summary>
/// 发送者名称
/// </summary>
public string SenderUserName { get; set; }
/// <summary>
/// 接受者Id
/// </summary>
public Guid? ReceiverUserId { get; set; }
/// <summary>
/// 接受者名称
/// </summary>
public string ReceiverUserName { get; set; }
/// <summary>
/// 是否已读
/// </summary>
public bool? Read { get; set; }
/// <summary>
/// 已读开始时间
/// </summary>
public DateTime? StartReadTime { get; set; }
/// <summary>
/// 已读结束时间
/// </summary>
public DateTime? EndReadTime { get; set; }
/// <summary>
/// 消息类型
/// </summary>
public MessageType? MessageType { get; set; }
}
}

8
aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Application.Contracts/Notifications/Dtos/PagingNotificationListInput.cs

@ -1,8 +0,0 @@
namespace Lion.AbpPro.NotificationManagement.Notifications.Dtos
{
public class PagingNotificationListInput:PagingBase
{
}
}

46
aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Application.Contracts/Notifications/Dtos/PagingNotificationListOutput.cs

@ -1,46 +0,0 @@
namespace Lion.AbpPro.NotificationManagement.Notifications.Dtos
{
public class PagingNotificationListOutput
{
public Guid Id { get; set; }
/// <summary>
/// 消息标题
/// </summary>
public string Title { get; set; }
/// <summary>
/// 消息内容
/// </summary>
public string Content { get; set; }
/// <summary>
/// 消息类型
/// </summary>
public MessageType MessageType { get; set; }
public string MessageTypeDescription => MessageType.ToDescription();
/// <summary>
/// 消息等级
/// </summary>
public MessageLevel MessageLevel { get; set; }
public string MessageLevelDescription => MessageLevel.ToDescription();
/// <summary>
/// 发送人
/// </summary>
public Guid SenderId { get; set; }
/// <summary>
/// 创建时间
/// </summary>
public DateTime CreationTime { get; set; }
/// <summary>
/// 是否已读
/// </summary>
public bool Read { get; set; }
}
}

70
aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Application.Contracts/Notifications/Dtos/PagingNotificationOutput.cs

@ -0,0 +1,70 @@
namespace Lion.AbpPro.NotificationManagement.Notifications.Dtos
{
public class PagingNotificationOutput
{
public Guid Id { get; set; }
/// <summary>
/// 租户id
/// </summary>
public Guid? TenantId { get; set; }
/// <summary>
/// 消息标题
/// </summary>
public string Title { get; set; }
/// <summary>
/// 消息内容
/// </summary>
public string Content { get; set; }
/// <summary>
/// 消息类型
/// </summary>
public MessageType MessageType { get; set; }
public string MessageTypeName => MessageType.ToDescription();
/// <summary>
/// 消息等级
/// </summary>
public MessageLevel MessageLevel { get; set; }
public string MessageLevelName => MessageLevel.ToDescription();
/// <summary>
/// 发送人
/// </summary>
public Guid SenderUserId { get; set; }
/// <summary>
/// 发送人用户名
/// </summary>
public string SenderUserName { get; set; }
/// <summary>
/// 订阅人
/// 消息类型是广播消息时,订阅人为空
/// </summary>
public Guid? ReceiveUserId { get; set; }
/// <summary>
/// 接收人用户名
/// 消息类型是广播消息时,订接收人用户名为空
/// </summary>
public string ReceiveUserName { get; set; }
/// <summary>
/// 是否已读
/// </summary>
public bool Read { get; set; }
/// <summary>
/// 已读时间
/// </summary>
public DateTime? ReadTime { get; set; }
public DateTime CreationTime { get; set; }
}
}

34
aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Application.Contracts/Notifications/Dtos/PagingNotificationSubscriptionInput.cs

@ -0,0 +1,34 @@
namespace Lion.AbpPro.NotificationManagement.Notifications.Dtos
{
public class PagingNotificationSubscriptionInput : PagingBase
{
public Guid NotificationId { get; set; }
/// <summary>
/// 接受者Id
/// </summary>
public Guid? ReceiverUserId { get; set; }
/// <summary>
/// 接受者名称
/// </summary>
public string ReceiverUserName { get; set; }
/// <summary>
/// 是否已读
/// </summary>
public bool? Read { get; set; }
/// <summary>
/// 已读开始时间
/// </summary>
public DateTime? StartReadTime { get; set; }
/// <summary>
/// 已读结束时间
/// </summary>
public DateTime? EndReadTime { get; set; }
}
}

70
aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Application.Contracts/Notifications/Dtos/PagingNotificationSubscriptionOutput.cs

@ -0,0 +1,70 @@
namespace Lion.AbpPro.NotificationManagement.Notifications.Dtos
{
public class PagingNotificationSubscriptionOutput
{
public Guid Id { get; set; }
/// <summary>
/// 租户id
/// </summary>
public Guid? TenantId { get; set; }
/// <summary>
/// 消息Id
/// </summary>
public Guid NotificationId { get; set; }
/// <summary>
/// 接收人id
/// </summary>
public Guid ReceiveUserId { get; set; }
/// <summary>
/// 接收人用户名
/// </summary>
public string ReceiveUserName { get; set; }
/// <summary>
/// 是否已读
/// </summary>
public bool Read { get; set; }
/// <summary>
/// 已读时间
/// </summary>
public DateTime ReadTime { get; set; }
/// <summary>
/// 消息标题
/// </summary>
public string Title { get; set; }
/// <summary>
/// 消息内容
/// </summary>
public string Content { get; set; }
/// <summary>
/// 消息类型
/// </summary>
public MessageType MessageType { get; set; }
public string MessageTypeName => MessageType.ToDescription();
/// <summary>
/// 消息等级
/// </summary>
public MessageLevel MessageLevel { get; set; }
public string MessageLevelName => MessageLevel.ToDescription();
/// <summary>
/// 发送人
/// </summary>
public Guid SenderUserId { get; set; }
/// <summary>
/// 发送人用户名
/// </summary>
public string SenderUserName { get; set; }
}
}

16
aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Application.Contracts/Notifications/Dtos/SendCommonMessageInput.cs

@ -15,12 +15,13 @@ public class SendCommonMessageInput : IValidatableObject
/// <summary>
/// 发送人
/// </summary>
public List<Guid> ReceiveIds { get; set; }
public Guid ReceiveUserId { get; set; }
public SendCommonMessageInput()
{
ReceiveIds = new List<Guid>();
}
/// <summary>
/// 发送人名称
/// </summary>
public string ReceiveUserName { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
@ -35,10 +36,5 @@ public class SendCommonMessageInput : IValidatableObject
{
yield return new ValidationResult(localization[NotificationManagementErrorCodes.MessageContent], new[] { nameof(Content) });
}
if (ReceiveIds == null || ReceiveIds.Count == 0)
{
yield return new ValidationResult(localization[NotificationManagementErrorCodes.ReceiverNotNull], new[] { nameof(ReceiveIds) });
}
}
}

24
aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Application.Contracts/Notifications/INotificationAppService.cs

@ -1,8 +1,7 @@
namespace Lion.AbpPro.NotificationManagement.Notifications
{
public interface INotificationAppService:IApplicationService
public interface INotificationAppService : IApplicationService
{
/// <summary>
/// 发送警告文本消息
/// </summary>
@ -32,28 +31,17 @@ namespace Lion.AbpPro.NotificationManagement.Notifications
/// 发送错误广播消息
/// </summary>
Task SendBroadCastErrorMessageAsync(SendBroadCastMessageInput input);
/// <summary>
/// 消息设置为已读
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
Task SetReadAsync(SetReadInput input);
/// <summary>
/// 分页获取用户普通文本消息
/// </summary>
/// <param name="listInput"></param>
/// <returns></returns>
Task<PagedResultDto<PagingNotificationListOutput>> GetPageCommonNotificationByUserIdAsync(
PagingNotificationListInput listInput);
/// <summary>
/// 分页获取广播消息
/// 分页获取消息
/// </summary>
/// <param name="listInput"></param>
/// <returns></returns>
Task<PagedResultDto<PagingNotificationListOutput>> GetPageBroadCastNotificationByUserIdAsync(
PagingNotificationListInput listInput);
Task<PagedResultDto<PagingNotificationOutput>> PageNotificationAsync(PagingNotificationInput input);
Task<PagedResultDto<PagingNotificationSubscriptionOutput>> PageNotificationSubscriptionAsync(PagingNotificationSubscriptionInput input);
}
}

4
aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Application.Contracts/Permissions/NotificationManagementPermissionDefinitionProvider.cs

@ -4,7 +4,9 @@ namespace Lion.AbpPro.NotificationManagement.Permissions
{
public override void Define(IPermissionDefinitionContext context)
{
var myGroup = context.AddGroup(NotificationManagementPermissions.GroupName, L("Permission:NotificationManagement"));
var abpIdentityGroup = context.GetGroup("AbpIdentity");
var notificationManagement = abpIdentityGroup.AddPermission(NotificationManagementPermissions.NotificationManagement.Default, L("Permission:NotificationManagement"));
var notificationSubscriptionManagement = abpIdentityGroup.AddPermission(NotificationManagementPermissions.NotificationSubscriptionManagement.Default, L("Permission:NotificationSubscriptionManagement"));
}
private static LocalizableString L(string name)

19
aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Application.Contracts/Permissions/NotificationManagementPermissions.cs

@ -2,8 +2,25 @@ namespace Lion.AbpPro.NotificationManagement.Permissions
{
public class NotificationManagementPermissions
{
public const string GroupName = "NotificationManagement";
public const string GroupName = "AbpIdentity";
public static class NotificationManagement
{
public const string Default = GroupName + ".NotificationManagement";
public const string Create = Default + ".Create";
public const string Update = Default + ".Update";
public const string Delete = Default + ".Delete";
}
public static class NotificationSubscriptionManagement
{
public const string Default = GroupName + ".NotificationSubscriptionManagement";
public const string Create = Default + ".Create";
public const string Update = Default + ".Update";
public const string Delete = Default + ".Delete";
}
public static string[] GetAll()
{
return ReflectionHelper.GetPublicConstantsRecursively(typeof(NotificationManagementPermissions));

12
aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Application/Hubs/NotificationHubAppService.cs

@ -20,12 +20,12 @@ public class NotificationHubAppService : NotificationManagementAppService, INoti
/// <summary>
/// 发送消息
/// </summary>
public virtual async Task SendMessageAsync(Guid id, string title, string content, MessageType messageType, MessageLevel messageLevel, List<string> users)
public virtual async Task SendMessageAsync(Guid id, string title, string content, MessageType messageType, MessageLevel messageLevel, string receiverUserId)
{
switch (messageType)
{
case MessageType.Common:
await SendMessageToClientByUserIdAsync(new SendNotificationDto(id, title, content, messageType, messageLevel), users);
await SendMessageToClientByUserIdAsync(new SendNotificationDto(id, title, content, messageType, messageLevel), receiverUserId);
break;
case MessageType.BroadCast:
await SendMessageToAllClientAsync(new SendNotificationDto(id, title, content, messageType, messageLevel));
@ -38,14 +38,14 @@ public class NotificationHubAppService : NotificationManagementAppService, INoti
/// <summary>
/// 发送消息指定客户端用户
/// </summary>
private async Task SendMessageToClientByUserIdAsync(SendNotificationDto sendNotificationDto, List<string> users)
private async Task SendMessageToClientByUserIdAsync(SendNotificationDto sendNotificationDto, string receiverUserId)
{
if (users is { Count: > 0 })
if (receiverUserId.IsNotNullOrWhiteSpace())
{
await _hubContext.Clients
.Users(users.AsReadOnly().ToList())
.Users(new string[] { receiverUserId })
.ReceiveTextMessageAsync(sendNotificationDto);
_logger.LogInformation($"通知模块收到消息:{_jsonSerializer.Serialize(sendNotificationDto)},发送给:{_jsonSerializer.Serialize(users)}");
_logger.LogInformation($"通知模块收到消息:{_jsonSerializer.Serialize(sendNotificationDto)},发送给:{receiverUserId}");
}
else
{

10
aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Application/NotificationManagementApplicationAutoMapperProfile.cs

@ -7,8 +7,14 @@ namespace Lion.AbpPro.NotificationManagement
/* You can configure your AutoMapper mapping configuration here.
* Alternatively, you can split your mapping configurations
* into multiple profile classes for a better organization. */
CreateMap<Notification, PagingNotificationListOutput>()
.ForMember(dest => dest.Read, opt => opt.MapFrom(e => e.NotificationSubscriptions.FirstOrDefault().Read));
CreateMap<NotificationDto, PagingNotificationOutput>();
CreateMap<NotificationSubscriptionDto, PagingNotificationSubscriptionOutput>()
.ForMember(dest => dest.Title, opt => opt.Ignore())
.ForMember(dest => dest.Content, opt => opt.Ignore())
.ForMember(dest => dest.MessageType, opt => opt.Ignore())
.ForMember(dest => dest.MessageLevel, opt => opt.Ignore())
.ForMember(dest => dest.SenderUserId, opt => opt.Ignore())
.ForMember(dest => dest.SenderUserName, opt => opt.Ignore());
}
}
}

2
aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Application/Notifications/LocalEventHandlers/NotificationCreatedLocalEventHandler.cs

@ -22,7 +22,7 @@ namespace Lion.AbpPro.NotificationManagement.Notifications.LocalEventHandlers
eventData.NotificationEto.Content,
eventData.NotificationEto.MessageType,
eventData.NotificationEto.MessageLevel,
eventData.NotificationEto.NotificationSubscriptions.Select(e => e.ReceiveId.ToString()).ToList());
eventData.NotificationEto.ReceiveUserId.ToString());
}
}

94
aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Application/Notifications/NotificationAppService.cs

@ -1,18 +1,18 @@
using System.Security.Authentication;
namespace Lion.AbpPro.NotificationManagement.Notifications
{
[Authorize]
public class NotificationAppService : NotificationManagementAppService, INotificationAppService
{
private readonly INotificationManager _notificationManager;
private readonly ICurrentUser _currentUser;
private readonly INotificationSubscriptionManager _notificationSubscriptionManager;
public NotificationAppService(
INotificationManager notificationManager,
ICurrentUser currentUser)
public NotificationAppService(INotificationManager notificationManager, INotificationSubscriptionManager notificationSubscriptionManager)
{
_notificationManager = notificationManager;
_currentUser = currentUser;
_notificationSubscriptionManager = notificationSubscriptionManager;
}
@ -21,7 +21,7 @@ namespace Lion.AbpPro.NotificationManagement.Notifications
/// </summary>
public virtual async Task SendCommonWarningMessageAsync(SendCommonMessageInput input)
{
await _notificationManager.SendCommonWarningMessageAsync(input.Title, input.Content, input.ReceiveIds);
await _notificationManager.SendCommonWarningMessageAsync(input.Title, input.Content, MessageLevel.Warning, input.ReceiveUserId, input.ReceiveUserName);
}
/// <summary>
@ -29,7 +29,7 @@ namespace Lion.AbpPro.NotificationManagement.Notifications
/// </summary>
public virtual async Task SendCommonInformationMessageAsync(SendCommonMessageInput input)
{
await _notificationManager.SendCommonInformationMessageAsync(input.Title, input.Content, input.ReceiveIds);
await _notificationManager.SendCommonWarningMessageAsync(input.Title, input.Content, MessageLevel.Information, input.ReceiveUserId, input.ReceiveUserName);
}
/// <summary>
@ -37,7 +37,7 @@ namespace Lion.AbpPro.NotificationManagement.Notifications
/// </summary>
public virtual async Task SendCommonErrorMessageAsync(SendCommonMessageInput input)
{
await _notificationManager.SendCommonErrorMessageAsync(input.Title, input.Content, input.ReceiveIds);
await _notificationManager.SendCommonWarningMessageAsync(input.Title, input.Content, MessageLevel.Error, input.ReceiveUserId, input.ReceiveUserName);
}
/// <summary>
@ -45,7 +45,7 @@ namespace Lion.AbpPro.NotificationManagement.Notifications
/// </summary>
public virtual async Task SendBroadCastWarningMessageAsync(SendBroadCastMessageInput input)
{
await _notificationManager.SendBroadCastWarningMessageAsync(input.Title, input.Content);
await _notificationManager.SendBroadCastWarningMessageAsync(input.Title, input.Content, MessageLevel.Warning);
}
/// <summary>
@ -53,7 +53,7 @@ namespace Lion.AbpPro.NotificationManagement.Notifications
/// </summary>
public virtual async Task SendBroadCastInformationMessageAsync(SendBroadCastMessageInput input)
{
await _notificationManager.SendBroadCastInformationMessageAsync(input.Title, input.Content);
await _notificationManager.SendBroadCastWarningMessageAsync(input.Title, input.Content, MessageLevel.Information);
}
/// <summary>
@ -61,40 +61,72 @@ namespace Lion.AbpPro.NotificationManagement.Notifications
/// </summary>
public virtual async Task SendBroadCastErrorMessageAsync(SendBroadCastMessageInput input)
{
await _notificationManager.SendBroadCastErrorMessageAsync(input.Title, input.Content);
await _notificationManager.SendBroadCastWarningMessageAsync(input.Title, input.Content, MessageLevel.Error);
}
public virtual Task SetReadAsync(SetReadInput input)
public virtual async Task SetReadAsync(SetReadInput input)
{
return _notificationManager.SetReadAsync(input.Id);
var notification = await _notificationManager.FindAsync(input.Id);
if (notification == null)
{
throw new UserFriendlyException("消息不存在");
}
if (notification.MessageType == MessageType.Common)
{
await _notificationManager.SetReadAsync(input.Id);
}
else
{
if (!CurrentUser.IsAuthenticated)
{
throw new AuthenticationException();
}
await _notificationSubscriptionManager.SetReadAsync(CurrentUser.Id.Value, CurrentUser.UserName, input.Id);
}
}
/// <summary>
/// 分页获取用户普通文本消息
/// 分页获取消息
/// </summary>
public virtual async Task<PagedResultDto<PagingNotificationListOutput>> GetPageCommonNotificationByUserIdAsync(PagingNotificationListInput listInput)
public virtual async Task<PagedResultDto<PagingNotificationOutput>> PageNotificationAsync(PagingNotificationInput input)
{
if (_currentUser == null || !_currentUser.Id.HasValue)
{
return null;
}
var totalCount = await _notificationManager.GetPagingCountAsync(_currentUser.Id.Value, MessageType.Common);
var list = await _notificationManager.GetPagingListAsync(_currentUser.Id.Value, MessageType.Common, listInput.PageSize, listInput.SkipCount);
return new PagedResultDto<PagingNotificationListOutput>(totalCount, ObjectMapper.Map<List<Notification>, List<PagingNotificationListOutput>>(list));
var totalCount = await _notificationManager.GetPagingCountAsync(input.Title, input.Content, input.SenderUserId, input.SenderUserName, input.ReceiverUserId, input.ReceiverUserName, input.Read, input.StartReadTime, input.EndReadTime, input.MessageType);
var list = await _notificationManager.GetPagingListAsync(input.Title, input.Content, input.SenderUserId, input.SenderUserName, input.ReceiverUserId, input.ReceiverUserName, input.Read, input.StartReadTime, input.EndReadTime, input.MessageType, input.PageSize, input.SkipCount);
return new PagedResultDto<PagingNotificationOutput>(totalCount, ObjectMapper.Map<List<NotificationDto>, List<PagingNotificationOutput>>(list));
}
/// <summary>
/// 分页获取广播消息
/// 分页获取消息
/// </summary>
/// <param name="listInput"></param>
/// <returns></returns>
public virtual async Task<PagedResultDto<PagingNotificationListOutput>> GetPageBroadCastNotificationByUserIdAsync(PagingNotificationListInput listInput)
public virtual async Task<PagedResultDto<PagingNotificationSubscriptionOutput>> PageNotificationSubscriptionAsync(PagingNotificationSubscriptionInput input)
{
var totalCount = await _notificationManager.GetPagingCountAsync(null, MessageType.Common);
var list = await _notificationManager.GetPagingListAsync(null, MessageType.BroadCast, listInput.PageSize, listInput.SkipCount);
return new PagedResultDto<PagingNotificationListOutput>(totalCount, ObjectMapper.Map<List<Notification>, List<PagingNotificationListOutput>>(list));
var totalCount = await _notificationSubscriptionManager.GetPagingCountAsync(input.NotificationId, input.ReceiverUserId, input.ReceiverUserName, input.StartReadTime, input.EndReadTime);
var list = await _notificationSubscriptionManager.GetPagingListAsync(input.NotificationId, input.ReceiverUserId, input.ReceiverUserName, input.StartReadTime, input.EndReadTime, input.PageSize, input.SkipCount);
var result = new PagedResultDto<PagingNotificationSubscriptionOutput>(totalCount, ObjectMapper.Map<List<NotificationSubscriptionDto>, List<PagingNotificationSubscriptionOutput>>(list));
// 获取消息内容
if (totalCount > 0)
{
var notifications = await _notificationManager.GetListAsync(list.Select(e => e.NotificationId).Distinct().ToList());
foreach (var item in result.Items)
{
var notification = notifications.FirstOrDefault(e => e.Id == item.NotificationId);
if (notification != null)
{
item.Title = notification.Title;
item.Content = notification.Content;
item.MessageType = notification.MessageType;
item.MessageLevel = notification.MessageLevel;
item.SenderUserId = notification.SenderUserId;
item.SenderUserName = notification.SenderUserName;
}
}
}
return result;
}
}
}

4
aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Domain.Shared/Localization/NotificationManagement/en.json

@ -9,6 +9,8 @@
"Lion.AbpPro.NotificationManagement:100004": "User UnSubscription",
"Lion.AbpPro.NotificationManagement:100005": "Message Title NotNull",
"Lion.AbpPro.NotificationManagement:100006": "Message Content NotNull",
"Lion.AbpPro.NotificationManagement:100007": "Message Receiver NotNull"
"Lion.AbpPro.NotificationManagement:100007": "Message Receiver NotNull",
"Permission:NotificationManagement": "NotificationManagement",
"Permission:NotificationSubscriptionManagement": "NotificationSubscriptionManagement"
}
}

4
aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Domain.Shared/Localization/NotificationManagement/zh-Hans.json

@ -9,6 +9,8 @@
"Lion.AbpPro.NotificationManagement:100003": "未知的消息类型",
"Lion.AbpPro.NotificationManagement:100004": "当前用户未订阅消息",
"Lion.AbpPro.NotificationManagement:100005": "消息标题不能为空",
"Lion.AbpPro.NotificationManagement:100006": "消息内容不能为空"
"Lion.AbpPro.NotificationManagement:100006": "消息内容不能为空",
"Permission:NotificationManagement": "消息管理",
"Permission:NotificationSubscriptionManagement": "通告管理"
}
}

69
aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Domain.Shared/Notifications/Dtos/NotificationDto.cs

@ -0,0 +1,69 @@
using Lion.AbpPro.NotificationManagement.Notifications.Enums;
namespace Lion.AbpPro.NotificationManagement.Notifications.Dtos
{
public class NotificationDto
{
public Guid Id { get; set; }
/// <summary>
/// 租户id
/// </summary>
public Guid? TenantId { get; set; }
/// <summary>
/// 消息标题
/// </summary>
public string Title { get; set; }
/// <summary>
/// 消息内容
/// </summary>
public string Content { get; set; }
/// <summary>
/// 消息类型
/// </summary>
public MessageType MessageType { get; set; }
/// <summary>
/// 消息等级
/// </summary>
public MessageLevel MessageLevel { get; set; }
/// <summary>
/// 发送人
/// </summary>
public Guid SenderUserId { get; set; }
/// <summary>
/// 发送人用户名
/// </summary>
public string SenderUserName { get; set; }
/// <summary>
/// 订阅人
/// 消息类型是广播消息时,订阅人为空
/// </summary>
public Guid? ReceiveUserId { get; set; }
/// <summary>
/// 接收人用户名
/// 消息类型是广播消息时,订接收人用户名为空
/// </summary>
public string ReceiveUserName { get; set; }
/// <summary>
/// 是否已读
/// </summary>
public bool Read { get; set; }
/// <summary>
/// 已读时间
/// </summary>
public DateTime? ReadTime { get; set; }
public DateTime CreationTime { get; set; }
}
}

36
aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Domain.Shared/Notifications/Dtos/NotificationSubscriptionDto.cs

@ -0,0 +1,36 @@
namespace Lion.AbpPro.NotificationManagement.Notifications.Dtos;
public class NotificationSubscriptionDto
{
public Guid Id { get; set; }
/// <summary>
/// 租户id
/// </summary>
public Guid? TenantId { get; private set; }
/// <summary>
/// 消息Id
/// </summary>
public Guid NotificationId { get; private set; }
/// <summary>
/// 接收人id
/// </summary>
public Guid ReceiveUserId { get; private set; }
/// <summary>
/// 接收人用户名
/// </summary>
public string ReceiveUserName { get; private set; }
/// <summary>
/// 是否已读
/// </summary>
public bool Read { get; private set; }
/// <summary>
/// 已读时间
/// </summary>
public DateTime ReadTime { get; private set; }
}

11
aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Domain.Shared/Notifications/Enums/MessageLevel.cs

@ -10,16 +10,15 @@ public enum MessageLevel
/// <summary>
/// 警告
/// </summary>
[Description("警告")]
Warning = 10,
[Description("警告")] Warning = 10,
/// <summary>
/// 正常
/// </summary>
[Description("正常")]
Information = 20,
[Description("正常")] Information = 20,
/// <summary>
/// 错误
/// </summary>
[Description("错误")]
Error = 30,
[Description("错误")] Error = 30,
}

9
aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Domain.Shared/Notifications/Enums/MessageType.cs

@ -7,17 +7,14 @@ namespace Lion.AbpPro.NotificationManagement.Notifications.Enums
/// </summary>
public enum MessageType
{
/// <summary>
/// 广播消息
/// </summary>
[Description("广播消息")]
BroadCast = 10,
[Description("广播消息")] BroadCast = 10,
/// <summary>
/// 普通文本消息
/// </summary>
[Description("普通文本消息")]
Common = 20,
[Description("普通文本消息")] Common = 20,
}
}

41
aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Domain.Shared/Notifications/Etos/NotificationEto.cs

@ -7,59 +7,66 @@ namespace Lion.AbpPro.NotificationManagement.Notifications.Etos
{
public class NotificationEto
{
public Guid Id { get; set; }
/// <summary>
/// 租户id
/// </summary>
public Guid? TenantId { get; set; }
public Guid Id { get; set; }
/// <summary>
/// 消息标题
/// </summary>
public string Title { get; set; }
public string Title { get; set; }
/// <summary>
/// 消息内容
/// </summary>
public string Content { get; set; }
public string Content { get; set; }
/// <summary>
/// 消息类型
/// </summary>
public MessageType MessageType { get; set; }
public MessageType MessageType { get; set; }
/// <summary>
/// 消息等级
/// </summary>
public MessageLevel MessageLevel { get; set; }
/// <summary>
/// 发送人
/// </summary>
public Guid SenderId { get; set; }
public Guid SenderUserId { get; set; }
/// <summary>
/// 关联属性1:N 消息订阅者集合
/// 发送人用户名
/// </summary>
public List<NotificationSubscriptionEto> NotificationSubscriptions { get; set; }
}
public string SenderUserName { get; set; }
public class NotificationSubscriptionEto
{
/// <summary>
/// 订阅人
/// 消息类型是广播消息时,订阅人为空
/// </summary>
public Guid ReceiveId { get; set; }
public Guid? ReceiveUserId { get; set; }
/// <summary>
/// 接收人用户名
/// 消息类型是广播消息时,订接收人用户名为空
/// </summary>
public string ReceiveUserName { get; set; }
/// <summary>
/// 是否已读
/// </summary>
public bool Read { get; set; }
public bool Read { get; set; }
/// <summary>
/// 已读时间
/// </summary>
public DateTime? ReadTime { get; set; }
public DateTime? ReadTime { get; set; }
}
}

11
aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Domain.Shared/Notifications/MaxLengths/NotificationMaxLengths.cs

@ -3,14 +3,9 @@ namespace Lion.AbpPro.NotificationManagement.Notifications.MaxLengths
public class NotificationMaxLengths
{
/// <summary>
/// 消息标题
/// </summary>
public const int Title = 256;
/// <summary>
/// 消息内容
/// </summary>
public const int Content = 1024;
public const int Length128 = 128;
public const int Length1024 = 1024;
}
}

5
aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Domain/NotificationDomainAutoMapperProfile.cs

@ -1,3 +1,5 @@
using Lion.AbpPro.NotificationManagement.Notifications.Dtos;
namespace Lion.AbpPro.NotificationManagement
{
public class NotificationDomainAutoMapperProfile:Profile
@ -5,7 +7,8 @@ namespace Lion.AbpPro.NotificationManagement
public NotificationDomainAutoMapperProfile()
{
CreateMap<Notification, NotificationEto>();
CreateMap<NotificationSubscription, NotificationSubscriptionEto>();
CreateMap<Notification, NotificationDto>();
CreateMap<NotificationSubscription, NotificationSubscriptionDto>();
}
}
}

129
aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Domain/Notifications/Aggregates/Notification.cs

@ -11,19 +11,15 @@ namespace Lion.AbpPro.NotificationManagement.Notifications.Aggregates
/// 租户id
/// </summary>
public Guid? TenantId { get; private set; }
/// <summary>
/// 消息标题
/// </summary>
[StringLength(NotificationMaxLengths.Title)]
[Required]
public string Title { get; private set; }
/// <summary>
/// 消息内容
/// </summary>
[StringLength(NotificationMaxLengths.Content)]
[Required]
public string Content { get; private set; }
/// <summary>
@ -39,16 +35,40 @@ namespace Lion.AbpPro.NotificationManagement.Notifications.Aggregates
/// <summary>
/// 发送人
/// </summary>
public Guid SenderId { get; private set; }
public Guid SenderUserId { get; private set; }
/// <summary>
/// 发送人用户名
/// </summary>
public string SenderUserName { get; private set; }
/// <summary>
/// 关联属性1:N 消息订阅者集合
/// 订阅人
/// 消息类型是广播消息时,订阅人为空
/// </summary>
public Guid? ReceiveUserId { get; private set; }
/// <summary>
/// 接收人用户名
/// 消息类型是广播消息时,订接收人用户名为空
/// </summary>
public string ReceiveUserName { get; private set; }
/// <summary>
/// 是否已读
/// </summary>
public bool Read { get; private set; }
/// <summary>
/// 已读时间
/// </summary>
public List<NotificationSubscription> NotificationSubscriptions { get; private set; }
public DateTime? ReadTime { get; private set; }
private Notification()
{
NotificationSubscriptions = new List<NotificationSubscription>();
}
public Notification(
@ -57,57 +77,65 @@ namespace Lion.AbpPro.NotificationManagement.Notifications.Aggregates
string content,
MessageType messageType,
MessageLevel messageLevel,
Guid senderId,
Guid senderUserId,
string senderUserName,
Guid? receiveUserId = null,
string receiveUserName ="",
DateTime? readTime = null,
bool read = false,
Guid? tenantId = null
) : base(id)
{
NotificationSubscriptions = new List<NotificationSubscription>();
SetProperties(
title,
content,
messageType,
messageLevel,
senderId
);
SetTenantId(tenantId);
}
private void SetProperties(
string title,
string content,
MessageType messageType,
MessageLevel messageLevel,
Guid senderId
)
{
SetTitle(title);
SetContent(content);
SetMessageType(messageType);
SetMessageLevel(messageLevel);
SetSenderId(senderId);
SetSenderUserId(senderUserId);
SetSenderUserName(senderUserName);
SetReceiveUserId(receiveUserId);
SetReceiveUserName(receiveUserName);
SetTenantId(tenantId);
SetRead(read,readTime);
}
private void SetTenantId(Guid? tenantId)
{
TenantId = tenantId;
}
private void SetSenderUserId(Guid senderUserId)
{
Guard.NotEmpty(senderUserId, nameof(senderUserId));
SenderUserId = senderUserId;
}
private void SetSenderUserName(string senderUserName)
{
Guard.NotNullOrWhiteSpace(senderUserName, nameof(senderUserName), NotificationMaxLengths.Length128);
SenderUserName = senderUserName;
}
private void SetReceiveUserId(Guid? receiveUserId)
{
ReceiveUserId = receiveUserId;
}
private void SetSenderId(Guid senderId)
private void SetReceiveUserName(string receiveUserName)
{
Guard.NotEmpty(senderId, nameof(senderId));
SenderId = senderId;
ReceiveUserName = receiveUserName;
}
private void SetTitle(string title)
{
Guard.NotNullOrWhiteSpace(title, nameof(title), NotificationMaxLengths.Title);
Guard.NotNullOrWhiteSpace(title, nameof(title), NotificationMaxLengths.Length128);
Title = title;
}
private void SetContent(string content)
{
Guard.NotNullOrWhiteSpace(content, nameof(content), NotificationMaxLengths.Content);
Guard.NotNullOrWhiteSpace(content, nameof(content), NotificationMaxLengths.Length1024);
Content = content;
}
@ -120,37 +148,18 @@ namespace Lion.AbpPro.NotificationManagement.Notifications.Aggregates
{
MessageLevel = messageLevel;
}
/// <summary>
/// 新增非广播消息订阅人
/// </summary>
public void AddNotificationSubscription(Guid notificationSubscriptionId, Guid receiveId)
{
if (NotificationSubscriptions.Any(e => e.ReceiveId == receiveId)) return;
NotificationSubscriptions.Add(
new NotificationSubscription(notificationSubscriptionId, Id, receiveId));
}
/// <summary>
/// 新增消息类型为广播订阅人
/// </summary>
public void AddBroadCastNotificationSubscription(Guid notificationSubscriptionId, Guid receiveId, DateTime readTime)
public void SetRead(bool read, DateTime? readTime = null)
{
if (NotificationSubscriptions.Any(e => e.ReceiveId == receiveId))
{
return;
}
var temp = new NotificationSubscription(notificationSubscriptionId, Id, receiveId);
temp.SetRead(readTime);
NotificationSubscriptions.Add(temp);
Read = read;
ReadTime = readTime;
}
/// <summary>
/// 添加创建消息事件
/// </summary>
public void AddCreatedNotificationLocalEvent(
CreatedNotificationLocalEvent createdNotificationLocalEvent)
public void AddCreatedNotificationLocalEvent(CreatedNotificationLocalEvent createdNotificationLocalEvent)
{
AddLocalEvent(createdNotificationLocalEvent);
}

50
aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Domain/Notifications/Aggregates/NotificationSubscription.cs

@ -5,22 +5,27 @@ namespace Lion.AbpPro.NotificationManagement.Notifications.Aggregates
/// <summary>
/// 消息订阅者
/// </summary>
public class NotificationSubscription : FullAuditedEntity<Guid>, IMultiTenant
public class NotificationSubscription : FullAuditedAggregateRoot<Guid>, IMultiTenant
{
/// <summary>
/// 租户id
/// </summary>
public Guid? TenantId { get; private set; }
/// <summary>
/// 消息Id
/// </summary>
public Guid NotificationId { get; set; }
public Guid NotificationId { get; private set; }
/// <summary>
/// 接收人id
/// </summary>
public Guid ReceiveUserId { get; private set; }
/// <summary>
/// 订阅人
/// 接收人用户名
/// </summary>
public Guid ReceiveId { get; private set; }
public string ReceiveUserName { get; private set; }
/// <summary>
/// 是否已读
@ -30,7 +35,7 @@ namespace Lion.AbpPro.NotificationManagement.Notifications.Aggregates
/// <summary>
/// 已读时间
/// </summary>
public DateTime? ReadTime { get; private set; }
public DateTime ReadTime { get; private set; }
private NotificationSubscription()
@ -40,31 +45,48 @@ namespace Lion.AbpPro.NotificationManagement.Notifications.Aggregates
public NotificationSubscription(
Guid id,
Guid notificationId,
Guid receiveId,
Guid receiveUserId,
string receiveUserName,
DateTime readTime,
bool read = true,
Guid? tenantId = null
) : base(id)
{
SetNotificationId(notificationId);
SetReceiveId(receiveId);
Read = false;
ReadTime = null;
SetReceiveUserId(receiveUserId);
SetReceiveUserName(receiveUserName);
SetRead(read, readTime);
SetTenantId(tenantId);
}
public void SetRead(bool read, DateTime readTime)
{
Read = read;
ReadTime = readTime;
}
private void SetTenantId(Guid? tenantId)
{
TenantId = tenantId;
}
private void SetNotificationId(Guid notificationId)
{
NotificationId = notificationId;
}
private void SetReceiveId(Guid receiveId)
private void SetReceiveUserId(Guid receiveUserId)
{
ReceiveId = receiveId;
ReceiveUserId = receiveUserId;
}
private void SetReceiveUserName(string receiveUserName)
{
Guard.NotNullOrWhiteSpace(receiveUserName, nameof(receiveUserName), NotificationMaxLengths.Length128);
ReceiveUserName = receiveUserName;
}
public void SetRead(DateTime readTime)
{
Read = true;

74
aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Domain/Notifications/INotificationManager.cs

@ -1,4 +1,5 @@
using Volo.Abp.DependencyInjection;
using Lion.AbpPro.NotificationManagement.Notifications.Dtos;
using Volo.Abp.DependencyInjection;
namespace Lion.AbpPro.NotificationManagement.Notifications;
@ -7,65 +8,60 @@ public interface INotificationManager
/// <summary>
/// 分页获取消息
/// </summary>
Task<List<Notification>> GetPagingListAsync(
Guid? userId,
MessageType messageType,
Task<List<NotificationDto>> GetPagingListAsync(
string title,
string content,
Guid? senderUserId,
string senderUserName,
Guid? receiverUserId,
string receiverUserName,
bool? read,
DateTime? startReadTime,
DateTime? endReadTime,
MessageType? messageType,
int maxResultCount = 10,
int skipCount = 0);
/// <summary>
/// 获取消息总条数
/// </summary>
Task<long> GetPagingCountAsync(Guid? userId, MessageType messageType);
Task<long> GetPagingCountAsync(
string title,
string content,
Guid? senderUserId,
string senderUserName,
Guid? receiverUserId,
string receiverUserName,
bool? read,
DateTime? startReadTime,
DateTime? endReadTime,
MessageType? messageType);
/// <summary>
/// 发送警告文本消息
/// </summary>
/// <param name="title">标题</param>
/// <param name="content">消息内容</param>
/// <param name="receiveIds">接受人,发送给谁。</param>
Task SendCommonWarningMessageAsync(string title, string content, List<Guid> receiveIds);
/// <summary>
/// 发送普通文本消息
/// </summary>
/// <param name="title">标题</param>
/// <param name="content">消息内容</param>
/// <param name="receiveIds">接受人,发送给谁。</param>
Task SendCommonInformationMessageAsync(string title, string content, List<Guid> receiveIds);
/// <summary>
/// 发送错误文本消息
/// </summary>
Task SendCommonErrorMessageAsync(string title, string content, List<Guid> receiveIds);
/// <param name="level">消息等级</param>
/// <param name="receiveUserId">接受人,发送给谁。</param>
/// <param name="receiveUserName">接受人用户名</param>
Task SendCommonWarningMessageAsync(string title, string content, MessageLevel level, Guid receiveUserId,string receiveUserName);
/// <summary>
/// 发送警告广播消息
/// </summary>
/// <param name="title">标题</param>
/// <param name="content">消息内容</param>
Task SendBroadCastWarningMessageAsync(string title, string content);
/// <summary>
/// 发送正常广播消息
/// </summary>
/// <param name="title">标题</param>
/// <param name="content">消息内容</param>
Task SendBroadCastInformationMessageAsync(string title, string content);
/// <summary>
/// 发送错误广播消息
/// </summary>
/// <param name="title">标题</param>
/// <param name="content">消息内容</param>
Task SendBroadCastErrorMessageAsync(string title, string content);
/// <param name="level">消息等级</param>
Task SendBroadCastWarningMessageAsync(string title, string content, MessageLevel level);
/// <summary>
/// 消息设置为已读
/// </summary>
/// <param name="id">消息Id</param>
Task SetReadAsync(Guid id);
IAbpLazyServiceProvider LazyServiceProvider { get; set; }
IServiceProvider ServiceProvider { get; set; }
Task<NotificationDto> FindAsync(Guid id);
Task<List<NotificationDto>> GetListAsync(List<Guid> ids);
}

35
aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Domain/Notifications/INotificationRepository.cs

@ -3,20 +3,22 @@ namespace Lion.AbpPro.NotificationManagement.Notifications
/// <summary>
/// 消息通知 仓储接口
/// </summary>
public partial interface INotificationRepository : IBasicRepository<Notification, Guid>
public interface INotificationRepository : IBasicRepository<Notification, Guid>
{
/// <summary>
/// 查找用户消息
/// </summary>
/// <param name="id"></param>
Task<Notification> FindByIdAsync(Guid id);
/// <summary>
/// 分页获取消息
/// </summary>
Task<List<Notification>> GetPagingListAsync(
Guid? userId,
MessageType messageType,
string title,
string content,
Guid? senderUserId,
string senderUserName,
Guid? receiverUserId,
string receiverUserName,
bool? read,
DateTime? startReadTime,
DateTime? endReadTime,
MessageType? messageType,
int maxResultCount = 10,
int skipCount = 0,
CancellationToken cancellationToken = default);
@ -24,6 +26,19 @@ namespace Lion.AbpPro.NotificationManagement.Notifications
/// <summary>
/// 获取消息总条数
/// </summary>
Task<long> GetPagingCountAsync(Guid? userId, MessageType messageType, CancellationToken cancellationToken = default);
Task<long> GetPagingCountAsync(
string title,
string content,
Guid? senderUserId,
string senderUserName,
Guid? receiverUserId,
string receiverUserName,
bool? read,
DateTime? startReadTime,
DateTime? endReadTime,
MessageType? messageType,
CancellationToken cancellationToken = default);
Task<List<Notification>> GetListAsync(List<Guid> ids);
}
}

35
aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Domain/Notifications/INotificationSubscriptionManager.cs

@ -0,0 +1,35 @@
using Lion.AbpPro.NotificationManagement.Notifications.Dtos;
namespace Lion.AbpPro.NotificationManagement.Notifications;
public interface INotificationSubscriptionManager
{
/// <summary>
/// 设置已读
/// </summary>
Task SetReadAsync(Guid receiveUserId, string receiveUserName, Guid notificationId);
/// <summary>
/// 分页获取消息
/// </summary>
Task<List<NotificationSubscriptionDto>> GetPagingListAsync(
Guid notificationId,
Guid? receiverUserId,
string receiverUserName,
DateTime? startReadTime,
DateTime? endReadTime,
int maxResultCount = 10,
int skipCount = 0,
CancellationToken cancellationToken = default);
/// <summary>
/// 获取消息总条数
/// </summary>
Task<long> GetPagingCountAsync(
Guid notificationId,
Guid? receiverUserId,
string receiverUserName,
DateTime? startReadTime,
DateTime? endReadTime,
CancellationToken cancellationToken = default);
}

34
aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Domain/Notifications/INotificationSubscriptionRepository.cs

@ -0,0 +1,34 @@
namespace Lion.AbpPro.NotificationManagement.Notifications
{
/// <summary>
/// 消息通知 仓储接口
/// </summary>
public interface INotificationSubscriptionRepository : IBasicRepository<NotificationSubscription, Guid>
{
/// <summary>
/// 分页获取消息
/// </summary>
Task<List<NotificationSubscription>> GetPagingListAsync(
Guid notificationId,
Guid? receiverUserId,
string receiverUserName,
DateTime? startReadTime,
DateTime? endReadTime,
int maxResultCount = 10,
int skipCount = 0,
CancellationToken cancellationToken = default);
/// <summary>
/// 获取消息总条数
/// </summary>
Task<long> GetPagingCountAsync(
Guid notificationId,
Guid? receiverUserId,
string receiverUserName,
DateTime? startReadTime,
DateTime? endReadTime,
CancellationToken cancellationToken = default);
Task<NotificationSubscription> FindAsync(Guid receiverUserId, Guid notificationId, CancellationToken cancellationToken = default);
}
}

187
aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Domain/Notifications/NotificationManager.cs

@ -1,3 +1,4 @@
using Lion.AbpPro.NotificationManagement.Notifications.Dtos;
using Lion.AbpPro.NotificationManagement.Notifications.LocalEvents;
namespace Lion.AbpPro.NotificationManagement.Notifications
@ -17,170 +18,82 @@ namespace Lion.AbpPro.NotificationManagement.Notifications
/// <summary>
/// 分页获取消息
/// </summary>
public async Task<List<Notification>> GetPagingListAsync(
Guid? userId,
MessageType messageType,
public async Task<List<NotificationDto>> GetPagingListAsync(
string title,
string content,
Guid? senderUserId,
string senderUserName,
Guid? receiverUserId,
string receiverUserName,
bool? read,
DateTime? startReadTime,
DateTime? endReadTime,
MessageType? messageType,
int maxResultCount = 10,
int skipCount = 0)
{
return await _notificationRepository.GetPagingListAsync(userId, messageType, maxResultCount, skipCount);
var list = await _notificationRepository.GetPagingListAsync(title, content, senderUserId, senderUserName, receiverUserId, receiverUserName, read, startReadTime, endReadTime, messageType, maxResultCount, skipCount);
return ObjectMapper.Map<List<Notification>, List<NotificationDto>>(list);
}
/// <summary>
/// 获取消息总条数
/// </summary>
public async Task<long> GetPagingCountAsync(Guid? userId, MessageType messageType)
public async Task<long> GetPagingCountAsync(
string title,
string content,
Guid? senderUserId,
string senderUserName,
Guid? receiverUserId,
string receiverUserName,
bool? read,
DateTime? startReadTime,
DateTime? endReadTime,
MessageType? messageType)
{
return await _notificationRepository.GetPagingCountAsync(userId, messageType);
return await _notificationRepository.GetPagingCountAsync(title, content, senderUserId, senderUserName, receiverUserId, receiverUserName, read, startReadTime, endReadTime, messageType);
}
/// <summary>
/// 发送警告文本消息
/// </summary>
/// <param name="title">标题</param>
/// <param name="content">消息内容</param>
/// <param name="receiveIds">接受人,发送给谁。</param>
public async Task SendCommonWarningMessageAsync(string title, string content, List<Guid> receiveIds)
public async Task SendCommonWarningMessageAsync(string title, string content, MessageLevel level, Guid receiveUserId, string receiveUserName)
{
if (receiveIds is { Count: 0 })
{
throw new NotificationManagementDomainException(NotificationManagementErrorCodes.ReceiverNotNull);
}
var senderId = Guid.Empty;
if (_currentUser?.Id != null)
if (!_currentUser.Id.HasValue)
{
senderId = _currentUser.Id.Value;
throw new AbpAuthorizationException();
}
var entity = new Notification(GuidGenerator.Create(), title, content, MessageType.Common, MessageLevel.Warning, senderId, CurrentTenant.Id);
foreach (var item in receiveIds)
{
entity.AddNotificationSubscription(GuidGenerator.Create(), item);
}
var notificationEto = ObjectMapper.Map<Notification, NotificationEto>(entity);
var entity = new Notification(GuidGenerator.Create(), title, content, MessageType.Common, level, _currentUser.Id.Value, _currentUser.UserName, receiveUserId, receiveUserName, tenantId: CurrentTenant?.Id);
// 发送集成事件
entity.AddCreatedNotificationLocalEvent(new CreatedNotificationLocalEvent(notificationEto));
await _notificationRepository.InsertAsync(entity);
}
/// <summary>
/// 发送普通文本消息
/// </summary>
/// <param name="title">标题</param>
/// <param name="content">消息内容</param>
/// <param name="receiveIds">接受人,发送给谁。</param>
public async Task SendCommonInformationMessageAsync(string title, string content, List<Guid> receiveIds)
{
if (receiveIds is { Count: 0 })
{
throw new NotificationManagementDomainException(NotificationManagementErrorCodes.ReceiverNotNull);
}
var senderId = Guid.Empty;
if (_currentUser?.Id != null)
{
senderId = _currentUser.Id.Value;
}
var entity = new Notification(GuidGenerator.Create(), title, content, MessageType.Common, MessageLevel.Information, senderId, CurrentTenant.Id);
foreach (var item in receiveIds)
{
entity.AddNotificationSubscription(GuidGenerator.Create(), item);
}
var notificationEto = ObjectMapper.Map<Notification, NotificationEto>(entity);
// 发送集成事件
entity.AddCreatedNotificationLocalEvent(new CreatedNotificationLocalEvent(notificationEto));
await _notificationRepository.InsertAsync(entity);
}
/// <summary>
/// 发送错误文本消息
/// </summary>
public async Task SendCommonErrorMessageAsync(string title, string content, List<Guid> receiveIds)
public async Task SendBroadCastWarningMessageAsync(string title, string content, MessageLevel level)
{
if (receiveIds is { Count: 0 })
{
throw new NotificationManagementDomainException(NotificationManagementErrorCodes.ReceiverNotNull);
}
var senderId = Guid.Empty;
if (_currentUser?.Id != null)
if (!_currentUser.Id.HasValue)
{
senderId = _currentUser.Id.Value;
throw new AbpAuthorizationException();
}
var entity = new Notification(GuidGenerator.Create(), title, content, MessageType.Common, MessageLevel.Error, senderId, CurrentTenant.Id);
foreach (var item in receiveIds)
{
entity.AddNotificationSubscription(GuidGenerator.Create(), item);
}
var notificationEto = ObjectMapper.Map<Notification, NotificationEto>(entity);
var entity = new Notification(GuidGenerator.Create(), title, content, MessageType.BroadCast, level, _currentUser.Id.Value, _currentUser.UserName, tenantId: CurrentTenant?.Id);
// 发送集成事件
entity.AddCreatedNotificationLocalEvent(new CreatedNotificationLocalEvent(notificationEto));
await _notificationRepository.InsertAsync(entity);
}
/// <summary>
/// 发送警告广播消息
/// </summary>
/// <param name="title">标题</param>
/// <param name="content">消息内容</param>
public async Task SendBroadCastWarningMessageAsync(string title, string content)
{
var senderId = Guid.Empty;
if (_currentUser?.Id != null)
{
senderId = _currentUser.Id.Value;
}
var entity = new Notification(GuidGenerator.Create(), title, content, MessageType.BroadCast, MessageLevel.Warning, senderId, CurrentTenant.Id);
var notificationEto = ObjectMapper.Map<Notification, NotificationEto>(entity);
// 发送集成事件
entity.AddCreatedNotificationLocalEvent(new CreatedNotificationLocalEvent(notificationEto));
await _notificationRepository.InsertAsync(entity);
}
/// <summary>
/// 发送正常广播消息
/// </summary>
/// <param name="title">标题</param>
/// <param name="content">消息内容</param>
public async Task SendBroadCastInformationMessageAsync(string title, string content)
{
var senderId = Guid.Empty;
if (_currentUser?.Id != null)
{
senderId = _currentUser.Id.Value;
}
var entity = new Notification(GuidGenerator.Create(), title, content, MessageType.BroadCast, MessageLevel.Information, senderId, CurrentTenant.Id);
var notificationEto = ObjectMapper.Map<Notification, NotificationEto>(entity);
// 发送集成事件
entity.AddCreatedNotificationLocalEvent(new CreatedNotificationLocalEvent(notificationEto));
await _notificationRepository.InsertAsync(entity);
public async Task<NotificationDto> FindAsync(Guid id)
{
var notification = await _notificationRepository.FindAsync(id);
if (notification == null) throw new NotificationManagementDomainException(NotificationManagementErrorCodes.MessageNotExist);
return ObjectMapper.Map<Notification, NotificationDto>(notification);
}
/// <summary>
/// 发送错误广播消息
/// </summary>
/// <param name="title">标题</param>
/// <param name="content">消息内容</param>
public async Task SendBroadCastErrorMessageAsync(string title, string content)
public async Task<List<NotificationDto>> GetListAsync(List<Guid> ids)
{
var senderId = Guid.Empty;
if (_currentUser?.Id != null)
{
senderId = _currentUser.Id.Value;
}
var entity = new Notification(GuidGenerator.Create(), title, content, MessageType.BroadCast, MessageLevel.Error, senderId, CurrentTenant.Id);
var notificationEto = ObjectMapper.Map<Notification, NotificationEto>(entity);
entity.AddCreatedNotificationLocalEvent(new CreatedNotificationLocalEvent(notificationEto));
await _notificationRepository.InsertAsync(entity);
var notifications = await _notificationRepository.GetListAsync(ids);
return ObjectMapper.Map<List<Notification>, List<NotificationDto>>(notifications);
}
/// <summary>
@ -191,23 +104,21 @@ namespace Lion.AbpPro.NotificationManagement.Notifications
{
if (_currentUser is not { IsAuthenticated: true }) throw new AbpAuthorizationException();
var notification = await _notificationRepository.FindByIdAsync(id);
var notification = await _notificationRepository.FindAsync(id);
if (notification == null) throw new NotificationManagementDomainException(NotificationManagementErrorCodes.MessageNotExist);
if (notification.MessageType == MessageType.BroadCast)
if (notification.Read)
{
//如果类型是广播消息,用户设置为已读,在插入一条数据
notification.AddBroadCastNotificationSubscription(GuidGenerator.Create(), _currentUser.GetId(), Clock.Now);
return;
}
else
if (notification.MessageType == MessageType.BroadCast)
{
var notificationSubscription = notification.NotificationSubscriptions.FirstOrDefault(e => e.ReceiveId == _currentUser.GetId());
if (notificationSubscription == null)
throw new NotificationManagementDomainException(NotificationManagementErrorCodes.UserUnSubscription);
notificationSubscription.SetRead(Clock.Now);
return;
}
notification.SetRead(true, Clock.Now);
await _notificationRepository.UpdateAsync(notification);
}
}

36
aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Domain/Notifications/NotificationSubscriptionManager.cs

@ -0,0 +1,36 @@
using Lion.AbpPro.NotificationManagement.Notifications.Dtos;
namespace Lion.AbpPro.NotificationManagement.Notifications;
public class NotificationSubscriptionManager : NotificationManagementDomainService, INotificationSubscriptionManager
{
private readonly INotificationSubscriptionRepository _notificationSubscriptionRepository;
public NotificationSubscriptionManager(INotificationSubscriptionRepository notificationSubscriptionRepository)
{
_notificationSubscriptionRepository = notificationSubscriptionRepository;
}
public async Task SetReadAsync(Guid receiveUserId, string receiveUserName, Guid notificationId)
{
var subscription = await _notificationSubscriptionRepository.FindAsync(receiveUserId, notificationId);
if (subscription != null)
{
return;
}
subscription = new NotificationSubscription(GuidGenerator.Create(), notificationId, receiveUserId, receiveUserName, Clock.Now, true, CurrentTenant?.Id);
await _notificationSubscriptionRepository.InsertAsync(subscription);
}
public async Task<List<NotificationSubscriptionDto>> GetPagingListAsync(Guid notificationId, Guid? receiverUserId, string receiverUserName, DateTime? startReadTime, DateTime? endReadTime, int maxResultCount = 10, int skipCount = 0, CancellationToken cancellationToken = default)
{
var list = await _notificationSubscriptionRepository.GetPagingListAsync(notificationId, receiverUserId, receiverUserName, startReadTime, endReadTime, maxResultCount, skipCount, cancellationToken);
return ObjectMapper.Map<List<NotificationSubscription>, List<NotificationSubscriptionDto>>(list);
}
public async Task<long> GetPagingCountAsync(Guid notificationId, Guid? receiverUserId, string receiverUserName, DateTime? startReadTime, DateTime? endReadTime, CancellationToken cancellationToken = default)
{
return await _notificationSubscriptionRepository.GetPagingCountAsync(notificationId, receiverUserId, receiverUserName, startReadTime, endReadTime, cancellationToken);
}
}

2
aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.EntityFrameworkCore/EntityFrameworkCore/INotificationManagementDbContext.cs

@ -8,5 +8,7 @@ namespace Lion.AbpPro.NotificationManagement.EntityFrameworkCore
*/
DbSet<Notification> Notifications { get; set; }
DbSet<NotificationSubscription> NotificationSubscriptions { get; set; }
}
}

3
aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.EntityFrameworkCore/EntityFrameworkCore/NotificationManagementDbContext.cs

@ -13,7 +13,8 @@ namespace Lion.AbpPro.NotificationManagement.EntityFrameworkCore
}
public DbSet<Notification> Notifications { get; set; }
public DbSet<NotificationSubscription> NotificationSubscriptions { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);

10
aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.EntityFrameworkCore/EntityFrameworkCore/NotificationManagementDbContextModelCreatingExtensions.cs

@ -1,3 +1,5 @@
using Lion.AbpPro.NotificationManagement.Notifications.MaxLengths;
namespace Lion.AbpPro.NotificationManagement.EntityFrameworkCore
{
public static class NotificationManagementDbContextModelCreatingExtensions
@ -10,13 +12,19 @@ namespace Lion.AbpPro.NotificationManagement.EntityFrameworkCore
builder.Entity<Notification>(b =>
{
b.ToTable(NotificationManagementDbProperties.DbTablePrefix + "Notifications", NotificationManagementDbProperties.DbSchema);
b.HasMany(e => e.NotificationSubscriptions).WithOne().HasForeignKey(uc => uc.NotificationId).IsRequired();
b.Property(e => e.Title).IsRequired().HasMaxLength(NotificationMaxLengths.Length128);
b.Property(e => e.Content).IsRequired().HasMaxLength(NotificationMaxLengths.Length1024);
b.Property(e => e.SenderUserName).IsRequired().HasMaxLength(NotificationMaxLengths.Length128);
b.Property(e => e.ReceiveUserName).HasMaxLength(NotificationMaxLengths.Length128);
b.ConfigureByConvention();
});
builder.Entity<NotificationSubscription>(b =>
{
b.ToTable(NotificationManagementDbProperties.DbTablePrefix + "NotificationSubscriptions", NotificationManagementDbProperties.DbSchema);
b.Property(e => e.ReceiveUserName).HasMaxLength(NotificationMaxLengths.Length128);
b.HasIndex(e => e.NotificationId);
b.HasIndex(e => e.ReceiveUserId);
b.ConfigureByConvention();
});
}

10
aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.EntityFrameworkCore/EntityFrameworkCore/Notifications/EfCoreNotificationQueryableExtensions.cs

@ -1,10 +0,0 @@
namespace Lion.AbpPro.NotificationManagement.EntityFrameworkCore.Notifications
{
public static class EfCoreNotificationQueryableExtensions
{
public static IQueryable<Notification> IncludeDetails(this IQueryable<Notification> queryable, bool include = true)
{
return !include ? queryable : queryable.Include(e => e.NotificationSubscriptions);
}
}
}

72
aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.EntityFrameworkCore/EntityFrameworkCore/Notifications/EfCoreNotificationRepository.cs

@ -3,7 +3,7 @@ namespace Lion.AbpPro.NotificationManagement.EntityFrameworkCore.Notifications
/// <summary>
/// 消息通知 仓储Ef core 实现
/// </summary>
public partial class EfCoreNotificationRepository :
public class EfCoreNotificationRepository :
EfCoreRepository<INotificationManagementDbContext, Notification, Guid>,
INotificationRepository
{
@ -12,47 +12,67 @@ namespace Lion.AbpPro.NotificationManagement.EntityFrameworkCore.Notifications
{
}
/// <summary>
/// 查找用户消息
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public async Task<Notification> FindByIdAsync(Guid id)
{
return await (await GetDbSetAsync())
.IncludeDetails()
.Where(e => e.Id == id)
.FirstOrDefaultAsync();
}
public async Task<List<Notification>> GetPagingListAsync(
Guid? userId,
MessageType messageType,
string title,
string content,
Guid? senderUserId,
string senderUserName,
Guid? receiverUserId,
string receiverUserName,
bool? read,
DateTime? startReadTime,
DateTime? endReadTime,
MessageType? messageType,
int maxResultCount = 10,
int skipCount = 0,
CancellationToken cancellationToken = default)
{
return await (await GetDbSetAsync())
.IncludeDetails()
.Where(e => e.MessageType == messageType)
.WhereIf(userId.HasValue, e => e.NotificationSubscriptions.Any(s => s.ReceiveId == userId))
.WhereIf(title.IsNotNullOrWhiteSpace(), e => e.Title.Contains(title))
.WhereIf(content.IsNotNullOrWhiteSpace(), e => e.Content.Contains(content))
.WhereIf(senderUserId.HasValue, e => e.SenderUserId == senderUserId.Value)
.WhereIf(senderUserName.IsNotNullOrWhiteSpace(), e => e.SenderUserName == senderUserName)
.WhereIf(receiverUserId.HasValue, e => e.ReceiveUserId == receiverUserId.Value)
.WhereIf(receiverUserName.IsNotNullOrWhiteSpace(), e => e.ReceiveUserName == receiverUserName)
.WhereIf(read.HasValue, e => e.Read == read.Value)
.WhereIf(startReadTime.HasValue, e => e.ReadTime >= startReadTime.Value)
.WhereIf(endReadTime.HasValue, e => e.ReadTime <= endReadTime.Value)
.WhereIf(messageType.HasValue, e => e.MessageType == messageType.Value)
.OrderByDescending(e => e.CreationTime)
.PageBy(skipCount, maxResultCount)
.ToListAsync(GetCancellationToken(cancellationToken));
}
public async Task<long> GetPagingCountAsync(Guid? userId, MessageType messageType, CancellationToken cancellationToken = default)
public async Task<long> GetPagingCountAsync(
string title,
string content,
Guid? senderUserId,
string senderUserName,
Guid? receiverUserId,
string receiverUserName,
bool? read,
DateTime? startReadTime,
DateTime? endReadTime,
MessageType? messageType,
CancellationToken cancellationToken = default)
{
return await (await GetDbSetAsync())
.Where(e => e.MessageType == messageType)
.WhereIf(userId.HasValue, e => e.NotificationSubscriptions.Any(s => s.ReceiveId == userId))
.CountAsync(cancellationToken: cancellationToken);
.WhereIf(title.IsNotNullOrWhiteSpace(), e => e.Title.Contains(title))
.WhereIf(content.IsNotNullOrWhiteSpace(), e => e.Content.Contains(content))
.WhereIf(senderUserId.HasValue, e => e.SenderUserId == senderUserId.Value)
.WhereIf(senderUserName.IsNotNullOrWhiteSpace(), e => e.SenderUserName == senderUserName)
.WhereIf(receiverUserId.HasValue, e => e.ReceiveUserId == receiverUserId.Value)
.WhereIf(receiverUserName.IsNotNullOrWhiteSpace(), e => e.ReceiveUserName == receiverUserName)
.WhereIf(read.HasValue, e => e.Read == read.Value)
.WhereIf(startReadTime.HasValue, e => e.ReadTime >= startReadTime.Value)
.WhereIf(endReadTime.HasValue, e => e.ReadTime <= endReadTime.Value)
.WhereIf(messageType.HasValue, e => e.MessageType == messageType.Value)
.CountAsync(cancellationToken);
}
public override async Task<IQueryable<Notification>> WithDetailsAsync()
public async Task<List<Notification>> GetListAsync(List<Guid> ids)
{
return (await GetQueryableAsync()).IncludeDetails();
return await (await GetDbSetAsync()).Where(e => ids.Contains(e.Id)).ToListAsync();
}
}
}

39
aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.EntityFrameworkCore/EntityFrameworkCore/Notifications/EfCoreNotificationSubscriptionRepository.cs

@ -0,0 +1,39 @@
namespace Lion.AbpPro.NotificationManagement.EntityFrameworkCore.Notifications;
public class EfCoreNotificationSubscriptionRepository : EfCoreRepository<INotificationManagementDbContext, NotificationSubscription, Guid>, INotificationSubscriptionRepository
{
public EfCoreNotificationSubscriptionRepository([NotNull] IDbContextProvider<INotificationManagementDbContext> dbContextProvider) : base(dbContextProvider)
{
}
public async Task<List<NotificationSubscription>> GetPagingListAsync(Guid notificationId, Guid? receiverUserId, string receiverUserName, DateTime? startReadTime, DateTime? endReadTime, int maxResultCount = 10, int skipCount = 0, CancellationToken cancellationToken = default)
{
return await (await GetDbSetAsync())
.Where(e => e.NotificationId == notificationId)
.WhereIf(receiverUserId.HasValue, e => e.ReceiveUserId == receiverUserId.Value)
.WhereIf(receiverUserName.IsNotNullOrWhiteSpace(), e => e.ReceiveUserName == receiverUserName)
.WhereIf(startReadTime.HasValue, e => e.ReadTime >= startReadTime.Value)
.WhereIf(endReadTime.HasValue, e => e.ReadTime <= endReadTime.Value)
.OrderByDescending(e => e.CreationTime)
.PageBy(skipCount, maxResultCount)
.ToListAsync(GetCancellationToken(cancellationToken));
}
public async Task<long> GetPagingCountAsync(Guid notificationId, Guid? receiverUserId, string receiverUserName, DateTime? startReadTime, DateTime? endReadTime, CancellationToken cancellationToken = default)
{
return await (await GetDbSetAsync())
.Where(e => e.NotificationId == notificationId)
.WhereIf(receiverUserId.HasValue, e => e.ReceiveUserId == receiverUserId.Value)
.WhereIf(receiverUserName.IsNotNullOrWhiteSpace(), e => e.ReceiveUserName == receiverUserName)
.WhereIf(startReadTime.HasValue, e => e.ReadTime >= startReadTime.Value)
.WhereIf(endReadTime.HasValue, e => e.ReadTime <= endReadTime.Value)
.OrderByDescending(e => e.CreationTime)
.CountAsync(GetCancellationToken(cancellationToken));
}
public async Task<NotificationSubscription> FindAsync(Guid receiverUserId, Guid notificationId, CancellationToken cancellationToken = default)
{
return await (await GetDbSetAsync()).FirstOrDefaultAsync(e => e.ReceiveUserId == receiverUserId && e.NotificationId == notificationId, GetCancellationToken(cancellationToken));
}
}

27
aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.HttpApi/Notifications/NotificationController.cs

@ -13,29 +13,26 @@ namespace Lion.AbpPro.NotificationManagement.Notifications
/// <summary>
/// 分页获取用户普通文本消息
/// 分页获取文本消息
/// </summary>x
[HttpPost("Common")]
[SwaggerOperation(summary: "分页查询普通消息", Tags = new[] { "Notification" })]
public Task<PagedResultDto<PagingNotificationListOutput>>
GetPageCommonNotificationByUserIdAsync(
PagingNotificationListInput listInput)
[HttpPost("NotificationPage")]
[SwaggerOperation(summary: "分页查询消息", Tags = new[] { "Notification" })]
public Task<PagedResultDto<PagingNotificationOutput>> PageNotificationAsync(PagingNotificationInput input)
{
return _notificationAppService.GetPageCommonNotificationByUserIdAsync(listInput);
return _notificationAppService.PageNotificationAsync(input);
}
/// <summary>
/// 分页获取广播消息
/// </summary>
[HttpPost("BroadCast")]
[SwaggerOperation(summary: "分页查询广播消息", Tags = new[] { "Notification" })]
public Task<PagedResultDto<PagingNotificationListOutput>>
GetPageBroadCastNotificationByUserIdAsync(
PagingNotificationListInput listInput)
/// 分页获取广播消息已读人数
/// </summary>x
[HttpPost("NotificationSubscriptionPage")]
[SwaggerOperation(summary: "分页获取广播消息已读人数", Tags = new[] { "Notification" })]
public Task<PagedResultDto<PagingNotificationSubscriptionOutput>> PageNotificationSubscriptionAsync(PagingNotificationSubscriptionInput input)
{
return _notificationAppService.GetPageBroadCastNotificationByUserIdAsync(listInput);
return _notificationAppService.PageNotificationSubscriptionAsync(input);
}
[HttpPost("SendCommonWarningMessage")]
[SwaggerOperation(summary: "发送警告文本消息", Tags = new[] { "Notification" })]
public Task SendCommonWarningMessageAsync(SendCommonMessageInput input)

6
aspnet-core/services/host/Lion.AbpPro.HttpApi.Host/appsettings.json

@ -34,16 +34,16 @@
"CorsOrigins": "https://*.AbpPro.com,http://localhost:4200,http://localhost:3100"
},
"ConnectionStrings": {
"Default": "Data Source=43.139.143.143;Port=3306;Database=tenantdb;uid=root;pwd=1q2w3E*;charset=utf8mb4;Allow User Variables=true;AllowLoadLocalInfile=true"
"Default": "Data Source=localhost;Port=3306;Database=LionAbpProDB;uid=root;pwd=1q2w3E*;charset=utf8mb4;Allow User Variables=true;AllowLoadLocalInfile=true"
},
"Hangfire": {
"Redis": {
"Host": "43.139.143.143:6379,password=1q2w3E*",
"Host": "localhost:6379,password=1q2w3E*",
"DB": "2"
}
},
"Redis": {
"Configuration": "43.139.143.143:6379,password=1q2w3E*,defaultdatabase=5"
"Configuration": "localhost:6379,password=1q2w3E*,defaultdatabase=5"
},
"Jwt": {
"Audience": "Lion.AbpPro",

1
aspnet-core/services/src/Lion.AbpPro.EntityFrameworkCore/EntityFrameworkCore/AbpProDbContext.cs

@ -42,6 +42,7 @@ namespace Lion.AbpPro.EntityFrameworkCore
public DbSet<BackgroundJobRecord> BackgroundJobs { get; set; }
public DbSet<AuditLog> AuditLogs { get; set; }
public DbSet<Notification> Notifications { get; set; }
public DbSet<NotificationSubscription> NotificationSubscriptions { get; set; }
public DbSet<DataDictionary> DataDictionaries { get; set; }
public DbSet<Language> Languages { get; set; }
public DbSet<LanguageText> LanguageTexts { get; set; }

1991
aspnet-core/services/src/Lion.AbpPro.EntityFrameworkCore/Migrations/20231220041852_Init.Designer.cs

File diff suppressed because it is too large

2003
aspnet-core/services/src/Lion.AbpPro.EntityFrameworkCore/Migrations/20240404001711_AddTenantId.Designer.cs

File diff suppressed because it is too large

104
aspnet-core/services/src/Lion.AbpPro.EntityFrameworkCore/Migrations/20240404001711_AddTenantId.cs

@ -1,104 +0,0 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Lion.AbpPro.Migrations
{
/// <inheritdoc />
public partial class AddTenantId : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<string>(
name: "Providers",
table: "AbpSettingDefinitions",
type: "varchar(1024)",
maxLength: 1024,
nullable: true,
oldClrType: typeof(string),
oldType: "varchar(128)",
oldMaxLength: 128,
oldNullable: true)
.Annotation("MySql:CharSet", "utf8mb4")
.OldAnnotation("MySql:CharSet", "utf8mb4");
migrationBuilder.AlterColumn<string>(
name: "DefaultValue",
table: "AbpSettingDefinitions",
type: "varchar(2048)",
maxLength: 2048,
nullable: true,
oldClrType: typeof(string),
oldType: "varchar(256)",
oldMaxLength: 256,
oldNullable: true)
.Annotation("MySql:CharSet", "utf8mb4")
.OldAnnotation("MySql:CharSet", "utf8mb4");
migrationBuilder.AddColumn<Guid>(
name: "TenantId",
table: "AbpNotificationSubscriptions",
type: "char(36)",
nullable: true,
collation: "ascii_general_ci");
migrationBuilder.AddColumn<Guid>(
name: "TenantId",
table: "AbpNotifications",
type: "char(36)",
nullable: true,
collation: "ascii_general_ci");
migrationBuilder.AddColumn<Guid>(
name: "TenantId",
table: "AbpLanguages",
type: "char(36)",
nullable: true,
collation: "ascii_general_ci");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "TenantId",
table: "AbpNotificationSubscriptions");
migrationBuilder.DropColumn(
name: "TenantId",
table: "AbpNotifications");
migrationBuilder.DropColumn(
name: "TenantId",
table: "AbpLanguages");
migrationBuilder.AlterColumn<string>(
name: "Providers",
table: "AbpSettingDefinitions",
type: "varchar(128)",
maxLength: 128,
nullable: true,
oldClrType: typeof(string),
oldType: "varchar(1024)",
oldMaxLength: 1024,
oldNullable: true)
.Annotation("MySql:CharSet", "utf8mb4")
.OldAnnotation("MySql:CharSet", "utf8mb4");
migrationBuilder.AlterColumn<string>(
name: "DefaultValue",
table: "AbpSettingDefinitions",
type: "varchar(256)",
maxLength: 256,
nullable: true,
oldClrType: typeof(string),
oldType: "varchar(2048)",
oldMaxLength: 2048,
oldNullable: true)
.Annotation("MySql:CharSet", "utf8mb4")
.OldAnnotation("MySql:CharSet", "utf8mb4");
}
}
}

37
aspnet-core/services/src/Lion.AbpPro.EntityFrameworkCore/Migrations/20240404004344_RemoveLanguageIndex.cs

@ -1,37 +0,0 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Lion.AbpPro.Migrations
{
/// <inheritdoc />
public partial class RemoveLanguageIndex : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropIndex(
name: "IX_AbpLanguages_CultureName",
table: "AbpLanguages");
migrationBuilder.CreateIndex(
name: "IX_AbpLanguages_CultureName",
table: "AbpLanguages",
column: "CultureName");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropIndex(
name: "IX_AbpLanguages_CultureName",
table: "AbpLanguages");
migrationBuilder.CreateIndex(
name: "IX_AbpLanguages_CultureName",
table: "AbpLanguages",
column: "CultureName",
unique: true);
}
}
}

64
aspnet-core/services/src/Lion.AbpPro.EntityFrameworkCore/Migrations/20240404004344_RemoveLanguageIndex.Designer.cs → aspnet-core/services/src/Lion.AbpPro.EntityFrameworkCore/Migrations/20240418052548_1.0.0.Designer.cs

@ -12,8 +12,8 @@ using Volo.Abp.EntityFrameworkCore;
namespace Lion.AbpPro.Migrations
{
[DbContext(typeof(AbpProDbContext))]
[Migration("20240404004344_RemoveLanguageIndex")]
partial class RemoveLanguageIndex
[Migration("20240418052548_1.0.0")]
partial class _100
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
@ -368,17 +368,35 @@ namespace Lion.AbpPro.Migrations
b.Property<int>("MessageType")
.HasColumnType("int");
b.Property<Guid>("SenderId")
b.Property<bool>("Read")
.HasColumnType("tinyint(1)");
b.Property<DateTime?>("ReadTime")
.HasColumnType("datetime(6)");
b.Property<Guid?>("ReceiveUserId")
.HasColumnType("char(36)");
b.Property<string>("ReceiveUserName")
.HasMaxLength(128)
.HasColumnType("varchar(128)");
b.Property<Guid>("SenderUserId")
.HasColumnType("char(36)");
b.Property<string>("SenderUserName")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("varchar(128)");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.Property<string>("Title")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("varchar(256)");
.HasMaxLength(128)
.HasColumnType("varchar(128)");
b.HasKey("Id");
@ -390,6 +408,13 @@ namespace Lion.AbpPro.Migrations
b.Property<Guid>("Id")
.HasColumnType("char(36)");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.IsRequired()
.HasMaxLength(40)
.HasColumnType("varchar(40)")
.HasColumnName("ConcurrencyStamp");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
@ -406,6 +431,11 @@ namespace Lion.AbpPro.Migrations
.HasColumnType("datetime(6)")
.HasColumnName("DeletionTime");
b.Property<string>("ExtraProperties")
.IsRequired()
.HasColumnType("longtext")
.HasColumnName("ExtraProperties");
b.Property<bool>("IsDeleted")
.ValueGeneratedOnAdd()
.HasColumnType("tinyint(1)")
@ -426,12 +456,16 @@ namespace Lion.AbpPro.Migrations
b.Property<bool>("Read")
.HasColumnType("tinyint(1)");
b.Property<DateTime?>("ReadTime")
b.Property<DateTime>("ReadTime")
.HasColumnType("datetime(6)");
b.Property<Guid>("ReceiveId")
b.Property<Guid>("ReceiveUserId")
.HasColumnType("char(36)");
b.Property<string>("ReceiveUserName")
.HasMaxLength(128)
.HasColumnType("varchar(128)");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
@ -440,6 +474,8 @@ namespace Lion.AbpPro.Migrations
b.HasIndex("NotificationId");
b.HasIndex("ReceiveUserId");
b.ToTable("AbpNotificationSubscriptions", (string)null);
});
@ -1814,15 +1850,6 @@ namespace Lion.AbpPro.Migrations
.IsRequired();
});
modelBuilder.Entity("Lion.AbpPro.NotificationManagement.Notifications.Aggregates.NotificationSubscription", b =>
{
b.HasOne("Lion.AbpPro.NotificationManagement.Notifications.Aggregates.Notification", null)
.WithMany("NotificationSubscriptions")
.HasForeignKey("NotificationId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLogAction", b =>
{
b.HasOne("Volo.Abp.AuditLogging.AuditLog", null)
@ -1952,11 +1979,6 @@ namespace Lion.AbpPro.Migrations
b.Navigation("Details");
});
modelBuilder.Entity("Lion.AbpPro.NotificationManagement.Notifications.Aggregates.Notification", b =>
{
b.Navigation("NotificationSubscriptions");
});
modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLog", b =>
{
b.Navigation("Actions");

92
aspnet-core/services/src/Lion.AbpPro.EntityFrameworkCore/Migrations/20231220041852_Init.cs → aspnet-core/services/src/Lion.AbpPro.EntityFrameworkCore/Migrations/20240418052548_1.0.0.cs

@ -6,7 +6,7 @@ using Microsoft.EntityFrameworkCore.Migrations;
namespace Lion.AbpPro.Migrations
{
/// <inheritdoc />
public partial class Init : Migration
public partial class _100 : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
@ -223,6 +223,7 @@ namespace Lion.AbpPro.Migrations
columns: table => new
{
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
TenantId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"),
CultureName = table.Column<string>(type: "varchar(128)", maxLength: 128, nullable: false, comment: "语言名称")
.Annotation("MySql:CharSet", "utf8mb4"),
UiCultureName = table.Column<string>(type: "varchar(128)", maxLength: 128, nullable: false, comment: "Ui语言名称")
@ -304,13 +305,21 @@ namespace Lion.AbpPro.Migrations
columns: table => new
{
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
Title = table.Column<string>(type: "varchar(256)", maxLength: 256, nullable: false)
TenantId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"),
Title = table.Column<string>(type: "varchar(128)", maxLength: 128, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
Content = table.Column<string>(type: "varchar(1024)", maxLength: 1024, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
MessageType = table.Column<int>(type: "int", nullable: false),
MessageLevel = table.Column<int>(type: "int", nullable: false),
SenderId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
SenderUserId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
SenderUserName = table.Column<string>(type: "varchar(128)", maxLength: 128, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
ReceiveUserId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"),
ReceiveUserName = table.Column<string>(type: "varchar(128)", maxLength: 128, nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
Read = table.Column<bool>(type: "tinyint(1)", nullable: false),
ReadTime = table.Column<DateTime>(type: "datetime(6)", nullable: true),
ExtraProperties = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
ConcurrencyStamp = table.Column<string>(type: "varchar(40)", maxLength: 40, nullable: false)
@ -329,6 +338,36 @@ namespace Lion.AbpPro.Migrations
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "AbpNotificationSubscriptions",
columns: table => new
{
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
TenantId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"),
NotificationId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
ReceiveUserId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
ReceiveUserName = table.Column<string>(type: "varchar(128)", maxLength: 128, nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
Read = table.Column<bool>(type: "tinyint(1)", nullable: false),
ReadTime = table.Column<DateTime>(type: "datetime(6)", nullable: false),
ExtraProperties = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
ConcurrencyStamp = table.Column<string>(type: "varchar(40)", maxLength: 40, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
CreationTime = table.Column<DateTime>(type: "datetime(6)", nullable: false),
CreatorId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"),
LastModificationTime = table.Column<DateTime>(type: "datetime(6)", nullable: true),
LastModifierId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"),
IsDeleted = table.Column<bool>(type: "tinyint(1)", nullable: false, defaultValue: false),
DeleterId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"),
DeletionTime = table.Column<DateTime>(type: "datetime(6)", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_AbpNotificationSubscriptions", x => x.Id);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "AbpOrganizationUnits",
columns: table => new
@ -502,10 +541,10 @@ namespace Lion.AbpPro.Migrations
.Annotation("MySql:CharSet", "utf8mb4"),
Description = table.Column<string>(type: "varchar(512)", maxLength: 512, nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
DefaultValue = table.Column<string>(type: "varchar(256)", maxLength: 256, nullable: true)
DefaultValue = table.Column<string>(type: "varchar(2048)", maxLength: 2048, nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
IsVisibleToClients = table.Column<bool>(type: "tinyint(1)", nullable: false),
Providers = table.Column<string>(type: "varchar(128)", maxLength: 128, nullable: true)
Providers = table.Column<string>(type: "varchar(1024)", maxLength: 1024, nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
IsInherited = table.Column<bool>(type: "tinyint(1)", nullable: false),
IsEncrypted = table.Column<bool>(type: "tinyint(1)", nullable: false),
@ -724,35 +763,6 @@ namespace Lion.AbpPro.Migrations
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "AbpNotificationSubscriptions",
columns: table => new
{
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
NotificationId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
ReceiveId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
Read = table.Column<bool>(type: "tinyint(1)", nullable: false),
ReadTime = table.Column<DateTime>(type: "datetime(6)", nullable: true),
CreationTime = table.Column<DateTime>(type: "datetime(6)", nullable: false),
CreatorId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"),
LastModificationTime = table.Column<DateTime>(type: "datetime(6)", nullable: true),
LastModifierId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"),
IsDeleted = table.Column<bool>(type: "tinyint(1)", nullable: false, defaultValue: false),
DeleterId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"),
DeletionTime = table.Column<DateTime>(type: "datetime(6)", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_AbpNotificationSubscriptions", x => x.Id);
table.ForeignKey(
name: "FK_AbpNotificationSubscriptions_AbpNotifications_NotificationId",
column: x => x.NotificationId,
principalTable: "AbpNotifications",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "AbpOrganizationUnitRoles",
columns: table => new
@ -1054,8 +1064,7 @@ namespace Lion.AbpPro.Migrations
migrationBuilder.CreateIndex(
name: "IX_AbpLanguages_CultureName",
table: "AbpLanguages",
column: "CultureName",
unique: true);
column: "CultureName");
migrationBuilder.CreateIndex(
name: "IX_AbpLanguageTexts_TenantId_ResourceName_CultureName",
@ -1073,6 +1082,11 @@ namespace Lion.AbpPro.Migrations
table: "AbpNotificationSubscriptions",
column: "NotificationId");
migrationBuilder.CreateIndex(
name: "IX_AbpNotificationSubscriptions_ReceiveUserId",
table: "AbpNotificationSubscriptions",
column: "ReceiveUserId");
migrationBuilder.CreateIndex(
name: "IX_AbpOrganizationUnitRoles_RoleId_OrganizationUnitId",
table: "AbpOrganizationUnitRoles",
@ -1235,6 +1249,9 @@ namespace Lion.AbpPro.Migrations
migrationBuilder.DropTable(
name: "AbpLinkUsers");
migrationBuilder.DropTable(
name: "AbpNotifications");
migrationBuilder.DropTable(
name: "AbpNotificationSubscriptions");
@ -1289,9 +1306,6 @@ namespace Lion.AbpPro.Migrations
migrationBuilder.DropTable(
name: "AbpEntityChanges");
migrationBuilder.DropTable(
name: "AbpNotifications");
migrationBuilder.DropTable(
name: "AbpTenants");

60
aspnet-core/services/src/Lion.AbpPro.EntityFrameworkCore/Migrations/AbpProDbContextModelSnapshot.cs

@ -365,17 +365,35 @@ namespace Lion.AbpPro.Migrations
b.Property<int>("MessageType")
.HasColumnType("int");
b.Property<Guid>("SenderId")
b.Property<bool>("Read")
.HasColumnType("tinyint(1)");
b.Property<DateTime?>("ReadTime")
.HasColumnType("datetime(6)");
b.Property<Guid?>("ReceiveUserId")
.HasColumnType("char(36)");
b.Property<string>("ReceiveUserName")
.HasMaxLength(128)
.HasColumnType("varchar(128)");
b.Property<Guid>("SenderUserId")
.HasColumnType("char(36)");
b.Property<string>("SenderUserName")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("varchar(128)");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.Property<string>("Title")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("varchar(256)");
.HasMaxLength(128)
.HasColumnType("varchar(128)");
b.HasKey("Id");
@ -387,6 +405,13 @@ namespace Lion.AbpPro.Migrations
b.Property<Guid>("Id")
.HasColumnType("char(36)");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.IsRequired()
.HasMaxLength(40)
.HasColumnType("varchar(40)")
.HasColumnName("ConcurrencyStamp");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
@ -403,6 +428,11 @@ namespace Lion.AbpPro.Migrations
.HasColumnType("datetime(6)")
.HasColumnName("DeletionTime");
b.Property<string>("ExtraProperties")
.IsRequired()
.HasColumnType("longtext")
.HasColumnName("ExtraProperties");
b.Property<bool>("IsDeleted")
.ValueGeneratedOnAdd()
.HasColumnType("tinyint(1)")
@ -423,12 +453,16 @@ namespace Lion.AbpPro.Migrations
b.Property<bool>("Read")
.HasColumnType("tinyint(1)");
b.Property<DateTime?>("ReadTime")
b.Property<DateTime>("ReadTime")
.HasColumnType("datetime(6)");
b.Property<Guid>("ReceiveId")
b.Property<Guid>("ReceiveUserId")
.HasColumnType("char(36)");
b.Property<string>("ReceiveUserName")
.HasMaxLength(128)
.HasColumnType("varchar(128)");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
@ -437,6 +471,8 @@ namespace Lion.AbpPro.Migrations
b.HasIndex("NotificationId");
b.HasIndex("ReceiveUserId");
b.ToTable("AbpNotificationSubscriptions", (string)null);
});
@ -1811,15 +1847,6 @@ namespace Lion.AbpPro.Migrations
.IsRequired();
});
modelBuilder.Entity("Lion.AbpPro.NotificationManagement.Notifications.Aggregates.NotificationSubscription", b =>
{
b.HasOne("Lion.AbpPro.NotificationManagement.Notifications.Aggregates.Notification", null)
.WithMany("NotificationSubscriptions")
.HasForeignKey("NotificationId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLogAction", b =>
{
b.HasOne("Volo.Abp.AuditLogging.AuditLog", null)
@ -1949,11 +1976,6 @@ namespace Lion.AbpPro.Migrations
b.Navigation("Details");
});
modelBuilder.Entity("Lion.AbpPro.NotificationManagement.Notifications.Aggregates.Notification", b =>
{
b.Navigation("NotificationSubscriptions");
});
modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLog", b =>
{
b.Navigation("Actions");

18
vben28/src/hooks/web/useSignalR.ts

@ -72,21 +72,16 @@ export function useSignalR() {
message: message.title,
description: message.content,
});
} else if (message.messageLevel == 20) {
} if (message.messageLevel == 20) {
notification.info({
message: message.title,
description: message.content,
});
} else if (message.messageLevel == 30) {
} if (message.messageLevel == 30) {
notification.error({
message: message.title,
description: message.content,
});
} else {
notification.info({
message: message.title,
description: message.content,
});
}
}
@ -101,21 +96,16 @@ export function useSignalR() {
message: message.title,
description: message.content,
});
} else if (message.messageLevel == 20) {
} if (message.messageLevel == 20) {
notification.info({
message: message.title,
description: message.content,
});
} else if (message.messageLevel == 30) {
} if (message.messageLevel == 30) {
notification.error({
message: message.title,
description: message.content,
});
} else {
notification.info({
message: message.title,
description: message.content,
});
}
}

182
vben28/src/layouts/default/header/components/notify/NoticeList.vue

@ -5,33 +5,28 @@
<a-list-item-meta>
<template #title>
<div class="title">
<a-typography-paragraph
style="width: 100%; margin-bottom: 0 !important"
:ellipsis="titleRows > 0 ? { rows: titleRows, tooltip: item.title } : false"
:content="item.title"
/>
<div>
<a-typography-paragraph @click="handleTitleClick(item)" style="width: 100%; margin-bottom: 0 !important"
:ellipsis="titleRows > 0 ? { rows: titleRows, tooltip: item.title } : false" :content="item.title" />
<!-- <div>
<a-tag class="tag" :color="item.read ? 'green' : 'red'">
{{ item.read ? '已读' : '未读' }}
</a-tag>
<a-tag v-if="!item.read" class="tag" color="green" @click="onSetRead(item)">
{{ '标记为已读' }}
</a-tag>
</div>
</div> -->
</div>
</template>
<template #description>
<div>
<div class="description">
<a-typography-paragraph
style="width: 100%; margin-bottom: 0 !important"
:ellipsis="descRows > 0 ? { rows: descRows, tooltip: item.content } : false"
:content="item.content"
/>
<a-typography-paragraph style="width: 100%; margin-bottom: 0 !important"
:ellipsis="descRows > 0 ? { rows: descRows, tooltip: item.content } : false" :content="item.content"
@click="handleTitleClick(item)" />
</div>
<div class="datetime">
{{ formatToDateTime(item.creationTime) }}
{{ formatToDateTime(item.creationTime) }}
</div>
</div>
</template>
@ -41,95 +36,110 @@
</a-list>
</template>
<script lang="ts">
import { defineComponent, PropType } from 'vue';
import { setReadAsync } from './data';
import { useDesign } from '/@/hooks/web/useDesign';
import { List, Tag, Typography } from 'ant-design-vue';
import { PagingNotificationListOutput, SetReadInput } from '/@/services/ServiceProxies';
import { formatToDateTime } from '/@/utils/dateUtil';
export default defineComponent({
components: {
[List.name]: List,
[List.Item.name]: List.Item,
AListItemMeta: List.Item.Meta,
ATypographyParagraph: Typography.Paragraph,
[Tag.name]: Tag,
import { defineComponent, PropType } from 'vue';
import { setReadAsync } from './data';
import { useDesign } from '/@/hooks/web/useDesign';
import { List, Tag, Typography } from 'ant-design-vue';
import { PagingNotificationOutput, SetReadInput } from '/@/services/ServiceProxies';
import { formatToDateTime } from '/@/utils/dateUtil';
import { Modal } from 'ant-design-vue';
export default defineComponent({
components: {
[List.name]: List,
[List.Item.name]: List.Item,
AListItemMeta: List.Item.Meta,
ATypographyParagraph: Typography.Paragraph,
[Tag.name]: Tag,
},
props: {
list: {
type: Array as PropType<PagingNotificationOutput[]>,
default: () => [],
},
props: {
list: {
type: Array as PropType<PagingNotificationListOutput[]>,
default: () => [],
},
titleRows: {
type: Number,
default: 1,
},
descRows: {
type: Number,
default: 1,
},
titleRows: {
type: Number,
default: 1,
},
setup() {
const onSetRead = async (record: PagingNotificationListOutput) => {
let request = new SetReadInput();
request.id = record.id;
await setReadAsync(request);
record.read = true;
console.log(record);
};
const { prefixCls } = useDesign('header-notify-list');
return { prefixCls, onSetRead,formatToDateTime };
descRows: {
type: Number,
default: 1,
},
});
},
setup() {
const onSetRead = async (record: PagingNotificationOutput) => {
let request = new SetReadInput();
request.id = record.id;
await setReadAsync(request);
record.read = true;
};
const { prefixCls } = useDesign('header-notify-list');
async function readMessageAsync(item) {
let request = new SetReadInput();
request.id = item.id;
await setReadAsync(request);
}
async function handleTitleClick(item) {
console.log(item)
Modal.success({
okText: '朕已阅',
title: item.title,
content: item.content,
onOk: await readMessageAsync(item)
});
}
return { prefixCls, onSetRead, formatToDateTime, handleTitleClick };
},
});
</script>
<style lang="less" scoped>
@prefix-cls: ~'@{namespace}-header-notify-list';
@prefix-cls: ~'@{namespace}-header-notify-list';
.@{prefix-cls} {
&::-webkit-scrollbar {
display: none;
}
.@{prefix-cls} {
&::-webkit-scrollbar {
display: none;
}
::v-deep(.ant-pagination-disabled) {
display: inline-block !important;
}
::v-deep(.ant-pagination-disabled) {
display: inline-block !important;
}
&-item {
padding: 6px;
overflow: hidden;
cursor: pointer;
transition: all 0.3s;
&-item {
padding: 6px;
overflow: hidden;
cursor: pointer;
transition: all 0.3s;
.title {
margin-bottom: 8px;
.title {
margin-bottom: 8px;
font-weight: normal;
.extra {
float: right;
margin-top: -1.5px;
margin-right: 0;
font-weight: normal;
.extra {
float: right;
margin-top: -1.5px;
margin-right: 0;
.tag {
font-weight: normal;
.tag {
font-weight: normal;
}
}
.avatar {
margin-top: 4px;
}
}
.description {
font-size: 12px;
line-height: 18px;
}
.avatar {
margin-top: 4px;
}
.datetime {
margin-top: 4px;
font-size: 12px;
line-height: 18px;
}
.description {
font-size: 12px;
line-height: 18px;
}
.datetime {
margin-top: 4px;
font-size: 12px;
line-height: 18px;
}
}
}
}
</style>

29
vben28/src/layouts/default/header/components/notify/data.ts

@ -1,9 +1,12 @@
import {
NotificationServiceProxy,
PagingNotificationListOutput,
PagingNotificationListInput,
PagingNotificationListOutputPagedResultDto,
PagingNotificationOutput,
PagingNotificationInput,
PagingNotificationSubscriptionInput,
PagingNotificationOutputPagedResultDto,
} from '/@/services/ServiceProxies';
import { useUserStoreWithOut } from '/@/store/modules/user';
const userStore = useUserStoreWithOut();
export interface ListItem {
id: string;
avatar: string;
@ -23,7 +26,7 @@ export interface ListItem {
export interface TabItem {
key: string;
name: string;
list?: PagingNotificationListOutput[];
list?: PagingNotificationOutput[];
unreadlist?: ListItem[];
}
@ -40,21 +43,27 @@ export const tabListData: TabItem[] = [
},
];
export async function getTextAsync(): Promise<PagingNotificationListOutputPagedResultDto> {
let request = new PagingNotificationListInput();
export async function getTextAsync(): Promise<PagingNotificationOutputPagedResultDto> {
let request = new PagingNotificationInput();
request.pageSize = 5;
request.pageIndex = 1;
request.receiverUserId = userStore.getUserInfo.userId as string;
request.messageType = 20;
const _notificationServiceProxy = new NotificationServiceProxy();
return await _notificationServiceProxy.common(request);
return await _notificationServiceProxy.notificationPage(request);
}
export async function getBroadCastAsync(): Promise<PagingNotificationListOutputPagedResultDto> {
let request = new PagingNotificationListInput();
export async function getBroadCastAsync(): Promise<PagingNotificationOutputPagedResultDto> {
let request = new PagingNotificationInput();
request.pageSize = 5;
request.pageIndex = 1;
request.messageType = 10;
const _notificationServiceProxy = new NotificationServiceProxy();
return await _notificationServiceProxy.broadCast(request);
return await _notificationServiceProxy.notificationPage(request);
}
export async function setReadAsync(request) {
const _notificationServiceProxy = new NotificationServiceProxy();
await _notificationServiceProxy.read(request);
}

6
vben28/src/layouts/default/header/components/notify/index.vue

@ -25,7 +25,7 @@
import { defineComponent, computed } from 'vue';
import { Popover, Tabs, Badge } from 'ant-design-vue';
import { BellOutlined } from '@ant-design/icons-vue';
import { PagingNotificationListOutput } from '/@/services/ServiceProxies';
import { PagingNotificationOutput } from '/@/services/ServiceProxies';
import { tabListData } from './data';
import NoticeList from './NoticeList.vue';
import { useDesign } from '/@/hooks/web/useDesign';
@ -34,8 +34,8 @@
export default defineComponent({
components: { Popover, BellOutlined, Tabs, TabPane: Tabs.TabPane, Badge, NoticeList },
props: {
textMessage: Array as PropType<PagingNotificationListOutput[]>,
broadCastMessage: Array as PropType<PagingNotificationListOutput[]>,
textMessage: Array as PropType<PagingNotificationOutput[]>,
broadCastMessage: Array as PropType<PagingNotificationOutput[]>,
ff: string,
},
setup(props) {

10
vben28/src/layouts/default/header/index.vue

@ -84,7 +84,7 @@
import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent';
import { useLocale } from '/@/locales/useLocale';
import { useSignalR } from '/@/hooks/web/useSignalR';
import { PagingNotificationListOutput } from '/@/services/ServiceProxies';
import { PagingNotificationOutput } from '/@/services/ServiceProxies';
import {
getTextAsync,
getBroadCastAsync,
@ -181,8 +181,8 @@
onMounted(() => {
startConnect();
});
let textMessage: PagingNotificationListOutput[] = [];
let broadCastMessage: PagingNotificationListOutput[] = [];
let textMessage: PagingNotificationOutput[] = [];
let broadCastMessage: PagingNotificationOutput[] = [];
const notifiData = reactive({
textMessage,
broadCastMessage,
@ -190,10 +190,10 @@
const clickNotify = async () => {
notifiData.textMessage = (await (
await getTextAsync()
).items) as PagingNotificationListOutput[];
).items) as PagingNotificationOutput[];
notifiData.broadCastMessage = (await (
await getBroadCastAsync()
).items) as PagingNotificationListOutput[];
).items) as PagingNotificationOutput[];
console.log(notifiData);
};
return {

13
vben28/src/locales/lang/en/routes/admin.ts

@ -97,4 +97,17 @@ export default {
identitySecurityLog_CorrelationId: 'CorrelationId',
identitySecurityLog_ClientIpAddress: 'ClientIpAddress',
identitySecurityLog_CreationTime: 'LoginTime',
notificationManagement: 'NotificationManagement',
notificationSubscriptionManagement: 'NotificationSubscriptionManagement',
notificationManagement_title : 'Title',
notificationManagement_content : 'Content',
notificationManagement_read : 'Read',
notificationManagement_readTime : 'ReadTime',
notificationManagement_messageType : 'Type',
notificationManagement_messageLevel : 'Level',
notificationManagement_senderUserName : 'SenderUserName ',
notificationManagement_receiveUserName : 'ReceiveUserName',
notificationManagement_setRead : 'SetRead',
notificationManagement_sendNotification : 'SendNotification',
notificationManagement_sendNotificationSubscription : 'SendNotificationSubscription',
};

13
vben28/src/locales/lang/zh-CN/routes/admin.ts

@ -97,4 +97,17 @@ export default {
identitySecurityLog_CorrelationId: 'CorrelationId',
identitySecurityLog_ClientIpAddress: '客户端IP',
identitySecurityLog_CreationTime: '登录时间',
notificationManagement: '消息管理',
notificationSubscriptionManagement: '通告管理',
notificationManagement_title : '标题',
notificationManagement_content : '内容',
notificationManagement_read : '已读',
notificationManagement_readTime : '已读时间',
notificationManagement_messageType : '类型',
notificationManagement_messageLevel : '级别',
notificationManagement_senderUserName : '发送人',
notificationManagement_receiveUserName : '接收人',
notificationManagement_setRead : '设置已读',
notificationManagement_sendNotification : '发送消息',
notificationManagement_sendNotificationSubscription : '发送公告',
};

20
vben28/src/router/routes/modules/admin.ts

@ -114,6 +114,26 @@ const admin: AppRouteModule = {
policy: 'AbpIdentity.LanguageTexts',
},
},
{
path: 'notification',
name: 'notification',
component: () => import('/@/views/admin/notification/Index.vue'),
meta: {
title: t('routes.admin.notificationManagement'),
icon: 'ant-design:comment-outlined',
policy: 'AbpIdentity.NotificationManagement',
},
},
{
path: 'subscription',
name: 'subscription',
component: () => import('/@/views/admin/notification/Subscription.vue'),
meta: {
title: t('routes.admin.notificationSubscriptionManagement'),
icon: 'ant-design:customer-service-twotone',
policy: 'AbpIdentity.NotificationSubscriptionManagement',
},
},
],
};

566
vben28/src/services/ServiceProxies.ts

@ -2917,12 +2917,12 @@ export class NotificationServiceProxy extends ServiceProxyBase {
}
/**
*
*
* @param body (optional)
* @return Success
*/
common(body: PagingNotificationListInput | undefined , cancelToken?: CancelToken | undefined): Promise<PagingNotificationListOutputPagedResultDto> {
let url_ = this.baseUrl + "/Notification/Common";
notificationPage(body: PagingNotificationInput | undefined , cancelToken?: CancelToken | undefined): Promise<PagingNotificationOutputPagedResultDto> {
let url_ = this.baseUrl + "/Notification/NotificationPage";
url_ = url_.replace(/[?&]$/, "");
const content_ = JSON.stringify(body);
@ -2947,11 +2947,11 @@ export class NotificationServiceProxy extends ServiceProxyBase {
throw _error;
}
}).then((_response: AxiosResponse) => {
return this.transformResult(url_, _response, (_response: AxiosResponse) => this.processCommon(_response));
return this.transformResult(url_, _response, (_response: AxiosResponse) => this.processNotificationPage(_response));
});
}
protected processCommon(response: AxiosResponse): Promise<PagingNotificationListOutputPagedResultDto> {
protected processNotificationPage(response: AxiosResponse): Promise<PagingNotificationOutputPagedResultDto> {
const status = response.status;
let _headers: any = {};
if (response.headers && typeof response.headers === "object") {
@ -2965,8 +2965,8 @@ export class NotificationServiceProxy extends ServiceProxyBase {
const _responseText = response.data;
let result200: any = null;
let resultData200 = _responseText;
result200 = PagingNotificationListOutputPagedResultDto.fromJS(resultData200);
return Promise.resolve<PagingNotificationListOutputPagedResultDto>(result200);
result200 = PagingNotificationOutputPagedResultDto.fromJS(resultData200);
return Promise.resolve<PagingNotificationOutputPagedResultDto>(result200);
} else if (status === 403) {
const _responseText = response.data;
@ -3014,16 +3014,16 @@ export class NotificationServiceProxy extends ServiceProxyBase {
const _responseText = response.data;
return throwException("An unexpected server error occurred.", status, _responseText, _headers);
}
return Promise.resolve<PagingNotificationListOutputPagedResultDto>(null as any);
return Promise.resolve<PagingNotificationOutputPagedResultDto>(null as any);
}
/**
* 广
* 广
* @param body (optional)
* @return Success
*/
broadCast(body: PagingNotificationListInput | undefined , cancelToken?: CancelToken | undefined): Promise<PagingNotificationListOutputPagedResultDto> {
let url_ = this.baseUrl + "/Notification/BroadCast";
notificationSubscriptionPage(body: PagingNotificationSubscriptionInput | undefined , cancelToken?: CancelToken | undefined): Promise<PagingNotificationSubscriptionOutputPagedResultDto> {
let url_ = this.baseUrl + "/Notification/NotificationSubscriptionPage";
url_ = url_.replace(/[?&]$/, "");
const content_ = JSON.stringify(body);
@ -3048,11 +3048,11 @@ export class NotificationServiceProxy extends ServiceProxyBase {
throw _error;
}
}).then((_response: AxiosResponse) => {
return this.transformResult(url_, _response, (_response: AxiosResponse) => this.processBroadCast(_response));
return this.transformResult(url_, _response, (_response: AxiosResponse) => this.processNotificationSubscriptionPage(_response));
});
}
protected processBroadCast(response: AxiosResponse): Promise<PagingNotificationListOutputPagedResultDto> {
protected processNotificationSubscriptionPage(response: AxiosResponse): Promise<PagingNotificationSubscriptionOutputPagedResultDto> {
const status = response.status;
let _headers: any = {};
if (response.headers && typeof response.headers === "object") {
@ -3066,8 +3066,8 @@ export class NotificationServiceProxy extends ServiceProxyBase {
const _responseText = response.data;
let result200: any = null;
let resultData200 = _responseText;
result200 = PagingNotificationListOutputPagedResultDto.fromJS(resultData200);
return Promise.resolve<PagingNotificationListOutputPagedResultDto>(result200);
result200 = PagingNotificationSubscriptionOutputPagedResultDto.fromJS(resultData200);
return Promise.resolve<PagingNotificationSubscriptionOutputPagedResultDto>(result200);
} else if (status === 403) {
const _responseText = response.data;
@ -3115,7 +3115,7 @@ export class NotificationServiceProxy extends ServiceProxyBase {
const _responseText = response.data;
return throwException("An unexpected server error occurred.", status, _responseText, _headers);
}
return Promise.resolve<PagingNotificationListOutputPagedResultDto>(null as any);
return Promise.resolve<PagingNotificationSubscriptionOutputPagedResultDto>(null as any);
}
/**
@ -6846,6 +6846,114 @@ export class UsersServiceProxy extends ServiceProxyBase {
return Promise.resolve<IdentityUserDtoPagedResultDto>(null as any);
}
/**
*
* @param body (optional)
* @return Success
*/
list(body: PagingUserListInput | undefined , cancelToken?: CancelToken | undefined): Promise<IdentityUserDto[]> {
let url_ = this.baseUrl + "/Users/list";
url_ = url_.replace(/[?&]$/, "");
const content_ = JSON.stringify(body);
let options_ = <AxiosRequestConfig>{
data: content_,
method: "POST",
url: url_,
headers: {
"Content-Type": "application/json",
"Accept": "text/plain"
},
cancelToken
};
return this.transformOptions(options_).then(transformedOptions_ => {
return this.instance.request(transformedOptions_);
}).catch((_error: any) => {
if (isAxiosError(_error) && _error.response) {
return _error.response;
} else {
throw _error;
}
}).then((_response: AxiosResponse) => {
return this.transformResult(url_, _response, (_response: AxiosResponse) => this.processList(_response));
});
}
protected processList(response: AxiosResponse): Promise<IdentityUserDto[]> {
const status = response.status;
let _headers: any = {};
if (response.headers && typeof response.headers === "object") {
for (let k in response.headers) {
if (response.headers.hasOwnProperty(k)) {
_headers[k] = response.headers[k];
}
}
}
if (status === 200) {
const _responseText = response.data;
let result200: any = null;
let resultData200 = _responseText;
if (Array.isArray(resultData200)) {
result200 = [] as any;
for (let item of resultData200)
result200!.push(IdentityUserDto.fromJS(item));
}
else {
result200 = <any>null;
}
return Promise.resolve<IdentityUserDto[]>(result200);
} else if (status === 403) {
const _responseText = response.data;
let result403: any = null;
let resultData403 = _responseText;
result403 = RemoteServiceErrorResponse.fromJS(resultData403);
return throwException("Forbidden", status, _responseText, _headers, result403);
} else if (status === 401) {
const _responseText = response.data;
let result401: any = null;
let resultData401 = _responseText;
result401 = RemoteServiceErrorResponse.fromJS(resultData401);
return throwException("Unauthorized", status, _responseText, _headers, result401);
} else if (status === 400) {
const _responseText = response.data;
let result400: any = null;
let resultData400 = _responseText;
result400 = RemoteServiceErrorResponse.fromJS(resultData400);
return throwException("Bad Request", status, _responseText, _headers, result400);
} else if (status === 404) {
const _responseText = response.data;
let result404: any = null;
let resultData404 = _responseText;
result404 = RemoteServiceErrorResponse.fromJS(resultData404);
return throwException("Not Found", status, _responseText, _headers, result404);
} else if (status === 501) {
const _responseText = response.data;
let result501: any = null;
let resultData501 = _responseText;
result501 = RemoteServiceErrorResponse.fromJS(resultData501);
return throwException("Server Error", status, _responseText, _headers, result501);
} else if (status === 500) {
const _responseText = response.data;
let result500: any = null;
let resultData500 = _responseText;
result500 = RemoteServiceErrorResponse.fromJS(resultData500);
return throwException("Server Error", status, _responseText, _headers, result500);
} else if (status !== 200 && status !== 204) {
const _responseText = response.data;
return throwException("An unexpected server error occurred.", status, _responseText, _headers);
}
return Promise.resolve<IdentityUserDto[]>(null as any);
}
/**
*
* @param body (optional)
@ -15113,15 +15221,34 @@ export interface IPagingIdentitySecurityLogOutputPagedResultDto {
totalCount: number;
}
export class PagingNotificationListInput implements IPagingNotificationListInput {
export class PagingNotificationInput implements IPagingNotificationInput {
/** 当前页面.默认从1开始 */
pageIndex!: number;
/** 每页多少条.每页显示多少记录 */
pageSize!: number;
/** 跳过多少条 */
readonly skipCount!: number;
/** 标题 */
title!: string | undefined;
/** 内容 */
content!: string | undefined;
/** 发送者Id */
senderUserId!: string | undefined;
/** 发送者名称 */
senderUserName!: string | undefined;
/** 接受者Id */
receiverUserId!: string | undefined;
/** 接受者名称 */
receiverUserName!: string | undefined;
/** 是否已读 */
read!: boolean | undefined;
/** 已读开始时间 */
startReadTime!: dayjs.Dayjs | undefined;
/** 已读结束时间 */
endReadTime!: dayjs.Dayjs | undefined;
messageType!: MessageType;
constructor(data?: IPagingNotificationListInput) {
constructor(data?: IPagingNotificationInput) {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
@ -15135,12 +15262,22 @@ export class PagingNotificationListInput implements IPagingNotificationListInput
this.pageIndex = _data["pageIndex"];
this.pageSize = _data["pageSize"];
(<any>this).skipCount = _data["skipCount"];
this.title = _data["title"];
this.content = _data["content"];
this.senderUserId = _data["senderUserId"];
this.senderUserName = _data["senderUserName"];
this.receiverUserId = _data["receiverUserId"];
this.receiverUserName = _data["receiverUserName"];
this.read = _data["read"];
this.startReadTime = _data["startReadTime"] ? dayjs(_data["startReadTime"].toString()) : <any>undefined;
this.endReadTime = _data["endReadTime"] ? dayjs(_data["endReadTime"].toString()) : <any>undefined;
this.messageType = _data["messageType"];
}
}
static fromJS(data: any): PagingNotificationListInput {
static fromJS(data: any): PagingNotificationInput {
data = typeof data === 'object' ? data : {};
let result = new PagingNotificationListInput();
let result = new PagingNotificationInput();
result.init(data);
return result;
}
@ -15150,37 +15287,77 @@ export class PagingNotificationListInput implements IPagingNotificationListInput
data["pageIndex"] = this.pageIndex;
data["pageSize"] = this.pageSize;
data["skipCount"] = this.skipCount;
data["title"] = this.title;
data["content"] = this.content;
data["senderUserId"] = this.senderUserId;
data["senderUserName"] = this.senderUserName;
data["receiverUserId"] = this.receiverUserId;
data["receiverUserName"] = this.receiverUserName;
data["read"] = this.read;
data["startReadTime"] = this.startReadTime ? this.startReadTime.toLocaleString() : <any>undefined;
data["endReadTime"] = this.endReadTime ? this.endReadTime.toLocaleString() : <any>undefined;
data["messageType"] = this.messageType;
return data;
}
}
export interface IPagingNotificationListInput {
export interface IPagingNotificationInput {
/** 当前页面.默认从1开始 */
pageIndex: number;
/** 每页多少条.每页显示多少记录 */
pageSize: number;
/** 跳过多少条 */
skipCount: number;
/** 标题 */
title: string | undefined;
/** 内容 */
content: string | undefined;
/** 发送者Id */
senderUserId: string | undefined;
/** 发送者名称 */
senderUserName: string | undefined;
/** 接受者Id */
receiverUserId: string | undefined;
/** 接受者名称 */
receiverUserName: string | undefined;
/** 是否已读 */
read: boolean | undefined;
/** 已读开始时间 */
startReadTime: dayjs.Dayjs | undefined;
/** 已读结束时间 */
endReadTime: dayjs.Dayjs | undefined;
messageType: MessageType;
}
export class PagingNotificationListOutput implements IPagingNotificationListOutput {
export class PagingNotificationOutput implements IPagingNotificationOutput {
id!: string;
/** 租户id */
tenantId!: string | undefined;
/** 消息标题 */
title!: string | undefined;
/** 消息内容 */
content!: string | undefined;
messageType!: MessageType;
readonly messageTypeDescription!: string | undefined;
readonly messageTypeName!: string | undefined;
messageLevel!: MessageLevel;
readonly messageLevelDescription!: string | undefined;
readonly messageLevelName!: string | undefined;
/** 发送人 */
senderId!: string;
/** 创建时间 */
creationTime!: dayjs.Dayjs;
senderUserId!: string;
/** 发送人用户名 */
senderUserName!: string | undefined;
/**
广 */
receiveUserId!: string | undefined;
/**
广 */
receiveUserName!: string | undefined;
/** 是否已读 */
read!: boolean;
/** 已读时间 */
readTime!: dayjs.Dayjs | undefined;
creationTime!: dayjs.Dayjs;
constructor(data?: IPagingNotificationListOutput) {
constructor(data?: IPagingNotificationOutput) {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
@ -15192,21 +15369,26 @@ export class PagingNotificationListOutput implements IPagingNotificationListOutp
init(_data?: any) {
if (_data) {
this.id = _data["id"];
this.tenantId = _data["tenantId"];
this.title = _data["title"];
this.content = _data["content"];
this.messageType = _data["messageType"];
(<any>this).messageTypeDescription = _data["messageTypeDescription"];
(<any>this).messageTypeName = _data["messageTypeName"];
this.messageLevel = _data["messageLevel"];
(<any>this).messageLevelDescription = _data["messageLevelDescription"];
this.senderId = _data["senderId"];
this.creationTime = _data["creationTime"] ? dayjs(_data["creationTime"].toString()) : <any>undefined;
(<any>this).messageLevelName = _data["messageLevelName"];
this.senderUserId = _data["senderUserId"];
this.senderUserName = _data["senderUserName"];
this.receiveUserId = _data["receiveUserId"];
this.receiveUserName = _data["receiveUserName"];
this.read = _data["read"];
this.readTime = _data["readTime"] ? dayjs(_data["readTime"].toString()) : <any>undefined;
this.creationTime = _data["creationTime"] ? dayjs(_data["creationTime"].toString()) : <any>undefined;
}
}
static fromJS(data: any): PagingNotificationListOutput {
static fromJS(data: any): PagingNotificationOutput {
data = typeof data === 'object' ? data : {};
let result = new PagingNotificationListOutput();
let result = new PagingNotificationOutput();
result.init(data);
return result;
}
@ -15214,42 +15396,302 @@ export class PagingNotificationListOutput implements IPagingNotificationListOutp
toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
data["id"] = this.id;
data["tenantId"] = this.tenantId;
data["title"] = this.title;
data["content"] = this.content;
data["messageType"] = this.messageType;
data["messageTypeDescription"] = this.messageTypeDescription;
data["messageTypeName"] = this.messageTypeName;
data["messageLevel"] = this.messageLevel;
data["messageLevelDescription"] = this.messageLevelDescription;
data["senderId"] = this.senderId;
data["creationTime"] = this.creationTime ? this.creationTime.toLocaleString() : <any>undefined;
data["messageLevelName"] = this.messageLevelName;
data["senderUserId"] = this.senderUserId;
data["senderUserName"] = this.senderUserName;
data["receiveUserId"] = this.receiveUserId;
data["receiveUserName"] = this.receiveUserName;
data["read"] = this.read;
data["readTime"] = this.readTime ? this.readTime.toLocaleString() : <any>undefined;
data["creationTime"] = this.creationTime ? this.creationTime.toLocaleString() : <any>undefined;
return data;
}
}
export interface IPagingNotificationListOutput {
export interface IPagingNotificationOutput {
id: string;
/** 租户id */
tenantId: string | undefined;
/** 消息标题 */
title: string | undefined;
/** 消息内容 */
content: string | undefined;
messageType: MessageType;
messageTypeDescription: string | undefined;
messageTypeName: string | undefined;
messageLevel: MessageLevel;
messageLevelDescription: string | undefined;
messageLevelName: string | undefined;
/** 发送人 */
senderId: string;
/** 创建时间 */
senderUserId: string;
/** 发送人用户名 */
senderUserName: string | undefined;
/**
广 */
receiveUserId: string | undefined;
/**
广 */
receiveUserName: string | undefined;
/** 是否已读 */
read: boolean;
/** 已读时间 */
readTime: dayjs.Dayjs | undefined;
creationTime: dayjs.Dayjs;
}
export class PagingNotificationOutputPagedResultDto implements IPagingNotificationOutputPagedResultDto {
items!: PagingNotificationOutput[] | undefined;
totalCount!: number;
constructor(data?: IPagingNotificationOutputPagedResultDto) {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
(<any>this)[property] = (<any>data)[property];
}
}
}
init(_data?: any) {
if (_data) {
if (Array.isArray(_data["items"])) {
this.items = [] as any;
for (let item of _data["items"])
this.items!.push(PagingNotificationOutput.fromJS(item));
}
this.totalCount = _data["totalCount"];
}
}
static fromJS(data: any): PagingNotificationOutputPagedResultDto {
data = typeof data === 'object' ? data : {};
let result = new PagingNotificationOutputPagedResultDto();
result.init(data);
return result;
}
toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
if (Array.isArray(this.items)) {
data["items"] = [];
for (let item of this.items)
data["items"].push(item.toJSON());
}
data["totalCount"] = this.totalCount;
return data;
}
}
export interface IPagingNotificationOutputPagedResultDto {
items: PagingNotificationOutput[] | undefined;
totalCount: number;
}
export class PagingNotificationSubscriptionInput implements IPagingNotificationSubscriptionInput {
/** 当前页面.默认从1开始 */
pageIndex!: number;
/** 每页多少条.每页显示多少记录 */
pageSize!: number;
/** 跳过多少条 */
readonly skipCount!: number;
notificationId!: string;
/** 接受者Id */
receiverUserId!: string | undefined;
/** 接受者名称 */
receiverUserName!: string | undefined;
/** 是否已读 */
read!: boolean | undefined;
/** 已读开始时间 */
startReadTime!: dayjs.Dayjs | undefined;
/** 已读结束时间 */
endReadTime!: dayjs.Dayjs | undefined;
constructor(data?: IPagingNotificationSubscriptionInput) {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
(<any>this)[property] = (<any>data)[property];
}
}
}
init(_data?: any) {
if (_data) {
this.pageIndex = _data["pageIndex"];
this.pageSize = _data["pageSize"];
(<any>this).skipCount = _data["skipCount"];
this.notificationId = _data["notificationId"];
this.receiverUserId = _data["receiverUserId"];
this.receiverUserName = _data["receiverUserName"];
this.read = _data["read"];
this.startReadTime = _data["startReadTime"] ? dayjs(_data["startReadTime"].toString()) : <any>undefined;
this.endReadTime = _data["endReadTime"] ? dayjs(_data["endReadTime"].toString()) : <any>undefined;
}
}
static fromJS(data: any): PagingNotificationSubscriptionInput {
data = typeof data === 'object' ? data : {};
let result = new PagingNotificationSubscriptionInput();
result.init(data);
return result;
}
toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
data["pageIndex"] = this.pageIndex;
data["pageSize"] = this.pageSize;
data["skipCount"] = this.skipCount;
data["notificationId"] = this.notificationId;
data["receiverUserId"] = this.receiverUserId;
data["receiverUserName"] = this.receiverUserName;
data["read"] = this.read;
data["startReadTime"] = this.startReadTime ? this.startReadTime.toLocaleString() : <any>undefined;
data["endReadTime"] = this.endReadTime ? this.endReadTime.toLocaleString() : <any>undefined;
return data;
}
}
export interface IPagingNotificationSubscriptionInput {
/** 当前页面.默认从1开始 */
pageIndex: number;
/** 每页多少条.每页显示多少记录 */
pageSize: number;
/** 跳过多少条 */
skipCount: number;
notificationId: string;
/** 接受者Id */
receiverUserId: string | undefined;
/** 接受者名称 */
receiverUserName: string | undefined;
/** 是否已读 */
read: boolean | undefined;
/** 已读开始时间 */
startReadTime: dayjs.Dayjs | undefined;
/** 已读结束时间 */
endReadTime: dayjs.Dayjs | undefined;
}
export class PagingNotificationSubscriptionOutput implements IPagingNotificationSubscriptionOutput {
id!: string;
/** 租户id */
tenantId!: string | undefined;
/** 消息Id */
notificationId!: string;
/** 接收人id */
receiveUserId!: string;
/** 接收人用户名 */
receiveUserName!: string | undefined;
/** 是否已读 */
read!: boolean;
/** 已读时间 */
readTime!: dayjs.Dayjs;
/** 消息标题 */
title!: string | undefined;
/** 消息内容 */
content!: string | undefined;
messageType!: MessageType;
readonly messageTypeName!: string | undefined;
messageLevel!: MessageLevel;
readonly messageLevelName!: string | undefined;
/** 发送人 */
senderUserId!: string;
/** 发送人用户名 */
senderUserName!: string | undefined;
constructor(data?: IPagingNotificationSubscriptionOutput) {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
(<any>this)[property] = (<any>data)[property];
}
}
}
init(_data?: any) {
if (_data) {
this.id = _data["id"];
this.tenantId = _data["tenantId"];
this.notificationId = _data["notificationId"];
this.receiveUserId = _data["receiveUserId"];
this.receiveUserName = _data["receiveUserName"];
this.read = _data["read"];
this.readTime = _data["readTime"] ? dayjs(_data["readTime"].toString()) : <any>undefined;
this.title = _data["title"];
this.content = _data["content"];
this.messageType = _data["messageType"];
(<any>this).messageTypeName = _data["messageTypeName"];
this.messageLevel = _data["messageLevel"];
(<any>this).messageLevelName = _data["messageLevelName"];
this.senderUserId = _data["senderUserId"];
this.senderUserName = _data["senderUserName"];
}
}
static fromJS(data: any): PagingNotificationSubscriptionOutput {
data = typeof data === 'object' ? data : {};
let result = new PagingNotificationSubscriptionOutput();
result.init(data);
return result;
}
toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
data["id"] = this.id;
data["tenantId"] = this.tenantId;
data["notificationId"] = this.notificationId;
data["receiveUserId"] = this.receiveUserId;
data["receiveUserName"] = this.receiveUserName;
data["read"] = this.read;
data["readTime"] = this.readTime ? this.readTime.toLocaleString() : <any>undefined;
data["title"] = this.title;
data["content"] = this.content;
data["messageType"] = this.messageType;
data["messageTypeName"] = this.messageTypeName;
data["messageLevel"] = this.messageLevel;
data["messageLevelName"] = this.messageLevelName;
data["senderUserId"] = this.senderUserId;
data["senderUserName"] = this.senderUserName;
return data;
}
}
export interface IPagingNotificationSubscriptionOutput {
id: string;
/** 租户id */
tenantId: string | undefined;
/** 消息Id */
notificationId: string;
/** 接收人id */
receiveUserId: string;
/** 接收人用户名 */
receiveUserName: string | undefined;
/** 是否已读 */
read: boolean;
/** 已读时间 */
readTime: dayjs.Dayjs;
/** 消息标题 */
title: string | undefined;
/** 消息内容 */
content: string | undefined;
messageType: MessageType;
messageTypeName: string | undefined;
messageLevel: MessageLevel;
messageLevelName: string | undefined;
/** 发送人 */
senderUserId: string;
/** 发送人用户名 */
senderUserName: string | undefined;
}
export class PagingNotificationListOutputPagedResultDto implements IPagingNotificationListOutputPagedResultDto {
items!: PagingNotificationListOutput[] | undefined;
export class PagingNotificationSubscriptionOutputPagedResultDto implements IPagingNotificationSubscriptionOutputPagedResultDto {
items!: PagingNotificationSubscriptionOutput[] | undefined;
totalCount!: number;
constructor(data?: IPagingNotificationListOutputPagedResultDto) {
constructor(data?: IPagingNotificationSubscriptionOutputPagedResultDto) {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
@ -15263,15 +15705,15 @@ export class PagingNotificationListOutputPagedResultDto implements IPagingNotifi
if (Array.isArray(_data["items"])) {
this.items = [] as any;
for (let item of _data["items"])
this.items!.push(PagingNotificationListOutput.fromJS(item));
this.items!.push(PagingNotificationSubscriptionOutput.fromJS(item));
}
this.totalCount = _data["totalCount"];
}
}
static fromJS(data: any): PagingNotificationListOutputPagedResultDto {
static fromJS(data: any): PagingNotificationSubscriptionOutputPagedResultDto {
data = typeof data === 'object' ? data : {};
let result = new PagingNotificationListOutputPagedResultDto();
let result = new PagingNotificationSubscriptionOutputPagedResultDto();
result.init(data);
return result;
}
@ -15288,8 +15730,8 @@ export class PagingNotificationListOutputPagedResultDto implements IPagingNotifi
}
}
export interface IPagingNotificationListOutputPagedResultDto {
items: PagingNotificationListOutput[] | undefined;
export interface IPagingNotificationSubscriptionOutputPagedResultDto {
items: PagingNotificationSubscriptionOutput[] | undefined;
totalCount: number;
}
@ -16055,7 +16497,9 @@ export class SendCommonMessageInput implements ISendCommonMessageInput {
/** 消息内容 */
content!: string | undefined;
/** 发送人 */
receiveIds!: string[] | undefined;
receiveUserId!: string;
/** 发送人名称 */
receiveUserName!: string | undefined;
constructor(data?: ISendCommonMessageInput) {
if (data) {
@ -16070,11 +16514,8 @@ export class SendCommonMessageInput implements ISendCommonMessageInput {
if (_data) {
this.title = _data["title"];
this.content = _data["content"];
if (Array.isArray(_data["receiveIds"])) {
this.receiveIds = [] as any;
for (let item of _data["receiveIds"])
this.receiveIds!.push(item);
}
this.receiveUserId = _data["receiveUserId"];
this.receiveUserName = _data["receiveUserName"];
}
}
@ -16089,11 +16530,8 @@ export class SendCommonMessageInput implements ISendCommonMessageInput {
data = typeof data === 'object' ? data : {};
data["title"] = this.title;
data["content"] = this.content;
if (Array.isArray(this.receiveIds)) {
data["receiveIds"] = [];
for (let item of this.receiveIds)
data["receiveIds"].push(item);
}
data["receiveUserId"] = this.receiveUserId;
data["receiveUserName"] = this.receiveUserName;
return data;
}
}
@ -16104,7 +16542,9 @@ export interface ISendCommonMessageInput {
/** 消息内容 */
content: string | undefined;
/** 发送人 */
receiveIds: string[] | undefined;
receiveUserId: string;
/** 发送人名称 */
receiveUserName: string | undefined;
}
export class SetDataDictinaryDetailInput implements ISetDataDictinaryDetailInput {

65
vben28/src/views/admin/notification/CreateNotification.vue

@ -0,0 +1,65 @@
<template>
<BasicModal
:title="t('common.createText')"
:canFullscreen="false"
@ok="submit"
@cancel="cancel"
@register="registerNotificationModal"
>
<BasicForm @register="registerNotificationForm" />
</BasicModal>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { BasicModal, useModalInner } from '/@/components/Modal';
import { BasicForm, useForm } from '/@/components/Form/index';
import { createFormSchema, sendNotificationAsync } from './Index';
import { useI18n } from '/@/hooks/web/useI18n';
export default defineComponent({
name: 'CreateSubscription',
components: {
BasicModal,
BasicForm,
},
emits: ['reload', 'register'],
setup(_, { emit }) {
const { t } = useI18n();
const [registerNotificationForm, { getFieldsValue, resetFields, validate }] = useForm({
labelWidth: 120,
schemas: createFormSchema,
showActionButtonGroup: false,
});
const [registerNotificationModal, { changeOkLoading, closeModal }] = useModalInner();
const submit = async () => {
try {
const params = getFieldsValue();
changeOkLoading(true);
await validate();
await sendNotificationAsync({ params });
await resetFields();
emit('reload');
closeModal();
} finally {
changeOkLoading(false);
}
};
const cancel = () => {
resetFields();
closeModal();
};
return {
registerNotificationModal,
registerNotificationForm,
submit,
cancel,
t
};
},
});
</script>
<style lang="less" scoped></style>

65
vben28/src/views/admin/notification/CreateSubscription.vue

@ -0,0 +1,65 @@
<template>
<BasicModal
:title="t('routes.admin.notificationManagement_sendNotificationSubscription')"
:canFullscreen="false"
@ok="submit"
@cancel="cancel"
@register="registerNotificationModal"
>
<BasicForm @register="registerNotificationForm" />
</BasicModal>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { BasicModal, useModalInner } from '/@/components/Modal';
import { BasicForm, useForm } from '/@/components/Form/index';
import { createSubscriptionFormSchema, sendNotificationSubscriptionAsync } from './Index';
import { useI18n } from '/@/hooks/web/useI18n';
export default defineComponent({
name: 'CreateNotification',
components: {
BasicModal,
BasicForm,
},
emits: ['reload', 'register'],
setup(_, { emit }) {
const { t } = useI18n();
const [registerNotificationForm, { getFieldsValue, resetFields, validate }] = useForm({
labelWidth: 120,
schemas: createSubscriptionFormSchema,
showActionButtonGroup: false,
});
const [registerNotificationModal, { changeOkLoading, closeModal }] = useModalInner();
const submit = async () => {
try {
const params = getFieldsValue();
changeOkLoading(true);
await validate();
await sendNotificationSubscriptionAsync({ params });
await resetFields();
emit('reload');
closeModal();
} finally {
changeOkLoading(false);
}
};
const cancel = () => {
resetFields();
closeModal();
};
return {
registerNotificationModal,
registerNotificationForm,
submit,
cancel,
t
};
},
});
</script>
<style lang="less" scoped></style>

396
vben28/src/views/admin/notification/Index.ts

@ -0,0 +1,396 @@
import { FormSchema } from '/@/components/Table';
import { BasicColumn } from '/@/components/Table';
import {
NotificationServiceProxy,
PagingNotificationSubscriptionInput,
PagingNotificationInput,
PagingUserListInput,
UsersServiceProxy
} from '/@/services/ServiceProxies';
import { useI18n } from '/@/hooks/web/useI18n';
import { formatToDateTime, dateUtil } from '/@/utils/dateUtil';
const { t } = useI18n();
// 分页表格消息通知 BasicColumn
export const tableColumns: BasicColumn[] = [
{
title: t('routes.admin.notificationManagement_title'),
dataIndex: 'title',
width: 200,
},
{
title: t('routes.admin.notificationManagement_content'),
dataIndex: 'content',
},
// {
// title: t('routes.admin.notificationManagement_messageType'),
// dataIndex: 'messageTypeName',
// width: 100,
// },
{
title: t('routes.admin.notificationManagement_messageLevel'),
dataIndex: 'messageLevelName',
width: 100,
},
{
title: t('routes.admin.notificationManagement_senderUserName'),
dataIndex: 'senderUserName',
width: 100,
},
{
title: t('routes.admin.notificationManagement_receiveUserName'),
dataIndex: 'receiveUserName',
width: 100,
},
{
title: t('routes.admin.notificationManagement_read'),
dataIndex: 'read',
width: 100,
},
{
title: t('routes.admin.notificationManagement_readTime'),
dataIndex: 'readTime',
customRender: ({ text }) => {
return formatToDateTime(text);
},
width: 250,
},
];
// 分页查询消息通知 FormSchema
export const searchFormSchema: FormSchema[] = [
{
field: 'title',
label: t('routes.admin.notificationManagement_title'),
component: "Input",
colProps: { span: 4 }
},
{
field: 'content',
label: t('routes.admin.notificationManagement_content'),
component: "Input",
colProps: { span: 6 }
},
{
field: 'messageType',
label: t('routes.admin.notificationManagement_messageType'),
component: "Input",
required: true,
defaultValue: 20,
show: false,
colProps: { span: 18 }
},
{
field: 'messageLevel',
component: 'Select',
label: t('routes.admin.notificationManagement_messageLevel'),
colProps: {
span: 2,
},
componentProps: {
options: [
{
label: '警告',
value: 10,
},
{
label: '正常',
value: 20,
},
{
label: '错误',
value: 30,
},
],
},
},
{
field: 'read',
component: 'Select',
label: t('routes.admin.notificationManagement_read'),
colProps: {
span: 2,
},
componentProps: {
options: [
{
label: '是',
value: true,
},
{
label: '否',
value: false,
}
],
},
},
];
// 创建消息通知 FormSchema
export const createFormSchema: FormSchema[] = [
{
field: 'title',
label: t('routes.admin.notificationManagement_title'),
component: "Input",
required: true,
colProps: { span: 18 }
},
{
field: 'content',
label: t('routes.admin.notificationManagement_content'),
component: "Input",
required: true,
colProps: { span: 18 }
},
{
field: 'messageLevel',
component: 'Select',
label: t('routes.admin.notificationManagement_messageLevel'),
defaultValue: 20,
colProps: { span: 18 },
componentProps: {
options: [
{
label: '警告',
value: 10,
},
{
label: '正常',
value: 20,
},
{
label: '错误',
value: 30,
},
],
},
},
{
field: 'receiveUserId',
label: t('routes.admin.notificationManagement_receiveUserName'),
labelWidth: 120,
component: 'ApiSelect',
colProps: { span: 18 },
componentProps: ({ formModel }) => {
return {
api: getUserListAsync,
labelField: 'userName',
valueField: 'id',
showSearch: true,
optionFilterProp: 'label',
onChange: async (e: any, options : any) => {
formModel.receiveUserName = options.name;
},
};
},
},
{
field: 'receiveUserName',
label: 'ReceiveUserName',
component: "Input",
required: true,
show: false,
colProps: { span: 18 }
},
];
// 创建消息通知 FormSchema
export const createSubscriptionFormSchema: FormSchema[] = [
{
field: 'title',
label: t('routes.admin.notificationManagement_title'),
component: "Input",
required: true,
colProps: { span: 18 }
},
{
field: 'content',
label: t('routes.admin.notificationManagement_content'),
component: "Input",
required: true,
colProps: { span: 18 }
},
{
field: 'messageLevel',
component: 'Select',
label: t('routes.admin.notificationManagement_messageLevel'),
defaultValue: 20,
colProps: { span: 18 },
componentProps: {
options: [
{
label: '警告',
value: 10,
},
{
label: '正常',
value: 20,
},
{
label: '错误',
value: 30,
},
],
},
}
];
// 分页查询消息通知 FormSchema
export const searchSubscriptionFormSchema: FormSchema[] = [
{
field: 'title',
label: t('routes.admin.notificationManagement_title'),
component: "Input",
colProps: { span: 4 }
},
{
field: 'content',
label: t('routes.admin.notificationManagement_content'),
component: "Input",
colProps: { span: 6 }
},
{
field: 'messageType',
label: t('routes.admin.notificationManagement_messageType'),
component: "Input",
required: true,
defaultValue: 10,
show: false,
colProps: { span: 18 }
},
{
field: 'messageLevel',
component: 'Select',
label: t('routes.admin.notificationManagement_messageLevel'),
colProps: {
span: 2,
},
componentProps: {
options: [
{
label: '警告',
value: 10,
},
{
label: '正常',
value: 20,
},
{
label: '错误',
value: 30,
},
],
},
},
];
// 分页表格消息通知 BasicColumn
export const tableSubscriptionColumns: BasicColumn[] = [
{
title: t('routes.admin.notificationManagement_title'),
dataIndex: 'title',
width: 200,
},
{
title: t('routes.admin.notificationManagement_content'),
dataIndex: 'content',
},
// {
// title: t('routes.admin.notificationManagement_messageType'),
// dataIndex: 'messageTypeName',
// width: 100,
// },
{
title: t('routes.admin.notificationManagement_messageLevel'),
dataIndex: 'messageLevelName',
width: 100,
},
{
title: t('routes.admin.notificationManagement_senderUserName'),
dataIndex: 'senderUserName',
width: 100,
},
{
title: t('routes.admin.userManagement_createTime'),
dataIndex: 'creationTime',
customRender: ({ text }) => {
return dateUtil(text).format('YYYY-MM-DD HH:mm:ss');
},
width: 250,
},
];
/**
*
*/
export async function notificationPageAsync(params: PagingNotificationInput,
) {
const notificationServiceProxy = new NotificationServiceProxy();
return notificationServiceProxy.notificationPage(params);
}
/**
*
*/
export async function notificationSubscriptionPageAsync(params: PagingNotificationSubscriptionInput,
) {
const notificationServiceProxy = new NotificationServiceProxy();
return notificationServiceProxy.notificationSubscriptionPage(params);
}
export async function setReadAsync(request) {
const _notificationServiceProxy = new NotificationServiceProxy();
await _notificationServiceProxy.read(request);
}
/**
*
*/
export async function sendNotificationAsync({ params }) {
const notificationServiceProxy = new NotificationServiceProxy();
if (params.messageLevel == 10) {
await notificationServiceProxy.sendCommonWarningMessage(params);
}
if (params.messageLevel == 20) {
await notificationServiceProxy.sendCommonInformationMessage(params);
}
if (params.messageLevel == 30) {
await notificationServiceProxy.sendCommonErrorMessage(params);
}
}
/**
*
*/
export async function sendNotificationSubscriptionAsync({ params }) {
const notificationServiceProxy = new NotificationServiceProxy();
if (params.messageLevel == 10) {
await notificationServiceProxy.sendBroadCastWarningMessage(params);
}
if (params.messageLevel == 20) {
await notificationServiceProxy.sendBroadCastInformationMessage(params);
}
if (params.messageLevel == 30) {
await notificationServiceProxy.sendBroadCastErrorMessage(params);
}
}
/**
*
* @param params
* @returns
*/
export async function getUserListAsync(
params: PagingUserListInput,
) {
const _userServiceProxy = new UsersServiceProxy();
return _userServiceProxy.list(params);
}

107
vben28/src/views/admin/notification/Index.vue

@ -0,0 +1,107 @@
<template>
<div>
<BasicTable @register="registerTable" size="small">
<template #toolbar>
<a-button
preIcon="ant-design:plus-circle-outlined"
type="primary"
@click="openCreateNotificationModal"
>
{{t('routes.admin.notificationManagement_sendNotification')}}
</a-button>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'read'">
<Tag color='green' v-if="record.read">{{ record.read? '已读' : '未读' }}</Tag>
<Tag v-if="!record.read">{{ record.read? '已读' : '未读' }}</Tag>
</template>
<template v-if="column.key === 'messageLevelName'">
<Tag color='yellow' v-if="record.messageLevel ===10">{{ record.messageLevelName}}</Tag>
<Tag color='green' v-if="record.messageLevel === 20">{{ record.messageLevelName}}</Tag>
<Tag color='red' v-if="record.messageLevel === 30">{{ record.messageLevelName}}</Tag>
</template>
</template>
<template #action="{ record }">
<TableAction
:actions="[
{
icon: 'clarity:note-edit-line',
label: t('routes.admin.notificationManagement_setRead'),
onClick: handleSetRead.bind(null, record),
},
]"
/>
</template>
</BasicTable>
<CreateNotification
@register="registerCreateNotificationModal"
@reload="reload"
:bodyStyle="{ 'padding-top': '0' }"
/>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { BasicTable, TableAction, useTable } from '/@/components/Table';
import { Tag } from 'ant-design-vue';
import { tableColumns, searchFormSchema, notificationPageAsync,setReadAsync } from './Index';
import { useI18n } from '/@/hooks/web/useI18n';
import { SetReadInput } from '/@/services/ServiceProxies';
import CreateNotification from './CreateNotification.vue';
import { useModal } from '/@/components/Modal';
export default defineComponent({
name: 'Notification',
components: {
BasicTable,
TableAction,
Tag,
CreateNotification
},
setup() {
const { t } = useI18n();
// table
const [registerTable, { reload }] = useTable({
columns: tableColumns,
formConfig: {
labelWidth: 70,
schemas: searchFormSchema,
},
api: notificationPageAsync,
showTableSetting: true,
useSearchForm: true,
bordered: true,
canResize: true,
showIndexColumn: true,
immediate: true,
scroll: { x: true },
actionColumn: {
width: 220,
title: '操作',
dataIndex: 'action',
slots: { customRender: 'action' },
},
});
const [registerCreateNotificationModal, { openModal: openCreateNotificationModal }] = useModal();
async function handleSetRead(record: Recordable) {
let request = new SetReadInput();
request.id = record.id;
await setReadAsync(request);
await reload();
}
return {
registerTable,
reload,
t,
handleSetRead,
registerCreateNotificationModal,
openCreateNotificationModal
};
},
});
</script>

76
vben28/src/views/admin/notification/Subscription.vue

@ -0,0 +1,76 @@
<template>
<div>
<BasicTable @register="registerTable" size="small">
<template #toolbar>
<a-button
preIcon="ant-design:plus-circle-outlined"
type="primary"
@click="openCreateNotificationModal"
>
{{t('routes.admin.notificationManagement_sendNotificationSubscription')}}
</a-button>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'messageLevelName'">
<Tag color='yellow' v-if="record.messageLevel ===10">{{ record.messageLevelName}}</Tag>
<Tag color='green' v-if="record.messageLevel === 20">{{ record.messageLevelName}}</Tag>
<Tag color='red' v-if="record.messageLevel === 30">{{ record.messageLevelName}}</Tag>
</template>
</template>
</BasicTable>
<CreateSubscription
@register="registerCreateNotificationModal"
@reload="reload"
:bodyStyle="{ 'padding-top': '0' }"
/>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { BasicTable, TableAction, useTable } from '/@/components/Table';
import { Tag } from 'ant-design-vue';
import { tableSubscriptionColumns, searchSubscriptionFormSchema, notificationPageAsync } from './Index';
import { useI18n } from '/@/hooks/web/useI18n';
import CreateSubscription from './CreateSubscription.vue';
import { useModal } from '/@/components/Modal';
export default defineComponent({
name: 'Subscription',
components: {
BasicTable,
TableAction,
Tag,
CreateSubscription
},
setup() {
const { t } = useI18n();
// table
const [registerTable, { reload }] = useTable({
columns: tableSubscriptionColumns,
formConfig: {
labelWidth: 70,
schemas: searchSubscriptionFormSchema,
},
api: notificationPageAsync,
showTableSetting: true,
useSearchForm: true,
bordered: true,
canResize: true,
showIndexColumn: true,
immediate: true,
scroll: { x: true },
});
const [registerCreateNotificationModal, { openModal: openCreateNotificationModal }] = useModal();
return {
registerTable,
reload,
t,
registerCreateNotificationModal,
openCreateNotificationModal
};
},
});
</script>
Loading…
Cancel
Save