feat(api): Контроллер RobotTaskRobotStatusController управления статусами работы робота

This commit is contained in:
Mikhail Trubnikov
2023-10-06 11:38:33 +10:00
parent 1934f7c645
commit d334e46780
21 changed files with 4313 additions and 20 deletions

View File

@@ -99,12 +99,19 @@
public static class RobotTask public static class RobotTask
{ {
public const string GetByRobotAndStatusTask = Base + "/robot-tasks/" + robotCode + "/statuses/" + taskStatusCode; public const string GetByRobotAndStatusTask = Base + "/robot-tasks/robots/" + robotCode + "/statuses/" + taskStatusCode;
public const string robotCode = "{robotCode}"; public const string robotCode = "{robotCode}";
public const string taskStatusCode = "{taskStatusCode}"; public const string taskStatusCode = "{taskStatusCode}";
} }
public static class RobotTaskRobotStatus
{
public const string ChangeRobotStatus = Base + "/robot-tasks/" + taskId + "/robot-status";
public const string taskId = "{taskId}";
}
//public static class Layer //public static class Layer
//{ //{

View File

@@ -0,0 +1,12 @@
using PARR.DAL.Contracts;
namespace PARR.API.Contracts.V1.Requests
{
public class RobotTaskChangeRobotStatusRequest
{
/// <summary>
/// Статус робота
/// </summary>
public RobotStatusEnum RobotStatusCode { get; set; }
}
}

View File

