feat(api): TemplateResponse - добавлены поля с примененными шорткодами

This commit is contained in:
Mikhail Trubnikov
2026-07-03 11:16:31 +10:00
parent f8e16e9496
commit 143ae10190
2 changed files with 97 additions and 79 deletions

View File

@@ -55,7 +55,6 @@
} }
public class TemplateResponse : TemplateBaseResponse public class TemplateResponse : TemplateBaseResponse
{ {
public required string Category { get; set; } public required string Category { get; set; }
@@ -72,6 +71,42 @@
public required string TemplateDuration { get; set; } public required string TemplateDuration { get; set; }
#region Поля с примененнымм шорткодами
/// <summary>
/// Работа в ЕСПП (с примененными шорткодами)
/// </summary>
public string? WorkNameRendered { get; set; }
/// <summary>
/// Рабочая группа (с примененными шорткодами)
/// </summary>
public string? WorkGroupRendered { get; set; }
/// <summary>
/// ЗО (с примененными шорткодами)
/// </summary>
public string? ResponseAreaRendered { get; set; }
/// <summary>
/// Краткое описание (с примененными шорткодами)
/// </summary>
public string? ShortDescriptionRendered { get; set; }
/// <summary>
/// Подробное описание (с примененными шорткодами)
/// </summary>
public string? FullDescriptionRendered { get; set; }
/// <summary>
/// Решение (с примененными шорткодами)
/// </summary>
public string? SolutionRendered { get; set; }
#endregion
public JobResponse? Job { get; set; } public JobResponse? Job { get; set; }
public ProcessResponse? Process { get; set; } public ProcessResponse? Process { get; set; }

View File

@@ -10,7 +10,6 @@ using PARR.API.Contracts.V1.Responses.Base;
using PARR.API.Controllers.V1.Base; using PARR.API.Controllers.V1.Base;
using PARR.API.Extensions; using PARR.API.Extensions;
using PARR.API.Services.Interfaces; using PARR.API.Services.Interfaces;
using PARR.BLL.Helpers;
using PARR.Core.Common.Helpers; using PARR.Core.Common.Helpers;
using PARR.Core.Repositories.Interfaces; using PARR.Core.Repositories.Interfaces;
using PARR.Core.Repositories.Interfaces.Schedule; using PARR.Core.Repositories.Interfaces.Schedule;
@@ -30,37 +29,34 @@ namespace PARR.API.Controllers.V1
[Authorize(Roles = ParrRoles.Administrator.Role)] [Authorize(Roles = ParrRoles.Administrator.Role)]
public class TemplateController : BaseApiController public class TemplateController : BaseApiController
{ {
private readonly IMapper mapper; private readonly IMapper _mapper;
private readonly ITemplateRepository templateService; private readonly ITemplateRepository _templateRepository;
private readonly IRobotConfigurationRepository robotConfigurationService; private readonly IRobotConfigurationRepository _robotConfigurationRepository;
private readonly IClientService clientService; private readonly IClientService _clientService;
private readonly ILogger<TemplateController> logger; private readonly ILogger<TemplateController> _logger;
private readonly IShortcodesService shortcodesService; private readonly IShortcodesService _shortcodesService;
private readonly IOrderRepository orderService; private readonly IOrderRepository _orderRepository;
private readonly SettingsFromDb settingsFromDb; private readonly SettingsFromDb _settingsFromDb;
private readonly IScheduleResponseAreaTimeOffsetRepository scheduleResponseAreaTimeOffsetService;
public TemplateController( public TemplateController(
IMapper mapper, IMapper mapper,
ITemplateRepository templateService, ITemplateRepository templateRepository,
IRobotConfigurationRepository robotConfigurationService, IRobotConfigurationRepository robotConfigurationRepository,
IClientService clientService, IClientService clientService,
ILogger<TemplateController> logger, ILogger<TemplateController> logger,
IShortcodesService shortcodesService, IShortcodesService shortcodesService,
IOrderRepository orderService, IOrderRepository orderRepository,
SettingsFromDb settingsFromDb, SettingsFromDb settingsFromDb
IScheduleResponseAreaTimeOffsetRepository scheduleResponseAreaTimeOffsetService
) )
{ {
this.mapper = mapper; _mapper = mapper;
this.templateService = templateService; _templateRepository = templateRepository;
this.robotConfigurationService = robotConfigurationService; _robotConfigurationRepository = robotConfigurationRepository;
this.clientService = clientService; _clientService = clientService;
this.logger = logger; _logger = logger;
this.shortcodesService = shortcodesService; _shortcodesService = shortcodesService;
this.orderService = orderService; _orderRepository = orderRepository;
this.settingsFromDb = settingsFromDb; _settingsFromDb = settingsFromDb;
this.scheduleResponseAreaTimeOffsetService = scheduleResponseAreaTimeOffsetService;
} }
@@ -72,9 +68,10 @@ namespace PARR.API.Controllers.V1
[HttpGet(ApiRoutes.Template.GetAll)] [HttpGet(ApiRoutes.Template.GetAll)]
public async Task<IActionResult> GetAll([FromQuery] PaginationQuery paginationQuery, [FromQuery] TemplateQuery filter) public async Task<IActionResult> GetAll([FromQuery] PaginationQuery paginationQuery, [FromQuery] TemplateQuery filter)
{ {
var paginationFilter = mapper.Map<PaginationFilter>(paginationQuery); var paginationFilter = _mapper.Map<PaginationFilter>(paginationQuery);
IQueryable<Template> query = templateService.Get() IQueryable<Template> query = _templateRepository.Get()
.AsNoTracking()
.Include(t => t.Unit).ThenInclude(t => t!.UnitValues).ThenInclude(t => t.Field) .Include(t => t.Unit).ThenInclude(t => t!.UnitValues).ThenInclude(t => t.Field)
.Include(t => t.Unit).ThenInclude(t => t!.UnitValues).ThenInclude(t => t.Value) .Include(t => t.Unit).ThenInclude(t => t!.UnitValues).ThenInclude(t => t.Value)
.Include(t => t.StatusType) .Include(t => t.StatusType)
@@ -82,8 +79,7 @@ namespace PARR.API.Controllers.V1
.Include(t => t.RobotConfigurations).ThenInclude(t => t.Robot) .Include(t => t.RobotConfigurations).ThenInclude(t => t.Robot)
.Include(t => t.RobotConfigurations).ThenInclude(t => t.TaskStatus) .Include(t => t.RobotConfigurations).ThenInclude(t => t.TaskStatus)
.Include(t => t.RobotConfigurations).ThenInclude(t => t.RobotStatus) .Include(t => t.RobotConfigurations).ThenInclude(t => t.RobotStatus)
.OrderBy(t => t.Name) .OrderBy(t => t.Name);
.AsNoTracking();
if (!string.IsNullOrEmpty(filter.Mask)) if (!string.IsNullOrEmpty(filter.Mask))
@@ -114,7 +110,7 @@ namespace PARR.API.Controllers.V1
#endregion #endregion
var templates = await templateService.GetPage(query, paginationFilter).ToListAsync(); var templates = await _templateRepository.GetPage(query, paginationFilter).ToListAsync();
//logger.LogDebug("Загрузка шаблонов из БД: {ElapsedMs} мс", sw.ElapsedMilliseconds); //logger.LogDebug("Загрузка шаблонов из БД: {ElapsedMs} мс", sw.ElapsedMilliseconds);
@@ -122,7 +118,7 @@ namespace PARR.API.Controllers.V1
if (!templates.Any()) if (!templates.Any())
return NoContent(); return NoContent();
var templateResponse = mapper.Map<List<TemplateListResponse>>(templates); var templateResponse = _mapper.Map<List<TemplateListResponse>>(templates);
// словари для быстрого поиска // словари для быстрого поиска
var templatesDict = templates.ToDictionary(t => t.Id); var templatesDict = templates.ToDictionary(t => t.Id);
@@ -135,7 +131,7 @@ namespace PARR.API.Controllers.V1
foreach (var responseItem in templateResponse) foreach (var responseItem in templateResponse)
{ {
//await ApplyTemplateShortcodesAsync(responseItem, templates.First(t => t.Id == responseItem.Id)); //await ApplyTemplateShortcodesAsync(responseItem, templates.First(t => t.Id == responseItem.Id));
await ApplyTemplateShortcodesAsync(responseItem, templatesDict[responseItem.Id]); await ApplyBaseTemplateShortcodesAsync(responseItem, templatesDict[responseItem.Id]);
//FillResponseAreaOffset(responseItem); //FillResponseAreaOffset(responseItem);
} }
//logger.LogDebug("Получение шорткодов: {ElapsedMs} мс", sw.ElapsedMilliseconds); //logger.LogDebug("Получение шорткодов: {ElapsedMs} мс", sw.ElapsedMilliseconds);
@@ -165,7 +161,8 @@ namespace PARR.API.Controllers.V1
[HttpGet(ApiRoutes.Template.Get)] [HttpGet(ApiRoutes.Template.Get)]
public async Task<IActionResult> GetById([FromRoute] Guid id) public async Task<IActionResult> GetById([FromRoute] Guid id)
{ {
var template = await templateService.GetWithIncludes().AsNoTracking() var template = await _templateRepository.GetWithIncludes()
.AsNoTracking()
.Include(t => t.RobotConfigurations).ThenInclude(t => t.Robot) .Include(t => t.RobotConfigurations).ThenInclude(t => t.Robot)
.Include(t => t.RobotConfigurations).ThenInclude(t => t.TaskStatus) .Include(t => t.RobotConfigurations).ThenInclude(t => t.TaskStatus)
.Include(t => t.RobotConfigurations).ThenInclude(t => t.RobotStatus) .Include(t => t.RobotConfigurations).ThenInclude(t => t.RobotStatus)
@@ -179,9 +176,9 @@ namespace PARR.API.Controllers.V1
if (template == null) if (template == null)
return NotFound(); return NotFound();
var response = mapper.Map<TemplateResponse>(template); var response = _mapper.Map<TemplateResponse>(template);
await ApplyBaseTemplateShortcodesAsync(response, template);
await ApplyTemplateShortcodesAsync(response, template); await ApplyTemplateShortcodesAsync(response, template);
//FillResponseAreaOffset(response);
var ordersCountResult = await GetOrdersCountAsync(new List<Guid> { response.Id }); var ordersCountResult = await GetOrdersCountAsync(new List<Guid> { response.Id });
response.OrderCount = ordersCountResult.Count > 0 ? ordersCountResult.First().Value : 0; response.OrderCount = ordersCountResult.Count > 0 ? ordersCountResult.First().Value : 0;
@@ -215,7 +212,7 @@ namespace PARR.API.Controllers.V1
// .FirstOrDefaultAsync(t => t.Id == id); // .FirstOrDefaultAsync(t => t.Id == id);
#endregion #endregion
var template = await templateService.Get() var template = await _templateRepository.Get()
.Include(t => t.RobotConfigurations) .Include(t => t.RobotConfigurations)
.FirstOrDefaultAsync(t => t.Id == id); .FirstOrDefaultAsync(t => t.Id == id);
@@ -226,21 +223,21 @@ namespace PARR.API.Controllers.V1
{ {
template.IsActiveTemplate = request.IsActiveTemplate; template.IsActiveTemplate = request.IsActiveTemplate;
//необходимо обновить шаблон //необходимо обновить шаблон
var config = robotConfigurationService.GetFromTemplateByRobotCode(RobotsEnum.TemplateOrder, template); var config = _robotConfigurationRepository.GetFromTemplateByRobotCode(RobotsEnum.TemplateOrder, template);
//robotConfigurationService.ChangeTaskStatus(TaskStatusEnum.Updating, config); //robotConfigurationService.ChangeTaskStatus(TaskStatusEnum.Updating, config);
robotConfigurationService.SetUpdateTaskStatusIfAllow(config); _robotConfigurationRepository.SetUpdateTaskStatusIfAllow(config);
} }
if (template.IsActiveSchedule != request.IsActiveSchedule) if (template.IsActiveSchedule != request.IsActiveSchedule)
{ {
template.IsActiveSchedule = request.IsActiveSchedule; template.IsActiveSchedule = request.IsActiveSchedule;
//необходимо обновить расписание //необходимо обновить расписание
var config = robotConfigurationService.GetFromTemplateByRobotCode(RobotsEnum.ScheduleOrder, template); var config = _robotConfigurationRepository.GetFromTemplateByRobotCode(RobotsEnum.ScheduleOrder, template);
//robotConfigurationService.ChangeTaskStatus(TaskStatusEnum.Updating, config); //robotConfigurationService.ChangeTaskStatus(TaskStatusEnum.Updating, config);
robotConfigurationService.SetUpdateTaskStatusIfAllow(config); _robotConfigurationRepository.SetUpdateTaskStatusIfAllow(config);
} }
if (!await templateService.CommitAsync(new HistoryInitiator { InitiatorComment = "Изменён статус шаблона/расписания", InitiatorIp = clientService.GetClientIp()?.ToString(), InitiatorParrComponentId = ParrComponentsEnum.Api })) if (!await _templateRepository.CommitAsync(new HistoryInitiator { InitiatorComment = "Изменён статус шаблона/расписания", InitiatorIp = _clientService.GetClientIp()?.ToString(), InitiatorParrComponentId = ParrComponentsEnum.Api }))
return BadRequest(new Response(false, new List<ErrorModel> { new ErrorModel { Message = "Ошибка при изменении шаблона." } })); return BadRequest(new Response(false, new List<ErrorModel> { new ErrorModel { Message = "Ошибка при изменении шаблона." } }));
#region old #region old
@@ -263,7 +260,7 @@ namespace PARR.API.Controllers.V1
//return Ok(new Response<TemplateResponse>(response, true)); //return Ok(new Response<TemplateResponse>(response, true));
#endregion #endregion
var templateToResponse = await templateService.Get() var templateToResponse = await _templateRepository.Get()
.AsNoTracking() .AsNoTracking()
.Include(t => t.Unit).ThenInclude(t => t!.UnitValues).ThenInclude(t => t.Field) .Include(t => t.Unit).ThenInclude(t => t!.UnitValues).ThenInclude(t => t.Field)
.Include(t => t.Unit).ThenInclude(t => t!.UnitValues).ThenInclude(t => t.Value) .Include(t => t.Unit).ThenInclude(t => t!.UnitValues).ThenInclude(t => t.Value)
@@ -274,10 +271,9 @@ namespace PARR.API.Controllers.V1
.Include(t => t.RobotConfigurations).ThenInclude(t => t.RobotStatus) .Include(t => t.RobotConfigurations).ThenInclude(t => t.RobotStatus)
.FirstAsync(t => t.Id == id); .FirstAsync(t => t.Id == id);
var response = mapper.Map<TemplateListResponse>(templateToResponse); var response = _mapper.Map<TemplateListResponse>(templateToResponse);
await ApplyTemplateShortcodesAsync(response, templateToResponse); await ApplyBaseTemplateShortcodesAsync(response, templateToResponse);
//FillResponseAreaOffset(response);
var ordersCountResult = await GetOrdersCountAsync(new List<Guid> { response.Id }); var ordersCountResult = await GetOrdersCountAsync(new List<Guid> { response.Id });
response.OrderCount = ordersCountResult.Count > 0 ? ordersCountResult.First().Value : 0; response.OrderCount = ordersCountResult.Count > 0 ? ordersCountResult.First().Value : 0;
@@ -287,18 +283,34 @@ namespace PARR.API.Controllers.V1
/// <summary> /// <summary>
/// Применить шорткоды /// Применить шорткоды. Для респонса TemplateBaseResponse
/// </summary> /// </summary>
/// <param name="response"></param> /// <param name="response"></param>
/// <param name="template"></param> /// <param name="template"></param>
/// <returns></returns> /// <returns></returns>
private async Task ApplyTemplateShortcodesAsync(TemplateBaseResponse response, Template template) private async Task ApplyBaseTemplateShortcodesAsync(TemplateBaseResponse response, Template template)
{ {
response.WorkGroup = await shortcodesService.ApplyShortcodesAsync(template.Job.WorkGroupMask, template); response.WorkGroup = await _shortcodesService.ApplyShortcodesAsync(template.Job!.WorkGroupMask, template);
response.ResponseArea = await shortcodesService.ApplyShortcodesAsync(template.Job.ResponseAreaMask, template); response.ResponseArea = await _shortcodesService.ApplyShortcodesAsync(template.Job!.ResponseAreaMask, template);
} }
/// <summary>
/// Применить шорткоды. Для респонса TemplateResponse (добавлены дополнительные поля Rendered)
/// </summary>
/// <param name="response"></param>
/// <param name="template"></param>
/// <returns></returns>
private async Task ApplyTemplateShortcodesAsync(TemplateResponse response, Template template)
{
response.WorkNameRendered = await _shortcodesService.ApplyShortcodesAsync(template.Job!.WorkName, template);
response.WorkGroupRendered = await _shortcodesService.ApplyShortcodesAsync(template.Job!.WorkGroupMask, template);
response.ResponseAreaRendered = await _shortcodesService.ApplyShortcodesAsync(template.Job!.ResponseAreaMask, template);
response.ShortDescriptionRendered = await _shortcodesService.ApplyShortcodesAsync(template.Job.Group!.ShortDescription, template);
response.FullDescriptionRendered = await _shortcodesService.ApplyShortcodesAsync(template.Job.Group!.FullDescription, template);
response.SolutionRendered = await _shortcodesService.ApplyShortcodesAsync(template.Job.Group!.Solution, template);
}
/// <summary> /// <summary>
/// Получить кол-во нарядов для шаблонов /// Получить кол-во нарядов для шаблонов
/// </summary> /// </summary>
@@ -309,7 +321,7 @@ namespace PARR.API.Controllers.V1
if (!templateIdList.Any()) if (!templateIdList.Any())
return new Dictionary<Guid, int>(); return new Dictionary<Guid, int>();
var templateWithOrders = await orderService.Get() var templateWithOrders = await _orderRepository.Get()
.Where(t => t.TemplateId.HasValue && templateIdList.Contains(t.TemplateId.Value)) .Where(t => t.TemplateId.HasValue && templateIdList.Contains(t.TemplateId.Value))
.GroupBy(t => t.TemplateId) .GroupBy(t => t.TemplateId)
.Select(t => new { TemplateId = t.Key, OrderCount = t.Count() }) .Select(t => new { TemplateId = t.Key, OrderCount = t.Count() })
@@ -323,36 +335,7 @@ namespace PARR.API.Controllers.V1
} }
///// <summary>
///// Заполнить ResponseAreaOffset
///// </summary>
///// <param name="response"></param>
//private void FillResponseAreaOffset(TemplateBaseResponse response)
//{
// // если стоит галка IsResponseAreaTimezone и есть ЗО, то возвращаем оффсет
// if (response.IsResponseAreaTimezone && !string.IsNullOrEmpty(response.ResponseArea))
// {
// var responseArea = response.ResponseArea;
// response.ResponseAreaOffset = mapper.Map<ScheduleResponseAreaTimeOffsetResponse>(scheduleResponseAreaTimeOffsetService.GetByResponseAreaOrDefault(responseArea));
// }
// else
// {
// response.ResponseAreaOffset = null;
// }
// //var responseArea = response.IsResponseAreaTimezone && !string.IsNullOrEmpty(response.ResponseArea)
// // ? response.ResponseArea
// // : settingsFromDb.DefaultResponseAreaToTimeOffset;
// //response.NextRunResponseAreaInLocal = response.IsResponseAreaTimezone && !string.IsNullOrEmpty(response.ResponseArea)
// // ? nextRunService.GetNextRunWithResponseAreaOffset(response.NextRun, response.ResponseArea)
// // // возвращаем в дефолтной зоне
// // : nextRunService.GetNextRunWithResponseAreaOffset(response.NextRun, settingsFromDb.DefaultResponseAreaToTimeOffset);
// //response.NextRunResponseAreaInLocal = nextRunService.GetNextRunWithResponseAreaOffset(response.NextRun, responseArea);
// //response.ResponseAreaOffset = mapper.Map<ScheduleResponseAreaTimeOffsetResponse>(scheduleResponseAreaTimeOffsetService.GetByResponseAreaOrDefault(responseArea));
//}
} }
} }