erp-platform/api/src/Kurs.Platform.Application/Classroom/ClassroomAppService.cs

245 lines
8.2 KiB
C#
Raw Normal View History

2025-08-25 18:01:57 +00:00
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
2025-08-25 18:01:57 +00:00
using System.Threading.Tasks;
using Kurs.Platform.Entities;
using Microsoft.AspNetCore.Authorization;
2025-08-27 15:00:22 +00:00
using Microsoft.AspNetCore.Mvc;
2025-08-25 18:01:57 +00:00
using Volo.Abp.Application.Dtos;
using Volo.Abp.Domain.Repositories;
2025-08-26 05:59:39 +00:00
namespace Kurs.Platform.Classrooms;
2025-08-25 18:01:57 +00:00
[Authorize]
2025-08-26 05:59:39 +00:00
public class ClassroomAppService : PlatformAppService, IClassroomAppService
2025-08-25 18:01:57 +00:00
{
2025-08-26 05:59:39 +00:00
private readonly IRepository<Classroom, Guid> _classSessionRepository;
private readonly IRepository<ClassParticipant, Guid> _participantRepository;
private readonly IRepository<ClassAttandance, Guid> _attendanceRepository;
public ClassroomAppService(
IRepository<Classroom, Guid> classSessionRepository,
IRepository<ClassParticipant, Guid> participantRepository,
IRepository<ClassAttandance, Guid> attendanceRepository)
2025-08-25 18:01:57 +00:00
{
_classSessionRepository = classSessionRepository;
_participantRepository = participantRepository;
_attendanceRepository = attendanceRepository;
}
public async Task<ClassroomDto> GetAsync(Guid id)
2025-08-25 18:01:57 +00:00
{
var classSession = await _classSessionRepository.GetAsync(id);
2025-08-26 05:59:39 +00:00
return ObjectMapper.Map<Classroom, ClassroomDto>(classSession);
2025-08-25 18:01:57 +00:00
}
public async Task<PagedResultDto<ClassroomDto>> GetListAsync(PagedAndSortedResultRequestDto input)
2025-08-25 18:01:57 +00:00
{
var query = await _classSessionRepository.GetQueryableAsync();
var totalCount = query.Count();
var items = query
.OrderBy(x => x.ScheduledStartTime)
.Skip(input.SkipCount)
.Take(input.MaxResultCount)
.ToList();
2025-08-26 05:59:39 +00:00
return new PagedResultDto<ClassroomDto>(
2025-08-25 18:01:57 +00:00
totalCount,
2025-08-26 05:59:39 +00:00
ObjectMapper.Map<List<Classroom>, List<ClassroomDto>>(items)
2025-08-25 18:01:57 +00:00
);
}
public async Task<ClassroomDto> CreateAsync(ClassroomDto input)
2025-08-25 18:01:57 +00:00
{
var classSession = new Classroom(
GuidGenerator.Create(),
input.Name,
input.Description,
input.Subject,
CurrentUser.Id,
CurrentUser.Name,
input.ScheduledStartTime,
2025-08-28 11:53:47 +00:00
input.ScheduledStartTime.AddMinutes(input.Duration),
input.Duration,
input.MaxParticipants,
input.SettingsJson = JsonSerializer.Serialize(input.SettingsDto)
);
await _classSessionRepository.InsertAsync(classSession);
2025-08-26 05:59:39 +00:00
return ObjectMapper.Map<Classroom, ClassroomDto>(classSession);
2025-08-25 18:01:57 +00:00
}
public async Task<ClassroomDto> UpdateAsync(Guid id, ClassroomDto input)
2025-08-25 18:01:57 +00:00
{
var classSession = await _classSessionRepository.GetAsync(id);
if (classSession.TeacherId != CurrentUser.Id)
{
throw new UnauthorizedAccessException("Only the teacher can update this class");
}
classSession.Name = input.Name;
classSession.Description = input.Description;
classSession.Subject = input.Subject;
2025-08-27 15:00:22 +00:00
classSession.TeacherId = input.TeacherId;
classSession.TeacherName = input.TeacherName;
2025-08-25 18:01:57 +00:00
classSession.ScheduledStartTime = input.ScheduledStartTime;
2025-08-28 11:53:47 +00:00
classSession.ScheduledEndTime = input.ScheduledStartTime.AddMinutes(input.Duration);
2025-08-25 18:01:57 +00:00
classSession.Duration = input.Duration;
classSession.MaxParticipants = input.MaxParticipants;
2025-08-27 15:00:22 +00:00
classSession.SettingsJson = JsonSerializer.Serialize(input.SettingsDto);
2025-08-25 18:01:57 +00:00
await _classSessionRepository.UpdateAsync(classSession);
2025-08-26 05:59:39 +00:00
return ObjectMapper.Map<Classroom, ClassroomDto>(classSession);
2025-08-25 18:01:57 +00:00
}
public async Task DeleteAsync(Guid id)
{
var classSession = await _classSessionRepository.GetAsync(id);
if (classSession.TeacherId != CurrentUser.Id)
{
throw new UnauthorizedAccessException("Only the teacher can delete this class");
}
await _classSessionRepository.DeleteAsync(id);
}
2025-08-27 15:00:22 +00:00
[HttpPut]
2025-08-27 20:55:01 +00:00
public async Task<ClassroomDto> StartClassAsync(Guid id)
2025-08-25 18:01:57 +00:00
{
var classSession = await _classSessionRepository.GetAsync(id);
if (classSession.TeacherId != CurrentUser.Id)
{
throw new UnauthorizedAccessException("Only the teacher can start this class");
}
2025-08-27 15:00:22 +00:00
classSession.ActualStartTime = DateTime.Now;
2025-08-25 18:01:57 +00:00
await _classSessionRepository.UpdateAsync(classSession);
2025-08-26 05:59:39 +00:00
return ObjectMapper.Map<Classroom, ClassroomDto>(classSession);
2025-08-25 18:01:57 +00:00
}
2025-08-27 15:00:22 +00:00
[HttpPut]
2025-08-27 20:55:01 +00:00
public async Task EndClassAsync(Guid id)
2025-08-25 18:01:57 +00:00
{
var classSession = await _classSessionRepository.GetAsync(id);
if (classSession.TeacherId != CurrentUser.Id)
{
throw new UnauthorizedAccessException("Only the teacher can end this class");
}
2025-08-28 11:53:47 +00:00
classSession.ActualEndTime = DateTime.Now;
2025-08-27 15:00:22 +00:00
2025-08-25 18:01:57 +00:00
await _classSessionRepository.UpdateAsync(classSession);
// Update attendance records
var activeAttendances = await _attendanceRepository.GetListAsync(
x => x.SessionId == id && x.LeaveTime == null
);
foreach (var attendance in activeAttendances)
{
2025-08-28 11:53:47 +00:00
attendance.LeaveTime = DateTime.Now;
2025-08-25 18:01:57 +00:00
attendance.CalculateDuration();
await _attendanceRepository.UpdateAsync(attendance);
}
}
2025-08-26 05:59:39 +00:00
public async Task<ClassroomDto> JoinClassAsync(Guid id)
2025-08-25 18:01:57 +00:00
{
var classSession = await _classSessionRepository.GetAsync(id);
if (classSession.ParticipantCount >= classSession.MaxParticipants)
{
throw new InvalidOperationException("Class is full");
}
// Check if user is already in the class
var existingParticipant = await _participantRepository.FirstOrDefaultAsync(
x => x.SessionId == id && x.UserId == CurrentUser.Id
);
if (existingParticipant == null)
{
// Add participant
2025-08-26 05:59:39 +00:00
var participant = new ClassParticipant(
2025-08-25 18:01:57 +00:00
GuidGenerator.Create(),
id,
CurrentUser.Id,
CurrentUser.Name,
CurrentUser.Email,
false // isTeacher
);
await _participantRepository.InsertAsync(participant);
// Create attendance record
2025-08-26 05:59:39 +00:00
var attendance = new ClassAttandance(
2025-08-25 18:01:57 +00:00
GuidGenerator.Create(),
id,
CurrentUser.Id,
CurrentUser.Name,
2025-08-28 11:53:47 +00:00
DateTime.Now
2025-08-25 18:01:57 +00:00
);
await _attendanceRepository.InsertAsync(attendance);
// Update participant count
classSession.ParticipantCount++;
await _classSessionRepository.UpdateAsync(classSession);
}
2025-08-26 05:59:39 +00:00
return ObjectMapper.Map<Classroom, ClassroomDto>(classSession);
2025-08-25 18:01:57 +00:00
}
public async Task LeaveClassAsync(Guid id)
{
var participant = await _participantRepository.FirstOrDefaultAsync(
x => x.SessionId == id && x.UserId == CurrentUser.Id
);
if (participant != null)
{
await _participantRepository.DeleteAsync(participant);
// Update attendance record
var attendance = await _attendanceRepository.FirstOrDefaultAsync(
x => x.SessionId == id && x.StudentId == CurrentUser.Id && x.LeaveTime == null
);
if (attendance != null)
{
attendance.LeaveTime = DateTime.UtcNow;
attendance.CalculateDuration();
await _attendanceRepository.UpdateAsync(attendance);
}
// Update participant count
var classSession = await _classSessionRepository.GetAsync(id);
classSession.ParticipantCount = Math.Max(0, classSession.ParticipantCount - 1);
await _classSessionRepository.UpdateAsync(classSession);
}
}
2025-08-26 05:59:39 +00:00
public async Task<List<ClassAttendanceDto>> GetAttendanceAsync(Guid sessionId)
2025-08-25 18:01:57 +00:00
{
var classSession = await _classSessionRepository.GetAsync(sessionId);
if (classSession.TeacherId != CurrentUser.Id)
{
throw new UnauthorizedAccessException("Only the teacher can view attendance");
}
var attendanceRecords = await _attendanceRepository.GetListAsync(
x => x.SessionId == sessionId
);
2025-08-26 05:59:39 +00:00
return ObjectMapper.Map<List<ClassAttandance>, List<ClassAttendanceDto>>(attendanceRecords);
2025-08-25 18:01:57 +00:00
}
}