@@ -1,5 +1,6 @@
namespace PARR.API.Contracts.V1.Requests namespace PARR.API.Contracts.V1.Requests
{ {
//todo: delete
public class TemplateRobotStatusRequest public class TemplateRobotStatusRequest
{ {
public int Code { get; set; } public int Code { get; set; }

View File

@@ -2,6 +2,21 @@
{ {
public class RobotConfigurationResponse public class RobotConfigurationResponse
{ {
public Guid Id { get; set; }
public DateTimeOffset DateCreated { get; set; }
public Guid TemplateId { get; set; }
public RobotResponse? Robot { get; set; }
public TaskStatusResponse? TaskStatus { get; set; }
public RobotStatusResponse? RobotStatus { get; set; }
public int AttemptsNumber { get; set; }
public DateTimeOffset? LastRobotStatusUpdated { get; set; }
} }
} }

View File

@@ -0,0 +1,9 @@
namespace PARR.API.Contracts.V1.Responses
{
public class RobotResponse
{
public int Code { get; set; }
public required string Name { get; set; }
public required string Description { get; set; }
}
}

View File

@@ -2,6 +2,12 @@
{ {
public class RobotTaskScheduleResponse public class RobotTaskScheduleResponse
{ {
/// <summary>
/// RobotConfigurationId
/// </summary>
public Guid TaskId { get; set; }
//TODO: //TODO:
} }
} }

View File

@@ -2,6 +2,11 @@
{ {
public class RobotTaskTemplateResponse public class RobotTaskTemplateResponse
{ {
/// <summary>
/// RobotConfigurationId
/// </summary>
public Guid TaskId { get; set; }
public bool IsActive { get; set; } public bool IsActive { get; set; }
public required string ClosingCode { get; set; } public required string ClosingCode { get; set; }
public required string FullDescription { get; set; } public required string FullDescription { get; set; }
@@ -27,5 +32,7 @@
public required string WorkName { get; set; } public required string WorkName { get; set; }
public required string WorkEsppId { get; set; } public required string WorkEsppId { get; set; }
} }
} }

View File

@@ -0,0 +1,9 @@
namespace PARR.API.Contracts.V1.Responses
{
public class TaskStatusResponse
{
public int Code { get; set; }
public required string Name { get; set; }
public required string Description { get; set; }
}
}

View File

@@ -82,7 +82,7 @@ namespace PARR.API.Controllers.V1
task = await query.FirstOrDefaultAsync(t => task = await query.FirstOrDefaultAsync(t =>
t.RobotStatusCode == (int)RobotStatusEnum.InProgress t.RobotStatusCode == (int)RobotStatusEnum.InProgress
&& t.AttemptsNumber < settingsFromDb.RobotAttemptsNumber && t.AttemptsNumber < settingsFromDb.RobotAttemptsNumber
&& t.LastStatusUpdated < endDate && t.LastRobotStatusUpdated < endDate
); );
} }

View File

@@ -0,0 +1,86 @@
using AutoMapper;
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.DAL.Contracts;
using PARR.DAL.Models;
using PARR.DAL.Services.Interfaces;
namespace PARR.API.Controllers.V1
{
public class RobotTaskRobotStatusController : BaseApiController
{
private readonly IRobotConfigurationService robotConfigurationService;
private readonly IRobotHistoryService robotHistoryService;
private readonly IMapper mapper;
public RobotTaskRobotStatusController(
IRobotConfigurationService robotConfigurationService,
IRobotHistoryService robotHistoryService,
IMapper mapper
)
{
this.robotConfigurationService = robotConfigurationService;
this.robotHistoryService = robotHistoryService;
this.mapper = mapper;
}
/// <summary>
/// Изменить статус выполнения задания роботом по ИД задания
/// </summary>
/// <param name="taskId"></param>
/// <returns></returns>
[HttpPut(ApiRoutes.RobotTaskRobotStatus.ChangeRobotStatus)]
public async Task<IActionResult> ChangeStatus([FromRoute] Guid taskId, [FromBody] RobotTaskChangeRobotStatusRequest request)
{
var config = await robotConfigurationService.Get()
.FirstOrDefaultAsync(t => t.Id == taskId);
if (config == null)
return BadRequest(new Response(false, new List<ErrorModel> { new ErrorModel { Message = $"Не найдено задание с id: {taskId}" } }));
//изменение статуса робота
robotConfigurationService.ChangeRobotStatus(request.RobotStatusCode, ref config);
//если успех, изменяем статус задания на успех
if (request.RobotStatusCode == RobotStatusEnum.Complete)
robotConfigurationService.ChangeTaskStatus(TaskStatusEnum.Ok, ref config);
if (!await robotConfigurationService.CommitAsync())
return BadRequest("Ошибка при изменении статуса работы робота.");
//записываем в лог робота
if (request.RobotStatusCode == RobotStatusEnum.InProgress || request.RobotStatusCode == RobotStatusEnum.Complete)
{
var historyLevel = request.RobotStatusCode == RobotStatusEnum.InProgress ? RobotHistoryLevelEnum.Start : RobotHistoryLevelEnum.Complete;
var history = new RobotHistory
{
Id = Guid.NewGuid(),
HistoryLevel = (int)historyLevel,
TaskStatusCode = config.TaskStatusCode,
RobotConfigurationId = config.Id
};
await robotHistoryService.CreateAsync(history);
await robotHistoryService.CommitAsync();
}
var configToResonse = await robotConfigurationService.Get()
.Include(t => t.Robot)
.Include(t => t.StatusTask)
.Include(t => t.RobotStatus)
.FirstOrDefaultAsync(t => t.Id == taskId);
var response = mapper.Map<RobotConfigurationResponse>(configToResonse);
return Ok(new Response<RobotConfigurationResponse>(response, true));
}
}
}

View File

@@ -114,12 +114,24 @@ namespace PARR.API.MappingProfiles
.ForMember(d => d.TnkName, o => o.MapFrom(s => s.Template!.ApplicationsInWork!.Work!.Tnk!.Name)) .ForMember(d => d.TnkName, o => o.MapFrom(s => s.Template!.ApplicationsInWork!.Work!.Tnk!.Name))
.ForMember(d => d.TnkEsppId, o => o.MapFrom(s => s.Template!.ApplicationsInWork!.Work!.Tnk!.EsppId)) .ForMember(d => d.TnkEsppId, o => o.MapFrom(s => s.Template!.ApplicationsInWork!.Work!.Tnk!.EsppId))
.ForMember(d => d.WorkName, o => o.MapFrom(s => s.Template!.ApplicationsInWork!.Work!.Name)) .ForMember(d => d.WorkName, o => o.MapFrom(s => s.Template!.ApplicationsInWork!.Work!.Name))
.ForMember(d => d.WorkEsppId, o => o.MapFrom(s => s.Template!.ApplicationsInWork!.Work!.EsppId)); .ForMember(d => d.WorkEsppId, o => o.MapFrom(s => s.Template!.ApplicationsInWork!.Work!.EsppId))
.ForMember(d => d.TaskId, o => o.MapFrom(s => s.Id));
//TODO: сделать маппинг!!! //TODO: сделать маппинг!!!
CreateMap<RobotConfiguration, RobotTaskScheduleResponse>(); CreateMap<RobotConfiguration, RobotTaskScheduleResponse>()
.ForMember(d => d.TaskId, o => o.MapFrom(s => s.Id));
// === RobotConfiguration === // === RobotConfiguration ===
CreateMap<Robot, RobotResponse>();
CreateMap<DAL.Models.TaskStatus, TaskStatusResponse>();
CreateMap<RobotConfiguration, RobotConfigurationResponse>()
.ForMember(d => d.Robot, o => o.MapFrom(s => s.Robot))
.ForMember(d => d.TaskStatus, o => o.MapFrom(s => s.StatusTask))
.ForMember(d => d.RobotStatus, o => o.MapFrom(s => s.RobotStatus));
} }
} }
} }

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,30 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace PARR.DAL.Migrations
{
/// <inheritdoc />
public partial class TblRobotHistoryRmIdSeries : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "IdSeries",
table: "RobotHistories");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<Guid>(
name: "IdSeries",
table: "RobotHistories",
type: "uuid",
nullable: false,
defaultValue: new Guid("00000000-0000-0000-0000-000000000000"));
}
}
}

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 TblRobotConfiguratinosUpd : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.RenameColumn(
name: "LastStatusUpdated",
table: "RobotConfigurations",
newName: "LastRobotStatusUpdated");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.RenameColumn(
name: "LastRobotStatusUpdated",
table: "RobotConfigurations",
newName: "LastStatusUpdated");
}
}
}

