forked from ddrilling/AsbCloudServer
Рефакториг после ревью
1. Обновил классы модели и dto уведомления. 2. Удалил лишние сервисы. 3. Накатил новую миграцию. 4. Поправил репозиторий. 5. Поправил сервис уведомлений.
This commit is contained in:
parent
daa780a766
commit
b1d3da5f80
@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Text.Json.Serialization;
|
|
||||||
|
|
||||||
namespace AsbCloudApp.Data;
|
namespace AsbCloudApp.Data;
|
||||||
|
|
||||||
@ -33,60 +32,44 @@ public class NotificationDto : IId
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string Message { get; set; } = null!;
|
public string Message { get; set; } = null!;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Время жизни уведомления
|
|
||||||
/// </summary>
|
|
||||||
public TimeSpan TimeToLife { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Дата отправки уведомления
|
/// Дата отправки уведомления
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DateTime? SentDate { get; set; }
|
public DateTime? SentDate { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Состояния уведомления
|
/// Дата прочтения уведомления
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public NotificationState NotificationState { get; set; }
|
public DateTime? ReadDate { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Способ доставки уведомления
|
/// Состояние уведомления
|
||||||
|
/// 0 - Зарегистрировано,
|
||||||
|
/// 1 - Отправлено,
|
||||||
|
/// 2 - Прочитано
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public NotificationTransport NotificationTransport { get; set; }
|
public int IdState
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (SentDate is not null && ReadDate is not null)
|
||||||
|
return 2;
|
||||||
|
|
||||||
|
if (SentDate is not null)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Id типа доставки уведомления
|
||||||
|
/// 0 - SignalR
|
||||||
|
/// </summary>
|
||||||
|
public int IdTransportType { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// DTO категории уведомления
|
/// DTO категории уведомления
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public NotificationCategoryDto NotificationCategory { get; set; } = null!;
|
public NotificationCategoryDto NotificationCategory { get; set; } = null!;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Состояние уведомления
|
|
||||||
/// </summary>
|
|
||||||
[JsonConverter(typeof(JsonStringEnumConverter))]
|
|
||||||
public enum NotificationState
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Зарегистрировано
|
|
||||||
/// </summary>
|
|
||||||
Registered = 1,
|
|
||||||
/// <summary>
|
|
||||||
/// Отправлено
|
|
||||||
/// </summary>
|
|
||||||
Sent = 2,
|
|
||||||
/// <summary>
|
|
||||||
/// Прочитано
|
|
||||||
/// </summary>
|
|
||||||
Read = 3,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Способ отправки уведомления
|
|
||||||
/// </summary>
|
|
||||||
[JsonConverter(typeof(JsonStringEnumConverter))]
|
|
||||||
public enum NotificationTransport
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// SignalR
|
|
||||||
/// </summary>
|
|
||||||
SignalR = 1
|
|
||||||
}
|
|
@ -1,4 +1,3 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using AsbCloudApp.Data;
|
using AsbCloudApp.Data;
|
||||||
@ -12,18 +11,6 @@ namespace AsbCloudApp.Repositories;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public interface INotificationRepository : ICrudRepository<NotificationDto>
|
public interface INotificationRepository : ICrudRepository<NotificationDto>
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Получение не отправленных уведомлений
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="idUser"></param>
|
|
||||||
/// <param name="notificationTransport"></param>
|
|
||||||
/// <param name="cancellationToken"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
Task<IEnumerable<NotificationDto>> GetUnsentNotificationsAsync(int idUser,
|
|
||||||
NotificationTransport notificationTransport,
|
|
||||||
CancellationToken cancellationToken);
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получение уведомлений по параметрам
|
/// Получение уведомлений по параметрам
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
using System;
|
||||||
using AsbCloudApp.Data;
|
|
||||||
|
|
||||||
namespace AsbCloudApp.Requests;
|
namespace AsbCloudApp.Requests;
|
||||||
|
|
||||||
@ -9,8 +8,12 @@ namespace AsbCloudApp.Requests;
|
|||||||
public class NotificationRequest : RequestBase
|
public class NotificationRequest : RequestBase
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Способ отправки уведомления
|
/// Дата отправки уведомления
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Required]
|
public DateTime? SentDate { get; set; }
|
||||||
public NotificationTransport NotificationTransport { get; set; }
|
|
||||||
|
/// <summary>
|
||||||
|
/// Id типа доставки уведомления
|
||||||
|
/// </summary>
|
||||||
|
public int? IdTransportType { get; set; }
|
||||||
}
|
}
|
@ -1,16 +0,0 @@
|
|||||||
using AsbCloudApp.Data;
|
|
||||||
|
|
||||||
namespace AsbCloudApp.Services.Notifications;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Сервис для работы с отправителями уведомлений
|
|
||||||
/// </summary>
|
|
||||||
public interface INotificationSenderManager
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Метод получения нужного отправителя уведомлений
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="notificationTransport"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
INotificationSender? GetOrDefault(NotificationTransport notificationTransport);
|
|
||||||
}
|
|
@ -1,7 +1,6 @@
|
|||||||
using System;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using AsbCloudApp.Data;
|
using AsbCloudApp.Requests;
|
||||||
|
|
||||||
namespace AsbCloudApp.Services.Notifications;
|
namespace AsbCloudApp.Services.Notifications;
|
||||||
|
|
||||||
@ -17,16 +16,14 @@ public interface INotificationService
|
|||||||
/// <param name="idNotificationCategory"></param>
|
/// <param name="idNotificationCategory"></param>
|
||||||
/// <param name="title"></param>
|
/// <param name="title"></param>
|
||||||
/// <param name="message"></param>
|
/// <param name="message"></param>
|
||||||
/// <param name="timeToLife"></param>
|
/// <param name="idTransportType"></param>
|
||||||
/// <param name="notificationTransport"></param>
|
|
||||||
/// <param name="cancellationToken"></param>
|
/// <param name="cancellationToken"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task NotifyAsync(int idUser,
|
Task NotifyAsync(int idUser,
|
||||||
int idNotificationCategory,
|
int idNotificationCategory,
|
||||||
string title,
|
string title,
|
||||||
string message,
|
string message,
|
||||||
TimeSpan timeToLife,
|
int idTransportType,
|
||||||
NotificationTransport notificationTransport,
|
|
||||||
CancellationToken cancellationToken);
|
CancellationToken cancellationToken);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -44,10 +41,10 @@ public interface INotificationService
|
|||||||
/// Отправка уведомлений, которые не были отправлены
|
/// Отправка уведомлений, которые не были отправлены
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="idUser"></param>
|
/// <param name="idUser"></param>
|
||||||
/// <param name="notificationTransport"></param>
|
/// <param name="request"></param>
|
||||||
/// <param name="cancellationToken"></param>
|
/// <param name="cancellationToken"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task ResendNotificationAsync(int idUser,
|
Task ResendNotificationAsync(int idUser,
|
||||||
NotificationTransport notificationTransport,
|
NotificationRequest request,
|
||||||
CancellationToken cancellationToken);
|
CancellationToken cancellationToken);
|
||||||
}
|
}
|
@ -8,12 +8,12 @@ namespace AsbCloudApp.Services.Notifications;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Интерфейс для отправителя уведомлений
|
/// Интерфейс для отправителя уведомлений
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface INotificationSender
|
public interface INotificationTransportService
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Способ отправки уведомлений
|
/// Id типа доставки уведомления
|
||||||
/// </summary>
|
/// </summary>
|
||||||
NotificationTransport NotificationTransport { get; }
|
int IdTransportType { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Отправка одного уведомлений
|
/// Отправка одного уведомлений
|
8334
AsbCloudDb/Migrations/20230713085928_Update_Notification.Designer.cs
generated
Normal file
8334
AsbCloudDb/Migrations/20230713085928_Update_Notification.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
95
AsbCloudDb/Migrations/20230713085928_Update_Notification.cs
Normal file
95
AsbCloudDb/Migrations/20230713085928_Update_Notification.cs
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace AsbCloudDb.Migrations
|
||||||
|
{
|
||||||
|
public partial class Update_Notification : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "notification_state",
|
||||||
|
table: "t_notification");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "notification_transport",
|
||||||
|
table: "t_notification");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "time_to_life",
|
||||||
|
table: "t_notification");
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<int>(
|
||||||
|
name: "id_transport_type",
|
||||||
|
table: "t_notification",
|
||||||
|
type: "integer",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: 0,
|
||||||
|
comment: "Id типа доставки уведомления");
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<DateTime>(
|
||||||
|
name: "read_date",
|
||||||
|
table: "t_notification",
|
||||||
|
type: "timestamp with time zone",
|
||||||
|
nullable: true,
|
||||||
|
comment: "Дата прочтения уведомления");
|
||||||
|
|
||||||
|
migrationBuilder.AlterColumn<int>(
|
||||||
|
name: "id_category",
|
||||||
|
table: "t_help_page",
|
||||||
|
type: "integer",
|
||||||
|
nullable: false,
|
||||||
|
comment: "Id категории файла",
|
||||||
|
oldClrType: typeof(int),
|
||||||
|
oldType: "integer",
|
||||||
|
oldComment: "id категории файла");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "id_transport_type",
|
||||||
|
table: "t_notification");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "read_date",
|
||||||
|
table: "t_notification");
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<string>(
|
||||||
|
name: "notification_state",
|
||||||
|
table: "t_notification",
|
||||||
|
type: "text",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: "",
|
||||||
|
comment: "Состояние уведомления");
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<string>(
|
||||||
|
name: "notification_transport",
|
||||||
|
table: "t_notification",
|
||||||
|
type: "text",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: "",
|
||||||
|
comment: "Метод доставки уведомления");
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<TimeSpan>(
|
||||||
|
name: "time_to_life",
|
||||||
|
table: "t_notification",
|
||||||
|
type: "interval",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: new TimeSpan(0, 0, 0, 0, 0),
|
||||||
|
comment: "Время жизни уведомления");
|
||||||
|
|
||||||
|
migrationBuilder.AlterColumn<int>(
|
||||||
|
name: "id_category",
|
||||||
|
table: "t_help_page",
|
||||||
|
type: "integer",
|
||||||
|
nullable: false,
|
||||||
|
comment: "id категории файла",
|
||||||
|
oldClrType: typeof(int),
|
||||||
|
oldType: "integer",
|
||||||
|
oldComment: "Id категории файла");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1166,6 +1166,11 @@ namespace AsbCloudDb.Migrations
|
|||||||
.HasColumnName("id_notification_category")
|
.HasColumnName("id_notification_category")
|
||||||
.HasComment("Id категории уведомления");
|
.HasComment("Id категории уведомления");
|
||||||
|
|
||||||
|
b.Property<int>("IdTransportType")
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasColumnName("id_transport_type")
|
||||||
|
.HasComment("Id типа доставки уведомления");
|
||||||
|
|
||||||
b.Property<int>("IdUser")
|
b.Property<int>("IdUser")
|
||||||
.HasColumnType("integer")
|
.HasColumnType("integer")
|
||||||
.HasColumnName("id_user")
|
.HasColumnName("id_user")
|
||||||
@ -1177,28 +1182,16 @@ namespace AsbCloudDb.Migrations
|
|||||||
.HasColumnName("message")
|
.HasColumnName("message")
|
||||||
.HasComment("Сообщение уведомления");
|
.HasComment("Сообщение уведомления");
|
||||||
|
|
||||||
b.Property<string>("NotificationState")
|
b.Property<DateTime?>("ReadDate")
|
||||||
.IsRequired()
|
.HasColumnType("timestamp with time zone")
|
||||||
.HasColumnType("text")
|
.HasColumnName("read_date")
|
||||||
.HasColumnName("notification_state")
|
.HasComment("Дата прочтения уведомления");
|
||||||
.HasComment("Состояние уведомления");
|
|
||||||
|
|
||||||
b.Property<string>("NotificationTransport")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("text")
|
|
||||||
.HasColumnName("notification_transport")
|
|
||||||
.HasComment("Метод доставки уведомления");
|
|
||||||
|
|
||||||
b.Property<DateTime?>("SentDate")
|
b.Property<DateTime?>("SentDate")
|
||||||
.HasColumnType("timestamp with time zone")
|
.HasColumnType("timestamp with time zone")
|
||||||
.HasColumnName("sent_date")
|
.HasColumnName("sent_date")
|
||||||
.HasComment("Дата отправки уведомления");
|
.HasComment("Дата отправки уведомления");
|
||||||
|
|
||||||
b.Property<TimeSpan>("TimeToLife")
|
|
||||||
.HasColumnType("interval")
|
|
||||||
.HasColumnName("time_to_life")
|
|
||||||
.HasComment("Время жизни уведомления");
|
|
||||||
|
|
||||||
b.Property<string>("Title")
|
b.Property<string>("Title")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasColumnType("text")
|
.HasColumnType("text")
|
||||||
|
@ -24,17 +24,14 @@ public class Notification : IId
|
|||||||
[Column("message"), Comment("Сообщение уведомления")]
|
[Column("message"), Comment("Сообщение уведомления")]
|
||||||
public string Message { get; set; } = null!;
|
public string Message { get; set; } = null!;
|
||||||
|
|
||||||
[Column("time_to_life"), Comment("Время жизни уведомления")]
|
|
||||||
public TimeSpan TimeToLife { get; set; }
|
|
||||||
|
|
||||||
[Column("sent_date"), Comment("Дата отправки уведомления")]
|
[Column("sent_date"), Comment("Дата отправки уведомления")]
|
||||||
public DateTime? SentDate { get; set; }
|
public DateTime? SentDate { get; set; }
|
||||||
|
|
||||||
[Column("notification_state"), Comment("Состояние уведомления")]
|
[Column("read_date"), Comment("Дата прочтения уведомления")]
|
||||||
public string NotificationState { get; set; } = null!;
|
public DateTime? ReadDate { get; set; }
|
||||||
|
|
||||||
[Column("notification_transport"), Comment("Метод доставки уведомления")]
|
[Column("id_transport_type"), Comment("Id типа доставки уведомления")]
|
||||||
public string NotificationTransport { get; set; } = null!;
|
public int IdTransportType { get; set; }
|
||||||
|
|
||||||
[ForeignKey(nameof(IdNotificationCategory))]
|
[ForeignKey(nameof(IdNotificationCategory))]
|
||||||
public virtual NotificationCategory NotificationCategory { get; set; } = null!;
|
public virtual NotificationCategory NotificationCategory { get; set; } = null!;
|
||||||
|
@ -147,6 +147,8 @@ namespace AsbCloudInfrastructure
|
|||||||
|
|
||||||
services.AddTransient<INotificationService, NotificationService>();
|
services.AddTransient<INotificationService, NotificationService>();
|
||||||
services.AddTransient<INotificationRepository, NotificationRepository>();
|
services.AddTransient<INotificationRepository, NotificationRepository>();
|
||||||
|
services.AddTransient<ICrudRepository<NotificationCategoryDto>, CrudCacheRepositoryBase<NotificationCategoryDto,
|
||||||
|
NotificationCategory>>();
|
||||||
|
|
||||||
// admin crud services:
|
// admin crud services:
|
||||||
services.AddTransient<ICrudRepository<TelemetryDto>, CrudCacheRepositoryBase<TelemetryDto, Telemetry>>(s =>
|
services.AddTransient<ICrudRepository<TelemetryDto>, CrudCacheRepositoryBase<TelemetryDto, Telemetry>>(s =>
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@ -25,34 +23,19 @@ public class NotificationRepository : CrudCacheRepositoryBase<NotificationDto, N
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<NotificationDto>> GetUnsentNotificationsAsync(int idUser,
|
|
||||||
NotificationTransport notificationTransport,
|
|
||||||
CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
var notifications = (await GetCacheAsync(cancellationToken))
|
|
||||||
.Where(x => x.IdUser == idUser &&
|
|
||||||
x.NotificationTransport == notificationTransport.ToString() &&
|
|
||||||
x.SentDate == null);
|
|
||||||
|
|
||||||
return notifications.Select(Convert);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<PaginationContainer<NotificationDto>> GetNotificationsAsync(int idUser,
|
public async Task<PaginationContainer<NotificationDto>> GetNotificationsAsync(int idUser,
|
||||||
NotificationRequest request,
|
NotificationRequest request,
|
||||||
CancellationToken cancellationToken)
|
CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
request.Skip ??= 0;
|
var skip = request.Skip ?? 0;
|
||||||
request.Take ??= 10;
|
var take = request.Take ?? 10;
|
||||||
|
|
||||||
var query = dbContext.Notifications
|
var query = BuildQuery(idUser, request);
|
||||||
.Where(x => x.NotificationTransport == request.NotificationTransport.ToString() &&
|
|
||||||
x.IdUser == idUser &&
|
|
||||||
x.SentDate != null);
|
|
||||||
|
|
||||||
var result = new PaginationContainer<NotificationDto>()
|
var result = new PaginationContainer<NotificationDto>()
|
||||||
{
|
{
|
||||||
Skip = request.Skip.Value,
|
Skip = skip,
|
||||||
Take = request.Take.Value,
|
Take = take,
|
||||||
Count = await query.CountAsync(cancellationToken),
|
Count = await query.CountAsync(cancellationToken),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -60,9 +43,9 @@ public class NotificationRepository : CrudCacheRepositoryBase<NotificationDto, N
|
|||||||
return result;
|
return result;
|
||||||
|
|
||||||
result.Items = await query
|
result.Items = await query
|
||||||
.OrderBy(x => x.SentDate)
|
|
||||||
.SortBy(request.SortFields)
|
.SortBy(request.SortFields)
|
||||||
.SkipTake(request.Skip, request.Take)
|
.Skip(skip)
|
||||||
|
.Take(take)
|
||||||
.Include(x => x.NotificationCategory)
|
.Include(x => x.NotificationCategory)
|
||||||
.Select(x => x.Adapt<NotificationDto>())
|
.Select(x => x.Adapt<NotificationDto>())
|
||||||
.ToListAsync(cancellationToken);
|
.ToListAsync(cancellationToken);
|
||||||
@ -70,23 +53,20 @@ public class NotificationRepository : CrudCacheRepositoryBase<NotificationDto, N
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Notification Convert(NotificationDto src)
|
private IQueryable<Notification> BuildQuery(int? idUser,
|
||||||
|
NotificationRequest request)
|
||||||
{
|
{
|
||||||
var entity = src.Adapt<Notification>();
|
var query = dbContext.Notifications.AsQueryable();
|
||||||
|
|
||||||
entity.NotificationState = src.NotificationState.ToString();
|
if (!request.SentDate.HasValue)
|
||||||
entity.NotificationTransport = src.NotificationTransport.ToString();
|
query = query.Where(n => n.SentDate == null);
|
||||||
|
|
||||||
return entity;
|
if (idUser.HasValue)
|
||||||
}
|
query = query.Where(n => n.IdUser == idUser);
|
||||||
|
|
||||||
protected override NotificationDto Convert(Notification src)
|
if (request.IdTransportType.HasValue)
|
||||||
{
|
query = query.Where(n => n.IdTransportType == request.IdTransportType);
|
||||||
var dto = src.Adapt<NotificationDto>();
|
|
||||||
|
|
||||||
dto.NotificationState = (NotificationState)Enum.Parse(typeof(NotificationState), src.NotificationState);
|
return query;
|
||||||
dto.NotificationTransport = (NotificationTransport)Enum.Parse(typeof(NotificationTransport), src.NotificationTransport);
|
|
||||||
|
|
||||||
return dto;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,21 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using AsbCloudApp.Data;
|
|
||||||
using AsbCloudApp.Services.Notifications;
|
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure.Services.Notifications;
|
|
||||||
|
|
||||||
public class NotificationSenderManager : INotificationSenderManager
|
|
||||||
{
|
|
||||||
private readonly IEnumerable<INotificationSender> notificationSenders;
|
|
||||||
|
|
||||||
public NotificationSenderManager(IEnumerable<INotificationSender> notificationSenders)
|
|
||||||
{
|
|
||||||
this.notificationSenders = notificationSenders;
|
|
||||||
}
|
|
||||||
|
|
||||||
public INotificationSender? GetOrDefault(NotificationTransport notificationTransport)
|
|
||||||
{
|
|
||||||
return notificationSenders.FirstOrDefault(x => x.NotificationTransport == notificationTransport);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,54 +1,62 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using AsbCloudApp.Data;
|
using AsbCloudApp.Data;
|
||||||
using AsbCloudApp.Exceptions;
|
using AsbCloudApp.Exceptions;
|
||||||
using AsbCloudApp.Repositories;
|
using AsbCloudApp.Repositories;
|
||||||
|
using AsbCloudApp.Requests;
|
||||||
using AsbCloudApp.Services;
|
using AsbCloudApp.Services;
|
||||||
using AsbCloudApp.Services.Notifications;
|
using AsbCloudApp.Services.Notifications;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure.Services.Notifications;
|
namespace AsbCloudInfrastructure.Services.Notifications;
|
||||||
|
|
||||||
public class NotificationService : INotificationService
|
public class NotificationService : INotificationService
|
||||||
{
|
{
|
||||||
private readonly INotificationSenderManager notificationSenderManager;
|
private readonly ICrudRepository<NotificationCategoryDto> notificationCategoryRepository;
|
||||||
private readonly INotificationRepository notificationRepository;
|
private readonly INotificationRepository notificationRepository;
|
||||||
|
private readonly IServiceProvider serviceProvider;
|
||||||
|
|
||||||
public NotificationService(INotificationSenderManager notificationSenderManager,
|
public NotificationService(ICrudRepository<NotificationCategoryDto> notificationCategoryRepository,
|
||||||
INotificationRepository notificationRepository)
|
INotificationRepository notificationRepository,
|
||||||
|
IServiceProvider serviceProvider)
|
||||||
{
|
{
|
||||||
this.notificationSenderManager = notificationSenderManager;
|
this.notificationCategoryRepository = notificationCategoryRepository;
|
||||||
this.notificationRepository = notificationRepository;
|
this.notificationRepository = notificationRepository;
|
||||||
|
this.serviceProvider = serviceProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task NotifyAsync(int idUser,
|
public async Task NotifyAsync(int idUser,
|
||||||
int idNotificationCategory,
|
int idNotificationCategory,
|
||||||
string title,
|
string title,
|
||||||
string message,
|
string message,
|
||||||
TimeSpan timeToLife,
|
int idTransportType,
|
||||||
NotificationTransport notificationTransport,
|
|
||||||
CancellationToken cancellationToken)
|
CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
|
var notificationCategory = await notificationCategoryRepository
|
||||||
|
.GetOrDefaultAsync(idNotificationCategory, cancellationToken);
|
||||||
|
|
||||||
|
if(notificationCategory is null)
|
||||||
|
throw new ArgumentInvalidException("Категория уведомления не найдена", nameof(idNotificationCategory));
|
||||||
|
|
||||||
var notification = new NotificationDto()
|
var notification = new NotificationDto()
|
||||||
{
|
{
|
||||||
IdUser = idUser,
|
IdUser = idUser,
|
||||||
IdNotificationCategory = idNotificationCategory,
|
IdNotificationCategory = idNotificationCategory,
|
||||||
Title = title,
|
Title = title,
|
||||||
Message = message,
|
Message = message,
|
||||||
TimeToLife = timeToLife,
|
IdTransportType = idTransportType
|
||||||
NotificationTransport = notificationTransport,
|
|
||||||
NotificationState = NotificationState.Registered
|
|
||||||
};
|
};
|
||||||
|
|
||||||
notification.Id = await notificationRepository.InsertAsync(notification,
|
notification.Id = await notificationRepository.InsertAsync(notification,
|
||||||
cancellationToken);
|
cancellationToken);
|
||||||
|
|
||||||
var notificationSender = notificationSenderManager.GetOrDefault(notificationTransport);
|
notification.NotificationCategory = notificationCategory;
|
||||||
|
|
||||||
if(notificationSender is null)
|
var notificationTransportService = GetNotificationTransportService(idTransportType);
|
||||||
throw new ArgumentInvalidException("Метод отправки уведомления не найден", nameof(notificationTransport));
|
|
||||||
|
|
||||||
await notificationSender.SendAsync(notification, cancellationToken);
|
await notificationTransportService.SendAsync(notification, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task UpdateNotificationAsync(int idNotification,
|
public async Task UpdateNotificationAsync(int idNotification,
|
||||||
@ -59,25 +67,39 @@ public class NotificationService : INotificationService
|
|||||||
cancellationToken) ?? throw new ArgumentInvalidException("Уведомление не найдено",
|
cancellationToken) ?? throw new ArgumentInvalidException("Уведомление не найдено",
|
||||||
nameof(idNotification));
|
nameof(idNotification));
|
||||||
|
|
||||||
notification.NotificationState = isRead ? NotificationState.Read : NotificationState.Sent;
|
if (isRead)
|
||||||
|
{
|
||||||
|
if (notification.SentDate == null)
|
||||||
|
throw new ArgumentInvalidException("Уведомление не может быть прочитано", nameof(isRead));
|
||||||
|
|
||||||
|
notification.SentDate = DateTime.UtcNow;
|
||||||
|
}
|
||||||
|
|
||||||
await notificationRepository.UpdateAsync(notification,
|
await notificationRepository.UpdateAsync(notification,
|
||||||
cancellationToken);
|
cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task ResendNotificationAsync(int idUser,
|
public async Task ResendNotificationAsync(int idUser,
|
||||||
NotificationTransport notificationTransport,
|
NotificationRequest request,
|
||||||
CancellationToken cancellationToken)
|
CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var notifications = await notificationRepository.GetUnsentNotificationsAsync(idUser,
|
var result = await notificationRepository.GetNotificationsAsync(idUser,
|
||||||
notificationTransport,
|
request,
|
||||||
cancellationToken);
|
cancellationToken);
|
||||||
|
|
||||||
var notificationSender = notificationSenderManager.GetOrDefault(notificationTransport);
|
var notificationTransportService = GetNotificationTransportService(request.IdTransportType!.Value);
|
||||||
|
|
||||||
if(notificationSender is null)
|
await notificationTransportService.SendRangeAsync(result.Items, cancellationToken);
|
||||||
throw new ArgumentInvalidException("Отправитель уведомления не найден", nameof(notificationTransport));
|
}
|
||||||
|
|
||||||
await notificationSender.SendRangeAsync(notifications, cancellationToken);
|
private INotificationTransportService GetNotificationTransportService(int idTransportType)
|
||||||
|
{
|
||||||
|
var notificationTransportService = serviceProvider.GetServices<INotificationTransportService>()
|
||||||
|
.FirstOrDefault(s => s.IdTransportType == idTransportType);
|
||||||
|
|
||||||
|
if(notificationTransportService is null)
|
||||||
|
throw new ArgumentInvalidException("Доставщик уведомлений не найден", nameof(idTransportType));
|
||||||
|
|
||||||
|
return notificationTransportService;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,4 +1,3 @@
|
|||||||
using System;
|
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@ -34,29 +33,30 @@ public class NotificationController : ControllerBase
|
|||||||
/// Отправка уведомления
|
/// Отправка уведомления
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="idUser">Id пользователя</param>
|
/// <param name="idUser">Id пользователя</param>
|
||||||
/// <param name="idNotificationCategory">Id категории уведомления</param>
|
/// <param name="idNotificationCategory">Id категории уведомления. Допустимое значение параметра: 1</param>
|
||||||
/// <param name="title">Заголовок уведомления</param>
|
/// <param name="title">Заголовок уведомления</param>
|
||||||
/// <param name="message">Сообщение уведомления</param>
|
/// <param name="message">Сообщение уведомления</param>
|
||||||
/// <param name="timeToLife">Время жизни уведомления</param>
|
/// <param name="idNotificationTransport">Id типа доставки уведомления. Допустимое значение: 0</param>
|
||||||
/// <param name="notificationTransport">Способ отправки уведомления</param>
|
|
||||||
/// <param name="cancellationToken"></param>
|
/// <param name="cancellationToken"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[Route("send")]
|
[Route("send")]
|
||||||
public async Task<IActionResult> SendAsync([Required] int idUser,
|
public async Task<IActionResult> SendAsync([Required] int idUser,
|
||||||
[Required] int idNotificationCategory,
|
[Required]
|
||||||
|
[Range(minimum: 1, maximum: 1, ErrorMessage = "Id категории уведомления недоступно. Допустимые: 1")]
|
||||||
|
int idNotificationCategory,
|
||||||
[Required] string title,
|
[Required] string title,
|
||||||
[Required] string message,
|
[Required] string message,
|
||||||
[Required] TimeSpan timeToLife,
|
[Required]
|
||||||
[Required] NotificationTransport notificationTransport,
|
[Range(minimum: 0, maximum: 0, ErrorMessage = "Id способа отправки уведомления недоступно. Допустимые: 0")]
|
||||||
|
int idNotificationTransport,
|
||||||
CancellationToken cancellationToken)
|
CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
await notificationService.NotifyAsync(idUser,
|
await notificationService.NotifyAsync(idUser,
|
||||||
idNotificationCategory,
|
idNotificationCategory,
|
||||||
title,
|
title,
|
||||||
message,
|
message,
|
||||||
timeToLife,
|
idNotificationTransport,
|
||||||
notificationTransport,
|
|
||||||
cancellationToken);
|
cancellationToken);
|
||||||
|
|
||||||
return Ok();
|
return Ok();
|
||||||
|
@ -10,7 +10,6 @@ using System.IO;
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using AsbCloudApp.Services.Notifications;
|
using AsbCloudApp.Services.Notifications;
|
||||||
using AsbCloudInfrastructure.Services.Notifications;
|
|
||||||
using AsbCloudWebApi.SignalR.Services;
|
using AsbCloudWebApi.SignalR.Services;
|
||||||
using Microsoft.OpenApi.Any;
|
using Microsoft.OpenApi.Any;
|
||||||
|
|
||||||
@ -109,10 +108,9 @@ namespace AsbCloudWebApi
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void AddNotificationSenders(this IServiceCollection services)
|
public static void AddNotificationTransportServices(this IServiceCollection services)
|
||||||
{
|
{
|
||||||
services.AddSingleton<INotificationSenderManager, NotificationSenderManager>();
|
services.AddSingleton<INotificationTransportService, SignalRNotificationTransportService>();
|
||||||
services.AddSingleton<INotificationSender, SignalRNotificationSender>();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using AsbCloudApp.Data;
|
using AsbCloudApp.Requests;
|
||||||
using AsbCloudApp.Services.Notifications;
|
using AsbCloudApp.Services.Notifications;
|
||||||
using AsbCloudWebApi.SignalR.ConnectionManager;
|
using AsbCloudWebApi.SignalR.ConnectionManager;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
@ -21,7 +21,7 @@ public class NotificationHub : BaseHub
|
|||||||
this.notificationService = notificationService;
|
this.notificationService = notificationService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task OnConnected(int idUser)
|
public async Task OnConnected(int idUser, NotificationRequest request)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -30,7 +30,7 @@ public class NotificationHub : BaseHub
|
|||||||
connectionManager.AddConnection(idUser, connectionId);
|
connectionManager.AddConnection(idUser, connectionId);
|
||||||
|
|
||||||
await notificationService.ResendNotificationAsync(idUser,
|
await notificationService.ResendNotificationAsync(idUser,
|
||||||
NotificationTransport.SignalR,
|
request,
|
||||||
CancellationToken.None);
|
CancellationToken.None);
|
||||||
|
|
||||||
await base.OnConnectedAsync();
|
await base.OnConnectedAsync();
|
||||||
|
@ -11,13 +11,13 @@ using Microsoft.Extensions.DependencyInjection;
|
|||||||
|
|
||||||
namespace AsbCloudWebApi.SignalR.Services;
|
namespace AsbCloudWebApi.SignalR.Services;
|
||||||
|
|
||||||
public class SignalRNotificationSender : INotificationSender
|
public class SignalRNotificationTransportService : INotificationTransportService
|
||||||
{
|
{
|
||||||
private readonly IConnectionManager connectionManager;
|
private readonly IConnectionManager connectionManager;
|
||||||
private readonly IHubContext<NotificationHub> notificationHubContext;
|
private readonly IHubContext<NotificationHub> notificationHubContext;
|
||||||
private readonly IServiceProvider serviceProvider;
|
private readonly IServiceProvider serviceProvider;
|
||||||
|
|
||||||
public SignalRNotificationSender(IConnectionManager connectionManager,
|
public SignalRNotificationTransportService(IConnectionManager connectionManager,
|
||||||
IHubContext<NotificationHub> notificationHubContext,
|
IHubContext<NotificationHub> notificationHubContext,
|
||||||
IServiceProvider serviceProvider)
|
IServiceProvider serviceProvider)
|
||||||
{
|
{
|
||||||
@ -26,7 +26,7 @@ public class SignalRNotificationSender : INotificationSender
|
|||||||
this.serviceProvider = serviceProvider;
|
this.serviceProvider = serviceProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
public NotificationTransport NotificationTransport => NotificationTransport.SignalR;
|
public int IdTransportType => 0;
|
||||||
|
|
||||||
public async Task SendAsync(NotificationDto notification,
|
public async Task SendAsync(NotificationDto notification,
|
||||||
CancellationToken cancellationToken)
|
CancellationToken cancellationToken)
|
||||||
@ -37,16 +37,13 @@ public class SignalRNotificationSender : INotificationSender
|
|||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(connectionId))
|
if (!string.IsNullOrWhiteSpace(connectionId))
|
||||||
{
|
{
|
||||||
string message = $"IdNotification: {notification.Id}";
|
notification.SentDate = DateTime.UtcNow;
|
||||||
|
|
||||||
await notificationHubContext.Clients.Client(connectionId)
|
await notificationHubContext.Clients.Client(connectionId)
|
||||||
.SendAsync(method,
|
.SendAsync(method,
|
||||||
message,
|
notification,
|
||||||
cancellationToken);
|
cancellationToken);
|
||||||
|
|
||||||
notification.SentDate = DateTime.UtcNow;
|
|
||||||
notification.NotificationState = NotificationState.Sent;
|
|
||||||
|
|
||||||
var scope = serviceProvider.CreateScope();
|
var scope = serviceProvider.CreateScope();
|
||||||
|
|
||||||
var notificationRepository = scope.ServiceProvider.GetService<INotificationRepository>();
|
var notificationRepository = scope.ServiceProvider.GetService<INotificationRepository>();
|
@ -43,7 +43,7 @@ namespace AsbCloudWebApi
|
|||||||
|
|
||||||
services.AddInfrastructure(Configuration);
|
services.AddInfrastructure(Configuration);
|
||||||
|
|
||||||
services.AddNotificationSenders();
|
services.AddNotificationTransportServices();
|
||||||
|
|
||||||
services.AddJWTAuthentication();
|
services.AddJWTAuthentication();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user