Compare commits

..

4 Commits

Author SHA1 Message Date
bekodeg
d9dea309c5 Починил 2024-11-25 21:07:27 +04:00
bekodeg
e66e721e98 Почти работает 2024-11-25 20:48:20 +04:00
bekodeg
a474bd8bbb добавил загрузку плагинов 2024-11-24 17:58:42 +04:00
bekodeg
5ee30cdde5 Реализация интерфейса плагина 2024-11-24 15:22:18 +04:00
13 changed files with 377 additions and 33 deletions

View File

@ -41,7 +41,7 @@ namespace Cop.Borovkov.Var3.Components
column.AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells; column.AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells;
} }
outDataGridView.Columns.Add(column); _ = outDataGridView.Columns.Add(column);
} }
} }
@ -108,10 +108,10 @@ namespace Cop.Borovkov.Var3.Components
Type type = typeof(TType); Type type = typeof(TType);
for (int i = 0; i < insertValues.Count(); ++i) for (int i = 0; i < insertValues.Count; ++i)
{ {
var row = insertValues[i]; var row = insertValues[i];
outDataGridView.Rows.Add(); _ = outDataGridView.Rows.Add();
for (int j = 0; j < outDataGridView.ColumnCount; ++j) for (int j = 0; j < outDataGridView.ColumnCount; ++j)
{ {

View File

@ -14,7 +14,7 @@ namespace Lab3.Database.Extensions
this IServiceCollection services, this IServiceCollection services,
IConfiguration configuration) IConfiguration configuration)
{ {
services.AddDbContextPool<COPContext>( _ = services.AddDbContextPool<COPContext>(
dbContextOptions => dbContextOptions =>
{ {
AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true); AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);

View File

@ -21,7 +21,7 @@ namespace Lab3.Extensions
return services; return services;
} }
public static IServiceCollection AddForms( public static IServiceCollection AddLab3Forms(
this IServiceCollection services) this IServiceCollection services)
{ {
services.AddScoped<MainForm>(); services.AddScoped<MainForm>();

View File

@ -19,7 +19,7 @@ namespace Lab3.Forms
var values = (await _repository.Get()).ToList(); var values = (await _repository.Get()).ToList();
for (int i = 0; i < values.Count; i++) for (int i = 0; i < values.Count; i++)
{ {
Catalog.Rows.Add(); _ = Catalog.Rows.Add();
Catalog.Rows[i].Cells[0].Value = values[i]; Catalog.Rows[i].Cells[0].Value = values[i];
} }
} }
@ -40,7 +40,7 @@ namespace Lab3.Forms
string? val = (string?)Catalog.Rows[i].Cells[0].Value; string? val = (string?)Catalog.Rows[i].Cells[0].Value;
if (string.IsNullOrEmpty(val)) if (string.IsNullOrEmpty(val))
{ {
MessageBox.Show( _ = MessageBox.Show(
"Неверные данные", "Неверные данные",
"Ошибка", "Ошибка",
MessageBoxButtons.OK, MessageBoxButtons.OK,
@ -54,7 +54,7 @@ namespace Lab3.Forms
} }
catch (Exception ex) catch (Exception ex)
{ {
MessageBox.Show( _ = MessageBox.Show(
ex.Message, ex.Message,
"Ошибка", "Ошибка",
MessageBoxButtons.OK, MessageBoxButtons.OK,
@ -66,7 +66,7 @@ namespace Lab3.Forms
{ {
if (e.KeyCode == Keys.Insert) if (e.KeyCode == Keys.Insert)
{ {
Catalog.Rows.Add(); _ = Catalog.Rows.Add();
} }
if (e.KeyCode == Keys.Delete && Catalog.SelectedRows.Count == 1) if (e.KeyCode == Keys.Delete && Catalog.SelectedRows.Count == 1)
@ -84,7 +84,7 @@ namespace Lab3.Forms
} }
catch (Exception ex) catch (Exception ex)
{ {
MessageBox.Show( _ = MessageBox.Show(
ex.Message, ex.Message,
"Ошибка", "Ошибка",
MessageBoxButtons.OK, MessageBoxButtons.OK,

View File

@ -37,7 +37,7 @@ namespace Lab3.Forms
} }
var student = await _studentRepository.GetAsync(_updatedStudentGuid.Value); var student = await _studentRepository.GetAsync(_updatedStudentGuid.Value);
NameTextBox.Text = student.Name; NameTextBox.Text = student!.Name;
StartEducationDataPicker.Value = student.StartEducation; StartEducationDataPicker.Value = student.StartEducation;
FormSelector.ComboBoxSelectedValue = student.EducationForm; FormSelector.ComboBoxSelectedValue = student.EducationForm;
@ -101,11 +101,11 @@ namespace Lab3.Forms
if (_updatedStudentGuid != null) if (_updatedStudentGuid != null)
{ {
await _studentRepository.UpdateAsync(student); _ = await _studentRepository.UpdateAsync(student);
} }
else else
{ {
await _studentRepository.CreateAsync(student); _ = await _studentRepository.CreateAsync(student);
} }
Close(); Close();
} }

View File

@ -9,7 +9,7 @@ namespace Lab3
internal static class Program internal static class Program
{ {
/// <summary> /// <summary>
/// The main entry point for the application. /// The main entry point for the application.
/// </summary> /// </summary>
[STAThread] [STAThread]
static void Main() static void Main()
@ -34,7 +34,7 @@ namespace Lab3
services.AddMapping(); services.AddMapping();
services.AddForms(); services.AddLab3Forms();
}); });
} }
} }

View File

@ -0,0 +1,29 @@
using Lab4.Forms;
using Lab4.Implementations;
using Lab4.Interfaces;
using Microsoft.Extensions.DependencyInjection;
namespace Lab4.Extensions
{
public static class DiExtensions
{
public static IServiceCollection AddLab4Forms(
this IServiceCollection services)
{
services.AddScoped<FormMain>();
return services;
}
public static IServiceCollection AddScopes(
this IServiceCollection services)
{
services.AddScoped<PluginsConvention>();
services.AddScoped<Func<Type, IPluginsConvention>>(sp
=> (type) => (sp.GetRequiredService(type) as IPluginsConvention)!);
return services;
}
}
}

View File

@ -8,23 +8,52 @@ namespace Lab4.Forms
private readonly Dictionary<string, IPluginsConvention> _plugins; private readonly Dictionary<string, IPluginsConvention> _plugins;
private string _selectedPlugin; private string _selectedPlugin;
public FormMain() private readonly Func<Type, IPluginsConvention> _getPluginObjectFunc;
public FormMain(Func<Type, IPluginsConvention> getPluginObjectFunc)
{ {
InitializeComponent(); InitializeComponent();
_getPluginObjectFunc = getPluginObjectFunc;
_plugins = LoadPlugins(); _plugins = LoadPlugins();
_selectedPlugin = string.Empty; _selectedPlugin = string.Empty;
} }
private Dictionary<string, IPluginsConvention> LoadPlugins() private Dictionary<string, IPluginsConvention> LoadPlugins()
{ {
// TODO Заполнить IPluginsConvention Dictionary<string, IPluginsConvention> result = [];
// TODO Заполнить пункт меню "Компоненты" на основе IPluginsConvention.PluginName
// TODO Например, создавать ToolStripMenuItem, привязывать к ним обработку событий и добавлять в menuStrip var plurinType = typeof(IPluginsConvention);
// TODO При выборе пункта меню получать UserControl и заполнять элемент panelControl этим контролом на всю площадь
// Пример: panelControl.Controls.Clear(); foreach (var type in AppDomain.CurrentDomain
// panelControl.Controls.Add(ctrl); .GetAssemblies()
return []; .SelectMany(x => x.GetTypes())
.Where(x => plurinType.IsAssignableFrom(x) && x != plurinType))
{
var plugin = _getPluginObjectFunc(type);
string key = plugin.PluginName;
result[key] = plugin;
var item = new ToolStripMenuItem(key);
item.Click += (s, e) =>
{
_selectedPlugin = key;
panelControl.Controls.Clear();
_plugins[_selectedPlugin].ReloadData();
var control = _plugins[key].GetControl;
control.Parent = panelControl;
control.Dock = DockStyle.Fill;
panelControl.Controls.Add(control);
};
ControlsStripMenuItem.DropDownItems!.Add(item);
}
return result;
} }
private void FormMain_KeyDown(object sender, KeyEventArgs e) private void FormMain_KeyDown(object sender, KeyEventArgs e)
@ -98,6 +127,7 @@ namespace Lab4.Forms
_plugins[_selectedPlugin].ReloadData(); _plugins[_selectedPlugin].ReloadData();
} }
} }
private void DeleteElement() private void DeleteElement()
{ {
if (MessageBox.Show("Удалить выбранный элемент", "Удаление", if (MessageBox.Show("Удалить выбранный элемент", "Удаление",
@ -123,8 +153,19 @@ namespace Lab4.Forms
private void CreateSimpleDoc() private void CreateSimpleDoc()
{ {
// TODO узнать где сохранять using var saveFileDialog = new SaveFileDialog
if (_plugins[_selectedPlugin].CreateSimpleDocument(new PluginsConventionSaveDocument())) {
Filter = "pdf|*.pdf"
};
if (saveFileDialog.ShowDialog() != DialogResult.OK)
{
return;
}
if (_plugins[_selectedPlugin].CreateSimpleDocument(new PluginsConventionSaveDocument()
{
FileName = saveFileDialog.FileName,
}))
{ {
_ = MessageBox.Show("Документ сохранен", _ = MessageBox.Show("Документ сохранен",
"Создание документа", "Создание документа",
@ -136,11 +177,24 @@ namespace Lab4.Forms
_ = MessageBox.Show("Ошибка при создании документа", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); _ = MessageBox.Show("Ошибка при создании документа", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
} }
} }
private void CreateTableDoc() private void CreateTableDoc()
{ {
// TODO узнать где сохранять using var saveFileDialog = new SaveFileDialog
{
Filter = "xlsx|*.xlsx"
};
if (saveFileDialog.ShowDialog() != DialogResult.OK)
{
return;
}
if (_plugins[_selectedPlugin].CreateTableDocument(new if (_plugins[_selectedPlugin].CreateTableDocument(new
PluginsConventionSaveDocument())) PluginsConventionSaveDocument()
{
FileName = saveFileDialog.FileName,
}))
{ {
_ = MessageBox.Show("Документ сохранен", _ = MessageBox.Show("Документ сохранен",
"Создание документа", "Создание документа",
@ -152,10 +206,23 @@ namespace Lab4.Forms
_ = MessageBox.Show("Ошибка при создании документа", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); _ = MessageBox.Show("Ошибка при создании документа", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
} }
} }
private void CreateChartDoc() private void CreateChartDoc()
{ {
// TODO узнать где сохранять using var saveFileDialog = new SaveFileDialog
if (_plugins[_selectedPlugin].CreateChartDocument(new PluginsConventionSaveDocument())) {
Filter = "docx|*.docx"
};
if (saveFileDialog.ShowDialog() != DialogResult.OK)
{
return;
}
if (_plugins[_selectedPlugin].CreateChartDocument(new PluginsConventionSaveDocument()
{
FileName= saveFileDialog.FileName,
}))
{ {
_ = MessageBox.Show("Документ сохранен", _ = MessageBox.Show("Документ сохранен",
"Создание документа", "Создание документа",
@ -167,7 +234,7 @@ namespace Lab4.Forms
_ = MessageBox.Show("Ошибка при создании документа", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); _ = MessageBox.Show("Ошибка при создании документа", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
} }
} }
private void ThesaurusToolStripMenuItem_Click(object sender, EventArgs e) => ShowThesaurus(); private void ThesaurusToolStripMenuItem_Click(object sender, EventArgs e) => ShowThesaurus();
private void AddElementToolStripMenuItem_Click(object sender, EventArgs e) => AddNewElement(); private void AddElementToolStripMenuItem_Click(object sender, EventArgs e) => AddNewElement();

View File

@ -0,0 +1,204 @@
using Cop.Borovkov.Var3.Components;
using Lab4.Interfaces;
using Lab4.Models;
using Lab3.Database.Repository.Interfaces;
using ComponentsLibrary.entities;
using ComponentsLibrary;
using ComponentsLibrary.entities.enums;
using Lab3.Database.DTO;
using CustomComponentsVar2;
using Lab3.Forms;
using Lab3.Models;
using AutoMapper;
namespace Lab4.Implementations
{
public class PluginsConvention : IPluginsConvention
{
private readonly IMapper _mapper;
private readonly IStudentRepository _studentRepository;
private readonly IEducationFormRepository _educationFormRepository;
private readonly CustomListBox _control;
private readonly CustomPdfTable _simpleDocumentCreator;
private readonly CustomExcelTable _tableCreator;
private readonly ComponentDiagram _chartCreator;
public PluginsConvention(
IMapper mapper,
IStudentRepository studentRepository,
IEducationFormRepository educationFormRepository)
{
_mapper = mapper;
_studentRepository = studentRepository;
_educationFormRepository = educationFormRepository;
_control = new();
_chartCreator = new();
_tableCreator = new();
_simpleDocumentCreator = new();
}
public string PluginName => "Успеваемость";
public UserControl GetControl => _control;
public PluginsConventionElement GetElement {
get
{
var filds = _control.Selected.Split();
Guid id = Guid.Parse(filds[0]);
return new()
{
Id = id,
};
}
}
public bool CreateChartDocument(PluginsConventionSaveDocument saveDocument)
{
try
{
var data = _studentRepository.GetAsync().Result
.GroupBy(s => s.EducationForm)
.Select(s => new DataLine(
s.Key,
s.GroupBy(x => x.StartEducation.Year)
.Select(x => (year: x.Key.ToString(), count: (double)x.Count()))
.ToArray()))
.ToList();
_chartCreator.AddDiagram(
new(
saveDocument.FileName,
"Поступления",
"Диаграмма",
EnumAreaLegend.Bottom,
data
)
);
return true;
}
catch
{
return false;
}
}
public bool CreateSimpleDocument(PluginsConventionSaveDocument saveDocument)
{
try
{
var values = (_studentRepository.GetAsync()).Result
.Select(s => s.StudentSessions
.OrderBy(x => x.Number)
.Select(x => x.Score.ToString())
.ToArray())
.ToArray();
var tables = new string[values.Length, 6];
for (int i = 0; i < values.Length; ++i)
{
for (int j = 0; j < 6; ++j)
{
tables[i, j] = values[i][j];
}
}
_simpleDocumentCreator.SaveToPdf(new()
{
FilePath = saveDocument.FileName,
Title = "Сессии",
Tables = [tables]
});
return true;
}
catch
{
return false;
}
}
public bool CreateTableDocument(PluginsConventionSaveDocument saveDocument)
{
try
{
_tableCreator.SaveToExcel<StudentDTO>(new()
{
FilePath = saveDocument.FileName,
Title = "Студенты",
Headers =
[
("Id", nameof(StudentDTO.Id)),
("ФИО", nameof(StudentDTO.Name)),
("Форма обучения", nameof(StudentDTO.EducationForm)),
("Дата поступления", nameof(StudentDTO.StartEducation)),
],
HeaderGroups = [new() {
GroupHeader = "Образование",
FirstHeader = 2,
LastHeader = 3,
}],
Values = _studentRepository.GetAsync().Result
});
return true;
}
catch
{
return false;
}
}
public bool DeleteElement(PluginsConventionElement element)
{
try
{
_studentRepository
.DeleteAsync(element.Id).Wait();
return true;
}
catch
{
return false;
}
}
public Form GetForm(PluginsConventionElement? element = null)
=> new CreateForm(_studentRepository, _educationFormRepository, element?.Id);
public Form GetThesaurus()
=> new CatalogForm(_educationFormRepository);
public async void ReloadData()
{
try
{
var students = _mapper.Map<List<StudentViewModel>>(await _studentRepository.GetAsync());
_control.FillValues(
students.Select(s => string.Join(" ",
[
s.Id,
s.Name,
s.EducationForm,
s.StartEducation.ToLongDateString(),
s.SessionMarks,
]
))
);
}
catch
{
}
}
}
}

View File

@ -12,7 +12,7 @@ namespace Lab4.Interfaces
/// <summary> /// <summary>
/// Получение контрола для вывода набора данных /// Получение контрола для вывода набора данных
/// </summary> /// </summary>
UserControl GetControl { get; } UserControl GetControl { get; }
/// <summary> /// <summary>
/// Получение элемента, выбранного в контроле /// Получение элемента, выбранного в контроле

View File

@ -8,4 +8,14 @@
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Lab3\Lab3.csproj" />
</ItemGroup>
<ItemGroup>
<None Update="appsettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project> </Project>

View File

@ -1,9 +1,17 @@
using Lab3.Extensions;
using Lab3.Forms;
using Lab4.Extensions;
using Lab4.Forms;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace Lab4 namespace Lab4
{ {
internal static class Program internal static class Program
{ {
/// <summary> /// <summary>
/// The main entry point for the application. /// The main entry point for the application.
/// </summary> /// </summary>
[STAThread] [STAThread]
static void Main() static void Main()
@ -11,7 +19,28 @@ namespace Lab4
// To customize application configuration such as set high DPI settings or default font, // To customize application configuration such as set high DPI settings or default font,
// see https://aka.ms/applicationconfiguration. // see https://aka.ms/applicationconfiguration.
ApplicationConfiguration.Initialize(); ApplicationConfiguration.Initialize();
Application.Run(new Form1());
var app = CreateHostBuilder().Build();
Application.Run(app.Services.GetRequiredService<FormMain>());
}
static IHostBuilder CreateHostBuilder()
{
return Host.CreateDefaultBuilder()
.ConfigureAppConfiguration(c
=> c.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true))
.ConfigureServices((context, services) => {
services.ConfigureDAL(context.Configuration);
services.AddMapping();
services.AddLab3Forms();
services.AddLab4Forms();
services.AddScopes();
});
} }
} }
} }

View File

@ -0,0 +1,5 @@
{
"ConnectionStrings": {
"COPDataBase": "Host=localhost;Username=postgres;Password=postgres;Database=COP"
}
}