CS2-3: Добавлена инфраструктура для работы с репортами

This commit is contained in:
KharchenkoVV 2021-05-18 12:33:23 +05:00
parent 2c0eb7b238
commit 35b24176ff
14 changed files with 1653 additions and 0 deletions

View File

@ -0,0 +1,11 @@
using System.IO;
namespace AsbCloudApp.Data
{
public class ReportPropertiesDto
{
public FileStream Filestream { get; set; }
public string ContentType { get; set; }
public string FileName { get; set; }
}
}

View File

@ -0,0 +1,12 @@
using System;
using AsbCloudApp.Data;
namespace AsbCloudApp.Services
{
public interface IReportService
{
int GetReportPagesCount(int wellId, DateTime begin, DateTime end, int stepSeconds, int format);
ReportPropertiesDto GetReportFileProperties(string reportName, string rootPath);
DatesRangeDto GetReportsDatesRange(int wellId);
}
}

View File

@ -0,0 +1,11 @@
using System;
namespace AsbCloudDb.Model
{
public class Report : IId, IIdTelemetryDate
{
public int Id { get; set; }
public int IdTelemetry { get; set; }
public DateTime Date { get; set; }
}
}

View File

@ -6,6 +6,7 @@
<ItemGroup>
<PackageReference Include="AutoMapper" Version="10.1.1" />
<PackageReference Include="itext7" Version="7.1.15" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.10.0" />
</ItemGroup>
@ -14,4 +15,10 @@
<ProjectReference Include="..\AsbCloudDb\AsbCloudDb.csproj" />
</ItemGroup>
<ItemGroup>
<Reference Include="AsbSaubReport">
<HintPath>CommonLibs\AsbSaubReport\AsbSaubReport.dll</HintPath>
</Reference>
</ItemGroup>
</Project>

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

View File

@ -30,6 +30,7 @@ namespace AsbCloudInfrastructure
services.AddTransient<IMessageService, MessageService>();
services.AddTransient<IEventService, EventService>();
services.AddTransient<ITelemetryUserService, TelemetryUserService>();
services.AddTransient<IReportService, ReportService>();
return services;
}

View File

@ -0,0 +1,107 @@
using AsbSaubReport.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using AsbCloudDb.Model;
using Microsoft.EntityFrameworkCore;
namespace AsbSaubReport
{
public class ReportDataSourcePgCloud : IReportDataSource
{
private readonly AsbCloudDbContext context;
private readonly int? idTelemetry;
private readonly WellInfoReport info;
private readonly Dictionary<int, Event> events;
private readonly Dictionary<int, TelemetryUser> users;
private readonly Dictionary<int, string> categories = new Dictionary<int, string>
{
{1, "Авария"},
{2, "Предупреждение"},
{3, "Информация"},
};
public ReportDataSourcePgCloud(AsbCloudDbContext context, int wellId)
{
this.context = context;
var well = context.Wells
.Include(w=>w.Cluster)
.ThenInclude(c=>c.Deposit)
.Include(w=>w.Customer)
.Include(w => w.Telemetry)
.FirstOrDefault(w => w.Id == wellId);
idTelemetry = well?.IdTelemetry;
if (idTelemetry is null)
throw new ArgumentException($"Well {wellId} doesn't contain telemetry", nameof(wellId));
events = context.Events
.Where(e => e.IdTelemetry == idTelemetry)
.ToDictionary(e => e.IdEvent, e => e);
users = context.TelemetryUsers
.Where(u => u.IdTelemetry == idTelemetry)
.ToDictionary(u => u.IdUser, u => u);
info = new WellInfoReport
{
Deposit = well.Cluster.Deposit.Caption,
Cluster = well.Cluster.Caption,
Well = well.Caption,
Customer = well.Customer.Caption,
DrillingStartDate = well.Telemetry?.Info?.DrillingStartDate??default,
TimeZoneId = well.Telemetry?.Info?.TimeZoneId??default,
};
}
public IQueryable<DataSaubReport> GetDataSaubItems(DateTime begin, DateTime end)
=> from item in context.DataSaubBases
where item.IdTelemetry == idTelemetry
&& item.Date >= begin
&& item.Date <= end
select new DataSaubReport
{
Id = item.Id,
Date = item.Date,
Mode = item.Mode,
WellDepth = item.WellDepth,
BitDepth = item.BitDepth,
BlockPosition = item.BlockPosition,
BlockSpeed = item.BlockSpeed,
BlockSpeedSp = item.BlockSpeedSp,
BlockSpeedSpDevelop = item.BlockSpeedSpDevelop,
Pressure = item.Pressure,
PressureSp = item.PressureSp,
AxialLoad = item.AxialLoad,
AxialLoadSp = item.AxialLoadSp,
AxialLoadLimitMax = item.AxialLoadLimitMax,
HookWeight = item.HookWeight,
RotorTorque = item.RotorTorque,
RotorTorqueSp = item.RotorTorqueSp,
RotorSpeed = item.RotorSpeed,
Flow = item.Flow,
PressureSpDevelop = item.PressureSpDevelop,
};
public IQueryable<MessageReport> GetMessages(DateTime begin, DateTime end)
=> from item in context.Messages
where item.IdTelemetry == idTelemetry
&& item.Date >= begin
&& item.Date <= end
select new MessageReport
{
Id = item.Id,
Date = item.Date,
Category = categories[events[item.IdEvent].IdCategory],
User = item.IdTelemetryUser == null
? ""
: users[(int)item.IdTelemetryUser].MakeDisplayName(),
Text = events[item.IdEvent].MakeMessageText(item)
};
public WellInfoReport GetWellInfo()
=> info;
}
}

