diff --git a/AsbCloudApp/Data/ReportPropertiesDto.cs b/AsbCloudApp/Data/ReportPropertiesDto.cs new file mode 100644 index 00000000..7526dc68 --- /dev/null +++ b/AsbCloudApp/Data/ReportPropertiesDto.cs @@ -0,0 +1,17 @@ +using System; + +namespace AsbCloudApp.Data +{ + public class ReportPropertiesDto + { + public int Id { get; set; } + public string Name { get; set; } + public string FullName { get; set; } + public int WellId { get; set; } + public DateTime Date { get; set; } + public DateTimeOffset Begin { get; set; } + public DateTimeOffset End { get; set; } + public int Step { get; set; } + public string Format { get; set; } + } +} diff --git a/AsbCloudApp/Services/IReportService.cs b/AsbCloudApp/Services/IReportService.cs index 7e21ca7b..8c3f0556 100644 --- a/AsbCloudApp/Services/IReportService.cs +++ b/AsbCloudApp/Services/IReportService.cs @@ -8,9 +8,9 @@ namespace AsbCloudApp.Services { string RootPath { get; } int CreateReport(int wellId, int stepSeconds, int format, DateTime begin, DateTime end, - Action handleReportProgress); + Action handleReportProgress, Action handleReportName); int GetReportPagesCount(int wellId, DateTime begin, DateTime end, int stepSeconds, int format); - IEnumerable GetExistingReportNames(int wellId, DateTime begin, DateTime end, int stepSeconds, int format); + IEnumerable GetSuitableReports(int wellId, DateTime begin, DateTime end, int stepSeconds, int format); DatesRangeDto GetReportsDatesRange(int wellId); } } diff --git a/AsbCloudDb/Model/Report.cs b/AsbCloudDb/Model/Report.cs index d17bdd33..2f63aa66 100644 --- a/AsbCloudDb/Model/Report.cs +++ b/AsbCloudDb/Model/Report.cs @@ -18,9 +18,9 @@ namespace AsbCloudDb.Model [Column("date", TypeName = "timestamp with time zone")] public DateTime Date { get; set; } [Column("begin", TypeName = "timestamp with time zone")] - public DateTime Begin { get; set; } + public DateTimeOffset Begin { get; set; } [Column("end"), Comment("timestamp with time zone")] - public DateTime End { get; set; } + public DateTimeOffset End { get; set; } [Column("step"), Comment("размер шага в секундах")] public int Step { get; set; } [Column("format"), Comment("Формат отчета")] diff --git a/AsbCloudInfrastructure/Services/BackgroundQueue.cs b/AsbCloudInfrastructure/Services/BackgroundQueue.cs index 7cd5286f..73d7be5c 100644 --- a/AsbCloudInfrastructure/Services/BackgroundQueue.cs +++ b/AsbCloudInfrastructure/Services/BackgroundQueue.cs @@ -16,7 +16,9 @@ namespace AsbCloudInfrastructure.Services if (action == null) throw new ArgumentNullException(nameof(action)); - tasks.Enqueue(new(action, id++)); + id++; + + tasks.Enqueue(new(action, id)); return id; } diff --git a/AsbCloudInfrastructure/Services/ReportService.cs b/AsbCloudInfrastructure/Services/ReportService.cs index c75a6fd6..dca2f934 100644 --- a/AsbCloudInfrastructure/Services/ReportService.cs +++ b/AsbCloudInfrastructure/Services/ReportService.cs @@ -30,7 +30,7 @@ namespace AsbCloudInfrastructure.Services public string RootPath { get ; private set; } public int CreateReport(int wellId, int stepSeconds, int format, DateTime begin, - DateTime end, Action progressHandler) + DateTime end, Action progressHandler, Action reportNameHandler) { var newReportId = queue.EnqueueTask((id) => { @@ -44,6 +44,9 @@ namespace AsbCloudInfrastructure.Services var newReportName = generator.Make(); if(newReportName is not null) { + var shorReportName = newReportName.Split(Path.DirectorySeparatorChar).Last(); + reportNameHandler.Invoke(shorReportName, id); + var newReportProperties = new Report { Name = newReportName, @@ -55,7 +58,7 @@ namespace AsbCloudInfrastructure.Services Format = format }; context.Reports.Add(newReportProperties); - db.SaveChanges(); + context.SaveChanges(); } } }); @@ -69,17 +72,24 @@ namespace AsbCloudInfrastructure.Services return generator.GetPagesCount(); } - public IEnumerable GetExistingReportNames(int wellId, DateTime begin, DateTime end, int stepSeconds, int format) + public IEnumerable GetSuitableReports(int wellId, DateTime begin, DateTime end, int stepSeconds, int format) { - var suitableReportsFromDb = GetSuitableReportNamesFromDb(wellId, begin, end, stepSeconds, format); + var suitableReportsFromDb = GetSuitableReportsFromDb(wellId, begin, end, stepSeconds, format); - var reportsFolder = Path.Combine(RootPath, $"{wellId}"); + var suitableReportsProperties = suitableReportsFromDb.Select(r => new ReportPropertiesDto + { + Id = r.Id, + Name = Path.GetFileName(r.Name), + FullName = r.Name, + WellId = r.WellId, + Date = r.Date, + Begin = r.Begin, + End = r.End, + Step = r.Step, + Format = r.Format == 0 ? ".pdf" : ".las" + }); - var suitableReportNames = Directory.GetFiles(reportsFolder) - .Select(Path.GetFileName) - .Where(name => suitableReportsFromDb.Contains(name)); - - return suitableReportNames; + return suitableReportsProperties; } public DatesRangeDto GetReportsDatesRange(int wellId) @@ -110,13 +120,16 @@ namespace AsbCloudInfrastructure.Services } } - private IEnumerable GetSuitableReportNamesFromDb(int wellId, DateTime begin, DateTime end, int stepSeconds, int format) + private IEnumerable GetSuitableReportsFromDb(int wellId, DateTime begin, DateTime end, int stepSeconds, int format) { var suitableReportsNames = (from r in db.Reports - where r.WellId == wellId && r.Begin == begin - && r.End == end && r.Step == stepSeconds + where r.WellId == wellId + && r.Begin >= begin + && r.End <= end + && r.Step <= stepSeconds && r.Format == format - select r.Name).ToList(); + select r).OrderBy(o => o.Date).Take(512).ToList(); + return suitableReportsNames; } diff --git a/AsbCloudWebApi/Controllers/ReportController.cs b/AsbCloudWebApi/Controllers/ReportController.cs index e9a46bb1..5c498867 100644 --- a/AsbCloudWebApi/Controllers/ReportController.cs +++ b/AsbCloudWebApi/Controllers/ReportController.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using AsbCloudApp.Data; using AsbCloudApp.Services; @@ -12,7 +13,7 @@ namespace AsbCloudWebApi.Controllers /// /// Контроллер отчетов по буровым скважинам /// - [Route("api/well")] + [Route("api/report")] [ApiController] public class ReportController : ControllerBase { @@ -27,9 +28,22 @@ namespace AsbCloudWebApi.Controllers this.reportsHubContext = reportsHubContext; } - private void HandleReportProgress (float progress, string operation, int id) => - reportsHubContext.Clients.Group($"Report{id}").SendAsync(nameof(IReportHubClient.GetReportProgress), progress); - + private void HandleReportProgressAsync (float progress, string operation, int id) => + Task.Run(()=> { + reportsHubContext.Clients.Group($"Report_{id}").SendAsync( + nameof(IReportHubClient.GetReportProgress), + new { Progress = progress, Operation = operation, ReportName = "" } + ); + }); + + private void HandleReportNameAsync (string reportName, int groupId) => + Task.Run(() => { + reportsHubContext.Clients.All.SendAsync( + nameof(IReportHubClient.GetReportProgress), + new { Progress = 100, Operation = "Отчет успешно создан", ReportName = reportName } + ); + }); + /// /// Создает отчет по скважине с указанными параметрами @@ -54,7 +68,7 @@ namespace AsbCloudWebApi.Controllers if (!wellService.CheckWellOwnership((int)idCustomer, wellId)) return Forbid(); - var id = reportService.CreateReport(wellId, stepSeconds, format, begin, end, HandleReportProgress); + var id = reportService.CreateReport(wellId, stepSeconds, format, begin, end, HandleReportProgressAsync, HandleReportNameAsync); return Ok(id); } @@ -66,9 +80,9 @@ namespace AsbCloudWebApi.Controllers /// имя запрашиваемого файла (отчета) /// файловый поток с отчетом [HttpGet] - [Route("{wellId}/report")] + [Route("{wellId}/{reportName}")] [ProducesResponseType(typeof(FileStreamResult), (int)System.Net.HttpStatusCode.OK)] - public IActionResult GetReport([FromRoute] int wellId, [FromQuery] string reportName) + public IActionResult GetReport([FromRoute] int wellId, string reportName) { try { @@ -80,6 +94,7 @@ namespace AsbCloudWebApi.Controllers if (!wellService.CheckWellOwnership((int)idCustomer, wellId)) return Forbid(); // TODO: словарь content typoв + var a = Path.Combine(reportService.RootPath, $"{wellId}", reportName); return PhysicalFile(Path.Combine(reportService.RootPath, $"{wellId}", reportName), "application/pdf", reportName); } catch (FileNotFoundException ex) @@ -104,7 +119,7 @@ namespace AsbCloudWebApi.Controllers public IActionResult GetSuitableReportsNames(int wellId, int stepSeconds, int format, DateTime begin = default, DateTime end = default) { - var suitableReportsNames = reportService.GetExistingReportNames(wellId, begin, end, stepSeconds, format); + var suitableReportsNames = reportService.GetSuitableReports(wellId, begin, end, stepSeconds, format); return Ok(suitableReportsNames); } diff --git a/AsbCloudWebApi/SignalR/IReportHubClient.cs b/AsbCloudWebApi/SignalR/IReportHubClient.cs index a756fa72..4eb9581f 100644 --- a/AsbCloudWebApi/SignalR/IReportHubClient.cs +++ b/AsbCloudWebApi/SignalR/IReportHubClient.cs @@ -2,6 +2,6 @@ { public interface IReportHubClient { - float GetReportProgress(); + float GetReportProgress(float progress); } } diff --git a/AsbCloudWebApi/SignalR/ReportsHub.cs b/AsbCloudWebApi/SignalR/ReportsHub.cs index e7521d8f..534063bd 100644 --- a/AsbCloudWebApi/SignalR/ReportsHub.cs +++ b/AsbCloudWebApi/SignalR/ReportsHub.cs @@ -1,4 +1,5 @@ -using Microsoft.AspNetCore.Authorization; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.SignalR; namespace AsbCloudWebApi.SignalR @@ -9,6 +10,10 @@ namespace AsbCloudWebApi.SignalR [Authorize] public class ReportsHub : Hub { + public Task AddToGroup(string groupName) + => Groups.AddToGroupAsync(Context.ConnectionId, groupName); + public Task RemoveFromGroup(string groupName) + => Groups.RemoveFromGroupAsync(Context.ConnectionId, groupName); } } diff --git a/AsbCloudWebApi/wwwroot/images/las.png b/AsbCloudWebApi/wwwroot/images/las.png new file mode 100644 index 00000000..1348d4b4 Binary files /dev/null and b/AsbCloudWebApi/wwwroot/images/las.png differ diff --git a/AsbCloudWebApi/wwwroot/images/pdf.png b/AsbCloudWebApi/wwwroot/images/pdf.png new file mode 100644 index 00000000..e47094f7 Binary files /dev/null and b/AsbCloudWebApi/wwwroot/images/pdf.png differ diff --git a/AsbCloudWebApi/кейсы для админки.txt b/AsbCloudWebApi/кейсы для админки.txt index ebdccc51..fb5a5117 100644 --- a/AsbCloudWebApi/кейсы для админки.txt +++ b/AsbCloudWebApi/кейсы для админки.txt @@ -3,4 +3,5 @@ Есть t_message для которой нет t_event | Ошибка синхронизации Есть t_telemetry для которой нет t_well | Кто-то начал новое бурение или исправил название старого 2 t_telemetry с не уникальными uid -Провалы в непрерывной t_data. \ No newline at end of file +Провалы в непрерывной t_data. +Сопоставление сущетсвующих на диске файлов-рапортов с теми, что хранятся в БД. \ No newline at end of file