293 lines
9.7 KiB
C#
293 lines
9.7 KiB
C#
using Avalonia.Controls;
|
||
using domain.Request;
|
||
using domain.UseCase;
|
||
using Presense.Desktop.Models;
|
||
using ReactiveUI;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.Collections.ObjectModel;
|
||
using System.IO;
|
||
using System.Linq;
|
||
using System.Reactive;
|
||
using System.Reactive.Linq;
|
||
using System.Text;
|
||
using System.Threading.Tasks;
|
||
using System.Windows.Input;
|
||
|
||
namespace Presence.Desktop.ViewModels
|
||
{
|
||
public class GroupViewModel : ViewModelBase
|
||
{
|
||
private readonly IGroupUseCase _groupService;
|
||
|
||
private readonly List<GroupPresenter> _groupPresentersDataSource = new();
|
||
private ObservableCollection<GroupPresenter> _groups;
|
||
public ObservableCollection<GroupPresenter> Groups => _groups;
|
||
|
||
private GroupPresenter? _selectedGroupItem;
|
||
public GroupPresenter? SelectedGroupItem
|
||
{
|
||
get => _selectedGroupItem;
|
||
set
|
||
{
|
||
if (_selectedGroupItem != value)
|
||
{
|
||
_selectedGroupItem = value;
|
||
this.RaisePropertyChanged();
|
||
UpdateStudents();
|
||
}
|
||
}
|
||
}
|
||
|
||
private ObservableCollection<StudentPresenter> _students;
|
||
public ObservableCollection<StudentPresenter> Students => _students;
|
||
|
||
public GroupViewModel() : this(null!) { }
|
||
public GroupViewModel(IGroupUseCase groupUseCase)
|
||
{
|
||
_groupService = groupUseCase;
|
||
|
||
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
|
||
|
||
ImportStudentsCommand = ReactiveCommand.CreateFromTask(ImportStudentsAsync);
|
||
|
||
LoadGroupsAndStudents();
|
||
_students = new ObservableCollection<StudentPresenter>();
|
||
RemoveAllStudentsCommand = ReactiveCommand.Create(RemoveAllStudents);
|
||
|
||
RemoveSelectedStudentsCommand = ReactiveCommand.Create(RemoveSelectedStudents);
|
||
}
|
||
|
||
private void LoadGroupsAndStudents()
|
||
{
|
||
foreach (var groupEntity in _groupService.GetGroupsWithStudents())
|
||
{
|
||
var groupPresenter = new GroupPresenter
|
||
{
|
||
GroupId = groupEntity.GroupId,
|
||
GroupName = groupEntity.GroupName,
|
||
Students = groupEntity.Students?.Select(student => new StudentPresenter
|
||
{
|
||
Id = student.Id,
|
||
FirstName = student.FirstName,
|
||
LastName = student.LastName,
|
||
Patronymic = student.Patronymic,
|
||
|
||
Group = null
|
||
}).ToList(),
|
||
Subjects = groupEntity.Subjects.Select(subject => new SubjectPresenter
|
||
{
|
||
SubjectId = subject.SubjectId,
|
||
SubjectName = subject.SubjectName
|
||
}).ToList()
|
||
};
|
||
|
||
foreach (var student in groupPresenter.Students ?? Enumerable.Empty<StudentPresenter>())
|
||
{
|
||
student.Group = groupPresenter;
|
||
}
|
||
|
||
_groupPresentersDataSource.Add(groupPresenter);
|
||
}
|
||
|
||
_groups = new ObservableCollection<GroupPresenter>(_groupPresentersDataSource);
|
||
}
|
||
|
||
private void UpdateStudents()
|
||
{
|
||
if (SelectedGroupItem?.Students == null) return;
|
||
|
||
Students.Clear();
|
||
|
||
foreach (var student in SelectedGroupItem.Students)
|
||
{
|
||
Students.Add(student);
|
||
}
|
||
}
|
||
|
||
private readonly string[] _sortingOptions = new[]
|
||
{
|
||
"Без сортировки",
|
||
"Фамилии (по возрастанию)",
|
||
"Фамилии (по убыванию)"
|
||
};
|
||
|
||
public string[] SortingOptions => _sortingOptions;
|
||
|
||
private string? _selectedSortingOption;
|
||
public string? SelectedSortingOption
|
||
{
|
||
get => _selectedSortingOption;
|
||
set
|
||
{
|
||
this.RaiseAndSetIfChanged(ref _selectedSortingOption, value);
|
||
ApplySorting();
|
||
}
|
||
}
|
||
|
||
private void ApplySorting()
|
||
{
|
||
if (SelectedGroupItem?.Students == null) return;
|
||
|
||
IEnumerable<StudentPresenter> sortedStudents = SelectedSortingOption switch
|
||
{
|
||
"Фамилии (по возрастанию)" => SelectedGroupItem.Students.OrderBy(s => s.LastName),
|
||
"Фамилии (по убыванию)" => SelectedGroupItem.Students.OrderByDescending(s => s.LastName),
|
||
_ => SelectedGroupItem.Students
|
||
};
|
||
|
||
Students.Clear();
|
||
foreach (var student in sortedStudents)
|
||
{
|
||
Students.Add(student);
|
||
}
|
||
}
|
||
|
||
public ReactiveCommand<Unit, Unit> RemoveAllStudentsCommand { get; }
|
||
|
||
private void RemoveAllStudents()
|
||
{
|
||
if (SelectedGroupItem == null || SelectedGroupItem.Students == null) return;
|
||
|
||
_groupService.RemoveStudentsFromGroup(SelectedGroupItem.GroupId);
|
||
|
||
SelectedGroupItem.Students.Clear();
|
||
UpdateStudents();
|
||
LoadGroupsAndStudents();
|
||
}
|
||
|
||
public ReactiveCommand<Unit, Unit> ImportStudentsCommand { get; }
|
||
|
||
public async Task ImportStudentsAsync()
|
||
{
|
||
var dialog = new OpenFileDialog
|
||
{
|
||
Title = "Выберите файл CSV:",
|
||
Filters = new List<FileDialogFilter>
|
||
{
|
||
new FileDialogFilter { Name = "CSV Files", Extensions = { "csv" } }
|
||
}
|
||
};
|
||
|
||
var result = await dialog.ShowAsync(new Window());
|
||
|
||
if (result != null && result.Any())
|
||
{
|
||
var filePath = result.First();
|
||
|
||
if (SelectedGroupItem == null)
|
||
{
|
||
Console.WriteLine("Группа не выбрана.");
|
||
return;
|
||
}
|
||
|
||
try
|
||
{
|
||
var csvLines = File.ReadAllLines(filePath, Encoding.GetEncoding("windows-1251"));
|
||
|
||
var studentsToAdd = new List<AddStudentRequest>();
|
||
|
||
foreach (var line in csvLines)
|
||
{
|
||
var data = line.Split(';');
|
||
if (data.Length != 3)
|
||
{
|
||
Console.WriteLine($"Либо разделитель либо хз: {line}");
|
||
continue;
|
||
}
|
||
|
||
studentsToAdd.Add(new AddStudentRequest
|
||
{
|
||
FirstName = data[0],
|
||
LastName = data[1],
|
||
Patronymic = data[2]
|
||
});
|
||
}
|
||
|
||
if (studentsToAdd.Any())
|
||
{
|
||
_groupService.AddStudentsToGroup(SelectedGroupItem.GroupId, studentsToAdd);
|
||
|
||
foreach (var studentRequest in studentsToAdd)
|
||
{
|
||
var studentPresenter = new StudentPresenter
|
||
{
|
||
FirstName = studentRequest.FirstName,
|
||
LastName = studentRequest.LastName,
|
||
Patronymic = studentRequest.Patronymic,
|
||
Group = SelectedGroupItem
|
||
};
|
||
|
||
SelectedGroupItem.Students.Add(studentPresenter);
|
||
Students.Add(studentPresenter);
|
||
}
|
||
|
||
UpdateStudents();
|
||
LoadGroupsAndStudents();
|
||
}
|
||
else
|
||
{
|
||
Console.WriteLine("Проблема с данными.");
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"...: {ex.Message}");
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
private ObservableCollection<StudentPresenter> _selectedStudents = new();
|
||
public ObservableCollection<StudentPresenter> SelectedStudents
|
||
{
|
||
get => _selectedStudents;
|
||
set
|
||
{
|
||
this.RaiseAndSetIfChanged(ref _selectedStudents, value);
|
||
UpdateSelectionStates();
|
||
}
|
||
}
|
||
|
||
private bool _isSingleSelection;
|
||
public bool IsSingleSelection
|
||
{
|
||
get => _isSingleSelection;
|
||
set => this.RaiseAndSetIfChanged(ref _isSingleSelection, value);
|
||
}
|
||
|
||
private bool _isMultipleSelection;
|
||
public bool IsMultipleSelection
|
||
{
|
||
get => _isMultipleSelection;
|
||
set => this.RaiseAndSetIfChanged(ref _isMultipleSelection, value);
|
||
}
|
||
|
||
public void UpdateSelectionStates()
|
||
{
|
||
IsSingleSelection = SelectedStudents.Count == 1;
|
||
IsMultipleSelection = SelectedStudents.Count > 1;
|
||
}
|
||
|
||
public ReactiveCommand<Unit, Unit> RemoveSelectedStudentsCommand { get; }
|
||
|
||
private void RemoveSelectedStudents()
|
||
{
|
||
if (SelectedStudents == null || SelectedStudents.Count == 0) return;
|
||
|
||
var studentIds = SelectedStudents.Select(s => s.Id).ToList();
|
||
_groupService.RemoveStudentsFromGroupByIds(SelectedGroupItem.GroupId, studentIds);
|
||
|
||
foreach (var student in SelectedStudents.ToList())
|
||
{
|
||
SelectedGroupItem.Students.Remove(student);
|
||
Students.Remove(student);
|
||
}
|
||
|
||
UpdateStudents();
|
||
LoadGroupsAndStudents();
|
||
}
|
||
}
|
||
}
|
||
|