api
This commit is contained in:
parent
c804d8ce82
commit
c4cc23258f
6
Demo.sln
6
Demo.sln
@ -7,6 +7,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Demo", "Demo\Demo.csproj",
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Demo", "Demo", "{21AE5A7C-0B77-4766-AC1E-94A8E52F1ED5}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Demo", "Demo", "{21AE5A7C-0B77-4766-AC1E-94A8E52F1ED5}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "presence_api", "presence_api\presence_api.csproj", "{402295CE-4ED2-4358-8B81-312891047A36}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@ -17,6 +19,10 @@ Global
|
|||||||
{983820F6-FF31-4B3A-8593-831BC3904E80}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{983820F6-FF31-4B3A-8593-831BC3904E80}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{983820F6-FF31-4B3A-8593-831BC3904E80}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{983820F6-FF31-4B3A-8593-831BC3904E80}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{983820F6-FF31-4B3A-8593-831BC3904E80}.Release|Any CPU.Build.0 = Release|Any CPU
|
{983820F6-FF31-4B3A-8593-831BC3904E80}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{402295CE-4ED2-4358-8B81-312891047A36}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{402295CE-4ED2-4358-8B81-312891047A36}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{402295CE-4ED2-4358-8B81-312891047A36}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{402295CE-4ED2-4358-8B81-312891047A36}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
10
Demo/Demo/Data/Exceptions/GroupNotFoundException.cs
Normal file
10
Demo/Demo/Data/Exceptions/GroupNotFoundException.cs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Demo.Data.Exceptions
|
||||||
|
{
|
||||||
|
public class GroupNotFoundException : RepositoryException
|
||||||
|
{
|
||||||
|
public GroupNotFoundException(int groupId)
|
||||||
|
: base($"Ошибка: группа с идентификатором {groupId} не найдена. Проверьте, правильный ли ID.") { }
|
||||||
|
}
|
||||||
|
}
|
9
Demo/Demo/Data/Exceptions/RepositoryException.cs
Normal file
9
Demo/Demo/Data/Exceptions/RepositoryException.cs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Demo.Data.Exceptions
|
||||||
|
{
|
||||||
|
public class RepositoryException : Exception
|
||||||
|
{
|
||||||
|
public RepositoryException(string message) : base(message) { }
|
||||||
|
}
|
||||||
|
}
|
10
Demo/Demo/Data/Exceptions/UserNotFoundException.cs
Normal file
10
Demo/Demo/Data/Exceptions/UserNotFoundException.cs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Demo.Data.Exceptions
|
||||||
|
{
|
||||||
|
public class UserNotFoundException : RepositoryException
|
||||||
|
{
|
||||||
|
public UserNotFoundException(Guid userGuid)
|
||||||
|
: base($"Ошибка: пользователь с GUID {userGuid} не найден. Проверьте правильность введенного значения.") { }
|
||||||
|
}
|
||||||
|
}
|
15
Demo/Demo/Data/LocalData/Entity/Group.cs
Normal file
15
Demo/Demo/Data/LocalData/Entity/Group.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Demo.domain.Models
|
||||||
|
{
|
||||||
|
public class GroupLocalEntity
|
||||||
|
{
|
||||||
|
public required int Id { get; set; }
|
||||||
|
public required string Name { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
8
Demo/Demo/Data/LocalData/Entity/Presence.cs
Normal file
8
Demo/Demo/Data/LocalData/Entity/Presence.cs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
public class PresenceLocalEntity
|
||||||
|
{
|
||||||
|
public Guid UserGuid { get; set; }
|
||||||
|
public int GroupId { get; set; }
|
||||||
|
public int LessonNumber { get; set; }
|
||||||
|
public DateTime Date { get; set; }
|
||||||
|
public bool IsAttedance { get; set; }
|
||||||
|
}
|
29
Demo/Demo/Data/LocalData/Entity/User.cs
Normal file
29
Demo/Demo/Data/LocalData/Entity/User.cs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Demo.domain.Models
|
||||||
|
{
|
||||||
|
public class UserLocalEntity : IEquatable<UserLocalEntity>
|
||||||
|
{
|
||||||
|
public Guid Guid { get; set; }
|
||||||
|
public required string FIO { get; set; }
|
||||||
|
|
||||||
|
// Добавлено новое свойство GroupId
|
||||||
|
public required int GroupId { get; set; }
|
||||||
|
|
||||||
|
public bool Equals(UserLocalEntity? other)
|
||||||
|
{
|
||||||
|
if (other == null) return false;
|
||||||
|
return this.Guid.Equals(other.Guid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
return Guid.GetHashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return $"{FIO} (Guid: {Guid}, GroupId: {GroupId})";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
36
Demo/Demo/Data/LocalData/LocalStaticData.cs
Normal file
36
Demo/Demo/Data/LocalData/LocalStaticData.cs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
using Demo.domain.Models;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.NetworkInformation;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Demo.Data.LocalData
|
||||||
|
{
|
||||||
|
public static class LocalStaticData
|
||||||
|
{
|
||||||
|
public static List<GroupLocalEntity> groups => new List<GroupLocalEntity>
|
||||||
|
|
||||||
|
{
|
||||||
|
new GroupLocalEntity{ Id = 1, Name = "ИП1-21" },
|
||||||
|
new GroupLocalEntity{ Id = 2, Name = "ИП1-22" },
|
||||||
|
new GroupLocalEntity{ Id = 3, Name = "ИП1-23" },
|
||||||
|
};
|
||||||
|
|
||||||
|
public static List<UserLocalEntity> users => new List<UserLocalEntity>
|
||||||
|
{
|
||||||
|
new UserLocalEntity{Guid=Guid.Parse("e6b9964d-ea9f-420a-84b9-af9633bbfab9"), FIO = "RandomFio", GroupId = 1 },
|
||||||
|
new UserLocalEntity{Guid=Guid.Parse("8388d931-5bef-41be-a152-78f1aca980ed"), FIO = "RandomFio1", GroupId = 2 },
|
||||||
|
new UserLocalEntity{Guid=Guid.Parse("ed174548-49ed-4503-a902-c970cbf27173"), FIO = "RandomFio2", GroupId = 3 },
|
||||||
|
new UserLocalEntity{Guid=Guid.Parse("614c0a23-5bd5-43ae-b48e-d5750afbc282"), FIO = "RandomFio3", GroupId = 1 },
|
||||||
|
new UserLocalEntity { Guid=Guid.Parse("efcc1473-c116-4244-b3f7-f2341a5c3003"), FIO = "RandomFio4", GroupId = 2 },
|
||||||
|
new UserLocalEntity { Guid=Guid.Parse("60640fb3-ace2-4cad-81d5-a0a58bc2dbbd"), FIO = "RandomFio5", GroupId = 3 },
|
||||||
|
};
|
||||||
|
|
||||||
|
public static List<PresenceLocalEntity> presences => new List<PresenceLocalEntity>
|
||||||
|
{
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
16
Demo/Demo/Data/RemoteData/RemoteDataBase/DAO/Group.cs
Normal file
16
Demo/Demo/Data/RemoteData/RemoteDataBase/DAO/Group.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Demo.Data.RemoteData.RemoteDataBase.DAO
|
||||||
|
{
|
||||||
|
public class GroupDao
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public required string Name { get; set; }
|
||||||
|
|
||||||
|
public IEnumerable<UserDao> User { get; set; }
|
||||||
|
}
|
||||||
|
}
|
27
Demo/Demo/Data/RemoteData/RemoteDataBase/DAO/Presence.cs
Normal file
27
Demo/Demo/Data/RemoteData/RemoteDataBase/DAO/Presence.cs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Demo.Data.RemoteData.RemoteDataBase.DAO
|
||||||
|
{
|
||||||
|
public class PresenceDao
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
public Guid UserGuid { get; set; }
|
||||||
|
|
||||||
|
// Указывает, присутствовал ли пользователь на уроке (по умолчанию - да)
|
||||||
|
public bool IsAttedance { get; set; } = true;
|
||||||
|
|
||||||
|
// Дата урока.
|
||||||
|
public DateOnly Date { get; set; }
|
||||||
|
|
||||||
|
// Номер урока.
|
||||||
|
public int LessonNumber { get; set; }
|
||||||
|
|
||||||
|
// Связанный объект пользователя, если требуется (может быть null)
|
||||||
|
public virtual UserDao? UserDao { get; set; } = null;
|
||||||
|
}
|
||||||
|
}
|
35
Demo/Demo/Data/RemoteData/RemoteDataBase/DAO/User.cs
Normal file
35
Demo/Demo/Data/RemoteData/RemoteDataBase/DAO/User.cs
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Demo.Data.RemoteData.RemoteDataBase.DAO
|
||||||
|
{
|
||||||
|
public class UserDao
|
||||||
|
{
|
||||||
|
// Уникальный идентификатор пользователя
|
||||||
|
public Guid Guid { get; set; }
|
||||||
|
|
||||||
|
// Идентификатор пользователя (например, для базы данных)
|
||||||
|
public int UserId { get; set; }
|
||||||
|
|
||||||
|
public string FIO { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
// Идентификатор группы, к которой принадлежит пользователь
|
||||||
|
public int GroupId { get; set; }
|
||||||
|
|
||||||
|
// Группа, к которой относится данный пользователь.
|
||||||
|
private GroupDao? _group;
|
||||||
|
public virtual GroupDao Group
|
||||||
|
{
|
||||||
|
get => _group ?? throw new InvalidOperationException("Группа не задана");
|
||||||
|
set => _group = value ?? throw new ArgumentNullException(nameof(Group), "Группа не может быть null.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Список информации о присутствии пользователя на уроках
|
||||||
|
private IEnumerable<PresenceDao> _presences = new List<PresenceDao>();
|
||||||
|
public virtual IEnumerable<PresenceDao> Presences
|
||||||
|
{
|
||||||
|
get => _presences;
|
||||||
|
set => _presences = value ?? throw new ArgumentNullException(nameof(Presences), "Посещаемость не может быть null.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
public class GroupPresenceSummary
|
||||||
|
{
|
||||||
|
// Количество учеников в данной группе
|
||||||
|
public int UserCount { get; set; }
|
||||||
|
|
||||||
|
// Количество уроков
|
||||||
|
public int LessonCount { get; set; }
|
||||||
|
|
||||||
|
// Средний уровень посещаемости группы (в процентах)
|
||||||
|
public double TotalAttendancePercentage { get; set; }
|
||||||
|
|
||||||
|
// Список данных о посещаемости для каждого ученика
|
||||||
|
public List<UserAttendance> UserAttendances { get; set; } = new List<UserAttendance>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Информация о посещаемости отдельного ученика
|
||||||
|
public class UserAttendance
|
||||||
|
{
|
||||||
|
public Guid UserGuid { get; set; }
|
||||||
|
|
||||||
|
// Число уроков, которые посещал ученик
|
||||||
|
public double Attended { get; set; }
|
||||||
|
|
||||||
|
// Число уроков, которые пропустил ученик
|
||||||
|
public double Missed { get; set; }
|
||||||
|
|
||||||
|
// Процент посещаемости (посещенные/общее число уроков)
|
||||||
|
public double AttendanceRate { get; set; }
|
||||||
|
}
|
@ -0,0 +1,61 @@
|
|||||||
|
using Demo.Data.RemoteData.RemoteDataBase.DAO;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Demo.Data.RemoteData.RemoteDataBase
|
||||||
|
{
|
||||||
|
public class RemoteDatabaseContext : DbContext
|
||||||
|
{
|
||||||
|
|
||||||
|
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||||
|
{
|
||||||
|
optionsBuilder.UseNpgsql("Host=45.67.56.214;" +
|
||||||
|
"Port=5421;" +
|
||||||
|
"Username=user10;" +
|
||||||
|
"Database=user10;" +
|
||||||
|
"Password=FY1rOnvu");
|
||||||
|
}
|
||||||
|
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
// Настройка ключа и генерации GroupDao
|
||||||
|
modelBuilder.Entity<GroupDao>()
|
||||||
|
.HasKey(group => group.Id); // Устанавливаем Id как первичный ключ
|
||||||
|
modelBuilder.Entity<GroupDao>()
|
||||||
|
.Property(group => group.Id)
|
||||||
|
.ValueGeneratedOnAdd(); // Указываем, что Id будет автоматически генерироваться при добавлении
|
||||||
|
|
||||||
|
// Настройка ключа и генерации UserDao
|
||||||
|
modelBuilder.Entity<UserDao>()
|
||||||
|
.HasKey(user => user.Guid); // Устанавливаем Guid как первичный ключ
|
||||||
|
modelBuilder.Entity<UserDao>()
|
||||||
|
.Property(user => user.Guid)
|
||||||
|
.ValueGeneratedOnAdd(); // Указываем, что Guid будет автоматически генерироваться при добавлении
|
||||||
|
|
||||||
|
// Настройка составного ключа PresenceDao
|
||||||
|
modelBuilder.Entity<PresenceDao>()
|
||||||
|
.HasKey(presense => new // Определяем составной ключ
|
||||||
|
{
|
||||||
|
presense.UserGuid,
|
||||||
|
presense.Date,
|
||||||
|
presense.IsAttedance,
|
||||||
|
presense.LessonNumber
|
||||||
|
});
|
||||||
|
|
||||||
|
// Настройка связи между UserDao и PresenceDao
|
||||||
|
modelBuilder.Entity<PresenceDao>()
|
||||||
|
.HasOne(p => p.UserDao) // Указываем, что PresenceDao имеет одну связь с UserDao
|
||||||
|
.WithMany() // Указываем, что у UserDao может быть много записей PresenceDao
|
||||||
|
.HasForeignKey(p => p.UserGuid) // Указываем внешний ключ UserGuid
|
||||||
|
.OnDelete(DeleteBehavior.Cascade); // Указываем поведение при удалении (удаление связанных записей)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Определение наборов данных для каждой сущности
|
||||||
|
public DbSet<GroupDao> Groups { get; set; } // Набор данных для GroupDao
|
||||||
|
public DbSet<UserDao> Users { get; set; } // Набор данных для UserDao
|
||||||
|
public DbSet<PresenceDao> PresenceDaos { get; set; } // Набор данных для PresenceDao
|
||||||
|
}
|
||||||
|
}
|
64
Demo/Demo/Data/Repository/AdminRepositoryImpl.cs
Normal file
64
Demo/Demo/Data/Repository/AdminRepositoryImpl.cs
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
using Demo.Data.RemoteData.RemoteDataBase.DAO;
|
||||||
|
using Demo.Data.RemoteData.RemoteDataBase;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Demo.Data.Repository
|
||||||
|
{
|
||||||
|
public class AdminRepositoryImp : IAdminRepository
|
||||||
|
{
|
||||||
|
private readonly RemoteDatabaseContext _remoteDataBaseContext;
|
||||||
|
|
||||||
|
public AdminRepositoryImp(RemoteDatabaseContext remoteDataBaseContext)
|
||||||
|
{
|
||||||
|
_remoteDataBaseContext = remoteDataBaseContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool AddStudents(GroupDao group, List<string> students)
|
||||||
|
{
|
||||||
|
_remoteDataBaseContext.Groups.Add(group);
|
||||||
|
_remoteDataBaseContext.SaveChanges();
|
||||||
|
foreach (string student in students)
|
||||||
|
{
|
||||||
|
var user = new UserDao
|
||||||
|
{
|
||||||
|
FIO = student,
|
||||||
|
GroupId = group.Id,
|
||||||
|
Group = _remoteDataBaseContext.Groups.Where(x => x.Id == group.Id).FirstOrDefault(),
|
||||||
|
};
|
||||||
|
_remoteDataBaseContext.Users.Add(user);
|
||||||
|
}
|
||||||
|
_remoteDataBaseContext.SaveChanges();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<GroupDao> GetAllGroupsWithStudents()
|
||||||
|
{
|
||||||
|
return _remoteDataBaseContext.Groups.Select(x => new GroupDao
|
||||||
|
{
|
||||||
|
Id = x.Id,
|
||||||
|
Name = x.Name,
|
||||||
|
User = _remoteDataBaseContext.Users.Where(it => it.GroupId == x.Id).ToList()
|
||||||
|
}).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserDao GetStudentInfo(int userId)
|
||||||
|
{
|
||||||
|
return _remoteDataBaseContext.Users.Where(x => x.UserId == userId).FirstOrDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool RemoveUserById(int userId, int groupId)
|
||||||
|
{
|
||||||
|
var userLocal = _remoteDataBaseContext.Users
|
||||||
|
.Where(x => x.UserId == userId && x.GroupId == groupId).FirstOrDefault();
|
||||||
|
if (userLocal == null) return false;
|
||||||
|
|
||||||
|
_remoteDataBaseContext.Users.Remove(userLocal);
|
||||||
|
_remoteDataBaseContext.SaveChanges();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
60
Demo/Demo/Data/Repository/GroupRepositoryImpl.cs
Normal file
60
Demo/Demo/Data/Repository/GroupRepositoryImpl.cs
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
using Demo.Data.Exceptions;
|
||||||
|
using Demo.Data.LocalData;
|
||||||
|
using Demo.Data.RemoteData.RemoteDataBase.DAO;
|
||||||
|
using Demo.Data.Repository;
|
||||||
|
using Demo.domain.Models;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
public class GroupRepositoryImpl : IGroupRepository
|
||||||
|
{
|
||||||
|
private List<GroupLocalEntity> _groups = LocalStaticData.groups;
|
||||||
|
|
||||||
|
// Получение группы на основе заданного идентификатора.
|
||||||
|
public GroupLocalEntity? GetGroupById(int groupId)
|
||||||
|
{
|
||||||
|
// Ищем первую группу с заданным идентификатором
|
||||||
|
return _groups.FirstOrDefault(g => g.Id == groupId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Получение всех групп
|
||||||
|
public List<GroupLocalEntity> GetAllGroup() => _groups; // Возвращаем весь список групп
|
||||||
|
|
||||||
|
// Добавление новой группы
|
||||||
|
public bool AddGroup(GroupLocalEntity group)
|
||||||
|
{
|
||||||
|
// Проверка на существование группы с таким же id
|
||||||
|
if (_groups.Any(g => g.Id == group.Id))
|
||||||
|
return false; // Если существует, возвращаем false
|
||||||
|
|
||||||
|
// Установка нового Id для группы
|
||||||
|
group.Id = _groups.Any() ? _groups.Max(g => g.Id) + 1 : 1; // Если группы существуют, находим максимальный id и увеличиваем его на 1, в другом случае устанавливаем id = 1
|
||||||
|
_groups.Add(group); // Добавляем группу в список
|
||||||
|
return true; // Возвращаем true, если добавление прошло успешно
|
||||||
|
}
|
||||||
|
|
||||||
|
// Метод обновления существующей группы по id
|
||||||
|
public bool UpdateGroupById(int groupID, GroupLocalEntity updatedGroup)
|
||||||
|
{
|
||||||
|
// Получение существующей группы по id
|
||||||
|
var existingGroup = GetGroupById(groupID);
|
||||||
|
if (existingGroup == null)
|
||||||
|
return false; // Если группа не найдена, возвращаем false
|
||||||
|
|
||||||
|
// Обновление имени существующей группы
|
||||||
|
existingGroup.Name = updatedGroup.Name;
|
||||||
|
return true; // Возвращаем true, если обновление прошло успешно
|
||||||
|
}
|
||||||
|
|
||||||
|
// Метод удаления группы по id
|
||||||
|
public bool RemoveGroupById(int groupID)
|
||||||
|
{
|
||||||
|
// Вывод существующей группы по id
|
||||||
|
var existingGroup = GetGroupById(groupID);
|
||||||
|
if (existingGroup == null)
|
||||||
|
return false; // Если группа не найдена, возвращаем false
|
||||||
|
|
||||||
|
_groups.Remove(existingGroup); // Удаляем группу
|
||||||
|
return true; // Возвращаем true, если удаление прошло успешно
|
||||||
|
}
|
||||||
|
}
|
17
Demo/Demo/Data/Repository/IAdminRepository.cs
Normal file
17
Demo/Demo/Data/Repository/IAdminRepository.cs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
using Demo.Data.RemoteData.RemoteDataBase.DAO;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Demo.Data.Repository
|
||||||
|
{
|
||||||
|
public interface IAdminRepository
|
||||||
|
{
|
||||||
|
bool AddStudents(GroupDao group, List<string> students);
|
||||||
|
IEnumerable<GroupDao> GetAllGroupsWithStudents();
|
||||||
|
UserDao GetStudentInfo(int userId);
|
||||||
|
bool RemoveUserById(int userId, int groupId);
|
||||||
|
}
|
||||||
|
}
|
28
Demo/Demo/Data/Repository/IGroupRepository.cs
Normal file
28
Demo/Demo/Data/Repository/IGroupRepository.cs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
using Demo.Data.RemoteData.RemoteDataBase.DAO;
|
||||||
|
using Demo.domain.Models;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Demo.Data.Repository
|
||||||
|
{
|
||||||
|
public interface IGroupRepository
|
||||||
|
{
|
||||||
|
// Получение группы по id
|
||||||
|
GroupLocalEntity GetGroupById(int groupID);
|
||||||
|
|
||||||
|
// Получение всех групп
|
||||||
|
List<GroupLocalEntity> GetAllGroup();
|
||||||
|
|
||||||
|
// Добавление новой группы
|
||||||
|
bool AddGroup(GroupLocalEntity newGroup);
|
||||||
|
|
||||||
|
// Обновление информации о группе по её id
|
||||||
|
bool UpdateGroupById(int groupID, GroupLocalEntity updatedGroup);
|
||||||
|
|
||||||
|
// Удаление группы по заданному id
|
||||||
|
bool RemoveGroupById(int groupID);
|
||||||
|
}
|
||||||
|
}
|
37
Demo/Demo/Data/Repository/IPresenceRepository.cs
Normal file
37
Demo/Demo/Data/Repository/IPresenceRepository.cs
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
using Demo.Data.RemoteData.RemoteDataBase.DAO;
|
||||||
|
using Demo.domain.Models;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Demo.Data.Repository
|
||||||
|
{
|
||||||
|
public interface IPresenceRepository
|
||||||
|
{
|
||||||
|
// Добавление информации о посещаемости
|
||||||
|
void AddPresence(PresenceLocalEntity presence);
|
||||||
|
|
||||||
|
// Получение сводной информации о посещаемости группы
|
||||||
|
public GroupPresenceSummary GetGeneralPresenceForGroup(int groupId);
|
||||||
|
|
||||||
|
// Извлечение данных о посещаемости группы в формате DAO
|
||||||
|
List<PresenceDao> GetAttendanceByGroup(int groupId);
|
||||||
|
|
||||||
|
// Получение записи о посещаемости для указанной группы
|
||||||
|
List<PresenceLocalEntity> GetPresenceByGroup(int groupId);
|
||||||
|
|
||||||
|
// Извлечение записи о посещаемости группы за конкретную дату
|
||||||
|
List<PresenceLocalEntity> GetPresenceByGroupAndDate(int groupId, DateTime date);
|
||||||
|
|
||||||
|
// Определение последней даты посещения для указанной группы
|
||||||
|
DateOnly? GetLastDateByGroupId(int groupId);
|
||||||
|
|
||||||
|
// Обновление статуса посещаемости ученика в заданном диапазоне уроков
|
||||||
|
bool UpdateAttention(Guid UserGuid, int groupId, int firstLesson, int lastLesson, DateOnly date, bool isAttendance);
|
||||||
|
|
||||||
|
// Сохранение записи о посещаемости для указанной группы
|
||||||
|
void SavePresence(List<PresenceLocalEntity> presences);
|
||||||
|
|
||||||
|
// Пометка ученика как "отсутствующего"
|
||||||
|
void MarkUserAsAbsent(Guid userGuid, int firstLessonNumber, int lastLessonNumber);
|
||||||
|
}
|
||||||
|
}
|
15
Demo/Demo/Data/Repository/IUserRepository.cs
Normal file
15
Demo/Demo/Data/Repository/IUserRepository.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
using Demo.Data.RemoteData.RemoteDataBase.DAO;
|
||||||
|
using Demo.domain.Models;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Demo.Data.Repository
|
||||||
|
{
|
||||||
|
public interface IUserRepository
|
||||||
|
{
|
||||||
|
IEnumerable<UserLocalEnity> GetAllUsers { get; }
|
||||||
|
bool RemoveUserByGuid(Guid userGuid); // удаление по Guid
|
||||||
|
UserLocalEnity? UpdateUser(UserLocalEnity user); // обновление данных ученика
|
||||||
|
List<UserDao> GetUserNames(); // получение списка пользователей с их именами
|
||||||
|
}
|
||||||
|
}
|
79
Demo/Demo/Data/Repository/PresenceRepositoryImpl.cs
Normal file
79
Demo/Demo/Data/Repository/PresenceRepositoryImpl.cs
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
using Demo.Data.RemoteData.RemoteDataBase.DAO;
|
||||||
|
using Demo.domain.Models;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace Demo.Data.Repository
|
||||||
|
{
|
||||||
|
public class PresenceRepositoryImpl
|
||||||
|
{
|
||||||
|
private readonly List<PresenceLocalEntity> _presences = new List<PresenceLocalEntity>();
|
||||||
|
|
||||||
|
// Сохранение информации о присутствии
|
||||||
|
public void SavePresence(List<PresenceLocalEntity> presences)
|
||||||
|
{
|
||||||
|
foreach (var presence in presences)
|
||||||
|
{
|
||||||
|
// Ищем существующую запись о присутствии по дате, пользователю и номеру урока
|
||||||
|
var existing = _presences.FirstOrDefault(p =>
|
||||||
|
p.Date == presence.Date &&
|
||||||
|
p.UserGuid == presence.UserGuid &&
|
||||||
|
p.LessonNumber == presence.LessonNumber);
|
||||||
|
|
||||||
|
// Если запись не найдена, добавляем новую
|
||||||
|
if (existing == null)
|
||||||
|
{
|
||||||
|
_presences.Add(presence);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Если запись найдена, обновляем статус присутствия
|
||||||
|
existing.IsAttedance = presence.IsAttedance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Метод добавления новой записи о присутствии
|
||||||
|
public void AddPresence(PresenceLocalEntity presence)
|
||||||
|
{
|
||||||
|
// Проверяем, что объект не равен null
|
||||||
|
if (presence == null) throw new ArgumentNullException(nameof(presence));
|
||||||
|
|
||||||
|
// Добавляем новую запись
|
||||||
|
_presences.Add(presence);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Метод получения записей о присутствии по id группы
|
||||||
|
public List<PresenceLocalEntity> GetPresenceByGroup(int groupId)
|
||||||
|
{
|
||||||
|
// Фильтруем записи по id группы и возвращаем их в виде списка
|
||||||
|
return _presences.Where(p => p.GroupId == groupId).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Метод получения записей о присутствии по id группы и дате
|
||||||
|
public List<PresenceLocalEntity> GetPresenceByGroupAndDate(int groupId, DateTime date)
|
||||||
|
{
|
||||||
|
// Фильтруем записи по id группы и дате, возвращая их в список
|
||||||
|
return _presences.Where(p => p.GroupId == groupId && p.Date.Date == date.Date).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Метод для пометки пользователя как отсутствующего
|
||||||
|
public void MarkUserAsAbsent(Guid userGuid, int firstLessonNumber, int lastLessonNumber)
|
||||||
|
{
|
||||||
|
// Проходим по всем урокам
|
||||||
|
foreach (var lesson in Enumerable.Range(firstLessonNumber, lastLessonNumber - firstLessonNumber + 1))
|
||||||
|
{
|
||||||
|
// Ищем запись о присутствии пользователя на текущем уроке
|
||||||
|
var presence = _presences.FirstOrDefault(p => p.UserGuid == userGuid && p.LessonNumber == lesson);
|
||||||
|
|
||||||
|
// Если запись не найдена, помечаем ее как отсутствующую
|
||||||
|
if (presence != null)
|
||||||
|
{
|
||||||
|
// Помечаем отсутствующего
|
||||||
|
presence.IsAttedance = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
84
Demo/Demo/Data/Repository/SQLGroupRepositoryImpl.cs
Normal file
84
Demo/Demo/Data/Repository/SQLGroupRepositoryImpl.cs
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
using Demo.Data.Exceptions;
|
||||||
|
using Demo.Data.LocalData;
|
||||||
|
using Demo.Data.RemoteData.RemoteDataBase;
|
||||||
|
using Demo.Data.RemoteData.RemoteDataBase.DAO;
|
||||||
|
using Demo.Data.Repository;
|
||||||
|
using Demo.domain.Models;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
public class SQLGroupRepositoryImpl : IGroupRepository
|
||||||
|
{
|
||||||
|
private readonly RemoteDatabaseContext _remoteDatabaseContext;
|
||||||
|
|
||||||
|
public SQLGroupRepositoryImpl(RemoteDatabaseContext remoteDatabaseContext)
|
||||||
|
{
|
||||||
|
_remoteDatabaseContext = remoteDatabaseContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Метод получения группы по id
|
||||||
|
public GroupLocalEntity? GetGroupById(int groupId)
|
||||||
|
{
|
||||||
|
// Ищем группу в бд по id
|
||||||
|
var groupDao = _remoteDatabaseContext.Groups.FirstOrDefault(g => g.Id == groupId);
|
||||||
|
|
||||||
|
// Если группа найдена, создаем и возвращаем объект GroupLocalEntity
|
||||||
|
return groupDao != null ? new GroupLocalEntity { Id = groupDao.Id, Name = groupDao.Name } : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Метод получения всех групп
|
||||||
|
public List<GroupLocalEntity> GetAllGroup()
|
||||||
|
{
|
||||||
|
return _remoteDatabaseContext.Groups
|
||||||
|
.Select(g => new GroupLocalEntity { Id = g.Id, Name = g.Name })
|
||||||
|
.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Метод добавления новой группы
|
||||||
|
public bool AddGroup(GroupLocalEntity group)
|
||||||
|
{
|
||||||
|
// Проверяем, существует ли уже группа с таким id
|
||||||
|
if (_remoteDatabaseContext.Groups.Any(g => g.Id == group.Id))
|
||||||
|
return false; // Если существует, возвращаем false
|
||||||
|
|
||||||
|
// Создаем объект GroupDao и добавляем его в бд
|
||||||
|
var groupDao = new GroupDao { Id = group.Id, Name = group.Name };
|
||||||
|
_remoteDatabaseContext.Groups.Add(groupDao);
|
||||||
|
|
||||||
|
// Сохраняем изменения в бд
|
||||||
|
_remoteDatabaseContext.SaveChanges();
|
||||||
|
return true; // Возвращаем true, если группа добавлена
|
||||||
|
}
|
||||||
|
|
||||||
|
// Метод обновления существующей группы
|
||||||
|
public bool UpdateGroupById(int groupID, GroupLocalEntity updatedGroup)
|
||||||
|
{
|
||||||
|
// Ищем группу по ее id
|
||||||
|
var existingGroup = _remoteDatabaseContext.Groups.FirstOrDefault(g => g.Id == groupID);
|
||||||
|
|
||||||
|
// Если группа не найдена, возвращаем false
|
||||||
|
if (existingGroup == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Обновляем имя группы и сохраняем изменения
|
||||||
|
existingGroup.Name = updatedGroup.Name;
|
||||||
|
_remoteDatabaseContext.SaveChanges();
|
||||||
|
return true; // Возвращаем true, если группа обновлена
|
||||||
|
}
|
||||||
|
|
||||||
|
// Метод удаления группы по id
|
||||||
|
public bool RemoveGroupById(int groupID)
|
||||||
|
{
|
||||||
|
// Ищем группу по заданному id
|
||||||
|
var existingGroup = _remoteDatabaseContext.Groups.FirstOrDefault(g => g.Id == groupID);
|
||||||
|
|
||||||
|
// Группа не найдена, возвращаем false
|
||||||
|
if (existingGroup == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Удаляем группу из бд
|
||||||
|
_remoteDatabaseContext.Groups.Remove(existingGroup);
|
||||||
|
_remoteDatabaseContext.SaveChanges();
|
||||||
|
return true; // Возвращаем true, если группа удалена
|
||||||
|
}
|
||||||
|
}
|
208
Demo/Demo/Data/Repository/SQLPresenceRepositoryImpl.cs
Normal file
208
Demo/Demo/Data/Repository/SQLPresenceRepositoryImpl.cs
Normal file
@ -0,0 +1,208 @@
|
|||||||
|
using Demo.Data.RemoteData.RemoteDataBase;
|
||||||
|
using Demo.Data.RemoteData.RemoteDataBase.DAO;
|
||||||
|
using Demo.domain.Models;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace Demo.Data.Repository
|
||||||
|
{
|
||||||
|
public class SQLPresenceRepositoryImpl : IPresenceRepository
|
||||||
|
{
|
||||||
|
private readonly RemoteDatabaseContext _remoteDatabaseContext;
|
||||||
|
|
||||||
|
public SQLPresenceRepositoryImpl(RemoteDatabaseContext remoteDatabaseContext)
|
||||||
|
{
|
||||||
|
_remoteDatabaseContext = remoteDatabaseContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Сохранение списка посещаемости
|
||||||
|
public void SavePresence(List<PresenceLocalEntity> presences)
|
||||||
|
{
|
||||||
|
foreach (var presence in presences)
|
||||||
|
{
|
||||||
|
// Проверка на существование этой же записи о посещаемости
|
||||||
|
var existing = _remoteDatabaseContext.PresenceDaos.FirstOrDefault(p =>
|
||||||
|
p.Date == DateOnly.FromDateTime(presence.Date) &&
|
||||||
|
p.UserGuid == presence.UserGuid &&
|
||||||
|
p.LessonNumber == presence.LessonNumber);
|
||||||
|
|
||||||
|
if (existing == null) // Если запись не найдена, добавляем новую
|
||||||
|
{
|
||||||
|
_remoteDatabaseContext.PresenceDaos.Add(new PresenceDao
|
||||||
|
{
|
||||||
|
Date = DateOnly.FromDateTime(presence.Date),
|
||||||
|
IsAttedance = presence.IsAttedance,
|
||||||
|
LessonNumber = presence.LessonNumber,
|
||||||
|
UserGuid = presence.UserGuid
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else // Если запись найдена, обновляем статус посещаемости
|
||||||
|
{
|
||||||
|
existing.IsAttedance = presence.IsAttedance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_remoteDatabaseContext.SaveChanges(); // Фиксация изменений
|
||||||
|
}
|
||||||
|
|
||||||
|
// Добавление записи о посещаемости
|
||||||
|
public void AddPresence(PresenceLocalEntity presence)
|
||||||
|
{
|
||||||
|
if (presence == null) throw new ArgumentNullException(nameof(presence));
|
||||||
|
|
||||||
|
var newPresence = new PresenceDao
|
||||||
|
{
|
||||||
|
Date = DateOnly.FromDateTime(presence.Date),
|
||||||
|
UserGuid = presence.UserGuid,
|
||||||
|
LessonNumber = presence.LessonNumber,
|
||||||
|
IsAttedance = presence.IsAttedance
|
||||||
|
};
|
||||||
|
_remoteDatabaseContext.PresenceDaos.Add(newPresence);
|
||||||
|
_remoteDatabaseContext.SaveChanges(); // Сохранение изменений
|
||||||
|
}
|
||||||
|
|
||||||
|
// Получение списка посещаемости по ID группы
|
||||||
|
public List<PresenceLocalEntity> GetPresenceByGroup(int groupId)
|
||||||
|
{
|
||||||
|
return _remoteDatabaseContext.PresenceDaos
|
||||||
|
.Include(p => p.UserDao)
|
||||||
|
.Where(p => p.UserDao != null && p.UserDao.GroupId == groupId)
|
||||||
|
.Select(p => new PresenceLocalEntity
|
||||||
|
{
|
||||||
|
Date = p.Date.ToDateTime(TimeOnly.MinValue),
|
||||||
|
UserGuid = p.UserGuid,
|
||||||
|
LessonNumber = p.LessonNumber,
|
||||||
|
IsAttedance = p.IsAttedance
|
||||||
|
})
|
||||||
|
.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Получение списка посещаемости по ID группы и дате
|
||||||
|
public List<PresenceLocalEntity> GetPresenceByGroupAndDate(int groupId, DateTime date)
|
||||||
|
{
|
||||||
|
return _remoteDatabaseContext.PresenceDaos
|
||||||
|
.Include(p => p.UserDao)
|
||||||
|
.Where(p => p.UserDao != null && p.UserDao.GroupId == groupId && p.Date == DateOnly.FromDateTime(date))
|
||||||
|
.Select(p => new PresenceLocalEntity
|
||||||
|
{
|
||||||
|
Date = p.Date.ToDateTime(TimeOnly.MinValue),
|
||||||
|
UserGuid = p.UserGuid,
|
||||||
|
LessonNumber = p.LessonNumber,
|
||||||
|
IsAttedance = p.IsAttedance
|
||||||
|
})
|
||||||
|
.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Отметка пользователя как отсутствующего на уроках в заданном диапазоне
|
||||||
|
public void MarkUserAsAbsent(Guid userGuid, int firstLessonNumber, int lastLessonNumber)
|
||||||
|
{
|
||||||
|
var presences = _remoteDatabaseContext.PresenceDaos
|
||||||
|
.Where(p => p.UserGuid == userGuid && p.LessonNumber >= firstLessonNumber && p.LessonNumber <= lastLessonNumber)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
foreach (var presence in presences)
|
||||||
|
{
|
||||||
|
presence.IsAttedance = false; // Устанавливаем статус отсутствия
|
||||||
|
}
|
||||||
|
_remoteDatabaseContext.SaveChanges(); // Фиксация изменений
|
||||||
|
}
|
||||||
|
|
||||||
|
// Получение последней даты посещаемости по ID группы
|
||||||
|
public DateOnly? GetLastDateByGroupId(int groupId)
|
||||||
|
{
|
||||||
|
var lastDate = _remoteDatabaseContext.PresenceDaos
|
||||||
|
.Where(p => p.UserDao != null && p.UserDao.GroupId == groupId)
|
||||||
|
.OrderByDescending(p => p.Date)
|
||||||
|
.Select(p => p.Date)
|
||||||
|
.FirstOrDefault();
|
||||||
|
|
||||||
|
return lastDate == default ? (DateOnly?)null : lastDate; // Возвращаем последнюю дату или null, если записи отсутствуют
|
||||||
|
}
|
||||||
|
|
||||||
|
// Получение общей информации о посещаемости группы
|
||||||
|
public GroupPresenceSummary GetGeneralPresenceForGroup(int groupId)
|
||||||
|
{
|
||||||
|
// Извлечение всех записей о посещаемости для указанной группы
|
||||||
|
var presences = _remoteDatabaseContext.PresenceDaos
|
||||||
|
.Where(p => p.UserDao != null && p.UserDao.GroupId == groupId)
|
||||||
|
.ToList();
|
||||||
|
// Подсчет количества уникальных уроков по дате и номеру урока
|
||||||
|
var distinctLessons = presences
|
||||||
|
.Select(p => new { p.Date, p.LessonNumber })
|
||||||
|
.Distinct()
|
||||||
|
.Count();
|
||||||
|
// Получение уникальных идентификаторов пользователей
|
||||||
|
var userGuids = presences.Select(p => p.UserGuid).Distinct().ToList();
|
||||||
|
// Подсчет общего количества посещений
|
||||||
|
double totalAttendance = presences.Count(p => p.IsAttedance);
|
||||||
|
// Подсчет общего возможного количества посещений (количество пользователей * количество уникальных уроков)
|
||||||
|
double totalPossibleAttendance = userGuids.Count * distinctLessons;
|
||||||
|
// Получение информации о посещаемости для каждого пользователя
|
||||||
|
var userAttendances = userGuids.Select(userGuid =>
|
||||||
|
{
|
||||||
|
// Извлечение записей о посещаемости для конкретного пользователя
|
||||||
|
var userPresences = presences.Where(p => p.UserGuid == userGuid).ToList();
|
||||||
|
double attended = userPresences.Count(p => p.IsAttedance); // Подсчет посещенных уроков
|
||||||
|
double missed = userPresences.Count(p => !p.IsAttedance); // Подсчет пропущенных уроков
|
||||||
|
|
||||||
|
return new UserAttendance
|
||||||
|
{
|
||||||
|
// Расчет процента посещаемости
|
||||||
|
UserGuid = userGuid,
|
||||||
|
Attended = attended,
|
||||||
|
Missed = missed,
|
||||||
|
AttendanceRate = attended + missed > 0
|
||||||
|
? (attended / (attended + missed)) * 100
|
||||||
|
: 0
|
||||||
|
};
|
||||||
|
}).ToList();
|
||||||
|
|
||||||
|
// Формирование итоговой информации о посещаемости группы
|
||||||
|
return new GroupPresenceSummary
|
||||||
|
{
|
||||||
|
UserCount = userGuids.Count, // Количество учеников в этой группе
|
||||||
|
LessonCount = distinctLessons, // Количество уроков
|
||||||
|
// Процент общей посещаемости
|
||||||
|
TotalAttendancePercentage = totalPossibleAttendance > 0
|
||||||
|
? (totalAttendance / totalPossibleAttendance) * 100
|
||||||
|
: 0,
|
||||||
|
UserAttendances = userAttendances // Список посещаемости учеников
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Обновление статуса посещаемости для ученика в заданном диапазоне уроков и дате
|
||||||
|
public bool UpdateAttention(Guid userGuid, int groupId, int firstLesson, int lastLesson, DateOnly date, bool isAttendance)
|
||||||
|
{
|
||||||
|
// Извлечение записей о посещаемости для указанного пользователя и условий
|
||||||
|
var presences = _remoteDatabaseContext.PresenceDaos
|
||||||
|
.Where(p => p.UserGuid == userGuid &&
|
||||||
|
p.UserDao != null &&
|
||||||
|
p.UserDao.GroupId == groupId &&
|
||||||
|
p.LessonNumber >= firstLesson &&
|
||||||
|
p.LessonNumber <= lastLesson &&
|
||||||
|
p.Date == date)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
if (presences.Any()) // Если записи найдены
|
||||||
|
{
|
||||||
|
foreach (var presence in presences)
|
||||||
|
{
|
||||||
|
presence.IsAttedance = isAttendance; // Обновление статуса посещаемости
|
||||||
|
}
|
||||||
|
_remoteDatabaseContext.SaveChanges(); // Сохранение изменений в бд
|
||||||
|
return true; // обновление прошло успешно
|
||||||
|
}
|
||||||
|
return false; // если записи не найдены, то обновление не прошло
|
||||||
|
}
|
||||||
|
|
||||||
|
// Получение списка посещаемости для группы
|
||||||
|
public List<PresenceDao> GetAttendanceByGroup(int groupId)
|
||||||
|
{
|
||||||
|
return _remoteDatabaseContext.PresenceDaos
|
||||||
|
.Include(p => p.UserDao) // информация о пользователе
|
||||||
|
.Where(p => p.UserDao != null && p.UserDao.GroupId == groupId) // фильтрация по id группы
|
||||||
|
.ToList(); // Возврат списка записей о посещаемости
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
85
Demo/Demo/Data/Repository/SQLUserRepositoryImpl.cs
Normal file
85
Demo/Demo/Data/Repository/SQLUserRepositoryImpl.cs
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
using Demo.Data.Exceptions;
|
||||||
|
using Demo.Data.RemoteData.RemoteDataBase;
|
||||||
|
using Demo.Data.RemoteData.RemoteDataBase.DAO;
|
||||||
|
using Demo.domain.Models;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace Demo.Data.Repository
|
||||||
|
{
|
||||||
|
public class SQLUserRepositoryImpl
|
||||||
|
{
|
||||||
|
private readonly RemoteDatabaseContext _remoteDatabaseContext;
|
||||||
|
public SQLUserRepositoryImpl(RemoteDatabaseContext remoteDatabaseContext)
|
||||||
|
{
|
||||||
|
_remoteDatabaseContext = remoteDatabaseContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Свойство для получения всех пользователей в виде списка
|
||||||
|
public IEnumerable<UserLocalEntity> GetAllUsers => _remoteDatabaseContext.Users
|
||||||
|
.Select(u => new UserLocalEntity
|
||||||
|
{
|
||||||
|
Guid = u.Guid,
|
||||||
|
FIO = u.FIO,
|
||||||
|
GroupId = u.GroupId
|
||||||
|
})
|
||||||
|
.ToList(); // Преобразуем результат в список
|
||||||
|
|
||||||
|
// Метод удаления пользователя по id
|
||||||
|
public bool RemoveUserByGuid(Guid userGuid)
|
||||||
|
{
|
||||||
|
// Ищем пользователя в бд по его id
|
||||||
|
var user = _remoteDatabaseContext.Users.FirstOrDefault(u => u.Guid == userGuid);
|
||||||
|
|
||||||
|
// Если пользователь не найден
|
||||||
|
if (user == null) throw new UserNotFoundException(userGuid);
|
||||||
|
|
||||||
|
// Удаляем пользователя
|
||||||
|
_remoteDatabaseContext.Users.Remove(user);
|
||||||
|
|
||||||
|
// Сохраняем изменения в бд
|
||||||
|
_remoteDatabaseContext.SaveChanges();
|
||||||
|
|
||||||
|
return true; // если удаление прошло, возвращаем true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Метод обновления информации о пользователе
|
||||||
|
public UserLocalEntity? UpdateUser(UserLocalEntity user)
|
||||||
|
{
|
||||||
|
// Ищем пользователя по id
|
||||||
|
var existingUser = _remoteDatabaseContext.Users.FirstOrDefault(u => u.Guid == user.Guid);
|
||||||
|
|
||||||
|
// Если пользователь не найден
|
||||||
|
if (existingUser == null) throw new UserNotFoundException(user.Guid);
|
||||||
|
|
||||||
|
// Обновляем информацию о пользователе
|
||||||
|
existingUser.FIO = user.FIO; // Обновляем ФИО
|
||||||
|
existingUser.GroupId = user.GroupId; // Обновляем id группы
|
||||||
|
|
||||||
|
// Сохраняем изменения в бд
|
||||||
|
_remoteDatabaseContext.SaveChanges();
|
||||||
|
|
||||||
|
// Возвращаем обновленный объект UserLocalEnity
|
||||||
|
return new UserLocalEntity
|
||||||
|
{
|
||||||
|
Guid = existingUser.Guid,
|
||||||
|
FIO = existingUser.FIO,
|
||||||
|
GroupId = existingUser.GroupId
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Метод получения всех пользователей в виде DAO
|
||||||
|
public IEnumerable<RemoteData.RemoteDataBase.DAO.UserDao> GetAllUsersDao =>
|
||||||
|
_remoteDatabaseContext.Users.ToList(); // Возвращаем список пользователей
|
||||||
|
|
||||||
|
// Метод получения списка пользователей с их ФИО и id
|
||||||
|
public List<UserDao> GetUserNames()
|
||||||
|
{
|
||||||
|
// Запрос пользователей и создание списка объектов UserDao с их GUID и ФИО
|
||||||
|
return _remoteDatabaseContext.Users
|
||||||
|
.Select(u => new UserDao { Guid = u.Guid, FIO = u.FIO })
|
||||||
|
.ToList(); // Преобразуем результат в список
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
66
Demo/Demo/Data/Repository/UserRepositoryImpl.cs
Normal file
66
Demo/Demo/Data/Repository/UserRepositoryImpl.cs
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
using Demo.Data.Exceptions;
|
||||||
|
using Demo.Data.LocalData;
|
||||||
|
using Demo.Data.RemoteData.RemoteDataBase.DAO;
|
||||||
|
using Demo.domain.Models;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace Demo.Data.Repository
|
||||||
|
{
|
||||||
|
public class UserRepositoryImpl
|
||||||
|
{
|
||||||
|
private List<UserLocalEntity> _users;
|
||||||
|
|
||||||
|
public UserRepositoryImpl()
|
||||||
|
{
|
||||||
|
_users = LocalStaticData.users;
|
||||||
|
}
|
||||||
|
public IEnumerable<UserLocalEntity> GetAllUsers => _users;
|
||||||
|
|
||||||
|
// Удаления пользователя по Guid
|
||||||
|
public bool RemoveUserByGuid(Guid userGuid)
|
||||||
|
{
|
||||||
|
// Ищем пользователя в списке по его Guid
|
||||||
|
var user = _users.FirstOrDefault(u => u.Guid == userGuid);
|
||||||
|
|
||||||
|
// Если пользователь не найден
|
||||||
|
if (user == null) throw new UserNotFoundException(userGuid);
|
||||||
|
|
||||||
|
// Удаляем пользователя
|
||||||
|
_users.Remove(user);
|
||||||
|
|
||||||
|
return true; // Если удаление прошло, возврашаем true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Метод обновления информации о пользователе
|
||||||
|
public UserLocalEntity? UpdateUser(UserLocalEntity user)
|
||||||
|
{
|
||||||
|
// Ищем пользователя по его Guid
|
||||||
|
var existingUser = _users.FirstOrDefault(u => u.Guid == user.Guid);
|
||||||
|
|
||||||
|
// Если пользователь не найден
|
||||||
|
if (existingUser == null) throw new UserNotFoundException(user.Guid);
|
||||||
|
|
||||||
|
// Обновляем информацию о пользователе
|
||||||
|
existingUser.FIO = user.FIO;
|
||||||
|
existingUser.GroupId = user.GroupId;
|
||||||
|
|
||||||
|
// Возвращаем обновленный объект UserLocalEnity
|
||||||
|
return existingUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Получение списка пользователей с их ФИО и Guid
|
||||||
|
public List<UserDao> GetUserNames()
|
||||||
|
{
|
||||||
|
// Запрос учеников и создание списка объектов UserDao с их GUID и ФИО
|
||||||
|
return _users
|
||||||
|
.Select(u => new UserDao
|
||||||
|
{
|
||||||
|
Guid = u.Guid,
|
||||||
|
FIO = u.FIO
|
||||||
|
})
|
||||||
|
.ToList(); // Преобразование в список
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
26
Demo/Demo/Demo.csproj
Normal file
26
Demo/Demo/Demo.csproj
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="ClosedXML" Version="0.104.2" />
|
||||||
|
<PackageReference Include="DocumentFormat.OpenXml" Version="3.1.1" />
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.10" />
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.10">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.1" />
|
||||||
|
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.10" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Data\RemoteData\RemoteApi\" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
14
Demo/Demo/Domain/Models/Group.cs
Normal file
14
Demo/Demo/Domain/Models/Group.cs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Demo.domain.Models
|
||||||
|
{
|
||||||
|
public class Group
|
||||||
|
{
|
||||||
|
public required int Id { get; set; }
|
||||||
|
public required string Name { get; set; }
|
||||||
|
}
|
||||||
|
}
|
19
Demo/Demo/Domain/Models/Presence.cs
Normal file
19
Demo/Demo/Domain/Models/Presence.cs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Demo.domain.Models
|
||||||
|
{
|
||||||
|
public class Presence
|
||||||
|
{
|
||||||
|
|
||||||
|
public required User User { get; set; }
|
||||||
|
public required int GroupId { get; set; }
|
||||||
|
public bool IsAttedance { get; set; } = true;
|
||||||
|
public required DateTime Date { get; set; }
|
||||||
|
|
||||||
|
public required int LessonNumber { get; set; }
|
||||||
|
}
|
||||||
|
}
|
7
Demo/Demo/Domain/Models/RequestModels/GroupAddRequest.cs
Normal file
7
Demo/Demo/Domain/Models/RequestModels/GroupAddRequest.cs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
namespace Demo.Domain.Models.RequestModels
|
||||||
|
{
|
||||||
|
public class GroupAddRequest
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
}
|
||||||
|
}
|
9
Demo/Demo/Domain/Models/ResponseModels/GroupResponse.cs
Normal file
9
Demo/Demo/Domain/Models/ResponseModels/GroupResponse.cs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
using Demo.Domain.Models.ResponseModels;
|
||||||
|
|
||||||
|
public class GroupResponse
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
public IEnumerable<UserResponse> User { get; set; }
|
||||||
|
|
||||||
|
}
|
16
Demo/Demo/Domain/Models/ResponseModels/PresencePesponse.cs
Normal file
16
Demo/Demo/Domain/Models/ResponseModels/PresencePesponse.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Demo.Domain.Models.ResponseModels
|
||||||
|
{
|
||||||
|
public class PresenceResponse
|
||||||
|
{
|
||||||
|
public required DateOnly Date { get; set; }
|
||||||
|
public int ClassNumber { get; set; }
|
||||||
|
public bool IsAttendence { get; set; }
|
||||||
|
public required UserResponse User { get; set; }
|
||||||
|
}
|
||||||
|
}
|
16
Demo/Demo/Domain/Models/ResponseModels/UserResponse.cs
Normal file
16
Demo/Demo/Domain/Models/ResponseModels/UserResponse.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Demo.Domain.Models.ResponseModels
|
||||||
|
{
|
||||||
|
public class UserResponse
|
||||||
|
{
|
||||||
|
public required string FIO { get; set; }
|
||||||
|
public int Id { get; set; }
|
||||||
|
public int GroupId { get; set; }
|
||||||
|
public GroupResponse Group { get; set; }
|
||||||
|
}
|
||||||
|
}
|
15
Demo/Demo/Domain/Models/User.cs
Normal file
15
Demo/Demo/Domain/Models/User.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Demo.domain.Models
|
||||||
|
{
|
||||||
|
public class User
|
||||||
|
{
|
||||||
|
public required string FIO { get; set; }
|
||||||
|
public Guid Guid { get; set; }
|
||||||
|
public required Group Group { get; set; }
|
||||||
|
}
|
||||||
|
}
|
62
Demo/Demo/Domain/UseCase/AdminUseCase.cs
Normal file
62
Demo/Demo/Domain/UseCase/AdminUseCase.cs
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
using Demo.Data.RemoteData.RemoteDataBase.DAO;
|
||||||
|
using Demo.Data.Repository;
|
||||||
|
using Demo.Domain.Models.ResponseModels;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Demo.Domain.UseCase
|
||||||
|
{
|
||||||
|
public class AdminUseCase
|
||||||
|
{
|
||||||
|
private readonly IAdminRepository _adminRepository;
|
||||||
|
private readonly IGroupRepository _groupRepository;
|
||||||
|
private readonly IUserRepository _userRepository;
|
||||||
|
|
||||||
|
|
||||||
|
public AdminUseCase(IAdminRepository adminRepository, IGroupRepository groupRepository, IUserRepository userRepository)
|
||||||
|
{
|
||||||
|
_adminRepository = adminRepository;
|
||||||
|
_groupRepository = groupRepository;
|
||||||
|
_userRepository = userRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<GroupResponse> GetAllGroupsWithStudents() =>
|
||||||
|
_adminRepository.GetAllGroupsWithStudents().Select(it => new GroupResponse
|
||||||
|
{
|
||||||
|
Name = it.Name,
|
||||||
|
Id = it.Id,
|
||||||
|
User = it.User.Where(u => u.GroupId == it.Id)
|
||||||
|
.Select(u => new UserResponse { Id = u.UserId, FIO = u.FIO })
|
||||||
|
.ToList()
|
||||||
|
})
|
||||||
|
.ToList();
|
||||||
|
public UserResponse GetStudentInfo(int userId)
|
||||||
|
{
|
||||||
|
|
||||||
|
var studentInfo = _adminRepository.GetStudentInfo(userId);
|
||||||
|
if (studentInfo == null) return null;
|
||||||
|
|
||||||
|
UserResponse user = new UserResponse
|
||||||
|
{
|
||||||
|
Id = userId,
|
||||||
|
FIO = _adminRepository.GetStudentInfo(userId).FIO,
|
||||||
|
GroupId = _adminRepository.GetStudentInfo(userId).GroupId
|
||||||
|
};
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool AddStudents(string GroupName, List<string> Students)
|
||||||
|
{
|
||||||
|
GroupDao groupDao = new GroupDao { Name = GroupName };
|
||||||
|
return _adminRepository.AddStudents(groupDao, Students);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool DeleteGroup(int groupId) => _groupRepository.RemoveGroupById(groupId);
|
||||||
|
|
||||||
|
public bool DeleteUserFromGroup(int userId, int groupId) => _adminRepository.RemoveUserById(userId, groupId);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
94
Demo/Demo/Domain/UseCase/GroupUseCase.cs
Normal file
94
Demo/Demo/Domain/UseCase/GroupUseCase.cs
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
using Demo.Data.LocalData;
|
||||||
|
using Demo.Data.Repository;
|
||||||
|
using Demo.domain.Models;
|
||||||
|
|
||||||
|
namespace Demo.Domain.UseCase
|
||||||
|
{
|
||||||
|
public class GroupUseCase
|
||||||
|
{
|
||||||
|
private readonly IGroupRepository _repositoryGroupImpl; // Репозиторий для работы с группами
|
||||||
|
|
||||||
|
// Конструктор для инициализации репозитория групп.
|
||||||
|
public GroupUseCase(IGroupRepository repositoryGroupImpl)
|
||||||
|
{
|
||||||
|
_repositoryGroupImpl = repositoryGroupImpl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Проверяет существование группы по её ID.
|
||||||
|
private GroupLocalEntity ValidateGroupExistence(int groupId)
|
||||||
|
{
|
||||||
|
var existingGroup = _repositoryGroupImpl.GetAllGroup()
|
||||||
|
.FirstOrDefault(g => g.Id == groupId);
|
||||||
|
|
||||||
|
if (existingGroup == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Группа не найдена.");
|
||||||
|
}
|
||||||
|
return existingGroup; // Возвращаем найденную группу
|
||||||
|
}
|
||||||
|
|
||||||
|
// Получить все группы
|
||||||
|
public List<Group> GetAllGroups()
|
||||||
|
{
|
||||||
|
return _repositoryGroupImpl.GetAllGroup()
|
||||||
|
.Select(it => new Group { Id = it.Id, Name = it.Name })
|
||||||
|
.ToList();// Список групп
|
||||||
|
}
|
||||||
|
|
||||||
|
// Найти группу по ID
|
||||||
|
public Group FindGroupById(int groupId)
|
||||||
|
{
|
||||||
|
return GetAllGroups().FirstOrDefault(g => g.Id == groupId) ?? throw new ArgumentException("Группа не найдена."); // если группа не найдена
|
||||||
|
}
|
||||||
|
|
||||||
|
// Добавить новую группу
|
||||||
|
public void AddGroup(string groupName)
|
||||||
|
{
|
||||||
|
var newId = _repositoryGroupImpl.GetAllGroup().Any()
|
||||||
|
? _repositoryGroupImpl.GetAllGroup().Max(g => g.Id) + 1 // Генерируем новый ID
|
||||||
|
: 1;
|
||||||
|
|
||||||
|
var newGroup = new GroupLocalEntity
|
||||||
|
{
|
||||||
|
Id = newId,
|
||||||
|
Name = groupName
|
||||||
|
};
|
||||||
|
_repositoryGroupImpl.AddGroup(newGroup); // Добавляем группу в репозиторий
|
||||||
|
}
|
||||||
|
|
||||||
|
// Удалить группу по ID
|
||||||
|
public void RemoveGroupById(int groupId)
|
||||||
|
{
|
||||||
|
ValidateGroupExistence(groupId); // Проверяем, существует ли группа
|
||||||
|
_repositoryGroupImpl.RemoveGroupById(groupId); // Удаляем группу
|
||||||
|
}
|
||||||
|
|
||||||
|
// Изменить название группы
|
||||||
|
public bool UpdateGroup(int groupId, string newGroupName)
|
||||||
|
{
|
||||||
|
var existingGroup = _repositoryGroupImpl.GetAllGroup()
|
||||||
|
.FirstOrDefault(g => g.Id == groupId);
|
||||||
|
|
||||||
|
if (existingGroup == null)
|
||||||
|
{
|
||||||
|
return false; // Если группа не найдена
|
||||||
|
}
|
||||||
|
|
||||||
|
existingGroup.Name = newGroupName; // Обновляем название
|
||||||
|
_repositoryGroupImpl.UpdateGroupById(existingGroup.Id, existingGroup); // Сохраняем изменения
|
||||||
|
return true;// True, если обновление успешно
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<GroupResponse> getAllGroup()
|
||||||
|
{
|
||||||
|
return _repositoryGroupImpl.GetAllGroup().Select(group =>
|
||||||
|
new GroupResponse
|
||||||
|
{
|
||||||
|
Id = group.Id,
|
||||||
|
Name = group.Name
|
||||||
|
}
|
||||||
|
).ToList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
109
Demo/Demo/Domain/UseCase/UseCaseGeneratePresence.cs
Normal file
109
Demo/Demo/Domain/UseCase/UseCaseGeneratePresence.cs
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
using Demo.Data.Repository;
|
||||||
|
using Demo.domain.Models;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Demo.Domain.UseCase
|
||||||
|
{
|
||||||
|
public class UseCaseGeneratePresence
|
||||||
|
{
|
||||||
|
public readonly IUserRepository _userRepository;
|
||||||
|
public readonly IPresenceRepository _presenceRepository;
|
||||||
|
private readonly IGroupRepository _groupRepository;
|
||||||
|
|
||||||
|
|
||||||
|
public UseCaseGeneratePresence(IUserRepository userRepository, IPresenceRepository presenceRepository, IGroupRepository groupRepository)
|
||||||
|
{
|
||||||
|
_userRepository = userRepository;
|
||||||
|
|
||||||
|
_presenceRepository = presenceRepository;
|
||||||
|
|
||||||
|
_groupRepository = groupRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Получение посещаемости по группе и дате
|
||||||
|
public List<PresenceLocalEntity> GetPresenceByGroupAndDate(int groupId, DateTime date)
|
||||||
|
{
|
||||||
|
// Запрос записей о посещаемости для указанной группы и даты из репозитория
|
||||||
|
return _presenceRepository.GetPresenceByGroupAndDate(groupId, date);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Генерация посещаемости для одного дня
|
||||||
|
public void GeneratePresenceForDay(int firstLesson, int lastLesson, int groupId, DateTime currentDate)
|
||||||
|
{
|
||||||
|
// Проверяем существование группы
|
||||||
|
if (!_groupRepository.GetAllGroup().Any(g => g.Id == groupId))
|
||||||
|
throw new ArgumentException($"Группа с ID {groupId} не существует.");
|
||||||
|
|
||||||
|
// Получаем пользователей группы
|
||||||
|
var users = _userRepository.GetAllUsers
|
||||||
|
.Where(u => u.GroupID == groupId) // Фильтруем пользователей по ID группы
|
||||||
|
.Select(u => u.Guid) // Извлекаем уникальные идентификаторы пользователей
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
// Генерируем записи посещаемости для всех уроков в указанный день
|
||||||
|
var presences = Enumerable.Range(firstLesson, lastLesson - firstLesson + 1)
|
||||||
|
.SelectMany(lesson => users.Select(userGuid => new PresenceLocalEntity
|
||||||
|
{
|
||||||
|
UserGuid = userGuid,
|
||||||
|
Date = currentDate,
|
||||||
|
LessonNumber = lesson,
|
||||||
|
IsAttedance = true // Устанавливаем статус присутствия на уроке
|
||||||
|
}))
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
// Сохраняем записи о посещаемости в репозитории
|
||||||
|
_presenceRepository.SavePresence(presences);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Генерация посещаемости недели
|
||||||
|
public void GeneratePresenceForWeek(int firstLesson, int lastLesson, int groupId, DateTime startTime)
|
||||||
|
{
|
||||||
|
// Проверка на существование группы
|
||||||
|
var groupExists = _groupRepository.GetAllGroup().Any(g => g.Id == groupId);
|
||||||
|
if (!groupExists)
|
||||||
|
{
|
||||||
|
throw new ArgumentException($"Группа с ID {groupId} не существует.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// посещаемость для каждого дня недели
|
||||||
|
for (int i = 0; i < 7; i++)
|
||||||
|
{
|
||||||
|
DateTime currentTime = startTime.AddDays(i); // Получаем дату текущего дня
|
||||||
|
GeneratePresenceForDay(firstLesson, lastLesson, groupId, currentTime); // Генерируем посещаемость для этого дня
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Отметить пользователя как отсутствующего
|
||||||
|
public void MarkUserAsAbsent(Guid userGuid, int groupId, int firstLesson, int lastLesson, DateTime date)
|
||||||
|
{
|
||||||
|
// Получение записи о посещаемости для указанной группы и даты
|
||||||
|
var presences = _presenceRepository.GetPresenceByGroupAndDate(groupId, date);
|
||||||
|
|
||||||
|
foreach (var presence in presences.Where(p => p.UserGuid == userGuid && p.LessonNumber >= firstLesson && p.LessonNumber <= lastLesson))
|
||||||
|
{
|
||||||
|
presence.IsAttedance = false; // отсутствие на уроке
|
||||||
|
}
|
||||||
|
|
||||||
|
// Сохранение изменения в репозитории
|
||||||
|
_presenceRepository.SavePresence(presences);
|
||||||
|
}
|
||||||
|
// Получение всех записей о посещаемости по группе
|
||||||
|
public List<PresenceLocalEntity> GetAllPresenceByGroup(int groupId)
|
||||||
|
{
|
||||||
|
// Запрос всех записей о посещаемости для указанной группы из репозитория
|
||||||
|
return _presenceRepository.GetPresenceByGroup(groupId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Получить общую информацию посещаемости для группы
|
||||||
|
public GroupPresenceSummary GetGeneralPresenceForGroup(int groupId)
|
||||||
|
{
|
||||||
|
// Запрос общей информации посещаемости для указанной группы из репозитория
|
||||||
|
return _presenceRepository.GetGeneralPresenceForGroup(groupId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
97
Demo/Demo/Domain/UseCase/UserUseCase.cs
Normal file
97
Demo/Demo/Domain/UseCase/UserUseCase.cs
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
using Demo.Data.Exceptions;
|
||||||
|
using Demo.Data.Repository;
|
||||||
|
using Demo.domain.Models;
|
||||||
|
|
||||||
|
namespace Demo.Domain.UseCase
|
||||||
|
{
|
||||||
|
public class UserUseCase
|
||||||
|
{
|
||||||
|
private readonly IUserRepository _repositoryUserImpl; // Репозиторий для работы с пользователями.
|
||||||
|
private readonly IGroupRepository _repositoryGroupImpl; // Репозиторий для работы с группами.
|
||||||
|
|
||||||
|
// Конструктор для инициализации зависимостей.
|
||||||
|
public UserUseCase(IUserRepository repositoryImpl, IGroupRepository repositoryGroupImpl)
|
||||||
|
{
|
||||||
|
_repositoryUserImpl = repositoryImpl; // Инициализация репозитория пользователей.
|
||||||
|
_repositoryGroupImpl = repositoryGroupImpl; // Инициализация репозитория групп.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Получить список всех пользователей с их группами.
|
||||||
|
public List<User> GetAllUsers() =>
|
||||||
|
_repositoryUserImpl.GetAllUsers.Join(
|
||||||
|
_repositoryGroupImpl.GetAllGroup(),
|
||||||
|
user => user.GroupID, // Ключ для соединения из пользователей (GroupID).
|
||||||
|
group => group.Id, // Ключ для соединения из групп (Id).
|
||||||
|
(user, group) => new User // Создание нового объекта User с информацией о группе.
|
||||||
|
{
|
||||||
|
FIO = user.FIO, // ФИО пользователя.
|
||||||
|
Guid = user.Guid, // Уникальный идентификатор пользователя.
|
||||||
|
Group = new Group { Id = group.Id, Name = group.Name } // Информация о группе.
|
||||||
|
}).ToList(); // Преобразование результата в список пользователей.
|
||||||
|
|
||||||
|
// Удалить пользователя по GUID.
|
||||||
|
public bool RemoveUserByGuid(Guid userGuid)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Возвращает true, если пользователь успешно удален, иначе false.
|
||||||
|
return _repositoryUserImpl.RemoveUserByGuid(userGuid);
|
||||||
|
}
|
||||||
|
catch (UserNotFoundException)
|
||||||
|
{
|
||||||
|
return false; // Если пользователь не найден, возвращаем false.
|
||||||
|
}
|
||||||
|
catch (RepositoryException)
|
||||||
|
{
|
||||||
|
return false; // Если произошла ошибка в репозитории, возвращаем false.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Обновить информацию о пользователе.
|
||||||
|
public User UpdateUser(User user)
|
||||||
|
{
|
||||||
|
// Обновление пользователя в репозитории.
|
||||||
|
var updatedUser = _repositoryUserImpl.UpdateUser(new UserLocalEnity
|
||||||
|
{
|
||||||
|
FIO = user.FIO,
|
||||||
|
GroupID = user.Group.Id,
|
||||||
|
Guid = user.Guid
|
||||||
|
}) ?? throw new Exception("Ошибка при обновлении пользователя.");
|
||||||
|
|
||||||
|
// Получение информации о группе после обновления пользователя.
|
||||||
|
var group = _repositoryGroupImpl.GetAllGroup()
|
||||||
|
.FirstOrDefault(g => g.Id == updatedUser.GroupID)
|
||||||
|
?? throw new Exception("Группа не найдена."); // Исключение, если группа не найдена.
|
||||||
|
|
||||||
|
// Возврат обновленного пользователя с информацией о группе.
|
||||||
|
return new User
|
||||||
|
{
|
||||||
|
FIO = updatedUser.FIO, // ФИО обновленного пользователя.
|
||||||
|
Guid = updatedUser.Guid, // Уникальный идентификатор обновленного пользователя.
|
||||||
|
Group = new Group { Id = group.Id, Name = group.Name } // Информация о группе.
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Найти пользователя по GUID.
|
||||||
|
public User FindUserByGuid(Guid userGuid)
|
||||||
|
{
|
||||||
|
// Поиск пользователя по его уникальному идентификатору.
|
||||||
|
var user = _repositoryUserImpl.GetAllUsers
|
||||||
|
.FirstOrDefault(u => u.Guid == userGuid)
|
||||||
|
?? throw new Exception("Пользователь не найден."); // Исключение, если пользователь не найден.
|
||||||
|
|
||||||
|
// Поиск группы пользователя по его ID группы.
|
||||||
|
var group = _repositoryGroupImpl.GetAllGroup()
|
||||||
|
.FirstOrDefault(g => g.Id == user.GroupID)
|
||||||
|
?? throw new Exception("Группа не найдена."); // Исключение, если группа не найдена.
|
||||||
|
|
||||||
|
// Возврат пользователя с информацией о группе.
|
||||||
|
return new User
|
||||||
|
{
|
||||||
|
FIO = user.FIO, // ФИО найденного пользователя.
|
||||||
|
Guid = user.Guid, // Уникальный идентификатор найденного пользователя.
|
||||||
|
Group = new Group { Id = group.Id, Name = group.Name } // Информация о группе найденного пользователя.
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
121
Demo/Demo/Migrations/20241031104311_InitialCreate.Designer.cs
generated
Normal file
121
Demo/Demo/Migrations/20241031104311_InitialCreate.Designer.cs
generated
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using Demo.Data.RemoteData.RemoteDataBase;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Demo.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(RemoteDatabaseContext))]
|
||||||
|
[Migration("20241031104311_InitialCreate")]
|
||||||
|
partial class InitialCreate
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
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("Demo.Data.RemoteData.RemoteDataBase.DAO.GroupDao", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("Groups");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Demo.Data.RemoteData.RemoteDataBase.DAO.PresenceDao", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("UserGuid")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<DateOnly>("Date")
|
||||||
|
.HasColumnType("date");
|
||||||
|
|
||||||
|
b.Property<bool>("IsAttedance")
|
||||||
|
.HasColumnType("boolean");
|
||||||
|
|
||||||
|
b.Property<int>("LessonNumber")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.Property<int>("GroupId")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.Property<Guid>("UserDaoGuid")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.HasKey("UserGuid", "Date", "IsAttedance", "LessonNumber");
|
||||||
|
|
||||||
|
b.HasIndex("UserDaoGuid");
|
||||||
|
|
||||||
|
b.ToTable("PresenceDaos");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Demo.Data.RemoteData.RemoteDataBase.DAO.UserDao", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Guid")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<string>("FIO")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<int>("GroupID")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.HasKey("Guid");
|
||||||
|
|
||||||
|
b.HasIndex("GroupID");
|
||||||
|
|
||||||
|
b.ToTable("Users");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Demo.Data.RemoteData.RemoteDataBase.DAO.PresenceDao", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Demo.Data.RemoteData.RemoteDataBase.DAO.UserDao", "UserDao")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserDaoGuid")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("UserDao");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Demo.Data.RemoteData.RemoteDataBase.DAO.UserDao", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Demo.Data.RemoteData.RemoteDataBase.DAO.GroupDao", "Group")
|
||||||
|
.WithMany("Users")
|
||||||
|
.HasForeignKey("GroupID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Group");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Demo.Data.RemoteData.RemoteDataBase.DAO.GroupDao", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("Users");
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
93
Demo/Demo/Migrations/20241031104311_InitialCreate.cs
Normal file
93
Demo/Demo/Migrations/20241031104311_InitialCreate.cs
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Demo.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class InitialCreate : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "Groups",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<int>(type: "integer", nullable: false)
|
||||||
|
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||||
|
Name = table.Column<string>(type: "text", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_Groups", x => x.Id);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "Users",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Guid = table.Column<Guid>(type: "uuid", nullable: false),
|
||||||
|
FIO = table.Column<string>(type: "text", nullable: false),
|
||||||
|
GroupID = table.Column<int>(type: "integer", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_Users", x => x.Guid);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_Users_Groups_GroupID",
|
||||||
|
column: x => x.GroupID,
|
||||||
|
principalTable: "Groups",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "PresenceDaos",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
UserGuid = table.Column<Guid>(type: "uuid", nullable: false),
|
||||||
|
IsAttedance = table.Column<bool>(type: "boolean", nullable: false),
|
||||||
|
Date = table.Column<DateOnly>(type: "date", nullable: false),
|
||||||
|
LessonNumber = table.Column<int>(type: "integer", nullable: false),
|
||||||
|
UserDaoGuid = table.Column<Guid>(type: "uuid", nullable: false),
|
||||||
|
GroupId = table.Column<int>(type: "integer", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_PresenceDaos", x => new { x.UserGuid, x.Date, x.IsAttedance, x.LessonNumber });
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_PresenceDaos_Users_UserDaoGuid",
|
||||||
|
column: x => x.UserDaoGuid,
|
||||||
|
principalTable: "Users",
|
||||||
|
principalColumn: "Guid",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_PresenceDaos_UserDaoGuid",
|
||||||
|
table: "PresenceDaos",
|
||||||
|
column: "UserDaoGuid");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_Users_GroupID",
|
||||||
|
table: "Users",
|
||||||
|
column: "GroupID");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "PresenceDaos");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "Users");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "Groups");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
118
Demo/Demo/Migrations/RemoteDatabaseContextModelSnapshot.cs
Normal file
118
Demo/Demo/Migrations/RemoteDatabaseContextModelSnapshot.cs
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using Demo.Data.RemoteData.RemoteDataBase;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Demo.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("Demo.Data.RemoteData.RemoteDataBase.DAO.GroupDao", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("Groups");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Demo.Data.RemoteData.RemoteDataBase.DAO.PresenceDao", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("UserGuid")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<DateOnly>("Date")
|
||||||
|
.HasColumnType("date");
|
||||||
|
|
||||||
|
b.Property<bool>("IsAttedance")
|
||||||
|
.HasColumnType("boolean");
|
||||||
|
|
||||||
|
b.Property<int>("LessonNumber")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.Property<int>("GroupId")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.Property<Guid>("UserDaoGuid")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.HasKey("UserGuid", "Date", "IsAttedance", "LessonNumber");
|
||||||
|
|
||||||
|
b.HasIndex("UserDaoGuid");
|
||||||
|
|
||||||
|
b.ToTable("PresenceDaos");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Demo.Data.RemoteData.RemoteDataBase.DAO.UserDao", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Guid")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<string>("FIO")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<int>("GroupID")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.HasKey("Guid");
|
||||||
|
|
||||||
|
b.HasIndex("GroupID");
|
||||||
|
|
||||||
|
b.ToTable("Users");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Demo.Data.RemoteData.RemoteDataBase.DAO.PresenceDao", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Demo.Data.RemoteData.RemoteDataBase.DAO.UserDao", "UserDao")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserDaoGuid")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("UserDao");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Demo.Data.RemoteData.RemoteDataBase.DAO.UserDao", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Demo.Data.RemoteData.RemoteDataBase.DAO.GroupDao", "Group")
|
||||||
|
.WithMany("Users")
|
||||||
|
.HasForeignKey("GroupID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Group");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Demo.Data.RemoteData.RemoteDataBase.DAO.GroupDao", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("Users");
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
124
Demo/Demo/UI/GroupConsole.cs
Normal file
124
Demo/Demo/UI/GroupConsole.cs
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
using Demo.Domain.UseCase;
|
||||||
|
using System;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Demo.UI
|
||||||
|
{
|
||||||
|
public class GroupConsole
|
||||||
|
{
|
||||||
|
private readonly GroupUseCase _groupUseCase;
|
||||||
|
|
||||||
|
public GroupConsole(GroupUseCase groupUseCase)
|
||||||
|
{
|
||||||
|
_groupUseCase = groupUseCase;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Поиск группы по id
|
||||||
|
public void FindGroupById(int groupId)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
var group = _groupUseCase.FindGroupById(groupId);
|
||||||
|
Console.WriteLine($"ID группы: {group.Id} Название группы: {group.Name}");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Ошибка: {ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// вывод всех групп
|
||||||
|
public void DisplayAllGroups()
|
||||||
|
{
|
||||||
|
Console.WriteLine("\n=== Список всех групп ===");
|
||||||
|
StringBuilder groupOutput = new StringBuilder();
|
||||||
|
|
||||||
|
// Получение списка групп
|
||||||
|
foreach (var group in _groupUseCase.GetAllGroups())
|
||||||
|
{
|
||||||
|
groupOutput.AppendLine($"{group.Id}\t{group.Name}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Вывод списка групп
|
||||||
|
Console.WriteLine(groupOutput);
|
||||||
|
Console.WriteLine("===========================\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Добавление новой группы
|
||||||
|
public void AddGroup(string groupName)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Проверяем, что имя группы валидно
|
||||||
|
ValidateGroupName(groupName);
|
||||||
|
|
||||||
|
// Добавляем новую группу через GroupUseCase
|
||||||
|
_groupUseCase.AddGroup(groupName);
|
||||||
|
Console.WriteLine($"\nГруппа {groupName} добавлена.\n");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Ошибка: {ex.Message}\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Удаление группы по её id
|
||||||
|
public void RemoveGroup(string groupIdStr)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
int groupId = int.Parse(groupIdStr);
|
||||||
|
ValidateGroupId(groupId);
|
||||||
|
|
||||||
|
// Удаление группы
|
||||||
|
_groupUseCase.RemoveGroupById(groupId);
|
||||||
|
Console.WriteLine($"Группа с ID: {groupId} удалена");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Ошибка: {ex.Message}\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Переименование группы
|
||||||
|
public void UpdateGroupName(int groupId, string newGroupName)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ValidateGroupName(newGroupName);
|
||||||
|
|
||||||
|
// Обновляем имя группы через
|
||||||
|
_groupUseCase.UpdateGroup(groupId, newGroupName);
|
||||||
|
Console.WriteLine($"\nНазвание группы с ID {groupId} изменено на {newGroupName}.\n");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Ошибка: {ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Проверка валидности имени группы
|
||||||
|
private void ValidateGroupName(string groupName)
|
||||||
|
{
|
||||||
|
// Проверяем, что имя группы не пустое и не состоит только из пробелов.
|
||||||
|
if (string.IsNullOrWhiteSpace(groupName))
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Имя группы не может быть пустым");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Проверка валидности идентификатора группы
|
||||||
|
private void ValidateGroupId(int groupId)
|
||||||
|
{
|
||||||
|
// Убедимся, что ID группы является положительным числом.
|
||||||
|
// Идентификаторы групп должны начинаться с 1, поэтому проверяем, что groupId больше или равен 1.
|
||||||
|
if (groupId < 1)
|
||||||
|
{
|
||||||
|
// Генерируем исключение с сообщением об ошибке, если ID группы некорректен.
|
||||||
|
throw new ArgumentException("Введите корректный ID группы.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
192
Demo/Demo/UI/MainMenu.cs
Normal file
192
Demo/Demo/UI/MainMenu.cs
Normal file
@ -0,0 +1,192 @@
|
|||||||
|
|
||||||
|
using Demo.Data.Repository;
|
||||||
|
using Demo.domain.Models;
|
||||||
|
using Demo.Domain.UseCase;
|
||||||
|
using Demo.UI.ui;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Demo.UI
|
||||||
|
{
|
||||||
|
public class MainMenuUI
|
||||||
|
{
|
||||||
|
private readonly UserConsole _userConsole;
|
||||||
|
private readonly GroupConsole _groupConsole;
|
||||||
|
private readonly PresenceConsole _presenceConsole;
|
||||||
|
|
||||||
|
|
||||||
|
public MainMenuUI(UserUseCase userUseCase, GroupUseCase groupUseCase, UseCaseGeneratePresence presenceUseCase, IPresenceRepository presenceRepository)
|
||||||
|
{
|
||||||
|
|
||||||
|
_userConsole = new UserConsole(userUseCase);
|
||||||
|
_groupConsole = new GroupConsole(groupUseCase);
|
||||||
|
_presenceConsole = new PresenceConsole(presenceUseCase, presenceRepository);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void DisplayMenu()
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
Console.WriteLine("МЕНЮ");
|
||||||
|
Console.WriteLine("1. Вывод всех учеников");
|
||||||
|
Console.WriteLine("2. Найти ученика");
|
||||||
|
Console.WriteLine("3. Обновить данные ученика");
|
||||||
|
Console.WriteLine("4. Удалить ученика");
|
||||||
|
Console.WriteLine("5. Список всех групп");
|
||||||
|
Console.WriteLine("6. Найти группу");
|
||||||
|
Console.WriteLine("7. Создать группу");
|
||||||
|
Console.WriteLine("8. Изменить название группы");
|
||||||
|
Console.WriteLine("9. Удалить группу");
|
||||||
|
Console.WriteLine("10. Вывод посещаемости на день");
|
||||||
|
Console.WriteLine("11. Вывод посещаемости на неделю");
|
||||||
|
Console.WriteLine("12. Вывод посещаемости группы");
|
||||||
|
Console.WriteLine("13. Вывод посещаемости группы за день");
|
||||||
|
Console.WriteLine("14. Отметить отсутствующего ученика");
|
||||||
|
Console.WriteLine("0. Выход");
|
||||||
|
Console.Write("Выберите команду: ");
|
||||||
|
|
||||||
|
string command = Console.ReadLine();
|
||||||
|
Console.WriteLine();
|
||||||
|
|
||||||
|
switch (command)
|
||||||
|
{
|
||||||
|
case "1": _userConsole.AllUsers(); break;
|
||||||
|
|
||||||
|
case "2": ExecuteGuidCommand("Введите Guid пользователя для поиска: ", _userConsole.FindUserByGuid); break;
|
||||||
|
|
||||||
|
case "3": ExecuteGuidCommand("Введите Guid пользователя для обновления: ", _userConsole.UpdateUserByGuid); break;
|
||||||
|
|
||||||
|
case "4": ExecuteGuidCommand("Введите Guid пользователя для удаления: ", _userConsole.RemoveUserByGuid); break;
|
||||||
|
|
||||||
|
case "5": _groupConsole.DisplayAllGroups(); break;
|
||||||
|
|
||||||
|
case "6": ExecuteIntCommand("Введите ID группы для поиска: ", _groupConsole.FindGroupById); break;
|
||||||
|
|
||||||
|
case "7":
|
||||||
|
Console.Write("Введите название новой группы: ");
|
||||||
|
_groupConsole.AddGroup(Console.ReadLine());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "8":
|
||||||
|
ExecuteIntCommand("Введите ID группы для изменения: ", id =>
|
||||||
|
{
|
||||||
|
Console.Write("Введите новое название группы: ");
|
||||||
|
_groupConsole.UpdateGroupName(id, Console.ReadLine());
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "9":
|
||||||
|
ExecuteIntCommand("Введите ID группы для удаления: ", id => _groupConsole.RemoveGroup(id.ToString()));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "10": GenerateAttendance("день"); break;
|
||||||
|
|
||||||
|
case "11": GenerateAttendance("неделю"); break;
|
||||||
|
|
||||||
|
case "12":
|
||||||
|
Console.Write("Введите дату (гггг-мм-дд): ");
|
||||||
|
DateTime date = DateTime.Parse(Console.ReadLine());
|
||||||
|
ExecuteIntCommand("Введите ID группы: ", id => _presenceConsole.DisplayPresence(date, id));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "13":
|
||||||
|
ExecuteIntCommand("Введите ID группы: ", _presenceConsole.DisplayAllPresenceByGroup);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "14":
|
||||||
|
Console.Write("Введите Guid пользователя: ");
|
||||||
|
Guid userGuid = Guid.Parse(Console.ReadLine());
|
||||||
|
GenerateAbsence(userGuid);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "0":
|
||||||
|
return;
|
||||||
|
|
||||||
|
default:
|
||||||
|
Console.WriteLine("Команда введена не правильно, попробуйте еще раз");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Метод для обработки команд с параметром Guid.
|
||||||
|
private void ExecuteGuidCommand(string prompt, Action<Guid> action)
|
||||||
|
{
|
||||||
|
Console.Write(prompt);
|
||||||
|
if (Guid.TryParse(Console.ReadLine(), out Guid guid))
|
||||||
|
{
|
||||||
|
action(guid);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Console.WriteLine("Неверный формат Guid.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Метод для обработки команд с параметром int.
|
||||||
|
private void ExecuteIntCommand(string prompt, Action<int> action)
|
||||||
|
{
|
||||||
|
Console.Write(prompt);
|
||||||
|
if (int.TryParse(Console.ReadLine(), out int value))
|
||||||
|
{
|
||||||
|
action(value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Console.WriteLine("Неверный формат числа.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Вывести посещаемость на день и неделю
|
||||||
|
private void GenerateAttendance(string period)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Console.Write("Введите номер первого занятия: ");
|
||||||
|
int firstLesson = int.Parse(Console.ReadLine());
|
||||||
|
Console.Write("Введите номер последнего занятия: ");
|
||||||
|
int lastLesson = int.Parse(Console.ReadLine());
|
||||||
|
|
||||||
|
ExecuteIntCommand("Введите ID группы: ", id =>
|
||||||
|
{
|
||||||
|
if (period == "день")
|
||||||
|
{
|
||||||
|
_presenceConsole.GeneratePresenceForDay(DateTime.Now, id, firstLesson, lastLesson);
|
||||||
|
Console.WriteLine("Посещаемость на день сгенерирована.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_presenceConsole.GeneratePresenceForWeek(DateTime.Now, id, firstLesson, lastLesson);
|
||||||
|
Console.WriteLine("Посещаемость на неделю сгенерирована.");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
Console.WriteLine("Ошибка");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Отметить ученика как отсутствующего
|
||||||
|
private void GenerateAbsence(Guid userGuid)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Console.Write("Введите номер первого занятия: ");
|
||||||
|
int firstLesson = int.Parse(Console.ReadLine());
|
||||||
|
Console.Write("Введите номер последнего занятия: ");
|
||||||
|
int lastLesson = int.Parse(Console.ReadLine());
|
||||||
|
|
||||||
|
ExecuteIntCommand("Введите ID группы: ", id =>
|
||||||
|
{
|
||||||
|
_presenceConsole.MarkUserAsAbsent(DateTime.Now, id, userGuid, firstLesson, lastLesson);
|
||||||
|
Console.WriteLine("Пользователь отмечен как отсутствующий.");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
Console.WriteLine("Ошибка ввода данных.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
210
Demo/Demo/UI/PresenceConsole.cs
Normal file
210
Demo/Demo/UI/PresenceConsole.cs
Normal file
@ -0,0 +1,210 @@
|
|||||||
|
using Demo.Data.RemoteData.RemoteDataBase;
|
||||||
|
using Demo.Data.Repository;
|
||||||
|
using Demo.domain.Models;
|
||||||
|
using Demo.Domain.UseCase;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Demo.UI
|
||||||
|
{
|
||||||
|
namespace ui
|
||||||
|
{
|
||||||
|
public class PresenceConsole
|
||||||
|
{
|
||||||
|
private readonly UseCaseGeneratePresence _presenceUseCase;
|
||||||
|
private readonly IPresenceRepository _presenceRepository;
|
||||||
|
private readonly RemoteDatabaseContext _remoteDatabaseContext;
|
||||||
|
|
||||||
|
public PresenceConsole(UseCaseGeneratePresence presenceUseCase, IPresenceRepository presenceRepository)
|
||||||
|
{
|
||||||
|
_presenceUseCase = presenceUseCase;
|
||||||
|
_presenceRepository = presenceRepository;
|
||||||
|
_remoteDatabaseContext = new RemoteDatabaseContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void GeneratePresenceForDay(DateTime date, int groupId, int firstLesson, int lastLesson)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Попытка сгенерировать посещаемость
|
||||||
|
_presenceUseCase.GeneratePresenceForDay(firstLesson, lastLesson, groupId, date);
|
||||||
|
Console.WriteLine("Посещаемость на день сгенерирована.");
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (ArgumentException ex)
|
||||||
|
{
|
||||||
|
// Обработка ошибки, если группа не существует
|
||||||
|
Console.WriteLine($"Ошибка при генерации посещаемости: {ex.Message}");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
// Обработка других ошибок
|
||||||
|
Console.WriteLine($"Неизвестная ошибка при генерации посещаемости: {ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void GeneratePresenceForWeek(DateTime date, int groupId, int firstLesson, int lastLesson)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_presenceUseCase.GeneratePresenceForWeek(firstLesson, lastLesson, groupId, date);
|
||||||
|
Console.WriteLine("Посещаемость на неделю успешно сгенерирована.");
|
||||||
|
}
|
||||||
|
catch (ArgumentException ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Ошибка при генерации посещаемости: {ex.Message}");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Неизвестная ошибка при генерации посещаемости: {ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Метод для отображения посещаемости на конкретную дату и группу
|
||||||
|
public void DisplayPresence(DateTime date, int groupId)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
List<PresenceLocalEntity> presences = _presenceUseCase.GetPresenceByGroupAndDate(groupId, date);
|
||||||
|
|
||||||
|
if (presences == null || presences.Count == 0)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Нет данных о посещаемости на выбранную дату.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine($"\n Посещаемость на {date:dd.MM.yyyy} ");
|
||||||
|
Console.WriteLine("-----------------------------------------------------");
|
||||||
|
|
||||||
|
// Сохраняем номер занятия для сравнения
|
||||||
|
int previousLessonNumber = -1;
|
||||||
|
|
||||||
|
foreach (var presence in presences)
|
||||||
|
{
|
||||||
|
// Проверяем, изменился ли номер занятия
|
||||||
|
if (previousLessonNumber != presence.LessonNumber)
|
||||||
|
{
|
||||||
|
Console.WriteLine("-----------------------------------------------------");
|
||||||
|
Console.WriteLine($" Занятие: {presence.LessonNumber} ");
|
||||||
|
Console.WriteLine("-----------------------------------------------------");
|
||||||
|
previousLessonNumber = presence.LessonNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Форматируем статус присутствия
|
||||||
|
string status = presence.IsAttedance ? "Присутствует" : "Отсутствует";
|
||||||
|
Console.WriteLine($"Пользователь (ID: {presence.UserGuid}) - Статус: {status}");
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine("-----------------------------------------------------");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Ошибка при отображении посещаемости: {ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void MarkUserAsAbsent(DateTime date, int groupId, Guid userGuid, int firstLesson, int lastLesson)
|
||||||
|
{
|
||||||
|
// Проверка существования группы
|
||||||
|
var groupExists = _remoteDatabaseContext.Groups.Any(g => g.Id == groupId);
|
||||||
|
if (!groupExists)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Ошибка: группа с таким ID не существует.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Проверка существования пользователя
|
||||||
|
var userExists = _remoteDatabaseContext.Users.Any(u => u.Guid == userGuid);
|
||||||
|
if (!userExists)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Ошибка: пользователь с таким GUID не существует.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Теперь, когда группа и пользователь найдены, вызываем метод для отметки отсутствия
|
||||||
|
_presenceUseCase.MarkUserAsAbsent(userGuid, groupId, firstLesson, lastLesson, date);
|
||||||
|
Console.WriteLine("Пользователь отмечен как отсутствующий.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void DisplayAllPresenceByGroup(int groupId)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var presences = _presenceUseCase.GetAllPresenceByGroup(groupId);
|
||||||
|
|
||||||
|
if (presences == null || !presences.Any())
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Нет данных о посещаемости для группы с ID: {groupId}.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Группируем записи посещаемости по дате
|
||||||
|
var groupedPresences = presences.GroupBy(p => p.Date);
|
||||||
|
|
||||||
|
foreach (var group in groupedPresences)
|
||||||
|
{
|
||||||
|
Console.WriteLine("===================================================");
|
||||||
|
Console.WriteLine($" Дата: {group.Key:dd.MM.yyyy} ");
|
||||||
|
Console.WriteLine("===================================================");
|
||||||
|
|
||||||
|
// Сохраняем номер занятия для сравнения
|
||||||
|
int previousLessonNumber = -1;
|
||||||
|
|
||||||
|
foreach (var presence in group)
|
||||||
|
{
|
||||||
|
// Проверяем, изменился ли номер занятия
|
||||||
|
if (previousLessonNumber != presence.LessonNumber)
|
||||||
|
{
|
||||||
|
Console.WriteLine("---------------------------------------------------");
|
||||||
|
Console.WriteLine($" Занятие: {presence.LessonNumber} ");
|
||||||
|
Console.WriteLine("---------------------------------------------------");
|
||||||
|
previousLessonNumber = presence.LessonNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Форматируем статус присутствия
|
||||||
|
string status = presence.IsAttedance ? "✅ Присутствует" : "❌ Отсутствует";
|
||||||
|
Console.WriteLine($"Пользователь (ID: {presence.UserGuid}) - Статус: {status}");
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine("---------------------------------------------------");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Ошибка при отображении посещаемости: {ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DisplayGeneralPresenceForGroup(int groupId)
|
||||||
|
{
|
||||||
|
var summary = _presenceRepository.GetGeneralPresenceForGroup(groupId);
|
||||||
|
|
||||||
|
Console.WriteLine($"Человек в группе: {summary.UserCount}, " +
|
||||||
|
$"Количество проведённых занятий: {summary.LessonCount}, " +
|
||||||
|
$"Общий процент посещаемости группы: {summary.TotalAttendancePercentage}%");
|
||||||
|
|
||||||
|
foreach (var user in summary.UserAttendances)
|
||||||
|
{
|
||||||
|
if (user.AttendanceRate < 40)
|
||||||
|
{
|
||||||
|
Console.ForegroundColor = ConsoleColor.Red;
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine($"GUID Пользователя: {user.UserGuid}, " +
|
||||||
|
$"Посетил: {user.Attended}, " +
|
||||||
|
$"Пропустил: {user.Missed}, " +
|
||||||
|
$"Процент посещаемости: {user.AttendanceRate}%");
|
||||||
|
Console.ResetColor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
120
Demo/Demo/UI/UserConsole.cs
Normal file
120
Demo/Demo/UI/UserConsole.cs
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
using Demo.domain.Models;
|
||||||
|
using Demo.Domain.UseCase;
|
||||||
|
using System;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Demo.UI
|
||||||
|
{
|
||||||
|
// Класс пользовательского интерфейса для работы с пользователями через консоль.
|
||||||
|
public class UserConsole
|
||||||
|
{
|
||||||
|
private readonly UserUseCase _userUseCase;
|
||||||
|
|
||||||
|
// Конструктор, принимающий экземпляр пользовательского UseCase.
|
||||||
|
public UserConsole(UserUseCase userUseCase)
|
||||||
|
{
|
||||||
|
_userUseCase = userUseCase;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Метод для отображения всех пользователей.
|
||||||
|
public void AllUsers()
|
||||||
|
{
|
||||||
|
// Получаем список всех пользователей.
|
||||||
|
var users = _userUseCase.GetAllUsers();
|
||||||
|
|
||||||
|
// Если пользователей нет, выводим сообщение и завершаем выполнение метода.
|
||||||
|
if (!users.Any())
|
||||||
|
{
|
||||||
|
Console.WriteLine("Нет пользователей.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Формируем и выводим список пользователей.
|
||||||
|
Console.WriteLine("\n=== Список пользователей ===");
|
||||||
|
foreach (var user in users)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"{user.Guid}\t{user.FIO}\t{user.Group.Name}");
|
||||||
|
}
|
||||||
|
Console.WriteLine("=============================\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Метод для поиска пользователя по Guid.
|
||||||
|
public void FindUserByGuid(Guid userGuid)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Ищем пользователя по указанному Guid.
|
||||||
|
var user = _userUseCase.FindUserByGuid(userGuid);
|
||||||
|
|
||||||
|
// Если пользователь найден, выводим его данные.
|
||||||
|
Console.WriteLine($"\nПользователь найден: {user.Guid}, {user.FIO}, {user.Group.Name}\n");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
// Если возникла ошибка, выводим сообщение об ошибке.
|
||||||
|
Console.WriteLine($"Ошибка: {ex.Message}\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Метод для удаления пользователя по Guid.
|
||||||
|
public void RemoveUserByGuid(Guid userGuid)
|
||||||
|
{
|
||||||
|
// Удаляем пользователя и выводим результат операции.
|
||||||
|
Console.WriteLine(_userUseCase.RemoveUserByGuid(userGuid)
|
||||||
|
? "Пользователь удален."
|
||||||
|
: "Пользователь не найден.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Метод для обновления данных пользователя по Guid.
|
||||||
|
public void UpdateUserByGuid(Guid userGuid)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Ищем пользователя по указанному Guid.
|
||||||
|
var user = _userUseCase.FindUserByGuid(userGuid);
|
||||||
|
|
||||||
|
// Выводим текущие данные пользователя.
|
||||||
|
Console.WriteLine($"\nТекущие данные: {user.FIO}, {user.Group.Name}");
|
||||||
|
|
||||||
|
// Запрашиваем новое ФИО у пользователя.
|
||||||
|
Console.Write("Введите новое ФИО: ");
|
||||||
|
string newFIO = Console.ReadLine();
|
||||||
|
|
||||||
|
// Проверяем, что новое ФИО не пустое.
|
||||||
|
if (string.IsNullOrWhiteSpace(newFIO))
|
||||||
|
{
|
||||||
|
Console.WriteLine("ФИО не может быть пустым.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Обновляем данные пользователя.
|
||||||
|
user.FIO = newFIO;
|
||||||
|
_userUseCase.UpdateUser(user);
|
||||||
|
Console.WriteLine("Пользователь обновлен.\n");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
// Если возникла ошибка, выводим сообщение об ошибке.
|
||||||
|
Console.WriteLine($"Ошибка: {ex.Message}\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Метод для проверки существования группы по ID.
|
||||||
|
private GroupLocalEntity ValidateGroupExistence(int groupId)
|
||||||
|
{
|
||||||
|
// Ищем группу с указанным ID среди всех пользователей.
|
||||||
|
var group = _userUseCase.GetAllUsers()
|
||||||
|
.Select(u => u.Group)
|
||||||
|
.FirstOrDefault(g => g.Id == groupId);
|
||||||
|
|
||||||
|
// Если группа не найдена, выбрасываем исключение.
|
||||||
|
if (group == null)
|
||||||
|
{
|
||||||
|
throw new Exception("Группа не найдена.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Возвращаем найденную группу как локальную сущность.
|
||||||
|
return new GroupLocalEntity { Id = group.Id, Name = group.Name };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
BIN
Demo/Demo/bin/Debug/net8.0/ClosedXML.Parser.dll
Normal file
BIN
Demo/Demo/bin/Debug/net8.0/ClosedXML.Parser.dll
Normal file
Binary file not shown.
BIN
Demo/Demo/bin/Debug/net8.0/ClosedXML.dll
Normal file
BIN
Demo/Demo/bin/Debug/net8.0/ClosedXML.dll
Normal file
Binary file not shown.
954
Demo/Demo/bin/Debug/net8.0/Demo.deps.json
Normal file
954
Demo/Demo/bin/Debug/net8.0/Demo.deps.json
Normal file
@ -0,0 +1,954 @@
|
|||||||
|
{
|
||||||
|
"runtimeTarget": {
|
||||||
|
"name": ".NETCoreApp,Version=v8.0",
|
||||||
|
"signature": ""
|
||||||
|
},
|
||||||
|
"compilationOptions": {},
|
||||||
|
"targets": {
|
||||||
|
".NETCoreApp,Version=v8.0": {
|
||||||
|
"Demo/1.0.0": {
|
||||||
|
"dependencies": {
|
||||||
|
"ClosedXML": "0.104.1",
|
||||||
|
"Microsoft.EntityFrameworkCore": "8.0.10",
|
||||||
|
"Microsoft.EntityFrameworkCore.Design": "8.0.10",
|
||||||
|
"Microsoft.Extensions.DependencyInjection": "8.0.1",
|
||||||
|
"Npgsql.EntityFrameworkCore.PostgreSQL": "8.0.10"
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"Demo.dll": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ClosedXML/0.104.1": {
|
||||||
|
"dependencies": {
|
||||||
|
"ClosedXML.Parser": "1.2.0",
|
||||||
|
"DocumentFormat.OpenXml": "3.0.1",
|
||||||
|
"ExcelNumberFormat": "1.1.0",
|
||||||
|
"RBush": "3.2.0",
|
||||||
|
"SixLabors.Fonts": "1.0.0",
|
||||||
|
"System.IO.Packaging": "8.0.0"
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"lib/netstandard2.1/ClosedXML.dll": {
|
||||||
|
"assemblyVersion": "0.104.1.0",
|
||||||
|
"fileVersion": "0.104.1.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ClosedXML.Parser/1.2.0": {
|
||||||
|
"runtime": {
|
||||||
|
"lib/netstandard2.1/ClosedXML.Parser.dll": {
|
||||||
|
"assemblyVersion": "1.0.0.0",
|
||||||
|
"fileVersion": "1.0.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"DocumentFormat.OpenXml/3.0.1": {
|
||||||
|
"dependencies": {
|
||||||
|
"DocumentFormat.OpenXml.Framework": "3.0.1"
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"lib/net8.0/DocumentFormat.OpenXml.dll": {
|
||||||
|
"assemblyVersion": "3.0.1.0",
|
||||||
|
"fileVersion": "3.0.1.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"DocumentFormat.OpenXml.Framework/3.0.1": {
|
||||||
|
"dependencies": {
|
||||||
|
"System.IO.Packaging": "8.0.0"
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"lib/net8.0/DocumentFormat.OpenXml.Framework.dll": {
|
||||||
|
"assemblyVersion": "3.0.1.0",
|
||||||
|
"fileVersion": "3.0.1.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ExcelNumberFormat/1.1.0": {
|
||||||
|
"runtime": {
|
||||||
|
"lib/netstandard2.0/ExcelNumberFormat.dll": {
|
||||||
|
"assemblyVersion": "1.1.0.0",
|
||||||
|
"fileVersion": "1.1.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Humanizer.Core/2.14.1": {
|
||||||
|
"runtime": {
|
||||||
|
"lib/net6.0/Humanizer.dll": {
|
||||||
|
"assemblyVersion": "2.14.0.0",
|
||||||
|
"fileVersion": "2.14.1.48190"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Microsoft.Bcl.AsyncInterfaces/6.0.0": {
|
||||||
|
"runtime": {
|
||||||
|
"lib/netstandard2.1/Microsoft.Bcl.AsyncInterfaces.dll": {
|
||||||
|
"assemblyVersion": "6.0.0.0",
|
||||||
|
"fileVersion": "6.0.21.52210"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Microsoft.CodeAnalysis.Analyzers/3.3.3": {},
|
||||||
|
"Microsoft.CodeAnalysis.Common/4.5.0": {
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.CodeAnalysis.Analyzers": "3.3.3",
|
||||||
|
"System.Collections.Immutable": "6.0.0",
|
||||||
|
"System.Reflection.Metadata": "6.0.1",
|
||||||
|
"System.Runtime.CompilerServices.Unsafe": "6.0.0",
|
||||||
|
"System.Text.Encoding.CodePages": "6.0.0"
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"lib/netcoreapp3.1/Microsoft.CodeAnalysis.dll": {
|
||||||
|
"assemblyVersion": "4.5.0.0",
|
||||||
|
"fileVersion": "4.500.23.10905"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"resources": {
|
||||||
|
"lib/netcoreapp3.1/cs/Microsoft.CodeAnalysis.resources.dll": {
|
||||||
|
"locale": "cs"
|
||||||
|
},
|
||||||
|
"lib/netcoreapp3.1/de/Microsoft.CodeAnalysis.resources.dll": {
|
||||||
|
"locale": "de"
|
||||||
|
},
|
||||||
|
"lib/netcoreapp3.1/es/Microsoft.CodeAnalysis.resources.dll": {
|
||||||
|
"locale": "es"
|
||||||
|
},
|
||||||
|
"lib/netcoreapp3.1/fr/Microsoft.CodeAnalysis.resources.dll": {
|
||||||
|
"locale": "fr"
|
||||||
|
},
|
||||||
|
"lib/netcoreapp3.1/it/Microsoft.CodeAnalysis.resources.dll": {
|
||||||
|
"locale": "it"
|
||||||
|
},
|
||||||
|
"lib/netcoreapp3.1/ja/Microsoft.CodeAnalysis.resources.dll": {
|
||||||
|
"locale": "ja"
|
||||||
|
},
|
||||||
|
"lib/netcoreapp3.1/ko/Microsoft.CodeAnalysis.resources.dll": {
|
||||||
|
"locale": "ko"
|
||||||
|
},
|
||||||
|
"lib/netcoreapp3.1/pl/Microsoft.CodeAnalysis.resources.dll": {
|
||||||
|
"locale": "pl"
|
||||||
|
},
|
||||||
|
"lib/netcoreapp3.1/pt-BR/Microsoft.CodeAnalysis.resources.dll": {
|
||||||
|
"locale": "pt-BR"
|
||||||
|
},
|
||||||
|
"lib/netcoreapp3.1/ru/Microsoft.CodeAnalysis.resources.dll": {
|
||||||
|
"locale": "ru"
|
||||||
|
},
|
||||||
|
"lib/netcoreapp3.1/tr/Microsoft.CodeAnalysis.resources.dll": {
|
||||||
|
"locale": "tr"
|
||||||
|
},
|
||||||
|
"lib/netcoreapp3.1/zh-Hans/Microsoft.CodeAnalysis.resources.dll": {
|
||||||
|
"locale": "zh-Hans"
|
||||||
|
},
|
||||||
|
"lib/netcoreapp3.1/zh-Hant/Microsoft.CodeAnalysis.resources.dll": {
|
||||||
|
"locale": "zh-Hant"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Microsoft.CodeAnalysis.CSharp/4.5.0": {
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.CodeAnalysis.Common": "4.5.0"
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"lib/netcoreapp3.1/Microsoft.CodeAnalysis.CSharp.dll": {
|
||||||
|
"assemblyVersion": "4.5.0.0",
|
||||||
|
"fileVersion": "4.500.23.10905"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"resources": {
|
||||||
|
"lib/netcoreapp3.1/cs/Microsoft.CodeAnalysis.CSharp.resources.dll": {
|
||||||
|
"locale": "cs"
|
||||||
|
},
|
||||||
|
"lib/netcoreapp3.1/de/Microsoft.CodeAnalysis.CSharp.resources.dll": {
|
||||||
|
"locale": "de"
|
||||||
|
},
|
||||||
|
"lib/netcoreapp3.1/es/Microsoft.CodeAnalysis.CSharp.resources.dll": {
|
||||||
|
"locale": "es"
|
||||||
|
},
|
||||||
|
"lib/netcoreapp3.1/fr/Microsoft.CodeAnalysis.CSharp.resources.dll": {
|
||||||
|
"locale": "fr"
|
||||||
|
},
|
||||||
|
"lib/netcoreapp3.1/it/Microsoft.CodeAnalysis.CSharp.resources.dll": {
|
||||||
|
"locale": "it"
|
||||||
|
},
|
||||||
|
"lib/netcoreapp3.1/ja/Microsoft.CodeAnalysis.CSharp.resources.dll": {
|
||||||
|
"locale": "ja"
|
||||||
|
},
|
||||||
|
"lib/netcoreapp3.1/ko/Microsoft.CodeAnalysis.CSharp.resources.dll": {
|
||||||
|
"locale": "ko"
|
||||||
|
},
|
||||||
|
"lib/netcoreapp3.1/pl/Microsoft.CodeAnalysis.CSharp.resources.dll": {
|
||||||
|
"locale": "pl"
|
||||||
|
},
|
||||||
|
"lib/netcoreapp3.1/pt-BR/Microsoft.CodeAnalysis.CSharp.resources.dll": {
|
||||||
|
"locale": "pt-BR"
|
||||||
|
},
|
||||||
|
"lib/netcoreapp3.1/ru/Microsoft.CodeAnalysis.CSharp.resources.dll": {
|
||||||
|
"locale": "ru"
|
||||||
|
},
|
||||||
|
"lib/netcoreapp3.1/tr/Microsoft.CodeAnalysis.CSharp.resources.dll": {
|
||||||
|
"locale": "tr"
|
||||||
|
},
|
||||||
|
"lib/netcoreapp3.1/zh-Hans/Microsoft.CodeAnalysis.CSharp.resources.dll": {
|
||||||
|
"locale": "zh-Hans"
|
||||||
|
},
|
||||||
|
"lib/netcoreapp3.1/zh-Hant/Microsoft.CodeAnalysis.CSharp.resources.dll": {
|
||||||
|
"locale": "zh-Hant"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Microsoft.CodeAnalysis.CSharp.Workspaces/4.5.0": {
|
||||||
|
"dependencies": {
|
||||||
|
"Humanizer.Core": "2.14.1",
|
||||||
|
"Microsoft.CodeAnalysis.CSharp": "4.5.0",
|
||||||
|
"Microsoft.CodeAnalysis.Common": "4.5.0",
|
||||||
|
"Microsoft.CodeAnalysis.Workspaces.Common": "4.5.0"
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"lib/netcoreapp3.1/Microsoft.CodeAnalysis.CSharp.Workspaces.dll": {
|
||||||
|
"assemblyVersion": "4.5.0.0",
|
||||||
|
"fileVersion": "4.500.23.10905"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"resources": {
|
||||||
|
"lib/netcoreapp3.1/cs/Microsoft.CodeAnalysis.CSharp.Workspaces.resources.dll": {
|
||||||
|
"locale": "cs"
|
||||||
|
},
|
||||||
|
"lib/netcoreapp3.1/de/Microsoft.CodeAnalysis.CSharp.Workspaces.resources.dll": {
|
||||||
|
"locale": "de"
|
||||||
|
},
|
||||||
|
"lib/netcoreapp3.1/es/Microsoft.CodeAnalysis.CSharp.Workspaces.resources.dll": {
|
||||||
|
"locale": "es"
|
||||||
|
},
|
||||||
|
"lib/netcoreapp3.1/fr/Microsoft.CodeAnalysis.CSharp.Workspaces.resources.dll": {
|
||||||
|
"locale": "fr"
|
||||||
|
},
|
||||||
|
"lib/netcoreapp3.1/it/Microsoft.CodeAnalysis.CSharp.Workspaces.resources.dll": {
|
||||||
|
"locale": "it"
|
||||||
|
},
|
||||||
|
"lib/netcoreapp3.1/ja/Microsoft.CodeAnalysis.CSharp.Workspaces.resources.dll": {
|
||||||
|
"locale": "ja"
|
||||||
|
},
|
||||||
|
"lib/netcoreapp3.1/ko/Microsoft.CodeAnalysis.CSharp.Workspaces.resources.dll": {
|
||||||
|
"locale": "ko"
|
||||||
|
},
|
||||||
|
"lib/netcoreapp3.1/pl/Microsoft.CodeAnalysis.CSharp.Workspaces.resources.dll": {
|
||||||
|
"locale": "pl"
|
||||||
|
},
|
||||||
|
"lib/netcoreapp3.1/pt-BR/Microsoft.CodeAnalysis.CSharp.Workspaces.resources.dll": {
|
||||||
|
"locale": "pt-BR"
|
||||||
|
},
|
||||||
|
"lib/netcoreapp3.1/ru/Microsoft.CodeAnalysis.CSharp.Workspaces.resources.dll": {
|
||||||
|
"locale": "ru"
|
||||||
|
},
|
||||||
|
"lib/netcoreapp3.1/tr/Microsoft.CodeAnalysis.CSharp.Workspaces.resources.dll": {
|
||||||
|
"locale": "tr"
|
||||||
|
},
|
||||||
|
"lib/netcoreapp3.1/zh-Hans/Microsoft.CodeAnalysis.CSharp.Workspaces.resources.dll": {
|
||||||
|
"locale": "zh-Hans"
|
||||||
|
},
|
||||||
|
"lib/netcoreapp3.1/zh-Hant/Microsoft.CodeAnalysis.CSharp.Workspaces.resources.dll": {
|
||||||
|
"locale": "zh-Hant"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Microsoft.CodeAnalysis.Workspaces.Common/4.5.0": {
|
||||||
|
"dependencies": {
|
||||||
|
"Humanizer.Core": "2.14.1",
|
||||||
|
"Microsoft.Bcl.AsyncInterfaces": "6.0.0",
|
||||||
|
"Microsoft.CodeAnalysis.Common": "4.5.0",
|
||||||
|
"System.Composition": "6.0.0",
|
||||||
|
"System.IO.Pipelines": "6.0.3",
|
||||||
|
"System.Threading.Channels": "6.0.0"
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"lib/netcoreapp3.1/Microsoft.CodeAnalysis.Workspaces.dll": {
|
||||||
|
"assemblyVersion": "4.5.0.0",
|
||||||
|
"fileVersion": "4.500.23.10905"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"resources": {
|
||||||
|
"lib/netcoreapp3.1/cs/Microsoft.CodeAnalysis.Workspaces.resources.dll": {
|
||||||
|
"locale": "cs"
|
||||||
|
},
|
||||||
|
"lib/netcoreapp3.1/de/Microsoft.CodeAnalysis.Workspaces.resources.dll": {
|
||||||
|
"locale": "de"
|
||||||
|
},
|
||||||
|
"lib/netcoreapp3.1/es/Microsoft.CodeAnalysis.Workspaces.resources.dll": {
|
||||||
|
"locale": "es"
|
||||||
|
},
|
||||||
|
"lib/netcoreapp3.1/fr/Microsoft.CodeAnalysis.Workspaces.resources.dll": {
|
||||||
|
"locale": "fr"
|
||||||
|
},
|
||||||
|
"lib/netcoreapp3.1/it/Microsoft.CodeAnalysis.Workspaces.resources.dll": {
|
||||||
|
"locale": "it"
|
||||||
|
},
|
||||||
|
"lib/netcoreapp3.1/ja/Microsoft.CodeAnalysis.Workspaces.resources.dll": {
|
||||||
|
"locale": "ja"
|
||||||
|
},
|
||||||
|
"lib/netcoreapp3.1/ko/Microsoft.CodeAnalysis.Workspaces.resources.dll": {
|
||||||
|
"locale": "ko"
|
||||||
|
},
|
||||||
|
"lib/netcoreapp3.1/pl/Microsoft.CodeAnalysis.Workspaces.resources.dll": {
|
||||||
|
"locale": "pl"
|
||||||
|
},
|
||||||
|
"lib/netcoreapp3.1/pt-BR/Microsoft.CodeAnalysis.Workspaces.resources.dll": {
|
||||||
|
"locale": "pt-BR"
|
||||||
|
},
|
||||||
|
"lib/netcoreapp3.1/ru/Microsoft.CodeAnalysis.Workspaces.resources.dll": {
|
||||||
|
"locale": "ru"
|
||||||
|
},
|
||||||
|
"lib/netcoreapp3.1/tr/Microsoft.CodeAnalysis.Workspaces.resources.dll": {
|
||||||
|
"locale": "tr"
|
||||||
|
},
|
||||||
|
"lib/netcoreapp3.1/zh-Hans/Microsoft.CodeAnalysis.Workspaces.resources.dll": {
|
||||||
|
"locale": "zh-Hans"
|
||||||
|
},
|
||||||
|
"lib/netcoreapp3.1/zh-Hant/Microsoft.CodeAnalysis.Workspaces.resources.dll": {
|
||||||
|
"locale": "zh-Hant"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Microsoft.EntityFrameworkCore/8.0.10": {
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.EntityFrameworkCore.Abstractions": "8.0.10",
|
||||||
|
"Microsoft.EntityFrameworkCore.Analyzers": "8.0.10",
|
||||||
|
"Microsoft.Extensions.Caching.Memory": "8.0.1",
|
||||||
|
"Microsoft.Extensions.Logging": "8.0.1"
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"lib/net8.0/Microsoft.EntityFrameworkCore.dll": {
|
||||||
|
"assemblyVersion": "8.0.10.0",
|
||||||
|
"fileVersion": "8.0.1024.46708"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Microsoft.EntityFrameworkCore.Abstractions/8.0.10": {
|
||||||
|
"runtime": {
|
||||||
|
"lib/net8.0/Microsoft.EntityFrameworkCore.Abstractions.dll": {
|
||||||
|
"assemblyVersion": "8.0.10.0",
|
||||||
|
"fileVersion": "8.0.1024.46708"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Microsoft.EntityFrameworkCore.Analyzers/8.0.10": {},
|
||||||
|
"Microsoft.EntityFrameworkCore.Design/8.0.10": {
|
||||||
|
"dependencies": {
|
||||||
|
"Humanizer.Core": "2.14.1",
|
||||||
|
"Microsoft.CodeAnalysis.CSharp.Workspaces": "4.5.0",
|
||||||
|
"Microsoft.EntityFrameworkCore.Relational": "8.0.10",
|
||||||
|
"Microsoft.Extensions.DependencyModel": "8.0.2",
|
||||||
|
"Mono.TextTemplating": "2.2.1"
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"lib/net8.0/Microsoft.EntityFrameworkCore.Design.dll": {
|
||||||
|
"assemblyVersion": "8.0.10.0",
|
||||||
|
"fileVersion": "8.0.1024.46708"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Microsoft.EntityFrameworkCore.Relational/8.0.10": {
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.EntityFrameworkCore": "8.0.10",
|
||||||
|
"Microsoft.Extensions.Configuration.Abstractions": "8.0.0"
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"lib/net8.0/Microsoft.EntityFrameworkCore.Relational.dll": {
|
||||||
|
"assemblyVersion": "8.0.10.0",
|
||||||
|
"fileVersion": "8.0.1024.46708"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Microsoft.Extensions.Caching.Abstractions/8.0.0": {
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.Extensions.Primitives": "8.0.0"
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"lib/net8.0/Microsoft.Extensions.Caching.Abstractions.dll": {
|
||||||
|
"assemblyVersion": "8.0.0.0",
|
||||||
|
"fileVersion": "8.0.23.53103"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Microsoft.Extensions.Caching.Memory/8.0.1": {
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.Extensions.Caching.Abstractions": "8.0.0",
|
||||||
|
"Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.2",
|
||||||
|
"Microsoft.Extensions.Logging.Abstractions": "8.0.2",
|
||||||
|
"Microsoft.Extensions.Options": "8.0.2",
|
||||||
|
"Microsoft.Extensions.Primitives": "8.0.0"
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"lib/net8.0/Microsoft.Extensions.Caching.Memory.dll": {
|
||||||
|
"assemblyVersion": "8.0.0.0",
|
||||||
|
"fileVersion": "8.0.1024.46610"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Microsoft.Extensions.Configuration.Abstractions/8.0.0": {
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.Extensions.Primitives": "8.0.0"
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"lib/net8.0/Microsoft.Extensions.Configuration.Abstractions.dll": {
|
||||||
|
"assemblyVersion": "8.0.0.0",
|
||||||
|
"fileVersion": "8.0.23.53103"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Microsoft.Extensions.DependencyInjection/8.0.1": {
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.2"
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"lib/net8.0/Microsoft.Extensions.DependencyInjection.dll": {
|
||||||
|
"assemblyVersion": "8.0.0.0",
|
||||||
|
"fileVersion": "8.0.1024.46610"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Microsoft.Extensions.DependencyInjection.Abstractions/8.0.2": {
|
||||||
|
"runtime": {
|
||||||
|
"lib/net8.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": {
|
||||||
|
"assemblyVersion": "8.0.0.0",
|
||||||
|
"fileVersion": "8.0.1024.46610"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Microsoft.Extensions.DependencyModel/8.0.2": {
|
||||||
|
"runtime": {
|
||||||
|
"lib/net8.0/Microsoft.Extensions.DependencyModel.dll": {
|
||||||
|
"assemblyVersion": "8.0.0.2",
|
||||||
|
"fileVersion": "8.0.1024.46610"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Microsoft.Extensions.Logging/8.0.1": {
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.Extensions.DependencyInjection": "8.0.1",
|
||||||
|
"Microsoft.Extensions.Logging.Abstractions": "8.0.2",
|
||||||
|
"Microsoft.Extensions.Options": "8.0.2"
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"lib/net8.0/Microsoft.Extensions.Logging.dll": {
|
||||||
|
"assemblyVersion": "8.0.0.0",
|
||||||
|
"fileVersion": "8.0.1024.46610"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Microsoft.Extensions.Logging.Abstractions/8.0.2": {
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.2"
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"lib/net8.0/Microsoft.Extensions.Logging.Abstractions.dll": {
|
||||||
|
"assemblyVersion": "8.0.0.0",
|
||||||
|
"fileVersion": "8.0.1024.46610"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Microsoft.Extensions.Options/8.0.2": {
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.2",
|
||||||
|
"Microsoft.Extensions.Primitives": "8.0.0"
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"lib/net8.0/Microsoft.Extensions.Options.dll": {
|
||||||
|
"assemblyVersion": "8.0.0.0",
|
||||||
|
"fileVersion": "8.0.224.6711"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Microsoft.Extensions.Primitives/8.0.0": {
|
||||||
|
"runtime": {
|
||||||
|
"lib/net8.0/Microsoft.Extensions.Primitives.dll": {
|
||||||
|
"assemblyVersion": "8.0.0.0",
|
||||||
|
"fileVersion": "8.0.23.53103"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Mono.TextTemplating/2.2.1": {
|
||||||
|
"dependencies": {
|
||||||
|
"System.CodeDom": "4.4.0"
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"lib/netstandard2.0/Mono.TextTemplating.dll": {
|
||||||
|
"assemblyVersion": "2.2.0.0",
|
||||||
|
"fileVersion": "2.2.1.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Npgsql/8.0.5": {
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.Extensions.Logging.Abstractions": "8.0.2"
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"lib/net8.0/Npgsql.dll": {
|
||||||
|
"assemblyVersion": "8.0.5.0",
|
||||||
|
"fileVersion": "8.0.5.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Npgsql.EntityFrameworkCore.PostgreSQL/8.0.10": {
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.EntityFrameworkCore": "8.0.10",
|
||||||
|
"Microsoft.EntityFrameworkCore.Abstractions": "8.0.10",
|
||||||
|
"Microsoft.EntityFrameworkCore.Relational": "8.0.10",
|
||||||
|
"Npgsql": "8.0.5"
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"lib/net8.0/Npgsql.EntityFrameworkCore.PostgreSQL.dll": {
|
||||||
|
"assemblyVersion": "8.0.10.0",
|
||||||
|
"fileVersion": "8.0.10.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"RBush/3.2.0": {
|
||||||
|
"runtime": {
|
||||||
|
"lib/net6.0/RBush.dll": {
|
||||||
|
"assemblyVersion": "3.0.0.0",
|
||||||
|
"fileVersion": "3.2.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"SixLabors.Fonts/1.0.0": {
|
||||||
|
"runtime": {
|
||||||
|
"lib/netcoreapp3.1/SixLabors.Fonts.dll": {
|
||||||
|
"assemblyVersion": "1.0.0.0",
|
||||||
|
"fileVersion": "1.0.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.CodeDom/4.4.0": {
|
||||||
|
"runtime": {
|
||||||
|
"lib/netstandard2.0/System.CodeDom.dll": {
|
||||||
|
"assemblyVersion": "4.0.0.0",
|
||||||
|
"fileVersion": "4.6.25519.3"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Collections.Immutable/6.0.0": {
|
||||||
|
"dependencies": {
|
||||||
|
"System.Runtime.CompilerServices.Unsafe": "6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Composition/6.0.0": {
|
||||||
|
"dependencies": {
|
||||||
|
"System.Composition.AttributedModel": "6.0.0",
|
||||||
|
"System.Composition.Convention": "6.0.0",
|
||||||
|
"System.Composition.Hosting": "6.0.0",
|
||||||
|
"System.Composition.Runtime": "6.0.0",
|
||||||
|
"System.Composition.TypedParts": "6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Composition.AttributedModel/6.0.0": {
|
||||||
|
"runtime": {
|
||||||
|
"lib/net6.0/System.Composition.AttributedModel.dll": {
|
||||||
|
"assemblyVersion": "6.0.0.0",
|
||||||
|
"fileVersion": "6.0.21.52210"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Composition.Convention/6.0.0": {
|
||||||
|
"dependencies": {
|
||||||
|
"System.Composition.AttributedModel": "6.0.0"
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"lib/net6.0/System.Composition.Convention.dll": {
|
||||||
|
"assemblyVersion": "6.0.0.0",
|
||||||
|
"fileVersion": "6.0.21.52210"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Composition.Hosting/6.0.0": {
|
||||||
|
"dependencies": {
|
||||||
|
"System.Composition.Runtime": "6.0.0"
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"lib/net6.0/System.Composition.Hosting.dll": {
|
||||||
|
"assemblyVersion": "6.0.0.0",
|
||||||
|
"fileVersion": "6.0.21.52210"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Composition.Runtime/6.0.0": {
|
||||||
|
"runtime": {
|
||||||
|
"lib/net6.0/System.Composition.Runtime.dll": {
|
||||||
|
"assemblyVersion": "6.0.0.0",
|
||||||
|
"fileVersion": "6.0.21.52210"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Composition.TypedParts/6.0.0": {
|
||||||
|
"dependencies": {
|
||||||
|
"System.Composition.AttributedModel": "6.0.0",
|
||||||
|
"System.Composition.Hosting": "6.0.0",
|
||||||
|
"System.Composition.Runtime": "6.0.0"
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"lib/net6.0/System.Composition.TypedParts.dll": {
|
||||||
|
"assemblyVersion": "6.0.0.0",
|
||||||
|
"fileVersion": "6.0.21.52210"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.IO.Packaging/8.0.0": {
|
||||||
|
"runtime": {
|
||||||
|
"lib/net8.0/System.IO.Packaging.dll": {
|
||||||
|
"assemblyVersion": "8.0.0.0",
|
||||||
|
"fileVersion": "8.0.23.53103"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.IO.Pipelines/6.0.3": {
|
||||||
|
"runtime": {
|
||||||
|
"lib/net6.0/System.IO.Pipelines.dll": {
|
||||||
|
"assemblyVersion": "6.0.0.0",
|
||||||
|
"fileVersion": "6.0.522.21309"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Reflection.Metadata/6.0.1": {
|
||||||
|
"dependencies": {
|
||||||
|
"System.Collections.Immutable": "6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Runtime.CompilerServices.Unsafe/6.0.0": {},
|
||||||
|
"System.Text.Encoding.CodePages/6.0.0": {
|
||||||
|
"dependencies": {
|
||||||
|
"System.Runtime.CompilerServices.Unsafe": "6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Threading.Channels/6.0.0": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"libraries": {
|
||||||
|
"Demo/1.0.0": {
|
||||||
|
"type": "project",
|
||||||
|
"serviceable": false,
|
||||||
|
"sha512": ""
|
||||||
|
},
|
||||||
|
"ClosedXML/0.104.1": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-RVm2fUNWJlBJlg07shrfeWzrHPG5ypI/vARqdUOUbUdaog8yBw8l4IbCHf2MXt0AXtzaZqGNqhFaCAHigCBdfw==",
|
||||||
|
"path": "closedxml/0.104.1",
|
||||||
|
"hashPath": "closedxml.0.104.1.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"ClosedXML.Parser/1.2.0": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-w+/0tsxABS3lkSH8EUlA7IGme+mq5T/Puf3DbOiTckmSuUpAUO2LK29oXYByCcWkBv6wcRHxgWlQb1lxkwI0Tw==",
|
||||||
|
"path": "closedxml.parser/1.2.0",
|
||||||
|
"hashPath": "closedxml.parser.1.2.0.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"DocumentFormat.OpenXml/3.0.1": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-DCK1cwFUJ1FGGyYyo++HWl9H1RkqMWIu+FGOLRy6E4L4y0/HIhlJ7N/n1HKboFfOwKn1cMBRxt1RCuDbIEy5YQ==",
|
||||||
|
"path": "documentformat.openxml/3.0.1",
|
||||||
|
"hashPath": "documentformat.openxml.3.0.1.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"DocumentFormat.OpenXml.Framework/3.0.1": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-ifyI7OW7sggz7LQMIAD2aUsY/zVUON9QaHrpZ4MK33iVMeHlTG4uhUE2aLWb31nry+LCs2ALDAwf8OfUJGjgBg==",
|
||||||
|
"path": "documentformat.openxml.framework/3.0.1",
|
||||||
|
"hashPath": "documentformat.openxml.framework.3.0.1.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"ExcelNumberFormat/1.1.0": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-R3BVHPs9O+RkExbZYTGT0+9HLbi8ZrNij1Yziyw6znd3J7P3uoIR07uwTLGOogtz1p6+0sna66eBoXu7tBiVQA==",
|
||||||
|
"path": "excelnumberformat/1.1.0",
|
||||||
|
"hashPath": "excelnumberformat.1.1.0.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"Humanizer.Core/2.14.1": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-lQKvtaTDOXnoVJ20ibTuSIOf2i0uO0MPbDhd1jm238I+U/2ZnRENj0cktKZhtchBMtCUSRQ5v4xBCUbKNmyVMw==",
|
||||||
|
"path": "humanizer.core/2.14.1",
|
||||||
|
"hashPath": "humanizer.core.2.14.1.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"Microsoft.Bcl.AsyncInterfaces/6.0.0": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-UcSjPsst+DfAdJGVDsu346FX0ci0ah+lw3WRtn18NUwEqRt70HaOQ7lI72vy3+1LxtqI3T5GWwV39rQSrCzAeg==",
|
||||||
|
"path": "microsoft.bcl.asyncinterfaces/6.0.0",
|
||||||
|
"hashPath": "microsoft.bcl.asyncinterfaces.6.0.0.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"Microsoft.CodeAnalysis.Analyzers/3.3.3": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-j/rOZtLMVJjrfLRlAMckJLPW/1rze9MT1yfWqSIbUPGRu1m1P0fuo9PmqapwsmePfGB5PJrudQLvmUOAMF0DqQ==",
|
||||||
|
"path": "microsoft.codeanalysis.analyzers/3.3.3",
|
||||||
|
"hashPath": "microsoft.codeanalysis.analyzers.3.3.3.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"Microsoft.CodeAnalysis.Common/4.5.0": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-lwAbIZNdnY0SUNoDmZHkVUwLO8UyNnyyh1t/4XsbFxi4Ounb3xszIYZaWhyj5ZjyfcwqwmtMbE7fUTVCqQEIdQ==",
|
||||||
|
"path": "microsoft.codeanalysis.common/4.5.0",
|
||||||
|
"hashPath": "microsoft.codeanalysis.common.4.5.0.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"Microsoft.CodeAnalysis.CSharp/4.5.0": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-cM59oMKAOxvdv76bdmaKPy5hfj+oR+zxikWoueEB7CwTko7mt9sVKZI8Qxlov0C/LuKEG+WQwifepqL3vuTiBQ==",
|
||||||
|
"path": "microsoft.codeanalysis.csharp/4.5.0",
|
||||||
|
"hashPath": "microsoft.codeanalysis.csharp.4.5.0.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"Microsoft.CodeAnalysis.CSharp.Workspaces/4.5.0": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-h74wTpmGOp4yS4hj+EvNzEiPgg/KVs2wmSfTZ81upJZOtPkJsVkgfsgtxxqmAeapjT/vLKfmYV0bS8n5MNVP+g==",
|
||||||
|
"path": "microsoft.codeanalysis.csharp.workspaces/4.5.0",
|
||||||
|
"hashPath": "microsoft.codeanalysis.csharp.workspaces.4.5.0.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"Microsoft.CodeAnalysis.Workspaces.Common/4.5.0": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-l4dDRmGELXG72XZaonnOeORyD/T5RpEu5LGHOUIhnv+MmUWDY/m1kWXGwtcgQ5CJ5ynkFiRnIYzTKXYjUs7rbw==",
|
||||||
|
"path": "microsoft.codeanalysis.workspaces.common/4.5.0",
|
||||||
|
"hashPath": "microsoft.codeanalysis.workspaces.common.4.5.0.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"Microsoft.EntityFrameworkCore/8.0.10": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-PPkQdIqfR1nU3n6YgGGDk8G+eaYbaAKM1AzIQtlPNTKf10Osg3N9T+iK9AlnSA/ujsK00flPpFHVfJrbuBFS1A==",
|
||||||
|
"path": "microsoft.entityframeworkcore/8.0.10",
|
||||||
|
"hashPath": "microsoft.entityframeworkcore.8.0.10.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"Microsoft.EntityFrameworkCore.Abstractions/8.0.10": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-FV0QlcX9INY4kAD2o72uPtyOh0nZut2jB11Jf9mNYBtHay8gDLe+x4AbXFwuQg+eSvofjT7naV82e827zGfyMg==",
|
||||||
|
"path": "microsoft.entityframeworkcore.abstractions/8.0.10",
|
||||||
|
"hashPath": "microsoft.entityframeworkcore.abstractions.8.0.10.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"Microsoft.EntityFrameworkCore.Analyzers/8.0.10": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-51KkPIc0EMv/gVXhPIUi6cwJE9Mvh+PLr4Lap4naLcsoGZ0lF2SvOPgUUprwRV3MnN7nyD1XPhT5RJ/p+xFAXw==",
|
||||||
|
"path": "microsoft.entityframeworkcore.analyzers/8.0.10",
|
||||||
|
"hashPath": "microsoft.entityframeworkcore.analyzers.8.0.10.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"Microsoft.EntityFrameworkCore.Design/8.0.10": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-uGNjfKvAsql2KHRqxlK5wHo8mMC60G/FecrFKEjJgeIxtUAbSXGOgKGw/gD9flO5Fzzt1C7uxfIcr6ZsMmFkeg==",
|
||||||
|
"path": "microsoft.entityframeworkcore.design/8.0.10",
|
||||||
|
"hashPath": "microsoft.entityframeworkcore.design.8.0.10.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"Microsoft.EntityFrameworkCore.Relational/8.0.10": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-OefBEE47kGKPRPV3OT+FAW6o5BFgLk2D9EoeWVy7NbOepzUneayLQxbVE098FfedTyMwxvZQoDD9LrvZc3MadA==",
|
||||||
|
"path": "microsoft.entityframeworkcore.relational/8.0.10",
|
||||||
|
"hashPath": "microsoft.entityframeworkcore.relational.8.0.10.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"Microsoft.Extensions.Caching.Abstractions/8.0.0": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-3KuSxeHoNYdxVYfg2IRZCThcrlJ1XJqIXkAWikCsbm5C/bCjv7G0WoKDyuR98Q+T607QT2Zl5GsbGRkENcV2yQ==",
|
||||||
|
"path": "microsoft.extensions.caching.abstractions/8.0.0",
|
||||||
|
"hashPath": "microsoft.extensions.caching.abstractions.8.0.0.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"Microsoft.Extensions.Caching.Memory/8.0.1": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-HFDnhYLccngrzyGgHkjEDU5FMLn4MpOsr5ElgsBMC4yx6lJh4jeWO7fHS8+TXPq+dgxCmUa/Trl8svObmwW4QA==",
|
||||||
|
"path": "microsoft.extensions.caching.memory/8.0.1",
|
||||||
|
"hashPath": "microsoft.extensions.caching.memory.8.0.1.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"Microsoft.Extensions.Configuration.Abstractions/8.0.0": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-3lE/iLSutpgX1CC0NOW70FJoGARRHbyKmG7dc0klnUZ9Dd9hS6N/POPWhKhMLCEuNN5nXEY5agmlFtH562vqhQ==",
|
||||||
|
"path": "microsoft.extensions.configuration.abstractions/8.0.0",
|
||||||
|
"hashPath": "microsoft.extensions.configuration.abstractions.8.0.0.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"Microsoft.Extensions.DependencyInjection/8.0.1": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-BmANAnR5Xd4Oqw7yQ75xOAYODybZQRzdeNucg7kS5wWKd2PNnMdYtJ2Vciy0QLylRmv42DGl5+AFL9izA6F1Rw==",
|
||||||
|
"path": "microsoft.extensions.dependencyinjection/8.0.1",
|
||||||
|
"hashPath": "microsoft.extensions.dependencyinjection.8.0.1.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"Microsoft.Extensions.DependencyInjection.Abstractions/8.0.2": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-3iE7UF7MQkCv1cxzCahz+Y/guQbTqieyxyaWKhrRO91itI9cOKO76OHeQDahqG4MmW5umr3CcCvGmK92lWNlbg==",
|
||||||
|
"path": "microsoft.extensions.dependencyinjection.abstractions/8.0.2",
|
||||||
|
"hashPath": "microsoft.extensions.dependencyinjection.abstractions.8.0.2.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"Microsoft.Extensions.DependencyModel/8.0.2": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-mUBDZZRgZrSyFOsJ2qJJ9fXfqd/kXJwf3AiDoqLD9m6TjY5OO/vLNOb9fb4juC0487eq4hcGN/M2Rh/CKS7QYw==",
|
||||||
|
"path": "microsoft.extensions.dependencymodel/8.0.2",
|
||||||
|
"hashPath": "microsoft.extensions.dependencymodel.8.0.2.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"Microsoft.Extensions.Logging/8.0.1": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-4x+pzsQEbqxhNf1QYRr5TDkLP9UsLT3A6MdRKDDEgrW7h1ljiEPgTNhKYUhNCCAaVpQECVQ+onA91PTPnIp6Lw==",
|
||||||
|
"path": "microsoft.extensions.logging/8.0.1",
|
||||||
|
"hashPath": "microsoft.extensions.logging.8.0.1.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"Microsoft.Extensions.Logging.Abstractions/8.0.2": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-nroMDjS7hNBPtkZqVBbSiQaQjWRDxITI8Y7XnDs97rqG3EbzVTNLZQf7bIeUJcaHOV8bca47s1Uxq94+2oGdxA==",
|
||||||
|
"path": "microsoft.extensions.logging.abstractions/8.0.2",
|
||||||
|
"hashPath": "microsoft.extensions.logging.abstractions.8.0.2.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"Microsoft.Extensions.Options/8.0.2": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-dWGKvhFybsaZpGmzkGCbNNwBD1rVlWzrZKANLW/CcbFJpCEceMCGzT7zZwHOGBCbwM0SzBuceMj5HN1LKV1QqA==",
|
||||||
|
"path": "microsoft.extensions.options/8.0.2",
|
||||||
|
"hashPath": "microsoft.extensions.options.8.0.2.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"Microsoft.Extensions.Primitives/8.0.0": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-bXJEZrW9ny8vjMF1JV253WeLhpEVzFo1lyaZu1vQ4ZxWUlVvknZ/+ftFgVheLubb4eZPSwwxBeqS1JkCOjxd8g==",
|
||||||
|
"path": "microsoft.extensions.primitives/8.0.0",
|
||||||
|
"hashPath": "microsoft.extensions.primitives.8.0.0.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"Mono.TextTemplating/2.2.1": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-KZYeKBET/2Z0gY1WlTAK7+RHTl7GSbtvTLDXEZZojUdAPqpQNDL6tHv7VUpqfX5VEOh+uRGKaZXkuD253nEOBQ==",
|
||||||
|
"path": "mono.texttemplating/2.2.1",
|
||||||
|
"hashPath": "mono.texttemplating.2.2.1.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"Npgsql/8.0.5": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-zRG5V8cyeZLpzJlKzFKjEwkRMYIYnHWJvEor2lWXeccS2E1G2nIWYYhnukB51iz5XsWSVEtqg3AxTWM0QJ6vfg==",
|
||||||
|
"path": "npgsql/8.0.5",
|
||||||
|
"hashPath": "npgsql.8.0.5.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"Npgsql.EntityFrameworkCore.PostgreSQL/8.0.10": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-gFPl9Dmxih7Yi4tZ3bITzZFzbxFMBx04gqTqcjoL2r5VEW+O2TA5UVw/wm/XW26NAJ7sg59Je0+9QrwiZt6MPQ==",
|
||||||
|
"path": "npgsql.entityframeworkcore.postgresql/8.0.10",
|
||||||
|
"hashPath": "npgsql.entityframeworkcore.postgresql.8.0.10.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"RBush/3.2.0": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-ijGh9N0zZ7JfXk3oQkWCwK8SwSSByexbyh/MjbCjNxOft9eG5ZqKC1vdgiYq78h4IZRFmN4s3JZ/b10Jipud5w==",
|
||||||
|
"path": "rbush/3.2.0",
|
||||||
|
"hashPath": "rbush.3.2.0.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"SixLabors.Fonts/1.0.0": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-LFQsCZlV0xlUyXAOMUo5kkSl+8zAQXXbbdwWchtk0B4o7zotZhQsQOcJUELGHdfPfm/xDAsz6hONAuV25bJaAg==",
|
||||||
|
"path": "sixlabors.fonts/1.0.0",
|
||||||
|
"hashPath": "sixlabors.fonts.1.0.0.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"System.CodeDom/4.4.0": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-2sCCb7doXEwtYAbqzbF/8UAeDRMNmPaQbU2q50Psg1J9KzumyVVCgKQY8s53WIPTufNT0DpSe9QRvVjOzfDWBA==",
|
||||||
|
"path": "system.codedom/4.4.0",
|
||||||
|
"hashPath": "system.codedom.4.4.0.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"System.Collections.Immutable/6.0.0": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-l4zZJ1WU2hqpQQHXz1rvC3etVZN+2DLmQMO79FhOTZHMn8tDRr+WU287sbomD0BETlmKDn0ygUgVy9k5xkkJdA==",
|
||||||
|
"path": "system.collections.immutable/6.0.0",
|
||||||
|
"hashPath": "system.collections.immutable.6.0.0.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"System.Composition/6.0.0": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-d7wMuKQtfsxUa7S13tITC8n1cQzewuhD5iDjZtK2prwFfKVzdYtgrTHgjaV03Zq7feGQ5gkP85tJJntXwInsJA==",
|
||||||
|
"path": "system.composition/6.0.0",
|
||||||
|
"hashPath": "system.composition.6.0.0.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"System.Composition.AttributedModel/6.0.0": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-WK1nSDLByK/4VoC7fkNiFuTVEiperuCN/Hyn+VN30R+W2ijO1d0Z2Qm0ScEl9xkSn1G2MyapJi8xpf4R8WRa/w==",
|
||||||
|
"path": "system.composition.attributedmodel/6.0.0",
|
||||||
|
"hashPath": "system.composition.attributedmodel.6.0.0.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"System.Composition.Convention/6.0.0": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-XYi4lPRdu5bM4JVJ3/UIHAiG6V6lWWUlkhB9ab4IOq0FrRsp0F4wTyV4Dj+Ds+efoXJ3qbLqlvaUozDO7OLeXA==",
|
||||||
|
"path": "system.composition.convention/6.0.0",
|
||||||
|
"hashPath": "system.composition.convention.6.0.0.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"System.Composition.Hosting/6.0.0": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-w/wXjj7kvxuHPLdzZ0PAUt++qJl03t7lENmb2Oev0n3zbxyNULbWBlnd5J5WUMMv15kg5o+/TCZFb6lSwfaUUQ==",
|
||||||
|
"path": "system.composition.hosting/6.0.0",
|
||||||
|
"hashPath": "system.composition.hosting.6.0.0.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"System.Composition.Runtime/6.0.0": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-qkRH/YBaMPTnzxrS5RDk1juvqed4A6HOD/CwRcDGyPpYps1J27waBddiiq1y93jk2ZZ9wuA/kynM+NO0kb3PKg==",
|
||||||
|
"path": "system.composition.runtime/6.0.0",
|
||||||
|
"hashPath": "system.composition.runtime.6.0.0.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"System.Composition.TypedParts/6.0.0": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-iUR1eHrL8Cwd82neQCJ00MpwNIBs4NZgXzrPqx8NJf/k4+mwBO0XCRmHYJT4OLSwDDqh5nBLJWkz5cROnrGhRA==",
|
||||||
|
"path": "system.composition.typedparts/6.0.0",
|
||||||
|
"hashPath": "system.composition.typedparts.6.0.0.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"System.IO.Packaging/8.0.0": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-8g1V4YRpdGAxFcK8v9OjuMdIOJSpF30Zb1JGicwVZhly3I994WFyBdV6mQEo8d3T+URQe55/M0U0eIH0Hts1bg==",
|
||||||
|
"path": "system.io.packaging/8.0.0",
|
||||||
|
"hashPath": "system.io.packaging.8.0.0.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"System.IO.Pipelines/6.0.3": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-ryTgF+iFkpGZY1vRQhfCzX0xTdlV3pyaTTqRu2ETbEv+HlV7O6y7hyQURnghNIXvctl5DuZ//Dpks6HdL/Txgw==",
|
||||||
|
"path": "system.io.pipelines/6.0.3",
|
||||||
|
"hashPath": "system.io.pipelines.6.0.3.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"System.Reflection.Metadata/6.0.1": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-III/lNMSn0ZRBuM9m5Cgbiho5j81u0FAEagFX5ta2DKbljZ3T0IpD8j+BIiHQPeKqJppWS9bGEp6JnKnWKze0g==",
|
||||||
|
"path": "system.reflection.metadata/6.0.1",
|
||||||
|
"hashPath": "system.reflection.metadata.6.0.1.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"System.Runtime.CompilerServices.Unsafe/6.0.0": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==",
|
||||||
|
"path": "system.runtime.compilerservices.unsafe/6.0.0",
|
||||||
|
"hashPath": "system.runtime.compilerservices.unsafe.6.0.0.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"System.Text.Encoding.CodePages/6.0.0": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-ZFCILZuOvtKPauZ/j/swhvw68ZRi9ATCfvGbk1QfydmcXBkIWecWKn/250UH7rahZ5OoDBaiAudJtPvLwzw85A==",
|
||||||
|
"path": "system.text.encoding.codepages/6.0.0",
|
||||||
|
"hashPath": "system.text.encoding.codepages.6.0.0.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"System.Threading.Channels/6.0.0": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-TY8/9+tI0mNaUMgntOxxaq2ndTkdXqLSxvPmas7XEqOlv9lQtB7wLjYGd756lOaO7Dvb5r/WXhluM+0Xe87v5Q==",
|
||||||
|
"path": "system.threading.channels/6.0.0",
|
||||||
|
"hashPath": "system.threading.channels.6.0.0.nupkg.sha512"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
BIN
Demo/Demo/bin/Debug/net8.0/Demo.dll
Normal file
BIN
Demo/Demo/bin/Debug/net8.0/Demo.dll
Normal file
Binary file not shown.
BIN
Demo/Demo/bin/Debug/net8.0/Demo.exe
Normal file
BIN
Demo/Demo/bin/Debug/net8.0/Demo.exe
Normal file
Binary file not shown.
BIN
Demo/Demo/bin/Debug/net8.0/Demo.pdb
Normal file
BIN
Demo/Demo/bin/Debug/net8.0/Demo.pdb
Normal file
Binary file not shown.
13
Demo/Demo/bin/Debug/net8.0/Demo.runtimeconfig.json
Normal file
13
Demo/Demo/bin/Debug/net8.0/Demo.runtimeconfig.json
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"runtimeOptions": {
|
||||||
|
"tfm": "net8.0",
|
||||||
|
"framework": {
|
||||||
|
"name": "Microsoft.NETCore.App",
|
||||||
|
"version": "8.0.0"
|
||||||
|
},
|
||||||
|
"configProperties": {
|
||||||
|
"System.Reflection.NullabilityInfoContext.IsSupported": true,
|
||||||
|
"System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
BIN
Demo/Demo/bin/Debug/net8.0/DocumentFormat.OpenXml.Framework.dll
Normal file
BIN
Demo/Demo/bin/Debug/net8.0/DocumentFormat.OpenXml.Framework.dll
Normal file
Binary file not shown.
BIN
Demo/Demo/bin/Debug/net8.0/DocumentFormat.OpenXml.dll
Normal file
BIN
Demo/Demo/bin/Debug/net8.0/DocumentFormat.OpenXml.dll
Normal file
Binary file not shown.
BIN
Demo/Demo/bin/Debug/net8.0/ExcelNumberFormat.dll
Normal file
BIN
Demo/Demo/bin/Debug/net8.0/ExcelNumberFormat.dll
Normal file
Binary file not shown.
BIN
Demo/Demo/bin/Debug/net8.0/Humanizer.dll
Normal file
BIN
Demo/Demo/bin/Debug/net8.0/Humanizer.dll
Normal file
Binary file not shown.
BIN
Demo/Demo/bin/Debug/net8.0/Microsoft.Bcl.AsyncInterfaces.dll
Normal file
BIN
Demo/Demo/bin/Debug/net8.0/Microsoft.Bcl.AsyncInterfaces.dll
Normal file
Binary file not shown.
Binary file not shown.
BIN
Demo/Demo/bin/Debug/net8.0/Microsoft.CodeAnalysis.CSharp.dll
Normal file
BIN
Demo/Demo/bin/Debug/net8.0/Microsoft.CodeAnalysis.CSharp.dll
Normal file
Binary file not shown.
BIN
Demo/Demo/bin/Debug/net8.0/Microsoft.CodeAnalysis.Workspaces.dll
Normal file
BIN
Demo/Demo/bin/Debug/net8.0/Microsoft.CodeAnalysis.Workspaces.dll
Normal file
Binary file not shown.
BIN
Demo/Demo/bin/Debug/net8.0/Microsoft.CodeAnalysis.dll
Normal file
BIN
Demo/Demo/bin/Debug/net8.0/Microsoft.CodeAnalysis.dll
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Demo/Demo/bin/Debug/net8.0/Microsoft.EntityFrameworkCore.dll
Normal file
BIN
Demo/Demo/bin/Debug/net8.0/Microsoft.EntityFrameworkCore.dll
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Demo/Demo/bin/Debug/net8.0/Microsoft.Extensions.Logging.dll
Normal file
BIN
Demo/Demo/bin/Debug/net8.0/Microsoft.Extensions.Logging.dll
Normal file
Binary file not shown.
BIN
Demo/Demo/bin/Debug/net8.0/Microsoft.Extensions.Options.dll
Normal file
BIN
Demo/Demo/bin/Debug/net8.0/Microsoft.Extensions.Options.dll
Normal file
Binary file not shown.
BIN
Demo/Demo/bin/Debug/net8.0/Microsoft.Extensions.Primitives.dll
Normal file
BIN
Demo/Demo/bin/Debug/net8.0/Microsoft.Extensions.Primitives.dll
Normal file
Binary file not shown.
BIN
Demo/Demo/bin/Debug/net8.0/Mono.TextTemplating.dll
Normal file
BIN
Demo/Demo/bin/Debug/net8.0/Mono.TextTemplating.dll
Normal file
Binary file not shown.
Binary file not shown.
BIN
Demo/Demo/bin/Debug/net8.0/Npgsql.dll
Normal file
BIN
Demo/Demo/bin/Debug/net8.0/Npgsql.dll
Normal file
Binary file not shown.
BIN
Demo/Demo/bin/Debug/net8.0/RBush.dll
Normal file
BIN
Demo/Demo/bin/Debug/net8.0/RBush.dll
Normal file
Binary file not shown.
BIN
Demo/Demo/bin/Debug/net8.0/SixLabors.Fonts.dll
Normal file
BIN
Demo/Demo/bin/Debug/net8.0/SixLabors.Fonts.dll
Normal file
Binary file not shown.
BIN
Demo/Demo/bin/Debug/net8.0/System.CodeDom.dll
Normal file
BIN
Demo/Demo/bin/Debug/net8.0/System.CodeDom.dll
Normal file
Binary file not shown.
Binary file not shown.
BIN
Demo/Demo/bin/Debug/net8.0/System.Composition.Convention.dll
Normal file
BIN
Demo/Demo/bin/Debug/net8.0/System.Composition.Convention.dll
Normal file
Binary file not shown.
BIN
Demo/Demo/bin/Debug/net8.0/System.Composition.Hosting.dll
Normal file
BIN
Demo/Demo/bin/Debug/net8.0/System.Composition.Hosting.dll
Normal file
Binary file not shown.
BIN
Demo/Demo/bin/Debug/net8.0/System.Composition.Runtime.dll
Normal file
BIN
Demo/Demo/bin/Debug/net8.0/System.Composition.Runtime.dll
Normal file
Binary file not shown.
BIN
Demo/Demo/bin/Debug/net8.0/System.Composition.TypedParts.dll
Normal file
BIN
Demo/Demo/bin/Debug/net8.0/System.Composition.TypedParts.dll
Normal file
Binary file not shown.
BIN
Demo/Demo/bin/Debug/net8.0/System.IO.Packaging.dll
Normal file
BIN
Demo/Demo/bin/Debug/net8.0/System.IO.Packaging.dll
Normal file
Binary file not shown.
BIN
Demo/Demo/bin/Debug/net8.0/System.IO.Pipelines.dll
Normal file
BIN
Demo/Demo/bin/Debug/net8.0/System.IO.Pipelines.dll
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user