demo040225_version2/dmeo040225/ReportWindow.axaml.cs

237 lines
7.3 KiB
C#
Raw Normal View History

2025-05-06 07:41:15 +00:00
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);
}
}