Внести доработки в Setpoint и TechMessage
This commit is contained in:
parent
097b422310
commit
efed33e648
@ -6,7 +6,7 @@ using Persistence.Repository.Data;
|
|||||||
namespace Persistence.API.Controllers;
|
namespace Persistence.API.Controllers;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// <EFBFBD>אבמעא ס גנולוםם<D79D>לט האםם<D79D>לט
|
/// Работа с временными данными
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ApiController]
|
[ApiController]
|
||||||
[Authorize]
|
[Authorize]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using Microsoft.AspNetCore.Authorization;
|
using System.Net;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Persistence.Models;
|
using Persistence.Models;
|
||||||
using Persistence.Repositories;
|
using Persistence.Repositories;
|
||||||
@ -63,18 +64,47 @@ public class SetpointController : ControllerBase, ISetpointApi
|
|||||||
return Ok(result);
|
return Ok(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Получить диапазон дат, для которых есть данные в репозитории
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="token"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpGet("range")]
|
||||||
|
public async Task<ActionResult<DatesRangeDto>> GetDatesRangeAsync(CancellationToken token)
|
||||||
|
{
|
||||||
|
var result = await setpointRepository.GetDatesRangeAsync(token);
|
||||||
|
|
||||||
|
return Ok(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Получить порцию записей, начиная с заданной даты
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dateBegin"></param>
|
||||||
|
/// <param name="take"></param>
|
||||||
|
/// <param name="token"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpGet("part")]
|
||||||
|
public async Task<ActionResult<IEnumerable<SetpointLogDto>>> GetPart(DateTimeOffset dateBegin, int take, CancellationToken token)
|
||||||
|
{
|
||||||
|
var result = await setpointRepository.GetPart(dateBegin, take, token);
|
||||||
|
|
||||||
|
return Ok(result);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Сохранить уставку
|
/// Сохранить уставку
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="setpointKey"></param>
|
/// <param name="setpointKey"></param>
|
||||||
/// <param name="newValue"></param>
|
/// <param name="newValue"></param>
|
||||||
|
/// <param name="idUser"></param>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
public async Task<ActionResult<int>> Save(Guid setpointKey, object newValue, CancellationToken token)
|
[ProducesResponseType(typeof(int), (int)HttpStatusCode.OK)]
|
||||||
|
public async Task<IActionResult> Save(Guid setpointKey, object newValue, Guid idUser, CancellationToken token)
|
||||||
{
|
{
|
||||||
// ToDo: вычитка idUser
|
await setpointRepository.Save(setpointKey, newValue, idUser, token);
|
||||||
await setpointRepository.Save(setpointKey, newValue, 0, token);
|
|
||||||
|
|
||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using Microsoft.AspNetCore.Authorization;
|
using System.Net;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Persistence.Models;
|
using Persistence.Models;
|
||||||
using Persistence.Repositories;
|
using Persistence.Repositories;
|
||||||
@ -14,6 +15,14 @@ namespace Persistence.API.Controllers;
|
|||||||
public class TechMessagesController : ControllerBase
|
public class TechMessagesController : ControllerBase
|
||||||
{
|
{
|
||||||
private readonly ITechMessagesRepository techMessagesRepository;
|
private readonly ITechMessagesRepository techMessagesRepository;
|
||||||
|
private static readonly Dictionary<int, string> categories = new Dictionary<int, string>()
|
||||||
|
{
|
||||||
|
{ 0, "System" },
|
||||||
|
{ 1, "Авария" },
|
||||||
|
{ 2, "Предупреждение" },
|
||||||
|
{ 3, "Инфо" },
|
||||||
|
{ 4, "Прочее" }
|
||||||
|
};
|
||||||
|
|
||||||
public TechMessagesController(ITechMessagesRepository techMessagesRepository)
|
public TechMessagesController(ITechMessagesRepository techMessagesRepository)
|
||||||
{
|
{
|
||||||
@ -37,14 +46,14 @@ public class TechMessagesController : ControllerBase
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получить статистику по системам
|
/// Получить статистику по системам
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="importantId"></param>
|
|
||||||
/// <param name="autoDrillingSystem"></param>
|
/// <param name="autoDrillingSystem"></param>
|
||||||
|
/// <param name="categoryIds"></param>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpGet("statistics/{autoDrillingSystem}")]
|
[HttpGet("statistics")]
|
||||||
public async Task<ActionResult<int>> GetStatistics([FromRoute] string? autoDrillingSystem, int? importantId, CancellationToken token)
|
public async Task<ActionResult<IEnumerable<MessagesStatisticDto>>> GetStatistics([FromQuery] IEnumerable<string> autoDrillingSystem, [FromQuery] IEnumerable<int> categoryIds, CancellationToken token)
|
||||||
{
|
{
|
||||||
var result = await techMessagesRepository.GetStatistics(importantId, autoDrillingSystem, token);
|
var result = await techMessagesRepository.GetStatistics(autoDrillingSystem, categoryIds, token);
|
||||||
|
|
||||||
return Ok(result);
|
return Ok(result);
|
||||||
}
|
}
|
||||||
@ -55,13 +64,41 @@ public class TechMessagesController : ControllerBase
|
|||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpGet("systems")]
|
[HttpGet("systems")]
|
||||||
public async Task<ActionResult<IEnumerable<string>>> GetSystems(CancellationToken token)
|
public async Task<ActionResult<Dictionary<string, int>>> GetSystems(CancellationToken token)
|
||||||
{
|
{
|
||||||
var result = await techMessagesRepository.GetSystems(token);
|
var result = await techMessagesRepository.GetSystems(token);
|
||||||
|
|
||||||
return Ok(result);
|
return Ok(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Получить диапазон дат, для которых есть данные в репозитории
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="token"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpGet("range")]
|
||||||
|
public async Task<ActionResult<DatesRangeDto>> GetDatesRangeAsync(CancellationToken token)
|
||||||
|
{
|
||||||
|
var result = await techMessagesRepository.GetDatesRangeAsync(token);
|
||||||
|
|
||||||
|
return Ok(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Получить порцию записей, начиная с заданной даты
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dateBegin"></param>
|
||||||
|
/// <param name="take"></param>
|
||||||
|
/// <param name="token"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpGet("part")]
|
||||||
|
public async Task<ActionResult<IEnumerable<SetpointLogDto>>> GetPart(DateTimeOffset dateBegin, int take, CancellationToken token)
|
||||||
|
{
|
||||||
|
var result = await techMessagesRepository.GetPart(dateBegin, take, token);
|
||||||
|
|
||||||
|
return Ok(result);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Добавить новые технологические сообщения
|
/// Добавить новые технологические сообщения
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -69,9 +106,16 @@ public class TechMessagesController : ControllerBase
|
|||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
public async Task<ActionResult<int>> InsertRange([FromBody] IEnumerable<TechMessageDto> dtos, CancellationToken token)
|
[ProducesResponseType(typeof(int), (int)HttpStatusCode.Created)]
|
||||||
|
public async Task<IActionResult> InsertRange([FromBody] IEnumerable<TechMessageDto> dtos, CancellationToken token)
|
||||||
{
|
{
|
||||||
var result = await techMessagesRepository.InsertRange(dtos, token);
|
var userId = User.GetUserId<Guid>();
|
||||||
|
foreach (var dto in dtos)
|
||||||
|
{
|
||||||
|
dto.UserId = userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = await techMessagesRepository.InsertRange(dtos, token);
|
||||||
|
|
||||||
return CreatedAtAction(nameof(InsertRange), result);
|
return CreatedAtAction(nameof(InsertRange), result);
|
||||||
}
|
}
|
||||||
@ -83,15 +127,6 @@ public class TechMessagesController : ControllerBase
|
|||||||
[HttpGet("categories")]
|
[HttpGet("categories")]
|
||||||
public ActionResult<Dictionary<int, string>> GetImportantCategories()
|
public ActionResult<Dictionary<int, string>> GetImportantCategories()
|
||||||
{
|
{
|
||||||
var result = new Dictionary<int, string>()
|
return Ok(categories);
|
||||||
{
|
|
||||||
{ 0, "System" },
|
|
||||||
{ 1, "Авария" },
|
|
||||||
{ 2, "Предупреждение" },
|
|
||||||
{ 3, "Инфо" },
|
|
||||||
{ 4, "Прочее" }
|
|
||||||
};
|
|
||||||
|
|
||||||
return Ok(result);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -19,7 +19,7 @@ public class TimeSeriesController<TDto> : ControllerBase, ITimeSeriesDataApi<TDt
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Ïîëó÷èòü ñïèñîê îáúåêòîâ, óäîâëåòâîðÿþùèé äèàïàçîíó äàò
|
/// Получить список объектов, удовлетворяющий диапазону дат
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="dateBegin"></param>
|
/// <param name="dateBegin"></param>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
@ -28,24 +28,24 @@ public class TimeSeriesController<TDto> : ControllerBase, ITimeSeriesDataApi<TDt
|
|||||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||||
public async Task<IActionResult> Get(DateTimeOffset dateBegin, CancellationToken token)
|
public async Task<IActionResult> Get(DateTimeOffset dateBegin, CancellationToken token)
|
||||||
{
|
{
|
||||||
var result = await this.timeSeriesDataRepository.GetGtDate(dateBegin, token);
|
var result = await timeSeriesDataRepository.GetGtDate(dateBegin, token);
|
||||||
return Ok(result);
|
return Ok(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Ïîëó÷èòü äèàïàçîí äàò, äëÿ êîòîðûõ åñòü äàííûå â ðåïîçèòîðèå
|
/// Получить диапазон дат, для которых есть данные в репозиторие
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpGet("datesRange")]
|
[HttpGet("datesRange")]
|
||||||
public async Task<IActionResult> GetDatesRange(CancellationToken token)
|
public async Task<IActionResult> GetDatesRange(CancellationToken token)
|
||||||
{
|
{
|
||||||
var result = await this.timeSeriesDataRepository.GetDatesRange(token);
|
var result = await timeSeriesDataRepository.GetDatesRange(token);
|
||||||
return Ok(result);
|
return Ok(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Ïîëó÷èòü ñïèñîê îáúåêòîâ ñ ïðîðåæèâàíèåì, óäîâëåòâîðÿþùèé äèàïàçîíó äàò
|
/// Получить список объектов с прореживанием, удовлетворяющий диапазону дат
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="dateBegin"></param>
|
/// <param name="dateBegin"></param>
|
||||||
/// <param name="intervalSec"></param>
|
/// <param name="intervalSec"></param>
|
||||||
@ -55,12 +55,12 @@ public class TimeSeriesController<TDto> : ControllerBase, ITimeSeriesDataApi<TDt
|
|||||||
[HttpGet("resampled")]
|
[HttpGet("resampled")]
|
||||||
public async Task<IActionResult> GetResampledData(DateTimeOffset dateBegin, double intervalSec = 600d, int approxPointsCount = 1024, CancellationToken token = default)
|
public async Task<IActionResult> GetResampledData(DateTimeOffset dateBegin, double intervalSec = 600d, int approxPointsCount = 1024, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
var result = await this.timeSeriesDataRepository.GetResampledData(dateBegin, intervalSec, approxPointsCount, token);
|
var result = await timeSeriesDataRepository.GetResampledData(dateBegin, intervalSec, approxPointsCount, token);
|
||||||
return Ok(result);
|
return Ok(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Äîáàâèòü çàïèñè
|
/// Добавить записи
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="dtos"></param>
|
/// <param name="dtos"></param>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
@ -68,7 +68,7 @@ public class TimeSeriesController<TDto> : ControllerBase, ITimeSeriesDataApi<TDt
|
|||||||
[HttpPost]
|
[HttpPost]
|
||||||
public async Task<IActionResult> InsertRange(IEnumerable<TDto> dtos, CancellationToken token)
|
public async Task<IActionResult> InsertRange(IEnumerable<TDto> dtos, CancellationToken token)
|
||||||
{
|
{
|
||||||
var result = await this.timeSeriesDataRepository.InsertRange(dtos, token);
|
var result = await timeSeriesDataRepository.InsertRange(dtos, token);
|
||||||
return Ok(result);
|
return Ok(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,6 +19,12 @@ public interface ISetpointClient
|
|||||||
[Get($"{BaseRoute}/log")]
|
[Get($"{BaseRoute}/log")]
|
||||||
Task<IApiResponse<Dictionary<Guid, IEnumerable<SetpointLogDto>>>> GetLog([Query(CollectionFormat.Multi)] IEnumerable<Guid> setpointKeys);
|
Task<IApiResponse<Dictionary<Guid, IEnumerable<SetpointLogDto>>>> GetLog([Query(CollectionFormat.Multi)] IEnumerable<Guid> setpointKeys);
|
||||||
|
|
||||||
|
[Get($"{BaseRoute}/range")]
|
||||||
|
Task<IApiResponse<DatesRangeDto>> GetDatesRangeAsync(CancellationToken token);
|
||||||
|
|
||||||
|
[Get($"{BaseRoute}/part")]
|
||||||
|
Task<IApiResponse<IEnumerable<SetpointLogDto>>> GetPart(DateTimeOffset dateBegin, int take, CancellationToken token);
|
||||||
|
|
||||||
[Post($"{BaseRoute}/")]
|
[Post($"{BaseRoute}/")]
|
||||||
Task<IApiResponse> Save(Guid setpointKey, object newValue);
|
Task<IApiResponse> Save(Guid setpointKey, object newValue);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
using Persistence.Models;
|
||||||
using Persistence.Models;
|
|
||||||
using Refit;
|
using Refit;
|
||||||
|
|
||||||
namespace Persistence.Client.Clients
|
namespace Persistence.Client.Clients
|
||||||
@ -20,7 +19,13 @@ namespace Persistence.Client.Clients
|
|||||||
[Get($"{BaseRoute}/systems")]
|
[Get($"{BaseRoute}/systems")]
|
||||||
Task<IApiResponse<IEnumerable<string>>> GetSystems(CancellationToken token);
|
Task<IApiResponse<IEnumerable<string>>> GetSystems(CancellationToken token);
|
||||||
|
|
||||||
[Get($"{BaseRoute}/statistics/" + "{autoDrillingSystem}")]
|
[Get($"{BaseRoute}/range")]
|
||||||
Task<IApiResponse<int>> GetStatistics(string? autoDrillingSystem, int? importantId, CancellationToken token);
|
Task<IApiResponse<DatesRangeDto>> GetDatesRangeAsync(CancellationToken token);
|
||||||
|
|
||||||
|
[Get($"{BaseRoute}/part")]
|
||||||
|
Task<IApiResponse<IEnumerable<TechMessageDto>>> GetPart(DateTimeOffset dateBegin, int take, CancellationToken token);
|
||||||
|
|
||||||
|
[Get($"{BaseRoute}/statistics")]
|
||||||
|
Task<IApiResponse<IEnumerable<MessagesStatisticDto>>> GetStatistics([Query] string autoDrillingSystem, [Query] int categoryId, CancellationToken token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,8 +29,10 @@ public static class ApiTokenHelper
|
|||||||
|
|
||||||
private static string CreateDefaultJwtToken(this AuthUser authUser)
|
private static string CreateDefaultJwtToken(this AuthUser authUser)
|
||||||
{
|
{
|
||||||
|
var nameIdetifier = Guid.NewGuid().ToString();
|
||||||
var claims = new List<Claim>()
|
var claims = new List<Claim>()
|
||||||
{
|
{
|
||||||
|
new(ClaimTypes.NameIdentifier, nameIdetifier),
|
||||||
new("client_id", authUser.ClientId),
|
new("client_id", authUser.ClientId),
|
||||||
new("username", authUser.Username),
|
new("username", authUser.Username),
|
||||||
new("password", authUser.Password),
|
new("password", authUser.Password),
|
||||||
|
@ -18,7 +18,7 @@ namespace Persistence.Database.Postgres.Migrations
|
|||||||
Key = table.Column<Guid>(type: "uuid", nullable: false, comment: "Ключ"),
|
Key = table.Column<Guid>(type: "uuid", nullable: false, comment: "Ключ"),
|
||||||
Created = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, comment: "Дата изменения уставки"),
|
Created = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, comment: "Дата изменения уставки"),
|
||||||
Value = table.Column<object>(type: "jsonb", nullable: false, comment: "Значение уставки"),
|
Value = table.Column<object>(type: "jsonb", nullable: false, comment: "Значение уставки"),
|
||||||
IdUser = table.Column<int>(type: "integer", nullable: false, comment: "Id автора последнего изменения")
|
IdUser = table.Column<Guid>(type: "uuid", nullable: false, comment: "Id автора последнего изменения")
|
||||||
},
|
},
|
||||||
constraints: table =>
|
constraints: table =>
|
||||||
{
|
{
|
||||||
|
@ -12,7 +12,7 @@ using Persistence.Database.Model;
|
|||||||
namespace Persistence.Database.Postgres.Migrations
|
namespace Persistence.Database.Postgres.Migrations
|
||||||
{
|
{
|
||||||
[DbContext(typeof(PersistenceDbContext))]
|
[DbContext(typeof(PersistenceDbContext))]
|
||||||
[Migration("20241128074729_TechMessageMigration")]
|
[Migration("20241202072250_TechMessageMigration")]
|
||||||
partial class TechMessageMigration
|
partial class TechMessageMigration
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@ -27,7 +27,7 @@ namespace Persistence.Database.Postgres.Migrations
|
|||||||
NpgsqlModelBuilderExtensions.HasPostgresExtension(modelBuilder, "adminpack");
|
NpgsqlModelBuilderExtensions.HasPostgresExtension(modelBuilder, "adminpack");
|
||||||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||||
|
|
||||||
modelBuilder.Entity("Persistence.Database.Entity.ADSystem", b =>
|
modelBuilder.Entity("Persistence.Database.Entity.DrillingSystem", b =>
|
||||||
{
|
{
|
||||||
b.Property<Guid>("SystemId")
|
b.Property<Guid>("SystemId")
|
||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
@ -45,7 +45,7 @@ namespace Persistence.Database.Postgres.Migrations
|
|||||||
|
|
||||||
b.HasKey("SystemId");
|
b.HasKey("SystemId");
|
||||||
|
|
||||||
b.ToTable("ADSystem");
|
b.ToTable("DrillingSystem");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("Persistence.Database.Entity.TechMessage", b =>
|
modelBuilder.Entity("Persistence.Database.Entity.TechMessage", b =>
|
||||||
@ -203,8 +203,8 @@ namespace Persistence.Database.Postgres.Migrations
|
|||||||
.HasColumnType("timestamp with time zone")
|
.HasColumnType("timestamp with time zone")
|
||||||
.HasComment("Дата создания уставки");
|
.HasComment("Дата создания уставки");
|
||||||
|
|
||||||
b.Property<int>("IdUser")
|
b.Property<Guid>("IdUser")
|
||||||
.HasColumnType("integer")
|
.HasColumnType("uuid")
|
||||||
.HasComment("Id автора последнего изменения");
|
.HasComment("Id автора последнего изменения");
|
||||||
|
|
||||||
b.Property<object>("Value")
|
b.Property<object>("Value")
|
||||||
@ -219,7 +219,7 @@ namespace Persistence.Database.Postgres.Migrations
|
|||||||
|
|
||||||
modelBuilder.Entity("Persistence.Database.Entity.TechMessage", b =>
|
modelBuilder.Entity("Persistence.Database.Entity.TechMessage", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("Persistence.Database.Entity.ADSystem", "System")
|
b.HasOne("Persistence.Database.Entity.DrillingSystem", "System")
|
||||||
.WithMany()
|
.WithMany()
|
||||||
.HasForeignKey("SystemId")
|
.HasForeignKey("SystemId")
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
.OnDelete(DeleteBehavior.Cascade)
|
@ -12,7 +12,7 @@ namespace Persistence.Database.Postgres.Migrations
|
|||||||
protected override void Up(MigrationBuilder migrationBuilder)
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
{
|
{
|
||||||
migrationBuilder.CreateTable(
|
migrationBuilder.CreateTable(
|
||||||
name: "ADSystem",
|
name: "DrillingSystem",
|
||||||
columns: table => new
|
columns: table => new
|
||||||
{
|
{
|
||||||
SystemId = table.Column<Guid>(type: "uuid", nullable: false, comment: "Id системы автобурения"),
|
SystemId = table.Column<Guid>(type: "uuid", nullable: false, comment: "Id системы автобурения"),
|
||||||
@ -21,7 +21,7 @@ namespace Persistence.Database.Postgres.Migrations
|
|||||||
},
|
},
|
||||||
constraints: table =>
|
constraints: table =>
|
||||||
{
|
{
|
||||||
table.PrimaryKey("PK_ADSystem", x => x.SystemId);
|
table.PrimaryKey("PK_DrillingSystem", x => x.SystemId);
|
||||||
});
|
});
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
migrationBuilder.CreateTable(
|
||||||
@ -40,9 +40,9 @@ namespace Persistence.Database.Postgres.Migrations
|
|||||||
{
|
{
|
||||||
table.PrimaryKey("PK_TechMessage", x => x.EventId);
|
table.PrimaryKey("PK_TechMessage", x => x.EventId);
|
||||||
table.ForeignKey(
|
table.ForeignKey(
|
||||||
name: "FK_TechMessage_ADSystem_SystemId",
|
name: "FK_TechMessage_DrillingSystem_SystemId",
|
||||||
column: x => x.SystemId,
|
column: x => x.SystemId,
|
||||||
principalTable: "ADSystem",
|
principalTable: "DrillingSystem",
|
||||||
principalColumn: "SystemId",
|
principalColumn: "SystemId",
|
||||||
onDelete: ReferentialAction.Cascade);
|
onDelete: ReferentialAction.Cascade);
|
||||||
});
|
});
|
||||||
@ -60,7 +60,7 @@ namespace Persistence.Database.Postgres.Migrations
|
|||||||
name: "TechMessage");
|
name: "TechMessage");
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
migrationBuilder.DropTable(
|
||||||
name: "ADSystem");
|
name: "DrillingSystem");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -24,7 +24,7 @@ namespace Persistence.Database.Postgres.Migrations
|
|||||||
NpgsqlModelBuilderExtensions.HasPostgresExtension(modelBuilder, "adminpack");
|
NpgsqlModelBuilderExtensions.HasPostgresExtension(modelBuilder, "adminpack");
|
||||||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||||
|
|
||||||
modelBuilder.Entity("Persistence.Database.Entity.ADSystem", b =>
|
modelBuilder.Entity("Persistence.Database.Entity.DrillingSystem", b =>
|
||||||
{
|
{
|
||||||
b.Property<Guid>("SystemId")
|
b.Property<Guid>("SystemId")
|
||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
@ -42,7 +42,7 @@ namespace Persistence.Database.Postgres.Migrations
|
|||||||
|
|
||||||
b.HasKey("SystemId");
|
b.HasKey("SystemId");
|
||||||
|
|
||||||
b.ToTable("ADSystem");
|
b.ToTable("DrillingSystem");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("Persistence.Database.Entity.TechMessage", b =>
|
modelBuilder.Entity("Persistence.Database.Entity.TechMessage", b =>
|
||||||
@ -200,8 +200,8 @@ namespace Persistence.Database.Postgres.Migrations
|
|||||||
.HasColumnType("timestamp with time zone")
|
.HasColumnType("timestamp with time zone")
|
||||||
.HasComment("Дата создания уставки");
|
.HasComment("Дата создания уставки");
|
||||||
|
|
||||||
b.Property<int>("IdUser")
|
b.Property<Guid>("IdUser")
|
||||||
.HasColumnType("integer")
|
.HasColumnType("uuid")
|
||||||
.HasComment("Id автора последнего изменения");
|
.HasComment("Id автора последнего изменения");
|
||||||
|
|
||||||
b.Property<object>("Value")
|
b.Property<object>("Value")
|
||||||
@ -216,7 +216,7 @@ namespace Persistence.Database.Postgres.Migrations
|
|||||||
|
|
||||||
modelBuilder.Entity("Persistence.Database.Entity.TechMessage", b =>
|
modelBuilder.Entity("Persistence.Database.Entity.TechMessage", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("Persistence.Database.Entity.ADSystem", "System")
|
b.HasOne("Persistence.Database.Entity.DrillingSystem", "System")
|
||||||
.WithMany()
|
.WithMany()
|
||||||
.HasForeignKey("SystemId")
|
.HasForeignKey("SystemId")
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
@ -3,7 +3,7 @@ using System.ComponentModel.DataAnnotations.Schema;
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
namespace Persistence.Database.Entity;
|
namespace Persistence.Database.Entity;
|
||||||
public class ADSystem
|
public class DrillingSystem
|
||||||
{
|
{
|
||||||
[Key, Comment("Id системы автобурения")]
|
[Key, Comment("Id системы автобурения")]
|
||||||
public Guid SystemId { get; set; }
|
public Guid SystemId { get; set; }
|
@ -16,6 +16,6 @@ namespace Persistence.Database.Model
|
|||||||
public DateTimeOffset Created { get; set; }
|
public DateTimeOffset Created { get; set; }
|
||||||
|
|
||||||
[Comment("Id автора последнего изменения")]
|
[Comment("Id автора последнего изменения")]
|
||||||
public int IdUser { get; set; }
|
public Guid IdUser { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ namespace Persistence.Database.Entity
|
|||||||
public required Guid SystemId { get; set; }
|
public required Guid SystemId { get; set; }
|
||||||
|
|
||||||
[Required, ForeignKey(nameof(SystemId)), Comment("Система автобурения, к которой относится сообщение")]
|
[Required, ForeignKey(nameof(SystemId)), Comment("Система автобурения, к которой относится сообщение")]
|
||||||
public virtual required ADSystem System { get; set; }
|
public virtual required DrillingSystem System { get; set; }
|
||||||
|
|
||||||
[Comment("Id пользователя за пультом бурильщика")]
|
[Comment("Id пользователя за пультом бурильщика")]
|
||||||
public Guid UserId { get; set; }
|
public Guid UserId { get; set; }
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Persistence.Client;
|
using Persistence.Client;
|
||||||
using Persistence.Client.Clients;
|
using Persistence.Client.Clients;
|
||||||
|
using Persistence.Database.Model;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Persistence.IntegrationTests.Controllers
|
namespace Persistence.IntegrationTests.Controllers
|
||||||
@ -131,6 +132,72 @@ namespace Persistence.IntegrationTests.Controllers
|
|||||||
Assert.Equal(setpointKey, response.Content.FirstOrDefault().Key);
|
Assert.Equal(setpointKey, response.Content.FirstOrDefault().Key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task GetDatesRange_returns_success()
|
||||||
|
{
|
||||||
|
//arrange
|
||||||
|
dbContext.CleanupDbSet<Setpoint>();
|
||||||
|
|
||||||
|
//act
|
||||||
|
var response = await setpointClient.GetDatesRangeAsync(new CancellationToken());
|
||||||
|
|
||||||
|
//assert
|
||||||
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
|
Assert.NotNull(response.Content);
|
||||||
|
Assert.Equal(DateTimeOffset.MinValue, response.Content?.From);
|
||||||
|
Assert.Equal(DateTimeOffset.MaxValue, response.Content?.To);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task GetDatesRange_AfterSave_returns_success()
|
||||||
|
{
|
||||||
|
//arrange
|
||||||
|
dbContext.CleanupDbSet<Setpoint>();
|
||||||
|
await Save();
|
||||||
|
|
||||||
|
//act
|
||||||
|
var response = await setpointClient.GetDatesRangeAsync(new CancellationToken());
|
||||||
|
|
||||||
|
//assert
|
||||||
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
|
Assert.NotNull(response.Content);
|
||||||
|
Assert.NotNull(response.Content?.From);
|
||||||
|
Assert.NotNull(response.Content?.To);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task GetPart_returns_success()
|
||||||
|
{
|
||||||
|
//arrange
|
||||||
|
var dateBegin = DateTimeOffset.UtcNow;
|
||||||
|
var take = 2;
|
||||||
|
|
||||||
|
//act
|
||||||
|
var response = await setpointClient.GetPart(dateBegin, take, new CancellationToken());
|
||||||
|
|
||||||
|
//assert
|
||||||
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
|
Assert.NotNull(response.Content);
|
||||||
|
Assert.Empty(response.Content);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task GetPart_AfterSave_returns_success()
|
||||||
|
{
|
||||||
|
//arrange
|
||||||
|
var dateBegin = DateTimeOffset.UtcNow;
|
||||||
|
var take = 1;
|
||||||
|
await Save();
|
||||||
|
|
||||||
|
//act
|
||||||
|
var response = await setpointClient.GetPart(dateBegin, take, new CancellationToken());
|
||||||
|
|
||||||
|
//assert
|
||||||
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
|
Assert.NotNull(response.Content);
|
||||||
|
Assert.NotEmpty(response.Content);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task Save_returns_success()
|
public async Task Save_returns_success()
|
||||||
{
|
{
|
||||||
|
@ -11,7 +11,7 @@ namespace Persistence.IntegrationTests.Controllers
|
|||||||
{
|
{
|
||||||
public class TechMessagesControllerTest : BaseIntegrationTest
|
public class TechMessagesControllerTest : BaseIntegrationTest
|
||||||
{
|
{
|
||||||
private static readonly string SystemCacheKey = $"{typeof(ADSystem).FullName}CacheKey";
|
private static readonly string SystemCacheKey = $"{typeof(Database.Entity.DrillingSystem).FullName}CacheKey";
|
||||||
private readonly ITechMessagesClient techMessagesClient;
|
private readonly ITechMessagesClient techMessagesClient;
|
||||||
private readonly IMemoryCache memoryCache;
|
private readonly IMemoryCache memoryCache;
|
||||||
public TechMessagesControllerTest(WebAppFactoryFixture factory) : base(factory)
|
public TechMessagesControllerTest(WebAppFactoryFixture factory) : base(factory)
|
||||||
@ -28,7 +28,10 @@ namespace Persistence.IntegrationTests.Controllers
|
|||||||
public async Task GetPage_returns_success()
|
public async Task GetPage_returns_success()
|
||||||
{
|
{
|
||||||
//arrange
|
//arrange
|
||||||
|
memoryCache.Remove(SystemCacheKey);
|
||||||
dbContext.CleanupDbSet<TechMessage>();
|
dbContext.CleanupDbSet<TechMessage>();
|
||||||
|
dbContext.CleanupDbSet<Database.Entity.DrillingSystem>();
|
||||||
|
|
||||||
var requestDto = new RequestDto()
|
var requestDto = new RequestDto()
|
||||||
{
|
{
|
||||||
Skip = 1,
|
Skip = 1,
|
||||||
@ -104,8 +107,9 @@ namespace Persistence.IntegrationTests.Controllers
|
|||||||
public async Task GetSystems_returns_success()
|
public async Task GetSystems_returns_success()
|
||||||
{
|
{
|
||||||
//arrange
|
//arrange
|
||||||
dbContext.CleanupDbSet<ADSystem>();
|
|
||||||
memoryCache.Remove(SystemCacheKey);
|
memoryCache.Remove(SystemCacheKey);
|
||||||
|
dbContext.CleanupDbSet<TechMessage>();
|
||||||
|
dbContext.CleanupDbSet<Database.Entity.DrillingSystem>();
|
||||||
|
|
||||||
//act
|
//act
|
||||||
var response = await techMessagesClient.GetSystems(new CancellationToken());
|
var response = await techMessagesClient.GetSystems(new CancellationToken());
|
||||||
@ -140,7 +144,10 @@ namespace Persistence.IntegrationTests.Controllers
|
|||||||
public async Task GetStatistics_returns_success()
|
public async Task GetStatistics_returns_success()
|
||||||
{
|
{
|
||||||
//arrange
|
//arrange
|
||||||
|
memoryCache.Remove(SystemCacheKey);
|
||||||
dbContext.CleanupDbSet<TechMessage>();
|
dbContext.CleanupDbSet<TechMessage>();
|
||||||
|
dbContext.CleanupDbSet<Database.Entity.DrillingSystem>();
|
||||||
|
|
||||||
var imortantId = 1;
|
var imortantId = 1;
|
||||||
var autoDrillingSystem = nameof(TechMessageDto.System);
|
var autoDrillingSystem = nameof(TechMessageDto.System);
|
||||||
|
|
||||||
@ -149,7 +156,8 @@ namespace Persistence.IntegrationTests.Controllers
|
|||||||
|
|
||||||
//assert
|
//assert
|
||||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
Assert.Equal(0, response.Content);
|
Assert.NotNull(response.Content);
|
||||||
|
Assert.Empty(response.Content);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@ -159,19 +167,89 @@ namespace Persistence.IntegrationTests.Controllers
|
|||||||
var imortantId = 0;
|
var imortantId = 0;
|
||||||
var autoDrillingSystem = nameof(TechMessageDto.System);
|
var autoDrillingSystem = nameof(TechMessageDto.System);
|
||||||
var dtos = await InsertRange();
|
var dtos = await InsertRange();
|
||||||
var filteredDtos = dtos.Where(e => e.CategoryId == imortantId && e.System == e.System);
|
var filteredDtos = dtos.Where(e => e.CategoryId == imortantId && e.System == autoDrillingSystem);
|
||||||
|
|
||||||
//act
|
//act
|
||||||
var response = await techMessagesClient.GetStatistics(autoDrillingSystem, imortantId, new CancellationToken());
|
var response = await techMessagesClient.GetStatistics(autoDrillingSystem, imortantId, new CancellationToken());
|
||||||
|
|
||||||
//assert
|
//assert
|
||||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
Assert.Equal(filteredDtos.Count(), response.Content);
|
Assert.NotNull(response.Content);
|
||||||
|
var categories = response.Content
|
||||||
|
.FirstOrDefault()?.Categories
|
||||||
|
.FirstOrDefault(e => e.Key == 0).Value;
|
||||||
|
Assert.Equal(filteredDtos.Count(), categories);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<TechMessageDto>> InsertRange()
|
[Fact]
|
||||||
|
public async Task GetDatesRange_returns_success()
|
||||||
|
{
|
||||||
|
//act
|
||||||
|
var response = await techMessagesClient.GetDatesRangeAsync(new CancellationToken());
|
||||||
|
|
||||||
|
//assert
|
||||||
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
|
Assert.NotNull(response.Content);
|
||||||
|
//Assert.Equal(DateTimeOffset.MinValue, response.Content?.From);
|
||||||
|
//Assert.Equal(DateTimeOffset.MaxValue, response.Content?.To);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task GetDatesRange_AfterSave_returns_success()
|
||||||
{
|
{
|
||||||
//arrange
|
//arrange
|
||||||
|
await InsertRange();
|
||||||
|
|
||||||
|
//act
|
||||||
|
var response = await techMessagesClient.GetDatesRangeAsync(new CancellationToken());
|
||||||
|
|
||||||
|
//assert
|
||||||
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
|
Assert.NotNull(response.Content);
|
||||||
|
Assert.NotNull(response.Content?.From);
|
||||||
|
Assert.NotNull(response.Content?.To);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task GetPart_returns_success()
|
||||||
|
{
|
||||||
|
//arrange
|
||||||
|
var dateBegin = DateTimeOffset.UtcNow;
|
||||||
|
var take = 2;
|
||||||
|
|
||||||
|
//act
|
||||||
|
var response = await techMessagesClient.GetPart(dateBegin, take, new CancellationToken());
|
||||||
|
|
||||||
|
//assert
|
||||||
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
|
Assert.NotNull(response.Content);
|
||||||
|
Assert.Empty(response.Content);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task GetPart_AfterSave_returns_success()
|
||||||
|
{
|
||||||
|
//arrange
|
||||||
|
var dateBegin = DateTimeOffset.UtcNow;
|
||||||
|
var take = 1;
|
||||||
|
await InsertRange();
|
||||||
|
|
||||||
|
//act
|
||||||
|
var response = await techMessagesClient.GetPart(dateBegin, take, new CancellationToken());
|
||||||
|
|
||||||
|
//assert
|
||||||
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
|
Assert.NotNull(response.Content);
|
||||||
|
Assert.NotEmpty(response.Content);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<IEnumerable<TechMessageDto>> InsertRange()
|
||||||
|
{
|
||||||
|
//arrange
|
||||||
|
memoryCache.Remove(SystemCacheKey);
|
||||||
|
dbContext.CleanupDbSet<TechMessage>();
|
||||||
|
dbContext.CleanupDbSet<DrillingSystem>();
|
||||||
|
|
||||||
var dtos = new List<TechMessageDto>()
|
var dtos = new List<TechMessageDto>()
|
||||||
{
|
{
|
||||||
new TechMessageDto()
|
new TechMessageDto()
|
||||||
@ -181,7 +259,7 @@ namespace Persistence.IntegrationTests.Controllers
|
|||||||
Timestamp = DateTimeOffset.UtcNow,
|
Timestamp = DateTimeOffset.UtcNow,
|
||||||
Depth = 1.11,
|
Depth = 1.11,
|
||||||
MessageText = nameof(TechMessageDto.MessageText),
|
MessageText = nameof(TechMessageDto.MessageText),
|
||||||
System = nameof(TechMessageDto.System),
|
System = nameof(TechMessageDto.System).ToLower(),
|
||||||
UserId = Guid.NewGuid()
|
UserId = Guid.NewGuid()
|
||||||
},
|
},
|
||||||
new TechMessageDto()
|
new TechMessageDto()
|
||||||
@ -191,7 +269,7 @@ namespace Persistence.IntegrationTests.Controllers
|
|||||||
Timestamp = DateTimeOffset.UtcNow,
|
Timestamp = DateTimeOffset.UtcNow,
|
||||||
Depth = 2.22,
|
Depth = 2.22,
|
||||||
MessageText = nameof(TechMessageDto.MessageText),
|
MessageText = nameof(TechMessageDto.MessageText),
|
||||||
System = nameof(TechMessageDto.System),
|
System = nameof(TechMessageDto.System).ToLower(),
|
||||||
UserId = Guid.NewGuid()
|
UserId = Guid.NewGuid()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -43,6 +43,38 @@ namespace Persistence.Repository.Repositories
|
|||||||
return dtos;
|
return dtos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<SetpointLogDto>> GetPart(DateTimeOffset dateBegin, int take, CancellationToken token)
|
||||||
|
{
|
||||||
|
var query = GetQueryReadOnly();
|
||||||
|
var entities = await query
|
||||||
|
.Where(e => e.Created > dateBegin)
|
||||||
|
.Take(take)
|
||||||
|
.ToArrayAsync(token);
|
||||||
|
var dtos = entities
|
||||||
|
.Select(e => e.Adapt<SetpointLogDto>());
|
||||||
|
|
||||||
|
return dtos;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<DatesRangeDto> GetDatesRangeAsync(CancellationToken token)
|
||||||
|
{
|
||||||
|
var query = GetQueryReadOnly()
|
||||||
|
.GroupBy(e => 1)
|
||||||
|
.Select(group => new
|
||||||
|
{
|
||||||
|
Min = group.Min(e => e.Created),
|
||||||
|
Max = group.Max(e => e.Created),
|
||||||
|
});
|
||||||
|
var values = await query.FirstOrDefaultAsync(token);
|
||||||
|
var result = new DatesRangeDto()
|
||||||
|
{
|
||||||
|
From = values?.Min ?? DateTimeOffset.MinValue,
|
||||||
|
To = values?.Max ?? DateTimeOffset.MaxValue
|
||||||
|
};
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<Dictionary<Guid, IEnumerable<SetpointLogDto>>> GetLog(IEnumerable<Guid> setpointKeys, CancellationToken token)
|
public async Task<Dictionary<Guid, IEnumerable<SetpointLogDto>>> GetLog(IEnumerable<Guid> setpointKeys, CancellationToken token)
|
||||||
{
|
{
|
||||||
var query = GetQueryReadOnly();
|
var query = GetQueryReadOnly();
|
||||||
@ -56,7 +88,7 @@ namespace Persistence.Repository.Repositories
|
|||||||
return dtos;
|
return dtos;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Save(Guid setpointKey, object newValue, int idUser, CancellationToken token)
|
public async Task Save(Guid setpointKey, object newValue, Guid idUser, CancellationToken token)
|
||||||
{
|
{
|
||||||
var entity = new Setpoint()
|
var entity = new Setpoint()
|
||||||
{
|
{
|
||||||
|
@ -10,7 +10,8 @@ namespace Persistence.Repository.Repositories
|
|||||||
{
|
{
|
||||||
public class TechMessagesRepository : ITechMessagesRepository
|
public class TechMessagesRepository : ITechMessagesRepository
|
||||||
{
|
{
|
||||||
private static readonly string SystemCacheKey = $"{typeof(ADSystem).FullName}CacheKey";
|
private static readonly string SystemCacheKey = $"{typeof(Database.Entity.DrillingSystem).FullName}CacheKey";
|
||||||
|
private const int CacheExpirationInMinutes = 60;
|
||||||
private readonly IMemoryCache memoryCache;
|
private readonly IMemoryCache memoryCache;
|
||||||
private DbContext db;
|
private DbContext db;
|
||||||
|
|
||||||
@ -26,40 +27,65 @@ namespace Persistence.Repository.Repositories
|
|||||||
public async Task<PaginationContainer<TechMessageDto>> GetPage(RequestDto request, CancellationToken token)
|
public async Task<PaginationContainer<TechMessageDto>> GetPage(RequestDto request, CancellationToken token)
|
||||||
{
|
{
|
||||||
var query = GetQueryReadOnly();
|
var query = GetQueryReadOnly();
|
||||||
|
var count = await query.CountAsync(token);
|
||||||
|
|
||||||
|
var sort = request.SortSettings != string.Empty
|
||||||
|
? request.SortSettings
|
||||||
|
: nameof(TechMessage.Timestamp);
|
||||||
var entities = await query
|
var entities = await query
|
||||||
.SortBy(request.SortSettings)
|
.SortBy(request.SortSettings)
|
||||||
.Skip(request.Skip)
|
.Skip(request.Skip)
|
||||||
.Take(request.Take)
|
.Take(request.Take)
|
||||||
.ToListAsync();
|
.ToArrayAsync(token);
|
||||||
|
|
||||||
var dto = new PaginationContainer<TechMessageDto>()
|
var dto = new PaginationContainer<TechMessageDto>()
|
||||||
{
|
{
|
||||||
Skip = request.Skip,
|
Skip = request.Skip,
|
||||||
Take = request.Take,
|
Take = request.Take,
|
||||||
Count = entities.Count,
|
Count = count,
|
||||||
Items = entities.Select(e => e.Adapt<TechMessageDto>())
|
Items = entities.Select(e => e.Adapt<TechMessageDto>())
|
||||||
};
|
};
|
||||||
|
|
||||||
return dto;
|
return dto;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Dictionary<string, int>> GetStatistics(int? importantId, string? autoDrillingSystem, CancellationToken token)
|
public async Task<IEnumerable<MessagesStatisticDto>> GetStatistics(IEnumerable<string> autoDrillingSystem, IEnumerable<int> categoryIds, CancellationToken token)
|
||||||
{
|
{
|
||||||
var query = GetQueryReadOnly();
|
var query = GetQueryReadOnly();
|
||||||
var count = await query
|
var systems = autoDrillingSystem.Select(s => s.ToLower().Trim());
|
||||||
.Where(e => importantId == null || e.CategoryId == importantId)
|
var result = await query
|
||||||
.Where(e => autoDrillingSystem == null || e.System.Name == autoDrillingSystem)
|
.Where(e => systems.Count() == 0 || systems.Contains(e.System.Name.ToLower().Trim()))
|
||||||
.GroupBy(e => e.System.Name)
|
.GroupBy(e => e.System.Name, (key, group) => new
|
||||||
.ToDictionaryAsync(e => e.Key, v => v.Count());
|
{
|
||||||
|
System = key,
|
||||||
|
Categories = group
|
||||||
|
.Where(g => categoryIds.Count() == 0 || categoryIds.Contains(g.CategoryId))
|
||||||
|
})
|
||||||
|
.ToArrayAsync(token);
|
||||||
|
|
||||||
return count;
|
var entities = new List<MessagesStatisticDto>();
|
||||||
|
foreach (var e in result)
|
||||||
|
{
|
||||||
|
var categories = e.Categories
|
||||||
|
.GroupBy(g => g.CategoryId)
|
||||||
|
.ToDictionary(c => c.Key, v => v.Count());
|
||||||
|
var entity = new MessagesStatisticDto()
|
||||||
|
{
|
||||||
|
System = e.System,
|
||||||
|
Categories = categories
|
||||||
|
};
|
||||||
|
entities.Add(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
return entities;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<string>> GetSystems(CancellationToken token)
|
public async Task<IEnumerable<string>> GetSystems(CancellationToken token)
|
||||||
{
|
{
|
||||||
var entities = await GetSystems();
|
var entities = await GetDrillingSystems(token);
|
||||||
var systems = entities.Select(e => e.Name);
|
var result = entities.Select(e => e.Name);
|
||||||
|
|
||||||
return systems ?? [];
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<int> InsertRange(IEnumerable<TechMessageDto> dtos, CancellationToken token)
|
public async Task<int> InsertRange(IEnumerable<TechMessageDto> dtos, CancellationToken token)
|
||||||
@ -69,9 +95,9 @@ namespace Persistence.Repository.Repositories
|
|||||||
foreach (var dto in dtos)
|
foreach (var dto in dtos)
|
||||||
{
|
{
|
||||||
var entity = dto.Adapt<TechMessage>();
|
var entity = dto.Adapt<TechMessage>();
|
||||||
var systems = await GetSystems();
|
var systems = await GetDrillingSystems(token);
|
||||||
var systemId = systems.FirstOrDefault(e => e.Name == dto.System)?.SystemId
|
var systemId = systems.FirstOrDefault(e => e.Name.ToLower().Trim() == dto.System.ToLower().Trim())?.SystemId
|
||||||
?? await CreateSystem(dto.System);
|
?? await CreateDrillingSystem(dto.System, token);
|
||||||
|
|
||||||
entity.SystemId = systemId;
|
entity.SystemId = systemId;
|
||||||
|
|
||||||
@ -84,36 +110,67 @@ namespace Persistence.Repository.Repositories
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<IEnumerable<ADSystemDto>> GetSystems()
|
public async Task<IEnumerable<TechMessageDto>> GetPart(DateTimeOffset dateBegin, int take, CancellationToken token)
|
||||||
|
{
|
||||||
|
var query = GetQueryReadOnly();
|
||||||
|
var entities = await query
|
||||||
|
.Where(e => e.Timestamp > dateBegin)
|
||||||
|
.Take(take)
|
||||||
|
.ToArrayAsync(token);
|
||||||
|
var dtos = entities
|
||||||
|
.Select(e => e.Adapt<TechMessageDto>());
|
||||||
|
|
||||||
|
return dtos;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<DatesRangeDto> GetDatesRangeAsync(CancellationToken token)
|
||||||
|
{
|
||||||
|
var query = GetQueryReadOnly()
|
||||||
|
.GroupBy(e => 1)
|
||||||
|
.Select(group => new
|
||||||
|
{
|
||||||
|
Min = group.Min(e => e.Timestamp),
|
||||||
|
Max = group.Max(e => e.Timestamp),
|
||||||
|
});
|
||||||
|
var values = await query.FirstOrDefaultAsync(token);
|
||||||
|
var result = new DatesRangeDto()
|
||||||
|
{
|
||||||
|
From = values?.Min ?? DateTimeOffset.MinValue,
|
||||||
|
To = values?.Max ?? DateTimeOffset.MaxValue
|
||||||
|
};
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<IEnumerable<Models.DrillingSystemDto>> GetDrillingSystems(CancellationToken token)
|
||||||
{
|
{
|
||||||
var systems = await memoryCache.GetOrCreateAsync(SystemCacheKey, async f =>
|
var systems = await memoryCache.GetOrCreateAsync(SystemCacheKey, async f =>
|
||||||
{
|
{
|
||||||
f.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(60);
|
f.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(CacheExpirationInMinutes);
|
||||||
|
|
||||||
var query = db.Set<ADSystem>();
|
var query = db.Set<Database.Entity.DrillingSystem>();
|
||||||
var entities = await query.ToListAsync();
|
var entities = await query.ToListAsync(token);
|
||||||
var dtos = entities.Select(e => e.Adapt<ADSystemDto>());
|
var dtos = entities.Select(e => e.Adapt<Models.DrillingSystemDto>());
|
||||||
|
|
||||||
return dtos;
|
return dtos;
|
||||||
});
|
});
|
||||||
|
|
||||||
return systems ?? [];
|
return systems!;
|
||||||
}
|
}
|
||||||
private async Task<Guid> CreateSystem(string name)
|
private async Task<Guid> CreateDrillingSystem(string name, CancellationToken token)
|
||||||
{
|
{
|
||||||
memoryCache.Remove(SystemCacheKey);
|
memoryCache.Remove(SystemCacheKey);
|
||||||
|
|
||||||
var systemId = Guid.NewGuid();
|
var entity = new Database.Entity.DrillingSystem()
|
||||||
var entity = new ADSystem()
|
|
||||||
{
|
{
|
||||||
SystemId = systemId,
|
SystemId = default,
|
||||||
Name = name
|
Name = name.ToLower().Trim()
|
||||||
};
|
};
|
||||||
|
|
||||||
await db.Set<ADSystem>().AddAsync(entity);
|
await db.Set<Database.Entity.DrillingSystem>().AddAsync(entity);
|
||||||
await db.SaveChangesAsync();
|
await db.SaveChangesAsync(token);
|
||||||
|
|
||||||
return systemId;
|
return entity.SystemId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ namespace Persistence.API;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Интерфейс для API, предназначенного для работы с уставками
|
/// Интерфейс для API, предназначенного для работы с уставками
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface ISetpointApi
|
public interface ISetpointApi : ISyncApi<SetpointLogDto>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получить актуальные значения уставок
|
/// Получить актуальные значения уставок
|
||||||
@ -33,12 +33,12 @@ public interface ISetpointApi
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<ActionResult<Dictionary<Guid, IEnumerable<SetpointLogDto>>>> GetLog(IEnumerable<Guid> setpoitKeys, CancellationToken token);
|
Task<ActionResult<Dictionary<Guid, IEnumerable<SetpointLogDto>>>> GetLog(IEnumerable<Guid> setpoitKeys, CancellationToken token);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Метод сохранения уставки
|
/// Метод сохранения уставки
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="setpointKey">ключ уставки</param>
|
/// <param name="setpointKey">ключ уставки</param>
|
||||||
/// <param name="newValue">значение</param>
|
/// <param name="newValue">значение</param>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<ActionResult<int>> Save(Guid setpointKey, object newValue, CancellationToken token);
|
Task<IActionResult> Save(Guid setpointKey, object newValue, Guid userId, CancellationToken token);
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ namespace Persistence.API;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Интерфейс для API, предназначенного для синхронизации данных
|
/// Интерфейс для API, предназначенного для синхронизации данных
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface ISyncApi<TDto> where TDto : class, new()
|
public interface ISyncApi<TDto>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получить порцию записей, начиная с заданной даты
|
/// Получить порцию записей, начиная с заданной даты
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Модель системы автобурения
|
/// Модель системы автобурения
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ADSystemDto
|
public class DrillingSystemDto
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Ключ
|
/// Ключ
|
17
Persistence/Models/MessagesStatisticDto.cs
Normal file
17
Persistence/Models/MessagesStatisticDto.cs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
namespace Persistence.Models;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Статистика сообщений по системам бурения
|
||||||
|
/// </summary>
|
||||||
|
public class MessagesStatisticDto
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Система бурения
|
||||||
|
/// </summary>
|
||||||
|
public required string System { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Количество сообщений в соответствии с категориями важности
|
||||||
|
/// </summary>
|
||||||
|
public required Dictionary<int, int> Categories { get; set; }
|
||||||
|
}
|
@ -13,5 +13,5 @@ public class SetpointLogDto : SetpointValueDto
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Ключ пользователя
|
/// Ключ пользователя
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int IdUser { get; set; }
|
public Guid IdUser { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Persistence.Models;
|
using Persistence.Models;
|
||||||
|
|
||||||
namespace Persistence.Repositories;
|
namespace Persistence.Repositories;
|
||||||
@ -32,15 +33,31 @@ public interface ISetpointRepository
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<Dictionary<Guid, IEnumerable<SetpointLogDto>>> GetLog(IEnumerable<Guid> setpointKeys, CancellationToken token);
|
Task<Dictionary<Guid, IEnumerable<SetpointLogDto>>> GetLog(IEnumerable<Guid> setpointKeys, CancellationToken token);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Метод сохранения уставки
|
/// Получить порцию записей, начиная с заданной даты
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="setpointKey">ключ операции</param>
|
/// <param name="dateBegin"></param>
|
||||||
/// <param name="idUser">ключ пользователя</param>
|
/// <param name="take"></param>
|
||||||
/// <param name="newValue">значение</param>
|
/// <param name="token"></param>
|
||||||
/// <param name="token"></param>
|
/// <returns></returns>
|
||||||
/// <returns></returns>
|
Task<IEnumerable<SetpointLogDto>> GetPart(DateTimeOffset dateBegin, int take, CancellationToken token);
|
||||||
/// to do
|
|
||||||
/// id User учесть в соответствующем методе репозитория
|
/// <summary>
|
||||||
Task Save(Guid setpointKey, object newValue, int idUser, CancellationToken token);
|
/// Получить диапазон дат, для которых есть данные в репозитории
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="token"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<DatesRangeDto> GetDatesRangeAsync(CancellationToken token);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Метод сохранения уставки
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="setpointKey">ключ операции</param>
|
||||||
|
/// <param name="idUser">ключ пользователя</param>
|
||||||
|
/// <param name="newValue">значение</param>
|
||||||
|
/// <param name="token"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
/// to do
|
||||||
|
/// id User учесть в соответствующем методе репозитория
|
||||||
|
Task Save(Guid setpointKey, object newValue, Guid idUser, CancellationToken token);
|
||||||
}
|
}
|
||||||
|
@ -34,10 +34,26 @@ namespace Persistence.Repositories
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получение количества сообщений по категориям и системам автобурения
|
/// Получение количества сообщений по категориям и системам автобурения
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="importantId">Id Категории важности</param>
|
/// <param name="categoryId">Id Категории важности</param>
|
||||||
/// <param name="autoDrillingSystem">Система автобурения</param>
|
/// <param name="autoDrillingSystem">Система автобурения</param>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<Dictionary<string, int>> GetStatistics(int? importantId, string? autoDrillingSystem, CancellationToken token);
|
Task<IEnumerable<MessagesStatisticDto>> GetStatistics(IEnumerable<string> autoDrillingSystem, IEnumerable<int> categoryIds, CancellationToken token);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Получить порцию записей, начиная с заданной даты
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dateBegin"></param>
|
||||||
|
/// <param name="take"></param>
|
||||||
|
/// <param name="token"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<IEnumerable<TechMessageDto>> GetPart(DateTimeOffset dateBegin, int take, CancellationToken token);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Получить диапазон дат, для которых есть данные в репозитории
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="token"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<DatesRangeDto> GetDatesRangeAsync(CancellationToken token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user