From db7680b8ec066975fbfc2ab3c8dff53c52c50886 Mon Sep 17 00:00:00 2001 From: Class_Student Date: Wed, 4 Dec 2024 10:24:43 +0300 Subject: [PATCH] hello --- 123.sln | 11 ++ 123/Data/LocalData/Entity/Presence.cs | 2 +- 123/Data/LocalData/Entity/User.cs | 10 +- 123/Data/LocalData/LocalStaticData.cs | 12 +- .../RemoteData/RemoteDatabase/DAO/Presence.cs | 2 +- .../RemoteDatabase/RemoteDatabaseContext.cs | 8 +- 123/Data/ReportsHistory/GroupRepositoty.cs | 33 ----- 123/Data/Repository/GroupRepositoty.cs | 10 ++ 123/Data/Repository/IGroupRepository.cs | 2 +- 123/Data/Repository/IPresenceRepository.cs | 5 +- 123/Data/Repository/IUserRepository.cs | 10 +- 123/Data/Repository/PresenceRepository.cs | 21 ++- 123/Data/Repository/SQLGroupRepository.cs | 27 ++-- 123/Data/Repository/SQLPresenceRepository.cs | 13 +- 123/Data/Repository/SQLUserRepository.cs | 13 +- 123/Data/Repository/UserRepositoty.cs | 40 +++--- 123/Demo.csproj | 1 + 123/Domain/Models/User.cs | 2 +- 123/Domain/UseCase/GroupUseCase.cs | 10 +- 123/Domain/UseCase/PresenceUseCase.cs | 68 ++++++--- 123/Domain/UseCase/UseCaseGeneratePresence.cs | 4 +- 123/Domain/UseCase/UserUseCase.cs | 30 ++-- .../20241118090715_InitialCreate.Designer.cs | 118 +++++++++++++++ .../20241118090715_InitialCreate.cs | 88 ++++++++++++ .../RemoteDatabaseContextModelSnapshot.cs | 115 +++++++++++++++ 123/Program.cs | 11 +- 123/UI/GroupConsole.cs | 12 +- 123/UI/MainMenu.cs | 4 +- 123/UI/PresenceConsole.cs | 135 +++++++++++++++--- 123/UI/UserConsole.cs | 2 +- 123/presence/console/Class1.cs | 6 + 123/presence/console/console.csproj | 9 ++ .../GroupController.cs/GroupController.cs | 10 ++ 123/presence_api/Program.cs | 44 ++++++ .../Properties/launchSettings.json | 41 ++++++ 123/presence_api/appsettings.Development.json | 8 ++ 123/presence_api/appsettings.json | 9 ++ 123/presence_api/presence_api.csproj | 18 +++ 123/presence_api/presence_api.http | 6 + 39 files changed, 773 insertions(+), 197 deletions(-) delete mode 100644 123/Data/ReportsHistory/GroupRepositoty.cs create mode 100644 123/Migrations/20241118090715_InitialCreate.Designer.cs create mode 100644 123/Migrations/20241118090715_InitialCreate.cs create mode 100644 123/Migrations/RemoteDatabaseContextModelSnapshot.cs create mode 100644 123/presence/console/Class1.cs create mode 100644 123/presence/console/console.csproj create mode 100644 123/presence_api/Controllers/GroupController.cs/GroupController.cs create mode 100644 123/presence_api/Program.cs create mode 100644 123/presence_api/Properties/launchSettings.json create mode 100644 123/presence_api/appsettings.Development.json create mode 100644 123/presence_api/appsettings.json create mode 100644 123/presence_api/presence_api.csproj create mode 100644 123/presence_api/presence_api.http diff --git a/123.sln b/123.sln index b6a511f..96b5e0f 100644 --- a/123.sln +++ b/123.sln @@ -5,6 +5,10 @@ VisualStudioVersion = 17.11.35312.102 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Demo", "123\Demo.csproj", "{5A6EDB7C-E5C5-4FCD-B6CE-7E131BD9EDA3}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "123", "123", "{C10296D5-B348-4B12-B15C-226DD4F1C7EB}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "presence_api", "123\presence_api\presence_api.csproj", "{1BCA5E0B-EF97-421C-AC72-0655BB7AEF7B}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -15,6 +19,10 @@ Global {5A6EDB7C-E5C5-4FCD-B6CE-7E131BD9EDA3}.Debug|Any CPU.Build.0 = Debug|Any CPU {5A6EDB7C-E5C5-4FCD-B6CE-7E131BD9EDA3}.Release|Any CPU.ActiveCfg = Release|Any CPU {5A6EDB7C-E5C5-4FCD-B6CE-7E131BD9EDA3}.Release|Any CPU.Build.0 = Release|Any CPU + {1BCA5E0B-EF97-421C-AC72-0655BB7AEF7B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1BCA5E0B-EF97-421C-AC72-0655BB7AEF7B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1BCA5E0B-EF97-421C-AC72-0655BB7AEF7B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1BCA5E0B-EF97-421C-AC72-0655BB7AEF7B}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -22,4 +30,7 @@ Global GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B3D7FA9B-E7AA-4A2B-8D13-416D51577CB6} EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {1BCA5E0B-EF97-421C-AC72-0655BB7AEF7B} = {C10296D5-B348-4B12-B15C-226DD4F1C7EB} + EndGlobalSection EndGlobal diff --git a/123/Data/LocalData/Entity/Presence.cs b/123/Data/LocalData/Entity/Presence.cs index fcaeeb0..86922a3 100644 --- a/123/Data/LocalData/Entity/Presence.cs +++ b/123/Data/LocalData/Entity/Presence.cs @@ -8,7 +8,7 @@ namespace _123.Data.LocalData.Entity { public class PresenceLocalEntity { - public required Guid UserGuid { get; set; } + public required int UserID { get; set; } public bool IsAttedance { get; set; } = true; public required DateOnly Date { get; set; } diff --git a/123/Data/LocalData/Entity/User.cs b/123/Data/LocalData/Entity/User.cs index f6284e7..ba6d84f 100644 --- a/123/Data/LocalData/Entity/User.cs +++ b/123/Data/LocalData/Entity/User.cs @@ -6,16 +6,12 @@ using System.Threading.Tasks; namespace _123.Data.LocalData.Entity { - public class UserLocalEntity : IEquatable + public class UserLocalEntity { public required string UserFIO { get; set; } - public Guid UserGuid { get; set; } + public int UserId { get; set; } public required int GroupID { get; set; } - public bool Equals(UserLocalEntity? other) - { - if (other == null) return false; - return this.UserGuid.Equals(other.UserGuid); - } + } } diff --git a/123/Data/LocalData/LocalStaticData.cs b/123/Data/LocalData/LocalStaticData.cs index 3ab7aad..b312e30 100644 --- a/123/Data/LocalData/LocalStaticData.cs +++ b/123/Data/LocalData/LocalStaticData.cs @@ -18,12 +18,12 @@ namespace _123.Data.LocalData }; public static List users => new List { - new UserLocalEntity{UserGuid=Guid.Parse("e6b9964d-ea9f-420a-84b9-af9633bbfab9"), UserFIO = "RandomFio", GroupID = 1 }, - new UserLocalEntity{UserGuid=Guid.Parse("8388d931-5bef-41be-a152-78f1aca980ed"), UserFIO = "RandomFio1", GroupID = 2 }, - new UserLocalEntity{UserGuid=Guid.Parse("ed174548-49ed-4503-a902-c970cbf27173"), UserFIO = "RandomFio2", GroupID = 3 }, - new UserLocalEntity{UserGuid=Guid.Parse("614c0a23-5bd5-43ae-b48e-d5750afbc282"), UserFIO = "RandomFio3", GroupID = 1 }, - new UserLocalEntity{UserGuid=Guid.Parse("efcc1473-c116-4244-b3f7-f2341a5c3003"), UserFIO = "RandomFio4", GroupID = 2 }, - new UserLocalEntity{UserGuid=Guid.Parse("60640fb3-ace2-4cad-81d5-a0a58bc2dbbd"), UserFIO = "RandomFio5", GroupID = 3 }, + new UserLocalEntity{UserId = 1, UserFIO = "RandomFio", GroupID = 1 }, + new UserLocalEntity{UserId = 2, UserFIO = "RandomFio1", GroupID = 2 }, + new UserLocalEntity{UserId = 3, UserFIO = "RandomFio2", GroupID = 3 }, + new UserLocalEntity{UserId = 4, UserFIO = "RandomFio3", GroupID = 1 }, + new UserLocalEntity{UserId = 5, UserFIO = "RandomFio4", GroupID = 2 }, + new UserLocalEntity{UserId = 6, UserFIO = "RandomFio5", GroupID = 3 }, }; public static List presences => new List { diff --git a/123/Data/RemoteData/RemoteDatabase/DAO/Presence.cs b/123/Data/RemoteData/RemoteDatabase/DAO/Presence.cs index 4e97fd0..1c10072 100644 --- a/123/Data/RemoteData/RemoteDatabase/DAO/Presence.cs +++ b/123/Data/RemoteData/RemoteDatabase/DAO/Presence.cs @@ -13,7 +13,7 @@ namespace _123.Data.RemoteData.RemoteDatabase.DAO public required int LessonNumber { get; set; } public UserDao UserDao { get; set; } - public int UserId { get; set; } + public int UserDaoUserId { get; set; } public int GroupId { get; set; } } } diff --git a/123/Data/RemoteData/RemoteDatabase/RemoteDatabaseContext.cs b/123/Data/RemoteData/RemoteDatabase/RemoteDatabaseContext.cs index d4aea7a..9e15f42 100644 --- a/123/Data/RemoteData/RemoteDatabase/RemoteDatabaseContext.cs +++ b/123/Data/RemoteData/RemoteDatabase/RemoteDatabaseContext.cs @@ -12,17 +12,17 @@ namespace _123.Data.RemoteData.RemoteDatabase { protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { - optionsBuilder.UseNpgsql(); + optionsBuilder.UseNpgsql("Host = 45.67.56.214; Port = 5454; Username = user3; Database = user3; Password = VOTfZ8PQ"); } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity().HasKey(group => group.ID); modelBuilder.Entity().Property(group => group.ID).ValueGeneratedOnAdd(); - modelBuilder.Entity().HasKey(user => user.UserGuid); - modelBuilder.Entity().Property(user => user.UserGuid).ValueGeneratedOnAdd(); + modelBuilder.Entity().HasKey(user => user.UserID); + modelBuilder.Entity().Property(user => user.UserID).ValueGeneratedOnAdd(); modelBuilder.Entity().HasKey(presence => new { - presence.UserGuid, + presence.UserDaoUserId, presence.Date, presence.IsAttedance, presence.LessonNumber diff --git a/123/Data/ReportsHistory/GroupRepositoty.cs b/123/Data/ReportsHistory/GroupRepositoty.cs deleted file mode 100644 index 8d8d97a..0000000 --- a/123/Data/ReportsHistory/GroupRepositoty.cs +++ /dev/null @@ -1,33 +0,0 @@ -using _123.Data.LocalData.Entity; -using _123.Data.LocalData; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace _123.Data.ReportsHistory -{ - - public class GroupRepositoryImpl - { - public List GetAllGroups() => LocalStaticData.groups; - - public GroupLocalEntity? UpdateGroup(String name) - { - GroupLocalEntity? groupLocal = GetAllGroups() - .Where(x => x.Name == name).FirstOrDefault(); - if (groupLocal == null) return null; - groupLocal.Name = name; - return groupLocal; - } - public GroupLocalEntity AddGroup(String name, String id) - { - GroupLocalEntity? groupLocal = GetAllGroups().FirstOrDefault(); - groupLocal.Name = name; - groupLocal.ID = int.Parse(id); - return groupLocal; - - } - } - } diff --git a/123/Data/Repository/GroupRepositoty.cs b/123/Data/Repository/GroupRepositoty.cs index 8a2b1e1..9e9cc0f 100644 --- a/123/Data/Repository/GroupRepositoty.cs +++ b/123/Data/Repository/GroupRepositoty.cs @@ -50,6 +50,16 @@ namespace _123.Data.Repository groupLocal.Name = name; return true; } + + List IGroupRepository.GetAllGroup() + { + throw new NotImplementedException(); + } + + GroupDao IGroupRepository.GetGroupById(int groupID) + { + throw new NotImplementedException(); + } } } diff --git a/123/Data/Repository/IGroupRepository.cs b/123/Data/Repository/IGroupRepository.cs index f010553..9fe2039 100644 --- a/123/Data/Repository/IGroupRepository.cs +++ b/123/Data/Repository/IGroupRepository.cs @@ -8,7 +8,7 @@ using System.Threading.Tasks; namespace _123.Data.Repository { - internal interface IGroupRepository + public interface IGroupRepository { List GetAllGroup(); bool RemoveGroupById(int groupID); diff --git a/123/Data/Repository/IPresenceRepository.cs b/123/Data/Repository/IPresenceRepository.cs index b27a789..1b5eea8 100644 --- a/123/Data/Repository/IPresenceRepository.cs +++ b/123/Data/Repository/IPresenceRepository.cs @@ -1,4 +1,5 @@ using _123.Data.LocalData.Entity; +using _123.Data.RemoteData.RemoteDatabase.DAO; using _123.Domain.Models; using System; using System.Collections.Generic; @@ -8,11 +9,11 @@ using System.Threading.Tasks; namespace _123.Data.Repository { - internal interface IPresenceRepository + public interface IPresenceRepository { List GetPresenceByGroup(int groupId); List GetPresenceByGroupAndDate(int groupId, DateOnly date); - bool UnCheckAttendence (int firstClass, int lastClass, DateOnly date, Guid userGuid); + bool UnCheckAttendence (int firstClass, int lastClass, DateOnly date, int UserId); void AddPresence (PresenceDao presence); } diff --git a/123/Data/Repository/IUserRepository.cs b/123/Data/Repository/IUserRepository.cs index fd41894..5e5011f 100644 --- a/123/Data/Repository/IUserRepository.cs +++ b/123/Data/Repository/IUserRepository.cs @@ -8,13 +8,13 @@ using System.Threading.Tasks; namespace _123.Data.Repository { - internal interface IUserRepository + public interface IUserRepository { List GetAllUser(); - bool RemoveUserByGuid(int userId); - UserDao FindUserByGuid(Guid userGuid); - UserDao? GetUserByGuid(int userId); + bool RemoveUserById(int userId); + UserDao FindUserById(int userId); + UserDao? GetUserById(int userId); UserDao? UpdateUser(UserDao userUpdate); - UserDao? UpdateUserByGuid(int userId); + UserDao? UpdateUserById(int userId); } } diff --git a/123/Data/Repository/PresenceRepository.cs b/123/Data/Repository/PresenceRepository.cs index c5222ff..9df4124 100644 --- a/123/Data/Repository/PresenceRepository.cs +++ b/123/Data/Repository/PresenceRepository.cs @@ -1,5 +1,6 @@ using _123.Data.LocalData; using _123.Data.LocalData.Entity; +using _123.Data.RemoteData.RemoteDatabase.DAO; using _123.Domain.Models; using System; using System.Collections.Generic; @@ -14,37 +15,33 @@ namespace _123.Data.Repository public class PresenceRepositoryImpl : IPresenceRepository { - public PresenceRepositoryImpl() - { - GetAllPresences = LocalStaticData.presences; - } - public List GetAllPresences + public List GetAllPresences { get; set; } - public void AddPresence(PresenceLocalEntity presence) + public void AddPresence(PresenceDao presence) { - PresenceLocalEntity? presenceLocal = GetAllPresences.FirstOrDefault(); - presenceLocal.UserGuid = presence.UserGuid; + PresenceDao? presenceLocal = GetAllPresences.FirstOrDefault(); + presenceLocal.UserDaoUserId = presence.UserDaoUserId; presenceLocal.Date = presence.Date; presenceLocal.IsAttedance = presence.IsAttedance; presenceLocal.LessonNumber = presence.LessonNumber; } - public List GetPresenceByGroup(int groupId) + public List GetPresenceByGroup(int groupId) { return GetAllPresences; } - public List GetPresenceByGroupAndDate(int groupId, DateOnly date) + public List GetPresenceByGroupAndDate(int groupId, DateOnly date) { return GetAllPresences; } - public bool UnCheckAttendence(int firstClass, int lastClass, DateOnly date, Guid userGuid) + public bool UnCheckAttendence(int firstClass, int lastClass, DateOnly date, int userId) { var presToUpdate = GetAllPresences - .Where(x => x.UserGuid == userGuid && x.LessonNumber >= firstClass + .Where(x => x.UserDaoUserId == userId && x.LessonNumber >= firstClass && x.LessonNumber <= lastClass && x.Date == date).ToList(); foreach (var presence in presToUpdate) { diff --git a/123/Data/Repository/SQLGroupRepository.cs b/123/Data/Repository/SQLGroupRepository.cs index 506f17a..055a88d 100644 --- a/123/Data/Repository/SQLGroupRepository.cs +++ b/123/Data/Repository/SQLGroupRepository.cs @@ -1,11 +1,13 @@ using _123.Data.LocalData; using _123.Data.LocalData.Entity; using _123.Data.RemoteData.RemoteDatabase; +using _123.Data.RemoteData.RemoteDatabase.DAO; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using System.Xml.Linq; namespace _123.Data.Repository { @@ -21,8 +23,8 @@ namespace _123.Data.Repository public List GetAllGroups() { var groups = _remoteDatabaseContext.Groups - .Select(g => new GroupDao - { + .Select(g => new GroupDao + { ID = g.ID, Name = g.Name }) @@ -59,13 +61,19 @@ namespace _123.Data.Repository { var group = _remoteDatabaseContext.Groups .FirstOrDefault(x => x.ID == groupID); - + if (group == null) return null; - - return new GroupDao + + return new GroupDao { ID = group.ID, - Name = group.Name + Name = group.Name, + Users = group.Users?.Select(u => new UserDao + { + UserID = u.UserID, + UserFIO = u.UserFIO, + GroupID = group.ID + }).ToList() ?? new List() }; } @@ -76,13 +84,12 @@ namespace _123.Data.Repository var group = _remoteDatabaseContext.Groups .FirstOrDefault(x => x.ID == groupID); if (group == null) return false; - - // Проверяем, есть ли связанные пользователи + if (group.Users != null && group.Users.Any()) { - return false; // Нельзя удалить группу с пользователями + return false; } - + _remoteDatabaseContext.Groups.Remove(group); _remoteDatabaseContext.SaveChanges(); return true; diff --git a/123/Data/Repository/SQLPresenceRepository.cs b/123/Data/Repository/SQLPresenceRepository.cs index 4a8e6dc..672180f 100644 --- a/123/Data/Repository/SQLPresenceRepository.cs +++ b/123/Data/Repository/SQLPresenceRepository.cs @@ -1,6 +1,7 @@ using _123.Data.LocalData; using _123.Data.LocalData.Entity; using _123.Data.RemoteData.RemoteDatabase; +using _123.Data.RemoteData.RemoteDatabase.DAO; using System; using System.Collections.Generic; using System.Linq; @@ -20,28 +21,28 @@ namespace _123.Data.Repository public void AddPresence(PresenceDao presence) { - _remoteDatabaseContext.Presences.Add(presence); + _remoteDatabaseContext.PresencesDaos.Add(presence); _remoteDatabaseContext.SaveChanges(); } public List GetPresenceByGroup(int groupId) { - return _remoteDatabaseContext.Presences + return _remoteDatabaseContext.PresencesDaos .Where(p => p.GroupId == groupId) .ToList(); } public List GetPresenceByGroupAndDate(int groupId, DateOnly date) { - return _remoteDatabaseContext.Presences + return _remoteDatabaseContext.PresencesDaos .Where(p => p.GroupId == groupId && p.Date == date) .ToList(); } - public bool UnCheckAttendence(int firstClass, int lastClass, DateOnly date, Guid userGuid) + public bool UnCheckAttendence(int firstClass, int lastClass, DateOnly date, int userId) { - var presToUpdate = _remoteDatabaseContext.Presences - .Where(x => x.UserGuid == userGuid && x.LessonNumber >= firstClass + var presToUpdate = _remoteDatabaseContext.PresencesDaos + .Where(x => x.UserDaoUserId == userId && x.LessonNumber >= firstClass && x.LessonNumber <= lastClass && x.Date == date).ToList(); foreach (var presence in presToUpdate) diff --git a/123/Data/Repository/SQLUserRepository.cs b/123/Data/Repository/SQLUserRepository.cs index bf5fac9..3db9c1f 100644 --- a/123/Data/Repository/SQLUserRepository.cs +++ b/123/Data/Repository/SQLUserRepository.cs @@ -1,6 +1,7 @@ using _123.Data.LocalData; using _123.Data.LocalData.Entity; using _123.Data.RemoteData.RemoteDatabase; +using _123.Data.RemoteData.RemoteDatabase.DAO; using System; using System.Collections.Generic; using System.Linq; @@ -18,14 +19,14 @@ namespace _123.Data.Repository _remoteDatabaseContext = remoteDatabaseContext; } - public UserDao FindUserByGuid(Guid userGuid) + public UserDao FindUserById(int userId) { var user = _remoteDatabaseContext.Users - .FirstOrDefault(x => x.UserID == userGuid); + .FirstOrDefault(x => x.UserID == userId); if (user == null) throw new Exception("Пользователь не найден"); return user; } - + public List GetAllUser() { return _remoteDatabaseContext.Users @@ -39,13 +40,13 @@ namespace _123.Data.Repository .ToList(); } - public UserDao? GetUserByGuid(int userId) + public UserDao? GetUserById(int userId) { return _remoteDatabaseContext.Users .FirstOrDefault(x => x.UserID == userId); } - public bool RemoveUserByGuid(int userId) + public bool RemoveUserById(int userId) { try { @@ -83,7 +84,7 @@ namespace _123.Data.Repository } } - public UserDao? UpdateUserByGuid(int userId) + public UserDao? UpdateUserById(int userId) { return _remoteDatabaseContext.Users .FirstOrDefault(x => x.UserID == userId); diff --git a/123/Data/Repository/UserRepositoty.cs b/123/Data/Repository/UserRepositoty.cs index d61425f..e260d6d 100644 --- a/123/Data/Repository/UserRepositoty.cs +++ b/123/Data/Repository/UserRepositoty.cs @@ -16,55 +16,55 @@ namespace _123.Data.ReportsHistory public UserRepositoryImpl() { - GetAllUsers = LocalStaticData.users; + GetAllUsers = LocalStaticData.users.Select(it => new UserDao { GroupID = it.GroupID, UserFIO = it.UserFIO, UserID = it.UserId}).ToList(); } - public List GetAllUsers + public List GetAllUsers { get; set; } - public List GetAllUser() + public List GetAllUser() { return GetAllUsers; } - public bool RemoveUserByGuid(Guid userGuid) + public bool RemoveUserById(int userId) { - UserLocalEntity? userLocal = GetAllUsers - .Where(x => x.UserGuid == userGuid).FirstOrDefault(); + UserDao? userLocal = GetAllUsers + .Where(x => x.UserID == userId).FirstOrDefault(); if (userLocal == null) return false; return GetAllUsers.Remove(userLocal); } - public UserLocalEntity FindUserByGuid(Guid userGuid) + public UserDao FindUserById(int userId) { - UserLocalEntity? userLocal = GetAllUsers - .Where(x => x.UserGuid == userGuid).FirstOrDefault(); + UserDao? userLocal = GetAllUsers + .Where(x => x.UserID == userId).FirstOrDefault(); if (userLocal == null) throw new Exception("Пользователь не найден"); return userLocal; } - public UserLocalEntity? GetUserByGuid(Guid userGuid) + public UserDao? GetUserById(int userId) { - UserLocalEntity? userLocal = GetAllUsers - .Where(x => x.UserGuid == userGuid).FirstOrDefault(); + UserDao? userLocal = GetAllUsers + .Where(x => x.UserID == userId).FirstOrDefault(); if (userLocal == null) return null; return userLocal; } - public UserLocalEntity? UpdateUser(UserLocalEntity userUpdateLocalEnity) + public UserDao? UpdateUser(UserDao userUpdateDao) { - UserLocalEntity? userLocal = GetAllUsers - .Where(x => x.UserGuid == userUpdateLocalEnity.UserGuid).FirstOrDefault(); + UserDao? userLocal = GetAllUsers + .Where(x => x.UserID == userUpdateDao.UserID).FirstOrDefault(); if (userLocal == null) return null; - userLocal.UserFIO = userUpdateLocalEnity.UserFIO; - userLocal.GroupID = userUpdateLocalEnity.GroupID; + userLocal.UserFIO = userUpdateDao.UserFIO; + userLocal.GroupID = userUpdateDao.GroupID; return userLocal; } - public UserLocalEntity? UpdateUserByGuid(Guid userGuid) + public UserDao? UpdateUserById(int userId) { - UserLocalEntity? userLocal = GetAllUsers - .Where(x => x.UserGuid == userGuid).FirstOrDefault(); + UserDao? userLocal = GetAllUsers + .Where(x => x.UserID == userId).FirstOrDefault(); if (userLocal == null) return null; return userLocal; diff --git a/123/Demo.csproj b/123/Demo.csproj index 47c142b..fd82c53 100644 --- a/123/Demo.csproj +++ b/123/Demo.csproj @@ -9,6 +9,7 @@ + runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/123/Domain/Models/User.cs b/123/Domain/Models/User.cs index e43f1e6..a0f10a5 100644 --- a/123/Domain/Models/User.cs +++ b/123/Domain/Models/User.cs @@ -9,7 +9,7 @@ namespace _123.Domain.Models public class User { public required string UserFIO { get; set; } - public Guid UserGuid { get; set; } + public int UserID { get; set; } public required Group UserGroup { get; set; } } diff --git a/123/Domain/UseCase/GroupUseCase.cs b/123/Domain/UseCase/GroupUseCase.cs index cf60f4a..60ce3a7 100644 --- a/123/Domain/UseCase/GroupUseCase.cs +++ b/123/Domain/UseCase/GroupUseCase.cs @@ -12,13 +12,13 @@ namespace _123.Domain.UseCase { public class GroupUseCase { - private readonly SQLGroupRepositoryImpl _repositoryGroupImpl; - public GroupUseCase(SQLGroupRepositoryImpl repositoryGroupImpl) + private readonly IGroupRepository _repositoryGroupImpl; + public GroupUseCase(IGroupRepository repositoryGroupImpl) { _repositoryGroupImpl = repositoryGroupImpl; } - public List GetAllGroups() => _repositoryGroupImpl.GetAllGroups() + public List GetAllGroups() => _repositoryGroupImpl.GetAllGroup() .Select(it => new Group { ID = it.ID, Name = it.Name }).ToList(); public bool UpdateGroupName(string id, string name) @@ -42,9 +42,5 @@ namespace _123.Domain.UseCase { return _repositoryGroupImpl.RemoveGroupById(id); } - public GroupLocalEntity AddGroup(String name, string id) - { - return _repositoryGroupImpl.AddGroup(name, id); - } } } diff --git a/123/Domain/UseCase/PresenceUseCase.cs b/123/Domain/UseCase/PresenceUseCase.cs index 1d0e253..eec2e4f 100644 --- a/123/Domain/UseCase/PresenceUseCase.cs +++ b/123/Domain/UseCase/PresenceUseCase.cs @@ -13,50 +13,50 @@ namespace _123.Domain.UseCase { public class PresenceUseCase { - private readonly SQLPresenceRepositoryImpl _presenceRepositoryImpl; - private readonly SQLGroupRepositoryImpl _groupRepositoryImpl; - private readonly SQLUserRepositoryImpl _userRepositoryImpl; + private readonly IPresenceRepository _presenceRepositoryImpl; + private readonly IGroupRepository _groupRepositoryImpl; + private readonly IUserRepository _userRepositoryImpl; public List GetPresenceByGroup(int groupId) { - var users = _userRepositoryImpl.GetAllUsers.Where(x => x.GroupID == groupId).ToList(); + var users = _userRepositoryImpl.GetAllUser().Where(x => x.GroupID == groupId).ToList(); var presenceByGroup = _presenceRepositoryImpl.GetPresenceByGroup(groupId) - .Where(x => users.Any(user => user.UserGuid == x.UserGuid)) + .Where(x => users.Any(user => user.UserID == x.UserDaoUserId)) .Select(presence => new Presence { User = new User { - UserGuid = presence.UserGuid, + UserID = presence.UserDaoUserId, UserGroup = new Group { ID = groupId, - Name = _groupRepositoryImpl.GetAllGroups().First(group => group.ID == groupId).Name + Name = _groupRepositoryImpl.GetAllGroup().First(group => group.ID == groupId).Name }, - UserFIO = users.First(user => user.UserGuid == presence.UserGuid).UserFIO, + UserFIO = users.First(user => user.UserID == presence.UserDaoUserId).UserFIO, }, ClassNum = presence.LessonNumber, Date = presence.Date, IsAttedance = presence.IsAttedance, }).ToList(); - return presenceByGroup; + return (List)presenceByGroup; } public List GetPresenceByGroupAndDate(int groupId, DateOnly date) { - var users = _userRepositoryImpl.GetAllUsers.Where(x => x.GroupID == groupId).ToList(); + var users = _userRepositoryImpl.GetAllUser().Where(x => x.GroupID == groupId).ToList(); var presenceByGroup = _presenceRepositoryImpl.GetPresenceByGroup(groupId) - .Where(x => users.Any(user => user.UserGuid == x.UserGuid && x.Date == date)) + .Where(x => users.Any(user => user.UserID == x.UserDaoUserId && x.Date == date)) .Select(presence => new Presence { User = new User { - UserGuid = presence.UserGuid, + UserID = presence.UserDaoUserId, UserGroup = new Group { ID = groupId, - Name = _groupRepositoryImpl.GetAllGroups().First(group => group.ID == groupId).Name + Name = _groupRepositoryImpl.GetAllGroup().First(group => group.ID == groupId).Name }, - UserFIO = users.First(user => user.UserGuid == presence.UserGuid).UserFIO, + UserFIO = users.First(user => user.UserID == presence.UserDaoUserId).UserFIO, }, ClassNum = presence.LessonNumber, Date = presence.Date, @@ -64,10 +64,44 @@ namespace _123.Domain.UseCase }).ToList(); return presenceByGroup; } - public bool UnCheckAttendance(int firstClass, int lastClass, DateOnly date, Guid userGuid) + public bool UnCheckAttendance(int firstClass, int lastClass, DateOnly date, int userID) { - return _presenceRepositoryImpl.UnCheckAttendence(firstClass, lastClass, date, userGuid); + return _presenceRepositoryImpl.UnCheckAttendence(firstClass, lastClass, date, userID); + } + + public Dictionary GetPresenceStatsByGroup(int groupId) + { + var stats = new Dictionary(); + + // Получаем всех студентов группы + var users = _userRepositoryImpl.GetAllUser().Where(x => x.GroupID == groupId).ToList(); + stats["Количество студентов"] = users.Count; + + // Получаем все записи посещаемости для группы + var presences = _presenceRepositoryImpl.GetPresenceByGroup(groupId); + + // Считаем количество уникальных занятий + var uniqueLessons = presences + .Select(p => new { p.Date, p.LessonNumber }) + .Distinct() + .Count(); + stats["Количество занятий"] = uniqueLessons; + + // Считаем общую посещаемость + var totalAttendances = presences.Count(p => p.IsAttedance); + var totalPossibleAttendances = users.Count * uniqueLessons; + + if (totalPossibleAttendances > 0) + { + var attendancePercentage = (totalAttendances * 100) / totalPossibleAttendances; + stats["Процент посещаемости"] = attendancePercentage; + } + else + { + stats["Процент посещаемости"] = 0; + } + + return stats; } - } } diff --git a/123/Domain/UseCase/UseCaseGeneratePresence.cs b/123/Domain/UseCase/UseCaseGeneratePresence.cs index 507e224..a263751 100644 --- a/123/Domain/UseCase/UseCaseGeneratePresence.cs +++ b/123/Domain/UseCase/UseCaseGeneratePresence.cs @@ -32,7 +32,7 @@ namespace _123.Domain.UseCase { foreach (var user in users) { - PresenceLocalEntity pres = new PresenceLocalEntity { LessonNumber = i, UserGuid = user.UserGuid, Date = date }; + PresenceLocalEntity pres = new PresenceLocalEntity { LessonNumber = i, UserID = user.UserID, Date = date }; } } } @@ -53,7 +53,7 @@ namespace _123.Domain.UseCase PresenceLocalEntity pres = new PresenceLocalEntity { LessonNumber = i, - UserGuid = user.UserGuid, + UserID = user.UserID, Date = date }; presence.Add(pres); diff --git a/123/Domain/UseCase/UserUseCase.cs b/123/Domain/UseCase/UserUseCase.cs index 74ba3c5..5c966da 100644 --- a/123/Domain/UseCase/UserUseCase.cs +++ b/123/Domain/UseCase/UserUseCase.cs @@ -13,34 +13,34 @@ namespace _123.Domain.UseCase { public class UserUseCase { - private readonly SQLUserRepositoryImpl _repositoryUserImpl; - private readonly SQLGroupRepositoryImpl _repositoryGroupImpl; + private readonly IUserRepository _repositoryUserImpl; + private readonly IGroupRepository _repositoryGroupImpl; - public UserUseCase(SQLUserRepositoryImpl repositoryImpl, SQLGroupRepositoryImpl repositoryGroupImpl) + public UserUseCase(IUserRepository repositoryImpl, IGroupRepository repositoryGroupImpl) { _repositoryUserImpl = repositoryImpl; _repositoryGroupImpl = repositoryGroupImpl; } - public List GetAllGroups() => _repositoryGroupImpl.GetAllGroups() + public List GetAllGroups() => _repositoryGroupImpl.GetAllGroup() .Select(it => new Group { ID = it.ID, Name = it.Name }).ToList(); public List GetAllUsers() => _repositoryUserImpl.GetAllUser() - .Join(_repositoryGroupImpl.GetAllGroups(), + .Join(_repositoryGroupImpl.GetAllGroup(), user => user.GroupID, group => group.ID, (user, group) => new User { UserFIO = user.UserFIO, - UserGuid = user.UserID, + UserID = user.UserID, UserGroup = new Group { ID = group.ID, Name = group.Name } } ).ToList(); public bool RemoveUserByGuid(int userId) { - return _repositoryUserImpl.RemoveUserByGuid(userId); + return _repositoryUserImpl.RemoveUserById(userId); } public User UpdateUser(User user) @@ -48,23 +48,29 @@ namespace _123.Domain.UseCase UserDao userDao = new UserDao { UserFIO = user.UserFIO, GroupID = user.UserGroup.ID, - UserID = user.UserGuid + UserID = user.UserID }; UserDao? result = _repositoryUserImpl.UpdateUser(userDao); if (result == null) throw new Exception("Не удалось обновить пользователя"); Group? group = GetAllGroups().FirstOrDefault(it => it.ID == result.GroupID); if (group == null) throw new Exception("Группа не найдена"); - return new User { UserFIO = user.UserFIO, UserGuid = user.UserGuid, UserGroup = group }; + return new User { UserFIO = user.UserFIO, UserID = user.UserID, UserGroup = group }; } - public UserDao FindUserByGuid(int userId) + public User FindUserByGuid(int userId) { - return _repositoryUserImpl.FindUserByGuid(userId); + var userDao = _repositoryUserImpl.FindUserById(userId); + return new User + { + UserID = userDao.UserID, + UserFIO = userDao.UserFIO, + UserGroup = GetAllGroups().FirstOrDefault(g => g.ID == userDao.GroupID) + }; } public UserDao UpdateUserByGuid(int userId, string name, string groupId) { - UserDao? result = _repositoryUserImpl.UpdateUserByGuid(userId); + UserDao? result = _repositoryUserImpl.UpdateUserById(userId); if (result == null) throw new Exception("Пользователь не найден"); Group? group = GetAllGroups().FirstOrDefault(it => it.ID == int.Parse(groupId)); if (group == null) throw new Exception("Группа не найдена"); diff --git a/123/Migrations/20241118090715_InitialCreate.Designer.cs b/123/Migrations/20241118090715_InitialCreate.Designer.cs new file mode 100644 index 0000000..57b43f3 --- /dev/null +++ b/123/Migrations/20241118090715_InitialCreate.Designer.cs @@ -0,0 +1,118 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using _123.Data.RemoteData.RemoteDatabase; + +#nullable disable + +namespace _123.Migrations +{ + [DbContext(typeof(RemoteDatabaseContext))] + [Migration("20241118090715_InitialCreate")] + partial class InitialCreate + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.10") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("_123.Data.RemoteData.RemoteDatabase.DAO.GroupDao", b => + { + b.Property("ID") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("ID")); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("ID"); + + b.ToTable("Groups"); + }); + + modelBuilder.Entity("_123.Data.RemoteData.RemoteDatabase.DAO.PresenceDao", b => + { + b.Property("UserDaoUserId") + .HasColumnType("integer"); + + b.Property("Date") + .HasColumnType("date"); + + b.Property("IsAttedance") + .HasColumnType("boolean"); + + b.Property("LessonNumber") + .HasColumnType("integer"); + + b.Property("GroupId") + .HasColumnType("integer"); + + b.HasKey("UserDaoUserId", "Date", "IsAttedance", "LessonNumber"); + + b.ToTable("PresencesDaos"); + }); + + modelBuilder.Entity("_123.Data.RemoteData.RemoteDatabase.DAO.UserDao", b => + { + b.Property("UserID") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("UserID")); + + b.Property("GroupID") + .HasColumnType("integer"); + + b.Property("UserFIO") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("UserID"); + + b.HasIndex("GroupID"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("_123.Data.RemoteData.RemoteDatabase.DAO.PresenceDao", b => + { + b.HasOne("_123.Data.RemoteData.RemoteDatabase.DAO.UserDao", "UserDao") + .WithMany() + .HasForeignKey("UserDaoUserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("UserDao"); + }); + + modelBuilder.Entity("_123.Data.RemoteData.RemoteDatabase.DAO.UserDao", b => + { + b.HasOne("_123.Data.RemoteData.RemoteDatabase.DAO.GroupDao", "Group") + .WithMany("Users") + .HasForeignKey("GroupID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Group"); + }); + + modelBuilder.Entity("_123.Data.RemoteData.RemoteDatabase.DAO.GroupDao", b => + { + b.Navigation("Users"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/123/Migrations/20241118090715_InitialCreate.cs b/123/Migrations/20241118090715_InitialCreate.cs new file mode 100644 index 0000000..4c9c894 --- /dev/null +++ b/123/Migrations/20241118090715_InitialCreate.cs @@ -0,0 +1,88 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace _123.Migrations +{ + /// + public partial class InitialCreate : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Groups", + columns: table => new + { + ID = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + Name = table.Column(type: "text", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Groups", x => x.ID); + }); + + migrationBuilder.CreateTable( + name: "Users", + columns: table => new + { + UserID = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + UserFIO = table.Column(type: "text", nullable: false), + GroupID = table.Column(type: "integer", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Users", x => x.UserID); + table.ForeignKey( + name: "FK_Users_Groups_GroupID", + column: x => x.GroupID, + principalTable: "Groups", + principalColumn: "ID", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "PresencesDaos", + columns: table => new + { + IsAttedance = table.Column(type: "boolean", nullable: false), + Date = table.Column(type: "date", nullable: false), + LessonNumber = table.Column(type: "integer", nullable: false), + UserDaoUserId = table.Column(type: "integer", nullable: false), + GroupId = table.Column(type: "integer", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_PresencesDaos", x => new { x.UserDaoUserId, x.Date, x.IsAttedance, x.LessonNumber }); + table.ForeignKey( + name: "FK_PresencesDaos_Users_UserDaoUserId", + column: x => x.UserDaoUserId, + principalTable: "Users", + principalColumn: "UserID", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_Users_GroupID", + table: "Users", + column: "GroupID"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "PresencesDaos"); + + migrationBuilder.DropTable( + name: "Users"); + + migrationBuilder.DropTable( + name: "Groups"); + } + } +} diff --git a/123/Migrations/RemoteDatabaseContextModelSnapshot.cs b/123/Migrations/RemoteDatabaseContextModelSnapshot.cs new file mode 100644 index 0000000..f2496a7 --- /dev/null +++ b/123/Migrations/RemoteDatabaseContextModelSnapshot.cs @@ -0,0 +1,115 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using _123.Data.RemoteData.RemoteDatabase; + +#nullable disable + +namespace _123.Migrations +{ + [DbContext(typeof(RemoteDatabaseContext))] + partial class RemoteDatabaseContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.10") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("_123.Data.RemoteData.RemoteDatabase.DAO.GroupDao", b => + { + b.Property("ID") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("ID")); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("ID"); + + b.ToTable("Groups"); + }); + + modelBuilder.Entity("_123.Data.RemoteData.RemoteDatabase.DAO.PresenceDao", b => + { + b.Property("UserDaoUserId") + .HasColumnType("integer"); + + b.Property("Date") + .HasColumnType("date"); + + b.Property("IsAttedance") + .HasColumnType("boolean"); + + b.Property("LessonNumber") + .HasColumnType("integer"); + + b.Property("GroupId") + .HasColumnType("integer"); + + b.HasKey("UserDaoUserId", "Date", "IsAttedance", "LessonNumber"); + + b.ToTable("PresencesDaos"); + }); + + modelBuilder.Entity("_123.Data.RemoteData.RemoteDatabase.DAO.UserDao", b => + { + b.Property("UserID") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("UserID")); + + b.Property("GroupID") + .HasColumnType("integer"); + + b.Property("UserFIO") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("UserID"); + + b.HasIndex("GroupID"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("_123.Data.RemoteData.RemoteDatabase.DAO.PresenceDao", b => + { + b.HasOne("_123.Data.RemoteData.RemoteDatabase.DAO.UserDao", "UserDao") + .WithMany() + .HasForeignKey("UserDaoUserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("UserDao"); + }); + + modelBuilder.Entity("_123.Data.RemoteData.RemoteDatabase.DAO.UserDao", b => + { + b.HasOne("_123.Data.RemoteData.RemoteDatabase.DAO.GroupDao", "Group") + .WithMany("Users") + .HasForeignKey("GroupID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Group"); + }); + + modelBuilder.Entity("_123.Data.RemoteData.RemoteDatabase.DAO.GroupDao", b => + { + b.Navigation("Users"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/123/Program.cs b/123/Program.cs index c879a62..71f1eb0 100644 --- a/123/Program.cs +++ b/123/Program.cs @@ -15,15 +15,8 @@ services .AddDbContext() .AddSingleton() .AddSingleton() - .AddSingleton() + .AddSingleton(); var serviceProvider = services.BuildServiceProvider (); -GroupRepositoryImpl groupRepositoryImpl = new GroupRepositoryImpl(); -UserRepositoryImpl userRepositoryImpl = new UserRepositoryImpl(); -UserUseCase userUseCase = new UserUseCase(userRepositoryImpl, groupRepositoryImpl); -GroupUseCase groupUseCase = new GroupUseCase(groupRepositoryImpl); -PresenceRepositoryImpl presenceRepositoryImpl = new PresenceRepositoryImpl(); -PresenceUseCase presenceUseCase = new PresenceUseCase(); - -MainMenuUI mainMenuUI = new MainMenuUI(userUseCase, groupUseCase, presenceUseCase); +var mainMenuUI = serviceProvider.GetRequiredService(); diff --git a/123/UI/GroupConsole.cs b/123/UI/GroupConsole.cs index a812fb6..6d21013 100644 --- a/123/UI/GroupConsole.cs +++ b/123/UI/GroupConsole.cs @@ -31,16 +31,10 @@ namespace _123.UI } public void AddGroup (String name, String id) { - StringBuilder groupOutput = new StringBuilder(); - var group = _groupUseCase.AddGroup(name,id); -<<<<<<< HEAD -======= - { - groupOutput.AppendLine($"{group.Name}\t{group.ID}"); - } - Console.WriteLine(groupOutput); ->>>>>>> b274d8f88d0df85505fa497de11d07625bde956d + string output = _groupUseCase.AddGroup(name , id) ? " " : " "; + Console.WriteLine(output); } + } } \ No newline at end of file diff --git a/123/UI/MainMenu.cs b/123/UI/MainMenu.cs index db97c76..309de15 100644 --- a/123/UI/MainMenu.cs +++ b/123/UI/MainMenu.cs @@ -33,7 +33,7 @@ namespace _123.UI switch (Console.ReadLine()) { case "1": _userConsoleUI.DisplayAllUsers(); break; - case "2": _userConsoleUI.RemoveUserByGuid(Guid.Parse(Console.ReadLine())); break; + case "2": _userConsoleUI.RemoveUserById(int.Parse(Console.ReadLine())); break; case "3": _groupConsoleUI.DisplayAllGroups(); break; case "4": _userConsoleUI.FindUserById(int.Parse(Console.ReadLine())); break; case "5": _userConsoleUI.UpdateUserById(int.Parse(Console.ReadLine()), Console.ReadLine(), Console.ReadLine()); break; @@ -41,7 +41,7 @@ namespace _123.UI case "7": _groupConsoleUI.AddGroup(Console.ReadLine(), Console.ReadLine()); break; case "8": _presenceConsoleUI.GetPresenceByGroup(int.Parse(Console.ReadLine())); break; case "9": _presenceConsoleUI.GetPresenceByGroupAndDAte(int.Parse(Console.ReadLine()), DateOnly.Parse(Console.ReadLine())); break; - case "10": _presenceConsoleUI.UnCheckAttendence(int.Parse(Console.ReadLine()), int.Parse(Console.ReadLine()), DateOnly.Parse(Console.ReadLine()), Guid.Parse(Console.ReadLine())); break; + case "10": _presenceConsoleUI.UnCheckAttendence(int.Parse(Console.ReadLine()), int.Parse(Console.ReadLine()), DateOnly.Parse(Console.ReadLine()), int.Parse(Console.ReadLine())); break; case "11": _presenceConsoleUI.AddPresence(int.Parse(Console.ReadLine()), int.Parse(Console.ReadLine()), int.Parse(Console.ReadLine()), DateOnly.Parse(Console.ReadLine())); break; default: diff --git a/123/UI/PresenceConsole.cs b/123/UI/PresenceConsole.cs index 6cb283e..272d231 100644 --- a/123/UI/PresenceConsole.cs +++ b/123/UI/PresenceConsole.cs @@ -11,6 +11,7 @@ namespace _123.UI { PresenceUseCase _presenceUseCase; UseCaseGeneratePresence _useCaseGeneratePresence; + private PresenceUseCase presenceUseCase; public PresenceConsoleUI(PresenceUseCase presenceUseCase, UseCaseGeneratePresence useCaseGeneratePresence) { @@ -18,13 +19,18 @@ namespace _123.UI _useCaseGeneratePresence = useCaseGeneratePresence; } + public PresenceConsoleUI(PresenceUseCase presenceUseCase) + { + this.presenceUseCase = presenceUseCase; + } + public void GetPresenceByGroup(int groupId) { StringBuilder presenceOutput = new StringBuilder(); var presence = _presenceUseCase.GetPresenceByGroup(groupId); foreach (var p in presence) { - presenceOutput.AppendLine($"{p.LessonNumber}\t{p.UserGuid}\t{p.Date}"); + presenceOutput.AppendLine($"{p.ClassNum}\t{p.User}\t{p.Date}"); } Console.WriteLine(presenceOutput); } @@ -35,14 +41,14 @@ namespace _123.UI var presence = _presenceUseCase.GetPresenceByGroupAndDate(groupId, date); foreach (var p in presence) { - presenceOutput.AppendLine($"{p.LessonNumber}\t{p.UserGuid}\t{p.Date}"); + presenceOutput.AppendLine($"{p.ClassNum}\t{p.User}\t{p.Date}"); } Console.WriteLine(presenceOutput); } - public void UnCheckAttendence(int firstClass, int lastClass, DateOnly date, Guid userGuid) + public void UnCheckAttendence(int firstClass, int lastClass, DateOnly date, int userId) { - var result = _presenceUseCase.UnCheckAttendance(firstClass, lastClass, date, userGuid); + var result = _presenceUseCase.UnCheckAttendance(firstClass, lastClass, date, userId); Console.WriteLine(result ? "Посещаемость успешно обновлена" : "Ошибка при обновлении посещаемости"); } @@ -58,28 +64,111 @@ namespace _123.UI Console.WriteLine($"Ошибка при добавлении посещаемости: {ex.Message}"); } } - public void GetGroupAttendanceStats(int groupId) + public void GetPresenceStatsByGroup(int groupId) { - StringBuilder statsOutput = new StringBuilder(); - var groupStats = _presenceUseCase.GetGroupStats(groupId); - - statsOutput.AppendLine($"Информация о группе {groupStats.GroupName}:"); - statsOutput.AppendLine($"Количество студентов: {groupStats.StudentsCount}"); - statsOutput.AppendLine($"Количество проведенных занятий: {groupStats.TotalLessons}"); - statsOutput.AppendLine($"Общий процент посещаемости: {groupStats.TotalAttendancePercent:F1}%"); - statsOutput.AppendLine("\nСтатистика по студентам:"); - statsOutput.AppendLine("ФИО\tПосещено\tПропущено\tПроцент посещаемости"); - - foreach(var student in groupStats.StudentStats) + var stats = _presenceUseCase.GetPresenceStatsByGroup(groupId); + StringBuilder output = new StringBuilder(); + + output.AppendLine($"Информация о группе {groupId}:"); + output.AppendLine($"Количество студентов: {stats["Количество студентов"]}"); + output.AppendLine($"Количество занятий: {stats["Количество занятий"]}"); + output.AppendLine($"Общий процент посещаемости: {stats["Процент посещаемости"]}%"); + output.AppendLine("\nСтатистика по студентам:"); + + var presence = _presenceUseCase.GetPresenceByGroup(groupId); + var students = presence.GroupBy(p => p.User) + .Select(g => new { + Student = g.Key, + Total = stats["Количество занятий"], + Attended = g.Count(p => p.IsAttedance), + Missed = stats["Количество занятий"] - g.Count(p => p.IsAttedance), + Percentage = (g.Count(p => p.IsAttedance) * 100) / stats["Количество занятий"] + }); + + foreach (var student in students) { - statsOutput.AppendLine( - $"{student.StudentName}\t{student.AttendedLessons}\t" + - $"{student.MissedLessons}\t{student.AttendancePercent:F1}%" - ); + output.AppendLine($"\nСтудент: {student.Student.UserFIO}"); + output.AppendLine($"Посещено занятий: {student.Attended}"); + output.AppendLine($"Пропущено занятий: {student.Missed}"); + output.AppendLine($"Процент посещаемости: {student.Percentage}%"); + } + + Console.WriteLine(output.ToString()); + } + + public void ExportPresenceToExcel(string groupId, string filePath) + { + int Id; + bool isParsed = int.TryParse(groupId, out Id); + if (!isParsed) + { + Console.WriteLine("Введено не число"); + } + var presence = _presenceUseCase.GetPresenceByGroup(Id); + var stats = _presenceUseCase.GetPresenceStatsByGroup(Id); + + using (var workbook = new XLWorkbook()) + { + var worksheet = workbook.Worksheets.Add("Посещаемость"); + + // Заголовок листа + worksheet.Cell(1, 1).Value = $"Группа {groupId}"; + worksheet.Range(1, 1, 1, 3).Merge(); + worksheet.Cell(1, 1).Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Center; + + // Заголовки столбцов + worksheet.Cell(3, 1).Value = "№"; + worksheet.Cell(3, 2).Value = "ФИО"; + + // Получаем все уникальные даты + var dates = presence.Select(p => p.Date).Distinct().OrderBy(d => d).ToList(); + int col = 3; + foreach (var date in dates) + { + worksheet.Cell(3, col).Value = date.ToString("dd.MM.yyyy"); + col++; + } + + // Группируем данные по студентам + var studentGroups = presence.GroupBy(p => p.User); + int row = 4; + int studentNumber = 1; + + foreach (var studentGroup in studentGroups) + { + // Номер и ФИО студента + worksheet.Cell(row, 1).Value = studentNumber++; + worksheet.Cell(row, 2).Value = studentGroup.Key.FIO; + + // Заполняем посещаемость по датам + col = 3; + foreach (var date in dates) + { + var presenceOnDate = studentGroup.FirstOrDefault(p => p.Date == date); + worksheet.Cell(row, col).Value = presenceOnDate?.IsAttendence == true ? "+" : "н"; + worksheet.Cell(row, col).Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Center; + col++; + } + row++; + } + + // Форматирование + var tableRange = worksheet.Range(3, 1, row - 1, dates.Count + 2); + tableRange.Style.Border.OutsideBorder = XLBorderStyleValues.Thin; + tableRange.Style.Border.InsideBorder = XLBorderStyleValues.Thin; + + worksheet.Columns().AdjustToContents(); + + try + { + workbook.SaveAs(filePath); + Console.WriteLine($"Данные успешно экспортированы в файл: {filePath}"); + } + catch (Exception ex) + { + Console.WriteLine($"Ошибка при сохранении файла: {ex.Message}"); + } } - - Console.WriteLine(statsOutput.ToString()); } } - } diff --git a/123/UI/UserConsole.cs b/123/UI/UserConsole.cs index 877eebe..2952bb5 100644 --- a/123/UI/UserConsole.cs +++ b/123/UI/UserConsole.cs @@ -37,7 +37,7 @@ namespace _123.UI { StringBuilder userOutput = new StringBuilder(); var user = _userUseCase.FindUserByGuid(userId); - userOutput.AppendLine($"{user.UserID}\t{user.UserFIO}\t{user.GroupID}"); + userOutput.AppendLine($"{user.UserID}\t{user.UserFIO}\t{user.UserGroup}"); Console.WriteLine(userOutput); } diff --git a/123/presence/console/Class1.cs b/123/presence/console/Class1.cs new file mode 100644 index 0000000..7f3550f --- /dev/null +++ b/123/presence/console/Class1.cs @@ -0,0 +1,6 @@ +namespace console; + +public class Class1 +{ + +} diff --git a/123/presence/console/console.csproj b/123/presence/console/console.csproj new file mode 100644 index 0000000..fa71b7a --- /dev/null +++ b/123/presence/console/console.csproj @@ -0,0 +1,9 @@ + + + + net8.0 + enable + enable + + + diff --git a/123/presence_api/Controllers/GroupController.cs/GroupController.cs b/123/presence_api/Controllers/GroupController.cs/GroupController.cs new file mode 100644 index 0000000..dfa539a --- /dev/null +++ b/123/presence_api/Controllers/GroupController.cs/GroupController.cs @@ -0,0 +1,10 @@ +namespace presence_api.Controllers; +[ApiConytoller] +[Route("api/[apicontroller]")] +public class GroupController(): ControllerBaswe { +private readonly GroupUseCase _groupUserCase; +GroupController(GroupUseCase groupUseCase){ + _groupUserCase = groupUseCase(); +} + +} \ No newline at end of file diff --git a/123/presence_api/Program.cs b/123/presence_api/Program.cs new file mode 100644 index 0000000..00ff539 --- /dev/null +++ b/123/presence_api/Program.cs @@ -0,0 +1,44 @@ +var builder = WebApplication.CreateBuilder(args); + +// Add services to the container. +// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle +builder.Services.AddEndpointsApiExplorer(); +builder.Services.AddSwaggerGen(); + +var app = builder.Build(); + +// Configure the HTTP request pipeline. +if (app.Environment.IsDevelopment()) +{ + app.UseSwagger(); + app.UseSwaggerUI(); +} + +app.UseHttpsRedirection(); + +var summaries = new[] +{ + "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" +}; + +app.MapGet("/weatherforecast", () => +{ + var forecast = Enumerable.Range(1, 5).Select(index => + new WeatherForecast + ( + DateOnly.FromDateTime(DateTime.Now.AddDays(index)), + Random.Shared.Next(-20, 55), + summaries[Random.Shared.Next(summaries.Length)] + )) + .ToArray(); + return forecast; +}) +.WithName("GetWeatherForecast") +.WithOpenApi(); + +app.Run(); + +record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary) +{ + public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); +} diff --git a/123/presence_api/Properties/launchSettings.json b/123/presence_api/Properties/launchSettings.json new file mode 100644 index 0000000..cf7571d --- /dev/null +++ b/123/presence_api/Properties/launchSettings.json @@ -0,0 +1,41 @@ +{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:6036", + "sslPort": 44357 + } + }, + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "http://localhost:5013", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "https://localhost:7117;http://localhost:5013", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/123/presence_api/appsettings.Development.json b/123/presence_api/appsettings.Development.json new file mode 100644 index 0000000..0c208ae --- /dev/null +++ b/123/presence_api/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/123/presence_api/appsettings.json b/123/presence_api/appsettings.json new file mode 100644 index 0000000..10f68b8 --- /dev/null +++ b/123/presence_api/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +} diff --git a/123/presence_api/presence_api.csproj b/123/presence_api/presence_api.csproj new file mode 100644 index 0000000..6ae6ebc --- /dev/null +++ b/123/presence_api/presence_api.csproj @@ -0,0 +1,18 @@ + + + + net8.0 + enable + enable + + + + + + + + + + + + diff --git a/123/presence_api/presence_api.http b/123/presence_api/presence_api.http new file mode 100644 index 0000000..1d91421 --- /dev/null +++ b/123/presence_api/presence_api.http @@ -0,0 +1,6 @@ +@presence_api_HostAddress = http://localhost:5013 + +GET {{presence_api_HostAddress}}/weatherforecast/ +Accept: application/json + +###