237 lines
7.3 KiB
C#
237 lines
7.3 KiB
C#
![]() |
using System;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.Linq;
|
|||
|
using Avalonia;
|
|||
|
using Avalonia.Controls;
|
|||
|
using Avalonia.Interactivity;
|
|||
|
using Avalonia.Markup.Xaml;
|
|||
|
using dmeo040225.Models;
|
|||
|
using dmeo040225.Services;
|
|||
|
using OxyPlot;
|
|||
|
using OxyPlot.Avalonia;
|
|||
|
using OxyPlot.Series;
|
|||
|
using OxyPlot.Axes;
|
|||
|
using PdfSharpCore.Drawing;
|
|||
|
using PdfSharpCore.Pdf;
|
|||
|
using LineSeries = OxyPlot.Series.LineSeries;
|
|||
|
|
|||
|
namespace dmeo040225;
|
|||
|
|
|||
|
public class ServicePerDay
|
|||
|
{
|
|||
|
public DateTime Date { get; set; }
|
|||
|
public int CountServices {get; set; }
|
|||
|
}
|
|||
|
|
|||
|
public class ServiceOrdersPerDay
|
|||
|
{
|
|||
|
public DateTime Date { get; set; }
|
|||
|
public string ServiceName { get; set; }
|
|||
|
public int OrderCount { get; set; }
|
|||
|
}
|
|||
|
|
|||
|
public partial class ReportWindow : Window
|
|||
|
{
|
|||
|
public List<ServicePerDay> ServicesPerDayList { get; set; }
|
|||
|
public List<ServiceOrdersPerDay> ServicesOrdersPerDayList { get; set; }
|
|||
|
public List<ServicePerDay> OrdersPerDayList { get; set; }
|
|||
|
|
|||
|
public ReportWindow()
|
|||
|
{
|
|||
|
InitializeComponent();
|
|||
|
|
|||
|
TimerService.Instance.TimeUpdated += UpdateTimerText;
|
|||
|
TimerService.Instance.TimerExpired += LogoutUser;
|
|||
|
|
|||
|
TimerService.Instance.Start();
|
|||
|
}
|
|||
|
|
|||
|
private void GenerateReport(object? sender, RoutedEventArgs e)
|
|||
|
{
|
|||
|
if (StartPicker.SelectedDate == null || EndPicker.SelectedDate == null)
|
|||
|
{
|
|||
|
Console.WriteLine("Выберите начальную и конечную дату!");
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
DateTime startDate = StartPicker.SelectedDate.Value.DateTime;
|
|||
|
DateTime endDate = EndPicker.SelectedDate.Value.DateTime;
|
|||
|
|
|||
|
if (startDate > endDate)
|
|||
|
{
|
|||
|
Console.WriteLine("Начальная дата не может быть позже конечной!");
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
using var context = new DatabaseContext();
|
|||
|
|
|||
|
ServicesPerDayList = GetServicesPerDay(context, startDate, endDate);
|
|||
|
ServicesOrdersPerDayList = GetServiceOrdersPerDay(context, startDate, endDate);
|
|||
|
OrdersPerDayList = GetOrdersPerDay(context, startDate, endDate);
|
|||
|
|
|||
|
CreatePdfWithTableAndGraph();
|
|||
|
|
|||
|
foreach (var service in ServicesOrdersPerDayList)
|
|||
|
{
|
|||
|
Console.WriteLine($"{service.Date.ToShortDateString()} | {service.ServiceName} | {service.OrderCount}");
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private PlotModel CreateServiceGraph()
|
|||
|
{
|
|||
|
var plotModel = new PlotModel { Title = "График по сервисам" };
|
|||
|
|
|||
|
var series = new LineSeries
|
|||
|
{
|
|||
|
Title = "Количество сервисов",
|
|||
|
MarkerType = MarkerType.Circle,
|
|||
|
MarkerSize = 4,
|
|||
|
Color = OxyColors.SkyBlue
|
|||
|
};
|
|||
|
|
|||
|
foreach (var item in ServicesPerDayList)
|
|||
|
{
|
|||
|
series.Points.Add(new DataPoint(OxyPlot.Axes.DateTimeAxis.ToDouble(item.Date), item.CountServices));
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
plotModel.Series.Add(series);
|
|||
|
return plotModel;
|
|||
|
}
|
|||
|
|
|||
|
private void CreatePdfWithTableAndGraph()
|
|||
|
{
|
|||
|
// Создаем новый PDF документ
|
|||
|
PdfDocument document = new PdfDocument();
|
|||
|
document.Info.Title = "Отчет";
|
|||
|
|
|||
|
// Создаем страницу
|
|||
|
PdfPage page = document.AddPage();
|
|||
|
|
|||
|
// Создаем XGraphics для рисования
|
|||
|
XGraphics gfx = XGraphics.FromPdfPage(page);
|
|||
|
XFont font = new XFont("Arial", 12, XFontStyle.Regular);
|
|||
|
|
|||
|
// Добавление таблицы в PDF
|
|||
|
int yPos = 40;
|
|||
|
// gfx.DrawString("Список сервисов:", font, XBrushes.Black, new XPoint(40, yPos));
|
|||
|
// yPos += 20;
|
|||
|
//
|
|||
|
// foreach (var service in ServicesPerDayList)
|
|||
|
// {
|
|||
|
// gfx.DrawString($"{service.Date.ToShortDateString()} | {service.CountServices} сервисов", font, XBrushes.Black, new XPoint(40, yPos));
|
|||
|
// yPos += 20;
|
|||
|
// }
|
|||
|
|
|||
|
// Добавление графика в PDF
|
|||
|
var plotModel = CreateServiceGraph();
|
|||
|
var pngStream = new System.IO.MemoryStream();
|
|||
|
var pngExporter = new OxyPlot.ImageSharp.PngExporter(400, 300);
|
|||
|
|
|||
|
try
|
|||
|
{
|
|||
|
pngExporter.Export(plotModel, pngStream);
|
|||
|
pngStream.Seek(0, System.IO.SeekOrigin.Begin); // Убедитесь, что поток начнется с первого байта
|
|||
|
|
|||
|
var image = XImage.FromStream(() => pngStream);
|
|||
|
|
|||
|
gfx.DrawImage(image, 40, yPos);
|
|||
|
}
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
Console.WriteLine($"Ошибка при экспортировании изображения: {ex.Message}");
|
|||
|
}
|
|||
|
|
|||
|
// Сохраняем PDF
|
|||
|
string filename = "report.pdf";
|
|||
|
document.Save(filename);
|
|||
|
Console.WriteLine($"PDF сохранен в {filename}");
|
|||
|
}
|
|||
|
|
|||
|
private List<ServicePerDay> GetServicesPerDay(DatabaseContext context, DateTime startDate, DateTime endDate)
|
|||
|
{
|
|||
|
return context.Orders
|
|||
|
.Where(order => order.Orderdata.Date >= startDate && order.Orderdata.Date <= endDate)
|
|||
|
.SelectMany(order => order.OrdersServices)
|
|||
|
.GroupBy(os => os.Order.Orderdata.Date)
|
|||
|
.Select(g => new ServicePerDay
|
|||
|
{
|
|||
|
Date = g.Key,
|
|||
|
CountServices = g.Count()
|
|||
|
})
|
|||
|
.OrderBy(spd => spd.Date)
|
|||
|
.ToList();
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
private List<ServiceOrdersPerDay> GetServiceOrdersPerDay(DatabaseContext context, DateTime startDate, DateTime endDate)
|
|||
|
{
|
|||
|
return context.Orders
|
|||
|
.Where(order => order.Orderdata.Date >= startDate.Date && order.Orderdata.Date <= endDate.Date)
|
|||
|
.SelectMany(order => order.OrdersServices, (order, os) => new { order.Orderdata, os.Service })
|
|||
|
.GroupBy(o => new { o.Orderdata.Date, o.Service.Name })
|
|||
|
.Select(g => new ServiceOrdersPerDay
|
|||
|
{
|
|||
|
Date = g.Key.Date,
|
|||
|
ServiceName = g.Key.Name,
|
|||
|
OrderCount = g.Count()
|
|||
|
})
|
|||
|
.OrderBy(spd => spd.Date)
|
|||
|
.ThenBy(spd => spd.ServiceName)
|
|||
|
.ToList();
|
|||
|
}
|
|||
|
|
|||
|
private List<ServicePerDay> GetOrdersPerDay(DatabaseContext context, DateTime startDate, DateTime endDate)
|
|||
|
{
|
|||
|
return context.Orders
|
|||
|
.Where(order => order.Orderdata.Date >= startDate.Date && order.Orderdata.Date <= endDate.Date)
|
|||
|
.GroupBy(order => order.Orderdata.Date)
|
|||
|
.Select(g => new ServicePerDay
|
|||
|
{
|
|||
|
Date = g.Key,
|
|||
|
CountServices = g.Count()
|
|||
|
})
|
|||
|
.OrderBy(spd => spd.Date)
|
|||
|
.ToList();
|
|||
|
}
|
|||
|
|
|||
|
private void Graph_Pdf()
|
|||
|
{
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
private void Table_Pdf()
|
|||
|
{
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
private void GraphXTable_Pdf()
|
|||
|
{
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
private void Back_OnClick(object? sender, RoutedEventArgs e)
|
|||
|
{
|
|||
|
TimerService.Instance.Reset();
|
|||
|
Close();
|
|||
|
}
|
|||
|
|
|||
|
private void UpdateTimerText(TimeSpan time)
|
|||
|
{
|
|||
|
TimerText.Text = $"Осталось: {time:mm\\:ss}";
|
|||
|
}
|
|||
|
|
|||
|
private void LogoutUser()
|
|||
|
{
|
|||
|
Close();
|
|||
|
var mainWindow = new MainWindow();
|
|||
|
mainWindow.Show();
|
|||
|
}
|
|||
|
|
|||
|
protected override void OnClosed(EventArgs e)
|
|||
|
{
|
|||
|
TimerService.Instance.TimeUpdated -= UpdateTimerText;
|
|||
|
TimerService.Instance.TimerExpired -= LogoutUser;
|
|||
|
base.OnClosed(e);
|
|||
|
}
|
|||
|
}
|