View File

@ -0,0 +1,67 @@
using AsbCloudApp.Services;
using AsbCloudApp.Data;
using AsbCloudDb.Model;
using System;
using System.IO;
using AsbSaubReport;
namespace AsbCloudInfrastructure.Services
{
public class ReportService : IReportService
{
private readonly IAsbCloudDbContext db;
private readonly ITelemetryService telemetryService;
public ReportService(IAsbCloudDbContext db, ITelemetryService telemetryService)
{
this.db = db;
this.telemetryService = telemetryService;
}
public int GetReportPagesCount(int wellId, DateTime begin, DateTime end, int stepSeconds, int format)
{
var generator = GetReportGenerator(wellId, begin, end, stepSeconds, format);
return generator.GetPagesCount();
}
public ReportPropertiesDto GetReportFileProperties(string reportName, string rootPath)
{
string path = Path.Combine(rootPath, reportName);
FileStream fs = new FileStream(path, FileMode.Open);
string contentType = Path.GetExtension(path);
string fileName = Path.GetFileName(path);
return new ReportPropertiesDto {
Filestream = fs,
ContentType = contentType,
FileName = fileName
};
}
public DatesRangeDto GetReportsDatesRange(int wellId)
{
var telemetry = telemetryService.GetTelemetryByWellId(wellId);
if (telemetry is null)
return null;
var result = db.GetDatesRange<Report>(telemetry.Id);
return new DatesRangeDto { From = result.From, To = result.To };
}
private IReportGenerator GetReportGenerator(int wellId,DateTime begin, DateTime end, int stepSeconds, int format)
{
var dataSource = new ReportDataSourcePgCloud((AsbCloudDbContext)db, wellId);
var generator = new PdfGenerator(dataSource);
generator.Begin = begin;
generator.End = end;
generator.Step = TimeSpan.FromSeconds(stepSeconds);
generator.WithCharts = true;
generator.WithEvents = true;
return generator;
}
}
}

View File

