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

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

View File

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

View File

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

View File

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

View File

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

View File

@ -2,7 +2,7 @@
{ {
public class ReportBindingModel public class ReportBindingModel
{ {
public string FileName { get; set; } = string.Empty; public Stream FileStream { get; set; } = new MemoryStream();
public DateTime? DateFrom { get; set; } 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)) .FirstOrDefault(x => x.Email.Equals(model.Email) && x.Password.Equals(model.Password))
?.GetViewModel; ?.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)) if (!string.IsNullOrEmpty(model.Email))
{ {
return context.Users return context.Users

View File

@ -26,17 +26,20 @@ namespace TravelAgencyWebApp.Controllers
private readonly IGuideLogic _guideLogic; private readonly IGuideLogic _guideLogic;
private readonly IExcursionGroupLogic _excursionGroupLogic;
private readonly AbstractSaveToPdf _pdfLogic; private readonly AbstractSaveToPdf _pdfLogic;
private readonly AbstractMailWorker _mailLogic; 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; _logger = logger;
_userLogic = userLogic; _userLogic = userLogic;
_reportLogic = reportLogic; _reportLogic = reportLogic;
_tourLogic = tourLogic; _tourLogic = tourLogic;
_guideLogic = guideLogic; _guideLogic = guideLogic;
_excursionGroupLogic = excursionGroupLogic;
_pdfLogic = pdfLogic; _pdfLogic = pdfLogic;
_mailLogic = mailLogic; _mailLogic = mailLogic;
} }
@ -245,21 +248,32 @@ namespace TravelAgencyWebApp.Controllers
} }
if (type.Equals("docx")) if (type.Equals("docx"))
{
using (var stream = new MemoryStream())
{ {
_reportLogic.SaveTourPlacesToWordFile(new ReportBindingModel _reportLogic.SaveTourPlacesToWordFile(new ReportBindingModel
{ {
FileName = $@"C:\Users\User\Downloads\Список мест по турам{DateTime.Now.ToString("dd-MM-yyyy HH-mm-ss")}.docx", FileStream = stream,
UserId = LoggedinUser.User.Id, UserId = LoggedinUser.User.Id,
Tours = tours Tours = tours
}); });
stream.Seek(0, SeekOrigin.Begin);
return File(stream.ToArray(), "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "wordfile.docx");
}
} else if (type.Equals("xlsx")) } else if (type.Equals("xlsx"))
{
using (var stream = new MemoryStream())
{ {
_reportLogic.SaveTourPlacesToExcelFile(new ReportBindingModel _reportLogic.SaveTourPlacesToExcelFile(new ReportBindingModel
{ {
FileName = $@"C:\Users\User\Downloads\Список мест по турам{DateTime.Now.ToString("dd-MM-yyyy HH-mm-ss")}.xlsx", FileStream = stream,
UserId = LoggedinUser.User.Id, UserId = LoggedinUser.User.Id,
Tours = tours 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 ViewBag.Tours = _tourLogic.ReadList(new TourSearchModel
@ -313,5 +327,69 @@ namespace TravelAgencyWebApp.Controllers
byte[] report = stream.GetBuffer(); byte[] report = stream.GetBuffer();
_mailLogic.MailSendAsync(new() { MailAddress = LoggedinUser.User.Email, Subject = "Отчет", FileName = "PdfReport.pdf", Pdf = report }); _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> <h2 class="display-4">Вход в приложение</h2>
</div> </div>
<form method="post"> <form method="post">
<div class="row"> <div class="row d-flex justify-content-center">
<div class="col-4">Логин:</div> <div class="col-2">Логин:</div>
<div class="col-8"><input type="text" name="email" /></div> <div class="col-4"><input type="text" name="email" /></div>
</div> </div>
<div class="row"> <div class="row d-flex justify-content-center">
<div class="col-4">Пароль:</div> <div class="col-2">Пароль:</div>
<div class="col-8"><input type="password" name="password" /></div> <div class="col-4"><input type="password" name="password" /></div>
</div> </div>
<div class="row"> <div class="row d-flex justify-content-center p-3">
<div class="col-8"></div> <input type="submit" value="Вход" class="btn btn-primary col-2" />
<div class="col-4"><input type="submit" value="Вход" class="btn btn-primary" /></div>
</div> </div>
</form> </form>

View File

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

View File

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