From 5ec407fa6d8e9c3cc919b808741a09fdaafce8f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A2=D0=B0=D1=82=D1=8C=D1=8F=D0=BD=D0=B0=20=D0=90=D1=80?= =?UTF-8?q?=D1=82=D0=B0=D0=BC=D0=BE=D0=BD=D0=BE=D0=B2=D0=B0?= Date: Sat, 28 Oct 2023 09:06:35 +0400 Subject: [PATCH] =?UTF-8?q?=D0=B4=D0=B5=D0=BB=D0=B0=D1=8E=203=20=D0=BB?= =?UTF-8?q?=D0=B0=D0=B1=D1=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- COP/COP.csproj | 8 +- COP/COP.sln | 34 +++- COP/UserTreeView.cs | 2 +- TestComponents/FormTestComponents.cs | 4 +- TestComponents/TestComponents.csproj | 10 + .../BusinessLogics/DirectionLogic.cs | 108 +++++++++++ .../BusinessLogics/StudentLogic.cs | 121 ++++++++++++ .../UniversityBusinessLogic.csproj | 18 ++ .../BindingModels/DirectionBindingModel.cs | 10 + .../BindingModels/StudentBindingModel.cs | 13 ++ .../IDirectionLogic.cs | 14 ++ .../BusinessLogicsContracts/IStudentLogic.cs | 15 ++ .../SearchModels/DirectionSearchModel.cs | 8 + .../SearchModels/StudentSearchModel.cs | 8 + .../StoragesContracts/IDirectionStorage.cs | 16 ++ .../StoragesContracts/IStudentStorage.cs | 16 ++ .../UniversityContracts.csproj | 14 ++ .../ViewModels/DirectionViewModel.cs | 12 ++ .../ViewModels/StudentViewModel.cs | 18 ++ UniversityDataModels/IId.cs | 7 + .../Models/IDirectionModel.cs | 7 + UniversityDataModels/Models/IStudentModel.cs | 10 + .../UniversityDataModels.csproj | 10 + .../Implements/DirectionStorage.cs | 80 ++++++++ .../Implements/StudentStorage.cs | 81 ++++++++ .../20231027233645_InitialCreate.Designer.cs | 75 ++++++++ .../20231027233645_InitialCreate.cs | 53 ++++++ .../UniversityDatabaseModelSnapshot.cs | 72 +++++++ .../Models/Direction.cs | 48 +++++ UniversityDatabaseImplement/Models/Student.cs | 66 +++++++ .../UniversityDatabase.cs | 19 ++ .../UniversityDatabaseImplement.csproj | 24 +++ UniversityView/FormHandbooks.Designer.cs | 66 +++++++ UniversityView/FormHandbooks.cs | 110 +++++++++++ UniversityView/FormHandbooks.resx | 60 ++++++ UniversityView/FormMain.Designer.cs | 154 +++++++++++++++ UniversityView/FormMain.cs | 177 ++++++++++++++++++ UniversityView/FormMain.resx | 69 +++++++ UniversityView/FormStudent.Designer.cs | 174 +++++++++++++++++ UniversityView/FormStudent.cs | 134 +++++++++++++ UniversityView/FormStudent.resx | 60 ++++++ UniversityView/Program.cs | 43 +++++ .../Properties/Resources.Designer.cs | 63 +++++++ UniversityView/Properties/Resources.resx | 120 ++++++++++++ UniversityView/UniversityView.csproj | 46 +++++ 45 files changed, 2271 insertions(+), 6 deletions(-) create mode 100644 UniversityBusinessLogic/BusinessLogics/DirectionLogic.cs create mode 100644 UniversityBusinessLogic/BusinessLogics/StudentLogic.cs create mode 100644 UniversityBusinessLogic/UniversityBusinessLogic.csproj create mode 100644 UniversityContracts/BindingModels/DirectionBindingModel.cs create mode 100644 UniversityContracts/BindingModels/StudentBindingModel.cs create mode 100644 UniversityContracts/BusinessLogicsContracts/IDirectionLogic.cs create mode 100644 UniversityContracts/BusinessLogicsContracts/IStudentLogic.cs create mode 100644 UniversityContracts/SearchModels/DirectionSearchModel.cs create mode 100644 UniversityContracts/SearchModels/StudentSearchModel.cs create mode 100644 UniversityContracts/StoragesContracts/IDirectionStorage.cs create mode 100644 UniversityContracts/StoragesContracts/IStudentStorage.cs create mode 100644 UniversityContracts/UniversityContracts.csproj create mode 100644 UniversityContracts/ViewModels/DirectionViewModel.cs create mode 100644 UniversityContracts/ViewModels/StudentViewModel.cs create mode 100644 UniversityDataModels/IId.cs create mode 100644 UniversityDataModels/Models/IDirectionModel.cs create mode 100644 UniversityDataModels/Models/IStudentModel.cs create mode 100644 UniversityDataModels/UniversityDataModels.csproj create mode 100644 UniversityDatabaseImplement/Implements/DirectionStorage.cs create mode 100644 UniversityDatabaseImplement/Implements/StudentStorage.cs create mode 100644 UniversityDatabaseImplement/Migrations/20231027233645_InitialCreate.Designer.cs create mode 100644 UniversityDatabaseImplement/Migrations/20231027233645_InitialCreate.cs create mode 100644 UniversityDatabaseImplement/Migrations/UniversityDatabaseModelSnapshot.cs create mode 100644 UniversityDatabaseImplement/Models/Direction.cs create mode 100644 UniversityDatabaseImplement/Models/Student.cs create mode 100644 UniversityDatabaseImplement/UniversityDatabase.cs create mode 100644 UniversityDatabaseImplement/UniversityDatabaseImplement.csproj create mode 100644 UniversityView/FormHandbooks.Designer.cs create mode 100644 UniversityView/FormHandbooks.cs create mode 100644 UniversityView/FormHandbooks.resx create mode 100644 UniversityView/FormMain.Designer.cs create mode 100644 UniversityView/FormMain.cs create mode 100644 UniversityView/FormMain.resx create mode 100644 UniversityView/FormStudent.Designer.cs create mode 100644 UniversityView/FormStudent.cs create mode 100644 UniversityView/FormStudent.resx create mode 100644 UniversityView/Program.cs create mode 100644 UniversityView/Properties/Resources.Designer.cs create mode 100644 UniversityView/Properties/Resources.resx create mode 100644 UniversityView/UniversityView.csproj diff --git a/COP/COP.csproj b/COP/COP.csproj index c39840f..7014b7f 100644 --- a/COP/COP.csproj +++ b/COP/COP.csproj @@ -8,9 +8,15 @@ True - + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/COP/COP.sln b/COP/COP.sln index 8efd9c1..610bbdd 100644 --- a/COP/COP.sln +++ b/COP/COP.sln @@ -3,9 +3,19 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.3.32825.248 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "COP", "COP.csproj", "{B22B20DB-B359-48B7-88CF-35A6EC770FD1}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "COP", "COP.csproj", "{B22B20DB-B359-48B7-88CF-35A6EC770FD1}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestComponents", "..\TestComponents\TestComponents.csproj", "{C0F09A72-65A3-49DD-8208-291778E03E81}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestComponents", "..\TestComponents\TestComponents.csproj", "{C0F09A72-65A3-49DD-8208-291778E03E81}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UniversityDataModels", "..\UniversityDataModels\UniversityDataModels.csproj", "{843E5B85-F60A-45D7-9B52-96284FFDCA1F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UniversityBusinessLogic", "..\UniversityBusinessLogic\UniversityBusinessLogic.csproj", "{453BBFDD-7D8B-463F-A622-AFD6F3E6C644}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UniversityContracts", "..\UniversityContracts\UniversityContracts.csproj", "{2EFD9DCC-226F-45D0-8688-4E0D716BC179}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UniversityDatabaseImplement", "..\UniversityDatabaseImplement\UniversityDatabaseImplement.csproj", "{7ED4372B-4D10-411D-9CC1-13CAA2833789}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UniversityView", "..\UniversityView\UniversityView.csproj", "{99AE36FC-FEF0-4E8C-8C0B-F6AB1952DEE6}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -21,6 +31,26 @@ Global {C0F09A72-65A3-49DD-8208-291778E03E81}.Debug|Any CPU.Build.0 = Debug|Any CPU {C0F09A72-65A3-49DD-8208-291778E03E81}.Release|Any CPU.ActiveCfg = Release|Any CPU {C0F09A72-65A3-49DD-8208-291778E03E81}.Release|Any CPU.Build.0 = Release|Any CPU + {843E5B85-F60A-45D7-9B52-96284FFDCA1F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {843E5B85-F60A-45D7-9B52-96284FFDCA1F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {843E5B85-F60A-45D7-9B52-96284FFDCA1F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {843E5B85-F60A-45D7-9B52-96284FFDCA1F}.Release|Any CPU.Build.0 = Release|Any CPU + {453BBFDD-7D8B-463F-A622-AFD6F3E6C644}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {453BBFDD-7D8B-463F-A622-AFD6F3E6C644}.Debug|Any CPU.Build.0 = Debug|Any CPU + {453BBFDD-7D8B-463F-A622-AFD6F3E6C644}.Release|Any CPU.ActiveCfg = Release|Any CPU + {453BBFDD-7D8B-463F-A622-AFD6F3E6C644}.Release|Any CPU.Build.0 = Release|Any CPU + {2EFD9DCC-226F-45D0-8688-4E0D716BC179}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2EFD9DCC-226F-45D0-8688-4E0D716BC179}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2EFD9DCC-226F-45D0-8688-4E0D716BC179}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2EFD9DCC-226F-45D0-8688-4E0D716BC179}.Release|Any CPU.Build.0 = Release|Any CPU + {7ED4372B-4D10-411D-9CC1-13CAA2833789}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7ED4372B-4D10-411D-9CC1-13CAA2833789}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7ED4372B-4D10-411D-9CC1-13CAA2833789}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7ED4372B-4D10-411D-9CC1-13CAA2833789}.Release|Any CPU.Build.0 = Release|Any CPU + {99AE36FC-FEF0-4E8C-8C0B-F6AB1952DEE6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {99AE36FC-FEF0-4E8C-8C0B-F6AB1952DEE6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {99AE36FC-FEF0-4E8C-8C0B-F6AB1952DEE6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {99AE36FC-FEF0-4E8C-8C0B-F6AB1952DEE6}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/COP/UserTreeView.cs b/COP/UserTreeView.cs index fa93409..a1594ac 100644 --- a/COP/UserTreeView.cs +++ b/COP/UserTreeView.cs @@ -62,7 +62,7 @@ namespace COP } //проверка что выбранный элем последний в ветке - public void PopulateTree(List items) + public void PopulateTree(List items, List Hierarchy) { treeView.BeginUpdate(); treeView.Nodes.Clear(); diff --git a/TestComponents/FormTestComponents.cs b/TestComponents/FormTestComponents.cs index 7480d01..5f9f10e 100644 --- a/TestComponents/FormTestComponents.cs +++ b/TestComponents/FormTestComponents.cs @@ -66,7 +66,7 @@ namespace TestComponents new Employee1 { Department = "Отдел1", Position = "Должность1", Name = "Сотрудник3" }, new Employee1 { Department = "Отдел2", Position = "Должность3", Name = "Сотрудник4" }, }; - var Hierarchy = new List { "Department", "Position", "Name" }; + var Hierarchy = new List { "Department", "Name" }; foreach (var prop in employees[0].GetType().GetProperties()) { userTreeView.Hierarchy.Add(prop.Name); @@ -74,7 +74,7 @@ namespace TestComponents try { - userTreeView.PopulateTree(employees); + userTreeView.PopulateTree(employees, Hierarchy); } catch (Exception ex) { diff --git a/TestComponents/TestComponents.csproj b/TestComponents/TestComponents.csproj index a119c12..2f2e7a6 100644 --- a/TestComponents/TestComponents.csproj +++ b/TestComponents/TestComponents.csproj @@ -8,8 +8,18 @@ enable + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + \ No newline at end of file diff --git a/UniversityBusinessLogic/BusinessLogics/DirectionLogic.cs b/UniversityBusinessLogic/BusinessLogics/DirectionLogic.cs new file mode 100644 index 0000000..771dcd0 --- /dev/null +++ b/UniversityBusinessLogic/BusinessLogics/DirectionLogic.cs @@ -0,0 +1,108 @@ +using Microsoft.Extensions.Logging; +using UniversityContracts.BindingModels; +using UniversityContracts.BusinessLogicsContracts; +using UniversityContracts.SearchModels; +using UniversityContracts.StoragesContracts; +using UniversityContracts.ViewModels; + +namespace UniversityBusinessLogic.BusinessLogics +{ + public class DirectionLogic : IDirectionLogic + { + private readonly ILogger _logger; + private readonly IDirectionStorage _directionStorage; + public DirectionLogic(ILogger logger, IDirectionStorage directionStorage) + { + _logger = logger; + _directionStorage = directionStorage; + } + + public void CreateOrUpdate(DirectionBindingModel model) + { + var element = _directionStorage.GetElement( + new DirectionBindingModel + { + Name = model.Name + }); + if (element != null && element.Id != model.Id) + { + throw new Exception("Такое направление уже существует"); + } + if (model.Id != null) + { + _directionStorage.Update(model); + } + else + { + _directionStorage.Insert(model); + } + } + + public bool Delete(DirectionBindingModel model) + { + CheckModel(model, false); + _logger.LogInformation("Delete. Id:{Id}", model.Id); + if (_directionStorage.Delete(model) == null) + { + _logger.LogWarning("Delete operation failed"); + return false; + } + return true; + } + + public DirectionViewModel? ReadElement(DirectionBindingModel model) + { + if (model == null) + { + throw new ArgumentNullException(nameof(model)); + } + _logger.LogInformation("ReadElement. Name:{Name}. Id:{ Id}", model.Name, model.Id); + var element = _directionStorage.GetElement(model); + if (element == null) + { + _logger.LogWarning("ReadElement element not found"); + return null; + } + _logger.LogInformation("ReadElement find. Id:{Id}", element.Id); + return element; + } + + public List? ReadList(DirectionBindingModel? model) + { + _logger.LogInformation("ReadList. Name:{Name}. Id:{ Id}", model?.Name, model?.Id); + var list = model == null ? _directionStorage.GetFullList() : _directionStorage.GetFilteredList(model); + if (list == null) + { + _logger.LogWarning("ReadList return null list"); + return null; + } + _logger.LogInformation("ReadList. Count:{Count}", list.Count); + return list; + } + + private void CheckModel(DirectionBindingModel model, bool withParams = true) + { + if (model == null) + { + throw new ArgumentNullException(nameof(model)); + } + if (!withParams) + { + return; + } + if (string.IsNullOrEmpty(model.Name)) + { + throw new ArgumentNullException("Нет названия направления", nameof(model.Name)); + } + _logger.LogInformation("Direction. Name:{Name}. Id: {Id} ", model.Name, model.Id); + var element = _directionStorage.GetElement(new DirectionBindingModel + { + Name = model.Name + }); + if (element != null && element.Id != model.Id) + { + throw new InvalidOperationException("Направление с таким названием уже есть"); + } + } + } +} diff --git a/UniversityBusinessLogic/BusinessLogics/StudentLogic.cs b/UniversityBusinessLogic/BusinessLogics/StudentLogic.cs new file mode 100644 index 0000000..9eadef1 --- /dev/null +++ b/UniversityBusinessLogic/BusinessLogics/StudentLogic.cs @@ -0,0 +1,121 @@ +using Microsoft.Extensions.Logging; +using UniversityContracts.BindingModels; +using UniversityContracts.BusinessLogicsContracts; +using UniversityContracts.SearchModels; +using UniversityContracts.StoragesContracts; +using UniversityContracts.ViewModels; + +namespace UniversityBusinessLogic.BusinessLogics +{ + public class StudentLogic : IStudentLogic + { + private readonly ILogger _logger; + private readonly IStudentStorage _studentStorage; + public StudentLogic(ILogger logger, IStudentStorage studentStorage) + { + _logger = logger; + _studentStorage = studentStorage; + } + public bool Create(StudentBindingModel model) + { + CheckModel(model); + model.DirectionName = model.DirectionName.Trim(); + if (_studentStorage.Insert(model) == null) + { + _logger.LogWarning("Insert operation failed"); + return false; + } + return true; + } + + public bool Delete(StudentBindingModel model) + { + CheckModel(model, false); + _logger.LogInformation("Delete. Id:{Id}", model.Id); + if (_studentStorage.Delete(model) == null) + { + _logger.LogWarning("Delete operation failed"); + return false; + } + return true; + } + + public StudentViewModel? ReadElement(StudentSearchModel model) + { + if (model == null) + { + throw new ArgumentNullException(nameof(model)); + } + _logger.LogInformation("ReadElement. FIO:{FIO}. Id:{ Id}", model.FIO, model.Id); + var element = _studentStorage.GetElement(model); + if (element == null) + { + _logger.LogWarning("ReadElement element not found"); + return null; + } + _logger.LogInformation("ReadElement find. Id:{Id}", element.Id); + return element; + } + + public List? ReadList(StudentSearchModel? model) + { + _logger.LogInformation("ReadList. FIO:{FIO}. Id:{ Id}", model?.FIO, model?.Id); + var list = model == null ? _studentStorage.GetFullList() : _studentStorage.GetFilteredList(model); + if (list == null) + { + _logger.LogWarning("ReadList return null list"); + return null; + } + _logger.LogInformation("ReadList. Count:{Count}", list.Count); + return list; + } + + public bool Update(StudentBindingModel model) + { + CheckModel(model); + if (_studentStorage.Update(model) == null) + { + _logger.LogWarning("Update operation failed"); + return false; + } + return true; + } + + private void CheckModel(StudentBindingModel model, bool withParams = true) + { + if (model == null) + { + throw new ArgumentNullException(nameof(model)); + } + if (!withParams) + { + return; + } + if (string.IsNullOrEmpty(model.FIO)) + { + throw new ArgumentNullException("Нет ФИО студента", nameof(model.FIO)); + } + if (string.IsNullOrEmpty(model.PhotoFilePath)) + { + throw new ArgumentNullException("Нет пути к фото", nameof(model.PhotoFilePath)); + } + if (string.IsNullOrEmpty(model.Email)) + { + throw new ArgumentNullException("Нет электронной почты", nameof(model.Email)); + } + if (string.IsNullOrEmpty(model.DirectionName)) + { + throw new ArgumentNullException("Нет направления", nameof(model.DirectionName)); + } + _logger.LogInformation("Student. FIO:{FIO}. PhotoFilePath:{PhotoFilePath}. Email:{Email}. DirectionName:{DirectionName}. Id: {Id} ", model.FIO, model.PhotoFilePath, model.Email, model.DirectionName, model.Id); + var element = _studentStorage.GetElement(new StudentSearchModel + { + FIO = model.FIO + }); + if (element != null && element.Id != model.Id) + { + throw new InvalidOperationException("Студент с таким ФИО уже есть"); + } + } + } +} diff --git a/UniversityBusinessLogic/UniversityBusinessLogic.csproj b/UniversityBusinessLogic/UniversityBusinessLogic.csproj new file mode 100644 index 0000000..c25f64d --- /dev/null +++ b/UniversityBusinessLogic/UniversityBusinessLogic.csproj @@ -0,0 +1,18 @@ + + + + net6.0-windows + enable + true + enable + + + + + + + + + + + diff --git a/UniversityContracts/BindingModels/DirectionBindingModel.cs b/UniversityContracts/BindingModels/DirectionBindingModel.cs new file mode 100644 index 0000000..0abec63 --- /dev/null +++ b/UniversityContracts/BindingModels/DirectionBindingModel.cs @@ -0,0 +1,10 @@ +using UniversityDataModels.Models; + +namespace UniversityContracts.BindingModels +{ + public class DirectionBindingModel : IDirectionModel + { + public int Id { get; set; } + public string Name { get; set; } = string.Empty; + } +} diff --git a/UniversityContracts/BindingModels/StudentBindingModel.cs b/UniversityContracts/BindingModels/StudentBindingModel.cs new file mode 100644 index 0000000..c5426bf --- /dev/null +++ b/UniversityContracts/BindingModels/StudentBindingModel.cs @@ -0,0 +1,13 @@ +using UniversityDataModels.Models; + +namespace UniversityContracts.BindingModels +{ + public class StudentBindingModel : IStudentModel + { + public int Id { get; set; } + public string FIO { get; set; } = string.Empty; + public string PhotoFilePath { get; set; } = string.Empty; + public string Email { get; set; } = string.Empty; + public string DirectionName { get; set; } = string.Empty; + } +} diff --git a/UniversityContracts/BusinessLogicsContracts/IDirectionLogic.cs b/UniversityContracts/BusinessLogicsContracts/IDirectionLogic.cs new file mode 100644 index 0000000..89161d3 --- /dev/null +++ b/UniversityContracts/BusinessLogicsContracts/IDirectionLogic.cs @@ -0,0 +1,14 @@ +using UniversityContracts.BindingModels; +using UniversityContracts.SearchModels; +using UniversityContracts.ViewModels; + +namespace UniversityContracts.BusinessLogicsContracts +{ + public interface IDirectionLogic + { + List? ReadList(DirectionBindingModel? model); + DirectionViewModel? ReadElement(DirectionBindingModel model); + bool Delete(DirectionBindingModel model); + void CreateOrUpdate(DirectionBindingModel model); + } +} diff --git a/UniversityContracts/BusinessLogicsContracts/IStudentLogic.cs b/UniversityContracts/BusinessLogicsContracts/IStudentLogic.cs new file mode 100644 index 0000000..12b37d7 --- /dev/null +++ b/UniversityContracts/BusinessLogicsContracts/IStudentLogic.cs @@ -0,0 +1,15 @@ +using UniversityContracts.BindingModels; +using UniversityContracts.SearchModels; +using UniversityContracts.ViewModels; + +namespace UniversityContracts.BusinessLogicsContracts +{ + public interface IStudentLogic + { + List? ReadList(StudentSearchModel? model); + StudentViewModel? ReadElement(StudentSearchModel model); + bool Create(StudentBindingModel model); + bool Update(StudentBindingModel model); + bool Delete(StudentBindingModel model); + } +} diff --git a/UniversityContracts/SearchModels/DirectionSearchModel.cs b/UniversityContracts/SearchModels/DirectionSearchModel.cs new file mode 100644 index 0000000..9e7091d --- /dev/null +++ b/UniversityContracts/SearchModels/DirectionSearchModel.cs @@ -0,0 +1,8 @@ +namespace UniversityContracts.SearchModels +{ + public class DirectionSearchModel + { + public int? Id { get; set; } + public string? Name { get; set; } + } +} diff --git a/UniversityContracts/SearchModels/StudentSearchModel.cs b/UniversityContracts/SearchModels/StudentSearchModel.cs new file mode 100644 index 0000000..51dbcc5 --- /dev/null +++ b/UniversityContracts/SearchModels/StudentSearchModel.cs @@ -0,0 +1,8 @@ +namespace UniversityContracts.SearchModels +{ + public class StudentSearchModel + { + public int? Id { get; set; } + public string? FIO { get; set; } + } +} diff --git a/UniversityContracts/StoragesContracts/IDirectionStorage.cs b/UniversityContracts/StoragesContracts/IDirectionStorage.cs new file mode 100644 index 0000000..73da254 --- /dev/null +++ b/UniversityContracts/StoragesContracts/IDirectionStorage.cs @@ -0,0 +1,16 @@ +using UniversityContracts.BindingModels; +using UniversityContracts.SearchModels; +using UniversityContracts.ViewModels; + +namespace UniversityContracts.StoragesContracts +{ + public interface IDirectionStorage + { + List GetFullList(); + List GetFilteredList(DirectionBindingModel model); + DirectionViewModel? GetElement(DirectionBindingModel model); + DirectionViewModel? Insert(DirectionBindingModel model); + DirectionViewModel? Update(DirectionBindingModel model); + DirectionViewModel? Delete(DirectionBindingModel model); + } +} diff --git a/UniversityContracts/StoragesContracts/IStudentStorage.cs b/UniversityContracts/StoragesContracts/IStudentStorage.cs new file mode 100644 index 0000000..ea3bd7e --- /dev/null +++ b/UniversityContracts/StoragesContracts/IStudentStorage.cs @@ -0,0 +1,16 @@ +using UniversityContracts.BindingModels; +using UniversityContracts.SearchModels; +using UniversityContracts.ViewModels; + +namespace UniversityContracts.StoragesContracts +{ + public interface IStudentStorage + { + List GetFullList(); + List GetFilteredList(StudentSearchModel model); + StudentViewModel? GetElement(StudentSearchModel model); + StudentViewModel? Insert(StudentBindingModel model); + StudentViewModel? Update(StudentBindingModel model); + StudentViewModel? Delete(StudentBindingModel model); + } +} diff --git a/UniversityContracts/UniversityContracts.csproj b/UniversityContracts/UniversityContracts.csproj new file mode 100644 index 0000000..1844a68 --- /dev/null +++ b/UniversityContracts/UniversityContracts.csproj @@ -0,0 +1,14 @@ + + + + net6.0-windows + enable + true + enable + + + + + + + diff --git a/UniversityContracts/ViewModels/DirectionViewModel.cs b/UniversityContracts/ViewModels/DirectionViewModel.cs new file mode 100644 index 0000000..0f4dfc3 --- /dev/null +++ b/UniversityContracts/ViewModels/DirectionViewModel.cs @@ -0,0 +1,12 @@ +using System.ComponentModel; +using UniversityDataModels.Models; + +namespace UniversityContracts.ViewModels +{ + public class DirectionViewModel : IDirectionModel + { + public int Id { get; set; } + [DisplayName("Название направления")] + public string Name { get; set; } = string.Empty; + } +} diff --git a/UniversityContracts/ViewModels/StudentViewModel.cs b/UniversityContracts/ViewModels/StudentViewModel.cs new file mode 100644 index 0000000..978b96c --- /dev/null +++ b/UniversityContracts/ViewModels/StudentViewModel.cs @@ -0,0 +1,18 @@ +using System.ComponentModel; +using UniversityDataModels.Models; + +namespace UniversityContracts.ViewModels +{ + public class StudentViewModel : IStudentModel + { + public int Id { get; set; } + [DisplayName("ФИО студента")] + public string FIO { get; set; } = string.Empty; + [DisplayName("Путь к фото")] + public string PhotoFilePath { get; set; } = string.Empty; + [DisplayName("Электронная почта")] + public string Email { get; set; } = string.Empty; + [DisplayName("Направление")] + public string DirectionName { get; set; } = string.Empty; + } +} diff --git a/UniversityDataModels/IId.cs b/UniversityDataModels/IId.cs new file mode 100644 index 0000000..ef1cc9d --- /dev/null +++ b/UniversityDataModels/IId.cs @@ -0,0 +1,7 @@ +namespace UniversityDataModels +{ + public interface IId + { + int Id { get; } + } +} diff --git a/UniversityDataModels/Models/IDirectionModel.cs b/UniversityDataModels/Models/IDirectionModel.cs new file mode 100644 index 0000000..8b91311 --- /dev/null +++ b/UniversityDataModels/Models/IDirectionModel.cs @@ -0,0 +1,7 @@ +namespace UniversityDataModels.Models +{ + public interface IDirectionModel : IId + { + string Name { get; } + } +} diff --git a/UniversityDataModels/Models/IStudentModel.cs b/UniversityDataModels/Models/IStudentModel.cs new file mode 100644 index 0000000..b990052 --- /dev/null +++ b/UniversityDataModels/Models/IStudentModel.cs @@ -0,0 +1,10 @@ +namespace UniversityDataModels.Models +{ + public interface IStudentModel : IId + { + string FIO { get; } + string PhotoFilePath { get; } + string Email { get; } + string DirectionName { get; } + } +} diff --git a/UniversityDataModels/UniversityDataModels.csproj b/UniversityDataModels/UniversityDataModels.csproj new file mode 100644 index 0000000..060aa1c --- /dev/null +++ b/UniversityDataModels/UniversityDataModels.csproj @@ -0,0 +1,10 @@ + + + + net6.0-windows + enable + true + enable + + + diff --git a/UniversityDatabaseImplement/Implements/DirectionStorage.cs b/UniversityDatabaseImplement/Implements/DirectionStorage.cs new file mode 100644 index 0000000..8cf1e2d --- /dev/null +++ b/UniversityDatabaseImplement/Implements/DirectionStorage.cs @@ -0,0 +1,80 @@ +using UniversityContracts.BindingModels; +using UniversityContracts.SearchModels; +using UniversityContracts.StoragesContracts; +using UniversityContracts.ViewModels; +using UniversityDatabaseImplement.Models; + +namespace UniversityDatabaseImplement.Implements +{ + public class DirectionStorage : IDirectionStorage + { + public List GetFullList() + { + using var context = new UniversityDatabase(); + return context.Directions + .Select(x => x.GetViewModel) + .ToList(); + } + public List GetFilteredList(DirectionBindingModel model) + { + if (string.IsNullOrEmpty(model.Name)) + { + return new(); + } + using var context = new UniversityDatabase(); + return context.Directions + .Select(x => x.GetViewModel) + .ToList(); + } + public DirectionViewModel? GetElement(DirectionBindingModel model) + { + if (string.IsNullOrEmpty(model.Name) && !model.Id.HasValue) + { + return null; + } + using var context = new UniversityDatabase(); + return context.Directions + .FirstOrDefault(x => (!string.IsNullOrEmpty(model.Name) && + x.Name == model.Name) || + (model.Id.HasValue && x.Id == model.Id)) + ?.GetViewModel; + } + public DirectionViewModel? Insert(DirectionBindingModel model) + { + using var context = new UniversityDatabase(); + var newDirection = Direction.Create(model); + if (newDirection == null) + { + return null; + } + context.Directions.Add(newDirection); + context.SaveChanges(); + return newDirection.GetViewModel; + } + public DirectionViewModel? Update(DirectionBindingModel model) + { + using var context = new UniversityDatabase(); + var direction = context.Directions.FirstOrDefault(rec => rec.Id == model.Id); + if (direction == null) + { + return null; + } + direction.Update(model); + context.SaveChanges(); + return direction.GetViewModel; + } + public DirectionViewModel? Delete(DirectionBindingModel model) + { + using var context = new UniversityDatabase(); + var element = context.Directions + .FirstOrDefault(rec => rec.Id == model.Id); + if (element != null) + { + context.Directions.Remove(element); + context.SaveChanges(); + return element.GetViewModel; + } + return null; + } + } +} diff --git a/UniversityDatabaseImplement/Implements/StudentStorage.cs b/UniversityDatabaseImplement/Implements/StudentStorage.cs new file mode 100644 index 0000000..68fe7ca --- /dev/null +++ b/UniversityDatabaseImplement/Implements/StudentStorage.cs @@ -0,0 +1,81 @@ +using Microsoft.EntityFrameworkCore; +using UniversityContracts.BindingModels; +using UniversityContracts.SearchModels; +using UniversityContracts.StoragesContracts; +using UniversityContracts.ViewModels; +using UniversityDatabaseImplement.Models; + +namespace UniversityDatabaseImplement.Implements +{ + public class StudentStorage : IStudentStorage + { + public List GetFullList() + { + using var context = new UniversityDatabase(); + return context.Students + .Select(x => x.GetViewModel) + .ToList(); + } + public List GetFilteredList(StudentSearchModel model) + { + if (string.IsNullOrEmpty(model.FIO)) + { + return new(); + } + using var context = new UniversityDatabase(); + return context.Students + .Select(x => x.GetViewModel) + .ToList(); + } + public StudentViewModel? GetElement(StudentSearchModel model) + { + if (!model.Id.HasValue) + { + return null; + } + using var context = new UniversityDatabase(); + return context.Students + .FirstOrDefault(x => (!string.IsNullOrEmpty(model.FIO) && + x.FIO == model.FIO) || + (model.Id.HasValue && x.Id == model.Id)) + ?.GetViewModel; + } + public StudentViewModel? Insert(StudentBindingModel model) + { + using var context = new UniversityDatabase(); + var newStudent = Student.Create(model); + if (newStudent == null) + { + return null; + } + context.Students.Add(newStudent); + context.SaveChanges(); + return newStudent.GetViewModel; + } + public StudentViewModel? Update(StudentBindingModel model) + { + using var context = new UniversityDatabase(); + var student = context.Students.FirstOrDefault(rec => rec.Id == model.Id); + if (student == null) + { + return null; + } + student.Update(model); + context.SaveChanges(); + return student.GetViewModel; + } + public StudentViewModel? Delete(StudentBindingModel model) + { + using var context = new UniversityDatabase(); + var element = context.Students + .FirstOrDefault(rec => rec.Id == model.Id); + if (element != null) + { + context.Students.Remove(element); + context.SaveChanges(); + return element.GetViewModel; + } + return null; + } + } +} diff --git a/UniversityDatabaseImplement/Migrations/20231027233645_InitialCreate.Designer.cs b/UniversityDatabaseImplement/Migrations/20231027233645_InitialCreate.Designer.cs new file mode 100644 index 0000000..ee98d04 --- /dev/null +++ b/UniversityDatabaseImplement/Migrations/20231027233645_InitialCreate.Designer.cs @@ -0,0 +1,75 @@ +// +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using UniversityDatabaseImplement; + +#nullable disable + +namespace UniversityDatabaseImplement.Migrations +{ + [DbContext(typeof(UniversityDatabase))] + [Migration("20231027233645_InitialCreate")] + partial class InitialCreate + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.13") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("UniversityDatabaseImplement.Models.Direction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Directions"); + }); + + modelBuilder.Entity("UniversityDatabaseImplement.Models.Student", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("DirectionName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Email") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("FIO") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("PhotoFilePath") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Students"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/UniversityDatabaseImplement/Migrations/20231027233645_InitialCreate.cs b/UniversityDatabaseImplement/Migrations/20231027233645_InitialCreate.cs new file mode 100644 index 0000000..6a1dafc --- /dev/null +++ b/UniversityDatabaseImplement/Migrations/20231027233645_InitialCreate.cs @@ -0,0 +1,53 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace UniversityDatabaseImplement.Migrations +{ + /// + public partial class InitialCreate : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Directions", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Name = table.Column(type: "nvarchar(max)", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Directions", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Students", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + FIO = table.Column(type: "nvarchar(max)", nullable: false), + Email = table.Column(type: "nvarchar(max)", nullable: false), + PhotoFilePath = table.Column(type: "nvarchar(max)", nullable: false), + DirectionName = table.Column(type: "nvarchar(max)", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Students", x => x.Id); + }); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Directions"); + + migrationBuilder.DropTable( + name: "Students"); + } + } +} diff --git a/UniversityDatabaseImplement/Migrations/UniversityDatabaseModelSnapshot.cs b/UniversityDatabaseImplement/Migrations/UniversityDatabaseModelSnapshot.cs new file mode 100644 index 0000000..0430ae5 --- /dev/null +++ b/UniversityDatabaseImplement/Migrations/UniversityDatabaseModelSnapshot.cs @@ -0,0 +1,72 @@ +// +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using UniversityDatabaseImplement; + +#nullable disable + +namespace UniversityDatabaseImplement.Migrations +{ + [DbContext(typeof(UniversityDatabase))] + partial class UniversityDatabaseModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.13") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("UniversityDatabaseImplement.Models.Direction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Directions"); + }); + + modelBuilder.Entity("UniversityDatabaseImplement.Models.Student", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("DirectionName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Email") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("FIO") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("PhotoFilePath") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Students"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/UniversityDatabaseImplement/Models/Direction.cs b/UniversityDatabaseImplement/Models/Direction.cs new file mode 100644 index 0000000..24b1263 --- /dev/null +++ b/UniversityDatabaseImplement/Models/Direction.cs @@ -0,0 +1,48 @@ +using System.ComponentModel.DataAnnotations; +using UniversityDataModels.Models; +using UniversityContracts.BindingModels; +using UniversityContracts.ViewModels; + +namespace UniversityDatabaseImplement.Models +{ + public class Direction : IDirectionModel + { + public int Id { get; private set; } + [Required] + public string Name { get; private set; } = string.Empty; + + public static Direction? Create(DirectionBindingModel model) + { + if (model == null) + { + return null; + } + return new Direction() + { + Id = model.Id, + Name = model.Name + }; + } + public static Direction Create(DirectionViewModel model) + { + return new Direction() + { + Id = model.Id, + Name = model.Name + }; + } + public void Update(DirectionBindingModel model) + { + if (model == null) + { + return; + } + Name = model.Name; + } + public DirectionViewModel GetViewModel => new() + { + Id = Id, + Name = Name + }; + } +} diff --git a/UniversityDatabaseImplement/Models/Student.cs b/UniversityDatabaseImplement/Models/Student.cs new file mode 100644 index 0000000..773b688 --- /dev/null +++ b/UniversityDatabaseImplement/Models/Student.cs @@ -0,0 +1,66 @@ +using System.ComponentModel.DataAnnotations; +using UniversityDataModels.Models; +using UniversityContracts.BindingModels; +using UniversityContracts.ViewModels; + +namespace UniversityDatabaseImplement.Models +{ + public class Student : IStudentModel + { + public int Id { get; private set; } + [Required] + public string FIO { get; private set; } = string.Empty; + [Required] + public string Email { get; private set; } = string.Empty; + [Required] + public string PhotoFilePath { get; private set; } = string.Empty; + [Required] + public string DirectionName { get; private set; } = string.Empty; + + public static Student? Create(StudentBindingModel model) + { + if (model == null) + { + return null; + } + return new Student() + { + Id = model.Id, + FIO = model.FIO, + Email = model.Email, + PhotoFilePath = model.PhotoFilePath, + DirectionName = model.DirectionName + }; + } + public static Student Create(StudentViewModel model) + { + return new Student() + { + Id = model.Id, + FIO = model.FIO, + Email = model.Email, + PhotoFilePath = model.PhotoFilePath, + DirectionName = model.DirectionName + }; + } + public void Update(StudentBindingModel model) + { + if (model == null) + { + return; + } + FIO = model.FIO; + Email = model.Email; + PhotoFilePath = model.PhotoFilePath; + DirectionName = model.DirectionName; + } + public StudentViewModel GetViewModel => new() + { + Id = Id, + FIO = FIO, + Email = Email, + PhotoFilePath = PhotoFilePath, + DirectionName = DirectionName + }; + } +} diff --git a/UniversityDatabaseImplement/UniversityDatabase.cs b/UniversityDatabaseImplement/UniversityDatabase.cs new file mode 100644 index 0000000..877d41b --- /dev/null +++ b/UniversityDatabaseImplement/UniversityDatabase.cs @@ -0,0 +1,19 @@ +using Microsoft.EntityFrameworkCore; +using UniversityDatabaseImplement.Models; + +namespace UniversityDatabaseImplement +{ + public class UniversityDatabase : DbContext + { + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + if (optionsBuilder.IsConfigured == false) + { + optionsBuilder.UseSqlServer(@"Data Source=DESKTOP-IHH1ICP\SQLEXPRESS;Initial Catalog=UniversityDatabaseFull;Integrated Security=True;MultipleActiveResultSets=True;TrustServerCertificate=True"); + } + base.OnConfiguring(optionsBuilder); + } + public virtual DbSet Students { set; get; } + public virtual DbSet Directions { set; get; } + } +} diff --git a/UniversityDatabaseImplement/UniversityDatabaseImplement.csproj b/UniversityDatabaseImplement/UniversityDatabaseImplement.csproj new file mode 100644 index 0000000..89fd487 --- /dev/null +++ b/UniversityDatabaseImplement/UniversityDatabaseImplement.csproj @@ -0,0 +1,24 @@ + + + + net6.0-windows + enable + true + enable + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + diff --git a/UniversityView/FormHandbooks.Designer.cs b/UniversityView/FormHandbooks.Designer.cs new file mode 100644 index 0000000..7038959 --- /dev/null +++ b/UniversityView/FormHandbooks.Designer.cs @@ -0,0 +1,66 @@ +namespace UniversityView +{ + partial class FormHandbooks + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.dataGridView = new System.Windows.Forms.DataGridView(); + ((System.ComponentModel.ISupportInitialize)(this.dataGridView)).BeginInit(); + this.SuspendLayout(); + // + // dataGridView + // + this.dataGridView.BackgroundColor = System.Drawing.SystemColors.Control; + this.dataGridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; + this.dataGridView.Dock = System.Windows.Forms.DockStyle.Fill; + this.dataGridView.Location = new System.Drawing.Point(0, 0); + this.dataGridView.Name = "dataGridView"; + this.dataGridView.RowTemplate.Height = 25; + this.dataGridView.Size = new System.Drawing.Size(429, 297); + this.dataGridView.TabIndex = 0; + this.dataGridView.CellEndEdit += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridView_CellEndEdit); + this.dataGridView.KeyDown += new System.Windows.Forms.KeyEventHandler(this.dataGridView_KeyDown); + // + // FormHandbooks + // + this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(429, 297); + this.Controls.Add(this.dataGridView); + this.Name = "FormHandbooks"; + this.Text = "Направления"; + this.Load += new System.EventHandler(this.FormHandbooks_Load); + ((System.ComponentModel.ISupportInitialize)(this.dataGridView)).EndInit(); + this.ResumeLayout(false); + + } + + #endregion + + private DataGridView dataGridView; + } +} \ No newline at end of file diff --git a/UniversityView/FormHandbooks.cs b/UniversityView/FormHandbooks.cs new file mode 100644 index 0000000..834d5cf --- /dev/null +++ b/UniversityView/FormHandbooks.cs @@ -0,0 +1,110 @@ +using System.ComponentModel; +using UniversityContracts.BindingModels; +using UniversityContracts.BusinessLogicsContracts; + +namespace UniversityView +{ + public partial class FormHandbooks : Form + { + private readonly IDirectionLogic _logic; + BindingList _list; + private int? _id; + public int Id { set { _id = value; } } + public FormHandbooks(IDirectionLogic logic) + { + InitializeComponent(); + _logic = logic; + _list = new BindingList(); + dataGridView.AllowUserToAddRows = false; + } + + private void FormHandbooks_Load(object sender, EventArgs e) + { + LoadData(); + } + private void LoadData() + { + try + { + var list = _logic.ReadList(null); + _list.Clear(); + foreach (var item in list) + { + _list.Add(new DirectionBindingModel + { + Id = item.Id, + Name = item.Name, + }); + } + if (_list != null) + { + dataGridView.DataSource = _list; + dataGridView.Columns[0].Visible = false; + dataGridView.Columns[1].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; + } + } + catch (Exception ex) + { + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + private void dataGridView_CellEndEdit(object sender, DataGridViewCellEventArgs e) + { + var typeName = (string)dataGridView.CurrentRow.Cells[1].Value; + if (!string.IsNullOrEmpty(typeName)) + { + if (dataGridView.CurrentRow.Cells[0].Value != null) + { + _logic.CreateOrUpdate(new DirectionBindingModel() + { + Id = Convert.ToInt32(dataGridView.CurrentRow.Cells[0].Value), + Name = (string)dataGridView.CurrentRow.Cells[1].EditedFormattedValue + }); + } + else + { + _logic.CreateOrUpdate(new DirectionBindingModel() + { + Name = (string)dataGridView.CurrentRow.Cells[1].EditedFormattedValue + }); + } + } + else + { + MessageBox.Show("Введена пустая строка", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + LoadData(); + } + + private void dataGridView_KeyDown(object sender, KeyEventArgs e) + { + if (e.KeyData == Keys.Insert) + { + if (dataGridView.Rows.Count == 0) + { + _list.Add(new DirectionBindingModel()); + dataGridView.DataSource = new BindingList(_list); + dataGridView.CurrentCell = dataGridView.Rows[0].Cells[1]; + return; + } + if (dataGridView.Rows[dataGridView.Rows.Count - 1].Cells[1].Value != null) + { + _list.Add(new DirectionBindingModel()); + dataGridView.DataSource = new BindingList(_list); + dataGridView.CurrentCell = dataGridView.Rows[dataGridView.Rows.Count - 1].Cells[1]; + return; + } + } + if (e.KeyData == Keys.Delete) + { + if (MessageBox.Show("Удалить выбранный элемент", "Удаление", + MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) + { + _logic.Delete(new DirectionBindingModel() { Id = (int)dataGridView.CurrentRow.Cells[0].Value }); + LoadData(); + } + } + } + } +} diff --git a/UniversityView/FormHandbooks.resx b/UniversityView/FormHandbooks.resx new file mode 100644 index 0000000..f298a7b --- /dev/null +++ b/UniversityView/FormHandbooks.resx @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/UniversityView/FormMain.Designer.cs b/UniversityView/FormMain.Designer.cs new file mode 100644 index 0000000..9b58c4f --- /dev/null +++ b/UniversityView/FormMain.Designer.cs @@ -0,0 +1,154 @@ +namespace UniversityView +{ + partial class FormMain + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.tableOfValues = new WinFormsControlLibrary.TableOfValues(); + this.contextMenuStrip = new System.Windows.Forms.ContextMenuStrip(this.components); + this.создатьToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.изменитьToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.удалитьToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.справочникиToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.создатьПростойДокументToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.создатьДокументСТаблицейToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.создатьДокументСДиаграммойToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.excelComponent = new COP.ExcelComponent(this.components); + this.gistogramPdfComponent = new WinFormsControlLibrary.GistogramPdfComponent3(this.components); + this.contextMenuStrip.SuspendLayout(); + this.SuspendLayout(); + // + // tableOfValues + // + this.tableOfValues.ContextMenuStrip = this.contextMenuStrip; + this.tableOfValues.Dock = System.Windows.Forms.DockStyle.Fill; + this.tableOfValues.Location = new System.Drawing.Point(0, 0); + this.tableOfValues.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2); + this.tableOfValues.Name = "tableOfValues"; + this.tableOfValues.SelectedRowIndex = -1; + this.tableOfValues.Size = new System.Drawing.Size(405, 302); + this.tableOfValues.TabIndex = 0; + // + // contextMenuStrip + // + this.contextMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.создатьToolStripMenuItem, + this.изменитьToolStripMenuItem, + this.удалитьToolStripMenuItem, + this.справочникиToolStripMenuItem, + this.создатьПростойДокументToolStripMenuItem, + this.создатьДокументСТаблицейToolStripMenuItem, + this.создатьДокументСДиаграммойToolStripMenuItem}); + this.contextMenuStrip.Name = "contextMenuStrip"; + this.contextMenuStrip.Size = new System.Drawing.Size(296, 180); + // + // создатьToolStripMenuItem + // + this.создатьToolStripMenuItem.Name = "создатьToolStripMenuItem"; + this.создатьToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.A))); + this.создатьToolStripMenuItem.Size = new System.Drawing.Size(295, 22); + this.создатьToolStripMenuItem.Text = "Создать"; + this.создатьToolStripMenuItem.Click += new System.EventHandler(this.СоздатьToolStripMenuItem_Click); + // + // изменитьToolStripMenuItem + // + this.изменитьToolStripMenuItem.Name = "изменитьToolStripMenuItem"; + this.изменитьToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.U))); + this.изменитьToolStripMenuItem.Size = new System.Drawing.Size(295, 22); + this.изменитьToolStripMenuItem.Text = "Изменить"; + this.изменитьToolStripMenuItem.Click += new System.EventHandler(this.ИзменитьToolStripMenuItem_Click); + // + // удалитьToolStripMenuItem + // + this.удалитьToolStripMenuItem.Name = "удалитьToolStripMenuItem"; + this.удалитьToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.D))); + this.удалитьToolStripMenuItem.Size = new System.Drawing.Size(295, 22); + this.удалитьToolStripMenuItem.Text = "Удалить"; + this.удалитьToolStripMenuItem.Click += new System.EventHandler(this.УдалитьToolStripMenuItem_Click); + // + // справочникиToolStripMenuItem + // + this.справочникиToolStripMenuItem.Name = "справочникиToolStripMenuItem"; + this.справочникиToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.O))); + this.справочникиToolStripMenuItem.Size = new System.Drawing.Size(295, 22); + this.справочникиToolStripMenuItem.Text = "Справочники"; + this.справочникиToolStripMenuItem.Click += new System.EventHandler(this.СправочникиToolStripMenuItem_Click); + // + // создатьПростойДокументToolStripMenuItem + // + this.создатьПростойДокументToolStripMenuItem.Name = "создатьПростойДокументToolStripMenuItem"; + this.создатьПростойДокументToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.S))); + this.создатьПростойДокументToolStripMenuItem.Size = new System.Drawing.Size(295, 22); + this.создатьПростойДокументToolStripMenuItem.Text = "Создать простой документ"; + this.создатьПростойДокументToolStripMenuItem.Click += new System.EventHandler(this.СоздатьПростойДокументToolStripMenuItem_Click); + // + // создатьДокументСТаблицейToolStripMenuItem + // + this.создатьДокументСТаблицейToolStripMenuItem.Name = "создатьДокументСТаблицейToolStripMenuItem"; + this.создатьДокументСТаблицейToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.T))); + this.создатьДокументСТаблицейToolStripMenuItem.Size = new System.Drawing.Size(295, 22); + this.создатьДокументСТаблицейToolStripMenuItem.Text = "Создать документ с таблицей"; + this.создатьДокументСТаблицейToolStripMenuItem.Click += new System.EventHandler(this.СоздатьДокументСТаблицейToolStripMenuItem_Click); + // + // создатьДокументСДиаграммойToolStripMenuItem + // + this.создатьДокументСДиаграммойToolStripMenuItem.Name = "создатьДокументСДиаграммойToolStripMenuItem"; + this.создатьДокументСДиаграммойToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.C))); + this.создатьДокументСДиаграммойToolStripMenuItem.Size = new System.Drawing.Size(295, 22); + this.создатьДокументСДиаграммойToolStripMenuItem.Text = "Создать документ с диаграммой"; + this.создатьДокументСДиаграммойToolStripMenuItem.Click += new System.EventHandler(this.СоздатьДокументСДиаграммойToolStripMenuItem_Click); + // + // FormMain + // + this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(405, 302); + this.Controls.Add(this.tableOfValues); + this.Name = "FormMain"; + this.Text = "Университет"; + this.Load += new System.EventHandler(this.FormMain_Load); + this.contextMenuStrip.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private WinFormsControlLibrary.TableOfValues tableOfValues; + private ContextMenuStrip contextMenuStrip; + private ToolStripMenuItem создатьToolStripMenuItem; + private ToolStripMenuItem изменитьToolStripMenuItem; + private ToolStripMenuItem удалитьToolStripMenuItem; + private ToolStripMenuItem создатьПростойДокументToolStripMenuItem; + private ToolStripMenuItem создатьДокументСТаблицейToolStripMenuItem; + private ToolStripMenuItem создатьДокументСДиаграммойToolStripMenuItem; + private ToolStripMenuItem справочникиToolStripMenuItem; + private COP.ExcelComponent excelComponent; + private WinFormsControlLibrary.GistogramPdfComponent3 gistogramPdfComponent; + } +} \ No newline at end of file diff --git a/UniversityView/FormMain.cs b/UniversityView/FormMain.cs new file mode 100644 index 0000000..3c1081c --- /dev/null +++ b/UniversityView/FormMain.cs @@ -0,0 +1,177 @@ +using COP.Info; +using DocumentFormat.OpenXml.Office2016.Drawing.ChartDrawing; +using DocumentFormat.OpenXml.Spreadsheet; +using Microsoft.Extensions.Logging; +using System.Windows.Forms; +using UniversityBusinessLogic.BusinessLogics; +using UniversityContracts.BindingModels; +using UniversityContracts.BusinessLogicsContracts; +using WinFormsControlLibrary; +using static COP.ExcelComponent; +using static System.Windows.Forms.VisualStyles.VisualStyleElement.Window; + +namespace UniversityView +{ + public partial class FormMain : Form + { + private readonly ILogger _logger; + private readonly IStudentLogic _studentLogic; + private readonly IDirectionLogic _directionLogic; + public FormMain(ILogger logger, IStudentLogic studentLogic, IDirectionLogic directionLogic) + { + InitializeComponent(); + _logger = logger; + _studentLogic = studentLogic; + _directionLogic = directionLogic; + Configure(); +; } + + private void LoadData() + { + _logger.LogInformation("Загрузка студентов"); + try + { + tableOfValues.ClearRows(); + var list = _studentLogic.ReadList(null); + if (list != null) + { + tableOfValues.SetCellValueFromList(list); + } + _logger.LogInformation("Загрузка студентов"); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка загрузки студентов"); + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + private void FormMain_Load(object sender, EventArgs e) + { + LoadData(); + } + + private void СоздатьToolStripMenuItem_Click(object sender, EventArgs e) + { + var service = Program.ServiceProvider?.GetService(typeof(FormStudent)); + if (service is FormStudent form) + { + form.ShowDialog(); + } + LoadData(); + } + + private void Configure() + { + var columnConfigs = new List + { + new GridColumnConfig { HeaderText = "ФИО", Width = 100, Visible = true, PropertyName = "FIO" }, + new GridColumnConfig { HeaderText = "Направление", Width = 80, Visible = true, PropertyName = "DirectionName" }, + new GridColumnConfig { HeaderText = "Электронная почта", Width = 80, Visible = true, PropertyName = "Email" }, + }; + + tableOfValues.ConfigureColumns(columnConfigs); + } + + private void ИзменитьToolStripMenuItem_Click(object sender, EventArgs e) + { + } + + private void УдалитьToolStripMenuItem_Click(object sender, EventArgs e) + { + DialogResult dialogResult = MessageBox.Show("Удалить выбранный элемент?", "Вопрос", MessageBoxButtons.YesNo, MessageBoxIcon.Question); + if (dialogResult == DialogResult.Yes) + _studentLogic.Delete(new StudentBindingModel { Id = tableOfValues.SelectedRowIndex }); + LoadData(); + } + + private void СоздатьПростойДокументToolStripMenuItem_Click(object sender, EventArgs e) + { + var list = _studentLogic.ReadList(null); + List images = new(); + using var dialog = new SaveFileDialog + { + Filter = "xlsx|*.xlsx" + }; + if (dialog.ShowDialog() == DialogResult.OK) + { + try + { + if (list != null) + { + foreach (var item in list) + { + images.Add(new ImageInfo() { FilePath = item.PhotoFilePath }); + } + } + ExcelImageInfo info = new(dialog.FileName, "Документ с фотографиями студентов", images); + excelComponent.GenerateExcelWithImages(info); + MessageBox.Show("Сохарнено успешно", "Результат", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + catch (Exception ex) + { + MessageBox.Show(ex.Message, "Ошибка", + MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + } + + private void СоздатьДокументСТаблицейToolStripMenuItem_Click(object sender, EventArgs e) + { + + } + + private void СоздатьДокументСДиаграммойToolStripMenuItem_Click(object sender, EventArgs e) + { + var listStudents = _studentLogic.ReadList(null); + var listDirections = _directionLogic.ReadList(null); + List<(string, int)> data = new(); + List gistData = new(); + using var dialog = new SaveFileDialog + { + Filter = "pdf|*.pdf" + }; + if (dialog.ShowDialog() == DialogResult.OK) + { + try + { + for (int i = 0; i < listDirections.Count; i++) + { + int count = 0; + for (int j = 0; j < listStudents.Count; j++) + { + if (listStudents[j].DirectionName == listDirections[i].Name) count++; + } + data.Add((listDirections[i].Name, count)); + } + if (data != null) { + foreach (var item in data) + { + gistData.Add(new HistogramData + { + SeriesName = item.Item1, + Data = new double[] { item.Item2 } + }); + } + } + gistogramPdfComponent.GenerateHistogramDocument(dialog.FileName, "Histogram", "Students-Directions", LegendPosition.TopRight, gistData); + MessageBox.Show("Сохарнено успешно", "Результат", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + catch (Exception ex) + { + MessageBox.Show(ex.Message, "Ошибка", + MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + } + + private void СправочникиToolStripMenuItem_Click(object sender, EventArgs e) + { + var service = Program.ServiceProvider?.GetService(typeof(FormHandbooks)); + if (service is FormHandbooks form) + { + form.ShowDialog(); + } + } + } +} diff --git a/UniversityView/FormMain.resx b/UniversityView/FormMain.resx new file mode 100644 index 0000000..8b51eef --- /dev/null +++ b/UniversityView/FormMain.resx @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + 166, 17 + + + 309, 17 + + \ No newline at end of file diff --git a/UniversityView/FormStudent.Designer.cs b/UniversityView/FormStudent.Designer.cs new file mode 100644 index 0000000..cc00368 --- /dev/null +++ b/UniversityView/FormStudent.Designer.cs @@ -0,0 +1,174 @@ +namespace UniversityView +{ + partial class FormStudent + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.textBoxFIO = new System.Windows.Forms.TextBox(); + this.label1 = new System.Windows.Forms.Label(); + this.label2 = new System.Windows.Forms.Label(); + this.componenttBox1 = new COPWinForms.ComponentTBox(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.userCheckedListBox1 = new COP.UserCheckedListBox(); + this.buttonSave = new System.Windows.Forms.Button(); + this.buttonCancel = new System.Windows.Forms.Button(); + this.buttonAddPhoto = new System.Windows.Forms.Button(); + this.pictureBox = new System.Windows.Forms.PictureBox(); + this.groupBox1.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox)).BeginInit(); + this.SuspendLayout(); + // + // textBoxFIO + // + this.textBoxFIO.Location = new System.Drawing.Point(105, 27); + this.textBoxFIO.Name = "textBoxFIO"; + this.textBoxFIO.Size = new System.Drawing.Size(214, 23); + this.textBoxFIO.TabIndex = 0; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(65, 30); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(34, 15); + this.label1.TabIndex = 1; + this.label1.Text = "ФИО"; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(65, 68); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(113, 15); + this.label2.TabIndex = 3; + this.label2.Text = "Электронная почта"; + // + // componenttBox1 + // + this.componenttBox1.Location = new System.Drawing.Point(184, 65); + this.componenttBox1.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); + this.componenttBox1.Name = "componenttBox1"; + this.componenttBox1.Pattern = null; + this.componenttBox1.Size = new System.Drawing.Size(135, 38); + this.componenttBox1.TabIndex = 4; + this.componenttBox1.TextBoxValue = null; + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.userCheckedListBox1); + this.groupBox1.Location = new System.Drawing.Point(12, 108); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(362, 150); + this.groupBox1.TabIndex = 5; + this.groupBox1.TabStop = false; + this.groupBox1.Text = "Направление"; + // + // userCheckedListBox1 + // + this.userCheckedListBox1.Dock = System.Windows.Forms.DockStyle.Fill; + this.userCheckedListBox1.Location = new System.Drawing.Point(3, 19); + this.userCheckedListBox1.Name = "userCheckedListBox1"; + this.userCheckedListBox1.SelectedValue = ""; + this.userCheckedListBox1.Size = new System.Drawing.Size(356, 128); + this.userCheckedListBox1.TabIndex = 0; + // + // buttonSave + // + this.buttonSave.Location = new System.Drawing.Point(218, 465); + this.buttonSave.Name = "buttonSave"; + this.buttonSave.Size = new System.Drawing.Size(75, 23); + this.buttonSave.TabIndex = 6; + this.buttonSave.Text = "Сохранить"; + this.buttonSave.UseVisualStyleBackColor = true; + this.buttonSave.Click += new System.EventHandler(this.buttonSave_Click); + // + // buttonCancel + // + this.buttonCancel.Location = new System.Drawing.Point(299, 465); + this.buttonCancel.Name = "buttonCancel"; + this.buttonCancel.Size = new System.Drawing.Size(75, 23); + this.buttonCancel.TabIndex = 7; + this.buttonCancel.Text = "Отмена"; + this.buttonCancel.UseVisualStyleBackColor = true; + this.buttonCancel.Click += new System.EventHandler(this.buttonCancel_Click); + // + // buttonAddPhoto + // + this.buttonAddPhoto.Location = new System.Drawing.Point(12, 264); + this.buttonAddPhoto.Name = "buttonAddPhoto"; + this.buttonAddPhoto.Size = new System.Drawing.Size(360, 23); + this.buttonAddPhoto.TabIndex = 8; + this.buttonAddPhoto.Text = "Загрузить фото"; + this.buttonAddPhoto.UseVisualStyleBackColor = true; + this.buttonAddPhoto.Click += new System.EventHandler(this.buttonAddPhoto_Click); + // + // pictureBox + // + this.pictureBox.Location = new System.Drawing.Point(12, 293); + this.pictureBox.Name = "pictureBox"; + this.pictureBox.Size = new System.Drawing.Size(359, 166); + this.pictureBox.TabIndex = 9; + this.pictureBox.TabStop = false; + // + // FormStudent + // + this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(384, 500); + this.Controls.Add(this.pictureBox); + this.Controls.Add(this.buttonAddPhoto); + this.Controls.Add(this.buttonCancel); + this.Controls.Add(this.buttonSave); + this.Controls.Add(this.groupBox1); + this.Controls.Add(this.componenttBox1); + this.Controls.Add(this.label2); + this.Controls.Add(this.label1); + this.Controls.Add(this.textBoxFIO); + this.Name = "FormStudent"; + this.Text = "Студент"; + this.Load += new System.EventHandler(this.FormStudent_Load); + this.groupBox1.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox)).EndInit(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private TextBox textBoxFIO; + private Label label1; + private Label label2; + private COPWinForms.ComponentTBox componenttBox1; + private GroupBox groupBox1; + private Button buttonSave; + private Button buttonCancel; + private COP.UserCheckedListBox userCheckedListBox1; + private Button buttonAddPhoto; + private PictureBox pictureBox; + } +} \ No newline at end of file diff --git a/UniversityView/FormStudent.cs b/UniversityView/FormStudent.cs new file mode 100644 index 0000000..cab5796 --- /dev/null +++ b/UniversityView/FormStudent.cs @@ -0,0 +1,134 @@ +using Microsoft.Extensions.Logging; +using System.ComponentModel; +using UniversityContracts.BindingModels; +using UniversityContracts.BusinessLogicsContracts; + +namespace UniversityView +{ + public partial class FormStudent : Form + { + private readonly ILogger _logger; + private readonly IStudentLogic _studentLogic; + private readonly IDirectionLogic _directionLogic; + private string imagePath; + BindingList _list; + private int? _id; + public int Id { set { _id = value; } } + List directions = new(); + public FormStudent(ILogger logger, IStudentLogic studentLogic, IDirectionLogic directionLogic) + { + InitializeComponent(); + _logger = logger; + _studentLogic = studentLogic; + _directionLogic = directionLogic; + imagePath = ""; + _list = new BindingList(); + componenttBox1.Pattern = @"^([\w\.\-]+)@([\w\-]+)((\.(\w){2,3})+)$"; + componenttBox1.setExample("example@mail.ru"); + } + + private void buttonSave_Click(object sender, EventArgs e) + { + if (string.IsNullOrEmpty(textBoxFIO.Text)) + { + MessageBox.Show("Заполните ФИО", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + if (string.IsNullOrEmpty(componenttBox1.TextBoxValue)) + { + MessageBox.Show("Заполните электронную почту", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + if (userCheckedListBox1.SelectedValue == null) + { + MessageBox.Show("Заполните направление", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + if (pictureBox.Image == null) + { + MessageBox.Show("Загрузите фото", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + _logger.LogInformation("Сохранение студента"); + try + { + var model = new StudentBindingModel + { + Id = _id ?? 0, + FIO = textBoxFIO.Text, + Email = componenttBox1.TextBoxValue, + PhotoFilePath = imagePath, + DirectionName = userCheckedListBox1.SelectedValue + }; + var operationResult = _id.HasValue ? _studentLogic.Update(model) : _studentLogic.Create(model); + if (!operationResult) + { + throw new Exception("Ошибка при сохранении. Дополнительная информация в логах."); + } + MessageBox.Show("Сохранение прошло успешно", "Сообщение", MessageBoxButtons.OK, MessageBoxIcon.Information); + DialogResult = DialogResult.OK; + Close(); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка сохранения студента"); + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + private void buttonCancel_Click(object sender, EventArgs e) + { + DialogResult = DialogResult.Cancel; + Close(); + } + + private void FormStudent_Load(object sender, EventArgs e) + { + LoadData(); + } + + private void LoadData() + { + _logger.LogInformation("Загрузка направлений"); + try + { + var list = _directionLogic.ReadList(null); + userCheckedListBox1.ClearList(); + directions.Clear(); + _list.Clear(); + if (list != null) + { + foreach (var item in list) + { + directions.Add(item.Name); + _list.Add(new DirectionBindingModel + { + Id = item.Id, + Name = item.Name, + }); + } + } + userCheckedListBox1.FillList(directions); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка загрузки направлений"); + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + private void buttonAddPhoto_Click(object sender, EventArgs e) + { + OpenFileDialog openFileDialog = new() + { + Filter = "Image Files(*.BMP;*.JPG;*.GIF;*.PNG)|*.BMP;*.JPG;*.GIF;*.PNG|All files (*.*)|*.*" + }; + + if (openFileDialog.ShowDialog() == DialogResult.OK) + { + imagePath = openFileDialog.FileName; + pictureBox.Image = Image.FromFile(imagePath); + } + } + } +} diff --git a/UniversityView/FormStudent.resx b/UniversityView/FormStudent.resx new file mode 100644 index 0000000..f298a7b --- /dev/null +++ b/UniversityView/FormStudent.resx @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/UniversityView/Program.cs b/UniversityView/Program.cs new file mode 100644 index 0000000..73ec1ab --- /dev/null +++ b/UniversityView/Program.cs @@ -0,0 +1,43 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using NLog.Extensions.Logging; +using System; +using UniversityBusinessLogic.BusinessLogics; +using UniversityContracts.BusinessLogicsContracts; +using UniversityContracts.StoragesContracts; +using UniversityDatabaseImplement.Implements; + +namespace UniversityView +{ + internal static class Program + { + private static ServiceProvider? _serviceProvider; + public static ServiceProvider? ServiceProvider => _serviceProvider; + + [STAThread] + static void Main() + { + ApplicationConfiguration.Initialize(); + var services = new ServiceCollection(); + ConfigureServices(services); + _serviceProvider = services.BuildServiceProvider(); + Application.Run(_serviceProvider.GetRequiredService()); + } + + private static void ConfigureServices(ServiceCollection services) + { + services.AddLogging(option => + { + option.SetMinimumLevel(LogLevel.Information); + option.AddNLog("nlog.config"); + }); + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + } + } +} \ No newline at end of file diff --git a/UniversityView/Properties/Resources.Designer.cs b/UniversityView/Properties/Resources.Designer.cs new file mode 100644 index 0000000..3ee9f5d --- /dev/null +++ b/UniversityView/Properties/Resources.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// Этот код создан программой. +// Исполняемая версия:4.0.30319.42000 +// +// Изменения в этом файле могут привести к неправильной работе и будут потеряны в случае +// повторной генерации кода. +// +//------------------------------------------------------------------------------ + +namespace UniversityView.Properties { + using System; + + + /// + /// Класс ресурса со строгой типизацией для поиска локализованных строк и т.д. + /// + // Этот класс создан автоматически классом StronglyTypedResourceBuilder + // с помощью такого средства, как ResGen или Visual Studio. + // Чтобы добавить или удалить член, измените файл .ResX и снова запустите ResGen + // с параметром /str или перестройте свой проект VS. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Возвращает кэшированный экземпляр ResourceManager, использованный этим классом. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("UniversityView.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Перезаписывает свойство CurrentUICulture текущего потока для всех + /// обращений к ресурсу с помощью этого класса ресурса со строгой типизацией. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/UniversityView/Properties/Resources.resx b/UniversityView/Properties/Resources.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/UniversityView/Properties/Resources.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/UniversityView/UniversityView.csproj b/UniversityView/UniversityView.csproj new file mode 100644 index 0000000..83eb141 --- /dev/null +++ b/UniversityView/UniversityView.csproj @@ -0,0 +1,46 @@ + + + + WinExe + net6.0-windows + enable + true + enable + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + + + + + + + True + True + Resources.resx + + + + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + \ No newline at end of file