sozsoft-platform/api/src/Sozsoft.Platform.Application/Videoroom/VideoroomAppService.cs

304 lines
10 KiB
C#
Raw Normal View History

2026-05-08 05:34:29 +00:00
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Sozsoft.Platform.Entities;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Domain.Repositories;
namespace Sozsoft.Platform.VideoRooms;
[Authorize]
public class VideoroomAppService : PlatformAppService, IVideoroomAppService
{
private readonly IRepository<Videoroom, Guid> _classSessionRepository;
private readonly IRepository<VideoroomParticipant, Guid> _participantRepository;
private readonly IRepository<VideoroomAttandance, Guid> _attendanceRepository;
private readonly IRepository<VideoroomChat, Guid> _chatRepository;
public VideoroomAppService(
IRepository<Videoroom, Guid> classSessionRepository,
IRepository<VideoroomParticipant, Guid> participantRepository,
IRepository<VideoroomAttandance, Guid> attendanceRepository,
IRepository<VideoroomChat, Guid> chatRepository)
{
_classSessionRepository = classSessionRepository;
_participantRepository = participantRepository;
_attendanceRepository = attendanceRepository;
_chatRepository = chatRepository;
}
public async Task<VideoroomDto> GetAsync(Guid id)
{
var classSession = await _classSessionRepository.GetAsync(id);
return ObjectMapper.Map<Videoroom, VideoroomDto>(classSession);
}
public async Task<PagedResultDto<VideoroomDto>> GetListAsync(VideoroomFilterInputDto input)
{
var query = await _classSessionRepository.GetQueryableAsync();
if (!string.IsNullOrWhiteSpace(input.Search))
{
query = query.Where(x =>
x.Name.Contains(input.Search) ||
x.Description.Contains(input.Search) ||
x.Subject.Contains(input.Search) ||
x.TeacherName.Contains(input.Search)
);
}
if (!string.IsNullOrWhiteSpace(input.Status))
{
switch (input.Status)
{
case "Active":
query = query.Where(x => x.ActualStartTime == null && x.ActualEndTime == null);
break;
case "Open":
query = query.Where(x => x.ActualStartTime != null && x.ActualEndTime == null);
break;
case "Passive":
query = query.Where(x => x.ActualEndTime != null);
break;
}
}
var totalCount = query.Count();
var items = query
.OrderBy(x => x.ScheduledStartTime)
.Skip(input.SkipCount)
.Take(input.MaxResultCount)
.ToList();
return new PagedResultDto<VideoroomDto>(
totalCount,
ObjectMapper.Map<List<Videoroom>, List<VideoroomDto>>(items)
);
}
public async Task<VideoroomDto> CreateAsync(VideoroomDto input)
{
var classSession = new Videoroom
{
Name = input.Name,
Description = input.Description,
Subject = input.Subject,
TeacherId = CurrentUser.Id,
TeacherName = CurrentUser.Name,
ScheduledStartTime = input.ScheduledStartTime,
ScheduledEndTime = input.ScheduledStartTime.AddMinutes(input.Duration),
Duration = input.Duration,
MaxParticipants = input.MaxParticipants,
SettingsJson = JsonSerializer.Serialize(input.SettingsDto)
};
await _classSessionRepository.InsertAsync(classSession);
return ObjectMapper.Map<Videoroom, VideoroomDto>(classSession);
}
public async Task<VideoroomDto> UpdateAsync(Guid id, VideoroomDto input)
{
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;
classSession.TeacherId = input.TeacherId;
classSession.TeacherName = input.TeacherName;
classSession.ScheduledStartTime = input.ScheduledStartTime;
classSession.ScheduledEndTime = input.ScheduledStartTime.AddMinutes(input.Duration);
classSession.Duration = input.Duration;
classSession.MaxParticipants = input.MaxParticipants;
classSession.SettingsJson = JsonSerializer.Serialize(input.SettingsDto);
await _classSessionRepository.UpdateAsync(classSession);
return ObjectMapper.Map<Videoroom, VideoroomDto>(classSession);
}
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);
}
[HttpPut]
public async Task<VideoroomDto> StartClassAsync(Guid id)
{
var classSession = await _classSessionRepository.GetAsync(id);
if (classSession.TeacherId != CurrentUser.Id)
{
throw new UnauthorizedAccessException("Only the teacher can start this class");
}
classSession.ActualStartTime = DateTime.Now;
await _classSessionRepository.UpdateAsync(classSession);
return ObjectMapper.Map<Videoroom, VideoroomDto>(classSession);
}
[HttpPut]
public async Task EndClassAsync(Guid id)
{
var classSession = await _classSessionRepository.GetAsync(id);
if (classSession.TeacherId != CurrentUser.Id)
{
throw new UnauthorizedAccessException("Only the teacher can end this class");
}
classSession.ActualEndTime = DateTime.Now;
await _classSessionRepository.UpdateAsync(classSession);
// Update attendance records
var activeAttendances = await _attendanceRepository.GetListAsync(
x => x.SessionId == id && x.LeaveTime == null
);
foreach (var attendance in activeAttendances)
{
attendance.LeaveTime = DateTime.Now;
attendance.CalculateDuration();
await _attendanceRepository.UpdateAsync(attendance);
}
}
public async Task<VideoroomDto> JoinClassAsync(Guid id)
{
var classSession = await _classSessionRepository.GetAsync(id);
if (classSession == null)
{
throw new InvalidOperationException("Class not found");
}
var videoroomSettings = string.IsNullOrWhiteSpace(classSession.SettingsJson)
? new VideoroomSettingsDto() // default ayarlar
: JsonSerializer.Deserialize<VideoroomSettingsDto>(classSession.SettingsJson);
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
var participant = new VideoroomParticipant(
GuidGenerator.Create(),
id,
CurrentUser.Id,
CurrentUser.Name,
false, // isTeacher
videoroomSettings?.DefaultMicrophoneState == "muted",
videoroomSettings?.DefaultCameraState == "off",
false, // HandRaised
false, // isKicked
true // isActive
);
await _participantRepository.InsertAsync(participant);
// Create attendance record
var attendance = new VideoroomAttandance(
GuidGenerator.Create(),
id,
CurrentUser.Id,
CurrentUser.Name,
DateTime.Now
);
await _attendanceRepository.InsertAsync(attendance);
// Update participant count
classSession.ParticipantCount++;
await _classSessionRepository.UpdateAsync(classSession);
}
return ObjectMapper.Map<Videoroom, VideoroomDto>(classSession);
}
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);
}
}
public async Task<List<VideoroomAttendanceDto>> GetAttendanceAsync(Guid sessionId)
{
var attendanceRecords = await _attendanceRepository.GetListAsync(
x => x.SessionId == sessionId
);
return ObjectMapper.Map<List<VideoroomAttandance>, List<VideoroomAttendanceDto>>(attendanceRecords);
}
public async Task<List<VideoroomParticipantDto>> GetParticipantAsync(Guid sessionId)
{
var participantRecords = await _participantRepository.GetListAsync(
x => x.SessionId == sessionId
);
return ObjectMapper.Map<List<VideoroomParticipant>, List<VideoroomParticipantDto>>(participantRecords);
}
public async Task<List<VideoroomChatDto>> GetChatAsync(Guid sessionId)
{
var chatRecords = await _chatRepository.GetListAsync(
x => x.SessionId == sessionId
);
return ObjectMapper.Map<List<VideoroomChat>, List<VideoroomChatDto>>(chatRecords);
}
}