графики и фикс сохранения файлов

This commit is contained in:
russell 2024-05-30 00:22:40 +04:00
parent c0af868126
commit 18c56ffab0
12 changed files with 225 additions and 45 deletions

View File

@ -117,7 +117,7 @@ namespace TravelAgencyBusinessLogic.BusinessLogics
{
_saveToWord.CreateDoc(new WordInfo
{
FileName = model.FileName,
FileStream = model.FileStream,
Title = "Список мест для посещения по выбранным турам.",
TourPlaces = GetTourPlaces(model)
});
@ -127,7 +127,7 @@ namespace TravelAgencyBusinessLogic.BusinessLogics
{
_saveToExcel.CreateReport(new ExcelInfo
{
FileName = model.FileName,
FileStream = model.FileStream,
Title = "Список мест",
TourPlaces = GetTourPlaces(model)
});

View File

@ -4,7 +4,7 @@ namespace TravelAgencyBusinessLogic.OfficePackage.HelperModels
{
public class ExcelInfo
{
public string FileName { get; set; } = string.Empty;
public Stream FileStream { get; set; } = new MemoryStream();
public string Title { get; set; } = string.Empty;

View File

@ -4,7 +4,7 @@ namespace TravelAgencyBusinessLogic.OfficePackage.HelperModels
{
public class WordInfo
{
public string FileName { get; set; } = string.Empty;
public Stream FileStream { get; set; } = new MemoryStream();
public string Title { get; set; } = string.Empty;

View File

@ -152,7 +152,7 @@ namespace TravelAgencyBusinessLogic.OfficePackage.Implements
protected override void CreateExcel(ExcelInfo info)
{
_spreadsheetDocument = SpreadsheetDocument.Create(info.FileName, SpreadsheetDocumentType.Workbook);
_spreadsheetDocument = SpreadsheetDocument.Create(info.FileStream, SpreadsheetDocumentType.Workbook);
// Создаем книгу (в ней хранятся листы)
var workbookpart = _spreadsheetDocument.AddWorkbookPart();
workbookpart.Workbook = new Workbook();

View File

@ -83,7 +83,7 @@ namespace TravelAgencyBusinessLogic.OfficePackage.Implements
protected override void CreateWord(WordInfo info)
{
_wordDocument = WordprocessingDocument.Create(info.FileName, WordprocessingDocumentType.Document);
_wordDocument = WordprocessingDocument.Create(info.FileStream, WordprocessingDocumentType.Document);
MainDocumentPart mainPart = _wordDocument.AddMainDocumentPart();
mainPart.Document = new Document();
_docBody = mainPart.Document.AppendChild(new Body());

View File

@ -2,7 +2,7 @@
{
public class ReportBindingModel
{
public string FileName { get; set; } = string.Empty;
public Stream FileStream { get; set; } = new MemoryStream();
public DateTime? DateFrom { get; set; }

View File

@ -44,6 +44,12 @@ namespace TravelAgencyDatabaseImplement.Implements
.FirstOrDefault(x => x.Email.Equals(model.Email) && x.Password.Equals(model.Password))
?.GetViewModel;
}
if (!string.IsNullOrEmpty(model.Email) && !string.IsNullOrEmpty(model.PhoneNumber))
{
return context.Users
.FirstOrDefault(x => x.Email.Equals(model.Email) || x.PhoneNumber.Equals(model.PhoneNumber))
?.GetViewModel;
}
if (!string.IsNullOrEmpty(model.Email))
{
return context.Users

View File

@ -26,17 +26,20 @@ namespace TravelAgencyWebApp.Controllers
private readonly IGuideLogic _guideLogic;
private readonly IExcursionGroupLogic _excursionGroupLogic;
private readonly AbstractSaveToPdf _pdfLogic;
private readonly AbstractMailWorker _mailLogic;
public HomeController(ILogger<HomeController> logger, IUserLogic userLogic, IReportLogic reportLogic, ITourLogic tourLogic, IGuideLogic guideLogic, AbstractSaveToPdf pdfLogic, AbstractMailWorker mailLogic)
public HomeController(ILogger<HomeController> logger, IUserLogic userLogic, IReportLogic reportLogic, ITourLogic tourLogic, IGuideLogic guideLogic, IExcursionGroupLogic excursionGroupLogic, AbstractSaveToPdf pdfLogic, AbstractMailWorker mailLogic)
{
_logger = logger;
_userLogic = userLogic;
_reportLogic = reportLogic;
_tourLogic = tourLogic;
_guideLogic = guideLogic;
_excursionGroupLogic = excursionGroupLogic;
_pdfLogic = pdfLogic;
_mailLogic = mailLogic;
}
@ -246,20 +249,31 @@ namespace TravelAgencyWebApp.Controllers
if (type.Equals("docx"))
{
_reportLogic.SaveTourPlacesToWordFile(new ReportBindingModel
using (var stream = new MemoryStream())
{
FileName = $@"C:\Users\User\Downloads\Список мест по турам{DateTime.Now.ToString("dd-MM-yyyy HH-mm-ss")}.docx",
UserId = LoggedinUser.User.Id,
Tours = tours
});
_reportLogic.SaveTourPlacesToWordFile(new ReportBindingModel
{
FileStream = stream,
UserId = LoggedinUser.User.Id,
Tours = tours
});
stream.Seek(0, SeekOrigin.Begin);
return File(stream.ToArray(), "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "wordfile.docx");
}
} else if (type.Equals("xlsx"))
{
_reportLogic.SaveTourPlacesToExcelFile(new ReportBindingModel
using (var stream = new MemoryStream())
{
FileName = $@"C:\Users\User\Downloads\Список мест по турам{DateTime.Now.ToString("dd-MM-yyyy HH-mm-ss")}.xlsx",
UserId = LoggedinUser.User.Id,
Tours = tours
});
_reportLogic.SaveTourPlacesToExcelFile(new ReportBindingModel
{
FileStream = stream,
UserId = LoggedinUser.User.Id,
Tours = tours
});
stream.Seek(0, SeekOrigin.Begin);
return File(stream.ToArray(), "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "excelfile.xlsx");
}
}
ViewBag.Tours = _tourLogic.ReadList(new TourSearchModel
@ -313,5 +327,69 @@ namespace TravelAgencyWebApp.Controllers
byte[] report = stream.GetBuffer();
_mailLogic.MailSendAsync(new() { MailAddress = LoggedinUser.User.Email, Subject = "Отчет", FileName = "PdfReport.pdf", Pdf = report });
}
[HttpGet]
public IActionResult Diagrams()
{
if (LoggedinUser.User == null)
{
throw new Exception("Необходимо авторизоваться!");
}
ViewBag.RevenuePerMonth = Newtonsoft.Json.JsonConvert.SerializeObject(getRevenues());
ViewBag.TourPopularity = Newtonsoft.Json.JsonConvert.SerializeObject(getTourPopularity());
return View();
}
private Dictionary<int, double> getRevenues()
{
var tours = _tourLogic.ReadList(new TourSearchModel { UserId = LoggedinUser.User.Id, DateFrom = new DateTime(DateTime.Today.Year, 1, 1), DateTo = DateTime.Today });
var excursionGroups = _excursionGroupLogic.ReadList(new ExcursionGroupSearchModel { UserId = LoggedinUser.User.Id });
var revenuePerMonth = new Dictionary<int, double>();
foreach (var tour in tours)
{
var month = tour.TourDate.Month;
if (!revenuePerMonth.ContainsKey(month))
{
revenuePerMonth[month] = 0;
}
foreach (var eg in excursionGroups)
{
if (eg.ExcursionGroupTours.ContainsKey(tour.Id))
{
revenuePerMonth[month] += tour.Price * eg.ParticipantsAmount;
}
}
}
return revenuePerMonth;
}
private Dictionary<string, int> getTourPopularity()
{
var tours = _tourLogic.ReadList(new TourSearchModel { UserId = LoggedinUser.User.Id });
var excursionGroups = _excursionGroupLogic.ReadList(new ExcursionGroupSearchModel { UserId = LoggedinUser.User.Id });
var participantsPerTour = new Dictionary<string, int>();
foreach (var tour in tours)
{
if (!participantsPerTour.ContainsKey(tour.TourName))
{
participantsPerTour[tour.TourName] = 0;
}
foreach (var eg in excursionGroups)
{
if (eg.ExcursionGroupTours.ContainsKey(tour.Id))
{
participantsPerTour[tour.TourName] += eg.ParticipantsAmount;
}
}
}
return participantsPerTour;
}
}
}

View File

@ -0,0 +1,98 @@
@{
ViewData["Title"] = "Diagrams";
var revenuePerMonthJson = ViewBag.RevenuePerMonth;
var tourPopularityJson = ViewBag.TourPopularity;
}
<div class="text-center">
<h2 class="display-4">Диаграммы</h2>
<h2 class="display-5 text-start">Прибыль</h2>
<canvas id="revenueChart"></canvas>
<h2 class="display-5 text-start">Популярность туров</h2>
<canvas id="popularityChart"></canvas>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js@3.9.1/dist/chart.min.js"></script>
<script type="text/javascript">
document.addEventListener('DOMContentLoaded', (event) => {
// Получение данных из Razor переменной
var revenuePerMonth = @Html.Raw(revenuePerMonthJson);
// Преобразуем объект в массивы для Chart.js
var labels = Object.keys(revenuePerMonth).map(month => new Date(0, month - 1).toLocaleString('default', { month: 'long' }));
var dataPoints = Object.values(revenuePerMonth);
var ctx = document.getElementById('revenueChart').getContext('2d');
var data = {
labels: labels,
datasets: [{
label: 'Доход по месяцам',
data: dataPoints,
fill: false,
borderColor: 'blue',
pointRadius: 5,
pointHoverRadius: 10,
pointHoverBackgroundColor: 'red',
pointHoverBorderColor: 'orange'
}]
};
var options = {
title: {
display: true,
text: 'Доход по месяцам'
},
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
};
var revenueChart = new Chart(ctx, {
type: 'line',
data: data,
options: options
});
// Вторая диаграмма
var tourPopularity = @Html.Raw(tourPopularityJson);
var tourLabels = Object.keys(tourPopularity).map(tourName => `${tourName}`);
var participantsData = Object.values(tourPopularity);
var ctx2 = document.getElementById('popularityChart').getContext('2d');
var data2 = {
labels: tourLabels,
datasets: [{
label: 'Количество участников по турам',
data: participantsData,
backgroundColor: 'rgba(75, 192, 192, 0.2)',
borderColor: 'rgba(75, 192, 192, 1)',
borderWidth: 1
}]
};
var options2 = {
title: {
display: true,
text: 'Количество участников по турам'
},
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
};
var popularityChart = new Chart(ctx2, {
type: 'bar',
data: data2,
options: options2
});
});
</script>

View File

@ -6,16 +6,15 @@
<h2 class="display-4">Вход в приложение</h2>
</div>
<form method="post">
<div class="row">
<div class="col-4">Логин:</div>
<div class="col-8"><input type="text" name="email" /></div>
<div class="row d-flex justify-content-center">
<div class="col-2">Логин:</div>
<div class="col-4"><input type="text" name="email" /></div>
</div>
<div class="row">
<div class="col-4">Пароль:</div>
<div class="col-8"><input type="password" name="password" /></div>
<div class="row d-flex justify-content-center">
<div class="col-2">Пароль:</div>
<div class="col-4"><input type="password" name="password" /></div>
</div>
<div class="row">
<div class="col-8"></div>
<div class="col-4"><input type="submit" value="Вход" class="btn btn-primary" /></div>
<div class="row d-flex justify-content-center p-3">
<input type="submit" value="Вход" class="btn btn-primary col-2" />
</div>
</form>

View File

@ -6,24 +6,23 @@
<h2 class="display-4">Регистрация</h2>
</div>
<form method="post">
<div class="row">
<div class="col-4">Логин:</div>
<div class="col-8"><input type="text" name="email" /></div>
<div class="row d-flex justify-content-center">
<div class="col-2">Логин:</div>
<div class="col-4"><input type="text" name="email" /></div>
</div>
<div class="row">
<div class="col-4">Пароль:</div>
<div class="col-8"><input type="password" name="password" /></div>
<div class="row d-flex justify-content-center">
<div class="col-2">Пароль:</div>
<div class="col-4"><input type="password" name="password" /></div>
</div>
<div class="row">
<div class="col-4">Номер телефона:</div>
<div class="col-8"><input type="text" name="phone" /></div>
<div class="row d-flex justify-content-center">
<div class="col-2">Номер телефона:</div>
<div class="col-4"><input type="text" name="phone" /></div>
</div>
<div class="row">
<div class="col-4">ФИО:</div>
<div class="col-8"><input type="text" name="fio" /></div>
<div class="row d-flex justify-content-center">
<div class="col-2">ФИО:</div>
<div class="col-4"><input type="text" name="fio" /></div>
</div>
<div class="row">
<div class="col-8"></div>
<div class="col-4"><input type="submit" value="Регистрация" class="btn btn-primary" /></div>
<div class="row d-flex justify-content-center p-3">
<input type="submit" value="Регистрация" class="btn btn-primary col-2" />
</div>
</form>

View File

@ -21,9 +21,6 @@
</button>
<div class="navbar-collapse collapse d-sm-inline-flex flex-smrow-reverse">
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link text-dark" asparea="" asp-controller="Home" asp-action="Privacy">Личные данные</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asparea="" asp-controller="Home" asp-action="Enter">Вход</a>
</li>
@ -48,6 +45,9 @@
<li class="nav-item">
<a class="nav-link text-dark" asparea="" asp-controller="Home" asp-action="ReportMenu">Отчеты</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asparea="" asp-controller="Home" asp-action="Diagrams">Диаграммы</a>
</li>
</ul>
</div>
</div>