DD.WellWorkover.Cloud/AsbCloudInfrastructure/Services/ReportService.cs

189 lines
7.3 KiB
C#

using AsbCloudApp.Data;
using AsbCloudApp.Services;
using AsbCloudDb.Model;
using AsbSaubReport;
using Mapster;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace AsbCloudInfrastructure.Services
{
public class ReportService : IReportService
{
private readonly IAsbCloudDbContext db;
private readonly string connectionString;
private readonly ITelemetryService telemetryService;
//private readonly IFileService fileService;
private readonly IReportsBackgroundQueue queue;
public ReportService(IAsbCloudDbContext db, IConfiguration configuration,
ITelemetryService telemetryService,
IReportsBackgroundQueue queue)
{
this.db = db;
this.connectionString = configuration.GetConnectionString("DefaultConnection");
this.telemetryService = telemetryService;
//this.fileService = fileService;
this.queue = queue;
ReportCategoryId = db.FileCategories.AsNoTracking()
.FirstOrDefault(c =>
c.Name.Equals("Рапорт")).Id;
}
public int ReportCategoryId { get; private set; }
public int CreateReport(int idWell, int idUser, int stepSeconds, int format, DateTime begin,
DateTime end, Action<object, int> progressHandler)
{
var newReportId = queue.EnqueueTask((id) =>
{
var optionsBuilder = new DbContextOptionsBuilder<AsbCloudDbContext>();
optionsBuilder.UseNpgsql(connectionString);
var tempDir = Path.Combine(Path.GetTempPath(), "report");
using var context = new AsbCloudDbContext(optionsBuilder.Options);
var generator = GetReportGenerator(idWell, begin, end, stepSeconds, format, context);
var reportFileName = Path.Combine(tempDir, generator.GetReportDefaultFileName());
var totalPages = generator.GetPagesCount();
generator.OnProgress += (s, e) =>
{
progressHandler.Invoke(e.Adapt<ReportProgressDto>(), id);
};
generator.Make(reportFileName);
var fileService = new FileService(context);
var fileInfo = fileService.MoveAsync(idWell, idUser, ReportCategoryId, reportFileName, reportFileName).Result;
progressHandler.Invoke(new
{
Operation = "done",
Progress = 100f,
TotalPages = totalPages,
CurrentPage = totalPages,
file = fileInfo,
}, id);
var newReportProperties = new ReportProperty
{
IdWell = idWell,
IdFile = fileInfo.Id,
Begin = begin,
End = end,
Step = stepSeconds,
Format = format
};
context.ReportProperties.Add(newReportProperties);
context.SaveChanges();
});
progressHandler.Invoke(new ReportProgressDto
{
Operation = "Ожидает начала в очереди.",
Progress = 0f,
}, newReportId);
return newReportId;
}
public int GetReportPagesCount(int idWell, DateTime begin, DateTime end, int stepSeconds, int format)
{
var generator = GetReportGenerator(idWell, begin, end, stepSeconds, format, (AsbCloudDbContext)db);
return generator.GetPagesCount();
}
public async Task<DatesRangeDto> GetReportsDatesRangeAsync(int idWell, bool isUtc,
CancellationToken token = default)
{
var telemetryId = telemetryService.GetIdTelemetryByIdWell(idWell);
if (telemetryId is null)
return null;
var datesRange = await (from d in db.TelemetryDataSaub
where d.IdTelemetry == telemetryId
select d.Date).Union(
from m in db.TelemetryMessages
where m.IdTelemetry == telemetryId
select m.Date).DefaultIfEmpty()
.GroupBy(g => true)
.AsNoTracking()
.Select(g => new
{
From = g.Min(),
To = g.Max()
}).OrderBy(gr => gr.From)
.FirstOrDefaultAsync(token)
.ConfigureAwait(false);
var result = new DatesRangeDto
{
From = datesRange.From,
To = datesRange.To.Year == 1 ? DateTime.MaxValue : datesRange.To
};
if (isUtc)
return result;
result = await telemetryService.DatesRangeToTelemetryTimeZoneAsync((int)telemetryId, result, token)
.ConfigureAwait(false);
return result;
}
public Task<List<ReportPropertiesDto>> GetAllReportsByWellAsync(int idWell, CancellationToken token) =>
(from r in db.ReportProperties.Include(r => r.File)
where r.IdWell == idWell
select new ReportPropertiesDto
{
Id = r.Id,
Name = r.File.Name,
File = new FileInfoDto
{
Id = r.File.Id,
Author = null,
IdAuthor = r.File.IdAuthor ?? 0,
IdCategory = r.File.IdCategory,
IdWell = r.File.IdWell,
Name = r.File.Name,
Size = r.File.Size,
UploadDate = r.File.UploadDate,
},
IdWell = r.IdWell,
Date = r.File.UploadDate,
Begin = r.Begin,
End = r.End,
Step = r.Step,
Format = r.Format == 0 ? ".pdf" : ".las"
})
.OrderBy(o => o.Date)
.AsNoTracking()
.Take(1024).ToListAsync(token);
private static IReportGenerator GetReportGenerator(int idWell, DateTime begin,
DateTime end, int stepSeconds, int format, AsbCloudDbContext context)
{
var dataSource = new ReportDataSourcePgCloud(context, idWell);
IReportGenerator generator = format switch
{
//LAS
1 => new AsbSaubReportLas.ReprotGeneratorLas(dataSource),
//PDF
_ => new AsbSaubReportPdf.ReprotGeneratorPdf(dataSource),
};
generator.Begin = begin;
generator.End = end;
generator.Step = TimeSpan.FromSeconds(stepSeconds);
generator.WithCharts = true;
generator.WithEvents = true;
return generator;
}
}
}