View File

@@ -788,7 +788,7 @@ namespace PARR.DAL.Migrations
b.Property<DateTimeOffset>("DateCreated") b.Property<DateTimeOffset>("DateCreated")
.HasColumnType("timestamp with time zone"); .HasColumnType("timestamp with time zone");
b.Property<DateTimeOffset?>("LastStatusUpdated") b.Property<DateTimeOffset?>("LastRobotStatusUpdated")
.HasColumnType("timestamp with time zone"); .HasColumnType("timestamp with time zone");
b.Property<int>("RobotCode") b.Property<int>("RobotCode")
@@ -832,9 +832,6 @@ namespace PARR.DAL.Migrations
b.Property<int>("HistoryLevel") b.Property<int>("HistoryLevel")
.HasColumnType("integer"); .HasColumnType("integer");
b.Property<Guid>("IdSeries")
.HasColumnType("uuid");
b.Property<Guid>("RobotConfigurationId") b.Property<Guid>("RobotConfigurationId")
.HasColumnType("uuid"); .HasColumnType("uuid");

View File

@@ -42,7 +42,7 @@ namespace PARR.DAL.Models
/// <summary> /// <summary>
/// Последняя дата обновления статуса RobotStatusCode роботом /// Последняя дата обновления статуса RobotStatusCode роботом
/// </summary> /// </summary>
public DateTimeOffset? LastStatusUpdated { get; set; } public DateTimeOffset? LastRobotStatusUpdated { get; set; }
[ForeignKey(nameof(TemplateId))] [ForeignKey(nameof(TemplateId))]
public Template? Template { get; set; } public Template? Template { get; set; }

View File

