From 44d41fb37707e4fdac658d4d001f6bd11d3e9d9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A4=D1=80=D0=BE=D0=BB=D0=BE=D0=B2?= Date: Thu, 23 Sep 2021 10:52:10 +0500 Subject: [PATCH 1/3] =?UTF-8?q?CS2-60=20ReportGenerator=20=D0=B2=D1=8B?= =?UTF-8?q?=D0=B4=D0=B0=D0=B5=D1=82=20=D0=BD=D0=B5=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=B8=D0=BB=D1=8C=D0=BD=D1=8B=D0=B5=20=D0=B7=D0=BD=D0=B0=D1=87?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=BF=D1=80=D0=B8=20=D0=BE=D1=82?= =?UTF-8?q?=D1=81=D1=83=D1=82=D1=81=D1=82=D0=B2=D0=B8=D0=B8=20=D0=B4=D0=B0?= =?UTF-8?q?=D0=BD=D0=BD=D1=8B=D1=85=20=D0=B2=20=D0=91=D0=94.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AsbCloudApp/Data/ReportProgressDto.cs | 10 + AsbCloudApp/Data/ReportPropertiesDto.cs | 2 +- AsbCloudApp/Services/IFileService.cs | 4 +- AsbCloudApp/Services/IReportService.cs | 7 +- .../CommonLibs/AsbSaubReport.dll | Bin 13824 -> 15360 bytes .../CommonLibs/AsbSaubReportLas.dll | Bin 15360 -> 16384 bytes .../CommonLibs/AsbSaubReportPdf.dll | Bin 552960 -> 553984 bytes .../CommonLibs/ref/AsbSaubReportLas.dll | Bin 6144 -> 6144 bytes .../CommonLibs/ref/AsbSaubReportPdf.dll | Bin 14848 -> 14336 bytes .../ReportDataSourcePgCloud.cs | 11 +- .../Services/ReportService.cs | 172 +++++++++--------- .../Controllers/ReportController.cs | 111 +++++------ 12 files changed, 161 insertions(+), 156 deletions(-) create mode 100644 AsbCloudApp/Data/ReportProgressDto.cs diff --git a/AsbCloudApp/Data/ReportProgressDto.cs b/AsbCloudApp/Data/ReportProgressDto.cs new file mode 100644 index 00000000..f3380d56 --- /dev/null +++ b/AsbCloudApp/Data/ReportProgressDto.cs @@ -0,0 +1,10 @@ +namespace AsbCloudApp.Data +{ + public class ReportProgressDto + { + public float Progress { get; set; } + public string Operation { get; set; } + public int CurrentPage { get; set; } + public int TotalPages { get; set; } + } +} diff --git a/AsbCloudApp/Data/ReportPropertiesDto.cs b/AsbCloudApp/Data/ReportPropertiesDto.cs index 09674a62..a1e3e6e9 100644 --- a/AsbCloudApp/Data/ReportPropertiesDto.cs +++ b/AsbCloudApp/Data/ReportPropertiesDto.cs @@ -6,7 +6,7 @@ namespace AsbCloudApp.Data { public int Id { get; set; } public string Name { get; set; } - public string FullName { get; set; } + public string Url { get; set; } public int IdWell { get; set; } public DateTime Date { get; set; } public DateTimeOffset Begin { get; set; } diff --git a/AsbCloudApp/Services/IFileService.cs b/AsbCloudApp/Services/IFileService.cs index 34a0f3fc..6b1eb37c 100644 --- a/AsbCloudApp/Services/IFileService.cs +++ b/AsbCloudApp/Services/IFileService.cs @@ -24,6 +24,8 @@ namespace AsbCloudApp.Services CancellationToken token = default); Task> GetInfosByCategoryAsync(int idWell, int idCategory, CancellationToken token = default); Task DeletedAsync(int id, CancellationToken token); - string GetFileName(FileInfoDto fileInfo); + string GetUrl(FileInfoDto fileInfo); + string GetUrl(int idFile); + string GetUrl(int idWell, int idCategory, int idFile, string dotExtention); } } diff --git a/AsbCloudApp/Services/IReportService.cs b/AsbCloudApp/Services/IReportService.cs index 939f6083..0d7d80b4 100644 --- a/AsbCloudApp/Services/IReportService.cs +++ b/AsbCloudApp/Services/IReportService.cs @@ -11,14 +11,15 @@ namespace AsbCloudApp.Services int ReportCategoryId { get; } int CreateReport(int idWell, int idUser, int stepSeconds, int format, DateTime begin, DateTime end, - Action handleReportProgress, - Action handleReportName); + Action handleReportProgress); int GetReportPagesCount(int idWell, DateTime begin, DateTime end, int stepSeconds, int format); - Task> GetSuitableReportsAsync(int idWell, + + Task> GetSuitableReportsAsync(int idWell, DateTime begin, DateTime end, int stepSeconds, int format, CancellationToken token); Task GetReportsDatesRangeAsync(int idWell, CancellationToken token); + Task> GetAllReportsByWellAsync(int idWell, CancellationToken token); } } diff --git a/AsbCloudInfrastructure/CommonLibs/AsbSaubReport.dll b/AsbCloudInfrastructure/CommonLibs/AsbSaubReport.dll index 19620af62711b47b1d1ed42528a3c79d87b6d4e2..9366757e5cfed82cadbeeb72113a8471fd3a954c 100644 GIT binary patch literal 15360 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 diff --git a/AsbCloudInfrastructure/CommonLibs/AsbSaubReportLas.dll b/AsbCloudInfrastructure/CommonLibs/AsbSaubReportLas.dll index 1e5c8d32e1a405ac14c731ef928488420f84b76a..56a220286a5e2ebc00676a18a831f0c3c211f204 100644 GIT binary patch literal 16384 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 a&fxwzOZLXk`HRN?Fmtbc!5`UJyYb(&I)y9% diff --git a/AsbCloudInfrastructure/CommonLibs/AsbSaubReportPdf.dll b/AsbCloudInfrastructure/CommonLibs/AsbSaubReportPdf.dll index 5c23bfddbc2a2847aea261c3e3052f3a6ec0e539..51b612f01fa9796a18a512a96f31208e4ffce60d 100644 GIT binary patch delta 26724 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 delta 25711 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 diff --git a/AsbCloudInfrastructure/CommonLibs/ref/AsbSaubReportLas.dll b/AsbCloudInfrastructure/CommonLibs/ref/AsbSaubReportLas.dll index f1c38b7857736a68d1d012c9eead52babb21885f..5f40dc30dd001273a666266aae19d60363b3a60d 100644 GIT binary patch delta 1660 zcmb7_T}&KR7>2)d&M@p!cG%fMi;*Cd5NO)a#Y(F}kuB7+R_d0Y0KsP2;)G&WSZBA5 znugg_B&|_XGB=tSQ-ePx+QbC)LL0+{Hfp>vv57HW*r<4EVyq_gLf`W(iyPyOvpLUv z@B5vI>0QR(*`9&To`^{c-V#xUjk+MrC*- z7Ry-Q-yB$}J$tTkVR?SlHhvX;rycYIW@Xu01(86LgMPwnJ#@t&YMLjiE+cwW$3r=H zW_CJDxH3T^SkyE!L^;G^9UmQu_u;+(-Q|B^wscVxm|j zoeH9gwHqMvz{d7E@v7#C#) z{UnLlh@Xt)?SuTE{L_23)oG?j04x(XF2)~vlH zT?!U+VyE#G-lWap#WQrSM4iFYE#?+IG&E^jNjF;Qm8-=%{vSTht$aM6`!JDPcp+`j zq&vV0+Rbr07)D+*#`NNRJHZ@hrkEE&lNxA>KBYEH$p^RNwQIw!_!w+re-C|uct8CG zc2bRK!vgIBkI_DGi2Vt$hx?gi=9$kjFME7jX09=RV3N=SH!ypclgvExGINb7@sx-@ z!k#EZZ_7ONFlpY9&w+oa=fQ88i|QpTS_pN+WP$#d6^A{6-5#PEGV+Cej@p}-g}tj! zhvHR7Z*o}J?M1g)A2WEtBE3iIo4qHRjMDKl>2&H;+L>&p zBWIo2Tz_izv9zPy$@W!m+ezX7S@})~m2;y`I^E}Fa;N>*Lr?lGR@?6Qpp%(%b4Q(7 z$4%wtTxy%rgzL`z<360q`tw%uz_gP~CfvDc*U4sipqPs@G5eqH@Juf4BvNkb3IBKN zT7>A|=dZt3RpXg8kwYR93%vJ0(z9<=+;5sS_P7X1(<?~mS)IkAUj^xAcP&) z;Q)sNs)3{d6QD>;dy!ZWEcD9y1nLA(ETa`YXbh-Uv}#3zfIks_%dfZVBV+ht6falD fJxh%{{4TrF&)BamMJrdW$cB;&o&3>QikANko7X9i delta 1645 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 c.Company.IdCompanyType == 1)?.Company.Caption, DrillingStartDate = well.Telemetry?.Info?.DrillingStartDate ?? default, TimeZoneId = well.Telemetry?.Info?.TimeZoneId ?? default, + TimeZoneOffsetTotalHours = well.Telemetry?.Info?.TimeZoneOffsetTotalHours ?? default, }; } @@ -62,19 +63,19 @@ namespace AsbSaubReport var messagesStat = (from item in context.TelemetryMessages where item.IdTelemetry == idTelemetry group item.Date by item.IdTelemetry into g - select new { min = g.Min(), max = g.Max(), count = g.Count()}) + select new { min = g.Min(), max = g.Max(), count = g.Count() }) .FirstOrDefault(); var dataStat = (from item in context.TelemetryDataSaub - where item.IdTelemetry == idTelemetry + where item.IdTelemetry == idTelemetry group item.Date by item.IdTelemetry into g select new { min = g.Min(), max = g.Max(), count = g.Count() }) .FirstOrDefault(); var result = new AnalyzeResult { - MinDate = dataStat?.max ?? messagesStat?.min ?? default, - MaxDate = dataStat?.max ?? messagesStat?.min ?? default, + MinDate = dataStat?.min ?? messagesStat?.min ?? default, + MaxDate = dataStat?.max ?? messagesStat?.max ?? default, MessagesCount = messagesStat?.count ?? 0, }; @@ -86,6 +87,7 @@ namespace AsbSaubReport where item.IdTelemetry == idTelemetry && item.Date >= begin && item.Date <= end + orderby item.Date select new DataSaubReport { Id = item.Id, @@ -115,6 +117,7 @@ namespace AsbSaubReport where item.IdTelemetry == idTelemetry && item.Date >= begin && item.Date <= end + orderby item.Date select new MessageReport { Id = item.Id, diff --git a/AsbCloudInfrastructure/Services/ReportService.cs b/AsbCloudInfrastructure/Services/ReportService.cs index 4f3f8875..6236f8d2 100644 --- a/AsbCloudInfrastructure/Services/ReportService.cs +++ b/AsbCloudInfrastructure/Services/ReportService.cs @@ -2,7 +2,7 @@ using AsbCloudApp.Services; using AsbCloudDb.Model; using AsbSaubReport; -using AsbSaubReportPdf; +using Mapster; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using System; @@ -39,90 +39,66 @@ namespace AsbCloudInfrastructure.Services public int ReportCategoryId { get; private set; } public int CreateReport(int idWell, int idUser, int stepSeconds, int format, DateTime begin, - DateTime end, Action progressHandler, Action reportNameHandler) + DateTime end, Action progressHandler) { var newReportId = queue.EnqueueTask((id) => { var optionsBuilder = new DbContextOptionsBuilder(); optionsBuilder.UseNpgsql(configuration.GetConnectionString("DefaultConnection")); + var tempDir = Path.Combine(Path.GetTempPath(), "report"); - using (var context = new AsbCloudDbContext(optionsBuilder.Options)) + 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) => { - var generator = GetReportGenerator(idWell, begin, end, stepSeconds, format, context); - generator.OnProgress += (s, e) => progressHandler.Invoke(e.progress, e.operation, id); + progressHandler.Invoke(e.Adapt(), id); + }; + generator.Make(reportFileName); - var reportFileName = GetReportFileName(context, idWell); + var fileService = new FileService(context); + using var filestream = File.OpenRead(reportFileName); + var fileInfo = fileService.SaveAsync(idWell, idUser, ReportCategoryId, reportFileName, filestream).Result; + filestream.Close(); - generator.Make(reportFileName); - if (reportFileName is not null) - { - var shorReportName = Path.GetFileName(reportFileName); - reportNameHandler.Invoke(shorReportName, id); + progressHandler.Invoke(new + { + Operation = "done", + Progress = 100f, + TotalPages = totalPages, + CurrentPage = totalPages, + file = fileInfo, + }, id); - var newReportFile = new AsbCloudDb.Model.FileInfo - { - IdWell = idWell, - IdAuthor = idUser, - IdCategory = ReportCategoryId, - Name = reportFileName, - UploadDate = DateTime.Now, - }; - - context.Files.Add(newReportFile); - - var newReportProperties = new ReportProperty - { - IdWell = idWell, - IdFile = newReportFile.Id, - Begin = begin, - End = end, - Step = stepSeconds, - Format = format - }; - context.ReportProperties.Add(newReportProperties); - context.SaveChanges(); - } - } + 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; } - private string GetReportFileName(AsbCloudDbContext context, int idWell) - { - var well = context.Wells.Include(w => w.Cluster).FirstOrDefault(w => w.Id == idWell); - var fileName = Path.Combine(fileService.RootPath, $"{idWell}", $"{ReportCategoryId}", $"Рапорт куст{well?.Cluster?.Caption} скв{well.Caption}.pdf") ; - return fileName; - } - 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> GetSuitableReportsAsync(int idWell, - DateTime begin, DateTime end, int stepSeconds, int format, CancellationToken token = default) - { - var suitableReportsFromDb = await GetSuitableReportsFromDbAsync(idWell, - begin, end, stepSeconds, format, token).ConfigureAwait(false); - - var suitableReportsProperties = suitableReportsFromDb.Select(r => new ReportPropertiesDto - { - Id = r.Id, - Name = Path.GetFileName(r.File.Name), - FullName = r.File.Name, - IdWell = r.IdWell, - Date = r.File.UploadDate, - Begin = r.Begin, - End = r.End, - Step = r.Step, - Format = r.Format == 0 ? ".pdf" : ".las" - }); - - return suitableReportsProperties; - } - public async Task GetReportsDatesRangeAsync(int idWell, CancellationToken token = default) { @@ -154,25 +130,53 @@ namespace AsbCloudInfrastructure.Services }; } - private async Task> GetSuitableReportsFromDbAsync(int idWell, - DateTime begin, DateTime end, int stepSeconds, int format, - CancellationToken token = default) - { - var suitableReportsNames = await (from r in db.ReportProperties.Include(r => r.File) - where r.IdWell == idWell - && r.Begin >= begin - && r.End <= end - && r.Step <= stepSeconds - && r.Format == format - select r).OrderBy(o => o.File.UploadDate) - .AsNoTracking() - .Take(512).ToListAsync(token) - .ConfigureAwait(false); - return suitableReportsNames; - } + [Obsolete] + Task> IReportService.GetSuitableReportsAsync(int idWell, DateTime begin, DateTime end, int stepSeconds, int format, CancellationToken token) => + (from r in db.ReportProperties.Include(r => r.File) + where r.IdWell == idWell + && r.Begin >= begin + && r.End <= end + && r.Step <= stepSeconds + && r.Format == format + select new ReportPropertiesDto + { + Id = r.Id, + Name = r.File.Name, + Url = fileService.GetUrl(r.IdFile), + 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(512).ToListAsync(token); - private IReportGenerator GetReportGenerator(int idWell, DateTime begin, + public Task> 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, +#pragma warning disable IDE0057 // Use range operator + Url = fileService.GetUrl(r.IdWell, ReportCategoryId, r.File.Id, r.File.Name.Substring(r.File.Name.LastIndexOf(".") > 0 ? r.File.Name.LastIndexOf(".") : r.File.Name.Length)), +#pragma warning restore IDE0057 // Use range operator + 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); @@ -181,11 +185,11 @@ namespace AsbCloudInfrastructure.Services switch (format) { case 1: //LAS - generator = new AsbSaubReportLas.LasReprotGenerator(dataSource); + generator = new AsbSaubReportLas.ReprotGeneratorLas(dataSource); break; case 0: //PDF default: - generator = new PdfReprotGenerator(dataSource); + generator = new AsbSaubReportPdf.ReprotGeneratorPdf(dataSource); break; } diff --git a/AsbCloudWebApi/Controllers/ReportController.cs b/AsbCloudWebApi/Controllers/ReportController.cs index 67e05734..180fb908 100644 --- a/AsbCloudWebApi/Controllers/ReportController.cs +++ b/AsbCloudWebApi/Controllers/ReportController.cs @@ -5,8 +5,6 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.SignalR; using System; using System.Collections.Generic; -using System.IO; -using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -33,25 +31,6 @@ namespace AsbCloudWebApi.Controllers this.reportsHubContext = reportsHubContext; } - 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 = "" } - ).ConfigureAwait(false); - }); - - private void HandleReportNameAsync(string reportName, int groupId) => - Task.Run(() => - { - reportsHubContext.Clients.All.SendAsync( - nameof(IReportHubClient.GetReportProgress), - new { Progress = 100, Operation = "Отчет успешно создан", ReportName = reportName } - ).ConfigureAwait(false); - }); - - /// /// Создает отчет по скважине с указанными параметрами /// @@ -65,9 +44,44 @@ namespace AsbCloudWebApi.Controllers /// id фоновой задачи формирования отчета [HttpPost] [ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)] - public async Task CreateReportAsync(int idWell, int idUser, int stepSeconds, int format, + public async Task CreateReportAsync(int idWell, int stepSeconds, int format, DateTime begin = default, DateTime end = default, CancellationToken token = default) + { + var idCompany = User.GetCompanyId(); + var idUser = User.GetUserId(); + + if ((idCompany is null) || (idUser is null)) + return Forbid(); + + if (!await wellService.IsCompanyInvolvedInWellAsync((int)idCompany, + idWell, token).ConfigureAwait(false)) + return Forbid(); + + void HandleReportProgressAsync(object progress, int id) => + Task.Run(() => + { + reportsHubContext.Clients.Group($"Report_{id}").SendAsync( + nameof(IReportHubClient.GetReportProgress), + progress + ).ConfigureAwait(false); + }); + + var id = reportService.CreateReport(idWell, (int)idUser, + stepSeconds, format, begin, end, HandleReportProgressAsync); + + return Ok(id); + } + + /// + /// Возвращает имена всех отчетов по скважине + /// + /// id скважины + /// Токен для отмены задачи + /// Список имен существующих отчетов (отчетов) + [HttpGet] + [ProducesResponseType(typeof(IEnumerable), (int)System.Net.HttpStatusCode.OK)] + public async Task GetAllReportsNamesByWellAsync(int idWell, CancellationToken token = default) { int? idCompany = User.GetCompanyId(); @@ -78,45 +92,9 @@ namespace AsbCloudWebApi.Controllers idWell, token).ConfigureAwait(false)) return Forbid(); - var id = reportService.CreateReport(idWell, idUser, - stepSeconds, format, begin, end, HandleReportProgressAsync, HandleReportNameAsync); + var reports = await reportService.GetAllReportsByWellAsync(idWell, token).ConfigureAwait(false); - return Ok(id); - } - - /// - /// Возвращает файл-отчет с диска на сервере - /// - /// id скважины - /// имя запрашиваемого файла (отчета) - /// Токен для отмены задачи - /// файл с отчетом - [HttpGet] - [Route("{reportName}")] - [ProducesResponseType(typeof(PhysicalFileResult), (int)System.Net.HttpStatusCode.OK)] - public async Task GetReportAsync([FromRoute] int idWell, - string reportName, CancellationToken token = default) - { - try - { - int? idCompany = User.GetCompanyId(); - - if (idCompany is null) - return Forbid(); - - if (!await wellService.IsCompanyInvolvedInWellAsync((int)idCompany, - idWell, token).ConfigureAwait(false)) - return Forbid(); - - // TODO: словарь content typoв - var relativePath = Path.Combine(fileService.RootPath, $"{idWell}", - $"{reportService.ReportCategoryId}", reportName); - return PhysicalFile(Path.GetFullPath(relativePath), "application/pdf", reportName); - } - catch (FileNotFoundException ex) - { - return NotFound($"Файл не найден. Текст ошибки: {ex.Message}"); - } + return Ok(reports); } /// @@ -130,6 +108,7 @@ namespace AsbCloudWebApi.Controllers /// дата окончания интервала /// Токен для отмены задачи /// Список имен существующих отчетов (отчетов) + [Obsolete] [HttpGet] [Route("suitableReports")] [ProducesResponseType(typeof(IEnumerable), (int)System.Net.HttpStatusCode.OK)] @@ -137,12 +116,18 @@ namespace AsbCloudWebApi.Controllers DateTime begin = default, DateTime end = default, CancellationToken token = default) { + int? idCompany = User.GetCompanyId(); + + if (idCompany is null) + return Forbid(); + + if (!await wellService.IsCompanyInvolvedInWellAsync((int)idCompany, + idWell, token).ConfigureAwait(false)) + return Forbid(); + var suitableReportsNames = await reportService.GetSuitableReportsAsync(idWell, begin, end, stepSeconds, format, token).ConfigureAwait(false); - if (suitableReportsNames is null || !suitableReportsNames.Any()) - return NoContent(); - return Ok(suitableReportsNames); } From 760a5161762fa2a4be45de416150dbe4b7fdab9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A4=D1=80=D0=BE=D0=BB=D0=BE=D0=B2?= Date: Thu, 23 Sep 2021 10:53:12 +0500 Subject: [PATCH 2/3] update EF --- AsbCloudDb/AsbCloudDb.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/AsbCloudDb/AsbCloudDb.csproj b/AsbCloudDb/AsbCloudDb.csproj index abcff305..903f171c 100644 --- a/AsbCloudDb/AsbCloudDb.csproj +++ b/AsbCloudDb/AsbCloudDb.csproj @@ -5,11 +5,11 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive - + From e93e1e72a18083c58d8f6051dfbdab9c0897a847 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A4=D1=80=D0=BE=D0=BB=D0=BE=D0=B2?= Date: Thu, 23 Sep 2021 10:53:48 +0500 Subject: [PATCH 3/3] =?UTF-8?q?=D0=BF=D0=B5=D1=80=D0=B5=D0=B8=D0=BC=D0=B5?= =?UTF-8?q?=D0=BD=D0=BE=D0=B2=D0=B0=D0=BB=20=D1=80=D1=8F=D0=B4=20=D0=BC?= =?UTF-8?q?=D0=B5=D1=82=D0=BE=D0=B4=D0=BE=D0=B2=20=D0=B4=D0=BB=D1=8F=20?= =?UTF-8?q?=D0=BB=D1=83=D1=87=D1=88=D0=B5=D0=B3=D0=BE=20=D0=BF=D0=BE=D0=BD?= =?UTF-8?q?=D0=B8=D0=BC=D0=B0=D0=BD=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Services/DrillingProgramService.cs | 2 +- .../Services/FileService.cs | 28 ++++++++++++------- ...Service.cs => TelemetryDataBaseService.cs} | 4 +-- .../Services/TelemetryDataSaubService.cs | 10 +++---- .../Services/TelemetryDataSpinService.cs | 2 +- .../Services/TelemetryService.cs | 2 +- .../Controllers/DrillingProgramController.cs | 2 +- AsbCloudWebApi/Controllers/FileController.cs | 3 +- 8 files changed, 30 insertions(+), 23 deletions(-) rename AsbCloudInfrastructure/Services/{TelemetryDataService.cs => TelemetryDataBaseService.cs} (96%) diff --git a/AsbCloudInfrastructure/Services/DrillingProgramService.cs b/AsbCloudInfrastructure/Services/DrillingProgramService.cs index 7197c4e9..275a106f 100644 --- a/AsbCloudInfrastructure/Services/DrillingProgramService.cs +++ b/AsbCloudInfrastructure/Services/DrillingProgramService.cs @@ -55,7 +55,7 @@ namespace AsbCloudInfrastructure.Services var fileNames = filesInfos .Where(f => f.Name != resultFileName) - .Select(f => fileService.GetFileName(f)); + .Select(f => fileService.GetUrl(f)); var stream = new MemoryStream(1024 * 1024); UniteExcelFiles(fileNames, stream); diff --git a/AsbCloudInfrastructure/Services/FileService.cs b/AsbCloudInfrastructure/Services/FileService.cs index 615fcc08..f6454701 100644 --- a/AsbCloudInfrastructure/Services/FileService.cs +++ b/AsbCloudInfrastructure/Services/FileService.cs @@ -52,10 +52,8 @@ namespace AsbCloudInfrastructure.Services Directory.CreateDirectory(Path.GetDirectoryName(relativePath)); - using (var newfileStream = new FileStream(relativePath, FileMode.Create)) - { - await fileStream.CopyToAsync(newfileStream); - } + using var newfileStream = new FileStream(relativePath, FileMode.Create); + await fileStream.CopyToAsync(newfileStream, token).ConfigureAwait(false); var dto = entry.Entity.Adapt(); return dto; @@ -164,7 +162,7 @@ namespace AsbCloudInfrastructure.Services if (fileInfo is null) return 0; - var fileName = GetFileName(fileInfo.Adapt()); + var fileName = GetUrl(fileInfo.Adapt()); if (File.Exists(fileName)) File.Delete(fileName); @@ -172,12 +170,22 @@ namespace AsbCloudInfrastructure.Services return await db.SaveChangesAsync(token).ConfigureAwait(false); } - public string GetFileName(FileInfoDto fileInfo) + public string GetUrl(FileInfoDto fileInfo) => + GetUrl(fileInfo.IdWell, fileInfo.IdCategory, fileInfo.Id, Path.GetExtension(fileInfo.Name)); + + public string GetUrl(int idFile) { - var fileName = $"{fileInfo.Id}{Path.GetExtension(fileInfo.Name)}"; - fileName = Path.Combine(RootPath, fileInfo.IdWell.ToString(), fileInfo.IdCategory.ToString(), fileName); - fileName = Path.GetFullPath(fileName); - return fileName; + var fileInfo = db.Files + .FirstOrDefault(f => f.Id == idFile); + + if (fileInfo is null) + return null; + + return GetUrl(fileInfo.IdWell, fileInfo.IdCategory, fileInfo.Id, Path.GetExtension(fileInfo.Name)); } + + public string GetUrl(int idWell, int idCategory, int idFile, string dotExtention) => + Path.Combine(RootPath, idWell.ToString(), idCategory.ToString(), $"{idFile}{dotExtention}"); + } } diff --git a/AsbCloudInfrastructure/Services/TelemetryDataService.cs b/AsbCloudInfrastructure/Services/TelemetryDataBaseService.cs similarity index 96% rename from AsbCloudInfrastructure/Services/TelemetryDataService.cs rename to AsbCloudInfrastructure/Services/TelemetryDataBaseService.cs index 568fd352..d818e37d 100644 --- a/AsbCloudInfrastructure/Services/TelemetryDataService.cs +++ b/AsbCloudInfrastructure/Services/TelemetryDataBaseService.cs @@ -12,7 +12,7 @@ using System.Threading.Tasks; namespace AsbCloudInfrastructure.Services { - public abstract class TelemetryDataService : ITelemetryDataService, IConverter + public abstract class TelemetryDataBaseService : ITelemetryDataService, IConverter where TDto : AsbCloudApp.Data.ITelemetryData where TModel : class, AsbCloudDb.Model.ITelemetryData { @@ -23,7 +23,7 @@ namespace AsbCloudInfrastructure.Services protected readonly CacheTable cacheTelemetryUsers; protected readonly CacheTable cacheWells; - public TelemetryDataService( + public TelemetryDataBaseService( IAsbCloudDbContext db, ITelemetryService telemetryService, CacheDb cacheDb) diff --git a/AsbCloudInfrastructure/Services/TelemetryDataSaubService.cs b/AsbCloudInfrastructure/Services/TelemetryDataSaubService.cs index f29fae45..c2b1248f 100644 --- a/AsbCloudInfrastructure/Services/TelemetryDataSaubService.cs +++ b/AsbCloudInfrastructure/Services/TelemetryDataSaubService.cs @@ -6,7 +6,7 @@ using Mapster; namespace AsbCloudInfrastructure.Services { - public class TelemetryDataSaubService: TelemetryDataService + public class TelemetryDataSaubService: TelemetryDataBaseService { public TelemetryDataSaubService( IAsbCloudDbContext db, @@ -18,18 +18,18 @@ namespace AsbCloudInfrastructure.Services public override TelemetryDataSaub Convert(TelemetryDataSaubDto src) { var entity = src.Adapt(); - var telemetryUser = cacheTelemetryUsers + var telemetryUser = cacheTelemetryUsers? .FirstOrDefault(u => u.IdTelemetry == src.IdTelemetry && (u.Name == src.User || u.Surname == src.User)); - entity.IdUser = telemetryUser.IdUser; + entity.IdUser = telemetryUser?.IdUser; return entity; } public override TelemetryDataSaubDto Convert(TelemetryDataSaub src) { var dto = src.Adapt(); - var telemetryUser = cacheTelemetryUsers + var telemetryUser = cacheTelemetryUsers? .FirstOrDefault(u => u.IdTelemetry == src.IdTelemetry && u.IdUser == src.IdUser); - dto.User = telemetryUser.MakeDisplayName(); + dto.User = telemetryUser?.MakeDisplayName(); return dto; } } diff --git a/AsbCloudInfrastructure/Services/TelemetryDataSpinService.cs b/AsbCloudInfrastructure/Services/TelemetryDataSpinService.cs index ebbe306a..a753da67 100644 --- a/AsbCloudInfrastructure/Services/TelemetryDataSpinService.cs +++ b/AsbCloudInfrastructure/Services/TelemetryDataSpinService.cs @@ -6,7 +6,7 @@ using Mapster; namespace AsbCloudInfrastructure.Services { - public class TelemetryDataSpinService : TelemetryDataService + public class TelemetryDataSpinService : TelemetryDataBaseService { public TelemetryDataSpinService( IAsbCloudDbContext db, diff --git a/AsbCloudInfrastructure/Services/TelemetryService.cs b/AsbCloudInfrastructure/Services/TelemetryService.cs index 5e14c310..93c85cb3 100644 --- a/AsbCloudInfrastructure/Services/TelemetryService.cs +++ b/AsbCloudInfrastructure/Services/TelemetryService.cs @@ -52,7 +52,7 @@ namespace AsbCloudInfrastructure.Services } private Telemetry GetOrCreateTelemetryByUid(string uid) - => cacheTelemetry.FirstOrDefault(t => t.RemoteUid == uid, RefreshMode.IfResultEmpty) + => cacheTelemetry.FirstOrDefault(t => t.RemoteUid == uid) ?? cacheTelemetry.Insert(new Telemetry { RemoteUid = uid, }); } diff --git a/AsbCloudWebApi/Controllers/DrillingProgramController.cs b/AsbCloudWebApi/Controllers/DrillingProgramController.cs index 42497429..7fbb9f35 100644 --- a/AsbCloudWebApi/Controllers/DrillingProgramController.cs +++ b/AsbCloudWebApi/Controllers/DrillingProgramController.cs @@ -29,7 +29,7 @@ namespace AsbCloudWebApi.Controllers .ConfigureAwait(false); if (fileInfo is null) return NoContent(); - var relativePath = fileService.GetFileName(fileInfo); + var relativePath = fileService.GetUrl(fileInfo); return PhysicalFile(Path.GetFullPath(relativePath), "application/octet-stream", fileInfo.Name); } } diff --git a/AsbCloudWebApi/Controllers/FileController.cs b/AsbCloudWebApi/Controllers/FileController.cs index 42058db1..28cf1d3b 100644 --- a/AsbCloudWebApi/Controllers/FileController.cs +++ b/AsbCloudWebApi/Controllers/FileController.cs @@ -157,8 +157,7 @@ namespace AsbCloudWebApi.Controllers if (fileInfo is null) throw new FileNotFoundException(); - // TODO: словарь content typoв - var relativePath = fileService.GetFileName(fileInfo); + var relativePath = fileService.GetUrl(fileInfo); return PhysicalFile(Path.GetFullPath(relativePath), "application/octet-stream", fileInfo.Name); } catch (FileNotFoundException ex)