@ -0,0 +1,150 @@
using System;
using System.Threading.Tasks;
using System.IO;
using Microsoft.AspNetCore.Mvc;
using AsbCloudApp.Data;
using AsbCloudApp.Services;
using AsbCloudDb.Model;
using Microsoft.AspNetCore.Hosting;
namespace AsbCloudWebApi.Controllers
{
/// <summary>
/// Контроллер отчетов по буровым скважинам
/// </summary>
[Route("api/well")]
[ApiController]
public class ReportController : ControllerBase
{
private readonly IAsbCloudDbContext db;
private readonly IReportService reportService;
private readonly IWellService wellService;
private readonly IWebHostEnvironment appEnvironment;
public ReportController(IAsbCloudDbContext db, IReportService reportService, IWellService wellService, IWebHostEnvironment appEnvironment)
{
this.db = db;
this.reportService = reportService;
this.wellService = wellService;
this.appEnvironment = appEnvironment;
}
/// <summary>
/// Создает отчет по скважине с указанными параметрами
/// </summary>
/// <param name="wellId">id скважины</param>
/// <param name="begin">дата начала интервала</param>
/// <param name="end">дата окончания интервала</param>
/// <param name="step">шаг интервала</param>
/// <param name="format">формат отчета (0-PDF, 1-LASS)</param>
/// <returns>id фоновой задачи формирования отчета</returns>
[HttpPost]
[Route("{wellId}/report")]
[ProducesResponseType(typeof(string), (int)System.Net.HttpStatusCode.OK)]
// ЭТОТ МЕТОД ПОКА НЕ РЕАЛИЗОВАН
public async Task<IActionResult> CreateReportAsync(int wellId, int stepSeconds, int format, DateTime begin = default, DateTime end = default)
{
int? idCustomer = User.GetCustomerId();
if (idCustomer is null)
return BadRequest();
if (!wellService.CheckWellOwnership((int)idCustomer, wellId))
return Forbid();
return await Task.Run(() =>
{
// создаем отчет. Это заготовка, пока еще не перенесена в сервис.
var taskId = Task.CurrentId;
if (taskId is null)
throw new NullReferenceException("Не удалось получить id задачи");
return Ok(taskId.ToString());
});
}
/// <summary>
/// Возвращает файл-отчет с диска на сервере
/// </summary>
/// <param name="wellId">id скважины</param>
/// <param name="reportName">имя запрашиваемого файла (отчета)</param>
/// <returns>файловый поток с отчетом</returns>
[HttpGet]
[Route("{wellId}/report")]
[ProducesResponseType(typeof(FileStreamResult), (int)System.Net.HttpStatusCode.OK)]
public IActionResult GetReport([FromRoute] int wellId, [FromQuery] string reportName)
{
try
{
int? idCustomer = User.GetCustomerId();
if (idCustomer is null)
return BadRequest();
if (!wellService.CheckWellOwnership((int)idCustomer, wellId))
return Forbid();
var options = reportService.GetReportFileProperties(reportName, appEnvironment.ContentRootPath);
return File(options.Filestream, options.ContentType, options.FileName);
}
catch (FileNotFoundException ex)
{
return NotFound("Файл не найден");
}
}
/// <summary>
/// Возвращает прогнозируемое количество страниц будущего отчета
/// </summary>
/// <param name="wellId">id скважины</param>
/// <param name="begin">дата начала интервала</param>
/// <param name="end">дата окончания интервала</param>
/// <param name="step">шаг интервала</param>
/// <param name="format">формат отчета (0-PDF, 1-LASS)</param>
/// <returns>прогнозируемое кол-во страниц отчета</returns>
[HttpGet]
[Route("{wellId}/reportSize")]
[ProducesResponseType(typeof(string), (int)System.Net.HttpStatusCode.OK)]
public IActionResult GetReportSize(int wellId, int stepSeconds, int format, DateTime begin = default, DateTime end = default)
{
int? idCustomer = User.GetCustomerId();
if (idCustomer is null)
return BadRequest();
if (!wellService.CheckWellOwnership((int)idCustomer, wellId))
return Forbid();
int reportSize = reportService.GetReportPagesCount(wellId, begin, end, stepSeconds, format);
return Ok(reportSize);
}
/// <summary>
/// Возвращает даты самого старого и самого свежего отчетов в БД
/// </summary>
/// <param name="wellId">id скважины</param>
/// <returns>Даты самого старого и самого свежего отчетов в БД</returns>
[HttpGet]
[Route("{wellId}/reportsDatesRange")]
[ProducesResponseType(typeof(DatesRangeDto), (int)System.Net.HttpStatusCode.OK)]
public IActionResult GetReportsDateRange(int wellId)
{
int? idCustomer = User.GetCustomerId();
if (idCustomer is null)
return BadRequest();
if (!wellService.CheckWellOwnership((int)idCustomer, wellId))
return Forbid();
DatesRangeDto wellReportsDatesRange = reportService.GetReportsDatesRange(wellId);
return Ok(wellReportsDatesRange);
}
}
}