feat(api): RobotHistoryController - сохранение истории работы робота

This commit is contained in:
Mikhail Trubnikov
2023-10-06 13:58:10 +10:00
parent d334e46780
commit 9060db1fe4
14 changed files with 2228 additions and 187 deletions

View File

@@ -71,10 +71,10 @@
public const string templateId = "{templateId}"; public const string templateId = "{templateId}";
} }
public static class RobotTemplateHistory public static class RobotHistory
{ {
public const string GetAll = Base + "/robot-template-histories/"; //public const string GetAll = Base + "/robot-histories/";
public const string Create = Base + "/robot-template-histories/"; public const string Create = Base + "/robot-histories/";
} }
public static class StatusTemplate public static class StatusTemplate

View File

@@ -0,0 +1,15 @@
using PARR.DAL.Contracts;
namespace PARR.API.Contracts.V1.Requests
{
public class RobotHistoryRequest
{
public RobotHistoryLevelEnum HistoryLevel { get; set; }
public string? RobotMessage { get; set; }
public string? EsppMessage { get; set; }
public Guid TaskId { get; set; }
}
}

View File

@@ -1,18 +0,0 @@
namespace PARR.API.Contracts.V1.Requests
{
public class RobotTemplateHistoryRequest
{
public int HistoryLevel { get; set; }
public string? RobotMessage { get; set; }
public string? EsppMessage { get; set; }
public Guid TemplateId { get; set; }
/// <summary>
/// ИД серии - идентификатор полного цикла выполнения роботом текущего задания. Если не передать, сгенерируется автоматически, в дальнейшем в рамках шагов по текущему заданию использовать его.
/// </summary>
public Guid? IdSeries { get; set; }
}
}

View File

