70 процентов лабы

This commit is contained in:
Сафия Мухамадиева 2024-12-19 11:27:27 +04:00
parent 9f035728d0
commit bbeae41de5
21 changed files with 313 additions and 142 deletions

View File

@ -1,11 +1,32 @@
namespace StudentProgress.Entities;
using System.ComponentModel;
namespace StudentProgress.Entities;
public class Grades
{
public int Id { get; private set; }
[Browsable(false)]
public int SubjectsId { get; private set; }
[Browsable(false)]
public int ProfessorsId { get; private set; }
[DisplayName("Предмет")]
public string SubjectsName { get; private set; } = string.Empty;
[DisplayName("Преподаватель")]
public string ProfessorsName { get; private set; } = string.Empty;
[DisplayName("Дата")]
public DateTime Date { get; private set; }
[DisplayName("Оценки")]
public string GradeStudent => StudentGrade != null ?
string.Join(", ", StudentGrade.Select(x => $"{x.StudentName} {x.Grade}")) :
string.Empty;
[Browsable(false)]
public IEnumerable<StudentGrades> StudentGrade { get; private set; } = [];
public static Grades CreateEntity(int id, int subjectsId, int professorsId, DateTime date, IEnumerable<StudentGrades> studentGrades)
{
@ -19,15 +40,11 @@ public class Grades
};
}
public static Grades CreateEntity(TempStudentGrades tempStudentGrades, IEnumerable<StudentGrades> studentGrades)
public void SetStudentGrade(IEnumerable<StudentGrades> studentGrade)
{
return new Grades
if (studentGrade != null && studentGrade.Any())
{
Id = tempStudentGrades.Id,
SubjectsId = tempStudentGrades.SubjectsId,
ProfessorsId = tempStudentGrades.ProfessorsId,
Date = tempStudentGrades.Date,
StudentGrade = studentGrades
};
StudentGrade = studentGrade;
}
}
}

View File

