forked from ddrilling/AsbCloudServer
Merge pull request '#27053248 - Отдельный work для создания диаграммы отчета' (#187) from fix/create-workers into dev
Reviewed-on: http://test.digitaldrilling.ru:8080/DDrilling/AsbCloudServer/pulls/187
This commit is contained in:
commit
f9a6279d0d
18
AsbCloudApp/Data/Progress/ProgressDto.cs
Normal file
18
AsbCloudApp/Data/Progress/ProgressDto.cs
Normal file
@ -0,0 +1,18 @@
|
||||
namespace AsbCloudApp.Data.Progress;
|
||||
|
||||
/// <summary>
|
||||
/// DTO прогресса
|
||||
/// </summary>
|
||||
public class ProgressDto
|
||||
{
|
||||
/// <summary>
|
||||
/// прогресс 0 - 100%
|
||||
/// </summary>
|
||||
public float Progress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// название текущей операции генерации
|
||||
/// </summary>
|
||||
public string? Operation { get; set; }
|
||||
|
||||
}
|
29
AsbCloudApp/Data/Progress/ProgressExceptionDto.cs
Normal file
29
AsbCloudApp/Data/Progress/ProgressExceptionDto.cs
Normal file
@ -0,0 +1,29 @@
|
||||
using System;
|
||||
|
||||
namespace AsbCloudApp.Data.Progress;
|
||||
|
||||
/// <summary>
|
||||
/// DTO прогресса с ошибкой
|
||||
/// </summary>
|
||||
public class ProgressExceptionDto
|
||||
{
|
||||
/// <summary>
|
||||
/// прогресс 0 - 100%
|
||||
/// </summary>
|
||||
public float Progress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// название текущей операции генерации
|
||||
/// </summary>
|
||||
public string? Operation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Отображаемый текст ошибки
|
||||
/// </summary>
|
||||
public string Message { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Инфо об исключении
|
||||
/// </summary>
|
||||
public Exception Exception { get; set; } = null!;
|
||||
}
|
12
AsbCloudApp/Data/Progress/ReportProgressDto.cs
Normal file
12
AsbCloudApp/Data/Progress/ReportProgressDto.cs
Normal file
@ -0,0 +1,12 @@
|
||||
namespace AsbCloudApp.Data.Progress;
|
||||
|
||||
/// <summary>
|
||||
/// DTO завершенного прогресса генерации рапорта-диаграммы
|
||||
/// </summary>
|
||||
public class ReportProgressFinalDto : ReportProgressDto
|
||||
{
|
||||
/// <summary>
|
||||
/// файл
|
||||
/// </summary>
|
||||
public FileInfoDto file { get; set; }
|
||||
}
|
17
AsbCloudApp/Data/Progress/ReportProgressFinalDto.cs
Normal file
17
AsbCloudApp/Data/Progress/ReportProgressFinalDto.cs
Normal file
@ -0,0 +1,17 @@
|
||||
namespace AsbCloudApp.Data.Progress;
|
||||
|
||||
/// <summary>
|
||||
/// DTO прогресса генерации рапорта-диаграммы
|
||||
/// </summary>
|
||||
public class ReportProgressDto : ProgressDto
|
||||
{
|
||||
/// <summary>
|
||||
/// номер текущей страницы
|
||||
/// </summary>
|
||||
public int CurrentPage { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// предполагаемое суммарное количество страниц
|
||||
/// </summary>
|
||||
public int TotalPages { get; set; }
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
namespace AsbCloudApp.Data
|
||||
{
|
||||
/// <summary>
|
||||
/// DTO прогресса генерации рапорта-диаграммы
|
||||
/// </summary>
|
||||
public class ReportProgressDto
|
||||
{
|
||||
/// <summary>
|
||||
/// прогресс 0 - 100%
|
||||
/// </summary>
|
||||
public float Progress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// название текущей операции генерации
|
||||
/// </summary>
|
||||
public string? Operation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// номер текущей страницы
|
||||
/// </summary>
|
||||
public int CurrentPage { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// предполагаемое суммарное количество страниц
|
||||
/// </summary>
|
||||
public int TotalPages { get; set; }
|
||||
}
|
||||
}
|
@ -1,4 +1,6 @@
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Data.Progress;
|
||||
using AsbCloudApp.Requests;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
@ -11,26 +13,30 @@ namespace AsbCloudApp.Services
|
||||
/// </summary>
|
||||
public interface IReportService
|
||||
{
|
||||
/// <summary>
|
||||
/// категория рапорта
|
||||
/// </summary>
|
||||
int ReportCategoryId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Поставить рапорт в очередь на формирование
|
||||
/// </summary>
|
||||
/// <param name="idWell"></param>
|
||||
/// <param name="idUser"></param>
|
||||
/// <param name="stepSeconds"></param>
|
||||
/// <param name="format"></param>
|
||||
/// <param name="begin"></param>
|
||||
/// <param name="end"></param>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="handleReportProgress"></param>
|
||||
/// <returns></returns>
|
||||
string EnqueueCreateReportWork(int idWell, int idUser, int stepSeconds,
|
||||
int format, DateTime begin, DateTime end,
|
||||
string EnqueueCreateReportWork(int idWell, int idUser, ReportParametersRequest request,
|
||||
Action<object, string> handleReportProgress);
|
||||
|
||||
/// <summary>
|
||||
/// Создание отчета
|
||||
/// </summary>
|
||||
/// <param name="workId"></param>
|
||||
/// <param name="idWell"></param>
|
||||
/// <param name="idUser"></param>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="progressHandler"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task CreateReportAsync(string workId, int idWell, int idUser, ReportParametersRequest request, Action<ProgressDto, string> progressHandler, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Получить предполагаемый список страниц рапорта
|
||||
/// </summary>
|
||||
|
41
AsbCloudInfrastructure/Background/WorkToCreateReport.cs
Normal file
41
AsbCloudInfrastructure/Background/WorkToCreateReport.cs
Normal file
@ -0,0 +1,41 @@
|
||||
using AsbCloudApp.Data.Progress;
|
||||
using AsbCloudApp.Requests;
|
||||
using AsbCloudApp.Services;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AsbCloudInfrastructure.Background;
|
||||
|
||||
/// <summary>
|
||||
/// Класс для создания отчета
|
||||
/// </summary>
|
||||
internal class WorkToCreateReport : Work
|
||||
{
|
||||
private readonly int idWell;
|
||||
private readonly int idUser;
|
||||
private readonly ReportParametersRequest request;
|
||||
private readonly Action<object, string> progressHandler;
|
||||
|
||||
public WorkToCreateReport(int idWell, int idUser, ReportParametersRequest request, Action<object, string> progressHandler) : base("")
|
||||
{
|
||||
this.idWell = idWell;
|
||||
this.idUser = idUser;
|
||||
this.request = request;
|
||||
this.progressHandler = progressHandler;
|
||||
|
||||
Id = $"create report by wellid:{idWell} for userid:{idUser} requested at {DateTime.Now}";
|
||||
}
|
||||
|
||||
protected override async Task Action(string id, IServiceProvider services, Action<string, double?> onProgress, CancellationToken token)
|
||||
{
|
||||
var reportService = services.GetRequiredService<IReportService>();
|
||||
void handler(ProgressDto state, string workId)
|
||||
{
|
||||
onProgress(state.Operation ?? string.Empty, state.Progress);
|
||||
progressHandler(state, workId);
|
||||
}
|
||||
await reportService.CreateReportAsync(Id, idWell, idUser, request, handler, token);
|
||||
}
|
||||
}
|
@ -1,11 +1,12 @@
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Data.Progress;
|
||||
using AsbCloudApp.Requests;
|
||||
using AsbCloudApp.Services;
|
||||
using AsbCloudDb.Model;
|
||||
using AsbCloudInfrastructure.Background;
|
||||
using AsbSaubReport;
|
||||
using Mapster;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
@ -23,8 +24,6 @@ public class ReportService : IReportService
|
||||
private readonly IWellService wellService;
|
||||
private readonly BackgroundWorker backgroundWorkerService;
|
||||
|
||||
public int ReportCategoryId { get; private set; }
|
||||
|
||||
public ReportService(IAsbCloudDbContext db,
|
||||
ITelemetryService telemetryService,
|
||||
IWellService wellService,
|
||||
@ -36,68 +35,14 @@ public class ReportService : IReportService
|
||||
this.backgroundWorkerService = backgroundWorkerService;
|
||||
this.telemetryService = telemetryService;
|
||||
this.fileService = fileService;
|
||||
ReportCategoryId = db.FileCategories
|
||||
.AsNoTracking()
|
||||
.First(c => c.Name.Equals("Рапорт"))
|
||||
.Id;
|
||||
}
|
||||
|
||||
public string EnqueueCreateReportWork(int idWell, int idUser, int stepSeconds, int format, DateTime begin,
|
||||
DateTime end, Action<object, string> progressHandler)
|
||||
public string EnqueueCreateReportWork(int idWell, int idUser, ReportParametersRequest request, Action<object, string> progressHandler)
|
||||
{
|
||||
var timezoneOffset = wellService.GetTimezone(idWell).Hours;
|
||||
var beginUtc = begin.ToUtcDateTimeOffset(timezoneOffset);
|
||||
var endUtc = end.ToUtcDateTimeOffset(timezoneOffset);
|
||||
var beginRemote = begin.ToTimeZoneOffsetHours(timezoneOffset);
|
||||
var endRemote = end.ToTimeZoneOffsetHours(timezoneOffset);
|
||||
var work = new WorkToCreateReport(idWell, idUser, request, progressHandler);
|
||||
|
||||
var workId = $"create report by wellid:{idWell} for userid:{idUser} requested at {DateTime.Now}";
|
||||
|
||||
var workAction = async (string id, IServiceProvider serviceProvider, Action<string, double?> onProgress, CancellationToken token) =>
|
||||
{
|
||||
using var context = serviceProvider.GetRequiredService<IAsbCloudDbContext>();
|
||||
var fileService = serviceProvider.GetRequiredService<FileService>();
|
||||
|
||||
var tempDir = Path.Combine(Path.GetTempPath(), "report");
|
||||
|
||||
var generator = GetReportGenerator(idWell, beginRemote, endRemote, stepSeconds, format, context);
|
||||
var reportFileName = Path.Combine(tempDir, generator.GetReportDefaultFileName());
|
||||
var totalPages = generator.GetPagesCount();
|
||||
|
||||
generator.OnProgress += (s, e) =>
|
||||
{
|
||||
var arg = e.Adapt<ReportProgressDto>();
|
||||
onProgress(arg.Operation?? string.Empty, arg.Progress);
|
||||
progressHandler.Invoke(arg, id);
|
||||
};
|
||||
generator.Make(reportFileName);
|
||||
|
||||
var fileInfo = (await fileService.MoveAsync(idWell, idUser, ReportCategoryId, reportFileName, reportFileName, token))!;
|
||||
|
||||
progressHandler.Invoke(new
|
||||
{
|
||||
Operation = "done",
|
||||
Progress = 100f,
|
||||
TotalPages = totalPages,
|
||||
CurrentPage = totalPages,
|
||||
file = fileInfo,
|
||||
}, id);
|
||||
|
||||
var newReportProperties = new ReportProperty
|
||||
{
|
||||
IdWell = idWell,
|
||||
IdFile = fileInfo.Id,
|
||||
Begin = beginUtc,
|
||||
End = endUtc,
|
||||
Step = stepSeconds,
|
||||
Format = format
|
||||
};
|
||||
context.ReportProperties.Add(newReportProperties);
|
||||
context.SaveChanges();
|
||||
};
|
||||
|
||||
var work = Work.CreateByDelegate(workId, workAction);
|
||||
work.OnErrorAsync = (message, exception, token) => Task.Run(() => progressHandler.Invoke(new
|
||||
work.OnErrorAsync = (message, exception, token) => Task.Run(() => {
|
||||
var state = new ProgressExceptionDto
|
||||
{
|
||||
Operation = "error",
|
||||
Progress = 100f,
|
||||
@ -105,8 +50,9 @@ public class ReportService : IReportService
|
||||
? exception.Message
|
||||
: message,
|
||||
Exception = exception,
|
||||
}, workId)
|
||||
, token);
|
||||
};
|
||||
progressHandler.Invoke(state, work.Id);
|
||||
}, token);
|
||||
|
||||
backgroundWorkerService.Enqueue(work);
|
||||
|
||||
@ -114,8 +60,8 @@ public class ReportService : IReportService
|
||||
{
|
||||
Operation = "Ожидает начала в очереди.",
|
||||
Progress = 0f,
|
||||
}, workId);
|
||||
return workId;
|
||||
}, work.Id);
|
||||
return work.Id;
|
||||
}
|
||||
|
||||
public int GetReportPagesCount(int idWell, DateTime begin, DateTime end, int stepSeconds, int format)
|
||||
@ -172,6 +118,62 @@ public class ReportService : IReportService
|
||||
return dtos;
|
||||
}
|
||||
|
||||
public async Task CreateReportAsync(
|
||||
string workId,
|
||||
int idWell,
|
||||
int idUser,
|
||||
ReportParametersRequest request,
|
||||
Action<ProgressDto, string> progressHandler,
|
||||
CancellationToken token)
|
||||
{
|
||||
var timezoneOffset = wellService.GetTimezone(idWell).Hours;
|
||||
var beginRemote = request.Begin.ToTimeZoneOffsetHours(timezoneOffset);
|
||||
var endRemote = request.End.ToTimeZoneOffsetHours(timezoneOffset);
|
||||
var beginUtc = request.Begin.ToUtcDateTimeOffset(timezoneOffset);
|
||||
var endUtc = request.End.ToUtcDateTimeOffset(timezoneOffset);
|
||||
|
||||
var tempDir = Path.Combine(Path.GetTempPath(), "report");
|
||||
|
||||
var generator = GetReportGenerator(idWell, beginRemote, endRemote, request.StepSeconds, request.Format, db);
|
||||
var reportFileName = Path.Combine(tempDir, generator.GetReportDefaultFileName());
|
||||
var totalPages = generator.GetPagesCount();
|
||||
|
||||
generator.OnProgress += (s, e) =>
|
||||
{
|
||||
var arg = e.Adapt<ReportProgressDto>();
|
||||
progressHandler(arg, workId);
|
||||
};
|
||||
generator.Make(reportFileName);
|
||||
|
||||
var ReportCategoryId = db.FileCategories
|
||||
.AsNoTracking()
|
||||
.First(c => c.Name.Equals("Рапорт"))
|
||||
.Id;
|
||||
|
||||
var fileInfo = (await fileService.MoveAsync(idWell, idUser, ReportCategoryId, reportFileName, reportFileName, token))!;
|
||||
|
||||
progressHandler(new ReportProgressFinalDto()
|
||||
{
|
||||
Operation = "done",
|
||||
Progress = 100f,
|
||||
TotalPages = totalPages,
|
||||
CurrentPage = totalPages,
|
||||
file = fileInfo,
|
||||
}, workId);
|
||||
|
||||
var newReportProperties = new ReportProperty
|
||||
{
|
||||
IdWell = idWell,
|
||||
IdFile = fileInfo.Id,
|
||||
Begin = beginUtc,
|
||||
End = endUtc,
|
||||
Step = request.StepSeconds,
|
||||
Format = request.Format
|
||||
};
|
||||
db.ReportProperties.Add(newReportProperties);
|
||||
db.SaveChanges();
|
||||
}
|
||||
|
||||
private static IReportGenerator GetReportGenerator(int idWell, DateTime begin,
|
||||
DateTime end, int stepSeconds, int format, IAsbCloudDbContext context)
|
||||
{
|
||||
@ -184,7 +186,7 @@ public class ReportService : IReportService
|
||||
_ => new AsbSaubReportPdf.ReprotGeneratorPdf(dataSource),
|
||||
};
|
||||
|
||||
if(begin == default || end == default)
|
||||
if (begin == default || end == default)
|
||||
{
|
||||
var analyzeResult = dataSource.Analyze();
|
||||
begin = begin == default ? analyzeResult.MinDate : begin;
|
||||
|
@ -65,8 +65,7 @@ namespace AsbCloudWebApi.Controllers
|
||||
.GetReportProgress(progress, token);
|
||||
}, token);
|
||||
|
||||
var id = reportService.EnqueueCreateReportWork(idWell, (int)idUser,
|
||||
request.StepSeconds, request.Format, request.Begin, request.End, HandleReportProgressAsync);
|
||||
var id = reportService.EnqueueCreateReportWork(idWell, (int)idUser, request, HandleReportProgressAsync);
|
||||
|
||||
return Ok(id);
|
||||
}
|
||||
|
@ -54,8 +54,7 @@ namespace AsbCloudWebApi.SignalR
|
||||
.GetReportProgress(progress, CancellationToken.None);
|
||||
}, CancellationToken.None);
|
||||
|
||||
var id = reportService.EnqueueCreateReportWork(idWell, (int)idUser,
|
||||
request.StepSeconds, request.Format, request.Begin, request.End, HandleReportProgressAsync);
|
||||
var id = reportService.EnqueueCreateReportWork(idWell, (int)idUser, request, HandleReportProgressAsync);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user