@@ -1,6 +1,6 @@
namespace PARR.API.Contracts.V1.Responses namespace PARR.API.Contracts.V1.Responses
{ {
public class RobotTemplateHistoryResponse public class RobotHistoryResponse
{ {
public Guid Id { get; set; } public Guid Id { get; set; }
@@ -10,13 +10,9 @@
public string? EsppMessage { get; set; } public string? EsppMessage { get; set; }
public int TemplateStatusCode { get; set; } public int TaskStatusCode { get; set; }
public Guid TemplateId { get; set; } public Guid TaskId { get; set; }
public string TemplateName { get; set; } = string.Empty;
public Guid IdSeries { get; set; }
public RobotHistoryLevelResponse? Level { get; set; } public RobotHistoryLevelResponse? Level { get; set; }

View File

@@ -0,0 +1,126 @@
using AutoMapper;
using FluentValidation;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using PARR.API.Contracts.V1;
using PARR.API.Contracts.V1.Requests;
using PARR.API.Contracts.V1.Responses;
using PARR.API.Contracts.V1.Responses.Base;
using PARR.API.Controllers.V1.Base;
using PARR.API.Services.Interfaces;
using PARR.DAL.Models;
using PARR.DAL.Services.Interfaces;
namespace PARR.API.Controllers.V1
{
public class RobotHistoryController : BaseApiController
{
private readonly IValidator<RobotHistoryRequest> validator;
private readonly ITemplateService templateService;
private readonly IRobotTemplateHistoryService historyService;
private readonly IMapper mapper;
private readonly IUriService uriService;
private readonly IRobotHistoryService robotHistoryService;
private readonly IRobotConfigurationService robotConfigurationService;
public RobotHistoryController(
IValidator<RobotHistoryRequest> validator,
ITemplateService templateService,
IRobotTemplateHistoryService historyService,
IMapper mapper,
IUriService uriService,
IRobotHistoryService robotHistoryService,
IRobotConfigurationService robotConfigurationService
)
{
this.validator = validator;
this.templateService = templateService;
this.historyService = historyService;
this.mapper = mapper;
this.uriService = uriService;
this.robotHistoryService = robotHistoryService;
this.robotConfigurationService = robotConfigurationService;
}
///// <summary>
///// Получить историю робота шаблонов
///// </summary>
///// <param name="paginationQuery"></param>
///// <param name="filter"></param>
///// <returns></returns>
//[HttpGet(ApiRoutes.RobotTemplateHistory.GetAll)]
//public async Task<IActionResult> GetAll([FromQuery] PaginationQuery paginationQuery, [FromQuery] RobotTemplateHistoryQuery filter)
//{
// var paginationFilter = mapper.Map<PaginationFilter>(paginationQuery);
// IQueryable<RobotTemplateHistory> query = historyService.Get()
// .Include(t => t.Template)
// .Include(t => t.RobotHistoryLevel)
// .OrderByDescending(t => t.DateCreated).ThenBy(t => t.IdSeries);
// if (filter.IdSeries != null)
// query = query.Where(t => t.IdSeries == filter.IdSeries);
// if (filter.TemplateId != null)
// query = query.Where(t => t.TemplateId == filter.TemplateId);
// var history = await historyService.GetPage(query, paginationFilter).ToListAsync();
// if (!history.Any())
// return NoContent();
// var response = mapper.Map<List<RobotTemplateHistoryResponse>>(history);
// var paginationResponse = new PagedResponse<RobotTemplateHistoryResponse>(response, true).GetPaginatedProps(paginationFilter, query);
// return Ok(paginationResponse);
//}
/// <summary>
/// Добавить историю работы робота
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
[HttpPost(ApiRoutes.RobotHistory.Create)]
public async Task<IActionResult> Create([FromBody] RobotHistoryRequest request)
{
var resultValidate = await validator.ValidateAsync(request);
if (!resultValidate.IsValid)
return BadRequest(new Response(resultValidate.Errors));
var config = await robotConfigurationService.GetAsync(request.TaskId);
if (config == null)
return BadRequest(new Response(false, new List<ErrorModel> { new ErrorModel { Message = $"Не найдено задание с id: {request.TaskId}" } }));
var history = new RobotHistory
{
Id = Guid.NewGuid(),
HistoryLevel = (int)request.HistoryLevel,
RobotMessage = request.RobotMessage,
EsppMessage = request.EsppMessage,
TaskStatusCode = config.TaskStatusCode,
RobotConfigurationId = request.TaskId
};
if (!await robotHistoryService.CreateAsync(history) || !await robotHistoryService.CommitAsync())
return BadRequest(new Response(false, new List<ErrorModel> { new ErrorModel { Message = $"Ошибка при добавлении записи в историю" } }));
var createdObj = await robotHistoryService.Get()
.Include(t => t.RobotConfiguration)
.Include(t => t.RobotHistoryLevel)
.FirstOrDefaultAsync(t => t.Id == history.Id);
var response = mapper.Map<RobotHistoryResponse>(createdObj);
//todo: createdUri
//var createdUri = uriService.GetAllUri(ApiRoutes.RobotTemplateHistory.GetAll) + $"?{nameof(RobotTemplateHistoryQuery.IdSeries)}={createdObj!.IdSeries}";
var createdUri = "";
return Created(createdUri, new Response<RobotHistoryResponse>(response, true));
}
}
}

View File

@@ -1,126 +0,0 @@
using AutoMapper;
using FluentValidation;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using PARR.API.Contracts.V1;
using PARR.API.Contracts.V1.Requests;
using PARR.API.Contracts.V1.Requests.Queries;
using PARR.API.Contracts.V1.Responses;
using PARR.API.Contracts.V1.Responses.Base;
using PARR.API.Controllers.V1.Base;
using PARR.API.Extensions;
using PARR.API.Services.Interfaces;
using PARR.DAL.DomainModels;
using PARR.DAL.Models;
using PARR.DAL.Services.Interfaces;
namespace PARR.API.Controllers.V1
{
public class RobotTemplateHistoryController : BaseApiController
{
private readonly IValidator<RobotTemplateHistoryRequest> validator;
private readonly ITemplateService templateService;
private readonly IRobotTemplateHistoryService historyService;
private readonly IMapper mapper;
private readonly IUriService uriService;
public RobotTemplateHistoryController(
IValidator<RobotTemplateHistoryRequest> validator,
ITemplateService templateService,
IRobotTemplateHistoryService historyService,
IMapper mapper,
IUriService uriService
)
{
this.validator = validator;
this.templateService = templateService;
this.historyService = historyService;
this.mapper = mapper;
this.uriService = uriService;
}
/// <summary>
/// Получить историю робота шаблонов
/// </summary>
/// <param name="paginationQuery"></param>
/// <param name="filter"></param>
/// <returns></returns>
[HttpGet(ApiRoutes.RobotTemplateHistory.GetAll)]
public async Task<IActionResult> GetAll([FromQuery] PaginationQuery paginationQuery, [FromQuery] RobotTemplateHistoryQuery filter)
{
var paginationFilter = mapper.Map<PaginationFilter>(paginationQuery);
IQueryable<RobotTemplateHistory> query = historyService.Get()
.Include(t => t.Template)
.Include(t => t.RobotHistoryLevel)
.OrderByDescending(t => t.DateCreated).ThenBy(t => t.IdSeries);
if (filter.IdSeries != null)
query = query.Where(t => t.IdSeries == filter.IdSeries);
if (filter.TemplateId != null)
query = query.Where(t => t.TemplateId == filter.TemplateId);
var history = await historyService.GetPage(query, paginationFilter).ToListAsync();
if (!history.Any())
return NoContent();
var response = mapper.Map<List<RobotTemplateHistoryResponse>>(history);
var paginationResponse = new PagedResponse<RobotTemplateHistoryResponse>(response, true).GetPaginatedProps(paginationFilter, query);
return Ok(paginationResponse);
}
/// <summary>
/// Добавить историю робота шаблонов
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
[HttpPost(ApiRoutes.RobotTemplateHistory.Create)]
public async Task<IActionResult> Create([FromBody] RobotTemplateHistoryRequest request)
{
var resultValidate = await validator.ValidateAsync(request);
if (!resultValidate.IsValid)
return BadRequest(new Response(resultValidate.Errors));
var template = await templateService.GetAsync(request.TemplateId);
if (template == null)
return BadRequest(new Response(false, new List<ErrorModel> { new ErrorModel { Message = $"Не найден шаблон с id: {request.TemplateId}" } }));
if (request.IdSeries == null)
request.IdSeries = Guid.NewGuid();
//var historyItem = new RobotTemplateHistory
//{
// Id = Guid.NewGuid(),
// HistoryLevel = request.HistoryLevel,
// RobotMessage = request.RobotMessage,
// EsppMessage = request.EsppMessage,
// TemplateId = request.TemplateId,
// TemplateStatusCode = template.StatusCode,
// IdSeries = request.IdSeries.Value
//};
//if (!await historyService.CreateAsync(historyItem) || !await historyService.CommitAsync())
// return BadRequest(new Response(false, new List<ErrorModel> { new ErrorModel { Message = $"Ошибка при добавлении записи в историю" } }));
//var createdObj = await historyService.Get()
// .Include(t => t.Template)
// .Include(t => t.RobotHistoryLevel)
// .FirstOrDefaultAsync(t => t.Id == historyItem.Id);
//var response = mapper.Map<RobotTemplateHistoryResponse>(createdObj);
//var createdUri = uriService.GetAllUri(ApiRoutes.RobotTemplateHistory.GetAll) + $"?{nameof(RobotTemplateHistoryQuery.IdSeries)}={createdObj!.IdSeries}";
//return Created(createdUri, new Response<RobotTemplateHistoryResponse>(response, true));
return Ok("Доделать");
}
}
}

View File

@@ -87,10 +87,10 @@ namespace PARR.API.MappingProfiles
CreateMap<RobotHistoryLevel, RobotHistoryLevelResponse>(); CreateMap<RobotHistoryLevel, RobotHistoryLevelResponse>();
CreateMap<RobotTemplateHistory, RobotTemplateHistoryResponse>() CreateMap<RobotHistory, RobotHistoryResponse>()
.ForMember(d => d.Level, o => o.MapFrom(s => s.RobotHistoryLevel)) .ForMember(d => d.Level, o => o.MapFrom(s => s.RobotHistoryLevel))
.ForMember(d => d.Date, o => o.MapFrom(s => s.DateCreated)) .ForMember(d => d.Date, o => o.MapFrom(s => s.DateCreated))
.ForMember(d => d.TemplateName, o => o.MapFrom(s => s.Template!.Name)); .ForMember(d => d.TaskId, o => o.MapFrom(s => s.RobotConfigurationId));
// --- RobotConfiguration --- // --- RobotConfiguration ---

View File

@@ -0,0 +1,18 @@
using FluentValidation;
using PARR.API.Contracts.V1.Requests;
using PARR.DAL.Contracts;
namespace PARR.API.Validators
{
public class RobotHistoryRequestValidator : AbstractValidator<RobotHistoryRequest>
{
public RobotHistoryRequestValidator()
{
RuleFor(r => r.HistoryLevel)
.Must(t => t == RobotHistoryLevelEnum.Inforamtion || t == RobotHistoryLevelEnum.Error)
.WithMessage($"Допустимые значения: {(int)RobotHistoryLevelEnum.Inforamtion}, {(int)RobotHistoryLevelEnum.Error}");
RuleFor(r => r.TaskId).NotNull().NotEmpty();
}
}
}

View File

@@ -1,17 +0,0 @@
using FluentValidation;
using PARR.API.Contracts.V1.Requests;
using PARR.DAL.Contracts;
namespace PARR.API.Validators
{
public class RobotTemplateHistoryRequestValidator : AbstractValidator<RobotTemplateHistoryRequest>
{
public RobotTemplateHistoryRequestValidator()
{
var levels = new List<int> { (int)RobotHistoryLevelEnum.Start, (int)RobotHistoryLevelEnum.Inforamtion, (int)RobotHistoryLevelEnum.Error, (int)RobotHistoryLevelEnum.Complete, (int)RobotHistoryLevelEnum.Breake };
RuleFor(r => r.HistoryLevel).Must(t => levels.Contains(t)).WithMessage($"Допустимые значения: {string.Join(", ", levels)}");
RuleFor(r => r.TemplateId).NotNull().NotEmpty();
}
}
}

View File

@@ -188,8 +188,7 @@ namespace PARR.DAL.Context
new { Level = (int)RobotHistoryLevelEnum.Start, Name = RobotHistoryLevelEnum.Start.ToString(), Description = "Робот начал работу " }, new { Level = (int)RobotHistoryLevelEnum.Start, Name = RobotHistoryLevelEnum.Start.ToString(), Description = "Робот начал работу " },
new { Level = (int)RobotHistoryLevelEnum.Inforamtion, Name = RobotHistoryLevelEnum.Inforamtion.ToString(), Description = "Информация" }, new { Level = (int)RobotHistoryLevelEnum.Inforamtion, Name = RobotHistoryLevelEnum.Inforamtion.ToString(), Description = "Информация" },
new { Level = (int)RobotHistoryLevelEnum.Error, Name = RobotHistoryLevelEnum.Error.ToString(), Description = "Ошибка" }, new { Level = (int)RobotHistoryLevelEnum.Error, Name = RobotHistoryLevelEnum.Error.ToString(), Description = "Ошибка" },
new { Level = (int)RobotHistoryLevelEnum.Complete, Name = RobotHistoryLevelEnum.Complete.ToString(), Description = "Успешно завершил работу" }, new { Level = (int)RobotHistoryLevelEnum.Complete, Name = RobotHistoryLevelEnum.Complete.ToString(), Description = "Успешно завершил работу" }
new { Level = (int)RobotHistoryLevelEnum.Breake, Name = RobotHistoryLevelEnum.Breake.ToString(), Description = "Завершил работу с ошибкой (не отработал до конца)" }
); );
}); });

View File

@@ -23,11 +23,6 @@
/// <summary> /// <summary>
/// Успешно завершил работу /// Успешно завершил работу
/// </summary> /// </summary>
Complete = 15, Complete = 15
/// <summary>
/// Завершил работу с ошибкой (не отработал до конца)
/// </summary>
Breake = 20
} }
} }

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,28 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace PARR.DAL.Migrations
{
/// <inheritdoc />
public partial class TblRobotHistoryLevelRmBreake : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DeleteData(
table: "RobotHistoryLevels",
keyColumn: "Level",
keyValue: 20);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.InsertData(
table: "RobotHistoryLevels",
columns: new[] { "Level", "Description", "Name" },
values: new object[] { 20, "Завершил работу с ошибкой (не отработал до конца)", "Breake" });
}
}
}

View File

@@ -896,12 +896,6 @@ namespace PARR.DAL.Migrations
Level = 15, Level = 15,
Description = "Успешно завершил работу", Description = "Успешно завершил работу",
Name = "Complete" Name = "Complete"
},
new
{
Level = 20,
Description = "Завершил работу с ошибкой (не отработал до конца)",
Name = "Breake"
}); });
}); });