@@ -26,10 +26,10 @@ namespace PARR.DAL.Models
public Guid RobotConfigurationId { get; set; } public Guid RobotConfigurationId { get; set; }
/// <summary> ///// <summary>
/// Уникальный идентификатор серии выполнения, нужен для сопоставления истории ///// Уникальный идентификатор серии выполнения, нужен для сопоставления истории
/// </summary> ///// </summary>
public Guid IdSeries { get; set; } //public Guid IdSeries { get; set; }
[ForeignKey(nameof(HistoryLevel))] [ForeignKey(nameof(HistoryLevel))]

View File

@@ -52,15 +52,15 @@ namespace PARR.DAL.Services.Implementations
{ {
case RobotStatusEnum.InProgress: case RobotStatusEnum.InProgress:
configuration.AttemptsNumber++; configuration.AttemptsNumber++;
configuration.LastStatusUpdated = DateTimeOffset.UtcNow; configuration.LastRobotStatusUpdated = DateTimeOffset.UtcNow;
break; break;
//case RobotStatusEnum.Error: //case RobotStatusEnum.Error:
// break; // break;
case RobotStatusEnum.Complete: case RobotStatusEnum.Complete:
configuration.LastStatusUpdated = DateTimeOffset.UtcNow; configuration.LastRobotStatusUpdated = DateTimeOffset.UtcNow;
break; break;
case RobotStatusEnum.Wait: case RobotStatusEnum.Wait:
configuration.LastStatusUpdated = null; configuration.LastRobotStatusUpdated = null;
configuration.AttemptsNumber = 0; configuration.AttemptsNumber = 0;
break; break;
default: default:
@@ -93,7 +93,7 @@ namespace PARR.DAL.Services.Implementations
var configObjs = await EntitySet.Where(t => var configObjs = await EntitySet.Where(t =>
t.RobotStatusCode == (int)RobotStatusEnum.InProgress t.RobotStatusCode == (int)RobotStatusEnum.InProgress
&& t.AttemptsNumber >= robotAttemptsNumber && t.AttemptsNumber >= robotAttemptsNumber
&& t.LastStatusUpdated <= endDate && t.LastRobotStatusUpdated <= endDate
).ToListAsync(); ).ToListAsync();
if (!configObjs.Any()) if (!configObjs.Any())

View File

@@ -117,7 +117,7 @@ namespace PARR.DAL.Services.Implementations
TaskStatusCode = (int)TaskStatusEnum.Creating, TaskStatusCode = (int)TaskStatusEnum.Creating,
RobotStatusCode = (int)RobotStatusEnum.Wait, RobotStatusCode = (int)RobotStatusEnum.Wait,
AttemptsNumber = 0, AttemptsNumber = 0,
LastStatusUpdated = null LastRobotStatusUpdated = null
}, },
// робот по управлениею расписанием // робот по управлениею расписанием
new RobotConfiguration new RobotConfiguration
@@ -129,7 +129,7 @@ namespace PARR.DAL.Services.Implementations
TaskStatusCode = (int)TaskStatusEnum.Creating, TaskStatusCode = (int)TaskStatusEnum.Creating,
RobotStatusCode = (int)RobotStatusEnum.Wait, RobotStatusCode = (int)RobotStatusEnum.Wait,
AttemptsNumber = 0, AttemptsNumber = 0,
LastStatusUpdated = null LastRobotStatusUpdated = null
} }
}; };

View File

@@ -14,7 +14,7 @@ namespace PARR.DAL.Services.Interfaces
void ChangeRobotStatus(RobotStatusEnum robotStatus, ref RobotConfiguration configuration); void ChangeRobotStatus(RobotStatusEnum robotStatus, ref RobotConfiguration configuration);
/// <summary> /// <summary>
/// Обновить статус задания (автоматически обновляется статус робота) /// Обновить статус задания (автоматически обновляется статус робота при необходимости)
/// </summary> /// </summary>
/// <param name="taskStatus"></param> /// <param name="taskStatus"></param>
/// <param name="configuration"></param> /// <param name="configuration"></param>