From c529bcf1b93a753a86cf610580793072848e4a38 Mon Sep 17 00:00:00 2001 From: prodigygirl <Prodigygirl1.0@yandex.ru> Date: Thu, 18 May 2023 18:23:17 +0400 Subject: [PATCH] =?UTF-8?q?=D0=AD=D1=82=D0=B0=D0=BF=202.=20=D0=9F=D0=BE?= =?UTF-8?q?=D0=BB=D1=83=D1=87=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BE=D1=82=D1=87?= =?UTF-8?q?=D0=B5=D1=82=D0=BE=D0=B2=20=D0=BD=D0=B0=20=D1=84=D0=BE=D1=80?= =?UTF-8?q?=D0=BC=D1=83=20=D0=B8=D0=BB=D0=B8=20=D0=BD=D0=B0=20=D1=81=D0=BA?= =?UTF-8?q?=D0=B0=D1=87=D0=B8=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/ReportController.cs | 87 +++++++++++++++++++ Hospital/HospitalRestApi/Program.cs | 7 +- Hospital/HospitalWeb/APIClient.cs | 19 ++++ .../Controllers/RecipeController.cs | 2 - .../Controllers/ReportController.cs | 62 +++++++++++++ Hospital/HospitalWeb/HelpModels/FileFormat.cs | 8 ++ .../Views/Report/ReportPatients.cshtml | 34 ++++++++ .../Views/Report/ReportPrescriptions.cshtml | 51 +++++++++++ .../HospitalWeb/Views/Shared/_Layout.cshtml | 9 ++ 9 files changed, 275 insertions(+), 4 deletions(-) create mode 100644 Hospital/HospitalRestApi/Controllers/ReportController.cs create mode 100644 Hospital/HospitalWeb/Controllers/ReportController.cs create mode 100644 Hospital/HospitalWeb/HelpModels/FileFormat.cs create mode 100644 Hospital/HospitalWeb/Views/Report/ReportPatients.cshtml create mode 100644 Hospital/HospitalWeb/Views/Report/ReportPrescriptions.cshtml diff --git a/Hospital/HospitalRestApi/Controllers/ReportController.cs b/Hospital/HospitalRestApi/Controllers/ReportController.cs new file mode 100644 index 0000000..0cdeb79 --- /dev/null +++ b/Hospital/HospitalRestApi/Controllers/ReportController.cs @@ -0,0 +1,87 @@ +using HospitalContracts.BindingModels; +using HospitalContracts.BusinessLogicContracts; +using HospitalContracts.ViewModels; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using System.IO; + +namespace HospitalRestApi.Controllers +{ + [Route("api/[controller]/[action]")] + [ApiController] + [ApiExplorerSettings(IgnoreApi = true)] + public class ReportController : ControllerBase + { + private readonly ILogger _logger; + private readonly IReportLogic _logic; + + public ReportController(ILogger<ReportController> logger, IReportLogic logic) + { + _logger = logger; + _logic = logic; + } + + [HttpPost] + public ActionResult GetReportPatientsToExcelFile(ReportBindingModel model) + { + try + { + var stream = _logic.SavePatientsToExcelFile(model); + return File(stream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", model.FileName); + + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка получения списка пациентов"); + throw; + } + } + + [HttpPost] + public ActionResult GetReportPatientsToWordFile(ReportBindingModel model) + { + try + { + var stream = _logic.SavePatientsToWordFile(model); + return File(stream, "application/vnd.openxmlformats-officedocument.wordprocessingml.document", model.FileName); + + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка получения списка пациентов"); + throw; + } + } + + [HttpGet] + public List<ReportPrescriptionProcedureViewModel> GetReportPrescriptions(DateTime startDate, DateTime endDate) + { + try + { + return _logic.GetPrescriptionProcedures(new ReportBindingModel { DateFrom = startDate, DateTo = endDate}); + + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка получения списка пациентов"); + throw; + } + } + [HttpPost] + public ActionResult GetReportPrescriptionsPdf(DateTime startDate, DateTime endDate, ReportBindingModel model) + { + try + { + var stream = _logic.SavePrescriptionsToPdfFile(model); + return File(stream, "application/pdf", "pdf.pdf"); + + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка получения списка пациентов"); + throw; + } + } + + } +} diff --git a/Hospital/HospitalRestApi/Program.cs b/Hospital/HospitalRestApi/Program.cs index 6d976d8..274fc68 100644 --- a/Hospital/HospitalRestApi/Program.cs +++ b/Hospital/HospitalRestApi/Program.cs @@ -1,4 +1,6 @@ using HospitalBusinessLogic; +using HospitalBusinessLogic.OfficePackage; +using HospitalBusinessLogic.OfficePackage.Implements; using HospitalContracts.BusinessLogicContracts; using HospitalContracts.StorageContracts; using HospitalDatabaseImplement.Implements; @@ -26,8 +28,9 @@ builder.Services.AddTransient<ITreatmentLogic, TreatmentLogic>(); builder.Services.AddTransient<IReportLogic, ReportLogic>(); -//builder.Services.AddTransient<AbstractSaveToWord, SaveToWord>(); -//builder.Services.AddTransient<AbstractSaveToExcel, SaveToExcel>(); +builder.Services.AddTransient<AbstractSaveToWord, SaveToWord>(); +builder.Services.AddTransient<AbstractSaveToExcel, SaveToExcel>(); +builder.Services.AddTransient<AbstractSaveToPdf, SaveToPdf>(); //builder.Services.AddSingleton<AbstractMailWorker, MailKitWorker>(); builder.Services.AddControllers().AddJsonOptions((option) => diff --git a/Hospital/HospitalWeb/APIClient.cs b/Hospital/HospitalWeb/APIClient.cs index c19ace9..43bc143 100644 --- a/Hospital/HospitalWeb/APIClient.cs +++ b/Hospital/HospitalWeb/APIClient.cs @@ -41,5 +41,24 @@ namespace HospitalWeb throw new Exception(result); } } + + public static (Stream stream, string? contentType)? GetFileRequest<T>(string requestUrl, T model) + { + var json = JsonConvert.SerializeObject(model); + var data = new StringContent(json, Encoding.UTF8, "application/json"); + var response = _client.PostAsync(requestUrl, data); + + var result = response.Result.Content.ReadAsStreamAsync().Result; + response.Result.Content.Headers.TryGetValues("content-type", out var type); + if (response.Result.IsSuccessStatusCode) + { + return (stream: result, contentType: type?.First()); + } + + else + { + throw new Exception($"Failed to retrieve file from {requestUrl}. StatusCode: {response.Result.StatusCode}"); + } + } } } diff --git a/Hospital/HospitalWeb/Controllers/RecipeController.cs b/Hospital/HospitalWeb/Controllers/RecipeController.cs index 1d4624b..30bd07c 100644 --- a/Hospital/HospitalWeb/Controllers/RecipeController.cs +++ b/Hospital/HospitalWeb/Controllers/RecipeController.cs @@ -51,8 +51,6 @@ namespace HospitalWeb.Controllers model.ApothecaryId = APIClient.Apothecary.Id; if (model.Id != 0) { - // тут надо вытащить ключи, потом по ним сделать массовый запрос сущностей лекарств, а потом вставить как значения в словарь - //model.RecipeMedicines = APIClient.PostRequest("api/recipe/update", model); } else diff --git a/Hospital/HospitalWeb/Controllers/ReportController.cs b/Hospital/HospitalWeb/Controllers/ReportController.cs new file mode 100644 index 0000000..37e6186 --- /dev/null +++ b/Hospital/HospitalWeb/Controllers/ReportController.cs @@ -0,0 +1,62 @@ +using HospitalContracts.BindingModels; +using HospitalContracts.ViewModels; +using HospitalWeb.HelpModels; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using System; +using System.Net; + +namespace HospitalWeb.Controllers +{ + public class ReportController : Controller + { + + [HttpGet("/reports/patients")] + public IActionResult ReportPatients() + { + ViewBag.Medicines = APIClient.GetRequest<List<MedicineViewModel>>($"api/medicine/getmedicines"); + return View(); + } + + [HttpGet("/reports/precriptions")] + public IActionResult ReportPrescriptions(List<ReportPrescriptionProcedureViewModel>? report) + { + return View(report); + } + + [HttpGet("/report/getprescriptions")] + public IActionResult GetPrescriptions(DateTime startDate, DateTime endDate, string type) + { + /* // если type - получение отчета на форме + // Преобразуем даты к нужному формату + string startDateString = startDate.ToString("yyyy-MM-dd HH:mm:ss.fffffff"); + string endDateString = endDate.ToString("yyyy-MM-dd HH:mm:ss.fffffff"); + var report = APIClient.GetRequest<List<ReportPrescriptionProcedureViewModel>>($"api/report/getreportprescriptions?startDate={startDateString}&endDate={endDateString}"); + return View("ReportPrescriptions", report);*/ + // иначе отправка на почту + string startDateString = startDate.ToString("yyyy-MM-dd HH:mm:ss.fffffff"); + string endDateString = endDate.ToString("yyyy-MM-dd HH:mm:ss.fffffff"); + var fileData = APIClient.GetFileRequest($"api/report/getreportprescriptionspdf?", new ReportBindingModel { DateFrom = startDate, DateTo = endDate }); + if (fileData != null) + return File(fileData.Value.stream, fileData.Value.contentType!, "prescriptions.pdf"); + throw new Exception($"Failed to retrieve file from."); + } + + [HttpGet("/reports/download")] + public IActionResult DownloadReport(ReportBindingModel model, string Format) + { + var format = Enum.Parse<FileFormat>(Format); + var (endpoint, extension) = format switch + { + FileFormat.Word => ("api/report/getreportpatientstowordfile/", ".docx"), + FileFormat.Excel => ("api/report/getreportpatientstoexcelfile/", ".xlsx"), + _ => throw new ArgumentException($"Invalid file format: {format}", nameof(Format)) + }; + model.FileName += extension; + var fileData = APIClient.GetFileRequest(endpoint, model); + if (fileData != null) + return File(fileData.Value.stream, fileData.Value.contentType!, model.FileName); + throw new Exception($"Failed to retrieve file from {endpoint}."); + } + } +} diff --git a/Hospital/HospitalWeb/HelpModels/FileFormat.cs b/Hospital/HospitalWeb/HelpModels/FileFormat.cs new file mode 100644 index 0000000..bdce4b0 --- /dev/null +++ b/Hospital/HospitalWeb/HelpModels/FileFormat.cs @@ -0,0 +1,8 @@ +namespace HospitalWeb.HelpModels +{ + public enum FileFormat + { + Word = 0, + Excel = 1 + } +} diff --git a/Hospital/HospitalWeb/Views/Report/ReportPatients.cshtml b/Hospital/HospitalWeb/Views/Report/ReportPatients.cshtml new file mode 100644 index 0000000..ffb4fc2 --- /dev/null +++ b/Hospital/HospitalWeb/Views/Report/ReportPatients.cshtml @@ -0,0 +1,34 @@ +@using HospitalContracts.ViewModels; +@using System.Globalization +@model MedicineViewModel +@{ + ViewData["Title"] = "Отчет Пациенты"; +} + +<div class="text-center"> + <h2 class="display-4">@ViewData["Title"]</h2> +</div> +<form id="reportForm" method="get" action="/reports/download"> + <div class="row"> + <div class="col-4">Выбор лекарств</div> + <div class="col-8"> + <select id="medicines" name="Medicines" class="form-control" multiple asp-items="@(new SelectList(@ViewBag.Medicines,"Id", "Name"))"></select> + <small>Для выбора нескольких элементов удерживайте клавишу Ctrl.</small> + </div> + </div> + <div class="row"> + <div class="col-4">Название файла (без формата):</div> + <div class="col-8"><input type="text" name="FileName" required /></div> + </div> + <div class="row"> + <div class="col-4">Формат файла:</div> + <div class="col-8"> + <select name="Format" required> + <option value="Word">Word</option> + <option value="Excel">Excel</option> + </select> + </div> + </div> + <button id="submitReport">Получить отчет</button> +</form> + diff --git a/Hospital/HospitalWeb/Views/Report/ReportPrescriptions.cshtml b/Hospital/HospitalWeb/Views/Report/ReportPrescriptions.cshtml new file mode 100644 index 0000000..b8ff787 --- /dev/null +++ b/Hospital/HospitalWeb/Views/Report/ReportPrescriptions.cshtml @@ -0,0 +1,51 @@ +@using HospitalContracts.ViewModels; +@model List<ReportPrescriptionProcedureViewModel> + +@{ + ViewData["Title"] = "Отчет Поступления"; +} + +<div class="text-center"> + <h2 class="display-4">@ViewData["Title"]</h2> +</div> + +<form method="get" class="form-inline" action="/report/getprescriptions"> + <div class="form-group mx-sm-3 mb-2"> + <label for="startDate" class="sr-only">Начальная дата:</label> + <input type="date" class="form-control" id="startDate" name="startDate" required /> + </div> + <div class="form-group mx-sm-3 mb-2"> + <label for="endDate" class="sr-only">Конечная дата:</label> + <input type="date" class="form-control" id="endDate" name="endDate" required /> + </div> + <div class="form-group mx-sm-3 mb-2"> + <button type="submit" class="btn btn-primary" name="type" value="getReport">Получить отчет</button> + </div> + <div class="form-group mx-sm-3 mb-2"> + <button type="submit" class="btn btn-secondary" name="type" value="sendPdf">Отправить pdf на почту</button> + </div> +</form> +@if (Model != null && Model.Any()) +{ + <table class="table"> + <thead> + <tr> + <th>Дата поступления</th> + <th>Лекарство</th> + <th>Количество</th> + <th>Название процедуры</th> + </tr> + </thead> + <tbody> + @foreach (var report in Model) + { + <tr> + <td>@report.DateCreate.ToShortDateString()</td> + <td>@report.MedicineName</td> + <td>@report.Number</td> + <td>@report.ProcedureName</td> + </tr> + } + </tbody> + </table> +} \ No newline at end of file diff --git a/Hospital/HospitalWeb/Views/Shared/_Layout.cshtml b/Hospital/HospitalWeb/Views/Shared/_Layout.cshtml index 01d7c15..e4da1da 100644 --- a/Hospital/HospitalWeb/Views/Shared/_Layout.cshtml +++ b/Hospital/HospitalWeb/Views/Shared/_Layout.cshtml @@ -28,6 +28,15 @@ <li class="nav-item"> <a class="nav-link text-dark" asp-area="" asp-controller="Recipe" asp-action="Recipes">Рецепты</a> </li> + <li class="nav-item dropdown"> + <a class="nav-link text-dark dropdown-toggle" href="#" id="reportDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false"> + Отчеты + </a> + <div class="dropdown-menu" aria-labelledby="reportDropdown"> + <a class="dropdown-item" asp-area="" asp-controller="Report" asp-action="ReportPatients">Отчет Пациенты</a> + <a class="dropdown-item" asp-area="" asp-controller="Report" asp-action="ReportPrescriptions">Отчет Поступления</a> + </div> + </li> <li class="nav-item"> <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Профиль</a> </li>