@ -1,8 +1,12 @@
namespace StudentProgress.Entities;
using System.ComponentModel;
namespace StudentProgress.Entities;
public class Group
{
public int Id { get; private set; }
[DisplayName("Название")]
public string NameGroup { get; set; } = string.Empty;
public static Group CreateEntity(int id, string nameGroup)

View File

@ -1,11 +1,23 @@
namespace StudentProgress.Entities;
using System.ComponentModel;
namespace StudentProgress.Entities;
public class Lectures
{
public int Id { get; private set; }
[Browsable(false)]
public int ProfessorsId { get; private set; }
[DisplayName("Преподаватель")]
public string ProfessorsName { get; private set; } = string.Empty;
[DisplayName("Дата")]
public DateTime Date { get; private set; }
[DisplayName("Аудитория")]
public string Auditorium { get; private set; } = string.Empty;
public static Lectures CreateElement(int id, int professorsId, DateTime date, string auditorium)
{
return new Lectures

View File

@ -1,9 +1,15 @@
namespace StudentProgress.Entities;
using System.ComponentModel;
namespace StudentProgress.Entities;
public class Professors
{
public int Id { get; set; }
[DisplayName("Имя")]
public string FirstName { get; set; } = string.Empty;
[DisplayName("Фамилия")]
public string Surname { get; set; } = string.Empty;
public static Professors CreateEntity(int id, string firstName, string surname)
{

View File

@ -1,12 +1,23 @@
namespace StudentProgress.Entities;
using System.ComponentModel;
namespace StudentProgress.Entities;
public class Student
{
public int Id { get; private set; }
[DisplayName("Имя")]
public string Name { get; set; } = string.Empty;
[DisplayName("Фамилия")]
public string Surname { get; set; } = string.Empty;
[Browsable(false)]
public int GroupId { get; set; }
[DisplayName("Группа")]
public string GroupName { get; set; } = string.Empty;
public static Student CreateEntity(int id, string name, string surname, int groupId)
{
return new Student

View File

@ -6,6 +6,7 @@ public class StudentGrades
{
public int Id { get; private set; }
public int StudentID { get; private set; }
public string StudentName { get; private set; } = string.Empty;
public Grade Grade { get; private set; }
public static StudentGrades CreateEntity(int id, int studentID, Grade grade)
{

View File

@ -1,12 +1,16 @@
using Microsoft.VisualBasic.Devices;
using StudentProgress.Entities.Enums;
using StudentProgress.Entities.Enums;
using System.ComponentModel;
namespace StudentProgress.Entities;
public class Subjects
{
public int Id { get; private set; }
[DisplayName("Название")]
public string NameSubject { get; private set; } = string.Empty;
[DisplayName("Курсы")]
public Course Course { get; private set; }
public static Subjects CreateEntity_(int id, string nameSubject, Course course)
{

View File

@ -1,18 +0,0 @@
using StudentProgress.Entities.Enums;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StudentProgress.Entities;
public class TempStudentGrades
{
public int Id { get; private set; }
public int SubjectsId { get; private set; }
public int ProfessorsId { get; private set; }
public DateTime Date { get; private set; }
public int StudentID { get; private set; }
public Grade Grade { get; private set; }
}

View File

@ -97,6 +97,41 @@ namespace StudentProgress
MessageBox.Show(ex.Message, "Îøèáêà ïðè çàãðóçêå", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void toolStripMenuItemDocReport_Click(object sender, EventArgs e)
{
try
{
_container.Resolve<FormDirectoryReport>().ShowDialog();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Îøèáêà ïðè çàãðóçêå", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void toolStripMenuItemStudentGradeReport_Click(object sender, EventArgs e)
{
try
{
_container.Resolve<FormStudentGradeReport>().ShowDialog();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Îøèáêà ïðè çàãðóçêå", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void toolStripMenuItemGradeDistribution_Click(object sender, EventArgs e)
{
try
{
_container.Resolve<FormGradeDistribution>().ShowDialog();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Îøèáêà ïðè çàãðóçêå", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}

View File

@ -1,21 +1,18 @@
using StudentProgress.Entities;
using StudentProgress.Repositories;
using System;
using System.Collections.Generic;
using System.Linq;
using StudentProgress.Repositories;
using System.Windows.Forms;
using Unity;
namespace StudentProgress.Forms
{
public partial class FormLecturesCount : Form
{
private readonly IProfessorsRepository _professorsRepository;
private readonly IUnityContainer _container;
private readonly ILecturesRepository _lecturesRepository;
public FormLecturesCount(IProfessorsRepository professorsRepository, ILecturesRepository lecturesRepository)
public FormLecturesCount(IUnityContainer container, ILecturesRepository lecturesRepository)
{
InitializeComponent();
_professorsRepository = professorsRepository;
_container = container ?? throw new ArgumentNullException(nameof(container));
_lecturesRepository = lecturesRepository;
}
@ -26,71 +23,56 @@ namespace StudentProgress.Forms
private void LoadLectures()
{
var lectures = _lecturesRepository.ReadLectures();
var lectureViewModels = new List<LectureViewModel>();
foreach (var lecture in lectures)
{
var professor = _professorsRepository.ReadProfessorsNameById(lecture.ProfessorsId);
lectureViewModels.Add(new LectureViewModel
{
LectureId = lecture.LectureId,
ProfessorName = $"{professor.FirstNameProfessor} {professor.SurnameProfessor}",
Auditorium = lecture.Auditorium,
Date = lecture.Date
});
}
LecturesDataGridView.DataSource = lectureViewModels;
LecturesDataGridView.DataSource = _lecturesRepository.ReadLectures();
LecturesDataGridView.Columns["Id"].Visible = false;
}
private void buttonAdd_Click(object sender, EventArgs e)
{
using (var formRecordLecture = new FormRecordLecture(_professorsRepository, _lecturesRepository))
try
{
formRecordLecture.ShowDialog();
LoadLectures(); // Обновляем данные после закрытия формы
_container.Resolve<FormRecordLecture>().ShowDialog();
LoadLectures();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при добавлении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void buttonDel_Click(object sender, EventArgs e)
{
if (LecturesDataGridView.SelectedRows.Count > 0)
if (!TryGetIdentifierFromSelectedRow(out var findId))
{
var selectedRow = LecturesDataGridView.SelectedRows[0];
var lectureViewModel = selectedRow.DataBoundItem as LectureViewModel;
if (lectureViewModel != null)
{
// Логика удаления лекции
_lecturesRepository.DeleteLecture(lectureViewModel.LectureId);
MessageBox.Show("Лекция успешно удалена!", "Успех", MessageBoxButtons.OK, MessageBoxIcon.Information);
LoadLectures(); // Обновляем данные после удаления
}
return;
}
else
if (MessageBox.Show("Удалить запись?", "Удаление", MessageBoxButtons.YesNo) != DialogResult.Yes)
{
MessageBox.Show("Выберите лекцию для удаления.", "Информация", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
try
{
_lecturesRepository.DeleteLecture(findId);
LoadLectures();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при удалении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void LecturesDataGridView_CellContentClick(object sender, DataGridViewCellEventArgs e)
private bool TryGetIdentifierFromSelectedRow(out int id)
{
id = 0;
if (LecturesDataGridView.SelectedRows.Count < 1)
{
MessageBox.Show("Нет выбранной записи", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
}
}
public class LectureViewModel
{
public int LectureId { get; set; }
public string ProfessorName { get; set; }
public string Auditorium { get; set; }
public DateTime Date { get; set; }
public LectureViewModel()
{
ProfessorName = string.Empty; // Инициализация свойства ProfessorName
Auditorium = string.Empty; // Инициализация свойства Auditorium
id = Convert.ToInt32(LecturesDataGridView.SelectedRows[0].Cells["Id"].Value);
return true;
}
}
}

View File

@ -1,52 +1,102 @@
using System;
using System.Windows.Forms;
using Unity;
using StudentProgress.Repositories;
using StudentProgress.Entities;
namespace StudentProgress.Forms
{
public partial class FormStudent : Form
public partial class FormStudents : Form
{
private readonly IUnityContainer _container;
private readonly IStudentRepository _studentRepository;
private readonly IGroupRepository _groupRepository;
public FormStudent(IStudentRepository studentRepository, IGroupRepository groupRepository)
public FormStudents(IUnityContainer container, IStudentRepository studentRepository)
{
InitializeComponent();
_container = container ?? throw new ArgumentNullException(nameof(container));
_studentRepository = studentRepository ?? throw new ArgumentNullException(nameof(studentRepository));
_groupRepository = groupRepository ?? throw new ArgumentNullException(nameof(groupRepository));
LoadGroups();
}
private void LoadGroups()
{
var groups = _groupRepository.ReadGroup();
comboBoxGroup.DataSource = groups;
comboBoxGroup.DisplayMember = "NameGroup";
comboBoxGroup.ValueMember = "Id";
}
private void buttonSave_Click(object sender, EventArgs e)
private void FormStudents_Load(object sender, EventArgs e)
{
try
{
if (string.IsNullOrWhiteSpace(textBoxName.Text) || string.IsNullOrWhiteSpace(textBoxSurname.Text) || comboBoxGroup.SelectedIndex < 0)
{
throw new Exception("Имеются незаполненные поля");
}
var student = Student.CreateEntity(0, textBoxName.Text, textBoxSurname.Text, (int)comboBoxGroup.SelectedValue);
_studentRepository.CreateStudent(student);
MessageBox.Show("Студент успешно добавлен", "Успех", MessageBoxButtons.OK, MessageBoxIcon.Information);
Close();
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при сохранении", MessageBoxButtons.OK, MessageBoxIcon.Error);
MessageBox.Show(ex.Message, "Ошибка при загрузке", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void buttonCancel_Click(object sender, EventArgs e) => Close();
private void buttonAdd_Click(object sender, EventArgs e)
{
try
{
_container.Resolve<FormStudent>().ShowDialog();
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при добавлении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void buttonPencil_Click(object sender, EventArgs e)
{
if (!TryGetIdentifierFromSelectedRow(out var findId))
{
return;
}
try
{
var form = _container.Resolve<FormStudent>();
form.Id = findId;
form.ShowDialog();
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при изменении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void buttonDel_Click(object sender, EventArgs e)
{
if (!TryGetIdentifierFromSelectedRow(out var findId))
{
return;
}
if (MessageBox.Show("Удалить запись?", "Удаление", MessageBoxButtons.YesNo) != DialogResult.Yes)
{
return;
}
try
{
_studentRepository.DeleteStudent(findId);
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при удалении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void LoadList()
{
dataGridView.DataSource = _studentRepository.ReadStudents();
dataGridView.Columns["Id"].Visible = false;
}
private bool TryGetIdentifierFromSelectedRow(out int id)
{
id = 0;
if (dataGridView.SelectedRows.Count < 1)
{
MessageBox.Show("Нет выбранной записи", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value);
return true;
}
}
}

View File

@ -51,7 +51,7 @@ namespace StudentProgress.Forms
try
{
var form = _container.Resolve<FormStudent>();
// Здесь нужно добавить логику для загрузки данных в форму редактирования
form.Id = findId;
form.ShowDialog();
LoadList();
}
@ -82,8 +82,11 @@ namespace StudentProgress.Forms
}
}
private void LoadList() => dataGridView.DataSource = _studentRepository.ReadStudents();
private void LoadList()
{
dataGridView.DataSource = _studentRepository.ReadStudents();
dataGridView.Columns["Id"].Visible = false;
}
private bool TryGetIdentifierFromSelectedRow(out int id)
{
id = 0;

View File

@ -1,7 +1,6 @@
using Microsoft.Extensions.Logging;
using StudentProgress.Repositories;
using StudentProgress.Repositories.Implementations;
using System.Reflection.PortableExecutable;
namespace StudentProgress.Reports;
@ -24,7 +23,7 @@ internal class ChartReport
{
new PdfBuilder(filePath)
.AddHeader("Диаграмма по оценкам")
.AddPieChart("Распределение оценок по предметам", GetData(dateTime))
.AddPieChart($"Распределение оценок по предметам на {dateTime:dd.MM.yyyy}", GetData(dateTime))
.Build();
return true;
}
@ -44,8 +43,7 @@ internal class ChartReport
// Группируем оценки по предметам за конкретный день
return _gradesRepository
.ReadGrades()
.Where(g => g.Date.Date == dateTime.Date) // Фильтруем по дате
.ReadGrades(dateFrom: dateTime.Date, dateTo: dateTime.Date.AddDays(1))
.GroupBy(g => g.SubjectsId) // Группировка по ID предмета
.Select(g => (
Caption: subjectNames.TryGetValue(g.Key, out var name) ? name : "Неизвестный предмет",

View File

@ -1,9 +1,6 @@
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
using DocumentFormat.OpenXml;
using Microsoft.Extensions.Primitives;
using Serilog.Parsing;
using static Npgsql.Replication.PgOutput.Messages.RelationMessage;
namespace StudentProgress.Reports;

View File

@ -1,7 +1,6 @@
using MigraDoc.DocumentObjectModel;
using MigraDoc.DocumentObjectModel.Shapes.Charts;
using MigraDoc.Rendering;
using System.Reflection.Metadata;
using System.Text;
namespace StudentProgress.Reports;

View File

@ -26,7 +26,7 @@ internal class TableReport
{
new ExcelBuilder(filePath)
.AddHeader("Сводка по оценкам", 0, 4)
.AddParagraph("за период", 0)
.AddParagraph($"за период {startDate:dd.MM.yyyy} по {endDate:dd.MM.yyyy}", 0)
.AddTable([10, 15, 15, 15], GetData(studentId, startDate, endDate))
.Build();
return true;
@ -50,9 +50,7 @@ internal class TableReport
// Получаем оценки за диапазон дат для указанного студента
var gradesData = _gradesRepository
.ReadGrades()
.Where(g => g.Date >= startDate && g.Date <= endDate
&& g.StudentGrade.Any(sg => sg.StudentID == studentId))
.ReadGrades(startDate, endDate, studentId)
.Select(g => new
{
Date = g.Date,

View File

@ -2,9 +2,6 @@
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Wordprocessing;
using DocumentFormat.OpenXml.Packaging;
using static System.Net.Mime.MediaTypeNames;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.Tab;
using System.Reflection.Metadata;
namespace StudentProgress.Reports;

View File

@ -70,17 +70,57 @@ namespace StudentProgress.Repositories.Implementations
}
}
public IEnumerable<Grades> ReadGrades(DateTime? dateFrom = null, DateTime? dateTo = null, int? subjectsId = null, int? professorsId = null)
public IEnumerable<Grades> ReadGrades(DateTime? dateFrom = null, DateTime? dateTo = null, int? studentId = null)
{
_logger.LogInformation("Получение оценок");
try
{
var builder = new QueryBuilder();
if (dateFrom.HasValue)
{
builder.AddCondition("g.Date >= @dateFrom");
}
if (dateTo.HasValue)
{
builder.AddCondition("g.Date <= @dateTo");
}
if (studentId.HasValue)
{
builder.AddCondition("sg.StudentId = @studentId");
}
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var query = "SELECT * FROM Grades";
var querySelect = $@"SELECT g.*, CONCAT(pr.FirstName, ' ', pr.Surname) as ProfessorsName,
su.NameSubject as SubjectsName, sg.StudentID, sg.Grade, CONCAT(st.Name, ' ', st.Surname) as StudentName
FROM Grades g
LEFT JOIN Professors pr on pr.Id = g.ProfessorsId
LEFT JOIN Subjects su on su.Id = g.SubjectsId
INNER JOIN StudentGrades sg on sg.GradesId = g.Id
LEFT JOIN Student st on st.Id = sg.StudentID
{builder.Build()}";
var grades = connection.Query<Grades>(query);
_logger.LogDebug("Полученные оценки: {json}", JsonConvert.SerializeObject(grades));
return grades;
var gradesDict = new Dictionary<int, List<StudentGrades>>();
var studentGrades = connection.Query<Grades, StudentGrades, Grades>(querySelect,
(grade, studentGrade) =>
{
if (!gradesDict.TryGetValue(grade.Id, out var ccf))
{
ccf = [];
gradesDict.Add(grade.Id, ccf);
}
ccf.Add(studentGrade);
return grade;
}, splitOn: "StudentId", param: new { dateFrom, dateTo, studentId });
_logger.LogDebug("Полученные объекты: {json}",
JsonConvert.SerializeObject(studentGrades));
return gradesDict.Select(x =>
{
var cf = studentGrades.First(y => y.Id == x.Key);
cf.SetStudentGrade(x.Value);
return cf;
}).ToArray();
}
catch (Exception ex)
{

View File

@ -23,7 +23,8 @@ namespace StudentProgress.Repositories.Implementations
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var query = "SELECT * FROM Lectures";
var query = @"SELECT le.*, CONCAT(pr.FirstName, ' ', pr.Surname) as ProfessorsName FROM Lectures le
LEFT JOIN Professors pr on pr.Id = le.ProfessorsId";
var lectures = connection.Query<Lectures>(query);
_logger.LogDebug("Полученные лекции: {json}", JsonConvert.SerializeObject(lectures));
return lectures;

View File

@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StudentProgress.Repositories.Implementations;
internal class QueryBuilder
{
private readonly StringBuilder _builder;
public QueryBuilder()
{
_builder = new();
}
public QueryBuilder AddCondition(string condition)
{
if (_builder.Length > 0)
{
_builder.Append(" AND ");
}
_builder.Append(condition);
return this;
}
public string Build()
{
if (_builder.Length == 0)
{
return string.Empty;
}
return $"WHERE {_builder}";
}
}

View File

@ -89,7 +89,8 @@ WHERE Id=@id";
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = "SELECT * FROM Student";
var querySelect = @"SELECT st.*, gr.NameGroup as GroupName FROM Student st
LEFT JOIN ""Group"" gr on gr.Id = st.GroupId";
var student = connection.Query<Student>(querySelect);
_logger.LogDebug("Полученные объекты: {json}",
JsonConvert.SerializeObject(student));