240 lines
8.9 KiB
C#
240 lines
8.9 KiB
C#
using DD.Persistence.Models;
|
||
using DD.Persistence.Models.Common;
|
||
using DD.Persistence.Models.Requests;
|
||
using DD.Persistence.Models.Requests.ChangeLog;
|
||
using DD.Persistence.Repositories;
|
||
using Microsoft.Extensions.Caching.Memory;
|
||
|
||
namespace DD.Persistence.API.Services;
|
||
|
||
/// <summary>
|
||
/// Сервис по работе с журналом изменений
|
||
/// </summary>
|
||
public class ChangeLogService
|
||
{
|
||
private readonly IMemoryCache memoryCache;
|
||
private readonly IChangeLogCommitRepository commitRepository;
|
||
private readonly IChangeLogRepository repository;
|
||
private readonly TimeSpan? AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(3);
|
||
|
||
/// <summary>
|
||
/// ctor
|
||
/// </summary>
|
||
/// <param name="memoryCache"></param>
|
||
/// <param name="commitRepository"></param>
|
||
/// <param name="repository"></param>
|
||
public ChangeLogService(
|
||
IMemoryCache memoryCache,
|
||
IChangeLogCommitRepository commitRepository,
|
||
IChangeLogRepository repository)
|
||
{
|
||
this.memoryCache = memoryCache;
|
||
this.commitRepository = commitRepository;
|
||
this.repository = repository;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Чтение или создание нового коммита
|
||
/// </summary>
|
||
/// <param name="idDiscriminator"></param>
|
||
/// <param name="request"></param>
|
||
/// <param name="token"></param>
|
||
/// <returns></returns>
|
||
private async Task<ChangeLogCommitDto> GetOrCreateCommitAsync(Guid idDiscriminator, CreateChangeLogCommitRequest request, CancellationToken token)
|
||
{
|
||
var key = (idDiscriminator, request.IdAuthor, request.Comment);
|
||
var commit = await memoryCache.GetOrCreateAsync(key, async (cacheEntry) =>
|
||
{
|
||
cacheEntry.AbsoluteExpirationRelativeToNow = AbsoluteExpirationRelativeToNow;
|
||
|
||
var commit = await commitRepository.Add(request, token);
|
||
|
||
return commit;
|
||
});
|
||
return commit!;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Добавление записи в журнал изменений
|
||
/// </summary>
|
||
/// <param name="idDiscriminator"></param>
|
||
/// <param name="request"></param>
|
||
/// <param name="dtos"></param>
|
||
/// <param name="token"></param>
|
||
/// <returns></returns>
|
||
public async Task<int> AddRange(Guid idDiscriminator, CreateChangeLogCommitRequest request, IEnumerable<ChangeLogValuesDto> dtos, CancellationToken token)
|
||
{
|
||
var commit = await GetOrCreateCommitAsync(idDiscriminator, request, token);
|
||
|
||
var result = await repository.AddRange(idDiscriminator, commit, dtos, token);
|
||
return result;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Пометить запись журнала изменений как удаленную
|
||
/// </summary>
|
||
/// <param name="idDiscriminator"></param>
|
||
/// <param name="ids"></param>
|
||
/// <param name="request"></param>
|
||
/// <param name="token"></param>
|
||
/// <returns></returns>
|
||
public async Task<int> MarkAsDeleted(Guid idDiscriminator, IEnumerable<Guid> ids, CreateChangeLogCommitRequest request, CancellationToken token)
|
||
{
|
||
var commit = await GetOrCreateCommitAsync(idDiscriminator, request, token);
|
||
|
||
var result = await repository.MarkAsDeleted(ids, commit, token);
|
||
|
||
return result;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Очистить старые и добавить новые записи в журнал изменений
|
||
/// </summary>
|
||
/// <param name="idDiscriminator"></param>
|
||
/// <param name="request"></param>
|
||
/// <param name="dtos"></param>
|
||
/// <param name="token"></param>
|
||
/// <returns></returns>
|
||
public async Task<int> ClearAndAddRange(Guid idDiscriminator, CreateChangeLogCommitRequest request, IEnumerable<ChangeLogValuesDto> dtos, CancellationToken token)
|
||
{
|
||
var commit = await GetOrCreateCommitAsync(idDiscriminator, request, token);
|
||
|
||
var result = await repository.ClearAndAddRange(idDiscriminator, commit, dtos, token);
|
||
|
||
return result;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Обновить записи в журнале изменений
|
||
/// </summary>
|
||
/// <param name="idDiscriminator"></param>
|
||
/// <param name="commitRequest"></param>
|
||
/// <param name="dtos"></param>
|
||
/// <param name="token"></param>
|
||
/// <returns></returns>
|
||
public async Task<int> UpdateRange(Guid idDiscriminator, CreateChangeLogCommitRequest commitRequest, IEnumerable<ChangeLogValuesDto> dtos, CancellationToken token)
|
||
{
|
||
var commit = await GetOrCreateCommitAsync(idDiscriminator, commitRequest, token);
|
||
var result = await repository.UpdateRange(commit, dtos, token);
|
||
|
||
return result;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Получение актуальных записей на определенный момент времени (с пагинацией)
|
||
/// </summary>
|
||
/// <param name="idDiscriminator"></param>
|
||
/// <param name="momentUtc"></param>
|
||
/// <param name="paginationRequest"></param>
|
||
/// <param name="token"></param>
|
||
/// <returns></returns>
|
||
public async Task<PaginationContainer<ChangeLogValuesDto>> GetByDate(
|
||
Guid idDiscriminator,
|
||
DateTimeOffset momentUtc,
|
||
PaginationRequest paginationRequest,
|
||
CancellationToken token)
|
||
{
|
||
var result = await repository.GetByDate(idDiscriminator, momentUtc, paginationRequest, token);
|
||
|
||
return result;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Получение измененных записей за период времени
|
||
/// </summary>
|
||
/// <param name="idDiscriminator"></param>
|
||
/// <param name="dateBegin"></param>
|
||
/// <param name="dateEnd"></param>
|
||
/// <param name="token"></param>
|
||
/// <returns></returns>
|
||
public async Task<IEnumerable<ChangeLogDto>> GetChangeLogForInterval(Guid idDiscriminator, DateTimeOffset dateBegin, DateTimeOffset dateEnd, CancellationToken token)
|
||
{
|
||
var result = await repository.GetChangeLogForInterval(idDiscriminator, dateBegin, dateEnd, token);
|
||
|
||
return result;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Получение списка дат, в которые происходили изменения (день, месяц, год, без времени)
|
||
/// </summary>
|
||
/// <param name="idDiscriminator"></param>
|
||
/// <param name="token"></param>
|
||
/// <returns></returns>
|
||
public async Task<IEnumerable<DateOnly>> GetDatesChange(Guid idDiscriminator, CancellationToken token)
|
||
{
|
||
var result = await repository.GetDatesChange(idDiscriminator, token);
|
||
|
||
return result;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Получить данные, начиная с определенной даты
|
||
/// </summary>
|
||
/// <param name="idDiscriminator"></param>
|
||
/// <param name="dateBegin"></param>
|
||
/// <param name="token"></param>
|
||
/// <returns></returns>
|
||
public async Task<IEnumerable<ChangeLogValuesDto>> GetGtDate(Guid idDiscriminator, DateTimeOffset dateBegin, CancellationToken token)
|
||
{
|
||
var result = await repository.GetGtDate(idDiscriminator, dateBegin, token);
|
||
|
||
return result;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Получить диапазон дат, для которых есть данные в репозитории
|
||
/// </summary>
|
||
/// <param name="idDiscriminator"></param>
|
||
/// <param name="token"></param>
|
||
/// <returns></returns>
|
||
public async Task<DatesRangeDto?> GetDatesRange(Guid idDiscriminator, CancellationToken token)
|
||
{
|
||
var result = await repository.GetDatesRange(idDiscriminator, token);
|
||
|
||
return result;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Метод получения статистики пользователя по количеству изменений в разрезе дней
|
||
/// </summary>
|
||
/// <param name="request"></param>
|
||
/// <param name="token"></param>
|
||
/// <returns></returns>
|
||
public async Task<IEnumerable<StatisticsChangeLogDto>> GetUserStatisticsCount(ChangeLogRequest request, CancellationToken token)
|
||
{
|
||
var result = await commitRepository.GetStatistics(request.DiscriminatorId, request.UserId, token);
|
||
|
||
return result;
|
||
|
||
|
||
}
|
||
|
||
/// <summary>
|
||
///
|
||
/// </summary>
|
||
/// <param name="request"></param>
|
||
/// <param name="token"></param>
|
||
/// <returns></returns>
|
||
/// <exception cref="NotImplementedException"></exception>
|
||
public async Task<IEnumerable<HistoryChangeLogDto>> GetHistoryChangeLog(ChangeLogRequest request, CancellationToken token)
|
||
{
|
||
var commits = await commitRepository.Get(request.DiscriminatorId, request.UserId, token);
|
||
|
||
if (!commits.Any())
|
||
return Enumerable.Empty<HistoryChangeLogDto>();
|
||
|
||
var result = commits.Select(c => new HistoryChangeLogDto()
|
||
{
|
||
ChangeLogItems = new List<ChangeLogDto>(),
|
||
Comment = c.Comment ?? string.Empty,
|
||
DateTime = c.Creation,
|
||
User = new UserDto() {
|
||
DisplayName = "",
|
||
Id = c.IdAuthor,
|
||
}
|
||
});
|
||
|
||
return result;
|
||
}
|
||
}
|