diff --git a/Persistence.API/Controllers/DataSaubController.cs b/Persistence.API/Controllers/DataSaubController.cs
index 63069a9..202e527 100644
--- a/Persistence.API/Controllers/DataSaubController.cs
+++ b/Persistence.API/Controllers/DataSaubController.cs
@@ -4,6 +4,10 @@ using Persistence.Repositories;
using Persistence.Repository.Data;
namespace Persistence.API.Controllers;
+
+///
+/// Работа с временными данными
+///
[ApiController]
[Authorize]
[Route("api/[controller]")]
diff --git a/Persistence.API/Controllers/SetpointController.cs b/Persistence.API/Controllers/SetpointController.cs
index 9a6bd61..42a5ff5 100644
--- a/Persistence.API/Controllers/SetpointController.cs
+++ b/Persistence.API/Controllers/SetpointController.cs
@@ -1,53 +1,112 @@
-using Microsoft.AspNetCore.Authorization;
+using System.Net;
+using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Persistence.Models;
using Persistence.Repositories;
-namespace Persistence.API.Controllers
+namespace Persistence.API.Controllers;
+
+///
+/// Работа с уставками
+///
+[ApiController]
+[Authorize]
+[Route("api/[controller]")]
+public class SetpointController : ControllerBase, ISetpointApi
{
- [ApiController]
- [Authorize]
- [Route("api/[controller]")]
- public class SetpointController : ControllerBase, ISetpointApi
+ private readonly ISetpointRepository setpointRepository;
+
+ public SetpointController(ISetpointRepository setpointRepository)
{
- private readonly ISetpointRepository setpointRepository;
+ this.setpointRepository = setpointRepository;
+ }
- public SetpointController(ISetpointRepository setpointRepository)
- {
- this.setpointRepository = setpointRepository;
- }
+ ///
+ /// Получить актуальные значения уставок
+ ///
+ ///
+ ///
+ ///
+ [HttpGet("current")]
+ public async Task>> GetCurrent([FromQuery] IEnumerable setpointKeys, CancellationToken token)
+ {
+ var result = await setpointRepository.GetCurrent(setpointKeys, token);
- [HttpGet("current")]
- public async Task>> GetCurrent([FromQuery] IEnumerable setpointKeys, CancellationToken token)
- {
- var result = await setpointRepository.GetCurrent(setpointKeys, token);
+ return Ok(result);
+ }
- return Ok(result);
- }
+ ///
+ /// Получить значения уставок за определенный момент времени
+ ///
+ ///
+ ///
+ ///
+ ///
+ [HttpGet("history")]
+ public async Task>> GetHistory([FromQuery] IEnumerable setpointKeys, [FromQuery] DateTimeOffset historyMoment, CancellationToken token)
+ {
+ var result = await setpointRepository.GetHistory(setpointKeys, historyMoment, token);
- [HttpGet("history")]
- public async Task>> GetHistory([FromQuery] IEnumerable setpointKeys, [FromQuery] DateTimeOffset historyMoment, CancellationToken token)
- {
- var result = await setpointRepository.GetHistory(setpointKeys, historyMoment, token);
+ return Ok(result);
+ }
- return Ok(result);
- }
+ ///
+ /// Получить историю изменений значений уставок
+ ///
+ ///
+ ///
+ ///
+ [HttpGet("log")]
+ public async Task>>> GetLog([FromQuery] IEnumerable setpointKeys, CancellationToken token)
+ {
+ var result = await setpointRepository.GetLog(setpointKeys, token);
- [HttpGet("log")]
- public async Task>>> GetLog([FromQuery] IEnumerable setpointKeys, CancellationToken token)
- {
- var result = await setpointRepository.GetLog(setpointKeys, token);
+ return Ok(result);
+ }
- return Ok(result);
- }
+ ///
+ /// Получить диапазон дат, для которых есть данные в репозитории
+ ///
+ ///
+ ///
+ [HttpGet("range")]
+ public async Task> GetDatesRangeAsync(CancellationToken token)
+ {
+ var result = await setpointRepository.GetDatesRangeAsync(token);
- [HttpPost]
- public async Task> Save(Guid setpointKey, object newValue, CancellationToken token)
- {
- // ToDo: вычитка idUser
- await setpointRepository.Save(setpointKey, newValue, 0, token);
+ return Ok(result);
+ }
- return Ok();
- }
+ ///
+ /// Получить порцию записей, начиная с заданной даты
+ ///
+ ///
+ ///
+ ///
+ ///
+ [HttpGet("part")]
+ public async Task>> GetPart(DateTimeOffset dateBegin, int take, CancellationToken token)
+ {
+ var result = await setpointRepository.GetPart(dateBegin, take, token);
+
+ return Ok(result);
+ }
+
+ ///
+ /// Сохранить уставку
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ [HttpPost]
+ [ProducesResponseType(typeof(int), (int)HttpStatusCode.Created)]
+ public async Task Add(Guid setpointKey, object newValue, CancellationToken token)
+ {
+ var userId = User.GetUserId();
+ await setpointRepository.Add(setpointKey, newValue, userId, token);
+
+ return CreatedAtAction(nameof(Add), true);
}
}
diff --git a/Persistence.API/Controllers/TechMessagesController.cs b/Persistence.API/Controllers/TechMessagesController.cs
new file mode 100644
index 0000000..d2691c1
--- /dev/null
+++ b/Persistence.API/Controllers/TechMessagesController.cs
@@ -0,0 +1,128 @@
+using System.Net;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using Persistence.Models;
+using Persistence.Repositories;
+
+namespace Persistence.API.Controllers;
+
+///
+/// Работа с состояниями систем автобурения (АБ)
+///
+[ApiController]
+[Authorize]
+[Route("api/[controller]")]
+public class TechMessagesController : ControllerBase
+{
+ private readonly ITechMessagesRepository techMessagesRepository;
+ private static readonly Dictionary categories = new Dictionary()
+ {
+ { 0, "System" },
+ { 1, "Авария" },
+ { 2, "Предупреждение" },
+ { 3, "Инфо" },
+ { 4, "Прочее" }
+ };
+
+ public TechMessagesController(ITechMessagesRepository techMessagesRepository)
+ {
+ this.techMessagesRepository = techMessagesRepository;
+ }
+
+ ///
+ /// Получить список технологических сообщений в виде страницы
+ ///
+ ///
+ ///
+ ///
+ [HttpGet]
+ public async Task>> GetPage([FromQuery] RequestDto request, CancellationToken token)
+ {
+ var result = await techMessagesRepository.GetPage(request, token);
+
+ return Ok(result);
+ }
+
+ ///
+ /// Получить статистику по системам
+ ///
+ ///
+ ///
+ ///
+ ///
+ [HttpGet("statistics")]
+ public async Task>> GetStatistics([FromQuery] IEnumerable autoDrillingSystem, [FromQuery] IEnumerable categoryIds, CancellationToken token)
+ {
+ var result = await techMessagesRepository.GetStatistics(autoDrillingSystem, categoryIds, token);
+
+ return Ok(result);
+ }
+
+ ///
+ /// Получить список всех систем
+ ///
+ ///
+ ///
+ [HttpGet("systems")]
+ public async Task>> GetSystems(CancellationToken token)
+ {
+ var result = await techMessagesRepository.GetSystems(token);
+
+ return Ok(result);
+ }
+
+ ///
+ /// Получить диапазон дат, для которых есть данные в репозитории
+ ///
+ ///
+ ///
+ [HttpGet("range")]
+ public async Task> GetDatesRangeAsync(CancellationToken token)
+ {
+ var result = await techMessagesRepository.GetDatesRangeAsync(token);
+
+ return Ok(result);
+ }
+
+ ///
+ /// Получить порцию записей, начиная с заданной даты
+ ///
+ ///
+ ///
+ ///
+ ///
+ [HttpGet("part")]
+ public async Task>> GetPart(DateTimeOffset dateBegin, int take, CancellationToken token)
+ {
+ var result = await techMessagesRepository.GetPart(dateBegin, take, token);
+
+ return Ok(result);
+ }
+
+ ///
+ /// Добавить новые технологические сообщения
+ ///
+ ///
+ ///
+ ///
+ [HttpPost]
+ [ProducesResponseType(typeof(int), (int)HttpStatusCode.Created)]
+ public async Task AddRange([FromBody] IEnumerable dtos, CancellationToken token)
+ {
+ var userId = User.GetUserId();
+
+ var result = await techMessagesRepository.AddRange(dtos, userId, token);
+
+ return CreatedAtAction(nameof(AddRange), result);
+ }
+
+ ///
+ /// Получить словарь категорий
+ ///
+ ///
+ [HttpGet("categories")]
+ public ActionResult> GetImportantCategories()
+ {
+ return Ok(categories);
+ }
+}
\ No newline at end of file
diff --git a/Persistence.API/Controllers/TimeSeriesController.cs b/Persistence.API/Controllers/TimeSeriesController.cs
index a4a860a..6991759 100644
--- a/Persistence.API/Controllers/TimeSeriesController.cs
+++ b/Persistence.API/Controllers/TimeSeriesController.cs
@@ -4,6 +4,7 @@ using Persistence.Models;
using Persistence.Repositories;
namespace Persistence.API.Controllers;
+
[ApiController]
[Authorize]
[Route("api/[controller]")]
@@ -12,37 +13,62 @@ public class TimeSeriesController : ControllerBase, ITimeSeriesDataApi timeSeriesDataRepository;
- public TimeSeriesController(ITimeSeriesDataRepository timeSeriesDataRepository)
- {
- this.timeSeriesDataRepository = timeSeriesDataRepository;
+ public TimeSeriesController(ITimeSeriesDataRepository timeSeriesDataRepository)
+ {
+ this.timeSeriesDataRepository = timeSeriesDataRepository;
}
- [HttpGet]
+ ///
+ /// Получить список объектов, удовлетворяющий диапазону дат
+ ///
+ ///
+ ///
+ ///
+ [HttpGet]
[ProducesResponseType(StatusCodes.Status200OK)]
public async Task Get(DateTimeOffset dateBegin, CancellationToken token)
{
- var result = await this.timeSeriesDataRepository.GetGtDate(dateBegin, token);
+ var result = await timeSeriesDataRepository.GetGtDate(dateBegin, token);
return Ok(result);
}
- [HttpGet("datesRange")]
+ ///
+ /// Получить диапазон дат, для которых есть данные в репозиторие
+ ///
+ ///
+ ///
+ [HttpGet("datesRange")]
public async Task GetDatesRange(CancellationToken token)
{
- var result = await this.timeSeriesDataRepository.GetDatesRange(token);
+ var result = await timeSeriesDataRepository.GetDatesRange(token);
return Ok(result);
}
- [HttpGet("resampled")]
+ ///
+ /// Получить список объектов с прореживанием, удовлетворяющий диапазону дат
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ [HttpGet("resampled")]
public async Task 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);
}
- [HttpPost]
- public async Task InsertRange(IEnumerable dtos, CancellationToken token)
+ ///
+ /// Добавить записи
+ ///
+ ///
+ ///
+ ///
+ [HttpPost]
+ public async Task AddRange(IEnumerable dtos, CancellationToken token)
{
- var result = await this.timeSeriesDataRepository.InsertRange(dtos, token);
+ var result = await timeSeriesDataRepository.AddRange(dtos, token);
return Ok(result);
}
diff --git a/Persistence.API/Controllers/TimestampedSetController.cs b/Persistence.API/Controllers/TimestampedSetController.cs
index f18e4c8..bd0e97e 100644
--- a/Persistence.API/Controllers/TimestampedSetController.cs
+++ b/Persistence.API/Controllers/TimestampedSetController.cs
@@ -32,9 +32,9 @@ public class TimestampedSetController : ControllerBase
/// кол-во затронутых записей
[HttpPost]
[ProducesResponseType(typeof(int), (int)HttpStatusCode.OK)]
- public async Task InsertRange([FromRoute]Guid idDiscriminator, [FromBody]IEnumerable sets, CancellationToken token)
+ public async Task AddRange([FromRoute]Guid idDiscriminator, [FromBody]IEnumerable sets, CancellationToken token)
{
- var result = await repository.InsertRange(idDiscriminator, sets, token);
+ var result = await repository.AddRange(idDiscriminator, sets, token);
return Ok(result);
}
diff --git a/Persistence.API/DependencyInjection.cs b/Persistence.API/DependencyInjection.cs
index cdfca4c..19cedc9 100644
--- a/Persistence.API/DependencyInjection.cs
+++ b/Persistence.API/DependencyInjection.cs
@@ -1,8 +1,12 @@
+using System.Reflection;
using System.Text.Json.Nodes;
+using Mapster;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Any;
using Microsoft.OpenApi.Models;
+using Persistence.Database.Entity;
+using Persistence.Models;
using Persistence.Models.Configurations;
using Swashbuckle.AspNetCore.SwaggerGen;
@@ -10,6 +14,12 @@ namespace Persistence.API;
public static class DependencyInjection
{
+ public static void MapsterSetup()
+ {
+ TypeAdapterConfig.GlobalSettings.Default.Config
+ .ForType()
+ .Ignore(dest => dest.System, dest => dest.SystemId);
+ }
public static void AddSwagger(this IServiceCollection services, IConfiguration configuration)
{
services.AddSwaggerGen(c =>
@@ -38,11 +48,10 @@ public static class DependencyInjection
c.AddKeycloackSecurity(configuration);
else c.AddDefaultSecurity(configuration);
- //var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
- //var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
- //var includeControllerXmlComment = true;
- //options.IncludeXmlComments(xmlPath, includeControllerXmlComment);
- //options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, "AsbCloudApp.xml"), includeControllerXmlComment);
+ var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
+ var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
+ var includeControllerXmlComment = true;
+ c.IncludeXmlComments(xmlPath, includeControllerXmlComment);
});
}
diff --git a/Persistence.API/Persistence.API.csproj b/Persistence.API/Persistence.API.csproj
index 2b8cb73..dfff363 100644
--- a/Persistence.API/Persistence.API.csproj
+++ b/Persistence.API/Persistence.API.csproj
@@ -5,10 +5,13 @@
enable
enable
Linux
+ True
+ $(NoWarn);1591
-
+
+
diff --git a/Persistence.API/Startup.cs b/Persistence.API/Startup.cs
index e074845..98ad4aa 100644
--- a/Persistence.API/Startup.cs
+++ b/Persistence.API/Startup.cs
@@ -23,6 +23,9 @@ public class Startup
services.AddInfrastructure();
services.AddPersistenceDbContext(Configuration);
services.AddJWTAuthentication(Configuration);
+ services.AddMemoryCache();
+
+ DependencyInjection.MapsterSetup();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
diff --git a/Persistence.Client/Clients/ISetpointClient.cs b/Persistence.Client/Clients/ISetpointClient.cs
index 49733f0..0b81ffa 100644
--- a/Persistence.Client/Clients/ISetpointClient.cs
+++ b/Persistence.Client/Clients/ISetpointClient.cs
@@ -4,7 +4,7 @@ using Refit;
namespace Persistence.Client.Clients;
///
-/// Интерфейс для тестирования API, предназначенного для работы с уставками
+/// Интерфейс клиента для работы с уставками
///
public interface ISetpointClient
{
@@ -19,6 +19,12 @@ public interface ISetpointClient
[Get($"{BaseRoute}/log")]
Task>>> GetLog([Query(CollectionFormat.Multi)] IEnumerable setpointKeys);
+ [Get($"{BaseRoute}/range")]
+ Task> GetDatesRangeAsync(CancellationToken token);
+
+ [Get($"{BaseRoute}/part")]
+ Task>> GetPart(DateTimeOffset dateBegin, int take, CancellationToken token);
+
[Post($"{BaseRoute}/")]
- Task Save(Guid setpointKey, object newValue);
+ Task Add(Guid setpointKey, object newValue);
}
diff --git a/Persistence.Client/Clients/ITechMessagesClient.cs b/Persistence.Client/Clients/ITechMessagesClient.cs
new file mode 100644
index 0000000..878c6cf
--- /dev/null
+++ b/Persistence.Client/Clients/ITechMessagesClient.cs
@@ -0,0 +1,31 @@
+using Persistence.Models;
+using Refit;
+
+namespace Persistence.Client.Clients
+{
+ ///
+ /// Интерфейс клиента для хранения технологических сообщений
+ ///
+ public interface ITechMessagesClient
+ {
+ private const string BaseRoute = "/api/techMessages";
+
+ [Get($"{BaseRoute}")]
+ Task>> GetPage([Query] RequestDto request, CancellationToken token);
+
+ [Post($"{BaseRoute}")]
+ Task> AddRange([Body] IEnumerable dtos, CancellationToken token);
+
+ [Get($"{BaseRoute}/systems")]
+ Task>> GetSystems(CancellationToken token);
+
+ [Get($"{BaseRoute}/range")]
+ Task> GetDatesRangeAsync(CancellationToken token);
+
+ [Get($"{BaseRoute}/part")]
+ Task>> GetPart(DateTimeOffset dateBegin, int take, CancellationToken token);
+
+ [Get($"{BaseRoute}/statistics")]
+ Task>> GetStatistics([Query] string autoDrillingSystem, [Query] int categoryId, CancellationToken token);
+ }
+}
diff --git a/Persistence.Client/Clients/ITimeSeriesClient.cs b/Persistence.Client/Clients/ITimeSeriesClient.cs
index 8f7ef0e..8e97836 100644
--- a/Persistence.Client/Clients/ITimeSeriesClient.cs
+++ b/Persistence.Client/Clients/ITimeSeriesClient.cs
@@ -1,5 +1,4 @@
-using Microsoft.AspNetCore.Mvc;
-using Persistence.Models;
+using Persistence.Models;
using Refit;
namespace Persistence.Client.Clients;
@@ -9,7 +8,7 @@ public interface ITimeSeriesClient
private const string BaseRoute = "/api/dataSaub";
[Post($"{BaseRoute}")]
- Task> InsertRange(IEnumerable dtos);
+ Task> AddRange(IEnumerable dtos);
[Get($"{BaseRoute}")]
Task>> Get(DateTimeOffset dateBegin, DateTimeOffset dateEnd);
diff --git a/Persistence.Client/Clients/ITimestampedSetClient.cs b/Persistence.Client/Clients/ITimestampedSetClient.cs
index 95e8bd1..bbff603 100644
--- a/Persistence.Client/Clients/ITimestampedSetClient.cs
+++ b/Persistence.Client/Clients/ITimestampedSetClient.cs
@@ -20,7 +20,7 @@ public interface ITimestampedSetClient
///
///
[Post(baseUrl)]
- Task> InsertRange(Guid idDiscriminator, IEnumerable sets);
+ Task> AddRange(Guid idDiscriminator, IEnumerable sets);
///
/// Получение данных с фильтрацией. Значение фильтра null - отключен
diff --git a/Persistence.Client/Helpers/ApiTokenHelper.cs b/Persistence.Client/Helpers/ApiTokenHelper.cs
index e508922..5eed66e 100644
--- a/Persistence.Client/Helpers/ApiTokenHelper.cs
+++ b/Persistence.Client/Helpers/ApiTokenHelper.cs
@@ -29,8 +29,10 @@ public static class ApiTokenHelper
private static string CreateDefaultJwtToken(this AuthUser authUser)
{
+ var nameIdetifier = Guid.NewGuid().ToString();
var claims = new List()
{
+ new(ClaimTypes.NameIdentifier, nameIdetifier),
new("client_id", authUser.ClientId),
new("username", authUser.Username),
new("password", authUser.Password),
diff --git a/Persistence.Database.Postgres/Migrations/20241118052225_SetpointMigration.cs b/Persistence.Database.Postgres/Migrations/20241118052225_SetpointMigration.cs
index 49e438a..ea6fccf 100644
--- a/Persistence.Database.Postgres/Migrations/20241118052225_SetpointMigration.cs
+++ b/Persistence.Database.Postgres/Migrations/20241118052225_SetpointMigration.cs
@@ -18,7 +18,7 @@ namespace Persistence.Database.Postgres.Migrations
Key = table.Column(type: "uuid", nullable: false, comment: "Ключ"),
Created = table.Column(type: "timestamp with time zone", nullable: false, comment: "Дата изменения уставки"),
Value = table.Column